From 3debd1554b39a6a2e790526fa02d56d1b81fda85 Mon Sep 17 00:00:00 2001
From: Duane Bailey <nayryeliab@gmail.com>
Date: Sat, 17 Sep 2005 21:35:26 +0000
Subject: 2005-09-17 Duane Bailey <nayryeliab@gmail.com>

	* src/net/messagin.cpp, src/net/messageout.cpp, src/net/network.cpp:
	removed replaced MACOSX defines with big endian defines
	* src/graphics.cpp, src/graphics.h: added screenshot method
	* src/game.cpp: added code, so that when one presses 'alt-p' (for
	picture), it takes a screenshot and saves it to a png
	* src/Makefile.am, config.ac: added png library stuff
---
 ChangeLog              |   9 +++++
 configure.ac           |   3 ++
 src/Makefile.am        |   2 +-
 src/game.cpp           |  10 ++++-
 src/graphics.cpp       | 100 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/graphics.h         |   5 +++
 src/net/messagein.cpp  |   6 +--
 src/net/messageout.cpp |   4 +-
 src/net/network.cpp    |   4 +-
 9 files changed, 134 insertions(+), 9 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 947e1534..c65added 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2005-09-17 Duane Bailey <nayryeliab@gmail.com>
+	
+	* src/net/messagin.cpp, src/net/messageout.cpp, src/net/network.cpp: 
+	removed replaced MACOSX defines with big endian defines
+	* src/graphics.cpp, src/graphics.h: added screenshot method
+	* src/game.cpp: added code, so that when one presses 'alt-p' (for
+	picture), it takes a screenshot and saves it to a png
+	* src/Makefile.am, config.ac: added png library stuff
+	
 2005-09-17  Matthias Hartmann  <hartmann.matthias@gmail.com>
 
 	* src/engine.cpp: [TARGET] text over player
diff --git a/configure.ac b/configure.ac
index 4c63e860..c4b98519 100755
--- a/configure.ac
+++ b/configure.ac
@@ -43,6 +43,9 @@ AC_MSG_ERROR([ *** Unable to find SDL_mixer library
 AC_CHECK_LIB(SDL_net, SDLNet_Init, ,
 AC_MSG_ERROR([ *** Unable to find SDL_net library]))
 
+AC_CHECK_LIB(png, png_write_info, ,
+ACMSG_ERROR([ ** Unable to find png library]))
+
 # Checks for header files.
 AC_HEADER_STDC
 AC_CHECK_HEADERS([arpa/inet.h fcntl.h malloc.h netdb.h netinet/in.h stdlib.h string.h sys/socket.h unistd.h])
diff --git a/src/Makefile.am b/src/Makefile.am
index 5e866f71..a400b149 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -180,5 +180,5 @@ INCLUDES =					\
 # the library search path.
 tmw_LDFLAGS = $(all_libraries) $(LIBSDL_RPATH) `pkg-config --libs libxml-2.0`
 tmw_CXXFLAGS = -Wall $(OPENGL_CFLAGS) $(LIBSDL_CFLAGS) `pkg-config --cflags libxml-2.0` $(CURL_CFLAGS)
-tmw_LDADD = $(LIBSDL_LIBS) -lguichan_sdl -lguichan $(OPENGL_LIBS) -lphysfs $(CURL_LIBS)
+tmw_LDADD = $(LIBSDL_LIBS) -lguichan_sdl -lguichan $(OPENGL_LIBS) -lphysfs $(CURL_LIBS) -lpng
 tmw_TARGET = tmw
diff --git a/src/game.cpp b/src/game.cpp
index 8f9586d9..7ef4967e 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -575,7 +575,15 @@ void do_input()
                         used = true;
                         break;
                     */
-
+                    // screenshot (picture, hence the p)
+                    case SDLK_p:
+                        static int picCount = 1;
+                        if (!graphics->saveScreenshot("Screenshot%d.png", picCount))
+                        {
+                            logger->log("Error: could not save Screenshot%d.png", picCount);
+                            picCount++;
+                        }
+                    break;
                         // Skill window
                     case SDLK_k:
                         skillDialog->setVisible(!skillDialog->isVisible());
diff --git a/src/graphics.cpp b/src/graphics.cpp
index a3299650..ecee2b5f 100644
--- a/src/graphics.cpp
+++ b/src/graphics.cpp
@@ -29,6 +29,8 @@
 
 #include "resources/image.h"
 
+#include <png.h>
+
 extern volatile int framesToDraw;
 
 Graphics::Graphics():
@@ -239,3 +241,101 @@ void Graphics::updateScreen()
         SDL_Delay(10);
     }
 }
