Added horizontal flip effect, as well as both horizontal and vertical together.
[supertux.git] / lib / video / surface.h
1 //  $Id$
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
21 #ifndef SUPERTUX_TEXTURE_H
22 #define SUPERTUX_TEXTURE_H
23
24 #include <string>
25 #include <list>
26
27 #ifndef NOOPENGL
28 #include "SDL_opengl.h"
29 #endif
30
31 #include "SDL.h"
32
33 #include "../math/vector.h"
34 #include "../video/screen.h"
35
36 namespace SuperTux
37   {
38   
39   SDL_Surface* sdl_surface_from_sdl_surface(SDL_Surface* sdl_surf, bool use_alpha);
40   SDL_Surface* sdl_surface_from_nothing();
41
42   class SurfaceImpl;
43   class SurfaceSDL;
44   class SurfaceOpenGL;
45   class DrawingContext;
46   
47   /// bitset for drawing effects
48   enum {
49     /** Don't apply anything */
50     NONE_EFFECT       = 0x0000,
51     /** Draw the Surface upside down */
52     VERTICAL_FLIP     = 0x0001,
53     /** Draw the Surface from left to down */
54     HORIZONTAL_FLIP   = 0x0002,
55     /** Draw the Surface with alpha equal to 128 */
56     SEMI_TRANSPARENT  = 0x0004
57   };
58
59   /** This class holds all the data necessary to construct a surface */
60   class SurfaceData
61     {
62     public:
63       enum ConstructorType { LOAD, LOAD_PART, SURFACE, GRADIENT };
64       ConstructorType type;
65       SDL_Surface* surface;
66       std::string file;
67       bool use_alpha;
68       int x;
69       int y;
70       int w;
71       int h;
72       Color top_gradient;
73       Color bottom_gradient;
74
75       SurfaceData(SDL_Surface* surf, bool use_alpha_);
76       SurfaceData(const std::string& file_, bool use_alpha_);
77       SurfaceData(const std::string& file_, int x_, int y_, int w_, int h_, bool use_alpha_);
78       SurfaceData(Color top_gradient_, Color bottom_gradient_, int w_, int h_);
79       ~SurfaceData();
80
81       SurfaceSDL* create_SurfaceSDL();
82       SurfaceOpenGL* create_SurfaceOpenGL();
83       SurfaceImpl* create();
84     };
85
86
87   /// Surface
88   /** Container class that holds a surface, necessary so that we can
89       switch Surface implementations (OpenGL, SDL) on the fly */
90   class Surface
91     {
92     public:
93       SurfaceData data;
94       SurfaceImpl* impl;
95       int w;
96       int h;
97
98       typedef std::list<Surface*> Surfaces;
99       static Surfaces surfaces;
100     public:
101       static void reload_all();
102       static void debug_check();
103
104       Surface(SDL_Surface* surf, bool use_alpha);
105       Surface(const std::string& file, bool use_alpha);
106       Surface(const std::string& file, int x, int y, int w, int h, bool use_alpha);
107       Surface(Color top_gradient, Color bottom_gradient, int w_, int h_);
108       ~Surface();
109
110       /** Reload the surface, which is necesarry in case of a mode swich */
111       void reload();
112
113       void resize(int widht, int height);
114     };
115
116   /** Surface implementation, all implementation have to inherit from
117       this class */
118   class SurfaceImpl
119     {
120     protected:
121       SDL_Surface* sdl_surface;
122
123     public:
124       int w;
125       int h;
126
127     public:
128       SurfaceImpl();
129       virtual ~SurfaceImpl();
130
131       /** Return 0 on success, -2 if surface needs to be reloaded */
132       virtual int draw(float x, float y, Uint8 alpha, Uint32 effect = NONE_EFFECT) = 0;
133       virtual int draw_part(float sx, float sy, float x, float y, float w, float h,  Uint8 alpha, Uint32 effect = NONE_EFFECT) = 0;
134       virtual int draw_stretched(float x, float y, int w, int h, Uint8 alpha, Uint32 effect = NONE_EFFECT) = 0;
135
136
137       int resize(int w_, int h_);
138
139       SDL_Surface* get_sdl_surface() const; // @evil@ try to avoid this function
140     };
141
142   class SurfaceSDL : public SurfaceImpl
143     {
144     public:
145       SurfaceSDL(SDL_Surface* surf, bool use_alpha);
146       SurfaceSDL(const std::string& file, bool use_alpha);
147       SurfaceSDL(const std::string& file, int x, int y, int w, int h, bool use_alpha);
148       SurfaceSDL(Color top_gradient, Color bottom_gradient, int w, int h);
149       virtual ~SurfaceSDL();
150
151       int draw(float x, float y, Uint8 alpha, Uint32 effect = NONE_EFFECT);
152       int draw_part(float sx, float sy, float x, float y, float w, float h,  Uint8 alpha, Uint32 effect = NONE_EFFECT);
153       int draw_stretched(float x, float y, int w, int h, Uint8 alpha, Uint32 effect = NONE_EFFECT);
154     };
155
156 #ifndef NOOPENGL
157   class SurfaceOpenGL : public SurfaceImpl
158     {
159     public:
160       GLuint gl_texture;
161
162     public:
163       SurfaceOpenGL(SDL_Surface* surf, bool use_alpha);
164       SurfaceOpenGL(const std::string& file, bool use_alpha);
165       SurfaceOpenGL(const std::string& file, int x, int y, int w, int h, bool use_alpha);
166       SurfaceOpenGL(Color top_gradient, Color bottom_gradient, int w, int h);
167
168       virtual ~SurfaceOpenGL();
169
170       int draw(float x, float y, Uint8 alpha, Uint32 effect = NONE_EFFECT);
171       int draw_part(float sx, float sy, float x, float y, float w, float h,  Uint8 alpha, Uint32 effect = NONE_EFFECT);
172       int draw_stretched(float x, float y, int w, int h, Uint8 alpha, Uint32 effect = NONE_EFFECT);
173
174
175     private:
176       void create_gl(SDL_Surface * surf, GLuint * tex);
177     };
178 #endif
179
180 } //namespace SuperTux
181
182 #endif /*SUPERTUX_TEXTURE_H*/
183
184 /* Local Variables: */
185 /* mode: c++ */
186 /* End: */