shithub: ft²

Download patch

ref: 9435ca2b06a5108b9314e700967ad4cb97ca791f
parent: f95626311367970a4e12789247baa2c245e6af9a
author: Olav Sørensen <olav.sorensen@live.no>
date: Thu Mar 4 08:49:00 EST 2021

Add support for lading a few more .MOD types

Also fix loading of .MODs with more than 32 channels (though the remaining c hannels get truncated).

--- a/src/ft2_module_loader.c
+++ b/src/ft2_module_loader.c
@@ -101,6 +101,10 @@
 	if (isdigit(I[0]) && I[0] != '0' && I[1] == 'C' && I[2] == 'H' && I[3] == 'N') // xCHN
 		return FORMAT_MOD;
 
+	// Digital Tracker (Atari Falcon)
+	if (I[0] == 'F' && I[1] == 'A' && I[2] == '0' && I[3] >= '4' && I[3] <= '8') // FA0x (x=4..8)
+		return FORMAT_MOD;
+
 	// Generic multi-channel MOD (10..99 channels)
 	if (isdigit(I[0]) && isdigit(I[1]) && I[0] != '0' && I[2] == 'C' && I[3] == 'H') // xxCH
 		return FORMAT_MOD;
@@ -109,11 +113,13 @@
 	if (isdigit(I[0]) && isdigit(I[1]) && I[0] != '0' && I[2] == 'C' && I[3] == 'N') // xxCN (same as xxCH)
 		return FORMAT_MOD;
 	
-	// Generic 4-channel MOD (NoiseTracker/ProTracker or compatible)
+	// ProTracker and generic MOD formats
 	if (!memcmp("M.K.", I, 4) || !memcmp("M!K!", I, 4) || !memcmp("NSMS", I, 4) ||
-		!memcmp("LARD", I, 4) || !memcmp("PATT", I, 4) || !memcmp("PATT", I, 4) ||
-		!memcmp("FLT4", I, 4) || !memcmp("FLT8", I, 4) || !memcmp("N.T.", I, 4) ||
-		!memcmp("M&K!", I, 4) || !memcmp("FEST", I, 4))
+		!memcmp("LARD", I, 4) || !memcmp("PATT", I, 4) || !memcmp("FLT4", I, 4) ||
+		!memcmp("FLT8", I, 4) || !memcmp("EXO4", I, 4) || !memcmp("EXO8", I, 4) ||
+		!memcmp("N.T.", I, 4) || !memcmp("M&K!", I, 4) || !memcmp("FEST", I, 4) ||
+		!memcmp("CD61", I, 4) || !memcmp("CD81", I, 4) || !memcmp("OKTA", I, 4) ||
+		!memcmp("OCTA", I, 4))
 	{
 		return FORMAT_MOD;
 	}
--- a/src/modloaders/ft2_load_mod.c
+++ b/src/modloaders/ft2_load_mod.c
@@ -54,7 +54,9 @@
 		return false;
 	}
 
-	songTmp.antChn = numChannels;
+	bool hasMoreThan32Chans = numChannels > 32;
+
+	songTmp.antChn = hasMoreThan32Chans ? 32 : numChannels;
 	songTmp.len = h_MOD31.len;
 	songTmp.repS = h_MOD31.repS;
 	songTmp.initialTempo = songTmp.tempo = 6;
@@ -132,6 +134,12 @@
 					ton->effTyp = bytes[2] & 0x0F;
 					ton->eff = bytes[3];
 				}
+
+				if (hasMoreThan32Chans)
+				{
+					int32_t remainingChans = numChannels-songTmp.antChn;
+					fseek(f, remainingChans*4, SEEK_CUR);
+				}
 			}
 
 			if (tmpPatternEmpty(a))
@@ -356,6 +364,9 @@
 		}
 	}
 
+	if (hasMoreThan32Chans)
+		loaderMsgBox("Warning: The module has >32 channels. Only 32 were loaded!");
+
 	return true;
 }
 
@@ -366,33 +377,47 @@
 	uint8_t modFormat = FORMAT_UNKNOWN;
 	*numChannels = 4;
 
-	if (IS_ID("M.K.", id) || IS_ID("M!K!", id) || IS_ID("NSMS", id) ||
-		IS_ID("LARD", id) || IS_ID("PATT", id))
+	if (IS_ID("M.K.", id) || IS_ID("M!K!", id) || IS_ID("NSMS", id) || IS_ID("LARD", id) || IS_ID("PATT", id))
 	{
 		modFormat = FORMAT_MK; // ProTracker or compatible
 	}
 	else if (isdigit(id[0]) && id[1] == 'C' && id[2] == 'H' && id[3] == 'N') // xCHN
 	{
-		modFormat = FORMAT_FT2; // FT2 or compatible (multi-channel)
+		modFormat = FORMAT_FT2;
 		*numChannels = id[0] - '0';
 	}
 	else if (isdigit(id[0]) && isdigit(id[1]) && id[2] == 'C' && id[3] == 'H') // xxCH
 	{
-		modFormat = FORMAT_FT2; // FT2 or compatible (multi-channel)
+		modFormat = FORMAT_FT2;
 		*numChannels = ((id[0] - '0') * 10) + (id[1] - '0');
 	}
 	else if (isdigit(id[0]) && isdigit(id[1]) && id[2] == 'C' && id[3] == 'N') // xxCN (load as xxCH)
 	{
-		modFormat = FORMAT_FT2; // FT2 or compatible (multi-channel)
+		modFormat = FORMAT_FT2;
 		*numChannels = ((id[0] - '0') * 10) + (id[1] - '0');
 	}
-	else if (IS_ID("FLT4", id))
+	else if (IS_ID("CD61", id) || IS_ID("CD81", id)) // Octalyser (Atari)
 	{
-		modFormat = FORMAT_FLT4; // StarTrekker (4ch modules)
+		modFormat = FORMAT_FT2;
+		*numChannels = id[2] - '0';
 	}
-	else if (IS_ID("FLT8", id))
+	else if (id[0] == 'F' && id[1] == 'A' && id[2] == '0' && id[3] >= '4' && id[3] <= '8') // FA0x (Digital Tracker, Atari)
 	{
-		modFormat = FORMAT_FLT8; // StarTrekker (8ch modules)
+		modFormat = FORMAT_FT2;
+		*numChannels = id[3] - '0';
+	}
+	else if (IS_ID("OKTA", id) || IS_ID("OCTA", id)) // Oktalyzer (as .MOD format)
+	{
+		modFormat = FORMAT_FT2;
+		*numChannels = 8;
+	}
+	else if (IS_ID("FLT4", id) || IS_ID("EXO4", id)) // StarTrekker 4ch
+	{
+		modFormat = FORMAT_FLT4;
+	}
+	else if (IS_ID("FLT8", id) || IS_ID("EXO8", id)) // StarTrekker 8ch
+	{
+		modFormat = FORMAT_FLT8;
 		*numChannels = 8;
 	}
 	else if (IS_ID("N.T.", id))