5 #include "cl_collision.h"
7 cvar_t scr_viewsize = {CVAR_SAVE, "viewsize","100"};
8 cvar_t scr_fov = {CVAR_SAVE, "fov","90"}; // 1 - 170
9 cvar_t scr_conspeed = {CVAR_SAVE, "scr_conspeed","900"}; // LordHavoc: quake used 300
10 cvar_t scr_conalpha = {CVAR_SAVE, "scr_conalpha", "1"};
11 cvar_t scr_conbrightness = {CVAR_SAVE, "scr_conbrightness", "0.2"};
12 cvar_t scr_conforcewhiledisconnected = {CVAR_SAVE, "scr_conforcewhiledisconnected", "1"};
13 cvar_t scr_centertime = {0, "scr_centertime","2"};
14 cvar_t scr_showram = {CVAR_SAVE, "showram","1"};
15 cvar_t scr_showturtle = {CVAR_SAVE, "showturtle","0"};
16 cvar_t scr_showpause = {CVAR_SAVE, "showpause","1"};
17 cvar_t scr_showbrand = {0, "showbrand","0"};
18 cvar_t scr_printspeed = {0, "scr_printspeed","8"};
19 cvar_t vid_conwidth = {CVAR_SAVE, "vid_conwidth", "640"};
20 cvar_t vid_conheight = {CVAR_SAVE, "vid_conheight", "480"};
21 cvar_t vid_pixelaspect = {CVAR_SAVE, "vid_pixelaspect", "1"};
22 cvar_t scr_screenshot_jpeg = {CVAR_SAVE, "scr_screenshot_jpeg","1"};
23 cvar_t scr_screenshot_jpeg_quality = {CVAR_SAVE, "scr_screenshot_jpeg_quality","0.9"};
24 cvar_t scr_screenshot_gamma = {CVAR_SAVE, "scr_screenshot_gamma","2.2"};
25 // scr_screenshot_name is defined in fs.c
26 cvar_t cl_capturevideo = {0, "cl_capturevideo", "0"};
27 cvar_t cl_capturevideo_sound = {0, "cl_capturevideo_sound", "0"};
28 cvar_t cl_capturevideo_fps = {0, "cl_capturevideo_fps", "30"};
29 cvar_t cl_capturevideo_rawrgb = {0, "cl_capturevideo_rawrgb", "0"};
30 cvar_t cl_capturevideo_rawyv12 = {0, "cl_capturevideo_rawyv12", "0"};
31 cvar_t r_textshadow = {0, "r_textshadow", "0"};
32 cvar_t r_letterbox = {0, "r_letterbox", "0"};
34 int jpeg_supported = false;
36 qboolean scr_initialized; // ready to draw
38 float scr_con_current;
40 extern int con_vislines;
42 void DrawCrosshair(int num);
43 static void SCR_ScreenShot_f (void);
44 static void R_Envmap_f (void);
47 void R_ClearScreen(void);
50 static vec4_t string_colors[] =
53 // LordHavoc: why on earth is cyan before magenta in Quake3?
54 // LordHavoc: note: Doom3 uses white for [0] and [7]
55 {0.0, 0.0, 0.0, 1.0}, // black
56 {1.0, 0.0, 0.0, 1.0}, // red
57 {0.0, 1.0, 0.0, 1.0}, // green
58 {1.0, 1.0, 0.0, 1.0}, // yellow
59 {0.0, 0.0, 1.0, 1.0}, // blue
60 {0.0, 1.0, 1.0, 1.0}, // cyan
61 {1.0, 0.0, 1.0, 1.0}, // magenta
62 {1.0, 1.0, 1.0, 1.0}, // white
63 // [515]'s BX_COLOREDTEXT extension
64 {1.0, 1.0, 1.0, 0.5}, // half transparent
65 {0.5, 0.5, 0.5, 1.0} // half brightness
66 // Black's color table
67 //{1.0, 1.0, 1.0, 1.0},
68 //{1.0, 0.0, 0.0, 1.0},
69 //{0.0, 1.0, 0.0, 1.0},
70 //{0.0, 0.0, 1.0, 1.0},
71 //{1.0, 1.0, 0.0, 1.0},
72 //{0.0, 1.0, 1.0, 1.0},
73 //{1.0, 0.0, 1.0, 1.0},
74 //{0.1, 0.1, 0.1, 1.0}
77 #define STRING_COLORS_COUNT (sizeof(string_colors) / sizeof(vec4_t))
79 // color is read and changed in the end
80 void DrawQ_ColoredString( float x, float y, const char *text, int maxlen, float scalex, float scaley, float basered, float basegreen, float baseblue, float basealpha, int flags, int *outcolor )
85 const char *start, *current;
87 if( !outcolor || *outcolor == -1 ) {
88 colorindex = STRING_COLOR_DEFAULT;
90 colorindex = *outcolor;
92 color = string_colors[colorindex];
95 len = (int)strlen( text );
97 len = min( maxlen, (int) strlen( text ) );
99 start = current = text;
101 // check for color control char
102 if( *current == STRING_COLOR_TAG ) {
109 // display the tag char?
110 if( *current == STRING_COLOR_TAG ) {
111 // only display one of the two
116 } else if( '0' <= *current && *current <= '9' ) {
119 colorindex = colorindex * 10 + (*current - '0');
120 // only read as long as it makes a valid index
121 if( colorindex >= (int)STRING_COLORS_COUNT ) {
122 // undo the last operation
128 } while( len > 0 && '0' <= *current && *current <= '9' );
130 color = string_colors[colorindex];
131 // we jump over the color tag
135 // go on and read normal text in until the next control char
136 while( len > 0 && *current != STRING_COLOR_TAG ) {
141 if( start != current ) {
143 DrawQ_String( x, y, start, current - start, scalex, scaley, basered * color[0], basegreen * color[1], baseblue * color[2], basealpha * color[3], flags );
144 // update x to be at the new start position
145 x += (current - start) * scalex;
146 // set start accordingly
151 // return the last colorindex
153 *outcolor = colorindex;
158 ===============================================================================
162 ===============================================================================
165 char scr_centerstring[1024];
166 float scr_centertime_start; // for slow victory printing
167 float scr_centertime_off;
168 int scr_center_lines;
170 int scr_erase_center;
176 Called for important messages that should stay in the center of the screen
180 void SCR_CenterPrint(char *str)
182 strlcpy (scr_centerstring, str, sizeof (scr_centerstring));
183 scr_centertime_off = scr_centertime.value;
184 scr_centertime_start = cl.time;
186 // count the number of lines for centering
187 scr_center_lines = 1;
197 void SCR_DrawCenterString (void)
205 // the finale prints the characters one at a time
207 remaining = scr_printspeed.value * (cl.time - scr_centertime_start);
211 scr_erase_center = 0;
212 start = scr_centerstring;
214 if (scr_center_lines <= 4)
215 y = vid_conheight.integer*0.35;
222 // scan the width of the line
223 for (l=0 ; l<vid_conwidth.integer/8 ; l++)
224 if (start[l] == '\n' || !start[l])
226 x = (vid_conwidth.integer - l*8)/2;
231 DrawQ_ColoredString(x, y, start, l, 8, 8, 1, 1, 1, 1, 0, &color);
239 while (*start && *start != '\n')
244 start++; // skip the \n
248 void SCR_CheckDrawCenterString (void)
250 if (scr_center_lines > scr_erase_lines)
251 scr_erase_lines = scr_center_lines;
253 scr_centertime_off -= host_frametime;
255 // don't draw if this is a normal stats-screen intermission,
256 // only if it is not an intermission, or a finale intermission
257 if (cl.intermission == 1)
259 if (scr_centertime_off <= 0 && !cl.intermission)
261 if (key_dest != key_game)
264 SCR_DrawCenterString ();
272 void SCR_DrawTurtle (void)
276 if (cls.state != ca_connected)
279 if (!scr_showturtle.integer)
282 if (host_frametime < 0.1)
292 DrawQ_Pic (0, 0, "gfx/turtle", 0, 0, 1, 1, 1, 1, 0);
300 void SCR_DrawNet (void)
302 if (cls.state != ca_connected)
304 if (realtime - cl.last_received_message < 0.3)
306 if (cls.demoplayback)
309 DrawQ_Pic (64, 0, "gfx/net", 0, 0, 1, 1, 1, 1, 0);
317 void SCR_DrawPause (void)
321 if (cls.state != ca_connected)
324 if (!scr_showpause.integer) // turn off for screenshots
330 pic = Draw_CachePic ("gfx/pause", true);
331 DrawQ_Pic ((vid_conwidth.integer - pic->width)/2, (vid_conheight.integer - pic->height)/2, "gfx/pause", 0, 0, 1, 1, 1, 1, 0);
339 void SCR_DrawBrand (void)
344 if (!scr_showbrand.value)
347 pic = Draw_CachePic ("gfx/brand", true);
349 switch ((int)scr_showbrand.value)
351 case 1: // bottom left
353 y = vid_conheight.integer - pic->height;
355 case 2: // bottom centre
356 x = (vid_conwidth.integer - pic->width) / 2;
357 y = vid_conheight.integer - pic->height;
359 case 3: // bottom right
360 x = vid_conwidth.integer - pic->width;
361 y = vid_conheight.integer - pic->height;
363 case 4: // centre right
364 x = vid_conwidth.integer - pic->width;
365 y = (vid_conheight.integer - pic->height) / 2;
368 x = vid_conwidth.integer - pic->width;
371 case 6: // top centre
372 x = (vid_conwidth.integer - pic->width) / 2;
379 case 8: // centre left
381 y = (vid_conheight.integer - pic->height) / 2;
387 DrawQ_Pic (x, y, "gfx/brand", 0, 0, 1, 1, 1, 1, 0);
390 //=============================================================================
395 SCR_SetUpToDrawConsole
398 void SCR_SetUpToDrawConsole (void)
400 // lines of console to display
405 if (key_dest == key_game && cls.signon != SIGNONS && scr_conforcewhiledisconnected.integer)
406 key_consoleactive |= KEY_CONSOLEACTIVE_FORCED;
408 key_consoleactive &= ~KEY_CONSOLEACTIVE_FORCED;
410 // decide on the height of the console
411 if (key_consoleactive & KEY_CONSOLEACTIVE_USER)
412 conlines = vid_conheight.integer/2; // half screen
414 conlines = 0; // none visible
416 if (scr_conspeed.value)
418 if (scr_con_current > conlines)
420 scr_con_current -= scr_conspeed.value*host_realframetime;
421 if (scr_con_current < conlines)
422 scr_con_current = conlines;
425 else if (scr_con_current < conlines)
427 scr_con_current += scr_conspeed.value*host_realframetime;
428 if (scr_con_current > conlines)
429 scr_con_current = conlines;
433 scr_con_current = conlines;
441 void SCR_DrawConsole (void)
443 if (key_consoleactive & KEY_CONSOLEACTIVE_FORCED)
446 Con_DrawConsole (vid_conheight.integer);
448 else if (scr_con_current)
449 Con_DrawConsole (scr_con_current);
453 if (key_dest == key_game || key_dest == key_message)
454 Con_DrawNotify (); // only draw notify in game
460 SCR_BeginLoadingPlaque
464 void SCR_BeginLoadingPlaque (void)
468 SCR_UpdateLoadingScreen();
471 //=============================================================================
473 char r_speeds_string[1024];
474 int speedstringcount, r_timereport_active;
475 double r_timereport_temp = 0, r_timereport_current = 0, r_timereport_start = 0;
477 void R_TimeReport(char *desc)
483 if (!r_timereport_active || r_showtrispass)
487 r_timereport_temp = r_timereport_current;
488 r_timereport_current = Sys_DoubleTime();
489 t = (int) ((r_timereport_current - r_timereport_temp) * 1000000.0);
491 dpsnprintf(tempbuf, sizeof(tempbuf), "%8i %s", t, desc);
492 length = (int)strlen(tempbuf);
494 tempbuf[length++] = ' ';
496 if (speedstringcount + length > (vid_conwidth.integer / 8))
498 strlcat(r_speeds_string, "\n", sizeof(r_speeds_string));
499 speedstringcount = 0;
501 // skip the space at the beginning if it's the first on the line
502 if (speedstringcount == 0)
504 strlcat(r_speeds_string, tempbuf + 1, sizeof(r_speeds_string));
505 speedstringcount = length - 1;
509 strlcat(r_speeds_string, tempbuf, sizeof(r_speeds_string));
510 speedstringcount += length;
514 void R_TimeReport_Start(void)
516 r_timereport_active = r_speeds.integer && cls.signon == SIGNONS && cls.state == ca_connected;
517 r_speeds_string[0] = 0;
518 if (r_timereport_active)
520 speedstringcount = 0;
521 sprintf(r_speeds_string + strlen(r_speeds_string), "org:'%+8.2f %+8.2f %+8.2f' dir:'%+2.3f %+2.3f %+2.3f'\n", r_vieworigin[0], r_vieworigin[1], r_vieworigin[2], r_viewforward[0], r_viewforward[1], r_viewforward[2]);
522 sprintf(r_speeds_string + strlen(r_speeds_string), "world:%6i faces%6i nodes%6i leafs%6i dlitwalls\n", c_faces, c_nodes, c_leafs, c_light_polys);
523 sprintf(r_speeds_string + strlen(r_speeds_string), "%5i models%5i bmodels%5i sprites%6i particles%4i dlights\n", c_models, c_bmodels, c_sprites, c_particles, c_dlights);
524 sprintf(r_speeds_string + strlen(r_speeds_string), "%6i modeltris%6i meshs%6i meshtris\n", c_alias_polys, c_meshs, c_meshelements / 3);
525 sprintf(r_speeds_string + strlen(r_speeds_string), "bloom %s: %i copies (%i pixels) %i draws (%i pixels)\n", c_bloom ? "active" : "inactive", c_bloomcopies, c_bloomcopypixels, c_bloomdraws, c_bloomdrawpixels);
526 sprintf(r_speeds_string + strlen(r_speeds_string), "realtime lighting:%4i lights%4i clears%4i scissored\n", c_rt_lights, c_rt_clears, c_rt_scissored);
527 sprintf(r_speeds_string + strlen(r_speeds_string), "dynamic: %6i shadowmeshes%6i shadowtris%6i lightmeshes%6i lighttris\n", c_rt_shadowmeshes, c_rt_shadowtris, c_rt_lightmeshes, c_rt_lighttris);
528 sprintf(r_speeds_string + strlen(r_speeds_string), "precomputed: %6i shadowmeshes%6i shadowtris\n", c_rtcached_shadowmeshes, c_rtcached_shadowtris);
545 c_rt_shadowmeshes = 0;
547 c_rt_lightmeshes = 0;
549 c_rtcached_shadowmeshes = 0;
550 c_rtcached_shadowtris = 0;
553 c_bloomcopypixels = 0;
555 c_bloomdrawpixels = 0;
557 r_timereport_start = Sys_DoubleTime();
561 void R_TimeReport_End(void)
563 r_timereport_current = r_timereport_start;
564 R_TimeReport("total");
566 if (r_timereport_active)
570 for (i = 0;r_speeds_string[i];i++)
571 if (r_speeds_string[i] == '\n')
573 y = vid_conheight.integer - sb_lines - lines * 8;
575 DrawQ_Fill(0, y, vid_conwidth.integer, lines * 8, 0, 0, 0, 0.5, 0);
576 while (r_speeds_string[i])
579 while (r_speeds_string[i] && r_speeds_string[i] != '\n')
582 DrawQ_String(0, y, r_speeds_string + j, i - j, 8, 8, 1, 1, 1, 1, 0);
583 if (r_speeds_string[i] == '\n')
597 void SCR_SizeUp_f (void)
599 Cvar_SetValue ("viewsize",scr_viewsize.value+10);
610 void SCR_SizeDown_f (void)
612 Cvar_SetValue ("viewsize",scr_viewsize.value-10);
615 void CL_Screen_Init(void)
617 Cvar_RegisterVariable (&scr_fov);
618 Cvar_RegisterVariable (&scr_viewsize);
619 Cvar_RegisterVariable (&scr_conspeed);
620 Cvar_RegisterVariable (&scr_conalpha);
621 Cvar_RegisterVariable (&scr_conbrightness);
622 Cvar_RegisterVariable (&scr_conforcewhiledisconnected);
623 Cvar_RegisterVariable (&scr_showram);
624 Cvar_RegisterVariable (&scr_showturtle);
625 Cvar_RegisterVariable (&scr_showpause);
626 Cvar_RegisterVariable (&scr_showbrand);
627 Cvar_RegisterVariable (&scr_centertime);
628 Cvar_RegisterVariable (&scr_printspeed);
629 Cvar_RegisterVariable (&vid_conwidth);
630 Cvar_RegisterVariable (&vid_conheight);
631 Cvar_RegisterVariable (&vid_pixelaspect);
632 Cvar_RegisterVariable (&scr_screenshot_jpeg);
633 Cvar_RegisterVariable (&scr_screenshot_jpeg_quality);
634 Cvar_RegisterVariable (&scr_screenshot_gamma);
635 Cvar_RegisterVariable (&cl_capturevideo);
636 Cvar_RegisterVariable (&cl_capturevideo_sound);
637 Cvar_RegisterVariable (&cl_capturevideo_fps);
638 Cvar_RegisterVariable (&cl_capturevideo_rawrgb);
639 Cvar_RegisterVariable (&cl_capturevideo_rawyv12);
640 Cvar_RegisterVariable (&r_textshadow);
641 Cvar_RegisterVariable (&r_letterbox);
643 Cmd_AddCommand ("sizeup",SCR_SizeUp_f);
644 Cmd_AddCommand ("sizedown",SCR_SizeDown_f);
645 Cmd_AddCommand ("screenshot",SCR_ScreenShot_f);
646 Cmd_AddCommand ("envmap", R_Envmap_f);
648 scr_initialized = true;
651 void DrawQ_Clear(void)
653 r_refdef.drawqueuesize = 0;
656 static int picelements[6] = {0, 1, 2, 0, 2, 3};
657 void DrawQ_Pic(float x, float y, const char *picname, float width, float height, float red, float green, float blue, float alpha, int flags)
659 DrawQ_SuperPic(x,y,picname,width,height,0,0,red,green,blue,alpha,1,0,red,green,blue,alpha,0,1,red,green,blue,alpha,1,1,red,green,blue,alpha,flags);
662 void DrawQ_String_Real(float x, float y, const char *string, int maxlen, float scalex, float scaley, float red, float green, float blue, float alpha, int flags)
667 if (alpha < (1.0f / 255.0f))
670 len = (int)strlen(string);
672 for (len = 0;len < maxlen && string[len];len++);
673 for (;len > 0 && string[0] == ' ';string++, x += scalex, len--);
674 for (;len > 0 && string[len - 1] == ' ';len--);
677 if (x >= vid_conwidth.integer || y >= vid_conheight.integer || x < (-scalex * len) || y < (-scaley))
679 size = sizeof(*dq) + ((len + 1 + 3) & ~3);
680 if (r_refdef.drawqueuesize + size > r_refdef.maxdrawqueuesize)
682 red = bound(0, red, 1);
683 green = bound(0, green, 1);
684 blue = bound(0, blue, 1);
685 alpha = bound(0, alpha, 1);
686 dq = (drawqueue_t *)(r_refdef.drawqueue + r_refdef.drawqueuesize);
688 dq->command = DRAWQUEUE_STRING;
690 dq->color = ((unsigned int) (red * 255.0f) << 24) | ((unsigned int) (green * 255.0f) << 16) | ((unsigned int) (blue * 255.0f) << 8) | ((unsigned int) (alpha * 255.0f));
695 out = (char *)(dq + 1);
696 memcpy(out, string, len);
698 r_refdef.drawqueuesize += dq->size;
701 void DrawQ_String(float x, float y, const char *string, int maxlen, float scalex, float scaley, float red, float green, float blue, float alpha, int flags)
703 if (r_textshadow.integer)
704 DrawQ_String_Real(x+scalex*0.25,y+scaley*0.25,string,maxlen,scalex,scaley,0,0,0,alpha*0.8,flags);
706 DrawQ_String_Real(x,y,string,maxlen,scalex,scaley,red,green,blue,alpha,flags);
711 void DrawQ_Fill (float x, float y, float w, float h, float red, float green, float blue, float alpha, int flags)
713 DrawQ_SuperPic(x,y,NULL,w,h,0,0,red,green,blue,alpha,1,0,red,green,blue,alpha,0,1,red,green,blue,alpha,1,1,red,green,blue,alpha,flags);
716 void DrawQ_SuperPic(float x, float y, const char *picname, float width, float height, float s1, float t1, float r1, float g1, float b1, float a1, float s2, float t2, float r2, float g2, float b2, float a2, float s3, float t3, float r3, float g3, float b3, float a3, float s4, float t4, float r4, float g4, float b4, float a4, int flags)
720 drawqueuemesh_t mesh;
721 memset(&mesh, 0, sizeof(mesh));
722 if (picname && picname[0])
724 pic = Draw_CachePic(picname, false);
728 height = pic->height;
729 mesh.texture = pic->tex;
731 mesh.num_triangles = 2;
732 mesh.num_vertices = 4;
733 mesh.data_element3i = picelements;
734 mesh.data_vertex3f = floats;
735 mesh.data_texcoord2f = floats + 12;
736 mesh.data_color4f = floats + 20;
737 memset(floats, 0, sizeof(floats));
738 mesh.data_vertex3f[0] = mesh.data_vertex3f[9] = x;
739 mesh.data_vertex3f[1] = mesh.data_vertex3f[4] = y;
740 mesh.data_vertex3f[3] = mesh.data_vertex3f[6] = x + width;
741 mesh.data_vertex3f[7] = mesh.data_vertex3f[10] = y + height;
742 mesh.data_texcoord2f[0] = s1;mesh.data_texcoord2f[1] = t1;mesh.data_color4f[ 0] = r1;mesh.data_color4f[ 1] = g1;mesh.data_color4f[ 2] = b1;mesh.data_color4f[ 3] = a1;
743 mesh.data_texcoord2f[2] = s2;mesh.data_texcoord2f[3] = t2;mesh.data_color4f[ 4] = r2;mesh.data_color4f[ 5] = g2;mesh.data_color4f[ 6] = b2;mesh.data_color4f[ 7] = a2;
744 mesh.data_texcoord2f[4] = s4;mesh.data_texcoord2f[5] = t4;mesh.data_color4f[ 8] = r4;mesh.data_color4f[ 9] = g4;mesh.data_color4f[10] = b4;mesh.data_color4f[11] = a4;
745 mesh.data_texcoord2f[6] = s3;mesh.data_texcoord2f[7] = t3;mesh.data_color4f[12] = r3;mesh.data_color4f[13] = g3;mesh.data_color4f[14] = b3;mesh.data_color4f[15] = a3;
746 DrawQ_Mesh (&mesh, flags);
749 void DrawQ_Mesh (drawqueuemesh_t *mesh, int flags)
756 size += sizeof(drawqueuemesh_t);
757 size += sizeof(int[3]) * mesh->num_triangles;
758 size += sizeof(float[3]) * mesh->num_vertices;
759 size += sizeof(float[2]) * mesh->num_vertices;
760 size += sizeof(float[4]) * mesh->num_vertices;
761 if (r_refdef.drawqueuesize + size > r_refdef.maxdrawqueuesize)
763 dq = (drawqueue_t *)(r_refdef.drawqueue + r_refdef.drawqueuesize);
765 dq->command = DRAWQUEUE_MESH;
772 p = (void *)(dq + 1);
773 m = (drawqueuemesh_t *)p;p = (qbyte*)p + sizeof(drawqueuemesh_t);
774 m->num_triangles = mesh->num_triangles;
775 m->num_vertices = mesh->num_vertices;
776 m->texture = mesh->texture;
777 m->data_element3i = (int *)p;memcpy(m->data_element3i , mesh->data_element3i , m->num_triangles * sizeof(int[3]));p = (qbyte*)p + m->num_triangles * sizeof(int[3]);
778 m->data_vertex3f = (float *)p;memcpy(m->data_vertex3f , mesh->data_vertex3f , m->num_vertices * sizeof(float[3]));p = (qbyte*)p + m->num_vertices * sizeof(float[3]);
779 m->data_texcoord2f = (float *)p;memcpy(m->data_texcoord2f, mesh->data_texcoord2f, m->num_vertices * sizeof(float[2]));p = (qbyte*)p + m->num_vertices * sizeof(float[2]);
780 m->data_color4f = (float *)p;memcpy(m->data_color4f , mesh->data_color4f , m->num_vertices * sizeof(float[4]));p = (qbyte*)p + m->num_vertices * sizeof(float[4]);
781 r_refdef.drawqueuesize += dq->size;
784 void DrawQ_SetClipArea(float x, float y, float width, float height)
787 if(r_refdef.drawqueuesize + (int)sizeof(*dq) > r_refdef.maxdrawqueuesize)
789 Con_DPrint("DrawQueue full !\n");
792 dq = (drawqueue_t *) (r_refdef.drawqueue + r_refdef.drawqueuesize);
793 dq->size = sizeof(*dq);
794 dq->command = DRAWQUEUE_SETCLIP;
802 r_refdef.drawqueuesize += dq->size;
805 void DrawQ_ResetClipArea(void)
808 if(r_refdef.drawqueuesize + (int)sizeof(*dq) > r_refdef.maxdrawqueuesize)
810 Con_DPrint("DrawQueue full !\n");
813 dq = (drawqueue_t *) (r_refdef.drawqueue + r_refdef.drawqueuesize);
814 dq->size = sizeof(*dq);
815 dq->command = DRAWQUEUE_RESETCLIP;
823 r_refdef.drawqueuesize += dq->size;
831 void SCR_ScreenShot_f (void)
833 static int shotnumber;
834 static char oldname[MAX_QPATH];
835 char base[MAX_QPATH];
836 char filename[MAX_QPATH];
840 qboolean jpeg = (scr_screenshot_jpeg.integer != 0);
842 sprintf (base, "screenshots/%s", scr_screenshot_name.string);
844 if (strcmp (oldname, scr_screenshot_name.string))
846 sprintf(oldname, "%s", scr_screenshot_name.string);
850 // find a file name to save it to
851 for (;shotnumber < 1000000;shotnumber++)
852 if (!FS_SysFileExists(va("%s/%s%06d.tga", fs_gamedir, base, shotnumber)) && !FS_SysFileExists(va("%s/%s%06d.jpg", fs_gamedir, base, shotnumber)))
854 if (shotnumber >= 1000000)
856 Con_Print("SCR_ScreenShot_f: Couldn't create the image file\n");
860 sprintf(filename, "%s%06d.%s", base, shotnumber, jpeg ? "jpg" : "tga");
862 buffer1 = (qbyte *)Mem_Alloc(tempmempool, vid.width * vid.height * 3);
863 buffer2 = (qbyte *)Mem_Alloc(tempmempool, vid.width * vid.height * 3);
864 buffer3 = (qbyte *)Mem_Alloc(tempmempool, vid.width * vid.height * 3 + 18);
866 if (SCR_ScreenShot (filename, buffer1, buffer2, buffer3, 0, 0, vid.width, vid.height, false, false, false, jpeg, true))
867 Con_Printf("Wrote %s\n", filename);
869 Con_Printf("unable to write %s\n", filename);
878 typedef enum capturevideoformat_e
880 CAPTUREVIDEOFORMAT_TARGA,
881 CAPTUREVIDEOFORMAT_JPEG,
882 CAPTUREVIDEOFORMAT_RAWRGB,
883 CAPTUREVIDEOFORMAT_RAWYV12
885 capturevideoformat_t;
887 qboolean cl_capturevideo_active = false;
888 capturevideoformat_t cl_capturevideo_format;
889 static double cl_capturevideo_starttime = 0;
890 double cl_capturevideo_framerate = 0;
891 static int cl_capturevideo_soundrate = 0;
892 static int cl_capturevideo_frame = 0;
893 static qbyte *cl_capturevideo_buffer = NULL;
894 static qfile_t *cl_capturevideo_videofile = NULL;
895 qfile_t *cl_capturevideo_soundfile = NULL;
896 static short cl_capturevideo_rgbtoyuvscaletable[3][3][256];
897 static unsigned char cl_capturevideo_yuvnormalizetable[3][256];
898 //static unsigned char cl_capturevideo_rgbgammatable[3][256];
900 void SCR_CaptureVideo_BeginVideo(void)
905 if (cl_capturevideo_active)
907 // soundrate is figured out on the first SoundFrame
908 cl_capturevideo_active = true;
909 cl_capturevideo_starttime = Sys_DoubleTime();
910 cl_capturevideo_framerate = bound(1, cl_capturevideo_fps.value, 1000);
911 cl_capturevideo_soundrate = 0;
912 cl_capturevideo_frame = 0;
913 cl_capturevideo_buffer = (qbyte *)Mem_Alloc(tempmempool, vid.width * vid.height * (3+3+3) + 18);
914 gamma = 1.0/scr_screenshot_gamma.value;
917 for (i = 0;i < 256;i++)
919 unsigned char j = (unsigned char)bound(0, 255*pow(i/255.0, gamma), 255);
920 cl_capturevideo_rgbgammatable[0][i] = j;
921 cl_capturevideo_rgbgammatable[1][i] = j;
922 cl_capturevideo_rgbgammatable[2][i] = j;
926 R = Y + 1.4075 * (Cr - 128);
927 G = Y + -0.3455 * (Cb - 128) + -0.7169 * (Cr - 128);
928 B = Y + 1.7790 * (Cb - 128);
929 Y = R * .299 + G * .587 + B * .114;
930 Cb = R * -.169 + G * -.332 + B * .500 + 128.;
931 Cr = R * .500 + G * -.419 + B * -.0813 + 128.;
933 for (i = 0;i < 256;i++)
935 g = 255*pow(i/255.0, gamma);
936 // Y weights from RGB
937 cl_capturevideo_rgbtoyuvscaletable[0][0][i] = (short)(g * 0.299);
938 cl_capturevideo_rgbtoyuvscaletable[0][1][i] = (short)(g * 0.587);
939 cl_capturevideo_rgbtoyuvscaletable[0][2][i] = (short)(g * 0.114);
940 // Cb weights from RGB
941 cl_capturevideo_rgbtoyuvscaletable[1][0][i] = (short)(g * -0.169);
942 cl_capturevideo_rgbtoyuvscaletable[1][1][i] = (short)(g * -0.332);
943 cl_capturevideo_rgbtoyuvscaletable[1][2][i] = (short)(g * 0.500);
944 // Cr weights from RGB
945 cl_capturevideo_rgbtoyuvscaletable[2][0][i] = (short)(g * 0.500);
946 cl_capturevideo_rgbtoyuvscaletable[2][1][i] = (short)(g * -0.419);
947 cl_capturevideo_rgbtoyuvscaletable[2][2][i] = (short)(g * -0.0813);
948 // range reduction of YCbCr to valid signal range
949 cl_capturevideo_yuvnormalizetable[0][i] = 16 + i * (236-16) / 256;
950 cl_capturevideo_yuvnormalizetable[1][i] = 16 + i * (240-16) / 256;
951 cl_capturevideo_yuvnormalizetable[2][i] = 16 + i * (240-16) / 256;
954 if (cl_capturevideo_rawrgb.integer)
956 cl_capturevideo_format = CAPTUREVIDEOFORMAT_RAWRGB;
957 cl_capturevideo_videofile = FS_Open ("video/dpvideo.rgb", "wb", false, true);
959 else if (cl_capturevideo_rawyv12.integer)
961 cl_capturevideo_format = CAPTUREVIDEOFORMAT_RAWYV12;
962 cl_capturevideo_videofile = FS_Open ("video/dpvideo.yv12", "wb", false, true);
964 else if (scr_screenshot_jpeg.integer)
966 cl_capturevideo_format = CAPTUREVIDEOFORMAT_JPEG;
967 cl_capturevideo_videofile = NULL;
971 cl_capturevideo_format = CAPTUREVIDEOFORMAT_TARGA;
972 cl_capturevideo_videofile = NULL;
975 if (cl_capturevideo_sound.integer)
977 cl_capturevideo_soundfile = FS_Open ("video/dpvideo.wav", "wb", false, true);
978 // wave header will be filled out when video ends
980 FS_Write (cl_capturevideo_soundfile, out, 44);
983 cl_capturevideo_soundfile = NULL;
986 void SCR_CaptureVideo_EndVideo(void)
990 if (!cl_capturevideo_active)
992 cl_capturevideo_active = false;
994 if (cl_capturevideo_videofile)
996 FS_Close(cl_capturevideo_videofile);
997 cl_capturevideo_videofile = NULL;
1000 // finish the wave file
1001 if (cl_capturevideo_soundfile)
1003 i = (int)FS_Tell (cl_capturevideo_soundfile);
1004 //"RIFF", (int) unknown (chunk size), "WAVE",
1005 //"fmt ", (int) 16 (chunk size), (short) format 1 (uncompressed PCM), (short) 2 channels, (int) unknown rate, (int) unknown bytes per second, (short) 4 bytes per sample (channels * bytes per channel), (short) 16 bits per channel
1006 //"data", (int) unknown (chunk size)
1007 memcpy (out, "RIFF****WAVEfmt \x10\x00\x00\x00\x01\x00\x02\x00********\x04\x00\x10\0data****", 44);
1008 // the length of the whole RIFF chunk
1010 out[4] = (n) & 0xFF;
1011 out[5] = (n >> 8) & 0xFF;
1012 out[6] = (n >> 16) & 0xFF;
1013 out[7] = (n >> 24) & 0xFF;
1015 n = cl_capturevideo_soundrate;
1016 out[24] = (n) & 0xFF;
1017 out[25] = (n >> 8) & 0xFF;
1018 out[26] = (n >> 16) & 0xFF;
1019 out[27] = (n >> 24) & 0xFF;
1020 // bytes per second (rate * channels * bytes per channel)
1021 n = cl_capturevideo_soundrate * 2 * 2;
1022 out[28] = (n) & 0xFF;
1023 out[29] = (n >> 8) & 0xFF;
1024 out[30] = (n >> 16) & 0xFF;
1025 out[31] = (n >> 24) & 0xFF;
1026 // the length of the data chunk
1028 out[40] = (n) & 0xFF;
1029 out[41] = (n >> 8) & 0xFF;
1030 out[42] = (n >> 16) & 0xFF;
1031 out[43] = (n >> 24) & 0xFF;
1032 FS_Seek (cl_capturevideo_soundfile, 0, SEEK_SET);
1033 FS_Write (cl_capturevideo_soundfile, out, 44);
1034 FS_Close (cl_capturevideo_soundfile);
1035 cl_capturevideo_soundfile = NULL;
1038 if (cl_capturevideo_buffer)
1040 Mem_Free (cl_capturevideo_buffer);
1041 cl_capturevideo_buffer = NULL;
1044 cl_capturevideo_starttime = 0;
1045 cl_capturevideo_framerate = 0;
1046 cl_capturevideo_frame = 0;
1049 qboolean SCR_CaptureVideo_VideoFrame(int newframenum)
1051 int x = 0, y = 0, width = vid.width, height = vid.height;
1052 unsigned char *b, *out;
1054 int outoffset = (width/2)*(height/2);
1055 //return SCR_ScreenShot(filename, cl_capturevideo_buffer, cl_capturevideo_buffer + vid.width * vid.height * 3, cl_capturevideo_buffer + vid.width * vid.height * 6, 0, 0, vid.width, vid.height, false, false, false, jpeg, true);
1056 // speed is critical here, so do saving as directly as possible
1057 switch (cl_capturevideo_format)
1059 case CAPTUREVIDEOFORMAT_RAWYV12:
1060 // FIXME: width/height must be multiple of 2, enforce this?
1061 qglReadPixels (x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, cl_capturevideo_buffer);
1063 // process one line at a time, and CbCr every other line at 2 pixel intervals
1064 for (y = 0;y < height;y++)
1067 for (b = cl_capturevideo_buffer + (height-1-y)*width*3, out = cl_capturevideo_buffer + width*height*3 + y*width, x = 0;x < width;x++, b += 3, out++)
1068 *out = cl_capturevideo_yuvnormalizetable[0][cl_capturevideo_rgbtoyuvscaletable[0][0][b[0]] + cl_capturevideo_rgbtoyuvscaletable[0][1][b[1]] + cl_capturevideo_rgbtoyuvscaletable[0][2][b[2]]];
1071 // 2x2 Cb and Cr planes
1073 // low quality, no averaging
1074 for (b = cl_capturevideo_buffer + (height-2-y)*width*3, out = cl_capturevideo_buffer + width*height*3 + width*height + (y/2)*(width/2), x = 0;x < width/2;x++, b += 6, out++)
1077 out[0 ] = cl_capturevideo_yuvnormalizetable[2][cl_capturevideo_rgbtoyuvscaletable[2][0][b[0]] + cl_capturevideo_rgbtoyuvscaletable[2][1][b[1]] + cl_capturevideo_rgbtoyuvscaletable[2][2][b[2]] + 128];
1079 out[outoffset] = cl_capturevideo_yuvnormalizetable[1][cl_capturevideo_rgbtoyuvscaletable[1][0][b[0]] + cl_capturevideo_rgbtoyuvscaletable[1][1][b[1]] + cl_capturevideo_rgbtoyuvscaletable[1][2][b[2]] + 128];
1082 // high quality, averaging
1083 int inpitch = width*3;
1084 for (b = cl_capturevideo_buffer + (height-2-y)*width*3, out = cl_capturevideo_buffer + width*height*3 + width*height + (y/2)*(width/2), x = 0;x < width/2;x++, b += 6, out++)
1086 int blockr, blockg, blockb;
1087 blockr = (b[0] + b[3] + b[inpitch+0] + b[inpitch+3]) >> 2;
1088 blockg = (b[1] + b[4] + b[inpitch+1] + b[inpitch+4]) >> 2;
1089 blockb = (b[2] + b[5] + b[inpitch+2] + b[inpitch+5]) >> 2;
1091 out[0 ] = cl_capturevideo_yuvnormalizetable[2][cl_capturevideo_rgbtoyuvscaletable[2][0][blockr] + cl_capturevideo_rgbtoyuvscaletable[2][1][blockg] + cl_capturevideo_rgbtoyuvscaletable[2][2][blockb] + 128];
1093 out[outoffset] = cl_capturevideo_yuvnormalizetable[1][cl_capturevideo_rgbtoyuvscaletable[1][0][blockr] + cl_capturevideo_rgbtoyuvscaletable[1][1][blockg] + cl_capturevideo_rgbtoyuvscaletable[1][2][blockb] + 128];
1098 for (;cl_capturevideo_frame < newframenum;cl_capturevideo_frame++)
1099 if (!FS_Write (cl_capturevideo_videofile, cl_capturevideo_buffer + width*height*3, width*height+(width/2)*(height/2)*2))
1102 case CAPTUREVIDEOFORMAT_RAWRGB:
1103 qglReadPixels (x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, cl_capturevideo_buffer);
1105 for (;cl_capturevideo_frame < newframenum;cl_capturevideo_frame++)
1106 if (!FS_Write (cl_capturevideo_videofile, cl_capturevideo_buffer, width*height*3))
1109 case CAPTUREVIDEOFORMAT_JPEG:
1110 qglReadPixels (x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, cl_capturevideo_buffer);
1112 for (;cl_capturevideo_frame < newframenum;cl_capturevideo_frame++)
1114 sprintf(filename, "video/dp%06d.jpg", cl_capturevideo_frame);
1115 if (!JPEG_SaveImage_preflipped (filename, width, height, cl_capturevideo_buffer))
1119 case CAPTUREVIDEOFORMAT_TARGA:
1120 //return Image_WriteTGARGB_preflipped (filename, width, height, cl_capturevideo_buffer, cl_capturevideo_buffer + vid.width * vid.height * 3, );
1121 memset (cl_capturevideo_buffer, 0, 18);
1122 cl_capturevideo_buffer[2] = 2; // uncompressed type
1123 cl_capturevideo_buffer[12] = (width >> 0) & 0xFF;
1124 cl_capturevideo_buffer[13] = (width >> 8) & 0xFF;
1125 cl_capturevideo_buffer[14] = (height >> 0) & 0xFF;
1126 cl_capturevideo_buffer[15] = (height >> 8) & 0xFF;
1127 cl_capturevideo_buffer[16] = 24; // pixel size
1128 qglReadPixels (x, y, width, height, GL_BGR, GL_UNSIGNED_BYTE, cl_capturevideo_buffer + 18);
1130 for (;cl_capturevideo_frame < newframenum;cl_capturevideo_frame++)
1132 sprintf(filename, "video/dp%06d.tga", cl_capturevideo_frame);
1133 if (!FS_WriteFile (filename, cl_capturevideo_buffer, width*height*3 + 18))
1142 void SCR_CaptureVideo_SoundFrame(qbyte *bufstereo16le, size_t length, int rate)
1144 if (!cl_capturevideo_soundfile)
1146 cl_capturevideo_soundrate = rate;
1147 if (FS_Write (cl_capturevideo_soundfile, bufstereo16le, 4 * length) < (fs_offset_t)(4 * length))
1149 Cvar_SetValueQuick(&cl_capturevideo, 0);
1150 Con_Printf("video sound saving failed on frame %i, out of disk space? stopping video capture.\n", cl_capturevideo_frame);
1151 SCR_CaptureVideo_EndVideo();
1155 void SCR_CaptureVideo(void)
1158 if (cl_capturevideo.integer && r_render.integer)
1160 if (!cl_capturevideo_active)
1161 SCR_CaptureVideo_BeginVideo();
1162 if (cl_capturevideo_framerate != cl_capturevideo_fps.value)
1164 Con_Printf("You can not change the video framerate while recording a video.\n");
1165 Cvar_SetValueQuick(&cl_capturevideo_fps, cl_capturevideo_framerate);
1167 if (cl_capturevideo_soundfile)
1169 // preserve sound sync by duplicating frames when running slow
1170 newframenum = (Sys_DoubleTime() - cl_capturevideo_starttime) * cl_capturevideo_framerate;
1173 newframenum = cl_capturevideo_frame + 1;
1174 // if falling behind more than one second, stop
1175 if (newframenum - cl_capturevideo_frame > (int)ceil(cl_capturevideo_framerate))
1177 Cvar_SetValueQuick(&cl_capturevideo, 0);
1178 Con_Printf("video saving failed on frame %i, your machine is too slow for this capture speed.\n", cl_capturevideo_frame);
1179 SCR_CaptureVideo_EndVideo();
1183 if (!SCR_CaptureVideo_VideoFrame(newframenum))
1185 Cvar_SetValueQuick(&cl_capturevideo, 0);
1186 Con_Printf("video saving failed on frame %i, out of disk space? stopping video capture.\n", cl_capturevideo_frame);
1187 SCR_CaptureVideo_EndVideo();
1190 else if (cl_capturevideo_active)
1191 SCR_CaptureVideo_EndVideo();
1198 Grab six views for environment mapping tests
1205 qboolean flipx, flipy, flipdiagonaly;
1209 {{ 0, 0, 0}, "rt", false, false, false},
1210 {{ 0, 270, 0}, "ft", false, false, false},
1211 {{ 0, 180, 0}, "lf", false, false, false},
1212 {{ 0, 90, 0}, "bk", false, false, false},
1213 {{-90, 180, 0}, "up", true, true, false},
1214 {{ 90, 180, 0}, "dn", true, true, false},
1216 {{ 0, 0, 0}, "px", true, true, true},
1217 {{ 0, 90, 0}, "py", false, true, false},
1218 {{ 0, 180, 0}, "nx", false, false, true},
1219 {{ 0, 270, 0}, "ny", true, false, false},
1220 {{-90, 180, 0}, "pz", false, false, true},
1221 {{ 90, 180, 0}, "nz", false, false, true}
1224 static void R_Envmap_f (void)
1227 char filename[256], basename[256];
1232 if (Cmd_Argc() != 3)
1234 Con_Print("envmap <basename> <size>: save out 6 cubic environment map images, usable with loadsky, note that size must one of 128, 256, 512, or 1024 and can't be bigger than your current resolution\n");
1238 strlcpy (basename, Cmd_Argv(1), sizeof (basename));
1239 size = atoi(Cmd_Argv(2));
1240 if (size != 128 && size != 256 && size != 512 && size != 1024)
1242 Con_Print("envmap: size must be one of 128, 256, 512, or 1024\n");
1245 if (size > vid.width || size > vid.height)
1247 Con_Print("envmap: your resolution is not big enough to render that size\n");
1255 r_refdef.width = size;
1256 r_refdef.height = size;
1258 r_refdef.fov_x = 90;
1259 r_refdef.fov_y = 90;
1261 buffer1 = (qbyte *)Mem_Alloc(tempmempool, size * size * 3);
1262 buffer2 = (qbyte *)Mem_Alloc(tempmempool, size * size * 3);
1263 buffer3 = (qbyte *)Mem_Alloc(tempmempool, size * size * 3 + 18);
1265 for (j = 0;j < 12;j++)
1267 sprintf(filename, "env/%s%s.tga", basename, envmapinfo[j].name);
1268 Matrix4x4_CreateFromQuakeEntity(&r_refdef.viewentitymatrix, r_vieworigin[0], r_vieworigin[1], r_vieworigin[2], envmapinfo[j].angles[0], envmapinfo[j].angles[1], envmapinfo[j].angles[2], 1);
1273 SCR_ScreenShot(filename, buffer1, buffer2, buffer3, 0, vid.height - (r_refdef.y + r_refdef.height), size, size, envmapinfo[j].flipx, envmapinfo[j].flipy, envmapinfo[j].flipdiagonaly, false, false);
1283 //=============================================================================
1285 // LordHavoc: SHOWLMP stuff
1286 #define SHOWLMP_MAXLABELS 256
1287 typedef struct showlmp_s
1297 showlmp_t showlmp[SHOWLMP_MAXLABELS];
1299 void SHOWLMP_decodehide(void)
1303 lmplabel = MSG_ReadString();
1304 for (i = 0;i < SHOWLMP_MAXLABELS;i++)
1305 if (showlmp[i].isactive && strcmp(showlmp[i].label, lmplabel) == 0)
1307 showlmp[i].isactive = false;
1312 void SHOWLMP_decodeshow(void)
1315 char lmplabel[256], picname[256];
1317 strlcpy (lmplabel,MSG_ReadString(), sizeof (lmplabel));
1318 strlcpy (picname, MSG_ReadString(), sizeof (picname));
1319 if (gamemode == GAME_NEHAHRA) // LordHavoc: nasty old legacy junk
1326 x = MSG_ReadShort();
1327 y = MSG_ReadShort();
1330 for (i = 0;i < SHOWLMP_MAXLABELS;i++)
1331 if (showlmp[i].isactive)
1333 if (strcmp(showlmp[i].label, lmplabel) == 0)
1336 break; // drop out to replace it
1339 else if (k < 0) // find first empty one to replace
1342 return; // none found to replace
1343 // change existing one
1344 showlmp[k].isactive = true;
1345 strlcpy (showlmp[k].label, lmplabel, sizeof (showlmp[k].label));
1346 strlcpy (showlmp[k].pic, picname, sizeof (showlmp[k].pic));
1351 void SHOWLMP_drawall(void)
1354 for (i = 0;i < SHOWLMP_MAXLABELS;i++)
1355 if (showlmp[i].isactive)
1356 DrawQ_Pic(showlmp[i].x, showlmp[i].y, showlmp[i].pic, 0, 0, 1, 1, 1, 1, 0);
1359 void SHOWLMP_clear(void)
1362 for (i = 0;i < SHOWLMP_MAXLABELS;i++)
1363 showlmp[i].isactive = false;
1366 void CL_SetupScreenSize(void)
1368 float conwidth, conheight;
1370 VID_UpdateGamma(false);
1372 conwidth = bound(320, vid_conwidth.value, 2048);
1373 conheight = bound(200, vid_conheight.value, 1536);
1374 if (vid_conwidth.value != conwidth)
1375 Cvar_SetValue("vid_conwidth", conwidth);
1376 if (vid_conheight.value != conheight)
1377 Cvar_SetValue("vid_conheight", conheight);
1379 vid_conwidth.integer = vid_conwidth.integer;
1380 vid_conheight.integer = vid_conheight.integer;
1382 SCR_SetUpToDrawConsole();
1385 extern void R_Shadow_EditLights_DrawSelectedLightProperties(void);
1386 void CL_UpdateScreen(void)
1388 if (!scr_initialized || !con_initialized || vid_hidden)
1389 return; // not initialized yet
1391 // don't allow cheats in multiplayer
1392 if (!cl.islocalgame && cl.worldmodel)
1394 if (r_fullbright.integer != 0)
1395 Cvar_Set ("r_fullbright", "0");
1396 if (r_ambient.value != 0)
1397 Cvar_Set ("r_ambient", "0");
1401 if (scr_viewsize.value < 30)
1402 Cvar_Set ("viewsize","30");
1403 if (scr_viewsize.value > 120)
1404 Cvar_Set ("viewsize","120");
1406 // bound field of view
1407 if (scr_fov.value < 1)
1408 Cvar_Set ("fov","1");
1409 if (scr_fov.value > 170)
1410 Cvar_Set ("fov","170");
1412 // intermission is always full screen
1413 if (cl.intermission)
1417 if (scr_viewsize.value >= 120)
1418 sb_lines = 0; // no status bar at all
1419 else if (scr_viewsize.value >= 110)
1420 sb_lines = 24; // no inventory
1425 r_refdef.colormask[0] = 1;
1426 r_refdef.colormask[1] = 1;
1427 r_refdef.colormask[2] = 1;
1431 if (cls.signon == SIGNONS)
1432 R_TimeReport("other");
1434 CL_SetupScreenSize();
1438 if (cls.signon == SIGNONS)
1439 R_TimeReport("setup");
1441 //FIXME: force menu if nothing else to look at?
1442 //if (key_dest == key_game && cls.signon != SIGNONS && cls.state == ca_disconnected)
1444 if (cls.signon == SIGNONS)
1449 if (!r_letterbox.value)
1452 SCR_CheckDrawCenterString();
1458 if (cls.signon == SIGNONS)
1462 R_TimeReport_Start();
1464 R_Shadow_EditLights_DrawSelectedLightProperties();
1473 void CL_Screen_NewMap(void)