diff --git a/src/engine/engine.h b/src/engine/engine.h index 85da26ea9..47146550c 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -53,8 +53,8 @@ #define EXTERN_BUSY_BEGIN_SOFT e->softLocked=true; e->isBusy.lock(); #define EXTERN_BUSY_END e->isBusy.unlock(); e->softLocked=false; -#define DIV_VERSION "dev152" -#define DIV_ENGINE_VERSION 152 +#define DIV_VERSION "dev153" +#define DIV_ENGINE_VERSION 153 // for imports #define DIV_VERSION_MOD 0xff01 #define DIV_VERSION_FC 0xff02 diff --git a/src/engine/fileOps.cpp b/src/engine/fileOps.cpp index 0ca5dff69..c184d20ac 100644 --- a/src/engine/fileOps.cpp +++ b/src/engine/fileOps.cpp @@ -2715,6 +2715,15 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) { } } + // SrgaPCM slide compat + if (ds.version<153) { + for (int i=0; icalcArp(chan[i].note,chan[i].std.arp.val)<<6); + chan[i].baseFreq=(parent->calcArp(chan[i].note,chan[i].std.arp.val)<<7); } chan[i].freqChanged=true; } @@ -106,21 +106,22 @@ void DivPlatformSegaPCM::tick(bool sysTick) { } if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) { - chan[i].freq=chan[i].baseFreq+(chan[i].pitch>>1)-64; + chan[i].freq=chan[i].baseFreq+(chan[i].pitch)-128+(oldSlides?0:chan[i].pitch2); if (!parent->song.oldArpStrategy) { if (chan[i].fixedArp) { - chan[i].freq=(chan[i].baseNoteOverride<<6)+(chan[i].pitch>>1)-64+chan[i].pitch2; + chan[i].freq=(chan[i].baseNoteOverride<<7)+chan[i].pitch-128+(chan[i].pitch2<<(oldSlides?1:0)); } else { - chan[i].freq+=chan[i].arpOff<<6; + chan[i].freq+=chan[i].arpOff<<7; } } + if (oldSlides) chan[i].freq&=~1; if (chan[i].furnacePCM) { double off=1.0; if (chan[i].pcm.sample>=0 && chan[i].pcm.samplesong.sampleLen) { DivSample* s=parent->getSample(chan[i].pcm.sample); off=(double)s->centerRate/8363.0; } - chan[i].pcm.freq=MIN(255,(15625+(off*parent->song.tuning*pow(2.0,double(chan[i].freq+256)/(64.0*12.0)))*255)/31250)+chan[i].pitch2; + chan[i].pcm.freq=MIN(255,(15625+(off*parent->song.tuning*pow(2.0,double(chan[i].freq+512)/(128.0*12.0)))*255)/31250)+(oldSlides?chan[i].pitch2:0); rWrite(7+(i<<3),chan[i].pcm.freq); } chan[i].freqChanged=false; @@ -201,7 +202,7 @@ int DivPlatformSegaPCM::dispatch(DivCommand c) { } if (c.value!=DIV_NOTE_NULL) { chan[c.chan].note=c.value; - chan[c.chan].baseFreq=(c.value<<6); + chan[c.chan].baseFreq=(c.value<<7); chan[c.chan].freqChanged=true; } chan[c.chan].furnacePCM=true; @@ -289,17 +290,18 @@ int DivPlatformSegaPCM::dispatch(DivCommand c) { break; } case DIV_CMD_NOTE_PORTA: { - int destFreq=(c.value2<<6); + int destFreq=(c.value2<<7); int newFreq; + int mul=(oldSlides || parent->song.linearPitch!=2)?8:parent->song.pitchSlideSpeed; bool return2=false; if (destFreq>chan[c.chan].baseFreq) { - newFreq=chan[c.chan].baseFreq+c.value*4; + newFreq=chan[c.chan].baseFreq+c.value*mul; if (newFreq>=destFreq) { newFreq=destFreq; return2=true; } } else { - newFreq=chan[c.chan].baseFreq-c.value*4; + newFreq=chan[c.chan].baseFreq-c.value*mul; if (newFreq<=destFreq) { newFreq=destFreq; return2=true; @@ -314,7 +316,7 @@ int DivPlatformSegaPCM::dispatch(DivCommand c) { break; } case DIV_CMD_LEGATO: { - chan[c.chan].baseFreq=(c.value<<6); + chan[c.chan].baseFreq=(c.value<<7); chan[c.chan].freqChanged=true; break; } @@ -337,7 +339,7 @@ int DivPlatformSegaPCM::dispatch(DivCommand c) { return 127; break; case DIV_CMD_PRE_PORTA: - if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will && !NEW_ARP_STRAT) chan[c.chan].baseFreq=(chan[c.chan].note<<6); + if (!chan[c.chan].inPorta && c.value && !parent->song.brokenPortaArp && chan[c.chan].std.arp.will && !NEW_ARP_STRAT) chan[c.chan].baseFreq=(chan[c.chan].note<<7); chan[c.chan].inPorta=c.value; break; case DIV_CMD_PRE_NOTE: @@ -504,6 +506,8 @@ void DivPlatformSegaPCM::setFlags(const DivConfig& flags) { for (int i=0; i<16; i++) { oscBuf[i]->rate=rate; } + + oldSlides=flags.getBool("oldSlides",false); } int DivPlatformSegaPCM::getOutputCount() { diff --git a/src/engine/platform/segapcm.h b/src/engine/platform/segapcm.h index 9e2ad5df1..b818306b1 100644 --- a/src/engine/platform/segapcm.h +++ b/src/engine/platform/segapcm.h @@ -65,6 +65,7 @@ class DivPlatformSegaPCM: public DivDispatch { segapcm_device pcm; int delay; int pcmL, pcmR, pcmCycles; + bool oldSlides; unsigned char sampleBank; unsigned char lastBusy; diff --git a/src/gui/sysConf.cpp b/src/gui/sysConf.cpp index 77bc6c726..3e36ad857 100644 --- a/src/gui/sysConf.cpp +++ b/src/gui/sysConf.cpp @@ -1770,6 +1770,21 @@ bool FurnaceGUI::drawSysConf(int chan, DivSystem type, DivConfig& flags, bool mo } break; } + case DIV_SYSTEM_SEGAPCM: + case DIV_SYSTEM_SEGAPCM_COMPAT: { + bool oldSlides=flags.getBool("oldSlides",false); + + if (ImGui::Checkbox("Legacy slides and pitch (compatibility)",&oldSlides)) { + altered=true; + } + + if (altered) { + e->lockSave([&]() { + flags.set("oldSlides",oldSlides); + }); + } + break; + } case DIV_SYSTEM_SM8521:/* { bool noAntiClick=flags.getBool("noAntiClick",false);