mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-08-31 17:55:23 +02:00
Module symbols are keyed by module+crc so they're shared by every game that
loads that module. But symbols the user attaches to addresses that aren't in
any module - the heap, the stack, scratchpad, a hardware register, typically
after a memory.search - describe one game's own memory layout and are worthless
to any other game. Those now go to PSP/SYSTEM/SYMBOLS/<gameID>_syms.ppsym.
They're module index 0 ("absolute"), which already round-trips through the
existing per-module code: GetModuleRelativeAddr/GetModuleAbsoluteAddr are
identity for it, so the file format is unchanged, just with absolute addresses.
SaveModuleSymbols only needed to stop requiring a ModuleEntry. Auto-load/save
hang off CPU_Init/CPU_Shutdown rather than module load/unload, gated on the same
bAutoSaveLoadSymbols setting - and deliberately not on SYSPROP_HAS_DEBUGGER,
which only the Windows port reports true for, so LoadSymbolsIfSupported next to
it does nothing at all on headless. hle.game.saveSymbols/loadSymbols expose it.
Four things found while doing it:
- Symbols outside any module were being dropped on the floor. AddFunction/
AddData/AddLabel take moduleIndex -1 as "work it out", pass it to
GetModuleIndex(), and store whatever comes back - but that returns -1 when no
module contains the address, and -1 is never an active module, so the symbol
never reached the active maps: invisible to every lookup and to any save.
hle.data.add had spotted this and normalized -1 to 0 locally; nothing else
did, so e.g. hle.func.add outside a module silently did nothing. Fixed
centrally in a new ResolveModuleIndex() the three of them share.
(This only became reachable with the GetModuleIndex() fix in 29a38af37e -
before that it returned a wrong-but-valid module index instead.)
- The saved files were almost entirely noise. Every function the analyzer finds
is named z_un_<addr> and every import stub zz_<name>, both regenerated from
scratch on each load. One real module wrote 13KB - 443 unnamed functions and
64 stub names - for the four names a human had actually chosen. Worse, on the
next run those were loaded back as authoritative and would beat the module's
own symbols to the address. Now only names that aren't regenerated get saved,
and a module with none writes no file at all (and removes a stale one, so
deleting a symbol sticks). That module's file went 13020 -> 81 bytes.
- LoadModuleSymbols trusted the addresses in the file. It's meant to be
hand-edited and can outlive the build it came from, so relative addresses past
the end of the module are now skipped with a warning instead of landing at
nonsense addresses.
- AddFunction and AddData both erased the map entry they were updating and then
read back through the now-dangling iterator to refresh the active copy. Only
latent: the refresh is guarded on the active copy's module matching the new
one, which is false exactly when the erase happens. Re-point the iterator at
the entry's new home instead, so it can't rot if that guard ever changes.
AddLabel already did the equivalent correctly, via a local copy.
Filename sanitizing goes through SanitizeString with a new FileName restriction
rather than being open-coded; unlike the existing restrictions it substitutes
'_' instead of dropping, so two module names can't collapse onto one file.
Verified end to end on headless with cpu_alu.prx: named a function inside the
module and data/functions in scratchpad and the heap, let it exit, checked both
files, rebooted and confirmed all of it came back at the right addresses.
Unit tests 51/51, pspautotests 314/314.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GZq8ZtJmFY7bkX5FVkr3P9
819 lines
25 KiB
C++
819 lines
25 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/.
|
|
|
|
#pragma once
|
|
|
|
#include <string>
|
|
#include <string_view>
|
|
#include <map>
|
|
#include <vector>
|
|
#include <mutex>
|
|
|
|
#include "ppsspp_config.h"
|
|
|
|
#include "Common/CommonTypes.h"
|
|
#include "Common/File/Path.h"
|
|
#include "Common/Math/geom2d.h"
|
|
#include "Core/ConfigValues.h"
|
|
|
|
extern const char *PPSSPP_GIT_VERSION;
|
|
|
|
namespace http {
|
|
class Request;
|
|
class RequestManager;
|
|
}
|
|
|
|
struct UrlEncoder;
|
|
|
|
class Section;
|
|
class IniFile;
|
|
|
|
class PlayTimeTracker {
|
|
public:
|
|
struct PlayTime {
|
|
int totalTimePlayed;
|
|
double startTime; // time_now_d() time
|
|
uint64_t lastTimePlayed; // UTC Unix time for portability.
|
|
};
|
|
|
|
// It's OK to call these redundantly.
|
|
void Start(std::string_view gameId);
|
|
void Stop(std::string_view gameId);
|
|
void Reset(std::string_view gameId);
|
|
|
|
void Load(const Section *section);
|
|
void Save(Section *section);
|
|
|
|
bool GetPlayedTimeString(std::string_view, std::string *str) const;
|
|
|
|
private:
|
|
std::map<std::string, PlayTime, std::less<>> tracker_;
|
|
};
|
|
|
|
struct ConfigSetting;
|
|
|
|
struct ConfigSectionMeta {
|
|
ConfigBlock *configBlock;
|
|
const ConfigSetting *settings;
|
|
size_t settingsCount;
|
|
std::string_view section;
|
|
std::string_view fallbackSectionName; // used if section is not found (useful when moving settings into a struct from Config).
|
|
};
|
|
|
|
struct DisplayLayoutConfig : public ConfigBlock {
|
|
int iDisplayFilter = SCALE_LINEAR; // 1 = linear, 2 = nearest
|
|
bool bDisplayStretch = false; // Automatically matches the aspect ratio of the window.
|
|
float fDisplayOffsetX = 0.5f;
|
|
float fDisplayOffsetY = 0.5f;
|
|
float fDisplayScale = 1.0f; // Relative to the most constraining axis (x or y).
|
|
bool bDisplayIntegerScale = false; // Snaps scaling to integer scale factors in raw pixels.
|
|
float fDisplayAspectRatio = 1.0f; // Stored relative to the PSP's native ratio, so 1.0 is the normal pixel aspect ratio.
|
|
int iInternalScreenRotation = ROTATION_LOCKED_HORIZONTAL; // The internal screen rotation angle. Useful for vertical SHMUPs and similar.
|
|
bool bRotateControlsWithScreen = true; // Rotate gamepad controls along with the internal screen rotation.
|
|
bool bIgnoreScreenInsets = true; // Android: Center screen disregarding insets if this is enabled.
|
|
|
|
// Deprecated
|
|
bool bEnableCardboardVR = false; // Cardboard Master Switch
|
|
int iCardboardScreenSize = 50; // Screen Size (in %)
|
|
int iCardboardXShift = 0; // X-Shift of Screen (in %)
|
|
int iCardboardYShift = 0; // Y-Shift of Screen (in %)
|
|
bool bImmersiveMode = true; // Mode on Android Kitkat 4.4 and later that hides the back button etc.
|
|
|
|
bool InternalRotationIsPortrait() const;
|
|
bool CanResetToDefault() const override { return true; }
|
|
bool ResetToDefault(std::string_view blockName) override;
|
|
size_t Size() const override { return sizeof(DisplayLayoutConfig); } // For sanity checks
|
|
};
|
|
|
|
struct TouchControlConfig : public ConfigBlock {
|
|
constexpr TouchControlConfig() {
|
|
// Hide all extras and custom buttons by default.
|
|
touchRightAnalogStick.show = false;
|
|
for (size_t i = 0; i < CUSTOM_BUTTON_COUNT; i++) {
|
|
touchCustom[i].show = false;
|
|
}
|
|
}
|
|
// the PSP button's center (triangle, circle, square, cross)
|
|
ConfigTouchPos touchActionButtonCenter;
|
|
// space between those PSP buttons
|
|
float fActionButtonSpacing = 1.0f;
|
|
// the D-pad (PSP cross) position
|
|
ConfigTouchPos touchDpad;
|
|
// And its spacing.
|
|
float fDpadSpacing = 1.0f;
|
|
|
|
ConfigTouchPos touchStartKey;
|
|
ConfigTouchPos touchSelectKey;
|
|
ConfigTouchPos touchFastForwardKey;
|
|
ConfigTouchPos touchLKey;
|
|
ConfigTouchPos touchRKey;
|
|
ConfigTouchPos touchAnalogStick;
|
|
ConfigTouchPos touchRightAnalogStick;
|
|
ConfigTouchPos touchPauseKey;
|
|
|
|
enum { CUSTOM_BUTTON_COUNT = 20 };
|
|
|
|
ConfigTouchPos touchCustom[CUSTOM_BUTTON_COUNT];
|
|
|
|
float fLeftStickHeadScale = 1.0f;
|
|
float fRightStickHeadScale = 1.0f;
|
|
|
|
bool bHideStickBackground = false;
|
|
|
|
bool bShowTouchCircle = true;
|
|
bool bShowTouchCross = true;
|
|
bool bShowTouchTriangle = true;
|
|
bool bShowTouchSquare = true;
|
|
|
|
void ResetLayout();
|
|
|
|
bool CanResetToDefault() const override { return true; }
|
|
bool ResetToDefault(std::string_view blockName) override;
|
|
size_t Size() const override { return sizeof(TouchControlConfig); } // For sanity checks
|
|
};
|
|
|
|
struct GestureControlConfig : public ConfigBlock {
|
|
// Motion gesture controller
|
|
bool bGestureControlEnabled = false;
|
|
int iSwipeUp = 0;
|
|
int iSwipeDown = 0;
|
|
int iSwipeLeft = 0;
|
|
int iSwipeRight = 0;
|
|
float fSwipeSensitivity = 1.0f;
|
|
float fSwipeSmoothing = 0.5f;
|
|
int iDoubleTapGesture = 0;
|
|
bool bAnalogGesture = false;
|
|
float fAnalogGestureSensitivity = 1.0f;
|
|
|
|
bool CanResetToDefault() const override { return true; }
|
|
bool ResetToDefault(std::string_view blockName) override;
|
|
size_t Size() const override { return sizeof(GestureControlConfig); } // For sanity checks
|
|
};
|
|
|
|
struct Config : public ConfigBlock {
|
|
public:
|
|
~Config();
|
|
|
|
void Init();
|
|
|
|
size_t Size() const override { return sizeof(Config); }
|
|
|
|
// Whether to save the config on close.
|
|
bool bSaveSettings;
|
|
bool bFirstRun;
|
|
bool bUpdatedInstanceCounter = false;
|
|
|
|
int iRunCount; // To be used to for example check for updates every 10 runs and things like that.
|
|
|
|
// Debugger
|
|
bool bAutoRun; // start immediately
|
|
bool bBreakOnFrameTimeout; // not saved
|
|
|
|
// General
|
|
bool bScreenshotsAsPNG;
|
|
bool bUseFFV1;
|
|
bool bDumpFrames;
|
|
bool bDumpVideoOutput;
|
|
bool bDumpAudio;
|
|
bool bSaveLoadResetsAVdumping;
|
|
bool bShowSaveLoadIndicator;
|
|
bool bEnableLogging;
|
|
bool bEnableFileLogging;
|
|
int iLogOutputTypes; // enum class LogOutput
|
|
int iDumpFileTypes; // DumpFileType bitflag enum
|
|
bool bFullscreenOnDoubleclick;
|
|
bool bPauseOnLostFocus;
|
|
|
|
// These are Win UI only
|
|
bool bTopMost;
|
|
bool bIgnoreWindowsKey;
|
|
bool bRestartRequired;
|
|
|
|
bool bPauseWhenMinimized;
|
|
|
|
bool bPauseExitsEmulator;
|
|
bool bPauseMenuExitsEmulator;
|
|
|
|
bool bRunBehindPauseMenu;
|
|
|
|
// Core
|
|
bool bIgnoreBadMemAccess;
|
|
|
|
// ExceptionAction enum: 0 = default (obey bIgnoreBadMemAccess), 1 = log, 2 = break, 3 = exit
|
|
int iExceptionActionMemRead; // this also includes alignment and other odd memory exceptions.
|
|
int iExceptionActionMemWrite;
|
|
int iExceptionActionBreak;
|
|
|
|
// If true, log a best-effort native stack trace (Windows only) when a genuinely
|
|
// unhandled access violation is about to crash the process. Diagnostic only, off by
|
|
// default - see --log-native-crashes in Core/CmdLine.cpp.
|
|
bool bLogNativeCrashStackTraces;
|
|
|
|
bool bFastMemory;
|
|
int iCpuCore;
|
|
bool bCheckForNewVersion;
|
|
bool bForceLagSync;
|
|
bool bFuncReplacements;
|
|
bool bHideSlowWarnings;
|
|
bool bHideStateWarnings;
|
|
uint32_t uJitDisableFlags;
|
|
|
|
bool bDisableHTTPS;
|
|
|
|
bool bShrinkIfWindowSmall;
|
|
bool bSeparateSASThread;
|
|
int iIOTimingMethod;
|
|
int iLockedCPUSpeed;
|
|
bool bAutoSaveSymbolMap;
|
|
bool bCompressSymbols;
|
|
bool bCacheFullIsoInRam;
|
|
int iRemoteISOPort; // Also used for serving a local remote debugger.
|
|
std::string sLastRemoteISOServer;
|
|
int iLastRemoteISOPort;
|
|
bool bRemoteISOManual;
|
|
bool bRemoteShareOnStartup;
|
|
std::string sRemoteISOSubdir;
|
|
std::string sRemoteISOSharedDir;
|
|
int iRemoteISOShareType;
|
|
bool bRemoteDebuggerOnStartup;
|
|
bool bRemoteDebuggerLocal;
|
|
bool bRemoteTab;
|
|
bool bMemStickInserted;
|
|
int iMemStickSizeGB;
|
|
bool bLoadPlugins;
|
|
int iAskForExitConfirmationAfterSeconds;
|
|
int iUIScaleFactor; // In 8ths of powers of two.
|
|
int iDisableHLE;
|
|
int iForceEnableHLE; // This is the opposite of DisableHLE but can force on HLE even when we've made it permanently off. Only used in tests, not hooked up to the ini file yet.
|
|
|
|
int iScreenRotation; // Screen rotation lock. Only supported on Android and possibly other mobile platforms.
|
|
|
|
std::string sReportHost;
|
|
std::vector<std::string> vPinnedPaths;
|
|
std::string sLanguageIni;
|
|
|
|
std::string sIgnoreCompatSettings;
|
|
|
|
bool bDiscordRichPresence; // Enables setting the Discord presence to the current game (or menu)
|
|
|
|
// GFX
|
|
int iGPUBackend;
|
|
std::string sCustomDriver;
|
|
std::string sFailedGPUBackends; // NOT stored in ppsspp.ini anymore!
|
|
std::string sDisabledGPUBackends;
|
|
// We have separate device parameters for each backend so it doesn't get erased if you switch backends.
|
|
// If not set, will use the "best" device.
|
|
std::string sVulkanDevice;
|
|
std::string sD3D11Device; // Windows only
|
|
std::string sCameraDevice;
|
|
std::string sMicDevice;
|
|
bool bCameraMirrorHorizontal;
|
|
int iDisplayFramerateMode; // enum DisplayFramerateMode. Android-only.
|
|
int iDisplayRefreshRate = 60;
|
|
|
|
// These two combined choose the presentation mode.
|
|
// vsync = false: Immediate
|
|
// vsync = true, low latency present = true: Mailbox
|
|
// vsync = true, low latency present = false: FIFO
|
|
bool bVSync;
|
|
bool bLowLatencyPresent;
|
|
|
|
bool bSoftwareRendering;
|
|
bool bSoftwareRenderingJit;
|
|
bool bSoftwareDisableDithering;
|
|
bool bHardwareTransform;
|
|
bool bVendorBugChecksEnabled;
|
|
|
|
// Speedhacks (more will be moved here):
|
|
bool bSkipBufferEffects;
|
|
int iDepthRasterMode;
|
|
|
|
int iTexFiltering; // 1 = auto , 2 = nearest , 3 = linear , 4 = auto max quality
|
|
bool bSmart2DTexFiltering;
|
|
|
|
// We'll carry over the old single layout into landscape for now.
|
|
DisplayLayoutConfig displayLayoutLandscape;
|
|
DisplayLayoutConfig displayLayoutPortrait;
|
|
|
|
bool bDisplayCropTo16x9; // Crops to 16:9 if the resolution is very close.
|
|
|
|
bool bSustainedPerformanceMode; // Android: Slows clocks down to avoid overheating/speed fluctuations.
|
|
|
|
bool bShowImDebugger;
|
|
|
|
int iFrameSkip;
|
|
bool bAutoFrameSkip;
|
|
|
|
int iWindowX;
|
|
int iWindowY;
|
|
int iWindowWidth; // Windows and other windowed environments
|
|
int iWindowHeight;
|
|
int iWindowSizeState; // WindowSizeState enum
|
|
|
|
bool bShowMenuBar; // Windows-only
|
|
|
|
float fUITint;
|
|
float fUISaturation;
|
|
|
|
bool bVertexDecoderJit;
|
|
int iAppSwitchMode;
|
|
bool bFullScreen;
|
|
bool bFullScreenMulti;
|
|
bool bAllowFullScreenExclusive;
|
|
int iInternalResolution; // 0 = Auto (native), 1 = 1x (480x272), 2 = 2x, 3 = 3x, 4 = 4x and so on.
|
|
int iAnisotropyLevel; // 0 - 5, powers of 2: 0 = 1x = no aniso
|
|
int iMultiSampleLevel;
|
|
int bHighQualityDepth;
|
|
bool bReplaceTextures;
|
|
bool bSaveNewTextures;
|
|
int iReplacementTextureLoadSpeed;
|
|
bool bIgnoreTextureFilenames;
|
|
int iTexScalingLevel; // 0 = auto, 1 = off, 2 = 2x, ..., 5 = 5x
|
|
int iTexScalingType; // 0 = xBRZ, 1 = Hybrid
|
|
bool bTexDeposterize;
|
|
bool bTexHardwareScaling;
|
|
int iFpsLimit1;
|
|
int iFpsLimit2;
|
|
int iAnalogFpsLimit;
|
|
int iMaxRecent;
|
|
int iCurrentStateSlot;
|
|
int iRewindSnapshotInterval;
|
|
bool bUISound;
|
|
bool bEnableStateUndo;
|
|
bool bConfirmLoadState;
|
|
std::string sStateLoadUndoGame;
|
|
std::string sStateUndoLastSaveGame;
|
|
int iStateUndoLastSaveSlot;
|
|
int iAutoLoadSaveState; // 0 = off, 1 = oldest (deprecated), 2 = newest, 3+ = slot number + 3 (up to 5)
|
|
int iSaveStateSlotCount;
|
|
bool bEnableCheats;
|
|
bool bReloadCheats;
|
|
bool bEnablePlugins;
|
|
bool bEnableFileHandlerPlugins;
|
|
int iCwCheatRefreshIntervalMs;
|
|
float fCwCheatScrollPosition;
|
|
float fGameListScrollPosition;
|
|
float fHomebrewScrollPosition;
|
|
float fRemoteScrollPosition;
|
|
bool bReportAccurateFreeStorageSpace;
|
|
int iBloomHack; //0 = off, 1 = safe, 2 = balanced, 3 = aggressive
|
|
int iSkipGPUReadbackMode; // 0 = off, 1 = skip, 2 = to texture
|
|
int iSplineBezierQuality; // 0 = low , 1 = Intermediate , 2 = High
|
|
bool bShaderCache; // Hidden ini-only setting, useful for debugging shader compile times.
|
|
bool bUberShaderVertex;
|
|
int iDefaultTab;
|
|
int iScreenshotMode;
|
|
bool bVulkanDisableImplicitLayers;
|
|
bool bForceFfmpegForAudioDec;
|
|
|
|
std::vector<std::string> vPostShaderNames; // Off for chain end (only Off for no shader)
|
|
std::map<std::string, float> mPostShaderSetting;
|
|
|
|
// Note that this is separate from VR stereo, though it'll share some code paths.
|
|
bool bStereoRendering;
|
|
// There can only be one, unlike regular post shaders.
|
|
std::string sStereoToMonoShader;
|
|
|
|
bool bShaderChainRequires60FPS;
|
|
std::string sTextureShaderName;
|
|
bool bGfxDebugOutput;
|
|
int iInflightFrames;
|
|
bool bRenderDuplicateFrames;
|
|
bool bRenderMultiThreading;
|
|
|
|
// HW debug
|
|
bool bShowGPOLEDs;
|
|
|
|
// Sound
|
|
bool bEnableSound;
|
|
int iSDLAudioBufferSize;
|
|
int iAudioBufferSize;
|
|
bool bFillAudioGaps;
|
|
int iAudioPlaybackMode;
|
|
|
|
// Legacy volume settings, 0-10. These get auto-upgraded and should not be used.
|
|
int iLegacyGameVolume;
|
|
int iLegacyReverbVolume;
|
|
int iLegacyAchievementVolume;
|
|
|
|
// Newer volume settings, 0-100
|
|
int iGameVolume;
|
|
int iReverbVolume;
|
|
int iUIVolume;
|
|
int iGamePreviewVolume; // Volume for the game preview sound in the game grid.
|
|
int iAchievementVolume;
|
|
int iAltSpeedVolume;
|
|
|
|
bool bExtraAudioBuffering; // For bluetooth
|
|
std::string sAudioDevice;
|
|
bool bAutoSwitchAudioDevice;
|
|
bool bUseOldAtrac;
|
|
|
|
// iOS only for now
|
|
bool bAudioMixWithOthers;
|
|
bool bAudioRespectSilentMode;
|
|
|
|
// UI
|
|
bool bShowDebuggerOnLoad;
|
|
int iShowStatusFlags;
|
|
bool bShowRegionOnGameIcon;
|
|
bool bShowIDOnGameIcon;
|
|
float fGameGridScale;
|
|
int iBackgroundAnimation; // enum BackgroundAnimation
|
|
bool bTransparentBackground;
|
|
int iSettingsCurrentTab;
|
|
int iDeveloperSettingsCurrentTab;
|
|
|
|
std::string sThemeName;
|
|
|
|
// These aren't saved, just for instant debugging.
|
|
bool bLogFrameDrops;
|
|
|
|
// Analog stick tilting
|
|
// This is the held base angle (from the horizon), that we compute the tilt relative from.
|
|
float fTiltBaseAngleY;
|
|
// Inverts the direction of the x axes and y axes for the purposes of tilt input.
|
|
bool bInvertTiltX;
|
|
bool bInvertTiltY;
|
|
// The sensitivity of the tilt in the X and Y directions, separately.
|
|
int iTiltSensitivityX;
|
|
int iTiltSensitivityY;
|
|
// The deadzone radius of the tilt. Only used in the analog mapping.
|
|
float fTiltAnalogDeadzoneRadius;
|
|
float fTiltInverseDeadzone; // An inverse deadzone for the output, counteracting excessive deadzones applied by games. See #17483.
|
|
bool bTiltCircularDeadzone;
|
|
// Type of tilt input currently selected: Defined in TiltEventProcessor.h
|
|
// 0 - no tilt, 1 - analog stick, 2 - D-Pad, 3 - Action Buttons (Tri, Cross, Square, Circle)
|
|
int iTiltInputType;
|
|
bool bTiltInputEnabled;
|
|
|
|
// The four tabs (including Remote last)
|
|
bool bGridView1;
|
|
bool bGridView2;
|
|
bool bGridView3;
|
|
bool bGridView4;
|
|
|
|
// Right analog binding
|
|
int iRightAnalogUp;
|
|
int iRightAnalogDown;
|
|
int iRightAnalogLeft;
|
|
int iRightAnalogRight;
|
|
int iRightAnalogPress;
|
|
bool bRightAnalogCustom;
|
|
bool bRightAnalogDisableDiagonal;
|
|
|
|
// 0 for left, 1 for right
|
|
GestureControlConfig gestureControls[2];
|
|
|
|
// Controls Visibility
|
|
bool bShowTouchControls = false;
|
|
|
|
// Disable diagonals
|
|
bool bDisableDpadDiagonals;
|
|
bool bGamepadOnlyFocused;
|
|
|
|
// Control Style
|
|
int iTouchButtonStyle;
|
|
int iTouchButtonOpacity;
|
|
int iTouchButtonHideSeconds;
|
|
|
|
// Snap touch control position
|
|
bool bTouchSnapToGrid;
|
|
int iTouchSnapGridSize;
|
|
|
|
// Floating analog stick (recenters on thumb on press).
|
|
bool bAutoCenterTouchAnalog;
|
|
|
|
// Sticky D-pad (can't glide off it)
|
|
bool bStickyTouchDPad;
|
|
|
|
// Touch gliding (see #14490)
|
|
bool bTouchGliding;
|
|
|
|
TouchControlConfig touchControlsLandscape;
|
|
TouchControlConfig touchControlsPortrait;
|
|
|
|
// These are shared between portrait and landscape, just the positions aren't.
|
|
ConfigCustomButton CustomButton[TouchControlConfig::CUSTOM_BUTTON_COUNT];
|
|
|
|
// Ignored on iOS and other platforms that lack pause.
|
|
bool bShowTouchPause;
|
|
|
|
bool bHapticFeedback;
|
|
|
|
// We also use the XInput settings as analog settings on other platforms like Android.
|
|
float fAnalogDeadzone;
|
|
float fAnalogInverseDeadzone;
|
|
float fAnalogSensitivity;
|
|
// convert analog stick circle to square
|
|
bool bAnalogIsCircular;
|
|
// Auto rotation speed
|
|
float fAnalogAutoRotSpeed;
|
|
|
|
// Advanced analog deadzone settings (Steam Input-style).
|
|
// Deadzone shape: 0 = Circle, 1 = Square (default, matches legacy max-norm), 2 = Cross
|
|
int iAnalogDeadzoneShape;
|
|
// Cross-shaped axial anti-deadzone. Boosts small off-axis values past this threshold,
|
|
// making the output skip the zone near each cardinal axis to prevent axis snapping.
|
|
float fAnalogAxialDeadzone;
|
|
// Response curve type: 0 = Linear, 1 = Aggressive, 2 = Relaxed, 3 = Wide
|
|
int iAnalogResponseCurve;
|
|
|
|
// Sets up how much the analog limiter button restricts digital->analog input.
|
|
float fAnalogLimiterDeadzone;
|
|
|
|
// Thresholds for triggers and stick when mapped to digital button inputs.
|
|
float fAnalogTriggerThreshold;
|
|
float fAnalogStickThreshold;
|
|
|
|
// Sets whether combo mapping is enabled.
|
|
bool bAllowMappingCombos;
|
|
bool bStrictComboOrder;
|
|
|
|
bool bMouseControl;
|
|
bool bMouseConfine; // Trap inside the window.
|
|
float fMouseSensitivity;
|
|
float fMouseSmoothing;
|
|
int iMouseWheelUpDelayMs;
|
|
|
|
// Crude Windows controller filter.
|
|
bool bAllowHIDInput;
|
|
bool bAllowXInput;
|
|
bool bAllowDInput;
|
|
|
|
bool bSystemControls;
|
|
int iRapidFireInterval;
|
|
|
|
// Use the hardware scaler to scale up the image to save fillrate. Similar to Windows' window size, really.
|
|
int iAndroidHwScale; // 0 = device resolution. 1 = 480x272 (extended to correct aspect), 2 = 960x544 etc.
|
|
|
|
// Risky JIT optimizations
|
|
bool bDiscardRegsOnJRRA;
|
|
|
|
// SystemParam
|
|
std::string sNickName; // AdHoc and system nickname
|
|
std::string sMACAddress;
|
|
|
|
int iLanguage;
|
|
int iTimeFormat;
|
|
int iDateFormat;
|
|
int iTimeZone;
|
|
bool bDayLightSavings;
|
|
int iButtonPreference;
|
|
int iLockParentalLevel;
|
|
bool bEncryptSave;
|
|
|
|
// Networking
|
|
bool bEnableAdhocServer;
|
|
std::string sProAdhocServer;
|
|
int iAdhocServerRelayMode;
|
|
bool bAdhocServerShowPlayerPorts;
|
|
std::string sInfrastructureDNSServer;
|
|
std::string sInfrastructureUsername; // Username used for Infrastructure play. Different restrictions.
|
|
bool bInfrastructureAutoDNS;
|
|
bool bAllowSavestateWhileConnected; // Developer option, ini-only. No normal users need this, it's always wrong to save/load state when online.
|
|
bool bAllowSpeedControlWhileConnected; // Useful in some games but not recommended.
|
|
|
|
std::string sAdhocServerListUrl;
|
|
std::vector<std::string> vCustomAdhocServerList;
|
|
std::vector<std::string> vCustomAdhocServerListWithRelay;
|
|
|
|
bool bEnableWlan;
|
|
std::map<std::string, std::string> mHostToAlias; // Local DNS database stored in ini file
|
|
bool bEnableUPnP;
|
|
bool bUPnPUseOriginalPort;
|
|
bool bForcedFirstConnect;
|
|
int iPortOffset;
|
|
int iMinTimeout;
|
|
int iWlanAdhocChannel;
|
|
bool bWlanPowerSave;
|
|
bool bEnableNetworkChat;
|
|
bool bDontDownloadInfraJson;
|
|
int iChatButtonPosition;
|
|
int iChatScreenPosition;
|
|
|
|
bool bEnableQuickChat;
|
|
std::string sQuickChat[5];
|
|
|
|
int iPSPModel;
|
|
int iFirmwareVersion;
|
|
bool bBypassOSKWithKeyboard;
|
|
|
|
|
|
// Virtual reality
|
|
bool bEnableVR;
|
|
bool bEnable6DoF;
|
|
bool bEnableStereo;
|
|
bool bEnableImmersiveVR;
|
|
bool bForce72Hz;
|
|
bool bForceVR;
|
|
bool bManualForceVR;
|
|
bool bPassthrough;
|
|
bool bRescaleHUD;
|
|
float fCameraDistance;
|
|
float fCameraHeight;
|
|
float fCameraSide;
|
|
float fCameraPitch;
|
|
float fCanvasDistance;
|
|
float fCanvas3DDistance;
|
|
float fFieldOfViewPercentage;
|
|
float fHeadUpDisplayScale;
|
|
|
|
// Debugger
|
|
int iDisasmWindowX;
|
|
int iDisasmWindowY;
|
|
int iDisasmWindowW;
|
|
int iDisasmWindowH;
|
|
int iGEWindowX;
|
|
int iGEWindowY;
|
|
int iGEWindowW;
|
|
int iGEWindowH;
|
|
uint32_t uGETabsLeft;
|
|
uint32_t uGETabsRight;
|
|
uint32_t uGETabsTopRight;
|
|
int iConsoleWindowX;
|
|
int iConsoleWindowY;
|
|
int iFontWidth;
|
|
int iFontHeight;
|
|
bool bShowBottomTabTitles;
|
|
bool bShowDeveloperMenu;
|
|
|
|
// Double edged sword: much easier debugging, but not accurate.
|
|
bool bSkipDeadbeefFilling;
|
|
|
|
bool bFuncHashMap;
|
|
std::string sSkipFuncHashMap;
|
|
bool bDebugMemInfoDetailed;
|
|
// Auto-save a loaded module's symbols (name/CRC keyed, shared across games that load the
|
|
// same module) to PSP/SYSTEM/SYMBOLS on unload, and auto-load them back on module load.
|
|
// See SymbolMap::SaveModuleSymbols/LoadModuleSymbols and Core/HLE/sceKernelModule.cpp.
|
|
// Also covers the symbols that aren't inside any module, which are keyed by game instead -
|
|
// see SymbolMap::GetGameSymbolsPath and Load/SaveGameSymbolsIfEnabled in Core/System.cpp.
|
|
bool bAutoSaveLoadSymbols;
|
|
|
|
// Volatile development settings
|
|
// Overlays
|
|
int iDebugOverlay;
|
|
|
|
bool bGpuLogProfiler; // Controls the Vulkan logging profiler (profiles textures uploads etc).
|
|
|
|
// Retro Achievement settings
|
|
// Copied from Duckstation, we might want to remove some.
|
|
bool bAchievementsEnable;
|
|
bool bAchievementsHardcoreMode;
|
|
bool bAchievementsEncoreMode;
|
|
bool bAchievementsUnofficial;
|
|
bool bAchievementsSoundEffects;
|
|
bool bAchievementsLogBadMemReads;
|
|
bool bAchievementsSaveStateInHardcoreMode;
|
|
bool bAchievementsEnableRAIntegration;
|
|
|
|
// Positioning of the various notifications
|
|
int iNotificationPos;
|
|
int iAchievementsLeaderboardTrackerPos;
|
|
int iAchievementsLeaderboardStartedOrFailedPos;
|
|
int iAchievementsLeaderboardSubmittedPos;
|
|
int iAchievementsProgressPos;
|
|
int iAchievementsChallengePos;
|
|
int iAchievementsUnlockedPos;
|
|
|
|
// Customizations
|
|
std::string sAchievementsUnlockAudioFile;
|
|
std::string sAchievementsLeaderboardSubmitAudioFile;
|
|
|
|
// Achivements login info. Note that password is NOT stored, only a login token.
|
|
// Still, we may wanna store it more securely than in PPSSPP.ini, especially on Android.
|
|
std::string sAchievementsUserName;
|
|
std::string sAchievementsToken; // Not saved, to be used if you want to manually make your RA login persistent. See Native_SaveSecret for the normal case.
|
|
std::string sAchievementsHost; // Optional custom host for debugging against alternate RA servers.
|
|
|
|
// Various directories. Autoconfigured, not read from ini.
|
|
Path currentDirectory; // The directory selected in the game browsing window.
|
|
Path defaultCurrentDirectory; // Platform dependent, initialized at startup.
|
|
|
|
Path memStickDirectory;
|
|
Path flash0Directory;
|
|
Path internalDataDirectory;
|
|
Path appCacheDirectory;
|
|
|
|
Path mountRoot; // Actually, mount as host0. keeping consistent with headless args.
|
|
|
|
// Data for upgrade prompt
|
|
std::string sUpgradeMessage; // The actual message from the server is currently not used, need a translation mechanism. So this just acts as a flag.
|
|
std::string sUpgradeVersion;
|
|
std::string sDismissedVersion;
|
|
|
|
void Load(const char *iniFileName = nullptr, const char *controllerIniFilename = nullptr);
|
|
bool Save(const char *saveReason);
|
|
void Reload();
|
|
void RestoreDefaults(RestoreSettingsBits whatToRestore, bool log = false);
|
|
|
|
// For bug reporting
|
|
std::string GetConfigAsString();
|
|
|
|
// Note: This doesn't switch to the config, just creates it.
|
|
bool CreateGameConfig(std::string_view gameId);
|
|
bool DeleteGameConfig(std::string_view gameId);
|
|
bool LoadGameConfig(const std::string &gameId);
|
|
bool SaveGameConfig(const std::string &pGameId, std::string_view titleForComment);
|
|
void UnloadGameConfig();
|
|
|
|
bool HasGameConfig(std::string_view gameId);
|
|
bool IsGameSpecific() const { return !gameId_.empty(); }
|
|
|
|
void SetSearchPath(const Path &path);
|
|
|
|
void UpdateIniLocation(const char *iniFileName = nullptr, const char *controllerIniFilename = nullptr);
|
|
|
|
bool SupportsUpgradeCheck() const;
|
|
void CheckForUpdate();
|
|
void VersionJsonDownloadCompleted(http::Request &download);
|
|
void DismissUpgrade();
|
|
bool ShowUpgradeReminder();
|
|
|
|
void GetReportingInfo(UrlEncoder &data) const;
|
|
|
|
int NextValidBackend();
|
|
bool IsBackendEnabled(GPUBackend backend);
|
|
|
|
bool LoadAppendedConfig();
|
|
void SetAppendedConfigIni(const Path &path) { appendedConfigFileName_ = path; }
|
|
void UpdateAfterSettingAutoFrameSkip();
|
|
void NotifyUpdatedCpuCore();
|
|
|
|
PlayTimeTracker &TimeTracker() { return playTimeTracker_; }
|
|
|
|
const DisplayLayoutConfig &GetDisplayLayoutConfig(DeviceOrientation orientation) const {
|
|
return orientation == DeviceOrientation::Portrait ? displayLayoutPortrait : displayLayoutLandscape;
|
|
}
|
|
DisplayLayoutConfig &GetDisplayLayoutConfig(DeviceOrientation orientation) {
|
|
return orientation == DeviceOrientation::Portrait ? displayLayoutPortrait : displayLayoutLandscape;
|
|
}
|
|
const TouchControlConfig &GetTouchControlsConfig(DeviceOrientation orientation) const {
|
|
return orientation == DeviceOrientation::Portrait ? touchControlsPortrait : touchControlsLandscape;
|
|
}
|
|
TouchControlConfig &GetTouchControlsConfig(DeviceOrientation orientation) {
|
|
return orientation == DeviceOrientation::Portrait ? touchControlsPortrait : touchControlsLandscape;
|
|
}
|
|
|
|
static int GetDefaultValueInt(int *configSetting);
|
|
|
|
void DoNotSaveSetting(void *configSetting) {
|
|
settingsNotToSave_.push_back(configSetting);
|
|
}
|
|
|
|
private:
|
|
void LoadStandardControllerIni();
|
|
|
|
void PostLoadCleanup();
|
|
void PreSaveCleanup();
|
|
void PostSaveCleanup();
|
|
|
|
friend struct ConfigSetting;
|
|
|
|
static std::map<const void *, std::pair<const ConfigBlock *, const ConfigSetting *>> &getPtrLUT();
|
|
|
|
// Applies defaults for missing settings.
|
|
void ReadAllSettings(const IniFile &iniFile);
|
|
|
|
bool inReload_ = false;
|
|
|
|
// If not empty, we're using a game-specific config.
|
|
std::string gameId_;
|
|
|
|
PlayTimeTracker playTimeTracker_;
|
|
|
|
// Always the paths to the main configs, doesn't change with game-specific overlay.
|
|
Path iniFilename_;
|
|
Path controllerIniFilename_;
|
|
|
|
Path searchPath_;
|
|
Path appendedConfigFileName_;
|
|
// A set make more sense, but won't have many entry, and I dont want to include the whole std::set header here
|
|
std::vector<std::string> appendedConfigUpdatedGames_;
|
|
std::vector<void *> settingsNotToSave_;
|
|
|
|
bool ShouldSaveSetting(const void *configSetting) const;
|
|
};
|
|
|
|
std::string CreateRandMAC();
|
|
std::string DefaultProAdhocServer();
|
|
|
|
// TODO: Find a better place for this.
|
|
extern http::RequestManager g_DownloadManager;
|
|
extern Config g_Config;
|