ref: 002822dfa2bd78f946b7e4730004220919d4ddb9
parent: a8029480188a1b02f4acffc33ef4cfb1b94aecc1
author: Fabian Greffrath <[email protected]>
date: Mon Mar 17 12:42:49 EDT 2014
Allow for PNG screenshots.
--- a/configure.ac
+++ b/configure.ac
@@ -80,6 +80,14 @@
[
AC_CHECK_LIB(samplerate, src_new)
])
+ # Check for libpng.
+ AC_ARG_WITH([libpng],
+ AS_HELP_STRING([--without-libpng],
+ [Build without libpng @<:@default=check@:>@]),
+ [],
+ [
+ AC_CHECK_LIB(png, png_get_io_ptr)
+ ])
AC_CHECK_LIB(m, log)
AC_CHECK_HEADERS([linux/kd.h dev/isa/spkrio.h dev/speaker/speaker.h])
--- a/src/doom/g_game.c
+++ b/src/doom/g_game.c
@@ -870,7 +870,7 @@
G_DoWorldDone ();
break;
case ga_screenshot:
- V_ScreenShot("DOOM%02i.pcx");
+ V_ScreenShot("DOOM%02i.%s");
players[consoleplayer].message = DEH_String("screen shot");
gameaction = ga_nothing;
break;
--- a/src/heretic/g_game.c
+++ b/src/heretic/g_game.c
@@ -930,7 +930,7 @@
G_DoPlayDemo();
break;
case ga_screenshot:
- V_ScreenShot("HTIC%02i.pcx");
+ V_ScreenShot("HTIC%02i.%s");
gameaction = ga_nothing;
break;
case ga_completed:
--- a/src/hexen/g_game.c
+++ b/src/hexen/g_game.c
@@ -934,7 +934,7 @@
G_DoPlayDemo();
break;
case ga_screenshot:
- V_ScreenShot("HEXEN%02i.pcx");
+ V_ScreenShot("HEXEN%02i.%s");
P_SetMessage(&players[consoleplayer], "SCREEN SHOT", false);
gameaction = ga_nothing;
break;
--- a/src/i_video.c
+++ b/src/i_video.c
@@ -178,6 +178,10 @@
int novert = 0;
+// Save screenshots in PNG format.
+
+int png_screenshots = 0;
+
// if true, I_VideoBuffer is screen->pixels
static boolean native_surface;
@@ -2220,6 +2224,7 @@
M_BindVariable("usegamma", &usegamma);
M_BindVariable("vanilla_keyboard_mapping", &vanilla_keyboard_mapping);
M_BindVariable("novert", &novert);
+ M_BindVariable("png_screenshots", &png_screenshots);
// Windows Vista or later? Set screen color depth to
// 32 bits per pixel, as 8-bit palettized screen modes
--- a/src/m_config.c
+++ b/src/m_config.c
@@ -1434,6 +1434,12 @@
//
CONFIG_VARIABLE_KEY(key_multi_msgplayer8),
+
+ //!
+ // If non-zero, save screenshots in PNG format.
+ //
+
+ CONFIG_VARIABLE_INT(png_screenshots),
};
static default_collection_t extra_defaults =
--- a/src/setup/display.c
+++ b/src/setup/display.c
@@ -110,6 +110,7 @@
int graphical_startup = 1;
int show_endoom = 1;
+int png_screenshots = 0;
// These are the last screen width/height values that were chosen by the
// user. These are used when finding the "nearest" mode, so when
@@ -710,6 +711,7 @@
M_BindVariable("video_driver", &video_driver);
M_BindVariable("window_position", &window_position);
M_BindVariable("usegamma", &usegamma);
+ M_BindVariable("png_screenshots", &png_screenshots);
if (gamemission == doom || gamemission == heretic
--- a/src/strife/g_game.c
+++ b/src/strife/g_game.c
@@ -937,7 +937,7 @@
G_DoWorldDone ();
break;
case ga_screenshot:
- V_ScreenShot("STRIFE%02i.pcx"); // [STRIFE] file name, message
+ V_ScreenShot("STRIFE%02i.%s"); // [STRIFE] file name, message
players[consoleplayer].message = DEH_String("STRIFE by Rogue entertainment");
gameaction = ga_nothing;
break;
--- a/src/v_video.c
+++ b/src/v_video.c
@@ -44,6 +44,11 @@
#include "w_wad.h"
#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.
#define RANGECHECK
@@ -706,7 +711,82 @@
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 width, int height,
+ byte *palette)
+{
+ png_structp ppng;
+ png_infop pinfo;
+ png_colorp pcolor;
+ FILE *handle;
+ int i;
+
+ 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 + 0);
+ 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);
+
+ for (i = 0; i < SCREENHEIGHT; i++)
+ png_write_row(ppng, data + i*SCREENWIDTH);
+
+ png_write_end(ppng, pinfo);
+ png_destroy_write_struct(&ppng, &pinfo);
+ fclose(handle);
+}
+#endif
+
+//
// V_ScreenShot
//
@@ -714,12 +794,21 @@
{
int i;
char lbmname[16]; // haleyjd 20110213: BUG FIX - 12 is too small!
+ char *ext;
+ extern int png_screenshots;
// find a file name to save it to
+#ifdef HAVE_LIBPNG
+ if (png_screenshots)
+ ext = "png";
+ else
+#endif
+ ext = "pcx";
+
for (i=0; i<=99; i++)
{
- sprintf(lbmname, format, i);
+ sprintf(lbmname, format, i, ext);
if (!M_FileExists(lbmname))
{
@@ -732,6 +821,13 @@
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));
+ else
+#endif
// save the pcx file
WritePCXfile(lbmname, I_VideoBuffer,
SCREENWIDTH, SCREENHEIGHT,