ref: 15897be81442299876efd399c7b14f8110e65879
parent: 659ffaa46c783451aa0c7e29ac33d8767569b3be
author: Olav Sørensen <olav.sorensen@live.no>
date: Mon Apr 27 16:14:16 EDT 2020
Pushed v1.22 code - Fixed crash when loading XMs with pattern lengths above 256. They are now safely truncated, and the user gets a warning message about the truncation. - Allow loading overflown BPM/speed values from quirky XMs, up to BPM 999 and speed 99 ("jk_error_txt.xm" is an example for quirky BPM/speed values). - Tiny code cleanup
--- a/src/ft2_audio.c
+++ b/src/ft2_audio.c
@@ -921,7 +921,7 @@
pattSyncData.patternPos = song.curReplayerPattPos;
pattSyncData.pattern = song.curReplayerPattNr;
pattSyncData.songPos = song.curReplayerSongPos;
- pattSyncData.speed = (uint8_t)song.speed;
+ pattSyncData.speed = song.speed;
pattSyncData.tempo = (uint8_t)song.tempo;
pattSyncData.globalVol = (uint8_t)song.globVol;
pattSyncData.timestamp = audio.tickTime64;
--- a/src/ft2_audio.h
+++ b/src/ft2_audio.h
@@ -81,7 +81,8 @@
typedef struct pattSyncData_t
{
- uint8_t pattern, globalVol, songPos, timer, speed, tempo, patternPos;
+ uint8_t pattern, globalVol, songPos, timer, tempo, patternPos;
+ uint16_t speed;
uint64_t timestamp;
} pattSyncData_t;
--- a/src/ft2_header.h
+++ b/src/ft2_header.h
@@ -12,7 +12,7 @@
#endif
#include "ft2_replayer.h"
-#define PROG_VER_STR "1.21"
+#define PROG_VER_STR "1.22"
// do NOT change these! It will only mess things up...
--- a/src/ft2_module_loader.c
+++ b/src/ft2_module_loader.c
@@ -129,7 +129,7 @@
static volatile uint8_t loadedFormat;
static volatile bool linearFreqTable, musicIsLoading, moduleLoaded, moduleFailedToLoad;
-static uint8_t oldPlayMode, pattBuff[12288];
+static uint8_t oldPlayMode, pattBuff[12288], packedPattData[65536];
static const uint8_t stmEff[16] = { 0, 0, 11, 0, 10, 2, 1, 3, 4, 7, 0, 5 ,6, 0, 0, 0 };
static SDL_Thread *thread;
@@ -143,7 +143,7 @@
static void freeTmpModule(void);
static bool loadInstrHeader(FILE *f, uint16_t i);
static bool loadInstrSample(FILE *f, uint16_t i);
-void unpackPatt(uint8_t *dst, uint16_t inn, uint16_t len, int32_t antChn);
+void unpackPatt(uint8_t *dst, uint8_t *src, uint16_t len, int32_t antChn);
static bool tmpPatternEmpty(uint16_t nr);
static bool loadPatterns(FILE *f, uint16_t antPtn);
@@ -1752,8 +1752,8 @@
songTmp.ver = h.ver;
linearFreqTable = h.flags & 1;
- songTmp.speed = CLAMP(songTmp.speed, 32, 255);
- songTmp.tempo = CLAMP(songTmp.tempo, 1, 31);
+ songTmp.speed = CLAMP(songTmp.speed, 1, 999);
+ songTmp.tempo = CLAMP(songTmp.tempo, 1, 99);
songTmp.initialTempo = songTmp.tempo;
@@ -2192,15 +2192,14 @@
return true;
}
-void unpackPatt(uint8_t *dst, uint16_t inn, uint16_t len, int32_t antChn)
+void unpackPatt(uint8_t *dst, uint8_t *src, uint16_t len, int32_t antChn)
{
- uint8_t note, data, *src;
+ uint8_t note, data;
int32_t srcEnd, srcIdx;
if (dst == NULL)
return;
- src = dst + inn;
srcEnd = len * TRACK_WIDTH;
srcIdx = 0;
@@ -2280,8 +2279,8 @@
static bool loadPatterns(FILE *f, uint16_t antPtn)
{
bool pattLenWarn;
- uint8_t tmpLen, *pattPtr;
- uint16_t i, a;
+ uint8_t tmpLen;
+ uint16_t i;
patternHeaderTyp ph;
pattLenWarn = false;
@@ -2324,6 +2323,11 @@
goto pattCorrupt;
pattLensTmp[i] = ph.pattLen;
+ if (pattLensTmp[i] > MAX_PATT_LEN)
+ {
+ pattLensTmp[i] = MAX_PATT_LEN;
+ pattLenWarn = true;
+ }
if (ph.dataLen > 0)
{
@@ -2334,15 +2338,11 @@
return false;
}
- a = ph.pattLen * TRACK_WIDTH;
-
- pattPtr = (uint8_t *)pattTmp[i];
- memset(pattPtr, 0, a);
-
- if (fread(&pattPtr[a - ph.dataLen], 1, ph.dataLen, f) != ph.dataLen)
+ if (fread(packedPattData, 1, ph.dataLen, f) != ph.dataLen)
goto pattCorrupt;
- unpackPatt(pattPtr, a - ph.dataLen, ph.pattLen, songTmp.antChn);
+ unpackPatt((uint8_t *)pattTmp[i], packedPattData, pattLensTmp[i], songTmp.antChn);
+
clearUnusedChannels(pattTmp[i], pattLensTmp[i], songTmp.antChn);
}
@@ -2356,16 +2356,10 @@
pattLensTmp[i] = 64;
}
-
- if (pattLensTmp[i] > 256)
- {
- pattLensTmp[i] = 64;
- pattLenWarn = true;
- }
}
if (pattLenWarn)
- okBoxThreadSafe(0, "System message", "The module contains pattern lengths above 256! They will be set to 64.");
+ okBoxThreadSafe(0, "System message", "This module contains pattern(s) with a length above 256! They will be truncated.");
return true;
--- a/src/ft2_pattern_ed.c
+++ b/src/ft2_pattern_ed.c
@@ -2182,11 +2182,30 @@
void drawSongBPM(uint16_t val)
{
+ char str[4];
+ const char *strOut;
+
if (editor.ui.extended)
return;
- assert(val < 256);
- textOutFixed(145, 36, PAL_FORGRND, PAL_DESKTOP, dec3StrTab[val]);
+ if (val <= 255)
+ {
+ strOut = dec3StrTab[val];
+ }
+ else
+ {
+ if (val > 999)
+ val = 999;
+
+ str[0] = '0' + (char)(val / 100);
+ str[1] = '0' + ((val / 10) % 10);
+ str[2] = '0' + (val % 10);
+ str[3] = 0;
+
+ strOut = str;
+ }
+
+ textOutFixed(145, 36, PAL_FORGRND, PAL_DESKTOP, strOut);
}
void drawSongSpeed(uint16_t val)
@@ -2194,7 +2213,9 @@
if (editor.ui.extended)
return;
- assert(val < 32);
+ if (val > 99)
+ val = 99;
+
textOutFixed(152, 50, PAL_FORGRND, PAL_DESKTOP, dec2StrTab[val]);
}
--- a/src/ft2_replayer.c
+++ b/src/ft2_replayer.c
@@ -29,7 +29,7 @@
** FT2 obviously didn't have such big tables.
*/
-static uint32_t musicTimeTab[256-32];
+static uint32_t musicTimeTab[1000];
static uint64_t period2ScopeDeltaTab[65536];
static double dLogTab[768], dLogTabMul[32], dAudioRateFactor;
@@ -412,11 +412,12 @@
// calculate table used to count replayer time (displayed as hours/minutes/seconds)
const double dMul = (UINT32_MAX + 1.0) / rate;
- for (i = 32; i < 256; i++)
+ musicTimeTab[0] = UINT32_MAX;
+ for (i = 1; i < 1000; i++)
{
uint32_t samplesPerTick = ((rate + rate) + (rate >> 1)) / i; // exactly how setSpeed() calculates it
const double dVal = samplesPerTick * dMul;
- musicTimeTab[i-32] = (int32_t)(dVal + 0.5);
+ musicTimeTab[i] = (uint32_t)(dVal + 0.5);
}
calcPeriod2DeltaTables();
@@ -2139,8 +2140,8 @@
return;
}
- assert(song.speed >= 32 && song.speed <= 255);
- song.musicTime64 += musicTimeTab[song.speed-32]; // for playback counter
+ assert(song.speed >= 1 && song.speed <= 999);
+ song.musicTime64 += musicTimeTab[song.speed]; // for playback counter
readNewNote = false;
if (--song.timer == 0)
--- a/src/ft2_tables.c
+++ b/src/ft2_tables.c
@@ -38,13 +38,13 @@
24, 23, 22, 20, 19, 17, 16, 14, 12, 11, 9, 8, 6, 5, 3, 2
};
-const uint8_t vibTab[32] =
+const uint8_t vibTab[32] = // for normal vibrato/tremolo
{
0, 24, 49, 74, 97,120,141,161,180,197,212,224,235,244,250,253,
255,253,250,244,235,224,212,197,180,161,141,120, 97, 74, 49, 24
};
-const uint16_t amigaPeriod[12 * 8] =
+const uint16_t amigaPeriod[12 * 8] = // used for .MOD loading/saving
{
6848, 6464, 6096, 5760, 5424, 5120, 4832, 4560, 4304, 4064, 3840, 3624,
3424, 3232, 3048, 2880, 2712, 2560, 2416, 2280, 2152, 2032, 1920, 1812,
@@ -56,18 +56,6 @@
53, 50, 47, 45, 42, 40, 37, 35, 33, 31, 30, 28
};
-const uint16_t amigaFinePeriod[12 * 8] =
-{
- 907, 900, 894, 887, 881, 875, 868, 862, 856, 850, 844, 838,
- 832, 826, 820, 814, 808, 802, 796, 791, 785, 779, 774, 768,
- 762, 757, 752, 746, 741, 736, 730, 725, 720, 715, 709, 704,
- 699, 694, 689, 684, 678, 675, 670, 665, 660, 655, 651, 646,
- 640, 636, 632, 628, 623, 619, 614, 610, 604, 601, 597, 592,
- 588, 584, 580, 575, 570, 567, 563, 559, 555, 551, 547, 543,
- 538, 535, 532, 528, 524, 520, 516, 513, 508, 505, 502, 498,
- 494, 491, 487, 484, 480, 477, 474, 470, 467, 463, 460, 457
-};
-
const uint16_t linearPeriods[1936] = // bit-exact to FT2 table
{
7744, 7740, 7736, 7732, 7728, 7724, 7720, 7716, 7712, 7708, 7704, 7700, 7696, 7692, 7688, 7684,
@@ -704,6 +692,7 @@
24, 4, 4, 4, 4, 4, 4, 4 // 12 columns visible
};
+// these two are for channel numbering on pattern data/scopes
const char chDecTab1[MAX_VOICES+1] =
{
'0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
--- a/src/ft2_tables.h
+++ b/src/ft2_tables.h
@@ -14,7 +14,6 @@
extern const int8_t vibSineTab[256]; // for auto-vibrato
extern const uint8_t vibTab[32];
extern const uint16_t amigaPeriod[12 * 8];
-extern const uint16_t amigaFinePeriod[12 * 8];
extern const uint16_t linearPeriods[1936];
extern const uint16_t amigaPeriods[1936];
--- a/src/ft2_wav_renderer.c
+++ b/src/ft2_wav_renderer.c
@@ -215,7 +215,7 @@
tmpLen = ftell(f) - 8;
// go back and fill in WAV header
- fseek(f, 0, SEEK_SET);
+ rewind(f);
wavHeader.chunkID = 0x46464952; // "RIFF"
wavHeader.chunkSize = tmpLen;
@@ -322,10 +322,10 @@
sampleCounter = 0;
renderDone = false;
- loopCounter = 0;
+ loopCounter = 8;
editor.wavReachedEndFlag = false;
- while (!renderDone && editor.wavIsRendering)
+ while (!renderDone)
{
samplesInChunk = 0;
@@ -339,7 +339,7 @@
break;
}
- tickSamples = dump_RenderTick(ptr8) * 2; // *2 for stereo
+ tickSamples = dump_RenderTick(ptr8) << 1; // *2 for stereo
samplesInChunk += tickSamples;
sampleCounter += tickSamples;
@@ -350,7 +350,7 @@
else
ptr8 += (tickSamples * sizeof (float));
- if (++loopCounter > 16)
+ if (++loopCounter >= 8)
{
loopCounter = 0;
updateVisuals();