diff --git a/Makefile b/Makefile
index 372f909f96..5994b783a5 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ include config.mk
TARGET = ssnes tools/ssnes-joyconfig
-OBJ = ssnes.o file.o driver.o settings.o dynamic.o message.o rewind.o movie.o autosave.o gfx/gfx_common.o ups.o strl.o
+OBJ = ssnes.o file.o driver.o settings.o dynamic.o message.o rewind.o movie.o autosave.o gfx/gfx_common.o ups.o strl.o screenshot.o
JOYCONFIG_OBJ = tools/ssnes-joyconfig.o conf/config_file.o
HEADERS = $(wildcard */*.h) $(wildcard *.h)
diff --git a/Makefile.win32 b/Makefile.win32
index e0f417fb4a..0817264d83 100644
--- a/Makefile.win32
+++ b/Makefile.win32
@@ -1,6 +1,6 @@
TARGET = ssnes.exe
JTARGET = ssnes-joyconfig.exe
-OBJ = ssnes.o file.o driver.o conf/config_file.o settings.o dynamic.o message.o rewind.o movie.o autosave.o gfx/gfx_common.o ups.o strl.o
+OBJ = ssnes.o file.o driver.o conf/config_file.o settings.o dynamic.o message.o rewind.o movie.o autosave.o gfx/gfx_common.o ups.o strl.o screenshot.o
JOBJ = conf/config_file.o tools/main-stub.o tools/ssnes-joyconfig.o
CC = gcc
diff --git a/Makefile.win64 b/Makefile.win64
index 76f6f75a3c..cba897452a 100644
--- a/Makefile.win64
+++ b/Makefile.win64
@@ -1,6 +1,6 @@
TARGET = ssnes.exe
JTARGET = ssnes-joyconfig.exe
-OBJ = ssnes.o file.o driver.o conf/config_file.o settings.o dynamic.o message.o rewind.o movie.o autosave.o gfx/gfx_common.o ups.o strl.o
+OBJ = ssnes.o file.o driver.o conf/config_file.o settings.o dynamic.o message.o rewind.o movie.o autosave.o gfx/gfx_common.o ups.o strl.o screenshot.o
JOBJ = conf/config_file.o tools/main-stub.o tools/ssnes-joyconfig.o
CC = gcc
diff --git a/screenshot.c b/screenshot.c
new file mode 100644
index 0000000000..bcf8f2467d
--- /dev/null
+++ b/screenshot.c
@@ -0,0 +1,110 @@
+/* SSNES - A Super Nintendo Entertainment System (SNES) Emulator frontend for libsnes.
+ * Copyright (C) 2010-2011 - Hans-Kristian Arntzen
+ *
+ * Some code herein may be based on code found in BSNES.
+ *
+ * SSNES is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Found-
+ * ation, either version 3 of the License, or (at your option) any later version.
+ *
+ * SSNES is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with SSNES.
+ * If not, see .
+ */
+
+#include "screenshot.h"
+#include "strl.h"
+#include
+#include
+#include
+#include
+#include
+#include "general.h"
+
+// Simple 24bpp .BMP writer.
+
+static void write_header(FILE *file, unsigned width, unsigned height)
+{
+ unsigned line_size = (width * 3 + 3) & ~3;
+ unsigned size = line_size * height + 54;
+ unsigned size_array = line_size * height;
+
+ // Generic BMP stuff.
+ const uint8_t header[] = {
+ 'B', 'M',
+ (size >> 0) & 0xff, (size >> 8) & 0xff, (size >> 16) & 0xff, (size >> 24) & 0xff,
+ 0, 0, 0, 0,
+ 54, 0, 0, 0,
+ 40, 0, 0, 0,
+ (width >> 0) & 0xff, (width >> 8) & 0xff, (width >> 16) & 0xff, (width >> 24) & 0xff,
+ (height >> 0) & 0xff, (height >> 8) & 0xff, (height >> 16) & 0xff, (height >> 24) & 0xff,
+ 1, 0,
+ 24, 0,
+ 0, 0, 0, 0,
+ (size_array >> 0) & 0xff, (size_array >> 8) & 0xff, (size_array >> 16) & 0xff, (size_array >> 24) & 0xff,
+ 19, 11, 0, 0,
+ 19, 11, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0
+ };
+
+ fwrite(header, 1, sizeof(header), file);
+}
+
+static void dump_content(FILE *file, const uint16_t *frame, unsigned width, unsigned height, unsigned pitch)
+{
+ pitch >>= 1;
+ unsigned line_size = (width * 3 + 3) & ~3;
+ uint8_t line[line_size];
+ memset(line, 0, sizeof(line));
+
+ for (int j = height - 1; j >= 0; j--)
+ {
+ uint8_t * restrict dst = line;
+ const uint16_t * restrict src = frame + j * pitch;
+ for (unsigned i = 0; i < width; i++)
+ {
+ uint16_t pixel = *src++;
+ uint8_t b = (pixel & 0x1f) << 3;
+ uint8_t g = (pixel & 0x03e0) >> 2;
+ uint8_t r = (pixel & 0x7c00) >> 7;
+ *dst++ = b;
+ *dst++ = g;
+ *dst++ = r;
+ }
+
+ fwrite(line, 1, sizeof(line), file);
+ }
+}
+
+bool screenshot_dump(const char *folder, const uint16_t *frame,
+ unsigned width, unsigned height, unsigned pitch)
+{
+ time_t cur_time;
+ time(&cur_time);
+
+ char timefmt[64];
+ strftime(timefmt, sizeof(timefmt), "SSNES-%c", localtime(&cur_time));
+
+ char filename[256];
+ strlcpy(filename, folder, sizeof(filename));
+ strlcat(filename, "/", sizeof(filename));
+ strlcat(filename, timefmt, sizeof(filename));
+
+ FILE *file = fopen(filename, "wb");
+ if (!file)
+ {
+ SSNES_ERR("Failed to open file \"%s\" for screenshot.\n", filename);
+ return false;
+ }
+
+ write_header(file, width, height);
+ dump_content(file, frame, width, height, pitch);
+
+ fclose(file);
+
+ return true;
+}
diff --git a/screenshot.h b/screenshot.h
new file mode 100644
index 0000000000..849db56a60
--- /dev/null
+++ b/screenshot.h
@@ -0,0 +1,27 @@
+/* SSNES - A Super Nintendo Entertainment System (SNES) Emulator frontend for libsnes.
+ * Copyright (C) 2010-2011 - Hans-Kristian Arntzen
+ *
+ * Some code herein may be based on code found in BSNES.
+ *
+ * SSNES is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Found-
+ * ation, either version 3 of the License, or (at your option) any later version.
+ *
+ * SSNES is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with SSNES.
+ * If not, see .
+ */
+
+#ifndef __SSNES_SCREENSHOT_H
+#define __SSNES_SCREENSHOT_H
+
+#include
+#include
+
+bool screenshot_dump(const char *folder, const uint16_t *frame,
+ unsigned width, unsigned height, unsigned pitch);
+
+#endif