From 62289d924eb5ed9dfcf1178cbc44edbe4b40bbdd Mon Sep 17 00:00:00 2001 From: tildearrow Date: Mon, 2 May 2022 16:53:55 -0500 Subject: [PATCH] FDS: add NSFPlay core --- src/engine/dispatchContainer.cpp | 1 + src/engine/platform/fds.cpp | 65 +++++++++++++++++-- src/engine/platform/fds.h | 9 +++ .../platform/sound/nes_nsfplay/nes_fds.cpp | 2 + src/gui/gui.h | 2 + src/gui/settings.cpp | 7 ++ 6 files changed, 80 insertions(+), 6 deletions(-) diff --git a/src/engine/dispatchContainer.cpp b/src/engine/dispatchContainer.cpp index 187523c72..f44ed0d5c 100644 --- a/src/engine/dispatchContainer.cpp +++ b/src/engine/dispatchContainer.cpp @@ -228,6 +228,7 @@ void DivDispatchContainer::init(DivSystem sys, DivEngine* eng, int chanCount, do break; case DIV_SYSTEM_FDS: dispatch=new DivPlatformFDS; + ((DivPlatformFDS*)dispatch)->setNSFPlay(eng->getConfInt("fdsCore",0)==1); break; case DIV_SYSTEM_TIA: dispatch=new DivPlatformTIA; diff --git a/src/engine/platform/fds.cpp b/src/engine/platform/fds.cpp index 4c8e92b38..f3908148d 100644 --- a/src/engine/platform/fds.cpp +++ b/src/engine/platform/fds.cpp @@ -20,11 +20,12 @@ #include "fds.h" #include "sound/nes/cpu_inline.h" #include "../engine.h" +#include "sound/nes_nsfplay/nes_fds.h" #include #define CHIP_FREQBASE 262144 -#define rWrite(a,v) if (!skipRegisterWrites) {fds_wr_mem(fds,a,v); regPool[(a)&0x7f]=v; if (dumpWrites) {addWrite(a,v);} } +#define rWrite(a,v) if (!skipRegisterWrites) {doWrite(a,v); regPool[(a)&0x7f]=v; if (dumpWrites) {addWrite(a,v);} } const char* regCheatSheetFDS[]={ "IOCtrl", "4023", @@ -78,7 +79,7 @@ const char* DivPlatformFDS::getEffectName(unsigned char effect) { return NULL; } -void DivPlatformFDS::acquire(short* bufL, short* bufR, size_t start, size_t len) { +void DivPlatformFDS::acquire_puNES(short* bufL, short* bufR, size_t start, size_t len) { for (size_t i=start; isnd.main.output; @@ -92,6 +93,38 @@ void DivPlatformFDS::acquire(short* bufL, short* bufR, size_t start, size_t len) } } +void DivPlatformFDS::acquire_NSFPlay(short* bufL, short* bufR, size_t start, size_t len) { + int out[2]; + for (size_t i=start; iTick(1); + fds_NP->Render(out); + int sample=isMuted[0]?0:(out[0]<<1); + if (sample>32767) sample=32767; + if (sample<-32768) sample=-32768; + bufL[i]=sample; + if (++writeOscBuf>=32) { + writeOscBuf=0; + oscBuf->data[oscBuf->needle++]=sample<<1; + } + } +} + +void DivPlatformFDS::doWrite(unsigned short addr, unsigned char data) { + if (useNP) { + fds_NP->Write(addr,data); + } else { + fds_wr_mem(fds,addr,data); + } +} + +void DivPlatformFDS::acquire(short* bufL, short* bufR, size_t start, size_t len) { + if (useNP) { + acquire_NSFPlay(bufL,bufR,start,len); + } else { + acquire_puNES(bufL,bufR,start,len); + } +} + void DivPlatformFDS::updateWave() { // TODO: master volume rWrite(0x4089,0x80); @@ -423,7 +456,11 @@ void DivPlatformFDS::reset() { addWrite(0xffffffff,0); } - fds_reset(fds); + if (useNP) { + fds_NP->Reset(); + } else { + fds_reset(fds); + } memset(regPool,0,128); rWrite(0x4023,0); @@ -435,6 +472,10 @@ bool DivPlatformFDS::keyOffAffectsArp(int ch) { return true; } +void DivPlatformFDS::setNSFPlay(bool use) { + useNP=use; +} + void DivPlatformFDS::setFlags(unsigned int flags) { if (flags==2) { // Dendy rate=COLOR_PAL*2.0/5.0; @@ -445,6 +486,10 @@ void DivPlatformFDS::setFlags(unsigned int flags) { } chipClock=rate; oscBuf->rate=rate/32; + if (useNP) { + fds_NP->SetClock(rate); + fds_NP->SetRate(rate); + } } void DivPlatformFDS::notifyInsDeletion(void* ins) { @@ -467,7 +512,11 @@ int DivPlatformFDS::init(DivEngine* p, int channels, int sugRate, unsigned int f dumpWrites=false; skipRegisterWrites=false; writeOscBuf=0; - fds=new struct _fds; + if (useNP) { + fds_NP=new xgm::NES_FDS; + } else { + fds=new struct _fds; + } oscBuf=new DivDispatchOscBuffer; for (int i=0; i<1; i++) { isMuted[i]=false; @@ -475,12 +524,16 @@ int DivPlatformFDS::init(DivEngine* p, int channels, int sugRate, unsigned int f setFlags(flags); reset(); - return 5; + return 1; } void DivPlatformFDS::quit() { delete oscBuf; - delete fds; + if (useNP) { + delete fds_NP; + } else { + delete fds; + } } DivPlatformFDS::~DivPlatformFDS() { diff --git a/src/engine/platform/fds.h b/src/engine/platform/fds.h index c7c53aea2..1c08e1bbb 100644 --- a/src/engine/platform/fds.h +++ b/src/engine/platform/fds.h @@ -24,6 +24,8 @@ #include "../macroInt.h" #include "../waveSynth.h" +#include "sound/nes_nsfplay/nes_fds.h" + class DivPlatformFDS: public DivDispatch { struct Channel { int freq, baseFreq, pitch, pitch2, prevFreq, note, modFreq, ins; @@ -69,13 +71,19 @@ class DivPlatformFDS: public DivDispatch { DivWaveSynth ws; unsigned char apuType; unsigned char writeOscBuf; + bool useNP; struct _fds* fds; + xgm::NES_FDS* fds_NP; unsigned char regPool[128]; void updateWave(); friend void putDispatchChan(void*,int,int); + void doWrite(unsigned short addr, unsigned char data); + void acquire_puNES(short* bufL, short* bufR, size_t start, size_t len); + void acquire_NSFPlay(short* bufL, short* bufR, size_t start, size_t len); + public: void acquire(short* bufL, short* bufR, size_t start, size_t len); int dispatch(DivCommand c); @@ -88,6 +96,7 @@ class DivPlatformFDS: public DivDispatch { void tick(bool sysTick=true); void muteChannel(int ch, bool mute); bool keyOffAffectsArp(int ch); + void setNSFPlay(bool use); void setFlags(unsigned int flags); void notifyInsDeletion(void* ins); void poke(unsigned int addr, unsigned short val); diff --git a/src/engine/platform/sound/nes_nsfplay/nes_fds.cpp b/src/engine/platform/sound/nes_nsfplay/nes_fds.cpp index f3e61decc..7599fa857 100644 --- a/src/engine/platform/sound/nes_nsfplay/nes_fds.cpp +++ b/src/engine/platform/sound/nes_nsfplay/nes_fds.cpp @@ -21,6 +21,8 @@ NES_FDS::NES_FDS () sm[0] = 128; sm[1] = 128; + mask=0; + Reset(); } diff --git a/src/gui/gui.h b/src/gui/gui.h index 49e56f0c2..90d909f2d 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -789,6 +789,7 @@ class FurnaceGUI { int ym2612Core; int saaCore; int nesCore; + int fdsCore; int mainFont; int patFont; int audioRate; @@ -872,6 +873,7 @@ class FurnaceGUI { ym2612Core(0), saaCore(1), nesCore(0), + fdsCore(0), mainFont(0), patFont(0), audioRate(44100), diff --git a/src/gui/settings.cpp b/src/gui/settings.cpp index 383fa4202..b515d6535 100644 --- a/src/gui/settings.cpp +++ b/src/gui/settings.cpp @@ -868,6 +868,10 @@ void FurnaceGUI::drawSettings() { ImGui::SameLine(); ImGui::Combo("##NESCore",&settings.nesCore,nesCores,2); + ImGui::Text("FDS core"); + ImGui::SameLine(); + ImGui::Combo("##FDSCore",&settings.fdsCore,nesCores,2); + ImGui::EndTabItem(); } if (ImGui::BeginTabItem("Appearance")) { @@ -1741,6 +1745,7 @@ void FurnaceGUI::syncSettings() { settings.ym2612Core=e->getConfInt("ym2612Core",0); settings.saaCore=e->getConfInt("saaCore",1); settings.nesCore=e->getConfInt("nesCore",0); + settings.fdsCore=e->getConfInt("fdsCore",0); settings.mainFont=e->getConfInt("mainFont",0); settings.patFont=e->getConfInt("patFont",0); settings.mainFontPath=e->getConfString("mainFontPath",""); @@ -1816,6 +1821,7 @@ void FurnaceGUI::syncSettings() { clampSetting(settings.ym2612Core,0,1); clampSetting(settings.saaCore,0,1); clampSetting(settings.nesCore,0,1); + clampSetting(settings.fdsCore,0,1); clampSetting(settings.mainFont,0,6); clampSetting(settings.patFont,0,6); clampSetting(settings.patRowsBase,0,1); @@ -1919,6 +1925,7 @@ void FurnaceGUI::commitSettings() { e->setConf("ym2612Core",settings.ym2612Core); e->setConf("saaCore",settings.saaCore); e->setConf("nesCore",settings.nesCore); + e->setConf("fdsCore",settings.fdsCore); e->setConf("mainFont",settings.mainFont); e->setConf("patFont",settings.patFont); e->setConf("mainFontPath",settings.mainFontPath);