- Refactored worldmap a bit to reuse GameObject from the rest of the game
[supertux.git] / src / video / surface.h
1 //  $Id: surface.h 2175 2004-11-24 19:02:49Z sik0fewl $
2 // 
3 //  SuperTux
4 //  Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
5 //
6 //  This program is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU General Public License
8 //  as published by the Free Software Foundation; either version 2
9 //  of the License, or (at your option) any later version.
10 //
11 //  This program is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 //  GNU General Public License for more details.
15 // 
16 //  You should have received a copy of the GNU General Public License
17 //  along with this program; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 //  02111-1307, USA.
20 #ifndef SUPERTUX_TEXTURE_H
21 #define SUPERTUX_TEXTURE_H
22
23 #include <string>
24 #include <list>
25
26 #include <SDL.h>
27 #include <SDL_opengl.h>
28
29 #include "math/vector.h"
30 #include "video/screen.h"
31
32 void apply_filter_to_surface(SDL_Surface *surface, int filter, int value);
33 SDL_Surface* sdl_surface_from_sdl_surface(SDL_Surface* sdl_surf, bool use_alpha);
34 SDL_Surface* sdl_surface_from_nothing();
35
36 class SurfaceImpl;
37 class SurfaceSDL;
38 class SurfaceOpenGL;
39 class DrawingContext;
40   
41 /// bitset for drawing effects
42 enum {
43   /** Don't apply anything */
44   NONE_EFFECT       = 0x0000,
45   /** Draw the Surface upside down */
46   VERTICAL_FLIP     = 0x0001,
47   /** Draw the Surface from left to down */
48   HORIZONTAL_FLIP   = 0x0002,
49   /** Draw the Surface with alpha equal to 128 */
50   SEMI_TRANSPARENT  = 0x0004
51 };
52
53 /// types of filters
54 enum {
55   HORIZONTAL_FLIP_FILTER,
56   MASK_FILTER,
57   NONE_FILTER
58 };
59
60 /** This class holds all the data necessary to construct a surface */
61 class SurfaceData
62 {
63 public:
64   enum ConstructorType { LOAD, LOAD_PART, SURFACE, GRADIENT };
65   ConstructorType type;
66   SDL_Surface* surface;
67   std::string file;
68   
69   struct Filter { int type; Color color; };
70   std::vector<Filter> applied_filters;
71   
72   bool use_alpha;
73   int x;
74   int y;
75   int w;
76   int h;
77   Color top_gradient;
78   Color bottom_gradient;
79   
80   SurfaceData(SDL_Surface* surf, bool use_alpha_);
81   SurfaceData(const std::string& file_, bool use_alpha_);
82   SurfaceData(const std::string& file_, int x_, int y_, int w_, int h_, bool use_alpha_);
83   SurfaceData(Color top_gradient_, Color bottom_gradient_, int w_, int h_);
84   ~SurfaceData();
85   
86   SurfaceSDL* create_SurfaceSDL();
87   SurfaceOpenGL* create_SurfaceOpenGL();
88   SurfaceImpl* create();
89 };
90
91
92 /** Container class that holds a surface, necessary so that we can
93  *  switch Surface implementations (OpenGL, SDL) on the fly
94  */
95 class Surface
96 {
97 public:
98   SurfaceImpl* impl;
99   SurfaceData data;
100   int w;
101   int h;
102   
103   typedef std::list<Surface*> Surfaces;
104   static Surfaces surfaces;
105 public:
106   static void reload_all();
107   static void debug_check();
108   
109   Surface(SDL_Surface* surf, bool use_alpha);
110   Surface(const std::string& file, bool use_alpha);
111   Surface(const std::string& file, int x, int y, int w, int h, bool use_alpha);
112   Surface(Color top_gradient, Color bottom_gradient, int w_, int h_);
113   ~Surface();
114   
115   /** Reload the surface, which is necesarry in case of a mode swich */
116   void reload();
117   
118   void apply_filter(int filter, Color color = Color(0,0,0));
119 };
120
121 /** Surface implementation, all implementation have to inherit from
122     this class */
123 class SurfaceImpl
124 {
125 protected:
126   SDL_Surface* sdl_surface;
127   
128 public:
129   int w;
130   int h;
131   
132 public:
133   SurfaceImpl();
134   virtual ~SurfaceImpl();
135   
136   /** Return 0 on success, -2 if surface needs to be reloaded */
137   virtual int draw(float x, float y, Uint8 alpha, Uint32 effect = NONE_EFFECT) = 0;
138   virtual int draw_part(float sx, float sy, float x, float y, float w, float h,  Uint8 alpha, Uint32 effect = NONE_EFFECT) = 0;
139   virtual int draw_stretched(float x, float y, int w, int h, Uint8 alpha, Uint32 effect = NONE_EFFECT) = 0;
140   
141   
142   SDL_Surface* get_sdl_surface() const; // @evil@ try to avoid this function
143   
144   virtual void apply_filter(int filter, Color color = Color(0,0,0)) = 0;
145 };
146
147 class SurfaceSDL : public SurfaceImpl
148 {
149 public:
150   SurfaceSDL(SDL_Surface* surf, bool use_alpha);
151   SurfaceSDL(const std::string& file, bool use_alpha);
152   SurfaceSDL(const std::string& file, int x, int y, int w_, int h_, bool use_alpha);
153   SurfaceSDL(Color top_gradient, Color bottom_gradient, int w, int h);
154   virtual ~SurfaceSDL();
155   
156   int draw(float x, float y, Uint8 alpha, Uint32 effect = NONE_EFFECT);
157   int draw_part(float sx, float sy, float x, float y, float w, float h,  Uint8 alpha, Uint32 effect = NONE_EFFECT);
158   int draw_stretched(float x, float y, int w, int h, Uint8 alpha, Uint32 effect = NONE_EFFECT);
159   
160   void apply_filter(int filter, Color color);
161 };
162
163 class SurfaceOpenGL : public SurfaceImpl
164 {
165 public:
166   GLuint gl_texture;
167   
168 public:
169   SurfaceOpenGL(SDL_Surface* surf, bool use_alpha);
170   SurfaceOpenGL(const std::string& file, bool use_alpha);
171   SurfaceOpenGL(const std::string& file, int x, int y, int w, int h, bool use_alpha);
172   SurfaceOpenGL(Color top_gradient, Color bottom_gradient, int w, int h);
173   
174   virtual ~SurfaceOpenGL();
175   
176   int draw(float x, float y, Uint8 alpha, Uint32 effect = NONE_EFFECT);
177   int draw_part(float sx, float sy, float x, float y, float w, float h,  Uint8 alpha, Uint32 effect = NONE_EFFECT);
178   int draw_stretched(float x, float y, int w, int h, Uint8 alpha, Uint32 effect = NONE_EFFECT);
179   
180   void apply_filter(int filter, Color color);
181   
182 private:
183   void create_gl(SDL_Surface * surf, GLuint * tex);
184 };
185
186 #endif