FDS: add NSFPlay core

This commit is contained in:
tildearrow 2022-05-02 16:53:55 -05:00
parent 960048cf4b
commit 62289d924e
6 changed files with 80 additions and 6 deletions

View file

@ -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;

View file

@ -20,11 +20,12 @@
#include "fds.h"
#include "sound/nes/cpu_inline.h"
#include "../engine.h"
#include "sound/nes_nsfplay/nes_fds.h"
#include <math.h>
#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; i<start+len; i++) {
extcl_apu_tick_FDS(fds);
int sample=isMuted[0]?0:fds->snd.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; i<start+len; i++) {
fds_NP->Tick(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() {

View file

@ -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);

View file

@ -21,6 +21,8 @@ NES_FDS::NES_FDS ()
sm[0] = 128;
sm[1] = 128;
mask=0;
Reset();
}

View file

@ -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),

View file

@ -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);