fix(pad): synthesize touch contact for Xbox View

This commit is contained in:
hamb3r 2026-10-05 16:13:26 +03:00
parent a347b02b48
commit aad1be52e8
3 changed files with 23 additions and 2 deletions

View File

@ -14,7 +14,7 @@ endif()
if(BUILD_TESTING)
add_test_executable(guest_pad_tests ${LIBS_INCLUDE_DIR}/tests/GuestPad.cpp)
target_include_directories(guest_pad_tests PRIVATE ${LIBS_INCLUDE_DIR})
target_include_directories(guest_pad_tests PRIVATE ${LIBS_INCLUDE_DIR} ${CMAKE_SOURCE_DIR}/3rdparty/SDL2/include)
target_link_libraries(guest_pad_tests PRIVATE libScePad libc)
configure_windows_unwind(guest_pad_tests)
add_test(NAME guest_pad COMMAND guest_pad_tests)

View File

@ -133,7 +133,8 @@ PadInputState PadInput::sampleController() const {
addButton(SDL_CONTROLLER_BUTTON_LEFTSHOULDER, Pad::PadButton::L1);
addButton(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, Pad::PadButton::R1);
const auto type = SDL_GameControllerGetType(controller);
if (type != SDL_CONTROLLER_TYPE_PS4 && type != SDL_CONTROLLER_TYPE_PS5) addButton(SDL_CONTROLLER_BUTTON_BACK, Pad::PadButton::TouchPad);
const bool viewPressed = type != SDL_CONTROLLER_TYPE_PS4 && type != SDL_CONTROLLER_TYPE_PS5 && readButton(SDL_CONTROLLER_BUTTON_BACK);
if (viewPressed) result.buttons |= static_cast<std::uint32_t>(Pad::PadButton::TouchPad);
addButton(SDL_CONTROLLER_BUTTON_START, Pad::PadButton::Options);
addButton(SDL_CONTROLLER_BUTTON_LEFTSTICK, Pad::PadButton::L3);
addButton(SDL_CONTROLLER_BUTTON_RIGHTSTICK, Pad::PadButton::R3);
@ -187,6 +188,10 @@ PadInputState PadInput::sampleController() const {
result.touch[finger].y = static_cast<std::uint16_t>(std::clamp(y, 0.0f, 1.0f) * 942.0f);
}
}
// View has no touch position, so use a neutral center contact when SDL reports none.
if (viewPressed && !result.touch[0].active && !result.touch[1].active) {
result.touch[0] = {true, 960, 471, 0};
}
return result;
}

View File

@ -1,4 +1,5 @@
#include "prx/libScePad/include/Pad.hpp"
#include "prx/libScePad/include/PadInputTypes.hpp"
#include "prx/libScePad/include/PadState.hpp"
#include "prx/libc/include/general/VabiMacros.hpp"
#include <chrono>
@ -42,6 +43,20 @@ static void CheckTiltCorrection(int handle) {
PadPublishInput_nid_postfix(PadInputState{});
}
static void CheckTouchContact() {
PadInputState touch;
touch.buttons = static_cast<std::uint32_t>(Pad::PadButton::TouchPad);
touch.touch[0] = {true, 960, 471, 0};
PadPublishInput_nid_postfix(touch);
const auto data = Pad::ReadState();
Require((data.buttons & static_cast<std::uint32_t>(Pad::PadButton::TouchPad)) != 0);
Require(data.touch_data_touch_num == 1);
Require(data.touch_data_touch0_x == 960);
Require(data.touch_data_touch0_y == 471);
PadPublishInput_nid_postfix(PadInputState{});
Pad::ReadState();
}
int main() {
constexpr int noHandle = static_cast<int>(0x80920008);
constexpr int user = 0x10000000;
@ -55,6 +70,7 @@ int main() {
Require(scePadGetHandle(user, 0, 0) == handle);
Require(scePadGetHandle(user, 2, 0) == handle);
CheckTiltCorrection(handle);
CheckTouchContact();
Require(scePadGetHandle(0xff, 16, 0) == handle);
Require(scePadGetHandle(user, 16, 0) == noHandle);
Require(scePadGetHandle(user, 0, 1) == noHandle);