WonderSwan: bring Mednafen core back

This commit is contained in:
tildearrow 2025-03-22 01:36:03 -05:00
parent b4b0481b3f
commit 841af611ba
10 changed files with 1334 additions and 3 deletions

View file

@ -58,6 +58,79 @@ const char** DivPlatformSwan::getRegisterSheet() {
return regCheatSheetWS;
}
// Mednafen
void DivPlatformSwan::acquireDirect(blip_buffer_t** bb, size_t len) {
for (int i=0; i<4; i++) {
oscBuf[i]->begin(len);
ws_mdfn->oscBuf[i]=oscBuf[i];
}
ws_mdfn->sbuf[0]=bb[0];
ws_mdfn->sbuf[1]=bb[1];
for (size_t h=0; h<len; h++) {
ws_mdfn->v30mz_timestamp=h;
// heuristic
int pcmAdvance=1;
if (writes.empty()) {
if (!pcm || dacSample==-1) {
break;
} else {
pcmAdvance=len-h;
if (dacRate>0) {
int remainTime=(rate-dacPeriod+dacRate-1)/dacRate;
if (remainTime<pcmAdvance) pcmAdvance=remainTime;
if (remainTime<1) pcmAdvance=1;
}
}
}
// PCM part
if (pcm && dacSample!=-1) {
dacPeriod+=dacRate*pcmAdvance;
while (dacPeriod>=rate) {
DivSample* s=parent->getSample(dacSample);
if (s->samples<=0 || dacPos>=s->samples) {
dacSample=-1;
dacPeriod=0;
break;
}
rWrite(0x09,(unsigned char)s->data8[dacPos++]+0x80);
if (s->isLoopable() && dacPos>=(unsigned int)s->loopEnd) {
dacPos=s->loopStart;
} else if (dacPos>=s->samples) {
dacSample=-1;
}
dacPeriod-=rate;
}
}
h+=pcmAdvance-1;
// the rest
while (!writes.empty()) {
QueuedWrite w=writes.front();
regPool[w.addr]=w.val;
if (w.addr<0x40) {
ws_mdfn->SoundWrite(w.addr|0x80,w.val);
} else {
ws_mdfn->SoundCheckRAMWrite(w.addr&0x3f);
ws_mdfn->RAMWrite(w.addr&0x3f,w.val);
}
writes.pop();
}
}
ws_mdfn->v30mz_timestamp=len;
ws_mdfn->SoundUpdate();
ws_mdfn->SoundFlush(NULL,0);
for (int i=0; i<4; i++) {
oscBuf[i]->end(len);
}
}
// asiekierka
void DivPlatformSwan::acquire(short** buf, size_t len) {
for (int i=0; i<4; i++) {
oscBuf[i]->begin(len);
@ -598,6 +671,7 @@ void DivPlatformSwan::reset() {
if (dumpWrites) {
addWrite(0xffffffff,0);
}
ws_mdfn->SoundReset();
swan_sound_init(&ws, true);
pcm=false;
sweep=false;
@ -614,7 +688,15 @@ void DivPlatformSwan::reset() {
}
int DivPlatformSwan::getOutputCount() {
return stereo?2:1;
return (stereo || useMdfn)?2:1;
}
bool DivPlatformSwan::hasAcquireDirect() {
return useMdfn;
}
void DivPlatformSwan::setUseMdfn(bool use) {
useMdfn=use;
}
void DivPlatformSwan::notifyWaveChange(int wave) {
@ -643,7 +725,11 @@ void DivPlatformSwan::poke(std::vector<DivRegWrite>& wlist) {
void DivPlatformSwan::setFlags(const DivConfig& flags) {
chipClock=3072000;
CHECK_CUSTOM_CLOCK;
rate=chipClock/128;
if (useMdfn) {
rate=chipClock;
} else {
rate=chipClock/128;
}
stereo=flags.getBool("stereo",true);
for (int i=0; i<4; i++) {
oscBuf[i]->setRate(rate);
@ -654,12 +740,15 @@ int DivPlatformSwan::init(DivEngine* p, int channels, int sugRate, const DivConf
parent=p;
dumpWrites=false;
skipRegisterWrites=false;
stereo=false;
for (int i=0; i<4; i++) {
isMuted[i]=false;
oscBuf[i]=new DivDispatchOscBuffer;
}
ws_mdfn=new WSwan();
setFlags(flags);
reset();
return 4;
@ -669,6 +758,7 @@ void DivPlatformSwan::quit() {
for (int i=0; i<4; i++) {
delete oscBuf[i];
}
delete ws_mdfn;
}
DivPlatformSwan::~DivPlatformSwan() {