#include "cl_video.h"
#include "image.h"
#include "jpeg.h"
+#include "image_png.h"
#include "cl_collision.h"
#include "libcurl.h"
#include "csprogs.h"
cvar_t scr_showbrand = {0, "showbrand","0", "shows gfx/brand.tga in a corner of the screen (different values select different positions, including centered)"};
cvar_t scr_printspeed = {0, "scr_printspeed","0", "speed of intermission printing (episode end texts), a value of 0 disables the slow printing"};
cvar_t scr_loadingscreen_background = {0, "scr_loadingscreen_background","0", "show the last visible background during loading screen (costs one screenful of video memory)"};
+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_barcolor = {0, "scr_loadingscreen_barcolor", "0 0 1", "rgb color of loadingscreen progress bar"};
+cvar_t scr_loadingscreen_barheight = {0, "scr_loadingscreen_barheight", "8", "a height loadingscreen progress bar"};
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 vid_pixelheight = {CVAR_SAVE, "vid_pixelheight", "1", "adjusts vertical field of vision to account for non-square pixels (1280x1024 on a CRT monitor for example)"};
cvar_t scr_screenshot_jpeg = {CVAR_SAVE, "scr_screenshot_jpeg","1", "save jpeg instead of targa"};
cvar_t scr_screenshot_jpeg_quality = {CVAR_SAVE, "scr_screenshot_jpeg_quality","0.9", "image quality of saved jpeg"};
+cvar_t scr_screenshot_png = {CVAR_SAVE, "scr_screenshot_png","0", "save png instead of targa"};
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"};
// scr_screenshot_name is defined in fs.c
// scan the number of characters on the line, not counting color codes
char *newline = strchr(start, '\n');
int l = newline ? (newline - start) : (int)strlen(start);
- float width = DrawQ_TextWidth_Font(start, l, false, FONT_CENTERPRINT) * 8;
+ float width = DrawQ_TextWidth(start, l, 8, 8, false, FONT_CENTERPRINT);
x = (int) (vid_conwidth.integer - width)/2;
if (l > 0)
{
if (remaining < l)
l = remaining;
- DrawQ_String_Font(x, y, start, l, 8, 8, 1, 1, 1, 1, 0, &color, false, FONT_CENTERPRINT);
+ DrawQ_String(x, y, start, l, 8, 8, 1, 1, 1, 1, 0, &color, false, FONT_CENTERPRINT);
remaining -= l;
if (remaining <= 0)
return;
x = graphx;
y = graphy + graphheight;
dpsnprintf(bytesstring, sizeof(bytesstring), "%i", totalbytes);
- DrawQ_String(x, y, label , 0, textsize, textsize, 1.0f, 1.0f, 1.0f, 1.0f, 0, NULL, false);y += textsize;
- DrawQ_String(x, y, bytesstring, 0, textsize, textsize, 1.0f, 1.0f, 1.0f, 1.0f, 0, NULL, false);y += textsize;
+ DrawQ_String(x, y, label , 0, textsize, textsize, 1.0f, 1.0f, 1.0f, 1.0f, 0, NULL, false, FONT_DEFAULT);y += textsize;
+ DrawQ_String(x, y, bytesstring, 0, textsize, textsize, 1.0f, 1.0f, 1.0f, 1.0f, 0, NULL, false, FONT_DEFAULT);y += textsize;
}
/*
else
dpsnprintf(temp, sizeof(temp), "Downloading %s %3i%% (%i/%i) at %i bytes/s\n", cls.qw_downloadname, cls.qw_downloadpercent, cls.qw_downloadmemorycursize, cls.qw_downloadmemorymaxsize, cls.qw_downloadspeedrate);
len = (int)strlen(temp);
- x = (vid_conwidth.integer - DrawQ_TextWidth_Font(temp, len, true, FONT_INFOBAR) * size) / 2;
+ x = (vid_conwidth.integer - DrawQ_TextWidth(temp, len, size, size, true, FONT_INFOBAR)) / 2;
y = vid_conheight.integer - size - offset;
DrawQ_Fill(0, y, vid_conwidth.integer, size, 0, 0, 0, cls.signon == SIGNONS ? 0.5 : 1, 0);
- DrawQ_String_Font(x, y, temp, len, size, size, 1, 1, 1, 1, 0, NULL, true, FONT_INFOBAR);
+ DrawQ_String(x, y, temp, len, size, size, 1, 1, 1, 1, 0, NULL, true, FONT_INFOBAR);
return 8;
}
/*
float size = 8;
len = (int)strlen(scr_infobarstring);
- x = (vid_conwidth.integer - DrawQ_TextWidth_Font(scr_infobarstring, len, false, FONT_INFOBAR) * size) / 2;
+ x = (vid_conwidth.integer - DrawQ_TextWidth(scr_infobarstring, len, size, size, false, FONT_INFOBAR)) / 2;
y = vid_conheight.integer - size - offset;
DrawQ_Fill(0, y, vid_conwidth.integer, size, 0, 0, 0, cls.signon == SIGNONS ? 0.5 : 1, 0);
- DrawQ_String_Font(x, y, scr_infobarstring, len, size, size, 1, 1, 1, 1, 0, NULL, false, FONT_INFOBAR);
+ DrawQ_String(x, y, scr_infobarstring, len, size, size, 1, 1, 1, 1, 0, NULL, false, FONT_INFOBAR);
return 8;
}
if(addinfo)
{
len = (int)strlen(addinfo);
- x = (vid_conwidth.integer - DrawQ_TextWidth_Font(addinfo, len, true, FONT_INFOBAR) * size) / 2;
+ x = (vid_conwidth.integer - DrawQ_TextWidth(addinfo, len, size, size, true, FONT_INFOBAR)) / 2;
DrawQ_Fill(0, y - size, vid_conwidth.integer, size, 1, 1, 1, cls.signon == SIGNONS ? 0.8 : 1, 0);
- DrawQ_String_Font(x, y - size, addinfo, len, size, size, 0, 0, 0, 1, 0, NULL, true, FONT_INFOBAR);
+ DrawQ_String(x, y - size, addinfo, len, size, size, 0, 0, 0, 1, 0, NULL, true, FONT_INFOBAR);
}
for(i = 0; i != nDownloads; ++i)
else
dpsnprintf(temp, sizeof(temp), "Downloading %s ... %5.1f%% @ %.1f KiB/s\n", downinfo[i].filename, 100.0 * downinfo[i].progress, downinfo[i].speed / 1024.0);
len = (int)strlen(temp);
- x = (vid_conwidth.integer - DrawQ_TextWidth_Font(temp, len, true, FONT_INFOBAR) * size) / 2;
+ x = (vid_conwidth.integer - DrawQ_TextWidth(temp, len, size, size, true, FONT_INFOBAR)) / 2;
DrawQ_Fill(0, y + i * size, vid_conwidth.integer, size, 0, 0, 0, cls.signon == SIGNONS ? 0.5 : 1, 0);
- DrawQ_String_Font(x, y + i * size, temp, len, size, size, 1, 1, 1, 1, 0, NULL, true, FONT_INFOBAR);
+ DrawQ_String(x, y + i * size, temp, len, size, size, 1, 1, 1, 1, 0, NULL, true, FONT_INFOBAR);
}
Z_Free(downinfo);
if (scr_menuforcewhiledisconnected.integer && key_dest == key_game && cls.state == ca_disconnected)
{
if (framecounter >= 2)
- MR_ToggleMenu_f();
+ MR_ToggleMenu(1);
else
framecounter++;
}
while (string[i] && string[i] != '\n')
i++;
if (i - j > 0)
- DrawQ_String(0, y, string + j, i - j, 8, 8, 1, 1, 1, 1, 0, NULL, true);
+ DrawQ_String(0, y, string + j, i - j, 8, 8, 1, 1, 1, 1, 0, NULL, true, FONT_DEFAULT);
if (string[i] == '\n')
i++;
y += 8;
Cvar_RegisterVariable (&scr_conforcewhiledisconnected);
Cvar_RegisterVariable (&scr_menuforcewhiledisconnected);
Cvar_RegisterVariable (&scr_loadingscreen_background);
+ Cvar_RegisterVariable (&scr_loadingscreen_count);
+ Cvar_RegisterVariable (&scr_loadingscreen_barcolor);
+ Cvar_RegisterVariable (&scr_loadingscreen_barheight);
Cvar_RegisterVariable (&scr_showram);
Cvar_RegisterVariable (&scr_showturtle);
Cvar_RegisterVariable (&scr_showpause);
Cvar_RegisterVariable (&vid_pixelheight);
Cvar_RegisterVariable (&scr_screenshot_jpeg);
Cvar_RegisterVariable (&scr_screenshot_jpeg_quality);
+ Cvar_RegisterVariable (&scr_screenshot_png);
Cvar_RegisterVariable (&scr_screenshot_gammaboost);
Cvar_RegisterVariable (&scr_screenshot_hwgamma);
Cvar_RegisterVariable (&scr_screenshot_name_in_mapdir);
unsigned char *buffer2;
unsigned char *buffer3;
qboolean jpeg = (scr_screenshot_jpeg.integer != 0);
+ qboolean png = (scr_screenshot_png.integer != 0) && !jpeg;
if (Cmd_Argc() == 2)
{
strlcpy(filename, Cmd_Argv(1), sizeof(filename));
ext = FS_FileExtension(filename);
if (!strcasecmp(ext, "jpg"))
+ {
jpeg = true;
+ png = false;
+ }
else if (!strcasecmp(ext, "tga"))
+ {
+ jpeg = false;
+ png = false;
+ }
+ else if (!strcasecmp(ext, "png"))
+ {
jpeg = false;
+ png = true;
+ }
else
{
- Con_Printf("screenshot: supplied filename must end in .jpg or .tga\n");
+ Con_Printf("screenshot: supplied filename must end in .jpg or .tga or .png\n");
return;
}
}
// 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)))
+ 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)))
break;
if (shotnumber >= 1000000)
{
return;
}
- dpsnprintf(filename, sizeof(filename), "screenshots/%s%06d.%s", prefix_name, shotnumber, jpeg ? "jpg" : "tga");
+ dpsnprintf(filename, sizeof(filename), "screenshots/%s%06d.%s", prefix_name, shotnumber, jpeg ? "jpg" : png ? "png" : "tga");
}
buffer1 = (unsigned char *)Mem_Alloc(tempmempool, vid.width * vid.height * 3);
buffer2 = (unsigned char *)Mem_Alloc(tempmempool, vid.width * vid.height * 3);
buffer3 = (unsigned char *)Mem_Alloc(tempmempool, vid.width * vid.height * 3 + 18);
- if (SCR_ScreenShot (filename, buffer1, buffer2, buffer3, 0, 0, vid.width, vid.height, false, false, false, jpeg, true))
+ if (SCR_ScreenShot (filename, buffer1, buffer2, buffer3, 0, 0, vid.width, vid.height, false, false, false, jpeg, png, true))
Con_Printf("Wrote %s\n", filename);
else
+ {
Con_Printf("Unable to write %s\n", filename);
+ if(jpeg || png)
+ {
+ if(SCR_ScreenShot (filename, buffer1, buffer2, buffer3, 0, 0, vid.width, vid.height, false, false, false, false, false, true))
+ {
+ strlcpy(filename + strlen(filename) - 3, "tga", 4);
+ Con_Printf("Wrote %s\n", filename);
+ }
+ }
+ }
Mem_Free (buffer1);
Mem_Free (buffer2);
r_refdef.view.useperspective = true;
r_refdef.view.isoverlay = false;
- r_refdef.view.frustum_x = tan(90 * M_PI / 360.0);
- r_refdef.view.frustum_y = tan(90 * M_PI / 360.0);
+ r_refdef.view.frustum_x = 1; // tan(45 * M_PI / 180.0);
+ r_refdef.view.frustum_y = 1; // tan(45 * M_PI / 180.0);
buffer1 = (unsigned char *)Mem_Alloc(tempmempool, size * size * 3);
buffer2 = (unsigned char *)Mem_Alloc(tempmempool, size * size * 3);
R_Mesh_Start();
R_RenderView();
R_Mesh_Finish();
- SCR_ScreenShot(filename, buffer1, buffer2, buffer3, 0, vid.height - (r_refdef.view.y + r_refdef.view.height), size, size, envmapinfo[j].flipx, envmapinfo[j].flipy, envmapinfo[j].flipdiagonaly, false, false);
+ SCR_ScreenShot(filename, buffer1, buffer2, buffer3, 0, vid.height - (r_refdef.view.y + r_refdef.view.height), size, size, envmapinfo[j].flipx, envmapinfo[j].flipy, envmapinfo[j].flipdiagonaly, false, false, false);
}
Mem_Free (buffer1);
==============================================================================
*/
-qboolean SCR_ScreenShot(char *filename, unsigned char *buffer1, unsigned char *buffer2, unsigned char *buffer3, int x, int y, int width, int height, qboolean flipx, qboolean flipy, qboolean flipdiagonal, qboolean jpeg, qboolean gammacorrect)
+qboolean SCR_ScreenShot(char *filename, unsigned char *buffer1, unsigned char *buffer2, unsigned char *buffer3, int x, int y, int width, int height, qboolean flipx, qboolean flipy, qboolean flipdiagonal, qboolean jpeg, qboolean png, qboolean gammacorrect)
{
int indices[3] = {0,1,2};
qboolean ret;
if (jpeg)
ret = JPEG_SaveImage_preflipped (filename, width, height, buffer2);
+ else if (png)
+ ret = PNG_SaveImage_preflipped (filename, width, height, buffer2);
else
ret = Image_WriteTGABGR_preflipped (filename, width, height, buffer2, buffer3);
R_Mesh_Start();
- R_TimeReport_BeginFrame();
-
R_UpdateVariables();
// Quake uses clockwise winding, so these are swapped
buffer1 = (unsigned char *)Mem_Alloc(tempmempool, vid.width * vid.height * 3);
buffer2 = (unsigned char *)Mem_Alloc(tempmempool, vid.width * vid.height * 3);
buffer3 = (unsigned char *)Mem_Alloc(tempmempool, vid.width * vid.height * 3 + 18);
- SCR_ScreenShot(filename, buffer1, buffer2, buffer3, 0, 0, vid.width, vid.height, false, false, false, false, true);
+ SCR_ScreenShot(filename, buffer1, buffer2, buffer3, 0, 0, vid.width, vid.height, false, false, false, false, false, true);
Mem_Free(buffer1);
Mem_Free(buffer2);
Mem_Free(buffer3);
R_TimeReport("2d");
if (cls.signon == SIGNONS)
+ {
R_TimeReport_EndFrame();
+ R_TimeReport_BeginFrame();
+ }
DrawQ_Finish();
rtexture_t *loadingscreentexture = NULL;
static float loadingscreentexture_vertex3f[12];
static float loadingscreentexture_texcoord2f[8];
+static int loadingscreenpic_number = 0;
static void SCR_ClearLoadingScreenTexture(void)
{
loadingscreentexture_h = vid.height / (float) h;
}
- loadingscreentexture = R_LoadTexture2D(r_main_texturepool, "loadingscreentexture", w, h, NULL, TEXTYPE_BGRA, TEXF_FORCENEAREST | TEXF_CLAMP, NULL);
+ loadingscreentexture = R_LoadTexture2D(r_main_texturepool, "loadingscreentexture", w, h, NULL, TEXTYPE_COLORBUFFER, TEXF_FORCENEAREST | TEXF_CLAMP, NULL);
R_Mesh_CopyToTexture(loadingscreentexture, 0, 0, 0, 0, vid.width, vid.height);
loadingscreentexture_vertex3f[2] = loadingscreentexture_vertex3f[5] = loadingscreentexture_vertex3f[8] = loadingscreentexture_vertex3f[11] = 0;
SCR_PopLoadingScreen(redraw && !loadingscreenstack->prev);
}
-static float SCR_DrawLoadingStack_r(loadingscreenstack_t *s, float y)
+static float SCR_DrawLoadingStack_r(loadingscreenstack_t *s, float y, float size)
{
- float size = 8;
float x;
size_t len;
float total;
#if 0
if(s)
{
- total += SCR_DrawLoadingStack_r(s->prev, y);
+ total += SCR_DrawLoadingStack_r(s->prev, y, 8);
y -= total;
if(!s->prev || strcmp(s->msg, s->prev->msg))
{
len = strlen(s->msg);
- x = (vid_conwidth.integer - DrawQ_TextWidth_Font(s->msg, len, true, FONT_INFOBAR) * size) / 2;
+ x = (vid_conwidth.integer - DrawQ_TextWidth(s->msg, len, size, size, true, FONT_INFOBAR)) / 2;
y -= size;
DrawQ_Fill(0, y, vid_conwidth.integer, size, 0, 0, 0, 1, 0);
- DrawQ_String_Font(x, y, s->msg, len, size, size, 1, 1, 1, 1, 0, NULL, true, FONT_INFOBAR);
+ DrawQ_String(x, y, s->msg, len, size, size, 1, 1, 1, 1, 0, NULL, true, FONT_INFOBAR);
total += size;
}
}
if(s)
{
len = strlen(s->msg);
- x = (vid_conwidth.integer - DrawQ_TextWidth_Font(s->msg, len, true, FONT_INFOBAR) * size) / 2;
+ x = (vid_conwidth.integer - DrawQ_TextWidth(s->msg, len, size, size, true, FONT_INFOBAR)) / 2;
y -= size;
DrawQ_Fill(0, y, vid_conwidth.integer, size, 0, 0, 0, 1, 0);
- DrawQ_String_Font(x, y, s->msg, len, size, size, 1, 1, 1, 1, 0, NULL, true, FONT_INFOBAR);
+ DrawQ_String(x, y, s->msg, len, size, size, 1, 1, 1, 1, 0, NULL, true, FONT_INFOBAR);
total += size;
}
#endif
{
float verts[12];
float colors[16];
- int i;
- loadingscreenheight = SCR_DrawLoadingStack_r(loadingscreenstack, vid_conheight.integer);
+ loadingscreenheight = SCR_DrawLoadingStack_r(loadingscreenstack, vid_conheight.integer, scr_loadingscreen_barheight.value);
if(loadingscreenstack)
{
// height = 32; // sorry, using the actual one is ugly
R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1);
verts[2] = verts[5] = verts[8] = verts[11] = 0;
verts[0] = verts[9] = 0;
- verts[1] = verts[4] = vid_conheight.integer - 8;
+ verts[1] = verts[4] = vid_conheight.integer - scr_loadingscreen_barheight.value;
verts[3] = verts[6] = vid_conwidth.integer * loadingscreenstack->absolute_loading_amount_min;
verts[7] = verts[10] = vid_conheight.integer;
+
+#if _MSC_VER >= 1400
+#define sscanf sscanf_s
+#endif
+ // ^^^^^^^^^^ blue component
+ // ^^^^^^ bottom row
+ // ^^^^^^^^^^^^ alpha is always on
+ colors[0] = 0; colors[1] = 0; colors[2] = 0; colors[3] = 1;
+ colors[4] = 0; colors[5] = 0; colors[6] = 0; colors[7] = 1;
+ sscanf(scr_loadingscreen_barcolor.string, "%f %f %f", &colors[8], &colors[9], &colors[10]); colors[11] = 1;
+ sscanf(scr_loadingscreen_barcolor.string, "%f %f %f", &colors[12], &colors[13], &colors[14]); colors[15] = 1;
- for(i = 0; i < 16; ++i)
- colors[i] = (i % 4 == 3) ? 1 : (i >= 8 && i % 4 == 2) ? 1 : 0;
- // ^^^^^^^^^^ blue component
- // ^^^^^^ bottom row
- // ^^^^^^^^^^^^ alpha is always on
R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, polygonelement3s, 0, 0);
// make sure everything is cleared, including the progress indicator
R_Mesh_Start();
R_EntityMatrix(&identitymatrix);
// draw the loading plaque
- loadingscreenpic = Draw_CachePic ("gfx/loading");
+ loadingscreenpic = Draw_CachePic (loadingscreenpic_number ? va("gfx/loading%d", loadingscreenpic_number+1) : "gfx/loading");
x = (vid_conwidth.integer - loadingscreenpic->width)/2;
y = (vid_conheight.integer - loadingscreenpic->height)/2;
loadingscreenpic_vertex3f[2] = loadingscreenpic_vertex3f[5] = loadingscreenpic_vertex3f[8] = loadingscreenpic_vertex3f[11] = 0;
if(loadingscreentime == realtime)
clear |= loadingscreencleared;
+ if(loadingscreentime != realtime)
+ loadingscreenpic_number = rand() % (scr_loadingscreen_count.integer > 1 ? scr_loadingscreen_count.integer : 1);
+
if(clear)
SCR_ClearLoadingScreenTexture();
else if(loadingscreentime != realtime)
old_key_consoleactive = key_consoleactive;
key_dest = key_void;
key_consoleactive = false;
- Sys_SendKeyEvents();
+ Key_EventQueue_Block(); Sys_SendKeyEvents();
key_dest = old_key_dest;
key_consoleactive = old_key_consoleactive;
}