mirror of
https://github.com/ddnet/ddnet.git
synced 2024-09-18 16:52:18 +00:00
Compare commits
8 commits
933acce52b
...
f7527dffcf
Author | SHA1 | Date | |
---|---|---|---|
f7527dffcf | |||
0feee9aa3e | |||
65cf776846 | |||
62075d22e3 | |||
0369946156 | |||
232018de23 | |||
fe2f73b518 | |||
41ad7263eb |
|
@ -1845,6 +1845,7 @@ set(EXPECTED_DATA
|
|||
themes/winter.png
|
||||
themes/winter_day.map
|
||||
themes/winter_night.map
|
||||
touch_controls.json
|
||||
wordlist.txt
|
||||
)
|
||||
|
||||
|
@ -2399,6 +2400,8 @@ if(CLIENT)
|
|||
components/statboard.h
|
||||
components/tooltips.cpp
|
||||
components/tooltips.h
|
||||
components/touch_controls.cpp
|
||||
components/touch_controls.h
|
||||
components/voting.cpp
|
||||
components/voting.h
|
||||
gameclient.cpp
|
||||
|
|
306
data/touch_controls.json
Normal file
306
data/touch_controls.json
Normal file
|
@ -0,0 +1,306 @@
|
|||
{
|
||||
"direct-touch-ingame": true,
|
||||
"direct-touch-spectate": true,
|
||||
"touch-buttons": [
|
||||
{
|
||||
"x": 0,
|
||||
"y": 833333,
|
||||
"w": 200000,
|
||||
"h": 166667,
|
||||
"shape": "rect",
|
||||
"visibilities": [
|
||||
"ingame"
|
||||
],
|
||||
"behavior": {
|
||||
"type": "bind",
|
||||
"label": "Move left",
|
||||
"label-type": "localized",
|
||||
"command": "+left"
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": 200000,
|
||||
"y": 833333,
|
||||
"w": 200000,
|
||||
"h": 166667,
|
||||
"shape": "rect",
|
||||
"visibilities": [
|
||||
"ingame"
|
||||
],
|
||||
"behavior": {
|
||||
"type": "bind",
|
||||
"label": "Move right",
|
||||
"label-type": "localized",
|
||||
"command": "+right"
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": 100000,
|
||||
"y": 666667,
|
||||
"w": 200000,
|
||||
"h": 166667,
|
||||
"shape": "rect",
|
||||
"visibilities": [
|
||||
"ingame"
|
||||
],
|
||||
"behavior": {
|
||||
"type": "bind",
|
||||
"label": "Jump",
|
||||
"label-type": "localized",
|
||||
"command": "+jump"
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": 116667,
|
||||
"y": 16667,
|
||||
"w": 83333,
|
||||
"h": 83333,
|
||||
"shape": "rect",
|
||||
"visibilities": [
|
||||
"ingame"
|
||||
],
|
||||
"behavior": {
|
||||
"type": "bind",
|
||||
"label": "Prev. weapon",
|
||||
"label-type": "localized",
|
||||
"command": "+prevweapon"
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": 200000,
|
||||
"y": 16667,
|
||||
"w": 83333,
|
||||
"h": 83333,
|
||||
"shape": "rect",
|
||||
"visibilities": [
|
||||
"ingame"
|
||||
],
|
||||
"behavior": {
|
||||
"type": "bind",
|
||||
"label": "Next weapon",
|
||||
"label-type": "localized",
|
||||
"command": "+nextweapon"
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": 16667,
|
||||
"y": 16667,
|
||||
"w": 83333,
|
||||
"h": 83333,
|
||||
"shape": "rect",
|
||||
"visibilities": [
|
||||
],
|
||||
"behavior": {
|
||||
"type": "predefined",
|
||||
"id": "extra-menu",
|
||||
"number": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": 300000,
|
||||
"y": 16667,
|
||||
"w": 83333,
|
||||
"h": 83333,
|
||||
"shape": "rect",
|
||||
"visibilities": [
|
||||
"extra-menu",
|
||||
"zoom-allowed"
|
||||
],
|
||||
"behavior": {
|
||||
"type": "bind",
|
||||
"label": "Zoom out",
|
||||
"label-type": "localized",
|
||||
"command": "zoom-"
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": 383333,
|
||||
"y": 16667,
|
||||
"w": 83333,
|
||||
"h": 83333,
|
||||
"shape": "rect",
|
||||
"visibilities": [
|
||||
"extra-menu",
|
||||
"zoom-allowed"
|
||||
],
|
||||
"behavior": {
|
||||
"type": "bind",
|
||||
"label": "Default zoom",
|
||||
"label-type": "localized",
|
||||
"command": "zoom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": 466666,
|
||||
"y": 16667,
|
||||
"w": 83333,
|
||||
"h": 83333,
|
||||
"shape": "rect",
|
||||
"visibilities": [
|
||||
"extra-menu",
|
||||
"zoom-allowed"
|
||||
],
|
||||
"behavior": {
|
||||
"type": "bind",
|
||||
"label": "Zoom in",
|
||||
"label-type": "localized",
|
||||
"command": "zoom+"
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": 16667,
|
||||
"y": 133333,
|
||||
"w": 83333,
|
||||
"h": 66667,
|
||||
"shape": "rect",
|
||||
"visibilities": [
|
||||
"extra-menu"
|
||||
],
|
||||
"behavior": {
|
||||
"type": "bind",
|
||||
"label": "Scoreboard",
|
||||
"label-type": "localized",
|
||||
"command": "+scoreboard"
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": 116667,
|
||||
"y": 133333,
|
||||
"w": 83333,
|
||||
"h": 66667,
|
||||
"shape": "rect",
|
||||
"visibilities": [
|
||||
"ingame",
|
||||
"extra-menu"
|
||||
],
|
||||
"behavior": {
|
||||
"type": "predefined",
|
||||
"id": "emoticon"
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": 116667,
|
||||
"y": 133333,
|
||||
"w": 83333,
|
||||
"h": 66667,
|
||||
"shape": "rect",
|
||||
"visibilities": [
|
||||
"-ingame",
|
||||
"extra-menu"
|
||||
],
|
||||
"behavior": {
|
||||
"type": "predefined",
|
||||
"id": "spectate"
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": 216667,
|
||||
"y": 133333,
|
||||
"w": 83333,
|
||||
"h": 66667,
|
||||
"shape": "rect",
|
||||
"visibilities": [
|
||||
"extra-menu"
|
||||
],
|
||||
"behavior": {
|
||||
"type": "bind",
|
||||
"label": "Chat",
|
||||
"label-type": "localized",
|
||||
"command": "chat all"
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": 316667,
|
||||
"y": 133333,
|
||||
"w": 83333,
|
||||
"h": 66667,
|
||||
"shape": "rect",
|
||||
"visibilities": [
|
||||
"extra-menu"
|
||||
],
|
||||
"behavior": {
|
||||
"type": "bind",
|
||||
"label": "Team chat",
|
||||
"label-type": "localized",
|
||||
"command": "chat team"
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": 16667,
|
||||
"y": 333333,
|
||||
"w": 83333,
|
||||
"h": 66667,
|
||||
"shape": "rect",
|
||||
"visibilities": [
|
||||
"extra-menu",
|
||||
"vote-active"
|
||||
],
|
||||
"behavior": {
|
||||
"type": "bind",
|
||||
"label": "Vote yes",
|
||||
"label-type": "localized",
|
||||
"command": "vote yes"
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": 116667,
|
||||
"y": 333333,
|
||||
"w": 83333,
|
||||
"h": 66667,
|
||||
"shape": "rect",
|
||||
"visibilities": [
|
||||
"extra-menu",
|
||||
"vote-active"
|
||||
],
|
||||
"behavior": {
|
||||
"type": "bind",
|
||||
"label": "Vote no",
|
||||
"label-type": "localized",
|
||||
"command": "vote no"
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": 766667,
|
||||
"y": 16667,
|
||||
"w": 100000,
|
||||
"h": 100000,
|
||||
"shape": "rect",
|
||||
"visibilities": [
|
||||
"dummy-connected"
|
||||
],
|
||||
"behavior": {
|
||||
"type": "bind",
|
||||
"label": "Toggle dummy",
|
||||
"label-type": "localized",
|
||||
"command": "toggle cl_dummy 0 1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": 883333,
|
||||
"y": 16667,
|
||||
"w": 100000,
|
||||
"h": 100000,
|
||||
"shape": "rect",
|
||||
"visibilities": [
|
||||
"ingame"
|
||||
],
|
||||
"behavior": {
|
||||
"type": "predefined",
|
||||
"id": "swap-action"
|
||||
}
|
||||
},
|
||||
{
|
||||
"x": 755000,
|
||||
"y": 580000,
|
||||
"w": 225000,
|
||||
"h": 400000,
|
||||
"shape": "circle",
|
||||
"visibilities": [
|
||||
],
|
||||
"behavior": {
|
||||
"type": "predefined",
|
||||
"id": "joystick-action"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -300,6 +300,14 @@ const std::vector<IInput::CTouchFingerState> &CInput::TouchFingerStates() const
|
|||
return m_vTouchFingerStates;
|
||||
}
|
||||
|
||||
void CInput::ClearTouchDeltas()
|
||||
{
|
||||
for(CTouchFingerState &TouchFingerState : m_vTouchFingerStates)
|
||||
{
|
||||
TouchFingerState.m_Delta = vec2(0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
std::string CInput::GetClipboardText()
|
||||
{
|
||||
char *pClipboardText = SDL_GetClipboardText();
|
||||
|
@ -347,10 +355,7 @@ void CInput::Clear()
|
|||
mem_zero(m_aInputState, sizeof(m_aInputState));
|
||||
mem_zero(m_aInputCount, sizeof(m_aInputCount));
|
||||
m_vInputEvents.clear();
|
||||
for(CTouchFingerState &TouchFingerState : m_vTouchFingerStates)
|
||||
{
|
||||
TouchFingerState.m_Delta = vec2(0.0f, 0.0f);
|
||||
}
|
||||
ClearTouchDeltas();
|
||||
}
|
||||
|
||||
float CInput::GetUpdateTime() const
|
||||
|
|
|
@ -144,6 +144,7 @@ public:
|
|||
bool NativeMousePressed(int Index) const override;
|
||||
|
||||
const std::vector<CTouchFingerState> &TouchFingerStates() const override;
|
||||
void ClearTouchDeltas() override;
|
||||
|
||||
std::string GetClipboardText() override;
|
||||
void SetClipboardText(const char *pText) override;
|
||||
|
|
|
@ -137,6 +137,12 @@ public:
|
|||
* @return vector of all touch finger states
|
||||
*/
|
||||
virtual const std::vector<CTouchFingerState> &TouchFingerStates() const = 0;
|
||||
/**
|
||||
* Must be called after the touch finger states have been used during the client update to ensure that
|
||||
* touch deltas are only accumulated until the next update. If the touch states are only used during
|
||||
* rendering, i.e. for user interfaces, then this is called automatically by calling @link Clear @endlink.
|
||||
*/
|
||||
virtual void ClearTouchDeltas() = 0;
|
||||
|
||||
// clipboard
|
||||
virtual std::string GetClipboardText() = 0;
|
||||
|
|
|
@ -22,6 +22,11 @@ MACRO_CONFIG_INT(ClAntiPingSmooth, cl_antiping_smooth, 0, 0, 1, CFGFLAG_CLIENT |
|
|||
MACRO_CONFIG_INT(ClAntiPingGunfire, cl_antiping_gunfire, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Predict gunfire and show predicted weapon physics (with cl_antiping_grenade 1 and cl_antiping_weapons 1)")
|
||||
MACRO_CONFIG_INT(ClPredictionMargin, cl_prediction_margin, 10, 1, 300, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Prediction margin in ms (adds latency, can reduce lag from ping jumps)")
|
||||
MACRO_CONFIG_INT(ClSubTickAiming, cl_sub_tick_aiming, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Send aiming data at sub-tick accuracy")
|
||||
#if defined(CONF_PLATFORM_ANDROID)
|
||||
MACRO_CONFIG_INT(ClTouchControls, cl_touch_controls, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Enable ingame touch controls")
|
||||
#else
|
||||
MACRO_CONFIG_INT(ClTouchControls, cl_touch_controls, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Enable ingame touch controls")
|
||||
#endif
|
||||
|
||||
MACRO_CONFIG_INT(ClNameplates, cl_nameplates, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Show name plates")
|
||||
MACRO_CONFIG_INT(ClAfkEmote, cl_afk_emote, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Show zzz emote next to afk players")
|
||||
|
|
|
@ -212,6 +212,14 @@ public:
|
|||
* @param Event The input event.
|
||||
*/
|
||||
virtual bool OnInput(const IInput::CEvent &Event) { return false; }
|
||||
/**
|
||||
* Called with all current touch finger states.
|
||||
*
|
||||
* @param vTouchFingerStates The touch finger states to be handled.
|
||||
*
|
||||
* @return `true` if the component used the touch events, `false` otherwise
|
||||
*/
|
||||
virtual bool OnTouchState(const std::vector<IInput::CTouchFingerState> &vTouchFingerStates) { return false; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -805,50 +805,9 @@ void CChat::AddLine(int ClientId, int Team, const char *pLine)
|
|||
{
|
||||
if(!g_Config.m_ClChatOld)
|
||||
{
|
||||
pCurrentLine->m_CustomColoredSkin = LineAuthor.m_RenderInfo.m_CustomColoredSkin;
|
||||
if(pCurrentLine->m_CustomColoredSkin)
|
||||
pCurrentLine->m_RenderSkin = LineAuthor.m_RenderInfo.m_ColorableRenderSkin;
|
||||
else
|
||||
pCurrentLine->m_RenderSkin = LineAuthor.m_RenderInfo.m_OriginalRenderSkin;
|
||||
|
||||
str_copy(pCurrentLine->m_aSkinName, LineAuthor.m_aSkinName);
|
||||
pCurrentLine->m_ColorBody = LineAuthor.m_RenderInfo.m_ColorBody;
|
||||
pCurrentLine->m_ColorFeet = LineAuthor.m_RenderInfo.m_ColorFeet;
|
||||
|
||||
pCurrentLine->m_RenderSkinMetrics = LineAuthor.m_RenderInfo.m_SkinMetrics;
|
||||
pCurrentLine->m_TeeRenderInfo = LineAuthor.m_RenderInfo;
|
||||
pCurrentLine->m_HasRenderTee = true;
|
||||
|
||||
// 0.7
|
||||
if(Client()->IsSixup())
|
||||
{
|
||||
for(int Part = 0; Part < protocol7::NUM_SKINPARTS; Part++)
|
||||
{
|
||||
const char *pPartName = LineAuthor.m_aSixup[g_Config.m_ClDummy].m_aaSkinPartNames[Part];
|
||||
int Id = m_pClient->m_Skins7.FindSkinPart(Part, pPartName, false);
|
||||
const CSkins7::CSkinPart *pSkinPart = m_pClient->m_Skins7.GetSkinPart(Part, Id);
|
||||
if(LineAuthor.m_aSixup[g_Config.m_ClDummy].m_aUseCustomColors[Part])
|
||||
{
|
||||
pCurrentLine->m_Sixup.m_aTextures[Part] = pSkinPart->m_ColorTexture;
|
||||
pCurrentLine->m_Sixup.m_aColors[Part] = m_pClient->m_Skins7.GetColor(
|
||||
LineAuthor.m_aSixup[g_Config.m_ClDummy].m_aSkinPartColors[Part],
|
||||
Part == protocol7::SKINPART_MARKING);
|
||||
}
|
||||
else
|
||||
{
|
||||
pCurrentLine->m_Sixup.m_aTextures[Part] = pSkinPart->m_OrgTexture;
|
||||
pCurrentLine->m_Sixup.m_aColors[Part] = vec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
if(LineAuthor.m_SkinInfo.m_aSixup[g_Config.m_ClDummy].m_HatTexture.IsValid())
|
||||
{
|
||||
if(Part == protocol7::SKINPART_BODY && str_comp(pPartName, "standard"))
|
||||
pCurrentLine->m_Sixup.m_HatSpriteIndex = CSkins7::HAT_OFFSET_SIDE + (ClientId % CSkins7::HAT_NUM);
|
||||
if(Part == protocol7::SKINPART_DECORATION && str_comp(pPartName, "twinbopp"))
|
||||
pCurrentLine->m_Sixup.m_HatSpriteIndex = CSkins7::HAT_OFFSET_SIDE + (ClientId % CSkins7::HAT_NUM);
|
||||
pCurrentLine->m_Sixup.m_HatTexture = LineAuthor.m_SkinInfo.m_aSixup[g_Config.m_ClDummy].m_HatTexture;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -917,17 +876,11 @@ void CChat::OnRefreshSkins()
|
|||
{
|
||||
if(Line.m_HasRenderTee)
|
||||
{
|
||||
const CSkin *pSkin = m_pClient->m_Skins.Find(Line.m_aSkinName);
|
||||
if(Line.m_CustomColoredSkin)
|
||||
Line.m_RenderSkin = pSkin->m_ColorableSkin;
|
||||
else
|
||||
Line.m_RenderSkin = pSkin->m_OriginalSkin;
|
||||
|
||||
Line.m_RenderSkinMetrics = pSkin->m_Metrics;
|
||||
Line.m_TeeRenderInfo.Apply(m_pClient->m_Skins.Find(Line.m_aSkinName));
|
||||
}
|
||||
else
|
||||
{
|
||||
Line.m_RenderSkin.Reset();
|
||||
Line.m_TeeRenderInfo.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1291,28 +1244,7 @@ void CChat::OnRender()
|
|||
if(!g_Config.m_ClChatOld && Line.m_HasRenderTee)
|
||||
{
|
||||
const int TeeSize = MessageTeeSize();
|
||||
CTeeRenderInfo RenderInfo;
|
||||
RenderInfo.m_CustomColoredSkin = Line.m_CustomColoredSkin;
|
||||
if(Line.m_CustomColoredSkin)
|
||||
RenderInfo.m_ColorableRenderSkin = Line.m_RenderSkin;
|
||||
else
|
||||
RenderInfo.m_OriginalRenderSkin = Line.m_RenderSkin;
|
||||
RenderInfo.m_SkinMetrics = Line.m_RenderSkinMetrics;
|
||||
|
||||
RenderInfo.m_ColorBody = Line.m_ColorBody;
|
||||
RenderInfo.m_ColorFeet = Line.m_ColorFeet;
|
||||
RenderInfo.m_Size = TeeSize;
|
||||
|
||||
if(Client()->IsSixup())
|
||||
{
|
||||
for(int Part = 0; Part < protocol7::NUM_SKINPARTS; Part++)
|
||||
{
|
||||
RenderInfo.m_aSixup[g_Config.m_ClDummy].m_aColors[Part] = Line.m_Sixup.m_aColors[Part];
|
||||
RenderInfo.m_aSixup[g_Config.m_ClDummy].m_aTextures[Part] = Line.m_Sixup.m_aTextures[Part];
|
||||
RenderInfo.m_aSixup[g_Config.m_ClDummy].m_HatSpriteIndex = Line.m_Sixup.m_HatSpriteIndex;
|
||||
RenderInfo.m_aSixup[g_Config.m_ClDummy].m_HatTexture = Line.m_Sixup.m_HatTexture;
|
||||
}
|
||||
}
|
||||
Line.m_TeeRenderInfo.m_Size = TeeSize;
|
||||
|
||||
float RowHeight = FontSize() + RealMsgPaddingY;
|
||||
float OffsetTeeY = TeeSize / 2.0f;
|
||||
|
@ -1320,9 +1252,9 @@ void CChat::OnRender()
|
|||
|
||||
const CAnimState *pIdleState = CAnimState::GetIdle();
|
||||
vec2 OffsetToMid;
|
||||
CRenderTools::GetRenderTeeOffsetToRenderedTee(pIdleState, &RenderInfo, OffsetToMid);
|
||||
CRenderTools::GetRenderTeeOffsetToRenderedTee(pIdleState, &Line.m_TeeRenderInfo, OffsetToMid);
|
||||
vec2 TeeRenderPos(x + (RealMsgPaddingX + TeeSize) / 2.0f, y + OffsetTeeY + FullHeightMinusTee / 2.0f + OffsetToMid.y);
|
||||
RenderTools()->RenderTee(pIdleState, &RenderInfo, EMOTE_NORMAL, vec2(1, 0.1f), TeeRenderPos, Blend);
|
||||
RenderTools()->RenderTee(pIdleState, &Line.m_TeeRenderInfo, EMOTE_NORMAL, vec2(1, 0.1f), TeeRenderPos, Blend);
|
||||
}
|
||||
|
||||
const ColorRGBA TextColor = TextRender()->DefaultTextColor().WithMultipliedAlpha(Blend);
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include <game/client/component.h>
|
||||
#include <game/client/lineinput.h>
|
||||
#include <game/client/render.h>
|
||||
#include <game/client/skin.h>
|
||||
#include <game/generated/protocol7.h>
|
||||
|
||||
|
@ -45,30 +46,12 @@ class CChat : public CComponent
|
|||
int m_QuadContainerIndex;
|
||||
|
||||
char m_aSkinName[std::size(g_Config.m_ClPlayerSkin)];
|
||||
CSkin::SSkinTextures m_RenderSkin;
|
||||
CSkin::SSkinMetrics m_RenderSkinMetrics;
|
||||
bool m_CustomColoredSkin;
|
||||
ColorRGBA m_ColorBody;
|
||||
ColorRGBA m_ColorFeet;
|
||||
|
||||
bool m_HasRenderTee;
|
||||
CTeeRenderInfo m_TeeRenderInfo;
|
||||
|
||||
float m_TextYOffset;
|
||||
|
||||
int m_TimesRepeated;
|
||||
|
||||
class CSixup
|
||||
{
|
||||
public:
|
||||
IGraphics::CTextureHandle m_aTextures[protocol7::NUM_SKINPARTS];
|
||||
IGraphics::CTextureHandle m_HatTexture;
|
||||
IGraphics::CTextureHandle m_BotTexture;
|
||||
int m_HatSpriteIndex;
|
||||
ColorRGBA m_BotColor;
|
||||
ColorRGBA m_aColors[protocol7::NUM_SKINPARTS];
|
||||
};
|
||||
|
||||
// 0.7 Skin
|
||||
CSixup m_Sixup;
|
||||
};
|
||||
|
||||
bool m_PrevScoreBoardShowed;
|
||||
|
|
|
@ -12,10 +12,10 @@
|
|||
|
||||
class CControls : public CComponent
|
||||
{
|
||||
public:
|
||||
float GetMinMouseDistance() const;
|
||||
float GetMaxMouseDistance() const;
|
||||
|
||||
public:
|
||||
vec2 m_aMousePos[NUM_DUMMIES];
|
||||
vec2 m_aMousePosOnAction[NUM_DUMMIES];
|
||||
vec2 m_aTargetPos[NUM_DUMMIES];
|
||||
|
|
|
@ -366,10 +366,7 @@ void CGhost::OnRender()
|
|||
IsTeamplay = (m_pClient->m_Snap.m_pGameInfoObj->m_GameFlags & GAMEFLAG_TEAMS) != 0;
|
||||
|
||||
GhostNinjaRenderInfo = Ghost.m_RenderInfo;
|
||||
GhostNinjaRenderInfo.m_OriginalRenderSkin = pSkin->m_OriginalSkin;
|
||||
GhostNinjaRenderInfo.m_ColorableRenderSkin = pSkin->m_ColorableSkin;
|
||||
GhostNinjaRenderInfo.m_BloodColor = pSkin->m_BloodColor;
|
||||
GhostNinjaRenderInfo.m_SkinMetrics = pSkin->m_Metrics;
|
||||
GhostNinjaRenderInfo.Apply(pSkin);
|
||||
GhostNinjaRenderInfo.m_CustomColoredSkin = IsTeamplay;
|
||||
if(!IsTeamplay)
|
||||
{
|
||||
|
@ -392,11 +389,7 @@ void CGhost::InitRenderInfos(CGhostItem *pGhost)
|
|||
IntsToStr(&pGhost->m_Skin.m_Skin0, 6, aSkinName, std::size(aSkinName));
|
||||
CTeeRenderInfo *pRenderInfo = &pGhost->m_RenderInfo;
|
||||
|
||||
const CSkin *pSkin = m_pClient->m_Skins.Find(aSkinName);
|
||||
pRenderInfo->m_OriginalRenderSkin = pSkin->m_OriginalSkin;
|
||||
pRenderInfo->m_ColorableRenderSkin = pSkin->m_ColorableSkin;
|
||||
pRenderInfo->m_BloodColor = pSkin->m_BloodColor;
|
||||
pRenderInfo->m_SkinMetrics = pSkin->m_Metrics;
|
||||
pRenderInfo->Apply(m_pClient->m_Skins.Find(aSkinName));
|
||||
pRenderInfo->m_CustomColoredSkin = pGhost->m_Skin.m_UseCustomColor;
|
||||
if(pGhost->m_Skin.m_UseCustomColor)
|
||||
{
|
||||
|
@ -697,11 +690,7 @@ void CGhost::OnRefreshSkins()
|
|||
CTeeRenderInfo *pRenderInfo = &Ghost.m_RenderInfo;
|
||||
if(aSkinName[0] != '\0')
|
||||
{
|
||||
const CSkin *pSkin = m_pClient->m_Skins.Find(aSkinName);
|
||||
pRenderInfo->m_OriginalRenderSkin = pSkin->m_OriginalSkin;
|
||||
pRenderInfo->m_ColorableRenderSkin = pSkin->m_ColorableSkin;
|
||||
pRenderInfo->m_BloodColor = pSkin->m_BloodColor;
|
||||
pRenderInfo->m_SkinMetrics = pSkin->m_Metrics;
|
||||
pRenderInfo->Apply(m_pClient->m_Skins.Find(aSkinName));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -475,8 +475,12 @@ protected:
|
|||
// found in menus_ingame.cpp
|
||||
STextContainerIndex m_MotdTextContainerIndex;
|
||||
void RenderGame(CUIRect MainView);
|
||||
void RenderTouchControlsEditor(CUIRect MainView);
|
||||
void PopupConfirmDisconnect();
|
||||
void PopupConfirmDisconnectDummy();
|
||||
void PopupConfirmDiscardTouchControlsChanged();
|
||||
void PopupConfirmResetTouchControls();
|
||||
void PopupConfirmImportTouchControlsClipboard();
|
||||
void RenderPlayers(CUIRect MainView);
|
||||
void RenderServerInfo(CUIRect MainView);
|
||||
void RenderServerInfoMotd(CUIRect Motd);
|
||||
|
@ -637,7 +641,6 @@ protected:
|
|||
static CUi::EPopupMenuFunctionResult PopupMapPicker(void *pContext, CUIRect View, bool Active);
|
||||
|
||||
void SetNeedSendInfo();
|
||||
void SetActive(bool Active);
|
||||
void UpdateColors();
|
||||
|
||||
IGraphics::CTextureHandle m_TextureBlob;
|
||||
|
@ -657,6 +660,8 @@ public:
|
|||
bool IsInit() { return m_IsInit; }
|
||||
|
||||
bool IsActive() const { return m_MenuActive; }
|
||||
void SetActive(bool Active);
|
||||
|
||||
void KillServer();
|
||||
|
||||
virtual void OnInit() override;
|
||||
|
|
|
@ -1822,12 +1822,8 @@ bool CMenus::PrintHighlighted(const char *pName, F &&PrintFn)
|
|||
|
||||
CTeeRenderInfo CMenus::GetTeeRenderInfo(vec2 Size, const char *pSkinName, bool CustomSkinColors, int CustomSkinColorBody, int CustomSkinColorFeet) const
|
||||
{
|
||||
const CSkin *pSkin = m_pClient->m_Skins.Find(pSkinName);
|
||||
|
||||
CTeeRenderInfo TeeInfo;
|
||||
TeeInfo.m_OriginalRenderSkin = pSkin->m_OriginalSkin;
|
||||
TeeInfo.m_ColorableRenderSkin = pSkin->m_ColorableSkin;
|
||||
TeeInfo.m_SkinMetrics = pSkin->m_Metrics;
|
||||
TeeInfo.Apply(m_pClient->m_Skins.Find(pSkinName));
|
||||
TeeInfo.m_CustomColoredSkin = CustomSkinColors;
|
||||
if(CustomSkinColors)
|
||||
{
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include <game/client/animstate.h>
|
||||
#include <game/client/components/countryflags.h>
|
||||
#include <game/client/components/touch_controls.h>
|
||||
#include <game/client/gameclient.h>
|
||||
#include <game/client/render.h>
|
||||
#include <game/client/ui.h>
|
||||
|
@ -40,21 +41,19 @@ using namespace std::chrono_literals;
|
|||
|
||||
void CMenus::RenderGame(CUIRect MainView)
|
||||
{
|
||||
CUIRect Button, ButtonBar, ButtonBar2;
|
||||
CUIRect Button, ButtonBars, ButtonBar, ButtonBar2;
|
||||
bool ShowDDRaceButtons = MainView.w > 855.0f;
|
||||
MainView.HSplitTop(45.0f, &ButtonBar, &MainView);
|
||||
ButtonBar.Draw(ms_ColorTabbarActive, IGraphics::CORNER_B, 10.0f);
|
||||
|
||||
// button bar
|
||||
ButtonBar.HSplitTop(10.0f, 0, &ButtonBar);
|
||||
ButtonBar.HSplitTop(25.0f, &ButtonBar, 0);
|
||||
ButtonBar.VMargin(10.0f, &ButtonBar);
|
||||
|
||||
ButtonBar.HSplitTop(30.0f, 0, &ButtonBar2);
|
||||
ButtonBar2.HSplitTop(25.0f, &ButtonBar2, 0);
|
||||
MainView.HSplitTop(45.0f + (g_Config.m_ClTouchControls ? 35.0f : 0.0f), &ButtonBars, &MainView);
|
||||
ButtonBars.Draw(ms_ColorTabbarActive, IGraphics::CORNER_B, 10.0f);
|
||||
ButtonBars.Margin(10.0f, &ButtonBars);
|
||||
ButtonBars.HSplitTop(25.0f, &ButtonBar, &ButtonBars);
|
||||
if(g_Config.m_ClTouchControls)
|
||||
{
|
||||
ButtonBars.HSplitTop(10.0f, nullptr, &ButtonBars);
|
||||
ButtonBars.HSplitTop(25.0f, &ButtonBar2, &ButtonBars);
|
||||
}
|
||||
|
||||
ButtonBar.VSplitRight(120.0f, &ButtonBar, &Button);
|
||||
|
||||
static CButtonContainer s_DisconnectButton;
|
||||
if(DoButton_Menu(&s_DisconnectButton, Localize("Disconnect"), 0, &Button))
|
||||
{
|
||||
|
@ -214,6 +213,147 @@ void CMenus::RenderGame(CUIRect MainView)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(g_Config.m_ClTouchControls)
|
||||
{
|
||||
ButtonBar2.VSplitLeft(200.0f, &Button, &ButtonBar2);
|
||||
static char s_TouchControlsEditCheckbox;
|
||||
if(DoButton_CheckBox(&s_TouchControlsEditCheckbox, Localize("Edit touch controls"), GameClient()->m_TouchControls.IsEditingActive(), &Button))
|
||||
{
|
||||
GameClient()->m_TouchControls.SetEditingActive(!GameClient()->m_TouchControls.IsEditingActive());
|
||||
}
|
||||
|
||||
ButtonBar2.VSplitRight(80.0f, &ButtonBar2, &Button);
|
||||
static CButtonContainer s_CloseButton;
|
||||
if(DoButton_Menu(&s_CloseButton, Localize("Close"), 0, &Button))
|
||||
{
|
||||
SetActive(false);
|
||||
}
|
||||
|
||||
ButtonBar2.VSplitRight(5.0f, &ButtonBar2, nullptr);
|
||||
ButtonBar2.VSplitRight(160.0f, &ButtonBar2, &Button);
|
||||
static CButtonContainer s_RemoveConsoleButton;
|
||||
if(DoButton_Menu(&s_RemoveConsoleButton, Localize("Remote console"), 0, &Button))
|
||||
{
|
||||
Console()->ExecuteLine("toggle_remote_console");
|
||||
}
|
||||
|
||||
ButtonBar2.VSplitRight(5.0f, &ButtonBar2, nullptr);
|
||||
ButtonBar2.VSplitRight(120.0f, &ButtonBar2, &Button);
|
||||
static CButtonContainer s_LocalConsoleButton;
|
||||
if(DoButton_Menu(&s_LocalConsoleButton, Localize("Console"), 0, &Button))
|
||||
{
|
||||
Console()->ExecuteLine("toggle_local_console");
|
||||
}
|
||||
|
||||
if(GameClient()->m_TouchControls.IsEditingActive())
|
||||
{
|
||||
CUIRect TouchControlsEditor;
|
||||
MainView.VMargin((MainView.w - 505.0f) / 2.0f, &TouchControlsEditor);
|
||||
TouchControlsEditor.HMargin((TouchControlsEditor.h - 195.0f) / 2.0f, &TouchControlsEditor);
|
||||
RenderTouchControlsEditor(TouchControlsEditor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CMenus::RenderTouchControlsEditor(CUIRect MainView)
|
||||
{
|
||||
CUIRect Button, Row;
|
||||
MainView.Draw(ms_ColorTabbarActive, IGraphics::CORNER_ALL, 10.0f);
|
||||
MainView.Margin(10.0f, &MainView);
|
||||
|
||||
MainView.HSplitTop(25.0f, &Button, &MainView);
|
||||
MainView.HSplitTop(5.0f, nullptr, &MainView);
|
||||
Ui()->DoLabel(&Button, Localize("Edit touch controls"), 20.0f, TEXTALIGN_MC);
|
||||
|
||||
MainView.HSplitTop(25.0f, &Row, &MainView);
|
||||
MainView.HSplitTop(5.0f, nullptr, &MainView);
|
||||
|
||||
Row.VSplitLeft(240.0f, &Button, &Row);
|
||||
static CButtonContainer s_SaveConfigurationButton;
|
||||
if(DoButton_Menu(&s_SaveConfigurationButton, Localize("Save changes"), GameClient()->m_TouchControls.HasEditingChanges() ? 0 : 1, &Button))
|
||||
{
|
||||
if(GameClient()->m_TouchControls.SaveConfigurationToFile())
|
||||
{
|
||||
GameClient()->m_TouchControls.SetEditingChanges(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
SWarning Warning(Localize("Error saving touch controls"), Localize("Could not save touch controls to file. See local console for details."));
|
||||
Warning.m_AutoHide = false;
|
||||
Client()->AddWarning(Warning);
|
||||
}
|
||||
}
|
||||
|
||||
Row.VSplitLeft(5.0f, nullptr, &Row);
|
||||
Row.VSplitLeft(240.0f, &Button, &Row);
|
||||
if(GameClient()->m_TouchControls.HasEditingChanges())
|
||||
{
|
||||
TextRender()->TextColor(ColorRGBA(1.0f, 0.0f, 0.0f, 1.0f));
|
||||
Ui()->DoLabel(&Button, Localize("Unsaved changes"), 14.0f, TEXTALIGN_MC);
|
||||
TextRender()->TextColor(TextRender()->DefaultTextColor());
|
||||
}
|
||||
|
||||
MainView.HSplitTop(25.0f, &Row, &MainView);
|
||||
MainView.HSplitTop(5.0f, nullptr, &MainView);
|
||||
|
||||
Row.VSplitLeft(240.0f, &Button, &Row);
|
||||
static CButtonContainer s_DiscardChangesButton;
|
||||
if(DoButton_Menu(&s_DiscardChangesButton, Localize("Discard changes"), GameClient()->m_TouchControls.HasEditingChanges() ? 0 : 1, &Button))
|
||||
{
|
||||
PopupConfirm(Localize("Discard changes"),
|
||||
Localize("Are you sure that you want to discard the current changes to the touch controls?"),
|
||||
Localize("Yes"), Localize("No"),
|
||||
&CMenus::PopupConfirmDiscardTouchControlsChanged);
|
||||
}
|
||||
|
||||
Row.VSplitLeft(5.0f, nullptr, &Row);
|
||||
Row.VSplitLeft(240.0f, &Button, &Row);
|
||||
static CButtonContainer s_ResetButton;
|
||||
if(DoButton_Menu(&s_ResetButton, Localize("Reset to default"), 0, &Button))
|
||||
{
|
||||
PopupConfirm(Localize("Reset to default"),
|
||||
Localize("Are you sure that you want to reset the touch controls to default?"),
|
||||
Localize("Yes"), Localize("No"),
|
||||
&CMenus::PopupConfirmResetTouchControls);
|
||||
}
|
||||
|
||||
MainView.HSplitTop(25.0f, &Row, &MainView);
|
||||
MainView.HSplitTop(5.0f, nullptr, &MainView);
|
||||
|
||||
Row.VSplitLeft(240.0f, &Button, &Row);
|
||||
static CButtonContainer s_ClipboardImportButton;
|
||||
if(DoButton_Menu(&s_ClipboardImportButton, Localize("Import from clipboard"), 0, &Button))
|
||||
{
|
||||
PopupConfirm(Localize("Import from clipboard"),
|
||||
Localize("Are you sure that you want to import the touch controls from the clipboard? The will overwrite your current touch controls."),
|
||||
Localize("Yes"), Localize("No"),
|
||||
&CMenus::PopupConfirmImportTouchControlsClipboard);
|
||||
}
|
||||
|
||||
Row.VSplitLeft(5.0f, nullptr, &Row);
|
||||
Row.VSplitLeft(240.0f, &Button, &Row);
|
||||
static CButtonContainer s_ClipboardExportButton;
|
||||
if(DoButton_Menu(&s_ClipboardExportButton, Localize("Export to clipboard"), 0, &Button))
|
||||
{
|
||||
GameClient()->m_TouchControls.SaveConfigurationToClipboard();
|
||||
}
|
||||
|
||||
MainView.HSplitTop(25.0f, &Button, &MainView);
|
||||
MainView.HSplitTop(5.0f, nullptr, &MainView);
|
||||
static char s_DirectTouchIngameButton;
|
||||
if(DoButton_CheckBox(&s_DirectTouchIngameButton, Localize("Direct touch input while ingame"), GameClient()->m_TouchControls.IsDirectTouchIngame(), &Button))
|
||||
{
|
||||
GameClient()->m_TouchControls.SetDirectTouchIngame(!GameClient()->m_TouchControls.IsDirectTouchIngame());
|
||||
}
|
||||
|
||||
MainView.HSplitTop(25.0f, &Button, &MainView);
|
||||
MainView.HSplitTop(5.0f, nullptr, &MainView);
|
||||
static char s_DirectTouchSpectateButton;
|
||||
if(DoButton_CheckBox(&s_DirectTouchSpectateButton, Localize("Direct touch input while spectate"), GameClient()->m_TouchControls.IsDirectTouchSpectate(), &Button))
|
||||
{
|
||||
GameClient()->m_TouchControls.SetDirectTouchSpectate(!GameClient()->m_TouchControls.IsDirectTouchSpectate());
|
||||
}
|
||||
}
|
||||
|
||||
void CMenus::PopupConfirmDisconnect()
|
||||
|
@ -227,6 +367,57 @@ void CMenus::PopupConfirmDisconnectDummy()
|
|||
SetActive(false);
|
||||
}
|
||||
|
||||
void CMenus::PopupConfirmDiscardTouchControlsChanged()
|
||||
{
|
||||
if(GameClient()->m_TouchControls.LoadConfigurationFromFile(IStorage::TYPE_ALL))
|
||||
{
|
||||
GameClient()->m_TouchControls.SetEditingChanges(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
SWarning Warning(Localize("Error loading touch controls"), Localize("Could not load touch controls from file. See local console for details."));
|
||||
Warning.m_AutoHide = false;
|
||||
Client()->AddWarning(Warning);
|
||||
}
|
||||
}
|
||||
|
||||
void CMenus::PopupConfirmResetTouchControls()
|
||||
{
|
||||
bool Success = false;
|
||||
for(int StorageType = 1; StorageType < Storage()->NumPaths(); ++StorageType)
|
||||
{
|
||||
if(GameClient()->m_TouchControls.LoadConfigurationFromFile(StorageType))
|
||||
{
|
||||
Success = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(Success)
|
||||
{
|
||||
GameClient()->m_TouchControls.SetEditingChanges(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
SWarning Warning(Localize("Error loading touch controls"), Localize("Could not load default touch controls from file. See local console for details."));
|
||||
Warning.m_AutoHide = false;
|
||||
Client()->AddWarning(Warning);
|
||||
}
|
||||
}
|
||||
|
||||
void CMenus::PopupConfirmImportTouchControlsClipboard()
|
||||
{
|
||||
if(GameClient()->m_TouchControls.LoadConfigurationFromClipboard())
|
||||
{
|
||||
GameClient()->m_TouchControls.SetEditingChanges(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
SWarning Warning(Localize("Error loading touch controls"), Localize("Could not load touch controls from clipboard. See local console for details."));
|
||||
Warning.m_AutoHide = false;
|
||||
Client()->AddWarning(Warning);
|
||||
}
|
||||
}
|
||||
|
||||
void CMenus::RenderPlayers(CUIRect MainView)
|
||||
{
|
||||
CUIRect Button, Button2, ButtonBar, PlayerList, Player;
|
||||
|
@ -1281,6 +1472,9 @@ void CMenus::RenderGhost(CUIRect MainView)
|
|||
|
||||
void CMenus::RenderIngameHint()
|
||||
{
|
||||
if(g_Config.m_ClTouchControls)
|
||||
return;
|
||||
|
||||
float Width = 300 * Graphics()->ScreenAspect();
|
||||
Graphics()->MapScreen(0, 0, Width, 300);
|
||||
TextRender()->TextColor(1, 1, 1, 1);
|
||||
|
|
|
@ -633,11 +633,8 @@ void CMenus::RenderSettingsTee(CUIRect MainView)
|
|||
|
||||
// Note: get the skin info after the settings buttons, because they can trigger a refresh
|
||||
// which invalidates the skin.
|
||||
const CSkin *pSkin = m_pClient->m_Skins.Find(pSkinName);
|
||||
CTeeRenderInfo OwnSkinInfo;
|
||||
OwnSkinInfo.m_OriginalRenderSkin = pSkin->m_OriginalSkin;
|
||||
OwnSkinInfo.m_ColorableRenderSkin = pSkin->m_ColorableSkin;
|
||||
OwnSkinInfo.m_SkinMetrics = pSkin->m_Metrics;
|
||||
OwnSkinInfo.Apply(m_pClient->m_Skins.Find(pSkinName));
|
||||
OwnSkinInfo.m_CustomColoredSkin = *pUseCustomColor;
|
||||
if(*pUseCustomColor)
|
||||
{
|
||||
|
|
|
@ -844,10 +844,7 @@ void CPlayers::OnRender()
|
|||
{
|
||||
aRenderInfo[i].m_aSixup[g_Config.m_ClDummy].Reset();
|
||||
|
||||
aRenderInfo[i].m_OriginalRenderSkin = pSkin->m_OriginalSkin;
|
||||
aRenderInfo[i].m_ColorableRenderSkin = pSkin->m_ColorableSkin;
|
||||
aRenderInfo[i].m_BloodColor = pSkin->m_BloodColor;
|
||||
aRenderInfo[i].m_SkinMetrics = pSkin->m_Metrics;
|
||||
aRenderInfo[i].Apply(pSkin);
|
||||
aRenderInfo[i].m_CustomColoredSkin = IsTeamplay;
|
||||
if(!IsTeamplay)
|
||||
{
|
||||
|
@ -857,12 +854,8 @@ void CPlayers::OnRender()
|
|||
}
|
||||
}
|
||||
}
|
||||
const CSkin *pSkin = m_pClient->m_Skins.Find("x_spec");
|
||||
CTeeRenderInfo RenderInfoSpec;
|
||||
RenderInfoSpec.m_OriginalRenderSkin = pSkin->m_OriginalSkin;
|
||||
RenderInfoSpec.m_ColorableRenderSkin = pSkin->m_ColorableSkin;
|
||||
RenderInfoSpec.m_BloodColor = pSkin->m_BloodColor;
|
||||
RenderInfoSpec.m_SkinMetrics = pSkin->m_Metrics;
|
||||
RenderInfoSpec.Apply(m_pClient->m_Skins.Find("x_spec"));
|
||||
RenderInfoSpec.m_CustomColoredSkin = false;
|
||||
RenderInfoSpec.m_Size = 64.0f;
|
||||
const int LocalClientId = m_pClient->m_Snap.m_LocalClientId;
|
||||
|
|
1302
src/game/client/components/touch_controls.cpp
Normal file
1302
src/game/client/components/touch_controls.cpp
Normal file
File diff suppressed because it is too large
Load diff
424
src/game/client/components/touch_controls.h
Normal file
424
src/game/client/components/touch_controls.h
Normal file
|
@ -0,0 +1,424 @@
|
|||
#ifndef GAME_CLIENT_COMPONENTS_TOUCH_CONTROLS_H
|
||||
#define GAME_CLIENT_COMPONENTS_TOUCH_CONTROLS_H
|
||||
|
||||
#include <base/vmath.h>
|
||||
|
||||
#include <engine/input.h>
|
||||
|
||||
#include <game/client/component.h>
|
||||
#include <game/client/ui_rect.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class CJsonWriter;
|
||||
typedef struct _json_value json_value;
|
||||
|
||||
class CTouchControls : public CComponent
|
||||
{
|
||||
enum class EButtonShape
|
||||
{
|
||||
RECT,
|
||||
CIRCLE,
|
||||
NUM_SHAPES
|
||||
};
|
||||
|
||||
static constexpr const char *SHAPE_NAMES[(int)EButtonShape::NUM_SHAPES] = {"rect", "circle"};
|
||||
|
||||
enum class EButtonVisibility
|
||||
{
|
||||
INGAME,
|
||||
ZOOM_ALLOWED,
|
||||
VOTE_ACTIVE,
|
||||
DUMMY_ALLOWED,
|
||||
DUMMY_CONNECTED,
|
||||
RCON_AUTHED,
|
||||
EXTRA_MENU_1,
|
||||
EXTRA_MENU_2,
|
||||
EXTRA_MENU_3,
|
||||
EXTRA_MENU_4,
|
||||
EXTRA_MENU_5,
|
||||
NUM_VISIBILITIES
|
||||
};
|
||||
|
||||
class CButtonVisibility
|
||||
{
|
||||
public:
|
||||
EButtonVisibility m_Type;
|
||||
bool m_Parity;
|
||||
|
||||
CButtonVisibility(EButtonVisibility Type, bool Parity) :
|
||||
m_Type(Type), m_Parity(Parity) {}
|
||||
};
|
||||
|
||||
class CButtonVisibilityData
|
||||
{
|
||||
public:
|
||||
const char *m_pId;
|
||||
std::function<bool()> m_Function;
|
||||
};
|
||||
|
||||
CButtonVisibilityData m_aVisibilityFunctions[(int)EButtonVisibility::NUM_VISIBILITIES];
|
||||
|
||||
enum
|
||||
{
|
||||
ACTION_FIRE,
|
||||
ACTION_HOOK,
|
||||
NUM_ACTIONS
|
||||
};
|
||||
|
||||
class CButtonLabel
|
||||
{
|
||||
public:
|
||||
enum class EType
|
||||
{
|
||||
/**
|
||||
* Label is used as is.
|
||||
*/
|
||||
PLAIN,
|
||||
/**
|
||||
* Label is localized. Only usable for default button labels for which there must be
|
||||
* corresponding `Localizable`-calls in code and string in the translation files.
|
||||
*/
|
||||
LOCALIZED,
|
||||
/**
|
||||
* Icon font is used for the label.
|
||||
*/
|
||||
ICON,
|
||||
/**
|
||||
* Number of label types.
|
||||
*/
|
||||
NUM_TYPES
|
||||
};
|
||||
|
||||
EType m_Type;
|
||||
const char *m_pLabel;
|
||||
};
|
||||
|
||||
static constexpr const char *LABEL_TYPE_NAMES[(int)CButtonLabel::EType::NUM_TYPES] = {"plain", "localized", "icon"};
|
||||
|
||||
class CUnitRect
|
||||
{
|
||||
public:
|
||||
int m_X;
|
||||
int m_Y;
|
||||
int m_W;
|
||||
int m_H;
|
||||
};
|
||||
|
||||
class CTouchButtonBehavior;
|
||||
|
||||
class CTouchButton
|
||||
{
|
||||
public:
|
||||
CTouchButton(CTouchControls *pTouchControls);
|
||||
CTouchButton(CTouchButton &&Other) noexcept;
|
||||
CTouchButton(const CTouchButton &Other) = delete;
|
||||
|
||||
CTouchButton &operator=(const CTouchButton &Other) = delete;
|
||||
CTouchButton &operator=(CTouchButton &&Other) noexcept;
|
||||
|
||||
CTouchControls *m_pTouchControls;
|
||||
|
||||
CUnitRect m_UnitRect;
|
||||
CUIRect m_ScreenRect;
|
||||
|
||||
EButtonShape m_Shape;
|
||||
int m_BackgroundCorners; // only used with EButtonShape::RECT
|
||||
|
||||
std::vector<CButtonVisibility> m_vVisibilities;
|
||||
std::unique_ptr<CTouchButtonBehavior> m_pBehavior;
|
||||
|
||||
void UpdatePointers();
|
||||
void UpdateScreenFromUnitRect();
|
||||
void UpdateUnitFromScreenRect();
|
||||
void UpdateBackgroundCorners();
|
||||
|
||||
vec2 ClampTouchPosition(vec2 TouchPosition) const;
|
||||
bool IsInside(vec2 TouchPosition) const;
|
||||
bool IsVisible() const;
|
||||
void Render() const;
|
||||
void WriteToConfiguration(CJsonWriter *pWriter);
|
||||
};
|
||||
|
||||
class CTouchButtonBehavior
|
||||
{
|
||||
public:
|
||||
CTouchButton *m_pTouchButton;
|
||||
CTouchControls *m_pTouchControls;
|
||||
|
||||
bool m_Active; // variables below must only be used when active
|
||||
IInput::CTouchFinger m_Finger;
|
||||
vec2 m_ActivePosition;
|
||||
vec2 m_AccumulatedDelta;
|
||||
std::chrono::nanoseconds m_ActivationStartTime;
|
||||
|
||||
virtual ~CTouchButtonBehavior() = default;
|
||||
virtual void Init(CTouchButton *pTouchButton);
|
||||
|
||||
void Reset();
|
||||
void SetActive(const IInput::CTouchFingerState &FingerState);
|
||||
void SetInactive();
|
||||
bool IsActive() const;
|
||||
bool IsActive(const IInput::CTouchFinger &Finger) const;
|
||||
|
||||
virtual CButtonLabel GetLabel() const = 0;
|
||||
virtual void OnActivate() {}
|
||||
virtual void OnDeactivate() {}
|
||||
virtual void OnUpdate() {}
|
||||
virtual void WriteToConfiguration(CJsonWriter *pWriter) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract class for predefined behaviors.
|
||||
*
|
||||
* Subclasses must implemented the concrete behavior and provide the label.
|
||||
*/
|
||||
class CPredefinedTouchButtonBehavior : public CTouchButtonBehavior
|
||||
{
|
||||
const char *m_pId;
|
||||
|
||||
public:
|
||||
static constexpr const char *BEHAVIOR_TYPE = "predefined";
|
||||
|
||||
CPredefinedTouchButtonBehavior(const char *pId) :
|
||||
m_pId(pId) {}
|
||||
|
||||
/**
|
||||
* Implements the serialization for predefined behaviors. Subclasses
|
||||
* may override this, but they should call the parent function first.
|
||||
*/
|
||||
void WriteToConfiguration(CJsonWriter *pWriter) override;
|
||||
};
|
||||
|
||||
class CIngameMenuTouchButtonBehavior : public CPredefinedTouchButtonBehavior
|
||||
{
|
||||
public:
|
||||
static constexpr const char *BEHAVIOR_ID = "ingame-menu";
|
||||
|
||||
CIngameMenuTouchButtonBehavior() :
|
||||
CPredefinedTouchButtonBehavior(BEHAVIOR_ID) {}
|
||||
|
||||
CButtonLabel GetLabel() const override;
|
||||
void OnDeactivate() override;
|
||||
};
|
||||
|
||||
class CExtraMenuTouchButtonBehavior : public CPredefinedTouchButtonBehavior
|
||||
{
|
||||
int m_Number;
|
||||
char m_aLabel[16];
|
||||
|
||||
public:
|
||||
static constexpr const char *BEHAVIOR_ID = "extra-menu";
|
||||
|
||||
CExtraMenuTouchButtonBehavior(int Number);
|
||||
|
||||
CButtonLabel GetLabel() const override;
|
||||
void OnDeactivate() override;
|
||||
void WriteToConfiguration(CJsonWriter *pWriter) override;
|
||||
static std::unique_ptr<CExtraMenuTouchButtonBehavior> Parse(const json_value *pBehaviorObject);
|
||||
};
|
||||
|
||||
class CEmoticonTouchButtonBehavior : public CPredefinedTouchButtonBehavior
|
||||
{
|
||||
public:
|
||||
static constexpr const char *BEHAVIOR_ID = "emoticon";
|
||||
|
||||
CEmoticonTouchButtonBehavior() :
|
||||
CPredefinedTouchButtonBehavior(BEHAVIOR_ID) {}
|
||||
|
||||
CButtonLabel GetLabel() const override;
|
||||
void OnDeactivate() override;
|
||||
};
|
||||
|
||||
class CSpectateTouchButtonBehavior : public CPredefinedTouchButtonBehavior
|
||||
{
|
||||
public:
|
||||
static constexpr const char *BEHAVIOR_ID = "spectate";
|
||||
|
||||
CSpectateTouchButtonBehavior() :
|
||||
CPredefinedTouchButtonBehavior(BEHAVIOR_ID) {}
|
||||
|
||||
CButtonLabel GetLabel() const override;
|
||||
void OnDeactivate() override;
|
||||
};
|
||||
|
||||
class CSwapActionTouchButtonBehavior : public CPredefinedTouchButtonBehavior
|
||||
{
|
||||
int m_ActiveAction = NUM_ACTIONS;
|
||||
|
||||
public:
|
||||
static constexpr const char *BEHAVIOR_ID = "swap-action";
|
||||
|
||||
CSwapActionTouchButtonBehavior() :
|
||||
CPredefinedTouchButtonBehavior(BEHAVIOR_ID) {}
|
||||
|
||||
CButtonLabel GetLabel() const override;
|
||||
void OnActivate() override;
|
||||
void OnDeactivate() override;
|
||||
};
|
||||
|
||||
class CUseActionTouchButtonBehavior : public CPredefinedTouchButtonBehavior
|
||||
{
|
||||
int m_ActiveAction = NUM_ACTIONS;
|
||||
|
||||
public:
|
||||
static constexpr const char *BEHAVIOR_ID = "use-action";
|
||||
|
||||
CUseActionTouchButtonBehavior() :
|
||||
CPredefinedTouchButtonBehavior(BEHAVIOR_ID) {}
|
||||
|
||||
CButtonLabel GetLabel() const override;
|
||||
void OnActivate() override;
|
||||
void OnDeactivate() override;
|
||||
};
|
||||
|
||||
class CJoystickTouchButtonBehavior : public CPredefinedTouchButtonBehavior
|
||||
{
|
||||
int m_ActiveAction = NUM_ACTIONS;
|
||||
|
||||
public:
|
||||
CJoystickTouchButtonBehavior(const char *pId) :
|
||||
CPredefinedTouchButtonBehavior(pId) {}
|
||||
|
||||
CButtonLabel GetLabel() const override;
|
||||
void OnActivate() override;
|
||||
void OnDeactivate() override;
|
||||
void OnUpdate() override;
|
||||
int ActiveAction() const { return m_ActiveAction; }
|
||||
virtual int SelectedAction() const = 0;
|
||||
};
|
||||
|
||||
class CJoystickActionTouchButtonBehavior : public CJoystickTouchButtonBehavior
|
||||
{
|
||||
public:
|
||||
static constexpr const char *BEHAVIOR_ID = "joystick-action";
|
||||
|
||||
CJoystickActionTouchButtonBehavior() :
|
||||
CJoystickTouchButtonBehavior(BEHAVIOR_ID) {}
|
||||
~CJoystickActionTouchButtonBehavior();
|
||||
|
||||
void Init(CTouchButton *pTouchButton) override;
|
||||
int SelectedAction() const override;
|
||||
};
|
||||
|
||||
class CJoystickFireTouchButtonBehavior : public CJoystickTouchButtonBehavior
|
||||
{
|
||||
public:
|
||||
static constexpr const char *BEHAVIOR_ID = "joystick-fire";
|
||||
|
||||
CJoystickFireTouchButtonBehavior() :
|
||||
CJoystickTouchButtonBehavior(BEHAVIOR_ID) {}
|
||||
|
||||
int SelectedAction() const override;
|
||||
};
|
||||
|
||||
class CJoystickHookTouchButtonBehavior : public CJoystickTouchButtonBehavior
|
||||
{
|
||||
public:
|
||||
static constexpr const char *BEHAVIOR_ID = "joystick-hook";
|
||||
|
||||
CJoystickHookTouchButtonBehavior() :
|
||||
CJoystickTouchButtonBehavior(BEHAVIOR_ID) {}
|
||||
|
||||
int SelectedAction() const override;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generic behavior implementation that executes a console command like a bind.
|
||||
*/
|
||||
class CBindTouchButtonBehavior : public CTouchButtonBehavior
|
||||
{
|
||||
std::string m_Label;
|
||||
CButtonLabel::EType m_LabelType;
|
||||
std::string m_Command;
|
||||
|
||||
bool m_Repeating = false;
|
||||
std::chrono::nanoseconds m_LastUpdateTime;
|
||||
std::chrono::nanoseconds m_AccumulatedRepeatingTime;
|
||||
|
||||
public:
|
||||
static constexpr const char *BEHAVIOR_TYPE = "bind";
|
||||
|
||||
CBindTouchButtonBehavior(const char *pLabel, CButtonLabel::EType LabelType, const char *pCommand) :
|
||||
m_Label(pLabel),
|
||||
m_LabelType(LabelType),
|
||||
m_Command(pCommand) {}
|
||||
|
||||
CButtonLabel GetLabel() const override;
|
||||
void OnActivate() override;
|
||||
void OnDeactivate() override;
|
||||
void OnUpdate() override;
|
||||
void WriteToConfiguration(CJsonWriter *pWriter) override;
|
||||
};
|
||||
|
||||
bool m_DirectTouchIngame = true;
|
||||
bool m_DirectTouchSpectate = true;
|
||||
|
||||
std::vector<CTouchButton> m_vTouchButtons;
|
||||
|
||||
bool m_aExtraMenuActive[(int)EButtonVisibility::EXTRA_MENU_5 - (int)EButtonVisibility::EXTRA_MENU_1 + 1] = {false};
|
||||
|
||||
class CActionState
|
||||
{
|
||||
public:
|
||||
bool m_Active = false;
|
||||
IInput::CTouchFinger m_Finger;
|
||||
};
|
||||
|
||||
int m_ActionSelected = ACTION_FIRE;
|
||||
int m_ActionLastActivated = ACTION_FIRE;
|
||||
CActionState m_aActionStates[NUM_ACTIONS];
|
||||
CJoystickActionTouchButtonBehavior *m_pPrimaryJoystickTouchButtonBehavior;
|
||||
|
||||
bool m_EditingActive = false;
|
||||
bool m_EditingChanges = false;
|
||||
|
||||
void InitVisibilityFunctions();
|
||||
void UpdateButtons(const std::vector<IInput::CTouchFingerState> &vTouchFingerStates);
|
||||
void RenderButtons();
|
||||
vec2 CalculateScreenSize() const;
|
||||
|
||||
std::unique_ptr<CPredefinedTouchButtonBehavior> ParsePredefinedBehavior(const json_value *pBehaviorObject);
|
||||
std::unique_ptr<CBindTouchButtonBehavior> ParseBindBehavior(const json_value *pBehaviorObject);
|
||||
std::unique_ptr<CTouchButtonBehavior> ParseBehavior(const json_value *pBehaviorObject);
|
||||
std::optional<CTouchButton> ParseButton(const json_value *pButtonObject);
|
||||
bool ParseConfiguration(const void *pFileData, unsigned FileLength);
|
||||
void WriteConfiguration(CJsonWriter *pWriter);
|
||||
|
||||
public:
|
||||
int Sizeof() const override { return sizeof(*this); }
|
||||
void OnInit() override;
|
||||
void OnReset() override;
|
||||
void OnWindowResize() override;
|
||||
bool OnTouchState(const std::vector<IInput::CTouchFingerState> &vTouchFingerStates) override;
|
||||
void OnRender() override;
|
||||
|
||||
bool LoadConfigurationFromFile(int StorageType);
|
||||
bool LoadConfigurationFromClipboard();
|
||||
bool SaveConfigurationToFile();
|
||||
void SaveConfigurationToClipboard();
|
||||
|
||||
bool IsDirectTouchIngame() const { return m_DirectTouchIngame; }
|
||||
void SetDirectTouchIngame(bool DirectTouchIngame)
|
||||
{
|
||||
m_DirectTouchIngame = DirectTouchIngame;
|
||||
m_EditingChanges = true;
|
||||
}
|
||||
bool IsDirectTouchSpectate() const { return m_DirectTouchSpectate; }
|
||||
void SetDirectTouchSpectate(bool DirectTouchSpectate)
|
||||
{
|
||||
m_DirectTouchSpectate = DirectTouchSpectate;
|
||||
m_EditingChanges = true;
|
||||
}
|
||||
bool IsEditingActive() const { return m_EditingActive; }
|
||||
void SetEditingActive(bool EditingActive) { m_EditingActive = EditingActive; }
|
||||
bool HasEditingChanges() const { return m_EditingChanges; }
|
||||
void SetEditingChanges(bool EditingChanges) { m_EditingChanges = EditingChanges; }
|
||||
};
|
||||
|
||||
#endif
|
|
@ -145,6 +145,7 @@ void CGameClient::OnConsoleInit()
|
|||
&m_Chat,
|
||||
&m_Broadcast,
|
||||
&m_DebugHud,
|
||||
&m_TouchControls,
|
||||
&m_Scoreboard,
|
||||
&m_Statboard,
|
||||
&m_Motd,
|
||||
|
@ -164,6 +165,7 @@ void CGameClient::OnConsoleInit()
|
|||
&m_Emoticon,
|
||||
&m_Menus,
|
||||
&m_Controls,
|
||||
&m_TouchControls,
|
||||
&m_Binds});
|
||||
|
||||
// add basic console commands
|
||||
|
@ -443,6 +445,23 @@ void CGameClient::OnUpdate()
|
|||
}
|
||||
}
|
||||
|
||||
// handle touch events
|
||||
const std::vector<IInput::CTouchFingerState> &vTouchFingerStates = Input()->TouchFingerStates();
|
||||
bool TouchHandled = false;
|
||||
for(auto &pComponent : m_vpInput)
|
||||
{
|
||||
if(TouchHandled)
|
||||
{
|
||||
// Also update inactive components so they can handle touch fingers being released.
|
||||
pComponent->OnTouchState({});
|
||||
}
|
||||
else if(pComponent->OnTouchState(vTouchFingerStates))
|
||||
{
|
||||
Input()->ClearTouchDeltas();
|
||||
TouchHandled = true;
|
||||
}
|
||||
}
|
||||
|
||||
// handle key presses
|
||||
Input()->ConsumeEvents([&](const IInput::CEvent &Event) {
|
||||
for(auto &pComponent : m_vpInput)
|
||||
|
@ -1554,11 +1573,7 @@ void CGameClient::OnNewSnapshot()
|
|||
pClient->m_SkinInfo.m_Size = 64;
|
||||
|
||||
// find new skin
|
||||
const CSkin *pSkin = m_Skins.Find(pClient->m_aSkinName);
|
||||
pClient->m_SkinInfo.m_OriginalRenderSkin = pSkin->m_OriginalSkin;
|
||||
pClient->m_SkinInfo.m_ColorableRenderSkin = pSkin->m_ColorableSkin;
|
||||
pClient->m_SkinInfo.m_SkinMetrics = pSkin->m_Metrics;
|
||||
pClient->m_SkinInfo.m_BloodColor = pSkin->m_BloodColor;
|
||||
pClient->m_SkinInfo.Apply(m_Skins.Find(pClient->m_aSkinName));
|
||||
pClient->m_SkinInfo.m_CustomColoredSkin = pClient->m_UseCustomColor;
|
||||
|
||||
if(!pClient->m_UseCustomColor)
|
||||
|
@ -3750,13 +3765,9 @@ void CGameClient::RefreshSkins()
|
|||
|
||||
for(auto &Client : m_aClients)
|
||||
{
|
||||
Client.m_SkinInfo.m_OriginalRenderSkin.Reset();
|
||||
Client.m_SkinInfo.m_ColorableRenderSkin.Reset();
|
||||
if(Client.m_aSkinName[0] != '\0')
|
||||
{
|
||||
const CSkin *pSkin = m_Skins.Find(Client.m_aSkinName);
|
||||
Client.m_SkinInfo.m_OriginalRenderSkin = pSkin->m_OriginalSkin;
|
||||
Client.m_SkinInfo.m_ColorableRenderSkin = pSkin->m_ColorableSkin;
|
||||
Client.m_SkinInfo.Apply(m_Skins.Find(Client.m_aSkinName));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
#include "components/spectator.h"
|
||||
#include "components/statboard.h"
|
||||
#include "components/tooltips.h"
|
||||
#include "components/touch_controls.h"
|
||||
#include "components/voting.h"
|
||||
|
||||
class CGameInfo
|
||||
|
@ -146,6 +147,7 @@ public:
|
|||
CSounds m_Sounds;
|
||||
CEmoticon m_Emoticon;
|
||||
CDamageInd m_DamageInd;
|
||||
CTouchControls m_TouchControls;
|
||||
CVoting m_Voting;
|
||||
CSpectator m_Spectator;
|
||||
|
||||
|
|
|
@ -56,6 +56,14 @@ public:
|
|||
Sixup.Reset();
|
||||
}
|
||||
|
||||
void Apply(const CSkin *pSkin)
|
||||
{
|
||||
m_OriginalRenderSkin = pSkin->m_OriginalSkin;
|
||||
m_ColorableRenderSkin = pSkin->m_ColorableSkin;
|
||||
m_BloodColor = pSkin->m_BloodColor;
|
||||
m_SkinMetrics = pSkin->m_Metrics;
|
||||
}
|
||||
|
||||
CSkin::SSkinTextures m_OriginalRenderSkin;
|
||||
CSkin::SSkinTextures m_ColorableRenderSkin;
|
||||
|
||||
|
|
|
@ -3526,7 +3526,7 @@ void CGameContext::ConAddMapVotes(IConsole::IResult *pResult, void *pUserData)
|
|||
str_format(aCommand, sizeof(aCommand), "clear_votes; add_map_votes \"%s\"", aDirectory);
|
||||
}
|
||||
else
|
||||
str_format(aCommand, sizeof(aCommand), "change_map \"%s/%s\"", pDirectory, aOptionEscaped);
|
||||
str_format(aCommand, sizeof(aCommand), "change_map \"%s%s%s\"", pDirectory, pDirectory[0] == '\0' ? "" : "/", aOptionEscaped);
|
||||
|
||||
pSelf->AddVote(aDescription, aCommand);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue