1 /******************************************************************************
2  *  Warmux is a convivial mass murder game.
3  *  Copyright (C) 2001-2011 Warmux Team.
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
18  ******************************************************************************
19  * Handle a SDL_Surface.
20  *****************************************************************************/
21 
22 #ifndef SURFACE_H
23 #define SURFACE_H
24 
25 #include <string>
26 #include <list>
27 #include "color.h"
28 #include <WARMUX_base.h>
29 #include <WARMUX_point.h>
30 #include <WARMUX_rectangle.h>
31 
32 struct SDL_Surface;
33 struct SDL_PixelFormat;
34 
35 class Surface
36 {
37 private:
38   SDL_Surface* surface;
39   bool autoFree;
40   int Blit(const Surface& src, SDL_Rect *srcRect, SDL_Rect *dstRect);
41   static SDL_Rect GetSDLRect(const Rectanglei &r);
42   static SDL_Rect GetSDLRect(const Point2i &r);
43 
44 public:
45   /**
46    * Default constructor.
47    *
48    * Build a null surface with autoFree at true.
49    */
Surface()50   explicit Surface() : surface(NULL), autoFree(true) { };
51   /**
52    * Constructor building a surface object using an existing SDL_Surface pointer.
53    *
54    * @param sdl_surface The existing sdl_surface.
55    */
Surface(SDL_Surface * sdl_surface)56   explicit Surface(SDL_Surface *sdl_surface) : surface(sdl_surface), autoFree(true) { };
57   /**
58    * Constructor building a surface object using the NewSurface function.
59    *
60    * @param size
61    * @param flags
62    * @param useAlpha
63    * @see NewSurface
64    */
65   explicit Surface(const Point2i &size, Uint32 flags, bool useAlpha = true)
surface(NULL)66   : surface(NULL), autoFree(true) { NewSurface(size, flags, useAlpha); }
67   explicit Surface(const std::string &filename);
68   Surface(const Surface &src);
69   /**
70    * Destructor of the surface.
71    *
72    * Will free the memory used by the surface if autoFree is set to true and if the counter of reference reach 0
73    */
~Surface()74   ~Surface() { AutoFree(); };
75 
76   Surface &operator=(const Surface &src);
77 
78   void Free();
AutoFree()79   void AutoFree() { if (autoFree) Free(); };
80   /**
81    * Set the auto free status of a surface.
82    *
83    * In general it should always be true for non-system surface.
84    * @param newAutoFree the new autoFree status.
85    */
SetAutoFree(bool newAutoFree)86   void SetAutoFree(bool newAutoFree) { autoFree = newAutoFree; };
87 
88   /**
89    * Change the surface pointer.
90    *
91    * @param newSurface The new surface to use.
92    * @param freePrevius Indicate if the old surface should be freed.
93    */
94   void SetSurface(SDL_Surface *newSurface, bool freePrevious = true){
95     if (freePrevious)
96       Free();
97 
98     surface = newSurface;
99   }
100 
101   /**
102    * Return the pointer of the SDL_Surface.
103    *
104    * Should be used carefully.
105    */
GetSurface()106   SDL_Surface *GetSurface() { return surface; };
GetSurface()107   const SDL_Surface *GetSurface() const { return surface; };
108 
109   void NewSurface(const Point2i &size, Uint32 flags, bool useAlpha = true);
110   int SetAlpha(Uint32 flags, Uint8 alpha);
111 
112   void Lock();
113   void Unlock();
114 
115   void SwapClipRect(Rectanglei& rect);
116 
117   /**
118    * Blit the whole surface src on the current surface.
119    *
120    * @param src The source surface.
121    */
Blit(const Surface & src)122   int Blit(const Surface& src) { return Blit(src, NULL, NULL); };
123   int Blit(const Surface& src, const Point2i& dst);
124   int Blit(const Surface& src, const Rectanglei& srcRect, const Point2i &dstPoint);
125 
126   void MergeSurface(Surface &spr, const Point2i &position);
127 
128   int SetColorKey(Uint32 flag, Uint32 key);
129 
130   void GetRGBA(Uint32 color, Uint8 &r, Uint8 &g, Uint8 &b, Uint8 &a) const;
131   Uint32 MapRGBA(Uint8 r, Uint8 g, Uint8 b, Uint8 a) const;
132   Color GetColor(Uint32 color) const;
133   Uint32 MapColor(const Color& color) const;
134 
135   void Flip();
136 
137   int BoxColor(const Rectanglei &rect, const Color &color);
138   int RectangleColor(const Rectanglei &rect, const Color &color, const uint &border_size = 1);
139   int VlineColor(const uint &x, const uint &y1, const uint &y2, const Color &color);
140   int HlineColor(const uint &x1, const uint &x2, const uint &y, const Color &color);
141   int LineColor(const uint &x1, const uint &x2, const uint &y1, const uint &y2, const Color &color);
142   int AALineColor(const uint &x1, const uint &x2, const uint &y1, const uint &y2, const Color &color);
143   int AAFadingLineColor(const uint &x1, const uint &x2, const uint &y1, const uint &y2, const Color &color1, const Color &color2);
144   int CircleColor(const uint &x, const uint &y, const uint &rad, const Color &color);
145   int FilledCircleColor(const uint &x, const uint &y, const uint &rad, const Color &color);
146   int PieColor(const uint &x, const uint &y, const uint &rad, const int &start, const int &end, const Color &color);
147   int FilledPieColor(const uint &x, const uint &y, const uint &rad, const int &start, const int &end, const Color &color);
148   int AAPolygonColor(const Sint16 * vx, const Sint16 * vy, const int n, const Color & color);
149   int AAPolygonColor(std::list<Point2i> polygon, const Color & color);
150   int FilledPolygon(const Sint16 * vx, const Sint16 * vy, const int n, const Color & color);
151   int FilledPolygon(std::list<Point2i> polygon, const Color & color);
152   int TexturedPolygon(const Sint16 * vx, const Sint16 * vy, const int n, const Surface *texture, const int texture_dx, const int texture_dy);
153   int TexturedPolygon(std::list<Point2i> polygon, const Surface *texture);
154 
155   int Fill(Uint32 color) const;
156   int Fill(const Color &color) const;
157   int FillRect(const Rectanglei &dstRect, Uint32 color) const;
158   int FillRect(const Rectanglei &dstRect, const Color &color) const;
159 
160   int ImgLoad(const std::string& filename);
161   bool ImgSave(const std::string& filename, bool bmp=false);
162   Surface RotoZoom(Double angle, Double zoomx, Double zoomy);
163   Surface DisplayFormatAlpha();
164   Surface DisplayFormat();
165   Uint32 GetPixel(int x, int y) const;
166   void PutPixel(int x, int y, Uint32 pixel) const;
167 
IsNull()168   bool IsNull() const { return surface == NULL; };
GetSize()169   Point2i GetSize() const { return Point2i( GetWidth(), GetHeight() ); };
170 
GetWidth()171   inline int GetWidth() const { return surface->w; }
GetHeight()172   inline int GetHeight() const { return surface->h; }
173 
GetFlags()174   Uint32 GetFlags() const { return surface->flags; };
175   /** Return the length of a surface scanline in bytes. */
GetPitch()176   Uint16 GetPitch() const { return surface->pitch; };
177   /** Return the number of bytes used to represent each pixel
178    *  in a surface. Usually one to four.
179    */
GetBytesPerPixel()180   Uint8 GetBytesPerPixel() const { return surface->format->BytesPerPixel; };
181   /** Return a pointer on the pixels data. */
GetPixels()182   unsigned char *GetPixels() const { return (unsigned char *)surface->pixels; }
183 
184   static Surface DisplayFormatColorKey(const uint32_t* data, SDL_PixelFormat *fmt,
185                                        int w, int h, int stride,
186                                        uint8_t alpha_threshold, bool rle=false);
187   Surface DisplayFormatColorKey(uint8_t alpha_threshold, bool rle=false);
188 
189   Surface Crop(const Rectanglei& area) const;
190 
191   Surface Mirror();
192 };
193 
194 #endif
195