mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-13 00:24:12 +00:00
[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.
This commit is contained in:
parent
0880fab909
commit
ddfacf61ee
3 changed files with 175 additions and 170 deletions
|
@ -46,8 +46,6 @@ void SCR_SetFOV (float fov);
|
||||||
// control whether the 3d viewport is user-controlled or always fullscreen
|
// control whether the 3d viewport is user-controlled or always fullscreen
|
||||||
void SCR_SetFullscreen (qboolean fullscreen);
|
void SCR_SetFullscreen (qboolean fullscreen);
|
||||||
void SCR_SetBottomMargin (int lines);
|
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 struct cvar_s *hud_fps, *hud_time, *r_timegraph, *r_zgraph;
|
||||||
extern int scr_copytop;
|
extern int scr_copytop;
|
||||||
|
|
|
@ -479,152 +479,6 @@ SCR_DrawPause (void)
|
||||||
pic);
|
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
|
static void
|
||||||
viewsize_listener (void *data, const cvar_t *cvar)
|
viewsize_listener (void *data, const cvar_t *cvar)
|
||||||
{
|
{
|
||||||
|
|
|
@ -45,41 +45,180 @@
|
||||||
#include "qw/include/cl_parse.h"
|
#include "qw/include/cl_parse.h"
|
||||||
#include "qw/include/client.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;
|
int pcx_len;
|
||||||
pcx_t *pcx = 0;
|
pcx_t *pcx = 0;
|
||||||
tex_t *tex = 0;
|
tex_t *tex = cruch_snap (snap, RSSHOT_WIDTH, RSSHOT_HEIGHT);
|
||||||
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);
|
|
||||||
|
|
||||||
|
snap_pending = 0;
|
||||||
if (tex) {
|
if (tex) {
|
||||||
|
time_t now;
|
||||||
time (&now);
|
time (&now);
|
||||||
st = dstring_strdup (ctime (&now));
|
dstring_t *st = dstring_strdup (ctime (&now));
|
||||||
dstring_snip (st, strlen (st->str) - 1, 1);
|
dstring_snip (st, strlen (st->str) - 1, 1);
|
||||||
SCR_DrawStringToSnap (st->str, tex, tex->width - strlen (st->str) * 8,
|
snap_drawstring (st->str, tex, tex->width - strlen (st->str) * 8,
|
||||||
tex->height - 1);
|
tex->height - 1);
|
||||||
|
|
||||||
dstring_copystr (st, cls.servername->str);
|
dstring_copystr (st, cls.servername->str);
|
||||||
SCR_DrawStringToSnap (st->str, tex, tex->width - strlen (st->str) * 8,
|
snap_drawstring (st->str, tex, tex->width - strlen (st->str) * 8,
|
||||||
tex->height - 11);
|
tex->height - 11);
|
||||||
|
|
||||||
dstring_copystr (st, cl_name->string);
|
dstring_copystr (st, cl_name->string);
|
||||||
SCR_DrawStringToSnap (st->str, tex, tex->width - strlen (st->str) * 8,
|
snap_drawstring (st->str, tex, tex->width - strlen (st->str) * 8,
|
||||||
tex->height - 21);
|
tex->height - 21);
|
||||||
|
|
||||||
pcx = EncodePCX (tex->data, tex->width, tex->height, tex->width,
|
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);
|
free (tex);
|
||||||
}
|
}
|
||||||
if (pcx) {
|
if (pcx) {
|
||||||
|
@ -88,3 +227,17 @@ CL_RSShot_f (void)
|
||||||
Sys_Printf ("Sending shot to server...\n");
|
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);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue