-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
UI: Add analog speed limit mapping #15645
Changes from 3 commits
536c050
c15c4a6
6e1457e
3cb4207
f18c1a6
e159cb2
0179da6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. About the XBOX controller getting stuck, could you try set the speed back to normal rather than just returning here? I got a really vague memory about some problem with controller going [-1, 0] because 0 is somewhat positive. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This does indeed help: value = fabsf(value);
if (opposite) {
value = 0.0f;
} instead of returning. Though, I would argue that the code that tries to figure out an "opposite" key for a throttle already is wrong, but that's a separate bug. The value that comes in in that case is indeed 0.0, and returning there means that we miss the return to 0.0. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah basically if it's a zero value, the mapping finds itself as an opposite with value 0.0, and skips it with the existing code :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hm, I guess that's fine, I suppose any case where you don't want the negative (like mapping right analog X to speed) it'd make sense for it to clamp. So
So sure, one would get skipped, but the other wouldn't. I guess it's probably not exactly equaling 0 or something? -[Unknown] There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Well, changed to MAPPED_DIR_TO_OPPOSITE_DIR. I guess it could be THROUGH or UNTIL or something, but already kinda long. I guess it could be MAPPED_FULL_RANGE or MAPPED_EDGE_TO_EDGE or something, none of them are great. -[Unknown] There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Both do get called, so hm, I retract my statement about a bug, and now I'm slightly confused how this happens. The change does help though! I'm gonna debug some more because this doesn't quite make sense... |
||
} 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; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we provide a message when user try to bind a key? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, it just doesn't react. -[Unknown] There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Mhhhh, it should react to at least "Back" button. If a controller have no analog axis this will brick the emulation basically. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, I thought it did allow a way to cancel without touch already. Well, I let cancel go through. Thanks for pointing out. -[Unknown] |
||
return true; | ||
|
||
mapped_ = true; | ||
KeyDef kdf(key.deviceId, key.keyCode); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This doesn't update when you get back from control mapping. If you exit to main menu and go back to setting screen it work tho'. Probably missing some There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep, you're right. Made it recreate. I had tested with it already mapped by the time I changed this... -[Unknown] |
||
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(); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this belong to controls section? Related to #15406.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't the button or anything, it's the limit. It's kinda more related to graphics.
-[Unknown]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm just wondering if we want to allow different control profile to have different limit or not. Not really interested in the semantic meaning here :)
Not a big deal anyway