- Main Page
- Classes
- Files
- Directories
- Related Pages

# rle.h

    00001 /*--License:
    00002         Kyra Sprite Engine
    00003         Copyright Lee Thomason (Grinning Lizard Software) 2001-2005
    00004         www.grinninglizard.com/kyra
    00005         www.sourceforge.net/projects/kyra
    00006
    00007         Kyra is provided under the LGPL.
    00008
    00009         I kindly request you display a splash screen (provided in the HTML documentation)
    00010         to promote Kyra and acknowledge the software and everyone who has contributed to it,
    00011         but it is not required by the license.
    00012
    00013 --- LGPL License --
    00014
    00015     This library is free software; you can redistribute it and/or
    00016     modify it under the terms of the GNU Lesser General Public
    00017     License as published by the Free Software Foundation; either
    00018     version 2.1 of the License, or (at your option) any later version.
    00019
    00020     This library is distributed in the hope that it will be useful,
    00021     but WITHOUT ANY WARRANTY; without even the implied warranty of
    00022     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00023     Lesser General Public License for more details.
    00024
    00025     You should have received a copy of the GNU Lesser General Public
    00026     License along with this library; if not, write to the Free Software
    00027     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    00028
    00029         The full text of the license can be found in lgpl.txt
    00030 */
    00031
    00032 #ifndef KYRA_RLE_INCLUDED
    00033 #define KYRA_RLE_INCLUDED
    00034
    00035 #include <stdlib.h>
    00036
    00037 #include "../../grinliz/gltypes.h"
    00038 #include "../../grinliz/gldebug.h"
    00039 #include "../engine/krmath.h"
    00040 #include "../../grinliz/glmemorypool.h"
    00041 #include "../util/glbitstream.h"
    00042 #include "../../grinliz/glgeometry.h"
    00043 #include "SDL.h"
    00044 #include "painter.h"
    00045
    00046 class KrCanvasResource;
    00047 class KrTexture;
    00048 class KrCollisionMap;
    00049
    00050
    00051
    00052 class KrRleSegment
    00053 {
    00054         friend class KrRle;
    00055   public:
    00056         KrRleSegment()  : start( 0 ), end( 0 ), rgba( 0 )       {}
    00057         ~KrRleSegment();
    00058
    00059         void Clear()    { start = 0; end = 0; rgba = 0; }
    00060
    00061         U32                             Alpha()         { return flags.IsSet( ALPHA ); }
    00062         U16                             Start()         { return start; }
    00063         U16                             End()           { return end; }
    00064         U16                             Len()           { return end - start + 1; }
    00065
    00066         KrRGBA*                 RGBA()      { return rgba; }
    00067         grinliz::Flag<U32>              Flags()         { return flags; }
    00068
    00069         // For creating the RLE in the reader.
    00070         bool Read( GlReadBitStream* reader, KrRGBA minColor, KrRGBA bits );
    00071
    00072         // For creating the RLE
    00073         bool Create( KrPaintInfo* surface,
    00074                                  int x, int xMax, int y, int objectOriginX );
    00075
    00076         bool Write( GlWriteBitStream* writer, KrRGBA minColor, KrRGBA bits );
    00077         void CalcRange( KrRGBA* minColor, KrRGBA* maxColor );
    00078
    00079         #ifdef DEBUG
    00080                 static U32 numRGBA;
    00081         #endif
    00082
    00083   protected:
    00084 //      static LinearMemoryPool*        memoryPool;
    00085
    00086         enum {
    00087                 ALPHA =                 0x01,
    00088                 //COMPRESS8BIT =        0x02,   // Set if we can write the length and skip in 8 bits.
    00089
    00090                 BITS_USED =     3,                      // For compression.
    00091                 MEMORYPOOL =    0x02,           // Is the rgba out of a memory pool?
    00092         };
    00093
    00094         grinliz::Flag<U32>      flags;
    00095         U16                     start;          // measured from the start of the line, which can be a surprise.
    00096         U16                     end;            // measured from the start of the line
    00097         KrRGBA*         rgba;
    00098 };
    00099
    00100
    00101 class KrRleLine
    00102 {
    00103         friend class KrRle;
    00104   public:
    00105         KrRleLine()     :               nSegments( 0 ), segment( 0 ) {}
    00106         ~KrRleLine()            { if (!flags.IsSet( MEMORYPOOL ) ) delete [] segment; }
    00107
    00108         void                    Clear()                 {       nSegments = 0; segment = 0; }
    00109         U32                             Alpha()                 {       return flags.IsSet( ALPHA ); }
    00110         int                             NumSegments()   {       return nSegments; }
    00111         KrRleSegment*   Segment( int i ){       GLASSERT( i < nSegments );
    00112                                                                                 GLASSERT( segment );
    00113                                                                                 return &segment[i]; }
    00114         int                             CalcSize()              {       if ( nSegments )
    00115                                                                                         return ( segment[ nSegments-1 ].End() - segment[ 0 ].Start() + 1 );
    00116                                                                                 else
    00117                                                                                         return 0; }
    00118
    00119         /*
    00120         Pushed to the RLE
    00121         void Draw( U8* target,                          // pointer to beginning of scanline
    00122                            KrPaintInfo* paintInfo,
    00123                            const grinliz::Rectangle2I& bounds,  // bounds of the RLE
    00124                            const grinliz::Rectangle2I& isect,           // intersection of the RLE and DirtyRectangle
    00125                            const KrColorTransform& cForm );     // color transform to use
    00126         */
    00127
    00128         void DrawScaled(U8* target,                             // pointer to beginning of line (will be offset from here.)
    00129                                         KrPaintInfo* paintInfo,
    00130                                         const grinliz::Rectangle2I& bounds,     // bounds of the RLE
    00131                                         const grinliz::Rectangle2I& isect,              // intersection of the RLE and DirtyRectangle
    00132                                         const KrColorTransform& cForm,  // color transform to use
    00133                                         U32 xInc );
    00134
    00135         // For creating the RLE in the reader.
    00136         bool Read( GlReadBitStream* writer, KrRGBA minColor, KrRGBA bits );
    00137
    00138         // For creating the RLE
    00139         bool Create( KrPaintInfo* surface, int x, int y, int w );
    00140         bool Write( GlWriteBitStream* writer, KrRGBA minColor, KrRGBA bits );
    00141         void CalcRange( KrRGBA* minColor, KrRGBA* maxColor );
    00142
    00143   protected:
    00144         enum {
    00145                 ALPHA =                 0x01,
    00146                 MEMORYPOOL =    0x02,           // Is the semgment allocated out of a pool?
    00147
    00148                 BITS_USED = 2
    00149         };
    00150
    00151         grinliz::Flag<U32>              flags;
    00152         int                             nSegments;
    00153
    00154         KrRleSegment*   segment;
    00155 };
    00156
    00157
    00158 /*      A basic drawing thing. A Run length encoded image.
    00159
    00160         WARNING: The KrAction::GrowFrameArray copies these things
    00161         like structures. It is careful to 0 out old memory, but if
    00162         anything ever has a pointer *back* to the Rle, the pointers
    00163         will be trashed. Could be fixed with a proper copy constructor,
    00164         although that would be difficult.
    00165 */
    00166 class KrRle
    00167 {
    00168   public:
    00169         // The flags are never used directly by the engine code using
    00170         // this class. However, the tile code is borrowing id's
    00171         // for consistency.
    00172         enum {
    00173                 ALPHA =         0x01,
    00174                 MEMORYPOOL = 0x02,      // is the line out of a memory pool?
    00175         };
    00176
    00177         KrRle() : line( 0 ), texture( 0 ), collisionMap( 0 )
    00178                                                                 { deltaHotToOrigin.Zero(); size.Zero(); delta.Zero(); }
    00179         ~KrRle();
    00180
    00181         void Draw( KrPaintInfo* paintInfo,
    00182                            const KrMatrix2& matrix,
    00183                            const KrColorTransform& cForm,       // color transform to use
    00184                            const grinliz::Rectangle2I& clipping );
    00185
    00186         // Reads the RLE from a stream. Returns true if not empty.
    00187         bool Read( SDL_RWops* stream );
    00188
    00189         // The encoder uses this to create the sprite. Returns true if not empty.
    00190         bool Create( KrPaintInfo* surface,
    00191                                  int x, int y, int width, int height,
    00192                                  int hotx, int hoty,
    00193                                  int deltax, int deltay );
    00194
    00195         // Writes the RLE sprite to the stream.
    00196         bool Write( SDL_RWops* stream );
    00197
    00198         // The x and y "step" for this sprite.
    00199         const grinliz::Vector2I& StepSize()     const   { return delta; }
    00200
    00201         int Width()     const   { return size.x; }
    00202         int Height() const      { return size.y; }
    00203
    00204         bool Alpha() const      { return flags.IsSet( ALPHA ) ? true : false; }
    00205         const grinliz::Vector2I& Delta() const                  { return delta; }
    00206         grinliz::Vector2I                Hotspot() const                {       grinliz::Vector2I hot = deltaHotToOrigin;
    00207                                                                                                 hot.x = -hot.x; hot.y = -hot.y;
    00208                                                                                                 return hot;
    00209                                                                                         }
    00210
    00211         /*      Given a hotspot x and y, return the bounding box
    00212                 for the rle.
    00213         */
    00214         void CalculateBounds( const KrMatrix2& xForm,
    00215                                                   grinliz::Rectangle2I* bounds ) const;
    00216
    00217         bool HitTestTransformed( int x, int y, int hitFlags );
    00218
    00219         // Count all the parts of this object. Used by the encoder.
    00220         void CountComponents( U32* numLines, U32* numSegments, U32* numRGBA );
    00221
    00222         KrCanvasResource* CreateCanvasResource( int* hotx, int* hoty );
    00223         KrRle*            CreateScaledRle( GlFixed xScale, GlFixed yScale, int* hotx, int* hoty );
    00224         KrCollisionMap*   GetCollisionMap( GlFixed xScale, GlFixed yScale );
    00225
    00226         // Scary function: basically sets the global memory allocator.
    00227         // The vault will set this, allocate a bunch of sprites,
    00228         // then clear it. Will cause problems in a multi-threaded version...
    00229         static void SetMemoryPools(             grinliz::LinearMemoryPool*      _memoryPoolRgba,
    00230                                                                         grinliz::LinearMemoryPool*      _memoryPoolLine,
    00231                                                                         grinliz::LinearMemoryPool*      _memoryPoolSegment );
    00232         static bool PoolOut();
    00233
    00234         // Treat as private:
    00235         // These are NOT owned by the Rle, but the vault. Set here temporarily.
    00236         static grinliz::LinearMemoryPool*       memoryPoolRGBA;
    00237         static grinliz::LinearMemoryPool*       memoryPoolLine;
    00238         static grinliz::LinearMemoryPool*       memoryPoolSegment;
    00239
    00240   protected:
    00241         void DrawScaled(        KrPaintInfo* paintInfo,
    00242                                                 const KrMatrix2& xForm,
    00243                                                 const KrColorTransform& cForm,
    00244                                                 const grinliz::Rectangle2I& clipping );
    00245
    00246         void DrawOpenGL(        KrPaintInfo* paintInfo,
    00247                                                 const KrMatrix2& matrix,
    00248                                                 const KrColorTransform& cForm,
    00249                                                 const grinliz::Rectangle2I& clipping );
    00250
    00251         grinliz::Flag<U32>      flags;
    00252         KrRleLine*      line;                           // An array of lines, each which can (somewhat) draw themselves.
    00253         grinliz::Vector2I       deltaHotToOrigin;       // Offset between the hotspot and the start of the image
    00254         grinliz::Vector2I       size;                           // x and y extends of this RLE
    00255         grinliz::Vector2I   delta;                              // motion delta for this RLE
    00256         KrTexture*      texture;                        // used for openGL texturing
    00257         KrCollisionMap* collisionMap;
    00258 };
    00259
    00260
    00261
    00262 #endif