(svn r12199) -Codechange: Remove magic around the results of GetTileTrackStatus().

This commit is contained in:
frosch 2008-02-20 17:49:50 +00:00
parent 9e65157548
commit b7993793c8
30 changed files with 180 additions and 134 deletions

View File

@ -69,10 +69,9 @@ enum {
};
static TrackBits GetRailTrackStatus(TileIndex tile)
static inline TrackBits GetRailTrackStatus(TileIndex tile)
{
uint32 r = GetTileTrackStatus(tile, TRANSPORT_RAIL, 0);
return (TrackBits)(byte) (r | r >> 8);
return TrackStatusToTrackBits(GetTileTrackStatus(tile, TRANSPORT_RAIL, 0));
}
@ -2883,7 +2882,7 @@ static bool AiCheckRoadFinished(Player *p)
tile = TILE_MASK(_players_ai[p->index].cur_tile_a + TileOffsByDiagDir(dir));
if (IsRoadStopTile(tile) || IsTileDepotType(tile, TRANSPORT_ROAD)) return false;
bits = GetTileTrackStatus(tile, TRANSPORT_ROAD, ROADTYPES_ROAD) & _ai_road_table_and[dir];
bits = TrackStatusToTrackdirBits(GetTileTrackStatus(tile, TRANSPORT_ROAD, ROADTYPES_ROAD)) & _ai_road_table_and[dir];
if (bits == 0) return false;
are.best_dist = (uint)-1;

View File

