From 4f9c10d35f46b5c2592a85ab1eff6c4f17d0f17f Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sat, 26 Oct 2024 10:17:44 +0100 Subject: [PATCH] Codechange: Simplify storage of WaterTileType in map. (#13030) --- docs/landscape.html | 176 ++++++++++++++++++------------------- docs/landscape_grid.html | 29 +++--- src/saveload/afterload.cpp | 21 +++++ src/saveload/saveload.h | 1 + src/water_map.h | 37 ++++---- 5 files changed, 144 insertions(+), 120 deletions(-) diff --git a/docs/landscape.html b/docs/landscape.html index c0bea86500..24739af619 100644 --- a/docs/landscape.html +++ b/docs/landscape.html @@ -1050,98 +1050,92 @@
  • m1 bits 4..0: owner (for sea, rivers, and coasts normally 11)
  • m2: Depot index (for depots only)
  • m4: Random data for canal or river tiles
  • -
  • m5: tile type: +
  • m5 bits 7..4: Water tile type: - - - - - - - - - - - - - - - - - - - -
    00  water, canal or river
    01  coast or riverbank
    10..1B  canal locks - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    10  middle part, (SW-NE direction)
    11  middle part, (NW-SE direction)
    12  middle part, (NE-SW direction)
    13  middle part, (SE-NW direction)
    14  lower part, (SW-NE direction)
    15  lower part, (NW-SE direction)
    16  lower part, (NE-SW direction)
    17  lower part, (SE-NW direction)
    18  upper part, (SW-NE direction)
    19  upper part, (NW-SE direction)
    1A  upper part, (NE-SW direction)
    1B  upper part, (SE-NW direction)
    -
    80..83  ship depots - - - - - - - - - - - - - - - - - -
    80  ship depot, NE part (X direction)
    81  ship depot, SW part (X direction)
    82  ship depot, NW part (Y direction)
    83  ship depot, SE part (Y direction)
    -
    + + 0  + water, canal or river + + + 1  + coast or riverbank + + + 2  + canal lock
    + + + + + 3  + depot
    + + + + +
  • diff --git a/docs/landscape_grid.html b/docs/landscape_grid.html index 23c6a4d791..841e43b6bc 100644 --- a/docs/landscape_grid.html +++ b/docs/landscape_grid.html @@ -240,32 +240,37 @@ the array so you can quickly see what is used and what is not. OOOO OOOO - 6 - sea, shore - X XX XXXXX - OOOO OOOO OOOO OOOO - OOOO OOOO - OOOO OOOO - OOOO OOOX - OOOO OOOO - OOOO OOOO + 6 + sea + X XX XXXXX OOOO OOOO OOOO OOOO + OOOO OOOO + OOOO OOOO + 0000 OOO0 + OOOO OOOO + OOOO OOOO + OOOO OOOO OOOO OOOO canal, river XXXX XXXX - OOOO OOOO + 0000 OOOO + + + shore + OOOO OOOO + 0001 OOOO lock OOOO OOOO - OOO1 XX XX + 0010 XXXX shipdepot XXXX XXXX XXXX XXXX OOOO OOOO - 1OOO OOX X + 0011 OOXX 8 diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 78bea5302c..e140cb5bb4 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -840,6 +840,27 @@ bool AfterLoadGame() cp->current_station = cp->front->last_station_visited; } + + if (IsSavegameVersionBefore(SLV_WATER_TILE_TYPE)) { + /* Prior to SLV_WATER_TILE_TYPE, the water tile type was stored differently from the enumeration. This has to be + * converted before SLV_72 and SLV_82 conversions which use GetWaterTileType. */ + static constexpr uint8_t WBL_COAST_FLAG = 0; ///< Flag for coast. + + for (auto t : Map::Iterate()) { + if (!IsTileType(t, MP_WATER)) continue; + + switch (GB(t.m5(), 4, 4)) { + case 0x0: /* Previously WBL_TYPE_NORMAL, Clear water or coast. */ + SetWaterTileType(t, HasBit(t.m5(), WBL_COAST_FLAG) ? WATER_TILE_COAST : WATER_TILE_CLEAR); + break; + + case 0x1: SetWaterTileType(t, WATER_TILE_LOCK); break; /* Previously WBL_TYPE_LOCK */ + case 0x8: SetWaterTileType(t, WATER_TILE_DEPOT); break; /* Previously WBL_TYPE_DEPOT */ + default: SetWaterTileType(t, WATER_TILE_CLEAR); break; /* Shouldn't happen... */ + } + } + } + if (IsSavegameVersionBefore(SLV_72)) { /* Locks in very old savegames had OWNER_WATER as owner */ for (auto t : Map::Iterate()) { diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index e92373a26c..357167e9a8 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -387,6 +387,7 @@ enum SaveLoadVersion : uint16_t { SLV_ROAD_STOP_TILE_DATA, ///< 340 PR#12883 Move storage of road stop tile data, also save for road waypoints. SLV_COMPANY_ALLOW_LIST_V2, ///< 341 PR#12908 Fixed savegame format for saving of list of client keys that are allowed to join this company. + SLV_WATER_TILE_TYPE, ///< 342 PR#13030 Simplify water tile type. SL_MAX_VERSION, ///< Highest possible saveload version }; diff --git a/src/water_map.h b/src/water_map.h index 560a9914df..a080a883bc 100644 --- a/src/water_map.h +++ b/src/water_map.h @@ -20,12 +20,6 @@ enum WaterTileTypeBitLayout { WBL_TYPE_BEGIN = 4, ///< Start of the 'type' bitfield. WBL_TYPE_COUNT = 4, ///< Length of the 'type' bitfield. - WBL_TYPE_NORMAL = 0x0, ///< Clear water or coast ('type' bitfield). - WBL_TYPE_LOCK = 0x1, ///< Lock ('type' bitfield). - WBL_TYPE_DEPOT = 0x8, ///< Depot ('type' bitfield). - - WBL_COAST_FLAG = 0, ///< Flag for coast. - WBL_LOCK_ORIENT_BEGIN = 0, ///< Start of lock orientation bitfield. WBL_LOCK_ORIENT_COUNT = 2, ///< Length of lock orientation bitfield. WBL_LOCK_PART_BEGIN = 2, ///< Start of lock part bitfield. @@ -79,20 +73,25 @@ enum LockPart { bool IsPossibleDockingTile(Tile t); /** - * Get the water tile type at a tile. + * Get the water tile type of a tile. * @param t Water tile to query. * @return Water tile type at the tile. */ inline WaterTileType GetWaterTileType(Tile t) { assert(IsTileType(t, MP_WATER)); + return static_cast(GB(t.m5(), WBL_TYPE_BEGIN, WBL_TYPE_COUNT)); +} - switch (GB(t.m5(), WBL_TYPE_BEGIN, WBL_TYPE_COUNT)) { - case WBL_TYPE_NORMAL: return HasBit(t.m5(), WBL_COAST_FLAG) ? WATER_TILE_COAST : WATER_TILE_CLEAR; - case WBL_TYPE_LOCK: return WATER_TILE_LOCK; - case WBL_TYPE_DEPOT: return WATER_TILE_DEPOT; - default: NOT_REACHED(); - } +/** + * Set the water tile type of a tile. + * @param t Water tile to set. + * @param type Water tile type of the tile. + */ +inline void SetWaterTileType(Tile t, WaterTileType type) +{ + assert(IsTileType(t, MP_WATER)); + SB(t.m5(), WBL_TYPE_BEGIN, WBL_TYPE_COUNT, to_underlying(type)); } /** @@ -390,7 +389,8 @@ inline void MakeShore(Tile t) t.m2() = 0; t.m3() = 0; t.m4() = 0; - t.m5() = WBL_TYPE_NORMAL << WBL_TYPE_BEGIN | 1 << WBL_COAST_FLAG; + t.m5() = 0; + SetWaterTileType(t, WATER_TILE_COAST); SB(t.m6(), 2, 4, 0); t.m7() = 0; } @@ -411,7 +411,8 @@ inline void MakeWater(Tile t, Owner o, WaterClass wc, uint8_t random_bits) t.m2() = 0; t.m3() = 0; t.m4() = random_bits; - t.m5() = WBL_TYPE_NORMAL << WBL_TYPE_BEGIN; + t.m5() = 0; + SetWaterTileType(t, WATER_TILE_CLEAR); SB(t.m6(), 2, 4, 0); t.m7() = 0; } @@ -465,7 +466,8 @@ inline void MakeShipDepot(Tile t, Owner o, DepotID did, DepotPart part, Axis a, t.m2() = did; t.m3() = 0; t.m4() = 0; - t.m5() = WBL_TYPE_DEPOT << WBL_TYPE_BEGIN | part << WBL_DEPOT_PART | a << WBL_DEPOT_AXIS; + t.m5() = part << WBL_DEPOT_PART | a << WBL_DEPOT_AXIS; + SetWaterTileType(t, WATER_TILE_DEPOT); SB(t.m6(), 2, 4, 0); t.m7() = 0; } @@ -488,7 +490,8 @@ inline void MakeLockTile(Tile t, Owner o, LockPart part, DiagDirection dir, Wate t.m2() = 0; t.m3() = 0; t.m4() = 0; - t.m5() = WBL_TYPE_LOCK << WBL_TYPE_BEGIN | part << WBL_LOCK_PART_BEGIN | dir << WBL_LOCK_ORIENT_BEGIN; + t.m5() = part << WBL_LOCK_PART_BEGIN | dir << WBL_LOCK_ORIENT_BEGIN; + SetWaterTileType(t, WATER_TILE_LOCK); SB(t.m6(), 2, 4, 0); t.m7() = 0; }