WonderSwan: acquireDirect()

This commit is contained in:
tildearrow 2025-03-07 18:37:25 -05:00
parent 3d915270b1
commit 0d7ef2e8eb
7 changed files with 90 additions and 156 deletions

View file

@ -620,11 +620,6 @@ void DivDispatchContainer::init(DivSystem sys, DivEngine* eng, int chanCount, do
break; break;
case DIV_SYSTEM_SWAN: case DIV_SYSTEM_SWAN:
dispatch=new DivPlatformSwan; dispatch=new DivPlatformSwan;
if (isRender) {
((DivPlatformSwan*)dispatch)->setCoreQuality(eng->getConfInt("swanQualityRender",3));
} else {
((DivPlatformSwan*)dispatch)->setCoreQuality(eng->getConfInt("swanQuality",3));
}
break; break;
case DIV_SYSTEM_T6W28: case DIV_SYSTEM_T6W28:
dispatch=new DivPlatformT6W28; dispatch=new DivPlatformT6W28;

View file

@ -49,18 +49,23 @@
} }
#define SYNCSAMPLE(wt) /* \ #define SYNCSAMPLE(wt) \
{ \ { \
int32_t left = sample_cache[ch][0], right = sample_cache[ch][1]; \ int32_t left = sample_cache[ch][0] << 5, right = sample_cache[ch][1] << 5; \
WaveSynth.offset_inline(wt, left - last_val[ch][0], sbuf[0]); \ if (left!=last_val[ch][0]) { \
WaveSynth.offset_inline(wt, right - last_val[ch][1], sbuf[1]); \ blip_add_delta(sbuf[0], wt, left - last_val[ch][0]); \
last_val[ch][0] = left; \ last_val[ch][0] = left; \
last_val[ch][1] = right; \ } \
} */ if (right!=last_val[ch][1]) { \
blip_add_delta(sbuf[1], wt, right - last_val[ch][1]); \
last_val[ch][1] = right; \
} \
oscBuf[ch]->putSample(wt,(left+right)<<1); \
}
#define SYNCSAMPLE_NOISE(wt) SYNCSAMPLE(wt) #define SYNCSAMPLE_NOISE(wt) SYNCSAMPLE(wt)
void WSwan::SoundUpdate(uint32_t v30mz_timestamp) void WSwan::SoundUpdate(void)
{ {
int32_t run_time; int32_t run_time;
@ -68,9 +73,6 @@ void WSwan::SoundUpdate(uint32_t v30mz_timestamp)
//printf("%02x %02x\n", control, noise_control); //printf("%02x %02x\n", control, noise_control);
run_time = v30mz_timestamp - last_ts; run_time = v30mz_timestamp - last_ts;
for(int y = 0; y < 2; y++)
sbuf[y] = 0;
for(unsigned int ch = 0; ch < 4; ch++) for(unsigned int ch = 0; ch < 4; ch++)
{ {
// Channel is disabled? // Channel is disabled?
@ -85,6 +87,7 @@ void WSwan::SoundUpdate(uint32_t v30mz_timestamp)
else if(ch == 2 && (control & 0x40) && sweep_value) // Sweep else if(ch == 2 && (control & 0x40) && sweep_value) // Sweep
{ {
uint32_t tmp_pt = 2048 - period[ch]; uint32_t tmp_pt = 2048 - period[ch];
uint32_t meow_timestamp = v30mz_timestamp - run_time;
uint32_t tmp_run_time = run_time; uint32_t tmp_run_time = run_time;
while(tmp_run_time) while(tmp_run_time)
@ -106,6 +109,7 @@ void WSwan::SoundUpdate(uint32_t v30mz_timestamp)
} }
} }
meow_timestamp += sub_run_time;
if(tmp_pt > 4) if(tmp_pt > 4)
{ {
period_counter[ch] -= sub_run_time; period_counter[ch] -= sub_run_time;
@ -114,6 +118,7 @@ void WSwan::SoundUpdate(uint32_t v30mz_timestamp)
sample_pos[ch] = (sample_pos[ch] + 1) & 0x1F; sample_pos[ch] = (sample_pos[ch] + 1) & 0x1F;
MK_SAMPLE_CACHE; MK_SAMPLE_CACHE;
SYNCSAMPLE(meow_timestamp + period_counter[ch]);
period_counter[ch] += tmp_pt; period_counter[ch] += tmp_pt;
} }
} }
@ -162,8 +167,6 @@ void WSwan::SoundUpdate(uint32_t v30mz_timestamp)
} }
} }
} }
sbuf[0] += sample_cache[ch][0];
sbuf[1] += sample_cache[ch][1];
} }
if(HVoiceCtrl & 0x80) if(HVoiceCtrl & 0x80)
@ -181,21 +184,25 @@ void WSwan::SoundUpdate(uint32_t v30mz_timestamp)
sample >>= 5; sample >>= 5;
int32_t left, right; int32_t left, right;
left = (HVoiceChanCtrl & 0x40) ? sample : 0; left = (HVoiceChanCtrl & 0x40) ? (sample << 5) : 0;
right = (HVoiceChanCtrl & 0x20) ? sample : 0; right = (HVoiceChanCtrl & 0x20) ? (sample << 5) : 0;
// WaveSynth.offset_inline(v30mz_timestamp, left - last_hv_val[0], sbuf[0]); if (left!=last_hv_val[0]) {
// WaveSynth.offset_inline(v30mz_timestamp, right - last_hv_val[1], sbuf[1]); blip_add_delta(sbuf[0], v30mz_timestamp, left - last_hv_val[0]);
// last_hv_val[0] = left; last_hv_val[0] = left;
// last_hv_val[1] = right; }
sbuf[0] += left; if (right!=last_hv_val[1]) {
sbuf[1] += right; blip_add_delta(sbuf[1], v30mz_timestamp, right - last_hv_val[1]);
last_hv_val[1] = right;
}
} }
last_ts = v30mz_timestamp; last_ts = v30mz_timestamp;
} }
void WSwan::SoundWrite(uint32_t A, uint8_t V) void WSwan::SoundWrite(uint32_t A, uint8_t V)
{ {
SoundUpdate();
if(A >= 0x80 && A <= 0x87) if(A >= 0x80 && A <= 0x87)
{ {
int ch = (A - 0x80) >> 1; int ch = (A - 0x80) >> 1;
@ -262,10 +269,13 @@ void WSwan::SoundWrite(uint32_t A, uint8_t V)
case 0x95: HyperVoice = V; break; // Pick a port, any port?! case 0x95: HyperVoice = V; break; // Pick a port, any port?!
//default: printf("%04x:%02x\n", A, V); break; //default: printf("%04x:%02x\n", A, V); break;
} }
SoundUpdate();
} }
uint8_t WSwan::SoundRead(uint32_t A) uint8_t WSwan::SoundRead(uint32_t A)
{ {
SoundUpdate();
if(A >= 0x80 && A <= 0x87) if(A >= 0x80 && A <= 0x87)
{ {
int ch = (A - 0x80) >> 1; int ch = (A - 0x80) >> 1;
@ -303,22 +313,8 @@ int32_t WSwan::SoundFlush(int16_t *SoundBuf, const int32_t MaxSoundFrames)
{ {
int32_t FrameCount = 0; int32_t FrameCount = 0;
if(SoundBuf) SoundUpdate();
{
for(int y = 0; y < 2; y++)
{
// sbuf[y]->end_frame(v30mz_timestamp);
// FrameCount = sbuf[y]->read_samples(SoundBuf + y, MaxSoundFrames, true);
int32_t left = sbuf[0];
int32_t right = sbuf[1];
if (left >= 0x400) left = 0x3FF;
else if (left < -0x400) left = -0x400;
if (right >= 0x400) left = 0x3FF;
else if (right < -0x400) left = -0x400;
SoundBuf[0] = (int16_t)left << 5;
SoundBuf[1] = (int16_t)right << 5;
}
}
last_ts = 0; last_ts = 0;
@ -326,51 +322,11 @@ int32_t WSwan::SoundFlush(int16_t *SoundBuf, const int32_t MaxSoundFrames)
} }
// Call before wsRAM is updated // Call before wsRAM is updated
// void WSwan::SoundCheckRAMWrite(uint32_t A) void WSwan::SoundCheckRAMWrite(uint32_t A)
// { {
// if((A >> 6) == SampleRAMPos) if((A >> 6) == SampleRAMPos)
// SoundUpdate(); SoundUpdate();
// } }
// static void RedoVolume(void)
// {
// WaveSynth.volume(2.5);
// }
// void WSwan::SoundInit(void)
// {
// for(int i = 0; i < 2; i++)
// {
// sbuf[i] = new Blip_Buffer();
// sbuf[i]->set_sample_rate(0 ? 0 : 44100, 60);
// sbuf[i]->clock_rate((long)(3072000));
// sbuf[i]->bass_freq(20);
// }
// RedoVolume();
// }
// void WSwan::SoundKill(void)
// {
// for(int i = 0; i < 2; i++)
// {
// if(sbuf[i])
// {
// delete sbuf[i];
// sbuf[i] = NULL;
// }
// }
// }
// bool WSwan::SetSoundRate(uint32_t rate)
// {
// for(int i = 0; i < 2; i++)
// sbuf[i]->set_sample_rate(rate?rate:44100, 60);
// return(true);
// }
void WSwan::SoundReset(void) void WSwan::SoundReset(void)
{ {
@ -394,7 +350,7 @@ void WSwan::SoundReset(void)
nreg = 0; nreg = 0;
memset(sample_cache, 0, sizeof(sample_cache)); memset(sample_cache, 0, sizeof(sample_cache));
// memset(last_val, 0, sizeof(last_val)); memset(last_val, 0, sizeof(last_val));
last_v_val = 0; last_v_val = 0;
HyperVoice = 0; HyperVoice = 0;
@ -402,8 +358,6 @@ void WSwan::SoundReset(void)
HVoiceCtrl = 0; HVoiceCtrl = 0;
HVoiceChanCtrl = 0; HVoiceChanCtrl = 0;
for(int y = 0; y < 2; y++)
// sbuf[y]->clear();
sbuf[y] = 0;
last_ts = 0; last_ts = 0;
v30mz_timestamp = 0;
} }

View file

@ -23,32 +23,29 @@
#define __WSWAN_SOUND_H #define __WSWAN_SOUND_H
#include <stdint.h> #include <stdint.h>
#include "blip_buf.h"
#include "../../dispatch.h"
class WSwan class WSwan
{ {
public: public:
int32_t SoundFlush(int16_t *SoundBuf, const int32_t MaxSoundFrames); int32_t SoundFlush(int16_t *SoundBuf, const int32_t MaxSoundFrames);
// void SoundInit(void);
// void SoundKill(void);
// void SetSoundMultiplier(double multiplier);
// bool SetSoundRate(uint32_t rate);
void SoundWrite(uint32_t, uint8_t); void SoundWrite(uint32_t, uint8_t);
uint8_t SoundRead(uint32_t); uint8_t SoundRead(uint32_t);
void SoundReset(void); void SoundReset(void);
// void SoundCheckRAMWrite(uint32_t A); void SoundCheckRAMWrite(uint32_t A);
void SoundUpdate(uint32_t); void SoundUpdate();
void RAMWrite(uint32_t, uint8_t); void RAMWrite(uint32_t, uint8_t);
int32_t sample_cache[4][2]; int32_t sample_cache[4][2];
private:
// Blip_Synth<blip_good_quality, 4096> WaveSynth; // Blip_Synth<blip_good_quality, 4096> WaveSynth;
// Blip_Buffer *sbuf[2] = { NULL }; // Blip_Buffer *sbuf[2] = { NULL };
int32_t sbuf[2]; blip_buffer_t* sbuf[2];
DivDispatchOscBuffer* oscBuf[4];
uint16_t period[4]; uint16_t period[4];
uint8_t volume[4]; // left volume in upper 4 bits, right in lower 4 bits uint8_t volume[4]; // left volume in upper 4 bits, right in lower 4 bits
@ -70,10 +67,11 @@ private:
uint8_t HVoiceCtrl, HVoiceChanCtrl; uint8_t HVoiceCtrl, HVoiceChanCtrl;
int32_t period_counter[4]; int32_t period_counter[4];
// int32_t last_val[4][2]; // Last outputted value, l&r int32_t last_val[4][2]; // Last outputted value, l&r
uint8_t sample_pos[4]; uint8_t sample_pos[4];
uint16_t nreg; uint16_t nreg;
uint32_t last_ts; uint32_t last_ts;
uint32_t v30mz_timestamp;
uint8_t wsRAM[64]; uint8_t wsRAM[64];
}; };

View file

@ -53,16 +53,36 @@ const char** DivPlatformSwan::getRegisterSheet() {
return regCheatSheetWS; return regCheatSheetWS;
} }
void DivPlatformSwan::acquire(short** buf, size_t len) { void DivPlatformSwan::acquireDirect(blip_buffer_t** bb, size_t len) {
for (int i=0; i<4; i++) { for (int i=0; i<4; i++) {
oscBuf[i]->begin(len); oscBuf[i]->begin(len);
ws->oscBuf[i]=oscBuf[i];
} }
ws->sbuf[0]=bb[0];
ws->sbuf[1]=bb[1];
for (size_t h=0; h<len; h++) { for (size_t h=0; h<len; h++) {
ws->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 // PCM part
if (pcm && dacSample!=-1) { if (pcm && dacSample!=-1) {
dacPeriod+=dacRate; dacPeriod+=dacRate*pcmAdvance;
while (dacPeriod>rate) { while (dacPeriod>=rate) {
DivSample* s=parent->getSample(dacSample); DivSample* s=parent->getSample(dacSample);
if (s->samples<=0 || dacPos>=s->samples) { if (s->samples<=0 || dacPos>=s->samples) {
dacSample=-1; dacSample=-1;
@ -79,24 +99,26 @@ void DivPlatformSwan::acquire(short** buf, size_t len) {
} }
} }
h+=pcmAdvance-1;
// the rest // the rest
while (!writes.empty()) { while (!writes.empty()) {
QueuedWrite w=writes.front(); QueuedWrite w=writes.front();
regPool[w.addr]=w.val; regPool[w.addr]=w.val;
if (w.addr<0x40) ws->SoundWrite(w.addr|0x80,w.val); if (w.addr<0x40) {
else ws->RAMWrite(w.addr&0x3f,w.val); ws->SoundWrite(w.addr|0x80,w.val);
} else {
ws->SoundCheckRAMWrite(w.addr&0x3f);
ws->RAMWrite(w.addr&0x3f,w.val);
}
writes.pop(); writes.pop();
} }
int16_t samp[2]{0, 0};
ws->SoundUpdate(coreQuality);
ws->SoundFlush(samp,1);
buf[0][h]=samp[0];
buf[1][h]=samp[1];
for (int i=0; i<4; i++) {
oscBuf[i]->putSample(h,(ws->sample_cache[i][0]+ws->sample_cache[i][1])<<6);
}
} }
ws->v30mz_timestamp=len;
ws->SoundUpdate();
ws->SoundFlush(NULL,0);
for (int i=0; i<4; i++) { for (int i=0; i<4; i++) {
oscBuf[i]->end(len); oscBuf[i]->end(len);
} }
@ -587,6 +609,10 @@ int DivPlatformSwan::getOutputCount() {
return 2; return 2;
} }
bool DivPlatformSwan::hasAcquireDirect() {
return true;
}
void DivPlatformSwan::notifyWaveChange(int wave) { void DivPlatformSwan::notifyWaveChange(int wave) {
for (int i=0; i<4; i++) { for (int i=0; i<4; i++) {
if (chan[i].wave==wave) { if (chan[i].wave==wave) {
@ -613,38 +639,12 @@ void DivPlatformSwan::poke(std::vector<DivRegWrite>& wlist) {
void DivPlatformSwan::setFlags(const DivConfig& flags) { void DivPlatformSwan::setFlags(const DivConfig& flags) {
chipClock=3072000; chipClock=3072000;
CHECK_CUSTOM_CLOCK; CHECK_CUSTOM_CLOCK;
rate=chipClock/coreQuality; rate=chipClock;
for (int i=0; i<4; i++) { for (int i=0; i<4; i++) {
oscBuf[i]->setRate(rate); oscBuf[i]->setRate(rate);
} }
} }
void DivPlatformSwan::setCoreQuality(unsigned char q) {
switch (q) {
case 0:
coreQuality=96;
break;
case 1:
coreQuality=64;
break;
case 2:
coreQuality=32;
break;
case 3:
coreQuality=16;
break;
case 4:
coreQuality=4;
break;
case 5:
coreQuality=1;
break;
default:
coreQuality=16;
break;
}
}
int DivPlatformSwan::init(DivEngine* p, int channels, int sugRate, const DivConfig& flags) { int DivPlatformSwan::init(DivEngine* p, int channels, int sugRate, const DivConfig& flags) {
parent=p; parent=p;
dumpWrites=false; dumpWrites=false;

View file

@ -53,13 +53,12 @@ class DivPlatformSwan: public DivDispatch {
}; };
FixedQueue<QueuedWrite,256> writes; FixedQueue<QueuedWrite,256> writes;
FixedQueue<DivRegWrite,2048> postDACWrites; FixedQueue<DivRegWrite,2048> postDACWrites;
int coreQuality;
WSwan* ws; WSwan* ws;
void updateWave(int ch); void updateWave(int ch);
friend void putDispatchChip(void*,int); friend void putDispatchChip(void*,int);
friend void putDispatchChan(void*,int,int); friend void putDispatchChan(void*,int,int);
public: public:
void acquire(short** buf, size_t len); void acquireDirect(blip_buffer_t** bb, size_t len);
int dispatch(DivCommand c); int dispatch(DivCommand c);
void* getChanState(int chan); void* getChanState(int chan);
DivMacroInt* getChanMacroInt(int ch); DivMacroInt* getChanMacroInt(int ch);
@ -76,10 +75,10 @@ class DivPlatformSwan: public DivDispatch {
void notifyWaveChange(int wave); void notifyWaveChange(int wave);
void notifyInsDeletion(void* ins); void notifyInsDeletion(void* ins);
int getOutputCount(); int getOutputCount();
bool hasAcquireDirect();
void poke(unsigned int addr, unsigned short val); void poke(unsigned int addr, unsigned short val);
void poke(std::vector<DivRegWrite>& wlist); void poke(std::vector<DivRegWrite>& wlist);
const char** getRegisterSheet(); const char** getRegisterSheet();
void setCoreQuality(unsigned char q);
int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags); int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags);
void quit(); void quit();
~DivPlatformSwan(); ~DivPlatformSwan();

View file

@ -1802,7 +1802,6 @@ class FurnaceGUI {
int pnQuality; int pnQuality;
int saaQuality; int saaQuality;
int smQuality; int smQuality;
int swanQuality;
int arcadeCoreRender; int arcadeCoreRender;
int ym2612CoreRender; int ym2612CoreRender;
int snCoreRender; int snCoreRender;
@ -1826,7 +1825,6 @@ class FurnaceGUI {
int pnQualityRender; int pnQualityRender;
int saaQualityRender; int saaQualityRender;
int smQualityRender; int smQualityRender;
int swanQualityRender;
int pcSpeakerOutMethod; int pcSpeakerOutMethod;
String yrw801Path; String yrw801Path;
String tg100Path; String tg100Path;
@ -2061,7 +2059,6 @@ class FurnaceGUI {
pnQuality(3), pnQuality(3),
saaQuality(3), saaQuality(3),
smQuality(3), smQuality(3),
swanQuality(3),
arcadeCoreRender(1), arcadeCoreRender(1),
ym2612CoreRender(0), ym2612CoreRender(0),
snCoreRender(0), snCoreRender(0),
@ -2085,7 +2082,6 @@ class FurnaceGUI {
pnQualityRender(3), pnQualityRender(3),
saaQualityRender(3), saaQualityRender(3),
smQualityRender(3), smQualityRender(3),
swanQualityRender(3),
pcSpeakerOutMethod(0), pcSpeakerOutMethod(0),
yrw801Path(""), yrw801Path(""),
tg100Path(""), tg100Path(""),

View file

@ -2127,7 +2127,6 @@ void FurnaceGUI::drawSettings() {
CORE_QUALITY("SAA1099",saaQuality,saaQualityRender); CORE_QUALITY("SAA1099",saaQuality,saaQualityRender);
CORE_QUALITY("SID (dSID)",dsidQuality,dsidQualityRender); CORE_QUALITY("SID (dSID)",dsidQuality,dsidQualityRender);
CORE_QUALITY("SM8521",smQuality,smQualityRender); CORE_QUALITY("SM8521",smQuality,smQualityRender);
CORE_QUALITY("WonderSwan",swanQuality,swanQualityRender);
ImGui::EndTable(); ImGui::EndTable();
} }
@ -5135,7 +5134,6 @@ void FurnaceGUI::readConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
settings.pnQuality=conf.getInt("pnQuality",3); settings.pnQuality=conf.getInt("pnQuality",3);
settings.saaQuality=conf.getInt("saaQuality",3); settings.saaQuality=conf.getInt("saaQuality",3);
settings.smQuality=conf.getInt("smQuality",3); settings.smQuality=conf.getInt("smQuality",3);
settings.swanQuality=conf.getInt("swanQuality",3);
settings.arcadeCoreRender=conf.getInt("arcadeCoreRender",1); settings.arcadeCoreRender=conf.getInt("arcadeCoreRender",1);
settings.ym2612CoreRender=conf.getInt("ym2612CoreRender",0); settings.ym2612CoreRender=conf.getInt("ym2612CoreRender",0);
@ -5161,7 +5159,6 @@ void FurnaceGUI::readConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
settings.pnQualityRender=conf.getInt("pnQualityRender",3); settings.pnQualityRender=conf.getInt("pnQualityRender",3);
settings.saaQualityRender=conf.getInt("saaQualityRender",3); settings.saaQualityRender=conf.getInt("saaQualityRender",3);
settings.smQualityRender=conf.getInt("smQualityRender",3); settings.smQualityRender=conf.getInt("smQualityRender",3);
settings.swanQualityRender=conf.getInt("swanQualityRender",3);
settings.pcSpeakerOutMethod=conf.getInt("pcSpeakerOutMethod",0); settings.pcSpeakerOutMethod=conf.getInt("pcSpeakerOutMethod",0);
@ -5203,7 +5200,6 @@ void FurnaceGUI::readConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
clampSetting(settings.pnQuality,0,5); clampSetting(settings.pnQuality,0,5);
clampSetting(settings.saaQuality,0,5); clampSetting(settings.saaQuality,0,5);
clampSetting(settings.smQuality,0,5); clampSetting(settings.smQuality,0,5);
clampSetting(settings.swanQuality,0,5);
clampSetting(settings.arcadeCoreRender,0,1); clampSetting(settings.arcadeCoreRender,0,1);
clampSetting(settings.ym2612CoreRender,0,2); clampSetting(settings.ym2612CoreRender,0,2);
clampSetting(settings.snCoreRender,0,1); clampSetting(settings.snCoreRender,0,1);
@ -5227,7 +5223,6 @@ void FurnaceGUI::readConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
clampSetting(settings.pnQualityRender,0,5); clampSetting(settings.pnQualityRender,0,5);
clampSetting(settings.saaQualityRender,0,5); clampSetting(settings.saaQualityRender,0,5);
clampSetting(settings.smQualityRender,0,5); clampSetting(settings.smQualityRender,0,5);
clampSetting(settings.swanQualityRender,0,5);
clampSetting(settings.pcSpeakerOutMethod,0,4); clampSetting(settings.pcSpeakerOutMethod,0,4);
clampSetting(settings.mainFont,0,6); clampSetting(settings.mainFont,0,6);
clampSetting(settings.patFont,0,6); clampSetting(settings.patFont,0,6);
@ -5725,7 +5720,6 @@ void FurnaceGUI::writeConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
conf.set("pnQuality",settings.pnQuality); conf.set("pnQuality",settings.pnQuality);
conf.set("saaQuality",settings.saaQuality); conf.set("saaQuality",settings.saaQuality);
conf.set("smQuality",settings.smQuality); conf.set("smQuality",settings.smQuality);
conf.set("swanQuality",settings.swanQuality);
conf.set("arcadeCoreRender",settings.arcadeCoreRender); conf.set("arcadeCoreRender",settings.arcadeCoreRender);
conf.set("ym2612CoreRender",settings.ym2612CoreRender); conf.set("ym2612CoreRender",settings.ym2612CoreRender);
@ -5751,7 +5745,6 @@ void FurnaceGUI::writeConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
conf.set("pnQualityRender",settings.pnQualityRender); conf.set("pnQualityRender",settings.pnQualityRender);
conf.set("saaQualityRender",settings.saaQualityRender); conf.set("saaQualityRender",settings.saaQualityRender);
conf.set("smQualityRender",settings.smQualityRender); conf.set("smQualityRender",settings.smQualityRender);
conf.set("swanQualityRender",settings.swanQualityRender);
conf.set("pcSpeakerOutMethod",settings.pcSpeakerOutMethod); conf.set("pcSpeakerOutMethod",settings.pcSpeakerOutMethod);
@ -5811,7 +5804,6 @@ void FurnaceGUI::commitSettings() {
settings.pnQuality!=e->getConfInt("pnQuality",3) || settings.pnQuality!=e->getConfInt("pnQuality",3) ||
settings.saaQuality!=e->getConfInt("saaQuality",3) || settings.saaQuality!=e->getConfInt("saaQuality",3) ||
settings.smQuality!=e->getConfInt("smQuality",3) || settings.smQuality!=e->getConfInt("smQuality",3) ||
settings.swanQuality!=e->getConfInt("swanQuality",3) ||
settings.audioQuality!=e->getConfInt("audioQuality",0) || settings.audioQuality!=e->getConfInt("audioQuality",0) ||
settings.audioHiPass!=e->getConfInt("audioHiPass",1) settings.audioHiPass!=e->getConfInt("audioHiPass",1)
); );