Changeset - r1944:ed1b90ae1557
[Not reviewed]
master
0 7 0
matthijs - 19 years ago 2005-06-17 00:22:46
matthijs@openttd.org
(svn r2450) * Codechange: Replaced all uses of the arrays in tile.h with calls to the associated wrapper functions.
* Codechange: Made npf.c use some map array accessing wrappers instead of direct access.
* Codechange/Fix: Named every enum in tile.h. Fixes a nasty bug on MSVC where arrays would be initialised with zeroes (tnx Asterix_)
* Removed magic numbers from tables in tile.c.
* Added some explicit casts in tile.h.
7 files changed with 146 insertions and 127 deletions:
depot.h
1
1
npf.c
28
31
rail.c
39
37
rail.h
66
47
tile.h
1
1
0 comments (0 inline, 0 general)
depot.h
Show inline comments
 
@@ -95,13 +95,13 @@ static inline DiagDirection GetDepotDire
 

	
 
	switch (type)
 
	{
 
		case TRANSPORT_RAIL:
 
		case TRANSPORT_ROAD:
 
			/* Rail and road store a diagonal direction in bits 0 and 1 */
 
			return _map5[tile] & 3;
 
			return (DiagDirection)(_map5[tile] & 3);
 
		case TRANSPORT_WATER:
 
			/* Water is stubborn, it stores the directions in a different order. */
 
			switch (_map5[tile] & 3) {
 
				case 0: return DIAGDIR_NE;
 
				case 1: return DIAGDIR_SW;
 
				case 2: return DIAGDIR_NW;
npf.c
Show inline comments
 
@@ -125,13 +125,13 @@ void NPFFillTrackdirChoice(AyStarNode* c
 
}
 

	
 
/* Will return the cost of the tunnel. If it is an entry, it will return the
 
 * cost of that tile. If the tile is an exit, it will return the tunnel length
 
 * including the exit tile. Requires that this is a Tunnel tile */
 
uint NPFTunnelCost(AyStarNode* current) {
 
	byte exitdir = _trackdir_to_exitdir[current->direction];
 
	byte exitdir = TrackdirToExitdir(current->direction);
 
	TileIndex tile = current->tile;
 
	if ( (uint)(_map5[tile] & 3) == ReverseDiagdir(exitdir)) {
 
		/* We just popped out if this tunnel, since were
 
		 * facing the tunnel exit */
 
		FindLengthOfTunnelResult flotr;
 
		flotr = FindLengthOfTunnel(tile, ReverseDiagdir(exitdir));
 
@@ -142,13 +142,13 @@ uint NPFTunnelCost(AyStarNode* current) 
 
		 * straight track */
 
		return NPF_TILE_LENGTH;
 
	}
 
}
 

	
 
uint NPFSlopeCost(AyStarNode* current) {
 
	TileIndex next = current->tile + TileOffsByDir(_trackdir_to_exitdir[current->direction]);
 
	TileIndex next = current->tile + TileOffsByDir(TrackdirToExitdir(current->direction));
 
	int x,y;
 
	int8 z1,z2;
 

	
 
	x = TileX(current->tile) * TILE_SIZE;
 
	y = TileY(current->tile) * TILE_SIZE;
 
	/* get the height of the center of the current tile */
 
@@ -203,13 +203,13 @@ int32 NPFWaterPathCost(AyStar* as, AySta
 

	
 
	cost = _trackdir_length[trackdir]; /* Should be different for diagonal tracks */
 

	
 
	if (IsBuoyTile(current->tile) && IsDiagonalTrackdir(current->direction))
 
		cost += _patches.npf_buoy_penalty; /* A small penalty for going over buoys */
 

	
 
	if (current->direction != _next_trackdir[parent->path.node.direction])
 
	if (current->direction != NextTrackdir(parent->path.node.direction))
 
		cost += _patches.npf_water_curve_penalty;
 

	
 
	/* TODO More penalties? */
 

	
 
	return cost;
 
}
 
@@ -288,22 +288,23 @@ int32 NPFRailPathCost(AyStar* as, AyStar
 
			break;
 
	}
 

	
 
	/* Determine extra costs */
 

	
 
	/* Check for signals */
 
	if (IsTileType(tile, MP_RAILWAY) && (_map5[tile] & 0xC0) == 0x40 && (_map3_lo[tile] & _signal_along_trackdir[trackdir]) != 0) {
 
	if (IsTileType(tile, MP_RAILWAY) && HasSignalOnTrackdir(tile, trackdir)) {
 
		/* Ordinary track with signals */
 
		if ((_map2[tile] & _signal_along_trackdir[trackdir]) == 0) {
 
		if (GetSignalState(tile, trackdir) == SIGNAL_STATE_RED) {
 
			/* Signal facing us is red */
 
			if (!NPFGetFlag(current, NPF_FLAG_SEEN_SIGNAL)) {
 
				/* Penalize the first signal we
 
				 * encounter, if it is red */
 

	
 
				/* Is this a presignal exit or combo? */
 
				if ((_map3_hi[tile] & 0x3) == 0x2 || (_map3_hi[tile] & 0x3) == 0x3)
 
				SignalType sigtype = GetSignalType(tile, trackdir);
 
				if (sigtype == SIGTYPE_EXIT || sigtype == SIGTYPE_COMBO)
 
					/* Penalise exit and combo signals differently (heavier) */
 
					cost += _patches.npf_rail_firstred_exit_penalty;
 
				else
 
					cost += _patches.npf_rail_firstred_penalty;
 
			}
 
			/* Record the state of this signal */
 
@@ -322,13 +323,13 @@ int32 NPFRailPathCost(AyStar* as, AyStar
 
		cost += _patches.npf_rail_lastred_penalty;
 

	
 
	/* Check for slope */
 
	cost += NPFSlopeCost(current);
 

	
 
	/* Check for turns */
 
	if (current->direction != _next_trackdir[parent->path.node.direction])
 
	if (current->direction != NextTrackdir(parent->path.node.direction))
 
		cost += _patches.npf_rail_curve_penalty;
 
	//TODO, with realistic acceleration, also the amount of straight track between
 
	//      curves should be taken into account, as this affects the speed limit.
 

	
 
	/* Check for reverse in depot */
 
	if (IsTileDepotType(tile, TRANSPORT_RAIL) && !as->EndNodeCheck(as, &new_node)==AYSTAR_FOUND_END_NODE)
 
@@ -433,26 +434,26 @@ static inline RailType GetTileRailType(T
 
 * go and where not. Uses AyStar.user_data[NPF_TYPE] as the transport type and
 
 * an argument to GetTileTrackStatus. Will skip tunnels, meaning that the
 
 * entry and exit are neighbours. Will fill
 
 * AyStarNode.user_data[NPF_TRACKDIR_CHOICE] with an appropriate value, and
 
 * copy AyStarNode.user_data[NPF_NODE_FLAGS] from the parent */
 
void NPFFollowTrack(AyStar* aystar, OpenListNode* current) {
 
	byte src_trackdir = current->path.node.direction;
 
	Trackdir src_trackdir = current->path.node.direction;
 
	TileIndex src_tile = current->path.node.tile;
 
	byte src_exitdir = _trackdir_to_exitdir[src_trackdir];
 
	DiagDirection src_exitdir = TrackdirToExitdir(src_trackdir);
 
	FindLengthOfTunnelResult flotr;
 
	TileIndex dst_tile;
 
	int i = 0;
 
	uint trackdirs, ts;
 
	TrackdirBits trackdirbits, ts;
 
	TransportType type = aystar->user_data[NPF_TYPE];
 
	/* Initialize to 0, so we can jump out (return) somewhere an have no neighbours */
 
	aystar->num_neighbours = 0;
 
	DEBUG(npf, 4)("Expanding: (%d, %d, %d) [%d]", TileX(src_tile), TileY(src_tile), src_trackdir, src_tile);
 

	
 
	/* Find dest tile */
 
	if (IsTileType(src_tile, MP_TUNNELBRIDGE) && (_map5[src_tile] & 0xF0)==0 && (_map5[src_tile] & 3) == src_exitdir) {
 
	if (IsTileType(src_tile, MP_TUNNELBRIDGE) && (_map5[src_tile] & 0xF0)==0 && (DiagDirection)(_map5[src_tile] & 3) == src_exitdir) {
 
		/* This is a tunnel. We know this tunnel is our type,
 
		 * otherwise we wouldn't have got here. It is also facing us,
 
		 * so we should skip it's body */
 
		flotr = FindLengthOfTunnel(src_tile, src_exitdir);
 
		dst_tile = flotr.tile;
 
	} else {
 
@@ -469,24 +470,24 @@ void NPFFollowTrack(AyStar* aystar, Open
 
				exitdir = GetDepotDirection(src_tile, type);
 

	
 
			/* Let's see if were headed the right way into the depot, and reverse
 
			 * otherwise (only for trains, since only with trains you can
 
			 * (sometimes) reach tiles after reversing that you couldn't reach
 
			 * without reversing. */
 
			if (src_trackdir == _dir_to_diag_trackdir[ReverseDiagdir(exitdir)] && type == TRANSPORT_RAIL)
 
			if (src_trackdir == DiagdirToDiagTrackdir(ReverseDiagdir(exitdir)) && type == TRANSPORT_RAIL)
 
				/* We are headed inwards. We can only reverse here, so we'll not
 
				 * consider this direction, but jump ahead to the reverse direction.
 
				 * It would be nicer to return one neighbour here (the reverse
 
				 * trackdir of the one we are considering now) and then considering
 
				 * that one to return the tracks outside of the depot. But, because
 
				 * the code layout is cleaner this way, we will just pretend we are
 
				 * reversed already */
 
				src_trackdir = _reverse_trackdir[src_trackdir];
 
				src_trackdir = ReverseTrackdir(src_trackdir);
 
		}
 
		/* This a normal tile, a bridge, a tunnel exit, etc. */
 
		dst_tile = AddTileIndexDiffCWrap(src_tile, TileIndexDiffCByDir(_trackdir_to_exitdir[src_trackdir]));
 
		dst_tile = AddTileIndexDiffCWrap(src_tile, TileIndexDiffCByDir(TrackdirToExitdir(src_trackdir)));
 
		if (dst_tile == INVALID_TILE) {
 
			/* We reached the border of the map */
 
			/* TODO Nicer control flow for this */
 
			return;
 
		}
 
	}
 
@@ -494,13 +495,13 @@ void NPFFollowTrack(AyStar* aystar, Open
 
	/* check correct rail type (mono, maglev, etc)
 
	 * XXX: This now compares with the previous tile, which should not pose a
 
	 * problem, but it might be nicer to compare with the first tile, or even
 
	 * the type of the vehicle... Maybe an NPF_RAILTYPE userdata sometime? */
 
	if (type == TRANSPORT_RAIL) {
 
		byte src_type = GetTileRailType(src_tile, src_trackdir);
 
		byte dst_type = GetTileRailType(dst_tile, _trackdir_to_exitdir[src_trackdir]);
 
		byte dst_type = GetTileRailType(dst_tile, TrackdirToExitdir(src_trackdir));
 
		if (src_type != dst_type) {
 
			return;
 
		}
 
	}
 

	
 
	/* Check the owner of the tile */
 
@@ -528,37 +529,33 @@ void NPFFollowTrack(AyStar* aystar, Open
 
		 * from some other tile. This prevents vehicles driving into depots from
 
		 * the back */
 
		ts = TrackdirToTrackdirBits(DiagdirToDiagTrackdir(ReverseDiagdir(exitdir)));
 
	} else {
 
		ts = GetTileTrackStatus(dst_tile, type);
 
	}
 
	trackdirs = ts & 0x3F3F; /* Filter out signal status and the unused bits */
 
	trackdirbits = ts & 0x3F3F; /* Filter out signal status and the unused bits */
 

	
 
	DEBUG(npf, 4)("Next node: (%d, %d) [%d], possible trackdirs: %#x", TileX(dst_tile), TileY(dst_tile), dst_tile, trackdirs);
 
	DEBUG(npf, 4)("Next node: (%d, %d) [%d], possible trackdirs: %#x", TileX(dst_tile), TileY(dst_tile), dst_tile, trackdirbits);
 
	/* Select only trackdirs we can reach from our current trackdir */
 
	trackdirs &= TrackdirReachesTrackdirs(src_trackdir);
 
	trackdirbits &= TrackdirReachesTrackdirs(src_trackdir);
 
	if (_patches.forbid_90_deg && (type == TRANSPORT_RAIL || type == TRANSPORT_WATER)) /* Filter out trackdirs that would make 90 deg turns for trains */
 
		trackdirs &= ~_trackdir_crosses_trackdirs[src_trackdir];
 
	DEBUG(npf,6)("After filtering: (%d, %d), possible trackdirs: %#x", TileX(dst_tile), TileY(dst_tile), trackdirs);
 
		trackdirbits &= ~TrackdirCrossesTrackdirs(src_trackdir);
 
	DEBUG(npf,6)("After filtering: (%d, %d), possible trackdirs: %#x", TileX(dst_tile), TileY(dst_tile), trackdirbits);
 

	
 
	/* Enumerate possible track */
 
	while (trackdirs != 0) {
 
	while (trackdirbits != 0) {
 
		byte dst_trackdir;
 
		dst_trackdir =  FindFirstBit2x64(trackdirs);
 
		trackdirs = KillFirstBit2x64(trackdirs);
 
		DEBUG(npf, 5)("Expanded into trackdir: %d, remaining trackdirs: %#x", dst_trackdir, trackdirs);
 
		dst_trackdir =  FindFirstBit2x64(trackdirbits);
 
		trackdirbits = KillFirstBit2x64(trackdirbits);
 
		DEBUG(npf, 5)("Expanded into trackdir: %d, remaining trackdirs: %#x", dst_trackdir, trackdirbits);
 

	
 
		/* Check for oneway signal against us */
 
		if (IsTileType(dst_tile, MP_RAILWAY) && (_map5[dst_tile]&0xC0) == 0x40) {
 
			// the tile has a signal
 
			byte signal_present = _map3_lo[dst_tile];
 
			if (!(signal_present & _signal_along_trackdir[dst_trackdir])) {
 
		if (IsTileType(dst_tile, MP_RAILWAY) && GetRailTileType(dst_tile) == RAIL_TYPE_SIGNALS) {
 
			if (HasSignalOnTrackdir(dst_tile, ReverseTrackdir(dst_trackdir)) && !HasSignalOnTrackdir(dst_tile, dst_trackdir))
 
				// if one way signal not pointing towards us, stop going in this direction.
 
				if (signal_present & _signal_against_trackdir[dst_trackdir])
 
					break;
 
			}
 
				break;
 
		}
 
		{
 
			/* We've found ourselves a neighbour :-) */
 
			AyStarNode* neighbour = &aystar->neighbours[i];
 
			neighbour->tile = dst_tile;
 
			neighbour->direction = dst_trackdir;
rail.c
Show inline comments
 
#include "rail.h"
 

	
 
/* XXX: Below 3 tables store duplicate data. Maybe remove some? */
 
/* Maps a trackdir to the bit that stores its status in the map arrays, in the
 
 * direction along with the trackdir */
 
const byte _signal_along_trackdir[] = {
 
	0x80, 0x80, 0x80, 0x20, 0x40, 0x10, 0, 0,
 
	0x40, 0x40, 0x40, 0x10, 0x80, 0x20
 
};
 
@@ -21,73 +22,74 @@ const byte _signal_on_track[] = {
 
};
 

	
 
/* Maps a diagonal direction to the all trackdirs that are connected to any
 
 * track entering in this direction (including those making 90 degree turns)
 
 */
 
const TrackdirBits _exitdir_reaches_trackdirs[] = {
 
	TRACKDIR_BIT_DIAG1_NE|TRACKDIR_BIT_LOWER_E|TRACKDIR_BIT_LEFT_N,  /* DIAGDIR_NE */
 
	TRACKDIR_BIT_DIAG2_SE|TRACKDIR_BIT_LEFT_S |TRACKDIR_BIT_UPPER_E, /* DIAGDIR_SE */
 
	TRACKDIR_BIT_DIAG1_SW|TRACKDIR_BIT_UPPER_W|TRACKDIR_BIT_RIGHT_S, /* DIAGDIR_SW */
 
	TRACKDIR_BIT_DIAG2_NW|TRACKDIR_BIT_RIGHT_N|TRACKDIR_BIT_LOWER_W  /* DIAGDIR_NW */
 
	TRACKDIR_BIT_DIAG1_NE | TRACKDIR_BIT_LOWER_E | TRACKDIR_BIT_LEFT_N,  /* DIAGDIR_NE */
 
	TRACKDIR_BIT_DIAG2_SE | TRACKDIR_BIT_LEFT_S  | TRACKDIR_BIT_UPPER_E, /* DIAGDIR_SE */
 
	TRACKDIR_BIT_DIAG1_SW | TRACKDIR_BIT_UPPER_W | TRACKDIR_BIT_RIGHT_S, /* DIAGDIR_SW */
 
	TRACKDIR_BIT_DIAG2_NW | TRACKDIR_BIT_RIGHT_N | TRACKDIR_BIT_LOWER_W  /* DIAGDIR_NW */
 
};
 

	
 
/* TODO: Remove magic numbers from tables below just like
 
 * _exitdir_reaches_trackdirs[] */
 

	
 
const Trackdir _next_trackdir[14] = {
 
	0,  1,  3,  2,  5,  4, 0, 0,
 
	8,  9,  11, 10, 13, 12
 
const Trackdir _next_trackdir[] = {
 
	TRACKDIR_DIAG1_NE,  TRACKDIR_DIAG2_SE,  TRACKDIR_LOWER_E, TRACKDIR_UPPER_E, TRACKDIR_RIGHT_S, TRACKDIR_LEFT_S, INVALID_TRACKDIR, INVALID_TRACKDIR,
 
	TRACKDIR_DIAG1_SW,  TRACKDIR_DIAG2_NW,  TRACKDIR_LOWER_W, TRACKDIR_UPPER_W, TRACKDIR_RIGHT_N, TRACKDIR_LEFT_N
 
};
 

	
 
/* Maps a trackdir to all trackdirs that make 90 deg turns with it. */
 
const TrackdirBits _trackdir_crosses_trackdirs[] = {
 
	0x0202, 0x0101, 0x3030, 0x3030, 0x0C0C, 0x0C0C, 0, 0,
 
	0x0202, 0x0101, 0x3030, 0x3030, 0x0C0C, 0x0C0C
 
const TrackdirBits _track_crosses_trackdirs[] = {
 
	TRACKDIR_BIT_DIAG2_SE | TRACKDIR_BIT_DIAG2_NW,                                               /* TRACK_DIAG1 */
 
	TRACKDIR_BIT_DIAG1_NE | TRACKDIR_BIT_DIAG1_SW,                                               /* TRACK_DIAG2 */
 
	TRACKDIR_BIT_RIGHT_N  | TRACKDIR_BIT_RIGHT_S  | TRACKDIR_BIT_LEFT_N  | TRACKDIR_BIT_LEFT_S,  /* TRACK_UPPER */
 
	TRACKDIR_BIT_RIGHT_N  | TRACKDIR_BIT_RIGHT_S  | TRACKDIR_BIT_LEFT_N  | TRACKDIR_BIT_LEFT_S,  /* TRACK_LOWER */
 
	TRACKDIR_BIT_UPPER_W  | TRACKDIR_BIT_UPPER_E  | TRACKDIR_BIT_LOWER_W | TRACKDIR_BIT_LOWER_E, /* TRACK_LEFT  */
 
	TRACKDIR_BIT_UPPER_W  | TRACKDIR_BIT_UPPER_E  | TRACKDIR_BIT_LOWER_W | TRACKDIR_BIT_LOWER_E  /* TRACK_RIGHT */
 
};
 

	
 
/* Maps a track to all tracks that make 90 deg turns with it. */
 
const TrackBits _track_crosses_tracks[] = {
 
	0x2, /* Track 1 -> Track 2 */
 
	0x1, /* Track 2 -> Track 1 */
 
	0x30, /* Upper -> Left | Right */
 
	0x30, /* Lower -> Left | Right */
 
	0x0C, /* Left -> Upper | Lower */
 
	0x0C, /* Right -> Upper | Lower */
 
	TRACK_BIT_DIAG2,                   /* TRACK_DIAG1 */
 
	TRACK_BIT_DIAG1,                   /* TRACK_DIAG2 */
 
	TRACK_BIT_LEFT  | TRACK_BIT_RIGHT, /* TRACK_UPPER */
 
	TRACK_BIT_LEFT  | TRACK_BIT_RIGHT, /* TRACK_LOWER */
 
	TRACK_BIT_UPPER | TRACK_BIT_LOWER, /* TRACK_LEFT  */
 
	TRACK_BIT_UPPER | TRACK_BIT_LOWER  /* TRACK_RIGHT */
 
};
 

	
 
/* Maps a trackdir to the (4-way) direction the tile is exited when following
 
 * that trackdir */
 
const DiagDirection _trackdir_to_exitdir[] = {
 
	0,1,0,1,2,1, 0,0,
 
	2,3,3,2,3,0,
 
	DIAGDIR_NE,DIAGDIR_SE,DIAGDIR_NE,DIAGDIR_SE,DIAGDIR_SW,DIAGDIR_SE, DIAGDIR_NE,DIAGDIR_NE,
 
	DIAGDIR_SW,DIAGDIR_NW,DIAGDIR_NW,DIAGDIR_SW,DIAGDIR_NW,DIAGDIR_NE,
 
};
 

	
 
const Trackdir _track_exitdir_to_trackdir[][DIAGDIR_END] = {
 
	{0,    0xff, 8,    0xff},
 
	{0xff, 1,    0xff, 9},
 
	{2,    0xff, 0xff, 10},
 
	{0xff, 3,    11,   0xf},
 
	{0xff, 0xff, 4,    12},
 
	{13,   5,    0xff, 0xff}
 
	{TRACKDIR_DIAG1_NE, INVALID_TRACKDIR,  TRACKDIR_DIAG1_SW, INVALID_TRACKDIR},
 
	{INVALID_TRACKDIR,  TRACKDIR_DIAG2_SE, INVALID_TRACKDIR,  TRACKDIR_DIAG2_NW},
 
	{TRACKDIR_UPPER_E,  INVALID_TRACKDIR,  INVALID_TRACKDIR,  TRACKDIR_UPPER_W},
 
	{INVALID_TRACKDIR,  TRACKDIR_LOWER_E,  TRACKDIR_LOWER_W,  INVALID_TRACKDIR},
 
	{INVALID_TRACKDIR,  INVALID_TRACKDIR,  TRACKDIR_LEFT_S,   TRACKDIR_LEFT_N},
 
	{TRACKDIR_RIGHT_N,  TRACKDIR_RIGHT_S,  INVALID_TRACKDIR,  INVALID_TRACKDIR}
 
};
 

	
 
const Trackdir _track_direction_to_trackdir[][DIR_END] = {
 
	{0xff, 0,    0xff, 0xff, 0xff, 8,    0xff, 0xff},
 
	{0xff, 0xff, 0xff, 1,    0xff, 0xff, 0xff, 9},
 
	{0xff, 0xff, 2,    0xff, 0xff, 0xff, 10,   0xff},
 
	{0xff, 0xff, 3,    0xff, 0xff, 0xff, 11,   0xff},
 
	{12,   0xff, 0xff, 0xff, 4,    0xff, 0xff, 0xff},
 
	{13,   0xff, 0xff, 0xff, 5,    0xff, 0xff, 0xff}
 
	{INVALID_TRACKDIR, TRACKDIR_DIAG1_NE, INVALID_TRACKDIR, INVALID_TRACKDIR,  INVALID_TRACKDIR, TRACKDIR_DIAG1_SW, INVALID_TRACKDIR, INVALID_TRACKDIR},
 
	{INVALID_TRACKDIR, INVALID_TRACKDIR,  INVALID_TRACKDIR, TRACKDIR_DIAG2_SE, INVALID_TRACKDIR, INVALID_TRACKDIR,  INVALID_TRACKDIR, TRACKDIR_DIAG2_NW},
 
	{INVALID_TRACKDIR, INVALID_TRACKDIR,  TRACKDIR_UPPER_E, INVALID_TRACKDIR,  INVALID_TRACKDIR, INVALID_TRACKDIR,  TRACKDIR_UPPER_W, INVALID_TRACKDIR},
 
	{INVALID_TRACKDIR, INVALID_TRACKDIR,  TRACKDIR_LOWER_E, INVALID_TRACKDIR,  INVALID_TRACKDIR, INVALID_TRACKDIR,  TRACKDIR_LOWER_W, INVALID_TRACKDIR},
 
	{TRACKDIR_LEFT_N,  INVALID_TRACKDIR,  INVALID_TRACKDIR, INVALID_TRACKDIR,  TRACKDIR_LEFT_S,  INVALID_TRACKDIR,  INVALID_TRACKDIR, INVALID_TRACKDIR},
 
	{TRACKDIR_RIGHT_N, INVALID_TRACKDIR,  INVALID_TRACKDIR, INVALID_TRACKDIR,  TRACKDIR_RIGHT_S, INVALID_TRACKDIR,  INVALID_TRACKDIR, INVALID_TRACKDIR}
 
};
 

	
 
const Trackdir _dir_to_diag_trackdir[] = {
 
	0, 1, 8, 9,
 
	TRACKDIR_DIAG1_NE, TRACKDIR_DIAG2_SE, TRACKDIR_DIAG1_SW, TRACKDIR_DIAG2_NW,
 
};
 

	
 
const DiagDirection _reverse_diagdir[] = {
 
	2, 3, 0, 1
 
	DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NE, DIAGDIR_SE
 
};
 

	
 
const Trackdir _reverse_trackdir[] = {
 
	8, 9, 10, 11, 12, 13, 0xFF, 0xFF,
 
	0, 1, 2,  3,  4,  5
 
	TRACKDIR_DIAG1_SW, TRACKDIR_DIAG2_NW, TRACKDIR_UPPER_W, TRACKDIR_LOWER_W, TRACKDIR_LEFT_N, TRACKDIR_RIGHT_N, INVALID_TRACKDIR, INVALID_TRACKDIR,
 
	TRACKDIR_DIAG1_NE, TRACKDIR_DIAG2_SE, TRACKDIR_UPPER_E, TRACKDIR_LOWER_E, TRACKDIR_LEFT_S, TRACKDIR_RIGHT_S
 
};
rail.h
Show inline comments
 
@@ -30,29 +30,29 @@ enum { /* DEPRECATED TODO: Rewrite all u
 
	/* There used to be RAIL_BIT_* enums here, they moved to (for now) npf.c as
 
	 * TRACK_BIT_* */
 
};
 

	
 
/* These subtypes are used in the map5 byte when the main rail type is
 
 * RAIL_TYPE_DEPOT_WAYPOINT */
 
typedef enum {
 
typedef enum RailTileSubtypes {
 
	RAIL_SUBTYPE_DEPOT    = 0x00,
 
	RAIL_SUBTYPE_WAYPOINT = 0x04,
 
	RAIL_SUBTYPE_MASK     = 0x3C,
 
} RailTileSubtype;
 

	
 
typedef enum {
 
typedef enum SignalTypes {
 
	/* Stored in _map3_hi[0..1] for MP_RAILWAY */
 
  SIGTYPE_NORMAL  = 0,        // normal signal
 
  SIGTYPE_ENTRY   = 1,        // presignal block entry
 
  SIGTYPE_EXIT    = 2,        // presignal block exit
 
  SIGTYPE_COMBO   = 3,        // presignal inter-block
 
	SIGTYPE_END,
 
	SIGTYPE_MASK    = 3,
 
} SignalType;
 

	
 
typedef enum {
 
typedef enum RailTypes {
 
	RAILTYPE_RAIL   = 0,
 
	RAILTYPE_MONO   = 1,
 
	RAILTYPE_MAGLEV = 2,
 
	RAILTYPE_END,
 
	RAILTYPE_MASK   = 0x3,
 
	INVALID_RAILTYPE = 0xFF,
 
@@ -61,37 +61,37 @@ typedef enum {
 
enum {
 
	SIG_SEMAPHORE_MASK = 4,
 
};
 

	
 
/* These are used to specify a single track. Can be translated to a trackbit
 
 * with TrackToTrackbit */
 
typedef enum {
 
typedef enum Tracks {
 
  TRACK_DIAG1 = 0,
 
  TRACK_DIAG2 = 1,
 
  TRACK_UPPER = 2,
 
  TRACK_LOWER = 3,
 
  TRACK_LEFT  = 4,
 
  TRACK_RIGHT = 5,
 
  TRACK_END,
 
  INVALID_TRACK = 0xFF,
 
} Track;
 

	
 
/* These are the bitfield variants of the above */
 
typedef enum {
 
typedef enum TrackBits {
 
  TRACK_BIT_DIAG1 = 1,  // 0
 
  TRACK_BIT_DIAG2 = 2,  // 1
 
  TRACK_BIT_UPPER = 4,  // 2
 
  TRACK_BIT_LOWER = 8,  // 3
 
  TRACK_BIT_LEFT  = 16, // 4
 
  TRACK_BIT_RIGHT = 32, // 5
 
	TRACK_BIT_MASK  = 0x3F,
 
} TrackBits;
 

	
 
/* 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. */
 
typedef enum {
 
typedef enum Trackdirs {
 
  TRACKDIR_DIAG1_NE = 0,
 
  TRACKDIR_DIAG2_SE = 1,
 
  TRACKDIR_UPPER_E  = 2,
 
  TRACKDIR_LOWER_E  = 3,
 
  TRACKDIR_LEFT_S   = 4,
 
  TRACKDIR_RIGHT_S  = 5,
 
@@ -105,13 +105,13 @@ typedef enum {
 
  TRACKDIR_END,
 
  INVALID_TRACKDIR  = 0xFF,
 
} Trackdir;
 

	
 
/* 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. */
 
typedef enum {
 
typedef enum TrackdirBits {
 
  TRACKDIR_BIT_DIAG1_NE = 0x1,
 
  TRACKDIR_BIT_DIAG2_SE = 0x2,
 
  TRACKDIR_BIT_UPPER_E  = 0x4,
 
  TRACKDIR_BIT_LOWER_E  = 0x8,
 
  TRACKDIR_BIT_LEFT_S   = 0x10,
 
  TRACKDIR_BIT_RIGHT_S  = 0x20,
 
@@ -127,15 +127,15 @@ typedef enum {
 
} TrackdirBits;
 

	
 
/* These are states in which a signal can be. Currently these are only two, so
 
 * simple boolean logic will do. But do try to compare to this enum instead of
 
 * normal boolean evaluation, since that will make future additions easier.
 
 */
 
typedef enum {
 
	SIGNALSTATE_RED = 0,
 
	SIGNALSTATE_GREEN = 1,
 
typedef enum SignalStates {
 
	SIGNAL_STATE_RED = 0,
 
	SIGNAL_STATE_GREEN = 1,
 
} SignalState;
 

	
 

	
 
/*
 
 * These functions check the validity of Tracks and Trackdirs. assert against
 
 * them when convenient.
 
@@ -184,13 +184,13 @@ static inline RailTileType GetRailTileTy
 
	return (_map5[tile] & RAIL_TILE_TYPE_MASK);
 
}
 

	
 
/**
 
 * Returns the rail type of the given rail tile (ie rail, mono, maglev).
 
 */
 
static inline RailType GetRailType(TileIndex tile) { return _map3_lo[tile] & RAILTYPE_MASK; }
 
static inline RailType GetRailType(TileIndex tile) { return (RailType)(_map3_lo[tile] & RAILTYPE_MASK); }
 

	
 
/**
 
 * Checks if a rail tile has signals.
 
 */
 
static inline bool HasSignals(TileIndex tile)
 
{
 
@@ -201,13 +201,13 @@ static inline bool HasSignals(TileIndex 
 
 * Returns the RailTileSubtype of a given rail tile with type
 
 * RAIL_TYPE_DEPOT_WAYPOINT
 
 */
 
static inline RailTileSubtype GetRailTileSubtype(TileIndex tile)
 
{
 
	assert(GetRailTileType(tile) == RAIL_TYPE_DEPOT_WAYPOINT);
 
	return _map5[tile] & RAIL_SUBTYPE_MASK;
 
	return (RailTileSubtype)(_map5[tile] & RAIL_SUBTYPE_MASK);
 
}
 

	
 
/**
 
 * Returns whether this is plain rails, with or without signals. Iow, if this
 
 * tiles RailTileType is RAIL_TYPE_NORMAL or RAIL_TYPE_SIGNALS.
 
 */
 
@@ -220,13 +220,13 @@ static inline bool IsPlainRailTile(TileI
 
/**
 
 * Returns the tracks present on the given plain rail tile (IsPlainRailTile())
 
 */
 
static inline TrackBits GetTrackBits(TileIndex tile)
 
{
 
	assert(GetRailTileType(tile) == RAIL_TYPE_NORMAL || GetRailTileType(tile) == RAIL_TYPE_SIGNALS);
 
	return _map5[tile] & TRACK_BIT_MASK;
 
	return (TrackBits)(_map5[tile] & TRACK_BIT_MASK);
 
}
 

	
 
/**
 
 * Returns whether the given track is present on the given tile. Tile must be
 
 * a plain rail tile (IsPlainRailTile()).
 
 */
 
@@ -242,12 +242,43 @@ static inline bool HasTrack(TileIndex ti
 
 *
 
 * TODO: Add #unndefs or something similar to remove the arrays used below
 
 * from the global scope and expose direct uses of them.
 
 */
 

	
 
/**
 
 * Maps a trackdir to the reverse trackdir.
 
 */
 
const Trackdir _reverse_trackdir[TRACKDIR_END];
 
static inline Trackdir ReverseTrackdir(Trackdir trackdir) { return _reverse_trackdir[trackdir]; }
 

	
 
/**
 
 * Maps a Trackdir to the corresponding TrackdirBits value
 
 */
 
static inline TrackdirBits TrackdirToTrackdirBits(Trackdir trackdir) { return (TrackdirBits)(1 << trackdir); }
 

	
 
/*
 
 * Maps a Track to the corresponding TrackBits value
 
 */
 
static inline TrackBits TrackToTrackBits(Track track) { return (TrackBits)(1 << track); }
 

	
 
/* Returns the Track that a given Trackdir represents */
 
static inline Track TrackdirToTrack(Trackdir trackdir) { return (Track)(trackdir & 0x7); }
 

	
 
/* Returns a Trackdir for the given Track. Since every Track corresponds to
 
 * two Trackdirs, we choose the one which points between NE and S.
 
 * Note that the actual implementation is quite futile, but this might change
 
 * in the future.
 
 */
 
static inline Trackdir TrackToTrackdir(Track track) { return (Trackdir)track; }
 

	
 
/* Returns a TrackdirBit mask that contains the two TrackdirBits that
 
 * correspond with the given Track (one for each direction).
 
 */
 
static inline TrackdirBits TrackToTrackdirBits(Track track) { Trackdir td = TrackToTrackdir(track); return TrackdirToTrackdirBits(td) | TrackdirToTrackdirBits(ReverseTrackdir(td));}
 

	
 
/**
 
 * Maps a trackdir to the trackdir that you will end up on if you go straight
 
 * ahead. This will be the same trackdir for diagonal trackdirs, but a
 
 * different (alternating) one for straight trackdirs
 
 */
 
const Trackdir _next_trackdir[TRACKDIR_END];
 
static inline Trackdir NextTrackdir(Trackdir trackdir) { return _next_trackdir[trackdir]; }
 
@@ -295,77 +326,65 @@ const TrackdirBits _exitdir_reaches_trac
 
 * but it uses two simpeler tables to achieve the result */
 
static inline TrackdirBits TrackdirReachesTrackdirs(Trackdir trackdir) { return _exitdir_reaches_trackdirs[TrackdirToExitdir(trackdir)]; }
 

	
 
/**
 
 * Maps a trackdir to all trackdirs that make 90 deg turns with it.
 
 */
 
const TrackdirBits _trackdir_crosses_trackdirs[TRACKDIR_END];
 
static inline TrackdirBits TrackdirCrossesTrackdirs(Trackdir trackdir) { return _trackdir_crosses_trackdirs[trackdir]; }
 
const TrackdirBits _track_crosses_trackdirs[TRACKDIR_END];
 
static inline TrackdirBits TrackdirCrossesTrackdirs(Trackdir trackdir) { return _track_crosses_trackdirs[TrackdirToTrack(trackdir)]; }
 

	
 
/**
 
 * Maps a (4-way) direction to the reverse.
 
 */
 
const DiagDirection _reverse_diagdir[DIAGDIR_END];
 
static inline DiagDirection ReverseDiagdir(DiagDirection diagdir) { return _reverse_diagdir[diagdir]; }
 

	
 
/**
 
 * Maps a trackdir to the reverse trackdir.
 
 */
 
const Trackdir _reverse_trackdir[TRACKDIR_END];
 
static inline Trackdir ReverseTrackdir(Trackdir trackdir) { return _reverse_trackdir[trackdir]; }
 

	
 
/**
 
 * Maps a Trackdir to the corresponding TrackdirBits value
 
 */
 
static inline TrackdirBits TrackdirToTrackdirBits(Trackdir trackdir) { return 1 << trackdir; }
 

	
 
/*
 
 * Maps a Track to the corresponding TrackBits value
 
 */
 
static inline TrackBits TrackToTrackBits(Track track) { return 1 << track; }
 

	
 
/* Returns the Track that a given Trackdir represents */
 
static inline Track TrackdirToTrack(Trackdir trackdir) { return trackdir & 0x7; }
 

	
 
/* Returns a Trackdir for the given Track. Since every Track corresponds to
 
 * two Trackdirs, we choose the one which points between N and SE.
 
 * Note that the actual implementation is quite futile, but this might change
 
 * in the future.
 
 */
 
static inline Trackdir TrackToTrackdir(Track track) { return track; }
 

	
 
/* Checks if a given Track is diagonal */
 
static inline bool IsDiagonalTrack(Track track) { return track == TRACK_DIAG1 || track == TRACK_DIAG2; }
 
static inline bool IsDiagonalTrack(Track track) { return (track == TRACK_DIAG1) || (track == TRACK_DIAG2); }
 

	
 
/* Checks if a given Trackdir is diagonal. */
 
static inline bool IsDiagonalTrackdir(Trackdir trackdir) { return IsDiagonalTrack(TrackdirToTrack(trackdir)); }
 

	
 
/*
 
 * Functions quering signals on tiles.
 
 */
 

	
 
/**
 
 * Checks for the presence of signals on the given track on the given tile
 
 * Checks for the presence of signals (either way) on the given track on the
 
 * given rail tile.
 
 */
 
static inline bool HasSignalOnTrack(TileIndex tile, Track track)
 
{
 
	assert(IsValidTrack(track));
 
	return (GetRailTileType(tile) == RAIL_TYPE_SIGNALS && (_map3_lo[tile] & SignalOnTrack(track)));
 
	return ((GetRailTileType(tile) == RAIL_TYPE_SIGNALS) && ((_map3_lo[tile] & SignalOnTrack(track)) != 0));
 
}
 

	
 
/**
 
 * Checks for the presence of signals along the given trackdir on the given
 
 * rail tile.
 
 *
 
 * Along meaning if you are currently driving on the given trackdir, this is
 
 * the signal that is facing us (for which we stop when it's red).
 
 */
 
static inline bool HasSignalOnTrackdir(TileIndex tile, Trackdir trackdir)
 
{
 
	assert (IsValidTrackdir(trackdir));
 
	return (GetRailTileType(tile) == RAIL_TYPE_SIGNALS) && (_map3_lo[tile] & SignalAlongTrackdir(trackdir));
 
}
 

	
 
/**
 
 * Gets the state of the signal along the given trackdir.
 
 *
 
 * Along meaning if you are currently driving on the given trackdir, this is
 
 * the signal that is facing us (for which we stop when it's red).
 
 */
 
static inline SignalState GetSignalState(TileIndex tile, Trackdir trackdir)
 
{
 
	assert(IsValidTrackdir(trackdir));
 
	assert(HasSignalOnTrack(tile, TrackdirToTrack(trackdir)));
 
	return ((_map2[tile] & SignalAlongTrackdir(trackdir))?SIGNALSTATE_GREEN:SIGNALSTATE_RED);
 
	return ((_map2[tile] & SignalAlongTrackdir(trackdir))?SIGNAL_STATE_GREEN:SIGNAL_STATE_RED);
 
}
 

	
 
/**
 
 * Gets the type of signal on a given track on a given rail tile with signals.
 
 *
 
 * Note that currently, the track argument is not used, since
 
@@ -373,13 +392,13 @@ static inline SignalState GetSignalState
 
 * future-compatible, though.
 
 */
 
static inline SignalType GetSignalType(TileIndex tile, Track track)
 
{
 
	assert(IsValidTrack(track));
 
	assert(GetRailTileType(tile) == RAIL_TYPE_SIGNALS);
 
	return _map3_hi[tile] & SIGTYPE_MASK;
 
	return (SignalType)(_map3_hi[tile] & SIGTYPE_MASK);
 
}
 

	
 
/**
 
 * Checks if this tile contains semaphores (returns true) or normal signals
 
 * (returns false) on the given track. Does not check if there are actually
 
 * signals on the track, you should use HasSignalsOnTrack() for that.
 
@@ -388,10 +407,10 @@ static inline SignalType GetSignalType(T
 
 * semaphores/electric signals cannot be mixed. This function is trying to be
 
 * future-compatible, though.
 
 */
 
static inline bool HasSemaphores(TileIndex tile, Track track)
 
{
 
	assert(IsValidTrack(track));
 
	return _map3_hi[tile] & SIG_SEMAPHORE_MASK;
 
	return (_map3_hi[tile] & SIG_SEMAPHORE_MASK);
 
}
 

	
 
#endif // RAIL_H
tile.h
Show inline comments
 
#ifndef TILE_H
 
#define TILE_H
 

	
 
#include "macros.h"
 
#include "map.h"
 

	
 
typedef enum TileType {
 
typedef enum TileTypes {
 
	MP_CLEAR,
 
	MP_RAILWAY,
 
	MP_STREET,
 
	MP_HOUSE,
 
	MP_TREES,
 
	MP_STATION,
vehicle.c
Show inline comments
 
@@ -1733,42 +1733,42 @@ byte GetDirectionTowards(Vehicle *v, int
 
	dirdiff = _new_direction_table[i] - dir;
 
	if (dirdiff == 0)
 
		return dir;
 
	return (dir+((dirdiff&7)<5?1:-1)) & 7;
 
}
 

	
 
byte GetVehicleTrackdir(const Vehicle* v)
 
Trackdir GetVehicleTrackdir(const Vehicle* v)
 
{
 
	if (v->vehstatus & VS_CRASHED) return 0xFF;
 

	
 
	switch(v->type)
 
	{
 
		case VEH_Train:
 
			if (v->u.rail.track == 0x80) /* We'll assume the train is facing outwards */
 
				return _dir_to_diag_trackdir[GetDepotDirection(v->tile, TRANSPORT_RAIL)]; /* Train in depot */
 
				return DiagdirToDiagTrackdir(GetDepotDirection(v->tile, TRANSPORT_RAIL)); /* Train in depot */
 

	
 
			if (v->u.rail.track == 0x40) /* train in tunnel, so just use his direction and assume a diagonal track */
 
				return _dir_to_diag_trackdir[(v->direction >> 1) & 3];
 
				return DiagdirToDiagTrackdir((v->direction >> 1) & 3);
 

	
 
			return _track_direction_to_trackdir[FIND_FIRST_BIT(v->u.rail.track)][v->direction];
 
			return TrackDirectionToTrackdir(FIND_FIRST_BIT(v->u.rail.track),v->direction);
 
			break;
 
		case VEH_Ship:
 
			if (v->u.ship.state == 0x80)  /* Inside a depot? */
 
				/* We'll assume the ship is facing outwards */
 
				return _dir_to_diag_trackdir[GetDepotDirection(v->tile, TRANSPORT_WATER)]; /* Ship in depot */
 
				return DiagdirToDiagTrackdir(GetDepotDirection(v->tile, TRANSPORT_WATER)); /* Ship in depot */
 

	
 
			return _track_direction_to_trackdir[FIND_FIRST_BIT(v->u.ship.state)][v->direction];
 
			return TrackDirectionToTrackdir(FIND_FIRST_BIT(v->u.ship.state),v->direction);
 
			break;
 
		case VEH_Road:
 
			if (v->u.road.state == 254) /* We'll assume the road vehicle is facing outwards */
 
				return _dir_to_diag_trackdir[GetDepotDirection(v->tile, TRANSPORT_ROAD)]; /* Road vehicle in depot */
 
				return DiagdirToDiagTrackdir(GetDepotDirection(v->tile, TRANSPORT_ROAD)); /* Road vehicle in depot */
 

	
 
			if (IsRoadStationTile(v->tile)) /* We'll assume the road vehicle is facing outwards */
 
				return _dir_to_diag_trackdir[GetRoadStationDir(v->tile)]; /* Road vehicle in a station */
 
				return DiagdirToDiagTrackdir(GetRoadStationDir(v->tile)); /* Road vehicle in a station */
 

	
 
			return _dir_to_diag_trackdir[(v->direction >> 1) & 3];
 
			return DiagdirToDiagTrackdir((v->direction >> 1) & 3);
 
			break;
 
		/* case VEH_Aircraft: case VEH_Special: case VEH_Disaster: */
 
		default: return 0xFF;
 
	}
 
}
 
/* Return value has bit 0x2 set, when the vehicle enters a station. Then,
vehicle.h
Show inline comments
 
#ifndef VEHICLE_H
 
#define VEHICLE_H
 

	
 
#include "pool.h"
 
#include "order.h"
 
#include "rail.h"
 

	
 
enum {
 
	VEH_Train = 0x10,
 
	VEH_Road = 0x11,
 
	VEH_Ship = 0x12,
 
	VEH_Aircraft = 0x13,
 
@@ -337,13 +338,13 @@ typedef struct GetNewVehiclePosResult {
 
 * vehicle that is halfway a tile, never really understood that part. For road
 
 * vehicles that are at the beginning or end of the tile, should just return
 
 * the diagonal trackdir on which they are driving. I _think_.
 
 * For other vehicles types, or vehicles with no clear trackdir (such as those
 
 * in depots), returns 0xFF.
 
 */
 
byte GetVehicleTrackdir(const Vehicle* v);
 
Trackdir GetVehicleTrackdir(const Vehicle* v);
 

	
 
/* returns true if staying in the same tile */
 
bool GetNewVehiclePos(Vehicle *v, GetNewVehiclePosResult *gp);
 
byte GetDirectionTowards(Vehicle *v, int x, int y);
 

	
 
#define BEGIN_ENUM_WAGONS(v) do {
0 comments (0 inline, 0 general)