From 308aacc1e6511ec8ed19a62e056f298b1be0c9d9 Mon Sep 17 00:00:00 2001 From: techmetx11 Date: Wed, 19 Feb 2025 14:01:11 +0100 Subject: [PATCH 1/4] Implement looping in TFM import --- src/engine/fileOps/tfm.cpp | 42 ++++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/src/engine/fileOps/tfm.cpp b/src/engine/fileOps/tfm.cpp index 919e7f52f..6b0365346 100644 --- a/src/engine/fileOps/tfm.cpp +++ b/src/engine/fileOps/tfm.cpp @@ -193,6 +193,7 @@ struct TFMParsePatternInfo { DivSong* ds; int* insNumMaps; bool v2; + unsigned char loop_pos; }; void TFMParsePattern(struct TFMParsePatternInfo info) { @@ -366,7 +367,7 @@ void TFMParsePattern(struct TFMParsePatternInfo info) { pat->data[k][5+(l*2)]=effectVal[k]; break; case 13: - // modify TL of operator 2 + // modify TL of operator 4 pat->data[k][4+(l*2)]=0x15; pat->data[k][5+(l*2)]=effectVal[k]; break; @@ -459,17 +460,21 @@ void TFMParsePattern(struct TFMParsePatternInfo info) { bool chVibrato[6]={false}; bool chPorta[6]={false}; bool chVolumeSlide[6]={false}; + int lastPatSeen=0; for (int i=0; isubsong[0]->ordersLen; i++) { + // this is if the last pattern is used more than once + if (info.orderList[i] == info.orderList[info.ds->subsong[0]->ordersLen - 1]) { + lastPatSeen++; + } for (int j=0; j<6; j++) { for (int l=0; lsubsong[0]->pat[j].data[info.orderList[i]]; + unsigned char truePatLen=(info.patLens[info.orderList[i]]subsong[0]->patLen) ? info.patLens[info.orderList[i]] : info.ds->subsong[0]->patLen; // default instrument if (i==0 && pat->data[0][2]==-1) pat->data[0][2]=0; - unsigned char truePatLen=(info.patLens[info.orderList[i]]subsong[0]->patLen) ? info.patLens[info.orderList[i]] : info.ds->subsong[0]->patLen; - for (int k=0; kdata[k][4+(l*2)]!=0x00 && pat->data[k][0]!=-1) { pat->data[k][4+usedEffectsCol*2+(l*2)]=0x00; @@ -505,12 +510,35 @@ void TFMParsePattern(struct TFMParsePatternInfo info) { chVolumeSlide[j]=true; break; default: - break; + break; } } } } } + + if (lastPatSeen>1) { + // clone the last pattern + info.maxPat++; + for (int i=0;i<6;i++) { + int last_pat_num = info.ds->subsong[0]->orders.ord[i][info.ds->subsong[0]->ordersLen - 1]; + DivPattern* new_pat = new DivPattern; + DivPattern* last_pat = info.ds->subsong[0]->pat[i].data[last_pat_num]; + last_pat->copyOn(new_pat); + + info.ds->subsong[0]->orders.ord[i][info.ds->subsong[0]->ordersLen - 1] = info.maxPat; + new_pat->data[info.patLens[last_pat_num]-1][4+(usedEffectsCol*4)] = 0x0B; + new_pat->data[info.patLens[last_pat_num]-1][5+(usedEffectsCol*4)] = info.loop_pos; + info.ds->subsong[0]->pat[i].data[info.maxPat] = new_pat; + } + } else { + for (int i=0;i<6;i++) { + int last_pat_num = info.ds->subsong[0]->orders.ord[i][info.ds->subsong[0]->ordersLen - 1]; + DivPattern* last_pat = info.ds->subsong[0]->pat[i].data[last_pat_num]; + last_pat->data[info.patLens[last_pat_num]-1][4+(usedEffectsCol*4)] = 0x0B; + last_pat->data[info.patLens[last_pat_num]-1][5+(usedEffectsCol*4)] = info.loop_pos; + } + } } bool DivEngine::loadTFMv1(unsigned char* file, size_t len) { @@ -551,7 +579,7 @@ bool DivEngine::loadTFMv1(unsigned char* file, size_t len) { ds.subsong[0]->ordersLen=reader.readCNoRLE(); // order loop position, unused - (void)reader.readCNoRLE(); + unsigned char loop_pos = reader.readCNoRLE(); ds.createdDate=TFMparseDate(reader.readSNoRLE()); ds.revisionDate=TFMparseDate(reader.readSNoRLE()); @@ -677,6 +705,7 @@ bool DivEngine::loadTFMv1(unsigned char* file, size_t len) { info.patLens=patLens; info.reader=&reader; info.v2=false; + info.loop_pos=loop_pos; TFMParsePattern(info); if (active) quitDispatch(); @@ -750,7 +779,7 @@ bool DivEngine::loadTFMv2(unsigned char* file, size_t len) { ds.subsong[0]->ordersLen=reader.readCNoRLE(); // order loop position, unused - (void)reader.readCNoRLE(); + unsigned char loop_pos = reader.readCNoRLE(); ds.createdDate=TFMparseDate(reader.readSNoRLE()); ds.revisionDate=TFMparseDate(reader.readSNoRLE()); @@ -876,6 +905,7 @@ bool DivEngine::loadTFMv2(unsigned char* file, size_t len) { info.patLens=patLens; info.reader=&reader; info.v2=true; + info.loop_pos=loop_pos; TFMParsePattern(info); if (active) quitDispatch(); From 56937d8f05758096d44684d07bc08850ff9dfd5c Mon Sep 17 00:00:00 2001 From: techmetx11 Date: Wed, 19 Feb 2025 17:34:34 +0100 Subject: [PATCH 2/4] Fix naming --- src/engine/fileOps/tfm.cpp | 42 +++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/engine/fileOps/tfm.cpp b/src/engine/fileOps/tfm.cpp index 6b0365346..44ec51f21 100644 --- a/src/engine/fileOps/tfm.cpp +++ b/src/engine/fileOps/tfm.cpp @@ -193,7 +193,7 @@ struct TFMParsePatternInfo { DivSong* ds; int* insNumMaps; bool v2; - unsigned char loop_pos; + unsigned char loopPos; }; void TFMParsePattern(struct TFMParsePatternInfo info) { @@ -510,7 +510,7 @@ void TFMParsePattern(struct TFMParsePatternInfo info) { chVolumeSlide[j]=true; break; default: - break; + break; } } } @@ -518,25 +518,25 @@ void TFMParsePattern(struct TFMParsePatternInfo info) { } if (lastPatSeen>1) { - // clone the last pattern + // clone the last pattern info.maxPat++; for (int i=0;i<6;i++) { - int last_pat_num = info.ds->subsong[0]->orders.ord[i][info.ds->subsong[0]->ordersLen - 1]; - DivPattern* new_pat = new DivPattern; - DivPattern* last_pat = info.ds->subsong[0]->pat[i].data[last_pat_num]; - last_pat->copyOn(new_pat); + int lastPatNum = info.ds->subsong[0]->orders.ord[i][info.ds->subsong[0]->ordersLen - 1]; + DivPattern* newPat = new DivPattern; + DivPattern* lastPat = info.ds->subsong[0]->pat[i].data[lastPatNum]; + lastPat->copyOn(newPat); info.ds->subsong[0]->orders.ord[i][info.ds->subsong[0]->ordersLen - 1] = info.maxPat; - new_pat->data[info.patLens[last_pat_num]-1][4+(usedEffectsCol*4)] = 0x0B; - new_pat->data[info.patLens[last_pat_num]-1][5+(usedEffectsCol*4)] = info.loop_pos; - info.ds->subsong[0]->pat[i].data[info.maxPat] = new_pat; + newPat->data[info.patLens[lastPatNum]-1][4+(usedEffectsCol*4)] = 0x0B; + newPat->data[info.patLens[lastPatNum]-1][5+(usedEffectsCol*4)] = info.loopPos; + info.ds->subsong[0]->pat[i].data[info.maxPat] = newPat; } } else { for (int i=0;i<6;i++) { - int last_pat_num = info.ds->subsong[0]->orders.ord[i][info.ds->subsong[0]->ordersLen - 1]; - DivPattern* last_pat = info.ds->subsong[0]->pat[i].data[last_pat_num]; - last_pat->data[info.patLens[last_pat_num]-1][4+(usedEffectsCol*4)] = 0x0B; - last_pat->data[info.patLens[last_pat_num]-1][5+(usedEffectsCol*4)] = info.loop_pos; + int lastPatNum = info.ds->subsong[0]->orders.ord[i][info.ds->subsong[0]->ordersLen - 1]; + DivPattern* lastPat = info.ds->subsong[0]->pat[i].data[lastPatNum]; + lastPat->data[info.patLens[lastPatNum]-1][4+(usedEffectsCol*4)] = 0x0B; + lastPat->data[info.patLens[lastPatNum]-1][5+(usedEffectsCol*4)] = info.loopPos; } } } @@ -578,8 +578,8 @@ bool DivEngine::loadTFMv1(unsigned char* file, size_t len) { } ds.subsong[0]->ordersLen=reader.readCNoRLE(); - // order loop position, unused - unsigned char loop_pos = reader.readCNoRLE(); + // order loop position + unsigned char loopPos = reader.readCNoRLE(); ds.createdDate=TFMparseDate(reader.readSNoRLE()); ds.revisionDate=TFMparseDate(reader.readSNoRLE()); @@ -705,7 +705,7 @@ bool DivEngine::loadTFMv1(unsigned char* file, size_t len) { info.patLens=patLens; info.reader=&reader; info.v2=false; - info.loop_pos=loop_pos; + info.loopPos=loopPos; TFMParsePattern(info); if (active) quitDispatch(); @@ -778,8 +778,8 @@ bool DivEngine::loadTFMv2(unsigned char* file, size_t len) { } ds.subsong[0]->ordersLen=reader.readCNoRLE(); - // order loop position, unused - unsigned char loop_pos = reader.readCNoRLE(); + // order loop position + unsigned char loopPos = reader.readCNoRLE(); ds.createdDate=TFMparseDate(reader.readSNoRLE()); ds.revisionDate=TFMparseDate(reader.readSNoRLE()); @@ -905,7 +905,7 @@ bool DivEngine::loadTFMv2(unsigned char* file, size_t len) { info.patLens=patLens; info.reader=&reader; info.v2=true; - info.loop_pos=loop_pos; + info.loopPos=loopPos; TFMParsePattern(info); if (active) quitDispatch(); @@ -930,7 +930,7 @@ bool DivEngine::loadTFMv2(unsigned char* file, size_t len) { } catch(InvalidHeaderException& e) { lastError="invalid info header!"; } - + delete[] file; return success; } From 27a1914924610416d52955291fa8001dcc73560d Mon Sep 17 00:00:00 2001 From: techmetx11 Date: Thu, 20 Feb 2025 23:40:04 +0100 Subject: [PATCH 3/4] Use .getPattern() --- src/engine/fileOps/tfm.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/engine/fileOps/tfm.cpp b/src/engine/fileOps/tfm.cpp index 44ec51f21..7e102b0e9 100644 --- a/src/engine/fileOps/tfm.cpp +++ b/src/engine/fileOps/tfm.cpp @@ -521,9 +521,9 @@ void TFMParsePattern(struct TFMParsePatternInfo info) { // clone the last pattern info.maxPat++; for (int i=0;i<6;i++) { - int lastPatNum = info.ds->subsong[0]->orders.ord[i][info.ds->subsong[0]->ordersLen - 1]; - DivPattern* newPat = new DivPattern; - DivPattern* lastPat = info.ds->subsong[0]->pat[i].data[lastPatNum]; + int lastPatNum=info.ds->subsong[0]->orders.ord[i][info.ds->subsong[0]->ordersLen - 1]; + DivPattern* newPat=info.ds->subsong[0]->pat[i].getPattern(info.maxPat,true); + DivPattern* lastPat=info.ds->subsong[0]->pat[i].data[lastPatNum]; lastPat->copyOn(newPat); info.ds->subsong[0]->orders.ord[i][info.ds->subsong[0]->ordersLen - 1] = info.maxPat; @@ -533,8 +533,8 @@ void TFMParsePattern(struct TFMParsePatternInfo info) { } } else { for (int i=0;i<6;i++) { - int lastPatNum = info.ds->subsong[0]->orders.ord[i][info.ds->subsong[0]->ordersLen - 1]; - DivPattern* lastPat = info.ds->subsong[0]->pat[i].data[lastPatNum]; + int lastPatNum=info.ds->subsong[0]->orders.ord[i][info.ds->subsong[0]->ordersLen - 1]; + DivPattern* lastPat=info.ds->subsong[0]->pat[i].data[lastPatNum]; lastPat->data[info.patLens[lastPatNum]-1][4+(usedEffectsCol*4)] = 0x0B; lastPat->data[info.patLens[lastPatNum]-1][5+(usedEffectsCol*4)] = info.loopPos; } From 18c5d80a091f85c141e8b0840426958ad4026bcd Mon Sep 17 00:00:00 2001 From: techmetx11 Date: Sat, 22 Feb 2025 07:59:58 +0100 Subject: [PATCH 4/4] Use more .getPattern() --- src/engine/fileOps/tfm.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/fileOps/tfm.cpp b/src/engine/fileOps/tfm.cpp index 7e102b0e9..a96ee28be 100644 --- a/src/engine/fileOps/tfm.cpp +++ b/src/engine/fileOps/tfm.cpp @@ -523,7 +523,7 @@ void TFMParsePattern(struct TFMParsePatternInfo info) { for (int i=0;i<6;i++) { int lastPatNum=info.ds->subsong[0]->orders.ord[i][info.ds->subsong[0]->ordersLen - 1]; DivPattern* newPat=info.ds->subsong[0]->pat[i].getPattern(info.maxPat,true); - DivPattern* lastPat=info.ds->subsong[0]->pat[i].data[lastPatNum]; + DivPattern* lastPat=info.ds->subsong[0]->pat[i].getPattern(lastPatNum, false); lastPat->copyOn(newPat); info.ds->subsong[0]->orders.ord[i][info.ds->subsong[0]->ordersLen - 1] = info.maxPat; @@ -534,7 +534,7 @@ void TFMParsePattern(struct TFMParsePatternInfo info) { } else { for (int i=0;i<6;i++) { int lastPatNum=info.ds->subsong[0]->orders.ord[i][info.ds->subsong[0]->ordersLen - 1]; - DivPattern* lastPat=info.ds->subsong[0]->pat[i].data[lastPatNum]; + DivPattern* lastPat=info.ds->subsong[0]->pat[i].getPattern(lastPatNum, false); lastPat->data[info.patLens[lastPatNum]-1][4+(usedEffectsCol*4)] = 0x0B; lastPat->data[info.patLens[lastPatNum]-1][5+(usedEffectsCol*4)] = info.loopPos; }