diff --git a/src/game/client/components/emoticon.cpp b/src/game/client/components/emoticon.cpp index 9d0d2b910..e7c0963d0 100644 --- a/src/game/client/components/emoticon.cpp +++ b/src/game/client/components/emoticon.cpp @@ -41,6 +41,7 @@ void CEmoticon::OnReset() m_Active = false; m_SelectedEmote = -1; m_SelectedEyeEmote = -1; + m_TouchPressedOutside = false; } void CEmoticon::OnRelease() @@ -58,6 +59,16 @@ bool CEmoticon::OnCursorMove(float x, float y, IInput::ECursorType CursorType) return true; } +bool CEmoticon::OnInput(const IInput::CEvent &Event) +{ + if(IsActive() && Event.m_Flags & IInput::FLAG_PRESS && Event.m_Key == KEY_ESCAPE) + { + OnRelease(); + return true; + } + return false; +} + void CEmoticon::OnRender() { if(Client()->State() != IClient::STATE_ONLINE && Client()->State() != IClient::STATE_DEMOPLAYBACK) @@ -65,6 +76,13 @@ void CEmoticon::OnRender() if(!m_Active) { + if(m_TouchPressedOutside) + { + m_SelectedEmote = -1; + m_SelectedEyeEmote = -1; + m_TouchPressedOutside = false; + } + if(m_WasActive && m_SelectedEmote != -1) Emote(m_SelectedEmote); if(m_WasActive && m_SelectedEyeEmote != -1) @@ -82,6 +100,29 @@ void CEmoticon::OnRender() m_WasActive = true; + const CUIRect Screen = *Ui()->Screen(); + + const bool WasTouchPressed = m_TouchState.m_AnyPressed; + Ui()->UpdateTouchState(m_TouchState); + if(m_TouchState.m_AnyPressed) + { + const vec2 TouchPos = (m_TouchState.m_PrimaryPosition - vec2(0.5f, 0.5f)) * Screen.Size(); + const float TouchCenterDistance = length(TouchPos); + if(TouchCenterDistance <= 170.0f) + { + m_SelectorMouse = TouchPos; + } + else if(TouchCenterDistance > 190.0f) + { + m_TouchPressedOutside = true; + } + } + else if(WasTouchPressed) + { + m_Active = false; + return; + } + if(length(m_SelectorMouse) > 170.0f) m_SelectorMouse = normalize(m_SelectorMouse) * 170.0f; @@ -96,7 +137,7 @@ void CEmoticon::OnRender() else if(length(m_SelectorMouse) > 40.0f) m_SelectedEyeEmote = (int)(SelectedAngle / (2 * pi) * NUM_EMOTES); - CUIRect Screen = *Ui()->Screen(); + const vec2 ScreenCenter = Screen.Center(); Ui()->MapScreen(); @@ -105,26 +146,22 @@ void CEmoticon::OnRender() Graphics()->TextureClear(); Graphics()->QuadsBegin(); Graphics()->SetColor(0, 0, 0, 0.3f); - Graphics()->DrawCircle(Screen.w / 2, Screen.h / 2, 190.0f, 64); + Graphics()->DrawCircle(ScreenCenter.x, ScreenCenter.y, 190.0f, 64); Graphics()->QuadsEnd(); Graphics()->WrapClamp(); - for(int i = 0; i < NUM_EMOTICONS; i++) + for(int Emote = 0; Emote < NUM_EMOTICONS; Emote++) { - float Angle = 2 * pi * i / NUM_EMOTICONS; + float Angle = 2 * pi * Emote / NUM_EMOTICONS; if(Angle > pi) Angle -= 2 * pi; - bool Selected = m_SelectedEmote == i; - - float Size = Selected ? 80.0f : 50.0f; - - Graphics()->TextureSet(GameClient()->m_EmoticonsSkin.m_aSpriteEmoticons[i]); + Graphics()->TextureSet(GameClient()->m_EmoticonsSkin.m_aSpriteEmoticons[Emote]); Graphics()->QuadsSetSubset(0, 0, 1, 1); - Graphics()->QuadsBegin(); const vec2 Nudge = direction(Angle) * 150.0f; - IGraphics::CQuadItem QuadItem(Screen.w / 2 + Nudge.x, Screen.h / 2 + Nudge.y, Size, Size); + const float Size = m_SelectedEmote == Emote ? 80.0f : 50.0f; + IGraphics::CQuadItem QuadItem(ScreenCenter.x + Nudge.x, ScreenCenter.y + Nudge.y, Size, Size); Graphics()->QuadsDraw(&QuadItem, 1); Graphics()->QuadsEnd(); } @@ -135,34 +172,32 @@ void CEmoticon::OnRender() Graphics()->TextureClear(); Graphics()->QuadsBegin(); Graphics()->SetColor(1.0, 1.0, 1.0, 0.3f); - Graphics()->DrawCircle(Screen.w / 2, Screen.h / 2, 100.0f, 64); + Graphics()->DrawCircle(ScreenCenter.x, ScreenCenter.y, 100.0f, 64); Graphics()->QuadsEnd(); CTeeRenderInfo TeeInfo = m_pClient->m_aClients[m_pClient->m_aLocalIds[g_Config.m_ClDummy]].m_RenderInfo; - for(int i = 0; i < NUM_EMOTES; i++) + for(int Emote = 0; Emote < NUM_EMOTES; Emote++) { - float Angle = 2 * pi * i / NUM_EMOTES; + float Angle = 2 * pi * Emote / NUM_EMOTES; if(Angle > pi) Angle -= 2 * pi; - const bool Selected = m_SelectedEyeEmote == i; - const vec2 Nudge = direction(Angle) * 70.0f; - TeeInfo.m_Size = Selected ? 64.0f : 48.0f; - RenderTools()->RenderTee(CAnimState::GetIdle(), &TeeInfo, i, vec2(-1, 0), vec2(Screen.w / 2 + Nudge.x, Screen.h / 2 + Nudge.y)); + TeeInfo.m_Size = m_SelectedEyeEmote == Emote ? 64.0f : 48.0f; + RenderTools()->RenderTee(CAnimState::GetIdle(), &TeeInfo, Emote, vec2(-1, 0), ScreenCenter + Nudge); } Graphics()->TextureClear(); Graphics()->QuadsBegin(); Graphics()->SetColor(0, 0, 0, 0.3f); - Graphics()->DrawCircle(Screen.w / 2, Screen.h / 2, 30.0f, 64); + Graphics()->DrawCircle(ScreenCenter.x, ScreenCenter.y, 30.0f, 64); Graphics()->QuadsEnd(); } else m_SelectedEyeEmote = -1; - RenderTools()->RenderCursor(m_SelectorMouse + vec2(Screen.w, Screen.h) / 2, 24.0f); + RenderTools()->RenderCursor(ScreenCenter + m_SelectorMouse, 24.0f); } void CEmoticon::Emote(int Emoticon) diff --git a/src/game/client/components/emoticon.h b/src/game/client/components/emoticon.h index c7d068cb1..890f1c80e 100644 --- a/src/game/client/components/emoticon.h +++ b/src/game/client/components/emoticon.h @@ -4,7 +4,9 @@ #define GAME_CLIENT_COMPONENTS_EMOTICON_H #include #include + #include +#include class CEmoticon : public CComponent { @@ -15,6 +17,9 @@ class CEmoticon : public CComponent int m_SelectedEmote; int m_SelectedEyeEmote; + CUi::CTouchState m_TouchState; + bool m_TouchPressedOutside; + static void ConKeyEmoticon(IConsole::IResult *pResult, void *pUserData); static void ConEmote(IConsole::IResult *pResult, void *pUserData); @@ -27,9 +32,12 @@ public: virtual void OnRender() override; virtual void OnRelease() override; virtual bool OnCursorMove(float x, float y, IInput::ECursorType CursorType) override; + virtual bool OnInput(const IInput::CEvent &Event) override; void Emote(int Emoticon); void EyeEmote(int EyeEmote); + + bool IsActive() const { return m_Active; } }; #endif diff --git a/src/game/client/components/spectator.cpp b/src/game/client/components/spectator.cpp index 97b9d955b..c14a33f91 100644 --- a/src/game/client/components/spectator.cpp +++ b/src/game/client/components/spectator.cpp @@ -186,6 +186,16 @@ bool CSpectator::OnCursorMove(float x, float y, IInput::ECursorType CursorType) return true; } +bool CSpectator::OnInput(const IInput::CEvent &Event) +{ + if(IsActive() && Event.m_Flags & IInput::FLAG_PRESS && Event.m_Key == KEY_ESCAPE) + { + OnRelease(); + return true; + } + return false; +} + void CSpectator::OnRelease() { OnReset(); @@ -258,8 +268,6 @@ void CSpectator::OnRender() float BoxMove = -10.0f; float BoxOffset = 0.0f; - const bool MousePressed = Input()->KeyPress(KEY_MOUSE_1); - for(const auto &pInfo : m_pClient->m_Snap.m_apInfoByDDTeamName) { if(!pInfo || pInfo->m_Team == TEAM_SPECTATORS) @@ -293,14 +301,42 @@ void CSpectator::OnRender() ObjWidth = 600.0f; } + const vec2 ScreenSize = vec2(Width, Height); + const vec2 ScreenCenter = ScreenSize / 2.0f; + CUIRect SpectatorRect = {Width / 2.0f - ObjWidth, Height / 2.0f - 300.0f, ObjWidth * 2.0f, 600.0f}; + CUIRect SpectatorMouseRect; + SpectatorRect.Margin(20.0f, &SpectatorMouseRect); + + const bool WasTouchPressed = m_TouchState.m_AnyPressed; + Ui()->UpdateTouchState(m_TouchState); + if(m_TouchState.m_AnyPressed) + { + const vec2 TouchPos = (m_TouchState.m_PrimaryPosition - vec2(0.5f, 0.5f)) * ScreenSize; + if(SpectatorMouseRect.Inside(ScreenCenter + TouchPos)) + { + m_SelectorMouse = TouchPos; + } + } + else if(WasTouchPressed) + { + const vec2 TouchPos = (m_TouchState.m_PrimaryPosition - vec2(0.5f, 0.5f)) * ScreenSize; + if(!SpectatorRect.Inside(ScreenCenter + TouchPos)) + { + OnRelease(); + return; + } + } + Graphics()->MapScreen(0, 0, Width, Height); - Graphics()->DrawRect(Width / 2.0f - ObjWidth, Height / 2.0f - 300.0f, ObjWidth * 2, 600.0f, ColorRGBA(0.0f, 0.0f, 0.0f, 0.3f), IGraphics::CORNER_ALL, 20.0f); + SpectatorRect.Draw(ColorRGBA(0.0f, 0.0f, 0.0f, 0.3f), IGraphics::CORNER_ALL, 20.0f); // clamp mouse position to selector area m_SelectorMouse.x = clamp(m_SelectorMouse.x, -(ObjWidth - 20.0f), ObjWidth - 20.0f); m_SelectorMouse.y = clamp(m_SelectorMouse.y, -280.0f, 280.0f); + const bool MousePressed = Input()->KeyPress(KEY_MOUSE_1) || m_TouchState.m_PrimaryPressed; + // draw selections if((Client()->State() == IClient::STATE_DEMOPLAYBACK && m_pClient->m_DemoSpecId == SPEC_FREEVIEW) || (Client()->State() != IClient::STATE_DEMOPLAYBACK && m_pClient->m_Snap.m_SpecInfo.m_SpectatorId == SPEC_FREEVIEW)) @@ -543,7 +579,7 @@ void CSpectator::OnRender() } TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f); - RenderTools()->RenderCursor(m_SelectorMouse + vec2(Width, Height) / 2, 48.0f); + RenderTools()->RenderCursor(ScreenCenter + m_SelectorMouse, 48.0f); } void CSpectator::OnReset() diff --git a/src/game/client/components/spectator.h b/src/game/client/components/spectator.h index e7fdc2449..25dddfb60 100644 --- a/src/game/client/components/spectator.h +++ b/src/game/client/components/spectator.h @@ -6,6 +6,7 @@ #include #include +#include class CSpectator : public CComponent { @@ -21,6 +22,8 @@ class CSpectator : public CComponent int m_SelectedSpectatorId; vec2 m_SelectorMouse; + CUi::CTouchState m_TouchState; + float m_MultiViewActivateDelay; bool CanChangeSpectator(); @@ -39,12 +42,15 @@ public: virtual void OnConsoleInit() override; virtual bool OnCursorMove(float x, float y, IInput::ECursorType CursorType) override; + virtual bool OnInput(const IInput::CEvent &Event) override; virtual void OnRender() override; virtual void OnRelease() override; virtual void OnReset() override; void Spectate(int SpectatorId); void SpectateClosest(); + + bool IsActive() const { return m_Active; } }; #endif diff --git a/src/game/client/gameclient.cpp b/src/game/client/gameclient.cpp index 636f9e806..1f450fa04 100644 --- a/src/game/client/gameclient.cpp +++ b/src/game/client/gameclient.cpp @@ -160,9 +160,9 @@ void CGameClient::OnConsoleInit() &m_GameConsole, &m_Chat, // chat has higher prio, due to that you can quit it by pressing esc &m_Motd, // for pressing esc to remove it - &m_Menus, &m_Spectator, &m_Emoticon, + &m_Menus, &m_Controls, &m_Binds});