From ec831d2d6c41dde1bf8fd92a5621f524d3499b98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 19 Jan 2026 16:05:42 +0100 Subject: [PATCH 1/7] Fix some logic bugs in the java code --- .../src/org/ppsspp/ppsspp/InputDeviceState.java | 13 +++++++++---- android/src/org/ppsspp/ppsspp/PpssppActivity.java | 15 +++++++++++---- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/android/src/org/ppsspp/ppsspp/InputDeviceState.java b/android/src/org/ppsspp/ppsspp/InputDeviceState.java index 46277d13fa..f79be5a257 100644 --- a/android/src/org/ppsspp/ppsspp/InputDeviceState.java +++ b/android/src/org/ppsspp/ppsspp/InputDeviceState.java @@ -139,9 +139,11 @@ public class InputDeviceState { boolean repeat = event.getRepeatCount() > 0; if (isInvalidKeyCode(keyCode) && isEventSentByNintendoSwitchLeftJoyCon(event)) { - keyCode = remapNintendoSwitchLeftJoyConKeyCodeFromScanCode(event.getScanCode()); - // need to pass false for the repeat flag, otherwise pressing two adjacent dpad buttons simultaneously to move diagonally does not work. - return NativeApp.keyDown(deviceId, keyCode, false); + int remappedKeyCode = remapNintendoSwitchLeftJoyConKeyCodeFromScanCode(event.getScanCode()); + if (remappedKeyCode != 0) { + // need to pass false for the repeat flag, otherwise pressing two adjacent dpad buttons simultaneously to move diagonally does not work. + return NativeApp.keyDown(deviceId, remappedKeyCode, false); + } } return NativeApp.keyDown(deviceId, keyCode, repeat); @@ -152,7 +154,10 @@ public class InputDeviceState { int keyCode = event.getKeyCode(); if (isInvalidKeyCode(keyCode) && isEventSentByNintendoSwitchLeftJoyCon(event)) { - keyCode = remapNintendoSwitchLeftJoyConKeyCodeFromScanCode(event.getScanCode()); + int remappedKeyCode = remapNintendoSwitchLeftJoyConKeyCodeFromScanCode(event.getScanCode()); + if (remappedKeyCode != 0) { + return NativeApp.keyUp(deviceId, remappedKeyCode); + } } return NativeApp.keyUp(deviceId, keyCode); diff --git a/android/src/org/ppsspp/ppsspp/PpssppActivity.java b/android/src/org/ppsspp/ppsspp/PpssppActivity.java index 238282e146..75e90e6b32 100644 --- a/android/src/org/ppsspp/ppsspp/PpssppActivity.java +++ b/android/src/org/ppsspp/ppsspp/PpssppActivity.java @@ -301,14 +301,17 @@ public class PpssppActivity extends AppCompatActivity implements SensorEventList if (list == null) { Log.i(TAG, "getSdCardPaths: Attempting fallback"); // Try another method. - list = new ArrayList<>(); File[] fileList = new File("/storage/").listFiles(); if (fileList != null) { + list = new ArrayList<>(); for (File file : fileList) { if (!file.getAbsolutePath().equalsIgnoreCase(Environment.getExternalStorageDirectory().getAbsolutePath()) && file.isDirectory() && file.canRead()) { list.add(file.getAbsolutePath()); } } + if (list.isEmpty()) { + list = null; + } } } @@ -316,7 +319,7 @@ public class PpssppActivity extends AppCompatActivity implements SensorEventList String[] varNames = { "EXTERNAL_SDCARD_STORAGE", "SECONDARY_STORAGE" }; for (String var : varNames) { Log.i(TAG, "getSdCardPaths: Checking env " + var); - String secStore = System.getenv("SECONDARY_STORAGE"); + String secStore = System.getenv(var); if (secStore != null && !secStore.isEmpty()) { list = new ArrayList<>(); list.add(secStore); @@ -518,9 +521,13 @@ public class PpssppActivity extends AppCompatActivity implements SensorEventList } } - mLocationHelper = new LocationHelper(this); + if (mLocationHelper == null) { + mLocationHelper = new LocationHelper(this); + } try { - mInfraredHelper = new InfraredHelper(this); + if (mInfraredHelper == null) { + mInfraredHelper = new InfraredHelper(this); + } } catch (Exception e) { mInfraredHelper = null; Log.i(TAG, "InfraredHelper exception: " + e); From c13060363f66f9b0c5de6886c20404b10267e225 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 19 Jan 2026 17:00:15 +0100 Subject: [PATCH 2/7] More minor Android cleanup/fixes --- android/src/org/ppsspp/ppsspp/ContentUri.java | 2 +- .../src/org/ppsspp/ppsspp/PpssppActivity.java | 8 ++-- .../org/ppsspp/ppsspp/ShortcutActivity.java | 48 +++++++------------ .../org/ppsspp/ppsspp/SimpleFileChooser.java | 6 +++ 4 files changed, 29 insertions(+), 35 deletions(-) diff --git a/android/src/org/ppsspp/ppsspp/ContentUri.java b/android/src/org/ppsspp/ppsspp/ContentUri.java index b25093def9..69c8ae9cab 100644 --- a/android/src/org/ppsspp/ppsspp/ContentUri.java +++ b/android/src/org/ppsspp/ppsspp/ContentUri.java @@ -128,8 +128,8 @@ public class ContentUri { } } c.close(); + c = null; } - c = null; for (Uri childUri : childDirs) { long dirSize = directorySizeRecursion(activity, childUri); diff --git a/android/src/org/ppsspp/ppsspp/PpssppActivity.java b/android/src/org/ppsspp/ppsspp/PpssppActivity.java index 75e90e6b32..a9898e065a 100644 --- a/android/src/org/ppsspp/ppsspp/PpssppActivity.java +++ b/android/src/org/ppsspp/ppsspp/PpssppActivity.java @@ -1096,14 +1096,14 @@ public class PpssppActivity extends AppCompatActivity implements SensorEventList } protected String getInputDeviceDebugString() { - String buffer = ""; + StringBuilder buffer = new StringBuilder(); for (InputDeviceState input : inputPlayers) { - buffer += input.getDebugString(); + buffer.append(input.getDebugString()); } - if (buffer.isEmpty()) { + if (buffer.length() == 0) { return "(no devices)"; } - return buffer; + return buffer.toString(); } // We grab the keys before onKeyDown/... even see them. This is also better because it lets us diff --git a/android/src/org/ppsspp/ppsspp/ShortcutActivity.java b/android/src/org/ppsspp/ppsspp/ShortcutActivity.java index 65f00cc34a..3a6eabd5c1 100644 --- a/android/src/org/ppsspp/ppsspp/ShortcutActivity.java +++ b/android/src/org/ppsspp/ppsspp/ShortcutActivity.java @@ -14,6 +14,7 @@ import android.os.Environment; import android.util.Log; import androidx.annotation.NonNull; +import androidx.documentfile.provider.DocumentFile; import java.io.File; @@ -30,6 +31,9 @@ public class ShortcutActivity extends Activity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + // Ensure library is loaded before any native methods are called. + PpssppActivity.CheckABIAndLoadLibrary(); + // Show file selector dialog here. If Android version is more than or equal to 11, // use the native document file browser instead of our SimpleFileChooser. boolean scoped = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R); @@ -85,39 +89,19 @@ public class ShortcutActivity extends Activity { shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); Log.i(TAG, "Shortcut URI: " + uri); shortcutIntent.setData(uri); - String path = uri.toString(); - shortcutIntent.putExtra(PpssppActivity.SHORTCUT_EXTRA_KEY, path); + shortcutIntent.putExtra(PpssppActivity.SHORTCUT_EXTRA_KEY, uri.toString()); - // We can't call C++ functions here that use storage APIs since there's no - // NativeActivity and all the AndroidStorage methods are methods on that. - // Should probably change that. In the meantime, let's just process the URI to make - // up a name. - - String pathStr = "PPSSPP Game"; - if (path.startsWith("content://")) { - String [] segments = path.split("/"); - try { - pathStr = java.net.URLDecoder.decode(segments[segments.length - 1], "UTF-8"); - } catch (Exception e) { - Log.i(TAG, "Exception getting name: " + e); - } - } else if (path.startsWith("file:///")) { - try { - pathStr = java.net.URLDecoder.decode(path.substring(7), "UTF-8"); - } catch (Exception e) { - Log.i(TAG, "Exception getting name: " + e); - } - } else { - pathStr = path; + String name = "PPSSPP Game"; + DocumentFile docFile = DocumentFile.fromSingleUri(this, uri); + if (docFile != null && docFile.getName() != null) { + name = docFile.getName(); } - String[] pathSegments = pathStr.split("/"); - String name = pathSegments[pathSegments.length - 1]; - - PpssppActivity.CheckABIAndLoadLibrary(); String gameName = name; + Log.i(TAG, "Fallback name from URI: " + name); + byte[] iconData; - Object[] result = queryGameInfo(this, path); + Object[] result = queryGameInfo(this, uri.toString()); if (result != null && result.length >= 2) { if (result[0] != null) { gameName = (String) result[0]; // index 0 = name @@ -129,13 +113,13 @@ public class ShortcutActivity extends Activity { Log.e(TAG, "Bad return value from queryGameInfo"); } - Log.i(TAG, "Game name: " + name + " : Creating shortcut to " + uri); + Log.i(TAG, "Game name: " + gameName + " : Creating shortcut to " + uri); // This is Intent that will be returned by this method, as response to // ACTION_CREATE_SHORTCUT. Wrap shortcut intent inside this intent. Intent responseIntent = new Intent(); responseIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent); - responseIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, name); + responseIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, gameName); if (iconData != null) { try { @@ -156,9 +140,11 @@ public class ShortcutActivity extends Activity { canvas.drawBitmap(bmp, 0, y, new Paint(Paint.FILTER_BITMAP_FLAG)); // Bitmap scaledBitmap = Bitmap.createScaledBitmap(bmp, 144, 72, true); responseIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON, paddedBitmap); + bmp.recycle(); } } catch (Exception e) { NativeApp.reportException(e, "Error assigning generated icon"); + Log.e(TAG, "Error assigning generated icon: " + e); } } else { Log.i(TAG, "No icon available, falling back to PPSSPP icon"); @@ -168,6 +154,7 @@ public class ShortcutActivity extends Activity { responseIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconResource); } catch (Exception e) { NativeApp.reportException(e, "Error assigning default icon"); + Log.e(TAG, "Error assigning default icon: " + e); } } @@ -175,6 +162,7 @@ public class ShortcutActivity extends Activity { // Must call finish for result to be returned immediately finish(); + Log.i(TAG, "End of respondToShortcutRequest"); } // Event when a file is selected on file dialog. diff --git a/android/src/org/ppsspp/ppsspp/SimpleFileChooser.java b/android/src/org/ppsspp/ppsspp/SimpleFileChooser.java index 9f4b4a358a..3610ae76b3 100644 --- a/android/src/org/ppsspp/ppsspp/SimpleFileChooser.java +++ b/android/src/org/ppsspp/ppsspp/SimpleFileChooser.java @@ -4,6 +4,8 @@ import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import android.os.Environment; +import android.widget.Toast; + import java.io.File; import java.util.ArrayList; import java.util.Arrays; @@ -54,7 +56,11 @@ public class SimpleFileChooser { for (File file : fileList) { r.add(file.getName()); } + } else { + // BUG FIX: Notify user if directory is inaccessible + Toast.makeText(mActivity, "Cannot read directory", Toast.LENGTH_SHORT).show(); } + // Strange syntax but correct. mFileList = r.toArray(new String[0]); } From 8b8c776491d3e50ce9b8d9954a54b8b6da31a85c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 19 Jan 2026 17:00:27 +0100 Subject: [PATCH 3/7] Fix visual issue with rotation button on the pause screen --- Common/Data/Text/I18n.cpp | 9 +++++++-- Common/UI/PopupScreens.cpp | 2 +- Common/UI/View.h | 4 ++++ UI/MiscViews.cpp | 3 +++ UI/PauseScreen.cpp | 2 +- 5 files changed, 16 insertions(+), 4 deletions(-) diff --git a/Common/Data/Text/I18n.cpp b/Common/Data/Text/I18n.cpp index 9df7729605..c909ad3af7 100644 --- a/Common/Data/Text/I18n.cpp +++ b/Common/Data/Text/I18n.cpp @@ -82,7 +82,10 @@ std::string_view I18NCategory::T(std::string_view key, std::string_view def) { // Too early. This is probably in desktop-ui translation. return !def.empty() ? def : key; } - INFO_LOG(Log::UI, "Missing translation [%s] %.*s (%.*s)", name_.c_str(), STR_VIEW(key), STR_VIEW(def)); + if (key != "Font") { + // Font is allowed to be missing. + INFO_LOG(Log::UI, "Missing translation [%s] %.*s (%.*s)", name_.c_str(), STR_VIEW(key), STR_VIEW(def)); + } std::lock_guard guard(missedKeyLock_); std::string missedKey(key); @@ -103,7 +106,9 @@ const char *I18NCategory::T_cstr(const char *key, const char *def) { // Too early. This is probably in desktop-ui translation. return def ? def : key; } - INFO_LOG(Log::UI, "Missing translation %s (%s)", key, def); + if (key != "Font") { + INFO_LOG(Log::UI, "Missing translation %s (%s)", key, def); + } std::lock_guard guard(missedKeyLock_); std::string missedKey(key); diff --git a/Common/UI/PopupScreens.cpp b/Common/UI/PopupScreens.cpp index fdce86a4bc..8ff5051661 100644 --- a/Common/UI/PopupScreens.cpp +++ b/Common/UI/PopupScreens.cpp @@ -882,7 +882,7 @@ void AbstractChoiceWithValueDisplay::Draw(UIContext &dc) { } else { Choice::Draw(dc); - if (text_.empty() && valueText.empty() && !image_.isValid()) { + if (iconOnly_) { // In this case we only display the image of the choice. Useful for small buttons spawning a popup. dc.Draw()->DrawImageRotated(ValueImage(), bounds_.centerX(), bounds_.centerY(), imgScale_, imgRot_, style.fgColor, imgFlipH_); return; diff --git a/Common/UI/View.h b/Common/UI/View.h index 39108d6db4..92b0717e36 100644 --- a/Common/UI/View.h +++ b/Common/UI/View.h @@ -748,6 +748,9 @@ public: void SetText(std::string_view text) { text_ = text; } + void SetIconOnly(bool iconOnly) { + iconOnly_ = iconOnly; + } protected: void ClickInternal() override; @@ -770,6 +773,7 @@ protected: u32 drawTextFlags_ = 0; bool hideTitle_ = false; float shine_ = false; + bool iconOnly_ = false; private: bool selected_ = false; diff --git a/UI/MiscViews.cpp b/UI/MiscViews.cpp index 42273de999..0afdfca848 100644 --- a/UI/MiscViews.cpp +++ b/UI/MiscViews.cpp @@ -241,7 +241,10 @@ void AddRotationPicker(ScreenManager *screenManager, UI::ViewGroup *parent, bool auto co = GetI18NCategory(I18NCat::CONTROLS); PopupMultiChoice *rot = parent->Add(new PopupMultiChoice(&g_Config.iScreenRotation, text ? co->T("Screen Rotation") : "", screenRotation, 0, ARRAY_SIZE(screenRotation), I18NCat::CONTROLS, screenManager, text ? nullptr : new LinearLayoutParams(ITEM_HEIGHT, ITEM_HEIGHT))); + rot->SetHideTitle(true); + rot->SetIconOnly(true); rot->SetChoiceIcons(screenRotationIcons); + // Portrait Reversed is not recommended on iPhone (and we also ban it in the plist). // However it's recommended to support it on iPad, so maybe we will in the future. rot->HideChoice(4); diff --git a/UI/PauseScreen.cpp b/UI/PauseScreen.cpp index c8531ac3c6..82c68a1edf 100644 --- a/UI/PauseScreen.cpp +++ b/UI/PauseScreen.cpp @@ -683,7 +683,7 @@ void GamePauseScreen::CreateViews() { screenManager()->push(new GameScreen(gamePath_, true)); }); - if (System_GetPropertyInt(SYSPROP_DEVICE_TYPE) == DEVICE_TYPE_MOBILE) { + if (true || System_GetPropertyInt(SYSPROP_DEVICE_TYPE) == DEVICE_TYPE_MOBILE) { AddRotationPicker(screenManager(), middleColumn, false); } From 1d2f846c66c3d8ebb4620a730f8f218e224aff69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 19 Jan 2026 17:14:24 +0100 Subject: [PATCH 4/7] Partial drive-by cleanup of quick chat code --- Core/Config.cpp | 10 ++--- Core/Config.h | 6 +-- Core/HLE/proAdhoc.cpp | 1 + UI/ChatScreen.cpp | 31 +++------------- UI/ChatScreen.h | 5 --- UI/GameSettingsScreen.cpp | 78 ++++++++++++++++++--------------------- UI/GameSettingsScreen.h | 3 -- 7 files changed, 49 insertions(+), 85 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index 689d88ab74..94bce54019 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -1029,11 +1029,11 @@ static const ConfigSetting networkSettings[] = { ConfigSetting("ChatButtonPosition", SETTING(g_Config, iChatButtonPosition), (int)ScreenEdgePosition::BOTTOM_LEFT, CfgFlag::PER_GAME), ConfigSetting("ChatScreenPosition", SETTING(g_Config, iChatScreenPosition), (int)ScreenEdgePosition::BOTTOM_LEFT, CfgFlag::PER_GAME), ConfigSetting("EnableQuickChat", SETTING(g_Config, bEnableQuickChat), true, CfgFlag::PER_GAME), - ConfigSetting("QuickChat1", SETTING(g_Config, sQuickChat0), "Quick Chat 1", CfgFlag::PER_GAME), - ConfigSetting("QuickChat2", SETTING(g_Config, sQuickChat1), "Quick Chat 2", CfgFlag::PER_GAME), - ConfigSetting("QuickChat3", SETTING(g_Config, sQuickChat2), "Quick Chat 3", CfgFlag::PER_GAME), - ConfigSetting("QuickChat4", SETTING(g_Config, sQuickChat3), "Quick Chat 4", CfgFlag::PER_GAME), - ConfigSetting("QuickChat5", SETTING(g_Config, sQuickChat4), "Quick Chat 5", CfgFlag::PER_GAME), + ConfigSetting("QuickChat1", SETTING(g_Config, sQuickChat[0]), "Quick Chat 1", CfgFlag::PER_GAME), + ConfigSetting("QuickChat2", SETTING(g_Config, sQuickChat[1]), "Quick Chat 2", CfgFlag::PER_GAME), + ConfigSetting("QuickChat3", SETTING(g_Config, sQuickChat[2]), "Quick Chat 3", CfgFlag::PER_GAME), + ConfigSetting("QuickChat4", SETTING(g_Config, sQuickChat[3]), "Quick Chat 4", CfgFlag::PER_GAME), + ConfigSetting("QuickChat5", SETTING(g_Config, sQuickChat[4]), "Quick Chat 5", CfgFlag::PER_GAME), }; static const ConfigSetting systemParamSettings[] = { diff --git a/Core/Config.h b/Core/Config.h index eed525f59a..5bc654ae02 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -561,11 +561,7 @@ public: int iChatScreenPosition; bool bEnableQuickChat; - std::string sQuickChat0; - std::string sQuickChat1; - std::string sQuickChat2; - std::string sQuickChat3; - std::string sQuickChat4; + std::string sQuickChat[5]; int iPSPModel; int iFirmwareVersion; diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index b9d2f4e17b..38d10b4b0e 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -1305,6 +1305,7 @@ void sendChat(const std::string &chatString) { std::lock_guard guard(chatLogLock); auto n = GetI18NCategory(I18NCat::NETWORKING); chatLog.push_back(std::string(n->T("You're in Offline Mode, go to lobby or online hall"))); + INFO_LOG(Log::sceNet, "Offline. Would have sent: %s", chatString.c_str()); chatMessageGeneration++; } } diff --git a/UI/ChatScreen.cpp b/UI/ChatScreen.cpp index 0a9b0f7cf9..7a54038305 100644 --- a/UI/ChatScreen.cpp +++ b/UI/ChatScreen.cpp @@ -40,11 +40,12 @@ void ChatMenu::CreateContents(UI::ViewGroup *parent) { if (g_Config.bEnableQuickChat) { LinearLayout *quickChat = outer->Add(new LinearLayout(ORIENT_HORIZONTAL, new LayoutParams(FILL_PARENT, WRAP_CONTENT))); - quickChat->Add(new Button("1", new LinearLayoutParams(1.0)))->OnClick.Handle(this, &ChatMenu::OnQuickChat1); - quickChat->Add(new Button("2", new LinearLayoutParams(1.0)))->OnClick.Handle(this, &ChatMenu::OnQuickChat2); - quickChat->Add(new Button("3", new LinearLayoutParams(1.0)))->OnClick.Handle(this, &ChatMenu::OnQuickChat3); - quickChat->Add(new Button("4", new LinearLayoutParams(1.0)))->OnClick.Handle(this, &ChatMenu::OnQuickChat4); - quickChat->Add(new Button("5", new LinearLayoutParams(1.0)))->OnClick.Handle(this, &ChatMenu::OnQuickChat5); + for (int i = 0; i < 5; i++) { + std::string name = std::to_string(i + 1); + quickChat->Add(new Button(name, new LinearLayoutParams(1.0)))->OnClick.Add([this, i](UI::EventParams &e) { + sendChat(g_Config.sQuickChat[i]); + }); + } } chatVert_ = scroll_->Add(new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT))); chatVert_->SetSpacing(0); @@ -127,26 +128,6 @@ void ChatMenu::OnAskForChatMessage(UI::EventParams &e) { } } -void ChatMenu::OnQuickChat1(UI::EventParams &e) { - sendChat(g_Config.sQuickChat0); -} - -void ChatMenu::OnQuickChat2(UI::EventParams &e) { - sendChat(g_Config.sQuickChat1); -} - -void ChatMenu::OnQuickChat3(UI::EventParams &e) { - sendChat(g_Config.sQuickChat2); -} - -void ChatMenu::OnQuickChat4(UI::EventParams &e) { - sendChat(g_Config.sQuickChat3); -} - -void ChatMenu::OnQuickChat5(UI::EventParams &e) { - sendChat(g_Config.sQuickChat4); -} - void ChatMenu::UpdateChat() { using namespace UI; if (chatVert_ != nullptr) { diff --git a/UI/ChatScreen.h b/UI/ChatScreen.h index 7935fc2ff5..7cddbe9098 100644 --- a/UI/ChatScreen.h +++ b/UI/ChatScreen.h @@ -28,11 +28,6 @@ private: void OnAskForChatMessage(UI::EventParams &e); void OnSubmitMessage(UI::EventParams &e); - void OnQuickChat1(UI::EventParams &e); - void OnQuickChat2(UI::EventParams &e); - void OnQuickChat3(UI::EventParams &e); - void OnQuickChat4(UI::EventParams &e); - void OnQuickChat5(UI::EventParams &e); UI::TextEdit *chatEdit_ = nullptr; UI::ScrollView *scroll_ = nullptr; diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 094f7b9fe5..927fa1a543 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -468,7 +468,9 @@ void GameSettingsScreen::CreateGraphicsSettings(UI::ViewGroup *graphicsSettings) static const char *frameSkip[] = {"Off", "1", "2", "3", "4", "5", "6", "7", "8"}; graphicsSettings->Add(new PopupMultiChoice(&g_Config.iFrameSkip, gr->T("Frame Skipping"), frameSkip, 0, ARRAY_SIZE(frameSkip), I18NCat::GRAPHICS, screenManager())); frameSkipAuto_ = graphicsSettings->Add(new CheckBox(&g_Config.bAutoFrameSkip, gr->T("Auto FrameSkip"))); - frameSkipAuto_->OnClick.Handle(this, &GameSettingsScreen::OnAutoFrameskip); + frameSkipAuto_->OnClick.Add([](UI::EventParams &e) { + g_Config.UpdateAfterSettingAutoFrameSkip(); + }); PopupSliderChoice *altSpeed1 = graphicsSettings->Add(new PopupSliderChoice(&iAlternateSpeedPercent1_, 0, 1000, UI::NO_DEFAULT_INT, gr->T("Alternative Speed", "Alternative speed"), 5, screenManager(), gr->T("%, 0:unlimited"))); altSpeed1->SetFormat("%i%%"); @@ -564,7 +566,18 @@ void GameSettingsScreen::CreateGraphicsSettings(UI::ViewGroup *graphicsSettings) if (GetGPUBackend() == GPUBackend::VULKAN) { ChoiceWithValueDisplay *textureShaderChoice = graphicsSettings->Add(new ChoiceWithValueDisplay(&g_Config.sTextureShaderName, gr->T("GPU texture upscaler (fast)"), &TextureTranslateName)); - textureShaderChoice->OnClick.Handle(this, &GameSettingsScreen::OnTextureShader); + textureShaderChoice->OnClick.Add([this](UI::EventParams &e) { + auto gr = GetI18NCategory(I18NCat::GRAPHICS); + auto shaderScreen = new TextureShaderScreen(gr->T("GPU texture upscaler (fast)")); + shaderScreen->OnChoice.Add([this](UI::EventParams &e) { + System_PostUIMessage(UIMessage::GPU_CONFIG_CHANGED); + RecreateViews(); // Update setting name + g_Config.bTexHardwareScaling = g_Config.sTextureShaderName != "Off"; + }); + if (e.v) + shaderScreen->SetPopupOrigin(e.v); + screenManager()->push(shaderScreen); + }); textureShaderChoice->SetDisabledPtr(&g_Config.bSoftwareRendering); } @@ -1054,23 +1067,23 @@ void GameSettingsScreen::CreateNetworkingSettings(UI::ViewGroup *networkingSetti #endif #if !defined(MOBILE_DEVICE) && !defined(USING_QT_UI) // TODO: Add all platforms where KeyInputFlags::CHAR support is added - PopupTextInputChoice *qc1 = networkingSettings->Add(new PopupTextInputChoice(GetRequesterToken(), &g_Config.sQuickChat0, n->T("Quick Chat 1"), "", 32, screenManager())); - PopupTextInputChoice *qc2 = networkingSettings->Add(new PopupTextInputChoice(GetRequesterToken(), &g_Config.sQuickChat1, n->T("Quick Chat 2"), "", 32, screenManager())); - PopupTextInputChoice *qc3 = networkingSettings->Add(new PopupTextInputChoice(GetRequesterToken(), &g_Config.sQuickChat2, n->T("Quick Chat 3"), "", 32, screenManager())); - PopupTextInputChoice *qc4 = networkingSettings->Add(new PopupTextInputChoice(GetRequesterToken(), &g_Config.sQuickChat3, n->T("Quick Chat 4"), "", 32, screenManager())); - PopupTextInputChoice *qc5 = networkingSettings->Add(new PopupTextInputChoice(GetRequesterToken(), &g_Config.sQuickChat4, n->T("Quick Chat 5"), "", 32, screenManager())); + PopupTextInputChoice *qc1 = networkingSettings->Add(new PopupTextInputChoice(GetRequesterToken(), &g_Config.sQuickChat[0], n->T("Quick Chat 1"), "", 32, screenManager())); + PopupTextInputChoice *qc2 = networkingSettings->Add(new PopupTextInputChoice(GetRequesterToken(), &g_Config.sQuickChat[1], n->T("Quick Chat 2"), "", 32, screenManager())); + PopupTextInputChoice *qc3 = networkingSettings->Add(new PopupTextInputChoice(GetRequesterToken(), &g_Config.sQuickChat[2], n->T("Quick Chat 3"), "", 32, screenManager())); + PopupTextInputChoice *qc4 = networkingSettings->Add(new PopupTextInputChoice(GetRequesterToken(), &g_Config.sQuickChat[3], n->T("Quick Chat 4"), "", 32, screenManager())); + PopupTextInputChoice *qc5 = networkingSettings->Add(new PopupTextInputChoice(GetRequesterToken(), &g_Config.sQuickChat[4], n->T("Quick Chat 5"), "", 32, screenManager())); #elif defined(USING_QT_UI) - Choice *qc1 = networkingSettings->Add(new Choice(n->T("Quick Chat 1"))); +] Choice *qc1 = networkingSettings->Add(new Choice(n->T("Quick Chat 1"))); Choice *qc2 = networkingSettings->Add(new Choice(n->T("Quick Chat 2"))); Choice *qc3 = networkingSettings->Add(new Choice(n->T("Quick Chat 3"))); Choice *qc4 = networkingSettings->Add(new Choice(n->T("Quick Chat 4"))); Choice *qc5 = networkingSettings->Add(new Choice(n->T("Quick Chat 5"))); #elif PPSSPP_PLATFORM(ANDROID) - ChoiceWithValueDisplay *qc1 = networkingSettings->Add(new ChoiceWithValueDisplay(&g_Config.sQuickChat0, n->T("Quick Chat 1"), I18NCat::NONE)); - ChoiceWithValueDisplay *qc2 = networkingSettings->Add(new ChoiceWithValueDisplay(&g_Config.sQuickChat1, n->T("Quick Chat 2"), I18NCat::NONE)); - ChoiceWithValueDisplay *qc3 = networkingSettings->Add(new ChoiceWithValueDisplay(&g_Config.sQuickChat2, n->T("Quick Chat 3"), I18NCat::NONE)); - ChoiceWithValueDisplay *qc4 = networkingSettings->Add(new ChoiceWithValueDisplay(&g_Config.sQuickChat3, n->T("Quick Chat 4"), I18NCat::NONE)); - ChoiceWithValueDisplay *qc5 = networkingSettings->Add(new ChoiceWithValueDisplay(&g_Config.sQuickChat4, n->T("Quick Chat 5"), I18NCat::NONE)); + ChoiceWithValueDisplay *qc1 = networkingSettings->Add(new ChoiceWithValueDisplay(&g_Config.sQuickChat[0], n->T("Quick Chat 1"), I18NCat::NONE)); + ChoiceWithValueDisplay *qc2 = networkingSettings->Add(new ChoiceWithValueDisplay(&g_Config.sQuickChat[1], n->T("Quick Chat 2"), I18NCat::NONE)); + ChoiceWithValueDisplay *qc3 = networkingSettings->Add(new ChoiceWithValueDisplay(&g_Config.sQuickChat[2], n->T("Quick Chat 3"), I18NCat::NONE)); + ChoiceWithValueDisplay *qc4 = networkingSettings->Add(new ChoiceWithValueDisplay(&g_Config.sQuickChat[3], n->T("Quick Chat 4"), I18NCat::NONE)); + ChoiceWithValueDisplay *qc5 = networkingSettings->Add(new ChoiceWithValueDisplay(&g_Config.sQuickChat[4], n->T("Quick Chat 5"), I18NCat::NONE)); #endif #if (!defined(MOBILE_DEVICE) && !defined(USING_QT_UI)) || defined(USING_QT_UI) || PPSSPP_PLATFORM(ANDROID) @@ -1472,10 +1485,6 @@ void GameSettingsScreen::CreateVRSettings(UI::ViewGroup *vrSettings) { vrSettings->Add(new CheckBox(&g_Config.bManualForceVR, vr->T("Manual switching between flat screen and VR using SCREEN key"))); } -void GameSettingsScreen::OnAutoFrameskip(UI::EventParams &e) { - g_Config.UpdateAfterSettingAutoFrameSkip(); -} - void GameSettingsScreen::OnAdhocGuides(UI::EventParams &e) { auto n = GetI18NCategory(I18NCat::NETWORKING); std::string url(n->T("MultiplayerHowToURL", "https://github.com/hrydgard/ppsspp/wiki/How-to-play-multiplayer-games-with-PPSSPP")); @@ -1752,54 +1761,39 @@ void GameSettingsScreen::OnAudioDevice(UI::EventParams &e) { void GameSettingsScreen::OnChangeQuickChat0(UI::EventParams &e) { auto n = GetI18NCategory(I18NCat::NETWORKING); - System_InputBoxGetString(GetRequesterToken(), n->T("Enter Quick Chat 1"), g_Config.sQuickChat0, false, [](const std::string &value, int) { - g_Config.sQuickChat0 = value; + System_InputBoxGetString(GetRequesterToken(), n->T("Enter Quick Chat 1"), g_Config.sQuickChat[0], false, [](const std::string &value, int) { + g_Config.sQuickChat[0] = value; }); } void GameSettingsScreen::OnChangeQuickChat1(UI::EventParams &e) { auto n = GetI18NCategory(I18NCat::NETWORKING); - System_InputBoxGetString(GetRequesterToken(), n->T("Enter Quick Chat 2"), g_Config.sQuickChat1, false, [](const std::string &value, int) { - g_Config.sQuickChat1 = value; + System_InputBoxGetString(GetRequesterToken(), n->T("Enter Quick Chat 2"), g_Config.sQuickChat[1], false, [](const std::string &value, int) { + g_Config.sQuickChat[1] = value; }); } void GameSettingsScreen::OnChangeQuickChat2(UI::EventParams &e) { auto n = GetI18NCategory(I18NCat::NETWORKING); - System_InputBoxGetString(GetRequesterToken(), n->T("Enter Quick Chat 3"), g_Config.sQuickChat2, false, [](const std::string &value, int) { - g_Config.sQuickChat2 = value; + System_InputBoxGetString(GetRequesterToken(), n->T("Enter Quick Chat 3"), g_Config.sQuickChat[2], false, [](const std::string &value, int) { + g_Config.sQuickChat[2] = value; }); } void GameSettingsScreen::OnChangeQuickChat3(UI::EventParams &e) { auto n = GetI18NCategory(I18NCat::NETWORKING); - System_InputBoxGetString(GetRequesterToken(), n->T("Enter Quick Chat 4"), g_Config.sQuickChat3, false, [](const std::string &value, int) { - g_Config.sQuickChat3 = value; + System_InputBoxGetString(GetRequesterToken(), n->T("Enter Quick Chat 4"), g_Config.sQuickChat[3], false, [](const std::string &value, int) { + g_Config.sQuickChat[3] = value; }); } void GameSettingsScreen::OnChangeQuickChat4(UI::EventParams &e) { auto n = GetI18NCategory(I18NCat::NETWORKING); - System_InputBoxGetString(GetRequesterToken(), n->T("Enter Quick Chat 5"), g_Config.sQuickChat4, false, [](const std::string &value, int) { - g_Config.sQuickChat4 = value; + System_InputBoxGetString(GetRequesterToken(), n->T("Enter Quick Chat 5"), g_Config.sQuickChat[4], false, [](const std::string &value, int) { + g_Config.sQuickChat[4] = value; }); } -void GameSettingsScreen::OnTextureShader(UI::EventParams &e) { - auto gr = GetI18NCategory(I18NCat::GRAPHICS); - auto shaderScreen = new TextureShaderScreen(gr->T("GPU texture upscaler (fast)")); - shaderScreen->OnChoice.Handle(this, &GameSettingsScreen::OnTextureShaderChange); - if (e.v) - shaderScreen->SetPopupOrigin(e.v); - screenManager()->push(shaderScreen); -} - -void GameSettingsScreen::OnTextureShaderChange(UI::EventParams &e) { - System_PostUIMessage(UIMessage::GPU_CONFIG_CHANGED); - RecreateViews(); // Update setting name - g_Config.bTexHardwareScaling = g_Config.sTextureShaderName != "Off"; -} - void GameSettingsScreen::CallbackRestoreDefaults(bool yes) { if (yes) { g_Config.RestoreDefaults(RestoreSettingsBits::SETTINGS); diff --git a/UI/GameSettingsScreen.h b/UI/GameSettingsScreen.h index 458bd1244d..6421bfb9d5 100644 --- a/UI/GameSettingsScreen.h +++ b/UI/GameSettingsScreen.h @@ -76,9 +76,6 @@ private: std::string memstickDisplay_; // Global settings handlers - void OnAutoFrameskip(UI::EventParams &e); - void OnTextureShader(UI::EventParams &e); - void OnTextureShaderChange(UI::EventParams &e); void OnChangeQuickChat0(UI::EventParams &e); void OnChangeQuickChat1(UI::EventParams &e); void OnChangeQuickChat2(UI::EventParams &e); From 1363cb22826a1955e7602cfc73639339632f4103 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 19 Jan 2026 17:19:02 +0100 Subject: [PATCH 5/7] Remove a bunch of member variables from GameSettingsScreen --- UI/GameSettingsScreen.cpp | 46 +++++++++++++++++---------------------- UI/GameSettingsScreen.h | 6 ----- 2 files changed, 20 insertions(+), 32 deletions(-) diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 927fa1a543..31e2e2c70e 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -347,15 +347,15 @@ void GameSettingsScreen::CreateGraphicsSettings(UI::ViewGroup *graphicsSettings) } static const char *internalResolutions[] = { "Auto (1:1)", "1x PSP", "2x PSP", "3x PSP", "4x PSP", "5x PSP", "6x PSP", "7x PSP", "8x PSP", "9x PSP", "10x PSP" }; - resolutionChoice_ = graphicsSettings->Add(new PopupMultiChoice(&g_Config.iInternalResolution, gr->T("Rendering Resolution"), internalResolutions, 0, ARRAY_SIZE(internalResolutions), I18NCat::GRAPHICS, screenManager())); - resolutionChoice_->OnChoice.Add([](UI::EventParams &e) { + PopupMultiChoice *resolutionChoice = graphicsSettings->Add(new PopupMultiChoice(&g_Config.iInternalResolution, gr->T("Rendering Resolution"), internalResolutions, 0, ARRAY_SIZE(internalResolutions), I18NCat::GRAPHICS, screenManager())); + resolutionChoice->OnChoice.Add([](UI::EventParams &e) { if (g_Config.iAndroidHwScale == 1) { System_RecreateActivity(); } Reporting::UpdateConfig(); System_PostUIMessage(UIMessage::GPU_RENDER_RESIZED); }); - resolutionChoice_->SetEnabledFunc([] { + resolutionChoice->SetEnabledFunc([] { return !g_Config.bSoftwareRendering && !g_Config.bSkipBufferEffects; }); @@ -436,8 +436,8 @@ void GameSettingsScreen::CreateGraphicsSettings(UI::ViewGroup *graphicsSettings) } #endif // Display Layout Editor: To avoid overlapping touch controls on large tablets, meet geeky demands for integer zoom/unstretched image etc. - displayEditor_ = graphicsSettings->Add(new Choice(gr->T("Display layout & effects"))); - displayEditor_->OnClick.Add([&](UI::EventParams &) -> void { + Choice *displayEditor = graphicsSettings->Add(new Choice(gr->T("Display layout & effects"))); + displayEditor->OnClick.Add([&](UI::EventParams &) -> void { screenManager()->push(new DisplayLayoutScreen(gamePath_)); }); } @@ -467,8 +467,8 @@ void GameSettingsScreen::CreateGraphicsSettings(UI::ViewGroup *graphicsSettings) graphicsSettings->Add(new ItemHeader(gr->T("Frame Rate Control"))); static const char *frameSkip[] = {"Off", "1", "2", "3", "4", "5", "6", "7", "8"}; graphicsSettings->Add(new PopupMultiChoice(&g_Config.iFrameSkip, gr->T("Frame Skipping"), frameSkip, 0, ARRAY_SIZE(frameSkip), I18NCat::GRAPHICS, screenManager())); - frameSkipAuto_ = graphicsSettings->Add(new CheckBox(&g_Config.bAutoFrameSkip, gr->T("Auto FrameSkip"))); - frameSkipAuto_->OnClick.Add([](UI::EventParams &e) { + CheckBox *frameSkipAuto = graphicsSettings->Add(new CheckBox(&g_Config.bAutoFrameSkip, gr->T("Auto FrameSkip"))); + frameSkipAuto->OnClick.Add([](UI::EventParams &e) { g_Config.UpdateAfterSettingAutoFrameSkip(); }); @@ -866,11 +866,11 @@ void GameSettingsScreen::CreateControlsSettings(UI::ViewGroup *controlsSettings) if ((deviceType != DEVICE_TYPE_TV) && (deviceType != DEVICE_TYPE_VR)) { controlsSettings->Add(new ItemHeader(co->T("On-screen touch controls"))); controlsSettings->Add(new CheckBox(&g_Config.bShowTouchControls, co->T("On-screen touch controls"))); - layoutEditorChoice_ = controlsSettings->Add(new Choice(co->T("Edit touch control layout..."))); - layoutEditorChoice_->OnClick.Add([this](UI::EventParams &e) { + Choice *layoutEditorChoice = controlsSettings->Add(new Choice(co->T("Edit touch control layout..."))); + layoutEditorChoice->OnClick.Add([this](UI::EventParams &e) { screenManager()->push(new TouchControlLayoutScreen(gamePath_)); }); - layoutEditorChoice_->SetEnabledPtr(&g_Config.bShowTouchControls); + layoutEditorChoice->SetEnabledPtr(&g_Config.bShowTouchControls); Choice *gesture = controlsSettings->Add(new Choice(co->T("Gesture mapping"))); gesture->OnClick.Add([=](EventParams &e) { @@ -1198,15 +1198,14 @@ void GameSettingsScreen::CreateSystemSettings(UI::ViewGroup *systemSettings) { const Path bgPng = GetSysDirectory(DIRECTORY_SYSTEM) / "background.png"; const Path bgJpg = GetSysDirectory(DIRECTORY_SYSTEM) / "background.jpg"; + Choice *backgroundChoice = nullptr; if (File::Exists(bgPng) || File::Exists(bgJpg)) { - backgroundChoice_ = systemSettings->Add(new Choice(sy->T("Clear UI background"))); + backgroundChoice = systemSettings->Add(new Choice(sy->T("Clear UI background"))); } else if (System_GetPropertyBool(SYSPROP_HAS_IMAGE_BROWSER) || System_GetPropertyBool(SYSPROP_HAS_FILE_BROWSER)) { - backgroundChoice_ = systemSettings->Add(new Choice(sy->T("Set UI background..."))); - } else { - backgroundChoice_ = nullptr; + backgroundChoice = systemSettings->Add(new Choice(sy->T("Set UI background..."))); } - if (backgroundChoice_ != nullptr) { - backgroundChoice_->OnClick.Handle(this, &GameSettingsScreen::OnChangeBackground); + if (backgroundChoice) { + backgroundChoice->OnClick.Handle(this, &GameSettingsScreen::OnChangeBackground); } systemSettings->Add(new CheckBox(&g_Config.bTransparentBackground, sy->T("Transparent UI background"))); @@ -1342,9 +1341,10 @@ void GameSettingsScreen::CreateSystemSettings(UI::ViewGroup *systemSettings) { if (!enableReportsSet_) enableReports_ = Reporting::IsEnabled(); enableReportsSet_ = true; - enableReportsCheckbox_ = new CheckBox(&enableReports_, sy->T("Enable Compatibility Server Reports")); - enableReportsCheckbox_->SetEnabled(Reporting::IsSupported()); - systemSettings->Add(enableReportsCheckbox_); + CheckBox *enableReportsCheckbox; + enableReportsCheckbox = new CheckBox(&enableReports_, sy->T("Enable Compatibility Server Reports")); + enableReportsCheckbox->SetEnabledFunc([]() { return Reporting::IsSupported(); }); + systemSettings->Add(enableReportsCheckbox); systemSettings->Add(new ItemHeader(sy->T("Emulation"))); @@ -1355,9 +1355,6 @@ void GameSettingsScreen::CreateSystemSettings(UI::ViewGroup *systemSettings) { View *ioTimingMethod = systemSettings->Add(new PopupMultiChoice(&g_Config.iIOTimingMethod, sy->T("I/O timing method"), ioTimingMethods, 0, ARRAY_SIZE(ioTimingMethods), I18NCat::SYSTEM, screenManager())); systemSettings->Add(new CheckBox(&g_Config.bForceLagSync, sy->T("Force real clock sync (slower, less lag)")))->SetDisabledPtr(&g_Config.bAutoFrameSkip); PopupSliderChoice *lockedMhz = systemSettings->Add(new PopupSliderChoice(&g_Config.iLockedCPUSpeed, 0, 1000, 0, sy->T("Change CPU Clock", "Change CPU Clock (unstable)"), screenManager(), sy->T("MHz, 0:default"))); - lockedMhz->OnChange.Add([&](UI::EventParams &) { - enableReportsCheckbox_->SetEnabled(Reporting::IsSupported()); - }); lockedMhz->SetZeroLabel(sy->T("Auto")); auto sa = GetI18NCategory(I18NCat::SAVEDATA); @@ -1416,10 +1413,7 @@ void GameSettingsScreen::CreateSystemSettings(UI::ViewGroup *systemSettings) { #endif systemSettings->Add(new ItemHeader(sy->T("Cheats", "Cheats"))); - CheckBox *enableCheats = systemSettings->Add(new CheckBox(&g_Config.bEnableCheats, sy->T("Enable Cheats"))); - enableCheats->OnClick.Add([&](UI::EventParams &) { - enableReportsCheckbox_->SetEnabled(Reporting::IsSupported()); - }); + systemSettings->Add(new CheckBox(&g_Config.bEnableCheats, sy->T("Enable Cheats"))); systemSettings->Add(new CheckBox(&g_Config.bEnablePlugins, sy->T("Enable plugins"))); systemSettings->Add(new ItemHeader(sy->T("PSP Settings"))); diff --git a/UI/GameSettingsScreen.h b/UI/GameSettingsScreen.h index 6421bfb9d5..86162969de 100644 --- a/UI/GameSettingsScreen.h +++ b/UI/GameSettingsScreen.h @@ -59,12 +59,6 @@ private: void CreateVRSettings(UI::ViewGroup *vrSettings); std::string gameID_; - UI::CheckBox *enableReportsCheckbox_ = nullptr; - UI::Choice *layoutEditorChoice_ = nullptr; - UI::Choice *displayEditor_ = nullptr; - UI::Choice *backgroundChoice_ = nullptr; - UI::PopupMultiChoice *resolutionChoice_ = nullptr; - UI::CheckBox *frameSkipAuto_ = nullptr; #ifdef _WIN32 UI::CheckBox *SavePathInMyDocumentChoice = nullptr; UI::CheckBox *SavePathInOtherChoice = nullptr; From c8db8463f2711503be01865ef86502c0b98f86da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 19 Jan 2026 17:28:55 +0100 Subject: [PATCH 6/7] Some cleanup of the frameskipping setting. Avoid having Auto Frameskip reset the frameskip setting to 1. --- Core/Config.cpp | 4 ---- Core/HLE/sceDisplay.cpp | 12 +++++++++--- UI/GameSettingsScreen.cpp | 8 ++++++-- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index 94bce54019..393d27ab30 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -1224,10 +1224,6 @@ bool Config::LoadAppendedConfig() { } void Config::UpdateAfterSettingAutoFrameSkip() { - if (bAutoFrameSkip && iFrameSkip == 0) { - iFrameSkip = 1; - } - if (bAutoFrameSkip && bSkipBufferEffects) { bSkipBufferEffects = false; } diff --git a/Core/HLE/sceDisplay.cpp b/Core/HLE/sceDisplay.cpp index 6aecc36bb5..b68bb5797c 100644 --- a/Core/HLE/sceDisplay.cpp +++ b/Core/HLE/sceDisplay.cpp @@ -156,8 +156,12 @@ void __DisplayVblankEndCallback(SceUID threadID, SceUID prevCallbackId); void __DisplayFlip(int cyclesLate); static void __DisplaySetFramerate(void); +static bool UseAutoFrameSkip() { + return g_Config.bAutoFrameSkip && !g_Config.bSkipBufferEffects; +} + static bool UseLagSync() { - return g_Config.bForceLagSync && !g_Config.bAutoFrameSkip; + return g_Config.bForceLagSync && !UseAutoFrameSkip(); } static void ScheduleLagSync(int over = 0) { @@ -402,6 +406,8 @@ static void DoFrameTiming(bool throttle, bool *skipFrame, float scaledTimestep, PROFILE_THIS_SCOPE("timing"); *skipFrame = false; + const bool autoFrameSkip = UseAutoFrameSkip(); + // Check if the frameskipping code should be enabled. If neither throttling or frameskipping is on, // we have nothing to do here. bool doFrameSkip = g_Config.iFrameSkip != 0; @@ -424,8 +430,8 @@ static void DoFrameTiming(bool throttle, bool *skipFrame, float scaledTimestep, } // Auto-frameskip automatically if speed limit is set differently than the default. - int frameSkipNum = g_Config.iFrameSkip; - if (g_Config.bAutoFrameSkip && !g_Config.bSkipBufferEffects) { + const int frameSkipNum = g_Config.iFrameSkip; + if (autoFrameSkip) { // autoframeskip // Argh, we are falling behind! Let's skip a frame and see if we catch up. if (curFrameTime > nextFrameTime && doFrameSkip) { diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 31e2e2c70e..f0a103f30e 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -466,7 +466,11 @@ void GameSettingsScreen::CreateGraphicsSettings(UI::ViewGroup *graphicsSettings) graphicsSettings->Add(new ItemHeader(gr->T("Frame Rate Control"))); static const char *frameSkip[] = {"Off", "1", "2", "3", "4", "5", "6", "7", "8"}; - graphicsSettings->Add(new PopupMultiChoice(&g_Config.iFrameSkip, gr->T("Frame Skipping"), frameSkip, 0, ARRAY_SIZE(frameSkip), I18NCat::GRAPHICS, screenManager())); + PopupMultiChoice *frameSkipping = graphicsSettings->Add(new PopupMultiChoice(&g_Config.iFrameSkip, gr->T("Frame Skipping"), frameSkip, 0, ARRAY_SIZE(frameSkip), I18NCat::GRAPHICS, screenManager())); + frameSkipping->SetEnabledFunc([] { + return !g_Config.bAutoFrameSkip; + }); + CheckBox *frameSkipAuto = graphicsSettings->Add(new CheckBox(&g_Config.bAutoFrameSkip, gr->T("Auto FrameSkip"))); frameSkipAuto->OnClick.Add([](UI::EventParams &e) { g_Config.UpdateAfterSettingAutoFrameSkip(); @@ -1073,7 +1077,7 @@ void GameSettingsScreen::CreateNetworkingSettings(UI::ViewGroup *networkingSetti PopupTextInputChoice *qc4 = networkingSettings->Add(new PopupTextInputChoice(GetRequesterToken(), &g_Config.sQuickChat[3], n->T("Quick Chat 4"), "", 32, screenManager())); PopupTextInputChoice *qc5 = networkingSettings->Add(new PopupTextInputChoice(GetRequesterToken(), &g_Config.sQuickChat[4], n->T("Quick Chat 5"), "", 32, screenManager())); #elif defined(USING_QT_UI) -] Choice *qc1 = networkingSettings->Add(new Choice(n->T("Quick Chat 1"))); + Choice *qc1 = networkingSettings->Add(new Choice(n->T("Quick Chat 1"))); Choice *qc2 = networkingSettings->Add(new Choice(n->T("Quick Chat 2"))); Choice *qc3 = networkingSettings->Add(new Choice(n->T("Quick Chat 3"))); Choice *qc4 = networkingSettings->Add(new Choice(n->T("Quick Chat 4"))); From 188945f0fe77a53fe3cb52d328d6dd4c58e783ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 19 Jan 2026 17:44:03 +0100 Subject: [PATCH 7/7] Warning fixes --- Core/HLE/AtracCtx2.cpp | 2 +- Core/SaveState.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/HLE/AtracCtx2.cpp b/Core/HLE/AtracCtx2.cpp index b2fc724fbb..de68b8a371 100644 --- a/Core/HLE/AtracCtx2.cpp +++ b/Core/HLE/AtracCtx2.cpp @@ -221,7 +221,7 @@ int InitContextFromTrackInfo(SceAtracContext *ctx, const TrackInfo *wave, u32 bu return SCE_ERROR_ATRAC_BAD_CODEC_PARAMS; } - const int numChunks = (endSample >> (0x100b - (ctx->info).codec & 0x1f)); + const int numChunks = (endSample >> ((0x100b - (ctx->info).codec) & 0x1f)); if ((numChunks * (u32)(ctx->info).sampleSize < (wave->waveDataSize + dataOff) - dataOff)) { int retval = ComputeAtracStateAndInitSecondBuffer(&ctx->info, readSize, bufferSize); diff --git a/Core/SaveState.cpp b/Core/SaveState.cpp index ae65c58816..3fa47a1c87 100644 --- a/Core/SaveState.cpp +++ b/Core/SaveState.cpp @@ -948,7 +948,7 @@ enum class OperationType { break; } default: - ERROR_LOG(Log::SaveState, "Savestate failure: unknown operation type %d", op.type); + ERROR_LOG(Log::SaveState, "Savestate failure: unknown operation type %d", (int)op.type); callbackResult = Status::FAILURE; break; }