diff options
author | truelight <truelight@openttd.org> | 2004-09-05 16:15:22 +0000 |
---|---|---|
committer | truelight <truelight@openttd.org> | 2004-09-05 16:15:22 +0000 |
commit | 10d54ac604b2d4d761877de1ceda07ceb3aa96bf (patch) | |
tree | ee4a252395acdf618350f3ff31b92a1b493f12ef | |
parent | 1846563cf89fc4cdd41691ddadac6b56dd8c2e58 (diff) | |
download | openttd-10d54ac604b2d4d761877de1ceda07ceb3aa96bf.tar.xz |
(svn r160) -Codechange: made GetTileTrackStatus more readable (blathijs)
-Fix: some minor fixes around GetTileTrackStatus (blathijs)
-rw-r--r-- | ai.c | 8 | ||||
-rw-r--r-- | clear_cmd.c | 2 | ||||
-rw-r--r-- | disaster_cmd.c | 2 | ||||
-rw-r--r-- | dummy_land.c | 2 | ||||
-rw-r--r-- | functions.h | 2 | ||||
-rw-r--r-- | industry_cmd.c | 2 | ||||
-rw-r--r-- | landscape.c | 2 | ||||
-rw-r--r-- | pathfind.c | 13 | ||||
-rw-r--r-- | pathfind.h | 2 | ||||
-rw-r--r-- | rail_cmd.c | 6 | ||||
-rw-r--r-- | rail_gui.c | 2 | ||||
-rw-r--r-- | road_cmd.c | 20 | ||||
-rw-r--r-- | roadveh_cmd.c | 41 | ||||
-rw-r--r-- | ship_cmd.c | 6 | ||||
-rw-r--r-- | station_cmd.c | 30 | ||||
-rw-r--r-- | town_cmd.c | 4 | ||||
-rw-r--r-- | train_cmd.c | 4 | ||||
-rw-r--r-- | ttd.h | 35 | ||||
-rw-r--r-- | tunnelbridge_cmd.c | 39 | ||||
-rw-r--r-- | water_cmd.c | 4 |
20 files changed, 146 insertions, 80 deletions
@@ -47,7 +47,7 @@ enum { #include "table/ai_rail.h" static byte GetRailTrackStatus(TileIndex tile) { - uint32 r = GetTileTrackStatus(tile, 0); + uint32 r = GetTileTrackStatus(tile, TRANSPORT_RAIL); return (byte) (r | r >> 8); } @@ -1849,7 +1849,7 @@ static bool AiDoFollowTrack(Player *p) arpfd.tile2 = p->ai.cur_tile_a; arpfd.flag = false; arpfd.count = 0; - FollowTrack(p->ai.cur_tile_a + _tileoffs_by_dir[p->ai.cur_dir_a], 0x2000, p->ai.cur_dir_a^2, + FollowTrack(p->ai.cur_tile_a + _tileoffs_by_dir[p->ai.cur_dir_a], 0x2000 | TRANSPORT_RAIL, p->ai.cur_dir_a^2, (TPFEnumProc*)AiEnumFollowTrack, NULL, &arpfd); return arpfd.count > 8; } @@ -2782,7 +2782,7 @@ bool AiCheckRoadFinished(Player *p) are.dest = p->ai.cur_tile_b; tile = TILE_MASK(p->ai.cur_tile_a + _tileoffs_by_dir[dir]); - bits = GetTileTrackStatus(tile, 2) & _ai_road_table_and[dir]; + bits = GetTileTrackStatus(tile, TRANSPORT_ROAD) & _ai_road_table_and[dir]; if (bits == 0) { return false; } @@ -2790,7 +2790,7 @@ bool AiCheckRoadFinished(Player *p) are.best_dist = (uint)-1; for_each_bit(i, bits) { - FollowTrack(tile, 0x3002, _dir_by_track[i], (TPFEnumProc*)AiEnumFollowRoad, NULL, &are); + FollowTrack(tile, 0x3000 | TRANSPORT_ROAD, _dir_by_track[i], (TPFEnumProc*)AiEnumFollowRoad, NULL, &are); } if (GetTileDist(tile, are.dest) <= are.best_dist) diff --git a/clear_cmd.c b/clear_cmd.c index 6b6445916..d7e742d5e 100644 --- a/clear_cmd.c +++ b/clear_cmd.c @@ -757,7 +757,7 @@ static void ClickTile_Clear(uint tile) /* not used */ } -uint32 GetTileTrackStatus_Clear(uint tile, int mode) +uint32 GetTileTrackStatus_Clear(uint tile, TransportType mode) { return 0; } diff --git a/disaster_cmd.c b/disaster_cmd.c index bcb69e8f8..23c7e3fcb 100644 --- a/disaster_cmd.c +++ b/disaster_cmd.c @@ -641,7 +641,7 @@ static void DisasterTick_5_and_6(Vehicle *v) tile = v->tile + _tileoffs_by_dir[v->direction >> 1]; if (IsValidTile(tile) && - (r=GetTileTrackStatus(tile,4),(byte)(r+(r >> 8)) == 0x3F) && + (r=GetTileTrackStatus(tile,TRANSPORT_WATER),(byte)(r+(r >> 8)) == 0x3F) && !CHANCE16(1,90)) { GetNewVehiclePos(v, &gp); SetDisasterVehiclePos(v, gp.x, gp.y, v->z_pos); diff --git a/dummy_land.c b/dummy_land.c index 590e48e78..0b0f4333f 100644 --- a/dummy_land.c +++ b/dummy_land.c @@ -53,7 +53,7 @@ static void ChangeTileOwner_Dummy(uint tile, byte old_player, byte new_player) /* not used */ } -static uint32 GetTileTrackStatus_Dummy(uint tile, int mode) +static uint32 GetTileTrackStatus_Dummy(uint tile, TransportType mode) { return 0; } diff --git a/functions.h b/functions.h index 9cb23d52a..faf450e2c 100644 --- a/functions.h +++ b/functions.h @@ -20,7 +20,7 @@ void RunTileLoop(); uint GetPartialZ(int x, int y, int corners); uint GetSlopeZ(int x, int y); -uint32 GetTileTrackStatus(uint tile, int mode); +uint32 GetTileTrackStatus(uint tile, TransportType mode); void GetAcceptedCargo(uint tile, AcceptedCargo *ac); void ChangeTileOwner(uint tile, byte old_player, byte new_player); void AnimateTile(uint tile); diff --git a/industry_cmd.c b/industry_cmd.c index bd955dbab..96ee9d98c 100644 --- a/industry_cmd.c +++ b/industry_cmd.c @@ -820,7 +820,7 @@ static void ClickTile_Industry(uint tile) ShowIndustryViewWindow(_map2[tile]); } -static uint32 GetTileTrackStatus_Industry(uint tile, int mode) +static uint32 GetTileTrackStatus_Industry(uint tile, TransportType mode) { return 0; } diff --git a/landscape.c b/landscape.c index 4c13d880b..b8e86dc5a 100644 --- a/landscape.c +++ b/landscape.c @@ -301,7 +301,7 @@ void DoClearSquare(uint tile) ); } -uint32 GetTileTrackStatus(uint tile, int mode) +uint32 GetTileTrackStatus(uint tile, TransportType mode) { return _tile_type_procs[GET_TILETYPE(tile)]->get_tile_track_status_proc(tile, mode); } diff --git a/pathfind.c b/pathfind.c index 5a6ed2890..1a39aa376 100644 --- a/pathfind.c +++ b/pathfind.c @@ -190,7 +190,7 @@ static const int8 _get_tunlen_inc[5] = { -16, 0, 16, 0, -16 }; /* Returns the end tile and the length of a tunnel. The length does not * include the starting tile (entry), it does include the end tile (exit). */ -FindLengthOfTunnelResult FindLengthOfTunnel(uint tile, int direction, byte type) +FindLengthOfTunnelResult FindLengthOfTunnel(uint tile, int direction) { FindLengthOfTunnelResult flotr; int x,y; @@ -213,7 +213,8 @@ FindLengthOfTunnelResult FindLengthOfTunnel(uint tile, int direction, byte type) if (IS_TILETYPE(tile, MP_TUNNELBRIDGE) && (_map5[tile] & 0xF0) == 0 && - ((_map5[tile]>>1)&6) == type && + //((_map5[tile]>>2)&3) == type && // This is + //not necesary to check, right? ((_map5[tile] & 3)^2) == direction && GetSlopeZ(x+8, y+8) == z) break; @@ -228,7 +229,7 @@ static const uint16 _tpfmode1_and[4] = { 0x1009, 0x16, 0x520, 0x2A00 }; static uint SkipToEndOfTunnel(TrackPathFinder *tpf, uint tile, int direction) { FindLengthOfTunnelResult flotr; TPFSetTileBit(tpf, tile, 14); - flotr = FindLengthOfTunnel(tile, direction, tpf->tracktype); + flotr = FindLengthOfTunnel(tile, direction); tpf->rd.cur_length += flotr.length; TPFSetTileBit(tpf, flotr.tile, 14); return flotr.tile; @@ -601,7 +602,7 @@ restart: /* We are not driving into the tunnel, or it * is an invalid tunnel */ goto popnext; - flotr = FindLengthOfTunnel(tile, direction, tpf->tracktype); + flotr = FindLengthOfTunnel(tile, direction); si.cur_length += flotr.length; tile = flotr.tile; } @@ -619,7 +620,7 @@ restart: // not a regular rail tile? if (!IS_TILETYPE(tile, MP_RAILWAY) || (bits = _map5[tile]) & 0xC0) { - bits = GetTileTrackStatus(tile, 0) & _tpfmode1_and[direction]; + bits = GetTileTrackStatus(tile, TRANSPORT_RAIL) & _tpfmode1_and[direction]; bits = (bits | (bits >> 8)) & 0x3F; break; } @@ -711,7 +712,7 @@ popnext: void NewTrainPathfind(uint tile, byte direction, TPFEnumProc *enum_proc, void *data, byte *cache) { if (!_patches.new_pathfinding) { - FollowTrack(tile, 0x3000, direction, enum_proc, NULL, data); + FollowTrack(tile, 0x3000 | TRANSPORT_RAIL, direction, enum_proc, NULL, data); } else { NewTrackPathFinder *tpf; diff --git a/pathfind.h b/pathfind.h index 5f12568b4..2f947cab6 100644 --- a/pathfind.h +++ b/pathfind.h @@ -58,7 +58,7 @@ typedef struct { uint tile; int length; } FindLengthOfTunnelResult; -FindLengthOfTunnelResult FindLengthOfTunnel(uint tile, int direction, byte type); +FindLengthOfTunnelResult FindLengthOfTunnel(uint tile, int direction); void NewTrainPathfind(uint tile, byte direction, TPFEnumProc *enum_proc, void *data, byte *cache); diff --git a/rail_cmd.c b/rail_cmd.c index cff3cea8e..d4dc81725 100644 --- a/rail_cmd.c +++ b/rail_cmd.c @@ -1762,7 +1762,7 @@ bool UpdateSignalsOnSegment(uint tile, byte direction) ssd.cur = ssd.presignal_exits = ssd.presignal_exits_free = 0; ssd.has_presignal = false; - FollowTrack(tile, 0xC000, direction, (TPFEnumProc*)SetSignalsEnumProc, SetSignalsAfterProc, &ssd); + FollowTrack(tile, 0xC000 | TRANSPORT_RAIL, direction, (TPFEnumProc*)SetSignalsEnumProc, SetSignalsAfterProc, &ssd); ChangeSignalStates(&ssd); // remember the result only for the first iteration. @@ -1933,11 +1933,11 @@ modify_me:; } -static uint32 GetTileTrackStatus_Track(uint tile, int mode) { +static uint32 GetTileTrackStatus_Track(uint tile, TransportType mode) { byte m5, a, b; uint32 ret; - if (mode != 0) + if (mode != TRANSPORT_RAIL) return 0; m5 = _map5[tile]; diff --git a/rail_gui.c b/rail_gui.c index ae1e4dc54..980695604 100644 --- a/rail_gui.c +++ b/rail_gui.c @@ -145,7 +145,7 @@ static void GenericPlaceSignals(uint tile) uint trackstat; int i; - trackstat = (byte)GetTileTrackStatus(tile,0); + trackstat = (byte)GetTileTrackStatus(tile, TRANSPORT_RAIL); if ((trackstat & 0x30) == 0x30) { trackstat = (_tile_fract_coords.x <= _tile_fract_coords.y) ? 0x20 : 0x10; diff --git a/road_cmd.c b/road_cmd.c index fa3ea30f1..b4e9774da 100644 --- a/road_cmd.c +++ b/road_cmd.c @@ -6,6 +6,7 @@ #include "player.h" #include "town.h" #include "gfx.h" +#include "table/directions.h" /* When true, GetTrackStatus for roads will treat roads under reconstruction * as normal roads instead of impassable. This is used when detecting whether @@ -119,7 +120,7 @@ bool IsRoadDepotTile(TileIndex tile) uint GetRoadBitsByTile(TileIndex tile) { - uint32 r = GetTileTrackStatus(tile, 2); + uint32 r = GetTileTrackStatus(tile, TRANSPORT_ROAD); return (byte)(r | (r >> 8)); } @@ -1023,18 +1024,20 @@ 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(uint tile, int mode) { - if (mode == 0) { +static uint32 GetTileTrackStatus_Road(uint tile, TransportType mode) { + if (mode == TRANSPORT_RAIL) { if ((_map5[tile] & 0xF0) != 0x10) return 0; return _map5[tile] & 8 ? 0x101 : 0x202; - } else if (mode == 2) { + } else if (mode == TRANSPORT_ROAD) { byte b = _map5[tile]; if ((b & 0xF0) == 0) { + /* Ordinary road */ if (!_road_special_gettrackstatus && (_map2[tile]&7) >= 6) return 0; return _road_trackbits[b&0xF] * 0x101; - } else if ((b&0xE0) == 0) { + } else if ((b&0xF0) == 0x10) { + /* Crossing */ uint32 r = 0x101; if (b&8) r <<= 1; @@ -1042,6 +1045,13 @@ static uint32 GetTileTrackStatus_Road(uint tile, int mode) { r *= 0x10001; } return r; + } else if ((b&0xF0) == 0x20) { + /* Depot */ + /* We reverse the dir because it points out of the + * exit, and we want to get in. Maybe we should return + * both dirs here? */ + byte dir = _reverse_dir[b&3]; + return 1 << _dir_to_straight_trackdir[dir]; } } return 0; diff --git a/roadveh_cmd.c b/roadveh_cmd.c index e3fec5681..cc8250ffc 100644 --- a/roadveh_cmd.c +++ b/roadveh_cmd.c @@ -371,7 +371,7 @@ static int FindClosestRoadDepot(Vehicle *v) /* search in all directions */ for(i=0; i!=4; i++) - FollowTrack(tile, 0x2002, i, (TPFEnumProc*)EnumRoadSignalFindDepot, NULL, &rfdd); + FollowTrack(tile, 0x2000 | TRANSPORT_ROAD, i, (TPFEnumProc*)EnumRoadSignalFindDepot, NULL, &rfdd); if (rfdd.best_length == (uint)-1) return -1; @@ -898,7 +898,7 @@ static bool FindRoadVehToOvertake(OvertakeData *od) { uint32 bits; - bits = GetTileTrackStatus(od->tile, 2)&0x3F; + bits = GetTileTrackStatus(od->tile, TRANSPORT_ROAD)&0x3F; if (!(od->tilebits & bits) || (bits&0x3C) || (bits & 0x3F3F0000)) return true; @@ -924,7 +924,7 @@ static void RoadVehCheckOvertake(Vehicle *v, Vehicle *u) if (v->u.road.state >= 32 || (v->u.road.state&7) > 1 ) return; - tt = (byte)(GetTileTrackStatus(v->tile, 2) & 0x3F); + tt = (byte)(GetTileTrackStatus(v->tile, TRANSPORT_ROAD) & 0x3F); if ((tt & 3) == 0) return; if ((tt & 0x3C) != 0) @@ -1020,31 +1020,24 @@ static int RoadFindPathToDest(Vehicle *v, uint tile, int direction) { uint32 r; - r = GetTileTrackStatus(tile, 2); + r = GetTileTrackStatus(tile, TRANSPORT_ROAD); signal = (uint16)(r >> 16); bitmask = (uint16)r; } - if (IS_TILETYPE(tile, MP_STREET)) { - - if ((_map5[tile]&0xF0) == 0x20 && v->owner == _map_owner[tile]) - bitmask |= _road_veh_fp_ax_or[_map5[tile]&3]; - - } else if (IS_TILETYPE(tile, MP_STATION)) { - if (_map_owner[tile] == OWNER_NONE || _map_owner[tile] == v->owner) { - Station *st = DEREF_STATION(_map2[tile]); - byte val = _map5[tile]; - - if (v->cargo_type != CT_PASSENGERS) { - if (IS_BYTE_INSIDE(val, 0x43, 0x47) && (_patches.roadveh_queue || st->truck_stop_status&3)) - bitmask |= _road_veh_fp_ax_or[(val-0x43)&3]; - } else { - if (IS_BYTE_INSIDE(val, 0x47, 0x4B) && (_patches.roadveh_queue || st->bus_stop_status&3)) - bitmask |= _road_veh_fp_ax_or[(val-0x47)&3]; - } - } - } + /* Most of the checks that used to be here, are now integrated into + * GetTileTrackStatus now. The only thing still remaining is the + * owner check for stations and depots, since GetTileTrackStatus + * doesn't know about owner */ + if (IS_TILETYPE(tile, MP_STREET) && (_map5[tile]&0xF0) == 0x20 && v->owner != _map_owner[tile]) + /* Depot not owned by us */ + bitmask = 0; + if (IS_TILETYPE(tile, MP_STATION) && _map_owner[tile] != OWNER_NONE && _map_owner[tile] != v->owner) + /* Station not owned by us */ + bitmask = 0; + + /* remove unreachable tracks */ bitmask &= _road_veh_fp_ax_and[direction]; if (bitmask == 0) { // reverse @@ -1096,7 +1089,7 @@ do_it:; if (best_track == -1) best_track = i; // in case we don't find the path, just pick a direction frd.maxtracklen = (uint)-1; frd.mindist = (uint)-1; - FollowTrack(tile, 0x3002, _road_pf_directions[i], (TPFEnumProc*)EnumRoadTrackFindDist, NULL, &frd); + FollowTrack(tile, 0x3000 | TRANSPORT_ROAD, _road_pf_directions[i], (TPFEnumProc*)EnumRoadTrackFindDist, NULL, &frd); if (frd.mindist < best_dist || (frd.mindist==best_dist && frd.maxtracklen < best_maxlen)) { best_dist = frd.mindist; diff --git a/ship_cmd.c b/ship_cmd.c index 009f2f18b..de853968e 100644 --- a/ship_cmd.c +++ b/ship_cmd.c @@ -15,7 +15,7 @@ static const uint16 _ship_sprites[] = {0x0E5D, 0x0E55, 0x0E65, 0x0E6D}; static const byte _ship_sometracks[4] = {0x19, 0x16, 0x25, 0x2A}; static byte GetTileShipTrackStatus(uint tile) { - uint32 r = GetTileTrackStatus(tile, 4); + uint32 r = GetTileTrackStatus(tile, TRANSPORT_WATER); return r | r >> 8; } @@ -492,7 +492,7 @@ static uint FindShipTrack(Vehicle *v, uint tile, int dir, uint bits, uint skipti pfs.best_bird_dist = (uint)-1; pfs.best_length = (uint)-1; - FollowTrack(tile, 0x3804, _ship_search_directions[i][dir], (TPFEnumProc*)ShipTrackFollower, NULL, &pfs); + FollowTrack(tile, 0x3800 | TRANSPORT_WATER, _ship_search_directions[i][dir], (TPFEnumProc*)ShipTrackFollower, NULL, &pfs); if (best_track >= 0) { if (pfs.best_bird_dist != 0) { @@ -569,7 +569,7 @@ static int ShipGetNewDirection(Vehicle *v, int x, int y) static int GetAvailShipTracks(uint tile, int dir) { - uint32 r = GetTileTrackStatus(tile, 4); + uint32 r = GetTileTrackStatus(tile, TRANSPORT_WATER); return (byte) ((r | r >> 8)) & _ship_sometracks[dir]; } diff --git a/station_cmd.c b/station_cmd.c index b2bd2f54a..c34aeb620 100644 --- a/station_cmd.c +++ b/station_cmd.c @@ -12,6 +12,7 @@ #include "economy.h" #include "player.h" #include "airport.h" +#include "table/directions.h" // FIXME -- need to be embedded into Airport variable. Is dynamically // deducteable from graphics-tile array, so will not be needed @@ -1837,21 +1838,34 @@ static void GetTileDesc_Station(uint tile, TileDesc *td) static const byte _tile_track_status_rail[8] = { 1,2,1,2,1,2,1,2 }; -static uint32 GetTileTrackStatus_Station(uint tile, int mode) { +static uint32 GetTileTrackStatus_Station(uint tile, TransportType mode) { uint i = _map5[tile]; uint j = 0; - if (mode == 0) { + if (mode == TRANSPORT_RAIL) { if (i < 8) j = _tile_track_status_rail[i]; - } else if (mode == 2) { - // not needed - } else if (mode == 4) { - // buoy + j += (j << 8); + } else if (mode == TRANSPORT_ROAD) { + Station *st = DEREF_STATION(_map2[tile]); + if ( (IS_BYTE_INSIDE(i, 0x43, 0x47) && (_patches.roadveh_queue || st->truck_stop_status&3)) || + (IS_BYTE_INSIDE(i, 0x47, 0x4B) && (_patches.roadveh_queue || st->bus_stop_status&3)) ) { + /* This is a bus/truck stop, and there is free space + * (or we allow queueing) */ + + /* We reverse the dir because it points out of the + * exit, and we want to get in. Maybe we should return + * both dirs here? */ + byte dir = _reverse_dir[(i-0x43)&3]; + j = 1 << _dir_to_straight_trackdir[dir]; + } + } else if (mode == TRANSPORT_WATER) { + // buoy is coded as a station, it is always on open water + // (0x3F, all tracks available) if (i == 0x52) j = 0x3F; + j += (j << 8); } - - return j + (j << 8); + return j; } static void TileLoop_Station(uint tile) diff --git a/town_cmd.c b/town_cmd.c index 719ba2b8b..6ed0b6151 100644 --- a/town_cmd.c +++ b/town_cmd.c @@ -319,7 +319,7 @@ static void GetTileDesc_Town(uint tile, TileDesc *td) td->owner = OWNER_TOWN; } -static uint32 GetTileTrackStatus_Town(uint tile, int mode) +static uint32 GetTileTrackStatus_Town(uint tile, TransportType mode) { /* not used */ return 0; @@ -540,7 +540,7 @@ static void GrowTownInTile(uint *tile_ptr, uint mask, int block, Town *t1) // Reached a tunnel? Then continue at the other side of it. if (IS_TILETYPE(tile, MP_TUNNELBRIDGE) && (_map5[tile]&~3)==4) { - FindLengthOfTunnelResult flotr = FindLengthOfTunnel(tile, _map5[tile]&3, 2); + FindLengthOfTunnelResult flotr = FindLengthOfTunnel(tile, _map5[tile]&3); *tile_ptr = flotr.tile; return; } diff --git a/train_cmd.c b/train_cmd.c index dd5bc6008..cb6306d91 100644 --- a/train_cmd.c +++ b/train_cmd.c @@ -2035,7 +2035,7 @@ static void TrainController(Vehicle *v) /* Get the status of the tracks in the new tile and mask * away the bits that aren't reachable. */ - ts = GetTileTrackStatus(gp.new_tile, 0) & _reachable_tracks[dir >> 1]; + ts = GetTileTrackStatus(gp.new_tile, TRANSPORT_RAIL) & _reachable_tracks[dir >> 1]; /* Combine the from & to directions. * Now, the lower byte contains the track status, and the byte at bit 16 contains @@ -2347,7 +2347,7 @@ static void TrainCheckIfLineEnds(Vehicle *v) /* Calculate next tile */ tile += _tileoffs_by_dir[t]; // determine the track status on the next tile. - ts = GetTileTrackStatus(tile, 0) & _reachable_tracks[t]; + ts = GetTileTrackStatus(tile, TRANSPORT_RAIL) & _reachable_tracks[t]; /* Calc position within the current tile ?? */ x = v->x_pos & 0xF; @@ -86,6 +86,20 @@ enum MapTileTypes { MP_UNMOVABLE }; +typedef enum TransportTypes { + /* These constants are for now linked to the representation of bridges + * and tunnels, so they can be used by GetTileTrackStatus_TunnelBridge + * to compare against the map5 array. In an ideal world, these + * constants would be used everywhere when accessing tunnels and + * bridges. For now, you should just not change the values for road + * and rail. + */ + TRANSPORT_RAIL = 0, + TRANSPORT_ROAD = 1, + TRANSPORT_WATER, + TRANSPORT_MAX +} TransportType; + typedef struct TileInfo { uint x; uint y; @@ -231,7 +245,26 @@ typedef uint GetSlopeZProc(TileInfo *ti); typedef int32 ClearTileProc(uint tile, byte flags); typedef void GetAcceptedCargoProc(uint tile, AcceptedCargo *res); typedef void GetTileDescProc(uint tile, TileDesc *td); -typedef uint32 GetTileTrackStatusProc(uint tile, int mode); +/* 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). + * + * 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 + * + * 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. + */ +typedef uint32 GetTileTrackStatusProc(uint tile, TransportType mode); typedef void GetProducedCargoProc(uint tile, byte *b); typedef void ClickTileProc(uint tile); typedef void AnimateTileProc(uint tile); diff --git a/tunnelbridge_cmd.c b/tunnelbridge_cmd.c index 7a7af310a..2ded3e90c 100644 --- a/tunnelbridge_cmd.c +++ b/tunnelbridge_cmd.c @@ -1296,34 +1296,49 @@ static void ClickTile_TunnelBridge(uint tile) } -static uint32 GetTileTrackStatus_TunnelBridge(uint tile, int mode) +static uint32 GetTileTrackStatus_TunnelBridge(uint tile, TransportType mode) { uint32 result; - byte t, m5 = _map5[tile]; + byte m5 = _map5[tile]; if ((m5 & 0xF0) == 0) { - if (((m5 & 0xC) >> 1) == mode) { /* XXX: possible problem when switching mode constants */ + /* This is a tunnel */ + if (((m5 & 0xC) >> 2) == mode) { + /* Tranport in the tunnel is compatible */ return m5&1 ? 0x202 : 0x101; } } else if (m5 & 0x80) { + /* This is a bridge */ result = 0; - if ((m5 & 6) == mode) { + if (((m5 & 0x6) >> 1) == mode) { + /* Transport over the bridge is compatible */ result = m5&1 ? 0x202 : 0x101; } if (m5 & 0x40) { - t = m5; - if (!(t & 0x20)) { - if ((t &= 0x18) != 8) + /* Bridge middle part */ + if (!(m5 & 0x20)) { + /* Clear ground or water underneath */ + if ((m5 &= 0x18) != 8) + /* Clear ground */ + return result; + else + if (mode != TRANSPORT_WATER) + return result; + } else { + /* Transport underneath */ + if ((m5 & 0x18) >> 3 != mode) + /* Incompatible transport underneath */ return result; - t = (t&0xE7) | 0x30; } - - if ((t & 0x18) >> 2 != mode) - return result; - + /* If we've not returned yet, there is a compatible + * transport or water beneath, so we can add it to + * result */ + /* Why is this xor'd ? Can't it just be or'd? */ result ^= m5&1 ? 0x101 : 0x202; } return result; + } else { + assert(0); /* This should never occur */ } return 0; } diff --git a/water_cmd.c b/water_cmd.c index a7740f3e1..fa22d5a1e 100644 --- a/water_cmd.c +++ b/water_cmd.c @@ -600,12 +600,12 @@ void TileLoop_Water(uint tile) static const byte _coast_tracks[16] = {0, 32, 4, 0, 16, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0}; static const byte _shipdepot_tracks[4] = {1,1,2,2}; static const byte _shiplift_tracks[12] = {1,2,1,2,1,2,1,2,1,2,1,2}; -static uint32 GetTileTrackStatus_Water(uint tile, int mode) +static uint32 GetTileTrackStatus_Water(uint tile, TransportType mode) { uint m5; uint b; - if (mode != 4) + if (mode != TRANSPORT_WATER) return 0; m5 = _map5[tile]; |