From 9946bbb8c1f21b678ef577ad741d16595db75849 Mon Sep 17 00:00:00 2001 From: jsalmon3 <> Date: Fri, 31 May 2002 06:10:28 +0000 Subject: [PATCH] Implemented task #38320: Making screen shots --- src/game/intro.cpp | 10 ++-- src/include/interface.h | 1 + src/include/video.h | 3 ++ src/ui/interface.cpp | 25 ++++++++++ src/video/png.cpp | 101 ++++++++++++++++++++++++++++++++++++++++ src/video/sdl.cpp | 3 ++ 6 files changed, 139 insertions(+), 4 deletions(-) diff --git a/src/game/intro.cpp b/src/game/intro.cpp index 3e3a71e75..3354304f0 100644 --- a/src/game/intro.cpp +++ b/src/game/intro.cpp @@ -114,9 +114,10 @@ local void IntroCallbackButton2(unsigned button) /** ** Callback for input. */ -local void IntroCallbackKey1(unsigned key __attribute__((unused)), - unsigned keychar) +local void IntroCallbackKey1(unsigned key, unsigned keychar) { + HandleKeyModifiersDown(key,keychar); + if (UseContinueButton) { if (keychar == 'c' || keychar == '\r') { ContinueButtonFlags |= MenuButtonClicked; @@ -129,9 +130,10 @@ local void IntroCallbackKey1(unsigned key __attribute__((unused)), /** ** Callback for input. */ -local void IntroCallbackKey2(unsigned key, - unsigned keychar __attribute__((unused))) +local void IntroCallbackKey2(unsigned key, unsigned keychar) { + HandleKeyModifiersDown(key,keychar); + if( UseContinueButton ) { if( (key =='c' || key =='\r') && (ContinueButtonFlags&MenuButtonClicked) ) { diff --git a/src/include/interface.h b/src/include/interface.h index a423a5196..7f1345bed 100644 --- a/src/include/interface.h +++ b/src/include/interface.h @@ -130,6 +130,7 @@ enum _key_codes_ { KeyCodeAlt, /// internal keycode: alt modifier KeyCodeSuper, /// internal keycode: super modifier KeyCodeHyper, /// internal keycode: hyper modifier + KeyCodePrint, /// internal keycode: print screen }; /// Key modifier diff --git a/src/include/video.h b/src/include/video.h index 824b0e4d5..0ed2cd198 100644 --- a/src/include/video.h +++ b/src/include/video.h @@ -1137,6 +1137,9 @@ extern void WaitEventsOneFrame(const EventCallback* callbacks); /// Load graphic from PNG file extern Graphic* LoadGraphicPNG(const char* name); + /// Save a screenshot to a PNG file +extern void SaveScreenshotPNG(const char* name); + /// New graphic extern Graphic* NewGraphic(unsigned d,unsigned w,unsigned h); diff --git a/src/ui/interface.cpp b/src/ui/interface.cpp index 65dc4a65b..dba44266f 100644 --- a/src/ui/interface.cpp +++ b/src/ui/interface.cpp @@ -51,6 +51,7 @@ #include "font.h" #include "campaign.h" #include "video.h" +#include "iolib.h" /*---------------------------------------------------------------------------- -- Declaration @@ -984,6 +985,27 @@ local int InputKey(int key) return 0; } + +/** +** Save a screenshot. +*/ +local void Screenshot() +{ + CLFile *fd; + char filename[1024]; + int i; + + for( i=1; i<99; ++i ) { + sprintf(filename, "screen%02d.png", i); + if( !(fd = CLopen(filename)) ) { + break; + } + CLclose(fd); + } + SaveScreenshotPNG(filename); +} + + /** ** Update KeyModifiers if a key is pressed. ** @@ -1012,6 +1034,9 @@ global int HandleKeyModifiersDown(unsigned key, case KeyCodeHyper: KeyModifiers|=ModifierHyper; return 1; + case KeyCodePrint: + Screenshot(); + return 1; default: break; } diff --git a/src/video/png.cpp b/src/video/png.cpp index 27242de94..19a65aa5b 100644 --- a/src/video/png.cpp +++ b/src/video/png.cpp @@ -209,4 +209,105 @@ global Graphic* LoadGraphicPNG(const char* name) return graphic; } +/** +** Save a screenshot to a PNG file. +** +** @param name PNG filename to save. +*/ +global void SaveScreenshotPNG(const char* name) +{ + FILE *fp; + png_structp png_ptr; + png_infop info_ptr; + unsigned char* row; + int i, j; + + fp = fopen(name, "wb"); + if (fp == NULL) + return; + + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (png_ptr == NULL) { + fclose(fp); + return; + } + + info_ptr = png_create_info_struct(png_ptr); + if (info_ptr == NULL) { + fclose(fp); + png_destroy_write_struct(&png_ptr, png_infopp_NULL); + return; + } + + if (setjmp(png_jmpbuf(png_ptr))) + { + /* If we get here, we had a problem reading the file */ + fclose(fp); + png_destroy_write_struct(&png_ptr, &info_ptr); + return; + } + + /* set up the output control if you are using standard C streams */ + png_init_io(png_ptr, fp); + + png_set_IHDR(png_ptr, info_ptr, VideoWidth, VideoHeight, 8, + PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, + PNG_FILTER_TYPE_DEFAULT); + + png_set_bgr(png_ptr); + + VideoLockScreen(); + + row = (char*)malloc(VideoWidth*3); + + png_write_info(png_ptr, info_ptr); + + for (i=0; i<VideoHeight; ++i) { + switch (VideoBpp) { + case 8: + // FIXME: Finish + break; + case 15: + for (j=0; j<VideoWidth; ++j) { + VMemType16 c = VideoMemory16[i*VideoWidth+j]; + row[j*3+0] = (((c >> 0) & 0x1f) * 0xff) / 0x1f; + row[j*3+1] = (((c >> 5) & 0x1f) * 0xff) / 0x1f; + row[j*3+2] = (((c >> 10) & 0x1f) * 0xff) / 0x1f; + } + break; + case 16: + for (j=0; j<VideoWidth; ++j) { + VMemType16 c = VideoMemory16[i*VideoWidth+j]; + row[j*3+0] = (((c >> 0) & 0x1f) * 0xff) / 0x1f; + row[j*3+1] = (((c >> 5) & 0x3f) * 0xff) / 0x3f; + row[j*3+2] = (((c >> 11) & 0x1f) * 0xff) / 0x1f; + } + break; + case 24: + memcpy(row, VideoMemory24+i*VideoWidth, VideoWidth*3); + break; + case 32: + for (j=0; j<VideoWidth; ++j) { + VMemType32 c = VideoMemory32[i*VideoWidth+j]; + row[j*3+0] = ((c >> 0) & 0xff); + row[j*3+1] = ((c >> 8) & 0xff); + row[j*3+2] = ((c >> 16) & 0xff); + } + break; + } + png_write_row(png_ptr, row); + } + + png_write_end(png_ptr, info_ptr); + + VideoUnlockScreen(); + + /* clean up after the write, and free any memory allocated */ + png_destroy_write_struct(&png_ptr, &info_ptr); + + free(row); + + fclose(fp); +} + //@} diff --git a/src/video/sdl.cpp b/src/video/sdl.cpp index 3926e9098..f58b8155f 100644 --- a/src/video/sdl.cpp +++ b/src/video/sdl.cpp @@ -372,6 +372,9 @@ local int Sdl2InternalKeycode(const SDL_keysym * code, int *keychar) case SDLK_KP_MINUS: icode = KeyCodeKPMinus; break; + case SDLK_SYSREQ: + icode = KeyCodePrint; + break; // We need these because if you only hit a modifier key, // the *ots from SDL don't report correct modifiers