diff --git a/include/QF/plugin/vid_render.h b/include/QF/plugin/vid_render.h index 478641a24..aa17f35ec 100644 --- a/include/QF/plugin/vid_render.h +++ b/include/QF/plugin/vid_render.h @@ -97,9 +97,6 @@ typedef struct vid_render_funcs_s { void (*Draw_SubPic) (int x, int y, qpic_t *pic, int srcx, int srcy, int width, int height); struct tex_s *(*SCR_CaptureBGR) (void); - struct tex_s *(*SCR_ScreenShot) (unsigned width, unsigned height); - void (*SCR_DrawStringToSnap) (const char *s, struct tex_s *tex, - int x, int y); void (*Fog_Update) (float density, float red, float green, float blue, float time); @@ -112,9 +109,7 @@ typedef struct vid_render_funcs_s { void (*R_LoadSkys) (const char *); void (*R_NewMap) (model_t *worldmodel, model_t **models, int num_models); void (*R_LineGraph) (int x, int y, int *h_vals, int count, int height); - void (*R_ViewChanged) (void); - void (*SCR_ScreenShot_f) (void); vid_model_funcs_t *model_funcs; } vid_render_funcs_t; diff --git a/include/QF/screen.h b/include/QF/screen.h index 4adf0a519..c58351d84 100644 --- a/include/QF/screen.h +++ b/include/QF/screen.h @@ -30,6 +30,7 @@ #define __QF_screen_h struct transform_s; +struct tex_s; void SCR_Init (void); void SCR_SetFOV (float fov); @@ -42,6 +43,8 @@ typedef void (*SCR_Func)(void); // scr_funcs is a null terminated array void SCR_UpdateScreen (struct transform_s *camera, double realtime, SCR_Func *scr_funcs); +void SCR_DrawStringToSnap (const char *s, struct tex_s *tex, int x, int y); +struct tex_s *SCR_SnapScreen (unsigned width, unsigned height); extern struct cvar_s *hud_fps, *hud_time; diff --git a/libs/video/renderer/gl/gl_screen.c b/libs/video/renderer/gl/gl_screen.c index 8e03bc5f9..3647b2c53 100644 --- a/libs/video/renderer/gl/gl_screen.c +++ b/libs/video/renderer/gl/gl_screen.c @@ -83,89 +83,6 @@ gl_SCR_CaptureBGR (void) return tex; } -tex_t * -gl_SCR_ScreenShot (unsigned width, unsigned height) -{ - unsigned char *src, *dest, *snap; - float fracw, frach; - int count, dex, dey, dx, dy, nx, r, g, b, x, y, w, h; - tex_t *tex; - - snap = Hunk_TempAlloc (0, vid.width * vid.height * 3); - - qfglReadPixels (0, 0, vid.width, vid.height, GL_RGB, GL_UNSIGNED_BYTE, - snap); - - w = (vid.width < width) ? vid.width : width; - h = (vid.height < height) ? vid.height : height; - - fracw = (float) vid.width / (float) w; - frach = (float) vid.height / (float) h; - - tex = malloc (sizeof (tex_t) + w * h); - tex->data = (byte *) (tex + 1); - if (!tex) - return 0; - - tex->width = w; - tex->height = h; - tex->palette = vid.palette; - - for (y = 0; y < h; y++) { - dest = tex->data + (w * y); - - for (x = 0; x < w; x++) { - r = g = b = 0; - - dx = x * fracw; - dex = (x + 1) * fracw; - if (dex == dx) - dex++; // at least one - dy = y * frach; - dey = (y + 1) * frach; - if (dey == dy) - dey++; // at least one - - count = 0; - for (; dy < dey; dy++) { - src = snap + (vid.width * 3 * dy) + dx * 3; - for (nx = dx; nx < dex; nx++) { - r += *src++; - g += *src++; - b += *src++; - count++; - } - } - r /= count; - g /= count; - b /= count; - *dest++ = MipColor (r, g, b); - } - } - - return tex; -} - -void -gl_SCR_ScreenShot_f (void) -{ - dstring_t *pcxname = dstring_new (); - - // find a file name to save it to - if (!QFS_NextFilename (pcxname, - va (0, "%s/qf", qfs_gamedir->dir.shots), ".tga")) { - Sys_Printf ("SCR_ScreenShot_f: Couldn't create a TGA file\n"); - } else { - tex_t *tex; - - tex = gl_SCR_CaptureBGR (); - WriteTGAfile (pcxname->str, tex->data, tex->width, tex->height); - free (tex); - Sys_Printf ("Wrote %s/%s\n", qfs_userpath, pcxname->str); - } - dstring_delete (pcxname); -} - static void SCR_TileClear (void) { diff --git a/libs/video/renderer/glsl/glsl_screen.c b/libs/video/renderer/glsl/glsl_screen.c index a25425f02..ff110f5fa 100644 --- a/libs/video/renderer/glsl/glsl_screen.c +++ b/libs/video/renderer/glsl/glsl_screen.c @@ -219,29 +219,3 @@ glsl_SCR_CaptureBGR (void) } return tex; } - -__attribute__((const)) tex_t * -glsl_SCR_ScreenShot (unsigned width, unsigned height) -{ - return 0; -} - -void -glsl_SCR_ScreenShot_f (void) -{ - dstring_t *name = dstring_new (); - - // find a file name to save it to - if (!QFS_NextFilename (name, va (0, "%s/qf", - qfs_gamedir->dir.shots), ".png")) { - Sys_Printf ("SCR_ScreenShot_f: Couldn't create a PNG file\n"); - } else { - tex_t *tex; - - tex = glsl_SCR_CaptureBGR (); - WritePNGqfs (name->str, tex->data, tex->width, tex->height); - free (tex); - Sys_Printf ("Wrote %s/%s\n", qfs_userpath, name->str); - } - dstring_delete (name); -} diff --git a/libs/video/renderer/r_screen.c b/libs/video/renderer/r_screen.c index 992822f5f..740b97640 100644 --- a/libs/video/renderer/r_screen.c +++ b/libs/video/renderer/r_screen.c @@ -38,11 +38,15 @@ #include "QF/cmd.h" #include "QF/cvar.h" #include "QF/draw.h" +#include "QF/dstring.h" #include "QF/image.h" +#include "QF/png.h" #include "QF/pcx.h" +#include "QF/quakefs.h" #include "QF/render.h" #include "QF/screen.h" #include "QF/sys.h" +#include "QF/va.h" #include "QF/scene/transform.h" #include "QF/ui/view.h" @@ -185,7 +189,21 @@ SCR_SetFOV (float fov) static void ScreenShot_f (void) { - r_funcs->SCR_ScreenShot_f (); + dstring_t *name = dstring_new (); + + // find a file name to save it to + if (!QFS_NextFilename (name, va (0, "%s/qf", + qfs_gamedir->dir.shots), ".png")) { + Sys_Printf ("SCR_ScreenShot_f: Couldn't create a PNG file\n"); + } else { + tex_t *tex; + + tex = r_funcs->SCR_CaptureBGR (); + WritePNGqfs (name->str, tex->data, tex->width, tex->height); + free (tex); + Sys_Printf ("Wrote %s/%s\n", qfs_userpath, name->str); + } + dstring_delete (name); } /* @@ -347,12 +365,74 @@ SCR_DrawStringToSnap (const char *s, tex_t *tex, int x, int y) } } +tex_t * +SCR_SnapScreen (unsigned width, unsigned height) +{ + byte *src, *dest; + float fracw, frach; + unsigned count, dex, dey, dx, dy, nx, r, g, b, x, y, w, h; + tex_t *tex; + + tex_t *snap = r_funcs->SCR_CaptureBGR (); + + //FIXME casts + w = ((unsigned)snap->width < width) ? (unsigned)snap->width : width; + h = ((unsigned)snap->height < height) ? (unsigned)snap->height : height; + + fracw = (float) snap->width / (float) w; + frach = (float) snap->height / (float) h; + + tex = malloc (sizeof (tex_t) + w * h); + tex->data = (byte *) (tex + 1); + if (!tex) + return 0; + + tex->width = w; + tex->height = h; + tex->palette = r_data->vid->palette; + + for (y = 0; y < h; y++) { + dest = tex->data + (w * y); + + for (x = 0; x < w; x++) { + r = g = b = 0; + + dx = x * fracw; + dex = (x + 1) * fracw; + if (dex == dx) + dex++; // at least one + dy = y * frach; + dey = (y + 1) * frach; + if (dey == dy) + dey++; // at least one + + count = 0; + for (; dy < dey; dy++) { + src = snap->data + (snap->width * 3 * dy) + dx * 3; + for (nx = dx; nx < dex; nx++) { + b += *src++; + g += *src++; + r += *src++; + count++; + } + } + r /= count; + g /= count; + b /= count; + *dest++ = MipColor (r, g, b); + } + } + free (snap); + + return tex; +} + void SCR_Init (void) { // register our commands Cmd_AddCommand ("screenshot", ScreenShot_f, "Take a screenshot, " - "saves as qfxxx.pcx in the current directory"); + "saves as qfxxxx.png in the QF directory"); Cmd_AddCommand ("sizeup", SCR_SizeUp_f, "Increases the screen size"); Cmd_AddCommand ("sizedown", SCR_SizeDown_f, "Decreases the screen size"); diff --git a/libs/video/renderer/sw/screen.c b/libs/video/renderer/sw/screen.c index 3e5b288d6..27a3741d1 100644 --- a/libs/video/renderer/sw/screen.c +++ b/libs/video/renderer/sw/screen.c @@ -85,88 +85,6 @@ SCR_CaptureBGR (void) return tex; } -tex_t * -SCR_ScreenShot (unsigned width, unsigned height) -{ - unsigned char *src, *dest; - float fracw, frach; - int count, dex, dey, dx, dy, nx, r, g, b, x, y, w, h; - tex_t *tex; - - w = (vid.width < width) ? vid.width : width; - h = (vid.height < height) ? vid.height : height; - - fracw = (float) vid.width / (float) w; - frach = (float) vid.height / (float) h; - - tex = malloc (sizeof (tex_t) + w * h); - tex->data = (byte *) (tex + 1); - if (!tex) - return 0; - - tex->width = w; - tex->height = h; - tex->palette = vid.palette; - - for (y = 0; y < h; y++) { - dest = tex->data + (w * (h - y - 1)); - - for (x = 0; x < w; x++) { - r = g = b = 0; - - dx = x * fracw; - dex = (x + 1) * fracw; - if (dex == dx) - dex++; // at least one - dy = y * frach; - dey = (y + 1) * frach; - if (dey == dy) - dey++; // at least one - - count = 0; - for (; dy < dey; dy++) { - src = ((byte*)vid.buffer) + (vid.rowbytes * dy) + dx; - for (nx = dx; nx < dex; nx++) { - r += vid.basepal[*src * 3]; - g += vid.basepal[*src * 3 + 1]; - b += vid.basepal[*src * 3 + 2]; - src++; - count++; - } - } - r /= count; - g /= count; - b /= count; - *dest++ = MipColor (r, g, b); - } - } - - return tex; -} - -void -SCR_ScreenShot_f (void) -{ - dstring_t *pcxname = dstring_new (); - pcx_t *pcx; - int pcx_len; - - // find a file name to save it to - if (!QFS_NextFilename (pcxname, - va (0, "%s/qf", qfs_gamedir->dir.shots), ".pcx")) { - Sys_Printf ("SCR_ScreenShot_f: Couldn't create a PCX"); - } else { - // save the pcx file - pcx = EncodePCX (vid.buffer, vid.width, vid.height, vid.rowbytes, - vid.basepal, false, &pcx_len); - QFS_WriteFile (pcxname->str, pcx, pcx_len); - - - Sys_Printf ("Wrote %s/%s\n", qfs_userpath, pcxname->str); - } - dstring_delete (pcxname); -} - void R_RenderFrame (SCR_Func *scr_funcs) { diff --git a/libs/video/renderer/sw32/screen.c b/libs/video/renderer/sw32/screen.c index 4a77aac77..072c88182 100644 --- a/libs/video/renderer/sw32/screen.c +++ b/libs/video/renderer/sw32/screen.c @@ -88,48 +88,6 @@ sw32_SCR_CaptureBGR (void) return tex; } -__attribute__((const)) tex_t * -sw32_SCR_ScreenShot (unsigned width, unsigned height) -{ - return 0; -} - -void -sw32_SCR_ScreenShot_f (void) -{ - dstring_t *pcxname = dstring_new (); - pcx_t *pcx = 0; - int pcx_len; - - // find a file name to save it to - if (!QFS_NextFilename (pcxname, va (0, "%s/qf", - qfs_gamedir->dir.shots), ".pcx")) { - Sys_Printf ("SCR_ScreenShot_f: Couldn't create a PCX"); - } else { - // save the pcx file - switch(sw32_ctx->pixbytes) { - case 1: - pcx = EncodePCX (vid.buffer, vid.width, vid.height, vid.rowbytes, - vid.basepal, false, &pcx_len); - break; - case 2: - Sys_Printf("SCR_ScreenShot_f: FIXME - add 16bit support\n"); - break; - case 4: - Sys_Printf("SCR_ScreenShot_f: FIXME - add 32bit support\n"); - break; - default: - Sys_Error("SCR_ScreenShot_f: unsupported r_pixbytes %i", sw32_ctx->pixbytes); - } - - if (pcx) { - QFS_WriteFile (pcxname->str, pcx, pcx_len); - Sys_Printf ("Wrote %s/%s\n", qfs_userpath, pcxname->str); - } - } - dstring_delete (pcxname); -} - void sw32_R_RenderFrame (SCR_Func *scr_funcs) { diff --git a/libs/video/renderer/vid_render_gl.c b/libs/video/renderer/vid_render_gl.c index ad2e5c272..c68cd8c9e 100644 --- a/libs/video/renderer/vid_render_gl.c +++ b/libs/video/renderer/vid_render_gl.c @@ -132,8 +132,6 @@ vid_render_funcs_t gl_vid_render_funcs = { gl_Draw_SubPic, gl_SCR_CaptureBGR, - gl_SCR_ScreenShot, - SCR_DrawStringToSnap, gl_Fog_Update, gl_Fog_ParseWorldspawn, @@ -146,7 +144,6 @@ vid_render_funcs_t gl_vid_render_funcs = { gl_R_NewMap, gl_R_LineGraph, gl_R_ViewChanged, - gl_SCR_ScreenShot_f, &model_funcs }; diff --git a/libs/video/renderer/vid_render_glsl.c b/libs/video/renderer/vid_render_glsl.c index a0978a685..2ca14d425 100644 --- a/libs/video/renderer/vid_render_glsl.c +++ b/libs/video/renderer/vid_render_glsl.c @@ -131,8 +131,6 @@ vid_render_funcs_t glsl_vid_render_funcs = { glsl_Draw_SubPic, glsl_SCR_CaptureBGR, - glsl_SCR_ScreenShot, - SCR_DrawStringToSnap, glsl_Fog_Update, glsl_Fog_ParseWorldspawn, @@ -145,7 +143,6 @@ vid_render_funcs_t glsl_vid_render_funcs = { glsl_R_NewMap, glsl_R_LineGraph, glsl_R_ViewChanged, - glsl_SCR_ScreenShot_f, &model_funcs }; diff --git a/libs/video/renderer/vid_render_sw.c b/libs/video/renderer/vid_render_sw.c index 02ba975b7..9ad7939ec 100644 --- a/libs/video/renderer/vid_render_sw.c +++ b/libs/video/renderer/vid_render_sw.c @@ -128,8 +128,6 @@ vid_render_funcs_t sw_vid_render_funcs = { Draw_SubPic, SCR_CaptureBGR, - SCR_ScreenShot, - SCR_DrawStringToSnap, 0, 0, @@ -142,7 +140,6 @@ vid_render_funcs_t sw_vid_render_funcs = { R_NewMap, R_LineGraph, R_ViewChanged, - SCR_ScreenShot_f, &model_funcs }; diff --git a/libs/video/renderer/vid_render_sw32.c b/libs/video/renderer/vid_render_sw32.c index 0fe8469fb..4f417d840 100644 --- a/libs/video/renderer/vid_render_sw32.c +++ b/libs/video/renderer/vid_render_sw32.c @@ -133,8 +133,6 @@ vid_render_funcs_t sw32_vid_render_funcs = { sw32_Draw_SubPic, sw32_SCR_CaptureBGR, - sw32_SCR_ScreenShot, - SCR_DrawStringToSnap, 0, 0, @@ -147,7 +145,6 @@ vid_render_funcs_t sw32_vid_render_funcs = { sw32_R_NewMap, sw32_R_LineGraph, sw32_R_ViewChanged, - sw32_SCR_ScreenShot_f, &model_funcs }; diff --git a/libs/video/renderer/vid_render_vulkan.c b/libs/video/renderer/vid_render_vulkan.c index d72e2da86..72e6caa5e 100644 --- a/libs/video/renderer/vid_render_vulkan.c +++ b/libs/video/renderer/vid_render_vulkan.c @@ -70,18 +70,6 @@ static vulkan_ctx_t *vulkan_ctx; -static tex_t * -vulkan_SCR_CaptureBGR (void) -{ - return 0; -} - -static tex_t * -vulkan_SCR_ScreenShot (unsigned width, unsigned height) -{ - return 0; -} - static void vulkan_Fog_Update (float density, float red, float green, float blue, float time) @@ -442,14 +430,16 @@ capture_screenshot (const byte *data, int width, int height) dstring_delete (name); } -static void -vulkan_SCR_ScreenShot_f (void) +static tex_t * +vulkan_SCR_CaptureBGR (void) { if (!vulkan_ctx->capture) { - Sys_Printf ("Screenshot not supported\n"); - return; + Sys_Printf ("Capture not supported\n"); + return 0; } vulkan_ctx->capture_callback = capture_screenshot; + //FIXME async process + return 0; } static void @@ -662,8 +652,6 @@ vid_render_funcs_t vulkan_vid_render_funcs = { vulkan_Draw_SubPic, vulkan_SCR_CaptureBGR, - vulkan_SCR_ScreenShot, - SCR_DrawStringToSnap, vulkan_Fog_Update, vulkan_Fog_ParseWorldspawn, @@ -676,7 +664,6 @@ vid_render_funcs_t vulkan_vid_render_funcs = { vulkan_R_NewMap, vulkan_R_LineGraph, vulkan_R_ViewChanged, - vulkan_SCR_ScreenShot_f, &model_funcs }; diff --git a/qw/source/cl_rss.c b/qw/source/cl_rss.c index bb4cbd993..ad519418a 100644 --- a/qw/source/cl_rss.c +++ b/qw/source/cl_rss.c @@ -61,25 +61,22 @@ CL_RSShot_f (void) Sys_Printf ("Remote screen shot requested.\n"); - tex = r_funcs->SCR_ScreenShot (RSSHOT_WIDTH, RSSHOT_HEIGHT); + tex = SCR_SnapScreen (RSSHOT_WIDTH, RSSHOT_HEIGHT); if (tex) { time (&now); st = dstring_strdup (ctime (&now)); dstring_snip (st, strlen (st->str) - 1, 1); - r_funcs->SCR_DrawStringToSnap (st->str, tex, - tex->width - strlen (st->str) * 8, - tex->height - 1); + SCR_DrawStringToSnap (st->str, tex, tex->width - strlen (st->str) * 8, + tex->height - 1); dstring_copystr (st, cls.servername->str); - r_funcs->SCR_DrawStringToSnap (st->str, tex, - tex->width - strlen (st->str) * 8, - tex->height - 11); + SCR_DrawStringToSnap (st->str, tex, tex->width - strlen (st->str) * 8, + tex->height - 11); dstring_copystr (st, cl_name->string); - r_funcs->SCR_DrawStringToSnap (st->str, tex, - tex->width - strlen (st->str) * 8, - tex->height - 21); + SCR_DrawStringToSnap (st->str, tex, tex->width - strlen (st->str) * 8, + tex->height - 21); pcx = EncodePCX (tex->data, tex->width, tex->height, tex->width, r_data->vid->basepal, true, &pcx_len);