From 0cd8ab94c4f026ac45075d7e3a49595e6f34ae16 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Wed, 15 Oct 2025 19:56:13 -0500 Subject: [PATCH] pattern data refactor, part 4 all file ops converted there may be some bugs related to note range - testing to be performed after Furnace builds again --- src/engine/fileOps/xm.cpp | 156 ++++++++++++++++++-------------------- 1 file changed, 75 insertions(+), 81 deletions(-) diff --git a/src/engine/fileOps/xm.cpp b/src/engine/fileOps/xm.cpp index edc1cf14c..5c3f68d97 100644 --- a/src/engine/fileOps/xm.cpp +++ b/src/engine/fileOps/xm.cpp @@ -901,32 +901,26 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) { if (note!=0) { lastNote[k]=note; if (note>96) { - p->data[j][0]=101; - p->data[j][1]=0; + p->newData[j][DIV_PAT_NOTE]=DIV_NOTE_REL; } else { note--; - p->data[j][0]=note%12; - p->data[j][1]=note/12; - if (p->data[j][0]==0) { - p->data[j][0]=12; - p->data[j][1]=(unsigned char)(p->data[j][1]-1); - } + p->newData[j][DIV_PAT_NOTE]=note+60; } } } if (hasIns) { ins=reader.readC(); - p->data[j][2]=((int)ins)-1; + p->newData[j][DIV_PAT_INS]=((int)ins)-1; // default volume if (lastNote[k]<96 && ins>0) { - p->data[j][3]=sampleVol[(((ins-1)&255)<<8)|(noteMap[(((ins-1)&255)<<7)|(lastNote[k]&127)])]; + p->newData[j][DIV_PAT_VOL]=sampleVol[(((ins-1)&255)<<8)|(noteMap[(((ins-1)&255)<<7)|(lastNote[k]&127)])]; } writePanning=true; } if (hasVol) { vol=reader.readC(); if (vol>=0x10 && vol<=0x50) { - p->data[j][3]=vol-0x10; + p->newData[j][DIV_PAT_VOL]=vol-0x10; } else { // effects in volume column switch (vol>>4) { case 0x6: // vol slide down @@ -986,11 +980,11 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) { vibing[k]=true; break; case 0xc: // panning - p->data[j][effectCol[k]++]=0x80; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0x80; if ((vol&15)==8) { - p->data[j][effectCol[k]++]=0x80; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0x80; } else { - p->data[j][effectCol[k]++]=(vol&15)|((vol&15)<<4); + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=(vol&15)|((vol&15)<<4); } writePanning=false; break; @@ -1113,14 +1107,14 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) { treming[k]=true; break; case 8: // panning - p->data[j][effectCol[k]++]=0x80; - p->data[j][effectCol[k]++]=effectVal; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0x80; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=effectVal; writePanning=false; break; case 9: // offset if (hasNote) { - p->data[j][effectCol[k]++]=0x91; - p->data[j][effectCol[k]++]=effectVal; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0x91; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=effectVal; } break; case 0xa: // vol slide @@ -1134,15 +1128,15 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) { volSliding[k]=true; break; case 0xb: // go to order - p->data[j][effectCol[k]++]=0x0b; - p->data[j][effectCol[k]++]=effectVal; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0x0b; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=effectVal; break; case 0xc: // set volume - p->data[j][3]=effectVal; + p->newData[j][DIV_PAT_VOL]=effectVal; break; case 0xd: // next order - p->data[j][effectCol[k]++]=0x0d; - p->data[j][effectCol[k]++]=effectVal; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0x0d; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=effectVal; break; case 0xe: // special... // TODO: implement the rest @@ -1150,27 +1144,27 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) { case 0x4: // vibrato waveform switch (effectVal&3) { case 0x0: // sine - p->data[j][effectCol[k]++]=0xe3; - p->data[j][effectCol[k]++]=0x00; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0xe3; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0x00; break; case 0x1: // ramp down - p->data[j][effectCol[k]++]=0xe3; - p->data[j][effectCol[k]++]=0x05; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0xe3; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0x05; break; case 0x2: // square case 0x3: - p->data[j][effectCol[k]++]=0xe3; - p->data[j][effectCol[k]++]=0x06; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0xe3; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0x06; break; } break; case 0x5: // fine tune - p->data[j][effectCol[k]++]=0xe5; - p->data[j][effectCol[k]++]=(effectVal&15)<<4; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0xe5; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=(effectVal&15)<<4; break; case 0x9: // retrigger - p->data[j][effectCol[k]++]=0x0c; - p->data[j][effectCol[k]++]=(effectVal&15); + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0x0c; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=(effectVal&15); break; case 0xa: // vol slide up (fine) volSlideStatus[k]=((effectVal&15)<<4)|0xf; @@ -1189,32 +1183,32 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) { volSliding[k]=true; break; case 0xc: // note cut - p->data[j][effectCol[k]++]=0xdc; - p->data[j][effectCol[k]++]=MAX(1,effectVal&15); + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0xdc; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=MAX(1,effectVal&15); break; case 0xd: // note delay - p->data[j][effectCol[k]++]=0xed; - p->data[j][effectCol[k]++]=MAX(1,effectVal&15); + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0xed; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=MAX(1,effectVal&15); break; } break; case 0xf: // speed/tempo if (effectVal>=0x20) { - p->data[j][effectCol[k]++]=0xf0; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0xf0; } else if (effectVal==0) { - p->data[j][effectCol[k]++]=0xff; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0xff; } else { - p->data[j][effectCol[k]++]=0x0f; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0x0f; } - p->data[j][effectCol[k]++]=effectVal; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=effectVal; break; case 0x10: // G: global volume (!) break; case 0x11: // H: global volume slide (!) break; case 0x14: // K: key off - p->data[j][effectCol[k]++]=0xe7; - p->data[j][effectCol[k]++]=effectVal; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0xe7; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=effectVal; break; case 0x15: // L: set envelope position (!) break; @@ -1226,8 +1220,8 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) { panSliding[k]=true; break; case 0x1b: // R: retrigger - p->data[j][effectCol[k]++]=0x0c; - p->data[j][effectCol[k]++]=effectVal; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0x0c; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=effectVal; break; case 0x1d: // T: tremor (!) break; @@ -1244,8 +1238,8 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) { } if (writePanning && hasNote && note<96 && ins>0) { - p->data[j][effectCol[k]++]=0x80; - p->data[j][effectCol[k]++]=samplePan[(((ins-1)&255)<<8)|(noteMap[(((ins-1)&255)<<7)|(note&127)])]; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0x80; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=samplePan[(((ins-1)&255)<<8)|(noteMap[(((ins-1)&255)<<7)|(note&127)])]; } } @@ -1253,76 +1247,76 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) { for (int k=0; kpat[k].getPattern(i,true); if (vibing[k]!=vibingOld[k] || vibStatusChanged[k]) { - p->data[j][effectCol[k]++]=0x04; - p->data[j][effectCol[k]++]=vibing[k]?vibStatus[k]:0; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0x04; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=vibing[k]?vibStatus[k]:0; doesVibrato[k]=true; } else if (doesVibrato[k] && mustCommitInitial) { - p->data[j][effectCol[k]++]=0x04; - p->data[j][effectCol[k]++]=0; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0x04; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0; } if (volSliding[k]!=volSlidingOld[k] || volSlideStatusChanged[k]) { if (volSlideStatus[k]>=0xf1 && volSliding[k]) { - p->data[j][effectCol[k]++]=0xf9; - p->data[j][effectCol[k]++]=volSlideStatus[k]&15; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0xf9; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=volSlideStatus[k]&15; volSliding[k]=false; } else if ((volSlideStatus[k]&15)==15 && volSlideStatus[k]>=0x10 && volSliding[k]) { - p->data[j][effectCol[k]++]=0xf8; - p->data[j][effectCol[k]++]=volSlideStatus[k]>>4; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0xf8; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=volSlideStatus[k]>>4; volSliding[k]=false; } else { - p->data[j][effectCol[k]++]=0xfa; - p->data[j][effectCol[k]++]=volSliding[k]?volSlideStatus[k]:0; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0xfa; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=volSliding[k]?volSlideStatus[k]:0; } doesVolSlide[k]=true; } else if (doesVolSlide[k] && mustCommitInitial) { - p->data[j][effectCol[k]++]=0xfa; - p->data[j][effectCol[k]++]=0; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0xfa; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0; } if (porting[k]!=portingOld[k] || portaStatusChanged[k]) { - p->data[j][effectCol[k]++]=portaType[k]; - p->data[j][effectCol[k]++]=porting[k]?portaStatus[k]:0; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=portaType[k]; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=porting[k]?portaStatus[k]:0; doesPitchSlide[k]=true; } else if (doesPitchSlide[k] && mustCommitInitial) { - p->data[j][effectCol[k]++]=0x01; - p->data[j][effectCol[k]++]=0; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0x01; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0; } if (arping[k]!=arpingOld[k] || arpStatusChanged[k]) { - p->data[j][effectCol[k]++]=0x00; - p->data[j][effectCol[k]++]=arping[k]?arpStatus[k]:0; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0x00; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=arping[k]?arpStatus[k]:0; doesArp[k]=true; } else if (doesArp[k] && mustCommitInitial) { - p->data[j][effectCol[k]++]=0x00; - p->data[j][effectCol[k]++]=0; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0x00; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0; } if (treming[k]!=tremingOld[k] || tremStatusChanged[k]) { - p->data[j][effectCol[k]++]=0x07; - p->data[j][effectCol[k]++]=treming[k]?tremStatus[k]:0; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0x07; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=treming[k]?tremStatus[k]:0; doesTremolo[k]=true; } else if (doesTremolo[k] && mustCommitInitial) { - p->data[j][effectCol[k]++]=0x07; - p->data[j][effectCol[k]++]=0; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0x07; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0; } if (panning[k]!=panningOld[k] || panStatusChanged[k]) { - p->data[j][effectCol[k]++]=0x84; - p->data[j][effectCol[k]++]=panning[k]?panStatus[k]:0; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0x84; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=panning[k]?panStatus[k]:0; doesPanbrello[k]=true; } else if (doesPanbrello[k] && mustCommitInitial) { - p->data[j][effectCol[k]++]=0x84; - p->data[j][effectCol[k]++]=0; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0x84; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0; } if (panSliding[k]!=panSlidingOld[k] || panSlideStatusChanged[k]) { - p->data[j][effectCol[k]++]=0x83; - p->data[j][effectCol[k]++]=panSliding[k]?panSlideStatus[k]:0; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0x83; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=panSliding[k]?panSlideStatus[k]:0; doesPanSlide[k]=true; } else if (doesPanSlide[k] && mustCommitInitial) { - p->data[j][effectCol[k]++]=0x83; - p->data[j][effectCol[k]++]=0; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0x83; + p->newData[j][DIV_PAT_FX(0)+effectCol[k]++]=0; } if ((effectCol[k]>>1)-2>ds.subsong[0]->pat[k].effectCols) { @@ -1346,8 +1340,8 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) { if (j==totalRows-1) { // place end of pattern marker DivPattern* p=ds.subsong[0]->pat[0].getPattern(i,true); - p->data[j][effectCol[0]++]=0x0d; - p->data[j][effectCol[0]++]=0; + p->newData[j][DIV_PAT_FX(0)+effectCol[0]++]=0x0d; + p->newData[j][DIV_PAT_FX(0)+effectCol[0]++]=0; if ((effectCol[0]>>1)-2>ds.subsong[0]->pat[0].effectCols) { ds.subsong[0]->pat[0].effectCols=(effectCol[0]>>1)-1;