From 7d249c829d65e228f64976d8497a311a87211ff5 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Sat, 31 Jan 2009 23:01:29 +0000 Subject: [PATCH] Add screen shot button --- src/Game.cpp | 3 +++ src/Input.cpp | 14 ++++++++++++-- src/Input.hpp | 6 ++++-- src/Menu.cpp | 2 ++ src/OpenGL.cpp | 48 +++++++++++++++++++++++++++++++++++++++++++++--- src/OpenGL.hpp | 7 ++++++- 6 files changed, 72 insertions(+), 8 deletions(-) diff --git a/src/Game.cpp b/src/Game.cpp index 1acc5ba..d6a4c20 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -137,6 +137,9 @@ void Game::Process() input.ResetAction(Input::PAUSE); } + if (input.QueryResetAction(Input::SCREENSHOT)) + opengl.DeferScreenShot(); + // Do no more game processing in the paused state if (state == gsPaused) return; diff --git a/src/Input.cpp b/src/Input.cpp index 28bc51d..50fc2d3 100644 --- a/src/Input.cpp +++ b/src/Input.cpp @@ -103,7 +103,7 @@ void Input::Update() case SDL_KEYUP: if (e.key.keysym.sym == SDLK_LSHIFT - || e.key.keysym.sym == SDLK_RSHIFT) { + || e.key.keysym.sym == SDLK_RSHIFT) { shift = false; } break; @@ -168,6 +168,15 @@ void Input::Update() } } +// Query an action and reset if fired. +bool Input::QueryResetAction(Action a) +{ + bool on = QueryAction(a); + if (on) + ResetAction(a); + return on; +} + // Returns true if the action a is being perfomed. // Either on the keyboard on the first joystick. bool Input::QueryAction(Action a) const @@ -201,6 +210,8 @@ bool Input::QueryAction(Action a) const return keystate[SDLK_p] != 0; case THRUST: return (keystate[SDLK_UP] != 0) || joyButton1; + case SCREENSHOT: + return keystate[SDLK_PRINT] != 0; default: assert(false); } @@ -247,4 +258,3 @@ const char* Input::GetInput() const { return text.c_str(); } - diff --git a/src/Input.hpp b/src/Input.hpp index c2afa1b..7c14cf8 100644 --- a/src/Input.hpp +++ b/src/Input.hpp @@ -30,12 +30,14 @@ public: // Possible inputs enum Action { UP, DOWN, LEFT, RIGHT, FIRE, - SKIP, ABORT, DEBUG, PAUSE, THRUST + SKIP, ABORT, DEBUG, PAUSE, THRUST, + SCREENSHOT }; static Input& GetInstance(); bool QueryAction(Action a) const; + bool QueryResetAction(Action a); void ResetAction(Action a); void Update(); @@ -47,7 +49,7 @@ private: Input(); ~Input(); - static const int NUM_ACTIONS = 10; + static const int NUM_ACTIONS = 11; static const int RESET_TIMEOUT = 7; // Frames between key presses SDL_Joystick* joystick; diff --git a/src/Menu.cpp b/src/Menu.cpp index 4cfe3a1..434499a 100644 --- a/src/Menu.cpp +++ b/src/Menu.cpp @@ -127,6 +127,8 @@ void MainMenu::Process() input.ResetAction(Input::FIRE); } + else if (input.QueryResetAction(Input::SCREENSHOT)) + OpenGL::GetInstance().DeferScreenShot(); } // See what menu state we're in diff --git a/src/OpenGL.cpp b/src/OpenGL.cpp index 5231ff8..f9f1911 100644 --- a/src/OpenGL.cpp +++ b/src/OpenGL.cpp @@ -1,6 +1,6 @@ // // OpenGL.cpp - Implementation of OpenGL wrapper class. -// Copyright (C) 2006 Nick Gasson +// Copyright (C) 2006-2009 Nick Gasson // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -25,7 +25,8 @@ OpenGL::OpenGL() : screen_width(0), screen_height(0), fullscreen(false), running(false), active(true), dodisplay(true), - fps_lastcheck(0), fps_framesdrawn(0), fps_rate(0) + fps_lastcheck(0), fps_framesdrawn(0), fps_rate(0), + deferredScreenShot(false) { // Start random number generator srand((unsigned)time(NULL)); @@ -63,7 +64,7 @@ void OpenGL::Init(int width, int height, int depth, bool fullscreen) RuntimeError("Initialisation failed."); } -void OpenGL::RuntimeError(string mess) +void OpenGL::RuntimeError(const string& mess) { throw runtime_error(mess); } @@ -135,6 +136,42 @@ void OpenGL::Run() } while (running); } +// Take a screenshot at the end of this frame +void OpenGL::DeferScreenShot() +{ + deferredScreenShot = true; +} + +void OpenGL::TakeScreenShot() const +{ + const string fileName("Lander.bmp"); + + SDL_Surface* temp = SDL_CreateRGBSurface + (SDL_SWSURFACE, screen_width, screen_height, 24, +#if SDL_BYTEORDER == SDL_LIL_ENDIAN + 0x000000FF, 0x0000FF00, 0x00FF0000, 0 +#else + 0x00FF0000, 0x0000FF00, 0x000000FF, 0 +#endif + ); + assert(temp); + + const int w = screen_width; + const int h = screen_height; + unsigned char* pixels = new unsigned char[3 * w * h]; + + glReadPixels(0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, pixels); + + for (int i = 0; i < h; i++) + memcpy(((char*)temp->pixels) + temp->pitch * i, pixels + 3*w * (h-i-1), w*3); + delete[] pixels; + + SDL_SaveBMP(temp, fileName.c_str()); + SDL_FreeSurface(temp); + + cout << "Wrote screen shot to " << fileName << endl; +} + void OpenGL::DrawGLScene() { // Render the scene @@ -145,6 +182,11 @@ void OpenGL::DrawGLScene() ScreenManager::GetInstance().Display(); SDL_GL_SwapBuffers(); + + if (deferredScreenShot) { + TakeScreenShot(); + deferredScreenShot = false; + } fps_framesdrawn++; } diff --git a/src/OpenGL.hpp b/src/OpenGL.hpp index e7e8cab..2ffd477 100644 --- a/src/OpenGL.hpp +++ b/src/OpenGL.hpp @@ -109,6 +109,8 @@ public: int GetWidth() const { return screen_width; } int GetHeight() const { return screen_height; } + void DeferScreenShot(); + bool SetVideoMode(bool fullscreen, int width, int height); bool IsTextureSizeSupported(int width, int height, int ncols=4, @@ -126,7 +128,8 @@ private: bool InitGL(); void DrawGLScene(); string SDLErrorString(); - void RuntimeError(string mess); + void RuntimeError(const string& mess); + void TakeScreenShot() const; // Window related variables int screen_width, screen_height; @@ -136,6 +139,8 @@ private: // Frame rate variables int fps_lastcheck, fps_framesdrawn, fps_rate; + + bool deferredScreenShot; }; #endif -- 2.39.2