From 613c7e9bf3f437b7ee83908e3f1f77928addc196 Mon Sep 17 00:00:00 2001 From: Richard Fine Date: Sat, 5 Jan 2019 13:58:32 +0000 Subject: [PATCH 1/5] Introduce 'Direction' typedef Directions are used quite widely across the codebase, but right now we just use uint8_t for them. Defining a proper type makes the intention clearer. --- src/openrct2/world/Location.hpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/openrct2/world/Location.hpp b/src/openrct2/world/Location.hpp index 950a2937c6..a2de7fd2ef 100644 --- a/src/openrct2/world/Location.hpp +++ b/src/openrct2/world/Location.hpp @@ -129,10 +129,12 @@ struct TileCoordsXYZ int32_t x = 0, y = 0, z = 0; }; +typedef uint8_t Direction; + struct CoordsXYZD { int32_t x, y, z; - uint8_t direction; + Direction direction; bool isNull() const { @@ -143,7 +145,7 @@ struct CoordsXYZD struct TileCoordsXYZD { int32_t x, y, z; - uint8_t direction; + Direction direction; bool isNull() const { From fd606542381582dea09ab13a72a262b3b1f9f390 Mon Sep 17 00:00:00 2001 From: Richard Fine Date: Sat, 5 Jan 2019 14:28:24 +0000 Subject: [PATCH 2/5] Add comments and direction_reverse function Add a bit of Javadocs, and introduce helper function for reversing directions because the ^2 trick used elsewhere in the codebase is not immediately obvious exactly what it does. --- src/openrct2/world/Location.hpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/openrct2/world/Location.hpp b/src/openrct2/world/Location.hpp index a2de7fd2ef..ea87892ee1 100644 --- a/src/openrct2/world/Location.hpp +++ b/src/openrct2/world/Location.hpp @@ -129,8 +129,26 @@ struct TileCoordsXYZ int32_t x = 0, y = 0, z = 0; }; +/** + * Cardinal directions are represented by the Direction type. It has four + * possible values: + * 0 is X-decreasing + * 1 is Y-increasing + * 2 is X-increasing + * 3 is Y-decreasing + * Direction is not used to model up/down, or diagonal directions. + */ typedef uint8_t Direction; +/** + * Given a direction, return the direction that points the other way, + * on the same axis. + */ +inline Direction direction_reverse(const Direction& dir) +{ + return dir ^ 2; +} + struct CoordsXYZD { int32_t x, y, z; From e90e9dd73f44c04ba1df18e75890ff62c0ab72ca Mon Sep 17 00:00:00 2001 From: Richard Fine Date: Sat, 5 Jan 2019 15:41:19 +0000 Subject: [PATCH 3/5] Introduce many uses of direction_reverse Change many of the places doing the ^2 trick to use direction_reverse instead, for improved readability. --- src/openrct2-ui/windows/Footpath.cpp | 10 ++--- src/openrct2-ui/windows/Map.cpp | 2 +- src/openrct2-ui/windows/MazeConstruction.cpp | 2 +- src/openrct2-ui/windows/RideConstruction.cpp | 13 +++--- src/openrct2-ui/windows/TopToolbar.cpp | 2 +- src/openrct2/Editor.cpp | 2 +- .../paint/tile_element/Paint.Banner.cpp | 2 +- .../paint/tile_element/Paint.Surface.cpp | 2 +- src/openrct2/peep/Guest.cpp | 12 +++--- src/openrct2/peep/GuestPathfinding.cpp | 24 +++++------ src/openrct2/peep/Peep.cpp | 10 ++--- src/openrct2/peep/Staff.cpp | 15 +++---- src/openrct2/ride/Ride.cpp | 32 +++++++-------- src/openrct2/ride/Track.cpp | 2 +- src/openrct2/ride/TrackDesign.cpp | 4 +- src/openrct2/ride/Vehicle.cpp | 4 +- src/openrct2/world/Footpath.cpp | 40 +++++++++---------- src/openrct2/world/Map.cpp | 2 +- src/openrct2/world/Park.cpp | 2 +- 19 files changed, 92 insertions(+), 90 deletions(-) diff --git a/src/openrct2-ui/windows/Footpath.cpp b/src/openrct2-ui/windows/Footpath.cpp index 6d9ae8bd39..d75d8b397e 100644 --- a/src/openrct2-ui/windows/Footpath.cpp +++ b/src/openrct2-ui/windows/Footpath.cpp @@ -1017,7 +1017,7 @@ static void footpath_remove_tile_element(TileElement* tileElement) if (tileElement->AsPath()->IsSloped()) { uint8_t slopeDirection = tileElement->AsPath()->GetSlopeDirection(); - slopeDirection ^= 2; + slopeDirection = direction_reverse(slopeDirection); if (slopeDirection == gFootpathConstructDirection) { z += 2; @@ -1025,7 +1025,7 @@ static void footpath_remove_tile_element(TileElement* tileElement) } // Find a connected edge - int32_t edge = gFootpathConstructDirection ^ 2; + int32_t edge = direction_reverse(gFootpathConstructDirection); if (!(tileElement->AsPath()->GetEdges() & (1 << edge))) { edge = (edge + 1) & 3; @@ -1037,7 +1037,7 @@ static void footpath_remove_tile_element(TileElement* tileElement) edge = (edge - 1) & 3; if (!(tileElement->AsPath()->GetEdges() & (1 << edge))) { - edge ^= 2; + edge = direction_reverse(edge); } } } @@ -1048,7 +1048,7 @@ static void footpath_remove_tile_element(TileElement* tileElement) gFootpathConstructFromPosition.x, gFootpathConstructFromPosition.y, tileElement->base_height, GAME_COMMAND_FLAG_APPLY); // Move selection - edge ^= 2; + edge = direction_reverse(edge); x = gFootpathConstructFromPosition.x - CoordsDirectionDelta[edge].x; y = gFootpathConstructFromPosition.y - CoordsDirectionDelta[edge].y; gFootpathConstructFromPosition.x = x; @@ -1086,7 +1086,7 @@ static TileElement* footpath_get_tile_element_to_remove() { if (tileElement->AsPath()->IsSloped()) { - if (((tileElement->AsPath()->GetSlopeDirection()) ^ 2) != gFootpathConstructDirection) + if (direction_reverse(tileElement->AsPath()->GetSlopeDirection()) != gFootpathConstructDirection) { continue; } diff --git a/src/openrct2-ui/windows/Map.cpp b/src/openrct2-ui/windows/Map.cpp index c2566a81a0..196135951e 100644 --- a/src/openrct2-ui/windows/Map.cpp +++ b/src/openrct2-ui/windows/Map.cpp @@ -1293,7 +1293,7 @@ static void window_map_set_peep_spawn_tool_update(int32_t x, int32_t y) gMapSelectPositionA.y = mapY; gMapSelectPositionB.x = mapX; gMapSelectPositionB.y = mapY; - gMapSelectArrowDirection = direction ^ 2; + gMapSelectArrowDirection = direction_reverse(direction); gMapSelectArrowPosition.x = mapX; gMapSelectArrowPosition.y = mapY; gMapSelectArrowPosition.z = mapZ; diff --git a/src/openrct2-ui/windows/MazeConstruction.cpp b/src/openrct2-ui/windows/MazeConstruction.cpp index b6dffbf4bc..b85c359ea4 100644 --- a/src/openrct2-ui/windows/MazeConstruction.cpp +++ b/src/openrct2-ui/windows/MazeConstruction.cpp @@ -376,7 +376,7 @@ static void window_maze_construction_entrance_tooldown(int32_t x, int32_t y, rct } money32 cost = game_do_command( - x, GAME_COMMAND_FLAG_APPLY | ((direction ^ 2) << 8), y, rideIndex | (entranceExitType << 8), + x, GAME_COMMAND_FLAG_APPLY | (direction_reverse(direction) << 8), y, rideIndex | (entranceExitType << 8), GAME_COMMAND_PLACE_RIDE_ENTRANCE_OR_EXIT, gRideEntranceExitPlaceStationIndex, 0); if (cost == MONEY32_UNDEFINED) diff --git a/src/openrct2-ui/windows/RideConstruction.cpp b/src/openrct2-ui/windows/RideConstruction.cpp index dafed7c2b8..f666810746 100644 --- a/src/openrct2-ui/windows/RideConstruction.cpp +++ b/src/openrct2-ui/windows/RideConstruction.cpp @@ -1713,7 +1713,7 @@ static void window_ride_construction_construct(rct_window* w) // game_command_callback_ride_construct_placed_front/back Please update both ends if there are any changes here if (_rideConstructionState == RIDE_CONSTRUCTION_STATE_BACK) { - trackDirection = _currentTrackPieceDirection ^ 2; + trackDirection = direction_reverse(_currentTrackPieceDirection); x = _currentTrackBeginX; y = _currentTrackBeginY; z = _currentTrackBeginZ; @@ -2568,7 +2568,7 @@ void sub_6C94D8() if (direction >= 4) direction += 4; if (_rideConstructionState == RIDE_CONSTRUCTION_STATE_BACK) - direction ^= 2; + direction = direction_reverse(direction); gMapSelectArrowDirection = direction; gMapSelectFlags &= ~MAP_SELECT_FLAG_ENABLE_ARROW; if (_currentTrackSelectionFlags & TRACK_SELECTION_FLAG_ARROW) @@ -3607,7 +3607,8 @@ void ride_construction_toolupdate_construct(int32_t screenX, int32_t screenY) pathsByDir[i] = map_get_footpath_element((x >> 5) + DirOffsets[i].x, (y >> 5) + DirOffsets[i].y, (z >> 3) - 2); if (pathsByDir[i] - && (!(pathsByDir[i])->AsPath()->IsSloped() || (pathsByDir[i])->AsPath()->GetSlopeDirection() != (i ^ 2))) + && (!(pathsByDir[i])->AsPath()->IsSloped() + || (pathsByDir[i])->AsPath()->GetSlopeDirection() != direction_reverse(i))) { pathsByDir[i] = nullptr; } @@ -3674,13 +3675,13 @@ void ride_construction_toolupdate_entrance_exit(int32_t screenX, int32_t screenY gMapSelectPositionA.y = y; gMapSelectPositionB.x = x; gMapSelectPositionB.y = y; - gMapSelectArrowDirection = direction ^ 2; + gMapSelectArrowDirection = direction_reverse(direction); gMapSelectArrowPosition.x = x; gMapSelectArrowPosition.y = y; gMapSelectArrowPosition.z = _unkF44188.z * 8; map_invalidate_selection_rect(); - direction = gRideEntranceExitPlaceDirection ^ 2; + direction = direction_reverse(gRideEntranceExitPlaceDirection); stationNum = gRideEntranceExitPlaceStationIndex; if (!(_currentTrackSelectionFlags & TRACK_SELECTION_FLAG_ENTRANCE_OR_EXIT) || x != gRideEntranceExitGhostPosition.x || y != gRideEntranceExitGhostPosition.y || direction != gRideEntranceExitGhostPosition.direction @@ -3928,7 +3929,7 @@ static void ride_construction_tooldown_entrance_exit(int32_t screenX, int32_t sc game_command_callback = game_command_callback_place_ride_entrance_or_exit; game_do_command( - _unkF44188.x, (GAME_COMMAND_FLAG_APPLY) | ((gRideEntranceExitPlaceDirection ^ 2) << 8), _unkF44188.y, + _unkF44188.x, (GAME_COMMAND_FLAG_APPLY) | (direction_reverse(gRideEntranceExitPlaceDirection) << 8), _unkF44188.y, gRideEntranceExitPlaceRideIndex | (gRideEntranceExitPlaceType << 8), GAME_COMMAND_PLACE_RIDE_ENTRANCE_OR_EXIT, gRideEntranceExitPlaceStationIndex, 0); } diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index f11f255355..8900a5d00b 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -1612,7 +1612,7 @@ static void sub_6E1F34( if (tile_element->AsPath()->IsSloped()) { - if (rotation != ((tile_element->AsPath()->GetSlopeDirection()) ^ 2)) + if (rotation != direction_reverse(tile_element->AsPath()->GetSlopeDirection())) { z += 2; } diff --git a/src/openrct2/Editor.cpp b/src/openrct2/Editor.cpp index fd3925b7b4..d0ee7c04cb 100644 --- a/src/openrct2/Editor.cpp +++ b/src/openrct2/Editor.cpp @@ -499,7 +499,7 @@ namespace Editor int32_t x = parkEntrance.x; int32_t y = parkEntrance.y; int32_t z = parkEntrance.z / 8; - int32_t direction = parkEntrance.direction ^ 2; + int32_t direction = direction_reverse(parkEntrance.direction); switch (footpath_is_connected_to_map_edge(x, y, z, direction, 0)) { diff --git a/src/openrct2/paint/tile_element/Paint.Banner.cpp b/src/openrct2/paint/tile_element/Paint.Banner.cpp index e08a2f72a4..964b36631b 100644 --- a/src/openrct2/paint/tile_element/Paint.Banner.cpp +++ b/src/openrct2/paint/tile_element/Paint.Banner.cpp @@ -78,7 +78,7 @@ void banner_paint(paint_session* session, uint8_t direction, int32_t height, con sub_98197C(session, image_id, 0, 0, 1, 1, 0x15, height, boundBoxOffsetX, boundBoxOffsetY, boundBoxOffsetZ); // Opposite direction - direction ^= 2; + direction = direction_reverse(direction); direction--; // If text not showing / ghost if (direction >= 2 || (tile_element->flags & TILE_ELEMENT_FLAG_GHOST)) diff --git a/src/openrct2/paint/tile_element/Paint.Surface.cpp b/src/openrct2/paint/tile_element/Paint.Surface.cpp index d2a0f1b185..41f456f0a2 100644 --- a/src/openrct2/paint/tile_element/Paint.Surface.cpp +++ b/src/openrct2/paint/tile_element/Paint.Surface.cpp @@ -1069,7 +1069,7 @@ void surface_paint(paint_session* session, uint8_t direction, uint16_t height, c { sub_98196C(session, SPR_TERRAIN_SELECTION_SQUARE_SIMPLE, 0, 0, 32, 32, 16, spawn.z); - const int32_t offset = ((spawn.direction ^ 2) + rotation) & 3; + const int32_t offset = (direction_reverse(spawn.direction) + rotation) & 3; const uint32_t image_id = (PEEP_SPAWN_ARROW_0 + offset) | 0x20380000; sub_98196C(session, image_id, 0, 0, 32, 32, 19, spawn.z); } diff --git a/src/openrct2/peep/Guest.cpp b/src/openrct2/peep/Guest.cpp index 3108bc970e..b2d90d5f2c 100644 --- a/src/openrct2/peep/Guest.cpp +++ b/src/openrct2/peep/Guest.cpp @@ -3271,7 +3271,7 @@ void rct_peep::UpdateBuying() sprite_direction ^= 0x10; destination_x = next_x + 16; destination_y = next_y + 16; - direction ^= 2; + direction = direction_reverse(direction); SetState(PEEP_STATE_WALKING); return; @@ -4052,7 +4052,7 @@ void rct_peep::UpdateRideLeaveVehicle() CoordsXYZD platformLocation; platformLocation.z = ride->stations[current_ride_station].Height; - platformLocation.direction = exitLocation.direction ^ (1 << 1); + platformLocation.direction = direction_reverse(exitLocation.direction); if (!ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_16)) { @@ -4096,7 +4096,7 @@ void rct_peep::UpdateRideLeaveVehicle() specialDirection &= 3; if (vehicle->var_CD == 6) - specialDirection ^= (1 << 1); + specialDirection = direction_reverse(specialDirection); } } @@ -4437,7 +4437,7 @@ void rct_peep::UpdateRideApproachExitWaypoints() auto exit = ride_get_exit_location(current_ride, current_ride_station); actionX = exit.x; actionY = exit.y; - uint8_t exit_direction = exit.direction ^ 2; + uint8_t exit_direction = direction_reverse(exit.direction); actionX *= 32; actionY *= 32; @@ -4699,7 +4699,7 @@ void rct_peep::UpdateRideLeaveSpiralSlide() actionX = exit.x * 32 + 16; actionY = exit.y * 32 + 16; - exit.direction ^= 2; + exit.direction = direction_reverse(exit.direction); int16_t xShift = word_981D6C[exit.direction].x; int16_t yShift = word_981D6C[exit.direction].y; @@ -4807,7 +4807,7 @@ void rct_peep::UpdateRideMazePathfinding() if (openHedges == 0) return; - uint8_t mazeLastEdge = maze_last_edge ^ (1 << 1); + uint8_t mazeLastEdge = direction_reverse(maze_last_edge); openHedges &= ~(1 << mazeLastEdge); if (openHedges == 0) openHedges |= (1 << mazeLastEdge); diff --git a/src/openrct2/peep/GuestPathfinding.cpp b/src/openrct2/peep/GuestPathfinding.cpp index eb15e5549f..8c06dfda14 100644 --- a/src/openrct2/peep/GuestPathfinding.cpp +++ b/src/openrct2/peep/GuestPathfinding.cpp @@ -144,7 +144,7 @@ static int32_t guest_surface_path_finding(rct_peep* peep) { x += CoordsDirectionDelta[randDirection].x; y += CoordsDirectionDelta[randDirection].y; - uint8_t backwardsDirection = randDirection ^ (1 << 1); + uint8_t backwardsDirection = direction_reverse(randDirection); if (!fence_in_the_way(x, y, z, z + 4, backwardsDirection)) { @@ -169,7 +169,7 @@ static int32_t guest_surface_path_finding(rct_peep* peep) { x += CoordsDirectionDelta[randDirection].x; y += CoordsDirectionDelta[randDirection].y; - uint8_t backwardsDirection = randDirection ^ (1 << 1); + uint8_t backwardsDirection = direction_reverse(randDirection); if (!fence_in_the_way(x, y, z, z + 4, backwardsDirection)) { @@ -189,7 +189,7 @@ static int32_t guest_surface_path_finding(rct_peep* peep) { x += CoordsDirectionDelta[randDirection].x; y += CoordsDirectionDelta[randDirection].y; - uint8_t backwardsDirection = randDirection ^ (1 << 1); + uint8_t backwardsDirection = direction_reverse(randDirection); if (!fence_in_the_way(x, y, z, z + 4, backwardsDirection)) { @@ -342,7 +342,7 @@ static uint8_t footpath_element_dest_in_dir( return PATH_SEARCH_WIDE; uint8_t edges = path_get_permitted_edges(tileElement); - edges &= ~(1 << (chosenDirection ^ 2)); + edges &= ~(1 << direction_reverse(chosenDirection)); loc.z = tileElement->base_height; for (direction = 0; direction < 4; direction++) @@ -1489,13 +1489,13 @@ int32_t peep_pathfind_choose_direction(TileCoordsXYZ loc, rct_peep* peep) peep->pathfind_history[i].direction &= ~(1 << chosen_edge); /* Also remove the edge through which the peep * entered the junction from those left to try. */ - peep->pathfind_history[i].direction &= ~(1 << (peep->direction ^ 2)); + peep->pathfind_history[i].direction &= ~(1 << direction_reverse(peep->direction)); #if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 if (gPathFindDebug) { log_verbose( "Updating existing pf_history (in index: %d) for %d,%d,%d without entry edge %d & exit edge %d.", i, - loc.x, loc.y, loc.z, peep->direction ^ 2, chosen_edge); + loc.x, loc.y, loc.z, direction_reverse(peep->direction), chosen_edge); } #endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 return chosen_edge; @@ -1514,13 +1514,13 @@ int32_t peep_pathfind_choose_direction(TileCoordsXYZ loc, rct_peep* peep) peep->pathfind_history[i].direction &= ~(1 << chosen_edge); /* Also remove the edge through which the peep * entered the junction from those left to try. */ - peep->pathfind_history[i].direction &= ~(1 << (peep->direction ^ 2)); + peep->pathfind_history[i].direction &= ~(1 << direction_reverse(peep->direction)); #if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 if (gPathFindDebug) { log_verbose( "Storing new pf_history (in index: %d) for %d,%d,%d without entry edge %d & exit edge %d.", i, loc.x, loc.y, - loc.z, peep->direction ^ 2, chosen_edge); + loc.z, direction_reverse(peep->direction), chosen_edge); } #endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 } @@ -1788,7 +1788,7 @@ static void get_ride_queue_end(TileCoordsXYZ& loc) if (!tileElement->AsPath()->IsSloped()) break; - if (tileElement->AsPath()->GetSlopeDirection() != (direction ^ 2)) + if (tileElement->AsPath()->GetSlopeDirection() != direction_reverse(direction)) break; baseZ -= 2; @@ -1803,7 +1803,7 @@ static void get_ride_queue_end(TileCoordsXYZ& loc) if (!tileElement->AsPath()->IsQueue()) break; - if (!(tileElement->AsPath()->GetEdges() & (1 << (direction ^ (1 << 1))))) + if (!(tileElement->AsPath()->GetEdges() & (1 << direction_reverse(direction)))) break; if (firstPathElement == nullptr) @@ -1819,7 +1819,7 @@ static void get_ride_queue_end(TileCoordsXYZ& loc) if (tileElement->AsPath()->GetEdges() & (1 << (direction))) continue; - direction ^= (1 << 1); + direction = direction_reverse(direction); // More queue to go. if (tileElement->AsPath()->GetEdges() & (1 << (direction))) continue; @@ -1901,7 +1901,7 @@ int32_t guest_path_finding(rct_peep* peep) edges = adjustedEdges; } - int8_t direction = peep->direction ^ (1 << 1); + int8_t direction = direction_reverse(peep->direction); // Check if in a dead end (i.e. only edge is where the peep came from) if (!(edges & ~(1 << direction))) { diff --git a/src/openrct2/peep/Peep.cpp b/src/openrct2/peep/Peep.cpp index b24790ba8f..644c8df03b 100644 --- a/src/openrct2/peep/Peep.cpp +++ b/src/openrct2/peep/Peep.cpp @@ -2413,7 +2413,7 @@ static bool peep_update_queue_position(rct_peep* peep, uint8_t previous_action) */ static void peep_return_to_centre_of_tile(rct_peep* peep) { - peep->direction ^= (1 << 1); + peep->direction = direction_reverse(peep->direction); peep->destination_x = (peep->x & 0xFFE0) + 16; peep->destination_y = (peep->y & 0xFFE0) + 16; peep->destination_tolerance = 5; @@ -2544,7 +2544,7 @@ static void peep_interact_with_entrance( uint8_t entranceDirection = tile_element->GetDirection(); if (entranceDirection != peep->direction) { - if ((entranceDirection ^ (1 << 1)) != peep->direction) + if (direction_reverse(entranceDirection) != peep->direction) { peep_return_to_centre_of_tile(peep); return; @@ -2642,7 +2642,7 @@ static void peep_interact_with_entrance( break; } - if ((slopeDirection ^ (1 << 1)) != entranceDirection) + if (direction_reverse(slopeDirection) != entranceDirection) continue; if (z - 2 != nextTileElement->base_height) @@ -2926,7 +2926,7 @@ static void peep_interact_with_path(rct_peep* peep, int16_t x, int16_t y, TileEl if ((tile_element->AsPath()->HasQueueBanner()) && (tile_element->AsPath()->GetQueueBannerDirection() - == ((peep->direction) ^ 2)) // Ride sign is facing the direction the peep is walking + == direction_reverse(peep->direction)) // Ride sign is facing the direction the peep is walking ) { /* Peep is approaching the entrance of a ride queue. @@ -3099,7 +3099,7 @@ bool is_valid_path_z_and_direction(TileElement* tileElement, int32_t currentZ, i } else { - slopeDirection ^= 2; + slopeDirection = direction_reverse(slopeDirection); if (slopeDirection != currentDirection) return false; if (currentZ != tileElement->base_height + 2) diff --git a/src/openrct2/peep/Staff.cpp b/src/openrct2/peep/Staff.cpp index d954d27a9c..5503f6f96a 100644 --- a/src/openrct2/peep/Staff.cpp +++ b/src/openrct2/peep/Staff.cpp @@ -1070,10 +1070,10 @@ static bool staff_path_finding_handyman(rct_peep* peep) } else { - pathDirections &= ~(1 << (peep->direction ^ (1 << 1))); + pathDirections &= ~(1 << direction_reverse(peep->direction)); if (pathDirections == 0) { - pathDirections |= 1 << (peep->direction ^ (1 << 1)); + pathDirections |= 1 << direction_reverse(peep->direction); } } @@ -1137,7 +1137,8 @@ static uint8_t staff_direction_surface(rct_peep* peep, uint8_t initialDirection) if (fence_in_the_way(peep->next_x, peep->next_y, peep->next_z, peep->next_z + 4, direction) == true) continue; - if (fence_in_the_way(peep->next_x, peep->next_y, peep->next_z, peep->next_z + 4, direction ^ (1 << 1)) == true) + if (fence_in_the_way(peep->next_x, peep->next_y, peep->next_z, peep->next_z + 4, direction_reverse(direction)) + == true) continue; LocationXY16 chosenTile = { static_cast(peep->next_x + CoordsDirectionDelta[direction].x), @@ -1225,10 +1226,10 @@ static uint8_t staff_mechanic_direction_path(rct_peep* peep, uint8_t validDirect } // Check if this is dead end - i.e. only way out is the reverse direction. - pathDirections &= ~(1 << (peep->direction ^ (1 << 1))); + pathDirections &= ~(1 << direction_reverse(peep->direction)); if (pathDirections == 0) { - pathDirections |= (1 << (peep->direction ^ (1 << 1))); + pathDirections |= (1 << direction_reverse(peep->direction)); } direction = bitscanforward(pathDirections); @@ -1361,10 +1362,10 @@ static uint8_t staff_direction_path(rct_peep* peep, uint8_t validDirections, Til return staff_direction_surface(peep, scenario_rand() & 3); } - pathDirections &= ~(1 << (peep->direction ^ (1 << 1))); + pathDirections &= ~(1 << direction_reverse(peep->direction)); if (pathDirections == 0) { - pathDirections |= (1 << (peep->direction ^ (1 << 1))); + pathDirections |= (1 << direction_reverse(peep->direction)); } direction = bitscanforward(pathDirections); diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index c8fcb0a846..c63aaa50ca 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -671,7 +671,7 @@ bool track_block_get_previous_from_zero( Ride* ride = get_ride(rideIndex); uint8_t directionStart = direction; - direction ^= (1 << 1); + direction = direction_reverse(direction); if (!(direction & (1 << 2))) { @@ -685,7 +685,7 @@ bool track_block_get_previous_from_zero( outTrackBeginEnd->end_x = x; outTrackBeginEnd->end_y = y; outTrackBeginEnd->begin_element = nullptr; - outTrackBeginEnd->begin_direction = directionStart ^ (1 << 1); + outTrackBeginEnd->begin_direction = direction_reverse(directionStart); return 0; } @@ -747,7 +747,7 @@ bool track_block_get_previous_from_zero( - nextTrackBlock->z; outTrackBeginEnd->begin_direction = nextRotation; - outTrackBeginEnd->end_direction = directionStart ^ (1 << 1); + outTrackBeginEnd->end_direction = direction_reverse(directionStart); return 1; } while (!(tileElement++)->IsLastForTile()); @@ -755,7 +755,7 @@ bool track_block_get_previous_from_zero( outTrackBeginEnd->end_y = y; outTrackBeginEnd->begin_z = z; outTrackBeginEnd->begin_element = nullptr; - outTrackBeginEnd->end_direction = directionStart ^ (1 << 1); + outTrackBeginEnd->end_direction = direction_reverse(directionStart); return 0; } @@ -1191,7 +1191,7 @@ void ride_remove_peeps(int32_t rideIndex) exitZ = (exitZ * 8) + 2; // Reverse direction - exitDirection ^= 2; + exitDirection = direction_reverse(exitDirection); exitDirection *= 8; } @@ -1673,7 +1673,7 @@ void ride_construction_set_default_next_piece() x = _currentTrackBeginX; y = _currentTrackBeginY; z = _currentTrackBeginZ; - direction = _currentTrackPieceDirection ^ 2; + direction = direction_reverse(_currentTrackPieceDirection); if (!track_block_get_next_from_zero(x, y, z, rideIndex, direction, &xyElement, &z, &direction, false)) { ride_construction_reset_current_piece(); @@ -3557,7 +3557,7 @@ static void ride_shop_connected(Ride* ride, int32_t ride_idx) entrance_directions >>= 1; // Flip direction north<->south, east<->west - uint8_t face_direction = count ^ 2; + uint8_t face_direction = direction_reverse(count); int32_t y2 = y - CoordsDirectionDelta[face_direction].y; int32_t x2 = x - CoordsDirectionDelta[face_direction].x; @@ -4451,7 +4451,7 @@ static void sub_6B5952(int32_t rideIndex) continue; int32_t direction = tileElement->GetDirection(); - footpath_chain_ride_queue(rideIndex, i, x, y, tileElement, direction ^ 2); + footpath_chain_ride_queue(rideIndex, i, x, y, tileElement, direction_reverse(direction)); } while (!(tileElement++)->IsLastForTile()); } } @@ -6330,7 +6330,7 @@ void game_command_callback_ride_construct_placed_back( int32_t trackDirection, x, y, z; track_begin_end trackBeginEnd; - trackDirection = _currentTrackPieceDirection ^ 2; + trackDirection = direction_reverse(_currentTrackPieceDirection); x = _currentTrackBeginX; y = _currentTrackBeginY; z = _currentTrackBeginZ; @@ -7225,8 +7225,8 @@ void ride_get_entrance_or_exit_position_from_screen_position( continue; if (tileElement->AsTrack()->GetTrackType() == TRACK_ELEM_INVERTED_90_DEG_UP_TO_FLAT_QUARTER_LOOP) { - gRideEntranceExitPlaceDirection = direction ^ 2; - *outDirection = direction ^ 2; + gRideEntranceExitPlaceDirection = direction_reverse(direction); + *outDirection = direction_reverse(direction); return; } if (tileElement->AsTrack()->GetStationIndex() != gRideEntranceExitPlaceStationIndex) @@ -7237,8 +7237,8 @@ void ride_get_entrance_or_exit_position_from_screen_position( [tileElement->AsTrack()->GetSequenceIndex()] & (1 << eax)) { - gRideEntranceExitPlaceDirection = direction ^ 2; - *outDirection = direction ^ 2; + gRideEntranceExitPlaceDirection = direction_reverse(direction); + *outDirection = direction_reverse(direction); return; } } while (!(tileElement++)->IsLastForTile()); @@ -7309,7 +7309,7 @@ void ride_get_entrance_or_exit_position_from_screen_position( } direction = loc_6CD18E(*outX, *outY, entranceMinX - 32, entranceMinY - 32, entranceMaxX + 32, entranceMaxY + 32); - if (direction != -1 && direction != stationDirection && direction != (stationDirection ^ 2)) + if (direction != -1 && direction != stationDirection && direction != direction_reverse(stationDirection)) { gRideEntranceExitPlaceDirection = direction; *outDirection = direction; @@ -7352,7 +7352,7 @@ bool ride_select_forwards_from_back() x = _currentTrackBeginX; y = _currentTrackBeginY; z = _currentTrackBeginZ; - direction = _currentTrackPieceDirection ^ 2; + direction = direction_reverse(_currentTrackPieceDirection); CoordsXYE next_track; if (track_block_get_next_from_zero(x, y, z, _currentRideIndex, direction, &next_track, &z, &direction, false)) @@ -8549,7 +8549,7 @@ bool ride_has_adjacent_station(Ride* ride) if (found) break; /* Check the other side of the station */ - direction ^= 2; + direction = direction_reverse(direction); found = check_for_adjacent_station(stationX, stationY, stationZ, direction); if (found) break; diff --git a/src/openrct2/ride/Track.cpp b/src/openrct2/ride/Track.cpp index 546bb57e8a..4df3df4386 100644 --- a/src/openrct2/ride/Track.cpp +++ b/src/openrct2/ride/Track.cpp @@ -1331,7 +1331,7 @@ static money32 track_place( int32_t temp_direction = (direction + dl) & 3; temp_x += CoordsDirectionDelta[temp_direction].x; temp_y += CoordsDirectionDelta[temp_direction].y; - temp_direction ^= (1 << 1); + temp_direction = direction_reverse(temp_direction); wall_remove_intersecting_walls(temp_x, temp_y, baseZ, clearanceZ, temp_direction & 3); } } diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index e53d9f82f3..f2aba18d07 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -602,7 +602,7 @@ static void track_design_mirror_ride(rct_track_td6* td6) entrance->y = -entrance->y; if (entrance->direction & 1) { - entrance->direction ^= (1 << 1); + entrance->direction = direction_reverse(entrance->direction); } } } @@ -627,7 +627,7 @@ static void track_design_mirror_maze(rct_track_td6* td6) { if (maze->direction & 1) { - maze->direction ^= (1 << 1); + maze->direction = direction_reverse(maze->direction); } continue; } diff --git a/src/openrct2/ride/Vehicle.cpp b/src/openrct2/ride/Vehicle.cpp index 710b0c5595..cff512d304 100644 --- a/src/openrct2/ride/Vehicle.cpp +++ b/src/openrct2/ride/Vehicle.cpp @@ -2872,7 +2872,7 @@ static bool vehicle_can_depart_synchronised(rct_vehicle* vehicle) y = location.y * 32; // Other search direction. - direction = (direction ^ 2) & 3; + direction = direction_reverse(direction) & 3; spaceBetween = maxCheckDistance; while (_lastSynchronisedVehicle < &_synchronisedVehicles[SYNCHRONISED_VEHICLE_COUNT - 1]) { @@ -7518,7 +7518,7 @@ static void vehicle_update_handle_scenery_door(rct_vehicle* vehicle) int32_t y = vehicle->track_y; int32_t z = (vehicle->track_z - trackBlock->z + trackCoordinates->z_begin) >> 3; int32_t direction = (vehicle->track_direction + trackCoordinates->rotation_begin) & 3; - direction ^= 2; + direction = direction_reverse(direction); TileElement* tileElement = map_get_wall_element_at(x, y, z, direction); if (tileElement == nullptr) diff --git a/src/openrct2/world/Footpath.cpp b/src/openrct2/world/Footpath.cpp index 1a97ae6b23..cd3f37fb2a 100644 --- a/src/openrct2/world/Footpath.cpp +++ b/src/openrct2/world/Footpath.cpp @@ -180,7 +180,7 @@ static void loc_6A6620(int32_t flags, int32_t x, int32_t y, TileElement* tileEle { int32_t direction = tileElement->AsPath()->GetSlopeDirection(); int32_t z = tileElement->base_height; - wall_remove_intersecting_walls(x, y, z, z + 6, direction ^ 2); + wall_remove_intersecting_walls(x, y, z, z + 6, direction_reverse(direction)); wall_remove_intersecting_walls(x, y, z, z + 6, direction); // Removing walls may have made the pointer invalid, so find it again tileElement = map_get_footpath_element(x / 32, y / 32, z); @@ -494,7 +494,7 @@ static money32 footpath_place_real( direction = direction & 0xF; // It is possible, let's remove walls between the old and new piece of path wall_remove_intersecting_walls( - x, y, z, z + 4 + ((slope & TILE_ELEMENT_SURFACE_RAISED_CORNERS_MASK) ? 2 : 0), direction ^ 2); + x, y, z, z + 4 + ((slope & TILE_ELEMENT_SURFACE_RAISED_CORNERS_MASK) ? 2 : 0), direction_reverse(direction)); wall_remove_intersecting_walls( x - CoordsDirectionDelta[direction].x, y - CoordsDirectionDelta[direction].y, z, z + 4, direction); } @@ -1124,14 +1124,14 @@ static void footpath_connect_corners(int32_t initialX, int32_t initialY, TileEle x += CoordsDirectionDelta[direction].x; y += CoordsDirectionDelta[direction].y; - tileElement[1] = footpath_connect_corners_get_neighbour(x, y, z, (1 << (direction ^ 2))); + tileElement[1] = footpath_connect_corners_get_neighbour(x, y, z, (1 << direction_reverse(direction))); if (tileElement[1] == nullptr) continue; direction = (direction + 1) & 3; x += CoordsDirectionDelta[direction].x; y += CoordsDirectionDelta[direction].y; - tileElement[2] = footpath_connect_corners_get_neighbour(x, y, z, (1 << (direction ^ 2))); + tileElement[2] = footpath_connect_corners_get_neighbour(x, y, z, (1 << direction_reverse(direction))); if (tileElement[2] == nullptr) continue; @@ -1139,7 +1139,7 @@ static void footpath_connect_corners(int32_t initialX, int32_t initialY, TileEle x += CoordsDirectionDelta[direction].x; y += CoordsDirectionDelta[direction].y; // First check link to previous tile - tileElement[3] = footpath_connect_corners_get_neighbour(x, y, z, (1 << (direction ^ 2))); + tileElement[3] = footpath_connect_corners_get_neighbour(x, y, z, (1 << direction_reverse(direction))); if (tileElement[3] == nullptr) continue; // Second check link to initial tile @@ -1272,7 +1272,7 @@ static TileElement* footpath_get_element(int32_t x, int32_t y, int32_t z0, int32 if (!tileElement->AsPath()->IsSloped()) break; - slope = tileElement->AsPath()->GetSlopeDirection() ^ 2; + slope = direction_reverse(tileElement->AsPath()->GetSlopeDirection()); if (slope != direction) break; @@ -1384,7 +1384,7 @@ static void loc_6A6D7E( } if (z - 2 == tileElement->base_height) { - if (!tileElement->AsPath()->IsSloped() || tileElement->AsPath()->GetSlopeDirection() != (direction ^ 2)) + if (!tileElement->AsPath()->IsSloped() || tileElement->AsPath()->GetSlopeDirection() != direction_reverse(direction)) { return; } @@ -1406,7 +1406,7 @@ static void loc_6A6D7E( { return; } - uint16_t dx = ((direction - tileElement->GetDirection()) & TILE_ELEMENT_DIRECTION_MASK) ^ 2; + uint16_t dx = direction_reverse((direction - tileElement->GetDirection()) & TILE_ELEMENT_DIRECTION_MASK); if (!(FlatRideTrackSequenceProperties[trackType][trackSequence] & (1 << dx))) { return; @@ -1421,7 +1421,7 @@ static void loc_6A6D7E( case TILE_ELEMENT_TYPE_ENTRANCE: if (z == tileElement->base_height) { - if (entrance_has_direction(tileElement, (direction - tileElement->GetDirection()) ^ 2)) + if (entrance_has_direction(tileElement, direction_reverse(direction - tileElement->GetDirection()))) { if (query) { @@ -1447,7 +1447,7 @@ static void loc_6A6D7E( loc_6A6F1F: if (query) { - if (fence_in_the_way(x, y, tileElement->base_height, tileElement->clearance_height, direction ^ 2)) + if (fence_in_the_way(x, y, tileElement->base_height, tileElement->clearance_height, direction_reverse(direction))) { return; } @@ -1480,7 +1480,7 @@ static void loc_6A6D7E( else { footpath_disconnect_queue_from_path(x, y, tileElement, 1 + ((flags >> 6) & 1)); - tileElement->AsPath()->SetEdges(tileElement->AsPath()->GetEdges() | (1 << (direction ^ 2))); + tileElement->AsPath()->SetEdges(tileElement->AsPath()->GetEdges() | (1 << direction_reverse(direction))); if (tileElement->AsPath()->IsQueue()) { footpath_queue_chain_push(tileElement->AsPath()->GetRideIndex()); @@ -1672,7 +1672,7 @@ void footpath_chain_ride_queue( if (!tileElement->AsPath()->IsSloped()) break; - if ((tileElement->AsPath()->GetSlopeDirection() ^ 2) != direction) + if (direction_reverse(tileElement->AsPath()->GetSlopeDirection()) != direction) break; z -= 2; @@ -1690,7 +1690,7 @@ void footpath_chain_ride_queue( int32_t numEdges = bitcount(edges); if (numEdges >= 2) { - int32_t requiredEdgeMask = 1 << (direction ^ 2); + int32_t requiredEdgeMask = 1 << direction_reverse(direction); if (!(edges & requiredEdgeMask)) { break; @@ -1698,7 +1698,7 @@ void footpath_chain_ride_queue( } tileElement->AsPath()->SetHasQueueBanner(false); - tileElement->AsPath()->SetEdges(tileElement->AsPath()->GetEdges() | (1 << (direction ^ 2))); + tileElement->AsPath()->SetEdges(tileElement->AsPath()->GetEdges() | (1 << direction_reverse(direction))); tileElement->AsPath()->SetRideIndex(rideIndex); tileElement->AsPath()->SetStationIndex(entranceIndex); @@ -1716,7 +1716,7 @@ void footpath_chain_ride_queue( if (tileElement->AsPath()->GetEdges() & (1 << direction)) continue; - direction ^= 2; + direction = direction_reverse(direction); if (tileElement->AsPath()->GetEdges() & (1 << direction)) continue; } @@ -1871,7 +1871,7 @@ static int32_t footpath_is_connected_to_map_edge_recurse( if (tileElement->AsPath()->IsSloped() && (slopeDirection = tileElement->AsPath()->GetSlopeDirection()) != direction) { - if ((slopeDirection ^ 2) != direction) + if (direction_reverse(slopeDirection) != direction) continue; if (tileElement->base_height + 2 != z) continue; @@ -1894,7 +1894,7 @@ static int32_t footpath_is_connected_to_map_edge_recurse( footpath_fix_ownership(x, y); } edges = tileElement->AsPath()->GetEdges(); - direction ^= 2; + direction = direction_reverse(direction); if (!(flags & (1 << 7))) { if (tileElement[1].GetType() == TILE_ELEMENT_TYPE_BANNER) @@ -2427,7 +2427,7 @@ static void footpath_remove_edges_towards_here( footpath_queue_chain_push(tileElement->AsPath()->GetRideIndex()); } - int32_t d = direction ^ 2; + int32_t d = direction_reverse(direction); tileElement->AsPath()->SetEdges(tileElement->AsPath()->GetEdges() & ~(1 << d)); int32_t cd = ((d - 1) & 3); tileElement->AsPath()->SetCorners(tileElement->AsPath()->GetCorners() & ~(1 << cd)); @@ -2494,7 +2494,7 @@ static void footpath_remove_edges_towards(int32_t x, int32_t y, int32_t z0, int3 if (!tileElement->AsPath()->IsSloped()) break; - uint8_t slope = tileElement->AsPath()->GetSlopeDirection() ^ 2; + uint8_t slope = direction_reverse(tileElement->AsPath()->GetSlopeDirection()); if (slope != direction) break; @@ -2523,7 +2523,7 @@ bool tile_element_wants_path_connection_towards(TileCoordsXYZD coords, const Til if (!tileElement->AsPath()->IsSloped()) // The footpath is flat, it can be connected to from any direction return true; - else if (tileElement->AsPath()->GetSlopeDirection() == (coords.direction ^ 2)) + else if (tileElement->AsPath()->GetSlopeDirection() == direction_reverse(coords.direction)) // The footpath is sloped and its lowest point matches the edge connection return true; } diff --git a/src/openrct2/world/Map.cpp b/src/openrct2/world/Map.cpp index 1059523993..d962768cef 100644 --- a/src/openrct2/world/Map.cpp +++ b/src/openrct2/world/Map.cpp @@ -624,7 +624,7 @@ bool map_coord_is_connected(int32_t x, int32_t y, int32_t z, uint8_t faceDirecti if (z == tileElement->base_height + 2) return true; } - else if ((slopeDirection ^ 2) == faceDirection && z == tileElement->base_height) + else if (direction_reverse(slopeDirection) == faceDirection && z == tileElement->base_height) { return true; } diff --git a/src/openrct2/world/Park.cpp b/src/openrct2/world/Park.cpp index 4a9d205faa..42be26cb09 100644 --- a/src/openrct2/world/Park.cpp +++ b/src/openrct2/world/Park.cpp @@ -996,7 +996,7 @@ rct_peep* Park::GenerateGuest() const auto spawn = get_random_peep_spawn(); if (spawn != nullptr) { - auto direction = spawn->direction ^ 2; + auto direction = direction_reverse(spawn->direction); peep = peep_generate(spawn->x, spawn->y, spawn->z); if (peep != nullptr) { From b77f1285a48e98cd24654911758e43e7d7885b8d Mon Sep 17 00:00:00 2001 From: Richard Fine Date: Sat, 5 Jan 2019 19:48:12 +0000 Subject: [PATCH 4/5] Reformat --- src/openrct2/peep/Staff.cpp | 3 +-- src/openrct2/world/Footpath.cpp | 6 ++++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/openrct2/peep/Staff.cpp b/src/openrct2/peep/Staff.cpp index 5503f6f96a..8301405fb5 100644 --- a/src/openrct2/peep/Staff.cpp +++ b/src/openrct2/peep/Staff.cpp @@ -1137,8 +1137,7 @@ static uint8_t staff_direction_surface(rct_peep* peep, uint8_t initialDirection) if (fence_in_the_way(peep->next_x, peep->next_y, peep->next_z, peep->next_z + 4, direction) == true) continue; - if (fence_in_the_way(peep->next_x, peep->next_y, peep->next_z, peep->next_z + 4, direction_reverse(direction)) - == true) + if (fence_in_the_way(peep->next_x, peep->next_y, peep->next_z, peep->next_z + 4, direction_reverse(direction)) == true) continue; LocationXY16 chosenTile = { static_cast(peep->next_x + CoordsDirectionDelta[direction].x), diff --git a/src/openrct2/world/Footpath.cpp b/src/openrct2/world/Footpath.cpp index cd3f37fb2a..1b9b39fc98 100644 --- a/src/openrct2/world/Footpath.cpp +++ b/src/openrct2/world/Footpath.cpp @@ -1384,7 +1384,8 @@ static void loc_6A6D7E( } if (z - 2 == tileElement->base_height) { - if (!tileElement->AsPath()->IsSloped() || tileElement->AsPath()->GetSlopeDirection() != direction_reverse(direction)) + if (!tileElement->AsPath()->IsSloped() + || tileElement->AsPath()->GetSlopeDirection() != direction_reverse(direction)) { return; } @@ -1406,7 +1407,8 @@ static void loc_6A6D7E( { return; } - uint16_t dx = direction_reverse((direction - tileElement->GetDirection()) & TILE_ELEMENT_DIRECTION_MASK); + uint16_t dx = direction_reverse( + (direction - tileElement->GetDirection()) & TILE_ELEMENT_DIRECTION_MASK); if (!(FlatRideTrackSequenceProperties[trackType][trackSequence] & (1 << dx))) { return; From 3b9dd87caf8e45d4ef5d4e9252ec68c046fad9c9 Mon Sep 17 00:00:00 2001 From: Richard Fine Date: Sun, 6 Jan 2019 11:58:28 +0000 Subject: [PATCH 5/5] Make direction_reverse constexpr and pass arg by value To make totally sure that the compiler understands it can fully compute the value at compile time when dealing with constant inputs, and to make totally sure there are no aliasing problems. --- src/openrct2/world/Location.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2/world/Location.hpp b/src/openrct2/world/Location.hpp index ea87892ee1..59b1e1cf57 100644 --- a/src/openrct2/world/Location.hpp +++ b/src/openrct2/world/Location.hpp @@ -144,7 +144,7 @@ typedef uint8_t Direction; * Given a direction, return the direction that points the other way, * on the same axis. */ -inline Direction direction_reverse(const Direction& dir) +constexpr Direction direction_reverse(Direction dir) { return dir ^ 2; }