ref: a6ffb6a8ffefb4806f659ae05d730eaa6f486191
parent: 07d119a17d5ebc9245470fb3d16c40f31e6745e5
author: Konstantinn Bonnet <qu7uux@gmail.com>
date: Tue Oct 6 01:50:31 EDT 2015
fix writing pcx screenshots from the wrong data having this superfluous code sucks, but screenshots written with rio have tearing.
--- a/screen.c
+++ b/screen.c
@@ -45,6 +45,8 @@
qboolean block_drawing;
+static int writepcx;
+
void SCR_ScreenShot_f (void);
/*
@@ -503,134 +505,96 @@
==============================================================================
*/
-
-typedef struct
-{
- char manufacturer;
- char version;
- char encoding;
- char bits_per_pixel;
- unsigned short xmin,ymin,xmax,ymax;
- unsigned short hres,vres;
- unsigned char palette[48];
- char reserved;
- char color_planes;
- unsigned short bytes_per_line;
- unsigned short palette_type;
- char filler[58];
- unsigned char data; // unbounded
-} pcx_t;
+void
+SCR_ScreenShot_f(void)
+{
+ writepcx++;
+}
-/*
-==============
-WritePCXfile
-==============
-*/
-void WritePCXfile (char *filename, byte *data, int width, int height,
- int rowbytes, byte *palette)
+static void
+pcxout(char *path, byte *src, int dx, int dy, int xlen, byte *pal)
{
- int i, j, length;
- pcx_t *pcx;
- byte *pack;
-
- pcx = Hunk_TempAlloc (width*height*2+1000);
- if (pcx == nil)
- {
- Con_Printf("SCR_ScreenShot_f: not enough memory\n");
+ int i, j;
+ uchar *buf, *p;
+
+ if((buf = Hunk_TempAlloc(dx * dy * 2 + 1000)) == nil){
+ Con_Printf("writepcx: not enough memory\n");
return;
- }
-
- pcx->manufacturer = 0x0a; // PCX id
- pcx->version = 5; // 256 color
- pcx->encoding = 1; // uncompressed
- pcx->bits_per_pixel = 8; // 256 color
- pcx->xmin = 0;
- pcx->ymin = 0;
- pcx->xmax = LittleShort((short)(width-1));
- pcx->ymax = LittleShort((short)(height-1));
- pcx->hres = LittleShort((short)width);
- pcx->vres = LittleShort((short)height);
- memset(pcx->palette, 0, sizeof pcx->palette);
- pcx->color_planes = 1; // chunky image
- pcx->bytes_per_line = LittleShort((short)width);
- pcx->palette_type = LittleShort(2); // not a grey scale
- memset(pcx->filler, 0, sizeof pcx->filler);
+ }
+ p = buf;
-// pack the image
- pack = &pcx->data;
-
- for (i=0 ; i<height ; i++)
- {
- for (j=0 ; j<width ; j++)
- {
- if ( (*data & 0xc0) != 0xc0)
- *pack++ = *data++;
- else
- {
- *pack++ = 0xc1;
- *pack++ = *data++;
+ /* pcx header */
+ memset(p, 0, 128);
+ p[0] = 0x0a;
+ p[1] = 5; /* version: 24bit pcx */
+ p[2] = 1;
+ p[3] = 8; /* bits per pixel */
+ p[8] = dx - 1;
+ p[9] = dx - 1 >> 8;
+ p[10] = dy - 1;
+ p[11] = dy - 1 >> 8;
+ p[12] = dx; /* HDpi and VDpi */
+ p[13] = dx >> 8;
+ p[14] = dy;
+ p[15] = dy >> 8;
+ p[65] = 1; /* number of color planes */
+ p[66] = dx; /* scanline length */
+ p[67] = dx >> 8;
+ p[68] = 2; /* palette type: not-greyscale greyscale */
+
+ p = buf + 128;
+ for(i=0; i<dy; i++){
+ for(j=0; j<dx; j++){
+ if((*src & 0xc0) != 0xc0)
+ *p++ = *src++;
+ else{
+ *p++ = 0xc1;
+ *p++ = *src++;
}
}
-
- data += rowbytes - width;
+ src += xlen - dx;
}
-
-// write the palette
- *pack++ = 0x0c; // palette ID byte
- for (i=0 ; i<768 ; i++)
- *pack++ = *palette++;
-
-// write output file
- length = pack - (byte *)pcx;
- COM_WriteFile (filename, pcx, length);
+
+ /* palette */
+ *p++ = 0x0c;
+ for(i=0; i<3*256; i++)
+ *p++ = *pal++;
+
+ COM_WriteFile(path, buf, p - buf);
}
-
+static void
+dopcx(void)
+{
+ int i;
+ char pcxname[12], checkname[MAX_OSPATH];
-/*
-==================
-SCR_ScreenShot_f
-==================
-*/
-void SCR_ScreenShot_f (void)
-{
- int i;
- char pcxname[80];
- char checkname[MAX_OSPATH];
+ writepcx = 0;
-//
-// find a file name to save it to
-//
- strcpy(pcxname,"quake00.pcx");
-
- for (i=0 ; i<=99 ; i++)
- {
- pcxname[5] = i/10 + '0';
- pcxname[6] = i%10 + '0';
- sprint (checkname, "%s/%s", com_gamedir, pcxname);
+ /* find a file name to save it to */
+ strcpy(pcxname, "quake00.pcx");
+ for(i=0; i<100; i++){
+ pcxname[5] = i / 10 + '0';
+ pcxname[6] = i % 10 + '0';
+ sprint(checkname, "%s/%s", com_gamedir, pcxname);
if(access(checkname, AEXIST) == -1)
break;
- }
- if (i==100)
- {
- Con_Printf ("SCR_ScreenShot_f: Couldn't create a PCX file\n");
+ }
+ if(i == 100){
+ Con_Printf("dopcx: no free slots\n");
return;
}
-//
-// save the pcx file
-//
- D_EnableBackBufferAccess (); // enable direct drawing of console to back
- // buffer
+ /* save the pcx file */
+ D_EnableBackBufferAccess();
+ pcxout(pcxname, vid.buffer, vid.width, vid.height, vid.rowbytes,
+ host_basepal);
+ /* for adapters that can't stay mapped in for linear writes all the
+ * time */
+ D_DisableBackBufferAccess();
- WritePCXfile (pcxname, vid.buffer, vid.width, vid.height, vid.rowbytes,
- host_basepal);
-
- D_DisableBackBufferAccess (); // for adapters that can't stay mapped in
- // for linear writes all the time
-
- Con_Printf ("Wrote %s\n", pcxname);
+ Con_Printf("Wrote %s\n", pcxname);
}
@@ -924,6 +888,10 @@
}
V_UpdatePalette ();
+
+ /* needs to be done before vid.buffer is transformed in st3_fixup */
+ if(writepcx)
+ dopcx();
//
// update one of three areas