Adonthell 0.4
surface.h
Go to the documentation of this file.
00001 /*
00002    $Id: surface.h,v 1.9 2004/10/25 06:55:01 ksterker Exp $
00003 
00004    Copyright (C) 1999/2000/2001/2004   Alexandre Courbot
00005    Part of the Adonthell Project http://adonthell.linuxgames.com
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License.
00009    This program is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY.
00011 
00012    See the COPYING file for more details.
00013 */
00014 
00015 
00016 /**
00017  * @file   surface.h
00018  * @author Alexandre Courbot <alexandrecourbot@linuxgames.com>
00019  * 
00020  * @brief  Declares the surface class.
00021  * 
00022  * 
00023  */
00024 
00025 
00026 #ifndef SURFACE_H_
00027 #define SURFACE_H_
00028 
00029 
00030 #include "drawable.h"
00031 
00032 
00033 
00034 /**
00035  * Class where drawables can actually be drawn to.
00036  * Another name for a surface could eventually be "pixmap". A surface
00037  * is nothing more than an array of pixels where drawables can put their
00038  * %image to. This class has only two purposes: to group methods shared by
00039  * image and screen, and to ensure that every drawing operation can be performed
00040  * on the screen or on an image.
00041  *
00042  * Every surface has two special parameters:
00043  *  @li a mask parameter, indicating whether the transparent color (which hex
00044  *      triplet is 0xFF00FF, and you can get with screen::trans_col ()) should
00045  *      be drawn or not.
00046  *  @li an alpha parameter, indicating the level of translucency of the surface.
00047  *      it's range go from 0 to 255, 0 being totally invisible and 255 totally
00048  *      opaque.
00049  * 
00050  */
00051 class surface : public drawable
00052 {
00053 public:
00054 
00055     /**
00056      * Default constructor.
00057      * The surface will be totally empty, that is
00058      * (0, 0) sized, no mask, alpha value of 255 (opaque).
00059      * 
00060      */ 
00061     surface (bool mode = true);
00062 
00063     /**
00064      * Destructor.
00065      * 
00066      */
00067     virtual ~surface (); 
00068     
00069 
00070     /**
00071      * @name Settings.
00072      * These methods sets the parameters of the surface.
00073      * 
00074      */ 
00075     //@{
00076         
00077 
00078     /** 
00079      * 
00080      * Returns whether a surface is masked or not.
00081      * 
00082      * @return true if the surface is masked, false if it isn't.
00083      */
00084     bool is_masked () const
00085     {
00086         return mask_on; 
00087     }
00088 
00089     /** 
00090      * Sets the mask parameter of the surface.
00091      * 
00092      * @param m true if the surface should be masked, false otherwise.
00093      */
00094     void set_mask (bool m); 
00095     
00096     /** 
00097      * Returns the alpha value of the surface.
00098      * 
00099      * 
00100      * @return the alpha value of the surface.
00101      */
00102     u_int8 alpha () const
00103     {
00104         return alpha_; 
00105     }
00106 
00107     /** 
00108      * Sets the alpha value of the surface.
00109      * 
00110      * @param a The new alpha value for this surface.
00111      */
00112     void set_alpha (u_int8 a); 
00113     
00114     
00115     bool is_dbl_mode () const { return dbl_mode; }
00116 
00117     void set_dbl_mode (bool mode) { dbl_mode = mode; }
00118 
00119     //@}
00120 
00121 
00122     /**
00123      * @name Drawing Methods.
00124      * 
00125      */
00126 
00127     //@{
00128 
00129     
00130     /** 
00131      * Draw the surface.
00132      * 
00133      * @param x X position where to draw.
00134      * @param y Y position where to draw.
00135      * @param da_opt optional drawing_area to use during the drawing operation.
00136      * @param target pointer to the surface where to draw the drawable. If NULL, draw on the screen.
00137      */ 
00138     void draw (s_int16 x, s_int16 y, const drawing_area * da_opt = NULL,
00139                surface * target = NULL) const
00140     {
00141         draw (x, y, 0, 0, length (), height (), da_opt, target); 
00142     }
00143 
00144 #ifndef SWIG
00145     /** 
00146      * Draw a part of the surface.
00147      * 
00148      * @param x X position where to draw.
00149      * @param y Y position where to draw.
00150      * @param sx X position where to start drawing from this image.
00151      * @param sy Y position where to start drawing from this image.
00152      * @param sl length of the part of this image to draw.
00153      * @param sh height of the part of this image to draw.
00154      * @param da_opt optional drawing_area to use during the drawing operation.
00155      * @param target pointer to the surface where to draw the drawable. If NULL, draw on the screen.
00156      *
00157      * @attention Not accessible from Python. Use draw_part () from Python instead.
00158      * @sa draw_part () 
00159      *
00160      */
00161     void draw (s_int16 x, s_int16 y, s_int16 sx, s_int16 sy, u_int16 sl,
00162                u_int16 sh, const drawing_area * da_opt = NULL,
00163                surface * target = NULL) const;
00164 #endif
00165 
00166     /**
00167      * Synonym of draw () to guarantee its access from Python.
00168      *
00169      * @sa draw () 
00170      * 
00171      */ 
00172     void draw_part (s_int16 x, s_int16 y, s_int16 sx, s_int16 sy, u_int16 sl,
00173                     u_int16 sh, const drawing_area * da_opt = NULL,
00174                     surface * target = NULL) const
00175     {
00176         draw (x, y, sx, sy, sl, sh, da_opt, target); 
00177     }
00178     
00179     /** 
00180      * Fills an area of the surface with a given color.
00181      *
00182      * The color you pass to this function MUST come from a game's function
00183      * (like surface::get_pix () or screen::trans_col ()), because of the
00184      * screen depth dependant value of the col argument.
00185      * 
00186      * @param x X position where to fill.
00187      * @param y Y position where to fill.
00188      * @param l length of the area to fill.
00189      * @param h height of the area to fill.
00190      * @param col color to fill the surface with.
00191      * @param da_opt optionnal drawing_area to use during the fill operation.
00192      *
00193      */
00194     void fillrect (s_int16 x, s_int16 y, u_int16 l, u_int16 h,
00195                    u_int32 col, drawing_area * da_opt = NULL);
00196     
00197 #ifndef SWIG
00198     /** 
00199      * Fills an area of the surface with a given color.
00200      *
00201      * This function is independant of the screen depth. You just give
00202      * the red, green and blue triplets of the color you want to fill with.
00203      * 
00204      * @param x X position where to fill.
00205      * @param y Y position where to fill.
00206      * @param l length of the area to fill.
00207      * @param h height of the area to fill.
00208      * @param r red value of the color to fill with.
00209      * @param g green value of the color to fill with.
00210      * @param b blue value of the color to fill with.
00211      * @param da_opt optionnal drawing_area to use during the fill operation.
00212      *
00213      * @attention Not accessible from Python. Use fillrect_rgb from Python instead.
00214      * @sa fillrect_rgb ()  
00215      */
00216     void fillrect (s_int16 x, s_int16 y, u_int16 l, u_int16 h, u_int8 r,
00217                    u_int8 g, u_int8 b, drawing_area * da_opt = NULL)
00218     {
00219         fillrect (x, y, l, h, SDL_MapRGB (vis->format, r, g, b), da_opt);
00220     }
00221 #endif
00222 
00223     /**
00224      * Synonym of fillrect () to guarantee its access from Python.
00225      * 
00226      * @sa fillrect () 
00227      */ 
00228     void fillrect_rgb (s_int16 x, s_int16 y, u_int16 l, u_int16 h, u_int8 r,
00229                        u_int8 g, u_int8 b, drawing_area * da_opt = NULL)
00230     {
00231         fillrect (x, y, l, h, r, g, b, da_opt); 
00232     }
00233 
00234 
00235     //@}
00236 
00237     /**
00238      * @name Pixel manipulation Methods.
00239      * Use these methods to directly and quickly manipulate
00240      * pixels from a surface.
00241      * 
00242      */ 
00243     //@{
00244          
00245     
00246     /** 
00247      * Locks the surface.
00248      * Sometimes you may want to access directly the pixels of a surface. This
00249      * can be done with the get_pix ()  and put_pix () methods, thus you must
00250      * ABSOLUTELY lock the surface before doing so. This function is made for
00251      * that. Note that using get_pix () or put_pix () without locking the surface
00252      * may result in unpredictable behavior, crashes included.
00253      * 
00254      */
00255     void lock () const; 
00256     
00257     /** 
00258      * Unlock the surface after you've worked on it's pixels with the
00259      * get_pix () and put_pix () methods.
00260      * 
00261      */
00262     void unlock () const;
00263     
00264     /** 
00265      * Puts a pixel of a given color.
00266      *
00267      * The col parameter is specific to the current screen depth,
00268      * and must come from a game's function like get_pix or
00269      * screen::trans_col ().
00270      * 
00271      * @param x X position of the pixel to change.
00272      * @param y Y position of the pixel to change.
00273      * @param col color to put.
00274      */
00275     void put_pix (u_int16 x, u_int16 y, u_int32 col); 
00276 
00277 #ifndef SWIG
00278     /** 
00279      * Puts a pixel of a given color.
00280      *
00281      * The r, g and b parameters are the hex triplets of the color
00282      * to put.
00283      * 
00284      * @param x X position of the pixel to change.
00285      * @param y Y position of the pixel to change.
00286      * @param r red value of the color to put.
00287      * @param g green value of the color to put.
00288      * @param b blue value of the color to put.
00289      *
00290      * @attention Not accessible from Python. Use put_pix_rgb from Python instead.
00291      * @sa put_pix_rgb ()  
00292      *
00293      */ 
00294     void put_pix (u_int16 x, u_int16 y, u_int8 r, u_int8 g, u_int8 b) 
00295     {
00296         put_pix (x, y, SDL_MapRGB (vis->format, r, g, b)); 
00297     }
00298 #endif
00299     
00300     /**
00301      * Synonym of put_pix () to guarantee its access from Python.
00302      *
00303      * @sa put_pix () 
00304      */ 
00305     void put_pix_rgb (u_int16 x, u_int16 y, u_int8 r, u_int8 g, u_int8 b) 
00306     {
00307         put_pix (x, y, r, g, b); 
00308     }
00309     
00310     /** 
00311      * Gets a pixel from the surface.
00312      *
00313      * The col parameter is specific to the current screen depth,
00314      * and can be used with functions like put_pix ().
00315      * 
00316      * @param x X position of the pixel to change.
00317      * @param y Y position of the pixel to change.
00318      * @param col returned color.
00319      */
00320     void get_pix (u_int16 x, u_int16 y, u_int32& col) const; 
00321 
00322 #ifndef SWIG
00323     /** 
00324      * Gets a pixel from a surface.
00325      *
00326      * The returned r, g and b values are the hex triplets of the color.
00327      * 
00328      * @param x X position of the pixel to change.
00329      * @param y Y position of the pixel to change.
00330      * @param r red value of the color.
00331      * @param g green value of the color.
00332      * @param b blue value of the color.
00333      *
00334      * @attention Not accessible from Python. Use get_pix_rgb from Python instead.
00335      * @sa get_pix_rgb ()   
00336      */
00337     void get_pix (u_int16 x, u_int16 y, u_int8& r, u_int8& g, u_int8& b) const
00338     {
00339         u_int32 col;
00340         get_pix (x, y, col); 
00341         SDL_GetRGB (col, vis->format, &r, &g, &b); 
00342     }
00343 #endif
00344     
00345     /**
00346      * Synonym of get_pix () to guarantee its access from Python.
00347      *
00348      * @sa get_pix () 
00349      */ 
00350     void get_pix_rgb (u_int16 x, u_int16 y, u_int8 r, u_int8 g, u_int8 b) const
00351     {
00352         get_pix (x, y, r, g, b); 
00353     }
00354 
00355     //@}
00356     
00357     
00358 #ifndef SWIG
00359     /**
00360      * Surface copy (similar to copy ()).
00361      *
00362      * @attention Not available from Python. Use copy () from Python instead.
00363      * @sa copy ()
00364      */
00365     surface& operator = (surface& src); 
00366 #endif
00367 
00368     /**
00369      * Synonym of operator = to guarantee its access from Python.
00370      *
00371      * @sa operator = 
00372      */
00373     void copy (surface& src) 
00374     {
00375         *this = src; 
00376     }
00377          
00378     /**
00379      * The actual surface.
00380      *
00381      */
00382     SDL_Surface *vis;
00383 protected: 
00384 
00385     /** 
00386      * Resize this surface. All the content will be lost.
00387      * 
00388      * @param l new length.
00389      * @param h new height.
00390      */
00391     void resize (u_int16 l, u_int16 h);
00392 
00393     /** 
00394      * Resets the surface to it's initial state, that is totally
00395      * empty.
00396      * 
00397      */
00398     void clear (); 
00399 
00400     /**
00401      * Must be set to true when you change the surface
00402      * by something else than class surface operations.
00403      * 
00404      */ 
00405     mutable bool changed; 
00406 
00407 #ifndef SWIG
00408     void resize_aux (u_int16 l, u_int16 h);
00409     void double_size(const surface & src);
00410     void half_size(const surface & src);
00411     void get_pix_aux (u_int16 x, u_int16 y, u_int32& col) const; 
00412     void put_pix_aux (u_int16 x, u_int16 y, u_int32 col); 
00413 #endif
00414 
00415     /// double mode
00416     bool dbl_mode;    
00417      
00418 private:
00419 
00420     /**
00421      * Forbid value passing.
00422      * 
00423      */ 
00424     surface (surface & src); 
00425     
00426     /// SDL_Rects used in every blitting function.
00427     static SDL_Rect srcrect, dstrect; 
00428 
00429     /// Mask
00430     bool mask_on; 
00431 
00432     /// Alpha value
00433     u_int8 alpha_;
00434 
00435     /// Set at true by screen's contructor to prevent screen surface from
00436     /// being deleted two times.
00437     bool not_screen; 
00438 
00439     /// Used internally for blitting operations with drawing_areas.
00440     void setup_rects (u_int16 x, u_int16 y, const drawing_area * draw_to) const
00441     {
00442         setup_rects (x, y, 0, 0, length (), height (), draw_to); 
00443     }
00444     
00445     /// Used internally for blitting operations with drawing_areas.
00446     void setup_rects (s_int16 x, s_int16 y, s_int16 sx, s_int16 sy,
00447                       u_int16 sl, u_int16 sh, const drawing_area * draw_to) const; 
00448 
00449 #ifndef SWIG
00450     friend class screen;
00451 #endif
00452 };
00453 
00454 #endif