mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-23 09:03:22 -05:00
Merge pull request #5853 from KernelPanicNT/feat/system-gesture-recognizer-information
feat(libSceSystemGesture): implement sceSystemGestureGetTouchRecognizerInformation
This commit is contained in:
3 files changed
+111
-10
No files matched your search
@@ -2,6 +2,9 @@
|
||||
#include <cstddef>
|
||||
#include "SceTypes.hpp"
|
||||
#include "prx/libc/include/General.hpp"
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
// No touch input is emulated: recognizers exist but never report events.
|
||||
static constexpr int32_t GESTURE_HANDLE = 1;
|
||||
@@ -9,6 +12,30 @@ static constexpr int SCE_SYSTEM_GESTURE_ERROR_INVALID_ARGUMENT = static_cast<int
|
||||
static constexpr int SCE_SYSTEM_GESTURE_ERROR_INVALID_HANDLE = static_cast<int>(0x80D10003);
|
||||
static constexpr int SCE_SYSTEM_GESTURE_ERROR_INDEX_OUT_OF_ARRAY = static_cast<int>(0x80D10005);
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr std::uint64_t RECOGNIZER_STATE_MAGIC = 0x41505335'47455354ULL;
|
||||
|
||||
struct RecognizerState {
|
||||
std::uint64_t magic;
|
||||
std::int32_t gestureType;
|
||||
std::uint32_t hasRectangle;
|
||||
SystemGestureRectangle rectangle;
|
||||
};
|
||||
|
||||
static_assert(sizeof(RecognizerState) <= sizeof(SystemGestureTouchRecognizer));
|
||||
|
||||
void storeRecognizerState(SystemGestureTouchRecognizer* recognizer, const RecognizerState& state) {
|
||||
std::memcpy(recognizer->reserve, &state, sizeof(state));
|
||||
}
|
||||
|
||||
bool loadRecognizerState(const SystemGestureTouchRecognizer* recognizer, RecognizerState& state) {
|
||||
std::memcpy(&state, recognizer->reserve, sizeof(state));
|
||||
return state.magic == RECOGNIZER_STATE_MAGIC;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
int APS5_VABI sceSystemGestureAppendTouchRecognizer(int32_t gesture_handle, SystemGestureTouchRecognizer* recognizer) {
|
||||
@@ -22,11 +49,15 @@ int APS5_VABI sceSystemGestureClose(int32_t gesture_handle) {
|
||||
}
|
||||
|
||||
int APS5_VABI sceSystemGestureCreateTouchRecognizer(int32_t gesture_handle, SystemGestureTouchRecognizer* recognizer, int32_t type, const SystemGestureRectangle* rectangle, const void* param) {
|
||||
(void)type;
|
||||
(void)rectangle;
|
||||
(void)param;
|
||||
if (gesture_handle != GESTURE_HANDLE) return SCE_SYSTEM_GESTURE_ERROR_INVALID_HANDLE;
|
||||
if (!recognizer) return SCE_SYSTEM_GESTURE_ERROR_INVALID_ARGUMENT;
|
||||
RecognizerState state{};
|
||||
state.magic = RECOGNIZER_STATE_MAGIC;
|
||||
state.gestureType = type;
|
||||
state.hasRectangle = rectangle ? 1 : 0;
|
||||
if (rectangle) state.rectangle = *rectangle;
|
||||
storeRecognizerState(recognizer, state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -95,11 +126,17 @@ int APS5_VABI sceSystemGestureGetTouchEventsCount(int32_t gesture_handle, const
|
||||
}
|
||||
|
||||
int APS5_VABI sceSystemGestureGetTouchRecognizerInformation(int32_t gesture_handle, const SystemGestureTouchRecognizer* recognizer, SystemGestureTouchRecognizerInformation* information) {
|
||||
(void)gesture_handle;
|
||||
(void)recognizer;
|
||||
(void)information;
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
if (gesture_handle != GESTURE_HANDLE) return SCE_SYSTEM_GESTURE_ERROR_INVALID_HANDLE;
|
||||
if (!recognizer || !information) return SCE_SYSTEM_GESTURE_ERROR_INVALID_ARGUMENT;
|
||||
RecognizerState state{};
|
||||
if (!loadRecognizerState(recognizer, state))
|
||||
throw std::runtime_error(std::string(__func__) + ": recognizer was not created by sceSystemGestureCreateTouchRecognizer");
|
||||
if (!state.hasRectangle)
|
||||
throw std::runtime_error(std::string(__func__) + ": recognizer was created without a rectangle");
|
||||
information->gesture_type = state.gestureType;
|
||||
information->rectangle = state.rectangle;
|
||||
information->updated_time = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI sceSystemGestureInitializePrimitiveTouchRecognizer(const void* param) {
|
||||
@@ -151,6 +188,12 @@ int APS5_VABI sceSystemGestureUpdateTouchRecognizerRectangle(int32_t gesture_han
|
||||
if (gesture_handle != GESTURE_HANDLE) return SCE_SYSTEM_GESTURE_ERROR_INVALID_HANDLE;
|
||||
if (!recognizer) return SCE_SYSTEM_GESTURE_ERROR_INVALID_ARGUMENT;
|
||||
if (!rectangle) return SCE_SYSTEM_GESTURE_ERROR_INVALID_ARGUMENT;
|
||||
RecognizerState state{};
|
||||
if (loadRecognizerState(recognizer, state)) {
|
||||
state.hasRectangle = 1;
|
||||
state.rectangle = *rectangle;
|
||||
storeRecognizerState(recognizer, state);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
#include "SceTypes.hpp"
|
||||
#include "prx/libc/include/general/VabiMacros.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
|
||||
extern "C" {
|
||||
std::int32_t APS5_VABI sceSystemGestureOpen(std::int32_t, const void*);
|
||||
@@ -11,6 +15,8 @@ int APS5_VABI sceSystemGestureGetPrimitiveTouchEventsCount(std::int32_t);
|
||||
int APS5_VABI sceSystemGestureGetTouchEvents(std::int32_t, const void*, void*, std::uint32_t, std::uint32_t*);
|
||||
int APS5_VABI sceSystemGestureGetPrimitiveTouchEventByIndex(std::int32_t, std::uint32_t, void*);
|
||||
int APS5_VABI sceSystemGestureAppendTouchRecognizer(std::int32_t, void*);
|
||||
int APS5_VABI sceSystemGestureCreateTouchRecognizer(std::int32_t, void*, std::int32_t, const void*, const void*);
|
||||
int APS5_VABI sceSystemGestureGetTouchRecognizerInformation(std::int32_t, const void*, void*);
|
||||
int APS5_VABI sceSystemGestureRemoveTouchRecognizer(std::int32_t, void*);
|
||||
int APS5_VABI sceSystemGestureResetTouchRecognizer(std::int32_t, void*);
|
||||
int APS5_VABI sceSystemGestureUpdateTouchRecognizer(std::int32_t, void*);
|
||||
@@ -22,6 +28,56 @@ int APS5_VABI sceSystemGestureUpdatePrimitiveTouchRecognizer(std::int32_t, const
|
||||
|
||||
static void Require(bool value) { if (!value) std::abort(); }
|
||||
|
||||
static bool SameRectangle(const SystemGestureRectangle& left, const SystemGestureRectangle& right) {
|
||||
return std::memcmp(&left, &right, sizeof(SystemGestureRectangle)) == 0;
|
||||
}
|
||||
|
||||
template <typename TCall>
|
||||
static bool Throws(TCall call) {
|
||||
try {
|
||||
call();
|
||||
} catch (const std::runtime_error&) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void TestTouchRecognizerInformation(std::int32_t handle, int invalidArgument, int invalidHandle) {
|
||||
constexpr std::int32_t gestureType = 2;
|
||||
const SystemGestureRectangle area{10.0f, 20.0f, 300.0f, 400.0f, {}};
|
||||
const SystemGestureRectangle moved{40.0f, 50.0f, 60.0f, 70.0f, {}};
|
||||
|
||||
SystemGestureTouchRecognizer recognizer{};
|
||||
Require(sceSystemGestureCreateTouchRecognizer(handle, &recognizer, gestureType, &area, nullptr) == 0);
|
||||
|
||||
SystemGestureTouchRecognizerInformation information;
|
||||
std::memset(&information, 0x5a, sizeof(information));
|
||||
Require(sceSystemGestureGetTouchRecognizerInformation(handle, &recognizer, &information) == 0);
|
||||
Require(information.gesture_type == gestureType);
|
||||
Require(SameRectangle(information.rectangle, area));
|
||||
Require(information.updated_time == 0);
|
||||
Require(std::all_of(std::begin(information.reserve), std::end(information.reserve), [](std::uint8_t value) { return value == 0x5a; }));
|
||||
|
||||
Require(sceSystemGestureUpdateTouchRecognizerRectangle(handle, &recognizer, &moved) == 0);
|
||||
Require(sceSystemGestureGetTouchRecognizerInformation(handle, &recognizer, &information) == 0);
|
||||
Require(information.gesture_type == gestureType);
|
||||
Require(SameRectangle(information.rectangle, moved));
|
||||
|
||||
Require(sceSystemGestureGetTouchRecognizerInformation(handle + 1, &recognizer, &information) == invalidHandle);
|
||||
Require(sceSystemGestureGetTouchRecognizerInformation(handle, nullptr, &information) == invalidArgument);
|
||||
Require(sceSystemGestureGetTouchRecognizerInformation(handle, &recognizer, nullptr) == invalidArgument);
|
||||
|
||||
SystemGestureTouchRecognizer uncreated{};
|
||||
Require(Throws([&] { sceSystemGestureGetTouchRecognizerInformation(handle, &uncreated, &information); }));
|
||||
|
||||
SystemGestureTouchRecognizer withoutRectangle{};
|
||||
Require(sceSystemGestureCreateTouchRecognizer(handle, &withoutRectangle, gestureType, nullptr, nullptr) == 0);
|
||||
Require(Throws([&] { sceSystemGestureGetTouchRecognizerInformation(handle, &withoutRectangle, &information); }));
|
||||
Require(sceSystemGestureUpdateTouchRecognizerRectangle(handle, &withoutRectangle, &area) == 0);
|
||||
Require(sceSystemGestureGetTouchRecognizerInformation(handle, &withoutRectangle, &information) == 0);
|
||||
Require(SameRectangle(information.rectangle, area));
|
||||
}
|
||||
|
||||
int main() {
|
||||
constexpr int invalidArgument = static_cast<int>(0x80D10002);
|
||||
constexpr int invalidHandle = static_cast<int>(0x80D10003);
|
||||
@@ -44,8 +100,8 @@ int main() {
|
||||
Require(sceSystemGestureGetPrimitiveTouchEventsCount(handle + 1) == invalidHandle);
|
||||
|
||||
constexpr int indexOutOfArray = static_cast<int>(0x80D10005);
|
||||
int recognizer = 0;
|
||||
int rectangle = 0;
|
||||
SystemGestureTouchRecognizer recognizer{};
|
||||
SystemGestureRectangle rectangle{};
|
||||
count = 7;
|
||||
Require(sceSystemGestureGetTouchEvents(handle, &recognizer, buffer.data(), 4, &count) == 0 && count == 0);
|
||||
Require(sceSystemGestureGetTouchEvents(handle, &recognizer, buffer.data(), 4, nullptr) == invalidArgument);
|
||||
@@ -76,5 +132,7 @@ int main() {
|
||||
Require(sceSystemGestureResetPrimitiveTouchRecognizer(handle + 1) == invalidHandle);
|
||||
Require(sceSystemGestureUpdateAllTouchRecognizer(handle + 1) == invalidHandle);
|
||||
Require(sceSystemGestureUpdatePrimitiveTouchRecognizer(handle + 1, nullptr) == invalidHandle);
|
||||
|
||||
TestTouchRecognizerInformation(handle, invalidArgument, invalidHandle);
|
||||
return 0;
|
||||
}
|
||||
@@ -2,4 +2,4 @@
|
||||
|
||||
### Silent stubs
|
||||
|
||||
- [System gesture recognizers](../../../core/libs/prx/libSceSystemGesture/Export.cpp) (libSceSystemGesture) - `sceSystemGestureGetPrimitiveTouchEvents`, `GetPrimitiveTouchEventsCount`, `GetTouchEvents`, `GetPrimitiveTouchEventByIndex` and the recognizer append, remove, reset and update calls report that no touch input exists and keep no recognizer state, so a title never receives a gesture event. Handle and pointer arguments are still checked. Error codes follow the 0x80D1 values main already uses in this file; KytyPS5 uses 0x8089 (INVALID_ARGUMENT 0x80890001, INVALID_HANDLE 0x80890006), and which one the console returns is not verified
|
||||
- [System gesture recognizers](../../../core/libs/prx/libSceSystemGesture/Export.cpp) (libSceSystemGesture) - `sceSystemGestureGetPrimitiveTouchEvents`, `GetPrimitiveTouchEventsCount`, `GetTouchEvents`, `GetPrimitiveTouchEventByIndex` and the recognizer append, remove, reset and update calls report that no touch input exists, so a title never receives a gesture event. Handle and pointer arguments are still checked. Error codes follow the 0x80D1 values main already uses in this file; KytyPS5 uses 0x8089 (INVALID_ARGUMENT 0x80890001, INVALID_HANDLE 0x80890006), and which one the console returns is not verified. `sceSystemGestureGetTouchRecognizerInformation` returns the gesture type and rectangle given to `sceSystemGestureCreateTouchRecognizer` or `UpdateTouchRecognizerRectangle`, stored in the title's recognizer buffer in a layout private to this file, and always reports `updated_time` 0 because no recognizer is ever updated with input. It throws for a recognizer that was not created by `sceSystemGestureCreateTouchRecognizer` or has no rectangle, since the console's result in those cases is not known
|
||||
Reference in new issue
Block a user