Changeset - r5999:c4019cc98d8a
[Not reviewed]
master
0 2 0
rubidium - 18 years ago 2007-02-13 20:57:02
rubidium@openttd.org
(svn r8712) -Codechange/cleanup: replace 'magic' constants with enums, use proper types instead of byte, uint etc., give variables more descriptive names and add some comments.
2 files changed with 83 insertions and 66 deletions:
0 comments (0 inline, 0 general)
src/rail.h
Show inline comments
 
@@ -103,29 +103,35 @@ static inline TrackBits AxisToTrackBits(
 
{
 
	return TrackToTrackBits(AxisToTrack(a));
 
}
 

	
 

	
 
/** These are a combination of tracks and directions. Values are 0-5 in one
 
 * direction (corresponding to the Track enum) and 8-13 in the other direction. */
 
 * direction (corresponding to the Track enum) and 8-13 in the other direction.
 
 * 6, 7, 14 and 15 are used to encode the reversing of road vehicles. Those
 
 * reversing track dirs are not considered to be 'valid' except in a small
 
 * corner in the road vehicle controller.
 
 */
 
typedef enum Trackdirs {
 
	TRACKDIR_BEGIN    =  0,
 
	TRACKDIR_X_NE     =  0,
 
	TRACKDIR_Y_SE     =  1,
 
	TRACKDIR_UPPER_E  =  2,
 
	TRACKDIR_LOWER_E  =  3,
 
	TRACKDIR_LEFT_S   =  4,
 
	TRACKDIR_RIGHT_S  =  5,
 
	/* Note the two missing values here. This enables trackdir -> track
 
	 * conversion by doing (trackdir & 7) */
 
	TRACKDIR_RVREV_NE =  6,
 
	TRACKDIR_RVREV_SE =  7,
 
	TRACKDIR_X_SW     =  8,
 
	TRACKDIR_Y_NW     =  9,
 
	TRACKDIR_UPPER_W  = 10,
 
	TRACKDIR_LOWER_W  = 11,
 
	TRACKDIR_LEFT_N   = 12,
 
	TRACKDIR_RIGHT_N  = 13,
 
	TRACKDIR_RVREV_SW = 14,
 
	TRACKDIR_RVREV_NW = 15,
 
	TRACKDIR_END,
 
	INVALID_TRACKDIR  = 0xFF,
 
} Trackdir;
 

	
 
/** Define basic enum properties */
 
template <> struct EnumPropsT<Trackdir> : MakeEnumPropsT<Trackdir, byte, TRACKDIR_BEGIN, TRACKDIR_END, INVALID_TRACKDIR> {};
src/roadveh_cmd.cpp
Show inline comments
 
@@ -50,23 +50,31 @@ static const uint16 _roadveh_full_adder[
 
	16,  16,   0,  88,   0,   0,   0,   0,
 
	48,  48,  48,  48,   0,   0,  64,  64,
 
	 0,  16,  16,   0,   8,   8,   8,   8,
 
	 0,   0,   0,   8,   8,   8,   8
 
};
 

	
 

	
 
static const uint16 _road_veh_fp_ax_and[4] = {
 
	0x1009, 0x16, 0x520, 0x2A00
 
/** 'Convert' the DiagDirection where a road vehicle enters to the trackdirs it can drive onto */
 
static const TrackdirBits _road_enter_dir_to_reachable_trackdirs[DIAGDIR_END] = {
 
	TRACKDIR_BIT_LEFT_N  | TRACKDIR_BIT_LOWER_E | TRACKDIR_BIT_X_NE,    // Enter from north east
 
	TRACKDIR_BIT_LEFT_S  | TRACKDIR_BIT_UPPER_E | TRACKDIR_BIT_Y_SE,    // Enter from south east
 
	TRACKDIR_BIT_UPPER_W | TRACKDIR_BIT_X_SW    | TRACKDIR_BIT_RIGHT_S, // Enter from south west
 
	TRACKDIR_BIT_RIGHT_N | TRACKDIR_BIT_LOWER_W | TRACKDIR_BIT_Y_NW     // Enter from north west
 
};
 

	
 
static const byte _road_reverse_table[4] = {
 
	6, 7, 14, 15
 
static const Trackdir _road_reverse_table[DIAGDIR_END] = {
 
	TRACKDIR_RVREV_NE, TRACKDIR_RVREV_SE, TRACKDIR_RVREV_SW, TRACKDIR_RVREV_NW
 
};
 

	
 
static const uint16 _road_pf_table_3[4] = {
 
	0x910, 0x1600, 0x2005, 0x2A
 
/** 'Convert' the DiagDirection where a road vehicle should exit to
 
 * the trackdirs it can use to drive to the exit direction*/
 
static const TrackdirBits _road_exit_dir_to_incoming_trackdirs[DIAGDIR_END] = {
 
	TRACKDIR_BIT_LOWER_W | TRACKDIR_BIT_X_SW    | TRACKDIR_BIT_LEFT_S,
 
	TRACKDIR_BIT_LEFT_N  | TRACKDIR_BIT_UPPER_W | TRACKDIR_BIT_Y_NW,
 
	TRACKDIR_BIT_RIGHT_N | TRACKDIR_BIT_UPPER_E | TRACKDIR_BIT_X_NE,
 
	TRACKDIR_BIT_RIGHT_S | TRACKDIR_BIT_LOWER_E | TRACKDIR_BIT_Y_SE
 
};
 

	
 
int GetRoadVehImage(const Vehicle* v, Direction direction)
 
{
 
	int img = v->spritenum;
 
	int image;
 
@@ -1038,66 +1046,66 @@ static inline NPFFoundTargetData PerfNPF
 
	NPFFoundTargetData ret = NPFRouteToStationOrTile(tile, trackdir, target, type, owner, railtypes);
 
	int t = NpfEndInterval(perf);
 
	DEBUG(yapf, 4, "[NPFR] %d us - %d rounds - %d open - %d closed -- ", t, 0, _aystar_stats_open_size, _aystar_stats_closed_size);
 
	return ret;
 
}
 

	
 
// Returns direction to choose
 
// or -1 if the direction is currently blocked
 
static int RoadFindPathToDest(Vehicle* v, TileIndex tile, DiagDirection enterdir)
 
/**
 
 * Returns direction to for a road vehicle to take or
 
 * INVALID_TRACKDIR if the direction is currently blocked
 
 * @param v        the vehicle to do the pathfinding for
 
 * @param tile     the where to start the pathfinding
 
 * @param enterdir the direction the vehicle enters the tile from
 
 * @return the trackdir to take
 
 */
 
static Trackdir RoadFindPathToDest(Vehicle* v, TileIndex tile, DiagDirection enterdir)
 
{
 
#define return_track(x) {best_track = x; goto found_best_track; }
 
#define return_track(x) { best_track = (Trackdir)x; goto found_best_track; }
 

	
 
	uint16 signal;
 
	uint bitmask;
 
	TileIndex desttile;
 
	FindRoadToChooseData frd;
 
	int best_track;
 
	uint best_dist, best_maxlen;
 
	uint i;
 
	Trackdir best_track;
 

	
 
	{
 
		uint32 r = GetTileTrackStatus(tile, TRANSPORT_ROAD);
 
		signal  = GB(r, 16, 16);
 
		bitmask = GB(r,  0, 16);
 
	}
 
	uint32 r  = GetTileTrackStatus(tile, TRANSPORT_ROAD);
 
	TrackdirBits signal    = (TrackdirBits)GB(r, 16, 16);
 
	TrackdirBits trackdirs = (TrackdirBits)GB(r,  0, 16);
 

	
 
	if (IsTileType(tile, MP_STREET)) {
 
		if (GetRoadTileType(tile) == ROAD_TILE_DEPOT && (!IsTileOwner(tile, v->owner) || GetRoadDepotDirection(tile) == enterdir)) {
 
			/* Road depot owned by another player or with the wrong orientation */
 
			bitmask = 0;
 
			trackdirs = TRACKDIR_BIT_NONE;
 
		}
 
	} else if (IsTileType(tile, MP_STATION) && IsRoadStopTile(tile)) {
 
		if (!IsTileOwner(tile, v->owner) || GetRoadStopDir(tile) == enterdir) {
 
			/* different station owner or wrong orientation */
 
			bitmask = 0;
 
			trackdirs = TRACKDIR_BIT_NONE;
 
		} else {
 
			/* Our station */
 
			RoadStop::Type rstype = (v->cargo_type == CT_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK;
 

	
 
			if (GetRoadStopType(tile) != rstype) {
 
				// wrong station type
 
				bitmask = 0;
 
				/* Wrong station type */
 
				trackdirs = TRACKDIR_BIT_NONE;
 
			} else {
 
				// proper station type, check if there is free loading bay
 
				/* Proper station type, check if there is free loading bay */
 
				if (!_patches.roadveh_queue &&
 
						!GetRoadStopByTile(tile, rstype)->HasFreeBay()) {
 
					// station is full and RV queuing is off
 
					bitmask = 0;
 
					/* Station is full and RV queuing is off */
 
					trackdirs = TRACKDIR_BIT_NONE;
 
				}
 
			}
 
		}
 
	}
 
	/* The above lookups should be moved to GetTileTrackStatus in the
 
	 * future, but that requires more changes to the pathfinder and other
 
	 * stuff, probably even more arguments to GTTS.
 
	 */
 

	
 
	/* remove unreachable tracks */
 
	bitmask &= _road_veh_fp_ax_and[enterdir];
 
	if (bitmask == 0) {
 
	/* Remove tracks unreachable from the enter dir */
 
	trackdirs &= _road_enter_dir_to_reachable_trackdirs[enterdir];
 
	if (trackdirs == TRACKDIR_BIT_NONE) {
 
		/* No reachable tracks, so we'll reverse */
 
		return_track(_road_reverse_table[enterdir]);
 
	}
 

	
 
	if (v->u.road.reverse_ctr != 0) {
 
		/* What happens here?? */
 
@@ -1106,40 +1114,40 @@ static int RoadFindPathToDest(Vehicle* v
 
			return_track(_road_reverse_table[enterdir]);
 
		}
 
	}
 

	
 
	desttile = v->dest_tile;
 
	if (desttile == 0) {
 
		// Pick a random track
 
		return_track(PickRandomBit(bitmask));
 
		/* We've got no destination, pick a random track */
 
		return_track(PickRandomBit(trackdirs));
 
	}
 

	
 
	// Only one track to choose between?
 
	if (!(KillFirstBit2x64(bitmask))) {
 
		return_track(FindFirstBit2x64(bitmask));
 
	/* Only one track to choose between? */
 
	if (!(KillFirstBit2x64(trackdirs))) {
 
		return_track(FindFirstBit2x64(trackdirs));
 
	}
 

	
 
	if (_patches.yapf.road_use_yapf) {
 
		Trackdir trackdir = YapfChooseRoadTrack(v, tile, enterdir);
 
		if (trackdir != INVALID_TRACKDIR) return_track(trackdir);
 
		return_track(PickRandomBit(bitmask));
 
		return_track(PickRandomBit(trackdirs));
 
	} else if (_patches.new_pathfinding_all) {
 
		NPFFindStationOrTileData fstd;
 
		NPFFoundTargetData ftd;
 
		Trackdir trackdir;
 

	
 
		NPFFillWithOrderData(&fstd, v);
 
		trackdir = DiagdirToDiagTrackdir(enterdir);
 
		//debug("Finding path. Enterdir: %d, Trackdir: %d", enterdir, trackdir);
 

	
 
		ftd = PerfNPFRouteToStationOrTile(tile - TileOffsByDiagDir(enterdir), trackdir, &fstd, TRANSPORT_ROAD, v->owner, INVALID_RAILTYPE);
 
		if (ftd.best_trackdir == 0xff) {
 
		if (ftd.best_trackdir == INVALID_TRACKDIR) {
 
			/* We are already at our target. Just do something */
 
			//TODO: maybe display error?
 
			//TODO: go straight ahead if possible?
 
			return_track(FindFirstBit2x64(bitmask));
 
			return_track(FindFirstBit2x64(trackdirs));
 
		} else {
 
			/* If ftd.best_bird_dist is 0, we found our target and ftd.best_trackdir contains
 
			the direction we need to take to get there, if ftd.best_bird_dist is not 0,
 
			we did not find our target, but ftd.best_trackdir contains the direction leading
 
			to the tile closest to our target. */
 
			return_track(ftd.best_trackdir);
 
@@ -1157,46 +1165,46 @@ static int RoadFindPathToDest(Vehicle* v
 
				dir = GetRoadStopDir(desttile);
 
do_it:;
 
				/* When we are heading for a depot or station, we just
 
				 * pretend we are heading for the tile in front, we'll
 
				 * see from there */
 
				desttile += TileOffsByDiagDir(dir);
 
				if (desttile == tile && bitmask & _road_pf_table_3[dir]) {
 
				if (desttile == tile && trackdirs & _road_exit_dir_to_incoming_trackdirs[dir]) {
 
					/* If we are already in front of the
 
					 * station/depot and we can get in from here,
 
					 * we enter */
 
					return_track(FindFirstBit2x64(bitmask & _road_pf_table_3[dir]));
 
					return_track(FindFirstBit2x64(trackdirs & _road_exit_dir_to_incoming_trackdirs[dir]));
 
				}
 
			}
 
		}
 
		// do pathfind
 
		/* Do some pathfinding */
 
		frd.dest = desttile;
 

	
 
		best_track = -1;
 
		best_dist = (uint)-1;
 
		best_maxlen = (uint)-1;
 
		i = 0;
 
		do {
 
			if (bitmask & 1) {
 
				if (best_track == -1) best_track = i; // in case we don't find the path, just pick a track
 
		best_track = INVALID_TRACKDIR;
 
		uint best_dist = (uint)-1;
 
		uint best_maxlen = (uint)-1;
 
		uint bitmask = (uint)trackdirs;
 
		for (int i = 0; bitmask != 0; bitmask >>= 1, i++) {
 
			if (HASBIT(bitmask, i)) {
 
				if (best_track == INVALID_TRACKDIR) best_track = (Trackdir)i; // in case we don't find the path, just pick a track
 
				frd.maxtracklen = (uint)-1;
 
				frd.mindist = (uint)-1;
 
				FollowTrack(tile, 0x2000 | TRANSPORT_ROAD, _road_pf_directions[i], EnumRoadTrackFindDist, NULL, &frd);
 

	
 
				if (frd.mindist < best_dist || (frd.mindist==best_dist && frd.maxtracklen < best_maxlen)) {
 
				if (frd.mindist < best_dist || (frd.mindist == best_dist && frd.maxtracklen < best_maxlen)) {
 
					best_dist = frd.mindist;
 
					best_maxlen = frd.maxtracklen;
 
					best_track = i;
 
					best_track = (Trackdir)i;
 
				}
 
			}
 
		} while (++i,(bitmask>>=1) != 0);
 
		}
 
	}
 

	
 
found_best_track:;
 

	
 
	if (HASBIT(signal, best_track)) return -1;
 
	if (HASBIT(signal, best_track)) return INVALID_TRACKDIR;
 

	
 
	return best_track;
 
}
 

	
 
static uint RoadFindPathToStop(const Vehicle *v, TileIndex tile)
 
{
 
@@ -1205,13 +1213,13 @@ static uint RoadFindPathToStop(const Veh
 
		// use YAPF
 
		dist = YapfRoadVehDistanceToTile(v, tile);
 
	} else {
 
		// use NPF
 
		NPFFindStationOrTileData fstd;
 
		Trackdir trackdir = GetVehicleTrackdir(v);
 
		assert(trackdir != 0xFF);
 
		assert(trackdir != INVALID_TRACKDIR);
 

	
 
		fstd.dest_coords = tile;
 
		fstd.station_index = INVALID_STATION; // indicates that the destination is a tile, not a station
 

	
 
		dist = NPFRouteToStationOrTile(v->tile, trackdir, &fstd, TRANSPORT_ROAD, v->owner, INVALID_RAILTYPE).best_path_dist;
 
		// change units from NPF_TILE_LENGTH to # of tiles
 
@@ -1231,13 +1239,16 @@ static const byte _road_veh_data_1[] = {
 
	20, 20, 16, 16, 0, 0, 0, 0,
 
	19, 19, 15, 15, 0, 0, 0, 0,
 
	16, 16, 12, 12, 0, 0, 0, 0,
 
	15, 15, 11, 11
 
};
 

	
 
static const byte _roadveh_data_2[4] = { 0, 1, 8, 9 };
 
/** Converts the exit direction of a depot to trackdir the vehicle is going to drive to */
 
static const Trackdir _roadveh_depot_exit_trackdir[DIAGDIR_END] = {
 
	TRACKDIR_X_NE, TRACKDIR_Y_SE, TRACKDIR_X_SW, TRACKDIR_Y_NW
 
};
 

	
 
static void RoadVehController(Vehicle *v)
 
{
 
	Direction new_dir;
 
	Direction old_dir;
 
	RoadDriveEntry rd;
 
@@ -1273,21 +1284,21 @@ static void RoadVehController(Vehicle *v
 
	if (v->current_order.type == OT_LOADING) return;
 

	
 
	if (IsRoadVehInDepot(v)) {
 
		/* Vehicle is about to leave a depot */
 
		DiagDirection dir;
 
		const RoadDriveEntry* rdp;
 
		byte rd2;
 
		Trackdir tdir;
 

	
 
		v->cur_speed = 0;
 

	
 
		dir = GetRoadDepotDirection(v->tile);
 
		v->direction = DiagDirToDir(dir);
 

	
 
		rd2 = _roadveh_data_2[dir];
 
		rdp = _road_drive_data[(_opt.road_side << 4) + rd2];
 
		tdir = _roadveh_depot_exit_trackdir[dir];
 
		rdp = _road_drive_data[(_opt.road_side << 4) + tdir];
 

	
 
		x = TileX(v->tile) * TILE_SIZE + (rdp[6].x & 0xF);
 
		y = TileY(v->tile) * TILE_SIZE + (rdp[6].y & 0xF);
 

	
 
		if (RoadVehFindCloseTo(v, x, y, v->direction) != NULL) return;
 

	
 
@@ -1295,13 +1306,13 @@ static void RoadVehController(Vehicle *v
 

	
 
		StartRoadVehSound(v);
 

	
 
		BeginVehicleMove(v);
 

	
 
		v->vehstatus &= ~VS_HIDDEN;
 
		v->u.road.state = rd2;
 
		v->u.road.state = tdir;
 
		v->u.road.frame = 6;
 

	
 
		v->cur_image = GetRoadVehImage(v, v->direction);
 
		UpdateRoadVehDeltaXY(v);
 
		SetRoadVehPosition(v,x,y);
 

	
 
@@ -1358,18 +1369,18 @@ static void RoadVehController(Vehicle *v
 
	/* Get move position data for next frame */
 
	rd = _road_drive_data[(v->u.road.state + (_opt.road_side << 4)) ^ v->u.road.overtaking][v->u.road.frame + 1];
 

	
 
	if (rd.x & 0x80) {
 
		/* Vehicle is moving to the next tile */
 
		TileIndex tile = v->tile + TileOffsByDiagDir(rd.x & 3);
 
		int dir = RoadFindPathToDest(v, tile, (DiagDirection)(rd.x & 3));
 
		Trackdir dir = RoadFindPathToDest(v, tile, (DiagDirection)(rd.x & 3));
 
		uint32 r;
 
		Direction newdir;
 
		const RoadDriveEntry *rdp;
 

	
 
		if (dir == -1) {
 
		if (dir == INVALID_TRACKDIR) {
 
			/* No path was found to destination */
 
			v->cur_speed = 0;
 
			return;
 
		}
 

	
 
again:
 
@@ -1432,19 +1443,19 @@ again:
 
		RoadZPosAffectSpeed(v, SetRoadVehPosition(v, x, y));
 
		return;
 
	}
 

	
 
	if (rd.x & 0x40) {
 
		/* Vehicle has finished turning around, it will now head back onto the same tile */
 
		int dir = RoadFindPathToDest(v, v->tile, (DiagDirection)(rd.x & 3));
 
		Trackdir dir = RoadFindPathToDest(v, v->tile, (DiagDirection)(rd.x & 3));
 
		uint32 r;
 
		int tmp;
 
		Direction newdir;
 
		const RoadDriveEntry *rdp;
 

	
 
		if (dir == -1) {
 
		if (dir == INVALID_TRACKDIR) {
 
			/* No path was found to destination */
 
			v->cur_speed = 0;
 
			return;
 
		}
 

	
 
		tmp = (_opt.road_side << 4) + dir;
0 comments (0 inline, 0 general)