home *** CD-ROM | disk | FTP | other *** search
/ Enter 2005 March / ENTER.ISO / files / fwp-0.0.6-win32-installer.exe / Hud.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2005-01-22  |  46.0 KB  |  1,546 lines

  1. #include "Hud.h"
  2.  
  3. #include "log.h"
  4. #include "Tokenizer.h"
  5. #include "Game.h"
  6. #include "TextureHandler.h"
  7. #include "FontHandler.h"
  8.  
  9. #include "LoadingMenu.h"
  10. #include "GuiInfo.h"
  11. #include "Gui.h"
  12. #include "Display.h"
  13. #include "Renderer.h"
  14. #include "RendererInfo.h"
  15. #include "Network.h"
  16.  
  17. #ifndef WIN32
  18. #include <stdarg.h>    // fr linux va_kram
  19. #define _vsnprintf vsnprintf
  20. #endif
  21.  
  22.  
  23. Hud::Hud(){
  24.     //font=FontHandler::getFont("gui/fonts/courier_small_bold.font");
  25.     font = FontHandler::getFont("gui/fonts/scifi_small.font");
  26.     messagebox = new HudMessagebox();
  27.     centerOfScreenMessages = new HudCenterOfScreenMessages();
  28.     chatPrompt = new HudChatPrompt();
  29.     crosshair = new HudCrosshair();
  30.     statusbar = new HudStatusbar();
  31.     debugInfo = new HudDebugInfo();
  32.     scoreboard = new HudScoreboard();
  33.     takeDamageIndicator = new HudTakeDamageIndicator();
  34.  
  35.     teamMarkerShader = new Shader("gui/hud/team_marker.shader");
  36.     hudReferenceTexture = TextureHandler::getTexture("gui/hud/hud_reference.jpg");
  37. }
  38.  
  39. Hud::~Hud(){
  40.     delete debugInfo;
  41.     delete messagebox;
  42.     delete centerOfScreenMessages;
  43.     delete chatPrompt;
  44.     delete crosshair;
  45.     delete statusbar;
  46.     delete scoreboard;
  47.  
  48.     if(font!=NULL)
  49.         FontHandler::releaseFont(font);
  50.  
  51.     delete teamMarkerShader;
  52.     TextureHandler::releaseTexture(hudReferenceTexture);
  53. }
  54.  
  55.  
  56. void Hud::draw(){
  57.  
  58. //    if( Gui::info.var.hud_markTeamMembers ){    // jetzt in Renderer::renderScene!
  59. //        renderTeamMarkers();
  60. //    }
  61.  
  62.     Renderer::beginDrawing();
  63.  
  64.     if( Gui::info.var.hud_drawTakeDamageIndicator ){
  65.         takeDamageIndicator->draw();
  66.     }
  67.  
  68.     if( Gui::info.var.hud_drawMessagebox )
  69.         messagebox->draw();
  70.  
  71.     if( Gui::info.var.hud_drawCrosshair )
  72.         crosshair->draw();
  73.  
  74.     if( Gui::info.var.hud_drawStatusbar )
  75.         statusbar->draw();
  76.  
  77.     if( Gui::info.var.hud_drawCenterOfScreenMessages )
  78.         centerOfScreenMessages->draw();
  79.  
  80.     if( Gui::info.var.hud_drawMiniscoreboard && Network::client->ci.team != GAME_TEAM_SPECTATORS )
  81.         scoreboard->drawMiniscoreboard();
  82.  
  83.     if( Gui::info.var.hud_identifyTarget )
  84.         drawTarget();
  85.  
  86.     if( Gui::info.var.hud_drawScoreboard )
  87.         scoreboard->draw();
  88.  
  89.     if( Gui::info.var.hud_drawFPS )
  90.         drawFPS();
  91.  
  92.     if( Gui::info.var.hud_drawPing )
  93.         drawPing();
  94.  
  95.     if( Gui::info.var.hud_drawDebugInfo )
  96.         debugInfo->draw();
  97.  
  98.     if( chatPrompt->isActive )
  99.         chatPrompt->draw();
  100.  
  101.     if( Gui::info.var.hud_drawHelp )
  102.         drawHelp();
  103.  
  104.     Renderer::endDrawing();
  105. }
  106.  
  107.  
  108. void Hud::drawFPS(){
  109.     glColor4fv(Gui::info.var.hud_activeColor);
  110.     drawAlignedFormatString(790, 570, font, TEXT_ALIGN_RIGHT, "fps: %.1f", Renderer::info.var.fps);
  111. }
  112.  
  113.  
  114. void Hud::drawPing(){
  115.     glColor4fv(Gui::info.var.hud_activeColor);
  116. //    if(SDL_GetTicks() - Network::client->lastPingMillis > (unsigned long)Network::info.var.server_pingInterval){    // connection interrupted
  117. //        glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
  118. //        drawAlignedString(790, 540, font, TEXT_ALIGN_RIGHT, "<connection interrupted>");
  119. //    }else{
  120.         drawAlignedFormatString(790, 540, font, TEXT_ALIGN_RIGHT, "ping: %i", Network::client->ci.ping);
  121. //    }
  122. }
  123.  
  124. void Hud::drawTarget(){
  125. //    if( Game::cam.mode == CAMERA_MODE_THIRD_PERSON )
  126. //        return;
  127.  
  128.     unsigned int i;
  129.     trace_t trace;
  130.     trace.ignoreFlags = 0 | COLLISION_FLAG_BACKFACES | COLLISION_FLAG_SHOOT_THROUGH;
  131.  
  132.     traceRay(Game::cam.pos, Game::cam.dir, &trace);
  133.  
  134.     Vehicle* target = NULL;
  135.     for(i=0;i<trace.hits.size();i++){
  136.         if( trace.hits[i].face != NULL ){    // hit a face of the arena
  137.             
  138.             break;
  139.         }
  140.         if( trace.hits[i].vehicle != NULL ){    // hit a vehicle
  141.             if( trace.hits[i].vehicle == Game::cam.target && Game::cam.mode != CAMERA_MODE_FREE )
  142.                 continue;
  143.             
  144.             target = trace.hits[i].vehicle;
  145.             break;
  146.         }
  147.     }
  148.  
  149.     if( target == NULL )    // no target
  150.         return;
  151.  
  152.     texFont_t* font = Gui::hud->font;
  153.     if( Game::info.var.mode == GAME_MODE_TEAM_DEATHMATCH ){
  154.         if( target->client->ci.team == GAME_TEAM_RED ){
  155.             glColor3f(1.0f, 0.0f, 0.0f);
  156.         }else{
  157.             glColor3f(0.0f, 0.0f, 1.0f);
  158.         }
  159.     }else{
  160.         glColor4fv(Gui::info.var.hud_activeColor);
  161.     }
  162.  
  163.     int y = 330;
  164.     if( Gui::info.var.hud_identifyTarget == 2 )    // bottom
  165.         y = 80;
  166.  
  167.  
  168.     if( Game::cam.target == NULL || Game::cam.mode == CAMERA_MODE_FREE
  169.         || (Game::info.var.mode == GAME_MODE_TEAM_DEATHMATCH && Game::cam.target != NULL && Game::cam.target->client->ci.team == target->client->ci.team)
  170.         ){        // with health
  171.         drawAlignedFormatString(400, y, font, TEXT_ALIGN_CENTER, "%s (%i)", target->client->ci.name, (int)( target->armor ) );
  172.     }else{        // no health
  173.         drawAlignedString(400, y, font, TEXT_ALIGN_CENTER, target->client->ci.name);
  174.     }
  175.  
  176. }
  177.  
  178. void Hud::drawHelp(){
  179.     texFont_t* font = Gui::info.var.menu_smallFont;
  180.     float fontScale = 0.9f;
  181.  
  182.     Renderer::drawQuad(50, 80, 750, 520, Gui::info.var.hud_activeColor, Gui::info.var.hud_backgroundColor);
  183.  
  184.     glColor4fv(Gui::info.var.hud_activeColor);
  185.     drawScaledAndAlignedString(400, 490, 1.1f, 1.1f, font, TEXT_ALIGN_CENTER, "[ QUICK REFERENCE (F1) ]");
  186.  
  187.     int y = 460;
  188.     drawScaledAndAlignedString(70, y, 1.1f, 1.1f, font, TEXT_ALIGN_LEFT, "VEHICLE CONTROLS:");
  189.     y-=25;
  190.     drawScaledAndAlignedString(70, y, fontScale, fontScale, font, TEXT_ALIGN_LEFT, "mouse/cursor-keys - look");
  191.     y-=20;
  192.     drawScaledAndAlignedString(70, y, fontScale, fontScale, font, TEXT_ALIGN_LEFT, "w - forward");
  193.     y-=20;
  194.     drawScaledAndAlignedString(70, y, fontScale, fontScale, font, TEXT_ALIGN_LEFT, "s - backwards");
  195.     y-=20;
  196.     drawScaledAndAlignedString(70, y, fontScale, fontScale, font, TEXT_ALIGN_LEFT, "a - left");
  197.     y-=20;
  198.     drawScaledAndAlignedString(70, y, fontScale, fontScale, font, TEXT_ALIGN_LEFT, "d - right");
  199.     y-=20;
  200.     drawScaledAndAlignedString(70, y, fontScale, fontScale, font, TEXT_ALIGN_LEFT, "space - up/jumpjets");
  201.     y-=20;
  202.     drawScaledAndAlignedString(70, y, fontScale, fontScale, font, TEXT_ALIGN_LEFT, "left ctrl - down");
  203.     y-=20;
  204.     drawScaledAndAlignedString(70, y, fontScale, fontScale, font, TEXT_ALIGN_LEFT, "left mouse - fire weapon 1");
  205.     y-=20;
  206.     drawScaledAndAlignedString(70, y, fontScale, fontScale, font, TEXT_ALIGN_LEFT, "right mouse - fire weapon 2");
  207.     y-=30;
  208.     
  209.     drawScaledAndAlignedString(70, y, 1.1f, 1.1f, font, TEXT_ALIGN_LEFT, "CAMERA CONTROLS:");
  210.     y-=25;
  211.     drawScaledAndAlignedString(70, y, fontScale, fontScale, font, TEXT_ALIGN_LEFT, "kp_enter - toggle camera mode");
  212.     y-=20;
  213.     drawScaledAndAlignedString(70, y, fontScale, fontScale, font, TEXT_ALIGN_LEFT, "kp_ins - reset camera");
  214.     y-=20;
  215.     drawScaledAndAlignedString(70, y, fontScale, fontScale, font, TEXT_ALIGN_LEFT, "kp_arrows - rotate camera");
  216.     y-=20;
  217.     drawScaledAndAlignedString(70, y, fontScale, fontScale, font, TEXT_ALIGN_LEFT, "kp_plus - zoom in");
  218.     y-=20;
  219.     drawScaledAndAlignedString(70, y, fontScale, fontScale, font, TEXT_ALIGN_LEFT, "kp_minus - zoom out");
  220.     y-=20;
  221.     drawScaledAndAlignedString(70, y, fontScale, fontScale, font, TEXT_ALIGN_LEFT, "kp_multiply - chase next");
  222.     y-=20;
  223.     drawScaledAndAlignedString(70, y, fontScale, fontScale, font, TEXT_ALIGN_LEFT, "kp_divide - chase previous");
  224.  
  225.     y = 460;
  226.     drawScaledAndAlignedString(420, y, 1.1f, 1.1f, font, TEXT_ALIGN_LEFT, "MISC CONTROLS:");
  227.     y-=25;
  228.     drawScaledAndAlignedString(420, y, fontScale, fontScale, font, TEXT_ALIGN_LEFT, "tab - toggle scoreboard");
  229.     y-=20;
  230.     drawScaledAndAlignedString(420, y, fontScale, fontScale, font, TEXT_ALIGN_LEFT, "y - message to all");
  231.     y-=20;
  232.     drawScaledAndAlignedString(420, y, fontScale, fontScale, font, TEXT_ALIGN_LEFT, "t - message to team");
  233.     y-=20;
  234.     drawScaledAndAlignedString(420, y, fontScale, fontScale, font, TEXT_ALIGN_LEFT, "k - kill yourself");
  235.     y-=20;
  236.     drawScaledAndAlignedString(420, y, fontScale, fontScale, font, TEXT_ALIGN_LEFT, "esc - toggle in game menu");
  237.     y-=20;
  238.     drawScaledAndAlignedString(420, y, fontScale, fontScale, font, TEXT_ALIGN_LEFT, "~ - toggle console");
  239.     y-=30;
  240.  
  241.     drawScaledAndAlignedString(420, y, 1.1f, 1.1f, font, TEXT_ALIGN_LEFT, "HUD:");
  242.  
  243.     glColor3f(1.0f, 1.0f, 1.0f);
  244.     Renderer::drawTexturedQuad(420, 100, 730, 300, hudReferenceTexture);
  245. }
  246.  
  247.  
  248. void Hud::renderTeamMarkers(){
  249.     for(int i=0;i<GAME_MAX_VEHICLES;i++){
  250.         if( Game::vehicles[i] != NULL && Game::info.var.mode == GAME_MODE_TEAM_DEATHMATCH 
  251.             && Game::vehicles[i]->client->ci.team == Network::client->ci.team
  252.             ){
  253.  
  254.             vec3_t p;
  255.             vectorMA3d(Game::vehicles[i]->pos, 1.5f, Game::cam.up, p);
  256.             if( Renderer::info.var.useTransparentPolysList ){
  257.                 Renderer::addBillboardToTransparentPolys(p, 1.0f, 1.0f, teamMarkerShader, SDL_GetTicks());
  258.             }else{
  259.                 Renderer::renderBillboard(p, 1.0f, 1.0f, teamMarkerShader, SDL_GetTicks());
  260.             }
  261.         }
  262.     }
  263. }
  264.  
  265. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  266. //
  267. // MESSAGE BOX
  268. //
  269. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  270.  
  271.  
  272. Message::Message(const char* string){
  273.     this->string=newString(string);
  274.     spawntime=SDL_GetTicks();
  275. }
  276.  
  277. Message::~Message(){
  278.     delete[] string;
  279. }
  280.  
  281.  
  282. HudMessagebox::HudMessagebox(){
  283.     for(int i=0;i<HUD_MESSAGE_BOX_MAX_MESSAGES;i++){
  284.         messages[i]=NULL;
  285.     }
  286.  
  287.     font=FontHandler::getFont("gui/fonts/eurasia_medium_normal_border.font");
  288.  
  289.     chatMessageSound = Sound::loadWAV("gui/hud/chat_beep.wav");
  290.  
  291. //    visible=true;
  292. }
  293.  
  294. HudMessagebox::~HudMessagebox(){
  295.     if(font!=NULL)
  296.         FontHandler::releaseFont(font);
  297.  
  298.     for(int i=0;i<HUD_MESSAGE_BOX_MAX_MESSAGES;i++){
  299.         if(messages[i]!=NULL)
  300.             delete messages[i];
  301.     }
  302.  
  303.     Mix_FreeChunk(chatMessageSound);
  304. }
  305.  
  306. void HudMessagebox::addMessage(Message* message){
  307.     if(messages[HUD_MESSAGE_BOX_MAX_MESSAGES-1]!=NULL){
  308.         delete messages[HUD_MESSAGE_BOX_MAX_MESSAGES-1];
  309.     }
  310.     for(int i=HUD_MESSAGE_BOX_MAX_MESSAGES-1;i>0;i--){
  311.         messages[i]=messages[i-1];
  312.     }
  313.     messages[0]=message;
  314. }
  315.  
  316. void HudMessagebox::deleteMessage(Message* message){
  317.     if(message==NULL)
  318.         return;
  319.  
  320.     for(int i=0;i<HUD_MESSAGE_BOX_MAX_MESSAGES;i++){
  321.         if(messages[i]==message){
  322.             delete messages[i];
  323.             for(int j=i;j<HUD_MESSAGE_BOX_MAX_MESSAGES-1;j++){
  324.                 messages[j]=messages[j+1];
  325.  
  326.             }
  327.             messages[HUD_MESSAGE_BOX_MAX_MESSAGES-1]=NULL;
  328.         }
  329.     }
  330. }
  331.  
  332. void HudMessagebox::addChatMessage(Client* fromClient, chatMessagePacket_t* cm){
  333.     if( fromClient == NULL ){    // message from server
  334.         log("^7%s: %s\n", "<server>", cm->message);
  335.     }else{
  336.         if( cm->mode == GAME_CHAT_MODE_TEAM ){
  337.             log("^6[%s]: %s\n", fromClient->ci.name, cm->message);
  338.         }else{
  339.             log("^3%s: %s\n", fromClient->ci.name, cm->message);
  340.         }
  341.     }
  342.  
  343.     if(Sound::info.var.enabled && Sound::info.var.playSamples)
  344.         Sound::playSample(SOUND_COMPUTER_CHANNEL, chatMessageSound);
  345. }
  346.  
  347. void HudMessagebox::draw(){
  348.     int i;
  349.     int x = 10;
  350.     int y = DISPLAY_VSCREEN_HEIGHT;
  351.  
  352.     float scale = 0.7f;
  353.  
  354.     for(i = Gui::info.var.hud_messagebox_numLines-1; i >= 0; i--){
  355.         if(messages[i] != NULL){
  356.             glColor4fv(Gui::info.var.hud_activeColor);
  357.             y = (int)( y-(font->height+1)*scale );
  358.             drawScaledAndAlignedString(x, y, scale, scale, font, TEXT_ALIGN_LEFT, messages[i]->string);
  359.         }
  360.     }
  361.  
  362.     unsigned int currentTime = SDL_GetTicks();
  363.     for(i = 0; i < HUD_MESSAGE_BOX_MAX_MESSAGES; i++){
  364.         if(messages[i] != NULL && (currentTime - messages[i]->spawntime > (unsigned int)Gui::info.var.hud_messagebox_messageLifetime) ){
  365.  
  366.             delete messages[i];
  367.             for(int j=i;j<HUD_MESSAGE_BOX_MAX_MESSAGES-1;j++){
  368.                 messages[j]=messages[j+1];
  369.             }
  370.             messages[HUD_MESSAGE_BOX_MAX_MESSAGES-1]=NULL;
  371.         }
  372.     }
  373. }
  374.  
  375.  
  376. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  377. //
  378. // CENTER OF SCREEN MESSAGES
  379. //
  380. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  381.  
  382. HudCenterOfScreenMessages::HudCenterOfScreenMessages(){
  383.     message = NULL;
  384.     lastMessageMillis = 0;
  385. }
  386.  
  387. HudCenterOfScreenMessages::~HudCenterOfScreenMessages(){
  388.     if( message != NULL )
  389.         delete[] message;
  390. }
  391.  
  392.  
  393. void HudCenterOfScreenMessages::setMessage(const char* formatString, ...){
  394.     if( message != NULL )
  395.         delete[] message;
  396.  
  397.     va_list ap;
  398.     char toStringBuffer[512];
  399.  
  400.     va_start (ap, formatString);
  401.     _vsnprintf(toStringBuffer, 511, formatString, ap);
  402.     va_end(ap);
  403.     toStringBuffer[511]='\0';
  404.     
  405.     this->message = newString(toStringBuffer);
  406.     this->lastMessageMillis = SDL_GetTicks();
  407. }
  408.  
  409. void HudCenterOfScreenMessages::draw(){
  410.     texFont_t* font = Gui::hud->font;
  411.  
  412.     if( message != NULL ){
  413.         unsigned long currentMillis = SDL_GetTicks();
  414.  
  415.         if( currentMillis > lastMessageMillis + Gui::info.var.hud_messagebox_messageLifetime ){
  416.             delete message;
  417.             message = NULL;
  418.         }else{
  419.             vec4_t col;
  420.             vectorCopy4d(Gui::info.var.hud_activeColor, col);
  421.  
  422.             col[3] = 1.0f;
  423.             float q = (currentMillis - lastMessageMillis)/(float)Gui::info.var.hud_messagebox_messageLifetime;
  424.             if( q > 0.75f ) {
  425.                 col[3] = -4.0f*q + 4.0f;
  426.             }
  427.  
  428.             glColor4fv(col);
  429.             drawScaledAndAlignedString(400, 350, 0.8f, 0.8f, Gui::info.var.menu_bigFont, TEXT_ALIGN_CENTER, message);
  430.         }
  431.     }
  432.  
  433.     // camera related stuff
  434.     glColor4fv(Gui::info.var.hud_activeColor);
  435.     if( Game::cam.target != NULL && Game::cam.target != Network::client->vehicle ){
  436.         if( Game::cam.mode == CAMERA_MODE_FIRST_PERSON ){
  437.             drawAlignedFormatString(400, 250, font, TEXT_ALIGN_CENTER, "chasing %s - first person view", Game::cam.target->client->ci.name);
  438.         }else if( Game::cam.mode == CAMERA_MODE_THIRD_PERSON ){
  439.             drawAlignedFormatString(400, 250, font, TEXT_ALIGN_CENTER, "chasing %s - third person view", Game::cam.target->client->ci.name);
  440.         }else if( Game::cam.mode == CAMERA_MODE_FREE ){
  441. //            drawAlignedFormatString(400, 250, font, TEXT_ALIGN_CENTER, "chasing %s - free camera", Game::cam.target->client->ci.name);
  442.             drawAlignedString(400, 250, font, TEXT_ALIGN_CENTER, "free camera");
  443.         }
  444.     }else{
  445.         if( Game::cam.mode == CAMERA_MODE_FREE || Game::cam.target == NULL ){
  446.             drawAlignedString(400, 250, font, TEXT_ALIGN_CENTER, "free camera");
  447.         }else if( Game::cam.mode == CAMERA_MODE_THIRD_PERSON ){
  448.             drawAlignedString(400, 250, font, TEXT_ALIGN_CENTER, "third person view");
  449.         }
  450.     }
  451.  
  452.     // team related stuff
  453.     if( Game::info.var.player_team != Game::info.cvar.game_player_team->getVal() && Network::client->vehicle == NULL ){    // waiting for team change
  454.             drawAlignedFormatString(400, 200, font, TEXT_ALIGN_CENTER, "you will change teams in %i seconds.", (int)( (Network::client->nextSpawnMillis - SDL_GetTicks()) / 1000 + 1) );
  455.     }else{
  456.         if( Game::info.var.player_team == GAME_TEAM_SPECTATORS ){    // spectating
  457.             drawAlignedFormatString(400, 200, font, TEXT_ALIGN_CENTER, "you are spectating - use the equipment menu to join the game.");
  458.         }else{
  459.             if( Network::client->vehicle == NULL ){    // dead
  460.                 drawAlignedFormatString(400, 200, font, TEXT_ALIGN_CENTER, "you will respawn in %i seconds.", (int)( (Network::client->nextSpawnMillis - SDL_GetTicks()) / 1000 + 1 ) );
  461.             }
  462.         }
  463.     }
  464. }
  465.  
  466.  
  467.  
  468.  
  469. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  470. //
  471. // CHAT PROMPT
  472. //
  473. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  474.  
  475. HudChatPrompt::HudChatPrompt(){
  476.     isActive = false;
  477.     mode = -1;
  478.  
  479.     promptStr = NULL;
  480.     inputStr = NULL;
  481.     inputStrIndex = 0;
  482.  
  483.     font=FontHandler::getFont("gui/fonts/eurasia_medium_normal_border.font");
  484. }
  485.  
  486. HudChatPrompt::~HudChatPrompt(){
  487.     if(font!=NULL)
  488.         FontHandler::releaseFont(font);
  489.  
  490.     if(inputStr != NULL)
  491.         delete[] inputStr;
  492. }
  493.  
  494. void HudChatPrompt::activate(int mode){
  495.     this->mode = mode;
  496.  
  497.     SDL_EnableUNICODE(1);
  498.     SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
  499.  
  500.     inputStr = new char[CON_MAX_STRING_LENGTH];
  501.     inputStr[0] = '\0';
  502.     inputStrIndex = 0;
  503.  
  504.     if( mode == GAME_CHAT_MODE_TEAM ){
  505.         promptStr = "^6[team]: ";
  506.     }else{
  507.         promptStr = "^3[all]: ";
  508.     }
  509.  
  510.     isActive=true;
  511. }
  512.  
  513.  
  514. void HudChatPrompt::deactivate(){
  515.     SDL_EnableUNICODE(0);
  516.     SDL_EnableKeyRepeat(0, SDL_DEFAULT_REPEAT_INTERVAL);
  517.  
  518.     delete[] inputStr;
  519.     inputStr = NULL;
  520.  
  521.     mode = -1;
  522.  
  523.     isActive=false;
  524. }
  525.  
  526. void HudChatPrompt::receiveKey(SDL_keysym* keysym){
  527.     int i;
  528.     SDLKey key=keysym->sym;
  529.  
  530.     if(key==SDLK_ESCAPE){
  531.         deactivate();
  532.     }else if(key==SDLK_RIGHT){
  533.         if(inputStr[inputStrIndex]!='\0'){
  534.             inputStrIndex++;
  535.         }
  536.     }else if(key==SDLK_LEFT){
  537.         if(inputStrIndex>0){
  538.             inputStrIndex--;
  539.         }
  540.     }else if(key==SDLK_HOME){
  541.         inputStrIndex=0;
  542.     }else if(key==SDLK_END){
  543.         inputStrIndex=strlen(inputStr);
  544.     }else if(key==SDLK_RETURN){    // enter
  545.  
  546.         if( mode == GAME_CHAT_MODE_TEAM ){
  547.             Game::chatMessageTeam(inputStr);
  548.         }else{
  549.             Game::chatMessageAll(inputStr);
  550.         }
  551.  
  552.         deactivate();
  553.  
  554.     }else if(key==SDLK_BACKSPACE){    // backspace
  555.         if(inputStrIndex<=0)
  556.             return;
  557.  
  558.         i=inputStrIndex-1;
  559.         while(inputStr[i]!='\0'){
  560.             inputStr[i]=inputStr[i+1];
  561.             i++;
  562.         }
  563.         inputStrIndex-=1;
  564.     }else if(key==SDLK_DELETE){    // del
  565.         if(inputStr[inputStrIndex]=='\0')
  566.             return;
  567.  
  568.         i=inputStrIndex;
  569.         while(inputStr[i]!='\0'){
  570.             inputStr[i]=inputStr[i+1];
  571.             i++;
  572.         }
  573.     }else{        // add char to inputStr
  574.         int l=strlen(inputStr);
  575.         if(l < CON_MAX_STRING_LENGTH){
  576.             char ch;
  577.             if ( (keysym->unicode & 0xFF80) == 0 && keysym->unicode!=0) {
  578.                 ch = keysym->unicode & 0x7F;
  579.                 for(i=l+1;i>inputStrIndex;i--){
  580.                     inputStr[i]=inputStr[i-1];
  581.                 }
  582.  
  583.                 inputStr[inputStrIndex]=ch;
  584.                 inputStrIndex++;
  585.                 //inputStr[inputStrIndex+1]='\0';
  586.                 //inputStrIndex = inputStrIndex >= CON_MAX_LINE_LENGTH-1 ? CON_MAX_LINE_LENGTH-1 : inputStrIndex+1;
  587.             }else{
  588. //                warn("(in ConsoleFrontEnd::recieveKey()): unicode of key not known!\n\n");
  589.             }
  590.         }
  591.     }
  592.  
  593. }
  594.  
  595.  
  596.  
  597. void HudChatPrompt::draw(){
  598.     int x = 10;
  599.     int y = 80;
  600.     float scale = 0.8f;
  601.  
  602.     //glColor4fv(Gui::info.var.hud_activeColor);
  603. //    if( mode == GAME_CHAT_MODE_TEAM ){
  604. //    }else{
  605. //    }
  606.  
  607.     drawScaledFormatString(x, y, scale, scale,
  608.         font, "%s%s", promptStr, inputStr);
  609.  
  610.     if((SDL_GetTicks()/500)%2){
  611.         char buff[CON_MAX_STRING_LENGTH];
  612.         strncpy(buff, inputStr, inputStrIndex);
  613.         buff[inputStrIndex] = '\0';
  614.         float xOffs = (getStringWidth(font, promptStr)+getStringWidth(font, buff))*scale;
  615.         drawScaledString(x+(int)xOffs, y, scale, scale, font, "_");
  616.     }
  617. }
  618.  
  619. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  620. //
  621. // CROSSHAIR
  622. //
  623. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  624.  
  625.  
  626.  
  627. HudCrosshair::HudCrosshair(){
  628.     crosshairTextures[0] = TextureHandler::getTexture("gui/hud/crosshair_01.tga");
  629.     crosshairTextures[1] = TextureHandler::getTexture("gui/hud/crosshair_02.tga");
  630.     crosshairTextures[2] = TextureHandler::getTexture("gui/hud/crosshair_03.tga");
  631.     crosshairTextures[3] = TextureHandler::getTexture("gui/hud/crosshair_04.tga");
  632.     crosshairTextures[4] = TextureHandler::getTexture("gui/hud/crosshair_05.tga");
  633.     crosshairTextures[5] = TextureHandler::getTexture("gui/hud/crosshair_06.tga");
  634.     crosshairTextures[6] = TextureHandler::getTexture("gui/hud/crosshair_07.tga");
  635.     crosshairTextures[7] = TextureHandler::getTexture("gui/hud/crosshair_08.tga");
  636.  
  637. //    visible=true;
  638. }
  639.  
  640. HudCrosshair::~HudCrosshair(){
  641.     for(int i=0;i<8;i++){
  642.         if(crosshairTextures[i]){
  643.             TextureHandler::releaseTexture(crosshairTextures[i]);
  644.         }
  645.     }
  646. }
  647.  
  648. void HudCrosshair::draw(){
  649.     int size=30;
  650.  
  651.     glColor4fv(Gui::info.var.hud_activeColor);
  652.  
  653.     glEnable(GL_TEXTURE_2D);
  654.     glBindTexture(GL_TEXTURE_2D, crosshairTextures[Gui::info.var.hud_crosshair]->texName);
  655.     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  656.  
  657.     glBegin(GL_QUADS);
  658.     glTexCoord2f(0.0f, 0.0f); glVertex2f((400-size), (300-size));
  659.     glTexCoord2f(1.0f, 0.0f); glVertex2f((400+size), (300-size));
  660.     glTexCoord2f(1.0f, 1.0f); glVertex2f((400+size), (300+size));
  661.     glTexCoord2f(0.0f, 1.0f); glVertex2f((400-size), (300+size));
  662.     glEnd();
  663.  
  664.     glDisable(GL_TEXTURE_2D);
  665. }
  666.  
  667.  
  668.  
  669. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  670. //
  671. // STATUSBAR
  672. //
  673. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  674.  
  675. HudStatusbar::HudStatusbar(){
  676.  
  677.     min[0]=10;
  678.     max[0]=522;
  679.     min[1]=10;
  680.     max[1]=74;
  681.  
  682.     background = TextureHandler::getTexture("gui/hud/status_info_background.tga");
  683.     energyIcon = TextureHandler::getTexture("gui/hud/energy_icon.tga");
  684.     armorIcon = TextureHandler::getTexture("gui/hud/armor_icon.tga");
  685.  
  686.     weaponThumbnails[GAME_WEAPON_NO_WEAPON] = NULL;
  687.     weaponThumbnails[GAME_WEAPON_LASER] = TextureHandler::getTexture("weapons/laser/laser_thumbnail.tga");
  688.     weaponThumbnails[GAME_WEAPON_CHAINGUN] = TextureHandler::getTexture("weapons/chaingun/chaingun_thumbnail.tga");
  689.     weaponThumbnails[GAME_WEAPON_RAILGUN] = TextureHandler::getTexture("weapons/railgun/railgun_thumbnail.tga");
  690.     weaponThumbnails[GAME_WEAPON_ROCKETLAUNCHER] = TextureHandler::getTexture("weapons/rocketlauncher/rocketlauncher_thumbnail.tga");
  691.     weaponThumbnails[GAME_WEAPON_PLASMAGUN] = TextureHandler::getTexture("weapons/plasmagun/plasmagun_thumbnail.tga");
  692. }
  693.  
  694. HudStatusbar::~HudStatusbar(){
  695.     TextureHandler::releaseTexture(background);
  696.     TextureHandler::releaseTexture(energyIcon);
  697.     TextureHandler::releaseTexture(armorIcon);
  698.     
  699.     for(int i=0;i<GAME_NUM_WEAPONS;i++){
  700.         if( weaponThumbnails[i] != NULL )
  701.             TextureHandler::releaseTexture(weaponThumbnails[i]);
  702.     }
  703. }
  704.  
  705. void HudStatusbar::draw(){
  706.  
  707.     if( Game::cam.target == NULL || Game::cam.mode == CAMERA_MODE_FREE ){
  708.         return;
  709.     }
  710.  
  711.     Vehicle* v = Game::cam.target;
  712.  
  713.     // bars
  714.     float armorPercent = v->armor/(float)v->maxArmor;
  715.     float energyPercent = v->energy/(float)v->maxEnergy;
  716.  
  717.     vec4_t col;
  718.     vectorInit4d(1.0f, 0.0f, 0.0f, 0.5f, col);
  719.     Renderer::drawQuad(min[0]+35, min[1]+3, (int)( min[0]+35 + (217)*armorPercent ), min[1]+29, col, col);
  720.  
  721.     vectorInit4d(0.0f, 0.0f, 1.0f, 0.5f, col);
  722.     Renderer::drawQuad(min[0]+35, min[1]+36, (int)( min[0]+35 + (217)*energyPercent ), min[1]+62, col, col);
  723.  
  724.  
  725.     // weapons
  726.     int x = min[0] + 259;
  727.     int y = min[1] + 4;
  728.     for(int k=0;k<4;k++){
  729.         if( v->weapons[k] == NULL )
  730.             continue;
  731.  
  732.         float weaponEnergyPercent = 1.0f;
  733.         if( v->weapons[k]->maxEnergy > 0 ){    // bar is energy info
  734.             weaponEnergyPercent = v->weapons[k]->energy/(float)v->weapons[k]->maxEnergy;
  735.         }else if( v->weapons[k]->maxAmmo > 0 ){    // bar is ammo info
  736.             weaponEnergyPercent = v->weapons[k]->ammo/(float)v->weapons[k]->maxAmmo;
  737.         }
  738.         vec4_t col;
  739.         vectorInit4d(1.0f, 0.0f, 0.0f, 0.5f, col);
  740.         vectorLinCombi3d(weaponEnergyPercent, Gui::info.var.hud_activeColor, 1.0f-weaponEnergyPercent, col, col);
  741.         col[3] = 0.5f;
  742.         Renderer::drawQuad(x, y, x+57, (int)(y+57*weaponEnergyPercent), col, col);
  743.  
  744.         if( v->weapons[k]->isReadyToFire() ){
  745.             glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
  746.         }else{
  747.             glColor4f(0.5f, 0.5f, 0.5f, 1.0f);
  748.         }
  749.         Renderer::drawTexturedQuad(x, y, x+57, y+57, weaponThumbnails[v->weapons[k]->type]);
  750.  
  751.         if( v->weapons[k]->maxAmmo > 0 ){    // draw ammo info
  752.             if( v->weapons[k]->ammo > v->weapons[k]->maxAmmo*0.2f ){
  753.                 glColor4f(0.1f, 0.6f, 1.0f, 1.0f);
  754.             }else if( v->weapons[k]->ammo > v->weapons[k]->maxAmmo*0.1f ){
  755.                 glColor4f(1.0f, 0.8f, 0.1f, 1.0f);
  756.             }else{
  757.                 glColor4f(1.0f, 0.1f, 0.1f, 1.0f);
  758.             }
  759.             drawShadowedFormatString(x+53, y+2, 1.0f, 1, Gui::info.var.menu_tinyFont, TEXT_ALIGN_RIGHT, "%i", v->weapons[k]->ammo);
  760.         }
  761.  
  762.         x += 64;
  763.     }
  764.  
  765.     drawBackground();
  766. }
  767.  
  768. void HudStatusbar::drawBackground(){
  769.     glEnable(GL_TEXTURE_2D);
  770.     glBindTexture(GL_TEXTURE_2D, background->texName);
  771.     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  772.  
  773.     glColor4fv(Gui::info.var.hud_activeColor);
  774.     glBegin(GL_QUADS);
  775.         glTexCoord2f(0.0f, 0.0f); glVertex2f(min[0], min[1]);
  776.         glTexCoord2f(1.0f, 0.0f); glVertex2f(max[0], min[1]);
  777.         glTexCoord2f(1.0f, 1.0f); glVertex2f(max[0], max[1]);
  778.         glTexCoord2f(0.0f, 1.0f); glVertex2f(min[0], max[1]);
  779.     glEnd();
  780.     glDisable(GL_TEXTURE_2D);
  781.  
  782.     glColor3f(1.0f, 1.0f, 1.0f);
  783.     int x = min[0]+3;
  784.     int y = min[1]+4;
  785.     Renderer::drawTexturedQuad(x, y, x+24, y+24, armorIcon);
  786.     y+=32;
  787.     Renderer::drawTexturedQuad(x, y, x+24, y+24, energyIcon);
  788. }
  789.  
  790.  
  791.  
  792.  
  793. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  794. //
  795. // SCOREBOARD
  796. //
  797. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  798.  
  799. HudScoreboard::HudScoreboard(){
  800.     font=FontHandler::getFont("gui/fonts/courier_small_bold.font");
  801.  
  802. }
  803.  
  804. HudScoreboard::~HudScoreboard(){
  805.     if(font!=NULL)
  806.         FontHandler::releaseFont(font);
  807. }
  808.  
  809. void HudScoreboard::draw(){
  810.     drawBackground();
  811.     
  812.     if( Game::info.var.mode == GAME_MODE_DEATHMATCH ){
  813.         drawDeathmatchScoreboard();
  814.     }else if( Game::info.var.mode == GAME_MODE_TEAM_DEATHMATCH ){
  815.         drawTeamDeathmatchScoreboard();
  816.     }
  817.  
  818.  
  819. }
  820.  
  821. void HudScoreboard::drawMiniscoreboard(){
  822.     glColor4fv(Gui::info.var.hud_activeColor);
  823.     
  824.     if( Game::info.var.mode == GAME_MODE_DEATHMATCH ){
  825.         int highestScore = -99;
  826.         for(int i=0;i<Network::server->si.maxClients;i++){
  827.             if( Network::server->clients[i] != NULL && Network::server->clients[i]->ci.team != GAME_TEAM_SPECTATORS ){
  828.                 if( Network::server->clients[i]->ci.score > highestScore ){
  829.                     highestScore = Network::server->clients[i]->ci.score;
  830.                 }
  831.             }
  832.         }
  833.         drawAlignedFormatString(790, 30, Gui::hud->font, TEXT_ALIGN_RIGHT, "1st: %i", highestScore);
  834.         drawAlignedFormatString(790, 5, Gui::hud->font, TEXT_ALIGN_RIGHT, "you: %i", Network::client->ci.score);
  835.  
  836.     }else if( Game::info.var.mode == GAME_MODE_TEAM_DEATHMATCH ){
  837.         int redScore = 0;
  838.         int blueScore = 0;
  839.         for(int i=0;i<Network::server->si.maxClients;i++){
  840.             if( Network::server->clients[i] != NULL ){
  841.                 if( Network::server->clients[i]->ci.team == GAME_TEAM_RED ){
  842.                     redScore += Network::server->clients[i]->ci.score;
  843.                 }else if( Network::server->clients[i]->ci.team == GAME_TEAM_BLUE ){
  844.                     blueScore += Network::server->clients[i]->ci.score;
  845.                 }
  846.             }
  847.         }
  848.  
  849.         drawAlignedFormatString(790, 30, Gui::hud->font, TEXT_ALIGN_RIGHT, "red: %i", redScore);
  850.         drawAlignedFormatString(790, 5, Gui::hud->font, TEXT_ALIGN_RIGHT, "blue: %i", blueScore);
  851.     }
  852.  
  853. }
  854.  
  855. void HudScoreboard::drawBackground(){
  856.     //glColor4f(0.0f, 0.0f, 0.0f, 0.5f);
  857.     vec2_t min, max;
  858.     vectorInit2d(20, 100, min);
  859.     vectorInit2d(780, 500, max);
  860.     glColor4fv(Gui::info.var.hud_backgroundColor);
  861.     glBegin(GL_QUADS);
  862.         glVertex2f(min[0], min[1]);
  863.         glVertex2f(max[0], min[1]);
  864.         glVertex2f(max[0], max[1]);
  865.         glVertex2f(min[0], max[1]);
  866.     glEnd();
  867.  
  868.     glColor4fv(Gui::info.var.hud_activeColor);
  869.     glBegin(GL_LINE_LOOP);
  870.         glVertex2f(min[0], min[1]);
  871.         glVertex2f(max[0], min[1]);
  872.         glVertex2f(max[0], max[1]);
  873.         glVertex2f(min[0], max[1]);
  874.     glEnd();
  875.  
  876. }
  877.  
  878. void HudScoreboard::drawDeathmatchScoreboard(){
  879.     int i, j;
  880.     Client** players = new Client*[Network::server->si.numClients];
  881.     Client** spectators = new Client*[Network::server->si.numClients];
  882.     int numPlayers = 0;
  883.     int numSpectators = 0;
  884.  
  885.     for(i=0;i<Network::server->si.maxClients;i++){
  886.         if( Network::server->clients[i] != NULL ){
  887.             if( Network::server->clients[i]->ci.team == GAME_TEAM_SPECTATORS ){
  888.                 spectators[numSpectators] = Network::server->clients[i];
  889.                 numSpectators++;
  890.             }else{
  891.                 players[numPlayers] = Network::server->clients[i];
  892.                 numPlayers++;
  893.             }
  894.         }
  895.     }
  896.  
  897.     for(i=0;i<numPlayers;i++){
  898.         for(j=i+1;j<numPlayers;j++){
  899.             if( players[i]->ci.score < players[j]->ci.score ){
  900.                 Client* tmp = players[i];
  901.                 players[i] = players[j];
  902.                 players[j] = tmp;
  903.             }
  904.         }
  905.     }
  906.  
  907.     // PLAYERS
  908.     glColor4fv(Gui::info.var.hud_activeColor);
  909.  
  910.     float scale = 0.9f;
  911.     int yUpper = 477;
  912.     int y = yUpper;
  913.     int ySpacing = 20;
  914.     // first column (rank)
  915.     int x = 29;
  916.     drawScaledAndAlignedFormatString(x, y, scale, scale, font, TEXT_ALIGN_LEFT, "RNK");
  917.     for(i=0;i<numPlayers;i++){
  918.         y -= ySpacing;
  919.         drawScaledAndAlignedFormatString(x+25, y, scale, scale, font, TEXT_ALIGN_RIGHT, "%i", i+1);
  920.     }
  921.  
  922.     // second column (name)
  923.     x += 40;
  924.     y = yUpper;
  925.     drawScaledAndAlignedFormatString(x, y, scale, scale, font, TEXT_ALIGN_LEFT, "NAME");
  926.     for(i=0;i<numPlayers;i++){
  927.         y -= ySpacing;
  928.         drawScaledAndAlignedFormatString(x, y, scale, scale, font, TEXT_ALIGN_LEFT, "%s (id:%i)", players[i]->ci.name, players[i]->clientId);
  929.     }
  930.  
  931.     // third column (status)
  932.     x += 350;
  933.     y = yUpper;
  934.     drawScaledAndAlignedFormatString(x, y, scale, scale, font, TEXT_ALIGN_CENTER, "STATE");
  935.     for(i=0;i<numPlayers;i++){
  936.         y -= ySpacing;
  937.         if( players[i]->vehicle != NULL ){
  938.             drawScaledAndAlignedFormatString(x+20, y, scale, scale, font, TEXT_ALIGN_RIGHT, "%i", players[i]->cs.armor);
  939.         }else{
  940.             drawScaledAndAlignedString(x+20, y, scale, scale, font, TEXT_ALIGN_RIGHT, "DEAD");
  941.         }
  942.     }
  943.  
  944.     // third column (score)
  945.     x += 70;
  946.     y = yUpper;
  947.     drawScaledAndAlignedFormatString(x, y, scale, scale, font, TEXT_ALIGN_CENTER, "SCORE");
  948.     for(i=0;i<numPlayers;i++){
  949.         y -= ySpacing;
  950.         drawScaledAndAlignedFormatString(x+20, y, scale, scale, font, TEXT_ALIGN_RIGHT, "%i", players[i]->ci.score);
  951.     }
  952.  
  953.     // fourth column (kills)
  954.     x += 70;
  955.     y = yUpper;
  956.     drawScaledAndAlignedFormatString(x, y, scale, scale, font, TEXT_ALIGN_CENTER, "KILLS");
  957.     for(i=0;i<numPlayers;i++){
  958.         y -= ySpacing;
  959.         drawScaledAndAlignedFormatString(x+20, y, scale, scale, font, TEXT_ALIGN_RIGHT, "%i", players[i]->ci.kills);
  960.     }
  961.  
  962.     // fifth column (deaths)
  963.     x += 70;
  964.     y = yUpper;
  965.     drawScaledAndAlignedFormatString(x, y, scale, scale, font, TEXT_ALIGN_CENTER, "DEATHS");
  966.     for(i=0;i<numPlayers;i++){
  967.         y -= ySpacing;
  968.         drawScaledAndAlignedFormatString(x+20, y, scale, scale, font, TEXT_ALIGN_RIGHT, "%i", players[i]->ci.deaths);
  969.     }
  970.  
  971.     // sixth column (time)
  972.     x += 65;
  973.     y = yUpper;
  974.     drawScaledAndAlignedFormatString(x, y, scale, scale, font, TEXT_ALIGN_CENTER, "TIME");
  975.     for(i=0;i<numPlayers;i++){
  976.         y -= ySpacing;
  977.         int mins = players[i]->ci.secondsOnServer / 60;
  978.         drawScaledAndAlignedFormatString(x+20, y, scale, scale, font, TEXT_ALIGN_RIGHT, "%i", mins);
  979.     }
  980.  
  981.     // seventh column (ping)
  982.     x += 55;
  983.     y = yUpper;
  984.     drawScaledAndAlignedFormatString(x, y, scale, scale, font, TEXT_ALIGN_CENTER, "PING");
  985.     for(i=0;i<numPlayers;i++){
  986.         y -= ySpacing;
  987.         drawScaledAndAlignedFormatString(x+20, y, scale, scale, font, TEXT_ALIGN_RIGHT, "%i", players[i]->ci.ping);
  988.     }
  989.  
  990.     // SPECTATORS
  991.     int yLower = 105;
  992.     if( numSpectators > 0 ){
  993.         y = yLower + (numSpectators*ySpacing);
  994.         x = 29;
  995.         drawScaledAndAlignedFormatString(x, y, scale, scale, font, TEXT_ALIGN_LEFT, "SPECTATORS:");
  996.  
  997.         // second column (name)
  998.         x += 40;
  999.         y = yLower + (numSpectators*ySpacing);
  1000.         for(i=0;i<numSpectators;i++){
  1001.             y -= ySpacing;
  1002.             drawScaledAndAlignedFormatString(x, y, scale, scale, font, TEXT_ALIGN_LEFT, "%s (id:%i)", spectators[i]->ci.name, spectators[i]->clientId);
  1003.         }
  1004.  
  1005.         // third column (status)
  1006.         x += 350;
  1007.  
  1008.         // third column (score)
  1009.         x += 70;
  1010.  
  1011.         // fourth column (kills)
  1012.         x += 70;
  1013.  
  1014.         // fifth column (deaths)
  1015.         x += 70;
  1016.  
  1017.         // sixth column (time)
  1018.         x += 65;
  1019.         y = yLower + (numSpectators*ySpacing);
  1020.         for(i=0;i<numSpectators;i++){
  1021.             y -= ySpacing;
  1022.             int mins = spectators[i]->ci.secondsOnServer / 60;
  1023.             drawScaledAndAlignedFormatString(x+20, y, scale, scale, font, TEXT_ALIGN_RIGHT, "%i", mins);
  1024.         }
  1025.  
  1026.         // seventh column (ping)
  1027.         x += 55;
  1028.         y =    yLower + (numSpectators*ySpacing);
  1029.         for(i=0;i<numSpectators;i++){
  1030.             y -= ySpacing;
  1031.             drawScaledAndAlignedFormatString(x+20, y, scale, scale, font, TEXT_ALIGN_RIGHT, "%i", spectators[i]->ci.ping);
  1032.         }
  1033.     }
  1034.  
  1035.     // draw marker
  1036.     vec4_t transparent;
  1037.     vectorInit4d(0.0f, 0.0f, 0.0f, 0.0f, transparent);
  1038.     if( Network::client->ci.team == GAME_TEAM_PLAYERS ){
  1039.         y = yUpper - ySpacing;
  1040.         for(i=0;i<numPlayers;i++){
  1041.             if( players[i] == Network::client ){
  1042.                 Renderer::drawQuad(25, y, 775, y+ySpacing-2, Gui::info.var.hud_activeColor,  transparent);
  1043.             }
  1044.             y -= ySpacing;
  1045.         }
  1046.     }else{
  1047.         y = yLower + (numSpectators*ySpacing);
  1048.         for(i=0;i<numSpectators;i++){
  1049.             y -= ySpacing;
  1050.             if( spectators[i] == Network::client ){
  1051.                 Renderer::drawQuad(25, y, 775, y+ySpacing-2, Gui::info.var.hud_activeColor,  transparent);
  1052.             }
  1053.         }
  1054.     }
  1055.  
  1056.     delete[] players;
  1057.     delete[] spectators;
  1058. }
  1059.  
  1060. void HudScoreboard::drawTeamDeathmatchScoreboard(){
  1061.     int i, j;
  1062.     Client** reds = new Client*[Network::server->si.numClients];
  1063.     Client** blues = new Client*[Network::server->si.numClients];
  1064.     Client** spectators = new Client*[Network::server->si.numClients];
  1065.     int numReds = 0;
  1066.     int numBlues = 0;
  1067.     int numSpectators = 0;
  1068.     int redScore = 0;
  1069.     int blueScore = 0;
  1070.     int redKills = 0;
  1071.     int blueKills = 0;
  1072.     int redDeaths = 0;
  1073.     int blueDeaths = 0;
  1074.  
  1075.     for(i=0;i<Network::server->si.maxClients;i++){
  1076.         if( Network::server->clients[i] != NULL ){
  1077.             if( Network::server->clients[i]->ci.team == GAME_TEAM_SPECTATORS ){
  1078.                 spectators[numSpectators] = Network::server->clients[i];
  1079.                 numSpectators++;
  1080.             }else if( Network::server->clients[i]->ci.team == GAME_TEAM_RED ){
  1081.                 reds[numReds] = Network::server->clients[i];
  1082.                 numReds++;
  1083.                 redScore += Network::server->clients[i]->ci.score;
  1084.                 redKills += Network::server->clients[i]->ci.kills;
  1085.                 redDeaths += Network::server->clients[i]->ci.deaths;
  1086.             }else if( Network::server->clients[i]->ci.team == GAME_TEAM_BLUE ){
  1087.                 blues[numBlues] = Network::server->clients[i];
  1088.                 numBlues++;
  1089.                 blueScore += Network::server->clients[i]->ci.score;
  1090.                 blueKills += Network::server->clients[i]->ci.kills;
  1091.                 blueDeaths += Network::server->clients[i]->ci.deaths;
  1092.             }
  1093.         }
  1094.     }
  1095.  
  1096.     for(i=0;i<numReds;i++){
  1097.         for(j=i+1;j<numReds;j++){
  1098.             if( reds[i]->ci.score < reds[j]->ci.score ){
  1099.                 Client* tmp = reds[i];
  1100.                 reds[i] = reds[j];
  1101.                 reds[j] = tmp;
  1102.             }
  1103.         }
  1104.     }
  1105.     for(i=0;i<numBlues;i++){
  1106.         for(j=i+1;j<numBlues;j++){
  1107.             if( blues[i]->ci.score < blues[j]->ci.score ){
  1108.                 Client* tmp = blues[i];
  1109.                 blues[i] = blues[j];
  1110.                 blues[j] = tmp;
  1111.             }
  1112.         }
  1113.     }
  1114.  
  1115.     // HEADING
  1116.     glColor4fv(Gui::info.var.hud_activeColor);
  1117.  
  1118.     float scale = 0.9f;
  1119.     int yUpper = 477;
  1120.     int y = yUpper;
  1121.     int ySpacing = 20;
  1122.  
  1123.     int x = 400;
  1124.     if( redScore > blueScore ){
  1125.         drawScaledAndAlignedFormatString(x, y, scale, scale, font, TEXT_ALIGN_CENTER, "RED leads BLUE with %i to %i", redScore, blueScore);
  1126.     }else if( redScore < blueScore ){
  1127.         drawScaledAndAlignedFormatString(x, y, scale, scale, font, TEXT_ALIGN_CENTER, "BLUE leads RED with %i to %i", blueScore, redScore);
  1128.     }else{
  1129.         drawScaledAndAlignedFormatString(x, y, scale, scale, font, TEXT_ALIGN_CENTER, "Teams are TIED with %i", redScore);
  1130.     }
  1131.  
  1132.     y -= ySpacing;
  1133.  
  1134.     // first column (rank)
  1135.     x = 29;
  1136. //    drawScaledAndAlignedFormatString(x, y, scale, scale, font, TEXT_ALIGN_LEFT, "RNK");
  1137.     // second column (name)
  1138.     x += 40;
  1139. //    drawScaledAndAlignedFormatString(x, y, scale, scale, font, TEXT_ALIGN_LEFT, "NAME");
  1140.     // third column (status)
  1141.     x += 350;
  1142.     drawScaledAndAlignedFormatString(x, y, scale, scale, font, TEXT_ALIGN_CENTER, "STATE");
  1143.     // third column (score)
  1144.     x += 70;
  1145.     drawScaledAndAlignedFormatString(x, y, scale, scale, font, TEXT_ALIGN_CENTER, "SCORE");
  1146.     // fourth column (kills)
  1147.     x += 70;
  1148.     drawScaledAndAlignedFormatString(x, y, scale, scale, font, TEXT_ALIGN_CENTER, "KILLS");
  1149.     // fifth column (deaths)
  1150.     x += 70;
  1151.     drawScaledAndAlignedFormatString(x, y, scale, scale, font, TEXT_ALIGN_CENTER, "DEATHS");
  1152.     // sixth column (time)
  1153.     x += 65;
  1154.     drawScaledAndAlignedFormatString(x, y, scale, scale, font, TEXT_ALIGN_CENTER, "TIME");
  1155.  
  1156.     // seventh column (ping)
  1157.     x += 55;
  1158.     drawScaledAndAlignedFormatString(x, y, scale, scale, font, TEXT_ALIGN_CENTER, "PING");
  1159.  
  1160.     y -= ySpacing;
  1161.  
  1162.     // RED TEAM
  1163.     vec4_t fill, border;
  1164.     vectorInit4d(1.0f, 0.0f, 0.0f, 0.25f, fill);
  1165.     vectorInit4d(1.0f, 0.0f, 0.0f, 1.0f, border);
  1166.     Renderer::drawQuad(24, y - ySpacing*(numReds) - 2, 776, y + ySpacing, border, fill);
  1167.     glColor4fv(Gui::info.var.hud_activeColor);
  1168.  
  1169.     x = 29;
  1170.     drawScaledAndAlignedFormatString(x, y, scale, scale, font, TEXT_ALIGN_LEFT, "RED Team (%i players):", numReds);
  1171.     x += 40;
  1172.     x += 350;
  1173.     x += 70;
  1174.     drawScaledAndAlignedFormatString(x+20, y, scale, scale, font, TEXT_ALIGN_RIGHT, "%i", redScore);
  1175.     x += 70;
  1176.     drawScaledAndAlignedFormatString(x+20, y, scale, scale, font, TEXT_ALIGN_RIGHT, "%i", redKills);
  1177.     x += 70;
  1178.     drawScaledAndAlignedFormatString(x+20, y, scale, scale, font, TEXT_ALIGN_RIGHT, "%i", redDeaths);
  1179.  
  1180.     y -= ySpacing;
  1181.  
  1182.     // team members
  1183.     int ySave = y;    
  1184.     // rank
  1185.     x = 29;
  1186.     for(i=0;i<numReds;i++){
  1187.         drawScaledAndAlignedFormatString(x+25, y, scale, scale, font, TEXT_ALIGN_RIGHT, "%i", i+1);
  1188.         y -= ySpacing;
  1189.     }
  1190.     // second column (name)
  1191.     x += 40;
  1192.     y = ySave;
  1193.     for(i=0;i<numReds;i++){
  1194.         drawScaledAndAlignedFormatString(x, y, scale, scale, font, TEXT_ALIGN_LEFT, "%s (id:%i)", reds[i]->ci.name, reds[i]->clientId);
  1195.         y -= ySpacing;
  1196.     }
  1197.     // third column (status)
  1198.     x += 350;
  1199.     y = ySave;
  1200.     for(i=0;i<numReds;i++){
  1201.         if( reds[i]->vehicle != NULL ){
  1202.             drawScaledAndAlignedFormatString(x+20, y, scale, scale, font, TEXT_ALIGN_RIGHT, "%i", reds[i]->cs.armor);
  1203.         }else{
  1204.             drawScaledAndAlignedString(x+20, y, scale, scale, font, TEXT_ALIGN_RIGHT, "DEAD");
  1205.         }
  1206.         y -= ySpacing;
  1207.     }
  1208.     // third column (score)
  1209.     x += 70;
  1210.     y = ySave;
  1211.     for(i=0;i<numReds;i++){
  1212.         drawScaledAndAlignedFormatString(x+20, y, scale, scale, font, TEXT_ALIGN_RIGHT, "%i", reds[i]->ci.score);
  1213.         y -= ySpacing;
  1214.     }
  1215.     // fourth column (kills)
  1216.     x += 70;
  1217.     y = ySave;
  1218.     for(i=0;i<numReds;i++){
  1219.         drawScaledAndAlignedFormatString(x+20, y, scale, scale, font, TEXT_ALIGN_RIGHT, "%i", reds[i]->ci.kills);
  1220.         y -= ySpacing;
  1221.     }
  1222.     // fifth column (deaths)
  1223.     x += 70;
  1224.     y = ySave;
  1225.     for(i=0;i<numReds;i++){
  1226.         drawScaledAndAlignedFormatString(x+20, y, scale, scale, font, TEXT_ALIGN_RIGHT, "%i", reds[i]->ci.deaths);
  1227.         y -= ySpacing;
  1228.     }
  1229.     // sixth column (time)
  1230.     x += 65;
  1231.     y = ySave;
  1232.     for(i=0;i<numReds;i++){
  1233.         int mins = reds[i]->ci.secondsOnServer / 60;
  1234.         drawScaledAndAlignedFormatString(x+20, y, scale, scale, font, TEXT_ALIGN_RIGHT, "%i", mins);
  1235.         y -= ySpacing;
  1236.     }
  1237.     // seventh column (ping)
  1238.     x += 55;
  1239.     y = ySave;
  1240.     for(i=0;i<numReds;i++){
  1241.         drawScaledAndAlignedFormatString(x+20, y, scale, scale, font, TEXT_ALIGN_RIGHT, "%i", reds[i]->ci.ping);
  1242.         y -= ySpacing;
  1243.     }
  1244.  
  1245.  
  1246.     y -= ySpacing;
  1247.  
  1248.  
  1249.     // BLUE TEAM
  1250. //    vec4_t fill, border;
  1251.     vectorInit4d(0.0f, 0.0f, 1.0f, 0.25f, fill);
  1252.     vectorInit4d(0.0f, 0.0f, 1.0f, 1.0f, border);
  1253.     Renderer::drawQuad(24, y - ySpacing*(numBlues) - 2, 776, y + ySpacing, border, fill);
  1254.     glColor4fv(Gui::info.var.hud_activeColor);
  1255.  
  1256.  
  1257.     x = 29;
  1258.     drawScaledAndAlignedFormatString(x, y, scale, scale, font, TEXT_ALIGN_LEFT, "BLUE Team (%i players):", numBlues);
  1259.     x += 40;
  1260.     x += 350;
  1261.     x += 70;
  1262.     drawScaledAndAlignedFormatString(x+20, y, scale, scale, font, TEXT_ALIGN_RIGHT, "%i", blueScore);
  1263.     x += 70;
  1264.     drawScaledAndAlignedFormatString(x+20, y, scale, scale, font, TEXT_ALIGN_RIGHT, "%i", blueKills);
  1265.     x += 70;
  1266.     drawScaledAndAlignedFormatString(x+20, y, scale, scale, font, TEXT_ALIGN_RIGHT, "%i", blueDeaths);
  1267.  
  1268.     y -= ySpacing;
  1269.  
  1270.     // team members
  1271.     ySave = y;    
  1272.     // rank
  1273.     x = 29;
  1274.     for(i=0;i<numBlues;i++){
  1275.         drawScaledAndAlignedFormatString(x+25, y, scale, scale, font, TEXT_ALIGN_RIGHT, "%i", i+1);
  1276.         y -= ySpacing;
  1277.     }
  1278.     // second column (name)
  1279.     x += 40;
  1280.     y = ySave;
  1281.     for(i=0;i<numBlues;i++){
  1282.         drawScaledAndAlignedFormatString(x, y, scale, scale, font, TEXT_ALIGN_LEFT, "%s (id:%i)", blues[i]->ci.name, blues[i]->clientId);
  1283.         y -= ySpacing;
  1284.     }
  1285.     // third column (status)
  1286.     x += 350;
  1287.     y = ySave;
  1288.     for(i=0;i<numBlues;i++){
  1289.         if( blues[i]->vehicle != NULL ){
  1290.             drawScaledAndAlignedFormatString(x+20, y, scale, scale, font, TEXT_ALIGN_RIGHT, "%i", blues[i]->cs.armor);
  1291.         }else{
  1292.             drawScaledAndAlignedString(x+20, y, scale, scale, font, TEXT_ALIGN_RIGHT, "DEAD");
  1293.         }
  1294.         y -= ySpacing;
  1295.     }
  1296.     // third column (score)
  1297.     x += 70;
  1298.     y = ySave;
  1299.     for(i=0;i<numBlues;i++){
  1300.         drawScaledAndAlignedFormatString(x+20, y, scale, scale, font, TEXT_ALIGN_RIGHT, "%i", blues[i]->ci.score);
  1301.         y -= ySpacing;
  1302.     }
  1303.     // fourth column (kills)
  1304.     x += 70;
  1305.     y = ySave;
  1306.     for(i=0;i<numBlues;i++){
  1307.         drawScaledAndAlignedFormatString(x+20, y, scale, scale, font, TEXT_ALIGN_RIGHT, "%i", blues[i]->ci.kills);
  1308.         y -= ySpacing;
  1309.     }
  1310.     // fifth column (deaths)
  1311.     x += 70;
  1312.     y = ySave;
  1313.     for(i=0;i<numBlues;i++){
  1314.         drawScaledAndAlignedFormatString(x+20, y, scale, scale, font, TEXT_ALIGN_RIGHT, "%i", blues[i]->ci.deaths);
  1315.         y -= ySpacing;
  1316.     }
  1317.     // sixth column (time)
  1318.     x += 65;
  1319.     y = ySave;
  1320.     for(i=0;i<numBlues;i++){
  1321.         int mins = blues[i]->ci.secondsOnServer / 60;
  1322.         drawScaledAndAlignedFormatString(x+20, y, scale, scale, font, TEXT_ALIGN_RIGHT, "%i", mins);
  1323.         y -= ySpacing;
  1324.     }
  1325.     // seventh column (ping)
  1326.     x += 55;
  1327.     y = ySave;
  1328.     for(i=0;i<numBlues;i++){
  1329.         drawScaledAndAlignedFormatString(x+20, y, scale, scale, font, TEXT_ALIGN_RIGHT, "%i", blues[i]->ci.ping);
  1330.         y -= ySpacing;
  1331.     }
  1332.  
  1333.  
  1334.  
  1335.     // SPECTATORS
  1336.     int yLower = 105;
  1337.     if( numSpectators > 0 ){
  1338.         y = yLower + (numSpectators*ySpacing);
  1339.         x = 29;
  1340.         drawScaledAndAlignedFormatString(x, y, scale, scale, font, TEXT_ALIGN_LEFT, "SPECTATORS:");
  1341.  
  1342.         // second column (name)
  1343.         x += 40;
  1344.         y = yLower + (numSpectators*ySpacing);
  1345.         for(i=0;i<numSpectators;i++){
  1346.             y -= ySpacing;
  1347.             drawScaledAndAlignedFormatString(x, y, scale, scale, font, TEXT_ALIGN_LEFT, "%s (id:%i)", spectators[i]->ci.name, spectators[i]->clientId);
  1348.         }
  1349.  
  1350.         // third column (status)
  1351.         x += 350;
  1352.  
  1353.         // third column (score)
  1354.         x += 70;
  1355.  
  1356.         // fourth column (kills)
  1357.         x += 70;
  1358.  
  1359.         // fifth column (deaths)
  1360.         x += 70;
  1361.  
  1362.         // sixth column (time)
  1363.         x += 65;
  1364.         y = yLower + (numSpectators*ySpacing);
  1365.         for(i=0;i<numSpectators;i++){
  1366.             y -= ySpacing;
  1367.             int mins = spectators[i]->ci.secondsOnServer / 60;
  1368.             drawScaledAndAlignedFormatString(x+20, y, scale, scale, font, TEXT_ALIGN_RIGHT, "%i", mins);
  1369.         }
  1370.  
  1371.         // seventh column (ping)
  1372.         x += 55;
  1373.         y =    yLower + (numSpectators*ySpacing);
  1374.         for(i=0;i<numSpectators;i++){
  1375.             y -= ySpacing;
  1376.             drawScaledAndAlignedFormatString(x+20, y, scale, scale, font, TEXT_ALIGN_RIGHT, "%i", spectators[i]->ci.ping);
  1377.         }
  1378.     }
  1379.  
  1380.  
  1381.     // draw marker
  1382.     vec4_t transparent;
  1383.     vectorInit4d(0.0f, 0.0f, 0.0f, 0.0f, transparent);
  1384.     if( Network::client->ci.team == GAME_TEAM_RED ){
  1385.         y = yUpper - ySpacing;
  1386.         y -= ySpacing;
  1387.         y -= ySpacing;
  1388.         for(i=0;i<numReds;i++){
  1389.             if( reds[i] == Network::client ){
  1390.                 Renderer::drawQuad(25, y, 775, y+ySpacing-2, Gui::info.var.hud_activeColor,  transparent);
  1391.             }
  1392.             y -= ySpacing;
  1393.         }
  1394.     }else if( Network::client->ci.team == GAME_TEAM_BLUE ){
  1395.         y = yUpper - ySpacing;
  1396.         y -= ySpacing;
  1397.         y -= ySpacing;
  1398.         for(i=0;i<numReds;i++){
  1399.             y -= ySpacing;
  1400.         }
  1401.         y -= ySpacing;
  1402.         y -= ySpacing;
  1403.  
  1404.         for(i=0;i<numBlues;i++){
  1405.             if( blues[i] == Network::client ){
  1406.                 Renderer::drawQuad(25, y, 775, y+ySpacing-2, Gui::info.var.hud_activeColor,  transparent);
  1407.             }
  1408.             y -= ySpacing;
  1409.         }
  1410.  
  1411.     }else{
  1412.         y = yLower + (numSpectators*ySpacing);
  1413.         for(i=0;i<numSpectators;i++){
  1414.             y -= ySpacing;
  1415.             if( spectators[i] == Network::client ){
  1416.                 Renderer::drawQuad(25, y, 775, y+ySpacing-2, Gui::info.var.hud_activeColor,  transparent);
  1417.             }
  1418.         }
  1419.     }
  1420.  
  1421.     delete[] reds;
  1422.     delete[] blues;
  1423.     delete[] spectators;
  1424. }
  1425.  
  1426.  
  1427.  
  1428.  
  1429.  
  1430.  
  1431.  
  1432. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1433. //
  1434. // TAKE DAMAGE INDICATOR
  1435. //
  1436. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1437.  
  1438.  
  1439.  
  1440. HudTakeDamageIndicator::HudTakeDamageIndicator(){
  1441.     texture = TextureHandler::getTexture("gui/hud/take_damage_indicator.tga");
  1442.  
  1443. //    visible=true;
  1444. }
  1445.  
  1446. HudTakeDamageIndicator::~HudTakeDamageIndicator(){
  1447.     if(texture)
  1448.         TextureHandler::releaseTexture(texture);
  1449. }
  1450.  
  1451. void HudTakeDamageIndicator::draw(){
  1452.     if( Game::cam.target == NULL || Game::cam.mode == CAMERA_MODE_FREE ){
  1453.         return;
  1454.     }
  1455.  
  1456.     Vehicle* v = Game::cam.target;
  1457.  
  1458.     unsigned long currentMillis = SDL_GetTicks();
  1459.     if( currentMillis < v->lastTakeDamageMillis + 1000 ){
  1460.         
  1461.         float alpha =  1.0f - (currentMillis - v->lastTakeDamageMillis)/1000.0f;
  1462.         glColor4f(1.0f, 1.0f, 1.0f, alpha);
  1463.         Renderer::drawTexturedQuad(0,0,800,600, texture);
  1464.     }
  1465.  
  1466. }
  1467.  
  1468.  
  1469.  
  1470.  
  1471.  
  1472.  
  1473. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1474. //
  1475. // DEBUG INFO
  1476. //
  1477. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1478.  
  1479. HudDebugInfo::HudDebugInfo(){
  1480.     font=FontHandler::getFont("gui/fonts/courier_tiny_bold.font");
  1481.  
  1482.     min[0]=530;
  1483.     max[0]=790;
  1484.     min[1]=10;
  1485.     max[1]=170;
  1486.  
  1487. //    visible=true;
  1488. }
  1489.  
  1490. HudDebugInfo::~HudDebugInfo(){
  1491.     if(font!=NULL)
  1492.         FontHandler::releaseFont(font);
  1493. }
  1494.  
  1495. void HudDebugInfo::draw(){
  1496.  
  1497.     drawBackground();
  1498.     glColor4fv(Gui::info.var.hud_activeColor);
  1499.  
  1500.     int y = (max[1]-10-font->height);
  1501.     drawAlignedFormatString(min[0]+10, y, font, TEXT_ALIGN_LEFT, "RENDERER");
  1502.     y-=(font->height+1);
  1503.     drawAlignedFormatString(min[0]+10, y, font, TEXT_ALIGN_LEFT, "nodeCount: %i", Renderer::info.var.nodeCount);
  1504.     y-=(font->height+1);
  1505.     drawAlignedFormatString(min[0]+10, y, font, TEXT_ALIGN_LEFT, "modelCount:%i", Renderer::info.var.modelCount);
  1506.     y-=(font->height+1);
  1507.     drawAlignedFormatString(min[0]+10, y, font, TEXT_ALIGN_LEFT, "meshCount: %i", Renderer::info.var.meshCount);
  1508.     y-=(font->height+1);
  1509.     drawAlignedFormatString(min[0]+10, y, font, TEXT_ALIGN_LEFT, "polyCount: %i", Renderer::info.var.polyCount);
  1510.     y-=(font->height+1);
  1511.     drawAlignedFormatString(min[0]+10, y, font, TEXT_ALIGN_LEFT, "transCount:%i", Renderer::info.var.transPolyCount);
  1512.  
  1513.     y-=(font->height+3);
  1514.     drawAlignedFormatString(min[0]+10, y, font, TEXT_ALIGN_LEFT, "CAMERA");
  1515.     y-=(font->height+1);
  1516.     drawAlignedFormatString(min[0]+10, y, font, TEXT_ALIGN_LEFT, "cam.pos:(%.1f, %.1f, %.1f)", Game::cam.pos[0], Game::cam.pos[1], Game::cam.pos[2]);
  1517.     y-=(font->height+1);
  1518.     drawAlignedFormatString(min[0]+10, y, font, TEXT_ALIGN_LEFT, "cam.dir:(%.1f, %.1f, %.1f)", Game::cam.dir[0], Game::cam.dir[1], Game::cam.dir[2]);
  1519.     y-=(font->height+1);
  1520.     drawAlignedFormatString(min[0]+10, y, font, TEXT_ALIGN_LEFT, "cam.up: (%.1f, %.1f, %.1f)", Game::cam.up[0], Game::cam.up[1], Game::cam.up[2]);
  1521.     y-=(font->height+1);
  1522.     drawAlignedFormatString(min[0]+10, y, font, TEXT_ALIGN_LEFT, "cam.yaw:   %.3f", Game::cam.yaw);
  1523.     y-=(font->height+1);
  1524.     drawAlignedFormatString(min[0]+10, y, font, TEXT_ALIGN_LEFT, "cam.pitch: %.3f", Game::cam.pitch);
  1525. }
  1526.  
  1527. void HudDebugInfo::drawBackground(){
  1528.     //glColor4f(0.0f, 0.0f, 0.0f, 0.5f);
  1529.     glColor4fv(Gui::info.var.hud_backgroundColor);
  1530.     glBegin(GL_QUADS);
  1531.         glVertex2f(min[0], min[1]);
  1532.         glVertex2f(max[0], min[1]);
  1533.         glVertex2f(max[0], max[1]);
  1534.         glVertex2f(min[0], max[1]);
  1535.     glEnd();
  1536.  
  1537.     glColor4fv(Gui::info.var.hud_activeColor);
  1538.     glBegin(GL_LINE_LOOP);
  1539.         glVertex2f(min[0], min[1]);
  1540.         glVertex2f(max[0], min[1]);
  1541.         glVertex2f(max[0], max[1]);
  1542.         glVertex2f(min[0], max[1]);
  1543.     glEnd();
  1544.  
  1545. }
  1546.