Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //
- #define INDEX( Z, X, Y ) Z->data[ (X) + ((Y) * Z->width) ]
- #define ISWALL( Z, X, Y ) ((Z->data[ (X) + ((Y) * Z->width) ] & cWall ) > 0 )
- //
- void preprocess( sMapInfo *map )
- {
- // mask out all push data
- for ( uint32 i=0; i<map->width * map->height; i++ )
- map->data[ i ] &= 0xF0;
- // vertical process
- for ( uint32 x=0; x < map->width; x++ )
- {
- // check if is wall
- int prev = ISWALL( map, x, 0 );
- //
- for ( uint32 y=1; y < map->height; y++ )
- {
- // sample the current tile
- int cur = ISWALL( map, x, y );
- // check for a wall gradient
- switch (cur - prev)
- {
- case ( -1 ): INDEX( map, x, y-1 ) |= cQLower; break;
- case ( 1 ): INDEX( map, x, y ) |= cQUpper; break;
- }
- //
- prev = cur;
- }
- }
- // horozontal process
- for ( uint32 y=0; y < map->height; y++ )
- {
- // check if is wall
- int prev = ISWALL( map, 0, y );
- //
- for ( uint32 x=1; x < map->width; x++ )
- {
- // sample the current tile
- int cur = ISWALL( map, x, y );
- // check for a wall gradient
- switch (cur - prev)
- {
- case ( -1 ): INDEX( map, x-1, y ) |= cQRight; break;
- case ( 1 ): INDEX( map, x , y ) |= cQLeft ; break;
- }
- //
- prev = cur;
- }
- }
- }
- //
- int limiti( int min, int cur, int max )
- {
- if ( cur < min ) return min;
- if ( cur > max ) return max;
- return cur;
- }
- //
- int absi( int a )
- {
- if ( a < 0 ) return -a;
- return a;
- }
- //
- int select_from_absmin( int a, int b )
- {
- int i = a;
- int j = b;
- if ( a < 0 ) a = -a;
- if ( b < 0 ) a = -b;
- if ( a < b ) return i;
- return j;
- }
- //
- bool collide( sMapInfo *map, sCollideInfo *info )
- {
- //
- int ts = map->tileSize;
- //
- int x1 = info->px - (info->w / 2);
- int y1 = info->py - (info->h / 2);
- int x2 = x1 + info->w;
- int y2 = y1 + info->h;
- // comvert into clipped map space
- x1 = limiti( 0, x1 / ts, map->width -1 );
- x2 = limiti( 0, x2 / ts, map->width -1 );
- y1 = limiti( 0, y1 / ts, map->height-1 );
- y2 = limiti( 0, y2 / ts, map->height-1 );
- //
- int dp_x = 0xFFFF;
- int dp_y = 0xFFFF;
- //
- for ( int y=y1; y<=y2; y++ )
- {
- for ( int x=x1; x<=x2; x++ )
- {
- // extract this tile
- uint8 tile = map->data[ x + y*map->width ];
- // skip if not a blocking tile
- if ( (tile & cWall) == 0 )
- continue;
- //
- int quad[4] = { 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF };
- // find all of the splits
- if ( (tile & cQUpper) != 0 ) quad[0] = (y *ts) - (info->py + info->h / 2);
- if ( (tile & cQLower) != 0 ) quad[1] = ((y+1)*ts) - (info->py - info->h / 2);
- if ( (tile & cQLeft ) != 0 ) quad[2] = (x *ts) - (info->px + info->w / 2);
- if ( (tile & cQRight) != 0 ) quad[3] = ((x+1)*ts) - (info->px - info->w / 2);
- // select each quadrant from comparison of their abs min
- quad[0] = select_from_absmin( quad[0], quad[1] );
- quad[2] = select_from_absmin( quad[2], quad[3] );
- // select the smallest split axis from this tile
- if ( absi( quad[2] ) < absi( quad[0] ) )
- {
- // x - axis
- // save if smaller then our current split
- if ( absi( quad[2] ) < absi( dp_x ) ) dp_x = quad[2];
- }
- else
- {
- // y - axis
- // save if smaller then our current split
- if ( absi( quad[0] ) < absi( dp_y ) ) dp_y = quad[0];
- }
- }
- }
- // resolve a split on any axis
- if ( dp_x != 0xFFFF ) info->px += dp_x;
- if ( dp_y != 0xFFFF ) info->py += dp_y;
- // did we have a split
- return (dp_x != 0xFFFF) || (dp_y != 0xFFFF);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement