CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/Windows/MainWindowMenu.cpp
Views: 1401
#include "ppsspp_config.h"1#include <algorithm>2#include <string>3#include <sstream>4#include <unordered_map>56#include "CommonWindows.h"7#include <shellapi.h>89#include "resource.h"1011#include "Common/GPU/OpenGL/GLFeatures.h"1213#include "Common/Data/Text/I18n.h"14#include "Common/Data/Encoding/Utf8.h"15#include "Common/System/System.h"16#include "Common/System/OSD.h"17#include "Common/System/NativeApp.h"18#include "Common/System/Request.h"19#include "Common/File/FileUtil.h"20#include "Common/Log.h"21#include "Common/Log/LogManager.h"22#include "Common/Log/ConsoleListener.h"23#include "Common/OSVersion.h"24#include "Common/GPU/Vulkan/VulkanLoader.h"25#include "Common/StringUtils.h"26#if PPSSPP_API(ANY_GL)27#include "GPU/GLES/TextureCacheGLES.h"28#include "GPU/GLES/FramebufferManagerGLES.h"29#endif30#include "UI/OnScreenDisplay.h"31#include "GPU/Common/PostShader.h"32#include "GPU/Common/FramebufferManagerCommon.h"33#include "GPU/Common/TextureDecoder.h"34#include "GPU/Common/TextureScalerCommon.h"3536#include "Core/Config.h"37#include "Core/ConfigValues.h"38#include "Core/FileSystems/MetaFileSystem.h"39#include "Core/KeyMap.h"40#include "UI/OnScreenDisplay.h"41#include "Windows/MainWindowMenu.h"42#include "Windows/MainWindow.h"43#include "Windows/W32Util/DialogManager.h"44#include "Windows/W32Util/ShellUtil.h"45#include "Windows/W32Util/Misc.h"46#include "Windows/InputBox.h"47#include "Windows/main.h"48#include "Windows/W32Util/DarkMode.h"4950#include "Core/HLE/sceUmd.h"51#include "Core/SaveState.h"52#include "Core/Core.h"53#include "Core/RetroAchievements.h"5455#ifdef RC_CLIENT_SUPPORTS_RAINTEGRATION56#include "ext/rcheevos/include/rc_client_raintegration.h"57#endif5859extern bool g_TakeScreenshot;6061namespace MainWindow {62extern HINSTANCE hInst;63extern bool noFocusPause;64static bool browsePauseAfter;6566static std::unordered_map<int, std::string> initialMenuKeys;67static std::vector<std::string> availableShaders;68static std::string menuLanguageID = "";69static int menuKeymapGeneration = -1;70static bool menuShaderInfoLoaded = false;71std::vector<ShaderInfo> menuShaderInfo;7273LRESULT CALLBACK AboutDlgProc(HWND, UINT, WPARAM, LPARAM);7475void SetIngameMenuItemStates(HMENU menu, const GlobalUIState state) {76bool menuEnableBool = state == UISTATE_INGAME || state == UISTATE_EXCEPTION;7778bool loadStateEnableBool = menuEnableBool;79bool saveStateEnableBool = menuEnableBool;80if (Achievements::HardcoreModeActive()) {81loadStateEnableBool = false;82if (!g_Config.bAchievementsSaveStateInHardcoreMode) {83saveStateEnableBool = false;84}85}8687UINT menuEnable = menuEnableBool ? MF_ENABLED : MF_GRAYED;88UINT loadStateEnable = loadStateEnableBool ? MF_ENABLED : MF_GRAYED;89UINT saveStateEnable = saveStateEnableBool ? MF_ENABLED : MF_GRAYED;90UINT menuInGameEnable = state == UISTATE_INGAME ? MF_ENABLED : MF_GRAYED;91UINT umdSwitchEnable = state == UISTATE_INGAME && getUMDReplacePermit() ? MF_ENABLED : MF_GRAYED;9293EnableMenuItem(menu, ID_FILE_SAVESTATE_SLOT_MENU, saveStateEnable);94EnableMenuItem(menu, ID_FILE_SAVESTATEFILE, saveStateEnable);95EnableMenuItem(menu, ID_FILE_LOADSTATEFILE, loadStateEnable);96EnableMenuItem(menu, ID_FILE_QUICKSAVESTATE, saveStateEnable);97EnableMenuItem(menu, ID_FILE_QUICKLOADSTATE, loadStateEnable);98EnableMenuItem(menu, ID_EMULATION_PAUSE, menuEnable);99EnableMenuItem(menu, ID_EMULATION_STOP, menuEnable);100EnableMenuItem(menu, ID_EMULATION_RESET, menuEnable);101EnableMenuItem(menu, ID_EMULATION_SWITCH_UMD, umdSwitchEnable);102EnableMenuItem(menu, ID_EMULATION_CHAT, g_Config.bEnableNetworkChat ? menuInGameEnable : MF_GRAYED);103EnableMenuItem(menu, ID_TOGGLE_BREAK, menuEnable);104EnableMenuItem(menu, ID_DEBUG_LOADMAPFILE, menuEnable);105EnableMenuItem(menu, ID_DEBUG_SAVEMAPFILE, menuEnable);106EnableMenuItem(menu, ID_DEBUG_LOADSYMFILE, menuEnable);107EnableMenuItem(menu, ID_DEBUG_SAVESYMFILE, menuEnable);108EnableMenuItem(menu, ID_DEBUG_RESETSYMBOLTABLE, menuEnable);109EnableMenuItem(menu, ID_DEBUG_SHOWDEBUGSTATISTICS, menuInGameEnable);110EnableMenuItem(menu, ID_DEBUG_EXTRACTFILE, menuEnable);111EnableMenuItem(menu, ID_DEBUG_MEMORYBASE, menuInGameEnable);112113// While playing, this pop up doesn't work - and probably doesn't make sense.114EnableMenuItem(menu, ID_OPTIONS_LANGUAGE, state == UISTATE_INGAME ? MF_GRAYED : MF_ENABLED);115}116117static HMENU GetSubmenuById(HMENU menu, int menuID) {118MENUITEMINFO menuInfo{ sizeof(MENUITEMINFO), MIIM_SUBMENU };119if (GetMenuItemInfo(menu, menuID, MF_BYCOMMAND, &menuInfo) != FALSE) {120return menuInfo.hSubMenu;121}122return nullptr;123}124125static void EmptySubMenu(HMENU menu) {126int c = GetMenuItemCount(menu);127for (int i = 0; i < c; ++i) {128RemoveMenu(menu, 0, MF_BYPOSITION);129}130}131132static std::string GetMenuItemText(HMENU menu, int menuID) {133MENUITEMINFO menuInfo{ sizeof(menuInfo), MIIM_STRING };134std::string retVal;135if (GetMenuItemInfo(menu, menuID, MF_BYCOMMAND, &menuInfo) != FALSE) {136wchar_t *buffer = new wchar_t[++menuInfo.cch];137menuInfo.dwTypeData = buffer;138GetMenuItemInfo(menu, menuID, MF_BYCOMMAND, &menuInfo);139retVal = ConvertWStringToUTF8(menuInfo.dwTypeData);140delete[] buffer;141}142143return retVal;144}145146const std::string &GetMenuItemInitialText(HMENU menu, const int menuID) {147if (initialMenuKeys.find(menuID) == initialMenuKeys.end()) {148initialMenuKeys[menuID] = GetMenuItemText(menu, menuID);149}150return initialMenuKeys[menuID];151}152153void CreateHelpMenu(HMENU menu) {154auto des = GetI18NCategory(I18NCat::DESKTOPUI);155156const std::wstring visitMainWebsite = ConvertUTF8ToWString(des->T("www.ppsspp.org"));157const std::wstring visitForum = ConvertUTF8ToWString(des->T("PPSSPP Forums"));158const std::wstring buyGold = ConvertUTF8ToWString(des->T("Buy Gold"));159const std::wstring gitHub = ConvertUTF8ToWString(des->T("GitHub"));160const std::wstring discord = ConvertUTF8ToWString(des->T("Discord"));161const std::wstring aboutPPSSPP = ConvertUTF8ToWString(des->T("About PPSSPP..."));162163HMENU helpMenu = GetSubmenuById(menu, ID_HELP_MENU);164EmptySubMenu(helpMenu);165166AppendMenu(helpMenu, MF_STRING | MF_BYCOMMAND, ID_HELP_OPENWEBSITE, visitMainWebsite.c_str());167AppendMenu(helpMenu, MF_STRING | MF_BYCOMMAND, ID_HELP_OPENFORUM, visitForum.c_str());168// Repeat the process for other languages, if necessary.169AppendMenu(helpMenu, MF_STRING | MF_BYCOMMAND, ID_HELP_BUYGOLD, buyGold.c_str());170AppendMenu(helpMenu, MF_STRING | MF_BYCOMMAND, ID_HELP_GITHUB, gitHub.c_str());171AppendMenu(helpMenu, MF_STRING | MF_BYCOMMAND, ID_HELP_DISCORD, discord.c_str());172AppendMenu(helpMenu, MF_SEPARATOR, 0, 0);173AppendMenu(helpMenu, MF_STRING | MF_BYCOMMAND, ID_HELP_ABOUT, aboutPPSSPP.c_str());174}175176static void TranslateMenuItem(const HMENU hMenu, const int menuID, const std::wstring& accelerator = L"", const char *key = nullptr) {177auto des = GetI18NCategory(I18NCat::DESKTOPUI);178179std::wstring translated;180if (key == nullptr || !strcmp(key, "")) {181translated = ConvertUTF8ToWString(des->T(GetMenuItemInitialText(hMenu, menuID)));182} else {183translated = ConvertUTF8ToWString(des->T(key));184}185translated.append(accelerator);186187ModifyMenu(hMenu, menuID, MF_STRING | MF_BYCOMMAND, menuID, translated.c_str());188}189190void DoTranslateMenus(HWND hWnd, HMENU menu) {191auto useDefHotkey = [](int virtKey) {192return !KeyMap::PspButtonHasMappings(virtKey);193};194195TranslateMenuItem(menu, ID_FILE_MENU);196TranslateMenuItem(menu, ID_EMULATION_MENU);197TranslateMenuItem(menu, ID_DEBUG_MENU);198TranslateMenuItem(menu, ID_OPTIONS_MENU);199TranslateMenuItem(menu, ID_HELP_MENU);200201// File menu202TranslateMenuItem(menu, ID_FILE_LOAD);203TranslateMenuItem(menu, ID_FILE_LOAD_DIR);204TranslateMenuItem(menu, ID_FILE_LOAD_MEMSTICK);205TranslateMenuItem(menu, ID_FILE_OPEN_NEW_INSTANCE);206TranslateMenuItem(menu, ID_FILE_MEMSTICK);207TranslateMenuItem(menu, ID_FILE_SAVESTATE_SLOT_MENU, useDefHotkey(VIRTKEY_NEXT_SLOT) ? L"\tF3" : L"");208TranslateMenuItem(menu, ID_FILE_QUICKLOADSTATE, useDefHotkey(VIRTKEY_LOAD_STATE) ? L"\tF4" : L"");209TranslateMenuItem(menu, ID_FILE_QUICKSAVESTATE, useDefHotkey(VIRTKEY_SAVE_STATE) ? L"\tF2" : L"");210TranslateMenuItem(menu, ID_FILE_LOADSTATEFILE);211TranslateMenuItem(menu, ID_FILE_SAVESTATEFILE);212TranslateMenuItem(menu, ID_FILE_RECORD_MENU);213TranslateMenuItem(menu, ID_FILE_EXIT, L"\tAlt+F4");214215// Emulation menu216TranslateMenuItem(menu, ID_EMULATION_PAUSE);217TranslateMenuItem(menu, ID_EMULATION_STOP, g_Config.bSystemControls ? L"\tCtrl+W" : L"");218TranslateMenuItem(menu, ID_EMULATION_RESET, g_Config.bSystemControls ? L"\tCtrl+B" : L"");219TranslateMenuItem(menu, ID_EMULATION_SWITCH_UMD, g_Config.bSystemControls ? L"\tCtrl+U" : L"");220TranslateMenuItem(menu, ID_EMULATION_ROTATION_MENU);221TranslateMenuItem(menu, ID_EMULATION_ROTATION_H);222TranslateMenuItem(menu, ID_EMULATION_ROTATION_V);223TranslateMenuItem(menu, ID_EMULATION_ROTATION_H_R);224TranslateMenuItem(menu, ID_EMULATION_ROTATION_V_R);225226// Debug menu227TranslateMenuItem(menu, ID_TOGGLE_BREAK, g_Config.bSystemControls ? L"\tF8" : L"", "Break");228TranslateMenuItem(menu, ID_DEBUG_BREAKONLOAD);229TranslateMenuItem(menu, ID_DEBUG_IGNOREILLEGALREADS);230TranslateMenuItem(menu, ID_DEBUG_LOADMAPFILE);231TranslateMenuItem(menu, ID_DEBUG_SAVEMAPFILE);232TranslateMenuItem(menu, ID_DEBUG_LOADSYMFILE);233TranslateMenuItem(menu, ID_DEBUG_SAVESYMFILE);234TranslateMenuItem(menu, ID_DEBUG_RESETSYMBOLTABLE);235TranslateMenuItem(menu, ID_DEBUG_TAKESCREENSHOT, g_Config.bSystemControls ? L"\tF12" : L"");236TranslateMenuItem(menu, ID_DEBUG_DUMPNEXTFRAME);237TranslateMenuItem(menu, ID_DEBUG_SHOWDEBUGSTATISTICS);238TranslateMenuItem(menu, ID_DEBUG_RESTARTGRAPHICS);239TranslateMenuItem(menu, ID_DEBUG_DISASSEMBLY, g_Config.bSystemControls ? L"\tCtrl+D" : L"");240TranslateMenuItem(menu, ID_DEBUG_GEDEBUGGER, g_Config.bSystemControls ? L"\tCtrl+G" : L"");241TranslateMenuItem(menu, ID_DEBUG_EXTRACTFILE);242TranslateMenuItem(menu, ID_DEBUG_LOG, g_Config.bSystemControls ? L"\tCtrl+L" : L"");243TranslateMenuItem(menu, ID_DEBUG_MEMORYBASE);244TranslateMenuItem(menu, ID_DEBUG_MEMORYVIEW, g_Config.bSystemControls ? L"\tCtrl+M" : L"");245246// Options menu247TranslateMenuItem(menu, ID_OPTIONS_LANGUAGE);248TranslateMenuItem(menu, ID_OPTIONS_TOPMOST);249TranslateMenuItem(menu, ID_OPTIONS_PAUSE_FOCUS);250TranslateMenuItem(menu, ID_OPTIONS_IGNOREWINKEY);251TranslateMenuItem(menu, ID_OPTIONS_MORE_SETTINGS);252TranslateMenuItem(menu, ID_OPTIONS_CONTROLS);253TranslateMenuItem(menu, ID_OPTIONS_DISPLAY_LAYOUT);254255// Movie menu256TranslateMenuItem(menu, ID_FILE_DUMPFRAMES);257TranslateMenuItem(menu, ID_FILE_USEFFV1);258TranslateMenuItem(menu, ID_FILE_DUMP_VIDEO_OUTPUT);259TranslateMenuItem(menu, ID_FILE_DUMPAUDIO);260261// Skip display multipliers x1-x10262TranslateMenuItem(menu, ID_OPTIONS_FULLSCREEN, g_Config.bSystemControls ? L"\tAlt+Return, F11" : L"");263TranslateMenuItem(menu, ID_OPTIONS_VSYNC);264TranslateMenuItem(menu, ID_OPTIONS_SCREEN_MENU, g_Config.bSystemControls ? L"\tCtrl+1" : L"");265TranslateMenuItem(menu, ID_OPTIONS_SCREENAUTO);266// Skip rendering resolution 2x-5x..267TranslateMenuItem(menu, ID_OPTIONS_WINDOW_MENU);268// Skip window size 1x-4x..269TranslateMenuItem(menu, ID_OPTIONS_BACKEND_MENU);270TranslateMenuItem(menu, ID_OPTIONS_DIRECT3D11);271TranslateMenuItem(menu, ID_OPTIONS_DIRECT3D9);272TranslateMenuItem(menu, ID_OPTIONS_OPENGL);273TranslateMenuItem(menu, ID_OPTIONS_VULKAN);274275TranslateMenuItem(menu, ID_OPTIONS_RENDERMODE_MENU);276TranslateMenuItem(menu, ID_OPTIONS_SKIP_BUFFER_EFFECTS);277TranslateMenuItem(menu, ID_OPTIONS_FRAMESKIP_MENU, g_Config.bSystemControls ? L"\tF7" : L"");278TranslateMenuItem(menu, ID_OPTIONS_FRAMESKIP_AUTO);279TranslateMenuItem(menu, ID_OPTIONS_FRAMESKIP_0);280TranslateMenuItem(menu, ID_OPTIONS_FRAMESKIPTYPE_MENU);281TranslateMenuItem(menu, ID_OPTIONS_FRAMESKIPTYPE_COUNT);282TranslateMenuItem(menu, ID_OPTIONS_FRAMESKIPTYPE_PRCNT);283// Skip frameskipping 1-8..284TranslateMenuItem(menu, ID_OPTIONS_TEXTUREFILTERING_MENU);285TranslateMenuItem(menu, ID_OPTIONS_TEXTUREFILTERING_AUTO);286TranslateMenuItem(menu, ID_OPTIONS_NEARESTFILTERING);287TranslateMenuItem(menu, ID_OPTIONS_LINEARFILTERING);288TranslateMenuItem(menu, ID_OPTIONS_AUTOMAXQUALITYFILTERING);289TranslateMenuItem(menu, ID_OPTIONS_SMART2DTEXTUREFILTERING);290TranslateMenuItem(menu, ID_OPTIONS_SCREENFILTER_MENU);291TranslateMenuItem(menu, ID_OPTIONS_BUFLINEARFILTER);292TranslateMenuItem(menu, ID_OPTIONS_BUFNEARESTFILTER);293TranslateMenuItem(menu, ID_OPTIONS_TEXTURESCALING_MENU);294TranslateMenuItem(menu, ID_TEXTURESCALING_OFF);295// Skip texture scaling 2x-5x...296TranslateMenuItem(menu, ID_TEXTURESCALING_XBRZ);297TranslateMenuItem(menu, ID_TEXTURESCALING_HYBRID);298TranslateMenuItem(menu, ID_TEXTURESCALING_BICUBIC);299TranslateMenuItem(menu, ID_TEXTURESCALING_HYBRID_BICUBIC);300TranslateMenuItem(menu, ID_TEXTURESCALING_DEPOSTERIZE);301TranslateMenuItem(menu, ID_OPTIONS_HARDWARETRANSFORM);302TranslateMenuItem(menu, ID_EMULATION_SOUND);303TranslateMenuItem(menu, ID_EMULATION_CHEATS, g_Config.bSystemControls ? L"\tCtrl+T" : L"");304TranslateMenuItem(menu, ID_EMULATION_CHAT, g_Config.bSystemControls ? L"\tCtrl+C" : L"");305306// Help menu: it's translated in CreateHelpMenu.307CreateHelpMenu(menu);308}309310void TranslateMenus(HWND hWnd, HMENU menu) {311bool changed = false;312313const std::string curLanguageID = g_i18nrepo.LanguageID();314if (curLanguageID != menuLanguageID || KeyMap::HasChanged(menuKeymapGeneration)) {315DoTranslateMenus(hWnd, menu);316menuLanguageID = curLanguageID;317changed = true;318}319320if (changed) {321DrawMenuBar(hWnd);322}323}324325void BrowseAndBootDone(std::string filename);326327void BrowseAndBoot(RequesterToken token, std::string defaultPath, bool browseDirectory) {328browsePauseAfter = false;329if (GetUIState() == UISTATE_INGAME) {330browsePauseAfter = Core_IsStepping();331if (!browsePauseAfter)332Core_EnableStepping(true, "ui.boot", 0);333}334auto mm = GetI18NCategory(I18NCat::MAINMENU);335336W32Util::MakeTopMost(GetHWND(), false);337338if (browseDirectory) {339System_BrowseForFolder(token, mm->T("Load"), Path(), [](const std::string &value, int) {340BrowseAndBootDone(value);341});342} else {343System_BrowseForFile(token, mm->T("Load"), BrowseFileType::BOOTABLE, [](const std::string &value, int) {344BrowseAndBootDone(value);345});346}347}348349void BrowseAndBootDone(std::string filename) {350if (GetUIState() == UISTATE_INGAME || GetUIState() == UISTATE_EXCEPTION || GetUIState() == UISTATE_PAUSEMENU) {351Core_EnableStepping(false);352}353filename = ReplaceAll(filename, "\\", "/");354System_PostUIMessage(UIMessage::REQUEST_GAME_BOOT, filename);355W32Util::MakeTopMost(GetHWND(), g_Config.bTopMost);356}357358static void UmdSwitchAction(RequesterToken token) {359auto mm = GetI18NCategory(I18NCat::MAINMENU);360System_BrowseForFile(token, mm->T("Switch UMD"), BrowseFileType::BOOTABLE, [](const std::string &value, int) {361__UmdReplace(Path(value));362});363}364365static void SaveStateActionFinished(SaveState::Status status, std::string_view message, void *userdata) {366if (!message.empty() && (!g_Config.bDumpFrames || !g_Config.bDumpVideoOutput)) {367g_OSD.Show(status == SaveState::Status::SUCCESS ? OSDType::MESSAGE_SUCCESS : OSDType::MESSAGE_ERROR, message, status == SaveState::Status::SUCCESS ? 2.0 : 5.0);368}369PostMessage(MainWindow::GetHWND(), WM_USER_SAVESTATE_FINISH, 0, 0);370}371372// not static373void setTexScalingMultiplier(int level) {374g_Config.iTexScalingLevel = level;375System_PostUIMessage(UIMessage::GPU_CONFIG_CHANGED);376}377378static void setTexScalingType(int type) {379g_Config.iTexScalingType = type;380System_PostUIMessage(UIMessage::GPU_CONFIG_CHANGED);381}382383static void setSkipBufferEffects(bool skip) {384g_Config.bSkipBufferEffects = skip;385System_PostUIMessage(UIMessage::GPU_CONFIG_CHANGED);386}387388static void setFrameSkipping(int framesToSkip = -1) {389if (framesToSkip >= FRAMESKIP_OFF)390g_Config.iFrameSkip = framesToSkip;391else {392if (++g_Config.iFrameSkip > FRAMESKIP_MAX)393g_Config.iFrameSkip = FRAMESKIP_OFF;394}395396auto gr = GetI18NCategory(I18NCat::GRAPHICS);397398std::ostringstream messageStream;399messageStream << gr->T("Frame Skipping") << ":" << " ";400401if (g_Config.iFrameSkip == FRAMESKIP_OFF)402messageStream << gr->T("Off");403else404messageStream << g_Config.iFrameSkip;405406g_OSD.Show(OSDType::MESSAGE_INFO, messageStream.str());407}408409static void setFrameSkippingType(int fskipType = -1) {410if (fskipType >= 0 && fskipType <= 1) {411g_Config.iFrameSkipType = fskipType;412} else {413g_Config.iFrameSkipType = 0;414}415416auto gr = GetI18NCategory(I18NCat::GRAPHICS);417418std::ostringstream messageStream;419messageStream << gr->T("Frame Skipping Type") << ":" << " ";420421if (g_Config.iFrameSkipType == 0)422messageStream << gr->T("Number of Frames");423else424messageStream << gr->T("Percent of FPS");425426g_OSD.Show(OSDType::MESSAGE_INFO, messageStream.str());427}428429static void RestartApp() {430if (System_GetPropertyBool(SYSPROP_DEBUGGER_PRESENT)) {431PostMessage(MainWindow::GetHWND(), WM_USER_RESTART_EMUTHREAD, 0, 0);432} else {433g_Config.bRestartRequired = true;434PostMessage(MainWindow::GetHWND(), WM_CLOSE, 0, 0);435}436}437438void MainWindowMenu_Process(HWND hWnd, WPARAM wParam) {439std::string fn;440441auto gr = GetI18NCategory(I18NCat::GRAPHICS);442443int wmId = LOWORD(wParam);444// Parse the menu selections:445switch (wmId) {446case ID_FILE_LOAD:447BrowseAndBoot(NON_EPHEMERAL_TOKEN, "", false);448break;449450case ID_FILE_LOAD_DIR:451BrowseAndBoot(NON_EPHEMERAL_TOKEN, "", true);452break;453454case ID_FILE_LOAD_MEMSTICK:455BrowseAndBoot(NON_EPHEMERAL_TOKEN, GetSysDirectory(DIRECTORY_GAME).ToString());456break;457458case ID_FILE_OPEN_NEW_INSTANCE:459W32Util::SpawnNewInstance(false);460break;461462case ID_FILE_MEMSTICK:463ShellExecute(NULL, L"open", g_Config.memStickDirectory.ToWString().c_str(), 0, 0, SW_SHOWNORMAL);464break;465466case ID_TOGGLE_BREAK:467if (GetUIState() == UISTATE_PAUSEMENU) {468// Causes hang (outdated comment?)469// System_PostUIMessage(UIMessage::REQUEST_GAME_RUN, "");470471if (disasmWindow)472SendMessage(disasmWindow->GetDlgHandle(), WM_COMMAND, IDC_STOPGO, 0);473} else if (Core_IsStepping()) { // It is paused, then continue to run.474if (disasmWindow)475SendMessage(disasmWindow->GetDlgHandle(), WM_COMMAND, IDC_STOPGO, 0);476else477Core_EnableStepping(false);478} else {479if (disasmWindow)480SendMessage(disasmWindow->GetDlgHandle(), WM_COMMAND, IDC_STOPGO, 0);481else482Core_EnableStepping(true, "ui.break", 0);483}484noFocusPause = !noFocusPause; // If we pause, override pause on lost focus485break;486487case ID_EMULATION_PAUSE:488System_PostUIMessage(UIMessage::REQUEST_GAME_PAUSE);489break;490491case ID_EMULATION_STOP:492if (Core_IsStepping())493Core_EnableStepping(false);494495Core_Stop();496System_PostUIMessage(UIMessage::REQUEST_GAME_STOP);497Core_WaitInactive();498break;499500case ID_EMULATION_RESET:501System_PostUIMessage(UIMessage::REQUEST_GAME_RESET);502Core_EnableStepping(false);503break;504505case ID_EMULATION_SWITCH_UMD:506UmdSwitchAction(NON_EPHEMERAL_TOKEN);507break;508509case ID_EMULATION_ROTATION_H: g_Config.iInternalScreenRotation = ROTATION_LOCKED_HORIZONTAL; break;510case ID_EMULATION_ROTATION_V: g_Config.iInternalScreenRotation = ROTATION_LOCKED_VERTICAL; break;511case ID_EMULATION_ROTATION_H_R: g_Config.iInternalScreenRotation = ROTATION_LOCKED_HORIZONTAL180; break;512case ID_EMULATION_ROTATION_V_R: g_Config.iInternalScreenRotation = ROTATION_LOCKED_VERTICAL180; break;513514case ID_EMULATION_CHEATS:515g_Config.bEnableCheats = !g_Config.bEnableCheats;516g_OSD.ShowOnOff(gr->T("Cheats"), g_Config.bEnableCheats);517break;518519case ID_EMULATION_CHAT:520if (GetUIState() == UISTATE_INGAME) {521System_PostUIMessage(UIMessage::SHOW_CHAT_SCREEN);522}523break;524case ID_FILE_LOADSTATEFILE:525if (!Achievements::WarnUserIfHardcoreModeActive(false)) {526if (W32Util::BrowseForFileName(true, hWnd, L"Load state", 0, L"Save States (*.ppst)\0*.ppst\0All files\0*.*\0\0", L"ppst", fn)) {527SetCursor(LoadCursor(0, IDC_WAIT));528SaveState::Load(Path(fn), -1, SaveStateActionFinished);529}530}531break;532case ID_FILE_SAVESTATEFILE:533if (!Achievements::WarnUserIfHardcoreModeActive(true)) {534if (W32Util::BrowseForFileName(false, hWnd, L"Save state", 0, L"Save States (*.ppst)\0*.ppst\0All files\0*.*\0\0", L"ppst", fn)) {535SetCursor(LoadCursor(0, IDC_WAIT));536SaveState::Save(Path(fn), -1, SaveStateActionFinished);537}538}539break;540541case ID_FILE_SAVESTATE_NEXT_SLOT:542{543if (!Achievements::WarnUserIfHardcoreModeActive(true)) {544SaveState::NextSlot();545System_PostUIMessage(UIMessage::SAVESTATE_DISPLAY_SLOT);546}547break;548}549550case ID_FILE_SAVESTATE_NEXT_SLOT_HC:551{552if (!Achievements::WarnUserIfHardcoreModeActive(true)) {553if (!KeyMap::PspButtonHasMappings(VIRTKEY_NEXT_SLOT)) {554SaveState::NextSlot();555System_PostUIMessage(UIMessage::SAVESTATE_DISPLAY_SLOT);556}557}558break;559}560561case ID_FILE_SAVESTATE_SLOT_1:562case ID_FILE_SAVESTATE_SLOT_2:563case ID_FILE_SAVESTATE_SLOT_3:564case ID_FILE_SAVESTATE_SLOT_4:565case ID_FILE_SAVESTATE_SLOT_5:566if (!Achievements::WarnUserIfHardcoreModeActive(true)) {567g_Config.iCurrentStateSlot = wmId - ID_FILE_SAVESTATE_SLOT_1;568}569break;570571case ID_FILE_QUICKLOADSTATE:572if (!Achievements::WarnUserIfHardcoreModeActive(false)) {573SetCursor(LoadCursor(0, IDC_WAIT));574SaveState::LoadSlot(PSP_CoreParameter().fileToStart, g_Config.iCurrentStateSlot, SaveStateActionFinished);575}576break;577578case ID_FILE_QUICKLOADSTATE_HC:579{580if (!Achievements::WarnUserIfHardcoreModeActive(false)) {581if (!KeyMap::PspButtonHasMappings(VIRTKEY_LOAD_STATE)) {582SetCursor(LoadCursor(0, IDC_WAIT));583SaveState::LoadSlot(PSP_CoreParameter().fileToStart, g_Config.iCurrentStateSlot, SaveStateActionFinished);584}585}586break;587}588case ID_FILE_QUICKSAVESTATE:589{590if (!Achievements::WarnUserIfHardcoreModeActive(true)) {591SetCursor(LoadCursor(0, IDC_WAIT));592SaveState::SaveSlot(PSP_CoreParameter().fileToStart, g_Config.iCurrentStateSlot, SaveStateActionFinished);593}594break;595}596597case ID_FILE_QUICKSAVESTATE_HC:598{599if (!Achievements::WarnUserIfHardcoreModeActive(true)) {600if (!KeyMap::PspButtonHasMappings(VIRTKEY_SAVE_STATE))601{602SetCursor(LoadCursor(0, IDC_WAIT));603SaveState::SaveSlot(PSP_CoreParameter().fileToStart, g_Config.iCurrentStateSlot, SaveStateActionFinished);604break;605}606}607break;608}609610case ID_OPTIONS_LANGUAGE:611System_PostUIMessage(UIMessage::SHOW_LANGUAGE_SCREEN);612break;613614case ID_OPTIONS_IGNOREWINKEY:615g_Config.bIgnoreWindowsKey = !g_Config.bIgnoreWindowsKey;616break;617618case ID_OPTIONS_SCREENAUTO: SetInternalResolution(RESOLUTION_AUTO); break;619case ID_OPTIONS_SCREEN1X: SetInternalResolution(RESOLUTION_NATIVE); break;620case ID_OPTIONS_SCREEN2X: SetInternalResolution(RESOLUTION_2X); break;621case ID_OPTIONS_SCREEN3X: SetInternalResolution(RESOLUTION_3X); break;622case ID_OPTIONS_SCREEN4X: SetInternalResolution(RESOLUTION_4X); break;623case ID_OPTIONS_SCREEN5X: SetInternalResolution(RESOLUTION_5X); break;624case ID_OPTIONS_SCREEN6X: SetInternalResolution(RESOLUTION_6X); break;625case ID_OPTIONS_SCREEN7X: SetInternalResolution(RESOLUTION_7X); break;626case ID_OPTIONS_SCREEN8X: SetInternalResolution(RESOLUTION_8X); break;627case ID_OPTIONS_SCREEN9X: SetInternalResolution(RESOLUTION_9X); break;628case ID_OPTIONS_SCREEN10X: SetInternalResolution(RESOLUTION_MAX); break;629630case ID_OPTIONS_WINDOW1X: SetWindowSize(1); break;631case ID_OPTIONS_WINDOW2X: SetWindowSize(2); break;632case ID_OPTIONS_WINDOW3X: SetWindowSize(3); break;633case ID_OPTIONS_WINDOW4X: SetWindowSize(4); break;634case ID_OPTIONS_WINDOW5X: SetWindowSize(5); break;635case ID_OPTIONS_WINDOW6X: SetWindowSize(6); break;636case ID_OPTIONS_WINDOW7X: SetWindowSize(7); break;637case ID_OPTIONS_WINDOW8X: SetWindowSize(8); break;638case ID_OPTIONS_WINDOW9X: SetWindowSize(9); break;639case ID_OPTIONS_WINDOW10X: SetWindowSize(10); break;640641case ID_OPTIONS_RESOLUTIONDUMMY:642{643SetInternalResolution();644break;645}646647case ID_OPTIONS_VSYNC:648g_Config.bVSync = !g_Config.bVSync;649NativeResized();650break;651652case ID_OPTIONS_FRAMESKIP_AUTO:653g_Config.bAutoFrameSkip = !g_Config.bAutoFrameSkip;654if (g_Config.bAutoFrameSkip && g_Config.bSkipBufferEffects) {655g_Config.bSkipBufferEffects = false;656System_PostUIMessage(UIMessage::GPU_CONFIG_CHANGED);657}658break;659660case ID_TEXTURESCALING_OFF: setTexScalingMultiplier(TEXSCALING_OFF); break;661case ID_TEXTURESCALING_2X: setTexScalingMultiplier(TEXSCALING_2X); break;662case ID_TEXTURESCALING_3X: setTexScalingMultiplier(TEXSCALING_3X); break;663case ID_TEXTURESCALING_4X: setTexScalingMultiplier(TEXSCALING_4X); break;664case ID_TEXTURESCALING_5X: setTexScalingMultiplier(TEXSCALING_MAX); break;665666case ID_TEXTURESCALING_XBRZ: setTexScalingType(TextureScalerCommon::XBRZ); break;667case ID_TEXTURESCALING_HYBRID: setTexScalingType(TextureScalerCommon::HYBRID); break;668case ID_TEXTURESCALING_BICUBIC: setTexScalingType(TextureScalerCommon::BICUBIC); break;669case ID_TEXTURESCALING_HYBRID_BICUBIC: setTexScalingType(TextureScalerCommon::HYBRID_BICUBIC); break;670671case ID_TEXTURESCALING_DEPOSTERIZE:672g_Config.bTexDeposterize = !g_Config.bTexDeposterize;673System_PostUIMessage(UIMessage::GPU_CONFIG_CHANGED);674break;675676case ID_OPTIONS_DIRECT3D9:677g_Config.iGPUBackend = (int)GPUBackend::DIRECT3D9;678g_Config.Save("gpu_choice");679RestartApp();680break;681682case ID_OPTIONS_DIRECT3D11:683g_Config.iGPUBackend = (int)GPUBackend::DIRECT3D11;684g_Config.Save("gpu_choice");685RestartApp();686break;687688case ID_OPTIONS_OPENGL:689g_Config.iGPUBackend = (int)GPUBackend::OPENGL;690g_Config.Save("gpu_choice");691RestartApp();692break;693694case ID_OPTIONS_VULKAN:695g_Config.iGPUBackend = (int)GPUBackend::VULKAN;696g_Config.Save("gpu_choice");697RestartApp();698break;699700case ID_OPTIONS_SKIP_BUFFER_EFFECTS:701g_Config.bSkipBufferEffects = !g_Config.bSkipBufferEffects;702System_PostUIMessage(UIMessage::GPU_RENDER_RESIZED);703g_OSD.ShowOnOff(gr->T("Skip Buffer Effects"), g_Config.bSkipBufferEffects);704break;705706case ID_DEBUG_SHOWDEBUGSTATISTICS:707// This is still useful as a shortcut to tell users to use.708// So let's fake the enum.709if ((DebugOverlay)g_Config.iDebugOverlay == DebugOverlay::DEBUG_STATS) {710g_Config.iDebugOverlay = (int)DebugOverlay::OFF;711} else {712g_Config.iDebugOverlay = (int)DebugOverlay::DEBUG_STATS;713}714System_PostUIMessage(UIMessage::REQUEST_CLEAR_JIT);715break;716717case ID_OPTIONS_HARDWARETRANSFORM:718g_Config.bHardwareTransform = !g_Config.bHardwareTransform;719System_PostUIMessage(UIMessage::GPU_CONFIG_CHANGED);720g_OSD.ShowOnOff(gr->T("Hardware Transform"), g_Config.bHardwareTransform);721break;722723case ID_OPTIONS_DISPLAY_LAYOUT:724System_PostUIMessage(UIMessage::SHOW_DISPLAY_LAYOUT_EDITOR);725break;726727728case ID_OPTIONS_FRAMESKIP_0: setFrameSkipping(FRAMESKIP_OFF); break;729case ID_OPTIONS_FRAMESKIP_1: setFrameSkipping(FRAMESKIP_1); break;730case ID_OPTIONS_FRAMESKIP_2: setFrameSkipping(FRAMESKIP_2); break;731case ID_OPTIONS_FRAMESKIP_3: setFrameSkipping(FRAMESKIP_3); break;732case ID_OPTIONS_FRAMESKIP_4: setFrameSkipping(FRAMESKIP_4); break;733case ID_OPTIONS_FRAMESKIP_5: setFrameSkipping(FRAMESKIP_5); break;734case ID_OPTIONS_FRAMESKIP_6: setFrameSkipping(FRAMESKIP_6); break;735case ID_OPTIONS_FRAMESKIP_7: setFrameSkipping(FRAMESKIP_7); break;736case ID_OPTIONS_FRAMESKIP_8: setFrameSkipping(FRAMESKIP_MAX); break;737738case ID_OPTIONS_FRAMESKIPTYPE_COUNT: setFrameSkippingType(FRAMESKIPTYPE_COUNT); break;739case ID_OPTIONS_FRAMESKIPTYPE_PRCNT: setFrameSkippingType(FRAMESKIPTYPE_PRCNT); break;740741case ID_OPTIONS_FRAMESKIPDUMMY:742setFrameSkipping();743setFrameSkippingType();744break;745746case ID_FILE_EXIT:747PostMessage(hWnd, WM_CLOSE, 0, 0);748break;749750case ID_DEBUG_BREAKONLOAD:751g_Config.bAutoRun = !g_Config.bAutoRun;752break;753754case ID_DEBUG_DUMPNEXTFRAME:755System_PostUIMessage(UIMessage::REQUEST_GPU_DUMP_NEXT_FRAME);756break;757758case ID_DEBUG_LOADMAPFILE:759if (W32Util::BrowseForFileName(true, hWnd, L"Load .ppmap", 0, L"Maps\0*.ppmap\0All files\0*.*\0\0", L"ppmap", fn)) {760g_symbolMap->LoadSymbolMap(Path(fn));761NotifyDebuggerMapLoaded();762}763break;764765case ID_DEBUG_SAVEMAPFILE:766if (W32Util::BrowseForFileName(false, hWnd, L"Save .ppmap", 0, L"Maps\0*.ppmap\0All files\0*.*\0\0", L"ppmap", fn))767g_symbolMap->SaveSymbolMap(Path(fn));768break;769770case ID_DEBUG_LOADSYMFILE:771if (W32Util::BrowseForFileName(true, hWnd, L"Load .sym", 0, L"Symbols\0*.sym\0All files\0*.*\0\0", L"sym", fn)) {772g_symbolMap->LoadNocashSym(Path(fn));773NotifyDebuggerMapLoaded();774}775break;776777case ID_DEBUG_SAVESYMFILE:778if (W32Util::BrowseForFileName(false, hWnd, L"Save .sym", 0, L"Symbols\0*.sym\0All files\0*.*\0\0", L"sym", fn))779g_symbolMap->SaveNocashSym(Path(fn));780break;781782case ID_DEBUG_RESETSYMBOLTABLE:783g_symbolMap->Clear();784NotifyDebuggerMapLoaded();785break;786787case ID_DEBUG_DISASSEMBLY:788CreateDisasmWindow();789if (disasmWindow)790disasmWindow->Show(true);791break;792793case ID_DEBUG_GEDEBUGGER:794#if PPSSPP_API(ANY_GL)795CreateGeDebuggerWindow();796if (geDebuggerWindow)797geDebuggerWindow->Show(true);798#endif799break;800801case ID_DEBUG_MEMORYVIEW:802CreateMemoryWindow();803if (memoryWindow)804memoryWindow->Show(true);805break;806807case ID_DEBUG_MEMORYBASE:808{809W32Util::CopyTextToClipboard(hWnd, ConvertUTF8ToWString(StringFromFormat("%016llx", (uint64_t)(uintptr_t)Memory::base)));810break;811}812813case ID_DEBUG_EXTRACTFILE:814{815std::string filename;816if (!InputBox_GetString(hInst, hWnd, L"Disc filename", filename, filename)) {817break;818}819820const char *lastSlash = strrchr(filename.c_str(), '/');821if (lastSlash) {822fn = lastSlash + 1;823} else {824fn.clear();825}826827PSPFileInfo info = pspFileSystem.GetFileInfo(filename);828if (!info.exists) {829MessageBox(hWnd, L"File does not exist.", L"Sorry", 0);830} else if (info.type == FILETYPE_DIRECTORY) {831MessageBox(hWnd, L"Cannot extract directories.", L"Sorry", 0);832} else if (W32Util::BrowseForFileName(false, hWnd, L"Save file as...", 0, L"All files\0*.*\0\0", L"", fn)) {833u32 handle = pspFileSystem.OpenFile(filename, FILEACCESS_READ, "");834// Note: len may be in blocks.835size_t len = pspFileSystem.SeekFile(handle, 0, FILEMOVE_END);836bool isBlockMode = pspFileSystem.DevType(handle) & PSPDevType::BLOCK;837838FILE *fp = File::OpenCFile(Path(fn), "wb");839pspFileSystem.SeekFile(handle, 0, FILEMOVE_BEGIN);840u8 buffer[4096];841size_t bufferSize = isBlockMode ? sizeof(buffer) / 2048 : sizeof(buffer);842while (len > 0) {843// This is all in blocks, not bytes, if isBlockMode.844size_t remain = std::min(len, bufferSize);845size_t readSize = pspFileSystem.ReadFile(handle, buffer, remain);846if (readSize == 0)847break;848size_t bytes = isBlockMode ? readSize * 2048 : readSize;849fwrite(buffer, 1, bytes, fp);850len -= readSize;851}852pspFileSystem.CloseFile(handle);853fclose(fp);854}855}856break;857858case ID_DEBUG_LOG:859LogManager::GetInstance()->GetConsoleListener()->Show(LogManager::GetInstance()->GetConsoleListener()->Hidden());860break;861862case ID_DEBUG_IGNOREILLEGALREADS:863g_Config.bIgnoreBadMemAccess = !g_Config.bIgnoreBadMemAccess;864break;865866case ID_OPTIONS_FULLSCREEN:867SendToggleFullscreen(!g_Config.UseFullScreen());868break;869870case ID_OPTIONS_TEXTUREFILTERING_AUTO: g_Config.iTexFiltering = TEX_FILTER_AUTO; break;871case ID_OPTIONS_NEARESTFILTERING: g_Config.iTexFiltering = TEX_FILTER_FORCE_NEAREST; break;872case ID_OPTIONS_LINEARFILTERING: g_Config.iTexFiltering = TEX_FILTER_FORCE_LINEAR; break;873case ID_OPTIONS_AUTOMAXQUALITYFILTERING: g_Config.iTexFiltering = TEX_FILTER_AUTO_MAX_QUALITY; break;874875case ID_OPTIONS_SMART2DTEXTUREFILTERING: g_Config.bSmart2DTexFiltering = !g_Config.bSmart2DTexFiltering; break;876877case ID_OPTIONS_BUFLINEARFILTER: g_Config.iDisplayFilter = SCALE_LINEAR; break;878case ID_OPTIONS_BUFNEARESTFILTER: g_Config.iDisplayFilter = SCALE_NEAREST; break;879880case ID_OPTIONS_TOPMOST:881g_Config.bTopMost = !g_Config.bTopMost;882W32Util::MakeTopMost(hWnd, g_Config.bTopMost);883break;884885case ID_OPTIONS_PAUSE_FOCUS:886g_Config.bPauseOnLostFocus = !g_Config.bPauseOnLostFocus;887break;888889case ID_OPTIONS_CONTROLS:890System_PostUIMessage(UIMessage::SHOW_CONTROL_MAPPING);891break;892893case ID_OPTIONS_MORE_SETTINGS:894System_PostUIMessage(UIMessage::SHOW_SETTINGS);895break;896897case ID_EMULATION_SOUND:898g_Config.bEnableSound = !g_Config.bEnableSound;899break;900901case ID_HELP_OPENWEBSITE:902ShellExecute(NULL, L"open", L"https://www.ppsspp.org/", NULL, NULL, SW_SHOWNORMAL);903break;904905case ID_HELP_BUYGOLD:906ShellExecute(NULL, L"open", L"https://www.ppsspp.org/buygold", NULL, NULL, SW_SHOWNORMAL);907break;908909case ID_HELP_OPENFORUM:910ShellExecute(NULL, L"open", L"https://forums.ppsspp.org/", NULL, NULL, SW_SHOWNORMAL);911break;912913case ID_HELP_GITHUB:914ShellExecute(NULL, L"open", L"https://github.com/hrydgard/ppsspp/", NULL, NULL, SW_SHOWNORMAL);915break;916917case ID_HELP_DISCORD:918ShellExecute(NULL, L"open", L"https://discord.gg/5NJB6dD", NULL, NULL, SW_SHOWNORMAL);919break;920921case ID_HELP_ABOUT:922DialogManager::EnableAll(FALSE);923DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)AboutDlgProc);924DialogManager::EnableAll(TRUE);925break;926927case ID_DEBUG_TAKESCREENSHOT:928g_TakeScreenshot = true;929break;930931case ID_DEBUG_RESTARTGRAPHICS:932System_PostUIMessage(UIMessage::RESTART_GRAPHICS);933break;934935case ID_FILE_DUMPFRAMES:936g_Config.bDumpFrames = !g_Config.bDumpFrames;937break;938939case ID_FILE_USEFFV1:940g_Config.bUseFFV1 = !g_Config.bUseFFV1;941break;942943case ID_FILE_DUMP_VIDEO_OUTPUT:944g_Config.bDumpVideoOutput = !g_Config.bDumpVideoOutput;945break;946947case ID_FILE_DUMPAUDIO:948g_Config.bDumpAudio = !g_Config.bDumpAudio;949break;950951default:952#ifdef RC_CLIENT_SUPPORTS_RAINTEGRATION953if (rc_client_raintegration_activate_menu_item(Achievements::GetClient(), LOWORD(wParam))) {954break;955}956#endif957MessageBox(hWnd, L"Unhandled menu item", L"Sorry", 0);958break;959}960}961962void UpdateMenus(bool isMenuSelect) {963if (isMenuSelect) {964menuShaderInfoLoaded = false;965}966967HMENU menu = GetMenu(GetHWND());968#define CHECKITEM(item,value) CheckMenuItem(menu,item,MF_BYCOMMAND | ((value) ? MF_CHECKED : MF_UNCHECKED));969CHECKITEM(ID_DEBUG_IGNOREILLEGALREADS, g_Config.bIgnoreBadMemAccess);970CHECKITEM(ID_DEBUG_SHOWDEBUGSTATISTICS, (DebugOverlay)g_Config.iDebugOverlay == DebugOverlay::DEBUG_STATS);971CHECKITEM(ID_OPTIONS_HARDWARETRANSFORM, g_Config.bHardwareTransform);972CHECKITEM(ID_DEBUG_BREAKONLOAD, !g_Config.bAutoRun);973CHECKITEM(ID_OPTIONS_FRAMESKIP_AUTO, g_Config.bAutoFrameSkip);974CHECKITEM(ID_OPTIONS_FRAMESKIP, g_Config.iFrameSkip != FRAMESKIP_OFF);975CHECKITEM(ID_OPTIONS_FRAMESKIPTYPE_COUNT, g_Config.iFrameSkipType == FRAMESKIPTYPE_COUNT);976CHECKITEM(ID_OPTIONS_FRAMESKIPTYPE_PRCNT, g_Config.iFrameSkipType == FRAMESKIPTYPE_PRCNT);977CHECKITEM(ID_OPTIONS_VSYNC, g_Config.bVSync);978CHECKITEM(ID_OPTIONS_TOPMOST, g_Config.bTopMost);979CHECKITEM(ID_OPTIONS_PAUSE_FOCUS, g_Config.bPauseOnLostFocus);980CHECKITEM(ID_OPTIONS_SMART2DTEXTUREFILTERING, g_Config.bSmart2DTexFiltering);981CHECKITEM(ID_EMULATION_SOUND, g_Config.bEnableSound);982CHECKITEM(ID_TEXTURESCALING_DEPOSTERIZE, g_Config.bTexDeposterize);983CHECKITEM(ID_EMULATION_CHEATS, g_Config.bEnableCheats);984CHECKITEM(ID_OPTIONS_IGNOREWINKEY, g_Config.bIgnoreWindowsKey);985CHECKITEM(ID_FILE_DUMPFRAMES, g_Config.bDumpFrames);986CHECKITEM(ID_FILE_USEFFV1, g_Config.bUseFFV1);987CHECKITEM(ID_FILE_DUMP_VIDEO_OUTPUT, g_Config.bDumpVideoOutput);988CHECKITEM(ID_FILE_DUMPAUDIO, g_Config.bDumpAudio);989CHECKITEM(ID_OPTIONS_SKIP_BUFFER_EFFECTS, g_Config.bSkipBufferEffects);990991static const int displayrotationitems[] = {992ID_EMULATION_ROTATION_H,993ID_EMULATION_ROTATION_V,994ID_EMULATION_ROTATION_H_R,995ID_EMULATION_ROTATION_V_R996};997if (g_Config.iInternalScreenRotation < ROTATION_LOCKED_HORIZONTAL)998g_Config.iInternalScreenRotation = ROTATION_LOCKED_HORIZONTAL;9991000else if (g_Config.iInternalScreenRotation > ROTATION_LOCKED_VERTICAL180)1001g_Config.iInternalScreenRotation = ROTATION_LOCKED_VERTICAL180;10021003for (int i = 0; i < ARRAY_SIZE(displayrotationitems); i++) {1004CheckMenuItem(menu, displayrotationitems[i], MF_BYCOMMAND | ((i + 1) == g_Config.iInternalScreenRotation ? MF_CHECKED : MF_UNCHECKED));1005}10061007static const int zoomitems[11] = {1008ID_OPTIONS_SCREENAUTO,1009ID_OPTIONS_SCREEN1X,1010ID_OPTIONS_SCREEN2X,1011ID_OPTIONS_SCREEN3X,1012ID_OPTIONS_SCREEN4X,1013ID_OPTIONS_SCREEN5X,1014ID_OPTIONS_SCREEN6X,1015ID_OPTIONS_SCREEN7X,1016ID_OPTIONS_SCREEN8X,1017ID_OPTIONS_SCREEN9X,1018ID_OPTIONS_SCREEN10X,1019};1020if (g_Config.iInternalResolution < RESOLUTION_AUTO)1021g_Config.iInternalResolution = RESOLUTION_AUTO;10221023else if (g_Config.iInternalResolution > RESOLUTION_MAX)1024g_Config.iInternalResolution = RESOLUTION_MAX;10251026for (int i = 0; i < ARRAY_SIZE(zoomitems); i++) {1027CheckMenuItem(menu, zoomitems[i], MF_BYCOMMAND | ((i == g_Config.iInternalResolution) ? MF_CHECKED : MF_UNCHECKED));1028}10291030static const int windowSizeItems[10] = {1031ID_OPTIONS_WINDOW1X,1032ID_OPTIONS_WINDOW2X,1033ID_OPTIONS_WINDOW3X,1034ID_OPTIONS_WINDOW4X,1035ID_OPTIONS_WINDOW5X,1036ID_OPTIONS_WINDOW6X,1037ID_OPTIONS_WINDOW7X,1038ID_OPTIONS_WINDOW8X,1039ID_OPTIONS_WINDOW9X,1040ID_OPTIONS_WINDOW10X,1041};10421043RECT rc;1044GetClientRect(GetHWND(), &rc);10451046int checkW = g_Config.IsPortrait() ? 272 : 480;1047int checkH = g_Config.IsPortrait() ? 480 : 272;10481049for (int i = 0; i < ARRAY_SIZE(windowSizeItems); i++) {1050bool check = (i + 1) * checkW == rc.right - rc.left || (i + 1) * checkH == rc.bottom - rc.top;1051CheckMenuItem(menu, windowSizeItems[i], MF_BYCOMMAND | (check ? MF_CHECKED : MF_UNCHECKED));1052}10531054static const int texscalingitems[] = {1055ID_TEXTURESCALING_OFF,1056ID_TEXTURESCALING_2X,1057ID_TEXTURESCALING_3X,1058ID_TEXTURESCALING_4X,1059ID_TEXTURESCALING_5X,1060};1061if (g_Config.iTexScalingLevel < TEXSCALING_OFF)1062g_Config.iTexScalingLevel = TEXSCALING_OFF;10631064else if (g_Config.iTexScalingLevel > TEXSCALING_MAX)1065g_Config.iTexScalingLevel = TEXSCALING_MAX;10661067for (int i = 0; i < ARRAY_SIZE(texscalingitems); i++) {1068// OFF is 1, skip 0.1069bool selected = i + 1 == g_Config.iTexScalingLevel;1070CheckMenuItem(menu, texscalingitems[i], MF_BYCOMMAND | (selected ? MF_CHECKED : MF_UNCHECKED));1071}10721073if (g_Config.iGPUBackend == (int)GPUBackend::OPENGL && !gl_extensions.OES_texture_npot) {1074EnableMenuItem(menu, ID_TEXTURESCALING_3X, MF_GRAYED);1075EnableMenuItem(menu, ID_TEXTURESCALING_5X, MF_GRAYED);1076} else {1077EnableMenuItem(menu, ID_TEXTURESCALING_3X, MF_ENABLED);1078EnableMenuItem(menu, ID_TEXTURESCALING_5X, MF_ENABLED);1079}10801081static const int texscalingtypeitems[] = {1082ID_TEXTURESCALING_XBRZ,1083ID_TEXTURESCALING_HYBRID,1084ID_TEXTURESCALING_BICUBIC,1085ID_TEXTURESCALING_HYBRID_BICUBIC,1086};1087if (g_Config.iTexScalingType < TextureScalerCommon::XBRZ)1088g_Config.iTexScalingType = TextureScalerCommon::XBRZ;10891090else if (g_Config.iTexScalingType > TextureScalerCommon::HYBRID_BICUBIC)1091g_Config.iTexScalingType = TextureScalerCommon::HYBRID_BICUBIC;10921093for (int i = 0; i < ARRAY_SIZE(texscalingtypeitems); i++) {1094CheckMenuItem(menu, texscalingtypeitems[i], MF_BYCOMMAND | ((i == g_Config.iTexScalingType) ? MF_CHECKED : MF_UNCHECKED));1095}10961097static const int texfilteringitems[] = {1098ID_OPTIONS_TEXTUREFILTERING_AUTO,1099ID_OPTIONS_NEARESTFILTERING,1100ID_OPTIONS_LINEARFILTERING,1101ID_OPTIONS_AUTOMAXQUALITYFILTERING,1102};1103if (g_Config.iTexFiltering < TEX_FILTER_AUTO)1104g_Config.iTexFiltering = TEX_FILTER_AUTO;1105else if (g_Config.iTexFiltering > TEX_FILTER_AUTO_MAX_QUALITY)1106g_Config.iTexFiltering = TEX_FILTER_AUTO_MAX_QUALITY;11071108for (int i = 0; i < ARRAY_SIZE(texfilteringitems); i++) {1109CheckMenuItem(menu, texfilteringitems[i], MF_BYCOMMAND | ((i + 1) == g_Config.iTexFiltering ? MF_CHECKED : MF_UNCHECKED));1110}11111112static const int bufferfilteritems[] = {1113ID_OPTIONS_BUFLINEARFILTER,1114ID_OPTIONS_BUFNEARESTFILTER,1115};1116if (g_Config.iDisplayFilter < SCALE_LINEAR)1117g_Config.iDisplayFilter = SCALE_LINEAR;11181119else if (g_Config.iDisplayFilter > SCALE_NEAREST)1120g_Config.iDisplayFilter = SCALE_NEAREST;11211122for (int i = 0; i < ARRAY_SIZE(bufferfilteritems); i++) {1123CheckMenuItem(menu, bufferfilteritems[i], MF_BYCOMMAND | ((i + 1) == g_Config.iDisplayFilter ? MF_CHECKED : MF_UNCHECKED));1124}11251126static const int frameskipping[] = {1127ID_OPTIONS_FRAMESKIP_0,1128ID_OPTIONS_FRAMESKIP_1,1129ID_OPTIONS_FRAMESKIP_2,1130ID_OPTIONS_FRAMESKIP_3,1131ID_OPTIONS_FRAMESKIP_4,1132ID_OPTIONS_FRAMESKIP_5,1133ID_OPTIONS_FRAMESKIP_6,1134ID_OPTIONS_FRAMESKIP_7,1135ID_OPTIONS_FRAMESKIP_8,1136};11371138static const int frameskippingType[] = {1139ID_OPTIONS_FRAMESKIPTYPE_COUNT,1140ID_OPTIONS_FRAMESKIPTYPE_PRCNT,1141};11421143if (g_Config.iFrameSkip < FRAMESKIP_OFF)1144g_Config.iFrameSkip = FRAMESKIP_OFF;11451146else if (g_Config.iFrameSkip > FRAMESKIP_MAX)1147g_Config.iFrameSkip = FRAMESKIP_MAX;11481149for (int i = 0; i < ARRAY_SIZE(frameskipping); i++) {1150CheckMenuItem(menu, frameskipping[i], MF_BYCOMMAND | ((i == g_Config.iFrameSkip) ? MF_CHECKED : MF_UNCHECKED));1151}11521153for (int i = 0; i < ARRAY_SIZE(frameskippingType); i++) {1154CheckMenuItem(menu, frameskippingType[i], MF_BYCOMMAND | ((i == g_Config.iFrameSkipType) ? MF_CHECKED : MF_UNCHECKED));1155}11561157static const int savestateSlot[] = {1158ID_FILE_SAVESTATE_SLOT_1,1159ID_FILE_SAVESTATE_SLOT_2,1160ID_FILE_SAVESTATE_SLOT_3,1161ID_FILE_SAVESTATE_SLOT_4,1162ID_FILE_SAVESTATE_SLOT_5,1163};11641165if (g_Config.iCurrentStateSlot < 0)1166g_Config.iCurrentStateSlot = 0;11671168else if (g_Config.iCurrentStateSlot >= SaveState::NUM_SLOTS)1169g_Config.iCurrentStateSlot = SaveState::NUM_SLOTS - 1;11701171for (int i = 0; i < ARRAY_SIZE(savestateSlot); i++) {1172CheckMenuItem(menu, savestateSlot[i], MF_BYCOMMAND | ((i == g_Config.iCurrentStateSlot) ? MF_CHECKED : MF_UNCHECKED));1173}11741175bool allowD3D9 = g_Config.IsBackendEnabled(GPUBackend::DIRECT3D9);1176bool allowD3D11 = g_Config.IsBackendEnabled(GPUBackend::DIRECT3D11);1177bool allowOpenGL = g_Config.IsBackendEnabled(GPUBackend::OPENGL);1178bool allowVulkan = g_Config.IsBackendEnabled(GPUBackend::VULKAN);11791180switch (GetGPUBackend()) {1181case GPUBackend::DIRECT3D9:1182EnableMenuItem(menu, ID_OPTIONS_DIRECT3D9, MF_GRAYED);1183EnableMenuItem(menu, ID_OPTIONS_DIRECT3D11, allowD3D11 ? MF_ENABLED : MF_GRAYED);1184EnableMenuItem(menu, ID_OPTIONS_OPENGL, allowOpenGL ? MF_ENABLED : MF_GRAYED);1185EnableMenuItem(menu, ID_OPTIONS_VULKAN, allowVulkan ? MF_ENABLED : MF_GRAYED);1186CheckMenuItem(menu, ID_OPTIONS_DIRECT3D9, MF_CHECKED);1187CheckMenuItem(menu, ID_OPTIONS_DIRECT3D11, MF_UNCHECKED);1188CheckMenuItem(menu, ID_OPTIONS_OPENGL, MF_UNCHECKED);1189CheckMenuItem(menu, ID_OPTIONS_VULKAN, MF_UNCHECKED);1190break;1191case GPUBackend::OPENGL:1192EnableMenuItem(menu, ID_OPTIONS_DIRECT3D9, allowD3D9 ? MF_ENABLED : MF_GRAYED);1193EnableMenuItem(menu, ID_OPTIONS_DIRECT3D11, allowD3D11 ? MF_ENABLED : MF_GRAYED);1194EnableMenuItem(menu, ID_OPTIONS_OPENGL, MF_GRAYED);1195EnableMenuItem(menu, ID_OPTIONS_VULKAN, allowVulkan ? MF_ENABLED : MF_GRAYED);1196CheckMenuItem(menu, ID_OPTIONS_DIRECT3D9, MF_UNCHECKED);1197CheckMenuItem(menu, ID_OPTIONS_DIRECT3D11, MF_UNCHECKED);1198CheckMenuItem(menu, ID_OPTIONS_OPENGL, MF_CHECKED);1199CheckMenuItem(menu, ID_OPTIONS_VULKAN, MF_UNCHECKED);1200break;1201case GPUBackend::VULKAN:1202EnableMenuItem(menu, ID_OPTIONS_DIRECT3D9, allowD3D9 ? MF_ENABLED : MF_GRAYED);1203EnableMenuItem(menu, ID_OPTIONS_DIRECT3D11, allowD3D11 ? MF_ENABLED : MF_GRAYED);1204EnableMenuItem(menu, ID_OPTIONS_OPENGL, allowOpenGL ? MF_ENABLED : MF_GRAYED);1205EnableMenuItem(menu, ID_OPTIONS_VULKAN, MF_GRAYED);1206CheckMenuItem(menu, ID_OPTIONS_DIRECT3D9, MF_UNCHECKED);1207CheckMenuItem(menu, ID_OPTIONS_DIRECT3D11, MF_UNCHECKED);1208CheckMenuItem(menu, ID_OPTIONS_OPENGL, MF_UNCHECKED);1209CheckMenuItem(menu, ID_OPTIONS_VULKAN, MF_CHECKED);1210break;1211case GPUBackend::DIRECT3D11:1212EnableMenuItem(menu, ID_OPTIONS_DIRECT3D9, allowD3D9 ? MF_ENABLED : MF_GRAYED);1213EnableMenuItem(menu, ID_OPTIONS_DIRECT3D11, MF_GRAYED);1214EnableMenuItem(menu, ID_OPTIONS_OPENGL, allowOpenGL ? MF_ENABLED : MF_GRAYED);1215EnableMenuItem(menu, ID_OPTIONS_VULKAN, allowVulkan ? MF_ENABLED : MF_GRAYED);1216CheckMenuItem(menu, ID_OPTIONS_DIRECT3D9, MF_UNCHECKED);1217CheckMenuItem(menu, ID_OPTIONS_DIRECT3D11, MF_CHECKED);1218CheckMenuItem(menu, ID_OPTIONS_OPENGL, MF_UNCHECKED);1219CheckMenuItem(menu, ID_OPTIONS_VULKAN, MF_UNCHECKED);1220break;1221}12221223#if !PPSSPP_API(ANY_GL)1224EnableMenuItem(menu, ID_DEBUG_GEDEBUGGER, MF_GRAYED);1225#endif12261227UpdateCommands();1228}12291230void UpdateCommands() {1231static GlobalUIState lastGlobalUIState = UISTATE_PAUSEMENU;1232static CoreState lastCoreState = CORE_BOOT_ERROR;12331234HMENU menu = GetMenu(GetHWND());1235EnableMenuItem(menu, ID_DEBUG_LOG, g_Config.bEnableLogging ? MF_ENABLED : MF_GRAYED);1236SetIngameMenuItemStates(menu, GetUIState());12371238if (lastGlobalUIState == GetUIState() && lastCoreState == coreState)1239return;12401241lastCoreState = coreState;1242lastGlobalUIState = GetUIState();12431244bool isPaused = Core_IsStepping() && GetUIState() == UISTATE_INGAME;1245TranslateMenuItem(menu, ID_TOGGLE_BREAK, L"\tF8", isPaused ? "Run" : "Break");1246}12471248void UpdateSwitchUMD() {1249HMENU menu = GetMenu(GetHWND());1250GlobalUIState state = GetUIState();1251UINT umdSwitchEnable = state == UISTATE_INGAME && getUMDReplacePermit() ? MF_ENABLED : MF_GRAYED;1252EnableMenuItem(menu, ID_EMULATION_SWITCH_UMD, umdSwitchEnable);1253}12541255// Message handler for about box.1256LRESULT CALLBACK AboutDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {1257switch (message) {1258case WM_INITDIALOG:1259{1260W32Util::CenterWindow(hDlg);1261HWND versionBox = GetDlgItem(hDlg, IDC_VERSION);1262std::string windowText = System_GetPropertyBool(SYSPROP_APP_GOLD) ? "PPSSPP Gold " : "PPSSPP ";1263windowText.append(PPSSPP_GIT_VERSION);1264SetWindowText(versionBox, ConvertUTF8ToWString(windowText).c_str());1265DarkModeInitDialog(hDlg);1266return TRUE;1267}12681269case WM_COMMAND:1270{1271if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) {1272EndDialog(hDlg, LOWORD(wParam));1273return TRUE;1274}1275break;1276return FALSE;1277}12781279default:1280return DarkModeDlgProc(hDlg, message, wParam, lParam);1281}1282return FALSE;1283}1284}128512861287