diff --git a/CMakeLists.txt b/CMakeLists.txt index aeb705028..1af38ffb3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -779,6 +779,7 @@ src/gui/doAction.cpp src/gui/editing.cpp src/gui/editControls.cpp src/gui/effectList.cpp +src/gui/exportOptions.cpp src/gui/findReplace.cpp src/gui/fmPreview.cpp src/gui/gradient.cpp diff --git a/TODO.md b/TODO.md index 06951982a..f1918edef 100644 --- a/TODO.md +++ b/TODO.md @@ -1,15 +1,12 @@ # to-do -- add cheat code to insert bruno time (blank) - -# THE REAL TO-DO LIST - +- finish color import improvements (settings refactor) +- new undo stuff +- fix some bugs - finish auto-clone once you have done all of this (maybe not the first one), release 0.6.1 -Furnace is like alcohol... - # and then - new oscilloscope renderer - custom code that uses texture and fixes two issues: too many vertices, and broken anti-aliasing diff --git a/doc/2-interface/settings.md b/doc/2-interface/settings.md index b3a93b04c..f65f23fcb 100644 --- a/doc/2-interface/settings.md +++ b/doc/2-interface/settings.md @@ -498,7 +498,7 @@ below all the binds, select a key from the dropdown list to add it. it will appe - **Rounded window corners** - **Rounded buttons** - **Rounded menu corners** -- **Borders around widgets**: draws thin borders on buttons, checkboxes, text widgets, and the like. +- **Borders around widgets**: draws borders on buttons, checkboxes, text widgets, and the like. @@ -509,6 +509,7 @@ below all the binds, select a key from the dropdown list to add it. it will appe - **Import** - **Export** - **Reset defaults** +- **Guru mode**: exposes all color options (instead of accent colors). - **General** - **Color scheme type:** - **Dark** diff --git a/src/engine/configEngine.cpp b/src/engine/configEngine.cpp index 123a19a81..f226d1364 100644 --- a/src/engine/configEngine.cpp +++ b/src/engine/configEngine.cpp @@ -167,4 +167,8 @@ void DivEngine::setConf(String key, String value) { bool DivEngine::hasConf(String key) { return conf.has(key); -} \ No newline at end of file +} + +DivConfig& DivEngine::getConfObject() { + return conf; +} diff --git a/src/engine/engine.h b/src/engine/engine.h index 4170119e9..eb4bc5bbb 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -54,8 +54,8 @@ class DivWorkPool; #define DIV_UNSTABLE -#define DIV_VERSION "dev189" -#define DIV_ENGINE_VERSION 189 +#define DIV_VERSION "dev190" +#define DIV_ENGINE_VERSION 190 // for imports #define DIV_VERSION_MOD 0xff01 #define DIV_VERSION_FC 0xff02 @@ -702,6 +702,9 @@ class DivEngine { double getConfDouble(String key, double fallback); String getConfString(String key, String fallback); + // get config object + DivConfig& getConfObject(); + // set a config value void setConf(String key, bool value); void setConf(String key, int value); diff --git a/src/engine/fileOps.cpp b/src/engine/fileOps.cpp index cb6f4fa90..1dd9d89d4 100644 --- a/src/engine/fileOps.cpp +++ b/src/engine/fileOps.cpp @@ -6492,7 +6492,7 @@ SafeWriter* DivEngine::saveText(bool separatePatterns) { if (ins->type==DIV_INS_GB) { w->writeText("- Game Boy parameters:\n"); w->writeText(fmt::sprintf(" - volume: %d\n",ins->gb.envVol)); - w->writeText(fmt::sprintf(" - direction: %d\n",gbEnvDir[ins->gb.envDir?1:0])); + w->writeText(fmt::sprintf(" - direction: %s\n",gbEnvDir[ins->gb.envDir?1:0])); w->writeText(fmt::sprintf(" - length: %d\n",ins->gb.envLen)); w->writeText(fmt::sprintf(" - sound length: %d\n",ins->gb.soundLen)); w->writeText(fmt::sprintf(" - use software envelope: %s\n",trueFalse[ins->gb.softEnv?1:0])); diff --git a/src/engine/platform/namcowsg.cpp b/src/engine/platform/namcowsg.cpp index 0aa4bbd94..223216f66 100644 --- a/src/engine/platform/namcowsg.cpp +++ b/src/engine/platform/namcowsg.cpp @@ -199,7 +199,7 @@ void DivPlatformNamcoWSG::tick(bool sysTick) { for (int i=0; i>4; + chan[i].outVol=VOL_SCALE_LINEAR(chan[i].vol,chan[i].std.vol.val,15); } if (chan[i].std.duty.had) { chan[i].noise=chan[i].std.duty.val; diff --git a/src/gui/doAction.cpp b/src/gui/doAction.cpp index 5bf40a028..a26700fc0 100644 --- a/src/gui/doAction.cpp +++ b/src/gui/doAction.cpp @@ -66,6 +66,10 @@ void FurnaceGUI::doAction(int what) { case GUI_ACTION_SAVE_AS: openFileDialog(GUI_FILE_SAVE); break; + case GUI_ACTION_EXPORT: + curExportType=GUI_EXPORT_NONE; + displayExport=true; + break; case GUI_ACTION_UNDO: if (curWindow==GUI_WINDOW_SAMPLE_EDIT) { doUndoSample(); diff --git a/src/gui/editControls.cpp b/src/gui/editControls.cpp index b9b8a7409..1ce85020d 100644 --- a/src/gui/editControls.cpp +++ b/src/gui/editControls.cpp @@ -519,24 +519,8 @@ void FurnaceGUI::drawMobileControls() { openFileDialog(GUI_FILE_SAVE_DMF_LEGACY); } ImGui::SameLine(); - if (ImGui::Button("Export Audio")) { - openFileDialog(GUI_FILE_EXPORT_AUDIO_ONE); - } - ImGui::SameLine(); - if (ImGui::Button("Export VGM")) { - openFileDialog(GUI_FILE_EXPORT_VGM); - } - - if (ImGui::Button("CmdStream")) { - openFileDialog(GUI_FILE_EXPORT_CMDSTREAM_BINARY); - } - ImGui::SameLine(); - if (ImGui::Button("CmdStream Text")) { - openFileDialog(GUI_FILE_EXPORT_CMDSTREAM); - } - ImGui::SameLine(); - if (ImGui::Button("Text")) { - openFileDialog(GUI_FILE_EXPORT_TEXT); + if (ImGui::Button("Export")) { + doAction(GUI_ACTION_EXPORT); } if (ImGui::Button("Restore Backup")) { diff --git a/src/gui/editing.cpp b/src/gui/editing.cpp index d27c55a13..50c92aadf 100644 --- a/src/gui/editing.cpp +++ b/src/gui/editing.cpp @@ -771,10 +771,10 @@ unsigned int convertEffectMPT_S3M(unsigned char symbol, unsigned int val) { return (0x80<<8)|((val&0xf)<<4); break; case 0xC: - return (0xFC<<8)|(val&0xf); + return (0xEC<<8)|(val&0xf); break; case 0xD: - return (0xFD<<8)|(val&0xf); + return (0xED<<8)|(val&0xf); break; default: break; @@ -1117,7 +1117,7 @@ void FurnaceGUI::doPasteMPT(PasteMode mode, int arg, bool readClipboard, String if (invalidData) { - logW("invalid OpenMPT clipboard data! failed at line %d char %d",i,charPos); + logW("invalid clipboard data! failed at line %d char %d",i,charPos); logW("%s",line.c_str()); break; } diff --git a/src/gui/exportOptions.cpp b/src/gui/exportOptions.cpp new file mode 100644 index 000000000..165ba5f95 --- /dev/null +++ b/src/gui/exportOptions.cpp @@ -0,0 +1,357 @@ +/** + * Furnace Tracker - multi-system chiptune tracker + * Copyright (C) 2021-2023 tildearrow and contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "gui.h" +#include "guiConst.h" +#include "../fileutils.h" +#include "misc/cpp/imgui_stdlib.h" +#include + +void FurnaceGUI::drawExportAudio(bool onWindow) { + exitDisabledTimer=1; + + ImGui::RadioButton("one file",&audioExportType,0); + ImGui::RadioButton("multiple files (one per chip)",&audioExportType,1); + ImGui::RadioButton("multiple files (one per channel)",&audioExportType,2); + if (ImGui::InputInt("Loops",&exportLoops,1,2)) { + if (exportLoops<0) exportLoops=0; + } + if (ImGui::InputDouble("Fade out (seconds)",&exportFadeOut,1.0,2.0,"%.1f")) { + if (exportFadeOut<0.0) exportFadeOut=0.0; + } + + if (onWindow) { + ImGui::Separator(); + if (ImGui::Button("Cancel",ImVec2(200.0f*dpiScale,0))) ImGui::CloseCurrentPopup(); + ImGui::SameLine(); + } + + if (ImGui::Button("Export",ImVec2(200.0f*dpiScale,0))) { + switch (audioExportType) { + case 0: + openFileDialog(GUI_FILE_EXPORT_AUDIO_ONE); + break; + case 1: + openFileDialog(GUI_FILE_EXPORT_AUDIO_PER_SYS); + break; + case 2: + openFileDialog(GUI_FILE_EXPORT_AUDIO_PER_CHANNEL); + break; + } + ImGui::CloseCurrentPopup(); + } +} + +void FurnaceGUI::drawExportVGM(bool onWindow) { + exitDisabledTimer=1; + + ImGui::Text("settings:"); + if (ImGui::BeginCombo("format version",fmt::sprintf("%d.%.2x",vgmExportVersion>>8,vgmExportVersion&0xff).c_str())) { + for (int i=0; i<7; i++) { + if (ImGui::Selectable(fmt::sprintf("%d.%.2x",vgmVersions[i]>>8,vgmVersions[i]&0xff).c_str(),vgmExportVersion==vgmVersions[i])) { + vgmExportVersion=vgmVersions[i]; + } + } + ImGui::EndCombo(); + } + ImGui::Checkbox("loop",&vgmExportLoop); + if (vgmExportLoop && e->song.loopModality==2) { + ImGui::Text("loop trail:"); + ImGui::Indent(); + if (ImGui::RadioButton("auto-detect",vgmExportTrailingTicks==-1)) { + vgmExportTrailingTicks=-1; + } + if (ImGui::RadioButton("add one loop",vgmExportTrailingTicks==-2)) { + vgmExportTrailingTicks=-2; + } + if (ImGui::RadioButton("custom",vgmExportTrailingTicks>=0)) { + vgmExportTrailingTicks=0; + } + if (vgmExportTrailingTicks>=0) { + ImGui::SameLine(); + if (ImGui::InputInt("##TrailTicks",&vgmExportTrailingTicks,1,100)) { + if (vgmExportTrailingTicks<0) vgmExportTrailingTicks=0; + } + } + ImGui::Unindent(); + } + ImGui::Checkbox("add pattern change hints",&vgmExportPatternHints); + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip( + "inserts data blocks on pattern changes.\n" + "useful if you are writing a playback routine.\n\n" + + "the format of a pattern change data block is:\n" + "67 66 FE ll ll ll ll 01 oo rr pp pp pp ...\n" + "- ll: length, a 32-bit little-endian number\n" + "- oo: order\n" + "- rr: initial row (a 0Dxx effect is able to select a different row)\n" + "- pp: pattern index (one per channel)\n\n" + + "pattern indexes are ordered as they appear in the song." + ); + } + ImGui::Checkbox("direct stream mode",&vgmExportDirectStream); + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip( + "required for DualPCM and MSM6258 export.\n\n" + "allows for volume/direction changes when playing samples,\n" + "at the cost of a massive increase in file size." + ); + } + ImGui::Text("chips to export:"); + bool hasOneAtLeast=false; + for (int i=0; isong.systemLen; i++) { + int minVersion=e->minVGMVersion(e->song.system[i]); + ImGui::BeginDisabled(minVersion>vgmExportVersion || minVersion==0); + ImGui::Checkbox(fmt::sprintf("%d. %s##_SYSV%d",i+1,getSystemName(e->song.system[i]),i).c_str(),&willExport[i]); + ImGui::EndDisabled(); + if (minVersion>vgmExportVersion) { + if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) { + ImGui::SetTooltip("this chip is only available in VGM %d.%.2x and higher!",minVersion>>8,minVersion&0xff); + } + } else if (minVersion==0) { + if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) { + ImGui::SetTooltip("this chip is not supported by the VGM format!"); + } + } else { + if (willExport[i]) hasOneAtLeast=true; + } + } + ImGui::Text("select the chip you wish to export, but only up to %d of each type.",(vgmExportVersion>=0x151)?2:1); + if (hasOneAtLeast) { + if (onWindow) { + ImGui::Separator(); + if (ImGui::Button("Cancel",ImVec2(200.0f*dpiScale,0))) ImGui::CloseCurrentPopup(); + ImGui::SameLine(); + } + if (ImGui::Button("Export",ImVec2(200.0f*dpiScale,0))) { + openFileDialog(GUI_FILE_EXPORT_VGM); + ImGui::CloseCurrentPopup(); + } + } else { + ImGui::Text("nothing to export"); + if (onWindow) { + ImGui::Separator(); + if (ImGui::Button("Cancel",ImVec2(400.0f*dpiScale,0))) ImGui::CloseCurrentPopup(); + } + } +} + +void FurnaceGUI::drawExportZSM(bool onWindow) { + exitDisabledTimer=1; + + ImGui::Text("Commander X16 Zsound Music File"); + if (ImGui::InputInt("Tick Rate (Hz)",&zsmExportTickRate,1,2)) { + if (zsmExportTickRate<1) zsmExportTickRate=1; + if (zsmExportTickRate>44100) zsmExportTickRate=44100; + } + ImGui::Checkbox("loop",&zsmExportLoop); + ImGui::SameLine(); + ImGui::Checkbox("optimize size",&zsmExportOptimize); + if (onWindow) { + ImGui::Separator(); + if (ImGui::Button("Cancel",ImVec2(200.0f*dpiScale,0))) ImGui::CloseCurrentPopup(); + ImGui::SameLine(); + } + if (ImGui::Button("Export",ImVec2(200.0f*dpiScale,0))) { + openFileDialog(GUI_FILE_EXPORT_ZSM); + ImGui::CloseCurrentPopup(); + } +} + +void FurnaceGUI::drawExportAmigaVal(bool onWindow) { + exitDisabledTimer=1; + + ImGui::Text( + "this is NOT ROM export! only use for making sure the\n" + "Furnace Amiga emulator is working properly by\n" + "comparing it with real Amiga output." + ); + ImGui::AlignTextToFramePadding(); + ImGui::Text("Directory"); + ImGui::SameLine(); + ImGui::InputText("##AVDPath",&workingDirROMExport); + if (onWindow) { + ImGui::Separator(); + if (ImGui::Button("Cancel",ImVec2(200.0f*dpiScale,0))) ImGui::CloseCurrentPopup(); + ImGui::SameLine(); + } + if (ImGui::Button("Bake Data",ImVec2(200.0f*dpiScale,0))) { + std::vector out=e->buildROM(DIV_ROM_AMIGA_VALIDATION); + if (workingDirROMExport.size()>0) { + if (workingDirROMExport[workingDirROMExport.size()-1]!=DIR_SEPARATOR) workingDirROMExport+=DIR_SEPARATOR_STR; + } + for (DivROMExportOutput& i: out) { + String path=workingDirROMExport+i.name; + FILE* outFile=ps_fopen(path.c_str(),"wb"); + if (outFile!=NULL) { + fwrite(i.data->getFinalBuf(),1,i.data->size(),outFile); + fclose(outFile); + } + i.data->finish(); + delete i.data; + } + showError(fmt::sprintf("Done! Baked %d files.",(int)out.size())); + ImGui::CloseCurrentPopup(); + } +} + +void FurnaceGUI::drawExportText(bool onWindow) { + exitDisabledTimer=1; + + ImGui::Text( + "this option exports the song to a text file.\n" + ); + if (onWindow) { + ImGui::Separator(); + if (ImGui::Button("Cancel",ImVec2(200.0f*dpiScale,0))) ImGui::CloseCurrentPopup(); + ImGui::SameLine(); + } + if (ImGui::Button("Export",ImVec2(200.0f*dpiScale,0))) { + openFileDialog(GUI_FILE_EXPORT_TEXT); + ImGui::CloseCurrentPopup(); + } +} + +void FurnaceGUI::drawExportCommand(bool onWindow) { + exitDisabledTimer=1; + + ImGui::Text( + "this option exports a text or binary file which\n" + "contains a dump of the internal command stream\n" + "produced when playing the song.\n\n" + + "technical/development use only!" + ); + if (onWindow) { + ImGui::Separator(); + if (ImGui::Button("Cancel",ImVec2(133.3f*dpiScale,0))) ImGui::CloseCurrentPopup(); + ImGui::SameLine(); + } + if (ImGui::Button("Export (binary)",ImVec2(133.3f*dpiScale,0))) { + openFileDialog(GUI_FILE_EXPORT_CMDSTREAM_BINARY); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::Button("Export (text)",ImVec2(133.3f*dpiScale,0))) { + openFileDialog(GUI_FILE_EXPORT_CMDSTREAM); + ImGui::CloseCurrentPopup(); + } +} + +void FurnaceGUI::drawExport() { + if (settings.exportOptionsLayout==1 || curExportType==GUI_EXPORT_NONE) { + if (ImGui::BeginTabBar("ExportTypes")) { + if (ImGui::BeginTabItem("Audio")) { + drawExportAudio(true); + ImGui::EndTabItem(); + } + if (ImGui::BeginTabItem("VGM")) { + drawExportVGM(true); + ImGui::EndTabItem(); + } + int numZSMCompat=0; + for (int i=0; isong.systemLen; i++) { + if ((e->song.system[i]==DIV_SYSTEM_VERA) || (e->song.system[i]==DIV_SYSTEM_YM2151)) numZSMCompat++; + } + if (numZSMCompat>0) { + if (ImGui::BeginTabItem("ZSM")) { + drawExportZSM(true); + ImGui::EndTabItem(); + } + } + int numAmiga=0; + for (int i=0; isong.systemLen; i++) { + if (e->song.system[i]==DIV_SYSTEM_AMIGA) numAmiga++; + } + if (numAmiga && settings.iCannotWait) { + if (ImGui::BeginTabItem("Amiga Validation")) { + drawExportAmigaVal(true); + ImGui::EndTabItem(); + } + } + if (ImGui::BeginTabItem("Text")) { + drawExportText(true); + ImGui::EndTabItem(); + } + if (ImGui::BeginTabItem("Command Stream")) { + drawExportCommand(true); + ImGui::EndTabItem(); + } + ImGui::EndTabBar(); + } + } else switch (curExportType) { + case GUI_EXPORT_AUDIO: + drawExportAudio(true); + break; + case GUI_EXPORT_VGM: + drawExportVGM(true); + break; + case GUI_EXPORT_ZSM: + drawExportZSM(true); + break; + case GUI_EXPORT_AMIGA_VAL: + drawExportAmigaVal(true); + break; + case GUI_EXPORT_TEXT: + drawExportText(true); + break; + case GUI_EXPORT_CMD_STREAM: + drawExportCommand(true); + break; + default: + ImGui::Text("congratulations! you've unlocked a secret panel."); + if (ImGui::Button("Toggle hidden systems")) { + settings.hiddenSystems=!settings.hiddenSystems; + ImGui::CloseCurrentPopup(); + } + if (ImGui::Button("Toggle all instrument types")) { + settings.displayAllInsTypes=!settings.displayAllInsTypes; + ImGui::CloseCurrentPopup(); + } + if (ImGui::Button("Set pitch linearity to Partial")) { + e->song.linearPitch=1; + ImGui::CloseCurrentPopup(); + } + if (ImGui::Button("Enable multi-threading settings")) { + settings.showPool=1; + ImGui::CloseCurrentPopup(); + } + if (ImGui::Button("Set fat to max")) { + ImGuiStyle& sty=ImGui::GetStyle(); + sty.FramePadding=ImVec2(20.0f*dpiScale,20.0f*dpiScale); + sty.ItemSpacing=ImVec2(10.0f*dpiScale,10.0f*dpiScale); + sty.ItemInnerSpacing=ImVec2(10.0f*dpiScale,10.0f*dpiScale); + ImGui::CloseCurrentPopup(); + } + if (ImGui::Button("Set muscle and fat to zero")) { + ImGuiStyle& sty=ImGui::GetStyle(); + sty.FramePadding=ImVec2(0,0); + sty.ItemSpacing=ImVec2(0,0); + sty.ItemInnerSpacing=ImVec2(0,0); + ImGui::CloseCurrentPopup(); + } + if (ImGui::Button("Tell tildearrow this must be a mistake")) { + showError("yeah, it's a bug. write a bug report in the GitHub page and tell me how did you get here."); + ImGui::CloseCurrentPopup(); + } + break; + } +} diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index b323b1160..8ea7d50bd 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -4110,197 +4110,84 @@ bool FurnaceGUI::loop() { openFileDialog(GUI_FILE_SAVE_DMF_LEGACY); } ImGui::Separator(); - if (ImGui::BeginMenu("export audio...")) { - exitDisabledTimer=1; - if (ImGui::MenuItem("one file")) { - openFileDialog(GUI_FILE_EXPORT_AUDIO_ONE); + if (settings.exportOptionsLayout==0) { + if (ImGui::BeginMenu("export audio...")) { + drawExportAudio(); + ImGui::EndMenu(); } - if (ImGui::MenuItem("multiple files (one per chip)")) { - openFileDialog(GUI_FILE_EXPORT_AUDIO_PER_SYS); + if (ImGui::BeginMenu("export VGM...")) { + drawExportVGM(); + ImGui::EndMenu(); } - if (ImGui::MenuItem("multiple files (one per channel)")) { - openFileDialog(GUI_FILE_EXPORT_AUDIO_PER_CHANNEL); - } - if (ImGui::InputInt("Loops",&exportLoops,1,2)) { - if (exportLoops<0) exportLoops=0; - } - if (ImGui::InputDouble("Fade out (seconds)",&exportFadeOut,1.0,2.0,"%.1f")) { - if (exportFadeOut<0.0) exportFadeOut=0.0; - } - ImGui::EndMenu(); - } - if (ImGui::BeginMenu("export VGM...")) { - exitDisabledTimer=1; - ImGui::Text("settings:"); - if (ImGui::BeginCombo("format version",fmt::sprintf("%d.%.2x",vgmExportVersion>>8,vgmExportVersion&0xff).c_str())) { - for (int i=0; i<7; i++) { - if (ImGui::Selectable(fmt::sprintf("%d.%.2x",vgmVersions[i]>>8,vgmVersions[i]&0xff).c_str(),vgmExportVersion==vgmVersions[i])) { - vgmExportVersion=vgmVersions[i]; - } - } - ImGui::EndCombo(); - } - ImGui::Checkbox("loop",&vgmExportLoop); - if (vgmExportLoop && e->song.loopModality==2) { - ImGui::Text("loop trail:"); - ImGui::Indent(); - if (ImGui::RadioButton("auto-detect",vgmExportTrailingTicks==-1)) { - vgmExportTrailingTicks=-1; - } - if (ImGui::RadioButton("add one loop",vgmExportTrailingTicks==-2)) { - vgmExportTrailingTicks=-2; - } - if (ImGui::RadioButton("custom",vgmExportTrailingTicks>=0)) { - vgmExportTrailingTicks=0; - } - if (vgmExportTrailingTicks>=0) { - ImGui::SameLine(); - if (ImGui::InputInt("##TrailTicks",&vgmExportTrailingTicks,1,100)) { - if (vgmExportTrailingTicks<0) vgmExportTrailingTicks=0; - } - } - ImGui::Unindent(); - } - ImGui::Checkbox("add pattern change hints",&vgmExportPatternHints); - if (ImGui::IsItemHovered()) { - ImGui::SetTooltip( - "inserts data blocks on pattern changes.\n" - "useful if you are writing a playback routine.\n\n" - - "the format of a pattern change data block is:\n" - "67 66 FE ll ll ll ll 01 oo rr pp pp pp ...\n" - "- ll: length, a 32-bit little-endian number\n" - "- oo: order\n" - "- rr: initial row (a 0Dxx effect is able to select a different row)\n" - "- pp: pattern index (one per channel)\n\n" - - "pattern indexes are ordered as they appear in the song." - ); - } - ImGui::Checkbox("direct stream mode",&vgmExportDirectStream); - if (ImGui::IsItemHovered()) { - ImGui::SetTooltip( - "required for DualPCM and MSM6258 export.\n\n" - "allows for volume/direction changes when playing samples,\n" - "at the cost of a massive increase in file size." - ); - } - ImGui::Text("chips to export:"); - bool hasOneAtLeast=false; + int numZSMCompat=0; for (int i=0; isong.systemLen; i++) { - int minVersion=e->minVGMVersion(e->song.system[i]); - ImGui::BeginDisabled(minVersion>vgmExportVersion || minVersion==0); - ImGui::Checkbox(fmt::sprintf("%d. %s##_SYSV%d",i+1,getSystemName(e->song.system[i]),i).c_str(),&willExport[i]); - ImGui::EndDisabled(); - if (minVersion>vgmExportVersion) { - if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) { - ImGui::SetTooltip("this chip is only available in VGM %d.%.2x and higher!",minVersion>>8,minVersion&0xff); - } - } else if (minVersion==0) { - if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) { - ImGui::SetTooltip("this chip is not supported by the VGM format!"); - } - } else { - if (willExport[i]) hasOneAtLeast=true; + if ((e->song.system[i]==DIV_SYSTEM_VERA) || (e->song.system[i]==DIV_SYSTEM_YM2151)) numZSMCompat++; + } + if (numZSMCompat>0) { + if (ImGui::BeginMenu("export ZSM...")) { + drawExportZSM(); + ImGui::EndMenu(); } } - ImGui::Text("select the chip you wish to export,"); - ImGui::Text("but only up to %d of each type.",(vgmExportVersion>=0x151)?2:1); - if (hasOneAtLeast) { - if (ImGui::MenuItem("click to export")) { - openFileDialog(GUI_FILE_EXPORT_VGM); - } - } else { - ImGui::Text("nothing to export"); + int numAmiga=0; + for (int i=0; isong.systemLen; i++) { + if (e->song.system[i]==DIV_SYSTEM_AMIGA) numAmiga++; } - ImGui::EndMenu(); - } - int numZSMCompat=0; - for (int i=0; isong.systemLen; i++) { - if ((e->song.system[i] == DIV_SYSTEM_VERA) || (e->song.system[i] == DIV_SYSTEM_YM2151)) numZSMCompat++; - } - if (numZSMCompat > 0) { - if (ImGui::BeginMenu("export ZSM...")) { - exitDisabledTimer=1; - ImGui::Text("Commander X16 Zsound Music File"); - if (ImGui::InputInt("Tick Rate (Hz)",&zsmExportTickRate,1,10)) { - if (zsmExportTickRate<1) zsmExportTickRate=1; - if (zsmExportTickRate>44100) zsmExportTickRate=44100; - } - ImGui::Checkbox("loop",&zsmExportLoop); - ImGui::SameLine(); - ImGui::Checkbox("optimize size",&zsmExportOptimize); - ImGui::SameLine(); - if (ImGui::Button("Begin Export")) { - openFileDialog(GUI_FILE_EXPORT_ZSM); - ImGui::CloseCurrentPopup(); + if (numAmiga && settings.iCannotWait) { + if (ImGui::BeginMenu("export Amiga validation data...")) { + drawExportAmigaVal(); + ImGui::EndMenu(); } + } + if (ImGui::BeginMenu("export text...")) { + drawExportText(); ImGui::EndMenu(); } - } - int numAmiga=0; - for (int i=0; isong.systemLen; i++) { - if (e->song.system[i]==DIV_SYSTEM_AMIGA) numAmiga++; - } - if (numAmiga && settings.iCannotWait) { - if (ImGui::BeginMenu("export Amiga validation data...")) { - exitDisabledTimer=1; - ImGui::Text( - "this is NOT ROM export! only use for making sure the\n" - "Furnace Amiga emulator is working properly by\n" - "comparing it with real Amiga output." - ); - ImGui::AlignTextToFramePadding(); - ImGui::Text("Directory"); - ImGui::SameLine(); - ImGui::InputText("##AVDPath",&workingDirROMExport); - if (ImGui::Button("Bake Data")) { - std::vector out=e->buildROM(DIV_ROM_AMIGA_VALIDATION); - if (workingDirROMExport.size()>0) { - if (workingDirROMExport[workingDirROMExport.size()-1]!=DIR_SEPARATOR) workingDirROMExport+=DIR_SEPARATOR_STR; - } - for (DivROMExportOutput& i: out) { - String path=workingDirROMExport+i.name; - FILE* outFile=ps_fopen(path.c_str(),"wb"); - if (outFile!=NULL) { - fwrite(i.data->getFinalBuf(),1,i.data->size(),outFile); - fclose(outFile); - } - i.data->finish(); - delete i.data; - } - showError(fmt::sprintf("Done! Baked %d files.",(int)out.size())); - ImGui::CloseCurrentPopup(); - } + if (ImGui::BeginMenu("export command stream...")) { + drawExportCommand(); ImGui::EndMenu(); } - } - if (ImGui::BeginMenu("export text...")) { - exitDisabledTimer=1; - ImGui::Text( - "this option exports the song to a text file.\n" - ); - if (ImGui::Button("export")) { - openFileDialog(GUI_FILE_EXPORT_TEXT); + } else if (settings.exportOptionsLayout==2) { + if (ImGui::MenuItem("export audio...")) { + curExportType=GUI_EXPORT_AUDIO; + displayExport=true; } - ImGui::EndMenu(); - } - if (ImGui::BeginMenu("export command stream...")) { - exitDisabledTimer=1; - ImGui::Text( - "this option exports a text or binary file which\n" - "contains a dump of the internal command stream\n" - "produced when playing the song.\n\n" - - "technical/development use only!" - ); - if (ImGui::Button("export (binary)")) { - openFileDialog(GUI_FILE_EXPORT_CMDSTREAM_BINARY); + if (ImGui::MenuItem("export VGM...")) { + curExportType=GUI_EXPORT_VGM; + displayExport=true; } - if (ImGui::Button("export (text)")) { - openFileDialog(GUI_FILE_EXPORT_CMDSTREAM); + int numZSMCompat=0; + for (int i=0; isong.systemLen; i++) { + if ((e->song.system[i]==DIV_SYSTEM_VERA) || (e->song.system[i]==DIV_SYSTEM_YM2151)) numZSMCompat++; + } + if (numZSMCompat>0) { + if (ImGui::MenuItem("export ZSM...")) { + curExportType=GUI_EXPORT_ZSM; + displayExport=true; + } + } + int numAmiga=0; + for (int i=0; isong.systemLen; i++) { + if (e->song.system[i]==DIV_SYSTEM_AMIGA) numAmiga++; + } + if (numAmiga && settings.iCannotWait) { + if (ImGui::MenuItem("export Amiga validation data...")) { + curExportType=GUI_EXPORT_AMIGA_VAL; + displayExport=true; + } + } + if (ImGui::MenuItem("export text...")) { + curExportType=GUI_EXPORT_TEXT; + displayExport=true; + } + if (ImGui::MenuItem("export command stream...")) { + curExportType=GUI_EXPORT_CMD_STREAM; + displayExport=true; + } + } else { + if (ImGui::MenuItem("export...",BIND_FOR(GUI_ACTION_EXPORT))) { + displayExport=true; } - ImGui::EndMenu(); } ImGui::Separator(); if (!settings.classicChipOptions) { @@ -5507,6 +5394,11 @@ bool FurnaceGUI::loop() { ImGui::OpenPopup("Command Palette"); } + if (displayExport) { + displayExport=false; + ImGui::OpenPopup("Export"); + } + if (displayEditString) { ImGui::OpenPopup("EditString"); } @@ -5556,6 +5448,12 @@ bool FurnaceGUI::loop() { ImGui::EndPopup(); } + if (ImGui::BeginPopupModal("Export",NULL,ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoScrollWithMouse|ImGuiWindowFlags_NoScrollbar|ImGuiWindowFlags_AlwaysAutoResize)) { + ImGui::SetWindowPos(ImVec2(((canvasW)-ImGui::GetWindowSize().x)*0.5,((canvasH)-ImGui::GetWindowSize().y)*0.5)); + drawExport(); + ImGui::EndPopup(); + } + centerNextWindow("Error",canvasW,canvasH); if (ImGui::BeginPopupModal("Error",NULL,ImGuiWindowFlags_AlwaysAutoResize)) { ImGui::Text("%s",errorString.c_str()); @@ -7760,7 +7658,9 @@ FurnaceGUI::FurnaceGUI(): introSkipDo(false), introStopped(false), curTutorial(-1), - curTutorialStep(0) { + curTutorialStep(0), + audioExportType(0), + curExportType(GUI_EXPORT_NONE) { // value keys valueKeys[SDLK_0]=0; valueKeys[SDLK_1]=1; diff --git a/src/gui/gui.h b/src/gui/gui.h index fbdebcb49..d9a85290c 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -101,6 +101,7 @@ enum FurnaceGUIColors { GUI_COLOR_MODAL_BACKDROP, GUI_COLOR_HEADER, GUI_COLOR_TEXT, + GUI_COLOR_TEXT_DISABLED, GUI_COLOR_ACCENT_PRIMARY, GUI_COLOR_ACCENT_SECONDARY, GUI_COLOR_TITLE_INACTIVE, @@ -124,6 +125,36 @@ enum FurnaceGUIColors { GUI_COLOR_NAV_HIGHLIGHT, GUI_COLOR_NAV_WIN_HIGHLIGHT, GUI_COLOR_NAV_WIN_BACKDROP, + GUI_COLOR_PLOT_LINES, + GUI_COLOR_PLOT_LINES_HOVER, + GUI_COLOR_PLOT_HISTOGRAM, + GUI_COLOR_PLOT_HISTOGRAM_HOVER, + + GUI_COLOR_BUTTON, + GUI_COLOR_BUTTON_HOVER, + GUI_COLOR_BUTTON_ACTIVE, + GUI_COLOR_TAB, + GUI_COLOR_TAB_HOVER, + GUI_COLOR_TAB_ACTIVE, + GUI_COLOR_TAB_UNFOCUSED, + GUI_COLOR_TAB_UNFOCUSED_ACTIVE, + GUI_COLOR_IMGUI_HEADER, + GUI_COLOR_IMGUI_HEADER_HOVER, + GUI_COLOR_IMGUI_HEADER_ACTIVE, + GUI_COLOR_RESIZE_GRIP, + GUI_COLOR_RESIZE_GRIP_HOVER, + GUI_COLOR_RESIZE_GRIP_ACTIVE, + GUI_COLOR_WIDGET_BACKGROUND, + GUI_COLOR_WIDGET_BACKGROUND_HOVER, + GUI_COLOR_WIDGET_BACKGROUND_ACTIVE, + GUI_COLOR_SLIDER_GRAB, + GUI_COLOR_SLIDER_GRAB_ACTIVE, + GUI_COLOR_TITLE_BACKGROUND_ACTIVE, + GUI_COLOR_CHECK_MARK, + GUI_COLOR_TEXT_SELECTION, + GUI_COLOR_TABLE_ROW_EVEN, + GUI_COLOR_TABLE_ROW_ODD, + GUI_COLOR_TOGGLE_OFF, GUI_COLOR_TOGGLE_ON, GUI_COLOR_EDITING, @@ -437,6 +468,21 @@ enum FurnaceGUIMobileScenes { GUI_SCENE_OTHER, }; +enum FurnaceGUISettingGroups: unsigned int { + GUI_SETTINGS_GENERAL=1, + GUI_SETTINGS_AUDIO=2, + GUI_SETTINGS_MIDI=4, + GUI_SETTINGS_KEYBOARD=8, + GUI_SETTINGS_BEHAVIOR=16, + GUI_SETTINGS_FONT=32, + GUI_SETTINGS_APPEARANCE=64, + GUI_SETTINGS_LAYOUTS=128, + GUI_SETTINGS_COLOR=256, + GUI_SETTINGS_EMULATION=512, + + GUI_SETTINGS_ALL=0xffffffff +}; + enum FurnaceGUIFileDialogs { GUI_FILE_OPEN, GUI_FILE_OPEN_BACKUP, @@ -504,6 +550,17 @@ enum FurnaceGUIWarnings { GUI_WARN_GENERIC }; +enum FurnaceGUIExportTypes { + GUI_EXPORT_NONE=-1, + + GUI_EXPORT_AUDIO=0, + GUI_EXPORT_VGM, + GUI_EXPORT_ZSM, + GUI_EXPORT_CMD_STREAM, + GUI_EXPORT_AMIGA_VAL, + GUI_EXPORT_TEXT +}; + enum FurnaceGUIFMAlgs { FM_ALGS_4OP, FM_ALGS_2OP_OPL, @@ -517,6 +574,7 @@ enum FurnaceGUIActions { GUI_ACTION_OPEN_BACKUP, GUI_ACTION_SAVE, GUI_ACTION_SAVE_AS, + GUI_ACTION_EXPORT, GUI_ACTION_UNDO, GUI_ACTION_REDO, GUI_ACTION_PLAY_TOGGLE, @@ -836,6 +894,14 @@ struct SelectionPoint { xCoarse(0), xFine(0), y(0) {} }; +struct UndoRegion { + struct UndoRegionPoint { + int ord, x, y; + UndoRegionPoint(): + ord(0), x(0), y(0) {} + } begin, end; +}; + enum ActionType { GUI_UNDO_CHANGE_ORDER, GUI_UNDO_PATTERN_EDIT, @@ -1398,7 +1464,11 @@ class FurnaceGUI { bool vgmExportDirectStream, displayInsTypeList, displayWaveSizeList; bool portrait, injectBackUp, mobileMenuOpen, warnColorPushed; bool wantCaptureKeyboard, oldWantCaptureKeyboard, displayMacroMenu; +<<<<<<< HEAD bool displayNew, displayPalette, fullScreen, preserveChanPos, wantScrollList, noteInputPoly, notifyWaveChange; +======= + bool displayNew, displayExport, fullScreen, preserveChanPos, wantScrollList, noteInputPoly, notifyWaveChange; +>>>>>>> 07b037349b2419736359f25e114e5798e17bb327 bool displayPendingIns, pendingInsSingle, displayPendingRawSample, snesFilterHex, modTableHex, displayEditString; bool mobileEdit; bool killGraphics; @@ -1653,6 +1723,7 @@ class FurnaceGUI { int centerPopup; int insIconsStyle; int classicChipOptions; + int exportOptionsLayout; int wasapiEx; int chanOscThreads; int renderPoolThreads; @@ -1665,6 +1736,7 @@ class FurnaceGUI { int fontAutoHint; int fontAntiAlias; int selectAssetOnLoad; + int basicColors; unsigned int maxUndoSteps; String mainFontPath; String headFontPath; @@ -1848,11 +1920,12 @@ class FurnaceGUI { centerPopup(1), insIconsStyle(1), classicChipOptions(0), + exportOptionsLayout(1), wasapiEx(0), chanOscThreads(0), renderPoolThreads(0), showPool(0), - writeInsNames(1), + writeInsNames(0), readInsNames(1), fontBackend(1), fontHinting(0), @@ -1860,6 +1933,7 @@ class FurnaceGUI { fontAutoHint(1), fontAntiAlias(1), selectAssetOnLoad(1), + basicColors(1), maxUndoSteps(100), mainFontPath(""), headFontPath(""), @@ -2255,7 +2329,7 @@ class FurnaceGUI { int pianoOffset, pianoOffsetEdit; int pianoView, pianoInputPadMode; - //effect sorting + // effect sorting bool effectsShow[10]; // TX81Z @@ -2295,6 +2369,17 @@ class FurnaceGUI { // tutorial int curTutorial, curTutorialStep; + // export options + int audioExportType; + FurnaceGUIExportTypes curExportType; + + void drawExportAudio(bool onWindow=false); + void drawExportVGM(bool onWindow=false); + void drawExportZSM(bool onWindow=false); + void drawExportAmigaVal(bool onWindow=false); + void drawExportText(bool onWindow=false); + void drawExportCommand(bool onWindow=false); + void drawSSGEnv(unsigned char type, const ImVec2& size); void drawWaveform(unsigned char type, bool opz, const ImVec2& size); void drawAlgorithm(unsigned char alg, FurnaceGUIFMAlgs algType, const ImVec2& size); @@ -2406,7 +2491,11 @@ class FurnaceGUI { void drawSettings(); void drawDebug(); void drawNewSong(); +<<<<<<< HEAD void drawPalette(); +======= + void drawExport(); +>>>>>>> 07b037349b2419736359f25e114e5798e17bb327 void drawLog(); void drawEffectList(); void drawSubSongs(bool asChild=false); @@ -2432,6 +2521,9 @@ class FurnaceGUI { void resetColors(); void resetKeybinds(); + void readConfig(DivConfig& conf, FurnaceGUISettingGroups groups=GUI_SETTINGS_ALL); + void writeConfig(DivConfig& conf, FurnaceGUISettingGroups groups=GUI_SETTINGS_ALL); + void syncSettings(); void commitSettings(); void syncTutorial(); diff --git a/src/gui/guiConst.cpp b/src/gui/guiConst.cpp index 43d57864b..64c24ba97 100644 --- a/src/gui/guiConst.cpp +++ b/src/gui/guiConst.cpp @@ -537,6 +537,7 @@ const FurnaceGUIActionDef guiActions[GUI_ACTION_MAX]={ D("OPEN_BACKUP", "Restore backup", 0), D("SAVE", "Save file", FURKMOD_CMD|SDLK_s), D("SAVE_AS", "Save as", FURKMOD_CMD|FURKMOD_SHIFT|SDLK_s), + D("EXPORT", "Export", 0), D("UNDO", "Undo", FURKMOD_CMD|SDLK_z), #ifdef __APPLE__ D("REDO", "Redo", FURKMOD_CMD|FURKMOD_SHIFT|SDLK_z), @@ -804,6 +805,7 @@ const FurnaceGUIColorDef guiColors[GUI_COLOR_MAX]={ D(GUI_COLOR_MODAL_BACKDROP,"",ImVec4(0.0f,0.0f,0.0f,0.55f)), D(GUI_COLOR_HEADER,"",ImVec4(0.2f,0.2f,0.2f,1.0f)), D(GUI_COLOR_TEXT,"",ImVec4(1.0f,1.0f,1.0f,1.0f)), + D(GUI_COLOR_TEXT_DISABLED,"",ImVec4(0.5f,0.5f,0.5f,1.0f)), D(GUI_COLOR_ACCENT_PRIMARY,"",ImVec4(0.06f,0.53f,0.98f,1.0f)), D(GUI_COLOR_ACCENT_SECONDARY,"",ImVec4(0.26f,0.59f,0.98f,1.0f)), D(GUI_COLOR_TITLE_INACTIVE,"",ImVec4(0.04f,0.04f,0.04f,1.0f)), @@ -827,6 +829,36 @@ const FurnaceGUIColorDef guiColors[GUI_COLOR_MAX]={ D(GUI_COLOR_NAV_HIGHLIGHT,"",ImVec4(0.26f,0.59f,0.98f,1.0f)), D(GUI_COLOR_NAV_WIN_HIGHLIGHT,"",ImVec4(1.0f,1.0f,1.0f,0.7f)), D(GUI_COLOR_NAV_WIN_BACKDROP,"",ImVec4(0.8f,0.8f,0.8f,0.2f)), + D(GUI_COLOR_PLOT_LINES,"",ImVec4(0.61f,0.61f,0.61f,1.0f)), + D(GUI_COLOR_PLOT_LINES_HOVER,"",ImVec4(1.00f,0.43f,0.35f,1.00f)), + D(GUI_COLOR_PLOT_HISTOGRAM,"",ImVec4(0.0f,0.9f,1.0f,1.0f)), + D(GUI_COLOR_PLOT_HISTOGRAM_HOVER,"",ImVec4(0.0f,0.9f,1.0f,1.0f)), + + D(GUI_COLOR_BUTTON,"",ImVec4(0.085f,0.216f,0.343f,1.0f)), + D(GUI_COLOR_BUTTON_HOVER,"",ImVec4(0.075f,0.287f,0.49f,1.0f)), + D(GUI_COLOR_BUTTON_ACTIVE,"",ImVec4(0.06f,0.53f,0.98f,1.0f)), + D(GUI_COLOR_TAB,"",ImVec4(0.085f,0.216f,0.343f,1.0f)), + D(GUI_COLOR_TAB_HOVER,"",ImVec4(0.165f,0.313f,0.49f,1.0f)), + D(GUI_COLOR_TAB_ACTIVE,"",ImVec4(0.25f,0.47f,0.735f,1.0f)), + D(GUI_COLOR_TAB_UNFOCUSED,"",ImVec4(0.085f,0.216f,0.343f,1.0f)), + D(GUI_COLOR_TAB_UNFOCUSED_ACTIVE,"",ImVec4(0.075f,0.287f,0.49f,1.0f)), + D(GUI_COLOR_IMGUI_HEADER,"",ImVec4(0.083f,0.156f,0.245f,1.0f)), + D(GUI_COLOR_IMGUI_HEADER_HOVER,"",ImVec4(0.165f,0.313f,0.49f,1.0f)), + D(GUI_COLOR_IMGUI_HEADER_ACTIVE,"",ImVec4(0.26f,0.59f,0.98f,1.0f)), + D(GUI_COLOR_RESIZE_GRIP,"",ImVec4(0.083f,0.156f,0.245f,1.0f)), + D(GUI_COLOR_RESIZE_GRIP_HOVER,"",ImVec4(0.165f,0.313f,0.49f,1.0f)), + D(GUI_COLOR_RESIZE_GRIP_ACTIVE,"",ImVec4(0.26f,0.59f,0.98f,1.0f)), + D(GUI_COLOR_WIDGET_BACKGROUND,"",ImVec4(0.083f,0.156f,0.245f,1.0f)), + D(GUI_COLOR_WIDGET_BACKGROUND_HOVER,"",ImVec4(0.165f,0.313f,0.49f,1.0f)), + D(GUI_COLOR_WIDGET_BACKGROUND_ACTIVE,"",ImVec4(0.26f,0.59f,0.98f,1.0f)), + D(GUI_COLOR_SLIDER_GRAB,"",ImVec4(0.06f,0.53f,0.98f,1.0f)), + D(GUI_COLOR_SLIDER_GRAB_ACTIVE,"",ImVec4(0.06f,0.53f,0.98f,1.0f)), + D(GUI_COLOR_TITLE_BACKGROUND_ACTIVE,"",ImVec4(0.085f,0.216f,0.343f,1.0f)), + D(GUI_COLOR_CHECK_MARK,"",ImVec4(0.06f,0.53f,0.98f,1.0f)), + D(GUI_COLOR_TEXT_SELECTION,"",ImVec4(0.165f,0.313f,0.49f,1.0f)), + D(GUI_COLOR_TABLE_ROW_EVEN,"",ImVec4(0.0f,0.0f,0.0f,0.0f)), + D(GUI_COLOR_TABLE_ROW_ODD,"",ImVec4(1.0f,1.0f,1.0f,0.06f)), + D(GUI_COLOR_TOGGLE_OFF,"",ImVec4(0.2f,0.2f,0.2f,1.0f)), D(GUI_COLOR_TOGGLE_ON,"",ImVec4(0.2f,0.6f,0.2f,1.0f)), D(GUI_COLOR_EDITING,"",ImVec4(0.2f,0.1f,0.1f,1.0f)), diff --git a/src/gui/settings.cpp b/src/gui/settings.cpp index 51f0bde01..68fa26c23 100644 --- a/src/gui/settings.cpp +++ b/src/gui/settings.cpp @@ -1672,6 +1672,7 @@ void FurnaceGUI::drawSettings() { UI_KEYBIND_CONFIG(GUI_ACTION_OPEN_BACKUP); UI_KEYBIND_CONFIG(GUI_ACTION_SAVE); UI_KEYBIND_CONFIG(GUI_ACTION_SAVE_AS); + UI_KEYBIND_CONFIG(GUI_ACTION_EXPORT); UI_KEYBIND_CONFIG(GUI_ACTION_UNDO); UI_KEYBIND_CONFIG(GUI_ACTION_REDO); UI_KEYBIND_CONFIG(GUI_ACTION_PLAY_TOGGLE); @@ -2664,6 +2665,22 @@ void FurnaceGUI::drawSettings() { } ImGui::Unindent(); + ImGui::Text("Export options layout:"); + ImGui::Indent(); + if (ImGui::RadioButton("Sub-menus in File menu##eol0",settings.exportOptionsLayout==0)) { + settings.exportOptionsLayout=0; + settingsChanged=true; + } + if (ImGui::RadioButton("Modal window with tabs##eol1",settings.exportOptionsLayout==1)) { + settings.exportOptionsLayout=1; + settingsChanged=true; + } + if (ImGui::RadioButton("Modal windows with options in File menu##eol2",settings.exportOptionsLayout==2)) { + settings.exportOptionsLayout=2; + settingsChanged=true; + } + ImGui::Unindent(); + bool capitalMenuBarB=settings.capitalMenuBar; if (ImGui::Checkbox("Capitalize menu bar",&capitalMenuBarB)) { settings.capitalMenuBar=capitalMenuBarB; @@ -3175,26 +3192,84 @@ void FurnaceGUI::drawSettings() { if (ImGui::Button("Reset defaults")) { showWarning("Are you sure you want to reset the color scheme?",GUI_WARN_RESET_COLORS); } - if (ImGui::TreeNode("General")) { - ImGui::Text("Color scheme type:"); - ImGui::Indent(); - if (ImGui::RadioButton("Dark##gcb0",settings.guiColorsBase==0)) { - settings.guiColorsBase=0; - applyUISettings(false); - settingsChanged=true; + bool basicColorsB=!settings.basicColors; + if (ImGui::Checkbox("Guru mode",&basicColorsB)) { + settings.basicColors=!basicColorsB; + applyUISettings(false); + settingsChanged=true; + } + if (settings.basicColors) { + if (ImGui::TreeNode("Interface")) { + if (ImGui::SliderInt("Frame shading",&settings.guiColorsShading,0,100,"%d%%")) { + if (settings.guiColorsShading<0) settings.guiColorsShading=0; + if (settings.guiColorsShading>100) settings.guiColorsShading=100; + applyUISettings(false); + settingsChanged=true; + } + ImGui::Text("Color scheme type:"); + ImGui::Indent(); + if (ImGui::RadioButton("Dark##gcb0",settings.guiColorsBase==0)) { + settings.guiColorsBase=0; + applyUISettings(false); + settingsChanged=true; + } + if (ImGui::RadioButton("Light##gcb1",settings.guiColorsBase==1)) { + settings.guiColorsBase=1; + applyUISettings(false); + settingsChanged=true; + } + ImGui::Unindent(); + + ImGui::Text("Accent colors:"); + ImGui::Indent(); + UI_COLOR_CONFIG(GUI_COLOR_ACCENT_PRIMARY,"Primary"); + UI_COLOR_CONFIG(GUI_COLOR_ACCENT_SECONDARY,"Secondary"); + ImGui::Unindent(); + + ImGui::TreePop(); } - if (ImGui::RadioButton("Light##gcb1",settings.guiColorsBase==1)) { - settings.guiColorsBase=1; - applyUISettings(false); - settingsChanged=true; - } - ImGui::Unindent(); - if (ImGui::SliderInt("Frame shading",&settings.guiColorsShading,0,100,"%d%%")) { - if (settings.guiColorsShading<0) settings.guiColorsShading=0; - if (settings.guiColorsShading>100) settings.guiColorsShading=100; - applyUISettings(false); - settingsChanged=true; + } else { + if (ImGui::TreeNode("Interface")) { + if (ImGui::SliderInt("Frame shading",&settings.guiColorsShading,0,100,"%d%%")) { + if (settings.guiColorsShading<0) settings.guiColorsShading=0; + if (settings.guiColorsShading>100) settings.guiColorsShading=100; + applyUISettings(false); + settingsChanged=true; + } + + UI_COLOR_CONFIG(GUI_COLOR_BUTTON,"Button"); + UI_COLOR_CONFIG(GUI_COLOR_BUTTON_HOVER,"Button (hovered)"); + UI_COLOR_CONFIG(GUI_COLOR_BUTTON_ACTIVE,"Button (active)"); + UI_COLOR_CONFIG(GUI_COLOR_TAB,"Tab"); + UI_COLOR_CONFIG(GUI_COLOR_TAB_HOVER,"Tab (hovered)"); + UI_COLOR_CONFIG(GUI_COLOR_TAB_ACTIVE,"Tab (active)"); + UI_COLOR_CONFIG(GUI_COLOR_TAB_UNFOCUSED,"Tab (unfocused)"); + UI_COLOR_CONFIG(GUI_COLOR_TAB_UNFOCUSED_ACTIVE,"Tab (unfocused and active)"); + UI_COLOR_CONFIG(GUI_COLOR_IMGUI_HEADER,"ImGui header"); + UI_COLOR_CONFIG(GUI_COLOR_IMGUI_HEADER_HOVER,"ImGui header (hovered)"); + UI_COLOR_CONFIG(GUI_COLOR_IMGUI_HEADER_ACTIVE,"ImGui header (active)"); + UI_COLOR_CONFIG(GUI_COLOR_RESIZE_GRIP,"Resize grip"); + UI_COLOR_CONFIG(GUI_COLOR_RESIZE_GRIP_HOVER,"Resize grip (hovered)"); + UI_COLOR_CONFIG(GUI_COLOR_RESIZE_GRIP_ACTIVE,"Resize grip (active)"); + UI_COLOR_CONFIG(GUI_COLOR_WIDGET_BACKGROUND,"Widget background"); + UI_COLOR_CONFIG(GUI_COLOR_WIDGET_BACKGROUND_HOVER,"Widget background (hovered)"); + UI_COLOR_CONFIG(GUI_COLOR_WIDGET_BACKGROUND_ACTIVE,"Widget background (active)"); + UI_COLOR_CONFIG(GUI_COLOR_SLIDER_GRAB,"Slider grab"); + UI_COLOR_CONFIG(GUI_COLOR_SLIDER_GRAB_ACTIVE,"Slider grab (active)"); + UI_COLOR_CONFIG(GUI_COLOR_TITLE_BACKGROUND_ACTIVE,"Title background (active)"); + UI_COLOR_CONFIG(GUI_COLOR_CHECK_MARK,"Checkbox/radio button mark"); + UI_COLOR_CONFIG(GUI_COLOR_TEXT_SELECTION,"Text selection"); + UI_COLOR_CONFIG(GUI_COLOR_PLOT_LINES,"Line plot"); + UI_COLOR_CONFIG(GUI_COLOR_PLOT_LINES_HOVER,"Line plot (hovered)"); + UI_COLOR_CONFIG(GUI_COLOR_PLOT_HISTOGRAM,"Histogram plot"); + UI_COLOR_CONFIG(GUI_COLOR_PLOT_HISTOGRAM_HOVER,"Histogram plot (hovered)"); + UI_COLOR_CONFIG(GUI_COLOR_TABLE_ROW_EVEN,"Table row (even)"); + UI_COLOR_CONFIG(GUI_COLOR_TABLE_ROW_ODD,"Table row (odd)"); + + ImGui::TreePop(); } + } + if (ImGui::TreeNode("Interface (other)")) { UI_COLOR_CONFIG(GUI_COLOR_BACKGROUND,"Background"); UI_COLOR_CONFIG(GUI_COLOR_FRAME_BACKGROUND,"Window background"); UI_COLOR_CONFIG(GUI_COLOR_FRAME_BACKGROUND_CHILD,"Sub-window background"); @@ -3202,8 +3277,7 @@ void FurnaceGUI::drawSettings() { UI_COLOR_CONFIG(GUI_COLOR_MODAL_BACKDROP,"Modal backdrop"); UI_COLOR_CONFIG(GUI_COLOR_HEADER,"Header"); UI_COLOR_CONFIG(GUI_COLOR_TEXT,"Text"); - UI_COLOR_CONFIG(GUI_COLOR_ACCENT_PRIMARY,"Primary"); - UI_COLOR_CONFIG(GUI_COLOR_ACCENT_SECONDARY,"Secondary"); + UI_COLOR_CONFIG(GUI_COLOR_TEXT_DISABLED,"Text (disabled)"); UI_COLOR_CONFIG(GUI_COLOR_TITLE_INACTIVE,"Title bar (inactive)"); UI_COLOR_CONFIG(GUI_COLOR_TITLE_COLLAPSED,"Title bar (collapsed)"); UI_COLOR_CONFIG(GUI_COLOR_MENU_BAR,"Menu bar"); @@ -3224,11 +3298,11 @@ void FurnaceGUI::drawSettings() { UI_COLOR_CONFIG(GUI_COLOR_DRAG_DROP_TARGET,"Drag and drop target"); UI_COLOR_CONFIG(GUI_COLOR_NAV_WIN_HIGHLIGHT,"Window switcher (highlight)"); UI_COLOR_CONFIG(GUI_COLOR_NAV_WIN_BACKDROP,"Window switcher backdrop"); + ImGui::TreePop(); + } + if (ImGui::TreeNode("Miscellaneous")) { UI_COLOR_CONFIG(GUI_COLOR_TOGGLE_ON,"Toggle on"); UI_COLOR_CONFIG(GUI_COLOR_TOGGLE_OFF,"Toggle off"); - UI_COLOR_CONFIG(GUI_COLOR_EDITING,"Editing"); - UI_COLOR_CONFIG(GUI_COLOR_EDITING_CLONE,"Editing (will clone)"); - UI_COLOR_CONFIG(GUI_COLOR_SONG_LOOP,"Song loop"); UI_COLOR_CONFIG(GUI_COLOR_PLAYBACK_STAT,"Playback status"); UI_COLOR_CONFIG(GUI_COLOR_DESTRUCTIVE,"Destructive hint"); UI_COLOR_CONFIG(GUI_COLOR_WARNING,"Warning hint"); @@ -3289,6 +3363,7 @@ void FurnaceGUI::drawSettings() { if (ImGui::TreeNode("Orders")) { UI_COLOR_CONFIG(GUI_COLOR_ORDER_ROW_INDEX,"Order number"); UI_COLOR_CONFIG(GUI_COLOR_ORDER_ACTIVE,"Playing order background"); + UI_COLOR_CONFIG(GUI_COLOR_SONG_LOOP,"Song loop"); UI_COLOR_CONFIG(GUI_COLOR_ORDER_SELECTED,"Selected order"); UI_COLOR_CONFIG(GUI_COLOR_ORDER_SIMILAR,"Similar patterns"); UI_COLOR_CONFIG(GUI_COLOR_ORDER_INACTIVE,"Inactive patterns"); @@ -3401,6 +3476,8 @@ void FurnaceGUI::drawSettings() { } if (ImGui::TreeNode("Pattern")) { UI_COLOR_CONFIG(GUI_COLOR_PATTERN_PLAY_HEAD,"Playhead"); + UI_COLOR_CONFIG(GUI_COLOR_EDITING,"Editing"); + UI_COLOR_CONFIG(GUI_COLOR_EDITING_CLONE,"Editing (will clone)"); UI_COLOR_CONFIG(GUI_COLOR_PATTERN_CURSOR,"Cursor"); UI_COLOR_CONFIG(GUI_COLOR_PATTERN_CURSOR_HOVER,"Cursor (hovered)"); UI_COLOR_CONFIG(GUI_COLOR_PATTERN_CURSOR_ACTIVE,"Cursor (clicked)"); @@ -3623,207 +3700,327 @@ void FurnaceGUI::drawSettings() { x=maxV; \ } -void FurnaceGUI::syncSettings() { - settings.mainFontSize=e->getConfInt("mainFontSize",18); - settings.headFontSize=e->getConfInt("headFontSize",27); - settings.patFontSize=e->getConfInt("patFontSize",18); - settings.iconSize=e->getConfInt("iconSize",16); - settings.audioEngine=(e->getConfString("audioEngine","SDL")=="SDL")?1:0; - if (e->getConfString("audioEngine","SDL")=="JACK") { - settings.audioEngine=DIV_AUDIO_JACK; - } else if (e->getConfString("audioEngine","SDL")=="PortAudio") { - settings.audioEngine=DIV_AUDIO_PORTAUDIO; - } else { - settings.audioEngine=DIV_AUDIO_SDL; +void FurnaceGUI::readConfig(DivConfig& conf, FurnaceGUISettingGroups groups) { + if (groups&GUI_SETTINGS_GENERAL) { + settings.renderDriver=conf.getString("renderDriver",""); + settings.noDMFCompat=conf.getInt("noDMFCompat",0); + + settings.dpiScale=conf.getFloat("dpiScale",0.0f); + + settings.initialSysName=conf.getString("initialSysName",""); + + // initial system + String initialSys2=conf.getString("initialSys2",""); + bool oldVol=conf.getInt("configVersion",DIV_ENGINE_VERSION)<135; + if (initialSys2.empty()) { + initialSys2=e->decodeSysDesc(conf.getString("initialSys","")); + oldVol=false; + } + settings.initialSys.clear(); + settings.initialSys.loadFromBase64(initialSys2.c_str()); + if (settings.initialSys.getInt("id0",0)==0) { + settings.initialSys.clear(); + settings.initialSys.set("id0",e->systemToFileFur(DIV_SYSTEM_YM2612)); + settings.initialSys.set("vol0",1.0f); + settings.initialSys.set("pan0",0.0f); + settings.initialSys.set("fr0",0.0f); + settings.initialSys.set("flags0",""); + settings.initialSys.set("id1",e->systemToFileFur(DIV_SYSTEM_SMS)); + settings.initialSys.set("vol1",0.5f); + settings.initialSys.set("pan1",0); + settings.initialSys.set("fr1",0); + settings.initialSys.set("flags1",""); + } else { + if (oldVol) { + for (int i=0; settings.initialSys.getInt(fmt::sprintf("id%d",i),0); i++) { + float newVol=settings.initialSys.getInt(fmt::sprintf("vol%d",i),64); + float newPan=settings.initialSys.getInt(fmt::sprintf("pan%d",i),0); + newVol/=64.0f; + newPan/=127.0f; + settings.initialSys.set(fmt::sprintf("vol%d",i),newVol); + settings.initialSys.set(fmt::sprintf("pan%d",i),newPan); + } + conf.set("initialSys2",settings.initialSys.toBase64()); + conf.set("configVersion",DIV_ENGINE_VERSION); + } + } + + settings.noThreadedInput=conf.getInt("noThreadedInput",0); + settings.powerSave=conf.getInt("powerSave",POWER_SAVE_DEFAULT); + settings.eventDelay=conf.getInt("eventDelay",0); + + settings.renderBackend=conf.getString("renderBackend",GUI_BACKEND_DEFAULT_NAME); + settings.renderClearPos=conf.getInt("renderClearPos",0); + + settings.chanOscThreads=conf.getInt("chanOscThreads",0); + settings.renderPoolThreads=conf.getInt("renderPoolThreads",0); + settings.showPool=conf.getInt("showPool",0); + settings.writeInsNames=conf.getInt("writeInsNames",0); + settings.readInsNames=conf.getInt("readInsNames",1); + settings.defaultAuthorName=conf.getString("defaultAuthorName",""); + + settings.hiddenSystems=conf.getInt("hiddenSystems",0); + settings.allowEditDocking=conf.getInt("allowEditDocking",1); + settings.sysFileDialog=conf.getInt("sysFileDialog",SYS_FILE_DIALOG_DEFAULT); + settings.displayAllInsTypes=conf.getInt("displayAllInsTypes",0); + settings.displayPartial=conf.getInt("displayPartial",0); + + settings.blankIns=conf.getInt("blankIns",0); + + settings.saveWindowPos=conf.getInt("saveWindowPos",1); + + settings.saveUnusedPatterns=conf.getInt("saveUnusedPatterns",0); + settings.maxRecentFile=conf.getInt("maxRecentFile",10); + + settings.persistFadeOut=conf.getInt("persistFadeOut",1); + settings.exportLoops=conf.getInt("exportLoops",0); + settings.exportFadeOut=conf.getDouble("exportFadeOut",0.0); + + settings.doubleClickTime=conf.getFloat("doubleClickTime",0.3f); + settings.disableFadeIn=conf.getInt("disableFadeIn",0); + settings.alwaysPlayIntro=conf.getInt("alwaysPlayIntro",0); + settings.iCannotWait=conf.getInt("iCannotWait",0); + + settings.compress=conf.getInt("compress",1); + settings.newPatternFormat=conf.getInt("newPatternFormat",1); + settings.newSongBehavior=conf.getInt("newSongBehavior",0); + settings.playOnLoad=conf.getInt("playOnLoad",0); + settings.centerPopup=conf.getInt("centerPopup",1); + } + + if (groups&GUI_SETTINGS_AUDIO) { + settings.audioEngine=(conf.getString("audioEngine","SDL")=="SDL")?1:0; + if (conf.getString("audioEngine","SDL")=="JACK") { + settings.audioEngine=DIV_AUDIO_JACK; + } else if (conf.getString("audioEngine","SDL")=="PortAudio") { + settings.audioEngine=DIV_AUDIO_PORTAUDIO; + } else { + settings.audioEngine=DIV_AUDIO_SDL; + } + settings.audioDevice=conf.getString("audioDevice",""); + settings.sdlAudioDriver=conf.getString("sdlAudioDriver",""); + settings.audioQuality=conf.getInt("audioQuality",0); + settings.audioHiPass=conf.getInt("audioHiPass",1); + settings.audioBufSize=conf.getInt("audioBufSize",1024); + settings.audioRate=conf.getInt("audioRate",44100); + settings.audioChans=conf.getInt("audioChans",2); + + settings.lowLatency=conf.getInt("lowLatency",0); + + settings.metroVol=conf.getInt("metroVol",100); + settings.sampleVol=conf.getInt("sampleVol",50); + + settings.wasapiEx=conf.getInt("wasapiEx",0); + + settings.clampSamples=conf.getInt("clampSamples",0); + settings.forceMono=conf.getInt("forceMono",0); + } + + if (groups&GUI_SETTINGS_MIDI) { + settings.midiInDevice=conf.getString("midiInDevice",""); + settings.midiOutDevice=conf.getString("midiOutDevice",""); + settings.midiOutClock=conf.getInt("midiOutClock",0); + settings.midiOutTime=conf.getInt("midiOutTime",0); + settings.midiOutProgramChange=conf.getInt("midiOutProgramChange",0); + settings.midiOutMode=conf.getInt("midiOutMode",1); + settings.midiOutTimeRate=conf.getInt("midiOutTimeRate",0); + } + + if (groups&GUI_SETTINGS_KEYBOARD) { + // keybinds + for (int i=0; igetConfString("audioDevice",""); - settings.audioChans=e->getConfInt("audioChans",2); - settings.midiInDevice=e->getConfString("midiInDevice",""); - settings.midiOutDevice=e->getConfString("midiOutDevice",""); - settings.renderDriver=e->getConfString("renderDriver",""); - settings.sdlAudioDriver=e->getConfString("sdlAudioDriver",""); - settings.audioQuality=e->getConfInt("audioQuality",0); - settings.audioHiPass=e->getConfInt("audioHiPass",1); - 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.snCore=e->getConfInt("snCore",0); - settings.nesCore=e->getConfInt("nesCore",0); - settings.fdsCore=e->getConfInt("fdsCore",0); - settings.c64Core=e->getConfInt("c64Core",0); - settings.pokeyCore=e->getConfInt("pokeyCore",1); - settings.opnCore=e->getConfInt("opnCore",1); - settings.opl2Core=e->getConfInt("opl2Core",0); - settings.opl3Core=e->getConfInt("opl3Core",0); - settings.arcadeCoreRender=e->getConfInt("arcadeCoreRender",1); - settings.ym2612CoreRender=e->getConfInt("ym2612CoreRender",0); - settings.snCoreRender=e->getConfInt("snCoreRender",0); - settings.nesCoreRender=e->getConfInt("nesCoreRender",0); - settings.fdsCoreRender=e->getConfInt("fdsCoreRender",1); - settings.c64CoreRender=e->getConfInt("c64CoreRender",1); - settings.pokeyCoreRender=e->getConfInt("pokeyCoreRender",1); - settings.opnCoreRender=e->getConfInt("opnCoreRender",1); - settings.opl2CoreRender=e->getConfInt("opl2CoreRender",0); - settings.opl3CoreRender=e->getConfInt("opl3CoreRender",0); - settings.pcSpeakerOutMethod=e->getConfInt("pcSpeakerOutMethod",0); - settings.yrw801Path=e->getConfString("yrw801Path",""); - settings.tg100Path=e->getConfString("tg100Path",""); - settings.mu5Path=e->getConfString("mu5Path",""); - settings.mainFont=e->getConfInt("mainFont",0); - settings.headFont=e->getConfInt("headFont",0); - settings.patFont=e->getConfInt("patFont",0); - settings.mainFontPath=e->getConfString("mainFontPath",""); - settings.headFontPath=e->getConfString("headFontPath",""); - settings.patFontPath=e->getConfString("patFontPath",""); - settings.patRowsBase=e->getConfInt("patRowsBase",0); - settings.orderRowsBase=e->getConfInt("orderRowsBase",1); - settings.soloAction=e->getConfInt("soloAction",0); - settings.pullDeleteBehavior=e->getConfInt("pullDeleteBehavior",1); - settings.wrapHorizontal=e->getConfInt("wrapHorizontal",0); - settings.wrapVertical=e->getConfInt("wrapVertical",0); - settings.macroView=e->getConfInt("macroView",0); - settings.fmNames=e->getConfInt("fmNames",0); - settings.allowEditDocking=e->getConfInt("allowEditDocking",1); - settings.chipNames=e->getConfInt("chipNames",0); - settings.overflowHighlight=e->getConfInt("overflowHighlight",0); - settings.partyTime=e->getConfInt("partyTime",0); - settings.flatNotes=e->getConfInt("flatNotes",0); - settings.germanNotation=e->getConfInt("germanNotation",0); - settings.stepOnDelete=e->getConfInt("stepOnDelete",0); - settings.scrollStep=e->getConfInt("scrollStep",0); - settings.sysSeparators=e->getConfInt("sysSeparators",1); - settings.forceMono=e->getConfInt("forceMono",0); - settings.controlLayout=e->getConfInt("controlLayout",3); - settings.statusDisplay=e->getConfInt("statusDisplay",0); - settings.dpiScale=e->getConfFloat("dpiScale",0.0f); - settings.viewPrevPattern=e->getConfInt("viewPrevPattern",1); - settings.guiColorsBase=e->getConfInt("guiColorsBase",0); - settings.guiColorsShading=e->getConfInt("guiColorsShading",0); - settings.avoidRaisingPattern=e->getConfInt("avoidRaisingPattern",0); - settings.insFocusesPattern=e->getConfInt("insFocusesPattern",1); - settings.stepOnInsert=e->getConfInt("stepOnInsert",0); - settings.unifiedDataView=e->getConfInt("unifiedDataView",0); - settings.sysFileDialog=e->getConfInt("sysFileDialog",SYS_FILE_DIALOG_DEFAULT); - settings.roundedWindows=e->getConfInt("roundedWindows",1); - settings.roundedButtons=e->getConfInt("roundedButtons",1); - settings.roundedMenus=e->getConfInt("roundedMenus",0); - settings.loadJapanese=e->getConfInt("loadJapanese",0); - settings.loadChinese=e->getConfInt("loadChinese",0); - settings.loadChineseTraditional=e->getConfInt("loadChineseTraditional",0); - settings.loadKorean=e->getConfInt("loadKorean",0); - settings.fmLayout=e->getConfInt("fmLayout",4); - settings.sampleLayout=e->getConfInt("sampleLayout",0); - settings.waveLayout=e->getConfInt("waveLayout",0); - settings.susPosition=e->getConfInt("susPosition",0); - settings.effectCursorDir=e->getConfInt("effectCursorDir",1); - settings.cursorPastePos=e->getConfInt("cursorPastePos",1); - settings.titleBarInfo=e->getConfInt("titleBarInfo",1); - settings.titleBarSys=e->getConfInt("titleBarSys",1); - settings.frameBorders=e->getConfInt("frameBorders",0); - settings.effectDeletionAltersValue=e->getConfInt("effectDeletionAltersValue",1); - settings.oscRoundedCorners=e->getConfInt("oscRoundedCorners",1); - settings.oscTakesEntireWindow=e->getConfInt("oscTakesEntireWindow",0); - settings.oscBorder=e->getConfInt("oscBorder",1); - settings.oscEscapesBoundary=e->getConfInt("oscEscapesBoundary",0); - settings.oscMono=e->getConfInt("oscMono",1); - settings.oscAntiAlias=e->getConfInt("oscAntiAlias",1); - settings.separateFMColors=e->getConfInt("separateFMColors",0); - settings.insEditColorize=e->getConfInt("insEditColorize",0); - settings.metroVol=e->getConfInt("metroVol",100); - settings.sampleVol=e->getConfInt("sampleVol",50); - settings.pushNibble=e->getConfInt("pushNibble",0); - settings.scrollChangesOrder=e->getConfInt("scrollChangesOrder",0); - settings.oplStandardWaveNames=e->getConfInt("oplStandardWaveNames",0); - settings.cursorMoveNoScroll=e->getConfInt("cursorMoveNoScroll",0); - settings.lowLatency=e->getConfInt("lowLatency",0); - settings.notePreviewBehavior=e->getConfInt("notePreviewBehavior",1); - settings.powerSave=e->getConfInt("powerSave",POWER_SAVE_DEFAULT); - settings.absorbInsInput=e->getConfInt("absorbInsInput",0); - settings.eventDelay=e->getConfInt("eventDelay",0); - settings.moveWindowTitle=e->getConfInt("moveWindowTitle",1); - settings.hiddenSystems=e->getConfInt("hiddenSystems",0); - settings.horizontalDataView=e->getConfInt("horizontalDataView",0); - settings.noMultiSystem=e->getConfInt("noMultiSystem",0); - settings.oldMacroVSlider=e->getConfInt("oldMacroVSlider",0); - settings.displayAllInsTypes=e->getConfInt("displayAllInsTypes",0); - settings.displayPartial=e->getConfInt("displayPartial",0); - settings.noteCellSpacing=e->getConfInt("noteCellSpacing",0); - settings.insCellSpacing=e->getConfInt("insCellSpacing",0); - settings.volCellSpacing=e->getConfInt("volCellSpacing",0); - settings.effectCellSpacing=e->getConfInt("effectCellSpacing",0); - settings.effectValCellSpacing=e->getConfInt("effectValCellSpacing",0); - settings.doubleClickColumn=e->getConfInt("doubleClickColumn",1); - settings.blankIns=e->getConfInt("blankIns",0); - settings.dragMovesSelection=e->getConfInt("dragMovesSelection",2); - settings.unsignedDetune=e->getConfInt("unsignedDetune",0); - settings.noThreadedInput=e->getConfInt("noThreadedInput",0); - settings.saveWindowPos=e->getConfInt("saveWindowPos",1); - settings.initialSysName=e->getConfString("initialSysName",""); - settings.clampSamples=e->getConfInt("clampSamples",0); - settings.noteOffLabel=e->getConfString("noteOffLabel","OFF"); - settings.noteRelLabel=e->getConfString("noteRelLabel","==="); - settings.macroRelLabel=e->getConfString("macroRelLabel","REL"); - settings.emptyLabel=e->getConfString("emptyLabel","..."); - settings.emptyLabel2=e->getConfString("emptyLabel2",".."); - settings.saveUnusedPatterns=e->getConfInt("saveUnusedPatterns",0); - settings.channelColors=e->getConfInt("channelColors",1); - settings.channelTextColors=e->getConfInt("channelTextColors",0); - settings.channelStyle=e->getConfInt("channelStyle",1); - settings.channelVolStyle=e->getConfInt("channelVolStyle",0); - settings.channelFeedbackStyle=e->getConfInt("channelFeedbackStyle",1); - settings.channelFont=e->getConfInt("channelFont",1); - settings.channelTextCenter=e->getConfInt("channelTextCenter",1); - settings.maxRecentFile=e->getConfInt("maxRecentFile",10); - settings.midiOutClock=e->getConfInt("midiOutClock",0); - settings.midiOutTime=e->getConfInt("midiOutTime",0); - settings.midiOutProgramChange=e->getConfInt("midiOutProgramChange",0); - settings.midiOutMode=e->getConfInt("midiOutMode",1); - settings.midiOutTimeRate=e->getConfInt("midiOutTimeRate",0); - settings.centerPattern=e->getConfInt("centerPattern",0); - settings.ordersCursor=e->getConfInt("ordersCursor",1); - settings.persistFadeOut=e->getConfInt("persistFadeOut",1); - settings.exportLoops=e->getConfInt("exportLoops",0); - settings.exportFadeOut=e->getConfDouble("exportFadeOut",0.0); - settings.macroLayout=e->getConfInt("macroLayout",0); - settings.doubleClickTime=e->getConfFloat("doubleClickTime",0.3f); - settings.oneDigitEffects=e->getConfInt("oneDigitEffects",0); - settings.disableFadeIn=e->getConfInt("disableFadeIn",0); - settings.alwaysPlayIntro=e->getConfInt("alwaysPlayIntro",0); - settings.cursorFollowsOrder=e->getConfInt("cursorFollowsOrder",1); - settings.iCannotWait=e->getConfInt("iCannotWait",0); - settings.orderButtonPos=e->getConfInt("orderButtonPos",2); - settings.compress=e->getConfInt("compress",1); - settings.newPatternFormat=e->getConfInt("newPatternFormat",1); - settings.renderBackend=e->getConfString("renderBackend",GUI_BACKEND_DEFAULT_NAME); - settings.renderClearPos=e->getConfInt("renderClearPos",0); - settings.insertBehavior=e->getConfInt("insertBehavior",1); - settings.pullDeleteRow=e->getConfInt("pullDeleteRow",1); - settings.newSongBehavior=e->getConfInt("newSongBehavior",0); - settings.memUsageUnit=e->getConfInt("memUsageUnit",1); - settings.cursorFollowsWheel=e->getConfInt("cursorFollowsWheel",0); - settings.noDMFCompat=e->getConfInt("noDMFCompat",0); - settings.removeInsOff=e->getConfInt("removeInsOff",0); - settings.removeVolOff=e->getConfInt("removeVolOff",0); - settings.playOnLoad=e->getConfInt("playOnLoad",0); - settings.insTypeMenu=e->getConfInt("insTypeMenu",1); - settings.capitalMenuBar=e->getConfInt("capitalMenuBar",0); - settings.centerPopup=e->getConfInt("centerPopup",1); - settings.insIconsStyle=e->getConfInt("insIconsStyle",1); - settings.classicChipOptions=e->getConfInt("classicChipOptions",0); - settings.wasapiEx=e->getConfInt("wasapiEx",0); - settings.chanOscThreads=e->getConfInt("chanOscThreads",0); - settings.renderPoolThreads=e->getConfInt("renderPoolThreads",0); - settings.showPool=e->getConfInt("showPool",0); - settings.writeInsNames=e->getConfInt("writeInsNames",1); - settings.readInsNames=e->getConfInt("readInsNames",1); - settings.defaultAuthorName=e->getConfString("defaultAuthorName",""); - settings.fontBackend=e->getConfInt("fontBackend",FONT_BACKEND_DEFAULT); - settings.fontHinting=e->getConfInt("fontHinting",0); - settings.fontBitmap=e->getConfInt("fontBitmap",0); - settings.fontAutoHint=e->getConfInt("fontAutoHint",1); - settings.fontAntiAlias=e->getConfInt("fontAntiAlias",1); - settings.selectAssetOnLoad=e->getConfInt("selectAssetOnLoad",1); clampSetting(settings.mainFontSize,2,96); clampSetting(settings.headFontSize,2,96); @@ -3864,7 +4061,6 @@ void FurnaceGUI::syncSettings() { clampSetting(settings.pullDeleteBehavior,0,1); clampSetting(settings.wrapHorizontal,0,2); clampSetting(settings.wrapVertical,0,3); - clampSetting(settings.macroView,0,1); clampSetting(settings.fmNames,0,2); clampSetting(settings.allowEditDocking,0,1); clampSetting(settings.chipNames,0,1); @@ -3978,6 +4174,7 @@ void FurnaceGUI::syncSettings() { clampSetting(settings.centerPopup,0,1); clampSetting(settings.insIconsStyle,0,2); clampSetting(settings.classicChipOptions,0,1); + clampSetting(settings.exportOptionsLayout,0,2); clampSetting(settings.wasapiEx,0,1); clampSetting(settings.chanOscThreads,0,256); clampSetting(settings.renderPoolThreads,0,DIV_MAX_CHIPS); @@ -3990,52 +4187,305 @@ void FurnaceGUI::syncSettings() { clampSetting(settings.fontAutoHint,0,2); clampSetting(settings.fontAntiAlias,0,1); clampSetting(settings.selectAssetOnLoad,0,1); + clampSetting(settings.basicColors,0,1); if (settings.exportLoops<0.0) settings.exportLoops=0.0; - if (settings.exportFadeOut<0.0) settings.exportFadeOut=0.0; + if (settings.exportFadeOut<0.0) settings.exportFadeOut=0.0; +} - String initialSys2=e->getConfString("initialSys2",""); - bool oldVol=e->getConfInt("configVersion",DIV_ENGINE_VERSION)<135; - if (initialSys2.empty()) { - initialSys2=e->decodeSysDesc(e->getConfString("initialSys","")); - oldVol=false; +void FurnaceGUI::writeConfig(DivConfig& conf, FurnaceGUISettingGroups groups) { + // general + if (groups&GUI_SETTINGS_GENERAL) { + conf.set("renderDriver",settings.renderDriver); + conf.set("noDMFCompat",settings.noDMFCompat); + + conf.set("dpiScale",settings.dpiScale); + + conf.set("initialSys2",settings.initialSys.toBase64()); + conf.set("initialSysName",settings.initialSysName); + + conf.set("noThreadedInput",settings.noThreadedInput); + conf.set("powerSave",settings.powerSave); + conf.set("eventDelay",settings.eventDelay); + + conf.set("renderBackend",settings.renderBackend); + conf.set("renderClearPos",settings.renderClearPos); + + conf.set("chanOscThreads",settings.chanOscThreads); + conf.set("renderPoolThreads",settings.renderPoolThreads); + conf.set("showPool",settings.showPool); + conf.set("writeInsNames",settings.writeInsNames); + conf.set("readInsNames",settings.readInsNames); + conf.set("defaultAuthorName",settings.defaultAuthorName); + + conf.set("hiddenSystems",settings.hiddenSystems); + conf.set("allowEditDocking",settings.allowEditDocking); + conf.set("sysFileDialog",settings.sysFileDialog); + conf.set("displayAllInsTypes",settings.displayAllInsTypes); + conf.set("displayPartial",settings.displayPartial); + + conf.set("blankIns",settings.blankIns); + + conf.set("saveWindowPos",settings.saveWindowPos); + + conf.set("saveUnusedPatterns",settings.saveUnusedPatterns); + conf.set("maxRecentFile",settings.maxRecentFile); + + conf.set("persistFadeOut",settings.persistFadeOut); + conf.set("exportLoops",settings.exportLoops); + conf.set("exportFadeOut",settings.exportFadeOut); + + conf.set("doubleClickTime",settings.doubleClickTime); + conf.set("disableFadeIn",settings.disableFadeIn); + conf.set("alwaysPlayIntro",settings.alwaysPlayIntro); + conf.set("iCannotWait",settings.iCannotWait); + + conf.set("compress",settings.compress); + conf.set("newPatternFormat",settings.newPatternFormat); + conf.set("newSongBehavior",settings.newSongBehavior); + conf.set("playOnLoad",settings.playOnLoad); + conf.set("centerPopup",settings.centerPopup); } - settings.initialSys.clear(); - settings.initialSys.loadFromBase64(initialSys2.c_str()); - if (settings.initialSys.getInt("id0",0)==0) { - settings.initialSys.clear(); - settings.initialSys.set("id0",e->systemToFileFur(DIV_SYSTEM_YM2612)); - settings.initialSys.set("vol0",1.0f); - settings.initialSys.set("pan0",0.0f); - settings.initialSys.set("fr0",0.0f); - settings.initialSys.set("flags0",""); - settings.initialSys.set("id1",e->systemToFileFur(DIV_SYSTEM_SMS)); - settings.initialSys.set("vol1",0.5f); - settings.initialSys.set("pan1",0); - settings.initialSys.set("fr1",0); - settings.initialSys.set("flags1",""); - } else { - if (oldVol) { - for (int i=0; settings.initialSys.getInt(fmt::sprintf("id%d",i),0); i++) { - float newVol=settings.initialSys.getInt(fmt::sprintf("vol%d",i),64); - float newPan=settings.initialSys.getInt(fmt::sprintf("pan%d",i),0); - newVol/=64.0f; - newPan/=127.0f; - settings.initialSys.set(fmt::sprintf("vol%d",i),newVol); - settings.initialSys.set(fmt::sprintf("pan%d",i),newPan); - } - e->setConf("initialSys2",settings.initialSys.toBase64()); - e->setConf("configVersion",DIV_ENGINE_VERSION); + + // audio + if (groups&GUI_SETTINGS_AUDIO) { + conf.set("audioEngine",String(audioBackends[settings.audioEngine])); + conf.set("audioDevice",settings.audioDevice); + conf.set("sdlAudioDriver",settings.sdlAudioDriver); + conf.set("audioQuality",settings.audioQuality); + conf.set("audioHiPass",settings.audioHiPass); + conf.set("audioBufSize",settings.audioBufSize); + conf.set("audioRate",settings.audioRate); + conf.set("audioChans",settings.audioChans); + + conf.set("lowLatency",settings.lowLatency); + + conf.set("metroVol",settings.metroVol); + conf.set("sampleVol",settings.sampleVol); + + conf.set("wasapiEx",settings.wasapiEx); + + conf.set("clampSamples",settings.clampSamples); + conf.set("forceMono",settings.forceMono); + } + + // MIDI + if (groups&GUI_SETTINGS_MIDI) { + conf.set("midiInDevice",settings.midiInDevice); + conf.set("midiOutDevice",settings.midiOutDevice); + conf.set("midiOutClock",settings.midiOutClock); + conf.set("midiOutTime",settings.midiOutTime); + conf.set("midiOutProgramChange",settings.midiOutProgramChange); + conf.set("midiOutMode",settings.midiOutMode); + conf.set("midiOutTimeRate",settings.midiOutTimeRate); + } + + // keyboard + if (groups&GUI_SETTINGS_KEYBOARD) { + // keybinds + for (int i=0; igetConfInt(String("keybind_GUI_ACTION_")+String(guiActions[i].name),guiActions[i].defaultBind); - } + // emulation + if (groups&GUI_SETTINGS_EMULATION) { + conf.set("arcadeCore",settings.arcadeCore); + conf.set("ym2612Core",settings.ym2612Core); + conf.set("snCore",settings.snCore); + conf.set("nesCore",settings.nesCore); + conf.set("fdsCore",settings.fdsCore); + conf.set("c64Core",settings.c64Core); + conf.set("pokeyCore",settings.pokeyCore); + conf.set("opnCore",settings.opnCore); + conf.set("opl2Core",settings.opl2Core); + conf.set("opl3Core",settings.opl3Core); + conf.set("arcadeCoreRender",settings.arcadeCoreRender); + conf.set("ym2612CoreRender",settings.ym2612CoreRender); + conf.set("snCoreRender",settings.snCoreRender); + conf.set("nesCoreRender",settings.nesCoreRender); + conf.set("fdsCoreRender",settings.fdsCoreRender); + conf.set("c64CoreRender",settings.c64CoreRender); + conf.set("pokeyCoreRender",settings.pokeyCoreRender); + conf.set("opnCoreRender",settings.opnCoreRender); + conf.set("opl2CoreRender",settings.opl2CoreRender); + conf.set("opl3CoreRender",settings.opl3CoreRender); - decodeKeyMap(noteKeys,e->getConfString("noteKeys",DEFAULT_NOTE_KEYS)); + conf.set("pcSpeakerOutMethod",settings.pcSpeakerOutMethod); + + conf.set("yrw801Path",settings.yrw801Path); + conf.set("tg100Path",settings.tg100Path); + conf.set("mu5Path",settings.mu5Path); + } +} + +void FurnaceGUI::syncSettings() { + readConfig(e->getConfObject()); parseKeybinds(); @@ -4079,216 +4529,10 @@ void FurnaceGUI::commitSettings() { settings.audioHiPass!=e->getConfInt("audioHiPass",1) ); - e->setConf("mainFontSize",settings.mainFontSize); - e->setConf("headFontSize",settings.headFontSize); - e->setConf("patFontSize",settings.patFontSize); - e->setConf("iconSize",settings.iconSize); - e->setConf("audioEngine",String(audioBackends[settings.audioEngine])); - e->setConf("audioDevice",settings.audioDevice); - e->setConf("midiInDevice",settings.midiInDevice); - e->setConf("midiOutDevice",settings.midiOutDevice); - e->setConf("renderDriver",settings.renderDriver); - e->setConf("sdlAudioDriver",settings.sdlAudioDriver); - e->setConf("audioQuality",settings.audioQuality); - e->setConf("audioHiPass",settings.audioHiPass); - e->setConf("audioBufSize",settings.audioBufSize); - e->setConf("audioRate",settings.audioRate); - e->setConf("audioChans",settings.audioChans); - e->setConf("arcadeCore",settings.arcadeCore); - e->setConf("ym2612Core",settings.ym2612Core); - e->setConf("snCore",settings.snCore); - e->setConf("nesCore",settings.nesCore); - e->setConf("fdsCore",settings.fdsCore); - e->setConf("c64Core",settings.c64Core); - e->setConf("pokeyCore",settings.pokeyCore); - e->setConf("opnCore",settings.opnCore); - e->setConf("opl2Core",settings.opl2Core); - e->setConf("opl3Core",settings.opl3Core); - e->setConf("arcadeCoreRender",settings.arcadeCoreRender); - e->setConf("ym2612CoreRender",settings.ym2612CoreRender); - e->setConf("snCoreRender",settings.snCoreRender); - e->setConf("nesCoreRender",settings.nesCoreRender); - e->setConf("fdsCoreRender",settings.fdsCoreRender); - e->setConf("c64CoreRender",settings.c64CoreRender); - e->setConf("pokeyCoreRender",settings.pokeyCoreRender); - e->setConf("opnCoreRender",settings.opnCoreRender); - e->setConf("opl2CoreRender",settings.opl2CoreRender); - e->setConf("opl3CoreRender",settings.opl3CoreRender); - e->setConf("pcSpeakerOutMethod",settings.pcSpeakerOutMethod); - e->setConf("yrw801Path",settings.yrw801Path); - e->setConf("tg100Path",settings.tg100Path); - e->setConf("mu5Path",settings.mu5Path); - e->setConf("mainFont",settings.mainFont); - e->setConf("headFont",settings.headFont); - e->setConf("patFont",settings.patFont); - e->setConf("mainFontPath",settings.mainFontPath); - e->setConf("headFontPath",settings.headFontPath); - e->setConf("patFontPath",settings.patFontPath); - e->setConf("patRowsBase",settings.patRowsBase); - e->setConf("orderRowsBase",settings.orderRowsBase); - e->setConf("soloAction",settings.soloAction); - e->setConf("pullDeleteBehavior",settings.pullDeleteBehavior); - e->setConf("wrapHorizontal",settings.wrapHorizontal); - e->setConf("wrapVertical",settings.wrapVertical); - e->setConf("macroView",settings.macroView); - e->setConf("fmNames",settings.fmNames); - e->setConf("allowEditDocking",settings.allowEditDocking); - e->setConf("chipNames",settings.chipNames); - e->setConf("overflowHighlight",settings.overflowHighlight); - e->setConf("partyTime",settings.partyTime); - e->setConf("flatNotes",settings.flatNotes); - e->setConf("germanNotation",settings.germanNotation); - e->setConf("stepOnDelete",settings.stepOnDelete); - e->setConf("scrollStep",settings.scrollStep); - e->setConf("sysSeparators",settings.sysSeparators); - e->setConf("forceMono",settings.forceMono); - e->setConf("controlLayout",settings.controlLayout); - e->setConf("statusDisplay",settings.statusDisplay); - e->setConf("dpiScale",settings.dpiScale); - e->setConf("viewPrevPattern",settings.viewPrevPattern); - e->setConf("guiColorsBase",settings.guiColorsBase); - e->setConf("guiColorsShading",settings.guiColorsShading); - e->setConf("avoidRaisingPattern",settings.avoidRaisingPattern); - e->setConf("insFocusesPattern",settings.insFocusesPattern); - e->setConf("stepOnInsert",settings.stepOnInsert); - e->setConf("unifiedDataView",settings.unifiedDataView); - e->setConf("sysFileDialog",settings.sysFileDialog); - e->setConf("roundedWindows",settings.roundedWindows); - e->setConf("roundedButtons",settings.roundedButtons); - e->setConf("roundedMenus",settings.roundedMenus); - e->setConf("loadJapanese",settings.loadJapanese); - e->setConf("loadChinese",settings.loadChinese); - e->setConf("loadChineseTraditional",settings.loadChineseTraditional); - e->setConf("loadKorean",settings.loadKorean); - e->setConf("fmLayout",settings.fmLayout); - e->setConf("sampleLayout",settings.sampleLayout); - e->setConf("waveLayout",settings.waveLayout); - e->setConf("susPosition",settings.susPosition); - e->setConf("effectCursorDir",settings.effectCursorDir); - e->setConf("cursorPastePos",settings.cursorPastePos); - e->setConf("titleBarInfo",settings.titleBarInfo); - e->setConf("titleBarSys",settings.titleBarSys); - e->setConf("frameBorders",settings.frameBorders); - e->setConf("effectDeletionAltersValue",settings.effectDeletionAltersValue); - e->setConf("oscRoundedCorners",settings.oscRoundedCorners); - e->setConf("oscTakesEntireWindow",settings.oscTakesEntireWindow); - e->setConf("oscBorder",settings.oscBorder); - e->setConf("oscEscapesBoundary",settings.oscEscapesBoundary); - e->setConf("oscMono",settings.oscMono); - e->setConf("oscAntiAlias",settings.oscAntiAlias); - e->setConf("separateFMColors",settings.separateFMColors); - e->setConf("insEditColorize",settings.insEditColorize); - e->setConf("metroVol",settings.metroVol); - e->setConf("sampleVol",settings.sampleVol); - e->setConf("pushNibble",settings.pushNibble); - e->setConf("scrollChangesOrder",settings.scrollChangesOrder); - e->setConf("oplStandardWaveNames",settings.oplStandardWaveNames); - e->setConf("cursorMoveNoScroll",settings.cursorMoveNoScroll); - e->setConf("lowLatency",settings.lowLatency); - e->setConf("notePreviewBehavior",settings.notePreviewBehavior); - e->setConf("powerSave",settings.powerSave); - e->setConf("absorbInsInput",settings.absorbInsInput); - e->setConf("eventDelay",settings.eventDelay); - e->setConf("moveWindowTitle",settings.moveWindowTitle); - e->setConf("hiddenSystems",settings.hiddenSystems); - e->setConf("initialSys2",settings.initialSys.toBase64()); - e->setConf("initialSysName",settings.initialSysName); - e->setConf("horizontalDataView",settings.horizontalDataView); - e->setConf("noMultiSystem",settings.noMultiSystem); - e->setConf("oldMacroVSlider",settings.oldMacroVSlider); - e->setConf("displayAllInsTypes",settings.displayAllInsTypes); - e->setConf("displayPartial",settings.displayPartial); - e->setConf("noteCellSpacing",settings.noteCellSpacing); - e->setConf("insCellSpacing",settings.insCellSpacing); - e->setConf("volCellSpacing",settings.volCellSpacing); - e->setConf("effectCellSpacing",settings.effectCellSpacing); - e->setConf("effectValCellSpacing",settings.effectValCellSpacing); - e->setConf("doubleClickColumn",settings.doubleClickColumn); - e->setConf("blankIns",settings.blankIns); - e->setConf("dragMovesSelection",settings.dragMovesSelection); - e->setConf("unsignedDetune",settings.unsignedDetune); - e->setConf("noThreadedInput",settings.noThreadedInput); - e->setConf("saveWindowPos",settings.saveWindowPos); - e->setConf("clampSamples",settings.clampSamples); - e->setConf("noteOffLabel",settings.noteOffLabel); - e->setConf("noteRelLabel",settings.noteRelLabel); - e->setConf("macroRelLabel",settings.macroRelLabel); - e->setConf("emptyLabel",settings.emptyLabel); - e->setConf("emptyLabel2",settings.emptyLabel2); - e->setConf("saveUnusedPatterns",settings.saveUnusedPatterns); - e->setConf("channelColors",settings.channelColors); - e->setConf("channelTextColors",settings.channelTextColors); - e->setConf("channelStyle",settings.channelStyle); - e->setConf("channelVolStyle",settings.channelVolStyle); - e->setConf("channelFeedbackStyle",settings.channelFeedbackStyle); - e->setConf("channelFont",settings.channelFont); - e->setConf("channelTextCenter",settings.channelTextCenter); - e->setConf("maxRecentFile",settings.maxRecentFile); - e->setConf("midiOutClock",settings.midiOutClock); - e->setConf("midiOutTime",settings.midiOutTime); - e->setConf("midiOutProgramChange",settings.midiOutProgramChange); - e->setConf("midiOutMode",settings.midiOutMode); - e->setConf("midiOutTimeRate",settings.midiOutTimeRate); - e->setConf("centerPattern",settings.centerPattern); - e->setConf("ordersCursor",settings.ordersCursor); - e->setConf("persistFadeOut",settings.persistFadeOut); - e->setConf("exportLoops",settings.exportLoops); - e->setConf("exportFadeOut",settings.exportFadeOut); - e->setConf("macroLayout",settings.macroLayout); - e->setConf("doubleClickTime",settings.doubleClickTime); - e->setConf("oneDigitEffects",settings.oneDigitEffects); - e->setConf("disableFadeIn",settings.disableFadeIn); - e->setConf("alwaysPlayIntro",settings.alwaysPlayIntro); - e->setConf("cursorFollowsOrder",settings.cursorFollowsOrder); - e->setConf("iCannotWait",settings.iCannotWait); - e->setConf("orderButtonPos",settings.orderButtonPos); - e->setConf("compress",settings.compress); - e->setConf("newPatternFormat",settings.newPatternFormat); - e->setConf("renderBackend",settings.renderBackend); - e->setConf("renderClearPos",settings.renderClearPos); - e->setConf("insertBehavior",settings.insertBehavior); - e->setConf("pullDeleteRow",settings.pullDeleteRow); - e->setConf("newSongBehavior",settings.newSongBehavior); - e->setConf("memUsageUnit",settings.memUsageUnit); - e->setConf("cursorFollowsWheel",settings.cursorFollowsWheel); - e->setConf("noDMFCompat",settings.noDMFCompat); - e->setConf("removeInsOff",settings.removeInsOff); - e->setConf("removeVolOff",settings.removeVolOff); - e->setConf("playOnLoad",settings.playOnLoad); - e->setConf("insTypeMenu",settings.insTypeMenu); - e->setConf("capitalMenuBar",settings.capitalMenuBar); - e->setConf("centerPopup",settings.centerPopup); - e->setConf("insIconsStyle",settings.insIconsStyle); - e->setConf("classicChipOptions",settings.classicChipOptions); - e->setConf("wasapiEx",settings.wasapiEx); - e->setConf("chanOscThreads",settings.chanOscThreads); - e->setConf("renderPoolThreads",settings.renderPoolThreads); - e->setConf("showPool",settings.showPool); - e->setConf("writeInsNames",settings.writeInsNames); - e->setConf("readInsNames",settings.readInsNames); - e->setConf("defaultAuthorName",settings.defaultAuthorName); - e->setConf("fontBackend",settings.fontBackend); - e->setConf("fontHinting",settings.fontHinting); - e->setConf("fontBitmap",settings.fontBitmap); - e->setConf("fontAutoHint",settings.fontAutoHint); - e->setConf("fontAntiAlias",settings.fontAntiAlias); - e->setConf("selectAssetOnLoad",settings.selectAssetOnLoad); - - // colors - for (int i=0; isetConf(guiColors[i].name,(int)ImGui::ColorConvertFloat4ToU32(uiColors[i])); - } - - // keybinds - for (int i=0; isetConf(String("keybind_GUI_ACTION_")+String(guiActions[i].name),actionKeys[i]); - } + writeConfig(e->getConfObject()); parseKeybinds(); - e->setConf("noteKeys",encodeKeyMap(noteKeys)); - midiMap.compile(); midiMap.write(e->getConfigPath()+DIR_SEPARATOR_STR+"midiIn_"+stripName(settings.midiInDevice)+".cfg"); @@ -4335,69 +4579,36 @@ void FurnaceGUI::commitSettings() { } bool FurnaceGUI::importColors(String path) { - FILE* f=ps_fopen(path.c_str(),"rb"); - if (f==NULL) { + DivConfig c; + if (!c.loadFromFile(path.c_str(),false,false)) { logW("error while opening color file for import: %s",strerror(errno)); return false; } - resetColors(); - char line[4096]; - while (!feof(f)) { - String key=""; - String value=""; - bool keyOrValue=false; - if (fgets(line,4095,f)==NULL) { - break; - } - for (char* i=line; *i; i++) { - if (*i=='\n') continue; - if (keyOrValue) { - value+=*i; - } else { - if (*i=='=') { - keyOrValue=true; - } else { - key+=*i; - } - } - } - if (keyOrValue) { - // unoptimal - const char* cs=key.c_str(); - bool found=false; - for (int i=0; igetConfInt(guiColors[i].name,guiColors[i].defaultColor)); - } - } - for (int i=0; i<64; i++) { ImVec4 col1=uiColors[GUI_COLOR_PATTERN_VOLUME_MIN]; ImVec4 col2=uiColors[GUI_COLOR_PATTERN_VOLUME_HALF]; @@ -4853,6 +5057,7 @@ void FurnaceGUI::applyUISettings(bool updateFonts) { secondaryHoverActual=secondaryHover; + // TODO: improve if (mobileUI) { // disable all hovered colors primaryHover=primary; secondaryHover=secondary; @@ -4882,31 +5087,63 @@ void FurnaceGUI::applyUISettings(bool updateFonts) { sty.Colors[ImGuiCol_NavWindowingHighlight]=uiColors[GUI_COLOR_NAV_WIN_HIGHLIGHT]; sty.Colors[ImGuiCol_NavWindowingDimBg]=uiColors[GUI_COLOR_NAV_WIN_BACKDROP]; sty.Colors[ImGuiCol_Text]=uiColors[GUI_COLOR_TEXT]; + sty.Colors[ImGuiCol_TextDisabled]=uiColors[GUI_COLOR_TEXT_DISABLED]; - sty.Colors[ImGuiCol_Button]=primary; - sty.Colors[ImGuiCol_ButtonHovered]=primaryHover; - sty.Colors[ImGuiCol_ButtonActive]=primaryActive; - sty.Colors[ImGuiCol_Tab]=primary; - sty.Colors[ImGuiCol_TabHovered]=secondaryHover; - sty.Colors[ImGuiCol_TabActive]=secondarySemiActive; - sty.Colors[ImGuiCol_TabUnfocused]=primary; - sty.Colors[ImGuiCol_TabUnfocusedActive]=primaryHover; - sty.Colors[ImGuiCol_Header]=secondary; - sty.Colors[ImGuiCol_HeaderHovered]=secondaryHover; - sty.Colors[ImGuiCol_HeaderActive]=secondaryActive; - sty.Colors[ImGuiCol_ResizeGrip]=secondary; - sty.Colors[ImGuiCol_ResizeGripHovered]=secondaryHover; - sty.Colors[ImGuiCol_ResizeGripActive]=secondaryActive; - sty.Colors[ImGuiCol_FrameBg]=secondary; - sty.Colors[ImGuiCol_FrameBgHovered]=secondaryHover; - sty.Colors[ImGuiCol_FrameBgActive]=secondaryActive; - sty.Colors[ImGuiCol_SliderGrab]=primaryActive; - sty.Colors[ImGuiCol_SliderGrabActive]=primaryActive; - sty.Colors[ImGuiCol_TitleBgActive]=primary; - sty.Colors[ImGuiCol_CheckMark]=primaryActive; - sty.Colors[ImGuiCol_TextSelectedBg]=secondaryHoverActual; - sty.Colors[ImGuiCol_PlotHistogram]=uiColors[GUI_COLOR_MACRO_OTHER]; - sty.Colors[ImGuiCol_PlotHistogramHovered]=uiColors[GUI_COLOR_MACRO_OTHER]; + if (settings.basicColors) { + sty.Colors[ImGuiCol_Button]=primary; + sty.Colors[ImGuiCol_ButtonHovered]=primaryHover; + sty.Colors[ImGuiCol_ButtonActive]=primaryActive; + sty.Colors[ImGuiCol_Tab]=primary; + sty.Colors[ImGuiCol_TabHovered]=secondaryHover; + sty.Colors[ImGuiCol_TabActive]=secondarySemiActive; + sty.Colors[ImGuiCol_TabUnfocused]=primary; + sty.Colors[ImGuiCol_TabUnfocusedActive]=primaryHover; + sty.Colors[ImGuiCol_Header]=secondary; + sty.Colors[ImGuiCol_HeaderHovered]=secondaryHover; + sty.Colors[ImGuiCol_HeaderActive]=secondaryActive; + sty.Colors[ImGuiCol_ResizeGrip]=secondary; + sty.Colors[ImGuiCol_ResizeGripHovered]=secondaryHover; + sty.Colors[ImGuiCol_ResizeGripActive]=secondaryActive; + sty.Colors[ImGuiCol_FrameBg]=secondary; + sty.Colors[ImGuiCol_FrameBgHovered]=secondaryHover; + sty.Colors[ImGuiCol_FrameBgActive]=secondaryActive; + sty.Colors[ImGuiCol_SliderGrab]=primaryActive; + sty.Colors[ImGuiCol_SliderGrabActive]=primaryActive; + sty.Colors[ImGuiCol_TitleBgActive]=primary; + sty.Colors[ImGuiCol_CheckMark]=primaryActive; + sty.Colors[ImGuiCol_TextSelectedBg]=secondaryHoverActual; + sty.Colors[ImGuiCol_PlotHistogram]=uiColors[GUI_COLOR_MACRO_OTHER]; + sty.Colors[ImGuiCol_PlotHistogramHovered]=uiColors[GUI_COLOR_MACRO_OTHER]; + } else { + sty.Colors[ImGuiCol_Button]=uiColors[GUI_COLOR_BUTTON]; + sty.Colors[ImGuiCol_ButtonHovered]=uiColors[GUI_COLOR_BUTTON_HOVER]; + sty.Colors[ImGuiCol_ButtonActive]=uiColors[GUI_COLOR_BUTTON_ACTIVE]; + sty.Colors[ImGuiCol_Tab]=uiColors[GUI_COLOR_TAB]; + sty.Colors[ImGuiCol_TabHovered]=uiColors[GUI_COLOR_TAB_HOVER]; + sty.Colors[ImGuiCol_TabActive]=uiColors[GUI_COLOR_TAB_ACTIVE]; + sty.Colors[ImGuiCol_TabUnfocused]=uiColors[GUI_COLOR_TAB_UNFOCUSED]; + sty.Colors[ImGuiCol_TabUnfocusedActive]=uiColors[GUI_COLOR_TAB_UNFOCUSED_ACTIVE]; + sty.Colors[ImGuiCol_Header]=uiColors[GUI_COLOR_IMGUI_HEADER]; + sty.Colors[ImGuiCol_HeaderHovered]=uiColors[GUI_COLOR_IMGUI_HEADER_HOVER]; + sty.Colors[ImGuiCol_HeaderActive]=uiColors[GUI_COLOR_IMGUI_HEADER_ACTIVE]; + sty.Colors[ImGuiCol_ResizeGrip]=uiColors[GUI_COLOR_RESIZE_GRIP]; + sty.Colors[ImGuiCol_ResizeGripHovered]=uiColors[GUI_COLOR_RESIZE_GRIP_HOVER]; + sty.Colors[ImGuiCol_ResizeGripActive]=uiColors[GUI_COLOR_RESIZE_GRIP_ACTIVE]; + sty.Colors[ImGuiCol_FrameBg]=uiColors[GUI_COLOR_WIDGET_BACKGROUND]; + sty.Colors[ImGuiCol_FrameBgHovered]=uiColors[GUI_COLOR_WIDGET_BACKGROUND_HOVER]; + sty.Colors[ImGuiCol_FrameBgActive]=uiColors[GUI_COLOR_WIDGET_BACKGROUND_ACTIVE]; + sty.Colors[ImGuiCol_SliderGrab]=uiColors[GUI_COLOR_SLIDER_GRAB]; + sty.Colors[ImGuiCol_SliderGrabActive]=uiColors[GUI_COLOR_SLIDER_GRAB_ACTIVE]; + sty.Colors[ImGuiCol_TitleBgActive]=uiColors[GUI_COLOR_TITLE_BACKGROUND_ACTIVE]; + sty.Colors[ImGuiCol_CheckMark]=uiColors[GUI_COLOR_CHECK_MARK]; + sty.Colors[ImGuiCol_TextSelectedBg]=uiColors[GUI_COLOR_TEXT_SELECTION]; + sty.Colors[ImGuiCol_PlotLines]=uiColors[GUI_COLOR_PLOT_LINES]; + sty.Colors[ImGuiCol_PlotLinesHovered]=uiColors[GUI_COLOR_PLOT_LINES_HOVER]; + sty.Colors[ImGuiCol_PlotHistogram]=uiColors[GUI_COLOR_PLOT_HISTOGRAM]; + sty.Colors[ImGuiCol_PlotHistogramHovered]=uiColors[GUI_COLOR_PLOT_HISTOGRAM_HOVER]; + sty.Colors[ImGuiCol_TableRowBg]=uiColors[GUI_COLOR_TABLE_ROW_EVEN]; + sty.Colors[ImGuiCol_TableRowBgAlt]=uiColors[GUI_COLOR_TABLE_ROW_ODD]; + } sty.Colors[ImGuiCol_Border]=uiColors[GUI_COLOR_BORDER]; sty.Colors[ImGuiCol_BorderShadow]=uiColors[GUI_COLOR_BORDER_SHADOW];