gosu 0.15.2 → 1.1.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (243) hide show
  1. checksums.yaml +4 -4
  2. data/dependencies/SDL/include/SDL.h +138 -0
  3. data/dependencies/SDL/include/SDL_assert.h +293 -0
  4. data/dependencies/SDL/include/SDL_atomic.h +295 -0
  5. data/dependencies/SDL/include/SDL_audio.h +859 -0
  6. data/dependencies/SDL/include/SDL_bits.h +121 -0
  7. data/dependencies/SDL/include/SDL_blendmode.h +123 -0
  8. data/dependencies/SDL/include/SDL_clipboard.h +71 -0
  9. data/dependencies/SDL/include/SDL_config.h +55 -0
  10. data/dependencies/SDL/include/SDL_config_android.h +182 -0
  11. data/dependencies/SDL/include/SDL_config_iphoneos.h +207 -0
  12. data/dependencies/SDL/include/SDL_config_macosx.h +266 -0
  13. data/dependencies/SDL/include/SDL_config_minimal.h +85 -0
  14. data/dependencies/SDL/include/SDL_config_os2.h +188 -0
  15. data/dependencies/SDL/include/SDL_config_pandora.h +135 -0
  16. data/dependencies/SDL/include/SDL_config_psp.h +165 -0
  17. data/dependencies/SDL/include/SDL_config_windows.h +288 -0
  18. data/dependencies/SDL/include/SDL_config_winrt.h +243 -0
  19. data/dependencies/SDL/include/SDL_config_wiz.h +149 -0
  20. data/dependencies/SDL/include/SDL_copying.h +20 -0
  21. data/dependencies/SDL/include/SDL_cpuinfo.h +299 -0
  22. data/dependencies/SDL/include/SDL_egl.h +1676 -0
  23. data/dependencies/SDL/include/SDL_endian.h +263 -0
  24. data/dependencies/SDL/include/SDL_error.h +112 -0
  25. data/dependencies/SDL/include/SDL_events.h +827 -0
  26. data/dependencies/SDL/include/SDL_filesystem.h +136 -0
  27. data/dependencies/SDL/include/SDL_gamecontroller.h +541 -0
  28. data/dependencies/SDL/include/SDL_gesture.h +87 -0
  29. data/dependencies/SDL/include/SDL_haptic.h +1247 -0
  30. data/dependencies/SDL/include/SDL_hints.h +1578 -0
  31. data/dependencies/SDL/include/SDL_joystick.h +499 -0
  32. data/dependencies/SDL/include/SDL_keyboard.h +217 -0
  33. data/dependencies/SDL/include/SDL_keycode.h +351 -0
  34. data/dependencies/SDL/include/SDL_loadso.h +81 -0
  35. data/dependencies/SDL/include/SDL_locale.h +101 -0
  36. data/dependencies/SDL/include/SDL_log.h +211 -0
  37. data/dependencies/SDL/include/SDL_main.h +180 -0
  38. data/dependencies/SDL/include/SDL_messagebox.h +146 -0
  39. data/dependencies/SDL/include/SDL_metal.h +117 -0
  40. data/dependencies/SDL/include/SDL_misc.h +75 -0
  41. data/dependencies/SDL/include/SDL_mouse.h +302 -0
  42. data/dependencies/SDL/include/SDL_mutex.h +251 -0
  43. data/dependencies/SDL/include/SDL_name.h +33 -0
  44. data/dependencies/SDL/include/SDL_opengl.h +2183 -0
  45. data/dependencies/SDL/include/SDL_opengl_glext.h +11180 -0
  46. data/dependencies/SDL/include/SDL_opengles.h +39 -0
  47. data/dependencies/SDL/include/SDL_opengles2.h +52 -0
  48. data/dependencies/SDL/include/SDL_opengles2_gl2.h +621 -0
  49. data/dependencies/SDL/include/SDL_opengles2_gl2ext.h +2050 -0
  50. data/dependencies/SDL/include/SDL_opengles2_gl2platform.h +30 -0
  51. data/dependencies/SDL/include/SDL_opengles2_khrplatform.h +282 -0
  52. data/dependencies/SDL/include/SDL_pixels.h +479 -0
  53. data/dependencies/SDL/include/SDL_platform.h +198 -0
  54. data/dependencies/SDL/include/SDL_power.h +75 -0
  55. data/dependencies/SDL/include/SDL_quit.h +58 -0
  56. data/dependencies/SDL/include/SDL_rect.h +174 -0
  57. data/dependencies/SDL/include/SDL_render.h +1158 -0
  58. data/dependencies/SDL/include/SDL_revision.h +2 -0
  59. data/dependencies/SDL/include/SDL_rwops.h +283 -0
  60. data/dependencies/SDL/include/SDL_scancode.h +413 -0
  61. data/dependencies/SDL/include/SDL_sensor.h +267 -0
  62. data/dependencies/SDL/include/SDL_shape.h +144 -0
  63. data/dependencies/SDL/include/SDL_stdinc.h +647 -0
  64. data/dependencies/SDL/include/SDL_surface.h +563 -0
  65. data/dependencies/SDL/include/SDL_system.h +325 -0
  66. data/dependencies/SDL/include/SDL_syswm.h +354 -0
  67. data/dependencies/SDL/include/SDL_test.h +69 -0
  68. data/dependencies/SDL/include/SDL_test_assert.h +105 -0
  69. data/dependencies/SDL/include/SDL_test_common.h +218 -0
  70. data/dependencies/SDL/include/SDL_test_compare.h +69 -0
  71. data/dependencies/SDL/include/SDL_test_crc32.h +124 -0
  72. data/dependencies/SDL/include/SDL_test_font.h +81 -0
  73. data/dependencies/SDL/include/SDL_test_fuzzer.h +384 -0
  74. data/dependencies/SDL/include/SDL_test_harness.h +134 -0
  75. data/dependencies/SDL/include/SDL_test_images.h +78 -0
  76. data/dependencies/SDL/include/SDL_test_log.h +67 -0
  77. data/dependencies/SDL/include/SDL_test_md5.h +129 -0
  78. data/dependencies/SDL/include/SDL_test_memory.h +63 -0
  79. data/dependencies/SDL/include/SDL_test_random.h +115 -0
  80. data/dependencies/SDL/include/SDL_thread.h +366 -0
  81. data/dependencies/SDL/include/SDL_timer.h +115 -0
  82. data/dependencies/SDL/include/SDL_touch.h +102 -0
  83. data/dependencies/SDL/include/SDL_types.h +29 -0
  84. data/dependencies/SDL/include/SDL_version.h +162 -0
  85. data/dependencies/SDL/include/SDL_video.h +1282 -0
  86. data/dependencies/SDL/include/SDL_vulkan.h +276 -0
  87. data/dependencies/SDL/include/begin_code.h +166 -0
  88. data/dependencies/SDL/include/close_code.h +40 -0
  89. data/dependencies/SDL/lib/x64/libSDL2.dll.a +0 -0
  90. data/dependencies/SDL/lib/x86/libSDL2.dll.a +0 -0
  91. data/dependencies/SDL_sound/SDL_sound.c +795 -0
  92. data/dependencies/SDL_sound/SDL_sound.h +725 -0
  93. data/dependencies/SDL_sound/SDL_sound_aiff.c +537 -0
  94. data/dependencies/SDL_sound/SDL_sound_au.c +352 -0
  95. data/dependencies/SDL_sound/SDL_sound_coreaudio.c +747 -0
  96. data/dependencies/SDL_sound/SDL_sound_flac.c +182 -0
  97. data/dependencies/SDL_sound/SDL_sound_internal.h +304 -0
  98. data/dependencies/SDL_sound/SDL_sound_modplug.c +228 -0
  99. data/dependencies/SDL_sound/SDL_sound_mp3.c +184 -0
  100. data/dependencies/SDL_sound/SDL_sound_raw.c +164 -0
  101. data/dependencies/SDL_sound/SDL_sound_shn.c +1309 -0
  102. data/dependencies/SDL_sound/SDL_sound_voc.c +550 -0
  103. data/dependencies/SDL_sound/SDL_sound_vorbis.c +223 -0
  104. data/dependencies/SDL_sound/SDL_sound_wav.c +783 -0
  105. data/dependencies/SDL_sound/dr_flac.h +5906 -0
  106. data/dependencies/SDL_sound/dr_mp3.h +2832 -0
  107. data/dependencies/SDL_sound/libmodplug/fastmix.c +1748 -0
  108. data/dependencies/SDL_sound/libmodplug/libmodplug.h +1001 -0
  109. data/dependencies/SDL_sound/libmodplug/load_669.c +188 -0
  110. data/dependencies/SDL_sound/libmodplug/load_abc.c +4725 -0
  111. data/dependencies/SDL_sound/libmodplug/load_amf.c +403 -0
  112. data/dependencies/SDL_sound/libmodplug/load_ams.c +587 -0
  113. data/dependencies/SDL_sound/libmodplug/load_dbm.c +357 -0
  114. data/dependencies/SDL_sound/libmodplug/load_dmf.c +531 -0
  115. data/dependencies/SDL_sound/libmodplug/load_dsm.c +232 -0
  116. data/dependencies/SDL_sound/libmodplug/load_far.c +253 -0
  117. data/dependencies/SDL_sound/libmodplug/load_it.c +796 -0
  118. data/dependencies/SDL_sound/libmodplug/load_mdl.c +488 -0
  119. data/dependencies/SDL_sound/libmodplug/load_med.c +757 -0
  120. data/dependencies/SDL_sound/libmodplug/load_mid.c +1405 -0
  121. data/dependencies/SDL_sound/libmodplug/load_mod.c +269 -0
  122. data/dependencies/SDL_sound/libmodplug/load_mt2.c +546 -0
  123. data/dependencies/SDL_sound/libmodplug/load_mtm.c +142 -0
  124. data/dependencies/SDL_sound/libmodplug/load_okt.c +192 -0
  125. data/dependencies/SDL_sound/libmodplug/load_pat.c +1143 -0
  126. data/dependencies/SDL_sound/libmodplug/load_pat.h +25 -0
  127. data/dependencies/SDL_sound/libmodplug/load_psm.c +350 -0
  128. data/dependencies/SDL_sound/libmodplug/load_ptm.c +204 -0
  129. data/dependencies/SDL_sound/libmodplug/load_s3m.c +325 -0
  130. data/dependencies/SDL_sound/libmodplug/load_stm.c +180 -0
  131. data/dependencies/SDL_sound/libmodplug/load_ult.c +206 -0
  132. data/dependencies/SDL_sound/libmodplug/load_umx.c +51 -0
  133. data/dependencies/SDL_sound/libmodplug/load_xm.c +554 -0
  134. data/dependencies/SDL_sound/libmodplug/mmcmp.c +382 -0
  135. data/dependencies/SDL_sound/libmodplug/modplug.c +170 -0
  136. data/dependencies/SDL_sound/libmodplug/modplug.h +90 -0
  137. data/dependencies/SDL_sound/libmodplug/snd_dsp.c +301 -0
  138. data/dependencies/SDL_sound/libmodplug/snd_flt.c +63 -0
  139. data/dependencies/SDL_sound/libmodplug/snd_fx.c +2350 -0
  140. data/dependencies/SDL_sound/libmodplug/sndfile.c +1169 -0
  141. data/dependencies/SDL_sound/libmodplug/sndmix.c +1034 -0
  142. data/dependencies/SDL_sound/libmodplug/tables.h +371 -0
  143. data/{src/stb_vorbis.c → dependencies/SDL_sound/stb_vorbis.h} +143 -78
  144. data/dependencies/al_soft/AL/al.h +655 -0
  145. data/dependencies/al_soft/AL/alc.h +270 -0
  146. data/dependencies/al_soft/AL/alext.h +585 -0
  147. data/dependencies/al_soft/AL/efx-creative.h +3 -0
  148. data/dependencies/al_soft/AL/efx-presets.h +402 -0
  149. data/dependencies/al_soft/AL/efx.h +762 -0
  150. data/dependencies/al_soft/x64/libOpenAL32.dll.a +0 -0
  151. data/dependencies/al_soft/x86/libOpenAL32.dll.a +0 -0
  152. data/{src → dependencies/stb}/stb_image.h +330 -127
  153. data/{src → dependencies/stb}/stb_image_write.h +156 -85
  154. data/{src → dependencies/stb}/stb_truetype.h +192 -69
  155. data/{src → dependencies/utf8proc}/utf8proc.c +0 -0
  156. data/{src → dependencies/utf8proc}/utf8proc.h +0 -0
  157. data/{src → dependencies/utf8proc}/utf8proc_data.h +0 -0
  158. data/ext/gosu/extconf.rb +53 -39
  159. data/{Gosu → include/Gosu}/Audio.hpp +6 -8
  160. data/include/Gosu/Bitmap.hpp +100 -0
  161. data/{Gosu → include/Gosu}/Buttons.hpp +104 -44
  162. data/{Gosu → include/Gosu}/Color.hpp +0 -0
  163. data/{Gosu → include/Gosu}/Directories.hpp +0 -0
  164. data/{Gosu → include/Gosu}/Font.hpp +1 -1
  165. data/{Gosu → include/Gosu}/Fwd.hpp +0 -5
  166. data/{Gosu → include/Gosu}/Gosu.hpp +0 -0
  167. data/{Gosu → include/Gosu}/Graphics.hpp +0 -0
  168. data/{Gosu → include/Gosu}/GraphicsBase.hpp +0 -0
  169. data/{Gosu → include/Gosu}/IO.hpp +0 -0
  170. data/{Gosu → include/Gosu}/Image.hpp +7 -6
  171. data/{Gosu → include/Gosu}/ImageData.hpp +0 -0
  172. data/{Gosu → include/Gosu}/Input.hpp +39 -51
  173. data/{Gosu → include/Gosu}/Inspection.hpp +0 -0
  174. data/{Gosu → include/Gosu}/Math.hpp +0 -0
  175. data/{Gosu → include/Gosu}/Platform.hpp +0 -0
  176. data/{Gosu → include/Gosu}/Text.hpp +0 -0
  177. data/{Gosu → include/Gosu}/TextInput.hpp +0 -0
  178. data/{Gosu → include/Gosu}/Timing.hpp +0 -0
  179. data/{Gosu → include/Gosu}/Utility.hpp +15 -4
  180. data/{Gosu → include/Gosu}/Version.hpp +3 -3
  181. data/{Gosu → include/Gosu}/Window.hpp +46 -34
  182. data/lib/OpenAL32.dll +0 -0
  183. data/lib/SDL2.dll +0 -0
  184. data/lib/gosu.rb +0 -3
  185. data/lib/gosu/patches.rb +0 -23
  186. data/lib/gosu/preview.rb +1 -3
  187. data/lib/gosu/swig_patches.rb +14 -12
  188. data/lib64/OpenAL32.dll +0 -0
  189. data/lib64/SDL2.dll +0 -0
  190. data/rdoc/gosu.rb +112 -23
  191. data/src/Audio.cpp +50 -224
  192. data/src/AudioFile.hpp +20 -37
  193. data/src/AudioFileAudioToolbox.cpp +237 -0
  194. data/src/AudioFileSDLSound.cpp +147 -0
  195. data/src/AudioImpl.cpp +3 -12
  196. data/src/AudioImpl.hpp +3 -1
  197. data/src/Bitmap.cpp +85 -83
  198. data/src/BitmapIO.cpp +52 -58
  199. data/src/Font.cpp +3 -1
  200. data/src/Graphics.cpp +7 -4
  201. data/src/Image.cpp +13 -16
  202. data/src/Input.cpp +412 -164
  203. data/src/LargeImageData.cpp +1 -1
  204. data/src/MarkupParser.cpp +2 -1
  205. data/src/Resolution.cpp +8 -8
  206. data/src/RubyGosu.cxx +1017 -196
  207. data/src/RubyGosu.h +4 -2
  208. data/src/TexChunk.cpp +1 -1
  209. data/src/TextBuilder.cpp +3 -1
  210. data/src/Texture.cpp +1 -1
  211. data/src/TrueTypeFont.cpp +1 -1
  212. data/src/TrueTypeFontWin.cpp +3 -3
  213. data/src/Utility.cpp +11 -7
  214. data/src/Window.cpp +90 -62
  215. data/src/WindowUIKit.cpp +21 -9
  216. metadata +194 -65
  217. data/Gosu/AutoLink.hpp +0 -14
  218. data/Gosu/Bitmap.hpp +0 -113
  219. data/Gosu/Channel.h +0 -25
  220. data/Gosu/Color.h +0 -38
  221. data/Gosu/Font.h +0 -36
  222. data/Gosu/Gosu.h +0 -79
  223. data/Gosu/Image.h +0 -54
  224. data/Gosu/Sample.h +0 -19
  225. data/Gosu/Song.h +0 -24
  226. data/Gosu/TextInput.h +0 -30
  227. data/Gosu/Window.h +0 -61
  228. data/lib/gosu/zen.rb +0 -89
  229. data/src/AudioToolboxFile.hpp +0 -210
  230. data/src/ChannelWrapper.cpp +0 -50
  231. data/src/ColorWrapper.cpp +0 -126
  232. data/src/Constants.cpp +0 -287
  233. data/src/FontWrapper.cpp +0 -74
  234. data/src/GosuWrapper.cpp +0 -232
  235. data/src/ImageWrapper.cpp +0 -168
  236. data/src/MPEGFile.hpp +0 -90
  237. data/src/OggFile.hpp +0 -92
  238. data/src/SampleWrapper.cpp +0 -30
  239. data/src/SndFile.hpp +0 -174
  240. data/src/SongWrapper.cpp +0 -52
  241. data/src/TextInputWrapper.cpp +0 -101
  242. data/src/WinMain.cpp +0 -64
  243. data/src/WindowWrapper.cpp +0 -289
