gosu 1.4.1 → 1.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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))
|