ControlMapper: Change the callbacks to be more suitable for the upcoming refactor. (#17209)

* ControlMapper: Change the callbacks to be more suitable for the upcoming refactor.

* SetAllButtons: Separate bits to set and bits to clear.

* Oops, missed committing some files somehow
This commit is contained in:
Henrik Rydgård 2023-03-30 10:47:28 +02:00 committed by GitHub
parent d65afcc7f0
commit 26bf40c497
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 171 additions and 182 deletions

View file

@ -41,9 +41,13 @@ void ConvertAnalogStick(float &x, float &y) {
y = Clamp(y / norm * mappedNorm, -1.0f, 1.0f);
}
void ControlMapper::SetCallbacks(std::function<void(int)> onVKeyDown, std::function<void(int)> onVKeyUp, std::function<void(int, bool)> setPSPButtonState, std::function<void(int, float, float)> setPSPAnalog) {
onVKeyDown_ = onVKeyDown;
onVKeyUp_ = onVKeyUp;
void ControlMapper::SetCallbacks(
std::function<void(int, bool)> onVKey,
std::function<void(uint32_t, uint32_t)> setAllPSPButtonStates,
std::function<void(int, bool)> setPSPButtonState,
std::function<void(int, float, float)> setPSPAnalog) {
onVKey_ = onVKey;
setAllPSPButtonStates_ = setAllPSPButtonStates;
setPSPButtonState_ = setPSPButtonState;
setPSPAnalog_ = setPSPAnalog;
}
@ -200,11 +204,11 @@ void ControlMapper::SetPSPKey(int deviceId, int pspKeyCode, int flags) {
int vk = pspKeyCode - VIRTKEY_FIRST;
if (flags & KEY_DOWN) {
virtKeys_[vk] = true;
onVKeyDown(deviceId, pspKeyCode);
onVKey(deviceId, pspKeyCode, true);
}
if (flags & KEY_UP) {
virtKeys_[vk] = false;
onVKeyUp(deviceId, pspKeyCode);
onVKey(deviceId, pspKeyCode, false);
}
} else {
int rotations = 0;
@ -232,7 +236,7 @@ void ControlMapper::SetPSPKey(int deviceId, int pspKeyCode, int flags) {
}
}
void ControlMapper::onVKeyDown(int deviceId, int vkey) {
void ControlMapper::onVKey(int deviceId, int vkey, bool down) {
switch (vkey) {
case VIRTKEY_AXIS_X_MIN:
case VIRTKEY_AXIS_X_MAX:
@ -260,62 +264,27 @@ void ControlMapper::onVKeyDown(int deviceId, int vkey) {
break;
case VIRTKEY_ANALOG_ROTATE_CW:
autoRotatingAnalogCW_ = true;
autoRotatingAnalogCCW_ = false;
if (down) {
autoRotatingAnalogCW_ = true;
autoRotatingAnalogCCW_ = false;
} else {
autoRotatingAnalogCW_ = false;
setPSPAnalog_(0, 0.0f, 0.0f);
}
break;
case VIRTKEY_ANALOG_ROTATE_CCW:
autoRotatingAnalogCW_ = false;
autoRotatingAnalogCCW_ = true;
if (down) {
autoRotatingAnalogCW_ = false;
autoRotatingAnalogCCW_ = true;
} else {
autoRotatingAnalogCCW_ = false;
setPSPAnalog_(0, 0.0f, 0.0f);
}
break;
default:
if (onVKeyDown_)
onVKeyDown_(vkey);
break;
}
}
void ControlMapper::onVKeyUp(int deviceId, int vkey) {
switch (vkey) {
case VIRTKEY_AXIS_X_MIN:
case VIRTKEY_AXIS_X_MAX:
SetVKeyAnalog(deviceId, 'X', CTRL_STICK_LEFT, VIRTKEY_AXIS_X_MIN, VIRTKEY_AXIS_X_MAX);
break;
case VIRTKEY_AXIS_Y_MIN:
case VIRTKEY_AXIS_Y_MAX:
SetVKeyAnalog(deviceId, 'Y', CTRL_STICK_LEFT, VIRTKEY_AXIS_Y_MIN, VIRTKEY_AXIS_Y_MAX);
break;
case VIRTKEY_AXIS_RIGHT_X_MIN:
case VIRTKEY_AXIS_RIGHT_X_MAX:
SetVKeyAnalog(deviceId, 'X', CTRL_STICK_RIGHT, VIRTKEY_AXIS_RIGHT_X_MIN, VIRTKEY_AXIS_RIGHT_X_MAX);
break;
case VIRTKEY_AXIS_RIGHT_Y_MIN:
case VIRTKEY_AXIS_RIGHT_Y_MAX:
SetVKeyAnalog(deviceId, 'Y', CTRL_STICK_RIGHT, VIRTKEY_AXIS_RIGHT_Y_MIN, VIRTKEY_AXIS_RIGHT_Y_MAX);
break;
case VIRTKEY_ANALOG_LIGHTLY:
SetVKeyAnalog(deviceId, 'X', CTRL_STICK_LEFT, VIRTKEY_AXIS_X_MIN, VIRTKEY_AXIS_X_MAX, false);
SetVKeyAnalog(deviceId, 'Y', CTRL_STICK_LEFT, VIRTKEY_AXIS_Y_MIN, VIRTKEY_AXIS_Y_MAX, false);
SetVKeyAnalog(deviceId, 'X', CTRL_STICK_RIGHT, VIRTKEY_AXIS_RIGHT_X_MIN, VIRTKEY_AXIS_RIGHT_X_MAX, false);
SetVKeyAnalog(deviceId, 'Y', CTRL_STICK_RIGHT, VIRTKEY_AXIS_RIGHT_Y_MIN, VIRTKEY_AXIS_RIGHT_Y_MAX, false);
break;
case VIRTKEY_ANALOG_ROTATE_CW:
autoRotatingAnalogCW_ = false;
setPSPAnalog_(0, 0.0f, 0.0f);
break;
case VIRTKEY_ANALOG_ROTATE_CCW:
autoRotatingAnalogCCW_ = false;
setPSPAnalog_(0, 0.0f, 0.0f);
break;
default:
if (onVKeyUp_)
onVKeyUp_(vkey);
if (onVKey_)
onVKey_(vkey, down);
break;
}
}

View file

@ -21,8 +21,8 @@ public:
// Required callbacks
void SetCallbacks(
std::function<void(int)> onVKeyDown,
std::function<void(int)> onVKeyUp,
std::function<void(int, bool)> onVKey,
std::function<void(uint32_t, uint32_t)> setAllPSPButtonStates_,
std::function<void(int, bool)> setPSPButtonState,
std::function<void(int, float, float)> setPSPAnalog);
@ -41,8 +41,7 @@ private:
void SetPSPAxis(int deviceId, char axis, float value, int stick);
void ProcessAnalogSpeed(const AxisInput &axis, bool opposite);
void onVKeyDown(int deviceId, int vkey);
void onVKeyUp(int deviceId, int vkey);
void onVKey(int deviceId, int vkey, bool down);
// To track mappable virtual keys. We can have as many as we want.
bool virtKeys_[VIRTKEY_COUNT]{};
@ -59,9 +58,9 @@ private:
bool autoRotatingAnalogCCW_ = false;
// Callbacks
std::function<void(int, bool)> onVKey_;
std::function<void(uint32_t, uint32_t)> setAllPSPButtonStates_;
std::function<void(int, bool)> setPSPButtonState_;
std::function<void(int)> onVKeyDown_;
std::function<void(int)> onVKeyUp_;
std::function<void(int, float, float)> setPSPAnalog_;
std::function<void(int, float, float)> setRawAnalog_;
};

View file

@ -204,6 +204,13 @@ void __CtrlButtonUp(u32 buttonBit)
ctrlCurrent.buttons &= ~buttonBit;
}
void __CtrlSetAllButtons(u32 bitsToSet, u32 bitsToClear)
{
std::lock_guard<std::mutex> guard(ctrlMutex);
ctrlCurrent.buttons &= ~(bitsToClear & CTRL_MASK_USER);
ctrlCurrent.buttons |= (bitsToSet & CTRL_MASK_USER);
}
void __CtrlSetAnalogXY(int stick, float x, float y)
{
u8 scaledX = clamp_u8((int)ceilf(x * 127.5f + 127.5f));

View file

@ -70,6 +70,8 @@ void __CtrlShutdown();
void __CtrlButtonDown(u32 buttonBit);
// Call this whenever a button is released. Similar to __CtrlButtonDown().
void __CtrlButtonUp(u32 buttonBit);
// To be used by the new mapping code.
void __CtrlSetAllButtons(u32 bitsToSet, u32 bitsToClear);
// Call this to set the position of an analog stick, ideally when it changes.
// X and Y values should be from -1 to 1, inclusive, in a square (no need to force to a circle.)

View file

@ -449,8 +449,8 @@ void KeyMappingNewMouseKeyDialog::axis(const AxisInput &axis) {
AnalogSetupScreen::AnalogSetupScreen(const Path &gamePath) : UIDialogScreenWithGameBackground(gamePath) {
mapper_.SetCallbacks(
[](int vkey) {},
[](int vkey) {},
[](int vkey, bool down) {},
[&](uint32_t bitsToSet, uint32_t bitsToClear) {},
[&](int button, bool down) {},
[&](int stick, float x, float y) {
analogX_[stick] = x;

View file

@ -176,13 +176,15 @@ EmuScreen::EmuScreen(const Path &filename)
lastNumFlips = gpuStats.numFlips;
startDumping = false;
controlMapper_.SetCallbacks(
std::bind(&EmuScreen::onVKeyDown, this, _1),
std::bind(&EmuScreen::onVKeyUp, this, _1),
[](int pspKey, bool down) {
std::bind(&EmuScreen::onVKey, this, _1, _2),
[](uint32_t bitsToSet, uint32_t bitsToClear) {
__CtrlSetAllButtons(bitsToSet, bitsToClear);
},
[](int pspButton, bool down) {
if (down) {
__CtrlButtonDown(pspKey);
__CtrlButtonDown(pspButton);
} else {
__CtrlButtonUp(pspKey);
__CtrlButtonUp(pspButton);
}
},
&SetPSPAnalog);
@ -562,190 +564,200 @@ void EmuScreen::touch(const TouchInput &touch) {
}
}
void EmuScreen::onVKeyDown(int virtualKeyCode) {
void EmuScreen::onVKey(int virtualKeyCode, bool down) {
auto sc = GetI18NCategory("Screen");
switch (virtualKeyCode) {
case VIRTKEY_FASTFORWARD:
if (coreState == CORE_STEPPING) {
Core_EnableStepping(false);
if (down) {
if (coreState == CORE_STEPPING) {
Core_EnableStepping(false);
}
PSP_CoreParameter().fastForward = true;
} else {
PSP_CoreParameter().fastForward = false;
}
PSP_CoreParameter().fastForward = true;
break;
case VIRTKEY_SPEED_TOGGLE:
// 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::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::CUSTOM1 || PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM2) {
PSP_CoreParameter().fpsLimit = FPSLimit::NORMAL;
osm.Show(sc->T("standard", "Speed: standard"), 1.0);
if (down) {
// 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::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::CUSTOM1 || PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM2) {
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);
if (down) {
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 == 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::NORMAL) {
PSP_CoreParameter().fpsLimit = FPSLimit::CUSTOM2;
osm.Show(sc->T("SpeedCustom2", "Speed: alternate 2"), 1.0);
if (down) {
if (PSP_CoreParameter().fpsLimit == FPSLimit::NORMAL) {
PSP_CoreParameter().fpsLimit = FPSLimit::CUSTOM2;
osm.Show(sc->T("SpeedCustom2", "Speed: alternate 2"), 1.0);
}
} else {
if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM2) {
PSP_CoreParameter().fpsLimit = FPSLimit::NORMAL;
osm.Show(sc->T("standard", "Speed: standard"), 1.0);
}
}
break;
case VIRTKEY_PAUSE:
pauseTrigger_ = true;
if (down) {
pauseTrigger_ = true;
}
break;
case VIRTKEY_FRAME_ADVANCE:
// If game is running, pause emulation immediately. Otherwise, advance a single frame.
if (Core_IsStepping())
{
frameStep_ = true;
Core_EnableStepping(false);
}
else if (!frameStep_)
{
Core_EnableStepping(true, "ui.frameAdvance", 0);
if (down) {
// If game is running, pause emulation immediately. Otherwise, advance a single frame.
if (Core_IsStepping()) {
frameStep_ = true;
Core_EnableStepping(false);
} else if (!frameStep_) {
Core_EnableStepping(true, "ui.frameAdvance", 0);
}
}
break;
case VIRTKEY_OPENCHAT:
if (g_Config.bEnableNetworkChat) {
if (down && g_Config.bEnableNetworkChat) {
UI::EventParams e{};
OnChatMenu.Trigger(e);
}
break;
case VIRTKEY_AXIS_SWAP:
KeyMap::SwapAxis();
if (down) {
KeyMap::SwapAxis();
}
break;
case VIRTKEY_DEVMENU:
{
UI::EventParams e{};
OnDevMenu.Trigger(e);
if (down) {
UI::EventParams e{};
OnDevMenu.Trigger(e);
}
break;
}
#ifndef MOBILE_DEVICE
case VIRTKEY_RECORD:
{
if (g_Config.bDumpFrames == g_Config.bDumpAudio) {
g_Config.bDumpFrames = !g_Config.bDumpFrames;
g_Config.bDumpAudio = !g_Config.bDumpAudio;
} else {
// This hotkey should always toggle both audio and video together.
// So let's make sure that's the only outcome even if video OR audio was already being dumped.
if (g_Config.bDumpFrames) {
AVIDump::Stop();
AVIDump::Start(PSP_CoreParameter().renderWidth, PSP_CoreParameter().renderHeight);
g_Config.bDumpAudio = true;
if (down) {
if (g_Config.bDumpFrames == g_Config.bDumpAudio) {
g_Config.bDumpFrames = !g_Config.bDumpFrames;
g_Config.bDumpAudio = !g_Config.bDumpAudio;
} else {
WAVDump::Reset();
g_Config.bDumpFrames = true;
// This hotkey should always toggle both audio and video together.
// So let's make sure that's the only outcome even if video OR audio was already being dumped.
if (g_Config.bDumpFrames) {
AVIDump::Stop();
AVIDump::Start(PSP_CoreParameter().renderWidth, PSP_CoreParameter().renderHeight);
g_Config.bDumpAudio = true;
} else {
WAVDump::Reset();
g_Config.bDumpFrames = true;
}
}
}
break;
}
#endif
case VIRTKEY_REWIND:
if (SaveState::CanRewind()) {
SaveState::Rewind(&AfterSaveStateAction);
} else {
osm.Show(sc->T("norewind", "No rewind save states available"), 2.0);
if (down) {
if (SaveState::CanRewind()) {
SaveState::Rewind(&AfterSaveStateAction);
} else {
osm.Show(sc->T("norewind", "No rewind save states available"), 2.0);
}
}
break;
case VIRTKEY_SAVE_STATE:
SaveState::SaveSlot(gamePath_, g_Config.iCurrentStateSlot, &AfterSaveStateAction);
if (down)
SaveState::SaveSlot(gamePath_, g_Config.iCurrentStateSlot, &AfterSaveStateAction);
break;
case VIRTKEY_LOAD_STATE:
SaveState::LoadSlot(gamePath_, g_Config.iCurrentStateSlot, &AfterSaveStateAction);
if (down)
SaveState::LoadSlot(gamePath_, g_Config.iCurrentStateSlot, &AfterSaveStateAction);
break;
case VIRTKEY_NEXT_SLOT:
SaveState::NextSlot();
NativeMessageReceived("savestate_displayslot", "");
if (down) {
SaveState::NextSlot();
NativeMessageReceived("savestate_displayslot", "");
}
break;
case VIRTKEY_TOGGLE_FULLSCREEN:
System_ToggleFullscreenState("");
if (down)
System_ToggleFullscreenState("");
break;
case VIRTKEY_SCREENSHOT:
g_TakeScreenshot = true;
if (down)
g_TakeScreenshot = true;
break;
case VIRTKEY_TEXTURE_DUMP:
g_Config.bSaveNewTextures = !g_Config.bSaveNewTextures;
if (g_Config.bSaveNewTextures) {
osm.Show(sc->T("saveNewTextures_true", "Textures will now be saved to your storage"), 2.0);
NativeMessageReceived("gpu_configChanged", "");
} else {
osm.Show(sc->T("saveNewTextures_false", "Texture saving was disabled"), 2.0);
if (down) {
g_Config.bSaveNewTextures = !g_Config.bSaveNewTextures;
if (g_Config.bSaveNewTextures) {
osm.Show(sc->T("saveNewTextures_true", "Textures will now be saved to your storage"), 2.0);
NativeMessageReceived("gpu_configChanged", "");
} else {
osm.Show(sc->T("saveNewTextures_false", "Texture saving was disabled"), 2.0);
}
}
break;
case VIRTKEY_TEXTURE_REPLACE:
g_Config.bReplaceTextures = !g_Config.bReplaceTextures;
if (g_Config.bReplaceTextures)
osm.Show(sc->T("replaceTextures_true", "Texture replacement enabled"), 2.0);
else
osm.Show(sc->T("replaceTextures_false", "Textures no longer are being replaced"), 2.0);
NativeMessageReceived("gpu_configChanged", "");
if (down) {
g_Config.bReplaceTextures = !g_Config.bReplaceTextures;
if (g_Config.bReplaceTextures)
osm.Show(sc->T("replaceTextures_true", "Texture replacement enabled"), 2.0);
else
osm.Show(sc->T("replaceTextures_false", "Textures no longer are being replaced"), 2.0);
NativeMessageReceived("gpu_configChanged", "");
}
break;
case VIRTKEY_RAPID_FIRE:
__CtrlSetRapidFire(true);
__CtrlSetRapidFire(down);
break;
case VIRTKEY_MUTE_TOGGLE:
g_Config.bEnableSound = !g_Config.bEnableSound;
if (down)
g_Config.bEnableSound = !g_Config.bEnableSound;
break;
case VIRTKEY_SCREEN_ROTATION_VERTICAL:
g_Config.iInternalScreenRotation = ROTATION_LOCKED_VERTICAL;
if (down)
g_Config.iInternalScreenRotation = ROTATION_LOCKED_VERTICAL;
break;
case VIRTKEY_SCREEN_ROTATION_VERTICAL180:
g_Config.iInternalScreenRotation = ROTATION_LOCKED_VERTICAL180;
if (down)
g_Config.iInternalScreenRotation = ROTATION_LOCKED_VERTICAL180;
break;
case VIRTKEY_SCREEN_ROTATION_HORIZONTAL:
g_Config.iInternalScreenRotation = ROTATION_LOCKED_HORIZONTAL;
if (down)
g_Config.iInternalScreenRotation = ROTATION_LOCKED_HORIZONTAL;
break;
case VIRTKEY_SCREEN_ROTATION_HORIZONTAL180:
g_Config.iInternalScreenRotation = ROTATION_LOCKED_HORIZONTAL180;
break;
}
}
void EmuScreen::onVKeyUp(int virtualKeyCode) {
auto sc = GetI18NCategory("Screen");
switch (virtualKeyCode) {
case VIRTKEY_FASTFORWARD:
PSP_CoreParameter().fastForward = 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_RAPID_FIRE:
__CtrlSetRapidFire(false);
break;
default:
if (down)
g_Config.iInternalScreenRotation = ROTATION_LOCKED_HORIZONTAL180;
break;
}
}

View file

@ -68,8 +68,7 @@ private:
bool hasVisibleUI();
void renderUI();
void onVKeyDown(int virtualKeyCode);
void onVKeyUp(int virtualKeyCode);
void onVKey(int virtualKeyCode, bool down);
void autoLoad();
void checkPowerDown();

View file

@ -1,10 +1,11 @@
#include <algorithm>
#include "UI/JoystickHistoryView.h"
#include "Common/UI/Context.h"
#include "Common/UI/UI.h"
// From ControlMapper.h
void ConvertAnalogStick(float &x, float &y);
#include "Core/ControlMapper.h"
void JoystickHistoryView::Draw(UIContext &dc) {
const AtlasImage *image = dc.Draw()->GetAtlas()->getImage(ImageID("I_CROSS"));