S3M import: pattern data, part 2

also fix OPL ins loading
This commit is contained in:
tildearrow 2024-06-22 15:35:38 -05:00
parent 816c93c1b7
commit 7371992835

View file

@ -76,8 +76,8 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
try { try {
DivSong ds; DivSong ds;
ds.version=DIV_VERSION_S3M; ds.version=DIV_VERSION_S3M;
//ds.linearPitch=0; ds.linearPitch=0;
//ds.pitchMacroIsLinear=false; ds.pitchMacroIsLinear=false;
ds.noSlidesOnFirstTick=true; ds.noSlidesOnFirstTick=true;
ds.rowResetsArpPos=true; ds.rowResetsArpPos=true;
ds.ignoreJumpAtEnd=false; ds.ignoreJumpAtEnd=false;
@ -248,7 +248,7 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
ds.systemName="PC"; ds.systemName="PC";
// would use ES5506 but it has log volume // would use ES5506 but it has log volume
if (hasPCM) { if (hasPCM) {
ds.system[ds.systemLen]=DIV_SYSTEM_C140; ds.system[ds.systemLen]=DIV_SYSTEM_NDS;
ds.systemVol[ds.systemLen]=1.0f; ds.systemVol[ds.systemLen]=1.0f;
ds.systemPan[ds.systemLen]=0; ds.systemPan[ds.systemLen]=0;
ds.systemLen++; ds.systemLen++;
@ -276,12 +276,12 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
reader.read(magic,4); reader.read(magic,4);
if (memcmp(magic,"SCRS",4)==0) { if (memcmp(magic,"SCRS",4)==0) {
ins->type=DIV_INS_C140; ins->type=DIV_INS_AMIGA;
} else if (memcmp(magic,"SCRI",4)==0) { } else if (memcmp(magic,"SCRI",4)==0) {
ins->type=DIV_INS_OPL; ins->type=DIV_INS_OPL;
} else { } else {
logW("odd magic!"); logW("odd magic!");
ins->type=DIV_INS_C140; ins->type=DIV_INS_AMIGA;
ds.ins.push_back(ins); ds.ins.push_back(ins);
continue; continue;
} }
@ -296,7 +296,7 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
unsigned char type=reader.readC(); unsigned char type=reader.readC();
if (ins->type==DIV_INS_C140) { if (ins->type==DIV_INS_AMIGA) {
if (type>1) { if (type>1) {
logE("invalid instrument type! %d",type); logE("invalid instrument type! %d",type);
lastError="invalid instrument!"; lastError="invalid instrument!";
@ -316,7 +316,7 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
String dosName=reader.readString(12); String dosName=reader.readString(12);
if (ins->type==DIV_INS_C140) { if (ins->type==DIV_INS_AMIGA) {
unsigned int memSeg=0; unsigned int memSeg=0;
memSeg=(unsigned char)reader.readC(); memSeg=(unsigned char)reader.readC();
memSeg|=((unsigned short)reader.readS())<<8; memSeg|=((unsigned short)reader.readS())<<8;
@ -451,6 +451,9 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
opC.sl=((s3i.Ceg_SR>>4)&15); opC.sl=((s3i.Ceg_SR>>4)&15);
opC.ws=s3i.Cwave; opC.ws=s3i.Cwave;
// unused
reader.readC();
defVol[i]=reader.readC(); defVol[i]=reader.readC();
// what? // what?
unsigned char dsk=reader.readC(); unsigned char dsk=reader.readC();
@ -624,13 +627,24 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
unsigned char vol=reader.readC(); unsigned char vol=reader.readC();
if (vol==255) { if (vol==255) {
p->data[curRow][3]=-1; p->data[curRow][3]=-1;
} else {
// check for OPL channel
if ((chanSettings[chan]&31)>=16) {
if (vol>63) vol=63;
} else { } else {
if (vol>64) vol=64; if (vol>64) vol=64;
}
p->data[curRow][3]=vol; p->data[curRow][3]=vol;
} }
} else if (p->data[curRow][2]!=-1) { } else if (p->data[curRow][2]!=-1) {
// populate with instrument volume // populate with instrument volume
p->data[curRow][3]=defVol[p->data[curRow][2]&255]; unsigned char vol=defVol[p->data[curRow][2]&255];
if ((chanSettings[chan]&31)>=16) {
if (vol>63) vol=63;
} else {
if (vol>64) vol=64;
}
p->data[curRow][3]=vol;
} }
if (hasEffect) { if (hasEffect) {
unsigned char effect=reader.readC(); unsigned char effect=reader.readC();
@ -661,7 +675,7 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
portaStatus[chan]=effectVal; portaStatus[chan]=effectVal;
portaStatusChanged[chan]=true; portaStatusChanged[chan]=true;
} }
portaType[chan]=1; portaType[chan]=2;
porting[chan]=true; porting[chan]=true;
break; break;
case 'F': // pitch up case 'F': // pitch up
@ -669,7 +683,7 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
portaStatus[chan]=effectVal; portaStatus[chan]=effectVal;
portaStatusChanged[chan]=true; portaStatusChanged[chan]=true;
} }
portaType[chan]=2; portaType[chan]=1;
porting[chan]=true; porting[chan]=true;
break; break;
case 'G': // porta case 'G': // porta
@ -700,6 +714,13 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
vibing[chan]=true; vibing[chan]=true;
break; break;
case 'L': // vol slide + porta case 'L': // vol slide + porta
if (effectVal!=0) {
volSlideStatus[chan]=effectVal;
volSlideStatusChanged[chan]=true;
}
volSliding[chan]=true;
porting[chan]=true;
portaType[chan]=3;
break; break;
case 'M': // channel vol (!) case 'M': // channel vol (!)
break; break;
@ -710,6 +731,8 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
case 'P': // pan slide (!) case 'P': // pan slide (!)
break; break;
case 'Q': // retrigger case 'Q': // retrigger
p->data[curRow][effectCol[chan]++]=0x0c;
p->data[curRow][effectCol[chan]++]=effectVal&15;
break; break;
case 'R': // tremolo case 'R': // tremolo
break; break;
@ -726,6 +749,8 @@ bool DivEngine::loadS3M(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[curRow][effectCol[chan]++]=effectVal;
break; break;
case 'Y': // panbrello (!) case 'Y': // panbrello (!)
break; break;