diff --git a/src/engine/fileOps.cpp b/src/engine/fileOps.cpp index a77722c5a..28b7ff8fe 100644 --- a/src/engine/fileOps.cpp +++ b/src/engine/fileOps.cpp @@ -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;idepth=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; itype=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(); diff --git a/src/engine/platform/amiga.cpp b/src/engine/platform/amiga.cpp index 31a7a04c6..49b5b59ab 100644 --- a/src/engine/platform/amiga.cpp +++ b/src/engine/platform/amiga.cpp @@ -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) { diff --git a/src/engine/platform/amiga.h b/src/engine/platform/amiga.h index 93b61b6eb..02dcb3de9 100644 --- a/src/engine/platform/amiga.h +++ b/src/engine/platform/amiga.h @@ -66,6 +66,8 @@ class DivPlatformAmiga: public DivDispatch { }; Channel chan[4]; bool isMuted[4]; + bool bypassLimits; + bool amigaModel; int sep1, sep2; diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 344480b47..809c61fe7 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -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;