@ -315,7 +315,7 @@ static void ClickTile_Clear(TileIndex tile)
/* not used */
}
static uint32 GetTileTrackStatus_Clear(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
static TrackStatus GetTileTrackStatus_Clear(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
{
return 0;
}

View File

@ -716,9 +716,8 @@ static void DisasterTick_Submarine(Vehicle *v)
tile = v->tile + TileOffsByDiagDir(DirToDiagDir(v->direction));
if (IsValidTile(tile)) {
TrackdirBits r = (TrackdirBits)GetTileTrackStatus(tile, TRANSPORT_WATER, 0);
if (TrackdirBitsToTrackBits(r) == TRACK_BIT_ALL && !Chance16(1, 90)) {
TrackBits trackbits = TrackStatusToTrackBits(GetTileTrackStatus(tile, TRANSPORT_WATER, 0));
if (trackbits == TRACK_BIT_ALL && !Chance16(1, 90)) {
GetNewVehiclePosResult gp = GetNewVehiclePos(v);
SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos);
return;

View File

@ -64,7 +64,7 @@ static void ChangeTileOwner_Dummy(TileIndex tile, PlayerID old_player, PlayerID
/* not used */
}
static uint32 GetTileTrackStatus_Dummy(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
static TrackStatus GetTileTrackStatus_Dummy(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
{
return 0;
}

View File

@ -815,7 +815,7 @@ static void ClickTile_Industry(TileIndex tile)
ShowIndustryViewWindow(GetIndustryIndex(tile));
}
static uint32 GetTileTrackStatus_Industry(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
static TrackStatus GetTileTrackStatus_Industry(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
{
return 0;
}

View File

@ -437,16 +437,16 @@ void DoClearSquare(TileIndex tile)
MarkTileDirtyByTile(tile);
}
/** Returns trackdirbits in lower two bytes and additional info about track status in upper two bytes
/** Returns information about trackdirs and signal states.
* If there is any trackbit at 'side', return all trackdirbits.
* For TRANSPORT_ROAD, return 0 if there is no roadbit (of given subtype) at given side.
* For TRANSPORT_ROAD, return no trackbits if there is no roadbit (of given subtype) at given side.
* @param tile tile to get info about
* @param mode transport type
* @param sub_mode for TRANSPORT_ROAD, roadtypes to check
* @param side side we are entering from, INVALID_DIAGDIR to return all trackbits
* @return trackdirbits and other info depending on 'mode'
*/
uint32 GetTileTrackStatus(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
TrackStatus GetTileTrackStatus(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
{
return _tile_type_procs[GetTileType(tile)]->get_tile_track_status_proc(tile, mode, sub_mode, side);
}

View File

@ -291,13 +291,13 @@ static uint32 GetRailContinuationInfo(TileIndex tile)
uint i;
for (i = 0; i < lengthof(x_dir); i++, dir++, diagdir++) {
uint32 ts = GetTileTrackStatus(tile + TileOffsByDir(*dir), TRANSPORT_RAIL, 0);
if (ts != 0) {
TrackBits trackbits = TrackStatusToTrackBits(GetTileTrackStatus(tile + TileOffsByDir(*dir), TRANSPORT_RAIL, 0));
if (trackbits != TRACK_BIT_NONE) {
/* If there is any track on the tile, set the bit in the second byte */
SetBit(res, i + 8);
/* If any track reaches our exit direction, set the bit in the lower byte */
if (ts & DiagdirReachesTracks(*diagdir)) SetBit(res, i);
if (trackbits & DiagdirReachesTracks(*diagdir)) SetBit(res, i);
}
}

View File

@ -607,8 +607,7 @@ static bool CanEnterTile(TileIndex tile, DiagDirection dir, TransportType type,
*/
static TrackdirBits GetDriveableTrackdirBits(TileIndex dst_tile, Trackdir src_trackdir, TransportType type, uint subtype)
{
uint32 ts = GetTileTrackStatus(dst_tile, type, subtype);
TrackdirBits trackdirbits = (TrackdirBits)(ts & TRACKDIR_BIT_MASK);
TrackdirBits trackdirbits = TrackStatusToTrackdirBits(GetTileTrackStatus(dst_tile, type, subtype));
if (trackdirbits == 0 && type == TRANSPORT_ROAD && HasBit(subtype, ROADTYPE_TRAM)) {
/* GetTileTrackStatus() returns 0 for single tram bits.

View File

@ -152,8 +152,8 @@ static void TPFMode2(TrackPathFinder* tpf, TileIndex tile, DiagDirection directi
if (++tpf->rd.cur_length > 50)
return;
uint32 ts = GetTileTrackStatus(tile, tpf->tracktype, tpf->sub_type);
TrackBits bits = (TrackBits)((byte)((ts | (ts >> 8)) & _bits_mask[direction]));
TrackStatus ts = GetTileTrackStatus(tile, tpf->tracktype, tpf->sub_type);
TrackBits bits = (TrackBits)(TrackStatusToTrackBits(ts) & _bits_mask[direction]);
if (bits == TRACK_BIT_NONE) return;
assert(TileX(tile) != MapMaxX() && TileY(tile) != MapMaxY());
@ -252,11 +252,11 @@ static void TPFMode1(TrackPathFinder* tpf, TileIndex tile, DiagDirection directi
}
}
uint32 bits = GetTileTrackStatus(tile, tpf->tracktype, tpf->sub_type);
uint32 bits = TrackStatusToTrackdirBits(GetTileTrackStatus(tile, tpf->tracktype, tpf->sub_type));
/* Check in case of rail if the owner is the same */
if (tpf->tracktype == TRANSPORT_RAIL) {
if (bits != 0 && GetTileTrackStatus(tile_org, TRANSPORT_RAIL, 0) != 0) {
if (bits != 0 && TrackStatusToTrackdirBits(GetTileTrackStatus(tile_org, TRANSPORT_RAIL, 0)) != TRACKDIR_BIT_NONE) {
if (GetTileOwner(tile_org) != GetTileOwner(tile)) return;
}
}
@ -682,8 +682,8 @@ start_at:
if (!IsTileType(tile, MP_RAILWAY) || !IsPlainRailTile(tile)) {
/* We found a tile which is not a normal railway tile.
* Determine which tracks that exist on this tile. */
uint32 ts = GetTileTrackStatus(tile, TRANSPORT_RAIL, 0) & _tpfmode1_and[direction];
bits = TrackdirBitsToTrackBits((TrackdirBits)(ts & TRACKDIR_BIT_MASK));
TrackStatus ts = GetTileTrackStatus(tile, TRANSPORT_RAIL, 0) & _tpfmode1_and[direction];
bits = TrackStatusToTrackBits(ts);
/* Check that the tile contains exactly one track */
if (bits == 0 || KillFirstBit(bits) != 0) break;

View File

@ -911,8 +911,7 @@ static bool CheckSignalAutoFill(TileIndex &tile, Trackdir &trackdir, int &signal
if (tile == INVALID_TILE) return false;
/* Check for track bits on the new tile */
uint32 ts = GetTileTrackStatus(tile, TRANSPORT_RAIL, 0);
TrackdirBits trackdirbits = (TrackdirBits)(ts & TRACKDIR_BIT_MASK);
TrackdirBits trackdirbits = TrackStatusToTrackdirBits(GetTileTrackStatus(tile, TRANSPORT_RAIL, 0));
if (TracksOverlap(TrackdirBitsToTrackBits(trackdirbits))) return false;
trackdirbits &= TrackdirReachesTrackdirs(trackdir);
@ -2083,17 +2082,21 @@ set_ground:
}
static uint32 GetTileTrackStatus_Track(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
static TrackStatus GetTileTrackStatus_Track(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
{
if (mode != TRANSPORT_RAIL) return 0;
TrackBits trackbits = TRACK_BIT_NONE;
TrackdirBits red_signals = TRACKDIR_BIT_NONE;
switch (GetRailTileType(tile)) {
default: NOT_REACHED();
case RAIL_TILE_NORMAL:
return GetTrackBits(tile) * 0x101;
trackbits = GetTrackBits(tile);
break;
case RAIL_TILE_SIGNALS: {
uint32 ret = GetTrackBits(tile) * 0x101;
trackbits = GetTrackBits(tile);
byte a = GetPresentSignals(tile);
uint b = GetSignalStates(tile);
@ -2106,25 +2109,29 @@ static uint32 GetTileTrackStatus_Track(TileIndex tile, TransportType mode, uint
if ((a & 0xC) == 0) b |= 0xC;
if ((a & 0x3) == 0) b |= 0x3;
if ((b & 0x8) == 0) ret |= 0x10070000;
if ((b & 0x4) == 0) ret |= 0x07100000;
if ((b & 0x2) == 0) ret |= 0x20080000;
if ((b & 0x1) == 0) ret |= 0x08200000;
if ((b & 0x8) == 0) red_signals |= (TRACKDIR_BIT_LEFT_N | TRACKDIR_BIT_X_NE | TRACKDIR_BIT_Y_SE | TRACKDIR_BIT_UPPER_E);
if ((b & 0x4) == 0) red_signals |= (TRACKDIR_BIT_LEFT_S | TRACKDIR_BIT_X_SW | TRACKDIR_BIT_Y_NW | TRACKDIR_BIT_UPPER_W);
if ((b & 0x2) == 0) red_signals |= (TRACKDIR_BIT_RIGHT_N | TRACKDIR_BIT_LOWER_E);
if ((b & 0x1) == 0) red_signals |= (TRACKDIR_BIT_RIGHT_S | TRACKDIR_BIT_LOWER_W);
return ret;
break;
}
case RAIL_TILE_DEPOT: {
DiagDirection dir = GetRailDepotDirection(tile);
if (side != INVALID_DIAGDIR && side != dir) return 0;
if (side != INVALID_DIAGDIR && side != dir) break;
return AxisToTrackBits(DiagDirToAxis(dir)) * 0x101;
trackbits = AxisToTrackBits(DiagDirToAxis(dir));
break;
}
case RAIL_TILE_WAYPOINT:
return GetRailWaypointBits(tile) * 0x101;
trackbits = GetRailWaypointBits(tile);
break;
}
return CombineTrackStatus(TrackBitsToTrackdirBits(trackbits), red_signals);
}
static void ClickTile_Track(TileIndex tile)

View File

@ -189,7 +189,7 @@ static void PlaceRail_Station(TileIndex tile)
*/
static void GenericPlaceSignals(TileIndex tile)
{
TrackBits trackbits = (TrackBits)GB(GetTileTrackStatus(tile, TRANSPORT_RAIL, 0), 0, 6);
TrackBits trackbits = TrackStatusToTrackBits(GetTileTrackStatus(tile, TRANSPORT_RAIL, 0));
if (trackbits & TRACK_BIT_VERT) { // N-S direction
trackbits = (_tile_fract_coords.x <= _tile_fract_coords.y) ? TRACK_BIT_RIGHT : TRACK_BIT_LEFT;

View File

@ -1311,20 +1311,22 @@ static void ClickTile_Road(TileIndex tile)
if (IsRoadDepot(tile)) ShowDepotWindow(tile, VEH_ROAD);
}
/* Converts RoadBits to TrackBits */
static const byte _road_trackbits[16] = {
0x0, 0x0, 0x0, 0x10, 0x0, 0x2, 0x8, 0x1A, 0x0, 0x4, 0x1, 0x15, 0x20, 0x26, 0x29, 0x3F,
};
static uint32 GetTileTrackStatus_Road(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
static TrackStatus GetTileTrackStatus_Road(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
{
TrackdirBits trackdirbits = TRACKDIR_BIT_NONE;
TrackdirBits red_signals = TRACKDIR_BIT_NONE; // crossing barred
switch (mode) {
case TRANSPORT_RAIL:
if (!IsLevelCrossing(tile)) return 0;
return GetCrossingRailBits(tile) * 0x101;
if (IsLevelCrossing(tile)) trackdirbits = TrackBitsToTrackdirBits(GetCrossingRailBits(tile));
break;
case TRANSPORT_ROAD:
if ((GetRoadTypes(tile) & sub_mode) == 0) return 0;
if ((GetRoadTypes(tile) & sub_mode) == 0) break;
switch (GetRoadTileType(tile)) {
case ROAD_TILE_NORMAL: {
const uint drd_to_multiplier[DRD_END] = { 0x101, 0x100, 0x1, 0x0 };
@ -1332,36 +1334,38 @@ static uint32 GetTileTrackStatus_Road(TileIndex tile, TransportType mode, uint s
RoadBits bits = GetRoadBits(tile, rt);
/* no roadbit at this side of tile, return 0 */
if (side != INVALID_DIAGDIR && (DiagDirToRoadBits(side) & bits) == 0) return 0;
if (side != INVALID_DIAGDIR && (DiagDirToRoadBits(side) & bits) == 0) break;
uint multiplier = drd_to_multiplier[rt == ROADTYPE_TRAM ? DRD_NONE : GetDisallowedRoadDirections(tile)];
return HasRoadWorks(tile) ? 0 : _road_trackbits[bits] * multiplier;
if (!HasRoadWorks(tile)) trackdirbits = (TrackdirBits)(_road_trackbits[bits] * multiplier);
break;
}
case ROAD_TILE_CROSSING: {
Axis axis = GetCrossingRoadAxis(tile);
if (side != INVALID_DIAGDIR && axis != DiagDirToAxis(side)) return 0;
if (side != INVALID_DIAGDIR && axis != DiagDirToAxis(side)) break;
uint32 r = AxisToTrackBits(axis) * 0x101;
if (IsCrossingBarred(tile)) r *= 0x10001;
return r;
trackdirbits = TrackBitsToTrackdirBits(AxisToTrackBits(axis));
if (IsCrossingBarred(tile)) red_signals = trackdirbits;
break;
}
default:
case ROAD_TILE_DEPOT: {
DiagDirection dir = GetRoadDepotDirection(tile);
if (side != INVALID_DIAGDIR && side != dir) return 0;
if (side != INVALID_DIAGDIR && side != dir) break;
return AxisToTrackBits(DiagDirToAxis(dir)) * 0x101;
trackdirbits = TrackBitsToTrackdirBits(AxisToTrackBits(DiagDirToAxis(dir)));
break;
}
}
break;
default: break;
}
return 0;
return CombineTrackStatus(trackdirbits, red_signals);
}
static const StringID _road_tile_strings[] = {

View File

@ -43,14 +43,10 @@ RoadBits GetAnyRoadBits(TileIndex tile, RoadType rt)
TrackBits GetAnyRoadTrackBits(TileIndex tile, RoadType rt)
{
uint32 r;
/* Don't allow local authorities to build roads through road depots or road stops. */
if (IsRoadDepotTile(tile) || (IsTileType(tile, MP_STATION) && !IsDriveThroughStopTile(tile)) || !HasTileRoadType(tile, rt)) {
return TRACK_BIT_NONE;
}
r = GetTileTrackStatus(tile, TRANSPORT_ROAD, RoadTypeToRoadTypes(rt));
return (TrackBits)(byte)(r | (r >> 8));
return TrackStatusToTrackBits(GetTileTrackStatus(tile, TRANSPORT_ROAD, RoadTypeToRoadTypes(rt)));
}

View File

@ -1028,9 +1028,9 @@ static void* EnumFindVehBlockingOvertake(Vehicle* v, void* data)
*/
static bool CheckRoadBlockedForOvertaking(OvertakeData *od)
{
uint32 ts = GetTileTrackStatus(od->tile, TRANSPORT_ROAD, od->v->u.road.compatible_roadtypes);
TrackdirBits trackdirbits = (TrackdirBits)(ts & TRACKDIR_BIT_MASK);
TrackdirBits red_signals = (TrackdirBits)((ts >> 16) & TRACKDIR_BIT_MASK); // barred level crossing
TrackStatus ts = GetTileTrackStatus(od->tile, TRANSPORT_ROAD, od->v->u.road.compatible_roadtypes);
TrackdirBits trackdirbits = TrackStatusToTrackdirBits(ts);
TrackdirBits red_signals = TrackStatusToRedSignals(ts); // barred level crossing
TrackBits trackbits = TrackdirBitsToTrackBits(trackdirbits);
/* Track does not continue along overtaking direction || track has junction || levelcrossing is barred */
@ -1159,9 +1159,9 @@ static Trackdir RoadFindPathToDest(Vehicle* v, TileIndex tile, DiagDirection ent
FindRoadToChooseData frd;
Trackdir best_track;
uint32 r = GetTileTrackStatus(tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes);
TrackdirBits signal = (TrackdirBits)GB(r, 16, 16);
TrackdirBits trackdirs = (TrackdirBits)GB(r, 0, 16);
TrackStatus ts = GetTileTrackStatus(tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes);
TrackdirBits red_signals = TrackStatusToRedSignals(ts); // crossing
TrackdirBits trackdirs = TrackStatusToTrackdirBits(ts);
if (IsTileType(tile, MP_ROAD)) {
if (IsRoadDepot(tile) && (!IsTileOwner(tile, v->owner) || GetRoadDepotDirection(tile) == enterdir || (GetRoadTypes(tile) & v->u.road.compatible_roadtypes) == 0)) {
@ -1302,7 +1302,7 @@ do_it:;
found_best_track:;
if (HasBit(signal, best_track)) return INVALID_TRACKDIR;
if (HasBit(red_signals, best_track)) return INVALID_TRACKDIR;
return best_track;
}

View File

@ -50,10 +50,9 @@ static const TrackBits _ship_sometracks[4] = {
TRACK_BIT_Y | TRACK_BIT_LOWER | TRACK_BIT_RIGHT, // 0x2A, // DIAGDIR_NW
};
static TrackBits GetTileShipTrackStatus(TileIndex tile)
static inline TrackBits GetTileShipTrackStatus(TileIndex tile)
{
uint32 r = GetTileTrackStatus(tile, TRANSPORT_WATER, 0);
return TrackdirBitsToTrackBits((TrackdirBits)(TRACKDIR_BIT_MASK & (r | r >> 8)));
return TrackStatusToTrackBits(GetTileTrackStatus(tile, TRANSPORT_WATER, 0));
}
void DrawShipEngine(int x, int y, EngineID engine, SpriteID pal)
@ -592,10 +591,9 @@ static Direction ShipGetNewDirection(Vehicle *v, int x, int y)
return _new_vehicle_direction_table[offs];
}
static TrackBits GetAvailShipTracks(TileIndex tile, int dir)
static inline TrackBits GetAvailShipTracks(TileIndex tile, int dir)
{
uint32 r = GetTileTrackStatus(tile, TRANSPORT_WATER, 0);
return (TrackBits)((r | r >> 8) & _ship_sometracks[dir]);
return GetTileShipTrackStatus(tile) & _ship_sometracks[dir];
}
static const byte _ship_subcoord[4][6][3] = {

View File

@ -506,7 +506,7 @@ static bool UpdateSignalsInBuffer(Owner owner)
/* FALLTHROUGH */
case MP_STATION:
case MP_ROAD:
if ((TrackBits)(GetTileTrackStatus(tile, TRANSPORT_RAIL, 0) & _enterdir_to_trackbits[dir]) != TRACK_BIT_NONE) {
if ((TrackStatusToTrackBits(GetTileTrackStatus(tile, TRANSPORT_RAIL, 0)) & _enterdir_to_trackbits[dir]) != TRACK_BIT_NONE) {
/* only add to set when there is some 'interesting' track */
_tbdset.Add(tile, dir);
_tbdset.Add(tile + TileOffsByDiagDir(dir), ReverseDiagDir(dir));
@ -517,7 +517,7 @@ static bool UpdateSignalsInBuffer(Owner owner)
/* jump to next tile */
tile = tile + TileOffsByDiagDir(dir);
dir = ReverseDiagDir(dir);
if ((TrackBits)(GetTileTrackStatus(tile, TRANSPORT_RAIL, 0) & _enterdir_to_trackbits[dir]) != TRACK_BIT_NONE) {
if ((TrackStatusToTrackBits(GetTileTrackStatus(tile, TRANSPORT_RAIL, 0)) & _enterdir_to_trackbits[dir]) != TRACK_BIT_NONE) {
_tbdset.Add(tile, dir);
break;
}

View File

@ -2280,24 +2280,25 @@ static void GetTileDesc_Station(TileIndex tile, TileDesc *td)
}
static uint32 GetTileTrackStatus_Station(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
static TrackStatus GetTileTrackStatus_Station(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
{
TrackBits trackbits = TRACK_BIT_NONE;
switch (mode) {
case TRANSPORT_RAIL:
if (IsRailwayStation(tile) && !IsStationTileBlocked(tile)) {
return TrackToTrackBits(GetRailStationTrack(tile)) * 0x101;
trackbits = TrackToTrackBits(GetRailStationTrack(tile));
}
break;
case TRANSPORT_WATER:
/* buoy is coded as a station, it is always on open water */
if (IsBuoy(tile)) {
TrackBits ts = TRACK_BIT_ALL;
trackbits = TRACK_BIT_ALL;
/* remove tracks that connect NE map edge */
if (TileX(tile) == 0) ts &= ~(TRACK_BIT_X | TRACK_BIT_UPPER | TRACK_BIT_RIGHT);
if (TileX(tile) == 0) trackbits &= ~(TRACK_BIT_X | TRACK_BIT_UPPER | TRACK_BIT_RIGHT);
/* remove tracks that connect NW map edge */
if (TileY(tile) == 0) ts &= ~(TRACK_BIT_Y | TRACK_BIT_LEFT | TRACK_BIT_UPPER);
return uint32(ts) * 0x101;
if (TileY(tile) == 0) trackbits &= ~(TRACK_BIT_Y | TRACK_BIT_LEFT | TRACK_BIT_UPPER);
}
break;
@ -2307,10 +2308,10 @@ static uint32 GetTileTrackStatus_Station(TileIndex tile, TransportType mode, uin
Axis axis = DiagDirToAxis(dir);
if (side != INVALID_DIAGDIR) {
if (axis != DiagDirToAxis(side) || (IsStandardRoadStopTile(tile) && dir != side)) return 0;
if (axis != DiagDirToAxis(side) || (IsStandardRoadStopTile(tile) && dir != side)) break;
}
return AxisToTrackBits(axis) * 0x101;
trackbits = AxisToTrackBits(axis);
}
break;
@ -2318,7 +2319,7 @@ static uint32 GetTileTrackStatus_Station(TileIndex tile, TransportType mode, uin
break;
}
return 0;
return CombineTrackStatus(TrackBitsToTrackdirBits(trackbits), TRACKDIR_BIT_NONE);
}

View File

@ -14,6 +14,7 @@
#include "date_type.h"
#include "player_type.h"
#include "direction_type.h"
#include "track_type.h"
/** The returned bits of VehicleEnterTile. */
enum VehicleEnterTileStatus {
@ -60,29 +61,17 @@ typedef void GetTileDescProc(TileIndex tile, TileDesc *td);
/**
* GetTileTrackStatusProcs return a value that contains the possible tracks
* that can be taken on a given tile by a given transport. The return value is
* composed as follows: 0xaabbccdd. ccdd and aabb are bitmasks of trackdirs,
* where bit n corresponds to trackdir n. ccdd are the trackdirs that are
* present in the tile (1==present, 0==not present), aabb is the signal
* status, if applicable (0==green/no signal, 1==red, note that this is
* reversed from map3/2[tile] for railway signals).
* that can be taken on a given tile by a given transport.
* The return value contains the existing trackdirs and signal states.
*
* The result (let's call it ts) is often used as follows:
* tracks = (byte)(ts | ts >>8)
* This effectively converts the present part of the result (ccdd) to a
* track bitmask, which disregards directions. Normally, this is the same as just
* doing (byte)ts I think, although I am not really sure
* see track_func.h for usage of TrackStatus.
*
* A trackdir is combination of a track and a dir, where the lower three bits
* are a track, the fourth bit is the direction. these give 12 (or 14)
* possible options: 0-5 and 8-13, so we need 14 bits for a trackdir bitmask
* above.
* @param tile the tile to get the track status from
* @param mode the mode of transportation
* @param sub_mode used to differentiate between different kinds within the mode
* @return the above mentions track status information
* @return the track status information
*/
typedef uint32 GetTileTrackStatusProc(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side);
typedef TrackStatus GetTileTrackStatusProc(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side);
typedef void GetProducedCargoProc(TileIndex tile, CargoID *b);
typedef void ClickTileProc(TileIndex tile);
typedef void AnimateTileProc(TileIndex tile);
@ -127,7 +116,7 @@ struct TileTypeProcs {
extern const TileTypeProcs * const _tile_type_procs[16];
uint32 GetTileTrackStatus(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side = INVALID_DIAGDIR);
TrackStatus GetTileTrackStatus(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side = INVALID_DIAGDIR);
void GetAcceptedCargo(TileIndex tile, AcceptedCargo ac);
void ChangeTileOwner(TileIndex tile, PlayerID old_player, PlayerID new_player);
void AnimateTile(TileIndex tile);

View File

@ -592,7 +592,7 @@ static void GetTileDesc_Town(TileIndex tile, TileDesc *td)
td->owner = OWNER_TOWN;
}
static uint32 GetTileTrackStatus_Town(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
static TrackStatus GetTileTrackStatus_Town(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
{
/* not used */
return 0;

View File

@ -273,6 +273,64 @@ static inline TrackBits TrackdirBitsToTrackBits(TrackdirBits bits)
return (TrackBits)((bits | (bits >> 8)) & TRACK_BIT_MASK);
}
/**
* Converts TrackBits to TrackdirBits while allowing both directions.
*
* @param bits The TrackBits
* @return The TrackDirBits containing of bits in both directions.
*/
static inline TrackdirBits TrackBitsToTrackdirBits(TrackBits bits)
{
return (TrackdirBits)(bits * 0x101);
}
/**
* Returns the present-trackdir-information of a TrackStatus.
*
* @param ts The TrackStatus returned by GetTileTrackStatus()
* @return the present trackdirs
*/
static inline TrackdirBits TrackStatusToTrackdirBits(TrackStatus ts)
{
return (TrackdirBits)(ts & TRACKDIR_BIT_MASK);
}
/**
* Returns the present-track-information of a TrackStatus.
*
* @param ts The TrackStatus returned by GetTileTrackStatus()
* @return the present tracks
*/
static inline TrackBits TrackStatusToTrackBits(TrackStatus ts)
{
return TrackdirBitsToTrackBits(TrackStatusToTrackdirBits(ts));
}
/**
* Returns the red-signal-information of a TrackStatus.
*
* Note: The result may contain red signals for non-present tracks.
*
* @param ts The TrackStatus returned by GetTileTrackStatus()
* @return the The trackdirs that are blocked by red-signals
*/
static inline TrackdirBits TrackStatusToRedSignals(TrackStatus ts)
{
return (TrackdirBits)((ts >> 16) & TRACKDIR_BIT_MASK);
}
/**
* Builds a TrackStatus
*
* @param trackdirbits present trackdirs
* @param red_signals red signals
* @return the TrackStatus representing the given information
*/
static inline TrackStatus CombineTrackStatus(TrackdirBits trackdirbits, TrackdirBits red_signals)
{
return (TrackStatus)(trackdirbits | (red_signals << 16));
}
/**
* Maps a trackdir to the trackdir that you will end up on if you go straight
* ahead.

View File

@ -124,4 +124,6 @@ template <> struct EnumPropsT<TrackdirBits> : MakeEnumPropsT<TrackdirBits, uint1
typedef TinyEnumT<TrackdirBits> TrackdirBitsShort;
DECLARE_ENUM_AS_BIT_SET(TrackdirBits);
typedef uint32 TrackStatus;
#endif /* TRACK_TYPE_H */

View File

@ -3040,13 +3040,11 @@ static void TrainController(Vehicle *v, bool update_image)
/* Get the status of the tracks in the new tile and mask
* away the bits that aren't reachable. */
uint32 ts = GetTileTrackStatus(gp.new_tile, TRANSPORT_RAIL, 0, ReverseDiagDir(enterdir)) & _reachable_tracks[enterdir];
TrackStatus ts = GetTileTrackStatus(gp.new_tile, TRANSPORT_RAIL, 0, ReverseDiagDir(enterdir)) & _reachable_tracks[enterdir];
TrackdirBits trackdirbits = TrackStatusToTrackdirBits(ts);
TrackdirBits red_signals = TrackStatusToRedSignals(ts);
/* Combine the from & to directions.
* Now, the lower byte contains the track status, and the byte at bit 16 contains
* the signal status. */
uint32 tracks = ts | (ts >> 8);
TrackBits bits = (TrackBits)(tracks & TRACK_BIT_MASK);
TrackBits bits = TrackdirBitsToTrackBits(trackdirbits);
if (_patches.pathfinder_for_trains != VPF_NTP && _patches.forbid_90_deg && prev == NULL) {
/* We allow wagons to make 90 deg turns, because forbid_90_deg
* can be switched on halfway a turn */
@ -3064,14 +3062,12 @@ static void TrainController(Vehicle *v, bool update_image)
/* Currently the locomotive is active. Determine which one of the
* available tracks to choose */
chosen_track = TrackToTrackBits(ChooseTrainTrack(v, gp.new_tile, enterdir, bits));
assert(chosen_track & tracks);
assert(chosen_track & bits);
/* Check if it's a red signal and that force proceed is not clicked. */
if ((tracks >> 16) & chosen_track && v->u.rail.force_proceed == 0) {
/* In front of a red signal
* find the first set bit in ts. need to do it in 2 steps, since
* FIND_FIRST_BIT only handles 6 bits at a time. */
Trackdir i = FindFirstTrackdir((TrackdirBits)(uint16)ts);
if (red_signals & chosen_track && v->u.rail.force_proceed == 0) {
/* In front of a red signal */
Trackdir i = FindFirstTrackdir(trackdirbits);
if (!HasSignalOnTrackdir(gp.new_tile, ReverseTrackdir(i))) {
v->cur_speed = 0;
@ -3475,12 +3471,14 @@ static bool TrainCheckIfLineEnds(Vehicle *v)
TileIndex tile = v->tile + TileOffsByDiagDir(dir);
/* Determine the track status on the next tile */
uint32 ts = GetTileTrackStatus(tile, TRANSPORT_RAIL, 0, ReverseDiagDir(dir)) & _reachable_tracks[dir];
TrackStatus ts = GetTileTrackStatus(tile, TRANSPORT_RAIL, 0, ReverseDiagDir(dir)) & _reachable_tracks[dir];
TrackdirBits trackdirbits = TrackStatusToTrackdirBits(ts);
TrackdirBits red_signals = TrackStatusToRedSignals(ts);
/* We are sure the train is not entering a depot, it is detected above */
/* mask unreachable track bits if we are forbidden to do 90deg turns */
TrackBits bits = (TrackBits)((ts | (ts >> 8)) & TRACK_BIT_MASK);
TrackBits bits = TrackdirBitsToTrackBits(trackdirbits);
if (_patches.pathfinder_for_trains != VPF_NTP && _patches.forbid_90_deg) {
bits &= ~TrackCrossesTracks(FindFirstTrack(v->u.rail.track));
}
@ -3491,7 +3489,7 @@ static bool TrainCheckIfLineEnds(Vehicle *v)
}
/* approaching red signal */
if ((ts & (ts >> 16)) != 0) return TrainApproachingLineEnd(v, true);
if ((trackdirbits & red_signals) != 0) return TrainApproachingLineEnd(v, true);
/* approaching a rail/road crossing? then make it red */
if (IsLevelCrossingTile(tile)) MaybeBarCrossingWithSound(tile);

View File

@ -747,7 +747,7 @@ static void ClickTile_Trees(TileIndex tile)
/* not used */
}
static uint32 GetTileTrackStatus_Trees(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
static TrackStatus GetTileTrackStatus_Trees(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
{
return 0;
}

View File

@ -1193,14 +1193,14 @@ static void ClickTile_TunnelBridge(TileIndex tile)
}
static uint32 GetTileTrackStatus_TunnelBridge(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
static TrackStatus GetTileTrackStatus_TunnelBridge(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
{
TransportType transport_type = GetTunnelBridgeTransportType(tile);
if (transport_type != mode || (transport_type == TRANSPORT_ROAD && (GetRoadTypes(tile) & sub_mode) == 0)) return 0;
DiagDirection dir = GetTunnelBridgeDirection(tile);
if (side != INVALID_DIAGDIR && side != ReverseDiagDir(dir)) return 0;
return AxisToTrackBits(DiagDirToAxis(dir)) * 0x101;
return CombineTrackStatus(TrackBitsToTrackdirBits(AxisToTrackBits(DiagDirToAxis(dir))), TRACKDIR_BIT_NONE);
}
static void ChangeTileOwner_TunnelBridge(TileIndex tile, PlayerID old_player, PlayerID new_player)

View File

@ -348,7 +348,7 @@ static void TileLoop_Unmovable(TileIndex tile)
}
static uint32 GetTileTrackStatus_Unmovable(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
static TrackStatus GetTileTrackStatus_Unmovable(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
{
return 0;
}

View File

@ -1104,7 +1104,7 @@ void ConvertGroundTilesIntoWaterTiles()
}
}
static uint32 GetTileTrackStatus_Water(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
static TrackStatus GetTileTrackStatus_Water(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
{
static const byte coast_tracks[] = {0, 32, 4, 0, 16, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0};
@ -1127,7 +1127,7 @@ static uint32 GetTileTrackStatus_Water(TileIndex tile, TransportType mode, uint
/* NW border: remove tracks that connects NW tile edge */
ts &= ~(TRACK_BIT_Y | TRACK_BIT_LEFT | TRACK_BIT_UPPER);
}
return ts * 0x101;
return CombineTrackStatus(TrackBitsToTrackdirBits(ts), TRACKDIR_BIT_NONE);
}
static void ClickTile_Water(TileIndex tile)

View File

@ -64,7 +64,7 @@ struct CFollowTrackT : public FollowTrack_t
m_old_tile = old_tile;
m_old_td = old_td;
m_err = EC_NONE;
assert(((GetTileTrackStatus(m_old_tile, TT(), m_veh->u.road.compatible_roadtypes) & TrackdirToTrackdirBits(m_old_td)) != 0) ||
assert(((TrackStatusToTrackdirBits(GetTileTrackStatus(m_old_tile, TT(), m_veh->u.road.compatible_roadtypes)) & TrackdirToTrackdirBits(m_old_td)) != 0) ||
(GetSingleTramBit(m_old_tile) != INVALID_DIAGDIR)); // Disable the assertion for single tram bits
m_exitdir = TrackdirToExitdir(m_old_td);
if (ForcedReverse()) return true;
@ -133,8 +133,7 @@ protected:
if (IsRailTT() && GetTileType(m_new_tile) == MP_RAILWAY && IsPlainRailTile(m_new_tile)) {
m_new_td_bits = (TrackdirBits)(GetTrackBits(m_new_tile) * 0x101);
} else {
uint32 ts = GetTileTrackStatus(m_new_tile, TT(), m_veh->u.road.compatible_roadtypes);
m_new_td_bits = (TrackdirBits)(ts & TRACKDIR_BIT_MASK);
m_new_td_bits = TrackStatusToTrackdirBits(GetTileTrackStatus(m_new_tile, TT(), m_veh->u.road.compatible_roadtypes));
if (m_new_td_bits == 0) {
/* GetTileTrackStatus() returns 0 for single tram bits.

View File

@ -113,7 +113,7 @@ public:
default:
m_destTile = v->dest_tile;
m_dest_station_id = INVALID_STATION;
m_destTrackdirs = (TrackdirBits)(GetTileTrackStatus(v->dest_tile, TRANSPORT_RAIL, 0) & TRACKDIR_BIT_MASK);
m_destTrackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(v->dest_tile, TRANSPORT_RAIL, 0));
break;
}
CYapfDestinationRailBase::SetDestination(v);

View File

@ -268,15 +268,13 @@ public:
// our source tile will be the next vehicle tile (should be the given one)
TileIndex src_tile = tile;
// get available trackdirs on the start tile
uint ts = GetTileTrackStatus(tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes);
TrackdirBits src_trackdirs = (TrackdirBits)(ts & TRACKDIR_BIT_MASK);
TrackdirBits src_trackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes));
// select reachable trackdirs only
src_trackdirs &= DiagdirReachesTrackdirs(enterdir);
// get available trackdirs on the destination tile
TileIndex dest_tile = v->dest_tile;
uint dest_ts = GetTileTrackStatus(dest_tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes);
TrackdirBits dest_trackdirs = (TrackdirBits)(dest_ts & TRACKDIR_BIT_MASK);
TrackdirBits dest_trackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(dest_tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes));
// set origin and destination nodes
Yapf().SetOrigin(src_tile, src_trackdirs);
@ -320,8 +318,7 @@ public:
// set destination tile, trackdir
// get available trackdirs on the destination tile
uint dest_ts = GetTileTrackStatus(dst_tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes);
TrackdirBits dst_td_bits = (TrackdirBits)(dest_ts & TRACKDIR_BIT_MASK);
TrackdirBits dst_td_bits = TrackStatusToTrackdirBits(GetTileTrackStatus(dst_tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes));
Yapf().SetDestination(dst_tile, dst_td_bits);
// find the best path
@ -345,7 +342,7 @@ public:
// set origin (tile, trackdir)
TileIndex src_tile = v->tile;
Trackdir src_td = GetVehicleTrackdir(v);
if ((GetTileTrackStatus(src_tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes) & TrackdirToTrackdirBits(src_td)) == 0) {
if ((TrackStatusToTrackdirBits(GetTileTrackStatus(src_tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes)) & TrackdirToTrackdirBits(src_td)) == 0) {
// sometimes the roadveh is not on the road (it resides on non-existing track)
// how should we handle that situation?
return false;
@ -438,7 +435,7 @@ Depot* YapfFindNearestRoadDepot(const Vehicle *v)
{
TileIndex tile = v->tile;
Trackdir trackdir = GetVehicleTrackdir(v);
if ((GetTileTrackStatus(tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes) & TrackdirToTrackdirBits(trackdir)) == 0)
if ((TrackStatusToTrackdirBits(GetTileTrackStatus(tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes)) & TrackdirToTrackdirBits(trackdir)) == 0)
return NULL;
// handle the case when our vehicle is already in the depot tile

View File

@ -53,7 +53,7 @@ public:
// convert origin trackdir to TrackdirBits
TrackdirBits trackdirs = TrackdirToTrackdirBits(trackdir);
// get available trackdirs on the destination tile
TrackdirBits dest_trackdirs = (TrackdirBits)(GetTileTrackStatus(v->dest_tile, TRANSPORT_WATER, 0) & TRACKDIR_BIT_MASK);
TrackdirBits dest_trackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(v->dest_tile, TRANSPORT_WATER, 0));
// create pathfinder instance
Tpf pf;