commit 07afb7749ff807118431ea356ab56364ef8cfee8
Author: Fabian Greffrath <fabian@greffrath.com>
AuthorDate: Mon May 2 22:42:26 2016 +0200
Commit: Fabian Greffrath <fabian@greffrath.com>
CommitDate: Mon May 2 22:42:26 2016 +0200
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?).
---
configure.ac | 23 ++---------
src/Makefile.am | 6 ++-
src/i_video.c | 18 ++++++++
src/i_video.h | 2 +
src/setup/display.c | 2 -
src/v_video.c | 115 +---------------------------------------------------
6 files changed, 28 insertions(+), 138 deletions(-)
diff --git a/configure.ac b/configure.ac
index 0443e731..ed2763a2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -37,6 +37,7 @@ fi
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 @@ AS_IF([test "x$with_libsamplerate" != xno], [
])
])
-# 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])
diff --git a/src/Makefile.am b/src/Makefile.am
index db8d46e4..0e83f92c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -21,7 +21,8 @@ execgames_SCRIPTS = $(SETUP_BINARIES)
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 @@ EXTRA_LIBS = \
@LDFLAGS@ \
@SDL_LIBS@ \
@SDLMIXER_LIBS@ \
- @SDLNET_LIBS@
+ @SDLNET_LIBS@ \
+ @SDLIMAGE_LIBS@
if HAVE_WINDRES
@PROGRAM_PREFIX@doom_SOURCES=$(SOURCE_FILES_WITH_DEH) resource.rc
diff --git a/src/i_video.c b/src/i_video.c
index c0fd78db..76fe14f8 100644
--- 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
@@ -1196,3 +1197,20 @@ void I_BindVideoVariables(void)
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);
+}
diff --git a/src/i_video.h b/src/i_video.h
index 8e6c2906..3e815aba 100644
--- a/src/i_video.h
+++ b/src/i_video.h
@@ -82,6 +82,8 @@ void I_StartTic (void);
void I_EnableLoadingDisk(int xoffs, int yoffs);
+void I_SavePNGScreenshot (char *filename);
+
extern char *video_driver;
extern boolean screenvisible;
diff --git a/src/setup/display.c b/src/setup/display.c
index f0b52b6f..7c06be3e 100644
--- a/src/setup/display.c
+++ b/src/setup/display.c
@@ -246,11 +246,9 @@ static void AdvancedDisplayConfig(TXT_UNCAST_ARG(widget),
&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);
}
diff --git a/src/v_video.c b/src/v_video.c
index 9d575e03..64702316 100644
--- 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,110 +701,6 @@ void WritePCXfile(char *filename, byte *data,
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,14 +713,12 @@ void V_ScreenShot(char *format)
// find a file name to save it to
-#ifdef HAVE_LIBPNG
extern int png_screenshots;
if (png_screenshots)
{
ext = "png";
}
else
-#endif
{
ext = "pcx";
}
@@ -847,15 +738,11 @@ void V_ScreenShot(char *format)
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,