S3M/IT import: why is this variable used

issue #1998
This commit is contained in:
tildearrow 2024-07-05 14:52:05 -05:00
parent 13c63f60bb
commit e495c8d990
2 changed files with 125 additions and 124 deletions

View file

@ -742,7 +742,7 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) {
unsigned char vol[64]; unsigned char vol[64];
unsigned char effect[64]; unsigned char effect[64];
unsigned char effectVal[64]; unsigned char effectVal[64];
int curRow=0; int readRow=0;
memset(mask,0,64); memset(mask,0,64);
memset(note,0,64); memset(note,0,64);
@ -782,8 +782,8 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) {
bool hasEffect=false; bool hasEffect=false;
if (chan==0) { if (chan==0) {
curRow++; readRow++;
if (curRow>=patRows) { if (readRow>=patRows) {
break; break;
} }
continue; continue;
@ -905,7 +905,7 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) {
unsigned char vol[64]; unsigned char vol[64];
unsigned char effect[64]; unsigned char effect[64];
unsigned char effectVal[64]; unsigned char effectVal[64];
int curRow=0; int readRow=0;
bool mustCommitInitial=true; bool mustCommitInitial=true;
memset(effectCol,4,64); memset(effectCol,4,64);
@ -972,55 +972,55 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) {
for (int j=0; j<64; j++) { for (int j=0; j<64; j++) {
DivPattern* p=ds.subsong[0]->pat[j].getPattern(i,true); DivPattern* p=ds.subsong[0]->pat[j].getPattern(i,true);
if (vibing[j]!=vibingOld[j] || vibStatusChanged[j]) { if (vibing[j]!=vibingOld[j] || vibStatusChanged[j]) {
p->data[curRow][effectCol[j]++]=0x04; p->data[readRow][effectCol[j]++]=0x04;
p->data[curRow][effectCol[j]++]=vibing[j]?vibStatus[j]:0; p->data[readRow][effectCol[j]++]=vibing[j]?vibStatus[j]:0;
doesVibrato[j]=true; doesVibrato[j]=true;
} else if (doesVibrato[j] && mustCommitInitial) { } else if (doesVibrato[j] && mustCommitInitial) {
p->data[curRow][effectCol[j]++]=0x04; p->data[readRow][effectCol[j]++]=0x04;
p->data[curRow][effectCol[j]++]=0; p->data[readRow][effectCol[j]++]=0;
} }
if (volSliding[j]!=volSlidingOld[j] || volSlideStatusChanged[j]) { if (volSliding[j]!=volSlidingOld[j] || volSlideStatusChanged[j]) {
if (volSlideStatus[j]>=0xf1 && volSliding[j]) { if (volSlideStatus[j]>=0xf1 && volSliding[j]) {
p->data[curRow][effectCol[j]++]=0xf9; p->data[readRow][effectCol[j]++]=0xf9;
p->data[curRow][effectCol[j]++]=volSlideStatus[j]&15; p->data[readRow][effectCol[j]++]=volSlideStatus[j]&15;
volSliding[j]=false; volSliding[j]=false;
} else if ((volSlideStatus[j]&15)==15 && volSlideStatus[j]>=0x10 && volSliding[j]) { } else if ((volSlideStatus[j]&15)==15 && volSlideStatus[j]>=0x10 && volSliding[j]) {
p->data[curRow][effectCol[j]++]=0xf8; p->data[readRow][effectCol[j]++]=0xf8;
p->data[curRow][effectCol[j]++]=volSlideStatus[j]>>4; p->data[readRow][effectCol[j]++]=volSlideStatus[j]>>4;
volSliding[j]=false; volSliding[j]=false;
} else { } else {
p->data[curRow][effectCol[j]++]=0xfa; p->data[readRow][effectCol[j]++]=0xfa;
p->data[curRow][effectCol[j]++]=volSliding[j]?volSlideStatus[j]:0; p->data[readRow][effectCol[j]++]=volSliding[j]?volSlideStatus[j]:0;
} }
doesVolSlide[j]=true; doesVolSlide[j]=true;
} else if (doesVolSlide[j] && mustCommitInitial) { } else if (doesVolSlide[j] && mustCommitInitial) {
p->data[curRow][effectCol[j]++]=0xfa; p->data[readRow][effectCol[j]++]=0xfa;
p->data[curRow][effectCol[j]++]=0; p->data[readRow][effectCol[j]++]=0;
} }
if (porting[j]!=portingOld[j] || portaStatusChanged[j]) { if (porting[j]!=portingOld[j] || portaStatusChanged[j]) {
if (portaStatus[j]>=0xe0 && portaType[j]!=3 && porting[j]) { if (portaStatus[j]>=0xe0 && portaType[j]!=3 && porting[j]) {
p->data[curRow][effectCol[j]++]=portaType[j]|0xf0; p->data[readRow][effectCol[j]++]=portaType[j]|0xf0;
p->data[curRow][effectCol[j]++]=(portaStatus[j]&15)*((portaStatus[j]>=0xf0)?1:1); p->data[readRow][effectCol[j]++]=(portaStatus[j]&15)*((portaStatus[j]>=0xf0)?1:1);
porting[j]=false; porting[j]=false;
} else { } else {
p->data[curRow][effectCol[j]++]=portaType[j]; p->data[readRow][effectCol[j]++]=portaType[j];
p->data[curRow][effectCol[j]++]=porting[j]?portaStatus[j]:0; p->data[readRow][effectCol[j]++]=porting[j]?portaStatus[j]:0;
} }
doesPitchSlide[j]=true; doesPitchSlide[j]=true;
} else if (doesPitchSlide[j] && mustCommitInitial) { } else if (doesPitchSlide[j] && mustCommitInitial) {
p->data[curRow][effectCol[j]++]=0x01; p->data[readRow][effectCol[j]++]=0x01;
p->data[curRow][effectCol[j]++]=0; p->data[readRow][effectCol[j]++]=0;
} }
if (arping[j]!=arpingOld[j] || arpStatusChanged[j]) { if (arping[j]!=arpingOld[j] || arpStatusChanged[j]) {
p->data[curRow][effectCol[j]++]=0x00; p->data[readRow][effectCol[j]++]=0x00;
p->data[curRow][effectCol[j]++]=arping[j]?arpStatus[j]:0; p->data[readRow][effectCol[j]++]=arping[j]?arpStatus[j]:0;
doesArp[j]=true; doesArp[j]=true;
} else if (doesArp[j] && mustCommitInitial) { } else if (doesArp[j] && mustCommitInitial) {
p->data[curRow][effectCol[j]++]=0x00; p->data[readRow][effectCol[j]++]=0x00;
p->data[curRow][effectCol[j]++]=0; p->data[readRow][effectCol[j]++]=0;
} }
if ((effectCol[j]>>1)-2>ds.subsong[0]->pat[j].effectCols) { if ((effectCol[j]>>1)-2>ds.subsong[0]->pat[j].effectCols) {
@ -1028,7 +1028,7 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) {
} }
} }
curRow++; readRow++;
memset(effectCol,4,64); memset(effectCol,4,64);
memcpy(vibingOld,vibing,64*sizeof(bool)); memcpy(vibingOld,vibing,64*sizeof(bool));
memcpy(volSlidingOld,volSliding,64*sizeof(bool)); memcpy(volSlidingOld,volSliding,64*sizeof(bool));
@ -1044,12 +1044,12 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) {
memset(arping,0,64*sizeof(bool)); memset(arping,0,64*sizeof(bool));
memset(did,0,64); memset(did,0,64);
mustCommitInitial=false; mustCommitInitial=false;
if (curRow>=patRows) { if (readRow>=patRows) {
if (curRow>0) { if (readRow>0) {
// place end of pattern marker // place end of pattern marker
DivPattern* p=ds.subsong[0]->pat[0].getPattern(i,true); DivPattern* p=ds.subsong[0]->pat[0].getPattern(i,true);
p->data[curRow-1][effectCol[0]++]=0x0d; p->data[readRow-1][effectCol[0]++]=0x0d;
p->data[curRow-1][effectCol[0]++]=0; p->data[readRow-1][effectCol[0]++]=0;
if ((effectCol[0]>>1)-2>ds.subsong[0]->pat[0].effectCols) { if ((effectCol[0]>>1)-2>ds.subsong[0]->pat[0].effectCols) {
ds.subsong[0]->pat[0].effectCols=(effectCol[0]>>1)-1; ds.subsong[0]->pat[0].effectCols=(effectCol[0]>>1)-1;
@ -1099,33 +1099,33 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) {
if (hasNote) { if (hasNote) {
if (note[chan]==255) { // note release if (note[chan]==255) { // note release
p->data[curRow][0]=101; p->data[readRow][0]=101;
p->data[curRow][1]=0; p->data[readRow][1]=0;
} else if (note[chan]==254) { // note off } else if (note[chan]==254) { // note off
p->data[curRow][0]=100; p->data[readRow][0]=100;
p->data[curRow][1]=0; p->data[readRow][1]=0;
} else if (note[chan]<120) { } else if (note[chan]<120) {
p->data[curRow][0]=note[chan]%12; p->data[readRow][0]=note[chan]%12;
p->data[curRow][1]=note[chan]/12; p->data[readRow][1]=note[chan]/12;
if (p->data[curRow][0]==0) { if (p->data[readRow][0]==0) {
p->data[curRow][0]=12; p->data[readRow][0]=12;
p->data[curRow][1]--; p->data[readRow][1]--;
} }
} else { // note fade, but Furnace does not support that } else { // note fade, but Furnace does not support that
p->data[curRow][0]=102; p->data[readRow][0]=102;
p->data[curRow][1]=0; p->data[readRow][1]=0;
} }
} }
if (hasIns) { if (hasIns) {
p->data[curRow][2]=ins[chan]-1; p->data[readRow][2]=ins[chan]-1;
} }
if (hasVol) { if (hasVol) {
if (vol[chan]<=64) { if (vol[chan]<=64) {
p->data[curRow][3]=vol[chan]; p->data[readRow][3]=vol[chan];
} else { // effects in volume column } else { // effects in volume column
if (vol[chan]>=128 && vol[chan]<=192) { // panning if (vol[chan]>=128 && vol[chan]<=192) { // panning
p->data[curRow][effectCol[chan]++]=0x80; p->data[readRow][effectCol[chan]++]=0x80;
p->data[curRow][effectCol[chan]++]=CLAMP((vol[chan]-128)<<2,0,255); p->data[readRow][effectCol[chan]++]=CLAMP((vol[chan]-128)<<2,0,255);
} else if (vol[chan]>=65 && vol[chan]<=74) { // fine vol up } else if (vol[chan]>=65 && vol[chan]<=74) { // fine vol up
} else if (vol[chan]>=75 && vol[chan]<=84) { // fine vol down } else if (vol[chan]>=75 && vol[chan]<=84) { // fine vol down
} else if (vol[chan]>=85 && vol[chan]<=94) { // vol slide up } else if (vol[chan]>=85 && vol[chan]<=94) { // vol slide up
@ -1148,24 +1148,24 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) {
} }
} else if (hasNote && hasIns && (note[chan]<120 || ds.insLen==0) && ins[chan]>0) { } else if (hasNote && hasIns && (note[chan]<120 || ds.insLen==0) && ins[chan]>0) {
if (ds.insLen==0) { if (ds.insLen==0) {
p->data[curRow][3]=defVol[(ins[chan]-1)&255]; p->data[readRow][3]=defVol[(ins[chan]-1)&255];
} else { } else {
p->data[curRow][3]=defVol[noteMap[(ins[chan]-1)&255][note[chan]]]; p->data[readRow][3]=defVol[noteMap[(ins[chan]-1)&255][note[chan]]];
} }
} }
if (hasEffect) { if (hasEffect) {
switch (effect[chan]+'A'-1) { switch (effect[chan]+'A'-1) {
case 'A': // speed case 'A': // speed
p->data[curRow][effectCol[chan]++]=0x0f; p->data[readRow][effectCol[chan]++]=0x0f;
p->data[curRow][effectCol[chan]++]=effectVal[chan]; p->data[readRow][effectCol[chan]++]=effectVal[chan];
break; break;
case 'B': // go to order case 'B': // go to order
p->data[curRow][effectCol[chan]++]=0x0b; p->data[readRow][effectCol[chan]++]=0x0b;
p->data[curRow][effectCol[chan]++]=orders[effectVal[chan]]; p->data[readRow][effectCol[chan]++]=orders[effectVal[chan]];
break; break;
case 'C': // next order case 'C': // next order
p->data[curRow][effectCol[chan]++]=0x0d; p->data[readRow][effectCol[chan]++]=0x0d;
p->data[curRow][effectCol[chan]++]=effectVal[chan]; p->data[readRow][effectCol[chan]++]=effectVal[chan];
break; break;
case 'D': // vol slide case 'D': // vol slide
if (effectVal[chan]!=0) { if (effectVal[chan]!=0) {
@ -1248,32 +1248,32 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) {
case 'N': // channel vol slide case 'N': // channel vol slide
break; break;
case 'O': // offset case 'O': // offset
p->data[curRow][effectCol[chan]++]=0x91; p->data[readRow][effectCol[chan]++]=0x91;
p->data[curRow][effectCol[chan]++]=effectVal[chan]; p->data[readRow][effectCol[chan]++]=effectVal[chan];
break; break;
case 'P': // pan slide case 'P': // pan slide
break; break;
case 'Q': // retrigger case 'Q': // retrigger
p->data[curRow][effectCol[chan]++]=0x0c; p->data[readRow][effectCol[chan]++]=0x0c;
p->data[curRow][effectCol[chan]++]=effectVal[chan]&15; p->data[readRow][effectCol[chan]++]=effectVal[chan]&15;
break; break;
case 'R': // tremolo case 'R': // tremolo
break; break;
case 'S': // special... case 'S': // special...
switch (effectVal[chan]>>4) { switch (effectVal[chan]>>4) {
case 0xc: case 0xc:
p->data[curRow][effectCol[chan]++]=0xec; p->data[readRow][effectCol[chan]++]=0xec;
p->data[curRow][effectCol[chan]++]=effectVal[chan]&15; p->data[readRow][effectCol[chan]++]=effectVal[chan]&15;
break; break;
case 0xd: case 0xd:
p->data[curRow][effectCol[chan]++]=0xed; p->data[readRow][effectCol[chan]++]=0xed;
p->data[curRow][effectCol[chan]++]=effectVal[chan]&15; p->data[readRow][effectCol[chan]++]=effectVal[chan]&15;
break; break;
} }
break; break;
case 'T': // tempo case 'T': // tempo
p->data[curRow][effectCol[chan]++]=0xf0; p->data[readRow][effectCol[chan]++]=0xf0;
p->data[curRow][effectCol[chan]++]=effectVal[chan]; p->data[readRow][effectCol[chan]++]=effectVal[chan];
break; break;
case 'U': // fine vibrato case 'U': // fine vibrato
if (effectVal[chan]!=0) { if (effectVal[chan]!=0) {
@ -1287,8 +1287,8 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) {
case 'W': // global volume slide (!) case 'W': // global volume slide (!)
break; break;
case 'X': // panning case 'X': // panning
p->data[curRow][effectCol[chan]++]=0x80; p->data[readRow][effectCol[chan]++]=0x80;
p->data[curRow][effectCol[chan]++]=effectVal[chan]; p->data[readRow][effectCol[chan]++]=effectVal[chan];
break; break;
case 'Y': // panbrello case 'Y': // panbrello
break; break;

View file

@ -618,13 +618,14 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
unsigned short dataLen=reader.readS(); unsigned short dataLen=reader.readS();
unsigned int dataEnd=reader.tell()+dataLen; unsigned int dataEnd=reader.tell()+dataLen;
int readRow=0;
while (reader.tell()<dataEnd) { while (reader.tell()<dataEnd) {
unsigned char what=reader.readC(); unsigned char what=reader.readC();
if (what==0) { if (what==0) {
curRow++; readRow++;
if (curRow>=64) break; if (readRow>=64) break;
continue; continue;
} }
@ -711,10 +712,10 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
unsigned short dataLen=reader.readS(); unsigned short dataLen=reader.readS();
unsigned int dataEnd=reader.tell()+dataLen; unsigned int dataEnd=reader.tell()+dataLen;
int readRow=0;
logV("length: %d",dataLen); logV("length: %d",dataLen);
int curRow=0;
bool mustCommitInitial=true; bool mustCommitInitial=true;
memset(effectCol,4,32); memset(effectCol,4,32);
@ -745,55 +746,55 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
for (int j=0; j<32; j++) { for (int j=0; j<32; j++) {
DivPattern* p=ds.subsong[0]->pat[chanMap[j]].getPattern(i,true); DivPattern* p=ds.subsong[0]->pat[chanMap[j]].getPattern(i,true);
if (vibing[j]!=vibingOld[j] || vibStatusChanged[j]) { if (vibing[j]!=vibingOld[j] || vibStatusChanged[j]) {
p->data[curRow][effectCol[j]++]=0x04; p->data[readRow][effectCol[j]++]=0x04;
p->data[curRow][effectCol[j]++]=vibing[j]?vibStatus[j]:0; p->data[readRow][effectCol[j]++]=vibing[j]?vibStatus[j]:0;
doesVibrato[j]=true; doesVibrato[j]=true;
} else if (doesVibrato[j] && mustCommitInitial) { } else if (doesVibrato[j] && mustCommitInitial) {
p->data[curRow][effectCol[j]++]=0x04; p->data[readRow][effectCol[j]++]=0x04;
p->data[curRow][effectCol[j]++]=0; p->data[readRow][effectCol[j]++]=0;
} }
if (volSliding[j]!=volSlidingOld[j] || volSlideStatusChanged[j]) { if (volSliding[j]!=volSlidingOld[j] || volSlideStatusChanged[j]) {
if (volSlideStatus[j]>=0xf1 && volSliding[j]) { if (volSlideStatus[j]>=0xf1 && volSliding[j]) {
p->data[curRow][effectCol[j]++]=0xf9; p->data[readRow][effectCol[j]++]=0xf9;
p->data[curRow][effectCol[j]++]=volSlideStatus[j]&15; p->data[readRow][effectCol[j]++]=volSlideStatus[j]&15;
volSliding[j]=false; volSliding[j]=false;
} else if ((volSlideStatus[j]&15)==15 && volSlideStatus[j]>=0x10 && volSliding[j]) { } else if ((volSlideStatus[j]&15)==15 && volSlideStatus[j]>=0x10 && volSliding[j]) {
p->data[curRow][effectCol[j]++]=0xf8; p->data[readRow][effectCol[j]++]=0xf8;
p->data[curRow][effectCol[j]++]=volSlideStatus[j]>>4; p->data[readRow][effectCol[j]++]=volSlideStatus[j]>>4;
volSliding[j]=false; volSliding[j]=false;
} else { } else {
p->data[curRow][effectCol[j]++]=0xfa; p->data[readRow][effectCol[j]++]=0xfa;
p->data[curRow][effectCol[j]++]=volSliding[j]?volSlideStatus[j]:0; p->data[readRow][effectCol[j]++]=volSliding[j]?volSlideStatus[j]:0;
} }
doesVolSlide[j]=true; doesVolSlide[j]=true;
} else if (doesVolSlide[j] && mustCommitInitial) { } else if (doesVolSlide[j] && mustCommitInitial) {
p->data[curRow][effectCol[j]++]=0xfa; p->data[readRow][effectCol[j]++]=0xfa;
p->data[curRow][effectCol[j]++]=0; p->data[readRow][effectCol[j]++]=0;
} }
if (porting[j]!=portingOld[j] || portaStatusChanged[j]) { if (porting[j]!=portingOld[j] || portaStatusChanged[j]) {
if (portaStatus[j]>=0xe0 && portaType[j]!=3 && porting[j]) { if (portaStatus[j]>=0xe0 && portaType[j]!=3 && porting[j]) {
p->data[curRow][effectCol[j]++]=portaType[j]|0xf0; p->data[readRow][effectCol[j]++]=portaType[j]|0xf0;
p->data[curRow][effectCol[j]++]=(portaStatus[j]&15)*((portaStatus[j]>=0xf0)?1:1); p->data[readRow][effectCol[j]++]=(portaStatus[j]&15)*((portaStatus[j]>=0xf0)?1:1);
porting[j]=false; porting[j]=false;
} else { } else {
p->data[curRow][effectCol[j]++]=portaType[j]; p->data[readRow][effectCol[j]++]=portaType[j];
p->data[curRow][effectCol[j]++]=porting[j]?portaStatus[j]:0; p->data[readRow][effectCol[j]++]=porting[j]?portaStatus[j]:0;
} }
doesPitchSlide[j]=true; doesPitchSlide[j]=true;
} else if (doesPitchSlide[j] && mustCommitInitial) { } else if (doesPitchSlide[j] && mustCommitInitial) {
p->data[curRow][effectCol[j]++]=0x01; p->data[readRow][effectCol[j]++]=0x01;
p->data[curRow][effectCol[j]++]=0; p->data[readRow][effectCol[j]++]=0;
} }
if (arping[j]!=arpingOld[j] || arpStatusChanged[j]) { if (arping[j]!=arpingOld[j] || arpStatusChanged[j]) {
p->data[curRow][effectCol[j]++]=0x00; p->data[readRow][effectCol[j]++]=0x00;
p->data[curRow][effectCol[j]++]=arping[j]?arpStatus[j]:0; p->data[readRow][effectCol[j]++]=arping[j]?arpStatus[j]:0;
doesArp[j]=true; doesArp[j]=true;
} else if (doesArp[j] && mustCommitInitial) { } else if (doesArp[j] && mustCommitInitial) {
p->data[curRow][effectCol[j]++]=0x00; p->data[readRow][effectCol[j]++]=0x00;
p->data[curRow][effectCol[j]++]=0; p->data[readRow][effectCol[j]++]=0;
} }
if (effectCol[j]>=4+8*2) { if (effectCol[j]>=4+8*2) {
@ -805,7 +806,7 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
} }
} }
curRow++; readRow++;
memset(effectCol,4,32); memset(effectCol,4,32);
memcpy(vibingOld,vibing,32*sizeof(bool)); memcpy(vibingOld,vibing,32*sizeof(bool));
memcpy(volSlidingOld,volSliding,32*sizeof(bool)); memcpy(volSlidingOld,volSliding,32*sizeof(bool));
@ -821,7 +822,7 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
memset(arping,0,32*sizeof(bool)); memset(arping,0,32*sizeof(bool));
memset(did,0,32); memset(did,0,32);
mustCommitInitial=false; mustCommitInitial=false;
if (curRow>=64) break; if (readRow>=64) break;
continue; continue;
} }
@ -831,7 +832,7 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
bool hasEffect=what&128; bool hasEffect=what&128;
if (did[chan]) { if (did[chan]) {
logW("pat %d chan %d row %d: we already populated this channel!",i,chan,curRow); logW("pat %d chan %d row %d: we already populated this channel!",i,chan,readRow);
} else { } else {
did[chan]=true; did[chan]=true;
} }
@ -842,22 +843,22 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
unsigned char ins=reader.readC(); unsigned char ins=reader.readC();
if (note==254) { // note off if (note==254) { // note off
p->data[curRow][0]=100; p->data[readRow][0]=100;
p->data[curRow][1]=0; p->data[readRow][1]=0;
} else if (note!=255) { } else if (note!=255) {
p->data[curRow][0]=note&15; p->data[readRow][0]=note&15;
p->data[curRow][1]=note>>4; p->data[readRow][1]=note>>4;
if ((note&15)==0) { if ((note&15)==0) {
p->data[curRow][0]=12; p->data[readRow][0]=12;
p->data[curRow][1]--; p->data[readRow][1]--;
} }
} }
p->data[curRow][2]=(short)ins-1; p->data[readRow][2]=(short)ins-1;
} }
if (hasVol) { if (hasVol) {
unsigned char vol=reader.readC(); unsigned char vol=reader.readC();
if (vol==255) { if (vol==255) {
p->data[curRow][3]=-1; p->data[readRow][3]=-1;
} else { } else {
// check for OPL channel // check for OPL channel
if ((chanSettings[chan]&31)>=16) { if ((chanSettings[chan]&31)>=16) {
@ -865,17 +866,17 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
} else { } else {
if (vol>64) vol=64; if (vol>64) vol=64;
} }
p->data[curRow][3]=vol; p->data[readRow][3]=vol;
} }
} else if (p->data[curRow][2]!=-1) { } else if (p->data[readRow][2]!=-1) {
// populate with instrument volume // populate with instrument volume
unsigned char vol=defVol[p->data[curRow][2]&255]; unsigned char vol=defVol[p->data[readRow][2]&255];
if ((chanSettings[chan]&31)>=16) { if ((chanSettings[chan]&31)>=16) {
if (vol>63) vol=63; if (vol>63) vol=63;
} else { } else {
if (vol>64) vol=64; if (vol>64) vol=64;
} }
p->data[curRow][3]=vol; p->data[readRow][3]=vol;
} }
if (hasEffect) { if (hasEffect) {
unsigned char effect=reader.readC(); unsigned char effect=reader.readC();
@ -883,17 +884,17 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
switch (effect+'A'-1) { switch (effect+'A'-1) {
case 'A': // speed case 'A': // speed
p->data[curRow][effectCol[chan]++]=0x0f; p->data[readRow][effectCol[chan]++]=0x0f;
p->data[curRow][effectCol[chan]++]=effectVal; p->data[readRow][effectCol[chan]++]=effectVal;
break; break;
case 'B': // go to order case 'B': // go to order
p->data[curRow][effectCol[chan]++]=0x0b; p->data[readRow][effectCol[chan]++]=0x0b;
logD("0B: %x %x",effectVal,orders[effectVal]); logD("0B: %x %x",effectVal,orders[effectVal]);
p->data[curRow][effectCol[chan]++]=orders[effectVal]; p->data[readRow][effectCol[chan]++]=orders[effectVal];
break; break;
case 'C': // next order case 'C': // next order
p->data[curRow][effectCol[chan]++]=0x0d; p->data[readRow][effectCol[chan]++]=0x0d;
p->data[curRow][effectCol[chan]++]=(effectVal>>4)*10+(effectVal&15); p->data[readRow][effectCol[chan]++]=(effectVal>>4)*10+(effectVal&15);
break; break;
case 'D': // vol slide case 'D': // vol slide
if (effectVal!=0) { if (effectVal!=0) {
@ -985,32 +986,32 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
case 'N': // channel vol slide (extension) case 'N': // channel vol slide (extension)
break; break;
case 'O': // offset case 'O': // offset
p->data[curRow][effectCol[chan]++]=0x91; p->data[readRow][effectCol[chan]++]=0x91;
p->data[curRow][effectCol[chan]++]=effectVal; p->data[readRow][effectCol[chan]++]=effectVal;
break; break;
case 'P': // pan slide (extension) case 'P': // pan slide (extension)
break; break;
case 'Q': // retrigger case 'Q': // retrigger
p->data[curRow][effectCol[chan]++]=0x0c; p->data[readRow][effectCol[chan]++]=0x0c;
p->data[curRow][effectCol[chan]++]=effectVal&15; p->data[readRow][effectCol[chan]++]=effectVal&15;
break; break;
case 'R': // tremolo case 'R': // tremolo
break; break;
case 'S': // special... case 'S': // special...
switch (effectVal>>4) { switch (effectVal>>4) {
case 0xc: case 0xc:
p->data[curRow][effectCol[chan]++]=0xec; p->data[readRow][effectCol[chan]++]=0xec;
p->data[curRow][effectCol[chan]++]=effectVal&15; p->data[readRow][effectCol[chan]++]=effectVal&15;
break; break;
case 0xd: case 0xd:
p->data[curRow][effectCol[chan]++]=0xed; p->data[readRow][effectCol[chan]++]=0xed;
p->data[curRow][effectCol[chan]++]=effectVal&15; p->data[readRow][effectCol[chan]++]=effectVal&15;
break; break;
} }
break; break;
case 'T': // tempo case 'T': // tempo
p->data[curRow][effectCol[chan]++]=0xf0; p->data[readRow][effectCol[chan]++]=0xf0;
p->data[curRow][effectCol[chan]++]=effectVal; p->data[readRow][effectCol[chan]++]=effectVal;
break; break;
case 'U': // fine vibrato case 'U': // fine vibrato
if (effectVal!=0) { if (effectVal!=0) {
@ -1025,8 +1026,8 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
break; break;
case 'X': // panning (extension) case 'X': // panning (extension)
if (effectVal<=0x80) { if (effectVal<=0x80) {
p->data[curRow][effectCol[chan]++]=0x80; p->data[readRow][effectCol[chan]++]=0x80;
p->data[curRow][effectCol[chan]++]=(effectVal&0x80)?0xff:(effectVal<<1); p->data[readRow][effectCol[chan]++]=(effectVal&0x80)?0xff:(effectVal<<1);
} }
break; break;
case 'Y': // panbrello (extension) case 'Y': // panbrello (extension)