mirror of
https://git.sr.ht/~thestr4ng3r/chiaki
synced 2025-08-19 13:09:39 -07:00
Track Finger IDs on Switch
This commit is contained in:
parent
1b8fa556f8
commit
fc58e83e9c
5 changed files with 46 additions and 34 deletions
|
@ -56,7 +56,7 @@ class Host
|
||||||
std::function<void(bool)> chiaki_even_login_pin_request_cb = nullptr;
|
std::function<void(bool)> chiaki_even_login_pin_request_cb = nullptr;
|
||||||
std::function<void(uint8_t, uint8_t)> chiaki_event_rumble_cb = nullptr;
|
std::function<void(uint8_t, uint8_t)> chiaki_event_rumble_cb = nullptr;
|
||||||
std::function<void(ChiakiQuitEvent *)> chiaki_event_quit_cb = nullptr;
|
std::function<void(ChiakiQuitEvent *)> chiaki_event_quit_cb = nullptr;
|
||||||
std::function<void(ChiakiControllerState *)> io_read_controller_cb = nullptr;
|
std::function<void(ChiakiControllerState *, std::map<uint32_t, int8_t> *)> io_read_controller_cb = nullptr;
|
||||||
|
|
||||||
// internal state
|
// internal state
|
||||||
bool discovered = false;
|
bool discovered = false;
|
||||||
|
@ -76,6 +76,7 @@ class Host
|
||||||
ChiakiTarget target = CHIAKI_TARGET_PS4_UNKNOWN;
|
ChiakiTarget target = CHIAKI_TARGET_PS4_UNKNOWN;
|
||||||
ChiakiDiscoveryHostState state = CHIAKI_DISCOVERY_HOST_STATE_UNKNOWN;
|
ChiakiDiscoveryHostState state = CHIAKI_DISCOVERY_HOST_STATE_UNKNOWN;
|
||||||
ChiakiControllerState controller_state = {0};
|
ChiakiControllerState controller_state = {0};
|
||||||
|
std::map<uint32_t, int8_t> finger_id_touch_id;
|
||||||
|
|
||||||
// mac address = 48 bits
|
// mac address = 48 bits
|
||||||
uint8_t server_mac[6] = {0};
|
uint8_t server_mac[6] = {0};
|
||||||
|
@ -115,7 +116,7 @@ class Host
|
||||||
void SetEventLoginPinRequestCallback(std::function<void(bool)> chiaki_even_login_pin_request_cb);
|
void SetEventLoginPinRequestCallback(std::function<void(bool)> chiaki_even_login_pin_request_cb);
|
||||||
void SetEventRumbleCallback(std::function<void(uint8_t, uint8_t)> chiaki_event_rumble_cb);
|
void SetEventRumbleCallback(std::function<void(uint8_t, uint8_t)> chiaki_event_rumble_cb);
|
||||||
void SetEventQuitCallback(std::function<void(ChiakiQuitEvent *)> chiaki_event_quit_cb);
|
void SetEventQuitCallback(std::function<void(ChiakiQuitEvent *)> chiaki_event_quit_cb);
|
||||||
void SetReadControllerCallback(std::function<void(ChiakiControllerState *)> io_read_controller_cb);
|
void SetReadControllerCallback(std::function<void(ChiakiControllerState *, std::map<uint32_t, int8_t> *)> io_read_controller_cb);
|
||||||
bool IsRegistered();
|
bool IsRegistered();
|
||||||
bool IsDiscovered();
|
bool IsDiscovered();
|
||||||
bool IsReady();
|
bool IsReady();
|
||||||
|
|
|
@ -35,6 +35,8 @@ Reproducible: False
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
#include <libavcodec/avcodec.h>
|
#include <libavcodec/avcodec.h>
|
||||||
|
@ -96,7 +98,7 @@ class IO
|
||||||
GLuint CreateAndCompileShader(GLenum type, const char *source);
|
GLuint CreateAndCompileShader(GLenum type, const char *source);
|
||||||
void SetOpenGlYUVPixels(AVFrame *frame);
|
void SetOpenGlYUVPixels(AVFrame *frame);
|
||||||
bool ReadGameKeys(SDL_Event *event, ChiakiControllerState *state);
|
bool ReadGameKeys(SDL_Event *event, ChiakiControllerState *state);
|
||||||
bool ReadGameTouchScreen(ChiakiControllerState *state);
|
bool ReadGameTouchScreen(ChiakiControllerState *state, std::map<uint32_t, int8_t> *finger_id_touch_id);
|
||||||
bool ReadGameSixAxis(ChiakiControllerState *state);
|
bool ReadGameSixAxis(ChiakiControllerState *state);
|
||||||
public:
|
public:
|
||||||
// singleton configuration
|
// singleton configuration
|
||||||
|
@ -114,7 +116,7 @@ class IO
|
||||||
bool InitController();
|
bool InitController();
|
||||||
bool FreeController();
|
bool FreeController();
|
||||||
bool MainLoop();
|
bool MainLoop();
|
||||||
void UpdateControllerState(ChiakiControllerState *state);
|
void UpdateControllerState(ChiakiControllerState *state, std::map<uint32_t, int8_t> *finger_id_touch_id);
|
||||||
void SetRumble(uint8_t left, uint8_t right);
|
void SetRumble(uint8_t left, uint8_t right);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ HostInterface::HostInterface(Host *host)
|
||||||
this->host->SetEventQuitCallback(std::bind(&HostInterface::CloseStream, this, std::placeholders::_1));
|
this->host->SetEventQuitCallback(std::bind(&HostInterface::CloseStream, this, std::placeholders::_1));
|
||||||
// allow host to update controller state
|
// allow host to update controller state
|
||||||
this->host->SetEventRumbleCallback(std::bind(&IO::SetRumble, this->io, std::placeholders::_1, std::placeholders::_2));
|
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()
|
HostInterface::~HostInterface()
|
||||||
|
|
|
@ -163,10 +163,6 @@ int Host::InitSession(IO *user)
|
||||||
// init controller states
|
// init controller states
|
||||||
chiaki_controller_state_set_idle(&this->controller_state);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,7 +197,7 @@ void Host::SendFeedbackState()
|
||||||
{
|
{
|
||||||
// send controller/joystick key
|
// send controller/joystick key
|
||||||
if(this->io_read_controller_cb != nullptr)
|
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);
|
chiaki_session_set_controller_state(&this->session, &this->controller_state);
|
||||||
}
|
}
|
||||||
|
@ -373,7 +369,7 @@ void Host::SetEventRumbleCallback(std::function<void(uint8_t, uint8_t)> chiaki_e
|
||||||
this->chiaki_event_rumble_cb = chiaki_event_rumble_cb;
|
this->chiaki_event_rumble_cb = chiaki_event_rumble_cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Host::SetReadControllerCallback(std::function<void(ChiakiControllerState *)> io_read_controller_cb)
|
void Host::SetReadControllerCallback(std::function<void(ChiakiControllerState *, std::map<uint32_t, int8_t> *)> io_read_controller_cb)
|
||||||
{
|
{
|
||||||
this->io_read_controller_cb = io_read_controller_cb;
|
this->io_read_controller_cb = io_read_controller_cb;
|
||||||
}
|
}
|
||||||
|
|
|
@ -339,7 +339,7 @@ bool IO::FreeVideo()
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IO::ReadGameTouchScreen(ChiakiControllerState *chiaki_state)
|
bool IO::ReadGameTouchScreen(ChiakiControllerState *chiaki_state, std::map<uint32_t, int8_t> *finger_id_touch_id)
|
||||||
{
|
{
|
||||||
#ifdef __SWITCH__
|
#ifdef __SWITCH__
|
||||||
HidTouchScreenState sw_state = {0};
|
HidTouchScreenState sw_state = {0};
|
||||||
|
@ -348,31 +348,44 @@ bool IO::ReadGameTouchScreen(ChiakiControllerState *chiaki_state)
|
||||||
hidGetTouchScreenStates(&sw_state, 1);
|
hidGetTouchScreenStates(&sw_state, 1);
|
||||||
// scale switch screen to the PS trackpad
|
// scale switch screen to the PS trackpad
|
||||||
chiaki_state->buttons &= ~CHIAKI_CONTROLLER_BUTTON_TOUCHPAD; // touchscreen release
|
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);
|
if(sw_state.touches[i].finger_id == cur->first)
|
||||||
uint16_t y = sw_state.touches[i].y * ((float)DS4_TRACKPAD_MAX_Y / (float)SWITCH_TOUCHSCREEN_MAX_Y);
|
goto cont;
|
||||||
|
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
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
|
// new touch
|
||||||
chiaki_state->touches[i].x = 0;
|
(*finger_id_touch_id)[sw_state.touches[i].finger_id] =
|
||||||
chiaki_state->touches[i].y = 0;
|
chiaki_controller_state_start_touch(chiaki_state, x, y);
|
||||||
chiaki_state->touches[i].id = -1;
|
|
||||||
}
|
}
|
||||||
// printf("switch id=%d x=%03d, y=%03d\nchiaki id=%d x=%03d, y=%03d\n",
|
else if(it->second >= 0)
|
||||||
// i, sw_state.touches[i].x, sw_state.touches[i].y,
|
chiaki_controller_state_set_touch_pos(chiaki_state, (uint8_t)it->second, x, y);
|
||||||
// chiaki_state->touches[i].id, chiaki_state->touches[i].x, chiaki_state->touches[i].y);
|
// it->second < 0 ==> touch ignored because there were already too many multi-touches
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -961,7 +974,7 @@ bool IO::FreeController()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IO::UpdateControllerState(ChiakiControllerState *state)
|
void IO::UpdateControllerState(ChiakiControllerState *state, std::map<uint32_t, int8_t> *finger_id_touch_id)
|
||||||
{
|
{
|
||||||
#ifdef __SWITCH__
|
#ifdef __SWITCH__
|
||||||
padUpdate(&this->pad);
|
padUpdate(&this->pad);
|
||||||
|
@ -977,7 +990,7 @@ void IO::UpdateControllerState(ChiakiControllerState *state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReadGameTouchScreen(state);
|
ReadGameTouchScreen(state, finger_id_touch_id);
|
||||||
ReadGameSixAxis(state);
|
ReadGameSixAxis(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue