From 13683d417cce0c9394e0bdcfb89c00df29374081 Mon Sep 17 00:00:00 2001 From: RedBlackAka <140876408+RedBlackAka@users.noreply.github.com> Date: Fri, 26 Dec 2025 23:00:40 +0100 Subject: [PATCH] UI: Small adjustments and cleanup, end emulation hotkey for debug builds (#1754) --- src/gui/wxgui/GeneralSettings2.cpp | 8 +- src/gui/wxgui/MainWindow.cpp | 147 ++++++++++++++----------- src/gui/wxgui/MainWindow.h | 1 + src/gui/wxgui/input/HotkeySettings.cpp | 11 ++ src/gui/wxgui/wxCemuConfig.cpp | 3 + src/gui/wxgui/wxCemuConfig.h | 3 + src/gui/wxgui/wxWindowSystem.cpp | 7 +- src/resource/cemu.rc | 2 +- 8 files changed, 111 insertions(+), 71 deletions(-) diff --git a/src/gui/wxgui/GeneralSettings2.cpp b/src/gui/wxgui/GeneralSettings2.cpp index 5e447eae..0c6968bc 100644 --- a/src/gui/wxgui/GeneralSettings2.cpp +++ b/src/gui/wxgui/GeneralSettings2.cpp @@ -219,14 +219,14 @@ wxPanel* GeneralSettings2::AddGeneralPage(wxNotebook* notebook) #ifndef ENABLE_DISCORD_RPC m_discord_presence->Disable(); #endif - //third_row->AddSpacer(10); + // third_row->AddSpacer(10); m_fullscreen_menubar = new wxCheckBox(box, wxID_ANY, _("Fullscreen menu bar")); m_fullscreen_menubar->SetToolTip(_("Displays the menu bar when Cemu is running in fullscreen mode and the mouse cursor is moved to the top")); third_row->Add(m_fullscreen_menubar, 0, botflag, 5); CountRowElement(); m_save_screenshot = new wxCheckBox(box, wxID_ANY, _("Save screenshot")); - m_save_screenshot->SetToolTip(_("Pressing the screenshot key (F12) will save a screenshot directly to the screenshots folder")); + m_save_screenshot->SetToolTip(_("Pressing the screenshot key will save a screenshot directly to the screenshots folder instead of to the clipboard")); third_row->Add(m_save_screenshot, 0, botflag, 5); CountRowElement(); @@ -235,7 +235,7 @@ wxPanel* GeneralSettings2::AddGeneralPage(wxNotebook* notebook) third_row->Add(m_disable_screensaver, 0, botflag, 5); CountRowElement(); - // Enable/disable feral interactive gamemode + // enable/disable feral interactive gamemode #if BOOST_OS_LINUX && defined(ENABLE_FERAL_GAMEMODE) m_feral_gamemode = new wxCheckBox(box, wxID_ANY, _("Enable Feral GameMode")); m_feral_gamemode->SetToolTip(_("Use FeralInteractive GameMode if installed.")); @@ -1099,7 +1099,7 @@ void GeneralSettings2::StoreConfig() #endif config.play_boot_sound = m_play_boot_sound->IsChecked(); config.disable_screensaver = m_disable_screensaver->IsChecked(); - // Toggle while a game is running + // toggle while a game is running if (CafeSystem::IsTitleRunning()) { ScreenSaver::SetInhibit(config.disable_screensaver); diff --git a/src/gui/wxgui/MainWindow.cpp b/src/gui/wxgui/MainWindow.cpp index 20372326..450fa02c 100644 --- a/src/gui/wxgui/MainWindow.cpp +++ b/src/gui/wxgui/MainWindow.cpp @@ -331,59 +331,59 @@ MainWindow::MainWindow() auto load_title_id = LaunchSettings::GetLoadTitleID(); bool quick_launch = false; - if (load_file) - { - MainWindow::RequestLaunchGame(load_file.value(), wxLaunchGameEvent::INITIATED_BY::COMMAND_LINE); - quick_launch = true; - } - else if (load_title_id) - { - TitleInfo info; - TitleId baseId; - if (CafeTitleList::FindBaseTitleId(load_title_id.value(), baseId) && CafeTitleList::GetFirstByTitleId(baseId, info)) - { - MainWindow::RequestLaunchGame(info.GetPath(), wxLaunchGameEvent::INITIATED_BY::COMMAND_LINE); - quick_launch = true; - } - else - { - wxString errorMsg = fmt::format("Title ID {:016x} not found", load_title_id.value()); - wxMessageBox(errorMsg, _("Error"), wxOK | wxCENTRE | wxICON_ERROR); + if (load_file) + { + MainWindow::RequestLaunchGame(load_file.value(), wxLaunchGameEvent::INITIATED_BY::COMMAND_LINE); + quick_launch = true; + } + else if (load_title_id) + { + TitleInfo info; + TitleId baseId; + if (CafeTitleList::FindBaseTitleId(load_title_id.value(), baseId) && CafeTitleList::GetFirstByTitleId(baseId, info)) + { + MainWindow::RequestLaunchGame(info.GetPath(), wxLaunchGameEvent::INITIATED_BY::COMMAND_LINE); + quick_launch = true; + } + else + { + wxString errorMsg = fmt::format("Title ID {:016x} not found", load_title_id.value()); + wxMessageBox(errorMsg, _("Error"), wxOK | wxCENTRE | wxICON_ERROR); - } - } - SetSizer(main_sizer); - if (!quick_launch) - { - CreateGameListAndStatusBar(); - } - else - { - // launching game via -g or -t option. Don't set up or load game list - m_game_list = nullptr; - m_info_bar = nullptr; - } - SetSizer(main_sizer); + } + } + SetSizer(main_sizer); + if (!quick_launch) + { + CreateGameListAndStatusBar(); + } + else + { + // launching game via -g or -t option. Don't set up or load game list + m_game_list = nullptr; + m_info_bar = nullptr; + } + SetSizer(main_sizer); - m_last_mouse_move_time = std::chrono::steady_clock::now(); + m_last_mouse_move_time = std::chrono::steady_clock::now(); - m_timer = new wxTimer(this, MAINFRAME_ID_TIMER1); - m_timer->Start(500); + m_timer = new wxTimer(this, MAINFRAME_ID_TIMER1); + m_timer->Start(500); - LoadSettings(); + LoadSettings(); - #ifdef ENABLE_DISCORD_RPC - if (GetWxGUIConfig().use_discord_presence) - m_discord = std::make_unique(); - #endif + #ifdef ENABLE_DISCORD_RPC + if (GetWxGUIConfig().use_discord_presence) + m_discord = std::make_unique(); + #endif - Bind(wxEVT_OPEN_GRAPHIC_PACK, &MainWindow::OnGraphicWindowOpen, this); - Bind(wxEVT_LAUNCH_GAME, &MainWindow::OnLaunchFromFile, this); + Bind(wxEVT_OPEN_GRAPHIC_PACK, &MainWindow::OnGraphicWindowOpen, this); + Bind(wxEVT_LAUNCH_GAME, &MainWindow::OnLaunchFromFile, this); - if (LaunchSettings::GDBStubEnabled()) - { - g_gdbstub = std::make_unique(GetConfig().gdb_port); - } + if (LaunchSettings::GDBStubEnabled()) + { + g_gdbstub = std::make_unique(GetConfig().gdb_port); + } } MainWindow::~MainWindow() @@ -599,12 +599,7 @@ bool MainWindow::FileLoad(const fs::path launchPath, wxLaunchGameEvent::INITIATE #endif if (GetConfig().disable_screensaver) - { ScreenSaver::SetInhibit(true); - // TODO: disable when only the game, not Cemu, is closed (a feature not yet implemented) - // currently unnecessary because this will happen automatically when Cemu closes - // ScreenSaver::SetInhibit(false); - } if (FullscreenEnabled()) SetFullScreen(true); @@ -684,13 +679,7 @@ void MainWindow::OnFileMenu(wxCommandEvent& event) } else if (menuId == MAINFRAME_MENU_ID_FILE_END_EMULATION) { - CafeSystem::ShutdownTitle(); - DestroyCanvas(); - m_game_launched = false; - RecreateMenu(); - CreateGameListAndStatusBar(); - DoLayout(); - UpdateChildWindowTitleRunningState(); + EndEmulation(); } } @@ -1046,14 +1035,13 @@ void MainWindow::OnDebugSetting(wxCommandEvent& event) if(!GetConfig().vk_accurate_barriers) wxMessageBox(_("Warning: Disabling the accurate barriers option will lead to flickering graphics but may improve performance. It is highly recommended to leave it turned on."), _("Accurate barriers are off"), wxOK); } - else if (event.GetId() == MAINFRAME_MENU_ID_DEBUG_GPU_CAPTURE) - { - cemu_assert_debug(g_renderer->GetType() == RendererAPI::Metal); - #if ENABLE_METAL - static_cast(g_renderer.get())->CaptureFrame(); + else if (event.GetId() == MAINFRAME_MENU_ID_DEBUG_GPU_CAPTURE) + { + cemu_assert_debug(g_renderer->GetType() == RendererAPI::Metal); + static_cast(g_renderer.get())->CaptureFrame(); + } #endif - } else if (event.GetId() == MAINFRAME_MENU_ID_DEBUG_AUDIO_AUX_ONLY) ActiveSettings::EnableAudioOnlyAux(event.IsChecked()); else if (event.GetId() == MAINFRAME_MENU_ID_DEBUG_DUMP_RAM) @@ -1767,6 +1755,34 @@ void MainWindow::SetFullScreen(bool state) SetMenuVisible(true); } +void MainWindow::EndEmulation() // unfinished - memory leaks and crashes after repeated use (after 3x usually) +{ + CafeSystem::ShutdownTitle(); + DestroyCanvas(); + m_game_launched = false; + m_launched_game_name.clear(); + #ifdef ENABLE_DISCORD_RPC + if (m_discord) + m_discord->UpdatePresence(DiscordPresence::Idling, ""); + #endif + + if (GetConfig().disable_screensaver) + ScreenSaver::SetInhibit(false); + + // close memory searcher if created + if (m_toolWindow) + { + m_toolWindow->Close(); + m_toolWindow = nullptr; + m_memorySearcherMenuItem->Enable(false); + } + + RecreateMenu(); + CreateGameListAndStatusBar(); + DoLayout(); + UpdateChildWindowTitleRunningState(); +} + void MainWindow::SetMenuVisible(bool state) { if (m_menu_visible == state) @@ -2163,6 +2179,7 @@ void MainWindow::RecreateMenu() // add 'Stop emulation' menu entry to file menu #ifdef CEMU_DEBUG_ASSERT m_fileMenu->Append(MAINFRAME_MENU_ID_FILE_END_EMULATION, _("Stop emulation")); + m_fileMenuSeparator1 = m_fileMenu->AppendSeparator() #endif } @@ -2264,7 +2281,7 @@ void MainWindow::RecreateMenu() // nfc submenu wxMenu* nfcMenu = new wxMenu(); m_nfcMenu = nfcMenu; - nfcMenu->Append(MAINFRAME_MENU_ID_NFC_TOUCH_NFC_FILE, _("&Scan NFC tag from file"))->Enable(false); + nfcMenu->Append(MAINFRAME_MENU_ID_NFC_TOUCH_NFC_FILE, _("&Scan NFC tag/amiibo from file"))->Enable(false); m_menuBar->Append(nfcMenu, _("&NFC")); m_nfcMenuSeparator0 = nullptr; // debug->logging submenu diff --git a/src/gui/wxgui/MainWindow.h b/src/gui/wxgui/MainWindow.h index 0e80b16d..eec043b8 100644 --- a/src/gui/wxgui/MainWindow.h +++ b/src/gui/wxgui/MainWindow.h @@ -71,6 +71,7 @@ public: [[nodiscard]] bool IsGameLaunched() const { return m_game_launched; } void SetFullScreen(bool state); + void EndEmulation(); void SetMenuVisible(bool state); void UpdateNFCMenu(); bool IsMenuHidden() const; diff --git a/src/gui/wxgui/input/HotkeySettings.cpp b/src/gui/wxgui/input/HotkeySettings.cpp index 0bf59025..cadf3e9d 100644 --- a/src/gui/wxgui/input/HotkeySettings.cpp +++ b/src/gui/wxgui/input/HotkeySettings.cpp @@ -6,6 +6,7 @@ #include "HotkeySettings.h" #include "MainWindow.h" +#include #include #if BOOST_OS_WINDOWS @@ -157,6 +158,9 @@ HotkeySettings::HotkeySettings(wxWindow* parent) CreateHotkeyRow(_tr("Toggle fullscreen"), s_cfgHotkeys.toggleFullscreen); CreateHotkeyRow(_tr("Take screenshot"), s_cfgHotkeys.takeScreenshot); CreateHotkeyRow(_tr("Toggle fast-forward"), s_cfgHotkeys.toggleFastForward); +#ifdef CEMU_DEBUG_ASSERT + CreateHotkeyRow(_tr("End emulation"), s_cfgHotkeys.endEmulation); +#endif m_controllerTimer = new wxTimer(this); Bind(wxEVT_TIMER, &HotkeySettings::OnControllerTimer, this); @@ -192,6 +196,13 @@ void HotkeySettings::Init(MainWindow* mainWindowFrame) {&s_cfgHotkeys.toggleFastForward, [](void) { ActiveSettings::SetTimerShiftFactor((ActiveSettings::GetTimerShiftFactor() < 3) ? 3 : 1); }}, +#ifdef CEMU_DEBUG_ASSERT + {&s_cfgHotkeys.endEmulation, [](void) { + wxTheApp->CallAfter([]() { + s_mainWindow->EndEmulation(); + }); + }}, +#endif }); s_keyboardHotkeyToFuncMap.reserve(s_cfgHotkeyToFuncMap.size()); diff --git a/src/gui/wxgui/wxCemuConfig.cpp b/src/gui/wxgui/wxCemuConfig.cpp index bbd24ab4..3c5080d2 100644 --- a/src/gui/wxgui/wxCemuConfig.cpp +++ b/src/gui/wxgui/wxCemuConfig.cpp @@ -115,6 +115,9 @@ void wxCemuConfig::Load(XMLConfigParser& parser) hotkeys.toggleFullscreenAlt = xml_hotkeys.get("ToggleFullscreenAlt", sHotkeyCfg{uKeyboardHotkey{WXK_CONTROL_M, true}}); // ALT+ENTER hotkeys.takeScreenshot = xml_hotkeys.get("TakeScreenshot", sHotkeyCfg{uKeyboardHotkey{WXK_F12}}); hotkeys.toggleFastForward = xml_hotkeys.get("ToggleFastForward", sHotkeyCfg{}); +#ifdef CEMU_DEBUG_ASSERT + hotkeys.endEmulation = xml_hotkeys.get("EndEmulation", sHotkeyCfg{uKeyboardHotkey{WXK_F5}}); +#endif } void wxCemuConfig::Save(XMLConfigParser& config) diff --git a/src/gui/wxgui/wxCemuConfig.h b/src/gui/wxgui/wxCemuConfig.h index 9463d4df..a2f758dd 100644 --- a/src/gui/wxgui/wxCemuConfig.h +++ b/src/gui/wxgui/wxCemuConfig.h @@ -127,6 +127,9 @@ struct wxCemuConfig sHotkeyCfg exitFullscreen; sHotkeyCfg takeScreenshot; sHotkeyCfg toggleFastForward; +#ifdef CEMU_DEBUG_ASSERT + sHotkeyCfg endEmulation; +#endif } hotkeys{}; void AddRecentlyLaunchedFile(std::string_view file); diff --git a/src/gui/wxgui/wxWindowSystem.cpp b/src/gui/wxgui/wxWindowSystem.cpp index 48c015c1..4b199741 100644 --- a/src/gui/wxgui/wxWindowSystem.cpp +++ b/src/gui/wxgui/wxWindowSystem.cpp @@ -84,7 +84,7 @@ void WindowSystem::UpdateWindowTitles(bool isIdle, bool isLoading, double fps) } if (isLoading) { - windowText.append(" - loading..."); + windowText.append(" - Loading..."); if (g_mainFrame) g_mainFrame->AsyncSetTitle(windowText); return; @@ -101,6 +101,11 @@ void WindowSystem::UpdateWindowTitles(bool isIdle, bool isLoading, double fps) case RendererAPI::Vulkan: renderer = "[Vulkan]"; break; +#if ENABLE_METAL + case RendererAPI::Metal: + renderer = "[Metal]"; + break; +#endif default:; } } diff --git a/src/resource/cemu.rc b/src/resource/cemu.rc index fb397056..e6332032 100644 --- a/src/resource/cemu.rc +++ b/src/resource/cemu.rc @@ -90,7 +90,7 @@ BEGIN BEGIN BLOCK "040904b0" BEGIN - VALUE "FileDescription", "Wii U emulator" + VALUE "FileDescription", "Cemu Wii U emulator" VALUE "InternalName", "Cemu" VALUE "LegalCopyright", "Team Cemu" VALUE "OriginalFilename", "Cemu.exe"