ImGuiOverlays: Move debug state to auxiliary windows

This commit is contained in:
Stenzek 2024-10-13 22:11:06 +10:00
parent b2a4010661
commit c14ff03d5f
No known key found for this signature in database
19 changed files with 154 additions and 152 deletions

View File

@ -3809,18 +3809,10 @@ const std::string* CDROM::LookupFileMap(u32 lba, u32* start_lba, u32* end_lba)
return &iter->second.second;
}
void CDROM::DrawDebugWindow()
void CDROM::DrawDebugWindow(float scale)
{
static const ImVec4 active_color{1.0f, 1.0f, 1.0f, 1.0f};
static const ImVec4 inactive_color{0.4f, 0.4f, 0.4f, 1.0f};
const float framebuffer_scale = ImGuiManager::GetGlobalScale();
ImGui::SetNextWindowSize(ImVec2(800.0f * framebuffer_scale, 580.0f * framebuffer_scale), ImGuiCond_FirstUseEver);
if (!ImGui::Begin("CDROM State", nullptr))
{
ImGui::End();
return;
}
// draw voice states
if (ImGui::CollapsingHeader("Media", ImGuiTreeNodeFlags_DefaultOpen))
@ -3916,7 +3908,7 @@ void CDROM::DrawDebugWindow()
else
{
const float end_y = ImGui::GetCursorPosY();
ImGui::SetCursorPosX(ImGui::GetWindowWidth() - 120.0f * framebuffer_scale);
ImGui::SetCursorPosX(ImGui::GetWindowWidth() - 120.0f * scale);
ImGui::SetCursorPosY(start_y);
if (ImGui::Button("Show Current File"))
s_state.show_current_file = true;
@ -4081,6 +4073,4 @@ void CDROM::DrawDebugWindow()
ImGui::Text("Audio FIFO Size: %u frames", s_state.audio_fifo.GetSize());
}
ImGui::End();
}

View File

@ -37,7 +37,7 @@ void WriteRegister(u32 offset, u8 value);
void DMARead(u32* words, u32 word_count);
// Render statistics debug window.
void DrawDebugWindow();
void DrawDebugWindow(float scale);
void SetReadaheadSectors(u32 readahead_sectors);

View File

@ -910,33 +910,24 @@ TickCount DMA::TransferDeviceToMemory(u32 address, u32 increment, u32 word_count
return Bus::GetDMARAMTickCount(word_count);
}
void DMA::DrawDebugStateWindow()
void DMA::DrawDebugStateWindow(float scale)
{
static constexpr u32 NUM_COLUMNS = 10;
static constexpr std::array<const char*, NUM_COLUMNS> column_names = {
{"#", "Req", "Direction", "Chopping", "Mode", "Busy", "Enable", "Priority", "IRQ", "Flag"}};
static constexpr std::array<const char*, 4> sync_mode_names = {{"Manual", "Request", "LinkedList", "Reserved"}};
const float framebuffer_scale = ImGuiManager::GetGlobalScale();
ImGui::SetNextWindowSize(ImVec2(850.0f * framebuffer_scale, 250.0f * framebuffer_scale), ImGuiCond_FirstUseEver);
if (!ImGui::Begin("DMA State", nullptr))
{
ImGui::End();
return;
}
ImGui::Columns(NUM_COLUMNS);
ImGui::SetColumnWidth(0, 100.0f * framebuffer_scale);
ImGui::SetColumnWidth(1, 50.0f * framebuffer_scale);
ImGui::SetColumnWidth(2, 100.0f * framebuffer_scale);
ImGui::SetColumnWidth(3, 150.0f * framebuffer_scale);
ImGui::SetColumnWidth(4, 80.0f * framebuffer_scale);
ImGui::SetColumnWidth(5, 80.0f * framebuffer_scale);
ImGui::SetColumnWidth(6, 80.0f * framebuffer_scale);
ImGui::SetColumnWidth(7, 80.0f * framebuffer_scale);
ImGui::SetColumnWidth(8, 80.0f * framebuffer_scale);
ImGui::SetColumnWidth(9, 80.0f * framebuffer_scale);
ImGui::SetColumnWidth(0, 100.0f * scale);
ImGui::SetColumnWidth(1, 50.0f * scale);
ImGui::SetColumnWidth(2, 100.0f * scale);
ImGui::SetColumnWidth(3, 150.0f * scale);
ImGui::SetColumnWidth(4, 80.0f * scale);
ImGui::SetColumnWidth(5, 80.0f * scale);
ImGui::SetColumnWidth(6, 80.0f * scale);
ImGui::SetColumnWidth(7, 80.0f * scale);
ImGui::SetColumnWidth(8, 80.0f * scale);
ImGui::SetColumnWidth(9, 80.0f * scale);
for (const char* title : column_names)
{
@ -984,7 +975,6 @@ void DMA::DrawDebugStateWindow()
}
ImGui::Columns(1);
ImGui::End();
}
// Instantiate channel functions.

