diff --git a/core/libs/prx/libScePad/CMakeLists.txt b/core/libs/prx/libScePad/CMakeLists.txt index ccb006f0d..75308dd0f 100644 --- a/core/libs/prx/libScePad/CMakeLists.txt +++ b/core/libs/prx/libScePad/CMakeLists.txt @@ -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) diff --git a/core/libs/prx/libSceVideoOut/src/PadInput.cpp b/core/libs/prx/libSceVideoOut/src/PadInput.cpp index 5f1148d27..cf4ec4491 100644 --- a/core/libs/prx/libSceVideoOut/src/PadInput.cpp +++ b/core/libs/prx/libSceVideoOut/src/PadInput.cpp @@ -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(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::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; } diff --git a/core/libs/tests/GuestPad.cpp b/core/libs/tests/GuestPad.cpp index 8abd4f04f..522d99171 100644 --- a/core/libs/tests/GuestPad.cpp +++ b/core/libs/tests/GuestPad.cpp @@ -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 @@ -42,6 +43,20 @@ static void CheckTiltCorrection(int handle) { PadPublishInput_nid_postfix(PadInputState{}); } +static void CheckTouchContact() { + PadInputState touch; + touch.buttons = static_cast(Pad::PadButton::TouchPad); + touch.touch[0] = {true, 960, 471, 0}; + PadPublishInput_nid_postfix(touch); + const auto data = Pad::ReadState(); + Require((data.buttons & static_cast(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(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);