home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2007 September / maximum-cd-2007-09.iso / Assets / data / AssaultCube_v0.93.exe / source / src / renderhud.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2007-06-05  |  15.9 KB  |  485 lines

  1. // renderhud.cpp: HUD rendering
  2.  
  3. #include "cube.h"
  4.  
  5. void drawicon(Texture *tex, float x, float y, float s, int col, int row, float ts)
  6. {
  7.     if(tex && tex->xs == tex->ys) quad(tex->id, x, y, s, ts*col, ts*row, ts);
  8. }
  9.  
  10. void drawequipicon(float x, float y, int col, int row, float blend)
  11. {
  12.     static Texture *tex = NULL;
  13.     if(!tex) tex = textureload("packages/misc/items.png");
  14.     if(tex)
  15.     {
  16.         if(blend) glEnable(GL_BLEND);
  17.         drawicon(tex, x, y, 120, col, row, 1/3.0f);
  18.         if(blend) glDisable(GL_BLEND);
  19.     }
  20. }
  21.  
  22. void drawradaricon(float x, float y, float s, int col, int row)
  23. {
  24.     static Texture *tex = NULL;
  25.     if(!tex) tex = textureload("packages/misc/radaricons.png");
  26.     if(tex) 
  27.     {
  28.         glEnable(GL_BLEND);     
  29.         drawicon(tex, x, y, s, col, row, 1/4.0f);
  30.         glDisable(GL_BLEND);
  31.     }
  32. }
  33.  
  34. void drawctficon(float x, float y, float s, int col, int row, float ts)
  35. {
  36.     static Texture *tex = NULL;
  37.     if(!tex) tex = textureload("packages/misc/ctficons.png");
  38.     if(tex) drawicon(tex, x, y, s, col, row, ts);
  39. }
  40.  
  41. VARP(crosshairsize, 0, 15, 50);
  42.  
  43. int dblend = 0;
  44. void damageblend(int n) { dblend += n; }
  45.  
  46. VARP(hidestats, 0, 1, 1);
  47. VARP(crosshairfx, 0, 1, 1);
  48. VARP(hideradar, 0, 0, 1);
  49. VARP(radarres, 1, 64, 1024);
  50. VARP(radarentsize, 1, 4, 64);
  51. VARP(hidectfhud, 0, 0, 1);
  52. VARP(hidedemohud, 0, 0, 1);
  53.  
  54. VAR(showmap, 0, 0, 1);
  55.  
  56. void drawscope()
  57. {
  58.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  59.     glEnable(GL_ALPHA_TEST);
  60.     glAlphaFunc(GL_GREATER, 0.9f);
  61.     static Texture *scopetex = NULL;
  62.     if(!scopetex) scopetex = textureload("packages/misc/scope.png");
  63.     glBindTexture(GL_TEXTURE_2D, scopetex->id);
  64.     glBegin(GL_QUADS);
  65.     glColor3ub(255,255,255);
  66.  
  67.     glTexCoord2i(0, 0); glVertex2i(0, 0);
  68.     glTexCoord2i(1, 0); glVertex2i(VIRTW, 0);
  69.     glTexCoord2i(1, 1); glVertex2i(VIRTW, VIRTH);
  70.     glTexCoord2i(0, 1); glVertex2i(0, VIRTH);
  71.  
  72.     glEnd();
  73.     glDisable(GL_ALPHA_TEST);
  74. }
  75.  
  76. void drawcrosshair(bool showteamwarning)
  77. {
  78.     glBlendFunc(GL_ONE, GL_ONE);
  79.     static Texture *teammatetex = NULL;
  80.     if(!teammatetex) teammatetex = textureload("packages/misc/teammate.png");
  81.     glBindTexture(GL_TEXTURE_2D, showteamwarning ? teammatetex->id : crosshair->id);
  82.     glBegin(GL_QUADS);
  83.     glColor3ub(255,255,255);
  84.     if(crosshairfx)
  85.     {
  86.         if(showteamwarning) glColor3ub(255, 0, 0);
  87.         else if(player1->gunwait) glColor3ub(128,128,128);
  88.         else if(!m_osok)
  89.         {
  90.             if(player1->health<=25) glColor3ub(255,0,0);
  91.             else if(player1->health<=50) glColor3ub(255,128,0);
  92.         }
  93.     }
  94.     float chsize = (float)crosshairsize * (player1->gunselect==GUN_ASSAULT && player1->shots > 3 ? 1.4f : 1.0f) * (showteamwarning ? 2.0f : 1.0f);
  95.     glTexCoord2i(0, 0); glVertex2f(VIRTW/2 - chsize, VIRTH/2 - chsize);
  96.     glTexCoord2i(1, 0); glVertex2f(VIRTW/2 + chsize, VIRTH/2 - chsize);
  97.     glTexCoord2i(1, 1); glVertex2f(VIRTW/2 + chsize, VIRTH/2 + chsize);
  98.     glTexCoord2i(0, 1); glVertex2f(VIRTW/2 - chsize, VIRTH/2 + chsize);
  99.     glEnd();
  100. }
  101.  
  102. void drawequipicons()
  103. {   
  104.     glDisable(GL_BLEND);
  105.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  106.     glColor4f(1.0f, 1.0f, 1.0f, 0.2f+(sinf(lastmillis/100.0f)+1.0f)/2.0f);
  107.  
  108.     // health & armor
  109.     if(player1->armour) drawequipicon(620, 1650, 2, 0, false);
  110.     drawequipicon(20, 1650, 1, 0, (player1->state!=CS_DEAD && player1->health<=20 && !m_osok));
  111.     
  112.     // weapons
  113.     int c = player1->gunselect, r = 1;
  114.     if(c>2) { c -= 3; r = 2; }
  115.     if(c==GUN_GRENADE) c = r = 0;
  116.  
  117.     drawequipicon(1220, 1650, c, r, (!player1->mag[player1->gunselect] && player1->gunselect != GUN_KNIFE && player1->gunselect != GUN_GRENADE));
  118.     glEnable(GL_BLEND);
  119. }
  120.  
  121. void drawradarent(float x, float y, float yaw, int col, int row, float iconsize, bool pulse, char *label = NULL, ...)
  122. {
  123.     glPushMatrix();
  124.     if(pulse) glColor4f(1.0f, 1.0f, 1.0f, 0.2f+(sinf(lastmillis/30.0f)+1.0f)/2.0f);
  125.     else glColor4f(1, 1, 1, 1);
  126.     glTranslatef(x, y, 0);
  127.     glRotatef(yaw, 0, 0, 1);
  128.     drawradaricon(-iconsize/2.0f, -iconsize/2.0f, iconsize, col, row); 
  129.     glPopMatrix();
  130.     if(label && showmap)
  131.     {
  132.         glPushMatrix();
  133.         glEnable(GL_BLEND);
  134.         glTranslatef(iconsize/2, iconsize/2, 0);
  135.         glScalef(1/2.0f, 1/2.0f, 1/2.0f);
  136.         s_sprintfdv(lbl, label);
  137.         draw_text(lbl, (int)(x*2), (int)(y*2));
  138.         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  139.         glDisable(GL_BLEND);
  140.         glPopMatrix();
  141.     }
  142. }
  143.  
  144. bool insideradar(const vec ¢erpos, float radius, const vec &o)
  145. {
  146.     if(showmap) return !o.reject(centerpos, radius);
  147.     return o.distxy(centerpos)<=radius;
  148. }
  149.  
  150. bool isattacking(playerent *p) { return lastmillis-p->lastaction < 500; }
  151.  
  152. void drawradar(int w, int h)
  153. {
  154.     vec center = showmap ? vec(ssize/2, ssize/2, 0) : player1->o;
  155.     int res = showmap ? ssize : radarres;
  156.  
  157.     float worldsize = (float)ssize;
  158.     float radarviewsize = showmap ? VIRTH : VIRTH/6;
  159.     float radarsize = worldsize/res*radarviewsize;
  160.     float iconsize = radarentsize/(float)res*radarviewsize;
  161.     float coordtrans = radarsize/worldsize;
  162.     float overlaysize = radarviewsize*4.0f/3.25f;
  163.  
  164.     glPushMatrix();
  165.  
  166.     if(showmap) glTranslatef(VIRTW/2-radarviewsize/2, 0, 0);
  167.     else 
  168.     {
  169.         glTranslatef(VIRTW-radarviewsize-(overlaysize-radarviewsize)/2-10+radarviewsize/2, 10+(overlaysize-radarviewsize)/2+radarviewsize/2, 0);
  170.         glRotatef(-camera1->yaw, 0, 0, 1);
  171.         glTranslatef(-radarviewsize/2, -radarviewsize/2, 0);
  172.     }
  173.  
  174.     extern GLuint minimaptex;
  175.  
  176.     vec centerpos(min(max(center.x, res/2), worldsize-res/2), min(max(center.y, res/2), worldsize-res/2), 0);
  177.     if(showmap) 
  178.     {
  179.         glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
  180.         quad(minimaptex, 0, 0, radarviewsize, (centerpos.x-res/2)/worldsize, (centerpos.y-res/2)/worldsize, res/worldsize);
  181.         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  182.         glDisable(GL_BLEND);
  183.     }
  184.     else 
  185.     {
  186.         glDisable(GL_BLEND);
  187.         circle(minimaptex, radarviewsize/2, radarviewsize/2, radarviewsize/2, centerpos.x/worldsize, centerpos.y/worldsize, res/2/worldsize);
  188.     }
  189.     glTranslatef(-(centerpos.x-res/2)/worldsize*radarsize, -(centerpos.y-res/2)/worldsize*radarsize, 0);
  190.  
  191.     drawradarent(player1->o.x*coordtrans, player1->o.y*coordtrans, player1->yaw, player1->state==CS_ALIVE ? (isattacking(player1) ? 2 : 0) : 1, 2, iconsize, isattacking(player1), colorname(player1)); // local player
  192.  
  193.     loopv(players) // other players
  194.     {
  195.         playerent *pl = players[i];
  196.         if(!pl || !isteam(player1->team, pl->team) || !insideradar(centerpos, res/2, pl->o)) continue;
  197.         drawradarent(pl->o.x*coordtrans, pl->o.y*coordtrans, pl->yaw, pl->state==CS_ALIVE ? (isattacking(pl) ? 2 : 0) : 1, team_int(pl->team), iconsize, isattacking(pl), colorname(pl));
  198.     }
  199.     if(m_ctf)
  200.     {
  201.         glColor4f(1.0f, 1.0f, 1.0f, (sinf(lastmillis / 100.0f) + 1.0f) / 2.0f);
  202.         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  203.         loopi(2) // flag items
  204.         {
  205.             flaginfo &f = flaginfos[i];
  206.             entity *e = f.flag;
  207.             if(!e) continue;
  208.             float yaw = showmap ? 0 : player1->yaw;
  209.             if(f.state==CTFF_STOLEN)
  210.             {
  211.                 if(f.actor && i != team_int(player1->team) && insideradar(centerpos, res/2, f.actor->o))
  212.                     drawradarent(f.actor->o.x*coordtrans+iconsize/2, f.actor->o.y*coordtrans+iconsize/2, yaw, 3, f.team, iconsize, true); // draw near flag thief
  213.             }
  214.             else if(insideradar(centerpos, res/2, vec(e->x, e->y, centerpos.z))) drawradarent(e->x*coordtrans, e->y*coordtrans, yaw, 3, f.team, iconsize, false); // draw on entitiy pos
  215.         }
  216.     }
  217.  
  218.     glEnable(GL_BLEND);
  219.     glPopMatrix();
  220.  
  221.     if(!showmap)
  222.     {
  223.         glDisable(GL_CULL_FACE);
  224.         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  225.         glColor3f(1, 1, 1);
  226.         static Texture *overlaytex = NULL;
  227.         if(!overlaytex) overlaytex = textureload("packages/misc/radaroverlays.png", 3);
  228.         quad(overlaytex->id, VIRTW-overlaysize-10, 10, overlaysize, m_teammode ? 0.5f*team_int(player1->team) : 0, m_teammode ? 0 : 0.5f, 0.5f, 0.5f); 
  229.         glEnable(GL_CULL_FACE);
  230.     }
  231. }
  232.  
  233. void drawteamicons(int w, int h)
  234. {
  235.     glDisable(GL_CULL_FACE);
  236.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  237.     glColor3f(1, 1, 1);
  238.     static Texture *icons = NULL;
  239.     if(!icons) icons = textureload("packages/misc/teamicons.png");
  240.     quad(icons->id, VIRTW-VIRTH/12-10, 10, VIRTH/12, team_int(player1->team) ? 0.5f : 0, 0, 0.5f, 0.5f);
  241.     glEnable(GL_CULL_FACE);
  242. }
  243.  
  244. void gl_drawhud(int w, int h, int curfps, int nquads, int curvert, bool underwater)
  245. {
  246.     glDisable(GL_DEPTH_TEST);
  247.  
  248.     glMatrixMode(GL_MODELVIEW);
  249.     glLoadIdentity();
  250.  
  251.     glMatrixMode(GL_PROJECTION);
  252.     glLoadIdentity();
  253.     glOrtho(0, VIRTW, VIRTH, 0, -1, 1);
  254.     glEnable(GL_BLEND);
  255.  
  256.     if(dblend || underwater)
  257.     {
  258.         glDepthMask(GL_FALSE);
  259.         if(dblend) 
  260.         {
  261.             glBlendFunc(GL_ZERO, GL_SRC_COLOR);
  262.             glColor3f(1.0f, 0.1f, 0.1f);
  263.         }
  264.         else
  265.         {
  266.             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  267.             glColor4ub(hdr.watercolor[0], hdr.watercolor[1], hdr.watercolor[2], 102);
  268.         }
  269.         glBegin(GL_QUADS);
  270.         glVertex2i(0, 0);
  271.         glVertex2i(VIRTW, 0);
  272.         glVertex2i(VIRTW, VIRTH);
  273.         glVertex2i(0, VIRTH);
  274.         glEnd();
  275.         glDepthMask(GL_TRUE);
  276.         dblend -= min(1, curtime/3);
  277.         if(dblend<0) dblend = 0;
  278.     }
  279.  
  280.     glEnable(GL_TEXTURE_2D);
  281.  
  282.     bool demo3rd = demoplayback && !localdemoplayer1st();
  283.     playerent *targetplayer = playerincrosshair();
  284.     bool didteamkill = player1->lastteamkill && player1->lastteamkill + 5000 > lastmillis;
  285.     bool menuvisible = rendermenu();
  286.     bool command = getcurcommand() ? true : false;
  287.  
  288.     if(!demo3rd)
  289.     {
  290.         if(player1->state==CS_ALIVE && !player1->reloading && !didteamkill && !menuvisible)
  291.         {
  292.             bool drawteamwarning = targetplayer ? (isteam(targetplayer->team, player1->team) && targetplayer->state!=CS_DEAD) : false;
  293.             if(player1->gunselect==GUN_SNIPER && scoped) drawscope();
  294.             else if((player1->gunselect!=GUN_SNIPER || drawteamwarning)) drawcrosshair(drawteamwarning);
  295.         }
  296.  
  297.         drawequipicons();
  298.  
  299.         glMatrixMode(GL_MODELVIEW);
  300.         if(!hideradar) drawradar(w, h);
  301.         else drawteamicons(w, h);
  302.         glMatrixMode(GL_PROJECTION);
  303.  
  304.         char *infostr = editinfo();
  305.         if(command) rendercommand(20, 1570);
  306.         else if(infostr) draw_text(infostr, 20, 1570);
  307.         else if(targetplayer) draw_text(colorname(targetplayer), 20, 1570);
  308.     }
  309.  
  310.     glLoadIdentity();
  311.     glOrtho(0, VIRTW*2, VIRTH*2, 0, -1, 1);
  312.  
  313.     renderconsole();
  314.     if(command) renderdoc(40, VIRTH);
  315.     if(!hidestats)
  316.     {
  317.         const int left = (VIRTW-225-10)*2, top = (VIRTH*7/8)*2;
  318.         draw_textf("fps %d", left, top, curfps);
  319.         draw_textf("lod %d", left, top+80, lod_factor());
  320.         draw_textf("wqd %d", left, top+160, nquads); 
  321.         draw_textf("wvt %d", left, top+240, curvert);
  322.         draw_textf("evt %d", left, top+320, xtraverts);
  323.     }
  324.     
  325.     if(!hidedemohud && demoplayback)
  326.     {   
  327.         const int left = VIRTW*2/80, top = VIRTH*2*3/4;
  328.         int dmillis = demomillis();
  329.         s_sprintfd(time)("%d:%02d", dmillis/1000/60, dmillis/1000%60);
  330.         s_sprintfd(following)("\f0Following %s", colorname(demoplayer));
  331.  
  332.         draw_text(time, left, top-FONTH);
  333.         draw_text(following, left, top);
  334.         draw_text("jump to pause", left, top+2*FONTH);
  335.         draw_text("attack to change view", left, top+3*FONTH);
  336.         draw_text("reload for slow-motion", left, top+4*FONTH);
  337.     }
  338.  
  339.     if(player1->state==CS_ALIVE && !demo3rd)
  340.     {
  341.         glLoadIdentity();
  342.         glOrtho(0, VIRTW/2, VIRTH/2, 0, -1, 1);
  343.         draw_textf("%d",  90, 827, player1->health);
  344.         if(player1->armour) draw_textf("%d", 390, 827, player1->armour);
  345.         if(player1->gunselect!=GUN_KNIFE)
  346.         {
  347.             char gunstats[64];
  348.             if(player1->gunselect!=GUN_GRENADE) sprintf(gunstats,"%i/%i",player1->mag[player1->gunselect],player1->ammo[player1->gunselect]);
  349.             else sprintf(gunstats,"%i",player1->mag[player1->gunselect]);
  350.             draw_text(gunstats, 690, 827);
  351.         }
  352.  
  353.         if(didteamkill)
  354.         {
  355.             glLoadIdentity();
  356.             glOrtho(0, VIRTW/3, VIRTH/3, 0, -1, 1);
  357.             draw_text("\f3you killed a teammate", VIRTW/3/40, VIRTH/3/2);
  358.         }
  359.  
  360.         if(m_ctf && !hidectfhud)
  361.         {
  362.             glLoadIdentity();
  363.             glOrtho(0, VIRTW, VIRTH, 0, -1, 1);
  364.             glColor4f(1.0f, 1.0f, 1.0f, 0.2f);
  365.             glBlendFunc(GL_SRC_ALPHA, GL_ONE);
  366.  
  367.             loopi(2) // flag state
  368.             {
  369.                 if(flaginfos[i].state == CTFF_INBASE) glDisable(GL_BLEND); else glEnable(GL_BLEND);
  370.                 drawctficon(i*120+VIRTW/4.0f*3.0f, 1650, 120, i, 0, 1/4.0f);
  371.             }
  372.             
  373.             // big flag-stolen icon
  374.             flaginfo &f = flaginfos[team_opposite(team_int(player1->team))];
  375.             if(f.state==CTFF_STOLEN && f.actor == player1 && f.ack)
  376.             {
  377.                 glColor4f(1.0f, 1.0f, 1.0f, (sinf(lastmillis/100.0f)+1.0f) / 2.0f);
  378.                 glEnable(GL_BLEND);
  379.                 drawctficon(VIRTW-225-10, VIRTH*5/8, 225, team_opposite(team_int(player1->team)), 1, 1/2.0f);
  380.                 glDisable(GL_BLEND);
  381.             }
  382.         }
  383.     }
  384.  
  385.     glDisable(GL_BLEND);
  386.     glDisable(GL_TEXTURE_2D);
  387.     glEnable(GL_DEPTH_TEST);
  388.  
  389.     glMatrixMode(GL_MODELVIEW);
  390. }
  391.  
  392. void loadingscreen(const char *fmt, ...)
  393. {
  394.     static Texture *logo = NULL;
  395.     if(!logo) logo = textureload("packages/misc/startscreen.png");
  396.  
  397.     glEnable(GL_TEXTURE_2D);
  398.     glDisable(GL_DEPTH_TEST);
  399.  
  400.     glMatrixMode(GL_PROJECTION);
  401.     glLoadIdentity();
  402.     glOrtho(0, VIRTW, VIRTH, 0, -1, 1);
  403.  
  404.     glMatrixMode(GL_MODELVIEW);
  405.     glLoadIdentity();
  406.  
  407.     glClearColor(0, 0, 0, 1);
  408.     glColor3f(1, 1, 1);
  409.  
  410.     loopi(fmt ? 1 : 2)
  411.     {
  412.         glClear(GL_COLOR_BUFFER_BIT);
  413.         quad(logo->id, (VIRTW-VIRTH)/2, 0, VIRTH, 0, 0, 1);
  414.         if(fmt)
  415.         {
  416.             glEnable(GL_BLEND);
  417.             s_sprintfdlv(str, fmt, fmt);
  418.             int w = text_width(str);
  419.             draw_text(str, w>=VIRTW ? 0 : (VIRTW-w)/2, VIRTH*3/4);
  420.             glDisable(GL_BLEND);
  421.         }
  422.         SDL_GL_SwapBuffers();
  423.     }
  424.  
  425.     glDisable(GL_TEXTURE_2D);
  426.     glEnable(GL_DEPTH_TEST);
  427. }
  428.  
  429. static void bar(float bar, int o, float r, float g, float b)
  430. {
  431.     int side = 50;
  432.     glColor3f(r, g, b);
  433.     glVertex2f(side,                    o*FONTH);
  434.     glVertex2f(bar*(VIRTW-2*side)+side, o*FONTH);
  435.     glVertex2f(bar*(VIRTW-2*side)+side, (o+2)*FONTH);
  436.     glVertex2f(side,                    (o+2)*FONTH);
  437. }
  438.  
  439. void show_out_of_renderloop_progress(float bar1, const char *text1, float bar2, const char *text2)   // also used during loading
  440. {
  441.     c2skeepalive();
  442.  
  443.     glDisable(GL_DEPTH_TEST);
  444.     glMatrixMode(GL_MODELVIEW);
  445.     glPushMatrix();
  446.     glLoadIdentity();
  447.     glMatrixMode(GL_PROJECTION);
  448.     glPushMatrix();
  449.     glLoadIdentity();
  450.     glOrtho(0, VIRTW, VIRTH, 0, -1, 1);
  451.  
  452.     glBegin(GL_QUADS);
  453.  
  454.     if(text1)
  455.     {
  456.         bar(1,    1, 0.1f, 0.1f, 0.1f);
  457.         bar(bar1, 1, 0.2f, 0.2f, 0.2f);
  458.     }
  459.  
  460.     if(bar2>0)
  461.     {
  462.         bar(1,    3, 0.1f, 0.1f, 0.1f);
  463.         bar(bar2, 3, 0.2f, 0.2f, 0.2f);
  464.     }
  465.  
  466.     glEnd();
  467.  
  468.     glEnable(GL_BLEND);
  469.     glEnable(GL_TEXTURE_2D);
  470.  
  471.     if(text1) draw_text(text1, 70, 1*FONTH + FONTH/2);
  472.     if(bar2>0) draw_text(text2, 70, 3*FONTH + FONTH/2);
  473.  
  474.     glDisable(GL_TEXTURE_2D);
  475.     glDisable(GL_BLEND);
  476.  
  477.     glPopMatrix();
  478.     glMatrixMode(GL_MODELVIEW);
  479.     glPopMatrix();
  480.  
  481.     glEnable(GL_DEPTH_TEST);
  482.     SDL_GL_SwapBuffers();
  483. }
  484.  
  485.