shithub: choc

Download patch

ref: 07afb7749ff807118431ea356ab56364ef8cfee8
parent: 892074ce611d430d53014ace9b906dbfcb2cd798
author: Fabian Greffrath <fabian@greffrath.com>
date: Mon May 2 18:42:26 EDT 2016

video: depend on SDL_Image for taking PNG screenshots

Remove any libpbg-specific code, let SDL_Image handle this for us.

For now, this uses a slow software-scaling routine for up-scaling the
original 320x200 RGBA buffer up to the desired 1600x1200 dimensions.
In the future, we might want to fall back to using the
hardware-accelerated texture-based approach of the main rendering
stack (though this may seem like an overkill here).

However, it might be easier to take screenshots in the actual screen
dimensions with this approach (though I somehow remember that we
decided on 1600x1200 being the ideal solution that we should stay
with?).

--- a/configure.ac
+++ b/configure.ac
@@ -37,6 +37,7 @@
 PKG_CHECK_MODULES(SDL, [sdl2 >= 2.0.1])
 PKG_CHECK_MODULES(SDLMIXER, [SDL2_mixer >= 2.0.0])
 PKG_CHECK_MODULES(SDLNET, [SDL2_net >= 2.0.0])
+PKG_CHECK_MODULES(SDLIMAGE, [SDL2_image >= 2.0.0])
 
 # Check for libsamplerate.
 AC_ARG_WITH([libsamplerate],
@@ -56,28 +57,10 @@
     ])
 ])
 
-# Check for libpng.
-AC_ARG_WITH([libpng],
-AS_HELP_STRING([--without-libpng],
-    [Build without libpng @<:@default=check@:>@]),
-[],
-[
-    [with_libpng=check]
-])
-AS_IF([test "x$with_libpng" != xno], [
-    PKG_CHECK_MODULES(PNG, libpng >= 1.6.10, [
-        AC_DEFINE([HAVE_LIBPNG], [1], [libpng installed])
-    ], [
-        AS_IF([test "x$with_libpng" != xcheck], [AC_MSG_FAILURE(
-            [--with-libpng was given, but test for libpng failed])
-        ])
-    ])
-])
-
 # TODO: We currently link everything against libraries that don't need it.
 # Use the specific library CFLAGS/LIBS variables instead of setting them here.
-CFLAGS="$CFLAGS $SDL_CFLAGS ${SAMPLERATE_CFLAGS:-} ${PNG_CFLAGS:-}"
-LDFLAGS="$LDFLAGS $SDL_LIBS ${SAMPLERATE_LIBS:-} ${PNG_LIBS:-}"
+CFLAGS="$CFLAGS $SDL_CFLAGS ${SAMPLERATE_CFLAGS:-}"
+LDFLAGS="$LDFLAGS $SDL_LIBS ${SAMPLERATE_LIBS:-}"
 AC_CHECK_LIB(m, log)
 
 AC_CHECK_HEADERS([linux/kd.h dev/isa/spkrio.h dev/speaker/speaker.h])
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -21,7 +21,8 @@
 AM_CFLAGS = -I$(top_srcdir)/textscreen            \
             -I$(top_srcdir)/opl                   \
             -I$(top_srcdir)/pcsound               \
-            @SDLMIXER_CFLAGS@ @SDLNET_CFLAGS@
+            @SDLMIXER_CFLAGS@ @SDLNET_CFLAGS@     \
+            @SDLIMAGE_CFLAGS@
 
 # Common source files used by absolutely everything:
 
@@ -151,7 +152,8 @@
                @LDFLAGS@                                   \
                @SDL_LIBS@                                  \
                @SDLMIXER_LIBS@                             \
-               @SDLNET_LIBS@
+               @SDLNET_LIBS@                               \
+               @SDLIMAGE_LIBS@
 
 if HAVE_WINDRES
 @PROGRAM_PREFIX@doom_SOURCES=$(SOURCE_FILES_WITH_DEH) resource.rc
--- a/src/i_video.c
+++ b/src/i_video.c
@@ -18,6 +18,7 @@
 
 
 #include "SDL.h"
+#include "SDL_image.h"
 
 #ifdef _WIN32
 #define WIN32_LEAN_AND_MEAN
@@ -1195,4 +1196,21 @@
     M_BindStringVariable("window_position",        &window_position);
     M_BindIntVariable("usegamma",                  &usegamma);
     M_BindIntVariable("png_screenshots",           &png_screenshots);
