From 55d48db71121f7bb4b96f6edca576ef282625252 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Mon, 6 Jun 2022 22:03:24 +0200 Subject: [PATCH] Integrate joystick with game controls and menus/editor UI --- src/engine/client/input.cpp | 7 +-- src/game/client/component.h | 3 +- src/game/client/components/controls.cpp | 55 +++++++++++++++++------- src/game/client/components/controls.h | 4 +- src/game/client/components/emoticon.cpp | 4 +- src/game/client/components/emoticon.h | 2 +- src/game/client/components/menus.cpp | 4 +- src/game/client/components/menus.h | 2 +- src/game/client/components/spectator.cpp | 4 +- src/game/client/components/spectator.h | 2 +- src/game/client/gameclient.cpp | 5 ++- src/game/client/ui.cpp | 21 +++++++-- src/game/client/ui.h | 3 +- src/game/client/ui_ex.cpp | 4 +- src/game/client/ui_ex.h | 2 +- src/game/editor/editor.cpp | 4 +- src/game/variables.h | 1 + 17 files changed, 84 insertions(+), 43 deletions(-) diff --git a/src/engine/client/input.cpp b/src/engine/client/input.cpp index e73c61888..f134759bf 100644 --- a/src/engine/client/input.cpp +++ b/src/engine/client/input.cpp @@ -255,8 +255,6 @@ bool CInput::MouseRelative(float *pX, float *pY) return false; int nx = 0, ny = 0; - float Sens = g_Config.m_InpMousesens / 100.0f; - #if defined(CONF_PLATFORM_ANDROID) // No relative mouse on Android static int s_LastX = 0; static int s_LastY = 0; @@ -267,13 +265,12 @@ bool CInput::MouseRelative(float *pX, float *pY) s_LastY = ny; nx = XTmp; ny = YTmp; - Sens = 1; #else SDL_GetRelativeMouseState(&nx, &ny); #endif - *pX = nx * Sens; - *pY = ny * Sens; + *pX = nx; + *pY = ny; return *pX != 0.0f || *pY != 0.0f; } diff --git a/src/game/client/component.h b/src/game/client/component.h index 956f7d40e..e53628421 100644 --- a/src/game/client/component.h +++ b/src/game/client/component.h @@ -199,8 +199,9 @@ public: * * @param x The amount of change in the x coordinate since the last call. * @param y The amount of change in the y coordinate since the last call. + * @param CursorType The type of cursor that caused the movement. */ - virtual bool OnMouseMove(float x, float y) { return false; } + virtual bool OnCursorMove(float x, float y, IInput::ECursorType CursorType) { return false; } /** * Called on a input event. * @param e The input event. diff --git a/src/game/client/components/controls.cpp b/src/game/client/components/controls.cpp index 44a1d92d6..ceb70b610 100644 --- a/src/game/client/components/controls.cpp +++ b/src/game/client/components/controls.cpp @@ -365,26 +365,46 @@ void CControls::OnRender() m_TargetPos[g_Config.m_ClDummy] = m_MousePos[g_Config.m_ClDummy]; } -bool CControls::OnMouseMove(float x, float y) +bool CControls::OnCursorMove(float x, float y, IInput::ECursorType CursorType) { - if((m_pClient->m_Snap.m_pGameInfoObj && m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags & GAMESTATEFLAG_PAUSED)) + if(m_pClient->m_Snap.m_pGameInfoObj && (m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags & GAMESTATEFLAG_PAUSED)) return false; + if(CursorType == IInput::CURSOR_JOYSTICK && g_Config.m_InpJoystickAbsolute && m_pClient->m_Snap.m_pGameInfoObj && !m_pClient->m_Snap.m_SpecInfo.m_Active) + { + float AbsX = 0.0f, AbsY = 0.0f; + if(Input()->GetActiveJoystick()->Absolute(&AbsX, &AbsY)) + m_MousePos[g_Config.m_ClDummy] = vec2(AbsX, AbsY) * GetMaxMouseDistance(); + return true; + } + + float Factor = 1.0f; if(g_Config.m_ClDyncam && g_Config.m_ClDyncamMousesens) { - x = x * g_Config.m_ClDyncamMousesens / g_Config.m_InpMousesens; - y = y * g_Config.m_ClDyncamMousesens / g_Config.m_InpMousesens; + Factor = g_Config.m_ClDyncamMousesens / 100.0f; + } + else + { + switch(CursorType) + { + case IInput::CURSOR_MOUSE: + Factor = g_Config.m_InpMousesens / 100.0f; + break; + case IInput::CURSOR_JOYSTICK: + Factor = g_Config.m_InpJoystickSens / 100.0f; + break; + default: + dbg_msg("assert", "CControls::OnCursorMove CursorType %d", (int)CursorType); + dbg_break(); + break; + } } if(m_pClient->m_Snap.m_SpecInfo.m_Active && m_pClient->m_Snap.m_SpecInfo.m_SpectatorID < 0) - { - x = x * m_pClient->m_Camera.m_Zoom; - y = y * m_pClient->m_Camera.m_Zoom; - } + Factor *= m_pClient->m_Camera.m_Zoom; - m_MousePos[g_Config.m_ClDummy] += vec2(x, y); // TODO: ugly + m_MousePos[g_Config.m_ClDummy] += vec2(x, y) * Factor; ClampMousePos(); - return true; } @@ -397,11 +417,7 @@ void CControls::ClampMousePos() } else { - float CameraMaxDistance = 200.0f; - float FollowFactor = (g_Config.m_ClDyncam ? g_Config.m_ClDyncamFollowFactor : g_Config.m_ClMouseFollowfactor) / 100.0f; - float DeadZone = g_Config.m_ClDyncam ? g_Config.m_ClDyncamDeadzone : g_Config.m_ClMouseDeadzone; - float MaxDistance = g_Config.m_ClDyncam ? g_Config.m_ClDyncamMaxDistance : g_Config.m_ClMouseMaxDistance; - float MouseMax = minimum((FollowFactor != 0 ? CameraMaxDistance / FollowFactor + DeadZone : MaxDistance), MaxDistance); + float MouseMax = GetMaxMouseDistance(); float MinDistance = g_Config.m_ClDyncam ? g_Config.m_ClDyncamMinDistance : g_Config.m_ClMouseMinDistance; float MouseMin = MinDistance; @@ -419,3 +435,12 @@ void CControls::ClampMousePos() m_MousePos[g_Config.m_ClDummy] = normalize_pre_length(m_MousePos[g_Config.m_ClDummy], MDistance) * MouseMax; } } + +float CControls::GetMaxMouseDistance() const +{ + float CameraMaxDistance = 200.0f; + float FollowFactor = (g_Config.m_ClDyncam ? g_Config.m_ClDyncamFollowFactor : g_Config.m_ClMouseFollowfactor) / 100.0f; + float DeadZone = g_Config.m_ClDyncam ? g_Config.m_ClDyncamDeadzone : g_Config.m_ClMouseDeadzone; + float MaxDistance = g_Config.m_ClDyncam ? g_Config.m_ClDyncamMaxDistance : g_Config.m_ClMouseMaxDistance; + return minimum((FollowFactor != 0 ? CameraMaxDistance / FollowFactor + DeadZone : MaxDistance), MaxDistance); +} diff --git a/src/game/client/components/controls.h b/src/game/client/components/controls.h index 63e01be4e..cdbe12d2d 100644 --- a/src/game/client/components/controls.h +++ b/src/game/client/components/controls.h @@ -12,6 +12,8 @@ class CControls : public CComponent { + float GetMaxMouseDistance() const; + public: vec2 m_MousePos[NUM_DUMMIES]; vec2 m_TargetPos[NUM_DUMMIES]; @@ -35,7 +37,7 @@ public: virtual void OnRelease() override; virtual void OnRender() override; virtual void OnMessage(int MsgType, void *pRawMsg) override; - virtual bool OnMouseMove(float x, float y) override; + virtual bool OnCursorMove(float x, float y, IInput::ECursorType CursorType) override; virtual void OnConsoleInit() override; virtual void OnPlayerDeath(); diff --git a/src/game/client/components/emoticon.cpp b/src/game/client/components/emoticon.cpp index 38f058d66..35d84b730 100644 --- a/src/game/client/components/emoticon.cpp +++ b/src/game/client/components/emoticon.cpp @@ -48,12 +48,12 @@ void CEmoticon::OnRelease() m_Active = false; } -bool CEmoticon::OnMouseMove(float x, float y) +bool CEmoticon::OnCursorMove(float x, float y, IInput::ECursorType CursorType) { if(!m_Active) return false; - UI()->ConvertMouseMove(&x, &y); + UI()->ConvertMouseMove(&x, &y, CursorType); m_SelectorMouse += vec2(x, y); return true; } diff --git a/src/game/client/components/emoticon.h b/src/game/client/components/emoticon.h index 752f4bb8f..ed9f10a01 100644 --- a/src/game/client/components/emoticon.h +++ b/src/game/client/components/emoticon.h @@ -27,7 +27,7 @@ public: virtual void OnConsoleInit() override; virtual void OnRender() override; virtual void OnRelease() override; - virtual bool OnMouseMove(float x, float y) override; + virtual bool OnCursorMove(float x, float y, IInput::ECursorType CursorType) override; void Emote(int Emoticon); void EyeEmote(int EyeEmote); diff --git a/src/game/client/components/menus.cpp b/src/game/client/components/menus.cpp index 83d432460..ac547f648 100644 --- a/src/game/client/components/menus.cpp +++ b/src/game/client/components/menus.cpp @@ -2417,12 +2417,12 @@ void CMenus::OnShutdown() KillServer(); } -bool CMenus::OnMouseMove(float x, float y) +bool CMenus::OnCursorMove(float x, float y, IInput::ECursorType CursorType) { if(!m_MenuActive) return false; - UIEx()->ConvertMouseMove(&x, &y); + UIEx()->ConvertMouseMove(&x, &y, CursorType); m_MousePos.x = clamp(m_MousePos.x + x, 0.f, (float)Graphics()->WindowWidth()); m_MousePos.y = clamp(m_MousePos.y + y, 0.f, (float)Graphics()->WindowHeight()); diff --git a/src/game/client/components/menus.h b/src/game/client/components/menus.h index 1d2d96d1e..09aabdd0c 100644 --- a/src/game/client/components/menus.h +++ b/src/game/client/components/menus.h @@ -558,7 +558,7 @@ public: virtual void OnReset() override; virtual void OnRender() override; virtual bool OnInput(IInput::CEvent Event) override; - virtual bool OnMouseMove(float x, float y) override; + virtual bool OnCursorMove(float x, float y, IInput::ECursorType CursorType) override; virtual void OnShutdown() override; enum diff --git a/src/game/client/components/spectator.cpp b/src/game/client/components/spectator.cpp index fe7454416..cff0ceb4c 100644 --- a/src/game/client/components/spectator.cpp +++ b/src/game/client/components/spectator.cpp @@ -164,12 +164,12 @@ void CSpectator::OnConsoleInit() Console()->Register("spectate_closest", "", CFGFLAG_CLIENT, ConSpectateClosest, this, "Spectate the closest player"); } -bool CSpectator::OnMouseMove(float x, float y) +bool CSpectator::OnCursorMove(float x, float y, IInput::ECursorType CursorType) { if(!m_Active) return false; - UI()->ConvertMouseMove(&x, &y); + UI()->ConvertMouseMove(&x, &y, CursorType); m_SelectorMouse += vec2(x, y); return true; } diff --git a/src/game/client/components/spectator.h b/src/game/client/components/spectator.h index 5da55f933..ff1deac00 100644 --- a/src/game/client/components/spectator.h +++ b/src/game/client/components/spectator.h @@ -36,7 +36,7 @@ public: virtual int Sizeof() const override { return sizeof(*this); } virtual void OnConsoleInit() override; - virtual bool OnMouseMove(float x, float y) override; + virtual bool OnCursorMove(float x, float y, IInput::ECursorType CursorType) override; virtual void OnRender() override; virtual void OnRelease() override; virtual void OnReset() override; diff --git a/src/game/client/gameclient.cpp b/src/game/client/gameclient.cpp index f2ea7bc72..9b2c66f7a 100644 --- a/src/game/client/gameclient.cpp +++ b/src/game/client/gameclient.cpp @@ -352,11 +352,12 @@ void CGameClient::OnUpdate() { // handle mouse movement float x = 0.0f, y = 0.0f; - if(Input()->MouseRelative(&x, &y)) + IInput::ECursorType CursorType = Input()->CursorRelative(&x, &y); + if(CursorType != IInput::CURSOR_NONE) { for(auto &pComponent : m_vpInput) { - if(pComponent->OnMouseMove(x, y)) + if(pComponent->OnCursorMove(x, y, CursorType)) break; } } diff --git a/src/game/client/ui.cpp b/src/game/client/ui.cpp index e33a8f793..4b8b4dab4 100644 --- a/src/game/client/ui.cpp +++ b/src/game/client/ui.cpp @@ -164,11 +164,24 @@ bool CUI::MouseInside(const CUIRect *pRect) const return pRect->Inside(m_MouseX, m_MouseY); } -void CUI::ConvertMouseMove(float *x, float *y) const +void CUI::ConvertMouseMove(float *pX, float *pY, IInput::ECursorType CursorType) const { - float Fac = (float)(g_Config.m_UiMousesens) / g_Config.m_InpMousesens; - *x = *x * Fac; - *y = *y * Fac; + float Factor = 1.0f; + switch(CursorType) + { + case IInput::CURSOR_MOUSE: + Factor = g_Config.m_UiMousesens / 100.0f; + break; + case IInput::CURSOR_JOYSTICK: + Factor = g_Config.m_UiJoystickSens / 100.0f; + break; + default: + dbg_msg("assert", "CUI::ConvertMouseMove CursorType %d", (int)CursorType); + dbg_break(); + break; + } + *pX *= Factor; + *pY *= Factor; } float CUI::ButtonColorMul(const void *pID) diff --git a/src/game/client/ui.h b/src/game/client/ui.h index d82e5b6c5..a5bf95b63 100644 --- a/src/game/client/ui.h +++ b/src/game/client/ui.h @@ -3,6 +3,7 @@ #ifndef GAME_CLIENT_UI_H #define GAME_CLIENT_UI_H +#include #include #include @@ -304,7 +305,7 @@ public: bool MouseInside(const CUIRect *pRect) const; bool MouseInsideClip() const { return !IsClipped() || MouseInside(ClipArea()); } bool MouseHovered(const CUIRect *pRect) const { return MouseInside(pRect) && MouseInsideClip(); } - void ConvertMouseMove(float *x, float *y) const; + void ConvertMouseMove(float *pX, float *pY, IInput::ECursorType CursorType) const; float ButtonColorMulActive() { return 0.5f; } float ButtonColorMulHot() { return 1.5f; } diff --git a/src/game/client/ui_ex.cpp b/src/game/client/ui_ex.cpp index 2040342e2..7eca46853 100644 --- a/src/game/client/ui_ex.cpp +++ b/src/game/client/ui_ex.cpp @@ -30,9 +30,9 @@ void CUIEx::Init(CUI *pUI, IKernel *pKernel, CRenderTools *pRenderTools, IInput: m_pTextRender = Kernel()->RequestInterface(); } -void CUIEx::ConvertMouseMove(float *pX, float *pY) const +void CUIEx::ConvertMouseMove(float *pX, float *pY, IInput::ECursorType CursorType) const { - UI()->ConvertMouseMove(pX, pY); + UI()->ConvertMouseMove(pX, pY, CursorType); if(m_MouseSlow) { diff --git a/src/game/client/ui_ex.h b/src/game/client/ui_ex.h index af0af2474..0bae50ac9 100644 --- a/src/game/client/ui_ex.h +++ b/src/game/client/ui_ex.h @@ -57,7 +57,7 @@ public: void Init(CUI *pUI, IKernel *pKernel, CRenderTools *pRenderTools, IInput::CEvent *pInputEventsArray, int *pInputEventCount); - void ConvertMouseMove(float *pX, float *pY) const; + void ConvertMouseMove(float *pX, float *pY, IInput::ECursorType CursorType) const; void ResetMouseSlow() { m_MouseSlow = false; } float DoScrollbarV(const void *pID, const CUIRect *pRect, float Current); diff --git a/src/game/editor/editor.cpp b/src/game/editor/editor.cpp index 1da015195..ac86459b2 100644 --- a/src/game/editor/editor.cpp +++ b/src/game/editor/editor.cpp @@ -6409,8 +6409,8 @@ void CEditor::UpdateAndRender() float mx, my, Mwx, Mwy; float rx = 0, ry = 0; { - Input()->MouseRelative(&rx, &ry); - UIEx()->ConvertMouseMove(&rx, &ry); + IInput::ECursorType CursorType = Input()->CursorRelative(&rx, &ry); + UIEx()->ConvertMouseMove(&rx, &ry, CursorType); UIEx()->ResetMouseSlow(); m_MouseDeltaX = rx; diff --git a/src/game/variables.h b/src/game/variables.h index efbb74b0c..df4f01684 100644 --- a/src/game/variables.h +++ b/src/game/variables.h @@ -119,6 +119,7 @@ MACRO_CONFIG_INT(UiSettingsPage, ui_settings_page, 0, 0, 9, CFGFLAG_CLIENT | CFG MACRO_CONFIG_INT(UiToolboxPage, ui_toolbox_page, 0, 0, 2, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Toolbox page") MACRO_CONFIG_STR(UiServerAddress, ui_server_address, 64, "localhost:8303", CFGFLAG_CLIENT | CFGFLAG_SAVE | CFGFLAG_INSENSITIVE, "Interface server address") MACRO_CONFIG_INT(UiMousesens, ui_mousesens, 200, 1, 100000, CFGFLAG_SAVE | CFGFLAG_CLIENT, "Mouse sensitivity for menus/editor") +MACRO_CONFIG_INT(UiJoystickSens, ui_joystick_sens, 100, 1, 100000, CFGFLAG_SAVE | CFGFLAG_CLIENT, "Joystick sensitivity for menus/editor") MACRO_CONFIG_COL(UiColor, ui_color, 0xE4A046AF, CFGFLAG_CLIENT | CFGFLAG_SAVE | CFGFLAG_COLALPHA, "Interface color") // 160 70 175 228 hasalpha