diff --git a/Core/Config.cpp b/Core/Config.cpp index 3792308eec..1663b29aa4 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -1677,11 +1677,10 @@ const Path Config::FindConfigFile(const std::string &baseFilename) { } // Make sure at least the directory it's supposed to be in exists. - Path path = filename.NavigateUp(); - // This check is just to avoid logging. - if (!File::Exists(path)) { - File::CreateFullPath(path); - } + Path parent = filename.NavigateUp(); + + // We try to create the path and ignore if it fails (already exists). + File::CreateFullPath(parent); return filename; } diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 19183362ad..12ec9a6432 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -1670,6 +1670,7 @@ void EmuScreen::renderImDebugger() { Draw::DrawContext *draw = screenManager()->getDrawContext(); if (!imguiInited_) { imguiInited_ = true; + ImGui_ImplPlatform_Init(GetSysDirectory(DIRECTORY_SYSTEM) / "imgui.ini"); imDebugger_ = std::make_unique(); // Read the TTF font diff --git a/UI/ImDebugger/ImDebugger.cpp b/UI/ImDebugger/ImDebugger.cpp index 6742423dee..46867d2e5f 100644 --- a/UI/ImDebugger/ImDebugger.cpp +++ b/UI/ImDebugger/ImDebugger.cpp @@ -607,8 +607,14 @@ void DrawHLEModules(ImConfig &config) { ImDebugger::ImDebugger() { reqToken_ = g_requestManager.GenerateRequesterToken(); + cfg_.LoadConfig(ConfigPath()); } +ImDebugger::~ImDebugger() { + cfg_.SaveConfig(ConfigPath()); +} + + void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUDebugInterface *gpuDebug) { // Snapshot the coreState to avoid inconsistency. const CoreState coreState = ::coreState; @@ -921,6 +927,62 @@ void ImDisasmWindow::Draw(MIPSDebugInterface *mipsDebug, bool *open, CoreState c ImGui::End(); } -void ImDebugger::LoadConfig() { - IniFile ini; +Path ImDebugger::ConfigPath() { + return GetSysDirectory(DIRECTORY_SYSTEM) / "imdebugger.ini"; +} + +// TODO: Move this into the main config at some point. +// But, I don't really want Core to know about the ImDebugger.. + +void ImConfig::LoadConfig(const Path &iniFile) { + IniFile ini; + ini.Load(iniFile); // Ignore return value, might not exist yet. In that case we'll end up loading defaults. + SyncConfig(&ini, false); +} + +void ImConfig::SaveConfig(const Path &iniFile) { + IniFile ini; + ini.Load(iniFile); // ignore return value, might not exist yet + SyncConfig(&ini, true); + ini.Save(iniFile); +} + +class Syncer { +public: + explicit Syncer(bool save) : save_(save) {} + void SetSection(Section *section) { section_ = section; } + template + void Sync(std::string_view key, T *value, T defaultValue) { + if (save_) { + section_->Set(key, *value); + } else { + section_->Get(key, value, defaultValue); + } + } +private: + Section *section_ = nullptr; + bool save_; +}; + +void ImConfig::SyncConfig(IniFile *ini, bool save) { + Syncer sync(save); + sync.SetSection(ini->GetOrCreateSection("Windows")); + sync.Sync("disasmOpen", &disasmOpen, true); + sync.Sync("demoOpen ", &demoOpen, false); + sync.Sync("regsOpen", ®sOpen, true); + sync.Sync("threadsOpen", &threadsOpen, false); + sync.Sync("callstackOpen", &callstackOpen, false); + sync.Sync("breakpointsOpen", &breakpointsOpen, false); + sync.Sync("modulesOpen", &modulesOpen, false); + sync.Sync("hleModulesOpen", &hleModulesOpen, false); + sync.Sync("atracOpen", &atracOpen, false); + sync.Sync("structViewerOpen", &structViewerOpen, false); + sync.Sync("framebuffersOpen", &framebuffersOpen, false); + sync.Sync("displayOpen", &displayOpen, true); + sync.Sync("styleEditorOpen", &styleEditorOpen, false); + sync.Sync("filesystemBrowserOpen", &filesystemBrowserOpen, false); + sync.Sync("kernelObjectsOpen", &kernelObjectsOpen, false); + + sync.SetSection(ini->GetOrCreateSection("Settings")); + sync.Sync("displayLatched", &displayLatched, false); } diff --git a/UI/ImDebugger/ImDebugger.h b/UI/ImDebugger/ImDebugger.h index ee2ed91ccc..374966675b 100644 --- a/UI/ImDebugger/ImDebugger.h +++ b/UI/ImDebugger/ImDebugger.h @@ -58,21 +58,23 @@ private: }; struct ImConfig { - bool disasmOpen = true; - bool demoOpen = false; - bool regsOpen = true; - bool threadsOpen = true; - bool callstackOpen = true; - bool breakpointsOpen = false; - bool modulesOpen = true; - bool hleModulesOpen = false; - bool atracOpen = true; - bool structViewerOpen = false; - bool framebuffersOpen = false; - bool displayOpen = false; - bool styleEditorOpen = false; - bool filesystemBrowserOpen = false; - bool kernelObjectsOpen = false; + // Defaults for saved settings are set in SyncConfig. + + bool disasmOpen; + bool demoOpen; + bool regsOpen; + bool threadsOpen; + bool callstackOpen; + bool breakpointsOpen; + bool modulesOpen; + bool hleModulesOpen; + bool atracOpen; + bool structViewerOpen; + bool framebuffersOpen; + bool displayOpen; + bool styleEditorOpen; + bool filesystemBrowserOpen; + bool kernelObjectsOpen; // HLE explorer settings // bool filterByUsed = true; @@ -85,6 +87,12 @@ struct ImConfig { int selectedMemCheck = -1; bool displayLatched = false; + + // We use a separate ini file from the main PPSSPP config. + void LoadConfig(const Path &iniFile); + void SaveConfig(const Path &iniFile); + + void SyncConfig(IniFile *ini, bool save); }; enum ImUiCmd { @@ -98,13 +106,12 @@ struct ImUiCommand { class ImDebugger { public: ImDebugger(); + ~ImDebugger(); void Frame(MIPSDebugInterface *mipsDebug, GPUDebugInterface *gpuDebug); private: - // We use a separate ini file from the main PPSSPP config. - void LoadConfig(); - void SaveConfig(); + Path ConfigPath(); RequesterToken reqToken_; @@ -112,5 +119,5 @@ private: ImStructViewer structViewer_; // Open variables. - ImConfig cfg_; + ImConfig cfg_{}; }; diff --git a/ext/imgui/imgui_impl_platform.cpp b/ext/imgui/imgui_impl_platform.cpp index 957800d4da..f69c2c02ab 100644 --- a/ext/imgui/imgui_impl_platform.cpp +++ b/ext/imgui/imgui_impl_platform.cpp @@ -1,8 +1,10 @@ #include "ext/imgui/imgui.h" +#include "Common/File/Path.h" #include "Common/Input/KeyCodes.h" #include "Common/Data/Encoding/Utf8.h" #include "Common/System/Display.h" #include "Common/TimeUtil.h" +#include "Common/StringUtils.h" #include "Common/Log.h" #include "imgui_impl_platform.h" @@ -73,6 +75,12 @@ void ImGui_ImplPlatform_TouchEvent(const TouchInput &touch) { } } +void ImGui_ImplPlatform_Init(const Path &configPath) { + static char path[1024]; + truncate_cpy(path, configPath.ToString()); + ImGui::GetIO().IniFilename = path; +} + void ImGui_ImplPlatform_AxisEvent(const AxisInput &axis) { // Ignore for now. } diff --git a/ext/imgui/imgui_impl_platform.h b/ext/imgui/imgui_impl_platform.h index 65a8bf2e94..73090114fd 100644 --- a/ext/imgui/imgui_impl_platform.h +++ b/ext/imgui/imgui_impl_platform.h @@ -4,8 +4,11 @@ #include "Common/Input/KeyCodes.h" #include "Common/Input/InputState.h" +class Path; + ImGuiKey KeyCodeToImGui(InputKeyCode keyCode); +void ImGui_ImplPlatform_Init(const Path &configPath); void ImGui_ImplPlatform_NewFrame(); void ImGui_ImplPlatform_KeyEvent(const KeyInput &key); diff --git a/gradle.properties b/gradle.properties index 3b9f2d19b8..bd03bfddc7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,3 +2,4 @@ org.gradle.jvmargs=-Xmx1536M android.useAndroidX=true android.nonTransitiveRClass=true android.nonFinalResIds=true +android.ndk.suppressMinSdkVersionError=21