+}
+
+void I_SavePNGScreenshot (char *filename)
+{
+    const int width = 1600, height = 1200;
+    SDL_Surface *shotbuffer;
+
+    shotbuffer = SDL_CreateRGBSurface(0, width, height, 32,
+                                      0x00ff0000,
+                                      0x0000ff00,
+                                      0x000000ff,
+                                      0xff000000);
+
+    SDL_BlitScaled(rgbabuffer, NULL, shotbuffer, NULL);
+    IMG_SavePNG(shotbuffer, filename);
+
+    SDL_FreeSurface(shotbuffer);
 }
--- a/src/i_video.h
+++ b/src/i_video.h
@@ -82,6 +82,8 @@
 
 void I_EnableLoadingDisk(int xoffs, int yoffs);
 
+void I_SavePNGScreenshot (char *filename);
+
 extern char *video_driver;
 extern boolean screenvisible;
 
--- a/src/setup/display.c
+++ b/src/setup/display.c
@@ -246,11 +246,9 @@
                                       &show_diskicon));
     }
 
-#ifdef HAVE_LIBPNG
     TXT_AddWidget(window,
                   TXT_NewCheckBox("Save screenshots in PNG format",
                                   &png_screenshots));
-#endif
 
     TXT_SignalConnect(ar_checkbox, "changed", GenerateModesTable, modes_table);
 }
--- a/src/v_video.c
+++ b/src/v_video.c
@@ -38,9 +38,6 @@
 #include "z_zone.h"
 
 #include "config.h"
-#ifdef HAVE_LIBPNG
-#include <png.h>
-#endif
 
 // TODO: There are separate RANGECHECK defines for different games, but this
 // is common code. Fix this.
@@ -704,111 +701,7 @@
     Z_Free (pcx);
 }
 
-#ifdef HAVE_LIBPNG
 //
-// WritePNGfile
-//
-
-static void error_fn(png_structp p, png_const_charp s)
-{
-    printf("libpng error: %s\n", s);
-}
-
-static void warning_fn(png_structp p, png_const_charp s)
-{
-    printf("libpng warning: %s\n", s);
-}
-
-void WritePNGfile(char *filename, byte *data,
-                  int inwidth, int inheight,
-                  byte *palette)
-{
-    png_structp ppng;
-    png_infop pinfo;
-    png_colorp pcolor;
-    FILE *handle;
-    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)
-    {
-        return;
-    }
-
-    ppng = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,
-                                   error_fn, warning_fn);
-    if (!ppng)
-    {
-        return;
-    }
-
-    pinfo = png_create_info_struct(ppng);
-    if (!pinfo)
-    {
-        png_destroy_write_struct(&ppng, NULL);
-        return;
-    }
-
-    png_init_io(ppng, handle);
-
-    png_set_IHDR(ppng, pinfo, width, height,
-                 8, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,
-                 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
-
-    pcolor = malloc(sizeof(*pcolor) * 256);
-    if (!pcolor)
-    {
-        png_destroy_write_struct(&ppng, &pinfo);
-        return;
-    }
-
-    for (i = 0; i < 256; i++)
-    {
-        pcolor[i].red   = *(palette + 3 * i);
-        pcolor[i].green = *(palette + 3 * i + 1);
-        pcolor[i].blue  = *(palette + 3 * i + 2);
-    }
-
-    png_set_PLTE(ppng, pinfo, pcolor, 256);
-    free(pcolor);
-
-    png_write_info(ppng, pinfo);
-
-    rowbuf = malloc(width);
-
-    if (rowbuf)
-    {
-        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);
-    png_destroy_write_struct(&ppng, &pinfo);
-    fclose(handle);
-}
-#endif
-
-//
 // V_ScreenShot
 //
 
@@ -820,7 +713,6 @@
     
     // find a file name to save it to
 
-#ifdef HAVE_LIBPNG
     extern int png_screenshots;
     if (png_screenshots)
     {
@@ -827,7 +719,6 @@
         ext = "png";
     }
     else
-#endif
     {
         ext = "pcx";
     }
@@ -847,15 +738,11 @@
         I_Error ("V_ScreenShot: Couldn't create a PCX");
     }
 
-#ifdef HAVE_LIBPNG
     if (png_screenshots)
     {
-    WritePNGfile(lbmname, I_VideoBuffer,
-                 SCREENWIDTH, SCREENHEIGHT,
-                 W_CacheLumpName (DEH_String("PLAYPAL"), PU_CACHE));
+        I_SavePNGScreenshot(lbmname);
     }
     else
-#endif
     {
     // save the pcx file
     WritePCXfile(lbmname, I_VideoBuffer,