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 #ifndef GRINLIZ_BITARRAY_INCLUDED
00026 #define GRINLIZ_BITARRAY_INCLUDED
00027
00028
00029 #include "gltypes.h"
00030
00031 namespace grinliz {
00032
00038 template< int WIDTH, int HEIGHT >
00039 class BitArray
00040 {
00041 public:
00042 enum {
00043 ROW_WIDTH = ( ( WIDTH+31 ) / 32 ),
00044 WORDSIZE = ROW_WIDTH * HEIGHT,
00045 };
00046
00047 BitArray() { memset( array, 0, WORDSIZE*4 ); cache = 0; }
00048
00050 U32 IsSet( int x, int y ) const {
00051 GLASSERT( x >= 0 && x < WIDTH );
00052 GLASSERT( y >= 0 && y < HEIGHT );
00053 return array[ y*ROW_WIDTH + (x>>5) ] & ( 0x1 << (x & 31));
00054 }
00056 void Set( int x, int y ) {
00057 GLASSERT( x >= 0 && x < WIDTH );
00058 GLASSERT( y >= 0 && y < HEIGHT );
00059 array[ y*ROW_WIDTH + (x>>5) ] |= ( 0x1 << ( x & 31 ) );
00060 }
00062 void Clear( int x, int y ) {
00063 GLASSERT( x >= 0 && x < WIDTH );
00064 GLASSERT( y >= 0 && y < HEIGHT );
00065 array[ y*ROW_WIDTH + (x>>5) ] &= (~( 0x1 << ( x & 31 ) ) );
00066 }
00068 void ClearRect( const Rectangle2I& rect ) {
00069
00070 for( int j=rect.min.y; j<=rect.max.y; ++j )
00071 for( int i=rect.min.x; i<=rect.max.x; ++i )
00072 Clear( i, j );
00073 }
00075 void SetRect( const Rectangle2I& rect ) {
00076
00077 for( int j=rect.min.y; j<=rect.max.y; ++j )
00078 for( int i=rect.min.x; i<=rect.max.x; ++i )
00079 Set( i, j );
00080 }
00082 bool IsRectEmpty( const Rectangle2I& rect ) const {
00083
00084 for( int j=rect.min.y; j<=rect.max.y; ++j )
00085 for( int i=rect.min.x; i<=rect.max.x; ++i )
00086 if ( IsSet( i, j ) )
00087 return false;
00088 return true;
00089 }
00090
00092 bool IsRectSet( const Rectangle2I& rect ) const {
00093
00094 for( int j=rect.min.y; j<=rect.max.y; ++j )
00095 for( int i=rect.min.x; i<=rect.max.x; ++i )
00096 if ( !IsSet( i, j ) )
00097 return false;
00098 return true;
00099 }
00101 void ClearAll() { memset( array, 0, WORDSIZE*4 ); }
00103 void SetAll() { memset( array, 0xff, WORDSIZE*4 ); }
00104
00106 void CacheY( int y ) { cache = &array[ROW_WIDTH*y]; }
00108 U32 IsSetCache( int x ) { return cache[ x>>5 ] & ( 0x1 << (x & 31)); }
00109
00110
00111 U32 array[ WORDSIZE ];
00112 U32* cache;
00113 };
00114
00118 template< int WIDTH, int HEIGHT >
00119 class BitArrayRowIterator
00120 {
00121 public:
00122 BitArrayRowIterator( const BitArray<WIDTH, HEIGHT>& _array ) : bitArray( _array ), mask( 0 ), loc( 0 ) {}
00123
00125 void Begin( int x, int y) { loc = &bitArray.array[ y*bitArray.ROW_WIDTH + (x/32) ];
00126 U32 bit = x & 31;
00127 mask = 0x01 << bit;
00128 }
00130 void Next() { mask <<= 1;
00131 if ( !mask ) {
00132 mask = 0x01;
00133 ++loc;
00134 }
00135 }
00137 U32 IsSet() { return ( *loc ) & ( mask ); }
00139 bool WordEmpty() { return !(*loc); }
00140
00141 private:
00142 const BitArray<WIDTH, HEIGHT>& bitArray;
00143 U32 mask;
00144 const U32 *loc;
00145 };
00146 };
00147 #endif
00148