gosu 1.3.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (204) hide show
  1. checksums.yaml +4 -4
  2. data/dependencies/SDL/include/SDL.h +108 -14
  3. data/dependencies/SDL/include/SDL_assert.h +81 -50
  4. data/dependencies/SDL/include/SDL_atomic.h +135 -35
  5. data/dependencies/SDL/include/SDL_audio.h +960 -355
  6. data/dependencies/SDL/include/SDL_bits.h +11 -6
  7. data/dependencies/SDL/include/SDL_blendmode.h +91 -14
  8. data/dependencies/SDL/include/SDL_clipboard.h +30 -7
  9. data/dependencies/SDL/include/SDL_config.h +277 -27
  10. data/dependencies/SDL/include/SDL_config_android.h +13 -38
  11. data/dependencies/SDL/include/SDL_config_iphoneos.h +21 -62
  12. data/dependencies/SDL/include/SDL_config_macosx.h +23 -92
  13. data/dependencies/SDL/include/SDL_config_minimal.h +1 -4
  14. data/dependencies/SDL/include/SDL_config_pandora.h +15 -22
  15. data/dependencies/SDL/include/SDL_config_psp.h +16 -37
  16. data/dependencies/SDL/include/SDL_config_windows.h +28 -91
  17. data/dependencies/SDL/include/SDL_config_winrt.h +33 -61
  18. data/dependencies/SDL/include/SDL_config_wiz.h +28 -56
  19. data/dependencies/SDL/include/SDL_copying.h +1 -1
  20. data/dependencies/SDL/include/SDL_cpuinfo.h +331 -71
  21. data/dependencies/SDL/include/SDL_egl.h +906 -280
  22. data/dependencies/SDL/include/SDL_endian.h +101 -47
  23. data/dependencies/SDL/include/SDL_error.h +70 -19
  24. data/dependencies/SDL/include/SDL_events.h +387 -79
  25. data/dependencies/SDL/include/SDL_filesystem.h +73 -64
  26. data/dependencies/SDL/include/SDL_gamecontroller.h +585 -125
  27. data/dependencies/SDL/include/SDL_gesture.h +36 -6
  28. data/dependencies/SDL/include/SDL_haptic.h +304 -210
  29. data/dependencies/SDL/include/SDL_hidapi.h +451 -0
  30. data/dependencies/SDL/include/SDL_hints.h +1286 -897
  31. data/dependencies/SDL/include/SDL_joystick.h +577 -130
  32. data/dependencies/SDL/include/SDL_keyboard.h +162 -63
  33. data/dependencies/SDL/include/SDL_keycode.h +7 -5
  34. data/dependencies/SDL/include/SDL_loadso.h +42 -8
  35. data/dependencies/SDL/include/SDL_locale.h +34 -32
  36. data/dependencies/SDL/include/SDL_log.h +212 -19
  37. data/dependencies/SDL/include/SDL_main.h +72 -17
  38. data/dependencies/SDL/include/SDL_messagebox.h +70 -23
  39. data/dependencies/SDL/include/SDL_metal.h +27 -32
  40. data/dependencies/SDL/include/SDL_misc.h +19 -15
  41. data/dependencies/SDL/include/SDL_mouse.h +262 -110
  42. data/dependencies/SDL/include/SDL_mutex.h +286 -66
  43. data/dependencies/SDL/include/SDL_name.h +1 -1
  44. data/dependencies/SDL/include/SDL_opengl.h +1 -1
  45. data/dependencies/SDL/include/SDL_opengles.h +1 -1
  46. data/dependencies/SDL/include/SDL_opengles2.h +2 -2
  47. data/dependencies/SDL/include/SDL_pixels.h +199 -34
  48. data/dependencies/SDL/include/SDL_platform.h +39 -2
  49. data/dependencies/SDL/include/SDL_power.h +23 -10
  50. data/dependencies/SDL/include/SDL_quit.h +1 -1
  51. data/dependencies/SDL/include/SDL_rect.h +78 -28
  52. data/dependencies/SDL/include/SDL_render.h +1204 -472
  53. data/dependencies/SDL/include/SDL_revision.h +2 -2
  54. data/dependencies/SDL/include/SDL_rwops.h +605 -33
  55. data/dependencies/SDL/include/SDL_scancode.h +1 -1
  56. data/dependencies/SDL/include/SDL_sensor.h +76 -42
  57. data/dependencies/SDL/include/SDL_shape.h +38 -27
  58. data/dependencies/SDL/include/SDL_stdinc.h +96 -24
  59. data/dependencies/SDL/include/SDL_surface.h +571 -139
  60. data/dependencies/SDL/include/SDL_system.h +339 -101
  61. data/dependencies/SDL/include/SDL_syswm.h +50 -20
  62. data/dependencies/SDL/include/SDL_test.h +1 -1
  63. data/dependencies/SDL/include/SDL_test_assert.h +2 -2
  64. data/dependencies/SDL/include/SDL_test_common.h +23 -6
  65. data/dependencies/SDL/include/SDL_test_compare.h +1 -1
  66. data/dependencies/SDL/include/SDL_test_crc32.h +1 -1
  67. data/dependencies/SDL/include/SDL_test_font.h +3 -3
  68. data/dependencies/SDL/include/SDL_test_fuzzer.h +28 -26
  69. data/dependencies/SDL/include/SDL_test_harness.h +6 -6
  70. data/dependencies/SDL/include/SDL_test_images.h +1 -1
  71. data/dependencies/SDL/include/SDL_test_log.h +1 -1
  72. data/dependencies/SDL/include/SDL_test_md5.h +1 -1
  73. data/dependencies/SDL/include/SDL_test_memory.h +1 -1
  74. data/dependencies/SDL/include/SDL_test_random.h +2 -2
  75. data/dependencies/SDL/include/SDL_thread.h +226 -128
  76. data/dependencies/SDL/include/SDL_timer.h +129 -22
  77. data/dependencies/SDL/include/SDL_touch.h +48 -8
  78. data/dependencies/SDL/include/SDL_types.h +1 -1
  79. data/dependencies/SDL/include/SDL_version.h +72 -46
  80. data/dependencies/SDL/include/SDL_video.h +1266 -460
  81. data/dependencies/SDL/include/SDL_vulkan.h +100 -161
  82. data/dependencies/SDL/include/begin_code.h +22 -1
  83. data/dependencies/SDL/include/close_code.h +1 -1
  84. data/dependencies/SDL/lib/x64/libSDL2.dll.a +0 -0
  85. data/dependencies/SDL/lib/x86/libSDL2.dll.a +0 -0
  86. data/dependencies/SDL_sound/SDL_sound.c +83 -7
  87. data/dependencies/SDL_sound/SDL_sound.h +4 -4
  88. data/dependencies/SDL_sound/SDL_sound_aiff.c +9 -12
  89. data/dependencies/SDL_sound/SDL_sound_au.c +7 -7
  90. data/dependencies/SDL_sound/SDL_sound_coreaudio.c +3 -3
  91. data/dependencies/SDL_sound/SDL_sound_flac.c +1 -1
  92. data/dependencies/SDL_sound/SDL_sound_internal.h +17 -10
  93. data/dependencies/SDL_sound/SDL_sound_modplug.c +25 -27
  94. data/dependencies/SDL_sound/SDL_sound_mp3.c +5 -17
  95. data/dependencies/SDL_sound/SDL_sound_raw.c +11 -11
  96. data/dependencies/SDL_sound/SDL_sound_shn.c +8 -7
  97. data/dependencies/SDL_sound/SDL_sound_voc.c +6 -4
  98. data/dependencies/SDL_sound/SDL_sound_vorbis.c +6 -11
  99. data/dependencies/SDL_sound/SDL_sound_wav.c +35 -29
  100. data/dependencies/SDL_sound/dr_flac.h +618 -220
  101. data/dependencies/SDL_sound/dr_mp3.h +263 -94
  102. data/dependencies/SDL_sound/libmodplug/fastmix.c +58 -64
  103. data/dependencies/SDL_sound/libmodplug/libmodplug.h +25 -103
  104. data/dependencies/SDL_sound/libmodplug/load_669.c +14 -17
  105. data/dependencies/SDL_sound/libmodplug/load_amf.c +11 -7
  106. data/dependencies/SDL_sound/libmodplug/load_ams.c +65 -22
  107. data/dependencies/SDL_sound/libmodplug/load_dbm.c +8 -4
  108. data/dependencies/SDL_sound/libmodplug/load_dmf.c +55 -25
  109. data/dependencies/SDL_sound/libmodplug/load_far.c +9 -13
  110. data/dependencies/SDL_sound/libmodplug/load_gdm.c +448 -0
  111. data/dependencies/SDL_sound/libmodplug/load_it.c +45 -49
  112. data/dependencies/SDL_sound/libmodplug/load_mdl.c +80 -53
  113. data/dependencies/SDL_sound/libmodplug/load_med.c +20 -12
  114. data/dependencies/SDL_sound/libmodplug/load_mod.c +40 -15
  115. data/dependencies/SDL_sound/libmodplug/load_mt2.c +29 -17
  116. data/dependencies/SDL_sound/libmodplug/load_okt.c +12 -8
  117. data/dependencies/SDL_sound/libmodplug/load_psm.c +101 -78
  118. data/dependencies/SDL_sound/libmodplug/load_ptm.c +18 -17
  119. data/dependencies/SDL_sound/libmodplug/load_s3m.c +9 -7
  120. data/dependencies/SDL_sound/libmodplug/load_stm.c +3 -2
  121. data/dependencies/SDL_sound/libmodplug/load_ult.c +2 -2
  122. data/dependencies/SDL_sound/libmodplug/load_umx.c +315 -35
  123. data/dependencies/SDL_sound/libmodplug/load_xm.c +25 -21
  124. data/dependencies/SDL_sound/libmodplug/mmcmp.c +295 -149
  125. data/dependencies/SDL_sound/libmodplug/modplug.c +7 -123
  126. data/dependencies/SDL_sound/libmodplug/modplug.h +32 -29
  127. data/dependencies/SDL_sound/libmodplug/snd_dsp.c +0 -1
  128. data/dependencies/SDL_sound/libmodplug/snd_flt.c +2 -2
  129. data/dependencies/SDL_sound/libmodplug/snd_fx.c +24 -18
  130. data/dependencies/SDL_sound/libmodplug/sndfile.c +55 -156
  131. data/dependencies/SDL_sound/libmodplug/sndmix.c +7 -12
  132. data/dependencies/SDL_sound/libmodplug/tables.h +10 -15
  133. data/dependencies/SDL_sound/stb_vorbis.h +508 -325
  134. data/dependencies/{al_soft → mojoAL}/AL/al.h +38 -30
  135. data/dependencies/{al_soft → mojoAL}/AL/alc.h +27 -56
  136. data/dependencies/mojoAL/mojoal.c +4594 -0
  137. data/ext/gosu/extconf.rb +29 -30
  138. data/include/Gosu/Audio.hpp +70 -85
  139. data/include/Gosu/Color.hpp +19 -11
  140. data/include/Gosu/Font.hpp +40 -44
  141. data/include/Gosu/Graphics.hpp +58 -71
  142. data/include/Gosu/GraphicsBase.hpp +26 -33
  143. data/include/Gosu/Image.hpp +56 -62
  144. data/include/Gosu/ImageData.hpp +23 -27
  145. data/include/Gosu/Inspection.hpp +1 -4
  146. data/include/Gosu/TextInput.hpp +34 -40
  147. data/include/Gosu/Version.hpp +1 -1
  148. data/include/Gosu/Window.hpp +71 -70
  149. data/lib/SDL2.dll +0 -0
  150. data/lib/gosu/compat.rb +24 -37
  151. data/lib/gosu.rb +2 -2
  152. data/lib64/SDL2.dll +0 -0
  153. data/src/Audio.cpp +86 -86
  154. data/src/AudioFile.hpp +6 -6
  155. data/src/AudioFileAudioToolbox.cpp +1 -1
  156. data/src/AudioFileSDLSound.cpp +1 -1
  157. data/src/AudioImpl.hpp +5 -5
  158. data/src/BitmapIO.cpp +0 -20
  159. data/src/BlockAllocator.cpp +2 -1
  160. data/src/Channel.cpp +22 -20
  161. data/src/Color.cpp +12 -9
  162. data/src/EmptyImageData.hpp +15 -17
  163. data/src/FileUnix.cpp +1 -1
  164. data/src/FileWin.cpp +1 -1
  165. data/src/Font.cpp +48 -53
  166. data/src/Graphics.cpp +135 -143
  167. data/src/Image.cpp +41 -42
  168. data/src/Input.cpp +1 -1
  169. data/src/InputUIKit.cpp +1 -1
  170. data/src/LargeImageData.cpp +108 -101
  171. data/src/LargeImageData.hpp +17 -15
  172. data/src/Log.hpp +6 -6
  173. data/src/Macro.cpp +35 -37
  174. data/src/Macro.hpp +11 -11
  175. data/src/Math.cpp +8 -1
  176. data/src/Resolution.cpp +12 -7
  177. data/src/RubyGosu.cxx +5 -5
  178. data/src/TexChunk.cpp +50 -41
  179. data/src/TexChunk.hpp +22 -22
  180. data/src/Text.cpp +37 -37
  181. data/src/TextBuilder.cpp +60 -57
  182. data/src/TextBuilder.hpp +20 -20
  183. data/src/TextInput.cpp +127 -135
  184. data/src/TrueTypeFont.cpp +107 -107
  185. data/src/TrueTypeFont.hpp +39 -38
  186. data/src/TrueTypeFontApple.cpp +19 -22
  187. data/src/TrueTypeFontUnix.cpp +21 -26
  188. data/src/TrueTypeFontWin.cpp +30 -30
  189. data/src/Window.cpp +95 -86
  190. data/src/WindowUIKit.cpp +46 -49
  191. metadata +7 -17
  192. data/dependencies/SDL/include/SDL_config_os2.h +0 -188
  193. data/dependencies/SDL_sound/libmodplug/load_abc.c +0 -4725
  194. data/dependencies/SDL_sound/libmodplug/load_mid.c +0 -1405
  195. data/dependencies/SDL_sound/libmodplug/load_pat.c +0 -1143
  196. data/dependencies/SDL_sound/libmodplug/load_pat.h +0 -25
  197. data/dependencies/al_soft/AL/alext.h +0 -585
  198. data/dependencies/al_soft/AL/efx-creative.h +0 -3
  199. data/dependencies/al_soft/AL/efx-presets.h +0 -402
  200. data/dependencies/al_soft/AL/efx.h +0 -762
  201. data/dependencies/al_soft/x64/libOpenAL32.dll.a +0 -0
  202. data/dependencies/al_soft/x86/libOpenAL32.dll.a +0 -0
  203. data/lib/OpenAL32.dll +0 -0
  204. data/lib64/OpenAL32.dll +0 -0
