gosu 1.4.1 → 1.4.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/dependencies/SDL_sound/SDL_sound.c +21 -63
- data/dependencies/SDL_sound/SDL_sound.h +2 -2
- data/dependencies/SDL_sound/SDL_sound_aiff.c +26 -23
- data/dependencies/SDL_sound/SDL_sound_au.c +8 -8
- data/dependencies/SDL_sound/SDL_sound_coreaudio.c +4 -5
- data/dependencies/SDL_sound/SDL_sound_flac.c +28 -30
- data/dependencies/SDL_sound/SDL_sound_internal.h +4 -4
- data/dependencies/SDL_sound/SDL_sound_modplug.c +1 -1
- data/dependencies/SDL_sound/SDL_sound_mp3.c +19 -23
- data/dependencies/SDL_sound/SDL_sound_raw.c +5 -6
- data/dependencies/SDL_sound/SDL_sound_shn.c +4 -4
- data/dependencies/SDL_sound/SDL_sound_voc.c +15 -15
- data/dependencies/SDL_sound/SDL_sound_vorbis.c +14 -7
- data/dependencies/SDL_sound/SDL_sound_wav.c +17 -17
- data/dependencies/SDL_sound/dr_flac.h +10840 -4779
- data/dependencies/SDL_sound/dr_mp3.h +2793 -1004
- data/dependencies/SDL_sound/libmodplug/fastmix.c +5 -0
- data/dependencies/SDL_sound/libmodplug/load_669.c +1 -1
- data/dependencies/SDL_sound/libmodplug/load_amf.c +1 -0
- data/dependencies/SDL_sound/libmodplug/load_ams.c +38 -22
- data/dependencies/SDL_sound/libmodplug/load_it.c +18 -14
- data/dependencies/SDL_sound/libmodplug/load_mdl.c +18 -9
- data/dependencies/SDL_sound/libmodplug/load_med.c +7 -6
- data/dependencies/SDL_sound/libmodplug/load_mt2.c +36 -17
- data/dependencies/SDL_sound/libmodplug/load_okt.c +51 -24
- data/dependencies/SDL_sound/libmodplug/load_psm.c +4 -2
- data/dependencies/SDL_sound/libmodplug/load_s3m.c +4 -4
- data/dependencies/SDL_sound/libmodplug/load_ult.c +4 -3
- data/dependencies/SDL_sound/libmodplug/load_xm.c +5 -5
- data/dependencies/SDL_sound/libmodplug/snd_fx.c +8 -1
- data/dependencies/SDL_sound/libmodplug/sndfile.c +21 -4
- data/dependencies/SDL_sound/stb_vorbis.h +10 -18
- data/dependencies/mojoAL/mojoal.c +260 -6
- data/dependencies/stb/stb_image.h +208 -73
- data/dependencies/stb/stb_image_write.h +57 -23
- data/dependencies/stb/stb_truetype.h +345 -279
- data/dependencies/utf8proc/utf8proc.c +37 -18
- data/dependencies/utf8proc/utf8proc.h +17 -5
- data/dependencies/utf8proc/utf8proc_data.h +12012 -10089
- data/ext/gosu/extconf.rb +6 -3
- data/include/Gosu/Buttons.hpp +103 -103
- data/include/Gosu/Directories.hpp +31 -24
- data/include/Gosu/Font.hpp +4 -2
- data/include/Gosu/Gosu.hpp +5 -8
- data/include/Gosu/IO.hpp +0 -3
- data/include/Gosu/Input.hpp +7 -1
- data/include/Gosu/Math.hpp +0 -3
- data/include/Gosu/TextInput.hpp +3 -3
- data/include/Gosu/Timing.hpp +3 -6
- data/include/Gosu/Version.hpp +1 -1
- data/include/Gosu/Window.hpp +3 -2
- data/rdoc/gosu.rb +16 -2
- data/src/Audio.cpp +2 -2
- data/src/AudioFileAudioToolbox.cpp +1 -1
- data/src/AudioFileSDLSound.cpp +1 -1
- data/src/AudioImpl.cpp +0 -7
- data/src/AudioImpl.hpp +1 -3
- data/src/BitmapIO.cpp +23 -2
- data/src/BlockAllocator.cpp +1 -1
- data/src/DirectoriesApple.cpp +25 -24
- data/src/DirectoriesUnix.cpp +14 -12
- data/src/DirectoriesWin.cpp +26 -30
- data/src/FileUnix.cpp +1 -1
- data/src/FileWin.cpp +1 -1
- data/src/Font.cpp +13 -3
- data/src/Graphics.cpp +1 -1
- data/src/Image.cpp +10 -15
- data/src/Input.cpp +16 -1
- data/src/InputUIKit.cpp +1 -1
- data/src/Macro.cpp +1 -1
- data/src/RubyGosu.cxx +76 -34
- data/src/TextInput.cpp +1 -1
- data/src/TimingApple.cpp +2 -2
- data/src/TimingUnix.cpp +3 -7
- data/src/TimingWin.cpp +1 -2
- data/src/TrueTypeFont.cpp +1 -1
- data/src/Window.cpp +5 -4
- data/src/WindowUIKit.cpp +1 -1
- metadata +3 -3
@@ -8,6 +8,11 @@
|
|
8
8
|
#include "libmodplug.h"
|
9
9
|
#include <math.h>
|
10
10
|
|
11
|
+
#include "SDL_stdinc.h"
|
12
|
+
#if !(defined(HAVE_LIBC) && defined(__WATCOMC__)) /* Watcom has issues... */
|
13
|
+
#define floor SDL_floor
|
14
|
+
#endif
|
15
|
+
|
11
16
|
/*
|
12
17
|
*-----------------------------------------------------------------------------
|
13
18
|
cubic spline interpolation doc,
|
@@ -16,7 +16,7 @@
|
|
16
16
|
typedef struct tagFILEHEADER669
|
17
17
|
{
|
18
18
|
WORD sig; // 'if' or 'JN'
|
19
|
-
|
19
|
+
char songmessage[108]; // Song Message
|
20
20
|
BYTE samples; // number of samples (1-64)
|
21
21
|
BYTE patterns; // number of patterns (1-128)
|
22
22
|
BYTE restartpos;
|
@@ -292,6 +292,7 @@ BOOL CSoundFile_ReadAMF(CSoundFile *_this, LPCBYTE lpStream, const DWORD dwMemLe
|
|
292
292
|
// Setup sequence list
|
293
293
|
for (UINT iOrd=0; iOrd<MAX_ORDERS; iOrd++)
|
294
294
|
{
|
295
|
+
if (dwMemPos + 4 > dwMemLength) return TRUE;
|
295
296
|
_this->Order[iOrd] = 0xFF;
|
296
297
|
if (iOrd < pfh->numorders)
|
297
298
|
{
|
@@ -138,6 +138,13 @@ BOOL CSoundFile_ReadAMS(CSoundFile *_this, LPCBYTE lpStream, DWORD dwMemLength)
|
|
138
138
|
while ((row < _this->PatternSize[iPat]) && (i+2 < len))
|
139
139
|
{
|
140
140
|
BYTE b0 = p[i++];
|
141
|
+
|
142
|
+
if (b0 == 0xff)
|
143
|
+
{
|
144
|
+
row++;
|
145
|
+
continue;
|
146
|
+
}
|
147
|
+
|
141
148
|
BYTE b1 = p[i++];
|
142
149
|
BYTE b2 = 0;
|
143
150
|
UINT ch = b0 & 0x3F;
|
@@ -467,40 +474,49 @@ BOOL CSoundFile_ReadAMS2(CSoundFile *_this, LPCBYTE lpStream, DWORD dwMemLength)
|
|
467
474
|
{
|
468
475
|
MODCOMMAND *m = _this->Patterns[ipat] + row * _this->m_nChannels;
|
469
476
|
UINT byte1 = psrc[pos++];
|
477
|
+
UINT byte2;
|
470
478
|
UINT ch = byte1 & 0x1F;
|
479
|
+
if (byte1 == 0xff)
|
480
|
+
{
|
481
|
+
row++;
|
482
|
+
continue;
|
483
|
+
}
|
484
|
+
|
471
485
|
// Read Note + Instr
|
472
486
|
if (!(byte1 & 0x40))
|
473
487
|
{
|
474
|
-
|
488
|
+
byte2 = psrc[pos++];
|
475
489
|
UINT note = byte2 & 0x7F;
|
476
490
|
if (note) m[ch].note = (note > 1) ? (note-1) : 0xFF;
|
477
491
|
m[ch].instr = psrc[pos++];
|
478
|
-
|
479
|
-
|
492
|
+
} else {
|
493
|
+
byte2 = 0x80; /* row contains atleast one effect, so trigged the first parse */
|
494
|
+
}
|
495
|
+
// Read Effect
|
496
|
+
while (byte2 & 0x80)
|
497
|
+
{
|
498
|
+
byte2 = psrc[pos++];
|
499
|
+
if (byte2 & 0x40)
|
480
500
|
{
|
481
|
-
|
482
|
-
|
501
|
+
m[ch].volcmd = VOLCMD_VOLUME;
|
502
|
+
m[ch].vol = byte2 & 0x3F;
|
503
|
+
} else
|
504
|
+
{
|
505
|
+
UINT command = byte2 & 0x3F;
|
506
|
+
UINT param = psrc[pos++];
|
507
|
+
if (command == 0x0C)
|
483
508
|
{
|
484
509
|
m[ch].volcmd = VOLCMD_VOLUME;
|
485
|
-
m[ch].vol =
|
510
|
+
m[ch].vol = param / 2;
|
486
511
|
} else
|
512
|
+
if (command < 0x10)
|
487
513
|
{
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
} else
|
495
|
-
if (command < 0x10)
|
496
|
-
{
|
497
|
-
m[ch].command = command;
|
498
|
-
m[ch].param = param;
|
499
|
-
CSoundFile_ConvertModCommand(_this, &m[ch]);
|
500
|
-
} else
|
501
|
-
{
|
502
|
-
// TODO: AMS effects
|
503
|
-
}
|
514
|
+
m[ch].command = command;
|
515
|
+
m[ch].param = param;
|
516
|
+
CSoundFile_ConvertModCommand(_this, &m[ch]);
|
517
|
+
} else
|
518
|
+
{
|
519
|
+
// TODO: AMS effects
|
504
520
|
}
|
505
521
|
}
|
506
522
|
}
|
@@ -393,16 +393,16 @@ BOOL CSoundFile_ReadIT(CSoundFile *_this, const BYTE *lpStream, DWORD dwMemLengt
|
|
393
393
|
if (pis.flags & 2)
|
394
394
|
{
|
395
395
|
flags += 5;
|
396
|
-
if (pis.flags & 4) flags |= RSF_STEREO;
|
397
396
|
pins->uFlags |= CHN_16BIT;
|
398
397
|
// IT 2.14 16-bit packed sample ?
|
399
398
|
if (pis.flags & 8) flags = ((pifh.cmwt >= 0x215) && (pis.cvt & 4)) ? RS_IT21516 : RS_IT21416;
|
399
|
+
if (pis.flags & 4) flags |= RSF_STEREO;
|
400
400
|
} else
|
401
401
|
{
|
402
|
-
if (pis.flags & 4) flags |= RSF_STEREO;
|
403
402
|
if (pis.cvt == 0xFF) flags = RS_ADPCM4; else
|
404
403
|
// IT 2.14 8-bit packed sample ?
|
405
404
|
if (pis.flags & 8) flags = ((pifh.cmwt >= 0x215) && (pis.cvt & 4)) ? RS_IT2158 : RS_IT2148;
|
405
|
+
if (pis.flags & 4) flags |= RSF_STEREO;
|
406
406
|
}
|
407
407
|
CSoundFile_ReadSample(_this, &_this->Ins[nsmp+1], flags, (LPSTR)(lpStream+pis.samplepointer), dwMemLength - pis.samplepointer);
|
408
408
|
}
|
@@ -592,12 +592,13 @@ static DWORD ITReadBits(DWORD *bitbuf, UINT *bitnum, LPBYTE *_ibuf, LPBYTE ibufe
|
|
592
592
|
}
|
593
593
|
|
594
594
|
#define IT215_SUPPORT
|
595
|
-
|
596
|
-
|
595
|
+
DWORD ITUnpack8Bit(signed char *pSample, DWORD dwLen, LPBYTE lpMemFile, DWORD dwMemLength, DWORD channels, BOOL b215)
|
596
|
+
//-------------------------------------------------------------------------------------------------------------------
|
597
597
|
{
|
598
598
|
signed char *pDst = pSample;
|
599
599
|
LPBYTE pSrc = lpMemFile;
|
600
600
|
LPBYTE pStop = lpMemFile + dwMemLength;
|
601
|
+
DWORD writePos = 0;
|
601
602
|
// DWORD wHdr = 0;
|
602
603
|
DWORD wCount = 0;
|
603
604
|
DWORD bitbuf = 0;
|
@@ -658,29 +659,31 @@ void ITUnpack8Bit(signed char *pSample, DWORD dwLen, LPBYTE lpMemFile, DWORD dwM
|
|
658
659
|
bTemp = (BYTE)wBits;
|
659
660
|
bTemp2 += bTemp;
|
660
661
|
#ifdef IT215_SUPPORT
|
661
|
-
pDst[
|
662
|
+
pDst[writePos] = (b215) ? bTemp2 : bTemp;
|
662
663
|
#else
|
663
|
-
pDst[
|
664
|
+
pDst[writePos] = bTemp;
|
664
665
|
#endif
|
665
666
|
SkipByte:
|
666
667
|
dwPos++;
|
668
|
+
writePos += channels;
|
667
669
|
Next:
|
668
|
-
if (pSrc >= pStop + 1) return;
|
670
|
+
if (pSrc >= pStop + 1) return (DWORD)(pSrc - lpMemFile);
|
669
671
|
} while (dwPos < d);
|
670
672
|
// Move On
|
671
673
|
wCount -= d;
|
672
674
|
dwLen -= d;
|
673
|
-
pDst += d;
|
674
675
|
}
|
676
|
+
return (DWORD)(pSrc - lpMemFile);
|
675
677
|
}
|
676
678
|
|
677
679
|
|
678
|
-
|
679
|
-
|
680
|
+
DWORD ITUnpack16Bit(signed char *pSample, DWORD dwLen, LPBYTE lpMemFile, DWORD dwMemLength, DWORD channels, BOOL b215)
|
681
|
+
//--------------------------------------------------------------------------------------------------------------------
|
680
682
|
{
|
681
683
|
signed short *pDst = (signed short *)pSample;
|
682
684
|
LPBYTE pSrc = lpMemFile;
|
683
685
|
LPBYTE pStop = lpMemFile + dwMemLength;
|
686
|
+
DWORD writePos = 0;
|
684
687
|
// DWORD wHdr = 0;
|
685
688
|
DWORD wCount = 0;
|
686
689
|
DWORD bitbuf = 0;
|
@@ -742,21 +745,22 @@ void ITUnpack16Bit(signed char *pSample, DWORD dwLen, LPBYTE lpMemFile, DWORD dw
|
|
742
745
|
wTemp = (signed short)dwBits;
|
743
746
|
wTemp2 += wTemp;
|
744
747
|
#ifdef IT215_SUPPORT
|
745
|
-
pDst[
|
748
|
+
pDst[writePos] = (b215) ? wTemp2 : wTemp;
|
746
749
|
#else
|
747
|
-
pDst[
|
750
|
+
pDst[writePos] = wTemp;
|
748
751
|
#endif
|
749
752
|
SkipByte:
|
750
753
|
dwPos++;
|
754
|
+
writePos += channels;
|
751
755
|
Next:
|
752
|
-
if (pSrc >= pStop + 1) return;
|
756
|
+
if (pSrc >= pStop + 1) return (DWORD)(pSrc - lpMemFile);
|
753
757
|
} while (dwPos < d);
|
754
758
|
// Move On
|
755
759
|
wCount -= d;
|
756
760
|
dwLen -= d;
|
757
|
-
pDst += d;
|
758
761
|
if (pSrc >= pStop) break;
|
759
762
|
}
|
763
|
+
return (DWORD)(pSrc - lpMemFile);
|
760
764
|
}
|
761
765
|
|
762
766
|
UINT CSoundFile_LoadMixPlugins(CSoundFile *_this, const void *pData, UINT nLen)
|
@@ -122,17 +122,17 @@ static void UnpackMDLTrack(MODCOMMAND *pat, UINT nChannels, UINT nRows, UINT nTr
|
|
122
122
|
|
123
123
|
case 0x03:
|
124
124
|
{
|
125
|
-
cmd.note = (xx & 0x01) ? lpTracks[pos++] : 0;
|
126
|
-
cmd.instr = (xx & 0x02) ? lpTracks[pos++] : 0;
|
125
|
+
cmd.note = (xx & 0x01) ? (pos < len ? lpTracks[pos++] : 0) : 0;
|
126
|
+
cmd.instr = (xx & 0x02) ? (pos < len ? lpTracks[pos++] : 0) : 0;
|
127
127
|
cmd.volcmd = cmd.vol = 0;
|
128
128
|
cmd.command = cmd.param = 0;
|
129
129
|
if ((cmd.note < NOTE_MAX-12) && (cmd.note)) cmd.note += 12;
|
130
|
-
UINT volume = (xx & 0x04) ? lpTracks[pos++] : 0;
|
131
|
-
UINT commands = (xx & 0x08) ? lpTracks[pos++] : 0;
|
130
|
+
UINT volume = (xx & 0x04) ? (pos < len ? lpTracks[pos++] : 0) : 0;
|
131
|
+
UINT commands = (xx & 0x08) ? (pos < len ? lpTracks[pos++] : 0) : 0;
|
132
132
|
UINT command1 = commands & 0x0F;
|
133
133
|
UINT command2 = commands & 0xF0;
|
134
|
-
UINT param1 = (xx & 0x10) ? lpTracks[pos++] : 0;
|
135
|
-
UINT param2 = (xx & 0x20) ? lpTracks[pos++] : 0;
|
134
|
+
UINT param1 = (xx & 0x10) ? (pos < len ? lpTracks[pos++] : 0) : 0;
|
135
|
+
UINT param2 = (xx & 0x20) ? (pos < len ? lpTracks[pos++] : 0) : 0;
|
136
136
|
if ((command1 == 0x0E) && ((param1 & 0xF0) == 0xF0) && (!command2))
|
137
137
|
{
|
138
138
|
param1 = ((param1 & 0x0F) << 8) | param2;
|
@@ -208,6 +208,7 @@ BOOL CSoundFile_ReadMDL(CSoundFile *_this, const BYTE *lpStream, DWORD dwMemLeng
|
|
208
208
|
{
|
209
209
|
// IN: infoblock
|
210
210
|
case 0x4E49:
|
211
|
+
if (blocklen < sizeof(MDLINFOBLOCK)) break;
|
211
212
|
pmib = (const MDLINFOBLOCK *)(lpStream+dwMemPos);
|
212
213
|
norders = pmib->norders;
|
213
214
|
if (norders > MAX_ORDERS) norders = MAX_ORDERS;
|
@@ -263,6 +264,7 @@ BOOL CSoundFile_ReadMDL(CSoundFile *_this, const BYTE *lpStream, DWORD dwMemLeng
|
|
263
264
|
break;
|
264
265
|
// TR: Track Data
|
265
266
|
case 0x5254:
|
267
|
+
if (blocklen < 2) break;
|
266
268
|
if (dwTrackPos) break;
|
267
269
|
pp = lpStream + dwMemPos;
|
268
270
|
ntracks = pp[0] | (pp[1] << 8);
|
@@ -272,7 +274,9 @@ BOOL CSoundFile_ReadMDL(CSoundFile *_this, const BYTE *lpStream, DWORD dwMemLeng
|
|
272
274
|
case 0x4949:
|
273
275
|
ninstruments = lpStream[dwMemPos];
|
274
276
|
dwPos = dwMemPos+1;
|
275
|
-
|
277
|
+
if (blocklen < sizeof(INSTRUMENTHEADER)*ninstruments + 1) break;
|
278
|
+
|
279
|
+
for (i=0; i<ninstruments; i++)
|
276
280
|
{
|
277
281
|
UINT nins = lpStream[dwPos];
|
278
282
|
if ((nins >= MAX_INSTRUMENTS) || (!nins)) break;
|
@@ -282,6 +286,7 @@ BOOL CSoundFile_ReadMDL(CSoundFile *_this, const BYTE *lpStream, DWORD dwMemLeng
|
|
282
286
|
UINT note = 12;
|
283
287
|
if ((_this->Headers[nins] = (INSTRUMENTHEADER *) SDL_calloc(1, sizeof (INSTRUMENTHEADER))) == NULL) break;
|
284
288
|
INSTRUMENTHEADER *penv = _this->Headers[nins];
|
289
|
+
if (dwPos > dwMemLength - 34) break;
|
285
290
|
penv->nGlobalVol = 64;
|
286
291
|
penv->nPPC = 5*12;
|
287
292
|
if (34 + 14u*lpStream[dwPos+1] > dwMemLength - dwPos) break;
|
@@ -321,6 +326,7 @@ BOOL CSoundFile_ReadMDL(CSoundFile *_this, const BYTE *lpStream, DWORD dwMemLeng
|
|
321
326
|
}
|
322
327
|
}
|
323
328
|
dwPos += 34 + 14*lpStream[dwPos+1];
|
329
|
+
if (dwPos > dwMemLength - 2) break;
|
324
330
|
}
|
325
331
|
for (j=1; j<=_this->m_nInstruments; j++) if (!_this->Headers[j])
|
326
332
|
{
|
@@ -412,13 +418,16 @@ BOOL CSoundFile_ReadMDL(CSoundFile *_this, const BYTE *lpStream, DWORD dwMemLeng
|
|
412
418
|
for (UINT chn=0; chn<_this->m_nChannels; chn++) if ((patterntracks[ipat*32+chn]) && (patterntracks[ipat*32+chn] <= ntracks))
|
413
419
|
{
|
414
420
|
const BYTE *lpTracks = lpStream + dwTrackPos;
|
415
|
-
UINT len =
|
421
|
+
UINT len = 0;
|
422
|
+
if (dwTrackPos + 2 < dwMemLength)
|
423
|
+
len = lpTracks[0] | (lpTracks[1] << 8);
|
424
|
+
|
416
425
|
if (len < dwMemLength-dwTrackPos) {
|
417
426
|
MODCOMMAND *m = _this->Patterns[ipat] + chn;
|
418
427
|
UINT nTrack = patterntracks[ipat*32+chn];
|
419
428
|
|
420
429
|
lpTracks += 2;
|
421
|
-
for (UINT ntrk=1; ntrk<nTrack && lpTracks
|
430
|
+
for (UINT ntrk=1; ntrk<nTrack && lpTracks < (dwMemLength + lpStream - len - 2); ntrk++)
|
422
431
|
{
|
423
432
|
lpTracks += len;
|
424
433
|
len = lpTracks[0] | (lpTracks[1] << 8);
|
@@ -575,8 +575,8 @@ BOOL CSoundFile_ReadMed(CSoundFile *_this, const BYTE *lpStream, DWORD dwMemLeng
|
|
575
575
|
nSections = 0;
|
576
576
|
}
|
577
577
|
UINT pseq = 0;
|
578
|
-
|
579
|
-
if ((playseqtable) && (playseqtable < dwMemLength) && (nplayseq*4
|
578
|
+
|
579
|
+
if ((playseqtable) && (playseqtable < dwMemLength - 4) && ((nplayseq+1)*4 < dwMemLength - playseqtable))
|
580
580
|
{
|
581
581
|
pseq = bswapBE32(((LPDWORD)(lpStream+playseqtable))[nplayseq]);
|
582
582
|
}
|
@@ -624,11 +624,12 @@ BOOL CSoundFile_ReadMed(CSoundFile *_this, const BYTE *lpStream, DWORD dwMemLeng
|
|
624
624
|
UINT len = bswapBE32(psdh->length);
|
625
625
|
if ((len > MAX_SAMPLE_LENGTH) || (dwPos + len + 6 > dwMemLength)) len = 0;
|
626
626
|
UINT flags = RS_PCM8S, stype = bswapBE16(psdh->type);
|
627
|
-
dwPos
|
627
|
+
LPSTR psdata = (LPSTR)(lpStream + dwPos + 6);
|
628
|
+
UINT bLimit = dwMemLength - dwPos - 6;
|
628
629
|
if (stype & 0x80)
|
629
630
|
{
|
630
|
-
|
631
|
-
|
631
|
+
psdata += (stype & 0x20) ? 14 : 6;
|
632
|
+
bLimit -= (stype & 0x20) ? 14 : 6;
|
632
633
|
} else
|
633
634
|
{
|
634
635
|
if (stype & 0x10)
|
@@ -643,7 +644,7 @@ BOOL CSoundFile_ReadMed(CSoundFile *_this, const BYTE *lpStream, DWORD dwMemLeng
|
|
643
644
|
if (stype & 0x20) len /= 2;
|
644
645
|
}
|
645
646
|
_this->Ins[iSmp+1].nLength = len;
|
646
|
-
CSoundFile_ReadSample(_this, &_this->Ins[iSmp+1], flags,
|
647
|
+
CSoundFile_ReadSample(_this, &_this->Ins[iSmp+1], flags, psdata, bLimit);
|
647
648
|
}
|
648
649
|
// Reading patterns (blocks)
|
649
650
|
if (wNumBlocks > MAX_PATTERNS) wNumBlocks = MAX_PATTERNS;
|
@@ -122,6 +122,19 @@ typedef struct _MT2GROUP
|
|
122
122
|
#pragma pack()
|
123
123
|
|
124
124
|
|
125
|
+
static int calcNumOnes(int number) {
|
126
|
+
int cnt = 0;
|
127
|
+
|
128
|
+
while(number)
|
129
|
+
{
|
130
|
+
number &= (number -1);
|
131
|
+
cnt ++;
|
132
|
+
}
|
133
|
+
|
134
|
+
return(cnt);
|
135
|
+
}
|
136
|
+
|
137
|
+
|
125
138
|
static VOID ConvertMT2Command(CSoundFile *that, MODCOMMAND *m, const MT2COMMAND *p)
|
126
139
|
//---------------------------------------------------------------------------
|
127
140
|
{
|
@@ -188,7 +201,7 @@ BOOL CSoundFile_ReadMT2(CSoundFile *_this, LPCBYTE lpStream, DWORD dwMemLength)
|
|
188
201
|
const MT2INSTRUMENT *InstrMap[255];
|
189
202
|
const MT2SAMPLE *SampleMap[256];
|
190
203
|
|
191
|
-
if ((!lpStream) || (dwMemLength < sizeof(MT2FILEHEADER))
|
204
|
+
if ((!lpStream) || (dwMemLength < sizeof(MT2FILEHEADER) + 4)
|
192
205
|
|| (pfh->dwMT20 != 0x3032544D)
|
193
206
|
|| (pfh->wVersion < 0x0200) || (pfh->wVersion >= 0x0300)
|
194
207
|
|| (pfh->wChannels < 4) || (pfh->wChannels > 64)) return FALSE;
|
@@ -246,6 +259,7 @@ BOOL CSoundFile_ReadMT2(CSoundFile *_this, LPCBYTE lpStream, DWORD dwMemLength)
|
|
246
259
|
UINT wDataLen = (pmp->wDataLen + 1) & ~1;
|
247
260
|
dwMemPos += 6;
|
248
261
|
if (dwMemPos > dwMemLength - wDataLen || wDataLen > dwMemLength) break;
|
262
|
+
|
249
263
|
UINT nLines = pmp->wLines;
|
250
264
|
if ((iPat < MAX_PATTERNS) && (nLines > 0) && (nLines <= 256))
|
251
265
|
{
|
@@ -254,11 +268,13 @@ BOOL CSoundFile_ReadMT2(CSoundFile *_this, LPCBYTE lpStream, DWORD dwMemLength)
|
|
254
268
|
if (!_this->Patterns[iPat]) return TRUE;
|
255
269
|
MODCOMMAND *m = _this->Patterns[iPat];
|
256
270
|
UINT len = wDataLen;
|
271
|
+
if (len <= 4) return TRUE;
|
272
|
+
|
257
273
|
if (pfh->fulFlags & 1) // Packed Patterns
|
258
274
|
{
|
259
275
|
const BYTE *p = lpStream+dwMemPos;
|
260
276
|
UINT pos = 0, row=0, ch=0;
|
261
|
-
while (pos < len)
|
277
|
+
while (pos < len - 4)
|
262
278
|
{
|
263
279
|
MT2COMMAND cmd;
|
264
280
|
UINT infobyte = p[pos++];
|
@@ -273,13 +289,14 @@ BOOL CSoundFile_ReadMT2(CSoundFile *_this, LPCBYTE lpStream, DWORD dwMemLength)
|
|
273
289
|
{
|
274
290
|
UINT patpos = row*_this->m_nChannels+ch;
|
275
291
|
cmd.note = cmd.instr = cmd.vol = cmd.pan = cmd.fxcmd = cmd.fxparam1 = cmd.fxparam2 = 0;
|
276
|
-
if (
|
277
|
-
if (
|
278
|
-
if (
|
279
|
-
if (
|
280
|
-
if (
|
281
|
-
if (
|
282
|
-
if (
|
292
|
+
if (pos >= len - calcNumOnes(infobyte & 0x7F)) break;
|
293
|
+
if (infobyte & 1) cmd.note = p[pos++];
|
294
|
+
if (infobyte & 2) cmd.instr = p[pos++];
|
295
|
+
if (infobyte & 4) cmd.vol = p[pos++];
|
296
|
+
if (infobyte & 8) cmd.pan = p[pos++];
|
297
|
+
if (infobyte & 16) cmd.fxcmd = p[pos++];
|
298
|
+
if (infobyte & 32) cmd.fxparam1 = p[pos++];
|
299
|
+
if (infobyte & 64) cmd.fxparam2 = p[pos++];
|
283
300
|
ConvertMT2Command(_this, &m[patpos], &cmd);
|
284
301
|
}
|
285
302
|
row += rptcount+1;
|
@@ -361,7 +378,7 @@ BOOL CSoundFile_ReadMT2(CSoundFile *_this, LPCBYTE lpStream, DWORD dwMemLength)
|
|
361
378
|
{
|
362
379
|
if (dwMemPos + sizeof(MT2INSTRUMENT) - 4 > dwMemLength) return TRUE;
|
363
380
|
InstrMap[iIns-1] = pmi;
|
364
|
-
if (penv)
|
381
|
+
if (penv && pmi->dwDataLen >= sizeof(MT2INSTRUMENT) - 40)
|
365
382
|
{
|
366
383
|
penv->nFadeOut = pmi->wFadeOut;
|
367
384
|
penv->nNNA = pmi->wNNA & 3;
|
@@ -397,6 +414,10 @@ BOOL CSoundFile_ReadMT2(CSoundFile *_this, LPCBYTE lpStream, DWORD dwMemLength)
|
|
397
414
|
pedata[i] = NULL;
|
398
415
|
}
|
399
416
|
}
|
417
|
+
|
418
|
+
// envelopes exceed file length?
|
419
|
+
if (dwEnvPos > dwMemLength) return TRUE;
|
420
|
+
|
400
421
|
}
|
401
422
|
// Load envelopes
|
402
423
|
for (UINT iEnv=0; iEnv<4; iEnv++) if (pehdr[iEnv])
|
@@ -467,7 +488,7 @@ BOOL CSoundFile_ReadMT2(CSoundFile *_this, LPCBYTE lpStream, DWORD dwMemLength)
|
|
467
488
|
_this->m_nSamples = (pfh->wSamples < MAX_SAMPLES) ? pfh->wSamples : MAX_SAMPLES-1;
|
468
489
|
for (UINT iSmp=1; iSmp<=256; iSmp++)
|
469
490
|
{
|
470
|
-
if (dwMemPos
|
491
|
+
if (dwMemPos > dwMemLength - 36) return TRUE;
|
471
492
|
const MT2SAMPLE *pms = (MT2SAMPLE *)(lpStream+dwMemPos);
|
472
493
|
if (pms->dwDataLen > dwMemLength - (dwMemPos+36)) return TRUE;
|
473
494
|
if (pms->dwDataLen > 0)
|
@@ -505,8 +526,7 @@ BOOL CSoundFile_ReadMT2(CSoundFile *_this, LPCBYTE lpStream, DWORD dwMemLength)
|
|
505
526
|
if (iMap<_this->m_nInstruments) penv = _this->Headers[iMap+1];
|
506
527
|
for (UINT iGrp=0; iGrp<pmi->wSamples; iGrp++)
|
507
528
|
{
|
508
|
-
if (dwMemPos
|
509
|
-
if (penv)
|
529
|
+
if (penv && dwMemPos < dwMemLength && dwMemPos < dwMemLength - 8)
|
510
530
|
{
|
511
531
|
const MT2GROUP *pmg = (MT2GROUP *)(lpStream+dwMemPos);
|
512
532
|
for (UINT i=0; i<96; i++)
|
@@ -537,7 +557,7 @@ BOOL CSoundFile_ReadMT2(CSoundFile *_this, LPCBYTE lpStream, DWORD dwMemLength)
|
|
537
557
|
if (psmp->nLength > 0 && dwMemPos < dwMemLength)
|
538
558
|
{
|
539
559
|
UINT rsflags;
|
540
|
-
|
560
|
+
|
541
561
|
if (pms->nChannels == 2)
|
542
562
|
rsflags = (psmp->uFlags & CHN_16BIT) ? RS_STPCM16D : RS_STPCM8D;
|
543
563
|
else
|
@@ -546,13 +566,12 @@ BOOL CSoundFile_ReadMT2(CSoundFile *_this, LPCBYTE lpStream, DWORD dwMemLength)
|
|
546
566
|
dwMemPos += CSoundFile_ReadSample(_this, psmp, rsflags, (LPCSTR)(lpStream+dwMemPos), dwMemLength-dwMemPos);
|
547
567
|
}
|
548
568
|
} else
|
549
|
-
if (dwMemPos
|
569
|
+
if (dwMemPos < dwMemLength-4)
|
550
570
|
{
|
551
571
|
UINT nNameLen = *(DWORD *)(lpStream+dwMemPos);
|
552
572
|
dwMemPos += nNameLen + 16;
|
553
573
|
}
|
554
|
-
if (dwMemPos
|
574
|
+
if (dwMemPos >= dwMemLength-4) break;
|
555
575
|
}
|
556
576
|
return TRUE;
|
557
577
|
}
|
558
|
-
|
@@ -10,18 +10,20 @@
|
|
10
10
|
//////////////////////////////////////////////
|
11
11
|
#include "libmodplug.h"
|
12
12
|
|
13
|
+
#define MAGIC(a,b,c,d) (((a) << 24UL) | ((b) << 16UL) | ((c) << 8UL) | (d))
|
14
|
+
|
15
|
+
#pragma pack(1)
|
13
16
|
typedef struct OKTFILEHEADER
|
14
17
|
{
|
15
18
|
DWORD okta; // "OKTA"
|
16
19
|
DWORD song; // "SONG"
|
17
20
|
DWORD cmod; // "CMOD"
|
18
|
-
DWORD
|
21
|
+
DWORD cmodlen;
|
19
22
|
BYTE chnsetup[8];
|
20
23
|
DWORD samp; // "SAMP"
|
21
24
|
DWORD samplen;
|
22
25
|
} OKTFILEHEADER;
|
23
26
|
|
24
|
-
|
25
27
|
typedef struct OKTSAMPLE
|
26
28
|
{
|
27
29
|
CHAR name[20];
|
@@ -33,20 +35,29 @@ typedef struct OKTSAMPLE
|
|
33
35
|
BYTE pad2;
|
34
36
|
BYTE pad3;
|
35
37
|
} OKTSAMPLE;
|
38
|
+
#pragma pack()
|
39
|
+
|
36
40
|
|
41
|
+
static DWORD readBE32(const BYTE *v)
|
42
|
+
{
|
43
|
+
return (v[0] << 24UL) | (v[1] << 16UL) | (v[2] << 8UL) | v[3];
|
44
|
+
}
|
37
45
|
|
38
46
|
BOOL CSoundFile_ReadOKT(CSoundFile *_this, const BYTE *lpStream, DWORD dwMemLength)
|
39
47
|
//---------------------------------------------------------------
|
40
48
|
{
|
41
49
|
const OKTFILEHEADER *pfh = (OKTFILEHEADER *)lpStream;
|
42
|
-
DWORD dwMemPos = sizeof(OKTFILEHEADER);
|
50
|
+
DWORD dwMemPos = sizeof(OKTFILEHEADER), dwSize;
|
43
51
|
UINT nsamples = 0, norders = 0;//, npatterns = 0
|
44
52
|
|
45
53
|
if ((!lpStream) || (dwMemLength < 1024)) return FALSE;
|
46
|
-
if ((pfh->okta !=
|
47
|
-
|| (
|
48
|
-
|| (
|
49
|
-
|| (pfh->
|
54
|
+
if ((bswapBE32(pfh->okta) != MAGIC('O','K','T','A'))
|
55
|
+
|| (bswapBE32(pfh->song) != MAGIC('S','O','N','G'))
|
56
|
+
|| (bswapBE32(pfh->cmod) != MAGIC('C','M','O','D'))
|
57
|
+
|| (bswapBE32(pfh->cmodlen) != 8)
|
58
|
+
|| (pfh->chnsetup[0]) || (pfh->chnsetup[2])
|
59
|
+
|| (pfh->chnsetup[4]) || (pfh->chnsetup[6])
|
60
|
+
|| (bswapBE32(pfh->samp) != MAGIC('S','A','M','P'))) return FALSE;
|
50
61
|
_this->m_nType = MOD_TYPE_OKT;
|
51
62
|
_this->m_nChannels = 4 + pfh->chnsetup[1] + pfh->chnsetup[3] + pfh->chnsetup[5] + pfh->chnsetup[7];
|
52
63
|
if (_this->m_nChannels > MAX_CHANNELS) _this->m_nChannels = MAX_CHANNELS;
|
@@ -56,10 +67,10 @@ BOOL CSoundFile_ReadOKT(CSoundFile *_this, const BYTE *lpStream, DWORD dwMemLeng
|
|
56
67
|
// Reading samples
|
57
68
|
for (UINT smp=1; smp <= nsamples; smp++)
|
58
69
|
{
|
59
|
-
if (dwMemPos
|
70
|
+
if (dwMemPos >= dwMemLength - sizeof(OKTSAMPLE)) return TRUE;
|
60
71
|
if (smp < MAX_SAMPLES)
|
61
72
|
{
|
62
|
-
OKTSAMPLE *psmp = (OKTSAMPLE *)(lpStream + dwMemPos);
|
73
|
+
const OKTSAMPLE *psmp = (const OKTSAMPLE *)(lpStream + dwMemPos);
|
63
74
|
MODINSTRUMENT *pins = &_this->Ins[smp];
|
64
75
|
|
65
76
|
pins->uFlags = 0;
|
@@ -74,42 +85,52 @@ BOOL CSoundFile_ReadOKT(CSoundFile *_this, const BYTE *lpStream, DWORD dwMemLeng
|
|
74
85
|
dwMemPos += sizeof(OKTSAMPLE);
|
75
86
|
}
|
76
87
|
// SPEE
|
77
|
-
if (dwMemPos
|
78
|
-
if (
|
88
|
+
if (dwMemPos >= dwMemLength - 12) return TRUE;
|
89
|
+
if (readBE32(lpStream + dwMemPos) == MAGIC('S','P','E','E'))
|
79
90
|
{
|
80
91
|
_this->m_nDefaultSpeed = lpStream[dwMemPos+9];
|
81
|
-
|
92
|
+
|
93
|
+
dwSize = readBE32(lpStream + dwMemPos + 4);
|
94
|
+
if (dwSize > dwMemLength - 8 || dwMemPos > dwMemLength - dwSize - 8) return TRUE;
|
95
|
+
dwMemPos += dwSize + 8;
|
82
96
|
}
|
83
97
|
// SLEN
|
84
98
|
if (dwMemPos + 10 > dwMemLength) return TRUE;
|
85
|
-
if (
|
99
|
+
if (readBE32(lpStream + dwMemPos) == MAGIC('S','L','E','N'))
|
86
100
|
{
|
87
|
-
if (dwMemPos + 10 > dwMemLength) return TRUE;
|
88
101
|
// npatterns = lpStream[dwMemPos+9];
|
89
|
-
|
102
|
+
|
103
|
+
dwSize = readBE32(lpStream + dwMemPos + 4);
|
104
|
+
if (dwSize > dwMemLength - 8 || dwMemPos > dwMemLength - dwSize - 8) return TRUE;
|
105
|
+
dwMemPos += dwSize + 8;
|
90
106
|
}
|
91
107
|
// PLEN
|
92
108
|
if (dwMemPos + 10 > dwMemLength) return TRUE;
|
93
|
-
if (
|
109
|
+
if (readBE32(lpStream + dwMemPos) == MAGIC('P','L','E','N'))
|
94
110
|
{
|
95
|
-
if (dwMemPos + 10 > dwMemLength) return TRUE;
|
96
111
|
norders = lpStream[dwMemPos+9];
|
97
|
-
|
112
|
+
|
113
|
+
dwSize = readBE32(lpStream + dwMemPos + 4);
|
114
|
+
if (dwSize > dwMemLength - 8 || dwMemPos > dwMemLength - dwSize - 8) return TRUE;
|
115
|
+
dwMemPos += dwSize + 8;
|
98
116
|
}
|
99
117
|
// PATT
|
100
118
|
if (dwMemPos + 8 > dwMemLength) return TRUE;
|
101
|
-
if (
|
119
|
+
if (readBE32(lpStream + dwMemPos) == MAGIC('P','A','T','T'))
|
102
120
|
{
|
103
121
|
UINT orderlen = norders;
|
104
122
|
if (orderlen >= MAX_ORDERS) orderlen = MAX_ORDERS-1;
|
105
123
|
if (dwMemPos + 8 + orderlen > dwMemLength) return TRUE;
|
106
124
|
for (UINT i=0; i<orderlen; i++) _this->Order[i] = lpStream[dwMemPos+8+i];
|
107
125
|
for (UINT j=orderlen; j>1; j--) { if (_this->Order[j-1]) break; _this->Order[j-1] = 0xFF; }
|
108
|
-
|
126
|
+
|
127
|
+
dwSize = readBE32(lpStream + dwMemPos + 4);
|
128
|
+
if (dwSize > dwMemLength - 8 || dwMemPos > dwMemLength - dwSize - 8) return TRUE;
|
129
|
+
dwMemPos += dwSize + 8;
|
109
130
|
}
|
110
131
|
// PBOD
|
111
132
|
UINT npat = 0;
|
112
|
-
while ((dwMemPos
|
133
|
+
while ((dwMemPos < dwMemLength - 10) && (readBE32(lpStream + dwMemPos) == MAGIC('P','B','O','D')))
|
113
134
|
{
|
114
135
|
DWORD dwPos = dwMemPos + 10;
|
115
136
|
UINT rows = lpStream[dwMemPos+9];
|
@@ -181,15 +202,21 @@ BOOL CSoundFile_ReadOKT(CSoundFile *_this, const BYTE *lpStream, DWORD dwMemLeng
|
|
181
202
|
}
|
182
203
|
}
|
183
204
|
npat++;
|
184
|
-
|
205
|
+
|
206
|
+
dwSize = readBE32(lpStream + dwMemPos + 4);
|
207
|
+
if (dwSize > dwMemLength - 8 || dwMemPos > dwMemLength - dwSize - 8) return TRUE;
|
208
|
+
dwMemPos += dwSize + 8;
|
185
209
|
}
|
186
210
|
// SBOD
|
187
211
|
UINT nsmp = 1;
|
188
|
-
while ((dwMemPos
|
212
|
+
while ((dwMemPos < dwMemLength-10) && (readBE32(lpStream + dwMemPos) == MAGIC('S','B','O','D')))
|
189
213
|
{
|
190
214
|
if (nsmp < MAX_SAMPLES) CSoundFile_ReadSample(_this, &_this->Ins[nsmp], RS_PCM8S, (LPSTR)(lpStream+dwMemPos+8), dwMemLength-dwMemPos-8);
|
191
|
-
dwMemPos += bswapBE32(*((DWORD *)(lpStream + dwMemPos + 4))) + 8;
|
192
215
|
nsmp++;
|
216
|
+
|
217
|
+
dwSize = readBE32(lpStream + dwMemPos + 4);
|
218
|
+
if (dwSize > dwMemLength - 8 || dwMemPos > dwMemLength - dwSize - 8) return TRUE;
|
219
|
+
dwMemPos += dwSize + 8;
|
193
220
|
}
|
194
221
|
return TRUE;
|
195
222
|
}
|
@@ -100,7 +100,7 @@ BOOL CSoundFile_ReadPSM(CSoundFile *_this, LPCBYTE lpStream, DWORD dwMemLength)
|
|
100
100
|
// DWORD smpnames[MAX_SAMPLES];
|
101
101
|
DWORD patptrs[MAX_PATTERNS];
|
102
102
|
BYTE samplemap[MAX_SAMPLES];
|
103
|
-
UINT nPatterns;
|
103
|
+
UINT nPatterns = 0;
|
104
104
|
|
105
105
|
if (dwMemLength < 256) return FALSE;
|
106
106
|
|
@@ -309,8 +309,10 @@ BOOL CSoundFile_ReadPSM(CSoundFile *_this, LPCBYTE lpStream, DWORD dwMemLength)
|
|
309
309
|
if ((flags & 0x40) && (pos+1 < len))
|
310
310
|
{
|
311
311
|
UINT nins = p[pos++];
|
312
|
-
if (nins
|
312
|
+
if (nins >= _this->m_nSamples) {
|
313
|
+
} else {
|
313
314
|
sp->instr = samplemap[nins];
|
315
|
+
}
|
314
316
|
}
|
315
317
|
// Volume
|
316
318
|
if ((flags & 0x20) && (pos < len))
|