From 3aec770b221b6bd2a35ed8dd79535c39d0f93f6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 26 Oct 2026 11:36:32 +0100 Subject: [PATCH] Set Auto rotation to default, move more settings around. --- Common/System/System.h | 1 + Core/Config.cpp | 10 +-- UI/GameSettingsScreen.cpp | 41 +++++++----- UI/GameSettingsScreen.h | 13 ---- UI/Settings/GeneralPage.cpp | 113 ++++++++++++++++++++------------- UI/Settings/NetworkingPage.cpp | 63 ++++++++++++------ UI/Settings/SystemPage.cpp | 36 ++--------- 7 files changed, 145 insertions(+), 132 deletions(-) diff --git a/Common/System/System.h b/Common/System/System.h index ac22218c69..5bd9a4bb19 100644 --- a/Common/System/System.h +++ b/Common/System/System.h @@ -121,6 +121,7 @@ PermissionStatus System_GetPermissionStatus(SystemPermission permission); void System_AskForPermission(SystemPermission permission); // This will get muddy with multi-screen support :/ But this will always be the type of the main device. +// Actually we now have multi-screen and we consider the second screen a TV. Doesn't really change things. // These are the return values from System_GetPropertyInt(SYSPROP_DEVICE_TYPE). enum SystemDeviceType { DEVICE_TYPE_MOBILE = 0, // phones and pads diff --git a/Core/Config.cpp b/Core/Config.cpp index b87a6f3a37..9c24f73ee7 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -246,14 +246,6 @@ static int DefaultUIScaleFactor() { #endif } -static int DefaultScreenRotation() { -#if PPSSPP_PLATFORM(ANDROID) - return ROTATION_LOCKED_HORIZONTAL; -#else - return ROTATION_AUTO; -#endif -} - #if defined(__GNUC__) || defined(__clang__) // offsetof on classes with virtual functions (like ConfigBlock) is conditionally supported, and our compilers do support it. #pragma GCC diagnostic ignored "-Winvalid-offsetof" @@ -465,7 +457,7 @@ static constexpr ConfigSetting generalSettings[] = { .Label(I18NCat::SYSTEM, "Ask for exit confirmation after seconds").Range(0, 1200).Units("s").ZeroLabel("Off"), #if PPSSPP_PLATFORM(ANDROID) || PPSSPP_PLATFORM(IOS) - ConfigSetting("ScreenRotation", SETTING(g_Config, iScreenRotation), &DefaultScreenRotation, CfgFlag::DEFAULT), + ConfigSetting("ScreenRotation", SETTING(g_Config, iScreenRotation), ROTATION_AUTO, CfgFlag::DEFAULT), #endif ConfigSetting("BackgroundAnimation", SETTING(g_Config, iBackgroundAnimation), (int)BackgroundAnimation::WAVE, CfgFlag::DEFAULT) diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 3483442a60..73b54116b3 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -115,27 +115,36 @@ void GameSettingsScreen::PreCreateViews() { #endif } -const std::vector &GameSettingsScreen::PageDefs() { - static const std::vector pages = { - { "GameSettingsGeneral", "General", "I_SLIDERS", nullptr, I18NCat::SYSTEM, nullptr, &BuildGeneralSettings }, - { "GameSettingsGraphics", "Graphics", "I_DISPLAY", "graphics", I18NCat::GRAPHICS, &BuildGraphicsSettings }, - { "GameSettingsControls", "Controls", "I_CONTROLLER", "controls", I18NCat::CONTROLS, &BuildControlsSettings }, - { "GameSettingsAudio", "Audio", "I_SPEAKER_MAX", "audio", I18NCat::AUDIO, &BuildAudioSettings }, - { "GameSettingsNetworking", "Networking", "I_WIFI", "network", I18NCat::NETWORKING, &BuildNetworkingSettings }, - { "GameSettingsTools", "Tools", "I_TOOLS", "tools", I18NCat::MAINSETTINGS, &BuildToolsSettings }, - { "GameSettingsSystem", "System", "I_PSP", "system", I18NCat::SYSTEM, nullptr, &BuildSystemSettings }, - { "GameSettingsVR", "VR", nullptr, nullptr, I18NCat::VR, &BuildVRSettings }, - }; - return pages; -} +// One per tab. +struct PageDef { + const char *tag; + const char *title; // In MAINSETTINGS. + const char *icon; + const char *helpTag; // If null, there's no help button. + I18NCat cat; + // Null for the tabs that also take systemState_, given instead. + void (*build)(SettingsPage *page); + void (*buildWithState)(SettingsPage *page, SystemPageState *state); +}; + +static const PageDef pageDefs[] = { + { "GameSettingsGeneral", "General", "I_SLIDERS", nullptr, I18NCat::SYSTEM, nullptr, &BuildGeneralSettings }, + { "GameSettingsControls", "Controls", "I_CONTROLLER", "controls", I18NCat::CONTROLS, &BuildControlsSettings }, + { "GameSettingsGraphics", "Graphics", "I_DISPLAY", "graphics", I18NCat::GRAPHICS, &BuildGraphicsSettings }, + { "GameSettingsAudio", "Audio", "I_SPEAKER_MAX", "audio", I18NCat::AUDIO, &BuildAudioSettings }, + { "GameSettingsNetworking", "Networking", "I_WIFI", "network", I18NCat::NETWORKING, &BuildNetworkingSettings }, + { "GameSettingsTools", "Tools", "I_TOOLS", "tools", I18NCat::MAINSETTINGS, &BuildToolsSettings }, + { "GameSettingsSystem", "System", "I_PSP", "system", I18NCat::SYSTEM, nullptr, &BuildSystemSettings }, + { "GameSettingsVR", "VR", nullptr, nullptr, I18NCat::VR, &BuildVRSettings }, +}; void GameSettingsScreen::CreateTabs() { using namespace UI; - int deviceType = System_GetPropertyInt(SYSPROP_DEVICE_TYPE); - bool showVR = deviceType == DEVICE_TYPE_VR || g_Config.bForceVR; + const SystemDeviceType deviceType = (SystemDeviceType)System_GetPropertyInt(SYSPROP_DEVICE_TYPE); + const bool showVR = deviceType == DEVICE_TYPE_VR || g_Config.bForceVR; - for (const PageDef &def : PageDefs()) { + for (const PageDef &def : pageDefs) { if (def.build == &BuildVRSettings && !showVR) { continue; } diff --git a/UI/GameSettingsScreen.h b/UI/GameSettingsScreen.h index 8d7bb8df1f..856534090c 100644 --- a/UI/GameSettingsScreen.h +++ b/UI/GameSettingsScreen.h @@ -54,19 +54,6 @@ protected: private: void PreCreateViews() override; - // One per tab. - struct PageDef { - const char *tag; - const char *title; // In MAINSETTINGS. - const char *icon; - const char *helpTag; // If null, there's no help button. - I18NCat cat; - // Null for the tabs that also take systemState_, given instead. - void (*build)(SettingsPage *page); - void (*buildWithState)(SettingsPage *page, SystemPageState *state); - }; - static const std::vector &PageDefs(); - std::string gameID_; void RestartOrDo(std::function callback) override; diff --git a/UI/Settings/GeneralPage.cpp b/UI/Settings/GeneralPage.cpp index 31cef44ae4..9f548f13bf 100644 --- a/UI/Settings/GeneralPage.cpp +++ b/UI/Settings/GeneralPage.cpp @@ -39,6 +39,7 @@ #include "Core/Config.h" #include "Core/ConfigValues.h" #include "Core/HLE/sceUtility.h" +#include "Core/HLE/sceUsbCam.h" #include "Core/Reporting.h" #include "Core/System.h" #include "Core/Util/PathUtil.h" @@ -153,32 +154,6 @@ static void BuildUISettingsPage(SettingsPage *page) { using namespace UI; SettingsPageHost *host = page->Host(); -#if PPSSPP_PLATFORM(IOS) - static const char *indicator[] = { - "Swipe once to switch app (indicator auto-hides)", - "Swipe twice to switch app (indicator stays visible)" - }; - page->Setting(&g_Config.iAppSwitchMode); - - { - // Note: On iPhone, iOS hides the status bar in landscape no matter what this is set to. - DisplayLayoutConfig &config = g_Config.GetDisplayLayoutConfig(g_display.GetDeviceOrientation()); - page->Setting(&config.bImmersiveMode).OnChange([](EventParams &e) { - System_Notify(SystemNotification::IMMERSIVE_MODE_CHANGE); - }); - } -#endif - -#if PPSSPP_PLATFORM(ANDROID) - // Hide Immersive Mode on pre-kitkat Android - if (System_GetPropertyInt(SYSPROP_SYSTEMVERSION) >= 19) { - DisplayLayoutConfig &config = g_Config.GetDisplayLayoutConfig(g_display.GetDeviceOrientation()); - page->Setting(&config.bImmersiveMode).OnChange([](EventParams &e) { - OnImmersiveModeChange(); - }); - } -#endif - UIContext *ctx = host->PageScreenManager()->getUIContext(); page->Setting(&g_Config.iUIScaleFactor).OnChange([ctx](UI::EventParams &e) { const float dpiMul = UIScaleFactorToMultiplier(g_Config.iUIScaleFactor); @@ -238,9 +213,6 @@ void BuildGeneralSettings(SettingsPage *page, SystemPageState *state) { SettingsPageHost *host = page->Host(); - page->Header(); - page->Link({I18NCat::SYSTEM, "UI"}, I18NCat::SYSTEM, &BuildUISettingsPage); - page->Header(); page->Custom("Language", [host](UI::ViewGroup *parent) -> UI::View * { @@ -266,44 +238,97 @@ void BuildGeneralSettings(SettingsPage *page, SystemPageState *state) { return language; }); - page->Header({ I18NCat::MAINSETTINGS, "General" }); - - page->Setting(&g_Config.iAskForExitConfirmationAfterSeconds); + page->Header(); + page->Link({I18NCat::SYSTEM, "UI"}, I18NCat::SYSTEM, &BuildUISettingsPage); + page->Header(); if (System_GetPropertyBool(SYSPROP_CAN_RESTRICT_ORIENTATION)) { // Display rotation - page->Custom({ I18NCat::CONTROLS, "Screen Rotation" }, [host](UI::ViewGroup *parent) -> UI::View * { + page->Custom({I18NCat::CONTROLS, "Screen Rotation"}, [host](UI::ViewGroup *parent) -> UI::View * { AddRotationPicker(host->PageScreenManager(), parent, true); return parent->GetViewByIndex(parent->GetNumSubviews() - 1); }); } +#if PPSSPP_PLATFORM(IOS) + static const char *indicator[] = { + "Swipe once to switch app (indicator auto-hides)", + "Swipe twice to switch app (indicator stays visible)" + }; + page->Setting(&g_Config.iAppSwitchMode); + + { + // Note: On iPhone, iOS hides the status bar in landscape no matter what this is set to. + DisplayLayoutConfig &config = g_Config.GetDisplayLayoutConfig(g_display.GetDeviceOrientation()); + page->Setting(&config.bImmersiveMode).OnChange([](EventParams &e) { + System_Notify(SystemNotification::IMMERSIVE_MODE_CHANGE); + }); + } +#endif + +#if PPSSPP_PLATFORM(ANDROID) + // Hide Immersive Mode on pre-kitkat Android + if (System_GetPropertyInt(SYSPROP_SYSTEMVERSION) >= 19) { + DisplayLayoutConfig &config = g_Config.GetDisplayLayoutConfig(g_display.GetDeviceOrientation()); + page->Setting(&config.bImmersiveMode).OnChange([](EventParams &e) { + OnImmersiveModeChange(); + }); + } +#endif + page->Setting(&g_Config.iAskForExitConfirmationAfterSeconds); + // TODO: Make this setting available on Mac too. +#if PPSSPP_PLATFORM(WINDOWS) || (defined (SDL) && !defined(MOBILE_DEVICE)) + page->Setting(&g_Config.bPauseOnLostFocus); +#endif + if (System_GetPropertyBool(SYSPROP_HAS_KEYBOARD)) { + page->Setting(&g_Config.bBypassOSKWithKeyboard); + } + if (System_GetPropertyBool(SYSPROP_SUPPORTS_SUSTAINED_PERF_MODE)) { page->Setting(&g_Config.bSustainedPerformanceMode).OnChange([](UI::EventParams &e) { OnSustainedPerformanceModeChange(); }); } + page->Setting(&g_Config.bCheckForNewVersion); + + page->Header(); page->Choice("Restore Default Settings").OnClick([host, state](UI::EventParams &e) { OnRestoreDefaultSettings(host, state); }); - if (System_GetPropertyBool(SYSPROP_HAS_KEYBOARD)) - page->Setting(&g_Config.bBypassOSKWithKeyboard); + page->Header({I18NCat::SAVEDATA, "Save states"}); // Borrow this string from the savedata manager - if (System_GetPropertyBool(SYSPROP_ENOUGH_RAM_FOR_FULL_ISO)) { - page->Setting(&g_Config.bCacheFullIsoInRam).EnabledFunc([] { - return !PSP_IsInited(); - }); + page->Setting(&g_Config.bEnableStateUndo); + page->Setting(&g_Config.bConfirmLoadState); + + page->Setting(&g_Config.iSaveStateSlotCount); + + // NOTE: We will soon support more states, but we'll keep this niche feature limited to the first five. + page->Setting(&g_Config.iAutoLoadSaveState).Setup([](View *view) { + if (g_Config.iAutoLoadSaveState != 1) { + static_cast(view)->HideChoice(1); // Hide "Oldest Save" if not using that mode. It doesn't make sense. + } + }); + + page->Setting(&g_Config.iRewindSnapshotInterval); + + std::vector cameraList = Camera::getDeviceList(); + if (cameraList.size() >= 1) { + page->Header({I18NCat::GRAPHICS, "Camera"}); + page->Setting(&g_Config.sCameraDevice, std::move(cameraList)); +#if PPSSPP_PLATFORM(WINDOWS) && !PPSSPP_PLATFORM(UWP) + page->Setting(&g_Config.bCameraMirrorHorizontal); +#endif } - page->Setting(&g_Config.bCheckForNewVersion); + page->Header("Cheats"); + page->Setting(&g_Config.bEnableCheats); + page->Setting(&g_Config.bEnablePlugins); + + page->Header(); page->Setting(&g_Config.bScreenshotsAsPNG); page->Setting(&g_Config.iScreenshotMode); - // TODO: Make this setting available on Mac too. -#if PPSSPP_PLATFORM(WINDOWS) || (defined (SDL) && !defined(MOBILE_DEVICE)) - page->Setting(&g_Config.bPauseOnLostFocus); -#endif page->Header("Help the PPSSPP team"); page->Bool(&state->enableReports, "Enable Compatibility Server Reports").EnabledFunc([]() { diff --git a/UI/Settings/NetworkingPage.cpp b/UI/Settings/NetworkingPage.cpp index 0ce06862e8..7fc54f12d2 100644 --- a/UI/Settings/NetworkingPage.cpp +++ b/UI/Settings/NetworkingPage.cpp @@ -40,11 +40,24 @@ class MacAddressChooser : public UI::LinearLayout { public: MacAddressChooser(RequesterToken token, Path gamePath, std::string *value, std::string_view title, ScreenManager *screenManager, UI::LayoutParams *layoutParams = nullptr); + void Update() override { + UI::LinearLayout::Update(); + // Propagate rounding flags. TODO: Figure out a more general way. + if (macInput_) { + macInput_->SetRoundCorners((RoundCorners)((u32)roundCorners_ & (u32)RoundCorners::BottomLeft)); + } + if (randomize_) { + randomize_->SetRoundCorners((RoundCorners)((u32)roundCorners_ & (u32)RoundCorners::BottomRight)); + } + } +private: + UI::PopupTextInputChoice *macInput_ = nullptr; + UI::Choice *randomize_ = nullptr; }; MacAddressChooser::MacAddressChooser(RequesterToken token, Path gamePath, std::string *value, std::string_view title, ScreenManager *screenManager, UI::LayoutParams *layoutParams) : UI::LinearLayout(ORIENT_HORIZONTAL, layoutParams) { using namespace UI; - SetSpacing(5.0f); + SetSpacing(0.0f); if (!layoutParams) { layoutParams_->width = FILL_PARENT; layoutParams_->height = ITEM_HEIGHT; @@ -52,14 +65,16 @@ MacAddressChooser::MacAddressChooser(RequesterToken token, Path gamePath, std::s auto n = GetI18NCategory(I18NCat::NETWORKING); std::string initialValue = *value; - Add(new PopupTextInputChoice(token, value, title, g_Config.sMACAddress, 17, screenManager, new LinearLayoutParams(1.0f)))->OnChange.Add([=](UI::EventParams &e) { + macInput_ = Add(new PopupTextInputChoice(token, value, title, g_Config.sMACAddress, 17, screenManager, new LinearLayoutParams(1.0f))); + macInput_->OnChange.Add([=](UI::EventParams &e) { // Validate the chosen address, and restore to initialValue if bad. if (g_Config.sMACAddress.size() != 17) { // TODO: Alert the user *value = initialValue; } }); - Add(new Choice(n->T("Randomize"), new LinearLayoutParams(WRAP_CONTENT, ITEM_HEIGHT)))->OnClick.Add([=](UI::EventParams &) { + randomize_ = Add(new Choice(n->T("Randomize"), new LinearLayoutParams(WRAP_CONTENT, ITEM_HEIGHT))); + randomize_->OnClick.Add([=](UI::EventParams &) { auto n = GetI18NCategory(I18NCat::NETWORKING); auto di = GetI18NCategory(I18NCat::DIALOG); @@ -101,11 +116,33 @@ UI::View *AddNicknameChoice(SettingsPageHost *host, UI::ViewGroup *parent) { return nickname; } +static void BuildChatSettingsPage(SettingsPage *page) { + using namespace UI; + SettingsPageHost *host = page->Host(); + + page->Header("Chat"); + page->Setting(&g_Config.bEnableNetworkChat); + page->Setting(&g_Config.iChatButtonPosition).Enabled(&g_Config.bEnableNetworkChat); + page->Setting(&g_Config.iChatScreenPosition).Enabled(&g_Config.bEnableNetworkChat); + page->Setting(&g_Config.bChatTimestamps).Enabled(&g_Config.bEnableNetworkChat); + + page->Header("Quick chat"); + page->Setting(&g_Config.bEnableQuickChat).Enabled(&g_Config.bEnableNetworkChat); + + for (int i = 0; i < 5; i++) { + page->Custom("Quick chat %1", [host, i](UI::ViewGroup *parent) -> UI::View * { + return parent->Add(new PopupTextInputChoice(host->PageRequesterToken(), &g_Config.sQuickChat[i], ApplySafeSubstitutions(T(I18NCat::NETWORKING, "Quick chat %1"), i + 1), "", 32, host->PageScreenManager())); + }).EnabledFunc([] { + return g_Config.bEnableQuickChat && g_Config.bEnableNetworkChat; + }); + } +} + void BuildNetworkingSettings(SettingsPage *page) { using namespace UI; SettingsPageHost *host = page->Host(); - page->Header({ I18NCat::MAINSETTINGS, "Networking" }); + page->Header(); page->Choice("Quick start guide for multiplayer", ImageID("I_LINK_OUT")).OnClick([](EventParams &e) { auto n = GetI18NCategory(I18NCat::NETWORKING); @@ -227,22 +264,8 @@ void BuildNetworkingSettings(SettingsPage *page) { page->Setting(&g_Config.bUPnPUseOriginalPort).Enabled(&g_Config.bEnableUPnP); page->Hint({ I18NCat::NETWORKING, "UseOriginalPort Tip", "May not work for all devices or games, see wiki." }); - page->Header("Chat"); - page->Setting(&g_Config.bEnableNetworkChat); - page->Setting(&g_Config.iChatButtonPosition).Enabled(&g_Config.bEnableNetworkChat); - page->Setting(&g_Config.iChatScreenPosition).Enabled(&g_Config.bEnableNetworkChat); - page->Setting(&g_Config.bChatTimestamps).Enabled(&g_Config.bEnableNetworkChat); - - page->Header("Quick chat"); - page->Setting(&g_Config.bEnableQuickChat).Enabled(&g_Config.bEnableNetworkChat); - - for (int i = 0; i < 5; i++) { - page->Custom("Quick chat %1", [host, i](UI::ViewGroup *parent) -> UI::View * { - return parent->Add(new PopupTextInputChoice(host->PageRequesterToken(), &g_Config.sQuickChat[i], ApplySafeSubstitutions(T(I18NCat::NETWORKING, "Quick chat %1"), i + 1), "", 32, host->PageScreenManager())); - }).EnabledFunc([] { - return g_Config.bEnableQuickChat && g_Config.bEnableNetworkChat; - }); - } + page->Header(); + page->Link({I18NCat::NETWORKING, "Chat"}, I18NCat::NETWORKING, &BuildChatSettingsPage); page->Header({ I18NCat::NETWORKING, "Misc", "Misc (default = compatibility)" }); page->Choice("Open PPSSPP Multiplayer Wiki Page", ImageID("I_LINK_OUT")).OnClick([](EventParams &e) { diff --git a/UI/Settings/SystemPage.cpp b/UI/Settings/SystemPage.cpp index a4d789224a..d309e0b58a 100644 --- a/UI/Settings/SystemPage.cpp +++ b/UI/Settings/SystemPage.cpp @@ -40,7 +40,6 @@ #include "Common/UI/View.h" #include "Core/Config.h" #include "Core/ConfigValues.h" -#include "Core/HLE/sceUsbCam.h" #include "Core/HLE/sceUtility.h" #include "Core/Reporting.h" #include "Core/System.h" @@ -270,39 +269,16 @@ void BuildSystemSettings(SettingsPage *page, SystemPageState *state) { }); page->Setting(&g_Config.bIgnoreBadMemAccess); + if (System_GetPropertyBool(SYSPROP_ENOUGH_RAM_FOR_FULL_ISO)) { + page->Setting(&g_Config.bCacheFullIsoInRam).EnabledFunc([] { + return !PSP_IsInited(); + }); + } + page->Setting(&g_Config.iIOTimingMethod); page->Setting(&g_Config.bForceLagSync).Disabled(&g_Config.bAutoFrameSkip); page->Setting(&g_Config.iLockedCPUSpeed); - page->Header({ I18NCat::SAVEDATA, "Save states" }); // Borrow this string from the savedata manager - - page->Setting(&g_Config.bEnableStateUndo); - page->Setting(&g_Config.bConfirmLoadState); - - page->Setting(&g_Config.iSaveStateSlotCount); - - // NOTE: We will soon support more states, but we'll keep this niche feature limited to the first five. - page->Setting(&g_Config.iAutoLoadSaveState).Setup([](View *view) { - if (g_Config.iAutoLoadSaveState != 1) { - static_cast(view)->HideChoice(1); // Hide "Oldest Save" if not using that mode. It doesn't make sense. - } - }); - - page->Setting(&g_Config.iRewindSnapshotInterval); - - std::vector cameraList = Camera::getDeviceList(); - if (cameraList.size() >= 1) { - page->Header({ I18NCat::GRAPHICS, "Camera" }); - page->Setting(&g_Config.sCameraDevice, std::move(cameraList)); -#if PPSSPP_PLATFORM(WINDOWS) && !PPSSPP_PLATFORM(UWP) - page->Setting(&g_Config.bCameraMirrorHorizontal); -#endif - } - - page->Header("Cheats"); - page->Setting(&g_Config.bEnableCheats); - page->Setting(&g_Config.bEnablePlugins); - #if defined(_WIN32) page->Header("Recording"); page->Setting(&g_Config.bDumpFrames);