@@ -1,50 +1,330 @@
1
1
  /*
2
2
  * This source code is public domain.
3
3
  *
4
- * Authors: Olivier Lapicque <olivierl@jps.net>
4
+ * Epic Games Unreal UMX container loading for libmodplug
5
+ * Written by O. Sezer <sezero@users.sourceforge.net>
6
+ * UPKG parsing partially based on Unreal Media Ripper (UMR) v0.3
7
+ * by Andy Ward <wardwh@swbell.net>, with additional updates
8
+ * by O. Sezer - see git repo at https://github.com/sezero/umr.git
9
+ * Retrieves the offset, size and object type directly from umx.
5
10
  */
6
11
 
7
12
  #include "libmodplug.h"
8
13
 
9
- #define MODMAGIC_OFFSET (20+31*30+130)
14
+
15
+ typedef LONG fci_t; /* FCompactIndex */
16
+
17
+ #define UPKG_HDR_TAG 0x9e2a83c1
18
+
19
+ struct _genhist { /* for upkg versions >= 68 */
20
+ LONG export_count;
21
+ LONG name_count;
22
+ };
23
+
24
+ struct upkg_hdr {
25
+ DWORD tag; /* UPKG_HDR_TAG */
26
+ LONG file_version;
27
+ DWORD pkg_flags;
28
+ LONG name_count; /* number of names in name table (>= 0) */
29
+ LONG name_offset; /* offset to name table (>= 0) */
30
+ LONG export_count; /* num. exports in export table (>= 0) */
31
+ LONG export_offset; /* offset to export table (>= 0) */
32
+ LONG import_count; /* num. imports in export table (>= 0) */
33
+ LONG import_offset; /* offset to import table (>= 0) */
34
+
35
+ /* number of GUIDs in heritage table (>= 1) and table's offset:
36
+ * only with versions < 68. */
37
+ LONG heritage_count;
38
+ LONG heritage_offset;
39
+ /* with versions >= 68: a GUID, a dword for generation count
40
+ * and export_count and name_count dwords for each generation: */
41
+ DWORD guid[4];
42
+ LONG generation_count;
43
+ #define UPKG_HDR_SIZE 64 /* 64 bytes up until here */
44
+ /*struct _genhist *gen;*/
45
+ };
46
+
47
+ #define UMUSIC_IT 0
48
+ #define UMUSIC_S3M 1
49
+ #define UMUSIC_XM 2
50
+ #define UMUSIC_MOD 3
51
+ #define UMUSIC_WAV 4
52
+ #define UMUSIC_MP2 5
53
+
54
+ static const char *mustype[] = {
55
+ "IT", "S3M", "XM", "MOD",
56
+ NULL
57
+ };
58
+
59
+ /* decode an FCompactIndex.
60
+ * original documentation by Tim Sweeney was at
61
+ * http://unreal.epicgames.com/Packages.htm
62
+ * also see Unreal Wiki:
63
+ * http://wiki.beyondunreal.com/Legacy:Package_File_Format/Data_Details
64
+ */
65
+ static fci_t get_fci (const char *in, int *pos)
66
+ {
67
+ LONG a;
68
+ int size;
69
+
70
+ size = 1;
71
+ a = in[0] & 0x3f;
72
+
73
+ if (in[0] & 0x40) {
74
+ size++;
75
+ a |= (in[1] & 0x7f) << 6;
76
+
77
+ if (in[1] & 0x80) {
78
+ size++;
79
+ a |= (in[2] & 0x7f) << 13;
80
+
81
+ if (in[2] & 0x80) {
82
+ size++;
83
+ a |= (in[3] & 0x7f) << 20;
84
+
85
+ if (in[3] & 0x80) {
86
+ size++;
87
+ a |= (in[4] & 0x3f) << 27;
88
+ }
89
+ }
90
+ }
91
+ }
92
+
93
+ if (in[0] & 0x80)
94
+ a = -a;
95
+
96
+ *pos += size;
97
+
98
+ return a;
99
+ }
100
+
101
+ static int get_objtype (const BYTE *membase, LONG memlen,
102
+ LONG ofs, int type)
103
+ {
104
+ if (type == UMUSIC_IT) {
105
+ _retry:
106
+ if (SDL_memcmp(membase + ofs, "IMPM", 4) == 0)
107
+ return UMUSIC_IT;
108
+ return -1;
109
+ }
110
+ if (type == UMUSIC_XM) {
111
+ if (SDL_memcmp(membase + ofs, "Extended Module: ", 17) != 0)
112
+ return -1;
113
+ if (*(membase + ofs + 37) != 0x1a) return -1;
114
+ return UMUSIC_XM;
115
+ }
116
+
117
+ if (type == UMUSIC_S3M) {
118
+ if (SDL_memcmp(membase + ofs + 44, "SCRM", 4) == 0)
119
+ return UMUSIC_S3M;
120
+ /*return -1;*/
121
+ /* SpaceMarines.umx and Starseek.umx from Return to NaPali
122
+ * report as "s3m" whereas the actual music format is "it" */
123
+ goto _retry;
124
+ }
125
+
126
+ if (type == UMUSIC_MOD) {
127
+ membase += ofs + 1080;
128
+ if (SDL_memcmp(membase, "M.K.", 4) == 0 || SDL_memcmp(membase, "M!K!", 4) == 0)
129
+ return UMUSIC_MOD;
130
+ return -1;
131
+ }
132
+
133
+ return -1;
134
+ }
135
+
136
+ static int read_export (const BYTE *membase, LONG memlen,
137
+ const struct upkg_hdr *hdr,
138
+ LONG *ofs, LONG *objsize)
139
+ {
140
+ char buf[40];
141
+ int idx = 0, t;
142
+
143
+ SDL_memcpy(buf, membase + *ofs, 40);
144
+
145
+ if (hdr->file_version < 40) idx += 8; /* 00 00 00 00 00 00 00 00 */
146
+ if (hdr->file_version < 60) idx += 16; /* 81 00 00 00 00 00 FF FF FF FF FF FF FF FF 00 00 */
147
+ get_fci(&buf[idx], &idx); /* skip junk */
148
+ t = get_fci(&buf[idx], &idx); /* type_name */
149
+ if (hdr->file_version > 61) idx += 4; /* skip export size */
150
+ *objsize = get_fci(&buf[idx], &idx);
151
+ *ofs += idx; /* offset for real data */
152
+
153
+ return t; /* return type_name index */
154
+ }
155
+
156
+ static int read_typname(const BYTE *membase, LONG memlen,
157
+ const struct upkg_hdr *hdr,
158
+ int idx, char *out)
159
+ {
160
+ int i, s;
161
+ long l, ofs, siz;
162
+ char buf[64];
163
+
164
+ if (idx >= hdr->name_count) return -1;
165
+ SDL_memset(buf, 0, 64);
166
+ for (i = 0, l = 0; i <= idx; i++) {
167
+ if ((ofs = hdr->name_offset + l) >= memlen)
168
+ return -1;
169
+ if ((siz = memlen - ofs) > 63) siz = 63;
170
+ SDL_memcpy(buf, membase + ofs, siz);
171
+ if (hdr->file_version >= 64) {
172
+ s = *(signed char *)buf; /* numchars *including* terminator */
173
+ if (s <= 0) return -1;
174
+ l += s + 5; /* 1 for buf[0], 4 for int32_t name_flags */
175
+ } else {
176
+ l += (long)SDL_strlen(buf);
177
+ l += 5; /* 1 for terminator, 4 for int32_t name_flags */
178
+ }
179
+ }
180
+
181
+ SDL_strlcpy(out, (hdr->file_version >= 64)? &buf[1] : buf, 64);
182
+ return 0;
183
+ }
184
+
185
+ static void umx_strupr(char *str)
186
+ {
187
+ while (*str) {
188
+ if (*str >= 'a' && *str <= 'z') {
189
+ *str -= ('a' - 'A');
190
+ }
191
+ str++;
192
+ }
193
+ }
194
+
195
+ static int probe_umx (const BYTE *membase, LONG memlen,
196
+ const struct upkg_hdr *hdr,
197
+ LONG *ofs, LONG *objsize)
198
+ {
199
+ int i, idx, t;
200
+ LONG s, pos;
201
+ char buf[64];
202
+
203
+ if (hdr->name_offset >= memlen ||
204
+ hdr->export_offset >= memlen ||
205
+ hdr->import_offset >= memlen) {
206
+ return -1;
207
+ }
208
+
209
+ /* Find the offset and size of the first IT, S3M or XM
210
+ * by parsing the exports table. The umx files should
211
+ * have only one export. Kran32.umx from Unreal has two,
212
+ * but both pointing to the same music. */
213
+ s = memlen - hdr->export_offset;
214
+ if (s <= 0) return -1;
215
+ if (s > 64) s = 64;
216
+ SDL_memcpy(buf, membase + hdr->export_offset, s);
217
+ for (; s < 64; ++s) buf[s] = 0x0; /* really? */
218
+
219
+ idx = 0;
220
+
221
+ get_fci(&buf[idx], &idx); /* skip class_index */
222
+ get_fci(&buf[idx], &idx); /* skip super_index */
223
+ if (hdr->file_version >= 60) idx += 4; /* skip int32 package_index */
224
+ get_fci(&buf[idx], &idx); /* skip object_name */
225
+ idx += 4; /* skip int32 object_flags */
226
+
227
+ s = get_fci(&buf[idx], &idx); /* get serial_size */
228
+ if (s <= 0) return -1;
229
+ pos = get_fci(&buf[idx],&idx); /* get serial_offset */
230
+ if (pos < 0 || pos > memlen - 40) return -1;
231
+
232
+ if ((t = read_export(membase, memlen, hdr, &pos, &s)) < 0) return -1;
233
+ if (s <= 0 || s > memlen - pos) return -1;
234
+
235
+ if (read_typname(membase, memlen, hdr, t, buf) < 0) return -1;
236
+ umx_strupr(buf);
237
+ for (i = 0; mustype[i] != NULL; i++) {
238
+ if (!SDL_strcmp(buf, mustype[i])) {
239
+ t = i;
240
+ break;
241
+ }
242
+ }
243
+ if (mustype[i] == NULL) return -1;
244
+ if ((t = get_objtype(membase, memlen, pos, t)) < 0) return -1;
245
+
246
+ *ofs = pos;
247
+ *objsize = s;
248
+ return t;
249
+ }
250
+
251
+ static int probe_header (void *header)
252
+ {
253
+ struct upkg_hdr *hdr;
254
+ unsigned char *p;
255
+ DWORD *swp;
256
+ int i;
257
+
258
+ /* byte swap the header - all members are 32 bit LE values */
259
+ p = (unsigned char *) header;
260
+ swp = (DWORD *) header;
261
+ for (i = 0; i < UPKG_HDR_SIZE/4; i++, p += 4) {
262
+ swp[i] = p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
263
+ }
264
+
265
+ hdr = (struct upkg_hdr *) header;
266
+ if (hdr->tag != UPKG_HDR_TAG) {
267
+ return -1;
268
+ }
269
+ if (hdr->name_count < 0 ||
270
+ hdr->export_count < 0 ||
271
+ hdr->import_count < 0 ||
272
+ hdr->name_offset < 36 ||
273
+ hdr->export_offset < 36 ||
274
+ hdr->import_offset < 36 ) {
275
+ return -1;
276
+ }
277
+
278
+ #if 1 /* no need being overzealous */
279
+ return 0;
280
+ #else
281
+ switch (hdr->file_version) {
282
+ case 35: case 37: /* Unreal beta - */
283
+ case 40: case 41: /* 1998 */
284
+ case 61:/* Unreal */
285
+ case 62:/* Unreal Tournament */
286
+ case 63:/* Return to NaPali */
287
+ case 64:/* Unreal Tournament */
288
+ case 66:/* Unreal Tournament */
289
+ case 68:/* Unreal Tournament */
290
+ case 69:/* Tactical Ops */
291
+ case 83:/* Mobile Forces */
292
+ return 0;
293
+ }
294
+
295
+ return -1;/* Unknown upkg version for an UMX */
296
+ #endif /* #if 0 */
297
+ }
298
+
299
+ static int process_upkg (const BYTE *membase, LONG memlen,
300
+ LONG *ofs, LONG *objsize)
301
+ {
302
+ char header[UPKG_HDR_SIZE];
303
+
304
+ SDL_memcpy(header, membase, UPKG_HDR_SIZE);
305
+ if (probe_header(header) < 0)
306
+ return -1;
307
+
308
+ return probe_umx(membase, memlen, (struct upkg_hdr *)header, ofs, objsize);
309
+ }
10
310
 
