From 6a027549961000572c91ce2810478e39935f0564 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Wed, 8 Dec 2021 01:56:40 -0500 Subject: [PATCH] add PAL flag to dispatch now platforms run at their correct clock speed when in PAL mode also fix clipping in Genesis --- src/engine/dispatch.h | 2 +- src/engine/engine.cpp | 2 +- src/engine/platform/abstract.cpp | 2 +- src/engine/platform/c64.cpp | 8 ++++++-- src/engine/platform/c64.h | 2 +- src/engine/platform/dummy.cpp | 2 +- src/engine/platform/dummy.h | 2 +- src/engine/platform/gb.cpp | 2 +- src/engine/platform/gb.h | 2 +- src/engine/platform/genesis.cpp | 24 ++++++++++++++++++------ src/engine/platform/genesis.h | 2 +- src/engine/platform/genesisext.cpp | 4 ++-- src/engine/platform/genesisext.h | 2 +- src/engine/platform/nes.cpp | 23 +++++++++++++++-------- src/engine/platform/nes.h | 4 +++- src/engine/platform/pce.cpp | 8 ++++++-- src/engine/platform/pce.h | 2 +- src/engine/platform/sms.cpp | 10 +++++++--- src/engine/platform/sms.h | 2 +- 19 files changed, 69 insertions(+), 36 deletions(-) diff --git a/src/engine/dispatch.h b/src/engine/dispatch.h index 528dcebc..27e88ba0 100644 --- a/src/engine/dispatch.h +++ b/src/engine/dispatch.h @@ -108,6 +108,6 @@ class DivDispatch { * @param sugRate the suggested rate. this may change, so don't rely on it. * @return the number of channels allocated. */ - virtual int init(DivEngine* parent, int channels, int sugRate); + virtual int init(DivEngine* parent, int channels, int sugRate, bool pal); }; #endif diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index de4a6ea4..52ffaa64 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -801,7 +801,7 @@ bool DivEngine::init(String outName) { dispatch=new DivPlatformDummy; break; } - dispatch->init(this,getChannelCount(song.system),got.rate); + dispatch->init(this,getChannelCount(song.system),got.rate,(!song.pal) || (song.customTempo!=0 && song.hz<53)); blip_set_rates(bb[0],dispatch->rate,got.rate); blip_set_rates(bb[1],dispatch->rate,got.rate); diff --git a/src/engine/platform/abstract.cpp b/src/engine/platform/abstract.cpp index 48332e53..ceef77b3 100644 --- a/src/engine/platform/abstract.cpp +++ b/src/engine/platform/abstract.cpp @@ -18,6 +18,6 @@ bool DivDispatch::keyOffAffectsArp(int ch) { return false; } -int DivDispatch::init(DivEngine* p, int channels, int sugRate) { +int DivDispatch::init(DivEngine* p, int channels, int sugRate, bool pal) { return 0; } diff --git a/src/engine/platform/c64.cpp b/src/engine/platform/c64.cpp index 458c28fd..99e600f4 100644 --- a/src/engine/platform/c64.cpp +++ b/src/engine/platform/c64.cpp @@ -287,9 +287,13 @@ void DivPlatformC64::setChipModel(bool is6581) { } } -int DivPlatformC64::init(DivEngine* p, int channels, int sugRate) { +int DivPlatformC64::init(DivEngine* p, int channels, int sugRate, bool pal) { parent=p; - rate=985248; + if (pal) { + rate=985248; + } else { + rate=1022727; + } sid.reset(); diff --git a/src/engine/platform/c64.h b/src/engine/platform/c64.h index ac939263..cd9f17ed 100644 --- a/src/engine/platform/c64.h +++ b/src/engine/platform/c64.h @@ -56,7 +56,7 @@ class DivPlatformC64: public DivDispatch { void acquire(short* bufL, short* bufR, size_t start, size_t len); int dispatch(DivCommand c); void tick(); - int init(DivEngine* parent, int channels, int sugRate); + int init(DivEngine* parent, int channels, int sugRate, bool pal); void setChipModel(bool is6581); }; diff --git a/src/engine/platform/dummy.cpp b/src/engine/platform/dummy.cpp index 9e161b9a..0cdaf2f1 100644 --- a/src/engine/platform/dummy.cpp +++ b/src/engine/platform/dummy.cpp @@ -61,7 +61,7 @@ int DivPlatformDummy::dispatch(DivCommand c) { return 1; } -int DivPlatformDummy::init(DivEngine* p, int channels, int sugRate) { +int DivPlatformDummy::init(DivEngine* p, int channels, int sugRate, bool pal) { parent=p; rate=65536; chans=channels; diff --git a/src/engine/platform/dummy.h b/src/engine/platform/dummy.h index 626a502d..c51afc29 100644 --- a/src/engine/platform/dummy.h +++ b/src/engine/platform/dummy.h @@ -18,5 +18,5 @@ class DivPlatformDummy: public DivDispatch { void acquire(short* bufL, short* bufR, size_t start, size_t len); int dispatch(DivCommand c); void tick(); - int init(DivEngine* parent, int channels, int sugRate); + int init(DivEngine* parent, int channels, int sugRate, bool pal); }; diff --git a/src/engine/platform/gb.cpp b/src/engine/platform/gb.cpp index a0f1349e..f77cbe3a 100644 --- a/src/engine/platform/gb.cpp +++ b/src/engine/platform/gb.cpp @@ -274,7 +274,7 @@ bool DivPlatformGB::isStereo() { return true; } -int DivPlatformGB::init(DivEngine* p, int channels, int sugRate) { +int DivPlatformGB::init(DivEngine* p, int channels, int sugRate, bool pal) { parent=p; rate=262144; gb=new GB_gameboy_t; diff --git a/src/engine/platform/gb.h b/src/engine/platform/gb.h index aab8fe48..a8e3c1da 100644 --- a/src/engine/platform/gb.h +++ b/src/engine/platform/gb.h @@ -40,7 +40,7 @@ class DivPlatformGB: public DivDispatch { int dispatch(DivCommand c); void tick(); bool isStereo(); - int init(DivEngine* parent, int channels, int sugRate); + int init(DivEngine* parent, int channels, int sugRate, bool pal); }; #endif diff --git a/src/engine/platform/genesis.cpp b/src/engine/platform/genesis.cpp index cabdf9c0..e6c01ef8 100644 --- a/src/engine/platform/genesis.cpp +++ b/src/engine/platform/genesis.cpp @@ -57,14 +57,22 @@ void DivPlatformGenesis::acquire(short* bufL, short* bufR, size_t start, size_t //OPN2_Write(&fm,0,0); } - psgClocks+=223722; + psgClocks+=psg.rate; while (psgClocks>=rate) { psgOut=(psg.acquireOne()*3)>>3; psgClocks-=rate; } + + os[0]=(os[0]<<5)+psgOut; + if (os[0]<-32768) os[0]=-32768; + if (os[0]>32767) os[0]=32767; + + os[1]=(os[1]<<5)+psgOut; + if (os[1]<-32768) os[1]=-32768; + if (os[1]>32767) os[1]=32767; - bufL[h]=(os[0]<<5)+psgOut; - bufR[h]=(os[1]<<5)+psgOut; + bufL[h]=os[0]; + bufR[h]=os[1]; } } @@ -348,9 +356,13 @@ bool DivPlatformGenesis::keyOffAffectsArp(int ch) { return (ch>5); } -int DivPlatformGenesis::init(DivEngine* p, int channels, int sugRate) { +int DivPlatformGenesis::init(DivEngine* p, int channels, int sugRate, bool pal) { parent=p; - rate=213068; + if (pal) { + rate=211125; + } else { + rate=213068; + } OPN2_Reset(&fm); for (int i=0; i<10; i++) { chan[i].vol=0x7f; @@ -376,7 +388,7 @@ int DivPlatformGenesis::init(DivEngine* p, int channels, int sugRate) { delay=0; // PSG - psg.init(p,4,sugRate); + psg.init(p,4,sugRate,pal); psgClocks=0; psgOut=0; return 10; diff --git a/src/engine/platform/genesis.h b/src/engine/platform/genesis.h index 29af32e7..786fedc2 100644 --- a/src/engine/platform/genesis.h +++ b/src/engine/platform/genesis.h @@ -53,6 +53,6 @@ class DivPlatformGenesis: public DivDispatch { void tick(); bool isStereo(); bool keyOffAffectsArp(int ch); - int init(DivEngine* parent, int channels, int sugRate); + int init(DivEngine* parent, int channels, int sugRate, bool pal); }; #endif diff --git a/src/engine/platform/genesisext.cpp b/src/engine/platform/genesisext.cpp index dfe26777..e5a4a969 100644 --- a/src/engine/platform/genesisext.cpp +++ b/src/engine/platform/genesisext.cpp @@ -258,8 +258,8 @@ bool DivPlatformGenesisExt::keyOffAffectsArp(int ch) { return (ch>8); } -int DivPlatformGenesisExt::init(DivEngine* parent, int channels, int sugRate) { - DivPlatformGenesis::init(parent,channels,sugRate); +int DivPlatformGenesisExt::init(DivEngine* parent, int channels, int sugRate, bool pal) { + DivPlatformGenesis::init(parent,channels,sugRate,pal); for (int i=0; i<4; i++) { opChan[i].vol=127; diff --git a/src/engine/platform/genesisext.h b/src/engine/platform/genesisext.h index 1ce6264d..538a5c8e 100644 --- a/src/engine/platform/genesisext.h +++ b/src/engine/platform/genesisext.h @@ -18,5 +18,5 @@ class DivPlatformGenesisExt: public DivPlatformGenesis { int dispatch(DivCommand c); void tick(); bool keyOffAffectsArp(int ch); - int init(DivEngine* parent, int channels, int sugRate); + int init(DivEngine* parent, int channels, int sugRate, bool pal); }; diff --git a/src/engine/platform/nes.cpp b/src/engine/platform/nes.cpp index a2cb58ab..91781068 100644 --- a/src/engine/platform/nes.cpp +++ b/src/engine/platform/nes.cpp @@ -4,6 +4,7 @@ #include #define FREQ_BASE 3424.0f +#define FREQ_BASE_PAL 3180.0f void DivPlatformNES::acquire(short* bufL, short* bufR, size_t start, size_t len) { for (size_t i=start; ichan[c.chan].baseFreq) { chan[c.chan].baseFreq+=c.value; @@ -252,7 +253,7 @@ int DivPlatformNES::dispatch(DivCommand c) { } case DIV_CMD_LEGATO: if (c.chan==3) break; - chan[c.chan].baseFreq=round(FREQ_BASE/pow(2.0f,((float)(c.value+((chan[c.chan].std.willArp && !chan[c.chan].std.arpMode)?(chan[c.chan].std.arp-12):(0)))/12.0f))); + chan[c.chan].baseFreq=round(freqBase/pow(2.0f,((float)(c.value+((chan[c.chan].std.willArp && !chan[c.chan].std.arpMode)?(chan[c.chan].std.arp-12):(0)))/12.0f))); chan[c.chan].freqChanged=true; chan[c.chan].note=c.value; break; @@ -276,9 +277,15 @@ bool DivPlatformNES::keyOffAffectsArp(int ch) { return true; } -int DivPlatformNES::init(DivEngine* p, int channels, int sugRate) { +int DivPlatformNES::init(DivEngine* p, int channels, int sugRate, bool pal) { parent=p; - rate=1789773; + if (pal) { + rate=1662607; + freqBase=FREQ_BASE_PAL; + } else { + rate=1789773; + freqBase=FREQ_BASE; + } dacPeriod=0; dacPos=0; diff --git a/src/engine/platform/nes.h b/src/engine/platform/nes.h index 5d61b9b8..9c6f5782 100644 --- a/src/engine/platform/nes.h +++ b/src/engine/platform/nes.h @@ -35,13 +35,15 @@ class DivPlatformNES: public DivDispatch { int dacPeriod, dacRate, dacPos, dacSample; unsigned char lastPan; + float freqBase; + void updateWave(); public: void acquire(short* bufL, short* bufR, size_t start, size_t len); int dispatch(DivCommand c); void tick(); bool keyOffAffectsArp(int ch); - int init(DivEngine* parent, int channels, int sugRate); + int init(DivEngine* parent, int channels, int sugRate, bool pal); }; #endif diff --git a/src/engine/platform/pce.cpp b/src/engine/platform/pce.cpp index f0a07ce2..3723ab2e 100644 --- a/src/engine/platform/pce.cpp +++ b/src/engine/platform/pce.cpp @@ -264,9 +264,13 @@ bool DivPlatformPCE::keyOffAffectsArp(int ch) { } -int DivPlatformPCE::init(DivEngine* p, int channels, int sugRate) { +int DivPlatformPCE::init(DivEngine* p, int channels, int sugRate, bool pal) { parent=p; - rate=1789773; + if (pal) { // technically there is no PAL PC Engine but oh well... + rate=1773448; + } else { + rate=1789773; + } pce=new PCE_PSG(&tempL,&tempR,PCE_PSG::REVISION_HUC6280); lastPan=0xff; tempL=0; diff --git a/src/engine/platform/pce.h b/src/engine/platform/pce.h index f9ab3bb5..dc45449b 100644 --- a/src/engine/platform/pce.h +++ b/src/engine/platform/pce.h @@ -55,7 +55,7 @@ class DivPlatformPCE: public DivDispatch { void tick(); bool isStereo(); bool keyOffAffectsArp(int ch); - int init(DivEngine* parent, int channels, int sugRate); + int init(DivEngine* parent, int channels, int sugRate, bool pal); }; #endif diff --git a/src/engine/platform/sms.cpp b/src/engine/platform/sms.cpp index 5d69a78b..20092bfe 100644 --- a/src/engine/platform/sms.cpp +++ b/src/engine/platform/sms.cpp @@ -163,10 +163,14 @@ bool DivPlatformSMS::keyOffAffectsArp(int ch) { return true; } -int DivPlatformSMS::init(DivEngine* p, int channels, int sugRate) { +int DivPlatformSMS::init(DivEngine* p, int channels, int sugRate, bool pal) { parent=p; - rate=223722; - sn=new sn76496_device(223722); + if (pal) { + rate=221681; + } else { + rate=223722; + } + sn=new sn76496_device(rate); sn->device_start(); snNoiseMode=3; updateSNMode=false; diff --git a/src/engine/platform/sms.h b/src/engine/platform/sms.h index 85af8dbf..e468dd07 100644 --- a/src/engine/platform/sms.h +++ b/src/engine/platform/sms.h @@ -36,7 +36,7 @@ class DivPlatformSMS: public DivDispatch { int dispatch(DivCommand c); void tick(); bool keyOffAffectsArp(int ch); - int init(DivEngine* parent, int channels, int sugRate); + int init(DivEngine* parent, int channels, int sugRate, bool pal); }; #endif