@ -57,7 +57,30 @@
# include "safeguards.h"
# define GEN_HASH(x, y) ((GB((y), 6 + ZOOM_LVL_SHIFT, 6) << 6) + GB((x), 7 + ZOOM_LVL_SHIFT, 6))
/* Number of bits in the hash to use from each vehicle coord */
static const uint GEN_HASHX_BITS = 6 ;
static const uint GEN_HASHY_BITS = 6 ;
/* Size of each hash bucket */
static const uint GEN_HASHX_BUCKET_BITS = 7 ;
static const uint GEN_HASHY_BUCKET_BITS = 6 ;
/* Compute hash for vehicle coord */
# define GEN_HASHX(x) GB((x), GEN_HASHX_BUCKET_BITS + ZOOM_LVL_SHIFT, GEN_HASHX_BITS)
# define GEN_HASHY(y) (GB((y), GEN_HASHY_BUCKET_BITS + ZOOM_LVL_SHIFT, GEN_HASHY_BITS) << GEN_HASHX_BITS)
# define GEN_HASH(x, y) (GEN_HASHY(y) + GEN_HASHX(x))
/* Maximum size until hash repeats */
static const int GEN_HASHX_SIZE = 1 < < ( GEN_HASHX_BUCKET_BITS + GEN_HASHX_BITS + ZOOM_LVL_SHIFT ) ;
static const int GEN_HASHY_SIZE = 1 < < ( GEN_HASHY_BUCKET_BITS + GEN_HASHY_BITS + ZOOM_LVL_SHIFT ) ;
/* Increments to reach next bucket in hash table */
static const int GEN_HASHX_INC = 1 ;
static const int GEN_HASHY_INC = 1 < < GEN_HASHX_BITS ;
/* Mask to wrap-around buckets */
static const uint GEN_HASHX_MASK = ( 1 < < GEN_HASHX_BITS ) - 1 ;
static const uint GEN_HASHY_MASK = ( ( 1 < < GEN_HASHY_BITS ) - 1 ) < < GEN_HASHX_BITS ;
VehicleID _new_vehicle_id ;
uint16 _returned_refit_capacity ; ///< Stores the capacity after a refit operation.
@ -618,7 +641,7 @@ static void UpdateVehicleTileHash(Vehicle *v, bool remove)
v - > hash_tile_current = new_hash ;
}
static Vehicle * _vehicle_viewport_hash [ 0x1000 ] ;
static Vehicle * _vehicle_viewport_hash [ 1 < < ( GEN_HASHX_BITS + GEN_HASHY_BITS ) ] ;
static void UpdateVehicleViewportHash ( Vehicle * v , int x , int y )
{
@ -1088,26 +1111,26 @@ void ViewportAddVehicles(DrawPixelInfo *dpi)
/* The hash area to scan */
int xl , xu , yl , yu ;
if ( dpi - > width + ( 70 * ZOOM_LVL_BASE ) < ( 1 < < ( 7 + 6 + ZOOM_LVL_SHIFT ) ) ) {
xl = G B( l - ( 70 * ZOOM_LVL_BASE ) , 7 + ZOOM_LVL_SHIFT , 6 ) ;
xu = G B( r , 7 + ZOOM_LVL_SHIFT , 6 ) ;
if ( dpi - > width + ( MAX_VEHICLE_PIXEL_X * ZOOM_LVL_BASE ) < GEN_HASHX_SIZE ) {
xl = G EN_HASHX( l - MAX_VEHICLE_PIXEL_X * ZOOM_LVL_BASE ) ;
xu = G EN_HASHX( r ) ;
} else {
/* scan whole hash row */
xl = 0 ;
xu = 0x3F ;
xu = GEN_HASHX_MASK ;
}
if ( dpi - > height + ( 70 * ZOOM_LVL_BASE ) < ( 1 < < ( 6 + 6 + ZOOM_LVL_SHIFT ) ) ) {
yl = G B( t - ( 70 * ZOOM_LVL_BASE ) , 6 + ZOOM_LVL_SHIFT , 6 ) < < 6 ;
yu = G B( b , 6 + ZOOM_LVL_SHIFT , 6 ) < < 6 ;
if ( dpi - > height + ( MAX_VEHICLE_PIXEL_Y * ZOOM_LVL_BASE ) < GEN_HASHY_SIZE ) {
yl = G EN_HASHY( t - MAX_VEHICLE_PIXEL_Y * ZOOM_LVL_BASE ) ;
yu = G EN_HASHY( b ) ;
} else {
/* scan whole column */
yl = 0 ;
yu = 0x3F < < 6 ;
yu = GEN_HASHY_MASK ;
}
for ( int y = yl ; ; y = ( y + ( 1 < < 6 ) ) & ( 0x3F < < 6 ) ) {
for ( int x = xl ; ; x = ( x + 1 ) & 0x3F ) {
for ( int y = yl ; ; y = ( y + GEN_HASHY_INC ) & GEN_HASHY_MASK ) {
for ( int x = xl ; ; x = ( x + GEN_HASHX_INC ) & GEN_HASHX_MASK ) {
const Vehicle * v = _vehicle_viewport_hash [ x + y ] ; // already masked & 0xFFF
while ( v ! = NULL ) {