gosu 0.15.2 → 1.0.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (234) 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 +56 -22
  159. data/{Gosu → include/Gosu}/Audio.hpp +6 -8
  160. data/{Gosu → include/Gosu}/AutoLink.hpp +0 -0
  161. data/include/Gosu/Bitmap.hpp +100 -0
  162. data/{Gosu → include/Gosu}/Buttons.hpp +94 -35
  163. data/{Gosu → include/Gosu}/Channel.h +0 -0
  164. data/{Gosu → include/Gosu}/Color.h +0 -0
  165. data/{Gosu → include/Gosu}/Color.hpp +0 -0
  166. data/{Gosu → include/Gosu}/Directories.hpp +0 -0
  167. data/{Gosu → include/Gosu}/Font.h +0 -0
  168. data/{Gosu → include/Gosu}/Font.hpp +0 -0
  169. data/{Gosu → include/Gosu}/Fwd.hpp +0 -0
  170. data/{Gosu → include/Gosu}/Gosu.h +3 -0
  171. data/{Gosu → include/Gosu}/Gosu.hpp +0 -0
  172. data/{Gosu → include/Gosu}/Graphics.hpp +0 -0
  173. data/{Gosu → include/Gosu}/GraphicsBase.hpp +0 -0
  174. data/{Gosu → include/Gosu}/IO.hpp +0 -0
  175. data/{Gosu → include/Gosu}/Image.h +0 -0
  176. data/{Gosu → include/Gosu}/Image.hpp +7 -6
  177. data/{Gosu → include/Gosu}/ImageData.hpp +0 -0
  178. data/{Gosu → include/Gosu}/Input.hpp +30 -15
  179. data/{Gosu → include/Gosu}/Inspection.hpp +0 -0
  180. data/{Gosu → include/Gosu}/Math.hpp +0 -0
  181. data/{Gosu → include/Gosu}/Platform.hpp +0 -0
  182. data/{Gosu → include/Gosu}/Sample.h +0 -0
  183. data/{Gosu → include/Gosu}/Song.h +0 -0
  184. data/{Gosu → include/Gosu}/Text.hpp +0 -0
  185. data/{Gosu → include/Gosu}/TextInput.h +0 -0
  186. data/{Gosu → include/Gosu}/TextInput.hpp +0 -0
  187. data/{Gosu → include/Gosu}/Timing.hpp +0 -0
  188. data/{Gosu → include/Gosu}/Utility.hpp +1 -1
  189. data/{Gosu → include/Gosu}/Version.hpp +0 -0
  190. data/{Gosu → include/Gosu}/Window.h +2 -0
  191. data/{Gosu → include/Gosu}/Window.hpp +21 -13
  192. data/lib/OpenAL32.dll +0 -0
  193. data/lib/SDL2.dll +0 -0
  194. data/lib/gosu.rb +0 -3
  195. data/lib/gosu/patches.rb +0 -9
  196. data/lib/gosu/swig_patches.rb +3 -2
  197. data/lib/libmpg123.dll +0 -0
  198. data/lib/libsndfile.dll +0 -0
  199. data/lib64/OpenAL32.dll +0 -0
  200. data/lib64/SDL2.dll +0 -0
  201. data/lib64/libmpg123.dll +0 -0
  202. data/lib64/libsndfile.dll +0 -0
  203. data/rdoc/gosu.rb +95 -20
  204. data/src/Audio.cpp +50 -224
  205. data/src/AudioFile.hpp +17 -37
  206. data/src/AudioFileAudioToolbox.cpp +237 -0
  207. data/src/AudioFileSDLSound.cpp +147 -0
  208. data/src/AudioImpl.cpp +3 -12
  209. data/src/AudioImpl.hpp +3 -1
  210. data/src/Bitmap.cpp +85 -83
  211. data/src/BitmapIO.cpp +52 -58
  212. data/src/Constants.cpp +80 -33
  213. data/src/Font.cpp +3 -1
  214. data/src/GosuWrapper.cpp +19 -0
  215. data/src/Graphics.cpp +7 -4
  216. data/src/Image.cpp +13 -16
  217. data/src/Input.cpp +408 -159
  218. data/src/LargeImageData.cpp +1 -1
  219. data/src/MarkupParser.cpp +2 -1
  220. data/src/RubyGosu.cxx +349 -83
  221. data/src/RubyGosu.h +4 -2
  222. data/src/TexChunk.cpp +1 -1
  223. data/src/TextBuilder.cpp +3 -1
  224. data/src/Texture.cpp +1 -1
  225. data/src/TrueTypeFont.cpp +1 -1
  226. data/src/Utility.cpp +11 -7
  227. data/src/Window.cpp +30 -39
  228. data/src/WindowWrapper.cpp +28 -0
  229. metadata +207 -52
  230. data/Gosu/Bitmap.hpp +0 -113
  231. data/src/AudioToolboxFile.hpp +0 -210
  232. data/src/OggFile.hpp +0 -92
  233. data/src/SndFile.hpp +0 -174
  234. data/src/WinMain.cpp +0 -64
