From fc58e83e9cd75c0eb8b4d7afd9d910c0f13945b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=A4rkl?= Date: Tue, 12 Jan 2021 12:23:02 +0100 Subject: [PATCH] Track Finger IDs on Switch --- switch/include/host.h | 5 ++-- switch/include/io.h | 6 +++-- switch/src/gui.cpp | 2 +- switch/src/host.cpp | 8 ++---- switch/src/io.cpp | 59 ++++++++++++++++++++++++++----------------- 5 files changed, 46 insertions(+), 34 deletions(-) diff --git a/switch/include/host.h b/switch/include/host.h index 1e8114d..e28183e 100644 --- a/switch/include/host.h +++ b/switch/include/host.h @@ -56,7 +56,7 @@ class Host std::function chiaki_even_login_pin_request_cb = nullptr; std::function chiaki_event_rumble_cb = nullptr; std::function chiaki_event_quit_cb = nullptr; - std::function io_read_controller_cb = nullptr; + std::function *)> io_read_controller_cb = nullptr; // internal state bool discovered = false; @@ -76,6 +76,7 @@ class Host ChiakiTarget target = CHIAKI_TARGET_PS4_UNKNOWN; ChiakiDiscoveryHostState state = CHIAKI_DISCOVERY_HOST_STATE_UNKNOWN; ChiakiControllerState controller_state = {0}; + std::map finger_id_touch_id; // mac address = 48 bits uint8_t server_mac[6] = {0}; @@ -115,7 +116,7 @@ class Host void SetEventLoginPinRequestCallback(std::function chiaki_even_login_pin_request_cb); void SetEventRumbleCallback(std::function chiaki_event_rumble_cb); void SetEventQuitCallback(std::function chiaki_event_quit_cb); - void SetReadControllerCallback(std::function io_read_controller_cb); + void SetReadControllerCallback(std::function *)> io_read_controller_cb); bool IsRegistered(); bool IsDiscovered(); bool IsReady(); diff --git a/switch/include/io.h b/switch/include/io.h index 8466fb0..3c1031d 100644 --- a/switch/include/io.h +++ b/switch/include/io.h @@ -35,6 +35,8 @@ Reproducible: False #endif #include +#include + extern "C" { #include @@ -96,7 +98,7 @@ class IO GLuint CreateAndCompileShader(GLenum type, const char *source); void SetOpenGlYUVPixels(AVFrame *frame); bool ReadGameKeys(SDL_Event *event, ChiakiControllerState *state); - bool ReadGameTouchScreen(ChiakiControllerState *state); + bool ReadGameTouchScreen(ChiakiControllerState *state, std::map *finger_id_touch_id); bool ReadGameSixAxis(ChiakiControllerState *state); public: // singleton configuration @@ -114,7 +116,7 @@ class IO bool InitController(); bool FreeController(); bool MainLoop(); - void UpdateControllerState(ChiakiControllerState *state); + void UpdateControllerState(ChiakiControllerState *state, std::map *finger_id_touch_id); void SetRumble(uint8_t left, uint8_t right); }; diff --git a/switch/src/gui.cpp b/switch/src/gui.cpp index e77576c..2d0b71f 100644 --- a/switch/src/gui.cpp +++ b/switch/src/gui.cpp @@ -44,7 +44,7 @@ HostInterface::HostInterface(Host *host) this->host->SetEventQuitCallback(std::bind(&HostInterface::CloseStream, this, std::placeholders::_1)); // allow host to update controller state this->host->SetEventRumbleCallback(std::bind(&IO::SetRumble, this->io, std::placeholders::_1, std::placeholders::_2)); - this->host->SetReadControllerCallback(std::bind(&IO::UpdateControllerState, this->io, std::placeholders::_1)); + this->host->SetReadControllerCallback(std::bind(&IO::UpdateControllerState, this->io, std::placeholders::_1, std::placeholders::_2)); } HostInterface::~HostInterface() diff --git a/switch/src/host.cpp b/switch/src/host.cpp index 573a887..2f50e2f 100644 --- a/switch/src/host.cpp +++ b/switch/src/host.cpp @@ -163,10 +163,6 @@ int Host::InitSession(IO *user) // init controller states chiaki_controller_state_set_idle(&this->controller_state); - for(int x = 0; x < CHIAKI_CONTROLLER_TOUCHES_MAX; x++) - // start touchpad as "untouched" - this->controller_state.touches[x].id = -1; - return 0; } @@ -201,7 +197,7 @@ void Host::SendFeedbackState() { // send controller/joystick key if(this->io_read_controller_cb != nullptr) - this->io_read_controller_cb(&this->controller_state); + this->io_read_controller_cb(&this->controller_state, &finger_id_touch_id); chiaki_session_set_controller_state(&this->session, &this->controller_state); } @@ -373,7 +369,7 @@ void Host::SetEventRumbleCallback(std::function chiaki_e this->chiaki_event_rumble_cb = chiaki_event_rumble_cb; } -void Host::SetReadControllerCallback(std::function io_read_controller_cb) +void Host::SetReadControllerCallback(std::function *)> io_read_controller_cb) { this->io_read_controller_cb = io_read_controller_cb; } diff --git a/switch/src/io.cpp b/switch/src/io.cpp index 2b4dab5..409bba0 100644 --- a/switch/src/io.cpp +++ b/switch/src/io.cpp @@ -339,7 +339,7 @@ bool IO::FreeVideo() return ret; } -bool IO::ReadGameTouchScreen(ChiakiControllerState *chiaki_state) +bool IO::ReadGameTouchScreen(ChiakiControllerState *chiaki_state, std::map *finger_id_touch_id) { #ifdef __SWITCH__ HidTouchScreenState sw_state = {0}; @@ -348,31 +348,44 @@ bool IO::ReadGameTouchScreen(ChiakiControllerState *chiaki_state) hidGetTouchScreenStates(&sw_state, 1); // scale switch screen to the PS trackpad chiaki_state->buttons &= ~CHIAKI_CONTROLLER_BUTTON_TOUCHPAD; // touchscreen release - for(int i = 0; i < CHIAKI_CONTROLLER_TOUCHES_MAX; i++) + + // un-touch all old touches + for(auto it = finger_id_touch_id->begin(); it != finger_id_touch_id->end();) { - if((i + 1) <= sw_state.count) + auto cur = it; + it++; + for(int i = 0; i < sw_state.count; i++) { - uint16_t x = sw_state.touches[i].x * ((float)DS4_TRACKPAD_MAX_X / (float)SWITCH_TOUCHSCREEN_MAX_X); - uint16_t y = sw_state.touches[i].y * ((float)DS4_TRACKPAD_MAX_Y / (float)SWITCH_TOUCHSCREEN_MAX_Y); - - // use nintendo switch border's 5% to trigger the touchpad button - if(x <= (DS4_TRACKPAD_MAX_X * 0.05) || x >= (DS4_TRACKPAD_MAX_X * 0.95) || y <= (DS4_TRACKPAD_MAX_Y * 0.05) || y >= (DS4_TRACKPAD_MAX_Y * 0.95)) - chiaki_state->buttons |= CHIAKI_CONTROLLER_BUTTON_TOUCHPAD; // touchscreen - - chiaki_state->touches[i].x = x; - chiaki_state->touches[i].y = y; - chiaki_state->touches[i].id = i; + if(sw_state.touches[i].finger_id == cur->first) + goto cont; } - else + if(cur->second >= 0) + chiaki_controller_state_stop_touch(chiaki_state, (uint8_t)cur->second); + finger_id_touch_id->erase(cur); +cont: + continue; + } + + + // touch or update all current touches + for(int i = 0; i < sw_state.count; i++) + { + uint16_t x = sw_state.touches[i].x * ((float)DS4_TRACKPAD_MAX_X / (float)SWITCH_TOUCHSCREEN_MAX_X); + uint16_t y = sw_state.touches[i].y * ((float)DS4_TRACKPAD_MAX_Y / (float)SWITCH_TOUCHSCREEN_MAX_Y); + // use nintendo switch border's 5% to trigger the touchpad button + if(x <= (DS4_TRACKPAD_MAX_X * 0.05) || x >= (DS4_TRACKPAD_MAX_X * 0.95) || y <= (DS4_TRACKPAD_MAX_Y * 0.05) || y >= (DS4_TRACKPAD_MAX_Y * 0.95)) + chiaki_state->buttons |= CHIAKI_CONTROLLER_BUTTON_TOUCHPAD; // touchscreen + + auto it = finger_id_touch_id->find(sw_state.touches[i].finger_id); + if(it == finger_id_touch_id->end()) { - // flush touch state - chiaki_state->touches[i].x = 0; - chiaki_state->touches[i].y = 0; - chiaki_state->touches[i].id = -1; + // new touch + (*finger_id_touch_id)[sw_state.touches[i].finger_id] = + chiaki_controller_state_start_touch(chiaki_state, x, y); } - // printf("switch id=%d x=%03d, y=%03d\nchiaki id=%d x=%03d, y=%03d\n", - // i, sw_state.touches[i].x, sw_state.touches[i].y, - // chiaki_state->touches[i].id, chiaki_state->touches[i].x, chiaki_state->touches[i].y); + else if(it->second >= 0) + chiaki_controller_state_set_touch_pos(chiaki_state, (uint8_t)it->second, x, y); + // it->second < 0 ==> touch ignored because there were already too many multi-touches ret = true; } return ret; @@ -961,7 +974,7 @@ bool IO::FreeController() return true; } -void IO::UpdateControllerState(ChiakiControllerState *state) +void IO::UpdateControllerState(ChiakiControllerState *state, std::map *finger_id_touch_id) { #ifdef __SWITCH__ padUpdate(&this->pad); @@ -977,7 +990,7 @@ void IO::UpdateControllerState(ChiakiControllerState *state) } } - ReadGameTouchScreen(state); + ReadGameTouchScreen(state, finger_id_touch_id); ReadGameSixAxis(state); }