Adonthell  0.4
surface.h
Go to the documentation of this file.
1 /*
2  Copyright (C) 1999/2000/2001/2004 Alexandre Courbot
3  Copyright (C) 2016 Kai Sterker
4  Part of the Adonthell Project <http://adonthell.nongnu.org>
5 
6  Adonthell is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  Adonthell 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 Adonthell. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 
21 /**
22  * @file surface.h
23  * @author Alexandre Courbot <alexandrecourbot@linuxgames.com>
24  * @author Kai Sterker
25  *
26  * @brief Declares the surface class.
27  *
28  *
29  */
30 
31 
32 #ifndef SURFACE_H_
33 #define SURFACE_H_
34 
35 
36 #include "drawable.h"
37 
38 #ifdef __BIG_ENDIAN__
39 # define R_MASK 0x00ff0000
40 # define G_MASK 0x0000ff00
41 # define B_MASK 0x000000ff
42 # define A_MASK 0xff000000
43 #else
44 # define R_MASK 0x000000ff
45 # define G_MASK 0x0000ff00
46 # define B_MASK 0x00ff0000
47 # define A_MASK 0xff000000
48 #endif
49 #define BYTES_PER_PIXEL 4
50 
51 
53 {
54 public:
55  pixel_info() : Pixels(NULL), Pitch(0), Format(0), BytesPerPixel(0)
56  { }
57 
58  /// the pixel data of the locked Surface
59  void *Pixels;
60  /// the pitch of the locked Surface
61  int Pitch;
62  /// the format of the surface
64  /// number of bytes used to represent the format
66 };
67 
68 /**
69  * Class where drawables can actually be drawn to.
70  * Another name for a surface could eventually be "pixmap". A surface
71  * is nothing more than an array of pixels where drawables can put their
72  * %image to. This class has only two purposes: to group methods shared by
73  * image and screen, and to ensure that every drawing operation can be performed
74  * on the screen or on an image.
75  *
76  * Every surface has two special parameters:
77  * @li a mask parameter, indicating whether the transparent color (which hex
78  * triplet is 0xFF00FF, and you can get with screen::trans_col ()) should
79  * be drawn or not.
80  * @li an alpha parameter, indicating the level of translucency of the surface.
81  * it's range go from 0 to 255, 0 being totally invisible and 255 totally
82  * opaque.
83  *
84  */
85 class surface : public drawable
86 {
87 public:
88 
89  /**
90  * Default constructor.
91  * The surface will be totally empty, that is
92  * (0, 0) sized, no mask, alpha value of 255 (opaque).
93  *
94  */
95  surface (const u_int8 & scale = 1);
96 
97  /**
98  * Destructor.
99  *
100  */
101  virtual ~surface ();
102 
103 
104  /**
105  * @name Settings.
106  * These methods sets the parameters of the surface.
107  *
108  */
109  //@{
110 
111 
112  /**
113  *
114  * Returns whether a surface is masked or not.
115  *
116  * @return true if the surface is masked, false if it isn't.
117  */
118  bool is_masked () const
119  {
120  return is_masked_;
121  }
122 
123  /**
124  * Sets the mask parameter of the surface.
125  *
126  * @param m true if the surface should be masked, false otherwise.
127  */
128  void set_mask (bool m);
129 
130  /**
131  * Returns the alpha value of the surface.
132  *
133  *
134  * @return the alpha value of the surface.
135  */
136  u_int8 alpha () const
137  {
138  return alpha_;
139  }
140 
141  /**
142  * Sets the alpha value of the surface. If alpha_channel is set to true,
143  * then the surface_alpha value will be silently ignored. Needs to
144  * be called before surface::resize to take effect.
145  *
146  * @param surface_alpha The new alpha value for this surface.
147  * @param alpha_channel Whether to enable per-pixel alpha for the surface.
148  */
149  void set_alpha (u_int8 a, const bool & alpha_channel = false);
150 
151  /**
152  * Returns whether the surface has an alpha channel.
153  * @return true if it has an alpha channel, false otherwise.
154  */
155  bool has_alpha_channel () const
156  {
157  return alpha_channel_;
158  }
159 
160  /**
161  * Get the surfaces current scaling factor.
162  */
163  u_int8 scale () const { return scale_; }
164 
165  /**
166  * Change the scale of the surface to the given value,
167  * resizing the internal texture appropriately.
168  * @param scale the new scale to set.
169  */
170  void set_scale (const u_int8 & scale);
171 
172  //@}
173 
174 
175  /**
176  * @name Drawing Methods.
177  *
178  */
179 
180  //@{
181 
182 
183  /**
184  * Draw the surface.
185  *
186  * @param x X position where to draw.
187  * @param y Y position where to draw.
188  * @param da_opt optional drawing_area to use during the drawing operation.
189  * @param target pointer to the surface where to draw the drawable. If NULL, draw on the screen.
190  */
191  void draw (s_int16 x, s_int16 y, const drawing_area * da_opt = NULL,
192  surface * target = NULL) const
193  {
194  draw (x, y, 0, 0, length (), height (), da_opt, target);
195  }
196 
197 #ifndef SWIG
198  /**
199  * Draw a part of the surface.
200  *
201  * @param x X position where to draw.
202  * @param y Y position where to draw.
203  * @param sx X position where to start drawing from this image.
204  * @param sy Y position where to start drawing from this image.
205  * @param sl length of the part of this image to draw.
206  * @param sh height of the part of this image to draw.
207  * @param da_opt optional drawing_area to use during the drawing operation.
208  * @param target pointer to the surface where to draw the drawable. If NULL, draw on the screen.
209  *
210  * @attention Not accessible from Python. Use draw_part () from Python instead.
211  * @sa draw_part ()
212  *
213  */
214  void draw (s_int16 x, s_int16 y, s_int16 sx, s_int16 sy, u_int16 sl,
215  u_int16 sh, const drawing_area * da_opt = NULL,
216  surface * target = NULL) const;
217 #endif
218 
219  /**
220  * Synonym of draw () to guarantee its access from Python.
221  *
222  * @sa draw ()
223  *
224  */
225  void draw_part (s_int16 x, s_int16 y, s_int16 sx, s_int16 sy, u_int16 sl,
226  u_int16 sh, const drawing_area * da_opt = NULL,
227  surface * target = NULL) const
228  {
229  draw (x, y, sx, sy, sl, sh, da_opt, target);
230  }
231 
232  /**
233  * Fills an area of the surface with a given color.
234  *
235  * The color you pass to this function MUST come from a game's function
236  * (like surface::get_pix () or screen::trans_col ()), because of the
237  * screen depth dependant value of the col argument.
238  *
239  * @param x X position where to fill.
240  * @param y Y position where to fill.
241  * @param l length of the area to fill.
242  * @param h height of the area to fill.
243  * @param col color to fill the surface with.
244  * @param da_opt optionnal drawing_area to use during the fill operation.
245  *
246  */
247  void fillrect (s_int16 x, s_int16 y, u_int16 l, u_int16 h,
248  u_int32 col, drawing_area * da_opt = NULL);
249  //@}
250 
251  /**
252  * @name Pixel manipulation Methods.
253  * Use these methods to directly and quickly manipulate
254  * pixels from a surface.
255  *
256  */
257  //@{
258 
259  u_int32 map_color(const u_int8 & r, const u_int8 & g, const u_int8 & b, const u_int8 & a = 255) const;
260  void unmap_color(u_int32 col, u_int8 & r, u_int8 & g, u_int8 & b, u_int8 & a) const;
261 
262  /**
263  * Locks the surface.
264  * Sometimes you may want to access directly the pixels of a surface. This
265  * can be done with the get_pix () and put_pix () methods, thus you must
266  * ABSOLUTELY lock the surface before doing so. This function is made for
267  * that. Note that using get_pix () or put_pix () without locking the surface
268  * may result in unpredictable behavior, crashes included.
269  *
270  */
271  void lock () const
272  {
273  lock(NULL);
274  }
275 
276  /**
277  * Unlock the surface after you've worked on it's pixels with the
278  * get_pix () and put_pix () methods.
279  *
280  */
281  void unlock () const;
282 
283  /**
284  * Puts a pixel of a given color.
285  *
286  * The col parameter is specific to the current screen depth,
287  * and must come from a game's function like get_pix or
288  * screen::trans_col ().
289  *
290  * @param x X position of the pixel to change.
291  * @param y Y position of the pixel to change.
292  * @param col color to put.
293  */
294  void put_pix (u_int16 x, u_int16 y, u_int32 col);
295 
296 #ifndef SWIG
297  /**
298  * Puts a pixel of a given color.
299  *
300  * The r, g and b parameters are the hex triplets of the color
301  * to put.
302  *
303  * @param x X position of the pixel to change.
304  * @param y Y position of the pixel to change.
305  * @param r red value of the color to put.
306  * @param g green value of the color to put.
307  * @param b blue value of the color to put.
308  *
309  * @attention Not accessible from Python. Use put_pix_rgb from Python instead.
310  * @sa put_pix_rgb ()
311  *
312  */
313  void put_pix (u_int16 x, u_int16 y, u_int8 r, u_int8 g, u_int8 b)
314  {
315 #ifdef __BIG_ENDIAN__
316  put_pix (x, y, map_color(b, SDL_ALPHA_OPAQUE, g, r));
317 #else
318  put_pix (x, y, map_color(r, g, b, SDL_ALPHA_OPAQUE));
319 #endif
320  }
321 #endif
322 
323  /**
324  * Synonym of put_pix () to guarantee its access from Python.
325  *
326  * @sa put_pix ()
327  */
329  {
330  put_pix (x, y, r, g, b);
331  }
332 
333  /**
334  * Gets a pixel from the surface.
335  *
336  * The col parameter is specific to the current screen depth,
337  * and can be used with functions like put_pix ().
338  *
339  * @param x X position of the pixel to change.
340  * @param y Y position of the pixel to change.
341  * @returnl returned color.
342  */
343  u_int32 get_pix (u_int16 x, u_int16 y) const;
344 
345 #ifndef SWIG
346  /**
347  * Gets a pixel from a surface.
348  *
349  * The returned r, g and b values are the hex triplets of the color.
350  *
351  * @param x X position of the pixel to change.
352  * @param y Y position of the pixel to change.
353  * @param r red value of the color.
354  * @param g green value of the color.
355  * @param b blue value of the color.
356  *
357  * @attention Not accessible from Python. Use get_pix_rgb from Python instead.
358  * @sa get_pix_rgb ()
359  */
360  void get_pix (u_int16 x, u_int16 y, u_int8& r, u_int8& g, u_int8& b) const
361  {
362  u_int8 a;
363  u_int32 col = get_pix(x, y);
364 
365 #ifdef __BIG_ENDIAN__
366  unmap_color(col, g, r, a, b);
367 #else
368  unmap_color(col, r, g, b, a);
369 #endif
370  }
371 #endif
372 
373  /**
374  * Synonym of get_pix () to guarantee its access from Python.
375  *
376  * @sa get_pix ()
377  */
378  void get_pix_rgb (u_int16 x, u_int16 y, u_int8 r, u_int8 g, u_int8 b) const
379  {
380  get_pix (x, y, r, g, b);
381  }
382 
383  //@}
384 
385 
386 #ifndef SWIG
387  /**
388  * Surface copy (similar to copy ()).
389  *
390  * @attention Not available from Python. Use copy () from Python instead.
391  * @sa copy ()
392  */
393  surface& operator = (const surface& src);
394 #endif
395 
396  /**
397  * Synonym of operator = to guarantee its access from Python.
398  *
399  * @sa operator =
400  */
401  void copy (const surface& src)
402  {
403  *this = src;
404  }
405 
406 protected:
407 
408  /**
409  * Resize this surface. All the content will be lost.
410  *
411  * @param l new length.
412  * @param h new height.
413  */
414  void resize (u_int16 l, u_int16 h);
415 
416  /**
417  * Resets the surface to it's initial state, that is totally
418  * empty.
419  *
420  */
421  void clear ();
422 
423  void set_data (void * data, u_int16 l, u_int16 h,
424  u_int8 bytes_per_pixel = BYTES_PER_PIXEL,
425  u_int32 red_mask = R_MASK, u_int32 green_mask = G_MASK,
426  u_int32 blue_mask = B_MASK, u_int32 alpha_mask = 0);
427 
428  void * get_data (u_int8 bytes_per_pixel,
429  u_int32 red_mask, u_int32 green_mask,
430  u_int32 blue_mask, u_int32 alpha_mask) const;
431 
432 
433  /// Create a software surface backed by the (streaming) texture data.
434  SDL_Surface *to_sw_surface(SDL_Rect *rect = NULL) const;
435 
436  /// lock part of the surface specified by rect
437  void lock (SDL_Rect *rect) const;
438 
439  /// the surface
440  SDL_Texture *Surface;
441 
442  /// current scale
444 
445  /// sub-pixel offset
447 private:
448  /**
449  * Forbid copy construction.
450  *
451  */
452  surface (const surface & src);
453 
454  /// some meta-information about the surface
455  pixel_info *Info;
456 
457  /// Mask
458  bool is_masked_;
459 
460  /// Whether mask has been requested, but not yet set
461  bool mask_changed_;
462 
463  /// Per-Surface Alpha value
464  u_int8 alpha_;
465 
466  /// Whether Per-Pixel alpha is enabled
467  bool alpha_channel_;
468 
469  /// SDL_Rects used in every blitting function.
470  static SDL_Rect srcrect, dstrect;
471 
472  /// Used internally for blitting operations with drawing_areas.
473  void setup_rects (s_int16 x, s_int16 y, s_int16 sx, s_int16 sy,
474  u_int16 sl, u_int16 sh, const drawing_area * draw_to) const;
475 
476 #ifndef SWIG
477  friend class screen;
478 #endif
479 };
480 
481 #endif
void get_pix(u_int16 x, u_int16 y, u_int8 &r, u_int8 &g, u_int8 &b) const
Gets a pixel from a surface.
Definition: surface.h:360
bool has_alpha_channel() const
Returns whether the surface has an alpha channel.
Definition: surface.h:155
SDL_Texture * Surface
the surface
Definition: surface.h:440
#define u_int16
16 bits long unsigned integer
Definition: types.h:38
u_int32 BytesPerPixel
number of bytes used to represent the format
Definition: surface.h:65
void put_pix_rgb(u_int16 x, u_int16 y, u_int8 r, u_int8 g, u_int8 b)
Synonym of put_pix () to guarantee its access from Python.
Definition: surface.h:328
Class where drawables can actually be drawn to.
Definition: surface.h:85
u_int8 scale_
current scale
Definition: surface.h:443
u_int8 scale() const
Get the surfaces current scaling factor.
Definition: surface.h:163
#define u_int32
32 bits long unsigned integer
Definition: types.h:41
void put_pix(u_int16 x, u_int16 y, u_int8 r, u_int8 g, u_int8 b)
Puts a pixel of a given color.
Definition: surface.h:313
#define u_int8
8 bits long unsigned integer
Definition: types.h:35
int Pitch
the pitch of the locked Surface
Definition: surface.h:61
Declares the drawable class.
Implements "drawing zones" for drawing operations.
Definition: drawing_area.h:54
void * Pixels
the pixel data of the locked Surface
Definition: surface.h:59
void get_pix_rgb(u_int16 x, u_int16 y, u_int8 r, u_int8 g, u_int8 b) const
Synonym of get_pix () to guarantee its access from Python.
Definition: surface.h:378
Screen access is made through this class.
Definition: screen.h:48
#define s_int16
16 bits long signed integer
Definition: types.h:47
s_int16 offset_x_
sub-pixel offset
Definition: surface.h:446
bool is_masked() const
Returns whether a surface is masked or not.
Definition: surface.h:118
u_int32 Format
the format of the surface
Definition: surface.h:63
Abstract class for drawable objects manipulation.
Definition: drawable.h:59
void draw_part(s_int16 x, s_int16 y, s_int16 sx, s_int16 sy, u_int16 sl, u_int16 sh, const drawing_area *da_opt=NULL, surface *target=NULL) const
Synonym of draw () to guarantee its access from Python.
Definition: surface.h:225
void lock() const
Locks the surface.
Definition: surface.h:271
u_int8 alpha() const
Returns the alpha value of the surface.
Definition: surface.h:136
void draw(s_int16 x, s_int16 y, const drawing_area *da_opt=NULL, surface *target=NULL) const
Draw the surface.
Definition: surface.h:191
void copy(const surface &src)
Synonym of operator = to guarantee its access from Python.
Definition: surface.h:401