From 804169dd621a3ad3eec1a32ce30350de667fee80 Mon Sep 17 00:00:00 2001 From: aliaspider Date: Thu, 30 Oct 2014 00:23:30 +0100 Subject: apply a facelift --- source/screenshot.c | 277 ++++++++++++++++++++++++++++------------------------ 1 file changed, 147 insertions(+), 130 deletions(-) (limited to 'source/screenshot.c') diff --git a/source/screenshot.c b/source/screenshot.c index f33b240..fc3cccb 100644 --- a/source/screenshot.c +++ b/source/screenshot.c @@ -1,6 +1,6 @@ /******************************************************************************* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and Jerremy Koot (jkoot@snes9x.com) @@ -43,53 +43,53 @@ S-DD1 C emulator code (c) Copyright 2003 Brad Jorsch with research by Andreas Naive and John Weidman - + S-RTC C emulator code (c) Copyright 2001 John Weidman - + ST010 C++ emulator code (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - Super FX C emulator code + Super FX C emulator code (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + - Specific ports contains the works of other authors. See headers in individual files. - + Snes9x homepage: http://www.snes9x.com - + Permission to use, copy, modify and distribute Snes9x in both binary and source form, for non-commercial purposes, is hereby granted without fee, providing that this license information and copyright notice appear with all copies and any derived work. - + This software is provided 'as-is', without any express or implied warranty. In no event shall the authors be held liable for any damages arising from the use of this software. - + Snes9x is freeware for PERSONAL USE only. Commercial users should seek permission of the copyright holders first. Commercial use includes charging money for Snes9x or software derived from Snes9x. - + The copyright holders request that bug fixes and improvements to the code should be forwarded to them so everyone can benefit from the modifications in future versions. - + Super NES and Super Nintendo Entertainment System are trademarks of Nintendo Co., Limited and its subsidiary companies. *******************************************************************************/ #ifdef HAVE_CONFIG_H - #include +#include #endif #include @@ -112,124 +112,141 @@ #include "ppu.h" #include "screenshot.h" -bool8 S9xDoScreenshot(int width, int height){ +bool8 S9xDoScreenshot(int width, int height) +{ #ifdef HAVE_LIBPNG - FILE *fp; - png_structp png_ptr; - png_infop info_ptr; - png_color_8 sig_bit; - png_color pngpal[256]; - int imgwidth; - int imgheight; - const char *fname=S9xGetFilenameInc(".png"); - - Settings.TakeScreenshot=FALSE; - - if((fp=fopen(fname, "wb"))==NULL){ - perror("Screenshot failed"); - return FALSE; - } - - png_ptr=png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if(!png_ptr){ - fclose(fp); - unlink(fname); - return FALSE; - } - info_ptr=png_create_info_struct(png_ptr); - if(!info_ptr){ - png_destroy_write_struct(&png_ptr, (png_infopp)NULL); - fclose(fp); - unlink(fname); - return FALSE; - } - - if(setjmp(png_jmpbuf(png_ptr))){ - perror("Screenshot: setjmp"); - png_destroy_write_struct(&png_ptr, &info_ptr); - fclose(fp); - unlink(fname); - return FALSE; - } - - imgwidth=width; - imgheight=height; - if(Settings.StretchScreenshots==1){ - if(width<=256 && height>SNES_HEIGHT_EXTENDED) imgwidth=width<<1; - if(width>256 && height<=SNES_HEIGHT_EXTENDED) imgheight=height<<1; - } else if(Settings.StretchScreenshots==2){ - if(width<=256) imgwidth=width<<1; - if(height<=SNES_HEIGHT_EXTENDED) imgheight=height<<1; - } - - png_init_io(png_ptr, fp); - if(!Settings.SixteenBit){ - // BJ: credit sanmaiwashi for the idea to do palettized pngs, and to - // S9xSetPalette in x11.cpp for how to calculate the RGB values - int b=IPPU.MaxBrightness*140; - for(int i=0; i<256; i++){ - pngpal[i].red = (PPU.CGDATA[i] & 0x1f)*b>>8; - pngpal[i].green = ((PPU.CGDATA[i] >> 5) & 0x1f)*b>>8; - pngpal[i].blue = ((PPU.CGDATA[i] >> 10) & 0x1f)*b>>8; - } - png_set_PLTE(png_ptr, info_ptr, pngpal, 256); - } - png_set_IHDR(png_ptr, info_ptr, imgwidth, imgheight, 8, - (Settings.SixteenBit?PNG_COLOR_TYPE_RGB:PNG_COLOR_TYPE_PALETTE), - PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, - PNG_FILTER_TYPE_DEFAULT); - - if(Settings.SixteenBit){ - /* 5 bits per color */ - sig_bit.red=5; - sig_bit.green=5; - sig_bit.blue=5; - png_set_sBIT(png_ptr, info_ptr, &sig_bit); - png_set_shift(png_ptr, &sig_bit); - } - - png_write_info(png_ptr, info_ptr); - - png_set_packing(png_ptr); - - png_byte *row_pointer=new png_byte [png_get_rowbytes(png_ptr, info_ptr)]; - uint8 *screen=GFX.Screen; - for(int y=0; y SNES_HEIGHT_EXTENDED) imgwidth = width << 1; + if (width > 256 && height <= SNES_HEIGHT_EXTENDED) imgheight = height << 1; + } + else if (Settings.StretchScreenshots == 2) + { + if (width <= 256) imgwidth = width << 1; + if (height <= SNES_HEIGHT_EXTENDED) imgheight = height << 1; + } + + png_init_io(png_ptr, fp); + if (!Settings.SixteenBit) + { + // BJ: credit sanmaiwashi for the idea to do palettized pngs, and to + // S9xSetPalette in x11.cpp for how to calculate the RGB values + int b = IPPU.MaxBrightness * 140; + for (int i = 0; i < 256; i++) + { + pngpal[i].red = (PPU.CGDATA[i] & 0x1f) * b >> 8; + pngpal[i].green = ((PPU.CGDATA[i] >> 5) & 0x1f) * b >> 8; + pngpal[i].blue = ((PPU.CGDATA[i] >> 10) & 0x1f) * b >> 8; + } + png_set_PLTE(png_ptr, info_ptr, pngpal, 256); + } + png_set_IHDR(png_ptr, info_ptr, imgwidth, imgheight, 8, + (Settings.SixteenBit ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_PALETTE), + PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, + PNG_FILTER_TYPE_DEFAULT); + + if (Settings.SixteenBit) + { + /* 5 bits per color */ + sig_bit.red = 5; + sig_bit.green = 5; + sig_bit.blue = 5; + png_set_sBIT(png_ptr, info_ptr, &sig_bit); + png_set_shift(png_ptr, &sig_bit); + } + + png_write_info(png_ptr, info_ptr); + + png_set_packing(png_ptr); + + png_byte* row_pointer = new png_byte [png_get_rowbytes(png_ptr, info_ptr)]; + uint8* screen = GFX.Screen; + for (int y = 0; y < height; y++, screen += GFX.Pitch) + { + png_byte* rowpix = row_pointer; + for (int x = 0; x < width; x++) + { + if (Settings.SixteenBit) + { + uint32 r, g, b; + DECOMPOSE_PIXEL((*(uint16*)(screen + 2 * x)), r, g, b); + *(rowpix++) = r; + *(rowpix++) = g; + *(rowpix++) = b; + if (imgwidth != width) + { + *(rowpix++) = r; + *(rowpix++) = g; + *(rowpix++) = b; } - } - png_write_row(png_ptr, row_pointer); - if(imgheight!=height) - png_write_row(png_ptr, row_pointer); - } - - delete [] row_pointer; - - png_write_end(png_ptr, info_ptr); - png_destroy_write_struct(&png_ptr, &info_ptr); - - fclose(fp); - fprintf(stderr, "%s saved.\n", fname); - return TRUE; + } + else + { + *(rowpix++) = *(uint8*)(screen + x); + if (imgwidth != width) + *(rowpix++) = *(uint8*)(screen + x); + } + } + png_write_row(png_ptr, row_pointer); + if (imgheight != height) + png_write_row(png_ptr, row_pointer); + } + + delete [] row_pointer; + + png_write_end(png_ptr, info_ptr); + png_destroy_write_struct(&png_ptr, &info_ptr); + + fclose(fp); + fprintf(stderr, "%s saved.\n", fname); + return TRUE; #else - perror("Screenshot support not available (libpng was not found at build time)"); - return FALSE; + perror("Screenshot support not available (libpng was not found at build time)"); + return FALSE; #endif } -- cgit v1.2.3