From 06221a4cb3f44e7532e185bc775c73741d32cbf2 Mon Sep 17 00:00:00 2001 From: Yohann Ferreira Date: Sun, 18 Sep 2005 01:31:33 +0000 Subject: Made the saveScreenShot makes its screenshots under user home dir in *nices, made it more C++ way to avoid a leak, and made it check for existence of a file with same name before writing; In that case the screenshot's number is incremented until it finds an adequate name. --- ChangeLog | 10 ++++ src/game.cpp | 11 +--- src/graphics.cpp | 130 +++++++++++++++++++++++++++++++++++++++++- src/graphics.h | 7 +++ src/resources/imagewriter.cpp | 15 ++--- src/resources/imagewriter.h | 2 +- 6 files changed, 158 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index d7d74e9a..44905d56 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2005-09-18 Yohann Ferreira + + * src/game.cpp, src/graphics.cpp, src/graphics.h, + src/resources/imagewriter.cpp, src/resources/imagewriter.h: + Made the saveScreenShot makes its screenshots under user home dir in + *nices, made it more C++ way to avoid a leak, and made it check + for existence of a file with same name before writing; In that + case the screenshot's number is incremented until it finds + an adequate name. + 2005-09-18 Björn Steinbrink * src/Makefile.am, src/game.cpp, src/graphics.cpp, src/graphics.h, diff --git a/src/game.cpp b/src/game.cpp index 4778dae7..5aaf1e8e 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -69,8 +69,6 @@ #include "net/network.h" #include "net/protocol.h" -#include "resources/imagewriter.h" - extern Graphics *graphics; std::string map_path; @@ -580,13 +578,10 @@ void do_input() */ // screenshot (picture, hence the p) case SDLK_p: + //ImageWriter::writePNG(graphics->getScreenshot(), name.str()); + if (!graphics->saveScreenshot()) { - // TODO Fix the counting to start at a sane value. - static int picCount = 1; - std::stringstream name; - name << "Screenshot-" << picCount << ".png"; - ImageWriter::writePNG(graphics->getScreenshot(), name.str()); - picCount++; + logger->log("Error: could not save Screenshot."); } break; // Skill window diff --git a/src/graphics.cpp b/src/graphics.cpp index 33f25468..1d6734c8 100644 --- a/src/graphics.cpp +++ b/src/graphics.cpp @@ -28,11 +28,17 @@ #include "graphic/imagerect.h" #include "resources/image.h" +#include +#include +#include +#include +#include "resources/imagewriter.h" extern volatile int framesToDraw; Graphics::Graphics(): - mScreen(0) + mScreen(0), + screenshotsCount(1) { } @@ -240,6 +246,128 @@ void Graphics::updateScreen() } } +bool Graphics::saveScreenshot() +{ + std::stringstream pictureFilename; + // Write it under user home dir on *nices. + #ifdef __USE_UNIX98 + pictureFilename << PHYSFS_getUserDir(); + pictureFilename << "/"; + #endif + pictureFilename << "TMW_Screenshot_" << screenshotsCount << ".png"; + + // While these screenshots files already exists, increment the + // screenshots count. + std::fstream testExists; + testExists.open(std::string(pictureFilename.str()).c_str(), std::ios::in); + while ( testExists.is_open() ) + { + testExists.close(); + screenshotsCount++; + pictureFilename.str(""); + #ifdef __USE_UNIX98 + pictureFilename << PHYSFS_getUserDir(); + pictureFilename << "/"; + #endif + pictureFilename << "TMW_Screenshot_" << screenshotsCount << ".png"; + testExists.open(std::string(pictureFilename.str()).c_str(), std::ios::in); + } + testExists.close(); + + ImageWriter::writePNG(getScreenshot(), pictureFilename.str()); + + /*FILE *fp = fopen(std::string(pictureFilename.str()).c_str(), "wb"); + if (!fp) + { + logger->log("Could not open Screenshot's File %s in write mode.", std::string(pictureFilename.str()).c_str()); + return false; + } + + png_structp png_ptr; + png_infop info_ptr; + png_bytep *row_pointers; + int colortype; + + #if SDL_BYTEORDER == SDL_BIG_ENDIAN + int rmask = 0xff000000; + int gmask = 0x00ff0000; + int bmask = 0x0000ff00; + int amask = 0x000000ff; + #else + int rmask = 0x000000ff; + int gmask = 0x0000ff00; + int bmask = 0x00ff0000; + int amask = 0xff000000; + #endif + + SDL_Surface *surface = SDL_CreateRGBSurface(SDL_SWSURFACE, mScreen->w, + mScreen->h, 32, rmask, gmask, bmask, amask); + //SDL_LockSurface(mScreen); + SDL_BlitSurface(mScreen, NULL, surface, NULL); + //SDL_UnlockSurface(mScreen); + + SDL_LockSurface(surface); + + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); + if (!png_ptr) + { + logger->log("Had trouble creating png_structp"); + return false; + } + + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) + { + logger->log("Could not create png_info"); + return false; + } + + + if (setjmp(png_ptr->jmpbuf)) + { + logger->log("Problem writing to %s", std::string(pictureFilename.str()).c_str()); + return false; + } + + png_init_io(png_ptr, fp); + + if (mScreen->format->BitsPerPixel == 24) colortype = PNG_COLOR_TYPE_RGB; + else colortype = PNG_COLOR_TYPE_RGB_ALPHA; + + png_set_IHDR(png_ptr, info_ptr, surface->w, surface->h, 8,colortype, + PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + + png_write_info(png_ptr, info_ptr); + + png_set_packing(png_ptr); + + row_pointers = (png_bytep*) malloc(sizeof(png_bytep)*surface->h); + if (!row_pointers) + { + logger->log("Had trouble converting surface to row pointers"); + return false; + } + + for (int i = 0; i < surface->h; i++) + row_pointers[i] = (png_bytep)(Uint8 *)surface->pixels + i * surface->pitch; + + png_write_image(png_ptr, row_pointers); + png_write_end(png_ptr, info_ptr); + fclose(fp); + if (row_pointers) free(row_pointers); + + if (info_ptr->palette) free(info_ptr->palette); + + png_destroy_write_struct(&png_ptr, (png_infopp)NULL); + + SDL_UnlockSurface(surface); + SDL_FreeSurface(surface); +*/ + screenshotsCount++; + + return true; +} + SDL_Surface* Graphics::getScreenshot() { #if SDL_BYTEORDER == SDL_BIG_ENDIAN diff --git a/src/graphics.h b/src/graphics.h index a0749795..18a3be51 100644 --- a/src/graphics.h +++ b/src/graphics.h @@ -119,6 +119,11 @@ class Graphics : public gcn::SDLGraphics { */ int getHeight(); + /** + * takes a screenshot, and saves it as a png + */ + bool saveScreenshot(); + /** * takes a screenshot and returns it as SDL surface */ @@ -127,6 +132,8 @@ class Graphics : public gcn::SDLGraphics { protected: SDL_Surface *mScreen; bool mFullscreen, mHWAccel; + private: + int screenshotsCount; }; #endif diff --git a/src/resources/imagewriter.cpp b/src/resources/imagewriter.cpp index a6fb3d97..98219e44 100644 --- a/src/resources/imagewriter.cpp +++ b/src/resources/imagewriter.cpp @@ -29,15 +29,15 @@ #include "../log.h" -void ImageWriter::writePNG(SDL_Surface *surface, +bool ImageWriter::writePNG(SDL_Surface *surface, const std::string &filename) { // TODO Maybe someone can make this look nice? FILE *fp = fopen(filename.c_str(), "wb"); if (!fp) { - logger->log("could not open file &s for writing", filename.c_str()); - return; + logger->log("could not open file %s for writing", filename.c_str()); + return false; } png_structp png_ptr; @@ -53,7 +53,7 @@ void ImageWriter::writePNG(SDL_Surface *surface, if (!png_ptr) { logger->log("Had trouble creating png_structp"); - return; + return false; } info_ptr = png_create_info_struct(png_ptr); @@ -61,14 +61,14 @@ void ImageWriter::writePNG(SDL_Surface *surface, { png_destroy_write_struct(&png_ptr, (png_infopp)NULL); logger->log("Could not create png_info"); - return; + return false; } if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_write_struct(&png_ptr, (png_infopp)NULL); logger->log("problem writing to %s", filename.c_str()); - return; + return false; } png_init_io(png_ptr, fp); @@ -87,7 +87,7 @@ void ImageWriter::writePNG(SDL_Surface *surface, if (!row_pointers) { logger->log("Had trouble converting surface to row pointers"); - return; + return false; } for (int i = 0; i < surface->h; i++) @@ -105,4 +105,5 @@ void ImageWriter::writePNG(SDL_Surface *surface, if (SDL_MUSTLOCK(surface)) { SDL_UnlockSurface(surface); } + return true; } diff --git a/src/resources/imagewriter.h b/src/resources/imagewriter.h index edda723f..205e4584 100644 --- a/src/resources/imagewriter.h +++ b/src/resources/imagewriter.h @@ -28,6 +28,6 @@ struct SDL_Surface; class ImageWriter { public: - static void writePNG(SDL_Surface *surface, + static bool writePNG(SDL_Surface *surface, const std::string &filename); }; -- cgit v1.2.3-70-g09d2