From 4007e973f3cebbf74dcc21466579a47d56874515 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 1 Feb 2026 14:28:38 +0100 Subject: [PATCH 1/7] Driveby cleanup: Remove use of legacy --- Windows/Debugger/CtrlDisAsmView.cpp | 3 +-- Windows/Debugger/CtrlDisAsmView.h | 4 +--- Windows/Debugger/CtrlRegisterList.cpp | 3 +-- Windows/Debugger/CtrlRegisterList.h | 4 +--- Windows/GEDebugger/CtrlDisplayListView.cpp | 5 ++--- Windows/GEDebugger/CtrlDisplayListView.h | 4 +--- Windows/GEDebugger/GEDebugger.cpp | 2 +- Windows/MainWindow.cpp | 4 ++-- Windows/TouchInputHandler.cpp | 2 +- Windows/stdafx.h | 7 +++---- 10 files changed, 14 insertions(+), 24 deletions(-) diff --git a/Windows/Debugger/CtrlDisAsmView.cpp b/Windows/Debugger/CtrlDisAsmView.cpp index d6c932db9d..0c4f361008 100644 --- a/Windows/Debugger/CtrlDisAsmView.cpp +++ b/Windows/Debugger/CtrlDisAsmView.cpp @@ -24,10 +24,9 @@ #include "Common/Data/Encoding/Utf8.h" #include "Common/System/Display.h" -#include #include -TCHAR CtrlDisAsmView::szClassName[] = _T("CtrlDisAsmView"); +constexpr wchar_t *szClassName = L"CtrlDisAsmView"; static constexpr UINT_PTR IDT_REDRAW = 0xC0DE0001; static constexpr UINT REDRAW_DELAY = 1000 / 60; diff --git a/Windows/Debugger/CtrlDisAsmView.h b/Windows/Debugger/CtrlDisAsmView.h index fe908ddad0..d0432c0274 100644 --- a/Windows/Debugger/CtrlDisAsmView.h +++ b/Windows/Debugger/CtrlDisAsmView.h @@ -25,8 +25,7 @@ #include "Core/MIPS/MIPSDebugInterface.h" #include "Core/Debugger/DisassemblyManager.h" -class CtrlDisAsmView -{ +class CtrlDisAsmView { HWND wnd; HFONT font; HFONT boldfont; @@ -41,7 +40,6 @@ class CtrlDisAsmView bool hasFocus; bool showHex; MIPSDebugInterface *debugger; - static TCHAR szClassName[]; u32 windowStart; int visibleRows; diff --git a/Windows/Debugger/CtrlRegisterList.cpp b/Windows/Debugger/CtrlRegisterList.cpp index 0e1d634002..21c69d2499 100644 --- a/Windows/Debugger/CtrlRegisterList.cpp +++ b/Windows/Debugger/CtrlRegisterList.cpp @@ -1,5 +1,4 @@ #include -#include #include "Common/System/Display.h" #include "Common/Data/Encoding/Utf8.h" @@ -21,7 +20,7 @@ enum { REGISTER_PC = 32, REGISTER_HI, REGISTER_LO, REGISTERS_END }; -TCHAR CtrlRegisterList::szClassName[] = _T("CtrlRegisterList"); +constexpr wchar_t *szClassName = L"CtrlRegisterList"; static constexpr UINT_PTR IDT_REDRAW = 0xC0DE0001; static constexpr UINT REDRAW_DELAY = 1000 / 60; diff --git a/Windows/Debugger/CtrlRegisterList.h b/Windows/Debugger/CtrlRegisterList.h index 41fa19c91f..211e6203c7 100644 --- a/Windows/Debugger/CtrlRegisterList.h +++ b/Windows/Debugger/CtrlRegisterList.h @@ -18,8 +18,7 @@ #include "Core/MIPS/MIPSDebugInterface.h" -class CtrlRegisterList -{ +class CtrlRegisterList { HWND wnd; HFONT font; RECT rect; @@ -33,7 +32,6 @@ class CtrlRegisterList bool selecting = false; bool hasFocus = false; MIPSDebugInterface *cpu = nullptr; - static TCHAR szClassName[]; u32 lastPC = 0; u32 *lastCat0Values = nullptr; diff --git a/Windows/GEDebugger/CtrlDisplayListView.cpp b/Windows/GEDebugger/CtrlDisplayListView.cpp index 6c0f41961f..c7a59ada2e 100644 --- a/Windows/GEDebugger/CtrlDisplayListView.cpp +++ b/Windows/GEDebugger/CtrlDisplayListView.cpp @@ -1,5 +1,4 @@ #include -#include #include "Common/Data/Encoding/Utf8.h" #include "Common/StringUtils.h" #include "Common/System/Display.h" @@ -13,14 +12,14 @@ #include "GPU/Debugger/Breakpoints.h" #include "GPU/GPUState.h" -LPCTSTR CtrlDisplayListView::windowClass = _T("CtrlDisplayListView"); +constexpr wchar_t *szWindowClass = L"CtrlDisplayListView"; void CtrlDisplayListView::registerClass() { WNDCLASSEX wndClass; wndClass.cbSize = sizeof(wndClass); - wndClass.lpszClassName = windowClass; + wndClass.lpszClassName = szWindowClass; wndClass.hInstance = GetModuleHandle(0); wndClass.lpfnWndProc = wndProc; wndClass.hCursor = LoadCursor (NULL, IDC_ARROW); diff --git a/Windows/GEDebugger/CtrlDisplayListView.h b/Windows/GEDebugger/CtrlDisplayListView.h index 92244bb96c..048f57adf3 100644 --- a/Windows/GEDebugger/CtrlDisplayListView.h +++ b/Windows/GEDebugger/CtrlDisplayListView.h @@ -4,11 +4,9 @@ #include "Common/CommonWindows.h" #include "GPU/GPUDefinitions.h" -class CtrlDisplayListView -{ +class CtrlDisplayListView { HWND wnd; RECT rect; - static LPCTSTR windowClass; DisplayList list; HFONT font; diff --git a/Windows/GEDebugger/GEDebugger.cpp b/Windows/GEDebugger/GEDebugger.cpp index 26f68a475c..fe7de3734e 100644 --- a/Windows/GEDebugger/GEDebugger.cpp +++ b/Windows/GEDebugger/GEDebugger.cpp @@ -437,7 +437,7 @@ void CGEDebugger::DescribeSecondPreview(const GPUgstate &state, char desc[256]) } void CGEDebugger::PreviewExport(const GPUDebugBuffer *dbgBuffer) { - const TCHAR *filter = L"PNG Image (*.png)\0*.png\0JPEG Image (*.jpg)\0*.jpg\0All files\0*.*\0\0"; + constexpr wchar_t *filter = L"PNG Image (*.png)\0*.png\0JPEG Image (*.jpg)\0*.jpg\0All files\0*.*\0\0"; std::string fn; if (W32Util::BrowseForFileName(false, GetDlgHandle(), L"Save Preview Image...", nullptr, filter, L"png", fn)) { ScreenshotFormat fmt = fn.find(".jpg") != fn.npos ? ScreenshotFormat::JPG : ScreenshotFormat::PNG; diff --git a/Windows/MainWindow.cpp b/Windows/MainWindow.cpp index e94bb16f71..fbe19b48f5 100644 --- a/Windows/MainWindow.cpp +++ b/Windows/MainWindow.cpp @@ -153,7 +153,7 @@ namespace MainWindow bool noFocusPause = false; // TOGGLE_PAUSE state to override pause on lost focus bool trapMouse = true; // Handles some special cases(alt+tab, win menu) when game is running and mouse is confined - static const TCHAR szWindowClass[] = L"PPSSPPWnd"; + static constexpr wchar_t *szWindowClass = L"PPSSPPWnd"; static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); @@ -174,7 +174,7 @@ namespace MainWindow wcex.lpfnWndProc = (WNDPROC)WndProc; wcex.hInstance = hInstance; wcex.hCursor = LoadCursor(NULL, IDC_ARROW); - wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); + wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); // or NULL? wcex.lpszMenuName = (LPCWSTR)IDR_MENU1; wcex.lpszClassName = szWindowClass; wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_PPSSPP); diff --git a/Windows/TouchInputHandler.cpp b/Windows/TouchInputHandler.cpp index 2f7b5ec644..2bedf608f2 100644 --- a/Windows/TouchInputHandler.cpp +++ b/Windows/TouchInputHandler.cpp @@ -99,7 +99,7 @@ void TouchInputHandler::handleTouchEvent(HWND hWnd, UINT message, WPARAM wParam, // disable the press and hold gesture for the given window void TouchInputHandler::disablePressAndHold(HWND hWnd) { // The atom identifier and Tablet PC atom - LPCTSTR tabletAtom = _T("MicrosoftTabletPenServiceProperty"); + wchar_t *tabletAtom = L"MicrosoftTabletPenServiceProperty"; ATOM atomID = GlobalAddAtom(tabletAtom); // If getting the ID failed, return false diff --git a/Windows/stdafx.h b/Windows/stdafx.h index 95352445fb..4950ad043c 100644 --- a/Windows/stdafx.h +++ b/Windows/stdafx.h @@ -41,12 +41,11 @@ #include #include -#include -#include +#include #define _USE_MATH_DEFINES -#include -#include +#include +#include #include #include #include From 99a1ddb6578c707df545f4fce072281c932eaf37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 1 Feb 2026 15:03:23 +0100 Subject: [PATCH 2/7] Assorted code cleanup --- Windows/GEDebugger/TabVertices.cpp | 5 +- Windows/MainWindow.cpp | 98 ++++++++---------------------- Windows/MainWindowMenu.cpp | 5 +- Windows/W32Util/Misc.cpp | 76 +++++++++++++---------- Windows/W32Util/Misc.h | 9 ++- Windows/main.cpp | 3 +- 6 files changed, 79 insertions(+), 117 deletions(-) diff --git a/Windows/GEDebugger/TabVertices.cpp b/Windows/GEDebugger/TabVertices.cpp index 25c64b1669..9dd559ac87 100644 --- a/Windows/GEDebugger/TabVertices.cpp +++ b/Windows/GEDebugger/TabVertices.cpp @@ -544,10 +544,11 @@ void CtrlMatrixList::OnRightClick(int row, int column, const POINT &point) { case ID_DISASM_COPYINSTRUCTIONDISASM: { + // Not really copy instruction, more like copy a float. float val; if (GetValue(gpuDebug->GetGState(), row, column, val)) { - wchar_t dest[512]; - swprintf(dest, 511, L"%f", val); + char dest[128]; + snprintf(dest, sizeof(dest), "%f", val); W32Util::CopyTextToClipboard(GetHandle(), dest); } break; diff --git a/Windows/MainWindow.cpp b/Windows/MainWindow.cpp index fbe19b48f5..15f7cfd13f 100644 --- a/Windows/MainWindow.cpp +++ b/Windows/MainWindow.cpp @@ -125,9 +125,8 @@ static std::wstring g_windowTitle; namespace MainWindow { - HWND hwndMain; - HWND hwndGameList; - TouchInputHandler touchHandler; + static HWND hwndMain; + static TouchInputHandler touchHandler; static HMENU g_hMenu; @@ -151,15 +150,14 @@ namespace MainWindow // gross hack bool noFocusPause = false; // TOGGLE_PAUSE state to override pause on lost focus - bool trapMouse = true; // Handles some special cases(alt+tab, win menu) when game is running and mouse is confined + static bool trapMouse = true; // Handles some special cases(alt+tab, win menu) when game is running and mouse is confined static constexpr wchar_t *szWindowClass = L"PPSSPPWnd"; static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); - HWND GetHWND() { - return hwndMain; - } + HWND GetHWND() { return hwndMain; } + HINSTANCE GetHInstance() { return hInst; } void SetKeepScreenBright(bool keepBright) { g_keepScreenBright = keepBright; @@ -167,8 +165,7 @@ namespace MainWindow void Init(HINSTANCE hInstance) { // Register classes - Main Window - WNDCLASSEX wcex; - memset(&wcex, 0, sizeof(wcex)); + WNDCLASSEX wcex{}; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = 0; // Show in taskbar wcex.lpfnWndProc = (WNDPROC)WndProc; @@ -599,37 +596,6 @@ namespace MainWindow vfpudlg = nullptr; } - RECT MapRectFromClientToWndCoords(HWND hwnd, const RECT & r) - { - RECT wnd_coords = r; - - // map to screen - MapWindowPoints(hwnd, NULL, reinterpret_cast(&wnd_coords), 2); - - RECT scr_coords; - GetWindowRect(hwnd, &scr_coords); - - // map to window coords by substracting the window coord origin in - // screen coords. - OffsetRect(&wnd_coords, -scr_coords.left, -scr_coords.top); - - return wnd_coords; - } - - RECT GetNonclientMenuBorderRect(HWND hwnd) - { - RECT r; - GetClientRect(hwnd, &r); - r = MapRectFromClientToWndCoords(hwnd, r); - int y = r.top - 1; - return { - r.left, - y, - r.right, - y + 1 - }; - } - bool ConfirmAction(HWND hWnd, bool actionIsReset) { const GlobalUIState state = GetUIState(); if (state == UISTATE_MENU || state == UISTATE_EXIT) { @@ -780,7 +746,7 @@ namespace MainWindow auto result = DefWindowProc(hWnd, message, wParam, lParam); // Paint over the line with pure black. Could also try to figure out the dark theme color. HDC hdc = GetWindowDC(hWnd); - RECT r = GetNonclientMenuBorderRect(hWnd); + RECT r = W32Util::GetNonclientMenuBorderRect(hWnd); HBRUSH red = CreateSolidBrush(RGB(0, 0, 0)); FillRect(hdc, &r, red); DeleteObject(red); @@ -999,9 +965,9 @@ namespace MainWindow case WM_DROPFILES: { - if (!MainThread_Ready()) + if (!MainThread_Ready()) { return DefWindowProc(hWnd, message, wParam, lParam); - + } const HDROP hdrop = (HDROP)wParam; const int count = DragQueryFile(hdrop, 0xFFFFFFFF, 0, 0); if (count != 1) { @@ -1114,16 +1080,14 @@ namespace MainWindow } return DefWindowProc(hWnd, message, wParam, lParam); case WM_SETTINGCHANGE: - { - if (g_darkModeSupported && IsColorSchemeChangeMessage(lParam)) - SendMessageW(hWnd, WM_THEMECHANGED, 0, 0); + if (g_darkModeSupported && IsColorSchemeChangeMessage(lParam)) { + SendMessageW(hWnd, WM_THEMECHANGED, 0, 0); } return DefWindowProc(hWnd, message, wParam, lParam); case WM_THEMECHANGED: { - if (g_darkModeSupported) - { + if (g_darkModeSupported) { _AllowDarkModeForWindow(hWnd, g_darkModeEnabled); RefreshTitleBarThemeColor(hWnd); } @@ -1144,13 +1108,10 @@ namespace MainWindow case ImGuiMouseCursor_ResizeNWSE: win32_cursor = IDC_SIZENWSE; break; case ImGuiMouseCursor_Hand: win32_cursor = IDC_HAND; break; case ImGuiMouseCursor_NotAllowed: win32_cursor = IDC_NO; break; + default: break; } } - if (win32_cursor) { - SetCursor(::LoadCursor(nullptr, win32_cursor)); - } else { - SetCursor(nullptr); - } + SetCursor(win32_cursor ? ::LoadCursor(nullptr, win32_cursor) : nullptr); return TRUE; } else { return DefWindowProc(hWnd, message, wParam, lParam); @@ -1165,8 +1126,8 @@ namespace MainWindow // Hack: Take the opportunity to show the cursor. mouseButtonDown = true; - float x = GET_X_LPARAM(lParam) * g_display.dpi_scale_x; - float y = GET_Y_LPARAM(lParam) * g_display.dpi_scale_y; + const float x = GET_X_LPARAM(lParam) * g_display.dpi_scale_x; + const float y = GET_Y_LPARAM(lParam) * g_display.dpi_scale_y; WindowsRawInput::SetMousePos(x, y); TouchInput touch{}; @@ -1206,6 +1167,7 @@ namespace MainWindow mouseButtonDown = (wParam & MK_LBUTTON) != 0; int cursorX = GET_X_LPARAM(lParam); int cursorY = GET_Y_LPARAM(lParam); + // Require at least 2 pixels of movement to reset the hide timer. if (abs(cursorX - prevCursorX) > 1 || abs(cursorY - prevCursorY) > 1) { hideCursor = false; SetTimer(hwndMain, TIMER_CURSORMOVEUPDATE, CURSORUPDATE_MOVE_TIMESPAN_MS, 0); @@ -1213,8 +1175,8 @@ namespace MainWindow prevCursorX = cursorX; prevCursorY = cursorY; - float x = (float)cursorX * g_display.dpi_scale_x; - float y = (float)cursorY * g_display.dpi_scale_y; + const float x = (float)cursorX * g_display.dpi_scale_x; + const float y = (float)cursorY * g_display.dpi_scale_y; WindowsRawInput::SetMousePos(x, y); // Mouse moves now happen also when no button is pressed. @@ -1239,8 +1201,8 @@ namespace MainWindow // Hack: Take the opportunity to hide the cursor. mouseButtonDown = false; - float x = (float)GET_X_LPARAM(lParam) * g_display.dpi_scale_x; - float y = (float)GET_Y_LPARAM(lParam) * g_display.dpi_scale_y; + const float x = (float)GET_X_LPARAM(lParam) * g_display.dpi_scale_x; + const float y = (float)GET_Y_LPARAM(lParam) * g_display.dpi_scale_y; WindowsRawInput::SetMousePos(x, y); TouchInput touch{}; @@ -1259,28 +1221,22 @@ namespace MainWindow case WM_RBUTTONDOWN: { - float x = GET_X_LPARAM(lParam) * g_display.dpi_scale_x; - float y = GET_Y_LPARAM(lParam) * g_display.dpi_scale_y; - TouchInput touch{}; touch.buttons = 2; touch.flags = TouchInputFlags::DOWN | TouchInputFlags::MOUSE; - touch.x = x; - touch.y = y; + touch.x = GET_X_LPARAM(lParam) * g_display.dpi_scale_x; + touch.y = GET_Y_LPARAM(lParam) * g_display.dpi_scale_y; NativeTouch(touch); break; } case WM_RBUTTONUP: { - float x = GET_X_LPARAM(lParam) * g_display.dpi_scale_x; - float y = GET_Y_LPARAM(lParam) * g_display.dpi_scale_y; - TouchInput touch{}; touch.buttons = 2; touch.flags = TouchInputFlags::UP | TouchInputFlags::MOUSE; - touch.x = x; - touch.y = y; + touch.x = GET_X_LPARAM(lParam) * g_display.dpi_scale_x; + touch.y = GET_Y_LPARAM(lParam) * g_display.dpi_scale_y; NativeTouch(touch); break; } @@ -1291,10 +1247,6 @@ namespace MainWindow return 0; } - HINSTANCE GetHInstance() { - return hInst; - } - void ToggleDebugConsoleVisibility() { if (!g_Config.bEnableLogging) { g_logManager.GetConsoleListener()->Show(false); diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp index 0ac55669d9..04773bc645 100644 --- a/Windows/MainWindowMenu.cpp +++ b/Windows/MainWindowMenu.cpp @@ -62,7 +62,6 @@ extern bool g_TakeScreenshot; namespace MainWindow { - extern HINSTANCE hInst; extern bool noFocusPause; std::vector g_topLevelMenus; HMENU g_hMenuBackend; @@ -842,7 +841,7 @@ namespace MainWindow { case ID_DEBUG_EXTRACTFILE: { std::string filename; - if (!InputBox_GetString(hInst, hWnd, L"Disc filename", filename, filename)) { + if (!InputBox_GetString(MainWindow::GetHInstance(), hWnd, L"Disc filename", filename, filename)) { break; } const char *lastSlash = strrchr(filename.c_str(), '/'); @@ -960,7 +959,7 @@ namespace MainWindow { case ID_HELP_ABOUT: DialogManager::EnableAll(FALSE); - DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)AboutDlgProc); + DialogBox(MainWindow::GetHInstance(), (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)AboutDlgProc); DialogManager::EnableAll(TRUE); break; diff --git a/Windows/W32Util/Misc.cpp b/Windows/W32Util/Misc.cpp index 4dadb210d6..a1eb1435c1 100644 --- a/Windows/W32Util/Misc.cpp +++ b/Windows/W32Util/Misc.cpp @@ -22,8 +22,31 @@ bool KeyDownAsync(int vkey) { namespace W32Util { - void CenterWindow(HWND hwnd) - { + static RECT MapRectFromClientToWndCoords(HWND hwnd, const RECT &r) { + RECT wnd_coords = r; + // map to screen + MapWindowPoints(hwnd, NULL, reinterpret_cast(&wnd_coords), 2); + RECT scr_coords; + GetWindowRect(hwnd, &scr_coords); + // map to window coords by substracting the window coord origin in screen coords. + OffsetRect(&wnd_coords, -scr_coords.left, -scr_coords.top); + return wnd_coords; + } + + RECT GetNonclientMenuBorderRect(HWND hwnd) { + RECT r; + GetClientRect(hwnd, &r); + r = MapRectFromClientToWndCoords(hwnd, r); + const int y = r.top - 1; + return { + r.left, + y, + r.right, + y + 1 + }; + } + + void CenterWindow(HWND hwnd) { HWND hwndParent; RECT rect, rectP; int width, height; @@ -57,19 +80,17 @@ namespace W32Util MoveWindow(hwnd, x, y, width, height, FALSE); } - BOOL CopyTextToClipboard(HWND hwnd, const char *text) { + bool CopyTextToClipboard(HWND hWnd, std::string_view text) { std::wstring wtext = ConvertUTF8ToWString(text); - return CopyTextToClipboard(hwnd, wtext); - } + if (!OpenClipboard(hWnd)) { + return false; + } - BOOL CopyTextToClipboard(HWND hwnd, const std::wstring &wtext) { - if (!OpenClipboard(hwnd)) - return FALSE; EmptyClipboard(); HANDLE hglbCopy = GlobalAlloc(GMEM_MOVEABLE, (wtext.size() + 1) * sizeof(wchar_t)); - if (hglbCopy == NULL) { + if (!hglbCopy) { CloseClipboard(); - return FALSE; + return false; } // Lock the handle and copy the text to the buffer. @@ -82,13 +103,11 @@ namespace W32Util SetClipboardData(CF_UNICODETEXT, hglbCopy); } CloseClipboard(); - return lptstrCopy ? TRUE : FALSE; + return lptstrCopy != nullptr; } void MakeTopMost(HWND hwnd, bool topMost) { - HWND style = HWND_NOTOPMOST; - if (topMost) style = HWND_TOPMOST; - SetWindowPos(hwnd, style, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE); + SetWindowPos(hwnd, topMost ? HWND_TOPMOST : HWND_NOTOPMOST, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE); } void GetWindowRes(HWND hWnd, int *xres, int *yres) { @@ -98,7 +117,7 @@ namespace W32Util *yres = rc.bottom - rc.top; } - void ShowFileInFolder(const std::string &path) { + void ShowFileInFolder(std::string_view path) { // SHParseDisplayName can't handle relative paths, so normalize first. std::string resolved = ReplaceAll(File::ResolvePath(path), "/", "\\"); @@ -557,8 +576,7 @@ LRESULT CALLBACK GenericListControl::wndProc(HWND hwnd, UINT msg, WPARAM wParam, return (LRESULT)CallWindowProc((WNDPROC)list->oldProc,hwnd,msg,wParam,lParam); } -void GenericListControl::ProcessCopy() -{ +void GenericListControl::ProcessCopy() { int start = GetSelectedIndex(); int size; if (start == -1) @@ -569,15 +587,12 @@ void GenericListControl::ProcessCopy() CopyRows(start, size); } -void GenericListControl::CopyRows(int start, int size) -{ +void GenericListControl::CopyRows(int start, int size) { std::wstring data; - if (start == 0 && size == GetRowCount()) - { + if (start == 0 && size == GetRowCount()) { // Let's also copy the header if everything is selected. - for (int c = 0; c < columnCount; ++c) - { + for (int c = 0; c < columnCount; ++c) { data.append(columns[c].name); if (c < columnCount - 1) data.append(L"\t"); @@ -586,10 +601,8 @@ void GenericListControl::CopyRows(int start, int size) } } - for (int r = start; r < start + size; ++r) - { - for (int c = 0; c < columnCount; ++c) - { + for (int r = start; r < start + size; ++r) { + for (int c = 0; c < columnCount; ++c) { stringBuffer[0] = 0; GetColumnText(stringBuffer, ARRAY_SIZE(stringBuffer), r, c); data.append(stringBuffer); @@ -599,15 +612,14 @@ void GenericListControl::CopyRows(int start, int size) data.append(L"\r\n"); } } - W32Util::CopyTextToClipboard(handle, data); + + W32Util::CopyTextToClipboard(handle, ConvertWStringToUTF8(data)); } -void GenericListControl::SelectAll() -{ +void GenericListControl::SelectAll() { ListView_SetItemState(handle, -1, LVIS_SELECTED, LVIS_SELECTED); } -int GenericListControl::GetSelectedIndex() -{ +int GenericListControl::GetSelectedIndex() { return ListView_GetNextItem(handle, -1, LVNI_SELECTED); } diff --git a/Windows/W32Util/Misc.h b/Windows/W32Util/Misc.h index e2c31ef813..b173b241a6 100644 --- a/Windows/W32Util/Misc.h +++ b/Windows/W32Util/Misc.h @@ -6,11 +6,9 @@ #include "Common/CommonWindows.h" -namespace W32Util -{ +namespace W32Util { void CenterWindow(HWND hwnd); - BOOL CopyTextToClipboard(HWND hwnd, const char *text); - BOOL CopyTextToClipboard(HWND hwnd, const std::wstring &wtext); + bool CopyTextToClipboard(HWND hwnd, std::string_view text); void MakeTopMost(HWND hwnd, bool topMost); void ExitAndRestart(bool overrideArgs = false, const std::string &args = ""); void SpawnNewInstance(bool overrideArgs = false, const std::string &args = ""); @@ -18,7 +16,8 @@ namespace W32Util void GetSelfExecuteParams(std::wstring &workingDirectory, std::wstring &moduleFilename); void GetWindowRes(HWND hWnd, int *xres, int *yres); - void ShowFileInFolder(const std::string &path); + void ShowFileInFolder(std::string_view path); + RECT GetNonclientMenuBorderRect(HWND hwnd); struct ClipboardData { ClipboardData(const char *format, size_t sz); diff --git a/Windows/main.cpp b/Windows/main.cpp index e1f1de787c..04fe408a8d 100644 --- a/Windows/main.cpp +++ b/Windows/main.cpp @@ -618,8 +618,7 @@ bool System_MakeRequest(SystemRequestType type, int requestId, const std::string } case SystemRequestType::COPY_TO_CLIPBOARD: { - std::wstring data = ConvertUTF8ToWString(param1); - W32Util::CopyTextToClipboard(MainWindow::GetHWND(), data); + W32Util::CopyTextToClipboard(MainWindow::GetHWND(), param1); return true; } case SystemRequestType::SET_WINDOW_TITLE: From 670eb7b3b670c3c28444fe94b2f4a5924669d7b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 1 Feb 2026 15:20:05 +0100 Subject: [PATCH 3/7] Header cleanup --- Common/System/System.h | 1 + Windows/MainWindow.cpp | 11 +---------- Windows/MainWindowMenu.cpp | 34 ++++++++++++---------------------- Windows/W32Util/ShellUtil.h | 1 - Windows/main.cpp | 4 +++- 5 files changed, 17 insertions(+), 34 deletions(-) diff --git a/Common/System/System.h b/Common/System/System.h index b08ad08ce1..88e7e1ac3d 100644 --- a/Common/System/System.h +++ b/Common/System/System.h @@ -47,6 +47,7 @@ enum class LaunchUrlType { BROWSER_URL, MARKET_URL, EMAIL_ADDRESS, + LOCAL_FILE, }; void System_Vibrate(int length_ms); diff --git a/Windows/MainWindow.cpp b/Windows/MainWindow.cpp index 15f7cfd13f..a7b84b1aba 100644 --- a/Windows/MainWindow.cpp +++ b/Windows/MainWindow.cpp @@ -26,8 +26,7 @@ #include "Common/OSVersion.h" #include -#include -#include +#include // For drag/drop functionality #include #include @@ -37,7 +36,6 @@ #include "Common/TimeUtil.h" #include "Common/StringUtils.h" #include "Common/Data/Text/I18n.h" -#include "Common/Data/Text/Parsers.h" #include "Common/Input/InputState.h" #include "Common/Input/KeyCodes.h" #include "Common/Thread/ThreadUtil.h" @@ -51,12 +49,9 @@ #include "Core/Instance.h" #include "Core/KeyMap.h" #include "Core/MIPS/JitCommon/JitCommon.h" -#include "Core/MIPS/JitCommon/JitBlockCache.h" #include "Core/Reporting.h" -#include "Windows/InputBox.h" #include "Windows/InputDevice.h" #if PPSSPP_API(ANY_GL) -#include "Windows/GPU/WindowsGLContext.h" #include "Windows/GEDebugger/GEDebugger.h" #endif #include "Windows/W32Util/DarkMode.h" @@ -77,17 +72,13 @@ #include "Common/Log/LogManager.h" #include "Common/Log/ConsoleListener.h" #include "Windows/W32Util/DialogManager.h" -#include "Windows/W32Util/ShellUtil.h" #include "Windows/W32Util/Misc.h" #include "Windows/RawInput.h" #include "Windows/CaptureDevice.h" #include "Windows/TouchInputHandler.h" #include "Windows/MainWindowMenu.h" #include "GPU/GPUCommon.h" -#include "UI/OnScreenDisplay.h" -#include "UI/GameSettingsScreen.h" #include "UI/PauseScreen.h" -#include "Core/SaveState.h" #define MOUSEEVENTF_FROMTOUCH_NOPEN 0xFF515780 //http://msdn.microsoft.com/en-us/library/windows/desktop/ms703320(v=vs.85).aspx #define MOUSEEVENTF_MASK_PLUS_PENTOUCH 0xFFFFFF80 diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp index 04773bc645..fd30325bea 100644 --- a/Windows/MainWindowMenu.cpp +++ b/Windows/MainWindowMenu.cpp @@ -4,9 +4,6 @@ #include #include -#include "CommonWindows.h" -#include - #include "resource.h" #include "Common/GPU/OpenGL/GLFeatures.h" @@ -15,31 +12,24 @@ #include "Common/Data/Encoding/Utf8.h" #include "Common/System/System.h" #include "Common/System/OSD.h" -#include "Common/System/NativeApp.h" #include "Common/System/Request.h" #include "Common/System/Display.h" #include "Common/File/FileUtil.h" #include "Common/Log.h" #include "Common/Log/LogManager.h" #include "Common/Log/ConsoleListener.h" -#include "Common/OSVersion.h" -#include "Common/GPU/Vulkan/VulkanLoader.h" #include "Common/StringUtils.h" #if PPSSPP_API(ANY_GL) #include "GPU/GLES/TextureCacheGLES.h" #include "GPU/GLES/FramebufferManagerGLES.h" #endif -#include "UI/OnScreenDisplay.h" #include "GPU/Common/PostShader.h" -#include "GPU/Common/FramebufferManagerCommon.h" -#include "GPU/Common/TextureDecoder.h" #include "GPU/Common/TextureScalerCommon.h" #include "Core/Config.h" #include "Core/ConfigValues.h" #include "Core/FileSystems/MetaFileSystem.h" #include "Core/KeyMap.h" -#include "UI/OnScreenDisplay.h" #include "Windows/MainWindowMenu.h" #include "Windows/MainWindow.h" #include "Windows/W32Util/DialogManager.h" @@ -469,7 +459,7 @@ namespace MainWindow { auto gr = GetI18NCategory(I18NCat::GRAPHICS); - int wmId = LOWORD(wParam); + const int wmId = LOWORD(wParam); // Parse the menu selections: switch (wmId) { case ID_FILE_LOAD: @@ -489,7 +479,7 @@ namespace MainWindow { break; case ID_FILE_MEMSTICK: - ShellExecute(NULL, L"open", g_Config.memStickDirectory.ToWString().c_str(), 0, 0, SW_SHOWNORMAL); + System_LaunchUrl(LaunchUrlType::LOCAL_FILE, g_Config.memStickDirectory.ToString()); break; case ID_TOGGLE_BREAK: @@ -857,10 +847,10 @@ namespace MainWindow { } else if (info.type == FILETYPE_DIRECTORY) { MessageBox(hWnd, L"Cannot extract directories.", L"Sorry", 0); } else if (W32Util::BrowseForFileName(false, hWnd, L"Save file as...", 0, L"All files\0*.*\0\0", L"", fn)) { - u32 handle = pspFileSystem.OpenFile(filename, FILEACCESS_READ, ""); + const u32 handle = pspFileSystem.OpenFile(filename, FILEACCESS_READ, ""); // Note: len may be in blocks. size_t len = pspFileSystem.SeekFile(handle, 0, FILEMOVE_END); - bool isBlockMode = pspFileSystem.DevType(handle) & PSPDevType::BLOCK; + const bool isBlockMode = pspFileSystem.DevType(handle) & PSPDevType::BLOCK; FILE *fp = File::OpenCFile(Path(fn), "wb"); pspFileSystem.SeekFile(handle, 0, FILEMOVE_BEGIN); @@ -868,11 +858,11 @@ namespace MainWindow { size_t bufferSize = isBlockMode ? sizeof(buffer) / 2048 : sizeof(buffer); while (len > 0) { // This is all in blocks, not bytes, if isBlockMode. - size_t remain = std::min(len, bufferSize); - size_t readSize = pspFileSystem.ReadFile(handle, buffer, remain); + const size_t remain = std::min(len, bufferSize); + const size_t readSize = pspFileSystem.ReadFile(handle, buffer, remain); if (readSize == 0) break; - size_t bytes = isBlockMode ? readSize * 2048 : readSize; + const size_t bytes = isBlockMode ? readSize * 2048 : readSize; fwrite(buffer, 1, bytes, fp); len -= readSize; } @@ -938,23 +928,23 @@ namespace MainWindow { break; case ID_HELP_OPENWEBSITE: - ShellExecute(NULL, L"open", L"https://www.ppsspp.org/", NULL, NULL, SW_SHOWNORMAL); + System_LaunchUrl(LaunchUrlType::BROWSER_URL, "https://www.ppsspp.org/"); break; case ID_HELP_BUYGOLD: - ShellExecute(NULL, L"open", L"https://www.ppsspp.org/buygold", NULL, NULL, SW_SHOWNORMAL); + System_LaunchUrl(LaunchUrlType::BROWSER_URL, "https://www.ppsspp.org/buygold"); break; case ID_HELP_OPENFORUM: - ShellExecute(NULL, L"open", L"https://forums.ppsspp.org/", NULL, NULL, SW_SHOWNORMAL); + System_LaunchUrl(LaunchUrlType::BROWSER_URL, "https://forums.ppsspp.org/"); break; case ID_HELP_GITHUB: - ShellExecute(NULL, L"open", L"https://github.com/hrydgard/ppsspp/", NULL, NULL, SW_SHOWNORMAL); + System_LaunchUrl(LaunchUrlType::BROWSER_URL, "https://github.com/hrydgard/ppsspp/"); break; case ID_HELP_DISCORD: - ShellExecute(NULL, L"open", L"https://discord.gg/5NJB6dD", NULL, NULL, SW_SHOWNORMAL); + System_LaunchUrl(LaunchUrlType::BROWSER_URL, "https://discord.gg/5NJB6dD"); break; case ID_HELP_ABOUT: diff --git a/Windows/W32Util/ShellUtil.h b/Windows/W32Util/ShellUtil.h index 1874a2d0ea..697148d448 100644 --- a/Windows/W32Util/ShellUtil.h +++ b/Windows/W32Util/ShellUtil.h @@ -3,7 +3,6 @@ #include #include #include -#include class Path; diff --git a/Windows/main.cpp b/Windows/main.cpp index 04fe408a8d..cd836bee74 100644 --- a/Windows/main.cpp +++ b/Windows/main.cpp @@ -132,6 +132,7 @@ static double g_lastKeepAwake = 0.0; static constexpr double ACTIVITY_IDLE_TIMEOUT = 2.0 * 3600.0; void System_LaunchUrl(LaunchUrlType urlType, std::string_view url) { + // We don't even check urlType. std::string u(url); std::thread t = std::thread([u]() { ShellExecute(NULL, L"open", ConvertUTF8ToWString(u).c_str(), NULL, NULL, SW_SHOWNORMAL); @@ -141,7 +142,8 @@ void System_LaunchUrl(LaunchUrlType urlType, std::string_view url) { } void System_Vibrate(int length_ms) { - // Ignore on PC + // Ignore on PC. TODO: Actually, we could vibrate a controller if we wanted to, but we should only do that + // if it was used within the last few seconds. } static void AddDebugRestartArgs() { From c08ed7d14b18cce5dd78197dd1abafcc38951dcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 1 Feb 2026 15:26:35 +0100 Subject: [PATCH 4/7] More cleanup --- Windows/MainWindow.cpp | 61 ++++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 29 deletions(-) diff --git a/Windows/MainWindow.cpp b/Windows/MainWindow.cpp index a7b84b1aba..03ca6e1a54 100644 --- a/Windows/MainWindow.cpp +++ b/Windows/MainWindow.cpp @@ -114,6 +114,29 @@ static std::wstring g_windowTitle; #define CURSORUPDATE_INTERVAL_MS 1000 #define CURSORUPDATE_MOVE_TIMESPAN_MS 500 +inline WindowSizeState ShowCmdToWindowSizeState(const int showCmd) { + switch (showCmd) { + case SW_SHOWMAXIMIZED: + return WindowSizeState::Maximized; + case SW_SHOWMINIMIZED: + return WindowSizeState::Minimized; + case SW_SHOWNORMAL: + default: + return WindowSizeState::Normal; + } +} + +inline int WindowSizeStateToShowCmd(const WindowSizeState windowSizeState) { + switch (windowSizeState) { + case WindowSizeState::Maximized: + return SW_SHOWMAXIMIZED; + case WindowSizeState::Minimized: + return SW_SHOWMINIMIZED; + default: + return SW_SHOWNORMAL; + } +} + namespace MainWindow { static HWND hwndMain; @@ -138,6 +161,7 @@ namespace MainWindow static bool disasmMapLoadPending = false; static bool memoryMapLoadPending = false; + static bool wasMinimized = false; // gross hack bool noFocusPause = false; // TOGGLE_PAUSE state to override pause on lost focus @@ -176,18 +200,7 @@ namespace MainWindow WINDOWPLACEMENT placement{}; GetWindowPlacement(hwndMain, &placement); - switch (placement.showCmd) { - case SW_SHOWMAXIMIZED: - g_Config.iWindowSizeState = (int)WindowSizeState::Maximized; - break; - case SW_SHOWMINIMIZED: - g_Config.iWindowSizeState = (int)WindowSizeState::Minimized; - break; - case SW_SHOWNORMAL: - g_Config.iWindowSizeState = (int)WindowSizeState::Normal; - break; - } - + g_Config.iWindowSizeState = (int)ShowCmdToWindowSizeState(placement.showCmd); g_Config.iWindowX = placement.rcNormalPosition.left; g_Config.iWindowY = placement.rcNormalPosition.top; g_Config.iWindowWidth = placement.rcNormalPosition.right - placement.rcNormalPosition.left; @@ -473,17 +486,7 @@ namespace MainWindow rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hInstance, NULL); WINDOWPLACEMENT placement = {sizeof(WINDOWPLACEMENT)}; - placement.showCmd = SW_SHOWNORMAL; - switch ((WindowSizeState)g_Config.iWindowSizeState) { - case WindowSizeState::Maximized: - placement.showCmd = SW_SHOWMAXIMIZED; - break; - case WindowSizeState::Minimized: - placement.showCmd = SW_SHOWMINIMIZED; - break; - default: - break; - } + placement.showCmd = WindowSizeStateToShowCmd((WindowSizeState)g_Config.iWindowSizeState); placement.rcNormalPosition.left = g_Config.iWindowX; placement.rcNormalPosition.top = g_Config.iWindowY; placement.rcNormalPosition.right = g_Config.iWindowX + g_Config.iWindowWidth; @@ -527,9 +530,10 @@ namespace MainWindow disasmWindow = new CDisasm(MainWindow::GetHInstance(), MainWindow::GetHWND(), currentDebugMIPS); DialogManager::AddDlg(disasmWindow); } - if (disasmMapLoadPending) + if (disasmMapLoadPending) { disasmWindow->NotifyMapLoaded(); - disasmMapLoadPending = false; + disasmMapLoadPending = false; + } } void CreateGeDebuggerWindow() { @@ -546,9 +550,10 @@ namespace MainWindow memoryWindow = new CMemoryDlg(MainWindow::GetHInstance(), MainWindow::GetHWND(), currentDebugMIPS); DialogManager::AddDlg(memoryWindow); } - if (memoryMapLoadPending) + if (memoryMapLoadPending) { memoryWindow->NotifyMapLoaded(); - memoryMapLoadPending = false; + memoryMapLoadPending = false; + } } void CreateVFPUWindow() { @@ -616,8 +621,6 @@ namespace MainWindow } static bool first = true; - static bool wasMinimized = false; - switch (message) { case WM_CREATE: first = true; From 926f595591287706a9a12e2c217c2bbce4c054b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 1 Feb 2026 20:20:20 +0100 Subject: [PATCH 5/7] Tweak --- Windows/MainWindow.cpp | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/Windows/MainWindow.cpp b/Windows/MainWindow.cpp index 03ca6e1a54..8aa4c5c370 100644 --- a/Windows/MainWindow.cpp +++ b/Windows/MainWindow.cpp @@ -137,8 +137,7 @@ inline int WindowSizeStateToShowCmd(const WindowSizeState windowSizeState) { } } -namespace MainWindow -{ +namespace MainWindow { static HWND hwndMain; static TouchInputHandler touchHandler; @@ -478,12 +477,14 @@ namespace MainWindow BOOL Show(HINSTANCE hInstance) { hInst = hInstance; // Store instance handle in our global variable. - RECT rc = DetermineWindowRectangle(); - u32 style = WS_OVERLAPPEDWINDOW; + hwndMain = CreateWindowEx(0, szWindowClass, L"", WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); - hwndMain = CreateWindowEx(0, szWindowClass, L"", style, - rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hInstance, NULL); + if (!hwndMain) + return FALSE; + + g_hMenu = GetMenu(hwndMain); WINDOWPLACEMENT placement = {sizeof(WINDOWPLACEMENT)}; placement.showCmd = WindowSizeStateToShowCmd((WindowSizeState)g_Config.iWindowSizeState); @@ -493,16 +494,11 @@ namespace MainWindow placement.rcNormalPosition.bottom = g_Config.iWindowY + g_Config.iWindowHeight; SetWindowPlacement(hwndMain, &placement); - if (!hwndMain) - return FALSE; - - SetWindowLong(hwndMain, GWL_EXSTYLE, WS_EX_APPWINDOW); + // SetWindowLong(hwndMain, GWL_EXSTYLE, WS_EX_APPWINDOW); const DWM_WINDOW_CORNER_PREFERENCE pref = DWMWCP_DONOTROUND; DwmSetWindowAttribute(hwndMain, DWMWA_WINDOW_CORNER_PREFERENCE, &pref, sizeof(pref)); - g_hMenu = GetMenu(hwndMain); - MainMenuInit(hwndMain, g_hMenu); // Accept dragged files. From 51c3058cf691ab49cb7f5349f43307f2093a86c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 2 Feb 2026 09:23:05 +0100 Subject: [PATCH 6/7] Replace "ForceFullScreen" with a way to prevent specific settings from being saved. --- Core/Config.cpp | 9 +++++++++ Core/Config.h | 14 ++++++------- Core/ConfigSettings.h | 6 +++++- Core/Dialog/PSPOskDialog.cpp | 2 +- Qt/QtMain.cpp | 2 +- Qt/mainwindow.cpp | 9 ++++----- SDL/CocoaBarItems.mm | 2 +- SDL/SDLMain.cpp | 17 +++++++--------- UI/ChatScreen.cpp | 2 +- UI/GameSettingsScreen.cpp | 7 +++---- UI/MainScreen.cpp | 6 ++---- UI/NativeApp.cpp | 6 ++++-- UWP/App.cpp | 5 ++--- Windows/MainWindow.cpp | 39 +++++++++++------------------------- Windows/MainWindow.h | 1 - Windows/MainWindowMenu.cpp | 2 +- Windows/main.cpp | 5 +++-- 17 files changed, 63 insertions(+), 71 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index 00f9bf2b69..48f2b7e86c 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -1381,6 +1381,10 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename) { INFO_LOG(Log::Loader, "Config loaded: '%s' (%0.1f ms)", iniFilename_.c_str(), (time_now_d() - startTime) * 1000.0); } +bool Config::ShouldSaveSetting(const void *ptr) const { + return std::find(settingsNotToSave_.begin(), settingsNotToSave_.end(), ptr) == settingsNotToSave_.end(); +} + // If we're in game specific mode, we need to: // * Save the game-specific settings to the game-specific ini file. // * Then, save the NON-game-specific settings ONLY to the regular ini file! @@ -1420,6 +1424,11 @@ bool Config::Save(const char *saveReason) { // Skip per-game settings in non-game-specific ini. continue; } + if (!ShouldSaveSetting(meta.settings[j].GetVoidPtr(configBlock))) { + // Skip settings marked as "don't save". + INFO_LOG(Log::System, "Not saving setting '%.*s' as marked as don't save.", STR_VIEW(meta.settings[j].IniKey())); + continue; + } meta.settings[j].WriteToIniSection(configBlock, section); } } diff --git a/Core/Config.h b/Core/Config.h index 3c89e2b25c..6503645764 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -306,7 +306,6 @@ public: int iAppSwitchMode; bool bFullScreen; bool bFullScreenMulti; - int iForceFullScreen = -1; // -1 = nope, 0 = force off, 1 = force on (not saved.) int iInternalResolution; // 0 = Auto (native), 1 = 1x (480x272), 2 = 2x, 3 = 3x, 4 = 4x and so on. int iAnisotropyLevel; // 0 - 5, powers of 2: 0 = 1x = no aniso int iMultiSampleLevel; @@ -690,12 +689,6 @@ public: int NextValidBackend(); bool IsBackendEnabled(GPUBackend backend); - bool UseFullScreen() const { - if (iForceFullScreen != -1) - return iForceFullScreen == 1; - return bFullScreen; - } - bool LoadAppendedConfig(); void SetAppendedConfigIni(const Path &path) { appendedConfigFileName_ = path; } void UpdateAfterSettingAutoFrameSkip(); @@ -718,6 +711,10 @@ public: static int GetDefaultValueInt(int *configSetting); + void DoNotSaveSetting(void *configSetting) { + settingsNotToSave_.push_back(configSetting); + } + private: void LoadStandardControllerIni(); @@ -747,6 +744,9 @@ private: Path appendedConfigFileName_; // A set make more sense, but won't have many entry, and I dont want to include the whole std::set header here std::vector appendedConfigUpdatedGames_; + std::vector settingsNotToSave_; + + bool ShouldSaveSetting(const void *configSetting) const; }; std::string CreateRandMAC(); diff --git a/Core/ConfigSettings.h b/Core/ConfigSettings.h index 035a32f5d8..04472b4fd0 100644 --- a/Core/ConfigSettings.h +++ b/Core/ConfigSettings.h @@ -212,7 +212,10 @@ struct ConfigSetting { return defaultCallback_.i ? defaultCallback_.i() : default_.i; } - std::string_view iniKey_; + std::string_view IniKey() const { + return iniKey_; + } + const char *ini2_ = nullptr; const char *ini3_ = nullptr; const char *ini4_ = nullptr; @@ -229,6 +232,7 @@ struct ConfigSetting { } private: + std::string_view iniKey_; CfgFlag flags_; DefaultValue default_{}; DefaultCallback defaultCallback_{}; diff --git a/Core/Dialog/PSPOskDialog.cpp b/Core/Dialog/PSPOskDialog.cpp index 79806596fe..c1e9ef5716 100755 --- a/Core/Dialog/PSPOskDialog.cpp +++ b/Core/Dialog/PSPOskDialog.cpp @@ -891,7 +891,7 @@ int PSPOskDialog::Update(int animSpeed) { // Windows: Fall back to the OSK/continue normally if we're in fullscreen. // The dialog box doesn't work right if in fullscreen. if (System_GetPropertyBool(SYSPROP_HAS_KEYBOARD)) { - if (g_Config.bBypassOSKWithKeyboard && !g_Config.UseFullScreen()) + if (g_Config.bBypassOSKWithKeyboard && !g_Config.bFullScreen) return NativeKeyboard(); } #endif diff --git a/Qt/QtMain.cpp b/Qt/QtMain.cpp index 6997a1f0e4..c7d43a35ee 100644 --- a/Qt/QtMain.cpp +++ b/Qt/QtMain.cpp @@ -873,7 +873,7 @@ int main(int argc, char *argv[]) NativeInit(argc, (const char **)argv, savegame_dir.c_str(), external_dir.c_str(), nullptr); - g_mainWindow = new MainWindow(nullptr, g_Config.UseFullScreen()); + g_mainWindow = new MainWindow(nullptr, g_Config.bFullScreen); g_mainWindow->show(); // TODO: Support other backends than GL, like Vulkan, in the Qt backend. diff --git a/Qt/mainwindow.cpp b/Qt/mainwindow.cpp index d2ccd5820c..c0de52e460 100644 --- a/Qt/mainwindow.cpp +++ b/Qt/mainwindow.cpp @@ -60,16 +60,16 @@ void MainWindow::newFrame() { if (lastUIState != GetUIState()) { lastUIState = GetUIState(); - if (lastUIState == UISTATE_INGAME && g_Config.UseFullScreen() && !QApplication::overrideCursor() && !g_Config.bShowTouchControls) + if (lastUIState == UISTATE_INGAME && g_Config.bFullScreen && !QApplication::overrideCursor() && !g_Config.bShowTouchControls) QApplication::setOverrideCursor(QCursor(Qt::BlankCursor)); - if (lastUIState != UISTATE_INGAME && g_Config.UseFullScreen() && QApplication::overrideCursor()) + if (lastUIState != UISTATE_INGAME && g_Config.bFullScreen && QApplication::overrideCursor()) QApplication::restoreOverrideCursor(); updateMenus(); } - if (g_Config.UseFullScreen() != isFullScreen()) - SetFullScreen(g_Config.UseFullScreen()); + if (g_Config.bFullScreen != isFullScreen()) + SetFullScreen(g_Config.bFullScreen); std::unique_lock lock(msgMutex_); while (!msgQueue_.empty()) { @@ -407,7 +407,6 @@ void MainWindow::fullscrAct() { // Toggle the current state. g_Config.bFullScreen = !isFullScreen(); - g_Config.iForceFullScreen = -1; SetFullScreen(g_Config.bFullScreen); QTimer::singleShot(1000, this, SLOT(raiseTopMost())); diff --git a/SDL/CocoaBarItems.mm b/SDL/CocoaBarItems.mm index a76cbe02f7..7a04794383 100644 --- a/SDL/CocoaBarItems.mm +++ b/SDL/CocoaBarItems.mm @@ -549,7 +549,7 @@ TOGGLE_METHOD_INVERSE(BreakOnLoad, g_Config.bAutoRun) TOGGLE_METHOD(IgnoreIllegalRWs, g_Config.bIgnoreBadMemAccess) TOGGLE_METHOD(AutoFrameSkip, g_Config.bAutoFrameSkip, g_Config.UpdateAfterSettingAutoFrameSkip()) TOGGLE_METHOD(SoftwareRendering, g_Config.bSoftwareRendering) -TOGGLE_METHOD(FullScreen, g_Config.bFullScreen, System_MakeRequest(SystemRequestType::TOGGLE_FULLSCREEN_STATE, 0, g_Config.UseFullScreen() ? "1" : "0", "", 3, 0)) +TOGGLE_METHOD(FullScreen, g_Config.bFullScreen, System_MakeRequest(SystemRequestType::TOGGLE_FULLSCREEN_STATE, 0, g_Config.bFullScreen ? "1" : "0", "", 3, 0)) // TOGGLE_METHOD(VSync, g_Config.bVSync) #undef TOGGLE_METHOD diff --git a/SDL/SDLMain.cpp b/SDL/SDLMain.cpp index ed43e56c62..0a843845c5 100644 --- a/SDL/SDLMain.cpp +++ b/SDL/SDLMain.cpp @@ -965,9 +965,8 @@ static void ProcessSDLEvent(SDL_Window *window, const SDL_Event &event, InputSta Native_UpdateScreenScale(new_width_px, new_height_px, UIScaleFactorToMultiplier(g_Config.iUIScaleFactor)); // Set variable here in case fullscreen was toggled by hotkey - if (g_Config.UseFullScreen() != fullscreen) { + if (g_Config.bFullScreen != fullscreen) { g_Config.bFullScreen = fullscreen; - g_Config.iForceFullScreen = -1; } else { // It is possible for the monitor to change DPI, so recalculate // DPI on each resize event. @@ -1341,9 +1340,9 @@ void UpdateSDLCursor() { #if !defined(MOBILE_DEVICE) if (lastUIState != GetUIState()) { lastUIState = GetUIState(); - if (lastUIState == UISTATE_INGAME && g_Config.UseFullScreen() && !g_Config.bShowTouchControls) + if (lastUIState == UISTATE_INGAME && g_Config.bFullScreen && !g_Config.bShowTouchControls) SDL_ShowCursor(SDL_DISABLE); - if (lastUIState != UISTATE_INGAME || !g_Config.UseFullScreen()) + if (lastUIState != UISTATE_INGAME || !g_Config.bFullScreen) SDL_ShowCursor(SDL_ENABLE); } #endif @@ -1471,7 +1470,7 @@ int main(int argc, char *argv[]) { for (int i = 1; i < argc; i++) { if (!strcmp(argv[i], "--fullscreen")) { mode |= SDL_WINDOW_FULLSCREEN_DESKTOP; - g_Config.iForceFullScreen = 1; + g_Config.DoNotSaveSetting(&g_Config.bFullScreen); } else if (set_xres == -2) set_xres = parseInt(argv[i]); else if (set_yres == -2) @@ -1578,8 +1577,7 @@ int main(int argc, char *argv[]) { if (mode & SDL_WINDOW_FULLSCREEN_DESKTOP) { g_display.pixel_xres = g_DesktopWidth; g_display.pixel_yres = g_DesktopHeight; - if (g_Config.iForceFullScreen == -1) - g_Config.bFullScreen = true; + g_Config.bFullScreen = true; } else { // set a sensible default resolution (2x) g_display.pixel_xres = 480 * 2 * set_scale; @@ -1587,8 +1585,7 @@ int main(int argc, char *argv[]) { if (portrait) { std::swap(g_display.pixel_xres, g_display.pixel_yres); } - if (g_Config.iForceFullScreen == -1) - g_Config.bFullScreen = false; + g_Config.bFullScreen = false; } if (set_ipad) { @@ -1639,7 +1636,7 @@ int main(int argc, char *argv[]) { NativeInit(remain_argc, (const char **)remain_argv, path, external_dir, nullptr); // Use the setting from the config when initing the window. - if (g_Config.UseFullScreen()) + if (g_Config.bFullScreen) mode |= SDL_WINDOW_FULLSCREEN_DESKTOP; int x = SDL_WINDOWPOS_UNDEFINED_DISPLAY(getDisplayNumber()); diff --git a/UI/ChatScreen.cpp b/UI/ChatScreen.cpp index 01d29b0b25..2e420210b0 100644 --- a/UI/ChatScreen.cpp +++ b/UI/ChatScreen.cpp @@ -178,7 +178,7 @@ void ChatMenu::Update() { #if defined(USING_WIN_UI) // Could remove the fullscreen check here, it works now. auto n = GetI18NCategory(I18NCat::NETWORKING); - if (promptInput_ && g_Config.bBypassOSKWithKeyboard && !g_Config.UseFullScreen()) { + if (promptInput_ && g_Config.bBypassOSKWithKeyboard && !g_Config.bFullScreen) { System_InputBoxGetString(token_, n->T("Chat"), n->T("Chat Here"), false, [](const std::string &value, int) { sendChat(value); }); diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 43913fe9a2..1c5975b6ac 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -417,7 +417,7 @@ void GameSettingsScreen::CreateGraphicsSettings(UI::ViewGroup *graphicsSettings) if (System_GetPropertyInt(SYSPROP_DISPLAY_COUNT) > 1) { CheckBox *fullscreenMulti = new CheckBox(&g_Config.bFullScreenMulti, gr->T("Use all displays")); fullscreenMulti->SetEnabledFunc([] { - return g_Config.UseFullScreen(); + return g_Config.bFullScreen; }); graphicsSettings->Add(fullscreenMulti)->OnClick.Handle(this, &GameSettingsScreen::OnFullscreenMultiChange); } @@ -1622,12 +1622,11 @@ void GameSettingsScreen::OnChangeBackground(UI::EventParams &e) { } void GameSettingsScreen::OnFullscreenChange(UI::EventParams &e) { - g_Config.iForceFullScreen = -1; - System_ToggleFullscreenState(g_Config.UseFullScreen() ? "1" : "0"); + System_ToggleFullscreenState(g_Config.bFullScreen ? "1" : "0"); } void GameSettingsScreen::OnFullscreenMultiChange(UI::EventParams &e) { - System_ToggleFullscreenState(g_Config.UseFullScreen() ? "1" : "0"); + System_ToggleFullscreenState(g_Config.bFullScreen ? "1" : "0"); } void GameSettingsScreen::dialogFinished(const Screen *dialog, DialogResult result) { diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index 48407b83be..fa25a16c33 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -1428,7 +1428,7 @@ void MainScreen::CreateViews() { ViewGroup *logo = new LogoView(false, new LinearLayoutParams(FILL_PARENT, 80.0f)); #if !defined(MOBILE_DEVICE) auto gr = GetI18NCategory(I18NCat::GRAPHICS); - ImageID icon(g_Config.UseFullScreen() ? "I_RESTORE" : "I_FULLSCREEN"); + ImageID icon(g_Config.bFullScreen ? "I_RESTORE" : "I_FULLSCREEN"); fullscreenButton_ = logo->Add(new Button(gr->T("FullScreen", "Full Screen"), icon, new AnchorLayoutParams(48, 48, NONE, 0, 0, NONE, Centering::None))); fullscreenButton_->SetIgnoreText(true); fullscreenButton_->OnClick.Handle(this, &MainScreen::OnFullScreenToggle); @@ -1511,10 +1511,8 @@ void MainScreen::OnLoadFile(UI::EventParams &e) { } void MainScreen::OnFullScreenToggle(UI::EventParams &e) { - if (g_Config.iForceFullScreen != -1) - g_Config.bFullScreen = g_Config.UseFullScreen(); if (fullscreenButton_) { - fullscreenButton_->SetImageID(ImageID(!g_Config.UseFullScreen() ? "I_RESTORE" : "I_FULLSCREEN")); + fullscreenButton_->SetImageID(ImageID(!g_Config.bFullScreen ? "I_RESTORE" : "I_FULLSCREEN")); } #if !defined(MOBILE_DEVICE) g_Config.bFullScreen = !g_Config.bFullScreen; diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index ff8064c997..b39e55a5de 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -580,14 +580,16 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch if (!strncmp(argv[i], "--pause-menu-exit", strlen("--pause-menu-exit"))) g_Config.bPauseMenuExitsEmulator = true; if (!strcmp(argv[i], "--fullscreen")) { - g_Config.iForceFullScreen = 1; + g_Config.DoNotSaveSetting(&g_Config.bFullScreen); + g_Config.bFullScreen = true; System_ToggleFullscreenState("1"); } if (!strncmp(argv[i], "--root=", strlen("--root=")) && strlen(argv[i]) > strlen("--root=")) { g_Config.mountRoot = Path(argv[i] + strlen("--root=")); } if (!strcmp(argv[i], "--windowed")) { - g_Config.iForceFullScreen = 0; + g_Config.DoNotSaveSetting(&g_Config.bFullScreen); + g_Config.bFullScreen = false; System_ToggleFullscreenState("0"); } if (!strcmp(argv[i], "--touchscreentest")) diff --git a/UWP/App.cpp b/UWP/App.cpp index 48bfc60048..ef75269702 100644 --- a/UWP/App.cpp +++ b/UWP/App.cpp @@ -264,9 +264,9 @@ void App::OnActivated(const CoreApplicationView& applicationView, const IActivat CoreWindow::GetForCurrentThread().Activate(); // On mobile, we force-enter fullscreen mode. if (m_isPhone) - g_Config.iForceFullScreen = 1; + g_Config.bFullScreen = true; - if (g_Config.UseFullScreen()) + if (g_Config.bFullScreen) winrt::Windows::UI::ViewManagement::ApplicationView::GetForCurrentView().TryEnterFullScreenMode(); //Detect if app started or activated by launch item (file, uri) @@ -300,7 +300,6 @@ void App::OnResuming(const IInspectable& sender, const IInspectable& args) { void App::OnWindowSizeChanged(const CoreWindow& sender, const WindowSizeChangedEventArgs& args) { auto view = winrt::Windows::UI::ViewManagement::ApplicationView::GetForCurrentView(); g_Config.bFullScreen = view.IsFullScreenMode(); - g_Config.iForceFullScreen = -1; float width = sender.Bounds().Width; float height = sender.Bounds().Height; diff --git a/Windows/MainWindow.cpp b/Windows/MainWindow.cpp index 8aa4c5c370..60010f238a 100644 --- a/Windows/MainWindow.cpp +++ b/Windows/MainWindow.cpp @@ -155,7 +155,6 @@ namespace MainWindow { static bool inFullscreenResize = false; static bool inResizeMove = false; static bool hasFocus = true; - static bool g_isFullscreen = false; static bool g_keepScreenBright = false; static bool disasmMapLoadPending = false; @@ -194,7 +193,7 @@ namespace MainWindow { } void SavePosition() { - if (g_Config.UseFullScreen() || inFullscreenResize) + if (g_Config.bFullScreen || inFullscreenResize) return; WINDOWPLACEMENT placement{}; @@ -242,7 +241,7 @@ namespace MainWindow { } void CorrectCursor() { - bool autoHide = ((g_Config.UseFullScreen() && !mouseButtonDown) || (g_Config.bMouseControl && trapMouse)) && GetUIState() == UISTATE_INGAME; + bool autoHide = ((g_Config.bFullScreen && !mouseButtonDown) || (g_Config.bMouseControl && trapMouse)) && GetUIState() == UISTATE_INGAME; if (autoHide && (hideCursor || g_Config.bMouseControl)) { while (cursorCounter >= 0) { cursorCounter = ShowCursor(FALSE); @@ -290,7 +289,7 @@ namespace MainWindow { } // Don't save the window state if fullscreen. - if (!g_Config.UseFullScreen()) { + if (!g_Config.bFullScreen) { g_WindowState = newSizingType; } } @@ -337,11 +336,7 @@ namespace MainWindow { // Remove the menu bar if going fullscreen. This can trigger WM_SIZE because the contents change size. ::SetMenu(hWnd, goingFullscreen || !g_Config.bShowMenuBar ? NULL : g_hMenu); - if (g_Config.UseFullScreen() != goingFullscreen) { - g_Config.bFullScreen = goingFullscreen; - g_Config.iForceFullScreen = -1; - } - g_isFullscreen = goingFullscreen; + g_Config.bFullScreen = goingFullscreen; g_IgnoreWM_SIZE = false; @@ -402,7 +397,7 @@ namespace MainWindow { bool resetPositionX = true; bool resetPositionY = true; - if (g_Config.iWindowWidth > 0 && g_Config.iWindowHeight > 0 && !g_Config.UseFullScreen()) { + if (g_Config.iWindowWidth > 0 && g_Config.iWindowHeight > 0 && !g_Config.bFullScreen) { bool visibleHorizontally = ((g_Config.iWindowX + g_Config.iWindowWidth) >= virtualScreenX) && ((g_Config.iWindowX + g_Config.iWindowWidth) < (virtualScreenWidth + g_Config.iWindowWidth)); @@ -507,7 +502,7 @@ namespace MainWindow { hideCursor = true; SetTimer(hwndMain, TIMER_CURSORUPDATE, CURSORUPDATE_INTERVAL_MS, 0); - ToggleFullscreen(hwndMain, g_Config.UseFullScreen()); + ToggleFullscreen(hwndMain, g_Config.bFullScreen); W32Util::MakeTopMost(hwndMain, g_Config.bTopMost); @@ -657,28 +652,23 @@ namespace MainWindow { // Return game ID as four u32 values // wParam: 0-3 = which u32 to return (chars 0-3, 4-7, 8-11, 12-15) // Returns: packed u32 with 4 bytes of game ID - if (!PSP_IsInited()) - { + if (!PSP_IsInited()) { return 0; } const std::string gameID = Reporting::CurrentGameID(); - if (gameID.empty()) - { + if (gameID.empty()) { return 0; } const size_t offset = (wParam & 0x3) * 4; // 0, 4, 8, 12 u32 packed = 0; - for (size_t i = 0; i < 4; ++i) - { - if (offset + i < gameID.length()) - { + for (size_t i = 0; i < 4; ++i) { + if (offset + i < gameID.length()) { const u8 c = static_cast(gameID[offset + i]); packed |= ((u32)c << (i * 8)); } } return packed; } - break; case WM_USER_GET_MODULE_INFO: { // Get module information by name @@ -722,7 +712,6 @@ namespace MainWindow { // Module not found return 0; } - break; // Hack to kill the white line underneath the menubar. // From https://stackoverflow.com/questions/57177310/how-to-paint-over-white-line-between-menu-bar-and-client-area-of-window @@ -755,8 +744,8 @@ namespace MainWindow { AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, TRUE); minmax->ptMinTrackSize.x = rc.right - rc.left; minmax->ptMinTrackSize.y = rc.bottom - rc.top; + return 0; } - return 0; case WM_ACTIVATE: { @@ -1138,7 +1127,7 @@ namespace MainWindow { const float dy = lastMouseDownY - y; const float distSq = dx * dx + dy * dy; if (distSq < 3.0f*3.0f && !g_Config.bShowTouchControls && !g_Config.bShowImDebugger && !g_Config.bMouseControl && GetUIState() == UISTATE_INGAME && g_Config.bFullscreenOnDoubleclick) { - SendToggleFullscreen(!g_Config.UseFullScreen()); + SendToggleFullscreen(!g_Config.bFullScreen); } lastMouseDownTime = 0.0; } else { @@ -1252,10 +1241,6 @@ namespace MainWindow { PostMessage(hwndMain, WM_USER_TOGGLE_FULLSCREEN, fullscreen, 0); } - bool IsFullscreen() { - return g_isFullscreen; - } - void RunCallbackInWndProc(void (*callback)(void *, void *), void *userdata) { PostMessage(hwndMain, WM_USER_RUN_CALLBACK, reinterpret_cast(callback), reinterpret_cast(userdata)); } diff --git a/Windows/MainWindow.h b/Windows/MainWindow.h index e80c376ab3..cd3a1c44f9 100644 --- a/Windows/MainWindow.h +++ b/Windows/MainWindow.h @@ -75,7 +75,6 @@ namespace MainWindow void ToggleFullscreen(HWND hWnd, bool goingFullscreen); void Minimize(); void SendToggleFullscreen(bool fullscreen); // To be used off-thread - bool IsFullscreen(); void ToggleDebugConsoleVisibility(); void SetInternalResolution(int res = -1); void SetWindowSize(int zoom); diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp index fd30325bea..8cccf6223a 100644 --- a/Windows/MainWindowMenu.cpp +++ b/Windows/MainWindowMenu.cpp @@ -882,7 +882,7 @@ namespace MainWindow { case ID_OPTIONS_FULLSCREEN: if (!g_Config.bShowImDebugger) { - SendToggleFullscreen(!g_Config.UseFullScreen()); + SendToggleFullscreen(!g_Config.bFullScreen); } break; diff --git a/Windows/main.cpp b/Windows/main.cpp index cd836bee74..4b52ba4dd5 100644 --- a/Windows/main.cpp +++ b/Windows/main.cpp @@ -726,7 +726,7 @@ bool System_MakeRequest(SystemRequestType type, int requestId, const std::string case SystemRequestType::TOGGLE_FULLSCREEN_STATE: { - bool flag = !MainWindow::IsFullscreen(); + bool flag = !g_Config.bFullScreen; if (param1 == "0") { flag = false; } else if (param1 == "1") { @@ -1122,7 +1122,8 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin if (iCmdShow == SW_MAXIMIZE) { // Consider this to mean --fullscreen. - g_Config.iForceFullScreen = 1; + g_Config.bFullScreen = true; + g_Config.DoNotSaveSetting(&g_Config.bFullScreen); } // Consider at least the following cases before changing this code: From 7db8709e56a59de2f3684a90174bafdece997c75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 2 Feb 2026 09:44:18 +0100 Subject: [PATCH 7/7] Buildfix --- GPU/Common/PostShader.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/GPU/Common/PostShader.h b/GPU/Common/PostShader.h index 8165e66d5a..0eee0f8976 100644 --- a/GPU/Common/PostShader.h +++ b/GPU/Common/PostShader.h @@ -24,6 +24,8 @@ #include #include +#include "Common/GPU/thin3d.h" + struct ShaderInfo { Path iniFile; // which ini file was this definition in? So we can write settings back later std::string section; // ini file section. This is saved.