mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-27 06:53:01 +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_UNSTABLE
|
||||||
|
|
||||||
#define DIV_VERSION "0.6pre14"
|
#define DIV_VERSION "dev176"
|
||||||
#define DIV_ENGINE_VERSION 175
|
#define DIV_ENGINE_VERSION 176
|
||||||
// for imports
|
// for imports
|
||||||
#define DIV_VERSION_MOD 0xff01
|
#define DIV_VERSION_MOD 0xff01
|
||||||
#define DIV_VERSION_FC 0xff02
|
#define DIV_VERSION_FC 0xff02
|
||||||
|
|
|
@ -1058,6 +1058,11 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||||
ds.systemFlags[0].set("keyPriority",false);
|
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));
|
ds.systemName=getSongSystemLegacyName(ds,!getConfInt("noMultiSystem",0));
|
||||||
|
|
||||||
if (active) quitDispatch();
|
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();
|
if (active) quitDispatch();
|
||||||
BUSY_BEGIN_SOFT;
|
BUSY_BEGIN_SOFT;
|
||||||
saveLock.lock();
|
saveLock.lock();
|
||||||
|
|
|
@ -197,10 +197,10 @@ void DivPlatformArcade::tick(bool sysTick) {
|
||||||
|
|
||||||
if (chan[i].std.pitch.had) {
|
if (chan[i].std.pitch.had) {
|
||||||
if (chan[i].std.pitch.mode) {
|
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);
|
CLAMP_VAR(chan[i].pitch2,-32768,32767);
|
||||||
} else {
|
} else {
|
||||||
chan[i].pitch2=chan[i].std.pitch.val;
|
chan[i].pitch2=chan[i].std.pitch.val*(brokenPitch?2:1);
|
||||||
}
|
}
|
||||||
chan[i].freqChanged=true;
|
chan[i].freqChanged=true;
|
||||||
}
|
}
|
||||||
|
@ -354,18 +354,18 @@ void DivPlatformArcade::tick(bool sysTick) {
|
||||||
|
|
||||||
for (int i=0; i<8; i++) {
|
for (int i=0; i<8; i++) {
|
||||||
if (chan[i].freqChanged) {
|
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 (!parent->song.oldArpStrategy) {
|
||||||
if (chan[i].fixedArp) {
|
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 {
|
} 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<0) chan[i].freq=0;
|
||||||
if (chan[i].freq>=(95<<6)) chan[i].freq=(95<<6)-1;
|
if (chan[i].freq>=(95<<7)) chan[i].freq=(95<<7)-1;
|
||||||
immWrite(i+0x28,hScale(chan[i].freq>>6));
|
immWrite(i+0x28,hScale(chan[i].freq>>7));
|
||||||
immWrite(i+0x30,chan[i].freq<<2);
|
immWrite(i+0x30,((chan[i].freq<<1)&0xfc));
|
||||||
hardResetElapsed+=2;
|
hardResetElapsed+=2;
|
||||||
chan[i].freqChanged=false;
|
chan[i].freqChanged=false;
|
||||||
}
|
}
|
||||||
|
@ -534,13 +534,13 @@ int DivPlatformArcade::dispatch(DivCommand c) {
|
||||||
int newFreq;
|
int newFreq;
|
||||||
bool return2=false;
|
bool return2=false;
|
||||||
if (destFreq>chan[c.chan].baseFreq) {
|
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) {
|
if (newFreq>=destFreq) {
|
||||||
newFreq=destFreq;
|
newFreq=destFreq;
|
||||||
return2=true;
|
return2=true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
newFreq=chan[c.chan].baseFreq-c.value;
|
newFreq=chan[c.chan].baseFreq-c.value*(brokenPitch?2:1);
|
||||||
if (newFreq<=destFreq) {
|
if (newFreq<=destFreq) {
|
||||||
newFreq=destFreq;
|
newFreq=destFreq;
|
||||||
return2=true;
|
return2=true;
|
||||||
|
@ -932,7 +932,9 @@ void DivPlatformArcade::setFlags(const DivConfig& flags) {
|
||||||
}
|
}
|
||||||
CHECK_CUSTOM_CLOCK;
|
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;
|
rate=chipClock/64;
|
||||||
for (int i=0; i<8; i++) {
|
for (int i=0; i<8; i++) {
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
#include "fmsharedbase.h"
|
#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 {
|
class DivPlatformOPM: public DivPlatformFMBase {
|
||||||
protected:
|
protected:
|
||||||
|
@ -42,13 +42,15 @@ class DivPlatformOPM: public DivPlatformFMBase {
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned char lfoValue, lfoValue2, lfoShape, lfoShape2;
|
unsigned char lfoValue, lfoValue2, lfoShape, lfoShape2;
|
||||||
|
bool brokenPitch;
|
||||||
|
|
||||||
DivPlatformOPM():
|
DivPlatformOPM():
|
||||||
DivPlatformFMBase(),
|
DivPlatformFMBase(),
|
||||||
lfoValue(0),
|
lfoValue(0),
|
||||||
lfoValue2(0),
|
lfoValue2(0),
|
||||||
lfoShape(0),
|
lfoShape(0),
|
||||||
lfoShape2(0) {}
|
lfoShape2(0),
|
||||||
|
brokenPitch(false) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -147,10 +147,10 @@ void DivPlatformTX81Z::tick(bool sysTick) {
|
||||||
|
|
||||||
if (chan[i].std.pitch.had) {
|
if (chan[i].std.pitch.had) {
|
||||||
if (chan[i].std.pitch.mode) {
|
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);
|
CLAMP_VAR(chan[i].pitch2,-32768,32767);
|
||||||
} else {
|
} else {
|
||||||
chan[i].pitch2=chan[i].std.pitch.val;
|
chan[i].pitch2=chan[i].std.pitch.val*(brokenPitch?2:1);
|
||||||
}
|
}
|
||||||
chan[i].freqChanged=true;
|
chan[i].freqChanged=true;
|
||||||
}
|
}
|
||||||
|
@ -337,18 +337,18 @@ void DivPlatformTX81Z::tick(bool sysTick) {
|
||||||
|
|
||||||
for (int i=0; i<8; i++) {
|
for (int i=0; i<8; i++) {
|
||||||
if (chan[i].freqChanged) {
|
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 (!parent->song.oldArpStrategy) {
|
||||||
if (chan[i].fixedArp) {
|
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 {
|
} 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<0) chan[i].freq=0;
|
||||||
if (chan[i].freq>=(95<<6)) chan[i].freq=(95<<6)-1;
|
if (chan[i].freq>=(95<<7)) chan[i].freq=(95<<7)-1;
|
||||||
immWrite(i+0x28,hScale(chan[i].freq>>6));
|
immWrite(i+0x28,hScale(chan[i].freq>>7));
|
||||||
immWrite(i+0x30,(chan[i].freq<<2)|(chan[i].chVolL==chan[i].chVolR));
|
immWrite(i+0x30,((chan[i].freq<<1)&0xfc)|(chan[i].chVolL==chan[i].chVolR));
|
||||||
hardResetElapsed+=2;
|
hardResetElapsed+=2;
|
||||||
chan[i].freqChanged=false;
|
chan[i].freqChanged=false;
|
||||||
}
|
}
|
||||||
|
@ -523,13 +523,13 @@ int DivPlatformTX81Z::dispatch(DivCommand c) {
|
||||||
int newFreq;
|
int newFreq;
|
||||||
bool return2=false;
|
bool return2=false;
|
||||||
if (destFreq>chan[c.chan].baseFreq) {
|
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) {
|
if (newFreq>=destFreq) {
|
||||||
newFreq=destFreq;
|
newFreq=destFreq;
|
||||||
return2=true;
|
return2=true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
newFreq=chan[c.chan].baseFreq-c.value;
|
newFreq=chan[c.chan].baseFreq-c.value*(brokenPitch?2:1);
|
||||||
if (newFreq<=destFreq) {
|
if (newFreq<=destFreq) {
|
||||||
newFreq=destFreq;
|
newFreq=destFreq;
|
||||||
return2=true;
|
return2=true;
|
||||||
|
@ -1043,7 +1043,9 @@ void DivPlatformTX81Z::setFlags(const DivConfig& flags) {
|
||||||
}
|
}
|
||||||
CHECK_CUSTOM_CLOCK;
|
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;
|
rate=chipClock/64;
|
||||||
for (int i=0; i<8; i++) {
|
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: {
|
case DIV_SYSTEM_YM2151: {
|
||||||
int clockSel=flags.getInt("clockSel",0);
|
int clockSel=flags.getInt("clockSel",0);
|
||||||
|
bool brokenPitch=flags.getBool("brokenPitch",false);
|
||||||
|
|
||||||
ImGui::Indent();
|
ImGui::Indent();
|
||||||
if (ImGui::RadioButton("NTSC/X16 (3.58MHz)",clockSel==0)) {
|
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();
|
ImGui::Unindent();
|
||||||
|
|
||||||
|
if (ImGui::Checkbox("Broken pitch macro/slides (compatibility)",&brokenPitch)) {
|
||||||
|
altered=true;
|
||||||
|
}
|
||||||
|
|
||||||
if (altered) {
|
if (altered) {
|
||||||
e->lockSave([&]() {
|
e->lockSave([&]() {
|
||||||
flags.set("clockSel",clockSel);
|
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;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue