FDS: add NSFPlay core
This commit is contained in:
parent
960048cf4b
commit
62289d924e
|
@ -228,6 +228,7 @@ void DivDispatchContainer::init(DivSystem sys, DivEngine* eng, int chanCount, do
|
||||||
break;
|
break;
|
||||||
case DIV_SYSTEM_FDS:
|
case DIV_SYSTEM_FDS:
|
||||||
dispatch=new DivPlatformFDS;
|
dispatch=new DivPlatformFDS;
|
||||||
|
((DivPlatformFDS*)dispatch)->setNSFPlay(eng->getConfInt("fdsCore",0)==1);
|
||||||
break;
|
break;
|
||||||
case DIV_SYSTEM_TIA:
|
case DIV_SYSTEM_TIA:
|
||||||
dispatch=new DivPlatformTIA;
|
dispatch=new DivPlatformTIA;
|
||||||
|
|
|
@ -20,11 +20,12 @@
|
||||||
#include "fds.h"
|
#include "fds.h"
|
||||||
#include "sound/nes/cpu_inline.h"
|
#include "sound/nes/cpu_inline.h"
|
||||||
#include "../engine.h"
|
#include "../engine.h"
|
||||||
|
#include "sound/nes_nsfplay/nes_fds.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#define CHIP_FREQBASE 262144
|
#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[]={
|
const char* regCheatSheetFDS[]={
|
||||||
"IOCtrl", "4023",
|
"IOCtrl", "4023",
|
||||||
|
@ -78,7 +79,7 @@ const char* DivPlatformFDS::getEffectName(unsigned char effect) {
|
||||||
return NULL;
|
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++) {
|
for (size_t i=start; i<start+len; i++) {
|
||||||
extcl_apu_tick_FDS(fds);
|
extcl_apu_tick_FDS(fds);
|
||||||
int sample=isMuted[0]?0:fds->snd.main.output;
|
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() {
|
void DivPlatformFDS::updateWave() {
|
||||||
// TODO: master volume
|
// TODO: master volume
|
||||||
rWrite(0x4089,0x80);
|
rWrite(0x4089,0x80);
|
||||||
|
@ -423,7 +456,11 @@ void DivPlatformFDS::reset() {
|
||||||
addWrite(0xffffffff,0);
|
addWrite(0xffffffff,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (useNP) {
|
||||||
|
fds_NP->Reset();
|
||||||
|
} else {
|
||||||
fds_reset(fds);
|
fds_reset(fds);
|
||||||
|
}
|
||||||
memset(regPool,0,128);
|
memset(regPool,0,128);
|
||||||
|
|
||||||
rWrite(0x4023,0);
|
rWrite(0x4023,0);
|
||||||
|
@ -435,6 +472,10 @@ bool DivPlatformFDS::keyOffAffectsArp(int ch) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DivPlatformFDS::setNSFPlay(bool use) {
|
||||||
|
useNP=use;
|
||||||
|
}
|
||||||
|
|
||||||
void DivPlatformFDS::setFlags(unsigned int flags) {
|
void DivPlatformFDS::setFlags(unsigned int flags) {
|
||||||
if (flags==2) { // Dendy
|
if (flags==2) { // Dendy
|
||||||
rate=COLOR_PAL*2.0/5.0;
|
rate=COLOR_PAL*2.0/5.0;
|
||||||
|
@ -445,6 +486,10 @@ void DivPlatformFDS::setFlags(unsigned int flags) {
|
||||||
}
|
}
|
||||||
chipClock=rate;
|
chipClock=rate;
|
||||||
oscBuf->rate=rate/32;
|
oscBuf->rate=rate/32;
|
||||||
|
if (useNP) {
|
||||||
|
fds_NP->SetClock(rate);
|
||||||
|
fds_NP->SetRate(rate);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivPlatformFDS::notifyInsDeletion(void* ins) {
|
void DivPlatformFDS::notifyInsDeletion(void* ins) {
|
||||||
|
@ -467,7 +512,11 @@ int DivPlatformFDS::init(DivEngine* p, int channels, int sugRate, unsigned int f
|
||||||
dumpWrites=false;
|
dumpWrites=false;
|
||||||
skipRegisterWrites=false;
|
skipRegisterWrites=false;
|
||||||
writeOscBuf=0;
|
writeOscBuf=0;
|
||||||
|
if (useNP) {
|
||||||
|
fds_NP=new xgm::NES_FDS;
|
||||||
|
} else {
|
||||||
fds=new struct _fds;
|
fds=new struct _fds;
|
||||||
|
}
|
||||||
oscBuf=new DivDispatchOscBuffer;
|
oscBuf=new DivDispatchOscBuffer;
|
||||||
for (int i=0; i<1; i++) {
|
for (int i=0; i<1; i++) {
|
||||||
isMuted[i]=false;
|
isMuted[i]=false;
|
||||||
|
@ -475,12 +524,16 @@ int DivPlatformFDS::init(DivEngine* p, int channels, int sugRate, unsigned int f
|
||||||
setFlags(flags);
|
setFlags(flags);
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
return 5;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivPlatformFDS::quit() {
|
void DivPlatformFDS::quit() {
|
||||||
delete oscBuf;
|
delete oscBuf;
|
||||||
|
if (useNP) {
|
||||||
|
delete fds_NP;
|
||||||
|
} else {
|
||||||
delete fds;
|
delete fds;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DivPlatformFDS::~DivPlatformFDS() {
|
DivPlatformFDS::~DivPlatformFDS() {
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
#include "../macroInt.h"
|
#include "../macroInt.h"
|
||||||
#include "../waveSynth.h"
|
#include "../waveSynth.h"
|
||||||
|
|
||||||
|
#include "sound/nes_nsfplay/nes_fds.h"
|
||||||
|
|
||||||
class DivPlatformFDS: public DivDispatch {
|
class DivPlatformFDS: public DivDispatch {
|
||||||
struct Channel {
|
struct Channel {
|
||||||
int freq, baseFreq, pitch, pitch2, prevFreq, note, modFreq, ins;
|
int freq, baseFreq, pitch, pitch2, prevFreq, note, modFreq, ins;
|
||||||
|
@ -69,13 +71,19 @@ class DivPlatformFDS: public DivDispatch {
|
||||||
DivWaveSynth ws;
|
DivWaveSynth ws;
|
||||||
unsigned char apuType;
|
unsigned char apuType;
|
||||||
unsigned char writeOscBuf;
|
unsigned char writeOscBuf;
|
||||||
|
bool useNP;
|
||||||
struct _fds* fds;
|
struct _fds* fds;
|
||||||
|
xgm::NES_FDS* fds_NP;
|
||||||
unsigned char regPool[128];
|
unsigned char regPool[128];
|
||||||
|
|
||||||
void updateWave();
|
void updateWave();
|
||||||
|
|
||||||
friend void putDispatchChan(void*,int,int);
|
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:
|
public:
|
||||||
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||||
int dispatch(DivCommand c);
|
int dispatch(DivCommand c);
|
||||||
|
@ -88,6 +96,7 @@ class DivPlatformFDS: public DivDispatch {
|
||||||
void tick(bool sysTick=true);
|
void tick(bool sysTick=true);
|
||||||
void muteChannel(int ch, bool mute);
|
void muteChannel(int ch, bool mute);
|
||||||
bool keyOffAffectsArp(int ch);
|
bool keyOffAffectsArp(int ch);
|
||||||
|
void setNSFPlay(bool use);
|
||||||
void setFlags(unsigned int flags);
|
void setFlags(unsigned int flags);
|
||||||
void notifyInsDeletion(void* ins);
|
void notifyInsDeletion(void* ins);
|
||||||
void poke(unsigned int addr, unsigned short val);
|
void poke(unsigned int addr, unsigned short val);
|
||||||
|
|
|
@ -21,6 +21,8 @@ NES_FDS::NES_FDS ()
|
||||||
sm[0] = 128;
|
sm[0] = 128;
|
||||||
sm[1] = 128;
|
sm[1] = 128;
|
||||||
|
|
||||||
|
mask=0;
|
||||||
|
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -789,6 +789,7 @@ class FurnaceGUI {
|
||||||
int ym2612Core;
|
int ym2612Core;
|
||||||
int saaCore;
|
int saaCore;
|
||||||
int nesCore;
|
int nesCore;
|
||||||
|
int fdsCore;
|
||||||
int mainFont;
|
int mainFont;
|
||||||
int patFont;
|
int patFont;
|
||||||
int audioRate;
|
int audioRate;
|
||||||
|
@ -872,6 +873,7 @@ class FurnaceGUI {
|
||||||
ym2612Core(0),
|
ym2612Core(0),
|
||||||
saaCore(1),
|
saaCore(1),
|
||||||
nesCore(0),
|
nesCore(0),
|
||||||
|
fdsCore(0),
|
||||||
mainFont(0),
|
mainFont(0),
|
||||||
patFont(0),
|
patFont(0),
|
||||||
audioRate(44100),
|
audioRate(44100),
|
||||||
|
|
|
@ -868,6 +868,10 @@ void FurnaceGUI::drawSettings() {
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::Combo("##NESCore",&settings.nesCore,nesCores,2);
|
ImGui::Combo("##NESCore",&settings.nesCore,nesCores,2);
|
||||||
|
|
||||||
|
ImGui::Text("FDS core");
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::Combo("##FDSCore",&settings.fdsCore,nesCores,2);
|
||||||
|
|
||||||
ImGui::EndTabItem();
|
ImGui::EndTabItem();
|
||||||
}
|
}
|
||||||
if (ImGui::BeginTabItem("Appearance")) {
|
if (ImGui::BeginTabItem("Appearance")) {
|
||||||
|
@ -1741,6 +1745,7 @@ void FurnaceGUI::syncSettings() {
|
||||||
settings.ym2612Core=e->getConfInt("ym2612Core",0);
|
settings.ym2612Core=e->getConfInt("ym2612Core",0);
|
||||||
settings.saaCore=e->getConfInt("saaCore",1);
|
settings.saaCore=e->getConfInt("saaCore",1);
|
||||||
settings.nesCore=e->getConfInt("nesCore",0);
|
settings.nesCore=e->getConfInt("nesCore",0);
|
||||||
|
settings.fdsCore=e->getConfInt("fdsCore",0);
|
||||||
settings.mainFont=e->getConfInt("mainFont",0);
|
settings.mainFont=e->getConfInt("mainFont",0);
|
||||||
settings.patFont=e->getConfInt("patFont",0);
|
settings.patFont=e->getConfInt("patFont",0);
|
||||||
settings.mainFontPath=e->getConfString("mainFontPath","");
|
settings.mainFontPath=e->getConfString("mainFontPath","");
|
||||||
|
@ -1816,6 +1821,7 @@ void FurnaceGUI::syncSettings() {
|
||||||
clampSetting(settings.ym2612Core,0,1);
|
clampSetting(settings.ym2612Core,0,1);
|
||||||
clampSetting(settings.saaCore,0,1);
|
clampSetting(settings.saaCore,0,1);
|
||||||
clampSetting(settings.nesCore,0,1);
|
clampSetting(settings.nesCore,0,1);
|
||||||
|
clampSetting(settings.fdsCore,0,1);
|
||||||
clampSetting(settings.mainFont,0,6);
|
clampSetting(settings.mainFont,0,6);
|
||||||
clampSetting(settings.patFont,0,6);
|
clampSetting(settings.patFont,0,6);
|
||||||
clampSetting(settings.patRowsBase,0,1);
|
clampSetting(settings.patRowsBase,0,1);
|
||||||
|
@ -1919,6 +1925,7 @@ void FurnaceGUI::commitSettings() {
|
||||||
e->setConf("ym2612Core",settings.ym2612Core);
|
e->setConf("ym2612Core",settings.ym2612Core);
|
||||||
e->setConf("saaCore",settings.saaCore);
|
e->setConf("saaCore",settings.saaCore);
|
||||||
e->setConf("nesCore",settings.nesCore);
|
e->setConf("nesCore",settings.nesCore);
|
||||||
|
e->setConf("fdsCore",settings.fdsCore);
|
||||||
e->setConf("mainFont",settings.mainFont);
|
e->setConf("mainFont",settings.mainFont);
|
||||||
e->setConf("patFont",settings.patFont);
|
e->setConf("patFont",settings.patFont);
|
||||||
e->setConf("mainFontPath",settings.mainFontPath);
|
e->setConf("mainFontPath",settings.mainFontPath);
|
||||||
|
|
Loading…
Reference in a new issue