gosu 0.15.1 → 1.1.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (227) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -0
  3. data/COPYING +1 -1
  4. data/dependencies/SDL/include/SDL.h +138 -0
  5. data/dependencies/SDL/include/SDL_assert.h +293 -0
  6. data/dependencies/SDL/include/SDL_atomic.h +295 -0
  7. data/dependencies/SDL/include/SDL_audio.h +859 -0
  8. data/dependencies/SDL/include/SDL_bits.h +121 -0
  9. data/dependencies/SDL/include/SDL_blendmode.h +123 -0
  10. data/dependencies/SDL/include/SDL_clipboard.h +71 -0
  11. data/dependencies/SDL/include/SDL_config.h +55 -0
  12. data/dependencies/SDL/include/SDL_config_android.h +182 -0
  13. data/dependencies/SDL/include/SDL_config_iphoneos.h +207 -0
  14. data/dependencies/SDL/include/SDL_config_macosx.h +266 -0
  15. data/dependencies/SDL/include/SDL_config_minimal.h +85 -0
  16. data/dependencies/SDL/include/SDL_config_os2.h +188 -0
  17. data/dependencies/SDL/include/SDL_config_pandora.h +135 -0
  18. data/dependencies/SDL/include/SDL_config_psp.h +165 -0
  19. data/dependencies/SDL/include/SDL_config_windows.h +288 -0
  20. data/dependencies/SDL/include/SDL_config_winrt.h +243 -0
  21. data/dependencies/SDL/include/SDL_config_wiz.h +149 -0
  22. data/dependencies/SDL/include/SDL_copying.h +20 -0
  23. data/dependencies/SDL/include/SDL_cpuinfo.h +299 -0
  24. data/dependencies/SDL/include/SDL_egl.h +1676 -0
  25. data/dependencies/SDL/include/SDL_endian.h +263 -0
  26. data/dependencies/SDL/include/SDL_error.h +112 -0
  27. data/dependencies/SDL/include/SDL_events.h +827 -0
  28. data/dependencies/SDL/include/SDL_filesystem.h +136 -0
  29. data/dependencies/SDL/include/SDL_gamecontroller.h +541 -0
  30. data/dependencies/SDL/include/SDL_gesture.h +87 -0
  31. data/dependencies/SDL/include/SDL_haptic.h +1247 -0
  32. data/dependencies/SDL/include/SDL_hints.h +1578 -0
  33. data/dependencies/SDL/include/SDL_joystick.h +499 -0
  34. data/dependencies/SDL/include/SDL_keyboard.h +217 -0
  35. data/dependencies/SDL/include/SDL_keycode.h +351 -0
  36. data/dependencies/SDL/include/SDL_loadso.h +81 -0
  37. data/dependencies/SDL/include/SDL_locale.h +101 -0
  38. data/dependencies/SDL/include/SDL_log.h +211 -0
  39. data/dependencies/SDL/include/SDL_main.h +180 -0
  40. data/dependencies/SDL/include/SDL_messagebox.h +146 -0
  41. data/dependencies/SDL/include/SDL_metal.h +117 -0
  42. data/dependencies/SDL/include/SDL_misc.h +75 -0
  43. data/dependencies/SDL/include/SDL_mouse.h +302 -0
  44. data/dependencies/SDL/include/SDL_mutex.h +251 -0
  45. data/dependencies/SDL/include/SDL_name.h +33 -0
  46. data/dependencies/SDL/include/SDL_opengl.h +2183 -0
  47. data/dependencies/SDL/include/SDL_opengl_glext.h +11180 -0
  48. data/dependencies/SDL/include/SDL_opengles.h +39 -0
  49. data/dependencies/SDL/include/SDL_opengles2.h +52 -0
  50. data/dependencies/SDL/include/SDL_opengles2_gl2.h +621 -0
  51. data/dependencies/SDL/include/SDL_opengles2_gl2ext.h +2050 -0
  52. data/dependencies/SDL/include/SDL_opengles2_gl2platform.h +30 -0
  53. data/dependencies/SDL/include/SDL_opengles2_khrplatform.h +282 -0
  54. data/dependencies/SDL/include/SDL_pixels.h +479 -0
  55. data/dependencies/SDL/include/SDL_platform.h +198 -0
  56. data/dependencies/SDL/include/SDL_power.h +75 -0
  57. data/dependencies/SDL/include/SDL_quit.h +58 -0
  58. data/dependencies/SDL/include/SDL_rect.h +174 -0
  59. data/dependencies/SDL/include/SDL_render.h +1158 -0
  60. data/dependencies/SDL/include/SDL_revision.h +2 -0
  61. data/dependencies/SDL/include/SDL_rwops.h +283 -0
  62. data/dependencies/SDL/include/SDL_scancode.h +413 -0
  63. data/dependencies/SDL/include/SDL_sensor.h +267 -0
  64. data/dependencies/SDL/include/SDL_shape.h +144 -0
  65. data/dependencies/SDL/include/SDL_stdinc.h +647 -0
  66. data/dependencies/SDL/include/SDL_surface.h +563 -0
  67. data/dependencies/SDL/include/SDL_system.h +325 -0
  68. data/dependencies/SDL/include/SDL_syswm.h +354 -0
  69. data/dependencies/SDL/include/SDL_test.h +69 -0
  70. data/dependencies/SDL/include/SDL_test_assert.h +105 -0
  71. data/dependencies/SDL/include/SDL_test_common.h +218 -0
  72. data/dependencies/SDL/include/SDL_test_compare.h +69 -0
  73. data/dependencies/SDL/include/SDL_test_crc32.h +124 -0
  74. data/dependencies/SDL/include/SDL_test_font.h +81 -0
  75. data/dependencies/SDL/include/SDL_test_fuzzer.h +384 -0
  76. data/dependencies/SDL/include/SDL_test_harness.h +134 -0
  77. data/dependencies/SDL/include/SDL_test_images.h +78 -0
  78. data/dependencies/SDL/include/SDL_test_log.h +67 -0
  79. data/dependencies/SDL/include/SDL_test_md5.h +129 -0
  80. data/dependencies/SDL/include/SDL_test_memory.h +63 -0
  81. data/dependencies/SDL/include/SDL_test_random.h +115 -0
  82. data/dependencies/SDL/include/SDL_thread.h +366 -0
  83. data/dependencies/SDL/include/SDL_timer.h +115 -0
  84. data/dependencies/SDL/include/SDL_touch.h +102 -0
  85. data/dependencies/SDL/include/SDL_types.h +29 -0
  86. data/dependencies/SDL/include/SDL_version.h +162 -0
  87. data/dependencies/SDL/include/SDL_video.h +1282 -0
  88. data/dependencies/SDL/include/SDL_vulkan.h +276 -0
  89. data/dependencies/SDL/include/begin_code.h +166 -0
  90. data/dependencies/SDL/include/close_code.h +40 -0
  91. data/dependencies/SDL/lib/x64/libSDL2.dll.a +0 -0
  92. data/dependencies/SDL/lib/x86/libSDL2.dll.a +0 -0
  93. data/dependencies/SDL_sound/SDL_sound.c +795 -0
  94. data/dependencies/SDL_sound/SDL_sound.h +725 -0
  95. data/dependencies/SDL_sound/SDL_sound_aiff.c +537 -0
  96. data/dependencies/SDL_sound/SDL_sound_au.c +352 -0
  97. data/dependencies/SDL_sound/SDL_sound_coreaudio.c +747 -0
  98. data/dependencies/SDL_sound/SDL_sound_flac.c +182 -0
  99. data/dependencies/SDL_sound/SDL_sound_internal.h +304 -0
  100. data/dependencies/SDL_sound/SDL_sound_modplug.c +228 -0
  101. data/dependencies/SDL_sound/SDL_sound_mp3.c +184 -0
  102. data/dependencies/SDL_sound/SDL_sound_raw.c +164 -0
  103. data/dependencies/SDL_sound/SDL_sound_shn.c +1309 -0
  104. data/dependencies/SDL_sound/SDL_sound_voc.c +550 -0
  105. data/dependencies/SDL_sound/SDL_sound_vorbis.c +223 -0
  106. data/dependencies/SDL_sound/SDL_sound_wav.c +783 -0
  107. data/dependencies/SDL_sound/dr_flac.h +5906 -0
  108. data/dependencies/SDL_sound/dr_mp3.h +2832 -0
  109. data/dependencies/SDL_sound/libmodplug/fastmix.c +1748 -0
  110. data/dependencies/SDL_sound/libmodplug/libmodplug.h +1001 -0
  111. data/dependencies/SDL_sound/libmodplug/load_669.c +188 -0
  112. data/dependencies/SDL_sound/libmodplug/load_abc.c +4725 -0
  113. data/dependencies/SDL_sound/libmodplug/load_amf.c +403 -0
  114. data/dependencies/SDL_sound/libmodplug/load_ams.c +587 -0
  115. data/dependencies/SDL_sound/libmodplug/load_dbm.c +357 -0
  116. data/dependencies/SDL_sound/libmodplug/load_dmf.c +531 -0
  117. data/dependencies/SDL_sound/libmodplug/load_dsm.c +232 -0
  118. data/dependencies/SDL_sound/libmodplug/load_far.c +253 -0
  119. data/dependencies/SDL_sound/libmodplug/load_it.c +796 -0
  120. data/dependencies/SDL_sound/libmodplug/load_mdl.c +488 -0
  121. data/dependencies/SDL_sound/libmodplug/load_med.c +757 -0
  122. data/dependencies/SDL_sound/libmodplug/load_mid.c +1405 -0
  123. data/dependencies/SDL_sound/libmodplug/load_mod.c +269 -0
  124. data/dependencies/SDL_sound/libmodplug/load_mt2.c +546 -0
  125. data/dependencies/SDL_sound/libmodplug/load_mtm.c +142 -0
  126. data/dependencies/SDL_sound/libmodplug/load_okt.c +192 -0
  127. data/dependencies/SDL_sound/libmodplug/load_pat.c +1143 -0
  128. data/dependencies/SDL_sound/libmodplug/load_pat.h +25 -0
  129. data/dependencies/SDL_sound/libmodplug/load_psm.c +350 -0
  130. data/dependencies/SDL_sound/libmodplug/load_ptm.c +204 -0
  131. data/dependencies/SDL_sound/libmodplug/load_s3m.c +325 -0
  132. data/dependencies/SDL_sound/libmodplug/load_stm.c +180 -0
  133. data/dependencies/SDL_sound/libmodplug/load_ult.c +206 -0
  134. data/dependencies/SDL_sound/libmodplug/load_umx.c +51 -0
  135. data/dependencies/SDL_sound/libmodplug/load_xm.c +554 -0
  136. data/dependencies/SDL_sound/libmodplug/mmcmp.c +382 -0
  137. data/dependencies/SDL_sound/libmodplug/modplug.c +170 -0
  138. data/dependencies/SDL_sound/libmodplug/modplug.h +90 -0
  139. data/dependencies/SDL_sound/libmodplug/snd_dsp.c +301 -0
  140. data/dependencies/SDL_sound/libmodplug/snd_flt.c +63 -0
  141. data/dependencies/SDL_sound/libmodplug/snd_fx.c +2350 -0
  142. data/dependencies/SDL_sound/libmodplug/sndfile.c +1169 -0
  143. data/dependencies/SDL_sound/libmodplug/sndmix.c +1034 -0
  144. data/dependencies/SDL_sound/libmodplug/tables.h +371 -0
  145. data/{src/stb_vorbis.c → dependencies/SDL_sound/stb_vorbis.h} +143 -78
  146. data/dependencies/al_soft/AL/al.h +655 -0
  147. data/dependencies/al_soft/AL/alc.h +270 -0
  148. data/dependencies/al_soft/AL/alext.h +585 -0
  149. data/dependencies/al_soft/AL/efx-creative.h +3 -0
  150. data/dependencies/al_soft/AL/efx-presets.h +402 -0
  151. data/dependencies/al_soft/AL/efx.h +762 -0
  152. data/dependencies/al_soft/x64/libOpenAL32.dll.a +0 -0
  153. data/dependencies/al_soft/x86/libOpenAL32.dll.a +0 -0
  154. data/{src → dependencies/stb}/stb_image.h +330 -127
  155. data/{src → dependencies/stb}/stb_image_write.h +156 -85
  156. data/{src → dependencies/stb}/stb_truetype.h +192 -69
  157. data/{src → dependencies/utf8proc}/utf8proc.c +0 -0
  158. data/{src → dependencies/utf8proc}/utf8proc.h +0 -0
  159. data/{src → dependencies/utf8proc}/utf8proc_data.h +0 -0
  160. data/ext/gosu/extconf.rb +53 -39
  161. data/{Gosu → include/Gosu}/Audio.hpp +6 -8
  162. data/include/Gosu/Bitmap.hpp +100 -0
  163. data/{Gosu → include/Gosu}/Buttons.hpp +104 -44
  164. data/{Gosu → include/Gosu}/Color.hpp +0 -0
  165. data/{Gosu → include/Gosu}/Directories.hpp +0 -0
  166. data/{Gosu → include/Gosu}/Font.hpp +1 -1
  167. data/{Gosu → include/Gosu}/Fwd.hpp +0 -5
  168. data/{Gosu → include/Gosu}/Gosu.hpp +0 -0
  169. data/{Gosu → include/Gosu}/Graphics.hpp +0 -0
  170. data/{Gosu → include/Gosu}/GraphicsBase.hpp +0 -0
  171. data/{Gosu → include/Gosu}/IO.hpp +0 -0
  172. data/{Gosu → include/Gosu}/Image.hpp +7 -6
  173. data/{Gosu → include/Gosu}/ImageData.hpp +0 -0
  174. data/{Gosu → include/Gosu}/Input.hpp +39 -51
  175. data/{Gosu → include/Gosu}/Inspection.hpp +0 -0
  176. data/{Gosu → include/Gosu}/Math.hpp +0 -0
  177. data/{Gosu → include/Gosu}/Platform.hpp +0 -0
  178. data/{Gosu → include/Gosu}/Text.hpp +0 -0
  179. data/{Gosu → include/Gosu}/TextInput.hpp +0 -0
  180. data/{Gosu → include/Gosu}/Timing.hpp +0 -0
  181. data/{Gosu → include/Gosu}/Utility.hpp +15 -4
  182. data/{Gosu → include/Gosu}/Version.hpp +3 -3
  183. data/{Gosu → include/Gosu}/Window.hpp +46 -34
  184. data/lib/OpenAL32.dll +0 -0
  185. data/lib/SDL2.dll +0 -0
  186. data/lib/gosu.rb +0 -3
  187. data/lib/gosu/patches.rb +0 -23
  188. data/lib/gosu/preview.rb +1 -3
  189. data/lib/gosu/swig_patches.rb +6 -8
  190. data/lib64/OpenAL32.dll +0 -0
  191. data/lib64/SDL2.dll +0 -0
  192. data/rdoc/gosu.rb +112 -23
  193. data/src/Audio.cpp +50 -224
  194. data/src/AudioFile.hpp +20 -37
  195. data/src/AudioFileAudioToolbox.cpp +237 -0
  196. data/src/AudioFileSDLSound.cpp +147 -0
  197. data/src/AudioImpl.cpp +3 -12
  198. data/src/AudioImpl.hpp +3 -1
  199. data/src/Bitmap.cpp +85 -83
  200. data/src/BitmapIO.cpp +52 -58
  201. data/src/Font.cpp +4 -1
  202. data/src/Graphics.cpp +7 -4
  203. data/src/Image.cpp +13 -16
  204. data/src/Input.cpp +412 -164
  205. data/src/LargeImageData.cpp +2 -1
  206. data/src/MarkupParser.cpp +2 -1
  207. data/src/Resolution.cpp +8 -8
  208. data/src/RubyGosu.cxx +1184 -352
  209. data/src/RubyGosu.h +3 -2
  210. data/src/TexChunk.cpp +1 -1
  211. data/src/Text.cpp +1 -0
  212. data/src/TextBuilder.cpp +3 -1
  213. data/src/Texture.cpp +1 -1
  214. data/src/TrueTypeFont.cpp +2 -1
  215. data/src/TrueTypeFontWin.cpp +3 -3
  216. data/src/Utility.cpp +11 -7
  217. data/src/Window.cpp +90 -62
  218. data/src/WindowUIKit.cpp +21 -9
  219. metadata +195 -46
  220. data/Gosu/AutoLink.hpp +0 -14
  221. data/Gosu/Bitmap.hpp +0 -113
  222. data/lib/gosu/zen.rb +0 -89
  223. data/src/AudioToolboxFile.hpp +0 -210
  224. data/src/MPEGFile.hpp +0 -90
  225. data/src/OggFile.hpp +0 -92
  226. data/src/SndFile.hpp +0 -174
  227. data/src/WinMain.cpp +0 -64