View File

@ -35,6 +35,6 @@ void WriteRegister(u32 offset, u32 value);
void SetRequest(Channel channel, bool request);
void DrawDebugStateWindow();
void DrawDebugStateWindow(float scale);
} // namespace DMA

View File

@ -2759,17 +2759,8 @@ bool GPU::DumpVRAMToFile(const char* filename, u32 width, u32 height, u32 stride
return image.SaveToFile(filename);
}
void GPU::DrawDebugStateWindow()
void GPU::DrawDebugStateWindow(float scale)
{
const float framebuffer_scale = ImGuiManager::GetGlobalScale();
ImGui::SetNextWindowSize(ImVec2(450.0f * framebuffer_scale, 550.0f * framebuffer_scale), ImGuiCond_FirstUseEver);
if (!ImGui::Begin("GPU", nullptr))
{
ImGui::End();
return;
}
DrawRendererStats();
if (ImGui::CollapsingHeader("GPU", ImGuiTreeNodeFlags_DefaultOpen))
@ -2824,8 +2815,6 @@ void GPU::DrawDebugStateWindow()
cs.display_width - cs.display_vram_width - cs.display_origin_left,
cs.display_height - cs.display_vram_height - cs.display_origin_top);
}
ImGui::End();
}
void GPU::DrawRendererStats()

View File

@ -103,7 +103,7 @@ public:
virtual void RestoreDeviceContext();
// Render statistics debug window.
void DrawDebugStateWindow();
void DrawDebugStateWindow(float scale);
void GetStatsString(SmallStringBase& str);
void GetMemoryStatsString(SmallStringBase& str);
void ResetStatistics();

View File