@@ -0,0 +1,269 @@
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
+ #include "tables.h"
10
+
11
+ //////////////////////////////////////////////////////////
12
+ // ProTracker / NoiseTracker MOD/NST file support
13
+
14
+ void CSoundFile_ConvertModCommand(CSoundFile *_this, MODCOMMAND *m)
15
+ //-----------------------------------------------------
16
+ {
17
+ UINT command = m->command, param = m->param;
18
+
19
+ switch(command)
20
+ {
21
+ case 0x00: if (param) command = CMD_ARPEGGIO; break;
22
+ case 0x01: command = CMD_PORTAMENTOUP; break;
23
+ case 0x02: command = CMD_PORTAMENTODOWN; break;
24
+ case 0x03: command = CMD_TONEPORTAMENTO; break;
25
+ case 0x04: command = CMD_VIBRATO; break;
26
+ case 0x05: command = CMD_TONEPORTAVOL; if (param & 0xF0) param &= 0xF0; break;
27
+ case 0x06: command = CMD_VIBRATOVOL; if (param & 0xF0) param &= 0xF0; break;
28
+ case 0x07: command = CMD_TREMOLO; break;
29
+ case 0x08: command = CMD_PANNING8; break;
30
+ case 0x09: command = CMD_OFFSET; break;
31
+ case 0x0A: command = CMD_VOLUMESLIDE; if (param & 0xF0) param &= 0xF0; break;
32
+ case 0x0B: command = CMD_POSITIONJUMP; break;
33
+ case 0x0C: command = CMD_VOLUME; break;
34
+ case 0x0D: command = CMD_PATTERNBREAK; param = ((param >> 4) * 10) + (param & 0x0F); break;
35
+ case 0x0E: command = CMD_MODCMDEX; break;
36
+ case 0x0F: command = (param <= (UINT)((_this->m_nType & (MOD_TYPE_XM|MOD_TYPE_MT2)) ? 0x1F : 0x20)) ? CMD_SPEED : CMD_TEMPO;
37
+ if ((param == 0xFF) && (_this->m_nSamples == 15)) command = 0; break;
38
+ // Extension for XM extended effects
39
+ case 'G' - 55: command = CMD_GLOBALVOLUME; break;
40
+ case 'H' - 55: command = CMD_GLOBALVOLSLIDE; if (param & 0xF0) param &= 0xF0; break;
41
+ case 'K' - 55: command = CMD_KEYOFF; break;
42
+ case 'L' - 55: command = CMD_SETENVPOSITION; break;
43
+ case 'M' - 55: command = CMD_CHANNELVOLUME; break;
44
+ case 'N' - 55: command = CMD_CHANNELVOLSLIDE; break;
45
+ case 'P' - 55: command = CMD_PANNINGSLIDE; if (param & 0xF0) param &= 0xF0; break;
46
+ case 'R' - 55: command = CMD_RETRIG; break;
47
+ case 'T' - 55: command = CMD_TREMOR; break;
48
+ case 'X' - 55: command = CMD_XFINEPORTAUPDOWN; break;
49
+ case 'Y' - 55: command = CMD_PANBRELLO; break;
50
+ case 'Z' - 55: command = CMD_MIDI; break;
51
+ default: command = 0;
52
+ }
53
+ m->command = command;
54
+ m->param = param;
55
+ }
56
+
57
+
58
+ #pragma pack(1)
59
+
60
+ typedef struct _MODSAMPLE
61
+ {
62
+ CHAR name[22];
63
+ WORD length;
64
+ BYTE finetune;
65
+ BYTE volume;
66
+ WORD loopstart;
67
+ WORD looplen;
68
+ } MODSAMPLE, *PMODSAMPLE;
69
+
70
+ typedef struct _MODMAGIC
71
+ {
72
+ BYTE nOrders;
73
+ BYTE nRestartPos;
74
+ BYTE Orders[128];
75
+ char Magic[4]; // changed from CHAR
76
+ } MODMAGIC, *PMODMAGIC;
77
+
78
+ #pragma pack()
79
+
80
+ static BOOL IsMagic(LPCSTR s1, LPCSTR s2)
81
+ {
82
+ return ((*(DWORD *)s1) == (*(DWORD *)s2)) ? TRUE : FALSE;
83
+ }
84
+
85
+
86
+ BOOL CSoundFile_ReadMod(CSoundFile *_this, const BYTE *lpStream, DWORD dwMemLength)
87
+ //---------------------------------------------------------------
88
+ {
89
+ char s[1024]; // changed from CHAR
90
+ DWORD dwMemPos, dwTotalSampleLen;
91
+ PMODMAGIC pMagic;
92
+ UINT nErr;
93
+
94
+ if ((!lpStream) || (dwMemLength < 0x600)) return FALSE;
95
+ dwMemPos = 20;
96
+ _this->m_nSamples = 31;
97
+ _this->m_nChannels = 4;
98
+ pMagic = (PMODMAGIC)(lpStream+dwMemPos+sizeof(MODSAMPLE)*31);
99
+ // Check Mod Magic
100
+ SDL_memcpy(s, pMagic->Magic, 4);
101
+ if ((IsMagic(s, "M.K.")) || (IsMagic(s, "M!K!"))
102
+ || (IsMagic(s, "M&K!")) || (IsMagic(s, "N.T."))) _this->m_nChannels = 4; else
103
+ if ((IsMagic(s, "CD81")) || (IsMagic(s, "OKTA"))) _this->m_nChannels = 8; else
104
+ if ((s[0]=='F') && (s[1]=='L') && (s[2]=='T') && (s[3]>='4') && (s[3]<='9')) _this->m_nChannels = s[3] - '0'; else
105
+ if ((s[0]>='2') && (s[0]<='9') && (s[1]=='C') && (s[2]=='H') && (s[3]=='N')) _this->m_nChannels = s[0] - '0'; else
106
+ if ((s[0]=='1') && (s[1]>='0') && (s[1]<='9') && (s[2]=='C') && (s[3]=='H')) _this->m_nChannels = s[1] - '0' + 10; else
107
+ if ((s[0]=='2') && (s[1]>='0') && (s[1]<='9') && (s[2]=='C') && (s[3]=='H')) _this->m_nChannels = s[1] - '0' + 20; else
108
+ if ((s[0]=='3') && (s[1]>='0') && (s[1]<='2') && (s[2]=='C') && (s[3]=='H')) _this->m_nChannels = s[1] - '0' + 30; else
109
+ if ((s[0]=='T') && (s[1]=='D') && (s[2]=='Z') && (s[3]>='4') && (s[3]<='9')) _this->m_nChannels = s[3] - '0'; else
110
+ if (IsMagic(s,"16CN")) _this->m_nChannels = 16; else
111
+ if (IsMagic(s,"32CN")) _this->m_nChannels = 32; else _this->m_nSamples = 15;
112
+ // Load Samples
113
+ nErr = 0;
114
+ dwTotalSampleLen = 0;
115
+ for (UINT i=1; i<=_this->m_nSamples; i++)
116
+ {
117
+ PMODSAMPLE pms = (PMODSAMPLE)(lpStream+dwMemPos);
118
+ MODINSTRUMENT *psmp = &_this->Ins[i];
119
+ UINT loopstart, looplen;
120
+
121
+ psmp->uFlags = 0;
122
+ psmp->nLength = bswapBE16(pms->length)*2;
123
+ dwTotalSampleLen += psmp->nLength;
124
+ psmp->nFineTune = MOD2XMFineTune(pms->finetune & 0x0F);
125
+ psmp->nVolume = 4*pms->volume;
126
+ if (psmp->nVolume > 256) { psmp->nVolume = 256; nErr++; }
127
+ psmp->nGlobalVol = 64;
128
+ psmp->nPan = 128;
129
+ loopstart = bswapBE16(pms->loopstart)*2;
130
+ looplen = bswapBE16(pms->looplen)*2;
131
+ // Fix loops
132
+ if ((looplen > 2) && (loopstart+looplen > psmp->nLength)
133
+ && (loopstart/2+looplen <= psmp->nLength))
134
+ {
135
+ loopstart /= 2;
136
+ }
137
+ psmp->nLoopStart = loopstart;
138
+ psmp->nLoopEnd = loopstart + looplen;
139
+ if (psmp->nLength < 4) psmp->nLength = 0;
140
+ if (psmp->nLength)
141
+ {
142
+ if (psmp->nLoopStart >= psmp->nLength) { psmp->nLoopStart = psmp->nLength-1; }
143
+ if (psmp->nLoopEnd > psmp->nLength) { psmp->nLoopEnd = psmp->nLength; }
144
+
145
+ if ((psmp->nLoopStart > psmp->nLoopEnd) || (psmp->nLoopEnd <= 8)
146
+ || (psmp->nLoopEnd - psmp->nLoopStart <= 4))
147
+ {
148
+ psmp->nLoopStart = 0;
149
+ psmp->nLoopEnd = 0;
150
+ }
151
+ if (psmp->nLoopEnd > psmp->nLoopStart)
152
+ {
153
+ psmp->uFlags |= CHN_LOOP;
154
+ }
155
+ }
156
+ dwMemPos += sizeof(MODSAMPLE);
157
+ }
158
+ if ((_this->m_nSamples == 15) && (dwTotalSampleLen > dwMemLength * 4)) return FALSE;
159
+ pMagic = (PMODMAGIC)(lpStream+dwMemPos);
160
+ dwMemPos += sizeof(MODMAGIC);
161
+ if (_this->m_nSamples == 15) dwMemPos -= 4;
162
+ SDL_memset(_this->Order, 0,sizeof(_this->Order));
163
+ SDL_memcpy(_this->Order, pMagic->Orders, 128);
164
+
165
+ UINT nbp, nbpbuggy, nbpbuggy2, norders;
166
+
167
+ norders = pMagic->nOrders;
168
+ if ((!norders) || (norders > 0x80))
169
+ {
170
+ norders = 0x80;
171
+ while ((norders > 1) && (!_this->Order[norders-1])) norders--;
172
+ }
173
+ nbpbuggy = 0;
174
+ nbpbuggy2 = 0;
175
+ nbp = 0;
176
+ for (UINT iord=0; iord<128; iord++)
177
+ {
178
+ UINT i = _this->Order[iord];
179
+ if ((i < 0x80) && (nbp <= i))
180
+ {
181
+ nbp = i+1;
182
+ if (iord<norders) nbpbuggy = nbp;
183
+ }
184
+ if (i >= nbpbuggy2) nbpbuggy2 = i+1;
185
+ }
186
+ for (UINT iend=norders; iend<MAX_ORDERS; iend++) _this->Order[iend] = 0xFF;
187
+ norders--;
188
+ _this->m_nRestartPos = pMagic->nRestartPos;
189
+ if (_this->m_nRestartPos >= 0x78) _this->m_nRestartPos = 0;
190
+ if (_this->m_nRestartPos + 1 >= (UINT)norders) _this->m_nRestartPos = 0;
191
+ if (!nbp) return FALSE;
192
+ DWORD dwWowTest = dwTotalSampleLen+dwMemPos;
193
+ if ((IsMagic(pMagic->Magic, "M.K.")) && (dwWowTest + nbp*8*256 == dwMemLength)) _this->m_nChannels = 8;
194
+ if ((nbp != nbpbuggy) && (dwWowTest + nbp*_this->m_nChannels*256 != dwMemLength))
195
+ {
196
+ if (dwWowTest + nbpbuggy*_this->m_nChannels*256 == dwMemLength) nbp = nbpbuggy;
197
+ else nErr += 8;
198
+ } else
199
+ if ((nbpbuggy2 > nbp) && (dwWowTest + nbpbuggy2*_this->m_nChannels*256 == dwMemLength))
200
+ {
201
+ nbp = nbpbuggy2;
202
+ }
203
+ if ((dwWowTest < 0x600) || (dwWowTest > dwMemLength)) nErr += 8;
204
+ if ((_this->m_nSamples == 15) && (nErr >= 16)) return FALSE;
205
+ // Default settings
206
+ _this->m_nType = MOD_TYPE_MOD;
207
+ _this->m_nDefaultSpeed = 6;
208
+ _this->m_nDefaultTempo = 125;
209
+ _this->m_nMinPeriod = 14 << 2;
210
+ _this->m_nMaxPeriod = 3424 << 2;
211
+ // Setting channels pan
212
+ for (UINT ich=0; ich<_this->m_nChannels; ich++)
213
+ {
214
+ _this->ChnSettings[ich].nVolume = 64;
215
+ if (_this->gdwSoundSetup & SNDMIX_MAXDEFAULTPAN)
216
+ _this->ChnSettings[ich].nPan = (((ich&3)==1) || ((ich&3)==2)) ? 256 : 0;
217
+ else
218
+ _this->ChnSettings[ich].nPan = (((ich&3)==1) || ((ich&3)==2)) ? 0xC0 : 0x40;
219
+ }
220
+ // Reading channels
221
+ for (UINT ipat=0; ipat<nbp; ipat++)
222
+ {
223
+ if (ipat < MAX_PATTERNS)
224
+ {
225
+ if ((_this->Patterns[ipat] = CSoundFile_AllocatePattern(64, _this->m_nChannels)) == NULL) break;
226
+ _this->PatternSize[ipat] = 64;
227
+ if (dwMemPos + _this->m_nChannels*256 >= dwMemLength) break;
228
+ MODCOMMAND *m = _this->Patterns[ipat];
229
+ LPCBYTE p = lpStream + dwMemPos;
230
+ for (UINT j=_this->m_nChannels*64; j; m++,p+=4,j--)
231
+ {
232
+ BYTE A0=p[0], A1=p[1], A2=p[2], A3=p[3];
233
+ UINT n = ((((UINT)A0 & 0x0F) << 8) | (A1));
234
+ if ((n) && (n != 0xFFF)) m->note = CSoundFile_GetNoteFromPeriod(_this, n << 2);
235
+ m->instr = ((UINT)A2 >> 4) | (A0 & 0x10);
236
+ m->command = A2 & 0x0F;
237
+ m->param = A3;
238
+ if ((m->command) || (m->param)) CSoundFile_ConvertModCommand(_this, m);
239
+ }
240
+ }
241
+ dwMemPos += _this->m_nChannels*256;
242
+ }
243
+ // Reading instruments
244
+ DWORD dwErrCheck = 0;
245
+ for (UINT ismp=1; ismp<=_this->m_nSamples; ismp++) if (_this->Ins[ismp].nLength)
246
+ {
247
+ LPSTR p = (LPSTR)(lpStream+dwMemPos);
248
+ UINT flags = 0;
249
+ if (dwMemPos + 5 >= dwMemLength) break;
250
+ if (!SDL_strncasecmp(p, "ADPCM", 5))
251
+ {
252
+ flags = 3;
253
+ p += 5;
254
+ dwMemPos += 5;
255
+ }
256
+ DWORD dwSize = CSoundFile_ReadSample(_this, &_this->Ins[ismp], flags, p, dwMemLength - dwMemPos);
257
+ if (dwSize)
258
+ {
259
+ dwMemPos += dwSize;
260
+ dwErrCheck++;
261
+ }
262
+ }
263
+ #ifdef MODPLUG_TRACKER
264
+ return TRUE;
265
+ #else
266
+ return (dwErrCheck) ? TRUE : FALSE;
267
+ #endif
268
+ }
269
+
@@ -0,0 +1,546 @@
1
+ #include "libmodplug.h"
2
+
3
+ #pragma pack(1)
4
+
5
+ typedef struct _MT2FILEHEADER
6
+ {
7
+ DWORD dwMT20; // 0x3032544D "MT20"
8
+ DWORD dwSpecial;
9
+ WORD wVersion;
10
+ CHAR szTrackerName[32]; // "MadTracker 2.0"
11
+ CHAR szSongName[64];
12
+ WORD nOrders;
13
+ WORD wRestart;
14
+ WORD wPatterns;
15
+ WORD wChannels;
16
+ WORD wSamplesPerTick;
17
+ BYTE bTicksPerLine;
18
+ BYTE bLinesPerBeat;
19
+ DWORD fulFlags; // b0=packed patterns
20
+ WORD wInstruments;
21
+ WORD wSamples;
22
+ BYTE Orders[256];
23
+ } MT2FILEHEADER;
24
+
25
+ typedef struct _MT2PATTERN
26
+ {
27
+ WORD wLines;
28
+ DWORD wDataLen;
29
+ } MT2PATTERN;
30
+
31
+ typedef struct _MT2COMMAND
32
+ {
33
+ BYTE note; // 0=nothing, 97=note off
34
+ BYTE instr;
35
+ BYTE vol;
36
+ BYTE pan;
37
+ BYTE fxcmd;
38
+ BYTE fxparam1;
39
+ BYTE fxparam2;
40
+ } MT2COMMAND;
41
+
42
+ typedef struct _MT2DRUMSDATA
43
+ {
44
+ WORD wDrumPatterns;
45
+ WORD wDrumSamples[8];
46
+ BYTE DrumPatternOrder[256];
47
+ } MT2DRUMSDATA;
48
+
49
+ typedef struct _MT2AUTOMATION
50
+ {
51
+ DWORD dwFlags;
52
+ DWORD dwEffectId;
53
+ DWORD nEnvPoints;
54
+ } MT2AUTOMATION;
55
+
56
+ typedef struct _MT2INSTRUMENT
57
+ {
58
+ DWORD dwDataLen;
59
+ WORD wSamples;
60
+ BYTE GroupsMapping[96];
61
+ BYTE bVibType;
62
+ BYTE bVibSweep;
63
+ BYTE bVibDepth;
64
+ BYTE bVibRate;
65
+ WORD wFadeOut;
66
+ WORD wNNA;
67
+ WORD wInstrFlags;
68
+ WORD wEnvFlags1;
69
+ WORD wEnvFlags2;
70
+ } MT2INSTRUMENT;
71
+
72
+ typedef struct _MT2ENVELOPE
73
+ {
74
+ BYTE nFlags;
75
+ BYTE nPoints;
76
+ BYTE nSustainPos;
77
+ BYTE nLoopStart;
78
+ BYTE nLoopEnd;
79
+ BYTE bReserved[3];
80
+ BYTE EnvData[64];
81
+ } MT2ENVELOPE;
82
+
83
+ typedef struct _MT2SYNTH
84
+ {
85
+ BYTE nSynthId;
86
+ BYTE nFxId;
87
+ WORD wCutOff;
88
+ BYTE nResonance;
89
+ BYTE nAttack;
90
+ BYTE nDecay;
91
+ BYTE bReserved[25];
92
+ } MT2SYNTH;
93
+
94
+ typedef struct _MT2SAMPLE
95
+ {
96
+ DWORD dwDataLen;
97
+ DWORD dwLength;
98
+ DWORD dwFrequency;
99
+ BYTE nQuality;
100
+ BYTE nChannels;
101
+ BYTE nFlags;
102
+ BYTE nLoop;
103
+ DWORD dwLoopStart;
104
+ DWORD dwLoopEnd;
105
+ WORD wVolume;
106
+ BYTE nPan;
107
+ BYTE nBaseNote;
108
+ WORD wSamplesPerBeat;
109
+ } MT2SAMPLE;
110
+
111
+ typedef struct _MT2GROUP
112
+ {
113
+ BYTE nSmpNo;
114
+ BYTE nVolume; // 0-128
115
+ BYTE nFinePitch;
116
+ BYTE Reserved[5];
117
+ } MT2GROUP;
118
+
119
+ #pragma pack()
120
+
121
+
122
+ static VOID ConvertMT2Command(CSoundFile *that, MODCOMMAND *m, const MT2COMMAND *p)
123
+ //---------------------------------------------------------------------------
124
+ {
125
+ // Note
126
+ m->note = 0;
127
+ if (p->note) m->note = (p->note > 96) ? 0xFF : p->note+12;
128
+ // Instrument
129
+ m->instr = p->instr;
130
+ // Volume Column
131
+ if ((p->vol >= 0x10) && (p->vol <= 0x90))
132
+ {
133
+ m->volcmd = VOLCMD_VOLUME;
134
+ m->vol = (p->vol - 0x10) >> 1;
135
+ } else
136
+ if ((p->vol >= 0xA0) && (p->vol <= 0xAF))
137
+ {
138
+ m->volcmd = VOLCMD_VOLSLIDEDOWN;
139
+ m->vol = (p->vol & 0x0f);
140
+ } else
141
+ if ((p->vol >= 0xB0) && (p->vol <= 0xBF))
142
+ {
143
+ m->volcmd = VOLCMD_VOLSLIDEUP;
144
+ m->vol = (p->vol & 0x0f);
145
+ } else
146
+ if ((p->vol >= 0xC0) && (p->vol <= 0xCF))
147
+ {
148
+ m->volcmd = VOLCMD_FINEVOLDOWN;
149
+ m->vol = (p->vol & 0x0f);
150
+ } else
151
+ if ((p->vol >= 0xD0) && (p->vol <= 0xDF))
152
+ {
153
+ m->volcmd = VOLCMD_FINEVOLUP;
154
+ m->vol = (p->vol & 0x0f);
155
+ } else
156
+ {
157
+ m->volcmd = 0;
158
+ m->vol = 0;
159
+ }
160
+ // Effects
161
+ m->command = 0;
162
+ m->param = 0;
163
+ if ((p->fxcmd) || (p->fxparam1) || (p->fxparam2))
164
+ {
165
+ if (!p->fxcmd)
166
+ {
167
+ m->command = p->fxparam2;
168
+ m->param = p->fxparam1;
169
+ CSoundFile_ConvertModCommand(that, m);
170
+ } else
171
+ {
172
+ // TODO: MT2 Effects
173
+ }
174
+ }
175
+ }
176
+
177
+
178
+ BOOL CSoundFile_ReadMT2(CSoundFile *_this, LPCBYTE lpStream, DWORD dwMemLength)
179
+ //-----------------------------------------------------------
180
+ {
181
+ const MT2FILEHEADER *pfh = (MT2FILEHEADER *)lpStream;
182
+ DWORD dwMemPos, dwDrumDataPos, dwExtraDataPos;
183
+ UINT nDrumDataLen, nExtraDataLen;
184
+ const MT2DRUMSDATA *pdd;
185
+ const MT2INSTRUMENT *InstrMap[255];
186
+ const MT2SAMPLE *SampleMap[256];
187
+
188
+ if ((!lpStream) || (dwMemLength < sizeof(MT2FILEHEADER))
189
+ || (pfh->dwMT20 != 0x3032544D)
190
+ || (pfh->wVersion < 0x0200) || (pfh->wVersion >= 0x0300)
191
+ || (pfh->wChannels < 4) || (pfh->wChannels > 64)) return FALSE;
192
+ pdd = NULL;
193
+ _this->m_nType = MOD_TYPE_MT2;
194
+ _this->m_nChannels = pfh->wChannels;
195
+ _this->m_nRestartPos = pfh->wRestart;
196
+ _this->m_nDefaultSpeed = pfh->bTicksPerLine;
197
+ _this->m_nDefaultTempo = 125;
198
+ if ((pfh->wSamplesPerTick > 100) && (pfh->wSamplesPerTick < 5000))
199
+ {
200
+ _this->m_nDefaultTempo = 110250 / pfh->wSamplesPerTick;
201
+ }
202
+ for (UINT iOrd=0; iOrd<MAX_ORDERS; iOrd++)
203
+ {
204
+ _this->Order[iOrd] = (BYTE)((iOrd < pfh->nOrders) ? pfh->Orders[iOrd] : 0xFF);
205
+ }
206
+ dwMemPos = sizeof(MT2FILEHEADER);
207
+ nDrumDataLen = *(WORD *)(lpStream + dwMemPos);
208
+ dwDrumDataPos = dwMemPos + 2;
209
+ if (nDrumDataLen >= 2) pdd = (MT2DRUMSDATA *)(lpStream+dwDrumDataPos);
210
+ dwMemPos += 2 + nDrumDataLen;
211
+ if (dwMemPos >= dwMemLength-12) return TRUE;
212
+ if (!*(DWORD *)(lpStream+dwMemPos)) dwMemPos += 4;
213
+ if (!*(DWORD *)(lpStream+dwMemPos)) dwMemPos += 4;
214
+ nExtraDataLen = *(DWORD *)(lpStream+dwMemPos);
215
+ dwExtraDataPos = dwMemPos + 4;
216
+ dwMemPos += 4;
217
+ if (dwMemPos + nExtraDataLen >= dwMemLength) return TRUE;
218
+ while (dwMemPos+8 < dwExtraDataPos + nExtraDataLen)
219
+ {
220
+ DWORD dwId = *(DWORD *)(lpStream+dwMemPos);
221
+ DWORD dwLen = *(DWORD *)(lpStream+dwMemPos+4);
222
+ dwMemPos += 8;
223
+ if (dwMemPos + dwLen > dwMemLength) return TRUE;
224
+ switch(dwId)
225
+ {
226
+ // MSG
227
+ case 0x0047534D:
228
+ break;
229
+ // SUM -> author name (or "Unregistered")
230
+ // TMAP
231
+ // TRKS
232
+ case 0x534b5254:
233
+ break;
234
+ }
235
+ dwMemPos += dwLen;
236
+ }
237
+ // Load Patterns
238
+ dwMemPos = dwExtraDataPos + nExtraDataLen;
239
+ for (UINT iPat=0; iPat<pfh->wPatterns; iPat++) if (dwMemPos < dwMemLength-6)
240
+ {
241
+ const MT2PATTERN *pmp = (MT2PATTERN *)(lpStream+dwMemPos);
242
+ UINT wDataLen = (pmp->wDataLen + 1) & ~1;
243
+ dwMemPos += 6;
244
+ if (dwMemPos + wDataLen > dwMemLength) break;
245
+ UINT nLines = pmp->wLines;
246
+ if ((iPat < MAX_PATTERNS) && (nLines > 0) && (nLines <= 256))
247
+ {
248
+ _this->PatternSize[iPat] = nLines;
249
+ _this->Patterns[iPat] = CSoundFile_AllocatePattern(nLines, _this->m_nChannels);
250
+ if (!_this->Patterns[iPat]) return TRUE;
251
+ MODCOMMAND *m = _this->Patterns[iPat];
252
+ UINT len = wDataLen;
253
+ if (pfh->fulFlags & 1) // Packed Patterns
254
+ {
255
+ BYTE *p = (BYTE *)(lpStream+dwMemPos);
256
+ UINT pos = 0, row=0, ch=0;
257
+ while (pos < len)
258
+ {
259
+ MT2COMMAND cmd;
260
+ UINT infobyte = p[pos++];
261
+ UINT rptcount = 0;
262
+ if (infobyte == 0xff)
263
+ {
264
+ rptcount = p[pos++];
265
+ infobyte = p[pos++];
266
+ }
267
+ if (infobyte & 0x7f)
268
+ {
269
+ UINT patpos = row*_this->m_nChannels+ch;
270
+ cmd.note = cmd.instr = cmd.vol = cmd.pan = cmd.fxcmd = cmd.fxparam1 = cmd.fxparam2 = 0;
271
+ if (infobyte & 1) cmd.note = p[pos++];
272
+ if (infobyte & 2) cmd.instr = p[pos++];
273
+ if (infobyte & 4) cmd.vol = p[pos++];
274
+ if (infobyte & 8) cmd.pan = p[pos++];
275
+ if (infobyte & 16) cmd.fxcmd = p[pos++];
276
+ if (infobyte & 32) cmd.fxparam1 = p[pos++];
277
+ if (infobyte & 64) cmd.fxparam2 = p[pos++];
278
+ ConvertMT2Command(_this, &m[patpos], &cmd);
279
+ }
280
+ row += rptcount+1;
281
+ while (row >= nLines) { row-=nLines; ch++; }
282
+ if (ch >= _this->m_nChannels) break;
283
+ }
284
+ } else
285
+ {
286
+ const MT2COMMAND *p = (MT2COMMAND *)(lpStream+dwMemPos);
287
+ UINT n = 0;
288
+ while ((len > sizeof(MT2COMMAND)) && (n < _this->m_nChannels*nLines))
289
+ {
290
+ ConvertMT2Command(_this, m, p);
291
+ len -= sizeof(MT2COMMAND);
292
+ n++;
293
+ p++;
294
+ m++;
295
+ }
296
+ }
297
+ }
298
+ dwMemPos += wDataLen;
299
+ }
300
+ // Skip Drum Patterns
301
+ if (pdd)
302
+ {
303
+ for (UINT iDrm=0; iDrm<pdd->wDrumPatterns; iDrm++)
304
+ {
305
+ if (dwMemPos > dwMemLength-2) return TRUE;
306
+ UINT nLines = *(WORD *)(lpStream+dwMemPos);
307
+ dwMemPos += 2 + nLines * 32;
308
+ }
309
+ }
310
+ // Automation
311
+ if (pfh->fulFlags & 2)
312
+ {
313
+ UINT nAutoCount = _this->m_nChannels;
314
+ if (pfh->fulFlags & 0x10) nAutoCount++; // Master Automation
315
+ if ((pfh->fulFlags & 0x08) && (pdd)) nAutoCount += 8; // Drums Automation
316
+ nAutoCount *= pfh->wPatterns;
317
+ for (UINT iAuto=0; iAuto<nAutoCount; iAuto++)
318
+ {
319
+ if (dwMemPos+12 >= dwMemLength) return TRUE;
320
+ const MT2AUTOMATION *pma = (MT2AUTOMATION *)(lpStream+dwMemPos);
321
+ dwMemPos += (pfh->wVersion <= 0x201) ? 4 : 8;
322
+ for (UINT iEnv=0; iEnv<14; iEnv++)
323
+ {
324
+ if (pma->dwFlags & (1 << iEnv))
325
+ {
326
+ dwMemPos += 260;
327
+ }
328
+ }
329
+ }
330
+ }
331
+ // Load Instruments
332
+ SDL_memset(InstrMap, 0, sizeof(InstrMap));
333
+ _this->m_nInstruments = (pfh->wInstruments < MAX_INSTRUMENTS) ? pfh->wInstruments : MAX_INSTRUMENTS-1;
334
+ for (UINT iIns=1; iIns<=255; iIns++)
335
+ {
336
+ if (dwMemPos+36 > dwMemLength) return TRUE;
337
+ const MT2INSTRUMENT *pmi = (MT2INSTRUMENT *)(lpStream+dwMemPos);
338
+ INSTRUMENTHEADER *penv = NULL;
339
+ if (iIns <= _this->m_nInstruments)
340
+ {
341
+ penv = (INSTRUMENTHEADER *) SDL_malloc(sizeof (INSTRUMENTHEADER));
342
+ _this->Headers[iIns] = penv;
343
+ if (penv)
344
+ {
345
+ SDL_memset(penv, 0, sizeof(INSTRUMENTHEADER));
346
+ penv->nGlobalVol = 64;
347
+ penv->nPan = 128;
348
+ for (UINT i=0; i<NOTE_MAX; i++)
349
+ {
350
+ penv->NoteMap[i] = i+1;
351
+ }
352
+ }
353
+ }
354
+ if (((LONG)pmi->dwDataLen > 0) && (dwMemPos <= dwMemLength - 40) && (pmi->dwDataLen <= dwMemLength - (dwMemPos + 40)))
355
+ {
356
+ InstrMap[iIns-1] = pmi;
357
+ if (penv)
358
+ {
359
+ penv->nFadeOut = pmi->wFadeOut;
360
+ penv->nNNA = pmi->wNNA & 3;
361
+ penv->nDCT = (pmi->wNNA>>8) & 3;
362
+ penv->nDNA = (pmi->wNNA>>12) & 3;
363
+ MT2ENVELOPE *pehdr[4];
364
+ WORD *pedata[4];
365
+ if (pfh->wVersion <= 0x201)
366
+ {
367
+ DWORD dwEnvPos = dwMemPos + sizeof(MT2INSTRUMENT) - 4;
368
+ pehdr[0] = (MT2ENVELOPE *)(lpStream+dwEnvPos);
369
+ pehdr[1] = (MT2ENVELOPE *)(lpStream+dwEnvPos+8);
370
+ pehdr[2] = pehdr[3] = NULL;
371
+ pedata[0] = (WORD *)(lpStream+dwEnvPos+16);
372
+ pedata[1] = (WORD *)(lpStream+dwEnvPos+16+64);
373
+ pedata[2] = pedata[3] = NULL;
374
+ } else
375
+ {
376
+ DWORD dwEnvPos = dwMemPos + sizeof(MT2INSTRUMENT);
377
+ for (UINT i=0; i<4; i++)
378
+ {
379
+ if (pmi->wEnvFlags1 & (1<<i))
380
+ {
381
+ pehdr[i] = (MT2ENVELOPE *)(lpStream+dwEnvPos);
382
+ pedata[i] = (WORD *)pehdr[i]->EnvData;
383
+ dwEnvPos += sizeof(MT2ENVELOPE);
384
+ } else
385
+ {
386
+ pehdr[i] = NULL;
387
+ pedata[i] = NULL;
388
+ }
389
+ }
390
+ }
391
+ // Load envelopes
392
+ for (UINT iEnv=0; iEnv<4; iEnv++) if (pehdr[iEnv])
393
+ {
394
+ const MT2ENVELOPE *pme = pehdr[iEnv];
395
+ WORD *pEnvPoints = NULL;
396
+ BYTE *pEnvData = NULL;
397
+ switch(iEnv)
398
+ {
399
+ // Volume Envelope
400
+ case 0:
401
+ if (pme->nFlags & 1) penv->dwFlags |= ENV_VOLUME;
402
+ if (pme->nFlags & 2) penv->dwFlags |= ENV_VOLSUSTAIN;
403
+ if (pme->nFlags & 4) penv->dwFlags |= ENV_VOLLOOP;
404
+ penv->nVolEnv = (pme->nPoints > 16) ? 16 : pme->nPoints;
405
+ penv->nVolSustainBegin = penv->nVolSustainEnd = pme->nSustainPos;
406
+ penv->nVolLoopStart = pme->nLoopStart;
407
+ penv->nVolLoopEnd = pme->nLoopEnd;
408
+ pEnvPoints = penv->VolPoints;
409
+ pEnvData = penv->VolEnv;
410
+ break;
411
+
412
+ // Panning Envelope
413
+ case 1:
414
+ if (pme->nFlags & 1) penv->dwFlags |= ENV_PANNING;
415
+ if (pme->nFlags & 2) penv->dwFlags |= ENV_PANSUSTAIN;
416
+ if (pme->nFlags & 4) penv->dwFlags |= ENV_PANLOOP;
417
+ penv->nPanEnv = (pme->nPoints > 16) ? 16 : pme->nPoints;
418
+ penv->nPanSustainBegin = penv->nPanSustainEnd = pme->nSustainPos;
419
+ penv->nPanLoopStart = pme->nLoopStart;
420
+ penv->nPanLoopEnd = pme->nLoopEnd;
421
+ pEnvPoints = penv->PanPoints;
422
+ pEnvData = penv->PanEnv;
423
+ break;
424
+
425
+ // Pitch/Filter envelope
426
+ default:
427
+ if (pme->nFlags & 1) penv->dwFlags |= (iEnv==3) ? (ENV_PITCH|ENV_FILTER) : ENV_PITCH;
428
+ if (pme->nFlags & 2) penv->dwFlags |= ENV_PITCHSUSTAIN;
429
+ if (pme->nFlags & 4) penv->dwFlags |= ENV_PITCHLOOP;
430
+ penv->nPitchEnv = (pme->nPoints > 16) ? 16 : pme->nPoints;
431
+ penv->nPitchSustainBegin = penv->nPitchSustainEnd = pme->nSustainPos;
432
+ penv->nPitchLoopStart = pme->nLoopStart;
433
+ penv->nPitchLoopEnd = pme->nLoopEnd;
434
+ pEnvPoints = penv->PitchPoints;
435
+ pEnvData = penv->PitchEnv;
436
+ }
437
+ // Envelope data
438
+ if ((pEnvPoints) && (pEnvData) && (pedata[iEnv]))
439
+ {
440
+ WORD *psrc = pedata[iEnv];
441
+ for (UINT i=0; i<16; i++)
442
+ {
443
+ pEnvPoints[i] = psrc[i*2];
444
+ pEnvData[i] = (BYTE)psrc[i*2+1];
445
+ }
446
+ }
447
+ }
448
+ }
449
+ dwMemPos += pmi->dwDataLen + 36;
450
+ if (pfh->wVersion > 0x201) dwMemPos += 4; // ?
451
+ } else
452
+ {
453
+ dwMemPos += 36;
454
+ }
455
+ }
456
+ SDL_memset(SampleMap, 0, sizeof(SampleMap));
457
+ _this->m_nSamples = (pfh->wSamples < MAX_SAMPLES) ? pfh->wSamples : MAX_SAMPLES-1;
458
+ for (UINT iSmp=1; iSmp<=256; iSmp++)
459
+ {
460
+ if (dwMemPos+36 > dwMemLength) return TRUE;
461
+ const MT2SAMPLE *pms = (MT2SAMPLE *)(lpStream+dwMemPos);
462
+ if (pms->dwDataLen > 0)
463
+ {
464
+ SampleMap[iSmp-1] = pms;
465
+ if (iSmp < MAX_SAMPLES)
466
+ {
467
+ MODINSTRUMENT *psmp = &_this->Ins[iSmp];
468
+ psmp->nGlobalVol = 64;
469
+ psmp->nVolume = (pms->wVolume >> 7);
470
+ psmp->nPan = (pms->nPan == 0x80) ? 128 : (pms->nPan^0x80);
471
+ psmp->nLength = pms->dwLength;
472
+ psmp->nC4Speed = pms->dwFrequency;
473
+ psmp->nLoopStart = pms->dwLoopStart;
474
+ psmp->nLoopEnd = pms->dwLoopEnd;
475
+ CSoundFile_FrequencyToTransposeInstrument(psmp);
476
+ psmp->RelativeTone -= pms->nBaseNote - 49;
477
+ psmp->nC4Speed = CSoundFile_TransposeToFrequency(psmp->RelativeTone, psmp->nFineTune);
478
+ if (pms->nQuality == 2) { psmp->uFlags |= CHN_16BIT; psmp->nLength >>= 1; }
479
+ if (pms->nChannels == 2) { psmp->nLength >>= 1; }
480
+ if (pms->nLoop == 1) psmp->uFlags |= CHN_LOOP;
481
+ if (pms->nLoop == 2) psmp->uFlags |= CHN_LOOP|CHN_PINGPONGLOOP;
482
+ }
483
+ dwMemPos += pms->dwDataLen + 36;
484
+ } else
485
+ {
486
+ dwMemPos += 36;
487
+ }
488
+ }
489
+ for (UINT iMap=0; iMap<255; iMap++) if (InstrMap[iMap])
490
+ {
491
+ if (dwMemPos+8 > dwMemLength) return TRUE;
492
+ const MT2INSTRUMENT *pmi = InstrMap[iMap];
493
+ INSTRUMENTHEADER *penv = NULL;
494
+ if (iMap<_this->m_nInstruments) penv = _this->Headers[iMap+1];
495
+ for (UINT iGrp=0; iGrp<pmi->wSamples; iGrp++)
496
+ {
497
+ if (penv)
498
+ {
499
+ const MT2GROUP *pmg = (MT2GROUP *)(lpStream+dwMemPos);
500
+ for (UINT i=0; i<96; i++)
501
+ {
502
+ if (pmi->GroupsMapping[i] == iGrp)
503
+ {
504
+ UINT nSmp = pmg->nSmpNo+1;
505
+ penv->Keyboard[i+12] = (BYTE)nSmp;
506
+ if (nSmp <= _this->m_nSamples)
507
+ {
508
+ _this->Ins[nSmp].nVibType = pmi->bVibType;
509
+ _this->Ins[nSmp].nVibSweep = pmi->bVibSweep;
510
+ _this->Ins[nSmp].nVibDepth = pmi->bVibDepth;
511
+ _this->Ins[nSmp].nVibRate = pmi->bVibRate;
512
+ }
513
+ }
514
+ }
515
+ }
516
+ dwMemPos += 8;
517
+ }
518
+ }
519
+ for (UINT iData=0; iData<256; iData++) if ((iData < _this->m_nSamples) && (SampleMap[iData]))
520
+ {
521
+ const MT2SAMPLE *pms = SampleMap[iData];
522
+ MODINSTRUMENT *psmp = &_this->Ins[iData+1];
523
+ if (!(pms->nFlags & 5))
524
+ {
525
+ if (psmp->nLength > 0)
526
+ {
527
+ UINT rsflags;
528
+
529
+ if (pms->nChannels == 2)
530
+ rsflags = (psmp->uFlags & CHN_16BIT) ? RS_STPCM16D : RS_STPCM8D;
531
+ else
532
+ rsflags = (psmp->uFlags & CHN_16BIT) ? RS_PCM16D : RS_PCM8D;
533
+
534
+ dwMemPos += CSoundFile_ReadSample(_this, psmp, rsflags, (LPCSTR)(lpStream+dwMemPos), dwMemLength-dwMemPos);
535
+ }
536
+ } else
537
+ if (dwMemPos+4 < dwMemLength)
538
+ {
539
+ UINT nNameLen = *(DWORD *)(lpStream+dwMemPos);
540
+ dwMemPos += nNameLen + 16;
541
+ }
542
+ if (dwMemPos+4 >= dwMemLength) break;
543
+ }
544
+ return TRUE;
545
+ }
546
+