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.tuning=436.0;
|
||||||
ds.version=DIV_VERSION_MOD;
|
ds.version=DIV_VERSION_MOD;
|
||||||
|
|
||||||
|
int insCount=31;
|
||||||
|
bool bypassLimits=false;
|
||||||
|
|
||||||
// check mod magic bytes
|
// check mod magic bytes
|
||||||
if (!reader.seek(1080,SEEK_SET)) {
|
if (!reader.seek(1080,SEEK_SET)) {
|
||||||
logD("couldn't seek to 1080\n");
|
logD("couldn't seek to 1080\n");
|
||||||
throw EndOfFileException(&reader,reader.tell());
|
throw EndOfFileException(&reader,reader.tell());
|
||||||
}
|
}
|
||||||
reader.read(magic,4);
|
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");
|
logD("detected a ProTracker module\n");
|
||||||
chCount=4;
|
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");
|
logD("detected a FastTracker module\n");
|
||||||
chCount=magic[0]-'0';
|
chCount=magic[0]-'0';
|
||||||
} else if((memcmp(magic+2,"CH",2)==0 || memcmp(magic+2,"CN",2)==0)
|
} else if (memcmp(magic,"FLT",3)==0 && magic[3]>='1' && magic[3]<='9') {
|
||||||
&&(magic[0]>='1' && magic[0]<='9' && magic[1]>='0' && magic[1]<='9')) {
|
logD("detected a Fairlight module\n");
|
||||||
logD("detected a FastTracker 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');
|
chCount=((magic[0]-'0')*10)+(magic[1]-'0');
|
||||||
} else {
|
} else {
|
||||||
// TODO: Soundtracker MOD?
|
// TODO: Soundtracker MOD?
|
||||||
|
insCount=15;
|
||||||
throw InvalidHeaderException();
|
throw InvalidHeaderException();
|
||||||
}
|
}
|
||||||
// song name
|
// song name
|
||||||
reader.seek(0,SEEK_SET);
|
reader.seek(0,SEEK_SET);
|
||||||
ds.name=reader.readString(20);
|
ds.name=reader.readString(20);
|
||||||
// samples
|
// samples
|
||||||
ds.sampleLen=31;
|
for (int i=0;i<insCount;i++) {
|
||||||
for (int i=0;i<31;i++) {
|
|
||||||
DivSample* sample=new DivSample;
|
DivSample* sample=new DivSample;
|
||||||
sample->depth=8;
|
sample->depth=8;
|
||||||
sample->name=reader.readString(22);
|
sample->name=reader.readString(22);
|
||||||
|
@ -1302,6 +1314,7 @@ bool DivEngine::loadMod(unsigned char* file, size_t len) {
|
||||||
sample->init(slen);
|
sample->init(slen);
|
||||||
ds.sample.push_back(sample);
|
ds.sample.push_back(sample);
|
||||||
}
|
}
|
||||||
|
ds.sampleLen=ds.sample.size();
|
||||||
// orders
|
// orders
|
||||||
ds.ordersLen=ordCount=reader.readC();
|
ds.ordersLen=ordCount=reader.readC();
|
||||||
reader.readC(); // restart position, unused
|
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);
|
short note=(short)round(log2(3424.0/period)*12);
|
||||||
dstrow[0]=((note-1)%12)+1;
|
dstrow[0]=((note-1)%12)+1;
|
||||||
dstrow[1]=(note-1)/12+1;
|
dstrow[1]=(note-1)/12+1;
|
||||||
|
if (period<114) {
|
||||||
|
bypassLimits=true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// effects are done later
|
// effects are done later
|
||||||
short fxtyp=data[2]&0x0f;
|
short fxtyp=data[2]&0x0f;
|
||||||
|
@ -1521,24 +1537,26 @@ bool DivEngine::loadMod(unsigned char* file, size_t len) {
|
||||||
ds.systemLen=(chCount+3)/4;
|
ds.systemLen=(chCount+3)/4;
|
||||||
for(int i=0; i<ds.systemLen; i++) {
|
for(int i=0; i<ds.systemLen; i++) {
|
||||||
ds.system[i]=DIV_SYSTEM_AMIGA;
|
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++) {
|
for(int i=0; i<chCount; i++) {
|
||||||
ds.chanShow[i]=true;
|
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++) {
|
for(int i=chCount; i<ds.systemLen*4; i++) {
|
||||||
ds.pat[i].effectRows=1;
|
ds.pat[i].effectRows=1;
|
||||||
ds.chanShow[i]=false;
|
ds.chanShow[i]=false;
|
||||||
}
|
}
|
||||||
// instrument creation
|
// instrument creation
|
||||||
ds.insLen=31;
|
for(int i=0; i<insCount; i++) {
|
||||||
for(int i=0; i<31; i++) {
|
|
||||||
DivInstrument* ins=new DivInstrument;
|
DivInstrument* ins=new DivInstrument;
|
||||||
ins->type=DIV_INS_AMIGA;
|
ins->type=DIV_INS_AMIGA;
|
||||||
ins->amiga.initSample=i;
|
ins->amiga.initSample=i;
|
||||||
ins->name=ds.sample[i]->name;
|
ins->name=ds.sample[i]->name;
|
||||||
ds.ins.push_back(ins);
|
ds.ins.push_back(ins);
|
||||||
}
|
}
|
||||||
|
ds.insLen=ds.ins.size();
|
||||||
|
|
||||||
if (active) quitDispatch();
|
if (active) quitDispatch();
|
||||||
isBusy.lock();
|
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].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]) {
|
if (!isMuted[i]) {
|
||||||
|
@ -355,6 +359,8 @@ void DivPlatformAmiga::setFlags(unsigned int flags) {
|
||||||
rate=chipClock/AMIGA_DIVIDER;
|
rate=chipClock/AMIGA_DIVIDER;
|
||||||
sep1=((flags>>8)&127)+127;
|
sep1=((flags>>8)&127)+127;
|
||||||
sep2=127-((flags>>8)&127);
|
sep2=127-((flags>>8)&127);
|
||||||
|
amigaModel=flags&2;
|
||||||
|
bypassLimits=flags&4;
|
||||||
}
|
}
|
||||||
|
|
||||||
int DivPlatformAmiga::init(DivEngine* p, int channels, int sugRate, unsigned int flags) {
|
int DivPlatformAmiga::init(DivEngine* p, int channels, int sugRate, unsigned int flags) {
|
||||||
|
|
|
@ -66,6 +66,8 @@ class DivPlatformAmiga: public DivDispatch {
|
||||||
};
|
};
|
||||||
Channel chan[4];
|
Channel chan[4];
|
||||||
bool isMuted[4];
|
bool isMuted[4];
|
||||||
|
bool bypassLimits;
|
||||||
|
bool amigaModel;
|
||||||
|
|
||||||
int sep1, sep2;
|
int sep1, sep2;
|
||||||
|
|
||||||
|
|
|
@ -5853,19 +5853,23 @@ bool FurnaceGUI::loop() {
|
||||||
if (ImGui::SliderInt("##StereoSep",&stereoSep,0,127)) {
|
if (ImGui::SliderInt("##StereoSep",&stereoSep,0,127)) {
|
||||||
if (stereoSep<0) stereoSep=0;
|
if (stereoSep<0) stereoSep=0;
|
||||||
if (stereoSep>127) stereoSep=127;
|
if (stereoSep>127) stereoSep=127;
|
||||||
e->setSysFlags(i,(flags&1)|((stereoSep&127)<<8),restart);
|
e->setSysFlags(i,(flags&(~0x7f00))|((stereoSep&127)<<8),restart);
|
||||||
updateWindowTitle();
|
updateWindowTitle();
|
||||||
} rightClickable
|
} rightClickable
|
||||||
/* TODO LATER: I want 0.5 out already
|
|
||||||
if (ImGui::RadioButton("Amiga 500 (OCS)",(flags&2)==0)) {
|
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)) {
|
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;
|
sysPal=flags&1;
|
||||||
if (ImGui::Checkbox("PAL",&sysPal)) {
|
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();
|
updateWindowTitle();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue