diff --git a/TODO.md b/TODO.md index a3e82986..09f794ab 100644 --- a/TODO.md +++ b/TODO.md @@ -13,12 +13,10 @@ - maybe YMU759 ADPCM channel - ADPCM chips - more effects for FM param control -- ability to customize startup system - store system presets in new file - Game Boy envelope macro/sequence - option to display chip names instead of "multi-system" on title bar - rewrite the system name detection function anyway -- add nightly.link - scroll instrument/wave/sample list when selecting item - unified data view - volume commands should work on Game Boy diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index edd7dcc4..47d70093 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -620,6 +620,98 @@ void DivEngine::renderSamples() { x1_010MemLen=memPos+256; } +String DivEngine::encodeSysDesc(std::vector& desc) { + String ret; + if (desc[0]!=0) { + int index=0; + for (size_t i=0; i=32) break; + } + } + return ret; +} + +std::vector DivEngine::decodeSysDesc(String desc) { + std::vector ret; + bool hasVal=false; + bool negative=false; + int val=0; + int curStage=0; + int sysID, sysVol, sysPan, sysFlags; + desc+=' '; // ha + for (char i: desc) { + switch (i) { + case ' ': + if (hasVal) { + if (negative) val=-val; + switch (curStage) { + case 0: + sysID=val; + curStage++; + break; + case 1: + sysVol=val; + curStage++; + break; + case 2: + sysPan=val; + curStage++; + break; + case 3: + sysFlags=val; + + if (systemFromFileFur(sysID)!=0) { + if (sysVol<-128) sysVol=-128; + if (sysVol>127) sysVol=127; + if (sysPan<-128) sysPan=-128; + if (sysPan>127) sysPan=127; + ret.push_back(systemFromFileFur(sysID)); + ret.push_back(sysVol); + ret.push_back(sysPan); + ret.push_back(sysFlags); + } + + curStage=0; + break; + } + hasVal=false; + negative=false; + val=0; + } + break; + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + val=(val*10)+(i-'0'); + hasVal=true; + break; + case '-': + if (!hasVal) negative=true; + break; + } + } + return ret; +} + +void DivEngine::initSongWithDesc(const int* description) { + int chanCount=0; + if (description[0]!=0) { + int index=0; + for (int i=0; description[i]; i+=4) { + song.system[index]=(DivSystem)description[i]; + song.systemVol[index]=description[i+1]; + song.systemPan[index]=description[i+2]; + song.systemFlags[index]=description[i+3]; + index++; + chanCount+=getChannelCount(song.system[index]); + if (chanCount>=63) break; + if (index>=32) break; + } + song.systemLen=index; + } +} + void DivEngine::createNew(const int* description) { quitDispatch(); BUSY_BEGIN; @@ -627,18 +719,7 @@ void DivEngine::createNew(const int* description) { song.unload(); song=DivSong(); if (description!=NULL) { - if (description[0]!=0) { - int index=0; - for (int i=0; description[i]; i+=4) { - song.system[index]=(DivSystem)description[i]; - song.systemVol[index]=description[i+1]; - song.systemPan[index]=description[i+2]; - song.systemFlags[index]=description[i+3]; - index++; - if (index>=32) break; - } - song.systemLen=index; - } + initSongWithDesc(description); } recalcChans(); renderSamples(); @@ -1207,6 +1288,8 @@ void DivEngine::recalcChans() { for (int i=0; i preset=decodeSysDesc(getConfString("initialSys","")); + logI("preset size %ld",preset.size()); + if (preset.size()>0 && (preset.size()&3)==0) { + preset.push_back(0); + initSongWithDesc(preset.data()); + } + hasLoadedSomething=true; + } + // init the rest of engine bool haveAudio=false; if (!initAudioBackend()) { diff --git a/src/engine/engine.h b/src/engine/engine.h index e3a0f71c..7dd7489c 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -298,6 +298,7 @@ class DivEngine { bool midiIsDirect; bool lowLatency; bool systemsRegistered; + bool hasLoadedSomething; int softLockCount; int subticks, ticks, curRow, curOrder, remainingLoops, nextSpeed; double divider; @@ -398,6 +399,7 @@ class DivEngine { bool deinitAudioBackend(); void registerSystems(); + void initSongWithDesc(const int* description); void exchangeIns(int one, int two); void swapChannels(int src, int dest); @@ -420,6 +422,9 @@ class DivEngine { DivInstrument* getIns(int index, DivInstrumentType fallbackType=DIV_INS_FM); DivWavetable* getWave(int index); DivSample* getSample(int index); + // parse system setup description + String encodeSysDesc(std::vector& desc); + std::vector decodeSysDesc(String desc); // start fresh void createNew(const int* description); // load a file. @@ -876,6 +881,7 @@ class DivEngine { midiIsDirect(false), lowLatency(false), systemsRegistered(false), + hasLoadedSomething(false), softLockCount(0), subticks(0), ticks(0), diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index e82a16ae..932a7f81 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -2662,7 +2662,7 @@ bool FurnaceGUI::loop() { if (ImGui::BeginMenu("configure system...")) { for (int i=0; isong.systemLen; i++) { if (ImGui::TreeNode(fmt::sprintf("%d. %s##_SYSP%d",i+1,getSystemName(e->song.system[i]),i).c_str())) { - drawSysConf(i); + drawSysConf(i,e->song.system[i],e->song.systemFlags[i],true); ImGui::TreePop(); } } diff --git a/src/gui/gui.h b/src/gui/gui.h index 31ab566f..9608e5eb 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -857,6 +857,7 @@ class FurnaceGUI { String audioDevice; String midiInDevice; String midiOutDevice; + std::vector initialSys; Settings(): mainFontSize(18), @@ -1114,7 +1115,7 @@ class FurnaceGUI { void drawAlgorithm(unsigned char alg, FurnaceGUIFMAlgs algType, const ImVec2& size); void drawFMEnv(unsigned char tl, unsigned char ar, unsigned char dr, unsigned char d2r, unsigned char rr, unsigned char sl, unsigned char sus, unsigned char egt, unsigned char algOrGlobalSus, float maxTl, float maxArDr, const ImVec2& size, unsigned short instType); void drawGBEnv(unsigned char vol, unsigned char len, unsigned char sLen, bool dir, const ImVec2& size); - void drawSysConf(int i); + void drawSysConf(int chan, DivSystem type, unsigned int& flags, bool modifyOnChange); // these ones offer ctrl-wheel fine value changes. bool CWSliderScalar(const char* label, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format=NULL, ImGuiSliderFlags flags=0); diff --git a/src/gui/settings.cpp b/src/gui/settings.cpp index 6f864087..9eeeeae9 100644 --- a/src/gui/settings.cpp +++ b/src/gui/settings.cpp @@ -23,6 +23,7 @@ #include "../fileutils.h" #include "util.h" #include "guiConst.h" +#include "intConst.h" #include "ImGuiFileDialog.h" #include "IconsFontAwesome4.h" #include "misc/cpp/imgui_stdlib.h" @@ -219,7 +220,8 @@ void FurnaceGUI::drawSettings() { } if (ImGui::BeginTabBar("settingsTab")) { if (ImGui::BeginTabItem("General")) { - ImGui::Text("Workspace layout"); + ImGui::Text("Workspace layout:"); + ImGui::SameLine(); if (ImGui::Button("Import")) { openFileDialog(GUI_FILE_IMPORT_LAYOUT); } @@ -231,7 +233,108 @@ void FurnaceGUI::drawSettings() { if (ImGui::Button("Reset")) { showWarning("Are you sure you want to reset the workspace layout?",GUI_WARN_RESET_LAYOUT); } + ImGui::Separator(); + + ImGui::Text("Initial system/chips:"); + ImGui::SameLine(); + if (ImGui::Button("Current systems")) { + settings.initialSys.clear(); + for (int i=0; isong.systemLen; i++) { + settings.initialSys.push_back(e->song.system[i]); + settings.initialSys.push_back(e->song.systemVol[i]); + settings.initialSys.push_back(e->song.systemPan[i]); + settings.initialSys.push_back(e->song.systemFlags[i]); + } + } + ImGui::SameLine(); + if (ImGui::Button("Randomize")) { + settings.initialSys.clear(); + int howMany=1+rand()%3; + int totalAvailSys=0; + for (totalAvailSys=0; availableSystems[totalAvailSys]; totalAvailSys++); + if (totalAvailSys>0) { + for (int i=0; i=8) { + settings.initialSys.erase(settings.initialSys.begin()+i,settings.initialSys.begin()+i+4); + i-=4; + } + } + + if (ImGui::Button(ICON_FA_PLUS "##InitSysAdd")) { + settings.initialSys.push_back(DIV_SYSTEM_YM2612); + settings.initialSys.push_back(64); + settings.initialSys.push_back(0); + settings.initialSys.push_back(0); + } + + ImGui::Separator(); + ImGui::Text("Toggle channel solo on:"); if (ImGui::RadioButton("Right-click or double-click##soloA",settings.soloAction==0)) { settings.soloAction=0; @@ -1755,6 +1858,19 @@ void FurnaceGUI::syncSettings() { clampSetting(settings.moveWindowTitle,0,1); clampSetting(settings.hiddenSystems,0,1); + settings.initialSys=e->decodeSysDesc(e->getConfString("initialSys","")); + if (settings.initialSys.size()<4) { + settings.initialSys.clear(); + settings.initialSys.push_back(DIV_SYSTEM_YM2612); + settings.initialSys.push_back(64); + settings.initialSys.push_back(0); + settings.initialSys.push_back(0); + settings.initialSys.push_back(DIV_SYSTEM_SMS); + settings.initialSys.push_back(32); + settings.initialSys.push_back(0); + settings.initialSys.push_back(0); + } + // keybinds for (int i=0; isetConf("eventDelay",settings.eventDelay); e->setConf("moveWindowTitle",settings.moveWindowTitle); e->setConf("hiddenSystems",settings.hiddenSystems); + e->setConf("initialSys",e->encodeSysDesc(settings.initialSys)); // colors for (int i=0; isong.systemFlags[i]; - bool restart=settings.restartOnFlagChange; +void FurnaceGUI::drawSysConf(int chan, DivSystem type, unsigned int& flags, bool modifyOnChange) { + bool restart=settings.restartOnFlagChange && modifyOnChange; bool sysPal=flags&1; - switch (e->song.system[i]) { + unsigned int copyOfFlags=flags; + switch (type) { case DIV_SYSTEM_YM2612: case DIV_SYSTEM_YM2612_EXT: { if (ImGui::RadioButton("NTSC (7.67MHz)",(flags&3)==0)) { - e->setSysFlags(i,(flags&0x80000000)|0,restart); - updateWindowTitle(); + copyOfFlags=(flags&0x80000000)|0; } if (ImGui::RadioButton("PAL (7.61MHz)",(flags&3)==1)) { - e->setSysFlags(i,(flags&0x80000000)|1,restart); - updateWindowTitle(); + copyOfFlags=(flags&0x80000000)|1; } if (ImGui::RadioButton("FM Towns (8MHz)",(flags&3)==2)) { - e->setSysFlags(i,(flags&0x80000000)|2,restart); - updateWindowTitle(); + copyOfFlags=(flags&0x80000000)|2; } if (ImGui::RadioButton("AtGames Genesis (6.13MHz)",(flags&3)==3)) { - e->setSysFlags(i,(flags&0x80000000)|3,restart); - updateWindowTitle(); + copyOfFlags=(flags&0x80000000)|3; } bool ladder=flags&0x80000000; if (ImGui::Checkbox("Enable DAC distortion",&ladder)) { - e->setSysFlags(i,(flags&(~0x80000000))|(ladder?0x80000000:0),restart); - updateWindowTitle(); + copyOfFlags=(flags&(~0x80000000))|(ladder?0x80000000:0); } break; } case DIV_SYSTEM_SMS: { ImGui::Text("Clock rate:"); if (ImGui::RadioButton("NTSC (3.58MHz)",(flags&3)==0)) { - e->setSysFlags(i,(flags&(~3))|0,restart); - updateWindowTitle(); + copyOfFlags=(flags&(~3))|0; + } if (ImGui::RadioButton("PAL (3.55MHz)",(flags&3)==1)) { - e->setSysFlags(i,(flags&(~3))|1,restart); - updateWindowTitle(); + copyOfFlags=(flags&(~3))|1; + } if (ImGui::RadioButton("BBC Micro (4MHz)",(flags&3)==2)) { - e->setSysFlags(i,(flags&(~3))|2,restart); - updateWindowTitle(); + copyOfFlags=(flags&(~3))|2; + } if (ImGui::RadioButton("Half NTSC (1.79MHz)",(flags&3)==3)) { - e->setSysFlags(i,(flags&(~3))|3,restart); - updateWindowTitle(); + copyOfFlags=(flags&(~3))|3; + } ImGui::Text("Chip type:"); if (ImGui::RadioButton("Sega VDP/Master System",((flags>>2)&3)==0)) { - e->setSysFlags(i,(flags&(~12))|0,restart); - updateWindowTitle(); + copyOfFlags=(flags&(~12))|0; + } if (ImGui::RadioButton("TI SN76489",((flags>>2)&3)==1)) { - e->setSysFlags(i,(flags&(~12))|4,restart); - updateWindowTitle(); + copyOfFlags=(flags&(~12))|4; + } if (ImGui::RadioButton("TI SN76489 with Atari-like short noise",((flags>>2)&3)==2)) { - e->setSysFlags(i,(flags&(~12))|8,restart); - updateWindowTitle(); + copyOfFlags=(flags&(~12))|8; + } /*if (ImGui::RadioButton("Game Gear",(flags>>2)==3)) { - e->setSysFlags(i,(flags&3)|12); + copyOfFlags=(flags&3)|12); }*/ bool noPhaseReset=flags&16; if (ImGui::Checkbox("Disable noise period change phase reset",&noPhaseReset)) { - e->setSysFlags(i,(flags&(~16))|(noPhaseReset<<4),restart); - updateWindowTitle(); + copyOfFlags=(flags&(~16))|(noPhaseReset<<4); + } break; } @@ -96,54 +91,54 @@ void FurnaceGUI::drawSysConf(int i) { case DIV_SYSTEM_VRC7: { ImGui::Text("Clock rate:"); if (ImGui::RadioButton("NTSC (3.58MHz)",(flags&15)==0)) { - e->setSysFlags(i,(flags&(~15))|0,restart); - updateWindowTitle(); + copyOfFlags=(flags&(~15))|0; + } if (ImGui::RadioButton("PAL (3.55MHz)",(flags&15)==1)) { - e->setSysFlags(i,(flags&(~15))|1,restart); - updateWindowTitle(); + copyOfFlags=(flags&(~15))|1; + } if (ImGui::RadioButton("BBC Micro (4MHz)",(flags&15)==2)) { - e->setSysFlags(i,(flags&(~15))|2,restart); - updateWindowTitle(); + copyOfFlags=(flags&(~15))|2; + } if (ImGui::RadioButton("Half NTSC (1.79MHz)",(flags&15)==3)) { - e->setSysFlags(i,(flags&(~15))|3,restart); - updateWindowTitle(); + copyOfFlags=(flags&(~15))|3; + } - if (e->song.system[i]!=DIV_SYSTEM_VRC7) { + if (type!=DIV_SYSTEM_VRC7) { ImGui::Text("Patch set:"); if (ImGui::RadioButton("Yamaha YM2413",((flags>>4)&15)==0)) { - e->setSysFlags(i,(flags&(~0xf0))|0,restart); - updateWindowTitle(); + copyOfFlags=(flags&(~0xf0))|0; + } if (ImGui::RadioButton("Yamaha YMF281",((flags>>4)&15)==1)) { - e->setSysFlags(i,(flags&(~0xf0))|0x10,restart); - updateWindowTitle(); + copyOfFlags=(flags&(~0xf0))|0x10; + } if (ImGui::RadioButton("Yamaha YM2423",((flags>>4)&15)==2)) { - e->setSysFlags(i,(flags&(~0xf0))|0x20,restart); - updateWindowTitle(); + copyOfFlags=(flags&(~0xf0))|0x20; + } if (ImGui::RadioButton("Konami VRC7",((flags>>4)&15)==3)) { - e->setSysFlags(i,(flags&(~0xf0))|0x30,restart); - updateWindowTitle(); + copyOfFlags=(flags&(~0xf0))|0x30; + } } break; } case DIV_SYSTEM_YM2151: if (ImGui::RadioButton("NTSC/X16 (3.58MHz)",flags==0)) { - e->setSysFlags(i,0,restart); - updateWindowTitle(); + copyOfFlags=0; + } if (ImGui::RadioButton("PAL (3.55MHz)",flags==1)) { - e->setSysFlags(i,1,restart); - updateWindowTitle(); + copyOfFlags=1; + } if (ImGui::RadioButton("X1/X68000 (4MHz)",flags==2)) { - e->setSysFlags(i,2,restart); - updateWindowTitle(); + copyOfFlags=2; + } break; case DIV_SYSTEM_NES: @@ -151,120 +146,117 @@ void FurnaceGUI::drawSysConf(int i) { case DIV_SYSTEM_FDS: case DIV_SYSTEM_MMC5: if (ImGui::RadioButton("NTSC (1.79MHz)",flags==0)) { - e->setSysFlags(i,0,restart); - updateWindowTitle(); + copyOfFlags=0; + } if (ImGui::RadioButton("PAL (1.67MHz)",flags==1)) { - e->setSysFlags(i,1,restart); - updateWindowTitle(); + copyOfFlags=1; + } if (ImGui::RadioButton("Dendy (1.77MHz)",flags==2)) { - e->setSysFlags(i,2,restart); - updateWindowTitle(); + copyOfFlags=2; + } break; case DIV_SYSTEM_C64_8580: case DIV_SYSTEM_C64_6581: if (ImGui::RadioButton("NTSC (1.02MHz)",flags==0)) { - e->setSysFlags(i,0,restart); - updateWindowTitle(); + copyOfFlags=0; + } if (ImGui::RadioButton("PAL (0.99MHz)",flags==1)) { - e->setSysFlags(i,1,restart); - updateWindowTitle(); + copyOfFlags=1; + } if (ImGui::RadioButton("SSI 2001 (0.89MHz)",flags==2)) { - e->setSysFlags(i,2,restart); - updateWindowTitle(); + copyOfFlags=2; + } break; case DIV_SYSTEM_AY8910: case DIV_SYSTEM_AY8930: { ImGui::Text("Clock rate:"); if (ImGui::RadioButton("1.79MHz (ZX Spectrum NTSC/MSX)",(flags&15)==0)) { - e->setSysFlags(i,(flags&(~15))|0,restart); - updateWindowTitle(); + copyOfFlags=(flags&(~15))|0; + } if (ImGui::RadioButton("1.77MHz (ZX Spectrum)",(flags&15)==1)) { - e->setSysFlags(i,(flags&(~15))|1,restart); - updateWindowTitle(); + copyOfFlags=(flags&(~15))|1; + } if (ImGui::RadioButton("1.75MHz (ZX Spectrum)",(flags&15)==2)) { - e->setSysFlags(i,(flags&(~15))|2,restart); - updateWindowTitle(); + copyOfFlags=(flags&(~15))|2; + } if (ImGui::RadioButton("2MHz (Atari ST/Sharp X1)",(flags&15)==3)) { - e->setSysFlags(i,(flags&(~15))|3,restart); - updateWindowTitle(); + copyOfFlags=(flags&(~15))|3; + } if (ImGui::RadioButton("1.5MHz (Vectrex)",(flags&15)==4)) { - e->setSysFlags(i,(flags&(~15))|4,restart); - updateWindowTitle(); + copyOfFlags=(flags&(~15))|4; + } if (ImGui::RadioButton("1MHz (Amstrad CPC)",(flags&15)==5)) { - e->setSysFlags(i,(flags&(~15))|5,restart); - updateWindowTitle(); + copyOfFlags=(flags&(~15))|5; + } if (ImGui::RadioButton("0.89MHz (Sunsoft 5B)",(flags&15)==6)) { - e->setSysFlags(i,(flags&(~15))|6,restart); - updateWindowTitle(); + copyOfFlags=(flags&(~15))|6; + } if (ImGui::RadioButton("1.67MHz (?)",(flags&15)==7)) { - e->setSysFlags(i,(flags&(~15))|7,restart); - updateWindowTitle(); + copyOfFlags=(flags&(~15))|7; + } if (ImGui::RadioButton("0.83MHz (Sunsoft 5B on PAL)",(flags&15)==8)) { - e->setSysFlags(i,(flags&(~15))|8,restart); - updateWindowTitle(); + copyOfFlags=(flags&(~15))|8; + } if (ImGui::RadioButton("1.10MHz (Gamate/VIC-20 PAL)",(flags&15)==9)) { - e->setSysFlags(i,(flags&(~15))|9,restart); - updateWindowTitle(); + copyOfFlags=(flags&(~15))|9; + } if (ImGui::RadioButton("2^21Hz (Game Boy)",(flags&15)==10)) { - e->setSysFlags(i,(flags&(~15))|10,restart); - updateWindowTitle(); + copyOfFlags=(flags&(~15))|10; + } - if (e->song.system[i]==DIV_SYSTEM_AY8910) { + if (type==DIV_SYSTEM_AY8910) { ImGui::Text("Chip type:"); if (ImGui::RadioButton("AY-3-8910",(flags&0x30)==0)) { - e->setSysFlags(i,(flags&(~0x30))|0,restart); - updateWindowTitle(); + copyOfFlags=(flags&(~0x30))|0; + } if (ImGui::RadioButton("YM2149(F)",(flags&0x30)==16)) { - e->setSysFlags(i,(flags&(~0x30))|16,restart); - updateWindowTitle(); + copyOfFlags=(flags&(~0x30))|16; + } if (ImGui::RadioButton("Sunsoft 5B",(flags&0x30)==32)) { - e->setSysFlags(i,(flags&(~0x30))|32,restart); - updateWindowTitle(); + copyOfFlags=(flags&(~0x30))|32; + } if (ImGui::RadioButton("AY-3-8914",(flags&0x30)==48)) { - e->setSysFlags(i,(flags&(~0x30))|48,restart); - updateWindowTitle(); + copyOfFlags=(flags&(~0x30))|48; + } } bool stereo=flags&0x40; ImGui::BeginDisabled((flags&0x30)==32); if (ImGui::Checkbox("Stereo##_AY_STEREO",&stereo)) { - e->setSysFlags(i,(flags&(~0x40))|(stereo?0x40:0),restart); - updateWindowTitle(); + copyOfFlags=(flags&(~0x40))|(stereo?0x40:0); + } ImGui::EndDisabled(); break; } case DIV_SYSTEM_SAA1099: if (ImGui::RadioButton("SAM Coupé (8MHz)",flags==0)) { - e->setSysFlags(i,0,restart); - updateWindowTitle(); + copyOfFlags=0; } if (ImGui::RadioButton("NTSC (7.15MHz)",flags==1)) { - e->setSysFlags(i,1,restart); - updateWindowTitle(); + copyOfFlags=1; } if (ImGui::RadioButton("PAL (7.09MHz)",flags==2)) { - e->setSysFlags(i,2,restart); - updateWindowTitle(); + copyOfFlags=2; } break; case DIV_SYSTEM_AMIGA: { @@ -273,44 +265,37 @@ void FurnaceGUI::drawSysConf(int i) { if (CWSliderInt("##StereoSep",&stereoSep,0,127)) { if (stereoSep<0) stereoSep=0; if (stereoSep>127) stereoSep=127; - e->setSysFlags(i,(flags&(~0x7f00))|((stereoSep&127)<<8),restart); - updateWindowTitle(); + copyOfFlags=(flags&(~0x7f00))|((stereoSep&127)<<8); } rightClickable if (ImGui::RadioButton("Amiga 500 (OCS)",(flags&2)==0)) { - e->setSysFlags(i,flags&(~2),restart); + copyOfFlags=flags&(~2); } if (ImGui::RadioButton("Amiga 1200 (AGA)",(flags&2)==2)) { - e->setSysFlags(i,(flags&(~2))|2,restart); + copyOfFlags=(flags&(~2))|2; } sysPal=flags&1; if (ImGui::Checkbox("PAL",&sysPal)) { - e->setSysFlags(i,(flags&(~1))|(unsigned int)sysPal,restart); - updateWindowTitle(); + copyOfFlags=(flags&(~1))|(unsigned int)sysPal; } bool bypassLimits=flags&4; if (ImGui::Checkbox("Bypass frequency limits",&bypassLimits)) { - e->setSysFlags(i,(flags&(~4))|(bypassLimits<<2),restart); - updateWindowTitle(); + copyOfFlags=(flags&(~4))|(bypassLimits<<2); } break; } case DIV_SYSTEM_PCSPKR: { ImGui::Text("Speaker type:"); if (ImGui::RadioButton("Unfiltered",(flags&3)==0)) { - e->setSysFlags(i,(flags&(~3))|0,restart); - updateWindowTitle(); + copyOfFlags=(flags&(~3))|0; } if (ImGui::RadioButton("Cone",(flags&3)==1)) { - e->setSysFlags(i,(flags&(~3))|1,restart); - updateWindowTitle(); + copyOfFlags=(flags&(~3))|1; } if (ImGui::RadioButton("Piezo",(flags&3)==2)) { - e->setSysFlags(i,(flags&(~3))|2,restart); - updateWindowTitle(); + copyOfFlags=(flags&(~3))|2; } if (ImGui::RadioButton("Use system beeper (Linux only!)",(flags&3)==3)) { - e->setSysFlags(i,(flags&(~3))|3,restart); - updateWindowTitle(); + copyOfFlags=(flags&(~3))|3; } break; } @@ -320,62 +305,53 @@ void FurnaceGUI::drawSysConf(int i) { if (CWSliderInt("##EchoBufSize",&echoBufSize,0,2725)) { if (echoBufSize<0) echoBufSize=0; if (echoBufSize>2725) echoBufSize=2725; - e->setSysFlags(i,(flags & ~4095) | ((2725 - echoBufSize) & 4095),restart); - updateWindowTitle(); + copyOfFlags=(flags & ~4095) | ((2725 - echoBufSize) & 4095); } rightClickable ImGui::Text("Echo feedback:"); int echoFeedback=(flags>>12)&255; if (CWSliderInt("##EchoFeedback",&echoFeedback,0,255)) { if (echoFeedback<0) echoFeedback=0; if (echoFeedback>255) echoFeedback=255; - e->setSysFlags(i,(flags & ~(255 << 12)) | ((echoFeedback & 255) << 12),restart); - updateWindowTitle(); + copyOfFlags=(flags & ~(255 << 12)) | ((echoFeedback & 255) << 12); } rightClickable break; } case DIV_SYSTEM_X1_010: { ImGui::Text("Clock rate:"); if (ImGui::RadioButton("16MHz (Seta 1)",(flags&15)==0)) { - e->setSysFlags(i,(flags&(~15))|0,restart); - updateWindowTitle(); + copyOfFlags=(flags&(~15))|0; } if (ImGui::RadioButton("16.67MHz (Seta 2)",(flags&15)==1)) { - e->setSysFlags(i,(flags&(~15))|1,restart); - updateWindowTitle(); + copyOfFlags=(flags&(~15))|1; } bool x1_010Stereo=flags&16; if (ImGui::Checkbox("Stereo",&x1_010Stereo)) { - e->setSysFlags(i,(flags&(~16))|(x1_010Stereo<<4),restart); - updateWindowTitle(); + copyOfFlags=(flags&(~16))|(x1_010Stereo<<4); } break; } case DIV_SYSTEM_N163: { ImGui::Text("Clock rate:"); if (ImGui::RadioButton("NTSC (1.79MHz)",(flags&15)==0)) { - e->setSysFlags(i,(flags&(~15))|0,restart); - updateWindowTitle(); + copyOfFlags=(flags&(~15))|0; } if (ImGui::RadioButton("PAL (1.67MHz)",(flags&15)==1)) { - e->setSysFlags(i,(flags&(~15))|1,restart); - updateWindowTitle(); + copyOfFlags=(flags&(~15))|1; } if (ImGui::RadioButton("Dendy (1.77MHz)",(flags&15)==2)) { - e->setSysFlags(i,(flags&(~15))|2,restart); - updateWindowTitle(); + copyOfFlags=(flags&(~15))|2; } ImGui::Text("Initial channel limit:"); int initialChannelLimit=((flags>>4)&7)+1; if (CWSliderInt("##InitialChannelLimit",&initialChannelLimit,1,8)) { if (initialChannelLimit<1) initialChannelLimit=1; if (initialChannelLimit>8) initialChannelLimit=8; - e->setSysFlags(i,(flags & ~(7 << 4)) | (((initialChannelLimit-1) & 7) << 4),restart); - updateWindowTitle(); + copyOfFlags=(flags & ~(7 << 4)) | (((initialChannelLimit-1) & 7) << 4); + } rightClickable bool n163Multiplex=flags&128; if (ImGui::Checkbox("Disable hissing",&n163Multiplex)) { - e->setSysFlags(i,(flags&(~128))|(n163Multiplex<<7),restart); - updateWindowTitle(); + copyOfFlags=(flags&(~128))|(n163Multiplex<<7); } break; } @@ -395,9 +371,17 @@ void FurnaceGUI::drawSysConf(int i) { break; default: if (ImGui::Checkbox("PAL",&sysPal)) { - e->setSysFlags(i,sysPal,restart); - updateWindowTitle(); + copyOfFlags=sysPal; } break; } + + if (copyOfFlags!=flags) { + if (chan>=0) { + e->setSysFlags(chan,copyOfFlags,restart); + updateWindowTitle(); + } else { + flags=copyOfFlags; + } + } }