Genesis: add ability to use ymfm instead of Nuked
This commit is contained in:
parent
2fdca5a98f
commit
ccfe3bdd97
|
@ -113,9 +113,11 @@ void DivDispatchContainer::init(DivSystem sys, DivEngine* eng, int chanCount, do
|
||||||
case DIV_SYSTEM_GENESIS:
|
case DIV_SYSTEM_GENESIS:
|
||||||
case DIV_SYSTEM_YM2612:
|
case DIV_SYSTEM_YM2612:
|
||||||
dispatch=new DivPlatformGenesis;
|
dispatch=new DivPlatformGenesis;
|
||||||
|
((DivPlatformGenesis*)dispatch)->setYMFM(eng->getConfInt("ym2612Core",0));
|
||||||
break;
|
break;
|
||||||
case DIV_SYSTEM_GENESIS_EXT:
|
case DIV_SYSTEM_GENESIS_EXT:
|
||||||
dispatch=new DivPlatformGenesisExt;
|
dispatch=new DivPlatformGenesisExt;
|
||||||
|
((DivPlatformGenesisExt*)dispatch)->setYMFM(eng->getConfInt("ym2612Core",0));
|
||||||
break;
|
break;
|
||||||
case DIV_SYSTEM_SMS:
|
case DIV_SYSTEM_SMS:
|
||||||
dispatch=new DivPlatformSMS;
|
dispatch=new DivPlatformSMS;
|
||||||
|
|
|
@ -5835,6 +5835,8 @@ void DivEngine::setConsoleMode(bool enable) {
|
||||||
|
|
||||||
void DivEngine::switchMaster() {
|
void DivEngine::switchMaster() {
|
||||||
deinitAudioBackend();
|
deinitAudioBackend();
|
||||||
|
quitDispatch();
|
||||||
|
initDispatch();
|
||||||
if (initAudioBackend()) {
|
if (initAudioBackend()) {
|
||||||
for (int i=0; i<song.systemLen; i++) {
|
for (int i=0; i<song.systemLen; i++) {
|
||||||
disCont[i].setRates(got.rate);
|
disCont[i].setRates(got.rate);
|
||||||
|
|
|
@ -11,7 +11,7 @@ static unsigned char konOffs[6]={
|
||||||
|
|
||||||
#define CHIP_FREQBASE 9440540
|
#define CHIP_FREQBASE 9440540
|
||||||
|
|
||||||
void DivPlatformGenesis::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
void DivPlatformGenesis::acquire_nuked(short* bufL, short* bufR, size_t start, size_t len) {
|
||||||
static short o[2];
|
static short o[2];
|
||||||
static int os[2];
|
static int os[2];
|
||||||
|
|
||||||
|
@ -85,6 +85,87 @@ void DivPlatformGenesis::acquire(short* bufL, short* bufR, size_t start, size_t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DivPlatformGenesis::acquire_ymfm(short* bufL, short* bufR, size_t start, size_t len) {
|
||||||
|
static int os[2];
|
||||||
|
|
||||||
|
for (size_t h=start; h<start+len; h++) {
|
||||||
|
if (dacMode && dacSample!=-1) {
|
||||||
|
dacPeriod-=24;
|
||||||
|
if (dacPeriod<1) {
|
||||||
|
DivSample* s=parent->song.sample[dacSample];
|
||||||
|
if (s->rendLength>0) {
|
||||||
|
if (!isMuted[5]) {
|
||||||
|
if (s->depth==8) {
|
||||||
|
immWrite(0x2a,(unsigned char)s->rendData[dacPos]+0x80);
|
||||||
|
} else {
|
||||||
|
immWrite(0x2a,((unsigned short)s->rendData[dacPos]+0x8000)>>8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (++dacPos>=s->rendLength) {
|
||||||
|
if (s->loopStart>=0 && s->loopStart<=(int)s->rendLength) {
|
||||||
|
dacPos=s->loopStart;
|
||||||
|
} else {
|
||||||
|
dacSample=-1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dacPeriod+=MAX(40,dacRate);
|
||||||
|
} else {
|
||||||
|
dacSample=-1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
os[0]=0; os[1]=0;
|
||||||
|
if (!writes.empty() && !fm_ymfm->read_status()) {
|
||||||
|
QueuedWrite& w=writes.front();
|
||||||
|
if (w.addrOrVal) {
|
||||||
|
fm_ymfm->write(0x1+((w.addr>>8)<<1),w.val);
|
||||||
|
//printf("write: %x = %.2x\n",w.addr,w.val);
|
||||||
|
lastBusy=0;
|
||||||
|
writes.pop();
|
||||||
|
} else {
|
||||||
|
//printf("busycounter: %d\n",lastBusy);
|
||||||
|
fm_ymfm->write(0x0+((w.addr>>8)<<1),w.addr);
|
||||||
|
w.addrOrVal=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ladder) {
|
||||||
|
fm_ymfm->generate(&out_ymfm);
|
||||||
|
} else {
|
||||||
|
((ymfm::ym3438*)fm_ymfm)->generate(&out_ymfm);
|
||||||
|
}
|
||||||
|
os[0]=out_ymfm.data[0];
|
||||||
|
os[1]=out_ymfm.data[1];
|
||||||
|
//OPN2_Write(&fm,0,0);
|
||||||
|
|
||||||
|
psgClocks+=psg.rate;
|
||||||
|
while (psgClocks>=rate) {
|
||||||
|
psgOut=(psg.acquireOne()*3)>>3;
|
||||||
|
psgClocks-=rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
os[0]=os[0]+psgOut;
|
||||||
|
if (os[0]<-32768) os[0]=-32768;
|
||||||
|
if (os[0]>32767) os[0]=32767;
|
||||||
|
|
||||||
|
os[1]=os[1]+psgOut;
|
||||||
|
if (os[1]<-32768) os[1]=-32768;
|
||||||
|
if (os[1]>32767) os[1]=32767;
|
||||||
|
|
||||||
|
bufL[h]=os[0];
|
||||||
|
bufR[h]=os[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DivPlatformGenesis::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||||
|
if (useYMFM) {
|
||||||
|
acquire_ymfm(bufL,bufR,start,len);
|
||||||
|
} else {
|
||||||
|
acquire_nuked(bufL,bufR,start,len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DivPlatformGenesis::tick() {
|
void DivPlatformGenesis::tick() {
|
||||||
for (int i=0; i<6; i++) {
|
for (int i=0; i<6; i++) {
|
||||||
if (i==2 && extMode) continue;
|
if (i==2 && extMode) continue;
|
||||||
|
@ -616,6 +697,9 @@ void* DivPlatformGenesis::getChanState(int ch) {
|
||||||
|
|
||||||
void DivPlatformGenesis::reset() {
|
void DivPlatformGenesis::reset() {
|
||||||
while (!writes.empty()) writes.pop();
|
while (!writes.empty()) writes.pop();
|
||||||
|
if (useYMFM) {
|
||||||
|
fm_ymfm->reset();
|
||||||
|
}
|
||||||
OPN2_Reset(&fm);
|
OPN2_Reset(&fm);
|
||||||
OPN2_SetChipType(ladder?ym3438_mode_ym2612:0);
|
OPN2_SetChipType(ladder?ym3438_mode_ym2612:0);
|
||||||
if (dumpWrites) {
|
if (dumpWrites) {
|
||||||
|
@ -693,6 +777,10 @@ int DivPlatformGenesis::getPortaFloor(int ch) {
|
||||||
return (ch>5)?12:0;
|
return (ch>5)?12:0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DivPlatformGenesis::setYMFM(bool use) {
|
||||||
|
useYMFM=use;
|
||||||
|
}
|
||||||
|
|
||||||
void DivPlatformGenesis::setFlags(unsigned int flags) {
|
void DivPlatformGenesis::setFlags(unsigned int flags) {
|
||||||
if (flags==2) {
|
if (flags==2) {
|
||||||
chipClock=8000000.0;
|
chipClock=8000000.0;
|
||||||
|
@ -702,9 +790,19 @@ void DivPlatformGenesis::setFlags(unsigned int flags) {
|
||||||
chipClock=COLOR_NTSC*15.0/7.0;
|
chipClock=COLOR_NTSC*15.0/7.0;
|
||||||
}
|
}
|
||||||
psg.setFlags(flags==1);
|
psg.setFlags(flags==1);
|
||||||
rate=chipClock/36;
|
|
||||||
ladder=flags&0x80000000;
|
ladder=flags&0x80000000;
|
||||||
OPN2_SetChipType(ladder?ym3438_mode_ym2612:0);
|
OPN2_SetChipType(ladder?ym3438_mode_ym2612:0);
|
||||||
|
if (useYMFM) {
|
||||||
|
if (fm_ymfm!=NULL) delete fm_ymfm;
|
||||||
|
if (ladder) {
|
||||||
|
fm_ymfm=new ymfm::ym2612(iface);
|
||||||
|
} else {
|
||||||
|
fm_ymfm=new ymfm::ym3438(iface);
|
||||||
|
}
|
||||||
|
rate=chipClock/144;
|
||||||
|
} else {
|
||||||
|
rate=chipClock/36;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int DivPlatformGenesis::init(DivEngine* p, int channels, int sugRate, unsigned int flags) {
|
int DivPlatformGenesis::init(DivEngine* p, int channels, int sugRate, unsigned int flags) {
|
||||||
|
@ -715,6 +813,7 @@ int DivPlatformGenesis::init(DivEngine* p, int channels, int sugRate, unsigned i
|
||||||
for (int i=0; i<10; i++) {
|
for (int i=0; i<10; i++) {
|
||||||
isMuted[i]=false;
|
isMuted[i]=false;
|
||||||
}
|
}
|
||||||
|
fm_ymfm=NULL;
|
||||||
psg.init(p,4,sugRate,flags==1);
|
psg.init(p,4,sugRate,flags==1);
|
||||||
setFlags(flags);
|
setFlags(flags);
|
||||||
|
|
||||||
|
@ -723,6 +822,7 @@ int DivPlatformGenesis::init(DivEngine* p, int channels, int sugRate, unsigned i
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivPlatformGenesis::quit() {
|
void DivPlatformGenesis::quit() {
|
||||||
|
if (fm_ymfm!=NULL) delete fm_ymfm;
|
||||||
psg.quit();
|
psg.quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,14 @@
|
||||||
#include "../dispatch.h"
|
#include "../dispatch.h"
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include "../../../extern/Nuked-OPN2/ym3438.h"
|
#include "../../../extern/Nuked-OPN2/ym3438.h"
|
||||||
|
#include "sound/ymfm/ymfm_opn.h"
|
||||||
|
|
||||||
#include "sms.h"
|
#include "sms.h"
|
||||||
|
|
||||||
|
class DivYM2612Interface: public ymfm::ymfm_interface {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
class DivPlatformGenesis: public DivDispatch {
|
class DivPlatformGenesis: public DivDispatch {
|
||||||
protected:
|
protected:
|
||||||
struct Channel {
|
struct Channel {
|
||||||
|
@ -51,6 +56,10 @@ class DivPlatformGenesis: public DivDispatch {
|
||||||
int psgOut;
|
int psgOut;
|
||||||
int delay;
|
int delay;
|
||||||
unsigned char lastBusy;
|
unsigned char lastBusy;
|
||||||
|
|
||||||
|
ymfm::ym2612* fm_ymfm;
|
||||||
|
ymfm::ym2612::output_data out_ymfm;
|
||||||
|
DivYM2612Interface iface;
|
||||||
|
|
||||||
bool dacMode;
|
bool dacMode;
|
||||||
int dacPeriod;
|
int dacPeriod;
|
||||||
|
@ -60,7 +69,7 @@ class DivPlatformGenesis: public DivDispatch {
|
||||||
unsigned char sampleBank;
|
unsigned char sampleBank;
|
||||||
unsigned char lfoValue;
|
unsigned char lfoValue;
|
||||||
|
|
||||||
bool extMode;
|
bool extMode, useYMFM;
|
||||||
bool ladder;
|
bool ladder;
|
||||||
|
|
||||||
short oldWrites[512];
|
short oldWrites[512];
|
||||||
|
@ -70,6 +79,9 @@ class DivPlatformGenesis: public DivDispatch {
|
||||||
int toFreq(int freq);
|
int toFreq(int freq);
|
||||||
|
|
||||||
friend void putDispatchChan(void*,int,int);
|
friend void putDispatchChan(void*,int,int);
|
||||||
|
|
||||||
|
void acquire_nuked(short* bufL, short* bufR, size_t start, size_t len);
|
||||||
|
void acquire_ymfm(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);
|
||||||
|
@ -80,6 +92,7 @@ class DivPlatformGenesis: public DivDispatch {
|
||||||
void tick();
|
void tick();
|
||||||
void muteChannel(int ch, bool mute);
|
void muteChannel(int ch, bool mute);
|
||||||
bool isStereo();
|
bool isStereo();
|
||||||
|
void setYMFM(bool use);
|
||||||
bool keyOffAffectsArp(int ch);
|
bool keyOffAffectsArp(int ch);
|
||||||
bool keyOffAffectsPorta(int ch);
|
bool keyOffAffectsPorta(int ch);
|
||||||
void toggleRegisterDump(bool enable);
|
void toggleRegisterDump(bool enable);
|
||||||
|
|
|
@ -2753,6 +2753,11 @@ const char* arcadeCores[]={
|
||||||
"Nuked-OPM"
|
"Nuked-OPM"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const char* ym2612Cores[]={
|
||||||
|
"Nuked-OPN2",
|
||||||
|
"ymfm"
|
||||||
|
};
|
||||||
|
|
||||||
#define SAMPLE_RATE_SELECTABLE(x) \
|
#define SAMPLE_RATE_SELECTABLE(x) \
|
||||||
if (ImGui::Selectable(#x,settings.audioRate==x)) { \
|
if (ImGui::Selectable(#x,settings.audioRate==x)) { \
|
||||||
settings.audioRate=x; \
|
settings.audioRate=x; \
|
||||||
|
@ -2860,6 +2865,10 @@ void FurnaceGUI::drawSettings() {
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::Combo("##ArcadeCore",&settings.arcadeCore,arcadeCores,2);
|
ImGui::Combo("##ArcadeCore",&settings.arcadeCore,arcadeCores,2);
|
||||||
|
|
||||||
|
ImGui::Text("Genesis core");
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::Combo("##YM2612Core",&settings.ym2612Core,ym2612Cores,2);
|
||||||
|
|
||||||
ImGui::EndTabItem();
|
ImGui::EndTabItem();
|
||||||
}
|
}
|
||||||
if (ImGui::BeginTabItem("Appearance")) {
|
if (ImGui::BeginTabItem("Appearance")) {
|
||||||
|
@ -3041,6 +3050,7 @@ void FurnaceGUI::syncSettings() {
|
||||||
settings.audioBufSize=e->getConfInt("audioBufSize",1024);
|
settings.audioBufSize=e->getConfInt("audioBufSize",1024);
|
||||||
settings.audioRate=e->getConfInt("audioRate",44100);
|
settings.audioRate=e->getConfInt("audioRate",44100);
|
||||||
settings.arcadeCore=e->getConfInt("arcadeCore",0);
|
settings.arcadeCore=e->getConfInt("arcadeCore",0);
|
||||||
|
settings.ym2612Core=e->getConfInt("ym2612Core",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","");
|
||||||
|
@ -3071,6 +3081,7 @@ void FurnaceGUI::commitSettings() {
|
||||||
e->setConf("audioBufSize",settings.audioBufSize);
|
e->setConf("audioBufSize",settings.audioBufSize);
|
||||||
e->setConf("audioRate",settings.audioRate);
|
e->setConf("audioRate",settings.audioRate);
|
||||||
e->setConf("arcadeCore",settings.arcadeCore);
|
e->setConf("arcadeCore",settings.arcadeCore);
|
||||||
|
e->setConf("ym2612Core",settings.ym2612Core);
|
||||||
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);
|
||||||
|
|
|
@ -196,6 +196,7 @@ class FurnaceGUI {
|
||||||
int audioEngine;
|
int audioEngine;
|
||||||
int audioQuality;
|
int audioQuality;
|
||||||
int arcadeCore;
|
int arcadeCore;
|
||||||
|
int ym2612Core;
|
||||||
int mainFont;
|
int mainFont;
|
||||||
int patFont;
|
int patFont;
|
||||||
int audioRate;
|
int audioRate;
|
||||||
|
@ -223,6 +224,7 @@ class FurnaceGUI {
|
||||||
audioEngine(DIV_AUDIO_SDL),
|
audioEngine(DIV_AUDIO_SDL),
|
||||||
audioQuality(0),
|
audioQuality(0),
|
||||||
arcadeCore(0),
|
arcadeCore(0),
|
||||||
|
ym2612Core(0),
|
||||||
mainFont(0),
|
mainFont(0),
|
||||||
patFont(0),
|
patFont(0),
|
||||||
audioRate(44100),
|
audioRate(44100),
|
||||||
|
|
Loading…
Reference in a new issue