#include "quakedef.h"
#include "cl_video.h"
#include "jpeg.h"
+#include "cl_collision.h"
cvar_t scr_viewsize = {CVAR_SAVE, "viewsize","100"};
-cvar_t scr_fov = {CVAR_SAVE, "fov","90"}; // 10 - 170
+cvar_t scr_fov = {CVAR_SAVE, "fov","90"}; // 1 - 170
cvar_t scr_conspeed = {CVAR_SAVE, "scr_conspeed","900"}; // LordHavoc: quake used 300
cvar_t scr_conalpha = {CVAR_SAVE, "scr_conalpha", "1"};
-cvar_t scr_conbrightness = {CVAR_SAVE, "scr_conbrightness", "0"};
+cvar_t scr_conbrightness = {CVAR_SAVE, "scr_conbrightness", "0.2"};
+cvar_t scr_conforcewhiledisconnected = {CVAR_SAVE, "scr_conforcewhiledisconnected", "1"};
cvar_t scr_centertime = {0, "scr_centertime","2"};
cvar_t scr_showram = {CVAR_SAVE, "showram","1"};
cvar_t scr_showturtle = {CVAR_SAVE, "showturtle","0"};
cvar_t scr_showpause = {CVAR_SAVE, "showpause","1"};
cvar_t scr_printspeed = {0, "scr_printspeed","8"};
-cvar_t scr_2dresolution = {CVAR_SAVE, "scr_2dresolution", "1"};
+cvar_t vid_conwidth = {CVAR_SAVE, "vid_conwidth", "640"};
+cvar_t vid_conheight = {CVAR_SAVE, "vid_conheight", "480"};
+cvar_t vid_pixelaspect = {CVAR_SAVE, "vid_pixelaspect", "1"};
cvar_t scr_screenshot_jpeg = {CVAR_SAVE, "scr_screenshot_jpeg","0"};
-cvar_t cl_avidemo = {0, "cl_avidemo", "0"};
+cvar_t scr_screenshot_jpeg_quality = {CVAR_SAVE, "scr_screenshot_jpeg_quality","0.9"};
+cvar_t scr_screenshot_gamma = {CVAR_SAVE, "scr_screenshot_gamma","2.2"};
+cvar_t scr_screenshot_name = {0, "scr_screenshot_name","dp"};
+cvar_t cl_capturevideo = {0, "cl_capturevideo", "0"};
+cvar_t cl_capturevideo_fps = {0, "cl_capturevideo_fps", "30"};
+cvar_t cl_capturevideo_rawrgb = {0, "cl_capturevideo_rawrgb", "0"};
+cvar_t cl_capturevideo_rawyv12 = {0, "cl_capturevideo_rawyv12", "0"};
+cvar_t r_textshadow = {0, "r_textshadow", "0"};
+cvar_t r_letterbox = {0, "r_letterbox", "0"};
+
+int jpeg_supported = false;
qboolean scr_initialized; // ready to draw
float scr_con_current;
-float scr_conlines; // lines of console to display
-int clearconsole;
-int clearnotify;
-
-qboolean scr_drawloading = false;
-
-static qbyte menuplyr_pixels[4096];
+extern int con_vislines;
void DrawCrosshair(int num);
-void V_CalcRefdef (void);
static void SCR_ScreenShot_f (void);
static void R_Envmap_f (void);
for a few moments
==============
*/
-void SCR_CenterPrint (char *str)
+void SCR_CenterPrint(char *str)
{
- strncpy (scr_centerstring, str, sizeof(scr_centerstring)-1);
+ strlcpy (scr_centerstring, str, sizeof (scr_centerstring));
scr_centertime_off = scr_centertime.value;
scr_centertime_start = cl.time;
do
{
// scan the width of the line
- for (l=0 ; l<40 ; l++)
+ for (l=0 ; l<vid.conwidth/8 ; l++)
if (start[l] == '\n' || !start[l])
break;
x = (vid.conwidth - l*8)/2;
-/*
-==============
-SCR_DrawLoading
-==============
-*/
-void SCR_DrawLoading (void)
-{
- cachepic_t *pic;
-
- pic = Draw_CachePic ("gfx/loading.lmp");
- DrawQ_Pic ((vid.conwidth - pic->width)/2, (vid.conheight - pic->height)/2, "gfx/loading.lmp", 0, 0, 1, 1, 1, 1, 0);
-}
-
//=============================================================================
*/
void SCR_SetUpToDrawConsole (void)
{
+ // lines of console to display
+ float conlines;
+
Con_CheckResize ();
- if (key_dest == key_game && cls.signon != SIGNONS)
+ if (key_dest == key_game && cls.signon != SIGNONS && scr_conforcewhiledisconnected.integer)
key_consoleactive |= KEY_CONSOLEACTIVE_FORCED;
else
key_consoleactive &= ~KEY_CONSOLEACTIVE_FORCED;
// decide on the height of the console
- if (key_consoleactive & KEY_CONSOLEACTIVE_FORCED)
- scr_conlines = vid.conheight; // full screen
- else if (key_consoleactive & KEY_CONSOLEACTIVE_USER)
- scr_conlines = vid.conheight/2; // half screen
+ if (key_consoleactive & KEY_CONSOLEACTIVE_USER)
+ conlines = vid.conheight/2; // half screen
else
- scr_conlines = 0; // none visible
+ conlines = 0; // none visible
if (scr_conspeed.value)
{
- if (scr_conlines < scr_con_current)
+ if (scr_con_current > conlines)
{
scr_con_current -= scr_conspeed.value*host_realframetime;
- if (scr_conlines > scr_con_current)
- scr_con_current = scr_conlines;
+ if (scr_con_current < conlines)
+ scr_con_current = conlines;
}
- else if (scr_conlines > scr_con_current)
+ else if (scr_con_current < conlines)
{
scr_con_current += scr_conspeed.value*host_realframetime;
- if (scr_conlines < scr_con_current)
- scr_con_current = scr_conlines;
+ if (scr_con_current > conlines)
+ scr_con_current = conlines;
}
}
else
- scr_con_current = scr_conlines;
+ scr_con_current = conlines;
}
/*
*/
void SCR_DrawConsole (void)
{
- if (scr_con_current)
+ if (key_consoleactive & KEY_CONSOLEACTIVE_FORCED)
{
- Con_DrawConsole (scr_con_current);
- clearconsole = 0;
+ // full screen
+ Con_DrawConsole (vid.conheight);
}
+ else if (scr_con_current)
+ Con_DrawConsole (scr_con_current);
else
{
+ con_vislines = 0;
if (key_dest == key_game || key_dest == key_message)
Con_DrawNotify (); // only draw notify in game
}
*/
void SCR_BeginLoadingPlaque (void)
{
- if (scr_drawloading)
- return;
-
- S_StopAllSounds (true);
-
- scr_drawloading = true;
- CL_UpdateScreen ();
- scr_drawloading = true;
- CL_UpdateScreen ();
+ S_StopAllSounds ();
+ SCR_UpdateLoadingScreen();
}
//=============================================================================
}
}
-extern int c_rt_lights, c_rt_clears, c_rt_scissored;
-extern int c_rt_shadowmeshes, c_rt_shadowtris, c_rt_lightmeshes, c_rt_lighttris;
-extern int c_rtcached_shadowmeshes, c_rtcached_shadowtris;
void R_TimeReport_Start(void)
{
r_timereport_active = r_speeds.integer && cls.signon == SIGNONS && cls.state == ca_connected;
if (r_timereport_active)
{
speedstringcount = 0;
- AngleVectors (r_refdef.viewangles, vpn, NULL, NULL);
- sprintf(r_speeds_string,
- "org:'%+8.2f %+8.2f %+8.2f' ang:'%+4.0f %+4.0f %+4.0f' dir:'%+2.3f %+2.3f %+2.3f'\n"
- "world:%6i faces%6i nodes%6i leafs%6i dlitwalls\n"
- "%5i models%5i bmodels%5i sprites%6i particles%4i dlights\n"
- "%6i modeltris%6i meshs%6i meshtris\n",
- 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],
- c_faces, c_nodes, c_leafs, c_light_polys,
- c_models, c_bmodels, c_sprites, c_particles, c_dlights,
- c_alias_polys, c_meshs, c_meshelements / 3);
-
- sprintf(r_speeds_string + strlen(r_speeds_string),
- "realtime lighting:%4i lights%4i clears%4i scissored\n"
- "dynamic: %6i shadowmeshes%6i shadowtris%6i lightmeshes%6i lighttris\n"
- "precomputed: %6i shadowmeshes%6i shadowtris\n",
- c_rt_lights, c_rt_clears, c_rt_scissored,
- c_rt_shadowmeshes, c_rt_shadowtris, c_rt_lightmeshes, c_rt_lighttris,
- c_rtcached_shadowmeshes, c_rtcached_shadowtris);
+ 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]);
+ 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);
+ 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);
+ sprintf(r_speeds_string + strlen(r_speeds_string), "%6i modeltris%6i meshs%6i meshtris\n", c_alias_polys, c_meshs, c_meshelements / 3);
+ 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);
+ 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);
+ 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);
+ sprintf(r_speeds_string + strlen(r_speeds_string), "precomputed: %6i shadowmeshes%6i shadowtris\n", c_rtcached_shadowmeshes, c_rtcached_shadowtris);
c_alias_polys = 0;
c_light_polys = 0;
c_bmodels = 0;
c_sprites = 0;
c_particles = 0;
+ c_dlights = 0;
c_meshs = 0;
c_meshelements = 0;
+ c_rt_lights = 0;
+ c_rt_clears = 0;
+ c_rt_scissored = 0;
+ c_rt_shadowmeshes = 0;
+ c_rt_shadowtris = 0;
+ c_rt_lightmeshes = 0;
+ c_rt_lighttris = 0;
+ c_rtcached_shadowmeshes = 0;
+ c_rtcached_shadowtris = 0;
+ c_bloom = 0;
+ c_bloomcopies = 0;
+ c_bloomcopypixels = 0;
+ c_bloomdraws = 0;
+ c_bloomdrawpixels = 0;
r_timereport_start = Sys_DoubleTime();
}
void CL_Screen_Init(void)
{
- qpic_t *dat;
-
Cvar_RegisterVariable (&scr_fov);
Cvar_RegisterVariable (&scr_viewsize);
Cvar_RegisterVariable (&scr_conspeed);
Cvar_RegisterVariable (&scr_conalpha);
Cvar_RegisterVariable (&scr_conbrightness);
+ Cvar_RegisterVariable (&scr_conforcewhiledisconnected);
Cvar_RegisterVariable (&scr_showram);
Cvar_RegisterVariable (&scr_showturtle);
Cvar_RegisterVariable (&scr_showpause);
Cvar_RegisterVariable (&scr_centertime);
Cvar_RegisterVariable (&scr_printspeed);
- Cvar_RegisterVariable (&scr_2dresolution);
+ Cvar_RegisterVariable (&vid_conwidth);
+ Cvar_RegisterVariable (&vid_conheight);
+ Cvar_RegisterVariable (&vid_pixelaspect);
Cvar_RegisterVariable (&scr_screenshot_jpeg);
- Cvar_RegisterVariable (&cl_avidemo);
+ Cvar_RegisterVariable (&scr_screenshot_jpeg_quality);
+ Cvar_RegisterVariable (&scr_screenshot_gamma);
+ Cvar_RegisterVariable (&cl_capturevideo);
+ Cvar_RegisterVariable (&cl_capturevideo_fps);
+ Cvar_RegisterVariable (&cl_capturevideo_rawrgb);
+ Cvar_RegisterVariable (&cl_capturevideo_rawyv12);
+ Cvar_RegisterVariable (&r_textshadow);
+ Cvar_RegisterVariable (&r_letterbox);
Cmd_AddCommand ("sizeup",SCR_SizeUp_f);
Cmd_AddCommand ("sizedown",SCR_SizeDown_f);
Cmd_AddCommand ("envmap", R_Envmap_f);
scr_initialized = true;
-
- // HACK HACK HACK
- // load the image data for the player image in the config menu
- dat = (qpic_t *)FS_LoadFile ("gfx/menuplyr.lmp", false);
- if (!dat)
- Sys_Error("unable to load gfx/menuplyr.lmp");
- SwapPic (dat);
-
- if (dat->width*dat->height <= 4096)
- memcpy (menuplyr_pixels, dat->data, dat->width * dat->height);
- else
- Con_Printf("gfx/menuplyr.lmp larger than 4k buffer");
- Mem_Free(dat);
}
void DrawQ_Clear(void)
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);
}
-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)
+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)
{
int size, len;
drawqueue_t *dq;
for (;len > 0 && string[len - 1] == ' ';len--);
if (len < 1)
return;
- if (x >= vid.conwidth || y >= vid.conheight || x < (-scalex * maxlen) || y < (-scaley))
+ if (x >= vid.conwidth || y >= vid.conheight || x < (-scalex * len) || y < (-scaley))
return;
size = sizeof(*dq) + ((len + 1 + 3) & ~3);
if (r_refdef.drawqueuesize + size > r_refdef.maxdrawqueuesize)
r_refdef.drawqueuesize += dq->size;
}
+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)
+{
+ if (r_textshadow.integer)
+ DrawQ_String_Real(x+scalex*0.25,y+scaley*0.25,string,maxlen,scalex,scaley,0,0,0,alpha*0.8,flags);
+
+ DrawQ_String_Real(x,y,string,maxlen,scalex,scaley,red,green,blue,alpha,flags);
+}
+
void DrawQ_Fill (float x, float y, float w, float h, float red, float green, float blue, float alpha, int flags)
{
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);
height = pic->height;
mesh.texture = pic->tex;
}
- mesh.numtriangles = 2;
- mesh.numvertices = 4;
- mesh.element3i = picelements;
- mesh.vertex3f = floats;
- mesh.texcoord2f = floats + 12;
- mesh.color4f = floats + 20;
+ mesh.num_triangles = 2;
+ mesh.num_vertices = 4;
+ mesh.data_element3i = picelements;
+ mesh.data_vertex3f = floats;
+ mesh.data_texcoord2f = floats + 12;
+ mesh.data_color4f = floats + 20;
memset(floats, 0, sizeof(floats));
- mesh.vertex3f[0] = mesh.vertex3f[9] = x;
- mesh.vertex3f[1] = mesh.vertex3f[4] = y;
- mesh.vertex3f[3] = mesh.vertex3f[6] = x + width;
- mesh.vertex3f[7] = mesh.vertex3f[10] = y + height;
- mesh.texcoord2f[0] = s1;mesh.texcoord2f[1] = t1;mesh.color4f[ 0] = r1;mesh.color4f[ 1] = g1;mesh.color4f[ 2] = b1;mesh.color4f[ 3] = a1;
- mesh.texcoord2f[2] = s2;mesh.texcoord2f[3] = t2;mesh.color4f[ 4] = r2;mesh.color4f[ 5] = g2;mesh.color4f[ 6] = b2;mesh.color4f[ 7] = a2;
- mesh.texcoord2f[4] = s4;mesh.texcoord2f[5] = t4;mesh.color4f[ 8] = r4;mesh.color4f[ 9] = g4;mesh.color4f[10] = b4;mesh.color4f[11] = a4;
- mesh.texcoord2f[6] = s3;mesh.texcoord2f[7] = t3;mesh.color4f[12] = r3;mesh.color4f[13] = g3;mesh.color4f[14] = b3;mesh.color4f[15] = a3;
+ mesh.data_vertex3f[0] = mesh.data_vertex3f[9] = x;
+ mesh.data_vertex3f[1] = mesh.data_vertex3f[4] = y;
+ mesh.data_vertex3f[3] = mesh.data_vertex3f[6] = x + width;
+ mesh.data_vertex3f[7] = mesh.data_vertex3f[10] = y + height;
+ 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;
+ 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;
+ 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;
+ 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;
DrawQ_Mesh (&mesh, flags);
}
drawqueuemesh_t *m;
size = sizeof(*dq);
size += sizeof(drawqueuemesh_t);
- size += sizeof(int[3]) * mesh->numtriangles;
- size += sizeof(float[3]) * mesh->numvertices;
- size += sizeof(float[2]) * mesh->numvertices;
- size += sizeof(float[4]) * mesh->numvertices;
+ size += sizeof(int[3]) * mesh->num_triangles;
+ size += sizeof(float[3]) * mesh->num_vertices;
+ size += sizeof(float[2]) * mesh->num_vertices;
+ size += sizeof(float[4]) * mesh->num_vertices;
if (r_refdef.drawqueuesize + size > r_refdef.maxdrawqueuesize)
return;
dq = (void *)(r_refdef.drawqueue + r_refdef.drawqueuesize);
dq->scalex = 0;
dq->scaley = 0;
p = (void *)(dq + 1);
- m = p;(qbyte *)p += sizeof(drawqueuemesh_t);
- m->numtriangles = mesh->numtriangles;
- m->numvertices = mesh->numvertices;
+ m = p;p = (qbyte*)p + sizeof(drawqueuemesh_t);
+ m->num_triangles = mesh->num_triangles;
+ m->num_vertices = mesh->num_vertices;
m->texture = mesh->texture;
- m->element3i = p;memcpy(m->element3i , mesh->element3i , m->numtriangles * sizeof(int[3]));(qbyte *)p += m->numtriangles * sizeof(int[3]);
- m->vertex3f = p;memcpy(m->vertex3f , mesh->vertex3f , m->numvertices * sizeof(float[3]));(qbyte *)p += m->numvertices * sizeof(float[3]);
- m->texcoord2f = p;memcpy(m->texcoord2f, mesh->texcoord2f, m->numvertices * sizeof(float[2]));(qbyte *)p += m->numvertices * sizeof(float[2]);
- m->color4f = p;memcpy(m->color4f , mesh->color4f , m->numvertices * sizeof(float[4]));(qbyte *)p += m->numvertices * sizeof(float[4]);
+ m->data_element3i = p;memcpy(m->data_element3i , mesh->data_element3i , m->num_triangles * sizeof(int[3]));p = (qbyte*)p + m->num_triangles * sizeof(int[3]);
+ m->data_vertex3f = p;memcpy(m->data_vertex3f , mesh->data_vertex3f , m->num_vertices * sizeof(float[3]));p = (qbyte*)p + m->num_vertices * sizeof(float[3]);
+ m->data_texcoord2f = p;memcpy(m->data_texcoord2f, mesh->data_texcoord2f, m->num_vertices * sizeof(float[2]));p = (qbyte*)p + m->num_vertices * sizeof(float[2]);
+ m->data_color4f = p;memcpy(m->data_color4f , mesh->data_color4f , m->num_vertices * sizeof(float[4]));p = (qbyte*)p + m->num_vertices * sizeof(float[4]);
r_refdef.drawqueuesize += dq->size;
}
-/*
-====================
-CalcFov
-====================
-*/
-float CalcFov (float fov_x, float width, float height)
+void DrawQ_SetClipArea(float x, float y, float width, float height)
{
- // calculate vision size and alter by aspect, then convert back to angle
- return atan (height / (width / tan(fov_x/360*M_PI))) * 360 / M_PI;
+ drawqueue_t * dq;
+ if(r_refdef.drawqueuesize + (int)sizeof(*dq) > r_refdef.maxdrawqueuesize)
+ {
+ Con_DPrint("DrawQueue full !\n");
+ return;
+ }
+ dq = (void*) (r_refdef.drawqueue + r_refdef.drawqueuesize);
+ dq->size = sizeof(*dq);
+ dq->command = DRAWQUEUE_SETCLIP;
+ dq->x = x;
+ dq->y = y;
+ dq->scalex = width;
+ dq->scaley = height;
+ dq->flags = 0;
+ dq->color = 0;
+
+ r_refdef.drawqueuesize += dq->size;
}
-/*
-=================
-SCR_CalcRefdef
+void DrawQ_ResetClipArea(void)
+{
+ drawqueue_t *dq;
+ if(r_refdef.drawqueuesize + (int)sizeof(*dq) > r_refdef.maxdrawqueuesize)
+ {
+ Con_DPrint("DrawQueue full !\n");
+ return;
+ }
+ dq = (void*) (r_refdef.drawqueue + r_refdef.drawqueuesize);
+ dq->size = sizeof(*dq);
+ dq->command = DRAWQUEUE_RESETCLIP;
+ dq->x = 0;
+ dq->y = 0;
+ dq->scalex = 0;
+ dq->scaley = 0;
+ dq->flags = 0;
+ dq->color = 0;
-Must be called whenever vid changes
-Internal use only
-=================
+ r_refdef.drawqueuesize += dq->size;
+}
+
+/*
+==================
+SCR_ScreenShot_f
+==================
*/
-static void SCR_CalcRefdef (void)
+void SCR_ScreenShot_f (void)
{
- float size;
- int contents;
+ static int shotnumber;
+ static char oldname[MAX_QPATH];
+ char base[MAX_QPATH];
+ char filename[MAX_QPATH];
+ qbyte *buffer1;
+ qbyte *buffer2;
+ qbyte *buffer3;
+ qboolean jpeg = (scr_screenshot_jpeg.integer != 0);
-//========================================
+ sprintf (base, "screenshots/%s", scr_screenshot_name.string);
-// bound viewsize
- if (scr_viewsize.value < 30)
- Cvar_Set ("viewsize","30");
- if (scr_viewsize.value > 120)
- Cvar_Set ("viewsize","120");
+ if (strcmp (oldname, scr_screenshot_name.string))
+ {
+ sprintf(oldname, "%s", scr_screenshot_name.string);
+ shotnumber = 0;
+ }
-// bound field of view
- if (scr_fov.value < 10)
- Cvar_Set ("fov","10");
- if (scr_fov.value > 170)
- Cvar_Set ("fov","170");
+ // find a file name to save it to
+ for (;shotnumber < 1000000;shotnumber++)
+ if (!FS_SysFileExists(va("%s/%s%06d.tga", fs_gamedir, base, shotnumber)) && !FS_SysFileExists(va("%s/%s%06d.jpg", fs_gamedir, base, shotnumber)))
+ break;
+ if (shotnumber >= 1000000)
+ {
+ Con_Print("SCR_ScreenShot_f: Couldn't create the image file\n");
+ return;
+ }
-// intermission is always full screen
- if (cl.intermission)
+ sprintf(filename, "%s%06d.%s", base, shotnumber, jpeg ? "jpg" : "tga");
+
+ buffer1 = Mem_Alloc(tempmempool, vid.realwidth * vid.realheight * 3);
+ buffer2 = Mem_Alloc(tempmempool, vid.realwidth * vid.realheight * 3);
+ buffer3 = Mem_Alloc(tempmempool, vid.realwidth * vid.realheight * 3 + 18);
+
+ if (SCR_ScreenShot (filename, buffer1, buffer2, buffer3, vid.realx, vid.realy, vid.realwidth, vid.realheight, false, false, false, jpeg))
+ Con_Printf("Wrote %s\n", filename);
+ else
+ Con_Printf("unable to write %s\n", filename);
+
+ Mem_Free (buffer1);
+ Mem_Free (buffer2);
+ Mem_Free (buffer3);
+
+ shotnumber++;
+}
+
+typedef enum capturevideoformat_e
+{
+ CAPTUREVIDEOFORMAT_TARGA,
+ CAPTUREVIDEOFORMAT_JPEG,
+ CAPTUREVIDEOFORMAT_RAWRGB,
+ CAPTUREVIDEOFORMAT_RAWYV12
+}
+capturevideoformat_t;
+
+qboolean cl_capturevideo_active = false;
+capturevideoformat_t cl_capturevideo_format;
+static double cl_capturevideo_starttime = 0;
+double cl_capturevideo_framerate = 0;
+static int cl_capturevideo_soundrate = 0;
+static int cl_capturevideo_frame = 0;
+static qbyte *cl_capturevideo_buffer = NULL;
+static qfile_t *cl_capturevideo_videofile = NULL;
+static qfile_t *cl_capturevideo_soundfile = NULL;
+static short cl_capturevideo_rgbtoyuvscaletable[3][3][256];
+static unsigned char cl_capturevideo_yuvnormalizetable[3][256];
+static unsigned char cl_capturevideo_rgbgammatable[3][256];
+
+void SCR_CaptureVideo_BeginVideo(void)
+{
+ double gamma, g;
+ unsigned int i, j;
+ qbyte out[44];
+ if (cl_capturevideo_active)
+ return;
+ // soundrate is figured out on the first SoundFrame
+ cl_capturevideo_active = true;
+ cl_capturevideo_starttime = Sys_DoubleTime();
+ cl_capturevideo_framerate = bound(1, cl_capturevideo_fps.value, 1000);
+ cl_capturevideo_soundrate = 0;
+ cl_capturevideo_frame = 0;
+ cl_capturevideo_buffer = Mem_Alloc(tempmempool, vid.realwidth * vid.realheight * (3+3+3) + 18);
+ gamma = 1.0/scr_screenshot_gamma.value;
+
+ for (i = 0;i < 256;i++)
{
- size = 1;
- sb_lines = 0;
+ j = (unsigned char)bound(0, 255*pow(i/255.0, gamma), 255);
+ cl_capturevideo_rgbgammatable[0][i] = j;
+ cl_capturevideo_rgbgammatable[1][i] = j;
+ cl_capturevideo_rgbgammatable[2][i] = j;
}
- else
+/*
+R = Y + 1.4075 * (Cr - 128);
+G = Y + -0.3455 * (Cb - 128) + -0.7169 * (Cr - 128);
+B = Y + 1.7790 * (Cb - 128);
+Y = R * .299 + G * .587 + B * .114;
+Cb = R * -.169 + G * -.332 + B * .500 + 128.;
+Cr = R * .500 + G * -.419 + B * -.0813 + 128.;
+*/
+ for (i = 0;i < 256;i++)
{
- if (scr_viewsize.value >= 120)
- sb_lines = 0; // no status bar at all
- else if (scr_viewsize.value >= 110)
- sb_lines = 24; // no inventory
- else
- sb_lines = 24+16+8;
- size = scr_viewsize.value * (1.0 / 100.0);
+ g = i;//255*pow(i/255.0, gamma);
+ // Y weights from RGB
+ cl_capturevideo_rgbtoyuvscaletable[0][0][i] = (short)(g * 0.299);
+ cl_capturevideo_rgbtoyuvscaletable[0][1][i] = (short)(g * 0.587);
+ cl_capturevideo_rgbtoyuvscaletable[0][2][i] = (short)(g * 0.114);
+ // Cb weights from RGB
+ cl_capturevideo_rgbtoyuvscaletable[1][0][i] = (short)(g * -0.169);
+ cl_capturevideo_rgbtoyuvscaletable[1][1][i] = (short)(g * -0.332);
+ cl_capturevideo_rgbtoyuvscaletable[1][2][i] = (short)(g * 0.500);
+ // Cr weights from RGB
+ cl_capturevideo_rgbtoyuvscaletable[2][0][i] = (short)(g * 0.500);
+ cl_capturevideo_rgbtoyuvscaletable[2][1][i] = (short)(g * -0.419);
+ cl_capturevideo_rgbtoyuvscaletable[2][2][i] = (short)(g * -0.0813);
+ // range reduction of YCbCr to valid signal range
+ cl_capturevideo_yuvnormalizetable[0][i] = 16 + i * (236-16) / 256;
+ cl_capturevideo_yuvnormalizetable[1][i] = 16 + i * (240-16) / 256;
+ cl_capturevideo_yuvnormalizetable[2][i] = 16 + i * (240-16) / 256;
}
- if (size >= 1)
+ if (cl_capturevideo_rawrgb.integer)
{
- r_refdef.width = vid.realwidth;
- r_refdef.height = vid.realheight;
- r_refdef.x = 0;
- r_refdef.y = 0;
+ cl_capturevideo_format = CAPTUREVIDEOFORMAT_RAWRGB;
+ cl_capturevideo_videofile = FS_Open ("video/dpvideo.rgb", "wb", false);
+ }
+ else if (cl_capturevideo_rawyv12.integer)
+ {
+ cl_capturevideo_format = CAPTUREVIDEOFORMAT_RAWYV12;
+ cl_capturevideo_videofile = FS_Open ("video/dpvideo.yv12", "wb", false);
+ }
+ else if (scr_screenshot_jpeg.integer)
+ {
+ cl_capturevideo_format = CAPTUREVIDEOFORMAT_JPEG;
+ cl_capturevideo_videofile = NULL;
}
else
{
- r_refdef.width = vid.realwidth * size;
- r_refdef.height = vid.realheight * size;
- r_refdef.x = (vid.realwidth - r_refdef.width)/2;
- r_refdef.y = (vid.realheight - r_refdef.height)/2;
+ cl_capturevideo_format = CAPTUREVIDEOFORMAT_TARGA;
+ cl_capturevideo_videofile = NULL;
}
- r_refdef.width = bound(0, r_refdef.width, vid.realwidth);
- r_refdef.height = bound(0, r_refdef.height, vid.realheight);
- r_refdef.x = bound(0, r_refdef.x, vid.realwidth - r_refdef.width) + vid.realx;
- r_refdef.y = bound(0, r_refdef.y, vid.realheight - r_refdef.height) + vid.realy;
+ cl_capturevideo_soundfile = FS_Open ("video/dpvideo.wav", "wb", false);
- // LordHavoc: viewzoom (zoom in for sniper rifles, etc)
- r_refdef.fov_x = scr_fov.value * cl.viewzoom;
- r_refdef.fov_y = CalcFov (r_refdef.fov_x, r_refdef.width, r_refdef.height);
-
- if (cl.worldmodel)
- {
- Mod_CheckLoaded(cl.worldmodel);
- contents = cl.worldmodel ? cl.worldmodel->PointContents(cl.worldmodel, r_refdef.vieworg) : CONTENTS_EMPTY;
- if (contents != CONTENTS_EMPTY && contents != CONTENTS_SOLID)
- {
- r_refdef.fov_x *= (sin(cl.time * 4.7) * 0.015 + 0.985);
- r_refdef.fov_y *= (sin(cl.time * 3.0) * 0.015 + 0.985);
- }
- }
+ // wave header will be filled out when video ends
+ memset(out, 0, 44);
+ FS_Write (cl_capturevideo_soundfile, out, 44);
}
-/*
-==================
-SCR_ScreenShot_f
-==================
-*/
-void SCR_ScreenShot_f (void)
+void SCR_CaptureVideo_EndVideo(void)
{
- static int i = 0;
- char filename[16];
- char checkname[MAX_OSPATH];
- const char* extens;
- qboolean jpeg = (scr_screenshot_jpeg.integer != 0);
+ int i, n;
+ qbyte out[44];
+ if (!cl_capturevideo_active)
+ return;
+ cl_capturevideo_active = false;
- if (jpeg)
- extens = "jpg";
- else
- extens = "tga";
+ if (cl_capturevideo_videofile)
+ {
+ FS_Close(cl_capturevideo_videofile);
+ cl_capturevideo_videofile = NULL;
+ }
- // find a file name to save it to
- for (; i<=9999 ; i++)
+ // finish the wave file
+ if (cl_capturevideo_soundfile)
{
- sprintf (filename, "dp%04i.%s", i, extens);
- sprintf (checkname, "%s/%s", fs_gamedir, filename);
- if (!FS_SysFileExists(checkname))
- break;
+ i = FS_Tell (cl_capturevideo_soundfile);
+ //"RIFF", (int) unknown (chunk size), "WAVE",
+ //"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
+ //"data", (int) unknown (chunk size)
+ memcpy (out, "RIFF****WAVEfmt \x10\x00\x00\x00\x01\x00\x02\x00********\x04\x00\x10\0data****", 44);
+ // the length of the whole RIFF chunk
+ n = i - 8;
+ out[4] = (n) & 0xFF;
+ out[5] = (n >> 8) & 0xFF;
+ out[6] = (n >> 16) & 0xFF;
+ out[7] = (n >> 24) & 0xFF;
+ // rate
+ n = cl_capturevideo_soundrate;
+ out[24] = (n) & 0xFF;
+ out[25] = (n >> 8) & 0xFF;
+ out[26] = (n >> 16) & 0xFF;
+ out[27] = (n >> 24) & 0xFF;
+ // bytes per second (rate * channels * bytes per channel)
+ n = cl_capturevideo_soundrate * 2 * 2;
+ out[28] = (n) & 0xFF;
+ out[29] = (n >> 8) & 0xFF;
+ out[30] = (n >> 16) & 0xFF;
+ out[31] = (n >> 24) & 0xFF;
+ // the length of the data chunk
+ n = i - 44;
+ out[40] = (n) & 0xFF;
+ out[41] = (n >> 8) & 0xFF;
+ out[42] = (n >> 16) & 0xFF;
+ out[43] = (n >> 24) & 0xFF;
+ FS_Seek (cl_capturevideo_soundfile, 0, SEEK_SET);
+ FS_Write (cl_capturevideo_soundfile, out, 44);
+ FS_Close (cl_capturevideo_soundfile);
+ cl_capturevideo_soundfile = NULL;
}
- if (i==10000)
+
+ if (cl_capturevideo_buffer)
{
- Con_Printf ("SCR_ScreenShot_f: Couldn't create the image file\n");
- return;
- }
+ Mem_Free (cl_capturevideo_buffer);
+ cl_capturevideo_buffer = NULL;
+ }
- if (SCR_ScreenShot (filename, vid.realx, vid.realy, vid.realwidth, vid.realheight, jpeg))
- Con_Printf ("Wrote %s\n", filename);
- else
- Con_Printf ("unable to write %s\n", filename);
+ cl_capturevideo_starttime = 0;
+ cl_capturevideo_framerate = 0;
+ cl_capturevideo_frame = 0;
}
-static int cl_avidemo_frame = 0;
-
-void SCR_CaptureAVIDemo(void)
+qboolean SCR_CaptureVideo_VideoFrame(int newframenum)
{
+ int x = vid.realx, y = vid.realy, width = vid.realwidth, height = vid.realheight;
+ unsigned char *b, *out;
char filename[32];
- sprintf(filename, "dpavi%06d.tga", cl_avidemo_frame);
- if (SCR_ScreenShot(filename, vid.realx, vid.realy, vid.realwidth, vid.realheight, false))
- cl_avidemo_frame++;
- else
+ int outoffset = (width/2)*(height/2);
+ //return SCR_ScreenShot(filename, cl_capturevideo_buffer, cl_capturevideo_buffer + vid.realwidth * vid.realheight * 3, cl_capturevideo_buffer + vid.realwidth * vid.realheight * 6, vid.realx, vid.realy, vid.realwidth, vid.realheight, false, false, false, jpeg);
+ // speed is critical here, so do saving as directly as possible
+ switch (cl_capturevideo_format)
+ {
+ case CAPTUREVIDEOFORMAT_RAWYV12:
+ // FIXME: width/height must be multiple of 2, enforce this?
+ qglReadPixels (x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, cl_capturevideo_buffer);
+ CHECKGLERROR
+ // process one line at a time, and CbCr every other line at 2 pixel intervals
+ for (y = 0;y < height;y++)
+ {
+ // 1x1 Y
+ 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++)
+ *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]]];
+ if ((y & 1) == 0)
+ {
+ // 2x2 Cb and Cr planes
+#if 1
+ // low quality, no averaging
+ 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++)
+ {
+ // Cr
+ 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];
+ // Cb
+ 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];
+ }
+#else
+ // high quality, averaging
+ int inpitch = width*3;
+ 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++)
+ {
+ int blockr, blockg, blockb;
+ blockr = (b[0] + b[3] + b[inpitch+0] + b[inpitch+3]) >> 2;
+ blockg = (b[1] + b[4] + b[inpitch+1] + b[inpitch+4]) >> 2;
+ blockb = (b[2] + b[5] + b[inpitch+2] + b[inpitch+5]) >> 2;
+ // Cr
+ 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];
+ // Cb
+ 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];
+ }
+#endif
+ }
+ }
+ for (;cl_capturevideo_frame < newframenum;cl_capturevideo_frame++)
+ if (!FS_Write (cl_capturevideo_videofile, cl_capturevideo_buffer + width*height*3, width*height+(width/2)*(height/2)*2))
+ return false;
+ return true;
+ case CAPTUREVIDEOFORMAT_RAWRGB:
+ qglReadPixels (x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, cl_capturevideo_buffer);
+ CHECKGLERROR
+ for (;cl_capturevideo_frame < newframenum;cl_capturevideo_frame++)
+ if (!FS_Write (cl_capturevideo_videofile, cl_capturevideo_buffer, width*height*3))
+ return false;
+ return true;
+ case CAPTUREVIDEOFORMAT_JPEG:
+ qglReadPixels (x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, cl_capturevideo_buffer);
+ CHECKGLERROR
+ for (;cl_capturevideo_frame < newframenum;cl_capturevideo_frame++)
+ {
+ sprintf(filename, "video/dp%06d.jpg", cl_capturevideo_frame);
+ if (!JPEG_SaveImage_preflipped (filename, width, height, cl_capturevideo_buffer))
+ return false;
+ }
+ return true;
+ case CAPTUREVIDEOFORMAT_TARGA:
+ //return Image_WriteTGARGB_preflipped (filename, width, height, cl_capturevideo_buffer, cl_capturevideo_buffer + vid.realwidth * vid.realheight * 3, );
+ memset (cl_capturevideo_buffer, 0, 18);
+ cl_capturevideo_buffer[2] = 2; // uncompressed type
+ cl_capturevideo_buffer[12] = (width >> 0) & 0xFF;
+ cl_capturevideo_buffer[13] = (width >> 8) & 0xFF;
+ cl_capturevideo_buffer[14] = (height >> 0) & 0xFF;
+ cl_capturevideo_buffer[15] = (height >> 8) & 0xFF;
+ cl_capturevideo_buffer[16] = 24; // pixel size
+ qglReadPixels (x, y, width, height, GL_BGR, GL_UNSIGNED_BYTE, cl_capturevideo_buffer + 18);
+ CHECKGLERROR
+ for (;cl_capturevideo_frame < newframenum;cl_capturevideo_frame++)
+ {
+ sprintf(filename, "video/dp%06d.tga", cl_capturevideo_frame);
+ if (!FS_WriteFile (filename, cl_capturevideo_buffer, width*height*3 + 18))
+ return false;
+ }
+ return true;
+ default:
+ return false;
+ }
+}
+
+void SCR_CaptureVideo_SoundFrame(qbyte *bufstereo16le, size_t length, int rate)
+{
+ cl_capturevideo_soundrate = rate;
+ if (FS_Write (cl_capturevideo_soundfile, bufstereo16le, 4 * length) < 4 * length)
+ {
+ Cvar_SetValueQuick(&cl_capturevideo, 0);
+ Con_Printf("video sound saving failed on frame %i, out of disk space? stopping video capture.\n", cl_capturevideo_frame);
+ SCR_CaptureVideo_EndVideo();
+ }
+}
+
+void SCR_CaptureVideo(void)
+{
+ int newframenum;
+ if (cl_capturevideo.integer && r_render.integer)
{
- Cvar_SetValueQuick(&cl_avidemo, 0);
- Con_Printf("avi saving failed on frame %i, out of disk space? stopping avi demo catpure.\n", cl_avidemo_frame);
- cl_avidemo_frame = 0;
+ if (!cl_capturevideo_active)
+ SCR_CaptureVideo_BeginVideo();
+ if (cl_capturevideo_framerate != cl_capturevideo_fps.value)
+ {
+ Con_Printf("You can not change the video framerate while recording a video.\n");
+ Cvar_SetValueQuick(&cl_capturevideo_fps, cl_capturevideo_framerate);
+ }
+ newframenum = (Sys_DoubleTime() - cl_capturevideo_starttime) * cl_capturevideo_framerate;
+ // if falling behind more than one second, stop
+ if (newframenum - cl_capturevideo_frame > (int)ceil(cl_capturevideo_framerate))
+ {
+ Cvar_SetValueQuick(&cl_capturevideo, 0);
+ Con_Printf("video saving failed on frame %i, your machine is too slow for this capture speed.\n", cl_capturevideo_frame);
+ SCR_CaptureVideo_EndVideo();
+ return;
+ }
+ // write frames
+ if (!SCR_CaptureVideo_VideoFrame(newframenum))
+ {
+ Cvar_SetValueQuick(&cl_capturevideo, 0);
+ Con_Printf("video saving failed on frame %i, out of disk space? stopping video capture.\n", cl_capturevideo_frame);
+ SCR_CaptureVideo_EndVideo();
+ }
}
+ else if (cl_capturevideo_active)
+ SCR_CaptureVideo_EndVideo();
}
/*
{
float angles[3];
char *name;
+ qboolean flipx, flipy, flipdiagonaly;
}
-envmapinfo[6] =
+envmapinfo[12] =
{
- {{ 0, 0, 0}, "ft"},
- {{ 0, 90, 0}, "rt"},
- {{ 0, 180, 0}, "bk"},
- {{ 0, 270, 0}, "lf"},
- {{-90, 90, 0}, "up"},
- {{ 90, 90, 0}, "dn"}
+ {{ 0, 0, 0}, "rt", true, false, false},
+ {{ 0, 90, 0}, "ft", true, false, false},
+ {{ 0, 180, 0}, "lf", true, false, false},
+ {{ 0, 270, 0}, "bk", true, false, false},
+ {{-90, 180, 0}, "up", false, true, false},
+ {{ 90, 180, 0}, "dn", false, true, false},
+
+ {{ 0, 0, 0}, "px", true, true, true},
+ {{ 0, 90, 0}, "py", false, true, false},
+ {{ 0, 180, 0}, "nx", false, false, true},
+ {{ 0, 270, 0}, "ny", true, false, false},
+ {{-90, 180, 0}, "pz", false, false, true},
+ {{ 90, 180, 0}, "nz", false, false, true}
};
static void R_Envmap_f (void)
{
int j, size;
char filename[256], basename[256];
+ qbyte *buffer1;
+ qbyte *buffer2;
+ qbyte *buffer3;
if (Cmd_Argc() != 3)
{
- 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");
+ 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");
return;
}
- strcpy(basename, Cmd_Argv(1));
+ strlcpy (basename, Cmd_Argv(1), sizeof (basename));
size = atoi(Cmd_Argv(2));
if (size != 128 && size != 256 && size != 512 && size != 1024)
{
- Con_Printf("envmap: size must be one of 128, 256, 512, or 1024\n");
+ Con_Print("envmap: size must be one of 128, 256, 512, or 1024\n");
return;
}
if (size > vid.realwidth || size > vid.realheight)
{
- Con_Printf("envmap: your resolution is not big enough to render that size\n");
+ Con_Print("envmap: your resolution is not big enough to render that size\n");
return;
}
r_refdef.fov_x = 90;
r_refdef.fov_y = 90;
- for (j = 0;j < 6;j++)
+ buffer1 = Mem_Alloc(tempmempool, size * size * 3);
+ buffer2 = Mem_Alloc(tempmempool, size * size * 3);
+ buffer3 = Mem_Alloc(tempmempool, size * size * 3 + 18);
+
+ for (j = 0;j < 12;j++)
{
sprintf(filename, "env/%s%s.tga", basename, envmapinfo[j].name);
- VectorCopy(envmapinfo[j].angles, r_refdef.viewangles);
+ 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);
R_ClearScreen();
- R_RenderView ();
- SCR_ScreenShot(filename, vid.realx, vid.realy, size, size, false);
+ R_Mesh_Start();
+ R_RenderView();
+ R_Mesh_Finish();
+ SCR_ScreenShot(filename, buffer1, buffer2, buffer3, vid.realx, vid.realy + vid.realheight - (r_refdef.y + r_refdef.height), size, size, envmapinfo[j].flipx, envmapinfo[j].flipy, envmapinfo[j].flipdiagonaly, false);
}
+ Mem_Free (buffer1);
+ Mem_Free (buffer2);
+ Mem_Free (buffer3);
+
envmap = false;
}
int i, k;
qbyte lmplabel[256], picname[256];
float x, y;
- strcpy(lmplabel,MSG_ReadString());
- strcpy(picname, MSG_ReadString());
+ strlcpy (lmplabel,MSG_ReadString(), sizeof (lmplabel));
+ strlcpy (picname, MSG_ReadString(), sizeof (picname));
if (gamemode == GAME_NEHAHRA) // LordHavoc: nasty old legacy junk
{
x = MSG_ReadByte();
return; // none found to replace
// change existing one
showlmp[k].isactive = true;
- strcpy(showlmp[k].label, lmplabel);
- strcpy(showlmp[k].pic, picname);
+ strlcpy (showlmp[k].label, lmplabel, sizeof (showlmp[k].label));
+ strlcpy (showlmp[k].pic, picname, sizeof (showlmp[k].pic));
showlmp[k].x = x;
showlmp[k].y = y;
}
void CL_SetupScreenSize(void)
{
- static float old2dresolution = -1;
+ float conwidth, conheight;
VID_GetWindowSize (&vid.realx, &vid.realy, &vid.realwidth, &vid.realheight);
VID_UpdateGamma(false);
- if (scr_2dresolution.value != old2dresolution)
- {
- Cvar_SetValue("scr_2dresolution", bound(0.0f, scr_2dresolution.value, 1.0f));
- old2dresolution = scr_2dresolution.value;
- }
+ conwidth = bound(320, vid_conwidth.value, 2048);
+ conheight = bound(200, vid_conheight.value, 1536);
+ if (vid_conwidth.value != conwidth)
+ Cvar_SetValue("vid_conwidth", conwidth);
+ if (vid_conheight.value != conheight)
+ Cvar_SetValue("vid_conheight", conheight);
- if (vid.realwidth > 320)
- {
- vid.conwidth = (vid.realwidth - 320) * scr_2dresolution.value + 320;
- vid.conwidth = bound(320, vid.conwidth, vid.realwidth);
- }
- else
- vid.conwidth = 320;
+ vid.conwidth = vid_conwidth.integer;
+ vid.conheight = vid_conheight.integer;
- if (vid.realheight > 240)
+/* if (vid.realheight > 240)
{
vid.conheight = (vid.realheight - 240) * scr_2dresolution.value + 240;
vid.conheight = bound(240, vid.conheight, vid.realheight);
}
else
- vid.conheight = 240;
+ vid.conheight = 240;*/
SCR_SetUpToDrawConsole();
-
- // determine size of refresh window
- SCR_CalcRefdef();
}
extern void R_Shadow_EditLights_DrawSelectedLightProperties(void);
if (!scr_initialized || !con_initialized || vid_hidden)
return; // not initialized yet
- if (cl_avidemo.integer)
- SCR_CaptureAVIDemo();
+ // don't allow cheats in multiplayer
+ if (!cl.islocalgame && cl.worldmodel)
+ {
+ if (r_fullbright.integer != 0)
+ Cvar_Set ("r_fullbright", "0");
+ if (r_ambient.value != 0)
+ Cvar_Set ("r_ambient", "0");
+ }
+
+ // bound viewsize
+ if (scr_viewsize.value < 30)
+ Cvar_Set ("viewsize","30");
+ if (scr_viewsize.value > 120)
+ Cvar_Set ("viewsize","120");
+
+ // bound field of view
+ if (scr_fov.value < 1)
+ Cvar_Set ("fov","1");
+ if (scr_fov.value > 170)
+ Cvar_Set ("fov","170");
+
+ // intermission is always full screen
+ if (cl.intermission)
+ sb_lines = 0;
else
- cl_avidemo_frame = 0;
+ {
+ if (scr_viewsize.value >= 120)
+ sb_lines = 0; // no status bar at all
+ else if (scr_viewsize.value >= 110)
+ sb_lines = 24; // no inventory
+ else
+ sb_lines = 24+16+8;
+ }
+
+ r_refdef.colormask[0] = 1;
+ r_refdef.colormask[1] = 1;
+ r_refdef.colormask[2] = 1;
+
+ SCR_CaptureVideo();
if (cls.signon == SIGNONS)
R_TimeReport("other");
DrawQ_Clear();
- V_UpdateBlends();
- V_CalcRefdef ();
-
if (cls.signon == SIGNONS)
R_TimeReport("setup");
//FIXME: force menu if nothing else to look at?
//if (key_dest == key_game && cls.signon != SIGNONS && cls.state == ca_disconnected)
- if (scr_drawloading)
+ if (cls.signon == SIGNONS)
{
- scr_drawloading = false;
- SCR_DrawLoading();
+ SCR_DrawNet ();
+ SCR_DrawTurtle ();
+ SCR_DrawPause ();
+ if (!r_letterbox.value)
+ Sbar_Draw();
+ SHOWLMP_drawall();
+ SCR_CheckDrawCenterString();
}
- else
+ MR_Draw();
+ UI_Callback_Draw();
+ CL_DrawVideo();
+ //ui_draw();
+ if (cls.signon == SIGNONS)
{
- if (cls.signon == SIGNONS)
- {
- SCR_DrawNet ();
- SCR_DrawTurtle ();
- SCR_DrawPause ();
- Sbar_Draw();
- SHOWLMP_drawall();
- SCR_CheckDrawCenterString();
- }
- ui_draw();
- CL_DrawVideo();
- M_Draw();
- if (cls.signon == SIGNONS)
- {
- R_TimeReport("2d");
- R_TimeReport_End();
- R_TimeReport_Start();
- }
- R_Shadow_EditLights_DrawSelectedLightProperties();
+ R_TimeReport("2d");
+ R_TimeReport_End();
+ R_TimeReport_Start();
}
+ R_Shadow_EditLights_DrawSelectedLightProperties();
+
SCR_DrawConsole();
SCR_UpdateScreen();
{
SHOWLMP_clear();
}
-