diff --git a/LEGO1/lego/legoomni/src/input/legoinputmanager.cpp b/LEGO1/lego/legoomni/src/input/legoinputmanager.cpp index a794581b..1a1dfc8f 100644 --- a/LEGO1/lego/legoomni/src/input/legoinputmanager.cpp +++ b/LEGO1/lego/legoomni/src/input/legoinputmanager.cpp @@ -638,7 +638,7 @@ void LegoInputManager::RemoveJoystick(SDL_JoystickID p_joystickID) MxBool LegoInputManager::HandleTouchEvent(SDL_Event* p_event, TouchScheme p_touchScheme) { - if (Extension::Call(HandleTouchInput).value_or(FALSE)) { + if (Extension::Call(HandleTouchInput, p_event).value_or(FALSE)) { return FALSE; } diff --git a/extensions/include/extensions/multiplayer.h b/extensions/include/extensions/multiplayer.h index e8e3f77c..ea1e0891 100644 --- a/extensions/include/extensions/multiplayer.h +++ b/extensions/include/extensions/multiplayer.h @@ -71,9 +71,9 @@ class MultiplayerExt { // Returns TRUE when the third-person camera is active. static MxBool IsThirdPersonCameraActive(); - // Suppresses touch input when a multi-touch camera gesture is active. - // Returns TRUE if the caller should return early. - static MxBool HandleTouchInput(); + // Routes touch events by screen zone: right half → camera, left half → movement. + // Returns TRUE if the event was consumed by the camera (caller should skip movement). + static MxBool HandleTouchInput(SDL_Event* p_event); // Overrides nav controller movement for camera-relative 3rd person controls. // Returns TRUE if the hook handled movement (caller should return early). diff --git a/extensions/include/extensions/multiplayer/thirdpersoncamera.h b/extensions/include/extensions/multiplayer/thirdpersoncamera.h index d9dfeb6f..7de796cb 100644 --- a/extensions/include/extensions/multiplayer/thirdpersoncamera.h +++ b/extensions/include/extensions/multiplayer/thirdpersoncamera.h @@ -68,7 +68,13 @@ class ThirdPersonCamera { // Free camera input handling void HandleSDLEvent(SDL_Event* p_event); - bool IsTouchGestureActive() const { return m_touchGestureActive; } + + // Finger-claiming API for split-screen touch zones (left=movement, right=camera) + bool TryClaimFinger(const SDL_TouchFingerEvent& event); + bool TryReleaseFinger(SDL_FingerID id); + bool IsFingerTracked(SDL_FingerID id) const; + + static constexpr float CAMERA_ZONE_X = 0.5f; private: // Orbit camera helpers @@ -114,7 +120,6 @@ class ThirdPersonCamera { float m_smoothedSpeed; // Extension-managed velocity for smooth acceleration/deceleration // Touch gesture tracking - bool m_touchGestureActive = false; struct TouchState { SDL_FingerID id[2]; float x[2], y[2]; diff --git a/extensions/src/multiplayer.cpp b/extensions/src/multiplayer.cpp index bede0661..a9908bad 100644 --- a/extensions/src/multiplayer.cpp +++ b/extensions/src/multiplayer.cpp @@ -11,7 +11,6 @@ #include "legoentity.h" #include "legoeventnotificationparam.h" #include "legogamestate.h" -#include "legoinputmanager.h" #include "legonavcontroller.h" #include "legopathactor.h" #include "misc.h" @@ -310,18 +309,37 @@ MxBool MultiplayerExt::IsThirdPersonCameraActive() return FALSE; } -MxBool MultiplayerExt::HandleTouchInput() +MxBool MultiplayerExt::HandleTouchInput(SDL_Event* p_event) { - if (s_networkManager && s_networkManager->GetThirdPersonCamera().IsActive() && - s_networkManager->GetThirdPersonCamera().IsTouchGestureActive()) { - LegoInputManager* im = InputManager(); - im->m_touchFinger = 0; - im->m_touchVirtualThumb = {0, 0}; - im->m_touchFlags.clear(); - return TRUE; + if (!s_networkManager || !s_networkManager->GetThirdPersonCamera().IsActive()) { + return FALSE; } - return FALSE; + Multiplayer::ThirdPersonCamera& cam = s_networkManager->GetThirdPersonCamera(); + + switch (p_event->type) { + case SDL_EVENT_FINGER_DOWN: + if (cam.TryClaimFinger(p_event->tfinger)) { + return TRUE; + } + return FALSE; + + case SDL_EVENT_FINGER_MOTION: + if (cam.IsFingerTracked(p_event->tfinger.fingerID)) { + return TRUE; + } + return FALSE; + + case SDL_EVENT_FINGER_UP: + case SDL_EVENT_FINGER_CANCELED: + if (cam.TryReleaseFinger(p_event->tfinger.fingerID)) { + return TRUE; + } + return FALSE; + + default: + return FALSE; + } } MxBool MultiplayerExt::HandleNavOverride( diff --git a/extensions/src/multiplayer/thirdpersoncamera.cpp b/extensions/src/multiplayer/thirdpersoncamera.cpp index aeb95301..7ee33732 100644 --- a/extensions/src/multiplayer/thirdpersoncamera.cpp +++ b/extensions/src/multiplayer/thirdpersoncamera.cpp @@ -758,6 +758,55 @@ MxBool ThirdPersonCamera::HandleCameraRelativeMovement( return TRUE; } +bool ThirdPersonCamera::TryClaimFinger(const SDL_TouchFingerEvent& event) +{ + if (!m_active || m_touch.count >= 2 || event.x < CAMERA_ZONE_X) { + return false; + } + + int idx = m_touch.count; + m_touch.id[idx] = event.fingerID; + m_touch.x[idx] = event.x; + m_touch.y[idx] = event.y; + m_touch.count++; + + if (m_touch.count == 2) { + float dx = m_touch.x[1] - m_touch.x[0]; + float dy = m_touch.y[1] - m_touch.y[0]; + m_touch.initialPinchDist = SDL_sqrtf(dx * dx + dy * dy); + } + + return true; +} + +bool ThirdPersonCamera::TryReleaseFinger(SDL_FingerID id) +{ + for (int i = 0; i < m_touch.count; i++) { + if (m_touch.id[i] == id) { + // Shift remaining finger down + if (i == 0 && m_touch.count == 2) { + m_touch.id[0] = m_touch.id[1]; + m_touch.x[0] = m_touch.x[1]; + m_touch.y[0] = m_touch.y[1]; + } + m_touch.count--; + m_touch.initialPinchDist = 0.0f; + return true; + } + } + return false; +} + +bool ThirdPersonCamera::IsFingerTracked(SDL_FingerID id) const +{ + for (int i = 0; i < m_touch.count; i++) { + if (m_touch.id[i] == id) { + return true; + } + } + return false; +} + void ThirdPersonCamera::HandleSDLEvent(SDL_Event* p_event) { switch (p_event->type) { @@ -784,7 +833,10 @@ void ThirdPersonCamera::HandleSDLEvent(SDL_Event* p_event) } case SDL_EVENT_FINGER_DOWN: { - if (m_touch.count < 2) { + // Finger may already be claimed via TryClaimFinger (called from HandleTouchInput). + // Only register if not already tracked and in the camera zone. + if (!IsFingerTracked(p_event->tfinger.fingerID) && m_touch.count < 2 && + p_event->tfinger.x >= CAMERA_ZONE_X) { int idx = m_touch.count; m_touch.id[idx] = p_event->tfinger.fingerID; m_touch.x[idx] = p_event->tfinger.x; @@ -792,7 +844,6 @@ void ThirdPersonCamera::HandleSDLEvent(SDL_Event* p_event) m_touch.count++; if (m_touch.count == 2) { - m_touchGestureActive = true; float dx = m_touch.x[1] - m_touch.x[0]; float dy = m_touch.y[1] - m_touch.y[0]; m_touch.initialPinchDist = SDL_sqrtf(dx * dx + dy * dy); @@ -802,7 +853,22 @@ void ThirdPersonCamera::HandleSDLEvent(SDL_Event* p_event) } case SDL_EVENT_FINGER_MOTION: { - if (m_touch.count == 2) { + if (m_touch.count == 1) { + // Single-finger drag: apply yaw/pitch rotation + if (m_touch.id[0] == p_event->tfinger.fingerID) { + float oldX = m_touch.x[0]; + float oldY = m_touch.y[0]; + m_touch.x[0] = p_event->tfinger.x; + m_touch.y[0] = p_event->tfinger.y; + + float moveX = m_touch.x[0] - oldX; + float moveY = m_touch.y[0] - oldY; + m_absoluteYaw -= moveX * 2.0f; + m_orbitPitch += moveY * 2.0f; + ClampPitch(); + } + } + else if (m_touch.count == 2) { // Find which finger moved int idx = -1; for (int i = 0; i < 2; i++) { @@ -835,7 +901,7 @@ void ThirdPersonCamera::HandleSDLEvent(SDL_Event* p_event) // Two-finger drag for orbit float moveX = m_touch.x[idx] - oldX; float moveY = m_touch.y[idx] - oldY; - m_absoluteYaw += moveX * 2.0f; + m_absoluteYaw -= moveX * 2.0f; m_orbitPitch += moveY * 2.0f; ClampPitch(); } @@ -844,22 +910,7 @@ void ThirdPersonCamera::HandleSDLEvent(SDL_Event* p_event) case SDL_EVENT_FINGER_UP: case SDL_EVENT_FINGER_CANCELED: { - for (int i = 0; i < m_touch.count; i++) { - if (m_touch.id[i] == p_event->tfinger.fingerID) { - // Shift remaining finger down - if (i == 0 && m_touch.count == 2) { - m_touch.id[0] = m_touch.id[1]; - m_touch.x[0] = m_touch.x[1]; - m_touch.y[0] = m_touch.y[1]; - } - m_touch.count--; - if (m_touch.count == 0) { - m_touchGestureActive = false; - } - m_touch.initialPinchDist = 0.0f; - break; - } - } + TryReleaseFinger(p_event->tfinger.fingerID); break; }