mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-23 13:05:11 +00:00
dev176 - OPM/OPZ: fix pitch
This commit is contained in:
parent
8fe3811233
commit
658f69bc4e
6 changed files with 73 additions and 26 deletions
|
@ -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
|
||||
|
|
|
@ -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<ds.systemLen; i++) {
|
||||
if (ds.system[i]==DIV_SYSTEM_YM2151 ||
|
||||
ds.system[i]==DIV_SYSTEM_OPZ) {
|
||||
ds.systemFlags[i].set("brokenPitch",true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (active) quitDispatch();
|
||||
BUSY_BEGIN_SOFT;
|
||||
saveLock.lock();
|
||||
|
|
|
@ -197,10 +197,10 @@ void DivPlatformArcade::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;
|
||||
}
|
||||
|
@ -354,18 +354,18 @@ void DivPlatformArcade::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);
|
||||
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++) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue