cvar_t scr_loadingscreen_scale = {0, "scr_loadingscreen_scale","1", "scale factor of the background"};
cvar_t scr_loadingscreen_scale_base = {0, "scr_loadingscreen_scale_base","0", "0 = console pixels, 1 = video pixels"};
cvar_t scr_loadingscreen_scale_limit = {0, "scr_loadingscreen_scale_limit","0", "0 = no limit, 1 = until first edge hits screen edge, 2 = until last edge hits screen edge, 3 = until width hits screen width, 4 = until height hits screen height"};
+cvar_t scr_loadingscreen_picture = {CVAR_SAVE, "scr_loadingscreen_picture", "gfx/loading", "picture shown during loading"};
cvar_t scr_loadingscreen_count = {0, "scr_loadingscreen_count","1", "number of loading screen files to use randomly (named loading.tga, loading2.tga, loading3.tga, ...)"};
+cvar_t scr_loadingscreen_firstforstartup = {0, "scr_loadingscreen_firstforstartup","0", "remove loading.tga from random scr_loadingscreen_count selection and only display it on client startup, 0 = normal, 1 = firstforstartup"};
cvar_t scr_loadingscreen_barcolor = {0, "scr_loadingscreen_barcolor", "0 0 1", "rgb color of loadingscreen progress bar"};
cvar_t scr_loadingscreen_barheight = {0, "scr_loadingscreen_barheight", "8", "the height of the loadingscreen progress bar"};
+cvar_t scr_loadingscreen_maxfps = {0, "scr_loadingscreen_maxfps", "10", "restrict maximal FPS for loading screen so it will not update very often (this will make lesser loading times on a maps loading large number of models)"};
cvar_t scr_infobar_height = {0, "scr_infobar_height", "8", "the height of the infobar items"};
cvar_t vid_conwidth = {CVAR_SAVE, "vid_conwidth", "640", "virtual width of 2D graphics system"};
cvar_t vid_conheight = {CVAR_SAVE, "vid_conheight", "480", "virtual height of 2D graphics system"};
cvar_t scr_screenshot_gammaboost = {CVAR_SAVE, "scr_screenshot_gammaboost","1", "gamma correction on saved screenshots and videos, 1.0 saves unmodified images"};
cvar_t scr_screenshot_hwgamma = {CVAR_SAVE, "scr_screenshot_hwgamma","1", "apply the video gamma ramp to saved screenshots and videos"};
cvar_t scr_screenshot_alpha = {CVAR_SAVE, "scr_screenshot_alpha","0", "try to write an alpha channel to screenshots (debugging feature)"};
+cvar_t scr_screenshot_timestamp = {CVAR_SAVE, "scr_screenshot_timestamp", "1", "use a timestamp based number of the type YYYYMMDDHHMMSSsss instead of sequential numbering"};
// scr_screenshot_name is defined in fs.c
cvar_t cl_capturevideo = {0, "cl_capturevideo", "0", "enables saving of video to a .avi file using uncompressed I420 colorspace and PCM audio, note that scr_screenshot_gammaboost affects the brightness of the output)"};
cvar_t cl_capturevideo_printfps = {CVAR_SAVE, "cl_capturevideo_printfps", "1", "prints the frames per second captured in capturevideo (is only written to the log file, not to the console, as that would be visible on the video)"};
cvar_t r_stereo_redcyan = {0, "r_stereo_redcyan", "0", "red/cyan anaglyph stereo glasses, the kind given away at drive-in movies like Creature From The Black Lagoon In 3D"};
cvar_t r_stereo_redgreen = {0, "r_stereo_redgreen", "0", "red/green anaglyph stereo glasses (for those who don't mind yellow)"};
cvar_t r_stereo_angle = {0, "r_stereo_angle", "0", "separation angle of eyes (makes the views look different directions, as an example, 90 gives a 90 degree separation where the views are 45 degrees left and 45 degrees right)"};
-cvar_t scr_zoomwindow = {CVAR_SAVE, "scr_zoomwindow", "0", "displays a zoomed in overlay window"};
-cvar_t scr_zoomwindow_viewsizex = {CVAR_SAVE, "scr_zoomwindow_viewsizex", "20", "horizontal viewsize of zoom window"};
-cvar_t scr_zoomwindow_viewsizey = {CVAR_SAVE, "scr_zoomwindow_viewsizey", "20", "vertical viewsize of zoom window"};
-cvar_t scr_zoomwindow_fov = {CVAR_SAVE, "scr_zoomwindow_fov", "20", "fov of zoom window"};
cvar_t scr_stipple = {0, "scr_stipple", "0", "interlacing-like stippling of the display"};
cvar_t scr_refresh = {0, "scr_refresh", "1", "allows you to completely shut off rendering for benchmarking purposes"};
cvar_t scr_screenshot_name_in_mapdir = {CVAR_SAVE, "scr_screenshot_name_in_mapdir", "0", "if set to 1, screenshots are placed in a subdirectory named like the map they are from"};
}
-void SCR_DrawCenterString (void)
+static void SCR_DrawCenterString (void)
{
char *start;
int x, y;
} while (1);
}
-void SCR_CheckDrawCenterString (void)
+static void SCR_CheckDrawCenterString (void)
{
if (scr_center_lines > scr_erase_lines)
scr_erase_lines = scr_center_lines;
SCR_DrawCenterString ();
}
-void SCR_DrawNetGraph_DrawGraph (int graphx, int graphy, int graphwidth, int graphheight, float graphscale, const char *label, float textsize, int packetcounter, netgraphitem_t *netgraph)
+static void SCR_DrawNetGraph_DrawGraph (int graphx, int graphy, int graphwidth, int graphheight, float graphscale, const char *label, float textsize, int packetcounter, netgraphitem_t *netgraph)
{
netgraphitem_t *graph;
int j, x, y, numlines;
float *c;
DrawQ_Fill(graphx, graphy, graphwidth, graphheight + textsize * 2, 0, 0, 0, 0.5, 0);
// draw the bar graph itself
- // advance the packet counter because it is the latest packet column being
- // built up and should come last
- packetcounter = (packetcounter + 1) % NETGRAPH_PACKETS;
memset(g, 0, sizeof(g));
for (j = 0;j < NETGRAPH_PACKETS;j++)
{
SCR_DrawNetGraph
==============
*/
-void SCR_DrawNetGraph (void)
+static void SCR_DrawNetGraph (void)
{
int i, separator1, separator2, graphwidth, graphheight, netgraph_x, netgraph_y, textsize, index, netgraphsperrow;
float graphscale;
netconn_t *c;
+ char vabuf[1024];
if (cls.state != ca_connected)
return;
continue;
netgraph_x = (vid_conwidth.integer + separator2) - (1 + (index % netgraphsperrow)) * (graphwidth * 2 + separator1 + separator2);
netgraph_y = (vid_conheight.integer - 48 + separator2) - (1 + (index / netgraphsperrow)) * (graphheight + textsize + separator2);
- SCR_DrawNetGraph_DrawGraph(netgraph_x , netgraph_y, graphwidth, graphheight, graphscale, va("%s", svs.clients[i].name), textsize, c->outgoing_packetcounter, c->outgoing_netgraph);
+ SCR_DrawNetGraph_DrawGraph(netgraph_x , netgraph_y, graphwidth, graphheight, graphscale, va(vabuf, sizeof(vabuf), "%s", svs.clients[i].name), textsize, c->outgoing_packetcounter, c->outgoing_netgraph);
SCR_DrawNetGraph_DrawGraph(netgraph_x + graphwidth + separator1, netgraph_y, graphwidth, graphheight, graphscale, "" , textsize, c->incoming_packetcounter, c->incoming_netgraph);
index++;
}
SCR_DrawTurtle
==============
*/
-void SCR_DrawTurtle (void)
+static void SCR_DrawTurtle (void)
{
static int count;
SCR_DrawNet
==============
*/
-void SCR_DrawNet (void)
+static void SCR_DrawNet (void)
{
if (cls.state != ca_connected)
return;
DrawPause
==============
*/
-void SCR_DrawPause (void)
+static void SCR_DrawPause (void)
{
cachepic_t *pic;
SCR_DrawBrand
==============
*/
-void SCR_DrawBrand (void)
+static void SCR_DrawBrand (void)
{
cachepic_t *pic;
float x, y;
float size = scr_infobar_height.value;
Curl_downloadinfo_t *downinfo;
char temp[256];
+ char addinfobuf[128];
const char *addinfo;
- downinfo = Curl_GetDownloadInfo(&nDownloads, &addinfo);
+ downinfo = Curl_GetDownloadInfo(&nDownloads, &addinfo, addinfobuf, sizeof(addinfobuf));
if(!downinfo)
return 0;
Curl_downloadinfo_t *downinfo;
const char *addinfo;
int nDownloads;
+ char addinfobuf[128];
if (cl.time > cl.oldtime)
scr_infobartime_off -= cl.time - cl.oldtime;
if(cls.qw_downloadname[0])
offset += 1;
- downinfo = Curl_GetDownloadInfo(&nDownloads, &addinfo);
+ downinfo = Curl_GetDownloadInfo(&nDownloads, &addinfo, addinfobuf, sizeof(addinfobuf));
if(downinfo)
{
offset += (nDownloads + (addinfo ? 1 : 0));
SCR_InfoBar_f
==============
*/
-void SCR_InfoBar_f(void)
+static void SCR_InfoBar_f(void)
{
if(Cmd_Argc() == 3)
{
SCR_SetUpToDrawConsole
==================
*/
-void SCR_SetUpToDrawConsole (void)
+static void SCR_SetUpToDrawConsole (void)
{
// lines of console to display
float conlines;
================
*/
-void SCR_BeginLoadingPlaque (void)
+void SCR_BeginLoadingPlaque (qboolean startup)
{
// save console log up to this point to log_file if it was set by configs
Log_Start();
Host_StartVideo();
- SCR_UpdateLoadingScreen(false);
+ SCR_UpdateLoadingScreen(false, startup);
}
//=============================================================================
GL_Finish();
CHECKGLERROR
r_timereport_temp = r_timereport_current;
- r_timereport_current = Sys_DoubleTime();
+ r_timereport_current = Sys_DirtyTime();
t = (int) ((r_timereport_current - r_timereport_temp) * 1000000.0 + 0.5);
length = dpsnprintf(tempbuf, sizeof(tempbuf), "%8i %s", t, desc);
speedstringcount += length;
}
-void R_TimeReport_BeginFrame(void)
+static void R_TimeReport_BeginFrame(void)
{
speedstringcount = 0;
r_speeds_timestring[0] = 0;
if (r_speeds.integer >= 2)
{
r_timereport_active = true;
- r_timereport_start = r_timereport_current = Sys_DoubleTime();
+ r_timereport_start = r_timereport_current = Sys_DirtyTime();
}
}
extern cvar_t r_viewscale;
extern float viewscalefpsadjusted;
-void R_TimeReport_EndFrame(void)
+static void R_TimeReport_EndFrame(void)
{
int i, j, lines, y;
cl_locnode_t *loc;
loc = CL_Locs_FindNearest(cl.movement_origin);
viewleaf = (r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.PointInLeaf) ? r_refdef.scene.worldmodel->brush.PointInLeaf(r_refdef.scene.worldmodel, r_refdef.view.origin) : NULL;
dpsnprintf(string, sizeof(string),
-"%6.0fus rendertime %3.0f%% viewscale %s%s %.3f cl.time\n"
+"%6.0fus rendertime %3.0f%% viewscale %s%s %.3f cl.time%2.4f brightness\n"
"%3i renders org:'%+8.2f %+8.2f %+8.2f' dir:'%+2.3f %+2.3f %+2.3f'\n"
"%5i viewleaf%5i cluster%3i area%4i brushes%4i surfaces(%7i triangles)\n"
"%7i surfaces%7i triangles %5i entities (%7i surfaces%7i triangles)\n"
"%6i draws%8i vertices%8i triangles bloompixels%8i copied%8i drawn\n"
"updated%5i indexbuffers%8i bytes%5i vertexbuffers%8i bytes\n"
"%s"
-, r_refdef.lastdrawscreentime * 1000000.0, r_viewscale.value * sqrt(viewscalefpsadjusted) * 100.0f, loc ? "Location: " : "", loc ? loc->name : "", cl.time
+, r_refdef.lastdrawscreentime * 1000000.0, r_viewscale.value * sqrt(viewscalefpsadjusted) * 100.0f, loc ? "Location: " : "", loc ? loc->name : "", cl.time, r_refdef.view.colorscale
, r_refdef.stats.renders, r_refdef.view.origin[0], r_refdef.view.origin[1], r_refdef.view.origin[2], r_refdef.view.forward[0], r_refdef.view.forward[1], r_refdef.view.forward[2]
, viewleaf ? (int)(viewleaf - r_refdef.scene.worldmodel->brush.data_leafs) : -1, viewleaf ? viewleaf->clusterindex : -1, viewleaf ? viewleaf->areaindex : -1, viewleaf ? viewleaf->numleafbrushes : 0, viewleaf ? viewleaf->numleafsurfaces : 0, viewleaf ? R_CountLeafTriangles(r_refdef.scene.worldmodel, viewleaf) : 0
, r_refdef.stats.world_surfaces, r_refdef.stats.world_triangles, r_refdef.stats.entities, r_refdef.stats.entities_surfaces, r_refdef.stats.entities_triangles
if (r_speeds.integer >= 2)
{
r_timereport_active = true;
- r_timereport_start = r_timereport_current = Sys_DoubleTime();
+ r_timereport_start = r_timereport_current = Sys_DirtyTime();
}
}
Keybinding command
=================
*/
-void SCR_SizeUp_f (void)
+static void SCR_SizeUp_f (void)
{
Cvar_SetValue ("viewsize",scr_viewsize.value+10);
}
Keybinding command
=================
*/
-void SCR_SizeDown_f (void)
+static void SCR_SizeDown_f (void)
{
Cvar_SetValue ("viewsize",scr_viewsize.value-10);
}
Cvar_RegisterVariable (&scr_loadingscreen_scale);
Cvar_RegisterVariable (&scr_loadingscreen_scale_base);
Cvar_RegisterVariable (&scr_loadingscreen_scale_limit);
+ Cvar_RegisterVariable (&scr_loadingscreen_picture);
Cvar_RegisterVariable (&scr_loadingscreen_count);
+ Cvar_RegisterVariable (&scr_loadingscreen_firstforstartup);
Cvar_RegisterVariable (&scr_loadingscreen_barcolor);
Cvar_RegisterVariable (&scr_loadingscreen_barheight);
+ Cvar_RegisterVariable (&scr_loadingscreen_maxfps);
Cvar_RegisterVariable (&scr_infobar_height);
Cvar_RegisterVariable (&scr_showram);
Cvar_RegisterVariable (&scr_showturtle);
Cvar_RegisterVariable (&scr_screenshot_hwgamma);
Cvar_RegisterVariable (&scr_screenshot_name_in_mapdir);
Cvar_RegisterVariable (&scr_screenshot_alpha);
+ Cvar_RegisterVariable (&scr_screenshot_timestamp);
Cvar_RegisterVariable (&cl_capturevideo);
Cvar_RegisterVariable (&cl_capturevideo_printfps);
Cvar_RegisterVariable (&cl_capturevideo_width);
Cvar_RegisterVariable(&r_stereo_redcyan);
Cvar_RegisterVariable(&r_stereo_redgreen);
Cvar_RegisterVariable(&r_stereo_angle);
- Cvar_RegisterVariable(&scr_zoomwindow);
- Cvar_RegisterVariable(&scr_zoomwindow_viewsizex);
- Cvar_RegisterVariable(&scr_zoomwindow_viewsizey);
- Cvar_RegisterVariable(&scr_zoomwindow_fov);
Cvar_RegisterVariable(&scr_stipple);
Cvar_RegisterVariable(&scr_refresh);
Cvar_RegisterVariable(&shownetgraph);
Cvar_RegisterVariable(&vid_touchscreen_outlinealpha);
Cvar_RegisterVariable(&vid_touchscreen_overlayalpha);
+ // if we want no console, turn it off here too
+ if (COM_CheckParm ("-noconsole"))
+ Cvar_SetQuick(&scr_conforcewhiledisconnected, "0");
+
Cmd_AddCommand ("sizeup",SCR_SizeUp_f, "increase view size (increases viewsize cvar)");
Cmd_AddCommand ("sizedown",SCR_SizeDown_f, "decrease view size (decreases viewsize cvar)");
Cmd_AddCommand ("screenshot",SCR_ScreenShot_f, "takes a screenshot of the next rendered frame");
unsigned char *buffer2;
qboolean jpeg = (scr_screenshot_jpeg.integer != 0);
qboolean png = (scr_screenshot_png.integer != 0) && !jpeg;
+ char vabuf[1024];
if (Cmd_Argc() == 2)
{
return;
}
}
+ else if (scr_screenshot_timestamp.integer)
+ {
+ int shotnumber100;
+
+ // TODO maybe make capturevideo and screenshot use similar name patterns?
+ if (scr_screenshot_name_in_mapdir.integer && cl.worldbasename[0])
+ dpsnprintf(prefix_name, sizeof(prefix_name), "%s/%s%s", cl.worldbasename, scr_screenshot_name.string, Sys_TimeString("%Y%m%d%H%M%S"));
+ else
+ dpsnprintf(prefix_name, sizeof(prefix_name), "%s%s", scr_screenshot_name.string, Sys_TimeString("%Y%m%d%H%M%S"));
+
+ // find a file name to save it to
+ for (shotnumber100 = 0;shotnumber100 < 100;shotnumber100++)
+ if (!FS_SysFileExists(va(vabuf, sizeof(vabuf), "%s/screenshots/%s-%02d.tga", fs_gamedir, prefix_name, shotnumber100))
+ && !FS_SysFileExists(va(vabuf, sizeof(vabuf), "%s/screenshots/%s-%02d.jpg", fs_gamedir, prefix_name, shotnumber100))
+ && !FS_SysFileExists(va(vabuf, sizeof(vabuf), "%s/screenshots/%s-%02d.png", fs_gamedir, prefix_name, shotnumber100)))
+ break;
+ if (shotnumber100 >= 100)
+ {
+ Con_Print("Couldn't create the image file - already 100 shots taken this second!\n");
+ return;
+ }
+
+ dpsnprintf(filename, sizeof(filename), "screenshots/%s-%02d.%s", prefix_name, shotnumber100, jpeg ? "jpg" : png ? "png" : "tga");
+ }
else
{
// TODO maybe make capturevideo and screenshot use similar name patterns?
if (scr_screenshot_name_in_mapdir.integer && cl.worldbasename[0])
- dpsnprintf (prefix_name, sizeof(prefix_name), "%s/%s", cl.worldbasename, Sys_TimeString(scr_screenshot_name.string));
+ dpsnprintf(prefix_name, sizeof(prefix_name), "%s/%s", cl.worldbasename, Sys_TimeString(scr_screenshot_name.string));
else
- dpsnprintf (prefix_name, sizeof(prefix_name), "%s", Sys_TimeString(scr_screenshot_name.string));
+ dpsnprintf(prefix_name, sizeof(prefix_name), "%s", Sys_TimeString(scr_screenshot_name.string));
+ // if prefix changed, gamedir or map changed, reset the shotnumber so
+ // we scan again
+ // FIXME: should probably do this whenever FS_Rescan or something like that occurs?
if (strcmp(old_prefix_name, prefix_name))
{
dpsnprintf(old_prefix_name, sizeof(old_prefix_name), "%s", prefix_name );
// find a file name to save it to
for (;shotnumber < 1000000;shotnumber++)
- if (!FS_SysFileExists(va("%s/screenshots/%s%06d.tga", fs_gamedir, prefix_name, shotnumber)) && !FS_SysFileExists(va("%s/screenshots/%s%06d.jpg", fs_gamedir, prefix_name, shotnumber)) && !FS_SysFileExists(va("%s/screenshots/%s%06d.png", fs_gamedir, prefix_name, shotnumber)))
+ if (!FS_SysFileExists(va(vabuf, sizeof(vabuf), "%s/screenshots/%s%06d.tga", fs_gamedir, prefix_name, shotnumber))
+ && !FS_SysFileExists(va(vabuf, sizeof(vabuf), "%s/screenshots/%s%06d.jpg", fs_gamedir, prefix_name, shotnumber))
+ && !FS_SysFileExists(va(vabuf, sizeof(vabuf), "%s/screenshots/%s%06d.png", fs_gamedir, prefix_name, shotnumber)))
break;
if (shotnumber >= 1000000)
{
- Con_Print("Couldn't create the image file\n");
+ Con_Print("Couldn't create the image file - you already have 1000000 screenshots!\n");
return;
}
dpsnprintf(filename, sizeof(filename), "screenshots/%s%06d.%s", prefix_name, shotnumber, jpeg ? "jpg" : png ? "png" : "tga");
+
+ shotnumber++;
}
buffer1 = (unsigned char *)Mem_Alloc(tempmempool, vid.width * vid.height * 4);
Mem_Free (buffer1);
Mem_Free (buffer2);
-
- shotnumber++;
}
-void SCR_CaptureVideo_BeginVideo(void)
+static void SCR_CaptureVideo_BeginVideo(void)
{
double r, g, b;
unsigned int i;
cls.capturevideo.soundchannels = S_GetSoundChannels();
cls.capturevideo.startrealtime = realtime;
cls.capturevideo.frame = cls.capturevideo.lastfpsframe = 0;
- cls.capturevideo.starttime = cls.capturevideo.lastfpstime = Sys_DoubleTime();
+ cls.capturevideo.starttime = cls.capturevideo.lastfpstime = realtime;
cls.capturevideo.soundsampleframe = 0;
cls.capturevideo.realtime = cl_capturevideo_realtime.integer != 0;
cls.capturevideo.screenbuffer = (unsigned char *)Mem_Alloc(tempmempool, vid.width * vid.height * 4);
}
}
-void SCR_CaptureVideo_VideoFrame(int newframestepframenum)
+static void SCR_CaptureVideo_VideoFrame(int newframestepframenum)
{
int x = 0, y = 0;
int width = cls.capturevideo.width, height = cls.capturevideo.height;
if(cl_capturevideo_printfps.integer)
{
char buf[80];
- double t = Sys_DoubleTime();
+ double t = realtime;
if(t > cls.capturevideo.lastfpstime + 1)
{
double fps1 = (cls.capturevideo.frame - cls.capturevideo.lastfpsframe) / (t - cls.capturevideo.lastfpstime + 0.0000001);
cls.capturevideo.soundframe(paintbuffer, length);
}
-void SCR_CaptureVideo(void)
+static void SCR_CaptureVideo(void)
{
int newframenum;
if (cl_capturevideo.integer)
r_refdef.view.frustum_x = 1; // tan(45 * M_PI / 180.0);
r_refdef.view.frustum_y = 1; // tan(45 * M_PI / 180.0);
+ r_refdef.view.ortho_x = 90; // abused as angle by VM_CL_R_SetView
+ r_refdef.view.ortho_y = 90; // abused as angle by VM_CL_R_SetView
buffer1 = (unsigned char *)Mem_Alloc(tempmempool, size * size * 4);
buffer2 = (unsigned char *)Mem_Alloc(tempmempool, size * size * 3);
{
int i;
char *lmplabel;
- lmplabel = MSG_ReadString();
+ lmplabel = MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring));
for (i = 0;i < cl.num_showlmps;i++)
if (cl.showlmps[i].isactive && strcmp(cl.showlmps[i].label, lmplabel) == 0)
{
int k;
char lmplabel[256], picname[256];
float x, y;
- strlcpy (lmplabel,MSG_ReadString(), sizeof (lmplabel));
- strlcpy (picname, MSG_ReadString(), sizeof (picname));
+ strlcpy (lmplabel,MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)), sizeof (lmplabel));
+ strlcpy (picname, MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring)), sizeof (picname));
if (gamemode == GAME_NEHAHRA) // LordHavoc: nasty old legacy junk
{
- x = MSG_ReadByte();
- y = MSG_ReadByte();
+ x = MSG_ReadByte(&cl_message);
+ y = MSG_ReadByte(&cl_message);
}
else
{
- x = MSG_ReadShort();
- y = MSG_ReadShort();
+ x = MSG_ReadShort(&cl_message);
+ y = MSG_ReadShort(&cl_message);
}
if (!cl.showlmps || cl.num_showlmps >= cl.max_showlmps)
{
}
}
-extern void R_UpdateFogColor(void);
void R_ClearScreen(qboolean fogcolor)
{
float clearcolor[4];
// clear to black
Vector4Clear(clearcolor);
- if (fogcolor)
+ if (fogcolor && r_fog_clear.integer)
{
- R_UpdateFogColor();
- if (r_fog_clear.integer)
- VectorCopy(r_refdef.fogcolor, clearcolor);
+ R_UpdateFog();
+ VectorCopy(r_refdef.fogcolor, clearcolor);
}
// clear depth is 1.0
// LordHavoc: we use a stencil centered around 128 instead of 0,
GL_Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | (vid.stencil ? GL_STENCIL_BUFFER_BIT : 0), clearcolor, 1.0f, 128);
}
-qboolean CL_VM_UpdateView (void);
-void SCR_DrawConsole (void);
-void R_Shadow_EditLights_DrawSelectedLightProperties(void);
-
int r_stereo_side;
-extern void Sbar_ShowFPS(void);
-void SCR_DrawScreen (void)
+static void SCR_DrawScreen (void)
{
Draw_Frame();
r_refdef.view.frustum_x *= r_refdef.frustumscale_x;
r_refdef.view.frustum_y *= r_refdef.frustumscale_y;
+ r_refdef.view.ortho_x = atan(r_refdef.view.frustum_x) * (360.0 / M_PI); // abused as angle by VM_CL_R_SetView
+ r_refdef.view.ortho_y = atan(r_refdef.view.frustum_y) * (360.0 / M_PI); // abused as angle by VM_CL_R_SetView
if(!CL_VM_UpdateView())
R_RenderView();
-
- if (scr_zoomwindow.integer)
- {
- float sizex = bound(10, scr_zoomwindow_viewsizex.value, 100) / 100.0;
- float sizey = bound(10, scr_zoomwindow_viewsizey.value, 100) / 100.0;
- r_refdef.view.width = (int)(vid.width * sizex);
- r_refdef.view.height = (int)(vid.height * sizey);
- r_refdef.view.depth = 1;
- r_refdef.view.x = (int)((vid.width - r_refdef.view.width)/2);
- r_refdef.view.y = 0;
- r_refdef.view.z = 0;
-
- r_refdef.view.useperspective = true;
- r_refdef.view.frustum_y = tan(scr_zoomwindow_fov.value * M_PI / 360.0) * (3.0/4.0) * cl.viewzoom;
- r_refdef.view.frustum_x = r_refdef.view.frustum_y * vid_pixelheight.value * (float)r_refdef.view.width / (float)r_refdef.view.height;
-
- r_refdef.view.frustum_x *= r_refdef.frustumscale_x;
- r_refdef.view.frustum_y *= r_refdef.frustumscale_y;
-
- if(!CL_VM_UpdateView())
- R_RenderView();
- }
}
if (!r_stereo_sidebyside.integer && !r_stereo_horizontal.integer && !r_stereo_vertical.integer)
void SCR_UpdateLoadingScreenIfShown(void)
{
if(loadingscreendone)
- SCR_UpdateLoadingScreen(loadingscreencleared);
+ SCR_UpdateLoadingScreen(loadingscreencleared, false);
}
void SCR_PushLoadingScreen (qboolean redraw, const char *msg, float len_in_parent)
sscanf(scr_loadingscreen_barcolor.string, "%f %f %f", &colors[12], &colors[13], &colors[14]); colors[15] = 1;
R_Mesh_PrepareVertices_Generic_Arrays(4, verts, colors, NULL);
- R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1, true, true);
+ R_SetupShader_Generic_NoTexture(true, true);
R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
// make sure everything is cleared, including the progress indicator
{
r_viewport_t viewport;
float x, y, w, h, sw, sh, f;
+ char vabuf[1024];
// release mouse grab while loading
if (!vid.fullscreen)
VID_SetMouse(false, false, false);
// CHECKGLERROR
r_refdef.draw2dstage = true;
R_Viewport_InitOrtho(&viewport, &identitymatrix, 0, 0, vid.width, vid.height, 0, 0, vid_conwidth.integer, vid_conheight.integer, -10, 100, NULL);
- R_Mesh_ResetRenderTargets();
+ R_Mesh_SetRenderTargets(0, NULL, NULL, NULL, NULL, NULL);
R_SetViewport(&viewport);
GL_ColorMask(1,1,1,1);
// when starting up a new video mode, make sure the screen is cleared to black
R_Mesh_Start();
R_EntityMatrix(&identitymatrix);
// draw the loading plaque
- loadingscreenpic = Draw_CachePic_Flags (loadingscreenpic_number ? va("gfx/loading%d", loadingscreenpic_number+1) : "gfx/loading", loadingscreenpic_number ? CACHEPICFLAG_NOTPERSISTENT : 0);
+ loadingscreenpic = Draw_CachePic_Flags (loadingscreenpic_number ? va(vabuf, sizeof(vabuf), "%s%d", scr_loadingscreen_picture.string, loadingscreenpic_number+1) : scr_loadingscreen_picture.string, loadingscreenpic_number ? CACHEPICFLAG_NOTPERSISTENT : 0);
w = loadingscreenpic->width;
h = loadingscreenpic->height;
if(loadingscreentexture)
{
R_Mesh_PrepareVertices_Generic_Arrays(4, loadingscreentexture_vertex3f, NULL, loadingscreentexture_texcoord2f);
- R_SetupShader_Generic(loadingscreentexture, NULL, GL_MODULATE, 1, true, true);
+ R_SetupShader_Generic(loadingscreentexture, NULL, GL_MODULATE, 1, true, true, true);
R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
}
R_Mesh_PrepareVertices_Generic_Arrays(4, loadingscreenpic_vertex3f, NULL, loadingscreenpic_texcoord2f);
- R_SetupShader_Generic(Draw_GetPicTexture(loadingscreenpic), NULL, GL_MODULATE, 1, true, true);
+ R_SetupShader_Generic(Draw_GetPicTexture(loadingscreenpic), NULL, GL_MODULATE, 1, true, true, false);
R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
SCR_DrawLoadingStack();
}
VID_Finish();
}
-void SCR_UpdateLoadingScreen (qboolean clear)
+static double loadingscreen_lastupdate;
+
+void SCR_UpdateLoadingScreen (qboolean clear, qboolean startup)
{
keydest_t old_key_dest;
int old_key_consoleactive;
if (vid_hidden || cls.state == ca_dedicated)
return;
+ // limit update rate
+ if (scr_loadingscreen_maxfps.value)
+ {
+ double t = Sys_DirtyTime();
+ if ((t - loadingscreen_lastupdate) < 1.0f/scr_loadingscreen_maxfps.value)
+ return;
+ loadingscreen_lastupdate = t;
+ }
+
if(!scr_loadingscreen_background.integer)
clear = true;
clear |= loadingscreencleared;
if(!loadingscreendone)
- loadingscreenpic_number = rand() % (scr_loadingscreen_count.integer > 1 ? scr_loadingscreen_count.integer : 1);
+ {
+ if(startup && scr_loadingscreen_firstforstartup.integer)
+ loadingscreenpic_number = 0;
+ else if(scr_loadingscreen_firstforstartup.integer)
+ if(scr_loadingscreen_count.integer > 1)
+ loadingscreenpic_number = rand() % (scr_loadingscreen_count.integer - 1) + 1;
+ else
+ loadingscreenpic_number = 0;
+ else
+ loadingscreenpic_number = rand() % (scr_loadingscreen_count.integer > 1 ? scr_loadingscreen_count.integer : 1);
+ }
if(clear)
SCR_ClearLoadingScreenTexture();
}
loadingscreencleared = clear;
+#ifdef USE_GLES2
+ SCR_DrawLoadingScreen_SharedSetup(clear);
+ SCR_DrawLoadingScreen(clear);
+#else
if (qglDrawBuffer)
qglDrawBuffer(GL_BACK);
SCR_DrawLoadingScreen_SharedSetup(clear);
qglDrawBuffer(GL_BACK);
SCR_DrawLoadingScreen(clear);
}
+#endif
SCR_DrawLoadingScreen_SharedFinish(clear);
// this goes into the event loop, and should prevent unresponsive cursor on vista
extern cvar_t cl_minfps_fade;
extern cvar_t cl_minfps_qualitymax;
extern cvar_t cl_minfps_qualitymin;
-extern cvar_t cl_minfps_qualitypower;
-extern cvar_t cl_minfps_qualityscale;
-extern cvar_t r_viewscale_fpsscaling;
-static double cl_updatescreen_rendertime = 0;
+extern cvar_t cl_minfps_qualitymultiply;
+extern cvar_t cl_minfps_qualityhysteresis;
+extern cvar_t cl_minfps_qualitystepmax;
+extern cvar_t cl_minfps_force;
static double cl_updatescreen_quality = 1;
-extern void Sbar_ShowFPS_Update(void);
void CL_UpdateScreen(void)
{
vec3_t vieworigin;
- double rendertime1;
- double drawscreenstart;
+ static double drawscreenstart = 0.0;
+ double drawscreendelta;
float conwidth, conheight;
- float f;
r_viewport_t viewport;
+ if(drawscreenstart)
+ {
+ drawscreendelta = Sys_DirtyTime() - drawscreenstart;
+ if (cl_minfps.value > 0 && (cl_minfps_force.integer || !(cls.timedemo || (cls.capturevideo.active && !cls.capturevideo.realtime))) && drawscreendelta >= 0 && drawscreendelta < 60)
+ {
+ // quality adjustment according to render time
+ double actualframetime;
+ double targetframetime;
+ double adjust;
+ double f;
+ double h;
+
+ // fade lastdrawscreentime
+ r_refdef.lastdrawscreentime += (drawscreendelta - r_refdef.lastdrawscreentime) * cl_minfps_fade.value;
+
+ // find actual and target frame times
+ actualframetime = r_refdef.lastdrawscreentime;
+ targetframetime = (1.0 / cl_minfps.value);
+
+ // we scale hysteresis by quality
+ h = cl_updatescreen_quality * cl_minfps_qualityhysteresis.value;
+
+ // calculate adjustment assuming linearity
+ f = cl_updatescreen_quality / actualframetime * cl_minfps_qualitymultiply.value;
+ adjust = (targetframetime - actualframetime) * f;
+
+ // one sided hysteresis
+ if(adjust > 0)
+ adjust = max(0, adjust - h);
+
+ // adjust > 0 if:
+ // (targetframetime - actualframetime) * f > h
+ // ((1.0 / cl_minfps.value) - actualframetime) * (cl_updatescreen_quality / actualframetime * cl_minfps_qualitymultiply.value) > (cl_updatescreen_quality * cl_minfps_qualityhysteresis.value)
+ // ((1.0 / cl_minfps.value) - actualframetime) * (cl_minfps_qualitymultiply.value / actualframetime) > cl_minfps_qualityhysteresis.value
+ // (1.0 / cl_minfps.value) * (cl_minfps_qualitymultiply.value / actualframetime) - cl_minfps_qualitymultiply.value > cl_minfps_qualityhysteresis.value
+ // (1.0 / cl_minfps.value) * (cl_minfps_qualitymultiply.value / actualframetime) > cl_minfps_qualityhysteresis.value + cl_minfps_qualitymultiply.value
+ // (1.0 / cl_minfps.value) / actualframetime > (cl_minfps_qualityhysteresis.value + cl_minfps_qualitymultiply.value) / cl_minfps_qualitymultiply.value
+ // (1.0 / cl_minfps.value) / actualframetime > 1.0 + cl_minfps_qualityhysteresis.value / cl_minfps_qualitymultiply.value
+ // cl_minfps.value * actualframetime < 1.0 / (1.0 + cl_minfps_qualityhysteresis.value / cl_minfps_qualitymultiply.value)
+ // actualframetime < 1.0 / cl_minfps.value / (1.0 + cl_minfps_qualityhysteresis.value / cl_minfps_qualitymultiply.value)
+ // actualfps > cl_minfps.value * (1.0 + cl_minfps_qualityhysteresis.value / cl_minfps_qualitymultiply.value)
+
+ // adjust < 0 if:
+ // (targetframetime - actualframetime) * f < 0
+ // ((1.0 / cl_minfps.value) - actualframetime) * (cl_updatescreen_quality / actualframetime * cl_minfps_qualitymultiply.value) < 0
+ // ((1.0 / cl_minfps.value) - actualframetime) < 0
+ // -actualframetime) < -(1.0 / cl_minfps.value)
+ // actualfps < cl_minfps.value
+
+ /*
+ Con_Printf("adjust UP if fps > %f, adjust DOWN if fps < %f\n",
+ cl_minfps.value * (1.0 + cl_minfps_qualityhysteresis.value / cl_minfps_qualitymultiply.value),
+ cl_minfps.value);
+ */
+
+ // don't adjust too much at once
+ adjust = bound(-cl_minfps_qualitystepmax.value, adjust, cl_minfps_qualitystepmax.value);
+
+ // adjust!
+ cl_updatescreen_quality += adjust;
+ cl_updatescreen_quality = bound(max(0.01, cl_minfps_qualitymin.value), cl_updatescreen_quality, cl_minfps_qualitymax.value);
+ }
+ else
+ {
+ cl_updatescreen_quality = 1;
+ r_refdef.lastdrawscreentime = 0;
+ }
+ }
+
+ drawscreenstart = Sys_DirtyTime();
+
Sbar_ShowFPS_Update();
if (!scr_initialized || !con_initialized || !scr_refresh.integer)
return;
}
- rendertime1 = Sys_DoubleTime();
-
conwidth = bound(160, vid_conwidth.value, 32768);
conheight = bound(90, vid_conheight.value, 24576);
if (vid_conwidth.value != conwidth)
SCR_SetUpToDrawConsole();
+#ifndef USE_GLES2
if (qglDrawBuffer)
{
CHECKGLERROR
qglDisable(GL_DITHER);CHECKGLERROR
}
}
+#endif
R_Viewport_InitOrtho(&viewport, &identitymatrix, 0, 0, vid.width, vid.height, 0, 0, vid_conwidth.integer, vid_conheight.integer, -10, 100, NULL);
- R_Mesh_ResetRenderTargets();
+ R_Mesh_SetRenderTargets(0, NULL, NULL, NULL, NULL, NULL);
R_SetViewport(&viewport);
GL_ScissorTest(false);
GL_ColorMask(1,1,1,1);
R_ClearScreen(false);
r_refdef.view.clear = false;
r_refdef.view.isoverlay = false;
- f = pow((float)cl_updatescreen_quality, cl_minfps_qualitypower.value) * cl_minfps_qualityscale.value;
- r_refdef.view.quality = bound(cl_minfps_qualitymin.value, f, cl_minfps_qualitymax.value);
+ // calculate r_refdef.view.quality
+ r_refdef.view.quality = cl_updatescreen_quality;
+
+#ifndef USE_GLES2
if (qglPolygonStipple)
{
if(scr_stipple.integer)
qglDisable(GL_POLYGON_STIPPLE);CHECKGLERROR
}
}
+#endif
- if (r_viewscale_fpsscaling.integer)
- GL_Finish();
- drawscreenstart = Sys_DoubleTime();
+#ifndef USE_GLES2
if (R_Stereo_Active())
{
r_stereo_side = 0;
SCR_DrawScreen();
r_stereo_side = 1;
+ r_refdef.view.clear = true;
if (r_stereo_redblue.integer || r_stereo_redgreen.integer || r_stereo_redcyan.integer)
{
SCR_DrawScreen();
}
else
+#endif
SCR_DrawScreen();
- if (r_viewscale_fpsscaling.integer)
- GL_Finish();
- r_refdef.lastdrawscreentime = Sys_DoubleTime() - drawscreenstart;
SCR_CaptureVideo();
if (qglFlush)
qglFlush(); // FIXME: should we really be using qglFlush here?
- // quality adjustment according to render time
- cl_updatescreen_rendertime += ((Sys_DoubleTime() - rendertime1) - cl_updatescreen_rendertime) * bound(0, cl_minfps_fade.value, 1);
- if (cl_minfps.value > 0 && cl_updatescreen_rendertime > 0 && !cls.timedemo && (!cls.capturevideo.active || !cls.capturevideo.realtime))
- cl_updatescreen_quality = 1 / (cl_updatescreen_rendertime * cl_minfps.value);
- else
- cl_updatescreen_quality = 1;
-
if (!vid_activewindow)
VID_SetMouse(false, false, false);
else if (key_consoleactive)