11
311
  BOOL CSoundFile_ReadUMX(CSoundFile *_this, const BYTE *lpStream, DWORD dwMemLength)
12
312
  //---------------------------------------------------------------
13
313
  {
14
- if ((!lpStream) || (dwMemLength < 0x800)) return FALSE;
314
+ int type;
315
+ LONG ofs = 0, size = 0;
316
+
317
+ if (!lpStream || dwMemLength < 0x800 || dwMemLength > 0x7fffffff)
318
+ return FALSE;
319
+ type = process_upkg(lpStream, (LONG)dwMemLength, &ofs, &size);
320
+ if (type < 0) return FALSE;
321
+
15
322
  // Rip Mods from UMX
16
- if ((bswapLE32(*((DWORD *)(lpStream+0x20))) < dwMemLength)
17
- && (bswapLE32(*((DWORD *)(lpStream+0x18))) <= dwMemLength - 0x10)
18
- && (bswapLE32(*((DWORD *)(lpStream+0x18))) >= dwMemLength - 0x200))
19
- {
20
- for (UINT uscan=0x40; uscan<0x500; uscan++)
21
- {
22
- DWORD dwScan = bswapLE32(*((DWORD *)(lpStream+uscan)));
23
- // IT
24
- if (dwScan == 0x4D504D49)
25
- {
26
- DWORD dwRipOfs = uscan;
27
- return CSoundFile_ReadIT(_this, lpStream + dwRipOfs, dwMemLength - dwRipOfs);
28
- }
29
- // S3M
30
- if (dwScan == 0x4D524353)
31
- {
32
- DWORD dwRipOfs = uscan - 44;
33
- return CSoundFile_ReadS3M(_this, lpStream + dwRipOfs, dwMemLength - dwRipOfs);
34
- }
35
- // XM
36
- if (!SDL_strncasecmp((LPCSTR)(lpStream+uscan), "Extended Module", 15))
37
- {
38
- DWORD dwRipOfs = uscan;
39
- return CSoundFile_ReadXM(_this, lpStream + dwRipOfs, dwMemLength - dwRipOfs);
40
- }
41
- // MOD
42
- if ((uscan > MODMAGIC_OFFSET) && (dwScan == 0x2e4b2e4d))
43
- {
44
- DWORD dwRipOfs = uscan - MODMAGIC_OFFSET;
45
- return CSoundFile_ReadMod(_this, lpStream+dwRipOfs, dwMemLength-dwRipOfs);
46
- }
47
- }
323
+ switch (type) {
324
+ case UMUSIC_IT: return CSoundFile_ReadIT(_this, lpStream + ofs, size);
325
+ case UMUSIC_S3M: return CSoundFile_ReadS3M(_this, lpStream + ofs, size);
326
+ case UMUSIC_XM: return CSoundFile_ReadXM(_this, lpStream + ofs, size);
327
+ case UMUSIC_MOD: return CSoundFile_ReadMod(_this, lpStream + ofs, size);
48
328
  }
49
329
  return FALSE;
50
330
  }
@@ -10,7 +10,7 @@
10
10
  ////////////////////////////////////////////////////////
11
11
  // FastTracker II XM file support
12
12
 
13
- #ifdef MSC_VER
13
+ #ifdef _MSC_VER
14
14
  #pragma warning(disable:4244)
15
15
  #endif
16
16
 
@@ -29,7 +29,6 @@ typedef struct tagXMFILEHEADER
29
29
  BYTE order[256];
30
30
  } XMFILEHEADER;
