mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-02-25 00:22:10 +00:00
UI: Add analog speed limit mapping.
Only shows up as a setting if mapped, to avoid cluttering settings.
This commit is contained in:
parent
536c050943
commit
c15c4a6967
@ -867,6 +867,8 @@ static ConfigSetting graphicsSettings[] = {
|
||||
ReportedConfigSetting("AutoFrameSkip", &g_Config.bAutoFrameSkip, false, true, true),
|
||||
ConfigSetting("FrameRate", &g_Config.iFpsLimit1, 0, true, true),
|
||||
ConfigSetting("FrameRate2", &g_Config.iFpsLimit2, -1, true, true),
|
||||
ConfigSetting("AnalogFrameRate", &g_Config.iAnalogFpsLimit, 240, true, true),
|
||||
ConfigSetting("AnalogFrameRateMode", &g_Config.iAnalogFpsMode, 0, true, true),
|
||||
ConfigSetting("UnthrottlingMode", &g_Config.iFastForwardMode, &DefaultFastForwardMode, &FastForwardModeToString, &FastForwardModeFromString, true, true),
|
||||
#if defined(USING_WIN_UI)
|
||||
ConfigSetting("RestartRequired", &g_Config.bRestartRequired, false, false),
|
||||
|
@ -214,6 +214,8 @@ public:
|
||||
bool bTexHardwareScaling;
|
||||
int iFpsLimit1;
|
||||
int iFpsLimit2;
|
||||
int iAnalogFpsLimit;
|
||||
int iAnalogFpsMode; // 0 = auto, 1 = single direction, 2 = mapped to opposite
|
||||
int iMaxRecent;
|
||||
int iCurrentStateSlot;
|
||||
int iRewindFlipFrequency;
|
||||
|
@ -130,3 +130,9 @@ enum class BackgroundAnimation {
|
||||
WAVE = 3,
|
||||
MOVING_BACKGROUND = 4,
|
||||
};
|
||||
|
||||
enum class AnalogFpsMode {
|
||||
AUTO = 0,
|
||||
MAPPED_DIRECTION = 1,
|
||||
MAPPED_TO_OPPOSITE = 2,
|
||||
};
|
||||
|
@ -7,6 +7,8 @@
|
||||
#include "Core/KeyMap.h"
|
||||
#include "Core/ControlMapper.h"
|
||||
#include "Core/Config.h"
|
||||
#include "Core/CoreParameter.h"
|
||||
#include "Core/System.h"
|
||||
|
||||
static float MapAxisValue(float v) {
|
||||
const float deadzone = g_Config.fAnalogDeadzone;
|
||||
@ -334,12 +336,21 @@ void ControlMapper::processAxis(const AxisInput &axis, int direction) {
|
||||
case VIRTKEY_AXIS_RIGHT_Y_MAX:
|
||||
SetPSPAxis('Y', value, CTRL_STICK_RIGHT);
|
||||
break;
|
||||
|
||||
case VIRTKEY_SPEED_ANALOG:
|
||||
ProcessAnalogSpeed(axis, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<int> resultsOpposite;
|
||||
KeyMap::AxisToPspButton(axis.deviceId, axis.axisId, -direction, &resultsOpposite);
|
||||
|
||||
for (int result : resultsOpposite) {
|
||||
if (result == VIRTKEY_SPEED_ANALOG)
|
||||
ProcessAnalogSpeed(axis, true);
|
||||
}
|
||||
|
||||
int axisState = 0;
|
||||
float threshold = axis.deviceId == DEVICE_ID_MOUSE ? AXIS_BIND_THRESHOLD_MOUSE : AXIS_BIND_THRESHOLD;
|
||||
if (direction == 1 && axis.value >= threshold) {
|
||||
@ -375,3 +386,55 @@ void ControlMapper::processAxis(const AxisInput &axis, int direction) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ControlMapper::ProcessAnalogSpeed(const AxisInput &axis, bool opposite) {
|
||||
FPSLimit &limitMode = PSP_CoreParameter().fpsLimit;
|
||||
// If we're using an alternate speed already, let that win.
|
||||
if (limitMode != FPSLimit::NORMAL && limitMode != FPSLimit::ANALOG)
|
||||
return;
|
||||
// Don't even try if the limit is invalid.
|
||||
if (g_Config.iAnalogFpsLimit <= 0)
|
||||
return;
|
||||
|
||||
AnalogFpsMode mode = (AnalogFpsMode)g_Config.iAnalogFpsMode;
|
||||
float value = axis.value;
|
||||
if (mode == AnalogFpsMode::AUTO) {
|
||||
// TODO: Consider the pad name for better auto? KeyMap::PadName(axis.deviceId);
|
||||
switch (axis.axisId) {
|
||||
case JOYSTICK_AXIS_X:
|
||||
case JOYSTICK_AXIS_Y:
|
||||
case JOYSTICK_AXIS_Z:
|
||||
case JOYSTICK_AXIS_RX:
|
||||
case JOYSTICK_AXIS_RY:
|
||||
case JOYSTICK_AXIS_RZ:
|
||||
// These, at least on directinput, can be used for triggers that go from mapped to opposite.
|
||||
mode = AnalogFpsMode::MAPPED_TO_OPPOSITE;
|
||||
break;
|
||||
|
||||
default:
|
||||
// Other axises probably don't go from negative to positive.
|
||||
mode = AnalogFpsMode::MAPPED_DIRECTION;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Okay, now let's map it as appropriate.
|
||||
if (mode == AnalogFpsMode::MAPPED_DIRECTION) {
|
||||
value = fabsf(value);
|
||||
if (opposite)
|
||||
return;
|
||||
} else if (mode == AnalogFpsMode::MAPPED_TO_OPPOSITE) {
|
||||
value = fabsf(value);
|
||||
if (opposite)
|
||||
value = -value;
|
||||
value = 0.5f - value * 0.5f;
|
||||
}
|
||||
|
||||
// If target is above 60, value is how much to speed up over 60. Otherwise, it's how much slower.
|
||||
// So normalize the target.
|
||||
int target = g_Config.iAnalogFpsLimit - 60;
|
||||
PSP_CoreParameter().analogFpsLimit = 60 + (int)(target * value);
|
||||
|
||||
// If we've reset back to normal, turn it off.
|
||||
limitMode = PSP_CoreParameter().analogFpsLimit == 60 ? FPSLimit::NORMAL : FPSLimit::ANALOG;
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ private:
|
||||
void setVKeyAnalog(char axis, int stick, int virtualKeyMin, int virtualKeyMax, bool setZero = true);
|
||||
|
||||
void SetPSPAxis(char axis, float value, int stick);
|
||||
void ProcessAnalogSpeed(const AxisInput &axis, bool opposite);
|
||||
|
||||
void onVKeyDown(int vkey);
|
||||
void onVKeyUp(int vkey);
|
||||
|
@ -33,6 +33,7 @@ enum class FPSLimit {
|
||||
NORMAL = 0,
|
||||
CUSTOM1 = 1,
|
||||
CUSTOM2 = 2,
|
||||
ANALOG = 3,
|
||||
};
|
||||
|
||||
class FileLoader;
|
||||
@ -76,6 +77,7 @@ struct CoreParameter {
|
||||
// Can be modified at runtime.
|
||||
bool fastForward = false;
|
||||
FPSLimit fpsLimit = FPSLimit::NORMAL;
|
||||
int analogFpsLimit = 0;
|
||||
|
||||
bool updateRecent = true;
|
||||
|
||||
|
@ -354,6 +354,8 @@ static int FrameTimingLimit() {
|
||||
return g_Config.iFpsLimit1;
|
||||
if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM2)
|
||||
return g_Config.iFpsLimit2;
|
||||
if (PSP_CoreParameter().fpsLimit == FPSLimit::ANALOG)
|
||||
return PSP_CoreParameter().analogFpsLimit;
|
||||
if (PSP_CoreParameter().fastForward)
|
||||
return 0;
|
||||
return 60;
|
||||
|
@ -369,6 +369,7 @@ const KeyMap_IntStrPair psp_button_names[] = {
|
||||
{VIRTKEY_SPEED_TOGGLE, "SpeedToggle"},
|
||||
{VIRTKEY_SPEED_CUSTOM1, "Alt speed 1"},
|
||||
{VIRTKEY_SPEED_CUSTOM2, "Alt speed 2"},
|
||||
{VIRTKEY_SPEED_ANALOG, "Analog speed"},
|
||||
{VIRTKEY_PAUSE, "Pause"},
|
||||
#ifndef MOBILE_DEVICE
|
||||
{VIRTKEY_FRAME_ADVANCE, "Frame Advance"},
|
||||
@ -543,8 +544,10 @@ bool AxisFromPspButton(int btn, int *deviceId, int *axisId, int *direction) {
|
||||
for (auto iter = g_controllerMap.begin(); iter != g_controllerMap.end(); ++iter) {
|
||||
for (auto iter2 = iter->second.begin(); iter2 != iter->second.end(); ++iter2) {
|
||||
if (iter->first == btn && iter2->keyCode >= AXIS_BIND_NKCODE_START) {
|
||||
*deviceId = iter2->deviceId;
|
||||
*axisId = TranslateKeyCodeToAxis(iter2->keyCode, *direction);
|
||||
if (deviceId)
|
||||
*deviceId = iter2->deviceId;
|
||||
if (axisId)
|
||||
*axisId = TranslateKeyCodeToAxis(iter2->keyCode, *direction);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -798,6 +801,13 @@ const std::set<std::string> &GetSeenPads() {
|
||||
return g_seenPads;
|
||||
}
|
||||
|
||||
std::string PadName(int deviceId) {
|
||||
auto it = g_padNames.find(deviceId);
|
||||
if (it != g_padNames.end())
|
||||
return it->second;
|
||||
return "";
|
||||
}
|
||||
|
||||
// Swap direction buttons and left analog axis
|
||||
void SwapAxis() {
|
||||
g_swapped_keys = !g_swapped_keys;
|
||||
|
@ -67,6 +67,7 @@ enum {
|
||||
VIRTKEY_SCREEN_ROTATION_VERTICAL180 = 0x40000021,
|
||||
VIRTKEY_SCREEN_ROTATION_HORIZONTAL = 0x40000022,
|
||||
VIRTKEY_SCREEN_ROTATION_HORIZONTAL180 = 0x40000023,
|
||||
VIRTKEY_SPEED_ANALOG = 0x40000024,
|
||||
VIRTKEY_LAST,
|
||||
VIRTKEY_COUNT = VIRTKEY_LAST - VIRTKEY_FIRST
|
||||
};
|
||||
@ -163,6 +164,7 @@ namespace KeyMap {
|
||||
bool HasBuiltinController(const std::string &name);
|
||||
|
||||
const std::set<std::string> &GetSeenPads();
|
||||
std::string PadName(int deviceId);
|
||||
void AutoConfForPad(const std::string &name);
|
||||
|
||||
bool IsKeyMapped(int device, int key);
|
||||
|
@ -505,7 +505,14 @@ void GPUCommon::UpdateVsyncInterval(bool force) {
|
||||
desiredVSyncInterval = 0;
|
||||
}
|
||||
if (PSP_CoreParameter().fpsLimit != FPSLimit::NORMAL) {
|
||||
int limit = PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM1 ? g_Config.iFpsLimit1 : g_Config.iFpsLimit2;
|
||||
int limit;
|
||||
if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM1)
|
||||
limit = g_Config.iFpsLimit1;
|
||||
else if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM2)
|
||||
limit = g_Config.iFpsLimit2;
|
||||
else
|
||||
limit = PSP_CoreParameter().analogFpsLimit;
|
||||
|
||||
// For an alternative speed that is a clean factor of 60, the user probably still wants vsync.
|
||||
if (limit == 0 || (limit >= 0 && limit != 15 && limit != 30 && limit != 60)) {
|
||||
desiredVSyncInterval = 0;
|
||||
|
@ -337,6 +337,9 @@ bool KeyMappingNewKeyDialog::key(const KeyInput &key) {
|
||||
if (key.keyCode == NKCODE_EXT_MOUSEBUTTON_1) {
|
||||
return true;
|
||||
}
|
||||
// Only map analog values to this mapping.
|
||||
if (pspBtn_ == VIRTKEY_SPEED_ANALOG)
|
||||
return true;
|
||||
|
||||
mapped_ = true;
|
||||
KeyDef kdf(key.deviceId, key.keyCode);
|
||||
|
@ -585,10 +585,10 @@ void EmuScreen::onVKeyDown(int virtualKeyCode) {
|
||||
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) {
|
||||
} else if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM1 && 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) {
|
||||
} else if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM1 || PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM2) {
|
||||
PSP_CoreParameter().fpsLimit = FPSLimit::NORMAL;
|
||||
osm.Show(sc->T("standard", "Speed: standard"), 1.0);
|
||||
}
|
||||
|
@ -201,6 +201,7 @@ void GameSettingsScreen::CreateViews() {
|
||||
|
||||
iAlternateSpeedPercent1_ = g_Config.iFpsLimit1 < 0 ? -1 : (g_Config.iFpsLimit1 * 100) / 60;
|
||||
iAlternateSpeedPercent2_ = g_Config.iFpsLimit2 < 0 ? -1 : (g_Config.iFpsLimit2 * 100) / 60;
|
||||
iAlternateSpeedPercentAnalog_ = (g_Config.iAnalogFpsLimit * 100) / 60;
|
||||
|
||||
bool vertical = UseVerticalLayout();
|
||||
|
||||
@ -335,6 +336,11 @@ void GameSettingsScreen::CreateViews() {
|
||||
altSpeed2->SetZeroLabel(gr->T("Unlimited"));
|
||||
altSpeed2->SetNegativeDisable(gr->T("Disabled"));
|
||||
|
||||
if (KeyMap::AxisFromPspButton(VIRTKEY_SPEED_ANALOG, nullptr, nullptr, nullptr)) {
|
||||
PopupSliderChoice *analogSpeed = graphicsSettings->Add(new PopupSliderChoice(&iAlternateSpeedPercentAnalog_, 1, 1000, gr->T("Analog Alternative Speed", "Analog alternative speed (in %)"), 5, screenManager(), gr->T("%")));
|
||||
altSpeed2->SetFormat("%i%%");
|
||||
}
|
||||
|
||||
graphicsSettings->Add(new ItemHeader(gr->T("Postprocessing effect")));
|
||||
|
||||
std::set<std::string> alreadyAddedShader;
|
||||
@ -1402,6 +1408,7 @@ void GameSettingsScreen::dialogFinished(const Screen *dialog, DialogResult resul
|
||||
if (result == DialogResult::DR_OK) {
|
||||
g_Config.iFpsLimit1 = iAlternateSpeedPercent1_ < 0 ? -1 : (iAlternateSpeedPercent1_ * 60) / 100;
|
||||
g_Config.iFpsLimit2 = iAlternateSpeedPercent2_ < 0 ? -1 : (iAlternateSpeedPercent2_ * 60) / 100;
|
||||
g_Config.iAnalogFpsLimit = (iAlternateSpeedPercentAnalog_ * 60) / 100;
|
||||
|
||||
RecreateViews();
|
||||
}
|
||||
|
@ -137,6 +137,7 @@ private:
|
||||
// Temporaries to convert setting types, cache enabled, etc.
|
||||
int iAlternateSpeedPercent1_;
|
||||
int iAlternateSpeedPercent2_;
|
||||
int iAlternateSpeedPercentAnalog_;
|
||||
int prevInflightFrames_;
|
||||
bool enableReports_ = false;
|
||||
bool enableReportsSet_ = false;
|
||||
|
Loading…
x
Reference in New Issue
Block a user