mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-11 10:38:20 +00:00
1313 lines
34 KiB
C++
1313 lines
34 KiB
C++
// copyright (c) 2007 magnus auvinen, see licence.txt for more info
|
|
#include <math.h>
|
|
|
|
#include <base/system.h>
|
|
#include <base/math.h>
|
|
#include <base/vmath.h>
|
|
|
|
#include "menus.h"
|
|
#include "skins.h"
|
|
|
|
#include <engine/graphics.h>
|
|
#include <engine/textrender.h>
|
|
#include <engine/serverbrowser.h>
|
|
#include <engine/keys.h>
|
|
#include <engine/storage.h>
|
|
#include <engine/shared/config.h>
|
|
|
|
#include <game/version.h>
|
|
#include <game/generated/protocol.h>
|
|
|
|
#include <game/generated/client_data.h>
|
|
#include <game/client/gameclient.h>
|
|
#include <game/client/lineinput.h>
|
|
#include <game/localization.h>
|
|
#include <mastersrv/mastersrv.h>
|
|
|
|
vec4 CMenus::ms_GuiColor;
|
|
vec4 CMenus::ms_ColorTabbarInactiveOutgame;
|
|
vec4 CMenus::ms_ColorTabbarActiveOutgame;
|
|
vec4 CMenus::ms_ColorTabbarInactive;
|
|
vec4 CMenus::ms_ColorTabbarActive;
|
|
vec4 CMenus::ms_ColorTabbarInactiveIngame;
|
|
vec4 CMenus::ms_ColorTabbarActiveIngame;
|
|
|
|
|
|
float CMenus::ms_ButtonHeight = 25.0f;
|
|
float CMenus::ms_ListheaderHeight = 17.0f;
|
|
float CMenus::ms_FontmodHeight = 0.8f;
|
|
|
|
IInput::CEvent CMenus::m_aInputEvents[MAX_INPUTEVENTS];
|
|
int CMenus::m_NumInputEvents;
|
|
|
|
inline float HueToRgb(float v1, float v2, float h)
|
|
{
|
|
if(h < 0) h += 1;
|
|
if(h > 1) h -= 1;
|
|
if((6 * h) < 1) return v1 + ( v2 - v1 ) * 6 * h;
|
|
if((2 * h) < 1) return v2;
|
|
if((3 * h) < 2) return v1 + ( v2 - v1 ) * ((2.0f/3.0f) - h) * 6;
|
|
return v1;
|
|
}
|
|
|
|
inline vec3 HslToRgb(vec3 In)
|
|
{
|
|
float v1, v2;
|
|
vec3 Out;
|
|
|
|
if(In.s == 0)
|
|
{
|
|
Out.r = In.l;
|
|
Out.g = In.l;
|
|
Out.b = In.l;
|
|
}
|
|
else
|
|
{
|
|
if(In.l < 0.5f)
|
|
v2 = In.l * (1 + In.s);
|
|
else
|
|
v2 = (In.l+In.s) - (In.s*In.l);
|
|
|
|
v1 = 2 * In.l - v2;
|
|
|
|
Out.r = HueToRgb(v1, v2, In.h + (1.0f/3.0f));
|
|
Out.g = HueToRgb(v1, v2, In.h);
|
|
Out.b = HueToRgb(v1, v2, In.h - (1.0f/3.0f));
|
|
}
|
|
|
|
return Out;
|
|
}
|
|
|
|
|
|
CMenus::CMenus()
|
|
{
|
|
m_Popup = POPUP_NONE;
|
|
m_ActivePage = PAGE_INTERNET;
|
|
m_GamePage = PAGE_GAME;
|
|
|
|
m_NeedRestart = false;
|
|
m_NeedSendinfo = false;
|
|
m_MenuActive = true;
|
|
m_UseMouseButtons = true;
|
|
m_DemolistDelEntry = false;
|
|
|
|
m_EscapePressed = false;
|
|
m_EnterPressed = false;
|
|
m_DeletePressed = false;
|
|
m_NumInputEvents = 0;
|
|
|
|
m_LastInput = time_get();
|
|
|
|
str_copy(m_aCurrentDemoFolder, "demos", sizeof(m_aCurrentDemoFolder));
|
|
}
|
|
|
|
vec4 CMenus::ButtonColorMul(const void *pID)
|
|
{
|
|
if(UI()->ActiveItem() == pID)
|
|
return vec4(1,1,1,0.5f);
|
|
else if(UI()->HotItem() == pID)
|
|
return vec4(1,1,1,1.5f);
|
|
return vec4(1,1,1,1);
|
|
}
|
|
|
|
int CMenus::DoButton_BrowseIcon(int What, const CUIRect *pRect)
|
|
{
|
|
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_BROWSEICONS].m_Id);
|
|
|
|
Graphics()->QuadsBegin();
|
|
RenderTools()->SelectSprite(What);
|
|
IGraphics::CQuadItem QuadItem(pRect->x, pRect->y, pRect->w, pRect->h);
|
|
Graphics()->QuadsDrawTL(&QuadItem, 1);
|
|
Graphics()->QuadsEnd();
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int CMenus::DoButton_Menu(const void *pID, const char *pText, int Checked, const CUIRect *pRect)
|
|
{
|
|
RenderTools()->DrawUIRect(pRect, vec4(1,1,1,0.5f)*ButtonColorMul(pID), CUI::CORNER_ALL, 5.0f);
|
|
UI()->DoLabel(pRect, pText, pRect->h*ms_FontmodHeight, 0);
|
|
return UI()->DoButtonLogic(pID, pText, Checked, pRect);
|
|
}
|
|
|
|
void CMenus::DoButton_KeySelect(const void *pID, const char *pText, int Checked, const CUIRect *pRect)
|
|
{
|
|
RenderTools()->DrawUIRect(pRect, vec4(1,1,1,0.5f)*ButtonColorMul(pID), CUI::CORNER_ALL, 5.0f);
|
|
UI()->DoLabel(pRect, pText, pRect->h*ms_FontmodHeight, 0);
|
|
}
|
|
|
|
int CMenus::DoButton_MenuTab(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Corners)
|
|
{
|
|
vec4 ColorMod(1,1,1,1);
|
|
|
|
if(Checked)
|
|
RenderTools()->DrawUIRect(pRect, ms_ColorTabbarActive, Corners, 10.0f);
|
|
else
|
|
RenderTools()->DrawUIRect(pRect, ms_ColorTabbarInactive, Corners, 10.0f);
|
|
UI()->DoLabel(pRect, pText, pRect->h*ms_FontmodHeight, 0);
|
|
|
|
return UI()->DoButtonLogic(pID, pText, Checked, pRect);
|
|
}
|
|
|
|
|
|
int CMenus::DoButton_SettingsTab(const void *pID, const char *pText, int Checked, const CUIRect *pRect)
|
|
{
|
|
if(Checked)
|
|
RenderTools()->DrawUIRect(pRect, ms_ColorTabbarActive, CUI::CORNER_R, 10.0f);
|
|
else
|
|
RenderTools()->DrawUIRect(pRect, ms_ColorTabbarInactive, CUI::CORNER_R, 10.0f);
|
|
UI()->DoLabel(pRect, pText, pRect->h*ms_FontmodHeight, 0);
|
|
return UI()->DoButtonLogic(pID, pText, Checked, pRect);
|
|
}
|
|
|
|
int CMenus::DoButton_GridHeader(const void *pID, const char *pText, int Checked, const CUIRect *pRect)
|
|
//void CMenus::ui_draw_grid_header(const void *id, const char *text, int checked, const CUIRect *r, const void *extra)
|
|
{
|
|
if(Checked)
|
|
RenderTools()->DrawUIRect(pRect, vec4(1,1,1,0.5f), CUI::CORNER_T, 5.0f);
|
|
CUIRect t;
|
|
pRect->VSplitLeft(5.0f, 0, &t);
|
|
UI()->DoLabel(&t, pText, pRect->h*ms_FontmodHeight, -1);
|
|
return UI()->DoButtonLogic(pID, pText, Checked, pRect);
|
|
}
|
|
|
|
int CMenus::DoButton_ListRow(const void *pID, const char *pText, int Checked, const CUIRect *pRect)
|
|
{
|
|
if(Checked)
|
|
{
|
|
CUIRect sr = *pRect;
|
|
sr.Margin(1.5f, &sr);
|
|
RenderTools()->DrawUIRect(&sr, vec4(1,1,1,0.5f), CUI::CORNER_ALL, 4.0f);
|
|
}
|
|
UI()->DoLabel(pRect, pText, pRect->h*ms_FontmodHeight, -1);
|
|
return UI()->DoButtonLogic(pID, pText, Checked, pRect);
|
|
}
|
|
|
|
int CMenus::DoButton_CheckBox_Common(const void *pID, const char *pText, const char *pBoxText, const CUIRect *pRect)
|
|
//void CMenus::ui_draw_checkbox_common(const void *id, const char *text, const char *boxtext, const CUIRect *r, const void *extra)
|
|
{
|
|
CUIRect c = *pRect;
|
|
CUIRect t = *pRect;
|
|
c.w = c.h;
|
|
t.x += c.w;
|
|
t.w -= c.w;
|
|
t.VSplitLeft(5.0f, 0, &t);
|
|
|
|
c.Margin(2.0f, &c);
|
|
RenderTools()->DrawUIRect(&c, vec4(1,1,1,0.25f)*ButtonColorMul(pID), CUI::CORNER_ALL, 3.0f);
|
|
c.y += 2;
|
|
UI()->DoLabel(&c, pBoxText, pRect->h*ms_FontmodHeight*0.6f, 0);
|
|
UI()->DoLabel(&t, pText, pRect->h*ms_FontmodHeight*0.8f, -1);
|
|
return UI()->DoButtonLogic(pID, pText, 0, pRect);
|
|
}
|
|
|
|
int CMenus::DoButton_CheckBox(const void *pID, const char *pText, int Checked, const CUIRect *pRect)
|
|
{
|
|
return DoButton_CheckBox_Common(pID, pText, Checked?"X":"", pRect);
|
|
}
|
|
|
|
|
|
int CMenus::DoButton_CheckBox_Number(const void *pID, const char *pText, int Checked, const CUIRect *pRect)
|
|
{
|
|
char aBuf[16];
|
|
str_format(aBuf, sizeof(aBuf), "%d", Checked);
|
|
return DoButton_CheckBox_Common(pID, pText, aBuf, pRect);
|
|
}
|
|
|
|
int CMenus::DoEditBox(void *pID, const CUIRect *pRect, char *pStr, unsigned StrSize, float FontSize, float *Offset, bool Hidden, int Corners)
|
|
{
|
|
int Inside = UI()->MouseInside(pRect);
|
|
bool ReturnValue = false;
|
|
static int s_AtIndex = 0;
|
|
|
|
if(UI()->LastActiveItem() == pID)
|
|
{
|
|
int Len = str_length(pStr);
|
|
if(Len == 0)
|
|
s_AtIndex = 0;
|
|
|
|
if(Inside && UI()->MouseButton(0))
|
|
{
|
|
int MxRel = (int)(UI()->MouseX() - pRect->x);
|
|
|
|
for(int i = 1; i <= Len; i++)
|
|
{
|
|
if(TextRender()->TextWidth(0, FontSize, pStr, i) - *Offset + 10 > MxRel)
|
|
{
|
|
s_AtIndex = i - 1;
|
|
break;
|
|
}
|
|
|
|
if(i == Len)
|
|
s_AtIndex = Len;
|
|
}
|
|
}
|
|
|
|
for(int i = 0; i < m_NumInputEvents; i++)
|
|
{
|
|
Len = str_length(pStr);
|
|
ReturnValue |= CLineInput::Manipulate(m_aInputEvents[i], pStr, StrSize, &Len, &s_AtIndex);
|
|
}
|
|
}
|
|
|
|
bool JustGotActive = false;
|
|
|
|
if(UI()->ActiveItem() == pID)
|
|
{
|
|
if(!UI()->MouseButton(0))
|
|
UI()->SetActiveItem(0);
|
|
}
|
|
else if(UI()->HotItem() == pID)
|
|
{
|
|
if(UI()->MouseButton(0))
|
|
{
|
|
if (UI()->LastActiveItem() != pID)
|
|
JustGotActive = true;
|
|
UI()->SetActiveItem(pID);
|
|
}
|
|
}
|
|
|
|
if(Inside)
|
|
UI()->SetHotItem(pID);
|
|
|
|
CUIRect Textbox = *pRect;
|
|
RenderTools()->DrawUIRect(&Textbox, vec4(1, 1, 1, 0.5f), Corners, 3.0f);
|
|
Textbox.VMargin(2.0f, &Textbox);
|
|
Textbox.HMargin(2.0f, &Textbox);
|
|
|
|
const char *pDisplayStr = pStr;
|
|
char aStars[128];
|
|
|
|
if(Hidden)
|
|
{
|
|
unsigned s = str_length(pStr);
|
|
if(s >= sizeof(aStars))
|
|
s = sizeof(aStars)-1;
|
|
for(unsigned int i = 0; i < s; ++i)
|
|
aStars[i] = '*';
|
|
aStars[s] = 0;
|
|
pDisplayStr = aStars;
|
|
}
|
|
|
|
// check if the text has to be moved
|
|
if(UI()->LastActiveItem() == pID && !JustGotActive && m_NumInputEvents)
|
|
{
|
|
float w = TextRender()->TextWidth(0, FontSize, pDisplayStr, s_AtIndex)*UI()->Scale();
|
|
if(w-*Offset > Textbox.w)
|
|
{
|
|
// move to the left
|
|
float wt = TextRender()->TextWidth(0, FontSize, pDisplayStr, -1)*UI()->Scale();
|
|
do
|
|
{
|
|
*Offset += min(wt-*Offset-Textbox.w, Textbox.w/3);
|
|
}
|
|
while(w-*Offset > Textbox.w);
|
|
}
|
|
else if(w-*Offset < 0.0f)
|
|
{
|
|
// move to the right
|
|
do
|
|
{
|
|
*Offset = max(0.0f, *Offset-Textbox.w/3);
|
|
}
|
|
while(w-*Offset < 0.0f);
|
|
}
|
|
}
|
|
UI()->ClipEnable(pRect);
|
|
Textbox.x -= *Offset*UI()->Scale();
|
|
|
|
UI()->DoLabel(&Textbox, pDisplayStr, FontSize, -1);
|
|
|
|
// render the cursor
|
|
if(UI()->LastActiveItem() == pID && !JustGotActive)
|
|
{
|
|
float w = TextRender()->TextWidth(0, FontSize, pDisplayStr, s_AtIndex);
|
|
Textbox = *pRect;
|
|
Textbox.VSplitLeft(2.0f, 0, &Textbox);
|
|
Textbox.x += (w-*Offset-TextRender()->TextWidth(0, FontSize, "|", -1)/2)*UI()->Scale();
|
|
|
|
if((2*time_get()/time_freq()) % 2) // make it blink
|
|
UI()->DoLabel(&Textbox, "|", FontSize, -1);
|
|
}
|
|
UI()->ClipDisable();
|
|
|
|
return ReturnValue;
|
|
}
|
|
|
|
float CMenus::DoScrollbarV(const void *pID, const CUIRect *pRect, float Current)
|
|
{
|
|
CUIRect Handle;
|
|
static float OffsetY;
|
|
pRect->HSplitTop(33, &Handle, 0);
|
|
|
|
Handle.y += (pRect->h-Handle.h)*Current;
|
|
|
|
// logic
|
|
float ReturnValue = Current;
|
|
int Inside = UI()->MouseInside(&Handle);
|
|
|
|
if(UI()->ActiveItem() == pID)
|
|
{
|
|
if(!UI()->MouseButton(0))
|
|
UI()->SetActiveItem(0);
|
|
|
|
float Min = pRect->y;
|
|
float Max = pRect->h-Handle.h;
|
|
float Cur = UI()->MouseY()-OffsetY;
|
|
ReturnValue = (Cur-Min)/Max;
|
|
if(ReturnValue < 0.0f) ReturnValue = 0.0f;
|
|
if(ReturnValue > 1.0f) ReturnValue = 1.0f;
|
|
}
|
|
else if(UI()->HotItem() == pID)
|
|
{
|
|
if(UI()->MouseButton(0))
|
|
{
|
|
UI()->SetActiveItem(pID);
|
|
OffsetY = UI()->MouseY()-Handle.y;
|
|
}
|
|
}
|
|
|
|
if(Inside)
|
|
UI()->SetHotItem(pID);
|
|
|
|
// render
|
|
CUIRect Rail;
|
|
pRect->VMargin(5.0f, &Rail);
|
|
RenderTools()->DrawUIRect(&Rail, vec4(1,1,1,0.25f), 0, 0.0f);
|
|
|
|
CUIRect Slider = Handle;
|
|
Slider.w = Rail.x-Slider.x;
|
|
RenderTools()->DrawUIRect(&Slider, vec4(1,1,1,0.25f), CUI::CORNER_L, 2.5f);
|
|
Slider.x = Rail.x+Rail.w;
|
|
RenderTools()->DrawUIRect(&Slider, vec4(1,1,1,0.25f), CUI::CORNER_R, 2.5f);
|
|
|
|
Slider = Handle;
|
|
Slider.Margin(5.0f, &Slider);
|
|
RenderTools()->DrawUIRect(&Slider, vec4(1,1,1,0.25f)*ButtonColorMul(pID), CUI::CORNER_ALL, 2.5f);
|
|
|
|
return ReturnValue;
|
|
}
|
|
|
|
|
|
|
|
float CMenus::DoScrollbarH(const void *pID, const CUIRect *pRect, float Current)
|
|
{
|
|
CUIRect Handle;
|
|
static float OffsetX;
|
|
pRect->VSplitLeft(33, &Handle, 0);
|
|
|
|
Handle.x += (pRect->w-Handle.w)*Current;
|
|
|
|
// logic
|
|
float ReturnValue = Current;
|
|
int Inside = UI()->MouseInside(&Handle);
|
|
|
|
if(UI()->ActiveItem() == pID)
|
|
{
|
|
if(!UI()->MouseButton(0))
|
|
UI()->SetActiveItem(0);
|
|
|
|
float Min = pRect->x;
|
|
float Max = pRect->w-Handle.w;
|
|
float Cur = UI()->MouseX()-OffsetX;
|
|
ReturnValue = (Cur-Min)/Max;
|
|
if(ReturnValue < 0.0f) ReturnValue = 0.0f;
|
|
if(ReturnValue > 1.0f) ReturnValue = 1.0f;
|
|
}
|
|
else if(UI()->HotItem() == pID)
|
|
{
|
|
if(UI()->MouseButton(0))
|
|
{
|
|
UI()->SetActiveItem(pID);
|
|
OffsetX = UI()->MouseX()-Handle.x;
|
|
}
|
|
}
|
|
|
|
if(Inside)
|
|
UI()->SetHotItem(pID);
|
|
|
|
// render
|
|
CUIRect Rail;
|
|
pRect->HMargin(5.0f, &Rail);
|
|
RenderTools()->DrawUIRect(&Rail, vec4(1,1,1,0.25f), 0, 0.0f);
|
|
|
|
CUIRect Slider = Handle;
|
|
Slider.h = Rail.y-Slider.y;
|
|
RenderTools()->DrawUIRect(&Slider, vec4(1,1,1,0.25f), CUI::CORNER_T, 2.5f);
|
|
Slider.y = Rail.y+Rail.h;
|
|
RenderTools()->DrawUIRect(&Slider, vec4(1,1,1,0.25f), CUI::CORNER_B, 2.5f);
|
|
|
|
Slider = Handle;
|
|
Slider.Margin(5.0f, &Slider);
|
|
RenderTools()->DrawUIRect(&Slider, vec4(1,1,1,0.25f)*ButtonColorMul(pID), CUI::CORNER_ALL, 2.5f);
|
|
|
|
return ReturnValue;
|
|
}
|
|
|
|
int CMenus::DoKeyReader(void *pID, const CUIRect *pRect, int Key)
|
|
{
|
|
// process
|
|
static void *pGrabbedID = 0;
|
|
static bool MouseReleased = true;
|
|
static int ButtonUsed = 0;
|
|
int Inside = UI()->MouseInside(pRect);
|
|
int NewKey = Key;
|
|
|
|
if(!UI()->MouseButton(0) && !UI()->MouseButton(1) && pGrabbedID == pID)
|
|
MouseReleased = true;
|
|
|
|
if(UI()->ActiveItem() == pID)
|
|
{
|
|
if(m_Binder.m_GotKey)
|
|
{
|
|
// abort with escape key
|
|
if(m_Binder.m_Key.m_Key != KEY_ESCAPE)
|
|
NewKey = m_Binder.m_Key.m_Key;
|
|
m_Binder.m_GotKey = false;
|
|
UI()->SetActiveItem(0);
|
|
MouseReleased = false;
|
|
pGrabbedID = pID;
|
|
}
|
|
|
|
if(ButtonUsed == 1 && !UI()->MouseButton(1))
|
|
{
|
|
if(Inside)
|
|
NewKey = 0;
|
|
UI()->SetActiveItem(0);
|
|
}
|
|
}
|
|
else if(UI()->HotItem() == pID)
|
|
{
|
|
if(MouseReleased)
|
|
{
|
|
if(UI()->MouseButton(0))
|
|
{
|
|
m_Binder.m_TakeKey = true;
|
|
m_Binder.m_GotKey = false;
|
|
UI()->SetActiveItem(pID);
|
|
ButtonUsed = 0;
|
|
}
|
|
|
|
if(UI()->MouseButton(1))
|
|
{
|
|
UI()->SetActiveItem(pID);
|
|
ButtonUsed = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(Inside)
|
|
UI()->SetHotItem(pID);
|
|
|
|
// draw
|
|
if (UI()->ActiveItem() == pID && ButtonUsed == 0)
|
|
DoButton_KeySelect(pID, "???", 0, pRect);
|
|
else
|
|
{
|
|
if(Key == 0)
|
|
DoButton_KeySelect(pID, "", 0, pRect);
|
|
else
|
|
DoButton_KeySelect(pID, Input()->KeyName(Key), 0, pRect);
|
|
}
|
|
return NewKey;
|
|
}
|
|
|
|
|
|
int CMenus::RenderMenubar(CUIRect r)
|
|
{
|
|
CUIRect Box = r;
|
|
CUIRect Button;
|
|
|
|
m_ActivePage = g_Config.m_UiPage;
|
|
int NewPage = -1;
|
|
|
|
if(Client()->State() != IClient::STATE_OFFLINE)
|
|
m_ActivePage = m_GamePage;
|
|
|
|
if(Client()->State() == IClient::STATE_OFFLINE)
|
|
{
|
|
// offline menus
|
|
if(0) // this is not done yet
|
|
{
|
|
Box.VSplitLeft(90.0f, &Button, &Box);
|
|
static int s_NewsButton=0;
|
|
if (DoButton_MenuTab(&s_NewsButton, Localize("News"), m_ActivePage==PAGE_NEWS, &Button, 0))
|
|
NewPage = PAGE_NEWS;
|
|
Box.VSplitLeft(30.0f, 0, &Box);
|
|
}
|
|
|
|
Box.VSplitLeft(100.0f, &Button, &Box);
|
|
static int s_InternetButton=0;
|
|
if(DoButton_MenuTab(&s_InternetButton, Localize("Internet"), m_ActivePage==PAGE_INTERNET, &Button, CUI::CORNER_TL))
|
|
{
|
|
ServerBrowser()->Refresh(IServerBrowser::TYPE_INTERNET);
|
|
NewPage = PAGE_INTERNET;
|
|
}
|
|
|
|
//Box.VSplitLeft(4.0f, 0, &Box);
|
|
Box.VSplitLeft(80.0f, &Button, &Box);
|
|
static int s_LanButton=0;
|
|
if(DoButton_MenuTab(&s_LanButton, Localize("LAN"), m_ActivePage==PAGE_LAN, &Button, 0))
|
|
{
|
|
ServerBrowser()->Refresh(IServerBrowser::TYPE_LAN);
|
|
NewPage = PAGE_LAN;
|
|
}
|
|
|
|
//box.VSplitLeft(4.0f, 0, &box);
|
|
Box.VSplitLeft(110.0f, &Button, &Box);
|
|
static int s_FavoritesButton=0;
|
|
if(DoButton_MenuTab(&s_FavoritesButton, Localize("Favorites"), m_ActivePage==PAGE_FAVORITES, &Button, CUI::CORNER_TR))
|
|
{
|
|
ServerBrowser()->Refresh(IServerBrowser::TYPE_FAVORITES);
|
|
NewPage = PAGE_FAVORITES;
|
|
}
|
|
|
|
Box.VSplitLeft(4.0f*5, 0, &Box);
|
|
Box.VSplitLeft(100.0f, &Button, &Box);
|
|
static int s_DemosButton=0;
|
|
if(DoButton_MenuTab(&s_DemosButton, Localize("Demos"), m_ActivePage==PAGE_DEMOS, &Button, CUI::CORNER_T))
|
|
{
|
|
DemolistPopulate();
|
|
NewPage = PAGE_DEMOS;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// online menus
|
|
Box.VSplitLeft(90.0f, &Button, &Box);
|
|
static int s_GameButton=0;
|
|
if(DoButton_MenuTab(&s_GameButton, Localize("Game"), m_ActivePage==PAGE_GAME, &Button, CUI::CORNER_T))
|
|
NewPage = PAGE_GAME;
|
|
|
|
Box.VSplitLeft(4.0f, 0, &Box);
|
|
Box.VSplitLeft(140.0f, &Button, &Box);
|
|
static int s_ServerInfoButton=0;
|
|
if(DoButton_MenuTab(&s_ServerInfoButton, Localize("Server info"), m_ActivePage==PAGE_SERVER_INFO, &Button, CUI::CORNER_T))
|
|
NewPage = PAGE_SERVER_INFO;
|
|
|
|
Box.VSplitLeft(4.0f, 0, &Box);
|
|
Box.VSplitLeft(140.0f, &Button, &Box);
|
|
static int s_CallVoteButton=0;
|
|
if(DoButton_MenuTab(&s_CallVoteButton, Localize("Call vote"), m_ActivePage==PAGE_CALLVOTE, &Button, CUI::CORNER_T))
|
|
NewPage = PAGE_CALLVOTE;
|
|
|
|
Box.VSplitLeft(30.0f, 0, &Box);
|
|
}
|
|
|
|
/*
|
|
box.VSplitRight(110.0f, &box, &button);
|
|
static int system_button=0;
|
|
if (UI()->DoButton(&system_button, "System", g_Config.m_UiPage==PAGE_SYSTEM, &button))
|
|
g_Config.m_UiPage = PAGE_SYSTEM;
|
|
|
|
box.VSplitRight(30.0f, &box, 0);
|
|
*/
|
|
|
|
Box.VSplitRight(90.0f, &Box, &Button);
|
|
static int s_QuitButton=0;
|
|
if(DoButton_MenuTab(&s_QuitButton, Localize("Quit"), 0, &Button, CUI::CORNER_T))
|
|
m_Popup = POPUP_QUIT;
|
|
|
|
Box.VSplitRight(10.0f, &Box, &Button);
|
|
Box.VSplitRight(130.0f, &Box, &Button);
|
|
static int s_SettingsButton=0;
|
|
if(DoButton_MenuTab(&s_SettingsButton, Localize("Settings"), m_ActivePage==PAGE_SETTINGS, &Button, CUI::CORNER_T))
|
|
NewPage = PAGE_SETTINGS;
|
|
|
|
if(NewPage != -1)
|
|
{
|
|
if(Client()->State() == IClient::STATE_OFFLINE)
|
|
g_Config.m_UiPage = NewPage;
|
|
else
|
|
m_GamePage = NewPage;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void CMenus::RenderLoading(float Percent)
|
|
{
|
|
static int64 LastLoadRender = 0;
|
|
|
|
// make sure that we don't render for each little thing we load
|
|
// because that will slow down loading if we have vsync
|
|
if(time_get()-LastLoadRender < time_freq()/60)
|
|
return;
|
|
|
|
LastLoadRender = time_get();
|
|
|
|
// need up date this here to get correct
|
|
vec3 Rgb = HslToRgb(vec3(g_Config.m_UiColorHue/255.0f, g_Config.m_UiColorSat/255.0f, g_Config.m_UiColorLht/255.0f));
|
|
ms_GuiColor = vec4(Rgb.r, Rgb.g, Rgb.b, g_Config.m_UiColorAlpha/255.0f);
|
|
|
|
CUIRect Screen = *UI()->Screen();
|
|
Graphics()->MapScreen(Screen.x, Screen.y, Screen.w, Screen.h);
|
|
|
|
RenderBackground();
|
|
|
|
float tw;
|
|
|
|
float w = 700;
|
|
float h = 200;
|
|
float x = Screen.w/2-w/2;
|
|
float y = Screen.h/2-h/2;
|
|
|
|
Graphics()->BlendNormal();
|
|
|
|
Graphics()->TextureSet(-1);
|
|
Graphics()->QuadsBegin();
|
|
Graphics()->SetColor(0,0,0,0.50f);
|
|
RenderTools()->DrawRoundRect(x, y, w, h, 40.0f);
|
|
Graphics()->QuadsEnd();
|
|
|
|
|
|
const char *pCaption = Localize("Loading");
|
|
|
|
tw = TextRender()->TextWidth(0, 48.0f, pCaption, -1);
|
|
CUIRect r;
|
|
r.x = x;
|
|
r.y = y+20;
|
|
r.w = w;
|
|
r.h = h;
|
|
UI()->DoLabel(&r, pCaption, 48.0f, 0, -1);
|
|
|
|
Graphics()->TextureSet(-1);
|
|
Graphics()->QuadsBegin();
|
|
Graphics()->SetColor(1,1,1,0.75f);
|
|
RenderTools()->DrawRoundRect(x+40, y+h-75, (w-80)*Percent, 25, 5.0f);
|
|
Graphics()->QuadsEnd();
|
|
|
|
Graphics()->Swap();
|
|
}
|
|
|
|
void CMenus::RenderNews(CUIRect MainView)
|
|
{
|
|
RenderTools()->DrawUIRect(&MainView, ms_ColorTabbarActive, CUI::CORNER_ALL, 10.0f);
|
|
}
|
|
|
|
void CMenus::OnInit()
|
|
{
|
|
|
|
/*
|
|
array<string> my_strings;
|
|
array<string>::range r2;
|
|
my_strings.add("4");
|
|
my_strings.add("6");
|
|
my_strings.add("1");
|
|
my_strings.add("3");
|
|
my_strings.add("7");
|
|
my_strings.add("5");
|
|
my_strings.add("2");
|
|
|
|
for(array<string>::range r = my_strings.all(); !r.empty(); r.pop_front())
|
|
dbg_msg("", "%s", r.front().cstr());
|
|
|
|
sort(my_strings.all());
|
|
|
|
dbg_msg("", "after:");
|
|
for(array<string>::range r = my_strings.all(); !r.empty(); r.pop_front())
|
|
dbg_msg("", "%s", r.front().cstr());
|
|
|
|
|
|
array<int> myarray;
|
|
myarray.add(4);
|
|
myarray.add(6);
|
|
myarray.add(1);
|
|
myarray.add(3);
|
|
myarray.add(7);
|
|
myarray.add(5);
|
|
myarray.add(2);
|
|
|
|
for(array<int>::range r = myarray.all(); !r.empty(); r.pop_front())
|
|
dbg_msg("", "%d", r.front());
|
|
|
|
sort(myarray.all());
|
|
sort_verify(myarray.all());
|
|
|
|
dbg_msg("", "after:");
|
|
for(array<int>::range r = myarray.all(); !r.empty(); r.pop_front())
|
|
dbg_msg("", "%d", r.front());
|
|
|
|
exit(-1);
|
|
// */
|
|
|
|
if(g_Config.m_ClShowWelcome)
|
|
m_Popup = POPUP_FIRST_LAUNCH;
|
|
g_Config.m_ClShowWelcome = 0;
|
|
|
|
Console()->Chain("add_favorite", ConchainServerbrowserUpdate, this);
|
|
}
|
|
|
|
void CMenus::PopupMessage(const char *pTopic, const char *pBody, const char *pButton)
|
|
{
|
|
// reset active item
|
|
UI()->SetActiveItem(0);
|
|
|
|
str_copy(m_aMessageTopic, pTopic, sizeof(m_aMessageTopic));
|
|
str_copy(m_aMessageBody, pBody, sizeof(m_aMessageBody));
|
|
str_copy(m_aMessageButton, pButton, sizeof(m_aMessageButton));
|
|
m_Popup = POPUP_MESSAGE;
|
|
}
|
|
|
|
|
|
int CMenus::Render()
|
|
{
|
|
CUIRect Screen = *UI()->Screen();
|
|
Graphics()->MapScreen(Screen.x, Screen.y, Screen.w, Screen.h);
|
|
|
|
static bool s_First = true;
|
|
if(s_First)
|
|
{
|
|
if(g_Config.m_UiPage == PAGE_INTERNET)
|
|
ServerBrowser()->Refresh(IServerBrowser::TYPE_INTERNET);
|
|
else if(g_Config.m_UiPage == PAGE_LAN)
|
|
ServerBrowser()->Refresh(IServerBrowser::TYPE_LAN);
|
|
else if(g_Config.m_UiPage == PAGE_FAVORITES)
|
|
ServerBrowser()->Refresh(IServerBrowser::TYPE_FAVORITES);
|
|
s_First = false;
|
|
}
|
|
|
|
if(Client()->State() == IClient::STATE_ONLINE)
|
|
{
|
|
ms_ColorTabbarInactive = ms_ColorTabbarInactiveIngame;
|
|
ms_ColorTabbarActive = ms_ColorTabbarActiveIngame;
|
|
}
|
|
else
|
|
{
|
|
RenderBackground();
|
|
ms_ColorTabbarInactive = ms_ColorTabbarInactiveOutgame;
|
|
ms_ColorTabbarActive = ms_ColorTabbarActiveOutgame;
|
|
}
|
|
|
|
CUIRect TabBar;
|
|
CUIRect MainView;
|
|
|
|
// some margin around the screen
|
|
Screen.Margin(10.0f, &Screen);
|
|
|
|
if(m_Popup == POPUP_NONE)
|
|
{
|
|
// do tab bar
|
|
Screen.HSplitTop(24.0f, &TabBar, &MainView);
|
|
TabBar.VMargin(20.0f, &TabBar);
|
|
RenderMenubar(TabBar);
|
|
|
|
// news is not implemented yet
|
|
if(g_Config.m_UiPage <= PAGE_NEWS || g_Config.m_UiPage > PAGE_SETTINGS || (Client()->State() == IClient::STATE_OFFLINE && g_Config.m_UiPage >= PAGE_GAME && g_Config.m_UiPage <= PAGE_CALLVOTE))
|
|
{
|
|
ServerBrowser()->Refresh(IServerBrowser::TYPE_INTERNET);
|
|
g_Config.m_UiPage = PAGE_INTERNET;
|
|
}
|
|
|
|
// render current page
|
|
if(Client()->State() != IClient::STATE_OFFLINE)
|
|
{
|
|
if(m_GamePage == PAGE_GAME)
|
|
RenderGame(MainView);
|
|
else if(m_GamePage == PAGE_SERVER_INFO)
|
|
RenderServerInfo(MainView);
|
|
else if(m_GamePage == PAGE_CALLVOTE)
|
|
RenderServerControl(MainView);
|
|
else if(m_GamePage == PAGE_SETTINGS)
|
|
RenderSettings(MainView);
|
|
}
|
|
else if(g_Config.m_UiPage == PAGE_NEWS)
|
|
RenderNews(MainView);
|
|
else if(g_Config.m_UiPage == PAGE_INTERNET)
|
|
RenderServerbrowser(MainView);
|
|
else if(g_Config.m_UiPage == PAGE_LAN)
|
|
RenderServerbrowser(MainView);
|
|
else if(g_Config.m_UiPage == PAGE_DEMOS)
|
|
RenderDemoList(MainView);
|
|
else if(g_Config.m_UiPage == PAGE_FAVORITES)
|
|
RenderServerbrowser(MainView);
|
|
else if(g_Config.m_UiPage == PAGE_SETTINGS)
|
|
RenderSettings(MainView);
|
|
}
|
|
else
|
|
{
|
|
// make sure that other windows doesn't do anything funnay!
|
|
//UI()->SetHotItem(0);
|
|
//UI()->SetActiveItem(0);
|
|
char aBuf[128];
|
|
const char *pTitle = "";
|
|
const char *pExtraText = "";
|
|
const char *pButtonText = "";
|
|
int ExtraAlign = 0;
|
|
|
|
if(m_Popup == POPUP_MESSAGE)
|
|
{
|
|
pTitle = m_aMessageTopic;
|
|
pExtraText = m_aMessageBody;
|
|
pButtonText = m_aMessageButton;
|
|
}
|
|
else if(m_Popup == POPUP_CONNECTING)
|
|
{
|
|
pTitle = Localize("Connecting to");
|
|
pExtraText = g_Config.m_UiServerAddress; // TODO: query the client about the address
|
|
pButtonText = Localize("Abort");
|
|
if(Client()->MapDownloadTotalsize() > 0)
|
|
{
|
|
pTitle = Localize("Downloading map");
|
|
str_format(aBuf, sizeof(aBuf), "%d/%d KiB", Client()->MapDownloadAmount()/1024, Client()->MapDownloadTotalsize()/1024);
|
|
pExtraText = aBuf;
|
|
}
|
|
}
|
|
else if(m_Popup == POPUP_DISCONNECTED)
|
|
{
|
|
pTitle = Localize("Disconnected");
|
|
pExtraText = Client()->ErrorString();
|
|
pButtonText = Localize("Ok");
|
|
ExtraAlign = -1;
|
|
}
|
|
else if(m_Popup == POPUP_PURE)
|
|
{
|
|
pTitle = Localize("Disconnected");
|
|
pExtraText = Localize("The server is running a non-standard tuning on a pure game type.");
|
|
pButtonText = Localize("Ok");
|
|
ExtraAlign = -1;
|
|
}
|
|
else if(m_Popup == POPUP_DELETE_DEMO)
|
|
{
|
|
pTitle = Localize("Delete demo");
|
|
pExtraText = Localize("Are you sure that you want to delete the demo?");
|
|
ExtraAlign = -1;
|
|
}
|
|
else if(m_Popup == POPUP_PASSWORD)
|
|
{
|
|
pTitle = Localize("Password incorrect");
|
|
pExtraText = Client()->ErrorString();
|
|
pButtonText = Localize("Try again");
|
|
}
|
|
else if(m_Popup == POPUP_QUIT)
|
|
{
|
|
pTitle = Localize("Quit");
|
|
pExtraText = Localize("Are you sure that you want to quit?");
|
|
}
|
|
else if(m_Popup == POPUP_FIRST_LAUNCH)
|
|
{
|
|
pTitle = Localize("Welcome to Teeworlds");
|
|
pExtraText = Localize("As this is the first time you launch the game, please enter your nick name below. It's recommended that you check the settings to adjust them to your liking before joining a server.");
|
|
pButtonText = Localize("Ok");
|
|
ExtraAlign = -1;
|
|
}
|
|
|
|
CUIRect Box, Part;
|
|
Box = Screen;
|
|
Box.VMargin(150.0f, &Box);
|
|
Box.HMargin(150.0f, &Box);
|
|
|
|
// render the box
|
|
RenderTools()->DrawUIRect(&Box, vec4(0,0,0,0.5f), CUI::CORNER_ALL, 15.0f);
|
|
|
|
Box.HSplitTop(20.f, &Part, &Box);
|
|
Box.HSplitTop(24.f, &Part, &Box);
|
|
UI()->DoLabel(&Part, pTitle, 24.f, 0);
|
|
Box.HSplitTop(20.f, &Part, &Box);
|
|
Box.HSplitTop(24.f, &Part, &Box);
|
|
Part.VMargin(20.f, &Part);
|
|
|
|
if(ExtraAlign == -1)
|
|
UI()->DoLabel(&Part, pExtraText, 20.f, -1, (int)Part.w);
|
|
else
|
|
UI()->DoLabel(&Part, pExtraText, 20.f, 0, -1);
|
|
|
|
if(m_Popup == POPUP_QUIT)
|
|
{
|
|
CUIRect Yes, No;
|
|
Box.HSplitBottom(20.f, &Box, &Part);
|
|
Box.HSplitBottom(24.f, &Box, &Part);
|
|
Part.VMargin(80.0f, &Part);
|
|
|
|
Part.VSplitMid(&No, &Yes);
|
|
|
|
Yes.VMargin(20.0f, &Yes);
|
|
No.VMargin(20.0f, &No);
|
|
|
|
static int s_ButtonAbort = 0;
|
|
if(DoButton_Menu(&s_ButtonAbort, Localize("No"), 0, &No) || m_EscapePressed)
|
|
m_Popup = POPUP_NONE;
|
|
|
|
static int s_ButtonTryAgain = 0;
|
|
if(DoButton_Menu(&s_ButtonTryAgain, Localize("Yes"), 0, &Yes) || m_EnterPressed)
|
|
Client()->Quit();
|
|
}
|
|
else if(m_Popup == POPUP_PASSWORD)
|
|
{
|
|
CUIRect Label, TextBox, TryAgain, Abort;
|
|
|
|
Box.HSplitBottom(20.f, &Box, &Part);
|
|
Box.HSplitBottom(24.f, &Box, &Part);
|
|
Part.VMargin(80.0f, &Part);
|
|
|
|
Part.VSplitMid(&Abort, &TryAgain);
|
|
|
|
TryAgain.VMargin(20.0f, &TryAgain);
|
|
Abort.VMargin(20.0f, &Abort);
|
|
|
|
static int s_ButtonAbort = 0;
|
|
if(DoButton_Menu(&s_ButtonAbort, Localize("Abort"), 0, &Abort) || m_EscapePressed)
|
|
m_Popup = POPUP_NONE;
|
|
|
|
static int s_ButtonTryAgain = 0;
|
|
if(DoButton_Menu(&s_ButtonTryAgain, Localize("Try again"), 0, &TryAgain) || m_EnterPressed)
|
|
{
|
|
Client()->Connect(g_Config.m_UiServerAddress);
|
|
}
|
|
|
|
Box.HSplitBottom(60.f, &Box, &Part);
|
|
Box.HSplitBottom(24.f, &Box, &Part);
|
|
|
|
Part.VSplitLeft(60.0f, 0, &Label);
|
|
Label.VSplitLeft(100.0f, 0, &TextBox);
|
|
TextBox.VSplitLeft(20.0f, 0, &TextBox);
|
|
TextBox.VSplitRight(60.0f, &TextBox, 0);
|
|
UI()->DoLabel(&Label, Localize("Password"), 18.0f, -1);
|
|
static float Offset = 0.0f;
|
|
DoEditBox(&g_Config.m_Password, &TextBox, g_Config.m_Password, sizeof(g_Config.m_Password), 12.0f, &Offset, true);
|
|
}
|
|
else if(m_Popup == POPUP_DELETE_DEMO)
|
|
{
|
|
CUIRect Yes, No;
|
|
Box.HSplitBottom(20.f, &Box, &Part);
|
|
Box.HSplitBottom(24.f, &Box, &Part);
|
|
Part.VMargin(80.0f, &Part);
|
|
|
|
Part.VSplitMid(&No, &Yes);
|
|
|
|
Yes.VMargin(20.0f, &Yes);
|
|
No.VMargin(20.0f, &No);
|
|
|
|
static int s_ButtonAbort = 0;
|
|
if(DoButton_Menu(&s_ButtonAbort, Localize("No"), 0, &No) || m_EscapePressed)
|
|
m_Popup = POPUP_NONE;
|
|
|
|
static int s_ButtonTryAgain = 0;
|
|
if(DoButton_Menu(&s_ButtonTryAgain, Localize("Yes"), 0, &Yes) || m_EnterPressed)
|
|
{
|
|
m_Popup = POPUP_NONE;
|
|
m_DemolistDelEntry = true;
|
|
}
|
|
}
|
|
else if(m_Popup == POPUP_FIRST_LAUNCH)
|
|
{
|
|
CUIRect Label, TextBox;
|
|
|
|
Box.HSplitBottom(20.f, &Box, &Part);
|
|
Box.HSplitBottom(24.f, &Box, &Part);
|
|
Part.VMargin(80.0f, &Part);
|
|
|
|
static int s_EnterButton = 0;
|
|
if(DoButton_Menu(&s_EnterButton, Localize("Enter"), 0, &Part) || m_EnterPressed)
|
|
m_Popup = POPUP_NONE;
|
|
|
|
Box.HSplitBottom(40.f, &Box, &Part);
|
|
Box.HSplitBottom(24.f, &Box, &Part);
|
|
|
|
Part.VSplitLeft(60.0f, 0, &Label);
|
|
Label.VSplitLeft(100.0f, 0, &TextBox);
|
|
TextBox.VSplitLeft(20.0f, 0, &TextBox);
|
|
TextBox.VSplitRight(60.0f, &TextBox, 0);
|
|
UI()->DoLabel(&Label, Localize("Nickname"), 18.0f, -1);
|
|
static float Offset = 0.0f;
|
|
DoEditBox(&g_Config.m_PlayerName, &TextBox, g_Config.m_PlayerName, sizeof(g_Config.m_PlayerName), 12.0f, &Offset);
|
|
}
|
|
else
|
|
{
|
|
Box.HSplitBottom(20.f, &Box, &Part);
|
|
Box.HSplitBottom(24.f, &Box, &Part);
|
|
Part.VMargin(120.0f, &Part);
|
|
|
|
static int s_Button = 0;
|
|
if(DoButton_Menu(&s_Button, pButtonText, 0, &Part) || m_EscapePressed || m_EnterPressed)
|
|
{
|
|
if(m_Popup == POPUP_CONNECTING)
|
|
Client()->Disconnect();
|
|
m_Popup = POPUP_NONE;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
void CMenus::SetActive(bool Active)
|
|
{
|
|
m_MenuActive = Active;
|
|
if(!m_MenuActive)
|
|
{
|
|
if(m_NeedSendinfo)
|
|
{
|
|
m_pClient->SendInfo(false);
|
|
m_NeedSendinfo = false;
|
|
}
|
|
|
|
if(Client()->State() == IClient::STATE_ONLINE)
|
|
{
|
|
m_pClient->OnRelease();
|
|
}
|
|
}
|
|
}
|
|
|
|
void CMenus::OnReset()
|
|
{
|
|
}
|
|
|
|
bool CMenus::OnMouseMove(float x, float y)
|
|
{
|
|
m_LastInput = time_get();
|
|
|
|
if(!m_MenuActive)
|
|
return false;
|
|
|
|
m_MousePos.x += x;
|
|
m_MousePos.y += y;
|
|
if(m_MousePos.x < 0) m_MousePos.x = 0;
|
|
if(m_MousePos.y < 0) m_MousePos.y = 0;
|
|
if(m_MousePos.x > Graphics()->ScreenWidth()) m_MousePos.x = Graphics()->ScreenWidth();
|
|
if(m_MousePos.y > Graphics()->ScreenHeight()) m_MousePos.y = Graphics()->ScreenHeight();
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CMenus::OnInput(IInput::CEvent e)
|
|
{
|
|
m_LastInput = time_get();
|
|
|
|
// special handle esc and enter for popup purposes
|
|
if(e.m_Flags&IInput::FLAG_PRESS)
|
|
{
|
|
if(e.m_Key == KEY_ESCAPE)
|
|
{
|
|
m_EscapePressed = true;
|
|
SetActive(!IsActive());
|
|
return true;
|
|
}
|
|
}
|
|
|
|
if(IsActive())
|
|
{
|
|
if(e.m_Flags&IInput::FLAG_PRESS)
|
|
{
|
|
// special for popups
|
|
if(e.m_Key == KEY_RETURN || e.m_Key == KEY_KP_ENTER)
|
|
m_EnterPressed = true;
|
|
else if(e.m_Key == KEY_DELETE)
|
|
m_DeletePressed = true;
|
|
}
|
|
|
|
if(m_NumInputEvents < MAX_INPUTEVENTS)
|
|
m_aInputEvents[m_NumInputEvents++] = e;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void CMenus::OnStateChange(int NewState, int OldState)
|
|
{
|
|
// reset active item
|
|
UI()->SetActiveItem(0);
|
|
|
|
if(NewState == IClient::STATE_OFFLINE)
|
|
{
|
|
m_Popup = POPUP_NONE;
|
|
if(Client()->ErrorString() && Client()->ErrorString()[0] != 0)
|
|
{
|
|
if(str_find(Client()->ErrorString(), "password"))
|
|
{
|
|
m_Popup = POPUP_PASSWORD;
|
|
UI()->SetHotItem(&g_Config.m_Password);
|
|
UI()->SetActiveItem(&g_Config.m_Password);
|
|
}
|
|
else
|
|
m_Popup = POPUP_DISCONNECTED;
|
|
}
|
|
}
|
|
else if(NewState == IClient::STATE_LOADING)
|
|
{
|
|
m_Popup = POPUP_CONNECTING;
|
|
//client_serverinfo_request();
|
|
}
|
|
else if(NewState == IClient::STATE_CONNECTING)
|
|
m_Popup = POPUP_CONNECTING;
|
|
else if (NewState == IClient::STATE_ONLINE || NewState == IClient::STATE_DEMOPLAYBACK)
|
|
{
|
|
m_Popup = POPUP_NONE;
|
|
SetActive(false);
|
|
}
|
|
}
|
|
|
|
extern "C" void font_debug_render();
|
|
|
|
void CMenus::OnRender()
|
|
{
|
|
/*
|
|
// text rendering test stuff
|
|
render_background();
|
|
|
|
CTextCursor cursor;
|
|
TextRender()->SetCursor(&cursor, 10, 10, 20, TEXTFLAG_RENDER);
|
|
TextRender()->TextEx(&cursor, "ようこそ - ガイド", -1);
|
|
|
|
TextRender()->SetCursor(&cursor, 10, 30, 15, TEXTFLAG_RENDER);
|
|
TextRender()->TextEx(&cursor, "ようこそ - ガイド", -1);
|
|
|
|
//Graphics()->TextureSet(-1);
|
|
Graphics()->QuadsBegin();
|
|
Graphics()->QuadsDrawTL(60, 60, 5000, 5000);
|
|
Graphics()->QuadsEnd();
|
|
return;*/
|
|
|
|
if(Client()->State() != IClient::STATE_ONLINE && Client()->State() != IClient::STATE_DEMOPLAYBACK)
|
|
SetActive(true);
|
|
|
|
if(Client()->State() == IClient::STATE_DEMOPLAYBACK)
|
|
{
|
|
CUIRect Screen = *UI()->Screen();
|
|
Graphics()->MapScreen(Screen.x, Screen.y, Screen.w, Screen.h);
|
|
RenderDemoPlayer(Screen);
|
|
}
|
|
|
|
if(Client()->State() == IClient::STATE_ONLINE && m_pClient->m_ServerMode == m_pClient->SERVERMODE_PUREMOD)
|
|
{
|
|
Client()->Disconnect();
|
|
SetActive(true);
|
|
m_Popup = POPUP_PURE;
|
|
}
|
|
|
|
if(!IsActive())
|
|
{
|
|
m_EscapePressed = false;
|
|
m_EnterPressed = false;
|
|
m_DeletePressed = false;
|
|
m_NumInputEvents = 0;
|
|
return;
|
|
}
|
|
|
|
// update colors
|
|
vec3 Rgb = HslToRgb(vec3(g_Config.m_UiColorHue/255.0f, g_Config.m_UiColorSat/255.0f, g_Config.m_UiColorLht/255.0f));
|
|
ms_GuiColor = vec4(Rgb.r, Rgb.g, Rgb.b, g_Config.m_UiColorAlpha/255.0f);
|
|
|
|
ms_ColorTabbarInactiveOutgame = vec4(0,0,0,0.25f);
|
|
ms_ColorTabbarActiveOutgame = vec4(0,0,0,0.5f);
|
|
|
|
float ColorIngameScaleI = 0.5f;
|
|
float ColorIngameAcaleA = 0.2f;
|
|
ms_ColorTabbarInactiveIngame = vec4(
|
|
ms_GuiColor.r*ColorIngameScaleI,
|
|
ms_GuiColor.g*ColorIngameScaleI,
|
|
ms_GuiColor.b*ColorIngameScaleI,
|
|
ms_GuiColor.a*0.8f);
|
|
|
|
ms_ColorTabbarActiveIngame = vec4(
|
|
ms_GuiColor.r*ColorIngameAcaleA,
|
|
ms_GuiColor.g*ColorIngameAcaleA,
|
|
ms_GuiColor.b*ColorIngameAcaleA,
|
|
ms_GuiColor.a);
|
|
|
|
// update the ui
|
|
CUIRect *pScreen = UI()->Screen();
|
|
float mx = (m_MousePos.x/(float)Graphics()->ScreenWidth())*pScreen->w;
|
|
float my = (m_MousePos.y/(float)Graphics()->ScreenHeight())*pScreen->h;
|
|
|
|
int Buttons = 0;
|
|
if(m_UseMouseButtons)
|
|
{
|
|
if(Input()->KeyPressed(KEY_MOUSE_1)) Buttons |= 1;
|
|
if(Input()->KeyPressed(KEY_MOUSE_2)) Buttons |= 2;
|
|
if(Input()->KeyPressed(KEY_MOUSE_3)) Buttons |= 4;
|
|
}
|
|
|
|
UI()->Update(mx,my,mx*3.0f,my*3.0f,Buttons);
|
|
|
|
// render
|
|
if(Client()->State() != IClient::STATE_DEMOPLAYBACK)
|
|
Render();
|
|
|
|
// render cursor
|
|
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_CURSOR].m_Id);
|
|
Graphics()->QuadsBegin();
|
|
Graphics()->SetColor(1,1,1,1);
|
|
IGraphics::CQuadItem QuadItem(mx, my, 24, 24);
|
|
Graphics()->QuadsDrawTL(&QuadItem, 1);
|
|
Graphics()->QuadsEnd();
|
|
|
|
// render debug information
|
|
if(g_Config.m_Debug)
|
|
{
|
|
CUIRect Screen = *UI()->Screen();
|
|
Graphics()->MapScreen(Screen.x, Screen.y, Screen.w, Screen.h);
|
|
|
|
char aBuf[512];
|
|
str_format(aBuf, sizeof(aBuf), "%p %p %p", UI()->HotItem(), UI()->ActiveItem(), UI()->LastActiveItem());
|
|
CTextCursor Cursor;
|
|
TextRender()->SetCursor(&Cursor, 10, 10, 10, TEXTFLAG_RENDER);
|
|
TextRender()->TextEx(&Cursor, aBuf, -1);
|
|
}
|
|
|
|
m_EscapePressed = false;
|
|
m_EnterPressed = false;
|
|
m_DeletePressed = false;
|
|
m_NumInputEvents = 0;
|
|
}
|
|
|
|
static int gs_TextureBlob = -1;
|
|
|
|
void CMenus::RenderBackground()
|
|
{
|
|
//Graphics()->Clear(1,1,1);
|
|
//render_sunrays(0,0);
|
|
if(gs_TextureBlob == -1)
|
|
gs_TextureBlob = Graphics()->LoadTexture("blob.png", IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, 0);
|
|
|
|
|
|
float sw = 300*Graphics()->ScreenAspect();
|
|
float sh = 300;
|
|
Graphics()->MapScreen(0, 0, sw, sh);
|
|
|
|
// render background color
|
|
Graphics()->TextureSet(-1);
|
|
Graphics()->QuadsBegin();
|
|
//vec4 bottom(gui_color.r*0.3f, gui_color.g*0.3f, gui_color.b*0.3f, 1.0f);
|
|
//vec4 bottom(0, 0, 0, 1.0f);
|
|
vec4 Bottom(ms_GuiColor.r, ms_GuiColor.g, ms_GuiColor.b, 1.0f);
|
|
vec4 Top(ms_GuiColor.r, ms_GuiColor.g, ms_GuiColor.b, 1.0f);
|
|
IGraphics::CColorVertex Array[4] = {
|
|
IGraphics::CColorVertex(0, Top.r, Top.g, Top.b, Top.a),
|
|
IGraphics::CColorVertex(1, Top.r, Top.g, Top.b, Top.a),
|
|
IGraphics::CColorVertex(2, Bottom.r, Bottom.g, Bottom.b, Bottom.a),
|
|
IGraphics::CColorVertex(3, Bottom.r, Bottom.g, Bottom.b, Bottom.a)};
|
|
Graphics()->SetColorVertex(Array, 4);
|
|
IGraphics::CQuadItem QuadItem(0, 0, sw, sh);
|
|
Graphics()->QuadsDrawTL(&QuadItem, 1);
|
|
Graphics()->QuadsEnd();
|
|
|
|
// render the tiles
|
|
Graphics()->TextureSet(-1);
|
|
Graphics()->QuadsBegin();
|
|
float Size = 15.0f;
|
|
float OffsetTime = fmod(Client()->LocalTime()*0.15f, 2.0f);
|
|
for(int y = -2; y < (int)(sw/Size); y++)
|
|
for(int x = -2; x < (int)(sh/Size); x++)
|
|
{
|
|
Graphics()->SetColor(0,0,0,0.045f);
|
|
IGraphics::CQuadItem QuadItem((x-OffsetTime)*Size*2+(y&1)*Size, (y+OffsetTime)*Size, Size, Size);
|
|
Graphics()->QuadsDrawTL(&QuadItem, 1);
|
|
}
|
|
Graphics()->QuadsEnd();
|
|
|
|
// render border fade
|
|
Graphics()->TextureSet(gs_TextureBlob);
|
|
Graphics()->QuadsBegin();
|
|
Graphics()->SetColor(0,0,0,0.5f);
|
|
QuadItem = IGraphics::CQuadItem(-100, -100, sw+200, sh+200);
|
|
Graphics()->QuadsDrawTL(&QuadItem, 1);
|
|
Graphics()->QuadsEnd();
|
|
|
|
// restore screen
|
|
{CUIRect Screen = *UI()->Screen();
|
|
Graphics()->MapScreen(Screen.x, Screen.y, Screen.w, Screen.h);}
|
|
}
|