gosu 0.14.6.pre1 → 1.0.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (242) 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} +128 -23
  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 +476 -176
  155. data/{src → dependencies/stb}/stb_image_write.h +253 -131
  156. data/{src → dependencies/stb}/stb_truetype.h +262 -104
  157. data/{src → dependencies/utf8proc}/utf8proc.c +47 -29
  158. data/{src → dependencies/utf8proc}/utf8proc.h +46 -24
  159. data/{src → dependencies/utf8proc}/utf8proc_data.h +10043 -9609
  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/include/Gosu/Channel.h +25 -0
  165. data/include/Gosu/Color.h +38 -0
  166. data/{Gosu → include/Gosu}/Color.hpp +0 -0
  167. data/{Gosu → include/Gosu}/Directories.hpp +0 -0
  168. data/include/Gosu/Font.h +36 -0
  169. data/{Gosu → include/Gosu}/Font.hpp +0 -0
  170. data/{Gosu → include/Gosu}/Fwd.hpp +0 -5
  171. data/include/Gosu/Gosu.h +82 -0
  172. data/{Gosu → include/Gosu}/Gosu.hpp +0 -0
  173. data/{Gosu → include/Gosu}/Graphics.hpp +0 -0
  174. data/{Gosu → include/Gosu}/GraphicsBase.hpp +0 -0
  175. data/{Gosu → include/Gosu}/IO.hpp +0 -0
  176. data/include/Gosu/Image.h +54 -0
  177. data/{Gosu → include/Gosu}/Image.hpp +7 -6
  178. data/{Gosu → include/Gosu}/ImageData.hpp +0 -0
  179. data/{Gosu → include/Gosu}/Input.hpp +39 -51
  180. data/{Gosu → include/Gosu}/Inspection.hpp +0 -0
  181. data/{Gosu → include/Gosu}/Math.hpp +0 -0
  182. data/{Gosu → include/Gosu}/Platform.hpp +0 -0
  183. data/include/Gosu/Sample.h +19 -0
  184. data/include/Gosu/Song.h +24 -0
  185. data/{Gosu → include/Gosu}/Text.hpp +0 -0
  186. data/include/Gosu/TextInput.h +30 -0
  187. data/{Gosu → include/Gosu}/TextInput.hpp +0 -0
  188. data/{Gosu → include/Gosu}/Timing.hpp +0 -0
  189. data/{Gosu → include/Gosu}/Utility.hpp +15 -4
  190. data/{Gosu → include/Gosu}/Version.hpp +3 -3
  191. data/include/Gosu/Window.h +63 -0
  192. data/{Gosu → include/Gosu}/Window.hpp +23 -25
  193. data/lib/OpenAL32.dll +0 -0
  194. data/lib/SDL2.dll +0 -0
  195. data/lib/gosu.rb +0 -3
  196. data/lib/gosu/compat.rb +9 -4
  197. data/lib/gosu/patches.rb +8 -11
  198. data/lib/gosu/swig_patches.rb +13 -6
  199. data/lib64/OpenAL32.dll +0 -0
  200. data/lib64/SDL2.dll +0 -0
  201. data/rdoc/gosu.rb +114 -21
  202. data/src/Audio.cpp +50 -224
  203. data/src/AudioFile.hpp +20 -37
  204. data/src/AudioFileAudioToolbox.cpp +237 -0
  205. data/src/AudioFileSDLSound.cpp +147 -0
  206. data/src/AudioImpl.cpp +3 -12
  207. data/src/AudioImpl.hpp +3 -1
  208. data/src/Bitmap.cpp +85 -83
  209. data/src/BitmapIO.cpp +52 -58
  210. data/src/ChannelWrapper.cpp +50 -0
  211. data/src/ColorWrapper.cpp +126 -0
  212. data/src/Constants.cpp +338 -0
  213. data/src/Font.cpp +4 -1
  214. data/src/FontWrapper.cpp +74 -0
  215. data/src/GosuWrapper.cpp +251 -0
  216. data/src/Graphics.cpp +11 -5
  217. data/src/GraphicsImpl.hpp +0 -1
  218. data/src/Image.cpp +13 -16
  219. data/src/ImageWrapper.cpp +168 -0
  220. data/src/Input.cpp +412 -164
  221. data/src/LargeImageData.cpp +2 -1
  222. data/src/MarkupParser.cpp +13 -4
  223. data/src/RubyGosu.cxx +502 -219
  224. data/src/RubyGosu.h +4 -2
  225. data/src/SampleWrapper.cpp +30 -0
  226. data/src/SongWrapper.cpp +52 -0
  227. data/src/TexChunk.cpp +29 -19
  228. data/src/Text.cpp +2 -0
  229. data/src/TextBuilder.cpp +6 -4
  230. data/src/TextInputWrapper.cpp +101 -0
  231. data/src/Texture.cpp +1 -1
  232. data/src/TrueTypeFont.cpp +2 -1
  233. data/src/Utility.cpp +11 -7
  234. data/src/Window.cpp +30 -39
  235. data/src/WindowWrapper.cpp +317 -0
  236. metadata +212 -42
  237. data/Gosu/AutoLink.hpp +0 -14
  238. data/Gosu/Bitmap.hpp +0 -113
  239. data/src/AudioToolboxFile.hpp +0 -210
  240. data/src/OggFile.hpp +0 -92
  241. data/src/SndFile.hpp +0 -174
  242. data/src/WinMain.cpp +0 -64
