Merge pull request #21130 from hrydgard/more-android-bug-fixes

Fix annoying issue with frameskipping settings, assorted Android cleanups
This commit is contained in:
Henrik Rydgård authored and GitHub committed 2026-01-19 18:42:39 +01:00
commit f98c2484f8
20 files changed
+148 -172

No files matched your search

+7 -2
View File
@@ -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<std::mutex> 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<std::mutex> guard(missedKeyLock_);
std::string missedKey(key);
+1 -1
View File
@@ -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;
+4
View File
@@ -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;
+5 -9
View File
@@ -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[] = {
@@ -1224,10 +1224,6 @@ bool Config::LoadAppendedConfig() {
}
void Config::UpdateAfterSettingAutoFrameSkip() {
if (bAutoFrameSkip && iFrameSkip == 0) {
iFrameSkip = 1;
}
if (bAutoFrameSkip && bSkipBufferEffects) {
bSkipBufferEffects = false;
}
+1 -5
View File
@@ -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;
+1 -1
View File
@@ -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);
+1
View File
@@ -1305,6 +1305,7 @@ void sendChat(const std::string &chatString) {
std::lock_guard<std::mutex> 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++;
}
}
+9 -3
View File
@@ -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) {
+1 -1
View File
@@ -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;
}
+6 -25
View File
@@ -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) {
-5
View File
@@ -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;
+59 -67
View File
@@ -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_));
});
}
@@ -466,9 +466,15 @@ 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.Handle(this, &GameSettingsScreen::OnAutoFrameskip);
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();
});
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 +570,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);
}
@@ -853,11 +870,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) {
@@ -1054,11 +1071,11 @@ 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 *qc2 = networkingSettings->Add(new Choice(n->T("Quick Chat 2")));
@@ -1066,11 +1083,11 @@ void GameSettingsScreen::CreateNetworkingSettings(UI::ViewGroup *networkingSetti
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)
@@ -1185,15 +1202,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")));
@@ -1329,9 +1345,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")));
@@ -1342,9 +1359,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);
@@ -1403,10 +1417,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")));
@@ -1472,10 +1483,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 +1759,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);
-9
View File
@@ -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;
@@ -76,9 +70,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);
+3
View File
@@ -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);
+1 -1
View File
@@ -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);
}
@@ -128,8 +128,8 @@ public class ContentUri {
}
}
c.close();
c = null;
}
c = null;
for (Uri childUri : childDirs) {
long dirSize = directorySizeRecursion(activity, childUri);
@@ -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);
@@ -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);
@@ -1089,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
@@ -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.
@@ -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]);
}