6 cvar_t scr_viewsize = {CVAR_SAVE, "viewsize","100"};
7 cvar_t scr_fov = {CVAR_SAVE, "fov","90"}; // 10 - 170
8 cvar_t scr_conspeed = {CVAR_SAVE, "scr_conspeed","900"}; // LordHavoc: quake used 300
9 cvar_t scr_centertime = {0, "scr_centertime","2"};
10 cvar_t scr_showram = {CVAR_SAVE, "showram","1"};
11 cvar_t scr_showturtle = {CVAR_SAVE, "showturtle","0"};
12 cvar_t scr_showpause = {CVAR_SAVE, "showpause","1"};
13 cvar_t scr_printspeed = {0, "scr_printspeed","8"};
14 cvar_t scr_2dresolution = {CVAR_SAVE, "scr_2dresolution", "1"};
15 cvar_t scr_screenshot_jpeg = {CVAR_SAVE, "scr_screenshot_jpeg","0"};
16 cvar_t cl_avidemo = {0, "cl_avidemo", "0"};
18 qboolean scr_initialized; // ready to draw
20 float scr_con_current;
21 float scr_conlines; // lines of console to display
26 qboolean scr_drawloading = false;
28 static qbyte menuplyr_pixels[4096];
30 void DrawCrosshair(int num);
31 void V_CalcRefdef (void);
32 static void SCR_ScreenShot_f (void);
33 static void R_Envmap_f (void);
36 void R_ClearScreen(void);
39 ===============================================================================
43 ===============================================================================
46 char scr_centerstring[1024];
47 float scr_centertime_start; // for slow victory printing
48 float scr_centertime_off;
57 Called for important messages that should stay in the center of the screen
61 void SCR_CenterPrint (char *str)
63 strncpy (scr_centerstring, str, sizeof(scr_centerstring)-1);
64 scr_centertime_off = scr_centertime.value;
65 scr_centertime_start = cl.time;
67 // count the number of lines for centering
78 void SCR_DrawCenterString (void)
85 // the finale prints the characters one at a time
87 remaining = scr_printspeed.value * (cl.time - scr_centertime_start);
92 start = scr_centerstring;
94 if (scr_center_lines <= 4)
95 y = vid.conheight*0.35;
101 // scan the width of the line
102 for (l=0 ; l<40 ; l++)
103 if (start[l] == '\n' || !start[l])
105 x = (vid.conwidth - l*8)/2;
110 DrawQ_String(x, y, start, l, 8, 8, 1, 1, 1, 1, 0);
118 while (*start && *start != '\n')
123 start++; // skip the \n
127 void SCR_CheckDrawCenterString (void)
129 if (scr_center_lines > scr_erase_lines)
130 scr_erase_lines = scr_center_lines;
132 scr_centertime_off -= host_frametime;
134 // don't draw if this is a normal stats-screen intermission,
135 // only if it is not an intermission, or a finale intermission
136 if (cl.intermission == 1)
138 if (scr_centertime_off <= 0 && !cl.intermission)
140 if (key_dest != key_game)
143 SCR_DrawCenterString ();
151 void SCR_DrawTurtle (void)
155 if (cls.state != ca_connected)
158 if (!scr_showturtle.integer)
161 if (host_frametime < 0.1)
171 DrawQ_Pic (0, 0, "turtle", 0, 0, 1, 1, 1, 1, 0);
179 void SCR_DrawNet (void)
181 if (cls.state != ca_connected)
183 if (realtime - cl.last_received_message < 0.3)
185 if (cls.demoplayback)
188 DrawQ_Pic (64, 0, "net", 0, 0, 1, 1, 1, 1, 0);
196 void SCR_DrawPause (void)
200 if (cls.state != ca_connected)
203 if (!scr_showpause.integer) // turn off for screenshots
209 pic = Draw_CachePic ("gfx/pause.lmp");
210 DrawQ_Pic ((vid.conwidth - pic->width)/2, (vid.conheight - pic->height)/2, "gfx/pause.lmp", 0, 0, 1, 1, 1, 1, 0);
220 void SCR_DrawLoading (void)
224 pic = Draw_CachePic ("gfx/loading.lmp");
225 DrawQ_Pic ((vid.conwidth - pic->width)/2, (vid.conheight - pic->height)/2, "gfx/loading.lmp", 0, 0, 1, 1, 1, 1, 0);
230 //=============================================================================
235 SCR_SetUpToDrawConsole
238 void SCR_SetUpToDrawConsole (void)
242 if (key_dest == key_game && cls.signon != SIGNONS)
243 key_consoleactive |= KEY_CONSOLEACTIVE_FORCED;
245 key_consoleactive &= ~KEY_CONSOLEACTIVE_FORCED;
247 // decide on the height of the console
248 if (key_consoleactive & KEY_CONSOLEACTIVE_FORCED)
249 scr_conlines = vid.conheight; // full screen
250 else if (key_consoleactive & KEY_CONSOLEACTIVE_USER)
251 scr_conlines = vid.conheight/2; // half screen
253 scr_conlines = 0; // none visible
255 if (scr_conspeed.value)
257 if (scr_conlines < scr_con_current)
259 scr_con_current -= scr_conspeed.value*host_realframetime;
260 if (scr_conlines > scr_con_current)
261 scr_con_current = scr_conlines;
264 else if (scr_conlines > scr_con_current)
266 scr_con_current += scr_conspeed.value*host_realframetime;
267 if (scr_conlines < scr_con_current)
268 scr_con_current = scr_conlines;
272 scr_con_current = scr_conlines;
280 void SCR_DrawConsole (void)
284 Con_DrawConsole (scr_con_current);
289 if (key_dest == key_game || key_dest == key_message)
290 Con_DrawNotify (); // only draw notify in game
296 SCR_BeginLoadingPlaque
300 void SCR_BeginLoadingPlaque (void)
305 S_StopAllSounds (true);
307 scr_drawloading = true;
309 scr_drawloading = true;
313 //=============================================================================
315 char r_speeds_string[1024];
316 int speedstringcount, r_timereport_active;
317 double r_timereport_temp = 0, r_timereport_current = 0, r_timereport_start = 0;
319 void R_TimeReport(char *desc)
325 if (!r_timereport_active)
328 r_timereport_temp = r_timereport_current;
329 r_timereport_current = Sys_DoubleTime();
330 t = (int) ((r_timereport_current - r_timereport_temp) * 1000000.0);
332 sprintf(tempbuf, "%8i %s", t, desc);
333 length = strlen(tempbuf);
335 tempbuf[length++] = ' ';
337 if (speedstringcount + length > (vid.conwidth / 8))
339 strcat(r_speeds_string, "\n");
340 speedstringcount = 0;
342 // skip the space at the beginning if it's the first on the line
343 if (speedstringcount == 0)
345 strcat(r_speeds_string, tempbuf + 1);
346 speedstringcount = length - 1;
350 strcat(r_speeds_string, tempbuf);
351 speedstringcount += length;
355 extern int c_rt_lights, c_rt_clears, c_rt_scissored;
356 extern int c_rt_shadowmeshes, c_rt_shadowtris, c_rt_lightmeshes, c_rt_lighttris;
357 extern int c_rtcached_shadowmeshes, c_rtcached_shadowtris;
358 extern int r_shadow_lightingmode;
359 void R_TimeReport_Start(void)
361 r_timereport_active = r_speeds.integer && cls.signon == SIGNONS && cls.state == ca_connected;
362 r_speeds_string[0] = 0;
363 if (r_timereport_active)
365 speedstringcount = 0;
366 AngleVectors (r_refdef.viewangles, vpn, NULL, NULL);
367 sprintf(r_speeds_string,
368 "org:'%+8.2f %+8.2f %+8.2f' ang:'%+4.0f %+4.0f %+4.0f' dir:'%+2.3f %+2.3f %+2.3f'\n"
369 "world:%6i faces%6i nodes%6i leafs%6i dlitwalls\n"
370 "%5i models%5i bmodels%5i sprites%6i particles%4i dlights\n"
371 "%6i modeltris%6i meshs%6i meshtris\n",
372 r_refdef.vieworg[0], r_refdef.vieworg[1], r_refdef.vieworg[2], r_refdef.viewangles[0], r_refdef.viewangles[1], r_refdef.viewangles[2], vpn[0], vpn[1], vpn[2],
373 c_faces, c_nodes, c_leafs, c_light_polys,
374 c_models, c_bmodels, c_sprites, c_particles, c_dlights,
375 c_alias_polys, c_meshs, c_meshelements / 3);
376 if (r_shadow_lightingmode)
378 sprintf(r_speeds_string + strlen(r_speeds_string),
379 "realtime lighting:%4i lights%4i clears%4i scissored\n"
380 "dynamic: %6i shadowmeshes%6i shadowtris%6i lightmeshes%6i lighttris\n"
381 "precomputed: %6i shadowmeshes%6i shadowtris\n",
382 c_rt_lights, c_rt_clears, c_rt_scissored,
383 c_rt_shadowmeshes, c_rt_shadowtris, c_rt_lightmeshes, c_rt_lighttris,
384 c_rtcached_shadowmeshes, c_rtcached_shadowtris);
399 r_timereport_start = Sys_DoubleTime();
403 void R_TimeReport_End(void)
405 r_timereport_current = r_timereport_start;
406 R_TimeReport("total");
408 if (r_timereport_active)
412 for (i = 0;r_speeds_string[i];i++)
413 if (r_speeds_string[i] == '\n')
415 y = vid.conheight - sb_lines - lines * 8;
417 DrawQ_Fill(0, y, vid.conwidth, lines * 8, 0, 0, 0, 0.5, 0);
418 while (r_speeds_string[i])
421 while (r_speeds_string[i] && r_speeds_string[i] != '\n')
424 DrawQ_String(0, y, r_speeds_string + j, i - j, 8, 8, 1, 1, 1, 1, 0);
425 if (r_speeds_string[i] == '\n')
439 void SCR_SizeUp_f (void)
441 Cvar_SetValue ("viewsize",scr_viewsize.value+10);
452 void SCR_SizeDown_f (void)
454 Cvar_SetValue ("viewsize",scr_viewsize.value-10);
457 void CL_Screen_Init(void)
461 Cvar_RegisterVariable (&scr_fov);
462 Cvar_RegisterVariable (&scr_viewsize);
463 Cvar_RegisterVariable (&scr_conspeed);
464 Cvar_RegisterVariable (&scr_showram);
465 Cvar_RegisterVariable (&scr_showturtle);
466 Cvar_RegisterVariable (&scr_showpause);
467 Cvar_RegisterVariable (&scr_centertime);
468 Cvar_RegisterVariable (&scr_printspeed);
469 Cvar_RegisterVariable (&scr_2dresolution);
470 Cvar_RegisterVariable (&scr_screenshot_jpeg);
471 Cvar_RegisterVariable (&cl_avidemo);
473 Cmd_AddCommand ("sizeup",SCR_SizeUp_f);
474 Cmd_AddCommand ("sizedown",SCR_SizeDown_f);
475 Cmd_AddCommand ("screenshot",SCR_ScreenShot_f);
476 Cmd_AddCommand ("envmap", R_Envmap_f);
478 scr_initialized = true;
481 // load the image data for the player image in the config menu
482 dat = (qpic_t *)FS_LoadFile ("gfx/menuplyr.lmp", false);
484 Sys_Error("unable to load gfx/menuplyr.lmp");
487 if (dat->width*dat->height <= 4096)
488 memcpy (menuplyr_pixels, dat->data, dat->width * dat->height);
490 Con_Printf("gfx/menuplyr.lmp larger than 4k buffer");
494 void DrawQ_Clear(void)
496 r_refdef.drawqueuesize = 0;
499 static int picelements[6] = {0, 1, 2, 0, 2, 3};
500 void DrawQ_Pic(float x, float y, char *picname, float width, float height, float red, float green, float blue, float alpha, int flags)
503 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);
507 drawqueuemesh_t mesh;
508 if (alpha < (1.0f / 255.0f) || !picname || !picname[0])
510 pic = Draw_CachePic(picname);
514 height = pic->height;
515 mesh.texture = pic->tex;
516 mesh.numtriangles = 2;
517 mesh.numvertices = 4;
518 mesh.indices = picelements;
519 mesh.vertex3f = floats;
520 mesh.texcoord2f = floats + 16;
521 mesh.color4f = floats + 32;
522 memset(floats, 0, sizeof(floats));
523 mesh.vertex3f[0] = mesh.vertex3f[12] = x;
524 mesh.vertex3f[1] = mesh.vertex3f[5] = y;
525 mesh.vertex3f[4] = mesh.vertex3f[8] = x + width;
526 mesh.vertex3f[9] = mesh.vertex3f[13] = y + height;
527 mesh.texcoord2f[4] = mesh.texcoord2f[8] = mesh.texcoord2f[9] = mesh.texcoord2f[13] = 1;
528 mesh.color4f[0] = mesh.color4f[4] = mesh.color4f[8] = mesh.color4f[12] = red;
529 mesh.color4f[1] = mesh.color4f[5] = mesh.color4f[9] = mesh.color4f[13] = green;
530 mesh.color4f[2] = mesh.color4f[6] = mesh.color4f[10] = mesh.color4f[14] = blue;
531 mesh.color4f[3] = mesh.color4f[7] = mesh.color4f[11] = mesh.color4f[15] = alpha;
532 DrawQ_Mesh (&mesh, flags);
536 if (alpha < (1.0f / 255.0f) || !picname || !picname[0])
538 size = sizeof(*dq) + ((strlen(picname) + 1 + 3) & ~3);
539 if (r_refdef.drawqueuesize + size > r_refdef.maxdrawqueuesize)
541 red = bound(0, red, 1);
542 green = bound(0, green, 1);
543 blue = bound(0, blue, 1);
544 alpha = bound(0, alpha, 1);
545 dq = (void *)(r_refdef.drawqueue + r_refdef.drawqueuesize);
547 dq->command = DRAWQUEUE_PIC;
549 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));
552 // if these are not zero, they override the pic's size
555 strcpy((char *)(dq + 1), picname);
556 r_refdef.drawqueuesize += dq->size;
560 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)
565 if (alpha < (1.0f / 255.0f))
568 len = strlen(string);
570 for (len = 0;len < maxlen && string[len];len++);
571 for (;len > 0 && string[0] == ' ';string++, x += scalex, len--);
572 for (;len > 0 && string[len - 1] == ' ';len--);
575 if (x >= vid.conwidth || y >= vid.conheight || x < (-scalex * maxlen) || y < (-scaley))
577 size = sizeof(*dq) + ((len + 1 + 3) & ~3);
578 if (r_refdef.drawqueuesize + size > r_refdef.maxdrawqueuesize)
580 red = bound(0, red, 1);
581 green = bound(0, green, 1);
582 blue = bound(0, blue, 1);
583 alpha = bound(0, alpha, 1);
584 dq = (void *)(r_refdef.drawqueue + r_refdef.drawqueuesize);
586 dq->command = DRAWQUEUE_STRING;
588 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));
593 out = (char *)(dq + 1);
594 memcpy(out, string, len);
596 r_refdef.drawqueuesize += dq->size;
599 void DrawQ_Fill (float x, float y, float w, float h, float red, float green, float blue, float alpha, int flags)
602 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);
605 drawqueuemesh_t mesh;
606 if (alpha < (1.0f / 255.0f))
609 mesh.numtriangles = 2;
610 mesh.numvertices = 4;
611 mesh.indices = picelements;
612 mesh.vertex3f = floats;
613 mesh.texcoord2f = floats + 16;
614 mesh.color4f = floats + 32;
615 memset(floats, 0, sizeof(floats));
616 mesh.vertex3f[0] = mesh.vertex3f[12] = x;
617 mesh.vertex3f[1] = mesh.vertex3f[5] = y;
618 mesh.vertex3f[4] = mesh.vertex3f[8] = x + w;
619 mesh.vertex3f[9] = mesh.vertex3f[13] = y + h;
620 mesh.color4f[0] = mesh.color4f[4] = mesh.color4f[8] = mesh.color4f[12] = red;
621 mesh.color4f[1] = mesh.color4f[5] = mesh.color4f[9] = mesh.color4f[13] = green;
622 mesh.color4f[2] = mesh.color4f[6] = mesh.color4f[10] = mesh.color4f[14] = blue;
623 mesh.color4f[3] = mesh.color4f[7] = mesh.color4f[11] = mesh.color4f[15] = alpha;
624 DrawQ_Mesh (&mesh, flags);
628 if (alpha < (1.0f / 255.0f))
630 size = sizeof(*dq) + 4;
631 if (r_refdef.drawqueuesize + size > r_refdef.maxdrawqueuesize)
633 red = bound(0, red, 1);
634 green = bound(0, green, 1);
635 blue = bound(0, blue, 1);
636 alpha = bound(0, alpha, 1);
637 dq = (void *)(r_refdef.drawqueue + r_refdef.drawqueuesize);
639 dq->command = DRAWQUEUE_PIC;
641 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));
647 *((char *)(dq + 1)) = 0;
648 r_refdef.drawqueuesize += dq->size;
652 void DrawQ_SuperPic(float x, float y, 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)
656 drawqueuemesh_t mesh;
657 memset(&mesh, 0, sizeof(mesh));
658 if (picname && picname[0])
660 pic = Draw_CachePic(picname);
664 height = pic->height;
665 mesh.texture = pic->tex;
667 mesh.numtriangles = 2;
668 mesh.numvertices = 4;
669 mesh.element3i = picelements;
670 mesh.vertex3f = floats;
671 mesh.texcoord2f = floats + 12;
672 mesh.color4f = floats + 20;
673 memset(floats, 0, sizeof(floats));
674 mesh.vertex3f[0] = mesh.vertex3f[9] = x;
675 mesh.vertex3f[1] = mesh.vertex3f[4] = y;
676 mesh.vertex3f[3] = mesh.vertex3f[6] = x + width;
677 mesh.vertex3f[7] = mesh.vertex3f[10] = y + height;
678 mesh.texcoord2f[0] = s1;mesh.texcoord2f[1] = t1;mesh.color4f[ 0] = r1;mesh.color4f[ 1] = g1;mesh.color4f[ 2] = b1;mesh.color4f[ 3] = a1;
679 mesh.texcoord2f[2] = s2;mesh.texcoord2f[3] = t2;mesh.color4f[ 4] = r2;mesh.color4f[ 5] = g2;mesh.color4f[ 6] = b2;mesh.color4f[ 7] = a2;
680 mesh.texcoord2f[4] = s4;mesh.texcoord2f[5] = t4;mesh.color4f[ 8] = r4;mesh.color4f[ 9] = g4;mesh.color4f[10] = b4;mesh.color4f[11] = a4;
681 mesh.texcoord2f[6] = s3;mesh.texcoord2f[7] = t3;mesh.color4f[12] = r3;mesh.color4f[13] = g3;mesh.color4f[14] = b3;mesh.color4f[15] = a3;
682 DrawQ_Mesh (&mesh, flags);
685 void DrawQ_Mesh (drawqueuemesh_t *mesh, int flags)
692 size += sizeof(drawqueuemesh_t);
693 size += sizeof(int[3]) * mesh->numtriangles;
694 size += sizeof(float[3]) * mesh->numvertices;
695 size += sizeof(float[2]) * mesh->numvertices;
696 size += sizeof(float[4]) * mesh->numvertices;
697 if (r_refdef.drawqueuesize + size > r_refdef.maxdrawqueuesize)
699 dq = (void *)(r_refdef.drawqueue + r_refdef.drawqueuesize);
701 dq->command = DRAWQUEUE_MESH;
708 p = (void *)(dq + 1);
709 m = p;(qbyte *)p += sizeof(drawqueuemesh_t);
710 m->numtriangles = mesh->numtriangles;
711 m->numvertices = mesh->numvertices;
712 m->texture = mesh->texture;
713 m->element3i = p;memcpy(m->element3i , mesh->element3i , m->numtriangles * sizeof(int[3]));(qbyte *)p += m->numtriangles * sizeof(int[3]);
714 m->vertex3f = p;memcpy(m->vertex3f , mesh->vertex3f , m->numvertices * sizeof(float[3]));(qbyte *)p += m->numvertices * sizeof(float[3]);
715 m->texcoord2f = p;memcpy(m->texcoord2f, mesh->texcoord2f, m->numvertices * sizeof(float[2]));(qbyte *)p += m->numvertices * sizeof(float[2]);
716 m->color4f = p;memcpy(m->color4f , mesh->color4f , m->numvertices * sizeof(float[4]));(qbyte *)p += m->numvertices * sizeof(float[4]);
717 r_refdef.drawqueuesize += dq->size;
725 float CalcFov (float fov_x, float width, float height)
727 // calculate vision size and alter by aspect, then convert back to angle
728 return atan (height / (width / tan(fov_x/360*M_PI))) * 360 / M_PI;
735 Must be called whenever vid changes
739 static void SCR_CalcRefdef (void)
744 //========================================
747 if (scr_viewsize.value < 30)
748 Cvar_Set ("viewsize","30");
749 if (scr_viewsize.value > 120)
750 Cvar_Set ("viewsize","120");
752 // bound field of view
753 if (scr_fov.value < 10)
754 Cvar_Set ("fov","10");
755 if (scr_fov.value > 170)
756 Cvar_Set ("fov","170");
758 // intermission is always full screen
766 if (scr_viewsize.value >= 120)
767 sb_lines = 0; // no status bar at all
768 else if (scr_viewsize.value >= 110)
769 sb_lines = 24; // no inventory
772 size = scr_viewsize.value * (1.0 / 100.0);
777 r_refdef.width = vid.realwidth;
778 r_refdef.height = vid.realheight;
784 r_refdef.width = vid.realwidth * size;
785 r_refdef.height = vid.realheight * size;
786 r_refdef.x = (vid.realwidth - r_refdef.width)/2;
787 r_refdef.y = (vid.realheight - r_refdef.height)/2;
790 r_refdef.width = bound(0, r_refdef.width, vid.realwidth);
791 r_refdef.height = bound(0, r_refdef.height, vid.realheight);
792 r_refdef.x = bound(0, r_refdef.x, vid.realwidth - r_refdef.width) + vid.realx;
793 r_refdef.y = bound(0, r_refdef.y, vid.realheight - r_refdef.height) + vid.realy;
795 // LordHavoc: viewzoom (zoom in for sniper rifles, etc)
796 r_refdef.fov_x = scr_fov.value * cl.viewzoom;
797 r_refdef.fov_y = CalcFov (r_refdef.fov_x, r_refdef.width, r_refdef.height);
801 Mod_CheckLoaded(cl.worldmodel);
802 contents = Mod_PointContents(r_refdef.vieworg, cl.worldmodel);
803 if (contents != CONTENTS_EMPTY && contents != CONTENTS_SOLID)
805 r_refdef.fov_x *= (sin(cl.time * 4.7) * 0.015 + 0.985);
806 r_refdef.fov_y *= (sin(cl.time * 3.0) * 0.015 + 0.985);
816 void SCR_ScreenShot_f (void)
820 char checkname[MAX_OSPATH];
822 qboolean jpeg = (scr_screenshot_jpeg.integer != 0);
829 // find a file name to save it to
830 for (; i<=9999 ; i++)
832 sprintf (filename, "dp%04i.%s", i, extens);
833 sprintf (checkname, "%s/%s", fs_gamedir, filename);
834 if (!FS_SysFileExists(checkname))
839 Con_Printf ("SCR_ScreenShot_f: Couldn't create the image file\n");
843 if (SCR_ScreenShot (filename, vid.realx, vid.realy, vid.realwidth, vid.realheight, jpeg))
844 Con_Printf ("Wrote %s\n", filename);
846 Con_Printf ("unable to write %s\n", filename);
849 static int cl_avidemo_frame = 0;
851 void SCR_CaptureAVIDemo(void)
854 sprintf(filename, "dpavi%06d.tga", cl_avidemo_frame);
855 if (SCR_ScreenShot(filename, vid.realx, vid.realy, vid.realwidth, vid.realheight, false))
859 Cvar_SetValueQuick(&cl_avidemo, 0);
860 Con_Printf("avi saving failed on frame %i, out of disk space? stopping avi demo catpure.\n", cl_avidemo_frame);
861 cl_avidemo_frame = 0;
869 Grab six views for environment mapping tests
881 {{ 0, 180, 0}, "bk"},
882 {{ 0, 270, 0}, "lf"},
883 {{-90, 90, 0}, "up"},
887 static void R_Envmap_f (void)
890 char filename[256], basename[256];
894 Con_Printf ("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");
898 strcpy(basename, Cmd_Argv(1));
899 size = atoi(Cmd_Argv(2));
900 if (size != 128 && size != 256 && size != 512 && size != 1024)
902 Con_Printf("envmap: size must be one of 128, 256, 512, or 1024\n");
905 if (size > vid.realwidth || size > vid.realheight)
907 Con_Printf("envmap: your resolution is not big enough to render that size\n");
915 r_refdef.width = size;
916 r_refdef.height = size;
921 for (j = 0;j < 6;j++)
923 sprintf(filename, "env/%s%s.tga", basename, envmapinfo[j].name);
924 VectorCopy(envmapinfo[j].angles, r_refdef.viewangles);
927 SCR_ScreenShot(filename, vid.realx, vid.realy, size, size, false);
933 //=============================================================================
935 // LordHavoc: SHOWLMP stuff
936 #define SHOWLMP_MAXLABELS 256
937 typedef struct showlmp_s
947 showlmp_t showlmp[SHOWLMP_MAXLABELS];
949 void SHOWLMP_decodehide(void)
953 lmplabel = MSG_ReadString();
954 for (i = 0;i < SHOWLMP_MAXLABELS;i++)
955 if (showlmp[i].isactive && strcmp(showlmp[i].label, lmplabel) == 0)
957 showlmp[i].isactive = false;
962 void SHOWLMP_decodeshow(void)
965 qbyte lmplabel[256], picname[256];
967 strcpy(lmplabel,MSG_ReadString());
968 strcpy(picname, MSG_ReadString());
969 if (gamemode == GAME_NEHAHRA) // LordHavoc: nasty old legacy junk
980 for (i = 0;i < SHOWLMP_MAXLABELS;i++)
981 if (showlmp[i].isactive)
983 if (strcmp(showlmp[i].label, lmplabel) == 0)
986 break; // drop out to replace it
989 else if (k < 0) // find first empty one to replace
992 return; // none found to replace
993 // change existing one
994 showlmp[k].isactive = true;
995 strcpy(showlmp[k].label, lmplabel);
996 strcpy(showlmp[k].pic, picname);
1001 void SHOWLMP_drawall(void)
1004 for (i = 0;i < SHOWLMP_MAXLABELS;i++)
1005 if (showlmp[i].isactive)
1006 DrawQ_Pic(showlmp[i].x, showlmp[i].y, showlmp[i].pic, 0, 0, 1, 1, 1, 1, 0);
1009 void SHOWLMP_clear(void)
1012 for (i = 0;i < SHOWLMP_MAXLABELS;i++)
1013 showlmp[i].isactive = false;
1016 void CL_SetupScreenSize(void)
1018 static float old2dresolution = -1;
1020 VID_GetWindowSize (&vid.realx, &vid.realy, &vid.realwidth, &vid.realheight);
1022 VID_UpdateGamma(false);
1024 if (scr_2dresolution.value != old2dresolution)
1026 Cvar_SetValue("scr_2dresolution", bound(0.0f, scr_2dresolution.value, 1.0f));
1027 old2dresolution = scr_2dresolution.value;
1030 if (vid.realwidth > 320)
1032 vid.conwidth = (vid.realwidth - 320) * scr_2dresolution.value + 320;
1033 vid.conwidth = bound(320, vid.conwidth, vid.realwidth);
1038 if (vid.realheight > 240)
1040 vid.conheight = (vid.realheight - 240) * scr_2dresolution.value + 240;
1041 vid.conheight = bound(240, vid.conheight, vid.realheight);
1044 vid.conheight = 240;
1046 SCR_SetUpToDrawConsole();
1048 // determine size of refresh window
1052 extern void R_Shadow_EditLights_DrawSelectedLightProperties(void);
1053 void CL_UpdateScreen(void)
1055 if (!scr_initialized || !con_initialized || vid_hidden)
1056 return; // not initialized yet
1058 if (cl_avidemo.integer)
1059 SCR_CaptureAVIDemo();
1061 cl_avidemo_frame = 0;
1063 if (cls.signon == SIGNONS)
1064 R_TimeReport("other");
1066 CL_SetupScreenSize();
1073 if (cls.signon == SIGNONS)
1074 R_TimeReport("setup");
1076 //FIXME: force menu if nothing else to look at?
1077 //if (key_dest == key_game && cls.signon != SIGNONS && cls.state == ca_disconnected)
1079 if (scr_drawloading)
1081 scr_drawloading = false;
1086 if (cls.signon == SIGNONS)
1093 SCR_CheckDrawCenterString();
1098 if (cls.signon == SIGNONS)
1102 R_TimeReport_Start();
1104 R_Shadow_EditLights_DrawSelectedLightProperties();
1111 void CL_Screen_NewMap(void)