@ -446,6 +446,7 @@ void Host::ReleaseGPUDevice()
if (!g_gpu_device)
return;
ImGuiManager::DestroyAllDebugWindows();
ImGuiManager::DestroyOverlayTextures();
FullscreenUI::Shutdown();
ImGuiManager::Shutdown();

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: CC-BY-NC-ND-4.0
#include "imgui_overlays.h"
#include "achievements.h"
#include "cdrom.h"
#include "controller.h"
#include "cpu_core_private.h"
@ -37,6 +38,7 @@
#include "imgui.h"
#include "imgui_internal.h"
#include <array>
#include <atomic>
#include <chrono>
#include <cmath>
@ -47,12 +49,43 @@
LOG_CHANNEL(ImGuiManager);
namespace ImGuiManager {
namespace {
#ifndef __ANDROID__
struct DebugWindowInfo
{
const char* name;
const char* window_title;
const char* icon_name;
void (*draw_func)(float);
u32 default_width;
u32 default_height;
};
#endif
} // namespace
static void FormatProcessorStat(SmallStringBase& text, double usage, double time);
static void DrawPerformanceOverlay(float& position_y, float scale, float margin, float spacing);
static void DrawMediaCaptureOverlay(float& position_y, float scale, float margin, float spacing);
static void DrawFrameTimeOverlay(float& position_y, float scale, float margin, float spacing);
static void DrawEnhancementsOverlay();
static void DrawInputsOverlay();
static constexpr size_t NUM_DEBUG_WINDOWS = 6;
static constexpr const char* DEBUG_WINDOW_CONFIG_SECTION = "DebugWindows";
static constexpr const std::array<DebugWindowInfo, NUM_DEBUG_WINDOWS> s_debug_window_info = {{
{"SPU", "SPU State", ":icons/applications-system.png", &SPU::DrawDebugStateWindow, 800, 915},
{"CDROM", "CD-ROM State", ":icons/applications-system.png", &CDROM::DrawDebugWindow, 800, 540},
{"GPU", "GPU State", ":icons/applications-system.png", [](float sc) { g_gpu->DrawDebugStateWindow(sc); }, 450, 550},
{"DMA", "DMA State", ":icons/applications-system.png", &DMA::DrawDebugStateWindow, 860, 180},
{"MDEC", "MDEC State", ":icons/applications-system.png", &MDEC::DrawDebugStateWindow, 300, 350},
{"Timers", "Timers State", ":icons/applications-system.png", &Timers::DrawDebugStateWindow, 800, 95},
}};
static std::array<ImGuiManager::AuxiliaryRenderWindowState, NUM_DEBUG_WINDOWS> s_debug_window_state = {};
} // namespace ImGuiManager
static std::tuple<float, float> GetMinMax(std::span<const float> values)
@ -170,23 +203,71 @@ void Host::DisplayLoadingScreen(const char* message, int progress_min /*= -1*/,
ImGui::NewFrame();
}
void ImGuiManager::UpdateDebugWindowConfig()
{
#ifndef __ANDROID__
const bool block_all = Achievements::IsHardcoreModeActive();
for (size_t i = 0; i < NUM_DEBUG_WINDOWS; i++)
{
AuxiliaryRenderWindowState& state = s_debug_window_state[i];
const DebugWindowInfo& info = s_debug_window_info[i];
const bool current = (state.window_handle != nullptr);
const bool enabled = (!block_all && Host::GetBaseBoolSettingValue(DEBUG_WINDOW_CONFIG_SECTION, info.name, false));
if (enabled == current)
continue;
if (!enabled)
{
DestroyAuxiliaryRenderWindow(&state, DEBUG_WINDOW_CONFIG_SECTION, info.name);
}
else
{
Error error;
if (!CreateAuxiliaryRenderWindow(&state, info.window_title, info.icon_name, DEBUG_WINDOW_CONFIG_SECTION,
info.name, info.default_width, info.default_height, &error))
{
ERROR_LOG("Failed to create aux render window for {}: {}", info.name, error.GetDescription());
}
}
}
#endif
}
void ImGuiManager::RenderDebugWindows()
{
if (System::IsValid())
#ifndef __ANDROID__
for (size_t i = 0; i < NUM_DEBUG_WINDOWS; i++)
{
if (g_settings.debugging.show_gpu_state)
g_gpu->DrawDebugStateWindow();
if (g_settings.debugging.show_cdrom_state)
CDROM::DrawDebugWindow();
if (g_settings.debugging.show_timers_state)
Timers::DrawDebugStateWindow();
if (g_settings.debugging.show_spu_state)
SPU::DrawDebugStateWindow();
if (g_settings.debugging.show_mdec_state)
MDEC::DrawDebugStateWindow();
if (g_settings.debugging.show_dma_state)
DMA::DrawDebugStateWindow();
AuxiliaryRenderWindowState& state = s_debug_window_state[i];
if (!state.window_handle)
continue;
if (!RenderAuxiliaryRenderWindow(&state, s_debug_window_info[i].draw_func))
{
// window was closed, destroy it and update the configuration
const DebugWindowInfo& info = s_debug_window_info[i];
DestroyAuxiliaryRenderWindow(&state, DEBUG_WINDOW_CONFIG_SECTION, info.name);
Host::SetBaseBoolSettingValue(DEBUG_WINDOW_CONFIG_SECTION, info.name, false);
Host::CommitBaseSettingChanges();
}
}
#endif
}
void ImGuiManager::DestroyAllDebugWindows()
{
#ifndef __ANDROID__
for (size_t i = 0; i < NUM_DEBUG_WINDOWS; i++)
{
AuxiliaryRenderWindowState& state = s_debug_window_state[i];
if (!state.window_handle)
continue;
ImGuiManager::DestroyAuxiliaryRenderWindow(&state, DEBUG_WINDOW_CONFIG_SECTION, s_debug_window_info[i].name);
}
#endif
}
void ImGuiManager::RenderTextOverlays()

View File

