pattern data refactor, part 2

This commit is contained in:
tildearrow 2025-10-14 15:58:15 -05:00
parent d4ecf4045b
commit 00bbde217f
2 changed files with 51 additions and 58 deletions

View file

@ -935,22 +935,16 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
unsigned char ins=reader.readC();
if (note==254) { // note off
p->data[readRow][0]=100;
p->data[readRow][1]=0;
p->newData[readRow][DIV_PAT_NOTE]=DIV_NOTE_OFF;
} else if (note!=255) {
p->data[readRow][0]=note&15;
p->data[readRow][1]=note>>4;
if ((note&15)==0) {
p->data[readRow][0]=12;
p->data[readRow][1]--;
}
p->newData[readRow][DIV_PAT_NOTE]=(note&15)+(note>>4)*12;
}
p->data[readRow][2]=(short)ins-1;
p->newData[readRow][DIV_PAT_INS]=(short)ins-1;
}
if (hasVol) {
unsigned char vol=reader.readC();
if (vol==255) {
p->data[readRow][3]=-1;
p->newData[readRow][DIV_PAT_VOL]=-1;
} else {
// check for OPL channel
if ((chanSettings[chan]&31)>=16) {
@ -958,17 +952,17 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
} else {
if (vol>64) vol=64;
}
p->data[readRow][3]=vol;
p->newData[readRow][DIV_PAT_VOL]=vol;
}
} else if (p->data[readRow][2]!=-1) {
} else if (p->newData[readRow][DIV_PAT_INS]!=-1) {
// populate with instrument volume
unsigned char vol=defVol[p->data[readRow][2]&255];
unsigned char vol=defVol[p->newData[readRow][DIV_PAT_INS]&255];
if ((chanSettings[chan]&31)>=16) {
if (vol>63) vol=63;
} else {
if (vol>64) vol=64;
}
p->data[readRow][3]=vol;
p->newData[readRow][DIV_PAT_VOL]=vol;
}
if (hasEffect) {
unsigned char effect=reader.readC();
@ -976,17 +970,17 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
switch (effect+'A'-1) {
case 'A': // speed
p->data[readRow][effectCol[chan]++]=0x0f;
p->data[readRow][effectCol[chan]++]=effectVal;
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0x0f;
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=effectVal;
break;
case 'B': // go to order
p->data[readRow][effectCol[chan]++]=0x0b;
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0x0b;
logD("0B: %x %x",effectVal,orders[effectVal]);
p->data[readRow][effectCol[chan]++]=orders[effectVal];
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=orders[effectVal];
break;
case 'C': // next order
p->data[readRow][effectCol[chan]++]=0x0d;
p->data[readRow][effectCol[chan]++]=(effectVal>>4)*10+(effectVal&15);
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0x0d;
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=(effectVal>>4)*10+(effectVal&15);
break;
case 'D': // vol slide
if (effectVal!=0) {
@ -1078,8 +1072,8 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
case 'N': // channel vol slide (extension)
break;
case 'O': // offset
p->data[readRow][effectCol[chan]++]=0x91;
p->data[readRow][effectCol[chan]++]=effectVal;
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0x91;
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=effectVal;
break;
case 'P': // pan slide (extension)
if (effectVal!=0) {
@ -1089,8 +1083,8 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
panSliding[chan]=true;
break;
case 'Q': // retrigger
p->data[readRow][effectCol[chan]++]=0x0c;
p->data[readRow][effectCol[chan]++]=effectVal&15;
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0x0c;
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=effectVal&15;
break;
case 'R': // tremolo
if (effectVal!=0) {
@ -1104,40 +1098,40 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
case 0x3: // vibrato waveform
switch (effectVal&3) {
case 0x0: // sine
p->data[readRow][effectCol[chan]++]=0xe3;
p->data[readRow][effectCol[chan]++]=0x00;
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0xe3;
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0x00;
break;
case 0x1: // ramp down
p->data[readRow][effectCol[chan]++]=0xe3;
p->data[readRow][effectCol[chan]++]=0x05;
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0xe3;
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0x05;
break;
case 0x2: // square
p->data[readRow][effectCol[chan]++]=0xe3;
p->data[readRow][effectCol[chan]++]=0x06;
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0xe3;
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0x06;
break;
case 0x3: // random
p->data[readRow][effectCol[chan]++]=0xe3;
p->data[readRow][effectCol[chan]++]=0x07;
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0xe3;
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0x07;
break;
}
break;
case 0x8: // panning
p->data[readRow][effectCol[chan]++]=0x80;
p->data[readRow][effectCol[chan]++]=(effectVal&15)<<4;
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0x80;
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=(effectVal&15)<<4;
break;
case 0xc: // note cut
p->data[readRow][effectCol[chan]++]=0xec;
p->data[readRow][effectCol[chan]++]=effectVal&15;
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0xec;
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=effectVal&15;
break;
case 0xd: // note delay
p->data[readRow][effectCol[chan]++]=0xed;
p->data[readRow][effectCol[chan]++]=effectVal&15;
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0xed;
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=effectVal&15;
break;
}
break;
case 'T': // tempo
p->data[readRow][effectCol[chan]++]=0xf0;
p->data[readRow][effectCol[chan]++]=effectVal;
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0xf0;
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=effectVal;
break;
case 'U': // fine vibrato
if (effectVal!=0) {
@ -1152,8 +1146,8 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
break;
case 'X': // panning (extension)
if (effectVal<=0x80) {
p->data[readRow][effectCol[chan]++]=0x80;
p->data[readRow][effectCol[chan]++]=(effectVal&0x80)?0xff:(effectVal<<1);
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0x80;
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=(effectVal&0x80)?0xff:(effectVal<<1);
}
break;
case 'Y': // panbrello (extension)
@ -1193,16 +1187,16 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
for (int j=0; j<16; j++) {
DivPattern* p=ds.subsong[i]->pat[chanMap[j]].getPattern(ds.subsong[i]->orders.ord[j][0],true);
for (int k=0; k<DIV_MAX_EFFECTS; k++) {
if (p->data[0][4+(k<<1)]==0x80) {
if (p->newData[0][DIV_PAT_FX(k)]==0x80) {
// give up if there's a panning effect already
break;
}
if (p->data[0][4+(k<<1)]==-1) {
p->data[0][4+(k<<1)]=0x80;
if (p->newData[0][DIV_PAT_FX(k)]==-1) {
p->newData[0][DIV_PAT_FX(k)]=0x80;
if (chanPan[j]&16) {
p->data[0][5+(k<<1)]=(j&1)?0xcc:0x33;
p->newData[0][DIV_PAT_FXVAL(k)]=(j&1)?0xcc:0x33;
} else {
p->data[0][5+(k<<1)]=(chanPan[j]&15)|((chanPan[j]&15)<<4);
p->newData[0][DIV_PAT_FXVAL(k)]=(chanPan[j]&15)|((chanPan[j]&15)<<4);
}
if (ds.subsong[i]->pat[chanMap[j]].effectCols<=k) ds.subsong[i]->pat[chanMap[j]].effectCols=k+1;
break;

View file

@ -321,9 +321,8 @@ SafeWriter* DivEngine::saveText(bool separatePatterns) {
for (int l=0; l<chans; l++) {
DivPattern* p=s->pat[l].getPattern(s->orders.ord[l][j],false);
int note=p->data[k][0];
int octave=p->data[k][1];
short note, octave;
noteToSplitNote(p->newData[k][DIV_PAT_NOTE],note,octave);
if (note==0 && octave==0) {
w->writeText("|... ");
@ -344,28 +343,28 @@ SafeWriter* DivEngine::saveText(bool separatePatterns) {
w->writeText(fmt::sprintf("|%s%d ",(octave<0)?notesNegative[note]:notes[note],(octave<0)?(-octave):octave));
}
if (p->data[k][2]==-1) {
if (p->newData[k][DIV_PAT_INS]==-1) {
w->writeText(".. ");
} else {
w->writeText(fmt::sprintf("%.2X ",p->data[k][2]&0xff));
w->writeText(fmt::sprintf("%.2X ",p->newData[k][DIV_PAT_INS]&0xff));
}
if (p->data[k][3]==-1) {
if (p->newData[k][DIV_PAT_VOL]==-1) {
w->writeText("..");
} else {
w->writeText(fmt::sprintf("%.2X",p->data[k][3]&0xff));
w->writeText(fmt::sprintf("%.2X",p->newData[k][DIV_PAT_VOL]&0xff));
}
for (int m=0; m<s->pat[l].effectCols; m++) {
if (p->data[k][4+(m<<1)]==-1) {
if (p->newData[k][DIV_PAT_FX(m)]==-1) {
w->writeText(" ..");
} else {
w->writeText(fmt::sprintf(" %.2X",p->data[k][4+(m<<1)]&0xff));
w->writeText(fmt::sprintf(" %.2X",p->newData[k][DIV_PAT_FX(m)]&0xff));
}
if (p->data[k][5+(m<<1)]==-1) {
if (p->newData[k][DIV_PAT_FXVAL(m)]==-1) {
w->writeText("..");
} else {
w->writeText(fmt::sprintf("%.2X",p->data[k][5+(m<<1)]&0xff));
w->writeText(fmt::sprintf("%.2X",p->newData[k][DIV_PAT_FXVAL(m)]&0xff));
}
}
}