2010-11-20 10:37:14 +00:00
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
/* If you are missing that file, acquire a complete release at teeworlds.com. */
2011-08-31 11:56:04 +00:00
2022-06-23 17:59:38 +00:00
# include <algorithm>
2022-05-29 16:33:38 +00:00
# include <chrono>
2022-02-14 23:22:52 +00:00
# include <cmath>
2022-05-29 16:33:38 +00:00
# include <vector>
2008-08-27 15:48:50 +00:00
2010-05-29 07:25:38 +00:00
# include <base/math.h>
2020-09-22 16:02:03 +00:00
# include <base/system.h>
2010-05-29 07:25:38 +00:00
# include <base/vmath.h>
2008-08-27 15:48:50 +00:00
2022-06-23 17:59:38 +00:00
# include <engine/client.h>
2022-10-04 16:40:24 +00:00
# include <engine/config.h>
2011-03-21 23:31:42 +00:00
# include <engine/editor.h>
2011-03-23 12:06:35 +00:00
# include <engine/friends.h>
2010-05-29 07:25:38 +00:00
# include <engine/graphics.h>
# include <engine/keys.h>
2011-03-21 23:31:42 +00:00
# include <engine/serverbrowser.h>
2020-09-22 16:02:03 +00:00
# include <engine/shared/config.h>
2010-10-06 21:07:35 +00:00
# include <engine/storage.h>
2011-03-21 23:31:42 +00:00
# include <engine/textrender.h>
2009-06-13 17:18:06 +00:00
2010-05-29 07:25:38 +00:00
# include <game/generated/protocol.h>
2008-08-27 15:48:50 +00:00
2020-09-16 01:30:03 +00:00
# include <engine/client/updater.h>
2019-04-28 17:22:19 +00:00
# include <game/client/components/binds.h>
2020-09-03 12:08:26 +00:00
# include <game/client/components/console.h>
2020-09-18 16:45:42 +00:00
# include <game/client/components/menu_background.h>
2011-04-13 18:00:54 +00:00
# include <game/client/components/sounds.h>
2010-05-29 07:25:38 +00:00
# include <game/client/gameclient.h>
2023-01-05 11:21:10 +00:00
# include <game/client/ui_listbox.h>
2020-09-10 18:14:47 +00:00
# include <game/generated/client_data.h>
2010-05-29 07:25:38 +00:00
# include <game/localization.h>
2008-08-27 15:48:50 +00:00
2011-06-29 20:27:32 +00:00
# include "countryflags.h"
2011-03-23 12:06:35 +00:00
# include "menus.h"
2022-05-18 16:00:05 +00:00
using namespace std : : chrono_literals ;
2019-04-26 21:47:34 +00:00
ColorRGBA CMenus : : ms_GuiColor ;
ColorRGBA CMenus : : ms_ColorTabbarInactiveOutgame ;
ColorRGBA CMenus : : ms_ColorTabbarActiveOutgame ;
2020-09-16 01:30:03 +00:00
ColorRGBA CMenus : : ms_ColorTabbarHoverOutgame ;
2019-04-26 21:47:34 +00:00
ColorRGBA CMenus : : ms_ColorTabbarInactive ;
2020-09-16 01:30:03 +00:00
ColorRGBA CMenus : : ms_ColorTabbarActive = ColorRGBA ( 0 , 0 , 0 , 0.5f ) ;
ColorRGBA CMenus : : ms_ColorTabbarHover ;
2019-04-26 21:47:34 +00:00
ColorRGBA CMenus : : ms_ColorTabbarInactiveIngame ;
ColorRGBA CMenus : : ms_ColorTabbarActiveIngame ;
2020-09-16 01:30:03 +00:00
ColorRGBA CMenus : : ms_ColorTabbarHoverIngame ;
2008-08-27 15:48:50 +00:00
2020-10-28 02:59:50 +00:00
SColorPicker CMenus : : ms_ColorPicker ;
2020-12-14 00:51:31 +00:00
bool CMenus : : ms_ValueSelectorTextMode ;
2020-10-28 02:59:50 +00:00
2010-05-29 07:25:38 +00:00
float CMenus : : ms_ButtonHeight = 25.0f ;
float CMenus : : ms_ListheaderHeight = 17.0f ;
2008-10-06 18:05:01 +00:00
2010-05-29 07:25:38 +00:00
IInput : : CEvent CMenus : : m_aInputEvents [ MAX_INPUTEVENTS ] ;
int CMenus : : m_NumInputEvents ;
2008-08-30 09:28:31 +00:00
2010-05-29 07:25:38 +00:00
CMenus : : CMenus ( )
2008-08-27 15:48:50 +00:00
{
2010-05-29 07:25:38 +00:00
m_Popup = POPUP_NONE ;
m_ActivePage = PAGE_INTERNET ;
2020-09-03 12:08:26 +00:00
m_MenuPage = 0 ;
2010-05-29 07:25:38 +00:00
m_GamePage = PAGE_GAME ;
2022-02-21 00:04:49 +00:00
m_JoinTutorial = false ;
2011-04-13 18:37:12 +00:00
2010-10-16 09:24:42 +00:00
m_NeedRestartGraphics = false ;
m_NeedRestartSound = false ;
2010-05-29 07:25:38 +00:00
m_NeedSendinfo = false ;
2014-04-28 13:19:57 +00:00
m_NeedSendDummyinfo = false ;
2010-05-29 07:25:38 +00:00
m_MenuActive = true ;
2020-09-03 12:08:26 +00:00
m_ShowStart = true ;
2011-04-13 18:37:12 +00:00
2010-05-29 07:25:38 +00:00
m_NumInputEvents = 0 ;
2011-04-13 18:37:12 +00:00
2022-07-09 16:14:56 +00:00
str_copy ( m_aCurrentDemoFolder , " demos " ) ;
2010-10-09 18:34:17 +00:00
m_aCallvoteReason [ 0 ] = 0 ;
2011-03-23 12:06:35 +00:00
m_FriendlistSelectedIndex = - 1 ;
2011-04-09 06:41:31 +00:00
2014-08-23 15:48:04 +00:00
m_DemoPlayerState = DEMOPLAYER_NONE ;
2015-08-28 18:44:07 +00:00
m_Dummy = false ;
2020-09-03 12:08:26 +00:00
2023-03-10 16:39:24 +00:00
m_ServerProcess . m_Process = INVALID_PROCESS ;
2020-10-26 02:48:05 +00:00
for ( SUIAnimator & animator : m_aAnimatorsSettingsTab )
{
animator . m_YOffset = - 2.5f ;
animator . m_HOffset = 5.0f ;
animator . m_WOffset = 5.0f ;
2020-10-26 03:10:58 +00:00
animator . m_RepositionLabel = true ;
2020-10-26 02:48:05 +00:00
}
for ( SUIAnimator & animator : m_aAnimatorsBigPage )
{
animator . m_YOffset = - 5.0f ;
animator . m_HOffset = 5.0f ;
}
for ( SUIAnimator & animator : m_aAnimatorsSmallPage )
{
animator . m_YOffset = - 2.5f ;
animator . m_HOffset = 2.5f ;
}
2008-08-27 15:48:50 +00:00
}
2012-01-10 22:03:23 +00:00
int CMenus : : DoButton_Toggle ( const void * pID , int Checked , const CUIRect * pRect , bool Active )
2011-04-06 18:18:31 +00:00
{
Graphics ( ) - > TextureSet ( g_pData - > m_aImages [ IMAGE_GUIBUTTONS ] . m_Id ) ;
Graphics ( ) - > QuadsBegin ( ) ;
2012-01-10 22:03:23 +00:00
if ( ! Active )
Graphics ( ) - > SetColor ( 1.0f , 1.0f , 1.0f , 0.5f ) ;
2020-09-22 16:02:03 +00:00
RenderTools ( ) - > SelectSprite ( Checked ? SPRITE_GUIBUTTON_ON : SPRITE_GUIBUTTON_OFF ) ;
2011-04-06 18:18:31 +00:00
IGraphics : : CQuadItem QuadItem ( pRect - > x , pRect - > y , pRect - > w , pRect - > h ) ;
Graphics ( ) - > QuadsDrawTL ( & QuadItem , 1 ) ;
2012-01-10 22:03:23 +00:00
if ( UI ( ) - > HotItem ( ) = = pID & & Active )
2011-04-06 18:18:31 +00:00
{
RenderTools ( ) - > SelectSprite ( SPRITE_GUIBUTTON_HOVER ) ;
2022-03-20 11:57:50 +00:00
QuadItem = IGraphics : : CQuadItem ( pRect - > x , pRect - > y , pRect - > w , pRect - > h ) ;
2011-04-06 18:18:31 +00:00
Graphics ( ) - > QuadsDrawTL ( & QuadItem , 1 ) ;
}
Graphics ( ) - > QuadsEnd ( ) ;
2011-04-13 18:37:12 +00:00
2022-05-13 22:26:15 +00:00
return Active ? UI ( ) - > DoButtonLogic ( pID , Checked , pRect ) : 0 ;
2011-04-06 18:18:31 +00:00
}
2008-08-27 15:48:50 +00:00
2022-07-16 13:32:06 +00:00
int CMenus : : DoButton_Menu ( CButtonContainer * pButtonContainer , const char * pText , int Checked , const CUIRect * pRect , const char * pImageName , int Corners , float r , float FontFactor , vec4 ColorHot , vec4 Color , int AlignVertically , bool CheckForActiveColorPicker )
2008-08-27 15:48:50 +00:00
{
2020-09-03 12:08:26 +00:00
CUIRect Text = * pRect ;
2020-10-29 00:55:01 +00:00
bool MouseInsideColorPicker = false ;
if ( CheckForActiveColorPicker )
{
if ( ms_ColorPicker . m_Active )
{
CUIRect PickerRect ;
PickerRect . x = ms_ColorPicker . m_X ;
PickerRect . y = ms_ColorPicker . m_Y ;
PickerRect . w = ms_ColorPicker . ms_Width ;
PickerRect . h = ms_ColorPicker . ms_Height ;
MouseInsideColorPicker = UI ( ) - > MouseInside ( & PickerRect ) ;
}
}
if ( ! MouseInsideColorPicker )
2022-07-16 13:32:06 +00:00
Color . a * = UI ( ) - > ButtonColorMul ( pButtonContainer ) ;
2022-08-07 16:12:07 +00:00
pRect - > Draw ( Color , Corners , r ) ;
2020-09-03 12:08:26 +00:00
if ( pImageName )
{
CUIRect Image ;
2020-09-10 18:14:47 +00:00
pRect - > VSplitRight ( pRect - > h * 4.0f , & Text , & Image ) ; // always correct ratio for image
2020-09-03 12:08:26 +00:00
// render image
const CMenuImage * pImage = FindMenuImage ( pImageName ) ;
if ( pImage )
{
2022-07-16 13:32:06 +00:00
Graphics ( ) - > TextureSet ( UI ( ) - > HotItem ( ) = = pButtonContainer ? pImage - > m_OrgTexture : pImage - > m_GreyTexture ) ;
2020-09-03 12:08:26 +00:00
Graphics ( ) - > WrapClamp ( ) ;
Graphics ( ) - > QuadsBegin ( ) ;
Graphics ( ) - > SetColor ( 1.0f , 1.0f , 1.0f , 1.0f ) ;
IGraphics : : CQuadItem QuadItem ( Image . x , Image . y , Image . w , Image . h ) ;
Graphics ( ) - > QuadsDrawTL ( & QuadItem , 1 ) ;
Graphics ( ) - > QuadsEnd ( ) ;
Graphics ( ) - > WrapNormal ( ) ;
}
}
2020-09-10 18:14:47 +00:00
Text . HMargin ( pRect - > h > = 20.0f ? 2.0f : 1.0f , & Text ) ;
Text . HMargin ( ( Text . h * FontFactor ) / 2.0f , & Text ) ;
2022-03-11 16:34:48 +00:00
SLabelProperties Props ;
Props . m_AlignVertically = AlignVertically ;
UI ( ) - > DoLabel ( & Text , pText , Text . h * CUI : : ms_FontmodHeight , TEXTALIGN_CENTER , Props ) ;
2020-10-29 00:55:01 +00:00
if ( MouseInsideColorPicker )
return 0 ;
2022-07-16 13:32:06 +00:00
return UI ( ) - > DoButtonLogic ( pButtonContainer , Checked , pRect ) ;
2008-08-27 15:48:50 +00:00
}
2022-11-29 21:23:58 +00:00
void CMenus : : DoButton_KeySelect ( const void * pID , const char * pText , const CUIRect * pRect )
2008-08-27 15:48:50 +00:00
{
2022-08-07 16:12:07 +00:00
pRect - > Draw ( ColorRGBA ( 1 , 1 , 1 , 0.5f * UI ( ) - > ButtonColorMul ( pID ) ) , IGraphics : : CORNER_ALL , 5.0f ) ;
2011-04-01 15:57:04 +00:00
CUIRect Temp ;
pRect - > HMargin ( 1.0f , & Temp ) ;
2022-01-21 15:20:15 +00:00
UI ( ) - > DoLabel ( & Temp , pText , Temp . h * CUI : : ms_FontmodHeight , TEXTALIGN_CENTER ) ;
2008-08-27 15:48:50 +00:00
}
2022-07-16 13:32:06 +00:00
int CMenus : : DoButton_MenuTab ( CButtonContainer * pButtonContainer , const char * pText , int Checked , const CUIRect * pRect , int Corners , SUIAnimator * pAnimator , const ColorRGBA * pDefaultColor , const ColorRGBA * pActiveColor , const ColorRGBA * pHoverColor , float EdgeRounding , int AlignVertically )
2008-08-27 15:48:50 +00:00
{
2022-05-13 18:33:29 +00:00
const bool MouseInside = UI ( ) - > MouseInside ( pRect ) ;
2020-10-26 01:10:55 +00:00
CUIRect Rect = * pRect ;
if ( pAnimator ! = NULL )
{
2022-06-13 16:07:29 +00:00
auto Time = time_get_nanoseconds ( ) ;
2020-10-26 01:10:55 +00:00
2022-05-18 16:00:05 +00:00
if ( pAnimator - > m_Time + 100 ms < Time )
2020-10-26 01:10:55 +00:00
{
pAnimator - > m_Value = pAnimator - > m_Active ? 1 : 0 ;
pAnimator - > m_Time = Time ;
}
pAnimator - > m_Active = Checked | | MouseInside ;
if ( pAnimator - > m_Active )
2022-05-18 16:00:05 +00:00
pAnimator - > m_Value = clamp < float > ( pAnimator - > m_Value + ( Time - pAnimator - > m_Time ) . count ( ) / ( double ) std : : chrono : : nanoseconds ( 100 ms ) . count ( ) , 0 , 1 ) ;
2020-10-26 01:10:55 +00:00
else
2022-05-18 16:00:05 +00:00
pAnimator - > m_Value = clamp < float > ( pAnimator - > m_Value - ( Time - pAnimator - > m_Time ) . count ( ) / ( double ) std : : chrono : : nanoseconds ( 100 ms ) . count ( ) , 0 , 1 ) ;
2020-10-26 01:10:55 +00:00
2020-10-26 02:48:05 +00:00
Rect . w + = pAnimator - > m_Value * pAnimator - > m_WOffset ;
Rect . h + = pAnimator - > m_Value * pAnimator - > m_HOffset ;
Rect . x + = pAnimator - > m_Value * pAnimator - > m_XOffset ;
Rect . y + = pAnimator - > m_Value * pAnimator - > m_YOffset ;
2020-10-26 01:43:34 +00:00
pAnimator - > m_Time = Time ;
2020-10-26 01:10:55 +00:00
}
2009-10-27 14:38:53 +00:00
if ( Checked )
2020-09-16 01:30:03 +00:00
{
ColorRGBA ColorMenuTab = ms_ColorTabbarActive ;
if ( pActiveColor )
ColorMenuTab = * pActiveColor ;
2020-10-26 01:10:55 +00:00
2022-08-07 16:12:07 +00:00
Rect . Draw ( ColorMenuTab , Corners , EdgeRounding ) ;
2020-09-16 01:30:03 +00:00
}
2008-08-27 15:48:50 +00:00
else
2020-09-16 01:30:03 +00:00
{
2022-05-13 18:33:29 +00:00
if ( MouseInside )
2020-09-16 01:30:03 +00:00
{
ColorRGBA HoverColorMenuTab = ms_ColorTabbarHover ;
if ( pHoverColor )
HoverColorMenuTab = * pHoverColor ;
2020-10-26 01:10:55 +00:00
2022-08-07 16:12:07 +00:00
Rect . Draw ( HoverColorMenuTab , Corners , EdgeRounding ) ;
2020-09-16 01:30:03 +00:00
}
else
{
ColorRGBA ColorMenuTab = ms_ColorTabbarInactive ;
if ( pDefaultColor )
ColorMenuTab = * pDefaultColor ;
2020-10-26 01:10:55 +00:00
2022-08-07 16:12:07 +00:00
Rect . Draw ( ColorMenuTab , Corners , EdgeRounding ) ;
2020-09-16 01:30:03 +00:00
}
}
2020-10-26 01:10:55 +00:00
2020-10-26 02:48:05 +00:00
if ( pAnimator ! = NULL )
{
2020-10-26 03:10:58 +00:00
if ( pAnimator - > m_RepositionLabel )
{
Rect . x + = Rect . w - pRect - > w + Rect . x - pRect - > x ;
Rect . y + = Rect . h - pRect - > h + Rect . y - pRect - > y ;
}
2020-12-13 18:31:37 +00:00
2020-10-26 02:48:05 +00:00
if ( ! pAnimator - > m_ScaleLabel )
{
Rect . w = pRect - > w ;
Rect . h = pRect - > h ;
}
}
2020-12-13 18:31:37 +00:00
2022-05-13 18:34:11 +00:00
CUIRect Temp ;
2020-10-26 14:47:26 +00:00
Rect . HMargin ( 2.0f , & Temp ) ;
2022-03-11 16:34:48 +00:00
SLabelProperties Props ;
Props . m_AlignVertically = AlignVertically ;
UI ( ) - > DoLabel ( & Temp , pText , Temp . h * CUI : : ms_FontmodHeight , TEXTALIGN_CENTER , Props ) ;
2011-04-13 18:37:12 +00:00
2022-07-16 13:32:06 +00:00
return UI ( ) - > DoButtonLogic ( pButtonContainer , Checked , pRect ) ;
2008-08-27 15:48:50 +00:00
}
2010-05-29 07:25:38 +00:00
int CMenus : : DoButton_GridHeader ( const void * pID , const char * pText , int Checked , const CUIRect * pRect )
2008-08-27 15:48:50 +00:00
{
2020-08-24 21:23:37 +00:00
if ( Checked = = 2 )
2022-08-07 16:12:07 +00:00
pRect - > Draw ( ColorRGBA ( 1 , 0.98f , 0.5f , 0.55f ) , IGraphics : : CORNER_T , 5.0f ) ;
2020-08-24 21:23:37 +00:00
else if ( Checked )
2022-08-07 16:12:07 +00:00
pRect - > Draw ( ColorRGBA ( 1 , 1 , 1 , 0.5f ) , IGraphics : : CORNER_T , 5.0f ) ;
2009-10-27 14:38:53 +00:00
CUIRect t ;
pRect - > VSplitLeft ( 5.0f , 0 , & t ) ;
2022-01-21 15:20:15 +00:00
UI ( ) - > DoLabel ( & t , pText , pRect - > h * CUI : : ms_FontmodHeight , TEXTALIGN_LEFT ) ;
2022-05-13 22:26:15 +00:00
return UI ( ) - > DoButtonLogic ( pID , Checked , pRect ) ;
2008-08-27 15:48:50 +00:00
}
2010-05-29 07:25:38 +00:00
int CMenus : : DoButton_CheckBox_Common ( const void * pID , const char * pText , const char * pBoxText , const CUIRect * pRect )
2008-08-27 15:48:50 +00:00
{
2009-10-27 14:38:53 +00:00
CUIRect c = * pRect ;
CUIRect t = * pRect ;
2008-08-27 15:48:50 +00:00
c . w = c . h ;
t . x + = c . w ;
t . w - = c . w ;
2009-10-27 14:38:53 +00:00
t . VSplitLeft ( 5.0f , 0 , & t ) ;
2011-04-13 18:37:12 +00:00
2009-10-27 14:38:53 +00:00
c . Margin ( 2.0f , & c ) ;
2022-08-07 16:12:07 +00:00
c . Draw ( ColorRGBA ( 1 , 1 , 1 , 0.25f * UI ( ) - > ButtonColorMul ( pID ) ) , IGraphics : : CORNER_ALL , 3.0f ) ;
2018-03-13 20:59:07 +00:00
2022-05-13 18:35:02 +00:00
const bool Checkable = * pBoxText = = ' X ' ;
2022-03-11 16:34:48 +00:00
SLabelProperties Props ;
Props . m_AlignVertically = 0 ;
2022-05-13 18:35:02 +00:00
if ( Checkable )
2018-03-13 20:59:07 +00:00
{
2020-10-06 10:25:10 +00:00
TextRender ( ) - > SetRenderFlags ( ETextRenderFlags : : TEXT_RENDER_FLAG_ONLY_ADVANCE_WIDTH | ETextRenderFlags : : TEXT_RENDER_FLAG_NO_X_BEARING | ETextRenderFlags : : TEXT_RENDER_FLAG_NO_Y_BEARING | ETextRenderFlags : : TEXT_RENDER_FLAG_NO_OVERSIZE | ETextRenderFlags : : TEXT_RENDER_FLAG_NO_PIXEL_ALIGMENT ) ;
2018-03-13 20:59:07 +00:00
TextRender ( ) - > SetCurFont ( TextRender ( ) - > GetFont ( TEXT_FONT_ICON_FONT ) ) ;
2022-03-19 17:50:33 +00:00
UI ( ) - > DoLabel ( & c , " \xEF \x80 \x8D " , c . h * CUI : : ms_FontmodHeight , TEXTALIGN_CENTER , Props ) ;
2018-03-13 20:59:07 +00:00
TextRender ( ) - > SetCurFont ( NULL ) ;
}
else
2022-03-11 16:34:48 +00:00
UI ( ) - > DoLabel ( & c , pBoxText , c . h * CUI : : ms_FontmodHeight , TEXTALIGN_CENTER , Props ) ;
2018-03-13 20:59:07 +00:00
TextRender ( ) - > SetRenderFlags ( 0 ) ;
2022-01-21 15:20:15 +00:00
UI ( ) - > DoLabel ( & t , pText , c . h * CUI : : ms_FontmodHeight , TEXTALIGN_LEFT ) ;
2018-03-13 20:59:07 +00:00
2022-05-13 22:26:15 +00:00
return UI ( ) - > DoButtonLogic ( pID , 0 , pRect ) ;
2008-08-27 15:48:50 +00:00
}
2022-07-27 01:58:16 +00:00
void CMenus : : DoLaserPreview ( const CUIRect * pRect , const ColorHSLA LaserOutlineColor , const ColorHSLA LaserInnerColor , const int LaserType )
2020-10-29 00:55:01 +00:00
{
ColorRGBA LaserRGB ;
CUIRect Section = * pRect ;
2022-06-30 12:17:07 +00:00
vec2 From = vec2 ( Section . x + 50.0f , Section . y + Section . h / 2.0f ) ;
2020-10-29 00:55:01 +00:00
vec2 Pos = vec2 ( Section . x + Section . w - 10.0f , Section . y + Section . h / 2.0f ) ;
Graphics ( ) - > BlendNormal ( ) ;
Graphics ( ) - > TextureClear ( ) ;
Graphics ( ) - > QuadsBegin ( ) ;
LaserRGB = color_cast < ColorRGBA , ColorHSLA > ( LaserOutlineColor ) ;
ColorRGBA OuterColor ( LaserRGB . r , LaserRGB . g , LaserRGB . b , 1.0f ) ;
Graphics ( ) - > SetColor ( LaserRGB . r , LaserRGB . g , LaserRGB . b , 1.0f ) ;
2020-12-14 01:18:04 +00:00
vec2 Out = vec2 ( 0.0f , - 1.0f ) * ( 3.15f ) ;
2020-10-29 00:55:01 +00:00
IGraphics : : CFreeformItem Freeform ( From . x - Out . x , From . y - Out . y , From . x + Out . x , From . y + Out . y , Pos . x - Out . x , Pos . y - Out . y , Pos . x + Out . x , Pos . y + Out . y ) ;
Graphics ( ) - > QuadsDrawFreeform ( & Freeform , 1 ) ;
LaserRGB = color_cast < ColorRGBA , ColorHSLA > ( LaserInnerColor ) ;
ColorRGBA InnerColor ( LaserRGB . r , LaserRGB . g , LaserRGB . b , 1.0f ) ;
Out = vec2 ( 0.0f , - 1.0f ) * ( 2.25f ) ;
Graphics ( ) - > SetColor ( InnerColor . r , InnerColor . g , InnerColor . b , 1.0f ) ;
Freeform = IGraphics : : CFreeformItem ( From . x - Out . x , From . y - Out . y , From . x + Out . x , From . y + Out . y , Pos . x - Out . x , Pos . y - Out . y , Pos . x + Out . x , Pos . y + Out . y ) ;
Graphics ( ) - > QuadsDrawFreeform ( & Freeform , 1 ) ;
Graphics ( ) - > QuadsEnd ( ) ;
Graphics ( ) - > BlendNormal ( ) ;
int SpriteIndex = time_get ( ) % 3 ;
2022-06-25 08:39:39 +00:00
Graphics ( ) - > TextureSet ( GameClient ( ) - > m_ParticlesSkin . m_aSpriteParticleSplat [ SpriteIndex ] ) ;
2020-10-29 00:55:01 +00:00
Graphics ( ) - > QuadsBegin ( ) ;
Graphics ( ) - > QuadsSetRotation ( time_get ( ) ) ;
Graphics ( ) - > SetColor ( OuterColor . r , OuterColor . g , OuterColor . b , 1.0f ) ;
IGraphics : : CQuadItem QuadItem ( Pos . x , Pos . y , 24 , 24 ) ;
Graphics ( ) - > QuadsDraw ( & QuadItem , 1 ) ;
Graphics ( ) - > SetColor ( InnerColor . r , InnerColor . g , InnerColor . b , 1.0f ) ;
QuadItem = IGraphics : : CQuadItem ( Pos . x , Pos . y , 20 , 20 ) ;
Graphics ( ) - > QuadsDraw ( & QuadItem , 1 ) ;
Graphics ( ) - > QuadsEnd ( ) ;
2022-07-27 01:58:16 +00:00
switch ( LaserType )
{
case LASERTYPE_RIFLE :
Graphics ( ) - > TextureSet ( GameClient ( ) - > m_GameSkin . m_SpriteWeaponLaser ) ;
RenderTools ( ) - > SelectSprite ( SPRITE_WEAPON_LASER_BODY ) ;
Graphics ( ) - > QuadsBegin ( ) ;
Graphics ( ) - > QuadsSetSubset ( 0 , 0 , 1 , 1 ) ;
RenderTools ( ) - > DrawSprite ( Section . x + 30.0f , Section . y + Section . h / 2.0f , 60.0f ) ;
Graphics ( ) - > QuadsEnd ( ) ;
break ;
case LASERTYPE_SHOTGUN :
Graphics ( ) - > TextureSet ( GameClient ( ) - > m_GameSkin . m_SpriteWeaponShotgun ) ;
RenderTools ( ) - > SelectSprite ( SPRITE_WEAPON_SHOTGUN_BODY ) ;
Graphics ( ) - > QuadsBegin ( ) ;
Graphics ( ) - > QuadsSetSubset ( 0 , 0 , 1 , 1 ) ;
RenderTools ( ) - > DrawSprite ( Section . x + 30.0f , Section . y + Section . h / 2.0f , 60.0f ) ;
Graphics ( ) - > QuadsEnd ( ) ;
break ;
default :
Graphics ( ) - > QuadsBegin ( ) ;
Graphics ( ) - > SetColor ( OuterColor . r , OuterColor . g , OuterColor . b , 1.0f ) ;
QuadItem = IGraphics : : CQuadItem ( From . x , From . y , 24 , 24 ) ;
Graphics ( ) - > QuadsDraw ( & QuadItem , 1 ) ;
Graphics ( ) - > SetColor ( InnerColor . r , InnerColor . g , InnerColor . b , 1.0f ) ;
QuadItem = IGraphics : : CQuadItem ( From . x , From . y , 20 , 20 ) ;
Graphics ( ) - > QuadsDraw ( & QuadItem , 1 ) ;
Graphics ( ) - > QuadsEnd ( ) ;
}
2020-10-29 00:55:01 +00:00
}
2023-02-23 20:55:43 +00:00
ColorHSLA CMenus : : DoLine_ColorPicker ( CButtonContainer * pResetID , const float LineSize , const float LabelSize , const float BottomMargin , CUIRect * pMainRect , const char * pText , unsigned int * pColorValue , const ColorRGBA DefaultColor , bool CheckBoxSpacing , int * pCheckBoxValue )
2020-10-29 00:55:01 +00:00
{
2023-02-23 20:55:43 +00:00
CUIRect Section , ColorPickerButton , ResetButton , Label ;
2020-10-29 00:55:01 +00:00
pMainRect - > HSplitTop ( LineSize , & Section , pMainRect ) ;
2023-02-23 20:55:43 +00:00
pMainRect - > HSplitTop ( BottomMargin , nullptr , pMainRect ) ;
2020-10-29 00:55:01 +00:00
2023-02-23 20:55:43 +00:00
if ( CheckBoxSpacing | | pCheckBoxValue ! = nullptr )
2020-10-29 00:55:01 +00:00
{
CUIRect CheckBox ;
2023-02-23 20:55:43 +00:00
Section . VSplitLeft ( Section . h , & CheckBox , & Section ) ;
if ( pCheckBoxValue ! = nullptr )
{
CheckBox . Margin ( 2.0f , & CheckBox ) ;
if ( DoButton_CheckBox ( pCheckBoxValue , " " , * pCheckBoxValue , & CheckBox ) )
* pCheckBoxValue ^ = 1 ;
}
2020-10-29 00:55:01 +00:00
}
2023-02-23 20:55:43 +00:00
Section . VSplitLeft ( 5.0f , nullptr , & Section ) ;
Section . VSplitMid ( & Label , & Section , Section . h ) ;
Section . VSplitRight ( 60.0f , & Section , & ResetButton ) ;
Section . VSplitRight ( 8.0f , & Section , nullptr ) ;
Section . VSplitRight ( Section . h , & Section , & ColorPickerButton ) ;
2020-10-29 00:55:01 +00:00
2022-06-12 08:34:09 +00:00
UI ( ) - > DoLabel ( & Label , pText , LabelSize , TEXTALIGN_LEFT ) ;
2020-10-29 00:55:01 +00:00
2023-02-23 20:55:43 +00:00
ColorHSLA PickedColor = RenderHSLColorPicker ( & ColorPickerButton , pColorValue , false ) ;
2020-10-29 00:55:01 +00:00
2023-02-23 20:55:43 +00:00
ResetButton . HMargin ( 2.0f , & ResetButton ) ;
if ( DoButton_Menu ( pResetID , Localize ( " Reset " ) , 0 , & ResetButton , nullptr , IGraphics : : CORNER_ALL , 8.0f , 0.0f , vec4 ( 1 , 1 , 1 , 0.5f ) , vec4 ( 1 , 1 , 1 , 0.25f ) , 1 , true ) )
2020-10-29 00:55:01 +00:00
{
2023-02-23 20:55:43 +00:00
* pColorValue = color_cast < ColorHSLA > ( DefaultColor ) . Pack ( false ) ;
2020-10-29 00:55:01 +00:00
}
return PickedColor ;
}
int CMenus : : DoButton_CheckBoxAutoVMarginAndSet ( const void * pID , const char * pText , int * pValue , CUIRect * pRect , float VMargin )
{
CUIRect CheckBoxRect ;
pRect - > HSplitTop ( VMargin , & CheckBoxRect , pRect ) ;
int Logic = DoButton_CheckBox_Common ( pID , pText , * pValue ? " X " : " " , & CheckBoxRect ) ;
if ( Logic )
* pValue ^ = 1 ;
return Logic ;
}
2010-05-29 07:25:38 +00:00
int CMenus : : DoButton_CheckBox ( const void * pID , const char * pText , int Checked , const CUIRect * pRect )
2008-08-27 15:48:50 +00:00
{
2020-09-22 16:02:03 +00:00
return DoButton_CheckBox_Common ( pID , pText , Checked ? " X " : " " , pRect ) ;
2008-08-27 15:48:50 +00:00
}
2010-05-29 07:25:38 +00:00
int CMenus : : DoButton_CheckBox_Number ( const void * pID , const char * pText , int Checked , const CUIRect * pRect )
2008-08-27 15:48:50 +00:00
{
2010-05-29 07:25:38 +00:00
char aBuf [ 16 ] ;
str_format ( aBuf , sizeof ( aBuf ) , " %d " , Checked ) ;
return DoButton_CheckBox_Common ( pID , pText , aBuf , pRect ) ;
2008-08-27 15:48:50 +00:00
}
2022-06-30 22:36:32 +00:00
int CMenus : : DoValueSelector ( void * pID , CUIRect * pRect , const char * pLabel , bool UseScroll , int Current , int Min , int Max , int Step , float Scale , bool IsHex , float Round , ColorRGBA * pColor )
2020-12-14 00:51:31 +00:00
{
// logic
static float s_Value ;
2022-06-30 22:36:32 +00:00
static char s_aNumStr [ 64 ] ;
static void * s_pLastTextpID = pID ;
2022-05-13 18:27:03 +00:00
const bool Inside = UI ( ) - > MouseInside ( pRect ) ;
2020-12-14 00:51:31 +00:00
if ( Inside )
UI ( ) - > SetHotItem ( pID ) ;
if ( UI ( ) - > MouseButtonReleased ( 1 ) & & UI ( ) - > HotItem ( ) = = pID )
{
2022-06-30 22:36:32 +00:00
s_pLastTextpID = pID ;
2020-12-14 00:51:31 +00:00
ms_ValueSelectorTextMode = true ;
if ( IsHex )
2022-06-30 22:36:32 +00:00
str_format ( s_aNumStr , sizeof ( s_aNumStr ) , " %06X " , Current ) ;
2020-12-14 00:51:31 +00:00
else
2022-06-30 22:36:32 +00:00
str_format ( s_aNumStr , sizeof ( s_aNumStr ) , " %d " , Current ) ;
2020-12-14 00:51:31 +00:00
}
2022-05-27 08:55:32 +00:00
if ( UI ( ) - > CheckActiveItem ( pID ) )
2020-12-14 00:51:31 +00:00
{
if ( ! UI ( ) - > MouseButton ( 0 ) )
{
//m_LockMouse = false;
2022-05-27 09:59:14 +00:00
UI ( ) - > SetActiveItem ( nullptr ) ;
2020-12-14 00:51:31 +00:00
ms_ValueSelectorTextMode = false ;
}
}
2022-06-30 22:36:32 +00:00
if ( ms_ValueSelectorTextMode & & s_pLastTextpID = = pID )
2020-12-14 00:51:31 +00:00
{
static float s_NumberBoxID = 0 ;
2022-08-07 20:03:34 +00:00
UI ( ) - > DoEditBox ( & s_NumberBoxID , pRect , s_aNumStr , sizeof ( s_aNumStr ) , 10.0f , & s_NumberBoxID , false , IGraphics : : CORNER_ALL ) ;
2020-12-14 00:51:31 +00:00
UI ( ) - > SetActiveItem ( & s_NumberBoxID ) ;
if ( Input ( ) - > KeyIsPressed ( KEY_RETURN ) | | Input ( ) - > KeyIsPressed ( KEY_KP_ENTER ) | |
( ( UI ( ) - > MouseButtonClicked ( 1 ) | | UI ( ) - > MouseButtonClicked ( 0 ) ) & & ! Inside ) )
{
if ( IsHex )
2022-06-30 22:36:32 +00:00
Current = clamp ( str_toint_base ( s_aNumStr , 16 ) , Min , Max ) ;
2020-12-14 00:51:31 +00:00
else
2022-06-30 22:36:32 +00:00
Current = clamp ( str_toint ( s_aNumStr ) , Min , Max ) ;
2020-12-14 00:51:31 +00:00
//m_LockMouse = false;
2022-05-27 09:59:14 +00:00
UI ( ) - > SetActiveItem ( nullptr ) ;
2020-12-14 00:51:31 +00:00
ms_ValueSelectorTextMode = false ;
}
if ( Input ( ) - > KeyIsPressed ( KEY_ESCAPE ) )
{
//m_LockMouse = false;
2022-05-27 09:59:14 +00:00
UI ( ) - > SetActiveItem ( nullptr ) ;
2020-12-14 00:51:31 +00:00
ms_ValueSelectorTextMode = false ;
}
}
else
{
2022-05-27 08:55:32 +00:00
if ( UI ( ) - > CheckActiveItem ( pID ) )
2020-12-14 00:51:31 +00:00
{
if ( UseScroll )
{
if ( UI ( ) - > MouseButton ( 0 ) )
{
float delta = UI ( ) - > MouseDeltaX ( ) ;
2022-11-14 21:50:59 +00:00
if ( Input ( ) - > ShiftIsPressed ( ) )
2020-12-14 00:51:31 +00:00
s_Value + = delta * 0.05f ;
else
s_Value + = delta ;
if ( absolute ( s_Value ) > Scale )
{
int Count = ( int ) ( s_Value / Scale ) ;
2023-02-28 20:31:40 +00:00
s_Value = std : : fmod ( s_Value , Scale ) ;
2020-12-14 00:51:31 +00:00
Current + = Step * Count ;
Current = clamp ( Current , Min , Max ) ;
// Constrain to discrete steps
if ( Count > 0 )
Current = Current / Step * Step ;
else
2023-02-28 20:31:40 +00:00
Current = std : : ceil ( Current / ( float ) Step ) * Step ;
2020-12-14 00:51:31 +00:00
}
}
}
}
else if ( UI ( ) - > HotItem ( ) = = pID )
{
if ( UI ( ) - > MouseButtonClicked ( 0 ) )
{
//m_LockMouse = true;
s_Value = 0 ;
UI ( ) - > SetActiveItem ( pID ) ;
}
}
// render
char aBuf [ 128 ] ;
if ( pLabel [ 0 ] ! = ' \0 ' )
{
if ( IsHex )
str_format ( aBuf , sizeof ( aBuf ) , " %s #%06X " , pLabel , Current ) ;
else
str_format ( aBuf , sizeof ( aBuf ) , " %s %d " , pLabel , Current ) ;
}
else
{
if ( IsHex )
str_format ( aBuf , sizeof ( aBuf ) , " #%06X " , Current ) ;
else
str_format ( aBuf , sizeof ( aBuf ) , " %d " , Current ) ;
}
2022-08-07 16:12:07 +00:00
pRect - > Draw ( * pColor , IGraphics : : CORNER_ALL , Round ) ;
2022-03-11 16:34:48 +00:00
UI ( ) - > DoLabel ( pRect , aBuf , 10 , TEXTALIGN_CENTER ) ;
2020-12-14 00:51:31 +00:00
}
return Current ;
}
2022-06-30 22:36:32 +00:00
int CMenus : : DoKeyReader ( void * pID , const CUIRect * pRect , int Key , int ModifierCombination , int * pNewModifierCombination )
2008-08-27 15:48:50 +00:00
{
// process
2009-10-27 14:38:53 +00:00
static void * pGrabbedID = 0 ;
static bool MouseReleased = true ;
2022-05-13 18:28:57 +00:00
static int s_ButtonUsed = 0 ;
2022-05-13 19:26:35 +00:00
const bool Inside = UI ( ) - > MouseHovered ( pRect ) ;
2009-10-27 14:38:53 +00:00
int NewKey = Key ;
2022-06-30 22:36:32 +00:00
* pNewModifierCombination = ModifierCombination ;
2011-04-13 18:37:12 +00:00
2010-09-12 15:15:09 +00:00
if ( ! UI ( ) - > MouseButton ( 0 ) & & ! UI ( ) - > MouseButton ( 1 ) & & pGrabbedID = = pID )
2009-10-27 14:38:53 +00:00
MouseReleased = true ;
2008-08-27 15:48:50 +00:00
2022-05-27 08:55:32 +00:00
if ( UI ( ) - > CheckActiveItem ( pID ) )
2008-08-27 15:48:50 +00:00
{
2010-05-29 07:25:38 +00:00
if ( m_Binder . m_GotKey )
2008-08-27 15:48:50 +00:00
{
2010-09-12 11:40:24 +00:00
// abort with escape key
if ( m_Binder . m_Key . m_Key ! = KEY_ESCAPE )
2019-04-28 17:22:19 +00:00
{
2010-09-12 11:40:24 +00:00
NewKey = m_Binder . m_Key . m_Key ;
2022-06-30 22:36:32 +00:00
* pNewModifierCombination = m_Binder . m_ModifierCombination ;
2019-04-28 17:22:19 +00:00
}
2010-05-29 07:25:38 +00:00
m_Binder . m_GotKey = false ;
2022-05-27 09:59:14 +00:00
UI ( ) - > SetActiveItem ( nullptr ) ;
2009-10-27 14:38:53 +00:00
MouseReleased = false ;
pGrabbedID = pID ;
2008-08-27 15:48:50 +00:00
}
2010-09-12 15:15:09 +00:00
2022-05-13 18:28:57 +00:00
if ( s_ButtonUsed = = 1 & & ! UI ( ) - > MouseButton ( 1 ) )
2010-09-12 15:15:09 +00:00
{
if ( Inside )
NewKey = 0 ;
2022-05-27 09:59:14 +00:00
UI ( ) - > SetActiveItem ( nullptr ) ;
2010-09-12 15:15:09 +00:00
}
2008-08-27 15:48:50 +00:00
}
2009-10-27 14:38:53 +00:00
else if ( UI ( ) - > HotItem ( ) = = pID )
2008-08-27 15:48:50 +00:00
{
2010-09-12 15:15:09 +00:00
if ( MouseReleased )
2008-10-20 23:10:00 +00:00
{
2010-09-12 15:15:09 +00:00
if ( UI ( ) - > MouseButton ( 0 ) )
{
m_Binder . m_TakeKey = true ;
m_Binder . m_GotKey = false ;
UI ( ) - > SetActiveItem ( pID ) ;
2022-05-13 18:28:57 +00:00
s_ButtonUsed = 0 ;
2010-09-12 15:15:09 +00:00
}
if ( UI ( ) - > MouseButton ( 1 ) )
{
UI ( ) - > SetActiveItem ( pID ) ;
2022-05-13 18:28:57 +00:00
s_ButtonUsed = 1 ;
2010-09-12 15:15:09 +00:00
}
2008-10-20 23:10:00 +00:00
}
2008-08-27 15:48:50 +00:00
}
2011-04-13 18:37:12 +00:00
2009-10-27 14:38:53 +00:00
if ( Inside )
UI ( ) - > SetHotItem ( pID ) ;
2008-08-27 15:48:50 +00:00
// draw
2022-05-27 08:55:32 +00:00
if ( UI ( ) - > CheckActiveItem ( pID ) & & s_ButtonUsed = = 0 )
2022-11-29 21:23:58 +00:00
DoButton_KeySelect ( pID , " ??? " , pRect ) ;
else if ( NewKey = = 0 )
DoButton_KeySelect ( pID , " " , pRect ) ;
2008-08-27 15:48:50 +00:00
else
{
2022-11-29 21:23:58 +00:00
char aBuf [ 64 ] ;
str_format ( aBuf , sizeof ( aBuf ) , " %s%s " , CBinds : : GetKeyBindModifiersName ( * pNewModifierCombination ) , Input ( ) - > KeyName ( NewKey ) ) ;
DoButton_KeySelect ( pID , aBuf , pRect ) ;
2008-08-27 15:48:50 +00:00
}
2022-11-29 21:23:58 +00:00
2009-10-27 14:38:53 +00:00
return NewKey ;
2008-08-27 15:48:50 +00:00
}
2010-05-29 07:25:38 +00:00
int CMenus : : RenderMenubar ( CUIRect r )
2008-08-27 15:48:50 +00:00
{
2010-05-29 07:25:38 +00:00
CUIRect Box = r ;
CUIRect Button ;
2011-04-13 18:37:12 +00:00
2020-09-03 12:08:26 +00:00
m_ActivePage = m_MenuPage ;
2010-05-29 07:25:38 +00:00
int NewPage = - 1 ;
2011-04-13 18:37:12 +00:00
2010-05-29 07:25:38 +00:00
if ( Client ( ) - > State ( ) ! = IClient : : STATE_OFFLINE )
m_ActivePage = m_GamePage ;
2011-04-13 18:37:12 +00:00
2010-05-29 07:25:38 +00:00
if ( Client ( ) - > State ( ) = = IClient : : STATE_OFFLINE )
2008-08-27 15:48:50 +00:00
{
2022-10-02 21:57:28 +00:00
Box . VSplitLeft ( 33.0f , & Button , & Box ) ;
static CButtonContainer s_StartButton ;
TextRender ( ) - > SetCurFont ( TextRender ( ) - > GetFont ( TEXT_FONT_ICON_FONT ) ) ;
TextRender ( ) - > SetRenderFlags ( ETextRenderFlags : : TEXT_RENDER_FLAG_ONLY_ADVANCE_WIDTH | ETextRenderFlags : : TEXT_RENDER_FLAG_NO_X_BEARING | ETextRenderFlags : : TEXT_RENDER_FLAG_NO_Y_BEARING | ETextRenderFlags : : TEXT_RENDER_FLAG_NO_PIXEL_ALIGMENT | ETextRenderFlags : : TEXT_RENDER_FLAG_NO_OVERSIZE ) ;
bool GotNewsOrUpdate = false ;
# if defined(CONF_AUTOUPDATE)
int State = Updater ( ) - > GetCurrentState ( ) ;
bool NeedUpdate = str_comp ( Client ( ) - > LatestVersion ( ) , " 0 " ) ;
if ( State = = IUpdater : : CLEAN & & NeedUpdate )
{
GotNewsOrUpdate = true ;
}
# endif
GotNewsOrUpdate | = ( bool ) g_Config . m_UiUnreadNews ;
ColorRGBA HomeButtonColorAlert ( 0 , 1 , 0 , 0.25f ) ;
ColorRGBA HomeButtonColorAlertHover ( 0 , 1 , 0 , 0.5f ) ;
ColorRGBA * pHomeButtonColor = NULL ;
ColorRGBA * pHomeButtonColorHover = NULL ;
const char * pHomeScreenButtonLabel = " \xEF \x80 \x95 " ;
if ( GotNewsOrUpdate )
{
pHomeScreenButtonLabel = " \xEF \x87 \xAA " ;
pHomeButtonColor = & HomeButtonColorAlert ;
pHomeButtonColorHover = & HomeButtonColorAlertHover ;
}
if ( DoButton_MenuTab ( & s_StartButton , pHomeScreenButtonLabel , false , & Button , IGraphics : : CORNER_T , & m_aAnimatorsSmallPage [ SMALL_TAB_HOME ] , pHomeButtonColor , pHomeButtonColor , pHomeButtonColorHover , 10.0f , 0 ) )
{
m_ShowStart = true ;
}
TextRender ( ) - > SetRenderFlags ( 0 ) ;
TextRender ( ) - > SetCurFont ( NULL ) ;
Box . VSplitLeft ( 10.0f , 0 , & Box ) ;
2020-09-05 21:43:39 +00:00
// offline menus
if ( m_ActivePage = = PAGE_NEWS )
2008-08-27 15:48:50 +00:00
{
2020-09-05 21:43:39 +00:00
Box . VSplitLeft ( 100.0f , & Button , & Box ) ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_NewsButton ;
2022-07-26 19:17:29 +00:00
if ( DoButton_MenuTab ( & s_NewsButton , Localize ( " News " ) , m_ActivePage = = PAGE_NEWS , & Button , IGraphics : : CORNER_T , & m_aAnimatorsBigPage [ BIG_TAB_NEWS ] ) )
2020-09-05 21:43:39 +00:00
{
NewPage = PAGE_NEWS ;
}
2008-08-27 15:48:50 +00:00
}
2020-09-05 21:43:39 +00:00
else if ( m_ActivePage = = PAGE_DEMOS )
2008-08-27 15:48:50 +00:00
{
2020-09-05 21:43:39 +00:00
Box . VSplitLeft ( 100.0f , & Button , & Box ) ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_DemosButton ;
2022-07-26 19:17:29 +00:00
if ( DoButton_MenuTab ( & s_DemosButton , Localize ( " Demos " ) , m_ActivePage = = PAGE_DEMOS , & Button , IGraphics : : CORNER_T , & m_aAnimatorsBigPage [ BIG_TAB_DEMOS ] ) )
2020-09-05 21:43:39 +00:00
{
DemolistPopulate ( ) ;
NewPage = PAGE_DEMOS ;
}
2008-08-27 15:48:50 +00:00
}
2020-09-05 21:43:39 +00:00
else
2008-08-27 15:48:50 +00:00
{
2020-09-05 21:43:39 +00:00
Box . VSplitLeft ( 100.0f , & Button , & Box ) ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_InternetButton ;
2022-07-26 19:17:29 +00:00
if ( DoButton_MenuTab ( & s_InternetButton , Localize ( " Internet " ) , m_ActivePage = = PAGE_INTERNET , & Button , IGraphics : : CORNER_T , & m_aAnimatorsBigPage [ BIG_TAB_INTERNET ] ) )
2020-09-05 21:43:39 +00:00
{
if ( ServerBrowser ( ) - > GetCurrentType ( ) ! = IServerBrowser : : TYPE_INTERNET )
ServerBrowser ( ) - > Refresh ( IServerBrowser : : TYPE_INTERNET ) ;
NewPage = PAGE_INTERNET ;
}
2011-04-13 18:37:12 +00:00
2020-09-05 21:43:39 +00:00
Box . VSplitLeft ( 100.0f , & Button , & Box ) ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_LanButton ;
2022-07-26 19:17:29 +00:00
if ( DoButton_MenuTab ( & s_LanButton , Localize ( " LAN " ) , m_ActivePage = = PAGE_LAN , & Button , IGraphics : : CORNER_T , & m_aAnimatorsBigPage [ BIG_TAB_LAN ] ) )
2017-09-03 15:36:51 +00:00
{
2020-09-05 21:43:39 +00:00
if ( ServerBrowser ( ) - > GetCurrentType ( ) ! = IServerBrowser : : TYPE_LAN )
ServerBrowser ( ) - > Refresh ( IServerBrowser : : TYPE_LAN ) ;
NewPage = PAGE_LAN ;
2017-09-03 15:36:51 +00:00
}
2014-09-13 14:36:25 +00:00
2020-09-05 21:43:39 +00:00
Box . VSplitLeft ( 100.0f , & Button , & Box ) ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_FavoritesButton ;
2022-07-26 19:17:29 +00:00
if ( DoButton_MenuTab ( & s_FavoritesButton , Localize ( " Favorites " ) , m_ActivePage = = PAGE_FAVORITES , & Button , IGraphics : : CORNER_T , & m_aAnimatorsBigPage [ BIG_TAB_FAVORITES ] ) )
2019-03-24 22:15:38 +00:00
{
2020-09-05 21:43:39 +00:00
if ( ServerBrowser ( ) - > GetCurrentType ( ) ! = IServerBrowser : : TYPE_FAVORITES )
ServerBrowser ( ) - > Refresh ( IServerBrowser : : TYPE_FAVORITES ) ;
NewPage = PAGE_FAVORITES ;
2019-03-24 22:15:38 +00:00
}
2020-09-15 16:49:43 +00:00
Box . VSplitLeft ( 90.0f , & Button , & Box ) ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_DDNetButton ;
2022-07-26 19:17:29 +00:00
if ( DoButton_MenuTab ( & s_DDNetButton , " DDNet " , m_ActivePage = = PAGE_DDNET , & Button , IGraphics : : CORNER_T , & m_aAnimatorsBigPage [ BIG_TAB_DDNET ] ) )
2020-09-05 21:43:39 +00:00
{
if ( ServerBrowser ( ) - > GetCurrentType ( ) ! = IServerBrowser : : TYPE_DDNET )
{
Client ( ) - > RequestDDNetInfo ( ) ;
ServerBrowser ( ) - > Refresh ( IServerBrowser : : TYPE_DDNET ) ;
}
NewPage = PAGE_DDNET ;
}
2020-09-15 16:49:43 +00:00
Box . VSplitLeft ( 90.0f , & Button , & Box ) ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_KoGButton ;
2022-07-26 19:17:29 +00:00
if ( DoButton_MenuTab ( & s_KoGButton , " KoG " , m_ActivePage = = PAGE_KOG , & Button , IGraphics : : CORNER_T , & m_aAnimatorsBigPage [ BIG_TAB_KOG ] ) )
2020-09-05 21:43:39 +00:00
{
if ( ServerBrowser ( ) - > GetCurrentType ( ) ! = IServerBrowser : : TYPE_KOG )
{
Client ( ) - > RequestDDNetInfo ( ) ;
ServerBrowser ( ) - > Refresh ( IServerBrowser : : TYPE_KOG ) ;
}
NewPage = PAGE_KOG ;
}
2011-04-13 18:37:12 +00:00
}
2008-08-27 15:48:50 +00:00
}
else
{
2010-05-29 07:25:38 +00:00
// online menus
Box . VSplitLeft ( 90.0f , & Button , & Box ) ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_GameButton ;
2022-07-26 19:17:29 +00:00
if ( DoButton_MenuTab ( & s_GameButton , Localize ( " Game " ) , m_ActivePage = = PAGE_GAME , & Button , IGraphics : : CORNER_TL ) )
2010-05-29 07:25:38 +00:00
NewPage = PAGE_GAME ;
2011-04-06 18:18:31 +00:00
Box . VSplitLeft ( 90.0f , & Button , & Box ) ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_PlayersButton ;
2020-09-22 16:02:03 +00:00
if ( DoButton_MenuTab ( & s_PlayersButton , Localize ( " Players " ) , m_ActivePage = = PAGE_PLAYERS , & Button , 0 ) )
2011-04-06 18:18:31 +00:00
NewPage = PAGE_PLAYERS ;
Box . VSplitLeft ( 130.0f , & Button , & Box ) ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_ServerInfoButton ;
2020-09-22 16:02:03 +00:00
if ( DoButton_MenuTab ( & s_ServerInfoButton , Localize ( " Server info " ) , m_ActivePage = = PAGE_SERVER_INFO , & Button , 0 ) )
2010-05-29 07:25:38 +00:00
NewPage = PAGE_SERVER_INFO ;
2016-04-27 18:14:03 +00:00
Box . VSplitLeft ( 90.0f , & Button , & Box ) ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_NetworkButton ;
2020-09-22 16:02:03 +00:00
if ( DoButton_MenuTab ( & s_NetworkButton , Localize ( " Browser " ) , m_ActivePage = = PAGE_NETWORK , & Button , 0 ) )
2016-04-27 18:14:03 +00:00
NewPage = PAGE_NETWORK ;
2016-04-28 20:40:46 +00:00
{
2022-07-16 13:32:06 +00:00
static CButtonContainer s_GhostButton ;
2019-06-03 19:52:14 +00:00
if ( GameClient ( ) - > m_GameInfo . m_Race )
2016-04-28 20:40:46 +00:00
{
2020-09-05 21:43:39 +00:00
Box . VSplitLeft ( 90.0f , & Button , & Box ) ;
2020-09-10 18:14:47 +00:00
if ( DoButton_MenuTab ( & s_GhostButton , Localize ( " Ghost " ) , m_ActivePage = = PAGE_GHOST , & Button , 0 ) )
2016-04-28 20:40:46 +00:00
NewPage = PAGE_GHOST ;
}
}
2010-05-29 07:25:38 +00:00
2011-04-09 20:45:34 +00:00
Box . VSplitLeft ( 100.0f , & Button , & Box ) ;
2010-05-29 07:25:38 +00:00
Box . VSplitLeft ( 4.0f , 0 , & Box ) ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_CallVoteButton ;
2022-07-26 19:17:29 +00:00
if ( DoButton_MenuTab ( & s_CallVoteButton , Localize ( " Call vote " ) , m_ActivePage = = PAGE_CALLVOTE , & Button , IGraphics : : CORNER_TR ) )
2021-03-14 18:57:21 +00:00
{
2010-05-29 07:25:38 +00:00
NewPage = PAGE_CALLVOTE ;
2021-03-14 18:57:21 +00:00
m_ControlPageOpening = true ;
}
2008-08-27 15:48:50 +00:00
}
2011-04-13 18:37:12 +00:00
2018-03-13 20:59:07 +00:00
TextRender ( ) - > SetCurFont ( TextRender ( ) - > GetFont ( TEXT_FONT_ICON_FONT ) ) ;
2020-10-06 10:25:10 +00:00
TextRender ( ) - > SetRenderFlags ( ETextRenderFlags : : TEXT_RENDER_FLAG_ONLY_ADVANCE_WIDTH | ETextRenderFlags : : TEXT_RENDER_FLAG_NO_X_BEARING | ETextRenderFlags : : TEXT_RENDER_FLAG_NO_Y_BEARING | ETextRenderFlags : : TEXT_RENDER_FLAG_NO_PIXEL_ALIGMENT | ETextRenderFlags : : TEXT_RENDER_FLAG_NO_OVERSIZE ) ;
2018-03-13 20:59:07 +00:00
Box . VSplitRight ( 33.0f , & Box , & Button ) ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_QuitButton ;
2020-09-16 01:30:03 +00:00
ColorRGBA QuitColor ( 1 , 0 , 0 , 0.5f ) ;
2022-07-26 19:17:29 +00:00
if ( DoButton_MenuTab ( & s_QuitButton , " \xEF \x80 \x91 " , 0 , & Button , IGraphics : : CORNER_T , & m_aAnimatorsSmallPage [ SMALL_TAB_QUIT ] , NULL , NULL , & QuitColor , 10.0f , 0 ) )
2019-03-25 19:02:50 +00:00
{
2019-03-29 13:56:02 +00:00
if ( m_pClient - > Editor ( ) - > HasUnsavedData ( ) | | ( Client ( ) - > GetCurrentRaceTime ( ) / 60 > = g_Config . m_ClConfirmQuitTime & & g_Config . m_ClConfirmQuitTime > = 0 ) )
2019-03-25 19:02:50 +00:00
{
m_Popup = POPUP_QUIT ;
}
else
{
Client ( ) - > Quit ( ) ;
}
}
2010-05-29 07:25:38 +00:00
2022-10-02 21:57:28 +00:00
Box . VSplitRight ( 10.0f , & Box , & Button ) ;
2018-03-13 20:59:07 +00:00
Box . VSplitRight ( 33.0f , & Box , & Button ) ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_SettingsButton ;
2019-04-28 17:22:19 +00:00
2022-07-26 19:17:29 +00:00
if ( DoButton_MenuTab ( & s_SettingsButton , " \xEF \x80 \x93 " , m_ActivePage = = PAGE_SETTINGS , & Button , IGraphics : : CORNER_T , & m_aAnimatorsSmallPage [ SMALL_TAB_SETTINGS ] , NULL , NULL , NULL , 10.0f , 0 ) )
2010-05-29 07:25:38 +00:00
NewPage = PAGE_SETTINGS ;
2011-04-13 18:37:12 +00:00
2022-10-02 21:57:28 +00:00
Box . VSplitRight ( 10.0f , & Box , & Button ) ;
2018-03-13 20:59:07 +00:00
Box . VSplitRight ( 33.0f , & Box , & Button ) ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_EditorButton ;
2022-07-26 19:17:29 +00:00
if ( DoButton_MenuTab ( & s_EditorButton , " \xEF \x81 \x84 " , 0 , & Button , IGraphics : : CORNER_T , & m_aAnimatorsSmallPage [ SMALL_TAB_EDITOR ] , NULL , NULL , NULL , 10.0f , 0 ) )
2014-07-08 18:21:19 +00:00
{
g_Config . m_ClEditor = 1 ;
}
2020-09-16 00:14:11 +00:00
if ( Client ( ) - > State ( ) = = IClient : : STATE_OFFLINE )
{
2022-10-02 21:57:28 +00:00
Box . VSplitRight ( 10.0f , & Box , & Button ) ;
2020-09-16 00:14:11 +00:00
Box . VSplitRight ( 33.0f , & Box , & Button ) ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_DemoButton ;
2020-09-15 13:31:04 +00:00
2022-07-26 19:17:29 +00:00
if ( DoButton_MenuTab ( & s_DemoButton , " \xEE \x84 \xB1 " , m_ActivePage = = PAGE_DEMOS , & Button , IGraphics : : CORNER_T , & m_aAnimatorsSmallPage [ SMALL_TAB_DEMOBUTTON ] , NULL , NULL , NULL , 10.0f , 0 ) )
2020-09-16 00:14:11 +00:00
NewPage = PAGE_DEMOS ;
2020-09-15 13:31:04 +00:00
2022-10-02 21:57:28 +00:00
Box . VSplitRight ( 10.0f , & Box , & Button ) ;
2020-09-16 00:14:11 +00:00
Box . VSplitRight ( 33.0f , & Box , & Button ) ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_ServerButton ;
2020-09-15 13:31:04 +00:00
2022-07-26 19:17:29 +00:00
if ( DoButton_MenuTab ( & s_ServerButton , " \xEF \x95 \xBD " , m_ActivePage = = g_Config . m_UiPage , & Button , IGraphics : : CORNER_T , & m_aAnimatorsSmallPage [ SMALL_TAB_SERVER ] , NULL , NULL , NULL , 10.0f , 0 ) )
2020-09-16 00:14:11 +00:00
NewPage = g_Config . m_UiPage ;
}
2020-09-15 13:31:04 +00:00
2018-03-13 20:59:07 +00:00
TextRender ( ) - > SetRenderFlags ( 0 ) ;
TextRender ( ) - > SetCurFont ( NULL ) ;
2010-05-29 07:25:38 +00:00
if ( NewPage ! = - 1 )
2008-08-27 15:48:50 +00:00
{
2010-05-29 07:25:38 +00:00
if ( Client ( ) - > State ( ) = = IClient : : STATE_OFFLINE )
2020-09-03 12:08:26 +00:00
SetMenuPage ( NewPage ) ;
2008-08-27 15:48:50 +00:00
else
2010-05-29 07:25:38 +00:00
m_GamePage = NewPage ;
2008-08-27 15:48:50 +00:00
}
2011-04-13 18:37:12 +00:00
2008-08-27 15:48:50 +00:00
return 0 ;
}
2022-06-23 17:59:38 +00:00
void CMenus : : RenderLoading ( const char * pCaption , const char * pContent , int IncreaseCounter , bool RenderLoadingBar , bool RenderMenuBackgroundMap )
2008-08-27 15:48:50 +00:00
{
2011-12-30 15:02:22 +00:00
// TODO: not supported right now due to separate render thread
2022-05-18 16:00:05 +00:00
static std : : chrono : : nanoseconds LastLoadRender { 0 } ;
2022-04-02 11:37:59 +00:00
auto CurLoadRenderCount = m_LoadCurrent ;
2022-06-23 17:59:38 +00:00
m_LoadCurrent + = IncreaseCounter ;
2022-04-02 11:37:59 +00:00
float Percent = CurLoadRenderCount / ( float ) m_LoadTotal ;
2009-06-07 14:36:54 +00:00
// make sure that we don't render for each little thing we load
// because that will slow down loading if we have vsync
2022-06-13 16:07:29 +00:00
if ( time_get_nanoseconds ( ) - LastLoadRender < std : : chrono : : nanoseconds ( 1 s ) / 60l )
2009-06-07 14:36:54 +00:00
return ;
2011-04-13 18:37:12 +00:00
2022-06-13 16:07:29 +00:00
LastLoadRender = time_get_nanoseconds ( ) ;
2011-04-13 18:37:12 +00:00
2008-08-27 15:48:50 +00:00
// need up date this here to get correct
2019-04-26 23:02:31 +00:00
ms_GuiColor = color_cast < ColorRGBA > ( ColorHSLA ( g_Config . m_UiColor , true ) ) ;
2011-04-13 18:37:12 +00:00
CUIRect Screen = * UI ( ) - > Screen ( ) ;
2022-06-23 17:59:38 +00:00
// some margin around the screen
Screen . Margin ( 10.0f , & Screen ) ;
2021-09-22 19:48:55 +00:00
UI ( ) - > MapScreen ( ) ;
2010-12-14 00:20:47 +00:00
2022-06-23 17:59:38 +00:00
if ( ! RenderMenuBackgroundMap | | ! m_pBackground - > Render ( ) )
2020-09-18 16:45:42 +00:00
{
RenderBackground ( ) ;
}
2008-08-27 15:48:50 +00:00
2022-06-23 17:59:38 +00:00
CUIRect Box = Screen ;
Box . Margin ( 150.0f , & Box ) ;
2008-08-27 15:48:50 +00:00
2009-10-27 14:38:53 +00:00
Graphics ( ) - > BlendNormal ( ) ;
2008-08-27 15:48:50 +00:00
2012-08-12 10:41:50 +00:00
Graphics ( ) - > TextureClear ( ) ;
2022-08-07 16:12:07 +00:00
Box . Draw ( ColorRGBA { 0 , 0 , 0 , 0.50f } , IGraphics : : CORNER_ALL , 15.0f ) ;
2008-08-27 15:48:50 +00:00
2022-06-23 17:59:38 +00:00
CUIRect Part ;
2008-08-27 15:48:50 +00:00
2022-06-23 17:59:38 +00:00
Box . HSplitTop ( 20.f , & Part , & Box ) ;
Box . HSplitTop ( 24.f , & Part , & Box ) ;
Part . VMargin ( 20.f , & Part ) ;
SLabelProperties Props ;
Props . m_MaxWidth = ( int ) Part . w ;
UI ( ) - > DoLabel ( & Part , pCaption , 24.f , TEXTALIGN_CENTER ) ;
Box . HSplitTop ( 20.f , & Part , & Box ) ;
Box . HSplitTop ( 24.f , & Part , & Box ) ;
Part . VMargin ( 20.f , & Part ) ;
Props . m_MaxWidth = ( int ) Part . w ;
UI ( ) - > DoLabel ( & Part , pContent , 20.0f , TEXTALIGN_CENTER ) ;
2008-08-27 15:48:50 +00:00
2022-04-02 11:37:59 +00:00
if ( RenderLoadingBar )
2022-07-09 20:27:35 +00:00
Graphics ( ) - > DrawRect ( Box . x + 40 , Box . y + Box . h - 75 , ( Box . w - 80 ) * Percent , 25 , ColorRGBA ( 1.0f , 1.0f , 1.0f , 0.75f ) , IGraphics : : CORNER_ALL , 5.0f ) ;
2008-08-27 15:48:50 +00:00
2022-04-02 11:37:59 +00:00
Client ( ) - > UpdateAndSwap ( ) ;
2008-08-27 15:48:50 +00:00
}
2010-05-29 07:25:38 +00:00
void CMenus : : RenderNews ( CUIRect MainView )
2008-08-27 15:48:50 +00:00
{
2020-09-03 12:08:26 +00:00
g_Config . m_UiUnreadNews = false ;
2022-08-07 16:12:07 +00:00
MainView . Draw ( ms_ColorTabbarActive , IGraphics : : CORNER_B , 10.0f ) ;
2014-06-05 10:11:41 +00:00
MainView . HSplitTop ( 15.0f , 0 , & MainView ) ;
MainView . VSplitLeft ( 15.0f , 0 , & MainView ) ;
CUIRect Label ;
2019-04-29 20:55:12 +00:00
const char * pStr = Client ( ) - > m_aNews ;
char aLine [ 256 ] ;
while ( ( pStr = str_next_token ( pStr , " \n " , aLine , sizeof ( aLine ) ) ) )
2014-06-05 10:11:41 +00:00
{
2019-04-29 20:55:12 +00:00
const int Len = str_length ( aLine ) ;
2020-09-22 16:02:03 +00:00
if ( Len > 0 & & aLine [ 0 ] = = ' | ' & & aLine [ Len - 1 ] = = ' | ' )
2014-06-05 10:11:41 +00:00
{
MainView . HSplitTop ( 30.0f , & Label , & MainView ) ;
2020-09-22 16:02:03 +00:00
aLine [ Len - 1 ] = ' \0 ' ;
2022-06-12 08:34:09 +00:00
UI ( ) - > DoLabel ( & Label , aLine + 1 , 20.0f , TEXTALIGN_LEFT ) ;
2014-06-05 10:11:41 +00:00
}
else
{
MainView . HSplitTop ( 20.0f , & Label , & MainView ) ;
2022-06-12 08:34:09 +00:00
UI ( ) - > DoLabel ( & Label , aLine , 15.f , TEXTALIGN_LEFT ) ;
2014-06-05 10:11:41 +00:00
}
}
2008-08-27 15:48:50 +00:00
}
2010-05-29 07:25:38 +00:00
void CMenus : : OnInit ( )
2008-08-27 15:48:50 +00:00
{
2010-05-29 07:25:38 +00:00
if ( g_Config . m_ClShowWelcome )
2010-12-12 18:20:30 +00:00
m_Popup = POPUP_LANGUAGE ;
2020-09-03 12:08:26 +00:00
if ( g_Config . m_ClSkipStartMenu )
m_ShowStart = false ;
2010-07-04 14:10:00 +00:00
2022-08-07 20:03:34 +00:00
UI ( ) - > InitInputs ( m_aInputEvents , & m_NumInputEvents ) ;
2021-05-26 13:01:50 +00:00
2021-09-13 21:48:10 +00:00
m_RefreshButton . Init ( UI ( ) , - 1 ) ;
m_ConnectButton . Init ( UI ( ) , - 1 ) ;
2020-10-12 10:29:47 +00:00
2010-07-04 14:10:00 +00:00
Console ( ) - > Chain ( " add_favorite " , ConchainServerbrowserUpdate , this ) ;
2011-03-27 16:05:11 +00:00
Console ( ) - > Chain ( " remove_favorite " , ConchainServerbrowserUpdate , this ) ;
2011-06-26 15:10:13 +00:00
Console ( ) - > Chain ( " add_friend " , ConchainFriendlistUpdate , this ) ;
Console ( ) - > Chain ( " remove_friend " , ConchainFriendlistUpdate , this ) ;
2011-02-27 16:56:03 +00:00
2022-06-26 20:07:10 +00:00
Console ( ) - > Chain ( " snd_enable " , ConchainUpdateMusicState , this ) ;
Console ( ) - > Chain ( " snd_enable_music " , ConchainUpdateMusicState , this ) ;
2021-04-11 12:34:08 +00:00
Console ( ) - > Chain ( " cl_assets_entities " , ConchainAssetsEntities , this ) ;
Console ( ) - > Chain ( " cl_asset_game " , ConchainAssetGame , this ) ;
Console ( ) - > Chain ( " cl_asset_emoticons " , ConchainAssetEmoticons , this ) ;
Console ( ) - > Chain ( " cl_asset_particles " , ConchainAssetParticles , this ) ;
2022-03-15 15:52:41 +00:00
Console ( ) - > Chain ( " cl_asset_hud " , ConchainAssetHud , this ) ;
2022-06-14 17:28:51 +00:00
Console ( ) - > Chain ( " cl_asset_extras " , ConchainAssetExtras , this ) ;
2021-04-11 12:34:08 +00:00
2012-08-12 10:41:50 +00:00
m_TextureBlob = Graphics ( ) - > LoadTexture ( " blob.png " , IStorage : : TYPE_ALL , CImageInfo : : FORMAT_AUTO , 0 ) ;
2011-02-27 16:56:03 +00:00
// setup load amount
2020-09-10 20:56:59 +00:00
const int NumMenuImages = 5 ;
2011-02-27 16:56:03 +00:00
m_LoadCurrent = 0 ;
2022-06-23 17:59:38 +00:00
m_LoadTotal = g_pData - > m_NumImages + NumMenuImages + GameClient ( ) - > ComponentCount ( ) ;
2011-02-27 16:56:03 +00:00
if ( ! g_Config . m_ClThreadsoundloading )
m_LoadTotal + = g_pData - > m_NumSounds ;
2020-09-10 20:56:59 +00:00
2022-04-02 11:37:59 +00:00
m_IsInit = true ;
2020-09-10 20:56:59 +00:00
// load menu images
2022-05-23 20:48:56 +00:00
m_vMenuImages . clear ( ) ;
2020-09-10 20:56:59 +00:00
Storage ( ) - > ListDirectory ( IStorage : : TYPE_ALL , " menuimages " , MenuImageScan , this ) ;
2008-08-27 15:48:50 +00:00
}
2022-10-04 16:40:24 +00:00
void CMenus : : OnConsoleInit ( )
{
auto * pConfigManager = Kernel ( ) - > RequestInterface < IConfigManager > ( ) ;
if ( pConfigManager ! = nullptr )
pConfigManager - > RegisterCallback ( CMenus : : ConfigSaveCallback , this ) ;
Console ( ) - > Register ( " add_favorite_skin " , " s[skin_name] " , CFGFLAG_CLIENT , Con_AddFavoriteSkin , this , " Add a skin as a favorite " ) ;
Console ( ) - > Register ( " remove_favorite_skin " , " s[skin_name] " , CFGFLAG_CLIENT , Con_RemFavoriteSkin , this , " Remove a skin from the favorites " ) ;
}
2022-06-26 20:07:10 +00:00
void CMenus : : ConchainUpdateMusicState ( IConsole : : IResult * pResult , void * pUserData , IConsole : : FCommandCallback pfnCallback , void * pCallbackUserData )
{
pfnCallback ( pResult , pCallbackUserData ) ;
auto * pSelf = ( CMenus * ) pUserData ;
if ( pResult - > NumArguments ( ) )
pSelf - > UpdateMusicState ( ) ;
}
void CMenus : : UpdateMusicState ( )
{
const bool ShouldPlay = Client ( ) - > State ( ) = = IClient : : STATE_OFFLINE & & g_Config . m_SndEnable & & g_Config . m_SndMusic ;
if ( ShouldPlay & & ! m_pClient - > m_Sounds . IsPlaying ( SOUND_MENU ) )
m_pClient - > m_Sounds . Enqueue ( CSounds : : CHN_MUSIC , SOUND_MENU ) ;
else if ( ! ShouldPlay & & m_pClient - > m_Sounds . IsPlaying ( SOUND_MENU ) )
m_pClient - > m_Sounds . Stop ( SOUND_MENU ) ;
}
2022-11-30 21:26:40 +00:00
void CMenus : : PopupMessage ( const char * pTitle , const char * pMessage , const char * pButtonLabel , int NextPopup , FPopupButtonCallback pfnButtonCallback )
2009-06-15 13:16:33 +00:00
{
2010-06-03 20:03:27 +00:00
// reset active item
2022-05-27 09:59:14 +00:00
UI ( ) - > SetActiveItem ( nullptr ) ;
2010-06-03 20:03:27 +00:00
2022-11-30 21:26:40 +00:00
str_copy ( m_aPopupTitle , pTitle ) ;
str_copy ( m_aPopupMessage , pMessage ) ;
str_copy ( m_aPopupButtons [ BUTTON_CONFIRM ] . m_aLabel , pButtonLabel ) ;
m_aPopupButtons [ BUTTON_CONFIRM ] . m_NextPopup = NextPopup ;
m_aPopupButtons [ BUTTON_CONFIRM ] . m_pfnCallback = pfnButtonCallback ;
2020-09-05 14:54:20 +00:00
m_Popup = POPUP_MESSAGE ;
2009-06-15 13:16:33 +00:00
}
2022-11-30 21:26:40 +00:00
void CMenus : : PopupConfirm ( const char * pTitle , const char * pMessage , const char * pConfirmButtonLabel , const char * pCancelButtonLabel ,
FPopupButtonCallback pfnConfirmButtonCallback , int ConfirmNextPopup , FPopupButtonCallback pfnCancelButtonCallback , int CancelNextPopup )
{
// reset active item
UI ( ) - > SetActiveItem ( nullptr ) ;
str_copy ( m_aPopupTitle , pTitle ) ;
str_copy ( m_aPopupMessage , pMessage ) ;
str_copy ( m_aPopupButtons [ BUTTON_CONFIRM ] . m_aLabel , pConfirmButtonLabel ) ;
m_aPopupButtons [ BUTTON_CONFIRM ] . m_NextPopup = ConfirmNextPopup ;
m_aPopupButtons [ BUTTON_CONFIRM ] . m_pfnCallback = pfnConfirmButtonCallback ;
str_copy ( m_aPopupButtons [ BUTTON_CANCEL ] . m_aLabel , pCancelButtonLabel ) ;
m_aPopupButtons [ BUTTON_CANCEL ] . m_NextPopup = CancelNextPopup ;
m_aPopupButtons [ BUTTON_CANCEL ] . m_pfnCallback = pfnCancelButtonCallback ;
m_Popup = POPUP_CONFIRM ;
}
2022-05-18 16:00:05 +00:00
void CMenus : : PopupWarning ( const char * pTopic , const char * pBody , const char * pButton , std : : chrono : : nanoseconds Duration )
2020-08-29 10:49:45 +00:00
{
2022-12-09 15:16:16 +00:00
// no multiline support for console
std : : string BodyStr = pBody ;
while ( BodyStr . find ( ' \n ' ) ! = std : : string : : npos )
BodyStr . replace ( BodyStr . find ( ' \n ' ) , 1 , " " ) ;
dbg_msg ( pTopic , " %s " , BodyStr . c_str ( ) ) ;
2020-10-02 13:43:52 +00:00
2020-08-29 10:49:45 +00:00
// reset active item
2022-05-27 09:59:14 +00:00
UI ( ) - > SetActiveItem ( nullptr ) ;
2020-08-29 10:49:45 +00:00
2022-07-09 16:14:56 +00:00
str_copy ( m_aMessageTopic , pTopic ) ;
str_copy ( m_aMessageBody , pBody ) ;
str_copy ( m_aMessageButton , pButton ) ;
2020-08-29 10:49:45 +00:00
m_Popup = POPUP_WARNING ;
SetActive ( true ) ;
m_PopupWarningDuration = Duration ;
2022-06-13 16:07:29 +00:00
m_PopupWarningLastTime = time_get_nanoseconds ( ) ;
2020-08-29 10:49:45 +00:00
}
bool CMenus : : CanDisplayWarning ( )
{
2020-10-02 13:43:52 +00:00
return m_Popup = = POPUP_NONE ;
2020-08-29 10:49:45 +00:00
}
2009-06-15 13:16:33 +00:00
2020-10-28 02:59:50 +00:00
void CMenus : : RenderColorPicker ( )
{
2022-08-21 11:17:09 +00:00
if ( UI ( ) - > ConsumeHotkey ( CUI : : HOTKEY_ESCAPE ) )
2021-02-01 22:49:42 +00:00
{
ms_ColorPicker . m_Active = false ;
ms_ValueSelectorTextMode = false ;
2022-05-27 09:59:14 +00:00
UI ( ) - > SetActiveItem ( nullptr ) ;
2021-02-01 22:49:42 +00:00
}
2020-10-28 02:59:50 +00:00
if ( ! ms_ColorPicker . m_Active )
return ;
// First check if we should disable color picker
CUIRect PickerRect ;
PickerRect . x = ms_ColorPicker . m_X ;
PickerRect . y = ms_ColorPicker . m_Y ;
PickerRect . w = ms_ColorPicker . ms_Width ;
PickerRect . h = ms_ColorPicker . ms_Height ;
2020-10-29 00:55:01 +00:00
2020-12-14 00:51:31 +00:00
if ( UI ( ) - > MouseButtonClicked ( 0 ) & & ! UI ( ) - > MouseInside ( & PickerRect ) & & ! UI ( ) - > MouseInside ( & ms_ColorPicker . m_AttachedRect ) )
2020-10-28 02:59:50 +00:00
{
ms_ColorPicker . m_Active = false ;
2020-12-14 00:51:31 +00:00
ms_ValueSelectorTextMode = false ;
2022-05-27 09:59:14 +00:00
UI ( ) - > SetActiveItem ( nullptr ) ;
2020-10-28 02:59:50 +00:00
return ;
}
2022-09-17 11:09:40 +00:00
// Prevent activation of UI elements outside of active color picker
if ( UI ( ) - > MouseInside ( & PickerRect ) )
UI ( ) - > SetHotItem ( & ms_ColorPicker ) ;
2020-10-28 02:59:50 +00:00
// Render
2020-12-14 00:51:31 +00:00
ColorRGBA BackgroundColor ( 0.1f , 0.1f , 0.1f , 1.0f ) ;
2022-08-07 16:12:07 +00:00
PickerRect . Draw ( BackgroundColor , 0 , 0 ) ;
2020-10-28 02:59:50 +00:00
2022-09-17 08:50:44 +00:00
CUIRect ColorsArea , HueArea , ValuesHitbox , BottomArea , HueRect , SatRect , ValueRect , HexRect , AlphaRect ;
2020-10-28 02:59:50 +00:00
PickerRect . Margin ( 3 , & ColorsArea ) ;
2020-12-14 00:51:31 +00:00
ColorsArea . HSplitBottom ( ms_ColorPicker . ms_Height - 140.0f , & ColorsArea , & ValuesHitbox ) ;
2020-10-28 02:59:50 +00:00
ColorsArea . VSplitRight ( 20 , & ColorsArea , & HueArea ) ;
2020-12-14 00:51:31 +00:00
BottomArea = ValuesHitbox ;
2020-10-28 02:59:50 +00:00
BottomArea . HSplitTop ( 3 , 0x0 , & BottomArea ) ;
HueArea . VSplitLeft ( 3 , 0x0 , & HueArea ) ;
2022-09-17 08:50:44 +00:00
BottomArea . HSplitTop ( 20 , & HueRect , & BottomArea ) ;
2020-12-14 00:51:31 +00:00
BottomArea . HSplitTop ( 3 , 0x0 , & BottomArea ) ;
constexpr float ValuePadding = 5.0f ;
2022-09-17 08:50:44 +00:00
const float HsvValueWidth = ( HueRect . w - ValuePadding * 2 ) / 3.0f ;
const float HexValueWidth = HsvValueWidth * 2 + ValuePadding ;
2020-12-14 00:51:31 +00:00
2022-09-17 08:50:44 +00:00
HueRect . VSplitLeft ( HsvValueWidth , & HueRect , & SatRect ) ;
SatRect . VSplitLeft ( ValuePadding , 0x0 , & SatRect ) ;
SatRect . VSplitLeft ( HsvValueWidth , & SatRect , & ValueRect ) ;
ValueRect . VSplitLeft ( ValuePadding , 0x0 , & ValueRect ) ;
2020-12-14 00:51:31 +00:00
2022-09-17 08:50:44 +00:00
BottomArea . HSplitTop ( 20 , & HexRect , & BottomArea ) ;
HexRect . VSplitLeft ( HexValueWidth , & HexRect , & AlphaRect ) ;
AlphaRect . VSplitLeft ( ValuePadding , 0x0 , & AlphaRect ) ;
2020-10-28 02:59:50 +00:00
2020-12-14 00:51:31 +00:00
if ( UI ( ) - > MouseButtonReleased ( 1 ) & & ! UI ( ) - > MouseInside ( & ValuesHitbox ) )
{
ms_ColorPicker . m_Active = false ;
ms_ValueSelectorTextMode = false ;
2022-05-27 09:59:14 +00:00
UI ( ) - > SetActiveItem ( nullptr ) ;
2020-12-14 00:51:31 +00:00
return ;
}
ColorRGBA BlackColor ( 0 , 0 , 0 , 0.5f ) ;
2022-08-07 16:12:07 +00:00
HueArea . Draw ( BlackColor , 0 , 0 ) ;
2020-10-28 02:59:50 +00:00
HueArea . Margin ( 1 , & HueArea ) ;
2022-08-07 16:12:07 +00:00
ColorsArea . Draw ( BlackColor , 0 , 0 ) ;
2020-10-28 02:59:50 +00:00
ColorsArea . Margin ( 1 , & ColorsArea ) ;
2020-12-14 00:51:31 +00:00
ColorHSVA PickerColorHSV ( ms_ColorPicker . m_HSVColor ) ;
2022-09-17 08:50:44 +00:00
unsigned H = ( unsigned ) ( PickerColorHSV . x * 255.0f ) ;
unsigned S = ( unsigned ) ( PickerColorHSV . y * 255.0f ) ;
unsigned V = ( unsigned ) ( PickerColorHSV . z * 255.0f ) ;
2020-10-28 02:59:50 +00:00
// Color Area
2022-09-17 08:50:44 +00:00
vec4 TL = color_cast < ColorRGBA > ( ColorHSVA ( PickerColorHSV . x , 0.0f , 1.0f ) ) ;
vec4 TR = color_cast < ColorRGBA > ( ColorHSVA ( PickerColorHSV . x , 1.0f , 1.0f ) ) ;
vec4 BL = color_cast < ColorRGBA > ( ColorHSVA ( PickerColorHSV . x , 0.0f , 1.0f ) ) ;
vec4 BR = color_cast < ColorRGBA > ( ColorHSVA ( PickerColorHSV . x , 1.0f , 1.0f ) ) ;
2020-10-28 02:59:50 +00:00
2022-08-07 16:12:07 +00:00
ColorsArea . Draw4 ( TL , TR , BL , BR , IGraphics : : CORNER_NONE , 0.0f ) ;
2020-10-28 02:59:50 +00:00
TL = vec4 ( 0.0f , 0.0f , 0.0f , 0.0f ) ;
TR = vec4 ( 0.0f , 0.0f , 0.0f , 0.0f ) ;
BL = vec4 ( 0.0f , 0.0f , 0.0f , 1.0f ) ;
BR = vec4 ( 0.0f , 0.0f , 0.0f , 1.0f ) ;
2022-08-07 16:12:07 +00:00
ColorsArea . Draw4 ( TL , TR , BL , BR , IGraphics : : CORNER_NONE , 0.0f ) ;
2020-10-28 02:59:50 +00:00
// Hue Area
static const float s_aColorIndices [ 7 ] [ 3 ] = {
{ 1.0f , 0.0f , 0.0f } , // red
{ 1.0f , 0.0f , 1.0f } , // magenta
{ 0.0f , 0.0f , 1.0f } , // blue
{ 0.0f , 1.0f , 1.0f } , // cyan
{ 0.0f , 1.0f , 0.0f } , // green
{ 1.0f , 1.0f , 0.0f } , // yellow
{ 1.0f , 0.0f , 0.0f } // red
} ;
float HuePickerOffset = HueArea . h / 6.0f ;
CUIRect HuePartialArea = HueArea ;
HuePartialArea . h = HuePickerOffset ;
for ( int j = 0 ; j < 6 ; j + + )
{
TL = vec4 ( s_aColorIndices [ j ] [ 0 ] , s_aColorIndices [ j ] [ 1 ] , s_aColorIndices [ j ] [ 2 ] , 1.0f ) ;
BL = vec4 ( s_aColorIndices [ j + 1 ] [ 0 ] , s_aColorIndices [ j + 1 ] [ 1 ] , s_aColorIndices [ j + 1 ] [ 2 ] , 1.0f ) ;
HuePartialArea . y = HueArea . y + HuePickerOffset * j ;
2022-08-07 16:12:07 +00:00
HuePartialArea . Draw4 ( TL , TL , BL , BL , IGraphics : : CORNER_NONE , 0.0f ) ;
2020-10-28 02:59:50 +00:00
}
2022-09-17 08:50:44 +00:00
// Editboxes Area
2020-12-14 00:51:31 +00:00
ColorRGBA EditboxBackground ( 0 , 0 , 0 , 0.4f ) ;
2022-09-17 08:50:44 +00:00
static int s_aValueSelectorIds [ 4 ] ;
2020-12-14 00:51:31 +00:00
2022-09-17 08:50:44 +00:00
H = DoValueSelector ( & s_aValueSelectorIds [ 0 ] , & HueRect , " H: " , true , H , 0 , 255 , 1 , 1 , false , 5.0f , & EditboxBackground ) ;
S = DoValueSelector ( & s_aValueSelectorIds [ 1 ] , & SatRect , " S: " , true , S , 0 , 255 , 1 , 1 , false , 5.0f , & EditboxBackground ) ;
V = DoValueSelector ( & s_aValueSelectorIds [ 2 ] , & ValueRect , " V: " , true , V , 0 , 255 , 1 , 1 , false , 5.0f , & EditboxBackground ) ;
2020-10-28 02:59:50 +00:00
2022-09-17 08:50:44 +00:00
PickerColorHSV = ColorHSVA ( H / 255.0f , S / 255.0f , V / 255.0f ) ;
2020-10-28 02:59:50 +00:00
2022-09-17 08:50:44 +00:00
unsigned int Hex = color_cast < ColorRGBA > ( PickerColorHSV ) . Pack ( false ) ;
unsigned int NewHex = DoValueSelector ( & s_aValueSelectorIds [ 3 ] , & HexRect , " HEX: " , false , Hex , 0 , 0xFFFFFF , 1 , 1 , true , 5.0f , & EditboxBackground ) ;
2020-12-14 00:51:31 +00:00
2022-09-17 08:50:44 +00:00
if ( Hex ! = NewHex )
PickerColorHSV = color_cast < ColorHSVA > ( ColorRGBA ( NewHex ) ) ;
2020-12-14 00:51:31 +00:00
// TODO : ALPHA SUPPORT
2022-09-17 08:50:44 +00:00
UI ( ) - > DoLabel ( & AlphaRect , " A: 255 " , 10 , TEXTALIGN_CENTER ) ;
AlphaRect . Draw ( ColorRGBA ( 0 , 0 , 0 , 0.65f ) , IGraphics : : CORNER_ALL , 5.0f ) ;
2020-10-28 02:59:50 +00:00
// Logic
float PickerX , PickerY ;
2022-09-17 08:50:44 +00:00
static int s_ColorPickerId = 0 ;
static int s_HuePickerId = 0 ;
2020-12-14 01:49:24 +00:00
2022-09-17 08:50:44 +00:00
if ( UI ( ) - > DoPickerLogic ( & s_ColorPickerId , & ColorsArea , & PickerX , & PickerY ) )
2020-10-28 02:59:50 +00:00
{
2020-12-14 00:51:31 +00:00
PickerColorHSV . y = PickerX / ColorsArea . w ;
PickerColorHSV . z = 1.0f - PickerY / ColorsArea . h ;
2020-10-28 02:59:50 +00:00
}
2022-09-17 08:50:44 +00:00
if ( UI ( ) - > DoPickerLogic ( & s_HuePickerId , & HueArea , & PickerX , & PickerY ) )
2020-12-14 00:51:31 +00:00
PickerColorHSV . x = 1.0f - PickerY / HueArea . h ;
2020-10-28 02:59:50 +00:00
// Marker Color Area
2020-12-14 00:51:31 +00:00
float MarkerX = ColorsArea . x + ColorsArea . w * PickerColorHSV . y ;
float MarkerY = ColorsArea . y + ColorsArea . h * ( 1.0f - PickerColorHSV . z ) ;
2020-10-28 02:59:50 +00:00
2022-09-17 08:50:44 +00:00
const float MarkerOutlineInd = PickerColorHSV . z > 0.5f ? 0.0f : 1.0f ;
2020-10-28 02:59:50 +00:00
ColorRGBA MarkerOutline ( MarkerOutlineInd , MarkerOutlineInd , MarkerOutlineInd , 1.0f ) ;
2020-12-14 00:51:31 +00:00
Graphics ( ) - > TextureClear ( ) ;
2020-10-28 02:59:50 +00:00
Graphics ( ) - > QuadsBegin ( ) ;
Graphics ( ) - > SetColor ( MarkerOutline ) ;
2022-07-09 11:16:12 +00:00
Graphics ( ) - > DrawCircle ( MarkerX , MarkerY , 4.5f , 32 ) ;
2022-09-17 08:50:44 +00:00
Graphics ( ) - > SetColor ( color_cast < ColorRGBA > ( PickerColorHSV ) ) ;
2022-07-09 11:16:12 +00:00
Graphics ( ) - > DrawCircle ( MarkerX , MarkerY , 3.5f , 32 ) ;
2020-10-28 02:59:50 +00:00
Graphics ( ) - > QuadsEnd ( ) ;
2020-10-29 00:55:01 +00:00
// Marker Hue Area
CUIRect HueMarker ;
HueArea . Margin ( - 2.5f , & HueMarker ) ;
2020-12-14 00:51:31 +00:00
HueMarker . h = 6.5f ;
HueMarker . y = ( HueArea . y + HueArea . h * ( 1.0f - PickerColorHSV . x ) ) - HueMarker . h / 2.0f ;
2020-10-29 00:55:01 +00:00
2022-09-17 08:50:44 +00:00
ColorRGBA HueMarkerColor = color_cast < ColorRGBA > ( ColorHSVA ( PickerColorHSV . x , 1 , 1 , 1 ) ) ;
const float HueMarkerOutlineColor = PickerColorHSV . x > 0.75f ? 1.0f : 0.0f ;
ColorRGBA HueMarkerOutline ( HueMarkerOutlineColor , HueMarkerOutlineColor , HueMarkerOutlineColor , 1 ) ;
2020-10-29 00:55:01 +00:00
2022-08-07 16:12:07 +00:00
HueMarker . Draw ( HueMarkerOutline , IGraphics : : CORNER_ALL , 1.2f ) ;
2020-12-14 00:51:31 +00:00
HueMarker . Margin ( 1.2f , & HueMarker ) ;
2022-08-07 16:12:07 +00:00
HueMarker . Draw ( HueMarkerColor , IGraphics : : CORNER_ALL , 1.2f ) ;
2020-10-29 00:55:01 +00:00
2020-12-14 00:51:31 +00:00
ms_ColorPicker . m_HSVColor = PickerColorHSV . Pack ( false ) ;
2022-09-17 08:50:44 +00:00
* ms_ColorPicker . m_pColor = color_cast < ColorHSLA > ( PickerColorHSV ) . Pack ( false ) ;
2020-10-28 02:59:50 +00:00
}
2010-05-29 07:25:38 +00:00
int CMenus : : Render ( )
2008-08-27 15:48:50 +00:00
{
2020-08-29 10:49:45 +00:00
if ( Client ( ) - > State ( ) = = IClient : : STATE_DEMOPLAYBACK & & m_Popup = = POPUP_NONE )
return 0 ;
2011-04-13 18:37:12 +00:00
CUIRect Screen = * UI ( ) - > Screen ( ) ;
2021-09-22 19:48:55 +00:00
UI ( ) - > MapScreen ( ) ;
2022-08-07 20:03:34 +00:00
UI ( ) - > ResetMouseSlow ( ) ;
2016-05-03 13:11:52 +00:00
2016-06-03 17:50:49 +00:00
static int s_Frame = 0 ;
if ( s_Frame = = 0 )
{
2020-09-03 12:08:26 +00:00
m_MenuPage = g_Config . m_UiPage ;
2016-06-03 17:50:49 +00:00
s_Frame + + ;
}
else if ( s_Frame = = 1 )
2008-08-27 15:48:50 +00:00
{
2022-06-26 20:07:10 +00:00
UpdateMusicState ( ) ;
2016-06-03 17:50:49 +00:00
s_Frame + + ;
2014-09-20 14:20:27 +00:00
2022-09-23 17:59:18 +00:00
RefreshBrowserTab ( g_Config . m_UiPage ) ;
2010-05-29 07:25:38 +00:00
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 ) ;
2014-09-13 14:36:25 +00:00
else if ( g_Config . m_UiPage = = PAGE_DDNET )
ServerBrowser ( ) - > Refresh ( IServerBrowser : : TYPE_DDNET ) ;
2019-03-24 22:15:38 +00:00
else if ( g_Config . m_UiPage = = PAGE_KOG )
ServerBrowser ( ) - > Refresh ( IServerBrowser : : TYPE_KOG ) ;
2008-08-27 15:48:50 +00:00
}
2011-04-13 18:37:12 +00:00
2020-08-29 10:49:45 +00:00
if ( Client ( ) - > State ( ) > = IClient : : STATE_ONLINE )
2008-08-27 15:48:50 +00:00
{
2010-05-29 07:25:38 +00:00
ms_ColorTabbarInactive = ms_ColorTabbarInactiveIngame ;
ms_ColorTabbarActive = ms_ColorTabbarActiveIngame ;
2020-09-16 01:30:03 +00:00
ms_ColorTabbarHover = ms_ColorTabbarHoverIngame ;
2008-08-27 15:48:50 +00:00
}
else
{
2020-09-18 16:45:42 +00:00
if ( ! m_pBackground - > Render ( ) )
{
RenderBackground ( ) ;
}
2010-05-29 07:25:38 +00:00
ms_ColorTabbarInactive = ms_ColorTabbarInactiveOutgame ;
ms_ColorTabbarActive = ms_ColorTabbarActiveOutgame ;
2020-09-16 01:30:03 +00:00
ms_ColorTabbarHover = ms_ColorTabbarHoverOutgame ;
2008-08-27 15:48:50 +00:00
}
2011-04-13 18:37:12 +00:00
2010-05-29 07:25:38 +00:00
CUIRect TabBar ;
CUIRect MainView ;
2008-08-27 15:48:50 +00:00
// some margin around the screen
2010-05-29 07:25:38 +00:00
Screen . Margin ( 10.0f , & Screen ) ;
2011-04-13 18:37:12 +00:00
2011-01-17 12:28:15 +00:00
static bool s_SoundCheck = false ;
if ( ! s_SoundCheck & & m_Popup = = POPUP_NONE )
{
if ( Client ( ) - > SoundInitFailed ( ) )
2022-11-30 22:09:45 +00:00
PopupMessage ( Localize ( " Sound error " ) , Localize ( " The audio device couldn't be initialised. " ) , Localize ( " Ok " ) ) ;
2011-01-17 12:28:15 +00:00
s_SoundCheck = true ;
}
2010-05-29 07:25:38 +00:00
if ( m_Popup = = POPUP_NONE )
2008-08-27 15:48:50 +00:00
{
2022-04-04 08:15:53 +00:00
if ( m_JoinTutorial & & ! Client ( ) - > InfoTaskRunning ( ) & & ! ServerBrowser ( ) - > IsGettingServerlist ( ) )
2022-02-21 00:04:49 +00:00
{
m_JoinTutorial = false ;
const char * pAddr = ServerBrowser ( ) - > GetTutorialServer ( ) ;
if ( pAddr )
Client ( ) - > Connect ( pAddr ) ;
}
2020-09-03 12:08:26 +00:00
if ( m_ShowStart & & Client ( ) - > State ( ) = = IClient : : STATE_OFFLINE )
2020-09-18 16:45:42 +00:00
{
m_pBackground - > ChangePosition ( CMenuBackground : : POS_START ) ;
2020-09-03 12:08:26 +00:00
RenderStartMenu ( Screen ) ;
2020-09-18 16:45:42 +00:00
}
2020-09-03 12:08:26 +00:00
else
2008-10-01 18:40:09 +00:00
{
2020-09-03 12:08:26 +00:00
Screen . HSplitTop ( 24.0f , & TabBar , & MainView ) ;
2022-08-21 11:17:09 +00:00
if ( Client ( ) - > State ( ) = = IClient : : STATE_OFFLINE & & UI ( ) - > ConsumeHotkey ( CUI : : HOTKEY_ESCAPE ) )
2020-09-03 12:08:26 +00:00
{
m_ShowStart = true ;
}
2011-04-13 18:37:12 +00:00
2020-09-03 12:08:26 +00:00
// render news
if ( m_MenuPage < PAGE_NEWS | | m_MenuPage > PAGE_SETTINGS | | ( Client ( ) - > State ( ) = = IClient : : STATE_OFFLINE & & m_MenuPage > = PAGE_GAME & & m_MenuPage < = PAGE_CALLVOTE ) )
{
ServerBrowser ( ) - > Refresh ( IServerBrowser : : TYPE_INTERNET ) ;
SetMenuPage ( PAGE_INTERNET ) ;
}
// render current page
if ( Client ( ) - > State ( ) ! = IClient : : STATE_OFFLINE )
{
if ( m_GamePage = = PAGE_GAME )
2022-10-06 16:38:31 +00:00
{
2020-09-03 12:08:26 +00:00
RenderGame ( MainView ) ;
2022-10-06 16:38:31 +00:00
RenderIngameHint ( ) ;
}
2020-09-03 12:08:26 +00:00
else if ( m_GamePage = = PAGE_PLAYERS )
2022-10-06 16:38:31 +00:00
{
2020-09-03 12:08:26 +00:00
RenderPlayers ( MainView ) ;
2022-10-06 16:38:31 +00:00
}
2020-09-03 12:08:26 +00:00
else if ( m_GamePage = = PAGE_SERVER_INFO )
2022-10-06 16:38:31 +00:00
{
2020-09-03 12:08:26 +00:00
RenderServerInfo ( MainView ) ;
2022-10-06 16:38:31 +00:00
}
2020-09-03 12:08:26 +00:00
else if ( m_GamePage = = PAGE_NETWORK )
2022-10-06 16:38:31 +00:00
{
2020-09-03 12:08:26 +00:00
RenderInGameNetwork ( MainView ) ;
2022-10-06 16:38:31 +00:00
}
2020-09-03 12:08:26 +00:00
else if ( m_GamePage = = PAGE_GHOST )
2022-10-06 16:38:31 +00:00
{
2020-09-03 12:08:26 +00:00
RenderGhost ( MainView ) ;
2022-10-06 16:38:31 +00:00
}
2020-09-03 12:08:26 +00:00
else if ( m_GamePage = = PAGE_CALLVOTE )
2022-10-06 16:38:31 +00:00
{
2020-09-03 12:08:26 +00:00
RenderServerControl ( MainView ) ;
2022-10-06 16:38:31 +00:00
}
2020-09-03 12:08:26 +00:00
else if ( m_GamePage = = PAGE_SETTINGS )
2022-10-06 16:38:31 +00:00
{
2020-09-03 12:08:26 +00:00
RenderSettings ( MainView ) ;
2022-10-06 16:38:31 +00:00
}
2020-09-03 12:08:26 +00:00
}
else if ( m_MenuPage = = PAGE_NEWS )
2020-09-18 16:45:42 +00:00
{
m_pBackground - > ChangePosition ( CMenuBackground : : POS_NEWS ) ;
2020-09-03 12:08:26 +00:00
RenderNews ( MainView ) ;
2020-09-18 16:45:42 +00:00
}
2020-09-03 12:08:26 +00:00
else if ( m_MenuPage = = PAGE_INTERNET )
2020-09-18 16:45:42 +00:00
{
2020-09-26 07:37:35 +00:00
m_pBackground - > ChangePosition ( CMenuBackground : : POS_BROWSER_INTERNET ) ;
2020-09-03 12:08:26 +00:00
RenderServerbrowser ( MainView ) ;
2020-09-18 16:45:42 +00:00
}
2020-09-03 12:08:26 +00:00
else if ( m_MenuPage = = PAGE_LAN )
2020-09-18 16:45:42 +00:00
{
2020-09-26 07:37:35 +00:00
m_pBackground - > ChangePosition ( CMenuBackground : : POS_BROWSER_LAN ) ;
2020-09-03 12:08:26 +00:00
RenderServerbrowser ( MainView ) ;
2020-09-18 16:45:42 +00:00
}
2020-09-03 12:08:26 +00:00
else if ( m_MenuPage = = PAGE_DEMOS )
2020-09-18 16:45:42 +00:00
{
m_pBackground - > ChangePosition ( CMenuBackground : : POS_DEMOS ) ;
2020-09-03 12:08:26 +00:00
RenderDemoList ( MainView ) ;
2020-09-18 16:45:42 +00:00
}
2020-09-03 12:08:26 +00:00
else if ( m_MenuPage = = PAGE_FAVORITES )
2020-09-18 16:45:42 +00:00
{
2020-09-26 07:37:35 +00:00
m_pBackground - > ChangePosition ( CMenuBackground : : POS_BROWSER_FAVORITES ) ;
2020-09-03 12:08:26 +00:00
RenderServerbrowser ( MainView ) ;
2020-09-18 16:45:42 +00:00
}
2020-09-03 12:08:26 +00:00
else if ( m_MenuPage = = PAGE_DDNET )
2020-09-18 16:45:42 +00:00
{
2020-09-26 07:37:35 +00:00
m_pBackground - > ChangePosition ( CMenuBackground : : POS_BROWSER_CUSTOM0 ) ;
2020-09-03 12:08:26 +00:00
RenderServerbrowser ( MainView ) ;
2020-09-18 16:45:42 +00:00
}
2020-09-03 12:08:26 +00:00
else if ( m_MenuPage = = PAGE_KOG )
2020-09-18 16:45:42 +00:00
{
2020-09-26 07:37:35 +00:00
m_pBackground - > ChangePosition ( CMenuBackground : : POS_BROWSER_CUSTOM0 + 1 ) ;
2020-09-03 12:08:26 +00:00
RenderServerbrowser ( MainView ) ;
2020-09-18 16:45:42 +00:00
}
2020-09-03 12:08:26 +00:00
else if ( m_MenuPage = = PAGE_SETTINGS )
2010-05-29 07:25:38 +00:00
RenderSettings ( MainView ) ;
2020-10-28 02:59:50 +00:00
2020-09-03 12:08:26 +00:00
// do tab bar
RenderMenubar ( TabBar ) ;
}
2008-08-27 15:48:50 +00:00
}
else
{
// make sure that other windows doesn't do anything funnay!
2009-10-27 14:38:53 +00:00
//UI()->SetHotItem(0);
2022-05-27 09:59:14 +00:00
//UI()->SetActiveItem(nullptr);
2020-06-26 16:17:20 +00:00
char aBuf [ 1536 ] ;
2010-05-29 07:25:38 +00:00
const char * pTitle = " " ;
const char * pExtraText = " " ;
const char * pButtonText = " " ;
int ExtraAlign = 0 ;
2022-07-11 00:13:56 +00:00
bool UseIpLabel = false ;
2011-04-13 18:37:12 +00:00
2021-09-25 07:50:11 +00:00
ColorRGBA BgColor = ColorRGBA ( 0.0f , 0.0f , 0.0f , 0.5f ) ;
2022-11-30 21:26:40 +00:00
if ( m_Popup = = POPUP_MESSAGE | | m_Popup = = POPUP_CONFIRM )
2009-06-15 13:16:33 +00:00
{
2022-11-30 21:26:40 +00:00
pTitle = m_aPopupTitle ;
pExtraText = m_aPopupMessage ;
2009-06-15 13:16:33 +00:00
}
2010-05-29 07:25:38 +00:00
else if ( m_Popup = = POPUP_CONNECTING )
2008-08-27 15:48:50 +00:00
{
2010-05-29 07:25:38 +00:00
pTitle = Localize ( " Connecting to " ) ;
2022-07-11 00:13:56 +00:00
UseIpLabel = true ;
2010-05-29 07:25:38 +00:00
pButtonText = Localize ( " Abort " ) ;
2022-05-15 19:59:17 +00:00
if ( Client ( ) - > State ( ) = = IClient : : STATE_CONNECTING & & time_get ( ) - Client ( ) - > StateStartTime ( ) > time_freq ( ) )
{
2022-06-01 10:09:22 +00:00
int Connectivity = Client ( ) - > UdpConnectivity ( Client ( ) - > ConnectNetTypes ( ) ) ;
2022-05-15 19:59:17 +00:00
switch ( Connectivity )
{
case IClient : : CONNECTIVITY_UNKNOWN :
break ;
case IClient : : CONNECTIVITY_CHECKING :
2022-07-11 00:13:56 +00:00
pExtraText = Localize ( " Trying to determine UDP connectivity... " ) ;
2022-05-15 19:59:17 +00:00
break ;
case IClient : : CONNECTIVITY_UNREACHABLE :
2022-07-11 00:13:56 +00:00
pExtraText = Localize ( " UDP seems to be filtered. " ) ;
2022-05-15 19:59:17 +00:00
break ;
case IClient : : CONNECTIVITY_DIFFERING_UDP_TCP_IP_ADDRESSES :
2022-07-11 00:13:56 +00:00
pExtraText = Localize ( " UDP and TCP IP addresses seem to be different. Try disabling VPN, proxy or network accelerators. " ) ;
2022-05-15 19:59:17 +00:00
break ;
case IClient : : CONNECTIVITY_REACHABLE :
2022-07-11 00:13:56 +00:00
pExtraText = Localize ( " No answer from server yet. " ) ;
2022-05-15 19:59:17 +00:00
break ;
}
}
else if ( Client ( ) - > MapDownloadTotalsize ( ) > 0 )
2008-08-27 15:48:50 +00:00
{
2014-08-15 23:06:17 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " %s: %s " , Localize ( " Downloading map " ) , Client ( ) - > MapDownloadName ( ) ) ;
pTitle = aBuf ;
2022-07-11 00:13:56 +00:00
UseIpLabel = false ;
2008-08-27 15:48:50 +00:00
}
2022-06-23 17:59:38 +00:00
else if ( Client ( ) - > State ( ) = = IClient : : STATE_LOADING )
{
2022-07-11 00:13:56 +00:00
UseIpLabel = false ;
2022-06-23 17:59:38 +00:00
if ( Client ( ) - > LoadingStateDetail ( ) = = IClient : : LOADING_STATE_DETAIL_INITIAL )
{
pTitle = Localize ( " Connected " ) ;
pExtraText = Localize ( " Getting game info " ) ;
}
else if ( Client ( ) - > LoadingStateDetail ( ) = = IClient : : LOADING_STATE_DETAIL_LOADING_MAP )
{
pTitle = Localize ( " Connected " ) ;
pExtraText = Localize ( " Loading map file from storage " ) ;
}
else if ( Client ( ) - > LoadingStateDetail ( ) = = IClient : : LOADING_STATE_DETAIL_SENDING_READY )
{
pTitle = Localize ( " Connected " ) ;
pExtraText = Localize ( " Requesting to join the game " ) ;
}
else if ( Client ( ) - > LoadingStateDetail ( ) = = IClient : : LOADING_STATE_DETAIL_GETTING_READY )
{
pTitle = Localize ( " Connected " ) ;
2022-07-14 20:36:06 +00:00
pExtraText = Localize ( " Sending initial client info " ) ;
2022-06-23 17:59:38 +00:00
}
}
2008-08-27 15:48:50 +00:00
}
2018-03-13 20:59:07 +00:00
else if ( m_Popup = = POPUP_DISCONNECTED )
2008-08-27 15:48:50 +00:00
{
2010-05-29 07:25:38 +00:00
pTitle = Localize ( " Disconnected " ) ;
pExtraText = Client ( ) - > ErrorString ( ) ;
pButtonText = Localize ( " Ok " ) ;
2016-05-04 16:23:00 +00:00
if ( Client ( ) - > m_ReconnectTime > 0 )
2014-06-26 22:28:57 +00:00
{
2020-06-26 16:17:20 +00:00
str_format ( aBuf , sizeof ( aBuf ) , Localize ( " Reconnect in %d sec " ) , ( int ) ( ( Client ( ) - > m_ReconnectTime - time_get ( ) ) / time_freq ( ) ) ) ;
2016-05-04 16:23:00 +00:00
pTitle = Client ( ) - > ErrorString ( ) ;
pExtraText = aBuf ;
pButtonText = Localize ( " Abort " ) ;
2014-06-26 22:28:57 +00:00
}
ExtraAlign = 0 ;
2008-08-27 15:48:50 +00:00
}
2011-03-12 18:08:44 +00:00
else if ( m_Popup = = POPUP_RENAME_DEMO )
{
pTitle = Localize ( " Rename demo " ) ;
}
2020-09-22 16:02:03 +00:00
# if defined(CONF_VIDEORECORDER)
2019-09-27 03:06:02 +00:00
else if ( m_Popup = = POPUP_RENDER_DEMO )
{
pTitle = Localize ( " Render demo " ) ;
}
2020-09-22 16:02:03 +00:00
# endif
2010-05-29 07:25:38 +00:00
else if ( m_Popup = = POPUP_PASSWORD )
2008-08-27 15:48:50 +00:00
{
2010-06-02 19:03:15 +00:00
pTitle = Localize ( " Password incorrect " ) ;
2010-05-29 07:25:38 +00:00
pButtonText = Localize ( " Try again " ) ;
2008-08-27 15:48:50 +00:00
}
2010-05-29 07:25:38 +00:00
else if ( m_Popup = = POPUP_QUIT )
2008-08-27 15:48:50 +00:00
{
2010-05-29 07:25:38 +00:00
pTitle = Localize ( " Quit " ) ;
pExtraText = Localize ( " Are you sure that you want to quit? " ) ;
2008-08-27 15:48:50 +00:00
}
2010-05-29 07:25:38 +00:00
else if ( m_Popup = = POPUP_FIRST_LAUNCH )
2008-08-27 15:48:50 +00:00
{
2017-09-07 18:51:46 +00:00
pTitle = Localize ( " Welcome to DDNet " ) ;
2022-02-21 00:04:49 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " %s \n \n %s \n \n %s \n \n %s " ,
2020-06-26 16:17:20 +00:00
Localize ( " DDraceNetwork is a cooperative online game where the goal is for you and your group of tees to reach the finish line of the map. As a newcomer you should start on Novice servers, which host the easiest maps. Consider the ping to choose a server close to you. " ) ,
2020-08-18 08:32:44 +00:00
Localize ( " Use k key to kill (restart), q to pause and watch other players. See settings for other key binds. " ) ,
2020-06-26 16:17:20 +00:00
Localize ( " It's recommended that you check the settings to adjust them to your liking before joining a server. " ) ,
2020-11-05 08:32:14 +00:00
Localize ( " Please enter your nickname below. " ) ) ;
2020-06-26 16:17:20 +00:00
pExtraText = aBuf ;
2010-05-29 07:25:38 +00:00
pButtonText = Localize ( " Ok " ) ;
ExtraAlign = - 1 ;
2008-08-27 15:48:50 +00:00
}
2020-10-23 21:25:58 +00:00
else if ( m_Popup = = POPUP_POINTS )
{
pTitle = Localize ( " Existing Player " ) ;
if ( Client ( ) - > m_Points > 50 )
{
2020-11-05 08:32:14 +00:00
str_format ( aBuf , sizeof ( aBuf ) , Localize ( " Your nickname '%s' is already used (%d points). Do you still want to use it? " ) , Client ( ) - > PlayerName ( ) , Client ( ) - > m_Points ) ;
2020-10-23 21:25:58 +00:00
pExtraText = aBuf ;
2022-07-11 00:13:56 +00:00
ExtraAlign = - 1 ;
2020-10-23 21:25:58 +00:00
}
else if ( Client ( ) - > m_Points > = 0 )
{
m_Popup = POPUP_NONE ;
}
else
{
pExtraText = Localize ( " Checking for existing player with your name " ) ;
}
}
2020-08-29 10:49:45 +00:00
else if ( m_Popup = = POPUP_WARNING )
{
2021-09-25 07:50:11 +00:00
BgColor = ColorRGBA ( 0.5f , 0.0f , 0.0f , 0.7f ) ;
2020-08-29 10:49:45 +00:00
pTitle = m_aMessageTopic ;
pExtraText = m_aMessageBody ;
pButtonText = m_aMessageButton ;
ExtraAlign = - 1 ;
}
2011-04-13 18:37:12 +00:00
2010-09-27 19:41:41 +00:00
CUIRect Box , Part ;
2010-05-29 07:25:38 +00:00
Box = Screen ;
2020-06-19 09:53:26 +00:00
if ( m_Popup ! = POPUP_FIRST_LAUNCH )
2022-06-12 08:34:09 +00:00
Box . Margin ( 150.0f , & Box ) ;
2011-04-13 18:37:12 +00:00
2008-08-27 15:48:50 +00:00
// render the box
2022-08-07 16:12:07 +00:00
Box . Draw ( BgColor , IGraphics : : CORNER_ALL , 15.0f ) ;
2011-04-13 18:37:12 +00:00
2022-06-12 08:34:09 +00:00
Box . HSplitTop ( 20.f , & Part , & Box ) ;
Box . HSplitTop ( 24.f , & Part , & Box ) ;
Part . VMargin ( 20.f , & Part ) ;
2022-03-11 16:34:48 +00:00
SLabelProperties Props ;
Props . m_MaxWidth = ( int ) Part . w ;
2022-07-11 00:13:56 +00:00
2023-02-17 17:13:20 +00:00
if ( TextRender ( ) - > TextWidth ( 24.f , pTitle , - 1 , - 1.0f ) > Part . w )
2022-06-12 08:34:09 +00:00
UI ( ) - > DoLabel ( & Part , pTitle , 24.f , TEXTALIGN_LEFT , Props ) ;
2015-03-29 12:20:34 +00:00
else
2022-06-12 08:34:09 +00:00
UI ( ) - > DoLabel ( & Part , pTitle , 24.f , TEXTALIGN_CENTER ) ;
2022-07-11 00:13:56 +00:00
2022-06-12 08:34:09 +00:00
Box . HSplitTop ( 20.f , & Part , & Box ) ;
Box . HSplitTop ( 24.f , & Part , & Box ) ;
Part . VMargin ( 20.f , & Part ) ;
2011-04-13 18:37:12 +00:00
2020-06-19 09:53:26 +00:00
float FontSize = m_Popup = = POPUP_FIRST_LAUNCH ? 16.0f : 20.f ;
2022-07-11 00:13:56 +00:00
if ( UseIpLabel )
{
UI ( ) - > DoLabel ( & Part , Client ( ) - > ConnectAddressString ( ) , FontSize , TEXTALIGN_CENTER ) ;
Box . HSplitTop ( 20.f , & Part , & Box ) ;
Box . HSplitTop ( 24.f , & Part , & Box ) ;
}
2022-03-11 16:34:48 +00:00
Props . m_MaxWidth = ( int ) Part . w ;
2010-05-29 07:25:38 +00:00
if ( ExtraAlign = = - 1 )
2022-06-12 08:34:09 +00:00
UI ( ) - > DoLabel ( & Part , pExtraText , FontSize , TEXTALIGN_LEFT , Props ) ;
2008-08-27 15:48:50 +00:00
else
2015-04-27 21:17:28 +00:00
{
2023-02-17 17:13:20 +00:00
if ( TextRender ( ) - > TextWidth ( FontSize , pExtraText , - 1 , - 1.0f ) > Part . w )
2022-06-12 08:34:09 +00:00
UI ( ) - > DoLabel ( & Part , pExtraText , FontSize , TEXTALIGN_LEFT , Props ) ;
2015-04-27 21:17:28 +00:00
else
2022-06-12 08:34:09 +00:00
UI ( ) - > DoLabel ( & Part , pExtraText , FontSize , TEXTALIGN_CENTER ) ;
2015-04-27 21:17:28 +00:00
}
2008-08-27 15:48:50 +00:00
2022-11-30 21:26:40 +00:00
if ( m_Popup = = POPUP_MESSAGE | | m_Popup = = POPUP_CONFIRM )
{
CUIRect ButtonBar ;
Box . HSplitBottom ( 20.0f , & Box , nullptr ) ;
Box . HSplitBottom ( 24.0f , & Box , & ButtonBar ) ;
ButtonBar . VMargin ( 100.0f , & ButtonBar ) ;
if ( m_Popup = = POPUP_MESSAGE )
{
static CButtonContainer s_ButtonConfirm ;
if ( DoButton_Menu ( & s_ButtonConfirm , m_aPopupButtons [ BUTTON_CONFIRM ] . m_aLabel , 0 , & ButtonBar ) | | UI ( ) - > ConsumeHotkey ( CUI : : HOTKEY_ESCAPE ) | | UI ( ) - > ConsumeHotkey ( CUI : : HOTKEY_ENTER ) )
{
m_Popup = m_aPopupButtons [ BUTTON_CONFIRM ] . m_NextPopup ;
( this - > * m_aPopupButtons [ BUTTON_CONFIRM ] . m_pfnCallback ) ( ) ;
}
}
else if ( m_Popup = = POPUP_CONFIRM )
{
CUIRect CancelButton , ConfirmButton ;
ButtonBar . VSplitMid ( & CancelButton , & ConfirmButton , 40.0f ) ;
static CButtonContainer s_ButtonCancel ;
if ( DoButton_Menu ( & s_ButtonCancel , m_aPopupButtons [ BUTTON_CANCEL ] . m_aLabel , 0 , & CancelButton ) | | UI ( ) - > ConsumeHotkey ( CUI : : HOTKEY_ESCAPE ) )
{
m_Popup = m_aPopupButtons [ BUTTON_CANCEL ] . m_NextPopup ;
( this - > * m_aPopupButtons [ BUTTON_CANCEL ] . m_pfnCallback ) ( ) ;
}
static CButtonContainer s_ButtonConfirm ;
if ( DoButton_Menu ( & s_ButtonConfirm , m_aPopupButtons [ BUTTON_CONFIRM ] . m_aLabel , 0 , & ConfirmButton ) | | UI ( ) - > ConsumeHotkey ( CUI : : HOTKEY_ENTER ) )
{
m_Popup = m_aPopupButtons [ BUTTON_CONFIRM ] . m_NextPopup ;
( this - > * m_aPopupButtons [ BUTTON_CONFIRM ] . m_pfnCallback ) ( ) ;
}
}
}
else if ( m_Popup = = POPUP_QUIT )
2008-08-27 15:48:50 +00:00
{
2010-05-29 07:25:38 +00:00
CUIRect Yes , No ;
Box . HSplitBottom ( 20.f , & Box , & Part ) ;
Box . HSplitBottom ( 24.f , & Box , & Part ) ;
2011-03-21 23:31:42 +00:00
// additional info
2022-06-12 08:34:09 +00:00
Box . VMargin ( 20.f , & Box ) ;
2011-03-21 23:31:42 +00:00
if ( m_pClient - > Editor ( ) - > HasUnsavedData ( ) )
2011-04-02 10:08:46 +00:00
{
str_format ( aBuf , sizeof ( aBuf ) , " %s \n %s " , Localize ( " There's an unsaved map in the editor, you might want to save it before you quit the game. " ) , Localize ( " Quit anyway? " ) ) ;
2022-03-11 16:34:48 +00:00
Props . m_MaxWidth = Part . w - 20.0f ;
2022-06-12 08:34:09 +00:00
UI ( ) - > DoLabel ( & Box , aBuf , 20.f , TEXTALIGN_LEFT , Props ) ;
2011-04-02 10:08:46 +00:00
}
2011-03-21 23:31:42 +00:00
// buttons
2010-05-29 07:25:38 +00:00
Part . VMargin ( 80.0f , & Part ) ;
Part . VSplitMid ( & No , & Yes ) ;
Yes . VMargin ( 20.0f , & Yes ) ;
No . VMargin ( 20.0f , & No ) ;
2008-08-27 15:48:50 +00:00
2022-07-16 13:32:06 +00:00
static CButtonContainer s_ButtonAbort ;
2022-08-21 11:17:09 +00:00
if ( DoButton_Menu ( & s_ButtonAbort , Localize ( " No " ) , 0 , & No ) | | UI ( ) - > ConsumeHotkey ( CUI : : HOTKEY_ESCAPE ) )
2010-05-29 07:25:38 +00:00
m_Popup = POPUP_NONE ;
2008-08-27 15:48:50 +00:00
2022-07-16 13:32:06 +00:00
static CButtonContainer s_ButtonTryAgain ;
2022-08-21 11:17:09 +00:00
if ( DoButton_Menu ( & s_ButtonTryAgain , Localize ( " Yes " ) , 0 , & Yes ) | | UI ( ) - > ConsumeHotkey ( CUI : : HOTKEY_ENTER ) )
2020-10-02 13:43:52 +00:00
{
m_Popup = POPUP_NONE ;
2010-05-29 07:25:38 +00:00
Client ( ) - > Quit ( ) ;
2020-10-02 13:43:52 +00:00
}
2008-08-27 15:48:50 +00:00
}
2010-05-29 07:25:38 +00:00
else if ( m_Popup = = POPUP_PASSWORD )
2008-08-27 15:48:50 +00:00
{
2010-05-29 07:25:38 +00:00
CUIRect Label , TextBox , TryAgain , Abort ;
2011-04-13 18:37:12 +00:00
2010-05-29 07:25:38 +00:00
Box . HSplitBottom ( 20.f , & Box , & Part ) ;
Box . HSplitBottom ( 24.f , & Box , & Part ) ;
Part . VMargin ( 80.0f , & Part ) ;
2011-04-13 18:37:12 +00:00
2010-05-29 07:25:38 +00:00
Part . VSplitMid ( & Abort , & TryAgain ) ;
2011-04-13 18:37:12 +00:00
2010-05-29 07:25:38 +00:00
TryAgain . VMargin ( 20.0f , & TryAgain ) ;
Abort . VMargin ( 20.0f , & Abort ) ;
2011-04-13 18:37:12 +00:00
2022-07-16 13:32:06 +00:00
static CButtonContainer s_ButtonAbort ;
2022-08-21 11:17:09 +00:00
if ( DoButton_Menu ( & s_ButtonAbort , Localize ( " Abort " ) , 0 , & Abort ) | | UI ( ) - > ConsumeHotkey ( CUI : : HOTKEY_ESCAPE ) )
2010-05-29 07:25:38 +00:00
m_Popup = POPUP_NONE ;
2008-08-27 15:48:50 +00:00
2022-07-16 13:32:06 +00:00
static CButtonContainer s_ButtonTryAgain ;
2022-08-21 11:17:09 +00:00
if ( DoButton_Menu ( & s_ButtonTryAgain , Localize ( " Try again " ) , 0 , & TryAgain ) | | UI ( ) - > ConsumeHotkey ( CUI : : HOTKEY_ENTER ) )
2008-08-27 15:48:50 +00:00
{
2017-07-15 15:29:20 +00:00
Client ( ) - > Connect ( g_Config . m_UiServerAddress , g_Config . m_Password ) ;
2008-08-27 15:48:50 +00:00
}
2011-04-13 18:37:12 +00:00
2010-05-29 07:25:38 +00:00
Box . HSplitBottom ( 60.f , & Box , & Part ) ;
Box . HSplitBottom ( 24.f , & Box , & Part ) ;
2011-04-13 18:37:12 +00:00
2010-05-29 07:25:38 +00:00
Part . VSplitLeft ( 60.0f , 0 , & Label ) ;
Label . VSplitLeft ( 100.0f , 0 , & TextBox ) ;
TextBox . VSplitLeft ( 20.0f , 0 , & TextBox ) ;
TextBox . VSplitRight ( 60.0f , & TextBox , 0 ) ;
2022-01-21 15:20:15 +00:00
UI ( ) - > DoLabel ( & Label , Localize ( " Password " ) , 18.0f , TEXTALIGN_LEFT ) ;
2021-12-03 19:15:44 +00:00
static float s_Offset = 0.0f ;
2022-08-07 20:03:34 +00:00
UI ( ) - > DoEditBox ( & g_Config . m_Password , & TextBox , g_Config . m_Password , sizeof ( g_Config . m_Password ) , 12.0f , & s_Offset , true ) ;
2008-08-27 15:48:50 +00:00
}
2010-12-16 00:52:29 +00:00
else if ( m_Popup = = POPUP_CONNECTING )
{
Box = Screen ;
2022-04-30 21:58:14 +00:00
Box . Margin ( 150.0f , & Box ) ;
2010-12-16 00:52:29 +00:00
Box . HSplitBottom ( 20.f , & Box , & Part ) ;
Box . HSplitBottom ( 24.f , & Box , & Part ) ;
Part . VMargin ( 120.0f , & Part ) ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_Button ;
2022-08-21 11:17:09 +00:00
if ( DoButton_Menu ( & s_Button , pButtonText , 0 , & Part ) | | UI ( ) - > ConsumeHotkey ( CUI : : HOTKEY_ESCAPE ) )
2010-12-16 00:52:29 +00:00
{
Client ( ) - > Disconnect ( ) ;
m_Popup = POPUP_NONE ;
2022-09-23 17:59:18 +00:00
RefreshBrowserTab ( g_Config . m_UiPage ) ;
2010-12-16 00:52:29 +00:00
}
if ( Client ( ) - > MapDownloadTotalsize ( ) > 0 )
{
2021-06-23 05:05:49 +00:00
int64_t Now = time_get ( ) ;
2020-09-22 16:02:03 +00:00
if ( Now - m_DownloadLastCheckTime > = time_freq ( ) )
2010-12-16 00:52:29 +00:00
{
if ( m_DownloadLastCheckSize > Client ( ) - > MapDownloadAmount ( ) )
{
// map downloaded restarted
m_DownloadLastCheckSize = 0 ;
}
// update download speed
2020-09-22 16:02:03 +00:00
float Diff = ( Client ( ) - > MapDownloadAmount ( ) - m_DownloadLastCheckSize ) / ( ( int ) ( ( Now - m_DownloadLastCheckTime ) / time_freq ( ) ) ) ;
float StartDiff = m_DownloadLastCheckSize - 0.0f ;
if ( StartDiff + Diff > 0.0f )
m_DownloadSpeed = ( Diff / ( StartDiff + Diff ) ) * ( Diff / 1.0f ) + ( StartDiff / ( Diff + StartDiff ) ) * m_DownloadSpeed ;
2011-04-12 16:59:08 +00:00
else
m_DownloadSpeed = 0.0f ;
2010-12-16 00:52:29 +00:00
m_DownloadLastCheckTime = Now ;
m_DownloadLastCheckSize = Client ( ) - > MapDownloadAmount ( ) ;
}
Box . HSplitTop ( 64.f , 0 , & Box ) ;
Box . HSplitTop ( 24.f , & Part , & Box ) ;
2020-09-22 16:02:03 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " %d/%d KiB (%.1f KiB/s) " , Client ( ) - > MapDownloadAmount ( ) / 1024 , Client ( ) - > MapDownloadTotalsize ( ) / 1024 , m_DownloadSpeed / 1024.0f ) ;
2022-03-11 16:34:48 +00:00
UI ( ) - > DoLabel ( & Part , aBuf , 20.f , TEXTALIGN_CENTER ) ;
2011-04-13 18:37:12 +00:00
2010-12-16 00:52:29 +00:00
// time left
2020-09-22 16:02:03 +00:00
int TimeLeft = maximum ( 1 , m_DownloadSpeed > 0.0f ? static_cast < int > ( ( Client ( ) - > MapDownloadTotalsize ( ) - Client ( ) - > MapDownloadAmount ( ) ) / m_DownloadSpeed ) : 1 ) ;
2010-12-16 00:52:29 +00:00
if ( TimeLeft > = 60 )
{
TimeLeft / = 60 ;
2017-07-26 01:58:00 +00:00
str_format ( aBuf , sizeof ( aBuf ) , TimeLeft = = 1 ? Localize ( " %i minute left " ) : Localize ( " %i minutes left " ) , TimeLeft ) ;
2010-12-16 00:52:29 +00:00
}
else
2017-07-26 01:58:00 +00:00
{
str_format ( aBuf , sizeof ( aBuf ) , TimeLeft = = 1 ? Localize ( " %i second left " ) : Localize ( " %i seconds left " ) , TimeLeft ) ;
}
2010-12-16 00:52:29 +00:00
Box . HSplitTop ( 20.f , 0 , & Box ) ;
Box . HSplitTop ( 24.f , & Part , & Box ) ;
2022-03-11 16:34:48 +00:00
UI ( ) - > DoLabel ( & Part , aBuf , 20.f , TEXTALIGN_CENTER ) ;
2010-12-16 00:52:29 +00:00
// progress bar
Box . HSplitTop ( 20.f , 0 , & Box ) ;
Box . HSplitTop ( 24.f , & Part , & Box ) ;
Part . VMargin ( 40.0f , & Part ) ;
2022-08-07 16:12:07 +00:00
Part . Draw ( ColorRGBA ( 1.0f , 1.0f , 1.0f , 0.25f ) , IGraphics : : CORNER_ALL , 5.0f ) ;
2020-09-22 16:02:03 +00:00
Part . w = maximum ( 10.0f , ( Part . w * Client ( ) - > MapDownloadAmount ( ) ) / Client ( ) - > MapDownloadTotalsize ( ) ) ;
2022-08-07 16:12:07 +00:00
Part . Draw ( ColorRGBA ( 1.0f , 1.0f , 1.0f , 0.5f ) , IGraphics : : CORNER_ALL , 5.0f ) ;
2010-12-16 00:52:29 +00:00
}
}
2010-12-12 18:20:30 +00:00
else if ( m_Popup = = POPUP_LANGUAGE )
{
2023-01-05 11:21:10 +00:00
CUIRect Button ;
Screen . Margin ( 150.0f , & Box ) ;
Box . HSplitTop ( 20.0f , nullptr , & Box ) ;
Box . HSplitBottom ( 20.0f , & Box , nullptr ) ;
Box . HSplitBottom ( 24.0f , & Box , & Button ) ;
Box . HSplitBottom ( 20.0f , & Box , nullptr ) ;
2010-12-12 18:20:30 +00:00
Box . VMargin ( 20.0f , & Box ) ;
2023-01-05 11:21:10 +00:00
const bool Activated = RenderLanguageSelection ( Box ) ;
Button . VMargin ( 120.0f , & Button ) ;
2010-12-12 18:20:30 +00:00
2022-07-16 13:32:06 +00:00
static CButtonContainer s_Button ;
2023-01-05 11:21:10 +00:00
if ( DoButton_Menu ( & s_Button , Localize ( " Ok " ) , 0 , & Button ) | | UI ( ) - > ConsumeHotkey ( CUI : : HOTKEY_ESCAPE ) | | UI ( ) - > ConsumeHotkey ( CUI : : HOTKEY_ENTER ) | | Activated )
2010-12-12 18:20:30 +00:00
m_Popup = POPUP_FIRST_LAUNCH ;
}
2011-06-29 20:27:32 +00:00
else if ( m_Popup = = POPUP_COUNTRY )
{
2023-01-05 11:21:10 +00:00
CUIRect ButtonBar ;
Screen . Margin ( 150.0f , & Box ) ;
Box . HSplitTop ( 20.0f , nullptr , & Box ) ;
Box . HSplitBottom ( 20.0f , & Box , nullptr ) ;
Box . HSplitBottom ( 24.0f , & Box , & ButtonBar ) ;
Box . HSplitBottom ( 20.0f , & Box , nullptr ) ;
2011-06-29 20:27:32 +00:00
Box . VMargin ( 20.0f , & Box ) ;
2023-01-05 11:21:10 +00:00
ButtonBar . VMargin ( 100.0f , & ButtonBar ) ;
2011-08-11 08:59:14 +00:00
2022-12-03 12:12:10 +00:00
static int s_CurSelection = - 2 ;
if ( s_CurSelection = = - 2 )
s_CurSelection = g_Config . m_BrFilterCountryIndex ;
2023-01-05 11:21:10 +00:00
static CListBox s_ListBox ;
2011-06-29 20:27:32 +00:00
int OldSelected = - 1 ;
2023-01-05 11:21:10 +00:00
s_ListBox . DoStart ( 50.0f , m_pClient - > m_CountryFlags . Num ( ) , 10 , 1 , OldSelected , & Box ) ;
2011-06-29 20:27:32 +00:00
2022-05-23 17:51:54 +00:00
for ( size_t i = 0 ; i < m_pClient - > m_CountryFlags . Num ( ) ; + + i )
2011-06-29 20:27:32 +00:00
{
2021-07-12 09:43:56 +00:00
const CCountryFlags : : CCountryFlag * pEntry = m_pClient - > m_CountryFlags . GetByIndex ( i ) ;
2022-12-03 12:12:10 +00:00
if ( pEntry - > m_CountryCode = = s_CurSelection )
2011-06-29 20:27:32 +00:00
OldSelected = i ;
2023-01-05 11:21:10 +00:00
const CListboxItem Item = s_ListBox . DoNextItem ( pEntry , OldSelected > = 0 & & ( size_t ) OldSelected = = i ) ;
if ( ! Item . m_Visible )
continue ;
CUIRect FlagRect , Label ;
Item . m_Rect . Margin ( 5.0f , & FlagRect ) ;
FlagRect . HSplitBottom ( 12.0f , & FlagRect , & Label ) ;
Label . HSplitTop ( 2.0f , nullptr , & Label ) ;
const float OldWidth = FlagRect . w ;
FlagRect . w = FlagRect . h * 2.0f ;
FlagRect . x + = ( OldWidth - FlagRect . w ) / 2.0f ;
ColorRGBA Color ( 1.0f , 1.0f , 1.0f , 1.0f ) ;
m_pClient - > m_CountryFlags . Render ( pEntry - > m_CountryCode , & Color , FlagRect . x , FlagRect . y , FlagRect . w , FlagRect . h ) ;
SLabelProperties ItemLabelProps ;
ItemLabelProps . m_AlignVertically = 0 ;
UI ( ) - > DoLabel ( & Label , pEntry - > m_aCountryCodeString , 10.0f , TEXTALIGN_CENTER , ItemLabelProps ) ;
2011-06-29 20:27:32 +00:00
}
2023-01-05 11:21:10 +00:00
const int NewSelected = s_ListBox . DoEnd ( ) ;
2011-06-29 20:27:32 +00:00
if ( OldSelected ! = NewSelected )
2022-12-03 12:12:10 +00:00
s_CurSelection = m_pClient - > m_CountryFlags . GetByIndex ( NewSelected ) - > m_CountryCode ;
2011-06-29 20:27:32 +00:00
2022-12-03 12:21:41 +00:00
CUIRect CancelButton , OkButton ;
2023-01-05 11:21:10 +00:00
ButtonBar . VSplitMid ( & CancelButton , & OkButton , 40.0f ) ;
2011-06-29 20:27:32 +00:00
2022-12-03 12:21:41 +00:00
static CButtonContainer s_CancelButton ;
if ( DoButton_Menu ( & s_CancelButton , Localize ( " Cancel " ) , 0 , & CancelButton ) | | UI ( ) - > ConsumeHotkey ( CUI : : HOTKEY_ESCAPE ) )
2011-06-29 20:27:32 +00:00
{
2022-12-03 12:21:41 +00:00
s_CurSelection = g_Config . m_BrFilterCountryIndex ;
2011-06-29 20:27:32 +00:00
m_Popup = POPUP_NONE ;
}
2022-12-03 12:21:41 +00:00
static CButtonContainer s_OkButton ;
2023-01-05 11:21:10 +00:00
if ( DoButton_Menu ( & s_OkButton , Localize ( " Ok " ) , 0 , & OkButton ) | | UI ( ) - > ConsumeHotkey ( CUI : : HOTKEY_ENTER ) | | s_ListBox . WasItemActivated ( ) )
2011-06-29 20:27:32 +00:00
{
2022-12-03 12:21:41 +00:00
g_Config . m_BrFilterCountryIndex = s_CurSelection ;
Client ( ) - > ServerBrowserUpdate ( ) ;
2011-06-29 20:27:32 +00:00
m_Popup = POPUP_NONE ;
}
}
2011-03-12 18:08:44 +00:00
else if ( m_Popup = = POPUP_RENAME_DEMO )
{
CUIRect Label , TextBox , Ok , Abort ;
2011-04-13 18:37:12 +00:00
2011-03-12 18:08:44 +00:00
Box . HSplitBottom ( 20.f , & Box , & Part ) ;
Box . HSplitBottom ( 24.f , & Box , & Part ) ;
Part . VMargin ( 80.0f , & Part ) ;
2011-04-13 18:37:12 +00:00
2011-03-12 18:08:44 +00:00
Part . VSplitMid ( & Abort , & Ok ) ;
2011-04-13 18:37:12 +00:00
2011-03-12 18:08:44 +00:00
Ok . VMargin ( 20.0f , & Ok ) ;
Abort . VMargin ( 20.0f , & Abort ) ;
2011-04-13 18:37:12 +00:00
2022-07-16 13:32:06 +00:00
static CButtonContainer s_ButtonAbort ;
2022-08-21 11:17:09 +00:00
if ( DoButton_Menu ( & s_ButtonAbort , Localize ( " Abort " ) , 0 , & Abort ) | | UI ( ) - > ConsumeHotkey ( CUI : : HOTKEY_ESCAPE ) )
2011-03-12 18:08:44 +00:00
m_Popup = POPUP_NONE ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_ButtonOk ;
2022-08-21 11:17:09 +00:00
if ( DoButton_Menu ( & s_ButtonOk , Localize ( " Ok " ) , 0 , & Ok ) | | UI ( ) - > ConsumeHotkey ( CUI : : HOTKEY_ENTER ) )
2011-03-12 18:08:44 +00:00
{
m_Popup = POPUP_NONE ;
// rename demo
if ( m_DemolistSelectedIndex > = 0 & & ! m_DemolistSelectedIsDir )
{
2022-10-24 18:17:11 +00:00
char aBufOld [ IO_MAX_PATH_LENGTH ] ;
2022-06-11 19:38:18 +00:00
str_format ( aBufOld , sizeof ( aBufOld ) , " %s/%s " , m_aCurrentDemoFolder , m_vDemos [ m_DemolistSelectedIndex ] . m_aFilename ) ;
2022-10-24 18:17:11 +00:00
char aBufNew [ IO_MAX_PATH_LENGTH ] ;
str_format ( aBufNew , sizeof ( aBufNew ) , " %s/%s " , m_aCurrentDemoFolder , m_aCurrentDemoFile ) ;
if ( ! str_endswith ( aBufNew , " .demo " ) )
str_append ( aBufNew , " .demo " , sizeof ( aBufNew ) ) ;
2022-06-11 19:38:18 +00:00
if ( Storage ( ) - > RenameFile ( aBufOld , aBufNew , m_vDemos [ m_DemolistSelectedIndex ] . m_StorageType ) )
2011-03-12 18:08:44 +00:00
{
DemolistPopulate ( ) ;
DemolistOnUpdate ( false ) ;
}
else
PopupMessage ( Localize ( " Error " ) , Localize ( " Unable to rename the demo " ) , Localize ( " Ok " ) ) ;
}
}
2011-04-13 18:37:12 +00:00
2011-03-12 18:08:44 +00:00
Box . HSplitBottom ( 60.f , & Box , & Part ) ;
Box . HSplitBottom ( 24.f , & Box , & Part ) ;
2011-04-13 18:37:12 +00:00
2011-03-12 18:08:44 +00:00
Part . VSplitLeft ( 60.0f , 0 , & Label ) ;
Label . VSplitLeft ( 120.0f , 0 , & TextBox ) ;
TextBox . VSplitLeft ( 20.0f , 0 , & TextBox ) ;
TextBox . VSplitRight ( 60.0f , & TextBox , 0 ) ;
2022-01-21 15:20:15 +00:00
UI ( ) - > DoLabel ( & Label , Localize ( " New name: " ) , 18.0f , TEXTALIGN_LEFT ) ;
2021-12-03 19:15:44 +00:00
static float s_Offset = 0.0f ;
2022-08-07 20:03:34 +00:00
UI ( ) - > DoEditBox ( & s_Offset , & TextBox , m_aCurrentDemoFile , sizeof ( m_aCurrentDemoFile ) , 12.0f , & s_Offset ) ;
2011-03-12 18:08:44 +00:00
}
2019-09-27 07:22:50 +00:00
# if defined(CONF_VIDEORECORDER)
2019-09-27 03:06:02 +00:00
else if ( m_Popup = = POPUP_RENDER_DEMO )
{
2022-11-30 22:21:36 +00:00
CUIRect Label , TextBox , Ok , Abort , IncSpeed , DecSpeed , Button ;
2019-09-27 03:06:02 +00:00
Box . HSplitBottom ( 20.f , & Box , & Part ) ;
# if defined(__ANDROID__)
Box . HSplitBottom ( 60.f , & Box , & Part ) ;
# else
Box . HSplitBottom ( 24.f , & Box , & Part ) ;
# endif
Part . VMargin ( 80.0f , & Part ) ;
2022-11-30 22:21:36 +00:00
Part . VSplitMid ( & Abort , & Ok ) ;
2019-09-27 03:06:02 +00:00
Ok . VMargin ( 20.0f , & Ok ) ;
Abort . VMargin ( 20.0f , & Abort ) ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_ButtonAbort ;
2022-08-21 11:17:09 +00:00
if ( DoButton_Menu ( & s_ButtonAbort , Localize ( " Abort " ) , 0 , & Abort ) | | UI ( ) - > ConsumeHotkey ( CUI : : HOTKEY_ESCAPE ) )
2019-09-27 03:06:02 +00:00
m_Popup = POPUP_NONE ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_ButtonOk ;
2022-08-21 11:17:09 +00:00
if ( DoButton_Menu ( & s_ButtonOk , Localize ( " Ok " ) , 0 , & Ok ) | | UI ( ) - > ConsumeHotkey ( CUI : : HOTKEY_ENTER ) )
2019-09-27 03:06:02 +00:00
{
m_Popup = POPUP_NONE ;
// name video
if ( m_DemolistSelectedIndex > = 0 & & ! m_DemolistSelectedIsDir )
{
2022-10-24 18:17:11 +00:00
if ( ! str_endswith ( m_aCurrentDemoFile , " .mp4 " ) )
str_append ( m_aCurrentDemoFile , " .mp4 " , sizeof ( m_aCurrentDemoFile ) ) ;
char aWholePath [ IO_MAX_PATH_LENGTH ] ;
2019-09-27 06:51:08 +00:00
// store new video filename to origin buffer
if ( Storage ( ) - > FindFile ( m_aCurrentDemoFile , " videos " , IStorage : : TYPE_ALL , aWholePath , sizeof ( aWholePath ) ) )
{
2022-11-30 22:21:36 +00:00
char aMessage [ 128 + IO_MAX_PATH_LENGTH ] ;
str_format ( aMessage , sizeof ( aMessage ) , Localize ( " File '%s' already exists, do you want to overwrite it? " ) , m_aCurrentDemoFile ) ;
PopupConfirm ( Localize ( " Replace video " ) , aMessage , Localize ( " Yes " ) , Localize ( " No " ) , & CMenus : : PopupConfirmDemoReplaceVideo , POPUP_NONE , & CMenus : : DefaultButtonCallback , POPUP_RENDER_DEMO ) ;
2019-09-27 06:51:08 +00:00
}
else
{
2022-11-30 22:21:36 +00:00
PopupConfirmDemoReplaceVideo ( ) ;
2019-09-27 06:51:08 +00:00
}
2019-09-27 03:06:02 +00:00
}
}
2020-10-07 21:11:09 +00:00
Box . HSplitBottom ( 30.f , & Box , 0 ) ;
2020-09-08 09:31:45 +00:00
Box . HSplitBottom ( 20.f , & Box , & Part ) ;
2020-10-07 21:11:09 +00:00
Box . HSplitBottom ( 10.f , & Box , 0 ) ;
2020-09-08 09:31:45 +00:00
2020-10-07 21:11:09 +00:00
float ButtonSize = 20.0f ;
2020-09-08 09:31:45 +00:00
Part . VSplitLeft ( 113.0f , 0 , & Part ) ;
2022-03-18 13:31:52 +00:00
Part . VSplitLeft ( 200.0f , & Button , & Part ) ;
2020-09-08 09:31:45 +00:00
if ( DoButton_CheckBox ( & g_Config . m_ClVideoShowChat , Localize ( " Show chat " ) , g_Config . m_ClVideoShowChat , & Button ) )
g_Config . m_ClVideoShowChat ^ = 1 ;
2022-03-18 13:31:52 +00:00
Part . VSplitLeft ( 32.0f , 0 , & Part ) ;
if ( DoButton_CheckBox ( & g_Config . m_ClVideoSndEnable , Localize ( " Use sounds " ) , g_Config . m_ClVideoSndEnable , & Part ) )
2020-09-08 09:31:45 +00:00
g_Config . m_ClVideoSndEnable ^ = 1 ;
2019-09-28 04:18:38 +00:00
Box . HSplitBottom ( 20.f , & Box , & Part ) ;
Part . VSplitLeft ( 60.0f , 0 , & Part ) ;
Part . VSplitLeft ( 60.0f , 0 , & Label ) ;
Part . VSplitMid ( & IncSpeed , & DecSpeed ) ;
IncSpeed . VMargin ( 20.0f , & IncSpeed ) ;
DecSpeed . VMargin ( 20.0f , & DecSpeed ) ;
Part . VSplitLeft ( 20.0f , & Button , & Part ) ;
bool IncDemoSpeed = false , DecDemoSpeed = false ;
// slowdown
Part . VSplitLeft ( 5.0f , 0 , & Part ) ;
2020-10-07 21:11:09 +00:00
Part . VSplitLeft ( ButtonSize , & Button , & Part ) ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_SlowDownButton ;
2022-08-19 05:05:02 +00:00
if ( DoButton_FontIcon ( & s_SlowDownButton , " \xEF \x81 \x8A " , 0 , & Button , IGraphics : : CORNER_ALL ) )
2019-09-28 04:18:38 +00:00
DecDemoSpeed = true ;
// fastforward
Part . VSplitLeft ( 5.0f , 0 , & Part ) ;
2020-10-07 21:11:09 +00:00
Part . VSplitLeft ( ButtonSize , & Button , & Part ) ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_FastForwardButton ;
2022-08-19 05:05:02 +00:00
if ( DoButton_FontIcon ( & s_FastForwardButton , " \xEF \x81 \x8E " , 0 , & Button , IGraphics : : CORNER_ALL ) )
2019-09-28 04:18:38 +00:00
IncDemoSpeed = true ;
// speed meter
2020-09-08 09:31:45 +00:00
Part . VSplitLeft ( 8.0f , 0 , & Part ) ;
2019-09-28 04:18:38 +00:00
char aBuffer [ 64 ] ;
2020-09-08 09:31:45 +00:00
str_format ( aBuffer , sizeof ( aBuffer ) , " %s: × %g " , Localize ( " Speed " ) , g_aSpeeds [ m_Speed ] ) ;
2022-01-21 15:20:15 +00:00
UI ( ) - > DoLabel ( & Part , aBuffer , 12.8f , TEXTALIGN_LEFT ) ;
2019-09-28 04:18:38 +00:00
if ( IncDemoSpeed )
2022-03-21 08:01:56 +00:00
m_Speed = clamp ( m_Speed + 1 , 0 , ( int ) ( g_DemoSpeeds - 1 ) ) ;
2019-09-28 04:18:38 +00:00
else if ( DecDemoSpeed )
2022-03-21 08:01:56 +00:00
m_Speed = clamp ( m_Speed - 1 , 0 , ( int ) ( g_DemoSpeeds - 1 ) ) ;
2019-09-28 04:18:38 +00:00
2022-03-18 13:31:52 +00:00
Part . VSplitLeft ( 207.0f , 0 , & Part ) ;
if ( DoButton_CheckBox ( & g_Config . m_ClVideoShowhud , Localize ( " Show ingame HUD " ) , g_Config . m_ClVideoShowhud , & Part ) )
2019-10-02 05:11:58 +00:00
g_Config . m_ClVideoShowhud ^ = 1 ;
2019-09-28 04:18:38 +00:00
Box . HSplitBottom ( 20.f , & Box , & Part ) ;
2019-09-27 03:06:02 +00:00
# if defined(__ANDROID__)
Box . HSplitBottom ( 60.f , & Box , & Part ) ;
# else
Box . HSplitBottom ( 24.f , & Box , & Part ) ;
# endif
Part . VSplitLeft ( 60.0f , 0 , & Label ) ;
Label . VSplitLeft ( 120.0f , 0 , & TextBox ) ;
TextBox . VSplitLeft ( 20.0f , 0 , & TextBox ) ;
TextBox . VSplitRight ( 60.0f , & TextBox , 0 ) ;
2022-01-21 15:20:15 +00:00
UI ( ) - > DoLabel ( & Label , Localize ( " Video name: " ) , 18.0f , TEXTALIGN_LEFT ) ;
2021-12-03 19:15:44 +00:00
static float s_Offset = 0.0f ;
2022-08-07 20:03:34 +00:00
UI ( ) - > DoEditBox ( & s_Offset , & TextBox , m_aCurrentDemoFile , sizeof ( m_aCurrentDemoFile ) , 12.0f , & s_Offset ) ;
2019-09-27 03:06:02 +00:00
}
2019-09-27 07:22:50 +00:00
# endif
2010-05-29 07:25:38 +00:00
else if ( m_Popup = = POPUP_FIRST_LAUNCH )
2008-08-27 15:48:50 +00:00
{
2022-02-21 00:04:49 +00:00
CUIRect Label , TextBox , Skip , Join ;
2011-04-13 18:37:12 +00:00
2010-05-29 07:25:38 +00:00
Box . HSplitBottom ( 20.f , & Box , & Part ) ;
Box . HSplitBottom ( 24.f , & Box , & Part ) ;
Part . VMargin ( 80.0f , & Part ) ;
2022-02-21 00:04:49 +00:00
Part . VSplitMid ( & Skip , & Join ) ;
Skip . VMargin ( 20.0f , & Skip ) ;
Join . VMargin ( 20.0f , & Join ) ;
2011-04-13 18:37:12 +00:00
2022-07-16 13:32:06 +00:00
static CButtonContainer s_JoinTutorialButton ;
2022-08-21 11:17:09 +00:00
if ( DoButton_Menu ( & s_JoinTutorialButton , Localize ( " Join Tutorial Server " ) , 0 , & Join ) | | UI ( ) - > ConsumeHotkey ( CUI : : HOTKEY_ENTER ) )
2017-09-07 18:51:46 +00:00
{
2022-02-21 00:04:49 +00:00
m_JoinTutorial = true ;
2017-09-07 18:51:46 +00:00
Client ( ) - > RequestDDNetInfo ( ) ;
2022-02-21 00:04:49 +00:00
m_Popup = g_Config . m_BrIndicateFinished ? POPUP_POINTS : POPUP_NONE ;
}
2022-07-16 13:32:06 +00:00
static CButtonContainer s_SkipTutorialButton ;
2022-08-21 11:17:09 +00:00
if ( DoButton_Menu ( & s_SkipTutorialButton , Localize ( " Skip Tutorial " ) , 0 , & Skip ) | | UI ( ) - > ConsumeHotkey ( CUI : : HOTKEY_ESCAPE ) )
2022-02-21 00:04:49 +00:00
{
m_JoinTutorial = false ;
Client ( ) - > RequestDDNetInfo ( ) ;
m_Popup = g_Config . m_BrIndicateFinished ? POPUP_POINTS : POPUP_NONE ;
2017-09-07 18:51:46 +00:00
}
Box . HSplitBottom ( 20.f , & Box , & Part ) ;
Box . HSplitBottom ( 24.f , & Box , & Part ) ;
2020-06-19 09:53:26 +00:00
Part . VSplitLeft ( 30.0f , 0 , & Part ) ;
2020-06-26 16:17:20 +00:00
str_format ( aBuf , sizeof ( aBuf ) , " %s \n (%s) " ,
Localize ( " Show DDNet map finishes in server browser " ) ,
2022-08-30 08:09:06 +00:00
Localize ( " transmits your player name to info.ddnet.org " ) ) ;
2020-06-26 16:17:20 +00:00
if ( DoButton_CheckBox ( & g_Config . m_BrIndicateFinished , aBuf , g_Config . m_BrIndicateFinished , & Part ) )
2017-09-07 18:51:46 +00:00
g_Config . m_BrIndicateFinished ^ = 1 ;
2011-04-13 18:37:12 +00:00
2020-06-19 09:53:26 +00:00
Box . HSplitBottom ( 20.f , & Box , & Part ) ;
2010-05-29 07:25:38 +00:00
Box . HSplitBottom ( 24.f , & Box , & Part ) ;
2011-04-13 18:37:12 +00:00
2010-05-29 07:25:38 +00:00
Part . VSplitLeft ( 60.0f , 0 , & Label ) ;
Label . VSplitLeft ( 100.0f , 0 , & TextBox ) ;
TextBox . VSplitLeft ( 20.0f , 0 , & TextBox ) ;
TextBox . VSplitRight ( 60.0f , & TextBox , 0 ) ;
2022-01-21 15:20:15 +00:00
UI ( ) - > DoLabel ( & Label , Localize ( " Nickname " ) , 16.0f , TEXTALIGN_LEFT ) ;
2021-12-03 19:15:44 +00:00
static float s_Offset = 0.0f ;
2022-03-13 18:09:33 +00:00
SUIExEditBoxProperties EditProps ;
EditProps . m_pEmptyText = Client ( ) - > PlayerName ( ) ;
2022-08-07 20:03:34 +00:00
UI ( ) - > DoEditBox ( & g_Config . m_PlayerName , & TextBox , g_Config . m_PlayerName , sizeof ( g_Config . m_PlayerName ) , 12.0f , & s_Offset , false , IGraphics : : CORNER_ALL , EditProps ) ;
2008-08-27 15:48:50 +00:00
}
2020-10-23 21:25:58 +00:00
else if ( m_Popup = = POPUP_POINTS )
{
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 ) ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_ButtonNo ;
2022-08-21 11:17:09 +00:00
if ( DoButton_Menu ( & s_ButtonNo , Localize ( " No " ) , 0 , & No ) | | UI ( ) - > ConsumeHotkey ( CUI : : HOTKEY_ESCAPE ) )
2020-10-23 21:25:58 +00:00
m_Popup = POPUP_FIRST_LAUNCH ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_ButtonYes ;
2022-08-21 11:17:09 +00:00
if ( DoButton_Menu ( & s_ButtonYes , Localize ( " Yes " ) , 0 , & Yes ) | | UI ( ) - > ConsumeHotkey ( CUI : : HOTKEY_ENTER ) )
2020-10-23 21:25:58 +00:00
m_Popup = POPUP_NONE ;
}
2020-08-29 10:49:45 +00:00
else if ( m_Popup = = POPUP_WARNING )
{
Box . HSplitBottom ( 20.f , & Box , & Part ) ;
Box . HSplitBottom ( 24.f , & Box , & Part ) ;
Part . VMargin ( 120.0f , & Part ) ;
2022-07-16 13:32:06 +00:00
static CButtonContainer s_Button ;
2022-08-21 11:17:09 +00:00
if ( DoButton_Menu ( & s_Button , pButtonText , 0 , & Part ) | | UI ( ) - > ConsumeHotkey ( CUI : : HOTKEY_ESCAPE ) | | UI ( ) - > ConsumeHotkey ( CUI : : HOTKEY_ENTER ) | | ( time_get_nanoseconds ( ) - m_PopupWarningLastTime > = m_PopupWarningDuration ) )
2020-08-29 10:49:45 +00:00
{
m_Popup = POPUP_NONE ;
SetActive ( false ) ;
}
}
2008-08-27 15:48:50 +00:00
else
{
2010-05-29 07:25:38 +00:00
Box . HSplitBottom ( 20.f , & Box , & Part ) ;
Box . HSplitBottom ( 24.f , & Box , & Part ) ;
Part . VMargin ( 120.0f , & Part ) ;
2008-08-27 15:48:50 +00:00
2022-07-16 13:32:06 +00:00
static CButtonContainer s_Button ;
2022-08-21 11:17:09 +00:00
if ( DoButton_Menu ( & s_Button , pButtonText , 0 , & Part ) | | UI ( ) - > ConsumeHotkey ( CUI : : HOTKEY_ESCAPE ) | | UI ( ) - > ConsumeHotkey ( CUI : : HOTKEY_ENTER ) )
2016-05-07 14:12:23 +00:00
{
if ( m_Popup = = POPUP_DISCONNECTED & & Client ( ) - > m_ReconnectTime > 0 )
Client ( ) - > m_ReconnectTime = 0 ;
2010-05-29 07:25:38 +00:00
m_Popup = POPUP_NONE ;
2016-05-07 14:12:23 +00:00
}
2008-08-27 15:48:50 +00:00
}
2013-03-16 14:30:40 +00:00
if ( m_Popup = = POPUP_NONE )
2022-05-27 09:59:14 +00:00
UI ( ) - > SetActiveItem ( nullptr ) ;
2008-08-27 15:48:50 +00:00
}
return 0 ;
}
2022-11-30 22:21:36 +00:00
# if defined(CONF_VIDEORECORDER)
void CMenus : : PopupConfirmDemoReplaceVideo ( )
{
char aBuf [ IO_MAX_PATH_LENGTH ] ;
str_format ( aBuf , sizeof ( aBuf ) , " %s/%s " , m_aCurrentDemoFolder , m_vDemos [ m_DemolistSelectedIndex ] . m_aFilename ) ;
const char * pError = Client ( ) - > DemoPlayer_Render ( aBuf , m_vDemos [ m_DemolistSelectedIndex ] . m_StorageType , m_aCurrentDemoFile , m_Speed ) ;
m_Speed = 4 ;
if ( pError )
PopupMessage ( Localize ( " Error " ) , str_comp ( pError , " error loading demo " ) ? pError : Localize ( " Error loading demo " ) , Localize ( " Ok " ) ) ;
}
# endif
2023-01-05 11:21:10 +00:00
void CMenus : : RenderThemeSelection ( CUIRect MainView )
2020-09-18 16:45:42 +00:00
{
2023-01-05 11:21:10 +00:00
const std : : vector < CTheme > & vThemes = m_pBackground - > GetThemes ( ) ;
2020-09-18 16:45:42 +00:00
int SelectedTheme = - 1 ;
2023-01-05 11:21:10 +00:00
for ( int i = 0 ; i < ( int ) vThemes . size ( ) ; i + + )
2020-09-18 16:45:42 +00:00
{
2023-01-05 11:21:10 +00:00
if ( str_comp ( vThemes [ i ] . m_Name . c_str ( ) , g_Config . m_ClMenuMap ) = = 0 )
2020-09-18 16:45:42 +00:00
{
SelectedTheme = i ;
break ;
}
}
2023-01-05 11:21:10 +00:00
const int OldSelected = SelectedTheme ;
2020-09-18 16:45:42 +00:00
2023-01-05 11:21:10 +00:00
static CListBox s_ListBox ;
s_ListBox . DoHeader ( & MainView , Localize ( " Theme " ) , 20.0f ) ;
s_ListBox . DoStart ( 20.0f , vThemes . size ( ) , 1 , 3 , SelectedTheme , nullptr , true ) ;
2020-09-18 16:45:42 +00:00
2023-01-05 11:21:10 +00:00
for ( int i = 0 ; i < ( int ) vThemes . size ( ) ; i + + )
2020-09-18 16:45:42 +00:00
{
2023-01-05 11:21:10 +00:00
const CTheme & Theme = vThemes [ i ] ;
const CListboxItem Item = s_ListBox . DoNextItem ( & Theme . m_Name , i = = SelectedTheme ) ;
2020-09-18 16:45:42 +00:00
if ( ! Item . m_Visible )
continue ;
2023-01-05 11:21:10 +00:00
CUIRect Icon , Label ;
Item . m_Rect . VSplitLeft ( Item . m_Rect . h * 2.0f , & Icon , & Label ) ;
2020-09-18 16:45:42 +00:00
// draw icon if it exists
2012-08-12 12:02:50 +00:00
if ( Theme . m_IconTexture . IsValid ( ) )
2020-09-18 16:45:42 +00:00
{
Icon . VMargin ( 6.0f , & Icon ) ;
Icon . HMargin ( 3.0f , & Icon ) ;
Graphics ( ) - > TextureSet ( Theme . m_IconTexture ) ;
Graphics ( ) - > QuadsBegin ( ) ;
Graphics ( ) - > SetColor ( 1.0f , 1.0f , 1.0f , 1.0f ) ;
IGraphics : : CQuadItem QuadItem ( Icon . x , Icon . y , Icon . w , Icon . h ) ;
Graphics ( ) - > QuadsDrawTL ( & QuadItem , 1 ) ;
Graphics ( ) - > QuadsEnd ( ) ;
}
char aName [ 128 ] ;
2022-05-06 21:51:24 +00:00
if ( Theme . m_Name . empty ( ) )
2022-07-09 16:14:56 +00:00
str_copy ( aName , " (none) " ) ;
2022-05-06 21:51:24 +00:00
else if ( str_comp ( Theme . m_Name . c_str ( ) , " auto " ) = = 0 )
2022-07-09 16:14:56 +00:00
str_copy ( aName , " (seasons) " ) ;
2022-05-06 21:51:24 +00:00
else if ( str_comp ( Theme . m_Name . c_str ( ) , " rand " ) = = 0 )
2022-07-09 16:14:56 +00:00
str_copy ( aName , " (random) " ) ;
2020-09-18 16:45:42 +00:00
else if ( Theme . m_HasDay & & Theme . m_HasNight )
2022-10-27 19:28:49 +00:00
str_copy ( aName , Theme . m_Name . c_str ( ) ) ;
2020-09-18 16:45:42 +00:00
else if ( Theme . m_HasDay & & ! Theme . m_HasNight )
2022-05-06 21:51:24 +00:00
str_format ( aName , sizeof ( aName ) , " %s (day) " , Theme . m_Name . c_str ( ) ) ;
2020-09-18 16:45:42 +00:00
else if ( ! Theme . m_HasDay & & Theme . m_HasNight )
2022-05-06 21:51:24 +00:00
str_format ( aName , sizeof ( aName ) , " %s (night) " , Theme . m_Name . c_str ( ) ) ;
2020-09-18 16:45:42 +00:00
else // generic
2022-10-27 19:28:49 +00:00
str_copy ( aName , Theme . m_Name . c_str ( ) ) ;
2020-09-18 16:45:42 +00:00
2023-01-05 11:21:10 +00:00
SLabelProperties Props ;
Props . m_AlignVertically = 0 ;
UI ( ) - > DoLabel ( & Label , aName , 16.0f * CUI : : ms_FontmodHeight , TEXTALIGN_LEFT , Props ) ;
2020-09-18 16:45:42 +00:00
}
2023-01-05 11:21:10 +00:00
SelectedTheme = s_ListBox . DoEnd ( ) ;
2020-09-18 16:45:42 +00:00
2023-01-05 11:21:10 +00:00
if ( OldSelected ! = SelectedTheme )
2020-09-18 16:45:42 +00:00
{
2023-01-05 11:21:10 +00:00
const CTheme & Theme = vThemes [ SelectedTheme ] ;
str_copy ( g_Config . m_ClMenuMap , Theme . m_Name . c_str ( ) ) ;
m_pBackground - > LoadMenuBackground ( Theme . m_HasDay , Theme . m_HasNight ) ;
2020-09-18 16:45:42 +00:00
}
}
2010-05-29 07:25:38 +00:00
void CMenus : : SetActive ( bool Active )
2008-10-20 23:38:23 +00:00
{
2017-07-15 13:37:05 +00:00
if ( Active ! = m_MenuActive )
2020-12-16 04:55:41 +00:00
{
ms_ColorPicker . m_Active = false ;
2017-07-15 13:37:05 +00:00
Input ( ) - > SetIMEState ( Active ) ;
2022-07-11 16:52:51 +00:00
UI ( ) - > SetHotItem ( nullptr ) ;
UI ( ) - > SetActiveItem ( nullptr ) ;
2020-12-16 04:55:41 +00:00
}
2010-05-29 07:25:38 +00:00
m_MenuActive = Active ;
2010-09-12 10:43:03 +00:00
if ( ! m_MenuActive )
2008-10-20 23:38:23 +00:00
{
2010-09-12 10:43:03 +00:00
if ( m_NeedSendinfo )
{
m_pClient - > SendInfo ( false ) ;
m_NeedSendinfo = false ;
}
2014-04-28 13:19:57 +00:00
if ( m_NeedSendDummyinfo )
{
m_pClient - > SendDummyInfo ( false ) ;
m_NeedSendDummyinfo = false ;
}
2010-10-25 18:09:08 +00:00
if ( Client ( ) - > State ( ) = = IClient : : STATE_ONLINE )
2010-09-12 10:43:03 +00:00
{
m_pClient - > OnRelease ( ) ;
}
2008-10-20 23:38:23 +00:00
}
2011-01-12 00:33:16 +00:00
else if ( Client ( ) - > State ( ) = = IClient : : STATE_DEMOPLAYBACK )
{
m_pClient - > OnRelease ( ) ;
}
2008-10-20 23:38:23 +00:00
}
2010-05-29 07:25:38 +00:00
void CMenus : : OnReset ( )
2008-08-27 15:48:50 +00:00
{
}
2022-01-20 11:19:06 +00:00
void CMenus : : OnShutdown ( )
{
KillServer ( ) ;
}
2022-06-06 20:03:24 +00:00
bool CMenus : : OnCursorMove ( float x , float y , IInput : : ECursorType CursorType )
2008-08-27 15:48:50 +00:00
{
2010-05-29 07:25:38 +00:00
if ( ! m_MenuActive )
2021-10-23 11:48:21 +00:00
return false ;
2011-04-13 18:37:12 +00:00
2022-08-07 20:03:34 +00:00
UI ( ) - > ConvertMouseMove ( & x , & y , CursorType ) ;
2021-11-26 20:55:31 +00:00
m_MousePos . x = clamp ( m_MousePos . x + x , 0.f , ( float ) Graphics ( ) - > WindowWidth ( ) ) ;
m_MousePos . y = clamp ( m_MousePos . y + y , 0.f , ( float ) Graphics ( ) - > WindowHeight ( ) ) ;
2011-04-13 18:37:12 +00:00
2021-10-23 11:48:21 +00:00
return true ;
2008-08-27 15:48:50 +00:00
}
2022-08-21 11:17:09 +00:00
bool CMenus : : OnInput ( IInput : : CEvent Event )
2008-08-27 15:48:50 +00:00
{
2008-10-21 18:25:28 +00:00
// special handle esc and enter for popup purposes
2022-08-21 11:17:09 +00:00
if ( Event . m_Flags & IInput : : FLAG_PRESS & & Event . m_Key = = KEY_ESCAPE )
2008-08-27 20:23:50 +00:00
{
2022-08-21 11:17:09 +00:00
SetActive ( ! IsActive ( ) ) ;
UI ( ) - > OnInput ( Event ) ;
return true ;
2008-10-21 18:25:28 +00:00
}
2010-05-29 07:25:38 +00:00
if ( IsActive ( ) )
2008-10-21 18:25:28 +00:00
{
2010-05-29 07:25:38 +00:00
if ( m_NumInputEvents < MAX_INPUTEVENTS )
2022-08-21 11:17:09 +00:00
m_aInputEvents [ m_NumInputEvents + + ] = Event ;
UI ( ) - > OnInput ( Event ) ;
2008-08-27 20:23:50 +00:00
return true ;
2008-08-30 09:28:31 +00:00
}
2008-08-27 15:48:50 +00:00
return false ;
}
2010-05-29 07:25:38 +00:00
void CMenus : : OnStateChange ( int NewState , int OldState )
2008-08-27 15:48:50 +00:00
{
2010-05-29 07:25:38 +00:00
// reset active item
2022-05-27 09:59:14 +00:00
UI ( ) - > SetActiveItem ( nullptr ) ;
2010-05-29 07:25:38 +00:00
2023-02-19 11:17:56 +00:00
if ( OldState = = IClient : : STATE_ONLINE | | OldState = = IClient : : STATE_OFFLINE )
TextRender ( ) - > DeleteTextContainer ( m_MotdTextContainerIndex ) ;
2010-05-29 07:25:38 +00:00
if ( NewState = = IClient : : STATE_OFFLINE )
2008-08-27 15:48:50 +00:00
{
2020-10-02 13:44:27 +00:00
if ( OldState > = IClient : : STATE_ONLINE & & NewState < IClient : : STATE_QUITTING )
2022-06-26 20:07:10 +00:00
UpdateMusicState ( ) ;
2010-05-29 07:25:38 +00:00
m_Popup = POPUP_NONE ;
if ( Client ( ) - > ErrorString ( ) & & Client ( ) - > ErrorString ( ) [ 0 ] ! = 0 )
2008-08-27 15:48:50 +00:00
{
2010-05-29 07:25:38 +00:00
if ( str_find ( Client ( ) - > ErrorString ( ) , " password " ) )
2008-08-27 15:48:50 +00:00
{
2010-05-29 07:25:38 +00:00
m_Popup = POPUP_PASSWORD ;
UI ( ) - > SetHotItem ( & g_Config . m_Password ) ;
UI ( ) - > SetActiveItem ( & g_Config . m_Password ) ;
2008-08-27 15:48:50 +00:00
}
else
2010-05-29 07:25:38 +00:00
m_Popup = POPUP_DISCONNECTED ;
}
}
else if ( NewState = = IClient : : STATE_LOADING )
2009-01-12 14:03:19 +00:00
{
2010-05-29 07:25:38 +00:00
m_Popup = POPUP_CONNECTING ;
2010-12-16 00:52:29 +00:00
m_DownloadLastCheckTime = time_get ( ) ;
m_DownloadLastCheckSize = 0 ;
2011-04-12 16:59:08 +00:00
m_DownloadSpeed = 0.0f ;
2009-01-12 14:03:19 +00:00
}
2010-05-29 07:25:38 +00:00
else if ( NewState = = IClient : : STATE_CONNECTING )
2022-05-15 19:59:17 +00:00
{
2010-05-29 07:25:38 +00:00
m_Popup = POPUP_CONNECTING ;
2022-05-15 19:59:17 +00:00
}
2018-03-13 20:59:07 +00:00
else if ( NewState = = IClient : : STATE_ONLINE | | NewState = = IClient : : STATE_DEMOPLAYBACK )
2008-08-27 15:48:50 +00:00
{
2020-08-29 10:49:45 +00:00
if ( m_Popup ! = POPUP_WARNING )
{
m_Popup = POPUP_NONE ;
SetActive ( false ) ;
}
2008-08-27 15:48:50 +00:00
}
}
2023-02-19 11:17:56 +00:00
void CMenus : : OnWindowResize ( )
{
TextRender ( ) - > DeleteTextContainer ( m_MotdTextContainerIndex ) ;
}
2010-05-29 07:25:38 +00:00
void CMenus : : OnRender ( )
2008-08-27 15:48:50 +00:00
{
2022-05-27 08:55:32 +00:00
UI ( ) - > StartCheck ( ) ;
2010-05-29 07:25:38 +00:00
if ( Client ( ) - > State ( ) ! = IClient : : STATE_ONLINE & & Client ( ) - > State ( ) ! = IClient : : STATE_DEMOPLAYBACK )
SetActive ( true ) ;
2008-10-06 18:05:01 +00:00
2010-05-29 07:25:38 +00:00
if ( Client ( ) - > State ( ) = = IClient : : STATE_DEMOPLAYBACK )
2008-10-06 18:05:01 +00:00
{
2021-09-22 19:48:55 +00:00
UI ( ) - > MapScreen ( ) ;
RenderDemoPlayer ( * UI ( ) - > Screen ( ) ) ;
2008-10-06 18:05:01 +00:00
}
2011-04-13 18:37:12 +00:00
2010-10-22 13:22:17 +00:00
if ( Client ( ) - > State ( ) = = IClient : : STATE_ONLINE & & m_pClient - > m_ServerMode = = m_pClient - > SERVERMODE_PUREMOD )
2009-01-11 10:40:14 +00:00
{
2010-05-29 07:25:38 +00:00
Client ( ) - > Disconnect ( ) ;
SetActive ( true ) ;
2022-08-21 11:25:06 +00:00
PopupMessage ( Localize ( " Disconnected " ) , Localize ( " The server is running a non-standard tuning on a pure game type. " ) , Localize ( " Ok " ) ) ;
2010-10-22 13:22:17 +00:00
}
2011-04-13 18:37:12 +00:00
2010-05-29 07:25:38 +00:00
if ( ! IsActive ( ) )
2008-10-18 10:52:26 +00:00
{
2022-05-27 15:45:30 +00:00
UI ( ) - > FinishCheck ( ) ;
2022-08-21 11:17:09 +00:00
UI ( ) - > ClearHotkeys ( ) ;
m_NumInputEvents = 0 ;
2008-08-27 15:48:50 +00:00
return ;
2008-10-18 10:52:26 +00:00
}
2011-04-13 18:37:12 +00:00
2008-08-27 15:48:50 +00:00
// update colors
2019-04-26 23:02:31 +00:00
ms_GuiColor = color_cast < ColorRGBA > ( ColorHSLA ( g_Config . m_UiColor , true ) ) ;
2010-05-29 07:25:38 +00:00
2020-09-16 01:30:03 +00:00
ms_ColorTabbarInactiveOutgame = ColorRGBA ( 0 , 0 , 0 , 0.25f ) ;
ms_ColorTabbarActiveOutgame = ColorRGBA ( 0 , 0 , 0 , 0.5f ) ;
ms_ColorTabbarHoverOutgame = ColorRGBA ( 1 , 1 , 1 , 0.25f ) ;
2010-05-29 07:25:38 +00:00
float ColorIngameScaleI = 0.5f ;
float ColorIngameAcaleA = 0.2f ;
2020-09-16 01:30:03 +00:00
2019-04-26 21:47:34 +00:00
ms_ColorTabbarInactiveIngame = ColorRGBA (
2020-09-16 01:30:03 +00:00
ms_GuiColor . r * ColorIngameScaleI ,
ms_GuiColor . g * ColorIngameScaleI ,
ms_GuiColor . b * ColorIngameScaleI ,
ms_GuiColor . a * 0.8f ) ;
2011-04-13 18:37:12 +00:00
2019-04-26 21:47:34 +00:00
ms_ColorTabbarActiveIngame = ColorRGBA (
2020-09-22 16:02:03 +00:00
ms_GuiColor . r * ColorIngameAcaleA ,
ms_GuiColor . g * ColorIngameAcaleA ,
ms_GuiColor . b * ColorIngameAcaleA ,
2010-05-29 07:25:38 +00:00
ms_GuiColor . a ) ;
2011-04-13 18:37:12 +00:00
2020-09-16 01:30:03 +00:00
ms_ColorTabbarHoverIngame = ColorRGBA ( 1 , 1 , 1 , 0.75f ) ;
2008-08-27 15:48:50 +00:00
// update the ui
2010-05-29 07:25:38 +00:00
CUIRect * pScreen = UI ( ) - > Screen ( ) ;
2021-10-23 12:10:14 +00:00
float mx = ( m_MousePos . x / ( float ) Graphics ( ) - > WindowWidth ( ) ) * pScreen - > w ;
float my = ( m_MousePos . y / ( float ) Graphics ( ) - > WindowHeight ( ) ) * pScreen - > h ;
2011-04-13 18:37:12 +00:00
2022-05-27 16:14:31 +00:00
UI ( ) - > Update ( mx , my , mx * 3.0f , my * 3.0f ) ;
2011-04-13 18:37:12 +00:00
2020-08-29 10:49:45 +00:00
Render ( ) ;
2022-05-27 17:30:20 +00:00
RenderTools ( ) - > RenderCursor ( vec2 ( mx , my ) , 24.0f ) ;
2009-01-10 11:16:21 +00:00
// render debug information
2010-05-29 07:25:38 +00:00
if ( g_Config . m_Debug )
2008-08-27 15:48:50 +00:00
{
2021-09-22 19:48:55 +00:00
UI ( ) - > MapScreen ( ) ;
2010-05-29 07:25:38 +00:00
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 ) ;
2008-08-27 15:48:50 +00:00
}
2022-05-27 08:55:32 +00:00
UI ( ) - > FinishCheck ( ) ;
2022-08-21 11:17:09 +00:00
UI ( ) - > ClearHotkeys ( ) ;
2010-05-29 07:25:38 +00:00
m_NumInputEvents = 0 ;
2008-08-27 15:48:50 +00:00
}
2008-09-11 22:45:28 +00:00
2010-05-29 07:25:38 +00:00
void CMenus : : RenderBackground ( )
2008-09-11 22:45:28 +00:00
{
2020-08-31 14:18:45 +00:00
Graphics ( ) - > BlendNormal ( ) ;
2020-09-05 15:13:32 +00:00
2020-09-22 16:02:03 +00:00
float sw = 300 * Graphics ( ) - > ScreenAspect ( ) ;
2008-09-24 15:09:09 +00:00
float sh = 300 ;
2009-10-27 14:38:53 +00:00
Graphics ( ) - > MapScreen ( 0 , 0 , sw , sh ) ;
2008-09-23 11:58:12 +00:00
2008-09-24 15:09:09 +00:00
// render background color
2012-08-12 10:41:50 +00:00
Graphics ( ) - > TextureClear ( ) ;
2009-10-27 14:38:53 +00:00
Graphics ( ) - > QuadsBegin ( ) ;
2020-09-22 16:02:03 +00:00
ColorRGBA Bottom ( ms_GuiColor . r , ms_GuiColor . g , ms_GuiColor . b , 1.0f ) ;
ColorRGBA 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 ) ;
2009-10-27 14:38:53 +00:00
Graphics ( ) - > QuadsEnd ( ) ;
2011-04-13 18:37:12 +00:00
2008-09-24 15:09:09 +00:00
// render the tiles
2012-08-12 10:41:50 +00:00
Graphics ( ) - > TextureClear ( ) ;
2009-10-27 14:38:53 +00:00
Graphics ( ) - > QuadsBegin ( ) ;
2020-09-22 16:02:03 +00:00
float Size = 15.0f ;
2023-02-28 20:31:40 +00:00
float OffsetTime = std : : fmod ( LocalTime ( ) * 0.15f , 2.0f ) ;
2020-09-22 16:02:03 +00:00
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 ) ;
2022-03-20 11:57:50 +00:00
QuadItem = IGraphics : : CQuadItem ( ( x - OffsetTime ) * Size * 2 + ( y & 1 ) * Size , ( y + OffsetTime ) * Size , Size , Size ) ;
2020-09-22 16:02:03 +00:00
Graphics ( ) - > QuadsDrawTL ( & QuadItem , 1 ) ;
}
2009-10-27 14:38:53 +00:00
Graphics ( ) - > QuadsEnd ( ) ;
2008-09-24 15:09:09 +00:00
// render border fade
2012-08-12 10:41:50 +00:00
Graphics ( ) - > TextureSet ( m_TextureBlob ) ;
2009-10-27 14:38:53 +00:00
Graphics ( ) - > QuadsBegin ( ) ;
2020-09-22 16:02:03 +00:00
Graphics ( ) - > SetColor ( 1 , 1 , 1 , 1 ) ;
QuadItem = IGraphics : : CQuadItem ( - 100 , - 100 , sw + 200 , sh + 200 ) ;
Graphics ( ) - > QuadsDrawTL ( & QuadItem , 1 ) ;
2009-10-27 14:38:53 +00:00
Graphics ( ) - > QuadsEnd ( ) ;
2008-09-24 15:09:09 +00:00
2011-04-13 18:37:12 +00:00
// restore screen
2021-09-22 19:48:55 +00:00
UI ( ) - > MapScreen ( ) ;
2008-09-11 22:45:28 +00:00
}
2011-01-30 16:21:41 +00:00
2020-09-03 12:08:26 +00:00
bool CMenus : : CheckHotKey ( int Key ) const
{
return m_Popup = = POPUP_NONE & &
2022-11-14 21:50:59 +00:00
! Input ( ) - > ShiftIsPressed ( ) & & ! Input ( ) - > ModifierIsPressed ( ) & & // no modifier
2021-07-12 09:43:56 +00:00
Input ( ) - > KeyIsPressed ( Key ) & & m_pClient - > m_GameConsole . IsClosed ( ) ;
2020-09-03 12:08:26 +00:00
}
2022-05-23 18:16:18 +00:00
int CMenus : : DoButton_CheckBox_Tristate ( const void * pID , const char * pText , TRISTATE Checked , const CUIRect * pRect )
2011-01-30 16:21:41 +00:00
{
switch ( Checked )
{
2022-05-23 18:16:18 +00:00
case TRISTATE : : NONE :
2011-01-30 16:21:41 +00:00
return DoButton_CheckBox_Common ( pID , pText , " " , pRect ) ;
2022-05-23 18:16:18 +00:00
case TRISTATE : : SOME :
2011-01-30 16:21:41 +00:00
return DoButton_CheckBox_Common ( pID , pText , " O " , pRect ) ;
2022-05-23 18:16:18 +00:00
case TRISTATE : : ALL :
return DoButton_CheckBox_Common ( pID , pText , " X " , pRect ) ;
2011-01-30 16:21:41 +00:00
default :
2022-05-23 18:16:18 +00:00
dbg_assert ( false , " invalid tristate " ) ;
2011-01-30 16:21:41 +00:00
}
2022-05-23 18:16:18 +00:00
dbg_break ( ) ;
2011-12-01 17:48:09 +00:00
}
2014-04-27 03:01:03 +00:00
2020-09-03 12:08:26 +00:00
int CMenus : : MenuImageScan ( const char * pName , int IsDir , int DirType , void * pUser )
{
CMenus * pSelf = ( CMenus * ) pUser ;
if ( IsDir | | ! str_endswith ( pName , " .png " ) )
return 0 ;
2021-09-13 08:06:34 +00:00
char aBuf [ IO_MAX_PATH_LENGTH ] ;
2022-06-23 17:59:38 +00:00
bool ImgExists = false ;
for ( const auto & Img : pSelf - > m_vMenuImages )
2020-09-03 12:08:26 +00:00
{
2022-06-23 17:59:38 +00:00
str_format ( aBuf , std : : size ( aBuf ) , " %s.png " , Img . m_aName ) ;
if ( str_comp ( aBuf , pName ) = = 0 )
{
ImgExists = true ;
break ;
}
2020-09-03 12:08:26 +00:00
}
2022-06-23 17:59:38 +00:00
if ( ! ImgExists )
{
str_format ( aBuf , sizeof ( aBuf ) , " menuimages/%s " , pName ) ;
CImageInfo Info ;
if ( ! pSelf - > Graphics ( ) - > LoadPNG ( & Info , aBuf , DirType ) )
{
str_format ( aBuf , sizeof ( aBuf ) , " failed to load menu image from %s " , pName ) ;
pSelf - > Console ( ) - > Print ( IConsole : : OUTPUT_LEVEL_ADDINFO , " game " , aBuf ) ;
return 0 ;
}
2020-09-03 12:08:26 +00:00
2022-06-23 17:59:38 +00:00
CMenuImage MenuImage ;
MenuImage . m_OrgTexture = pSelf - > Graphics ( ) - > LoadTextureRaw ( Info . m_Width , Info . m_Height , Info . m_Format , Info . m_pData , Info . m_Format , 0 ) ;
2020-09-03 12:08:26 +00:00
2022-06-30 22:36:32 +00:00
unsigned char * pData = ( unsigned char * ) Info . m_pData ;
2022-06-23 17:59:38 +00:00
//int Pitch = Info.m_Width*4;
2020-09-03 12:08:26 +00:00
2022-06-23 17:59:38 +00:00
// create colorless version
int Step = Info . m_Format = = CImageInfo : : FORMAT_RGBA ? 4 : 3 ;
2020-09-03 12:08:26 +00:00
2022-06-23 17:59:38 +00:00
// make the texture gray scale
for ( int i = 0 ; i < Info . m_Width * Info . m_Height ; i + + )
{
2022-06-30 22:36:32 +00:00
int v = ( pData [ i * Step ] + pData [ i * Step + 1 ] + pData [ i * Step + 2 ] ) / 3 ;
pData [ i * Step ] = v ;
pData [ i * Step + 1 ] = v ;
pData [ i * Step + 2 ] = v ;
2022-06-23 17:59:38 +00:00
}
2020-09-03 12:08:26 +00:00
2022-06-23 17:59:38 +00:00
MenuImage . m_GreyTexture = pSelf - > Graphics ( ) - > LoadTextureRaw ( Info . m_Width , Info . m_Height , Info . m_Format , Info . m_pData , Info . m_Format , 0 ) ;
pSelf - > Graphics ( ) - > FreePNG ( & Info ) ;
2020-09-03 12:08:26 +00:00
2022-06-23 17:59:38 +00:00
// set menu image data
str_truncate ( MenuImage . m_aName , sizeof ( MenuImage . m_aName ) , pName , str_length ( pName ) - 4 ) ;
pSelf - > m_vMenuImages . push_back ( MenuImage ) ;
pSelf - > RenderLoading ( Localize ( " Loading DDNet Client " ) , Localize ( " Loading menu images " ) , 1 ) ;
}
2020-09-03 12:08:26 +00:00
return 0 ;
}
const CMenus : : CMenuImage * CMenus : : FindMenuImage ( const char * pName )
{
2022-05-23 20:48:56 +00:00
for ( auto & Image : m_vMenuImages )
if ( str_comp ( Image . m_aName , pName ) = = 0 )
return & Image ;
return nullptr ;
2020-09-03 12:08:26 +00:00
}
void CMenus : : SetMenuPage ( int NewPage )
{
m_MenuPage = NewPage ;
if ( NewPage > = PAGE_INTERNET & & NewPage < = PAGE_KOG )
g_Config . m_UiPage = NewPage ;
}
2020-11-12 13:20:38 +00:00
2022-09-23 17:59:18 +00:00
void CMenus : : RefreshBrowserTab ( int UiPage )
{
if ( UiPage = = PAGE_INTERNET )
2022-09-23 22:56:43 +00:00
ServerBrowser ( ) - > Refresh ( IServerBrowser : : TYPE_INTERNET ) ;
else if ( UiPage = = PAGE_LAN )
ServerBrowser ( ) - > Refresh ( IServerBrowser : : TYPE_LAN ) ;
else if ( UiPage = = PAGE_FAVORITES )
ServerBrowser ( ) - > Refresh ( IServerBrowser : : TYPE_FAVORITES ) ;
else if ( UiPage = = PAGE_DDNET )
{
// start a new server list request
Client ( ) - > RequestDDNetInfo ( ) ;
ServerBrowser ( ) - > Refresh ( IServerBrowser : : TYPE_DDNET ) ;
}
else if ( UiPage = = PAGE_KOG )
{
// start a new server list request
Client ( ) - > RequestDDNetInfo ( ) ;
ServerBrowser ( ) - > Refresh ( IServerBrowser : : TYPE_KOG ) ;
}
2022-09-23 17:59:18 +00:00
}