diff options
| author | Magnus Auvinen <magnus.auvinen@gmail.com> | 2010-05-29 07:25:38 +0000 |
|---|---|---|
| committer | Magnus Auvinen <magnus.auvinen@gmail.com> | 2010-05-29 07:25:38 +0000 |
| commit | 72c06a258940696093f255fb1061beb58e1cdd0b (patch) | |
| tree | 36b9a7712eec2d4f07837eab9c38ef1c5af85319 /src/game/client/components | |
| parent | e56feb597bc743677633432f77513b02907fd169 (diff) | |
| download | zcatch-72c06a258940696093f255fb1061beb58e1cdd0b.tar.gz zcatch-72c06a258940696093f255fb1061beb58e1cdd0b.zip | |
copied refactor to trunk
Diffstat (limited to 'src/game/client/components')
79 files changed, 5752 insertions, 5259 deletions
diff --git a/src/game/client/components/binds.cpp b/src/game/client/components/binds.cpp index e4252656..533658f2 100644 --- a/src/game/client/components/binds.cpp +++ b/src/game/client/components/binds.cpp @@ -1,184 +1,188 @@ -#include <stdlib.h> // atoi -#include <string.h> // strcmp -#include <engine/e_client_interface.h> -#include "binds.hpp" +#include <engine/config.h> +#include <engine/shared/config.h> +#include "binds.h" -bool BINDS::BINDS_SPECIAL::on_input(INPUT_EVENT e) +bool CBinds::CBindsSpecial::OnInput(IInput::CEvent Event) { // don't handle invalid events and keys that arn't set to anything - if(e.key >= KEY_F1 && e.key <= KEY_F15 && binds->keybindings[e.key][0] != 0) + if(Event.m_Key >= KEY_F1 && Event.m_Key <= KEY_F15 && m_pBinds->m_aaKeyBindings[Event.m_Key][0] != 0) { - int stroke = 0; - if(e.flags&INPFLAG_PRESS) - stroke = 1; - console_execute_line_stroked(stroke, binds->keybindings[e.key]); + int Stroke = 0; + if(Event.m_Flags&IInput::FLAG_PRESS) + Stroke = 1; + + m_pBinds->GetConsole()->ExecuteLineStroked(Stroke, m_pBinds->m_aaKeyBindings[Event.m_Key]); return true; } return false; } -BINDS::BINDS() +CBinds::CBinds() { - mem_zero(keybindings, sizeof(keybindings)); - special_binds.binds = this; + mem_zero(m_aaKeyBindings, sizeof(m_aaKeyBindings)); + m_SpecialBinds.m_pBinds = this; } -void BINDS::bind(int keyid, const char *str) +void CBinds::Bind(int KeyId, const char *pStr) { - if(keyid < 0 || keyid >= KEY_LAST) + if(KeyId < 0 || KeyId >= KEY_LAST) return; - str_copy(keybindings[keyid], str, sizeof(keybindings[keyid])); - if(!keybindings[keyid][0]) - dbg_msg("binds", "unbound %s (%d)", inp_key_name(keyid), keyid); + str_copy(m_aaKeyBindings[KeyId], pStr, sizeof(m_aaKeyBindings[KeyId])); + if(!m_aaKeyBindings[KeyId][0]) + dbg_msg("binds", "unbound %s (%d)", Input()->KeyName(KeyId), KeyId); else - dbg_msg("binds", "bound %s (%d) = %s", inp_key_name(keyid), keyid, keybindings[keyid]); + dbg_msg("binds", "bound %s (%d) = %s", Input()->KeyName(KeyId), KeyId, m_aaKeyBindings[KeyId]); } -bool BINDS::on_input(INPUT_EVENT e) +bool CBinds::OnInput(IInput::CEvent e) { // don't handle invalid events and keys that arn't set to anything - if(e.key <= 0 || e.key >= KEY_LAST || keybindings[e.key][0] == 0) + if(e.m_Key <= 0 || e.m_Key >= KEY_LAST || m_aaKeyBindings[e.m_Key][0] == 0) return false; - int stroke = 0; - if(e.flags&INPFLAG_PRESS) - stroke = 1; - console_execute_line_stroked(stroke, keybindings[e.key]); + int Stroke = 0; + if(e.m_Flags&IInput::FLAG_PRESS) + Stroke = 1; + Console()->ExecuteLineStroked(Stroke, m_aaKeyBindings[e.m_Key]); return true; } -void BINDS::unbindall() +void CBinds::UnbindAll() { for(int i = 0; i < KEY_LAST; i++) - keybindings[i][0] = 0; + m_aaKeyBindings[i][0] = 0; } -const char *BINDS::get(int keyid) +const char *CBinds::Get(int KeyId) { - if(keyid > 0 && keyid < KEY_LAST) - return keybindings[keyid]; + if(KeyId > 0 && KeyId < KEY_LAST) + return m_aaKeyBindings[KeyId]; return ""; } -const char *BINDS::get_key(const char *bindstr) +const char *CBinds::GetKey(const char *pBindStr) { - for(int keyid = 0; keyid < KEY_LAST; keyid++) + for(int KeyId = 0; KeyId < KEY_LAST; KeyId++) { - const char *bind = get(keyid); - if(!bind[0]) + const char *pBind = Get(KeyId); + if(!pBind[0]) continue; - if(strcmp(bind, bindstr) == 0) - return inp_key_name(keyid); + if(str_comp(pBind, pBindStr) == 0) + return Input()->KeyName(KeyId); } return ""; } -void BINDS::set_defaults() +void CBinds::SetDefaults() { // set default key bindings - unbindall(); - bind(KEY_F1, "toggle_local_console"); - bind(KEY_F2, "toggle_remote_console"); - bind(KEY_TAB, "+scoreboard"); - bind(KEY_F10, "screenshot"); - - bind('a', "+left"); - bind('d', "+right"); - - bind(KEY_SPACE, "+jump"); - bind(KEY_MOUSE_1, "+fire"); - bind(KEY_MOUSE_2, "+hook"); - bind(KEY_LSHIFT, "+emote"); - - bind('1', "+weapon1"); - bind('2', "+weapon2"); - bind('3', "+weapon3"); - bind('4', "+weapon4"); - bind('5', "+weapon5"); + UnbindAll(); + Bind(KEY_F1, "toggle_local_console"); + Bind(KEY_F2, "toggle_remote_console"); + Bind(KEY_TAB, "+scoreboard"); + Bind(KEY_F10, "screenshot"); + + Bind('a', "+left"); + Bind('d', "+right"); + + Bind(KEY_SPACE, "+jump"); + Bind(KEY_MOUSE_1, "+fire"); + Bind(KEY_MOUSE_2, "+hook"); + Bind(KEY_LSHIFT, "+emote"); + + Bind('1', "+weapon1"); + Bind('2', "+weapon2"); + Bind('3', "+weapon3"); + Bind('4', "+weapon4"); + Bind('5', "+weapon5"); - bind(KEY_MOUSE_WHEEL_UP, "+prevweapon"); - bind(KEY_MOUSE_WHEEL_DOWN, "+nextweapon"); + Bind(KEY_MOUSE_WHEEL_UP, "+prevweapon"); + Bind(KEY_MOUSE_WHEEL_DOWN, "+nextweapon"); - bind('t', "chat all"); - bind('y', "chat team"); + Bind('t', "chat all"); + Bind('y', "chat team"); - bind(KEY_F3, "vote yes"); - bind(KEY_F4, "vote no"); + Bind(KEY_F3, "vote yes"); + Bind(KEY_F4, "vote no"); } -void BINDS::on_console_init() +void CBinds::OnConsoleInit() { // bindings - MACRO_REGISTER_COMMAND("bind", "sr", CFGFLAG_CLIENT, con_bind, this, "Bind key to execute the command"); - MACRO_REGISTER_COMMAND("unbind", "s", CFGFLAG_CLIENT, con_unbind, this, "Unbind key"); - MACRO_REGISTER_COMMAND("unbindall", "", CFGFLAG_CLIENT, con_unbindall, this, "Unbind all keys"); - MACRO_REGISTER_COMMAND("dump_binds", "", CFGFLAG_CLIENT, con_dump_binds, this, "Dump binds"); + IConfig *pConfig = Kernel()->RequestInterface<IConfig>(); + if(pConfig) + pConfig->RegisterCallback(ConfigSaveCallback, this); + + Console()->Register("bind", "sr", CFGFLAG_CLIENT, ConBind, this, "Bind key to execute the command"); + Console()->Register("unbind", "s", CFGFLAG_CLIENT, ConUnbind, this, "Unbind key"); + Console()->Register("unbindall", "", CFGFLAG_CLIENT, ConUnbindAll, this, "Unbind all keys"); + Console()->Register("dump_binds", "", CFGFLAG_CLIENT, ConDumpBinds, this, "Dump binds"); // default bindings - set_defaults(); + SetDefaults(); } -void BINDS::con_bind(void *result, void *user_data) +void CBinds::ConBind(IConsole::IResult *pResult, void *pUserData) { - BINDS *binds = (BINDS *)user_data; - const char *key_name = console_arg_string(result, 0); - int id = binds->get_key_id(key_name); + CBinds *pBinds = (CBinds *)pUserData; + const char *pKeyName = pResult->GetString(0); + int id = pBinds->GetKeyId(pKeyName); if(!id) { - dbg_msg("binds", "key %s not found", key_name); + dbg_msg("binds", "key %s not found", pKeyName); return; } - binds->bind(id, console_arg_string(result, 1)); + pBinds->Bind(id, pResult->GetString(1)); } -void BINDS::con_unbind(void *result, void *user_data) +void CBinds::ConUnbind(IConsole::IResult *pResult, void *pUserData) { - BINDS *binds = (BINDS *)user_data; - const char *key_name = console_arg_string(result, 0); - int id = binds->get_key_id(key_name); + CBinds *pBinds = (CBinds *)pUserData; + const char *pKeyName = pResult->GetString(0); + int id = pBinds->GetKeyId(pKeyName); if(!id) { - dbg_msg("binds", "key %s not found", key_name); + dbg_msg("binds", "key %s not found", pKeyName); return; } - binds->bind(id, ""); + pBinds->Bind(id, ""); } -void BINDS::con_unbindall(void *result, void *user_data) +void CBinds::ConUnbindAll(IConsole::IResult *pResult, void *pUserData) { - BINDS *binds = (BINDS *)user_data; - binds->unbindall(); + CBinds *pBinds = (CBinds *)pUserData; + pBinds->UnbindAll(); } -void BINDS::con_dump_binds(void *result, void *user_data) +void CBinds::ConDumpBinds(IConsole::IResult *pResult, void *pUserData) { - BINDS *binds = (BINDS *)user_data; + CBinds *pBinds = (CBinds *)pUserData; for(int i = 0; i < KEY_LAST; i++) { - if(binds->keybindings[i][0] == 0) + if(pBinds->m_aaKeyBindings[i][0] == 0) continue; - dbg_msg("binds", "%s (%d) = %s", inp_key_name(i), i, binds->keybindings[i]); + dbg_msg("binds", "%s (%d) = %s", pBinds->Input()->KeyName(i), i, pBinds->m_aaKeyBindings[i]); } } -int BINDS::get_key_id(const char *key_name) +int CBinds::GetKeyId(const char *pKeyName) { // check for numeric - if(key_name[0] == '&') + if(pKeyName[0] == '&') { - int i = atoi(key_name+1); + int i = str_toint(pKeyName+1); if(i > 0 && i < KEY_LAST) return i; // numeric } @@ -186,37 +190,39 @@ int BINDS::get_key_id(const char *key_name) // search for key for(int i = 0; i < KEY_LAST; i++) { - if(strcmp(key_name, inp_key_name(i)) == 0) + if(str_comp(pKeyName, Input()->KeyName(i)) == 0) return i; } return 0; } -void BINDS::on_save() +void CBinds::ConfigSaveCallback(IConfig *pConfig, void *pUserData) { - char buffer[256]; - char *end = buffer+sizeof(buffer)-8; - client_save_line("unbindall"); + CBinds *pSelf = (CBinds *)pUserData; + + char aBuffer[256]; + char *pEnd = aBuffer+sizeof(aBuffer)-8; + pConfig->WriteLine("unbindall"); for(int i = 0; i < KEY_LAST; i++) { - if(keybindings[i][0] == 0) + if(pSelf->m_aaKeyBindings[i][0] == 0) continue; - str_format(buffer, sizeof(buffer), "bind %s ", inp_key_name(i)); + str_format(aBuffer, sizeof(aBuffer), "bind %s ", pSelf->Input()->KeyName(i)); // process the string. we need to escape some characters - const char *src = keybindings[i]; - char *dst = buffer + strlen(buffer); - *dst++ = '"'; - while(*src && dst < end) + const char *pSrc = pSelf->m_aaKeyBindings[i]; + char *pDst = aBuffer + str_length(aBuffer); + *pDst++ = '"'; + while(*pSrc && pDst < pEnd) { - if(*src == '"' || *src == '\\') // escape \ and " - *dst++ = '\\'; - *dst++ = *src++; + if(*pSrc == '"' || *pSrc == '\\') // escape \ and " + *pDst++ = '\\'; + *pDst++ = *pSrc++; } - *dst++ = '"'; - *dst++ = 0; + *pDst++ = '"'; + *pDst++ = 0; - client_save_line(buffer); + pConfig->WriteLine(aBuffer); } } diff --git a/src/game/client/components/binds.h b/src/game/client/components/binds.h new file mode 100644 index 00000000..e8393979 --- /dev/null +++ b/src/game/client/components/binds.h @@ -0,0 +1,41 @@ +#ifndef GAME_CLIENT_COMPONENTS_BINDS_H +#define GAME_CLIENT_COMPONENTS_BINDS_H +#include <game/client/component.h> +#include <engine/keys.h> + +class CBinds : public CComponent +{ + char m_aaKeyBindings[KEY_LAST][128]; + + int GetKeyId(const char *pKeyName); + + static void ConBind(IConsole::IResult *pResult, void *pUserData); + static void ConUnbind(IConsole::IResult *pResult, void *pUserData); + static void ConUnbindAll(IConsole::IResult *pResult, void *pUserData); + static void ConDumpBinds(IConsole::IResult *pResult, void *pUserData); + class IConsole *GetConsole() const { return Console(); } + + static void ConfigSaveCallback(class IConfig *pConfig, void *pUserData); + +public: + CBinds(); + + class CBindsSpecial : public CComponent + { + public: + CBinds *m_pBinds; + virtual bool OnInput(IInput::CEvent Event); + }; + + CBindsSpecial m_SpecialBinds; + + void Bind(int KeyId, const char *pStr); + void SetDefaults(); + void UnbindAll(); + const char *Get(int KeyId); + const char *GetKey(const char *pBindStr); + + virtual void OnConsoleInit(); + virtual bool OnInput(IInput::CEvent Event); +}; +#endif diff --git a/src/game/client/components/binds.hpp b/src/game/client/components/binds.hpp deleted file mode 100644 index bdf242f9..00000000 --- a/src/game/client/components/binds.hpp +++ /dev/null @@ -1,35 +0,0 @@ -#include <game/client/component.hpp> - -class BINDS : public COMPONENT -{ - char keybindings[KEY_LAST][128]; - - int get_key_id(const char *key_name); - - static void con_bind(void *result, void *user_data); - static void con_unbind(void *result, void *user_data); - static void con_unbindall(void *result, void *user_data); - static void con_dump_binds(void *result, void *user_data); - -public: - BINDS(); - - class BINDS_SPECIAL : public COMPONENT - { - public: - BINDS *binds; - virtual bool on_input(INPUT_EVENT e); - }; - - BINDS_SPECIAL special_binds; - - void bind(int keyid, const char *str); - void set_defaults(); - void unbindall(); - const char *get(int keyid); - const char *get_key(const char *bindstr); - - virtual void on_save(); - virtual void on_console_init(); - virtual bool on_input(INPUT_EVENT e); -}; diff --git a/src/game/client/components/broadcast.cpp b/src/game/client/components/broadcast.cpp index b86ed658..c3eb3b56 100644 --- a/src/game/client/components/broadcast.cpp +++ b/src/game/client/components/broadcast.cpp @@ -1,36 +1,36 @@ -#include <engine/e_client_interface.h> -#include <engine/e_config.h> -#include <engine/client/graphics.h> -#include <game/generated/g_protocol.hpp> -#include <game/generated/gc_data.hpp> +#include <engine/shared/config.h> +#include <engine/graphics.h> +#include <engine/textrender.h> +#include <game/generated/protocol.h> +#include <game/generated/client_data.h> -#include <game/client/gameclient.hpp> +#include <game/client/gameclient.h> -#include "broadcast.hpp" +#include "broadcast.h" -void BROADCAST::on_reset() +void CBroadcast::OnReset() { - broadcast_time = 0; + m_BroadcastTime = 0; } -void BROADCAST::on_render() +void CBroadcast::OnRender() { Graphics()->MapScreen(0, 0, 300*Graphics()->ScreenAspect(), 300); - if(time_get() < broadcast_time) + if(time_get() < m_BroadcastTime) { - float w = gfx_text_width(0, 14, broadcast_text, -1); - gfx_text(0, 150*Graphics()->ScreenAspect()-w/2, 35, 14, broadcast_text, -1); + float w = TextRender()->TextWidth(0, 14, m_aBroadcastText, -1); + TextRender()->Text(0, 150*Graphics()->ScreenAspect()-w/2, 35, 14, m_aBroadcastText, -1); } } -void BROADCAST::on_message(int msgtype, void *rawmsg) +void CBroadcast::OnMessage(int MsgType, void *pRawMsg) { - if(msgtype == NETMSGTYPE_SV_BROADCAST) + if(MsgType == NETMSGTYPE_SV_BROADCAST) { - NETMSG_SV_BROADCAST *msg = (NETMSG_SV_BROADCAST *)rawmsg; - str_copy(broadcast_text, msg->message, sizeof(broadcast_text)); - broadcast_time = time_get()+time_freq()*10; + CNetMsg_Sv_Broadcast *pMsg = (CNetMsg_Sv_Broadcast *)pRawMsg; + str_copy(m_aBroadcastText, pMsg->m_pMessage, sizeof(m_aBroadcastText)); + m_BroadcastTime = time_get()+time_freq()*10; } } diff --git a/src/game/client/components/broadcast.h b/src/game/client/components/broadcast.h new file mode 100644 index 00000000..ed281a2f --- /dev/null +++ b/src/game/client/components/broadcast.h @@ -0,0 +1,17 @@ +#ifndef GAME_CLIENT_COMPONENTS_BROADCAST_H +#define GAME_CLIENT_COMPONENTS_BROADCAST_H +#include <game/client/component.h> + +class CBroadcast : public CComponent +{ +public: + // broadcasts + char m_aBroadcastText[1024]; + int64 m_BroadcastTime; + + virtual void OnReset(); + virtual void OnRender(); + virtual void OnMessage(int MsgType, void *pRawMsg); +}; + +#endif diff --git a/src/game/client/components/broadcast.hpp b/src/game/client/components/broadcast.hpp deleted file mode 100644 index 102201cc..00000000 --- a/src/game/client/components/broadcast.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#include <game/client/component.hpp> - -class BROADCAST : public COMPONENT -{ -public: - // broadcasts - char broadcast_text[1024]; - int64 broadcast_time; - - virtual void on_reset(); - virtual void on_render(); - virtual void on_message(int msgtype, void *rawmsg); -}; - diff --git a/src/game/client/components/camera.cpp b/src/game/client/components/camera.cpp index 7b188e00..96baf459 100644 --- a/src/game/client/components/camera.cpp +++ b/src/game/client/components/camera.cpp @@ -1,40 +1,37 @@ -extern "C" { - #include <engine/e_config.h> - #include <engine/e_client_interface.h> -} +#include <engine/shared/config.h> -#include <base/math.hpp> -#include <game/collision.hpp> -#include <game/client/gameclient.hpp> -#include <game/client/component.hpp> +#include <base/math.h> +#include <game/collision.h> +#include <game/client/gameclient.h> +#include <game/client/component.h> -#include "camera.hpp" -#include "controls.hpp" +#include "camera.h" +#include "controls.h" -CAMERA::CAMERA() +CCamera::CCamera() { } -void CAMERA::on_render() +void CCamera::OnRender() { //vec2 center; - zoom = 1.0f; + m_Zoom = 1.0f; // update camera center - if(gameclient.snap.spectate) - center = gameclient.controls->mouse_pos; + if(m_pClient->m_Snap.m_Spectate) + m_Center = m_pClient->m_pControls->m_MousePos; else { - float l = length(gameclient.controls->mouse_pos); - float deadzone = config.cl_mouse_deadzone; - float follow_factor = config.cl_mouse_followfactor/100.0f; - vec2 camera_offset(0, 0); + float l = length(m_pClient->m_pControls->m_MousePos); + float DeadZone = g_Config.m_ClMouseDeadzone; + float FollowFactor = g_Config.m_ClMouseFollowfactor/100.0f; + vec2 CameraOffset(0, 0); - float offset_amount = max(l-deadzone, 0.0f) * follow_factor; + float OffsetAmount = max(l-DeadZone, 0.0f) * FollowFactor; if(l > 0.0001f) // make sure that this isn't 0 - camera_offset = normalize(gameclient.controls->mouse_pos)*offset_amount; + CameraOffset = normalize(m_pClient->m_pControls->m_MousePos)*OffsetAmount; - center = gameclient.local_character_pos + camera_offset; + m_Center = m_pClient->m_LocalCharacterPos + CameraOffset; } } diff --git a/src/game/client/components/camera.h b/src/game/client/components/camera.h new file mode 100644 index 00000000..9654bdf6 --- /dev/null +++ b/src/game/client/components/camera.h @@ -0,0 +1,16 @@ +#ifndef GAME_CLIENT_COMPONENTS_CAMERA_H +#define GAME_CLIENT_COMPONENTS_CAMERA_H +#include <base/vmath.h> +#include <game/client/component.h> + +class CCamera : public CComponent +{ +public: + vec2 m_Center; + float m_Zoom; + + CCamera(); + virtual void OnRender(); +}; + +#endif diff --git a/src/game/client/components/camera.hpp b/src/game/client/components/camera.hpp deleted file mode 100644 index 1cb05f5b..00000000 --- a/src/game/client/components/camera.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#include <base/vmath.hpp> -#include <game/client/component.hpp> - -class CAMERA : public COMPONENT -{ -public: - vec2 center; - float zoom; - - CAMERA(); - virtual void on_render(); -}; - diff --git a/src/game/client/components/chat.cpp b/src/game/client/components/chat.cpp index fdf1d21b..1a2c828d 100644 --- a/src/game/client/components/chat.cpp +++ b/src/game/client/components/chat.cpp @@ -1,227 +1,263 @@ -#include <string.h> // strcmp -#include <engine/e_client_interface.h> -#include <engine/client/graphics.h> -#include <game/generated/g_protocol.hpp> -#include <game/generated/gc_data.hpp> +#include <engine/graphics.h> +#include <engine/textrender.h> +#include <engine/keys.h> +#include <engine/shared/config.h> -#include <game/client/gameclient.hpp> +#include <game/generated/protocol.h> +#include <game/generated/client_data.h> -#include <game/client/components/sounds.hpp> +#include <game/client/gameclient.h> -#include "chat.hpp" +#include <game/client/components/sounds.h> +#include <game/localization.h> -void CHAT::on_statechange(int new_state, int old_state) +#include "chat.h" + + +CChat::CChat() { - if(old_state <= CLIENTSTATE_CONNECTING) + OnReset(); +} + +void CChat::OnReset() +{ + for(int i = 0; i < MAX_LINES; i++) { - mode = MODE_NONE; + m_aLines[i].m_Time = 0; + m_aLines[i].m_aText[0] = 0; + m_aLines[i].m_aName[0] = 0; + } +} + +void CChat::OnStateChange(int NewState, int OldState) +{ + if(OldState <= IClient::STATE_CONNECTING) + { + m_Mode = MODE_NONE; for(int i = 0; i < MAX_LINES; i++) - lines[i].time = 0; - current_line = 0; + m_aLines[i].m_Time = 0; + m_CurrentLine = 0; } } -void CHAT::con_say(void *result, void *user_data) +void CChat::ConSay(IConsole::IResult *pResult, void *pUserData) { - ((CHAT*)user_data)->say(0, console_arg_string(result, 0)); + ((CChat*)pUserData)->Say(0, pResult->GetString(0)); } -void CHAT::con_sayteam(void *result, void *user_data) +void CChat::ConSayTeam(IConsole::IResult *pResult, void *pUserData) { - ((CHAT*)user_data)->say(1, console_arg_string(result, 0)); + ((CChat*)pUserData)->Say(1, pResult->GetString(0)); } -void CHAT::con_chat(void *result, void *user_data) +void CChat::ConChat(IConsole::IResult *pResult, void *pUserData) { - const char *mode = console_arg_string(result, 0); - if(strcmp(mode, "all") == 0) - ((CHAT*)user_data)->enable_mode(0); - else if(strcmp(mode, "team") == 0) - ((CHAT*)user_data)->enable_mode(1); + const char *pMode = pResult->GetString(0); + if(str_comp(pMode, "all") == 0) + ((CChat*)pUserData)->EnableMode(0); + else if(str_comp(pMode, "team") == 0) + ((CChat*)pUserData)->EnableMode(1); else dbg_msg("console", "expected all or team as mode"); } -void CHAT::on_console_init() +void CChat::OnConsoleInit() { - MACRO_REGISTER_COMMAND("say", "r", CFGFLAG_CLIENT, con_say, this, "Say in chat"); - MACRO_REGISTER_COMMAND("say_team", "r", CFGFLAG_CLIENT, con_sayteam, this, "Say in team chat"); - MACRO_REGISTER_COMMAND("chat", "s", CFGFLAG_CLIENT, con_chat, this, "Enable chat with all/team mode"); + Console()->Register("say", "r", CFGFLAG_CLIENT, ConSay, this, "Say in chat"); + Console()->Register("say_team", "r", CFGFLAG_CLIENT, ConSayTeam, this, "Say in team chat"); + Console()->Register("chat", "s", CFGFLAG_CLIENT, ConChat, this, "Enable chat with all/team mode"); } -bool CHAT::on_input(INPUT_EVENT e) +bool CChat::OnInput(IInput::CEvent e) { - if(mode == MODE_NONE) + if(m_Mode == MODE_NONE) return false; - if(e.flags&INPFLAG_PRESS && e.key == KEY_ESCAPE) - mode = MODE_NONE; - else if(e.flags&INPFLAG_PRESS && (e.key == KEY_RETURN || e.key == KEY_KP_ENTER)) + if(e.m_Flags&IInput::FLAG_PRESS && e.m_Key == KEY_ESCAPE) + m_Mode = MODE_NONE; + else if(e.m_Flags&IInput::FLAG_PRESS && (e.m_Key == KEY_RETURN || e.m_Key == KEY_KP_ENTER)) { - if(input.get_string()[0]) - gameclient.chat->say(mode == MODE_ALL ? 0 : 1, input.get_string()); - mode = MODE_NONE; + if(m_Input.GetString()[0]) + Say(m_Mode == MODE_ALL ? 0 : 1, m_Input.GetString()); + m_Mode = MODE_NONE; } else - input.process_input(e); + m_Input.ProcessInput(e); return true; } -void CHAT::enable_mode(int team) +void CChat::EnableMode(int Team) { - if(mode == MODE_NONE) + if(m_Mode == MODE_NONE) { - if(team) - mode = MODE_TEAM; + if(Team) + m_Mode = MODE_TEAM; else - mode = MODE_ALL; + m_Mode = MODE_ALL; - input.clear(); - inp_clear_events(); + m_Input.Clear(); + Input()->ClearEvents(); } } -void CHAT::on_message(int msgtype, void *rawmsg) +void CChat::OnMessage(int MsgType, void *pRawMsg) { - if(msgtype == NETMSGTYPE_SV_CHAT) + if(MsgType == NETMSGTYPE_SV_CHAT) { - NETMSG_SV_CHAT *msg = (NETMSG_SV_CHAT *)rawmsg; - add_line(msg->cid, msg->team, msg->message); + CNetMsg_Sv_Chat *pMsg = (CNetMsg_Sv_Chat *)pRawMsg; + AddLine(pMsg->m_Cid, pMsg->m_Team, pMsg->m_pMessage); } } -void CHAT::add_line(int client_id, int team, const char *line) +void CChat::AddLine(int ClientId, int Team, const char *pLine) { - current_line = (current_line+1)%MAX_LINES; - lines[current_line].time = time_get(); - lines[current_line].client_id = client_id; - lines[current_line].team = team; - lines[current_line].name_color = -2; - - if(client_id == -1) // server message + char *p = const_cast<char*>(pLine); + while(*p) { - str_copy(lines[current_line].name, "*** ", sizeof(lines[current_line].name)); - str_format(lines[current_line].text, sizeof(lines[current_line].text), "%s", line); - } - else - { - if(gameclient.clients[client_id].team == -1) - lines[current_line].name_color = -1; + pLine = p; + // find line seperator and strip multiline + while(*p) + { + if(*p++ == '\n') + { + *(p-1) = 0; + break; + } + } - if(gameclient.snap.gameobj && gameclient.snap.gameobj->flags&GAMEFLAG_TEAMS) + m_CurrentLine = (m_CurrentLine+1)%MAX_LINES; + m_aLines[m_CurrentLine].m_Time = time_get(); + m_aLines[m_CurrentLine].m_ClientId = ClientId; + m_aLines[m_CurrentLine].m_Team = Team; + m_aLines[m_CurrentLine].m_NameColor = -2; + + if(ClientId == -1) // server message + { + str_copy(m_aLines[m_CurrentLine].m_aName, "*** ", sizeof(m_aLines[m_CurrentLine].m_aName)); + str_format(m_aLines[m_CurrentLine].m_aText, sizeof(m_aLines[m_CurrentLine].m_aText), "%s", pLine); + } + else { - if(gameclient.clients[client_id].team == 0) - lines[current_line].name_color = 0; - else if(gameclient.clients[client_id].team == 1) - lines[current_line].name_color = 1; + if(m_pClient->m_aClients[ClientId].m_Team == -1) + m_aLines[m_CurrentLine].m_NameColor = -1; + + if(m_pClient->m_Snap.m_pGameobj && m_pClient->m_Snap.m_pGameobj->m_Flags&GAMEFLAG_TEAMS) + { + if(m_pClient->m_aClients[ClientId].m_Team == 0) + m_aLines[m_CurrentLine].m_NameColor = 0; + else if(m_pClient->m_aClients[ClientId].m_Team == 1) + m_aLines[m_CurrentLine].m_NameColor = 1; + } + + str_copy(m_aLines[m_CurrentLine].m_aName, m_pClient->m_aClients[ClientId].m_aName, sizeof(m_aLines[m_CurrentLine].m_aName)); + str_format(m_aLines[m_CurrentLine].m_aText, sizeof(m_aLines[m_CurrentLine].m_aText), ": %s", pLine); } - str_copy(lines[current_line].name, gameclient.clients[client_id].name, sizeof(lines[current_line].name)); - str_format(lines[current_line].text, sizeof(lines[current_line].text), ": %s", line); + char aBuf[1024]; + str_format(aBuf, sizeof(aBuf), "[chat]%s%s", m_aLines[m_CurrentLine].m_aName, m_aLines[m_CurrentLine].m_aText); + Console()->Print(aBuf); } - + // play sound - if(client_id >= 0) - gameclient.sounds->play(SOUNDS::CHN_GUI, SOUND_CHAT_CLIENT, 0, vec2(0,0)); + if(ClientId >= 0) + m_pClient->m_pSounds->Play(CSounds::CHN_GUI, SOUND_CHAT_CLIENT, 0, vec2(0,0)); else - gameclient.sounds->play(SOUNDS::CHN_GUI, SOUND_CHAT_SERVER, 0, vec2(0,0)); - - dbg_msg("chat", "%s%s", lines[current_line].name, lines[current_line].text); + m_pClient->m_pSounds->Play(CSounds::CHN_GUI, SOUND_CHAT_SERVER, 0, vec2(0,0)); } -void CHAT::on_render() +void CChat::OnRender() { Graphics()->MapScreen(0,0,300*Graphics()->ScreenAspect(),300); float x = 10.0f; float y = 300.0f-20.0f; - if(mode != MODE_NONE) + if(m_Mode != MODE_NONE) { // render chat input - TEXT_CURSOR cursor; - gfx_text_set_cursor(&cursor, x, y, 8.0f, TEXTFLAG_RENDER); - cursor.line_width = 200.0f; + CTextCursor Cursor; + TextRender()->SetCursor(&Cursor, x, y, 8.0f, TEXTFLAG_RENDER); + Cursor.m_LineWidth = 200.0f; - if(mode == MODE_ALL) - gfx_text_ex(&cursor, localize("All"), -1); - else if(mode == MODE_TEAM) - gfx_text_ex(&cursor, localize("Team"), -1); + if(m_Mode == MODE_ALL) + TextRender()->TextEx(&Cursor, Localize("All"), -1); + else if(m_Mode == MODE_TEAM) + TextRender()->TextEx(&Cursor, Localize("Team"), -1); else - gfx_text_ex(&cursor, localize("Chat"), -1); + TextRender()->TextEx(&Cursor, Localize("Chat"), -1); - gfx_text_ex(&cursor, ": ", -1); + TextRender()->TextEx(&Cursor, ": ", -1); - gfx_text_ex(&cursor, input.get_string(), input.cursor_offset()); - TEXT_CURSOR marker = cursor; - gfx_text_ex(&marker, "|", -1); - gfx_text_ex(&cursor, input.get_string()+input.cursor_offset(), -1); + TextRender()->TextEx(&Cursor, m_Input.GetString(), m_Input.GetCursorOffset()); + CTextCursor Marker = Cursor; + TextRender()->TextEx(&Marker, "|", -1); + TextRender()->TextEx(&Cursor, m_Input.GetString()+m_Input.GetCursorOffset(), -1); } y -= 8; int i; + int64 Now = time_get(); for(i = 0; i < MAX_LINES; i++) { - int r = ((current_line-i)+MAX_LINES)%MAX_LINES; - if(time_get() > lines[r].time+15*time_freq()) + int r = ((m_CurrentLine-i)+MAX_LINES)%MAX_LINES; + if(Now > m_aLines[r].m_Time+15*time_freq()) break; - float begin = x; - float fontsize = 7.0f; + float Begin = x; + float FontSize = 7.0f; // get the y offset - TEXT_CURSOR cursor; - gfx_text_set_cursor(&cursor, begin, 0, fontsize, 0); - cursor.line_width = 200.0f; - gfx_text_ex(&cursor, lines[r].name, -1); - gfx_text_ex(&cursor, lines[r].text, -1); - y -= cursor.y + cursor.font_size; + CTextCursor Cursor; + TextRender()->SetCursor(&Cursor, Begin, 0, FontSize, 0); + Cursor.m_LineWidth = 200.0f; + TextRender()->TextEx(&Cursor, m_aLines[r].m_aName, -1); + TextRender()->TextEx(&Cursor, m_aLines[r].m_aText, -1); + y -= Cursor.m_Y + Cursor.m_FontSize; // cut off if msgs waste too much space if(y < 200.0f) break; // reset the cursor - gfx_text_set_cursor(&cursor, begin, y, fontsize, TEXTFLAG_RENDER); - cursor.line_width = 200.0f; + TextRender()->SetCursor(&Cursor, Begin, y, FontSize, TEXTFLAG_RENDER); + Cursor.m_LineWidth = 200.0f; // render name - gfx_text_color(0.8f,0.8f,0.8f,1); - if(lines[r].client_id == -1) - gfx_text_color(1,1,0.5f,1); // system - else if(lines[r].team) - gfx_text_color(0.45f,0.9f,0.45f,1); // team message - else if(lines[r].name_color == 0) - gfx_text_color(1.0f,0.5f,0.5f,1); // red - else if(lines[r].name_color == 1) - gfx_text_color(0.7f,0.7f,1.0f,1); // blue - else if(lines[r].name_color == -1) - gfx_text_color(0.75f,0.5f,0.75f, 1); // spectator + TextRender()->TextColor(0.8f,0.8f,0.8f,1); + if(m_aLines[r].m_ClientId == -1) + TextRender()->TextColor(1,1,0.5f,1); // system + else if(m_aLines[r].m_Team) + TextRender()->TextColor(0.45f,0.9f,0.45f,1); // team message + else if(m_aLines[r].m_NameColor == 0) + TextRender()->TextColor(1.0f,0.5f,0.5f,1); // red + else if(m_aLines[r].m_NameColor == 1) + TextRender()->TextColor(0.7f,0.7f,1.0f,1); // blue + else if(m_aLines[r].m_NameColor == -1) + TextRender()->TextColor(0.75f,0.5f,0.75f, 1); // spectator // render name - gfx_text_ex(&cursor, lines[r].name, -1); + TextRender()->TextEx(&Cursor, m_aLines[r].m_aName, -1); // render line - gfx_text_color(1,1,1,1); - if(lines[r].client_id == -1) - gfx_text_color(1,1,0.5f,1); // system - else if(lines[r].team) - gfx_text_color(0.65f,1,0.65f,1); // team message + TextRender()->TextColor(1,1,1,1); + if(m_aLines[r].m_ClientId == -1) + TextRender()->TextColor(1,1,0.5f,1); // system + else if(m_aLines[r].m_Team) + TextRender()->TextColor(0.65f,1,0.65f,1); // team message - gfx_text_ex(&cursor, lines[r].text, -1); + TextRender()->TextEx(&Cursor, m_aLines[r].m_aText, -1); } - gfx_text_color(1,1,1,1); + TextRender()->TextColor(1,1,1,1); } -void CHAT::say(int team, const char *line) +void CChat::Say(int Team, const char *pLine) { // send chat message - NETMSG_CL_SAY msg; - msg.team = team; - msg.message = line; - msg.pack(MSGFLAG_VITAL); - client_send_msg(); + CNetMsg_Cl_Say Msg; + Msg.m_Team = Team; + Msg.m_pMessage = pLine; + Client()->SendPackMsg(&Msg, MSGFLAG_VITAL); } diff --git a/src/game/client/components/chat.h b/src/game/client/components/chat.h new file mode 100644 index 00000000..8a33e9e8 --- /dev/null +++ b/src/game/client/components/chat.h @@ -0,0 +1,60 @@ +#ifndef GAME_CLIENT_COMPONENTS_CHAT_H +#define GAME_CLIENT_COMPONENTS_CHAT_H +#include <game/client/component.h> +#include <game/client/lineinput.h> + +class CChat : public CComponent +{ + CLineInput m_Input; + + enum + { + MAX_LINES = 10, + }; + + struct CLine + { + int64 m_Time; + int m_ClientId; + int m_Team; + int m_NameColor; + char m_aName[64]; + char m_aText[512]; + }; + + CLine m_aLines[MAX_LINES]; + int m_CurrentLine; + + // chat + enum + { + MODE_NONE=0, + MODE_ALL, + MODE_TEAM, + }; + + int m_Mode; + + static void ConSay(IConsole::IResult *pResult, void *pUserData); + static void ConSayTeam(IConsole::IResult *pResult, void *pUserData); + static void ConChat(IConsole::IResult *pResult, void *pUserData); + +public: + CChat(); + + bool IsActive() const { return m_Mode != MODE_NONE; } + + void AddLine(int ClientId, int Team, const char *pLine); + + void EnableMode(int Team); + + void Say(int Team, const char *pLine); + + virtual void OnReset(); + virtual void OnConsoleInit(); + virtual void OnStateChange(int NewState, int OldState); + virtual void OnRender(); + virtual void OnMessage(int MsgType, void *pRawMsg); + virtual bool OnInput(IInput::CEvent Event); +}; +#endif diff --git a/src/game/client/components/chat.hpp b/src/game/client/components/chat.hpp deleted file mode 100644 index ca34237d..00000000 --- a/src/game/client/components/chat.hpp +++ /dev/null @@ -1,54 +0,0 @@ -#include <game/client/component.hpp> -#include <game/client/lineinput.hpp> - -class CHAT : public COMPONENT -{ - LINEINPUT input; - - enum - { - MAX_LINES = 10, - }; - - struct LINE - { - int64 time; - int client_id; - int team; - int name_color; - char name[64]; - char text[512]; - }; - - LINE lines[MAX_LINES]; - int current_line; - - // chat - enum - { - MODE_NONE=0, - MODE_ALL, - MODE_TEAM, - }; - - int mode; - - static void con_say(void *result, void *user_data); - static void con_sayteam(void *result, void *user_data); - static void con_chat(void *result, void *user_data); - -public: - bool is_active() const { return mode != MODE_NONE; } - - void add_line(int client_id, int team, const char *line); - - void enable_mode(int team); - - void say(int team, const char *line); - - virtual void on_console_init(); - virtual void on_statechange(int new_state, int old_state); - virtual void on_render(); - virtual void on_message(int msgtype, void *rawmsg); - virtual bool on_input(INPUT_EVENT e); -}; diff --git a/src/game/client/components/console.cpp b/src/game/client/components/console.cpp index 382cb134..7de85f69 100644 --- a/src/game/client/components/console.cpp +++ b/src/game/client/components/console.cpp @@ -1,26 +1,29 @@ -//#include "gc_console.hpp" +//#include "gc_console.h" #include <math.h> -#include <game/generated/gc_data.hpp> +#include <game/generated/client_data.h> #include <base/system.h> -#include <engine/e_client_interface.h> -#include <engine/client/graphics.h> - -#include <engine/e_ringbuffer.h> +#include <engine/shared/ringbuffer.h> +#include <engine/shared/config.h> +#include <engine/graphics.h> +#include <engine/textrender.h> +#include <engine/keys.h> +#include <engine/console.h> #include <cstring> #include <cstdio> -#include <game/client/ui.hpp> +#include <game/client/ui.h> -#include <game/version.hpp> +#include <game/version.h> -#include <game/client/lineinput.hpp> -#include <game/client/render.hpp> +#include <game/client/lineinput.h> +#include <game/client/render.h> +#include <game/client/components/menus.h> -#include "console.hpp" +#include "console.h" enum { @@ -30,479 +33,550 @@ enum CONSOLE_CLOSING, }; -CONSOLE::INSTANCE::INSTANCE(int t) +CGameConsole::CInstance::CInstance(CGameConsole *pGameConsole, int Type) { + m_pGameConsole = pGameConsole; // init ringbuffers //history = ringbuf_init(history_data, sizeof(history_data), RINGBUF_FLAG_RECYCLE); //backlog = ringbuf_init(backlog_data, sizeof(backlog_data), RINGBUF_FLAG_RECYCLE); - history_entry = 0x0; + m_pHistoryEntry = 0x0; - type = t; + m_Type = Type; - if(t == 0) - completion_flagmask = CFGFLAG_CLIENT; + if(Type == 0) + m_CompletionFlagmask = CFGFLAG_CLIENT; else - completion_flagmask = CFGFLAG_SERVER; + m_CompletionFlagmask = CFGFLAG_SERVER; - completion_buffer[0] = 0; - completion_chosen = -1; + m_aCompletionBuffer[0] = 0; + m_CompletionChosen = -1; - command = 0x0; + m_pCommand = 0x0; } -void CONSOLE::INSTANCE::execute_line(const char *line) +void CGameConsole::CInstance::ExecuteLine(const char *pLine) { - if(type == 0) - console_execute_line(line); + if(m_Type == 0) + m_pGameConsole->m_pConsole->ExecuteLine(pLine); else { - if(client_rcon_authed()) - client_rcon(line); + if(m_pGameConsole->Client()->RconAuthed()) + m_pGameConsole->Client()->Rcon(pLine); else - client_rcon_auth("", line); + m_pGameConsole->Client()->RconAuth("", pLine); } } -void CONSOLE::INSTANCE::possible_commands_complete_callback(const char *str, void *user) +void CGameConsole::CInstance::PossibleCommandsCompleteCallback(const char *pStr, void *pUser) { - CONSOLE::INSTANCE *instance = (CONSOLE::INSTANCE *)user; - if(instance->completion_chosen == instance->completion_enumeration_count) - instance->input.set(str); - instance->completion_enumeration_count++; + CGameConsole::CInstance *pInstance = (CGameConsole::CInstance *)pUser; + if(pInstance->m_CompletionChosen == pInstance->m_CompletionEnumerationCount) + pInstance->m_Input.Set(pStr); + pInstance->m_CompletionEnumerationCount++; } -void CONSOLE::INSTANCE::on_input(INPUT_EVENT e) +void CGameConsole::CInstance::OnInput(IInput::CEvent Event) { - bool handled = false; + bool Handled = false; - if(e.flags&INPFLAG_PRESS) + if(Event.m_Flags&IInput::FLAG_PRESS) { - if(e.key == KEY_RETURN || e.key == KEY_KP_ENTER) + if(Event.m_Key == KEY_RETURN || Event.m_Key == KEY_KP_ENTER) { - if(input.get_string()[0]) + if(m_Input.GetString()[0]) { - char *entry = history.Allocate(input.get_length()+1); - mem_copy(entry, input.get_string(), input.get_length()+1); - - execute_line(input.get_string()); - input.clear(); - history_entry = 0x0; + char *pEntry = m_History.Allocate(m_Input.GetLength()+1); + mem_copy(pEntry, m_Input.GetString(), m_Input.GetLength()+1); + ExecuteLine(m_Input.GetString()); + m_Input.Clear(); + m_pHistoryEntry = 0x0; } - handled = true; + Handled = true; } - else if (e.key == KEY_UP) + else if (Event.m_Key == KEY_UP) { - if (history_entry) + if (m_pHistoryEntry) { - char *test = history.Prev(history_entry); + char *pTest = m_History.Prev(m_pHistoryEntry); - if (test) - history_entry = test; + if (pTest) + m_pHistoryEntry = pTest; } else - history_entry = history.Last(); + m_pHistoryEntry = m_History.Last(); - if (history_entry) + if (m_pHistoryEntry) { - unsigned int len = strlen(history_entry); - if (len < sizeof(input) - 1) - input.set(history_entry); + unsigned int Len = str_length(m_pHistoryEntry); + if (Len < sizeof(m_Input) - 1) // TODO: WTF? + m_Input.Set(m_pHistoryEntry); } - handled = true; + Handled = true; } - else if (e.key == KEY_DOWN) + else if (Event.m_Key == KEY_DOWN) { - if (history_entry) - history_entry = history.Next(history_entry); + if (m_pHistoryEntry) + m_pHistoryEntry = m_History.Next(m_pHistoryEntry); - if (history_entry) + if (m_pHistoryEntry) { - unsigned int len = strlen(history_entry); - if (len < sizeof(input) - 1) - input.set(history_entry); + unsigned int Len = str_length(m_pHistoryEntry); + if (Len < sizeof(m_Input) - 1) // TODO: WTF? + m_Input.Set(m_pHistoryEntry); } else - input.clear(); - handled = true; + m_Input.Clear(); + Handled = true; } - else if(e.key == KEY_TAB) + else if(Event.m_Key == KEY_TAB) { - completion_chosen++; - completion_enumeration_count = 0; - console_possible_commands(completion_buffer, completion_flagmask, possible_commands_complete_callback, this); - - // handle wrapping - if(completion_enumeration_count && completion_chosen >= completion_enumeration_count) + if(m_Type == 0 || m_pGameConsole->Client()->RconAuthed()) { - completion_chosen %= completion_enumeration_count; - completion_enumeration_count = 0; - console_possible_commands(completion_buffer, completion_flagmask, possible_commands_complete_callback, this); + m_CompletionChosen++; + m_CompletionEnumerationCount = 0; + m_pGameConsole->m_pConsole->PossibleCommands(m_aCompletionBuffer, m_CompletionFlagmask, PossibleCommandsCompleteCallback, this); + + // handle wrapping + if(m_CompletionEnumerationCount && m_CompletionChosen >= m_CompletionEnumerationCount) + { + m_CompletionChosen %= m_CompletionEnumerationCount; + m_CompletionEnumerationCount = 0; + m_pGameConsole->m_pConsole->PossibleCommands(m_aCompletionBuffer, m_CompletionFlagmask, PossibleCommandsCompleteCallback, this); + } } } - - if(e.key != KEY_TAB) + else if(Event.m_Key == KEY_PAGEUP) + { + ++m_BacklogActPage; + } + else if(Event.m_Key == KEY_PAGEDOWN) { - completion_chosen = -1; - str_copy(completion_buffer, input.get_string(), sizeof(completion_buffer)); + --m_BacklogActPage; + if(m_BacklogActPage < 0) + m_BacklogActPage = 0; + } + } + + if(!Handled) + m_Input.ProcessInput(Event); + + if(Event.m_Flags&IInput::FLAG_PRESS) + { + if(Event.m_Key != KEY_TAB) + { + m_CompletionChosen = -1; + str_copy(m_aCompletionBuffer, m_Input.GetString(), sizeof(m_aCompletionBuffer)); } // find the current command { - char buf[64] = {0}; - const char *src = get_string(); + char aBuf[64] = {0}; + const char *pSrc = GetString(); int i = 0; - for(; i < (int)sizeof(buf) && *src && *src != ' ' && *src != ' '; i++, src++) - buf[i] = *src; - buf[i] = 0; + for(; i < (int)sizeof(aBuf) && *pSrc && *pSrc != ' ' && *pSrc != ' '; i++, pSrc++) + aBuf[i] = *pSrc; + aBuf[i] = 0; - command = console_get_command(buf); + m_pCommand = m_pGameConsole->m_pConsole->GetCommandInfo(aBuf); } } - - if(!handled) - input.process_input(e); } -void CONSOLE::INSTANCE::print_line(const char *line) +void CGameConsole::CInstance::PrintLine(const char *pLine) { - int len = strlen(line); + int Len = str_length(pLine); - if (len > 255) - len = 255; + if (Len > 255) + Len = 255; - char *entry = backlog.Allocate(len+1); - mem_copy(entry, line, len+1); + char *pEntry = m_Backlog.Allocate(Len+1); + mem_copy(pEntry, pLine, Len); + pEntry[Len] = 0; } -CONSOLE::CONSOLE() -: local_console(0), remote_console(1) +CGameConsole::CGameConsole() +: m_LocalConsole(this, 0), m_RemoteConsole(this, 1) { - console_type = 0; - console_state = CONSOLE_CLOSED; - state_change_end = 0.0f; - state_change_duration = 0.1f; + m_ConsoleType = 0; + m_ConsoleState = CONSOLE_CLOSED; + m_StateChangeEnd = 0.0f; + m_StateChangeDuration = 0.1f; } -float CONSOLE::time_now() +float CGameConsole::TimeNow() { - static long long time_start = time_get(); - return float(time_get()-time_start)/float(time_freq()); + static long long s_TimeStart = time_get(); + return float(time_get()-s_TimeStart)/float(time_freq()); } -CONSOLE::INSTANCE *CONSOLE::current_console() +CGameConsole::CInstance *CGameConsole::CurrentConsole() { - if(console_type != 0) - return &remote_console; - return &local_console; + if(m_ConsoleType != 0) + return &m_RemoteConsole; + return &m_LocalConsole; } -void CONSOLE::on_reset() +void CGameConsole::OnReset() { } // only defined for 0<=t<=1 -static float console_scale_func(float t) +static float ConsoleScaleFunc(float t) { //return t; return sinf(acosf(1.0f-t)); } -struct RENDERINFO +struct CRenderInfo { - CONSOLE *self; - TEXT_CURSOR cursor; - const char *current_cmd; - int wanted_completion; - int enum_count; + CGameConsole *m_pSelf; + CTextCursor m_Cursor; + const char *m_pCurrentCmd; + int m_WantedCompletion; + int m_EnumCount; }; -void CONSOLE::possible_commands_render_callback(const char *str, void *user) +void CGameConsole::PossibleCommandsRenderCallback(const char *pStr, void *pUser) { - RENDERINFO *info = (RENDERINFO *)user; + CRenderInfo *pInfo = static_cast<CRenderInfo *>(pUser); - if(info->enum_count == info->wanted_completion) + if(pInfo->m_EnumCount == pInfo->m_WantedCompletion) { - float tw = gfx_text_width(info->cursor.font, info->cursor.font_size, str, -1); - info->self->Graphics()->TextureSet(-1); - info->self->Graphics()->QuadsBegin(); - info->self->Graphics()->SetColor(229.0f/255.0f,185.0f/255.0f,4.0f/255.0f,0.85f); - info->self->RenderTools()->draw_round_rect(info->cursor.x-3, info->cursor.y, tw+5, info->cursor.font_size+4, info->cursor.font_size/3); - info->self->Graphics()->QuadsEnd(); + float tw = pInfo->m_pSelf->TextRender()->TextWidth(pInfo->m_Cursor.m_pFont, pInfo->m_Cursor.m_FontSize, pStr, -1); + pInfo->m_pSelf->Graphics()->TextureSet(-1); + pInfo->m_pSelf->Graphics()->QuadsBegin(); + pInfo->m_pSelf->Graphics()->SetColor(229.0f/255.0f,185.0f/255.0f,4.0f/255.0f,0.85f); + pInfo->m_pSelf->RenderTools()->DrawRoundRect(pInfo->m_Cursor.m_X-3, pInfo->m_Cursor.m_Y, tw+5, pInfo->m_Cursor.m_FontSize+4, pInfo->m_Cursor.m_FontSize/3); + pInfo->m_pSelf->Graphics()->QuadsEnd(); - gfx_text_color(0.05f, 0.05f, 0.05f,1); - gfx_text_ex(&info->cursor, str, -1); + pInfo->m_pSelf->TextRender()->TextColor(0.05f, 0.05f, 0.05f,1); + pInfo->m_pSelf->TextRender()->TextEx(&pInfo->m_Cursor, pStr, -1); } else { - const char *match_start = str_find_nocase(str, info->current_cmd); + const char *pMatchStart = str_find_nocase(pStr, pInfo->m_pCurrentCmd); - if(match_start) + if(pMatchStart) { - gfx_text_color(0.5f,0.5f,0.5f,1); - gfx_text_ex(&info->cursor, str, match_start-str); - gfx_text_color(229.0f/255.0f,185.0f/255.0f,4.0f/255.0f,1); - gfx_text_ex(&info->cursor, match_start, strlen(info->current_cmd)); - gfx_text_color(0.5f,0.5f,0.5f,1); - gfx_text_ex(&info->cursor, match_start+strlen(info->current_cmd), -1); + pInfo->m_pSelf->TextRender()->TextColor(0.5f,0.5f,0.5f,1); + pInfo->m_pSelf->TextRender()->TextEx(&pInfo->m_Cursor, pStr, pMatchStart-pStr); + pInfo->m_pSelf->TextRender()->TextColor(229.0f/255.0f,185.0f/255.0f,4.0f/255.0f,1); + pInfo->m_pSelf->TextRender()->TextEx(&pInfo->m_Cursor, pMatchStart, str_length(pInfo->m_pCurrentCmd)); + pInfo->m_pSelf->TextRender()->TextColor(0.5f,0.5f,0.5f,1); + pInfo->m_pSelf->TextRender()->TextEx(&pInfo->m_Cursor, pMatchStart+str_length(pInfo->m_pCurrentCmd), -1); } else { - gfx_text_color(0.75f,0.75f,0.75f,1); - gfx_text_ex(&info->cursor, str, -1); + pInfo->m_pSelf->TextRender()->TextColor(0.75f,0.75f,0.75f,1); + pInfo->m_pSelf->TextRender()->TextEx(&pInfo->m_Cursor, pStr, -1); } } - info->enum_count++; - info->cursor.x += 7.0f; + pInfo->m_EnumCount++; + pInfo->m_Cursor.m_X += 7.0f; } -void CONSOLE::on_render() +void CGameConsole::OnRender() { - CUIRect screen = *UI()->Screen(); - float console_max_height = screen.h*3/5.0f; - float console_height; + CUIRect Screen = *UI()->Screen(); + float ConsoleMaxHeight = Screen.h*3/5.0f; + float ConsoleHeight; - float progress = (time_now()-(state_change_end-state_change_duration))/float(state_change_duration); + float Progress = (TimeNow()-(m_StateChangeEnd-m_StateChangeDuration))/float(m_StateChangeDuration); - if (progress >= 1.0f) + if (Progress >= 1.0f) { - if (console_state == CONSOLE_CLOSING) - console_state = CONSOLE_CLOSED; - else if (console_state == CONSOLE_OPENING) - console_state = CONSOLE_OPEN; + if (m_ConsoleState == CONSOLE_CLOSING) + m_ConsoleState = CONSOLE_CLOSED; + else if (m_ConsoleState == CONSOLE_OPENING) + m_ConsoleState = CONSOLE_OPEN; - progress = 1.0f; + Progress = 1.0f; } - if (console_state == CONSOLE_OPEN && config.cl_editor) - toggle(0); + if (m_ConsoleState == CONSOLE_OPEN && g_Config.m_ClEditor) + Toggle(0); - if (console_state == CONSOLE_CLOSED) + if (m_ConsoleState == CONSOLE_CLOSED) return; - if (console_state == CONSOLE_OPEN) - inp_mouse_mode_absolute(); + if (m_ConsoleState == CONSOLE_OPEN) + Input()->MouseModeAbsolute(); - float console_height_scale; + float ConsoleHeightScale; - if (console_state == CONSOLE_OPENING) - console_height_scale = console_scale_func(progress); - else if (console_state == CONSOLE_CLOSING) - console_height_scale = console_scale_func(1.0f-progress); + if (m_ConsoleState == CONSOLE_OPENING) + ConsoleHeightScale = ConsoleScaleFunc(Progress); + else if (m_ConsoleState == CONSOLE_CLOSING) + ConsoleHeightScale = ConsoleScaleFunc(1.0f-Progress); else //if (console_state == CONSOLE_OPEN) - console_height_scale = console_scale_func(1.0f); + ConsoleHeightScale = ConsoleScaleFunc(1.0f); - console_height = console_height_scale*console_max_height; + ConsoleHeight = ConsoleHeightScale*ConsoleMaxHeight; - Graphics()->MapScreen(screen.x, screen.y, screen.w, screen.h); + Graphics()->MapScreen(Screen.x, Screen.y, Screen.w, Screen.h); // do console shadow Graphics()->TextureSet(-1); Graphics()->QuadsBegin(); - Graphics()->SetColorVertex(0, 0,0,0, 0.5f); - Graphics()->SetColorVertex(1, 0,0,0, 0.5f); - Graphics()->SetColorVertex(2, 0,0,0, 0.0f); - Graphics()->SetColorVertex(3, 0,0,0, 0.0f); - Graphics()->QuadsDrawTL(0,console_height,screen.w,10.0f); + IGraphics::CColorVertex Array[4] = { + IGraphics::CColorVertex(0, 0,0,0, 0.5f), + IGraphics::CColorVertex(1, 0,0,0, 0.5f), + IGraphics::CColorVertex(2, 0,0,0, 0.0f), + IGraphics::CColorVertex(3, 0,0,0, 0.0f)}; + Graphics()->SetColorVertex(Array, 4); + IGraphics::CQuadItem QuadItem(0, ConsoleHeight, Screen.w, 10.0f); + Graphics()->QuadsDrawTL(&QuadItem, 1); Graphics()->QuadsEnd(); // do background - Graphics()->TextureSet(data->images[IMAGE_CONSOLE_BG].id); + Graphics()->TextureSet(g_pData->m_aImages[IMAGE_CONSOLE_BG].m_Id); Graphics()->QuadsBegin(); Graphics()->SetColor(0.2f, 0.2f, 0.2f,0.9f); - if(console_type != 0) + if(m_ConsoleType != 0) Graphics()->SetColor(0.4f, 0.2f, 0.2f,0.9f); - Graphics()->QuadsSetSubset(0,-console_height*0.075f,screen.w*0.075f*0.5f,0); - Graphics()->QuadsDrawTL(0,0,screen.w,console_height); + Graphics()->QuadsSetSubset(0,-ConsoleHeight*0.075f,Screen.w*0.075f*0.5f,0); + QuadItem = IGraphics::CQuadItem(0, 0, Screen.w, ConsoleHeight); + Graphics()->QuadsDrawTL(&QuadItem, 1); Graphics()->QuadsEnd(); // do small bar shadow Graphics()->TextureSet(-1); Graphics()->QuadsBegin(); - Graphics()->SetColorVertex(0, 0,0,0, 0.0f); - Graphics()->SetColorVertex(1, 0,0,0, 0.0f); - Graphics()->SetColorVertex(2, 0,0,0, 0.25f); - Graphics()->SetColorVertex(3, 0,0,0, 0.25f); - Graphics()->QuadsDrawTL(0,console_height-20,screen.w,10); + Array[0] = IGraphics::CColorVertex(0, 0,0,0, 0.0f); + Array[1] = IGraphics::CColorVertex(1, 0,0,0, 0.0f); + Array[2] = IGraphics::CColorVertex(2, 0,0,0, 0.25f); + Array[3] = IGraphics::CColorVertex(3, 0,0,0, 0.25f); + Graphics()->SetColorVertex(Array, 4); + QuadItem = IGraphics::CQuadItem(0, ConsoleHeight-20, Screen.w, 10); + Graphics()->QuadsDrawTL(&QuadItem, 1); Graphics()->QuadsEnd(); // do the lower bar - Graphics()->TextureSet(data->images[IMAGE_CONSOLE_BAR].id); + Graphics()->TextureSet(g_pData->m_aImages[IMAGE_CONSOLE_BAR].m_Id); Graphics()->QuadsBegin(); Graphics()->SetColor(1.0f, 1.0f, 1.0f, 0.9f); - Graphics()->QuadsSetSubset(0,0.1f,screen.w*0.015f,1-0.1f); - Graphics()->QuadsDrawTL(0,console_height-10.0f,screen.w,10.0f); + Graphics()->QuadsSetSubset(0,0.1f,Screen.w*0.015f,1-0.1f); + QuadItem = IGraphics::CQuadItem(0,ConsoleHeight-10.0f,Screen.w,10.0f); + Graphics()->QuadsDrawTL(&QuadItem, 1); Graphics()->QuadsEnd(); - console_height -= 22.0f; + ConsoleHeight -= 22.0f; - INSTANCE *console = current_console(); + CInstance *pConsole = CurrentConsole(); { - float font_size = 10.0f; - float row_height = font_size*1.25f; + float FontSize = 10.0f; + float RowHeight = FontSize*1.25f; float x = 3; - float y = console_height - row_height - 2; + float y = ConsoleHeight - RowHeight - 2; // render prompt - TEXT_CURSOR cursor; - gfx_text_set_cursor(&cursor, x, y, font_size, TEXTFLAG_RENDER); - - RENDERINFO info; - info.self = this; - info.wanted_completion = console->completion_chosen; - info.enum_count = 0; - info.current_cmd = console->completion_buffer; - gfx_text_set_cursor(&info.cursor, x, y+12.0f, font_size, TEXTFLAG_RENDER); - - const char *prompt = "> "; - if(console_type) + CTextCursor Cursor; + TextRender()->SetCursor(&Cursor, x, y, FontSize, TEXTFLAG_RENDER); + + CRenderInfo Info; + Info.m_pSelf = this; + Info.m_WantedCompletion = pConsole->m_CompletionChosen; + Info.m_EnumCount = 0; + Info.m_pCurrentCmd = pConsole->m_aCompletionBuffer; + TextRender()->SetCursor(&Info.m_Cursor, x, y+12.0f, FontSize, TEXTFLAG_RENDER); + + const char *pPrompt = "> "; + if(m_ConsoleType) { - if(client_state() == CLIENTSTATE_ONLINE) + if(Client()->State() == IClient::STATE_ONLINE) { - if(client_rcon_authed()) - prompt = "rcon> "; + if(Client()->RconAuthed()) + pPrompt = "rcon> "; else - prompt = "ENTER PASSWORD> "; + pPrompt = "ENTER PASSWORD> "; } else - prompt = "NOT CONNECTED> "; + pPrompt = "NOT CONNECTED> "; } - gfx_text_ex(&cursor, prompt, -1); - - // render console input - gfx_text_ex(&cursor, console->input.get_string(), console->input.cursor_offset()); - TEXT_CURSOR marker = cursor; - gfx_text_ex(&marker, "|", -1); - gfx_text_ex(&cursor, console->input.get_string()+console->input.cursor_offset(), -1); + TextRender()->TextEx(&Cursor, pPrompt, -1); + x = Cursor.m_X; // render version - char buf[128]; - str_format(buf, sizeof(buf), "v%s", GAME_VERSION); - float version_width = gfx_text_width(0, font_size, buf, -1); - gfx_text(0, screen.w-version_width-5, y, font_size, buf, -1); - - // render possible commands - if(console->input.get_string()[0] != 0) + char aBuf[128]; + str_format(aBuf, sizeof(aBuf), "v%s", GAME_VERSION); + float VersionWidth = TextRender()->TextWidth(0, FontSize, aBuf, -1); + TextRender()->Text(0, Screen.w-VersionWidth-5, y, FontSize, aBuf, -1); + + // render console input (wrap line) + int Lines = TextRender()->TextLineCount(0, FontSize, pConsole->m_Input.GetString(), Screen.w - (VersionWidth + 10 + x)); + y -= (Lines - 1) * FontSize; + TextRender()->SetCursor(&Cursor, x, y, FontSize, TEXTFLAG_RENDER); + Cursor.m_LineWidth = Screen.w - (VersionWidth + 10 + x); + + //hide rcon password + char aInputString[256]; + str_copy(aInputString, pConsole->m_Input.GetString(), sizeof(aInputString)); + if(m_ConsoleType && Client()->State() == IClient::STATE_ONLINE && !Client()->RconAuthed()) { - console_possible_commands(console->completion_buffer, console->completion_flagmask, possible_commands_render_callback, &info); + for(int i = 0; i < pConsole->m_Input.GetLength(); ++i) + aInputString[i] = '*'; + } - if(info.enum_count <= 0) + TextRender()->TextEx(&Cursor, aInputString, pConsole->m_Input.GetCursorOffset()); + CTextCursor Marker = Cursor; + TextRender()->TextEx(&Marker, "|", -1); + TextRender()->TextEx(&Cursor, aInputString+pConsole->m_Input.GetCursorOffset(), -1); + + // render possible commands + if(m_ConsoleType == 0 || Client()->RconAuthed()) + { + if(pConsole->m_Input.GetString()[0] != 0) { - if(console->command) + m_pConsole->PossibleCommands(pConsole->m_aCompletionBuffer, pConsole->m_CompletionFlagmask, PossibleCommandsRenderCallback, &Info); + + if(Info.m_EnumCount <= 0) { - - char buf[512]; - str_format(buf, sizeof(buf), "Help: %s ", console->command->help); - gfx_text_ex(&info.cursor, buf, -1); - gfx_text_color(0.75f, 0.75f, 0.75f, 1); - str_format(buf, sizeof(buf), "Syntax: %s %s", console->command->name, console->command->params); - gfx_text_ex(&info.cursor, buf, -1); + if(pConsole->m_pCommand) + { + + char aBuf[512]; + str_format(aBuf, sizeof(aBuf), "Help: %s ", pConsole->m_pCommand->m_pHelp); + TextRender()->TextEx(&Info.m_Cursor, aBuf, -1); + TextRender()->TextColor(0.75f, 0.75f, 0.75f, 1); + str_format(aBuf, sizeof(aBuf), "Syntax: %s %s", pConsole->m_pCommand->m_pName, pConsole->m_pCommand->m_pParams); + TextRender()->TextEx(&Info.m_Cursor, aBuf, -1); + } } } } - gfx_text_color(1,1,1,1); + TextRender()->TextColor(1,1,1,1); - // render log - y -= row_height; - char *entry = console->backlog.Last(); - while (y > 0.0f && entry) + // render log (actual page, wrap lines) + char *pEntry = pConsole->m_Backlog.Last(); + for(int Page = 0, Lines = 0; Page <= pConsole->m_BacklogActPage; ++Page, Lines = 0) { - gfx_text(0, x, y, font_size, entry, -1); - y -= row_height; + // next page when lines reach the top + while(y - Lines * RowHeight > RowHeight && pEntry) + { + Lines += TextRender()->TextLineCount(0, FontSize, pEntry, Screen.w-10); + // just render output from actual backlog page (render bottom up) + if(Page == pConsole->m_BacklogActPage) + { + TextRender()->SetCursor(&Cursor, 0, y - Lines * RowHeight, FontSize, TEXTFLAG_RENDER); + Cursor.m_LineWidth = Screen.w-10; + TextRender()->TextEx(&Cursor, pEntry, -1); + } + pEntry = pConsole->m_Backlog.Prev(pEntry); + } - entry = console->backlog.Prev(entry); + // actual backlog page number is too high, render last available page (current checked one, render top down) + if(!pEntry && Page < pConsole->m_BacklogActPage) + { + pConsole->m_BacklogActPage = Page; + pEntry = pConsole->m_Backlog.First(); + while(Lines > 0 && pEntry) + { + TextRender()->SetCursor(&Cursor, 0, y - Lines * RowHeight, FontSize, TEXTFLAG_RENDER); + Cursor.m_LineWidth = Screen.w-10; + Cursor.m_LineCount = 1; + TextRender()->TextEx(&Cursor, pEntry, -1); + Lines -= Cursor.m_LineCount; + pEntry = pConsole->m_Backlog.Next(pEntry); + } + break; + } } } } -void CONSOLE::on_message(int msgtype, void *rawmsg) +void CGameConsole::OnMessage(int MsgType, void *pRawMsg) { } -bool CONSOLE::on_input(INPUT_EVENT e) +bool CGameConsole::OnInput(IInput::CEvent Event) { - if(console_state == CONSOLE_CLOSED) + if(m_ConsoleState == CONSOLE_CLOSED) return false; - if(e.key >= KEY_F1 && e.key <= KEY_F15) + if(Event.m_Key >= KEY_F1 && Event.m_Key <= KEY_F15) return false; - if(e.key == KEY_ESCAPE && (e.flags&INPFLAG_PRESS)) - toggle(console_type); + if(Event.m_Key == KEY_ESCAPE && (Event.m_Flags&IInput::FLAG_PRESS)) + Toggle(m_ConsoleType); else - current_console()->on_input(e); + CurrentConsole()->OnInput(Event); return true; } -void CONSOLE::toggle(int type) +void CGameConsole::Toggle(int Type) { - if(console_type != type && (console_state == CONSOLE_OPEN || console_state == CONSOLE_OPENING)) + if(m_ConsoleType != Type && (m_ConsoleState == CONSOLE_OPEN || m_ConsoleState == CONSOLE_OPENING)) { // don't toggle console, just switch what console to use } else { - if (console_state == CONSOLE_CLOSED || console_state == CONSOLE_OPEN) + if (m_ConsoleState == CONSOLE_CLOSED || m_ConsoleState == CONSOLE_OPEN) { - state_change_end = time_now()+state_change_duration; + m_StateChangeEnd = TimeNow()+m_StateChangeDuration; } else { - float progress = state_change_end-time_now(); - float reversed_progress = state_change_duration-progress; + float Progress = m_StateChangeEnd-TimeNow(); + float ReversedProgress = m_StateChangeDuration-Progress; - state_change_end = time_now()+reversed_progress; + m_StateChangeEnd = TimeNow()+ReversedProgress; } - if (console_state == CONSOLE_CLOSED || console_state == CONSOLE_CLOSING) + if (m_ConsoleState == CONSOLE_CLOSED || m_ConsoleState == CONSOLE_CLOSING) { - inp_mouse_mode_absolute(); - console_state = CONSOLE_OPENING; + Input()->MouseModeAbsolute(); + m_pClient->m_pMenus->UseMouseButtons(false); + m_ConsoleState = CONSOLE_OPENING; } else { - inp_mouse_mode_relative(); - console_state = CONSOLE_CLOSING; + Input()->MouseModeRelative(); + m_pClient->m_pMenus->UseMouseButtons(true); + m_ConsoleState = CONSOLE_CLOSING; } } - console_type = type; + m_ConsoleType = Type; } -void CONSOLE::con_toggle_local_console(void *result, void *user_data) +void CGameConsole::ConToggleLocalConsole(IConsole::IResult *pResult, void *pUserData) { - ((CONSOLE *)user_data)->toggle(0); + ((CGameConsole *)pUserData)->Toggle(0); } -void CONSOLE::con_toggle_remote_console(void *result, void *user_data) +void CGameConsole::ConToggleRemoteConsole(IConsole::IResult *pResult, void *pUserData) { - ((CONSOLE *)user_data)->toggle(1); + ((CGameConsole *)pUserData)->Toggle(1); } -void CONSOLE::client_console_print_callback(const char *str, void *user_data) +void CGameConsole::ClientConsolePrintCallback(const char *pStr, void *pUserData) { - ((CONSOLE *)user_data)->local_console.print_line(str); + ((CGameConsole *)pUserData)->m_LocalConsole.PrintLine(pStr); } -void CONSOLE::print_line(int type, const char *line) +void CGameConsole::PrintLine(int Type, const char *pLine) { - if(type == 0) - local_console.print_line(line); - else if(type == 1) - remote_console.print_line(line); + if(Type == 0) + m_LocalConsole.PrintLine(pLine); + else if(Type == 1) + m_RemoteConsole.PrintLine(pLine); } -void CONSOLE::on_console_init() +void CGameConsole::OnConsoleInit() { + m_pConsole = Kernel()->RequestInterface<IConsole>(); + // - console_register_print_callback(client_console_print_callback, this); + Console()->RegisterPrintCallback(ClientConsolePrintCallback, this); - MACRO_REGISTER_COMMAND("toggle_local_console", "", CFGFLAG_CLIENT, con_toggle_local_console, this, "Toggle local console"); - MACRO_REGISTER_COMMAND("toggle_remote_console", "", CFGFLAG_CLIENT, con_toggle_remote_console, this, "Toggle remote console"); + Console()->Register("toggle_local_console", "", CFGFLAG_CLIENT, ConToggleLocalConsole, this, "Toggle local console"); + Console()->Register("toggle_remote_console", "", CFGFLAG_CLIENT, ConToggleRemoteConsole, this, "Toggle remote console"); } /* diff --git a/src/game/client/components/console.h b/src/game/client/components/console.h new file mode 100644 index 00000000..b88c6349 --- /dev/null +++ b/src/game/client/components/console.h @@ -0,0 +1,72 @@ +#ifndef GAME_CLIENT_COMPONENTS_CONSOLE_H +#define GAME_CLIENT_COMPONENTS_CONSOLE_H +#include <engine/shared/ringbuffer.h> +#include <game/client/component.h> +#include <game/client/lineinput.h> + +class CGameConsole : public CComponent +{ + class CInstance + { + public: + TStaticRingBuffer<char, 64*1024, CRingBufferBase::FLAG_RECYCLE> m_Backlog; + TStaticRingBuffer<char, 64*1024, CRingBufferBase::FLAG_RECYCLE> m_History; + char *m_pHistoryEntry; + + CLineInput m_Input; + int m_Type; + int m_CompletionEnumerationCount; + int m_BacklogActPage; + + public: + CGameConsole *m_pGameConsole; + + char m_aCompletionBuffer[128]; + int m_CompletionChosen; + int m_CompletionFlagmask; + + IConsole::CCommandInfo *m_pCommand; + + CInstance(CGameConsole *pGameConsole, int t); + + void ExecuteLine(const char *pLine); + + void OnInput(IInput::CEvent Event); + void PrintLine(const char *pLine); + + const char *GetString() const { return m_Input.GetString(); } + static void PossibleCommandsCompleteCallback(const char *pStr, void *pUser); + }; + + class IConsole *m_pConsole; + + CInstance m_LocalConsole; + CInstance m_RemoteConsole; + + CInstance *CurrentConsole(); + float TimeNow(); + + int m_ConsoleType; + int m_ConsoleState; + float m_StateChangeEnd; + float m_StateChangeDuration; + + void Toggle(int Type); + + static void PossibleCommandsRenderCallback(const char *pStr, void *pUser); + static void ClientConsolePrintCallback(const char *pStr, void *pUserData); + static void ConToggleLocalConsole(IConsole::IResult *pResult, void *pUserData); + static void ConToggleRemoteConsole(IConsole::IResult *pResult, void *pUserData); + +public: + CGameConsole(); + + void PrintLine(int Type, const char *pLine); + + virtual void OnConsoleInit(); + virtual void OnReset(); + virtual void OnRender(); + virtual void OnMessage(int MsgType, void *pRawMsg); + virtual bool OnInput(IInput::CEvent Events); +}; +#endif diff --git a/src/game/client/components/console.hpp b/src/game/client/components/console.hpp deleted file mode 100644 index 78da98b8..00000000 --- a/src/game/client/components/console.hpp +++ /dev/null @@ -1,68 +0,0 @@ -#include <engine/e_client_interface.h> -#include <engine/e_ringbuffer.h> -#include <game/client/component.hpp> -#include <game/client/lineinput.hpp> - -class CONSOLE : public COMPONENT -{ - class INSTANCE - { - public: - TStaticRingBuffer<char, 64*1024, CRingBufferBase::FLAG_RECYCLE> backlog; - TStaticRingBuffer<char, 64*1024, CRingBufferBase::FLAG_RECYCLE> history; - char *history_entry; - - LINEINPUT input; - - int type; - int completion_enumeration_count; - - public: - char completion_buffer[128]; - int completion_chosen; - int completion_flagmask; - - COMMAND *command; - - INSTANCE(int t); - - void execute_line(const char *line); - - void on_input(INPUT_EVENT e); - void print_line(const char *line); - - const char *get_string() const { return input.get_string(); } - - static void possible_commands_complete_callback(const char *str, void *user); - }; - - INSTANCE local_console; - INSTANCE remote_console; - - INSTANCE *current_console(); - float time_now(); - - int console_type; - int console_state; - float state_change_end; - float state_change_duration; - - - void toggle(int type); - - static void possible_commands_render_callback(const char *str, void *user); - static void client_console_print_callback(const char *str, void *user_data); - static void con_toggle_local_console(void *result, void *user_data); - static void con_toggle_remote_console(void *result, void *user_data); - -public: - CONSOLE(); - - void print_line(int type, const char *line); - - virtual void on_console_init(); - virtual void on_reset(); - virtual void on_render(); - virtual void on_message(int msgtype, void *rawmsg); - virtual bool on_input(INPUT_EVENT e); -}; diff --git a/src/game/client/components/controls.cpp b/src/game/client/components/controls.cpp index b48fb198..714f8b0c 100644 --- a/src/game/client/components/controls.cpp +++ b/src/game/client/components/controls.cpp @@ -1,210 +1,215 @@ -#include <engine/e_client_interface.h> -#include <base/math.hpp> -#include <game/collision.hpp> -#include <game/client/gameclient.hpp> -#include <game/client/component.hpp> -#include <game/client/components/chat.hpp> -#include <game/client/components/menus.hpp> +#include <base/math.h> -#include "controls.hpp" +#include <engine/shared/config.h> -CONTROLS::CONTROLS() +#include <game/collision.h> +#include <game/client/gameclient.h> +#include <game/client/component.h> +#include <game/client/components/chat.h> +#include <game/client/components/menus.h> + +#include "controls.h" + +CControls::CControls() { } -static void con_key_input_state(void *result, void *user_data) +static void ConKeyInputState(IConsole::IResult *pResult, void *pUserData) { - ((int *)user_data)[0] = console_arg_int(result, 0); + ((int *)pUserData)[0] = pResult->GetInteger(0); } -static void con_key_input_counter(void *result, void *user_data) +static void ConKeyInputCounter(IConsole::IResult *pResult, void *pUserData) { - int *v = (int *)user_data; - if(((*v)&1) != console_arg_int(result, 0)) + int *v = (int *)pUserData; + if(((*v)&1) != pResult->GetInteger(0)) (*v)++; *v &= INPUT_STATE_MASK; } -struct INPUTSET +struct CInputSet { - CONTROLS *controls; - int *variable; - int value; + CControls *m_pControls; + int *m_pVariable; + int m_Value; }; -static void con_key_input_set(void *result, void *user_data) +static void ConKeyInputSet(IConsole::IResult *pResult, void *pUserData) { - INPUTSET *set = (INPUTSET *)user_data; - if(console_arg_int(result, 0)) - *set->variable = set->value; + CInputSet *pSet = (CInputSet *)pUserData; + if(pResult->GetInteger(0)) + *pSet->m_pVariable = pSet->m_Value; } -static void con_key_input_nextprev_weapon(void *result, void *user_data) +static void ConKeyInputNextPrevWeapon(IConsole::IResult *pResult, void *pUserData) { - INPUTSET *set = (INPUTSET *)user_data; - con_key_input_counter(result, set->variable); - set->controls->input_data.wanted_weapon = 0; + CInputSet *pSet = (CInputSet *)pUserData; + ConKeyInputCounter(pResult, pSet->m_pVariable); + pSet->m_pControls->m_InputData.m_WantedWeapon = 0; } -void CONTROLS::on_console_init() +void CControls::OnConsoleInit() { // game commands - MACRO_REGISTER_COMMAND("+left", "", CFGFLAG_CLIENT, con_key_input_state, &input_direction_left, "Move left"); - MACRO_REGISTER_COMMAND("+right", "", CFGFLAG_CLIENT, con_key_input_state, &input_direction_right, "Move right"); - MACRO_REGISTER_COMMAND("+jump", "", CFGFLAG_CLIENT, con_key_input_state, &input_data.jump, "Jump"); - MACRO_REGISTER_COMMAND("+hook", "", CFGFLAG_CLIENT, con_key_input_state, &input_data.hook, "Hook"); - MACRO_REGISTER_COMMAND("+fire", "", CFGFLAG_CLIENT, con_key_input_counter, &input_data.fire, "Fire"); - - { static INPUTSET set = {this, &input_data.wanted_weapon, 1}; MACRO_REGISTER_COMMAND("+weapon1", "", CFGFLAG_CLIENT, con_key_input_set, (void *)&set, "Switch to hammer"); } - { static INPUTSET set = {this, &input_data.wanted_weapon, 2}; MACRO_REGISTER_COMMAND("+weapon2", "", CFGFLAG_CLIENT, con_key_input_set, (void *)&set, "Switch to gun"); } - { static INPUTSET set = {this, &input_data.wanted_weapon, 3}; MACRO_REGISTER_COMMAND("+weapon3", "", CFGFLAG_CLIENT, con_key_input_set, (void *)&set, "Switch to shotgun"); } - { static INPUTSET set = {this, &input_data.wanted_weapon, 4}; MACRO_REGISTER_COMMAND("+weapon4", "", CFGFLAG_CLIENT, con_key_input_set, (void *)&set, "Switch to grenade"); } - { static INPUTSET set = {this, &input_data.wanted_weapon, 5}; MACRO_REGISTER_COMMAND("+weapon5", "", CFGFLAG_CLIENT, con_key_input_set, (void *)&set, "Switch to rifle"); } - - { static INPUTSET set = {this, &input_data.next_weapon, 0}; MACRO_REGISTER_COMMAND("+nextweapon", "", CFGFLAG_CLIENT, con_key_input_nextprev_weapon, (void *)&set, "Switch to next weapon"); } - { static INPUTSET set = {this, &input_data.prev_weapon, 0}; MACRO_REGISTER_COMMAND("+prevweapon", "", CFGFLAG_CLIENT, con_key_input_nextprev_weapon, (void *)&set, "Switch to previous weapon"); } + Console()->Register("+left", "", CFGFLAG_CLIENT, ConKeyInputState, &m_InputDirectionLeft, "Move left"); + Console()->Register("+right", "", CFGFLAG_CLIENT, ConKeyInputState, &m_InputDirectionRight, "Move right"); + Console()->Register("+jump", "", CFGFLAG_CLIENT, ConKeyInputState, &m_InputData.m_Jump, "Jump"); + Console()->Register("+hook", "", CFGFLAG_CLIENT, ConKeyInputState, &m_InputData.m_Hook, "Hook"); + Console()->Register("+fire", "", CFGFLAG_CLIENT, ConKeyInputCounter, &m_InputData.m_Fire, "Fire"); + + { static CInputSet s_Set = {this, &m_InputData.m_WantedWeapon, 1}; Console()->Register("+weapon1", "", CFGFLAG_CLIENT, ConKeyInputSet, (void *)&s_Set, "Switch to hammer"); } + { static CInputSet s_Set = {this, &m_InputData.m_WantedWeapon, 2}; Console()->Register("+weapon2", "", CFGFLAG_CLIENT, ConKeyInputSet, (void *)&s_Set, "Switch to gun"); } + { static CInputSet s_Set = {this, &m_InputData.m_WantedWeapon, 3}; Console()->Register("+weapon3", "", CFGFLAG_CLIENT, ConKeyInputSet, (void *)&s_Set, "Switch to shotgun"); } + { static CInputSet s_Set = {this, &m_InputData.m_WantedWeapon, 4}; Console()->Register("+weapon4", "", CFGFLAG_CLIENT, ConKeyInputSet, (void *)&s_Set, "Switch to grenade"); } + { static CInputSet s_Set = {this, &m_InputData.m_WantedWeapon, 5}; Console()->Register("+weapon5", "", CFGFLAG_CLIENT, ConKeyInputSet, (void *)&s_Set, "Switch to rifle"); } + + { static CInputSet s_Set = {this, &m_InputData.m_NextWeapon, 0}; Console()->Register("+nextweapon", "", CFGFLAG_CLIENT, ConKeyInputNextPrevWeapon, (void *)&s_Set, "Switch to next weapon"); } + { static CInputSet s_Set = {this, &m_InputData.m_PrevWeapon, 0}; Console()->Register("+prevweapon", "", CFGFLAG_CLIENT, ConKeyInputNextPrevWeapon, (void *)&s_Set, "Switch to previous weapon"); } } -void CONTROLS::on_message(int msg, void *rawmsg) +void CControls::OnMessage(int Msg, void *pRawMsg) { - if(msg == NETMSGTYPE_SV_WEAPONPICKUP) + if(Msg == NETMSGTYPE_SV_WEAPONPICKUP) { - NETMSG_SV_WEAPONPICKUP *msg = (NETMSG_SV_WEAPONPICKUP *)rawmsg; - if(config.cl_autoswitch_weapons) - input_data.wanted_weapon = msg->weapon+1; + CNetMsg_Sv_WeaponPickup *pMsg = (CNetMsg_Sv_WeaponPickup *)pRawMsg; + if(g_Config.m_ClAutoswitchWeapons) + m_InputData.m_WantedWeapon = pMsg->m_Weapon+1; } } -int CONTROLS::snapinput(int *data) +int CControls::SnapInput(int *pData) { - static NETOBJ_PLAYER_INPUT last_data = {0}; - static int64 last_send_time = 0; - bool send = false; + static CNetObj_PlayerInput LastData = {0}; + static int64 LastSendTime = 0; + bool Send = false; // update player state - if(gameclient.chat->is_active()) - input_data.player_state = PLAYERSTATE_CHATTING; - else if(gameclient.menus->is_active()) - input_data.player_state = PLAYERSTATE_IN_MENU; + if(m_pClient->m_pChat->IsActive()) + m_InputData.m_PlayerState = PLAYERSTATE_CHATTING; + else if(m_pClient->m_pMenus->IsActive()) + m_InputData.m_PlayerState = PLAYERSTATE_IN_MENU; else - input_data.player_state = PLAYERSTATE_PLAYING; + m_InputData.m_PlayerState = PLAYERSTATE_PLAYING; - if(last_data.player_state != input_data.player_state) - send = true; + if(LastData.m_PlayerState != m_InputData.m_PlayerState) + Send = true; - last_data.player_state = input_data.player_state; + LastData.m_PlayerState = m_InputData.m_PlayerState; // we freeze the input if chat or menu is activated - if(input_data.player_state != PLAYERSTATE_PLAYING) + if(m_InputData.m_PlayerState != PLAYERSTATE_PLAYING) { - last_data.direction = 0; - last_data.hook = 0; - last_data.jump = 0; - input_data = last_data; + LastData.m_Direction = 0; + LastData.m_Hook = 0; + LastData.m_Jump = 0; + m_InputData = LastData; - input_direction_left = 0; - input_direction_right = 0; + m_InputDirectionLeft = 0; + m_InputDirectionRight = 0; - mem_copy(data, &input_data, sizeof(input_data)); + mem_copy(pData, &m_InputData, sizeof(m_InputData)); // send once a second just to be sure - if(time_get() > last_send_time + time_freq()) - send = true; + if(time_get() > LastSendTime + time_freq()) + Send = true; } else { - input_data.target_x = (int)mouse_pos.x; - input_data.target_y = (int)mouse_pos.y; - if(!input_data.target_x && !input_data.target_y) - input_data.target_y = 1; + m_InputData.m_TargetX = (int)m_MousePos.x; + m_InputData.m_TargetY = (int)m_MousePos.y; + if(!m_InputData.m_TargetX && !m_InputData.m_TargetY) + { + m_InputData.m_TargetX = 1; + m_MousePos.x = 1; + } // set direction - input_data.direction = 0; - if(input_direction_left && !input_direction_right) - input_data.direction = -1; - if(!input_direction_left && input_direction_right) - input_data.direction = 1; + m_InputData.m_Direction = 0; + if(m_InputDirectionLeft && !m_InputDirectionRight) + m_InputData.m_Direction = -1; + if(!m_InputDirectionLeft && m_InputDirectionRight) + m_InputData.m_Direction = 1; // stress testing - if(config.dbg_stress) + if(g_Config.m_DbgStress) { - float t = client_localtime(); - mem_zero(&input_data, sizeof(input_data)); - - input_data.direction = ((int)t/2)&1; - input_data.jump = ((int)t); - input_data.fire = ((int)(t*10)); - input_data.hook = ((int)(t*2))&1; - input_data.wanted_weapon = ((int)t)%NUM_WEAPONS; - input_data.target_x = (int)(sinf(t*3)*100.0f); - input_data.target_y = (int)(cosf(t*3)*100.0f); + float t = Client()->LocalTime(); + mem_zero(&m_InputData, sizeof(m_InputData)); + + m_InputData.m_Direction = ((int)t/2)&1; + m_InputData.m_Jump = ((int)t); + m_InputData.m_Fire = ((int)(t*10)); + m_InputData.m_Hook = ((int)(t*2))&1; + m_InputData.m_WantedWeapon = ((int)t)%NUM_WEAPONS; + m_InputData.m_TargetX = (int)(sinf(t*3)*100.0f); + m_InputData.m_TargetY = (int)(cosf(t*3)*100.0f); } // check if we need to send input - if(input_data.direction != last_data.direction) send = true; - else if(input_data.jump != last_data.jump) send = true; - else if(input_data.fire != last_data.fire) send = true; - else if(input_data.hook != last_data.hook) send = true; - else if(input_data.player_state != last_data.player_state) send = true; - else if(input_data.wanted_weapon != last_data.wanted_weapon) send = true; - else if(input_data.next_weapon != last_data.next_weapon) send = true; - else if(input_data.prev_weapon != last_data.prev_weapon) send = true; + if(m_InputData.m_Direction != LastData.m_Direction) Send = true; + else if(m_InputData.m_Jump != LastData.m_Jump) Send = true; + else if(m_InputData.m_Fire != LastData.m_Fire) Send = true; + else if(m_InputData.m_Hook != LastData.m_Hook) Send = true; + else if(m_InputData.m_PlayerState != LastData.m_PlayerState) Send = true; + else if(m_InputData.m_WantedWeapon != LastData.m_WantedWeapon) Send = true; + else if(m_InputData.m_NextWeapon != LastData.m_NextWeapon) Send = true; + else if(m_InputData.m_PrevWeapon != LastData.m_PrevWeapon) Send = true; // send at at least 10hz - if(time_get() > last_send_time + time_freq()/25) - send = true; + if(time_get() > LastSendTime + time_freq()/25) + Send = true; } // copy and return size - last_data = input_data; + LastData = m_InputData; - if(!send) + if(!Send) return 0; - last_send_time = time_get(); - mem_copy(data, &input_data, sizeof(input_data)); - return sizeof(input_data); + LastSendTime = time_get(); + mem_copy(pData, &m_InputData, sizeof(m_InputData)); + return sizeof(m_InputData); } -void CONTROLS::on_render() +void CControls::OnRender() { // update target pos - if(gameclient.snap.gameobj && !(gameclient.snap.gameobj->paused || gameclient.snap.spectate)) - target_pos = gameclient.local_character_pos + mouse_pos; + if(m_pClient->m_Snap.m_pGameobj && !(m_pClient->m_Snap.m_pGameobj->m_Paused || m_pClient->m_Snap.m_Spectate)) + m_TargetPos = m_pClient->m_LocalCharacterPos + m_MousePos; } -bool CONTROLS::on_mousemove(float x, float y) +bool CControls::OnMouseMove(float x, float y) { - if(gameclient.snap.gameobj && gameclient.snap.gameobj->paused) + if(m_pClient->m_Snap.m_pGameobj && m_pClient->m_Snap.m_pGameobj->m_Paused) return false; - mouse_pos += vec2(x, y); // TODO: ugly + m_MousePos += vec2(x, y); // TODO: ugly // - float camera_max_distance = 200.0f; - float follow_factor = config.cl_mouse_followfactor/100.0f; - float deadzone = config.cl_mouse_deadzone; - float mouse_max = min(camera_max_distance/follow_factor + deadzone, (float)config.cl_mouse_max_distance); + float CameraMaxDistance = 200.0f; + float FollowFactor = g_Config.m_ClMouseFollowfactor/100.0f; + float DeadZone = g_Config.m_ClMouseDeadzone; + float MouseMax = min(CameraMaxDistance/FollowFactor + DeadZone, (float)g_Config.m_ClMouseMaxDistance); //vec2 camera_offset(0, 0); - if(gameclient.snap.spectate) + if(m_pClient->m_Snap.m_Spectate) { - if(mouse_pos.x < 200.0f) mouse_pos.x = 200.0f; - if(mouse_pos.y < 200.0f) mouse_pos.y = 200.0f; - if(mouse_pos.x > col_width()*32-200.0f) mouse_pos.x = col_width()*32-200.0f; - if(mouse_pos.y > col_height()*32-200.0f) mouse_pos.y = col_height()*32-200.0f; + if(m_MousePos.x < 200.0f) m_MousePos.x = 200.0f; + if(m_MousePos.y < 200.0f) m_MousePos.y = 200.0f; + if(m_MousePos.x > Collision()->GetWidth()*32-200.0f) m_MousePos.x = Collision()->GetWidth()*32-200.0f; + if(m_MousePos.y > Collision()->GetHeight()*32-200.0f) m_MousePos.y = Collision()->GetHeight()*32-200.0f; - target_pos = mouse_pos; + m_TargetPos = m_MousePos; } else { - float l = length(mouse_pos); + float l = length(m_MousePos); - if(l > mouse_max) + if(l > MouseMax) { - mouse_pos = normalize(mouse_pos)*mouse_max; - l = mouse_max; + m_MousePos = normalize(m_MousePos)*MouseMax; + l = MouseMax; } //float offset_amount = max(l-deadzone, 0.0f) * follow_factor; diff --git a/src/game/client/components/controls.h b/src/game/client/components/controls.h new file mode 100644 index 00000000..7453d5d7 --- /dev/null +++ b/src/game/client/components/controls.h @@ -0,0 +1,25 @@ +#ifndef GAME_CLIENT_COMPONENTS_CONTROLS_H +#define GAME_CLIENT_COMPONENTS_CONTROLS_H +#include <base/vmath.h> +#include <game/client/component.h> + +class CControls : public CComponent +{ +public: + vec2 m_MousePos; + vec2 m_TargetPos; + + CNetObj_PlayerInput m_InputData; + int m_InputDirectionLeft; + int m_InputDirectionRight; + + CControls(); + + virtual void OnRender(); + virtual void OnMessage(int MsgType, void *pRawMsg); + virtual bool OnMouseMove(float x, float y); + virtual void OnConsoleInit(); + + int SnapInput(int *pData); +}; +#endif diff --git a/src/game/client/components/controls.hpp b/src/game/client/components/controls.hpp deleted file mode 100644 index e33d24f5..00000000 --- a/src/game/client/components/controls.hpp +++ /dev/null @@ -1,22 +0,0 @@ -#include <base/vmath.hpp> -#include <game/client/component.hpp> - -class CONTROLS : public COMPONENT -{ -public: - vec2 mouse_pos; - vec2 target_pos; - - NETOBJ_PLAYER_INPUT input_data; - int input_direction_left; - int input_direction_right; - - CONTROLS(); - - virtual void on_render(); - virtual void on_message(int msg, void *rawmsg); - virtual bool on_mousemove(float x, float y); - virtual void on_console_init(); - - int snapinput(int *data); -}; diff --git a/src/game/client/components/damageind.cpp b/src/game/client/components/damageind.cpp index 7f1991dc..8dfbf022 100644 --- a/src/game/client/components/damageind.cpp +++ b/src/game/client/components/damageind.cpp @@ -1,65 +1,64 @@ -#include <engine/e_client_interface.h> -#include <engine/client/graphics.h> -#include <game/generated/g_protocol.hpp> -#include <game/generated/gc_data.hpp> +#include <engine/graphics.h> +#include <game/generated/protocol.h> +#include <game/generated/client_data.h> -#include <game/gamecore.hpp> // get_angle -#include <game/client/ui.hpp> -#include <game/client/render.hpp> -#include "damageind.hpp" +#include <game/gamecore.h> // get_angle +#include <game/client/ui.h> +#include <game/client/render.h> +#include "damageind.h" -DAMAGEIND::DAMAGEIND() +CDamageInd::CDamageInd() { - lastupdate = 0; - num_items = 0; + m_Lastupdate = 0; + m_NumItems = 0; } -DAMAGEIND::ITEM *DAMAGEIND::create_i() +CDamageInd::CItem *CDamageInd::CreateI() { - if (num_items < MAX_ITEMS) + if (m_NumItems < MAX_ITEMS) { - ITEM *p = &items[num_items]; - num_items++; + CItem *p = &m_aItems[m_NumItems]; + m_NumItems++; return p; } return 0; } -void DAMAGEIND::destroy_i(DAMAGEIND::ITEM *i) +void CDamageInd::DestroyI(CDamageInd::CItem *i) { - num_items--; - *i = items[num_items]; + m_NumItems--; + *i = m_aItems[m_NumItems]; } -void DAMAGEIND::create(vec2 pos, vec2 dir) +void CDamageInd::Create(vec2 Pos, vec2 Dir) { - ITEM *i = create_i(); + CItem *i = CreateI(); if (i) { - i->pos = pos; - i->life = 0.75f; - i->dir = dir*-1; - i->startangle = (( (float)rand()/(float)RAND_MAX) - 1.0f) * 2.0f * pi; + i->m_Pos = Pos; + i->m_Life = 0.75f; + i->m_Dir = Dir*-1; + i->m_StartAngle = (( (float)rand()/(float)RAND_MAX) - 1.0f) * 2.0f * pi; } } -void DAMAGEIND::on_render() +void CDamageInd::OnRender() { - Graphics()->TextureSet(data->images[IMAGE_GAME].id); + Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id); Graphics()->QuadsBegin(); - for(int i = 0; i < num_items;) + for(int i = 0; i < m_NumItems;) { - vec2 pos = mix(items[i].pos+items[i].dir*75.0f, items[i].pos, clamp((items[i].life-0.60f)/0.15f, 0.0f, 1.0f)); + vec2 Pos = mix(m_aItems[i].m_Pos+m_aItems[i].m_Dir*75.0f, m_aItems[i].m_Pos, clamp((m_aItems[i].m_Life-0.60f)/0.15f, 0.0f, 1.0f)); - items[i].life -= client_frametime(); - if(items[i].life < 0.0f) - destroy_i(&items[i]); + m_aItems[i].m_Life -= Client()->FrameTime(); + if(m_aItems[i].m_Life < 0.0f) + DestroyI(&m_aItems[i]); else { - Graphics()->SetColor(1.0f,1.0f,1.0f, items[i].life/0.1f); - Graphics()->QuadsSetRotation(items[i].startangle + items[i].life * 2.0f); - RenderTools()->select_sprite(SPRITE_STAR1); - RenderTools()->draw_sprite(pos.x, pos.y, 48.0f); + Graphics()->SetColor(1.0f,1.0f,1.0f, m_aItems[i].m_Life/0.1f); + Graphics()->QuadsSetRotation(m_aItems[i].m_StartAngle + m_aItems[i].m_Life * 2.0f); + RenderTools()->SelectSprite(SPRITE_STAR1); + RenderTools()->DrawSprite(Pos.x, Pos.y, 48.0f); i++; } } diff --git a/src/game/client/components/damageind.h b/src/game/client/components/damageind.h new file mode 100644 index 00000000..b6e0bb47 --- /dev/null +++ b/src/game/client/components/damageind.h @@ -0,0 +1,34 @@ +#ifndef GAME_CLIENT_COMPONENTS_DAMAGEIND_H +#define GAME_CLIENT_COMPONENTS_DAMAGEIND_H +#include <base/vmath.h> +#include <game/client/component.h> + +class CDamageInd : public CComponent +{ + int64 m_Lastupdate; + struct CItem + { + vec2 m_Pos; + vec2 m_Dir; + float m_Life; + float m_StartAngle; + }; + + enum + { + MAX_ITEMS=64, + }; + + CItem m_aItems[MAX_ITEMS]; + int m_NumItems; + + CItem *CreateI(); + void DestroyI(CItem *i); + +public: + CDamageInd(); + + void Create(vec2 Pos, vec2 Dir); + virtual void OnRender(); +}; +#endif diff --git a/src/game/client/components/damageind.hpp b/src/game/client/components/damageind.hpp deleted file mode 100644 index c74af9ca..00000000 --- a/src/game/client/components/damageind.hpp +++ /dev/null @@ -1,31 +0,0 @@ -#include <base/vmath.hpp> -#include <game/client/component.hpp> - -class DAMAGEIND : public COMPONENT -{ - int64 lastupdate; - struct ITEM - { - vec2 pos; - vec2 dir; - float life; - float startangle; - }; - - enum - { - MAX_ITEMS=64, - }; - - ITEM items[MAX_ITEMS]; - int num_items; - - ITEM *create_i(); - void destroy_i(ITEM *i); - -public: - DAMAGEIND(); - - void create(vec2 pos, vec2 dir); - virtual void on_render(); -}; diff --git a/src/game/client/components/debughud.cpp b/src/game/client/components/debughud.cpp index c7cc559b..0fa004cb 100644 --- a/src/game/client/components/debughud.cpp +++ b/src/game/client/components/debughud.cpp @@ -1,27 +1,23 @@ -#include <memory.h> // memcmp +#include <engine/shared/config.h> +#include <engine/graphics.h> +#include <engine/textrender.h> -extern "C" { - #include <engine/e_config.h> -} - -#include <engine/e_client_interface.h> -#include <engine/client/graphics.h> -#include <game/generated/g_protocol.hpp> -#include <game/generated/gc_data.hpp> +#include <game/generated/protocol.h> +#include <game/generated/client_data.h> -#include <game/layers.hpp> +#include <game/layers.h> -#include <game/client/gameclient.hpp> -#include <game/client/animstate.hpp> -#include <game/client/render.hpp> +#include <game/client/gameclient.h> +#include <game/client/animstate.h> +#include <game/client/render.h> -//#include "controls.hpp" -//#include "camera.hpp" -#include "debughud.hpp" +//#include "controls.h" +//#include "camera.h" +#include "debughud.h" -void DEBUGHUD::render_netcorrections() +void CDebugHud::RenderNetCorrections() { - if(!config.debug || !gameclient.snap.local_character || !gameclient.snap.local_prev_character) + if(!g_Config.m_Debug || !m_pClient->m_Snap.m_pLocalCharacter || !m_pClient->m_Snap.m_pLocalPrevCharacter) return; Graphics()->MapScreen(0, 0, 300*Graphics()->ScreenAspect(), 300); @@ -29,7 +25,8 @@ void DEBUGHUD::render_netcorrections() /*float speed = distance(vec2(netobjects.local_prev_character->x, netobjects.local_prev_character->y), vec2(netobjects.local_character->x, netobjects.local_character->y));*/ - float velspeed = length(vec2(gameclient.snap.local_character->vx/256.0f, gameclient.snap.local_character->vy/256.0f))*50; +/* + float velspeed = length(vec2(gameclient.snap.local_character->m_VelX/256.0f, gameclient.snap.local_character->m_VelY/256.0f))*50; float ramp = velocity_ramp(velspeed, gameclient.tuning.velramp_start, gameclient.tuning.velramp_range, gameclient.tuning.velramp_curvature); @@ -37,77 +34,79 @@ void DEBUGHUD::render_netcorrections() str_format(buf, sizeof(buf), "%.0f\n%.0f\n%.2f\n%d %s\n%d %d", velspeed, velspeed*ramp, ramp, netobj_num_corrections(), netobj_corrected_on(), - gameclient.snap.local_character->x, - gameclient.snap.local_character->y + gameclient.snap.local_character->m_X, + gameclient.snap.local_character->m_Y ); - gfx_text(0, 150, 50, 12, buf, -1); + TextRender()->Text(0, 150, 50, 12, buf, -1);*/ } -void DEBUGHUD::render_tuning() +void CDebugHud::RenderTuning() { // render tuning debugging - if(!config.dbg_tuning) + if(!g_Config.m_DbgTuning) return; - TUNING_PARAMS standard_tuning; + CTuningParams StandardTuning; Graphics()->MapScreen(0, 0, 300*Graphics()->ScreenAspect(), 300); float y = 50.0f; - int count = 0; - for(int i = 0; i < gameclient.tuning.num(); i++) + int Count = 0; + for(int i = 0; i < m_pClient->m_Tuning.Num(); i++) { - char buf[128]; - float current, standard; - gameclient.tuning.get(i, ¤t); - standard_tuning.get(i, &standard); + char aBuf[128]; + float Current, Standard; + m_pClient->m_Tuning.Get(i, &Current); + StandardTuning.Get(i, &Standard); - if(standard == current) - gfx_text_color(1,1,1,1.0f); + if(Standard == Current) + TextRender()->TextColor(1,1,1,1.0f); else - gfx_text_color(1,0.25f,0.25f,1.0f); + TextRender()->TextColor(1,0.25f,0.25f,1.0f); float w; float x = 5.0f; - str_format(buf, sizeof(buf), "%.2f", standard); + str_format(aBuf, sizeof(aBuf), "%.2f", Standard); x += 20.0f; - w = gfx_text_width(0, 5, buf, -1); - gfx_text(0x0, x-w, y+count*6, 5, buf, -1); + w = TextRender()->TextWidth(0, 5, aBuf, -1); + TextRender()->Text(0x0, x-w, y+Count*6, 5, aBuf, -1); - str_format(buf, sizeof(buf), "%.2f", current); + str_format(aBuf, sizeof(aBuf), "%.2f", Current); x += 20.0f; - w = gfx_text_width(0, 5, buf, -1); - gfx_text(0x0, x-w, y+count*6, 5, buf, -1); + w = TextRender()->TextWidth(0, 5, aBuf, -1); + TextRender()->Text(0x0, x-w, y+Count*6, 5, aBuf, -1); x += 5.0f; - gfx_text(0x0, x, y+count*6, 5, gameclient.tuning.names[i], -1); + TextRender()->Text(0x0, x, y+Count*6, 5, m_pClient->m_Tuning.m_apNames[i], -1); - count++; + Count++; } - y = y+count*6; + y = y+Count*6; Graphics()->TextureSet(-1); Graphics()->BlendNormal(); Graphics()->LinesBegin(); - float height = 50.0f; + float Height = 50.0f; float pv = 1; + IGraphics::CLineItem Array[100]; for(int i = 0; i < 100; i++) { - float speed = i/100.0f * 3000; - float ramp = velocity_ramp(speed, gameclient.tuning.velramp_start, gameclient.tuning.velramp_range, gameclient.tuning.velramp_curvature); - float rampedspeed = (speed * ramp)/1000.0f; - Graphics()->LinesDraw((i-1)*2, y+height-pv*height, i*2, y+height-rampedspeed*height); + float Speed = i/100.0f * 3000; + float Ramp = VelocityRamp(Speed, m_pClient->m_Tuning.m_VelrampStart, m_pClient->m_Tuning.m_VelrampRange, m_pClient->m_Tuning.m_VelrampCurvature); + float RampedSpeed = (Speed * Ramp)/1000.0f; + Array[i] = IGraphics::CLineItem((i-1)*2, y+Height-pv*Height, i*2, y+Height-RampedSpeed*Height); //Graphics()->LinesDraw((i-1)*2, 200, i*2, 200); - pv = rampedspeed; + pv = RampedSpeed; } + Graphics()->LinesDraw(Array, 100); Graphics()->LinesEnd(); - gfx_text_color(1,1,1,1); + TextRender()->TextColor(1,1,1,1); } -void DEBUGHUD::on_render() +void CDebugHud::OnRender() { - render_tuning(); - render_netcorrections(); + RenderTuning(); + RenderNetCorrections(); } diff --git a/src/game/client/components/debughud.h b/src/game/client/components/debughud.h new file mode 100644 index 00000000..ae1c17ef --- /dev/null +++ b/src/game/client/components/debughud.h @@ -0,0 +1,13 @@ +#ifndef GAME_CLIENT_COMPONENTS_DEBUGHUD_H +#define GAME_CLIENT_COMPONENTS_DEBUGHUD_H +#include <game/client/component.h> + +class CDebugHud : public CComponent +{ + void RenderNetCorrections(); + void RenderTuning(); +public: + virtual void OnRender(); +}; + +#endif diff --git a/src/game/client/components/debughud.hpp b/src/game/client/components/debughud.hpp deleted file mode 100644 index 473b2ce2..00000000 --- a/src/game/client/components/debughud.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#include <game/client/component.hpp> - -class DEBUGHUD : public COMPONENT -{ - void render_netcorrections(); - void render_tuning(); -public: - virtual void on_render(); -}; - diff --git a/src/game/client/components/effects.cpp b/src/game/client/components/effects.cpp index c9c47a8d..91cea107 100644 --- a/src/game/client/components/effects.cpp +++ b/src/game/client/components/effects.cpp @@ -1,183 +1,181 @@ -#include <engine/e_client_interface.h> -//#include <gc_client.hpp> -#include <game/generated/gc_data.hpp> +#include <game/generated/client_data.h> -#include <game/client/components/particles.hpp> -#include <game/client/components/skins.hpp> -#include <game/client/components/flow.hpp> -#include <game/client/components/damageind.hpp> -#include <game/client/components/sounds.hpp> -#include <game/client/gameclient.hpp> +#include <game/client/components/particles.h> +#include <game/client/components/skins.h> +#include <game/client/components/flow.h> +#include <game/client/components/damageind.h> +#include <game/client/components/sounds.h> +#include <game/client/gameclient.h> -#include "effects.hpp" +#include "effects.h" -inline vec2 random_dir() { return normalize(vec2(frandom()-0.5f, frandom()-0.5f)); } +inline vec2 RandomDir() { return normalize(vec2(frandom()-0.5f, frandom()-0.5f)); } -EFFECTS::EFFECTS() +CEffects::CEffects() { - add_50hz = false; - add_100hz = false; + m_Add50hz = false; + m_Add100hz = false; } -void EFFECTS::air_jump(vec2 pos) +void CEffects::AirJump(vec2 Pos) { - PARTICLE p; - p.set_default(); - p.spr = SPRITE_PART_AIRJUMP; - p.pos = pos + vec2(-6.0f, 16.0f); - p.vel = vec2(0, -200); - p.life_span = 0.5f; - p.start_size = 48.0f; - p.end_size = 0; - p.rot = frandom()*pi*2; - p.rotspeed = pi*2; - p.gravity = 500; - p.friction = 0.7f; - p.flow_affected = 0.0f; - gameclient.particles->add(PARTICLES::GROUP_GENERAL, &p); + CParticle p; + p.SetDefault(); + p.m_Spr = SPRITE_PART_AIRJUMP; + p.m_Pos = Pos + vec2(-6.0f, 16.0f); + p.m_Vel = vec2(0, -200); + p.m_LifeSpan = 0.5f; + p.m_StartSize = 48.0f; + p.m_EndSize = 0; + p.m_Rot = frandom()*pi*2; + p.m_Rotspeed = pi*2; + p.m_Gravity = 500; + p.m_Friction = 0.7f; + p.m_FlowAffected = 0.0f; + m_pClient->m_pParticles->Add(CParticles::GROUP_GENERAL, &p); - p.pos = pos + vec2(6.0f, 16.0f); - gameclient.particles->add(PARTICLES::GROUP_GENERAL, &p); + p.m_Pos = Pos + vec2(6.0f, 16.0f); + m_pClient->m_pParticles->Add(CParticles::GROUP_GENERAL, &p); - gameclient.sounds->play(SOUNDS::CHN_WORLD, SOUND_PLAYER_AIRJUMP, 1.0f, pos); + m_pClient->m_pSounds->Play(CSounds::CHN_WORLD, SOUND_PLAYER_AIRJUMP, 1.0f, Pos); } -void EFFECTS::damage_indicator(vec2 pos, vec2 dir) +void CEffects::DamageIndicator(vec2 Pos, vec2 Dir) { - gameclient.damageind->create(pos, dir); + m_pClient->m_pDamageind->Create(Pos, Dir); } -void EFFECTS::powerupshine(vec2 pos, vec2 size) +void CEffects::PowerupShine(vec2 Pos, vec2 size) { - if(!add_50hz) + if(!m_Add50hz) return; - PARTICLE p; - p.set_default(); - p.spr = SPRITE_PART_SLICE; - p.pos = pos + vec2((frandom()-0.5f)*size.x, (frandom()-0.5f)*size.y); - p.vel = vec2(0, 0); - p.life_span = 0.5f; - p.start_size = 16.0f; - p.end_size = 0; - p.rot = frandom()*pi*2; - p.rotspeed = pi*2; - p.gravity = 500; - p.friction = 0.9f; - p.flow_affected = 0.0f; - gameclient.particles->add(PARTICLES::GROUP_GENERAL, &p); + CParticle p; + p.SetDefault(); + p.m_Spr = SPRITE_PART_SLICE; + p.m_Pos = Pos + vec2((frandom()-0.5f)*size.x, (frandom()-0.5f)*size.y); + p.m_Vel = vec2(0, 0); + p.m_LifeSpan = 0.5f; + p.m_StartSize = 16.0f; + p.m_EndSize = 0; + p.m_Rot = frandom()*pi*2; + p.m_Rotspeed = pi*2; + p.m_Gravity = 500; + p.m_Friction = 0.9f; + p.m_FlowAffected = 0.0f; + m_pClient->m_pParticles->Add(CParticles::GROUP_GENERAL, &p); } -void EFFECTS::smoketrail(vec2 pos, vec2 vel) +void CEffects::SmokeTrail(vec2 Pos, vec2 Vel) { - if(!add_50hz) + if(!m_Add50hz) return; - PARTICLE p; - p.set_default(); - p.spr = SPRITE_PART_SMOKE; - p.pos = pos; - p.vel = vel + random_dir()*50.0f; - p.life_span = 0.5f + frandom()*0.5f; - p.start_size = 12.0f + frandom()*8; - p.end_size = 0; - p.friction = 0.7; - p.gravity = frandom()*-500.0f; - gameclient.particles->add(PARTICLES::GROUP_PROJECTILE_TRAIL, &p); + CParticle p; + p.SetDefault(); + p.m_Spr = SPRITE_PART_SMOKE; + p.m_Pos = Pos; + p.m_Vel = Vel + RandomDir()*50.0f; + p.m_LifeSpan = 0.5f + frandom()*0.5f; + p.m_StartSize = 12.0f + frandom()*8; + p.m_EndSize = 0; + p.m_Friction = 0.7; + p.m_Gravity = frandom()*-500.0f; + m_pClient->m_pParticles->Add(CParticles::GROUP_PROJECTILE_TRAIL, &p); } -void EFFECTS::skidtrail(vec2 pos, vec2 vel) +void CEffects::SkidTrail(vec2 Pos, vec2 Vel) { - if(!add_100hz) + if(!m_Add100hz) return; - PARTICLE p; - p.set_default(); - p.spr = SPRITE_PART_SMOKE; - p.pos = pos; - p.vel = vel + random_dir()*50.0f; - p.life_span = 0.5f + frandom()*0.5f; - p.start_size = 24.0f + frandom()*12; - p.end_size = 0; - p.friction = 0.7f; - p.gravity = frandom()*-500.0f; - p.color = vec4(0.75f,0.75f,0.75f,1.0f); - gameclient.particles->add(PARTICLES::GROUP_GENERAL, &p); + CParticle p; + p.SetDefault(); + p.m_Spr = SPRITE_PART_SMOKE; + p.m_Pos = Pos; + p.m_Vel = Vel + RandomDir()*50.0f; + p.m_LifeSpan = 0.5f + frandom()*0.5f; + p.m_StartSize = 24.0f + frandom()*12; + p.m_EndSize = 0; + p.m_Friction = 0.7f; + p.m_Gravity = frandom()*-500.0f; + p.m_Color = vec4(0.75f,0.75f,0.75f,1.0f); + m_pClient->m_pParticles->Add(CParticles::GROUP_GENERAL, &p); } -void EFFECTS::bullettrail(vec2 pos) +void CEffects::BulletTrail(vec2 Pos) { - if(!add_100hz) + if(!m_Add100hz) return; - PARTICLE p; - p.set_default(); - p.spr = SPRITE_PART_BALL; - p.pos = pos; - p.life_span = 0.25f + frandom()*0.25f; - p.start_size = 8.0f; - p.end_size = 0; - p.friction = 0.7f; - gameclient.particles->add(PARTICLES::GROUP_PROJECTILE_TRAIL, &p); + CParticle p; + p.SetDefault(); + p.m_Spr = SPRITE_PART_BALL; + p.m_Pos = Pos; + p.m_LifeSpan = 0.25f + frandom()*0.25f; + p.m_StartSize = 8.0f; + p.m_EndSize = 0; + p.m_Friction = 0.7f; + m_pClient->m_pParticles->Add(CParticles::GROUP_PROJECTILE_TRAIL, &p); } -void EFFECTS::playerspawn(vec2 pos) +void CEffects::PlayerSpawn(vec2 Pos) { for(int i = 0; i < 32; i++) { - PARTICLE p; - p.set_default(); - p.spr = SPRITE_PART_SHELL; - p.pos = pos; - p.vel = random_dir() * (pow(frandom(), 3)*600.0f); - p.life_span = 0.3f + frandom()*0.3f; - p.start_size = 64.0f + frandom()*32; - p.end_size = 0; - p.rot = frandom()*pi*2; - p.rotspeed = frandom(); - p.gravity = frandom()*-400.0f; - p.friction = 0.7f; - p.color = vec4(0xb5/255.0f, 0x50/255.0f, 0xcb/255.0f, 1.0f); - gameclient.particles->add(PARTICLES::GROUP_GENERAL, &p); + CParticle p; + p.SetDefault(); + p.m_Spr = SPRITE_PART_SHELL; + p.m_Pos = Pos; + p.m_Vel = RandomDir() * (powf(frandom(), 3)*600.0f); + p.m_LifeSpan = 0.3f + frandom()*0.3f; + p.m_StartSize = 64.0f + frandom()*32; + p.m_EndSize = 0; + p.m_Rot = frandom()*pi*2; + p.m_Rotspeed = frandom(); + p.m_Gravity = frandom()*-400.0f; + p.m_Friction = 0.7f; + p.m_Color = vec4(0xb5/255.0f, 0x50/255.0f, 0xcb/255.0f, 1.0f); + m_pClient->m_pParticles->Add(CParticles::GROUP_GENERAL, &p); } - gameclient.sounds->play(SOUNDS::CHN_WORLD, SOUND_PLAYER_SPAWN, 1.0f, pos); + m_pClient->m_pSounds->Play(CSounds::CHN_WORLD, SOUND_PLAYER_SPAWN, 1.0f, Pos); } -void EFFECTS::playerdeath(vec2 pos, int cid) +void CEffects::PlayerDeath(vec2 Pos, int Cid) { - vec3 blood_color(1.0f,1.0f,1.0f); + vec3 BloodColor(1.0f,1.0f,1.0f); - if(cid >= 0) + if(Cid >= 0) { - const SKINS::SKIN *s = gameclient.skins->get(gameclient.clients[cid].skin_id); + const CSkins::CSkin *s = m_pClient->m_pSkins->Get(m_pClient->m_aClients[Cid].m_SkinId); if(s) - blood_color = s->blood_color; + BloodColor = s->m_BloodColor; } for(int i = 0; i < 64; i++) { - PARTICLE p; - p.set_default(); - p.spr = SPRITE_PART_SPLAT01 + (rand()%3); - p.pos = pos; - p.vel = random_dir() * ((frandom()+0.1f)*900.0f); - p.life_span = 0.3f + frandom()*0.3f; - p.start_size = 24.0f + frandom()*16; - p.end_size = 0; - p.rot = frandom()*pi*2; - p.rotspeed = (frandom()-0.5f) * pi; - p.gravity = 800.0f; - p.friction = 0.8f; - vec3 c = blood_color * (0.75f + frandom()*0.25f); - p.color = vec4(c.r, c.g, c.b, 0.75f); - gameclient.particles->add(PARTICLES::GROUP_GENERAL, &p); + CParticle p; + p.SetDefault(); + p.m_Spr = SPRITE_PART_SPLAT01 + (rand()%3); + p.m_Pos = Pos; + p.m_Vel = RandomDir() * ((frandom()+0.1f)*900.0f); + p.m_LifeSpan = 0.3f + frandom()*0.3f; + p.m_StartSize = 24.0f + frandom()*16; + p.m_EndSize = 0; + p.m_Rot = frandom()*pi*2; + p.m_Rotspeed = (frandom()-0.5f) * pi; + p.m_Gravity = 800.0f; + p.m_Friction = 0.8f; + vec3 c = BloodColor * (0.75f + frandom()*0.25f); + p.m_Color = vec4(c.r, c.g, c.b, 0.75f); + m_pClient->m_pParticles->Add(CParticles::GROUP_GENERAL, &p); } } -void EFFECTS::explosion(vec2 pos) +void CEffects::Explosion(vec2 Pos) { // add to flow for(int y = -8; y <= 8; y++) @@ -187,75 +185,75 @@ void EFFECTS::explosion(vec2 pos) continue; float a = 1 - (length(vec2(x,y)) / length(vec2(8,8))); - gameclient.flow->add(pos+vec2(x,y)*16, normalize(vec2(x,y))*5000.0f*a, 10.0f); + m_pClient->m_pFlow->Add(Pos+vec2(x,y)*16, normalize(vec2(x,y))*5000.0f*a, 10.0f); } // add the explosion - PARTICLE p; - p.set_default(); - p.spr = SPRITE_PART_EXPL01; - p.pos = pos; - p.life_span = 0.4f; - p.start_size = 150.0f; - p.end_size = 0; - p.rot = frandom()*pi*2; - gameclient.particles->add(PARTICLES::GROUP_EXPLOSIONS, &p); + CParticle p; + p.SetDefault(); + p.m_Spr = SPRITE_PART_EXPL01; + p.m_Pos = Pos; + p.m_LifeSpan = 0.4f; + p.m_StartSize = 150.0f; + p.m_EndSize = 0; + p.m_Rot = frandom()*pi*2; + m_pClient->m_pParticles->Add(CParticles::GROUP_EXPLOSIONS, &p); // add the smoke for(int i = 0; i < 24; i++) { - PARTICLE p; - p.set_default(); - p.spr = SPRITE_PART_SMOKE; - p.pos = pos; - p.vel = random_dir() * ((1.0f + frandom()*0.2f) * 1000.0f); - p.life_span = 0.5f + frandom()*0.4f; - p.start_size = 32.0f + frandom()*8; - p.end_size = 0; - p.gravity = frandom()*-800.0f; - p.friction = 0.4f; - p.color = mix(vec4(0.75f,0.75f,0.75f,1.0f), vec4(0.5f,0.5f,0.5f,1.0f), frandom()); - gameclient.particles->add(PARTICLES::GROUP_GENERAL, &p); + CParticle p; + p.SetDefault(); + p.m_Spr = SPRITE_PART_SMOKE; + p.m_Pos = Pos; + p.m_Vel = RandomDir() * ((1.0f + frandom()*0.2f) * 1000.0f); + p.m_LifeSpan = 0.5f + frandom()*0.4f; + p.m_StartSize = 32.0f + frandom()*8; + p.m_EndSize = 0; + p.m_Gravity = frandom()*-800.0f; + p.m_Friction = 0.4f; + p.m_Color = mix(vec4(0.75f,0.75f,0.75f,1.0f), vec4(0.5f,0.5f,0.5f,1.0f), frandom()); + m_pClient->m_pParticles->Add(CParticles::GROUP_GENERAL, &p); } } -void EFFECTS::hammerhit(vec2 pos) +void CEffects::HammerHit(vec2 Pos) { // add the explosion - PARTICLE p; - p.set_default(); - p.spr = SPRITE_PART_EXPL01; - p.pos = pos; - p.life_span = 0.4f; - p.start_size = 150.0f; - p.end_size = 0; - p.rot = frandom()*pi*2; - gameclient.particles->add(PARTICLES::GROUP_EXPLOSIONS, &p); - gameclient.sounds->play(SOUNDS::CHN_WORLD, SOUND_HAMMER_HIT, 1.0f, pos); + CParticle p; + p.SetDefault(); + p.m_Spr = SPRITE_PART_EXPL01; + p.m_Pos = Pos; + p.m_LifeSpan = 0.4f; + p.m_StartSize = 150.0f; + p.m_EndSize = 0; + p.m_Rot = frandom()*pi*2; + m_pClient->m_pParticles->Add(CParticles::GROUP_EXPLOSIONS, &p); + m_pClient->m_pSounds->Play(CSounds::CHN_WORLD, SOUND_HAMMER_HIT, 1.0f, Pos); } -void EFFECTS::on_render() +void CEffects::OnRender() { - static int64 last_update_100hz = 0; - static int64 last_update_50hz = 0; + static int64 LastUpdate100hz = 0; + static int64 LastUpdate50hz = 0; - if(time_get()-last_update_100hz > time_freq()/100) + if(time_get()-LastUpdate100hz > time_freq()/100) { - add_100hz = true; - last_update_100hz = time_get(); + m_Add100hz = true; + LastUpdate100hz = time_get(); } else - add_100hz = false; + m_Add100hz = false; - if(time_get()-last_update_50hz > time_freq()/100) + if(time_get()-LastUpdate50hz > time_freq()/100) { - add_50hz = true; - last_update_50hz = time_get(); + m_Add50hz = true; + LastUpdate50hz = time_get(); } else - add_50hz = false; + m_Add50hz = false; - if(add_50hz) - gameclient.flow->update(); + if(m_Add50hz) + m_pClient->m_pFlow->Update(); } diff --git a/src/game/client/components/effects.h b/src/game/client/components/effects.h new file mode 100644 index 00000000..e8345500 --- /dev/null +++ b/src/game/client/components/effects.h @@ -0,0 +1,27 @@ +#ifndef GAME_CLIENT_COMPONENTS_EFFECTS_H +#define GAME_CLIENT_COMPONENTS_EFFECTS_H +#include <game/client/component.h> + +class CEffects : public CComponent +{ + bool m_Add50hz; + bool m_Add100hz; +public: + CEffects(); + + virtual void OnRender(); + + void BulletTrail(vec2 Pos); + void SmokeTrail(vec2 Pos, vec2 Vel); + void SkidTrail(vec2 Pos, vec2 Vel); + void Explosion(vec2 Pos); + void HammerHit(vec2 Pos); + void AirJump(vec2 Pos); + void DamageIndicator(vec2 Pos, vec2 Dir); + void PlayerSpawn(vec2 Pos); + void PlayerDeath(vec2 Pos, int ClientId); + void PowerupShine(vec2 Pos, vec2 Size); + + void Update(); +}; +#endif diff --git a/src/game/client/components/effects.hpp b/src/game/client/components/effects.hpp deleted file mode 100644 index 8574bf60..00000000 --- a/src/game/client/components/effects.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#include <game/client/component.hpp> - -class EFFECTS : public COMPONENT -{ - bool add_50hz; - bool add_100hz; -public: - EFFECTS(); - - virtual void on_render(); - - void bullettrail(vec2 pos); - void smoketrail(vec2 pos, vec2 vel); - void skidtrail(vec2 pos, vec2 vel); - void explosion(vec2 pos); - void hammerhit(vec2 pos); - void air_jump(vec2 pos); - void damage_indicator(vec2 pos, vec2 dir); - void playerspawn(vec2 pos); - void playerdeath(vec2 pos, int cid); - void powerupshine(vec2 pos, vec2 size); - - void update(); -}; diff --git a/src/game/client/components/emoticon.cpp b/src/game/client/components/emoticon.cpp index 8001a306..6d03f88d 100644 --- a/src/game/client/components/emoticon.cpp +++ b/src/game/client/components/emoticon.cpp @@ -1,157 +1,161 @@ -#include <engine/e_client_interface.h> -#include <engine/client/graphics.h> -#include <game/generated/g_protocol.hpp> -#include <game/generated/gc_data.hpp> - -#include <game/gamecore.hpp> // get_angle -#include <game/client/gameclient.hpp> -#include <game/client/ui.hpp> -#include <game/client/render.hpp> -#include "emoticon.hpp" - -EMOTICON::EMOTICON() +#include <engine/graphics.h> +#include <engine/shared/config.h> +#include <game/generated/protocol.h> +#include <game/generated/client_data.h> + +#include <game/gamecore.h> // get_angle +#include <game/client/gameclient.h> +#include <game/client/ui.h> +#include <game/client/render.h> +#include "emoticon.h" + +CEmoticon::CEmoticon() { - on_reset(); + OnReset(); } -void EMOTICON::con_key_emoticon(void *result, void *user_data) +void CEmoticon::ConKeyEmoticon(IConsole::IResult *pResult, void *pUserData) { - ((EMOTICON *)user_data)->active = console_arg_int(result, 0) != 0; + ((CEmoticon *)pUserData)->m_Active = pResult->GetInteger(0) != 0; } -void EMOTICON::con_emote(void *result, void *user_data) +void CEmoticon::ConEmote(IConsole::IResult *pResult, void *pUserData) { - ((EMOTICON *)user_data)->emote(console_arg_int(result, 0)); + ((CEmoticon *)pUserData)->Emote(pResult->GetInteger(0)); } -void EMOTICON::on_console_init() +void CEmoticon::OnConsoleInit() { - MACRO_REGISTER_COMMAND("+emote", "", CFGFLAG_CLIENT, con_key_emoticon, this, "Open emote selector"); - MACRO_REGISTER_COMMAND("emote", "i", CFGFLAG_CLIENT, con_emote, this, "Use emote"); + Console()->Register("+emote", "", CFGFLAG_CLIENT, ConKeyEmoticon, this, "Open emote selector"); + Console()->Register("emote", "i", CFGFLAG_CLIENT, ConEmote, this, "Use emote"); } -void EMOTICON::on_reset() +void CEmoticon::OnReset() { - was_active = false; - active = false; - selected_emote = -1; + m_WasActive = false; + m_Active = false; + m_SelectedEmote = -1; } -void EMOTICON::on_message(int msgtype, void *rawmsg) +void CEmoticon::OnMessage(int MsgType, void *pRawMsg) { - if(msgtype == NETMSGTYPE_SV_EMOTICON) - { - NETMSG_SV_EMOTICON *msg = (NETMSG_SV_EMOTICON *)rawmsg; - gameclient.clients[msg->cid].emoticon = msg->emoticon; - gameclient.clients[msg->cid].emoticon_start = client_tick(); - } } -bool EMOTICON::on_mousemove(float x, float y) +bool CEmoticon::OnMouseMove(float x, float y) { - if(!active) + if(!m_Active) return false; - selector_mouse += vec2(x,y); + m_SelectorMouse += vec2(x,y); return true; } -void EMOTICON::draw_circle(float x, float y, float r, int segments) +void CEmoticon::DrawCircle(float x, float y, float r, int Segments) { - float f_segments = (float)segments; - for(int i = 0; i < segments; i+=2) + IGraphics::CFreeformItem Array[32]; + int NumItems = 0; + float FSegments = (float)Segments; + for(int i = 0; i < Segments; i+=2) { - float a1 = i/f_segments * 2*pi; - float a2 = (i+1)/f_segments * 2*pi; - float a3 = (i+2)/f_segments * 2*pi; - float ca1 = cosf(a1); - float ca2 = cosf(a2); - float ca3 = cosf(a3); - float sa1 = sinf(a1); - float sa2 = sinf(a2); - float sa3 = sinf(a3); - - client->Graphics()->QuadsDrawFreeform( + float a1 = i/FSegments * 2*pi; + float a2 = (i+1)/FSegments * 2*pi; + float a3 = (i+2)/FSegments * 2*pi; + float Ca1 = cosf(a1); + float Ca2 = cosf(a2); + float Ca3 = cosf(a3); + float Sa1 = sinf(a1); + float Sa2 = sinf(a2); + float Sa3 = sinf(a3); + + Array[NumItems++] = IGraphics::CFreeformItem( x, y, - x+ca1*r, y+sa1*r, - x+ca3*r, y+sa3*r, - x+ca2*r, y+sa2*r); + x+Ca1*r, y+Sa1*r, + x+Ca3*r, y+Sa3*r, + x+Ca2*r, y+Sa2*r); + if(NumItems == 32) + { + m_pClient->Graphics()->QuadsDrawFreeform(Array, 32); + NumItems = 0; + } } + if(NumItems) + m_pClient->Graphics()->QuadsDrawFreeform(Array, NumItems); } -void EMOTICON::on_render() +void CEmoticon::OnRender() { - if(!active) + if(!m_Active) { - if(was_active && selected_emote != -1) - emote(selected_emote); - was_active = false; + if(m_WasActive && m_SelectedEmote != -1) + Emote(m_SelectedEmote); + m_WasActive = false; return; } - was_active = true; + m_WasActive = true; int x, y; - inp_mouse_relative(&x, &y); + Input()->MouseRelative(&x, &y); - selector_mouse.x += x; - selector_mouse.y += y; + m_SelectorMouse.x += x; + m_SelectorMouse.y += y; - if (length(selector_mouse) > 140) - selector_mouse = normalize(selector_mouse) * 140; + if (length(m_SelectorMouse) > 140) + m_SelectorMouse = normalize(m_SelectorMouse) * 140; - float selected_angle = get_angle(selector_mouse) + 2*pi/24; - if (selected_angle < 0) - selected_angle += 2*pi; + float SelectedAngle = GetAngle(m_SelectorMouse) + 2*pi/24; + if (SelectedAngle < 0) + SelectedAngle += 2*pi; - if (length(selector_mouse) > 100) - selected_emote = (int)(selected_angle / (2*pi) * 12.0f); + if (length(m_SelectorMouse) > 100) + m_SelectedEmote = (int)(SelectedAngle / (2*pi) * 12.0f); - CUIRect screen = *UI()->Screen(); + CUIRect Screen = *UI()->Screen(); - Graphics()->MapScreen(screen.x, screen.y, screen.w, screen.h); + Graphics()->MapScreen(Screen.x, Screen.y, Screen.w, Screen.h); Graphics()->BlendNormal(); Graphics()->TextureSet(-1); Graphics()->QuadsBegin(); Graphics()->SetColor(0,0,0,0.3f); - draw_circle(screen.w/2, screen.h/2, 160, 64); + DrawCircle(Screen.w/2, Screen.h/2, 160, 64); Graphics()->QuadsEnd(); - Graphics()->TextureSet(data->images[IMAGE_EMOTICONS].id); + Graphics()->TextureSet(g_pData->m_aImages[IMAGE_EMOTICONS].m_Id); Graphics()->QuadsBegin(); for (int i = 0; i < 12; i++) { - float angle = 2*pi*i/12.0; - if (angle > pi) - angle -= 2*pi; + float Angle = 2*pi*i/12.0; + if (Angle > pi) + Angle -= 2*pi; - bool selected = selected_emote == i; + bool Selected = m_SelectedEmote == i; - float size = selected ? 96 : 64; + float Size = Selected ? 96 : 64; - float nudge_x = 120 * cos(angle); - float nudge_y = 120 * sin(angle); - RenderTools()->select_sprite(SPRITE_OOP + i); - Graphics()->QuadsDraw(screen.w/2 + nudge_x, screen.h/2 + nudge_y, size, size); + float NudgeX = 120 * cosf(Angle); + float NudgeY = 120 * sinf(Angle); + RenderTools()->SelectSprite(SPRITE_OOP + i); + IGraphics::CQuadItem QuadItem(Screen.w/2 + NudgeX, Screen.h/2 + NudgeY, Size, Size); + Graphics()->QuadsDraw(&QuadItem, 1); } Graphics()->QuadsEnd(); - Graphics()->TextureSet(data->images[IMAGE_CURSOR].id); + Graphics()->TextureSet(g_pData->m_aImages[IMAGE_CURSOR].m_Id); Graphics()->QuadsBegin(); Graphics()->SetColor(1,1,1,1); - Graphics()->QuadsDrawTL(selector_mouse.x+screen.w/2,selector_mouse.y+screen.h/2,24,24); + IGraphics::CQuadItem QuadItem(m_SelectorMouse.x+Screen.w/2,m_SelectorMouse.y+Screen.h/2,24,24); + Graphics()->QuadsDrawTL(&QuadItem, 1); Graphics()->QuadsEnd(); } -void EMOTICON::emote(int emoticon) +void CEmoticon::Emote(int Emoticon) { - NETMSG_CL_EMOTICON msg; - msg.emoticon = emoticon; - msg.pack(MSGFLAG_VITAL); - client_send_msg(); + CNetMsg_Cl_Emoticon Msg; + Msg.m_Emoticon = Emoticon; + Client()->SendPackMsg(&Msg, MSGFLAG_VITAL); } diff --git a/src/game/client/components/emoticon.h b/src/game/client/components/emoticon.h new file mode 100644 index 00000000..e10b57da --- /dev/null +++ b/src/game/client/components/emoticon.h @@ -0,0 +1,31 @@ +#ifndef GAME_CLIENT_COMPONENTS_EMOTICON_H +#define GAME_CLIENT_COMPONENTS_EMOTICON_H +#include <base/vmath.h> +#include <game/client/component.h> + +class CEmoticon : public CComponent +{ + void DrawCircle(float x, float y, float r, int Segments); + + bool m_WasActive; + bool m_Active; + + vec2 m_SelectorMouse; + int m_SelectedEmote; + + static void ConKeyEmoticon(IConsole::IResult *pResult, void *pUserData); + static void ConEmote(IConsole::IResult *pResult, void *pUserData); + +public: + CEmoticon(); + + virtual void OnReset(); + virtual void OnConsoleInit(); + virtual void OnRender(); + virtual void OnMessage(int MsgType, void *pRawMsg); + virtual bool OnMouseMove(float x, float y); + + void Emote(int Emoticon); +}; + +#endif diff --git a/src/game/client/components/emoticon.hpp b/src/game/client/components/emoticon.hpp deleted file mode 100644 index 446b4b00..00000000 --- a/src/game/client/components/emoticon.hpp +++ /dev/null @@ -1,28 +0,0 @@ -#include <base/vmath.hpp> -#include <game/client/component.hpp> - -class EMOTICON : public COMPONENT -{ - void draw_circle(float x, float y, float r, int segments); - - bool was_active; - bool active; - - vec2 selector_mouse; - int selected_emote; - - static void con_key_emoticon(void *result, void *user_data); - static void con_emote(void *result, void *user_data); - -public: - EMOTICON(); - - virtual void on_reset(); - virtual void on_console_init(); - virtual void on_render(); - virtual void on_message(int msgtype, void *rawmsg); - virtual bool on_mousemove(float x, float y); - - void emote(int emoticon); -}; - diff --git a/src/game/client/components/flow.cpp b/src/game/client/components/flow.cpp index 9ecd4b5c..d2ba704c 100644 --- a/src/game/client/components/flow.cpp +++ b/src/game/client/components/flow.cpp @@ -1,85 +1,94 @@ -#include <engine/client/graphics.h> -#include <game/mapitems.hpp> -#include <game/layers.hpp> -#include "flow.hpp" +#include <engine/graphics.h> +#include <game/mapitems.h> +#include <game/layers.h> +#include "flow.h" -FLOW::FLOW() +CFlow::CFlow() { - cells = 0; - height = 0; - width = 0; - spacing = 16; + m_pCells = 0; + m_Height = 0; + m_Width = 0; + m_Spacing = 16; } -void FLOW::dbg_render() +void CFlow::DbgRender() { - if(!cells) + if(!m_pCells) return; + IGraphics::CLineItem Array[1024]; + int NumItems = 0; Graphics()->TextureSet(-1); Graphics()->LinesBegin(); - for(int y = 0; y < height; y++) - for(int x = 0; x < width; x++) + for(int y = 0; y < m_Height; y++) + for(int x = 0; x < m_Width; x++) { - vec2 pos(x*spacing, y*spacing); - vec2 vel = cells[y*width+x].vel * 0.01f; - Graphics()->LinesDraw(pos.x, pos.y, pos.x+vel.x, pos.y+vel.y); + vec2 Pos(x*m_Spacing, y*m_Spacing); + vec2 Vel = m_pCells[y*m_Width+x].m_Vel * 0.01f; + Array[NumItems++] = IGraphics::CLineItem(Pos.x, Pos.y, Pos.x+Vel.x, Pos.y+Vel.y); + if(NumItems == 1024) + { + Graphics()->LinesDraw(Array, 1024); + NumItems = 0; + } } - + + if(NumItems) + Graphics()->LinesDraw(Array, NumItems); Graphics()->LinesEnd(); } -void FLOW::init() +void CFlow::Init() { - if(cells) + if(m_pCells) { - mem_free(cells); - cells = 0; + mem_free(m_pCells); + m_pCells = 0; } - MAPITEM_LAYER_TILEMAP *tilemap = layers_game_layer(); - width = tilemap->width*32/spacing; - height = tilemap->height*32/spacing; + CMapItemLayerTilemap *pTilemap = Layers()->GameLayer(); + m_Width = pTilemap->m_Width*32/m_Spacing; + m_Height = pTilemap->m_Height*32/m_Spacing; // allocate and clear - cells = (CELL *)mem_alloc(sizeof(CELL)*width*height, 1); - for(int y = 0; y < height; y++) - for(int x = 0; x < width; x++) - cells[y*width+x].vel = vec2(0.0f, 0.0f); + m_pCells = (CCell *)mem_alloc(sizeof(CCell)*m_Width*m_Height, 1); + for(int y = 0; y < m_Height; y++) + for(int x = 0; x < m_Width; x++) + m_pCells[y*m_Width+x].m_Vel = vec2(0.0f, 0.0f); } -void FLOW::update() +void CFlow::Update() { - if(!cells) + if(!m_pCells) return; - for(int y = 0; y < height; y++) - for(int x = 0; x < width; x++) - cells[y*width+x].vel *= 0.85f; + for(int y = 0; y < m_Height; y++) + for(int x = 0; x < m_Width; x++) + m_pCells[y*m_Width+x].m_Vel *= 0.85f; } -vec2 FLOW::get(vec2 pos) +vec2 CFlow::Get(vec2 Pos) { - if(!cells) + if(!m_pCells) return vec2(0,0); - int x = (int)(pos.x / spacing); - int y = (int)(pos.y / spacing); - if(x < 0 || y < 0 || x >= width || y >= height) + int x = (int)(Pos.x / m_Spacing); + int y = (int)(Pos.y / m_Spacing); + if(x < 0 || y < 0 || x >= m_Width || y >= m_Height) return vec2(0,0); - return cells[y*width+x].vel; + return m_pCells[y*m_Width+x].m_Vel; } -void FLOW::add(vec2 pos, vec2 vel, float size) +void CFlow::Add(vec2 Pos, vec2 Vel, float Size) { - if(!cells) + if(!m_pCells) return; - int x = (int)(pos.x / spacing); - int y = (int)(pos.y / spacing); - if(x < 0 || y < 0 || x >= width || y >= height) + int x = (int)(Pos.x / m_Spacing); + int y = (int)(Pos.y / m_Spacing); + if(x < 0 || y < 0 || x >= m_Width || y >= m_Height) return; - cells[y*width+x].vel += vel; + m_pCells[y*m_Width+x].m_Vel += Vel; } diff --git a/src/game/client/components/flow.h b/src/game/client/components/flow.h new file mode 100644 index 00000000..e8134797 --- /dev/null +++ b/src/game/client/components/flow.h @@ -0,0 +1,28 @@ +#ifndef GAME_CLIENT_COMPONENTS_FLOW_H +#define GAME_CLIENT_COMPONENTS_FLOW_H +#include <base/vmath.h> +#include <game/client/component.h> + +class CFlow : public CComponent +{ + struct CCell + { + vec2 m_Vel; + }; + + CCell *m_pCells; + int m_Height; + int m_Width; + int m_Spacing; + + void DbgRender(); + void Init(); +public: + CFlow(); + + vec2 Get(vec2 Pos); + void Add(vec2 Pos, vec2 Vel, float Size); + void Update(); +}; + +#endif diff --git a/src/game/client/components/flow.hpp b/src/game/client/components/flow.hpp deleted file mode 100644 index 351b1f69..00000000 --- a/src/game/client/components/flow.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#include <base/vmath.hpp> -#include <game/client/component.hpp> - -class FLOW : public COMPONENT -{ - struct CELL - { - vec2 vel; - }; - - CELL *cells; - int height; - int width; - int spacing; - - void dbg_render(); - void init(); -public: - FLOW(); - - vec2 get(vec2 pos); - void add(vec2 pos, vec2 vel, float size); - void update(); -}; - diff --git a/src/game/client/components/hud.cpp b/src/game/client/components/hud.cpp index 837322fb..f4a24384 100644 --- a/src/game/client/components/hud.cpp +++ b/src/game/client/components/hud.cpp @@ -1,32 +1,31 @@ -#include <memory.h> // memcmp - -#include <engine/e_client_interface.h> -#include <engine/client/graphics.h> -#include <game/generated/g_protocol.hpp> -#include <game/generated/gc_data.hpp> - -#include <game/layers.hpp> - -#include <game/client/gameclient.hpp> -#include <game/client/animstate.hpp> -#include <game/client/render.hpp> - -#include "controls.hpp" -#include "camera.hpp" -#include "hud.hpp" -#include "voting.hpp" -#include "binds.hpp" - -HUD::HUD() +#include <engine/graphics.h> +#include <engine/textrender.h> +#include <engine/shared/config.h> + +#include <game/generated/protocol.h> +#include <game/generated/client_data.h> +#include <game/layers.h> +#include <game/client/gameclient.h> +#include <game/client/animstate.h> +#include <game/client/render.h> + +#include "controls.h" +#include "camera.h" +#include "hud.h" +#include "voting.h" +#include "binds.h" + +CHud::CHud() { - + // won't work if zero + m_AverageFPS = 1.0f; } -void HUD::on_reset() +void CHud::OnReset() { } -void HUD::render_goals() +void CHud::RenderGoals() { // TODO: split this up into these: // render_gametimer @@ -34,41 +33,41 @@ void HUD::render_goals() // render_scorehud // render_warmuptimer - int gameflags = gameclient.snap.gameobj->flags; + int GameFlags = m_pClient->m_Snap.m_pGameobj->m_Flags; - float whole = 300*Graphics()->ScreenAspect(); - float half = whole/2.0f; + float Whole = 300*Graphics()->ScreenAspect(); + float Half = Whole/2.0f; Graphics()->MapScreen(0,0,300*Graphics()->ScreenAspect(),300); - if(!gameclient.snap.gameobj->sudden_death) + if(!m_pClient->m_Snap.m_pGameobj->m_SuddenDeath) { - char buf[32]; - int time = 0; - if(gameclient.snap.gameobj->time_limit) + char Buf[32]; + int Time = 0; + if(m_pClient->m_Snap.m_pGameobj->m_TimeLimit) { - time = gameclient.snap.gameobj->time_limit*60 - ((client_tick()-gameclient.snap.gameobj->round_start_tick)/client_tickspeed()); + Time = m_pClient->m_Snap.m_pGameobj->m_TimeLimit*60 - ((Client()->GameTick()-m_pClient->m_Snap.m_pGameobj->m_RoundStartTick)/Client()->GameTickSpeed()); - if(gameclient.snap.gameobj->game_over) - time = 0; + if(m_pClient->m_Snap.m_pGameobj->m_GameOver) + Time = 0; } else - time = (client_tick()-gameclient.snap.gameobj->round_start_tick)/client_tickspeed(); + Time = (Client()->GameTick()-m_pClient->m_Snap.m_pGameobj->m_RoundStartTick)/Client()->GameTickSpeed(); - str_format(buf, sizeof(buf), "%d:%02d", time /60, time %60); - float w = gfx_text_width(0, 16, buf, -1); - gfx_text(0, half-w/2, 2, 16, buf, -1); + str_format(Buf, sizeof(Buf), "%d:%02d", Time /60, Time %60); + float w = TextRender()->TextWidth(0, 16, Buf, -1); + TextRender()->Text(0, Half-w/2, 2, 16, Buf, -1); } - if(gameclient.snap.gameobj->sudden_death) + if(m_pClient->m_Snap.m_pGameobj->m_SuddenDeath) { - const char *text = "Sudden Death"; - float w = gfx_text_width(0, 16, text, -1); - gfx_text(0, half-w/2, 2, 16, text, -1); + const char *pText = "Sudden Death"; + float w = TextRender()->TextWidth(0, 16, pText, -1); + TextRender()->Text(0, Half-w/2, 2, 16, pText, -1); } // render small score hud - if(!(gameclient.snap.gameobj && gameclient.snap.gameobj->game_over) && (gameflags&GAMEFLAG_TEAMS)) + if(!(m_pClient->m_Snap.m_pGameobj && m_pClient->m_Snap.m_pGameobj->m_GameOver) && (GameFlags&GAMEFLAG_TEAMS)) { for(int t = 0; t < 2; t++) { @@ -79,166 +78,171 @@ void HUD::render_goals() Graphics()->SetColor(1,0,0,0.25f); else Graphics()->SetColor(0,0,1,0.25f); - RenderTools()->draw_round_rect(whole-40, 300-40-15+t*20, 50, 18, 5.0f); + RenderTools()->DrawRoundRect(Whole-45, 300-40-15+t*20, 50, 18, 5.0f); Graphics()->QuadsEnd(); - char buf[32]; - str_format(buf, sizeof(buf), "%d", t?gameclient.snap.gameobj->teamscore_blue:gameclient.snap.gameobj->teamscore_red); - float w = gfx_text_width(0, 14, buf, -1); + char Buf[32]; + str_format(Buf, sizeof(Buf), "%d", t?m_pClient->m_Snap.m_pGameobj->m_TeamscoreBlue : m_pClient->m_Snap.m_pGameobj->m_TeamscoreRed); + float w = TextRender()->TextWidth(0, 14, Buf, -1); - if(gameflags&GAMEFLAG_FLAGS) + if(GameFlags&GAMEFLAG_FLAGS) { - gfx_text(0, whole-20-w/2+5, 300-40-15+t*20, 14, buf, -1); - if(gameclient.snap.flags[t]) + TextRender()->Text(0, Whole-20-w/2+5, 300-40-15+t*20, 14, Buf, -1); + if(m_pClient->m_Snap.m_paFlags[t]) { - if(gameclient.snap.flags[t]->carried_by == -2 || (gameclient.snap.flags[t]->carried_by == -1 && ((client_tick()/10)&1))) + if(m_pClient->m_Snap.m_paFlags[t]->m_CarriedBy == -2 || (m_pClient->m_Snap.m_paFlags[t]->m_CarriedBy == -1 && ((Client()->GameTick()/10)&1))) { Graphics()->BlendNormal(); - Graphics()->TextureSet(data->images[IMAGE_GAME].id); + Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id); Graphics()->QuadsBegin(); - if(t == 0) RenderTools()->select_sprite(SPRITE_FLAG_RED); - else RenderTools()->select_sprite(SPRITE_FLAG_BLUE); + if(t == 0) RenderTools()->SelectSprite(SPRITE_FLAG_RED); + else RenderTools()->SelectSprite(SPRITE_FLAG_BLUE); - float size = 16; - Graphics()->QuadsDrawTL(whole-40+5, 300-40-15+t*20+1, size/2, size); + float Size = 16; + IGraphics::CQuadItem QuadItem(Whole-40+2, 300-40-15+t*20+1, Size/2, Size); + Graphics()->QuadsDrawTL(&QuadItem, 1); Graphics()->QuadsEnd(); } - else if(gameclient.snap.flags[t]->carried_by >= 0) + else if(m_pClient->m_Snap.m_paFlags[t]->m_CarriedBy >= 0) { - int id = gameclient.snap.flags[t]->carried_by%MAX_CLIENTS; - const char *name = gameclient.clients[id].name; - float w = gfx_text_width(0, 10, name, -1); - gfx_text(0, whole-40-5-w, 300-40-15+t*20+2, 10, name, -1); - TEE_RENDER_INFO info = gameclient.clients[id].render_info; - info.size = 18.0f; + int Id = m_pClient->m_Snap.m_paFlags[t]->m_CarriedBy%MAX_CLIENTS; + const char *pName = m_pClient->m_aClients[Id].m_aName; + float w = TextRender()->TextWidth(0, 10, pName, -1); + TextRender()->Text(0, Whole-40-7-w, 300-40-15+t*20+2, 10, pName, -1); + CTeeRenderInfo Info = m_pClient->m_aClients[Id].m_RenderInfo; + Info.m_Size = 18.0f; - RenderTools()->RenderTee(ANIMSTATE::get_idle(), &info, EMOTE_NORMAL, vec2(1,0), - vec2(whole-40+10, 300-40-15+9+t*20+1)); + RenderTools()->RenderTee(CAnimState::GetIdle(), &Info, EMOTE_NORMAL, vec2(1,0), + vec2(Whole-40+5, 300-40-15+9+t*20+1)); } } } else - gfx_text(0, whole-20-w/2, 300-40-15+t*20, 14, buf, -1); + TextRender()->Text(0, Whole-20-w/2, 300-40-15+t*20, 14, Buf, -1); } } // render warmup timer - if(gameclient.snap.gameobj->warmup) + if(m_pClient->m_Snap.m_pGameobj->m_Warmup) { - char buf[256]; - float w = gfx_text_width(0, 24, "Warmup", -1); - gfx_text(0, 150*Graphics()->ScreenAspect()+-w/2, 50, 24, "Warmup", -1); + char Buf[256]; + float w = TextRender()->TextWidth(0, 24, "Warmup", -1); + TextRender()->Text(0, 150*Graphics()->ScreenAspect()+-w/2, 50, 24, "Warmup", -1); - int seconds = gameclient.snap.gameobj->warmup/SERVER_TICK_SPEED; - if(seconds < 5) - str_format(buf, sizeof(buf), "%d.%d", seconds, (gameclient.snap.gameobj->warmup*10/SERVER_TICK_SPEED)%10); + int Seconds = m_pClient->m_Snap.m_pGameobj->m_Warmup/SERVER_TICK_SPEED; + if(Seconds < 5) + str_format(Buf, sizeof(Buf), "%d.%d", Seconds, (m_pClient->m_Snap.m_pGameobj->m_Warmup*10/SERVER_TICK_SPEED)%10); else - str_format(buf, sizeof(buf), "%d", seconds); - w = gfx_text_width(0, 24, buf, -1); - gfx_text(0, 150*Graphics()->ScreenAspect()+-w/2, 75, 24, buf, -1); + str_format(Buf, sizeof(Buf), "%d", Seconds); + w = TextRender()->TextWidth(0, 24, Buf, -1); + TextRender()->Text(0, 150*Graphics()->ScreenAspect()+-w/2, 75, 24, Buf, -1); } } -void HUD::mapscreen_to_group(float center_x, float center_y, MAPITEM_GROUP *group) +void CHud::MapscreenToGroup(float CenterX, float CenterY, CMapItemGroup *pGroup) { - float points[4]; - RenderTools()->mapscreen_to_world(center_x, center_y, group->parallax_x/100.0f, group->parallax_y/100.0f, - group->offset_x, group->offset_y, Graphics()->ScreenAspect(), 1.0f, points); - Graphics()->MapScreen(points[0], points[1], points[2], points[3]); + float Points[4]; + RenderTools()->MapscreenToWorld(CenterX, CenterY, pGroup->m_ParallaxX/100.0f, pGroup->m_ParallaxY/100.0f, + pGroup->m_OffsetX, pGroup->m_OffsetY, Graphics()->ScreenAspect(), 1.0f, Points); + Graphics()->MapScreen(Points[0], Points[1], Points[2], Points[3]); } -void HUD::render_fps() +void CHud::RenderFps() { - if(config.cl_showfps) + if(g_Config.m_ClShowfps) { - char buf[512]; - str_format(buf, sizeof(buf), "%d", (int)(1.0f/client_frametime())); - gfx_text(0, width-10-gfx_text_width(0,12,buf,-1), 5, 12, buf, -1); + // calculate avg. fps + float FPS = 1.0f / Client()->FrameTime(); + m_AverageFPS = (m_AverageFPS*(1.0f-(1.0f/m_AverageFPS))) + (FPS*(1.0f/m_AverageFPS)); + char Buf[512]; + str_format(Buf, sizeof(Buf), "%d", (int)m_AverageFPS); + TextRender()->Text(0, m_Width-10-TextRender()->TextWidth(0,12,Buf,-1), 5, 12, Buf, -1); } } -void HUD::render_connectionwarning() +void CHud::RenderConnectionWarning() { - if(client_connection_problems()) + if(Client()->ConnectionProblems()) { - const char *text = "Connection Problems..."; - float w = gfx_text_width(0, 24, text, -1); - gfx_text(0, 150*Graphics()->ScreenAspect()-w/2, 50, 24, text, -1); + const char *pText = "Connection Problems..."; + float w = TextRender()->TextWidth(0, 24, pText, -1); + TextRender()->Text(0, 150*Graphics()->ScreenAspect()-w/2, 50, 24, pText, -1); } } -void HUD::render_teambalancewarning() +void CHud::RenderTeambalanceWarning() { // render prompt about team-balance - bool flash = time_get()/(time_freq()/2)%2 == 0; - if (gameclient.snap.gameobj && (gameclient.snap.gameobj->flags&GAMEFLAG_TEAMS) != 0) + bool Flash = time_get()/(time_freq()/2)%2 == 0; + if (m_pClient->m_Snap.m_pGameobj && (m_pClient->m_Snap.m_pGameobj->m_Flags&GAMEFLAG_TEAMS) != 0) { - if (config.cl_warning_teambalance && abs(gameclient.snap.team_size[0]-gameclient.snap.team_size[1]) >= 2) + int TeamDiff = m_pClient->m_Snap.m_aTeamSize[0]-m_pClient->m_Snap.m_aTeamSize[1]; + if (g_Config.m_ClWarningTeambalance && (TeamDiff >= 2 || TeamDiff <= -2)) { - const char *text = "Please balance teams!"; - if(flash) - gfx_text_color(1,1,0.5f,1); + const char *pText = "Please balance teams!"; + if(Flash) + TextRender()->TextColor(1,1,0.5f,1); else - gfx_text_color(0.7f,0.7f,0.2f,1.0f); - gfx_text(0x0, 5, 50, 6, text, -1); - gfx_text_color(1,1,1,1); + TextRender()->TextColor(0.7f,0.7f,0.2f,1.0f); + TextRender()->Text(0x0, 5, 50, 6, pText, -1); + TextRender()->TextColor(1,1,1,1); } } } -void HUD::render_voting() +void CHud::RenderVoting() { - if(!gameclient.voting->is_voting()) + if(!m_pClient->m_pVoting->IsVoting()) return; Graphics()->TextureSet(-1); Graphics()->QuadsBegin(); Graphics()->SetColor(0,0,0,0.40f); - RenderTools()->draw_round_rect(-10, 60-2, 100+10+4+5, 28, 5.0f); + RenderTools()->DrawRoundRect(-10, 60-2, 100+10+4+5, 28, 5.0f); Graphics()->QuadsEnd(); - gfx_text_color(1,1,1,1); + TextRender()->TextColor(1,1,1,1); - char buf[512]; - gfx_text(0x0, 5, 60, 6, gameclient.voting->vote_description(), -1); + char Buf[512]; + TextRender()->Text(0x0, 5, 60, 6, m_pClient->m_pVoting->VoteDescription(), -1); - str_format(buf, sizeof(buf), "%ds left", gameclient.voting->seconds_left()); - float tw = gfx_text_width(0x0, 6, buf, -1); - gfx_text(0x0, 5+100-tw, 60, 6, buf, -1); + str_format(Buf, sizeof(Buf), "%ds left", m_pClient->m_pVoting->SecondsLeft()); + float tw = TextRender()->TextWidth(0x0, 6, Buf, -1); + TextRender()->Text(0x0, 5+100-tw, 60, 6, Buf, -1); - CUIRect base = {5, 70, 100, 4}; - gameclient.voting->render_bars(base, false); + CUIRect Base = {5, 70, 100, 4}; + m_pClient->m_pVoting->RenderBars(Base, false); - const char *yes_key = gameclient.binds->get_key("vote yes"); - const char *no_key = gameclient.binds->get_key("vote no"); - str_format(buf, sizeof(buf), "%s - Vote Yes", yes_key); - base.y += base.h+1; - UI()->DoLabel(&base, buf, 6.0f, -1); - - str_format(buf, sizeof(buf), "Vote No - %s", no_key); - UI()->DoLabel(&base, buf, 6.0f, 1); + const char *pYesKey = m_pClient->m_pBinds->GetKey("vote yes"); + const char *pNoKey = m_pClient->m_pBinds->GetKey("vote no"); + str_format(Buf, sizeof(Buf), "%s - Vote Yes", pYesKey); + Base.y += Base.h+1; + UI()->DoLabel(&Base, Buf, 6.0f, -1); + + str_format(Buf, sizeof(Buf), "Vote No - %s", pNoKey); + UI()->DoLabel(&Base, Buf, 6.0f, 1); } -void HUD::render_cursor() +void CHud::RenderCursor() { - if(!gameclient.snap.local_character) + if(!m_pClient->m_Snap.m_pLocalCharacter) return; - mapscreen_to_group(gameclient.camera->center.x, gameclient.camera->center.y, layers_game_group()); - Graphics()->TextureSet(data->images[IMAGE_GAME].id); + MapscreenToGroup(m_pClient->m_pCamera->m_Center.x, m_pClient->m_pCamera->m_Center.y, Layers()->GameGroup()); + Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id); Graphics()->QuadsBegin(); // render cursor - RenderTools()->select_sprite(data->weapons.id[gameclient.snap.local_character->weapon%NUM_WEAPONS].sprite_cursor); - float cursorsize = 64; - RenderTools()->draw_sprite(gameclient.controls->target_pos.x, gameclient.controls->target_pos.y, cursorsize); + RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[m_pClient->m_Snap.m_pLocalCharacter->m_Weapon%NUM_WEAPONS].m_pSpriteCursor); + float CursorSize = 64; + RenderTools()->DrawSprite(m_pClient->m_pControls->m_TargetPos.x, m_pClient->m_pControls->m_TargetPos.y, CursorSize); Graphics()->QuadsEnd(); } -void HUD::render_healthandammo() +void CHud::RenderHealthAndAmmo() { //mapscreen_to_group(gacenter_x, center_y, layers_game_group()); @@ -248,61 +252,69 @@ void HUD::render_healthandammo() // render ammo count // render gui stuff - Graphics()->TextureSet(data->images[IMAGE_GAME].id); - Graphics()->MapScreen(0,0,width,300); + Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id); + Graphics()->MapScreen(0,0,m_Width,300); Graphics()->QuadsBegin(); // if weaponstage is active, put a "glow" around the stage ammo - RenderTools()->select_sprite(data->weapons.id[gameclient.snap.local_character->weapon%NUM_WEAPONS].sprite_proj); - for (int i = 0; i < min(gameclient.snap.local_character->ammocount, 10); i++) - Graphics()->QuadsDrawTL(x+i*12,y+24,10,10); - + RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[m_pClient->m_Snap.m_pLocalCharacter->m_Weapon%NUM_WEAPONS].m_pSpriteProj); + IGraphics::CQuadItem Array[10]; + int i; + for (i = 0; i < min(m_pClient->m_Snap.m_pLocalCharacter->m_AmmoCount, 10); i++) + Array[i] = IGraphics::CQuadItem(x+i*12,y+24,10,10); + Graphics()->QuadsDrawTL(Array, i); Graphics()->QuadsEnd(); Graphics()->QuadsBegin(); int h = 0; // render health - RenderTools()->select_sprite(SPRITE_HEALTH_FULL); - for(; h < gameclient.snap.local_character->health; h++) - Graphics()->QuadsDrawTL(x+h*12,y,10,10); + RenderTools()->SelectSprite(SPRITE_HEALTH_FULL); + for(; h < min(m_pClient->m_Snap.m_pLocalCharacter->m_Health, 10); h++) + Array[h] = IGraphics::CQuadItem(x+h*12,y,10,10); + Graphics()->QuadsDrawTL(Array, h); - RenderTools()->select_sprite(SPRITE_HEALTH_EMPTY); + i = 0; + RenderTools()->SelectSprite(SPRITE_HEALTH_EMPTY); for(; h < 10; h++) - Graphics()->QuadsDrawTL(x+h*12,y,10,10); + Array[i++] = IGraphics::CQuadItem(x+h*12,y,10,10); + Graphics()->QuadsDrawTL(Array, i); // render armor meter h = 0; - RenderTools()->select_sprite(SPRITE_ARMOR_FULL); - for(; h < gameclient.snap.local_character->armor; h++) - Graphics()->QuadsDrawTL(x+h*12,y+12,10,10); + RenderTools()->SelectSprite(SPRITE_ARMOR_FULL); + for(; h < min(m_pClient->m_Snap.m_pLocalCharacter->m_Armor, 10); h++) + Array[h] = IGraphics::CQuadItem(x+h*12,y+12,10,10); + Graphics()->QuadsDrawTL(Array, h); - RenderTools()->select_sprite(SPRITE_ARMOR_EMPTY); + i = 0; + RenderTools()->SelectSprite(SPRITE_ARMOR_EMPTY); for(; h < 10; h++) - Graphics()->QuadsDrawTL(x+h*12,y+12,10,10); + Array[i++] = IGraphics::CQuadItem(x+h*12,y+12,10,10); + Graphics()->QuadsDrawTL(Array, i); Graphics()->QuadsEnd(); } -void HUD::on_render() +void CHud::OnRender() { - if(!gameclient.snap.gameobj) + if(!m_pClient->m_Snap.m_pGameobj) return; - width = 300*Graphics()->ScreenAspect(); + m_Width = 300*Graphics()->ScreenAspect(); - bool spectate = false; - if(gameclient.snap.local_info && gameclient.snap.local_info->team == -1) - spectate = true; + bool Spectate = false; + if(m_pClient->m_Snap.m_pLocalInfo && m_pClient->m_Snap.m_pLocalInfo->m_Team == -1) + Spectate = true; - if(gameclient.snap.local_character && !spectate && !(gameclient.snap.gameobj && gameclient.snap.gameobj->game_over)) - render_healthandammo(); - - render_goals(); - render_fps(); - if(client_state() != CLIENTSTATE_DEMOPLAYBACK) - render_connectionwarning(); - render_teambalancewarning(); - render_voting(); - render_cursor(); + if(m_pClient->m_Snap.m_pLocalCharacter && !Spectate && !(m_pClient->m_Snap.m_pGameobj && m_pClient->m_Snap.m_pGameobj->m_GameOver)) + RenderHealthAndAmmo(); + + RenderGoals(); + RenderFps(); + if(Client()->State() != IClient::STATE_DEMOPLAYBACK) + RenderConnectionWarning(); + RenderTeambalanceWarning(); + RenderVoting(); + RenderCursor(); } diff --git a/src/game/client/components/hud.h b/src/game/client/components/hud.h new file mode 100644 index 00000000..43f0e3a8 --- /dev/null +++ b/src/game/client/components/hud.h @@ -0,0 +1,27 @@ +#ifndef GAME_CLIENT_COMPONENTS_HUD_H +#define GAME_CLIENT_COMPONENTS_HUD_H +#include <game/client/component.h> + +class CHud : public CComponent +{ + float m_Width; + float m_AverageFPS; + + void RenderCursor(); + + void RenderFps(); + void RenderConnectionWarning(); + void RenderTeambalanceWarning(); + void RenderVoting(); + void RenderHealthAndAmmo(); + void RenderGoals(); + + void MapscreenToGroup(float CenterX, float CenterY, struct CMapItemGroup *PGroup); +public: + CHud(); + + virtual void OnReset(); + virtual void OnRender(); +}; + +#endif diff --git a/src/game/client/components/hud.hpp b/src/game/client/components/hud.hpp deleted file mode 100644 index 92ff0122..00000000 --- a/src/game/client/components/hud.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#include <game/client/component.hpp> - -class HUD : public COMPONENT -{ - float width; - - void render_cursor(); - - void render_fps(); - void render_connectionwarning(); - void render_teambalancewarning(); - void render_voting(); - void render_healthandammo(); - void render_goals(); - - - void mapscreen_to_group(float center_x, float center_y, struct MAPITEM_GROUP *group); -public: - HUD(); - - virtual void on_reset(); - virtual void on_render(); -}; - diff --git a/src/game/client/components/items.cpp b/src/game/client/components/items.cpp index 3c9e1b79..70479e53 100644 --- a/src/game/client/components/items.cpp +++ b/src/game/client/components/items.cpp @@ -1,94 +1,94 @@ -#include <engine/e_client_interface.h> -#include <engine/client/graphics.h> -#include <game/generated/g_protocol.hpp> -#include <game/generated/gc_data.hpp> +#include <engine/graphics.h> +#include <game/generated/protocol.h> +#include <game/generated/client_data.h> -#include <game/gamecore.hpp> // get_angle -#include <game/client/gameclient.hpp> -#include <game/client/ui.hpp> -#include <game/client/render.hpp> +#include <game/gamecore.h> // get_angle +#include <game/client/gameclient.h> +#include <game/client/ui.h> +#include <game/client/render.h> -#include <game/client/components/flow.hpp> -#include <game/client/components/effects.hpp> +#include <game/client/components/flow.h> +#include <game/client/components/effects.h> -#include "items.hpp" +#include "items.h" -void ITEMS::render_projectile(const NETOBJ_PROJECTILE *current, int itemid) +void CItems::RenderProjectile(const CNetObj_Projectile *pCurrent, int ItemId) { // get positions - float curvature = 0; - float speed = 0; - if(current->type == WEAPON_GRENADE) + float Curvature = 0; + float Speed = 0; + if(pCurrent->m_Type == WEAPON_GRENADE) { - curvature = gameclient.tuning.grenade_curvature; - speed = gameclient.tuning.grenade_speed; + Curvature = m_pClient->m_Tuning.m_GrenadeCurvature; + Speed = m_pClient->m_Tuning.m_GrenadeSpeed; } - else if(current->type == WEAPON_SHOTGUN) + else if(pCurrent->m_Type == WEAPON_SHOTGUN) { - curvature = gameclient.tuning.shotgun_curvature; - speed = gameclient.tuning.shotgun_speed; + Curvature = m_pClient->m_Tuning.m_ShotgunCurvature; + Speed = m_pClient->m_Tuning.m_ShotgunSpeed; } - else if(current->type == WEAPON_GUN) + else if(pCurrent->m_Type == WEAPON_GUN) { - curvature = gameclient.tuning.gun_curvature; - speed = gameclient.tuning.gun_speed; + Curvature = m_pClient->m_Tuning.m_GunCurvature; + Speed = m_pClient->m_Tuning.m_GunSpeed; } - float ct = (client_prevtick()-current->start_tick)/(float)SERVER_TICK_SPEED + client_ticktime(); - if(ct < 0) + float Ct = (Client()->PrevGameTick()-pCurrent->m_StartTick)/(float)SERVER_TICK_SPEED + Client()->GameTickTime(); + if(Ct < 0) return; // projectile havn't been shot yet - vec2 startpos(current->x, current->y); - vec2 startvel(current->vx/100.0f, current->vy/100.0f); - vec2 pos = calc_pos(startpos, startvel, curvature, speed, ct); - vec2 prevpos = calc_pos(startpos, startvel, curvature, speed, ct-0.001f); + vec2 StartPos(pCurrent->m_X, pCurrent->m_Y); + vec2 StartVel(pCurrent->m_VelX/100.0f, pCurrent->m_VelY/100.0f); + vec2 Pos = CalcPos(StartPos, StartVel, Curvature, Speed, Ct); + vec2 PrevPos = CalcPos(StartPos, StartVel, Curvature, Speed, Ct-0.001f); - Graphics()->TextureSet(data->images[IMAGE_GAME].id); + Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id); Graphics()->QuadsBegin(); - RenderTools()->select_sprite(data->weapons.id[clamp(current->type, 0, NUM_WEAPONS-1)].sprite_proj); - vec2 vel = pos-prevpos; - //vec2 pos = mix(vec2(prev->x, prev->y), vec2(current->x, current->y), client_intratick()); + RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[clamp(pCurrent->m_Type, 0, NUM_WEAPONS-1)].m_pSpriteProj); + vec2 Vel = Pos-PrevPos; + //vec2 pos = mix(vec2(prev->x, prev->y), vec2(current->x, current->y), Client()->IntraGameTick()); // add particle for this projectile - if(current->type == WEAPON_GRENADE) + if(pCurrent->m_Type == WEAPON_GRENADE) { - gameclient.effects->smoketrail(pos, vel*-1); - gameclient.flow->add(pos, vel*1000*client_frametime(), 10.0f); - Graphics()->QuadsSetRotation(client_localtime()*pi*2*2 + itemid); + m_pClient->m_pEffects->SmokeTrail(Pos, Vel*-1); + m_pClient->m_pFlow->Add(Pos, Vel*1000*Client()->FrameTime(), 10.0f); + Graphics()->QuadsSetRotation(Client()->LocalTime()*pi*2*2 + ItemId); } else { - gameclient.effects->bullettrail(pos); - gameclient.flow->add(pos, vel*1000*client_frametime(), 10.0f); + m_pClient->m_pEffects->BulletTrail(Pos); + m_pClient->m_pFlow->Add(Pos, Vel*1000*Client()->FrameTime(), 10.0f); - if(length(vel) > 0.00001f) - Graphics()->QuadsSetRotation(get_angle(vel)); + if(length(Vel) > 0.00001f) + Graphics()->QuadsSetRotation(GetAngle(Vel)); else Graphics()->QuadsSetRotation(0); } - Graphics()->QuadsDraw(pos.x, pos.y, 32, 32); + IGraphics::CQuadItem QuadItem(Pos.x, Pos.y, 32, 32); + Graphics()->QuadsDraw(&QuadItem, 1); Graphics()->QuadsSetRotation(0); Graphics()->QuadsEnd(); } -void ITEMS::render_pickup(const NETOBJ_PICKUP *prev, const NETOBJ_PICKUP *current) +void CItems::RenderPickup(const CNetObj_Pickup *pPrev, const CNetObj_Pickup *pCurrent) { - Graphics()->TextureSet(data->images[IMAGE_GAME].id); + Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id); Graphics()->QuadsBegin(); - vec2 pos = mix(vec2(prev->x, prev->y), vec2(current->x, current->y), client_intratick()); - float angle = 0.0f; - float size = 64.0f; - if (current->type == POWERUP_WEAPON) + vec2 Pos = mix(vec2(pPrev->m_X, pPrev->m_Y), vec2(pCurrent->m_X, pCurrent->m_Y), Client()->IntraGameTick()); + float Angle = 0.0f; + float Size = 64.0f; + if (pCurrent->m_Type == POWERUP_WEAPON) { - angle = 0; //-pi/6;//-0.25f * pi * 2.0f; - RenderTools()->select_sprite(data->weapons.id[clamp(current->subtype, 0, NUM_WEAPONS-1)].sprite_body); - size = data->weapons.id[clamp(current->subtype, 0, NUM_WEAPONS-1)].visual_size; + Angle = 0; //-pi/6;//-0.25f * pi * 2.0f; + RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[clamp(pCurrent->m_Subtype, 0, NUM_WEAPONS-1)].m_pSpriteBody); + Size = g_pData->m_Weapons.m_aId[clamp(pCurrent->m_Subtype, 0, NUM_WEAPONS-1)].m_VisualSize; } else { @@ -98,69 +98,70 @@ void ITEMS::render_pickup(const NETOBJ_PICKUP *prev, const NETOBJ_PICKUP *curren SPRITE_PICKUP_WEAPON, SPRITE_PICKUP_NINJA }; - RenderTools()->select_sprite(c[current->type]); + RenderTools()->SelectSprite(c[pCurrent->m_Type]); - if(c[current->type] == SPRITE_PICKUP_NINJA) + if(c[pCurrent->m_Type] == SPRITE_PICKUP_NINJA) { - gameclient.effects->powerupshine(pos, vec2(96,18)); - size *= 2.0f; - pos.x += 10.0f; + m_pClient->m_pEffects->PowerupShine(Pos, vec2(96,18)); + Size *= 2.0f; + Pos.x += 10.0f; } } - Graphics()->QuadsSetRotation(angle); + Graphics()->QuadsSetRotation(Angle); - float offset = pos.y/32.0f + pos.x/32.0f; - pos.x += cosf(client_localtime()*2.0f+offset)*2.5f; - pos.y += sinf(client_localtime()*2.0f+offset)*2.5f; - RenderTools()->draw_sprite(pos.x, pos.y, size); + float Offset = Pos.y/32.0f + Pos.x/32.0f; + Pos.x += cosf(Client()->LocalTime()*2.0f+Offset)*2.5f; + Pos.y += sinf(Client()->LocalTime()*2.0f+Offset)*2.5f; + RenderTools()->DrawSprite(Pos.x, Pos.y, Size); Graphics()->QuadsEnd(); } -void ITEMS::render_flag(const NETOBJ_FLAG *prev, const NETOBJ_FLAG *current) +void CItems::RenderFlag(const CNetObj_Flag *pPrev, const CNetObj_Flag *pCurrent) { - float angle = 0.0f; - float size = 42.0f; + float Angle = 0.0f; + float Size = 42.0f; Graphics()->BlendNormal(); - Graphics()->TextureSet(data->images[IMAGE_GAME].id); + Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id); Graphics()->QuadsBegin(); - if(current->team == 0) // red team - RenderTools()->select_sprite(SPRITE_FLAG_RED); + if(pCurrent->m_Team == 0) // red team + RenderTools()->SelectSprite(SPRITE_FLAG_RED); else - RenderTools()->select_sprite(SPRITE_FLAG_BLUE); + RenderTools()->SelectSprite(SPRITE_FLAG_BLUE); - Graphics()->QuadsSetRotation(angle); + Graphics()->QuadsSetRotation(Angle); - vec2 pos = mix(vec2(prev->x, prev->y), vec2(current->x, current->y), client_intratick()); + vec2 Pos = mix(vec2(pPrev->m_X, pPrev->m_Y), vec2(pCurrent->m_X, pCurrent->m_Y), Client()->IntraGameTick()); // make sure that the flag isn't interpolated between capture and return - if(prev->carried_by != current->carried_by) - pos = vec2(current->x, current->y); + if(pPrev->m_CarriedBy != pCurrent->m_CarriedBy) + Pos = vec2(pCurrent->m_X, pCurrent->m_Y); // make sure to use predicted position if we are the carrier - if(gameclient.snap.local_info && current->carried_by == gameclient.snap.local_info->cid) - pos = gameclient.local_character_pos; + if(m_pClient->m_Snap.m_pLocalInfo && pCurrent->m_CarriedBy == m_pClient->m_Snap.m_pLocalInfo->m_ClientId) + Pos = m_pClient->m_LocalCharacterPos; - Graphics()->QuadsDraw(pos.x, pos.y-size*0.75f, size, size*2); + IGraphics::CQuadItem QuadItem(Pos.x, Pos.y-Size*0.75f, Size, Size*2); + Graphics()->QuadsDraw(&QuadItem, 1); Graphics()->QuadsEnd(); } -void ITEMS::render_laser(const struct NETOBJ_LASER *current) +void CItems::RenderLaser(const struct CNetObj_Laser *pCurrent) { - vec2 pos = vec2(current->x, current->y); - vec2 from = vec2(current->from_x, current->from_y); - vec2 dir = normalize(pos-from); + vec2 Pos = vec2(pCurrent->m_X, pCurrent->m_Y); + vec2 From = vec2(pCurrent->m_FromX, pCurrent->m_FromY); + vec2 Dir = normalize(Pos-From); - float ticks = client_tick() + client_intratick() - current->start_tick; - float ms = (ticks/50.0f) * 1000.0f; - float a = ms / gameclient.tuning.laser_bounce_delay; + float Ticks = Client()->GameTick() + Client()->IntraGameTick() - pCurrent->m_StartTick; + float Ms = (Ticks/50.0f) * 1000.0f; + float a = Ms / m_pClient->m_Tuning.m_LaserBounceDelay; a = clamp(a, 0.0f, 1.0f); - float ia = 1-a; + float Ia = 1-a; - vec2 out, border; + vec2 Out, Border; Graphics()->BlendNormal(); Graphics()->TextureSet(-1); @@ -170,77 +171,87 @@ void ITEMS::render_laser(const struct NETOBJ_LASER *current) //vec4 outer_color(0.65f,0.85f,1.0f,1.0f); // do outline - vec4 outer_color(0.075f,0.075f,0.25f,1.0f); - Graphics()->SetColor(outer_color.r,outer_color.g,outer_color.b,1.0f); - out = vec2(dir.y, -dir.x) * (7.0f*ia); + vec4 OuterColor(0.075f, 0.075f, 0.25f, 1.0f); + Graphics()->SetColor(OuterColor.r, OuterColor.g, OuterColor.b, 1.0f); + Out = vec2(Dir.y, -Dir.x) * (7.0f*Ia); - Graphics()->QuadsDrawFreeform( - 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 - ); + 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); // do inner - vec4 inner_color(0.5f,0.5f,1.0f,1.0f); - out = vec2(dir.y, -dir.x) * (5.0f*ia); - Graphics()->SetColor(inner_color.r, inner_color.g, inner_color.b, 1.0f); // center + vec4 InnerColor(0.5f, 0.5f, 1.0f, 1.0f); + Out = vec2(Dir.y, -Dir.x) * (5.0f*Ia); + Graphics()->SetColor(InnerColor.r, InnerColor.g, InnerColor.b, 1.0f); // center - Graphics()->QuadsDrawFreeform( - 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 - ); + 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(); // render head { Graphics()->BlendNormal(); - Graphics()->TextureSet(data->images[IMAGE_PARTICLES].id); + Graphics()->TextureSet(g_pData->m_aImages[IMAGE_PARTICLES].m_Id); Graphics()->QuadsBegin(); - int sprites[] = {SPRITE_PART_SPLAT01, SPRITE_PART_SPLAT02, SPRITE_PART_SPLAT03}; - RenderTools()->select_sprite(sprites[client_tick()%3]); - Graphics()->QuadsSetRotation(client_tick()); - Graphics()->SetColor(outer_color.r,outer_color.g,outer_color.b,1.0f); - Graphics()->QuadsDraw(pos.x, pos.y, 24,24); - Graphics()->SetColor(inner_color.r, inner_color.g, inner_color.b, 1.0f); - Graphics()->QuadsDraw(pos.x, pos.y, 20,20); + int Sprites[] = {SPRITE_PART_SPLAT01, SPRITE_PART_SPLAT02, SPRITE_PART_SPLAT03}; + RenderTools()->SelectSprite(Sprites[Client()->GameTick()%3]); + Graphics()->QuadsSetRotation(Client()->GameTick()); + 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(); } Graphics()->BlendNormal(); } -void ITEMS::on_render() +void CItems::OnRender() { - int num = snap_num_items(SNAP_CURRENT); - for(int i = 0; i < num; i++) + int Num = Client()->SnapNumItems(IClient::SNAP_CURRENT); + for(int i = 0; i < Num; i++) { - SNAP_ITEM item; - const void *data = snap_get_item(SNAP_CURRENT, i, &item); + IClient::CSnapItem Item; + const void *pData = Client()->SnapGetItem(IClient::SNAP_CURRENT, i, &Item); - if(item.type == NETOBJTYPE_PROJECTILE) + if(Item.m_Type == NETOBJTYPE_PROJECTILE) { - render_projectile((const NETOBJ_PROJECTILE *)data, item.id); + RenderProjectile((const CNetObj_Projectile *)pData, Item.m_Id); } - else if(item.type == NETOBJTYPE_PICKUP) + else if(Item.m_Type == NETOBJTYPE_PICKUP) { - const void *prev = snap_find_item(SNAP_PREV, item.type, item.id); - if(prev) - render_pickup((const NETOBJ_PICKUP *)prev, (const NETOBJ_PICKUP *)data); + const void *pPrev = Client()->SnapFindItem(IClient::SNAP_PREV, Item.m_Type, Item.m_Id); + if(pPrev) + RenderPickup((const CNetObj_Pickup *)pPrev, (const CNetObj_Pickup *)pData); } - else if(item.type == NETOBJTYPE_LASER) + else if(Item.m_Type == NETOBJTYPE_LASER) { - render_laser((const NETOBJ_LASER *)data); + RenderLaser((const CNetObj_Laser *)pData); } - else if(item.type == NETOBJTYPE_FLAG) + } + + // render flag + for(int i = 0; i < Num; i++) + { + IClient::CSnapItem Item; + const void *pData = Client()->SnapGetItem(IClient::SNAP_CURRENT, i, &Item); + + if(Item.m_Type == NETOBJTYPE_FLAG) { - const void *prev = snap_find_item(SNAP_PREV, item.type, item.id); - if (prev) - render_flag((const NETOBJ_FLAG *)prev, (const NETOBJ_FLAG *)data); + const void *pPrev = Client()->SnapFindItem(IClient::SNAP_PREV, Item.m_Type, Item.m_Id); + if (pPrev) + RenderFlag((const CNetObj_Flag *)pPrev, (const CNetObj_Flag *)pData); } } @@ -248,7 +259,7 @@ void ITEMS::on_render() /* for(int i = 0; i < extraproj_num; i++) { - if(extraproj_projectiles[i].start_tick < client_tick()) + if(extraproj_projectiles[i].start_tick < Client()->GameTick()) { extraproj_projectiles[i] = extraproj_projectiles[extraproj_num-1]; extraproj_num--; diff --git a/src/game/client/components/items.h b/src/game/client/components/items.h new file mode 100644 index 00000000..e4525546 --- /dev/null +++ b/src/game/client/components/items.h @@ -0,0 +1,16 @@ +#ifndef GAME_CLIENT_COMPONENTS_ITEMS_H +#define GAME_CLIENT_COMPONENTS_ITEMS_H +#include <game/client/component.h> + +class CItems : public CComponent +{ + void RenderProjectile(const CNetObj_Projectile *pCurrent, int ItemId); + void RenderPickup(const CNetObj_Pickup *pPrev, const CNetObj_Pickup *pCurrent); + void RenderFlag(const CNetObj_Flag *pPrev, const CNetObj_Flag *pCurrent); + void RenderLaser(const struct CNetObj_Laser *pCurrent); + +public: + virtual void OnRender(); +}; + +#endif diff --git a/src/game/client/components/items.hpp b/src/game/client/components/items.hpp deleted file mode 100644 index 2f33c8c4..00000000 --- a/src/game/client/components/items.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#include <game/client/component.hpp> - -class ITEMS : public COMPONENT -{ - void render_projectile(const NETOBJ_PROJECTILE *current, int itemid); - void render_pickup(const NETOBJ_PICKUP *prev, const NETOBJ_PICKUP *current); - void render_flag(const NETOBJ_FLAG *prev, const NETOBJ_FLAG *current); - void render_laser(const struct NETOBJ_LASER *current); - -public: - virtual void on_render(); -}; - diff --git a/src/game/client/components/killmessages.cpp b/src/game/client/components/killmessages.cpp index e6232b7d..d18dd965 100644 --- a/src/game/client/components/killmessages.cpp +++ b/src/game/client/components/killmessages.cpp @@ -1,127 +1,129 @@ -#include <engine/e_client_interface.h> -#include <engine/client/graphics.h> -#include <game/generated/g_protocol.hpp> -#include <game/generated/gc_data.hpp> +#include <engine/graphics.h> +#include <engine/textrender.h> +#include <game/generated/protocol.h> +#include <game/generated/client_data.h> -#include <game/client/gameclient.hpp> -#include <game/client/animstate.hpp> -#include "killmessages.hpp" +#include <game/client/gameclient.h> +#include <game/client/animstate.h> +#include "killmessages.h" -void KILLMESSAGES::on_reset() +void CKillMessages::OnReset() { - killmsg_current = 0; - for(int i = 0; i < killmsg_max; i++) - killmsgs[i].tick = -100000; + m_KillmsgCurrent = 0; + for(int i = 0; i < MAX_KILLMSGS; i++) + m_aKillmsgs[i].m_Tick = -100000; } -void KILLMESSAGES::on_message(int msgtype, void *rawmsg) +void CKillMessages::OnMessage(int MsgType, void *pRawMsg) { - if(msgtype == NETMSGTYPE_SV_KILLMSG) + if(MsgType == NETMSGTYPE_SV_KILLMSG) { - NETMSG_SV_KILLMSG *msg = (NETMSG_SV_KILLMSG *)rawmsg; + CNetMsg_Sv_KillMsg *pMsg = (CNetMsg_Sv_KillMsg *)pRawMsg; // unpack messages - KILLMSG kill; - kill.killer = msg->killer; - kill.victim = msg->victim; - kill.weapon = msg->weapon; - kill.mode_special = msg->mode_special; - kill.tick = client_tick(); + CKillMsg Kill; + Kill.m_Killer = pMsg->m_Killer; + Kill.m_Victim = pMsg->m_Victim; + Kill.m_Weapon = pMsg->m_Weapon; + Kill.m_ModeSpecial = pMsg->m_ModeSpecial; + Kill.m_Tick = Client()->GameTick(); // add the message - killmsg_current = (killmsg_current+1)%killmsg_max; - killmsgs[killmsg_current] = kill; + m_KillmsgCurrent = (m_KillmsgCurrent+1)%MAX_KILLMSGS; + m_aKillmsgs[m_KillmsgCurrent] = Kill; } } -void KILLMESSAGES::on_render() +void CKillMessages::OnRender() { - float width = 400*3.0f*Graphics()->ScreenAspect(); - float height = 400*3.0f; + float Width = 400*3.0f*Graphics()->ScreenAspect(); + float Height = 400*3.0f; - Graphics()->MapScreen(0, 0, width*1.5f, height*1.5f); - float startx = width*1.5f-10.0f; + Graphics()->MapScreen(0, 0, Width*1.5f, Height*1.5f); + float StartX = Width*1.5f-10.0f; float y = 20.0f; - for(int i = 0; i < killmsg_max; i++) + for(int i = 0; i < MAX_KILLMSGS; i++) { - int r = (killmsg_current+i+1)%killmsg_max; - if(client_tick() > killmsgs[r].tick+50*10) + int r = (m_KillmsgCurrent+i+1)%MAX_KILLMSGS; + if(Client()->GameTick() > m_aKillmsgs[r].m_Tick+50*10) continue; - float font_size = 36.0f; - float killername_w = gfx_text_width(0, font_size, gameclient.clients[killmsgs[r].killer].name, -1); - float victimname_w = gfx_text_width(0, font_size, gameclient.clients[killmsgs[r].victim].name, -1); + float FontSize = 36.0f; + float KillerNameW = TextRender()->TextWidth(0, FontSize, m_pClient->m_aClients[m_aKillmsgs[r].m_Killer].m_aName, -1); + float VictimNameW = TextRender()->TextWidth(0, FontSize, m_pClient->m_aClients[m_aKillmsgs[r].m_Victim].m_aName, -1); - float x = startx; + float x = StartX; // render victim name - x -= victimname_w; - gfx_text(0, x, y, font_size, gameclient.clients[killmsgs[r].victim].name, -1); + x -= VictimNameW; + TextRender()->Text(0, x, y, FontSize, m_pClient->m_aClients[m_aKillmsgs[r].m_Victim].m_aName, -1); // render victim tee x -= 24.0f; - if(gameclient.snap.gameobj && gameclient.snap.gameobj->flags&GAMEFLAG_FLAGS) + if(m_pClient->m_Snap.m_pGameobj && m_pClient->m_Snap.m_pGameobj->m_Flags&GAMEFLAG_FLAGS) { - if(killmsgs[r].mode_special&1) + if(m_aKillmsgs[r].m_ModeSpecial&1) { Graphics()->BlendNormal(); - Graphics()->TextureSet(data->images[IMAGE_GAME].id); + Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id); Graphics()->QuadsBegin(); - if(gameclient.clients[killmsgs[r].victim].team == 0) RenderTools()->select_sprite(SPRITE_FLAG_BLUE); - else RenderTools()->select_sprite(SPRITE_FLAG_RED); + if(m_pClient->m_aClients[m_aKillmsgs[r].m_Victim].m_Team == 0) RenderTools()->SelectSprite(SPRITE_FLAG_BLUE); + else RenderTools()->SelectSprite(SPRITE_FLAG_RED); - float size = 56.0f; - Graphics()->QuadsDrawTL(x, y-16, size/2, size); + float Size = 56.0f; + IGraphics::CQuadItem QuadItem(x, y-16, Size/2, Size); + Graphics()->QuadsDrawTL(&QuadItem, 1); Graphics()->QuadsEnd(); } } - RenderTools()->RenderTee(ANIMSTATE::get_idle(), &gameclient.clients[killmsgs[r].victim].render_info, EMOTE_PAIN, vec2(-1,0), vec2(x, y+28)); + RenderTools()->RenderTee(CAnimState::GetIdle(), &m_pClient->m_aClients[m_aKillmsgs[r].m_Victim].m_RenderInfo, EMOTE_PAIN, vec2(-1,0), vec2(x, y+28)); x -= 32.0f; // render weapon x -= 44.0f; - if (killmsgs[r].weapon >= 0) + if (m_aKillmsgs[r].m_Weapon >= 0) { - Graphics()->TextureSet(data->images[IMAGE_GAME].id); + Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id); Graphics()->QuadsBegin(); - RenderTools()->select_sprite(data->weapons.id[killmsgs[r].weapon].sprite_body); - RenderTools()->draw_sprite(x, y+28, 96); + RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[m_aKillmsgs[r].m_Weapon].m_pSpriteBody); + RenderTools()->DrawSprite(x, y+28, 96); Graphics()->QuadsEnd(); } x -= 52.0f; - if(killmsgs[r].victim != killmsgs[r].killer) + if(m_aKillmsgs[r].m_Victim != m_aKillmsgs[r].m_Killer) { - if(gameclient.snap.gameobj && gameclient.snap.gameobj->flags&GAMEFLAG_FLAGS) + if(m_pClient->m_Snap.m_pGameobj && m_pClient->m_Snap.m_pGameobj->m_Flags&GAMEFLAG_FLAGS) { - if(killmsgs[r].mode_special&2) + if(m_aKillmsgs[r].m_ModeSpecial&2) { Graphics()->BlendNormal(); - Graphics()->TextureSet(data->images[IMAGE_GAME].id); + Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id); Graphics()->QuadsBegin(); - if(gameclient.clients[killmsgs[r].killer].team == 0) RenderTools()->select_sprite(SPRITE_FLAG_BLUE, SPRITE_FLAG_FLIP_X); - else RenderTools()->select_sprite(SPRITE_FLAG_RED, SPRITE_FLAG_FLIP_X); + if(m_pClient->m_aClients[m_aKillmsgs[r].m_Killer].m_Team == 0) RenderTools()->SelectSprite(SPRITE_FLAG_BLUE, SPRITE_FLAG_FLIP_X); + else RenderTools()->SelectSprite(SPRITE_FLAG_RED, SPRITE_FLAG_FLIP_X); - float size = 56.0f; - Graphics()->QuadsDrawTL(x-56, y-16, size/2, size); + float Size = 56.0f; + IGraphics::CQuadItem QuadItem(x-56, y-16, Size/2, Size); + Graphics()->QuadsDrawTL(&QuadItem, 1); Graphics()->QuadsEnd(); } } // render killer tee x -= 24.0f; - RenderTools()->RenderTee(ANIMSTATE::get_idle(), &gameclient.clients[killmsgs[r].killer].render_info, EMOTE_ANGRY, vec2(1,0), vec2(x, y+28)); + RenderTools()->RenderTee(CAnimState::GetIdle(), &m_pClient->m_aClients[m_aKillmsgs[r].m_Killer].m_RenderInfo, EMOTE_ANGRY, vec2(1,0), vec2(x, y+28)); x -= 32.0f; // render killer name - x -= killername_w; - gfx_text(0, x, y, font_size, gameclient.clients[killmsgs[r].killer].name, -1); + x -= KillerNameW; + TextRender()->Text(0, x, y, FontSize, m_pClient->m_aClients[m_aKillmsgs[r].m_Killer].m_aName, -1); } y += 44; diff --git a/src/game/client/components/killmessages.h b/src/game/client/components/killmessages.h new file mode 100644 index 00000000..720b10ae --- /dev/null +++ b/src/game/client/components/killmessages.h @@ -0,0 +1,31 @@ +#ifndef GAME_CLIENT_COMPONENTS_KILLMESSAGES_H +#define GAME_CLIENT_COMPONENTS_KILLMESSAGES_H +#include <game/client/component.h> + +class CKillMessages : public CComponent +{ +public: + // kill messages + struct CKillMsg + { + int m_Weapon; + int m_Victim; + int m_Killer; + int m_ModeSpecial; // for CTF, if the guy is carrying a flag for example + int m_Tick; + }; + + enum + { + MAX_KILLMSGS = 5, + }; + + CKillMsg m_aKillmsgs[MAX_KILLMSGS]; + int m_KillmsgCurrent; + + virtual void OnReset(); + virtual void OnRender(); + virtual void OnMessage(int MsgType, void *pRawMsg); +}; + +#endif diff --git a/src/game/client/components/killmessages.hpp b/src/game/client/components/killmessages.hpp deleted file mode 100644 index f29e0bdf..00000000 --- a/src/game/client/components/killmessages.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#include <game/client/component.hpp> - -class KILLMESSAGES : public COMPONENT -{ -public: - // kill messages - struct KILLMSG - { - int weapon; - int victim; - int killer; - int mode_special; // for CTF, if the guy is carrying a flag for example - int tick; - }; - - static const int killmsg_max = 5; - KILLMSG killmsgs[killmsg_max]; - int killmsg_current; - - virtual void on_reset(); - virtual void on_render(); - virtual void on_message(int msgtype, void *rawmsg); -}; - diff --git a/src/game/client/components/mapimages.cpp b/src/game/client/components/mapimages.cpp index 51194853..9be450d1 100644 --- a/src/game/client/components/mapimages.cpp +++ b/src/game/client/components/mapimages.cpp @@ -1,45 +1,48 @@ -#include <engine/client/graphics.h> -#include <game/client/component.hpp> -#include <game/mapitems.hpp> +#include <engine/graphics.h> +#include <engine/map.h> +#include <game/client/component.h> +#include <game/mapitems.h> -#include "mapimages.hpp" +#include "mapimages.h" -MAPIMAGES::MAPIMAGES() +CMapImages::CMapImages() { - count = 0; + m_Count = 0; } -void MAPIMAGES::on_mapload() +void CMapImages::OnMapLoad() { + IMap *pMap = Kernel()->RequestInterface<IMap>(); + // unload all textures - for(int i = 0; i < count; i++) + for(int i = 0; i < m_Count; i++) { - Graphics()->UnloadTexture(textures[i]); - textures[i] = -1; + Graphics()->UnloadTexture(m_aTextures[i]); + m_aTextures[i] = -1; } - count = 0; + m_Count = 0; - int start; - map_get_type(MAPITEMTYPE_IMAGE, &start, &count); + int Start; + pMap->GetType(MAPITEMTYPE_IMAGE, &Start, &m_Count); // load new textures - for(int i = 0; i < count; i++) + for(int i = 0; i < m_Count; i++) { - textures[i] = 0; + m_aTextures[i] = 0; - MAPITEM_IMAGE *img = (MAPITEM_IMAGE *)map_get_item(start+i, 0, 0); - if(img->external) + CMapItemImage *pImg = (CMapItemImage *)pMap->GetItem(Start+i, 0, 0); + if(pImg->m_External) { - char buf[256]; - char *name = (char *)map_get_data(img->image_name); - str_format(buf, sizeof(buf), "mapres/%s.png", name); - textures[i] = Graphics()->LoadTexture(buf, IMG_AUTO, 0); + char Buf[256]; + char *pName = (char *)pMap->GetData(pImg->m_ImageName); + str_format(Buf, sizeof(Buf), "mapres/%s.png", pName); + m_aTextures[i] = Graphics()->LoadTexture(Buf, CImageInfo::FORMAT_AUTO, 0); } else { - void *data = map_get_data(img->image_data); - textures[i] = Graphics()->LoadTextureRaw(img->width, img->height, IMG_RGBA, data, IMG_RGBA, 0); - map_unload_data(img->image_data); + void *pData = pMap->GetData(pImg->m_ImageData); + m_aTextures[i] = Graphics()->LoadTextureRaw(pImg->m_Width, pImg->m_Height, CImageInfo::FORMAT_RGBA, pData, CImageInfo::FORMAT_RGBA, 0); + pMap->UnloadData(pImg->m_ImageData); } } } diff --git a/src/game/client/components/mapimages.h b/src/game/client/components/mapimages.h new file mode 100644 index 00000000..2ef5fc32 --- /dev/null +++ b/src/game/client/components/mapimages.h @@ -0,0 +1,18 @@ +#ifndef GAME_CLIENT_COMPONENTS_MAPIMAGES_H +#define GAME_CLIENT_COMPONENTS_MAPIMAGES_H +#include <game/client/component.h> + +class CMapImages : public CComponent +{ + int m_aTextures[64]; + int m_Count; +public: + CMapImages(); + + int Get(int Index) const { return m_aTextures[Index]; } + int Num() const { return m_Count; } + + virtual void OnMapLoad(); +}; + +#endif diff --git a/src/game/client/components/mapimages.hpp b/src/game/client/components/mapimages.hpp deleted file mode 100644 index cba46033..00000000 --- a/src/game/client/components/mapimages.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#include <game/client/component.hpp> - -class MAPIMAGES : public COMPONENT -{ - int textures[64]; - int count; -public: - MAPIMAGES(); - - int get(int index) const { return textures[index]; } - int num() const { return count; } - - virtual void on_mapload(); -}; - diff --git a/src/game/client/components/maplayers.cpp b/src/game/client/components/maplayers.cpp index 75f91521..202ea2da 100644 --- a/src/game/client/components/maplayers.cpp +++ b/src/game/client/components/maplayers.cpp @@ -1,167 +1,192 @@ -#include <engine/client/graphics.h> +#include <stdio.h> +#include <engine/graphics.h> +#include <engine/keys.h> //temp +#include <engine/shared/config.h> -#include <game/layers.hpp> -#include <game/client/gameclient.hpp> -#include <game/client/component.hpp> -#include <game/client/render.hpp> +#include <game/layers.h> +#include <game/client/gameclient.h> +#include <game/client/component.h> +#include <game/client/render.h> -#include <game/client/components/camera.hpp> -#include <game/client/components/mapimages.hpp> +#include <game/client/components/camera.h> +#include <game/client/components/mapimages.h> -#include "maplayers.hpp" +#include "maplayers.h" -MAPLAYERS::MAPLAYERS(int t) +CMapLayers::CMapLayers(int t) { - type = t; + m_Type = t; + m_pLayers = 0; } +void CMapLayers::OnInit() +{ + m_pLayers = Layers(); +} -void MAPLAYERS::mapscreen_to_group(float center_x, float center_y, MAPITEM_GROUP *group) + +void CMapLayers::MapScreenToGroup(float CenterX, float CenterY, CMapItemGroup *pGroup) { - float points[4]; - RenderTools()->mapscreen_to_world(center_x, center_y, group->parallax_x/100.0f, group->parallax_y/100.0f, - group->offset_x, group->offset_y, Graphics()->ScreenAspect(), 1.0f, points); - Graphics()->MapScreen(points[0], points[1], points[2], points[3]); + float Points[4]; + RenderTools()->MapscreenToWorld(CenterX, CenterY, pGroup->m_ParallaxX/100.0f, pGroup->m_ParallaxY/100.0f, + pGroup->m_OffsetX, pGroup->m_OffsetY, Graphics()->ScreenAspect(), 1.0f, Points); + Graphics()->MapScreen(Points[0], Points[1], Points[2], Points[3]); } -void MAPLAYERS::envelope_eval(float time_offset, int env, float *channels, void *user) +void CMapLayers::EnvelopeEval(float TimeOffset, int Env, float *pChannels, void *pUser) { - MAPLAYERS *pThis = (MAPLAYERS *)user; - channels[0] = 0; - channels[1] = 0; - channels[2] = 0; - channels[3] = 0; + CMapLayers *pThis = (CMapLayers *)pUser; + pChannels[0] = 0; + pChannels[1] = 0; + pChannels[2] = 0; + pChannels[3] = 0; - ENVPOINT *points; + CEnvPoint *pPoints; { - int start, num; - map_get_type(MAPITEMTYPE_ENVPOINTS, &start, &num); - if(num) - points = (ENVPOINT *)map_get_item(start, 0, 0); + int Start, Num; + pThis->m_pLayers->Map()->GetType(MAPITEMTYPE_ENVPOINTS, &Start, &Num); + if(Num) + pPoints = (CEnvPoint *)pThis->m_pLayers->Map()->GetItem(Start, 0, 0); } - int start, num; - map_get_type(MAPITEMTYPE_ENVELOPE, &start, &num); + int Start, Num; + pThis->m_pLayers->Map()->GetType(MAPITEMTYPE_ENVELOPE, &Start, &Num); - if(env >= num) + if(Env >= Num) return; - MAPITEM_ENVELOPE *item = (MAPITEM_ENVELOPE *)map_get_item(start+env, 0, 0); - pThis->RenderTools()->render_eval_envelope(points+item->start_point, item->num_points, 4, client_localtime()+time_offset, channels); + CMapItemEnvelope *pItem = (CMapItemEnvelope *)pThis->m_pLayers->Map()->GetItem(Start+Env, 0, 0); + pThis->RenderTools()->RenderEvalEnvelope(pPoints+pItem->m_StartPoint, pItem->m_NumPoints, 4, pThis->Client()->LocalTime()+TimeOffset, pChannels); } -void MAPLAYERS::on_render() +void CMapLayers::OnRender() { - if(client_state() != CLIENTSTATE_ONLINE && client_state() != CLIENTSTATE_DEMOPLAYBACK) + if(Client()->State() != IClient::STATE_ONLINE && Client()->State() != IClient::STATE_DEMOPLAYBACK) return; - CUIRect screen; - Graphics()->GetScreen(&screen.x, &screen.y, &screen.w, &screen.h); + CUIRect Screen; + Graphics()->GetScreen(&Screen.x, &Screen.y, &Screen.w, &Screen.h); - vec2 center = gameclient.camera->center; + vec2 Center = m_pClient->m_pCamera->m_Center; //float center_x = gameclient.camera->center.x; //float center_y = gameclient.camera->center.y; - bool passed_gamelayer = false; + bool PassedGameLayer = false; - for(int g = 0; g < layers_num_groups(); g++) + for(int g = 0; g < m_pLayers->NumGroups(); g++) { - MAPITEM_GROUP *group = layers_get_group(g); + CMapItemGroup *pGroup = m_pLayers->GetGroup(g); - if(!config.gfx_noclip && group->version >= 2 && group->use_clipping) + if(!g_Config.m_GfxNoclip && pGroup->m_Version >= 2 && pGroup->m_UseClipping) { // set clipping - float points[4]; - mapscreen_to_group(center.x, center.y, layers_game_group()); - Graphics()->GetScreen(&points[0], &points[1], &points[2], &points[3]); - float x0 = (group->clip_x - points[0]) / (points[2]-points[0]); - float y0 = (group->clip_y - points[1]) / (points[3]-points[1]); - float x1 = ((group->clip_x+group->clip_w) - points[0]) / (points[2]-points[0]); - float y1 = ((group->clip_y+group->clip_h) - points[1]) / (points[3]-points[1]); + float Points[4]; + MapScreenToGroup(Center.x, Center.y, m_pLayers->GameGroup()); + Graphics()->GetScreen(&Points[0], &Points[1], &Points[2], &Points[3]); + float x0 = (pGroup->m_ClipX - Points[0]) / (Points[2]-Points[0]); + float y0 = (pGroup->m_ClipY - Points[1]) / (Points[3]-Points[1]); + float x1 = ((pGroup->m_ClipX+pGroup->m_ClipW) - Points[0]) / (Points[2]-Points[0]); + float y1 = ((pGroup->m_ClipY+pGroup->m_ClipH) - Points[1]) / (Points[3]-Points[1]); Graphics()->ClipEnable((int)(x0*Graphics()->ScreenWidth()), (int)(y0*Graphics()->ScreenHeight()), (int)((x1-x0)*Graphics()->ScreenWidth()), (int)((y1-y0)*Graphics()->ScreenHeight())); } - mapscreen_to_group(center.x, center.y, group); + MapScreenToGroup(Center.x, Center.y, pGroup); - for(int l = 0; l < group->num_layers; l++) + for(int l = 0; l < pGroup->m_NumLayers; l++) { - MAPITEM_LAYER *layer = layers_get_layer(group->start_layer+l); - bool render = false; - bool is_game_layer = false; + CMapItemLayer *pLayer = m_pLayers->GetLayer(pGroup->m_StartLayer+l); + bool Render = false; + bool IsGameLayer = false; - if(layer == (MAPITEM_LAYER*)layers_game_layer()) + if(pLayer == (CMapItemLayer*)m_pLayers->GameLayer()) { - is_game_layer = true; - passed_gamelayer = 1; + IsGameLayer = true; + PassedGameLayer = 1; } // skip rendering if detail layers if not wanted - if(layer->flags&LAYERFLAG_DETAIL && !config.gfx_high_detail && !is_game_layer) + if(pLayer->m_Flags&LAYERFLAG_DETAIL && !g_Config.m_GfxHighDetail && !IsGameLayer) continue; - if(type == -1) - render = true; - else if(type == 0) + if(m_Type == -1) + Render = true; + else if(m_Type == 0) { - if(passed_gamelayer) + if(PassedGameLayer) return; - render = true; + Render = true; } else { - if(passed_gamelayer && !is_game_layer) - render = true; + if(PassedGameLayer && !IsGameLayer) + Render = true; } - if(render && !is_game_layer) + if(pLayer->m_Type == LAYERTYPE_TILES && Input()->KeyPressed(KEY_KP0)) + { + CMapItemLayerTilemap *pTMap = (CMapItemLayerTilemap *)pLayer; + CTile *pTiles = (CTile *)m_pLayers->Map()->GetData(pTMap->m_Data); + char buf[256]; + str_format(buf, sizeof(buf), "%d%d_%dx%d", g, l, pTMap->m_Width, pTMap->m_Height); + FILE *f = fopen(buf, "w"); + for(int y = 0; y < pTMap->m_Height; y++) + { + for(int x = 0; x < pTMap->m_Width; x++) + fprintf(f, "%d,", pTiles[y*pTMap->m_Width + x].m_Index); + fprintf(f, "\n"); + } + fclose(f); + } + + if(Render && !IsGameLayer) { //layershot_begin(); - if(layer->type == LAYERTYPE_TILES) + if(pLayer->m_Type == LAYERTYPE_TILES) { - MAPITEM_LAYER_TILEMAP *tmap = (MAPITEM_LAYER_TILEMAP *)layer; - if(tmap->image == -1) + CMapItemLayerTilemap *pTMap = (CMapItemLayerTilemap *)pLayer; + if(pTMap->m_Image == -1) Graphics()->TextureSet(-1); else - Graphics()->TextureSet(gameclient.mapimages->get(tmap->image)); + Graphics()->TextureSet(m_pClient->m_pMapimages->Get(pTMap->m_Image)); - TILE *tiles = (TILE *)map_get_data(tmap->data); + CTile *pTiles = (CTile *)m_pLayers->Map()->GetData(pTMap->m_Data); Graphics()->BlendNone(); - RenderTools()->render_tilemap(tiles, tmap->width, tmap->height, 32.0f, vec4(1,1,1,1), TILERENDERFLAG_EXTEND|LAYERRENDERFLAG_OPAQUE); + RenderTools()->RenderTilemap(pTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, vec4(1,1,1,1), TILERENDERFLAG_EXTEND|LAYERRENDERFLAG_OPAQUE); Graphics()->BlendNormal(); - RenderTools()->render_tilemap(tiles, tmap->width, tmap->height, 32.0f, vec4(1,1,1,1), TILERENDERFLAG_EXTEND|LAYERRENDERFLAG_TRANSPARENT); + RenderTools()->RenderTilemap(pTiles, pTMap->m_Width, pTMap->m_Height, 32.0f, vec4(1,1,1,1), TILERENDERFLAG_EXTEND|LAYERRENDERFLAG_TRANSPARENT); } - else if(layer->type == LAYERTYPE_QUADS) + else if(pLayer->m_Type == LAYERTYPE_QUADS) { - MAPITEM_LAYER_QUADS *qlayer = (MAPITEM_LAYER_QUADS *)layer; - if(qlayer->image == -1) + CMapItemLayerQuads *pQLayer = (CMapItemLayerQuads *)pLayer; + if(pQLayer->m_Image == -1) Graphics()->TextureSet(-1); else - Graphics()->TextureSet(gameclient.mapimages->get(qlayer->image)); + Graphics()->TextureSet(m_pClient->m_pMapimages->Get(pQLayer->m_Image)); - QUAD *quads = (QUAD *)map_get_data_swapped(qlayer->data); + CQuad *pQuads = (CQuad *)m_pLayers->Map()->GetDataSwapped(pQLayer->m_Data); Graphics()->BlendNone(); - RenderTools()->render_quads(quads, qlayer->num_quads, LAYERRENDERFLAG_OPAQUE, envelope_eval, this); + RenderTools()->RenderQuads(pQuads, pQLayer->m_NumQuads, LAYERRENDERFLAG_OPAQUE, EnvelopeEval, this); Graphics()->BlendNormal(); - RenderTools()->render_quads(quads, qlayer->num_quads, LAYERRENDERFLAG_TRANSPARENT, envelope_eval, this); + RenderTools()->RenderQuads(pQuads, pQLayer->m_NumQuads, LAYERRENDERFLAG_TRANSPARENT, EnvelopeEval, this); } //layershot_end(); } } - if(!config.gfx_noclip) + if(!g_Config.m_GfxNoclip) Graphics()->ClipDisable(); } - if(!config.gfx_noclip) + if(!g_Config.m_GfxNoclip) Graphics()->ClipDisable(); // reset the screen like it was before - Graphics()->MapScreen(screen.x, screen.y, screen.w, screen.h); + Graphics()->MapScreen(Screen.x, Screen.y, Screen.w, Screen.h); } diff --git a/src/game/client/components/maplayers.h b/src/game/client/components/maplayers.h new file mode 100644 index 00000000..9f70d9cb --- /dev/null +++ b/src/game/client/components/maplayers.h @@ -0,0 +1,24 @@ +#ifndef GAME_CLIENT_COMPONENTS_MAPLAYERS_H +#define GAME_CLIENT_COMPONENTS_MAPLAYERS_H +#include <game/client/component.h> + +class CMapLayers : public CComponent +{ + CLayers *m_pLayers; // todo refactor: maybe remove it and access it through client* + int m_Type; + + void MapScreenToGroup(float CenterX, float CenterY, CMapItemGroup *pGroup); + static void EnvelopeEval(float TimeOffset, int Env, float *pChannels, void *pUser); +public: + enum + { + TYPE_BACKGROUND=0, + TYPE_FOREGROUND, + }; + + CMapLayers(int Type); + virtual void OnInit(); + virtual void OnRender(); +}; + +#endif diff --git a/src/game/client/components/maplayers.hpp b/src/game/client/components/maplayers.hpp deleted file mode 100644 index c8b154b2..00000000 --- a/src/game/client/components/maplayers.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#include <game/client/component.hpp> - -class MAPLAYERS : public COMPONENT -{ - int type; - - void mapscreen_to_group(float center_x, float center_y, MAPITEM_GROUP *group); - static void envelope_eval(float time_offset, int env, float *channels, void *user); -public: - enum - { - TYPE_BACKGROUND=0, - TYPE_FOREGROUND, - }; - - MAPLAYERS(int type); - virtual void on_render(); -}; - diff --git a/src/game/client/components/menus.cpp b/src/game/client/components/menus.cpp index 5f1bbf42..76ee2e5e 100644 --- a/src/game/client/components/menus.cpp +++ b/src/game/client/components/menus.cpp @@ -1,45 +1,45 @@ -/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */ -#include <stdio.h> +// copyright (c) 2007 magnus auvinen, see licence.txt for more info #include <math.h> -#include <string.h> -#include <stdlib.h> #include <base/system.h> -#include <base/math.hpp> -#include <base/vmath.hpp> +#include <base/math.h> +#include <base/vmath.h> -#include "menus.hpp" -#include "skins.hpp" +#include "menus.h" +#include "skins.h" -#include <engine/e_client_interface.h> -#include <engine/client/graphics.h> +#include <engine/graphics.h> +#include <engine/textrender.h> +#include <engine/serverbrowser.h> +#include <engine/keys.h> +#include <engine/shared/config.h> -#include <game/version.hpp> -#include <game/generated/g_protocol.hpp> +#include <game/version.h> +#include <game/generated/protocol.h> -#include <game/generated/gc_data.hpp> -#include <game/client/gameclient.hpp> -#include <game/client/lineinput.hpp> -#include <game/localization.hpp> +#include <game/generated/client_data.h> +#include <game/client/gameclient.h> +#include <game/client/lineinput.h> +#include <game/localization.h> #include <mastersrv/mastersrv.h> -vec4 MENUS::gui_color; -vec4 MENUS::color_tabbar_inactive_outgame; -vec4 MENUS::color_tabbar_active_outgame; -vec4 MENUS::color_tabbar_inactive; -vec4 MENUS::color_tabbar_active; -vec4 MENUS::color_tabbar_inactive_ingame; -vec4 MENUS::color_tabbar_active_ingame; +vec4 CMenus::ms_GuiColor; +vec4 CMenus::ms_ColorTabbarInactiveOutgame; +vec4 CMenus::ms_ColorTabbarActiveOutgame; +vec4 CMenus::ms_ColorTabbarInactive; +vec4 CMenus::ms_ColorTabbarActive; +vec4 CMenus::ms_ColorTabbarInactiveIngame; +vec4 CMenus::ms_ColorTabbarActiveIngame; -float MENUS::button_height = 25.0f; -float MENUS::listheader_height = 17.0f; -float MENUS::fontmod_height = 0.8f; +float CMenus::ms_ButtonHeight = 25.0f; +float CMenus::ms_ListheaderHeight = 17.0f; +float CMenus::ms_FontmodHeight = 0.8f; -INPUT_EVENT MENUS::inputevents[MAX_INPUTEVENTS]; -int MENUS::num_inputevents; +IInput::CEvent CMenus::m_aInputEvents[MAX_INPUTEVENTS]; +int CMenus::m_NumInputEvents; -inline float hue_to_rgb(float v1, float v2, float h) +inline float HueToRgb(float v1, float v2, float h) { if(h < 0) h += 1; if(h > 1) h -= 1; @@ -49,53 +49,54 @@ inline float hue_to_rgb(float v1, float v2, float h) return v1; } -inline vec3 hsl_to_rgb(vec3 in) +inline vec3 HslToRgb(vec3 In) { float v1, v2; - vec3 out; + vec3 Out; - if(in.s == 0) + if(In.s == 0) { - out.r = in.l; - out.g = in.l; - out.b = in.l; + Out.r = In.l; + Out.g = In.l; + Out.b = In.l; } else { - if(in.l < 0.5f) - v2 = in.l * (1 + in.s); + if(In.l < 0.5f) + v2 = In.l * (1 + In.s); else - v2 = (in.l+in.s) - (in.s*in.l); + v2 = (In.l+In.s) - (In.s*In.l); - v1 = 2 * in.l - v2; + v1 = 2 * In.l - v2; - out.r = hue_to_rgb(v1, v2, in.h + (1.0f/3.0f)); - out.g = hue_to_rgb(v1, v2, in.h); - out.b = hue_to_rgb(v1, v2, in.h - (1.0f/3.0f)); + Out.r = HueToRgb(v1, v2, In.h + (1.0f/3.0f)); + Out.g = HueToRgb(v1, v2, In.h); + Out.b = HueToRgb(v1, v2, In.h - (1.0f/3.0f)); } - return out; + return Out; } -MENUS::MENUS() +CMenus::CMenus() { - popup = POPUP_NONE; - active_page = PAGE_INTERNET; - game_page = PAGE_GAME; + m_Popup = POPUP_NONE; + m_ActivePage = PAGE_INTERNET; + m_GamePage = PAGE_GAME; - need_restart = false; - need_sendinfo = false; - menu_active = true; + m_NeedRestart = false; + m_NeedSendinfo = false; + m_MenuActive = true; + m_UseMouseButtons = true; - escape_pressed = false; - enter_pressed = false; - num_inputevents = 0; + m_EscapePressed = false; + m_EnterPressed = false; + m_NumInputEvents = 0; - last_input = time_get(); + m_LastInput = time_get(); } -vec4 MENUS::button_color_mul(const void *pID) +vec4 CMenus::ButtonColorMul(const void *pID) { if(UI()->ActiveItem() == pID) return vec4(1,1,1,0.5f); @@ -104,69 +105,69 @@ vec4 MENUS::button_color_mul(const void *pID) return vec4(1,1,1,1); } -int MENUS::DoButton_BrowseIcon(int What, const CUIRect *pRect) +int CMenus::DoButton_BrowseIcon(int What, const CUIRect *pRect) { - Graphics()->TextureSet(data->images[IMAGE_BROWSEICONS].id); + Graphics()->TextureSet(g_pData->m_aImages[IMAGE_BROWSEICONS].m_Id); Graphics()->QuadsBegin(); - RenderTools()->select_sprite(What); - Graphics()->QuadsDrawTL(pRect->x, pRect->y, pRect->w, pRect->h); + RenderTools()->SelectSprite(What); + IGraphics::CQuadItem QuadItem(pRect->x, pRect->y, pRect->w, pRect->h); + Graphics()->QuadsDrawTL(&QuadItem, 1); Graphics()->QuadsEnd(); return 0; } -int MENUS::DoButton_Menu(const void *pID, const char *pText, int Checked, const CUIRect *pRect) +int CMenus::DoButton_Menu(const void *pID, const char *pText, int Checked, const CUIRect *pRect) { - RenderTools()->DrawUIRect(pRect, vec4(1,1,1,0.5f)*button_color_mul(pID), CUI::CORNER_ALL, 5.0f); - UI()->DoLabel(pRect, pText, pRect->h*fontmod_height, 0); + RenderTools()->DrawUIRect(pRect, vec4(1,1,1,0.5f)*ButtonColorMul(pID), CUI::CORNER_ALL, 5.0f); + UI()->DoLabel(pRect, pText, pRect->h*ms_FontmodHeight, 0); return UI()->DoButtonLogic(pID, pText, Checked, pRect); } -int MENUS::DoButton_KeySelect(const void *pID, const char *pText, int Checked, const CUIRect *pRect) +void CMenus::DoButton_KeySelect(const void *pID, const char *pText, int Checked, const CUIRect *pRect) { - RenderTools()->DrawUIRect(pRect, vec4(1,1,1,0.5f)*button_color_mul(pID), CUI::CORNER_ALL, 5.0f); - UI()->DoLabel(pRect, pText, pRect->h*fontmod_height, 0); - return UI()->DoButtonLogic(pID, pText, Checked, pRect); + RenderTools()->DrawUIRect(pRect, vec4(1,1,1,0.5f)*ButtonColorMul(pID), CUI::CORNER_ALL, 5.0f); + UI()->DoLabel(pRect, pText, pRect->h*ms_FontmodHeight, 0); } -int MENUS::DoButton_MenuTab(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Corners) +int CMenus::DoButton_MenuTab(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Corners) { vec4 ColorMod(1,1,1,1); if(Checked) - RenderTools()->DrawUIRect(pRect, color_tabbar_active, Corners, 10.0f); + RenderTools()->DrawUIRect(pRect, ms_ColorTabbarActive, Corners, 10.0f); else - RenderTools()->DrawUIRect(pRect, color_tabbar_inactive, Corners, 10.0f); - UI()->DoLabel(pRect, pText, pRect->h*fontmod_height, 0); + RenderTools()->DrawUIRect(pRect, ms_ColorTabbarInactive, Corners, 10.0f); + UI()->DoLabel(pRect, pText, pRect->h*ms_FontmodHeight, 0); return UI()->DoButtonLogic(pID, pText, Checked, pRect); } -int MENUS::DoButton_SettingsTab(const void *pID, const char *pText, int Checked, const CUIRect *pRect) +int CMenus::DoButton_SettingsTab(const void *pID, const char *pText, int Checked, const CUIRect *pRect) { if(Checked) - RenderTools()->DrawUIRect(pRect, color_tabbar_active, CUI::CORNER_R, 10.0f); + RenderTools()->DrawUIRect(pRect, ms_ColorTabbarActive, CUI::CORNER_R, 10.0f); else - RenderTools()->DrawUIRect(pRect, color_tabbar_inactive, CUI::CORNER_R, 10.0f); - UI()->DoLabel(pRect, pText, pRect->h*fontmod_height, 0); + RenderTools()->DrawUIRect(pRect, ms_ColorTabbarInactive, CUI::CORNER_R, 10.0f); + UI()->DoLabel(pRect, pText, pRect->h*ms_FontmodHeight, 0); return UI()->DoButtonLogic(pID, pText, Checked, pRect); } -int MENUS::DoButton_GridHeader(const void *pID, const char *pText, int Checked, const CUIRect *pRect) -//void MENUS::ui_draw_grid_header(const void *id, const char *text, int checked, const CUIRect *r, const void *extra) +int CMenus::DoButton_GridHeader(const void *pID, const char *pText, int Checked, const CUIRect *pRect) +//void CMenus::ui_draw_grid_header(const void *id, const char *text, int checked, const CUIRect *r, const void *extra) { if(Checked) RenderTools()->DrawUIRect(pRect, vec4(1,1,1,0.5f), CUI::CORNER_T, 5.0f); CUIRect t; pRect->VSplitLeft(5.0f, 0, &t); - UI()->DoLabel(&t, pText, pRect->h*fontmod_height, -1); + UI()->DoLabel(&t, pText, pRect->h*ms_FontmodHeight, -1); return UI()->DoButtonLogic(pID, pText, Checked, pRect); } -int MENUS::DoButton_ListRow(const void *pID, const char *pText, int Checked, const CUIRect *pRect) +int CMenus::DoButton_ListRow(const void *pID, const char *pText, int Checked, const CUIRect *pRect) { if(Checked) { @@ -174,12 +175,12 @@ int MENUS::DoButton_ListRow(const void *pID, const char *pText, int Checked, con sr.Margin(1.5f, &sr); RenderTools()->DrawUIRect(&sr, vec4(1,1,1,0.5f), CUI::CORNER_ALL, 4.0f); } - UI()->DoLabel(pRect, pText, pRect->h*fontmod_height, -1); + UI()->DoLabel(pRect, pText, pRect->h*ms_FontmodHeight, -1); return UI()->DoButtonLogic(pID, pText, Checked, pRect); } -int MENUS::DoButton_CheckBox_Common(const void *pID, const char *pText, const char *pBoxText, const CUIRect *pRect) -//void MENUS::ui_draw_checkbox_common(const void *id, const char *text, const char *boxtext, const CUIRect *r, const void *extra) +int CMenus::DoButton_CheckBox_Common(const void *pID, const char *pText, const char *pBoxText, const CUIRect *pRect) +//void CMenus::ui_draw_checkbox_common(const void *id, const char *text, const char *boxtext, const CUIRect *r, const void *extra) { CUIRect c = *pRect; CUIRect t = *pRect; @@ -189,57 +190,59 @@ int MENUS::DoButton_CheckBox_Common(const void *pID, const char *pText, const ch t.VSplitLeft(5.0f, 0, &t); c.Margin(2.0f, &c); - RenderTools()->DrawUIRect(&c, vec4(1,1,1,0.25f)*button_color_mul(pID), CUI::CORNER_ALL, 3.0f); + RenderTools()->DrawUIRect(&c, vec4(1,1,1,0.25f)*ButtonColorMul(pID), CUI::CORNER_ALL, 3.0f); c.y += 2; - UI()->DoLabel(&c, pBoxText, pRect->h*fontmod_height*0.6f, 0); - UI()->DoLabel(&t, pText, pRect->h*fontmod_height*0.8f, -1); + UI()->DoLabel(&c, pBoxText, pRect->h*ms_FontmodHeight*0.6f, 0); + UI()->DoLabel(&t, pText, pRect->h*ms_FontmodHeight*0.8f, -1); return UI()->DoButtonLogic(pID, pText, 0, pRect); } -int MENUS::DoButton_CheckBox(const void *pID, const char *pText, int Checked, const CUIRect *pRect) +int CMenus::DoButton_CheckBox(const void *pID, const char *pText, int Checked, const CUIRect *pRect) { return DoButton_CheckBox_Common(pID, pText, Checked?"X":"", pRect); } -int MENUS::DoButton_CheckBox_Number(const void *pID, const char *pText, int Checked, const CUIRect *pRect) +int CMenus::DoButton_CheckBox_Number(const void *pID, const char *pText, int Checked, const CUIRect *pRect) { - char buf[16]; - str_format(buf, sizeof(buf), "%d", Checked); - return DoButton_CheckBox_Common(pID, pText, buf, pRect); + char aBuf[16]; + str_format(aBuf, sizeof(aBuf), "%d", Checked); + return DoButton_CheckBox_Common(pID, pText, aBuf, pRect); } -int MENUS::DoEditBox(void *pID, const CUIRect *pRect, char *pStr, unsigned StrSize, float FontSize, bool Hidden) +int CMenus::DoEditBox(void *pID, const CUIRect *pRect, char *pStr, unsigned StrSize, float FontSize, bool Hidden, int Corners) { int Inside = UI()->MouseInside(pRect); - int ReturnValue = 0; - static int AtIndex = 0; + bool ReturnValue = false; + static int s_AtIndex = 0; if(UI()->LastActiveItem() == pID) { - int Len = strlen(pStr); + int Len = str_length(pStr); + if(Len == 0) + s_AtIndex = 0; if(Inside && UI()->MouseButton(0)) { - int mx_rel = (int)(UI()->MouseX() - pRect->x); + int MxRel = (int)(UI()->MouseX() - pRect->x); - for (int i = 1; i <= Len; i++) + for(int i = 1; i <= Len; i++) { - if (gfx_text_width(0, FontSize, pStr, i) + 10 > mx_rel) + if(TextRender()->TextWidth(0, FontSize, pStr, i) + 10 > MxRel) { - AtIndex = i - 1; + s_AtIndex = i - 1; break; } - if (i == Len) - AtIndex = Len; + if(i == Len) + s_AtIndex = Len; } } - for(int i = 0; i < num_inputevents; i++) + for(int i = 0; i < m_NumInputEvents; i++) { - Len = strlen(pStr); - LINEINPUT::manipulate(inputevents[i], pStr, StrSize, &Len, &AtIndex); + Len = str_length(pStr); + ReturnValue |= CLineInput::Manipulate(m_aInputEvents[i], pStr, StrSize, &Len, &s_AtIndex); } } @@ -264,35 +267,41 @@ int MENUS::DoEditBox(void *pID, const CUIRect *pRect, char *pStr, unsigned StrSi UI()->SetHotItem(pID); CUIRect Textbox = *pRect; - RenderTools()->DrawUIRect(&Textbox, vec4(1,1,1,0.5f), CUI::CORNER_ALL, 5.0f); - Textbox.VMargin(5.0f, &Textbox); + RenderTools()->DrawUIRect(&Textbox, vec4(1, 1, 1, 0.5f), Corners, 3.0f); + Textbox.VMargin(3.0f, &Textbox); const char *pDisplayStr = pStr; char aStars[128]; if(Hidden) { - unsigned s = strlen(pStr); + unsigned s = str_length(pStr); if(s >= sizeof(aStars)) s = sizeof(aStars)-1; - memset(aStars, '*', s); + for(unsigned int i = 0; i < s; ++i) + aStars[i] = '*'; aStars[s] = 0; pDisplayStr = aStars; } UI()->DoLabel(&Textbox, pDisplayStr, FontSize, -1); - if (UI()->LastActiveItem() == pID && !JustGotActive) + //TODO: make it blink + if(UI()->LastActiveItem() == pID && !JustGotActive) { - float w = gfx_text_width(0, FontSize, pDisplayStr, AtIndex); + float w = TextRender()->TextWidth(0, FontSize, pDisplayStr, s_AtIndex); + Textbox = *pRect; + Textbox.VSplitLeft(2.0f, 0, &Textbox); Textbox.x += w*UI()->Scale(); - UI()->DoLabel(&Textbox, "_", FontSize, -1); + Textbox.y -= FontSize/10.f; + + UI()->DoLabel(&Textbox, "|", FontSize*1.1f, -1); } return ReturnValue; } -float MENUS::DoScrollbarV(const void *pID, const CUIRect *pRect, float Current) +float CMenus::DoScrollbarV(const void *pID, const CUIRect *pRect, float Current) { CUIRect Handle; static float OffsetY; @@ -300,7 +309,7 @@ float MENUS::DoScrollbarV(const void *pID, const CUIRect *pRect, float Current) Handle.y += (pRect->h-Handle.h)*Current; - /* logic */ + // logic float ReturnValue = Current; int Inside = UI()->MouseInside(&Handle); @@ -309,10 +318,10 @@ float MENUS::DoScrollbarV(const void *pID, const CUIRect *pRect, float Current) if(!UI()->MouseButton(0)) UI()->SetActiveItem(0); - float min = pRect->y; - float max = pRect->h-Handle.h; - float cur = UI()->MouseY()-OffsetY; - ReturnValue = (cur-min)/max; + float Min = pRect->y; + float Max = pRect->h-Handle.h; + float Cur = UI()->MouseY()-OffsetY; + ReturnValue = (Cur-Min)/Max; if(ReturnValue < 0.0f) ReturnValue = 0.0f; if(ReturnValue > 1.0f) ReturnValue = 1.0f; } @@ -341,14 +350,14 @@ float MENUS::DoScrollbarV(const void *pID, const CUIRect *pRect, float Current) Slider = Handle; Slider.Margin(5.0f, &Slider); - RenderTools()->DrawUIRect(&Slider, vec4(1,1,1,0.25f)*button_color_mul(pID), CUI::CORNER_ALL, 2.5f); + RenderTools()->DrawUIRect(&Slider, vec4(1,1,1,0.25f)*ButtonColorMul(pID), CUI::CORNER_ALL, 2.5f); return ReturnValue; } -float MENUS::DoScrollbarH(const void *pID, const CUIRect *pRect, float Current) +float CMenus::DoScrollbarH(const void *pID, const CUIRect *pRect, float Current) { CUIRect Handle; static float OffsetX; @@ -356,7 +365,7 @@ float MENUS::DoScrollbarH(const void *pID, const CUIRect *pRect, float Current) Handle.x += (pRect->w-Handle.w)*Current; - /* logic */ + // logic float ReturnValue = Current; int Inside = UI()->MouseInside(&Handle); @@ -365,10 +374,10 @@ float MENUS::DoScrollbarH(const void *pID, const CUIRect *pRect, float Current) if(!UI()->MouseButton(0)) UI()->SetActiveItem(0); - float min = pRect->x; - float max = pRect->w-Handle.w; - float cur = UI()->MouseX()-OffsetX; - ReturnValue = (cur-min)/max; + float Min = pRect->x; + float Max = pRect->w-Handle.w; + float Cur = UI()->MouseX()-OffsetX; + ReturnValue = (Cur-Min)/Max; if(ReturnValue < 0.0f) ReturnValue = 0.0f; if(ReturnValue > 1.0f) ReturnValue = 1.0f; } @@ -397,12 +406,12 @@ float MENUS::DoScrollbarH(const void *pID, const CUIRect *pRect, float Current) Slider = Handle; Slider.Margin(5.0f, &Slider); - RenderTools()->DrawUIRect(&Slider, vec4(1,1,1,0.25f)*button_color_mul(pID), CUI::CORNER_ALL, 2.5f); + RenderTools()->DrawUIRect(&Slider, vec4(1,1,1,0.25f)*ButtonColorMul(pID), CUI::CORNER_ALL, 2.5f); return ReturnValue; } -int MENUS::DoKeyReader(void *pID, const CUIRect *pRect, int Key) +int CMenus::DoKeyReader(void *pID, const CUIRect *pRect, int Key) { // process static void *pGrabbedID = 0; @@ -415,10 +424,10 @@ int MENUS::DoKeyReader(void *pID, const CUIRect *pRect, int Key) if(UI()->ActiveItem() == pID) { - if(binder.got_key) + if(m_Binder.m_GotKey) { - NewKey = binder.key.key; - binder.got_key = false; + NewKey = m_Binder.m_Key.m_Key; + m_Binder.m_GotKey = false; UI()->SetActiveItem(0); MouseReleased = false; pGrabbedID = pID; @@ -428,8 +437,8 @@ int MENUS::DoKeyReader(void *pID, const CUIRect *pRect, int Key) { if(UI()->MouseButton(0) && MouseReleased) { - binder.take_key = true; - binder.got_key = false; + m_Binder.m_TakeKey = true; + m_Binder.m_GotKey = false; UI()->SetActiveItem(pID); } } @@ -445,185 +454,185 @@ int MENUS::DoKeyReader(void *pID, const CUIRect *pRect, int Key) if(Key == 0) DoButton_KeySelect(pID, "", 0, pRect); else - DoButton_KeySelect(pID, inp_key_name(Key), 0, pRect); + DoButton_KeySelect(pID, Input()->KeyName(Key), 0, pRect); } return NewKey; } -int MENUS::render_menubar(CUIRect r) +int CMenus::RenderMenubar(CUIRect r) { - CUIRect box = r; - CUIRect button; + CUIRect Box = r; + CUIRect Button; - int active_page = config.ui_page; - int new_page = -1; + m_ActivePage = g_Config.m_UiPage; + int NewPage = -1; - if(client_state() != CLIENTSTATE_OFFLINE) - active_page = game_page; + if(Client()->State() != IClient::STATE_OFFLINE) + m_ActivePage = m_GamePage; - if(client_state() == CLIENTSTATE_OFFLINE) + if(Client()->State() == IClient::STATE_OFFLINE) { - /* offline menus */ + // offline menus if(0) // this is not done yet { - box.VSplitLeft(90.0f, &button, &box); - static int news_button=0; - if (DoButton_MenuTab(&news_button, localize("News"), active_page==PAGE_NEWS, &button, 0)) - new_page = PAGE_NEWS; - box.VSplitLeft(30.0f, 0, &box); + Box.VSplitLeft(90.0f, &Button, &Box); + static int s_NewsButton=0; + if (DoButton_MenuTab(&s_NewsButton, Localize("News"), m_ActivePage==PAGE_NEWS, &Button, 0)) + NewPage = PAGE_NEWS; + Box.VSplitLeft(30.0f, 0, &Box); } - box.VSplitLeft(100.0f, &button, &box); - static int internet_button=0; - if(DoButton_MenuTab(&internet_button, localize("Internet"), active_page==PAGE_INTERNET, &button, CUI::CORNER_TL)) + Box.VSplitLeft(100.0f, &Button, &Box); + static int s_InternetButton=0; + if(DoButton_MenuTab(&s_InternetButton, Localize("Internet"), m_ActivePage==PAGE_INTERNET, &Button, CUI::CORNER_TL)) { - client_serverbrowse_refresh(BROWSETYPE_INTERNET); - new_page = PAGE_INTERNET; + ServerBrowser()->Refresh(IServerBrowser::TYPE_INTERNET); + NewPage = PAGE_INTERNET; } - //box.VSplitLeft(4.0f, 0, &box); - box.VSplitLeft(80.0f, &button, &box); - static int lan_button=0; - if(DoButton_MenuTab(&lan_button, localize("LAN"), active_page==PAGE_LAN, &button, 0)) + //Box.VSplitLeft(4.0f, 0, &Box); + Box.VSplitLeft(80.0f, &Button, &Box); + static int s_LanButton=0; + if(DoButton_MenuTab(&s_LanButton, Localize("LAN"), m_ActivePage==PAGE_LAN, &Button, 0)) { - client_serverbrowse_refresh(BROWSETYPE_LAN); - new_page = PAGE_LAN; + ServerBrowser()->Refresh(IServerBrowser::TYPE_LAN); + NewPage = PAGE_LAN; } //box.VSplitLeft(4.0f, 0, &box); - box.VSplitLeft(110.0f, &button, &box); - static int favorites_button=0; - if(DoButton_MenuTab(&favorites_button, localize("Favorites"), active_page==PAGE_FAVORITES, &button, CUI::CORNER_TR)) + Box.VSplitLeft(110.0f, &Button, &Box); + static int s_FavoritesButton=0; + if(DoButton_MenuTab(&s_FavoritesButton, Localize("Favorites"), m_ActivePage==PAGE_FAVORITES, &Button, CUI::CORNER_TR)) { - client_serverbrowse_refresh(BROWSETYPE_FAVORITES); - new_page = PAGE_FAVORITES; + ServerBrowser()->Refresh(IServerBrowser::TYPE_FAVORITES); + NewPage = PAGE_FAVORITES; } - box.VSplitLeft(4.0f*5, 0, &box); - box.VSplitLeft(100.0f, &button, &box); - static int demos_button=0; - if(DoButton_MenuTab(&demos_button, localize("Demos"), active_page==PAGE_DEMOS, &button, 0)) + Box.VSplitLeft(4.0f*5, 0, &Box); + Box.VSplitLeft(100.0f, &Button, &Box); + static int s_DemosButton=0; + if(DoButton_MenuTab(&s_DemosButton, Localize("Demos"), m_ActivePage==PAGE_DEMOS, &Button, CUI::CORNER_T)) { - demolist_populate(); - new_page = PAGE_DEMOS; + DemolistPopulate(); + NewPage = PAGE_DEMOS; } } else { - /* online menus */ - box.VSplitLeft(90.0f, &button, &box); - static int game_button=0; - if(DoButton_MenuTab(&game_button, localize("Game"), active_page==PAGE_GAME, &button, 0)) - new_page = PAGE_GAME; - - box.VSplitLeft(4.0f, 0, &box); - box.VSplitLeft(140.0f, &button, &box); - static int server_info_button=0; - if(DoButton_MenuTab(&server_info_button, localize("Server info"), active_page==PAGE_SERVER_INFO, &button, 0)) - new_page = PAGE_SERVER_INFO; - - box.VSplitLeft(4.0f, 0, &box); - box.VSplitLeft(140.0f, &button, &box); - static int callvote_button=0; - if(DoButton_MenuTab(&callvote_button, localize("Call vote"), active_page==PAGE_CALLVOTE, &button, 0)) - new_page = PAGE_CALLVOTE; + // online menus + Box.VSplitLeft(90.0f, &Button, &Box); + static int s_GameButton=0; + if(DoButton_MenuTab(&s_GameButton, Localize("Game"), m_ActivePage==PAGE_GAME, &Button, CUI::CORNER_T)) + NewPage = PAGE_GAME; + + Box.VSplitLeft(4.0f, 0, &Box); + Box.VSplitLeft(140.0f, &Button, &Box); + static int s_ServerInfoButton=0; + if(DoButton_MenuTab(&s_ServerInfoButton, Localize("Server info"), m_ActivePage==PAGE_SERVER_INFO, &Button, CUI::CORNER_T)) + NewPage = PAGE_SERVER_INFO; + + Box.VSplitLeft(4.0f, 0, &Box); + Box.VSplitLeft(140.0f, &Button, &Box); + static int s_CallVoteButton=0; + if(DoButton_MenuTab(&s_CallVoteButton, Localize("Call vote"), m_ActivePage==PAGE_CALLVOTE, &Button, CUI::CORNER_T)) + NewPage = PAGE_CALLVOTE; - box.VSplitLeft(30.0f, 0, &box); + Box.VSplitLeft(30.0f, 0, &Box); } /* box.VSplitRight(110.0f, &box, &button); static int system_button=0; - if (UI()->DoButton(&system_button, "System", config.ui_page==PAGE_SYSTEM, &button)) - config.ui_page = PAGE_SYSTEM; + if (UI()->DoButton(&system_button, "System", g_Config.m_UiPage==PAGE_SYSTEM, &button)) + g_Config.m_UiPage = PAGE_SYSTEM; box.VSplitRight(30.0f, &box, 0); */ - box.VSplitRight(90.0f, &box, &button); - static int quit_button=0; - if(DoButton_MenuTab(&quit_button, localize("Quit"), 0, &button, 0)) - popup = POPUP_QUIT; - - box.VSplitRight(10.0f, &box, &button); - box.VSplitRight(130.0f, &box, &button); - static int settings_button=0; - if(DoButton_MenuTab(&settings_button, localize("Settings"), active_page==PAGE_SETTINGS, &button, 0)) - new_page = PAGE_SETTINGS; + Box.VSplitRight(90.0f, &Box, &Button); + static int s_QuitButton=0; + if(DoButton_MenuTab(&s_QuitButton, Localize("Quit"), 0, &Button, CUI::CORNER_T)) + m_Popup = POPUP_QUIT; + + Box.VSplitRight(10.0f, &Box, &Button); + Box.VSplitRight(130.0f, &Box, &Button); + static int s_SettingsButton=0; + if(DoButton_MenuTab(&s_SettingsButton, Localize("Settings"), m_ActivePage==PAGE_SETTINGS, &Button, CUI::CORNER_T)) + NewPage = PAGE_SETTINGS; - if(new_page != -1) + if(NewPage != -1) { - if(client_state() == CLIENTSTATE_OFFLINE) - config.ui_page = new_page; + if(Client()->State() == IClient::STATE_OFFLINE) + g_Config.m_UiPage = NewPage; else - game_page = new_page; + m_GamePage = NewPage; } return 0; } -void MENUS::render_loading(float percent) +void CMenus::RenderLoading(float Percent) { - static int64 last_load_render = 0; + static int64 LastLoadRender = 0; // make sure that we don't render for each little thing we load // because that will slow down loading if we have vsync - if(time_get()-last_load_render < time_freq()/60) + if(time_get()-LastLoadRender < time_freq()/60) return; - last_load_render = time_get(); + LastLoadRender = time_get(); // need up date this here to get correct - vec3 rgb = hsl_to_rgb(vec3(config.ui_color_hue/255.0f, config.ui_color_sat/255.0f, config.ui_color_lht/255.0f)); - gui_color = vec4(rgb.r, rgb.g, rgb.b, config.ui_color_alpha/255.0f); + vec3 Rgb = HslToRgb(vec3(g_Config.m_UiColorHue/255.0f, g_Config.m_UiColorSat/255.0f, g_Config.m_UiColorLht/255.0f)); + ms_GuiColor = vec4(Rgb.r, Rgb.g, Rgb.b, g_Config.m_UiColorAlpha/255.0f); - CUIRect screen = *UI()->Screen(); - Graphics()->MapScreen(screen.x, screen.y, screen.w, screen.h); + CUIRect Screen = *UI()->Screen(); + Graphics()->MapScreen(Screen.x, Screen.y, Screen.w, Screen.h); - render_background(); + RenderBackground(); float tw; float w = 700; float h = 200; - float x = screen.w/2-w/2; - float y = screen.h/2-h/2; + float x = Screen.w/2-w/2; + float y = Screen.h/2-h/2; Graphics()->BlendNormal(); Graphics()->TextureSet(-1); Graphics()->QuadsBegin(); Graphics()->SetColor(0,0,0,0.50f); - RenderTools()->draw_round_rect(x, y, w, h, 40.0f); + RenderTools()->DrawRoundRect(x, y, w, h, 40.0f); Graphics()->QuadsEnd(); - const char *caption = localize("Loading"); + const char *pCaption = Localize("Loading"); - tw = gfx_text_width(0, 48.0f, caption, -1); + tw = TextRender()->TextWidth(0, 48.0f, pCaption, -1); CUIRect r; r.x = x; r.y = y+20; r.w = w; r.h = h; - UI()->DoLabel(&r, caption, 48.0f, 0, -1); + UI()->DoLabel(&r, pCaption, 48.0f, 0, -1); Graphics()->TextureSet(-1); Graphics()->QuadsBegin(); Graphics()->SetColor(1,1,1,0.75f); - RenderTools()->draw_round_rect(x+40, y+h-75, (w-80)*percent, 25, 5.0f); + RenderTools()->DrawRoundRect(x+40, y+h-75, (w-80)*Percent, 25, 5.0f); Graphics()->QuadsEnd(); - gfx_swap(); + Graphics()->Swap(); } -void MENUS::render_news(CUIRect main_view) +void CMenus::RenderNews(CUIRect MainView) { - RenderTools()->DrawUIRect(&main_view, color_tabbar_active, CUI::CORNER_ALL, 10.0f); + RenderTools()->DrawUIRect(&MainView, ms_ColorTabbarActive, CUI::CORNER_ALL, 10.0f); } -void MENUS::on_init() +void CMenus::OnInit() { /* @@ -669,261 +678,263 @@ void MENUS::on_init() exit(-1); // */ - if(config.cl_show_welcome) - popup = POPUP_FIRST_LAUNCH; - config.cl_show_welcome = 0; + if(g_Config.m_ClShowWelcome) + m_Popup = POPUP_FIRST_LAUNCH; + g_Config.m_ClShowWelcome = 0; } -void MENUS::popup_message(const char *topic, const char *body, const char *button) +void CMenus::PopupMessage(const char *pTopic, const char *pBody, const char *pButton) { - str_copy(message_topic, topic, sizeof(message_topic)); - str_copy(message_body, body, sizeof(message_body)); - str_copy(message_button, button, sizeof(message_button)); - popup = POPUP_MESSAGE; + str_copy(m_aMessageTopic, pTopic, sizeof(m_aMessageTopic)); + str_copy(m_aMessageBody, pBody, sizeof(m_aMessageBody)); + str_copy(m_aMessageButton, pButton, sizeof(m_aMessageButton)); + m_Popup = POPUP_MESSAGE; } -int MENUS::render() +int CMenus::Render() { - CUIRect screen = *UI()->Screen(); - Graphics()->MapScreen(screen.x, screen.y, screen.w, screen.h); + CUIRect Screen = *UI()->Screen(); + Graphics()->MapScreen(Screen.x, Screen.y, Screen.w, Screen.h); - static bool first = true; - if(first) + static bool s_First = true; + if(s_First) { - if(config.ui_page == PAGE_INTERNET) - client_serverbrowse_refresh(0); - else if(config.ui_page == PAGE_LAN) - client_serverbrowse_refresh(1); - first = false; + if(g_Config.m_UiPage == PAGE_INTERNET) + ServerBrowser()->Refresh(IServerBrowser::TYPE_INTERNET); + else if(g_Config.m_UiPage == PAGE_LAN) + ServerBrowser()->Refresh(IServerBrowser::TYPE_LAN); + else if(g_Config.m_UiPage == PAGE_FAVORITES) + ServerBrowser()->Refresh(IServerBrowser::TYPE_FAVORITES); + s_First = false; } - if(client_state() == CLIENTSTATE_ONLINE) + if(Client()->State() == IClient::STATE_ONLINE) { - color_tabbar_inactive = color_tabbar_inactive_ingame; - color_tabbar_active = color_tabbar_active_ingame; + ms_ColorTabbarInactive = ms_ColorTabbarInactiveIngame; + ms_ColorTabbarActive = ms_ColorTabbarActiveIngame; } else { - render_background(); - color_tabbar_inactive = color_tabbar_inactive_outgame; - color_tabbar_active = color_tabbar_active_outgame; + RenderBackground(); + ms_ColorTabbarInactive = ms_ColorTabbarInactiveOutgame; + ms_ColorTabbarActive = ms_ColorTabbarActiveOutgame; } - CUIRect tab_bar; - CUIRect main_view; + CUIRect TabBar; + CUIRect MainView; // some margin around the screen - screen.Margin(10.0f, &screen); + Screen.Margin(10.0f, &Screen); - if(popup == POPUP_NONE) + if(m_Popup == POPUP_NONE) { // do tab bar - screen.HSplitTop(24.0f, &tab_bar, &main_view); - tab_bar.VMargin(20.0f, &tab_bar); - render_menubar(tab_bar); + Screen.HSplitTop(24.0f, &TabBar, &MainView); + TabBar.VMargin(20.0f, &TabBar); + RenderMenubar(TabBar); // news is not implemented yet - if(config.ui_page <= PAGE_NEWS || config.ui_page > PAGE_SETTINGS || (client_state() == CLIENTSTATE_OFFLINE && config.ui_page >= PAGE_GAME && config.ui_page <= PAGE_CALLVOTE)) + if(g_Config.m_UiPage <= PAGE_NEWS || g_Config.m_UiPage > PAGE_SETTINGS || (Client()->State() == IClient::STATE_OFFLINE && g_Config.m_UiPage >= PAGE_GAME && g_Config.m_UiPage <= PAGE_CALLVOTE)) { - client_serverbrowse_refresh(BROWSETYPE_INTERNET); - config.ui_page = PAGE_INTERNET; + ServerBrowser()->Refresh(IServerBrowser::TYPE_INTERNET); + g_Config.m_UiPage = PAGE_INTERNET; } // render current page - if(client_state() != CLIENTSTATE_OFFLINE) + if(Client()->State() != IClient::STATE_OFFLINE) { - if(game_page == PAGE_GAME) - render_game(main_view); - else if(game_page == PAGE_SERVER_INFO) - render_serverinfo(main_view); - else if(game_page == PAGE_CALLVOTE) - render_servercontrol(main_view); - else if(game_page == PAGE_SETTINGS) - render_settings(main_view); + if(m_GamePage == PAGE_GAME) + RenderGame(MainView); + else if(m_GamePage == PAGE_SERVER_INFO) + RenderServerInfo(MainView); + else if(m_GamePage == PAGE_CALLVOTE) + RenderServerControl(MainView); + else if(m_GamePage == PAGE_SETTINGS) + RenderSettings(MainView); } - else if(config.ui_page == PAGE_NEWS) - render_news(main_view); - else if(config.ui_page == PAGE_INTERNET) - render_serverbrowser(main_view); - else if(config.ui_page == PAGE_LAN) - render_serverbrowser(main_view); - else if(config.ui_page == PAGE_DEMOS) - render_demolist(main_view); - else if(config.ui_page == PAGE_FAVORITES) - render_serverbrowser(main_view); - else if(config.ui_page == PAGE_SETTINGS) - render_settings(main_view); + else if(g_Config.m_UiPage == PAGE_NEWS) + RenderNews(MainView); + else if(g_Config.m_UiPage == PAGE_INTERNET) + RenderServerbrowser(MainView); + else if(g_Config.m_UiPage == PAGE_LAN) + RenderServerbrowser(MainView); + else if(g_Config.m_UiPage == PAGE_DEMOS) + RenderDemoList(MainView); + else if(g_Config.m_UiPage == PAGE_FAVORITES) + RenderServerbrowser(MainView); + else if(g_Config.m_UiPage == PAGE_SETTINGS) + RenderSettings(MainView); } else { // make sure that other windows doesn't do anything funnay! //UI()->SetHotItem(0); //UI()->SetActiveItem(0); - char buf[128]; - const char *title = ""; - const char *extra_text = ""; - const char *button_text = ""; - int extra_align = 0; + char aBuf[128]; + const char *pTitle = ""; + const char *pExtraText = ""; + const char *pButtonText = ""; + int ExtraAlign = 0; - if(popup == POPUP_MESSAGE) + if(m_Popup == POPUP_MESSAGE) { - title = message_topic; - extra_text = message_body; - button_text = message_button; + pTitle = m_aMessageTopic; + pExtraText = m_aMessageBody; + pButtonText = m_aMessageButton; } - else if(popup == POPUP_CONNECTING) + else if(m_Popup == POPUP_CONNECTING) { - title = localize("Connecting to"); - extra_text = config.ui_server_address; // TODO: query the client about the address - button_text = localize("Abort"); - if(client_mapdownload_totalsize() > 0) + pTitle = Localize("Connecting to"); + pExtraText = g_Config.m_UiServerAddress; // TODO: query the client about the address + pButtonText = Localize("Abort"); + if(Client()->MapDownloadTotalsize() > 0) { - title = localize("Downloading map"); - str_format(buf, sizeof(buf), "%d/%d KiB", client_mapdownload_amount()/1024, client_mapdownload_totalsize()/1024); - extra_text = buf; + pTitle = Localize("Downloading map"); + str_format(aBuf, sizeof(aBuf), "%d/%d KiB", Client()->MapDownloadAmount()/1024, Client()->MapDownloadTotalsize()/1024); + pExtraText = aBuf; } } - else if(popup == POPUP_DISCONNECTED) + else if(m_Popup == POPUP_DISCONNECTED) { - title = localize("Disconnected"); - extra_text = client_error_string(); - button_text = localize("Ok"); - extra_align = -1; + pTitle = Localize("Disconnected"); + pExtraText = Client()->ErrorString(); + pButtonText = Localize("Ok"); + ExtraAlign = -1; } - else if(popup == POPUP_PURE) + else if(m_Popup == POPUP_PURE) { - title = localize("Disconnected"); - extra_text = localize("The server is running a non-standard tuning on a pure game type."); - button_text = localize("Ok"); - extra_align = -1; + pTitle = Localize("Disconnected"); + pExtraText = Localize("The server is running a non-standard tuning on a pure game type."); + pButtonText = Localize("Ok"); + ExtraAlign = -1; } - else if(popup == POPUP_PASSWORD) + else if(m_Popup == POPUP_PASSWORD) { - title = localize("Password Incorrect"); - extra_text = client_error_string(); - button_text = localize("Try again"); + pTitle = Localize("Password Incorrect"); + pExtraText = Client()->ErrorString(); + pButtonText = Localize("Try again"); } - else if(popup == POPUP_QUIT) + else if(m_Popup == POPUP_QUIT) { - title = localize("Quit"); - extra_text = localize("Are you sure that you want to quit?"); + pTitle = Localize("Quit"); + pExtraText = Localize("Are you sure that you want to quit?"); } - else if(popup == POPUP_FIRST_LAUNCH) + else if(m_Popup == POPUP_FIRST_LAUNCH) { - title = localize("Welcome to Teeworlds"); - extra_text = localize("As this is the first time you launch the game, please enter your nick name below. It's recommended that you check the settings to adjust them to your liking before joining a server."); - button_text = localize("Ok"); - extra_align = -1; + pTitle = Localize("Welcome to Teeworlds"); + pExtraText = Localize("As this is the first time you launch the game, please enter your nick name below. It's recommended that you check the settings to adjust them to your liking before joining a server."); + pButtonText = Localize("Ok"); + ExtraAlign = -1; } - CUIRect box, part; - box = screen; - box.VMargin(150.0f, &box); - box.HMargin(150.0f, &box); + CUIRect Box, Part; + Box = Screen; + Box.VMargin(150.0f, &Box); + Box.HMargin(150.0f, &Box); // render the box - RenderTools()->DrawUIRect(&box, vec4(0,0,0,0.5f), CUI::CORNER_ALL, 15.0f); + RenderTools()->DrawUIRect(&Box, vec4(0,0,0,0.5f), CUI::CORNER_ALL, 15.0f); - box.HSplitTop(20.f, &part, &box); - box.HSplitTop(24.f, &part, &box); - UI()->DoLabel(&part, title, 24.f, 0); - box.HSplitTop(20.f, &part, &box); - box.HSplitTop(24.f, &part, &box); - part.VMargin(20.f, &part); + Box.HSplitTop(20.f, &Part, &Box); + Box.HSplitTop(24.f, &Part, &Box); + UI()->DoLabel(&Part, pTitle, 24.f, 0); + Box.HSplitTop(20.f, &Part, &Box); + Box.HSplitTop(24.f, &Part, &Box); + Part.VMargin(20.f, &Part); - if(extra_align == -1) - UI()->DoLabel(&part, extra_text, 20.f, -1, (int)part.w); + if(ExtraAlign == -1) + UI()->DoLabel(&Part, pExtraText, 20.f, -1, (int)Part.w); else - UI()->DoLabel(&part, extra_text, 20.f, 0, -1); + UI()->DoLabel(&Part, pExtraText, 20.f, 0, -1); - if(popup == POPUP_QUIT) + if(m_Popup == POPUP_QUIT) { - CUIRect yes, no; - box.HSplitBottom(20.f, &box, &part); - box.HSplitBottom(24.f, &box, &part); - part.VMargin(80.0f, &part); + CUIRect Yes, No; + Box.HSplitBottom(20.f, &Box, &Part); + Box.HSplitBottom(24.f, &Box, &Part); + Part.VMargin(80.0f, &Part); - part.VSplitMid(&no, &yes); + Part.VSplitMid(&No, &Yes); - yes.VMargin(20.0f, &yes); - no.VMargin(20.0f, &no); + Yes.VMargin(20.0f, &Yes); + No.VMargin(20.0f, &No); - static int button_abort = 0; - if(DoButton_Menu(&button_abort, localize("No"), 0, &no) || escape_pressed) - popup = POPUP_NONE; + static int s_ButtonAbort = 0; + if(DoButton_Menu(&s_ButtonAbort, Localize("No"), 0, &No) || m_EscapePressed) + m_Popup = POPUP_NONE; - static int button_tryagain = 0; - if(DoButton_Menu(&button_tryagain, localize("Yes"), 0, &yes) || enter_pressed) - client_quit(); + static int s_ButtonTryAgain = 0; + if(DoButton_Menu(&s_ButtonTryAgain, Localize("Yes"), 0, &Yes) || m_EnterPressed) + Client()->Quit(); } - else if(popup == POPUP_PASSWORD) + else if(m_Popup == POPUP_PASSWORD) { - CUIRect label, textbox, tryagain, abort; + CUIRect Label, TextBox, TryAgain, Abort; - box.HSplitBottom(20.f, &box, &part); - box.HSplitBottom(24.f, &box, &part); - part.VMargin(80.0f, &part); + Box.HSplitBottom(20.f, &Box, &Part); + Box.HSplitBottom(24.f, &Box, &Part); + Part.VMargin(80.0f, &Part); - part.VSplitMid(&abort, &tryagain); + Part.VSplitMid(&Abort, &TryAgain); - tryagain.VMargin(20.0f, &tryagain); - abort.VMargin(20.0f, &abort); + TryAgain.VMargin(20.0f, &TryAgain); + Abort.VMargin(20.0f, &Abort); - static int button_abort = 0; - if(DoButton_Menu(&button_abort, localize("Abort"), 0, &abort) || escape_pressed) - popup = POPUP_NONE; + static int s_ButtonAbort = 0; + if(DoButton_Menu(&s_ButtonAbort, Localize("Abort"), 0, &Abort) || m_EscapePressed) + m_Popup = POPUP_NONE; - static int button_tryagain = 0; - if(DoButton_Menu(&button_tryagain, localize("Try again"), 0, &tryagain) || enter_pressed) + static int s_ButtonTryAgain = 0; + if(DoButton_Menu(&s_ButtonTryAgain, Localize("Try again"), 0, &TryAgain) || m_EnterPressed) { - client_connect(config.ui_server_address); + Client()->Connect(g_Config.m_UiServerAddress); } - box.HSplitBottom(60.f, &box, &part); - box.HSplitBottom(24.f, &box, &part); + Box.HSplitBottom(60.f, &Box, &Part); + Box.HSplitBottom(24.f, &Box, &Part); - part.VSplitLeft(60.0f, 0, &label); - label.VSplitLeft(100.0f, 0, &textbox); - textbox.VSplitLeft(20.0f, 0, &textbox); - textbox.VSplitRight(60.0f, &textbox, 0); - UI()->DoLabel(&label, localize("Password"), 20, -1); - DoEditBox(&config.password, &textbox, config.password, sizeof(config.password), 14.0f, true); + Part.VSplitLeft(60.0f, 0, &Label); + Label.VSplitLeft(100.0f, 0, &TextBox); + TextBox.VSplitLeft(20.0f, 0, &TextBox); + TextBox.VSplitRight(60.0f, &TextBox, 0); + UI()->DoLabel(&Label, Localize("Password"), 18.0f, -1); + DoEditBox(&g_Config.m_Password, &TextBox, g_Config.m_Password, sizeof(g_Config.m_Password), 12.0f, true); } - else if(popup == POPUP_FIRST_LAUNCH) + else if(m_Popup == POPUP_FIRST_LAUNCH) { - CUIRect label, textbox; + CUIRect Label, TextBox; - box.HSplitBottom(20.f, &box, &part); - box.HSplitBottom(24.f, &box, &part); - part.VMargin(80.0f, &part); + Box.HSplitBottom(20.f, &Box, &Part); + Box.HSplitBottom(24.f, &Box, &Part); + Part.VMargin(80.0f, &Part); - static int enter_button = 0; - if(DoButton_Menu(&enter_button, localize("Enter"), 0, &part) || enter_pressed) - popup = POPUP_NONE; + static int s_EnterButton = 0; + if(DoButton_Menu(&s_EnterButton, Localize("Enter"), 0, &Part) || m_EnterPressed) + m_Popup = POPUP_NONE; - box.HSplitBottom(40.f, &box, &part); - box.HSplitBottom(24.f, &box, &part); + Box.HSplitBottom(40.f, &Box, &Part); + Box.HSplitBottom(24.f, &Box, &Part); - part.VSplitLeft(60.0f, 0, &label); - label.VSplitLeft(100.0f, 0, &textbox); - textbox.VSplitLeft(20.0f, 0, &textbox); - textbox.VSplitRight(60.0f, &textbox, 0); - UI()->DoLabel(&label, localize("Nickname"), 20, -1); - DoEditBox(&config.player_name, &textbox, config.player_name, sizeof(config.player_name), 14.0f); + Part.VSplitLeft(60.0f, 0, &Label); + Label.VSplitLeft(100.0f, 0, &TextBox); + TextBox.VSplitLeft(20.0f, 0, &TextBox); + TextBox.VSplitRight(60.0f, &TextBox, 0); + UI()->DoLabel(&Label, Localize("Nickname"), 18.0f, -1); + DoEditBox(&g_Config.m_PlayerName, &TextBox, g_Config.m_PlayerName, sizeof(g_Config.m_PlayerName), 12.0f); } else { - box.HSplitBottom(20.f, &box, &part); - box.HSplitBottom(24.f, &box, &part); - part.VMargin(120.0f, &part); + Box.HSplitBottom(20.f, &Box, &Part); + Box.HSplitBottom(24.f, &Box, &Part); + Part.VMargin(120.0f, &Part); - static int button = 0; - if(DoButton_Menu(&button, button_text, 0, &part) || escape_pressed || enter_pressed) + static int s_Button = 0; + if(DoButton_Menu(&s_Button, pButtonText, 0, &Part) || m_EscapePressed || m_EnterPressed) { - if(popup == POPUP_CONNECTING) - client_disconnect(); - popup = POPUP_NONE; + if(m_Popup == POPUP_CONNECTING) + Client()->Disconnect(); + m_Popup = POPUP_NONE; } } } @@ -932,109 +943,113 @@ int MENUS::render() } -void MENUS::set_active(bool active) +void CMenus::SetActive(bool Active) { - menu_active = active; - if(!menu_active && need_sendinfo) + m_MenuActive = Active; + if(!m_MenuActive && m_NeedSendinfo) { - gameclient.send_info(false); - need_sendinfo = false; + m_pClient->SendInfo(false); + m_NeedSendinfo = false; } } -void MENUS::on_reset() +void CMenus::OnReset() { } -bool MENUS::on_mousemove(float x, float y) +bool CMenus::OnMouseMove(float x, float y) { - last_input = time_get(); + m_LastInput = time_get(); - if(!menu_active) + if(!m_MenuActive) return false; - mouse_pos.x += x; - mouse_pos.y += y; - if(mouse_pos.x < 0) mouse_pos.x = 0; - if(mouse_pos.y < 0) mouse_pos.y = 0; - if(mouse_pos.x > Graphics()->ScreenWidth()) mouse_pos.x = Graphics()->ScreenWidth(); - if(mouse_pos.y > Graphics()->ScreenHeight()) mouse_pos.y = Graphics()->ScreenHeight(); + m_MousePos.x += x; + m_MousePos.y += y; + if(m_MousePos.x < 0) m_MousePos.x = 0; + if(m_MousePos.y < 0) m_MousePos.y = 0; + if(m_MousePos.x > Graphics()->ScreenWidth()) m_MousePos.x = Graphics()->ScreenWidth(); + if(m_MousePos.y > Graphics()->ScreenHeight()) m_MousePos.y = Graphics()->ScreenHeight(); return true; } -bool MENUS::on_input(INPUT_EVENT e) +bool CMenus::OnInput(IInput::CEvent e) { - last_input = time_get(); + m_LastInput = time_get(); // special handle esc and enter for popup purposes - if(e.flags&INPFLAG_PRESS) + if(e.m_Flags&IInput::FLAG_PRESS) { - if(e.key == KEY_ESCAPE) + if(e.m_Key == KEY_ESCAPE) { - escape_pressed = true; - set_active(!is_active()); + m_EscapePressed = true; + SetActive(!IsActive()); return true; } } - if(is_active()) + if(IsActive()) { // special for popups - if(e.flags&INPFLAG_PRESS && e.key == KEY_RETURN) - enter_pressed = true; + if(e.m_Flags&IInput::FLAG_PRESS && e.m_Key == KEY_RETURN) + m_EnterPressed = true; - if(num_inputevents < MAX_INPUTEVENTS) - inputevents[num_inputevents++] = e; + if(m_NumInputEvents < MAX_INPUTEVENTS) + m_aInputEvents[m_NumInputEvents++] = e; return true; } return false; } -void MENUS::on_statechange(int new_state, int old_state) +void CMenus::OnStateChange(int NewState, int OldState) { - if(new_state == CLIENTSTATE_OFFLINE) + // reset active item + UI()->SetActiveItem(0); + + if(NewState == IClient::STATE_OFFLINE) { - popup = POPUP_NONE; - if(client_error_string() && client_error_string()[0] != 0) + m_Popup = POPUP_NONE; + if(Client()->ErrorString() && Client()->ErrorString()[0] != 0) { - if(strstr(client_error_string(), "password")) + if(str_find(Client()->ErrorString(), "password")) { - popup = POPUP_PASSWORD; - UI()->SetHotItem(&config.password); - UI()->SetActiveItem(&config.password); + m_Popup = POPUP_PASSWORD; + UI()->SetHotItem(&g_Config.m_Password); + UI()->SetActiveItem(&g_Config.m_Password); } else - popup = POPUP_DISCONNECTED; - } } - else if(new_state == CLIENTSTATE_LOADING) + m_Popup = POPUP_DISCONNECTED; + } + } + else if(NewState == IClient::STATE_LOADING) { - popup = POPUP_CONNECTING; - client_serverinfo_request(); + m_Popup = POPUP_CONNECTING; + //client_serverinfo_request(); } - else if(new_state == CLIENTSTATE_CONNECTING) - popup = POPUP_CONNECTING; - else if (new_state == CLIENTSTATE_ONLINE || new_state == CLIENTSTATE_DEMOPLAYBACK) + else if(NewState == IClient::STATE_CONNECTING) + m_Popup = POPUP_CONNECTING; + else if (NewState == IClient::STATE_ONLINE || NewState == IClient::STATE_DEMOPLAYBACK) { - popup = POPUP_NONE; - set_active(false); + m_Popup = POPUP_NONE; + SetActive(false); } } extern "C" void font_debug_render(); -void MENUS::on_render() +void CMenus::OnRender() { /* // text rendering test stuff render_background(); - TEXT_CURSOR cursor; - gfx_text_set_cursor(&cursor, 10, 10, 20, TEXTFLAG_RENDER); - gfx_text_ex(&cursor, "ようこそ - ガイド", -1); + CTextCursor cursor; + TextRender()->SetCursor(&cursor, 10, 10, 20, TEXTFLAG_RENDER); + TextRender()->TextEx(&cursor, "ようこそ - ガイド", -1); - gfx_text_set_cursor(&cursor, 10, 30, 15, TEXTFLAG_RENDER); - gfx_text_ex(&cursor, "ようこそ - ガイド", -1); + TextRender()->SetCursor(&cursor, 10, 30, 15, TEXTFLAG_RENDER); + TextRender()->TextEx(&cursor, "ようこそ - ガイド", -1); //Graphics()->TextureSet(-1); Graphics()->QuadsBegin(); @@ -1042,101 +1057,105 @@ void MENUS::on_render() Graphics()->QuadsEnd(); return;*/ - if(client_state() != CLIENTSTATE_ONLINE && client_state() != CLIENTSTATE_DEMOPLAYBACK) - set_active(true); + if(Client()->State() != IClient::STATE_ONLINE && Client()->State() != IClient::STATE_DEMOPLAYBACK) + SetActive(true); - if(client_state() == CLIENTSTATE_DEMOPLAYBACK) + if(Client()->State() == IClient::STATE_DEMOPLAYBACK) { - CUIRect screen = *UI()->Screen(); - Graphics()->MapScreen(screen.x, screen.y, screen.w, screen.h); - render_demoplayer(screen); + CUIRect Screen = *UI()->Screen(); + Graphics()->MapScreen(Screen.x, Screen.y, Screen.w, Screen.h); + RenderDemoPlayer(Screen); } - if(client_state() == CLIENTSTATE_ONLINE && gameclient.servermode == gameclient.SERVERMODE_PUREMOD) + if(Client()->State() == IClient::STATE_ONLINE && m_pClient->m_ServerMode == m_pClient->SERVERMODE_PUREMOD) { - client_disconnect(); - set_active(true); - popup = POPUP_PURE; + Client()->Disconnect(); + SetActive(true); + m_Popup = POPUP_PURE; } - if(!is_active()) + if(!IsActive()) { - escape_pressed = false; - enter_pressed = false; - num_inputevents = 0; + m_EscapePressed = false; + m_EnterPressed = false; + m_NumInputEvents = 0; return; } // update colors - vec3 rgb = hsl_to_rgb(vec3(config.ui_color_hue/255.0f, config.ui_color_sat/255.0f, config.ui_color_lht/255.0f)); - gui_color = vec4(rgb.r, rgb.g, rgb.b, config.ui_color_alpha/255.0f); - - color_tabbar_inactive_outgame = vec4(0,0,0,0.25f); - color_tabbar_active_outgame = vec4(0,0,0,0.5f); - - float color_ingame_scale_i = 0.5f; - float color_ingame_scale_a = 0.2f; - color_tabbar_inactive_ingame = vec4( - gui_color.r*color_ingame_scale_i, - gui_color.g*color_ingame_scale_i, - gui_color.b*color_ingame_scale_i, - gui_color.a*0.8f); + vec3 Rgb = HslToRgb(vec3(g_Config.m_UiColorHue/255.0f, g_Config.m_UiColorSat/255.0f, g_Config.m_UiColorLht/255.0f)); + ms_GuiColor = vec4(Rgb.r, Rgb.g, Rgb.b, g_Config.m_UiColorAlpha/255.0f); + + ms_ColorTabbarInactiveOutgame = vec4(0,0,0,0.25f); + ms_ColorTabbarActiveOutgame = vec4(0,0,0,0.5f); + + float ColorIngameScaleI = 0.5f; + float ColorIngameAcaleA = 0.2f; + ms_ColorTabbarInactiveIngame = vec4( + ms_GuiColor.r*ColorIngameScaleI, + ms_GuiColor.g*ColorIngameScaleI, + ms_GuiColor.b*ColorIngameScaleI, + ms_GuiColor.a*0.8f); - color_tabbar_active_ingame = vec4( - gui_color.r*color_ingame_scale_a, - gui_color.g*color_ingame_scale_a, - gui_color.b*color_ingame_scale_a, - gui_color.a); + ms_ColorTabbarActiveIngame = vec4( + ms_GuiColor.r*ColorIngameAcaleA, + ms_GuiColor.g*ColorIngameAcaleA, + ms_GuiColor.b*ColorIngameAcaleA, + ms_GuiColor.a); // update the ui - CUIRect *screen = UI()->Screen(); - float mx = (mouse_pos.x/(float)Graphics()->ScreenWidth())*screen->w; - float my = (mouse_pos.y/(float)Graphics()->ScreenHeight())*screen->h; + CUIRect *pScreen = UI()->Screen(); + float mx = (m_MousePos.x/(float)Graphics()->ScreenWidth())*pScreen->w; + float my = (m_MousePos.y/(float)Graphics()->ScreenHeight())*pScreen->h; - int buttons = 0; - if(inp_key_pressed(KEY_MOUSE_1)) buttons |= 1; - if(inp_key_pressed(KEY_MOUSE_2)) buttons |= 2; - if(inp_key_pressed(KEY_MOUSE_3)) buttons |= 4; + int Buttons = 0; + if(m_UseMouseButtons) + { + if(Input()->KeyPressed(KEY_MOUSE_1)) Buttons |= 1; + if(Input()->KeyPressed(KEY_MOUSE_2)) Buttons |= 2; + if(Input()->KeyPressed(KEY_MOUSE_3)) Buttons |= 4; + } - UI()->Update(mx,my,mx*3.0f,my*3.0f,buttons); + UI()->Update(mx,my,mx*3.0f,my*3.0f,Buttons); // render - if(client_state() != CLIENTSTATE_DEMOPLAYBACK) - render(); + if(Client()->State() != IClient::STATE_DEMOPLAYBACK) + Render(); // render cursor - Graphics()->TextureSet(data->images[IMAGE_CURSOR].id); + Graphics()->TextureSet(g_pData->m_aImages[IMAGE_CURSOR].m_Id); Graphics()->QuadsBegin(); Graphics()->SetColor(1,1,1,1); - Graphics()->QuadsDrawTL(mx,my,24,24); + IGraphics::CQuadItem QuadItem(mx, my, 24, 24); + Graphics()->QuadsDrawTL(&QuadItem, 1); Graphics()->QuadsEnd(); // render debug information - if(config.debug) + if(g_Config.m_Debug) { - CUIRect screen = *UI()->Screen(); - Graphics()->MapScreen(screen.x, screen.y, screen.w, screen.h); - - char buf[512]; - str_format(buf, sizeof(buf), "%p %p %p", UI()->HotItem(), UI()->ActiveItem(), UI()->LastActiveItem()); - TEXT_CURSOR cursor; - gfx_text_set_cursor(&cursor, 10, 10, 10, TEXTFLAG_RENDER); - gfx_text_ex(&cursor, buf, -1); + CUIRect Screen = *UI()->Screen(); + Graphics()->MapScreen(Screen.x, Screen.y, Screen.w, Screen.h); + + char aBuf[512]; + str_format(aBuf, sizeof(aBuf), "%p %p %p", UI()->HotItem(), UI()->ActiveItem(), UI()->LastActiveItem()); + CTextCursor Cursor; + TextRender()->SetCursor(&Cursor, 10, 10, 10, TEXTFLAG_RENDER); + TextRender()->TextEx(&Cursor, aBuf, -1); } - escape_pressed = false; - enter_pressed = false; - num_inputevents = 0; + m_EscapePressed = false; + m_EnterPressed = false; + m_NumInputEvents = 0; } -static int texture_blob = -1; +static int gs_TextureBlob = -1; -void MENUS::render_background() +void CMenus::RenderBackground() { //Graphics()->Clear(1,1,1); //render_sunrays(0,0); - if(texture_blob == -1) - texture_blob = Graphics()->LoadTexture("blob.png", IMG_AUTO, 0); + if(gs_TextureBlob == -1) + gs_TextureBlob = Graphics()->LoadTexture("blob.png", CImageInfo::FORMAT_AUTO, 0); float sw = 300*Graphics()->ScreenAspect(); @@ -1150,36 +1169,41 @@ void MENUS::render_background() Graphics()->QuadsBegin(); //vec4 bottom(gui_color.r*0.3f, gui_color.g*0.3f, gui_color.b*0.3f, 1.0f); //vec4 bottom(0, 0, 0, 1.0f); - vec4 bottom(gui_color.r, gui_color.g, gui_color.b, 1.0f); - vec4 top(gui_color.r, gui_color.g, gui_color.b, 1.0f); - Graphics()->SetColorVertex(0, top.r, top.g, top.b, top.a); - Graphics()->SetColorVertex(1, top.r, top.g, top.b, top.a); - Graphics()->SetColorVertex(2, bottom.r, bottom.g, bottom.b, bottom.a); - Graphics()->SetColorVertex(3, bottom.r, bottom.g, bottom.b, bottom.a); - Graphics()->QuadsDrawTL(0, 0, sw, sh); + vec4 Bottom(ms_GuiColor.r, ms_GuiColor.g, ms_GuiColor.b, 1.0f); + vec4 Top(ms_GuiColor.r, ms_GuiColor.g, ms_GuiColor.b, 1.0f); + IGraphics::CColorVertex Array[4] = { + IGraphics::CColorVertex(0, Top.r, Top.g, Top.b, Top.a), + IGraphics::CColorVertex(1, Top.r, Top.g, Top.b, Top.a), + IGraphics::CColorVertex(2, Bottom.r, Bottom.g, Bottom.b, Bottom.a), + IGraphics::CColorVertex(3, Bottom.r, Bottom.g, Bottom.b, Bottom.a)}; + Graphics()->SetColorVertex(Array, 4); + IGraphics::CQuadItem QuadItem(0, 0, sw, sh); + Graphics()->QuadsDrawTL(&QuadItem, 1); Graphics()->QuadsEnd(); // render the tiles Graphics()->TextureSet(-1); Graphics()->QuadsBegin(); - float size = 15.0f; - float offset_time = fmod(client_localtime()*0.15f, 2.0f); - for(int y = -2; y < (int)(sw/size); y++) - for(int x = -2; x < (int)(sh/size); x++) + float Size = 15.0f; + float OffsetTime = fmod(Client()->LocalTime()*0.15f, 2.0f); + for(int y = -2; y < (int)(sw/Size); y++) + for(int x = -2; x < (int)(sh/Size); x++) { Graphics()->SetColor(0,0,0,0.045f); - Graphics()->QuadsDrawTL((x-offset_time)*size*2+(y&1)*size, (y+offset_time)*size, size, size); + IGraphics::CQuadItem QuadItem((x-OffsetTime)*Size*2+(y&1)*Size, (y+OffsetTime)*Size, Size, Size); + Graphics()->QuadsDrawTL(&QuadItem, 1); } Graphics()->QuadsEnd(); // render border fade - Graphics()->TextureSet(texture_blob); + Graphics()->TextureSet(gs_TextureBlob); Graphics()->QuadsBegin(); Graphics()->SetColor(0,0,0,0.5f); - Graphics()->QuadsDrawTL(-100, -100, sw+200, sh+200); + QuadItem = IGraphics::CQuadItem(-100, -100, sw+200, sh+200); + Graphics()->QuadsDrawTL(&QuadItem, 1); Graphics()->QuadsEnd(); // restore screen - {CUIRect screen = *UI()->Screen(); - Graphics()->MapScreen(screen.x, screen.y, screen.w, screen.h);} + {CUIRect Screen = *UI()->Screen(); + Graphics()->MapScreen(Screen.x, Screen.y, Screen.w, Screen.h);} } diff --git a/src/game/client/components/menus.h b/src/game/client/components/menus.h new file mode 100644 index 00000000..3055e661 --- /dev/null +++ b/src/game/client/components/menus.h @@ -0,0 +1,223 @@ +#ifndef GAME_CLIENT_COMPONENTS_MENUS_H +#define GAME_CLIENT_COMPONENTS_MENUS_H + +#include <base/vmath.h> +#include <base/tl/sorted_array.h> + +#include <game/client/component.h> +#include <game/client/ui.h> + + +// compnent to fetch keypresses, override all other input +class CMenusKeyBinder : public CComponent +{ +public: + bool m_TakeKey; + bool m_GotKey; + IInput::CEvent m_Key; + CMenusKeyBinder(); + virtual bool OnInput(IInput::CEvent Event); +}; + +class CMenus : public CComponent +{ + static vec4 ms_GuiColor; + static vec4 ms_ColorTabbarInactiveOutgame; + static vec4 ms_ColorTabbarActiveOutgame; + static vec4 ms_ColorTabbarInactiveIngame; + static vec4 ms_ColorTabbarActiveIngame; + static vec4 ms_ColorTabbarInactive; + static vec4 ms_ColorTabbarActive; + + vec4 ButtonColorMul(const void *pID); + + + int DoButton_DemoPlayer(const void *pID, const char *pText, int Checked, const CUIRect *pRect); + int DoButton_Menu(const void *pID, const char *pText, int Checked, const CUIRect *pRect); + int DoButton_MenuTab(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Corners); + int DoButton_SettingsTab(const void *pID, const char *pText, int Checked, const CUIRect *pRect); + + int DoButton_CheckBox_Common(const void *pID, const char *pText, const char *pBoxText, const CUIRect *pRect); + int DoButton_CheckBox(const void *pID, const char *pText, int Checked, const CUIRect *pRect); + int DoButton_CheckBox_Number(const void *pID, const char *pText, int Checked, const CUIRect *pRect); + + /*static void ui_draw_menu_button(const void *id, const char *text, int checked, const CUIRect *r, const void *extra); + static void ui_draw_keyselect_button(const void *id, const char *text, int checked, const CUIRect *r, const void *extra); + static void ui_draw_menu_tab_button(const void *id, const char *text, int checked, const CUIRect *r, const void *extra); + static void ui_draw_settings_tab_button(const void *id, const char *text, int checked, const CUIRect *r, const void *extra); + */ + + int DoButton_BrowseIcon(int Checked, const CUIRect *pRect); + int DoButton_GridHeader(const void *pID, const char *pText, int Checked, const CUIRect *pRect); + int DoButton_ListRow(const void *pID, const char *pText, int Checked, const CUIRect *pRect); + + //static void ui_draw_browse_icon(int what, const CUIRect *r); + //static void ui_draw_grid_header(const void *id, const char *text, int checked, const CUIRect *r, const void *extra); + + /*static void ui_draw_checkbox_common(const void *id, const char *text, const char *boxtext, const CUIRect *r, const void *extra); + static void ui_draw_checkbox(const void *id, const char *text, int checked, const CUIRect *r, const void *extra); + static void ui_draw_checkbox_number(const void *id, const char *text, int checked, const CUIRect *r, const void *extra); + */ + int DoEditBox(void *pID, const CUIRect *pRect, char *pStr, unsigned StrSize, float FontSize, bool Hidden=false, int Corners=CUI::CORNER_ALL); + //static int ui_do_edit_box(void *id, const CUIRect *rect, char *str, unsigned str_size, float font_size, bool hidden=false); + + float DoScrollbarV(const void *pID, const CUIRect *pRect, float Current); + float DoScrollbarH(const void *pID, const CUIRect *pRect, float Current); + void DoButton_KeySelect(const void *pID, const char *pText, int Checked, const CUIRect *pRect); + int DoKeyReader(void *pID, const CUIRect *pRect, int Key); + + //static int ui_do_key_reader(void *id, const CUIRect *rect, int key); + void UiDoGetButtons(int Start, int Stop, CUIRect View); + + struct CListboxItem + { + int m_Visible; + int m_Selected; + CUIRect m_Rect; + CUIRect m_HitRect; + }; + + void UiDoListboxStart(void *pId, const CUIRect *pRect, float RowHeight, const char *pTitle, const char *pBottomText, int NumItems, + int ItemsPerRow, int SelectedIndex, float ScrollValue); + CListboxItem UiDoListboxNextItem(void *pID, bool Selected = false); + static CListboxItem UiDoListboxNextRow(); + int UiDoListboxEnd(float *pScrollValue, bool *pItemActivated); + + //static void demolist_listdir_callback(const char *name, int is_dir, void *user); + //static void demolist_list_callback(const CUIRect *rect, int index, void *user); + + enum + { + POPUP_NONE=0, + POPUP_FIRST_LAUNCH, + POPUP_CONNECTING, + POPUP_MESSAGE, + POPUP_DISCONNECTED, + POPUP_PURE, + POPUP_PASSWORD, + POPUP_QUIT, + }; + + enum + { + PAGE_NEWS=1, + PAGE_GAME, + PAGE_SERVER_INFO, + PAGE_CALLVOTE, + PAGE_INTERNET, + PAGE_LAN, + PAGE_FAVORITES, + PAGE_DEMOS, + PAGE_SETTINGS, + PAGE_SYSTEM, + }; + + int m_GamePage; + int m_Popup; + int m_ActivePage; + bool m_MenuActive; + bool m_UseMouseButtons; + vec2 m_MousePos; + + int64 m_LastInput; + + // + char m_aMessageTopic[512]; + char m_aMessageBody[512]; + char m_aMessageButton[512]; + + void PopupMessage(const char *pTopic, const char *pBody, const char *pButton); + + // TODO: this is a bit ugly but.. well.. yeah + enum { MAX_INPUTEVENTS = 32 }; + static IInput::CEvent m_aInputEvents[MAX_INPUTEVENTS]; + static int m_NumInputEvents; + + // some settings + static float ms_ButtonHeight; + static float ms_ListheaderHeight; + static float ms_FontmodHeight; + + // for graphic settings + bool m_NeedRestart; + bool m_NeedSendinfo; + + // + bool m_EscapePressed; + bool m_EnterPressed; + + // for call vote + int m_CallvoteSelectedOption; + int m_CallvoteSelectedPlayer; + + // demo + struct CDemoItem + { + char m_aFilename[512]; + char m_aName[256]; + + bool operator<(const CDemoItem &Other) { return str_comp(m_aName, Other.m_aName) < 0; } + }; + + sorted_array<CDemoItem> m_lDemos; + + void DemolistPopulate(); + static void DemolistCountCallback(const char *pName, int IsDir, void *pUser); + static void DemolistFetchCallback(const char *pName, int IsDir, void *pUser); + + // found in menus.cpp + int Render(); + //void render_background(); + //void render_loading(float percent); + int RenderMenubar(CUIRect r); + void RenderNews(CUIRect MainView); + + // found in menus_demo.cpp + void RenderDemoPlayer(CUIRect MainView); + void RenderDemoList(CUIRect MainView); + + // found in menus_ingame.cpp + void RenderGame(CUIRect MainView); + void RenderServerInfo(CUIRect MainView); + void RenderServerControl(CUIRect MainView); + void RenderServerControlKick(CUIRect MainView); + void RenderServerControlServer(CUIRect MainView); + + // found in menus_browser.cpp + int m_SelectedIndex; + void RenderServerbrowserServerList(CUIRect View); + void RenderServerbrowserServerDetail(CUIRect View); + void RenderServerbrowserFilters(CUIRect View); + void RenderServerbrowser(CUIRect MainView); + + // found in menus_settings.cpp + void RenderSettingsGeneral(CUIRect MainView); + void RenderSettingsPlayer(CUIRect MainView); + void RenderSettingsControls(CUIRect MainView); + void RenderSettingsGraphics(CUIRect MainView); + void RenderSettingsSound(CUIRect MainView); + void RenderSettings(CUIRect MainView); + + void SetActive(bool Active); +public: + void RenderBackground(); + + void UseMouseButtons(bool Use) { m_UseMouseButtons = Use; } + + static CMenusKeyBinder m_Binder; + + CMenus(); + + void RenderLoading(float Percent); + + bool IsActive() const { return m_MenuActive; } + + virtual void OnInit(); + + virtual void OnStateChange(int NewState, int OldState); + virtual void OnReset(); + virtual void OnRender(); + virtual bool OnInput(IInput::CEvent Event); + virtual bool OnMouseMove(float x, float y); +}; +#endif diff --git a/src/game/client/components/menus.hpp b/src/game/client/components/menus.hpp deleted file mode 100644 index 02759403..00000000 --- a/src/game/client/components/menus.hpp +++ /dev/null @@ -1,216 +0,0 @@ -#include <base/vmath.hpp> -#include <base/tl/sorted_array.hpp> - -#include <game/client/component.hpp> -#include <game/client/ui.hpp> - - -// compnent to fetch keypresses, override all other input -class MENUS_KEYBINDER : public COMPONENT -{ -public: - bool take_key; - bool got_key; - INPUT_EVENT key; - MENUS_KEYBINDER(); - virtual bool on_input(INPUT_EVENT e); -}; - -class MENUS : public COMPONENT -{ - static vec4 gui_color; - static vec4 color_tabbar_inactive_outgame; - static vec4 color_tabbar_active_outgame; - static vec4 color_tabbar_inactive_ingame; - static vec4 color_tabbar_active_ingame; - static vec4 color_tabbar_inactive; - static vec4 color_tabbar_active; - - vec4 button_color_mul(const void *pID); - - - int DoButton_DemoPlayer(const void *pID, const char *pText, int Checked, const CUIRect *pRect); - int DoButton_Menu(const void *pID, const char *pText, int Checked, const CUIRect *pRect); - int DoButton_MenuTab(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Corners); - int DoButton_SettingsTab(const void *pID, const char *pText, int Checked, const CUIRect *pRect); - - int DoButton_CheckBox_Common(const void *pID, const char *pText, const char *pBoxText, const CUIRect *pRect); - int DoButton_CheckBox(const void *pID, const char *pText, int Checked, const CUIRect *pRect); - int DoButton_CheckBox_Number(const void *pID, const char *pText, int Checked, const CUIRect *pRect); - - /*static void ui_draw_menu_button(const void *id, const char *text, int checked, const CUIRect *r, const void *extra); - static void ui_draw_keyselect_button(const void *id, const char *text, int checked, const CUIRect *r, const void *extra); - static void ui_draw_menu_tab_button(const void *id, const char *text, int checked, const CUIRect *r, const void *extra); - static void ui_draw_settings_tab_button(const void *id, const char *text, int checked, const CUIRect *r, const void *extra); - */ - - int DoButton_BrowseIcon(int Checked, const CUIRect *pRect); - int DoButton_GridHeader(const void *pID, const char *pText, int Checked, const CUIRect *pRect); - int DoButton_ListRow(const void *pID, const char *pText, int Checked, const CUIRect *pRect); - - //static void ui_draw_browse_icon(int what, const CUIRect *r); - //static void ui_draw_grid_header(const void *id, const char *text, int checked, const CUIRect *r, const void *extra); - - /*static void ui_draw_checkbox_common(const void *id, const char *text, const char *boxtext, const CUIRect *r, const void *extra); - static void ui_draw_checkbox(const void *id, const char *text, int checked, const CUIRect *r, const void *extra); - static void ui_draw_checkbox_number(const void *id, const char *text, int checked, const CUIRect *r, const void *extra); - */ - int DoEditBox(void *pID, const CUIRect *pRect, char *pStr, unsigned StrSize, float FontSize, bool Hidden=false); - //static int ui_do_edit_box(void *id, const CUIRect *rect, char *str, unsigned str_size, float font_size, bool hidden=false); - - float DoScrollbarV(const void *pID, const CUIRect *pRect, float Current); - float DoScrollbarH(const void *pID, const CUIRect *pRect, float Current); - int DoButton_KeySelect(const void *pID, const char *pText, int Checked, const CUIRect *pRect); - int DoKeyReader(void *pID, const CUIRect *pRect, int Key); - - //static int ui_do_key_reader(void *id, const CUIRect *rect, int key); - void ui_do_getbuttons(int start, int stop, CUIRect view); - - struct LISTBOXITEM - { - int visible; - int selected; - CUIRect rect; - CUIRect hitrect; - }; - - void ui_do_listbox_start(void *id, const CUIRect *rect, float row_height, const char *title, int num_items, int selected_index); - LISTBOXITEM ui_do_listbox_nextitem(void *id); - static LISTBOXITEM ui_do_listbox_nextrow(); - int ui_do_listbox_end(); - - //static void demolist_listdir_callback(const char *name, int is_dir, void *user); - //static void demolist_list_callback(const RECT *rect, int index, void *user); - - enum - { - POPUP_NONE=0, - POPUP_FIRST_LAUNCH, - POPUP_CONNECTING, - POPUP_MESSAGE, - POPUP_DISCONNECTED, - POPUP_PURE, - POPUP_PASSWORD, - POPUP_QUIT, - }; - - enum - { - PAGE_NEWS=1, - PAGE_GAME, - PAGE_SERVER_INFO, - PAGE_CALLVOTE, - PAGE_INTERNET, - PAGE_LAN, - PAGE_FAVORITES, - PAGE_DEMOS, - PAGE_SETTINGS, - PAGE_SYSTEM, - }; - - int game_page; - int popup; - int active_page; - bool menu_active; - vec2 mouse_pos; - - int64 last_input; - - // - char message_topic[512]; - char message_body[512]; - char message_button[512]; - - void popup_message(const char *topic, const char *body, const char *button); - - // TODO: this is a bit ugly but.. well.. yeah - enum { MAX_INPUTEVENTS = 32 }; - static INPUT_EVENT inputevents[MAX_INPUTEVENTS]; - static int num_inputevents; - - // some settings - static float button_height; - static float listheader_height; - static float fontmod_height; - - // for graphic settings - bool need_restart; - bool need_sendinfo; - - // - bool escape_pressed; - bool enter_pressed; - - // for call vote - int callvote_selectedoption; - int callvote_selectedplayer; - - // demo - struct DEMOITEM - { - char filename[512]; - char name[256]; - - bool operator<(const DEMOITEM &other) { return str_comp(name, other.name) < 0; } - }; - - sorted_array<DEMOITEM> demos; - - void demolist_populate(); - static void demolist_count_callback(const char *name, int is_dir, void *user); - static void demolist_fetch_callback(const char *name, int is_dir, void *user); - - // found in menus.cpp - int render(); - //void render_background(); - //void render_loading(float percent); - int render_menubar(CUIRect r); - void render_news(CUIRect main_view); - - // found in menus_demo.cpp - void render_demoplayer(CUIRect main_view); - void render_demolist(CUIRect main_view); - - // found in menus_ingame.cpp - void render_game(CUIRect main_view); - void render_serverinfo(CUIRect main_view); - void render_servercontrol(CUIRect main_view); - void render_servercontrol_kick(CUIRect main_view); - void render_servercontrol_server(CUIRect main_view); - - // found in menus_browser.cpp - int selected_index; - void render_serverbrowser_serverlist(CUIRect view); - void render_serverbrowser_serverdetail(CUIRect view); - void render_serverbrowser_filters(CUIRect view); - void render_serverbrowser(CUIRect main_view); - - // found in menus_settings.cpp - void render_settings_general(CUIRect main_view); - void render_settings_player(CUIRect main_view); - void render_settings_controls(CUIRect main_view); - void render_settings_graphics(CUIRect main_view); - void render_settings_sound(CUIRect main_view); - void render_settings(CUIRect main_view); - - void set_active(bool active); -public: - void render_background(); - - - static MENUS_KEYBINDER binder; - - MENUS(); - - void render_loading(float percent); - - bool is_active() const { return menu_active; } - - virtual void on_init(); - - virtual void on_statechange(int new_state, int old_state); - virtual void on_reset(); - virtual void on_render(); - virtual bool on_input(INPUT_EVENT e); - virtual bool on_mousemove(float x, float y); -}; diff --git a/src/game/client/components/menus_browser.cpp b/src/game/client/components/menus_browser.cpp index dcf68f8d..0a737052 100644 --- a/src/game/client/components/menus_browser.cpp +++ b/src/game/client/components/menus_browser.cpp @@ -1,46 +1,45 @@ +#include <engine/serverbrowser.h> +#include <engine/textrender.h> +#include <engine/keys.h> +#include <engine/shared/config.h> +#include <game/generated/protocol.h> +#include <game/generated/client_data.h> + +#include <game/client/ui.h> +#include <game/client/render.h> +#include "menus.h" +#include <game/localization.h> +#include <game/version.h> + +void CMenus::RenderServerbrowserServerList(CUIRect View) +{ + CUIRect Headers; + CUIRect Status; -#include <string.h> // strcmp, strlen, strncpy -#include <stdlib.h> // atoi - -#include <engine/e_client_interface.h> -#include <game/generated/g_protocol.hpp> -#include <game/generated/gc_data.hpp> - -#include <game/client/ui.hpp> -#include <game/client/render.hpp> -#include "menus.hpp" -#include <game/localization.hpp> -#include <game/version.hpp> + View.HSplitTop(ms_ListheaderHeight, &Headers, &View); + View.HSplitBottom(28.0f, &View, &Status); -void MENUS::render_serverbrowser_serverlist(CUIRect view) -{ - CUIRect headers; - CUIRect status; - - view.HSplitTop(listheader_height, &headers, &view); - view.HSplitBottom(28.0f, &view, &status); - // split of the scrollbar - RenderTools()->DrawUIRect(&headers, vec4(1,1,1,0.25f), CUI::CORNER_T, 5.0f); - headers.VSplitRight(20.0f, &headers, 0); - - struct column + RenderTools()->DrawUIRect(&Headers, vec4(1,1,1,0.25f), CUI::CORNER_T, 5.0f); + Headers.VSplitRight(20.0f, &Headers, 0); + + struct CColumn { - int id; - int sort; - LOC_CONSTSTRING caption; - int direction; - float width; - int flags; - CUIRect rect; - CUIRect spacer; + int m_Id; + int m_Sort; + CLocConstString m_Caption; + int m_Direction; + float m_Width; + int m_Flags; + CUIRect m_Rect; + CUIRect m_Spacer; }; - + enum { FIXED=1, SPACER=2, - + COL_FLAG_LOCK=0, COL_FLAG_PURE, COL_FLAG_FAV, @@ -51,494 +50,542 @@ void MENUS::render_serverbrowser_serverlist(CUIRect view) COL_PING, COL_VERSION, }; - - static column cols[] = { + + static CColumn s_aCols[] = { {-1, -1, " ", -1, 2.0f, 0, {0}, {0}}, {COL_FLAG_LOCK, -1, " ", -1, 14.0f, 0, {0}, {0}}, {COL_FLAG_PURE, -1, " ", -1, 14.0f, 0, {0}, {0}}, {COL_FLAG_FAV, -1, " ", -1, 14.0f, 0, {0}, {0}}, - {COL_NAME, BROWSESORT_NAME, localize("Name"), 0, 300.0f, 0, {0}, {0}}, - {COL_GAMETYPE, BROWSESORT_GAMETYPE, localize("Type"), 1, 50.0f, 0, {0}, {0}}, - {COL_MAP, BROWSESORT_MAP, localize("Map"), 1, 100.0f, 0, {0}, {0}}, - {COL_PLAYERS, BROWSESORT_NUMPLAYERS, localize("Players"), 1, 60.0f, 0, {0}, {0}}, + {COL_NAME, IServerBrowser::SORT_NAME, Localize("Name"), 0, 300.0f, 0, {0}, {0}}, + {COL_GAMETYPE, IServerBrowser::SORT_GAMETYPE, Localize("Type"), 1, 50.0f, 0, {0}, {0}}, + {COL_MAP, IServerBrowser::SORT_MAP, Localize("Map"), 1, 100.0f, 0, {0}, {0}}, + {COL_PLAYERS, IServerBrowser::SORT_NUMPLAYERS, Localize("Players"), 1, 60.0f, 0, {0}, {0}}, {-1, -1, " ", 1, 10.0f, 0, {0}, {0}}, - {COL_PING, BROWSESORT_PING, localize("Ping"), 1, 40.0f, FIXED, {0}, {0}}, + {COL_PING, IServerBrowser::SORT_PING, Localize("Ping"), 1, 40.0f, FIXED, {0}, {0}}, }; - - int num_cols = sizeof(cols)/sizeof(column); - + + int NumCols = sizeof(s_aCols)/sizeof(CColumn); + // do layout - for(int i = 0; i < num_cols; i++) + for(int i = 0; i < NumCols; i++) { - if(cols[i].direction == -1) + if(s_aCols[i].m_Direction == -1) { - headers.VSplitLeft(cols[i].width, &cols[i].rect, &headers); - - if(i+1 < num_cols) + Headers.VSplitLeft(s_aCols[i].m_Width, &s_aCols[i].m_Rect, &Headers); + + if(i+1 < NumCols) { - //cols[i].flags |= SPACER; - headers.VSplitLeft(2, &cols[i].spacer, &headers); + //Cols[i].flags |= SPACER; + Headers.VSplitLeft(2, &s_aCols[i].m_Spacer, &Headers); } } } - - for(int i = num_cols-1; i >= 0; i--) + + for(int i = NumCols-1; i >= 0; i--) { - if(cols[i].direction == 1) + if(s_aCols[i].m_Direction == 1) { - headers.VSplitRight(cols[i].width, &headers, &cols[i].rect); - headers.VSplitRight(2, &headers, &cols[i].spacer); + Headers.VSplitRight(s_aCols[i].m_Width, &Headers, &s_aCols[i].m_Rect); + Headers.VSplitRight(2, &Headers, &s_aCols[i].m_Spacer); } } - - for(int i = 0; i < num_cols; i++) + + for(int i = 0; i < NumCols; i++) { - if(cols[i].direction == 0) - cols[i].rect = headers; + if(s_aCols[i].m_Direction == 0) + s_aCols[i].m_Rect = Headers; } - + // do headers - for(int i = 0; i < num_cols; i++) + for(int i = 0; i < NumCols; i++) { - if(DoButton_GridHeader(cols[i].caption, cols[i].caption, config.b_sort == cols[i].sort, &cols[i].rect)) + if(DoButton_GridHeader(s_aCols[i].m_Caption, s_aCols[i].m_Caption, g_Config.m_BrSort == s_aCols[i].m_Sort, &s_aCols[i].m_Rect)) { - if(cols[i].sort != -1) + if(s_aCols[i].m_Sort != -1) { - if(config.b_sort == cols[i].sort) - config.b_sort_order ^= 1; + if(g_Config.m_BrSort == s_aCols[i].m_Sort) + g_Config.m_BrSortOrder ^= 1; else - config.b_sort_order = 0; - config.b_sort = cols[i].sort; + g_Config.m_BrSortOrder = 0; + g_Config.m_BrSort = s_aCols[i].m_Sort; } } } - - RenderTools()->DrawUIRect(&view, vec4(0,0,0,0.15f), 0, 0); - - CUIRect scroll; - view.VSplitRight(15, &view, &scroll); - - int num_servers = client_serverbrowse_sorted_num(); - + + RenderTools()->DrawUIRect(&View, vec4(0,0,0,0.15f), 0, 0); + + CUIRect Scroll; + View.VSplitRight(15, &View, &Scroll); + + int NumServers = ServerBrowser()->NumSortedServers(); + // display important messages in the middle of the screen so no // users misses it { - CUIRect msgbox = view; - msgbox.y += view.h/3; - - if(active_page == PAGE_INTERNET && client_serverbrowse_refreshingmasters()) - UI()->DoLabel(&msgbox, localize("Refreshing master servers"), 16.0f, 0); - else if(!client_serverbrowse_num()) - UI()->DoLabel(&msgbox, localize("No servers found"), 16.0f, 0); - else if(client_serverbrowse_num() && !num_servers) - UI()->DoLabel(&msgbox, localize("No servers match your filter criteria"), 16.0f, 0); + CUIRect MsgBox = View; + MsgBox.y += View.h/3; + + if(m_ActivePage == PAGE_INTERNET && ServerBrowser()->IsRefreshingMasters()) + UI()->DoLabel(&MsgBox, Localize("Refreshing master servers"), 16.0f, 0); + else if(!ServerBrowser()->NumServers()) + UI()->DoLabel(&MsgBox, Localize("No servers found"), 16.0f, 0); + else if(ServerBrowser()->NumServers() && !NumServers) + UI()->DoLabel(&MsgBox, Localize("No servers match your filter criteria"), 16.0f, 0); } - int num = (int)(view.h/cols[0].rect.h); - static int scrollbar = 0; - static float scrollvalue = 0; - //static int selected_index = -1; - scroll.HMargin(5.0f, &scroll); - scrollvalue = DoScrollbarV(&scrollbar, &scroll, scrollvalue); - - int scrollnum = num_servers-num+10; - if(scrollnum > 0) + int Num = (int)(View.h/s_aCols[0].m_Rect.h); + static int s_ScrollBar = 0; + static float s_ScrollValue = 0; + + Scroll.HMargin(5.0f, &Scroll); + s_ScrollValue = DoScrollbarV(&s_ScrollBar, &Scroll, s_ScrollValue); + + int ScrollNum = NumServers-Num+10; + if(ScrollNum > 0) { - if(inp_key_presses(KEY_MOUSE_WHEEL_UP)) - scrollvalue -= 1.0f/scrollnum; - if(inp_key_presses(KEY_MOUSE_WHEEL_DOWN)) - scrollvalue += 1.0f/scrollnum; - - if(scrollvalue < 0) scrollvalue = 0; - if(scrollvalue > 1) scrollvalue = 1; + if(Input()->KeyPresses(KEY_MOUSE_WHEEL_UP)) + s_ScrollValue -= 1.0f/ScrollNum; + if(Input()->KeyPresses(KEY_MOUSE_WHEEL_DOWN)) + s_ScrollValue += 1.0f/ScrollNum; } else - scrollnum = 0; + ScrollNum = 0; + + if(m_SelectedIndex > -1) + { + for(int i = 0; i < m_NumInputEvents; i++) + { + int NewIndex = -1; + if(m_aInputEvents[i].m_Flags&IInput::FLAG_PRESS) + { + if(m_aInputEvents[i].m_Key == KEY_DOWN) NewIndex = m_SelectedIndex + 1; + if(m_aInputEvents[i].m_Key == KEY_UP) NewIndex = m_SelectedIndex - 1; + } + if(NewIndex > -1 && NewIndex < NumServers) + { + //scroll + if(ScrollNum) + { + if(NewIndex - m_SelectedIndex > 0) + s_ScrollValue += 1.0f/ScrollNum; + else + s_ScrollValue -= 1.0f/ScrollNum; + } + + m_SelectedIndex = NewIndex; + + const CServerInfo *pItem = ServerBrowser()->SortedGet(m_SelectedIndex); + str_copy(g_Config.m_UiServerAddress, pItem->m_aAddress, sizeof(g_Config.m_UiServerAddress)); + } + } + } + + if(s_ScrollValue < 0) s_ScrollValue = 0; + if(s_ScrollValue > 1) s_ScrollValue = 1; // set clipping - UI()->ClipEnable(&view); - - int start = (int)(scrollnum*scrollvalue); - if(start < 0) - start = 0; - - CUIRect original_view = view; - view.y -= scrollvalue*scrollnum*cols[0].rect.h; - - int new_selected = -1; - int num_players = 0; + UI()->ClipEnable(&View); + + CUIRect OriginalView = View; + View.y -= s_ScrollValue*ScrollNum*s_aCols[0].m_Rect.h; - selected_index = -1; + int NewSelected = -1; + int NumPlayers = 0; - for (int i = 0; i < num_servers; i++) + m_SelectedIndex = -1; + + for (int i = 0; i < NumServers; i++) { - SERVER_INFO *item = client_serverbrowse_sorted_get(i); - num_players += item->num_players; + const CServerInfo *pItem = ServerBrowser()->SortedGet(i); + NumPlayers += pItem->m_NumPlayers; } - - for (int i = 0; i < num_servers; i++) + + for (int i = 0; i < NumServers; i++) { - int item_index = i; - SERVER_INFO *item = client_serverbrowse_sorted_get(item_index); - CUIRect row; - CUIRect select_hit_box; - - int selected = strcmp(item->address, config.ui_server_address) == 0; //selected_index==item_index; - - view.HSplitTop(17.0f, &row, &view); - select_hit_box = row; - - if(selected) - { - selected_index = i; - CUIRect r = row; - r.Margin(1.5f, &r); - RenderTools()->DrawUIRect(&r, vec4(1,1,1,0.5f), CUI::CORNER_ALL, 4.0f); - } + int ItemIndex = i; + const CServerInfo *pItem = ServerBrowser()->SortedGet(ItemIndex); + CUIRect Row; + CUIRect SelectHitBox; + + int Selected = str_comp(pItem->m_aAddress, g_Config.m_UiServerAddress) == 0; //selected_index==ItemIndex; + View.HSplitTop(17.0f, &Row, &View); + SelectHitBox = Row; + + if(Selected) + m_SelectedIndex = i; // make sure that only those in view can be selected - if(row.y+row.h > original_view.y) + if(Row.y+Row.h > OriginalView.y && Row.y < OriginalView.y+OriginalView.h) { - if(select_hit_box.y < original_view.y) // clip the selection + if(Selected) + { + CUIRect r = Row; + r.Margin(1.5f, &r); + RenderTools()->DrawUIRect(&r, vec4(1,1,1,0.5f), CUI::CORNER_ALL, 4.0f); + } + + // clip the selection + if(SelectHitBox.y < OriginalView.y) // top { - select_hit_box.h -= original_view.y-select_hit_box.y; - select_hit_box.y = original_view.y; + SelectHitBox.h -= OriginalView.y-SelectHitBox.y; + SelectHitBox.y = OriginalView.y; } - - if(UI()->DoButtonLogic(item, "", selected, &select_hit_box)) + else if(SelectHitBox.y+SelectHitBox.h > OriginalView.y+OriginalView.h) // bottom + SelectHitBox.h = OriginalView.y+OriginalView.h-SelectHitBox.y; + + if(UI()->DoButtonLogic(pItem, "", Selected, &SelectHitBox)) { - new_selected = item_index; + NewSelected = ItemIndex; } } - - // check if we need to do more - if(row.y > original_view.y+original_view.h) - break; + else + { + // reset active item, if not visible + if(UI()->ActiveItem() == pItem) + UI()->SetActiveItem(0); - for(int c = 0; c < num_cols; c++) + // don't render invisible items + continue; + } + + for(int c = 0; c < NumCols; c++) { - CUIRect button; - char temp[64]; - button.x = cols[c].rect.x; - button.y = row.y; - button.h = row.h; - button.w = cols[c].rect.w; - - //int s = 0; - int id = cols[c].id; - - //s = UI()->DoButton(item, "L", l, &button, ui_draw_browse_icon, 0); - - if(id == COL_FLAG_LOCK) + CUIRect Button; + char aTemp[64]; + Button.x = s_aCols[c].m_Rect.x; + Button.y = Row.y; + Button.h = Row.h; + Button.w = s_aCols[c].m_Rect.w; + + int Id = s_aCols[c].m_Id; + + if(Id == COL_FLAG_LOCK) { - if(item->flags & SRVFLAG_PASSWORD) - DoButton_BrowseIcon(SPRITE_BROWSE_LOCK, &button); + if(pItem->m_Flags & SERVER_FLAG_PASSWORD) + DoButton_BrowseIcon(SPRITE_BROWSE_LOCK, &Button); } - else if(id == COL_FLAG_PURE) + else if(Id == COL_FLAG_PURE) { - if(strcmp(item->gametype, "DM") == 0 || strcmp(item->gametype, "TDM") == 0 || strcmp(item->gametype, "CTF") == 0) + if( str_comp(pItem->m_aGameType, "DM") == 0 || + str_comp(pItem->m_aGameType, "TDM") == 0 || + str_comp(pItem->m_aGameType, "CTF") == 0) { // pure server } else { // unpure - DoButton_BrowseIcon(SPRITE_BROWSE_UNPURE, &button); + DoButton_BrowseIcon(SPRITE_BROWSE_UNPURE, &Button); } } - else if(id == COL_FLAG_FAV) + else if(Id == COL_FLAG_FAV) { - if(item->favorite) - DoButton_BrowseIcon(SPRITE_BROWSE_HEART, &button); + if(pItem->m_Favorite) + DoButton_BrowseIcon(SPRITE_BROWSE_HEART, &Button); } - else if(id == COL_NAME) + else if(Id == COL_NAME) { - TEXT_CURSOR cursor; - gfx_text_set_cursor(&cursor, button.x, button.y, 12.0f, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END); - cursor.line_width = button.w; - - if(config.b_filter_string[0] && (item->quicksearch_hit&BROWSEQUICK_SERVERNAME)) + CTextCursor Cursor; + TextRender()->SetCursor(&Cursor, Button.x, Button.y, 12.0f, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END); + Cursor.m_LineWidth = Button.w; + + if(g_Config.m_BrFilterString[0] && (pItem->m_QuickSearchHit&IServerBrowser::QUICK_SERVERNAME)) { // highlight the parts that matches - const char *s = str_find_nocase(item->name, config.b_filter_string); + const char *s = str_find_nocase(pItem->m_aName, g_Config.m_BrFilterString); if(s) { - gfx_text_ex(&cursor, item->name, (int)(s-item->name)); - gfx_text_color(0.4f,0.4f,1.0f,1); - gfx_text_ex(&cursor, s, strlen(config.b_filter_string)); - gfx_text_color(1,1,1,1); - gfx_text_ex(&cursor, s+strlen(config.b_filter_string), -1); + TextRender()->TextEx(&Cursor, pItem->m_aName, (int)(s-pItem->m_aName)); + TextRender()->TextColor(0.4f,0.4f,1.0f,1); + TextRender()->TextEx(&Cursor, s, str_length(g_Config.m_BrFilterString)); + TextRender()->TextColor(1,1,1,1); + TextRender()->TextEx(&Cursor, s+str_length(g_Config.m_BrFilterString), -1); } else - gfx_text_ex(&cursor, item->name, -1); + TextRender()->TextEx(&Cursor, pItem->m_aName, -1); } else - gfx_text_ex(&cursor, item->name, -1); + TextRender()->TextEx(&Cursor, pItem->m_aName, -1); } - else if(id == COL_MAP) - UI()->DoLabel(&button, item->map, 12.0f, -1); - else if(id == COL_PLAYERS) + else if(Id == COL_MAP) + UI()->DoLabel(&Button, pItem->m_aMap, 12.0f, -1); + else if(Id == COL_PLAYERS) { - str_format(temp, sizeof(temp), "%i/%i", item->num_players, item->max_players); - if(config.b_filter_string[0] && (item->quicksearch_hit&BROWSEQUICK_PLAYERNAME)) - gfx_text_color(0.4f,0.4f,1.0f,1); - UI()->DoLabel(&button, temp, 12.0f, 1); - gfx_text_color(1,1,1,1); + str_format(aTemp, sizeof(aTemp), "%i/%i", pItem->m_NumPlayers, pItem->m_MaxPlayers); + if(g_Config.m_BrFilterString[0] && (pItem->m_QuickSearchHit&IServerBrowser::QUICK_PLAYERNAME)) + TextRender()->TextColor(0.4f,0.4f,1.0f,1); + UI()->DoLabel(&Button, aTemp, 12.0f, 1); + TextRender()->TextColor(1,1,1,1); } - else if(id == COL_PING) + else if(Id == COL_PING) { - str_format(temp, sizeof(temp), "%i", item->latency); - UI()->DoLabel(&button, temp, 12.0f, 1); + str_format(aTemp, sizeof(aTemp), "%i", pItem->m_Latency); + UI()->DoLabel(&Button, aTemp, 12.0f, 1); } - else if(id == COL_VERSION) + else if(Id == COL_VERSION) { - const char *version = item->version; - if(strcmp(version, "0.3 e2d7973c6647a13c") == 0) // TODO: remove me later on - version = "0.3.0"; - UI()->DoLabel(&button, version, 12.0f, 1); - } - else if(id == COL_GAMETYPE) + const char *pVersion = pItem->m_aVersion; + if(str_comp(pVersion, "0.3 e2d7973c6647a13c") == 0) // TODO: remove me later on + pVersion = "0.3.0"; + UI()->DoLabel(&Button, pVersion, 12.0f, 1); + } + else if(Id == COL_GAMETYPE) { - UI()->DoLabel(&button, item->gametype, 12.0f, 0); + UI()->DoLabel(&Button, pItem->m_aGameType, 12.0f, 0); } } } UI()->ClipDisable(); - - if(new_selected != -1) + + if(NewSelected != -1) { // select the new server - SERVER_INFO *item = client_serverbrowse_sorted_get(new_selected); - strncpy(config.ui_server_address, item->address, sizeof(config.ui_server_address)); - if(inp_mouse_doubleclick()) - client_connect(config.ui_server_address); + const CServerInfo *pItem = ServerBrowser()->SortedGet(NewSelected); + str_copy(g_Config.m_UiServerAddress, pItem->m_aAddress, sizeof(g_Config.m_UiServerAddress)); + if(Input()->MouseDoubleClick()) + Client()->Connect(g_Config.m_UiServerAddress); } - RenderTools()->DrawUIRect(&status, vec4(1,1,1,0.25f), CUI::CORNER_B, 5.0f); - status.Margin(5.0f, &status); - + RenderTools()->DrawUIRect(&Status, vec4(1,1,1,0.25f), CUI::CORNER_B, 5.0f); + Status.Margin(5.0f, &Status); + // render quick search - CUIRect quicksearch; - status.VSplitLeft(250.0f, &quicksearch, &status); - const char *label = localize("Quick search"); - UI()->DoLabel(&quicksearch, label, 14.0f, -1); - quicksearch.VSplitLeft(gfx_text_width(0, 14.0f, label, -1), 0, &quicksearch); - quicksearch.VSplitLeft(5, 0, &quicksearch); - DoEditBox(&config.b_filter_string, &quicksearch, config.b_filter_string, sizeof(config.b_filter_string), 14.0f); - + CUIRect QuickSearch, Button; + Status.VSplitLeft(260.0f, &QuickSearch, &Status); + const char *pLabel = Localize("Quick search:"); + UI()->DoLabel(&QuickSearch, pLabel, 12.0f, -1); + QuickSearch.VSplitLeft(TextRender()->TextWidth(0, 12.0f, pLabel, -1), 0, &QuickSearch); + QuickSearch.VSplitLeft(5.0f, 0, &QuickSearch); + QuickSearch.VSplitLeft(155.0f, &QuickSearch, &Button); + DoEditBox(&g_Config.m_BrFilterString, &QuickSearch, g_Config.m_BrFilterString, sizeof(g_Config.m_BrFilterString), 12.0f, false, CUI::CORNER_L); + // clear button + { + static int s_ClearButton = 0; + RenderTools()->DrawUIRect(&Button, vec4(1,1,1,0.33f)*ButtonColorMul(&s_ClearButton), CUI::CORNER_R, 3.0f); + UI()->DoLabel(&Button, "x", Button.h*ms_FontmodHeight, 0); + if(UI()->DoButtonLogic(&s_ClearButton, "x", 0, &Button)) + { + g_Config.m_BrFilterString[0] = 0; + UI()->SetActiveItem(&g_Config.m_BrFilterString); + } + } + // render status - char buf[128]; - str_format(buf, sizeof(buf), localize("%d of %d servers, %d players"), client_serverbrowse_sorted_num(), client_serverbrowse_num(), num_players); - status.VSplitRight(gfx_text_width(0, 14.0f, buf, -1), 0, &status); - UI()->DoLabel(&status, buf, 14.0f, -1); + char aBuf[128]; + str_format(aBuf, sizeof(aBuf), Localize("%d of %d servers, %d players"), ServerBrowser()->NumSortedServers(), ServerBrowser()->NumServers(), NumPlayers); + Status.VSplitRight(TextRender()->TextWidth(0, 14.0f, aBuf, -1), 0, &Status); + UI()->DoLabel(&Status, aBuf, 14.0f, -1); } -void MENUS::render_serverbrowser_filters(CUIRect view) +void CMenus::RenderServerbrowserFilters(CUIRect View) { // filters - CUIRect button; + CUIRect Button; - view.HSplitTop(5.0f, 0, &view); - view.VSplitLeft(5.0f, 0, &view); - view.VSplitRight(5.0f, &view, 0); - view.HSplitBottom(5.0f, &view, 0); + View.HSplitTop(5.0f, 0, &View); + View.VSplitLeft(5.0f, 0, &View); + View.VSplitRight(5.0f, &View, 0); + View.HSplitBottom(5.0f, &View, 0); // render filters - view.HSplitTop(20.0f, &button, &view); - if (DoButton_CheckBox(&config.b_filter_empty, localize("Has people playing"), config.b_filter_empty, &button)) - config.b_filter_empty ^= 1; + View.HSplitTop(20.0f, &Button, &View); + if (DoButton_CheckBox(&g_Config.m_BrFilterEmpty, Localize("Has people playing"), g_Config.m_BrFilterEmpty, &Button)) + g_Config.m_BrFilterEmpty ^= 1; - view.HSplitTop(20.0f, &button, &view); - if (DoButton_CheckBox(&config.b_filter_full, localize("Server not full"), config.b_filter_full, &button)) - config.b_filter_full ^= 1; + View.HSplitTop(20.0f, &Button, &View); + if (DoButton_CheckBox(&g_Config.m_BrFilterFull, Localize("Server not full"), g_Config.m_BrFilterFull, &Button)) + g_Config.m_BrFilterFull ^= 1; - view.HSplitTop(20.0f, &button, &view); - if (DoButton_CheckBox(&config.b_filter_pw, localize("No password"), config.b_filter_pw, &button)) - config.b_filter_pw ^= 1; + View.HSplitTop(20.0f, &Button, &View); + if (DoButton_CheckBox(&g_Config.m_BrFilterPw, Localize("No password"), g_Config.m_BrFilterPw, &Button)) + g_Config.m_BrFilterPw ^= 1; - view.HSplitTop(20.0f, &button, &view); - if (DoButton_CheckBox((char *)&config.b_filter_compatversion, localize("Compatible version"), config.b_filter_compatversion, &button)) - config.b_filter_compatversion ^= 1; + View.HSplitTop(20.0f, &Button, &View); + if (DoButton_CheckBox((char *)&g_Config.m_BrFilterCompatversion, Localize("Compatible version"), g_Config.m_BrFilterCompatversion, &Button)) + g_Config.m_BrFilterCompatversion ^= 1; + + View.HSplitTop(20.0f, &Button, &View); + if (DoButton_CheckBox((char *)&g_Config.m_BrFilterPure, Localize("Standard gametype"), g_Config.m_BrFilterPure, &Button)) + g_Config.m_BrFilterPure ^= 1; + + View.HSplitTop(20.0f, &Button, &View); + //button.VSplitLeft(20.0f, 0, &button); + if (DoButton_CheckBox((char *)&g_Config.m_BrFilterPureMap, Localize("Standard map"), g_Config.m_BrFilterPureMap, &Button)) + g_Config.m_BrFilterPureMap ^= 1; - view.HSplitTop(20.0f, &button, &view); - if (DoButton_CheckBox((char *)&config.b_filter_pure, localize("Standard gametype"), config.b_filter_pure, &button)) - config.b_filter_pure ^= 1; - - view.HSplitTop(20.0f, &button, &view); - /*button.VSplitLeft(20.0f, 0, &button);*/ - if (DoButton_CheckBox((char *)&config.b_filter_pure_map, localize("Standard map"), config.b_filter_pure_map, &button)) - config.b_filter_pure_map ^= 1; - - view.HSplitTop(20.0f, &button, &view); - UI()->DoLabel(&button, localize("Game types"), 14.0f, -1); - button.VSplitLeft(95.0f, 0, &button); - button.Margin(1.0f, &button); - DoEditBox(&config.b_filter_gametype, &button, config.b_filter_gametype, sizeof(config.b_filter_gametype), 14.0f); + View.HSplitTop(5.0f, 0, &View); + + View.HSplitTop(19.0f, &Button, &View); + UI()->DoLabel(&Button, Localize("Game types:"), 12.0f, -1); + Button.VSplitLeft(95.0f, 0, &Button); + View.HSplitTop(3.0f, 0, &View); + DoEditBox(&g_Config.m_BrFilterGametype, &Button, g_Config.m_BrFilterGametype, sizeof(g_Config.m_BrFilterGametype), 12.0f); { - view.HSplitTop(20.0f, &button, &view); - CUIRect editbox; - button.VSplitLeft(40.0f, &editbox, &button); - button.VSplitLeft(5.0f, &button, &button); + View.HSplitTop(19.0f, &Button, &View); + CUIRect EditBox; + Button.VSplitRight(50.0f, &Button, &EditBox); + EditBox.VSplitRight(5.0f, &EditBox, 0); - char buf[8]; - str_format(buf, sizeof(buf), "%d", config.b_filter_ping); - DoEditBox(&config.b_filter_ping, &editbox, buf, sizeof(buf), 14.0f); - config.b_filter_ping = atoi(buf); + UI()->DoLabel(&Button, Localize("Maximum ping:"), 12.0f, -1); - UI()->DoLabel(&button, localize("Maximum ping"), 14.0f, -1); + char aBuf[5]; + str_format(aBuf, sizeof(aBuf), "%d", g_Config.m_BrFilterPing); + DoEditBox(&g_Config.m_BrFilterPing, &EditBox, aBuf, sizeof(aBuf), 12.0f); + g_Config.m_BrFilterPing = str_toint(aBuf); } - - view.HSplitBottom(button_height, &view, &button); - static int clear_button = 0; - if(DoButton_Menu(&clear_button, localize("Reset filter"), 0, &button)) + + View.HSplitBottom(ms_ButtonHeight, &View, &Button); + static int s_ClearButton = 0; + if(DoButton_Menu(&s_ClearButton, Localize("Reset filter"), 0, &Button)) { - config.b_filter_full = 0; - config.b_filter_empty = 0; - config.b_filter_pw = 0; - config.b_filter_ping = 999; - config.b_filter_gametype[0] = 0; - config.b_filter_compatversion = 1; - config.b_filter_string[0] = 0; - config.b_filter_pure = 1; + g_Config.m_BrFilterFull = 0; + g_Config.m_BrFilterEmpty = 0; + g_Config.m_BrFilterPw = 0; + g_Config.m_BrFilterPing = 999; + g_Config.m_BrFilterGametype[0] = 0; + g_Config.m_BrFilterCompatversion = 1; + g_Config.m_BrFilterString[0] = 0; + g_Config.m_BrFilterPure = 1; + g_Config.m_BrFilterPureMap = 1; } } -void MENUS::render_serverbrowser_serverdetail(CUIRect view) +void CMenus::RenderServerbrowserServerDetail(CUIRect View) { - CUIRect server_details = view; - CUIRect server_scoreboard, server_header; - - SERVER_INFO *selected_server = client_serverbrowse_sorted_get(selected_index); - + CUIRect ServerDetails = View; + CUIRect ServerScoreBoard, ServerHeader; + + const CServerInfo *pSelectedServer = ServerBrowser()->SortedGet(m_SelectedIndex); + //server_details.VSplitLeft(10.0f, 0x0, &server_details); // split off a piece to use for scoreboard - server_details.HSplitTop(140.0f, &server_details, &server_scoreboard); - server_details.HSplitBottom(10.0f, &server_details, 0x0); + ServerDetails.HSplitTop(140.0f, &ServerDetails, &ServerScoreBoard); + ServerDetails.HSplitBottom(10.0f, &ServerDetails, 0x0); // server details - const float font_size = 12.0f; - server_details.HSplitTop(20.0f, &server_header, &server_details); - RenderTools()->DrawUIRect(&server_header, vec4(1,1,1,0.25f), CUI::CORNER_T, 4.0f); - RenderTools()->DrawUIRect(&server_details, vec4(0,0,0,0.15f), CUI::CORNER_B, 4.0f); - server_header.VSplitLeft(8.0f, 0x0, &server_header); - UI()->DoLabel(&server_header, localize("Server details"), font_size+2.0f, -1); + const float FontSize = 12.0f; + ServerDetails.HSplitTop(20.0f, &ServerHeader, &ServerDetails); + RenderTools()->DrawUIRect(&ServerHeader, vec4(1,1,1,0.25f), CUI::CORNER_T, 4.0f); + RenderTools()->DrawUIRect(&ServerDetails, vec4(0,0,0,0.15f), CUI::CORNER_B, 4.0f); + ServerHeader.VSplitLeft(8.0f, 0x0, &ServerHeader); + UI()->DoLabel(&ServerHeader, Localize("Server details"), FontSize+2.0f, -1); - server_details.VSplitLeft(5.0f, 0x0, &server_details); + ServerDetails.VSplitLeft(5.0f, 0x0, &ServerDetails); - server_details.Margin(3.0f, &server_details); + ServerDetails.Margin(3.0f, &ServerDetails); - if (selected_server) + if (pSelectedServer) { - CUIRect row; - static LOC_CONSTSTRING labels[] = { - localize("Version"), - localize("Game type"), - localize("Ping")}; + CUIRect Row; + static CLocConstString s_aLabels[] = { + Localize("Version"), + Localize("Game type"), + Localize("Ping")}; - CUIRect left_column; - CUIRect right_column; + CUIRect LeftColumn; + CUIRect RightColumn; - // + // { - CUIRect button; - server_details.HSplitBottom(20.0f, &server_details, &button); - static int add_fav_button = 0; - if(DoButton_CheckBox(&add_fav_button, localize("Favorite"), selected_server->favorite, &button)) + CUIRect Button; + ServerDetails.HSplitBottom(20.0f, &ServerDetails, &Button); + static int s_AddFavButton = 0; + if(DoButton_CheckBox(&s_AddFavButton, Localize("Favorite"), pSelectedServer->m_Favorite, &Button)) { - if(selected_server->favorite) - client_serverbrowse_removefavorite(selected_server->netaddr); + if(pSelectedServer->m_Favorite) + ServerBrowser()->RemoveFavorite(pSelectedServer->m_NetAddr); else - client_serverbrowse_addfavorite(selected_server->netaddr); + ServerBrowser()->AddFavorite(pSelectedServer->m_NetAddr); } } - //UI()->DoLabel(&row, temp, font_size, -1); + //UI()->DoLabel(&row, temp, font_size, -1); - server_details.VSplitLeft(5.0f, 0x0, &server_details); - server_details.VSplitLeft(80.0f, &left_column, &right_column); + ServerDetails.VSplitLeft(5.0f, 0x0, &ServerDetails); + ServerDetails.VSplitLeft(80.0f, &LeftColumn, &RightColumn); - for (unsigned int i = 0; i < sizeof(labels) / sizeof(labels[0]); i++) + for (unsigned int i = 0; i < sizeof(s_aLabels) / sizeof(s_aLabels[0]); i++) { - left_column.HSplitTop(15.0f, &row, &left_column); - UI()->DoLabel(&row, labels[i], font_size, -1); + LeftColumn.HSplitTop(15.0f, &Row, &LeftColumn); + UI()->DoLabel(&Row, s_aLabels[i], FontSize, -1); } - right_column.HSplitTop(15.0f, &row, &right_column); - UI()->DoLabel(&row, selected_server->version, font_size, -1); + RightColumn.HSplitTop(15.0f, &Row, &RightColumn); + UI()->DoLabel(&Row, pSelectedServer->m_aVersion, FontSize, -1); - right_column.HSplitTop(15.0f, &row, &right_column); - UI()->DoLabel(&row, selected_server->gametype, font_size, -1); + RightColumn.HSplitTop(15.0f, &Row, &RightColumn); + UI()->DoLabel(&Row, pSelectedServer->m_aGameType, FontSize, -1); - char temp[16]; - str_format(temp, sizeof(temp), "%d", selected_server->latency); - right_column.HSplitTop(15.0f, &row, &right_column); - UI()->DoLabel(&row, temp, font_size, -1); + char aTemp[16]; + str_format(aTemp, sizeof(aTemp), "%d", pSelectedServer->m_Latency); + RightColumn.HSplitTop(15.0f, &Row, &RightColumn); + UI()->DoLabel(&Row, aTemp, FontSize, -1); } - + // server scoreboard - - server_scoreboard.HSplitBottom(10.0f, &server_scoreboard, 0x0); - server_scoreboard.HSplitTop(20.0f, &server_header, &server_scoreboard); - RenderTools()->DrawUIRect(&server_header, vec4(1,1,1,0.25f), CUI::CORNER_T, 4.0f); - RenderTools()->DrawUIRect(&server_scoreboard, vec4(0,0,0,0.15f), CUI::CORNER_B, 4.0f); - server_header.VSplitLeft(8.0f, 0x0, &server_header); - UI()->DoLabel(&server_header, localize("Scoreboard"), font_size+2.0f, -1); - server_scoreboard.VSplitLeft(5.0f, 0x0, &server_scoreboard); + ServerScoreBoard.HSplitBottom(10.0f, &ServerScoreBoard, 0x0); + ServerScoreBoard.HSplitTop(20.0f, &ServerHeader, &ServerScoreBoard); + RenderTools()->DrawUIRect(&ServerHeader, vec4(1,1,1,0.25f), CUI::CORNER_T, 4.0f); + RenderTools()->DrawUIRect(&ServerScoreBoard, vec4(0,0,0,0.15f), CUI::CORNER_B, 4.0f); + ServerHeader.VSplitLeft(8.0f, 0x0, &ServerHeader); + UI()->DoLabel(&ServerHeader, Localize("Scoreboard"), FontSize+2.0f, -1); - server_scoreboard.Margin(3.0f, &server_scoreboard); + ServerScoreBoard.VSplitLeft(5.0f, 0x0, &ServerScoreBoard); - if (selected_server) + ServerScoreBoard.Margin(3.0f, &ServerScoreBoard); + + if (pSelectedServer) { - for (int i = 0; i < selected_server->num_players; i++) + for (int i = 0; i < pSelectedServer->m_NumPlayers; i++) { - CUIRect row; - char temp[16]; - server_scoreboard.HSplitTop(16.0f, &row, &server_scoreboard); + CUIRect Row; + char aTemp[16]; + ServerScoreBoard.HSplitTop(16.0f, &Row, &ServerScoreBoard); - str_format(temp, sizeof(temp), "%d", selected_server->players[i].score); - UI()->DoLabel(&row, temp, font_size, -1); + str_format(aTemp, sizeof(aTemp), "%d", pSelectedServer->m_aPlayers[i].m_Score); + UI()->DoLabel(&Row, aTemp, FontSize, -1); - row.VSplitLeft(25.0f, 0x0, &row); - - TEXT_CURSOR cursor; - gfx_text_set_cursor(&cursor, row.x, row.y, 12.0f, TEXTFLAG_RENDER); - - const char *name = selected_server->players[i].name; - if(config.b_filter_string[0]) + Row.VSplitLeft(25.0f, 0x0, &Row); + + CTextCursor Cursor; + TextRender()->SetCursor(&Cursor, Row.x, Row.y, 12.0f, TEXTFLAG_RENDER); + + const char *pName = pSelectedServer->m_aPlayers[i].m_aName; + if(g_Config.m_BrFilterString[0]) { // highlight the parts that matches - const char *s = str_find_nocase(name, config.b_filter_string); + const char *s = str_find_nocase(pName, g_Config.m_BrFilterString); if(s) { - gfx_text_ex(&cursor, name, (int)(s-name)); - gfx_text_color(0.4f,0.4f,1,1); - gfx_text_ex(&cursor, s, strlen(config.b_filter_string)); - gfx_text_color(1,1,1,1); - gfx_text_ex(&cursor, s+strlen(config.b_filter_string), -1); + TextRender()->TextEx(&Cursor, pName, (int)(s-pName)); + TextRender()->TextColor(0.4f,0.4f,1,1); + TextRender()->TextEx(&Cursor, s, str_length(g_Config.m_BrFilterString)); + TextRender()->TextColor(1,1,1,1); + TextRender()->TextEx(&Cursor, s+str_length(g_Config.m_BrFilterString), -1); } else - gfx_text_ex(&cursor, name, -1); + TextRender()->TextEx(&Cursor, pName, -1); } else - gfx_text_ex(&cursor, name, -1); - + TextRender()->TextEx(&Cursor, pName, -1); + } } } -void MENUS::render_serverbrowser(CUIRect main_view) +void CMenus::RenderServerbrowser(CUIRect MainView) { - RenderTools()->DrawUIRect(&main_view, color_tabbar_active, CUI::CORNER_ALL, 10.0f); - - CUIRect view; - main_view.Margin(10.0f, &view); - + RenderTools()->DrawUIRect(&MainView, ms_ColorTabbarActive, CUI::CORNER_ALL, 10.0f); + + CUIRect View; + MainView.Margin(10.0f, &View); + /* +-----------------+ +------+ | | | | @@ -549,100 +596,103 @@ void MENUS::render_serverbrowser(CUIRect main_view) +-----------------+ button status toolbar box */ - - + + //CUIRect filters; - CUIRect status_toolbar; - CUIRect toolbox; - CUIRect button_box; + CUIRect StatusToolBox; + CUIRect ToolBox; + CUIRect ButtonBox; // split off a piece for filters, details and scoreboard - view.VSplitRight(200.0f, &view, &toolbox); - toolbox.HSplitBottom(80.0f, &toolbox, &button_box); - view.HSplitBottom(button_height+5.0f, &view, &status_toolbar); + View.VSplitRight(200.0f, &View, &ToolBox); + ToolBox.HSplitBottom(80.0f, &ToolBox, &ButtonBox); + View.HSplitBottom(ms_ButtonHeight+5.0f, &View, &StatusToolBox); - render_serverbrowser_serverlist(view); - - static int toolbox_page = 0; - - toolbox.VSplitLeft(5.0f, 0, &toolbox); + RenderServerbrowserServerList(View); + + int ToolboxPage = g_Config.m_UiToolboxPage; + + ToolBox.VSplitLeft(5.0f, 0, &ToolBox); // do tabbar { - CUIRect tab_bar; - CUIRect tabbutton0, tabbutton1; - toolbox.HSplitTop(22.0f, &tab_bar, &toolbox); - - tab_bar.VSplitMid(&tabbutton0, &tabbutton1); - tabbutton0.VSplitRight(5.0f, &tabbutton0, 0); - tabbutton1.VSplitLeft(5.0f, 0, &tabbutton1); - - static int filters_tab = 0; - if (DoButton_MenuTab(&filters_tab, localize("Filter"), toolbox_page==0, &tabbutton0, 0)) - toolbox_page = 0; - - static int info_tab = 0; - if (DoButton_MenuTab(&info_tab, localize("Info"), toolbox_page==1, &tabbutton1, 0)) - toolbox_page = 1; + CUIRect TabBar; + CUIRect TabButton0, TabButton1; + ToolBox.HSplitTop(22.0f, &TabBar, &ToolBox); + + TabBar.VSplitMid(&TabButton0, &TabButton1); + //TabButton0.VSplitRight(5.0f, &TabButton0, 0); + //TabButton1.VSplitLeft(5.0f, 0, &TabButton1); + + static int s_FiltersTab = 0; + if (DoButton_MenuTab(&s_FiltersTab, Localize("Filter"), ToolboxPage==0, &TabButton0, CUI::CORNER_TL)) + ToolboxPage = 0; + + static int s_InfoTab = 0; + if (DoButton_MenuTab(&s_InfoTab, Localize("Info"), ToolboxPage==1, &TabButton1, CUI::CORNER_TR)) + ToolboxPage = 1; } - RenderTools()->DrawUIRect(&toolbox, vec4(0,0,0,0.15f), 0, 0); - - toolbox.HSplitTop(5.0f, 0, &toolbox); - - if(toolbox_page == 0) - render_serverbrowser_filters(toolbox); - else if(toolbox_page == 1) - render_serverbrowser_serverdetail(toolbox); + g_Config.m_UiToolboxPage = ToolboxPage; + + RenderTools()->DrawUIRect(&ToolBox, vec4(0,0,0,0.15f), 0, 0); + + ToolBox.HSplitTop(5.0f, 0, &ToolBox); + + if(ToolboxPage == 0) + RenderServerbrowserFilters(ToolBox); + else if(ToolboxPage == 1) + RenderServerbrowserServerDetail(ToolBox); { - status_toolbar.HSplitTop(5.0f, 0, &status_toolbar); - - CUIRect button; + StatusToolBox.HSplitTop(5.0f, 0, &StatusToolBox); + + CUIRect Button; //buttons.VSplitRight(20.0f, &buttons, &button); - status_toolbar.VSplitRight(110.0f, &status_toolbar, &button); - button.VMargin(2.0f, &button); - static int refresh_button = 0; - if(DoButton_Menu(&refresh_button, localize("Refresh"), 0, &button)) + StatusToolBox.VSplitRight(110.0f, &StatusToolBox, &Button); + Button.VMargin(2.0f, &Button); + static int s_RefreshButton = 0; + if(DoButton_Menu(&s_RefreshButton, Localize("Refresh"), 0, &Button)) { - if(config.ui_page == PAGE_INTERNET) - client_serverbrowse_refresh(BROWSETYPE_INTERNET); - else if(config.ui_page == PAGE_LAN) - client_serverbrowse_refresh(BROWSETYPE_LAN); - else if(config.ui_page == PAGE_FAVORITES) - client_serverbrowse_refresh(BROWSETYPE_FAVORITES); + 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); } - - char buf[512]; - if(strcmp(client_latestversion(), "0") != 0) - str_format(buf, sizeof(buf), localize("Teeworlds %s is out! Download it at www.teeworlds.com!"), client_latestversion()); + + char aBuf[512]; + if(str_comp(Client()->LatestVersion(), "0") != 0) + str_format(aBuf, sizeof(aBuf), Localize("Teeworlds %s is out! Download it at www.teeworlds.com!"), Client()->LatestVersion()); else - str_format(buf, sizeof(buf), localize("Current version: %s"), GAME_VERSION); - UI()->DoLabel(&status_toolbar, buf, 14.0f, -1); + str_format(aBuf, sizeof(aBuf), Localize("Current version: %s"), GAME_VERSION); + UI()->DoLabel(&StatusToolBox, aBuf, 14.0f, -1); } - + // do the button box { - - button_box.VSplitLeft(5.0f, 0, &button_box); - button_box.VSplitRight(5.0f, &button_box, 0); - - CUIRect button; - button_box.HSplitBottom(button_height, &button_box, &button); - button.VSplitRight(120.0f, 0, &button); - button.VMargin(2.0f, &button); + + ButtonBox.VSplitLeft(5.0f, 0, &ButtonBox); + ButtonBox.VSplitRight(5.0f, &ButtonBox, 0); + + CUIRect Button; + ButtonBox.HSplitBottom(ms_ButtonHeight, &ButtonBox, &Button); + Button.VSplitRight(120.0f, 0, &Button); + Button.VMargin(2.0f, &Button); //button.VMargin(2.0f, &button); - static int join_button = 0; - if(DoButton_Menu(&join_button, localize("Connect"), 0, &button) || enter_pressed) + static int s_JoinButton = 0; + if(DoButton_Menu(&s_JoinButton, Localize("Connect"), 0, &Button) || m_EnterPressed) { - client_connect(config.ui_server_address); - enter_pressed = false; + dbg_msg("", "%s", g_Config.m_UiServerAddress); + Client()->Connect(g_Config.m_UiServerAddress); + m_EnterPressed = false; } - - button_box.HSplitBottom(5.0f, &button_box, &button); - button_box.HSplitBottom(20.0f, &button_box, &button); - DoEditBox(&config.ui_server_address, &button, config.ui_server_address, sizeof(config.ui_server_address), 14.0f); - button_box.HSplitBottom(20.0f, &button_box, &button); - UI()->DoLabel(&button, localize("Host address"), 14.0f, -1); + + ButtonBox.HSplitBottom(5.0f, &ButtonBox, &Button); + ButtonBox.HSplitBottom(20.0f, &ButtonBox, &Button); + DoEditBox(&g_Config.m_UiServerAddress, &Button, g_Config.m_UiServerAddress, sizeof(g_Config.m_UiServerAddress), 14.0f); + ButtonBox.HSplitBottom(20.0f, &ButtonBox, &Button); + UI()->DoLabel(&Button, Localize("Host address"), 14.0f, -1); } } diff --git a/src/game/client/components/menus_demo.cpp b/src/game/client/components/menus_demo.cpp index 07019d46..62c03a92 100644 --- a/src/game/client/components/menus_demo.cpp +++ b/src/game/client/components/menus_demo.cpp @@ -1,86 +1,82 @@ -#include <base/math.hpp> +#include <base/math.h> -//#include <string.h> // strcmp, strlen, strncpy -//#include <stdlib.h> // atoi -#include <engine/e_client_interface.h> -#include <game/client/render.hpp> -#include <game/client/gameclient.hpp> +#include <engine/demo.h> +#include <engine/keys.h> -//#include <game/generated/g_protocol.hpp> -//#include <game/generated/gc_data.hpp> +#include <game/client/render.h> +#include <game/client/gameclient.h> +#include <game/localization.h> -#include <game/client/ui.hpp> -//#include <game/client/gameclient.hpp> -//#include <game/client/animstate.hpp> +#include <game/client/ui.h> -#include "menus.hpp" +#include "menus.h" -int MENUS::DoButton_DemoPlayer(const void *pID, const char *pText, int Checked, const CUIRect *pRect) +int CMenus::DoButton_DemoPlayer(const void *pID, const char *pText, int Checked, const CUIRect *pRect) { - RenderTools()->DrawUIRect(pRect, vec4(1,1,1, Checked ? 0.10f : 0.5f)*button_color_mul(pID), CUI::CORNER_ALL, 5.0f); + RenderTools()->DrawUIRect(pRect, vec4(1,1,1, Checked ? 0.10f : 0.5f)*ButtonColorMul(pID), CUI::CORNER_ALL, 5.0f); UI()->DoLabel(pRect, pText, 14.0f, 0); return UI()->DoButtonLogic(pID, pText, Checked, pRect); } -void MENUS::render_demoplayer(CUIRect main_view) +void CMenus::RenderDemoPlayer(CUIRect MainView) { - const DEMOPLAYBACK_INFO *info = client_demoplayer_getinfo(); + const IDemoPlayer::CInfo *pInfo = DemoPlayer()->BaseInfo(); - const float seekbar_height = 15.0f; - const float buttonbar_height = 20.0f; - const float margins = 5.0f; - float total_height; + const float SeekBarHeight = 15.0f; + const float ButtonbarHeight = 20.0f; + const float Margins = 5.0f; + float TotalHeight; - if(menu_active) - total_height = seekbar_height+buttonbar_height+margins*3; + if(m_MenuActive) + TotalHeight = SeekBarHeight+ButtonbarHeight+Margins*3; else - total_height = seekbar_height+margins*2; + TotalHeight = SeekBarHeight+Margins*2; - main_view.HSplitBottom(total_height, 0, &main_view); - main_view.VSplitLeft(250.0f, 0, &main_view); - main_view.VSplitRight(250.0f, &main_view, 0); + MainView.HSplitBottom(TotalHeight, 0, &MainView); + MainView.VSplitLeft(250.0f, 0, &MainView); + MainView.VSplitRight(250.0f, &MainView, 0); - RenderTools()->DrawUIRect(&main_view, color_tabbar_active, CUI::CORNER_T, 10.0f); + RenderTools()->DrawUIRect(&MainView, ms_ColorTabbarActive, CUI::CORNER_T, 10.0f); - main_view.Margin(5.0f, &main_view); + MainView.Margin(5.0f, &MainView); - CUIRect seekbar, buttonbar; + CUIRect SeekBar, ButtonBar; - if(menu_active) + if(m_MenuActive) { - main_view.HSplitTop(seekbar_height, &seekbar, &buttonbar); - buttonbar.HSplitTop(margins, 0, &buttonbar); + MainView.HSplitTop(SeekBarHeight, &SeekBar, &ButtonBar); + ButtonBar.HSplitTop(Margins, 0, &ButtonBar); } else - seekbar = main_view; + SeekBar = MainView; // do seekbar { - static int seekbar_id = 0; - void *id = &seekbar_id; - char buffer[128]; + static int s_SeekBarId = 0; + void *id = &s_SeekBarId; + char aBuffer[128]; - RenderTools()->DrawUIRect(&seekbar, vec4(0,0,0,0.5f), CUI::CORNER_ALL, 5.0f); + RenderTools()->DrawUIRect(&SeekBar, vec4(0,0,0,0.5f), CUI::CORNER_ALL, 5.0f); - int current_tick = info->current_tick - info->first_tick; - int total_ticks = info->last_tick - info->first_tick; + int CurrentTick = pInfo->m_CurrentTick - pInfo->m_FirstTick; + int TotalTicks = pInfo->m_LastTick - pInfo->m_FirstTick; - float amount = current_tick/(float)total_ticks; + float Amount = CurrentTick/(float)TotalTicks; - CUIRect filledbar = seekbar; - filledbar.w = 10.0f + (filledbar.w-10.0f)*amount; + CUIRect FilledBar = SeekBar; + FilledBar.w = 10.0f + (FilledBar.w-10.0f)*Amount; - RenderTools()->DrawUIRect(&filledbar, vec4(1,1,1,0.5f), CUI::CORNER_ALL, 5.0f); + RenderTools()->DrawUIRect(&FilledBar, vec4(1,1,1,0.5f), CUI::CORNER_ALL, 5.0f); - str_format(buffer, sizeof(buffer), "%d:%02d / %d:%02d", - current_tick/SERVER_TICK_SPEED/60, (current_tick/SERVER_TICK_SPEED)%60, - total_ticks/SERVER_TICK_SPEED/60, (total_ticks/SERVER_TICK_SPEED)%60); - UI()->DoLabel(&seekbar, buffer, seekbar.h*0.70f, 0); + str_format(aBuffer, sizeof(aBuffer), "%d:%02d / %d:%02d", + CurrentTick/SERVER_TICK_SPEED/60, (CurrentTick/SERVER_TICK_SPEED)%60, + TotalTicks/SERVER_TICK_SPEED/60, (TotalTicks/SERVER_TICK_SPEED)%60); + UI()->DoLabel(&SeekBar, aBuffer, SeekBar.h*0.70f, 0); // do the logic - int inside = UI()->MouseInside(&seekbar); + int Inside = UI()->MouseInside(&SeekBar); if(UI()->ActiveItem() == id) { @@ -88,13 +84,15 @@ void MENUS::render_demoplayer(CUIRect main_view) UI()->SetActiveItem(0); else { - float amount = (UI()->MouseX()-seekbar.x)/(float)seekbar.w; - if(amount > 0 && amount < 1.0f) + static float PrevAmount = 0.0f; + float Amount = (UI()->MouseX()-SeekBar.x)/(float)SeekBar.w; + if(Amount > 0 && Amount < 1.0f && PrevAmount != Amount) { - gameclient.on_reset(); - gameclient.suppress_events = true; - client_demoplayer_setpos(amount); - gameclient.suppress_events = false; + PrevAmount = Amount; + m_pClient->OnReset(); + m_pClient->m_SuppressEvents = true; + DemoPlayer()->SetPos(Amount); + m_pClient->m_SuppressEvents = false; } } } @@ -104,334 +102,357 @@ void MENUS::render_demoplayer(CUIRect main_view) UI()->SetActiveItem(id); } - if(inside) + if(Inside) UI()->SetHotItem(id); } - if(menu_active) + if(m_MenuActive) { // do buttons - CUIRect button; + CUIRect Button; // pause button - buttonbar.VSplitLeft(buttonbar_height, &button, &buttonbar); - static int pause_button = 0; - if(DoButton_DemoPlayer(&pause_button, "| |", info->paused, &button)) - client_demoplayer_setpause(!info->paused); + ButtonBar.VSplitLeft(ButtonbarHeight, &Button, &ButtonBar); + static int s_PauseButton = 0; + if(DoButton_DemoPlayer(&s_PauseButton, "| |", pInfo->m_Paused, &Button)) + { + if(pInfo->m_Paused) + DemoPlayer()->Unpause(); + else + DemoPlayer()->Pause(); + } // play button - buttonbar.VSplitLeft(margins, 0, &buttonbar); - buttonbar.VSplitLeft(buttonbar_height, &button, &buttonbar); - static int play_button = 0; - if(DoButton_DemoPlayer(&play_button, ">", !info->paused, &button)) + ButtonBar.VSplitLeft(Margins, 0, &ButtonBar); + ButtonBar.VSplitLeft(ButtonbarHeight, &Button, &ButtonBar); + static int s_PlayButton = 0; + if(DoButton_DemoPlayer(&s_PlayButton, ">", !pInfo->m_Paused, &Button)) { - client_demoplayer_setpause(0); - client_demoplayer_setspeed(1.0f); + DemoPlayer()->Unpause(); + DemoPlayer()->SetSpeed(1.0f); } // slowdown - buttonbar.VSplitLeft(margins, 0, &buttonbar); - buttonbar.VSplitLeft(buttonbar_height, &button, &buttonbar); - static int slowdown_button = 0; - if(DoButton_DemoPlayer(&slowdown_button, "<<", 0, &button)) + ButtonBar.VSplitLeft(Margins, 0, &ButtonBar); + ButtonBar.VSplitLeft(ButtonbarHeight, &Button, &ButtonBar); + static int s_SlowDownButton = 0; + if(DoButton_DemoPlayer(&s_SlowDownButton, "<<", 0, &Button)) { - if(info->speed > 4.0f) client_demoplayer_setspeed(4.0f); - else if(info->speed > 2.0f) client_demoplayer_setspeed(2.0f); - else if(info->speed > 1.0f) client_demoplayer_setspeed(1.0f); - else if(info->speed > 0.5f) client_demoplayer_setspeed(0.5f); - else client_demoplayer_setspeed(0.05f); + if(pInfo->m_Speed > 4.0f) DemoPlayer()->SetSpeed(4.0f); + else if(pInfo->m_Speed > 2.0f) DemoPlayer()->SetSpeed(2.0f); + else if(pInfo->m_Speed > 1.0f) DemoPlayer()->SetSpeed(1.0f); + else if(pInfo->m_Speed > 0.5f) DemoPlayer()->SetSpeed(0.5f); + else DemoPlayer()->SetSpeed(0.05f); } // fastforward - buttonbar.VSplitLeft(margins, 0, &buttonbar); - buttonbar.VSplitLeft(buttonbar_height, &button, &buttonbar); - static int fastforward_button = 0; - if(DoButton_DemoPlayer(&fastforward_button, ">>", 0, &button)) + ButtonBar.VSplitLeft(Margins, 0, &ButtonBar); + ButtonBar.VSplitLeft(ButtonbarHeight, &Button, &ButtonBar); + static int s_FastForwardButton = 0; + if(DoButton_DemoPlayer(&s_FastForwardButton, ">>", 0, &Button)) { - if(info->speed < 0.5f) client_demoplayer_setspeed(0.5f); - else if(info->speed < 1.0f) client_demoplayer_setspeed(1.0f); - else if(info->speed < 2.0f) client_demoplayer_setspeed(2.0f); - else if(info->speed < 4.0f) client_demoplayer_setspeed(4.0f); - else client_demoplayer_setspeed(8.0f); + if(pInfo->m_Speed < 0.5f) DemoPlayer()->SetSpeed(0.5f); + else if(pInfo->m_Speed < 1.0f) DemoPlayer()->SetSpeed(1.0f); + else if(pInfo->m_Speed < 2.0f) DemoPlayer()->SetSpeed(2.0f); + else if(pInfo->m_Speed < 4.0f) DemoPlayer()->SetSpeed(4.0f); + else DemoPlayer()->SetSpeed(8.0f); } // speed meter - buttonbar.VSplitLeft(margins*3, 0, &buttonbar); - char buffer[64]; - if(info->speed >= 1.0f) - str_format(buffer, sizeof(buffer), "x%.0f", info->speed); + ButtonBar.VSplitLeft(Margins*3, 0, &ButtonBar); + char aBuffer[64]; + if(pInfo->m_Speed >= 1.0f) + str_format(aBuffer, sizeof(aBuffer), "x%.0f", pInfo->m_Speed); else - str_format(buffer, sizeof(buffer), "x%.1f", info->speed); - UI()->DoLabel(&buttonbar, buffer, button.h*0.7f, -1); + str_format(aBuffer, sizeof(aBuffer), "x%.1f", pInfo->m_Speed); + UI()->DoLabel(&ButtonBar, aBuffer, Button.h*0.7f, -1); // close button - buttonbar.VSplitRight(buttonbar_height*3, &buttonbar, &button); - static int exit_button = 0; - if(DoButton_DemoPlayer(&exit_button, localize("Close"), 0, &button)) - client_disconnect(); + ButtonBar.VSplitRight(ButtonbarHeight*3, &ButtonBar, &Button); + static int s_ExitButton = 0; + if(DoButton_DemoPlayer(&s_ExitButton, Localize("Close"), 0, &Button)) + Client()->Disconnect(); } } -static CUIRect listbox_originalview; -static CUIRect listbox_view; -static float listbox_rowheight; -static int listbox_itemindex; -static int listbox_selected_index; -static int listbox_new_selected; -static int listbox_doneevents; -static int listbox_numitems; - -void MENUS::ui_do_listbox_start(void *id, const CUIRect *rect, float row_height, const char *title, int num_items, int selected_index) +static CUIRect gs_ListBoxOriginalView; +static CUIRect gs_ListBoxView; +static float gs_ListBoxRowHeight; +static int gs_ListBoxItemIndex; +static int gs_ListBoxSelectedIndex; +static int gs_ListBoxNewSelected; +static int gs_ListBoxDoneEvents; +static int gs_ListBoxNumItems; +static int gs_ListBoxItemsPerRow; +static float gs_ListBoxScrollValue; +static bool gs_ListBoxItemActivated; + +void CMenus::UiDoListboxStart(void *pId, const CUIRect *pRect, float RowHeight, const char *pTitle, const char *pBottomText, int NumItems, + int ItemsPerRow, int SelectedIndex, float ScrollValue) { - CUIRect scroll, row; - CUIRect view = *rect; - CUIRect header, footer; + CUIRect Scroll, Row; + CUIRect View = *pRect; + CUIRect Header, Footer; // draw header - view.HSplitTop(listheader_height, &header, &view); - RenderTools()->DrawUIRect(&header, vec4(1,1,1,0.25f), CUI::CORNER_T, 5.0f); - UI()->DoLabel(&header, title, header.h*fontmod_height, 0); + View.HSplitTop(ms_ListheaderHeight, &Header, &View); + RenderTools()->DrawUIRect(&Header, vec4(1,1,1,0.25f), CUI::CORNER_T, 5.0f); + UI()->DoLabel(&Header, pTitle, Header.h*ms_FontmodHeight, 0); // draw footers - view.HSplitBottom(listheader_height, &view, &footer); - RenderTools()->DrawUIRect(&footer, vec4(1,1,1,0.25f), CUI::CORNER_B, 5.0f); - footer.VSplitLeft(10.0f, 0, &footer); + View.HSplitBottom(ms_ListheaderHeight, &View, &Footer); + RenderTools()->DrawUIRect(&Footer, vec4(1,1,1,0.25f), CUI::CORNER_B, 5.0f); + Footer.VSplitLeft(10.0f, 0, &Footer); + UI()->DoLabel(&Footer, pBottomText, Header.h*ms_FontmodHeight, 0); // background - RenderTools()->DrawUIRect(&view, vec4(0,0,0,0.15f), 0, 0); + RenderTools()->DrawUIRect(&View, vec4(0,0,0,0.15f), 0, 0); // prepare the scroll - view.VSplitRight(15, &view, &scroll); + View.VSplitRight(15, &View, &Scroll); // setup the variables - listbox_originalview = view; - listbox_selected_index = selected_index; - listbox_new_selected = selected_index; - listbox_itemindex = 0; - listbox_rowheight = row_height; - listbox_numitems = num_items; - listbox_doneevents = 0; - //int num_servers = client_serverbrowse_sorted_num(); - + gs_ListBoxOriginalView = View; + gs_ListBoxSelectedIndex = SelectedIndex; + gs_ListBoxNewSelected = SelectedIndex; + gs_ListBoxItemIndex = 0; + gs_ListBoxRowHeight = RowHeight; + gs_ListBoxNumItems = NumItems; + gs_ListBoxItemsPerRow = ItemsPerRow; + gs_ListBoxDoneEvents = 0; + gs_ListBoxScrollValue = ScrollValue; + gs_ListBoxItemActivated = false; // do the scrollbar - view.HSplitTop(listbox_rowheight, &row, 0); + View.HSplitTop(gs_ListBoxRowHeight, &Row, 0); - int num_viewable = (int)(listbox_originalview.h/row.h) + 1; - int num = num_items-num_viewable+1; - if(num < 0) - num = 0; + int NumViewable = (int)(gs_ListBoxOriginalView.h/Row.h) + 1; + int Num = (NumItems+gs_ListBoxItemsPerRow-1)/gs_ListBoxItemsPerRow-NumViewable+1; + if(Num < 0) + Num = 0; + if(Num > 0) + { + if(Input()->KeyPresses(KEY_MOUSE_WHEEL_UP)) + gs_ListBoxScrollValue -= 1.0f/Num; + if(Input()->KeyPresses(KEY_MOUSE_WHEEL_DOWN)) + gs_ListBoxScrollValue += 1.0f/Num; - static float scrollvalue = 0; - scroll.HMargin(5.0f, &scroll); - scrollvalue = DoScrollbarV(id, &scroll, scrollvalue); - - int start = (int)(num*scrollvalue); - if(start < 0) - start = 0; + if(gs_ListBoxScrollValue < 0.0f) gs_ListBoxScrollValue = 0.0f; + if(gs_ListBoxScrollValue > 1.0f) gs_ListBoxScrollValue = 1.0f; + } + + Scroll.HMargin(5.0f, &Scroll); + gs_ListBoxScrollValue = DoScrollbarV(pId, &Scroll, gs_ListBoxScrollValue); // the list - listbox_view = listbox_originalview; - listbox_view.VMargin(5.0f, &listbox_view); - UI()->ClipEnable(&listbox_view); - listbox_view.y -= scrollvalue*num*row.h; + gs_ListBoxView = gs_ListBoxOriginalView; + gs_ListBoxView.VMargin(5.0f, &gs_ListBoxView); + UI()->ClipEnable(&gs_ListBoxView); + gs_ListBoxView.y -= gs_ListBoxScrollValue*Num*Row.h; } -MENUS::LISTBOXITEM MENUS::ui_do_listbox_nextrow() +CMenus::CListboxItem CMenus::UiDoListboxNextRow() { - LISTBOXITEM item = {0}; - listbox_view.HSplitTop(listbox_rowheight /*-2.0f*/, &item.rect, &listbox_view); - item.visible = 1; + static CUIRect s_RowView; + CListboxItem Item = {0}; + if(gs_ListBoxItemIndex%gs_ListBoxItemsPerRow == 0) + gs_ListBoxView.HSplitTop(gs_ListBoxRowHeight /*-2.0f*/, &s_RowView, &gs_ListBoxView); + + s_RowView.VSplitLeft(s_RowView.w/(gs_ListBoxItemsPerRow-gs_ListBoxItemIndex%gs_ListBoxItemsPerRow), &Item.m_Rect, &s_RowView); + + Item.m_Visible = 1; //item.rect = row; - item.hitrect = item.rect; + Item.m_HitRect = Item.m_Rect; //CUIRect select_hit_box = item.rect; - if(listbox_selected_index == listbox_itemindex) - item.selected = 1; + if(gs_ListBoxSelectedIndex == gs_ListBoxItemIndex) + Item.m_Selected = 1; // make sure that only those in view can be selected - if(item.rect.y+item.rect.h > listbox_originalview.y) + if(Item.m_Rect.y+Item.m_Rect.h > gs_ListBoxOriginalView.y) { - if(item.hitrect.y < item.hitrect.y) // clip the selection + if(Item.m_HitRect.y < Item.m_HitRect.y) // clip the selection { - item.hitrect.h -= listbox_originalview.y-item.hitrect.y; - item.hitrect.y = listbox_originalview.y; + Item.m_HitRect.h -= gs_ListBoxOriginalView.y-Item.m_HitRect.y; + Item.m_HitRect.y = gs_ListBoxOriginalView.y; } } else - item.visible = 0; + Item.m_Visible = 0; // check if we need to do more - if(item.rect.y > listbox_originalview.y+listbox_originalview.h) - item.visible = 0; + if(Item.m_Rect.y > gs_ListBoxOriginalView.y+gs_ListBoxOriginalView.h) + Item.m_Visible = 0; - listbox_itemindex++; - return item; + gs_ListBoxItemIndex++; + return Item; } -MENUS::LISTBOXITEM MENUS::ui_do_listbox_nextitem(void *id) +CMenus::CListboxItem CMenus::UiDoListboxNextItem(void *pId, bool Selected) { - int this_itemindex = listbox_itemindex; - - LISTBOXITEM item = ui_do_listbox_nextrow(); - - if(UI()->DoButtonLogic(id, "", listbox_selected_index == listbox_itemindex, &item.hitrect)) - listbox_new_selected = listbox_itemindex; - - //CUIRect row; - //LISTBOXITEM item = {0}; - //listbox_view.HSplitTop(listbox_rowheight /*-2.0f*/, &row, &listbox_view); - //listbox_view.HSplitTop(2.0f, 0, &listbox_view); - /* - CUIRect select_hit_box = row; - - item.visible = 1; - if(listbox_selected_index == listbox_itemindex) - item.selected = 1; - - // make sure that only those in view can be selected - if(row.y+row.h > listbox_originalview.y) + int ThisItemIndex = gs_ListBoxItemIndex; + if(Selected) { - - if(select_hit_box.y < listbox_originalview.y) // clip the selection - { - select_hit_box.h -= listbox_originalview.y-select_hit_box.y; - select_hit_box.y = listbox_originalview.y; - } - - if(UI()->DoButton(id, "", listbox_selected_index==listbox_itemindex, &select_hit_box, 0, 0)) - listbox_new_selected = listbox_itemindex; + if(gs_ListBoxSelectedIndex == gs_ListBoxNewSelected) + gs_ListBoxNewSelected = ThisItemIndex; + gs_ListBoxSelectedIndex = ThisItemIndex; } - else - item.visible = 0; - - item.rect = row; - */ + CListboxItem Item = UiDoListboxNextRow(); - if(listbox_selected_index == this_itemindex) + if(Item.m_Visible && UI()->DoButtonLogic(pId, "", gs_ListBoxSelectedIndex == gs_ListBoxItemIndex, &Item.m_HitRect)) + gs_ListBoxNewSelected = ThisItemIndex; + + // process input, regard selected index + if(gs_ListBoxSelectedIndex == ThisItemIndex) { - if(!listbox_doneevents) + if(!gs_ListBoxDoneEvents) { - listbox_doneevents = 1; - - for(int i = 0; i < num_inputevents; i++) + gs_ListBoxDoneEvents = 1; + + if(m_EnterPressed || (Input()->MouseDoubleClick() && UI()->ActiveItem() == pId)) { - if(inputevents[i].flags&INPFLAG_PRESS) + gs_ListBoxItemActivated = true; + } + else + { + for(int i = 0; i < m_NumInputEvents; i++) { - if(inputevents[i].key == KEY_DOWN) listbox_new_selected++; - if(inputevents[i].key == KEY_UP) listbox_new_selected--; + int NewIndex = -1; + if(m_aInputEvents[i].m_Flags&IInput::FLAG_PRESS) + { + if(m_aInputEvents[i].m_Key == KEY_DOWN) NewIndex = gs_ListBoxNewSelected + 1; + if(m_aInputEvents[i].m_Key == KEY_UP) NewIndex = gs_ListBoxNewSelected - 1; + } + if(NewIndex > -1 && NewIndex < gs_ListBoxNumItems) + { + // scroll + int NumViewable = (int)(gs_ListBoxOriginalView.h/gs_ListBoxRowHeight) + 1; + int ScrollNum = (gs_ListBoxNumItems+gs_ListBoxItemsPerRow-1)/gs_ListBoxItemsPerRow-NumViewable+1; + if(ScrollNum > 0 && NewIndex/gs_ListBoxItemsPerRow-gs_ListBoxSelectedIndex/gs_ListBoxItemsPerRow) + { + // TODO: make the scrolling better + if(NewIndex - gs_ListBoxSelectedIndex > 0) + gs_ListBoxScrollValue += 1.0f/ScrollNum; + else + gs_ListBoxScrollValue -= 1.0f/ScrollNum; + if(gs_ListBoxScrollValue < 0.0f) gs_ListBoxScrollValue = 0.0f; + if(gs_ListBoxScrollValue > 1.0f) gs_ListBoxScrollValue = 1.0f; + } + + gs_ListBoxNewSelected = NewIndex; + } } } - - if(listbox_new_selected >= listbox_numitems) - listbox_new_selected = listbox_numitems-1; - if(listbox_new_selected < 0) - listbox_new_selected = 0; } //selected_index = i; - CUIRect r = item.rect; + CUIRect r = Item.m_Rect; r.Margin(1.5f, &r); RenderTools()->DrawUIRect(&r, vec4(1,1,1,0.5f), CUI::CORNER_ALL, 4.0f); } - //listbox_itemindex++; - return item; + return Item; } -int MENUS::ui_do_listbox_end() +int CMenus::UiDoListboxEnd(float *pScrollValue, bool *pItemActivated) { UI()->ClipDisable(); - return listbox_new_selected; + if(pScrollValue) + *pScrollValue = gs_ListBoxScrollValue; + if(pItemActivated) + *pItemActivated = gs_ListBoxItemActivated; + return gs_ListBoxNewSelected; } struct FETCH_CALLBACKINFO { - MENUS *self; - const char *prefix; - int count; + CMenus *m_pSelf; + const char *m_pPrefix; + int m_Count; }; -void MENUS::demolist_fetch_callback(const char *name, int is_dir, void *user) +void CMenus::DemolistFetchCallback(const char *pName, int IsDir, void *pUser) { - if(is_dir || name[0] == '.') + if(IsDir || pName[0] == '.') return; - FETCH_CALLBACKINFO *info = (FETCH_CALLBACKINFO *)user; + FETCH_CALLBACKINFO *pInfo = (FETCH_CALLBACKINFO *)pUser; - DEMOITEM item; - str_format(item.filename, sizeof(item.filename), "%s/%s", info->prefix, name); - str_copy(item.name, name, sizeof(item.name)); - info->self->demos.add(item); + CDemoItem Item; + str_format(Item.m_aFilename, sizeof(Item.m_aFilename), "%s/%s", pInfo->m_pPrefix, pName); + str_copy(Item.m_aName, pName, sizeof(Item.m_aName)); + pInfo->m_pSelf->m_lDemos.add(Item); } -void MENUS::demolist_populate() +void CMenus::DemolistPopulate() { - demos.clear(); + m_lDemos.clear(); - char buf[512]; - str_format(buf, sizeof(buf), "%s/demos", client_user_directory()); + char aBuf[512]; + str_format(aBuf, sizeof(aBuf), "%s/demos", Client()->UserDirectory()); - FETCH_CALLBACKINFO info = {this, buf, 0}; - fs_listdir(buf, demolist_fetch_callback, &info); - info.prefix = "demos"; - fs_listdir("demos", demolist_fetch_callback, &info); + FETCH_CALLBACKINFO Info = {this, aBuf, 0}; + fs_listdir(aBuf, DemolistFetchCallback, &Info); + Info.m_pPrefix = "demos"; + fs_listdir("demos", DemolistFetchCallback, &Info); } -void MENUS::render_demolist(CUIRect main_view) +void CMenus::RenderDemoList(CUIRect MainView) { - static int inited = 0; - if(!inited) - demolist_populate(); - inited = 1; + static int s_Inited = 0; + if(!s_Inited) + DemolistPopulate(); + s_Inited = 1; // render background - RenderTools()->DrawUIRect(&main_view, color_tabbar_active, CUI::CORNER_ALL, 10.0f); - main_view.Margin(10.0f, &main_view); + RenderTools()->DrawUIRect(&MainView, ms_ColorTabbarActive, CUI::CORNER_ALL, 10.0f); + MainView.Margin(10.0f, &MainView); - CUIRect buttonbar; - main_view.HSplitBottom(button_height+5.0f, &main_view, &buttonbar); - buttonbar.HSplitTop(5.0f, 0, &buttonbar); + CUIRect ButtonBar; + MainView.HSplitBottom(ms_ButtonHeight+5.0f, &MainView, &ButtonBar); + ButtonBar.HSplitTop(5.0f, 0, &ButtonBar); - static int selected_item = -1; - static int demolist_id = 0; + static int s_SelectedItem = -1; + static int s_DemoListId = 0; + static float s_ScrollValue = 0; - ui_do_listbox_start(&demolist_id, &main_view, 17.0f, localize("Demos"), demos.size(), selected_item); + UiDoListboxStart(&s_DemoListId, &MainView, 17.0f, Localize("Demos"), "", m_lDemos.size(), 1, s_SelectedItem, s_ScrollValue); //for(int i = 0; i < num_demos; i++) - for(sorted_array<DEMOITEM>::range r = demos.all(); !r.empty(); r.pop_front()) + for(sorted_array<CDemoItem>::range r = m_lDemos.all(); !r.empty(); r.pop_front()) { - LISTBOXITEM item = ui_do_listbox_nextitem((void*)(&r.front())); - if(item.visible) - UI()->DoLabel(&item.rect, r.front().name, item.rect.h*fontmod_height, -1); + CListboxItem Item = UiDoListboxNextItem((void*)(&r.front())); + if(Item.m_Visible) + UI()->DoLabel(&Item.m_Rect, r.front().m_aName, Item.m_Rect.h*ms_FontmodHeight, -1); } - selected_item = ui_do_listbox_end(); - - CUIRect refresh_rect, play_rect; - buttonbar.VSplitRight(250.0f, &buttonbar, &refresh_rect); - refresh_rect.VSplitRight(130.0f, &refresh_rect, &play_rect); - play_rect.VSplitRight(120.0f, 0x0, &play_rect); + bool Activated = false; + s_SelectedItem = UiDoListboxEnd(&s_ScrollValue, &Activated); - static int refresh_button = 0; - if(DoButton_Menu(&refresh_button, localize("Refresh"), 0, &refresh_rect)) - { - demolist_populate(); - } + CUIRect RefreshRect, PlayRect; + ButtonBar.VSplitRight(250.0f, &ButtonBar, &RefreshRect); + RefreshRect.VSplitRight(130.0f, &RefreshRect, &PlayRect); + PlayRect.VSplitRight(120.0f, 0x0, &PlayRect); - static int play_button = 0; - if(DoButton_Menu(&play_button, localize("Play"), 0, &play_rect)) + static int s_RefreshButton = 0; + if(DoButton_Menu(&s_RefreshButton, Localize("Refresh"), 0, &RefreshRect)) { - if(selected_item >= 0 && selected_item < demos.size()) + DemolistPopulate(); + } + + static int s_PlayButton = 0; + if(DoButton_Menu(&s_PlayButton, Localize("Play"), 0, &PlayRect) || Activated) + { + if(s_SelectedItem >= 0 && s_SelectedItem < m_lDemos.size()) { - const char *error = client_demoplayer_play(demos[selected_item].filename); - if(error) - popup_message(localize("Error"), error, localize("Ok")); + const char *pError = Client()->DemoPlayer_Play(m_lDemos[s_SelectedItem].m_aFilename); + if(pError) + PopupMessage(Localize("Error"), pError, Localize("Ok")); } } diff --git a/src/game/client/components/menus_ingame.cpp b/src/game/client/components/menus_ingame.cpp index d31a15bd..7d1f2513 100644 --- a/src/game/client/components/menus_ingame.cpp +++ b/src/game/client/components/menus_ingame.cpp @@ -1,89 +1,90 @@ -#include <base/math.hpp> +#include <base/math.h> -#include <string.h> // strcmp, strlen, strncpy -#include <stdlib.h> // atoi -#include <engine/e_client_interface.h> +#include <engine/serverbrowser.h> +#include <engine/textrender.h> +#include <engine/shared/config.h> -#include <game/generated/g_protocol.hpp> -#include <game/generated/gc_data.hpp> +#include <game/generated/protocol.h> +#include <game/generated/client_data.h> -#include <game/client/ui.hpp> -#include <game/client/gameclient.hpp> -#include <game/client/animstate.hpp> +#include <game/client/ui.h> +#include <game/client/gameclient.h> +#include <game/client/animstate.h> +#include <game/localization.h> -#include "menus.hpp" -#include "motd.hpp" -#include "voting.hpp" +#include "menus.h" +#include "motd.h" +#include "voting.h" -void MENUS::render_game(CUIRect main_view) +void CMenus::RenderGame(CUIRect MainView) { - CUIRect button; + CUIRect Button; //CUIRect votearea; - main_view.HSplitTop(45.0f, &main_view, 0); - RenderTools()->DrawUIRect(&main_view, color_tabbar_active, CUI::CORNER_ALL, 10.0f); + MainView.HSplitTop(45.0f, &MainView, 0); + RenderTools()->DrawUIRect(&MainView, ms_ColorTabbarActive, CUI::CORNER_ALL, 10.0f); - main_view.HSplitTop(10.0f, 0, &main_view); - main_view.HSplitTop(25.0f, &main_view, 0); - main_view.VMargin(10.0f, &main_view); + MainView.HSplitTop(10.0f, 0, &MainView); + MainView.HSplitTop(25.0f, &MainView, 0); + MainView.VMargin(10.0f, &MainView); - main_view.VSplitRight(120.0f, &main_view, &button); - static int disconnect_button = 0; - if(DoButton_Menu(&disconnect_button, localize("Disconnect"), 0, &button)) - client_disconnect(); + MainView.VSplitRight(120.0f, &MainView, &Button); + static int s_DisconnectButton = 0; + if(DoButton_Menu(&s_DisconnectButton, Localize("Disconnect"), 0, &Button)) + Client()->Disconnect(); - if(gameclient.snap.local_info && gameclient.snap.gameobj) + if(m_pClient->m_Snap.m_pLocalInfo && m_pClient->m_Snap.m_pGameobj) { - if(gameclient.snap.local_info->team != -1) + if(m_pClient->m_Snap.m_pLocalInfo->m_Team != -1) { - main_view.VSplitLeft(10.0f, &button, &main_view); - main_view.VSplitLeft(120.0f, &button, &main_view); - static int spectate_button = 0; - if(DoButton_Menu(&spectate_button, localize("Spectate"), 0, &button)) + MainView.VSplitLeft(10.0f, &Button, &MainView); + MainView.VSplitLeft(120.0f, &Button, &MainView); + static int s_SpectateButton = 0; + if(DoButton_Menu(&s_SpectateButton, Localize("Spectate"), 0, &Button)) { - gameclient.send_switch_team(-1); - set_active(false); + m_pClient->SendSwitchTeam(-1); + SetActive(false); } } - if(gameclient.snap.gameobj->flags & GAMEFLAG_TEAMS) + if(m_pClient->m_Snap.m_pGameobj->m_Flags & GAMEFLAG_TEAMS) { - if(gameclient.snap.local_info->team != 0) + if(m_pClient->m_Snap.m_pLocalInfo->m_Team != 0) { - main_view.VSplitLeft(10.0f, &button, &main_view); - main_view.VSplitLeft(120.0f, &button, &main_view); - static int spectate_button = 0; - if(DoButton_Menu(&spectate_button, localize("Join red"), 0, &button)) + MainView.VSplitLeft(10.0f, &Button, &MainView); + MainView.VSplitLeft(120.0f, &Button, &MainView); + static int s_SpectateButton = 0; + if(DoButton_Menu(&s_SpectateButton, Localize("Join red"), 0, &Button)) { - gameclient.send_switch_team(0); - set_active(false); + m_pClient->SendSwitchTeam(0); + SetActive(false); } } - if(gameclient.snap.local_info->team != 1) + if(m_pClient->m_Snap.m_pLocalInfo->m_Team != 1) { - main_view.VSplitLeft(10.0f, &button, &main_view); - main_view.VSplitLeft(120.0f, &button, &main_view); - static int spectate_button = 0; - if(DoButton_Menu(&spectate_button, localize("Join blue"), 0, &button)) + MainView.VSplitLeft(10.0f, &Button, &MainView); + MainView.VSplitLeft(120.0f, &Button, &MainView); + static int s_SpectateButton = 0; + if(DoButton_Menu(&s_SpectateButton, Localize("Join blue"), 0, &Button)) { - gameclient.send_switch_team(1); - set_active(false); + m_pClient->SendSwitchTeam(1); + SetActive(false); } } } else { - if(gameclient.snap.local_info->team != 0) + if(m_pClient->m_Snap.m_pLocalInfo->m_Team != 0) { - main_view.VSplitLeft(10.0f, &button, &main_view); - main_view.VSplitLeft(120.0f, &button, &main_view); - static int spectate_button = 0; - if(DoButton_Menu(&spectate_button, localize("Join game"), 0, &button)) + MainView.VSplitLeft(10.0f, &Button, &MainView); + MainView.VSplitLeft(120.0f, &Button, &MainView); + static int s_SpectateButton = 0; + if(DoButton_Menu(&s_SpectateButton, Localize("Join game"), 0, &Button)) { - gameclient.send_switch_team(0); - set_active(false); + m_pClient->SendSwitchTeam(0); + SetActive(false); } } } @@ -141,102 +142,102 @@ void MENUS::render_game(CUIRect main_view) }*/ } -void MENUS::render_serverinfo(CUIRect main_view) +void CMenus::RenderServerInfo(CUIRect MainView) { // fetch server info - SERVER_INFO current_server_info; - client_serverinfo(¤t_server_info); + CServerInfo CurrentServerInfo; + Client()->GetServerInfo(&CurrentServerInfo); - if(!gameclient.snap.local_info) + if(!m_pClient->m_Snap.m_pLocalInfo) return; // count players for server info-box - int num_players = 0; - for(int i = 0; i < snap_num_items(SNAP_CURRENT); i++) + int NumPlayers = 0; + for(int i = 0; i < Client()->SnapNumItems(IClient::SNAP_CURRENT); i++) { - SNAP_ITEM item; - snap_get_item(SNAP_CURRENT, i, &item); + IClient::CSnapItem Item; + Client()->SnapGetItem(IClient::SNAP_CURRENT, i, &Item); - if(item.type == NETOBJTYPE_PLAYER_INFO) + if(Item.m_Type == NETOBJTYPE_PLAYERINFO) { - num_players++; + NumPlayers++; } } // render background - RenderTools()->DrawUIRect(&main_view, color_tabbar_active, CUI::CORNER_ALL, 10.0f); + RenderTools()->DrawUIRect(&MainView, ms_ColorTabbarActive, CUI::CORNER_ALL, 10.0f); - CUIRect view, serverinfo, gameinfo, motd; + CUIRect View, ServerInfo, GameInfo, Motd; float x = 0.0f; float y = 0.0f; - char buf[1024]; + char aBuf[1024]; // set view to use for all sub-modules - main_view.Margin(10.0f, &view); + MainView.Margin(10.0f, &View); - /* serverinfo */ - view.HSplitTop(view.h/2-5.0f, &serverinfo, &motd); - serverinfo.VSplitLeft(view.w/2-5.0f, &serverinfo, &gameinfo); - RenderTools()->DrawUIRect(&serverinfo, vec4(1,1,1,0.25f), CUI::CORNER_ALL, 10.0f); + // serverinfo + View.HSplitTop(View.h/2-5.0f, &ServerInfo, &Motd); + ServerInfo.VSplitLeft(View.w/2-5.0f, &ServerInfo, &GameInfo); + RenderTools()->DrawUIRect(&ServerInfo, vec4(1,1,1,0.25f), CUI::CORNER_ALL, 10.0f); - serverinfo.Margin(5.0f, &serverinfo); + ServerInfo.Margin(5.0f, &ServerInfo); x = 5.0f; y = 0.0f; - gfx_text(0, serverinfo.x+x, serverinfo.y+y, 32, localize("Server info"), 250); + TextRender()->Text(0, ServerInfo.x+x, ServerInfo.y+y, 32, Localize("Server info"), 250); y += 32.0f+5.0f; - mem_zero(buf, sizeof(buf)); + mem_zero(aBuf, sizeof(aBuf)); str_format( - buf, - sizeof(buf), + aBuf, + sizeof(aBuf), "%s\n\n" "%s: %s\n" "%s: %d\n" "%s: %s\n" "%s: %s\n", - current_server_info.name, - localize("Address"), config.ui_server_address, - localize("Ping"), gameclient.snap.local_info->latency, - localize("Version"), current_server_info.version, - localize("Password"), current_server_info.flags&1 ? localize("Yes") : localize("No") + CurrentServerInfo.m_aName, + Localize("Address"), g_Config.m_UiServerAddress, + Localize("Ping"), m_pClient->m_Snap.m_pLocalInfo->m_Latency, + Localize("Version"), CurrentServerInfo.m_aVersion, + Localize("Password"), CurrentServerInfo.m_Flags &1 ? Localize("Yes") : Localize("No") ); - gfx_text(0, serverinfo.x+x, serverinfo.y+y, 20, buf, 250); + TextRender()->Text(0, ServerInfo.x+x, ServerInfo.y+y, 20, aBuf, 250); { - CUIRect button; - int is_favorite = client_serverbrowse_isfavorite(current_server_info.netaddr); - serverinfo.HSplitBottom(20.0f, &serverinfo, &button); - static int add_fav_button = 0; - if(DoButton_CheckBox(&add_fav_button, localize("Favorite"), is_favorite, &button)) + CUIRect Button; + int IsFavorite = ServerBrowser()->IsFavorite(CurrentServerInfo.m_NetAddr); + ServerInfo.HSplitBottom(20.0f, &ServerInfo, &Button); + static int s_AddFavButton = 0; + if(DoButton_CheckBox(&s_AddFavButton, Localize("Favorite"), IsFavorite, &Button)) { - if(is_favorite) - client_serverbrowse_removefavorite(current_server_info.netaddr); + if(IsFavorite) + ServerBrowser()->RemoveFavorite(CurrentServerInfo.m_NetAddr); else - client_serverbrowse_addfavorite(current_server_info.netaddr); + ServerBrowser()->AddFavorite(CurrentServerInfo.m_NetAddr); } } - /* gameinfo */ - gameinfo.VSplitLeft(10.0f, 0x0, &gameinfo); - RenderTools()->DrawUIRect(&gameinfo, vec4(1,1,1,0.25f), CUI::CORNER_ALL, 10.0f); + // gameinfo + GameInfo.VSplitLeft(10.0f, 0x0, &GameInfo); + RenderTools()->DrawUIRect(&GameInfo, vec4(1,1,1,0.25f), CUI::CORNER_ALL, 10.0f); - gameinfo.Margin(5.0f, &gameinfo); + GameInfo.Margin(5.0f, &GameInfo); x = 5.0f; y = 0.0f; - gfx_text(0, gameinfo.x+x, gameinfo.y+y, 32, localize("Game info"), 250); + TextRender()->Text(0, GameInfo.x+x, GameInfo.y+y, 32, Localize("Game info"), 250); y += 32.0f+5.0f; - mem_zero(buf, sizeof(buf)); + mem_zero(aBuf, sizeof(aBuf)); str_format( - buf, - sizeof(buf), + aBuf, + sizeof(aBuf), "\n\n" "%s: %s\n" "%s: %s\n" @@ -244,153 +245,178 @@ void MENUS::render_serverinfo(CUIRect main_view) "%s: %d\n" "\n" "%s: %d/%d\n", - localize("Game type"), current_server_info.gametype, - localize("Map"), current_server_info.map, - localize("Score limit"), gameclient.snap.gameobj->score_limit, - localize("Time limit"), gameclient.snap.gameobj->time_limit, - localize("Players"), gameclient.snap.num_players, current_server_info.max_players + Localize("Game type"), CurrentServerInfo.m_aGameType, + Localize("Map"), CurrentServerInfo.m_aMap, + Localize("Score limit"), m_pClient->m_Snap.m_pGameobj->m_ScoreLimit, + Localize("Time limit"), m_pClient->m_Snap.m_pGameobj->m_TimeLimit, + Localize("Players"), m_pClient->m_Snap.m_NumPlayers, CurrentServerInfo.m_MaxPlayers ); - gfx_text(0, gameinfo.x+x, gameinfo.y+y, 20, buf, 250); + TextRender()->Text(0, GameInfo.x+x, GameInfo.y+y, 20, aBuf, 250); - /* motd */ - motd.HSplitTop(10.0f, 0, &motd); - RenderTools()->DrawUIRect(&motd, vec4(1,1,1,0.25f), CUI::CORNER_ALL, 10.0f); - motd.Margin(5.0f, &motd); + // motd + Motd.HSplitTop(10.0f, 0, &Motd); + RenderTools()->DrawUIRect(&Motd, vec4(1,1,1,0.25f), CUI::CORNER_ALL, 10.0f); + Motd.Margin(5.0f, &Motd); y = 0.0f; x = 5.0f; - gfx_text(0, motd.x+x, motd.y+y, 32, localize("MOTD"), -1); + TextRender()->Text(0, Motd.x+x, Motd.y+y, 32, Localize("MOTD"), -1); y += 32.0f+5.0f; - gfx_text(0, motd.x+x, motd.y+y, 16, gameclient.motd->server_motd, (int)motd.w); + TextRender()->Text(0, Motd.x+x, Motd.y+y, 16, m_pClient->m_pMotd->m_aServerMotd, (int)Motd.w); } -static const char *format_command(const char *cmd) +static const char *FormatCommand(const char *pCmd) { - return cmd; + return pCmd; } -void MENUS::render_servercontrol_server(CUIRect main_view) +void CMenus::RenderServerControlServer(CUIRect MainView) { - int num_options = 0; - for(VOTING::VOTEOPTION *option = gameclient.voting->first; option; option = option->next) - num_options++; - - static int votelist = 0; - CUIRect list = main_view; - ui_do_listbox_start(&votelist, &list, 24.0f, localize("Settings"), num_options, callvote_selectedoption); + int NumOptions = 0; + for(CVoting::CVoteOption *pOption = m_pClient->m_pVoting->m_pFirst; pOption; pOption = pOption->m_pNext) + NumOptions++; + + static int s_VoteList = 0; + static float s_ScrollValue = 0; + CUIRect List = MainView; + UiDoListboxStart(&s_VoteList, &List, 24.0f, Localize("Settings"), "", NumOptions, 1, m_CallvoteSelectedOption, s_ScrollValue); - for(VOTING::VOTEOPTION *option = gameclient.voting->first; option; option = option->next) + for(CVoting::CVoteOption *pOption = m_pClient->m_pVoting->m_pFirst; pOption; pOption = pOption->m_pNext) { - LISTBOXITEM item = ui_do_listbox_nextitem(option); + CListboxItem Item = UiDoListboxNextItem(pOption); - if(item.visible) - UI()->DoLabel(&item.rect, format_command(option->command), 16.0f, -1); + if(Item.m_Visible) + UI()->DoLabel(&Item.m_Rect, FormatCommand(pOption->m_aCommand), 16.0f, -1); } - callvote_selectedoption = ui_do_listbox_end(); + m_CallvoteSelectedOption = UiDoListboxEnd(&s_ScrollValue, 0); } -void MENUS::render_servercontrol_kick(CUIRect main_view) +void CMenus::RenderServerControlKick(CUIRect MainView) { // draw header - CUIRect header, footer; - main_view.HSplitTop(20, &header, &main_view); - RenderTools()->DrawUIRect(&header, vec4(1,1,1,0.25f), CUI::CORNER_T, 5.0f); - UI()->DoLabel(&header, localize("Players"), 18.0f, 0); + CUIRect Header, Footer; + MainView.HSplitTop(20, &Header, &MainView); + RenderTools()->DrawUIRect(&Header, vec4(1,1,1,0.25f), CUI::CORNER_T, 5.0f); + UI()->DoLabel(&Header, Localize("Players"), 18.0f, 0); // draw footers - main_view.HSplitBottom(20, &main_view, &footer); - RenderTools()->DrawUIRect(&footer, vec4(1,1,1,0.25f), CUI::CORNER_B, 5.0f); - footer.VSplitLeft(10.0f, 0, &footer); + MainView.HSplitBottom(20, &MainView, &Footer); + RenderTools()->DrawUIRect(&Footer, vec4(1,1,1,0.25f), CUI::CORNER_B, 5.0f); + Footer.VSplitLeft(10.0f, 0, &Footer); // players - RenderTools()->DrawUIRect(&main_view, vec4(0,0,0,0.15f), 0, 0); - CUIRect list = main_view; + RenderTools()->DrawUIRect(&MainView, vec4(0,0,0,0.15f), 0, 0); + CUIRect List = MainView; for(int i = 0; i < MAX_CLIENTS; i++) { - if(!gameclient.snap.player_infos[i]) + if(!m_pClient->m_Snap.m_paPlayerInfos[i]) continue; - CUIRect button; - list.HSplitTop(button_height, &button, &list); + CUIRect Button; + List.HSplitTop(ms_ButtonHeight, &Button, &List); - if(DoButton_ListRow((char *)&gameclient.snap+i, "", callvote_selectedplayer == i, &button)) - callvote_selectedplayer = i; + if(DoButton_ListRow((char *)&m_pClient->m_Snap+i, "", m_CallvoteSelectedPlayer == i, &Button)) + m_CallvoteSelectedPlayer = i; - TEE_RENDER_INFO info = gameclient.clients[i].render_info; - info.size = button.h; - RenderTools()->RenderTee(ANIMSTATE::get_idle(), &info, EMOTE_NORMAL, vec2(1,0), vec2(button.x+button.h/2, button.y+button.h/2)); + CTeeRenderInfo Info = m_pClient->m_aClients[i].m_RenderInfo; + Info.m_Size = Button.h; + RenderTools()->RenderTee(CAnimState::GetIdle(), &Info, EMOTE_NORMAL, vec2(1,0), vec2(Button.x+Button.h/2, Button.y+Button.h/2)); - button.x += button.h; - UI()->DoLabel(&button, gameclient.clients[i].name, 18.0f, -1); + Button.x += Button.h; + UI()->DoLabel(&Button, m_pClient->m_aClients[i].m_aName, 18.0f, -1); } } -void MENUS::render_servercontrol(CUIRect main_view) +void CMenus::RenderServerControl(CUIRect MainView) { - static int control_page = 0; + static int s_ControlPage = 0; // render background - CUIRect temp, tabbar; - main_view.VSplitRight(120.0f, &main_view, &tabbar); - RenderTools()->DrawUIRect(&main_view, color_tabbar_active, CUI::CORNER_B|CUI::CORNER_TL, 10.0f); - tabbar.HSplitTop(50.0f, &temp, &tabbar); - RenderTools()->DrawUIRect(&temp, color_tabbar_active, CUI::CORNER_R, 10.0f); + CUIRect Temp, TabBar; + MainView.VSplitRight(120.0f, &MainView, &TabBar); + RenderTools()->DrawUIRect(&MainView, ms_ColorTabbarActive, CUI::CORNER_B|CUI::CORNER_TL, 10.0f); + TabBar.HSplitTop(50.0f, &Temp, &TabBar); + RenderTools()->DrawUIRect(&Temp, ms_ColorTabbarActive, CUI::CORNER_R, 10.0f); - main_view.HSplitTop(10.0f, 0, &main_view); + MainView.HSplitTop(10.0f, 0, &MainView); - CUIRect button; + CUIRect Button; - const char *tabs[] = { - localize("Settings"), - localize("Kick")}; - int num_tabs = (int)(sizeof(tabs)/sizeof(*tabs)); + const char *paTabs[] = { + Localize("Settings"), + Localize("Kick")}; + int aNumTabs = (int)(sizeof(paTabs)/sizeof(*paTabs)); - for(int i = 0; i < num_tabs; i++) + for(int i = 0; i < aNumTabs; i++) { - tabbar.HSplitTop(10, &button, &tabbar); - tabbar.HSplitTop(26, &button, &tabbar); - if(DoButton_SettingsTab(tabs[i], tabs[i], control_page == i, &button)) + TabBar.HSplitTop(10, &Button, &TabBar); + TabBar.HSplitTop(26, &Button, &TabBar); + if(DoButton_SettingsTab(paTabs[i], paTabs[i], s_ControlPage == i, &Button)) { - control_page = i; - callvote_selectedplayer = -1; - callvote_selectedoption = -1; + s_ControlPage = i; + m_CallvoteSelectedPlayer = -1; + m_CallvoteSelectedOption = -1; } } - main_view.Margin(10.0f, &main_view); - CUIRect bottom; - main_view.HSplitBottom(button_height + 5*2, &main_view, &bottom); - bottom.HMargin(5.0f, &bottom); + MainView.Margin(10.0f, &MainView); + CUIRect Bottom; + MainView.HSplitBottom(ms_ButtonHeight + 5*2, &MainView, &Bottom); + Bottom.HMargin(5.0f, &Bottom); // render page - if(control_page == 0) - render_servercontrol_server(main_view); - else if(control_page == 1) - render_servercontrol_kick(main_view); + if(s_ControlPage == 0) + RenderServerControlServer(MainView); + else if(s_ControlPage == 1) + RenderServerControlKick(MainView); { - CUIRect button; - bottom.VSplitRight(120.0f, &bottom, &button); + CUIRect Button; + Bottom.VSplitRight(120.0f, &Bottom, &Button); - static int callvote_button = 0; - if(DoButton_Menu(&callvote_button, localize("Call vote"), 0, &button)) + static int s_CallVoteButton = 0; + if(DoButton_Menu(&s_CallVoteButton, Localize("Call vote"), 0, &Button)) { - if(control_page == 0) + if(s_ControlPage == 0) { // - gameclient.voting->callvote_option(callvote_selectedoption); + m_pClient->m_pVoting->CallvoteOption(m_CallvoteSelectedOption); /* if(callvote_selectedmap >= 0 && callvote_selectedmap < gameclient.maplist->num()) gameclient.voting->callvote_map(gameclient.maplist->name(callvote_selectedmap));*/ } - else if(control_page == 1) + else if(s_ControlPage == 1) + { + if(m_CallvoteSelectedPlayer >= 0 && m_CallvoteSelectedPlayer < MAX_CLIENTS && + m_pClient->m_Snap.m_paPlayerInfos[m_CallvoteSelectedPlayer]) + { + m_pClient->m_pVoting->CallvoteKick(m_CallvoteSelectedPlayer); + SetActive(false); + } + } + } + + // force vote button (only available when authed in rcon) + if(Client()->RconAuthed()) + { + Bottom.VSplitLeft(120.0f, &Button, &Bottom); + + static int s_ForceVoteButton = 0; + if(DoButton_Menu(&s_ForceVoteButton, Localize("Force vote"), 0, &Button)) { - if(callvote_selectedplayer >= 0 && callvote_selectedplayer < MAX_CLIENTS && - gameclient.snap.player_infos[callvote_selectedplayer]) + if(s_ControlPage == 0) + { + m_pClient->m_pVoting->ForcevoteOption(m_CallvoteSelectedOption); + } + else if(s_ControlPage == 1) { - gameclient.voting->callvote_kick(callvote_selectedplayer); - set_active(false); + if(m_CallvoteSelectedPlayer >= 0 && m_CallvoteSelectedPlayer < MAX_CLIENTS && + m_pClient->m_Snap.m_paPlayerInfos[m_CallvoteSelectedPlayer]) + { + m_pClient->m_pVoting->ForcevoteKick(m_CallvoteSelectedPlayer); + SetActive(false); + } } } } diff --git a/src/game/client/components/menus_settings.cpp b/src/game/client/components/menus_settings.cpp index 05b4d047..a612ed77 100644 --- a/src/game/client/components/menus_settings.cpp +++ b/src/game/client/components/menus_settings.cpp @@ -1,821 +1,752 @@ -#include <base/math.hpp> +#include <base/math.h> -#include <string.h> // strcmp, strlen, strncpy -#include <stdlib.h> // atoi -#include <engine/e_client_interface.h> -#include <engine/client/graphics.h> +#include <engine/graphics.h> +#include <engine/textrender.h> +#include <engine/shared/config.h> -#include <game/generated/g_protocol.hpp> -#include <game/generated/gc_data.hpp> +#include <game/generated/protocol.h> +#include <game/generated/client_data.h> -#include <game/client/ui.hpp> -#include <game/client/render.hpp> -#include <game/client/gameclient.hpp> -#include <game/client/animstate.hpp> -#include <game/localization.hpp> +#include <game/client/ui.h> +#include <game/client/render.h> +#include <game/client/gameclient.h> +#include <game/client/animstate.h> +#include <game/localization.h> -#include "binds.hpp" -#include "menus.hpp" -#include "skins.hpp" +#include "binds.h" +#include "menus.h" +#include "skins.h" -MENUS_KEYBINDER MENUS::binder; +CMenusKeyBinder CMenus::m_Binder; -MENUS_KEYBINDER::MENUS_KEYBINDER() +CMenusKeyBinder::CMenusKeyBinder() { - take_key = false; - got_key = false; + m_TakeKey = false; + m_GotKey = false; } -bool MENUS_KEYBINDER::on_input(INPUT_EVENT e) +bool CMenusKeyBinder::OnInput(IInput::CEvent Event) { - if(take_key) + if(m_TakeKey) { - if(e.flags&INPFLAG_PRESS && e.key != KEY_ESCAPE) + if(Event.m_Flags&IInput::FLAG_PRESS && Event.m_Key != KEY_ESCAPE) { - key = e; - got_key = true; - take_key = false; + m_Key = Event; + m_GotKey = true; + m_TakeKey = false; } return true; } - + return false; } -void MENUS::render_settings_player(CUIRect main_view) +void CMenus::RenderSettingsPlayer(CUIRect MainView) { - CUIRect button; - CUIRect othersection; - main_view.VSplitLeft(300.0f, &main_view, &othersection); - main_view.HSplitTop(20.0f, &button, &main_view); + CUIRect Button; + CUIRect LeftView, RightView; + + MainView.VSplitLeft(MainView.w/2, &LeftView, &RightView); + LeftView.HSplitTop(20.0f, &Button, &LeftView); // render settings - { - char buf[128]; - - main_view.HSplitTop(20.0f, &button, &main_view); - str_format(buf, sizeof(buf), "%s:", localize("Name")); - UI()->DoLabel(&button, buf, 14.0, -1); - button.VSplitLeft(80.0f, 0, &button); - button.VSplitLeft(180.0f, &button, 0); - if(DoEditBox(config.player_name, &button, config.player_name, sizeof(config.player_name), 14.0f)) - need_sendinfo = true; + { + char aBuf[128]; + + LeftView.HSplitTop(20.0f, &Button, &LeftView); + str_format(aBuf, sizeof(aBuf), "%s:", Localize("Name")); + UI()->DoLabel(&Button, aBuf, 14.0, -1); + Button.VSplitLeft(80.0f, 0, &Button); + Button.VSplitLeft(180.0f, &Button, 0); + if(DoEditBox(g_Config.m_PlayerName, &Button, g_Config.m_PlayerName, sizeof(g_Config.m_PlayerName), 14.0f)) + m_NeedSendinfo = true; // extra spacing - main_view.HSplitTop(10.0f, 0, &main_view); + LeftView.HSplitTop(10.0f, 0, &LeftView); - static int dynamic_camera_button = 0; - main_view.HSplitTop(20.0f, &button, &main_view); - if(DoButton_CheckBox(&dynamic_camera_button, localize("Dynamic Camera"), config.cl_mouse_deadzone != 0, &button)) + static int s_DynamicCameraButton = 0; + LeftView.HSplitTop(20.0f, &Button, &LeftView); + if(DoButton_CheckBox(&s_DynamicCameraButton, Localize("Dynamic Camera"), g_Config.m_ClMouseDeadzone != 0, &Button)) { - - if(config.cl_mouse_deadzone) + + if(g_Config.m_ClMouseDeadzone) { - config.cl_mouse_followfactor = 0; - config.cl_mouse_max_distance = 400; - config.cl_mouse_deadzone = 0; + g_Config.m_ClMouseFollowfactor = 0; + g_Config.m_ClMouseMaxDistance = 400; + g_Config.m_ClMouseDeadzone = 0; } else { - config.cl_mouse_followfactor = 60; - config.cl_mouse_max_distance = 1000; - config.cl_mouse_deadzone = 300; + g_Config.m_ClMouseFollowfactor = 60; + g_Config.m_ClMouseMaxDistance = 1000; + g_Config.m_ClMouseDeadzone = 300; } } - main_view.HSplitTop(20.0f, &button, &main_view); - if(DoButton_CheckBox(&config.cl_autoswitch_weapons, localize("Switch weapon on pickup"), config.cl_autoswitch_weapons, &button)) - config.cl_autoswitch_weapons ^= 1; - - main_view.HSplitTop(20.0f, &button, &main_view); - if(DoButton_CheckBox(&config.cl_nameplates, localize("Show name plates"), config.cl_nameplates, &button)) - config.cl_nameplates ^= 1; + LeftView.HSplitTop(20.0f, &Button, &LeftView); + if(DoButton_CheckBox(&g_Config.m_ClAutoswitchWeapons, Localize("Switch weapon on pickup"), g_Config.m_ClAutoswitchWeapons, &Button)) + g_Config.m_ClAutoswitchWeapons ^= 1; + + LeftView.HSplitTop(20.0f, &Button, &LeftView); + if(DoButton_CheckBox(&g_Config.m_ClNameplates, Localize("Show name plates"), g_Config.m_ClNameplates, &Button)) + g_Config.m_ClNameplates ^= 1; //if(config.cl_nameplates) { - main_view.HSplitTop(20.0f, &button, &main_view); - button.VSplitLeft(15.0f, 0, &button); - if(DoButton_CheckBox(&config.cl_nameplates_always, localize("Always show name plates"), config.cl_nameplates_always, &button)) - config.cl_nameplates_always ^= 1; + LeftView.HSplitTop(20.0f, &Button, &LeftView); + Button.VSplitLeft(15.0f, 0, &Button); + if(DoButton_CheckBox(&g_Config.m_ClNameplatesAlways, Localize("Always show name plates"), g_Config.m_ClNameplatesAlways, &Button)) + g_Config.m_ClNameplatesAlways ^= 1; } - - main_view.HSplitTop(20.0f, &button, &main_view); - - main_view.HSplitTop(20.0f, &button, &main_view); - if(DoButton_CheckBox(&config.player_color_body, localize("Custom colors"), config.player_use_custom_color, &button)) + + { + const CSkins::CSkin *pOwnSkin = m_pClient->m_pSkins->Get(max(0, m_pClient->m_pSkins->Find(g_Config.m_PlayerSkin))); + + CTeeRenderInfo OwnSkinInfo; + OwnSkinInfo.m_Texture = pOwnSkin->m_OrgTexture; + OwnSkinInfo.m_ColorBody = vec4(1, 1, 1, 1); + OwnSkinInfo.m_ColorFeet = vec4(1, 1, 1, 1); + + if(g_Config.m_PlayerUseCustomColor) + { + OwnSkinInfo.m_ColorBody = m_pClient->m_pSkins->GetColor(g_Config.m_PlayerColorBody); + OwnSkinInfo.m_ColorFeet = m_pClient->m_pSkins->GetColor(g_Config.m_PlayerColorFeet); + OwnSkinInfo.m_Texture = pOwnSkin->m_ColorTexture; + } + + OwnSkinInfo.m_Size = UI()->Scale()*50.0f; + + LeftView.HSplitTop(20.0f, &Button, &LeftView); + LeftView.HSplitTop(20.0f, &Button, &LeftView); + + str_format(aBuf, sizeof(aBuf), "%s:", Localize("Your skin")); + UI()->DoLabel(&Button, aBuf, 14.0, -1); + + CUIRect SkinRect; + LeftView.VSplitLeft(LeftView.w/1.2f, &SkinRect, 0); + SkinRect.HSplitTop(50.0f, &SkinRect, 0); + RenderTools()->DrawUIRect(&SkinRect, vec4(1, 1, 1, 0.25f), CUI::CORNER_ALL, 10.0f); + + Button.VSplitLeft(30.0f, 0, &Button); + Button.HSplitTop(50.0f, 0, &Button); + RenderTools()->RenderTee(CAnimState::GetIdle(), &OwnSkinInfo, 0, vec2(1, 0), vec2(Button.x, Button.y)); + + LeftView.HSplitTop(20.0f, &Button, &LeftView); + Button.HSplitTop(15.0f, 0, &Button); + Button.VSplitLeft(100.0f, 0, &Button); + + str_format(aBuf, sizeof(aBuf), "%s", g_Config.m_PlayerSkin); + UI()->DoLabel(&Button, aBuf, 14.0, -1); + } + + RightView.HSplitTop(20.0f, &Button, &RightView); + RightView.HSplitTop(20.0f, &Button, &RightView); + + if(DoButton_CheckBox(&g_Config.m_PlayerColorBody, Localize("Custom colors"), g_Config.m_PlayerUseCustomColor, &Button)) { - config.player_use_custom_color = config.player_use_custom_color?0:1; - need_sendinfo = true; + g_Config.m_PlayerUseCustomColor = g_Config.m_PlayerUseCustomColor?0:1; + m_NeedSendinfo = true; } - - if(config.player_use_custom_color) + + if(g_Config.m_PlayerUseCustomColor) { - int *colors[2]; - colors[0] = &config.player_color_body; - colors[1] = &config.player_color_feet; - - const char *parts[] = { - localize("Body"), - localize("Feet")}; - const char *labels[] = { - localize("Hue"), - localize("Sat."), - localize("Lht.")}; - static int color_slider[2][3] = {{0}}; + int *paColors[2]; + paColors[0] = &g_Config.m_PlayerColorBody; + paColors[1] = &g_Config.m_PlayerColorFeet; + + const char *paParts[] = { + Localize("Body"), + Localize("Feet")}; + const char *paLabels[] = { + Localize("Hue"), + Localize("Sat."), + Localize("Lht.")}; + static int s_aColorSlider[2][3] = {{0}}; //static float v[2][3] = {{0, 0.5f, 0.25f}, {0, 0.5f, 0.25f}}; - + for(int i = 0; i < 2; i++) { - CUIRect text; - main_view.HSplitTop(20.0f, &text, &main_view); - text.VSplitLeft(15.0f, 0, &text); - UI()->DoLabel(&text, parts[i], 14.0f, -1); - - int prevcolor = *colors[i]; - int color = 0; + CUIRect Text; + RightView.HSplitTop(20.0f, &Text, &RightView); + Text.VSplitLeft(15.0f, 0, &Text); + UI()->DoLabel(&Text, paParts[i], 14.0f, -1); + + int PrevColor = *paColors[i]; + int Color = 0; for(int s = 0; s < 3; s++) { - CUIRect text; - main_view.HSplitTop(19.0f, &button, &main_view); - button.VSplitLeft(30.0f, 0, &button); - button.VSplitLeft(70.0f, &text, &button); - button.VSplitRight(5.0f, &button, 0); - button.HSplitTop(4.0f, 0, &button); - - float k = ((prevcolor>>((2-s)*8))&0xff) / 255.0f; - k = DoScrollbarH(&color_slider[i][s], &button, k); - color <<= 8; - color += clamp((int)(k*255), 0, 255); - UI()->DoLabel(&text, labels[s], 15.0f, -1); - + CUIRect Text; + RightView.HSplitTop(19.0f, &Button, &RightView); + Button.VSplitLeft(30.0f, 0, &Button); + Button.VSplitLeft(70.0f, &Text, &Button); + Button.VSplitRight(5.0f, &Button, 0); + Button.HSplitTop(4.0f, 0, &Button); + + float k = ((PrevColor>>((2-s)*8))&0xff) / 255.0f; + k = DoScrollbarH(&s_aColorSlider[i][s], &Button, k); + Color <<= 8; + Color += clamp((int)(k*255), 0, 255); + UI()->DoLabel(&Text, paLabels[s], 15.0f, -1); + } - - if(*colors[i] != color) - need_sendinfo = true; - - *colors[i] = color; - main_view.HSplitTop(5.0f, 0, &main_view); + + if(*paColors[i] != Color) + m_NeedSendinfo = true; + + *paColors[i] = Color; + RightView.HSplitTop(5.0f, 0, &RightView); } } - + + MainView.HSplitTop(MainView.h/2, 0, &MainView); + // render skinselector - static int skinselector_id = 0; - ui_do_listbox_start(&skinselector_id, &main_view, 50, localize("Skins"), (gameclient.skins->num()+3)/4, 0); + static const int s_MaxSkins = 256; + static const CSkins::CSkin *s_paSkinList[s_MaxSkins]; + static int s_NumSkins = -1; + static float s_ScrollValue = 0; + if(s_NumSkins == -1) + { + mem_zero(s_paSkinList, sizeof(s_paSkinList)); + s_NumSkins = 0; + for(int i = 0; i < m_pClient->m_pSkins->Num() && i < s_MaxSkins; ++i) + { + const CSkins::CSkin *s = m_pClient->m_pSkins->Get(i); + // no special skins + if(s->m_aName[0] == 'x' && s->m_aName[1] == '_') + continue; + s_paSkinList[s_NumSkins++] = s; + } + } - for(int skin_id = 0; skin_id < gameclient.skins->num(); ) + int OldSelected = -1; + UiDoListboxStart(&s_NumSkins , &MainView, 50.0f, Localize("Skins"), "", s_NumSkins, 4, OldSelected, s_ScrollValue); + + for(int i = 0; i < s_NumSkins; ++i) { - LISTBOXITEM item = ui_do_listbox_nextrow(); - CUIRect boxes[4]; - CUIRect first_half, second_half; - item.rect.VSplitMid(&first_half, &second_half); - first_half.VSplitMid(&boxes[0], &boxes[1]); - second_half.VSplitMid(&boxes[2], &boxes[3]); - - for(int i = 0; i < 4 && skin_id < gameclient.skins->num(); i++, skin_id++) + const CSkins::CSkin *s = s_paSkinList[i]; + if(s == 0) + continue; + + if(str_comp(s->m_aName, g_Config.m_PlayerSkin) == 0) + OldSelected = i; + + CListboxItem Item = UiDoListboxNextItem(&s_paSkinList[i], OldSelected == i); + if(Item.m_Visible) { - //CUIRect r = item. - const SKINS::SKIN *s = gameclient.skins->get(skin_id); - - TEE_RENDER_INFO info; - info.texture = s->org_texture; - info.color_body = vec4(1,1,1,1); - info.color_feet = vec4(1,1,1,1); - if(config.player_use_custom_color) + CTeeRenderInfo Info; + Info.m_Texture = s->m_OrgTexture; + Info.m_ColorBody = vec4(1, 1, 1, 1); + Info.m_ColorFeet = vec4(1, 1, 1, 1); + + if(g_Config.m_PlayerUseCustomColor) { - info.color_body = gameclient.skins->get_color(config.player_color_body); - info.color_feet = gameclient.skins->get_color(config.player_color_feet); - info.texture = s->color_texture; + Info.m_ColorBody = m_pClient->m_pSkins->GetColor(g_Config.m_PlayerColorBody); + Info.m_ColorFeet = m_pClient->m_pSkins->GetColor(g_Config.m_PlayerColorFeet); + Info.m_Texture = s->m_ColorTexture; } - - info.size = UI()->Scale()*50.0f; - - CUIRect icon = boxes[i]; //item.rect; - //button.VSplitLeft(50.0f, &icon, &text); - - /*if(UI()->DoButton(s, "", selected, &button, ui_draw_list_row, 0)) - { - config_set_player_skin(&config, s->name); - need_sendinfo = true; - }*/ - - //text.HSplitTop(12.0f, 0, &text); // some margin from the top - //UI()->DoLabel(&text, buf, 18.0f, 0); - - icon.HSplitTop(5.0f, 0, &icon); // some margin from the top - RenderTools()->RenderTee(ANIMSTATE::get_idle(), &info, 0, vec2(1, 0), vec2(icon.x+icon.w/2, icon.y+icon.h/2)); - - if(config.debug) + + Info.m_Size = UI()->Scale()*50.0f; + Item.m_Rect.HSplitTop(5.0f, 0, &Item.m_Rect); // some margin from the top + RenderTools()->RenderTee(CAnimState::GetIdle(), &Info, 0, vec2(1, 0), vec2(Item.m_Rect.x+Item.m_Rect.w/2, Item.m_Rect.y+Item.m_Rect.h/2)); + + if(g_Config.m_Debug) { Graphics()->TextureSet(-1); Graphics()->QuadsBegin(); - Graphics()->SetColor(s->blood_color.r, s->blood_color.g, s->blood_color.b, 1.0f); - Graphics()->QuadsDrawTL(icon.x, icon.y, 12, 12); + Graphics()->SetColor(s->m_BloodColor.r, s->m_BloodColor.g, s->m_BloodColor.b, 1.0f); + IGraphics::CQuadItem QuadItem(Item.m_Rect.x, Item.m_Rect.y, 12, 12); + Graphics()->QuadsDrawTL(&QuadItem, 1); Graphics()->QuadsEnd(); } } } - - int new_selection = ui_do_listbox_end(); - (void)new_selection; - //main_view - } - - // render skinselector - /* - { - - //othersection - } - - // draw header - CUIRect header, footer; - skinselection.HSplitTop(20, &header, &skinselection); - RenderTools()->DrawUIRect(&header, vec4(1,1,1,0.25f), CUI::CORNER_T, 5.0f); - UI()->DoLabel(&header, localize("Skins"), 18.0f, 0); - - // draw footers - skinselection.HSplitBottom(20, &skinselection, &footer); - RenderTools()->DrawUIRect(&footer, vec4(1,1,1,0.25f), CUI::CORNER_B, 5.0f); - footer.VSplitLeft(10.0f, 0, &footer); - - // modes - RenderTools()->DrawUIRect(&skinselection, vec4(0,0,0,0.15f), 0, 0); - - CUIRect scroll; - skinselection.VSplitRight(15, &skinselection, &scroll); - - CUIRect list = skinselection; - list.HSplitTop(50, &button, &list); - - int num = (int)(skinselection.h/button.h); - static float scrollvalue = 0; - static int scrollbar = 0; - scroll.HMargin(5.0f, &scroll); - scrollvalue = ui_do_scrollbar_v(&scrollbar, &scroll, scrollvalue); - - int start = (int)((gameclient.skins->num()-num)*scrollvalue); - if(start < 0) - start = 0; - - for(int i = start; i < start+num && i < gameclient.skins->num(); i++) - { - const SKINS::SKIN *s = gameclient.skins->get(i); - - // no special skins - if(s->name[0] == 'x' && s->name[1] == '_') - { - num++; - continue; - } - - char buf[128]; - str_format(buf, sizeof(buf), "%s", s->name); - int selected = 0; - if(strcmp(s->name, config.player_skin) == 0) - selected = 1; - - TEE_RENDER_INFO info; - info.texture = s->org_texture; - info.color_body = vec4(1,1,1,1); - info.color_feet = vec4(1,1,1,1); - if(config.player_use_custom_color) - { - info.color_body = gameclient.skins->get_color(config.player_color_body); - info.color_feet = gameclient.skins->get_color(config.player_color_feet); - info.texture = s->color_texture; - } - - info.size = UI()->Scale()*50.0f; - - CUIRect icon; - CUIRect text; - button.VSplitLeft(50.0f, &icon, &text); - - if(UI()->DoButton(s, "", selected, &button, ui_draw_list_row, 0)) - { - config_set_player_skin(&config, s->name); - need_sendinfo = true; - } - text.HSplitTop(12.0f, 0, &text); // some margin from the top - UI()->DoLabel(&text, buf, 18.0f, 0); - - icon.HSplitTop(5.0f, 0, &icon); // some margin from the top - RenderTools()->RenderTee(ANIMSTATE::get_idle(), &info, 0, vec2(1, 0), vec2(icon.x+icon.w/2, icon.y+icon.h/2)); - - if(config.debug) + const int NewSelected = UiDoListboxEnd(&s_ScrollValue, 0); + if(OldSelected != NewSelected) { - Graphics()->TextureSet(-1); - Graphics()->QuadsBegin(); - Graphics()->SetColor(s->blood_color.r, s->blood_color.g, s->blood_color.b, 1.0f); - Graphics()->QuadsDrawTL(icon.x, icon.y, 12, 12); - Graphics()->QuadsEnd(); + mem_copy(g_Config.m_PlayerSkin, s_paSkinList[NewSelected]->m_aName, sizeof(g_Config.m_PlayerSkin)); + m_NeedSendinfo = true; } - - list.HSplitTop(50, &button, &list); - }*/ + } } -typedef void (*assign_func_callback)(CONFIGURATION *config, int value); +typedef void (*pfnAssignFuncCallback)(CConfiguration *pConfig, int Value); -typedef struct +typedef struct { - LOC_CONSTSTRING name; - const char *command; - int keyid; -} KEYINFO; + CLocConstString m_Name; + const char *m_pCommand; + int m_KeyId; +} CKeyInfo; -static KEYINFO keys[] = +static CKeyInfo gs_aKeys[] = { // we need to do localize so the scripts can pickup the string - { localize("Move left"), "+left", 0}, - { localize("Move right"), "+right", 0 }, - { localize("Jump"), "+jump", 0 }, - { localize("Fire"), "+fire", 0 }, - { localize("Hook"), "+hook", 0 }, - { localize("Hammer"), "+weapon1", 0 }, - { localize("Pistol"), "+weapon2", 0 }, - { localize("Shotgun"), "+weapon3", 0 }, - { localize("Grenade"), "+weapon4", 0 }, - { localize("Rifle"), "+weapon5", 0 }, - { localize("Next weapon"), "+nextweapon", 0 }, - { localize("Prev. weapon"), "+prevweapon", 0 }, - { localize("Vote yes"), "vote yes", 0 }, - { localize("Vote no"), "vote no", 0 }, - { localize("Chat"), "chat all", 0 }, - { localize("Team chat"), "chat team", 0 }, - { localize("Emoticon"), "+emote", 0 }, - { localize("Console"), "toggle_local_console", 0 }, - { localize("Remote console"), "toggle_remote_console", 0 }, - { localize("Screenshot"), "screenshot", 0 }, - { localize("Scoreboard"), "+scoreboard", 0 }, + { Localize("Move left"), "+left", 0}, + { Localize("Move right"), "+right", 0 }, + { Localize("Jump"), "+jump", 0 }, + { Localize("Fire"), "+fire", 0 }, + { Localize("Hook"), "+hook", 0 }, + { Localize("Hammer"), "+weapon1", 0 }, + { Localize("Pistol"), "+weapon2", 0 }, + { Localize("Shotgun"), "+weapon3", 0 }, + { Localize("Grenade"), "+weapon4", 0 }, + { Localize("Rifle"), "+weapon5", 0 }, + { Localize("Next weapon"), "+nextweapon", 0 }, + { Localize("Prev. weapon"), "+prevweapon", 0 }, + { Localize("Vote yes"), "vote yes", 0 }, + { Localize("Vote no"), "vote no", 0 }, + { Localize("Chat"), "chat all", 0 }, + { Localize("Team chat"), "chat team", 0 }, + { Localize("Emoticon"), "+emote", 0 }, + { Localize("Console"), "toggle_local_console", 0 }, + { Localize("Remote console"), "toggle_remote_console", 0 }, + { Localize("Screenshot"), "screenshot", 0 }, + { Localize("Scoreboard"), "+scoreboard", 0 }, }; -const int key_count = sizeof(keys) / sizeof(KEYINFO); +const int g_KeyCount = sizeof(gs_aKeys) / sizeof(CKeyInfo); -void MENUS::ui_do_getbuttons(int start, int stop, CUIRect view) +void CMenus::UiDoGetButtons(int Start, int Stop, CUIRect View) { - for (int i = start; i < stop; i++) + for (int i = Start; i < Stop; i++) { - KEYINFO &key = keys[i]; - CUIRect button, label; - view.HSplitTop(20.0f, &button, &view); - button.VSplitLeft(130.0f, &label, &button); - - char buf[64]; - str_format(buf, sizeof(buf), "%s:", (const char *)key.name); - - UI()->DoLabel(&label, key.name, 14.0f, -1); - int oldid = key.keyid; - int newid = DoKeyReader((void *)&keys[i].name, &button, oldid); - if(newid != oldid) + CKeyInfo &Key = gs_aKeys[i]; + CUIRect Button, Label; + View.HSplitTop(20.0f, &Button, &View); + Button.VSplitLeft(130.0f, &Label, &Button); + + char aBuf[64]; + str_format(aBuf, sizeof(aBuf), "%s:", (const char *)Key.m_Name); + + UI()->DoLabel(&Label, aBuf, 14.0f, -1); + int OldId = Key.m_KeyId; + int NewId = DoKeyReader((void *)&gs_aKeys[i].m_Name, &Button, OldId); + if(NewId != OldId) { - gameclient.binds->bind(oldid, ""); - gameclient.binds->bind(newid, keys[i].command); + m_pClient->m_pBinds->Bind(OldId, ""); + m_pClient->m_pBinds->Bind(NewId, gs_aKeys[i].m_pCommand); } - view.HSplitTop(5.0f, 0, &view); + View.HSplitTop(5.0f, 0, &View); } } -void MENUS::render_settings_controls(CUIRect main_view) +void CMenus::RenderSettingsControls(CUIRect MainView) { // this is kinda slow, but whatever - for(int i = 0; i < key_count; i++) - keys[i].keyid = 0; - - for(int keyid = 0; keyid < KEY_LAST; keyid++) + for(int i = 0; i < g_KeyCount; i++) + gs_aKeys[i].m_KeyId = 0; + + for(int KeyId = 0; KeyId < KEY_LAST; KeyId++) { - const char *bind = gameclient.binds->get(keyid); - if(!bind[0]) + const char *pBind = m_pClient->m_pBinds->Get(KeyId); + if(!pBind[0]) continue; - - for(int i = 0; i < key_count; i++) - if(strcmp(bind, keys[i].command) == 0) + + for(int i = 0; i < g_KeyCount; i++) + if(str_comp(pBind, gs_aKeys[i].m_pCommand) == 0) { - keys[i].keyid = keyid; + gs_aKeys[i].m_KeyId = KeyId; break; } } - CUIRect movement_settings, weapon_settings, voting_settings, chat_settings, misc_settings, reset_button; - main_view.VSplitLeft(main_view.w/2-5.0f, &movement_settings, &voting_settings); - - /* movement settings */ + CUIRect MovementSettings, WeaponSettings, VotingSettings, ChatSettings, MiscSettings, ResetButton; + MainView.VSplitLeft(MainView.w/2-5.0f, &MovementSettings, &VotingSettings); + + // movement settings { - movement_settings.HSplitTop(main_view.h/2-5.0f, &movement_settings, &weapon_settings); - RenderTools()->DrawUIRect(&movement_settings, vec4(1,1,1,0.25f), CUI::CORNER_ALL, 10.0f); - movement_settings.Margin(10.0f, &movement_settings); - - gfx_text(0, movement_settings.x, movement_settings.y, 14, localize("Movement"), -1); - - movement_settings.HSplitTop(14.0f+5.0f+10.0f, 0, &movement_settings); - + MovementSettings.HSplitTop(MainView.h/2-5.0f, &MovementSettings, &WeaponSettings); + RenderTools()->DrawUIRect(&MovementSettings, vec4(1,1,1,0.25f), CUI::CORNER_ALL, 10.0f); + MovementSettings.Margin(10.0f, &MovementSettings); + + TextRender()->Text(0, MovementSettings.x, MovementSettings.y, 14, Localize("Movement"), -1); + + MovementSettings.HSplitTop(14.0f+5.0f+10.0f, 0, &MovementSettings); + { - CUIRect button, label; - movement_settings.HSplitTop(20.0f, &button, &movement_settings); - button.VSplitLeft(130.0f, &label, &button); - UI()->DoLabel(&label, localize("Mouse sens."), 14.0f, -1); - button.HMargin(2.0f, &button); - config.inp_mousesens = (int)(DoScrollbarV(&config.inp_mousesens, &button, (config.inp_mousesens-5)/500.0f)*500.0f)+5; - //*key.key = ui_do_key_reader(key.key, &button, *key.key); - movement_settings.HSplitTop(20.0f, 0, &movement_settings); + CUIRect Button, Label; + MovementSettings.HSplitTop(20.0f, &Button, &MovementSettings); + Button.VSplitLeft(130.0f, &Label, &Button); + UI()->DoLabel(&Label, Localize("Mouse sens."), 14.0f, -1); + Button.HMargin(2.0f, &Button); + g_Config.m_InpMousesens = (int)(DoScrollbarH(&g_Config.m_InpMousesens, &Button, (g_Config.m_InpMousesens-5)/500.0f)*500.0f)+5; + //*key.key = ui_do_key_reader(key.key, &Button, *key.key); + MovementSettings.HSplitTop(20.0f, 0, &MovementSettings); } - - ui_do_getbuttons(0, 5, movement_settings); + + UiDoGetButtons(0, 5, MovementSettings); } - - /* weapon settings */ + + // weapon settings { - weapon_settings.HSplitTop(10.0f, 0, &weapon_settings); - RenderTools()->DrawUIRect(&weapon_settings, vec4(1,1,1,0.25f), CUI::CORNER_ALL, 10.0f); - weapon_settings.Margin(10.0f, &weapon_settings); - - gfx_text(0, weapon_settings.x, weapon_settings.y, 14, localize("Weapon"), -1); - - weapon_settings.HSplitTop(14.0f+5.0f+10.0f, 0, &weapon_settings); - ui_do_getbuttons(5, 12, weapon_settings); + WeaponSettings.HSplitTop(10.0f, 0, &WeaponSettings); + RenderTools()->DrawUIRect(&WeaponSettings, vec4(1,1,1,0.25f), CUI::CORNER_ALL, 10.0f); + WeaponSettings.Margin(10.0f, &WeaponSettings); + + TextRender()->Text(0, WeaponSettings.x, WeaponSettings.y, 14, Localize("Weapon"), -1); + + WeaponSettings.HSplitTop(14.0f+5.0f+10.0f, 0, &WeaponSettings); + UiDoGetButtons(5, 12, WeaponSettings); } - - /* voting settings */ + + // voting settings { - voting_settings.VSplitLeft(10.0f, 0, &voting_settings); - voting_settings.HSplitTop(main_view.h/4-5.0f, &voting_settings, &chat_settings); - RenderTools()->DrawUIRect(&voting_settings, vec4(1,1,1,0.25f), CUI::CORNER_ALL, 10.0f); - voting_settings.Margin(10.0f, &voting_settings); - - gfx_text(0, voting_settings.x, voting_settings.y, 14, localize("Voting"), -1); - - voting_settings.HSplitTop(14.0f+5.0f+10.0f, 0, &voting_settings); - ui_do_getbuttons(12, 14, voting_settings); + VotingSettings.VSplitLeft(10.0f, 0, &VotingSettings); + VotingSettings.HSplitTop(MainView.h/4-5.0f, &VotingSettings, &ChatSettings); + RenderTools()->DrawUIRect(&VotingSettings, vec4(1,1,1,0.25f), CUI::CORNER_ALL, 10.0f); + VotingSettings.Margin(10.0f, &VotingSettings); + + TextRender()->Text(0, VotingSettings.x, VotingSettings.y, 14, Localize("Voting"), -1); + + VotingSettings.HSplitTop(14.0f+5.0f+10.0f, 0, &VotingSettings); + UiDoGetButtons(12, 14, VotingSettings); } - - /* chat settings */ + + // chat settings { - chat_settings.HSplitTop(10.0f, 0, &chat_settings); - chat_settings.HSplitTop(main_view.h/4-10.0f, &chat_settings, &misc_settings); - RenderTools()->DrawUIRect(&chat_settings, vec4(1,1,1,0.25f), CUI::CORNER_ALL, 10.0f); - chat_settings.Margin(10.0f, &chat_settings); - - gfx_text(0, chat_settings.x, chat_settings.y, 14, localize("Chat"), -1); - - chat_settings.HSplitTop(14.0f+5.0f+10.0f, 0, &chat_settings); - ui_do_getbuttons(14, 16, chat_settings); + ChatSettings.HSplitTop(10.0f, 0, &ChatSettings); + ChatSettings.HSplitTop(MainView.h/4-10.0f, &ChatSettings, &MiscSettings); + RenderTools()->DrawUIRect(&ChatSettings, vec4(1,1,1,0.25f), CUI::CORNER_ALL, 10.0f); + ChatSettings.Margin(10.0f, &ChatSettings); + + TextRender()->Text(0, ChatSettings.x, ChatSettings.y, 14, Localize("Chat"), -1); + + ChatSettings.HSplitTop(14.0f+5.0f+10.0f, 0, &ChatSettings); + UiDoGetButtons(14, 16, ChatSettings); } - - /* misc settings */ + + // misc settings { - misc_settings.HSplitTop(10.0f, 0, &misc_settings); - misc_settings.HSplitTop(main_view.h/2-5.0f-45.0f, &misc_settings, &reset_button); - RenderTools()->DrawUIRect(&misc_settings, vec4(1,1,1,0.25f), CUI::CORNER_ALL, 10.0f); - misc_settings.Margin(10.0f, &misc_settings); - - gfx_text(0, misc_settings.x, misc_settings.y, 14, localize("Miscellaneous"), -1); - - misc_settings.HSplitTop(14.0f+5.0f+10.0f, 0, &misc_settings); - ui_do_getbuttons(16, 21, misc_settings); + MiscSettings.HSplitTop(10.0f, 0, &MiscSettings); + MiscSettings.HSplitTop(MainView.h/2-5.0f-45.0f, &MiscSettings, &ResetButton); + RenderTools()->DrawUIRect(&MiscSettings, vec4(1,1,1,0.25f), CUI::CORNER_ALL, 10.0f); + MiscSettings.Margin(10.0f, &MiscSettings); + + TextRender()->Text(0, MiscSettings.x, MiscSettings.y, 14, Localize("Miscellaneous"), -1); + + MiscSettings.HSplitTop(14.0f+5.0f+10.0f, 0, &MiscSettings); + UiDoGetButtons(16, 21, MiscSettings); } - + // defaults - reset_button.HSplitTop(10.0f, 0, &reset_button); - static int default_button = 0; - if(DoButton_Menu((void*)&default_button, localize("Reset to defaults"), 0, &reset_button)) - gameclient.binds->set_defaults(); + ResetButton.HSplitTop(10.0f, 0, &ResetButton); + static int s_DefaultButton = 0; + if(DoButton_Menu((void*)&s_DefaultButton, Localize("Reset to defaults"), 0, &ResetButton)) + m_pClient->m_pBinds->SetDefaults(); } -void MENUS::render_settings_graphics(CUIRect main_view) +void CMenus::RenderSettingsGraphics(CUIRect MainView) { - CUIRect button; - char buf[128]; - + CUIRect Button; + char aBuf[128]; + static const int MAX_RESOLUTIONS = 256; - static VIDEO_MODE modes[MAX_RESOLUTIONS]; - static int num_modes = -1; - - if(num_modes == -1) - num_modes = gfx_get_video_modes(modes, MAX_RESOLUTIONS); - - CUIRect modelist; - main_view.VSplitLeft(300.0f, &main_view, &modelist); - + static CVideoMode s_aModes[MAX_RESOLUTIONS]; + static int s_NumNodes = -1; + const static int s_GfxScreenWidth = g_Config.m_GfxScreenWidth; + const static int s_GfxScreenHeight = g_Config.m_GfxScreenHeight; + const static int s_GfxColorDepth = g_Config.m_GfxColorDepth; + + if(s_NumNodes == -1) + s_NumNodes = Graphics()->GetVideoModes(s_aModes, MAX_RESOLUTIONS); + + CUIRect ModeList; + MainView.VSplitLeft(300.0f, &MainView, &ModeList); + // draw allmodes switch - CUIRect header, footer; - modelist.HSplitTop(20, &button, &modelist); - if(DoButton_CheckBox(&config.gfx_display_all_modes, localize("Show only supported"), config.gfx_display_all_modes^1, &button)) + ModeList.HSplitTop(20, &Button, &ModeList); + if(DoButton_CheckBox(&g_Config.m_GfxDisplayAllModes, Localize("Show only supported"), g_Config.m_GfxDisplayAllModes^1, &Button)) { - config.gfx_display_all_modes ^= 1; - num_modes = gfx_get_video_modes(modes, MAX_RESOLUTIONS); + g_Config.m_GfxDisplayAllModes ^= 1; + s_NumNodes = Graphics()->GetVideoModes(s_aModes, MAX_RESOLUTIONS); } - - // draw header - modelist.HSplitTop(20, &header, &modelist); - RenderTools()->DrawUIRect(&header, vec4(1,1,1,0.25f), CUI::CORNER_T, 5.0f); - UI()->DoLabel(&header, localize("Display Modes"), 14.0f, 0); - - // draw footers - modelist.HSplitBottom(20, &modelist, &footer); - str_format(buf, sizeof(buf), "%s: %dx%d %d bit", localize("Current"), config.gfx_screen_width, config.gfx_screen_height, config.gfx_color_depth); - RenderTools()->DrawUIRect(&footer, vec4(1,1,1,0.25f), CUI::CORNER_B, 5.0f); - footer.VSplitLeft(10.0f, 0, &footer); - UI()->DoLabel(&footer, buf, 14.0f, -1); - - // modes - RenderTools()->DrawUIRect(&modelist, vec4(0,0,0,0.15f), 0, 0); - - CUIRect scroll; - modelist.VSplitRight(15, &modelist, &scroll); - - CUIRect list = modelist; - list.HSplitTop(20, &button, &list); - - int num = (int)(modelist.h/button.h); - static float scrollvalue = 0; - static int scrollbar = 0; - scroll.HMargin(5.0f, &scroll); - scrollvalue = DoScrollbarV(&scrollbar, &scroll, scrollvalue); - - int start = (int)((num_modes-num)*scrollvalue); - if(start < 0) - start = 0; - - for(int i = start; i < start+num && i < num_modes; i++) + + // display mode list + static float s_ScrollValue = 0; + int OldSelected = -1; + str_format(aBuf, sizeof(aBuf), "%s: %dx%d %d bit", Localize("Current"), s_GfxScreenWidth, s_GfxScreenHeight, s_GfxColorDepth); + UiDoListboxStart(&s_NumNodes , &ModeList, 24.0f, Localize("Display Modes"), aBuf, s_NumNodes, 1, OldSelected, s_ScrollValue); + + for(int i = 0; i < s_NumNodes; ++i) { - int depth = modes[i].red+modes[i].green+modes[i].blue; - if(depth < 16) - depth = 16; - else if(depth > 16) - depth = 24; - - int selected = 0; - if(config.gfx_color_depth == depth && - config.gfx_screen_width == modes[i].width && - config.gfx_screen_height == modes[i].height) + const int Depth = s_aModes[i].m_Red+s_aModes[i].m_Green+s_aModes[i].m_Blue > 16 ? 24 : 16; + if(g_Config.m_GfxColorDepth == Depth && + g_Config.m_GfxScreenWidth == s_aModes[i].m_Width && + g_Config.m_GfxScreenHeight == s_aModes[i].m_Height) { - selected = 1; + OldSelected = i; } - - str_format(buf, sizeof(buf), " %dx%d %d bit", modes[i].width, modes[i].height, depth); - if(DoButton_ListRow(&modes[i], buf, selected, &button)) + + CListboxItem Item = UiDoListboxNextItem(&s_aModes[i], OldSelected == i); + if(Item.m_Visible) { - config.gfx_color_depth = depth; - config.gfx_screen_width = modes[i].width; - config.gfx_screen_height = modes[i].height; - if(!selected) - need_restart = true; + str_format(aBuf, sizeof(aBuf), " %dx%d %d bit", s_aModes[i].m_Width, s_aModes[i].m_Height, Depth); + UI()->DoLabel(&Item.m_Rect, aBuf, 16.0f, -1); } - - list.HSplitTop(20, &button, &list); } - - + + const int NewSelected = UiDoListboxEnd(&s_ScrollValue, 0); + if(OldSelected != NewSelected) + { + const int Depth = s_aModes[NewSelected].m_Red+s_aModes[NewSelected].m_Green+s_aModes[NewSelected].m_Blue > 16 ? 24 : 16; + g_Config.m_GfxColorDepth = Depth; + g_Config.m_GfxScreenWidth = s_aModes[NewSelected].m_Width; + g_Config.m_GfxScreenHeight = s_aModes[NewSelected].m_Height; + m_NeedRestart = true; + } + // switches - main_view.HSplitTop(20.0f, &button, &main_view); - if(DoButton_CheckBox(&config.gfx_fullscreen, localize("Fullscreen"), config.gfx_fullscreen, &button)) + MainView.HSplitTop(20.0f, &Button, &MainView); + if(DoButton_CheckBox(&g_Config.m_GfxFullscreen, Localize("Fullscreen"), g_Config.m_GfxFullscreen, &Button)) { - config.gfx_fullscreen ^= 1; - need_restart = true; + g_Config.m_GfxFullscreen ^= 1; + m_NeedRestart = true; } - main_view.HSplitTop(20.0f, &button, &main_view); - if(DoButton_CheckBox(&config.gfx_vsync, localize("V-Sync"), config.gfx_vsync, &button)) + MainView.HSplitTop(20.0f, &Button, &MainView); + if(DoButton_CheckBox(&g_Config.m_GfxVsync, Localize("V-Sync"), g_Config.m_GfxVsync, &Button)) { - config.gfx_vsync ^= 1; - need_restart = true; + g_Config.m_GfxVsync ^= 1; + m_NeedRestart = true; } - main_view.HSplitTop(20.0f, &button, &main_view); - if(DoButton_CheckBox_Number(&config.gfx_fsaa_samples, localize("FSAA samples"), config.gfx_fsaa_samples, &button)) + MainView.HSplitTop(20.0f, &Button, &MainView); + if(DoButton_CheckBox_Number(&g_Config.m_GfxFsaaSamples, Localize("FSAA samples"), g_Config.m_GfxFsaaSamples, &Button)) { - config.gfx_fsaa_samples = (config.gfx_fsaa_samples+1)%17; - need_restart = true; + g_Config.m_GfxFsaaSamples = (g_Config.m_GfxFsaaSamples+1)%17; + m_NeedRestart = true; } - - main_view.HSplitTop(40.0f, &button, &main_view); - main_view.HSplitTop(20.0f, &button, &main_view); - if(DoButton_CheckBox(&config.gfx_texture_quality, localize("Quality Textures"), config.gfx_texture_quality, &button)) + + MainView.HSplitTop(40.0f, &Button, &MainView); + MainView.HSplitTop(20.0f, &Button, &MainView); + if(DoButton_CheckBox(&g_Config.m_GfxTextureQuality, Localize("Quality Textures"), g_Config.m_GfxTextureQuality, &Button)) { - config.gfx_texture_quality ^= 1; - need_restart = true; + g_Config.m_GfxTextureQuality ^= 1; + m_NeedRestart = true; } - main_view.HSplitTop(20.0f, &button, &main_view); - if(DoButton_CheckBox(&config.gfx_texture_compression, localize("Texture Compression"), config.gfx_texture_compression, &button)) + MainView.HSplitTop(20.0f, &Button, &MainView); + if(DoButton_CheckBox(&g_Config.m_GfxTextureCompression, Localize("Texture Compression"), g_Config.m_GfxTextureCompression, &Button)) { - config.gfx_texture_compression ^= 1; - need_restart = true; + g_Config.m_GfxTextureCompression ^= 1; + m_NeedRestart = true; } - main_view.HSplitTop(20.0f, &button, &main_view); - if(DoButton_CheckBox(&config.gfx_high_detail, localize("High Detail"), config.gfx_high_detail, &button)) - config.gfx_high_detail ^= 1; + MainView.HSplitTop(20.0f, &Button, &MainView); + if(DoButton_CheckBox(&g_Config.m_GfxHighDetail, Localize("High Detail"), g_Config.m_GfxHighDetail, &Button)) + g_Config.m_GfxHighDetail ^= 1; // - - CUIRect text; - main_view.HSplitTop(20.0f, 0, &main_view); - main_view.HSplitTop(20.0f, &text, &main_view); + + CUIRect Text; + MainView.HSplitTop(20.0f, 0, &MainView); + MainView.HSplitTop(20.0f, &Text, &MainView); //text.VSplitLeft(15.0f, 0, &text); - UI()->DoLabel(&text, localize("UI Color"), 14.0f, -1); - - const char *labels[] = { - localize("Hue"), - localize("Sat."), - localize("Lht."), - localize("Alpha")}; - int *color_slider[4] = {&config.ui_color_hue, &config.ui_color_sat, &config.ui_color_lht, &config.ui_color_alpha}; + UI()->DoLabel(&Text, Localize("UI Color"), 14.0f, -1); + + const char *paLabels[] = { + Localize("Hue"), + Localize("Sat."), + Localize("Lht."), + Localize("Alpha")}; + int *pColorSlider[4] = {&g_Config.m_UiColorHue, &g_Config.m_UiColorSat, &g_Config.m_UiColorLht, &g_Config.m_UiColorAlpha}; for(int s = 0; s < 4; s++) { - CUIRect text; - main_view.HSplitTop(19.0f, &button, &main_view); - button.VMargin(15.0f, &button); - button.VSplitLeft(50.0f, &text, &button); - button.VSplitRight(5.0f, &button, 0); - button.HSplitTop(4.0f, 0, &button); - - float k = (*color_slider[s]) / 255.0f; - k = DoScrollbarH(color_slider[s], &button, k); - *color_slider[s] = (int)(k*255.0f); - UI()->DoLabel(&text, labels[s], 15.0f, -1); - } + CUIRect Text; + MainView.HSplitTop(19.0f, &Button, &MainView); + Button.VMargin(15.0f, &Button); + Button.VSplitLeft(50.0f, &Text, &Button); + Button.VSplitRight(5.0f, &Button, 0); + Button.HSplitTop(4.0f, 0, &Button); + + float k = (*pColorSlider[s]) / 255.0f; + k = DoScrollbarH(pColorSlider[s], &Button, k); + *pColorSlider[s] = (int)(k*255.0f); + UI()->DoLabel(&Text, paLabels[s], 15.0f, -1); + } } -void MENUS::render_settings_sound(CUIRect main_view) +void CMenus::RenderSettingsSound(CUIRect MainView) { - CUIRect button; - main_view.VSplitLeft(300.0f, &main_view, 0); - - main_view.HSplitTop(20.0f, &button, &main_view); - if(DoButton_CheckBox(&config.snd_enable, localize("Use sounds"), config.snd_enable, &button)) + CUIRect Button; + MainView.VSplitLeft(300.0f, &MainView, 0); + + MainView.HSplitTop(20.0f, &Button, &MainView); + if(DoButton_CheckBox(&g_Config.m_SndEnable, Localize("Use sounds"), g_Config.m_SndEnable, &Button)) { - config.snd_enable ^= 1; - need_restart = true; + g_Config.m_SndEnable ^= 1; + m_NeedRestart = true; } - - if(!config.snd_enable) + + if(!g_Config.m_SndEnable) return; - - main_view.HSplitTop(20.0f, &button, &main_view); - if(DoButton_CheckBox(&config.snd_nonactive_mute, localize("Mute when not active"), config.snd_nonactive_mute, &button)) - config.snd_nonactive_mute ^= 1; - + + MainView.HSplitTop(20.0f, &Button, &MainView); + if(DoButton_CheckBox(&g_Config.m_SndNonactiveMute, Localize("Mute when not active"), g_Config.m_SndNonactiveMute, &Button)) + g_Config.m_SndNonactiveMute ^= 1; + // sample rate box { - char buf[64]; - str_format(buf, sizeof(buf), "%d", config.snd_rate); - main_view.HSplitTop(20.0f, &button, &main_view); - UI()->DoLabel(&button, localize("Sample rate"), 14.0f, -1); - button.VSplitLeft(110.0f, 0, &button); - button.VSplitLeft(180.0f, &button, 0); - DoEditBox(&config.snd_rate, &button, buf, sizeof(buf), 14.0f); - int before = config.snd_rate; - config.snd_rate = atoi(buf); - - if(config.snd_rate != before) - need_restart = true; - - if(config.snd_rate < 1) - config.snd_rate = 1; + char aBuf[64]; + str_format(aBuf, sizeof(aBuf), "%d", g_Config.m_SndRate); + MainView.HSplitTop(20.0f, &Button, &MainView); + UI()->DoLabel(&Button, Localize("Sample rate"), 14.0f, -1); + Button.VSplitLeft(110.0f, 0, &Button); + Button.VSplitLeft(180.0f, &Button, 0); + DoEditBox(&g_Config.m_SndRate, &Button, aBuf, sizeof(aBuf), 14.0f); + int Before = g_Config.m_SndRate; + g_Config.m_SndRate = str_toint(aBuf); + + if(g_Config.m_SndRate != Before) + m_NeedRestart = true; + + if(g_Config.m_SndRate < 1) + g_Config.m_SndRate = 1; } - + // volume slider { - CUIRect button, label; - main_view.HSplitTop(5.0f, &button, &main_view); - main_view.HSplitTop(20.0f, &button, &main_view); - button.VSplitLeft(110.0f, &label, &button); - button.HMargin(2.0f, &button); - UI()->DoLabel(&label, localize("Sound volume"), 14.0f, -1); - config.snd_volume = (int)(DoScrollbarH(&config.snd_volume, &button, config.snd_volume/100.0f)*100.0f); - main_view.HSplitTop(20.0f, 0, &main_view); + CUIRect Button, Label; + MainView.HSplitTop(5.0f, &Button, &MainView); + MainView.HSplitTop(20.0f, &Button, &MainView); + Button.VSplitLeft(110.0f, &Label, &Button); + Button.HMargin(2.0f, &Button); + UI()->DoLabel(&Label, Localize("Sound volume"), 14.0f, -1); + g_Config.m_SndVolume = (int)(DoScrollbarH(&g_Config.m_SndVolume, &Button, g_Config.m_SndVolume/100.0f)*100.0f); + MainView.HSplitTop(20.0f, 0, &MainView); } } struct LANGUAGE { LANGUAGE() {} - LANGUAGE(const char *n, const char *f) : name(n), filename(f) {} - - string name; - string filename; - - bool operator<(const LANGUAGE &other) { return name < other.name; } + LANGUAGE(const char *n, const char *f) : m_Name(n), m_FileName(f) {} + + string m_Name; + string m_FileName; + + bool operator<(const LANGUAGE &Other) { return m_Name < Other.m_Name; } }; -int fs_listdir(const char *dir, FS_LISTDIR_CALLBACK cb, void *user); +int fs_listdir(const char *pDir, FS_LISTDIR_CALLBACK cb, void *pUser); -void gather_languages(const char *name, int is_dir, void *user) +void GatherLanguages(const char *pName, int IsDir, void *pUser) { - if(is_dir || name[0] == '.') + if(IsDir || pName[0] == '.') return; - - sorted_array<LANGUAGE> &languages = *((sorted_array<LANGUAGE> *)user); - char filename[128]; - str_format(filename, sizeof(filename), "data/languages/%s", name); - - char nicename[128]; - str_format(nicename, sizeof(nicename), "%s", name); - nicename[0] = str_uppercase(nicename[0]); - - - for(char *p = nicename; *p; p++) + + sorted_array<LANGUAGE> &Languages = *((sorted_array<LANGUAGE> *)pUser); + char aFileName[128]; + str_format(aFileName, sizeof(aFileName), "data/languages/%s", pName); + + char NiceName[128]; + str_format(NiceName, sizeof(NiceName), "%s", pName); + NiceName[0] = str_uppercase(NiceName[0]); + + + for(char *p = NiceName; *p; p++) if(*p == '.') *p = 0; - - languages.add(LANGUAGE(nicename, filename)); + + Languages.add(LANGUAGE(NiceName, aFileName)); } -void MENUS::render_settings_general(CUIRect main_view) +void CMenus::RenderSettingsGeneral(CUIRect MainView) { - static int lanuagelist = 0; - static int selected_language = 0; - static sorted_array<LANGUAGE> languages; - - if(languages.size() == 0) + static int s_LanguageList = 0; + static int s_SelectedLanguage = 0; + static sorted_array<LANGUAGE> s_Languages; + static float s_ScrollValue = 0; + + if(s_Languages.size() == 0) { - languages.add(LANGUAGE("English", "")); - fs_listdir("data/languages", gather_languages, &languages); - for(int i = 0; i < languages.size(); i++) - if(str_comp(languages[i].filename, config.cl_languagefile) == 0) + s_Languages.add(LANGUAGE("English", "")); + fs_listdir("data/languages", GatherLanguages, &s_Languages); + for(int i = 0; i < s_Languages.size(); i++) + if(str_comp(s_Languages[i].m_FileName, g_Config.m_ClLanguagefile) == 0) { - selected_language = i; + s_SelectedLanguage = i; break; } } - - int old_selected = selected_language; - - CUIRect list = main_view; - ui_do_listbox_start(&lanuagelist, &list, 24.0f, localize("Language"), languages.size(), selected_language); - - for(sorted_array<LANGUAGE>::range r = languages.all(); !r.empty(); r.pop_front()) + + int OldSelected = s_SelectedLanguage; + + CUIRect List = MainView; + UiDoListboxStart(&s_LanguageList , &List, 24.0f, Localize("Language"), "", s_Languages.size(), 1, s_SelectedLanguage, s_ScrollValue); + + for(sorted_array<LANGUAGE>::range r = s_Languages.all(); !r.empty(); r.pop_front()) { - LISTBOXITEM item = ui_do_listbox_nextitem(&r.front()); - - if(item.visible) - UI()->DoLabel(&item.rect, r.front().name, 16.0f, -1); + CListboxItem Item = UiDoListboxNextItem(&r.front()); + + if(Item.m_Visible) + UI()->DoLabel(&Item.m_Rect, r.front().m_Name, 16.0f, -1); } - - selected_language = ui_do_listbox_end(); - - if(old_selected != selected_language) + + s_SelectedLanguage = UiDoListboxEnd(&s_ScrollValue, 0); + + if(OldSelected != s_SelectedLanguage) { - str_copy(config.cl_languagefile, languages[selected_language].filename, sizeof(config.cl_languagefile)); - localization.load(languages[selected_language].filename); + str_copy(g_Config.m_ClLanguagefile, s_Languages[s_SelectedLanguage].m_FileName, sizeof(g_Config.m_ClLanguagefile)); + g_Localization.Load(s_Languages[s_SelectedLanguage].m_FileName); } } -void MENUS::render_settings(CUIRect main_view) +void CMenus::RenderSettings(CUIRect MainView) { - static int settings_page = 0; - + static int s_SettingsPage = 0; + // render background - CUIRect temp, tabbar; - main_view.VSplitRight(120.0f, &main_view, &tabbar); - RenderTools()->DrawUIRect(&main_view, color_tabbar_active, CUI::CORNER_B|CUI::CORNER_TL, 10.0f); - tabbar.HSplitTop(50.0f, &temp, &tabbar); - RenderTools()->DrawUIRect(&temp, color_tabbar_active, CUI::CORNER_R, 10.0f); - - main_view.HSplitTop(10.0f, 0, &main_view); - - CUIRect button; - - const char *tabs[] = { - localize("General"), - localize("Player"), - localize("Controls"), - localize("Graphics"), - localize("Sound")}; - - int num_tabs = (int)(sizeof(tabs)/sizeof(*tabs)); - - for(int i = 0; i < num_tabs; i++) + CUIRect Temp, TabBar; + MainView.VSplitRight(120.0f, &MainView, &TabBar); + RenderTools()->DrawUIRect(&MainView, ms_ColorTabbarActive, CUI::CORNER_B|CUI::CORNER_TL, 10.0f); + TabBar.HSplitTop(50.0f, &Temp, &TabBar); + RenderTools()->DrawUIRect(&Temp, ms_ColorTabbarActive, CUI::CORNER_R, 10.0f); + + MainView.HSplitTop(10.0f, 0, &MainView); + + CUIRect Button; + + const char *aTabs[] = { + Localize("General"), + Localize("Player"), + Localize("Controls"), + Localize("Graphics"), + Localize("Sound")}; + + int NumTabs = (int)(sizeof(aTabs)/sizeof(*aTabs)); + + for(int i = 0; i < NumTabs; i++) { - tabbar.HSplitTop(10, &button, &tabbar); - tabbar.HSplitTop(26, &button, &tabbar); - if(DoButton_SettingsTab(tabs[i], tabs[i], settings_page == i, &button)) - settings_page = i; + TabBar.HSplitTop(10, &Button, &TabBar); + TabBar.HSplitTop(26, &Button, &TabBar); + if(DoButton_SettingsTab(aTabs[i], aTabs[i], s_SettingsPage == i, &Button)) + s_SettingsPage = i; } - - main_view.Margin(10.0f, &main_view); - - if(settings_page == 0) - render_settings_general(main_view); - else if(settings_page == 1) - render_settings_player(main_view); - else if(settings_page == 2) - render_settings_controls(main_view); - else if(settings_page == 3) - render_settings_graphics(main_view); - else if(settings_page == 4) - render_settings_sound(main_view); - - if(need_restart) + + MainView.Margin(10.0f, &MainView); + + if(s_SettingsPage == 0) + RenderSettingsGeneral(MainView); + else if(s_SettingsPage == 1) + RenderSettingsPlayer(MainView); + else if(s_SettingsPage == 2) + RenderSettingsControls(MainView); + else if(s_SettingsPage == 3) + RenderSettingsGraphics(MainView); + else if(s_SettingsPage == 4) + RenderSettingsSound(MainView); + + if(m_NeedRestart) { - CUIRect restart_warning; - main_view.HSplitBottom(40, &main_view, &restart_warning); - UI()->DoLabel(&restart_warning, localize("You must restart the game for all settings to take effect."), 15.0f, -1, 220); + CUIRect RestartWarning; + MainView.HSplitBottom(40, &MainView, &RestartWarning); + UI()->DoLabel(&RestartWarning, Localize("You must restart the game for all settings to take effect."), 15.0f, -1, 220); } } diff --git a/src/game/client/components/motd.cpp b/src/game/client/components/motd.cpp index ba85f7f8..5905d52e 100644 --- a/src/game/client/components/motd.cpp +++ b/src/game/client/components/motd.cpp @@ -1,87 +1,91 @@ -#include <engine/e_client_interface.h> -#include <engine/client/graphics.h> -#include <engine/e_config.h> -#include <game/generated/g_protocol.hpp> -#include <game/generated/gc_data.hpp> +#include <engine/shared/config.h> +#include <engine/graphics.h> +#include <engine/textrender.h> +#include <engine/keys.h> -#include <game/client/gameclient.hpp> +#include <game/generated/protocol.h> +#include <game/generated/client_data.h> +#include <game/client/gameclient.h> -#include "motd.hpp" +#include "motd.h" -void MOTD::clear() +void CMotd::Clear() { - server_motd_time = 0; + m_ServerMotdTime = 0; } -bool MOTD::is_active() +bool CMotd::IsActive() { - return time_get() < server_motd_time; + return time_get() < m_ServerMotdTime; } -void MOTD::on_statechange(int new_state, int old_state) +void CMotd::OnStateChange(int NewState, int OldState) { - if(old_state == CLIENTSTATE_ONLINE || old_state == CLIENTSTATE_OFFLINE) - clear(); + if(OldState == IClient::STATE_ONLINE || OldState == IClient::STATE_OFFLINE) + Clear(); } -void MOTD::on_render() +void CMotd::OnRender() { - if(!is_active()) + if(!IsActive()) return; - float width = 400*3.0f*Graphics()->ScreenAspect(); - float height = 400*3.0f; + float Width = 400*3.0f*Graphics()->ScreenAspect(); + float Height = 400*3.0f; - Graphics()->MapScreen(0, 0, width, height); + Graphics()->MapScreen(0, 0, Width, Height); float h = 800.0f; float w = 650.0f; - float x = width/2 - w/2; + float x = Width/2 - w/2; float y = 150.0f; Graphics()->BlendNormal(); Graphics()->TextureSet(-1); Graphics()->QuadsBegin(); Graphics()->SetColor(0,0,0,0.5f); - RenderTools()->draw_round_rect(x, y, w, h, 40.0f); + RenderTools()->DrawRoundRect(x, y, w, h, 40.0f); Graphics()->QuadsEnd(); - gfx_text(0, x+40.0f, y+40.0f, 32.0f, server_motd, (int)(w-80.0f)); + TextRender()->Text(0, x+40.0f, y+40.0f, 32.0f, m_aServerMotd, (int)(w-80.0f)); } -void MOTD::on_message(int msgtype, void *rawmsg) +void CMotd::OnMessage(int MsgType, void *pRawMsg) { - if(msgtype == NETMSGTYPE_SV_MOTD) + if(Client()->State() == IClient::STATE_DEMOPLAYBACK) + return; + + if(MsgType == NETMSGTYPE_SV_MOTD) { - NETMSG_SV_MOTD *msg = (NETMSG_SV_MOTD *)rawmsg; + CNetMsg_Sv_Motd *pMsg = (CNetMsg_Sv_Motd *)pRawMsg; // process escaping - str_copy(server_motd, msg->message, sizeof(server_motd)); - for(int i = 0; server_motd[i]; i++) + str_copy(m_aServerMotd, pMsg->m_pMessage, sizeof(m_aServerMotd)); + for(int i = 0; m_aServerMotd[i]; i++) { - if(server_motd[i] == '\\') + if(m_aServerMotd[i] == '\\') { - if(server_motd[i+1] == 'n') + if(m_aServerMotd[i+1] == 'n') { - server_motd[i] = ' '; - server_motd[i+1] = '\n'; + m_aServerMotd[i] = ' '; + m_aServerMotd[i+1] = '\n'; i++; } } } - if(server_motd[0] && config.cl_motd_time) - server_motd_time = time_get()+time_freq()*config.cl_motd_time; + if(m_aServerMotd[0] && g_Config.m_ClMotdTime) + m_ServerMotdTime = time_get()+time_freq()*g_Config.m_ClMotdTime; else - server_motd_time = 0; + m_ServerMotdTime = 0; } } -bool MOTD::on_input(INPUT_EVENT e) +bool CMotd::OnInput(IInput::CEvent Event) { - if(is_active() && e.flags&INPFLAG_PRESS && e.key == KEY_ESCAPE) + if(IsActive() && Event.m_Flags&IInput::FLAG_PRESS && Event.m_Key == KEY_ESCAPE) { - clear(); + Clear(); return true; } return false; diff --git a/src/game/client/components/motd.h b/src/game/client/components/motd.h new file mode 100644 index 00000000..41e15b8c --- /dev/null +++ b/src/game/client/components/motd.h @@ -0,0 +1,21 @@ +#ifndef GAME_CLIENT_COMPONENTS_MOTD_H +#define GAME_CLIENT_COMPONENTS_MOTD_H +#include <game/client/component.h> + +class CMotd : public CComponent +{ + // motd + int64 m_ServerMotdTime; +public: + char m_aServerMotd[900]; + + void Clear(); + bool IsActive(); + + virtual void OnRender(); + virtual void OnStateChange(int NewState, int OldState); + virtual void OnMessage(int MsgType, void *pRawMsg); + virtual bool OnInput(IInput::CEvent Event); +}; + +#endif diff --git a/src/game/client/components/motd.hpp b/src/game/client/components/motd.hpp deleted file mode 100644 index 3b175e0a..00000000 --- a/src/game/client/components/motd.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#include <game/client/component.hpp> - -class MOTD : public COMPONENT -{ - // motd - int64 server_motd_time; -public: - char server_motd[900]; - - void clear(); - bool is_active(); - - virtual void on_render(); - virtual void on_statechange(int new_state, int old_state); - virtual void on_message(int msgtype, void *rawmsg); - virtual bool on_input(INPUT_EVENT e); -}; - diff --git a/src/game/client/components/nameplates.cpp b/src/game/client/components/nameplates.cpp index 4a47ea37..da114bbb 100644 --- a/src/game/client/components/nameplates.cpp +++ b/src/game/client/components/nameplates.cpp @@ -1,65 +1,66 @@ -#include <engine/e_client_interface.h> -#include <game/generated/g_protocol.hpp> -#include <game/generated/gc_data.hpp> +#include <engine/textrender.h> +#include <engine/shared/config.h> +#include <game/generated/protocol.h> +#include <game/generated/client_data.h> -#include <game/client/gameclient.hpp> -#include <game/client/animstate.hpp> -#include "nameplates.hpp" -#include "controls.hpp" +#include <game/client/gameclient.h> +#include <game/client/animstate.h> +#include "nameplates.h" +#include "controls.h" -void NAMEPLATES::render_nameplate( - const NETOBJ_CHARACTER *prev_char, - const NETOBJ_CHARACTER *player_char, - const NETOBJ_PLAYER_INFO *player_info +void CNamePlates::RenderNameplate( + const CNetObj_Character *pPrevChar, + const CNetObj_Character *pPlayerChar, + const CNetObj_PlayerInfo *pPlayerInfo ) { - float intratick = client_intratick(); + float IntraTick = Client()->IntraGameTick(); - vec2 position = mix(vec2(prev_char->x, prev_char->y), vec2(player_char->x, player_char->y), intratick); + vec2 Position = mix(vec2(pPrevChar->m_X, pPrevChar->m_Y), vec2(pPlayerChar->m_X, pPlayerChar->m_Y), IntraTick); // render name plate - if(!player_info->local) + if(!pPlayerInfo->m_Local) { - //gfx_text_color + //TextRender()->TextColor float a = 1; - if(config.cl_nameplates_always == 0) - a = clamp(1-powf(distance(gameclient.controls->target_pos, position)/200.0f,16.0f), 0.0f, 1.0f); + if(g_Config.m_ClNameplatesAlways == 0) + a = clamp(1-powf(distance(m_pClient->m_pControls->m_TargetPos, Position)/200.0f,16.0f), 0.0f, 1.0f); - const char *name = gameclient.clients[player_info->cid].name; - float tw = gfx_text_width(0, 28.0f, name, -1); - gfx_text_color(1,1,1,a); - gfx_text(0, position.x-tw/2.0f, position.y-60, 28.0f, name, -1); + const char *pName = m_pClient->m_aClients[pPlayerInfo->m_ClientId].m_aName; + float tw = TextRender()->TextWidth(0, 28.0f, pName, -1); + TextRender()->TextColor(1,1,1,a); + TextRender()->Text(0, Position.x-tw/2.0f, Position.y-60, 28.0f, pName, -1); - if(config.debug) // render client id when in debug aswell + if(g_Config.m_Debug) // render client id when in debug aswell { - char buf[128]; - str_format(buf, sizeof(buf),"%d", player_info->cid); - gfx_text(0, position.x, position.y-90, 28.0f, buf, -1); + char aBuf[128]; + str_format(aBuf, sizeof(aBuf),"%d", pPlayerInfo->m_ClientId); + TextRender()->Text(0, Position.x, Position.y-90, 28.0f, aBuf, -1); } - gfx_text_color(1,1,1,1); + TextRender()->TextColor(1,1,1,1); } } -void NAMEPLATES::on_render() +void CNamePlates::OnRender() { - if (!config.cl_nameplates) + if (!g_Config.m_ClNameplates) return; for(int i = 0; i < MAX_CLIENTS; i++) { // only render active characters - if(!gameclient.snap.characters[i].active) + if(!m_pClient->m_Snap.m_aCharacters[i].m_Active) continue; - const void *info = snap_find_item(SNAP_CURRENT, NETOBJTYPE_PLAYER_INFO, i); + const void *pInfo = Client()->SnapFindItem(IClient::SNAP_CURRENT, NETOBJTYPE_PLAYERINFO, i); - if(info) + if(pInfo) { - render_nameplate( - &gameclient.snap.characters[i].prev, - &gameclient.snap.characters[i].cur, - (const NETOBJ_PLAYER_INFO *)info); + RenderNameplate( + &m_pClient->m_Snap.m_aCharacters[i].m_Prev, + &m_pClient->m_Snap.m_aCharacters[i].m_Cur, + (const CNetObj_PlayerInfo *)pInfo); } } } diff --git a/src/game/client/components/nameplates.h b/src/game/client/components/nameplates.h new file mode 100644 index 00000000..279b6582 --- /dev/null +++ b/src/game/client/components/nameplates.h @@ -0,0 +1,17 @@ +#ifndef GAME_CLIENT_COMPONENTS_NAMEPLATES_H +#define GAME_CLIENT_COMPONENTS_NAMEPLATES_H +#include <game/client/component.h> + +class CNamePlates : public CComponent +{ + void RenderNameplate( + const class CNetObj_Character *pPrevChar, + const class CNetObj_Character *pPlayerChar, + const class CNetObj_PlayerInfo *pPlayerInfo + ); + +public: + virtual void OnRender(); +}; + +#endif diff --git a/src/game/client/components/nameplates.hpp b/src/game/client/components/nameplates.hpp deleted file mode 100644 index 2695f5ac..00000000 --- a/src/game/client/components/nameplates.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#include <game/client/component.hpp> - -class NAMEPLATES : public COMPONENT -{ - void render_nameplate( - const class NETOBJ_CHARACTER *prev_char, - const class NETOBJ_CHARACTER *player_char, - const class NETOBJ_PLAYER_INFO *player_info - ); - -public: - virtual void on_render(); -}; - diff --git a/src/game/client/components/particles.cpp b/src/game/client/components/particles.cpp index 61fcf738..99c2c721 100644 --- a/src/game/client/components/particles.cpp +++ b/src/game/client/components/particles.cpp @@ -1,155 +1,156 @@ -#include <base/math.hpp> -#include <engine/client/graphics.h> +#include <base/math.h> +#include <engine/graphics.h> -#include <game/generated/gc_data.hpp> -#include <game/client/render.hpp> -#include <game/gamecore.hpp> -#include "particles.hpp" +#include <game/generated/client_data.h> +#include <game/client/render.h> +#include <game/gamecore.h> +#include "particles.h" -PARTICLES::PARTICLES() +CParticles::CParticles() { - on_reset(); - render_trail.parts = this; - render_explosions.parts = this; - render_general.parts = this; + OnReset(); + m_RenderTrail.m_pParts = this; + m_RenderExplosions.m_pParts = this; + m_RenderGeneral.m_pParts = this; } -void PARTICLES::on_reset() +void CParticles::OnReset() { // reset particles for(int i = 0; i < MAX_PARTICLES; i++) { - particles[i].prev_part = i-1; - particles[i].next_part = i+1; + m_aParticles[i].m_PrevPart = i-1; + m_aParticles[i].m_NextPart = i+1; } - particles[0].prev_part = 0; - particles[MAX_PARTICLES-1].next_part = -1; - first_free = 0; + m_aParticles[0].m_PrevPart = 0; + m_aParticles[MAX_PARTICLES-1].m_NextPart = -1; + m_FirstFree = 0; for(int i = 0; i < NUM_GROUPS; i++) - first_part[i] = -1; + m_aFirstPart[i] = -1; } -void PARTICLES::add(int group, PARTICLE *part) +void CParticles::Add(int Group, CParticle *pPart) { - if (first_free == -1) + if (m_FirstFree == -1) return; // remove from the free list - int id = first_free; - first_free = particles[id].next_part; - particles[first_free].prev_part = -1; + int Id = m_FirstFree; + m_FirstFree = m_aParticles[Id].m_NextPart; + m_aParticles[m_FirstFree].m_PrevPart = -1; // copy data - particles[id] = *part; + m_aParticles[Id] = *pPart; // insert to the group list - particles[id].prev_part = -1; - particles[id].next_part = first_part[group]; - if(first_part[group] != -1) - particles[first_part[group]].prev_part = id; - first_part[group] = id; + m_aParticles[Id].m_PrevPart = -1; + m_aParticles[Id].m_NextPart = m_aFirstPart[Group]; + if(m_aFirstPart[Group] != -1) + m_aParticles[m_aFirstPart[Group]].m_PrevPart = Id; + m_aFirstPart[Group] = Id; // set some parameters - particles[id].life = 0; + m_aParticles[Id].m_Life = 0; } -void PARTICLES::update(float time_passed) +void CParticles::Update(float TimePassed) { - static float friction_fraction = 0; - friction_fraction += time_passed; + static float FrictionFraction = 0; + FrictionFraction += TimePassed; - if(friction_fraction > 2.0f) // safty messure - friction_fraction = 0; + if(FrictionFraction > 2.0f) // safty messure + FrictionFraction = 0; - int friction_count = 0; - while(friction_fraction > 0.05f) + int FrictionCount = 0; + while(FrictionFraction > 0.05f) { - friction_count++; - friction_fraction -= 0.05f; + FrictionCount++; + FrictionFraction -= 0.05f; } for(int g = 0; g < NUM_GROUPS; g++) { - int i = first_part[g]; + int i = m_aFirstPart[g]; while(i != -1) { - int next = particles[i].next_part; - //particles[i].vel += flow_get(particles[i].pos)*time_passed * particles[i].flow_affected; - particles[i].vel.y += particles[i].gravity*time_passed; + int Next = m_aParticles[i].m_NextPart; + //m_aParticles[i].vel += flow_get(m_aParticles[i].pos)*time_passed * m_aParticles[i].flow_affected; + m_aParticles[i].m_Vel.y += m_aParticles[i].m_Gravity*TimePassed; - for(int f = 0; f < friction_count; f++) // apply friction - particles[i].vel *= particles[i].friction; + for(int f = 0; f < FrictionCount; f++) // apply friction + m_aParticles[i].m_Vel *= m_aParticles[i].m_Friction; // move the point - vec2 vel = particles[i].vel*time_passed; - move_point(&particles[i].pos, &vel, 0.1f+0.9f*frandom(), NULL); - particles[i].vel = vel* (1.0f/time_passed); + vec2 Vel = m_aParticles[i].m_Vel*TimePassed; + Collision()->MovePoint(&m_aParticles[i].m_Pos, &Vel, 0.1f+0.9f*frandom(), NULL); + m_aParticles[i].m_Vel = Vel* (1.0f/TimePassed); - particles[i].life += time_passed; - particles[i].rot += time_passed * particles[i].rotspeed; + m_aParticles[i].m_Life += TimePassed; + m_aParticles[i].m_Rot += TimePassed * m_aParticles[i].m_Rotspeed; // check particle death - if(particles[i].life > particles[i].life_span) + if(m_aParticles[i].m_Life > m_aParticles[i].m_LifeSpan) { // remove it from the group list - if(particles[i].prev_part != -1) - particles[particles[i].prev_part].next_part = particles[i].next_part; + if(m_aParticles[i].m_PrevPart != -1) + m_aParticles[m_aParticles[i].m_PrevPart].m_NextPart = m_aParticles[i].m_NextPart; else - first_part[g] = particles[i].next_part; + m_aFirstPart[g] = m_aParticles[i].m_NextPart; - if(particles[i].next_part != -1) - particles[particles[i].next_part].prev_part = particles[i].prev_part; + if(m_aParticles[i].m_NextPart != -1) + m_aParticles[m_aParticles[i].m_NextPart].m_PrevPart = m_aParticles[i].m_PrevPart; // insert to the free list - if(first_free != -1) - particles[first_free].prev_part = i; - particles[i].prev_part = -1; - particles[i].next_part = first_free; - first_free = i; + if(m_FirstFree != -1) + m_aParticles[m_FirstFree].m_PrevPart = i; + m_aParticles[i].m_PrevPart = -1; + m_aParticles[i].m_NextPart = m_FirstFree; + m_FirstFree = i; } - i = next; + i = Next; } } } -void PARTICLES::on_render() +void CParticles::OnRender() { - static int64 lasttime = 0; + static int64 LastTime = 0; int64 t = time_get(); - update((float)((t-lasttime)/(double)time_freq())); - lasttime = t; + Update((float)((t-LastTime)/(double)time_freq())); + LastTime = t; } -void PARTICLES::render_group(int group) +void CParticles::RenderGroup(int Group) { Graphics()->BlendNormal(); //gfx_blend_additive(); - Graphics()->TextureSet(data->images[IMAGE_PARTICLES].id); + Graphics()->TextureSet(g_pData->m_aImages[IMAGE_PARTICLES].m_Id); Graphics()->QuadsBegin(); - int i = first_part[group]; + int i = m_aFirstPart[Group]; while(i != -1) { - RenderTools()->select_sprite(particles[i].spr); - float a = particles[i].life / particles[i].life_span; - vec2 p = particles[i].pos; - float size = mix(particles[i].start_size, particles[i].end_size, a); + RenderTools()->SelectSprite(m_aParticles[i].m_Spr); + float a = m_aParticles[i].m_Life / m_aParticles[i].m_LifeSpan; + vec2 p = m_aParticles[i].m_Pos; + float Size = mix(m_aParticles[i].m_StartSize, m_aParticles[i].m_EndSize, a); - Graphics()->QuadsSetRotation(particles[i].rot); + Graphics()->QuadsSetRotation(m_aParticles[i].m_Rot); Graphics()->SetColor( - particles[i].color.r, - particles[i].color.g, - particles[i].color.b, - particles[i].color.a); // pow(a, 0.75f) * + m_aParticles[i].m_Color.r, + m_aParticles[i].m_Color.g, + m_aParticles[i].m_Color.b, + m_aParticles[i].m_Color.a); // pow(a, 0.75f) * - Graphics()->QuadsDraw(p.x, p.y, size, size); + IGraphics::CQuadItem QuadItem(p.x, p.y, Size, Size); + Graphics()->QuadsDraw(&QuadItem, 1); - i = particles[i].next_part; + i = m_aParticles[i].m_NextPart; } Graphics()->QuadsEnd(); Graphics()->BlendNormal(); diff --git a/src/game/client/components/particles.h b/src/game/client/components/particles.h new file mode 100644 index 00000000..af9a9203 --- /dev/null +++ b/src/game/client/components/particles.h @@ -0,0 +1,94 @@ +#ifndef GAME_CLIENT_COMPONENTS_PARTICLES_H +#define GAME_CLIENT_COMPONENTS_PARTICLES_H +#include <base/vmath.h> +#include <game/client/component.h> + +// particles +struct CParticle +{ + void SetDefault() + { + m_Vel = vec2(0,0); + m_LifeSpan = 0; + m_StartSize = 32; + m_EndSize = 32; + m_Rot = 0; + m_Rotspeed = 0; + m_Gravity = 0; + m_Friction = 0; + m_FlowAffected = 1.0f; + m_Color = vec4(1,1,1,1); + } + + vec2 m_Pos; + vec2 m_Vel; + + int m_Spr; + + float m_FlowAffected; + + float m_LifeSpan; + + float m_StartSize; + float m_EndSize; + + float m_Rot; + float m_Rotspeed; + + float m_Gravity; + float m_Friction; + + vec4 m_Color; + + // set by the particle system + float m_Life; + int m_PrevPart; + int m_NextPart; +}; + +class CParticles : public CComponent +{ + friend class CGameClient; +public: + enum + { + GROUP_PROJECTILE_TRAIL=0, + GROUP_EXPLOSIONS, + GROUP_GENERAL, + NUM_GROUPS + }; + + CParticles(); + + void Add(int Group, CParticle *pPart); + + virtual void OnReset(); + virtual void OnRender(); + +private: + + enum + { + MAX_PARTICLES=1024*8, + }; + + CParticle m_aParticles[MAX_PARTICLES]; + int m_FirstFree; + int m_aFirstPart[NUM_GROUPS]; + + void RenderGroup(int Group); + void Update(float TimePassed); + + template<int TGROUP> + class CRenderGroup : public CComponent + { + public: + CParticles *m_pParts; + virtual void OnRender() { m_pParts->RenderGroup(TGROUP); } + }; + + CRenderGroup<GROUP_PROJECTILE_TRAIL> m_RenderTrail; + CRenderGroup<GROUP_EXPLOSIONS> m_RenderExplosions; + CRenderGroup<GROUP_GENERAL> m_RenderGeneral; +}; +#endif diff --git a/src/game/client/components/particles.hpp b/src/game/client/components/particles.hpp deleted file mode 100644 index 6c466d94..00000000 --- a/src/game/client/components/particles.hpp +++ /dev/null @@ -1,91 +0,0 @@ -#include <base/vmath.hpp> -#include <game/client/component.hpp> - -// particles -struct PARTICLE -{ - void set_default() - { - vel = vec2(0,0); - life_span = 0; - start_size = 32; - end_size = 32; - rot = 0; - rotspeed = 0; - gravity = 0; - friction = 0; - flow_affected = 1.0f; - color = vec4(1,1,1,1); - } - - vec2 pos; - vec2 vel; - - int spr; - - float flow_affected; - - float life_span; - - float start_size; - float end_size; - - float rot; - float rotspeed; - - float gravity; - float friction; - - vec4 color; - - // set by the particle system - float life; - int prev_part; - int next_part; -}; - -class PARTICLES : public COMPONENT -{ - friend class GAMECLIENT; -public: - enum - { - GROUP_PROJECTILE_TRAIL=0, - GROUP_EXPLOSIONS, - GROUP_GENERAL, - NUM_GROUPS - }; - - PARTICLES(); - - void add(int group, PARTICLE *part); - - virtual void on_reset(); - virtual void on_render(); - -private: - - enum - { - MAX_PARTICLES=1024*8, - }; - - PARTICLE particles[MAX_PARTICLES]; - int first_free; - int first_part[NUM_GROUPS]; - - void render_group(int group); - void update(float time_passed); - - template<int TGROUP> - class RENDER_GROUP : public COMPONENT - { - public: - PARTICLES *parts; - virtual void on_render() { parts->render_group(TGROUP); } - }; - - RENDER_GROUP<GROUP_PROJECTILE_TRAIL> render_trail; - RENDER_GROUP<GROUP_EXPLOSIONS> render_explosions; - RENDER_GROUP<GROUP_GENERAL> render_general; -}; diff --git a/src/game/client/components/players.cpp b/src/game/client/components/players.cpp index e1fee3e8..8ad7b0cb 100644 --- a/src/game/client/components/players.cpp +++ b/src/game/client/components/players.cpp @@ -1,147 +1,269 @@ -#include <engine/e_client_interface.h> -#include <engine/client/graphics.h> -#include <game/generated/g_protocol.hpp> -#include <game/generated/gc_data.hpp> - -#include <game/gamecore.hpp> // get_angle -#include <game/client/animstate.hpp> -#include <game/client/gameclient.hpp> -#include <game/client/ui.hpp> -#include <game/client/render.hpp> - -#include <game/client/components/flow.hpp> -#include <game/client/components/skins.hpp> -#include <game/client/components/effects.hpp> -#include <game/client/components/sounds.hpp> -#include <game/client/components/controls.hpp> - -#include "players.hpp" - -void PLAYERS::render_hand(TEE_RENDER_INFO *info, vec2 center_pos, vec2 dir, float angle_offset, vec2 post_rot_offset) +#include <engine/graphics.h> +#include <engine/shared/config.h> +#include <game/generated/protocol.h> +#include <game/generated/client_data.h> + +#include <game/gamecore.h> // get_angle +#include <game/client/animstate.h> +#include <game/client/gameclient.h> +#include <game/client/ui.h> +#include <game/client/render.h> + +#include <game/client/components/flow.h> +#include <game/client/components/skins.h> +#include <game/client/components/effects.h> +#include <game/client/components/sounds.h> +#include <game/client/components/controls.h> + +#include "players.h" + +void CPlayers::RenderHand(CTeeRenderInfo *pInfo, vec2 CenterPos, vec2 Dir, float AngleOffset, vec2 PostRotOffset) { // for drawing hand //const skin *s = skin_get(skin_id); - float basesize = 10.0f; + float BaseSize = 10.0f; //dir = normalize(hook_pos-pos); - vec2 hand_pos = center_pos + dir; - float angle = get_angle(dir); - if (dir.x < 0) - angle -= angle_offset; + vec2 HandPos = CenterPos + Dir; + float Angle = GetAngle(Dir); + if (Dir.x < 0) + Angle -= AngleOffset; else - angle += angle_offset; + Angle += AngleOffset; - vec2 dirx = dir; - vec2 diry(-dir.y,dir.x); + vec2 DirX = Dir; + vec2 DirY(-Dir.y,Dir.x); - if (dir.x < 0) - diry = -diry; + if (Dir.x < 0) + DirY = -DirY; - hand_pos += dirx * post_rot_offset.x; - hand_pos += diry * post_rot_offset.y; + HandPos += DirX * PostRotOffset.x; + HandPos += DirY * PostRotOffset.y; - //Graphics()->TextureSet(data->images[IMAGE_CHAR_DEFAULT].id); - Graphics()->TextureSet(info->texture); + //Graphics()->TextureSet(data->m_aImages[IMAGE_CHAR_DEFAULT].id); + Graphics()->TextureSet(pInfo->m_Texture); Graphics()->QuadsBegin(); - Graphics()->SetColor(info->color_body.r, info->color_body.g, info->color_body.b, info->color_body.a); + Graphics()->SetColor(pInfo->m_ColorBody.r, pInfo->m_ColorBody.g, pInfo->m_ColorBody.b, pInfo->m_ColorBody.a); // two passes for (int i = 0; i < 2; i++) { - bool outline = i == 0; + bool OutLine = i == 0; - RenderTools()->select_sprite(outline?SPRITE_TEE_HAND_OUTLINE:SPRITE_TEE_HAND, 0, 0, 0); - Graphics()->QuadsSetRotation(angle); - Graphics()->QuadsDraw(hand_pos.x, hand_pos.y, 2*basesize, 2*basesize); + RenderTools()->SelectSprite(OutLine?SPRITE_TEE_HAND_OUTLINE:SPRITE_TEE_HAND, 0, 0, 0); + Graphics()->QuadsSetRotation(Angle); + IGraphics::CQuadItem QuadItem(HandPos.x, HandPos.y, 2*BaseSize, 2*BaseSize); + Graphics()->QuadsDraw(&QuadItem, 1); } Graphics()->QuadsSetRotation(0); Graphics()->QuadsEnd(); } -inline float normalize_angular(float f) +inline float NormalizeAngular(float f) { return fmod(f+pi*2, pi*2); } -inline float angular_mix_direction(float src, float dst) { return sinf(dst-src) >0?1:-1; } -inline float angular_distance(float src, float dst) { return asinf(sinf(dst-src)); } +inline float AngularMixDirection (float Src, float Dst) { return sinf(Dst-Src) >0?1:-1; } +inline float AngularDistance(float Src, float Dst) { return asinf(sinf(Dst-Src)); } -inline float angular_approach(float src, float dst, float amount) +inline float AngularApproach(float Src, float Dst, float Amount) { - float d = angular_mix_direction(src, dst); - float n = src + amount*d; - if(angular_mix_direction(n, dst) != d) - return dst; + float d = AngularMixDirection (Src, Dst); + float n = Src + Amount*d; + if(AngularMixDirection (n, Dst) != d) + return Dst; return n; } -void PLAYERS::render_player( - const NETOBJ_CHARACTER *prev_char, - const NETOBJ_CHARACTER *player_char, - const NETOBJ_PLAYER_INFO *prev_info, - const NETOBJ_PLAYER_INFO *player_info +void CPlayers::RenderHook( + const CNetObj_Character *pPrevChar, + const CNetObj_Character *pPlayerChar, + const CNetObj_PlayerInfo *pPrevInfo, + const CNetObj_PlayerInfo *pPlayerInfo ) { - NETOBJ_CHARACTER prev; - NETOBJ_CHARACTER player; - prev = *prev_char; - player = *player_char; + CNetObj_Character Prev; + CNetObj_Character Player; + Prev = *pPrevChar; + Player = *pPlayerChar; - NETOBJ_PLAYER_INFO info = *player_info; - TEE_RENDER_INFO render_info = gameclient.clients[info.cid].render_info; + CNetObj_PlayerInfo pInfo = *pPlayerInfo; + CTeeRenderInfo RenderInfo = m_pClient->m_aClients[pInfo.m_ClientId].m_RenderInfo; // check for teamplay modes - bool is_teamplay = false; - bool new_tick = gameclient.new_tick; - if(gameclient.snap.gameobj) - is_teamplay = (gameclient.snap.gameobj->flags&GAMEFLAG_TEAMS) != 0; + bool IsTeamplay = false; + if(m_pClient->m_Snap.m_pGameobj) + IsTeamplay = (m_pClient->m_Snap.m_pGameobj->m_Flags&GAMEFLAG_TEAMS) != 0; // check for ninja - if (player.weapon == WEAPON_NINJA) + if (Player.m_Weapon == WEAPON_NINJA) { // change the skin for the player to the ninja - int skin = gameclient.skins->find("x_ninja"); - if(skin != -1) + int Skin = m_pClient->m_pSkins->Find("x_ninja"); + if(Skin != -1) { - if(is_teamplay) - render_info.texture = gameclient.skins->get(skin)->color_texture; + if(IsTeamplay) + RenderInfo.m_Texture = m_pClient->m_pSkins->Get(Skin)->m_ColorTexture; else { - render_info.texture = gameclient.skins->get(skin)->org_texture; - render_info.color_body = vec4(1,1,1,1); - render_info.color_feet = vec4(1,1,1,1); + RenderInfo.m_Texture = m_pClient->m_pSkins->Get(Skin)->m_OrgTexture; + RenderInfo.m_ColorBody = vec4(1,1,1,1); + RenderInfo.m_ColorFeet = vec4(1,1,1,1); + } + } + } + + float IntraTick = Client()->IntraGameTick(); + + if(Player.m_Health < 0) // dont render dead players + return; + + // set size + RenderInfo.m_Size = 64.0f; + + + // use preditect players if needed + if(pInfo.m_Local && g_Config.m_ClPredict && Client()->State() != IClient::STATE_DEMOPLAYBACK) + { + if(!m_pClient->m_Snap.m_pLocalCharacter || (m_pClient->m_Snap.m_pLocalCharacter->m_Health < 0) || (m_pClient->m_Snap.m_pGameobj && m_pClient->m_Snap.m_pGameobj->m_GameOver)) + { + } + else + { + // apply predicted results + m_pClient->m_PredictedChar.Write(&Player); + m_pClient->m_PredictedPrevChar.Write(&Prev); + IntraTick = Client()->PredIntraGameTick(); + } + } + + vec2 Position = mix(vec2(Prev.m_X, Prev.m_Y), vec2(Player.m_X, Player.m_Y), IntraTick); + + if(Prev.m_Health < 0) // Don't flicker from previous position + Position = vec2(Player.m_X, Player.m_Y); + + // draw hook + if (Prev.m_HookState>0 && Player.m_HookState>0) + { + Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id); + Graphics()->QuadsBegin(); + //Graphics()->QuadsBegin(); + + vec2 Pos = Position; + vec2 HookPos; + + if(pPlayerChar->m_HookedPlayer != -1) + { + if(m_pClient->m_Snap.m_pLocalInfo && pPlayerChar->m_HookedPlayer == m_pClient->m_Snap.m_pLocalInfo->m_ClientId) + { + if(Client()->State() == IClient::STATE_DEMOPLAYBACK) // only use prediction if needed + HookPos = vec2(m_pClient->m_LocalCharacterPos.x, m_pClient->m_LocalCharacterPos.y); + else + HookPos = mix(vec2(m_pClient->m_PredictedPrevChar.m_Pos.x, m_pClient->m_PredictedPrevChar.m_Pos.y), + vec2(m_pClient->m_PredictedChar.m_Pos.x, m_pClient->m_PredictedChar.m_Pos.y), Client()->PredIntraGameTick()); + } + else + HookPos = mix(vec2(pPrevChar->m_HookX, pPrevChar->m_HookY), vec2(pPlayerChar->m_HookX, pPlayerChar->m_HookY), Client()->IntraGameTick()); + } + else + HookPos = mix(vec2(Prev.m_HookX, Prev.m_HookY), vec2(Player.m_HookX, Player.m_HookY), IntraTick); + + float d = distance(Pos, HookPos); + vec2 Dir = normalize(Pos-HookPos); + + Graphics()->QuadsSetRotation(GetAngle(Dir)+pi); + + // render head + RenderTools()->SelectSprite(SPRITE_HOOK_HEAD); + IGraphics::CQuadItem QuadItem(HookPos.x, HookPos.y, 24,16); + Graphics()->QuadsDraw(&QuadItem, 1); + + // render chain + RenderTools()->SelectSprite(SPRITE_HOOK_CHAIN); + IGraphics::CQuadItem Array[1024]; + int i = 0; + for(float f = 24; f < d && i < 1024; f += 24, i++) + { + vec2 p = HookPos + Dir*f; + Array[i] = IGraphics::CQuadItem(p.x, p.y,24,16); + } + + Graphics()->QuadsDraw(Array, i); + Graphics()->QuadsSetRotation(0); + Graphics()->QuadsEnd(); + + RenderHand(&RenderInfo, Position, normalize(HookPos-Pos), -pi/2, vec2(20, 0)); + } +} + +void CPlayers::RenderPlayer( + const CNetObj_Character *pPrevChar, + const CNetObj_Character *pPlayerChar, + const CNetObj_PlayerInfo *pPrevInfo, + const CNetObj_PlayerInfo *pPlayerInfo + ) +{ + CNetObj_Character Prev; + CNetObj_Character Player; + Prev = *pPrevChar; + Player = *pPlayerChar; + + CNetObj_PlayerInfo pInfo = *pPlayerInfo; + CTeeRenderInfo RenderInfo = m_pClient->m_aClients[pInfo.m_ClientId].m_RenderInfo; + + // check for teamplay modes + bool IsTeamplay = false; + bool NewTick = m_pClient->m_NewTick; + if(m_pClient->m_Snap.m_pGameobj) + IsTeamplay = (m_pClient->m_Snap.m_pGameobj->m_Flags&GAMEFLAG_TEAMS) != 0; + + // check for ninja + if (Player.m_Weapon == WEAPON_NINJA) + { + // change the skin for the player to the ninja + int Skin = m_pClient->m_pSkins->Find("x_ninja"); + if(Skin != -1) + { + if(IsTeamplay) + RenderInfo.m_Texture = m_pClient->m_pSkins->Get(Skin)->m_ColorTexture; + else + { + RenderInfo.m_Texture = m_pClient->m_pSkins->Get(Skin)->m_OrgTexture; + RenderInfo.m_ColorBody = vec4(1,1,1,1); + RenderInfo.m_ColorFeet = vec4(1,1,1,1); } } } // set size - render_info.size = 64.0f; + RenderInfo.m_Size = 64.0f; - float intratick = client_intratick(); + float IntraTick = Client()->IntraGameTick(); - if(player.health < 0) // dont render dead players + if(Player.m_Health < 0) // dont render dead players return; - float angle = mix((float)prev.angle, (float)player.angle, intratick)/256.0f; + float Angle = mix((float)Prev.m_Angle, (float)Player.m_Angle, IntraTick)/256.0f; //float angle = 0; - if(info.local && client_state() != CLIENTSTATE_DEMOPLAYBACK) + if(pInfo.m_Local && Client()->State() != IClient::STATE_DEMOPLAYBACK) { // just use the direct input if it's local player we are rendering - angle = get_angle(gameclient.controls->mouse_pos); + Angle = GetAngle(m_pClient->m_pControls->m_MousePos); } else { /* - float mixspeed = client_frametime()*2.5f; + float mixspeed = Client()->FrameTime()*2.5f; if(player.attacktick != prev.attacktick) // shooting boosts the mixing speed mixspeed *= 15.0f; // move the delta on a constant speed on a x^2 curve - float current = gameclient.clients[info.cid].angle; + float current = g_GameClient.m_aClients[info.cid].angle; float target = player.angle/256.0f; float delta = angular_distance(current, target); float sign = delta < 0 ? -1 : 1; @@ -153,342 +275,305 @@ void PLAYERS::render_player( else angle = angular_approach(current, target, fabs(delta-new_delta)); - gameclient.clients[info.cid].angle = angle;*/ + g_GameClient.m_aClients[info.cid].angle = angle;*/ } // use preditect players if needed - if(info.local && config.cl_predict && client_state() != CLIENTSTATE_DEMOPLAYBACK) + if(pInfo.m_Local && g_Config.m_ClPredict && Client()->State() != IClient::STATE_DEMOPLAYBACK) { - if(!gameclient.snap.local_character || (gameclient.snap.local_character->health < 0) || (gameclient.snap.gameobj && gameclient.snap.gameobj->game_over)) + if(!m_pClient->m_Snap.m_pLocalCharacter || (m_pClient->m_Snap.m_pLocalCharacter->m_Health < 0) || (m_pClient->m_Snap.m_pGameobj && m_pClient->m_Snap.m_pGameobj->m_GameOver)) { } else { // apply predicted results - gameclient.predicted_char.write(&player); - gameclient.predicted_prev_char.write(&prev); - intratick = client_predintratick(); - new_tick = gameclient.new_predicted_tick; + m_pClient->m_PredictedChar.Write(&Player); + m_pClient->m_PredictedPrevChar.Write(&Prev); + IntraTick = Client()->PredIntraGameTick(); + NewTick = m_pClient->m_NewPredictedTick; } } - vec2 direction = get_direction((int)(angle*256.0f)); - vec2 position = mix(vec2(prev.x, prev.y), vec2(player.x, player.y), intratick); - vec2 vel = mix(vec2(prev.vx/256.0f, prev.vy/256.0f), vec2(player.vx/256.0f, player.vy/256.0f), intratick); + vec2 Direction = GetDirection((int)(Angle*256.0f)); + vec2 Position = mix(vec2(Prev.m_X, Prev.m_Y), vec2(Player.m_X, Player.m_Y), IntraTick); + vec2 Vel = mix(vec2(Prev.m_VelX/256.0f, Prev.m_VelY/256.0f), vec2(Player.m_VelX/256.0f, Player.m_VelY/256.0f), IntraTick); - gameclient.flow->add(position, vel*100.0f, 10.0f); + m_pClient->m_pFlow->Add(Position, Vel*100.0f, 10.0f); - render_info.got_airjump = player.jumped&2?0:1; + RenderInfo.m_GotAirJump = Player.m_Jumped&2?0:1; // detect events - if(new_tick) + if(NewTick) { // detect air jump - if(!render_info.got_airjump && !(prev.jumped&2)) - gameclient.effects->air_jump(position); + if(!RenderInfo.m_GotAirJump && !(Prev.m_Jumped&2)) + m_pClient->m_pEffects->AirJump(Position); } - if(prev.health < 0) // Don't flicker from previous position - position = vec2(player.x, player.y); + if(Prev.m_Health < 0) // Don't flicker from previous position + Position = vec2(Player.m_X, Player.m_Y); - bool stationary = player.vx < 1 && player.vx > -1; - bool inair = col_check_point(player.x, player.y+16) == 0; - bool want_other_dir = (player.direction == -1 && vel.x > 0) || (player.direction == 1 && vel.x < 0); + bool Stationary = Player.m_VelX <= 1 && Player.m_VelX >= -1; + bool InAir = !Collision()->CheckPoint(Player.m_X, Player.m_Y+16); + bool WantOtherDir = (Player.m_Direction == -1 && Vel.x > 0) || (Player.m_Direction == 1 && Vel.x < 0); // evaluate animation - float walk_time = fmod(position.x, 100.0f)/100.0f; - ANIMSTATE state; - state.set(&data->animations[ANIM_BASE], 0); - - if(inair) - state.add(&data->animations[ANIM_INAIR], 0, 1.0f); // TODO: some sort of time here - else if(stationary) - state.add(&data->animations[ANIM_IDLE], 0, 1.0f); // TODO: some sort of time here - else if(!want_other_dir) - state.add(&data->animations[ANIM_WALK], walk_time, 1.0f); - - if (player.weapon == WEAPON_HAMMER) + float WalkTime = fmod(Position.x, 100.0f)/100.0f; + CAnimState State; + State.Set(&g_pData->m_aAnimations[ANIM_BASE], 0); + + if(InAir) + State.Add(&g_pData->m_aAnimations[ANIM_INAIR], 0, 1.0f); // TODO: some sort of time here + else if(Stationary) + State.Add(&g_pData->m_aAnimations[ANIM_IDLE], 0, 1.0f); // TODO: some sort of time here + else if(!WantOtherDir) + State.Add(&g_pData->m_aAnimations[ANIM_WALK], WalkTime, 1.0f); + + if (Player.m_Weapon == WEAPON_HAMMER) { - float ct = (client_prevtick()-player.attacktick)/(float)SERVER_TICK_SPEED + client_ticktime(); - state.add(&data->animations[ANIM_HAMMER_SWING], clamp(ct*5.0f,0.0f,1.0f), 1.0f); + float ct = (Client()->PrevGameTick()-Player.m_AttackTick)/(float)SERVER_TICK_SPEED + Client()->GameTickTime(); + State.Add(&g_pData->m_aAnimations[ANIM_HAMMER_SWING], clamp(ct*5.0f,0.0f,1.0f), 1.0f); } - if (player.weapon == WEAPON_NINJA) + if (Player.m_Weapon == WEAPON_NINJA) { - float ct = (client_prevtick()-player.attacktick)/(float)SERVER_TICK_SPEED + client_ticktime(); - state.add(&data->animations[ANIM_NINJA_SWING], clamp(ct*2.0f,0.0f,1.0f), 1.0f); + float ct = (Client()->PrevGameTick()-Player.m_AttackTick)/(float)SERVER_TICK_SPEED + Client()->GameTickTime(); + State.Add(&g_pData->m_aAnimations[ANIM_NINJA_SWING], clamp(ct*2.0f,0.0f,1.0f), 1.0f); } // do skidding - if(!inair && want_other_dir && length(vel*50) > 500.0f) + if(!InAir && WantOtherDir && length(Vel*50) > 500.0f) { - static int64 skid_sound_time = 0; - if(time_get()-skid_sound_time > time_freq()/10) + static int64 SkidSoundTime = 0; + if(time_get()-SkidSoundTime > time_freq()/10) { - gameclient.sounds->play(SOUNDS::CHN_WORLD, SOUND_PLAYER_SKID, 0.25f, position); - skid_sound_time = time_get(); + m_pClient->m_pSounds->Play(CSounds::CHN_WORLD, SOUND_PLAYER_SKID, 0.25f, Position); + SkidSoundTime = time_get(); } - gameclient.effects->skidtrail( - position+vec2(-player.direction*6,12), - vec2(-player.direction*100*length(vel),-50) + m_pClient->m_pEffects->SkidTrail( + Position+vec2(-Player.m_Direction*6,12), + vec2(-Player.m_Direction*100*length(Vel),-50) ); } - // draw hook - if (prev.hook_state>0 && player.hook_state>0) - { - Graphics()->TextureSet(data->images[IMAGE_GAME].id); - Graphics()->QuadsBegin(); - //Graphics()->QuadsBegin(); - - vec2 pos = position; - vec2 hook_pos; - - if(player_char->hooked_player != -1) - { - if(gameclient.snap.local_info && player_char->hooked_player == gameclient.snap.local_info->cid) - { - hook_pos = mix(vec2(gameclient.predicted_prev_char.pos.x, gameclient.predicted_prev_char.pos.y), - vec2(gameclient.predicted_char.pos.x, gameclient.predicted_char.pos.y), client_predintratick()); - } - else - hook_pos = mix(vec2(prev_char->hook_x, prev_char->hook_y), vec2(player_char->hook_x, player_char->hook_y), client_intratick()); - } - else - hook_pos = mix(vec2(prev.hook_x, prev.hook_y), vec2(player.hook_x, player.hook_y), intratick); - - float d = distance(pos, hook_pos); - vec2 dir = normalize(pos-hook_pos); - - Graphics()->QuadsSetRotation(get_angle(dir)+pi); - - // render head - RenderTools()->select_sprite(SPRITE_HOOK_HEAD); - Graphics()->QuadsDraw(hook_pos.x, hook_pos.y, 24,16); - - // render chain - RenderTools()->select_sprite(SPRITE_HOOK_CHAIN); - int i = 0; - for(float f = 24; f < d && i < 1024; f += 24, i++) - { - vec2 p = hook_pos + dir*f; - Graphics()->QuadsDraw(p.x, p.y,24,16); - } - - Graphics()->QuadsSetRotation(0); - Graphics()->QuadsEnd(); - - render_hand(&render_info, position, normalize(hook_pos-pos), -pi/2, vec2(20, 0)); - } - // draw gun { - Graphics()->TextureSet(data->images[IMAGE_GAME].id); + Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id); Graphics()->QuadsBegin(); - Graphics()->QuadsSetRotation(state.attach.angle*pi*2+angle); + Graphics()->QuadsSetRotation(State.GetAttach()->m_Angle*pi*2+Angle); // normal weapons - int iw = clamp(player.weapon, 0, NUM_WEAPONS-1); - RenderTools()->select_sprite(data->weapons.id[iw].sprite_body, direction.x < 0 ? SPRITE_FLAG_FLIP_Y : 0); + int iw = clamp(Player.m_Weapon, 0, NUM_WEAPONS-1); + RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[iw].m_pSpriteBody, Direction.x < 0 ? SPRITE_FLAG_FLIP_Y : 0); - vec2 dir = direction; - float recoil = 0.0f; + vec2 Dir = Direction; + float Recoil = 0.0f; vec2 p; - if (player.weapon == WEAPON_HAMMER) + if (Player.m_Weapon == WEAPON_HAMMER) { // Static position for hammer - p = position + vec2(state.attach.x, state.attach.y); - p.y += data->weapons.id[iw].offsety; + p = Position + vec2(State.GetAttach()->m_X, State.GetAttach()->m_Y); + p.y += g_pData->m_Weapons.m_aId[iw].m_Offsety; // if attack is under way, bash stuffs - if(direction.x < 0) + if(Direction.x < 0) { - Graphics()->QuadsSetRotation(-pi/2-state.attach.angle*pi*2); - p.x -= data->weapons.id[iw].offsetx; + Graphics()->QuadsSetRotation(-pi/2-State.GetAttach()->m_Angle*pi*2); + p.x -= g_pData->m_Weapons.m_aId[iw].m_Offsetx; } else { - Graphics()->QuadsSetRotation(-pi/2+state.attach.angle*pi*2); + Graphics()->QuadsSetRotation(-pi/2+State.GetAttach()->m_Angle*pi*2); } - RenderTools()->draw_sprite(p.x, p.y, data->weapons.id[iw].visual_size); + RenderTools()->DrawSprite(p.x, p.y, g_pData->m_Weapons.m_aId[iw].m_VisualSize); } - else if (player.weapon == WEAPON_NINJA) + else if (Player.m_Weapon == WEAPON_NINJA) { - p = position; - p.y += data->weapons.id[iw].offsety; + p = Position; + p.y += g_pData->m_Weapons.m_aId[iw].m_Offsety; - if(direction.x < 0) + if(Direction.x < 0) { - Graphics()->QuadsSetRotation(-pi/2-state.attach.angle*pi*2); - p.x -= data->weapons.id[iw].offsetx; - gameclient.effects->powerupshine(p+vec2(32,0), vec2(32,12)); + Graphics()->QuadsSetRotation(-pi/2-State.GetAttach()->m_Angle*pi*2); + p.x -= g_pData->m_Weapons.m_aId[iw].m_Offsetx; + m_pClient->m_pEffects->PowerupShine(p+vec2(32,0), vec2(32,12)); } else { - Graphics()->QuadsSetRotation(-pi/2+state.attach.angle*pi*2); - gameclient.effects->powerupshine(p-vec2(32,0), vec2(32,12)); + Graphics()->QuadsSetRotation(-pi/2+State.GetAttach()->m_Angle*pi*2); + m_pClient->m_pEffects->PowerupShine(p-vec2(32,0), vec2(32,12)); } - RenderTools()->draw_sprite(p.x, p.y, data->weapons.id[iw].visual_size); + RenderTools()->DrawSprite(p.x, p.y, g_pData->m_Weapons.m_aId[iw].m_VisualSize); // HADOKEN - if ((client_tick()-player.attacktick) <= (SERVER_TICK_SPEED / 6) && data->weapons.id[iw].num_sprite_muzzles) + if ((Client()->GameTick()-Player.m_AttackTick) <= (SERVER_TICK_SPEED / 6) && g_pData->m_Weapons.m_aId[iw].m_NumSpriteMuzzles) { - int itex = rand() % data->weapons.id[iw].num_sprite_muzzles; - float alpha = 1.0f; - if (alpha > 0.0f && data->weapons.id[iw].sprite_muzzles[itex]) + int IteX = rand() % g_pData->m_Weapons.m_aId[iw].m_NumSpriteMuzzles; + float Alpha = 1.0f; + if (Alpha > 0.0f && g_pData->m_Weapons.m_aId[iw].m_aSpriteMuzzles[IteX]) { - vec2 dir = vec2(player_char->x,player_char->y) - vec2(prev_char->x, prev_char->y); - dir = normalize(dir); - float hadokenangle = get_angle(dir); - Graphics()->QuadsSetRotation(hadokenangle); + vec2 Dir = vec2(pPlayerChar->m_X,pPlayerChar->m_Y) - vec2(pPrevChar->m_X, pPrevChar->m_Y); + Dir = normalize(Dir); + float HadOkenAngle = GetAngle(Dir); + Graphics()->QuadsSetRotation(HadOkenAngle ); //float offsety = -data->weapons[iw].muzzleoffsety; - RenderTools()->select_sprite(data->weapons.id[iw].sprite_muzzles[itex], 0); - vec2 diry(-dir.y,dir.x); - p = position; - float offsetx = data->weapons.id[iw].muzzleoffsetx; - p -= dir * offsetx; - RenderTools()->draw_sprite(p.x, p.y, 160.0f); + RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[iw].m_aSpriteMuzzles[IteX], 0); + vec2 DirY(-Dir.y,Dir.x); + p = Position; + float OffsetX = g_pData->m_Weapons.m_aId[iw].m_Muzzleoffsetx; + p -= Dir * OffsetX; + RenderTools()->DrawSprite(p.x, p.y, 160.0f); } } } else { // TODO: should be an animation - recoil = 0; - float a = (client_tick()-player.attacktick+intratick)/5.0f; + Recoil = 0; + float a = (Client()->GameTick()-Player.m_AttackTick+IntraTick)/5.0f; if(a < 1) - recoil = sinf(a*pi); - p = position + dir * data->weapons.id[iw].offsetx - dir*recoil*10.0f; - p.y += data->weapons.id[iw].offsety; - RenderTools()->draw_sprite(p.x, p.y, data->weapons.id[iw].visual_size); + Recoil = sinf(a*pi); + p = Position + Dir * g_pData->m_Weapons.m_aId[iw].m_Offsetx - Dir*Recoil*10.0f; + p.y += g_pData->m_Weapons.m_aId[iw].m_Offsety; + RenderTools()->DrawSprite(p.x, p.y, g_pData->m_Weapons.m_aId[iw].m_VisualSize); } - if (player.weapon == WEAPON_GUN || player.weapon == WEAPON_SHOTGUN) + if (Player.m_Weapon == WEAPON_GUN || Player.m_Weapon == WEAPON_SHOTGUN) { // check if we're firing stuff - if(data->weapons.id[iw].num_sprite_muzzles)//prev.attackticks) + if(g_pData->m_Weapons.m_aId[iw].m_NumSpriteMuzzles)//prev.attackticks) { - float alpha = 0.0f; - int phase1tick = (client_tick() - player.attacktick); - if (phase1tick < (data->weapons.id[iw].muzzleduration + 3)) + float Alpha = 0.0f; + int Phase1Tick = (Client()->GameTick() - Player.m_AttackTick); + if (Phase1Tick < (g_pData->m_Weapons.m_aId[iw].m_Muzzleduration + 3)) { - float t = ((((float)phase1tick) + intratick)/(float)data->weapons.id[iw].muzzleduration); - alpha = LERP(2.0, 0.0f, min(1.0f,max(0.0f,t))); + float t = ((((float)Phase1Tick) + IntraTick)/(float)g_pData->m_Weapons.m_aId[iw].m_Muzzleduration); + Alpha = mix(2.0f, 0.0f, min(1.0f,max(0.0f,t))); } - int itex = rand() % data->weapons.id[iw].num_sprite_muzzles; - if (alpha > 0.0f && data->weapons.id[iw].sprite_muzzles[itex]) + int IteX = rand() % g_pData->m_Weapons.m_aId[iw].m_NumSpriteMuzzles; + if (Alpha > 0.0f && g_pData->m_Weapons.m_aId[iw].m_aSpriteMuzzles[IteX]) { - float offsety = -data->weapons.id[iw].muzzleoffsety; - RenderTools()->select_sprite(data->weapons.id[iw].sprite_muzzles[itex], direction.x < 0 ? SPRITE_FLAG_FLIP_Y : 0); - if(direction.x < 0) - offsety = -offsety; + float OffsetY = -g_pData->m_Weapons.m_aId[iw].m_Muzzleoffsety; + RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[iw].m_aSpriteMuzzles[IteX], Direction.x < 0 ? SPRITE_FLAG_FLIP_Y : 0); + if(Direction.x < 0) + OffsetY = -OffsetY; - vec2 diry(-dir.y,dir.x); - vec2 muzzlepos = p + dir * data->weapons.id[iw].muzzleoffsetx + diry * offsety; + vec2 DirY(-Dir.y,Dir.x); + vec2 MuzzlePos = p + Dir * g_pData->m_Weapons.m_aId[iw].m_Muzzleoffsetx + DirY * OffsetY; - RenderTools()->draw_sprite(muzzlepos.x, muzzlepos.y, data->weapons.id[iw].visual_size); + RenderTools()->DrawSprite(MuzzlePos.x, MuzzlePos.y, g_pData->m_Weapons.m_aId[iw].m_VisualSize); } } } Graphics()->QuadsEnd(); - switch (player.weapon) + switch (Player.m_Weapon) { - case WEAPON_GUN: render_hand(&render_info, p, direction, -3*pi/4, vec2(-15, 4)); break; - case WEAPON_SHOTGUN: render_hand(&render_info, p, direction, -pi/2, vec2(-5, 4)); break; - case WEAPON_GRENADE: render_hand(&render_info, p, direction, -pi/2, vec2(-4, 7)); break; + case WEAPON_GUN: RenderHand(&RenderInfo, p, Direction, -3*pi/4, vec2(-15, 4)); break; + case WEAPON_SHOTGUN: RenderHand(&RenderInfo, p, Direction, -pi/2, vec2(-5, 4)); break; + case WEAPON_GRENADE: RenderHand(&RenderInfo, p, Direction, -pi/2, vec2(-4, 7)); break; } } // render the "shadow" tee - if(info.local && config.debug) + if(pInfo.m_Local && g_Config.m_Debug) { - vec2 ghost_position = mix(vec2(prev_char->x, prev_char->y), vec2(player_char->x, player_char->y), client_intratick()); - TEE_RENDER_INFO ghost = render_info; - ghost.color_body.a = 0.5f; - ghost.color_feet.a = 0.5f; - RenderTools()->RenderTee(&state, &ghost, player.emote, direction, ghost_position); // render ghost + vec2 GhostPosition = mix(vec2(pPrevChar->m_X, pPrevChar->m_Y), vec2(pPlayerChar->m_X, pPlayerChar->m_Y), Client()->IntraGameTick()); + CTeeRenderInfo Ghost = RenderInfo; + Ghost.m_ColorBody.a = 0.5f; + Ghost.m_ColorFeet.a = 0.5f; + RenderTools()->RenderTee(&State, &Ghost, Player.m_Emote, Direction, GhostPosition); // render ghost } - render_info.size = 64.0f; // force some settings - render_info.color_body.a = 1.0f; - render_info.color_feet.a = 1.0f; - RenderTools()->RenderTee(&state, &render_info, player.emote, direction, position); + RenderInfo.m_Size = 64.0f; // force some settings + RenderInfo.m_ColorBody.a = 1.0f; + RenderInfo.m_ColorFeet.a = 1.0f; + RenderTools()->RenderTee(&State, &RenderInfo, Player.m_Emote, Direction, Position); - if(player.player_state == PLAYERSTATE_CHATTING) + if(Player.m_PlayerState == PLAYERSTATE_CHATTING) { - Graphics()->TextureSet(data->images[IMAGE_EMOTICONS].id); + Graphics()->TextureSet(g_pData->m_aImages[IMAGE_EMOTICONS].m_Id); Graphics()->QuadsBegin(); - RenderTools()->select_sprite(SPRITE_DOTDOT); - Graphics()->QuadsDraw(position.x + 24, position.y - 40, 64,64); + RenderTools()->SelectSprite(SPRITE_DOTDOT); + IGraphics::CQuadItem QuadItem(Position.x + 24, Position.y - 40, 64,64); + Graphics()->QuadsDraw(&QuadItem, 1); Graphics()->QuadsEnd(); } - if (gameclient.clients[info.cid].emoticon_start != -1 && gameclient.clients[info.cid].emoticon_start + 2 * client_tickspeed() > client_tick()) + if (m_pClient->m_aClients[pInfo.m_ClientId].m_EmoticonStart != -1 && m_pClient->m_aClients[pInfo.m_ClientId].m_EmoticonStart + 2 * Client()->GameTickSpeed() > Client()->GameTick()) { - Graphics()->TextureSet(data->images[IMAGE_EMOTICONS].id); + Graphics()->TextureSet(g_pData->m_aImages[IMAGE_EMOTICONS].m_Id); Graphics()->QuadsBegin(); - int since_start = client_tick() - gameclient.clients[info.cid].emoticon_start; - int from_end = gameclient.clients[info.cid].emoticon_start + 2 * client_tickspeed() - client_tick(); + int SinceStart = Client()->GameTick() - m_pClient->m_aClients[pInfo.m_ClientId].m_EmoticonStart; + int FromEnd = m_pClient->m_aClients[pInfo.m_ClientId].m_EmoticonStart + 2 * Client()->GameTickSpeed() - Client()->GameTick(); float a = 1; - if (from_end < client_tickspeed() / 5) - a = from_end / (client_tickspeed() / 5.0); + if (FromEnd < Client()->GameTickSpeed() / 5) + a = FromEnd / (Client()->GameTickSpeed() / 5.0); float h = 1; - if (since_start < client_tickspeed() / 10) - h = since_start / (client_tickspeed() / 10.0); + if (SinceStart < Client()->GameTickSpeed() / 10) + h = SinceStart / (Client()->GameTickSpeed() / 10.0); - float wiggle = 0; - if (since_start < client_tickspeed() / 5) - wiggle = since_start / (client_tickspeed() / 5.0); + float Wiggle = 0; + if (SinceStart < Client()->GameTickSpeed() / 5) + Wiggle = SinceStart / (Client()->GameTickSpeed() / 5.0); - float wiggle_angle = sin(5*wiggle); + float WiggleAngle = sinf(5*Wiggle); - Graphics()->QuadsSetRotation(pi/6*wiggle_angle); + Graphics()->QuadsSetRotation(pi/6*WiggleAngle); Graphics()->SetColor(1.0f,1.0f,1.0f,a); // client_datas::emoticon is an offset from the first emoticon - RenderTools()->select_sprite(SPRITE_OOP + gameclient.clients[info.cid].emoticon); - Graphics()->QuadsDraw(position.x, position.y - 23 - 32*h, 64, 64*h); + RenderTools()->SelectSprite(SPRITE_OOP + m_pClient->m_aClients[pInfo.m_ClientId].m_Emoticon); + IGraphics::CQuadItem QuadItem(Position.x, Position.y - 23 - 32*h, 64, 64*h); + Graphics()->QuadsDraw(&QuadItem, 1); Graphics()->QuadsEnd(); } } -void PLAYERS::on_render() +void CPlayers::OnRender() { // render other players in two passes, first pass we render the other, second pass we render our self - for(int p = 0; p < 2; p++) + for(int p = 0; p < 4; p++) { for(int i = 0; i < MAX_CLIENTS; i++) { // only render active characters - if(!gameclient.snap.characters[i].active) + if(!m_pClient->m_Snap.m_aCharacters[i].m_Active) continue; - const void *prev_info = snap_find_item(SNAP_PREV, NETOBJTYPE_PLAYER_INFO, i); - const void *info = snap_find_item(SNAP_CURRENT, NETOBJTYPE_PLAYER_INFO, i); + const void *pPrevInfo = Client()->SnapFindItem(IClient::SNAP_PREV, NETOBJTYPE_PLAYERINFO, i); + const void *pInfo = Client()->SnapFindItem(IClient::SNAP_CURRENT, NETOBJTYPE_PLAYERINFO, i); - if(prev_info && info) + if(pPrevInfo && pInfo) { // - bool local = ((const NETOBJ_PLAYER_INFO *)info)->local !=0; - if(p == 0 && local) continue; - if(p == 1 && !local) continue; + bool Local = ((const CNetObj_PlayerInfo *)pInfo)->m_Local !=0; + if((p % 2) == 0 && Local) continue; + if((p % 2) == 1 && !Local) continue; - NETOBJ_CHARACTER prev_char = gameclient.snap.characters[i].prev; - NETOBJ_CHARACTER cur_char = gameclient.snap.characters[i].cur; - - render_player( - &prev_char, - &cur_char, - (const NETOBJ_PLAYER_INFO *)prev_info, - (const NETOBJ_PLAYER_INFO *)info - ); + CNetObj_Character PrevChar = m_pClient->m_Snap.m_aCharacters[i].m_Prev; + CNetObj_Character CurChar = m_pClient->m_Snap.m_aCharacters[i].m_Cur; + + if(p<2) + RenderHook( + &PrevChar, + &CurChar, + (const CNetObj_PlayerInfo *)pPrevInfo, + (const CNetObj_PlayerInfo *)pInfo + ); + else + RenderPlayer( + &PrevChar, + &CurChar, + (const CNetObj_PlayerInfo *)pPrevInfo, + (const CNetObj_PlayerInfo *)pInfo + ); } } } diff --git a/src/game/client/components/players.h b/src/game/client/components/players.h new file mode 100644 index 00000000..57501380 --- /dev/null +++ b/src/game/client/components/players.h @@ -0,0 +1,25 @@ +#ifndef GAME_CLIENT_COMPONENTS_PLAYERS_H +#define GAME_CLIENT_COMPONENTS_PLAYERS_H +#include <game/client/component.h> + +class CPlayers : public CComponent +{ + void RenderHand(class CTeeRenderInfo *pInfo, vec2 CenterPos, vec2 Dir, float AngleOffset, vec2 PostRotOffset); + void RenderPlayer( + const class CNetObj_Character *pPrevChar, + const class CNetObj_Character *pPlayerChar, + const class CNetObj_PlayerInfo *pPrevInfo, + const class CNetObj_PlayerInfo *pPlayerInfo + ); + void RenderHook( + const CNetObj_Character *pPrevChar, + const CNetObj_Character *pPlayerChar, + const CNetObj_PlayerInfo *pPrevInfo, + const CNetObj_PlayerInfo *pPlayerInfo + ); + +public: + virtual void OnRender(); +}; + +#endif diff --git a/src/game/client/components/players.hpp b/src/game/client/components/players.hpp deleted file mode 100644 index bdce91de..00000000 --- a/src/game/client/components/players.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#include <game/client/component.hpp> - -class PLAYERS : public COMPONENT -{ - void render_hand(class TEE_RENDER_INFO *info, vec2 center_pos, vec2 dir, float angle_offset, vec2 post_rot_offset); - void render_player( - const class NETOBJ_CHARACTER *prev_char, - const class NETOBJ_CHARACTER *player_char, - const class NETOBJ_PLAYER_INFO *prev_info, - const class NETOBJ_PLAYER_INFO *player_info - ); - -public: - virtual void on_render(); -}; - diff --git a/src/game/client/components/scoreboard.cpp b/src/game/client/components/scoreboard.cpp index e8db1aed..b7e8aa9a 100644 --- a/src/game/client/components/scoreboard.cpp +++ b/src/game/client/components/scoreboard.cpp @@ -1,36 +1,37 @@ -#include <string.h> -#include <engine/e_client_interface.h> -#include <engine/client/graphics.h> -#include <game/generated/g_protocol.hpp> -#include <game/generated/gc_data.hpp> -#include <game/client/gameclient.hpp> -#include <game/client/animstate.hpp> -#include <game/client/render.hpp> -#include <game/client/components/motd.hpp> -#include "scoreboard.hpp" - - -SCOREBOARD::SCOREBOARD() +#include <engine/graphics.h> +#include <engine/textrender.h> +#include <engine/shared/config.h> +#include <game/generated/protocol.h> +#include <game/generated/client_data.h> +#include <game/client/gameclient.h> +#include <game/client/animstate.h> +#include <game/client/render.h> +#include <game/client/components/motd.h> +#include <game/localization.h> +#include "scoreboard.h" + + +CScoreboard::CScoreboard() { - on_reset(); + OnReset(); } -void SCOREBOARD::con_key_scoreboard(void *result, void *user_data) +void CScoreboard::ConKeyScoreboard(IConsole::IResult *pResult, void *pUserData) { - ((SCOREBOARD *)user_data)->active = console_arg_int(result, 0) != 0; + ((CScoreboard *)pUserData)->m_Active = pResult->GetInteger(0) != 0; } -void SCOREBOARD::on_reset() +void CScoreboard::OnReset() { - active = false; + m_Active = false; } -void SCOREBOARD::on_console_init() +void CScoreboard::OnConsoleInit() { - MACRO_REGISTER_COMMAND("+scoreboard", "", CFGFLAG_CLIENT, con_key_scoreboard, this, "Show scoreboard"); + Console()->Register("+scoreboard", "", CFGFLAG_CLIENT, ConKeyScoreboard, this, "Show scoreboard"); } -void SCOREBOARD::render_goals(float x, float y, float w) +void CScoreboard::RenderGoals(float x, float y, float w) { float h = 50.0f; @@ -38,74 +39,77 @@ void SCOREBOARD::render_goals(float x, float y, float w) Graphics()->TextureSet(-1); Graphics()->QuadsBegin(); Graphics()->SetColor(0,0,0,0.5f); - RenderTools()->draw_round_rect(x-10.f, y-10.f, w, h, 10.0f); + RenderTools()->DrawRoundRect(x-10.f, y-10.f, w, h, 10.0f); Graphics()->QuadsEnd(); // render goals //y = ystart+h-54; float tw = 0.0f; - if(gameclient.snap.gameobj && gameclient.snap.gameobj->score_limit) + if(m_pClient->m_Snap.m_pGameobj) { - char buf[64]; - str_format(buf, sizeof(buf), "%s: %d", localize("Score limit"), gameclient.snap.gameobj->score_limit); - gfx_text(0, x+20.0f, y, 22.0f, buf, -1); - tw += gfx_text_width(0, 22.0f, buf, -1); - } - if(gameclient.snap.gameobj && gameclient.snap.gameobj->time_limit) - { - char buf[64]; - str_format(buf, sizeof(buf), "%s: %d min", localize("Time limit"), gameclient.snap.gameobj->time_limit); - gfx_text(0, x+220.0f, y, 22.0f, buf, -1); - tw += gfx_text_width(0, 22.0f, buf, -1); - } - if(gameclient.snap.gameobj && gameclient.snap.gameobj->round_num && gameclient.snap.gameobj->round_current) - { - char buf[64]; - str_format(buf, sizeof(buf), "%s %d/%d", localize("Round"), gameclient.snap.gameobj->round_current, gameclient.snap.gameobj->round_num); - gfx_text(0, x+450.0f, y, 22.0f, buf, -1); - - /*[48c3fd4c][game/scoreboard]: timelimit x:219.428558 - [48c3fd4c][game/scoreboard]: round x:453.142822*/ + if(m_pClient->m_Snap.m_pGameobj->m_ScoreLimit) + { + char aBuf[64]; + str_format(aBuf, sizeof(aBuf), "%s: %d", Localize("Score limit"), m_pClient->m_Snap.m_pGameobj->m_ScoreLimit); + TextRender()->Text(0, x+20.0f, y, 22.0f, aBuf, -1); + tw += TextRender()->TextWidth(0, 22.0f, aBuf, -1); + } + if(m_pClient->m_Snap.m_pGameobj->m_TimeLimit) + { + char aBuf[64]; + str_format(aBuf, sizeof(aBuf), "%s: %d min", Localize("Time limit"), m_pClient->m_Snap.m_pGameobj->m_TimeLimit); + TextRender()->Text(0, x+220.0f, y, 22.0f, aBuf, -1); + tw += TextRender()->TextWidth(0, 22.0f, aBuf, -1); + } + if(m_pClient->m_Snap.m_pGameobj->m_RoundNum && m_pClient->m_Snap.m_pGameobj->m_RoundCurrent) + { + char aBuf[64]; + str_format(aBuf, sizeof(aBuf), "%s %d/%d", Localize("Round"), m_pClient->m_Snap.m_pGameobj->m_RoundCurrent, m_pClient->m_Snap.m_pGameobj->m_RoundNum); + TextRender()->Text(0, x+450.0f, y, 22.0f, aBuf, -1); + + /*[48c3fd4c][game/scoreboard]: timelimit x:219.428558 + [48c3fd4c][game/scoreboard]: round x:453.142822*/ + } } } -void SCOREBOARD::render_spectators(float x, float y, float w) +void CScoreboard::RenderSpectators(float x, float y, float w) { - char buffer[1024*4]; - int count = 0; + char aBuffer[1024*4]; + int Count = 0; float h = 120.0f; - str_format(buffer, sizeof(buffer), "%s: ", localize("Spectators")); + str_format(aBuffer, sizeof(aBuffer), "%s: ", Localize("Spectators")); Graphics()->BlendNormal(); Graphics()->TextureSet(-1); Graphics()->QuadsBegin(); Graphics()->SetColor(0,0,0,0.5f); - RenderTools()->draw_round_rect(x-10.f, y-10.f, w, h, 10.0f); + RenderTools()->DrawRoundRect(x-10.f, y-10.f, w, h, 10.0f); Graphics()->QuadsEnd(); - for(int i = 0; i < snap_num_items(SNAP_CURRENT); i++) + for(int i = 0; i < Client()->SnapNumItems(IClient::SNAP_CURRENT); i++) { - SNAP_ITEM item; - const void *data = snap_get_item(SNAP_CURRENT, i, &item); + IClient::CSnapItem Item; + const void *pData = Client()->SnapGetItem(IClient::SNAP_CURRENT, i, &Item); - if(item.type == NETOBJTYPE_PLAYER_INFO) + if(Item.m_Type == NETOBJTYPE_PLAYERINFO) { - const NETOBJ_PLAYER_INFO *info = (const NETOBJ_PLAYER_INFO *)data; - if(info->team == -1) + const CNetObj_PlayerInfo *pInfo = (const CNetObj_PlayerInfo *)pData; + if(pInfo->m_Team == -1) { - if(count) - strcat(buffer, ", "); - strcat(buffer, gameclient.clients[info->cid].name); - count++; + if(Count) + str_append(aBuffer, ", ", sizeof(aBuffer)); + str_append(aBuffer, m_pClient->m_aClients[pInfo->m_ClientId].m_aName, sizeof(aBuffer)); + Count++; } } } - gfx_text(0, x+10, y, 32, buffer, (int)w-20); + TextRender()->Text(0, x+10, y, 32, aBuffer, (int)w-20); } -void SCOREBOARD::render_scoreboard(float x, float y, float w, int team, const char *title) +void CScoreboard::RenderScoreboard(float x, float y, float w, int Team, const char *pTitle) { //float ystart = y; float h = 750.0f; @@ -114,202 +118,203 @@ void SCOREBOARD::render_scoreboard(float x, float y, float w, int team, const ch Graphics()->TextureSet(-1); Graphics()->QuadsBegin(); Graphics()->SetColor(0,0,0,0.5f); - RenderTools()->draw_round_rect(x-10.f, y-10.f, w, h, 17.0f); + RenderTools()->DrawRoundRect(x-10.f, y-10.f, w, h, 17.0f); Graphics()->QuadsEnd(); // render title - if(!title) + if(!pTitle) { - if(gameclient.snap.gameobj->game_over) - title = localize("Game over"); + if(m_pClient->m_Snap.m_pGameobj->m_GameOver) + pTitle = Localize("Game over"); else - title = localize("Score board"); + pTitle = Localize("Score board"); } - float tw = gfx_text_width(0, 48, title, -1); + float tw = TextRender()->TextWidth(0, 48, pTitle, -1); - if(team == -1) + if(Team == -1) { - gfx_text(0, x+w/2-tw/2, y, 48, title, -1); + TextRender()->Text(0, x+w/2-tw/2, y, 48, pTitle, -1); } else { - gfx_text(0, x+10, y, 48, title, -1); + TextRender()->Text(0, x+10, y, 48, pTitle, -1); - if(gameclient.snap.gameobj) + if(m_pClient->m_Snap.m_pGameobj) { - char buf[128]; - int score = team ? gameclient.snap.gameobj->teamscore_blue : gameclient.snap.gameobj->teamscore_red; - str_format(buf, sizeof(buf), "%d", score); - tw = gfx_text_width(0, 48, buf, -1); - gfx_text(0, x+w-tw-30, y, 48, buf, -1); + char aBuf[128]; + int Score = Team ? m_pClient->m_Snap.m_pGameobj->m_TeamscoreBlue : m_pClient->m_Snap.m_pGameobj->m_TeamscoreRed; + str_format(aBuf, sizeof(aBuf), "%d", Score); + tw = TextRender()->TextWidth(0, 48, aBuf, -1); + TextRender()->Text(0, x+w-tw-30, y, 48, aBuf, -1); } } y += 54.0f; // find players - const NETOBJ_PLAYER_INFO *players[MAX_CLIENTS] = {0}; - int num_players = 0; - for(int i = 0; i < snap_num_items(SNAP_CURRENT); i++) + const CNetObj_PlayerInfo *paPlayers[MAX_CLIENTS] = {0}; + int NumPlayers = 0; + for(int i = 0; i < Client()->SnapNumItems(IClient::SNAP_CURRENT); i++) { - SNAP_ITEM item; - const void *data = snap_get_item(SNAP_CURRENT, i, &item); + IClient::CSnapItem Item; + const void *pData = Client()->SnapGetItem(IClient::SNAP_CURRENT, i, &Item); - if(item.type == NETOBJTYPE_PLAYER_INFO) + if(Item.m_Type == NETOBJTYPE_PLAYERINFO) { - const NETOBJ_PLAYER_INFO *info = (const NETOBJ_PLAYER_INFO *)data; - if(info->team == team) + const CNetObj_PlayerInfo *pInfo = (const CNetObj_PlayerInfo *)pData; + if(pInfo->m_Team == Team) { - players[num_players] = info; - num_players++; + paPlayers[NumPlayers] = pInfo; + NumPlayers++; } } } // sort players - for(int k = 0; k < num_players; k++) // ffs, bubblesort + for(int k = 0; k < NumPlayers; k++) // ffs, bubblesort { - for(int i = 0; i < num_players-k-1; i++) + for(int i = 0; i < NumPlayers-k-1; i++) { - if(players[i]->score < players[i+1]->score) + if(paPlayers[i]->m_Score < paPlayers[i+1]->m_Score) { - const NETOBJ_PLAYER_INFO *tmp = players[i]; - players[i] = players[i+1]; - players[i+1] = tmp; + const CNetObj_PlayerInfo *pTmp = paPlayers[i]; + paPlayers[i] = paPlayers[i+1]; + paPlayers[i+1] = pTmp; } } } // render headlines - gfx_text(0, x+10, y, 24.0f, localize("Score"), -1); - gfx_text(0, x+125, y, 24.0f, localize("Name"), -1); - gfx_text(0, x+w-70, y, 24.0f, localize("Ping"), -1); + TextRender()->Text(0, x+10, y, 24.0f, Localize("Score"), -1); + TextRender()->Text(0, x+125, y, 24.0f, Localize("Name"), -1); + TextRender()->Text(0, x+w-70, y, 24.0f, Localize("Ping"), -1); y += 29.0f; - float font_size = 35.0f; - float line_height = 50.0f; - float tee_sizemod = 1.0f; - float tee_offset = 0.0f; + float FontSize = 35.0f; + float LineHeight = 50.0f; + float TeeSizeMod = 1.0f; + float TeeOffset = 0.0f; - if(num_players > 13) + if(NumPlayers > 13) { - font_size = 30.0f; - line_height = 40.0f; - tee_sizemod = 0.8f; - tee_offset = -5.0f; + FontSize = 30.0f; + LineHeight = 40.0f; + TeeSizeMod = 0.8f; + TeeOffset = -5.0f; } // render player scores - for(int i = 0; i < num_players; i++) + for(int i = 0; i < NumPlayers; i++) { - const NETOBJ_PLAYER_INFO *info = players[i]; + const CNetObj_PlayerInfo *pInfo = paPlayers[i]; // make sure that we render the correct team - char buf[128]; - if(info->local) + char aBuf[128]; + if(pInfo->m_Local) { // background so it's easy to find the local player Graphics()->TextureSet(-1); Graphics()->QuadsBegin(); Graphics()->SetColor(1,1,1,0.25f); - RenderTools()->draw_round_rect(x, y, w-20, line_height*0.95f, 17.0f); + RenderTools()->DrawRoundRect(x, y, w-20, LineHeight*0.95f, 17.0f); Graphics()->QuadsEnd(); } - str_format(buf, sizeof(buf), "%4d", info->score); - gfx_text(0, x+60-gfx_text_width(0, font_size,buf,-1), y, font_size, buf, -1); + str_format(aBuf, sizeof(aBuf), "%4d", pInfo->m_Score); + TextRender()->Text(0, x+60-TextRender()->TextWidth(0, FontSize,aBuf,-1), y, FontSize, aBuf, -1); - gfx_text(0, x+128, y, font_size, gameclient.clients[info->cid].name, -1); + TextRender()->Text(0, x+128, y, FontSize, m_pClient->m_aClients[pInfo->m_ClientId].m_aName, -1); - str_format(buf, sizeof(buf), "%4d", info->latency); - float tw = gfx_text_width(0, font_size, buf, -1); - gfx_text(0, x+w-tw-35, y, font_size, buf, -1); + str_format(aBuf, sizeof(aBuf), "%4d", pInfo->m_Latency); + float tw = TextRender()->TextWidth(0, FontSize, aBuf, -1); + TextRender()->Text(0, x+w-tw-35, y, FontSize, aBuf, -1); // render avatar - if((gameclient.snap.flags[0] && gameclient.snap.flags[0]->carried_by == info->cid) || - (gameclient.snap.flags[1] && gameclient.snap.flags[1]->carried_by == info->cid)) + if((m_pClient->m_Snap.m_paFlags[0] && m_pClient->m_Snap.m_paFlags[0]->m_CarriedBy == pInfo->m_ClientId) || + (m_pClient->m_Snap.m_paFlags[1] && m_pClient->m_Snap.m_paFlags[1]->m_CarriedBy == pInfo->m_ClientId)) { Graphics()->BlendNormal(); - Graphics()->TextureSet(data->images[IMAGE_GAME].id); + Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id); Graphics()->QuadsBegin(); - if(info->team == 0) RenderTools()->select_sprite(SPRITE_FLAG_BLUE, SPRITE_FLAG_FLIP_X); - else RenderTools()->select_sprite(SPRITE_FLAG_RED, SPRITE_FLAG_FLIP_X); + if(pInfo->m_Team == 0) RenderTools()->SelectSprite(SPRITE_FLAG_BLUE, SPRITE_FLAG_FLIP_X); + else RenderTools()->SelectSprite(SPRITE_FLAG_RED, SPRITE_FLAG_FLIP_X); float size = 64.0f; - Graphics()->QuadsDrawTL(x+55, y-15, size/2, size); + IGraphics::CQuadItem QuadItem(x+55, y-15, size/2, size); + Graphics()->QuadsDrawTL(&QuadItem, 1); Graphics()->QuadsEnd(); } - TEE_RENDER_INFO teeinfo = gameclient.clients[info->cid].render_info; - teeinfo.size *= tee_sizemod; - RenderTools()->RenderTee(ANIMSTATE::get_idle(), &teeinfo, EMOTE_NORMAL, vec2(1,0), vec2(x+90, y+28+tee_offset)); + CTeeRenderInfo TeeInfo = m_pClient->m_aClients[pInfo->m_ClientId].m_RenderInfo; + TeeInfo.m_Size *= TeeSizeMod; + RenderTools()->RenderTee(CAnimState::GetIdle(), &TeeInfo, EMOTE_NORMAL, vec2(1,0), vec2(x+90, y+28+TeeOffset)); - y += line_height; + y += LineHeight; } } -void SCOREBOARD::on_render() +void CScoreboard::OnRender() { - bool do_scoreboard = false; + bool DoScoreBoard = false; // if we activly wanna look on the scoreboard - if(active) - do_scoreboard = true; + if(m_Active) + DoScoreBoard = true; - if(gameclient.snap.local_info && gameclient.snap.local_info->team != -1) + if(m_pClient->m_Snap.m_pLocalInfo && m_pClient->m_Snap.m_pLocalInfo->m_Team != -1) { // we are not a spectator, check if we are ead - if(!gameclient.snap.local_character || gameclient.snap.local_character->health < 0) - do_scoreboard = true; + if(!m_pClient->m_Snap.m_pLocalCharacter || m_pClient->m_Snap.m_pLocalCharacter->m_Health < 0) + DoScoreBoard = true; } // if we the game is over - if(gameclient.snap.gameobj && gameclient.snap.gameobj->game_over) - do_scoreboard = true; + if(m_pClient->m_Snap.m_pGameobj && m_pClient->m_Snap.m_pGameobj->m_GameOver) + DoScoreBoard = true; - if(!do_scoreboard) + if(!DoScoreBoard) return; // if the score board is active, then we should clear the motd message aswell - if(active) - gameclient.motd->clear(); + if(m_Active) + m_pClient->m_pMotd->Clear(); - float width = 400*3.0f*Graphics()->ScreenAspect(); - float height = 400*3.0f; + float Width = 400*3.0f*Graphics()->ScreenAspect(); + float Height = 400*3.0f; - Graphics()->MapScreen(0, 0, width, height); + Graphics()->MapScreen(0, 0, Width, Height); float w = 650.0f; - if(gameclient.snap.gameobj && !(gameclient.snap.gameobj->flags&GAMEFLAG_TEAMS)) + if(m_pClient->m_Snap.m_pGameobj && !(m_pClient->m_Snap.m_pGameobj->m_Flags&GAMEFLAG_TEAMS)) { - render_scoreboard(width/2-w/2, 150.0f, w, 0, 0); + RenderScoreboard(Width/2-w/2, 150.0f, w, 0, 0); //render_scoreboard(gameobj, 0, 0, -1, 0); } else { - if(gameclient.snap.gameobj && gameclient.snap.gameobj->game_over) + if(m_pClient->m_Snap.m_pGameobj && m_pClient->m_Snap.m_pGameobj->m_GameOver) { - const char *text = localize("Draw!"); - if(gameclient.snap.gameobj->teamscore_red > gameclient.snap.gameobj->teamscore_blue) - text = localize("Red team wins!"); - else if(gameclient.snap.gameobj->teamscore_blue > gameclient.snap.gameobj->teamscore_red) - text = localize("Blue team wins!"); + const char *pText = Localize("Draw!"); + if(m_pClient->m_Snap.m_pGameobj->m_TeamscoreRed > m_pClient->m_Snap.m_pGameobj->m_TeamscoreBlue) + pText = Localize("Red team wins!"); + else if(m_pClient->m_Snap.m_pGameobj->m_TeamscoreBlue > m_pClient->m_Snap.m_pGameobj->m_TeamscoreRed) + pText = Localize("Blue team wins!"); - float w = gfx_text_width(0, 92.0f, text, -1); - gfx_text(0, width/2-w/2, 45, 92.0f, text, -1); + float w = TextRender()->TextWidth(0, 92.0f, pText, -1); + TextRender()->Text(0, Width/2-w/2, 45, 92.0f, pText, -1); } - render_scoreboard(width/2-w-20, 150.0f, w, 0, localize("Red team")); - render_scoreboard(width/2 + 20, 150.0f, w, 1, localize("Blue team")); + RenderScoreboard(Width/2-w-20, 150.0f, w, 0, Localize("Red team")); + RenderScoreboard(Width/2 + 20, 150.0f, w, 1, Localize("Blue team")); } - render_goals(width/2-w/2, 150+750+25, w); - render_spectators(width/2-w/2, 150+750+25+50+25, w); + RenderGoals(Width/2-w/2, 150+750+25, w); + RenderSpectators(Width/2-w/2, 150+750+25+50+25, w); } diff --git a/src/game/client/components/scoreboard.h b/src/game/client/components/scoreboard.h new file mode 100644 index 00000000..5aa2f0a7 --- /dev/null +++ b/src/game/client/components/scoreboard.h @@ -0,0 +1,22 @@ +#ifndef GAME_CLIENT_COMPONENTS_SCOREBOARD_H +#define GAME_CLIENT_COMPONENTS_SCOREBOARD_H +#include <game/client/component.h> + +class CScoreboard : public CComponent +{ + void RenderGoals(float x, float y, float w); + void RenderSpectators(float x, float y, float w); + void RenderScoreboard(float x, float y, float w, int Team, const char *pTitle); + + static void ConKeyScoreboard(IConsole::IResult *pResult, void *pUserData); + + bool m_Active; + +public: + CScoreboard(); + virtual void OnReset(); + virtual void OnConsoleInit(); + virtual void OnRender(); +}; + +#endif diff --git a/src/game/client/components/scoreboard.hpp b/src/game/client/components/scoreboard.hpp deleted file mode 100644 index 222dab9d..00000000 --- a/src/game/client/components/scoreboard.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#include <game/client/component.hpp> - -class SCOREBOARD : public COMPONENT -{ - void render_goals(float x, float y, float w); - void render_spectators(float x, float y, float w); - void render_scoreboard(float x, float y, float w, int team, const char *title); - - static void con_key_scoreboard(void *result, void *user_data); - - bool active; - -public: - SCOREBOARD(); - virtual void on_reset(); - virtual void on_console_init(); - virtual void on_render(); -}; - diff --git a/src/game/client/components/skins.cpp b/src/game/client/components/skins.cpp index ad3607a1..582adb10 100644 --- a/src/game/client/components/skins.cpp +++ b/src/game/client/components/skins.cpp @@ -1,153 +1,150 @@ -/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */ -#include <string.h> -#include <stdio.h> +// copyright (c) 2007 magnus auvinen, see licence.txt for more info #include <math.h> #include <base/system.h> -#include <base/math.hpp> +#include <base/math.h> -#include <engine/client/graphics.h> -#include <engine/e_client_interface.h> +#include <engine/graphics.h> +#include <engine/storage.h> +#include <engine/shared/engine.h> -#include <engine/e_engine.h> +#include "skins.h" -#include "skins.hpp" - -SKINS::SKINS() +CSkins::CSkins() { - num_skins = 0; + m_NumSkins = 0; } -void SKINS::skinscan(const char *name, int is_dir, void *user) +void CSkins::SkinScan(const char *pName, int IsDir, void *pUser) { - SKINS *self = (SKINS *)user; - int l = strlen(name); - if(l < 4 || is_dir || self->num_skins == MAX_SKINS) + CSkins *pSelf = (CSkins *)pUser; + int l = str_length(pName); + if(l < 4 || IsDir || pSelf->m_NumSkins == MAX_SKINS) return; - if(strcmp(name+l-4, ".png") != 0) + if(str_comp(pName+l-4, ".png") != 0) return; - char buf[512]; - str_format(buf, sizeof(buf), "skins/%s", name); - IMAGE_INFO info; - if(!self->Graphics()->LoadPNG(&info, buf)) + char aBuf[512]; + str_format(aBuf, sizeof(aBuf), "skins/%s", pName); + CImageInfo Info; + if(!pSelf->Graphics()->LoadPNG(&Info, aBuf)) { - dbg_msg("game", "failed to load skin from %s", name); + dbg_msg("game", "failed to load skin from %s", pName); return; } - self->skins[self->num_skins].org_texture = self->Graphics()->LoadTextureRaw(info.width, info.height, info.format, info.data, info.format, 0); + pSelf->m_aSkins[pSelf->m_NumSkins].m_OrgTexture = pSelf->Graphics()->LoadTextureRaw(Info.m_Width, Info.m_Height, Info.m_Format, Info.m_pData, Info.m_Format, 0); - int body_size = 96; // body size - unsigned char *d = (unsigned char *)info.data; - int pitch = info.width*4; + int BodySize = 96; // body size + unsigned char *d = (unsigned char *)Info.m_pData; + int Pitch = Info.m_Width*4; // dig out blood color { - int colors[3] = {0}; - for(int y = 0; y < body_size; y++) - for(int x = 0; x < body_size; x++) + int aColors[3] = {0}; + for(int y = 0; y < BodySize; y++) + for(int x = 0; x < BodySize; x++) { - if(d[y*pitch+x*4+3] > 128) + if(d[y*Pitch+x*4+3] > 128) { - colors[0] += d[y*pitch+x*4+0]; - colors[1] += d[y*pitch+x*4+1]; - colors[2] += d[y*pitch+x*4+2]; + aColors[0] += d[y*Pitch+x*4+0]; + aColors[1] += d[y*Pitch+x*4+1]; + aColors[2] += d[y*Pitch+x*4+2]; } } - self->skins[self->num_skins].blood_color = normalize(vec3(colors[0], colors[1], colors[2])); + pSelf->m_aSkins[pSelf->m_NumSkins].m_BloodColor = normalize(vec3(aColors[0], aColors[1], aColors[2])); } // create colorless version - int step = info.format == IMG_RGBA ? 4 : 3; + int Step = Info.m_Format == CImageInfo::FORMAT_RGBA ? 4 : 3; // make the texture gray scale - for(int i = 0; i < info.width*info.height; i++) + for(int i = 0; i < Info.m_Width*Info.m_Height; i++) { - int v = (d[i*step]+d[i*step+1]+d[i*step+2])/3; - d[i*step] = v; - d[i*step+1] = v; - d[i*step+2] = v; + int v = (d[i*Step]+d[i*Step+1]+d[i*Step+2])/3; + d[i*Step] = v; + d[i*Step+1] = v; + d[i*Step+2] = v; } if(1) { - int freq[256] = {0}; - int org_weight = 0; - int new_weight = 192; + int Freq[256] = {0}; + int OrgWeight = 0; + int NewWeight = 192; // find most common frequence - for(int y = 0; y < body_size; y++) - for(int x = 0; x < body_size; x++) + for(int y = 0; y < BodySize; y++) + for(int x = 0; x < BodySize; x++) { - if(d[y*pitch+x*4+3] > 128) - freq[d[y*pitch+x*4]]++; + if(d[y*Pitch+x*4+3] > 128) + Freq[d[y*Pitch+x*4]]++; } for(int i = 1; i < 256; i++) { - if(freq[org_weight] < freq[i]) - org_weight = i; + if(Freq[OrgWeight] < Freq[i]) + OrgWeight = i; } // reorder - int inv_org_weight = 255-org_weight; - int inv_new_weight = 255-new_weight; - for(int y = 0; y < body_size; y++) - for(int x = 0; x < body_size; x++) + int InvOrgWeight = 255-OrgWeight; + int InvNewWeight = 255-NewWeight; + for(int y = 0; y < BodySize; y++) + for(int x = 0; x < BodySize; x++) { - int v = d[y*pitch+x*4]; - if(v <= org_weight) - v = (int)(((v/(float)org_weight) * new_weight)); + int v = d[y*Pitch+x*4]; + if(v <= OrgWeight) + v = (int)(((v/(float)OrgWeight) * NewWeight)); else - v = (int)(((v-org_weight)/(float)inv_org_weight)*inv_new_weight + new_weight); - d[y*pitch+x*4] = v; - d[y*pitch+x*4+1] = v; - d[y*pitch+x*4+2] = v; + v = (int)(((v-OrgWeight)/(float)InvOrgWeight)*InvNewWeight + NewWeight); + d[y*Pitch+x*4] = v; + d[y*Pitch+x*4+1] = v; + d[y*Pitch+x*4+2] = v; } } - self->skins[self->num_skins].color_texture = self->Graphics()->LoadTextureRaw(info.width, info.height, info.format, info.data, info.format, 0); - mem_free(info.data); + pSelf->m_aSkins[pSelf->m_NumSkins].m_ColorTexture = pSelf->Graphics()->LoadTextureRaw(Info.m_Width, Info.m_Height, Info.m_Format, Info.m_pData, Info.m_Format, 0); + mem_free(Info.m_pData); // set skin data - strncpy(self->skins[self->num_skins].name, name, min((int)sizeof(self->skins[self->num_skins].name),l-4)); - dbg_msg("game", "load skin %s", self->skins[self->num_skins].name); - self->num_skins++; + str_copy(pSelf->m_aSkins[pSelf->m_NumSkins].m_aName, pName, min((int)sizeof(pSelf->m_aSkins[pSelf->m_NumSkins].m_aName),l-3)); + dbg_msg("game", "load skin %s", pSelf->m_aSkins[pSelf->m_NumSkins].m_aName); + pSelf->m_NumSkins++; } -void SKINS::init() +void CSkins::Init() { // load skins - num_skins = 0; - engine_listdir(LISTDIRTYPE_ALL, "skins", skinscan, this); + m_NumSkins = 0; + Storage()->ListDirectory(IStorage::TYPE_ALL, "skins", SkinScan, this); } -int SKINS::num() +int CSkins::Num() { - return num_skins; + return m_NumSkins; } -const SKINS::SKIN *SKINS::get(int index) +const CSkins::CSkin *CSkins::Get(int Index) { - return &skins[index%num_skins]; + return &m_aSkins[Index%m_NumSkins]; } -int SKINS::find(const char *name) +int CSkins::Find(const char *pName) { - for(int i = 0; i < num_skins; i++) + for(int i = 0; i < m_NumSkins; i++) { - if(strcmp(skins[i].name, name) == 0) + if(str_comp(m_aSkins[i].m_aName, pName) == 0) return i; } return -1; } // these converter functions were nicked from some random internet pages -static float hue_to_rgb(float v1, float v2, float h) +static float HueToRgb(float v1, float v2, float h) { if(h < 0) h += 1; if(h > 1) h -= 1; @@ -157,16 +154,16 @@ static float hue_to_rgb(float v1, float v2, float h) return v1; } -static vec3 hsl_to_rgb(vec3 in) +static vec3 HslToRgb(vec3 in) { float v1, v2; - vec3 out; + vec3 Out; if(in.s == 0) { - out.r = in.l; - out.g = in.l; - out.b = in.l; + Out.r = in.l; + Out.g = in.l; + Out.b = in.l; } else { @@ -177,16 +174,16 @@ static vec3 hsl_to_rgb(vec3 in) v1 = 2 * in.l - v2; - out.r = hue_to_rgb(v1, v2, in.h + (1.0f/3.0f)); - out.g = hue_to_rgb(v1, v2, in.h); - out.b = hue_to_rgb(v1, v2, in.h - (1.0f/3.0f)); + Out.r = HueToRgb(v1, v2, in.h + (1.0f/3.0f)); + Out.g = HueToRgb(v1, v2, in.h); + Out.b = HueToRgb(v1, v2, in.h - (1.0f/3.0f)); } - return out; + return Out; } -vec4 SKINS::get_color(int v) +vec4 CSkins::GetColor(int v) { - vec3 r = hsl_to_rgb(vec3((v>>16)/255.0f, ((v>>8)&0xff)/255.0f, 0.5f+(v&0xff)/255.0f*0.5f)); + vec3 r = HslToRgb(vec3(((v>>16)&0xff)/255.0f, ((v>>8)&0xff)/255.0f, 0.5f+(v&0xff)/255.0f*0.5f)); return vec4(r.r, r.g, r.b, 1.0f); } diff --git a/src/game/client/components/skins.h b/src/game/client/components/skins.h new file mode 100644 index 00000000..f733140f --- /dev/null +++ b/src/game/client/components/skins.h @@ -0,0 +1,39 @@ +#ifndef GAME_CLIENT_COMPONENTS_SKINS_H +#define GAME_CLIENT_COMPONENTS_SKINS_H +#include <base/vmath.h> +#include <game/client/component.h> + +class CSkins : public CComponent +{ +public: + // do this better and nicer + struct CSkin + { + int m_OrgTexture; + int m_ColorTexture; + char m_aName[31]; + char m_aTerm[1]; + vec3 m_BloodColor; + } ; + + CSkins(); + + void Init(); + + vec4 GetColor(int v); + int Num(); + const CSkin *Get(int Index); + int Find(const char *pName); + +private: + enum + { + MAX_SKINS=256, + }; + + CSkin m_aSkins[MAX_SKINS]; + int m_NumSkins; + + static void SkinScan(const char *pName, int IsDir, void *pUser); +}; +#endif diff --git a/src/game/client/components/skins.hpp b/src/game/client/components/skins.hpp deleted file mode 100644 index 078fd71d..00000000 --- a/src/game/client/components/skins.hpp +++ /dev/null @@ -1,36 +0,0 @@ -#include <base/vmath.hpp> -#include <game/client/component.hpp> - -class SKINS : public COMPONENT -{ -public: - // do this better and nicer - typedef struct - { - int org_texture; - int color_texture; - char name[31]; - char term[1]; - vec3 blood_color; - } SKIN; - - SKINS(); - - void init(); - - vec4 get_color(int v); - int num(); - const SKIN *get(int index); - int find(const char *name); - -private: - enum - { - MAX_SKINS=256, - }; - - SKIN skins[MAX_SKINS]; - int num_skins; - - static void skinscan(const char *name, int is_dir, void *user); -}; diff --git a/src/game/client/components/sounds.cpp b/src/game/client/components/sounds.cpp index dfa7e31b..84e45efa 100644 --- a/src/game/client/components/sounds.cpp +++ b/src/game/client/components/sounds.cpp @@ -1,54 +1,91 @@ -#include <engine/e_client_interface.h> -#include <game/generated/gc_data.hpp> -#include <game/client/gameclient.hpp> -#include <game/client/components/camera.hpp> -#include "sounds.hpp" +#include <engine/sound.h> +#include <game/generated/client_data.h> +#include <game/client/gameclient.h> +#include <game/client/components/camera.h> +#include "sounds.h" -void SOUNDS::on_init() +void CSounds::OnInit() { // setup sound channels - snd_set_channel(SOUNDS::CHN_GUI, 1.0f, 0.0f); - snd_set_channel(SOUNDS::CHN_MUSIC, 1.0f, 0.0f); - snd_set_channel(SOUNDS::CHN_WORLD, 0.9f, 1.0f); - snd_set_channel(SOUNDS::CHN_GLOBAL, 1.0f, 0.0f); + Sound()->SetChannel(CSounds::CHN_GUI, 1.0f, 0.0f); + Sound()->SetChannel(CSounds::CHN_MUSIC, 1.0f, 0.0f); + Sound()->SetChannel(CSounds::CHN_WORLD, 0.9f, 1.0f); + Sound()->SetChannel(CSounds::CHN_GLOBAL, 1.0f, 0.0f); - snd_set_listener_pos(0.0f, 0.0f); + Sound()->SetListenerPos(0.0f, 0.0f); + + ClearQueue(); +} + +void CSounds::OnReset() +{ + Sound()->StopAll(); + ClearQueue(); } -void SOUNDS::on_render() +void CSounds::OnRender() { // set listner pos - snd_set_listener_pos(gameclient.camera->center.x, gameclient.camera->center.y); + Sound()->SetListenerPos(m_pClient->m_pCamera->m_Center.x, m_pClient->m_pCamera->m_Center.y); + + // play sound from queue + if(m_QueuePos > 0) + { + int64 Now = time_get(); + if(m_QueueWaitTime <= Now) + { + Play(CHN_GLOBAL, m_aQueue[0], 1.0f, vec2(0,0)); + m_QueueWaitTime = Now+time_freq()*3/10; // wait 300ms before playing the next one + if(--m_QueuePos > 0) + mem_move(m_aQueue, m_aQueue+1, m_QueuePos*sizeof(int)); + } + } } -void SOUNDS::play_and_record(int chn, int setid, float vol, vec2 pos) +void CSounds::ClearQueue() { - NETMSG_SV_SOUNDGLOBAL msg; - msg.soundid = setid; - msg.pack(MSGFLAG_NOSEND|MSGFLAG_RECORD); - client_send_msg(); + mem_zero(m_aQueue, sizeof(m_aQueue)); + m_QueuePos = 0; + m_QueueWaitTime = time_get(); +} + +void CSounds::Enqueue(int SetId) +{ + // add sound to the queue + if(m_QueuePos < QUEUE_SIZE) + m_aQueue[m_QueuePos++] = SetId; +} + +void CSounds::PlayAndRecord(int Chn, int SetId, float Vol, vec2 Pos) +{ + CNetMsg_Sv_SoundGlobal Msg; + Msg.m_Soundid = SetId; + Client()->SendPackMsg(&Msg, MSGFLAG_NOSEND|MSGFLAG_RECORD); - play(chn, setid, vol, pos); + Play(Chn, SetId, Vol, Pos); } -void SOUNDS::play(int chn, int setid, float vol, vec2 pos) +void CSounds::Play(int Chn, int SetId, float Vol, vec2 Pos) { - SOUNDSET *set = &data->sounds[setid]; + if(SetId < 0 || SetId >= g_pData->m_NumSounds) + return; + + SOUNDSET *pSet = &g_pData->m_aSounds[SetId]; - if(!set->num_sounds) + if(!pSet->m_NumSounds) return; - if(set->num_sounds == 1) + if(pSet->m_NumSounds == 1) { - snd_play_at(chn, set->sounds[0].id, 0, pos.x, pos.y); + Sound()->PlayAt(Chn, pSet->m_aSounds[0].m_Id, 0, Pos.x, Pos.y); return; } // play a random one int id; do { - id = rand() % set->num_sounds; - } while(id == set->last); - snd_play_at(chn, set->sounds[id].id, 0, pos.x, pos.y); - set->last = id; + id = rand() % pSet->m_NumSounds; + } while(id == pSet->m_Last); + Sound()->PlayAt(Chn, pSet->m_aSounds[id].m_Id, 0, Pos.x, Pos.y); + pSet->m_Last = id; } diff --git a/src/game/client/components/sounds.h b/src/game/client/components/sounds.h new file mode 100644 index 00000000..ce74b85e --- /dev/null +++ b/src/game/client/components/sounds.h @@ -0,0 +1,36 @@ +#ifndef GAME_CLIENT_COMPONENTS_SOUNDS_H +#define GAME_CLIENT_COMPONENTS_SOUNDS_H +#include <game/client/component.h> + +class CSounds : public CComponent +{ + enum + { + QUEUE_SIZE = 32, + }; + int m_aQueue[QUEUE_SIZE]; + int m_QueuePos; + int64 m_QueueWaitTime; + +public: + // sound channels + enum + { + CHN_GUI=0, + CHN_MUSIC, + CHN_WORLD, + CHN_GLOBAL, + }; + + virtual void OnInit(); + virtual void OnReset(); + virtual void OnRender(); + + void ClearQueue(); + void Enqueue(int SetId); + void Play(int Channel, int SetId, float Vol, vec2 Pos); + void PlayAndRecord(int Channel, int SetId, float Vol, vec2 Pos); +}; + + +#endif diff --git a/src/game/client/components/sounds.hpp b/src/game/client/components/sounds.hpp deleted file mode 100644 index 95ddb1ec..00000000 --- a/src/game/client/components/sounds.hpp +++ /dev/null @@ -1,22 +0,0 @@ -#include <game/client/component.hpp> - -class SOUNDS : public COMPONENT -{ -public: - // sound channels - enum - { - CHN_GUI=0, - CHN_MUSIC, - CHN_WORLD, - CHN_GLOBAL, - }; - - virtual void on_init(); - virtual void on_render(); - - void play(int chn, int setid, float vol, vec2 pos); - void play_and_record(int chn, int setid, float vol, vec2 pos); -}; - - diff --git a/src/game/client/components/voting.cpp b/src/game/client/components/voting.cpp index dcf5c954..17c0fe31 100644 --- a/src/game/client/components/voting.cpp +++ b/src/game/client/components/voting.cpp @@ -1,200 +1,219 @@ -#include <engine/e_client_interface.h> -#include <game/generated/g_protocol.hpp> -#include <base/vmath.hpp> -#include <game/client/render.hpp> -//#include <game/client/gameclient.hpp> -#include "voting.hpp" - -void VOTING::con_callvote(void *result, void *user_data) +#include <engine/shared/config.h> + +#include <game/generated/protocol.h> +#include <base/vmath.h> +#include <game/client/render.h> +//#include <game/client/gameclient.h> +#include "voting.h" + +void CVoting::ConCallvote(IConsole::IResult *pResult, void *pUserData) +{ + CVoting *pSelf = (CVoting*)pUserData; + pSelf->Callvote(pResult->GetString(0), pResult->GetString(1)); +} + +void CVoting::ConVote(IConsole::IResult *pResult, void *pUserData) +{ + CVoting *pSelf = (CVoting *)pUserData; + if(str_comp_nocase(pResult->GetString(0), "yes") == 0) + pSelf->Vote(1); + else if(str_comp_nocase(pResult->GetString(0), "no") == 0) + pSelf->Vote(-1); +} + +void CVoting::Callvote(const char *pType, const char *pValue) { - VOTING *self = (VOTING*)user_data; - self->callvote(console_arg_string(result, 0), console_arg_string(result, 1)); + CNetMsg_Cl_CallVote Msg = {0}; + Msg.m_Type = pType; + Msg.m_Value = pValue; + Client()->SendPackMsg(&Msg, MSGFLAG_VITAL); } -void VOTING::con_vote(void *result, void *user_data) +void CVoting::CallvoteKick(int ClientId) { - VOTING *self = (VOTING *)user_data; - if(str_comp_nocase(console_arg_string(result, 0), "yes") == 0) - self->vote(1); - else if(str_comp_nocase(console_arg_string(result, 0), "no") == 0) - self->vote(-1); + char Buf[32]; + str_format(Buf, sizeof(Buf), "%d", ClientId); + Callvote("kick", Buf); } -void VOTING::callvote(const char *type, const char *value) +void CVoting::CallvoteOption(int OptionId) { - NETMSG_CL_CALLVOTE msg = {0}; - msg.type = type; - msg.value = value; - msg.pack(MSGFLAG_VITAL); - client_send_msg(); + CVoteOption *pOption = m_pFirst; + while(pOption && OptionId >= 0) + { + if(OptionId == 0) + { + Callvote("option", pOption->m_aCommand); + break; + } + + OptionId--; + pOption = pOption->m_pNext; + } } -void VOTING::callvote_kick(int client_id) +void CVoting::ForcevoteKick(int ClientId) { - char buf[32]; - str_format(buf, sizeof(buf), "%d", client_id); - callvote("kick", buf); + char Buf[32]; + str_format(Buf, sizeof(Buf), "kick %d", ClientId); + Client()->Rcon(Buf); } -void VOTING::callvote_option(int option_id) +void CVoting::ForcevoteOption(int OptionId) { - VOTEOPTION *option = this->first; - while(option && option_id >= 0) + CVoteOption *pOption = m_pFirst; + while(pOption && OptionId >= 0) { - if(option_id == 0) + if(OptionId == 0) { - callvote("option", option->command); + Client()->Rcon(pOption->m_aCommand); break; } - option_id--; - option = option->next; + OptionId--; + pOption = pOption->m_pNext; } } -void VOTING::vote(int v) +void CVoting::Vote(int v) { - NETMSG_CL_VOTE msg = {v}; - msg.pack(MSGFLAG_VITAL); - client_send_msg(); + CNetMsg_Cl_Vote Msg = {v}; + Client()->SendPackMsg(&Msg, MSGFLAG_VITAL); } -VOTING::VOTING() +CVoting::CVoting() { - heap = 0; - clearoptions(); - on_reset(); + ClearOptions(); + OnReset(); } -void VOTING::clearoptions() +void CVoting::ClearOptions() { - if(heap) - memheap_destroy(heap); - heap = memheap_create(); + m_Heap.Reset(); - first = 0; - last = 0; + m_pFirst = 0; + m_pLast = 0; } -void VOTING::on_reset() +void CVoting::OnReset() { - closetime = 0; - description[0] = 0; - command[0] = 0; - yes = no = pass = total = 0; - voted = 0; + m_Closetime = 0; + m_aDescription[0] = 0; + m_aCommand[0] = 0; + m_Yes = m_No = m_Pass = m_Total = 0; + m_Voted = 0; } -void VOTING::on_console_init() +void CVoting::OnConsoleInit() { - MACRO_REGISTER_COMMAND("callvote", "sr", CFGFLAG_CLIENT, con_callvote, this, "Call vote"); - MACRO_REGISTER_COMMAND("vote", "r", CFGFLAG_CLIENT, con_vote, this, "Vote yes/no"); + Console()->Register("callvote", "sr", CFGFLAG_CLIENT, ConCallvote, this, "Call vote"); + Console()->Register("vote", "r", CFGFLAG_CLIENT, ConVote, this, "Vote yes/no"); } -void VOTING::on_message(int msgtype, void *rawmsg) +void CVoting::OnMessage(int MsgType, void *pRawMsg) { - if(msgtype == NETMSGTYPE_SV_VOTE_SET) + if(MsgType == NETMSGTYPE_SV_VOTESET) { - NETMSG_SV_VOTE_SET *msg = (NETMSG_SV_VOTE_SET *)rawmsg; - if(msg->timeout) + CNetMsg_Sv_VoteSet *pMsg = (CNetMsg_Sv_VoteSet *)pRawMsg; + if(pMsg->m_Timeout) { - on_reset(); - str_copy(description, msg->description, sizeof(description)); - str_copy(command, msg->command, sizeof(description)); - closetime = time_get() + time_freq() * msg->timeout; + OnReset(); + str_copy(m_aDescription, pMsg->m_pDescription, sizeof(m_aDescription)); + str_copy(m_aCommand, pMsg->m_pCommand, sizeof(m_aCommand)); + m_Closetime = time_get() + time_freq() * pMsg->m_Timeout; } else - on_reset(); + OnReset(); } - else if(msgtype == NETMSGTYPE_SV_VOTE_STATUS) + else if(MsgType == NETMSGTYPE_SV_VOTESTATUS) { - NETMSG_SV_VOTE_STATUS *msg = (NETMSG_SV_VOTE_STATUS *)rawmsg; - yes = msg->yes; - no = msg->no; - pass = msg->pass; - total = msg->total; + CNetMsg_Sv_VoteStatus *pMsg = (CNetMsg_Sv_VoteStatus *)pRawMsg; + m_Yes = pMsg->m_Yes; + m_No = pMsg->m_No; + m_Pass = pMsg->m_Pass; + m_Total = pMsg->m_Total; } - else if(msgtype == NETMSGTYPE_SV_VOTE_CLEAROPTIONS) + else if(MsgType == NETMSGTYPE_SV_VOTECLEAROPTIONS) { - clearoptions(); + ClearOptions(); } - else if(msgtype == NETMSGTYPE_SV_VOTE_OPTION) + else if(MsgType == NETMSGTYPE_SV_VOTEOPTION) { - NETMSG_SV_VOTE_OPTION *msg = (NETMSG_SV_VOTE_OPTION *)rawmsg; - int len = str_length(msg->command); + CNetMsg_Sv_VoteOption *pMsg = (CNetMsg_Sv_VoteOption *)pRawMsg; + int Len = str_length(pMsg->m_pCommand); - VOTEOPTION *option = (VOTEOPTION *)memheap_allocate(heap, sizeof(VOTEOPTION) + len); - option->next = 0; - option->prev = last; - if(option->prev) - option->prev->next = option; - last = option; - if(!first) - first = option; + CVoteOption *pOption = (CVoteOption *)m_Heap.Allocate(sizeof(CVoteOption) + Len); + pOption->m_pNext = 0; + pOption->m_pPrev = m_pLast; + if(pOption->m_pPrev) + pOption->m_pPrev->m_pNext = pOption; + m_pLast = pOption; + if(!m_pFirst) + m_pFirst = pOption; - mem_copy(option->command, msg->command, len+1); + mem_copy(pOption->m_aCommand, pMsg->m_pCommand, Len+1); } } -void VOTING::on_render() +void CVoting::OnRender() { } -void VOTING::render_bars(CUIRect bars, bool text) +void CVoting::RenderBars(CUIRect Bars, bool Text) { - RenderTools()->DrawUIRect(&bars, vec4(0.8f,0.8f,0.8f,0.5f), CUI::CORNER_ALL, bars.h/3); + RenderTools()->DrawUIRect(&Bars, vec4(0.8f,0.8f,0.8f,0.5f), CUI::CORNER_ALL, Bars.h/3); - CUIRect splitter = bars; - splitter.x = splitter.x+splitter.w/2; - splitter.w = splitter.h/2.0f; - splitter.x -= splitter.w/2; - RenderTools()->DrawUIRect(&splitter, vec4(0.4f,0.4f,0.4f,0.5f), CUI::CORNER_ALL, splitter.h/4); + CUIRect Splitter = Bars; + Splitter.x = Splitter.x+Splitter.w/2; + Splitter.w = Splitter.h/2.0f; + Splitter.x -= Splitter.w/2; + RenderTools()->DrawUIRect(&Splitter, vec4(0.4f,0.4f,0.4f,0.5f), CUI::CORNER_ALL, Splitter.h/4); - if(total) + if(m_Total) { - CUIRect pass_area = bars; - if(yes) + CUIRect PassArea = Bars; + if(m_Yes) { - CUIRect yes_area = bars; - yes_area.w *= yes/(float)total; - RenderTools()->DrawUIRect(&yes_area, vec4(0.2f,0.9f,0.2f,0.85f), CUI::CORNER_ALL, bars.h/3); + CUIRect YesArea = Bars; + YesArea.w *= m_Yes/(float)m_Total; + RenderTools()->DrawUIRect(&YesArea, vec4(0.2f,0.9f,0.2f,0.85f), CUI::CORNER_ALL, Bars.h/3); - if(text) + if(Text) { - char buf[256]; - str_format(buf, sizeof(buf), "%d", yes); - UI()->DoLabel(&yes_area, buf, bars.h*0.75f, 0); + char Buf[256]; + str_format(Buf, sizeof(Buf), "%d", m_Yes); + UI()->DoLabel(&YesArea, Buf, Bars.h*0.75f, 0); } - pass_area.x += yes_area.w; - pass_area.w -= yes_area.w; + PassArea.x += YesArea.w; + PassArea.w -= YesArea.w; } - if(no) + if(m_No) { - CUIRect no_area = bars; - no_area.w *= no/(float)total; - no_area.x = (bars.x + bars.w)-no_area.w; - RenderTools()->DrawUIRect(&no_area, vec4(0.9f,0.2f,0.2f,0.85f), CUI::CORNER_ALL, bars.h/3); + CUIRect NoArea = Bars; + NoArea.w *= m_No/(float)m_Total; + NoArea.x = (Bars.x + Bars.w)-NoArea.w; + RenderTools()->DrawUIRect(&NoArea, vec4(0.9f,0.2f,0.2f,0.85f), CUI::CORNER_ALL, Bars.h/3); - if(text) + if(Text) { - char buf[256]; - str_format(buf, sizeof(buf), "%d", no); - UI()->DoLabel(&no_area, buf, bars.h*0.75f, 0); + char Buf[256]; + str_format(Buf, sizeof(Buf), "%d", m_No); + UI()->DoLabel(&NoArea, Buf, Bars.h*0.75f, 0); } - pass_area.w -= no_area.w; + PassArea.w -= NoArea.w; } - if(text && pass) + if(Text && m_Pass) { - char buf[256]; - str_format(buf, sizeof(buf), "%d", pass); - UI()->DoLabel(&pass_area, buf, bars.h*0.75f, 0); + char Buf[256]; + str_format(Buf, sizeof(Buf), "%d", m_Pass); + UI()->DoLabel(&PassArea, Buf, Bars.h*0.75f, 0); } } } diff --git a/src/game/client/components/voting.h b/src/game/client/components/voting.h new file mode 100644 index 00000000..1f5d2fc5 --- /dev/null +++ b/src/game/client/components/voting.h @@ -0,0 +1,58 @@ +#ifndef GAME_CLIENT_COMPONENTS_VOTING_H +#define GAME_CLIENT_COMPONENTS_VOTING_H +#include <game/client/component.h> +#include <game/client/ui.h> +#include <engine/shared/memheap.h> + +class CVoting : public CComponent +{ + CHeap m_Heap; + + static void ConCallvote(IConsole::IResult *pResult, void *pUserData); + static void ConVote(IConsole::IResult *pResult, void *pUserData); + + int64 m_Closetime; + char m_aDescription[512]; + char m_aCommand[512]; + int m_Voted; + + void ClearOptions(); + void Callvote(const char *pType, const char *pValue); + +public: + + struct CVoteOption + { + CVoteOption *m_pNext; + CVoteOption *m_pPrev; + char m_aCommand[1]; + }; + + CVoteOption *m_pFirst; + CVoteOption *m_pLast; + + CVoting(); + virtual void OnReset(); + virtual void OnConsoleInit(); + virtual void OnMessage(int Msgtype, void *pRawMsg); + virtual void OnRender(); + + void RenderBars(CUIRect Bars, bool Text); + + void CallvoteKick(int ClientId); + void CallvoteOption(int Option); + void ForcevoteKick(int ClientId); + void ForcevoteOption(int Option); + + void Vote(int v); // -1 = no, 1 = yes + + int SecondsLeft() { return (m_Closetime - time_get())/time_freq(); } + bool IsVoting() { return m_Closetime != 0; } + int TakenChoice() const { return m_Voted; } + const char *VoteDescription() const { return m_aDescription; } + const char *VoteCommand() const { return m_aCommand; } + + int m_Yes, m_No, m_Pass, m_Total; +}; + +#endif diff --git a/src/game/client/components/voting.hpp b/src/game/client/components/voting.hpp deleted file mode 100644 index e04e1840..00000000 --- a/src/game/client/components/voting.hpp +++ /dev/null @@ -1,52 +0,0 @@ -#include <game/client/component.hpp> -#include <game/client/ui.hpp> -#include <engine/e_memheap.h> - -class VOTING : public COMPONENT -{ - HEAP *heap; - - static void con_callvote(void *result, void *user_data); - static void con_vote(void *result, void *user_data); - - int64 closetime; - char description[512]; - char command[512]; - int voted; - - void clearoptions(); - void callvote(const char *type, const char *value); - -public: - - struct VOTEOPTION - { - VOTEOPTION *next; - VOTEOPTION *prev; - char command[1]; - }; - VOTEOPTION *first; - VOTEOPTION *last; - - VOTING(); - virtual void on_reset(); - virtual void on_console_init(); - virtual void on_message(int msgtype, void *rawmsg); - virtual void on_render(); - - void render_bars(CUIRect bars, bool text); - - void callvote_kick(int client_id); - void callvote_option(int option); - - void vote(int v); // -1 = no, 1 = yes - - int seconds_left() { return (closetime - time_get())/time_freq(); } - bool is_voting() { return closetime != 0; } - int taken_choice() const { return voted; } - const char *vote_description() const { return description; } - const char *vote_command() const { return command; } - - int yes, no, pass, total; -}; - |