GUI: add ability to customize startup system

This commit is contained in:
tildearrow 2022-04-30 01:37:37 -05:00
parent d79e5d77a7
commit 52c0044bd9
7 changed files with 361 additions and 160 deletions

View File

@ -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

View File

@ -620,6 +620,98 @@ void DivEngine::renderSamples() {
x1_010MemLen=memPos+256;
}
String DivEngine::encodeSysDesc(std::vector<int>& desc) {
String ret;
if (desc[0]!=0) {
int index=0;
for (size_t i=0; i<desc.size(); i+=4) {
ret+=fmt::sprintf("%d %d %d %d ",systemToFileFur((DivSystem)desc[i]),desc[i+1],desc[i+2],desc[i+3]);
index++;
if (index>=32) break;
}
}
return ret;
}
std::vector<int> DivEngine::decodeSysDesc(String desc) {
std::vector<int> 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<DIV_INS_MAX; i++) {
if (isInsTypePossible[i]) possibleInsTypes.push_back((DivInstrumentType)i);
}
hasLoadedSomething=true;
}
void DivEngine::reset() {
@ -2666,6 +2749,18 @@ bool DivEngine::init() {
loadConf();
// set default system preset
if (!hasLoadedSomething) {
logI("setting");
std::vector<int> 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()) {

View File

@ -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<int>& desc);
std::vector<int> 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),

View File

@ -2662,7 +2662,7 @@ bool FurnaceGUI::loop() {
if (ImGui::BeginMenu("configure system...")) {
for (int i=0; i<e->song.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();
}
}

View File

@ -857,6 +857,7 @@ class FurnaceGUI {
String audioDevice;
String midiInDevice;
String midiOutDevice;
std::vector<int> 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);

View File

@ -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; i<e->song.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<howMany; i++) {
settings.initialSys.push_back(availableSystems[rand()%totalAvailSys]);
settings.initialSys.push_back(64);
settings.initialSys.push_back(0);
settings.initialSys.push_back(0);
}
} else {
settings.initialSys.push_back(DIV_SYSTEM_DUMMY);
settings.initialSys.push_back(64);
settings.initialSys.push_back(0);
settings.initialSys.push_back(0);
}
}
ImGui::SameLine();
if (ImGui::Button("Reset to defaults")) {
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);
}
for (size_t i=0; i<settings.initialSys.size(); i+=4) {
bool doRemove=false;
bool doInvert=settings.initialSys[i+1]&128;
signed char vol=settings.initialSys[i+1]&127;
ImGui::PushID(i);
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x-ImGui::CalcTextSize("Invert").x-ImGui::GetFrameHeightWithSpacing()*2.0-ImGui::GetStyle().ItemSpacing.x);
if (ImGui::BeginCombo("##System",getSystemName((DivSystem)settings.initialSys[i]))) {
for (int j=0; availableSystems[j]; j++) {
if (ImGui::Selectable(getSystemName((DivSystem)availableSystems[j]),settings.initialSys[i]==availableSystems[j])) {
settings.initialSys[i]=availableSystems[j];
settings.initialSys[i+3]=0;
}
}
ImGui::EndCombo();
}
ImGui::SameLine();
if (ImGui::Checkbox("Invert",&doInvert)) {
settings.initialSys[i+1]^=128;
}
ImGui::SameLine();
ImGui::BeginDisabled(settings.initialSys.size()<=4);
if (ImGui::Button(ICON_FA_MINUS "##InitSysRemove")) {
doRemove=true;
}
ImGui::EndDisabled();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x-(50.0f*dpiScale));
if (CWSliderScalar("Volume",ImGuiDataType_S8,&vol,&_ZERO,&_ONE_HUNDRED_TWENTY_SEVEN)) {
settings.initialSys[i+1]=(settings.initialSys[i+1]&128)|vol;
} rightClickable
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x-(50.0f*dpiScale));
CWSliderScalar("Panning",ImGuiDataType_S8,&settings.initialSys[i+2],&_MINUS_ONE_HUNDRED_TWENTY_SEVEN,&_ONE_HUNDRED_TWENTY_SEVEN); rightClickable
// oh please MSVC don't cry
if (ImGui::TreeNode("Configure")) {
drawSysConf(-1,(DivSystem)settings.initialSys[i],(unsigned int&)settings.initialSys[i+3],false);
ImGui::TreePop();
}
ImGui::PopID();
if (doRemove && settings.initialSys.size()>=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; i<GUI_ACTION_MAX; i++) {
if (guiActions[i].defaultBind==-1) continue; // not a bind
@ -1849,6 +1965,7 @@ void FurnaceGUI::commitSettings() {
e->setConf("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; i<GUI_COLOR_MAX; i++) {

View File

@ -19,75 +19,70 @@
#include "gui.h"
void FurnaceGUI::drawSysConf(int i) {
unsigned int flags=e->song.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;
}
}
}