diff --git a/CMakeLists.txt b/CMakeLists.txt index 386f4e6eaf..8ae5fa9024 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1381,6 +1381,7 @@ add_library(${CoreLibName} ${CoreLinkType} ${CoreExtra} Core/Config.cpp Core/Config.h + Core/ConfigValues.h Core/Core.cpp Core/Core.h Core/Compatibility.cpp diff --git a/Common/KeyMap.cpp b/Common/KeyMap.cpp index ffe76c87a0..092ca95144 100644 --- a/Common/KeyMap.cpp +++ b/Common/KeyMap.cpp @@ -645,6 +645,8 @@ const KeyMap_IntStrPair psp_button_names[] = { {VIRTKEY_RAPID_FIRE, "RapidFire"}, {VIRTKEY_UNTHROTTLE, "Unthrottle"}, {VIRTKEY_SPEED_TOGGLE, "SpeedToggle"}, + {VIRTKEY_SPEED_CUSTOM1, "Alt speed 1"}, + {VIRTKEY_SPEED_CUSTOM2, "Alt speed 2"}, {VIRTKEY_PAUSE, "Pause"}, #ifndef MOBILE_DEVICE {VIRTKEY_FRAME_ADVANCE, "Frame Advance"}, diff --git a/Common/KeyMap.h b/Common/KeyMap.h index fd56d4d8f5..9f408ed7f6 100644 --- a/Common/KeyMap.h +++ b/Common/KeyMap.h @@ -52,6 +52,8 @@ enum { VIRTKEY_DEVMENU = 0x40000014, VIRTKEY_FRAME_ADVANCE = 0x40000015, VIRTKEY_RECORD = 0x40000016, + VIRTKEY_SPEED_CUSTOM1 = 0x40000017, + VIRTKEY_SPEED_CUSTOM2 = 0x40000018, VIRTKEY_LAST, VIRTKEY_COUNT = VIRTKEY_LAST - VIRTKEY_FIRST }; diff --git a/Core/Config.cpp b/Core/Config.cpp index 2751ae147f..4d6061a49f 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -38,6 +38,7 @@ #include "Common/StringUtils.h" #include "Common/Vulkan/VulkanLoader.h" #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "Core/Loaders.h" #include "Core/HLE/sceUtility.h" #include "GPU/Common/FramebufferCommon.h" @@ -63,6 +64,7 @@ struct ConfigSetting { TYPE_UINT32, TYPE_FLOAT, TYPE_STRING, + TYPE_TOUCH_POS, }; union Value { bool b; @@ -70,6 +72,7 @@ struct ConfigSetting { uint32_t u; float f; const char *s; + ConfigTouchPos touchPos; }; union SettingPtr { bool *b; @@ -77,6 +80,7 @@ struct ConfigSetting { uint32_t *u; float *f; std::string *s; + ConfigTouchPos *touchPos; }; typedef bool (*BoolDefaultCallback)(); @@ -84,6 +88,7 @@ struct ConfigSetting { typedef uint32_t (*Uint32DefaultCallback)(); typedef float (*FloatDefaultCallback)(); typedef const char *(*StringDefaultCallback)(); + typedef ConfigTouchPos (*TouchPosDefaultCallback)(); union Callback { BoolDefaultCallback b; @@ -91,6 +96,7 @@ struct ConfigSetting { Uint32DefaultCallback u; FloatDefaultCallback f; StringDefaultCallback s; + TouchPosDefaultCallback touchPos; }; ConfigSetting(bool v) @@ -134,6 +140,13 @@ struct ConfigSetting { default_.s = def; } + ConfigSetting(const char *iniX, const char *iniY, const char *iniScale, const char *iniShow, ConfigTouchPos *v, ConfigTouchPos def, bool save = true, bool perGame = false) + : ini_(iniX), ini2_(iniY), ini3_(iniScale), ini4_(iniShow), type_(TYPE_TOUCH_POS), report_(false), save_(save), perGame_(perGame) { + ptr_.touchPos = v; + cb_.touchPos = nullptr; + default_.touchPos = def; + } + ConfigSetting(const char *ini, bool *v, BoolDefaultCallback def, bool save = true, bool perGame = false) : ini_(ini), type_(TYPE_BOOL), report_(false), save_(save), perGame_(perGame) { ptr_.b = v; @@ -164,6 +177,12 @@ struct ConfigSetting { cb_.s = def; } + ConfigSetting(const char *iniX, const char *iniY, const char *iniScale, const char *iniShow, ConfigTouchPos *v, TouchPosDefaultCallback def, bool save = true, bool perGame = false) + : ini_(iniX), ini2_(iniY), ini3_(iniScale), ini4_(iniShow), type_(TYPE_TOUCH_POS), report_(false), save_(save), perGame_(perGame) { + ptr_.touchPos = v; + cb_.touchPos = def; + } + bool HasMore() const { return type_ != TYPE_TERMINATOR; } @@ -195,6 +214,19 @@ struct ConfigSetting { default_.s = cb_.s(); } return section->Get(ini_, ptr_.s, default_.s); + case TYPE_TOUCH_POS: + if (cb_.touchPos) { + default_.touchPos = cb_.touchPos(); + } + section->Get(ini_, &ptr_.touchPos->x, default_.touchPos.x); + section->Get(ini2_, &ptr_.touchPos->y, default_.touchPos.y); + section->Get(ini3_, &ptr_.touchPos->scale, default_.touchPos.scale); + if (ini4_) { + section->Get(ini4_, &ptr_.touchPos->show, default_.touchPos.show); + } else { + ptr_.touchPos->show = default_.touchPos.show; + } + return true; default: _dbg_assert_msg_(LOADER, false, "Unexpected ini setting type"); return false; @@ -216,6 +248,14 @@ struct ConfigSetting { return section->Set(ini_, *ptr_.f); case TYPE_STRING: return section->Set(ini_, *ptr_.s); + case TYPE_TOUCH_POS: + section->Set(ini_, ptr_.touchPos->x); + section->Set(ini2_, ptr_.touchPos->y); + section->Set(ini3_, ptr_.touchPos->scale); + if (ini4_) { + section->Set(ini4_, ptr_.touchPos->show); + } + return; default: _dbg_assert_msg_(LOADER, false, "Unexpected ini setting type"); return; @@ -237,6 +277,9 @@ struct ConfigSetting { return data.Add(prefix + ini_, *ptr_.f); case TYPE_STRING: return data.Add(prefix + ini_, *ptr_.s); + case TYPE_TOUCH_POS: + // Doesn't report. + return; default: _dbg_assert_msg_(LOADER, false, "Unexpected ini setting type"); return; @@ -244,6 +287,9 @@ struct ConfigSetting { } const char *ini_; + const char *ini2_; + const char *ini3_; + const char *ini4_; Type type_; bool report_; bool save_; @@ -383,9 +429,9 @@ static ConfigSetting generalSettings[] = { ConfigSetting("RemoteDebuggerOnStartup", &g_Config.bRemoteDebuggerOnStartup, false), #ifdef __ANDROID__ - ConfigSetting("ScreenRotation", &g_Config.iScreenRotation, 1), + ConfigSetting("ScreenRotation", &g_Config.iScreenRotation, ROTATION_LOCKED_HORIZONTAL), #endif - ConfigSetting("InternalScreenRotation", &g_Config.iInternalScreenRotation, 1), + ConfigSetting("InternalScreenRotation", &g_Config.iInternalScreenRotation, ROTATION_LOCKED_HORIZONTAL), #if defined(USING_WIN_UI) ConfigSetting("TopMost", &g_Config.bTopMost, false), @@ -453,7 +499,7 @@ static bool DefaultFrameskipUnthrottle() { } static int DefaultZoomType() { - return 2; + return (int)SmallDisplayZoom::AUTO; } static bool DefaultTimerHack() { @@ -518,13 +564,14 @@ static ConfigSetting graphicsSettings[] = { ReportedConfigSetting("HardwareTransform", &g_Config.bHardwareTransform, true, true, true), ReportedConfigSetting("SoftwareSkinning", &g_Config.bSoftwareSkinning, true, true, true), ReportedConfigSetting("TextureFiltering", &g_Config.iTexFiltering, 1, true, true), - ReportedConfigSetting("BufferFiltering", &g_Config.iBufFilter, 1, true, true), + ReportedConfigSetting("BufferFiltering", &g_Config.iBufFilter, SCALE_LINEAR, true, true), ReportedConfigSetting("InternalResolution", &g_Config.iInternalResolution, &DefaultInternalResolution, true, true), ReportedConfigSetting("AndroidHwScale", &g_Config.iAndroidHwScale, &DefaultAndroidHwScale), ReportedConfigSetting("HighQualityDepth", &g_Config.bHighQualityDepth, true, true, true), ReportedConfigSetting("FrameSkip", &g_Config.iFrameSkip, 0, true, true), ReportedConfigSetting("AutoFrameSkip", &g_Config.bAutoFrameSkip, false, true, true), - ConfigSetting("FrameRate", &g_Config.iFpsLimit, 0, true, true), + ConfigSetting("FrameRate", &g_Config.iFpsLimit1, 0, true, true), + ConfigSetting("FrameRate2", &g_Config.iFpsLimit2, -1, true, true), ConfigSetting("FrameSkipUnthrottle", &g_Config.bFrameSkipUnthrottle, &DefaultFrameskipUnthrottle, true, false), #if defined(USING_WIN_UI) ConfigSetting("RestartRequired", &g_Config.bRestartRequired, false, false), @@ -610,6 +657,8 @@ static bool DefaultShowTouchControls() { } static const float defaultControlScale = 1.15f; +static const ConfigTouchPos defaultTouchPosShow = { -1.0f, -1.0f, defaultControlScale, true }; +static const ConfigTouchPos defaultTouchPosHide = { -1.0f, -1.0f, defaultControlScale, false }; static ConfigSetting controlSettings[] = { ConfigSetting("HapticFeedback", &g_Config.bHapticFeedback, false, true, true), @@ -617,19 +666,7 @@ static ConfigSetting controlSettings[] = { ConfigSetting("ShowTouchCircle", &g_Config.bShowTouchCircle, true, true, true), ConfigSetting("ShowTouchSquare", &g_Config.bShowTouchSquare, true, true, true), ConfigSetting("ShowTouchTriangle", &g_Config.bShowTouchTriangle, true, true, true), - ConfigSetting("ShowTouchStart", &g_Config.bShowTouchStart, true, true, true), - ConfigSetting("ShowTouchSelect", &g_Config.bShowTouchSelect, true, true, true), - ConfigSetting("ShowTouchLTrigger", &g_Config.bShowTouchLTrigger, true, true, true), - ConfigSetting("ShowTouchRTrigger", &g_Config.bShowTouchRTrigger, true, true, true), - ConfigSetting("ShowAnalogStick", &g_Config.bShowTouchAnalogStick, true, true, true), - ConfigSetting("ShowTouchDpad", &g_Config.bShowTouchDpad, true, true, true), - ConfigSetting("ShowTouchUnthrottle", &g_Config.bShowTouchUnthrottle, true, true, true), - ConfigSetting("ShowComboKey0", &g_Config.bShowComboKey0, false, true, true), - ConfigSetting("ShowComboKey1", &g_Config.bShowComboKey1, false, true, true), - ConfigSetting("ShowComboKey2", &g_Config.bShowComboKey2, false, true, true), - ConfigSetting("ShowComboKey3", &g_Config.bShowComboKey3, false, true, true), - ConfigSetting("ShowComboKey4", &g_Config.bShowComboKey4, false, true, true), ConfigSetting("ComboKey0Mapping", &g_Config.iCombokey0, 0, true, true), ConfigSetting("ComboKey1Mapping", &g_Config.iCombokey1, 0, true, true), ConfigSetting("ComboKey2Mapping", &g_Config.iCombokey2, 0, true, true), @@ -669,49 +706,26 @@ static ConfigSetting controlSettings[] = { // -1.0f means uninitialized, set in GamepadEmu::CreatePadLayout(). ConfigSetting("ActionButtonSpacing2", &g_Config.fActionButtonSpacing, 1.0f, true, true), - ConfigSetting("ActionButtonCenterX", &g_Config.fActionButtonCenterX, -1.0f, true, true), - ConfigSetting("ActionButtonCenterY", &g_Config.fActionButtonCenterY, -1.0f, true, true), - ConfigSetting("ActionButtonScale", &g_Config.fActionButtonScale, defaultControlScale, true, true), - ConfigSetting("DPadX", &g_Config.fDpadX, -1.0f, true, true), - ConfigSetting("DPadY", &g_Config.fDpadY, -1.0f, true, true), + ConfigSetting("ActionButtonCenterX", "ActionButtonCenterY", "ActionButtonScale", nullptr, &g_Config.touchActionButtonCenter, defaultTouchPosShow, true, true), + ConfigSetting("DPadX", "DPadY", "DPadScale", "ShowTouchDpad", &g_Config.touchDpad, defaultTouchPosShow, true, true), // Note: these will be overwritten if DPadRadius is set. - ConfigSetting("DPadScale", &g_Config.fDpadScale, defaultControlScale, true, true), ConfigSetting("DPadSpacing", &g_Config.fDpadSpacing, 1.0f, true, true), - ConfigSetting("StartKeyX", &g_Config.fStartKeyX, -1.0f, true, true), - ConfigSetting("StartKeyY", &g_Config.fStartKeyY, -1.0f, true, true), - ConfigSetting("StartKeyScale", &g_Config.fStartKeyScale, defaultControlScale, true, true), - ConfigSetting("SelectKeyX", &g_Config.fSelectKeyX, -1.0f, true, true), - ConfigSetting("SelectKeyY", &g_Config.fSelectKeyY, -1.0f, true, true), - ConfigSetting("SelectKeyScale", &g_Config.fSelectKeyScale, defaultControlScale, true, true), - ConfigSetting("UnthrottleKeyX", &g_Config.fUnthrottleKeyX, -1.0f, true, true), - ConfigSetting("UnthrottleKeyY", &g_Config.fUnthrottleKeyY, -1.0f, true, true), - ConfigSetting("UnthrottleKeyScale", &g_Config.fUnthrottleKeyScale, defaultControlScale, true, true), - ConfigSetting("LKeyX", &g_Config.fLKeyX, -1.0f, true, true), - ConfigSetting("LKeyY", &g_Config.fLKeyY, -1.0f, true, true), - ConfigSetting("LKeyScale", &g_Config.fLKeyScale, defaultControlScale, true, true), - ConfigSetting("RKeyX", &g_Config.fRKeyX, -1.0f, true, true), - ConfigSetting("RKeyY", &g_Config.fRKeyY, -1.0f, true, true), - ConfigSetting("RKeyScale", &g_Config.fRKeyScale, defaultControlScale, true, true), - ConfigSetting("AnalogStickX", &g_Config.fAnalogStickX, -1.0f, true, true), - ConfigSetting("AnalogStickY", &g_Config.fAnalogStickY, -1.0f, true, true), - ConfigSetting("AnalogStickScale", &g_Config.fAnalogStickScale, defaultControlScale, true, true), + ConfigSetting("StartKeyX", "StartKeyY", "StartKeyScale", "ShowTouchStart", &g_Config.touchStartKey, defaultTouchPosShow, true, true), + ConfigSetting("SelectKeyX", "SelectKeyY", "SelectKeyScale", "ShowTouchSelect", &g_Config.touchSelectKey, defaultTouchPosShow, true, true), + ConfigSetting("UnthrottleKeyX", "UnthrottleKeyY", "UnthrottleKeyScale", "ShowTouchUnthrottle", &g_Config.touchUnthrottleKey, defaultTouchPosShow, true, true), + ConfigSetting("LKeyX", "LKeyY", "LKeyScale", "ShowTouchLTrigger", &g_Config.touchLKey, defaultTouchPosShow, true, true), + ConfigSetting("RKeyX", "RKeyY", "RKeyScale", "ShowTouchRTrigger", &g_Config.touchRKey, defaultTouchPosShow, true, true), + ConfigSetting("AnalogStickX", "AnalogStickY", "AnalogStickScale", "ShowAnalogStick", &g_Config.touchAnalogStick, defaultTouchPosShow, true, true), + + ConfigSetting("fcombo0X", "fcombo0Y", "comboKeyScale0", "ShowComboKey0", &g_Config.touchCombo0, defaultTouchPosHide, true, true), + ConfigSetting("fcombo1X", "fcombo1Y", "comboKeyScale1", "ShowComboKey1", &g_Config.touchCombo1, defaultTouchPosHide, true, true), + ConfigSetting("fcombo2X", "fcombo2Y", "comboKeyScale2", "ShowComboKey2", &g_Config.touchCombo2, defaultTouchPosHide, true, true), + ConfigSetting("fcombo3X", "fcombo3Y", "comboKeyScale3", "ShowComboKey3", &g_Config.touchCombo3, defaultTouchPosHide, true, true), + ConfigSetting("fcombo4X", "fcombo4Y", "comboKeyScale4", "ShowComboKey4", &g_Config.touchCombo4, defaultTouchPosHide, true, true), + ConfigSetting("Speed1KeyX", "Speed1KeyY", "Speed1KeyScale", "ShowSpeed1Key", &g_Config.touchSpeed1Key, defaultTouchPosHide, true, true), + ConfigSetting("Speed2KeyX", "Speed2KeyY", "Speed2KeyScale", "ShowSpeed2Key", &g_Config.touchSpeed2Key, defaultTouchPosHide, true, true), - ConfigSetting("fcombo0X", &g_Config.fcombo0X, -1.0f, true, true), - ConfigSetting("fcombo0Y", &g_Config.fcombo0Y, -1.0f, true, true), - ConfigSetting("comboKeyScale0", &g_Config.fcomboScale0, defaultControlScale, true, true), - ConfigSetting("fcombo1X", &g_Config.fcombo1X, -1.0f, true, true), - ConfigSetting("fcombo1Y", &g_Config.fcombo1Y, -1.0f, true, true), - ConfigSetting("comboKeyScale1", &g_Config.fcomboScale1, defaultControlScale, true, true), - ConfigSetting("fcombo2X", &g_Config.fcombo2X, -1.0f, true, true), - ConfigSetting("fcombo2Y", &g_Config.fcombo2Y, -1.0f, true, true), - ConfigSetting("comboKeyScale2", &g_Config.fcomboScale2, defaultControlScale, true, true), - ConfigSetting("fcombo3X", &g_Config.fcombo3X, -1.0f, true, true), - ConfigSetting("fcombo3Y", &g_Config.fcombo3Y, -1.0f, true, true), - ConfigSetting("comboKeyScale3", &g_Config.fcomboScale3, defaultControlScale, true, true), - ConfigSetting("fcombo4X", &g_Config.fcombo4X, -1.0f, true, true), - ConfigSetting("fcombo4Y", &g_Config.fcombo4Y, -1.0f, true, true), - ConfigSetting("comboKeyScale4", &g_Config.fcomboScale4, defaultControlScale, true, true), #ifdef _WIN32 ConfigSetting("DInputAnalogDeadzone", &g_Config.fDInputAnalogDeadzone, 0.1f, true, true), ConfigSetting("DInputAnalogInverseMode", &g_Config.iDInputAnalogInverseMode, 0, true, true), @@ -999,40 +1013,6 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename) { ResetControlLayout(); } - // MIGRATION: For users who had the old static touch layout, aren't I nice? - // We can probably kill this in 0.9.8 or something. - if (fDpadX > 1.0 || fDpadY > 1.0) { // Likely the rest are too! - float screen_width = dp_xres; - float screen_height = dp_yres; - - fActionButtonCenterX /= screen_width; - fActionButtonCenterY /= screen_height; - fDpadX /= screen_width; - fDpadY /= screen_height; - fStartKeyX /= screen_width; - fStartKeyY /= screen_height; - fSelectKeyX /= screen_width; - fSelectKeyY /= screen_height; - fUnthrottleKeyX /= screen_width; - fUnthrottleKeyY /= screen_height; - fLKeyX /= screen_width; - fLKeyY /= screen_height; - fRKeyX /= screen_width; - fRKeyY /= screen_height; - fAnalogStickX /= screen_width; - fAnalogStickY /= screen_height; - fcombo0X /= screen_width; - fcombo0Y /= screen_height; - fcombo1X /= screen_width; - fcombo1Y /= screen_height; - fcombo2X /= screen_width; - fcombo2Y /= screen_height; - fcombo3X /= screen_width; - fcombo3Y /= screen_height; - fcombo4X /= screen_width; - fcombo4Y /= screen_height; - } - const char *gitVer = PPSSPP_GIT_VERSION; Version installed(gitVer); Version upgrade(upgradeVersion); @@ -1430,47 +1410,28 @@ void Config::LoadStandardControllerIni() { } void Config::ResetControlLayout() { - g_Config.fActionButtonScale = defaultControlScale; + auto reset = [](ConfigTouchPos &pos) { + pos.x = defaultTouchPosShow.x; + pos.y = defaultTouchPosShow.y; + pos.scale = defaultTouchPosShow.scale; + }; + reset(g_Config.touchActionButtonCenter); g_Config.fActionButtonSpacing = 1.0f; - g_Config.fActionButtonCenterX = -1.0; - g_Config.fActionButtonCenterY = -1.0; - g_Config.fDpadScale = defaultControlScale; + reset(g_Config.touchDpad); g_Config.fDpadSpacing = 1.0f; - g_Config.fDpadX = -1.0; - g_Config.fDpadY = -1.0; - g_Config.fStartKeyX = -1.0; - g_Config.fStartKeyY = -1.0; - g_Config.fStartKeyScale = defaultControlScale; - g_Config.fSelectKeyX = -1.0; - g_Config.fSelectKeyY = -1.0; - g_Config.fSelectKeyScale = defaultControlScale; - g_Config.fUnthrottleKeyX = -1.0; - g_Config.fUnthrottleKeyY = -1.0; - g_Config.fUnthrottleKeyScale = defaultControlScale; - g_Config.fLKeyX = -1.0; - g_Config.fLKeyY = -1.0; - g_Config.fLKeyScale = defaultControlScale; - g_Config.fRKeyX = -1.0; - g_Config.fRKeyY = -1.0; - g_Config.fRKeyScale = defaultControlScale; - g_Config.fAnalogStickX = -1.0; - g_Config.fAnalogStickY = -1.0; - g_Config.fAnalogStickScale = defaultControlScale; - g_Config.fcombo0X = -1.0; - g_Config.fcombo0Y = -1.0; - g_Config.fcomboScale0 = defaultControlScale; - g_Config.fcombo1X = -1.0f; - g_Config.fcombo1Y = -1.0f; - g_Config.fcomboScale1 = defaultControlScale; - g_Config.fcombo2X = -1.0f; - g_Config.fcombo2Y = -1.0f; - g_Config.fcomboScale2 = defaultControlScale; - g_Config.fcombo3X = -1.0f; - g_Config.fcombo3Y = -1.0f; - g_Config.fcomboScale3 = defaultControlScale; - g_Config.fcombo4X = -1.0f; - g_Config.fcombo4Y = -1.0f; - g_Config.fcomboScale4 = defaultControlScale; + reset(g_Config.touchStartKey); + reset(g_Config.touchSelectKey); + reset(g_Config.touchUnthrottleKey); + reset(g_Config.touchLKey); + reset(g_Config.touchRKey); + reset(g_Config.touchAnalogStick); + reset(g_Config.touchCombo0); + reset(g_Config.touchCombo1); + reset(g_Config.touchCombo2); + reset(g_Config.touchCombo3); + reset(g_Config.touchCombo4); + reset(g_Config.touchSpeed1Key); + reset(g_Config.touchSpeed2Key); } void Config::GetReportingInfo(UrlEncoder &data) { @@ -1481,3 +1442,7 @@ void Config::GetReportingInfo(UrlEncoder &data) { } } } + +bool Config::IsPortrait() const { + return (iInternalScreenRotation == ROTATION_LOCKED_VERTICAL || iInternalScreenRotation == ROTATION_LOCKED_VERTICAL180) && iRenderingMode != FB_NON_BUFFERED_MODE; +} diff --git a/Core/Config.h b/Core/Config.h index 978b15614f..9223cfde7a 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -25,52 +25,6 @@ extern const char *PPSSPP_GIT_VERSION; -const int PSP_MODEL_FAT = 0; -const int PSP_MODEL_SLIM = 1; -const int PSP_DEFAULT_FIRMWARE = 660; -static const s8 VOLUME_OFF = 0; -static const s8 VOLUME_MAX = 10; - -enum class CPUCore { - INTERPRETER = 0, - JIT = 1, - IR_JIT = 2, -}; - -enum { - ROTATION_AUTO = 0, - ROTATION_LOCKED_HORIZONTAL = 1, - ROTATION_LOCKED_VERTICAL = 2, - ROTATION_LOCKED_HORIZONTAL180 = 3, - ROTATION_LOCKED_VERTICAL180 = 4, -}; - -enum BufferFilter { - SCALE_LINEAR = 1, - SCALE_NEAREST = 2, -}; - -// Software is not among these because it will have one of these perform the blit to display. -enum class GPUBackend { - OPENGL = 0, - DIRECT3D9 = 1, - DIRECT3D11 = 2, - VULKAN = 3, -}; - -enum AudioBackendType { - AUDIO_BACKEND_AUTO, - AUDIO_BACKEND_DSOUND, - AUDIO_BACKEND_WASAPI, -}; - -// For iIOTimingMethod. -enum IOTimingMethods { - IOTIMING_FAST = 0, - IOTIMING_HOST = 1, - IOTIMING_REALISTIC = 2, -}; - namespace http { class Download; class Downloader; @@ -78,6 +32,14 @@ namespace http { struct UrlEncoder; +struct ConfigTouchPos { + float x; + float y; + float scale; + // Note: Show is not used for all settings. + bool show; +}; + struct Config { public: Config(); @@ -203,10 +165,11 @@ public: bool bTrueColor; bool bReplaceTextures; bool bSaveNewTextures; - int iTexScalingLevel; // 1 = off, 2 = 2x, ..., 5 = 5x + int iTexScalingLevel; // 0 = auto, 1 = off, 2 = 2x, ..., 5 = 5x int iTexScalingType; // 0 = xBRZ, 1 = Hybrid bool bTexDeposterize; - int iFpsLimit; + int iFpsLimit1; + int iFpsLimit2; int iForceMaxEmulatedFPS; int iMaxRecent; int iCurrentStateSlot; @@ -312,46 +275,27 @@ public: //space between PSP buttons //the PSP button's center (triangle, circle, square, cross) - float fActionButtonCenterX, fActionButtonCenterY; - float fActionButtonScale; + ConfigTouchPos touchActionButtonCenter; float fActionButtonSpacing; //radius of the D-pad (PSP cross) // int iDpadRadius; //the D-pad (PSP cross) position - float fDpadX, fDpadY; - float fDpadScale; + ConfigTouchPos touchDpad; float fDpadSpacing; - //the start key position - float fStartKeyX, fStartKeyY; - float fStartKeyScale; - //the select key position; - float fSelectKeyX, fSelectKeyY; - float fSelectKeyScale; + ConfigTouchPos touchStartKey; + ConfigTouchPos touchSelectKey; + ConfigTouchPos touchUnthrottleKey; + ConfigTouchPos touchLKey; + ConfigTouchPos touchRKey; + ConfigTouchPos touchAnalogStick; - float fUnthrottleKeyX, fUnthrottleKeyY; - float fUnthrottleKeyScale; - - float fLKeyX, fLKeyY; - float fLKeyScale; - - float fRKeyX, fRKeyY; - float fRKeyScale; - - //position of the analog stick - float fAnalogStickX, fAnalogStickY; - float fAnalogStickScale; - - //the Combo Button position - float fcombo0X, fcombo0Y; - float fcomboScale0; - float fcombo1X, fcombo1Y; - float fcomboScale1; - float fcombo2X, fcombo2Y; - float fcomboScale2; - float fcombo3X, fcombo3Y; - float fcomboScale3; - float fcombo4X, fcombo4Y; - float fcomboScale4; + ConfigTouchPos touchCombo0; + ConfigTouchPos touchCombo1; + ConfigTouchPos touchCombo2; + ConfigTouchPos touchCombo3; + ConfigTouchPos touchCombo4; + ConfigTouchPos touchSpeed1Key; + ConfigTouchPos touchSpeed2Key; // Controls Visibility bool bShowTouchControls; @@ -361,23 +305,6 @@ public: bool bShowTouchTriangle; bool bShowTouchSquare; - bool bShowTouchStart; - bool bShowTouchSelect; - bool bShowTouchUnthrottle; - - bool bShowTouchLTrigger; - bool bShowTouchRTrigger; - - bool bShowTouchAnalogStick; - bool bShowTouchDpad; - - //Combo Button Visibility - bool bShowComboKey0; - bool bShowComboKey1; - bool bShowComboKey2; - bool bShowComboKey3; - bool bShowComboKey4; - // Combo_key mapping. These are bitfields. int iCombokey0; int iCombokey1; @@ -510,9 +437,7 @@ public: void GetReportingInfo(UrlEncoder &data); - bool IsPortrait() const { - return (iInternalScreenRotation == ROTATION_LOCKED_VERTICAL || iInternalScreenRotation == ROTATION_LOCKED_VERTICAL180) && iRenderingMode != 0; - } + bool IsPortrait() const; protected: void LoadStandardControllerIni(); diff --git a/Core/ConfigValues.h b/Core/ConfigValues.h new file mode 100644 index 0000000000..bc2df61f37 --- /dev/null +++ b/Core/ConfigValues.h @@ -0,0 +1,73 @@ +// 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 + +const int PSP_MODEL_FAT = 0; +const int PSP_MODEL_SLIM = 1; +const int PSP_DEFAULT_FIRMWARE = 660; +static const int8_t VOLUME_OFF = 0; +static const int8_t VOLUME_MAX = 10; + +enum class CPUCore { + INTERPRETER = 0, + JIT = 1, + IR_JIT = 2, +}; + +enum { + ROTATION_AUTO = 0, + ROTATION_LOCKED_HORIZONTAL = 1, + ROTATION_LOCKED_VERTICAL = 2, + ROTATION_LOCKED_HORIZONTAL180 = 3, + ROTATION_LOCKED_VERTICAL180 = 4, +}; + +enum BufferFilter { + SCALE_LINEAR = 1, + SCALE_NEAREST = 2, +}; + +// Software is not among these because it will have one of these perform the blit to display. +enum class GPUBackend { + OPENGL = 0, + DIRECT3D9 = 1, + DIRECT3D11 = 2, + VULKAN = 3, +}; + +enum AudioBackendType { + AUDIO_BACKEND_AUTO, + AUDIO_BACKEND_DSOUND, + AUDIO_BACKEND_WASAPI, +}; + +// For iIOTimingMethod. +enum IOTimingMethods { + IOTIMING_FAST = 0, + IOTIMING_HOST = 1, + IOTIMING_REALISTIC = 2, +}; + +enum class SmallDisplayZoom { + STRETCH = 0, + PARTIAL_STRETCH = 1, + AUTO = 2, + MANUAL = 3, +}; diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj index a8765dac4c..c0751c917a 100644 --- a/Core/Core.vcxproj +++ b/Core/Core.vcxproj @@ -544,6 +544,7 @@ + diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters index 6e86aea5b2..b398758157 100644 --- a/Core/Core.vcxproj.filters +++ b/Core/Core.vcxproj.filters @@ -1352,6 +1352,9 @@ Debugger\WebSocket + + Core + diff --git a/Core/CoreParameter.h b/Core/CoreParameter.h index 2f71d4c10d..736ecd9797 100644 --- a/Core/CoreParameter.h +++ b/Core/CoreParameter.h @@ -31,6 +31,12 @@ enum GPUCore { GPUCORE_VULKAN, }; +enum class FPSLimit { + NORMAL = 0, + CUSTOM1 = 1, + CUSTOM2 = 2, +}; + class FileLoader; class GraphicsContext; @@ -42,13 +48,13 @@ enum class CPUCore; // PSP_CoreParameter() struct CoreParameter { - CoreParameter() : thin3d(nullptr), collectEmuLog(0), unthrottle(false), fpsLimit(0), updateRecent(true), freezeNext(false), frozen(false), mountIsoLoader(nullptr) {} + CoreParameter() {} CPUCore cpuCore; GPUCore gpuCore; - GraphicsContext *graphicsContext; // TODO: Find a better place. - Draw::DrawContext *thin3d; + GraphicsContext *graphicsContext = nullptr; // TODO: Find a better place. + Draw::DrawContext *thin3d = nullptr; bool enableSound; // there aren't multiple sound cores. std::string fileToStart; @@ -58,7 +64,7 @@ struct CoreParameter { bool startBreak; bool printfEmuLog; // writes "emulator:" logging to stdout - std::string *collectEmuLog; + std::string *collectEmuLog = nullptr; bool headLess; // Try to avoid messageboxes etc // Internal PSP resolution @@ -70,16 +76,16 @@ struct CoreParameter { int pixelHeight; // Can be modified at runtime. - bool unthrottle; - int fpsLimit; + bool unthrottle = false; + FPSLimit fpsLimit = FPSLimit::NORMAL; - bool updateRecent; + bool updateRecent = true; // Freeze-frame. For nvidia perfhud profiling. Developers only. - bool freezeNext; - bool frozen; + bool freezeNext = false; + bool frozen = false; - FileLoader *mountIsoLoader; + FileLoader *mountIsoLoader = nullptr; Compatibility compat; }; diff --git a/Core/HLE/sceDisplay.cpp b/Core/HLE/sceDisplay.cpp index 42c8bd6310..b86d467df8 100644 --- a/Core/HLE/sceDisplay.cpp +++ b/Core/HLE/sceDisplay.cpp @@ -476,17 +476,17 @@ void __DisplayGetDebugStats(char *stats, size_t bufsize) { statbuf); } -enum { - FPS_LIMIT_NORMAL = 0, - FPS_LIMIT_CUSTOM = 1, -}; + void __DisplaySetWasPaused() { wasPaused = true; } static bool FrameTimingThrottled() { - if (PSP_CoreParameter().fpsLimit == FPS_LIMIT_CUSTOM && g_Config.iFpsLimit == 0) { + if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM1 && g_Config.iFpsLimit1 == 0) { + return false; + } + if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM2 && g_Config.iFpsLimit2 == 0) { return false; } return !PSP_CoreParameter().unthrottle; @@ -505,7 +505,7 @@ static void DoFrameDropLogging(float scaledTimestep) { // Let's collect all the throttling and frameskipping logic here. static void DoFrameTiming(bool &throttle, bool &skipFrame, float timestep) { PROFILE_THIS_SCOPE("timing"); - int fpsLimiter = PSP_CoreParameter().fpsLimit; + FPSLimit fpsLimiter = PSP_CoreParameter().fpsLimit; throttle = FrameTimingThrottled(); skipFrame = false; @@ -528,8 +528,10 @@ static void DoFrameTiming(bool &throttle, bool &skipFrame, float timestep) { time_update(); float scaledTimestep = timestep; - if (fpsLimiter == FPS_LIMIT_CUSTOM && g_Config.iFpsLimit != 0) { - scaledTimestep *= 60.0f / g_Config.iFpsLimit; + if (fpsLimiter == FPSLimit::CUSTOM1 && g_Config.iFpsLimit1 > 0) { + scaledTimestep *= 60.0f / g_Config.iFpsLimit1; + } else if (fpsLimiter == FPSLimit::CUSTOM2 && g_Config.iFpsLimit2 > 0) { + scaledTimestep *= 60.0f / g_Config.iFpsLimit2; } if (lastFrameTime == 0.0 || wasPaused) { @@ -549,7 +551,8 @@ static void DoFrameTiming(bool &throttle, bool &skipFrame, float timestep) { // Auto-frameskip automatically if speed limit is set differently than the default. bool useAutoFrameskip = g_Config.bAutoFrameSkip && g_Config.iRenderingMode != FB_NON_BUFFERED_MODE; - if (g_Config.bAutoFrameSkip || (g_Config.iFrameSkip == 0 && fpsLimiter == FPS_LIMIT_CUSTOM && g_Config.iFpsLimit > 60)) { + bool forceFrameskip = (fpsLimiter == FPSLimit::CUSTOM1 && g_Config.iFpsLimit1 > 60) || (fpsLimiter == FPSLimit::CUSTOM2 && g_Config.iFpsLimit2 > 60); + if (g_Config.bAutoFrameSkip || forceFrameskip) { // autoframeskip // Argh, we are falling behind! Let's skip a frame and see if we catch up. if (curFrameTime > nextFrameTime && doFrameSkip) { @@ -601,9 +604,11 @@ static void DoFrameIdleTiming() { } float scaledVblank = timePerVblank; - if (PSP_CoreParameter().fpsLimit == FPS_LIMIT_CUSTOM) { + if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM1 && g_Config.iFpsLimit1 > 0) { // 0 is handled in FrameTimingThrottled(). - scaledVblank *= 60.0f / g_Config.iFpsLimit; + scaledVblank *= 60.0f / g_Config.iFpsLimit1; + } else if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM2 && g_Config.iFpsLimit2 > 0) { + scaledVblank *= 60.0f / g_Config.iFpsLimit2; } // If we have over at least a vblank of spare time, maintain at least 30fps in delay. @@ -695,7 +700,7 @@ void __DisplayFlip(int cyclesLate) { // Let the user know if we're running slow, so they know to adjust settings. // Sometimes users just think the sound emulation is broken. static bool hasNotifiedSlow = false; - if (!g_Config.bHideSlowWarnings && !hasNotifiedSlow && PSP_CoreParameter().fpsLimit == FPS_LIMIT_NORMAL && IsRunningSlow()) { + if (!g_Config.bHideSlowWarnings && !hasNotifiedSlow && PSP_CoreParameter().fpsLimit == FPSLimit::NORMAL && IsRunningSlow()) { #ifndef _DEBUG I18NCategory *err = GetI18NCategory("Error"); if (g_Config.bSoftwareRendering) { @@ -787,9 +792,11 @@ void hleLagSync(u64 userdata, int cyclesLate) { } float scale = 1.0f; - if (PSP_CoreParameter().fpsLimit == FPS_LIMIT_CUSTOM) { + if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM1 && g_Config.iFpsLimit1 > 0) { // 0 is handled in FrameTimingThrottled(). - scale = 60.0f / g_Config.iFpsLimit; + scale = 60.0f / g_Config.iFpsLimit1; + } else if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM2 && g_Config.iFpsLimit2 > 0) { + scale = 60.0f / g_Config.iFpsLimit2; } const double goal = lastLagSync + (scale / 1000.0f); diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 2436c69bd4..dc85a0816b 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -24,6 +24,7 @@ #include "Core/Core.h" #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "Core/Debugger/Breakpoints.h" #include "Core/ELF/ParamSFO.h" #include "Core/MemMapHelpers.h" diff --git a/Core/HW/StereoResampler.cpp b/Core/HW/StereoResampler.cpp index ee636a89fe..8b2fcfadd1 100644 --- a/Core/HW/StereoResampler.cpp +++ b/Core/HW/StereoResampler.cpp @@ -37,6 +37,7 @@ #include "Common/MathUtil.h" #include "Common/Atomics.h" #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "Core/HW/StereoResampler.h" #include "Core/HLE/__sceAudio.h" #include "Core/Util/AudioFormat.h" // for clamp_u8 diff --git a/Core/MIPS/MIPS.cpp b/Core/MIPS/MIPS.cpp index 37f16025ad..a04e8f2387 100644 --- a/Core/MIPS/MIPS.cpp +++ b/Core/MIPS/MIPS.cpp @@ -22,6 +22,7 @@ #include "Common.h" #include "Common/ChunkFile.h" +#include "Core/ConfigValues.h" #include "Core/MIPS/MIPS.h" #include "Core/MIPS/MIPSInt.h" #include "Core/MIPS/MIPSTables.h" diff --git a/Core/MemMap.cpp b/Core/MemMap.cpp index 0fc1355ae0..9c7a2cce19 100644 --- a/Core/MemMap.cpp +++ b/Core/MemMap.cpp @@ -38,6 +38,7 @@ #include "Core/Debugger/SymbolMap.h" #include "Core/Debugger/Breakpoints.h" #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "Core/HLE/ReplaceTables.h" #include "Core/MIPS/JitCommon/JitBlockCache.h" diff --git a/Core/MemMapFunctions.cpp b/Core/MemMapFunctions.cpp index bf2cff521d..a463a0e0ae 100644 --- a/Core/MemMapFunctions.cpp +++ b/Core/MemMapFunctions.cpp @@ -21,6 +21,7 @@ #include "Core/Core.h" #include "Core/MemMap.h" #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "Core/Host.h" #include "Core/Reporting.h" diff --git a/Core/PSPLoaders.cpp b/Core/PSPLoaders.cpp index ecd58d3141..8ff92b6e29 100644 --- a/Core/PSPLoaders.cpp +++ b/Core/PSPLoaders.cpp @@ -48,6 +48,7 @@ #include "Host.h" #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "Core/System.h" #include "Core/PSPLoaders.h" #include "Core/HLE/HLE.h" diff --git a/GPU/Common/FramebufferCommon.cpp b/GPU/Common/FramebufferCommon.cpp index 928f2751ee..b8b1b7a48a 100644 --- a/GPU/Common/FramebufferCommon.cpp +++ b/GPU/Common/FramebufferCommon.cpp @@ -28,6 +28,7 @@ #include "Common/ColorConv.h" #include "Common/Common.h" #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "Core/CoreParameter.h" #include "Core/Host.h" #include "Core/Reporting.h" @@ -47,11 +48,11 @@ void CenterDisplayOutputRect(float *x, float *y, float *w, float *h, float origW bool rotated = rotation == ROTATION_LOCKED_VERTICAL || rotation == ROTATION_LOCKED_VERTICAL180; - if (g_Config.iSmallDisplayZoomType == 0) { // Stretching + if (g_Config.iSmallDisplayZoomType == (int)SmallDisplayZoom::STRETCH) { outW = frameW; outH = frameH; } else { - if (g_Config.iSmallDisplayZoomType == 3) { // Manual Scaling + if (g_Config.iSmallDisplayZoomType == (int)SmallDisplayZoom::MANUAL) { float offsetX = (g_Config.fSmallDisplayOffsetX - 0.5f) * 2.0f * frameW; float offsetY = (g_Config.fSmallDisplayOffsetY - 0.5f) * 2.0f * frameH; // Have to invert Y for GL @@ -74,7 +75,7 @@ void CenterDisplayOutputRect(float *x, float *y, float *w, float *h, float origW *h = floorf(smallDisplayW); return; } - } else if (g_Config.iSmallDisplayZoomType == 2) { // Auto Scaling + } else if (g_Config.iSmallDisplayZoomType == (int)SmallDisplayZoom::AUTO) { // Stretch to 1080 for 272*4. But don't distort if not widescreen (i.e. ultrawide of halfwide.) float pixelCrop = frameH / 270.0f; float resCommonWidescreen = pixelCrop - floor(pixelCrop); @@ -95,13 +96,13 @@ void CenterDisplayOutputRect(float *x, float *y, float *w, float *h, float origW outW = frameW; outH = frameW / origRatio; // Stretch a little bit - if (!rotated && g_Config.iSmallDisplayZoomType == 1) // Partial Stretch + if (!rotated && g_Config.iSmallDisplayZoomType == (int)SmallDisplayZoom::PARTIAL_STRETCH) outH = (frameH + outH) / 2.0f; // (408 + 720) / 2 = 564 } else { // Image is taller than frame. Center horizontally. outW = frameH * origRatio; outH = frameH; - if (rotated && g_Config.iSmallDisplayZoomType == 1) // Partial Stretch + if (rotated && g_Config.iSmallDisplayZoomType == (int)SmallDisplayZoom::PARTIAL_STRETCH) outW = (frameH + outH) / 2.0f; // (408 + 720) / 2 = 564 } } diff --git a/GPU/Common/GPUStateUtils.cpp b/GPU/Common/GPUStateUtils.cpp index d1091b9a3e..4f2b4dd3bd 100644 --- a/GPU/Common/GPUStateUtils.cpp +++ b/GPU/Common/GPUStateUtils.cpp @@ -22,6 +22,7 @@ #include "Common/StringUtils.h" #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "Core/System.h" #include "GPU/ge_constants.h" diff --git a/GPU/Common/ShaderUniforms.cpp b/GPU/Common/ShaderUniforms.cpp index 2e57ee6b72..21aee1ec11 100644 --- a/GPU/Common/ShaderUniforms.cpp +++ b/GPU/Common/ShaderUniforms.cpp @@ -7,6 +7,7 @@ #include "math/math_util.h" #include "math/lin/vec3.h" #include "GPU/GPUState.h" +#include "GPU/Common/FramebufferCommon.h" #include "GPU/Common/GPUStateUtils.h" #include "GPU/Math3D.h" #include "Core/Reporting.h" @@ -82,7 +83,7 @@ void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms, bool flipView ConvertProjMatrixToVulkan(flippedMatrix); } - if (g_Config.iRenderingMode == 0 && g_display_rotation != DisplayRotation::ROTATE_0) { + if (g_Config.iRenderingMode == FB_NON_BUFFERED_MODE && g_display_rotation != DisplayRotation::ROTATE_0) { flippedMatrix = flippedMatrix * g_display_rot_matrix; } @@ -96,7 +97,7 @@ void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms, bool flipView } else { proj_through.setOrthoVulkan(0.0f, gstate_c.curRTWidth, 0, gstate_c.curRTHeight, 0, 1); } - if (g_Config.iRenderingMode == 0 && g_display_rotation != DisplayRotation::ROTATE_0) { + if (g_Config.iRenderingMode == FB_NON_BUFFERED_MODE && g_display_rotation != DisplayRotation::ROTATE_0) { proj_through = proj_through * g_display_rot_matrix; } CopyMatrix4x4(ub->proj_through, proj_through.getReadPtr()); diff --git a/GPU/Common/VertexDecoderCommon.cpp b/GPU/Common/VertexDecoderCommon.cpp index 7d40fe5293..0b8ee6736c 100644 --- a/GPU/Common/VertexDecoderCommon.cpp +++ b/GPU/Common/VertexDecoderCommon.cpp @@ -24,6 +24,7 @@ #include "Common/CPUDetect.h" #include "Common/ColorConv.h" #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "Core/MemMap.h" #include "Core/HDRemaster.h" #include "Core/Reporting.h" diff --git a/GPU/D3D11/FramebufferManagerD3D11.cpp b/GPU/D3D11/FramebufferManagerD3D11.cpp index 0bfc412541..f2910cbec6 100644 --- a/GPU/D3D11/FramebufferManagerD3D11.cpp +++ b/GPU/D3D11/FramebufferManagerD3D11.cpp @@ -31,6 +31,7 @@ #include "Core/Host.h" #include "Core/MemMap.h" #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "Core/System.h" #include "Core/Reporting.h" #include "GPU/ge_constants.h" diff --git a/GPU/Directx9/FramebufferDX9.cpp b/GPU/Directx9/FramebufferDX9.cpp index 8b6025732a..a66faf39d1 100644 --- a/GPU/Directx9/FramebufferDX9.cpp +++ b/GPU/Directx9/FramebufferDX9.cpp @@ -22,6 +22,7 @@ #include "Core/Host.h" #include "Core/MemMap.h" #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "Core/System.h" #include "Core/Reporting.h" #include "GPU/ge_constants.h" diff --git a/GPU/Directx9/GPU_DX9.cpp b/GPU/Directx9/GPU_DX9.cpp index adb50ecbf0..afd5a86d10 100644 --- a/GPU/Directx9/GPU_DX9.cpp +++ b/GPU/Directx9/GPU_DX9.cpp @@ -28,6 +28,7 @@ #include "Core/MIPS/MIPS.h" #include "Core/Host.h" #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "Core/Reporting.h" #include "Core/System.h" @@ -210,7 +211,7 @@ void GPU_DX9::ReapplyGfxState() { void GPU_DX9::BeginFrame() { // Turn off vsync when unthrottled int desiredVSyncInterval = g_Config.bVSync ? 1 : 0; - if ((PSP_CoreParameter().unthrottle) || (PSP_CoreParameter().fpsLimit == 1)) + if (PSP_CoreParameter().unthrottle || PSP_CoreParameter().fpsLimit != FPSLimit::NORMAL) desiredVSyncInterval = 0; if (desiredVSyncInterval != lastVsync_) { dxstate.SetVSyncInterval(desiredVSyncInterval); diff --git a/GPU/GLES/FramebufferManagerGLES.cpp b/GPU/GLES/FramebufferManagerGLES.cpp index e15aa36983..81b2498346 100644 --- a/GPU/GLES/FramebufferManagerGLES.cpp +++ b/GPU/GLES/FramebufferManagerGLES.cpp @@ -32,6 +32,7 @@ #include "Core/Host.h" #include "Core/MemMap.h" #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "Core/System.h" #include "Core/Reporting.h" #include "GPU/ge_constants.h" diff --git a/GPU/GLES/GPU_GLES.cpp b/GPU/GLES/GPU_GLES.cpp index 6b4864c2c6..5eca0e9296 100644 --- a/GPU/GLES/GPU_GLES.cpp +++ b/GPU/GLES/GPU_GLES.cpp @@ -392,9 +392,10 @@ inline void GPU_GLES::UpdateVsyncInterval(bool force) { if (PSP_CoreParameter().unthrottle) { desiredVSyncInterval = 0; } - if (PSP_CoreParameter().fpsLimit == 1) { + if (PSP_CoreParameter().fpsLimit != FPSLimit::NORMAL) { + int limit = PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM1 ? g_Config.iFpsLimit1 : g_Config.iFpsLimit2; // For an alternative speed that is a clean factor of 60, the user probably still wants vsync. - if (g_Config.iFpsLimit == 0 || (g_Config.iFpsLimit != 15 && g_Config.iFpsLimit != 30 && g_Config.iFpsLimit != 60)) { + if (limit == 0 || (limit >= 0 && limit != 15 && limit != 30 && limit != 60)) { desiredVSyncInterval = 0; } } @@ -459,7 +460,7 @@ void GPU_GLES::CopyDisplayToOutput() { // If buffered, discard the depth buffer of the backbuffer. Don't even know if we need one. #if 0 #ifdef USING_GLES2 - if (gl_extensions.EXT_discard_framebuffer && g_Config.iRenderingMode != 0) { + if (gl_extensions.EXT_discard_framebuffer && g_Config.iRenderingMode != FB_NON_BUFFERED_MODE) { GLenum attachments[] = {GL_DEPTH_EXT, GL_STENCIL_EXT}; glDiscardFramebufferEXT(GL_FRAMEBUFFER, 2, attachments); } diff --git a/GPU/GLES/StencilBufferGLES.cpp b/GPU/GLES/StencilBufferGLES.cpp index 9dac4c9a3f..d8effd95ae 100644 --- a/GPU/GLES/StencilBufferGLES.cpp +++ b/GPU/GLES/StencilBufferGLES.cpp @@ -16,6 +16,8 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "gfx_es2/glsl_program.h" +#include "Core/Config.h" +#include "Core/ConfigValues.h" #include "Core/Reporting.h" #include "GPU/Common/StencilCommon.h" #include "GPU/GLES/FramebufferManagerGLES.h" diff --git a/GPU/Software/Rasterizer.cpp b/GPU/Software/Rasterizer.cpp index 77d45c5191..f6b6e398e7 100644 --- a/GPU/Software/Rasterizer.cpp +++ b/GPU/Software/Rasterizer.cpp @@ -28,6 +28,7 @@ #include "Core/Reporting.h" #include "GPU/GPUState.h" +#include "GPU/Common/TextureCacheCommon.h" #include "GPU/Common/TextureDecoder.h" #include "GPU/Software/SoftGpu.h" #include "GPU/Software/Rasterizer.h" @@ -1081,9 +1082,9 @@ static inline void CalculateSamplingParams(const float ds, const float dt, const levelFrac = 0; } - if (g_Config.iTexFiltering == 3) { + if (g_Config.iTexFiltering == TEX_FILTER_LINEAR) { filt = true; - } else if (g_Config.iTexFiltering == 2) { + } else if (g_Config.iTexFiltering == TEX_FILTER_NEAREST) { filt = false; } else { filt = detail > 0 ? gstate.isMinifyFilteringEnabled() : gstate.isMagnifyFilteringEnabled(); diff --git a/GPU/Software/SoftGpu.cpp b/GPU/Software/SoftGpu.cpp index 9432ba97ef..5d3b20c8e3 100644 --- a/GPU/Software/SoftGpu.cpp +++ b/GPU/Software/SoftGpu.cpp @@ -21,6 +21,7 @@ #include "Common/ColorConv.h" #include "Common/GraphicsContext.h" #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "Core/Debugger/Breakpoints.h" #include "Core/Host.h" #include "Core/MemMap.h" diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index a85d32e52e..405c10fc54 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -784,7 +784,7 @@ void DrawEngineVulkan::DoFlush() { if (prim != lastPrim_ || gstate_c.IsDirty(DIRTY_BLEND_STATE | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_RASTER_STATE | DIRTY_DEPTHSTENCIL_STATE)) { ConvertStateToVulkanKey(*framebufferManager_, shaderManager_, prim, pipelineKey_, dynState_); } - Draw::NativeObject object = g_Config.iRenderingMode != 0 ? Draw::NativeObject::FRAMEBUFFER_RENDERPASS : Draw::NativeObject::BACKBUFFER_RENDERPASS; + Draw::NativeObject object = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE ? Draw::NativeObject::FRAMEBUFFER_RENDERPASS : Draw::NativeObject::BACKBUFFER_RENDERPASS; VkRenderPass renderPass = (VkRenderPass)draw_->GetNativeObject(object); VulkanPipeline *pipeline = pipelineManager_->GetOrCreatePipeline(pipelineLayout_, renderPass, pipelineKey_, &dec_->decFmt, vshader, fshader, true); if (!pipeline || !pipeline->pipeline) { @@ -860,9 +860,9 @@ void DrawEngineVulkan::DoFlush() { params.transformedExpanded = transformedExpanded; params.fbman = framebufferManager_; params.texCache = textureCache_; - // We have to force drawing of primitives if g_Config.iRenderingMode == 0 (non-buffered) because Vulkan clears + // We have to force drawing of primitives if g_Config.iRenderingMode == FB_NON_BUFFERED_MODE because Vulkan clears // do not respect scissor rects. - params.allowClear = g_Config.iRenderingMode != 0; + params.allowClear = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE; params.allowSeparateAlphaClear = false; params.provokeFlatFirst = true; @@ -889,7 +889,7 @@ void DrawEngineVulkan::DoFlush() { if (prim != lastPrim_ || gstate_c.IsDirty(DIRTY_BLEND_STATE | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_RASTER_STATE | DIRTY_DEPTHSTENCIL_STATE)) { ConvertStateToVulkanKey(*framebufferManager_, shaderManager_, prim, pipelineKey_, dynState_); } - Draw::NativeObject object = g_Config.iRenderingMode != 0 ? Draw::NativeObject::FRAMEBUFFER_RENDERPASS : Draw::NativeObject::BACKBUFFER_RENDERPASS; + Draw::NativeObject object = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE ? Draw::NativeObject::FRAMEBUFFER_RENDERPASS : Draw::NativeObject::BACKBUFFER_RENDERPASS; VkRenderPass renderPass = (VkRenderPass)draw_->GetNativeObject(object); VulkanPipeline *pipeline = pipelineManager_->GetOrCreatePipeline(pipelineLayout_, renderPass, pipelineKey_, &dec_->decFmt, vshader, fshader, false); if (!pipeline || !pipeline->pipeline) { diff --git a/GPU/Vulkan/FramebufferVulkan.cpp b/GPU/Vulkan/FramebufferVulkan.cpp index d44b2a9983..9665019ffa 100644 --- a/GPU/Vulkan/FramebufferVulkan.cpp +++ b/GPU/Vulkan/FramebufferVulkan.cpp @@ -35,6 +35,7 @@ #include "Core/Host.h" #include "Core/MemMap.h" #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "Core/System.h" #include "Core/Reporting.h" #include "Core/HLE/sceDisplay.h" diff --git a/Qt/QtMain.cpp b/Qt/QtMain.cpp index 304d164ab0..ada30411ad 100644 --- a/Qt/QtMain.cpp +++ b/Qt/QtMain.cpp @@ -31,6 +31,8 @@ #include "gfx_es2/gpu_features.h" #include "math/math_util.h" #include "thread/threadutil.h" +#include "Core/Config.h" +#include "Core/ConfigValues.h" #include diff --git a/Qt/QtMain.h b/Qt/QtMain.h index 958e139bcc..58fefb6cfe 100644 --- a/Qt/QtMain.h +++ b/Qt/QtMain.h @@ -38,6 +38,7 @@ QTM_USE_NAMESPACE #include "Common/GraphicsContext.h" #include "Core/Core.h" #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "Core/System.h" #include "thin3d/thin3d_create.h" #include "thin3d/GLRenderManager.h" diff --git a/SDL/SDLGLGraphicsContext.cpp b/SDL/SDLGLGraphicsContext.cpp index e3dc209e3f..42ed9a261b 100644 --- a/SDL/SDLGLGraphicsContext.cpp +++ b/SDL/SDLGLGraphicsContext.cpp @@ -1,6 +1,7 @@ #include #include "SDLGLGraphicsContext.h" #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "Core/System.h" #include "base/NativeApp.h" #include "base/display.h" diff --git a/SDL/SDLMain.cpp b/SDL/SDLMain.cpp index 25f23e37a2..85b49825a1 100644 --- a/SDL/SDLMain.cpp +++ b/SDL/SDLMain.cpp @@ -51,6 +51,7 @@ SDLJoystick *joystick = NULL; #include "Core/System.h" #include "Core/Core.h" #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "Common/GraphicsContext.h" #include "SDLGLGraphicsContext.h" #include "SDLVulkanGraphicsContext.h" diff --git a/SDL/SDLVulkanGraphicsContext.cpp b/SDL/SDLVulkanGraphicsContext.cpp index 898d2c3a2a..a29d41ac3e 100644 --- a/SDL/SDLVulkanGraphicsContext.cpp +++ b/SDL/SDLVulkanGraphicsContext.cpp @@ -1,4 +1,5 @@ #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "base/NativeApp.h" #include "base/display.h" #include "thin3d/thin3d.h" diff --git a/UI/DevScreens.cpp b/UI/DevScreens.cpp index 227265233b..12d1ee1e14 100644 --- a/UI/DevScreens.cpp +++ b/UI/DevScreens.cpp @@ -30,6 +30,7 @@ #include "Core/MemMap.h" #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "Core/System.h" #include "Core/CoreParameter.h" #include "Core/MIPS/MIPSTables.h" diff --git a/UI/DisplayLayoutScreen.cpp b/UI/DisplayLayoutScreen.cpp index 4e719533ed..0ba1901811 100644 --- a/UI/DisplayLayoutScreen.cpp +++ b/UI/DisplayLayoutScreen.cpp @@ -26,6 +26,7 @@ #include "DisplayLayoutScreen.h" #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "Core/System.h" #include "DisplayLayoutEditor.h" #include "GPU/Common/FramebufferCommon.h" @@ -72,7 +73,7 @@ bool DisplayLayoutScreen::touch(const TouchInput &touch) { using namespace UI; int mode = mode_ ? mode_->GetSelection() : 0; - if (g_Config.iSmallDisplayZoomType == 2) { mode = -1; } + if (g_Config.iSmallDisplayZoomType == (int)SmallDisplayZoom::AUTO) { mode = -1; } const Bounds &screen_bounds = screenManager()->getUIContext()->GetBounds(); if ((touch.flags & TOUCH_MOVE) && picked_ != 0) { @@ -185,7 +186,7 @@ UI::EventReturn DisplayLayoutScreen::OnCenter(UI::EventParams &e) { }; UI::EventReturn DisplayLayoutScreen::OnZoomTypeChange(UI::EventParams &e) { - if (g_Config.iSmallDisplayZoomType < 3) { + if (g_Config.iSmallDisplayZoomType < (int)SmallDisplayZoom::MANUAL) { const Bounds &bounds = screenManager()->getUIContext()->GetBounds(); float autoBound = bounds.w / 480.0f; g_Config.fSmallDisplayZoomLevel = autoBound; @@ -268,8 +269,8 @@ void DisplayLayoutScreen::CreateViews() { HighlightLabel *label = nullptr; mode_ = nullptr; - if (g_Config.iSmallDisplayZoomType > 1) { // Scaling - if (g_Config.iSmallDisplayZoomType == 2) { // Auto Scaling + if (g_Config.iSmallDisplayZoomType >= (int)SmallDisplayZoom::AUTO) { // Scaling + if (g_Config.iSmallDisplayZoomType == (int)SmallDisplayZoom::AUTO) { label = new HighlightLabel(gr->T("Auto Scaling"), new AnchorLayoutParams(WRAP_CONTENT, 64.0f, local_dp_xres / 2.0f, local_dp_yres / 2.0f, NONE, NONE, true)); float autoBound = local_dp_yres / 270.0f; // Case of screen rotated ~ only works with buffered rendering @@ -311,7 +312,7 @@ void DisplayLayoutScreen::CreateViews() { displayRepresentation_->SetVisibility(V_INVISIBLE); float width = previewWidth; float height = previewHeight; - if (g_Config.iSmallDisplayZoomType == 0) { // Stretched + if (g_Config.iSmallDisplayZoomType == (int)SmallDisplayZoom::STRETCH) { Choice *stretched = new Choice("", "", false, new AnchorLayoutParams(width, height, width - width / 2.0f, NONE, NONE, height - height / 2.0f)); stretched->SetEnabled(false); root_->Add(stretched); @@ -320,12 +321,12 @@ void DisplayLayoutScreen::CreateViews() { float frameRatio = width / height; if (origRatio > frameRatio) { height = width / origRatio; - if (!bRotated && g_Config.iSmallDisplayZoomType == 1) { + if (!bRotated && g_Config.iSmallDisplayZoomType == (int)SmallDisplayZoom::PARTIAL_STRETCH) { height = (272.0f + height) / 2.0f; } } else { width = height * origRatio; - if (bRotated && g_Config.iSmallDisplayZoomType == 1) { + if (bRotated && g_Config.iSmallDisplayZoomType == (int)SmallDisplayZoom::PARTIAL_STRETCH) { width = (272.0f + height) / 2.0f; } } diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index 9b8317ee4e..7dcedfa43d 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -41,6 +41,7 @@ #include "Core/AVIDump.h" #endif #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "Core/CoreTiming.h" #include "Core/CoreParameter.h" #include "Core/Core.h" @@ -471,13 +472,29 @@ void EmuScreen::onVKeyDown(int virtualKeyCode) { break; case VIRTKEY_SPEED_TOGGLE: - if (PSP_CoreParameter().fpsLimit == 0) { - PSP_CoreParameter().fpsLimit = 1; + // Cycle through enabled speeds. + if (PSP_CoreParameter().fpsLimit == FPSLimit::NORMAL && g_Config.iFpsLimit1 >= 0) { + PSP_CoreParameter().fpsLimit = FPSLimit::CUSTOM1; + osm.Show(sc->T("fixed", "Speed: alternate"), 1.0); + } else if (PSP_CoreParameter().fpsLimit != FPSLimit::CUSTOM2 && g_Config.iFpsLimit2 >= 0) { + PSP_CoreParameter().fpsLimit = FPSLimit::CUSTOM2; + osm.Show(sc->T("SpeedCustom2", "Speed: alternate 2"), 1.0); + } else if (PSP_CoreParameter().fpsLimit != FPSLimit::NORMAL) { + PSP_CoreParameter().fpsLimit = FPSLimit::NORMAL; + osm.Show(sc->T("standard", "Speed: standard"), 1.0); + } + break; + + case VIRTKEY_SPEED_CUSTOM1: + if (PSP_CoreParameter().fpsLimit == FPSLimit::NORMAL) { + PSP_CoreParameter().fpsLimit = FPSLimit::CUSTOM1; osm.Show(sc->T("fixed", "Speed: alternate"), 1.0); } - else if (PSP_CoreParameter().fpsLimit == 1) { - PSP_CoreParameter().fpsLimit = 0; - osm.Show(sc->T("standard", "Speed: standard"), 1.0); + break; + case VIRTKEY_SPEED_CUSTOM2: + if (PSP_CoreParameter().fpsLimit == FPSLimit::NORMAL) { + PSP_CoreParameter().fpsLimit = FPSLimit::CUSTOM2; + osm.Show(sc->T("SpeedCustom2", "Speed: alternate 2"), 1.0); } break; @@ -580,11 +597,26 @@ void EmuScreen::onVKeyDown(int virtualKeyCode) { } void EmuScreen::onVKeyUp(int virtualKeyCode) { + I18NCategory *sc = GetI18NCategory("Screen"); + switch (virtualKeyCode) { case VIRTKEY_UNTHROTTLE: PSP_CoreParameter().unthrottle = false; break; + case VIRTKEY_SPEED_CUSTOM1: + if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM1) { + PSP_CoreParameter().fpsLimit = FPSLimit::NORMAL; + osm.Show(sc->T("standard", "Speed: standard"), 1.0); + } + break; + case VIRTKEY_SPEED_CUSTOM2: + if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM2) { + PSP_CoreParameter().fpsLimit = FPSLimit::NORMAL; + osm.Show(sc->T("standard", "Speed: standard"), 1.0); + } + break; + case VIRTKEY_AXIS_X_MIN: case VIRTKEY_AXIS_X_MAX: setVKeyAnalogX(CTRL_STICK_LEFT, VIRTKEY_AXIS_X_MIN, VIRTKEY_AXIS_X_MAX); @@ -1006,11 +1038,6 @@ void EmuScreen::update() { // Virtual keys. __CtrlSetRapidFire(virtKeys[VIRTKEY_RAPID_FIRE - VIRTKEY_FIRST]); - // Make sure fpsLimit starts at 0 - if (PSP_CoreParameter().fpsLimit != 0 && PSP_CoreParameter().fpsLimit != 1) { - PSP_CoreParameter().fpsLimit = 0; - } - // This is here to support the iOS on screen back button. if (pauseTrigger_) { pauseTrigger_ = false; diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 2834218006..6e76db39e7 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -49,6 +49,7 @@ #include "Common/FileUtil.h" #include "Common/OSVersion.h" #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "Core/Host.h" #include "Core/System.h" #include "Core/Reporting.h" @@ -126,7 +127,8 @@ void GameSettingsScreen::CreateViews() { cap60FPS_ = g_Config.iForceMaxEmulatedFPS == 60; - iAlternateSpeedPercent_ = (g_Config.iFpsLimit * 100) / 60; + iAlternateSpeedPercent1_ = g_Config.iFpsLimit1 < 0 ? -1 : (g_Config.iFpsLimit1 * 100) / 60; + iAlternateSpeedPercent2_ = g_Config.iFpsLimit2 < 0 ? -1 : (g_Config.iFpsLimit2 * 100) / 60; bool vertical = UseVerticalLayout(); @@ -270,9 +272,15 @@ void GameSettingsScreen::CreateViews() { frameSkipAuto_->OnClick.Handle(this, &GameSettingsScreen::OnAutoFrameskip); graphicsSettings->Add(new CheckBox(&cap60FPS_, gr->T("Force max 60 FPS (helps GoW)"))); - PopupSliderChoice *altSpeed = graphicsSettings->Add(new PopupSliderChoice(&iAlternateSpeedPercent_, 0, 1000, gr->T("Alternative Speed", "Alternative speed"), 5, screenManager(), gr->T("%, 0:unlimited"))); - altSpeed->SetFormat("%i%%"); - altSpeed->SetZeroLabel(gr->T("Unlimited")); + PopupSliderChoice *altSpeed1 = graphicsSettings->Add(new PopupSliderChoice(&iAlternateSpeedPercent1_, 0, 1000, gr->T("Alternative Speed", "Alternative speed"), 5, screenManager(), gr->T("%, 0:unlimited"))); + altSpeed1->SetFormat("%i%%"); + altSpeed1->SetZeroLabel(gr->T("Unlimited")); + altSpeed1->SetNegativeDisable(gr->T("Disabled")); + + PopupSliderChoice *altSpeed2 = graphicsSettings->Add(new PopupSliderChoice(&iAlternateSpeedPercent2_, 0, 1000, gr->T("Alternative Speed 2", "Alternative speed 2 (in %, 0 = unlimited)"), 5, screenManager(), gr->T("%, 0:unlimited"))); + altSpeed2->SetFormat("%i%%"); + altSpeed2->SetZeroLabel(gr->T("Unlimited")); + altSpeed2->SetNegativeDisable(gr->T("Disabled")); graphicsSettings->Add(new ItemHeader(gr->T("Features"))); // Hide postprocess option on unsupported backends to avoid confusion. @@ -1032,7 +1040,8 @@ void GameSettingsScreen::update() { UIScreen::update(); g_Config.iForceMaxEmulatedFPS = cap60FPS_ ? 60 : 0; - g_Config.iFpsLimit = (iAlternateSpeedPercent_ * 60) / 100; + g_Config.iFpsLimit1 = iAlternateSpeedPercent1_ < 0 ? -1 : (iAlternateSpeedPercent1_ * 60) / 100; + g_Config.iFpsLimit2 = iAlternateSpeedPercent2_ < 0 ? -1 : (iAlternateSpeedPercent2_ * 60) / 100; bool vertical = UseVerticalLayout(); if (vertical != lastVertical_) { diff --git a/UI/GameSettingsScreen.h b/UI/GameSettingsScreen.h index c68fb8939a..259c8cf58b 100644 --- a/UI/GameSettingsScreen.h +++ b/UI/GameSettingsScreen.h @@ -106,7 +106,8 @@ private: // Temporaries to convert bools to int settings bool cap60FPS_; - int iAlternateSpeedPercent_; + int iAlternateSpeedPercent1_; + int iAlternateSpeedPercent2_; bool enableReports_; //edit the game-specific settings and restore the global settings after exiting diff --git a/UI/GamepadEmu.cpp b/UI/GamepadEmu.cpp index 42edfa2979..96253b2727 100644 --- a/UI/GamepadEmu.cpp +++ b/UI/GamepadEmu.cpp @@ -18,6 +18,7 @@ #include #include "Common/Log.h" #include "Core/Config.h" +#include "Core/Core.h" #include "Core/System.h" #include "Core/HLE/sceCtrl.h" #include "UI/GamepadEmu.h" @@ -107,7 +108,7 @@ void MultiTouchButton::Draw(UIContext &dc) { uint32_t colorBg = colorAlpha(GetButtonColor(), opacity); uint32_t color = colorAlpha(0xFFFFFF, opacity); - dc.Draw()->DrawImageRotated(bgImg_, bounds_.centerX(), bounds_.centerY(), scale, angle_ * (M_PI * 2 / 360.0f), colorBg, flipImageH_); + dc.Draw()->DrawImageRotated(bgImg_, bounds_.centerX(), bounds_.centerY(), scale, bgAngle_ * (M_PI * 2 / 360.0f), colorBg, flipImageH_); int y = bounds_.centerY(); // Hack round the fact that the center of the rectangular picture the triangle is contained in @@ -124,9 +125,32 @@ void BoolButton::Touch(const TouchInput &input) { if (down != lastDown) { *value_ = down; + UI::EventParams params{ this }; + params.a = down; + OnChange.Trigger(params); } } +void FPSLimitButton::Touch(const TouchInput &input) { + bool lastDown = pointerDownMask_ != 0; + MultiTouchButton::Touch(input); + bool down = pointerDownMask_ != 0; + + if (!down && lastDown && IsDown()) { + PSP_CoreParameter().fpsLimit = FPSLimit::NORMAL; + } else if (down && !lastDown && PSP_CoreParameter().fpsLimit == FPSLimit::NORMAL) { + int limit = limit_ == FPSLimit::CUSTOM1 ? g_Config.iFpsLimit1 : g_Config.iFpsLimit2; + // Validate it actually has a setting (may this should override visible?) + if (limit >= 0) { + PSP_CoreParameter().fpsLimit = limit_; + } + } +} + +bool FPSLimitButton::IsDown() { + return PSP_CoreParameter().fpsLimit == limit_; +} + void PSPButton::Touch(const TouchInput &input) { bool lastDown = pointerDownMask_ != 0; MultiTouchButton::Touch(input); @@ -387,6 +411,15 @@ void PSPStick::ProcessTouch(float x, float y, bool down) { void InitPadLayout(float xres, float yres, float globalScale) { const float scale = globalScale; + const int halfW = xres / 2; + + auto initTouchPos = [=](ConfigTouchPos &touch, float x, float y) { + if (touch.x == -1.0f || touch.y == -1.0f) { + touch.x = x / xres; + touch.y = y / yres; + touch.scale = scale; + } + }; // PSP buttons (triangle, circle, square, cross)--------------------- // space between the PSP buttons (triangle, circle, square and cross) @@ -398,12 +431,7 @@ void InitPadLayout(float xres, float yres, float globalScale) { float Action_button_spacing = g_Config.fActionButtonSpacing * baseActionButtonSpacing; int Action_button_center_X = xres - Action_button_spacing * 2; int Action_button_center_Y = yres - Action_button_spacing * 2; - - if (g_Config.fActionButtonCenterX == -1.0 || g_Config.fActionButtonCenterY == -1.0) { - // Setup defaults - g_Config.fActionButtonCenterX = (float)Action_button_center_X / xres; - g_Config.fActionButtonCenterY = (float)Action_button_center_Y / yres; - } + initTouchPos(g_Config.touchActionButtonCenter, Action_button_center_X, Action_button_center_Y); //D-PAD (up down left right) (aka PSP cross)---------------------------- //radius to the D-pad @@ -411,26 +439,16 @@ void InitPadLayout(float xres, float yres, float globalScale) { int D_pad_X = 2.5 * D_pad_Radius * scale; int D_pad_Y = yres - D_pad_Radius * scale; - if (g_Config.bShowTouchAnalogStick) { + if (g_Config.touchAnalogStick.show) { D_pad_Y -= 200 * scale; } - - if (g_Config.fDpadX == -1.0 || g_Config.fDpadY == -1.0 ) { - //setup defaults - g_Config.fDpadX = (float)D_pad_X / xres; - g_Config.fDpadY = (float)D_pad_Y / yres; - } + initTouchPos(g_Config.touchDpad, D_pad_X, D_pad_Y); //analog stick------------------------------------------------------- //keep the analog stick right below the D pad int analog_stick_X = D_pad_X; int analog_stick_Y = yres - 80 * scale; - - if (g_Config.fAnalogStickX == -1.0 || g_Config.fAnalogStickY == -1.0 ) { - g_Config.fAnalogStickX = (float)analog_stick_X / xres; - g_Config.fAnalogStickY = (float)analog_stick_Y / yres; - g_Config.fAnalogStickScale = scale; - } + initTouchPos(g_Config.touchAnalogStick, analog_stick_X, analog_stick_Y); //select, start, throttle-------------------------------------------- //space between the bottom keys (space between select, start and un-throttle) @@ -439,32 +457,20 @@ void InitPadLayout(float xres, float yres, float globalScale) { bottom_key_spacing *= 0.8f; } - int start_key_X = xres / 2 + (bottom_key_spacing) * scale; + int start_key_X = halfW + bottom_key_spacing * scale; int start_key_Y = yres - 60 * scale; + initTouchPos(g_Config.touchStartKey, start_key_X, start_key_Y); - if (g_Config.fStartKeyX == -1.0 || g_Config.fStartKeyY == -1.0 ) { - g_Config.fStartKeyX = (float)start_key_X / xres; - g_Config.fStartKeyY = (float)start_key_Y / yres; - g_Config.fStartKeyScale = scale; - } - - int select_key_X = xres / 2; + int select_key_X = halfW; int select_key_Y = yres - 60 * scale; + initTouchPos(g_Config.touchSelectKey, select_key_X, select_key_Y); - if (g_Config.fSelectKeyX == -1.0 || g_Config.fSelectKeyY == -1.0 ) { - g_Config.fSelectKeyX = (float)select_key_X / xres; - g_Config.fSelectKeyY = (float)select_key_Y / yres; - g_Config.fSelectKeyScale = scale; - } - - int unthrottle_key_X = xres / 2 - (bottom_key_spacing) * scale; + int unthrottle_key_X = halfW - bottom_key_spacing * scale; int unthrottle_key_Y = yres - 60 * scale; + initTouchPos(g_Config.touchUnthrottleKey, unthrottle_key_X, unthrottle_key_Y); - if (g_Config.fUnthrottleKeyX == -1.0 || g_Config.fUnthrottleKeyY == -1.0 ) { - g_Config.fUnthrottleKeyX = (float)unthrottle_key_X / xres; - g_Config.fUnthrottleKeyY = (float)unthrottle_key_Y / yres; - g_Config.fUnthrottleKeyScale = scale; - } + initTouchPos(g_Config.touchSpeed1Key, unthrottle_key_X, unthrottle_key_Y - 60 * scale); + initTouchPos(g_Config.touchSpeed2Key, unthrottle_key_X + bottom_key_spacing * scale, unthrottle_key_Y - 60 * scale); // L and R------------------------------------------------------------ // Put them above the analog stick / above the buttons to the right. @@ -472,214 +478,145 @@ void InitPadLayout(float xres, float yres, float globalScale) { int l_key_X = 60 * scale; int l_key_Y = yres - 380 * scale; - - if (g_Config.fLKeyX == -1.0 || g_Config.fLKeyY == -1.0 ) { - g_Config.fLKeyX = (float)l_key_X / xres; - g_Config.fLKeyY = (float)l_key_Y / yres; - g_Config.fLKeyScale = scale; - } + initTouchPos(g_Config.touchLKey, l_key_X, l_key_Y); int r_key_X = xres - 60 * scale; int r_key_Y = l_key_Y; - - if (g_Config.fRKeyX == -1.0 || g_Config.fRKeyY == -1.0 ) { - g_Config.fRKeyX = (float)r_key_X / xres; - g_Config.fRKeyY = (float)r_key_Y / yres; - g_Config.fRKeyScale = scale; - } + initTouchPos(g_Config.touchRKey, r_key_X, r_key_Y); //Combo key - int combo_key_X = xres / 2 + (bottom_key_spacing)* scale*1.2f; + int combo_key_X = halfW + bottom_key_spacing * scale * 1.2f; int combo_key_Y = yres / 2; + initTouchPos(g_Config.touchCombo0, combo_key_X, combo_key_Y); - if (g_Config.fcombo0X == -1.0 || g_Config.fcombo0Y == -1.0) { - g_Config.fcombo0X = (float)combo_key_X / xres; - g_Config.fcombo0Y = (float)combo_key_Y / yres; - g_Config.fcomboScale0 = scale; - } - - int combo1_key_X = xres / 2 + (bottom_key_spacing)* scale * 2.2; + int combo1_key_X = halfW + bottom_key_spacing * scale * 2.2f; int combo1_key_Y = yres / 2; + initTouchPos(g_Config.touchCombo1, combo1_key_X, combo1_key_Y); - if (g_Config.fcombo1X == -1.0 || g_Config.fcombo1Y == -1.0) { - g_Config.fcombo1X = (float)combo1_key_X / xres; - g_Config.fcombo1Y = (float)combo1_key_Y / yres; - g_Config.fcomboScale1 = scale; - } - - int combo2_key_X = xres / 2 + (bottom_key_spacing)* scale * 3.2; + int combo2_key_X = halfW + bottom_key_spacing * scale * 3.2f; int combo2_key_Y = yres / 2; + initTouchPos(g_Config.touchCombo2, combo2_key_X, combo2_key_Y); - if (g_Config.fcombo2X == -1.0 || g_Config.fcombo2Y == -1.0) { - g_Config.fcombo2X = (float)combo2_key_X / xres; - g_Config.fcombo2Y = (float)combo2_key_Y / yres; - g_Config.fcomboScale2 = scale; - } - - int combo3_key_X = xres / 2 + (bottom_key_spacing)* scale * 1.2; + int combo3_key_X = halfW + bottom_key_spacing * scale * 1.2f; int combo3_key_Y = yres / 3; + initTouchPos(g_Config.touchCombo3, combo3_key_X, combo3_key_Y); - if (g_Config.fcombo3X == -1.0 || g_Config.fcombo3Y == -1.0) { - g_Config.fcombo3X = (float)combo3_key_X / xres; - g_Config.fcombo3Y = (float)combo3_key_Y / yres; - g_Config.fcomboScale3 = scale; - } - - int combo4_key_X = xres / 2 + (bottom_key_spacing)* scale * 2.2; + int combo4_key_X = halfW + bottom_key_spacing * scale * 2.2f; int combo4_key_Y = yres / 3; - - if (g_Config.fcombo4X == -1.0 || g_Config.fcombo4Y == -1.0) { - g_Config.fcombo4X = (float)combo4_key_X / xres; - g_Config.fcombo4Y = (float)combo4_key_Y / yres; - g_Config.fcomboScale4 = scale; - } - -}; + initTouchPos(g_Config.touchCombo4, combo4_key_X, combo4_key_Y); +} UI::ViewGroup *CreatePadLayout(float xres, float yres, bool *pause) { - //standard coord system - using namespace UI; AnchorLayout *root = new AnchorLayout(new LayoutParams(FILL_PARENT, FILL_PARENT)); + if (!g_Config.bShowTouchControls) { + return root; + } - //PSP buttons (triangle, circle, square, cross)--------------------- - //space between the PSP buttons (traingle, circle, square and cross) - const float Action_button_scale = g_Config.fActionButtonScale; - const float Action_button_spacing = g_Config.fActionButtonSpacing * baseActionButtonSpacing; - //position of the circle button (the PSP circle button). It is the farthest to the left - float Action_button_center_X = g_Config.fActionButtonCenterX * xres; - float Action_button_center_Y = g_Config.fActionButtonCenterY * yres; + struct ButtonOffset { + float x; + float y; + }; + auto buttonLayoutParams = [=](const ConfigTouchPos &touch, ButtonOffset off = { 0, 0 }) { + return new AnchorLayoutParams(touch.x * xres + off.x, touch.y * yres + off.y, NONE, NONE, true); + }; - const float Action_circle_button_X = Action_button_center_X + Action_button_spacing; - const float Action_circle_button_Y = Action_button_center_Y; - - const float Action_cross_button_X = Action_button_center_X; - const float Action_cross_button_Y = Action_button_center_Y + Action_button_spacing; - - const float Action_triangle_button_X = Action_button_center_X; - const float Action_triangle_button_Y = Action_button_center_Y - Action_button_spacing; - - const float Action_square_button_X = Action_button_center_X - Action_button_spacing; - const float Action_square_button_Y = Action_button_center_Y; - - //D-PAD (up down left right) (aka PSP cross)-------------------------------------------------------------- - //radius to the D-pad - - float D_pad_X = g_Config.fDpadX * xres; - float D_pad_Y = g_Config.fDpadY * yres; - float D_pad_scale = g_Config.fDpadScale; - float D_pad_spacing = g_Config.fDpadSpacing; - - //select, start, throttle-------------------------------------------- - //space between the bottom keys (space between select, start and un-throttle) - float start_key_X = g_Config.fStartKeyX * xres; - float start_key_Y = g_Config.fStartKeyY * yres; - float start_key_scale = g_Config.fStartKeyScale; - - float select_key_X = g_Config.fSelectKeyX * xres; - float select_key_Y = g_Config.fSelectKeyY * yres; - float select_key_scale = g_Config.fSelectKeyScale; - - float unthrottle_key_X = g_Config.fUnthrottleKeyX * xres; - float unthrottle_key_Y = g_Config.fUnthrottleKeyY * yres; - float unthrottle_key_scale = g_Config.fUnthrottleKeyScale; - - //L and R------------------------------------------------------------ - float l_key_X = g_Config.fLKeyX * xres; - float l_key_Y = g_Config.fLKeyY * yres; - float l_key_scale = g_Config.fLKeyScale; - - float r_key_X = g_Config.fRKeyX * xres; - float r_key_Y = g_Config.fRKeyY * yres; - float r_key_scale = g_Config.fRKeyScale; - - //analog stick------------------------------------------------------- - float analog_stick_X = g_Config.fAnalogStickX * xres; - float analog_stick_Y = g_Config.fAnalogStickY * yres; - float analog_stick_scale = g_Config.fAnalogStickScale; - - //combo key ------------------------------------------------------- - float combo0_key_X = g_Config.fcombo0X * xres; - float combo0_key_Y = g_Config.fcombo0Y * yres; - float combo_key_scale = g_Config.fcomboScale0; - float combo1_key_X = g_Config.fcombo1X * xres; - float combo1_key_Y = g_Config.fcombo1Y * yres; - float combo1_key_scale = g_Config.fcomboScale1; - float combo2_key_X = g_Config.fcombo2X * xres; - float combo2_key_Y = g_Config.fcombo2Y * yres; - float combo2_key_scale = g_Config.fcomboScale2; - float combo3_key_X = g_Config.fcombo3X * xres; - float combo3_key_Y = g_Config.fcombo3Y * yres; - float combo3_key_scale = g_Config.fcomboScale3; - float combo4_key_X = g_Config.fcombo4X * xres; - float combo4_key_Y = g_Config.fcombo4Y * yres; - float combo4_key_scale = g_Config.fcomboScale4; + // Space between the PSP buttons (traingle, circle, square and cross) + const float actionButtonSpacing = g_Config.fActionButtonSpacing * baseActionButtonSpacing; + // Position of the circle button (the PSP circle button). It is the farthest to the right. + ButtonOffset circleOffset{ actionButtonSpacing, 0.0f }; + ButtonOffset crossOffset{ 0.0f, actionButtonSpacing }; + ButtonOffset triangleOffset{ 0.0f, -actionButtonSpacing }; + ButtonOffset squareOffset{ -actionButtonSpacing, 0.0f }; const int halfW = xres / 2; const int roundImage = g_Config.iTouchButtonStyle ? I_ROUND_LINE : I_ROUND; - if (g_Config.bShowTouchControls) { - const int rectImage = g_Config.iTouchButtonStyle ? I_RECT_LINE : I_RECT; - const int shoulderImage = g_Config.iTouchButtonStyle ? I_SHOULDER_LINE : I_SHOULDER; - const int dirImage = g_Config.iTouchButtonStyle ? I_DIR_LINE : I_DIR; - const int stickImage = g_Config.iTouchButtonStyle ? I_STICK_LINE : I_STICK; - const int stickBg = g_Config.iTouchButtonStyle ? I_STICK_BG_LINE : I_STICK_BG; - static const int comboKeyImages[5] = { I_1, I_2, I_3, I_4, I_5 }; + const int rectImage = g_Config.iTouchButtonStyle ? I_RECT_LINE : I_RECT; + const int shoulderImage = g_Config.iTouchButtonStyle ? I_SHOULDER_LINE : I_SHOULDER; + const int dirImage = g_Config.iTouchButtonStyle ? I_DIR_LINE : I_DIR; + const int stickImage = g_Config.iTouchButtonStyle ? I_STICK_LINE : I_STICK; + const int stickBg = g_Config.iTouchButtonStyle ? I_STICK_BG_LINE : I_STICK_BG; + static const int comboKeyImages[5] = { I_1, I_2, I_3, I_4, I_5 }; - if (!System_GetPropertyBool(SYSPROP_HAS_BACK_BUTTON) || g_Config.bShowTouchPause) { - root->Add(new BoolButton(pause, roundImage, I_ARROW, 1.0f, new AnchorLayoutParams(halfW, 20, NONE, NONE, true)))->SetAngle(90); + auto addPSPButton = [=](int buttonBit, int bgImg, int img, const ConfigTouchPos &touch, ButtonOffset off = { 0, 0 }) -> PSPButton * { + if (touch.show) { + return root->Add(new PSPButton(buttonBit, bgImg, img, touch.scale, buttonLayoutParams(touch, off))); } + return nullptr; + }; + auto addComboKey = [=](int buttonBit, int bgImg, int img, const ConfigTouchPos &touch) -> ComboKey * { + if (touch.show) { + return root->Add(new ComboKey(buttonBit, bgImg, img, touch.scale, buttonLayoutParams(touch))); + } + return nullptr; + }; + auto addBoolButton = [=](bool *value, int bgImg, int img, const ConfigTouchPos &touch) -> BoolButton * { + if (touch.show) { + return root->Add(new BoolButton(value, bgImg, img, touch.scale, buttonLayoutParams(touch))); + } + return nullptr; + }; + auto addFPSLimitButton = [=](FPSLimit value, int bgImg, int img, const ConfigTouchPos &touch) -> FPSLimitButton * { + if (touch.show) { + return root->Add(new FPSLimitButton(value, bgImg, img, touch.scale, buttonLayoutParams(touch))); + } + return nullptr; + }; - if (g_Config.bShowTouchCircle) - root->Add(new PSPButton(CTRL_CIRCLE, roundImage, I_CIRCLE, Action_button_scale, new AnchorLayoutParams(Action_circle_button_X, Action_circle_button_Y, NONE, NONE, true))); - - if (g_Config.bShowTouchCross) - root->Add(new PSPButton(CTRL_CROSS, roundImage, I_CROSS, Action_button_scale, new AnchorLayoutParams(Action_cross_button_X, Action_cross_button_Y, NONE, NONE, true))); - - if (g_Config.bShowTouchTriangle) - root->Add(new PSPButton(CTRL_TRIANGLE, roundImage, I_TRIANGLE, Action_button_scale, new AnchorLayoutParams(Action_triangle_button_X, Action_triangle_button_Y, NONE, NONE, true))); - - if (g_Config.bShowTouchSquare) - root->Add(new PSPButton(CTRL_SQUARE, roundImage, I_SQUARE, Action_button_scale, new AnchorLayoutParams(Action_square_button_X, Action_square_button_Y, NONE, NONE, true))); - - if (g_Config.bShowTouchStart) - root->Add(new PSPButton(CTRL_START, rectImage, I_START, start_key_scale, new AnchorLayoutParams(start_key_X, start_key_Y, NONE, NONE, true))); - - if (g_Config.bShowTouchSelect) - root->Add(new PSPButton(CTRL_SELECT, rectImage, I_SELECT, select_key_scale, new AnchorLayoutParams(select_key_X, select_key_Y, NONE, NONE, true))); - - if (g_Config.bShowTouchUnthrottle) - root->Add(new BoolButton(&PSP_CoreParameter().unthrottle, rectImage, I_ARROW, unthrottle_key_scale, new AnchorLayoutParams(unthrottle_key_X, unthrottle_key_Y, NONE, NONE, true)))->SetAngle(180); - - if (g_Config.bShowTouchLTrigger) - root->Add(new PSPButton(CTRL_LTRIGGER, shoulderImage, I_L, l_key_scale, new AnchorLayoutParams(l_key_X, l_key_Y, NONE, NONE, true))); - - if (g_Config.bShowTouchRTrigger) - root->Add(new PSPButton(CTRL_RTRIGGER, shoulderImage, I_R, r_key_scale, new AnchorLayoutParams(r_key_X,r_key_Y, NONE, NONE, true)))->FlipImageH(true); - - if (g_Config.bShowTouchDpad) - root->Add(new PSPDpad(dirImage, I_ARROW, D_pad_scale, D_pad_spacing, new AnchorLayoutParams(D_pad_X, D_pad_Y, NONE, NONE, true))); - - if (g_Config.bShowTouchAnalogStick) - root->Add(new PSPStick(stickBg, stickImage, 0, analog_stick_scale, new AnchorLayoutParams(analog_stick_X, analog_stick_Y, NONE, NONE, true))); - - if (g_Config.bShowComboKey0) - root->Add(new ComboKey(g_Config.iCombokey0, roundImage, comboKeyImages[0], combo_key_scale, new AnchorLayoutParams(combo0_key_X, combo0_key_Y, NONE, NONE, true))); - - if (g_Config.bShowComboKey1) - root->Add(new ComboKey(g_Config.iCombokey1, roundImage, comboKeyImages[1], combo1_key_scale, new AnchorLayoutParams(combo1_key_X, combo1_key_Y, NONE, NONE, true))); - - if (g_Config.bShowComboKey2) - root->Add(new ComboKey(g_Config.iCombokey2, roundImage, comboKeyImages[2], combo2_key_scale, new AnchorLayoutParams(combo2_key_X, combo2_key_Y, NONE, NONE, true))); - - if (g_Config.bShowComboKey3) - root->Add(new ComboKey(g_Config.iCombokey3, roundImage, comboKeyImages[3], combo3_key_scale, new AnchorLayoutParams(combo3_key_X, combo3_key_Y, NONE, NONE, true))); - - if (g_Config.bShowComboKey4) - root->Add(new ComboKey(g_Config.iCombokey4, roundImage, comboKeyImages[4], combo4_key_scale, new AnchorLayoutParams(combo4_key_X, combo4_key_Y, NONE, NONE, true))); + if (!System_GetPropertyBool(SYSPROP_HAS_BACK_BUTTON) || g_Config.bShowTouchPause) { + root->Add(new BoolButton(pause, roundImage, I_ARROW, 1.0f, new AnchorLayoutParams(halfW, 20, NONE, NONE, true)))->SetAngle(90); } + // touchActionButtonCenter.show will always be true, since that's the default. + if (g_Config.bShowTouchCircle) + addPSPButton(CTRL_CIRCLE, roundImage, I_CIRCLE, g_Config.touchActionButtonCenter, circleOffset); + if (g_Config.bShowTouchCross) + addPSPButton(CTRL_CROSS, roundImage, I_CROSS, g_Config.touchActionButtonCenter, crossOffset); + if (g_Config.bShowTouchTriangle) + addPSPButton(CTRL_TRIANGLE, roundImage, I_TRIANGLE, g_Config.touchActionButtonCenter, triangleOffset); + if (g_Config.bShowTouchSquare) + addPSPButton(CTRL_SQUARE, roundImage, I_SQUARE, g_Config.touchActionButtonCenter, squareOffset); + + addPSPButton(CTRL_START, rectImage, I_START, g_Config.touchStartKey); + addPSPButton(CTRL_SELECT, rectImage, I_SELECT, g_Config.touchSelectKey); + + BoolButton *unthrottle = addBoolButton(&PSP_CoreParameter().unthrottle, rectImage, I_ARROW, g_Config.touchUnthrottleKey); + if (unthrottle) { + unthrottle->SetAngle(180.0f); + unthrottle->OnChange.Add([](UI::EventParams &e) { + if (e.a) { + Core_EnableStepping(false); + } + return UI::EVENT_DONE; + }); + } + + FPSLimitButton *speed1 = addFPSLimitButton(FPSLimit::CUSTOM1, rectImage, I_ARROW, g_Config.touchSpeed1Key); + if (speed1) + speed1->SetAngle(170.0f, 180.0f); + FPSLimitButton *speed2 = addFPSLimitButton(FPSLimit::CUSTOM2, rectImage, I_ARROW, g_Config.touchSpeed2Key); + if (speed2) + speed2->SetAngle(190.0f, 180.0f); + + addPSPButton(CTRL_LTRIGGER, shoulderImage, I_L, g_Config.touchLKey); + PSPButton *rTrigger = addPSPButton(CTRL_RTRIGGER, shoulderImage, I_R, g_Config.touchRKey); + if (rTrigger) + rTrigger->FlipImageH(true); + + if (g_Config.touchDpad.show) + root->Add(new PSPDpad(dirImage, I_ARROW, g_Config.touchDpad.scale, g_Config.fDpadSpacing, buttonLayoutParams(g_Config.touchDpad))); + + if (g_Config.touchAnalogStick.show) + root->Add(new PSPStick(stickBg, stickImage, 0, g_Config.touchAnalogStick.scale, buttonLayoutParams(g_Config.touchAnalogStick))); + + addComboKey(g_Config.iCombokey0, roundImage, comboKeyImages[0], g_Config.touchCombo0); + addComboKey(g_Config.iCombokey1, roundImage, comboKeyImages[1], g_Config.touchCombo1); + addComboKey(g_Config.iCombokey2, roundImage, comboKeyImages[2], g_Config.touchCombo2); + addComboKey(g_Config.iCombokey3, roundImage, comboKeyImages[3], g_Config.touchCombo3); + addComboKey(g_Config.iCombokey4, roundImage, comboKeyImages[4], g_Config.touchCombo4); + return root; } diff --git a/UI/GamepadEmu.h b/UI/GamepadEmu.h index 79e72bcf43..087fa7da8d 100644 --- a/UI/GamepadEmu.h +++ b/UI/GamepadEmu.h @@ -22,6 +22,7 @@ #include "ui/view.h" #include "ui/viewgroup.h" +#include "Core/CoreParameter.h" class GamepadView : public UI::View { public: @@ -43,7 +44,7 @@ protected: class MultiTouchButton : public GamepadView { public: MultiTouchButton(int bgImg, int img, float scale, UI::LayoutParams *layoutParams) - : GamepadView(layoutParams), pointerDownMask_(0), scale_(scale), bgImg_(bgImg), img_(img), angle_(0.0f), flipImageH_(false) { + : GamepadView(layoutParams), scale_(scale), bgImg_(bgImg), img_(img) { } void Touch(const TouchInput &input) override; @@ -52,17 +53,19 @@ public: virtual bool IsDown() { return pointerDownMask_ != 0; } // chainable MultiTouchButton *FlipImageH(bool flip) { flipImageH_ = flip; return this; } - MultiTouchButton *SetAngle(float angle) { angle_ = angle; return this; } + MultiTouchButton *SetAngle(float angle) { angle_ = angle; bgAngle_ = angle; return this; } + MultiTouchButton *SetAngle(float angle, float bgAngle) { angle_ = angle; bgAngle_ = bgAngle; return this; } protected: - uint32_t pointerDownMask_; + uint32_t pointerDownMask_ = 0; float scale_; private: int bgImg_; int img_; - float angle_; - bool flipImageH_; + float bgAngle_ = 0.0f; + float angle_ = 0.0f; + bool flipImageH_ = false; }; class BoolButton : public MultiTouchButton { @@ -74,10 +77,25 @@ public: void Touch(const TouchInput &input) override; bool IsDown() override { return *value_; } + UI::Event OnChange; + private: bool *value_; }; +class FPSLimitButton : public MultiTouchButton { +public: + FPSLimitButton(FPSLimit limit, int bgImg, int img, float scale, UI::LayoutParams *layoutParams) + : MultiTouchButton(bgImg, img, scale, layoutParams), limit_(limit) { + + } + void Touch(const TouchInput &input) override; + bool IsDown() override; + +private: + FPSLimit limit_; +}; + class PSPButton : public MultiTouchButton { public: PSPButton(int pspButtonBit, int bgImg, int img, float scale, UI::LayoutParams *layoutParams) diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 2d9326969a..bd9c3937ee 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -71,6 +71,7 @@ #include "Common/MemArena.h" #include "Common/GraphicsContext.h" #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "Core/Core.h" #include "Core/FileLoaders/DiskCachingFileLoader.h" #include "Core/Host.h" diff --git a/UI/TouchControlLayoutScreen.cpp b/UI/TouchControlLayoutScreen.cpp index 87dee45e31..fc841f4e8c 100644 --- a/UI/TouchControlLayoutScreen.cpp +++ b/UI/TouchControlLayoutScreen.cpp @@ -42,9 +42,9 @@ static u32 GetButtonColor() { class DragDropButton : public MultiTouchButton { public: - DragDropButton(float &x, float &y, int bgImg, int img, float &scale) - : MultiTouchButton(bgImg, img, scale, new UI::AnchorLayoutParams(fromFullscreenCoord(x), y*local_dp_yres, UI::NONE, UI::NONE, true)), - x_(x), y_(y), theScale_(scale) { + DragDropButton(ConfigTouchPos &pos, int bgImg, int img) + : MultiTouchButton(bgImg, img, pos.scale, new UI::AnchorLayoutParams(fromFullscreenCoord(pos.x), pos.y * local_dp_yres, UI::NONE, UI::NONE, true)), + x_(pos.x), y_(pos.y), theScale_(pos.scale) { scale_ = theScale_; } @@ -89,8 +89,8 @@ private: class PSPActionButtons : public DragDropButton { public: - PSPActionButtons(float &x, float &y, float &scale, float &spacing) - : DragDropButton(x, y, -1, -1, scale), spacing_(spacing) { + PSPActionButtons(ConfigTouchPos &pos, float &spacing) + : DragDropButton(pos, -1, -1), spacing_(spacing) { using namespace UI; roundId_ = g_Config.iTouchButtonStyle ? I_ROUND_LINE : I_ROUND; @@ -172,8 +172,8 @@ private: class PSPDPadButtons : public DragDropButton { public: - PSPDPadButtons(float &x, float &y, float &scale, float &spacing) - : DragDropButton(x, y, -1, -1, scale), spacing_(spacing) { + PSPDPadButtons(ConfigTouchPos &pos, float &spacing) + : DragDropButton(pos, -1, -1), spacing_(spacing) { } void Draw(UIContext &dc) override { @@ -361,7 +361,7 @@ void TouchControlLayoutScreen::CreateViews() { controls_.clear(); - PSPActionButtons *actionButtons = new PSPActionButtons(g_Config.fActionButtonCenterX, g_Config.fActionButtonCenterY, g_Config.fActionButtonScale, g_Config.fActionButtonSpacing); + PSPActionButtons *actionButtons = new PSPActionButtons(g_Config.touchActionButtonCenter, g_Config.fActionButtonSpacing); actionButtons->setCircleVisibility(g_Config.bShowTouchCircle); actionButtons->setCrossVisibility(g_Config.bShowTouchCross); actionButtons->setTriangleVisibility(g_Config.bShowTouchTriangle); @@ -378,51 +378,63 @@ void TouchControlLayoutScreen::CreateViews() { const int comboKeyImages[5] = { I_1, I_2, I_3, I_4, I_5 }; - if (g_Config.bShowTouchDpad) { - controls_.push_back(new PSPDPadButtons(g_Config.fDpadX, g_Config.fDpadY, g_Config.fDpadScale, g_Config.fDpadSpacing)); + if (g_Config.touchDpad.show) { + controls_.push_back(new PSPDPadButtons(g_Config.touchDpad, g_Config.fDpadSpacing)); } - if (g_Config.bShowTouchSelect) { - controls_.push_back(new DragDropButton(g_Config.fSelectKeyX, g_Config.fSelectKeyY, rectImage, I_SELECT, g_Config.fSelectKeyScale)); + if (g_Config.touchSelectKey.show) { + controls_.push_back(new DragDropButton(g_Config.touchSelectKey, rectImage, I_SELECT)); } - if (g_Config.bShowTouchStart) { - controls_.push_back(new DragDropButton(g_Config.fStartKeyX, g_Config.fStartKeyY, rectImage, I_START, g_Config.fStartKeyScale)); + if (g_Config.touchStartKey.show) { + controls_.push_back(new DragDropButton(g_Config.touchStartKey, rectImage, I_START)); } - if (g_Config.bShowTouchUnthrottle) { - DragDropButton *unthrottle = new DragDropButton(g_Config.fUnthrottleKeyX, g_Config.fUnthrottleKeyY, rectImage, I_ARROW, g_Config.fUnthrottleKeyScale); + if (g_Config.touchUnthrottleKey.show) { + DragDropButton *unthrottle = new DragDropButton(g_Config.touchUnthrottleKey, rectImage, I_ARROW); unthrottle->SetAngle(180.0f); controls_.push_back(unthrottle); } - if (g_Config.bShowTouchLTrigger) { - controls_.push_back(new DragDropButton(g_Config.fLKeyX, g_Config.fLKeyY, shoulderImage, I_L, g_Config.fLKeyScale)); + if (g_Config.touchSpeed1Key.show) { + DragDropButton *speed1 = new DragDropButton(g_Config.touchSpeed1Key, rectImage, I_ARROW); + speed1->SetAngle(170.0f, 180.0f); + controls_.push_back(speed1); } - if (g_Config.bShowTouchRTrigger) { - DragDropButton *rbutton = new DragDropButton(g_Config.fRKeyX, g_Config.fRKeyY, shoulderImage, I_R, g_Config.fRKeyScale); + if (g_Config.touchSpeed2Key.show) { + DragDropButton *speed2 = new DragDropButton(g_Config.touchSpeed2Key, rectImage, I_ARROW); + speed2->SetAngle(190.0f, 180.0f); + controls_.push_back(speed2); + } + + if (g_Config.touchLKey.show) { + controls_.push_back(new DragDropButton(g_Config.touchLKey, shoulderImage, I_L)); + } + + if (g_Config.touchRKey.show) { + DragDropButton *rbutton = new DragDropButton(g_Config.touchRKey, shoulderImage, I_R); rbutton->FlipImageH(true); controls_.push_back(rbutton); } - if (g_Config.bShowTouchAnalogStick) { - controls_.push_back(new DragDropButton(g_Config.fAnalogStickX, g_Config.fAnalogStickY, stickBg, stickImage, g_Config.fAnalogStickScale)); + if (g_Config.touchAnalogStick.show) { + controls_.push_back(new DragDropButton(g_Config.touchAnalogStick, stickBg, stickImage)); } - if (g_Config.bShowComboKey0) { - controls_.push_back(new DragDropButton(g_Config.fcombo0X, g_Config.fcombo0Y, roundImage, comboKeyImages[0], g_Config.fcomboScale0)); + if (g_Config.touchCombo0.show) { + controls_.push_back(new DragDropButton(g_Config.touchCombo0, roundImage, comboKeyImages[0])); } - if (g_Config.bShowComboKey1) { - controls_.push_back(new DragDropButton(g_Config.fcombo1X, g_Config.fcombo1Y, roundImage, comboKeyImages[1], g_Config.fcomboScale1)); + if (g_Config.touchCombo1.show) { + controls_.push_back(new DragDropButton(g_Config.touchCombo1, roundImage, comboKeyImages[1])); } - if (g_Config.bShowComboKey2) { - controls_.push_back(new DragDropButton(g_Config.fcombo2X, g_Config.fcombo2Y, roundImage, comboKeyImages[2], g_Config.fcomboScale2)); + if (g_Config.touchCombo2.show) { + controls_.push_back(new DragDropButton(g_Config.touchCombo2, roundImage, comboKeyImages[2])); } - if (g_Config.bShowComboKey3) { - controls_.push_back(new DragDropButton(g_Config.fcombo3X, g_Config.fcombo3Y, roundImage, comboKeyImages[3], g_Config.fcomboScale3)); + if (g_Config.touchCombo3.show) { + controls_.push_back(new DragDropButton(g_Config.touchCombo3, roundImage, comboKeyImages[3])); } - if (g_Config.bShowComboKey4) { - controls_.push_back(new DragDropButton(g_Config.fcombo4X, g_Config.fcombo4Y, roundImage, comboKeyImages[4], g_Config.fcomboScale4)); + if (g_Config.touchCombo4.show) { + controls_.push_back(new DragDropButton(g_Config.touchCombo4, roundImage, comboKeyImages[4])); }; for (size_t i = 0; i < controls_.size(); i++) { diff --git a/UI/TouchControlVisibilityScreen.cpp b/UI/TouchControlVisibilityScreen.cpp index 2d0381ede5..4e67d1cc5c 100644 --- a/UI/TouchControlVisibilityScreen.cpp +++ b/UI/TouchControlVisibilityScreen.cpp @@ -20,84 +20,91 @@ #include "UI/ui_atlas.h" #include "i18n/i18n.h" +static const int leftColumnWidth = 140; + +class CheckBoxChoice : public UI::Choice { +public: + CheckBoxChoice(const std::string &text, UI::CheckBox *checkbox, UI::LayoutParams *lp) + : Choice(text, lp), checkbox_(checkbox) { + OnClick.Handle(this, &CheckBoxChoice::HandleClick); + } + CheckBoxChoice(ImageID imgID, UI::CheckBox *checkbox, UI::LayoutParams *lp) + : Choice(imgID, lp), checkbox_(checkbox) { + OnClick.Handle(this, &CheckBoxChoice::HandleClick); + } + +private: + UI::EventReturn HandleClick(UI::EventParams &e); + + UI::CheckBox *checkbox_; +}; + void TouchControlVisibilityScreen::CreateViews() { using namespace UI; - root_ = new ScrollView(ORIENT_VERTICAL); - LinearLayout *vert = root_->Add(new LinearLayout(ORIENT_VERTICAL, new LayoutParams(FILL_PARENT, FILL_PARENT))); + I18NCategory *di = GetI18NCategory("Dialog"); + I18NCategory *co = GetI18NCategory("Controls"); + + root_ = new AnchorLayout(new LayoutParams(FILL_PARENT, FILL_PARENT)); + + Choice *back = new Choice(di->T("Back"), "", false, new AnchorLayoutParams(leftColumnWidth - 10, WRAP_CONTENT, 10, NONE, NONE, 10)); + root_->Add(back)->OnClick.Handle(this, &UIScreen::OnBack); + Choice *toggleAll = new Choice(di->T("Toggle All"), "", false, new AnchorLayoutParams(leftColumnWidth - 10, WRAP_CONTENT, 10, NONE, NONE, 84)); + root_->Add(toggleAll)->OnClick.Handle(this, &TouchControlVisibilityScreen::OnToggleAll); + + TabHolder *tabHolder = new TabHolder(ORIENT_VERTICAL, leftColumnWidth, new AnchorLayoutParams(10, 0, 10, 0, false)); + tabHolder->SetTag("TouchControlVisibility"); + root_->Add(tabHolder); + ScrollView *rightPanel = new ScrollView(ORIENT_VERTICAL); + tabHolder->AddTab(co->T("Visibility"), rightPanel); + + LinearLayout *vert = rightPanel->Add(new LinearLayout(ORIENT_VERTICAL, new LayoutParams(FILL_PARENT, FILL_PARENT))); vert->SetSpacing(0); - LinearLayout *topBar = new LinearLayout(ORIENT_HORIZONTAL); - I18NCategory *di = GetI18NCategory("Dialog"); - topBar->Add(new Choice(di->T("Back")))->OnClick.Handle(this, &UIScreen::OnBack); - topBar->Add(new Choice(di->T("Toggle All")))->OnClick.Handle(this, &TouchControlVisibilityScreen::OnToggleAll); - - vert->Add(topBar); - I18NCategory *co = GetI18NCategory("Controls"); vert->Add(new ItemHeader(co->T("Touch Control Visibility"))); - const int cellSize = 400; + const int cellSize = 380; UI::GridLayoutSettings gridsettings(cellSize, 64, 5); gridsettings.fillCells = true; GridLayout *grid = vert->Add(new GridLayout(gridsettings, new LayoutParams(FILL_PARENT, WRAP_CONTENT))); - std::map keyImages; - keyImages["Circle"] = I_CIRCLE; - keyImages["Cross"] = I_CROSS; - keyImages["Square"] = I_SQUARE; - keyImages["Triangle"] = I_TRIANGLE; - keyImages["Start"] = I_START; - keyImages["Select"] = I_SELECT; - keyImages["L"] = I_L; - keyImages["R"] = I_R; - keyImages["Combo0"] = I_1; - keyImages["Combo1"] = I_2; - keyImages["Combo2"] = I_3; - keyImages["Combo3"] = I_4; - keyImages["Combo4"] = I_5; - - keyToggles.clear(); - keyToggles["Circle"] = &g_Config.bShowTouchCircle; - keyToggles["Cross"] = &g_Config.bShowTouchCross; - keyToggles["Square"] = &g_Config.bShowTouchSquare; - keyToggles["Triangle"] = &g_Config.bShowTouchTriangle; - keyToggles["L"] = &g_Config.bShowTouchLTrigger; - keyToggles["R"] = &g_Config.bShowTouchRTrigger; - keyToggles["Start"] = &g_Config.bShowTouchStart; - keyToggles["Select"] = &g_Config.bShowTouchSelect; - keyToggles["Dpad"] = &g_Config.bShowTouchDpad; - keyToggles["Analog Stick"] = &g_Config.bShowTouchAnalogStick; - keyToggles["Unthrottle"] = &g_Config.bShowTouchUnthrottle; - keyToggles["Combo0"] = &g_Config.bShowComboKey0; - keyToggles["Combo1"] = &g_Config.bShowComboKey1; - keyToggles["Combo2"] = &g_Config.bShowComboKey2; - keyToggles["Combo3"] = &g_Config.bShowComboKey3; - keyToggles["Combo4"] = &g_Config.bShowComboKey4; - - std::map::iterator imageFinder; + toggles_.clear(); + toggles_.push_back({ "Circle", &g_Config.bShowTouchCircle, I_CIRCLE }); + toggles_.push_back({ "Cross", &g_Config.bShowTouchCross, I_CROSS }); + toggles_.push_back({ "Square", &g_Config.bShowTouchSquare, I_SQUARE }); + toggles_.push_back({ "Triangle", &g_Config.bShowTouchTriangle, I_TRIANGLE }); + toggles_.push_back({ "L", &g_Config.touchLKey.show, I_L }); + toggles_.push_back({ "R", &g_Config.touchRKey.show, I_R }); + toggles_.push_back({ "Start", &g_Config.touchStartKey.show, I_START }); + toggles_.push_back({ "Select", &g_Config.touchSelectKey.show, I_SELECT }); + toggles_.push_back({ "Dpad", &g_Config.touchDpad.show, -1 }); + toggles_.push_back({ "Analog Stick", &g_Config.touchAnalogStick.show, -1 }); + toggles_.push_back({ "Unthrottle", &g_Config.touchUnthrottleKey.show, -1 }); + toggles_.push_back({ "Combo0", &g_Config.touchCombo0.show, I_1 }); + toggles_.push_back({ "Combo1", &g_Config.touchCombo1.show, I_2 }); + toggles_.push_back({ "Combo2", &g_Config.touchCombo2.show, I_3 }); + toggles_.push_back({ "Combo3", &g_Config.touchCombo3.show, I_4 }); + toggles_.push_back({ "Combo4", &g_Config.touchCombo4.show, I_5 }); + toggles_.push_back({ "Alt speed 1", &g_Config.touchSpeed1Key.show, -1 }); + toggles_.push_back({ "Alt speed 2", &g_Config.touchSpeed2Key.show, -1 }); I18NCategory *mc = GetI18NCategory("MappableControls"); - for (auto i = keyToggles.begin(); i != keyToggles.end(); ++i) { + for (auto toggle : toggles_) { LinearLayout *row = new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)); row->SetSpacing(0); - CheckBox *checkbox = new CheckBox(i->second, "", "", new LinearLayoutParams(50, WRAP_CONTENT)); + CheckBox *checkbox = new CheckBox(toggle.show, "", "", new LinearLayoutParams(50, WRAP_CONTENT)); row->Add(checkbox); - imageFinder = keyImages.find(i->first); Choice *choice; - - if (imageFinder != keyImages.end()) { - choice = new Choice(keyImages[imageFinder->first], new LinearLayoutParams(1.0f)); + if (toggle.img != -1) { + choice = new CheckBoxChoice(toggle.img, checkbox, new LinearLayoutParams(1.0f)); } else { - choice = new Choice(mc->T(i->first.c_str()), new LinearLayoutParams(1.0f)); + choice = new CheckBoxChoice(mc->T(toggle.key), checkbox, new LinearLayoutParams(1.0f)); } - ChoiceEventHandler *choiceEventHandler = new ChoiceEventHandler(checkbox); - choice->OnClick.Handle(choiceEventHandler, &ChoiceEventHandler::onChoiceClick); - choice->SetCentered(true); row->Add(choice); @@ -110,16 +117,15 @@ void TouchControlVisibilityScreen::onFinish(DialogResult result) { } UI::EventReturn TouchControlVisibilityScreen::OnToggleAll(UI::EventParams &e) { - for (auto i = keyToggles.begin(); i != keyToggles.end(); ++i) { - *i->second = toggleSwitch; + for (auto toggle : toggles_) { + *toggle.show = nextToggleAll_; } - - toggleSwitch = !toggleSwitch; + nextToggleAll_ = !nextToggleAll_; return UI::EVENT_DONE; } -UI::EventReturn TouchControlVisibilityScreen::ChoiceEventHandler::onChoiceClick(UI::EventParams &e){ +UI::EventReturn CheckBoxChoice::HandleClick(UI::EventParams &e) { checkbox_->Toggle(); return UI::EVENT_DONE; diff --git a/UI/TouchControlVisibilityScreen.h b/UI/TouchControlVisibilityScreen.h index d7f98885f0..88455a343e 100644 --- a/UI/TouchControlVisibilityScreen.h +++ b/UI/TouchControlVisibilityScreen.h @@ -19,16 +19,18 @@ #include "MiscScreens.h" -#include - namespace UI { class CheckBox; } +struct TouchButtonToggle { + const char *key; + bool *show; + int img; +}; + class TouchControlVisibilityScreen : public UIDialogScreenWithBackground { public: - TouchControlVisibilityScreen() : toggleSwitch(true){ } - void CreateViews() override; void onFinish(DialogResult result) override; @@ -36,14 +38,6 @@ protected: UI::EventReturn OnToggleAll(UI::EventParams &e); private: - std::map keyToggles; - bool toggleSwitch; - - class ChoiceEventHandler{ - public: - ChoiceEventHandler(UI::CheckBox *checkbox) : checkbox_(checkbox) {} - UI::EventReturn onChoiceClick(UI::EventParams &e); - private: - UI::CheckBox *checkbox_; - }; + std::vector toggles_; + bool nextToggleAll_ = true; }; diff --git a/Windows/DSoundStream.cpp b/Windows/DSoundStream.cpp index 79d8d2699e..ca15e20856 100644 --- a/Windows/DSoundStream.cpp +++ b/Windows/DSoundStream.cpp @@ -12,6 +12,7 @@ #include "thread/threadutil.h" #include "Common/OSVersion.h" +#include "Core/ConfigValues.h" #include "Core/Reporting.h" #include "Core/Util/AudioFormat.h" #include "Windows/W32Util/Misc.h" diff --git a/Windows/DSoundStream.h b/Windows/DSoundStream.h index 95aee96326..fa101f4b71 100644 --- a/Windows/DSoundStream.h +++ b/Windows/DSoundStream.h @@ -2,6 +2,7 @@ #include "Common/CommonWindows.h" #include "Core/Config.h" +#include "Core/ConfigValues.h" typedef int (*StreamCallback)(short *buffer, int numSamples, int bits, int rate, int channels); diff --git a/Windows/EmuThread.cpp b/Windows/EmuThread.cpp index 34cf5846e8..987bb8b5e4 100644 --- a/Windows/EmuThread.cpp +++ b/Windows/EmuThread.cpp @@ -22,6 +22,7 @@ #include "Core/Host.h" #include "Core/System.h" #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "thread/threadutil.h" enum class EmuThreadState { diff --git a/Windows/GPU/D3D11Context.cpp b/Windows/GPU/D3D11Context.cpp index 7e6b748271..806458b1e8 100644 --- a/Windows/GPU/D3D11Context.cpp +++ b/Windows/GPU/D3D11Context.cpp @@ -10,6 +10,7 @@ #include "i18n/i18n.h" #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "Core/Reporting.h" #include "Core/System.h" #include "Windows/GPU/D3D11Context.h" diff --git a/Windows/GPU/D3D9Context.cpp b/Windows/GPU/D3D9Context.cpp index ad71c0a48d..80933615b2 100644 --- a/Windows/GPU/D3D9Context.cpp +++ b/Windows/GPU/D3D9Context.cpp @@ -8,6 +8,7 @@ #include "i18n/i18n.h" #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "Core/Reporting.h" #include "Core/System.h" #include "Common/OSVersion.h" diff --git a/Windows/GPU/WindowsGLContext.cpp b/Windows/GPU/WindowsGLContext.cpp index 7004fdde24..f3808583b0 100644 --- a/Windows/GPU/WindowsGLContext.cpp +++ b/Windows/GPU/WindowsGLContext.cpp @@ -26,6 +26,7 @@ #include "GL/gl.h" #include "GL/wglew.h" #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "Core/Core.h" #include "util/text/utf8.h" #include "i18n/i18n.h" diff --git a/Windows/GPU/WindowsVulkanContext.cpp b/Windows/GPU/WindowsVulkanContext.cpp index e82b5bc92b..ad619ab339 100644 --- a/Windows/GPU/WindowsVulkanContext.cpp +++ b/Windows/GPU/WindowsVulkanContext.cpp @@ -51,6 +51,7 @@ #include #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "Core/System.h" #include "Common/Vulkan/VulkanLoader.h" #include "Common/Vulkan/VulkanContext.h" diff --git a/Windows/MainWindow.cpp b/Windows/MainWindow.cpp index 67a820042e..83b5286771 100644 --- a/Windows/MainWindow.cpp +++ b/Windows/MainWindow.cpp @@ -42,6 +42,7 @@ #include "Core/Core.h" #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "Core/Debugger/SymbolMap.h" #include "Core/MIPS/JitCommon/JitCommon.h" #include "Core/MIPS/JitCommon/JitBlockCache.h" diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp index 280d4bf136..0999a47c7e 100644 --- a/Windows/MainWindowMenu.cpp +++ b/Windows/MainWindowMenu.cpp @@ -20,6 +20,7 @@ #include "GPU/Common/PostShader.h" #include "GPU/GLES/FramebufferManagerGLES.h" #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "Core/FileSystems/MetaFileSystem.h" #include "UI/OnScreenDisplay.h" #include "Windows/MainWindowMenu.h" @@ -516,10 +517,6 @@ namespace MainWindow { NativeMessageReceived("gpu_resized", ""); } - static void setFpsLimit(int fps) { - g_Config.iFpsLimit = fps; - } - static void setFrameSkipping(int framesToSkip = -1) { if (framesToSkip >= FRAMESKIP_OFF) g_Config.iFrameSkip = framesToSkip; @@ -1066,7 +1063,7 @@ namespace MainWindow { CHECKITEM(ID_OPTIONS_VERTEXCACHE, g_Config.bVertexCache); CHECKITEM(ID_OPTIONS_SHOWFPS, g_Config.iShowFPSCounter); CHECKITEM(ID_OPTIONS_FRAMESKIP_AUTO, g_Config.bAutoFrameSkip); - CHECKITEM(ID_OPTIONS_FRAMESKIP, g_Config.iFrameSkip != 0); + CHECKITEM(ID_OPTIONS_FRAMESKIP, g_Config.iFrameSkip != FRAMESKIP_OFF); CHECKITEM(ID_OPTIONS_VSYNC, g_Config.bVSync); CHECKITEM(ID_OPTIONS_TOPMOST, g_Config.bTopMost); CHECKITEM(ID_OPTIONS_PAUSE_FOCUS, g_Config.bPauseOnLostFocus); diff --git a/Windows/WindowsHost.cpp b/Windows/WindowsHost.cpp index 168f87c902..5372d655a1 100644 --- a/Windows/WindowsHost.cpp +++ b/Windows/WindowsHost.cpp @@ -42,6 +42,7 @@ #include "Common/StringUtils.h" #include "Core/Core.h" #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "Core/CoreParameter.h" #include "Core/System.h" #include "Core/Debugger/SymbolMap.h" diff --git a/Windows/main.cpp b/Windows/main.cpp index a003e3739a..01c0fe6664 100644 --- a/Windows/main.cpp +++ b/Windows/main.cpp @@ -36,6 +36,7 @@ #include "net/resolve.h" #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "Core/SaveState.h" #include "Windows/EmuThread.h" #include "Windows/DSoundStream.h" diff --git a/android/jni/AndroidEGLContext.cpp b/android/jni/AndroidEGLContext.cpp index 3eb13c8689..34d21597f5 100644 --- a/android/jni/AndroidEGLContext.cpp +++ b/android/jni/AndroidEGLContext.cpp @@ -6,6 +6,7 @@ #include "AndroidEGLContext.h" #include "GL/GLInterface/EGLAndroid.h" +#include "Core/ConfigValues.h" #include "Core/System.h" bool AndroidEGLGraphicsContext::InitFromRenderThread(ANativeWindow *wnd, int desiredBackbufferSizeX, int desiredBackbufferSizeY, int backbufferFormat, int androidVersion) { diff --git a/android/jni/AndroidJavaGLContext.cpp b/android/jni/AndroidJavaGLContext.cpp index 0f0937db08..aca9f8fcc9 100644 --- a/android/jni/AndroidJavaGLContext.cpp +++ b/android/jni/AndroidJavaGLContext.cpp @@ -3,6 +3,7 @@ #include "AndroidJavaGLContext.h" #include "base/NativeApp.h" #include "gfx_es2/gpu_features.h" +#include "Core/ConfigValues.h" #include "Core/System.h" AndroidJavaEGLGraphicsContext::AndroidJavaEGLGraphicsContext() { diff --git a/android/jni/AndroidVulkanContext.cpp b/android/jni/AndroidVulkanContext.cpp index 4240bde18c..128183dcc9 100644 --- a/android/jni/AndroidVulkanContext.cpp +++ b/android/jni/AndroidVulkanContext.cpp @@ -9,6 +9,7 @@ #include "thin3d/thin3d_create.h" #include "util/text/parsers.h" #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "Core/System.h" static VulkanLogOptions g_LogOptions; diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index 38fc3f6582..9206bcd59b 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -43,6 +43,7 @@ #include "AndroidJavaGLContext.h" #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "Core/Loaders.h" #include "Core/System.h" #include "Common/CPUDetect.h" diff --git a/ext/native/ui/ui_screen.cpp b/ext/native/ui/ui_screen.cpp index b4a4edb76b..3339c8d25b 100644 --- a/ext/native/ui/ui_screen.cpp +++ b/ext/native/ui/ui_screen.cpp @@ -516,6 +516,8 @@ EventReturn PopupSliderChoice::HandleClick(EventParams &e) { restoreFocus_ = HasFocus(); SliderPopupScreen *popupScreen = new SliderPopupScreen(value_, minValue_, maxValue_, ChopTitle(text_), step_, units_); + if (!negativeLabel_.empty()) + popupScreen->SetNegativeDisable(negativeLabel_); popupScreen->OnChange.Handle(this, &PopupSliderChoice::HandleChange); if (e.v) popupScreen->SetPopupOrigin(e.v); @@ -541,9 +543,12 @@ void PopupSliderChoice::Draw(UIContext &dc) { int paddingX = 12; dc.SetFontStyle(dc.theme->uiFont); - char temp[32]; + // Always good to have space for Unicode. + char temp[256]; if (zeroLabel_.size() && *value_ == 0) { strcpy(temp, zeroLabel_.c_str()); + } else if (negativeLabel_.size() && *value_ < 0) { + strcpy(temp, negativeLabel_.c_str()); } else { sprintf(temp, fmt_, *value_); } @@ -585,7 +590,7 @@ void PopupSliderChoiceFloat::Draw(UIContext &dc) { int paddingX = 12; dc.SetFontStyle(dc.theme->uiFont); - char temp[32]; + char temp[256]; if (zeroLabel_.size() && *value_ == 0.0f) { strcpy(temp, zeroLabel_.c_str()); } else { @@ -611,6 +616,7 @@ EventReturn SliderPopupScreen::OnDecrease(EventParams ¶ms) { sprintf(temp, "%d", sliderValue_); edit_->SetText(temp); changing_ = false; + disabled_ = false; return EVENT_DONE; } @@ -625,6 +631,7 @@ EventReturn SliderPopupScreen::OnIncrease(EventParams ¶ms) { sprintf(temp, "%d", sliderValue_); edit_->SetText(temp); changing_ = false; + disabled_ = false; return EVENT_DONE; } @@ -634,12 +641,14 @@ EventReturn SliderPopupScreen::OnSliderChange(EventParams ¶ms) { sprintf(temp, "%d", sliderValue_); edit_->SetText(temp); changing_ = false; + disabled_ = false; return EVENT_DONE; } EventReturn SliderPopupScreen::OnTextChange(EventParams ¶ms) { if (!changing_) { sliderValue_ = atoi(edit_->GetText().c_str()); + disabled_ = false; slider_->Clamp(); } return EVENT_DONE; @@ -650,6 +659,8 @@ void SliderPopupScreen::CreatePopupContents(UI::ViewGroup *parent) { UIContext &dc = *screenManager()->getUIContext(); sliderValue_ = *value_; + if (disabled_ && sliderValue_ < 0) + sliderValue_ = 0; LinearLayout *vert = parent->Add(new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(UI::Margins(10, 10)))); slider_ = new Slider(&sliderValue_, minValue_, maxValue_, new LinearLayoutParams(UI::Margins(10, 10))); slider_->OnChange.Handle(this, &SliderPopupScreen::OnSliderChange); @@ -672,6 +683,9 @@ void SliderPopupScreen::CreatePopupContents(UI::ViewGroup *parent) { if (!units_.empty()) lin->Add(new TextView(units_, new LinearLayoutParams(10.0f)))->SetTextColor(dc.theme->popupStyle.fgColor); + if (!negativeLabel_.empty()) + vert->Add(new CheckBox(&disabled_, negativeLabel_)); + if (IsFocusMovementEnabled()) UI::SetFocusedView(slider_); } @@ -754,7 +768,7 @@ EventReturn SliderFloatPopupScreen::OnTextChange(EventParams ¶ms) { void SliderPopupScreen::OnCompleted(DialogResult result) { if (result == DR_OK) { - *value_ = sliderValue_; + *value_ = disabled_ ? -1 : sliderValue_; EventParams e{}; e.v = nullptr; e.a = *value_; diff --git a/ext/native/ui/ui_screen.h b/ext/native/ui/ui_screen.h index fb0bda4494..99a6c486eb 100644 --- a/ext/native/ui/ui_screen.h +++ b/ext/native/ui/ui_screen.h @@ -169,9 +169,14 @@ namespace UI { class SliderPopupScreen : public PopupScreen { public: SliderPopupScreen(int *value, int minValue, int maxValue, const std::string &title, int step = 1, const std::string &units = "") - : PopupScreen(title, "OK", "Cancel"), units_(units), value_(value), minValue_(minValue), maxValue_(maxValue), step_(step), changing_(false) {} + : PopupScreen(title, "OK", "Cancel"), units_(units), value_(value), minValue_(minValue), maxValue_(maxValue), step_(step) {} virtual void CreatePopupContents(ViewGroup *parent) override; + void SetNegativeDisable(const std::string &str) { + negativeLabel_ = str; + disabled_ = *value_ < 0; + } + Event OnChange; private: @@ -183,12 +188,14 @@ private: Slider *slider_; UI::TextEdit *edit_; std::string units_; + std::string negativeLabel_; int *value_; int sliderValue_; int minValue_; int maxValue_; int step_; - bool changing_; + bool changing_ = false; + bool disabled_ = false; }; class SliderFloatPopupScreen : public PopupScreen { @@ -325,6 +332,9 @@ public: void SetZeroLabel(const std::string &str) { zeroLabel_ = str; } + void SetNegativeDisable(const std::string &str) { + negativeLabel_ = str; + } Event OnChange; @@ -338,6 +348,7 @@ private: int step_; const char *fmt_; std::string zeroLabel_; + std::string negativeLabel_; std::string units_; ScreenManager *screenManager_; bool restoreFocus_; diff --git a/headless/Headless.cpp b/headless/Headless.cpp index 8edea02384..e786e08c3b 100644 --- a/headless/Headless.cpp +++ b/headless/Headless.cpp @@ -11,12 +11,14 @@ #include "Common/FileUtil.h" #include "Common/GraphicsContext.h" #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "Core/Core.h" #include "Core/CoreTiming.h" #include "Core/System.h" #include "Core/HLE/sceUtility.h" #include "Core/Host.h" #include "Core/SaveState.h" +#include "GPU/Common/FramebufferCommon.h" #include "Log.h" #include "LogManager.h" #include "base/NativeApp.h" @@ -348,7 +350,7 @@ int main(int argc, const char* argv[]) // Never report from tests. g_Config.sReportHost = ""; g_Config.bAutoSaveSymbolMap = false; - g_Config.iRenderingMode = 1; + g_Config.iRenderingMode = FB_BUFFERED_MODE; g_Config.bHardwareTransform = true; g_Config.iAnisotropyLevel = 0; // When testing mipmapping we really don't want this. g_Config.bVertexCache = true; diff --git a/headless/SDLHeadlessHost.cpp b/headless/SDLHeadlessHost.cpp index a2ec3a9b51..1545a53f9c 100644 --- a/headless/SDLHeadlessHost.cpp +++ b/headless/SDLHeadlessHost.cpp @@ -27,6 +27,7 @@ #include "Common/GraphicsContext.h" #include "Core/CoreParameter.h" +#include "Core/ConfigValues.h" #include "Core/System.h" #include "GPU/Common/GPUDebugInterface.h" #include "GPU/GPUState.h" diff --git a/ios/ViewController.mm b/ios/ViewController.mm index 2b36a65ada..3ca85ebcdf 100644 --- a/ios/ViewController.mm +++ b/ios/ViewController.mm @@ -23,6 +23,7 @@ #include "gfx_es2/gpu_features.h" #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "Core/System.h" #include "Common/GraphicsContext.h" diff --git a/libretro/LibretroGLContext.cpp b/libretro/LibretroGLContext.cpp index c8a620c3cc..c8260650cb 100644 --- a/libretro/LibretroGLContext.cpp +++ b/libretro/LibretroGLContext.cpp @@ -1,6 +1,7 @@ #include "Common/Log.h" #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "Core/System.h" #include "gfx_es2/gpu_features.h" diff --git a/libretro/LibretroVulkanContext.cpp b/libretro/LibretroVulkanContext.cpp index 7530fd6916..5cc7d4f09b 100644 --- a/libretro/LibretroVulkanContext.cpp +++ b/libretro/LibretroVulkanContext.cpp @@ -4,6 +4,7 @@ #include "Common/Vulkan/VulkanDebug.h" #include "Common/Log.h" #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "Core/System.h" #include "GPU/GPUInterface.h" #include "util/text/parsers.h" diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp index ace31cefaf..e5cedb7298 100644 --- a/libretro/libretro.cpp +++ b/libretro/libretro.cpp @@ -8,6 +8,7 @@ #include "base/timeutil.h" #include "Common/ChunkFile.h" #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "Core/Core.h" #include "Core/HLE/sceCtrl.h" #include "Core/HLE/sceUtility.h" diff --git a/unittest/JitHarness.cpp b/unittest/JitHarness.cpp index 29ab315e44..a34f3f4952 100644 --- a/unittest/JitHarness.cpp +++ b/unittest/JitHarness.cpp @@ -19,6 +19,7 @@ #include "base/timeutil.h" #include "base/NativeApp.h" +#include "Core/ConfigValues.h" #include "Core/MIPS/JitCommon/JitCommon.h" #include "Core/MIPS/JitCommon/JitBlockCache.h" #include "Core/MIPS/MIPSCodeUtils.h" diff --git a/unittest/TestVertexJit.cpp b/unittest/TestVertexJit.cpp index 40dd640c8b..75e5985888 100644 --- a/unittest/TestVertexJit.cpp +++ b/unittest/TestVertexJit.cpp @@ -18,6 +18,7 @@ #include "base/timeutil.h" #include "Common/Common.h" #include "Core/Config.h" +#include "Core/ConfigValues.h" #include "GPU/Common/VertexDecoderCommon.h" #include "GPU/ge_constants.h" #include "GPU/GPUState.h"