@@ -0,0 +1,206 @@
1
+ /*
2
+ * This source code is public domain.
3
+ *
4
+ * Authors: Olivier Lapicque <olivierl@jps.net>
5
+ */
6
+
7
+ #include "libmodplug.h"
8
+
9
+ #define ULT_16BIT 0x04
10
+ #define ULT_LOOP 0x08
11
+ #define ULT_BIDI 0x10
12
+
13
+ #pragma pack(1)
14
+
15
+ // Raw ULT header struct:
16
+ typedef struct tagULTHEADER
17
+ {
18
+ char id[15]; // changed from CHAR
19
+ char songtitle[32]; // changed from CHAR
20
+ BYTE reserved;
21
+ } ULTHEADER;
22
+
23
+
24
+ // Raw ULT sampleinfo struct:
25
+ typedef struct tagULTSAMPLE
26
+ {
27
+ CHAR samplename[32];
28
+ CHAR dosname[12];
29
+ LONG loopstart;
30
+ LONG loopend;
31
+ LONG sizestart;
32
+ LONG sizeend;
33
+ BYTE volume;
34
+ BYTE flags;
35
+ WORD finetune;
36
+ } ULTSAMPLE;
37
+
38
+ #pragma pack()
39
+
40
+
41
+ BOOL CSoundFile_ReadUlt(CSoundFile *_this, const BYTE *lpStream, DWORD dwMemLength)
42
+ //---------------------------------------------------------------
43
+ {
44
+ ULTHEADER *pmh = (ULTHEADER *)lpStream;
45
+ ULTSAMPLE *pus;
46
+ UINT nos, nop;
47
+ DWORD dwMemPos = 0;
48
+
49
+ // try to read module header
50
+ if ((!lpStream) || (dwMemLength < 0x100)) return FALSE;
51
+ if (SDL_strncmp(pmh->id,"MAS_UTrack_V00",14)) return FALSE;
52
+ // Warning! Not supported ULT format, trying anyway
53
+ // if ((pmh->id[14] < '1') || (pmh->id[14] > '4')) return FALSE;
54
+ _this->m_nType = MOD_TYPE_ULT;
55
+ _this->m_nDefaultSpeed = 6;
56
+ _this->m_nDefaultTempo = 125;
57
+ // read songtext
58
+ dwMemPos = sizeof(ULTHEADER);
59
+ if ((pmh->reserved) && (dwMemPos + pmh->reserved * 32 < dwMemLength))
60
+ {
61
+ UINT len = pmh->reserved * 32;
62
+ dwMemPos += len;
63
+ }
64
+ if (dwMemPos >= dwMemLength) return TRUE;
65
+ nos = lpStream[dwMemPos++];
66
+ _this->m_nSamples = nos;
67
+ if (_this->m_nSamples >= MAX_SAMPLES) _this->m_nSamples = MAX_SAMPLES-1;
68
+ UINT smpsize = 64;
69
+ if (pmh->id[14] >= '4') smpsize += 2;
70
+ if (dwMemPos + nos*smpsize + 256 + 2 > dwMemLength) return TRUE;
71
+ for (UINT ins=1; ins<=nos; ins++, dwMemPos+=smpsize) if (ins<=_this->m_nSamples)
72
+ {
73
+ pus = (ULTSAMPLE *)(lpStream+dwMemPos);
74
+ MODINSTRUMENT *pins = &_this->Ins[ins];
75
+ pins->nLoopStart = pus->loopstart;
76
+ pins->nLoopEnd = pus->loopend;
77
+ pins->nLength = pus->sizeend - pus->sizestart;
78
+ pins->nVolume = pus->volume;
79
+ pins->nGlobalVol = 64;
80
+ pins->nC4Speed = 8363;
81
+ if (pmh->id[14] >= '4')
82
+ {
83
+ pins->nC4Speed = pus->finetune;
84
+ }
85
+ if (pus->flags & ULT_LOOP) pins->uFlags |= CHN_LOOP;
86
+ if (pus->flags & ULT_BIDI) pins->uFlags |= CHN_PINGPONGLOOP;
87
+ if (pus->flags & ULT_16BIT)
88
+ {
89
+ pins->uFlags |= CHN_16BIT;
90
+ pins->nLoopStart >>= 1;
91
+ pins->nLoopEnd >>= 1;
92
+ }
93
+ }
94
+ SDL_memcpy(_this->Order, lpStream+dwMemPos, 256);
95
+ dwMemPos += 256;
96
+ _this->m_nChannels = lpStream[dwMemPos] + 1;
97
+ nop = lpStream[dwMemPos+1] + 1;
98
+ dwMemPos += 2;
99
+ if (_this->m_nChannels > 32) _this->m_nChannels = 32;
100
+ // Default channel settings
101
+ for (UINT nSet=0; nSet<_this->m_nChannels; nSet++)
102
+ {
103
+ _this->ChnSettings[nSet].nVolume = 64;
104
+ _this->ChnSettings[nSet].nPan = (nSet & 1) ? 0x40 : 0xC0;
105
+ }
106
+ // read pan position table for v1.5 and higher
107
+ if(pmh->id[14]>='3')
108
+ {
109
+ if (dwMemPos + _this->m_nChannels > dwMemLength) return TRUE;
110
+ for(UINT t=0; t<_this->m_nChannels; t++)
111
+ {
112
+ _this->ChnSettings[t].nPan = (lpStream[dwMemPos++] << 4) + 8;
113
+ if (_this->ChnSettings[t].nPan > 256) _this->ChnSettings[t].nPan = 256;
114
+ }
115
+ }
116
+ // Allocating Patterns
117
+ for (UINT nAllocPat=0; nAllocPat<nop; nAllocPat++)
118
+ {
119
+ if (nAllocPat < MAX_PATTERNS)
120
+ {
121
+ _this->PatternSize[nAllocPat] = 64;
122
+ _this->Patterns[nAllocPat] = CSoundFile_AllocatePattern(64, _this->m_nChannels);
123
+ }
124
+ }
125
+ // Reading Patterns
126
+ for (UINT nChn=0; nChn<_this->m_nChannels; nChn++)
127
+ {
128
+ for (UINT nPat=0; nPat<nop; nPat++)
129
+ {
130
+ MODCOMMAND *pat = NULL;
131
+
132
+ if (nPat < MAX_PATTERNS)
133
+ {
134
+ pat = _this->Patterns[nPat];
135
+ if (pat) pat += nChn;
136
+ }
137
+ UINT row = 0;
138
+ while (row < 64)
139
+ {
140
+ if (dwMemPos + 6 > dwMemLength) return TRUE;
141
+ UINT rep = 1;
142
+ UINT note = lpStream[dwMemPos++];
143
+ if (note == 0xFC)
144
+ {
145
+ rep = lpStream[dwMemPos];
146
+ note = lpStream[dwMemPos+1];
147
+ dwMemPos += 2;
148
+ }
149
+ UINT instr = lpStream[dwMemPos++];
150
+ UINT eff = lpStream[dwMemPos++];
151
+ UINT dat1 = lpStream[dwMemPos++];
152
+ UINT dat2 = lpStream[dwMemPos++];
153
+ UINT cmd1 = eff & 0x0F;
154
+ UINT cmd2 = eff >> 4;
155
+ if (cmd1 == 0x0C) dat1 >>= 2; else
156
+ if (cmd1 == 0x0B) { cmd1 = dat1 = 0; }
157
+ if (cmd2 == 0x0C) dat2 >>= 2; else
158
+ if (cmd2 == 0x0B) { cmd2 = dat2 = 0; }
159
+ while ((rep != 0) && (row < 64))
160
+ {
161
+ if (pat)
162
+ {
163
+ pat->instr = instr;
164
+ if (note) pat->note = note + 36;
165
+ if (cmd1 | dat1)
166
+ {
167
+ if (cmd1 == 0x0C)
168
+ {
169
+ pat->volcmd = VOLCMD_VOLUME;
170
+ pat->vol = dat1;
171
+ } else
172
+ {
173
+ pat->command = cmd1;
174
+ pat->param = dat1;
175
+ CSoundFile_ConvertModCommand(_this, pat);
176
+ }
177
+ }
178
+ if (cmd2 == 0x0C)
179
+ {
180
+ pat->volcmd = VOLCMD_VOLUME;
181
+ pat->vol = dat2;
182
+ } else
183
+ if ((cmd2 | dat2) && (!pat->command))
184
+ {
185
+ pat->command = cmd2;
186
+ pat->param = dat2;
187
+ CSoundFile_ConvertModCommand(_this, pat);
188
+ }
189
+ pat += _this->m_nChannels;
190
+ }
191
+ row++;
192
+ rep--;
193
+ }
194
+ }
195
+ }
196
+ }
197
+ // Reading Instruments
198
+ for (UINT smp=1; smp<=_this->m_nSamples; smp++) if (_this->Ins[smp].nLength)
199
+ {
200
+ if (dwMemPos >= dwMemLength) return TRUE;
201
+ UINT flags = (_this->Ins[smp].uFlags & CHN_16BIT) ? RS_PCM16S : RS_PCM8S;
202
+ dwMemPos += CSoundFile_ReadSample(_this, &_this->Ins[smp], flags, (LPSTR)(lpStream+dwMemPos), dwMemLength - dwMemPos);
203
+ }
204
+ return TRUE;
205
+ }
206
+
@@ -0,0 +1,51 @@
1
+ /*
2
+ * This source code is public domain.
3
+ *
4
+ * Authors: Olivier Lapicque <olivierl@jps.net>
5
+ */
6
+
7
+ #include "libmodplug.h"
8
+
9
+ #define MODMAGIC_OFFSET (20+31*30+130)
10
+
11
+ BOOL CSoundFile_ReadUMX(CSoundFile *_this, const BYTE *lpStream, DWORD dwMemLength)
12
+ //---------------------------------------------------------------
13
+ {
14
+ if ((!lpStream) || (dwMemLength < 0x800)) return FALSE;
15
+ // Rip Mods from UMX
16
+ if ((bswapLE32(*((DWORD *)(lpStream+0x20))) < dwMemLength)
17
+ && (bswapLE32(*((DWORD *)(lpStream+0x18))) <= dwMemLength - 0x10)
18
+ && (bswapLE32(*((DWORD *)(lpStream+0x18))) >= dwMemLength - 0x200))
19
+ {
20
+ for (UINT uscan=0x40; uscan<0x500; uscan++)
21
+ {
22
+ DWORD dwScan = bswapLE32(*((DWORD *)(lpStream+uscan)));
23
+ // IT
24
+ if (dwScan == 0x4D504D49)
25
+ {
26
+ DWORD dwRipOfs = uscan;
27
+ return CSoundFile_ReadIT(_this, lpStream + dwRipOfs, dwMemLength - dwRipOfs);
28
+ }
29
+ // S3M
30
+ if (dwScan == 0x4D524353)
31
+ {
32
+ DWORD dwRipOfs = uscan - 44;
33
+ return CSoundFile_ReadS3M(_this, lpStream + dwRipOfs, dwMemLength - dwRipOfs);
34
+ }
35
+ // XM
36
+ if (!SDL_strncasecmp((LPCSTR)(lpStream+uscan), "Extended Module", 15))
37
+ {
38
+ DWORD dwRipOfs = uscan;
39
+ return CSoundFile_ReadXM(_this, lpStream + dwRipOfs, dwMemLength - dwRipOfs);
40
+ }
41
+ // MOD
42
+ if ((uscan > MODMAGIC_OFFSET) && (dwScan == 0x2e4b2e4d))
43
+ {
44
+ DWORD dwRipOfs = uscan - MODMAGIC_OFFSET;
45
+ return CSoundFile_ReadMod(_this, lpStream+dwRipOfs, dwMemLength-dwRipOfs);
46
+ }
47
+ }
48
+ }
49
+ return FALSE;
50
+ }
51
+
@@ -0,0 +1,554 @@
1
+ /*
2
+ * This source code is public domain.
3
+ *
4
+ * Authors: Olivier Lapicque <olivierl@jps.net>,
5
+ * Adam Goode <adam@evdebs.org> (endian and char fixes for PPC)
6
+ */
7
+
8
+ #include "libmodplug.h"
9
+
10
+ ////////////////////////////////////////////////////////
11
+ // FastTracker II XM file support
12
+
13
+ #ifdef MSC_VER
14
+ #pragma warning(disable:4244)
15
+ #endif
16
+
17
+ #pragma pack(1)
18
+ typedef struct tagXMFILEHEADER
19
+ {
20
+ DWORD size;
21
+ WORD norder;
22
+ WORD restartpos;
23
+ WORD channels;
24
+ WORD patterns;
25
+ WORD instruments;
26
+ WORD flags;
27
+ WORD speed;
28
+ WORD tempo;
29
+ BYTE order[256];
30
+ } XMFILEHEADER;
31
+
32
+
33
+ typedef struct tagXMINSTRUMENTHEADER
34
+ {
35
+ DWORD size;
36
+ CHAR name[22];
37
+ BYTE type;
38
+ BYTE samples;
39
+ BYTE samplesh;
40
+ } XMINSTRUMENTHEADER;
41
+
42
+
43
+ typedef struct tagXMSAMPLEHEADER
44
+ {
45
+ DWORD shsize;
46
+ BYTE snum[96];
47
+ WORD venv[24];
48
+ WORD penv[24];
49
+ BYTE vnum, pnum;
50
+ BYTE vsustain, vloops, vloope, psustain, ploops, ploope;
51
+ BYTE vtype, ptype;
52
+ BYTE vibtype, vibsweep, vibdepth, vibrate;
53
+ WORD volfade;
54
+ WORD res;
55
+ BYTE reserved1[20];
56
+ } XMSAMPLEHEADER;
57
+
58
+ typedef struct tagXMSAMPLESTRUCT
59
+ {
60
+ DWORD samplen;
61
+ DWORD loopstart;
62
+ DWORD looplen;
63
+ BYTE vol;
64
+ signed char finetune;
65
+ BYTE type;
66
+ BYTE pan;
67
+ signed char relnote;
68
+ BYTE res;
69
+ char name[22];
70
+ } XMSAMPLESTRUCT;
71
+ #pragma pack()
72
+
73
+
74
+ BOOL CSoundFile_ReadXM(CSoundFile *_this, const BYTE *lpStream, DWORD dwMemLength)
75
+ //--------------------------------------------------------------
76
+ {
77
+ XMSAMPLEHEADER xmsh;
78
+ XMSAMPLESTRUCT xmss;
79
+ DWORD dwMemPos, dwHdrSize;
80
+ WORD norders=0, restartpos=0, channels=0, patterns=0, instruments=0;
81
+ WORD xmflags=0, deftempo=125, defspeed=6;
82
+ BOOL InstUsed[256];
83
+ BYTE channels_used[MAX_CHANNELS];
84
+ BYTE pattern_map[256];
85
+ BOOL samples_used[MAX_SAMPLES];
86
+ UINT unused_samples;
87
+ XMFILEHEADER xmhead;
88
+
89
+ _this->m_nChannels = 0;
90
+ if ((!lpStream) || (dwMemLength < 0x200)) return FALSE;
91
+ if (SDL_strncasecmp((LPCSTR)lpStream, "Extended Module", 15)) return FALSE;
92
+
93
+ SDL_memcpy(&xmhead, lpStream+60, sizeof (xmhead));
94
+ dwHdrSize = bswapLE32(xmhead.size);
95
+ norders = bswapLE16(xmhead.norder);
96
+ if ((!norders) || (norders > MAX_ORDERS)) return FALSE;
97
+ restartpos = bswapLE16(xmhead.restartpos);
98
+ channels = bswapLE16(xmhead.channels);
99
+ if ((!channels) || (channels > 64)) return FALSE;
100
+ _this->m_nType = MOD_TYPE_XM;
101
+ _this->m_nMinPeriod = 27;
102
+ _this->m_nMaxPeriod = 54784;
103
+ _this->m_nChannels = channels;
104
+ if (restartpos < norders) _this->m_nRestartPos = restartpos;
105
+ patterns = bswapLE16(xmhead.patterns);
106
+ if (patterns > 256) patterns = 256;
107
+ instruments = bswapLE16(xmhead.instruments);
108
+ if (instruments >= MAX_INSTRUMENTS) instruments = MAX_INSTRUMENTS-1;
109
+ _this->m_nInstruments = instruments;
110
+ _this->m_nSamples = 0;
111
+ xmflags = bswapLE16(xmhead.flags);
112
+ if (xmflags & 1) _this->m_dwSongFlags |= SONG_LINEARSLIDES;
113
+ if (xmflags & 0x1000) _this->m_dwSongFlags |= SONG_EXFILTERRANGE;
114
+ defspeed = bswapLE16(xmhead.speed);
115
+ deftempo = bswapLE16(xmhead.tempo);
116
+ if ((deftempo >= 32) && (deftempo < 256)) _this->m_nDefaultTempo = deftempo;
117
+ if ((defspeed > 0) && (defspeed < 40)) _this->m_nDefaultSpeed = defspeed;
118
+ SDL_memcpy(_this->Order, lpStream+80, norders);
119
+ SDL_memset(InstUsed, 0, sizeof(InstUsed));
120
+ if (patterns > MAX_PATTERNS)
121
+ {
122
+ UINT i, j;
123
+ for (i=0; i<norders; i++)
124
+ {
125
+ if (_this->Order[i] < patterns) InstUsed[_this->Order[i]] = TRUE;
126
+ }
127
+ j = 0;
128
+ for (i=0; i<256; i++)
129
+ {
130
+ if (InstUsed[i]) pattern_map[i] = j++;
131
+ }
132
+ for (i=0; i<256; i++)
133
+ {
134
+ if (!InstUsed[i])
135
+ {
136
+ pattern_map[i] = (j < MAX_PATTERNS) ? j : 0xFE;
137
+ j++;
138
+ }
139
+ }
140
+ for (i=0; i<norders; i++)
141
+ {
142
+ _this->Order[i] = pattern_map[_this->Order[i]];
143
+ }
144
+ } else
145
+ {
146
+ for (UINT i=0; i<256; i++) pattern_map[i] = i;
147
+ }
148
+ SDL_memset(InstUsed, 0, sizeof(InstUsed));
149
+ dwMemPos = dwHdrSize + 60;
150
+ if (dwMemPos + 8 >= dwMemLength) return TRUE;
151
+ // Reading patterns
152
+ SDL_memset(channels_used, 0, sizeof(channels_used));
153
+ for (UINT ipat=0; ipat<patterns; ipat++)
154
+ {
155
+ UINT ipatmap = pattern_map[ipat];
156
+ DWORD dwSize = 0;
157
+ WORD rows=64, packsize=0;
158
+ dwSize = bswapLE32(*((DWORD *)(lpStream+dwMemPos)));
159
+ while ((dwMemPos + dwSize >= dwMemLength) || (dwSize & 0xFFFFFF00))
160
+ {
161
+ if (dwMemPos + 4 >= dwMemLength) break;
162
+ dwMemPos++;
163
+ dwSize = bswapLE32(*((DWORD *)(lpStream+dwMemPos)));
164
+ }
165
+ rows = bswapLE16(*((WORD *)(lpStream+dwMemPos+5)));
166
+ if ((!rows) || (rows > 256)) rows = 64;
167
+ packsize = bswapLE16(*((WORD *)(lpStream+dwMemPos+7)));
168
+ if (dwMemPos + dwSize + 4 > dwMemLength) return TRUE;
169
+ dwMemPos += dwSize;
170
+ if (dwMemPos + packsize + 4 > dwMemLength) return TRUE;
171
+ MODCOMMAND *p;
172
+ if (ipatmap < MAX_PATTERNS)
173
+ {
174
+ _this->PatternSize[ipatmap] = rows;
175
+ if ((_this->Patterns[ipatmap] = CSoundFile_AllocatePattern(rows, _this->m_nChannels)) == NULL) return TRUE;
176
+ if (!packsize) continue;
177
+ p = _this->Patterns[ipatmap];
178
+ } else p = NULL;
179
+ const BYTE *src = lpStream+dwMemPos;
180
+ UINT j=0;
181
+ for (UINT row=0; row<rows; row++)
182
+ {
183
+ for (UINT chn=0; chn<_this->m_nChannels; chn++)
184
+ {
185
+ if ((p) && (j < packsize))
186
+ {
187
+ BYTE b = src[j++];
188
+ UINT vol = 0;
189
+ if (b & 0x80)
190
+ {
191
+ if (b & 1) p->note = src[j++];
192
+ if (b & 2) p->instr = src[j++];
193
+ if (b & 4) vol = src[j++];
194
+ if (b & 8) p->command = src[j++];
195
+ if (b & 16) p->param = src[j++];
196
+ } else
197
+ {
198
+ p->note = b;
199
+ p->instr = src[j++];
200
+ vol = src[j++];
201
+ p->command = src[j++];
202
+ p->param = src[j++];
203
+ }
204
+ if (p->note == 97) p->note = 0xFF; else
205
+ if ((p->note) && (p->note < 97)) p->note += 12;
206
+ if (p->note) channels_used[chn] = 1;
207
+ if (p->command | p->param) CSoundFile_ConvertModCommand(_this, p);
208
+ if (p->instr == 0xff) p->instr = 0;
209
+ if (p->instr) InstUsed[p->instr] = TRUE;
210
+ if ((vol >= 0x10) && (vol <= 0x50))
211
+ {
212
+ p->volcmd = VOLCMD_VOLUME;
213
+ p->vol = vol - 0x10;
214
+ } else
215
+ if (vol >= 0x60)
216
+ {
217
+ UINT v = vol & 0xF0;
218
+ vol &= 0x0F;
219
+ p->vol = vol;
220
+ switch(v)
221
+ {
222
+ // 60-6F: Volume Slide Down
223
+ case 0x60: p->volcmd = VOLCMD_VOLSLIDEDOWN; break;
224
+ // 70-7F: Volume Slide Up:
225
+ case 0x70: p->volcmd = VOLCMD_VOLSLIDEUP; break;
226
+ // 80-8F: Fine Volume Slide Down
227
+ case 0x80: p->volcmd = VOLCMD_FINEVOLDOWN; break;
228
+ // 90-9F: Fine Volume Slide Up
229
+ case 0x90: p->volcmd = VOLCMD_FINEVOLUP; break;
230
+ // A0-AF: Set Vibrato Speed
231
+ case 0xA0: p->volcmd = VOLCMD_VIBRATOSPEED; break;
232
+ // B0-BF: Vibrato
233
+ case 0xB0: p->volcmd = VOLCMD_VIBRATO; break;
234
+ // C0-CF: Set Panning
235
+ case 0xC0: p->volcmd = VOLCMD_PANNING; p->vol = (vol << 2) + 2; break;
236
+ // D0-DF: Panning Slide Left
237
+ case 0xD0: p->volcmd = VOLCMD_PANSLIDELEFT; break;
238
+ // E0-EF: Panning Slide Right
239
+ case 0xE0: p->volcmd = VOLCMD_PANSLIDERIGHT; break;
240
+ // F0-FF: Tone Portamento
241
+ case 0xF0: p->volcmd = VOLCMD_TONEPORTAMENTO; break;
242
+ }
243
+ }
244
+ p++;
245
+ } else
246
+ if (j < packsize)
247
+ {
248
+ BYTE b = src[j++];
249
+ if (b & 0x80)
250
+ {
251
+ if (b & 1) j++;
252
+ if (b & 2) j++;
253
+ if (b & 4) j++;
254
+ if (b & 8) j++;
255
+ if (b & 16) j++;
256
+ } else j += 4;
257
+ } else break;
258
+ }
259
+ }
260
+ dwMemPos += packsize;
261
+ }
262
+ // Wrong offset check
263
+ while (dwMemPos + 4 < dwMemLength)
264
+ {
265
+ DWORD d = bswapLE32(*((DWORD *)(lpStream+dwMemPos)));
266
+ if (d < 0x300) break;
267
+ dwMemPos++;
268
+ }
269
+ SDL_memset(samples_used, 0, sizeof(samples_used));
270
+ unused_samples = 0;
271
+ // Reading instruments
272
+ for (UINT iIns=1; iIns<=instruments; iIns++)
273
+ {
274
+ XMINSTRUMENTHEADER *pih;
275
+ BYTE flags[32];
276
+ DWORD samplesize[32];
277
+ UINT samplemap[32];
278
+ WORD nsamples;
279
+
280
+ if (dwMemPos + sizeof(XMINSTRUMENTHEADER) >= dwMemLength) return TRUE;
281
+ pih = (XMINSTRUMENTHEADER *)(lpStream+dwMemPos);
282
+ if (dwMemPos + bswapLE32(pih->size) > dwMemLength) return TRUE;
283
+ if ((_this->Headers[iIns] = (INSTRUMENTHEADER *) SDL_malloc(sizeof (INSTRUMENTHEADER))) == NULL) continue;
284
+ SDL_memset(_this->Headers[iIns], 0, sizeof(INSTRUMENTHEADER));
285
+ if ((nsamples = pih->samples) > 0)
286
+ {
287
+ if (dwMemPos + sizeof(XMSAMPLEHEADER) > dwMemLength) return TRUE;
288
+ SDL_memcpy(&xmsh, lpStream+dwMemPos+sizeof(XMINSTRUMENTHEADER), sizeof(XMSAMPLEHEADER));
289
+ xmsh.shsize = bswapLE32(xmsh.shsize);
290
+ for (int i = 0; i < 24; ++i) {
291
+ xmsh.venv[i] = bswapLE16(xmsh.venv[i]);
292
+ xmsh.penv[i] = bswapLE16(xmsh.penv[i]);
293
+ }
294
+ xmsh.volfade = bswapLE16(xmsh.volfade);
295
+ xmsh.res = bswapLE16(xmsh.res);
296
+ dwMemPos += bswapLE32(pih->size);
297
+ } else
298
+ {
299
+ if (bswapLE32(pih->size)) dwMemPos += bswapLE32(pih->size);
300
+ else dwMemPos += sizeof(XMINSTRUMENTHEADER);
301
+ continue;
302
+ }
303
+ SDL_memset(samplemap, 0, sizeof(samplemap));
304
+ if (nsamples > 32) return TRUE;
305
+ UINT newsamples = _this->m_nSamples;
306
+ for (UINT nmap=0; nmap<nsamples; nmap++)
307
+ {
308
+ UINT n = _this->m_nSamples+nmap+1;
309
+ if (n >= MAX_SAMPLES)
310
+ {
311
+ n = _this->m_nSamples;
312
+ while (n > 0)
313
+ {
314
+ if (!_this->Ins[n].pSample)
315
+ {
316
+ for (UINT xmapchk=0; xmapchk < nmap; xmapchk++)
317
+ {
318
+ if (samplemap[xmapchk] == n) goto alreadymapped;
319
+ }
320
+ for (UINT clrs=1; clrs<iIns; clrs++) if (_this->Headers[clrs])
321
+ {
322
+ INSTRUMENTHEADER *pks = _this->Headers[clrs];
323
+ for (UINT ks=0; ks<128; ks++)
324
+ {
325
+ if (pks->Keyboard[ks] == n) pks->Keyboard[ks] = 0;
326
+ }
327
+ }
328
+ break;
329
+ }
330
+ alreadymapped:
331
+ n--;
332
+ }
333
+ // Damn! more than 200 samples: look for duplicates
334
+ if (!n)
335
+ {
336
+ if (!unused_samples)
337
+ {
338
+ unused_samples = CSoundFile_DetectUnusedSamples(_this, samples_used);
339
+ if (!unused_samples) unused_samples = 0xFFFF;
340
+ }
341
+ if ((unused_samples) && (unused_samples != 0xFFFF))
342
+ {
343
+ for (UINT iext=_this->m_nSamples; iext>=1; iext--) if (!samples_used[iext])
344
+ {
345
+ unused_samples--;
346
+ samples_used[iext] = TRUE;
347
+ CSoundFile_DestroySample(_this, iext);
348
+ n = iext;
349
+ for (UINT mapchk=0; mapchk<nmap; mapchk++)
350
+ {
351
+ if (samplemap[mapchk] == n) samplemap[mapchk] = 0;
352
+ }
353
+ for (UINT clrs=1; clrs<iIns; clrs++) if (_this->Headers[clrs])
354
+ {
355
+ INSTRUMENTHEADER *pks = _this->Headers[clrs];
356
+ for (UINT ks=0; ks<128; ks++)
357
+ {
358
+ if (pks->Keyboard[ks] == n) pks->Keyboard[ks] = 0;
359
+ }
360
+ }
361
+ SDL_memset(&_this->Ins[n], 0, sizeof(_this->Ins[0]));
362
+ break;
363
+ }
364
+ }
365
+ }
366
+ }
367
+ if (newsamples < n) newsamples = n;
368
+ samplemap[nmap] = n;
369
+ }
370
+ _this->m_nSamples = newsamples;
371
+ // Reading Volume Envelope
372
+ INSTRUMENTHEADER *penv = _this->Headers[iIns];
373
+ penv->nMidiProgram = pih->type;
374
+ penv->nFadeOut = xmsh.volfade;
375
+ penv->nPan = 128;
376
+ penv->nPPC = 5*12;
377
+ if (xmsh.vtype & 1) penv->dwFlags |= ENV_VOLUME;
378
+ if (xmsh.vtype & 2) penv->dwFlags |= ENV_VOLSUSTAIN;
379
+ if (xmsh.vtype & 4) penv->dwFlags |= ENV_VOLLOOP;
380
+ if (xmsh.ptype & 1) penv->dwFlags |= ENV_PANNING;
381
+ if (xmsh.ptype & 2) penv->dwFlags |= ENV_PANSUSTAIN;
382
+ if (xmsh.ptype & 4) penv->dwFlags |= ENV_PANLOOP;
383
+ if (xmsh.vnum > 12) xmsh.vnum = 12;
384
+ if (xmsh.pnum > 12) xmsh.pnum = 12;
385
+ penv->nVolEnv = xmsh.vnum;
386
+ if (!xmsh.vnum) penv->dwFlags &= ~ENV_VOLUME;
387
+ if (!xmsh.pnum) penv->dwFlags &= ~ENV_PANNING;
388
+ penv->nPanEnv = xmsh.pnum;
389
+ penv->nVolSustainBegin = penv->nVolSustainEnd = xmsh.vsustain;
390
+ if (xmsh.vsustain >= 12) penv->dwFlags &= ~ENV_VOLSUSTAIN;
391
+ penv->nVolLoopStart = xmsh.vloops;
392
+ penv->nVolLoopEnd = xmsh.vloope;
393
+ if (penv->nVolLoopEnd >= 12) penv->nVolLoopEnd = 0;
394
+ if (penv->nVolLoopStart >= penv->nVolLoopEnd) penv->dwFlags &= ~ENV_VOLLOOP;
395
+ penv->nPanSustainBegin = penv->nPanSustainEnd = xmsh.psustain;
396
+ if (xmsh.psustain >= 12) penv->dwFlags &= ~ENV_PANSUSTAIN;
397
+ penv->nPanLoopStart = xmsh.ploops;
398
+ penv->nPanLoopEnd = xmsh.ploope;
399
+ if (penv->nPanLoopEnd >= 12) penv->nPanLoopEnd = 0;
400
+ if (penv->nPanLoopStart >= penv->nPanLoopEnd) penv->dwFlags &= ~ENV_PANLOOP;
401
+ penv->nGlobalVol = 64;
402
+ for (UINT ienv=0; ienv<12; ienv++)
403
+ {
404
+ penv->VolPoints[ienv] = (WORD)xmsh.venv[ienv*2];
405
+ penv->VolEnv[ienv] = (BYTE)xmsh.venv[ienv*2+1];
406
+ penv->PanPoints[ienv] = (WORD)xmsh.penv[ienv*2];
407
+ penv->PanEnv[ienv] = (BYTE)xmsh.penv[ienv*2+1];
408
+ if (ienv)
409
+ {
410
+ if (penv->VolPoints[ienv] < penv->VolPoints[ienv-1])
411
+ {
412
+ penv->VolPoints[ienv] &= 0xFF;
413
+ penv->VolPoints[ienv] += penv->VolPoints[ienv-1] & 0xFF00;
414
+ if (penv->VolPoints[ienv] < penv->VolPoints[ienv-1]) penv->VolPoints[ienv] += 0x100;
415
+ }
416
+ if (penv->PanPoints[ienv] < penv->PanPoints[ienv-1])
417
+ {
418
+ penv->PanPoints[ienv] &= 0xFF;
419
+ penv->PanPoints[ienv] += penv->PanPoints[ienv-1] & 0xFF00;
420
+ if (penv->PanPoints[ienv] < penv->PanPoints[ienv-1]) penv->PanPoints[ienv] += 0x100;
421
+ }
422
+ }
423
+ }
424
+ for (UINT j=0; j<96; j++)
425
+ {
426
+ penv->NoteMap[j+12] = j+1+12;
427
+ if (xmsh.snum[j] < nsamples)
428
+ penv->Keyboard[j+12] = samplemap[xmsh.snum[j]];
429
+ }
430
+ // Reading samples
431
+ for (UINT ins=0; ins<nsamples; ins++)
432
+ {
433
+ if ((dwMemPos + sizeof(xmss) > dwMemLength)
434
+ || (dwMemPos + xmsh.shsize > dwMemLength)) return TRUE;
435
+ SDL_memcpy(&xmss, lpStream+dwMemPos, sizeof(xmss));
436
+ xmss.samplen = bswapLE32(xmss.samplen);
437
+ xmss.loopstart = bswapLE32(xmss.loopstart);
438
+ xmss.looplen = bswapLE32(xmss.looplen);
439
+ dwMemPos += xmsh.shsize;
440
+ flags[ins] = (xmss.type & 0x10) ? RS_PCM16D : RS_PCM8D;
441
+ if (xmss.type & 0x20) flags[ins] = (xmss.type & 0x10) ? RS_STPCM16D : RS_STPCM8D;
442
+ samplesize[ins] = xmss.samplen;
443
+ if (!samplemap[ins]) continue;
444
+ if (xmss.type & 0x10)
445
+ {
446
+ xmss.looplen >>= 1;
447
+ xmss.loopstart >>= 1;
448
+ xmss.samplen >>= 1;
449
+ }
450
+ if (xmss.type & 0x20)
451
+ {
452
+ xmss.looplen >>= 1;
453
+ xmss.loopstart >>= 1;
454
+ xmss.samplen >>= 1;
455
+ }
456
+ if (xmss.samplen > MAX_SAMPLE_LENGTH) xmss.samplen = MAX_SAMPLE_LENGTH;
457
+ if (xmss.loopstart >= xmss.samplen) xmss.type &= ~3;
458
+ xmss.looplen += xmss.loopstart;
459
+ if (xmss.looplen > xmss.samplen) xmss.looplen = xmss.samplen;
460
+ if (!xmss.looplen) xmss.type &= ~3;
461
+ UINT imapsmp = samplemap[ins];
462
+ MODINSTRUMENT *pins = &_this->Ins[imapsmp];
463
+ pins->nLength = (xmss.samplen > MAX_SAMPLE_LENGTH) ? MAX_SAMPLE_LENGTH : xmss.samplen;
464
+ pins->nLoopStart = xmss.loopstart;
465
+ pins->nLoopEnd = xmss.looplen;
466
+ if (pins->nLoopEnd > pins->nLength) pins->nLoopEnd = pins->nLength;
467
+ if (pins->nLoopStart >= pins->nLoopEnd)
468
+ {
469
+ pins->nLoopStart = pins->nLoopEnd = 0;
470
+ }
471
+ if (xmss.type & 3) pins->uFlags |= CHN_LOOP;
472
+ if (xmss.type & 2) pins->uFlags |= CHN_PINGPONGLOOP;
473
+ pins->nVolume = xmss.vol << 2;
474
+ if (pins->nVolume > 256) pins->nVolume = 256;
475
+ pins->nGlobalVol = 64;
476
+ if ((xmss.res == 0xAD) && (!(xmss.type & 0x30)))
477
+ {
478
+ flags[ins] = RS_ADPCM4;
479
+ samplesize[ins] = (samplesize[ins]+1)/2 + 16;
480
+ }
481
+ pins->nFineTune = xmss.finetune;
482
+ pins->RelativeTone = (int)xmss.relnote;
483
+ pins->nPan = xmss.pan;
484
+ pins->uFlags |= CHN_PANNING;
485
+ pins->nVibType = xmsh.vibtype;
486
+ pins->nVibSweep = xmsh.vibsweep;
487
+ pins->nVibDepth = xmsh.vibdepth;
488
+ pins->nVibRate = xmsh.vibrate;
489
+ }
490
+ for (UINT ismpd=0; ismpd<nsamples; ismpd++)
491
+ {
492
+ if ((samplemap[ismpd]) && (samplesize[ismpd]) && (dwMemPos < dwMemLength))
493
+ {
494
+ CSoundFile_ReadSample(_this, &_this->Ins[samplemap[ismpd]], flags[ismpd], (LPSTR)(lpStream + dwMemPos), dwMemLength - dwMemPos);
495
+ }
496
+ dwMemPos += samplesize[ismpd];
497
+ if (dwMemPos >= dwMemLength) break;
498
+ }
499
+ }
500
+ // Read song comments: "TEXT"
501
+ if ((dwMemPos + 8 < dwMemLength) && (bswapLE32(*((DWORD *)(lpStream+dwMemPos))) == 0x74786574))
502
+ {
503
+ UINT len = *((DWORD *)(lpStream+dwMemPos+4));
504
+ dwMemPos += 8;
505
+ if ((dwMemPos + len <= dwMemLength) && (len < 16384))
506
+ {
507
+ dwMemPos += len;
508
+ }
509
+ }
510
+ // Read midi config: "MIDI"
511
+ if ((dwMemPos + 8 < dwMemLength) && (bswapLE32(*((DWORD *)(lpStream+dwMemPos))) == 0x4944494D))
512
+ {
513
+ UINT len = *((DWORD *)(lpStream+dwMemPos+4));
514
+ dwMemPos += 8;
515
+ if (len == sizeof(MODMIDICFG))
516
+ {
517
+ SDL_memcpy(&_this->m_MidiCfg, lpStream+dwMemPos, len);
518
+ _this->m_dwSongFlags |= SONG_EMBEDMIDICFG;
519
+ }
520
+ }
521
+ // Read pattern names: "PNAM"
522
+ if ((dwMemPos + 8 < dwMemLength) && (bswapLE32(*((DWORD *)(lpStream+dwMemPos))) == 0x4d414e50))
523
+ {
524
+ UINT len = *((DWORD *)(lpStream+dwMemPos+4));
525
+ dwMemPos += 8;
526
+ if ((dwMemPos + len <= dwMemLength) && (len <= MAX_PATTERNS*MAX_PATTERNNAME) && (len >= MAX_PATTERNNAME))
527
+ {
528
+ _this->m_lpszPatternNames = (char *) SDL_malloc(len);
529
+ if (_this->m_lpszPatternNames)
530
+ {
531
+ _this->m_nPatternNames = len / MAX_PATTERNNAME;
532
+ SDL_memcpy(_this->m_lpszPatternNames, lpStream+dwMemPos, len);
533
+ }
534
+ dwMemPos += len;
535
+ }
536
+ }
537
+ // Read channel names: "CNAM"
538
+ if ((dwMemPos + 8 < dwMemLength) && (bswapLE32(*((DWORD *)(lpStream+dwMemPos))) == 0x4d414e43))
539
+ {
540
+ UINT len = *((DWORD *)(lpStream+dwMemPos+4));
541
+ dwMemPos += 8;
542
+ if ((dwMemPos + len <= dwMemLength) && (len <= MAX_BASECHANNELS*MAX_CHANNELNAME))
543
+ {
544
+ dwMemPos += len;
545
+ }
546
+ }
547
+ // Read mix plugins information
548
+ if (dwMemPos + 8 < dwMemLength)
549
+ {
550
+ dwMemPos += CSoundFile_LoadMixPlugins(_this, lpStream+dwMemPos, dwMemLength-dwMemPos);
551
+ }
552
+ return TRUE;
553
+ }
554
+