shithub: choc

Download patch

ref: 0229ae9cfd2e90f587c08280e17833fd7cb72303
parent: b81ba59d6649794cfba735d1ffa0e9458a6ee486
parent: 787ab13a1e7fb5054a082cd0278c125f925e6664
author: Simon Howard <[email protected]>
date: Wed Jul 15 19:48:22 EDT 2015

Merge pull request #580 from jmtd/aspect-ratio-screenshots

Write out aspect-corrected 1600x1200 PNGs

Doom's PCX screenshots are 320x200, which is in the wrong 16:10 aspect
ratio and doesn't match the 4:3 aspect ratio that the screen is 
supposed to be displayed at. Within the game we stretch the screen to
the correct aspect ratio, but screenshots are saved wrong.

When the user has made the choice to use PNG screenshots instead of 
PCX, they've already made the decision to break with Vanilla 
compatibility, so there's an opportunity to fix the aspect ratio. 
To correct aspect ratio losslessly it is necessary to scale up by 5x 
(horizontally) / 6x (vertically). However, PNG files have much better
compression than PCX so this isn't really an issue - a 1600x1200 PNG 
screenshot is actually smaller than a 320x200 PCX screenshot.

--- a/src/v_video.c
+++ b/src/v_video.c
@@ -719,7 +719,7 @@
 }
 
 void WritePNGfile(char *filename, byte *data,
-                  int width, int height,
+                  int inwidth, int inheight,
                   byte *palette)
 {
     png_structp ppng;
@@ -726,8 +726,14 @@
     png_infop pinfo;
     png_colorp pcolor;
     FILE *handle;
-    int i;
+    int i, j;
+    int width, height;
+    byte *rowbuf;
 
+    // scale up to accommodate aspect ratio correction
+    width = inwidth * 5;
+    height = inheight * 6;
+
     handle = fopen(filename, "wb");
     if (!handle)
     {
@@ -773,9 +779,26 @@
 
     png_write_info(ppng, pinfo);
 
-    for (i = 0; i < SCREENHEIGHT; i++)
+    rowbuf = malloc(width);
+
+    if (rowbuf)
     {
-        png_write_row(ppng, data + i*SCREENWIDTH);
+        for (i = 0; i < SCREENHEIGHT; i++)
+        {
+            // expand the row 5x
+            for (j = 0; j < SCREENWIDTH; j++)
+            {
+                memset(rowbuf + j * 5, *(data + i*SCREENWIDTH + j), 5);
+            }
+
+            // write the row 6 times
+            for (j = 0; j < 6; j++)
+            {
+                png_write_row(ppng, rowbuf);
+            }
+        }
+
+        free(rowbuf);
     }
 
     png_write_end(ppng, pinfo);