コード例 #1
0
ファイル: screenshot.cpp プロジェクト: askotx/snes9xgx143
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);
#ifndef NGC
        unlink(fname);
#endif
        return FALSE;
    }
    info_ptr=png_create_info_struct(png_ptr);
    if(!info_ptr){
        png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
        fclose(fp);
#ifndef NGC
        unlink(fname);
#endif
        return FALSE;
    }

    if(setjmp(png_jmpbuf(png_ptr))){
        perror("Screenshot: setjmp");
        png_destroy_write_struct(&png_ptr, &info_ptr);
        fclose(fp);
#ifndef NGC
        unlink(fname);
#endif
        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);
    }
コード例 #2
0
ファイル: screenshot.cpp プロジェクト: 7sevenx7/snes9x
bool8 S9xDoScreenshot (int width, int height)
{
	Settings.TakeScreenshot = FALSE;

#ifdef HAVE_LIBPNG
	FILE		*fp;
	png_structp	png_ptr;
	png_infop	info_ptr;
	png_color_8	sig_bit;
	int			imgwidth, imgheight;
	const char	*fname;

	fname = S9xGetFilenameInc(".png", SCREENSHOT_DIR);

	fp = fopen(fname, "wb");
	if (!fp)
	{
		S9xMessage(S9X_ERROR, 0, "Failed to take screenshot.");
		return (FALSE);
	}

	png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
	if (!png_ptr)
	{
		fclose(fp);
		remove(fname);
		S9xMessage(S9X_ERROR, 0, "Failed to take screenshot.");
		return (FALSE);
	}

	info_ptr = png_create_info_struct(png_ptr);
	if (!info_ptr)
	{
		png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
		fclose(fp);
		remove(fname);
		S9xMessage(S9X_ERROR, 0, "Failed to take screenshot.");
		return (FALSE);
	}

	if (setjmp(png_jmpbuf(png_ptr)))
	{
		png_destroy_write_struct(&png_ptr, &info_ptr);
		fclose(fp);
		remove(fname);
		S9xMessage(S9X_ERROR, 0, "Failed to take screenshot.");
		return (FALSE);
	}

	imgwidth  = width;
	imgheight = height;

	if (Settings.StretchScreenshots == 1)
	{
		if (width > SNES_WIDTH && height <= SNES_HEIGHT_EXTENDED)
			imgheight = height << 1;
	}
	else
	if (Settings.StretchScreenshots == 2)
	{
		if (width  <= SNES_WIDTH)
			imgwidth  = width  << 1;
		if (height <= SNES_HEIGHT_EXTENDED)
			imgheight = height << 1;
	}

	png_init_io(png_ptr, fp);

	png_set_IHDR(png_ptr, info_ptr, imgwidth, imgheight, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);

	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)];
	uint16		*screen = GFX.Screen;

	for (int y = 0; y < height; y++, screen += GFX.RealPPL)
	{
		png_byte	*rowpix = row_pointer;

		for (int x = 0; x < width; x++)
		{
			uint32	r, g, b;

			DECOMPOSE_PIXEL(screen[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);

	const char	*base = S9xBasename(fname);
	sprintf(String, "Saved screenshot %s", base);
	S9xMessage(S9X_INFO, 0, String);

	return (TRUE);
#else
	fprintf(stderr, "Screenshot support not available (libpng was not found at build time).\n");
	return (FALSE);
#endif
}