00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
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
00070 bool Read( GlReadBitStream* reader, KrRGBA minColor, KrRGBA bits );
00071
00072
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
00085
00086 enum {
00087 ALPHA = 0x01,
00088
00089
00090 BITS_USED = 3,
00091 MEMORYPOOL = 0x02,
00092 };
00093
00094 grinliz::Flag<U32> flags;
00095 U16 start;
00096 U16 end;
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
00121
00122
00123
00124
00125
00126
00127
00128 void DrawScaled(U8* target,
00129 KrPaintInfo* paintInfo,
00130 const grinliz::Rectangle2I& bounds,
00131 const grinliz::Rectangle2I& isect,
00132 const KrColorTransform& cForm,
00133 U32 xInc );
00134
00135
00136 bool Read( GlReadBitStream* writer, KrRGBA minColor, KrRGBA bits );
00137
00138
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,
00147
00148 BITS_USED = 2
00149 };
00150
00151 grinliz::Flag<U32> flags;
00152 int nSegments;
00153
00154 KrRleSegment* segment;
00155 };
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 class KrRle
00167 {
00168 public:
00169
00170
00171
00172 enum {
00173 ALPHA = 0x01,
00174 MEMORYPOOL = 0x02,
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,
00184 const grinliz::Rectangle2I& clipping );
00185
00186
00187 bool Read( SDL_RWops* stream );
00188
00189
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
00196 bool Write( SDL_RWops* stream );
00197
00198
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
00212
00213
00214 void CalculateBounds( const KrMatrix2& xForm,
00215 grinliz::Rectangle2I* bounds ) const;
00216
00217 bool HitTestTransformed( int x, int y, int hitFlags );
00218
00219
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
00227
00228
00229 static void SetMemoryPools( grinliz::LinearMemoryPool* _memoryPoolRgba,
00230 grinliz::LinearMemoryPool* _memoryPoolLine,
00231 grinliz::LinearMemoryPool* _memoryPoolSegment );
00232 static bool PoolOut();
00233
00234
00235
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;
00253 grinliz::Vector2I deltaHotToOrigin;
00254 grinliz::Vector2I size;
00255 grinliz::Vector2I delta;
00256 KrTexture* texture;
00257 KrCollisionMap* collisionMap;
00258 };
00259
00260
00261
00262 #endif