Files
ppsspp/UI/Settings/SystemPage.cpp
T
Henrik RydgårdandClaude Opus 5.5 3eaae508da Settings: Add a General tab, first
It gets the UI page, Language and "Help the PPSSPP team" from the System tab, and
its General group. Its title and the General headers are looked up in MainSettings.

Translations: Move "General" from System to MainSettings

Done with langtool move-key.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-26 11:36:53 +01:00

314 lines
10 KiB
C++

// Copyright (c) 2012- PPSSPP Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0 or later versions.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include "ppsspp_config.h"
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include "Common/Common.h"
#include "Common/Data/Text/I18n.h"
#include "Common/File/FileUtil.h"
#include "Common/File/Path.h"
#include "Common/GPU/thin3d.h"
#include "Common/Log.h"
#include "Common/Render/ManagedTexture.h"
#include "Common/System/Display.h"
#include "Common/System/NativeApp.h"
#include "Common/System/OSD.h"
#include "Common/System/Request.h"
#include "Common/System/System.h"
#include "Common/UI/Context.h"
#include "Common/UI/PopupScreens.h"
#include "Common/UI/ScreenManager.h"
#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"
#include "Core/Util/PathUtil.h"
#include "UI/Background.h"
#include "UI/GameSettingsScreen.h"
#include "UI/MemStickScreen.h"
#include "UI/MiscScreens.h"
#include "UI/MiscViews.h"
#include "UI/SettingsPage.h"
#include "UI/Settings/MainSettingsPages.h"
#include "UI/Theme.h"
#if PPSSPP_PLATFORM(MAC) || PPSSPP_PLATFORM(IOS)
#include "Core/Util/DarwinFileSystemServices.h"
#endif
#if defined(_WIN32) && !PPSSPP_PLATFORM(UWP)
#pragma warning(disable:4091) // workaround bug in VS2015 headers
#include "Windows/MainWindow.h"
#include "Windows/W32Util/ShellUtil.h"
#endif
void ReadSystemPageState(SystemPageState *state) {
// Written back on exit, so it must be read even if the System tab is never opened.
state->enableReports = Reporting::IsEnabled();
}
#if defined(_WIN32) && !PPSSPP_PLATFORM(UWP)
// Works out where the memstick is (installed.txt next to the exe means My Documents or a custom
// folder), and which of the two checkboxes can be changed.
void CheckMemstickInstallState(SystemPageState *state) {
const Path &PPSSPPpath = File::GetExeDirectory();
const Path installedFile = PPSSPPpath / "installed.txt";
const bool myDocsExists = W32Util::UserDocumentsPath().size() != 0;
state->installed = File::Exists(installedFile);
state->otherinstalled = false;
state->memstickMyDocEnabled = !PSP_IsInited();
state->memstickOtherEnabled = false;
if (!state->installed && myDocsExists) {
// Disable the setting if we can't create & delete a file next to the exe.
if (File::CreateEmptyFile(PPSSPPpath / "installedTEMP.txt")) {
if (!(File::Delete(PPSSPPpath / "installedTEMP.txt")))
state->memstickMyDocEnabled = false;
else
state->memstickOtherEnabled = !PSP_IsInited();
} else
state->memstickMyDocEnabled = false;
} else {
if (state->installed && myDocsExists) {
FILE *testInstalled = File::OpenCFile(installedFile, "rt");
if (testInstalled) {
char temp[2048];
char *tempStr = fgets(temp, sizeof(temp), testInstalled);
// Skip UTF-8 encoding bytes if there are any. There are 3 of them.
if (tempStr && strncmp(tempStr, "\xEF\xBB\xBF", 3) == 0) {
tempStr += 3;
}
state->memstickOtherEnabled = !PSP_IsInited();
if (tempStr && strlen(tempStr) != 0 && strcmp(tempStr, "\n") != 0) {
state->installed = false;
state->otherinstalled = true;
}
fclose(testInstalled);
}
} else if (!myDocsExists) {
state->memstickMyDocEnabled = false;
}
}
}
static void OnMemoryStickMyDoc(SystemPageState *state) {
const Path &PPSSPPpath = File::GetExeDirectory();
const Path installedFile = PPSSPPpath / "installed.txt";
state->installed = File::Exists(installedFile);
if (state->otherinstalled) {
File::Delete(PPSSPPpath / "installed.txt");
File::CreateEmptyFile(PPSSPPpath / "installed.txt");
state->otherinstalled = false;
const std::string myDocsPath = W32Util::UserDocumentsPath() + "/PPSSPP/";
g_Config.memStickDirectory = Path(myDocsPath);
} else if (state->installed) {
File::Delete(PPSSPPpath / "installed.txt");
state->installed = false;
g_Config.memStickDirectory = PPSSPPpath / "memstick";
} else {
FILE *f = File::OpenCFile(PPSSPPpath / "installed.txt", "wb");
if (f) {
fclose(f);
}
const std::string myDocsPath = W32Util::UserDocumentsPath() + "/PPSSPP/";
g_Config.memStickDirectory = Path(myDocsPath);
state->installed = true;
}
}
static void OnMemoryStickOther(SystemPageState *state) {
const Path &PPSSPPpath = File::GetExeDirectory();
if (state->otherinstalled) {
auto di = GetI18NCategory(I18NCat::DIALOG);
std::string initialPath = g_Config.memStickDirectory.ToCString();
std::string folder = W32Util::BrowseForFolder2(MainWindow::GetHWND(), di->T("Choose PPSSPP save folder"), initialPath);
if (folder.size()) {
g_Config.memStickDirectory = Path(folder);
FILE *f = File::OpenCFile(PPSSPPpath / "installed.txt", "wb");
if (f) {
std::string utfstring("\xEF\xBB\xBF");
utfstring.append(folder);
fwrite(utfstring.c_str(), 1, utfstring.length(), f);
fclose(f);
}
state->installed = false;
}
else
state->otherinstalled = false;
}
else {
File::Delete(PPSSPPpath / "installed.txt");
state->memstickMyDocEnabled = true;
state->otherinstalled = false;
state->installed = false;
g_Config.memStickDirectory = PPSSPPpath / "memstick";
}
}
#endif
static void OnJitAffectingSetting() {
System_PostUIMessage(UIMessage::REQUEST_CLEAR_JIT);
}
// Using SYSTEM translations
static void BuildPSPSettingsPage(SettingsPage *page) {
SettingsPageHost *host = page->Host();
page->Header("PSP Settings");
// The ordering here is simply mapping directly to PSP_SYSTEMPARAM_LANGUAGE_*.
page->Setting(&g_Config.iLanguage);
page->Setting(&g_Config.iPSPModel).EnabledFunc([] {
return !PSP_IsInited();
});
page->Custom("Nickname", [host](UI::ViewGroup *parent) {
return AddNicknameChoice(host, parent);
});
page->Setting(&g_Config.bDayLightSavings);
page->Setting(&g_Config.iDateFormat);
page->Setting(&g_Config.iTimeFormat);
page->Setting(&g_Config.iButtonPreference);
}
void BuildSystemSettings(SettingsPage *page, SystemPageState *state) {
using namespace UI;
SettingsPageHost *host = page->Host();
page->Header();
page->Link({I18NCat::SYSTEM, "PSP Settings"}, I18NCat::SYSTEM, &BuildPSPSettingsPage);
page->Header("PSP Memory Stick");
if (System_GetPropertyBool(SYSPROP_HAS_OPEN_DIRECTORY)) {
page->Choice("Show Memory Stick folder").OnClick([](UI::EventParams &p) {
System_LaunchUrl(LaunchUrlType::LOCAL_FOLDER, g_Config.memStickDirectory.ToString());
});
}
#if PPSSPP_PLATFORM(MAC) || PPSSPP_PLATFORM(IOS)
bool showItHere = true;
#if PPSSPP_PLATFORM(IOS_APP_STORE)
if (g_Config.memStickDirectory == DarwinFileSystemServices::defaultMemoryStickPath()) {
// We still keep a way to access it on the developer tools screen.
showItHere = false;
}
#endif
if (showItHere) {
page->Choice("Set Memory Stick folder").OnClick([host](UI::EventParams &) {
SetMemStickDirDarwin(host->PageRequesterToken());
});
}
#endif
auto addMemstickPath = [host, &page]() {
page->Custom("Memory Stick folder", [host](UI::ViewGroup *parent) -> UI::View * {
Choice *memstickPath = parent->Add(new ChoiceWithCallbackValueDisplay(T(I18NCat::SYSTEM, "Memory Stick folder"), []() {
return g_Config.memStickDirectory.ToVisualString();
}));
memstickPath->OnClick.Add([host](UI::EventParams &e) {
host->PageScreenManager()->push(new MemStickScreen(false));
});
return memstickPath;
}).EnabledFunc([] {
return !PSP_IsInited();
});
};
#if PPSSPP_PLATFORM(ANDROID)
if (System_GetPropertyInt(SYSPROP_DEVICE_TYPE) != DEVICE_TYPE_VR) {
addMemstickPath();
}
#elif defined(_WIN32)
#if PPSSPP_PLATFORM(UWP)
addMemstickPath();
#else
page->Bool(&state->installed, "Memory Stick in My Documents").Enabled(&state->memstickMyDocEnabled).OnChange([state](UI::EventParams &e) {
OnMemoryStickMyDoc(state);
});
page->Bool(&state->otherinstalled, "Memory Stick in installed.txt").Enabled(&state->memstickOtherEnabled).OnChange([state](UI::EventParams &e) {
OnMemoryStickOther(state);
});
if (!System_GetPropertyBool(SYSPROP_CAN_GET_FREE_SPACE_FAST)) {
// It might be slow, so use an option.
page->Setting(&g_Config.bReportAccurateFreeStorageSpace);
}
#endif
#endif
page->Setting(&g_Config.bMemStickInserted);
page->Setting(&g_Config.iMemStickSizeGB);
page->Header("Emulation");
page->Setting(&g_Config.bFastMemory).OnChange([](UI::EventParams &e) {
OnJitAffectingSetting();
});
page->Setting(&g_Config.bIgnoreBadMemAccess);
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<PopupMultiChoice *>(view)->HideChoice(1); // Hide "Oldest Save" if not using that mode. It doesn't make sense.
}
});
page->Setting(&g_Config.iRewindSnapshotInterval);
std::vector<std::string> 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);
page->Setting(&g_Config.bDumpVideoOutput);
page->Setting(&g_Config.bDumpAudio);
page->Setting(&g_Config.bSaveLoadResetsAVdumping);
#endif
}