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 void R_TimeReport_Start(void)
360 r_timereport_active = r_speeds.integer && cls.signon == SIGNONS && cls.state == ca_connected;
361 r_speeds_string[0] = 0;
362 if (r_timereport_active)
364 speedstringcount = 0;
365 AngleVectors (r_refdef.viewangles, vpn, NULL, NULL);
366 sprintf(r_speeds_string,
367 "org:'%+8.2f %+8.2f %+8.2f' ang:'%+4.0f %+4.0f %+4.0f' dir:'%+2.3f %+2.3f %+2.3f'\n"
368 "world:%6i faces%6i nodes%6i leafs%6i dlitwalls\n"
369 "%5i models%5i bmodels%5i sprites%6i particles%4i dlights\n"
370 "%6i modeltris%6i meshs%6i meshtris\n",
371 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],
372 c_faces, c_nodes, c_leafs, c_light_polys,
373 c_models, c_bmodels, c_sprites, c_particles, c_dlights,
374 c_alias_polys, c_meshs, c_meshelements / 3);
376 sprintf(r_speeds_string + strlen(r_speeds_string),
377 "realtime lighting:%4i lights%4i clears%4i scissored\n"
378 "dynamic: %6i shadowmeshes%6i shadowtris%6i lightmeshes%6i lighttris\n"
379 "precomputed: %6i shadowmeshes%6i shadowtris\n",
380 c_rt_lights, c_rt_clears, c_rt_scissored,
381 c_rt_shadowmeshes, c_rt_shadowtris, c_rt_lightmeshes, c_rt_lighttris,
382 c_rtcached_shadowmeshes, c_rtcached_shadowtris);
396 r_timereport_start = Sys_DoubleTime();
400 void R_TimeReport_End(void)
402 r_timereport_current = r_timereport_start;
403 R_TimeReport("total");
405 if (r_timereport_active)
409 for (i = 0;r_speeds_string[i];i++)
410 if (r_speeds_string[i] == '\n')
412 y = vid.conheight - sb_lines - lines * 8;
414 DrawQ_Fill(0, y, vid.conwidth, lines * 8, 0, 0, 0, 0.5, 0);
415 while (r_speeds_string[i])
418 while (r_speeds_string[i] && r_speeds_string[i] != '\n')
421 DrawQ_String(0, y, r_speeds_string + j, i - j, 8, 8, 1, 1, 1, 1, 0);
422 if (r_speeds_string[i] == '\n')
436 void SCR_SizeUp_f (void)
438 Cvar_SetValue ("viewsize",scr_viewsize.value+10);
449 void SCR_SizeDown_f (void)
451 Cvar_SetValue ("viewsize",scr_viewsize.value-10);
454 void CL_Screen_Init(void)
458 Cvar_RegisterVariable (&scr_fov);
459 Cvar_RegisterVariable (&scr_viewsize);
460 Cvar_RegisterVariable (&scr_conspeed);
461 Cvar_RegisterVariable (&scr_showram);
462 Cvar_RegisterVariable (&scr_showturtle);
463 Cvar_RegisterVariable (&scr_showpause);
464 Cvar_RegisterVariable (&scr_centertime);
465 Cvar_RegisterVariable (&scr_printspeed);
466 Cvar_RegisterVariable (&scr_2dresolution);
467 Cvar_RegisterVariable (&scr_screenshot_jpeg);
468 Cvar_RegisterVariable (&cl_avidemo);
470 Cmd_AddCommand ("sizeup",SCR_SizeUp_f);
471 Cmd_AddCommand ("sizedown",SCR_SizeDown_f);
472 Cmd_AddCommand ("screenshot",SCR_ScreenShot_f);
473 Cmd_AddCommand ("envmap", R_Envmap_f);
475 scr_initialized = true;
478 // load the image data for the player image in the config menu
479 dat = (qpic_t *)FS_LoadFile ("gfx/menuplyr.lmp", false);
481 Sys_Error("unable to load gfx/menuplyr.lmp");
484 if (dat->width*dat->height <= 4096)
485 memcpy (menuplyr_pixels, dat->data, dat->width * dat->height);
487 Con_Printf("gfx/menuplyr.lmp larger than 4k buffer");
491 void DrawQ_Clear(void)
493 r_refdef.drawqueuesize = 0;
496 static int picelements[6] = {0, 1, 2, 0, 2, 3};
497 void DrawQ_Pic(float x, float y, char *picname, float width, float height, float red, float green, float blue, float alpha, int flags)
500 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);
504 drawqueuemesh_t mesh;
505 if (alpha < (1.0f / 255.0f) || !picname || !picname[0])
507 pic = Draw_CachePic(picname);
511 height = pic->height;
512 mesh.texture = pic->tex;
513 mesh.numtriangles = 2;
514 mesh.numvertices = 4;
515 mesh.indices = picelements;
516 mesh.vertex3f = floats;
517 mesh.texcoord2f = floats + 16;
518 mesh.color4f = floats + 32;
519 memset(floats, 0, sizeof(floats));
520 mesh.vertex3f[0] = mesh.vertex3f[12] = x;
521 mesh.vertex3f[1] = mesh.vertex3f[5] = y;
522 mesh.vertex3f[4] = mesh.vertex3f[8] = x + width;
523 mesh.vertex3f[9] = mesh.vertex3f[13] = y + height;
524 mesh.texcoord2f[4] = mesh.texcoord2f[8] = mesh.texcoord2f[9] = mesh.texcoord2f[13] = 1;
525 mesh.color4f[0] = mesh.color4f[4] = mesh.color4f[8] = mesh.color4f[12] = red;
526 mesh.color4f[1] = mesh.color4f[5] = mesh.color4f[9] = mesh.color4f[13] = green;
527 mesh.color4f[2] = mesh.color4f[6] = mesh.color4f[10] = mesh.color4f[14] = blue;
528 mesh.color4f[3] = mesh.color4f[7] = mesh.color4f[11] = mesh.color4f[15] = alpha;
529 DrawQ_Mesh (&mesh, flags);
533 if (alpha < (1.0f / 255.0f) || !picname || !picname[0])
535 size = sizeof(*dq) + ((strlen(picname) + 1 + 3) & ~3);
536 if (r_refdef.drawqueuesize + size > r_refdef.maxdrawqueuesize)
538 red = bound(0, red, 1);
539 green = bound(0, green, 1);
540 blue = bound(0, blue, 1);
541 alpha = bound(0, alpha, 1);
542 dq = (void *)(r_refdef.drawqueue + r_refdef.drawqueuesize);
544 dq->command = DRAWQUEUE_PIC;
546 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));
549 // if these are not zero, they override the pic's size
552 strcpy((char *)(dq + 1), picname);
553 r_refdef.drawqueuesize += dq->size;
557 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)
562 if (alpha < (1.0f / 255.0f))
565 len = strlen(string);
567 for (len = 0;len < maxlen && string[len];len++);
568 for (;len > 0 && string[0] == ' ';string++, x += scalex, len--);
569 for (;len > 0 && string[len - 1] == ' ';len--);
572 if (x >= vid.conwidth || y >= vid.conheight || x < (-scalex * maxlen) || y < (-scaley))
574 size = sizeof(*dq) + ((len + 1 + 3) & ~3);
575 if (r_refdef.drawqueuesize + size > r_refdef.maxdrawqueuesize)
577 red = bound(0, red, 1);
578 green = bound(0, green, 1);
579 blue = bound(0, blue, 1);
580 alpha = bound(0, alpha, 1);
581 dq = (void *)(r_refdef.drawqueue + r_refdef.drawqueuesize);
583 dq->command = DRAWQUEUE_STRING;
585 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));
590 out = (char *)(dq + 1);
591 memcpy(out, string, len);
593 r_refdef.drawqueuesize += dq->size;
596 void DrawQ_Fill (float x, float y, float w, float h, float red, float green, float blue, float alpha, int flags)
599 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);
602 drawqueuemesh_t mesh;
603 if (alpha < (1.0f / 255.0f))
606 mesh.numtriangles = 2;
607 mesh.numvertices = 4;
608 mesh.indices = picelements;
609 mesh.vertex3f = floats;
610 mesh.texcoord2f = floats + 16;
611 mesh.color4f = floats + 32;
612 memset(floats, 0, sizeof(floats));
613 mesh.vertex3f[0] = mesh.vertex3f[12] = x;
614 mesh.vertex3f[1] = mesh.vertex3f[5] = y;
615 mesh.vertex3f[4] = mesh.vertex3f[8] = x + w;
616 mesh.vertex3f[9] = mesh.vertex3f[13] = y + h;
617 mesh.color4f[0] = mesh.color4f[4] = mesh.color4f[8] = mesh.color4f[12] = red;
618 mesh.color4f[1] = mesh.color4f[5] = mesh.color4f[9] = mesh.color4f[13] = green;
619 mesh.color4f[2] = mesh.color4f[6] = mesh.color4f[10] = mesh.color4f[14] = blue;
620 mesh.color4f[3] = mesh.color4f[7] = mesh.color4f[11] = mesh.color4f[15] = alpha;
621 DrawQ_Mesh (&mesh, flags);
625 if (alpha < (1.0f / 255.0f))
627 size = sizeof(*dq) + 4;
628 if (r_refdef.drawqueuesize + size > r_refdef.maxdrawqueuesize)
630 red = bound(0, red, 1);
631 green = bound(0, green, 1);
632 blue = bound(0, blue, 1);
633 alpha = bound(0, alpha, 1);
634 dq = (void *)(r_refdef.drawqueue + r_refdef.drawqueuesize);
636 dq->command = DRAWQUEUE_PIC;
638 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));
644 *((char *)(dq + 1)) = 0;
645 r_refdef.drawqueuesize += dq->size;
649 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)
653 drawqueuemesh_t mesh;
654 memset(&mesh, 0, sizeof(mesh));
655 if (picname && picname[0])
657 pic = Draw_CachePic(picname);
661 height = pic->height;
662 mesh.texture = pic->tex;
664 mesh.numtriangles = 2;
665 mesh.numvertices = 4;
666 mesh.element3i = picelements;
667 mesh.vertex3f = floats;
668 mesh.texcoord2f = floats + 12;
669 mesh.color4f = floats + 20;
670 memset(floats, 0, sizeof(floats));
671 mesh.vertex3f[0] = mesh.vertex3f[9] = x;
672 mesh.vertex3f[1] = mesh.vertex3f[4] = y;
673 mesh.vertex3f[3] = mesh.vertex3f[6] = x + width;
674 mesh.vertex3f[7] = mesh.vertex3f[10] = y + height;
675 mesh.texcoord2f[0] = s1;mesh.texcoord2f[1] = t1;mesh.color4f[ 0] = r1;mesh.color4f[ 1] = g1;mesh.color4f[ 2] = b1;mesh.color4f[ 3] = a1;
676 mesh.texcoord2f[2] = s2;mesh.texcoord2f[3] = t2;mesh.color4f[ 4] = r2;mesh.color4f[ 5] = g2;mesh.color4f[ 6] = b2;mesh.color4f[ 7] = a2;
677 mesh.texcoord2f[4] = s4;mesh.texcoord2f[5] = t4;mesh.color4f[ 8] = r4;mesh.color4f[ 9] = g4;mesh.color4f[10] = b4;mesh.color4f[11] = a4;
678 mesh.texcoord2f[6] = s3;mesh.texcoord2f[7] = t3;mesh.color4f[12] = r3;mesh.color4f[13] = g3;mesh.color4f[14] = b3;mesh.color4f[15] = a3;
679 DrawQ_Mesh (&mesh, flags);
682 void DrawQ_Mesh (drawqueuemesh_t *mesh, int flags)
689 size += sizeof(drawqueuemesh_t);
690 size += sizeof(int[3]) * mesh->numtriangles;
691 size += sizeof(float[3]) * mesh->numvertices;
692 size += sizeof(float[2]) * mesh->numvertices;
693 size += sizeof(float[4]) * mesh->numvertices;
694 if (r_refdef.drawqueuesize + size > r_refdef.maxdrawqueuesize)
696 dq = (void *)(r_refdef.drawqueue + r_refdef.drawqueuesize);
698 dq->command = DRAWQUEUE_MESH;
705 p = (void *)(dq + 1);
706 m = p;(qbyte *)p += sizeof(drawqueuemesh_t);
707 m->numtriangles = mesh->numtriangles;
708 m->numvertices = mesh->numvertices;
709 m->texture = mesh->texture;
710 m->element3i = p;memcpy(m->element3i , mesh->element3i , m->numtriangles * sizeof(int[3]));(qbyte *)p += m->numtriangles * sizeof(int[3]);
711 m->vertex3f = p;memcpy(m->vertex3f , mesh->vertex3f , m->numvertices * sizeof(float[3]));(qbyte *)p += m->numvertices * sizeof(float[3]);
712 m->texcoord2f = p;memcpy(m->texcoord2f, mesh->texcoord2f, m->numvertices * sizeof(float[2]));(qbyte *)p += m->numvertices * sizeof(float[2]);
713 m->color4f = p;memcpy(m->color4f , mesh->color4f , m->numvertices * sizeof(float[4]));(qbyte *)p += m->numvertices * sizeof(float[4]);
714 r_refdef.drawqueuesize += dq->size;
722 float CalcFov (float fov_x, float width, float height)
724 // calculate vision size and alter by aspect, then convert back to angle
725 return atan (height / (width / tan(fov_x/360*M_PI))) * 360 / M_PI;
732 Must be called whenever vid changes
736 static void SCR_CalcRefdef (void)
741 //========================================
744 if (scr_viewsize.value < 30)
745 Cvar_Set ("viewsize","30");
746 if (scr_viewsize.value > 120)
747 Cvar_Set ("viewsize","120");
749 // bound field of view
750 if (scr_fov.value < 10)
751 Cvar_Set ("fov","10");
752 if (scr_fov.value > 170)
753 Cvar_Set ("fov","170");
755 // intermission is always full screen
763 if (scr_viewsize.value >= 120)
764 sb_lines = 0; // no status bar at all
765 else if (scr_viewsize.value >= 110)
766 sb_lines = 24; // no inventory
769 size = scr_viewsize.value * (1.0 / 100.0);
774 r_refdef.width = vid.realwidth;
775 r_refdef.height = vid.realheight;
781 r_refdef.width = vid.realwidth * size;
782 r_refdef.height = vid.realheight * size;
783 r_refdef.x = (vid.realwidth - r_refdef.width)/2;
784 r_refdef.y = (vid.realheight - r_refdef.height)/2;
787 r_refdef.width = bound(0, r_refdef.width, vid.realwidth);
788 r_refdef.height = bound(0, r_refdef.height, vid.realheight);
789 r_refdef.x = bound(0, r_refdef.x, vid.realwidth - r_refdef.width) + vid.realx;
790 r_refdef.y = bound(0, r_refdef.y, vid.realheight - r_refdef.height) + vid.realy;
792 // LordHavoc: viewzoom (zoom in for sniper rifles, etc)
793 r_refdef.fov_x = scr_fov.value * cl.viewzoom;
794 r_refdef.fov_y = CalcFov (r_refdef.fov_x, r_refdef.width, r_refdef.height);
798 Mod_CheckLoaded(cl.worldmodel);
799 contents = Mod_PointContents(r_refdef.vieworg, cl.worldmodel);
800 if (contents != CONTENTS_EMPTY && contents != CONTENTS_SOLID)
802 r_refdef.fov_x *= (sin(cl.time * 4.7) * 0.015 + 0.985);
803 r_refdef.fov_y *= (sin(cl.time * 3.0) * 0.015 + 0.985);
813 void SCR_ScreenShot_f (void)
817 char checkname[MAX_OSPATH];
819 qboolean jpeg = (scr_screenshot_jpeg.integer != 0);
826 // find a file name to save it to
827 for (; i<=9999 ; i++)
829 sprintf (filename, "dp%04i.%s", i, extens);
830 sprintf (checkname, "%s/%s", fs_gamedir, filename);
831 if (!FS_SysFileExists(checkname))
836 Con_Printf ("SCR_ScreenShot_f: Couldn't create the image file\n");
840 if (SCR_ScreenShot (filename, vid.realx, vid.realy, vid.realwidth, vid.realheight, jpeg))
841 Con_Printf ("Wrote %s\n", filename);
843 Con_Printf ("unable to write %s\n", filename);
846 static int cl_avidemo_frame = 0;
848 void SCR_CaptureAVIDemo(void)
851 sprintf(filename, "dpavi%06d.tga", cl_avidemo_frame);
852 if (SCR_ScreenShot(filename, vid.realx, vid.realy, vid.realwidth, vid.realheight, false))
856 Cvar_SetValueQuick(&cl_avidemo, 0);
857 Con_Printf("avi saving failed on frame %i, out of disk space? stopping avi demo catpure.\n", cl_avidemo_frame);
858 cl_avidemo_frame = 0;
866 Grab six views for environment mapping tests
878 {{ 0, 180, 0}, "bk"},
879 {{ 0, 270, 0}, "lf"},
880 {{-90, 90, 0}, "up"},
884 static void R_Envmap_f (void)
887 char filename[256], basename[256];
891 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");
895 strcpy(basename, Cmd_Argv(1));
896 size = atoi(Cmd_Argv(2));
897 if (size != 128 && size != 256 && size != 512 && size != 1024)
899 Con_Printf("envmap: size must be one of 128, 256, 512, or 1024\n");
902 if (size > vid.realwidth || size > vid.realheight)
904 Con_Printf("envmap: your resolution is not big enough to render that size\n");
912 r_refdef.width = size;
913 r_refdef.height = size;
918 for (j = 0;j < 6;j++)
920 sprintf(filename, "env/%s%s.tga", basename, envmapinfo[j].name);
921 VectorCopy(envmapinfo[j].angles, r_refdef.viewangles);
924 SCR_ScreenShot(filename, vid.realx, vid.realy, size, size, false);
930 //=============================================================================
932 // LordHavoc: SHOWLMP stuff
933 #define SHOWLMP_MAXLABELS 256
934 typedef struct showlmp_s
944 showlmp_t showlmp[SHOWLMP_MAXLABELS];
946 void SHOWLMP_decodehide(void)
950 lmplabel = MSG_ReadString();
951 for (i = 0;i < SHOWLMP_MAXLABELS;i++)
952 if (showlmp[i].isactive && strcmp(showlmp[i].label, lmplabel) == 0)
954 showlmp[i].isactive = false;
959 void SHOWLMP_decodeshow(void)
962 qbyte lmplabel[256], picname[256];
964 strcpy(lmplabel,MSG_ReadString());
965 strcpy(picname, MSG_ReadString());
966 if (gamemode == GAME_NEHAHRA) // LordHavoc: nasty old legacy junk
977 for (i = 0;i < SHOWLMP_MAXLABELS;i++)
978 if (showlmp[i].isactive)
980 if (strcmp(showlmp[i].label, lmplabel) == 0)
983 break; // drop out to replace it
986 else if (k < 0) // find first empty one to replace
989 return; // none found to replace
990 // change existing one
991 showlmp[k].isactive = true;
992 strcpy(showlmp[k].label, lmplabel);
993 strcpy(showlmp[k].pic, picname);
998 void SHOWLMP_drawall(void)
1001 for (i = 0;i < SHOWLMP_MAXLABELS;i++)
1002 if (showlmp[i].isactive)
1003 DrawQ_Pic(showlmp[i].x, showlmp[i].y, showlmp[i].pic, 0, 0, 1, 1, 1, 1, 0);
1006 void SHOWLMP_clear(void)
1009 for (i = 0;i < SHOWLMP_MAXLABELS;i++)
1010 showlmp[i].isactive = false;
1013 void CL_SetupScreenSize(void)
1015 static float old2dresolution = -1;
1017 VID_GetWindowSize (&vid.realx, &vid.realy, &vid.realwidth, &vid.realheight);
1019 VID_UpdateGamma(false);
1021 if (scr_2dresolution.value != old2dresolution)
1023 Cvar_SetValue("scr_2dresolution", bound(0.0f, scr_2dresolution.value, 1.0f));
1024 old2dresolution = scr_2dresolution.value;
1027 if (vid.realwidth > 320)
1029 vid.conwidth = (vid.realwidth - 320) * scr_2dresolution.value + 320;
1030 vid.conwidth = bound(320, vid.conwidth, vid.realwidth);
1035 if (vid.realheight > 240)
1037 vid.conheight = (vid.realheight - 240) * scr_2dresolution.value + 240;
1038 vid.conheight = bound(240, vid.conheight, vid.realheight);
1041 vid.conheight = 240;
1043 SCR_SetUpToDrawConsole();
1045 // determine size of refresh window
1049 extern void R_Shadow_EditLights_DrawSelectedLightProperties(void);
1050 void CL_UpdateScreen(void)
1052 if (!scr_initialized || !con_initialized || vid_hidden)
1053 return; // not initialized yet
1055 if (cl_avidemo.integer)
1056 SCR_CaptureAVIDemo();
1058 cl_avidemo_frame = 0;
1060 if (cls.signon == SIGNONS)
1061 R_TimeReport("other");
1063 CL_SetupScreenSize();
1070 if (cls.signon == SIGNONS)
1071 R_TimeReport("setup");
1073 //FIXME: force menu if nothing else to look at?
1074 //if (key_dest == key_game && cls.signon != SIGNONS && cls.state == ca_disconnected)
1076 if (scr_drawloading)
1078 scr_drawloading = false;
1083 if (cls.signon == SIGNONS)
1090 SCR_CheckDrawCenterString();
1095 if (cls.signon == SIGNONS)
1099 R_TimeReport_Start();
1101 R_Shadow_EditLights_DrawSelectedLightProperties();
1108 void CL_Screen_NewMap(void)