@ -10,6 +10,8 @@
namespace ImGuiManager {
void RenderTextOverlays();
void RenderDebugWindows();
void UpdateDebugWindowConfig();
void DestroyAllDebugWindows();
void RenderOverlayWindows();
void DestroyOverlayTextures();

View File

@ -1125,17 +1125,8 @@ void MDEC::SetScaleMatrix(const u16* values)
}
}
void MDEC::DrawDebugStateWindow()
void MDEC::DrawDebugStateWindow(float scale)
{
const float framebuffer_scale = ImGuiManager::GetGlobalScale();
ImGui::SetNextWindowSize(ImVec2(300.0f * framebuffer_scale, 350.0f * framebuffer_scale), ImGuiCond_FirstUseEver);
if (!ImGui::Begin("MDEC State", nullptr))
{
ImGui::End();
return;
}
static constexpr std::array<const char*, 5> state_names = {
{"None", "Decoding Macroblock", "Writing Macroblock", "SetIqTab", "SetScale"}};
static constexpr std::array<const char*, 4> output_depths = {{"4-bit", "8-bit", "24-bit", "15-bit"}};
@ -1163,6 +1154,4 @@ void MDEC::DrawDebugStateWindow()
ImGui::Text("Parameter Words Remaining: %d",
static_cast<s32>(SignExtend32(s_state.status.parameter_words_remaining.GetValue())));
}
ImGui::End();
}

View File

@ -21,6 +21,6 @@ void WriteRegister(u32 offset, u32 value);
void DMARead(u32* words, u32 word_count);
void DMAWrite(const u32* words, u32 word_count);
void DrawDebugStateWindow();
void DrawDebugStateWindow(float scale);
} // namespace MDEC

View File

@ -438,13 +438,6 @@ void Settings::Load(SettingsInterface& si, SettingsInterface& controller_si)
debugging.gdb_server_port = static_cast<u16>(si.GetUIntValue("Debug", "GDBServerPort", DEFAULT_GDB_SERVER_PORT));
#endif
debugging.show_gpu_state = si.GetBoolValue("Debug", "ShowGPUState");
debugging.show_cdrom_state = si.GetBoolValue("Debug", "ShowCDROMState");
debugging.show_spu_state = si.GetBoolValue("Debug", "ShowSPUState");
debugging.show_timers_state = si.GetBoolValue("Debug", "ShowTimersState");
debugging.show_mdec_state = si.GetBoolValue("Debug", "ShowMDECState");
debugging.show_dma_state = si.GetBoolValue("Debug", "ShowDMAState");
texture_replacements.enable_texture_replacements =
si.GetBoolValue("TextureReplacements", "EnableTextureReplacements", false);
texture_replacements.enable_vram_write_replacements =
@ -712,13 +705,6 @@ void Settings::Save(SettingsInterface& si, bool ignore_base) const
si.SetBoolValue("Debug", "EnableGDBServer", debugging.enable_gdb_server);
si.SetUIntValue("Debug", "GDBServerPort", debugging.gdb_server_port);
#endif
si.SetBoolValue("Debug", "ShowGPUState", debugging.show_gpu_state);
si.SetBoolValue("Debug", "ShowCDROMState", debugging.show_cdrom_state);
si.SetBoolValue("Debug", "ShowSPUState", debugging.show_spu_state);
si.SetBoolValue("Debug", "ShowTimersState", debugging.show_timers_state);
si.SetBoolValue("Debug", "ShowMDECState", debugging.show_mdec_state);
si.SetBoolValue("Debug", "ShowDMAState", debugging.show_dma_state);
}
si.SetBoolValue("TextureReplacements", "EnableTextureReplacements", texture_replacements.enable_texture_replacements);
@ -1035,12 +1021,6 @@ void Settings::FixIncompatibleSettings(bool display_osd_messages)
}
g_settings.debugging.enable_gdb_server = false;
g_settings.debugging.show_vram = false;
g_settings.debugging.show_gpu_state = false;
g_settings.debugging.show_cdrom_state = false;
g_settings.debugging.show_spu_state = false;
g_settings.debugging.show_timers_state = false;
g_settings.debugging.show_mdec_state = false;
g_settings.debugging.show_dma_state = false;
g_settings.debugging.dump_cpu_to_vram_copies = false;
g_settings.debugging.dump_vram_to_cpu_copies = false;
}

View File

