From ddfacf61ee613849c1e2391d30e1d2bf8898d80a Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 1 Apr 2022 02:04:24 +0900 Subject: [PATCH] [qw] Get remote screen shots working again Probably better than they ever have, really, since I think they were broken for one renderer or another. --- include/QF/screen.h | 2 - libs/video/renderer/r_screen.c | 146 ------------------------ qw/source/cl_rss.c | 197 +++++++++++++++++++++++++++++---- 3 files changed, 175 insertions(+), 170 deletions(-) diff --git a/include/QF/screen.h b/include/QF/screen.h index 11a591f87..10e0176e1 100644 --- a/include/QF/screen.h +++ b/include/QF/screen.h @@ -46,8 +46,6 @@ void SCR_SetFOV (float fov); // control whether the 3d viewport is user-controlled or always fullscreen void SCR_SetFullscreen (qboolean fullscreen); void SCR_SetBottomMargin (int lines); -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, *r_timegraph, *r_zgraph; extern int scr_copytop; diff --git a/libs/video/renderer/r_screen.c b/libs/video/renderer/r_screen.c index f07a51fd7..86608c069 100644 --- a/libs/video/renderer/r_screen.c +++ b/libs/video/renderer/r_screen.c @@ -479,152 +479,6 @@ SCR_DrawPause (void) pic); } -/* - Find closest color in the palette for named color -*/ -#if 0 -static int -MipColor (int r, int g, int b) -{ - float bestdist, dist; - int r1, g1, b1, i; - int best = 0; - static int lastbest; - static int lr = -1, lg = -1, lb = -1; - - if (r == lr && g == lg && b == lb) - return lastbest; - - bestdist = 256 * 256 * 3; - - for (i = 0; i < 256; i++) { - int j; - j = i * 3; - r1 = r_data->vid->palette[j] - r; - g1 = r_data->vid->palette[j + 1] - g; - b1 = r_data->vid->palette[j + 2] - b; - dist = r1 * r1 + g1 * g1 + b1 * b1; - if (dist < bestdist) { - bestdist = dist; - best = i; - } - } - lr = r; - lg = g; - lb = b; - lastbest = best; - return best; -} -#endif - -// in draw.c - -static void -SCR_DrawCharToSnap (int num, byte *dest, int width) -{ - byte *source; - int col, row, drawline, x; - - row = num >> 4; - col = num & 15; - source = draw_chars + (row << 10) + (col << 3); - - drawline = 8; - - while (drawline--) { - for (x = 0; x < 8; x++) - if (source[x]) - dest[x] = source[x]; - else - dest[x] = 98; - source += 128; - dest -= width; - } - -} - -void -SCR_DrawStringToSnap (const char *s, tex_t *tex, int x, int y) -{ - byte *dest; - byte *buf = tex->data; - const unsigned char *p; - int width = tex->width; - - dest = buf + ((y * width) + x); - - p = (const unsigned char *) s; - while (*p) { - SCR_DrawCharToSnap (*p++, dest, width); - dest += 8; - } -} - -tex_t * -SCR_SnapScreen (unsigned width, unsigned height) -{ - return 0; -#if 0 - 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; -#endif -} - static void viewsize_listener (void *data, const cvar_t *cvar) { diff --git a/qw/source/cl_rss.c b/qw/source/cl_rss.c index ad519418a..b5974ba53 100644 --- a/qw/source/cl_rss.c +++ b/qw/source/cl_rss.c @@ -45,41 +45,180 @@ #include "qw/include/cl_parse.h" #include "qw/include/client.h" -void -CL_RSShot_f (void) +/* + Find closest color in the palette for named color +*/ +static int +rgb_palette (int r, int g, int b, int bgr) +{ + float bestdist, dist; + int r1, g1, b1, i; + int best = 0; + static int lastbest; + static int lr = -1, lg = -1, lb = -1; + + if (bgr) { + int t = r; + r = b; + b = t; + } + + if (r == lr && g == lg && b == lb) + return lastbest; + + bestdist = 256 * 256 * 3; + + for (i = 0; i < 256; i++) { + int j; + j = i * 3; + r1 = r_data->vid->palette[j] - r; + g1 = r_data->vid->palette[j + 1] - g; + b1 = r_data->vid->palette[j + 2] - b; + dist = r1 * r1 + g1 * g1 + b1 * b1; + if (dist < bestdist) { + bestdist = dist; + best = i; + } + } + lr = r; + lg = g; + lb = b; + lastbest = best; + return best; +} + +static void +snap_drawchar (int num, byte *dest, int width) +{ + byte *source; + int col, row, drawline, x; + + row = num >> 4; + col = num & 15; + source = draw_chars + (row << 10) + (col << 3); + + drawline = 8; + + while (drawline--) { + for (x = 0; x < 8; x++) + if (source[x]) + dest[x] = source[x]; + else + dest[x] = 98; + source += 128; + dest -= width; + } + +} + +static void +snap_drawstring (const char *s, tex_t *tex, int x, int y) +{ + byte *dest; + byte *buf = tex->data; + const byte *p; + int width = tex->width; + + dest = buf + ((y * width) + x); + + p = (const byte *) s; + while (*p) { + snap_drawchar (*p++, dest, width); + dest += 8; + } +} + +static tex_t * +cruch_snap (tex_t *snap, 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; + + //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->flagbits = 0; + tex->loaded = 1; + tex->flipped = snap->flipped; + 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++) { + r += *src++; + g += *src++; + b += *src++; + count++; + } + } + r /= count; + g /= count; + b /= count; + *dest++ = rgb_palette (r, g, b, snap->bgr); + } + } + free (snap); + + return tex; +} + +static int snap_pending; + +static void +snap_capture (tex_t *snap, void *data) { - dstring_t *st; int pcx_len; pcx_t *pcx = 0; - tex_t *tex = 0; - time_t now; - - if (CL_IsUploading ()) - return; // already one pending - if (cls.state < ca_onserver) - return; // must be connected - - Sys_Printf ("Remote screen shot requested.\n"); - - tex = SCR_SnapScreen (RSSHOT_WIDTH, RSSHOT_HEIGHT); + tex_t *tex = cruch_snap (snap, RSSHOT_WIDTH, RSSHOT_HEIGHT); + snap_pending = 0; if (tex) { + time_t now; time (&now); - st = dstring_strdup (ctime (&now)); + dstring_t *st = dstring_strdup (ctime (&now)); dstring_snip (st, strlen (st->str) - 1, 1); - SCR_DrawStringToSnap (st->str, tex, tex->width - strlen (st->str) * 8, - tex->height - 1); + snap_drawstring (st->str, tex, tex->width - strlen (st->str) * 8, + tex->height - 1); dstring_copystr (st, cls.servername->str); - SCR_DrawStringToSnap (st->str, tex, tex->width - strlen (st->str) * 8, - tex->height - 11); + snap_drawstring (st->str, tex, tex->width - strlen (st->str) * 8, + tex->height - 11); dstring_copystr (st, cl_name->string); - SCR_DrawStringToSnap (st->str, tex, tex->width - strlen (st->str) * 8, - tex->height - 21); + snap_drawstring (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); + r_data->vid->basepal, tex->flipped, &pcx_len); free (tex); } if (pcx) { @@ -88,3 +227,17 @@ CL_RSShot_f (void) Sys_Printf ("Sending shot to server...\n"); } } + +void +CL_RSShot_f (void) +{ + if (snap_pending || CL_IsUploading ()) + return; // already one pending + if (cls.state < ca_onserver) + return; // must be connected + + Sys_Printf ("Remote screen shot requested.\n"); + + snap_pending = 1; + r_funcs->capture_screen (snap_capture, 0); +}