MOD import: more improvements
- prepare for old Soundtracker MOD import - add "bypass limits" flag - dope.mod plays correctly now - automatic channel names
This commit is contained in:
parent
10cea9956b
commit
0a307fc4a6
|
@ -1250,32 +1250,44 @@ bool DivEngine::loadMod(unsigned char* file, size_t len) {
|
|||
ds.tuning=436.0;
|
||||
ds.version=DIV_VERSION_MOD;
|
||||
|
||||
int insCount=31;
|
||||
bool bypassLimits=false;
|
||||
|
||||
// check mod magic bytes
|
||||
if (!reader.seek(1080,SEEK_SET)) {
|
||||
logD("couldn't seek to 1080\n");
|
||||
throw EndOfFileException(&reader,reader.tell());
|
||||
}
|
||||
reader.read(magic,4);
|
||||
if (memcmp(magic,"M.K.",4)==0 || memcmp(magic,"M!K!",4)==0) {
|
||||
if (memcmp(magic,"M.K.",4)==0 || memcmp(magic,"M!K!",4)==0 || memcmp(magic,"M&K!",4)==0) {
|
||||
logD("detected a ProTracker module\n");
|
||||
chCount=4;
|
||||
} else if(memcmp(magic+1,"CHN",3)==0 && magic[0]>='1' && magic[0]<='9') {
|
||||
} else if (memcmp(magic,"CD81",4)==0 || memcmp(magic,"OKTA",4)==0 || memcmp(magic,"OCTA",4)==0) {
|
||||
logD("detected an Oktalyzer/Octalyzer/OctaMED module\n");
|
||||
chCount=8;
|
||||
} else if (memcmp(magic+1,"CHN",3)==0 && magic[0]>='1' && magic[0]<='9') {
|
||||
logD("detected a FastTracker module\n");
|
||||
chCount=magic[0]-'0';
|
||||
} else if((memcmp(magic+2,"CH",2)==0 || memcmp(magic+2,"CN",2)==0)
|
||||
&&(magic[0]>='1' && magic[0]<='9' && magic[1]>='0' && magic[1]<='9')) {
|
||||
logD("detected a FastTracker module\n");
|
||||
} else if (memcmp(magic,"FLT",3)==0 && magic[3]>='1' && magic[3]<='9') {
|
||||
logD("detected a Fairlight module\n");
|
||||
chCount=magic[3]-'0';
|
||||
} else if (memcmp(magic,"TDZ",3)==0 && magic[3]>='1' && magic[3]<='9') {
|
||||
logD("detected a TakeTracker module\n");
|
||||
chCount=magic[3]-'0';
|
||||
} else if ((memcmp(magic+2,"CH",2)==0 || memcmp(magic+2,"CN",2)==0)
|
||||
&& (magic[0]>='1' && magic[0]<='9' && magic[1]>='0' && magic[1]<='9')) {
|
||||
logD("detected a Fast/TakeTracker module\n");
|
||||
chCount=((magic[0]-'0')*10)+(magic[1]-'0');
|
||||
} else {
|
||||
// TODO: Soundtracker MOD?
|
||||
insCount=15;
|
||||
throw InvalidHeaderException();
|
||||
}
|
||||
// song name
|
||||
reader.seek(0,SEEK_SET);
|
||||
ds.name=reader.readString(20);
|
||||
// samples
|
||||
ds.sampleLen=31;
|
||||
for (int i=0;i<31;i++) {
|
||||
for (int i=0;i<insCount;i++) {
|
||||
DivSample* sample=new DivSample;
|
||||
sample->depth=8;
|
||||
sample->name=reader.readString(22);
|
||||
|
@ -1302,6 +1314,7 @@ bool DivEngine::loadMod(unsigned char* file, size_t len) {
|
|||
sample->init(slen);
|
||||
ds.sample.push_back(sample);
|
||||
}
|
||||
ds.sampleLen=ds.sample.size();
|
||||
// orders
|
||||
ds.ordersLen=ordCount=reader.readC();
|
||||
reader.readC(); // restart position, unused
|
||||
|
@ -1343,6 +1356,9 @@ bool DivEngine::loadMod(unsigned char* file, size_t len) {
|
|||
short note=(short)round(log2(3424.0/period)*12);
|
||||
dstrow[0]=((note-1)%12)+1;
|
||||
dstrow[1]=(note-1)/12+1;
|
||||
if (period<114) {
|
||||
bypassLimits=true;
|
||||
}
|
||||
}
|
||||
// effects are done later
|
||||
short fxtyp=data[2]&0x0f;
|
||||
|
@ -1521,24 +1537,26 @@ bool DivEngine::loadMod(unsigned char* file, size_t len) {
|
|||
ds.systemLen=(chCount+3)/4;
|
||||
for(int i=0; i<ds.systemLen; i++) {
|
||||
ds.system[i]=DIV_SYSTEM_AMIGA;
|
||||
ds.systemFlags[i]=1|(80<<8); // PAL
|
||||
ds.systemFlags[i]=1|(80<<8)|(bypassLimits?4:0); // PAL
|
||||
}
|
||||
for(int i=0; i<chCount; i++) {
|
||||
ds.chanShow[i]=true;
|
||||
ds.chanName[i]=fmt::sprintf("Channel %d",i+1);
|
||||
ds.chanShortName[i]=fmt::sprintf("C%d",i+1);
|
||||
}
|
||||
for(int i=chCount; i<ds.systemLen*4; i++) {
|
||||
ds.pat[i].effectRows=1;
|
||||
ds.chanShow[i]=false;
|
||||
}
|
||||
// instrument creation
|
||||
ds.insLen=31;
|
||||
for(int i=0; i<31; i++) {
|
||||
for(int i=0; i<insCount; i++) {
|
||||
DivInstrument* ins=new DivInstrument;
|
||||
ins->type=DIV_INS_AMIGA;
|
||||
ins->amiga.initSample=i;
|
||||
ins->name=ds.sample[i]->name;
|
||||
ds.ins.push_back(ins);
|
||||
}
|
||||
ds.insLen=ds.ins.size();
|
||||
|
||||
if (active) quitDispatch();
|
||||
isBusy.lock();
|
||||
|
|
|
@ -93,7 +93,11 @@ void DivPlatformAmiga::acquire(short* bufL, short* bufR, size_t start, size_t le
|
|||
chan[i].busClock=0;
|
||||
}
|
||||
}*/
|
||||
chan[i].audSub+=MAX(114,chan[i].freq);
|
||||
if (bypassLimits) {
|
||||
chan[i].audSub+=MAX(AMIGA_DIVIDER,chan[i].freq);
|
||||
} else {
|
||||
chan[i].audSub+=MAX(114,chan[i].freq);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isMuted[i]) {
|
||||
|
@ -355,6 +359,8 @@ void DivPlatformAmiga::setFlags(unsigned int flags) {
|
|||
rate=chipClock/AMIGA_DIVIDER;
|
||||
sep1=((flags>>8)&127)+127;
|
||||
sep2=127-((flags>>8)&127);
|
||||
amigaModel=flags&2;
|
||||
bypassLimits=flags&4;
|
||||
}
|
||||
|
||||
int DivPlatformAmiga::init(DivEngine* p, int channels, int sugRate, unsigned int flags) {
|
||||
|
|
|
@ -66,6 +66,8 @@ class DivPlatformAmiga: public DivDispatch {
|
|||
};
|
||||
Channel chan[4];
|
||||
bool isMuted[4];
|
||||
bool bypassLimits;
|
||||
bool amigaModel;
|
||||
|
||||
int sep1, sep2;
|
||||
|
||||
|
|
|
@ -5853,19 +5853,23 @@ bool FurnaceGUI::loop() {
|
|||
if (ImGui::SliderInt("##StereoSep",&stereoSep,0,127)) {
|
||||
if (stereoSep<0) stereoSep=0;
|
||||
if (stereoSep>127) stereoSep=127;
|
||||
e->setSysFlags(i,(flags&1)|((stereoSep&127)<<8),restart);
|
||||
e->setSysFlags(i,(flags&(~0x7f00))|((stereoSep&127)<<8),restart);
|
||||
updateWindowTitle();
|
||||
} rightClickable
|
||||
/* TODO LATER: I want 0.5 out already
|
||||
if (ImGui::RadioButton("Amiga 500 (OCS)",(flags&2)==0)) {
|
||||
e->setSysFlags(i,flags&1);
|
||||
e->setSysFlags(i,flags&(~2),restart);
|
||||
}
|
||||
if (ImGui::RadioButton("Amiga 1200 (AGA)",(flags&2)==2)) {
|
||||
e->setSysFlags(i,(flags&1)|2);
|
||||
}*/
|
||||
e->setSysFlags(i,(flags&(~2))|2,restart);
|
||||
}
|
||||
sysPal=flags&1;
|
||||
if (ImGui::Checkbox("PAL",&sysPal)) {
|
||||
e->setSysFlags(i,(flags&2)|sysPal,restart);
|
||||
e->setSysFlags(i,(flags&(~1))|sysPal,restart);
|
||||
updateWindowTitle();
|
||||
}
|
||||
bool bypassLimits=flags&4;
|
||||
if (ImGui::Checkbox("Bypass frequency limits",&bypassLimits)) {
|
||||
e->setSysFlags(i,(flags&(~4))|(bypassLimits<<2),restart);
|
||||
updateWindowTitle();
|
||||
}
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue