Quake II RTX doxygen  1.0 dev
screen.c
Go to the documentation of this file.
1 /*
2 Copyright (C) 1997-2001 Id Software, Inc.
3 
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13 
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18 // cl_scrn.c -- master for refresh, status bar, console, chat, notify, etc
19 
20 #include "client.h"
21 #include "refresh/images.h"
22 
23 #define STAT_PICS 11
24 #define STAT_MINUS (STAT_PICS - 1) // num frame for '-' stats digit
25 
26 static struct {
27  qboolean initialized; // ready to draw
28 
29  qhandle_t crosshair_pic;
31  color_t crosshair_color;
32 
33  qhandle_t pause_pic;
35 
36  qhandle_t loading_pic;
38  qboolean draw_loading;
39 
40  qhandle_t sb_pics[2][STAT_PICS];
41  qhandle_t inven_pic;
42  qhandle_t field_pic;
43 
44  qhandle_t backtile_pic;
45 
46  qhandle_t net_pic;
47  qhandle_t font_pic;
48 
50  float hud_scale;
51  float hud_alpha;
52 } scr;
53 
54 cvar_t *scr_viewsize;
55 static cvar_t *scr_centertime;
56 static cvar_t *scr_showpause;
57 #ifdef _DEBUG
58 static cvar_t *scr_showstats;
59 static cvar_t *scr_showpmove;
60 #endif
61 static cvar_t *scr_showturtle;
62 static cvar_t *scr_showitemname;
63 
64 static cvar_t *scr_draw2d;
65 static cvar_t *scr_lag_x;
66 static cvar_t *scr_lag_y;
67 static cvar_t *scr_lag_draw;
68 static cvar_t *scr_lag_min;
69 static cvar_t *scr_lag_max;
70 static cvar_t *scr_alpha;
71 static cvar_t *scr_fps;
72 
73 static cvar_t *scr_demobar;
74 static cvar_t *scr_font;
75 static cvar_t *scr_scale;
76 
77 static cvar_t *scr_crosshair;
78 
79 static cvar_t *scr_chathud;
80 static cvar_t *scr_chathud_lines;
81 static cvar_t *scr_chathud_time;
82 static cvar_t *scr_chathud_x;
83 static cvar_t *scr_chathud_y;
84 
85 static cvar_t *ch_health;
86 static cvar_t *ch_red;
87 static cvar_t *ch_green;
88 static cvar_t *ch_blue;
89 static cvar_t *ch_alpha;
90 
91 static cvar_t *ch_scale;
92 static cvar_t *ch_x;
93 static cvar_t *ch_y;
94 
95 #ifdef _DEBUG
96 cvar_t *scr_netgraph;
97 cvar_t *scr_timegraph;
98 cvar_t *scr_debuggraph;
99 
100 static cvar_t *scr_graphheight;
101 static cvar_t *scr_graphscale;
102 static cvar_t *scr_graphshift;
103 #endif
104 
105 vrect_t scr_vrect; // position of render window on screen
106 
107 static const char *const sb_nums[2][STAT_PICS] = {
108  {
109  "num_0", "num_1", "num_2", "num_3", "num_4", "num_5",
110  "num_6", "num_7", "num_8", "num_9", "num_minus"
111  },
112  {
113  "anum_0", "anum_1", "anum_2", "anum_3", "anum_4", "anum_5",
114  "anum_6", "anum_7", "anum_8", "anum_9", "anum_minus"
115  }
116 };
117 
118 const uint32_t colorTable[8] = {
119  U32_BLACK, U32_RED, U32_GREEN, U32_YELLOW,
120  U32_BLUE, U32_CYAN, U32_MAGENTA, U32_WHITE
121 };
122 
123 /*
124 ===============================================================================
125 
126 UTILS
127 
128 ===============================================================================
129 */
130 
131 #define SCR_DrawString(x, y, flags, string) \
132  SCR_DrawStringEx(x, y, flags, MAX_STRING_CHARS, string, scr.font_pic)
133 
134 /*
135 ==============
136 SCR_DrawStringEx
137 ==============
138 */
139 int SCR_DrawStringEx(int x, int y, int flags, size_t maxlen,
140  const char *s, qhandle_t font)
141 {
142  size_t len = strlen(s);
143 
144  if (len > maxlen) {
145  len = maxlen;
146  }
147 
148  if ((flags & UI_CENTER) == UI_CENTER) {
149  x -= len * CHAR_WIDTH / 2;
150  } else if (flags & UI_RIGHT) {
151  x -= len * CHAR_WIDTH;
152  }
153 
154  return R_DrawString(x, y, flags, maxlen, s, font);
155 }
156 
157 
158 /*
159 ==============
160 SCR_DrawStringMulti
161 ==============
162 */
163 void SCR_DrawStringMulti(int x, int y, int flags, size_t maxlen,
164  const char *s, qhandle_t font)
165 {
166  char *p;
167  size_t len;
168 
169  while (*s) {
170  p = strchr(s, '\n');
171  if (!p) {
172  SCR_DrawStringEx(x, y, flags, maxlen, s, font);
173  break;
174  }
175 
176  len = p - s;
177  if (len > maxlen) {
178  len = maxlen;
179  }
180  SCR_DrawStringEx(x, y, flags, len, s, font);
181 
182  y += CHAR_HEIGHT;
183  s = p + 1;
184  }
185 }
186 
187 
188 /*
189 =================
190 SCR_FadeAlpha
191 =================
192 */
193 float SCR_FadeAlpha(unsigned startTime, unsigned visTime, unsigned fadeTime)
194 {
195  float alpha;
196  unsigned timeLeft, delta = cls.realtime - startTime;
197 
198  if (delta >= visTime) {
199  return 0;
200  }
201 
202  if (fadeTime > visTime) {
203  fadeTime = visTime;
204  }
205 
206  alpha = 1;
207  timeLeft = visTime - delta;
208  if (timeLeft < fadeTime) {
209  alpha = (float)timeLeft / fadeTime;
210  }
211 
212  return alpha;
213 }
214 
215 qboolean SCR_ParseColor(const char *s, color_t *color)
216 {
217  int i;
218  int c[8];
219 
220  // parse generic color
221  if (*s == '#') {
222  s++;
223  for (i = 0; s[i]; i++) {
224  if (i == 8) {
225  return qfalse;
226  }
227  c[i] = Q_charhex(s[i]);
228  if (c[i] == -1) {
229  return qfalse;
230  }
231  }
232 
233  switch (i) {
234  case 3:
235  color->u8[0] = c[0] | (c[0] << 4);
236  color->u8[1] = c[1] | (c[1] << 4);
237  color->u8[2] = c[2] | (c[2] << 4);
238  color->u8[3] = 255;
239  break;
240  case 6:
241  color->u8[0] = c[1] | (c[0] << 4);
242  color->u8[1] = c[3] | (c[2] << 4);
243  color->u8[2] = c[5] | (c[4] << 4);
244  color->u8[3] = 255;
245  break;
246  case 8:
247  color->u8[0] = c[1] | (c[0] << 4);
248  color->u8[1] = c[3] | (c[2] << 4);
249  color->u8[2] = c[5] | (c[4] << 4);
250  color->u8[3] = c[7] | (c[6] << 4);
251  break;
252  default:
253  return qfalse;
254  }
255 
256  return qtrue;
257  }
258 
259  // parse name or index
260  i = Com_ParseColor(s, COLOR_WHITE);
261  if (i == COLOR_NONE) {
262  return qfalse;
263  }
264 
265  color->u32 = colorTable[i];
266  return qtrue;
267 }
268 
269 /*
270 ===============================================================================
271 
272 BAR GRAPHS
273 
274 ===============================================================================
275 */
276 
277 #ifdef _DEBUG
278 /*
279 ==============
280 CL_AddNetgraph
281 
282 A new packet was just parsed
283 ==============
284 */
285 void CL_AddNetgraph(void)
286 {
287  int i;
288  int in;
289  int ping;
290 
291  if (!scr.initialized)
292  return;
293 
294  // if using the debuggraph for something else, don't
295  // add the net lines
296  if (scr_debuggraph->integer || scr_timegraph->integer)
297  return;
298 
299  for (i = 0; i < cls.netchan->dropped; i++)
300  SCR_DebugGraph(30, 0x40);
301 
302  //for (i=0; i<cl.suppressCount; i++)
303  // SCR_DebugGraph (30, 0xdf);
304 
305  // see what the latency was on this packet
306  in = cls.netchan->incoming_acknowledged & CMD_MASK;
307  ping = cls.realtime - cl.history[in].sent;
308  ping /= 30;
309  if (ping > 30)
310  ping = 30;
311  SCR_DebugGraph(ping, 0xd0);
312 }
313 
314 
315 typedef struct {
316  float value;
317  int color;
318 } graphsamp_t;
319 
320 static int current;
321 static graphsamp_t values[2048];
322 
323 /*
324 ==============
325 SCR_DebugGraph
326 ==============
327 */
328 void SCR_DebugGraph(float value, int color)
329 {
330  values[current & 2047].value = value;
331  values[current & 2047].color = color;
332  current++;
333 }
334 
335 /*
336 ==============
337 SCR_DrawDebugGraph
338 ==============
339 */
340 static void SCR_DrawDebugGraph(void)
341 {
342  int a, x, y, w, i, h;
343  float v;
344  int color;
345 
346  //
347  // draw the graph
348  //
349  w = r_config.width;
350 
351  x = w - 1;
352  y = r_config.height;
353  R_DrawFill8(x, y - scr_graphheight->value,
354  w, scr_graphheight->value, 8);
355 
356  for (a = 0; a < w; a++) {
357  i = (current - 1 - a + 2048) & 2047;
358  v = values[i].value;
359  color = values[i].color;
360  v = v * scr_graphscale->value + scr_graphshift->value;
361 
362  if (v < 0)
363  v += scr_graphheight->value * (1 + (int)(-v / scr_graphheight->value));
364  h = (int)v % (int)scr_graphheight->value;
365  R_DrawFill8(x, y - h, 1, h, color);
366  x--;
367  }
368 }
369 #endif
370 
371 static void draw_percent_bar(int percent, qboolean paused, int framenum)
372 {
373  char buffer[16];
374  int x, w;
375  size_t len;
376 
377  scr.hud_height -= CHAR_HEIGHT;
378 
379  w = scr.hud_width * percent / 100;
380 
381  R_DrawFill8(0, scr.hud_height, w, CHAR_HEIGHT, 4);
382  R_DrawFill8(w, scr.hud_height, scr.hud_width - w, CHAR_HEIGHT, 0);
383 
384  len = Q_scnprintf(buffer, sizeof(buffer), "%d%%", percent);
385  x = (scr.hud_width - len * CHAR_WIDTH) / 2;
386  R_DrawString(x, scr.hud_height, 0, MAX_STRING_CHARS, buffer, scr.font_pic);
387 
388  if (scr_demobar->integer > 1) {
389  int sec = framenum / 10;
390  int min = sec / 60; sec %= 60;
391 
392  Q_scnprintf(buffer, sizeof(buffer), "%d:%02d.%d", min, sec, framenum % 10);
393  R_DrawString(0, scr.hud_height, 0, MAX_STRING_CHARS, buffer, scr.font_pic);
394  }
395 
396  if (paused) {
397  SCR_DrawString(scr.hud_width, scr.hud_height, UI_RIGHT, "[PAUSED]");
398  }
399 }
400 
401 static void SCR_DrawDemo(void)
402 {
403 #if USE_MVD_CLIENT
404  int percent;
405  qboolean paused;
406  int framenum;
407 #endif
408 
409  if (!scr_demobar->integer) {
410  return;
411  }
412 
413  if (cls.demo.playback) {
414  if (cls.demo.file_size) {
417  sv_paused->integer &&
418  cl_paused->integer &&
419  scr_showpause->integer == 2,
421  }
422  return;
423  }
424 
425 #if USE_MVD_CLIENT
426  if (sv_running->integer != ss_broadcast) {
427  return;
428  }
429 
430  if ((percent = MVD_GetDemoPercent(&paused, &framenum)) == -1) {
431  return;
432  }
433 
434  if (sv_paused->integer && cl_paused->integer && scr_showpause->integer == 2) {
435  paused |= qtrue;
436  }
437 
438  draw_percent_bar(percent, paused, framenum);
439 #endif
440 }
441 
442 /*
443 ===============================================================================
444 
445 CENTER PRINTING
446 
447 ===============================================================================
448 */
449 
450 static char scr_centerstring[MAX_STRING_CHARS];
451 static unsigned scr_centertime_start; // for slow victory printing
452 static int scr_center_lines;
453 
454 /*
455 ==============
456 SCR_CenterPrint
457 
458 Called for important messages that should stay in the center of the screen
459 for a few moments
460 ==============
461 */
462 void SCR_CenterPrint(const char *str)
463 {
464  const char *s;
465 
467  if (!strcmp(scr_centerstring, str)) {
468  return;
469  }
470 
472 
473  // count the number of lines for centering
474  scr_center_lines = 1;
475  s = str;
476  while (*s) {
477  if (*s == '\n')
479  s++;
480  }
481 
482  // echo it to the console
483  Com_Printf("%s\n", scr_centerstring);
485 }
486 
487 static void SCR_DrawCenterString(void)
488 {
489  int y;
490  float alpha;
491 
492  Cvar_ClampValue(scr_centertime, 0.3f, 10.0f);
493 
494  alpha = SCR_FadeAlpha(scr_centertime_start, scr_centertime->value * 1000, 300);
495  if (!alpha) {
496  return;
497  }
498 
499  R_SetAlpha(alpha * scr_alpha->value);
500 
501  y = scr.hud_height / 4 - scr_center_lines * 8 / 2;
502 
503  SCR_DrawStringMulti(scr.hud_width / 2, y, UI_CENTER,
504  MAX_STRING_CHARS, scr_centerstring, scr.font_pic);
505 
506  R_SetAlpha(scr_alpha->value);
507 }
508 
509 /*
510 ===============================================================================
511 
512 LAGOMETER
513 
514 ===============================================================================
515 */
516 
517 #define LAG_WIDTH 48
518 #define LAG_HEIGHT 48
519 
520 #define LAG_CRIT_BIT (1 << 31)
521 #define LAG_WARN_BIT (1 << 30)
522 
523 #define LAG_BASE 0xD5
524 #define LAG_WARN 0xDC
525 #define LAG_CRIT 0xF2
526 
527 static struct {
528  unsigned samples[LAG_WIDTH];
529  unsigned head;
530 } lag;
531 
532 void SCR_LagClear(void)
533 {
534  lag.head = 0;
535 }
536 
537 void SCR_LagSample(void)
538 {
539  int i = cls.netchan->incoming_acknowledged & CMD_MASK;
540  client_history_t *h = &cl.history[i];
541  unsigned ping;
542 
543  h->rcvd = cls.realtime;
544  if (!h->cmdNumber || h->rcvd < h->sent) {
545  return;
546  }
547 
548  ping = h->rcvd - h->sent;
549  for (i = 0; i < cls.netchan->dropped; i++) {
550  lag.samples[lag.head % LAG_WIDTH] = ping | LAG_CRIT_BIT;
551  lag.head++;
552  }
553 
554  if (cl.frameflags & FF_SUPPRESSED) {
555  ping |= LAG_WARN_BIT;
556  }
557  lag.samples[lag.head % LAG_WIDTH] = ping;
558  lag.head++;
559 }
560 
561 static void SCR_LagDraw(int x, int y)
562 {
563  int i, j, v, c, v_min, v_max, v_range;
564 
565  v_min = Cvar_ClampInteger(scr_lag_min, 0, LAG_HEIGHT * 10);
566  v_max = Cvar_ClampInteger(scr_lag_max, 0, LAG_HEIGHT * 10);
567 
568  v_range = v_max - v_min;
569  if (v_range < 1)
570  return;
571 
572  for (i = 0; i < LAG_WIDTH; i++) {
573  j = lag.head - i - 1;
574  if (j < 0) {
575  break;
576  }
577 
578  v = lag.samples[j % LAG_WIDTH];
579 
580  if (v & LAG_CRIT_BIT) {
581  c = LAG_CRIT;
582  } else if (v & LAG_WARN_BIT) {
583  c = LAG_WARN;
584  } else {
585  c = LAG_BASE;
586  }
587 
588  v &= ~(LAG_WARN_BIT | LAG_CRIT_BIT);
589  v = (v - v_min) * LAG_HEIGHT / v_range;
590  clamp(v, 0, LAG_HEIGHT);
591 
592  R_DrawFill8(x + LAG_WIDTH - i - 1, y + LAG_HEIGHT - v, 1, v, c);
593  }
594 }
595 
596 static void SCR_DrawNet(void)
597 {
598  int x = scr_lag_x->integer;
599  int y = scr_lag_y->integer;
600 
601  if (x < 0) {
602  x += scr.hud_width - LAG_WIDTH + 1;
603  }
604  if (y < 0) {
605  y += scr.hud_height - LAG_HEIGHT + 1;
606  }
607 
608  // draw ping graph
609  if (scr_lag_draw->integer) {
610  if (scr_lag_draw->integer > 1) {
611  R_DrawFill8(x, y, LAG_WIDTH, LAG_HEIGHT, 4);
612  }
613  SCR_LagDraw(x, y);
614  }
615 
616  // draw phone jack
617  if (cls.netchan && cls.netchan->outgoing_sequence - cls.netchan->incoming_acknowledged >= CMD_BACKUP) {
618  if ((cls.realtime >> 8) & 3) {
619  R_DrawStretchPic(x, y, LAG_WIDTH, LAG_HEIGHT, scr.net_pic);
620  }
621  }
622 }
623 
624 
625 /*
626 ===============================================================================
627 
628 DRAW OBJECTS
629 
630 ===============================================================================
631 */
632 
633 typedef struct {
634  list_t entry;
635  int x, y;
636  cvar_t *cvar;
637  cmd_macro_t *macro;
638  int flags;
639  color_t color;
640 } drawobj_t;
641 
642 #define FOR_EACH_DRAWOBJ(obj) \
643  LIST_FOR_EACH(drawobj_t, obj, &scr_objects, entry)
644 #define FOR_EACH_DRAWOBJ_SAFE(obj, next) \
645  LIST_FOR_EACH_SAFE(drawobj_t, obj, next, &scr_objects, entry)
646 
647 static LIST_DECL(scr_objects);
648 
649 static void SCR_Color_g(genctx_t *ctx)
650 {
651  int color;
652 
653  for (color = 0; color < 10; color++) {
654  if (!Prompt_AddMatch(ctx, colorNames[color])) {
655  break;
656  }
657  }
658 }
659 
660 static void SCR_Draw_c(genctx_t *ctx, int argnum)
661 {
662  if (argnum == 1) {
663  Cvar_Variable_g(ctx);
664  Cmd_Macro_g(ctx);
665  } else if (argnum == 4) {
666  SCR_Color_g(ctx);
667  }
668 }
669 
670 // draw cl_fps -1 80
671 static void SCR_Draw_f(void)
672 {
673  int x, y;
674  const char *s, *c;
675  drawobj_t *obj;
676  cmd_macro_t *macro;
677  cvar_t *cvar;
678  color_t color;
679  int flags;
680  int argc = Cmd_Argc();
681 
682  if (argc == 1) {
683  if (LIST_EMPTY(&scr_objects)) {
684  Com_Printf("No draw strings registered.\n");
685  return;
686  }
687  Com_Printf("Name X Y\n"
688  "--------------- ---- ----\n");
689  FOR_EACH_DRAWOBJ(obj) {
690  s = obj->macro ? obj->macro->name : obj->cvar->name;
691  Com_Printf("%-15s %4d %4d\n", s, obj->x, obj->y);
692  }
693  return;
694  }
695 
696  if (argc < 4) {
697  Com_Printf("Usage: %s <name> <x> <y> [color]\n", Cmd_Argv(0));
698  return;
699  }
700 
701  color.u32 = U32_BLACK;
702  flags = UI_IGNORECOLOR;
703 
704  s = Cmd_Argv(1);
705  x = atoi(Cmd_Argv(2));
706  y = atoi(Cmd_Argv(3));
707 
708  if (x < 0) {
709  flags |= UI_RIGHT;
710  }
711 
712  if (argc > 4) {
713  c = Cmd_Argv(4);
714  if (!strcmp(c, "alt")) {
715  flags |= UI_ALTCOLOR;
716  } else if (strcmp(c, "none")) {
717  if (!SCR_ParseColor(c, &color)) {
718  Com_Printf("Unknown color '%s'\n", c);
719  return;
720  }
721  flags &= ~UI_IGNORECOLOR;
722  }
723  }
724 
725  cvar = NULL;
726  macro = Cmd_FindMacro(s);
727  if (!macro) {
728  cvar = Cvar_WeakGet(s);
729  }
730 
731  FOR_EACH_DRAWOBJ(obj) {
732  if (obj->macro == macro && obj->cvar == cvar) {
733  obj->x = x;
734  obj->y = y;
735  obj->flags = flags;
736  obj->color.u32 = color.u32;
737  return;
738  }
739  }
740 
741  obj = Z_Malloc(sizeof(*obj));
742  obj->x = x;
743  obj->y = y;
744  obj->cvar = cvar;
745  obj->macro = macro;
746  obj->flags = flags;
747  obj->color.u32 = color.u32;
748 
749  List_Append(&scr_objects, &obj->entry);
750 }
751 
752 static void SCR_Draw_g(genctx_t *ctx)
753 {
754  drawobj_t *obj;
755  const char *s;
756 
757  if (LIST_EMPTY(&scr_objects)) {
758  return;
759  }
760 
761  Prompt_AddMatch(ctx, "all");
762 
763  FOR_EACH_DRAWOBJ(obj) {
764  s = obj->macro ? obj->macro->name : obj->cvar->name;
765  if (!Prompt_AddMatch(ctx, s)) {
766  break;
767  }
768  }
769 }
770 
771 static void SCR_UnDraw_c(genctx_t *ctx, int argnum)
772 {
773  if (argnum == 1) {
774  SCR_Draw_g(ctx);
775  }
776 }
777 
778 static void SCR_UnDraw_f(void)
779 {
780  char *s;
781  drawobj_t *obj, *next;
782  cmd_macro_t *macro;
783  cvar_t *cvar;
784 
785  if (Cmd_Argc() != 2) {
786  Com_Printf("Usage: %s <name>\n", Cmd_Argv(0));
787  return;
788  }
789 
790  if (LIST_EMPTY(&scr_objects)) {
791  Com_Printf("No draw strings registered.\n");
792  return;
793  }
794 
795  s = Cmd_Argv(1);
796  if (!strcmp(s, "all")) {
797  FOR_EACH_DRAWOBJ_SAFE(obj, next) {
798  Z_Free(obj);
799  }
800  List_Init(&scr_objects);
801  Com_Printf("Deleted all draw strings.\n");
802  return;
803  }
804 
805  cvar = NULL;
806  macro = Cmd_FindMacro(s);
807  if (!macro) {
808  cvar = Cvar_WeakGet(s);
809  }
810 
811  FOR_EACH_DRAWOBJ_SAFE(obj, next) {
812  if (obj->macro == macro && obj->cvar == cvar) {
813  List_Remove(&obj->entry);
814  Z_Free(obj);
815  return;
816  }
817  }
818 
819  Com_Printf("Draw string '%s' not found.\n", s);
820 }
821 
822 static void SCR_DrawObjects(void)
823 {
824  char buffer[MAX_QPATH];
825  int x, y;
826  drawobj_t *obj;
827 
828  FOR_EACH_DRAWOBJ(obj) {
829  x = obj->x;
830  y = obj->y;
831  if (x < 0) {
832  x += scr.hud_width + 1;
833  }
834  if (y < 0) {
835  y += scr.hud_height - CHAR_HEIGHT + 1;
836  }
837  if (!(obj->flags & UI_IGNORECOLOR)) {
838  R_SetColor(obj->color.u32);
839  }
840  if (obj->macro) {
841  obj->macro->function(buffer, sizeof(buffer));
842  SCR_DrawString(x, y, obj->flags, buffer);
843  } else {
844  SCR_DrawString(x, y, obj->flags, obj->cvar->string);
845  }
846  if (!(obj->flags & UI_IGNORECOLOR)) {
847  R_ClearColor();
848  R_SetAlpha(scr_alpha->value);
849  }
850  }
851 }
852 
853 extern int CL_GetFps();
854 extern int CL_GetResolutionScale();
855 
856 static void SCR_DrawFPS(void)
857 {
858  if (scr_fps->integer == 0)
859  return;
860 
861  int fps = CL_GetFps();
862  int scale = CL_GetResolutionScale();
863 
864  char buffer[MAX_QPATH];
865  if (scr_fps->integer == 2 && vid_rtx->integer)
866  Q_snprintf(buffer, MAX_QPATH, "%d FPS at %3d%%", fps, scale);
867  else
868  Q_snprintf(buffer, MAX_QPATH, "%d FPS", fps);
869 
870  int x = scr.hud_width - 2;
871  int y = 1;
872 
873  R_SetColor(~0u);
874  SCR_DrawString(x, y, UI_RIGHT, buffer);
875 }
876 
877 /*
878 ===============================================================================
879 
880 CHAT HUD
881 
882 ===============================================================================
883 */
884 
885 #define MAX_CHAT_TEXT 150
886 #define MAX_CHAT_LINES 32
887 #define CHAT_LINE_MASK (MAX_CHAT_LINES - 1)
888 
889 typedef struct {
890  char text[MAX_CHAT_TEXT];
891  unsigned time;
892 } chatline_t;
893 
895 static unsigned scr_chathead;
896 
898 {
899  memset(scr_chatlines, 0, sizeof(scr_chatlines));
900  scr_chathead = 0;
901 }
902 
903 void SCR_AddToChatHUD(const char *text)
904 {
905  chatline_t *line;
906  char *p;
907 
909  Q_strlcpy(line->text, text, sizeof(line->text));
910  line->time = cls.realtime;
911 
912  p = strrchr(line->text, '\n');
913  if (p)
914  *p = 0;
915 }
916 
917 static void SCR_DrawChatHUD(void)
918 {
919  int x, y, flags, step;
920  unsigned i, lines, time;
921  float alpha;
922  chatline_t *line;
923 
924  if (scr_chathud->integer == 0)
925  return;
926 
927  x = scr_chathud_x->integer;
928  y = scr_chathud_y->integer;
929 
930  if (scr_chathud->integer == 2)
931  flags = UI_ALTCOLOR;
932  else
933  flags = 0;
934 
935  if (x < 0) {
936  x += scr.hud_width + 1;
937  flags |= UI_RIGHT;
938  } else {
939  flags |= UI_LEFT;
940  }
941 
942  if (y < 0) {
943  y += scr.hud_height - CHAR_HEIGHT + 1;
944  step = -CHAR_HEIGHT;
945  } else {
946  step = CHAR_HEIGHT;
947  }
948 
949  lines = scr_chathud_lines->integer;
950  if (lines > scr_chathead)
951  lines = scr_chathead;
952 
953  time = scr_chathud_time->value * 1000;
954 
955  for (i = 0; i < lines; i++) {
956  line = &scr_chatlines[(scr_chathead - i - 1) & CHAT_LINE_MASK];
957 
958  if (time) {
959  alpha = SCR_FadeAlpha(line->time, time, 1000);
960  if (!alpha)
961  break;
962 
963  R_SetAlpha(alpha * scr_alpha->value);
964  SCR_DrawString(x, y, flags, line->text);
965  R_SetAlpha(scr_alpha->value);
966  } else {
967  SCR_DrawString(x, y, flags, line->text);
968  }
969 
970  y += step;
971  }
972 }
973 
974 /*
975 ===============================================================================
976 
977 DEBUG STUFF
978 
979 ===============================================================================
980 */
981 
982 static void SCR_DrawTurtle(void)
983 {
984  int x, y;
985 
986  if (scr_showturtle->integer <= 0)
987  return;
988 
989  if (!cl.frameflags)
990  return;
991 
992  x = CHAR_WIDTH;
993  y = scr.hud_height - 11 * CHAR_HEIGHT;
994 
995 #define DF(f) \
996  if (cl.frameflags & FF_##f) { \
997  SCR_DrawString(x, y, UI_ALTCOLOR, #f); \
998  y += CHAR_HEIGHT; \
999  }
1000 
1001  if (scr_showturtle->integer > 1) {
1002  DF(SUPPRESSED)
1003  }
1004  DF(CLIENTPRED)
1005  if (scr_showturtle->integer > 1) {
1006  DF(CLIENTDROP)
1007  DF(SERVERDROP)
1008  }
1009  DF(BADFRAME)
1010  DF(OLDFRAME)
1011  DF(OLDENT)
1012  DF(NODELTA)
1013 
1014 #undef DF
1015 }
1016 
1017 #ifdef _DEBUG
1018 
1019 static void SCR_DrawDebugStats(void)
1020 {
1021  char buffer[MAX_QPATH];
1022  int i, j;
1023  int x, y;
1024 
1025  j = scr_showstats->integer;
1026  if (j <= 0)
1027  return;
1028 
1029  if (j > MAX_STATS)
1030  j = MAX_STATS;
1031 
1032  x = CHAR_WIDTH;
1033  y = (scr.hud_height - j * CHAR_HEIGHT) / 2;
1034  for (i = 0; i < j; i++) {
1035  Q_snprintf(buffer, sizeof(buffer), "%2d: %d", i, cl.frame.ps.stats[i]);
1036  if (cl.oldframe.ps.stats[i] != cl.frame.ps.stats[i]) {
1037  R_SetColor(U32_RED);
1038  }
1039  R_DrawString(x, y, 0, MAX_STRING_CHARS, buffer, scr.font_pic);
1040  R_ClearColor();
1041  y += CHAR_HEIGHT;
1042  }
1043 }
1044 
1045 static void SCR_DrawDebugPmove(void)
1046 {
1047  static const char * const types[] = {
1048  "NORMAL", "SPECTATOR", "DEAD", "GIB", "FREEZE"
1049  };
1050  static const char * const flags[] = {
1051  "DUCKED", "JUMP_HELD", "ON_GROUND",
1052  "TIME_WATERJUMP", "TIME_LAND", "TIME_TELEPORT",
1053  "NO_PREDICTION", "TELEPORT_BIT"
1054  };
1055  unsigned i, j;
1056  int x, y;
1057 
1058  if (!scr_showpmove->integer)
1059  return;
1060 
1061  x = CHAR_WIDTH;
1062  y = (scr.hud_height - 2 * CHAR_HEIGHT) / 2;
1063 
1064  i = cl.frame.ps.pmove.pm_type;
1065  if (i > PM_FREEZE)
1066  i = PM_FREEZE;
1067 
1068  R_DrawString(x, y, 0, MAX_STRING_CHARS, types[i], scr.font_pic);
1069  y += CHAR_HEIGHT;
1070 
1071  j = cl.frame.ps.pmove.pm_flags;
1072  for (i = 0; i < 8; i++) {
1073  if (j & (1 << i)) {
1074  x = R_DrawString(x, y, 0, MAX_STRING_CHARS, flags[i], scr.font_pic);
1075  x += CHAR_WIDTH;
1076  }
1077  }
1078 }
1079 
1080 #endif
1081 
1082 //============================================================================
1083 
1084 // Sets scr_vrect, the coordinates of the rendered window
1085 void SCR_CalcVrect(void)
1086 {
1087  scr_vrect.width = scr.hud_width;
1088  scr_vrect.height = scr.hud_height;
1089  scr_vrect.x = 0;
1090  scr_vrect.y = 0;
1091 }
1092 
1093 /*
1094 =================
1095 SCR_SizeUp_f
1096 
1097 Keybinding command
1098 =================
1099 */
1100 static void SCR_SizeUp_f(void)
1101 {
1102  int delta = (scr_viewsize->integer < 100) ? 5 : 10;
1103  Cvar_SetInteger(scr_viewsize, scr_viewsize->integer + delta, FROM_CONSOLE);
1104 }
1105 
1106 /*
1107 =================
1108 SCR_SizeDown_f
1109 
1110 Keybinding command
1111 =================
1112 */
1113 static void SCR_SizeDown_f(void)
1114 {
1115  int delta = (scr_viewsize->integer <= 100) ? 5 : 10;
1116  Cvar_SetInteger(scr_viewsize, scr_viewsize->integer - delta, FROM_CONSOLE);
1117 }
1118 
1119 /*
1120 =================
1121 SCR_Sky_f
1122 
1123 Set a specific sky and rotation speed. If empty sky name is provided, falls
1124 back to server defaults.
1125 =================
1126 */
1127 static void SCR_Sky_f(void)
1128 {
1129  char *name;
1130  float rotate;
1131  vec3_t axis;
1132  int argc = Cmd_Argc();
1133 
1134  if (argc < 2) {
1135  Com_Printf("Usage: sky <basename> [rotate] [axis x y z]\n");
1136  return;
1137  }
1138 
1139  if (cls.state != ca_active) {
1140  Com_Printf("No map loaded.\n");
1141  return;
1142  }
1143 
1144  name = Cmd_Argv(1);
1145  if (!*name) {
1146  CL_SetSky();
1147  return;
1148  }
1149 
1150  if (argc > 2)
1151  rotate = atof(Cmd_Argv(2));
1152  else
1153  rotate = 0;
1154 
1155  if (argc == 6) {
1156  axis[0] = atof(Cmd_Argv(3));
1157  axis[1] = atof(Cmd_Argv(4));
1158  axis[2] = atof(Cmd_Argv(5));
1159  } else
1160  VectorSet(axis, 0, 0, 1);
1161 
1162  R_SetSky(name, rotate, axis);
1163 }
1164 
1165 /*
1166 ================
1167 SCR_TimeRefresh_f
1168 ================
1169 */
1170 static void SCR_TimeRefresh_f(void)
1171 {
1172  int i;
1173  unsigned start, stop;
1174  float time;
1175 
1176  if (cls.state != ca_active) {
1177  Com_Printf("No map loaded.\n");
1178  return;
1179  }
1180 
1181  start = Sys_Milliseconds();
1182 
1183  if (Cmd_Argc() == 2) {
1184  // run without page flipping
1185  R_BeginFrame();
1186  for (i = 0; i < 128; i++) {
1187  cl.refdef.viewangles[1] = i / 128.0f * 360.0f;
1189  }
1190  R_EndFrame();
1191  } else {
1192  for (i = 0; i < 128; i++) {
1193  cl.refdef.viewangles[1] = i / 128.0f * 360.0f;
1194 
1195  R_BeginFrame();
1197  R_EndFrame();
1198  }
1199  }
1200 
1201  stop = Sys_Milliseconds();
1202  time = (stop - start) * 0.001f;
1203  Com_Printf("%f seconds (%f fps)\n", time, 128.0f / time);
1204 }
1205 
1206 
1207 //============================================================================
1208 
1209 static void scr_crosshair_changed(cvar_t *self)
1210 {
1211  char buffer[16];
1212  int w, h;
1213  float scale;
1214 
1215  if (scr_crosshair->integer > 0) {
1216  Q_snprintf(buffer, sizeof(buffer), "ch%i", scr_crosshair->integer);
1217  scr.crosshair_pic = R_RegisterPic(buffer);
1218  R_GetPicSize(&w, &h, scr.crosshair_pic);
1219 
1220  // prescale
1221  scale = Cvar_ClampValue(ch_scale, 0.1f, 9.0f);
1222  scr.crosshair_width = w * scale;
1223  scr.crosshair_height = h * scale;
1224  if (scr.crosshair_width < 1)
1225  scr.crosshair_width = 1;
1226  if (scr.crosshair_height < 1)
1227  scr.crosshair_height = 1;
1228 
1229  if (ch_health->integer) {
1231  } else {
1232  scr.crosshair_color.u8[0] = (byte)(ch_red->value * 255);
1233  scr.crosshair_color.u8[1] = (byte)(ch_green->value * 255);
1234  scr.crosshair_color.u8[2] = (byte)(ch_blue->value * 255);
1235  }
1236  scr.crosshair_color.u8[3] = (byte)(ch_alpha->value * 255);
1237  } else {
1238  scr.crosshair_pic = 0;
1239  }
1240 }
1241 
1243 {
1244  int health;
1245 
1246  if (!ch_health->integer) {
1247  return;
1248  }
1249 
1250  health = cl.frame.ps.stats[STAT_HEALTH];
1251  if (health <= 0) {
1252  VectorSet(scr.crosshair_color.u8, 0, 0, 0);
1253  return;
1254  }
1255 
1256  // red
1257  scr.crosshair_color.u8[0] = 255;
1258 
1259  // green
1260  if (health >= 66) {
1261  scr.crosshair_color.u8[1] = 255;
1262  } else if (health < 33) {
1263  scr.crosshair_color.u8[1] = 0;
1264  } else {
1265  scr.crosshair_color.u8[1] = (255 * (health - 33)) / 33;
1266  }
1267 
1268  // blue
1269  if (health >= 99) {
1270  scr.crosshair_color.u8[2] = 255;
1271  } else if (health < 66) {
1272  scr.crosshair_color.u8[2] = 0;
1273  } else {
1274  scr.crosshair_color.u8[2] = (255 * (health - 66)) / 33;
1275  }
1276 }
1277 
1279 {
1280  IN_Activate();
1281  Con_CheckResize();
1282  UI_ModeChanged();
1283  // video sync flag may have changed
1285  cls.disable_screen = 0;
1286  if (scr.initialized)
1287  scr.hud_scale = R_ClampScale(scr_scale);
1288 
1289  scr.hud_alpha = 1.f;
1290 }
1291 
1292 /*
1293 ==================
1294 SCR_RegisterMedia
1295 ==================
1296 */
1298 {
1299  int i, j;
1300 
1301  for (i = 0; i < 2; i++)
1302  for (j = 0; j < STAT_PICS; j++)
1303  scr.sb_pics[i][j] = R_RegisterPic(sb_nums[i][j]);
1304 
1305  scr.inven_pic = R_RegisterPic("inventory");
1306  scr.field_pic = R_RegisterPic("field_3");
1307 
1308  scr.backtile_pic = R_RegisterImage("backtile", IT_PIC, IF_PERMANENT | IF_REPEAT, NULL);
1309 
1310  scr.pause_pic = R_RegisterPic("pause");
1311  R_GetPicSize(&scr.pause_width, &scr.pause_height, scr.pause_pic);
1312 
1313  scr.loading_pic = R_RegisterPic("loading");
1314  R_GetPicSize(&scr.loading_width, &scr.loading_height, scr.loading_pic);
1315 
1316  scr.net_pic = R_RegisterPic("net");
1317  scr.font_pic = R_RegisterFont(scr_font->string);
1318 
1320 }
1321 
1322 static void scr_font_changed(cvar_t *self)
1323 {
1324  scr.font_pic = R_RegisterFont(self->string);
1325 }
1326 
1327 static void scr_scale_changed(cvar_t *self)
1328 {
1329  scr.hud_scale = R_ClampScale(self);
1330 }
1331 
1332 static const cmdreg_t scr_cmds[] = {
1333  { "timerefresh", SCR_TimeRefresh_f },
1334  { "sizeup", SCR_SizeUp_f },
1335  { "sizedown", SCR_SizeDown_f },
1336  { "sky", SCR_Sky_f },
1337  { "draw", SCR_Draw_f, SCR_Draw_c },
1338  { "undraw", SCR_UnDraw_f, SCR_UnDraw_c },
1339  { "clearchathud", SCR_ClearChatHUD_f },
1340  { NULL }
1341 };
1342 
1343 /*
1344 ==================
1345 SCR_Init
1346 ==================
1347 */
1348 void SCR_Init(void)
1349 {
1350  scr_viewsize = Cvar_Get("viewsize", "100", CVAR_ARCHIVE);
1351  scr_showpause = Cvar_Get("scr_showpause", "1", 0);
1352  scr_centertime = Cvar_Get("scr_centertime", "2.5", 0);
1353 #ifdef _DEBUG
1354  scr_netgraph = Cvar_Get("netgraph", "0", 0);
1355  scr_timegraph = Cvar_Get("timegraph", "0", 0);
1356  scr_debuggraph = Cvar_Get("debuggraph", "0", 0);
1357  scr_graphheight = Cvar_Get("graphheight", "32", 0);
1358  scr_graphscale = Cvar_Get("graphscale", "1", 0);
1359  scr_graphshift = Cvar_Get("graphshift", "0", 0);
1360 #endif
1361  scr_demobar = Cvar_Get("scr_demobar", "1", 0);
1362  scr_font = Cvar_Get("scr_font", "conchars", 0);
1363  scr_font->changed = scr_font_changed;
1364  scr_scale = Cvar_Get("scr_scale", "2", 0);
1365  scr_scale->changed = scr_scale_changed;
1366  scr_crosshair = Cvar_Get("crosshair", "0", CVAR_ARCHIVE);
1368 
1369  scr_chathud = Cvar_Get("scr_chathud", "0", 0);
1370  scr_chathud_lines = Cvar_Get("scr_chathud_lines", "4", 0);
1371  scr_chathud_time = Cvar_Get("scr_chathud_time", "0", 0);
1372  scr_chathud_x = Cvar_Get("scr_chathud_x", "8", 0);
1373  scr_chathud_y = Cvar_Get("scr_chathud_y", "-64", 0);
1374 
1375  ch_health = Cvar_Get("ch_health", "0", 0);
1376  ch_health->changed = scr_crosshair_changed;
1377  ch_red = Cvar_Get("ch_red", "1", 0);
1378  ch_red->changed = scr_crosshair_changed;
1379  ch_green = Cvar_Get("ch_green", "1", 0);
1380  ch_green->changed = scr_crosshair_changed;
1381  ch_blue = Cvar_Get("ch_blue", "1", 0);
1382  ch_blue->changed = scr_crosshair_changed;
1383  ch_alpha = Cvar_Get("ch_alpha", "1", 0);
1384  ch_alpha->changed = scr_crosshair_changed;
1385 
1386  ch_scale = Cvar_Get("ch_scale", "1", 0);
1387  ch_scale->changed = scr_crosshair_changed;
1388  ch_x = Cvar_Get("ch_x", "0", 0);
1389  ch_y = Cvar_Get("ch_y", "0", 0);
1390 
1391  scr_draw2d = Cvar_Get("scr_draw2d", "2", 0);
1392  scr_showturtle = Cvar_Get("scr_showturtle", "1", 0);
1393  scr_showitemname = Cvar_Get("scr_showitemname", "1", CVAR_ARCHIVE);
1394  scr_lag_x = Cvar_Get("scr_lag_x", "-1", 0);
1395  scr_lag_y = Cvar_Get("scr_lag_y", "-1", 0);
1396  scr_lag_draw = Cvar_Get("scr_lag_draw", "0", 0);
1397  scr_lag_min = Cvar_Get("scr_lag_min", "0", 0);
1398  scr_lag_max = Cvar_Get("scr_lag_max", "200", 0);
1399  scr_alpha = Cvar_Get("scr_alpha", "1", 0);
1400  scr_fps = Cvar_Get("scr_fps", "0", CVAR_ARCHIVE);
1401 #ifdef _DEBUG
1402  scr_showstats = Cvar_Get("scr_showstats", "0", 0);
1403  scr_showpmove = Cvar_Get("scr_showpmove", "0", 0);
1404 #endif
1405 
1407 
1409 
1410  scr.initialized = qtrue;
1411 }
1412 
1413 void SCR_Shutdown(void)
1414 {
1416  scr.initialized = qfalse;
1417 }
1418 
1419 /*
1420 ================
1421 SCR_BeginLoadingPlaque
1422 ================
1423 */
1425 {
1426  if (!cls.state) {
1427  return;
1428  }
1429 
1430  if (cls.disable_screen) {
1431  return;
1432  }
1433 
1434 #ifdef _DEBUG
1435  if (developer->integer) {
1436  return;
1437  }
1438 #endif
1439 
1440  // if at console or menu, don't bring up the plaque
1441  if (cls.key_dest & (KEY_CONSOLE | KEY_MENU)) {
1442  return;
1443  }
1444 
1445  scr.draw_loading = qtrue;
1446  SCR_UpdateScreen();
1447 
1449 }
1450 
1451 /*
1452 ================
1453 SCR_EndLoadingPlaque
1454 ================
1455 */
1457 {
1458  if (!cls.state) {
1459  return;
1460  }
1461  cls.disable_screen = 0;
1463 }
1464 
1465 // Clear any parts of the tiled background that were drawn on last frame
1466 static void SCR_TileClear(void)
1467 {
1468 }
1469 
1470 /*
1471 ===============================================================================
1472 
1473 STAT PROGRAMS
1474 
1475 ===============================================================================
1476 */
1477 
1478 #define ICON_WIDTH 24
1479 #define ICON_HEIGHT 24
1480 #define DIGIT_WIDTH 16
1481 #define ICON_SPACE 8
1482 
1483 #define HUD_DrawString(x, y, string) \
1484  R_DrawString(x, y, 0, MAX_STRING_CHARS, string, scr.font_pic)
1485 
1486 #define HUD_DrawAltString(x, y, string) \
1487  R_DrawString(x, y, UI_XORCOLOR, MAX_STRING_CHARS, string, scr.font_pic)
1488 
1489 #define HUD_DrawCenterString(x, y, string) \
1490  SCR_DrawStringMulti(x, y, UI_CENTER, MAX_STRING_CHARS, string, scr.font_pic)
1491 
1492 #define HUD_DrawAltCenterString(x, y, string) \
1493  SCR_DrawStringMulti(x, y, UI_CENTER | UI_XORCOLOR, MAX_STRING_CHARS, string, scr.font_pic)
1494 
1495 static void HUD_DrawNumber(int x, int y, int color, int width, int value)
1496 {
1497  char num[16], *ptr;
1498  int l;
1499  int frame;
1500 
1501  if (width < 1)
1502  return;
1503 
1504  // draw number string
1505  if (width > 5)
1506  width = 5;
1507 
1508  color &= 1;
1509 
1510  l = Q_scnprintf(num, sizeof(num), "%i", value);
1511  if (l > width)
1512  l = width;
1513  x += 2 + DIGIT_WIDTH * (width - l);
1514 
1515  ptr = num;
1516  while (*ptr && l) {
1517  if (*ptr == '-')
1518  frame = STAT_MINUS;
1519  else
1520  frame = *ptr - '0';
1521 
1522  R_DrawPic(x, y, scr.sb_pics[color][frame]);
1523  x += DIGIT_WIDTH;
1524  ptr++;
1525  l--;
1526  }
1527 }
1528 
1529 #define DISPLAY_ITEMS 17
1530 
1531 static void SCR_DrawInventory(void)
1532 {
1533  int i;
1534  int num, selected_num, item;
1535  int index[MAX_ITEMS];
1536  char string[MAX_STRING_CHARS];
1537  int x, y;
1538  char *bind;
1539  int selected;
1540  int top;
1541 
1542  if (!(cl.frame.ps.stats[STAT_LAYOUTS] & 2))
1543  return;
1544 
1545  selected = cl.frame.ps.stats[STAT_SELECTED_ITEM];
1546 
1547  num = 0;
1548  selected_num = 0;
1549  for (i = 0; i < MAX_ITEMS; i++) {
1550  if (i == selected) {
1551  selected_num = num;
1552  }
1553  if (cl.inventory[i]) {
1554  index[num++] = i;
1555  }
1556  }
1557 
1558  // determine scroll point
1559  top = selected_num - DISPLAY_ITEMS / 2;
1560  if (top > num - DISPLAY_ITEMS) {
1561  top = num - DISPLAY_ITEMS;
1562  }
1563  if (top < 0) {
1564  top = 0;
1565  }
1566 
1567  x = (scr.hud_width - 256) / 2;
1568  y = (scr.hud_height - 240) / 2;
1569 
1570  R_DrawPic(x, y + 8, scr.inven_pic);
1571  y += 24;
1572  x += 24;
1573 
1574  HUD_DrawString(x, y, "hotkey ### item");
1575  y += CHAR_HEIGHT;
1576 
1577  HUD_DrawString(x, y, "------ --- ----");
1578  y += CHAR_HEIGHT;
1579 
1580  for (i = top; i < num && i < top + DISPLAY_ITEMS; i++) {
1581  item = index[i];
1582  // search for a binding
1583  Q_concat(string, sizeof(string),
1584  "use ", cl.configstrings[CS_ITEMS + item], NULL);
1585  bind = Key_GetBinding(string);
1586 
1587  Q_snprintf(string, sizeof(string), "%6s %3i %s",
1588  bind, cl.inventory[item], cl.configstrings[CS_ITEMS + item]);
1589 
1590  if (item != selected) {
1591  HUD_DrawAltString(x, y, string);
1592  } else { // draw a blinky cursor by the selected item
1593  HUD_DrawString(x, y, string);
1594  if ((cls.realtime >> 8) & 1) {
1595  R_DrawChar(x - CHAR_WIDTH, y, 0, 15, scr.font_pic);
1596  }
1597  }
1598 
1599  y += CHAR_HEIGHT;
1600  }
1601 }
1602 
1603 static void SCR_DrawSelectedItemName(int x, int y, int item)
1604 {
1605  static int display_item = -1;
1606  static int display_start_time = 0;
1607 
1608  float duration = 0.f;
1609  if (display_item != item)
1610  {
1611  display_start_time = Sys_Milliseconds();
1612  display_item = item;
1613  }
1614  else
1615  {
1616  duration = (float)(Sys_Milliseconds() - display_start_time) * 0.001f;
1617  }
1618 
1619  float alpha;
1620  if (scr_showitemname->integer < 2)
1621  alpha = max(0.f, min(1.f, 5.f - 4.f * duration)); // show and hide
1622  else
1623  alpha = 1; // always show
1624 
1625  if (alpha > 0.f)
1626  {
1627  R_SetAlpha(alpha * scr_alpha->value);
1628 
1629  int index = CS_ITEMS + item;
1630  HUD_DrawString(x, y, cl.configstrings[index]);
1631 
1632  R_SetAlpha(scr_alpha->value);
1633  }
1634 }
1635 
1636 static void SCR_ExecuteLayoutString(const char *s)
1637 {
1638  char buffer[MAX_QPATH];
1639  int x, y;
1640  int value;
1641  char *token;
1642  int width;
1643  int index;
1644  clientinfo_t *ci;
1645 
1646  if (!s[0])
1647  return;
1648 
1649  x = 0;
1650  y = 0;
1651 
1652  while (s) {
1653  token = COM_Parse(&s);
1654  if (token[2] == 0) {
1655  if (token[0] == 'x') {
1656  if (token[1] == 'l') {
1657  token = COM_Parse(&s);
1658  x = atoi(token);
1659  continue;
1660  }
1661 
1662  if (token[1] == 'r') {
1663  token = COM_Parse(&s);
1664  x = scr.hud_width + atoi(token);
1665  continue;
1666  }
1667 
1668  if (token[1] == 'v') {
1669  token = COM_Parse(&s);
1670  x = scr.hud_width / 2 - 160 + atoi(token);
1671  continue;
1672  }
1673  }
1674 
1675  if (token[0] == 'y') {
1676  if (token[1] == 't') {
1677  token = COM_Parse(&s);
1678  y = atoi(token);
1679  continue;
1680  }
1681 
1682  if (token[1] == 'b') {
1683  token = COM_Parse(&s);
1684  y = scr.hud_height + atoi(token);
1685  continue;
1686  }
1687 
1688  if (token[1] == 'v') {
1689  token = COM_Parse(&s);
1690  y = scr.hud_height / 2 - 120 + atoi(token);
1691  continue;
1692  }
1693  }
1694  }
1695 
1696  if (!strcmp(token, "pic")) {
1697  // draw a pic from a stat number
1698  token = COM_Parse(&s);
1699  value = atoi(token);
1700  if (value < 0 || value >= MAX_STATS) {
1701  Com_Error(ERR_DROP, "%s: invalid stat index", __func__);
1702  }
1703  index = cl.frame.ps.stats[value];
1704  if (index < 0 || index >= MAX_IMAGES) {
1705  Com_Error(ERR_DROP, "%s: invalid pic index", __func__);
1706  }
1707  token = cl.configstrings[CS_IMAGES + index];
1708  if (token[0] && cl.image_precache[index]) {
1709  R_DrawPic(x, y, cl.image_precache[index]);
1710  }
1711 
1712  if (value == STAT_SELECTED_ICON && scr_showitemname->integer)
1713  {
1714  SCR_DrawSelectedItemName(x + 32, y + 8, cl.frame.ps.stats[STAT_SELECTED_ITEM]);
1715  }
1716  continue;
1717  }
1718 
1719  if (!strcmp(token, "client")) {
1720  // draw a deathmatch client block
1721  int score, ping, time;
1722 
1723  token = COM_Parse(&s);
1724  x = scr.hud_width / 2 - 160 + atoi(token);
1725  token = COM_Parse(&s);
1726  y = scr.hud_height / 2 - 120 + atoi(token);
1727 
1728  token = COM_Parse(&s);
1729  value = atoi(token);
1730  if (value < 0 || value >= MAX_CLIENTS) {
1731  Com_Error(ERR_DROP, "%s: invalid client index", __func__);
1732  }
1733  ci = &cl.clientinfo[value];
1734 
1735  token = COM_Parse(&s);
1736  score = atoi(token);
1737 
1738  token = COM_Parse(&s);
1739  ping = atoi(token);
1740 
1741  token = COM_Parse(&s);
1742  time = atoi(token);
1743 
1744  HUD_DrawAltString(x + 32, y, ci->name);
1745  HUD_DrawString(x + 32, y + CHAR_HEIGHT, "Score: ");
1746  Q_snprintf(buffer, sizeof(buffer), "%i", score);
1747  HUD_DrawAltString(x + 32 + 7 * CHAR_WIDTH, y + CHAR_HEIGHT, buffer);
1748  Q_snprintf(buffer, sizeof(buffer), "Ping: %i", ping);
1749  HUD_DrawString(x + 32, y + 2 * CHAR_HEIGHT, buffer);
1750  Q_snprintf(buffer, sizeof(buffer), "Time: %i", time);
1751  HUD_DrawString(x + 32, y + 3 * CHAR_HEIGHT, buffer);
1752 
1753  if (!ci->icon) {
1754  ci = &cl.baseclientinfo;
1755  }
1756  R_DrawPic(x, y, ci->icon);
1757  continue;
1758  }
1759 
1760  if (!strcmp(token, "ctf")) {
1761  // draw a ctf client block
1762  int score, ping;
1763 
1764  token = COM_Parse(&s);
1765  x = scr.hud_width / 2 - 160 + atoi(token);
1766  token = COM_Parse(&s);
1767  y = scr.hud_height / 2 - 120 + atoi(token);
1768 
1769  token = COM_Parse(&s);
1770  value = atoi(token);
1771  if (value < 0 || value >= MAX_CLIENTS) {
1772  Com_Error(ERR_DROP, "%s: invalid client index", __func__);
1773  }
1774  ci = &cl.clientinfo[value];
1775 
1776  token = COM_Parse(&s);
1777  score = atoi(token);
1778 
1779  token = COM_Parse(&s);
1780  ping = atoi(token);
1781  if (ping > 999)
1782  ping = 999;
1783 
1784  Q_snprintf(buffer, sizeof(buffer), "%3d %3d %-12.12s",
1785  score, ping, ci->name);
1786  if (value == cl.frame.clientNum) {
1787  HUD_DrawAltString(x, y, buffer);
1788  } else {
1789  HUD_DrawString(x, y, buffer);
1790  }
1791  continue;
1792  }
1793 
1794  if (!strcmp(token, "picn")) {
1795  // draw a pic from a name
1796  token = COM_Parse(&s);
1797  R_DrawPic(x, y, R_RegisterPic2(token));
1798  continue;
1799  }
1800 
1801  if (!strcmp(token, "num")) {
1802  // draw a number
1803  token = COM_Parse(&s);
1804  width = atoi(token);
1805  token = COM_Parse(&s);
1806  value = atoi(token);
1807  if (value < 0 || value >= MAX_STATS) {
1808  Com_Error(ERR_DROP, "%s: invalid stat index", __func__);
1809  }
1810  value = cl.frame.ps.stats[value];
1811  HUD_DrawNumber(x, y, 0, width, value);
1812  continue;
1813  }
1814 
1815  if (!strcmp(token, "hnum")) {
1816  // health number
1817  int color;
1818 
1819  width = 3;
1820  value = cl.frame.ps.stats[STAT_HEALTH];
1821  if (value > 25)
1822  color = 0; // green
1823  else if (value > 0)
1824  color = ((cl.frame.number / CL_FRAMEDIV) >> 2) & 1; // flash
1825  else
1826  color = 1;
1827 
1828  if (cl.frame.ps.stats[STAT_FLASHES] & 1)
1829  R_DrawPic(x, y, scr.field_pic);
1830 
1831  HUD_DrawNumber(x, y, color, width, value);
1832  continue;
1833  }
1834 
1835  if (!strcmp(token, "anum")) {
1836  // ammo number
1837  int color;
1838 
1839  width = 3;
1840  value = cl.frame.ps.stats[STAT_AMMO];
1841  if (value > 5)
1842  color = 0; // green
1843  else if (value >= 0)
1844  color = ((cl.frame.number / CL_FRAMEDIV) >> 2) & 1; // flash
1845  else
1846  continue; // negative number = don't show
1847 
1848  if (cl.frame.ps.stats[STAT_FLASHES] & 4)
1849  R_DrawPic(x, y, scr.field_pic);
1850 
1851  HUD_DrawNumber(x, y, color, width, value);
1852  continue;
1853  }
1854 
1855  if (!strcmp(token, "rnum")) {
1856  // armor number
1857  int color;
1858 
1859  width = 3;
1860  value = cl.frame.ps.stats[STAT_ARMOR];
1861  if (value < 1)
1862  continue;
1863 
1864  color = 0; // green
1865 
1866  if (cl.frame.ps.stats[STAT_FLASHES] & 2)
1867  R_DrawPic(x, y, scr.field_pic);
1868 
1869  HUD_DrawNumber(x, y, color, width, value);
1870  continue;
1871  }
1872 
1873  if (!strcmp(token, "stat_string")) {
1874  token = COM_Parse(&s);
1875  index = atoi(token);
1876  if (index < 0 || index >= MAX_STATS) {
1877  Com_Error(ERR_DROP, "%s: invalid stat index", __func__);
1878  }
1879  index = cl.frame.ps.stats[index];
1880  if (index < 0 || index >= MAX_CONFIGSTRINGS) {
1881  Com_Error(ERR_DROP, "%s: invalid string index", __func__);
1882  }
1883  HUD_DrawString(x, y, cl.configstrings[index]);
1884  continue;
1885  }
1886 
1887  if (!strcmp(token, "cstring")) {
1888  token = COM_Parse(&s);
1889  HUD_DrawCenterString(x + 320 / 2, y, token);
1890  continue;
1891  }
1892 
1893  if (!strcmp(token, "cstring2")) {
1894  token = COM_Parse(&s);
1895  HUD_DrawAltCenterString(x + 320 / 2, y, token);
1896  continue;
1897  }
1898 
1899  if (!strcmp(token, "string")) {
1900  token = COM_Parse(&s);
1901  HUD_DrawString(x, y, token);
1902  continue;
1903  }
1904 
1905  if (!strcmp(token, "string2")) {
1906  token = COM_Parse(&s);
1907  HUD_DrawAltString(x, y, token);
1908  continue;
1909  }
1910 
1911  if (!strcmp(token, "if")) {
1912  token = COM_Parse(&s);
1913  value = atoi(token);
1914  if (value < 0 || value >= MAX_STATS) {
1915  Com_Error(ERR_DROP, "%s: invalid stat index", __func__);
1916  }
1917  value = cl.frame.ps.stats[value];
1918  if (!value) { // skip to endif
1919  while (strcmp(token, "endif")) {
1920  token = COM_Parse(&s);
1921  if (!s) {
1922  break;
1923  }
1924  }
1925  }
1926  continue;
1927  }
1928 
1929  if (!strcmp(token, "color")) {
1930  color_t color;
1931 
1932  token = COM_Parse(&s);
1933  if (SCR_ParseColor(token, &color)) {
1934  color.u8[3] *= scr_alpha->value;
1935  R_SetColor(color.u32);
1936  }
1937  continue;
1938  }
1939  }
1940 
1941  R_ClearColor();
1942  R_SetAlpha(scr_alpha->value);
1943 }
1944 
1945 //=============================================================================
1946 
1947 static void SCR_DrawPause(void)
1948 {
1949  int x, y;
1950 
1951  if (!sv_paused->integer)
1952  return;
1953  if (!cl_paused->integer)
1954  return;
1955  if (scr_showpause->integer != 1)
1956  return;
1957 
1958  x = (scr.hud_width - scr.pause_width) / 2;
1959  y = (scr.hud_height - scr.pause_height) / 2;
1960 
1961  R_DrawPic(x, y, scr.pause_pic);
1962 }
1963 
1964 static void SCR_DrawLoading(void)
1965 {
1966  int x, y;
1967 
1968  if (!scr.draw_loading)
1969  return;
1970 
1971  scr.draw_loading = qfalse;
1972 
1973  R_SetScale(scr.hud_scale);
1974 
1975  x = (r_config.width * scr.hud_scale - scr.loading_width) / 2;
1976  y = (r_config.height * scr.hud_scale - scr.loading_height) / 2;
1977 
1978  R_DrawPic(x, y, scr.loading_pic);
1979 
1980  R_SetScale(1.0f);
1981 }
1982 
1983 static void SCR_DrawCrosshair(void)
1984 {
1985  int x, y;
1986 
1987  if (!scr_crosshair->integer)
1988  return;
1989 
1990  x = (scr.hud_width - scr.crosshair_width) / 2;
1991  y = (scr.hud_height - scr.crosshair_height) / 2;
1992 
1993  R_SetColor(scr.crosshair_color.u32);
1994 
1995  R_DrawStretchPic(x + ch_x->integer,
1996  y + ch_y->integer,
1997  scr.crosshair_width,
1998  scr.crosshair_height,
1999  scr.crosshair_pic);
2000 }
2001 
2002 // The status bar is a small layout program that is based on the stats array
2003 static void SCR_DrawStats(void)
2004 {
2005  if (scr_draw2d->integer <= 1)
2006  return;
2007 
2008  SCR_ExecuteLayoutString(cl.configstrings[CS_STATUSBAR]);
2009 }
2010 
2011 static void SCR_DrawLayout(void)
2012 {
2013  if (scr_draw2d->integer == 3 && !Key_IsDown(K_F1))
2014  return; // turn off for GTV
2015 
2016  if (cls.demo.playback && Key_IsDown(K_F1))
2017  goto draw;
2018 
2019  if (!(cl.frame.ps.stats[STAT_LAYOUTS] & 1))
2020  return;
2021 
2022 draw:
2024 }
2025 
2026 static void SCR_Draw2D(void)
2027 {
2028  if (scr_draw2d->integer <= 0)
2029  return; // turn off for screenshots
2030 
2031  if (cls.key_dest & KEY_MENU)
2032  return;
2033 
2034  R_SetAlphaScale(scr.hud_alpha);
2035 
2036  R_SetScale(scr.hud_scale);
2037 
2038  scr.hud_height *= scr.hud_scale;
2039  scr.hud_width *= scr.hud_scale;
2040 
2041  // crosshair has its own color and alpha
2043 
2044  // the rest of 2D elements share common alpha
2045  R_ClearColor();
2047 
2048  SCR_DrawStats();
2049 
2050  SCR_DrawLayout();
2051 
2053 
2055 
2056  SCR_DrawNet();
2057 
2058  SCR_DrawObjects();
2059 
2060  SCR_DrawFPS();
2061 
2062  SCR_DrawChatHUD();
2063 
2064  SCR_DrawTurtle();
2065 
2066  SCR_DrawPause();
2067 
2068  // debug stats have no alpha
2069  R_ClearColor();
2070 
2071 #ifdef _DEBUG
2072  SCR_DrawDebugStats();
2073  SCR_DrawDebugPmove();
2074 #endif
2075 
2076  R_SetScale(1.0f);
2077  R_SetAlphaScale(1.0f);
2078 }
2079 
2080 static void SCR_DrawActive(void)
2081 {
2082  // if full screen menu is up, do nothing at all
2083  if (!UI_IsTransparent())
2084  return;
2085 
2086  // draw black background if not active
2087  if (cls.state < ca_active) {
2088  R_DrawFill8(0, 0, r_config.width, r_config.height, 0);
2089  return;
2090  }
2091 
2092  if (cls.state == ca_cinematic) {
2093  if (cl.image_precache[0])
2094  {
2095  // scale the image to touch the screen from inside, keeping the aspect ratio
2096 
2097  image_t* image = IMG_ForHandle(cl.image_precache[0]);
2098 
2099  float zoomx = (float)r_config.width / (float)image->width;
2100  float zoomy = (float)r_config.height / (float)image->height;
2101  float zoom = min(zoomx, zoomy);
2102 
2103  int w = (int)(image->width * zoom);
2104  int h = (int)(image->height * zoom);
2105  int x = (r_config.width - w) / 2;
2106  int y = (r_config.height - h) / 2;
2107 
2108  R_DrawFill8(0, 0, r_config.width, r_config.height, 0);
2109  R_DrawStretchPic(x, y, w, h, cl.image_precache[0]);
2110  }
2111  return;
2112  }
2113 
2114  // start with full screen HUD
2115  scr.hud_height = r_config.height;
2116  scr.hud_width = r_config.width;
2117 
2118  SCR_DrawDemo();
2119 
2120  SCR_CalcVrect();
2121 
2122  // clear any dirty part of the background
2123  SCR_TileClear();
2124 
2125  // draw 3D game view
2126  V_RenderView();
2127 
2128  // draw all 2D elements
2129  SCR_Draw2D();
2130 }
2131 
2132 //=======================================================
2133 
2134 /*
2135 ==================
2136 SCR_UpdateScreen
2137 
2138 This is called every frame, and can also be called explicitly to flush
2139 text to the screen.
2140 ==================
2141 */
2143 {
2144  static int recursive;
2145 
2146  if (!scr.initialized) {
2147  return; // not initialized yet
2148  }
2149 
2150  // if the screen is disabled (loading plaque is up), do nothing at all
2151  if (cls.disable_screen) {
2152  unsigned delta = Sys_Milliseconds() - cls.disable_screen;
2153 
2154  if (delta < 120 * 1000) {
2155  return;
2156  }
2157 
2158  cls.disable_screen = 0;
2159  Com_Printf("Loading plaque timed out.\n");
2160  }
2161 
2162  if (recursive > 1) {
2163  Com_Error(ERR_FATAL, "%s: recursively called", __func__);
2164  }
2165 
2166  recursive++;
2167 
2168  R_BeginFrame();
2169 
2170  // do 3D refresh drawing
2171  SCR_DrawActive();
2172 
2173  // draw main menu
2174  UI_Draw(cls.realtime);
2175 
2176  // draw console
2177  Con_DrawConsole();
2178 
2179  // draw loading plaque
2180  SCR_DrawLoading();
2181 
2182 #ifdef _DEBUG
2183  // draw debug graphs
2184  if (scr_timegraph->integer)
2185  SCR_DebugGraph(cls.frametime * 300, 0);
2186 
2187  if (scr_debuggraph->integer || scr_timegraph->integer || scr_netgraph->integer)
2188  SCR_DrawDebugGraph();
2189 #endif
2190 
2191  R_EndFrame();
2192 
2193  recursive--;
2194 }
2195 
2196 qhandle_t SCR_GetFont(void)
2197 {
2198  return scr.font_pic;
2199 }
2200 
2201 void SCR_SetHudAlpha(float alpha)
2202 {
2203  scr.hud_alpha = alpha;
2204 }
Com_ParseColor
color_index_t Com_ParseColor(const char *s, color_index_t last)
Definition: utils.c:204
scr_lag_x
static cvar_t * scr_lag_x
Definition: screen.c:65
scr_scale_changed
static void scr_scale_changed(cvar_t *self)
Definition: screen.c:1327
client_state_s::frame
server_frame_t frame
Definition: client.h:212
SCR_ModeChanged
void SCR_ModeChanged(void)
Definition: screen.c:1278
R_RegisterImage
qhandle_t R_RegisterImage(const char *name, imagetype_t type, imageflags_t flags, qerror_t *err_p)
Definition: images.c:1170
LAG_HEIGHT
#define LAG_HEIGHT
Definition: screen.c:518
client_state_s::configstrings
char configstrings[MAX_CONFIGSTRINGS][MAX_QPATH]
Definition: client.h:289
client_state_s::inventory
int inventory[MAX_ITEMS]
Definition: client.h:270
sb_pics
qhandle_t sb_pics[2][STAT_PICS]
Definition: screen.c:40
CL_SetSky
void CL_SetSky(void)
Definition: precache.c:306
colorTable
const uint32_t colorTable[8]
Definition: screen.c:118
SCR_AddToChatHUD
void SCR_AddToChatHUD(const char *text)
Definition: screen.c:903
R_SetColor
void(* R_SetColor)(uint32_t color)
Definition: refresh.c:413
MAX_CHAT_TEXT
#define MAX_CHAT_TEXT
Definition: screen.c:885
client_state_s::image_precache
qhandle_t image_precache[MAX_IMAGES]
Definition: client.h:306
crosshair_color
color_t crosshair_color
Definition: screen.c:31
SCR_DrawDemo
static void SCR_DrawDemo(void)
Definition: screen.c:401
client_static_s::playback
qhandle_t playback
Definition: client.h:453
R_SetSky
void(* R_SetSky)(const char *name, float rotate, vec3_t axis)
Definition: refresh.c:406
drawobj_t::x
int x
Definition: screen.c:635
R_SetAlpha
void(* R_SetAlpha)(float clpha)
Definition: refresh.c:411
HUD_DrawNumber
static void HUD_DrawNumber(int x, int y, int color, int width, int value)
Definition: screen.c:1495
SCR_DrawString
#define SCR_DrawString(x, y, flags, string)
Definition: screen.c:131
scr_lag_max
static cvar_t * scr_lag_max
Definition: screen.c:69
Q_snprintf
size_t Q_snprintf(char *dest, size_t size, const char *fmt,...)
Definition: shared.c:846
scr
static struct @4 scr
SCR_DrawTurtle
static void SCR_DrawTurtle(void)
Definition: screen.c:982
client_static_s::demo
struct client_static_s::@3 demo
image_t
struct image_s image_t
Definition: material.h:27
loading_width
int loading_width
Definition: screen.c:37
scr_lag_min
static cvar_t * scr_lag_min
Definition: screen.c:68
SCR_ExecuteLayoutString
static void SCR_ExecuteLayoutString(const char *s)
Definition: screen.c:1636
crosshair_pic
qhandle_t crosshair_pic
Definition: screen.c:29
SCR_ClearChatHUD_f
void SCR_ClearChatHUD_f(void)
Definition: screen.c:897
SCR_DrawNet
static void SCR_DrawNet(void)
Definition: screen.c:596
hud_scale
float hud_scale
Definition: screen.c:50
lag
static struct @5 lag
drawobj_t::entry
list_t entry
Definition: screen.c:634
Cvar_Get
cvar_t * Cvar_Get(const char *var_name, const char *var_value, int flags)
Definition: cvar.c:257
client_static_s::key_dest
keydest_t key_dest
Definition: client.h:376
scr_scale
static cvar_t * scr_scale
Definition: screen.c:75
initialized
qboolean initialized
Definition: screen.c:27
IN_Activate
void IN_Activate(void)
Definition: input.c:117
colorNames
const char *const colorNames[10]
Definition: utils.c:190
client_static_s::file_percent
int file_percent
Definition: client.h:465
R_ClearColor
void(* R_ClearColor)(void)
Definition: refresh.c:410
DISPLAY_ITEMS
#define DISPLAY_ITEMS
Definition: screen.c:1529
SCR_SizeDown_f
static void SCR_SizeDown_f(void)
Definition: screen.c:1113
SCR_DrawStringEx
int SCR_DrawStringEx(int x, int y, int flags, size_t maxlen, const char *s, qhandle_t font)
Definition: screen.c:139
SCR_DrawStringMulti
void SCR_DrawStringMulti(int x, int y, int flags, size_t maxlen, const char *s, qhandle_t font)
Definition: screen.c:163
SCR_UnDraw_c
static void SCR_UnDraw_c(genctx_t *ctx, int argnum)
Definition: screen.c:771
SCR_DrawFPS
static void SCR_DrawFPS(void)
Definition: screen.c:856
scr_crosshair_changed
static void scr_crosshair_changed(cvar_t *self)
Definition: screen.c:1209
ca_active
@ ca_active
Definition: client.h:340
DIGIT_WIDTH
#define DIGIT_WIDTH
Definition: screen.c:1480
scr_crosshair
static cvar_t * scr_crosshair
Definition: screen.c:77
client_static_s::state
connstate_t state
Definition: client.h:375
chatline_t::text
char text[MAX_CHAT_TEXT]
Definition: screen.c:890
scr_alpha
static cvar_t * scr_alpha
Definition: screen.c:70
R_DrawFill8
void(* R_DrawFill8)(int x, int y, int w, int h, int c)
Definition: refresh.c:422
sv_paused
cvar_t * sv_paused
Definition: common.c:96
R_ClampScale
float R_ClampScale(cvar_t *var)
Definition: refresh.c:440
R_BeginFrame
void(* R_BeginFrame)(void)
Definition: refresh.c:424
SCR_DrawCenterString
static void SCR_DrawCenterString(void)
Definition: screen.c:487
client_state_s::oldframe
server_frame_t oldframe
Definition: client.h:213
SCR_RegisterMedia
void SCR_RegisterMedia(void)
Definition: screen.c:1297
scr_chathead
static unsigned scr_chathead
Definition: screen.c:895
LAG_WIDTH
#define LAG_WIDTH
Definition: screen.c:517
CL_GetResolutionScale
int CL_GetResolutionScale()
Definition: main.c:2379
CL_FRAMEDIV
#define CL_FRAMEDIV
Definition: client.h:163
Cmd_Deregister
void Cmd_Deregister(const cmdreg_t *reg)
Definition: cmd.c:1580
SCR_DrawStats
static void SCR_DrawStats(void)
Definition: screen.c:2003
DF
#define DF(f)
SCR_SetHudAlpha
void SCR_SetHudAlpha(float alpha)
Definition: screen.c:2201
Cmd_Argv
char * Cmd_Argv(int arg)
Definition: cmd.c:899
scr_chathud_x
static cvar_t * scr_chathud_x
Definition: screen.c:82
Sys_Milliseconds
unsigned Sys_Milliseconds(void)
Definition: system.c:644
SCR_DrawPause
static void SCR_DrawPause(void)
Definition: screen.c:1947
SCR_DebugGraph
void SCR_DebugGraph(float value, int color)
V_RenderView
void V_RenderView(void)
Definition: view.c:402
Cmd_Argc
int Cmd_Argc(void)
Definition: cmd.c:889
Prompt_AddMatch
qboolean Prompt_AddMatch(genctx_t *ctx, const char *s)
Definition: prompt.c:149
backtile_pic
qhandle_t backtile_pic
Definition: screen.c:44
draw
drawStatic_t draw
Definition: draw.c:21
SCR_DrawLoading
static void SCR_DrawLoading(void)
Definition: screen.c:1964
ch_health
static cvar_t * ch_health
Definition: screen.c:85
hud_width
int hud_width
Definition: screen.c:49
R_SetAlphaScale
void(* R_SetAlphaScale)(float alpha)
Definition: refresh.c:412
width
static int width
Definition: physical_sky.c:38
scr_cmds
static const cmdreg_t scr_cmds[]
Definition: screen.c:1332
ch_alpha
static cvar_t * ch_alpha
Definition: screen.c:89
UI_IsTransparent
qboolean UI_IsTransparent(void)
Definition: ui.c:177
drawobj_t
Definition: screen.c:633
clientinfo_s::name
char name[MAX_QPATH]
Definition: client.h:113
SCR_UpdateScreen
void SCR_UpdateScreen(void)
Definition: screen.c:2142
SCR_SizeUp_f
static void SCR_SizeUp_f(void)
Definition: screen.c:1100
client_state_s::refdef
refdef_t refdef
Definition: client.h:253
scr_showturtle
static cvar_t * scr_showturtle
Definition: screen.c:61
SCR_DrawCrosshair
static void SCR_DrawCrosshair(void)
Definition: screen.c:1983
Cvar_Variable_g
void Cvar_Variable_g(genctx_t *ctx)
Definition: cvar.c:133
Com_Error
void Com_Error(error_type_t type, const char *fmt,...)
Definition: g_main.c:258
client_state_s::frameflags
unsigned frameflags
Definition: client.h:210
HUD_DrawString
#define HUD_DrawString(x, y, string)
Definition: screen.c:1483
ch_blue
static cvar_t * ch_blue
Definition: screen.c:88
SCR_Draw_c
static void SCR_Draw_c(genctx_t *ctx, int argnum)
Definition: screen.c:660
SCR_LagSample
void SCR_LagSample(void)
Definition: screen.c:537
sb_nums
static const char *const sb_nums[2][STAT_PICS]
Definition: screen.c:107
drawobj_t::flags
int flags
Definition: screen.c:638
clientinfo_s::icon
qhandle_t icon
Definition: client.h:115
client_static_s::frames_read
int frames_read
Definition: client.h:461
CL_GetFps
int CL_GetFps()
Definition: main.c:2374
scr_showpause
static cvar_t * scr_showpause
Definition: screen.c:56
scr_lag_y
static cvar_t * scr_lag_y
Definition: screen.c:66
SCR_GetFont
qhandle_t SCR_GetFont(void)
Definition: screen.c:2196
Cvar_ClampValue
float Cvar_ClampValue(cvar_t *var, float min, float max)
Definition: cvar.c:571
SCR_TileClear
static void SCR_TileClear(void)
Definition: screen.c:1466
LAG_WARN
#define LAG_WARN
Definition: screen.c:524
Z_Free
void Z_Free(void *ptr)
Definition: zone.c:147
R_DrawPic
void(* R_DrawPic)(int x, int y, qhandle_t pic)
Definition: refresh.c:419
CHAT_LINE_MASK
#define CHAT_LINE_MASK
Definition: screen.c:887
client_state_s::layout
char layout[MAX_NET_STRING]
Definition: client.h:269
Cmd_Register
void Cmd_Register(const cmdreg_t *reg)
Definition: cmd.c:1572
Key_IsDown
int Key_IsDown(int key)
Definition: keys.c:204
head
unsigned head
Definition: screen.c:529
HUD_DrawCenterString
#define HUD_DrawCenterString(x, y, string)
Definition: screen.c:1489
SCR_CalcVrect
void SCR_CalcVrect(void)
Definition: screen.c:1085
R_DrawString
int(* R_DrawString)(int x, int y, int flags, size_t maxChars, const char *string, qhandle_t font)
Definition: refresh.c:417
client_state_s::baseclientinfo
clientinfo_t baseclientinfo
Definition: client.h:309
scr_centerstring
static char scr_centerstring[MAX_STRING_CHARS]
Definition: screen.c:450
client_history_t::sent
unsigned sent
Definition: client.h:123
STAT_PICS
#define STAT_PICS
Definition: screen.c:23
Key_GetBinding
char * Key_GetBinding(const char *binding)
Definition: keys.c:288
hud_alpha
float hud_alpha
Definition: screen.c:51
STAT_MINUS
#define STAT_MINUS
Definition: screen.c:24
Q_strlcpy
size_t Q_strlcpy(char *dst, const char *src, size_t size)
Definition: shared.c:715
SCR_DrawChatHUD
static void SCR_DrawChatHUD(void)
Definition: screen.c:917
FOR_EACH_DRAWOBJ
#define FOR_EACH_DRAWOBJ(obj)
Definition: screen.c:642
FOR_EACH_DRAWOBJ_SAFE
#define FOR_EACH_DRAWOBJ_SAFE(obj, next)
Definition: screen.c:644
scr_font
static cvar_t * scr_font
Definition: screen.c:74
Cvar_SetInteger
void Cvar_SetInteger(cvar_t *var, int value, from_t from)
Definition: cvar.c:509
client_state_s::clientinfo
clientinfo_t clientinfo[MAX_CLIENTS]
Definition: client.h:308
UI_Draw
void UI_Draw(int realtime)
Definition: ui.c:420
ch_x
static cvar_t * ch_x
Definition: screen.c:92
scr_demobar
static cvar_t * scr_demobar
Definition: screen.c:73
SCR_Color_g
static void SCR_Color_g(genctx_t *ctx)
Definition: screen.c:649
SCR_CenterPrint
void SCR_CenterPrint(const char *str)
Definition: screen.c:462
Cmd_Macro_g
void Cmd_Macro_g(genctx_t *ctx)
Definition: cmd.c:754
crosshair_width
int crosshair_width
Definition: screen.c:30
Cvar_WeakGet
cvar_t * Cvar_WeakGet(const char *var_name)
Definition: cvar.c:324
scr_viewsize
cvar_t * scr_viewsize
Definition: screen.c:54
client_history_t::cmdNumber
unsigned cmdNumber
Definition: client.h:125
scr_center_lines
static int scr_center_lines
Definition: screen.c:452
UI_ModeChanged
void UI_ModeChanged(void)
Definition: ui.c:602
SCR_FadeAlpha
float SCR_FadeAlpha(unsigned startTime, unsigned visTime, unsigned fadeTime)
Definition: screen.c:193
cl
client_state_t cl
Definition: main.c:99
server_frame_t::clientNum
int clientNum
Definition: client.h:138
SCR_Draw_f
static void SCR_Draw_f(void)
Definition: screen.c:671
drawobj_t::macro
cmd_macro_t * macro
Definition: screen.c:637
chatline_t
Definition: screen.c:889
ch_scale
static cvar_t * ch_scale
Definition: screen.c:91
pause_height
int pause_height
Definition: screen.c:34
client_static_s::frametime
float frametime
Definition: client.h:390
SCR_LagDraw
static void SCR_LagDraw(int x, int y)
Definition: screen.c:561
LAG_BASE
#define LAG_BASE
Definition: screen.c:523
cls
client_static_t cls
Definition: main.c:98
crosshair_height
int crosshair_height
Definition: screen.c:30
ca_cinematic
@ ca_cinematic
Definition: client.h:341
SCR_Draw2D
static void SCR_Draw2D(void)
Definition: screen.c:2026
c
statCounters_t c
Definition: main.c:30
loading_pic
qhandle_t loading_pic
Definition: screen.c:36
SCR_SetCrosshairColor
void SCR_SetCrosshairColor(void)
Definition: screen.c:1242
LAG_CRIT
#define LAG_CRIT
Definition: screen.c:525
R_GetPicSize
qboolean R_GetPicSize(int *w, int *h, qhandle_t pic)
Definition: images.c:1289
LAG_WARN_BIT
#define LAG_WARN_BIT
Definition: screen.c:521
inven_pic
qhandle_t inven_pic
Definition: screen.c:41
ch_y
static cvar_t * ch_y
Definition: screen.c:93
scr_chathud
static cvar_t * scr_chathud
Definition: screen.c:79
HUD_DrawAltString
#define HUD_DrawAltString(x, y, string)
Definition: screen.c:1486
field_pic
qhandle_t field_pic
Definition: screen.c:42
Cvar_ClampInteger
int Cvar_ClampInteger(cvar_t *var, int min, int max)
Definition: cvar.c:549
scr_centertime
static cvar_t * scr_centertime
Definition: screen.c:55
SCR_DrawInventory
static void SCR_DrawInventory(void)
Definition: screen.c:1531
scr_fps
static cvar_t * scr_fps
Definition: screen.c:71
client_history_t::rcvd
unsigned rcvd
Definition: client.h:124
loading_height
int loading_height
Definition: screen.c:37
server_frame_t::ps
player_state_t ps
Definition: client.h:137
R_RenderFrame
void(* R_RenderFrame)(refdef_t *fd)
Definition: refresh.c:408
draw_loading
qboolean draw_loading
Definition: screen.c:38
drawobj_t::y
int y
Definition: screen.c:635
R_DrawStretchPic
void(* R_DrawStretchPic)(int x, int y, int w, int h, qhandle_t pic)
Definition: refresh.c:420
scr_centertime_start
static unsigned scr_centertime_start
Definition: screen.c:451
client_history_t
Definition: client.h:122
client.h
Con_CheckResize
void Con_CheckResize(void)
Definition: console.c:367
hud_height
int hud_height
Definition: screen.c:49
scr_lag_draw
static cvar_t * scr_lag_draw
Definition: screen.c:67
client_static_s::disable_screen
unsigned disable_screen
Definition: client.h:381
SCR_DrawLayout
static void SCR_DrawLayout(void)
Definition: screen.c:2011
ch_red
static cvar_t * ch_red
Definition: screen.c:86
SCR_DrawSelectedItemName
static void SCR_DrawSelectedItemName(int x, int y, int item)
Definition: screen.c:1603
R_SetScale
void(* R_SetScale)(float scale)
Definition: refresh.c:415
scr_font_changed
static void scr_font_changed(cvar_t *self)
Definition: screen.c:1322
server_frame_t::number
int number
Definition: client.h:131
draw_percent_bar
static void draw_percent_bar(int percent, qboolean paused, int framenum)
Definition: screen.c:371
samples
unsigned samples[LAG_WIDTH]
Definition: screen.c:528
client_static_s::realtime
unsigned realtime
Definition: client.h:389
R_EndFrame
void(* R_EndFrame)(void)
Definition: refresh.c:425
R_DrawChar
void(* R_DrawChar)(int x, int y, int flags, int ch, qhandle_t font)
Definition: refresh.c:416
scr_chathud_lines
static cvar_t * scr_chathud_lines
Definition: screen.c:80
COM_Parse
char * COM_Parse(const char **data_p)
Definition: shared.c:455
sv_running
cvar_t * sv_running
Definition: common.c:95
color
static vec4_t color
Definition: mesh.c:33
client_state_s::history
client_history_t history[CMD_BACKUP]
Definition: client.h:186
IMG_ForHandle
image_t * IMG_ForHandle(qhandle_t h)
Definition: images.c:1156
CL_UpdateFrameTimes
void CL_UpdateFrameTimes(void)
Definition: main.c:3136
scr_chatlines
static chatline_t scr_chatlines[MAX_CHAT_LINES]
Definition: screen.c:894
Q_concat
size_t Q_concat(char *dest, size_t size,...)
Definition: shared.c:758
SCR_EndLoadingPlaque
void SCR_EndLoadingPlaque(void)
Definition: screen.c:1456
vid_rtx
cvar_t * vid_rtx
Definition: refresh.c:30
scr_showitemname
static cvar_t * scr_showitemname
Definition: screen.c:62
SCR_Draw_g
static void SCR_Draw_g(genctx_t *ctx)
Definition: screen.c:752
Con_ClearNotify_f
void Con_ClearNotify_f(void)
Definition: console.c:276
MAX_CHAT_LINES
#define MAX_CHAT_LINES
Definition: screen.c:886
drawobj_t::color
color_t color
Definition: screen.c:639
pause_width
int pause_width
Definition: screen.c:34
SCR_ParseColor
qboolean SCR_ParseColor(const char *s, color_t *color)
Definition: screen.c:215
ch_green
static cvar_t * ch_green
Definition: screen.c:87
int
CONST PIXELFORMATDESCRIPTOR int
Definition: wgl.c:26
SCR_DrawObjects
static void SCR_DrawObjects(void)
Definition: screen.c:822
net_pic
qhandle_t net_pic
Definition: screen.c:46
client_static_s::file_size
int file_size
Definition: client.h:463
Con_DrawConsole
void Con_DrawConsole(void)
Definition: console.c:1032
drawobj_t::cvar
cvar_t * cvar
Definition: screen.c:636
Cmd_FindMacro
cmd_macro_t * Cmd_FindMacro(const char *name)
Definition: cmd.c:739
Q_scnprintf
size_t Q_scnprintf(char *dest, size_t size, const char *fmt,...)
Definition: shared.c:867
SCR_BeginLoadingPlaque
void SCR_BeginLoadingPlaque(void)
Definition: screen.c:1424
SCR_Shutdown
void SCR_Shutdown(void)
Definition: screen.c:1413
SCR_DrawActive
static void SCR_DrawActive(void)
Definition: screen.c:2080
client_static_s::netchan
netchan_t * netchan
Definition: client.h:421
scr_draw2d
static cvar_t * scr_draw2d
Definition: screen.c:64
scr_chathud_y
static cvar_t * scr_chathud_y
Definition: screen.c:83
scr_vrect
vrect_t scr_vrect
Definition: screen.c:105
SCR_UnDraw_f
static void SCR_UnDraw_f(void)
Definition: screen.c:778
scr_chathud_time
static cvar_t * scr_chathud_time
Definition: screen.c:81
HUD_DrawAltCenterString
#define HUD_DrawAltCenterString(x, y, string)
Definition: screen.c:1492
SCR_Sky_f
static void SCR_Sky_f(void)
Definition: screen.c:1127
SCR_TimeRefresh_f
static void SCR_TimeRefresh_f(void)
Definition: screen.c:1170
r_config
refcfg_t r_config
Definition: refresh.c:401
SCR_LagClear
void SCR_LagClear(void)
Definition: screen.c:532
font_pic
qhandle_t font_pic
Definition: screen.c:47
clientinfo_s
Definition: client.h:112
LIST_DECL
static LIST_DECL(scr_objects)
pause_pic
qhandle_t pause_pic
Definition: screen.c:33
LAG_CRIT_BIT
#define LAG_CRIT_BIT
Definition: screen.c:520
chatline_t::time
unsigned time
Definition: screen.c:891
SCR_Init
void SCR_Init(void)
Definition: screen.c:1348