From 2dc4397c1b5d8f2b7c715abb3d074f35b151201c Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 14 Feb 2025 22:54:06 -0800 Subject: [PATCH] Vita: Allow using rear touch pads as L2/L3/R2/R3 (#3054) --- CHANGES | 1 + src/platform/psp2/main.c | 2 ++ src/platform/psp2/psp2-context.c | 52 ++++++++++++++++++++++++-------- src/platform/psp2/psp2-context.h | 2 ++ 4 files changed, 45 insertions(+), 12 deletions(-) diff --git a/CHANGES b/CHANGES index d7b13c1aa..6b2bff781 100644 --- a/CHANGES +++ b/CHANGES @@ -5,6 +5,7 @@ Features: - New option to lock the maximum frame size - Memory access and information logging - 3DS: Add faster "loose" sync mode, default enabled + - Vita: Allow using rear touch pads as L2/L3/R2/R3 - Scripting: New `input` API for getting raw keyboard/mouse/controller state - Scripting: New `storage` API for saving data for a script, e.g. settings - Scripting: New `image` and `canvas` APIs for drawing images and displaying on-screen diff --git a/src/platform/psp2/main.c b/src/platform/psp2/main.c index 7b5d0855f..ad07bc9da 100644 --- a/src/platform/psp2/main.c +++ b/src/platform/psp2/main.c @@ -46,6 +46,7 @@ static uint32_t _pollInput(const struct mInputMap* map) { SceCtrlData pad; sceCtrlPeekBufferPositiveExt2(0, &pad, 1); int input = mInputMapKeyBits(map, PSP2_INPUT, pad.buttons, 0); + input |= mPSP2ReadTouchLR(map); if (pad.buttons & SCE_CTRL_UP || pad.ly < 64) { input |= 1 << GUI_INPUT_UP; @@ -248,6 +249,7 @@ int main() { }; sceTouchSetSamplingState(SCE_TOUCH_PORT_FRONT, SCE_TOUCH_SAMPLING_STATE_START); + sceTouchSetSamplingState(SCE_TOUCH_PORT_BACK, SCE_TOUCH_SAMPLING_STATE_START); sceCtrlSetSamplingMode(SCE_CTRL_MODE_ANALOG_WIDE); sceCtrlSetSamplingModeExt(SCE_CTRL_MODE_ANALOG_WIDE); sceSysmoduleLoadModule(SCE_SYSMODULE_PHOTO_EXPORT); diff --git a/src/platform/psp2/psp2-context.c b/src/platform/psp2/psp2-context.c index be9ff4495..61549e383 100644 --- a/src/platform/psp2/psp2-context.c +++ b/src/platform/psp2/psp2-context.c @@ -33,6 +33,7 @@ #include #include #include +#include #include @@ -57,6 +58,7 @@ static double fpsRatio = 1; static bool interframeBlending = false; static bool sgbCrop = false; static bool blurry = false; +static SceTouchPanelInfo panelInfo[SCE_TOUCH_PORT_MAX_NUM]; static struct mSceRotationSource { struct mRotationSource d; @@ -290,6 +292,8 @@ uint16_t mPSP2PollInput(struct mGUIRunner* runner) { if (angles != GBA_KEY_NONE) { activeKeys |= 1 << angles; } + activeKeys |= mPSP2ReadTouchLR(&runner->core->inputMap); + return activeKeys; } @@ -313,6 +317,9 @@ void mPSP2Setup(struct mGUIRunner* runner) { mCoreConfigSetDefaultIntValue(&runner->config, "threadedVideo", 1); mCoreLoadForeignConfig(runner->core, &runner->config); + sceTouchGetPanelInfo(SCE_TOUCH_PORT_FRONT, &panelInfo[SCE_TOUCH_PORT_FRONT]); + sceTouchGetPanelInfo(SCE_TOUCH_PORT_BACK, &panelInfo[SCE_TOUCH_PORT_BACK]); + mPSP2MapKey(&runner->core->inputMap, SCE_CTRL_CROSS, GBA_KEY_A); mPSP2MapKey(&runner->core->inputMap, SCE_CTRL_CIRCLE, GBA_KEY_B); mPSP2MapKey(&runner->core->inputMap, SCE_CTRL_START, GBA_KEY_START); @@ -406,18 +413,6 @@ void mPSP2LoadROM(struct mGUIRunner* runner) { mCoreConfigGetBoolValue(&runner->config, "interframeBlending", &interframeBlending); - // Backcompat: Old versions of mGBA use an older binding system that has different mappings for L/R - if (!sceKernelIsPSVitaTV()) { - int key = mInputMapKey(&runner->core->inputMap, PSP2_INPUT, __builtin_ctz(SCE_CTRL_L2)); - if (key >= 0) { - mPSP2MapKey(&runner->core->inputMap, SCE_CTRL_L1, key); - } - key = mInputMapKey(&runner->core->inputMap, PSP2_INPUT, __builtin_ctz(SCE_CTRL_R2)); - if (key >= 0) { - mPSP2MapKey(&runner->core->inputMap, SCE_CTRL_R1, key); - } - } - MutexInit(&audioContext.mutex); ConditionInit(&audioContext.cond); mAudioBufferClear(&audioContext.buffer); @@ -664,6 +659,39 @@ bool mPSP2SystemPoll(struct mGUIRunner* runner) { return true; } +int mPSP2ReadTouchLR(const struct mInputMap* map) { + SceTouchData touch[4]; + int activeKeys = 0; + int touches = sceTouchPeek(SCE_TOUCH_PORT_BACK, touch, 4); + int i; + for (i = 0; i < touches; ++i) { + if (touch[i].reportNum < 1) { + continue; + } + bool left = touch[i].report[0].x < (panelInfo[SCE_TOUCH_PORT_BACK].maxAaX - panelInfo[SCE_TOUCH_PORT_BACK].minAaX) / 2; + bool top = touch[i].report[0].y < (panelInfo[SCE_TOUCH_PORT_BACK].maxAaY - panelInfo[SCE_TOUCH_PORT_BACK].minAaY) / 2; + int button; + if (left) { + if (top) { + button = __builtin_ctz(SCE_CTRL_L2); + } else { + button = __builtin_ctz(SCE_CTRL_L3); + } + } else { + if (top) { + button = __builtin_ctz(SCE_CTRL_R2); + } else { + button = __builtin_ctz(SCE_CTRL_R3); + } + } + int key = mInputMapKey(map, PSP2_INPUT, button); + if (key != -1) { + activeKeys |= 1 << key; + } + } + return activeKeys; +} + __attribute__((noreturn, weak)) void __assert_func(const char* file, int line, const char* func, const char* expr) { printf("ASSERT FAILED: %s in %s at %s:%i\n", expr, func, file, line); exit(1); diff --git a/src/platform/psp2/psp2-context.h b/src/platform/psp2/psp2-context.h index 316dbd434..e45ea671a 100644 --- a/src/platform/psp2/psp2-context.h +++ b/src/platform/psp2/psp2-context.h @@ -28,4 +28,6 @@ void mPSP2SetFrameLimiter(struct mGUIRunner* runner, bool limit); uint16_t mPSP2PollInput(struct mGUIRunner* runner); bool mPSP2SystemPoll(struct mGUIRunner* runner); +int mPSP2ReadTouchLR(const struct mInputMap* map); + #endif