@@ -0,0 +1,357 @@
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
+ ///////////////////////////////////////////////////////////////
9
+ //
10
+ // DigiBooster Pro Module Loader (*.dbm)
11
+ //
12
+ // Note: this loader doesn't handle multiple songs
13
+ //
14
+ ///////////////////////////////////////////////////////////////
15
+
16
+ #include "libmodplug.h"
17
+
18
+ #define DBM_FILE_MAGIC 0x304d4244
19
+ #define DBM_ID_NAME 0x454d414e
20
+ #define DBM_NAMELEN 0x2c000000
21
+ #define DBM_ID_INFO 0x4f464e49
22
+ #define DBM_INFOLEN 0x0a000000
23
+ #define DBM_ID_SONG 0x474e4f53
24
+ #define DBM_ID_INST 0x54534e49
25
+ #define DBM_ID_VENV 0x564e4556
26
+ #define DBM_ID_PATT 0x54544150
27
+ #define DBM_ID_SMPL 0x4c504d53
28
+
29
+ #pragma pack(1)
30
+
31
+ typedef struct DBMFILEHEADER
32
+ {
33
+ DWORD dbm_id; // "DBM0" = 0x304d4244
34
+ WORD trkver; // Tracker version: 02.15
35
+ WORD reserved;
36
+ DWORD name_id; // "NAME" = 0x454d414e
37
+ DWORD name_len; // name length: always 44
38
+ CHAR songname[44];
39
+ DWORD info_id; // "INFO" = 0x4f464e49
40
+ DWORD info_len; // 0x0a000000
41
+ WORD instruments;
42
+ WORD samples;
43
+ WORD songs;
44
+ WORD patterns;
45
+ WORD channels;
46
+ DWORD song_id; // "SONG" = 0x474e4f53
47
+ DWORD song_len;
48
+ CHAR songname2[44];
49
+ WORD orders;
50
+ // WORD orderlist[0]; // orderlist[orders] in words
51
+ } DBMFILEHEADER;
52
+
53
+ typedef struct DBMINSTRUMENT
54
+ {
55
+ CHAR name[30];
56
+ WORD sampleno;
57
+ WORD volume;
58
+ DWORD finetune;
59
+ DWORD loopstart;
60
+ DWORD looplen;
61
+ WORD panning;
62
+ WORD flags;
63
+ } DBMINSTRUMENT;
64
+
65
+ typedef struct DBMENVELOPE
66
+ {
67
+ WORD instrument;
68
+ BYTE flags;
69
+ BYTE numpoints;
70
+ BYTE sustain1;
71
+ BYTE loopbegin;
72
+ BYTE loopend;
73
+ BYTE sustain2;
74
+ WORD volenv[2*32];
75
+ } DBMENVELOPE;
76
+
77
+ typedef struct DBMPATTERN
78
+ {
79
+ WORD rows;
80
+ DWORD packedsize;
81
+ BYTE patterndata[2]; // [packedsize]
82
+ } DBMPATTERN;
83
+
84
+ typedef struct DBMSAMPLE
85
+ {
86
+ DWORD flags;
87
+ DWORD samplesize;
88
+ BYTE sampledata[2]; // [samplesize]
89
+ } DBMSAMPLE;
90
+
91
+ #pragma pack()
92
+
93
+
94
+ BOOL CSoundFile_ReadDBM(CSoundFile *_this, const BYTE *lpStream, DWORD dwMemLength)
95
+ //---------------------------------------------------------------
96
+ {
97
+ const DBMFILEHEADER *pfh = (DBMFILEHEADER *)lpStream;
98
+ DWORD dwMemPos;
99
+ UINT nOrders, nSamples, nInstruments, nPatterns;
100
+
101
+ if ((!lpStream) || (dwMemLength <= sizeof(DBMFILEHEADER)) || (!pfh->channels)
102
+ || (pfh->dbm_id != bswapLE32(DBM_FILE_MAGIC)) || (!pfh->songs) || (pfh->song_id != bswapLE32(DBM_ID_SONG))
103
+ || (pfh->name_id != bswapLE32(DBM_ID_NAME)) || (pfh->name_len != bswapLE32(DBM_NAMELEN))
104
+ || (pfh->info_id != bswapLE32(DBM_ID_INFO)) || (pfh->info_len != bswapLE32(DBM_INFOLEN))) return FALSE;
105
+ dwMemPos = sizeof(DBMFILEHEADER);
106
+ nOrders = bswapBE16(pfh->orders);
107
+ if (dwMemPos + 2 * nOrders + 8*3 >= dwMemLength) return FALSE;
108
+ nInstruments = bswapBE16(pfh->instruments);
109
+ nSamples = bswapBE16(pfh->samples);
110
+ nPatterns = bswapBE16(pfh->patterns);
111
+ _this->m_nType = MOD_TYPE_DBM;
112
+ _this->m_nChannels = bswapBE16(pfh->channels);
113
+ if (_this->m_nChannels < 4) _this->m_nChannels = 4;
114
+ if (_this->m_nChannels > 64) _this->m_nChannels = 64;
115
+ for (UINT iOrd=0; iOrd < nOrders; iOrd++)
116
+ {
117
+ _this->Order[iOrd] = lpStream[dwMemPos+iOrd*2+1];
118
+ if (iOrd >= MAX_ORDERS-2) break;
119
+ }
120
+ dwMemPos += 2*nOrders;
121
+ while (dwMemPos + 10 < dwMemLength)
122
+ {
123
+ DWORD chunk_id = ((LPDWORD)(lpStream+dwMemPos))[0];
124
+ DWORD chunk_size = bswapBE32(((LPDWORD)(lpStream+dwMemPos))[1]);
125
+ DWORD chunk_pos;
126
+
127
+ dwMemPos += 8;
128
+ chunk_pos = dwMemPos;
129
+ if ((dwMemPos + chunk_size > dwMemLength) || (chunk_size > dwMemLength)) break;
130
+ dwMemPos += chunk_size;
131
+ // Instruments
132
+ if (chunk_id == bswapLE32(DBM_ID_INST))
133
+ {
134
+ if (nInstruments >= MAX_INSTRUMENTS) nInstruments = MAX_INSTRUMENTS-1;
135
+ for (UINT iIns=0; iIns<nInstruments; iIns++)
136
+ {
137
+ MODINSTRUMENT *psmp;
138
+ INSTRUMENTHEADER *penv;
139
+ DBMINSTRUMENT *pih;
140
+ UINT nsmp;
141
+
142
+ if (chunk_pos + sizeof(DBMINSTRUMENT) > dwMemPos) break;
143
+ if ((penv = (INSTRUMENTHEADER *) SDL_malloc(sizeof (INSTRUMENTHEADER))) == NULL) break;
144
+ pih = (DBMINSTRUMENT *)(lpStream+chunk_pos);
145
+ nsmp = bswapBE16(pih->sampleno);
146
+ psmp = ((nsmp) && (nsmp < MAX_SAMPLES)) ? &_this->Ins[nsmp] : NULL;
147
+ SDL_memset(penv, 0, sizeof(INSTRUMENTHEADER));
148
+ _this->Headers[iIns+1] = penv;
149
+ penv->nFadeOut = 1024; // ???
150
+ penv->nGlobalVol = 64;
151
+ penv->nPan = bswapBE16(pih->panning);
152
+ if ((penv->nPan) && (penv->nPan < 256))
153
+ penv->dwFlags = ENV_SETPANNING;
154
+ else
155
+ penv->nPan = 128;
156
+ penv->nPPC = 5*12;
157
+ for (UINT i=0; i<NOTE_MAX; i++)
158
+ {
159
+ penv->Keyboard[i] = nsmp;
160
+ penv->NoteMap[i] = i+1;
161
+ }
162
+ // Sample Info
163
+ if (psmp)
164
+ {
165
+ DWORD sflags = bswapBE16(pih->flags);
166
+ psmp->nVolume = bswapBE16(pih->volume) * 4;
167
+ if ((!psmp->nVolume) || (psmp->nVolume > 256)) psmp->nVolume = 256;
168
+ psmp->nGlobalVol = 64;
169
+ psmp->nC4Speed = bswapBE32(pih->finetune);
170
+ int f2t = CSoundFile_FrequencyToTranspose(psmp->nC4Speed);
171
+ psmp->RelativeTone = f2t >> 7;
172
+ psmp->nFineTune = f2t & 0x7F;
173
+ if ((pih->looplen) && (sflags & 3))
174
+ {
175
+ psmp->nLoopStart = bswapBE32(pih->loopstart);
176
+ psmp->nLoopEnd = psmp->nLoopStart + bswapBE32(pih->looplen);
177
+ psmp->uFlags |= CHN_LOOP;
178
+ psmp->uFlags &= ~CHN_PINGPONGLOOP;
179
+ if (sflags & 2) psmp->uFlags |= CHN_PINGPONGLOOP;
180
+ }
181
+ }
182
+ chunk_pos += sizeof(DBMINSTRUMENT);
183
+ _this->m_nInstruments = iIns+1;
184
+ }
185
+ } else
186
+ // Volume Envelopes
187
+ if (chunk_id == bswapLE32(DBM_ID_VENV))
188
+ {
189
+ UINT nEnvelopes = lpStream[chunk_pos+1];
190
+
191
+ chunk_pos += 2;
192
+ for (UINT iEnv=0; iEnv<nEnvelopes; iEnv++)
193
+ {
194
+ DBMENVELOPE *peh;
195
+ UINT nins;
196
+
197
+ if (chunk_pos + sizeof(DBMENVELOPE) > dwMemPos) break;
198
+ peh = (DBMENVELOPE *)(lpStream+chunk_pos);
199
+ nins = bswapBE16(peh->instrument);
200
+ if ((nins) && (nins < MAX_INSTRUMENTS) && (_this->Headers[nins]) && (peh->numpoints))
201
+ {
202
+ INSTRUMENTHEADER *penv = _this->Headers[nins];
203
+
204
+ if (peh->flags & 1) penv->dwFlags |= ENV_VOLUME;
205
+ if (peh->flags & 2) penv->dwFlags |= ENV_VOLSUSTAIN;
206
+ if (peh->flags & 4) penv->dwFlags |= ENV_VOLLOOP;
207
+ penv->nVolEnv = peh->numpoints + 1;
208
+ if (penv->nVolEnv > MAX_ENVPOINTS) penv->nVolEnv = MAX_ENVPOINTS;
209
+ penv->nVolLoopStart = peh->loopbegin;
210
+ penv->nVolLoopEnd = peh->loopend;
211
+ penv->nVolSustainBegin = penv->nVolSustainEnd = peh->sustain1;
212
+ for (UINT i=0; i<penv->nVolEnv; i++)
213
+ {
214
+ penv->VolPoints[i] = bswapBE16(peh->volenv[i*2]);
215
+ penv->VolEnv[i] = (BYTE)bswapBE16(peh->volenv[i*2+1]);
216
+ }
217
+ }
218
+ chunk_pos += sizeof(DBMENVELOPE);
219
+ }
220
+ } else
221
+ // Packed Pattern Data
222
+ if (chunk_id == bswapLE32(DBM_ID_PATT))
223
+ {
224
+ if (nPatterns > MAX_PATTERNS) nPatterns = MAX_PATTERNS;
225
+ for (UINT iPat=0; iPat<nPatterns; iPat++)
226
+ {
227
+ DBMPATTERN *pph;
228
+ DWORD pksize;
229
+ UINT nRows;
230
+
231
+ if (chunk_pos + sizeof(DBMPATTERN) > dwMemPos) break;
232
+ pph = (DBMPATTERN *)(lpStream+chunk_pos);
233
+ pksize = bswapBE32(pph->packedsize);
234
+ if ((chunk_pos + pksize + 6 > dwMemPos) || (pksize > dwMemPos)) break;
235
+ nRows = bswapBE16(pph->rows);
236
+ if ((nRows >= 4) && (nRows <= 256))
237
+ {
238
+ MODCOMMAND *m = CSoundFile_AllocatePattern(nRows, _this->m_nChannels);
239
+ if (m)
240
+ {
241
+ LPBYTE pkdata = (LPBYTE)&pph->patterndata;
242
+ UINT row = 0;
243
+ UINT i = 0;
244
+
245
+ _this->PatternSize[iPat] = nRows;
246
+ _this->Patterns[iPat] = m;
247
+ while ((i+3<pksize) && (row < nRows))
248
+ {
249
+ UINT ch = pkdata[i++];
250
+
251
+ if (ch)
252
+ {
253
+ BYTE b = pkdata[i++];
254
+ ch--;
255
+ if (ch < _this->m_nChannels)
256
+ {
257
+ if (b & 0x01)
258
+ {
259
+ UINT note = pkdata[i++];
260
+
261
+ if (note == 0x1F) note = 0xFF; else
262
+ if ((note) && (note < 0xFE))
263
+ {
264
+ note = ((note >> 4)*12) + (note & 0x0F) + 13;
265
+ }
266
+ m[ch].note = note;
267
+ }
268
+ if (b & 0x02) m[ch].instr = pkdata[i++];
269
+ if (b & 0x3C)
270
+ {
271
+ UINT cmd1 = 0xFF, param1 = 0, cmd2 = 0xFF, param2 = 0;
272
+ if (b & 0x04) cmd1 = (UINT)pkdata[i++];
273
+ if (b & 0x08) param1 = pkdata[i++];
274
+ if (b & 0x10) cmd2 = (UINT)pkdata[i++];
275
+ if (b & 0x20) param2 = pkdata[i++];
276
+ if (cmd1 == 0x0C)
277
+ {
278
+ m[ch].volcmd = VOLCMD_VOLUME;
279
+ m[ch].vol = param1;
280
+ cmd1 = 0xFF;
281
+ } else
282
+ if (cmd2 == 0x0C)
283
+ {
284
+ m[ch].volcmd = VOLCMD_VOLUME;
285
+ m[ch].vol = param2;
286
+ cmd2 = 0xFF;
287
+ }
288
+ if ((cmd1 > 0x13) || ((cmd1 >= 0x10) && (cmd2 < 0x10)))
289
+ {
290
+ cmd1 = cmd2;
291
+ param1 = param2;
292
+ cmd2 = 0xFF;
293
+ }
294
+ if (cmd1 <= 0x13)
295
+ {
296
+ m[ch].command = cmd1;
297
+ m[ch].param = param1;
298
+ CSoundFile_ConvertModCommand(_this, &m[ch]);
299
+ }
300
+ }
301
+ } else
302
+ {
303
+ if (b & 0x01) i++;
304
+ if (b & 0x02) i++;
305
+ if (b & 0x04) i++;
306
+ if (b & 0x08) i++;
307
+ if (b & 0x10) i++;
308
+ if (b & 0x20) i++;
309
+ }
310
+ } else
311
+ {
312
+ row++;
313
+ m += _this->m_nChannels;
314
+ }
315
+ }
316
+ }
317
+ }
318
+ chunk_pos += 6 + pksize;
319
+ }
320
+ } else
321
+ // Reading Sample Data
322
+ if (chunk_id == bswapLE32(DBM_ID_SMPL))
323
+ {
324
+ if (nSamples >= MAX_SAMPLES) nSamples = MAX_SAMPLES-1;
325
+ _this->m_nSamples = nSamples;
326
+ for (UINT iSmp=1; iSmp<=nSamples; iSmp++)
327
+ {
328
+ MODINSTRUMENT *pins;
329
+ DBMSAMPLE *psh;
330
+ DWORD samplesize;
331
+ DWORD sampleflags;
332
+
333
+ if (chunk_pos + sizeof(DBMSAMPLE) >= dwMemPos) break;
334
+ psh = (DBMSAMPLE *)(lpStream+chunk_pos);
335
+ chunk_pos += 8;
336
+ samplesize = bswapBE32(psh->samplesize);
337
+ sampleflags = bswapBE32(psh->flags);
338
+ pins = &_this->Ins[iSmp];
339
+ pins->nLength = samplesize;
340
+ if (sampleflags & 2)
341
+ {
342
+ pins->uFlags |= CHN_16BIT;
343
+ samplesize <<= 1;
344
+ }
345
+ if ((chunk_pos+samplesize > dwMemPos) || (samplesize > dwMemLength)) break;
346
+ if (sampleflags & 3)
347
+ {
348
+ CSoundFile_ReadSample(_this, pins, (pins->uFlags & CHN_16BIT) ? RS_PCM16M : RS_PCM8S,
349
+ (LPSTR)(psh->sampledata), samplesize);
350
+ }
351
+ chunk_pos += samplesize;
352
+ }
353
+ }
354
+ }
355
+ return TRUE;
356
+ }
357
+
@@ -0,0 +1,531 @@
1
+ /*
2
+ * This source code is public domain.
3
+ *
4
+ * Authors: Olivier Lapicque <olivierl@jps.net>
5
+ */
6
+
7
+ ///////////////////////////////////////////////////////
8
+ // DMF DELUSION DIGITAL MUSIC FILEFORMAT (X-Tracker) //
9
+ ///////////////////////////////////////////////////////
10
+ #include "libmodplug.h"
11
+
12
+ #pragma pack(1)
13
+
14
+ typedef struct DMFHEADER
15
+ {
16
+ DWORD id; // "DDMF" = 0x464d4444
17
+ BYTE version; // 4
18
+ CHAR trackername[8]; // "XTRACKER"
19
+ CHAR songname[30];
20
+ CHAR composer[20];
21
+ BYTE date[3];
22
+ } DMFHEADER;
23
+
24
+ typedef struct DMFINFO
25
+ {
26
+ DWORD id; // "INFO"
27
+ DWORD infosize;
28
+ } DMFINFO;
29
+
30
+ typedef struct DMFSEQU
31
+ {
32
+ DWORD id; // "SEQU"
33
+ DWORD seqsize;
34
+ WORD loopstart;
35
+ WORD loopend;
36
+ WORD sequ[2];
37
+ } DMFSEQU;
38
+
39
+ typedef struct DMFPATT
40
+ {
41
+ DWORD id; // "PATT"
42
+ DWORD patsize;
43
+ WORD numpat; // 1-1024
44
+ BYTE tracks;
45
+ BYTE firstpatinfo;
46
+ } DMFPATT;
47
+
48
+ typedef struct DMFTRACK
49
+ {
50
+ BYTE tracks;
51
+ BYTE beat; // [hi|lo] -> hi=ticks per beat, lo=beats per measure
52
+ WORD ticks; // max 512
53
+ DWORD jmpsize;
54
+ } DMFTRACK;
55
+
56
+ typedef struct DMFSMPI
57
+ {
58
+ DWORD id;
59
+ DWORD size;
60
+ BYTE samples;
61
+ } DMFSMPI;
62
+
63
+ typedef struct DMFSAMPLE
64
+ {
65
+ DWORD len;
66
+ DWORD loopstart;
67
+ DWORD loopend;
68
+ WORD c3speed;
69
+ BYTE volume;
70
+ BYTE flags;
71
+ } DMFSAMPLE;
72
+
73
+ #pragma pack()
74
+
75
+
76
+ BOOL CSoundFile_ReadDMF(CSoundFile *_this, const BYTE *lpStream, DWORD dwMemLength)
77
+ //---------------------------------------------------------------
78
+ {
79
+ const DMFHEADER *pfh = (DMFHEADER *)lpStream;
80
+ DMFINFO *psi;
81
+ DMFSEQU *sequ;
82
+ DWORD dwMemPos;
83
+ BYTE infobyte[32];
84
+ BYTE smplflags[MAX_SAMPLES], hasSMPI = 0;
85
+
86
+ if ((!lpStream) || (dwMemLength < 1024)) return FALSE;
87
+ if ((pfh->id != 0x464d4444) || (!pfh->version) || (pfh->version & 0xF0)) return FALSE;
88
+ dwMemPos = 66;
89
+ _this->m_nType = MOD_TYPE_DMF;
90
+ _this->m_nChannels = 0;
91
+ while (dwMemPos + 7 < dwMemLength)
92
+ {
93
+ DWORD id = *((LPDWORD)(lpStream+dwMemPos));
94
+
95
+ switch(id)
96
+ {
97
+ // "INFO"
98
+ case 0x4f464e49:
99
+ // "CMSG"
100
+ case 0x47534d43:
101
+ psi = (DMFINFO *)(lpStream+dwMemPos);
102
+ if (id == 0x47534d43) dwMemPos++;
103
+ if ((psi->infosize > dwMemLength) || (psi->infosize + dwMemPos + 8 > dwMemLength)) goto dmfexit;
104
+ dwMemPos += psi->infosize + 8 - 1;
105
+ break;
106
+
107
+ // "SEQU"
108
+ case 0x55514553:
109
+ sequ = (DMFSEQU *)(lpStream+dwMemPos);
110
+ if ((sequ->seqsize >= dwMemLength) || (dwMemPos + sequ->seqsize + 12 > dwMemLength)) goto dmfexit;
111
+ {
112
+ UINT nseq = sequ->seqsize >> 1;
113
+ if (nseq >= MAX_ORDERS-1) nseq = MAX_ORDERS-1;
114
+ if (sequ->loopstart < nseq) _this->m_nRestartPos = sequ->loopstart;
115
+ for (UINT i=0; i<nseq; i++) _this->Order[i] = (BYTE)sequ->sequ[i];
116
+ }
117
+ dwMemPos += sequ->seqsize + 8;
118
+ break;
119
+
120
+ // "PATT"
121
+ case 0x54544150:
122
+ if (!_this->m_nChannels)
123
+ {
124
+ DMFPATT *patt = (DMFPATT *)(lpStream+dwMemPos);
125
+ UINT numpat;
126
+ DWORD dwPos = dwMemPos + 11;
127
+ if ((patt->patsize >= dwMemLength) || (dwMemPos + patt->patsize + 8 > dwMemLength)) goto dmfexit;
128
+ numpat = patt->numpat;
129
+ if (numpat > MAX_PATTERNS) numpat = MAX_PATTERNS;
130
+ _this->m_nChannels = patt->tracks;
131
+ if (_this->m_nChannels < patt->firstpatinfo) _this->m_nChannels = patt->firstpatinfo;
132
+ if (_this->m_nChannels > 32) _this->m_nChannels = 32;
133
+ if (_this->m_nChannels < 4) _this->m_nChannels = 4;
134
+ for (UINT npat=0; npat<numpat; npat++)
135
+ {
136
+ DMFTRACK *pt = (DMFTRACK *)(lpStream+dwPos);
137
+ UINT tracks = pt->tracks;
138
+ if (tracks > 32) tracks = 32;
139
+ UINT ticks = pt->ticks;
140
+ if (ticks > 256) ticks = 256;
141
+ if (ticks < 16) ticks = 16;
142
+ dwPos += 8;
143
+ if ((pt->jmpsize >= dwMemLength) || (dwPos + pt->jmpsize + 4 >= dwMemLength)) break;
144
+ _this->PatternSize[npat] = (WORD)ticks;
145
+ MODCOMMAND *m = CSoundFile_AllocatePattern(_this->PatternSize[npat], _this->m_nChannels);
146
+ if (!m) goto dmfexit;
147
+ _this->Patterns[npat] = m;
148
+ DWORD d = dwPos;
149
+ dwPos += pt->jmpsize;
150
+ UINT ttype = 1;
151
+ UINT tempo = 125;
152
+ UINT glbinfobyte = 0;
153
+ UINT pbeat = (pt->beat & 0xf0) ? pt->beat>>4 : 8;
154
+ BOOL tempochange = (pt->beat & 0xf0) ? TRUE : FALSE;
155
+ SDL_memset(infobyte, 0, sizeof(infobyte));
156
+ for (UINT row=0; row<ticks; row++)
157
+ {
158
+ MODCOMMAND *p = &m[row*_this->m_nChannels];
159
+ // Parse track global effects
160
+ if (!glbinfobyte)
161
+ {
162
+ BYTE info = lpStream[d++];
163
+ BYTE infoval = 0;
164
+ if ((info & 0x80) && (d < dwPos)) glbinfobyte = lpStream[d++];
165
+ info &= 0x7f;
166
+ if ((info) && (d < dwPos)) infoval = lpStream[d++];
167
+ switch(info)
168
+ {
169
+ case 1: ttype = 0; tempo = infoval; tempochange = TRUE; break;
170
+ case 2: ttype = 1; tempo = infoval; tempochange = TRUE; break;
171
+ case 3: pbeat = infoval>>4; tempochange = ttype; break;
172
+ }
173
+ } else
174
+ {
175
+ glbinfobyte--;
176
+ }
177
+ // Parse channels
178
+ for (UINT i=0; i<tracks; i++) if (!infobyte[i])
179
+ {
180
+ MODCOMMAND cmd;
181
+ SDL_zero(cmd);
182
+ BYTE info = lpStream[d++];
183
+ if (info & 0x80) infobyte[i] = lpStream[d++];
184
+ // Instrument
185
+ if (info & 0x40)
186
+ {
187
+ cmd.instr = lpStream[d++];
188
+ }
189
+ // Note
190
+ if (info & 0x20)
191
+ {
192
+ cmd.note = lpStream[d++];
193
+ if ((cmd.note) && (cmd.note < 0xfe)) cmd.note &= 0x7f;
194
+ if ((cmd.note) && (cmd.note < 128)) cmd.note += 24;
195
+ }
196
+ // Volume
197
+ if (info & 0x10)
198
+ {
199
+ cmd.volcmd = VOLCMD_VOLUME;
200
+ cmd.vol = (lpStream[d++]+3)>>2;
201
+ }
202
+ // Effect 1
203
+ if (info & 0x08)
204
+ {
205
+ BYTE efx = lpStream[d++];
206
+ BYTE eval = lpStream[d++];
207
+ switch(efx)
208
+ {
209
+ // 1: Key Off
210
+ case 1: if (!cmd.note) cmd.note = 0xFE; break;
211
+ // 2: Set Loop
212
+ // 4: Sample Delay
213
+ case 4: if (eval&0xe0) { cmd.command = CMD_S3MCMDEX; cmd.param = (eval>>5)|0xD0; } break;
214
+ // 5: Retrig
215
+ case 5: if (eval&0xe0) { cmd.command = CMD_RETRIG; cmd.param = (eval>>5); } break;
216
+ // 6: Offset
217
+ case 6: cmd.command = CMD_OFFSET; cmd.param = eval; break;
218
+ }
219
+ }
220
+ // Effect 2
221
+ if (info & 0x04)
222
+ {
223
+ BYTE efx = lpStream[d++];
224
+ BYTE eval = lpStream[d++];
225
+ switch(efx)
226
+ {
227
+ // 1: Finetune
228
+ case 1: if (eval&0xf0) { cmd.command = CMD_S3MCMDEX; cmd.param = (eval>>4)|0x20; } break;
229
+ // 2: Note Delay
230
+ case 2: if (eval&0xe0) { cmd.command = CMD_S3MCMDEX; cmd.param = (eval>>5)|0xD0; } break;
231
+ // 3: Arpeggio
232
+ case 3: if (eval) { cmd.command = CMD_ARPEGGIO; cmd.param = eval; } break;
233
+ // 4: Portamento Up
234
+ case 4: cmd.command = CMD_PORTAMENTOUP; cmd.param = (eval >= 0xe0) ? 0xdf : eval; break;
235
+ // 5: Portamento Down
236
+ case 5: cmd.command = CMD_PORTAMENTODOWN; cmd.param = (eval >= 0xe0) ? 0xdf : eval; break;
237
+ // 6: Tone Portamento
238
+ case 6: cmd.command = CMD_TONEPORTAMENTO; cmd.param = eval; break;
239
+ // 8: Vibrato
240
+ case 8: cmd.command = CMD_VIBRATO; cmd.param = eval; break;
241
+ // 12: Note cut
242
+ case 12: if (eval & 0xe0) { cmd.command = CMD_S3MCMDEX; cmd.param = (eval>>5)|0xc0; }
243
+ else if (!cmd.note) { cmd.note = 0xfe; } break;
244
+ }
245
+ }
246
+ // Effect 3
247
+ if (info & 0x02)
248
+ {
249
+ BYTE efx = lpStream[d++];
250
+ BYTE eval = lpStream[d++];
251
+ switch(efx)
252
+ {
253
+ // 1: Vol Slide Up
254
+ case 1: if (eval == 0xff) break;
255
+ eval = (eval+3)>>2; if (eval > 0x0f) eval = 0x0f;
256
+ cmd.command = CMD_VOLUMESLIDE; cmd.param = eval<<4; break;
257
+ // 2: Vol Slide Down
258
+ case 2: if (eval == 0xff) break;
259
+ eval = (eval+3)>>2; if (eval > 0x0f) eval = 0x0f;
260
+ cmd.command = CMD_VOLUMESLIDE; cmd.param = eval; break;
261
+ // 7: Set Pan
262
+ case 7: if (!cmd.volcmd) { cmd.volcmd = VOLCMD_PANNING; cmd.vol = (eval+3)>>2; }
263
+ else { cmd.command = CMD_PANNING8; cmd.param = eval; } break;
264
+ // 8: Pan Slide Left
265
+ case 8: eval = (eval+3)>>2; if (eval > 0x0f) eval = 0x0f;
266
+ cmd.command = CMD_PANNINGSLIDE; cmd.param = eval<<4; break;
267
+ // 9: Pan Slide Right
268
+ case 9: eval = (eval+3)>>2; if (eval > 0x0f) eval = 0x0f;
269
+ cmd.command = CMD_PANNINGSLIDE; cmd.param = eval; break;
270
+
271
+ }
272
+ }
273
+ // Store effect
274
+ if (i < _this->m_nChannels) p[i] = cmd;
275
+ if (d > dwPos)
276
+ {
277
+ break;
278
+ }
279
+ } else
280
+ {
281
+ infobyte[i]--;
282
+ }
283
+
284
+ // Find free channel for tempo change
285
+ if (tempochange)
286
+ {
287
+ tempochange = FALSE;
288
+ UINT speed=6, modtempo=tempo;
289
+ UINT rpm = ((ttype) && (pbeat)) ? tempo*pbeat : (tempo+1)*15;
290
+ for (speed=30; speed>1; speed--)
291
+ {
292
+ modtempo = rpm*speed/24;
293
+ if (modtempo <= 200) break;
294
+ if ((speed < 6) && (modtempo < 256)) break;
295
+ }
296
+ for (UINT ich=0; ich<_this->m_nChannels; ich++) if (!p[ich].command)
297
+ {
298
+ if (speed)
299
+ {
300
+ p[ich].command = CMD_SPEED;
301
+ p[ich].param = (BYTE)speed;
302
+ speed = 0;
303
+ } else
304
+ if ((modtempo >= 32) && (modtempo < 256))
305
+ {
306
+ p[ich].command = CMD_TEMPO;
307
+ p[ich].param = (BYTE)modtempo;
308
+ modtempo = 0;
309
+ } else
310
+ {
311
+ break;
312
+ }
313
+ }
314
+ }
315
+ if (d >= dwPos) break;
316
+ }
317
+ if (dwPos + 8 >= dwMemLength) break;
318
+ }
319
+ dwMemPos += patt->patsize + 8;
320
+ }
321
+ break;
322
+
323
+ // "SMPI": Sample Info
324
+ case 0x49504d53:
325
+ {
326
+ hasSMPI = 1;
327
+ DMFSMPI *pds = (DMFSMPI *)(lpStream+dwMemPos);
328
+ if (pds->size <= dwMemLength - dwMemPos)
329
+ {
330
+ DWORD dwPos = dwMemPos + 9;
331
+ _this->m_nSamples = pds->samples;
332
+ if (_this->m_nSamples >= MAX_SAMPLES) _this->m_nSamples = MAX_SAMPLES-1;
333
+ for (UINT iSmp=1; iSmp<=_this->m_nSamples; iSmp++)
334
+ {
335
+ const UINT namelen = lpStream[dwPos];
336
+ smplflags[iSmp] = 0;
337
+ if (dwPos+namelen+1+sizeof(DMFSAMPLE) > dwMemPos+pds->size+8) break;
338
+ dwPos += namelen + 1;
339
+ DMFSAMPLE *psh = (DMFSAMPLE *)(lpStream+dwPos);
340
+ MODINSTRUMENT *psmp = &_this->Ins[iSmp];
341
+ psmp->nLength = psh->len;
342
+ psmp->nLoopStart = psh->loopstart;
343
+ psmp->nLoopEnd = psh->loopend;
344
+ psmp->nC4Speed = psh->c3speed;
345
+ psmp->nGlobalVol = 64;
346
+ psmp->nVolume = (psh->volume) ? ((WORD)psh->volume)+1 : (WORD)256;
347
+ psmp->uFlags = (psh->flags & 2) ? CHN_16BIT : 0;
348
+ if (psmp->uFlags & CHN_16BIT) psmp->nLength >>= 1;
349
+ if (psh->flags & 1) psmp->uFlags |= CHN_LOOP;
350
+ smplflags[iSmp] = psh->flags;
351
+ dwPos += (pfh->version < 8) ? 22 : 30;
352
+ }
353
+ }
354
+ dwMemPos += pds->size + 8;
355
+ }
356
+ break;
357
+
358
+ // "SMPD": Sample Data
359
+ case 0x44504d53:
360
+ {
361
+ DWORD dwPos = dwMemPos + 8;
362
+ UINT ismpd = 0;
363
+ for (UINT iSmp=1; iSmp<=_this->m_nSamples; iSmp++)
364
+ {
365
+ ismpd++;
366
+ DWORD pksize;
367
+ if (dwPos + 4 >= dwMemLength)
368
+ {
369
+ break;
370
+ }
371
+ pksize = *((LPDWORD)(lpStream+dwPos));
372
+ dwPos += 4;
373
+ if (pksize > dwMemLength - dwPos)
374
+ {
375
+ pksize = dwMemLength - dwPos;
376
+ }
377
+ if ((pksize) && (iSmp <= _this->m_nSamples))
378
+ {
379
+ UINT flags = (_this->Ins[iSmp].uFlags & CHN_16BIT) ? RS_PCM16S : RS_PCM8S;
380
+ if (hasSMPI && smplflags[ismpd] & 4)
381
+ flags = (_this->Ins[iSmp].uFlags & CHN_16BIT) ? RS_DMF16 : RS_DMF8;
382
+ CSoundFile_ReadSample(_this, &_this->Ins[iSmp], flags, (LPSTR)(lpStream+dwPos), pksize);
383
+ }
384
+ dwPos += pksize;
385
+ }
386
+ dwMemPos = dwPos;
387
+ }
388
+ break;
389
+
390
+ // "ENDE": end of file
391
+ case 0x45444e45:
392
+ goto dmfexit;
393
+
394
+ // Unrecognized id, or "ENDE" field
395
+ default:
396
+ dwMemPos += 4;
397
+ break;
398
+ }
399
+ }
400
+ dmfexit:
401
+ if (!_this->m_nChannels)
402
+ {
403
+ if (!_this->m_nSamples)
404
+ {
405
+ _this->m_nType = MOD_TYPE_NONE;
406
+ return FALSE;
407
+ }
408
+ _this->m_nChannels = 4;
409
+ }
410
+ return TRUE;
411
+ }
412
+
413
+
414
+ ///////////////////////////////////////////////////////////////////////
415
+ // DMF Compression
416
+
417
+ #pragma pack(1)
418
+
419
+ typedef struct DMF_HNODE
420
+ {
421
+ short int left, right;
422
+ BYTE value;
423
+ } DMF_HNODE;
424
+
425
+ typedef struct DMF_HTREE
426
+ {
427
+ LPBYTE ibuf, ibufmax;
428
+ DWORD bitbuf;
429
+ UINT bitnum;
430
+ UINT lastnode, nodecount;
431
+ DMF_HNODE nodes[256];
432
+ } DMF_HTREE;
433
+
434
+ #pragma pack()
435
+
436
+
437
+ // DMF Huffman ReadBits
438
+ BYTE DMFReadBits(DMF_HTREE *tree, UINT nbits)
439
+ //-------------------------------------------
440
+ {
441
+ BYTE x = 0, bitv = 1;
442
+ while (nbits--)
443
+ {
444
+ if (tree->bitnum)
445
+ {
446
+ tree->bitnum--;
447
+ } else
448
+ {
449
+ tree->bitbuf = (tree->ibuf < tree->ibufmax) ? *(tree->ibuf++) : 0;
450
+ tree->bitnum = 7;
451
+ }
452
+ if (tree->bitbuf & 1) x |= bitv;
453
+ bitv <<= 1;
454
+ tree->bitbuf >>= 1;
455
+ }
456
+ return x;
457
+ }
458
+
459
+ //
460
+ // tree: [8-bit value][12-bit index][12-bit index] = 32-bit
461
+ //
462
+
463
+ void DMFNewNode(DMF_HTREE *tree)
464
+ //------------------------------
465
+ {
466
+ BYTE isleft, isright;
467
+ UINT actnode;
468
+
469
+ actnode = tree->nodecount;
470
+ if (actnode > 255) return;
471
+ tree->nodes[actnode].value = DMFReadBits(tree, 7);
472
+ isleft = DMFReadBits(tree, 1);
473
+ isright = DMFReadBits(tree, 1);
474
+ actnode = tree->lastnode;
475
+ if (actnode > 255) return;
476
+ tree->nodecount++;
477
+ tree->lastnode = tree->nodecount;
478
+ if (isleft)
479
+ {
480
+ tree->nodes[actnode].left = tree->lastnode;
481
+ DMFNewNode(tree);
482
+ } else
483
+ {
484
+ tree->nodes[actnode].left = -1;
485
+ }
486
+ tree->lastnode = tree->nodecount;
487
+ if (isright)
488
+ {
489
+ tree->nodes[actnode].right = tree->lastnode;
490
+ DMFNewNode(tree);
491
+ } else
492
+ {
493
+ tree->nodes[actnode].right = -1;
494
+ }
495
+ }
496
+
497
+
498
+ int DMFUnpack(LPBYTE psample, LPBYTE ibuf, LPBYTE ibufmax, UINT maxlen)
499
+ //----------------------------------------------------------------------
500
+ {
501
+ DMF_HTREE tree;
502
+ UINT actnode;
503
+ BYTE value, sign, delta = 0;
504
+
505
+ SDL_memset(&tree, 0, sizeof(tree));
506
+ tree.ibuf = ibuf;
507
+ tree.ibufmax = ibufmax;
508
+ DMFNewNode(&tree);
509
+ value = 0;
510
+ for (UINT i=0; i<maxlen; i++)
511
+ {
512
+ actnode = 0;
513
+ sign = DMFReadBits(&tree, 1);
514
+ do
515
+ {
516
+ if (DMFReadBits(&tree, 1))
517
+ actnode = tree.nodes[actnode].right;
518
+ else
519
+ actnode = tree.nodes[actnode].left;
520
+ if (actnode > 255) break;
521
+ delta = tree.nodes[actnode].value;
522
+ if ((tree.ibuf >= tree.ibufmax) && (!tree.bitnum)) break;
523
+ } while ((tree.nodes[actnode].left >= 0) && (tree.nodes[actnode].right >= 0));
524
+ if (sign) delta ^= 0xFF;
525
+ value += delta;
526
+ psample[i] = (i) ? value : 0;
527
+ }
528
+ return tree.ibuf - ibuf;
529
+ }
530
+
531
+