+
+bool Graphics::saveScreenshot(char *filename, ...)
+{
+    va_list ap;
+    char *newname = (char *)malloc(32);
+    va_start(ap, filename);
+    vsprintf(newname, filename, ap);
+    va_end(ap);
+
+    FILE *fp = fopen(newname, "wb");
+    if (!fp)
+    {
+        logger->log("could not open file &s for writing", newname);
+        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", newname);
+        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);
+
+    return true;
+}
diff --git a/src/graphics.h b/src/graphics.h
index 6bd32ec2..b45bc15c 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(char *filename, ...);
+
     protected:
         SDL_Surface *mScreen;
         bool mFullscreen, mHWAccel;
diff --git a/src/net/messagein.cpp b/src/net/messagein.cpp
index c7760c82..77f6a54f 100644
--- a/src/net/messagein.cpp
+++ b/src/net/messagein.cpp
@@ -25,7 +25,7 @@
 
 #include <cassert>
 #include <SDL_net.h>
-#ifdef MACOSX
+#ifdef SDL_BYTEORDER == SDL_BIG_ENDIAN
 #include "win2mac.h"
 #endif
 
@@ -55,7 +55,7 @@ MessageIn::readShort()
 {
     assert(mPos + 2 <= mLength);
     mPos += 2;
-#ifdef MACOSX
+#ifdef SDL_BYTEORDER == SDL_BIG_ENDIAN
     return DR_SwapTwoBytes(*(short*)(mData + (mPos - 2)));
 #else
     return (*(short*)(mData + (mPos - 2)));
@@ -67,7 +67,7 @@ MessageIn::readLong()
 {
     assert(mPos + 4 <= mLength);
     mPos += 4;
-#ifdef MACOSX
+#ifdef SDL_BYTEORDER == SDL_BIG_ENDIAN
     return DR_SwapFourBytes(*(long*)(mData + (mPos - 4)));
 #else
     return (*(long*)(mData + (mPos - 4)));
diff --git a/src/net/messageout.cpp b/src/net/messageout.cpp
index 9c6527e0..b3f74078 100644
--- a/src/net/messageout.cpp
+++ b/src/net/messageout.cpp
@@ -69,7 +69,7 @@ void MessageOut::writeByte(char value)
 void MessageOut::writeShort(short value)
 {
     expand(mPos + sizeof(short));
-#ifdef MACOSX
+#ifdef SDL_BYTEORDER == SDL_BIG_ENDIAN
     (*(short *)(mData + mPos)) = DR_SwapTwoBytes(value);
 #else
     (*(short *)(mData + mPos)) = value;
@@ -81,7 +81,7 @@ void MessageOut::writeShort(short value)
 void MessageOut::writeLong(long value)
 {
     expand(mPos + sizeof(long));
-#ifdef MACOSX
+#ifdef SDL_BYTEORDER == SDL_BIG_ENDIAN
     (*(long *)(mData + mPos)) = DR_SwapFourBytes(value);
 #else
     (*(long *)(mData + mPos)) = value;
diff --git a/src/net/network.cpp b/src/net/network.cpp
index 4656a233..e5a0dead 100644
--- a/src/net/network.cpp
+++ b/src/net/network.cpp
@@ -30,7 +30,7 @@
 #include "messagein.h"
 
 #include "../log.h"
-#ifdef MACOSX
+#ifdef SDL_BYTEORDER == SDL_BIG_ENDIAN
 #include "win2mac.h"
 #endif
 
@@ -247,7 +247,7 @@ void flush()
 
 unsigned short readWord(int pos)
 {
-#ifdef MACOSX
+#ifdef SDL_BYTEORDER == SDL_BIG_ENDIAN
     return DR_SwapTwoBytes((*(unsigned short*)(in+(pos))));
 #else
     return (*(unsigned short *)(in+(pos)));
-- 
cgit v1.2.3-70-g09d2