mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-09 09:38:19 +00:00
Merge pull request #8801 from Robyt3/Client-Touch-Input-Emote-Spectate
Add touch support to emoticon selector and spectator menu, minor refactoring
This commit is contained in:
commit
be2e49e1f6
|
@ -41,6 +41,7 @@ void CEmoticon::OnReset()
|
||||||
m_Active = false;
|
m_Active = false;
|
||||||
m_SelectedEmote = -1;
|
m_SelectedEmote = -1;
|
||||||
m_SelectedEyeEmote = -1;
|
m_SelectedEyeEmote = -1;
|
||||||
|
m_TouchPressedOutside = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CEmoticon::OnRelease()
|
void CEmoticon::OnRelease()
|
||||||
|
@ -58,6 +59,16 @@ bool CEmoticon::OnCursorMove(float x, float y, IInput::ECursorType CursorType)
|
||||||
return true;
|
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()
|
void CEmoticon::OnRender()
|
||||||
{
|
{
|
||||||
if(Client()->State() != IClient::STATE_ONLINE && Client()->State() != IClient::STATE_DEMOPLAYBACK)
|
if(Client()->State() != IClient::STATE_ONLINE && Client()->State() != IClient::STATE_DEMOPLAYBACK)
|
||||||
|
@ -65,6 +76,13 @@ void CEmoticon::OnRender()
|
||||||
|
|
||||||
if(!m_Active)
|
if(!m_Active)
|
||||||
{
|
{
|
||||||
|
if(m_TouchPressedOutside)
|
||||||
|
{
|
||||||
|
m_SelectedEmote = -1;
|
||||||
|
m_SelectedEyeEmote = -1;
|
||||||
|
m_TouchPressedOutside = false;
|
||||||
|
}
|
||||||
|
|
||||||
if(m_WasActive && m_SelectedEmote != -1)
|
if(m_WasActive && m_SelectedEmote != -1)
|
||||||
Emote(m_SelectedEmote);
|
Emote(m_SelectedEmote);
|
||||||
if(m_WasActive && m_SelectedEyeEmote != -1)
|
if(m_WasActive && m_SelectedEyeEmote != -1)
|
||||||
|
@ -82,6 +100,29 @@ void CEmoticon::OnRender()
|
||||||
|
|
||||||
m_WasActive = true;
|
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)
|
if(length(m_SelectorMouse) > 170.0f)
|
||||||
m_SelectorMouse = normalize(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)
|
else if(length(m_SelectorMouse) > 40.0f)
|
||||||
m_SelectedEyeEmote = (int)(SelectedAngle / (2 * pi) * NUM_EMOTES);
|
m_SelectedEyeEmote = (int)(SelectedAngle / (2 * pi) * NUM_EMOTES);
|
||||||
|
|
||||||
CUIRect Screen = *Ui()->Screen();
|
const vec2 ScreenCenter = Screen.Center();
|
||||||
|
|
||||||
Ui()->MapScreen();
|
Ui()->MapScreen();
|
||||||
|
|
||||||
|
@ -105,26 +146,22 @@ void CEmoticon::OnRender()
|
||||||
Graphics()->TextureClear();
|
Graphics()->TextureClear();
|
||||||
Graphics()->QuadsBegin();
|
Graphics()->QuadsBegin();
|
||||||
Graphics()->SetColor(0, 0, 0, 0.3f);
|
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()->QuadsEnd();
|
||||||
|
|
||||||
Graphics()->WrapClamp();
|
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)
|
if(Angle > pi)
|
||||||
Angle -= 2 * pi;
|
Angle -= 2 * pi;
|
||||||
|
|
||||||
bool Selected = m_SelectedEmote == i;
|
Graphics()->TextureSet(GameClient()->m_EmoticonsSkin.m_aSpriteEmoticons[Emote]);
|
||||||
|
|
||||||
float Size = Selected ? 80.0f : 50.0f;
|
|
||||||
|
|
||||||
Graphics()->TextureSet(GameClient()->m_EmoticonsSkin.m_aSpriteEmoticons[i]);
|
|
||||||
Graphics()->QuadsSetSubset(0, 0, 1, 1);
|
Graphics()->QuadsSetSubset(0, 0, 1, 1);
|
||||||
|
|
||||||
Graphics()->QuadsBegin();
|
Graphics()->QuadsBegin();
|
||||||
const vec2 Nudge = direction(Angle) * 150.0f;
|
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()->QuadsDraw(&QuadItem, 1);
|
||||||
Graphics()->QuadsEnd();
|
Graphics()->QuadsEnd();
|
||||||
}
|
}
|
||||||
|
@ -135,34 +172,32 @@ void CEmoticon::OnRender()
|
||||||
Graphics()->TextureClear();
|
Graphics()->TextureClear();
|
||||||
Graphics()->QuadsBegin();
|
Graphics()->QuadsBegin();
|
||||||
Graphics()->SetColor(1.0, 1.0, 1.0, 0.3f);
|
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();
|
Graphics()->QuadsEnd();
|
||||||
|
|
||||||
CTeeRenderInfo TeeInfo = m_pClient->m_aClients[m_pClient->m_aLocalIds[g_Config.m_ClDummy]].m_RenderInfo;
|
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)
|
if(Angle > pi)
|
||||||
Angle -= 2 * pi;
|
Angle -= 2 * pi;
|
||||||
|
|
||||||
const bool Selected = m_SelectedEyeEmote == i;
|
|
||||||
|
|
||||||
const vec2 Nudge = direction(Angle) * 70.0f;
|
const vec2 Nudge = direction(Angle) * 70.0f;
|
||||||
TeeInfo.m_Size = Selected ? 64.0f : 48.0f;
|
TeeInfo.m_Size = m_SelectedEyeEmote == Emote ? 64.0f : 48.0f;
|
||||||
RenderTools()->RenderTee(CAnimState::GetIdle(), &TeeInfo, i, vec2(-1, 0), vec2(Screen.w / 2 + Nudge.x, Screen.h / 2 + Nudge.y));
|
RenderTools()->RenderTee(CAnimState::GetIdle(), &TeeInfo, Emote, vec2(-1, 0), ScreenCenter + Nudge);
|
||||||
}
|
}
|
||||||
|
|
||||||
Graphics()->TextureClear();
|
Graphics()->TextureClear();
|
||||||
Graphics()->QuadsBegin();
|
Graphics()->QuadsBegin();
|
||||||
Graphics()->SetColor(0, 0, 0, 0.3f);
|
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();
|
Graphics()->QuadsEnd();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_SelectedEyeEmote = -1;
|
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)
|
void CEmoticon::Emote(int Emoticon)
|
||||||
|
|
|
@ -4,7 +4,9 @@
|
||||||
#define GAME_CLIENT_COMPONENTS_EMOTICON_H
|
#define GAME_CLIENT_COMPONENTS_EMOTICON_H
|
||||||
#include <base/vmath.h>
|
#include <base/vmath.h>
|
||||||
#include <engine/console.h>
|
#include <engine/console.h>
|
||||||
|
|
||||||
#include <game/client/component.h>
|
#include <game/client/component.h>
|
||||||
|
#include <game/client/ui.h>
|
||||||
|
|
||||||
class CEmoticon : public CComponent
|
class CEmoticon : public CComponent
|
||||||
{
|
{
|
||||||
|
@ -15,6 +17,9 @@ class CEmoticon : public CComponent
|
||||||
int m_SelectedEmote;
|
int m_SelectedEmote;
|
||||||
int m_SelectedEyeEmote;
|
int m_SelectedEyeEmote;
|
||||||
|
|
||||||
|
CUi::CTouchState m_TouchState;
|
||||||
|
bool m_TouchPressedOutside;
|
||||||
|
|
||||||
static void ConKeyEmoticon(IConsole::IResult *pResult, void *pUserData);
|
static void ConKeyEmoticon(IConsole::IResult *pResult, void *pUserData);
|
||||||
static void ConEmote(IConsole::IResult *pResult, void *pUserData);
|
static void ConEmote(IConsole::IResult *pResult, void *pUserData);
|
||||||
|
|
||||||
|
@ -27,9 +32,12 @@ public:
|
||||||
virtual void OnRender() override;
|
virtual void OnRender() override;
|
||||||
virtual void OnRelease() override;
|
virtual void OnRelease() override;
|
||||||
virtual bool OnCursorMove(float x, float y, IInput::ECursorType CursorType) 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 Emote(int Emoticon);
|
||||||
void EyeEmote(int EyeEmote);
|
void EyeEmote(int EyeEmote);
|
||||||
|
|
||||||
|
bool IsActive() const { return m_Active; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -186,6 +186,16 @@ bool CSpectator::OnCursorMove(float x, float y, IInput::ECursorType CursorType)
|
||||||
return true;
|
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()
|
void CSpectator::OnRelease()
|
||||||
{
|
{
|
||||||
OnReset();
|
OnReset();
|
||||||
|
@ -258,8 +268,6 @@ void CSpectator::OnRender()
|
||||||
float BoxMove = -10.0f;
|
float BoxMove = -10.0f;
|
||||||
float BoxOffset = 0.0f;
|
float BoxOffset = 0.0f;
|
||||||
|
|
||||||
const bool MousePressed = Input()->KeyPress(KEY_MOUSE_1);
|
|
||||||
|
|
||||||
for(const auto &pInfo : m_pClient->m_Snap.m_apInfoByDDTeamName)
|
for(const auto &pInfo : m_pClient->m_Snap.m_apInfoByDDTeamName)
|
||||||
{
|
{
|
||||||
if(!pInfo || pInfo->m_Team == TEAM_SPECTATORS)
|
if(!pInfo || pInfo->m_Team == TEAM_SPECTATORS)
|
||||||
|
@ -293,14 +301,42 @@ void CSpectator::OnRender()
|
||||||
ObjWidth = 600.0f;
|
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()->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
|
// clamp mouse position to selector area
|
||||||
m_SelectorMouse.x = clamp(m_SelectorMouse.x, -(ObjWidth - 20.0f), ObjWidth - 20.0f);
|
m_SelectorMouse.x = clamp(m_SelectorMouse.x, -(ObjWidth - 20.0f), ObjWidth - 20.0f);
|
||||||
m_SelectorMouse.y = clamp(m_SelectorMouse.y, -280.0f, 280.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
|
// draw selections
|
||||||
if((Client()->State() == IClient::STATE_DEMOPLAYBACK && m_pClient->m_DemoSpecId == SPEC_FREEVIEW) ||
|
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))
|
(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);
|
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()
|
void CSpectator::OnReset()
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <engine/console.h>
|
#include <engine/console.h>
|
||||||
|
|
||||||
#include <game/client/component.h>
|
#include <game/client/component.h>
|
||||||
|
#include <game/client/ui.h>
|
||||||
|
|
||||||
class CSpectator : public CComponent
|
class CSpectator : public CComponent
|
||||||
{
|
{
|
||||||
|
@ -21,6 +22,8 @@ class CSpectator : public CComponent
|
||||||
int m_SelectedSpectatorId;
|
int m_SelectedSpectatorId;
|
||||||
vec2 m_SelectorMouse;
|
vec2 m_SelectorMouse;
|
||||||
|
|
||||||
|
CUi::CTouchState m_TouchState;
|
||||||
|
|
||||||
float m_MultiViewActivateDelay;
|
float m_MultiViewActivateDelay;
|
||||||
|
|
||||||
bool CanChangeSpectator();
|
bool CanChangeSpectator();
|
||||||
|
@ -39,12 +42,15 @@ public:
|
||||||
|
|
||||||
virtual void OnConsoleInit() override;
|
virtual void OnConsoleInit() override;
|
||||||
virtual bool OnCursorMove(float x, float y, IInput::ECursorType CursorType) 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 OnRender() override;
|
||||||
virtual void OnRelease() override;
|
virtual void OnRelease() override;
|
||||||
virtual void OnReset() override;
|
virtual void OnReset() override;
|
||||||
|
|
||||||
void Spectate(int SpectatorId);
|
void Spectate(int SpectatorId);
|
||||||
void SpectateClosest();
|
void SpectateClosest();
|
||||||
|
|
||||||
|
bool IsActive() const { return m_Active; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -160,9 +160,9 @@ void CGameClient::OnConsoleInit()
|
||||||
&m_GameConsole,
|
&m_GameConsole,
|
||||||
&m_Chat, // chat has higher prio, due to that you can quit it by pressing esc
|
&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_Motd, // for pressing esc to remove it
|
||||||
&m_Menus,
|
|
||||||
&m_Spectator,
|
&m_Spectator,
|
||||||
&m_Emoticon,
|
&m_Emoticon,
|
||||||
|
&m_Menus,
|
||||||
&m_Controls,
|
&m_Controls,
|
||||||
&m_Binds});
|
&m_Binds});
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue