(Touch controls) Use full virtual joystick instead of hybrid (#612)

* Test touch joystick

* Change radius
This commit is contained in:
Christian Semmler 2025-07-15 15:18:55 -07:00 committed by GitHub
parent f20fc475c7
commit d0dc595fc5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 38 additions and 46 deletions

View File

@ -94,6 +94,7 @@ class LegoInputManager : public MxPresenter {
}; };
enum TouchScheme { enum TouchScheme {
e_none = -1,
e_mouse = 0, e_mouse = 0,
e_arrowKeys, e_arrowKeys,
e_gamepad, e_gamepad,
@ -192,9 +193,10 @@ class LegoInputManager : public MxPresenter {
MxBool m_unk0x335; // 0x335 MxBool m_unk0x335; // 0x335
MxBool m_unk0x336; // 0x336 MxBool m_unk0x336; // 0x336
std::map<SDL_FingerID, SDL_FPoint> m_touchOrigins; TouchScheme m_touchScheme = e_none;
SDL_Point m_touchVirtualThumb = {0, 0};
SDL_FPoint m_touchVirtualThumbOrigin;
std::map<SDL_FingerID, MxU32> m_touchFlags; std::map<SDL_FingerID, MxU32> m_touchFlags;
std::map<SDL_FingerID, std::pair<MxU32, SDL_FPoint>> m_touchLastMotion;
std::map<SDL_MouseID, std::pair<void*, SDL_Haptic*>> m_mice; std::map<SDL_MouseID, std::pair<void*, SDL_Haptic*>> m_mice;
std::map<SDL_JoystickID, std::pair<SDL_Gamepad*, SDL_Haptic*>> m_joysticks; std::map<SDL_JoystickID, std::pair<SDL_Gamepad*, SDL_Haptic*>> m_joysticks;
std::map<SDL_HapticID, SDL_Haptic*> m_otherHaptics; std::map<SDL_HapticID, SDL_Haptic*> m_otherHaptics;

View File

@ -160,7 +160,7 @@ MxResult LegoInputManager::GetNavigationKeyStates(MxU32& p_keyFlags)
// FUNCTION: LEGO1 0x1005c320 // FUNCTION: LEGO1 0x1005c320
MxResult LegoInputManager::GetJoystickState(MxU32* p_joystickX, MxU32* p_joystickY, MxU32* p_povPosition) MxResult LegoInputManager::GetJoystickState(MxU32* p_joystickX, MxU32* p_joystickY, MxU32* p_povPosition)
{ {
if (m_joysticks.empty()) { if (m_joysticks.empty() && m_touchScheme != e_gamepad) {
return FAILURE; return FAILURE;
} }
@ -180,6 +180,11 @@ MxResult LegoInputManager::GetJoystickState(MxU32* p_joystickX, MxU32* p_joystic
} }
} }
if (!xPos && !yPos) {
xPos = m_touchVirtualThumb.x;
yPos = m_touchVirtualThumb.y;
}
*p_joystickX = ((xPos + 32768) * 100) / 65535; *p_joystickX = ((xPos + 32768) * 100) / 65535;
*p_joystickY = ((yPos + 32768) * 100) / 65535; *p_joystickY = ((yPos + 32768) * 100) / 65535;
*p_povPosition = -1; *p_povPosition = -1;
@ -499,18 +504,9 @@ void LegoInputManager::EnableInputProcessing()
MxResult LegoInputManager::GetNavigationTouchStates(MxU32& p_keyStates) MxResult LegoInputManager::GetNavigationTouchStates(MxU32& p_keyStates)
{ {
for (auto& [fingerID, touchFlags] : m_touchFlags) { if (m_touchScheme == e_arrowKeys) {
p_keyStates |= touchFlags; for (auto& [fingerID, touchFlags] : m_touchFlags) {
p_keyStates |= touchFlags;
// We need to clear these as they are not meant to be persistent in e_gamepad mode.
if (m_touchOrigins.count(fingerID) && m_touchLastMotion.count(fingerID)) {
const MxU32 inactivityThreshold = 3;
if (m_touchLastMotion[fingerID].first++ > inactivityThreshold) {
touchFlags &= ~c_left;
touchFlags &= ~c_right;
m_touchOrigins[fingerID].x = m_touchLastMotion[fingerID].second.x;
}
} }
} }
@ -588,6 +584,7 @@ void LegoInputManager::RemoveJoystick(SDL_JoystickID p_joystickID)
MxBool LegoInputManager::HandleTouchEvent(SDL_Event* p_event, TouchScheme p_touchScheme) MxBool LegoInputManager::HandleTouchEvent(SDL_Event* p_event, TouchScheme p_touchScheme)
{ {
const SDL_TouchFingerEvent& event = p_event->tfinger; const SDL_TouchFingerEvent& event = p_event->tfinger;
m_touchScheme = p_touchScheme;
switch (p_touchScheme) { switch (p_touchScheme) {
case e_mouse: case e_mouse:
@ -619,49 +616,42 @@ MxBool LegoInputManager::HandleTouchEvent(SDL_Event* p_event, TouchScheme p_touc
break; break;
} }
break; break;
case e_gamepad: case e_gamepad: {
static SDL_FingerID g_finger = (SDL_FingerID) 0;
switch (p_event->type) { switch (p_event->type) {
case SDL_EVENT_FINGER_DOWN: case SDL_EVENT_FINGER_DOWN:
m_touchOrigins[event.fingerID] = {event.x, event.y}; if (!g_finger) {
g_finger = event.fingerID;
m_touchVirtualThumb = {0, 0};
m_touchVirtualThumbOrigin = {event.x, event.y};
}
break; break;
case SDL_EVENT_FINGER_UP: case SDL_EVENT_FINGER_UP:
m_touchOrigins.erase(event.fingerID); if (event.fingerID == g_finger) {
m_touchFlags.erase(event.fingerID); g_finger = 0;
m_touchVirtualThumb = {0, 0};
m_touchVirtualThumbOrigin = {0, 0};
}
break; break;
case SDL_EVENT_FINGER_MOTION: case SDL_EVENT_FINGER_MOTION:
if (m_touchOrigins.count(event.fingerID)) { if (event.fingerID == g_finger) {
const float activationThreshold = 0.03f; const float thumbstickRadius = 0.25f;
m_touchFlags[event.fingerID] &= ~c_down; const float deltaX =
m_touchFlags[event.fingerID] &= ~c_up; SDL_clamp(event.x - m_touchVirtualThumbOrigin.x, -thumbstickRadius, thumbstickRadius);
const float deltaY =
SDL_clamp(event.y - m_touchVirtualThumbOrigin.y, -thumbstickRadius, thumbstickRadius);
const float deltaY = event.y - m_touchOrigins[event.fingerID].y; m_touchVirtualThumb = {
if (SDL_fabsf(deltaY) > activationThreshold) { (int) (deltaX / thumbstickRadius * 32767.0f),
if (deltaY > 0) { (int) (deltaY / thumbstickRadius * 32767.0f),
m_touchFlags[event.fingerID] |= c_down; };
}
else if (deltaY < 0) {
m_touchFlags[event.fingerID] |= c_up;
}
}
const float deltaX = event.x - m_touchOrigins[event.fingerID].x;
if (SDL_fabsf(deltaX) > activationThreshold && event.dx) {
if (event.dx > 0) {
m_touchFlags[event.fingerID] |= c_right;
m_touchFlags[event.fingerID] &= ~c_left;
}
else if (event.dx < 0) {
m_touchFlags[event.fingerID] |= c_left;
m_touchFlags[event.fingerID] &= ~c_right;
}
m_touchLastMotion[event.fingerID] = {0, {event.x, event.y}};
}
} }
break; break;
} }
break; break;
} }
}
return TRUE; return TRUE;
} }