mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-23 00:53:02 -05:00
sceSystemGestureUpdatePrimitiveTouchRecognizer reads the pad reports the title passes in and tracks every touch as a primitive, so the primitive event queries report begin, active and end events with their pressed and current positions, delta vector, delta time and elapsed time instead of reporting that no touch input exists. sceSystemGestureGetPrimitiveTouchEventByPrimitiveID no longer throws for a tracked touch.
272 lines
15 KiB
C++
272 lines
15 KiB
C++
#include "SceTypes.hpp"
|
|
#include "prx/libc/include/general/VabiMacros.hpp"
|
|
|
|
#include <algorithm>
|
|
#include <array>
|
|
#include <cstdint>
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
#include <initializer_list>
|
|
#include <stdexcept>
|
|
|
|
extern "C" {
|
|
std::int32_t APS5_VABI sceSystemGestureOpen(std::int32_t, const void*);
|
|
int APS5_VABI sceSystemGestureGetPrimitiveTouchEvents(std::int32_t, void*, std::uint32_t, std::uint32_t*);
|
|
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 sceSystemGestureGetTouchEventByIndex(std::int32_t, const void*, 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*);
|
|
int APS5_VABI sceSystemGestureUpdateTouchRecognizerRectangle(std::int32_t, void*, const void*);
|
|
int APS5_VABI sceSystemGestureResetPrimitiveTouchRecognizer(std::int32_t);
|
|
int APS5_VABI sceSystemGestureUpdateAllTouchRecognizer(std::int32_t);
|
|
int APS5_VABI sceSystemGestureUpdatePrimitiveTouchRecognizer(std::int32_t, const void*);
|
|
int APS5_VABI sceSystemGestureInitializePrimitiveTouchRecognizer(const void*);
|
|
int APS5_VABI sceSystemGestureFinalizePrimitiveTouchRecognizer(void);
|
|
int APS5_VABI sceSystemGestureGetPrimitiveTouchEventByPrimitiveID(std::int32_t, std::uint16_t, void*);
|
|
}
|
|
|
|
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));
|
|
}
|
|
|
|
static PadData TouchReport(std::uint64_t timestamp, std::initializer_list<std::array<std::uint16_t, 3>> touches) {
|
|
PadData report{};
|
|
report.timestamp = timestamp;
|
|
for (const auto& touch : touches) {
|
|
if (report.touch_data_touch_num == 0) {
|
|
report.touch_data_touch0_id = static_cast<std::uint8_t>(touch[0]);
|
|
report.touch_data_touch0_x = touch[1];
|
|
report.touch_data_touch0_y = touch[2];
|
|
} else {
|
|
report.touch_data_touch1_id = static_cast<std::uint8_t>(touch[0]);
|
|
report.touch_data_touch1_x = touch[1];
|
|
report.touch_data_touch1_y = touch[2];
|
|
}
|
|
++report.touch_data_touch_num;
|
|
}
|
|
return report;
|
|
}
|
|
|
|
static int UpdateWithReports(std::int32_t handle, const PadData* reports, std::int32_t count) {
|
|
SystemGestureTouchPadData input{};
|
|
input.pad_handle = 1;
|
|
input.report_number = count;
|
|
input.pad_data_buffer = reports;
|
|
return sceSystemGestureUpdatePrimitiveTouchRecognizer(handle, &input);
|
|
}
|
|
|
|
static SystemGesturePrimitiveTouchEvent SingleEvent(std::int32_t handle) {
|
|
SystemGesturePrimitiveTouchEvent event;
|
|
std::memset(&event, 0x5a, sizeof(event));
|
|
Require(sceSystemGestureGetPrimitiveTouchEventByIndex(handle, 0, &event) == 0);
|
|
return event;
|
|
}
|
|
|
|
static void TestPrimitiveTouchEvents(std::int32_t handle, int invalidArgument, int invalidHandle, int indexOutOfArray) {
|
|
Require(sceSystemGestureInitializePrimitiveTouchRecognizer(nullptr) == 0);
|
|
|
|
const PadData pressed = TouchReport(1000, {{7, 480, 471}});
|
|
Require(UpdateWithReports(handle, &pressed, 1) == 0);
|
|
Require(sceSystemGestureGetPrimitiveTouchEventsCount(handle) == 1);
|
|
SystemGesturePrimitiveTouchEvent event = SingleEvent(handle);
|
|
Require(event.event_state == 1);
|
|
Require(event.primitive_id == 7);
|
|
Require(event.is_updated == 1);
|
|
Require(event.pressed_position.x == 480.0f && event.pressed_position.y == 471.0f);
|
|
Require(event.current_position.x == 480.0f && event.current_position.y == 471.0f);
|
|
Require(event.delta_vector.x == 0.0f && event.delta_vector.y == 0.0f);
|
|
Require(event.delta_time == 0 && event.elapsed_time == 0);
|
|
|
|
const PadData moved = TouchReport(2000, {{7, 500, 480}});
|
|
Require(UpdateWithReports(handle, &moved, 1) == 0);
|
|
event = SingleEvent(handle);
|
|
Require(event.event_state == 2);
|
|
Require(event.is_updated == 1);
|
|
Require(event.pressed_position.x == 480.0f && event.pressed_position.y == 471.0f);
|
|
Require(event.current_position.x == 500.0f && event.current_position.y == 480.0f);
|
|
Require(event.delta_vector.x == 20.0f && event.delta_vector.y == 9.0f);
|
|
Require(event.delta_time == 1000 && event.elapsed_time == 1000);
|
|
|
|
const PadData held = TouchReport(3000, {{7, 500, 480}});
|
|
Require(UpdateWithReports(handle, &held, 1) == 0);
|
|
event = SingleEvent(handle);
|
|
Require(event.event_state == 2);
|
|
Require(event.is_updated == 0);
|
|
Require(event.delta_vector.x == 0.0f && event.delta_vector.y == 0.0f);
|
|
Require(event.delta_time == 1000 && event.elapsed_time == 2000);
|
|
|
|
const PadData released = TouchReport(4000, {});
|
|
Require(UpdateWithReports(handle, &released, 1) == 0);
|
|
Require(sceSystemGestureGetPrimitiveTouchEventsCount(handle) == 1);
|
|
event = SingleEvent(handle);
|
|
Require(event.event_state == 3);
|
|
Require(event.is_updated == 1);
|
|
Require(event.current_position.x == 500.0f && event.current_position.y == 480.0f);
|
|
Require(event.delta_time == 1000 && event.elapsed_time == 3000);
|
|
|
|
const PadData empty = TouchReport(5000, {});
|
|
Require(UpdateWithReports(handle, &empty, 1) == 0);
|
|
Require(sceSystemGestureGetPrimitiveTouchEventsCount(handle) == 0);
|
|
Require(sceSystemGestureGetPrimitiveTouchEventByIndex(handle, 0, &event) == indexOutOfArray);
|
|
|
|
const PadData pair = TouchReport(6000, {{3, 100, 200}, {4, 300, 400}});
|
|
Require(UpdateWithReports(handle, &pair, 1) == 0);
|
|
Require(sceSystemGestureGetPrimitiveTouchEventsCount(handle) == 2);
|
|
|
|
SystemGesturePrimitiveTouchEvent byId{};
|
|
Require(sceSystemGestureGetPrimitiveTouchEventByPrimitiveID(handle, 4, &byId) == 0);
|
|
Require(byId.primitive_id == 4);
|
|
Require(byId.current_position.x == 300.0f && byId.current_position.y == 400.0f);
|
|
Require(sceSystemGestureGetPrimitiveTouchEventByPrimitiveID(handle, 4, nullptr) == invalidArgument);
|
|
Require(sceSystemGestureGetPrimitiveTouchEventByPrimitiveID(handle + 1, 4, &byId) == invalidHandle);
|
|
Require(Throws([&] { sceSystemGestureGetPrimitiveTouchEventByPrimitiveID(handle, 9, &byId); }));
|
|
|
|
std::array<SystemGesturePrimitiveTouchEvent, 2> events{};
|
|
std::uint32_t reported = 7;
|
|
Require(sceSystemGestureGetPrimitiveTouchEvents(handle, events.data(), 1, &reported) == 0);
|
|
Require(reported == 1);
|
|
Require(events[0].primitive_id == 3);
|
|
reported = 7;
|
|
Require(sceSystemGestureGetPrimitiveTouchEvents(handle, events.data(), 2, &reported) == 0);
|
|
Require(reported == 2 && events[1].primitive_id == 4);
|
|
Require(sceSystemGestureGetPrimitiveTouchEvents(handle, nullptr, 2, &reported) == invalidArgument);
|
|
Require(sceSystemGestureGetPrimitiveTouchEventByIndex(handle, 2, &event) == indexOutOfArray);
|
|
|
|
Require(UpdateWithReports(handle + 1, &pair, 1) == invalidHandle);
|
|
Require(sceSystemGestureUpdatePrimitiveTouchRecognizer(handle, nullptr) == 0);
|
|
Require(sceSystemGestureGetPrimitiveTouchEventsCount(handle) == 2);
|
|
|
|
const std::array<PadData, 2> sequence{TouchReport(7000, {{3, 110, 200}}), TouchReport(8000, {{3, 130, 210}})};
|
|
Require(UpdateWithReports(handle, sequence.data(), 2) == 0);
|
|
Require(sceSystemGestureGetPrimitiveTouchEventsCount(handle) == 1);
|
|
event = SingleEvent(handle);
|
|
Require(event.primitive_id == 3);
|
|
Require(event.current_position.x == 130.0f && event.current_position.y == 210.0f);
|
|
Require(event.delta_vector.x == 20.0f && event.delta_vector.y == 10.0f);
|
|
|
|
Require(sceSystemGestureResetPrimitiveTouchRecognizer(handle) == 0);
|
|
Require(sceSystemGestureGetPrimitiveTouchEventsCount(handle) == 0);
|
|
|
|
Require(UpdateWithReports(handle, &pressed, 1) == 0);
|
|
Require(sceSystemGestureGetPrimitiveTouchEventsCount(handle) == 1);
|
|
Require(sceSystemGestureFinalizePrimitiveTouchRecognizer() == 0);
|
|
Require(sceSystemGestureGetPrimitiveTouchEventsCount(handle) == 0);
|
|
}
|
|
|
|
int main() {
|
|
constexpr int invalidArgument = static_cast<int>(0x80D10002);
|
|
constexpr int invalidHandle = static_cast<int>(0x80D10003);
|
|
const std::int32_t handle = sceSystemGestureOpen(0, nullptr);
|
|
|
|
std::array<unsigned char, 64> buffer;
|
|
buffer.fill(0x5a);
|
|
const auto original = buffer;
|
|
std::uint32_t count = 7;
|
|
Require(sceSystemGestureGetPrimitiveTouchEvents(handle, buffer.data(), 4, &count) == 0);
|
|
Require(count == 0);
|
|
Require(buffer == original);
|
|
|
|
count = 7;
|
|
Require(sceSystemGestureGetPrimitiveTouchEvents(handle, buffer.data(), 4, nullptr) == invalidArgument);
|
|
Require(sceSystemGestureGetPrimitiveTouchEvents(handle + 1, buffer.data(), 4, &count) == invalidHandle);
|
|
Require(count == 7);
|
|
|
|
Require(sceSystemGestureGetPrimitiveTouchEventsCount(handle) == 0);
|
|
Require(sceSystemGestureGetPrimitiveTouchEventsCount(handle + 1) == invalidHandle);
|
|
|
|
constexpr int indexOutOfArray = static_cast<int>(0x80D10005);
|
|
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);
|
|
Require(sceSystemGestureGetTouchEvents(handle + 1, &recognizer, buffer.data(), 4, &count) == invalidHandle);
|
|
Require(sceSystemGestureGetPrimitiveTouchEventByIndex(handle, 0, buffer.data()) == indexOutOfArray);
|
|
Require(sceSystemGestureGetPrimitiveTouchEventByIndex(handle + 1, 0, buffer.data()) == invalidHandle);
|
|
Require(sceSystemGestureGetTouchEventByIndex(handle, &recognizer, 0, buffer.data()) == indexOutOfArray);
|
|
Require(sceSystemGestureGetTouchEventByIndex(handle + 1, &recognizer, 0, buffer.data()) == invalidHandle);
|
|
Require(sceSystemGestureGetTouchEventByIndex(handle, nullptr, 0, buffer.data()) == invalidArgument);
|
|
Require(buffer == original);
|
|
|
|
Require(sceSystemGestureAppendTouchRecognizer(handle, &recognizer) == 0);
|
|
Require(sceSystemGestureRemoveTouchRecognizer(handle, &recognizer) == 0);
|
|
Require(sceSystemGestureResetTouchRecognizer(handle, &recognizer) == 0);
|
|
Require(sceSystemGestureUpdateTouchRecognizer(handle, &recognizer) == 0);
|
|
Require(sceSystemGestureUpdateTouchRecognizerRectangle(handle, &recognizer, &rectangle) == 0);
|
|
Require(sceSystemGestureResetPrimitiveTouchRecognizer(handle) == 0);
|
|
Require(sceSystemGestureUpdateAllTouchRecognizer(handle) == 0);
|
|
Require(sceSystemGestureUpdatePrimitiveTouchRecognizer(handle, nullptr) == 0);
|
|
Require(sceSystemGestureAppendTouchRecognizer(handle, nullptr) == invalidArgument);
|
|
Require(sceSystemGestureUpdateTouchRecognizerRectangle(handle, &recognizer, nullptr) == invalidArgument);
|
|
Require(sceSystemGestureAppendTouchRecognizer(handle + 1, &recognizer) == invalidHandle);
|
|
Require(sceSystemGestureRemoveTouchRecognizer(handle, nullptr) == invalidArgument);
|
|
Require(sceSystemGestureResetTouchRecognizer(handle, nullptr) == invalidArgument);
|
|
Require(sceSystemGestureUpdateTouchRecognizer(handle, nullptr) == invalidArgument);
|
|
Require(sceSystemGestureUpdateTouchRecognizerRectangle(handle, nullptr, &rectangle) == invalidArgument);
|
|
Require(sceSystemGestureRemoveTouchRecognizer(handle + 1, &recognizer) == invalidHandle);
|
|
Require(sceSystemGestureResetTouchRecognizer(handle + 1, &recognizer) == invalidHandle);
|
|
Require(sceSystemGestureUpdateTouchRecognizer(handle + 1, &recognizer) == invalidHandle);
|
|
Require(sceSystemGestureUpdateTouchRecognizerRectangle(handle + 1, &recognizer, &rectangle) == invalidHandle);
|
|
Require(sceSystemGestureResetPrimitiveTouchRecognizer(handle + 1) == invalidHandle);
|
|
Require(sceSystemGestureUpdateAllTouchRecognizer(handle + 1) == invalidHandle);
|
|
Require(sceSystemGestureUpdatePrimitiveTouchRecognizer(handle + 1, nullptr) == invalidHandle);
|
|
|
|
TestTouchRecognizerInformation(handle, invalidArgument, invalidHandle);
|
|
TestPrimitiveTouchEvents(handle, invalidArgument, invalidHandle, indexOutOfArray);
|
|
return 0;
|
|
}
|