diff --git a/src/png.c b/src/png.c index 778982d..8e6c818 100644 --- a/src/png.c +++ b/src/png.c @@ -8,7 +8,7 @@ * * Provide centralized access to the PNG image handler. * - * Version: @(#)png.c 1.0.5 2019/01/11 + * Version: @(#)png.c 1.0.6 2019/04/27 * * Author: Fred N. van Kempen, * @@ -358,7 +358,7 @@ error: /* Write the given BITMAP-format image as an 8-bit RGBA file. */ int -png_write_rgb(const wchar_t *fn, uint8_t *pix, int16_t w, int16_t h) +png_write_rgb(const wchar_t *fn, int flip, uint8_t *pix, int16_t w, int16_t h) { png_structp png = NULL; png_infop info = NULL; @@ -427,22 +427,15 @@ error: /* Create a buffer for scanlines of pixels. */ rows = (png_bytepp)mem_alloc(sizeof(png_bytep) * h); + + /* Process all scanlines in the image. */ for (y = 0; y < h; y++) { /* Create a buffer for this scanline. */ rows[y] = (png_bytep)mem_alloc(PNGFUNC(get_rowbytes)(png, info)); - } - /* - * Process all scanlines in the image. - * - * Since the bitmap is in 'bottom-up' mode, we have to - * convert all pixels to RGB mode, but also 'flip' the - * image to the normal top-down mode. - */ - for (y = 0; y < h; y++) { + /* Process all pixels on this line */ for (x = 0; x < w; x++) { - /* Get pointer to pixel in bitmap data. */ - b = &pix[((y * w) + x) * 4]; + b = &pix[((y * w) + x) * 4]; /* Transform if needed. */ if (vid_grayscale || invert_display) { @@ -450,13 +443,30 @@ error: *rgb = video_color_transform(*rgb); } - /* Get pointer to png row data. */ - r = &rows[(h - 1) - y][x * 3]; + if (flip) { + /* + * Since the bitmap is in 'bottom-up' mode, we + * have to convert all pixels to RGB mode, but + * also 'flip' the image to the normal top-down + * mode. + */ - /* Copy the pixel data. */ - r[0] = b[2]; - r[1] = b[1]; - r[2] = b[0]; + /* Get pointer to png row data. */ + r = &rows[(h - 1) - y][x * 3]; + + /* Copy the pixel data. */ + r[0] = b[2]; + r[1] = b[1]; + r[2] = b[0]; + } else { + /* Get pointer to png row data. */ + r = &rows[y][x * 3]; + + /* Copy the pixel data. */ + r[0] = b[0]; + r[1] = b[1]; + r[2] = b[2]; + } } } diff --git a/src/png.h b/src/png.h index f8df57f..a43acca 100644 --- a/src/png.h +++ b/src/png.h @@ -8,7 +8,7 @@ * * Definitions for the centralized PNG image handler. * - * Version: @(#)png.h 1.0.2 2019/01/11 + * Version: @(#)png.h 1.0.3 2019/04/27 * * Author: Fred N. van Kempen, * @@ -58,7 +58,7 @@ extern void png_unload(void); extern int png_write_gray(const wchar_t *path, int invert, uint8_t *pix, int16_t w, int16_t h); -extern int png_write_rgb(const wchar_t *fn, uint8_t *pix, +extern int png_write_rgb(const wchar_t *fn, int flip, uint8_t *pix, int16_t w, int16_t h); #ifdef EMU_VIDEO_H diff --git a/src/win/win_d2d.cpp b/src/win/win_d2d.cpp index 81d46f8..f8d8eff 100644 --- a/src/win/win_d2d.cpp +++ b/src/win/win_d2d.cpp @@ -222,7 +222,7 @@ d2d_blit(bitmap_t *scr, int x, int y, int y1, int y2, int w, int h) return; } - // TODO: Copy data directly from buffer32 to d2d_bitmap + // TODO: Copy data directly from screen to d2d_bitmap srcdata = mem_alloc(h * w * 4); for (yy = y1; yy < y2; yy++) { if ((y + yy) >= 0 && (y + yy) < scr->h) { diff --git a/src/win/win_ddraw.cpp b/src/win/win_ddraw.cpp index 5d2bafd..28fb346 100644 --- a/src/win/win_ddraw.cpp +++ b/src/win/win_ddraw.cpp @@ -8,7 +8,7 @@ * * Rendering module for Microsoft DirectDraw 9. * - * Version: @(#)win_ddraw.cpp 1.0.19 2019/03/08 + * Version: @(#)win_ddraw.cpp 1.0.20 2019/04/27 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -723,7 +723,7 @@ ddraw_screenshot(const wchar_t *fn) #ifdef USE_LIBPNG /* Save the screenshot, using PNG if available. */ - i = png_write_rgb(path, pixels, + i = png_write_rgb(path, 1, pixels, (int16_t)bmi.bmiHeader.biWidth, (int16_t)abs(bmi.bmiHeader.biHeight)); if (i == 0) { diff --git a/src/win/win_sdl.c b/src/win/win_sdl.c index 575a0df..23bf9a8 100644 --- a/src/win/win_sdl.c +++ b/src/win/win_sdl.c @@ -12,7 +12,7 @@ * we will not use that, but, instead, use a new window which * coverrs the entire desktop. * - * Version: @(#)win_sdl.c 1.0.8 2019/03/08 + * Version: @(#)win_sdl.c 1.0.9 2019/04/27 * * Authors: Fred N. van Kempen, * Michael Drüing, @@ -65,6 +65,9 @@ #include "../device.h" #include "../ui/ui.h" #include "../plat.h" +#if USE_LIBPNG +# include "../png.h" +#endif #include "../devices/video/video.h" #include "win.h" #include "win_sdl.h" @@ -90,28 +93,26 @@ static int sdl_fs; /* Pointers to the real functions. */ -static void (*sdl_GetVersion)(SDL_version *ver); +static void (*sdl_GetVersion)(SDL_version *); static char *const (*sdl_GetError)(void); -static int (*sdl_Init)(Uint32 flags); +static int (*sdl_Init)(Uint32); static void (*sdl_Quit)(void); -static SDL_Window *(*sdl_CreateWindowFrom)(const void *data); -static void (*sdl_DestroyWindow)(SDL_Window *window); -static SDL_Renderer *(*sdl_CreateRenderer)(SDL_Window *window, - int index, Uint32 flags); -static void (*sdl_DestroyRenderer)(SDL_Renderer *renderer); -static SDL_Texture *(*sdl_CreateTexture)(SDL_Renderer *renderer, - Uint32 format, int access, - int w, int h); -static void (*sdl_DestroyTexture)(SDL_Texture *texture); -static int (*sdl_LockTexture)(SDL_Texture *texture, - const SDL_Rect *rect, - void **pixels, int *pitch); -static void (*sdl_UnlockTexture)(SDL_Texture *texture); -static int (*sdl_RenderCopy)(SDL_Renderer *renderer, - SDL_Texture *texture, - const SDL_Rect *srcrect, - const SDL_Rect *dstrect); -static void (*sdl_RenderPresent)(SDL_Renderer *renderer); +static void (*sdl_GetWindowSize)(SDL_Window *, int *, int *); +static SDL_Window *(*sdl_CreateWindowFrom)(const void *); +static void (*sdl_DestroyWindow)(SDL_Window *); +static SDL_Renderer *(*sdl_CreateRenderer)(SDL_Window *, int, Uint32); +static void (*sdl_DestroyRenderer)(SDL_Renderer *); +static SDL_Texture *(*sdl_CreateTexture)(SDL_Renderer *, Uint32, int, int, int); +static void (*sdl_DestroyTexture)(SDL_Texture *); +static int (*sdl_LockTexture)(SDL_Texture *, const SDL_Rect *, + void **, int *); +static void (*sdl_UnlockTexture)(SDL_Texture *); +static int (*sdl_RenderCopy)(SDL_Renderer *, SDL_Texture *, + const SDL_Rect *, const SDL_Rect *); +static void (*sdl_RenderPresent)(SDL_Renderer *); +static int (*sdl_RenderReadPixels)(SDL_Renderer *, + const SDL_Rect *, + Uint32, void *, int); static const dllimp_t sdl_imports[] = { @@ -119,6 +120,7 @@ static const dllimp_t sdl_imports[] = { { "SDL_GetError", &sdl_GetError }, { "SDL_Init", &sdl_Init }, { "SDL_Quit", &sdl_Quit }, + { "SDL_GetWindowSize", &sdl_GetWindowSize }, { "SDL_CreateWindowFrom", &sdl_CreateWindowFrom }, { "SDL_DestroyWindow", &sdl_DestroyWindow }, { "SDL_CreateRenderer", &sdl_CreateRenderer }, @@ -129,6 +131,7 @@ static const dllimp_t sdl_imports[] = { { "SDL_UnlockTexture", &sdl_UnlockTexture }, { "SDL_RenderCopy", &sdl_RenderCopy }, { "SDL_RenderPresent", &sdl_RenderPresent }, + { "SDL_RenderReadPixels", &sdl_RenderReadPixels }, { NULL, NULL } }; @@ -466,9 +469,10 @@ sdl_init(int fs) static void sdl_screenshot(const wchar_t *fn) { -#if 0 + wchar_t temp[256]; + int width = 0, height = 0; uint8_t *pixels = NULL; - int res; + int i = 0, res; sdl_GetWindowSize(sdl_win, &width, &height); @@ -486,8 +490,20 @@ sdl_screenshot(const wchar_t *fn) return; } - if (pixels) free(pixels); +#ifdef USE_LIBPNG + /* Save the screenshot, using PNG. */ + i = png_write_rgb(fn, 0, pixels, (int16_t)width, (int16_t)height); #endif + + if (pixels) + free(pixels); + + /* Show error message if needed. */ + if (i == 0) { + swprintf(temp, sizeof_w(temp), + get_string(IDS_ERR_SCRSHOT), fn); + ui_msgbox(MBX_ERROR, temp); + } }