diff --git a/src/openrct2/actions/FootpathPlaceAction.hpp b/src/openrct2/actions/FootpathPlaceAction.hpp index 0474cbfc25..ec765b0277 100644 --- a/src/openrct2/actions/FootpathPlaceAction.hpp +++ b/src/openrct2/actions/FootpathPlaceAction.hpp @@ -28,11 +28,11 @@ private: CoordsXYZ _loc; uint8_t _slope; uint8_t _type; - uint8_t _direction = 0xFF; + Direction _direction = INVALID_DIRECTION; public: FootpathPlaceAction() = default; - FootpathPlaceAction(CoordsXYZ loc, uint8_t slope, uint8_t type, uint8_t direction = 0xFF) + FootpathPlaceAction(CoordsXYZ loc, uint8_t slope, uint8_t type, Direction direction = INVALID_DIRECTION) : _loc(loc) , _slope(slope) , _type(type) @@ -88,7 +88,7 @@ public: return MakeResult(GA_ERROR::DISALLOWED, STR_CANT_BUILD_FOOTPATH_HERE, STR_TOO_HIGH); } - if (_direction != 0xFF && _direction > 15) + if (_direction != INVALID_DIRECTION && !direction_valid(_direction)) { log_error("Direction invalid. direction = %u", _direction); return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_BUILD_FOOTPATH_HERE); @@ -127,7 +127,7 @@ public: if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST)) { - if (_direction != 0xFF && !gCheatsDisableClearanceChecks) + if (_direction != INVALID_DIRECTION && !gCheatsDisableClearanceChecks) { // It is possible, let's remove walls between the old and new piece of path auto zLow = _loc.z / 8; diff --git a/src/openrct2/actions/LandSetHeightAction.hpp b/src/openrct2/actions/LandSetHeightAction.hpp index 23cfd10774..e6f329542b 100644 --- a/src/openrct2/actions/LandSetHeightAction.hpp +++ b/src/openrct2/actions/LandSetHeightAction.hpp @@ -339,7 +339,7 @@ private: money32 GetSurfaceHeightChangeCost(SurfaceElement * surfaceElement) const { money32 cost{ 0 }; - for (int32_t i = 0; i < 4; i += 1) + for (Direction i : ALL_DIRECTIONS) { int32_t cornerHeight = tile_element_get_corner_height(surfaceElement, i); cornerHeight -= map_get_corner_height(_height, _style & TILE_ELEMENT_SURFACE_SLOPE_MASK, i); diff --git a/src/openrct2/actions/RideDemolishAction.hpp b/src/openrct2/actions/RideDemolishAction.hpp index 3530f747a9..38bd6491c6 100644 --- a/src/openrct2/actions/RideDemolishAction.hpp +++ b/src/openrct2/actions/RideDemolishAction.hpp @@ -332,7 +332,7 @@ private: { 16, 0 }, }; - for (uint8_t dir = 0; dir < 4; dir++) + for (Direction dir : ALL_DIRECTIONS) { const LocationXY16& off = DirOffsets[dir]; money32 removePrice = MazeRemoveTrack(x + off.x, y + off.y, z, dir); diff --git a/src/openrct2/actions/WallPlaceAction.hpp b/src/openrct2/actions/WallPlaceAction.hpp index cf581f64f1..6598dfeacd 100644 --- a/src/openrct2/actions/WallPlaceAction.hpp +++ b/src/openrct2/actions/WallPlaceAction.hpp @@ -54,7 +54,7 @@ DEFINE_GAME_ACTION(WallPlaceAction, GAME_COMMAND_PLACE_WALL, WallPlaceActionResu private: int32_t _wallType{ -1 }; CoordsXYZ _loc; - uint8_t _edge{ std::numeric_limits::max() }; + Direction _edge{ INVALID_DIRECTION }; int32_t _primaryColour; int32_t _secondaryColour; int32_t _tertiaryColour; @@ -557,7 +557,7 @@ private: { if (!(TrackCoordinates[trackType].rotation_begin & 4)) { - direction = trackElement->GetDirectionWithOffset(2); + direction = direction_reverse(trackElement->GetDirection()); if (direction == _edge) { const rct_preview_track* trackBlock = &TrackBlocks[trackType][sequence]; diff --git a/src/openrct2/core/Endianness.h b/src/openrct2/core/Endianness.h index 16d024cfbc..e0d065f512 100644 --- a/src/openrct2/core/Endianness.h +++ b/src/openrct2/core/Endianness.h @@ -17,6 +17,7 @@ template struct ByteSwapT template<> struct ByteSwapT<1> { + typedef uint8_t UIntType; static uint8_t SwapBE(uint8_t value) { return value; @@ -25,6 +26,7 @@ template<> struct ByteSwapT<1> template<> struct ByteSwapT<2> { + typedef uint16_t UIntType; static uint16_t SwapBE(uint16_t value) { return (uint16_t)((value << 8) | (value >> 8)); @@ -33,6 +35,7 @@ template<> struct ByteSwapT<2> template<> struct ByteSwapT<4> { + typedef uint32_t UIntType; static uint32_t SwapBE(uint32_t value) { return (uint32_t)(((value << 24) | ((value << 8) & 0x00FF0000) | ((value >> 8) & 0x0000FF00) | (value >> 24))); @@ -41,6 +44,7 @@ template<> struct ByteSwapT<4> template<> struct ByteSwapT<8> { + typedef uint64_t UIntType; static uint64_t SwapBE(uint64_t value) { value = (value & 0x00000000FFFFFFFF) << 32 | (value & 0xFFFFFFFF00000000) >> 32; @@ -52,5 +56,7 @@ template<> struct ByteSwapT<8> template static T ByteSwapBE(const T& value) { - return ByteSwapT::SwapBE(value); + typedef ByteSwapT ByteSwap; + typename ByteSwap::UIntType result = ByteSwap::SwapBE(reinterpret_cast(value)); + return *reinterpret_cast(&result); } diff --git a/src/openrct2/paint/tile_element/Paint.TileElement.cpp b/src/openrct2/paint/tile_element/Paint.TileElement.cpp index 619c421b4b..730a4e5409 100644 --- a/src/openrct2/paint/tile_element/Paint.TileElement.cpp +++ b/src/openrct2/paint/tile_element/Paint.TileElement.cpp @@ -248,7 +248,7 @@ static void sub_68B3FB(paint_session* session, int32_t x, int32_t y) if ((session->ViewFlags & VIEWPORT_FLAG_CLIP_VIEW) && (tile_element->base_height > gClipHeight)) continue; - int32_t direction = tile_element->GetDirectionWithOffset(rotation); + Direction direction = tile_element->GetDirectionWithOffset(rotation); int32_t height = tile_element->base_height * 8; // If we are on a new height level, look through elements on the diff --git a/src/openrct2/peep/Guest.cpp b/src/openrct2/peep/Guest.cpp index 9ada49696b..2ede34f725 100644 --- a/src/openrct2/peep/Guest.cpp +++ b/src/openrct2/peep/Guest.cpp @@ -6472,7 +6472,7 @@ static bool peep_find_ride_to_look_at(Peep* peep, uint8_t edge, uint8_t* rideToV } if (tileElement->GetType() != TILE_ELEMENT_TYPE_WALL) continue; - if (tileElement->GetDirectionWithOffset(2) != edge) + if (direction_reverse(tileElement->GetDirection()) != edge) continue; auto wallEntry = tileElement->AsWall()->GetEntry(); if (wallEntry == nullptr || (wallEntry->wall.flags2 & WALL_SCENERY_2_IS_OPAQUE)) @@ -6590,7 +6590,7 @@ static bool peep_find_ride_to_look_at(Peep* peep, uint8_t edge, uint8_t* rideToV } if (tileElement->GetType() != TILE_ELEMENT_TYPE_WALL) continue; - if (tileElement->GetDirectionWithOffset(2) != edge) + if (direction_reverse(tileElement->GetDirection()) != edge) continue; auto wallEntry = tileElement->AsWall()->GetEntry(); if (wallEntry == nullptr || (wallEntry->wall.flags2 & WALL_SCENERY_2_IS_OPAQUE)) @@ -6706,7 +6706,7 @@ static bool peep_find_ride_to_look_at(Peep* peep, uint8_t edge, uint8_t* rideToV } if (tileElement->GetType() != TILE_ELEMENT_TYPE_WALL) continue; - if (tileElement->GetDirectionWithOffset(2) != edge) + if (direction_reverse(tileElement->GetDirection()) != edge) continue; auto wallEntry = tileElement->AsWall()->GetEntry(); if (wallEntry == nullptr || (wallEntry->wall.flags2 & WALL_SCENERY_2_IS_OPAQUE)) diff --git a/src/openrct2/peep/GuestPathfinding.cpp b/src/openrct2/peep/GuestPathfinding.cpp index 36392ce5eb..fe97345d05 100644 --- a/src/openrct2/peep/GuestPathfinding.cpp +++ b/src/openrct2/peep/GuestPathfinding.cpp @@ -33,7 +33,7 @@ static int32_t guest_surface_path_finding(Peep* peep); static struct { TileCoordsXYZ location; - uint8_t direction; + Direction direction; } _peepPathFindHistory[16]; enum @@ -105,9 +105,9 @@ static int32_t path_get_permitted_edges(PathElement* pathElement) * * rct2: 0x0069524E */ -static int32_t peep_move_one_tile(uint8_t direction, Peep* peep) +static int32_t peep_move_one_tile(Direction direction, Peep* peep) { - assert(direction <= 3); + assert(direction_valid(direction)); int16_t x = peep->next_x; int16_t y = peep->next_y; x += CoordsDirectionDelta[direction].x; @@ -139,13 +139,13 @@ static int32_t guest_surface_path_finding(Peep* peep) int16_t x = peep->next_x; int16_t y = peep->next_y; int16_t z = peep->next_z; - uint8_t randDirection = scenario_rand() & 3; + Direction randDirection = scenario_rand() & 3; if (!fence_in_the_way(x, y, z, z + 4, randDirection)) { x += CoordsDirectionDelta[randDirection].x; y += CoordsDirectionDelta[randDirection].y; - uint8_t backwardsDirection = direction_reverse(randDirection); + Direction backwardsDirection = direction_reverse(randDirection); if (!fence_in_the_way(x, y, z, z + 4, backwardsDirection)) { @@ -170,7 +170,7 @@ static int32_t guest_surface_path_finding(Peep* peep) { x += CoordsDirectionDelta[randDirection].x; y += CoordsDirectionDelta[randDirection].y; - uint8_t backwardsDirection = direction_reverse(randDirection); + Direction backwardsDirection = direction_reverse(randDirection); if (!fence_in_the_way(x, y, z, z + 4, backwardsDirection)) { @@ -190,7 +190,7 @@ static int32_t guest_surface_path_finding(Peep* peep) { x += CoordsDirectionDelta[randDirection].x; y += CoordsDirectionDelta[randDirection].y; - uint8_t backwardsDirection = direction_reverse(randDirection); + Direction backwardsDirection = direction_reverse(randDirection); if (!fence_in_the_way(x, y, z, z + 4, backwardsDirection)) { @@ -223,7 +223,7 @@ static int32_t guest_surface_path_finding(Peep* peep) * Returns the type of the next footpath tile a peep can get to from x,y,z / * inputTileElement in the given direction. */ -static uint8_t footpath_element_next_in_direction(TileCoordsXYZ loc, PathElement* pathElement, uint8_t chosenDirection) +static uint8_t footpath_element_next_in_direction(TileCoordsXYZ loc, PathElement* pathElement, Direction chosenDirection) { TileElement* nextTileElement; @@ -275,10 +275,11 @@ static uint8_t footpath_element_next_in_direction(TileCoordsXYZ loc, PathElement * * This is the recursive portion of footpath_element_destination_in_direction(). */ -static uint8_t footpath_element_dest_in_dir(TileCoordsXYZ loc, uint8_t chosenDirection, ride_id_t* outRideIndex, int32_t level) +static uint8_t footpath_element_dest_in_dir( + TileCoordsXYZ loc, Direction chosenDirection, ride_id_t* outRideIndex, int32_t level) { TileElement* tileElement; - int32_t direction; + Direction direction; if (level > 25) return PATH_SEARCH_LIMIT_REACHED; @@ -344,23 +345,23 @@ static uint8_t footpath_element_dest_in_dir(TileCoordsXYZ loc, uint8_t chosenDir edges &= ~(1 << direction_reverse(chosenDirection)); loc.z = tileElement->base_height; - for (direction = 0; direction < 4; direction++) + for (Direction dir : ALL_DIRECTIONS) { - if (!(edges & (1 << direction))) + if (!(edges & (1 << dir))) continue; - edges &= ~(1 << direction); + edges &= ~(1 << dir); if (edges != 0) return PATH_SEARCH_JUNCTION; if (tileElement->AsPath()->IsSloped()) { - if (tileElement->AsPath()->GetSlopeDirection() == direction) + if (tileElement->AsPath()->GetSlopeDirection() == dir) { loc.z += 2; } } - return footpath_element_dest_in_dir(loc, direction, outRideIndex, level + 1); + return footpath_element_dest_in_dir(loc, dir, outRideIndex, level + 1); } return PATH_SEARCH_DEAD_END; } @@ -393,7 +394,7 @@ static uint8_t footpath_element_dest_in_dir(TileCoordsXYZ loc, uint8_t chosenDir * width path, for example that leads from a ride exit back to the main path. */ static uint8_t footpath_element_destination_in_direction( - TileCoordsXYZ loc, PathElement* pathElement, uint8_t chosenDirection, ride_id_t* outRideIndex) + TileCoordsXYZ loc, PathElement* pathElement, Direction chosenDirection, ride_id_t* outRideIndex) { if (pathElement->IsSloped()) { @@ -423,7 +424,7 @@ static int32_t guest_path_find_aimless(Peep* peep, uint8_t edges) while (true) { - uint8_t direction = scenario_rand() & 3; + Direction direction = scenario_rand() & 3; // Otherwise go in a random direction allowed from the tile. if (edges & (1 << direction)) { @@ -596,8 +597,8 @@ static int32_t CalculateHeuristicPathingScore(TileCoordsXYZ loc1, TileCoordsXYZ */ static void peep_pathfind_heuristic_search( TileCoordsXYZ loc, Peep* peep, TileElement* currentTileElement, bool inPatrolArea, uint8_t counter, uint16_t* endScore, - int32_t test_edge, uint8_t* endJunctions, TileCoordsXYZ junctionList[16], uint8_t directionList[16], TileCoordsXYZ* endXYZ, - uint8_t* endSteps) + Direction test_edge, uint8_t* endJunctions, TileCoordsXYZ junctionList[16], uint8_t directionList[16], + TileCoordsXYZ* endXYZ, uint8_t* endSteps) { uint8_t searchResult = PATH_SEARCH_FAILED; @@ -680,7 +681,7 @@ static void peep_pathfind_heuristic_search( case TILE_ELEMENT_TYPE_ENTRANCE: if (loc.z != tileElement->base_height) continue; - int32_t direction; + Direction direction; searchResult = PATH_SEARCH_OTHER; switch (tileElement->AsEntrance()->GetEntranceType()) { @@ -905,7 +906,7 @@ static void peep_pathfind_heuristic_search( #endif // defined(DEBUG_LEVEL_2) && DEBUG_LEVEL_2 /* Remove the reverse edge (i.e. the edge back to the previous map element.) */ - edges &= ~(1 << (test_edge ^ 2)); + edges &= ~(1 << direction_reverse(test_edge)); int32_t next_test_edge = bitscanforward(edges); @@ -1162,7 +1163,7 @@ static void peep_pathfind_heuristic_search( * * rct2: 0x0069A5F0 */ -int32_t peep_pathfind_choose_direction(TileCoordsXYZ loc, Peep* peep) +Direction peep_pathfind_choose_direction(TileCoordsXYZ loc, Peep* peep) { // The max number of thin junctions searched - a per-search-path limit. _peepPathFindMaxJunctions = peep_pathfind_get_max_number_junctions(peep); @@ -1231,7 +1232,7 @@ int32_t peep_pathfind_choose_direction(TileCoordsXYZ loc, Peep* peep) } while (!(dest_tile_element++)->IsLastForTile()); // Peep is not on a path. if (!found) - return -1; + return INVALID_DIRECTION; permitted_edges &= 0xF; uint8_t edges = permitted_edges; @@ -1302,7 +1303,7 @@ int32_t peep_pathfind_choose_direction(TileCoordsXYZ loc, Peep* peep) /* If this is a new goal for the peep. Store it and reset the peep's * pathfind_history. */ - if (peep->pathfind_goal.direction > 3 || peep->pathfind_goal.x != goal.x || peep->pathfind_goal.y != goal.y + if (!direction_valid(peep->pathfind_goal.direction) || peep->pathfind_goal.x != goal.x || peep->pathfind_goal.y != goal.y || peep->pathfind_goal.z != goal.z) { peep->pathfind_goal.x = goal.x; @@ -1322,7 +1323,7 @@ int32_t peep_pathfind_choose_direction(TileCoordsXYZ loc, Peep* peep) // Peep has tried all edges. if (edges == 0) - return -1; + return INVALID_DIRECTION; int32_t chosen_edge = bitscanforward(edges); @@ -1465,7 +1466,7 @@ int32_t peep_pathfind_choose_direction(TileCoordsXYZ loc, Peep* peep) log_verbose("Pathfind heuristic search failed."); } #endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 - return -1; + return INVALID_DIRECTION; } #if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 if (gPathFindDebug) @@ -1578,9 +1579,9 @@ static int32_t guest_path_find_entering_park(Peep* peep, uint8_t edges) gPeepPathFindIgnoreForeignQueues = true; gPeepPathFindQueueRideIndex = RIDE_ID_NULL; - int32_t chosenDirection = peep_pathfind_choose_direction({ peep->next_x / 32, peep->next_y / 32, peep->next_z }, peep); + Direction chosenDirection = peep_pathfind_choose_direction({ peep->next_x / 32, peep->next_y / 32, peep->next_z }, peep); - if (chosenDirection == -1) + if (chosenDirection == INVALID_DIRECTION) return guest_path_find_aimless(peep, edges); else return peep_move_one_tile(chosenDirection, peep); @@ -1628,7 +1629,7 @@ static int32_t guest_path_find_leaving_park(Peep* peep, uint8_t edges) int16_t x = peepSpawn->x & 0xFFE0; int16_t y = peepSpawn->y & 0xFFE0; uint8_t z = peepSpawn->z / 8; - uint8_t direction = peepSpawn->direction; + Direction direction = peepSpawn->direction; gPeepPathFindGoalPosition = { x / 32, y / 32, z }; if (x == peep->next_x && y == peep->next_y) @@ -1639,7 +1640,7 @@ static int32_t guest_path_find_leaving_park(Peep* peep, uint8_t edges) gPeepPathFindIgnoreForeignQueues = true; gPeepPathFindQueueRideIndex = RIDE_ID_NULL; direction = peep_pathfind_choose_direction({ peep->next_x / 32, peep->next_y / 32, peep->next_z }, peep); - if (direction == 0xFF) + if (direction == INVALID_DIRECTION) return guest_path_find_aimless(peep, edges); else return peep_move_one_tile(direction, peep); @@ -1694,13 +1695,13 @@ static int32_t guest_path_find_park_entrance(Peep* peep, uint8_t edges) pathfind_logging_enable(peep); #endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 - int32_t chosenDirection = peep_pathfind_choose_direction({ peep->next_x / 32, peep->next_y / 32, peep->next_z }, peep); + Direction chosenDirection = peep_pathfind_choose_direction({ peep->next_x / 32, peep->next_y / 32, peep->next_z }, peep); #if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 pathfind_logging_disable(); #endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 - if (chosenDirection == -1) + if (chosenDirection == INVALID_DIRECTION) return guest_path_find_aimless(peep, edges); else return peep_move_one_tile(chosenDirection, peep); @@ -1740,7 +1741,7 @@ static void get_ride_queue_end(TileCoordsXYZ& loc) if (!found) return; - uint8_t direction = tileElement->GetDirectionWithOffset(2); + Direction direction = direction_reverse(tileElement->GetDirection()); TileElement* lastPathElement = nullptr; TileElement* firstPathElement = nullptr; @@ -1889,7 +1890,7 @@ int32_t guest_path_finding(Guest* peep) /* If this tileElement is adjacent to any non-wide paths, * remove all of the edges to wide paths. */ uint8_t adjustedEdges = edges; - for (int32_t chosenDirection = 0; chosenDirection < 4; chosenDirection++) + for (Direction chosenDirection : ALL_DIRECTIONS) { // If there is no path in that direction try another if (!(adjustedEdges & (1 << chosenDirection))) @@ -1906,7 +1907,7 @@ int32_t guest_path_finding(Guest* peep) edges = adjustedEdges; } - int8_t direction = direction_reverse(peep->direction); + int32_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))) { @@ -1971,7 +1972,7 @@ int32_t guest_path_finding(Guest* peep) if (!peep->HasFood() && (scenario_rand() & 0xFFFF) >= 2184) { uint8_t adjustedEdges = edges; - for (int32_t chosenDirection = 0; chosenDirection < 4; chosenDirection++) + for (Direction chosenDirection : ALL_DIRECTIONS) { // If there is no path in that direction try another if (!(adjustedEdges & (1 << chosenDirection))) @@ -2134,7 +2135,7 @@ int32_t guest_path_finding(Guest* peep) direction = peep_pathfind_choose_direction({ peep->next_x / 32, peep->next_y / 32, peep->next_z }, peep); - if (direction == -1) + if (direction == INVALID_DIRECTION) { /* Heuristic search failed for all directions. * Reset the pathfind_goal - this means that the pathfind_history diff --git a/src/openrct2/peep/Peep.h b/src/openrct2/peep/Peep.h index 1a7cb375e8..4474244de6 100644 --- a/src/openrct2/peep/Peep.h +++ b/src/openrct2/peep/Peep.h @@ -615,7 +615,7 @@ struct Peep : rct_sprite_common union { uint8_t maze_last_edge; // 0x78 - uint8_t direction; // Direction ? + Direction direction; // Direction ? }; uint8_t interaction_ride_index; uint16_t time_in_queue; // 0x7A @@ -983,7 +983,7 @@ void peep_update_names(bool realNames); void guest_set_name(uint16_t spriteIndex, const char* name); -int32_t peep_pathfind_choose_direction(TileCoordsXYZ loc, Peep* peep); +Direction peep_pathfind_choose_direction(TileCoordsXYZ loc, Peep* peep); void peep_reset_pathfind_goal(Peep* peep); bool is_valid_path_z_and_direction(TileElement* tileElement, int32_t currentZ, int32_t currentDirection); diff --git a/src/openrct2/peep/Staff.cpp b/src/openrct2/peep/Staff.cpp index 152eb19293..bbbb63fbbf 100644 --- a/src/openrct2/peep/Staff.cpp +++ b/src/openrct2/peep/Staff.cpp @@ -234,7 +234,7 @@ bool staff_can_ignore_wide_flag(Peep* staff, int32_t x, int32_t y, uint8_t z, Ti uint8_t total = 0; uint8_t pathcount = 0; uint8_t widecount = 0; - for (int32_t adjac_dir = 0; adjac_dir <= 3; adjac_dir++) + for (Direction adjac_dir : ALL_DIRECTIONS) { int32_t adjac_x = x + CoordsDirectionDelta[adjac_dir].x; int32_t adjac_y = y + CoordsDirectionDelta[adjac_dir].y; @@ -514,15 +514,15 @@ static uint8_t staff_handyman_direction_to_uncut_grass(Peep* peep, uint8_t valid auto surfaceElement = map_get_surface_element_at({ peep->next_x, peep->next_y }); if (peep->next_z != surfaceElement->base_height) - return 0xFF; + return INVALID_DIRECTION; if (peep->GetNextIsSloped()) { if (surfaceElement->GetSlope() != PathSlopeToLandSlope[peep->GetNextDirection()]) - return 0xFF; + return INVALID_DIRECTION; } else if (surfaceElement->GetSlope() != TILE_ELEMENT_SLOPE_FLAT) - return 0xFF; + return INVALID_DIRECTION; } uint8_t chosenDirection = scenario_rand() & 0x3; @@ -553,7 +553,7 @@ static uint8_t staff_handyman_direction_to_uncut_grass(Peep* peep, uint8_t valid } } } - return 0xFF; + return INVALID_DIRECTION; } /** @@ -600,13 +600,13 @@ static bool staff_path_finding_handyman(Peep* peep) litterDirection = staff_handyman_direction_to_nearest_litter(peep); } - uint8_t direction = 0xFF; + Direction direction = INVALID_DIRECTION; if (litterDirection == 0xFF && (peep->staff_orders & STAFF_ORDERS_MOWING) && peep->staff_mowing_timeout >= 12) { direction = staff_handyman_direction_to_uncut_grass(peep, validDirections); } - if (direction == 0xFF) + if (direction == INVALID_DIRECTION) { if (peep->GetNextIsSurface()) { @@ -784,7 +784,7 @@ static uint8_t staff_mechanic_direction_path_rand(Peep* peep, uint8_t pathDirect */ static uint8_t staff_mechanic_direction_path(Peep* peep, uint8_t validDirections, PathElement* pathElement) { - uint8_t direction = 0xFF; + Direction direction = INVALID_DIRECTION; uint8_t pathDirections = pathElement->GetEdges(); pathDirections &= validDirections; @@ -847,14 +847,14 @@ static uint8_t staff_mechanic_direction_path(Peep* peep, uint8_t validDirections pathfind_logging_enable(peep); #endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 - int32_t pathfindDirection = peep_pathfind_choose_direction( + Direction pathfindDirection = peep_pathfind_choose_direction( { peep->next_x / 32, peep->next_y / 32, peep->next_z }, peep); #if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 pathfind_logging_disable(); #endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 - if (pathfindDirection == -1) + if (pathfindDirection == INVALID_DIRECTION) { /* Heuristic search failed for all directions. * Reset the pathfind_goal - this means that the pathfind_history @@ -878,7 +878,7 @@ static uint8_t staff_mechanic_direction_path(Peep* peep, uint8_t validDirections static bool staff_path_finding_mechanic(Peep* peep) { uint8_t validDirections = staff_get_valid_patrol_directions(peep, peep->next_x, peep->next_y); - uint8_t direction = 0xFF; + Direction direction = INVALID_DIRECTION; if (peep->GetNextIsSurface()) { direction = staff_mechanic_direction_surface(peep); @@ -919,7 +919,7 @@ static bool staff_path_finding_mechanic(Peep* peep) */ static uint8_t staff_direction_path(Peep* peep, uint8_t validDirections, PathElement* pathElement) { - uint8_t direction = 0xFF; + Direction direction = INVALID_DIRECTION; uint8_t pathDirections = pathElement->GetEdges(); if (peep->state != PEEP_STATE_ANSWERING && peep->state != PEEP_STATE_HEADING_TO_INSPECTION) { @@ -966,7 +966,7 @@ static bool staff_path_finding_misc(Peep* peep) { uint8_t validDirections = staff_get_valid_patrol_directions(peep, peep->next_x, peep->next_y); - uint8_t direction = 0xFF; + Direction direction = INVALID_DIRECTION; if (peep->GetNextIsSurface()) { direction = staff_direction_surface(peep, scenario_rand() & 3); diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index d710fa272e..0919a98178 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -7043,7 +7043,7 @@ void sub_6CB945(Ride* ride) uint8_t trackType = trackElement->AsTrack()->GetTrackType(); uint8_t trackSequence = trackElement->AsTrack()->GetSequenceIndex(); - uint8_t direction = (tileElement->GetDirection() - trackElement->GetDirectionWithOffset(2)) & 3; + Direction direction = (tileElement->GetDirection() - direction_reverse(trackElement->GetDirection())) & 3; if (!(TrackSequenceProperties[trackType][trackSequence] & (1 << direction))) { diff --git a/src/openrct2/world/Footpath.cpp b/src/openrct2/world/Footpath.cpp index a513c45986..4e2def14b9 100644 --- a/src/openrct2/world/Footpath.cpp +++ b/src/openrct2/world/Footpath.cpp @@ -755,7 +755,7 @@ static bool footpath_disconnect_queue_from_path(int32_t x, int32_t y, TileElemen return true; } - for (int32_t direction = 0; direction < 4; direction++) + for (Direction direction : ALL_DIRECTIONS) { if ((action < 0) && (direction == tileElement->AsPath()->GetSlopeDirection())) continue; @@ -994,7 +994,7 @@ void footpath_connect_edges(int32_t x, int32_t y, TileElement* tileElement, int3 neighbour_list_init(&neighbourList); footpath_update_queue_entrance_banner(x, y, tileElement); - for (int32_t direction = 0; direction < 4; direction++) + for (Direction direction : ALL_DIRECTIONS) { loc_6A6C85(x, y, direction, tileElement, flags, true, &neighbourList); } @@ -1212,7 +1212,7 @@ void footpath_update_queue_chains() if (tileElement->AsEntrance()->GetRideIndex() != rideIndex) continue; - uint8_t direction = tileElement->GetDirectionWithOffset(2); + Direction direction = direction_reverse(tileElement->GetDirection()); footpath_chain_ride_queue(rideIndex, i, location.x << 5, location.y << 5, tileElement, direction); } while (!(tileElement++)->IsLastForTile()); } @@ -1425,15 +1425,15 @@ void PathElement::SetSloped(bool isSloped) entryIndex |= FOOTPATH_PROPERTIES_FLAG_IS_SLOPED; } -uint8_t PathElement::GetSlopeDirection() const +Direction PathElement::GetSlopeDirection() const { - return entryIndex & FOOTPATH_PROPERTIES_SLOPE_DIRECTION_MASK; + return static_cast(entryIndex & FOOTPATH_PROPERTIES_SLOPE_DIRECTION_MASK); } -void PathElement::SetSlopeDirection(uint8_t newSlope) +void PathElement::SetSlopeDirection(Direction newSlope) { entryIndex &= ~FOOTPATH_PROPERTIES_SLOPE_DIRECTION_MASK; - entryIndex |= newSlope & FOOTPATH_PROPERTIES_SLOPE_DIRECTION_MASK; + entryIndex |= static_cast(newSlope) & FOOTPATH_PROPERTIES_SLOPE_DIRECTION_MASK; } bool PathElement::IsQueue() const @@ -1891,7 +1891,7 @@ void footpath_update_queue_entrance_banner(int32_t x, int32_t y, TileElement* ti if (tileElement->AsEntrance()->GetEntranceType() == ENTRANCE_TYPE_RIDE_ENTRANCE) { footpath_queue_chain_push(tileElement->AsEntrance()->GetRideIndex()); - footpath_chain_ride_queue(255, 0, x, y, tileElement, tileElement->GetDirectionWithOffset(2)); + footpath_chain_ride_queue(255, 0, x, y, tileElement, direction_reverse(tileElement->GetDirection())); } break; } diff --git a/src/openrct2/world/Location.hpp b/src/openrct2/world/Location.hpp index f05d28b534..03abf81c7c 100644 --- a/src/openrct2/world/Location.hpp +++ b/src/openrct2/world/Location.hpp @@ -267,6 +267,14 @@ struct TileCoordsXYZ */ typedef uint8_t Direction; +const Direction INVALID_DIRECTION = 0xFF; + +/** + * Array of all valid cardinal directions, to make it easy to write range-based for loops like: + * for (Direction d : ALL_DIRECTIONS) + */ +constexpr Direction ALL_DIRECTIONS[] = { 0, 1, 2, 3 }; + /** * Given a direction, return the direction that points the other way, * on the same axis. @@ -281,6 +289,24 @@ typedef uint8_t Direction; return dir < 4; } +/** + * Given a direction, return the next cardinal direction, wrapping around if necessary. + * (TODO: Figure out if this is CW or CCW) + */ +[[maybe_unused]] static constexpr Direction direction_next(Direction dir) +{ + return (dir + 1) & 0x03; +} + +/** + * Given a direction, return the previous cardinal direction, wrapping around if necessary. + * (TODO: Figure out if this is CW or CCW) + */ +[[maybe_unused]] static constexpr Direction direction_prev(Direction dir) +{ + return (dir - 1) & 0x03; +} + struct CoordsXYZD : public CoordsXYZ { Direction direction = 0; diff --git a/src/openrct2/world/TileElement.cpp b/src/openrct2/world/TileElement.cpp index a9c75c643a..a514a9cbb9 100644 --- a/src/openrct2/world/TileElement.cpp +++ b/src/openrct2/world/TileElement.cpp @@ -28,18 +28,18 @@ void TileElementBase::SetType(uint8_t newType) this->type |= (newType & TILE_ELEMENT_TYPE_MASK); } -uint8_t TileElementBase::GetDirection() const +Direction TileElementBase::GetDirection() const { return this->type & TILE_ELEMENT_DIRECTION_MASK; } -void TileElementBase::SetDirection(uint8_t direction) +void TileElementBase::SetDirection(Direction direction) { this->type &= ~TILE_ELEMENT_DIRECTION_MASK; this->type |= (direction & TILE_ELEMENT_DIRECTION_MASK); } -uint8_t TileElementBase::GetDirectionWithOffset(uint8_t offset) const +Direction TileElementBase::GetDirectionWithOffset(uint8_t offset) const { return ((this->type & TILE_ELEMENT_DIRECTION_MASK) + offset) & TILE_ELEMENT_DIRECTION_MASK; } diff --git a/src/openrct2/world/TileElement.h b/src/openrct2/world/TileElement.h index 24afa0b9a4..f4d1a47f6d 100644 --- a/src/openrct2/world/TileElement.h +++ b/src/openrct2/world/TileElement.h @@ -68,9 +68,9 @@ struct TileElementBase uint8_t GetType() const; void SetType(uint8_t newType); - uint8_t GetDirection() const; - void SetDirection(uint8_t direction); - uint8_t GetDirectionWithOffset(uint8_t offset) const; + Direction GetDirection() const; + void SetDirection(Direction direction); + Direction GetDirectionWithOffset(uint8_t offset) const; bool IsLastForTile() const; void SetLastForTile(bool on); bool IsGhost() const; @@ -206,8 +206,8 @@ public: bool IsSloped() const; void SetSloped(bool isSloped); - uint8_t GetSlopeDirection() const; - void SetSlopeDirection(uint8_t newSlope); + Direction GetSlopeDirection() const; + void SetSlopeDirection(Direction newSlope); ride_id_t GetRideIndex() const; void SetRideIndex(ride_id_t newRideIndex); diff --git a/test/tests/Endianness.cpp b/test/tests/Endianness.cpp new file mode 100644 index 0000000000..b673360797 --- /dev/null +++ b/test/tests/Endianness.cpp @@ -0,0 +1,43 @@ +#include "openrct2/core/Endianness.h" + +#include + +TEST(SwapBETest, ForUInt8_DoesNothing) +{ + uint8_t before = 0x12; + uint8_t after = ByteSwapBE(before); + ASSERT_EQ(before, after); +} + +TEST(SwapBETest, ForUInt16_SwapsBytes) +{ + uint16_t before = 0x1234; + uint16_t after = ByteSwapBE(before); + ASSERT_EQ(0x3412u, after); +} + +TEST(SwapBETest, ForUInt32_SwapsBytes) +{ + uint32_t before = 0x12345678; + uint32_t after = ByteSwapBE(before); + ASSERT_EQ(0x78563412u, after); +} + +TEST(SwapBETest, ForUInt64_SwapsBytes) +{ + uint64_t before = 0x1234567887654321; + uint64_t after = ByteSwapBE(before); + ASSERT_EQ(0x2143658778563412u, after); +} + +TEST(SwapBETest, ForCustomBlittableType_SwapsBytes) +{ + struct MyStruct + { + uint16_t value; + }; + + MyStruct before = { 0x1234 }; + MyStruct after = ByteSwapBE(before); + ASSERT_EQ(0x3412, after.value); +} diff --git a/test/tests/Pathfinding.cpp b/test/tests/Pathfinding.cpp index 8670952dd2..57a05cb9be 100644 --- a/test/tests/Pathfinding.cpp +++ b/test/tests/Pathfinding.cpp @@ -83,8 +83,8 @@ protected: // Pick the direction the peep should initially move in, given the goal position. // This will also store the goal position and initialize pathfinding data for the peep. gPeepPathFindGoalPosition = goal; - const int32_t moveDir = peep_pathfind_choose_direction(*pos, peep); - if (moveDir < 0) + const Direction moveDir = peep_pathfind_choose_direction(*pos, peep); + if (moveDir == INVALID_DIRECTION) { // Couldn't determine a direction to move off in return false; diff --git a/test/tests/tests.vcxproj b/test/tests/tests.vcxproj index f4d448af46..cc19c85c7f 100644 --- a/test/tests/tests.vcxproj +++ b/test/tests/tests.vcxproj @@ -58,6 +58,7 @@ +