From 658f69bc4e040c86845df8b069ad5ea683311aef Mon Sep 17 00:00:00 2001 From: tildearrow Date: Tue, 12 Sep 2023 01:12:59 -0500 Subject: [PATCH] dev176 - OPM/OPZ: fix pitch --- src/engine/engine.h | 4 ++-- src/engine/fileOps.cpp | 15 +++++++++++++++ src/engine/platform/arcade.cpp | 24 +++++++++++++----------- src/engine/platform/fmshared_OPM.h | 6 ++++-- src/engine/platform/tx81z.cpp | 24 +++++++++++++----------- src/gui/sysConf.cpp | 26 ++++++++++++++++++++++++++ 6 files changed, 73 insertions(+), 26 deletions(-) diff --git a/src/engine/engine.h b/src/engine/engine.h index ccaaf36e3..561cef222 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -58,8 +58,8 @@ class DivWorkPool; #define DIV_UNSTABLE -#define DIV_VERSION "0.6pre14" -#define DIV_ENGINE_VERSION 175 +#define DIV_VERSION "dev176" +#define DIV_ENGINE_VERSION 176 // 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 69f329e00..6f7065ef4 100644 --- a/src/engine/fileOps.cpp +++ b/src/engine/fileOps.cpp @@ -1058,6 +1058,11 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) { ds.systemFlags[0].set("keyPriority",false); } + // OPM broken pitch + if (ds.system[0]==DIV_SYSTEM_YM2151) { + ds.systemFlags[0].set("brokenPitch",true); + } + ds.systemName=getSongSystemLegacyName(ds,!getConfInt("noMultiSystem",0)); if (active) quitDispatch(); @@ -2976,6 +2981,16 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) { } } + // OPM/OPZ slide compat + if (ds.version<176) { + for (int i=0; i>1)-64+chan[i].pitch2; + chan[i].freq=chan[i].baseFreq+chan[i].pitch-128+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; } else { - chan[i].freq+=chan[i].arpOff<<6; + chan[i].freq+=chan[i].arpOff<<7; } } if (chan[i].freq<0) chan[i].freq=0; - if (chan[i].freq>=(95<<6)) chan[i].freq=(95<<6)-1; - immWrite(i+0x28,hScale(chan[i].freq>>6)); - immWrite(i+0x30,chan[i].freq<<2); + if (chan[i].freq>=(95<<7)) chan[i].freq=(95<<7)-1; + immWrite(i+0x28,hScale(chan[i].freq>>7)); + immWrite(i+0x30,((chan[i].freq<<1)&0xfc)); hardResetElapsed+=2; chan[i].freqChanged=false; } @@ -534,13 +534,13 @@ int DivPlatformArcade::dispatch(DivCommand c) { int newFreq; bool return2=false; if (destFreq>chan[c.chan].baseFreq) { - newFreq=chan[c.chan].baseFreq+c.value; + newFreq=chan[c.chan].baseFreq+c.value*(brokenPitch?2:1); if (newFreq>=destFreq) { newFreq=destFreq; return2=true; } } else { - newFreq=chan[c.chan].baseFreq-c.value; + newFreq=chan[c.chan].baseFreq-c.value*(brokenPitch?2:1); if (newFreq<=destFreq) { newFreq=destFreq; return2=true; @@ -932,7 +932,9 @@ void DivPlatformArcade::setFlags(const DivConfig& flags) { } CHECK_CUSTOM_CLOCK; - baseFreqOff=round(768.0*(log((COLOR_NTSC/(double)chipClock))/log(2.0))); + baseFreqOff=round(1536.0*(log((COLOR_NTSC/(double)chipClock))/log(2.0))); + + brokenPitch=flags.getBool("brokenPitch",false); rate=chipClock/64; for (int i=0; i<8; i++) { diff --git a/src/engine/platform/fmshared_OPM.h b/src/engine/platform/fmshared_OPM.h index e922e8abb..2002db333 100644 --- a/src/engine/platform/fmshared_OPM.h +++ b/src/engine/platform/fmshared_OPM.h @@ -22,7 +22,7 @@ #include "fmsharedbase.h" -#define NOTE_LINEAR(x) (((x)<<6)+baseFreqOff+log2(parent->song.tuning/440.0)*12.0*64.0) +#define NOTE_LINEAR(x) (((x)<<7)+baseFreqOff+log2(parent->song.tuning/440.0)*12.0*128.0) class DivPlatformOPM: public DivPlatformFMBase { protected: @@ -42,13 +42,15 @@ class DivPlatformOPM: public DivPlatformFMBase { }; unsigned char lfoValue, lfoValue2, lfoShape, lfoShape2; + bool brokenPitch; DivPlatformOPM(): DivPlatformFMBase(), lfoValue(0), lfoValue2(0), lfoShape(0), - lfoShape2(0) {} + lfoShape2(0), + brokenPitch(false) {} }; #endif diff --git a/src/engine/platform/tx81z.cpp b/src/engine/platform/tx81z.cpp index a8f3a2f46..f677429ff 100644 --- a/src/engine/platform/tx81z.cpp +++ b/src/engine/platform/tx81z.cpp @@ -147,10 +147,10 @@ void DivPlatformTX81Z::tick(bool sysTick) { if (chan[i].std.pitch.had) { if (chan[i].std.pitch.mode) { - chan[i].pitch2+=chan[i].std.pitch.val; + chan[i].pitch2+=chan[i].std.pitch.val*(brokenPitch?2:1); CLAMP_VAR(chan[i].pitch2,-32768,32767); } else { - chan[i].pitch2=chan[i].std.pitch.val; + chan[i].pitch2=chan[i].std.pitch.val*(brokenPitch?2:1); } chan[i].freqChanged=true; } @@ -337,18 +337,18 @@ void DivPlatformTX81Z::tick(bool sysTick) { for (int i=0; i<8; i++) { if (chan[i].freqChanged) { - chan[i].freq=chan[i].baseFreq+(chan[i].pitch>>1)-64+chan[i].pitch2; + chan[i].freq=chan[i].baseFreq+chan[i].pitch-128+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; } else { - chan[i].freq+=chan[i].arpOff<<6; + chan[i].freq+=chan[i].arpOff<<7; } } if (chan[i].freq<0) chan[i].freq=0; - if (chan[i].freq>=(95<<6)) chan[i].freq=(95<<6)-1; - immWrite(i+0x28,hScale(chan[i].freq>>6)); - immWrite(i+0x30,(chan[i].freq<<2)|(chan[i].chVolL==chan[i].chVolR)); + if (chan[i].freq>=(95<<7)) chan[i].freq=(95<<7)-1; + immWrite(i+0x28,hScale(chan[i].freq>>7)); + immWrite(i+0x30,((chan[i].freq<<1)&0xfc)|(chan[i].chVolL==chan[i].chVolR)); hardResetElapsed+=2; chan[i].freqChanged=false; } @@ -523,13 +523,13 @@ int DivPlatformTX81Z::dispatch(DivCommand c) { int newFreq; bool return2=false; if (destFreq>chan[c.chan].baseFreq) { - newFreq=chan[c.chan].baseFreq+c.value; + newFreq=chan[c.chan].baseFreq+c.value*(brokenPitch?2:1); if (newFreq>=destFreq) { newFreq=destFreq; return2=true; } } else { - newFreq=chan[c.chan].baseFreq-c.value; + newFreq=chan[c.chan].baseFreq-c.value*(brokenPitch?2:1); if (newFreq<=destFreq) { newFreq=destFreq; return2=true; @@ -1043,7 +1043,9 @@ void DivPlatformTX81Z::setFlags(const DivConfig& flags) { } CHECK_CUSTOM_CLOCK; - baseFreqOff=round(768.0*(log((COLOR_NTSC/(double)chipClock))/log(2.0))); + baseFreqOff=round(1536.0*(log((COLOR_NTSC/(double)chipClock))/log(2.0))); + + brokenPitch=flags.getBool("brokenPitch",false); rate=chipClock/64; for (int i=0; i<8; i++) { diff --git a/src/gui/sysConf.cpp b/src/gui/sysConf.cpp index a247650cd..10a6c76e5 100644 --- a/src/gui/sysConf.cpp +++ b/src/gui/sysConf.cpp @@ -461,6 +461,7 @@ bool FurnaceGUI::drawSysConf(int chan, int sysPos, DivSystem type, DivConfig& fl } case DIV_SYSTEM_YM2151: { int clockSel=flags.getInt("clockSel",0); + bool brokenPitch=flags.getBool("brokenPitch",false); ImGui::Indent(); if (ImGui::RadioButton("NTSC/X16 (3.58MHz)",clockSel==0)) { @@ -477,9 +478,34 @@ bool FurnaceGUI::drawSysConf(int chan, int sysPos, DivSystem type, DivConfig& fl } ImGui::Unindent(); + if (ImGui::Checkbox("Broken pitch macro/slides (compatibility)",&brokenPitch)) { + altered=true; + } + if (altered) { e->lockSave([&]() { flags.set("clockSel",clockSel); + flags.set("brokenPitch",brokenPitch); + }); + } + break; + } + case DIV_SYSTEM_OPZ: { + bool clockSel=flags.getInt("clockSel",0); + bool brokenPitch=flags.getBool("brokenPitch",false); + + if (ImGui::Checkbox("Pseudo-PAL",&clockSel)) { + altered=true; + } + + if (ImGui::Checkbox("Broken pitch macro/slides (compatibility)",&brokenPitch)) { + altered=true; + } + + if (altered) { + e->lockSave([&]() { + flags.set("clockSel",(int)clockSel); + flags.set("brokenPitch",brokenPitch); }); } break;