ft2-clone

Fasttracker 2 clone
Log | Files | Refs | README | LICENSE

commit 9435ca2b06a5108b9314e700967ad4cb97ca791f
parent f95626311367970a4e12789247baa2c245e6af9a
Author: Olav Sørensen <olav.sorensen@live.no>
Date:   Thu,  4 Mar 2021 13:48:33 +0100

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).

Diffstat:
Msrc/ft2_module_loader.c | 14++++++++++----
Msrc/modloaders/ft2_load_mod.c | 45+++++++++++++++++++++++++++++++++++----------
2 files changed, 45 insertions(+), 14 deletions(-)

diff --git a/src/ft2_module_loader.c b/src/ft2_module_loader.c @@ -101,6 +101,10 @@ static int8_t detectModule(FILE *f) 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 @@ static int8_t detectModule(FILE *f) 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; } diff --git a/src/modloaders/ft2_load_mod.c b/src/modloaders/ft2_load_mod.c @@ -54,7 +54,9 @@ bool loadMOD(FILE *f, uint32_t filesize) 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 @@ bool loadMOD(FILE *f, uint32_t filesize) 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 @@ bool loadMOD(FILE *f, uint32_t filesize) } } + if (hasMoreThan32Chans) + loaderMsgBox("Warning: The module has >32 channels. Only 32 were loaded!"); + return true; } @@ -366,33 +377,47 @@ static uint8_t getModType(uint8_t *numChannels, const char *id) 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_FT2; + *numChannels = id[2] - '0'; + } + else if (id[0] == 'F' && id[1] == 'A' && id[2] == '0' && id[3] >= '4' && id[3] <= '8') // FA0x (Digital Tracker, Atari) + { + 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; // StarTrekker (4ch modules) + modFormat = FORMAT_FLT4; } - else if (IS_ID("FLT8", id)) + else if (IS_ID("FLT8", id) || IS_ID("EXO8", id)) // StarTrekker 8ch { - modFormat = FORMAT_FLT8; // StarTrekker (8ch modules) + modFormat = FORMAT_FLT8; *numChannels = 8; } else if (IS_ID("N.T.", id))