shithub: ft²

Download patch

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();