mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-02 02:52:40 +00:00
Genesis: add ability to use ymfm instead of Nuked
This commit is contained in:
parent
2fdca5a98f
commit
ccfe3bdd97
6 changed files with 133 additions and 3 deletions
|
@ -113,9 +113,11 @@ void DivDispatchContainer::init(DivSystem sys, DivEngine* eng, int chanCount, do
|
|||
case DIV_SYSTEM_GENESIS:
|
||||
case DIV_SYSTEM_YM2612:
|
||||
dispatch=new DivPlatformGenesis;
|
||||
((DivPlatformGenesis*)dispatch)->setYMFM(eng->getConfInt("ym2612Core",0));
|
||||
break;
|
||||
case DIV_SYSTEM_GENESIS_EXT:
|
||||
dispatch=new DivPlatformGenesisExt;
|
||||
((DivPlatformGenesisExt*)dispatch)->setYMFM(eng->getConfInt("ym2612Core",0));
|
||||
break;
|
||||
case DIV_SYSTEM_SMS:
|
||||
dispatch=new DivPlatformSMS;
|
||||
|
|
|
@ -5835,6 +5835,8 @@ void DivEngine::setConsoleMode(bool enable) {
|
|||
|
||||
void DivEngine::switchMaster() {
|
||||
deinitAudioBackend();
|
||||
quitDispatch();
|
||||
initDispatch();
|
||||
if (initAudioBackend()) {
|
||||
for (int i=0; i<song.systemLen; i++) {
|
||||
disCont[i].setRates(got.rate);
|
||||
|
|
|
@ -11,7 +11,7 @@ static unsigned char konOffs[6]={
|
|||
|
||||
#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 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() {
|
||||
for (int i=0; i<6; i++) {
|
||||
if (i==2 && extMode) continue;
|
||||
|
@ -616,6 +697,9 @@ void* DivPlatformGenesis::getChanState(int ch) {
|
|||
|
||||
void DivPlatformGenesis::reset() {
|
||||
while (!writes.empty()) writes.pop();
|
||||
if (useYMFM) {
|
||||
fm_ymfm->reset();
|
||||
}
|
||||
OPN2_Reset(&fm);
|
||||
OPN2_SetChipType(ladder?ym3438_mode_ym2612:0);
|
||||
if (dumpWrites) {
|
||||
|
@ -693,6 +777,10 @@ int DivPlatformGenesis::getPortaFloor(int ch) {
|
|||
return (ch>5)?12:0;
|
||||
}
|
||||
|
||||
void DivPlatformGenesis::setYMFM(bool use) {
|
||||
useYMFM=use;
|
||||
}
|
||||
|
||||
void DivPlatformGenesis::setFlags(unsigned int flags) {
|
||||
if (flags==2) {
|
||||
chipClock=8000000.0;
|
||||
|
@ -702,9 +790,19 @@ void DivPlatformGenesis::setFlags(unsigned int flags) {
|
|||
chipClock=COLOR_NTSC*15.0/7.0;
|
||||
}
|
||||
psg.setFlags(flags==1);
|
||||
rate=chipClock/36;
|
||||
ladder=flags&0x80000000;
|
||||
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) {
|
||||
|
@ -715,6 +813,7 @@ int DivPlatformGenesis::init(DivEngine* p, int channels, int sugRate, unsigned i
|
|||
for (int i=0; i<10; i++) {
|
||||
isMuted[i]=false;
|
||||
}
|
||||
fm_ymfm=NULL;
|
||||
psg.init(p,4,sugRate,flags==1);
|
||||
setFlags(flags);
|
||||
|
||||
|
@ -723,6 +822,7 @@ int DivPlatformGenesis::init(DivEngine* p, int channels, int sugRate, unsigned i
|
|||
}
|
||||
|
||||
void DivPlatformGenesis::quit() {
|
||||
if (fm_ymfm!=NULL) delete fm_ymfm;
|
||||
psg.quit();
|
||||
}
|
||||
|
||||
|
|
|
@ -3,9 +3,14 @@
|
|||
#include "../dispatch.h"
|
||||
#include <queue>
|
||||
#include "../../../extern/Nuked-OPN2/ym3438.h"
|
||||
#include "sound/ymfm/ymfm_opn.h"
|
||||
|
||||
#include "sms.h"
|
||||
|
||||
class DivYM2612Interface: public ymfm::ymfm_interface {
|
||||
|
||||
};
|
||||
|
||||
class DivPlatformGenesis: public DivDispatch {
|
||||
protected:
|
||||
struct Channel {
|
||||
|
@ -51,6 +56,10 @@ class DivPlatformGenesis: public DivDispatch {
|
|||
int psgOut;
|
||||
int delay;
|
||||
unsigned char lastBusy;
|
||||
|
||||
ymfm::ym2612* fm_ymfm;
|
||||
ymfm::ym2612::output_data out_ymfm;
|
||||
DivYM2612Interface iface;
|
||||
|
||||
bool dacMode;
|
||||
int dacPeriod;
|
||||
|
@ -60,7 +69,7 @@ class DivPlatformGenesis: public DivDispatch {
|
|||
unsigned char sampleBank;
|
||||
unsigned char lfoValue;
|
||||
|
||||
bool extMode;
|
||||
bool extMode, useYMFM;
|
||||
bool ladder;
|
||||
|
||||
short oldWrites[512];
|
||||
|
@ -70,6 +79,9 @@ class DivPlatformGenesis: public DivDispatch {
|
|||
int toFreq(int freq);
|
||||
|
||||
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:
|
||||
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||
|
@ -80,6 +92,7 @@ class DivPlatformGenesis: public DivDispatch {
|
|||
void tick();
|
||||
void muteChannel(int ch, bool mute);
|
||||
bool isStereo();
|
||||
void setYMFM(bool use);
|
||||
bool keyOffAffectsArp(int ch);
|
||||
bool keyOffAffectsPorta(int ch);
|
||||
void toggleRegisterDump(bool enable);
|
||||
|
|
|
@ -2753,6 +2753,11 @@ const char* arcadeCores[]={
|
|||
"Nuked-OPM"
|
||||
};
|
||||
|
||||
const char* ym2612Cores[]={
|
||||
"Nuked-OPN2",
|
||||
"ymfm"
|
||||
};
|
||||
|
||||
#define SAMPLE_RATE_SELECTABLE(x) \
|
||||
if (ImGui::Selectable(#x,settings.audioRate==x)) { \
|
||||
settings.audioRate=x; \
|
||||
|
@ -2860,6 +2865,10 @@ void FurnaceGUI::drawSettings() {
|
|||
ImGui::SameLine();
|
||||
ImGui::Combo("##ArcadeCore",&settings.arcadeCore,arcadeCores,2);
|
||||
|
||||
ImGui::Text("Genesis core");
|
||||
ImGui::SameLine();
|
||||
ImGui::Combo("##YM2612Core",&settings.ym2612Core,ym2612Cores,2);
|
||||
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (ImGui::BeginTabItem("Appearance")) {
|
||||
|
@ -3041,6 +3050,7 @@ void FurnaceGUI::syncSettings() {
|
|||
settings.audioBufSize=e->getConfInt("audioBufSize",1024);
|
||||
settings.audioRate=e->getConfInt("audioRate",44100);
|
||||
settings.arcadeCore=e->getConfInt("arcadeCore",0);
|
||||
settings.ym2612Core=e->getConfInt("ym2612Core",0);
|
||||
settings.mainFont=e->getConfInt("mainFont",0);
|
||||
settings.patFont=e->getConfInt("patFont",0);
|
||||
settings.mainFontPath=e->getConfString("mainFontPath","");
|
||||
|
@ -3071,6 +3081,7 @@ void FurnaceGUI::commitSettings() {
|
|||
e->setConf("audioBufSize",settings.audioBufSize);
|
||||
e->setConf("audioRate",settings.audioRate);
|
||||
e->setConf("arcadeCore",settings.arcadeCore);
|
||||
e->setConf("ym2612Core",settings.ym2612Core);
|
||||
e->setConf("mainFont",settings.mainFont);
|
||||
e->setConf("patFont",settings.patFont);
|
||||
e->setConf("mainFontPath",settings.mainFontPath);
|
||||
|
|
|
@ -196,6 +196,7 @@ class FurnaceGUI {
|
|||
int audioEngine;
|
||||
int audioQuality;
|
||||
int arcadeCore;
|
||||
int ym2612Core;
|
||||
int mainFont;
|
||||
int patFont;
|
||||
int audioRate;
|
||||
|
@ -223,6 +224,7 @@ class FurnaceGUI {
|
|||
audioEngine(DIV_AUDIO_SDL),
|
||||
audioQuality(0),
|
||||
arcadeCore(0),
|
||||
ym2612Core(0),
|
||||
mainFont(0),
|
||||
patFont(0),
|
||||
audioRate(44100),
|
||||
|
|
Loading…
Reference in a new issue