@ -219,22 +219,14 @@ struct Settings
struct DebugSettings
{
#ifndef __ANDROID__
u16 gdb_server_port = DEFAULT_GDB_SERVER_PORT;
bool enable_gdb_server : 1 = false;
#endif
bool show_vram : 1 = false;
bool dump_cpu_to_vram_copies : 1 = false;
bool dump_vram_to_cpu_copies : 1 = false;
#ifndef __ANDROID__
bool enable_gdb_server : 1 = false;
u16 gdb_server_port = DEFAULT_GDB_SERVER_PORT;
#endif
// Mutable because the imgui window can close itself.
mutable bool show_gpu_state = false;
mutable bool show_cdrom_state = false;
mutable bool show_spu_state = false;
mutable bool show_timers_state = false;
mutable bool show_mdec_state = false;
mutable bool show_dma_state = false;
} debugging;
// texture replacements

View File

@ -2516,27 +2516,18 @@ void SPU::UpdateEventInterval()
s_state.tick_event.Schedule(downcount);
}
void SPU::DrawDebugStateWindow()
void SPU::DrawDebugStateWindow(float scale)
{
static const ImVec4 active_color{1.0f, 1.0f, 1.0f, 1.0f};
static const ImVec4 inactive_color{0.4f, 0.4f, 0.4f, 1.0f};
const float framebuffer_scale = ImGuiManager::GetGlobalScale();
ImGui::SetNextWindowSize(ImVec2(800.0f * framebuffer_scale, 800.0f * framebuffer_scale), ImGuiCond_FirstUseEver);
if (!ImGui::Begin("SPU State", nullptr))
{
ImGui::End();
return;
}
// status
if (ImGui::CollapsingHeader("Status", ImGuiTreeNodeFlags_DefaultOpen))
{
static constexpr std::array<const char*, 4> transfer_modes = {
{"Transfer Stopped", "Manual Write", "DMA Write", "DMA Read"}};
const std::array<float, 6> offsets = {{100.0f * framebuffer_scale, 200.0f * framebuffer_scale,
300.0f * framebuffer_scale, 420.0f * framebuffer_scale,
500.0f * framebuffer_scale, 600.0f * framebuffer_scale}};
const std::array<float, 6> offsets = {
{100.0f * scale, 200.0f * scale, 300.0f * scale, 420.0f * scale, 500.0f * scale, 600.0f * scale}};
ImGui::Text("Control: ");
ImGui::SameLine(offsets[0]);
@ -2698,6 +2689,4 @@ void SPU::DrawDebugStateWindow()
}
}
}
ImGui::End();
}

View File

@ -33,7 +33,7 @@ void DMARead(u32* words, u32 word_count);
void DMAWrite(const u32* words, u32 word_count);
// Render statistics debug window.
void DrawDebugStateWindow();
void DrawDebugStateWindow(float scale);
// Executes the SPU, generating any pending samples.
void GeneratePendingSamples();

View File

@ -1227,6 +1227,9 @@ bool System::RecreateGPU(GPURenderer renderer, bool force_recreate_device, bool
TimingEvents::DoState(sw);
}
if (force_recreate_device)
ImGuiManager::UpdateDebugWindowConfig();
// fix up vsync etc
UpdateSpeedLimiterState();
return true;
@ -1873,6 +1876,7 @@ bool System::BootSystem(SystemBootParameters parameters, Error* error)
PauseSystem(true);
UpdateSpeedLimiterState();
ImGuiManager::UpdateDebugWindowConfig();
ResetPerformanceCounters();
return true;
}
@ -1981,6 +1985,8 @@ void System::DestroySystem()
if (s_media_capture)
StopMediaCapture();
ImGuiManager::DestroyAllDebugWindows();
s_undo_load_state.reset();
#ifdef ENABLE_GDB_SERVER
@ -4507,6 +4513,8 @@ void System::CheckForSettingsChanges(const Settings& old_settings)
PostProcessing::UpdateSettings();
ImGuiManager::UpdateDebugWindowConfig();
#ifdef ENABLE_GDB_SERVER
if (g_settings.debugging.enable_gdb_server != old_settings.debugging.enable_gdb_server ||
g_settings.debugging.gdb_server_port != old_settings.debugging.gdb_server_port)
@ -5670,6 +5678,8 @@ bool System::PresentDisplay(bool explicit_present, u64 present_time)
// Debug windows are always rendered, otherwise mouse input breaks on skip.
ImGuiManager::RenderOverlayWindows();
if (IsValid())
ImGuiManager::RenderDebugWindows();
const GPUDevice::PresentResult pres =