@@ -0,0 +1,757 @@
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
+ // OctaMed MED file support (import only)
12
+ //
13
+ // Lookup table for bpm values.
14
+ static const BYTE bpmvals[10] = { 179,164,152,141,131,123,116,110,104,99 };
15
+
16
+
17
+ // flags
18
+ #define MMD_FLAG_FILTERON 0x1
19
+ #define MMD_FLAG_JUMPINGON 0x2
20
+ #define MMD_FLAG_JUMP8TH 0x4
21
+ #define MMD_FLAG_INSTRSATT 0x8 // instruments are attached (this is a module)
22
+ #define MMD_FLAG_VOLHEX 0x10
23
+ #define MMD_FLAG_STSLIDE 0x20 // SoundTracker mode for slides
24
+ #define MMD_FLAG_8CHANNEL 0x40 // OctaMED 8 channel song
25
+ #define MMD_FLAG_SLOWHQ 0x80 // HQ slows playing speed (V2-V4 compatibility)
26
+ // flags2
27
+ #define MMD_FLAG2_BMASK 0x1F
28
+ #define MMD_FLAG2_BPM 0x20
29
+ #define MMD_FLAG2_MIX 0x80 // uses Mixing (V7+)
30
+ // flags3:
31
+ #define MMD_FLAG3_STEREO 0x1 // mixing in Stereo mode
32
+ #define MMD_FLAG3_FREEPAN 0x2 // free panning
33
+ #define MMD_FLAG3_GM 0x4 // module designed for GM/XG compatibility
34
+
35
+
36
+ // generic MMD tags
37
+ #define MMDTAG_END 0
38
+ #define MMDTAG_PTR 0x80000000 // data needs relocation
39
+ #define MMDTAG_MUSTKNOW 0x40000000 // loader must fail if this isn't recognized
40
+ #define MMDTAG_MUSTWARN 0x20000000 // loader must warn if this isn't recognized
41
+
42
+ // ExpData tags
43
+ // # of effect groups, including the global group (will
44
+ // override settings in MMDSong struct), default = 1
45
+ #define MMDTAG_EXP_NUMFXGROUPS 1
46
+ #define MMDTAG_TRK_NAME (MMDTAG_PTR|1) // trackinfo tags
47
+ #define MMDTAG_TRK_NAMELEN 2 // namelen includes zero term.
48
+ #define MMDTAG_TRK_FXGROUP 3
49
+ // effectinfo tags
50
+ #define MMDTAG_FX_ECHOTYPE 1
51
+ #define MMDTAG_FX_ECHOLEN 2
52
+ #define MMDTAG_FX_ECHODEPTH 3
53
+ #define MMDTAG_FX_STEREOSEP 4
54
+ #define MMDTAG_FX_GROUPNAME (MMDTAG_PTR|5) // the Global Effects group shouldn't have name saved!
55
+ #define MMDTAG_FX_GRPNAMELEN 6 // namelen includes zero term.
56
+
57
+ #pragma pack(1)
58
+
59
+ typedef struct tagMEDMODULEHEADER
60
+ {
61
+ DWORD id; // MMD1-MMD3
62
+ DWORD modlen; // Size of file
63
+ DWORD song; // Position in file for this song
64
+ WORD psecnum;
65
+ WORD pseq;
66
+ DWORD blockarr; // Position in file for blocks
67
+ DWORD mmdflags;
68
+ DWORD smplarr; // Position in file for samples
69
+ DWORD reserved;
70
+ DWORD expdata; // Absolute offset in file for ExpData (0 if not present)
71
+ DWORD reserved2;
72
+ WORD pstate;
73
+ WORD pblock;
74
+ WORD pline;
75
+ WORD pseqnum;
76
+ WORD actplayline;
77
+ BYTE counter;
78
+ BYTE extra_songs; // # of songs - 1
79
+ } MEDMODULEHEADER;
80
+
81
+
82
+ typedef struct tagMMD0SAMPLE
83
+ {
84
+ WORD rep, replen;
85
+ BYTE midich;
86
+ BYTE midipreset;
87
+ BYTE svol;
88
+ signed char strans;
89
+ } MMD0SAMPLE;
90
+
91
+
92
+ // Sample header is immediately followed by sample data...
93
+ typedef struct tagMMDSAMPLEHEADER
94
+ {
95
+ DWORD length; // length of *one* *unpacked* channel in *bytes*
96
+ WORD type;
97
+ // if non-negative
98
+ // bits 0-3 reserved for multi-octave instruments, not supported on the PC
99
+ // 0x10: 16 bit (otherwise 8 bit)
100
+ // 0x20: Stereo (otherwise mono)
101
+ // 0x40: Uses DeltaCode
102
+ // 0x80: Packed data
103
+ // -1: Synth
104
+ // -2: Hybrid
105
+ // if type indicates packed data, these fields follow, otherwise we go right to the data
106
+ WORD packtype; // Only 1 = ADPCM is supported
107
+ WORD subtype; // Packing subtype
108
+ // ADPCM subtype
109
+ // 1: g723_40
110
+ // 2: g721
111
+ // 3: g723_24
112
+ BYTE commonflags; // flags common to all packtypes (none defined so far)
113
+ BYTE packerflags; // flags for the specific packtype
114
+ ULONG leftchlen; // packed length of left channel in bytes
115
+ ULONG rightchlen; // packed length of right channel in bytes (ONLY PRESENT IN STEREO SAMPLES)
116
+ BYTE SampleData[1]; // Sample Data
117
+ } MMDSAMPLEHEADER;
118
+
119
+
120
+ // MMD0/MMD1 song header
121
+ typedef struct tagMMD0SONGHEADER
122
+ {
123
+ MMD0SAMPLE sample[63];
124
+ WORD numblocks; // # of blocks
125
+ WORD songlen; // # of entries used in playseq
126
+ BYTE playseq[256]; // Play sequence
127
+ WORD deftempo; // BPM tempo
128
+ signed char playtransp; // Play transpose
129
+ BYTE flags; // 0x10: Hex Volumes | 0x20: ST/NT/PT Slides | 0x40: 8 Channels song
130
+ BYTE flags2; // [b4-b0]+1: Tempo LPB, 0x20: tempo mode, 0x80: mix_conv=on
131
+ BYTE tempo2; // tempo TPL
132
+ BYTE trkvol[16]; // track volumes
133
+ BYTE mastervol; // master volume
134
+ BYTE numsamples; // # of samples (max=63)
135
+ } MMD0SONGHEADER;
136
+
137
+
138
+ // MMD2/MMD3 song header
139
+ typedef struct tagMMD2SONGHEADER
140
+ {
141
+ MMD0SAMPLE sample[63];
142
+ WORD numblocks; // # of blocks
143
+ WORD numsections; // # of sections
144
+ DWORD playseqtable; // filepos of play sequence
145
+ DWORD sectiontable; // filepos of sections table (WORD array)
146
+ DWORD trackvols; // filepos of tracks volume (BYTE array)
147
+ WORD numtracks; // # of tracks (max 64)
148
+ WORD numpseqs; // # of play sequences
149
+ DWORD trackpans; // filepos of tracks pan values (BYTE array)
150
+ LONG flags3; // 0x1:stereo_mix, 0x2:free_panning, 0x4:GM/XG compatibility
151
+ WORD voladj; // vol_adjust (set to 100 if 0)
152
+ WORD channels; // # of channels (4 if =0)
153
+ BYTE mix_echotype; // 1:normal,2:xecho
154
+ BYTE mix_echodepth; // 1..6
155
+ WORD mix_echolen; // > 0
156
+ signed char mix_stereosep; // -4..4
157
+ BYTE pad0[223];
158
+ WORD deftempo; // BPM tempo
159
+ signed char playtransp; // play transpose
160
+ BYTE flags; // 0x1:filteron, 0x2:jumpingon, 0x4:jump8th, 0x8:instr_attached, 0x10:hex_vol, 0x20:PT_slides, 0x40:8ch_conv,0x80:hq slows playing speed
161
+ BYTE flags2; // 0x80:mix_conv=on, [b4-b0]+1:tempo LPB, 0x20:tempo_mode
162
+ BYTE tempo2; // tempo TPL
163
+ BYTE pad1[16];
164
+ BYTE mastervol; // master volume
165
+ BYTE numsamples; // # of samples (max 63)
166
+ } MMD2SONGHEADER;
167
+
168
+ // For MMD0 the note information is held in 3 bytes, byte0, byte1, byte2. For reference we
169
+ // number the bits in each byte 0..7, where 0 is the low bit.
170
+ // The note is held as bits 5..0 of byte0
171
+ // The instrument is encoded in 6 bits, bits 7 and 6 of byte0 and bits 7,6,5,4 of byte1
172
+ // The command number is bits 3,2,1,0 of byte1, command data is in byte2:
173
+ // For command 0, byte2 represents the second data byte, otherwise byte2
174
+ // represents the first data byte.
175
+ typedef struct tagMMD0BLOCK
176
+ {
177
+ BYTE numtracks;
178
+ BYTE lines; // File value is 1 less than actual, so 0 -> 1 line
179
+ } MMD0BLOCK; // BYTE data[lines+1][tracks][3];
180
+
181
+
182
+ // For MMD1,MMD2,MMD3 the note information is carried in 4 bytes, byte0, byte1,
183
+ // byte2 and byte3
184
+ // The note is held as byte0 (values above 0x84 are ignored)
185
+ // The instrument is held as byte1
186
+ // The command number is held as byte2, command data is in byte3
187
+ // For commands 0 and 0x19 byte3 represents the second data byte,
188
+ // otherwise byte2 represents the first data byte.
189
+ typedef struct tagMMD1BLOCK
190
+ {
191
+ WORD numtracks; // Number of tracks, may be > 64, but then that data is skipped.
192
+ WORD lines; // Stored value is 1 less than actual, so 0 -> 1 line
193
+ DWORD info; // Offset of BlockInfo (if 0, no block_info is present)
194
+ } MMD1BLOCK;
195
+
196
+
197
+ typedef struct tagMMD1BLOCKINFO
198
+ {
199
+ DWORD hlmask; // Unimplemented - ignore
200
+ DWORD blockname; // file offset of block name
201
+ DWORD blocknamelen; // length of block name (including term. 0)
202
+ DWORD pagetable; // file offset of command page table
203
+ DWORD cmdexttable; // file offset of command extension table
204
+ DWORD reserved[4]; // future expansion
205
+ } MMD1BLOCKINFO;
206
+
207
+
208
+ // A set of play sequences is stored as an array of ULONG files offsets
209
+ // Each offset points to the play sequence itself.
210
+ typedef struct tagMMD2PLAYSEQ
211
+ {
212
+ CHAR name[32];
213
+ DWORD command_offs; // filepos of command table
214
+ DWORD reserved;
215
+ WORD length;
216
+ WORD seq[512]; // skip if > 0x8000
217
+ } MMD2PLAYSEQ;
218
+
219
+
220
+ // A command table contains commands that effect a particular play sequence
221
+ // entry. The only commands read in are STOP or POSJUMP, all others are ignored
222
+ // POSJUMP is presumed to have extra bytes containing a WORD for the position
223
+ typedef struct tagMMDCOMMAND
224
+ {
225
+ WORD offset; // Offset within current sequence entry
226
+ BYTE cmdnumber; // STOP (537) or POSJUMP (538) (others skipped)
227
+ BYTE extra_count;
228
+ BYTE extra_bytes[4];// [extra_count];
229
+ } MMDCOMMAND; // Last entry has offset == 0xFFFF, cmd_number == 0 and 0 extrabytes
230
+
231
+
232
+ typedef struct tagMMD0EXP
233
+ {
234
+ DWORD nextmod; // File offset of next Hdr
235
+ DWORD exp_smp; // Pointer to extra instrument data
236
+ WORD s_ext_entries; // Number of extra instrument entries
237
+ WORD s_ext_entrsz; // Size of extra instrument data
238
+ DWORD annotxt;
239
+ DWORD annolen;
240
+ DWORD iinfo; // Instrument names
241
+ WORD i_ext_entries;
242
+ WORD i_ext_entrsz;
243
+ DWORD jumpmask;
244
+ DWORD rgbtable;
245
+ BYTE channelsplit[4]; // Only used if 8ch_conv (extra channel for every nonzero entry)
246
+ DWORD n_info;
247
+ DWORD songname; // Song name
248
+ DWORD songnamelen;
249
+ DWORD dumps;
250
+ DWORD mmdinfo;
251
+ DWORD mmdrexx;
252
+ DWORD mmdcmd3x;
253
+ DWORD trackinfo_ofs; // ptr to song->numtracks ptrs to tag lists
254
+ DWORD effectinfo_ofs; // ptr to group ptrs
255
+ DWORD tag_end;
256
+ } MMD0EXP;
257
+
258
+ #pragma pack()
259
+
260
+
261
+
262
+ static void MedConvert(MODCOMMAND *p, const MMD0SONGHEADER *pmsh)
263
+ //---------------------------------------------------------------
264
+ {
265
+ UINT command = p->command;
266
+ UINT param = p->param;
267
+ switch(command)
268
+ {
269
+ case 0x00: if (param) command = CMD_ARPEGGIO; else command = 0; break;
270
+ case 0x01: command = CMD_PORTAMENTOUP; break;
271
+ case 0x02: command = CMD_PORTAMENTODOWN; break;
272
+ case 0x03: command = CMD_TONEPORTAMENTO; break;
273
+ case 0x04: command = CMD_VIBRATO; break;
274
+ case 0x05: command = CMD_TONEPORTAVOL; break;
275
+ case 0x06: command = CMD_VIBRATOVOL; break;
276
+ case 0x07: command = CMD_TREMOLO; break;
277
+ case 0x0A: if (param & 0xF0) param &= 0xF0; command = CMD_VOLUMESLIDE; if (!param) command = 0; break;
278
+ case 0x0B: command = CMD_POSITIONJUMP; break;
279
+ case 0x0C: command = CMD_VOLUME;
280
+ if (pmsh->flags & MMD_FLAG_VOLHEX)
281
+ {
282
+ if (param < 0x80)
283
+ {
284
+ param = (param+1) / 2;
285
+ } else command = 0;
286
+ } else
287
+ {
288
+ if (param <= 0x99)
289
+ {
290
+ param = (param >> 4)*10+((param & 0x0F) % 10);
291
+ if (param > 64) param = 64;
292
+ } else command = 0;
293
+ }
294
+ break;
295
+ case 0x09: command = (param < 0x20) ? CMD_SPEED : CMD_TEMPO; break;
296
+ case 0x0D: if (param & 0xF0) param &= 0xF0; command = CMD_VOLUMESLIDE; if (!param) command = 0; break;
297
+ case 0x0F: // Set Tempo / Special
298
+ // F.00 = Pattern Break
299
+ if (!param) command = CMD_PATTERNBREAK; else
300
+ // F.01 - F.F0: Set tempo/speed
301
+ if (param <= 0xF0)
302
+ {
303
+ if (pmsh->flags & MMD_FLAG_8CHANNEL)
304
+ {
305
+ param = (param > 10) ? 99 : bpmvals[param-1];
306
+ } else
307
+ // F.01 - F.0A: Set Speed
308
+ if (param <= 0x0A)
309
+ {
310
+ command = CMD_SPEED;
311
+ } else
312
+ // Old tempo
313
+ if (!(pmsh->flags2 & MMD_FLAG2_BPM))
314
+ {
315
+ param = _muldiv(param, 5*715909, 2*474326);
316
+ }
317
+ // F.0B - F.F0: Set Tempo (assumes LPB=4)
318
+ if (param > 0x0A)
319
+ {
320
+ command = CMD_TEMPO;
321
+ if (param < 0x21) param = 0x21;
322
+ if (param > 240) param = 240;
323
+ }
324
+ } else
325
+ switch(param)
326
+ {
327
+ // F.F1: Retrig 2x
328
+ case 0xF1:
329
+ command = CMD_MODCMDEX;
330
+ param = 0x93;
331
+ break;
332
+ // F.F2: Note Delay 2x
333
+ case 0xF2:
334
+ command = CMD_MODCMDEX;
335
+ param = 0xD3;
336
+ break;
337
+ // F.F3: Retrig 3x
338
+ case 0xF3:
339
+ command = CMD_MODCMDEX;
340
+ param = 0x92;
341
+ break;
342
+ // F.F4: Note Delay 1/3
343
+ case 0xF4:
344
+ command = CMD_MODCMDEX;
345
+ param = 0xD2;
346
+ break;
347
+ // F.F5: Note Delay 2/3
348
+ case 0xF5:
349
+ command = CMD_MODCMDEX;
350
+ param = 0xD4;
351
+ break;
352
+ // F.F8: Filter Off
353
+ case 0xF8:
354
+ command = CMD_MODCMDEX;
355
+ param = 0x00;
356
+ break;
357
+ // F.F9: Filter On
358
+ case 0xF9:
359
+ command = CMD_MODCMDEX;
360
+ param = 0x01;
361
+ break;
362
+ // F.FD: Very fast tone-portamento
363
+ case 0xFD:
364
+ command = CMD_TONEPORTAMENTO;
365
+ param = 0xFF;
366
+ break;
367
+ // F.FE: End Song
368
+ case 0xFE:
369
+ command = CMD_SPEED;
370
+ param = 0;
371
+ break;
372
+ // F.FF: Note Cut
373
+ case 0xFF:
374
+ command = CMD_MODCMDEX;
375
+ param = 0xC0;
376
+ break;
377
+ default:
378
+ param = command = 0;
379
+ }
380
+ break;
381
+ // 11.0x: Fine Slide Up
382
+ case 0x11:
383
+ command = CMD_MODCMDEX;
384
+ if (param > 0x0F) param = 0x0F;
385
+ param |= 0x10;
386
+ break;
387
+ // 12.0x: Fine Slide Down
388
+ case 0x12:
389
+ command = CMD_MODCMDEX;
390
+ if (param > 0x0F) param = 0x0F;
391
+ param |= 0x20;
392
+ break;
393
+ // 14.xx: Vibrato
394
+ case 0x14:
395
+ command = CMD_VIBRATO;
396
+ break;
397
+ // 15.xx: FineTune
398
+ case 0x15:
399
+ command = CMD_MODCMDEX;
400
+ param &= 0x0F;
401
+ param |= 0x50;
402
+ break;
403
+ // 16.xx: Pattern Loop
404
+ case 0x16:
405
+ command = CMD_MODCMDEX;
406
+ if (param > 0x0F) param = 0x0F;
407
+ param |= 0x60;
408
+ break;
409
+ // 18.xx: Note Cut
410
+ case 0x18:
411
+ command = CMD_MODCMDEX;
412
+ if (param > 0x0F) param = 0x0F;
413
+ param |= 0xC0;
414
+ break;
415
+ // 19.xx: Sample Offset
416
+ case 0x19:
417
+ command = CMD_OFFSET;
418
+ break;
419
+ // 1A.0x: Fine Volume Up
420
+ case 0x1A:
421
+ command = CMD_MODCMDEX;
422
+ if (param > 0x0F) param = 0x0F;
423
+ param |= 0xA0;
424
+ break;
425
+ // 1B.0x: Fine Volume Down
426
+ case 0x1B:
427
+ command = CMD_MODCMDEX;
428
+ if (param > 0x0F) param = 0x0F;
429
+ param |= 0xB0;
430
+ break;
431
+ // 1D.xx: Pattern Break
432
+ case 0x1D:
433
+ command = CMD_PATTERNBREAK;
434
+ break;
435
+ // 1E.0x: Pattern Delay
436
+ case 0x1E:
437
+ command = CMD_MODCMDEX;
438
+ if (param > 0x0F) param = 0x0F;
439
+ param |= 0xE0;
440
+ break;
441
+ // 1F.xy: Retrig
442
+ case 0x1F:
443
+ command = CMD_RETRIG;
444
+ param &= 0x0F;
445
+ break;
446
+ // 2E.xx: set panning
447
+ case 0x2E:
448
+ command = CMD_MODCMDEX;
449
+ param = ((param + 0x10) & 0xFF) >> 1;
450
+ if (param > 0x0F) param = 0x0F;
451
+ param |= 0x80;
452
+ break;
453
+ default:
454
+ command = param = 0;
455
+ }
456
+ p->command = command;
457
+ p->param = param;
458
+ }
459
+
460
+
461
+ BOOL CSoundFile_ReadMed(CSoundFile *_this, const BYTE *lpStream, DWORD dwMemLength)
462
+ //---------------------------------------------------------------
463
+ {
464
+ const MEDMODULEHEADER *pmmh;
465
+ const MMD0SONGHEADER *pmsh;
466
+ const MMD2SONGHEADER *pmsh2;
467
+ const MMD0EXP *pmex;
468
+ DWORD dwBlockArr, dwSmplArr, dwExpData, wNumBlocks;
469
+ LPDWORD pdwTable;
470
+ CHAR version;
471
+ UINT deftempo;
472
+ int playtransp = 0;
473
+
474
+ if ((!lpStream) || (dwMemLength < 0x200)) return FALSE;
475
+ pmmh = (MEDMODULEHEADER *)lpStream;
476
+ if (((pmmh->id & 0x00FFFFFF) != 0x444D4D) || (!pmmh->song)) return FALSE;
477
+ // Check for 'MMDx'
478
+ DWORD dwSong = bswapBE32(pmmh->song);
479
+ if ((dwSong >= dwMemLength) || (dwSong + sizeof(MMD0SONGHEADER) >= dwMemLength)) return FALSE;
480
+ version = (signed char)((pmmh->id >> 24) & 0xFF);
481
+ if ((version < '0') || (version > '3')) return FALSE;
482
+ _this->m_nType = MOD_TYPE_MED;
483
+ _this->m_nSongPreAmp = 0x20;
484
+ dwBlockArr = bswapBE32(pmmh->blockarr);
485
+ dwSmplArr = bswapBE32(pmmh->smplarr);
486
+ dwExpData = bswapBE32(pmmh->expdata);
487
+ if ((dwExpData) && (dwExpData < dwMemLength - sizeof(MMD0EXP)))
488
+ pmex = (MMD0EXP *)(lpStream+dwExpData);
489
+ else
490
+ pmex = NULL;
491
+ pmsh = (MMD0SONGHEADER *)(lpStream + dwSong);
492
+ pmsh2 = (MMD2SONGHEADER *)pmsh;
493
+ wNumBlocks = bswapBE16(pmsh->numblocks);
494
+ _this->m_nChannels = 4;
495
+ _this->m_nSamples = pmsh->numsamples;
496
+ if (_this->m_nSamples > 63) _this->m_nSamples = 63;
497
+ // Tempo
498
+ _this->m_nDefaultTempo = 125;
499
+ deftempo = bswapBE16(pmsh->deftempo);
500
+ if (!deftempo) deftempo = 125;
501
+ if (pmsh->flags2 & MMD_FLAG2_BPM)
502
+ {
503
+ UINT tempo_tpl = (pmsh->flags2 & MMD_FLAG2_BMASK) + 1;
504
+ if (!tempo_tpl) tempo_tpl = 4;
505
+ deftempo *= tempo_tpl;
506
+ deftempo /= 4;
507
+ } else
508
+ {
509
+ if (pmsh->flags & MMD_FLAG_8CHANNEL && deftempo > 0 && deftempo <= 10)
510
+ {
511
+ deftempo = bpmvals[deftempo-1];
512
+ } else {
513
+ deftempo = _muldiv(deftempo, 5*715909, 2*474326);
514
+ }
515
+ }
516
+ // Speed
517
+ _this->m_nDefaultSpeed = pmsh->tempo2;
518
+ if (!_this->m_nDefaultSpeed) _this->m_nDefaultSpeed = 6;
519
+ if (deftempo < 0x21) deftempo = 0x21;
520
+ if (deftempo > 255)
521
+ {
522
+ while ((_this->m_nDefaultSpeed > 3) && (deftempo > 260))
523
+ {
524
+ deftempo = (deftempo * (_this->m_nDefaultSpeed - 1)) / _this->m_nDefaultSpeed;
525
+ _this->m_nDefaultSpeed--;
526
+ }
527
+ if (deftempo > 255) deftempo = 255;
528
+ }
529
+ _this->m_nDefaultTempo = deftempo;
530
+ // Reading Samples
531
+ for (UINT iSHdr=0; iSHdr<_this->m_nSamples; iSHdr++)
532
+ {
533
+ MODINSTRUMENT *pins = &_this->Ins[iSHdr+1];
534
+ pins->nLoopStart = bswapBE16(pmsh->sample[iSHdr].rep) << 1;
535
+ pins->nLoopEnd = pins->nLoopStart + (bswapBE16(pmsh->sample[iSHdr].replen) << 1);
536
+ pins->nVolume = (pmsh->sample[iSHdr].svol << 2);
537
+ pins->nGlobalVol = 64;
538
+ if (pins->nVolume > 256) pins->nVolume = 256;
539
+ pins->RelativeTone = -12 * pmsh->sample[iSHdr].strans;
540
+ pins->nPan = 128;
541
+ if (pins->nLoopEnd) pins->uFlags |= CHN_LOOP;
542
+ }
543
+ // Common Flags
544
+ if (!(pmsh->flags & 0x20)) _this->m_dwSongFlags |= SONG_FASTVOLSLIDES;
545
+ // Reading play sequence
546
+ if (version < '2')
547
+ {
548
+ UINT nbo = pmsh->songlen >> 8;
549
+ if (nbo >= MAX_ORDERS) nbo = MAX_ORDERS-1;
550
+ if (!nbo) nbo = 1;
551
+ SDL_memcpy(_this->Order, pmsh->playseq, nbo);
552
+ playtransp = pmsh->playtransp;
553
+ } else
554
+ {
555
+ UINT nOrders, nSections;
556
+ UINT nTrks = bswapBE16(pmsh2->numtracks);
557
+ if ((nTrks >= 4) && (nTrks <= 32)) _this->m_nChannels = nTrks;
558
+ DWORD playseqtable = bswapBE32(pmsh2->playseqtable);
559
+ UINT numplayseqs = bswapBE16(pmsh2->numpseqs);
560
+ if (!numplayseqs) numplayseqs = 1;
561
+ nOrders = 0;
562
+ nSections = bswapBE16(pmsh2->numsections);
563
+ DWORD sectiontable = bswapBE32(pmsh2->sectiontable);
564
+ if ((!nSections) || (!sectiontable) || (sectiontable >= dwMemLength-2)) nSections = 1;
565
+ nOrders = 0;
566
+ for (UINT iSection=0; iSection<nSections; iSection++)
567
+ {
568
+ UINT nplayseq = 0;
569
+ if ((sectiontable) && (sectiontable < dwMemLength-2))
570
+ {
571
+ nplayseq = lpStream[sectiontable+1];
572
+ sectiontable += 2; // WORDs
573
+ } else
574
+ {
575
+ nSections = 0;
576
+ }
577
+ UINT pseq = 0;
578
+
579
+ if ((playseqtable) && (playseqtable < dwMemLength) && (nplayseq*4 < dwMemLength - playseqtable))
580
+ {
581
+ pseq = bswapBE32(((LPDWORD)(lpStream+playseqtable))[nplayseq]);
582
+ }
583
+ if ((pseq) && (pseq < dwMemLength - sizeof(MMD2PLAYSEQ)))
584
+ {
585
+ const MMD2PLAYSEQ *pmps = (MMD2PLAYSEQ *)(lpStream + pseq);
586
+ UINT n = bswapBE16(pmps->length);
587
+ if (n < (dwMemLength - (pseq + sizeof(*pmps)) + sizeof(pmps->seq)) / sizeof(pmps->seq[0]))
588
+ {
589
+ for (UINT i=0; i<n; i++)
590
+ {
591
+ UINT seqval = pmps->seq[i] >> 8;
592
+ if ((seqval < wNumBlocks) && (nOrders < MAX_ORDERS-1))
593
+ {
594
+ _this->Order[nOrders++] = seqval;
595
+ }
596
+ }
597
+ }
598
+ }
599
+ }
600
+ playtransp = pmsh2->playtransp;
601
+ while (nOrders < MAX_ORDERS) _this->Order[nOrders++] = 0xFF;
602
+ }
603
+ // Reading Expansion structure
604
+ if (pmex)
605
+ {
606
+ // Channel Split
607
+ if ((_this->m_nChannels == 4) && (pmsh->flags & MMD_FLAG_8CHANNEL))
608
+ {
609
+ for (UINT i8ch=0; i8ch<4; i8ch++)
610
+ {
611
+ if (pmex->channelsplit[i8ch]) _this->m_nChannels++;
612
+ }
613
+ }
614
+ }
615
+ // Reading samples
616
+ if (dwSmplArr > dwMemLength - 4*_this->m_nSamples) return TRUE;
617
+ pdwTable = (LPDWORD)(lpStream + dwSmplArr);
618
+ for (UINT iSmp=0; iSmp<_this->m_nSamples; iSmp++) if (pdwTable[iSmp])
619
+ {
620
+ UINT dwPos = bswapBE32(pdwTable[iSmp]);
621
+ if ((dwPos >= dwMemLength) || (dwPos + sizeof(MMDSAMPLEHEADER) >= dwMemLength)) continue;
622
+ MMDSAMPLEHEADER *psdh = (MMDSAMPLEHEADER *)(lpStream + dwPos);
623
+ UINT len = bswapBE32(psdh->length);
624
+ if ((len > MAX_SAMPLE_LENGTH) || (dwPos + len + 6 > dwMemLength)) len = 0;
625
+ UINT flags = RS_PCM8S, stype = bswapBE16(psdh->type);
626
+ LPSTR psdata = (LPSTR)(lpStream + dwPos + 6);
627
+ if (stype & 0x80)
628
+ {
629
+ psdata += (stype & 0x20) ? 14 : 6;
630
+ } else
631
+ {
632
+ if (stype & 0x10)
633
+ {
634
+ _this->Ins[iSmp+1].uFlags |= CHN_16BIT;
635
+ len /= 2;
636
+ flags = (stype & 0x20) ? RS_STPCM16M : RS_PCM16M;
637
+ } else
638
+ {
639
+ flags = (stype & 0x20) ? RS_STPCM8S : RS_PCM8S;
640
+ }
641
+ if (stype & 0x20) len /= 2;
642
+ }
643
+ _this->Ins[iSmp+1].nLength = len;
644
+ CSoundFile_ReadSample(_this, &_this->Ins[iSmp+1], flags, psdata, dwMemLength - dwPos - 6);
645
+ }
646
+ // Reading patterns (blocks)
647
+ if (wNumBlocks > MAX_PATTERNS) wNumBlocks = MAX_PATTERNS;
648
+ if ((!dwBlockArr) || (dwBlockArr > dwMemLength - 4*wNumBlocks)) return TRUE;
649
+ pdwTable = (LPDWORD)(lpStream + dwBlockArr);
650
+ playtransp += (version == '3') ? 24 : 48;
651
+ for (UINT iBlk=0; iBlk<wNumBlocks; iBlk++)
652
+ {
653
+ UINT dwPos = bswapBE32(pdwTable[iBlk]);
654
+ if ((!dwPos) || (dwPos >= dwMemLength) || (dwPos >= dwMemLength - 8)) continue;
655
+ UINT lines = 64, tracks = 4;
656
+ if (version == '0')
657
+ {
658
+ const MMD0BLOCK *pmb = (const MMD0BLOCK *)(lpStream + dwPos);
659
+ lines = pmb->lines + 1;
660
+ tracks = pmb->numtracks;
661
+ if (!tracks) tracks = _this->m_nChannels;
662
+ if ((_this->Patterns[iBlk] = CSoundFile_AllocatePattern(lines, _this->m_nChannels)) == NULL) continue;
663
+ _this->PatternSize[iBlk] = lines;
664
+ MODCOMMAND *p = _this->Patterns[iBlk];
665
+ LPBYTE s = (LPBYTE)(lpStream + dwPos + 2);
666
+ UINT maxlen = tracks*lines*3;
667
+ if (maxlen + dwPos > dwMemLength - 2) break;
668
+ for (UINT y=0; y<lines; y++)
669
+ {
670
+ for (UINT x=0; x<tracks; x++, s+=3) if (x < _this->m_nChannels)
671
+ {
672
+ BYTE note = s[0] & 0x3F;
673
+ BYTE instr = s[1] >> 4;
674
+ if (s[0] & 0x80) instr |= 0x10;
675
+ if (s[0] & 0x40) instr |= 0x20;
676
+ if ((note) && (note <= 132)) p->note = note + playtransp;
677
+ p->instr = instr;
678
+ p->command = s[1] & 0x0F;
679
+ p->param = s[2];
680
+ // if (!iBlk) Log("%02X.%02X.%02X | ", s[0], s[1], s[2]);
681
+ MedConvert(p, pmsh);
682
+ p++;
683
+ }
684
+ //if (!iBlk) Log("\n");
685
+ }
686
+ } else
687
+ {
688
+ const MMD1BLOCK *pmb = (MMD1BLOCK *)(lpStream + dwPos);
689
+ const MMD1BLOCKINFO *pbi = NULL;
690
+ BYTE *pcmdext = NULL;
691
+ lines = (pmb->lines >> 8) + 1;
692
+ tracks = pmb->numtracks >> 8;
693
+ if (!tracks) tracks = _this->m_nChannels;
694
+ if ((_this->Patterns[iBlk] = CSoundFile_AllocatePattern(lines, _this->m_nChannels)) == NULL) continue;
695
+ _this->PatternSize[iBlk] = (WORD)lines;
696
+ DWORD dwBlockInfo = bswapBE32(pmb->info);
697
+ if ((dwBlockInfo) && (dwBlockInfo < dwMemLength - sizeof(MMD1BLOCKINFO)))
698
+ {
699
+ pbi = (MMD1BLOCKINFO *)(lpStream + dwBlockInfo);
700
+ if ((pbi->blockname) && (pbi->blocknamelen))
701
+ {
702
+ DWORD nameofs = bswapBE32(pbi->blockname);
703
+ UINT namelen = bswapBE32(pbi->blocknamelen);
704
+ if ((nameofs < dwMemLength) && (namelen < dwMemLength + nameofs))
705
+ {
706
+ CSoundFile_SetPatternName(_this, iBlk, (LPCSTR)(lpStream+nameofs));
707
+ }
708
+ }
709
+ if (pbi->cmdexttable)
710
+ {
711
+ DWORD cmdexttable = bswapBE32(pbi->cmdexttable);
712
+ if (cmdexttable < dwMemLength - 4)
713
+ {
714
+ cmdexttable = bswapBE32(*(DWORD *)(lpStream + cmdexttable));
715
+ if ((cmdexttable) && (cmdexttable <= dwMemLength - lines*tracks))
716
+ {
717
+ pcmdext = (BYTE *)(lpStream + cmdexttable);
718
+ }
719
+ }
720
+ }
721
+ }
722
+ MODCOMMAND *p = _this->Patterns[iBlk];
723
+ LPBYTE s = (LPBYTE)(lpStream + dwPos + 8);
724
+ UINT maxlen = tracks*lines*4;
725
+ if (maxlen + dwPos > dwMemLength - 8) break;
726
+ for (UINT y=0; y<lines; y++)
727
+ {
728
+ for (UINT x=0; x<tracks; x++, s+=4) if (x < _this->m_nChannels)
729
+ {
730
+ BYTE note = s[0];
731
+ if ((note) && (note <= 132))
732
+ {
733
+ int rnote = note + playtransp;
734
+ if (rnote < 1) rnote = 1;
735
+ if (rnote > NOTE_MAX) rnote = NOTE_MAX;
736
+ p->note = (BYTE)rnote;
737
+ }
738
+ p->instr = s[1];
739
+ p->command = s[2];
740
+ p->param = s[3];
741
+ if (pcmdext) p->vol = pcmdext[x];
742
+ MedConvert(p, pmsh);
743
+ p++;
744
+ }
745
+ if (pcmdext) pcmdext += tracks;
746
+ }
747
+ }
748
+ }
749
+ // Setup channel pan positions
750
+ for (UINT iCh=0; iCh<_this->m_nChannels; iCh++)
751
+ {
752
+ _this->ChnSettings[iCh].nPan = (((iCh&3) == 1) || ((iCh&3) == 2)) ? 0xC0 : 0x40;
753
+ _this->ChnSettings[iCh].nVolume = 64;
754
+ }
755
+ return TRUE;
756
+ }
757
+