31
31
 
32
-
33
32
  typedef struct tagXMINSTRUMENTHEADER
34
33
  {
35
34
  DWORD size;
@@ -39,7 +38,6 @@ typedef struct tagXMINSTRUMENTHEADER
39
38
  BYTE samplesh;
40
39
  } XMINSTRUMENTHEADER;
41
40
 
42
-
43
41
  typedef struct tagXMSAMPLEHEADER
44
42
  {
45
43
  DWORD shsize;
@@ -70,7 +68,6 @@ typedef struct tagXMSAMPLESTRUCT
70
68
  } XMSAMPLESTRUCT;
71
69
  #pragma pack()
72
70
 
73
-
74
71
  BOOL CSoundFile_ReadXM(CSoundFile *_this, const BYTE *lpStream, DWORD dwMemLength)
75
72
  //--------------------------------------------------------------
76
73
  {
@@ -88,14 +85,16 @@ BOOL CSoundFile_ReadXM(CSoundFile *_this, const BYTE *lpStream, DWORD dwMemLengt
88
85
 
89
86
  _this->m_nChannels = 0;
90
87
  if ((!lpStream) || (dwMemLength < 0x200)) return FALSE;
91
- if (SDL_strncasecmp((LPCSTR)lpStream, "Extended Module", 15)) return FALSE;
88
+ if (SDL_strncmp((LPCSTR)lpStream, "Extended Module:", 16)) return FALSE;
92
89
 
93
90
  SDL_memcpy(&xmhead, lpStream+60, sizeof (xmhead));
94
91
  dwHdrSize = bswapLE32(xmhead.size);
95
92
  norders = bswapLE16(xmhead.norder);
96
- if ((!norders) || (norders > MAX_ORDERS)) return FALSE;
97
93
  restartpos = bswapLE16(xmhead.restartpos);
98
94
  channels = bswapLE16(xmhead.channels);
95
+
96
+ if ((!dwHdrSize) || dwHdrSize > dwMemLength - 60) return FALSE;
97
+ if ((!norders) || (norders > MAX_ORDERS)) return FALSE;
99
98
  if ((!channels) || (channels > 64)) return FALSE;
100
99
  _this->m_nType = MOD_TYPE_XM;
101
100
  _this->m_nMinPeriod = 27;
@@ -162,6 +161,7 @@ BOOL CSoundFile_ReadXM(CSoundFile *_this, const BYTE *lpStream, DWORD dwMemLengt
162
161
  dwMemPos++;
163
162
  dwSize = bswapLE32(*((DWORD *)(lpStream+dwMemPos)));
164
163
  }
164
+ if (dwMemPos + 9 > dwMemLength) return TRUE;
165
165
  rows = bswapLE16(*((WORD *)(lpStream+dwMemPos+5)));
166
166
  if ((!rows) || (rows > 256)) rows = 64;
167
167
  packsize = bswapLE16(*((WORD *)(lpStream+dwMemPos+7)));
@@ -188,13 +188,14 @@ BOOL CSoundFile_ReadXM(CSoundFile *_this, const BYTE *lpStream, DWORD dwMemLengt
188
188
  UINT vol = 0;
189
189
  if (b & 0x80)
190
190
  {
191
- if (b & 1) p->note = src[j++];
192
- if (b & 2) p->instr = src[j++];
193
- if (b & 4) vol = src[j++];
194
- if (b & 8) p->command = src[j++];
195
- if (b & 16) p->param = src[j++];
191
+ if ((b & 1) && j < packsize) p->note = src[j++];
192
+ if ((b & 2) && j < packsize) p->instr = src[j++];
193
+ if ((b & 4) && j < packsize) vol = src[j++];
194
+ if ((b & 8) && j < packsize) p->command = src[j++];
195
+ if ((b & 16) && j < packsize) p->param = src[j++];
196
196
  } else
197
197
  {
198
+ if (j + 5 > packsize) break;
198
199
  p->note = b;
199
200
  p->instr = src[j++];
200
201
  vol = src[j++];
@@ -276,15 +277,16 @@ BOOL CSoundFile_ReadXM(CSoundFile *_this, const BYTE *lpStream, DWORD dwMemLengt
276
277
  DWORD samplesize[32];
277
278
  UINT samplemap[32];
278
279
  WORD nsamples;
280
+ DWORD pihlen;
279
281
 
280
282
  if (dwMemPos + sizeof(XMINSTRUMENTHEADER) >= dwMemLength) return TRUE;
281
283
  pih = (XMINSTRUMENTHEADER *)(lpStream+dwMemPos);
282
- if (dwMemPos + bswapLE32(pih->size) > dwMemLength) return TRUE;
283
- if ((_this->Headers[iIns] = (INSTRUMENTHEADER *) SDL_malloc(sizeof (INSTRUMENTHEADER))) == NULL) continue;
284
- SDL_memset(_this->Headers[iIns], 0, sizeof(INSTRUMENTHEADER));
284
+ pihlen = bswapLE32(pih->size);
285
+ if (pihlen >= dwMemLength || dwMemPos > dwMemLength - pihlen) return TRUE;
286
+ if ((_this->Headers[iIns] = (INSTRUMENTHEADER *) SDL_calloc(1, sizeof(INSTRUMENTHEADER))) == NULL) continue;
285
287
  if ((nsamples = pih->samples) > 0)
286
288
  {
287
- if (dwMemPos + sizeof(XMSAMPLEHEADER) > dwMemLength) return TRUE;
289
+ if (dwMemPos + sizeof(XMINSTRUMENTHEADER) + sizeof(XMSAMPLEHEADER) > dwMemLength) return TRUE;
288
290
  SDL_memcpy(&xmsh, lpStream+dwMemPos+sizeof(XMINSTRUMENTHEADER), sizeof(XMSAMPLEHEADER));
289
291
  xmsh.shsize = bswapLE32(xmsh.shsize);
290
292
  for (int i = 0; i < 24; ++i) {
@@ -293,10 +295,10 @@ BOOL CSoundFile_ReadXM(CSoundFile *_this, const BYTE *lpStream, DWORD dwMemLengt
293
295
  }
294
296
  xmsh.volfade = bswapLE16(xmsh.volfade);
295
297
  xmsh.res = bswapLE16(xmsh.res);
296
- dwMemPos += bswapLE32(pih->size);
298
+ dwMemPos += pihlen;
297
299
  } else
298
300
  {
299
- if (bswapLE32(pih->size)) dwMemPos += bswapLE32(pih->size);
301
+ if (pihlen) dwMemPos += pihlen;
300
302
  else dwMemPos += sizeof(XMINSTRUMENTHEADER);
301
303
  continue;
302
304
  }
@@ -431,7 +433,7 @@ BOOL CSoundFile_ReadXM(CSoundFile *_this, const BYTE *lpStream, DWORD dwMemLengt
431
433
  for (UINT ins=0; ins<nsamples; ins++)
432
434
  {
433
435
  if ((dwMemPos + sizeof(xmss) > dwMemLength)
434
- || (dwMemPos + xmsh.shsize > dwMemLength)) return TRUE;
436
+ || (xmsh.shsize >= dwMemLength) || (dwMemPos > dwMemLength - xmsh.shsize)) return TRUE;
435
437
  SDL_memcpy(&xmss, lpStream+dwMemPos, sizeof(xmss));
436
438
  xmss.samplen = bswapLE32(xmss.samplen);
437
439
  xmss.loopstart = bswapLE32(xmss.loopstart);
@@ -512,6 +514,7 @@ BOOL CSoundFile_ReadXM(CSoundFile *_this, const BYTE *lpStream, DWORD dwMemLengt
512
514
  {
513
515
  UINT len = *((DWORD *)(lpStream+dwMemPos+4));
514
516
  dwMemPos += 8;
517
+ if (len >= dwMemLength || dwMemPos > dwMemLength - len) return TRUE;
515
518
  if (len == sizeof(MODMIDICFG))
516
519
  {
517
520
  SDL_memcpy(&_this->m_MidiCfg, lpStream+dwMemPos, len);
@@ -523,7 +526,8 @@ BOOL CSoundFile_ReadXM(CSoundFile *_this, const BYTE *lpStream, DWORD dwMemLengt
523
526
  {
524
527
  UINT len = *((DWORD *)(lpStream+dwMemPos+4));
525
528
  dwMemPos += 8;
526
- if ((dwMemPos + len <= dwMemLength) && (len <= MAX_PATTERNS*MAX_PATTERNNAME) && (len >= MAX_PATTERNNAME))
529
+ if (len >= dwMemLength || dwMemPos > dwMemLength - len) return TRUE;
530
+ if ((len <= MAX_PATTERNS*MAX_PATTERNNAME) && (len >= MAX_PATTERNNAME))
527
531
  {
528
532
  _this->m_lpszPatternNames = (char *) SDL_malloc(len);
529
533
  if (_this->m_lpszPatternNames)
@@ -539,7 +543,8 @@ BOOL CSoundFile_ReadXM(CSoundFile *_this, const BYTE *lpStream, DWORD dwMemLengt
539
543
  {
540
544
  UINT len = *((DWORD *)(lpStream+dwMemPos+4));
541
545
  dwMemPos += 8;
542
- if ((dwMemPos + len <= dwMemLength) && (len <= MAX_BASECHANNELS*MAX_CHANNELNAME))
546
+ if (len >= dwMemLength || dwMemPos > dwMemLength - len) return TRUE;
547
+ if (len <= MAX_BASECHANNELS*MAX_CHANNELNAME)
543
548
  {
544
549
  dwMemPos += len;
545
550
  }
@@ -551,4 +556,3 @@ BOOL CSoundFile_ReadXM(CSoundFile *_this, const BYTE *lpStream, DWORD dwMemLengt
551
556
  }
552
557
  return TRUE;
553
558
  }
554
-