vehicle.c
changeset 4174 0b13c25586f7
parent 4165 2b5f642aa2bf
child 4175 b79ec8a94d4e
equal deleted inserted replaced
4173:0744150b6ffc 4174:0b13c25586f7
    31 #include "water_map.h"
    31 #include "water_map.h"
    32 #include "network.h"
    32 #include "network.h"
    33 #include "yapf/yapf.h"
    33 #include "yapf/yapf.h"
    34 
    34 
    35 #define INVALID_COORD (-0x8000)
    35 #define INVALID_COORD (-0x8000)
    36 #define GEN_HASH(x,y) (((x & 0x1F80)>>7) + ((y & 0xFC0)))
    36 #define GEN_HASH(x, y) ((GB((y), 6, 6) << 6) + GB((x), 7, 6))
    37 
    37 
    38 /*
    38 /*
    39  *	These command macros are used to call vehicle type specific commands with non type specific commands
    39  *	These command macros are used to call vehicle type specific commands with non type specific commands
    40  *	it should be used like: DoCommandP(x, y, p1, p2, flags, CMD_STARTSTOP_VEH(v->type))
    40  *	it should be used like: DoCommandP(x, y, p1, p2, flags, CMD_STARTSTOP_VEH(v->type))
    41  *	that line will start/stop a vehicle nomatter what type it is
    41  *	that line will start/stop a vehicle nomatter what type it is
   359 
   359 
   360 static VehicleID _vehicle_position_hash[0x1000];
   360 static VehicleID _vehicle_position_hash[0x1000];
   361 
   361 
   362 void *VehicleFromPos(TileIndex tile, void *data, VehicleFromPosProc *proc)
   362 void *VehicleFromPos(TileIndex tile, void *data, VehicleFromPosProc *proc)
   363 {
   363 {
   364 	int x,y,x2,y2;
       
   365 	Point pt = RemapCoords(TileX(tile) * TILE_SIZE, TileY(tile) * TILE_SIZE, 0);
   364 	Point pt = RemapCoords(TileX(tile) * TILE_SIZE, TileY(tile) * TILE_SIZE, 0);
   366 
   365 
   367 	x2 = ((pt.x + 104) & 0x1F80) >> 7;
   366 	// The hash area to scan
   368 	x  = ((pt.x - 174) & 0x1F80) >> 7;
   367 	const int xl = GB(pt.x - 174, 7, 6);
   369 
   368 	const int xu = GB(pt.x + 104, 7, 6);
   370 	y2 = ((pt.y + 56) & 0xFC0);
   369 	const int yl = GB(pt.y - 294, 6, 6) << 6;
   371 	y  = ((pt.y - 294) & 0xFC0);
   370 	const int yu = GB(pt.y +  56, 6, 6) << 6;
   372 
   371 
   373 	for (;;) {
   372 	int x;
   374 		int xb = x;
   373 	int y;
   375 		for (;;) {
   374 
       
   375 	for (y = yl;; y = (y + (1 << 6)) & (0x3F << 6)) {
       
   376 		for (x = xl;; x = (x + 1) & 0x3F) {
   376 			VehicleID veh = _vehicle_position_hash[(x + y) & 0xFFFF];
   377 			VehicleID veh = _vehicle_position_hash[(x + y) & 0xFFFF];
       
   378 
   377 			while (veh != INVALID_VEHICLE) {
   379 			while (veh != INVALID_VEHICLE) {
   378 				Vehicle *v = GetVehicle(veh);
   380 				Vehicle *v = GetVehicle(veh);
   379 				void *a;
   381 				void* a = proc(v, data);
   380 
   382 
   381 				a = proc(v, data);
       
   382 				if (a != NULL) return a;
   383 				if (a != NULL) return a;
   383 				veh = v->next_hash;
   384 				veh = v->next_hash;
   384 			}
   385 			}
   385 
   386 
   386 			if (x == x2)
   387 			if (x == xu) break;
   387 				break;
   388 		}
   388 
   389 
   389 			x = (x + 1) & 0x3F;
   390 		if (y == yu) break;
   390 		}
       
   391 		x = xb;
       
   392 
       
   393 		if (y == y2)
       
   394 			break;
       
   395 
       
   396 		y = (y + 0x40) & ((0x3F) << 6);
       
   397 	}
   391 	}
   398 	return NULL;
   392 	return NULL;
   399 }
   393 }
   400 
   394 
   401 
   395 
   435 	}
   429 	}
   436 }
   430 }
   437 
   431 
   438 void InitializeVehicles(void)
   432 void InitializeVehicles(void)
   439 {
   433 {
   440 	int i;
   434 	uint i;
   441 
   435 
   442 	/* Clean the vehicle pool, and reserve enough blocks
   436 	/* Clean the vehicle pool, and reserve enough blocks
   443 	 *  for the special vehicles, plus one for all the other
   437 	 *  for the special vehicles, plus one for all the other
   444 	 *  vehicles (which is increased on-the-fly) */
   438 	 *  vehicles (which is increased on-the-fly) */
   445 	CleanPool(&_vehicle_pool);
   439 	CleanPool(&_vehicle_pool);
   446 	AddBlockToPool(&_vehicle_pool);
   440 	AddBlockToPool(&_vehicle_pool);
   447 	for (i = 0; i < BLOCKS_FOR_SPECIAL_VEHICLES; i++)
   441 	for (i = 0; i < BLOCKS_FOR_SPECIAL_VEHICLES; i++)
   448 		AddBlockToPool(&_vehicle_pool);
   442 		AddBlockToPool(&_vehicle_pool);
   449 
   443 
   450 	// clear it...
   444 	for (i = 0; i < lengthof(_vehicle_position_hash); i++) {
   451 	memset(_vehicle_position_hash, -1, sizeof(_vehicle_position_hash));
   445 		_vehicle_position_hash[i] = INVALID_VEHICLE;
       
   446 	}
   452 }
   447 }
   453 
   448 
   454 Vehicle *GetLastVehicleInChain(Vehicle *v)
   449 Vehicle *GetLastVehicleInChain(Vehicle *v)
   455 {
   450 {
   456 	while (v->next != NULL) v = v->next;
   451 	while (v->next != NULL) v = v->next;
   738 		v->sprite_width, v->sprite_height, v->z_height, v->z_pos);
   733 		v->sprite_width, v->sprite_height, v->z_height, v->z_pos);
   739 }
   734 }
   740 
   735 
   741 void ViewportAddVehicles(DrawPixelInfo *dpi)
   736 void ViewportAddVehicles(DrawPixelInfo *dpi)
   742 {
   737 {
   743 	int x,xb, y, x2, y2;
   738 	// The bounding rectangle
   744 	VehicleID veh;
   739 	const int l = dpi->left;
   745 	Vehicle *v;
   740 	const int r = dpi->left + dpi->width;
   746 
   741 	const int t = dpi->top;
   747 	x  = ((dpi->left - 70) & 0x1F80) >> 7;
   742 	const int b = dpi->top + dpi->height;
   748 	x2 = ((dpi->left + dpi->width) & 0x1F80) >> 7;
   743 
   749 
   744 	// The hash area to scan
   750 	y  = ((dpi->top - 70) & 0xFC0);
   745 	const int xl = GB(l - 70, 7, 6);
   751 	y2 = ((dpi->top + dpi->height) & 0xFC0);
   746 	const int xu = GB(r,      7, 6);
   752 
   747 	const int yl = GB(t - 70, 6, 6) << 6;
   753 	for (;;) {
   748 	const int yu = GB(b,      6, 6) << 6;
   754 		xb = x;
   749 
   755 		for (;;) {
   750 	int x;
   756 			veh = _vehicle_position_hash[(x + y) & 0xFFFF];
   751 	int y;
       
   752 
       
   753 	for (y = yl;; y = (y + (1 << 6)) & (0x3F << 6)) {
       
   754 		for (x = xl;; x = (x + 1) & 0x3F) {
       
   755 			VehicleID veh = _vehicle_position_hash[(x + y) & 0xFFFF];
       
   756 
   757 			while (veh != INVALID_VEHICLE) {
   757 			while (veh != INVALID_VEHICLE) {
   758 				v = GetVehicle(veh);
   758 				const Vehicle* v = GetVehicle(veh);
   759 
   759 
   760 				if (!(v->vehstatus & VS_HIDDEN) &&
   760 				if (!(v->vehstatus & VS_HIDDEN) &&
   761 						dpi->left <= v->right_coord &&
   761 						l <= v->right_coord &&
   762 						dpi->top <= v->bottom_coord &&
   762 						t <= v->bottom_coord &&
   763 						dpi->left + dpi->width >= v->left_coord &&
   763 						r >= v->left_coord &&
   764 						dpi->top + dpi->height >= v->top_coord) {
   764 						b >= v->top_coord) {
   765 					DoDrawVehicle(v);
   765 					DoDrawVehicle(v);
   766 				}
   766 				}
   767 				veh = v->next_hash;
   767 				veh = v->next_hash;
   768 			}
   768 			}
   769 
   769 
   770 			if (x == x2) break;
   770 			if (x == xu) break;
   771 			x = (x + 1) & 0x3F;
   771 		}
   772 		}
   772 
   773 		x = xb;
   773 		if (y == yu) break;
   774 
       
   775 		if (y == y2) break;
       
   776 		y = (y + 0x40) & ((0x3F) << 6);
       
   777 	}
   774 	}
   778 }
   775 }
   779 
   776 
   780 static void ChimneySmokeInit(Vehicle *v)
   777 static void ChimneySmokeInit(Vehicle *v)
   781 {
   778 {