5 cvar_t scr_viewsize = {CVAR_SAVE, "viewsize","100"};
6 cvar_t scr_fov = {CVAR_SAVE, "fov","90"}; // 10 - 170
7 cvar_t scr_conspeed = {CVAR_SAVE, "scr_conspeed","900"}; // LordHavoc: quake used 300
8 cvar_t scr_centertime = {0, "scr_centertime","2"};
9 cvar_t scr_showram = {CVAR_SAVE, "showram","1"};
10 cvar_t scr_showturtle = {CVAR_SAVE, "showturtle","0"};
11 cvar_t scr_showpause = {CVAR_SAVE, "showpause","1"};
12 cvar_t scr_printspeed = {0, "scr_printspeed","8"};
13 cvar_t scr_2dresolution = {CVAR_SAVE, "scr_2dresolution", "1"};
14 cvar_t cl_avidemo = {0, "cl_avidemo", "0"};
16 qboolean scr_initialized; // ready to draw
18 float scr_con_current;
19 float scr_conlines; // lines of console to display
24 qboolean scr_drawloading = false;
26 static qbyte menuplyr_pixels[4096];
28 void DrawCrosshair(int num);
29 void V_CalcRefdef (void);
30 static void SCR_ScreenShot_f (void);
31 static void R_Envmap_f (void);
34 void R_ClearScreen(void);
37 ===============================================================================
41 ===============================================================================
44 char scr_centerstring[1024];
45 float scr_centertime_start; // for slow victory printing
46 float scr_centertime_off;
55 Called for important messages that should stay in the center of the screen
59 void SCR_CenterPrint (char *str)
61 strncpy (scr_centerstring, str, sizeof(scr_centerstring)-1);
62 scr_centertime_off = scr_centertime.value;
63 scr_centertime_start = cl.time;
65 // count the number of lines for centering
76 void SCR_DrawCenterString (void)
83 // the finale prints the characters one at a time
85 remaining = scr_printspeed.value * (cl.time - scr_centertime_start);
90 start = scr_centerstring;
92 if (scr_center_lines <= 4)
93 y = vid.conheight*0.35;
99 // scan the width of the line
100 for (l=0 ; l<40 ; l++)
101 if (start[l] == '\n' || !start[l])
103 x = (vid.conwidth - l*8)/2;
108 DrawQ_String(x, y, start, l, 8, 8, 1, 1, 1, 1, 0);
116 while (*start && *start != '\n')
121 start++; // skip the \n
125 void SCR_CheckDrawCenterString (void)
127 if (scr_center_lines > scr_erase_lines)
128 scr_erase_lines = scr_center_lines;
130 scr_centertime_off -= host_frametime;
132 // don't draw if this is a normal stats-screen intermission,
133 // only if it is not an intermission, or a finale intermission
134 if (cl.intermission == 1)
136 if (scr_centertime_off <= 0 && !cl.intermission)
138 if (key_dest != key_game)
141 SCR_DrawCenterString ();
149 void SCR_DrawTurtle (void)
153 if (cls.state != ca_connected)
156 if (!scr_showturtle.integer)
159 if (host_frametime < 0.1)
169 DrawQ_Pic (0, 0, "turtle", 0, 0, 1, 1, 1, 1, 0);
177 void SCR_DrawNet (void)
179 if (cls.state != ca_connected)
181 if (realtime - cl.last_received_message < 0.3)
183 if (cls.demoplayback)
186 DrawQ_Pic (64, 0, "net", 0, 0, 1, 1, 1, 1, 0);
194 void SCR_DrawPause (void)
198 if (cls.state != ca_connected)
201 if (!scr_showpause.integer) // turn off for screenshots
207 pic = Draw_CachePic ("gfx/pause.lmp");
208 DrawQ_Pic ((vid.conwidth - pic->width)/2, (vid.conheight - pic->height)/2, "gfx/pause.lmp", 0, 0, 1, 1, 1, 1, 0);
218 void SCR_DrawLoading (void)
222 pic = Draw_CachePic ("gfx/loading.lmp");
223 DrawQ_Pic ((vid.conwidth - pic->width)/2, (vid.conheight - pic->height)/2, "gfx/loading.lmp", 0, 0, 1, 1, 1, 1, 0);
228 //=============================================================================
233 SCR_SetUpToDrawConsole
236 void SCR_SetUpToDrawConsole (void)
240 if (key_dest == key_game && cls.signon != SIGNONS)
241 key_consoleactive |= KEY_CONSOLEACTIVE_FORCED;
243 key_consoleactive &= ~KEY_CONSOLEACTIVE_FORCED;
245 // decide on the height of the console
246 if (key_consoleactive & KEY_CONSOLEACTIVE_FORCED)
247 scr_conlines = vid.conheight; // full screen
248 else if (key_consoleactive & KEY_CONSOLEACTIVE_USER)
249 scr_conlines = vid.conheight/2; // half screen
251 scr_conlines = 0; // none visible
253 if (scr_conspeed.value)
255 if (scr_conlines < scr_con_current)
257 scr_con_current -= scr_conspeed.value*host_realframetime;
258 if (scr_conlines > scr_con_current)
259 scr_con_current = scr_conlines;
262 else if (scr_conlines > scr_con_current)
264 scr_con_current += scr_conspeed.value*host_realframetime;
265 if (scr_conlines < scr_con_current)
266 scr_con_current = scr_conlines;
270 scr_con_current = scr_conlines;
278 void SCR_DrawConsole (void)
282 Con_DrawConsole (scr_con_current);
287 if (key_dest == key_game || key_dest == key_message)
288 Con_DrawNotify (); // only draw notify in game
294 SCR_BeginLoadingPlaque
298 void SCR_BeginLoadingPlaque (void)
303 S_StopAllSounds (true);
305 scr_drawloading = true;
307 scr_drawloading = true;
311 //=============================================================================
313 char r_speeds_string[1024];
314 int speedstringcount, r_timereport_active;
315 double r_timereport_temp = 0, r_timereport_current = 0, r_timereport_start = 0;
317 void R_TimeReport(char *desc)
323 if (!r_timereport_active)
326 r_timereport_temp = r_timereport_current;
327 r_timereport_current = Sys_DoubleTime();
328 t = (int) ((r_timereport_current - r_timereport_temp) * 1000000.0);
330 sprintf(tempbuf, "%8i %s", t, desc);
331 length = strlen(tempbuf);
333 tempbuf[length++] = ' ';
335 if (speedstringcount + length > (vid.conwidth / 8))
337 strcat(r_speeds_string, "\n");
338 speedstringcount = 0;
340 // skip the space at the beginning if it's the first on the line
341 if (speedstringcount == 0)
343 strcat(r_speeds_string, tempbuf + 1);
344 speedstringcount = length - 1;
348 strcat(r_speeds_string, tempbuf);
349 speedstringcount += length;
353 extern int c_rt_lights, c_rt_clears, c_rt_scissored;
354 extern int c_rt_shadowmeshes, c_rt_shadowtris, c_rt_lightmeshes, c_rt_lighttris;
355 extern int c_rtcached_shadowmeshes, c_rtcached_shadowtris;
356 extern int r_shadow_lightingmode;
357 void R_TimeReport_Start(void)
359 r_timereport_active = r_speeds.integer && cls.signon == SIGNONS && cls.state == ca_connected;
360 r_speeds_string[0] = 0;
361 if (r_timereport_active)
363 speedstringcount = 0;
364 AngleVectors (r_refdef.viewangles, vpn, NULL, NULL);
365 sprintf(r_speeds_string,
366 "org:'%+8.2f %+8.2f %+8.2f' ang:'%+4.0f %+4.0f %+4.0f' dir:'%+2.3f %+2.3f %+2.3f'\n"
367 "world:%6i faces%6i nodes%6i leafs%6i dlitwalls\n"
368 "%5i models%5i bmodels%5i sprites%6i particles%4i dlights\n"
369 "%6i modeltris%6i meshs%6i meshtris\n",
370 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],
371 c_faces, c_nodes, c_leafs, c_light_polys,
372 c_models, c_bmodels, c_sprites, c_particles, c_dlights,
373 c_alias_polys, c_meshs, c_meshelements / 3);
374 if (r_shadow_lightingmode)
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);
397 r_timereport_start = Sys_DoubleTime();
401 void R_TimeReport_End(void)
403 r_timereport_current = r_timereport_start;
404 R_TimeReport("total");
406 if (r_timereport_active)
410 for (i = 0;r_speeds_string[i];i++)
411 if (r_speeds_string[i] == '\n')
413 y = vid.conheight - sb_lines - lines * 8;
415 DrawQ_Fill(0, y, vid.conwidth, lines * 8, 0, 0, 0, 0.5, 0);
416 while (r_speeds_string[i])
419 while (r_speeds_string[i] && r_speeds_string[i] != '\n')
422 DrawQ_String(0, y, r_speeds_string + j, i - j, 8, 8, 1, 1, 1, 1, 0);
423 if (r_speeds_string[i] == '\n')
437 void SCR_SizeUp_f (void)
439 Cvar_SetValue ("viewsize",scr_viewsize.value+10);
450 void SCR_SizeDown_f (void)
452 Cvar_SetValue ("viewsize",scr_viewsize.value-10);
455 void CL_Screen_Init(void)
459 Cvar_RegisterVariable (&scr_fov);
460 Cvar_RegisterVariable (&scr_viewsize);
461 Cvar_RegisterVariable (&scr_conspeed);
462 Cvar_RegisterVariable (&scr_showram);
463 Cvar_RegisterVariable (&scr_showturtle);
464 Cvar_RegisterVariable (&scr_showpause);
465 Cvar_RegisterVariable (&scr_centertime);
466 Cvar_RegisterVariable (&scr_printspeed);
467 Cvar_RegisterVariable (&scr_2dresolution);
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 // find a file name to save it to
821 for (; i<=9999 ; i++)
823 sprintf (filename, "dp%04i.tga", i);
824 sprintf (checkname, "%s/%s", fs_gamedir, filename);
825 if (!FS_SysFileExists(checkname))
830 Con_Printf ("SCR_ScreenShot_f: Couldn't create a TGA file\n");
834 if (SCR_ScreenShot(filename, vid.realx, vid.realy, vid.realwidth, vid.realheight))
835 Con_Printf ("Wrote %s\n", filename);
837 Con_Printf ("unable to write %s\n", filename);
840 static int cl_avidemo_frame = 0;
842 void SCR_CaptureAVIDemo(void)
845 sprintf(filename, "dpavi%06d.tga", cl_avidemo_frame);
846 if (SCR_ScreenShot(filename, vid.realx, vid.realy, vid.realwidth, vid.realheight))
850 Cvar_SetValueQuick(&cl_avidemo, 0);
851 Con_Printf("avi saving failed on frame %i, out of disk space? stopping avi demo catpure.\n", cl_avidemo_frame);
852 cl_avidemo_frame = 0;
860 Grab six views for environment mapping tests
872 {{ 0, 180, 0}, "bk"},
873 {{ 0, 270, 0}, "lf"},
874 {{-90, 90, 0}, "up"},
878 static void R_Envmap_f (void)
881 char filename[256], basename[256];
885 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");
889 strcpy(basename, Cmd_Argv(1));
890 size = atoi(Cmd_Argv(2));
891 if (size != 128 && size != 256 && size != 512 && size != 1024)
893 Con_Printf("envmap: size must be one of 128, 256, 512, or 1024\n");
896 if (size > vid.realwidth || size > vid.realheight)
898 Con_Printf("envmap: your resolution is not big enough to render that size\n");
906 r_refdef.width = size;
907 r_refdef.height = size;
912 for (j = 0;j < 6;j++)
914 sprintf(filename, "env/%s%s.tga", basename, envmapinfo[j].name);
915 VectorCopy(envmapinfo[j].angles, r_refdef.viewangles);
918 SCR_ScreenShot(filename, vid.realx, vid.realy, size, size);
924 //=============================================================================
926 // LordHavoc: SHOWLMP stuff
927 #define SHOWLMP_MAXLABELS 256
928 typedef struct showlmp_s
938 showlmp_t showlmp[SHOWLMP_MAXLABELS];
940 void SHOWLMP_decodehide(void)
944 lmplabel = MSG_ReadString();
945 for (i = 0;i < SHOWLMP_MAXLABELS;i++)
946 if (showlmp[i].isactive && strcmp(showlmp[i].label, lmplabel) == 0)
948 showlmp[i].isactive = false;
953 void SHOWLMP_decodeshow(void)
956 qbyte lmplabel[256], picname[256];
958 strcpy(lmplabel,MSG_ReadString());
959 strcpy(picname, MSG_ReadString());
960 if (gamemode == GAME_NEHAHRA) // LordHavoc: nasty old legacy junk
971 for (i = 0;i < SHOWLMP_MAXLABELS;i++)
972 if (showlmp[i].isactive)
974 if (strcmp(showlmp[i].label, lmplabel) == 0)
977 break; // drop out to replace it
980 else if (k < 0) // find first empty one to replace
983 return; // none found to replace
984 // change existing one
985 showlmp[k].isactive = true;
986 strcpy(showlmp[k].label, lmplabel);
987 strcpy(showlmp[k].pic, picname);
992 void SHOWLMP_drawall(void)
995 for (i = 0;i < SHOWLMP_MAXLABELS;i++)
996 if (showlmp[i].isactive)
997 DrawQ_Pic(showlmp[i].x, showlmp[i].y, showlmp[i].pic, 0, 0, 1, 1, 1, 1, 0);
1000 void SHOWLMP_clear(void)
1003 for (i = 0;i < SHOWLMP_MAXLABELS;i++)
1004 showlmp[i].isactive = false;
1007 void CL_SetupScreenSize(void)
1009 static float old2dresolution = -1;
1011 VID_GetWindowSize (&vid.realx, &vid.realy, &vid.realwidth, &vid.realheight);
1013 VID_UpdateGamma(false);
1015 if (scr_2dresolution.value != old2dresolution)
1017 Cvar_SetValue("scr_2dresolution", bound(0.0f, scr_2dresolution.value, 1.0f));
1018 old2dresolution = scr_2dresolution.value;
1021 if (vid.realwidth > 320)
1023 vid.conwidth = (vid.realwidth - 320) * scr_2dresolution.value + 320;
1024 vid.conwidth = bound(320, vid.conwidth, vid.realwidth);
1029 if (vid.realheight > 240)
1031 vid.conheight = (vid.realheight - 240) * scr_2dresolution.value + 240;
1032 vid.conheight = bound(240, vid.conheight, vid.realheight);
1035 vid.conheight = 240;
1037 SCR_SetUpToDrawConsole();
1039 // determine size of refresh window
1043 extern void R_Shadow_EditLights_DrawSelectedLightProperties(void);
1044 void CL_UpdateScreen(void)
1046 if (!scr_initialized || !con_initialized || vid_hidden)
1047 return; // not initialized yet
1049 if (cl_avidemo.integer)
1050 SCR_CaptureAVIDemo();
1052 cl_avidemo_frame = 0;
1054 if (cls.signon == SIGNONS)
1055 R_TimeReport("other");
1057 CL_SetupScreenSize();
1064 if (cls.signon == SIGNONS)
1065 R_TimeReport("setup");
1067 //FIXME: force menu if nothing else to look at?
1068 //if (key_dest == key_game && cls.signon != SIGNONS && cls.state == ca_disconnected)
1070 if (scr_drawloading)
1072 scr_drawloading = false;
1077 if (cls.signon == SIGNONS)
1084 SCR_CheckDrawCenterString();
1089 if (cls.signon == SIGNONS)
1093 R_TimeReport_Start();
1095 R_Shadow_EditLights_DrawSelectedLightProperties();
1102 void CL_Screen_NewMap(void)