From f75ab6186d525ffff30b2391d4c8515f3ba714ab Mon Sep 17 00:00:00 2001 From: techmetx11 Date: Thu, 11 Apr 2024 22:43:53 +0000 Subject: [PATCH] Partially implement TFM's effects Fix the mismatched patterns hack to be more seamless, by adding the "jump to next pattern" effects in the last row, in addition to the row after that --- src/engine/fileOps/tfm.cpp | 52 +++++++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/src/engine/fileOps/tfm.cpp b/src/engine/fileOps/tfm.cpp index 7572afee2..6fadee58e 100644 --- a/src/engine/fileOps/tfm.cpp +++ b/src/engine/fileOps/tfm.cpp @@ -86,7 +86,7 @@ public: // in certain parts of the header and footer) // TFM music maker actually uses double 0x80 to escape the 0x80 // for example: 0xDA 0x80 0x80 0x00 0x23 = 0xDA 0x80 0x00 0x23) - if (ret==0x80 && curSeek+1patLen) { + if (pat->data[patLens[i]-1][4]==-1 && pat->data[patLens[i]-1][5]==-1) { + pat->data[patLens[i]-1][4]=0x0D; + pat->data[patLens[i]-1][5]=0x00; + } pat->data[patLens[i]][4]=0x0D; pat->data[patLens[i]][5]=0x00; } @@ -374,14 +378,48 @@ bool DivEngine::loadTFM(unsigned char* file, size_t len) { logD("parsing instruments of pattern %d channel %d",i,j); for (int k=0; k<256; k++) { if (patDataBuf[k]==0) continue; - else { - pat->data[k][2]=insNumMaps[patDataBuf[k]-1]; - } + pat->data[k][2]=insNumMaps[patDataBuf[k]-1]; } - logD("ignoring unused data of pattern %d channel %d",i,j); - reader.read(patDataBuf,256); - reader.read(patDataBuf,256); + // effects + + unsigned char effectNum[256]; + unsigned char effectVal[256]; + reader.read(effectNum,256); + reader.read(effectVal,256); + + for (int k=0; k<256; k++) { + switch (effectNum[k]) { + case 0: + // arpeggio or no effect (if effect val is 0) + if (effectVal[k]==0) break; + pat->data[k][4]=effectNum[k]; + pat->data[k][5]=effectVal[k]; + break; + case 1: + // pitch slide up + case 2: + // pitch slide down + case 3: + // portamento + case 4: + // vibrato + pat->data[k][4]=effectNum[k]; + pat->data[k][5]=effectVal[k]; + break; + case 5: + // poramento + volume slide + pat->data[k][4]=0x06; + pat->data[k][5]=effectVal[k]; + break; + case 6: + // vibrato + volume slide + pat->data[k][4]=0x05; + pat->data[k][5]=effectVal[k]; + default: + break; + } + } reader.skip(1536); }