View File

@ -488,7 +488,7 @@ void Timers::UpdateSysClkEvent()
s_state.sysclk_event.Schedule(GetTicksUntilNextInterrupt());
}
void Timers::DrawDebugStateWindow()
void Timers::DrawDebugStateWindow(float scale)
{
static constexpr u32 NUM_COLUMNS = 10;
static constexpr std::array<const char*, NUM_COLUMNS> column_names = {
@ -500,26 +500,17 @@ void Timers::DrawDebugStateWindow()
{{"SysClk", "HBlank", "SysClk", "HBlank"}},
{{"SysClk", "DotClk", "SysClk/8", "SysClk/8"}}}};
const float framebuffer_scale = ImGuiManager::GetGlobalScale();
ImGui::SetNextWindowSize(ImVec2(800.0f * framebuffer_scale, 115.0f * framebuffer_scale), ImGuiCond_FirstUseEver);
if (!ImGui::Begin("Timer State", nullptr))
{
ImGui::End();
return;
}
ImGui::Columns(NUM_COLUMNS);
ImGui::SetColumnWidth(0, 20.0f * framebuffer_scale);
ImGui::SetColumnWidth(1, 50.0f * framebuffer_scale);
ImGui::SetColumnWidth(2, 50.0f * framebuffer_scale);
ImGui::SetColumnWidth(3, 100.0f * framebuffer_scale);
ImGui::SetColumnWidth(4, 80.0f * framebuffer_scale);
ImGui::SetColumnWidth(5, 80.0f * framebuffer_scale);
ImGui::SetColumnWidth(6, 80.0f * framebuffer_scale);
ImGui::SetColumnWidth(7, 80.0f * framebuffer_scale);
ImGui::SetColumnWidth(8, 80.0f * framebuffer_scale);
ImGui::SetColumnWidth(9, 80.0f * framebuffer_scale);
ImGui::SetColumnWidth(0, 20.0f * scale);
ImGui::SetColumnWidth(1, 50.0f * scale);
ImGui::SetColumnWidth(2, 50.0f * scale);
ImGui::SetColumnWidth(3, 100.0f * scale);
ImGui::SetColumnWidth(4, 80.0f * scale);
ImGui::SetColumnWidth(5, 80.0f * scale);
ImGui::SetColumnWidth(6, 80.0f * scale);
ImGui::SetColumnWidth(7, 80.0f * scale);
ImGui::SetColumnWidth(8, 80.0f * scale);
ImGui::SetColumnWidth(9, 80.0f * scale);
for (const char* title : column_names)
{
@ -557,5 +548,4 @@ void Timers::DrawDebugStateWindow()
}
ImGui::Columns(1);
ImGui::End();
}

View File

@ -16,7 +16,7 @@ bool DoState(StateWrapper& sw);
void SetGate(u32 timer, bool state);
void DrawDebugStateWindow();
void DrawDebugStateWindow(float scale);
void CPUClocksChanged();

View File

@ -2092,14 +2092,13 @@ void MainWindow::connectSignals()
g_emu_thread->dumpSPURAM(filename);
});
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionDebugShowVRAM, "Debug", "ShowVRAM", false);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionDebugShowGPUState, "Debug", "ShowGPUState", false);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionDebugShowCDROMState, "Debug", "ShowCDROMState",
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionDebugShowGPUState, "DebugWindows", "GPU", false);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionDebugShowCDROMState, "DebugWindows", "CDROM", false);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionDebugShowSPUState, "DebugWindows", "SPU", false);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionDebugShowTimersState, "DebugWindows", "Timers",
false);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionDebugShowSPUState, "Debug", "ShowSPUState", false);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionDebugShowTimersState, "Debug", "ShowTimersState",
false);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionDebugShowMDECState, "Debug", "ShowMDECState", false);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionDebugShowDMAState, "Debug", "ShowDMAState", false);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionDebugShowMDECState, "DebugWindows", "MDEC", false);
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionDebugShowDMAState, "DebugWindows", "DMA", false);
}
void MainWindow::updateTheme()