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