From 143581b9e03b56c6afb621ee181acf0f875e48ca Mon Sep 17 00:00:00 2001 From: Andrii Dokhniak Date: Thu, 30 May 2024 20:24:55 +0200 Subject: [PATCH 1/9] POC of more companies --- src/cargomonitor.h | 2 +- src/company_cmd.cpp | 72 ++++---------------------------------- src/company_type.h | 30 +++++++++------- src/graph_gui.cpp | 2 +- src/saveload/afterload.cpp | 20 +++++------ src/saveload/signs_sl.cpp | 2 +- src/vehiclelist.cpp | 2 +- 7 files changed, 38 insertions(+), 92 deletions(-) diff --git a/src/cargomonitor.h b/src/cargomonitor.h index 614f10002e..b71a355d7e 100644 --- a/src/cargomonitor.h +++ b/src/cargomonitor.h @@ -44,7 +44,7 @@ enum CargoCompanyBits { CCB_CARGO_TYPE_START = 19, ///< Start bit of the cargo type field. CCB_CARGO_TYPE_LENGTH = 6, ///< Number of bits of the cargo type field. CCB_COMPANY_START = 25, ///< Start bit of the company field. - CCB_COMPANY_LENGTH = 4, ///< Number of bits of the company field. + CCB_COMPANY_LENGTH = 8, ///< Number of bits of the company field. }; static_assert(NUM_CARGO <= (1 << CCB_CARGO_TYPE_LENGTH)); diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp index 74ad2893f4..675bb7f350 100644 --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -7,6 +7,7 @@ /** @file company_cmd.cpp Handling of companies. */ +#include "gfx_type.h" #include "stdafx.h" #include "company_base.h" #include "company_func.h" @@ -448,27 +449,6 @@ bad_town_name:; } } -/** Sorting weights for the company colours. */ -static const uint8_t _colour_sort[COLOUR_END] = {2, 2, 3, 2, 3, 2, 3, 2, 3, 2, 2, 2, 3, 1, 1, 1}; -/** Similar colours, so we can try to prevent same coloured companies. */ -static const Colours _similar_colour[COLOUR_END][2] = { - { COLOUR_BLUE, COLOUR_LIGHT_BLUE }, // COLOUR_DARK_BLUE - { COLOUR_GREEN, COLOUR_DARK_GREEN }, // COLOUR_PALE_GREEN - { INVALID_COLOUR, INVALID_COLOUR }, // COLOUR_PINK - { COLOUR_ORANGE, INVALID_COLOUR }, // COLOUR_YELLOW - { INVALID_COLOUR, INVALID_COLOUR }, // COLOUR_RED - { COLOUR_DARK_BLUE, COLOUR_BLUE }, // COLOUR_LIGHT_BLUE - { COLOUR_PALE_GREEN, COLOUR_DARK_GREEN }, // COLOUR_GREEN - { COLOUR_PALE_GREEN, COLOUR_GREEN }, // COLOUR_DARK_GREEN - { COLOUR_DARK_BLUE, COLOUR_LIGHT_BLUE }, // COLOUR_BLUE - { COLOUR_BROWN, COLOUR_ORANGE }, // COLOUR_CREAM - { COLOUR_PURPLE, INVALID_COLOUR }, // COLOUR_MAUVE - { COLOUR_MAUVE, INVALID_COLOUR }, // COLOUR_PURPLE - { COLOUR_YELLOW, COLOUR_CREAM }, // COLOUR_ORANGE - { COLOUR_CREAM, INVALID_COLOUR }, // COLOUR_BROWN - { COLOUR_WHITE, INVALID_COLOUR }, // COLOUR_GREY - { COLOUR_GREY, INVALID_COLOUR }, // COLOUR_WHITE -}; /** * Generate a company colour. @@ -476,53 +456,13 @@ static const Colours _similar_colour[COLOUR_END][2] = { */ static Colours GenerateCompanyColour() { - Colours colours[COLOUR_END]; + int num_colours = COLOUR_END - COLOUR_BEGIN; - /* Initialize array */ - for (uint i = 0; i < COLOUR_END; i++) colours[i] = static_cast(i); - - /* And randomize it */ - for (uint i = 0; i < 100; i++) { - uint r = Random(); - Swap(colours[GB(r, 0, 4)], colours[GB(r, 4, 4)]); + int companies = 0; + for (const Company *_ : Company::Iterate()) { + companies++; } - - /* Bubble sort it according to the values in table 1 */ - for (uint i = 0; i < COLOUR_END; i++) { - for (uint j = 1; j < COLOUR_END; j++) { - if (_colour_sort[colours[j - 1]] < _colour_sort[colours[j]]) { - Swap(colours[j - 1], colours[j]); - } - } - } - - /* Move the colours that look similar to each company's colour to the side */ - for (const Company *c : Company::Iterate()) { - Colours pcolour = c->colour; - - for (uint i = 0; i < COLOUR_END; i++) { - if (colours[i] == pcolour) { - colours[i] = INVALID_COLOUR; - break; - } - } - - for (uint j = 0; j < 2; j++) { - Colours similar = _similar_colour[pcolour][j]; - if (similar == INVALID_COLOUR) break; - - for (uint i = 1; i < COLOUR_END; i++) { - if (colours[i - 1] == similar) Swap(colours[i - 1], colours[i]); - } - } - } - - /* Return the first available colour */ - for (uint i = 0; i < COLOUR_END; i++) { - if (colours[i] != INVALID_COLOUR) return colours[i]; - } - - NOT_REACHED(); + return Colours(companies % num_colours); } /** diff --git a/src/company_type.h b/src/company_type.h index 355bde8630..7c4691048c 100644 --- a/src/company_type.h +++ b/src/company_type.h @@ -18,21 +18,27 @@ enum Owner : uint8_t { /* All companies below MAX_COMPANIES are playable * companies, above, they are special, computer controlled 'companies' */ - OWNER_BEGIN = 0x00, ///< First owner - COMPANY_FIRST = 0x00, ///< First company, same as owner - MAX_COMPANIES = 0x0F, ///< Maximum number of companies - OWNER_TOWN = 0x0F, ///< A town owns the tile, or a town is expanding - OWNER_NONE = 0x10, ///< The tile has no ownership - OWNER_WATER = 0x11, ///< The tile/execution is done by "water" - OWNER_DEITY = 0x12, ///< The object is owned by a superuser / goal script + OWNER_BEGIN = 0x00, ///< First owner + COMPANY_FIRST = 0x00, ///< First company, same as owner + MAX_COMPANIES = 0xF0, ///< Maximum number of companies + OLD_MAX_COMPANIES = 0x0F, ///< Maximum number of companies + OWNER_TOWN = 0xF1, ///< A town owns the tile, or a town is expanding + OLD_OWNER_TOWN = 0x0F, + OWNER_NONE = 0xF2, ///< The tile has no ownership + OLD_OWNER_NONE = 0x10, ///< The tile has no ownership + + + OWNER_WATER = 0xF3, ///< The tile/execution is done by "water" + OLD_OWNER_WATER = 0x11, ///< The tile/execution is done by "water" + OWNER_DEITY = 0xF4, ///< The object is owned by a superuser / goal script OWNER_END, ///< Last + 1 owner - INVALID_OWNER = 0xFF, ///< An invalid owner - INVALID_COMPANY = 0xFF, ///< An invalid company + INVALID_OWNER = 0xFF, ///< An invalid owner + INVALID_COMPANY = 0xFF, ///< An invalid company /* 'Fake' companies used for networks */ - COMPANY_INACTIVE_CLIENT = 253, ///< The client is joining - COMPANY_NEW_COMPANY = 254, ///< The client wants a new company - COMPANY_SPECTATOR = 255, ///< The client is spectating + COMPANY_INACTIVE_CLIENT = 0xF7, ///< The client is joining + COMPANY_NEW_COMPANY = 0xF8, ///< The client wants a new company + COMPANY_SPECTATOR = 0xF9, ///< The client is spectating }; DECLARE_POSTFIX_INCREMENT(Owner) DECLARE_ENUM_AS_ADDABLE(Owner) diff --git a/src/graph_gui.cpp b/src/graph_gui.cpp index e705e3749a..9c8f97b7ff 100644 --- a/src/graph_gui.cpp +++ b/src/graph_gui.cpp @@ -166,7 +166,7 @@ struct ValuesInterval { struct BaseGraphWindow : Window { protected: - static const int GRAPH_MAX_DATASETS = 64; + static const int GRAPH_MAX_DATASETS = 300; static const int GRAPH_BASE_COLOUR = GREY_SCALE(2); static const int GRAPH_GRID_COLOUR = GREY_SCALE(3); static const int GRAPH_AXIS_LINE_COLOUR = GREY_SCALE(1); diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 4771490268..b8ddf0258d 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -656,7 +656,7 @@ bool AfterLoadGame() * walk through the whole map.. */ if (IsSavegameVersionBefore(SLV_4, 3)) { for (auto t : Map::Iterate()) { - if (IsTileType(t, MP_WATER) && GetTileOwner(t) >= MAX_COMPANIES) { + if (IsTileType(t, MP_WATER) && GetTileOwner(t) >= OLD_MAX_COMPANIES) { SetTileOwner(t, OWNER_WATER); } } @@ -986,7 +986,7 @@ bool AfterLoadGame() case MP_ROAD: t.m4() |= (t.m2() << 4); - if ((GB(t.m5(), 4, 2) == ROAD_TILE_CROSSING ? (Owner)t.m3() : GetTileOwner(t)) == OWNER_TOWN) { + if ((GB(t.m5(), 4, 2) == ROAD_TILE_CROSSING ? (Owner)t.m3() : GetTileOwner(t)) == OLD_OWNER_TOWN) { SetTownIndex(t, CalcClosestTownFromTile(t)->index); } else { SetTownIndex(t, 0); @@ -1151,7 +1151,7 @@ bool AfterLoadGame() Owner o = GetTileOwner(t); SB(t.m7(), 0, 5, o); // road owner - SB(t.m3(), 4, 4, o == OWNER_NONE ? OWNER_TOWN : o); // tram owner + SB(t.m3(), 4, 4, o == OLD_OWNER_NONE ? OWNER_TOWN : o); // tram owner } SB(t.m6(), 2, 4, GB(t.m2(), 4, 4)); // bridge type SB(t.m7(), 5, 1, GB(t.m4(), 7, 1)); // snow/desert @@ -1213,7 +1213,7 @@ bool AfterLoadGame() GetRailType(t) ); } else { - TownID town = IsTileOwner(t, OWNER_TOWN) ? ClosestTownFromTile(t, UINT_MAX)->index : 0; + TownID town = IsTileOwner(t, OLD_OWNER_TOWN) ? ClosestTownFromTile(t, UINT_MAX)->index : 0; /* MakeRoadNormal */ SetTileType(t, MP_ROAD); @@ -1568,7 +1568,7 @@ bool AfterLoadGame() * be OWNER_NONE. So replace OWNER_NONE with OWNER_WATER. */ if (IsSavegameVersionBefore(SLV_46)) { for (Waypoint *wp : Waypoint::Iterate()) { - if ((wp->facilities & FACIL_DOCK) != 0 && IsTileOwner(wp->xy, OWNER_NONE) && TileHeight(wp->xy) == 0) SetTileOwner(wp->xy, OWNER_WATER); + if ((wp->facilities & FACIL_DOCK) != 0 && IsTileOwner(wp->xy, OLD_OWNER_NONE) && TileHeight(wp->xy) == 0) SetTileOwner(wp->xy, OWNER_WATER); } } @@ -1865,7 +1865,7 @@ bool AfterLoadGame() if (IsBuoyTile(t) || IsDriveThroughStopTile(t) || IsTileType(t, MP_WATER)) { Owner o = GetTileOwner(t); - if (o < MAX_COMPANIES && !Company::IsValidID(o)) { + if (o < OLD_MAX_COMPANIES && !Company::IsValidID(o)) { Backup cur_company(_current_company, o); ChangeTileOwner(t, o, INVALID_OWNER); cur_company.Restore(); @@ -1880,7 +1880,7 @@ bool AfterLoadGame() for (RoadTramType rtt : _roadtramtypes) { /* update even non-existing road types to update tile owner too */ Owner o = GetRoadOwner(t, rtt); - if (o < MAX_COMPANIES && !Company::IsValidID(o)) SetRoadOwner(t, rtt, OWNER_NONE); + if (o < OLD_MAX_COMPANIES && !Company::IsValidID(o)) SetRoadOwner(t, rtt, OWNER_NONE); } if (IsLevelCrossing(t)) { if (!Company::IsValidID(GetTileOwner(t))) FixOwnerOfRailTrack(t); @@ -1996,7 +1996,7 @@ bool AfterLoadGame() /* signs with invalid owner left from older savegames */ for (Sign *si : Sign::Iterate()) { - if (si->owner != OWNER_NONE && !Company::IsValidID(si->owner)) si->owner = OWNER_NONE; + if (si->owner != OLD_OWNER_NONE && !Company::IsValidID(si->owner)) si->owner = OWNER_NONE; } /* Station can get named based on an industry type, but the current ones @@ -2025,7 +2025,7 @@ bool AfterLoadGame() for (Town *t : Town::Iterate()) { if (t->have_ratings == 0xFF) t->have_ratings = MAX_UVALUE(CompanyMask); - for (uint i = 8; i != MAX_COMPANIES; i++) t->ratings[i] = RATING_INITIAL; + for (uint i = 8; i != OLD_MAX_COMPANIES; i++) t->ratings[i] = RATING_INITIAL; } } @@ -2474,7 +2474,7 @@ bool AfterLoadGame() if (IsSavegameVersionBefore(SLV_148)) { for (Object *o : Object::Iterate()) { Owner owner = GetTileOwner(o->location.tile); - o->colour = (owner == OWNER_NONE) ? static_cast(GB(Random(), 0, 4)) : Company::Get(owner)->livery->colour1; + o->colour = (owner == OLD_OWNER_NONE) ? static_cast(GB(Random(), 0, 4)) : Company::Get(owner)->livery->colour1; } } diff --git a/src/saveload/signs_sl.cpp b/src/saveload/signs_sl.cpp index 336a552f76..e3a69c2f5b 100644 --- a/src/saveload/signs_sl.cpp +++ b/src/saveload/signs_sl.cpp @@ -62,7 +62,7 @@ struct SIGNChunkHandler : ChunkHandler { } /* Signs placed in scenario editor shall now be OWNER_DEITY */ - if (IsSavegameVersionBefore(SLV_171) && si->owner == OWNER_NONE && _file_to_saveload.abstract_ftype == FT_SCENARIO) { + if (IsSavegameVersionBefore(SLV_171) && si->owner == OLD_OWNER_NONE && _file_to_saveload.abstract_ftype == FT_SCENARIO) { si->owner = OWNER_DEITY; } } diff --git a/src/vehiclelist.cpp b/src/vehiclelist.cpp index 48214d9384..aa4cd9ac16 100644 --- a/src/vehiclelist.cpp +++ b/src/vehiclelist.cpp @@ -7,6 +7,7 @@ /** @file vehiclelist.cpp Lists of vehicles. */ +#include "cargomonitor.h" #include "stdafx.h" #include "train.h" #include "vehicle_func.h" @@ -23,7 +24,6 @@ uint32_t VehicleListIdentifier::Pack() const { uint8_t c = this->company == OWNER_NONE ? 0xF : (uint8_t)this->company; - assert(c < (1 << 4)); assert(this->vtype < (1 << 2)); assert(this->index < (1 << 20)); assert(this->type < VLT_END); From da726f6d29db035c4d06055bbb667359e30cceb4 Mon Sep 17 00:00:00 2001 From: Andrii Dokhniak Date: Fri, 31 May 2024 21:35:39 +0200 Subject: [PATCH 2/9] IT WORKS (somewhat) --- src/cargomonitor.h | 15 ++++--- src/clear_map.h | 6 ++- src/company_cmd.cpp | 1 + src/company_type.h | 12 ++++- src/engine.cpp | 6 +-- src/graph_gui.cpp | 3 +- src/map_func.h | 17 ++++++- src/misc_gui.cpp | 1 + src/newgrf_town.cpp | 5 ++- src/rail_map.h | 2 + src/road_map.h | 33 +++++++++++++- src/saveload/afterload.cpp | 2 +- src/saveload/cargomonitor_sl.cpp | 2 +- src/saveload/company_sl.cpp | 4 +- src/saveload/engine_sl.cpp | 10 ++--- src/saveload/map_sl.cpp | 29 ++++++++++++ src/saveload/oldloader_sl.cpp | 1 + src/saveload/saveload.cpp | 77 ++++++++++++++++++++++++++++++++ src/saveload/saveload.h | 17 ++++++- src/saveload/town_sl.cpp | 8 ++-- src/tile_map.h | 43 ++++++++++++++++++ src/void_map.h | 2 + 22 files changed, 264 insertions(+), 32 deletions(-) diff --git a/src/cargomonitor.h b/src/cargomonitor.h index b71a355d7e..30a87ea320 100644 --- a/src/cargomonitor.h +++ b/src/cargomonitor.h @@ -12,6 +12,7 @@ #include "cargo_type.h" #include "company_func.h" +#include "company_type.h" #include "industry.h" #include "town.h" #include "core/overflowsafe_type.hpp" @@ -24,12 +25,12 @@ struct Station; * - bits 0-15 town or industry number * - bit 16 is set if it is an industry number (else it is a town number). * - bits 19-23 Cargo type. - * - bits 24-31 %Company number. + * - bits 24-COMPANY_BIT_SIZE %Company number. */ -typedef uint32_t CargoMonitorID; ///< Type of the cargo monitor number. +typedef uint64_t CargoMonitorID; ///< Type of the cargo monitor number. /** Map type for storing and updating active cargo monitor numbers and their amounts. */ -typedef std::map CargoMonitorMap; +typedef std::map CargoMonitorMap; extern CargoMonitorMap _cargo_pickups; extern CargoMonitorMap _cargo_deliveries; @@ -44,9 +45,11 @@ enum CargoCompanyBits { CCB_CARGO_TYPE_START = 19, ///< Start bit of the cargo type field. CCB_CARGO_TYPE_LENGTH = 6, ///< Number of bits of the cargo type field. CCB_COMPANY_START = 25, ///< Start bit of the company field. - CCB_COMPANY_LENGTH = 8, ///< Number of bits of the company field. + CCB_COMPANY_LENGTH = COMPANY_SIZE_BITS, ///< Number of bits of the company field. }; + +static_assert(CCB_COMPANY_LENGTH <= (1 << 30)); // This should never be a limiting factor static_assert(NUM_CARGO <= (1 << CCB_CARGO_TYPE_LENGTH)); static_assert(MAX_COMPANIES <= (1 << CCB_COMPANY_LENGTH)); @@ -63,7 +66,7 @@ inline CargoMonitorID EncodeCargoIndustryMonitor(CompanyID company, CargoID ctyp assert(ctype < (1 << CCB_CARGO_TYPE_LENGTH)); assert(company < (1 << CCB_COMPANY_LENGTH)); - uint32_t ret = 0; + uint64_t ret = 0; SB(ret, CCB_TOWN_IND_NUMBER_START, CCB_TOWN_IND_NUMBER_LENGTH, ind); SetBit(ret, CCB_IS_INDUSTRY_BIT); SB(ret, CCB_CARGO_TYPE_START, CCB_CARGO_TYPE_LENGTH, ctype); @@ -83,7 +86,7 @@ inline CargoMonitorID EncodeCargoTownMonitor(CompanyID company, CargoID ctype, T assert(ctype < (1 << CCB_CARGO_TYPE_LENGTH)); assert(company < (1 << CCB_COMPANY_LENGTH)); - uint32_t ret = 0; + uint64_t ret = 0; SB(ret, CCB_TOWN_IND_NUMBER_START, CCB_TOWN_IND_NUMBER_LENGTH, town); SB(ret, CCB_CARGO_TYPE_START, CCB_CARGO_TYPE_LENGTH, ctype); SB(ret, CCB_COMPANY_START, CCB_COMPANY_LENGTH, company); diff --git a/src/clear_map.h b/src/clear_map.h index 64eb640d12..b24753c5f2 100644 --- a/src/clear_map.h +++ b/src/clear_map.h @@ -260,7 +260,6 @@ inline void MakeClear(Tile t, ClearGround g, uint density) { SetTileType(t, MP_CLEAR); t.m1() = 0; - SetTileOwner(t, OWNER_NONE); t.m2() = 0; t.m3() = 0; t.m4() = 0 << 5 | 0 << 2; @@ -268,6 +267,8 @@ inline void MakeClear(Tile t, ClearGround g, uint density) t.m6() = 0; t.m7() = 0; t.m8() = 0; + t.m9() = 0; + SetTileOwner(t, OWNER_NONE); } @@ -281,7 +282,6 @@ inline void MakeField(Tile t, uint field_type, IndustryID industry) { SetTileType(t, MP_CLEAR); t.m1() = 0; - SetTileOwner(t, OWNER_NONE); t.m2() = industry; t.m3() = field_type; t.m4() = 0 << 5 | 0 << 2; @@ -289,6 +289,8 @@ inline void MakeField(Tile t, uint field_type, IndustryID industry) SB(t.m6(), 2, 4, 0); t.m7() = 0; t.m8() = 0; + t.m9() = 0; + SetTileOwner(t, OWNER_NONE); } /** diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp index 675bb7f350..ecc8bb2f52 100644 --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -7,6 +7,7 @@ /** @file company_cmd.cpp Handling of companies. */ +#include "company_type.h" #include "gfx_type.h" #include "stdafx.h" #include "company_base.h" diff --git a/src/company_type.h b/src/company_type.h index 7c4691048c..b283f4b565 100644 --- a/src/company_type.h +++ b/src/company_type.h @@ -11,6 +11,7 @@ #define COMPANY_TYPE_H #include "core/enum_type.hpp" +#include /** * Enum for all companies/owners. @@ -40,6 +41,15 @@ enum Owner : uint8_t { COMPANY_NEW_COMPANY = 0xF8, ///< The client wants a new company COMPANY_SPECTATOR = 0xF9, ///< The client is spectating }; +const uint8_t COMPANY_SIZE_BITS = 8; /// Size of the company id in bits + +static_assert(COMPANY_SIZE_BITS <= 10); /// 32bit m9 can only fit 3 owners of size 10 + +static_assert(MAX_COMPANIES <= (1U << COMPANY_SIZE_BITS) - 1); /// Checking that MAX_COMPANIES is in bounds +static_assert(OWNER_END <= (1U << COMPANY_SIZE_BITS) - 1); +static_assert(INVALID_OWNER <= (1U << COMPANY_SIZE_BITS) - 1); +static_assert(INVALID_COMPANY <= (1U << COMPANY_SIZE_BITS) - 1); + DECLARE_POSTFIX_INCREMENT(Owner) DECLARE_ENUM_AS_ADDABLE(Owner) @@ -53,7 +63,7 @@ static const uint MAX_COMPETITORS_INTERVAL = 500; ///< The maximum interval (in typedef Owner CompanyID; -typedef uint16_t CompanyMask; +typedef std::bitset CompanyMask; struct Company; typedef uint32_t CompanyManagerFace; ///< Company manager face bits, info see in company_manager_face.h diff --git a/src/engine.cpp b/src/engine.cpp index 979c6a7e31..74f2928636 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -940,7 +940,7 @@ static IntervalTimer _calendar_engines_daily({TimerGameCalend CloseWindowById(WC_ENGINE_PREVIEW, i); e->preview_company = INVALID_COMPANY; } - } else if (CountBits(e->preview_asked) < MAX_COMPANIES) { + } else if (e->preview_asked.count() < MAX_COMPANIES) { e->preview_company = GetPreviewCompany(e); if (e->preview_company == INVALID_COMPANY) { @@ -969,7 +969,7 @@ static IntervalTimer _calendar_engines_daily({TimerGameCalend void ClearEnginesHiddenFlagOfCompany(CompanyID cid) { for (Engine *e : Engine::Iterate()) { - SB(e->company_hidden, cid, 1, 0); + e->company_hidden.reset(cid); } } @@ -987,7 +987,7 @@ CommandCost CmdSetVehicleVisibility(DoCommandFlag flags, EngineID engine_id, boo if (!IsEngineBuildable(e->index, e->type, _current_company)) return CMD_ERROR; if ((flags & DC_EXEC) != 0) { - SB(e->company_hidden, _current_company, 1, hide ? 1 : 0); + e->company_hidden.set(_current_company, hide ? 1 : 0); AddRemoveEngineFromAutoreplaceAndBuildWindows(e->type); } diff --git a/src/graph_gui.cpp b/src/graph_gui.cpp index 9c8f97b7ff..1b39376367 100644 --- a/src/graph_gui.cpp +++ b/src/graph_gui.cpp @@ -7,6 +7,7 @@ /** @file graph_gui.cpp GUI that shows performance graphs. */ +#include "company_type.h" #include "stdafx.h" #include "graph_gui.h" #include "window_gui.h" @@ -182,7 +183,7 @@ protected: static const int MIN_GRAPH_NUM_LINES_Y = 9; ///< Minimal number of horizontal lines to draw. static const int MIN_GRID_PIXEL_SIZE = 20; ///< Minimum distance between graph lines. - uint64_t excluded_data; ///< bitmask of the datasets that shouldn't be displayed. + CompanyMask excluded_data; ///< bitmask of the datasets that shouldn't be displayed. uint8_t num_dataset; uint8_t num_on_x_axis; uint8_t num_vert_lines; diff --git a/src/map_func.h b/src/map_func.h index 7d3e11cd80..c85ac32795 100644 --- a/src/map_func.h +++ b/src/map_func.h @@ -10,6 +10,8 @@ #ifndef MAP_FUNC_H #define MAP_FUNC_H +#include "company_type.h" +#include "core/bitmath_func.hpp" #include "core/math_func.hpp" #include "tile_type.h" #include "map_type.h" @@ -33,7 +35,7 @@ private: uint8_t type; ///< The type (bits 4..7), bridges (2..3), rainforest/desert (0..1) uint8_t height; ///< The height of the northern corner. uint16_t m2; ///< Primarily used for indices to towns, industries and stations - uint8_t m1; ///< Primarily used for ownership information + uint8_t m1; ///< Primarily used for ownership information (In old versions) uint8_t m3; ///< General purpose uint8_t m4; ///< General purpose uint8_t m5; ///< General purpose @@ -49,6 +51,7 @@ private: uint8_t m6; ///< General purpose uint8_t m7; ///< Primarily used for newgrf support uint16_t m8; ///< General purpose + uint32_t m9; ///< Stores the actuall ownership information }; static TileBase *base_tiles; ///< Pointer to the tile-array. @@ -198,6 +201,18 @@ public: { return extended_tiles[tile.base()].m8; } + + /** + * Primarily used for ownership information + * TODO: Add more docs + * Look at docs/landscape.html for the exact meaning of the data. + * @param tile The tile to get the data for. + * @return reference to the byte holding the data. + */ + debug_inline uint32_t &m9() + { + return extended_tiles[tile.base()].m9; + } }; /** diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp index 7ed51cac1d..549a2599f7 100644 --- a/src/misc_gui.cpp +++ b/src/misc_gui.cpp @@ -129,6 +129,7 @@ public: Debug(misc, LANDINFOD_LEVEL, "m6 = 0x{:x}", tile.m6()); Debug(misc, LANDINFOD_LEVEL, "m7 = 0x{:x}", tile.m7()); Debug(misc, LANDINFOD_LEVEL, "m8 = 0x{:x}", tile.m8()); + Debug(misc, LANDINFOD_LEVEL, "m9 = 0x{:x}", tile.m9()); PrintWaterRegionDebugInfo(tile); #undef LANDINFOD_LEVEL diff --git a/src/newgrf_town.cpp b/src/newgrf_town.cpp index d144d56561..75227b788c 100644 --- a/src/newgrf_town.cpp +++ b/src/newgrf_town.cpp @@ -83,8 +83,9 @@ case 0xAB: return GB(this->t->ratings[6], 8, 8); case 0xAC: return this->t->ratings[7]; case 0xAD: return GB(this->t->ratings[7], 8, 8); - case 0xAE: return this->t->have_ratings; - case 0xB2: return this->t->statues; + // MYTODO: Fix this crap later + //case 0xAE: return this->t->have_ratings; + //case 0xB2: return this->t->statues; case 0xB6: return ClampTo(this->t->cache.num_houses); case 0xB9: return this->t->growth_rate / Ticks::TOWN_GROWTH_TICKS; case 0xBA: cid = GetCargoIDByLabel(CT_PASSENGERS); return IsValidCargoID(cid) ? ClampTo(this->t->supplied[cid].new_max) : 0; diff --git a/src/rail_map.h b/src/rail_map.h index 5ff2fb9ec3..f31bb0b5ce 100644 --- a/src/rail_map.h +++ b/src/rail_map.h @@ -528,6 +528,7 @@ inline void MakeRailNormal(Tile t, Owner o, TrackBits b, RailType r) SB(t.m6(), 2, 4, 0); t.m7() = 0; t.m8() = r; + t.m9() = 0; } /** @@ -561,6 +562,7 @@ inline void MakeRailDepot(Tile tile, Owner owner, DepotID depot_id, DiagDirectio SB(tile.m6(), 2, 4, 0); tile.m7() = 0; tile.m8() = rail_type; + tile.m9() = 0; } #endif /* RAIL_MAP_H */ diff --git a/src/road_map.h b/src/road_map.h index 9179579b4c..d979f65b78 100644 --- a/src/road_map.h +++ b/src/road_map.h @@ -10,6 +10,7 @@ #ifndef ROAD_MAP_H #define ROAD_MAP_H +#include "company_type.h" #include "track_func.h" #include "depot_type.h" #include "rail_type.h" @@ -231,7 +232,7 @@ inline bool HasTileAnyRoadType(Tile t, RoadTypes rts) * @param rtt RoadTramType. * @return Owner of the given road type. */ -inline Owner GetRoadOwner(Tile t, RoadTramType rtt) +inline Owner OldGetRoadOwner(Tile t, RoadTramType rtt) { assert(MayHaveRoad(t)); if (rtt == RTT_ROAD) return (Owner)GB(IsNormalRoadTile(t) ? t.m1() : t.m7(), 0, 5); @@ -242,6 +243,21 @@ inline Owner GetRoadOwner(Tile t, RoadTramType rtt) return o == OWNER_TOWN ? OWNER_NONE : o; } +/** + * Get the owner of a specific road type. + * @param t The tile to query. + * @param rtt RoadTramType. + * @return Owner of the given road type. + */ +inline Owner GetRoadOwner(Tile t, RoadTramType rtt) +{ + assert(MayHaveRoad(t)); + if (rtt == RTT_ROAD) return (Owner)GB(t.m9(), IsNormalRoadTile(t) ? 0 : COMPANY_SIZE_BITS * 2, COMPANY_SIZE_BITS); + + Owner o = (Owner)GB(t.m9(), COMPANY_SIZE_BITS, COMPANY_SIZE_BITS); + return o == OWNER_TOWN ? OWNER_NONE : o; +} + /** * Set the owner of a specific road type. * @param t The tile to change. @@ -249,6 +265,21 @@ inline Owner GetRoadOwner(Tile t, RoadTramType rtt) * @param o New owner of the given road type. */ inline void SetRoadOwner(Tile t, RoadTramType rtt, Owner o) +{ + if (rtt == RTT_ROAD) { + SB(t.m9(), IsNormalRoadTile(t) ? 0 : COMPANY_SIZE_BITS * 2, COMPANY_SIZE_BITS, o); + } else { + SB(t.m9(), COMPANY_SIZE_BITS, COMPANY_SIZE_BITS, o==OWNER_NONE ? OWNER_TOWN : o); + } +} + +/** + * Set the owner of a specific road type. + * @param t The tile to change. + * @param rtt RoadTramType. + * @param o New owner of the given road type. + */ +inline void OldSetRoadOwner(Tile t, RoadTramType rtt, Owner o) { if (rtt == RTT_ROAD) { SB(IsNormalRoadTile(t) ? t.m1() : t.m7(), 0, 5, o); diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index b8ddf0258d..e092960f66 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -451,7 +451,7 @@ static void FixOwnerOfRailTrack(Tile t) if (IsLevelCrossingTile(t)) { /* else change the crossing to normal road (road vehicles won't care) */ - Owner road = GetRoadOwner(t, RTT_ROAD); + Owner road = GetRoadOwner(t, RTT_ROAD); // TODO: m9 Owner tram = GetRoadOwner(t, RTT_TRAM); RoadBits bits = GetCrossingRoadBits(t); bool hasroad = HasBit(t.m7(), 6); diff --git a/src/saveload/cargomonitor_sl.cpp b/src/saveload/cargomonitor_sl.cpp index c932ea18d7..cdd166779b 100644 --- a/src/saveload/cargomonitor_sl.cpp +++ b/src/saveload/cargomonitor_sl.cpp @@ -24,7 +24,7 @@ struct TempStorage { /** Description of the #TempStorage structure for the purpose of load and save. */ static const SaveLoad _cargomonitor_pair_desc[] = { - SLE_VAR(TempStorage, number, SLE_UINT32), + SLE_VAR(TempStorage, number, SLE_UINT64), SLE_VAR(TempStorage, amount, SLE_UINT32), }; diff --git a/src/saveload/company_sl.cpp b/src/saveload/company_sl.cpp index 651daa1bcb..a4e5a35e7b 100644 --- a/src/saveload/company_sl.cpp +++ b/src/saveload/company_sl.cpp @@ -476,8 +476,8 @@ static const SaveLoad _company_desc[] = { SLE_CONDVAR(CompanyProperties, num_valid_stat_ent, SLE_UINT8, SL_MIN_VERSION, SLV_SAVELOAD_LIST_LENGTH), SLE_VAR(CompanyProperties, months_of_bankruptcy, SLE_UINT8), - SLE_CONDVAR(CompanyProperties, bankrupt_asked, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104), - SLE_CONDVAR(CompanyProperties, bankrupt_asked, SLE_UINT16, SLV_104, SL_MAX_VERSION), + // MYTODO: Fix all the compat issues + SLE_CONDCOMPMASK(CompanyProperties, bankrupt_asked, SLE_UINT8, COMPANY_SIZE_BITS, SLV_179, SL_MAX_VERSION), SLE_VAR(CompanyProperties, bankrupt_timeout, SLE_INT16), SLE_CONDVAR(CompanyProperties, bankrupt_value, SLE_VAR_I64 | SLE_FILE_I32, SL_MIN_VERSION, SLV_65), SLE_CONDVAR(CompanyProperties, bankrupt_value, SLE_INT64, SLV_65, SL_MAX_VERSION), diff --git a/src/saveload/engine_sl.cpp b/src/saveload/engine_sl.cpp index ab62d756a8..599803f74d 100644 --- a/src/saveload/engine_sl.cpp +++ b/src/saveload/engine_sl.cpp @@ -9,6 +9,7 @@ #include "../stdafx.h" +#include "company_type.h" #include "saveload.h" #include "compat/engine_sl_compat.h" @@ -32,12 +33,11 @@ static const SaveLoad _engine_desc[] = { SLE_VAR(Engine, duration_phase_2, SLE_UINT16), SLE_VAR(Engine, duration_phase_3, SLE_UINT16), SLE_VAR(Engine, flags, SLE_UINT8), - SLE_CONDVAR(Engine, preview_asked, SLE_UINT16, SLV_179, SL_MAX_VERSION), + SLE_CONDCOMPMASK(Engine, preview_asked, SLE_UINT8, COMPANY_SIZE_BITS, SLV_179, SL_MAX_VERSION), SLE_CONDVAR(Engine, preview_company, SLE_UINT8, SLV_179, SL_MAX_VERSION), - SLE_VAR(Engine, preview_wait, SLE_UINT8), - SLE_CONDVAR(Engine, company_avail, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104), - SLE_CONDVAR(Engine, company_avail, SLE_UINT16, SLV_104, SL_MAX_VERSION), - SLE_CONDVAR(Engine, company_hidden, SLE_UINT16, SLV_193, SL_MAX_VERSION), + SLE_VAR(Engine, preview_wait, SLE_UINT8), +// MYTODO: Fix all the compatibility here + SLE_CONDCOMPMASK(Engine, company_avail, SLE_UINT8, COMPANY_SIZE_BITS, SLV_179, SL_MAX_VERSION), SLE_CONDSSTR(Engine, name, SLE_STR, SLV_84, SL_MAX_VERSION), }; diff --git a/src/saveload/map_sl.cpp b/src/saveload/map_sl.cpp index 3ce23a42b2..8054753908 100644 --- a/src/saveload/map_sl.cpp +++ b/src/saveload/map_sl.cpp @@ -352,6 +352,33 @@ struct MAP8ChunkHandler : ChunkHandler { } }; +struct MAP9ChunkHandler : ChunkHandler { + MAP9ChunkHandler() : ChunkHandler('MAP9', CH_RIFF) {} + + void Load() const override + { + std::array buf; + uint size = Map::Size(); + + for (TileIndex i = 0; i != size;) { + SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT32); + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) Tile(i++).m8() = buf[j]; + } + } + + void Save() const override + { + std::array buf; + uint size = Map::Size(); + + SlSetLength(static_cast(size) * sizeof(uint32_t)); + for (TileIndex i = 0; i != size;) { + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = Tile(i++).m8(); + SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT32); + } + } +}; + static const MAPSChunkHandler MAPS; static const MAPTChunkHandler MAPT; static const MAPHChunkHandler MAPH; @@ -363,6 +390,7 @@ static const MAP5ChunkHandler MAP5; static const MAPEChunkHandler MAPE; static const MAP7ChunkHandler MAP7; static const MAP8ChunkHandler MAP8; +static const MAP8ChunkHandler MAP9; static const ChunkHandlerRef map_chunk_handlers[] = { MAPS, MAPT, @@ -375,6 +403,7 @@ static const ChunkHandlerRef map_chunk_handlers[] = { MAPE, MAP7, MAP8, + MAP9, }; extern const ChunkHandlerTable _map_chunk_handlers(map_chunk_handlers); diff --git a/src/saveload/oldloader_sl.cpp b/src/saveload/oldloader_sl.cpp index 538c1336c3..9985bccb57 100644 --- a/src/saveload/oldloader_sl.cpp +++ b/src/saveload/oldloader_sl.cpp @@ -253,6 +253,7 @@ static bool FixTTOMapArray() break; case 1: // ROAD_TILE_CROSSING (there aren't monorail crossings in TTO) tile.m3() = tile.m1(); // set owner of road = owner of rail + // TODO: Fix this break; case 2: // ROAD_TILE_DEPOT break; diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index ded1a83467..f00380b83f 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -20,6 +20,7 @@ * */ +#include "saveload/saveload.h" #include "../stdafx.h" #include "../debug.h" #include "../station_base.h" @@ -42,7 +43,11 @@ #include "../string_func.h" #include "../fios.h" #include "../error.h" +#include "company_type.h" #include +#include +#include +#include #ifdef __EMSCRIPTEN__ # include #endif @@ -1105,6 +1110,76 @@ static void SlArray(void *array, size_t length, VarType conv) } } + + +// MYTODO: Put this somewhere it belongs +std::vector bitset_to_bytes(const CompanyMask& bs) +{ + int N = COMPANY_SIZE_BITS; + std::vector result((N + 7) >> 3); + for (int j=0; j>3] |= (bs[j] << (j & 7)); + return result; +} + +CompanyMask bitset_from_bytes(const std::vector& buf) +{ + size_t N = COMPANY_SIZE_BITS; + assert(buf.size() == ((N + 7) >> 3)); + CompanyMask result; + for (int j=0; j>3] >> (j & 7)) & 1); + return result; +} + + + +/** + * Save/Load the length of the bitset followed by the array of SL_VAR bits. + * @param array The array being manipulated + * @param length The length of the bitset in bytes, + */ +static void SlCompanyMask(void *array, size_t length, VarType conv) +{ + switch (_sl.action) { + case SLA_SAVE: { + CompanyMask *bs = static_cast(array); + // We don't save the number of bits in the company mask, + // because it's incompatible with other versions anyway + std::vector bytes = bitset_to_bytes(*bs); + uint8_t *bytes_arr = &bytes[0]; + + SlWriteArrayLength(bytes.size()); + SlArray(bytes_arr, bytes.size(), conv); + + return; + } + + case SLA_LOAD_CHECK: + case SLA_LOAD: { + + std::vector buff(length); + + SlArray(&buff[0], length, conv); + + CompanyMask res = bitset_from_bytes(buff); + CompanyMask *bs = static_cast(array); + for (int i = 0; i < COMPANY_SIZE_BITS; i++) { + (*bs)[i] = res[i]; + } + + return; + } + + case SLA_PTRS: + case SLA_NULL: + return; + + default: + NOT_REACHED(); + } +} + /** * Pointers cannot be saved to a savegame, so this functions gets * the index of the item, and if not available, it hussles with @@ -1513,6 +1588,7 @@ size_t SlCalcObjMemberLength(const void *object, const SaveLoad &sld) case SL_VAR: return SlCalcConvFileLen(sld.conv); case SL_REF: return SlCalcRefLen(); case SL_ARR: return SlCalcArrayLen(sld.length, sld.conv); + case SL_COMPANY_MASK: return SlCalcArrayLen(sld.length, sld.conv); case SL_REFLIST: return SlCalcRefListLen(GetVariableAddress(object, sld), sld.conv); case SL_DEQUE: return SlCalcDequeLen(GetVariableAddress(object, sld), sld.conv); case SL_VECTOR: return SlCalcVectorLen(GetVariableAddress(object, sld), sld.conv); @@ -1568,6 +1644,7 @@ static bool SlObjectMember(void *object, const SaveLoad &sld) case SL_VAR: SlSaveLoadConv(ptr, conv); break; case SL_REF: SlSaveLoadRef(ptr, conv); break; case SL_ARR: SlArray(ptr, sld.length, conv); break; + case SL_COMPANY_MASK: SlCompanyMask(ptr, sld.length, conv); break; case SL_REFLIST: SlRefList(ptr, conv); break; case SL_DEQUE: SlDeque(ptr, conv); break; case SL_VECTOR: SlVector(ptr, conv); break; diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index 99f74777bf..f9b8b06905 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -690,9 +690,10 @@ enum SaveLoadType : uint8_t { SL_VECTOR = 7, ///< Save/load a vector of #SL_VAR elements. SL_REFLIST = 8, ///< Save/load a list of #SL_REF elements. SL_STRUCTLIST = 9, ///< Save/load a list of structs. + SL_COMPANY_MASK = 10, ///< Save/load a fixed-size bitset of #SL_VAR bits. - SL_SAVEBYTE = 10, ///< Save (but not load) a byte. - SL_NULL = 11, ///< Save null-bytes and load to nowhere. + SL_SAVEBYTE = 11, ///< Save (but not load) a byte. + SL_NULL = 12, ///< Save null-bytes and load to nowhere. }; typedef void *SaveLoadAddrProc(void *base, size_t extra); @@ -799,6 +800,7 @@ inline constexpr bool SlCheckVarSize(SaveLoadType cmd, VarType type, size_t leng case SL_REF: return sizeof(void *) == size; case SL_STDSTR: return SlVarSize(type) == size; case SL_ARR: return SlVarSize(type) * length <= size; // Partial load of array is permitted. + case SL_COMPANY_MASK: return SlVarSize(type) * length <= size; // Partial load of array is permitted. case SL_DEQUE: return sizeof(std::deque) == size; case SL_VECTOR: return sizeof(std::vector) == size; case SL_REFLIST: return sizeof(std::list) == size; @@ -1001,6 +1003,17 @@ inline constexpr bool SlCheckVarSize(SaveLoadType cmd, VarType type, size_t leng */ #define SLE_ARRNAME(base, variable, name, type, length) SLE_CONDARRNAME(base, variable, name, type, length, SL_MIN_VERSION, SL_MAX_VERSION) +/** + * Storage of a fixed-size array of #SL_VAR elements in some savegame versions. + * @param base Name of the class or struct containing the array. + * @param variable Name of the variable in the class or struct referenced by \a base. + * @param type Storage of the data in memory and in the savegame. + * @param length Number of elements in the array. + * @param from First savegame version that has the array. + * @param to Last savegame version that has the array. + */ +#define SLE_CONDCOMPMASK(base, variable, type, length, from, to) SLE_GENERAL(SL_COMPANY_MASK, base, variable, type, length, from, to, 0) + /** * Storage of a \c std::string in every savegame version. * @param base Name of the class or struct containing the string. diff --git a/src/saveload/town_sl.cpp b/src/saveload/town_sl.cpp index e09bf9d444..2dc3c1162c 100644 --- a/src/saveload/town_sl.cpp +++ b/src/saveload/town_sl.cpp @@ -215,11 +215,11 @@ static const SaveLoad _town_desc[] = { SLE_CONDSSTR(Town, name, SLE_STR | SLF_ALLOW_CONTROL, SLV_84, SL_MAX_VERSION), SLE_VAR(Town, flags, SLE_UINT8), - SLE_CONDVAR(Town, statues, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104), - SLE_CONDVAR(Town, statues, SLE_UINT16, SLV_104, SL_MAX_VERSION), + // MYTODO: Fix all the compat +SLE_CONDCOMPMASK(Town, statues, SLE_UINT8, COMPANY_SIZE_BITS, SLV_179, SL_MAX_VERSION), - SLE_CONDVAR(Town, have_ratings, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104), - SLE_CONDVAR(Town, have_ratings, SLE_UINT16, SLV_104, SL_MAX_VERSION), + // MYTODO: Fix all the compat +SLE_CONDCOMPMASK(Town, have_ratings, SLE_UINT8, COMPANY_SIZE_BITS, SLV_179, SL_MAX_VERSION), SLE_CONDARR(Town, ratings, SLE_INT16, 8, SL_MIN_VERSION, SLV_104), SLE_CONDARR(Town, ratings, SLE_INT16, MAX_COMPANIES, SLV_104, SL_MAX_VERSION), SLE_CONDARR(Town, unwanted, SLE_INT8, 8, SLV_4, SLV_104), diff --git a/src/tile_map.h b/src/tile_map.h index 6fbb3a53fa..032d75f6d7 100644 --- a/src/tile_map.h +++ b/src/tile_map.h @@ -10,6 +10,7 @@ #ifndef TILE_MAP_H #define TILE_MAP_H +#include "company_type.h" #include "slope_type.h" #include "map_func.h" #include "core/bitmath_func.hpp" @@ -181,6 +182,27 @@ inline Owner GetTileOwner(Tile tile) assert(!IsTileType(tile, MP_HOUSE)); assert(!IsTileType(tile, MP_INDUSTRY)); + return (Owner)GB(tile.m9(), 0, COMPANY_SIZE_BITS); +} + +/** + * Returns the owner of a tile. Only used for legacy code + * + * This function returns the owner of a tile. This cannot used + * for tiles which type is one of MP_HOUSE, MP_VOID and MP_INDUSTRY + * as no company owned any of these buildings. + * + * @param tile The tile to check + * @return The owner of the tile + * @pre IsValidTile(tile) + * @pre The type of the tile must not be MP_HOUSE and MP_INDUSTRY + */ +inline Owner OldGetTileOwner(Tile tile) +{ + assert(IsValidTile(tile)); + assert(!IsTileType(tile, MP_HOUSE)); + assert(!IsTileType(tile, MP_INDUSTRY)); + return (Owner)GB(tile.m1(), 0, 5); } @@ -201,9 +223,30 @@ inline void SetTileOwner(Tile tile, Owner owner) assert(!IsTileType(tile, MP_HOUSE)); assert(!IsTileType(tile, MP_INDUSTRY)); + SB(tile.m9(), 0, COMPANY_SIZE_BITS, owner); +} + +/** + * Sets the owner of a tile (Only for old formats) + * + * This function sets the owner status of a tile. Note that you cannot + * set a owner for tiles of type MP_HOUSE, MP_VOID and MP_INDUSTRY. + * + * @param tile The tile to change the owner status. + * @param owner The new owner. + * @pre IsValidTile(tile) + * @pre The type of the tile must not be MP_HOUSE and MP_INDUSTRY + */ +inline void OldSetTileOwner(Tile tile, Owner owner) +{ + assert(IsValidTile(tile)); + assert(!IsTileType(tile, MP_HOUSE)); + assert(!IsTileType(tile, MP_INDUSTRY)); + SB(tile.m1(), 0, 5, owner); } + /** * Checks if a tile belongs to the given owner * diff --git a/src/void_map.h b/src/void_map.h index e8e031be79..ede9f19d77 100644 --- a/src/void_map.h +++ b/src/void_map.h @@ -27,6 +27,8 @@ inline void MakeVoid(Tile t) t.m5() = 0; t.m6() = 0; t.m7() = 0; + t.m8() = 0; + t.m9() = 0; } #endif /* VOID_MAP_H */ From 4f332d77ad81a9a585ce685c93535a4479a4c134 Mon Sep 17 00:00:00 2001 From: Andrii Dokhniak Date: Fri, 31 May 2024 22:22:16 +0200 Subject: [PATCH 3/9] small fixup --- src/saveload/saveload.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index f00380b83f..7e524cfa6e 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -576,6 +576,7 @@ static uint8_t GetSavegameFileType(const SaveLoad &sld) case SL_STDSTR: case SL_ARR: case SL_VECTOR: + case SL_COMPANY_MASK: case SL_DEQUE: return GetVarFileType(sld.conv) | SLE_FILE_HAS_LENGTH_FIELD; break; @@ -1637,6 +1638,7 @@ static bool SlObjectMember(void *object, const SaveLoad &sld) case SL_REFLIST: case SL_DEQUE: case SL_VECTOR: + case SL_COMPANY_MASK: case SL_STDSTR: { void *ptr = GetVariableAddress(object, sld); From 924c14b84990c3ddedb1a9a7ff0ed9af18839696 Mon Sep 17 00:00:00 2001 From: Andrii Dokhniak Date: Sun, 2 Jun 2024 21:33:42 +0200 Subject: [PATCH 4/9] Finally POC --- .gitignore | 1 + media/baseset/opntitle_testing.dat | Bin 0 -> 31732 bytes src/company_base.h | 1 + src/engine_base.h | 9 ++++ src/saveload/afterload.cpp | 65 +++++++++++++++++------------ src/saveload/company_sl.cpp | 11 +++-- src/saveload/engine_sl.cpp | 49 ++++++++++++++-------- src/saveload/saveload.cpp | 51 +++++++++++----------- src/saveload/saveload.h | 12 +++--- src/saveload/town_sl.cpp | 15 +++++-- src/town.h | 3 ++ 11 files changed, 135 insertions(+), 82 deletions(-) create mode 100644 media/baseset/opntitle_testing.dat diff --git a/.gitignore b/.gitignore index 3d0376aa94..38765312bb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /.vs +/.cache/* /build* CMakeSettings.json docs/aidocs/* diff --git a/media/baseset/opntitle_testing.dat b/media/baseset/opntitle_testing.dat new file mode 100644 index 0000000000000000000000000000000000000000..b43b3f6cd3c46d01198be0b25580dc2595f5227d GIT binary patch literal 31732 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 b00GDM0pj@(r(eJSJ}?c70ssI200CKAdH29D literal 0 HcmV?d00001 diff --git a/src/company_base.h b/src/company_base.h index 814665777b..8173fdda4e 100644 --- a/src/company_base.h +++ b/src/company_base.h @@ -96,6 +96,7 @@ struct CompanyProperties { uint8_t months_empty = 0; ///< NOSAVE: Number of months this company has not had a client in multiplayer. uint8_t months_of_bankruptcy; ///< Number of months that the company is unable to pay its debts CompanyMask bankrupt_asked; ///< which companies were asked about buying it? + uint16_t old_bankrupt_asked; int16_t bankrupt_timeout; ///< If bigger than \c 0, amount of time to wait for an answer on an offer to buy this company. Money bankrupt_value; diff --git a/src/engine_base.h b/src/engine_base.h index de552bd9a7..4f545a7bd3 100644 --- a/src/engine_base.h +++ b/src/engine_base.h @@ -15,6 +15,7 @@ #include "core/pool_type.hpp" #include "newgrf_commons.h" #include "timer/timer_game_calendar.h" +#include struct WagonOverride { std::vector engines; @@ -47,11 +48,19 @@ struct Engine : EnginePool::PoolItem<&_engine_pool> { uint16_t duration_phase_2; ///< Second reliability phase in months, keeping #reliability_max. uint16_t duration_phase_3; ///< Third reliability phase in months, decaying to #reliability_final. uint8_t flags; ///< Flags of the engine. @see EngineFlags + CompanyMask preview_asked; ///< Bit for each company which has already been offered a preview. + uint16_t old_preview_asked; + CompanyID preview_company; ///< Company which is currently being offered a preview \c INVALID_COMPANY means no company. uint8_t preview_wait; ///< Daily countdown timer for timeout of offering the engine to the #preview_company company. + CompanyMask company_avail; ///< Bit for each company whether the engine is available for that company. + uint16_t old_company_avail; + CompanyMask company_hidden; ///< Bit for each company whether the engine is normally hidden in the build gui for that company. + uint16_t old_company_hidden; + uint8_t original_image_index; ///< Original vehicle image index, thus the image index of the overridden vehicle VehicleType type; ///< %Vehicle type, ie #VEH_ROAD, #VEH_TRAIN, etc. diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index e092960f66..bf1d2c1486 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -63,11 +63,14 @@ #include "../timer/timer_game_economy.h" #include "../timer/timer_game_tick.h" +#include "saveload/saveload.h" #include "saveload_internal.h" #include #include "../safeguards.h" +#include "tile_map.h" +#include "tile_type.h" extern Company *DoStartupNewCompany(bool is_ai, CompanyID company = INVALID_COMPANY); @@ -163,7 +166,7 @@ static void ConvertTownOwner() [[fallthrough]]; case MP_TUNNELBRIDGE: - if (tile.m1() & 0x80) SetTileOwner(tile, OWNER_TOWN); + if (tile.m1() & 0x80) OldSetTileOwner(tile, OWNER_TOWN); break; default: break; @@ -421,7 +424,7 @@ static void CDECL HandleSavegameLoadCrash(int signum) */ static void FixOwnerOfRailTrack(Tile t) { - assert(!Company::IsValidID(GetTileOwner(t)) && (IsLevelCrossingTile(t) || IsPlainRailTile(t))); + assert(!Company::IsValidID(OldGetTileOwner(t)) && (IsLevelCrossingTile(t) || IsPlainRailTile(t))); /* remove leftover rail piece from crossing (from very old savegames) */ Train *v = nullptr; @@ -434,7 +437,7 @@ static void FixOwnerOfRailTrack(Tile t) if (v != nullptr) { /* when there is a train on crossing (it could happen in TTD), set owner of crossing to train owner */ - SetTileOwner(t, v->owner); + OldSetTileOwner(t, v->owner); return; } @@ -443,15 +446,15 @@ static void FixOwnerOfRailTrack(Tile t) TileIndex tt = t + TileOffsByDiagDir(dd); if (GetTileTrackStatus(t, TRANSPORT_RAIL, 0, dd) != 0 && GetTileTrackStatus(tt, TRANSPORT_RAIL, 0, ReverseDiagDir(dd)) != 0 && - Company::IsValidID(GetTileOwner(tt))) { - SetTileOwner(t, GetTileOwner(tt)); + Company::IsValidID(OldGetTileOwner(tt))) { + OldSetTileOwner(t, OldGetTileOwner(tt)); return; } } if (IsLevelCrossingTile(t)) { /* else change the crossing to normal road (road vehicles won't care) */ - Owner road = GetRoadOwner(t, RTT_ROAD); // TODO: m9 + Owner road = GetRoadOwner(t, RTT_ROAD); Owner tram = GetRoadOwner(t, RTT_TRAM); RoadBits bits = GetCrossingRoadBits(t); bool hasroad = HasBit(t.m7(), 6); @@ -459,7 +462,7 @@ static void FixOwnerOfRailTrack(Tile t) /* MakeRoadNormal */ SetTileType(t, MP_ROAD); - SetTileOwner(t, road); + OldSetTileOwner(t, road); t.m3() = (hasroad ? bits : 0); t.m5() = (hastram ? bits : 0) | ROAD_TILE_NORMAL << 6; SB(t.m6(), 2, 4, 0); @@ -471,6 +474,7 @@ static void FixOwnerOfRailTrack(Tile t) MakeClear(t, CLEAR_GRASS, 0); } + /** * Fixes inclination of a vehicle. Older OpenTTD versions didn't update the bits correctly. * @param v vehicle @@ -656,8 +660,8 @@ bool AfterLoadGame() * walk through the whole map.. */ if (IsSavegameVersionBefore(SLV_4, 3)) { for (auto t : Map::Iterate()) { - if (IsTileType(t, MP_WATER) && GetTileOwner(t) >= OLD_MAX_COMPANIES) { - SetTileOwner(t, OWNER_WATER); + if (IsTileType(t, MP_WATER) && OldGetTileOwner(t) >= OLD_MAX_COMPANIES) { + OldSetTileOwner(t, OWNER_WATER); } } } @@ -858,7 +862,7 @@ bool AfterLoadGame() default: break; case MP_WATER: - if (GetWaterTileType(t) == WATER_TILE_LOCK && GetTileOwner(t) == OWNER_WATER) SetTileOwner(t, OWNER_NONE); + if (GetWaterTileType(t) == WATER_TILE_LOCK && OldGetTileOwner(t) == OWNER_WATER) OldSetTileOwner(t, OWNER_NONE); break; case MP_STATION: { @@ -913,7 +917,7 @@ bool AfterLoadGame() BaseStation *bst = BaseStation::GetByTile(t); /* Sanity check */ - if (!IsBuoy(t) && bst->owner != GetTileOwner(t)) SlErrorCorrupt("Wrong owner for station tile"); + if (!IsBuoy(t) && bst->owner != OldGetTileOwner(t)) SlErrorCorrupt("Wrong owner for station tile"); /* Set up station spread */ bst->rect.BeforeAddTile(t, StationRect::ADD_FORCE); @@ -986,7 +990,7 @@ bool AfterLoadGame() case MP_ROAD: t.m4() |= (t.m2() << 4); - if ((GB(t.m5(), 4, 2) == ROAD_TILE_CROSSING ? (Owner)t.m3() : GetTileOwner(t)) == OLD_OWNER_TOWN) { + if ((GB(t.m5(), 4, 2) == ROAD_TILE_CROSSING ? (Owner)t.m3() : OldGetTileOwner(t)) == OLD_OWNER_TOWN) { SetTownIndex(t, CalcClosestTownFromTile(t)->index); } else { SetTownIndex(t, 0); @@ -1139,7 +1143,7 @@ bool AfterLoadGame() if (!IsRoadStop(t)) break; if (fix_roadtypes) SB(t.m7(), 6, 2, (RoadTypes)GB(t.m3(), 0, 3)); - SB(t.m7(), 0, 5, HasBit(t.m6(), 2) ? OWNER_TOWN : GetTileOwner(t)); + SB(t.m7(), 0, 5, HasBit(t.m6(), 2) ? OWNER_TOWN : OldGetTileOwner(t)); SB(t.m3(), 4, 4, t.m1()); t.m4() = 0; break; @@ -1149,7 +1153,7 @@ bool AfterLoadGame() if (((old_bridge && IsBridge(t)) ? (TransportType)GB(t.m5(), 1, 2) : GetTunnelBridgeTransportType(t)) == TRANSPORT_ROAD) { if (fix_roadtypes) SB(t.m7(), 6, 2, (RoadTypes)GB(t.m3(), 0, 3)); - Owner o = GetTileOwner(t); + Owner o = OldGetTileOwner(t); SB(t.m7(), 0, 5, o); // road owner SB(t.m3(), 4, 4, o == OLD_OWNER_NONE ? OWNER_TOWN : o); // tram owner } @@ -1208,7 +1212,7 @@ bool AfterLoadGame() if (GB(t.m5(), 3, 2) == TRANSPORT_RAIL) { MakeRailNormal( t, - GetTileOwner(t), + OldGetTileOwner(t), axis == AXIS_X ? TRACK_BIT_Y : TRACK_BIT_X, GetRailType(t) ); @@ -1231,10 +1235,10 @@ bool AfterLoadGame() if (!IsTileFlat(t)) { MakeShore(t); } else { - if (GetTileOwner(t) == OWNER_WATER) { + if (OldGetTileOwner(t) == OWNER_WATER) { MakeSea(t); } else { - MakeCanal(t, GetTileOwner(t), Random()); + MakeCanal(t, OldGetTileOwner(t), Random()); } } } @@ -1568,7 +1572,7 @@ bool AfterLoadGame() * be OWNER_NONE. So replace OWNER_NONE with OWNER_WATER. */ if (IsSavegameVersionBefore(SLV_46)) { for (Waypoint *wp : Waypoint::Iterate()) { - if ((wp->facilities & FACIL_DOCK) != 0 && IsTileOwner(wp->xy, OLD_OWNER_NONE) && TileHeight(wp->xy) == 0) SetTileOwner(wp->xy, OWNER_WATER); + if ((wp->facilities & FACIL_DOCK) != 0 && IsTileOwner(wp->xy, OLD_OWNER_NONE) && TileHeight(wp->xy) == 0) OldSetTileOwner(wp->xy, OWNER_WATER); } } @@ -1678,9 +1682,9 @@ bool AfterLoadGame() for (auto t : Map::Iterate()) { if (IsTileType(t, MP_WATER) && GetWaterTileType(t) == WATER_TILE_CLEAR && - GetTileOwner(t) == OWNER_WATER && + OldGetTileOwner(t) == OWNER_WATER && TileHeight(t) != 0) { - SetTileOwner(t, OWNER_NONE); + OldSetTileOwner(t, OWNER_NONE); } } } @@ -1828,7 +1832,7 @@ bool AfterLoadGame() if (IsTileType(t, MP_WATER)) { if (GetWaterClass(t) != WATER_CLASS_RIVER) { if (IsWater(t)) { - Owner o = GetTileOwner(t); + Owner o = OldGetTileOwner(t); if (o == OWNER_WATER) { MakeSea(t); } else { @@ -1864,7 +1868,7 @@ bool AfterLoadGame() } if (IsBuoyTile(t) || IsDriveThroughStopTile(t) || IsTileType(t, MP_WATER)) { - Owner o = GetTileOwner(t); + Owner o = OldGetTileOwner(t); if (o < OLD_MAX_COMPANIES && !Company::IsValidID(o)) { Backup cur_company(_current_company, o); ChangeTileOwner(t, o, INVALID_OWNER); @@ -1883,10 +1887,10 @@ bool AfterLoadGame() if (o < OLD_MAX_COMPANIES && !Company::IsValidID(o)) SetRoadOwner(t, rtt, OWNER_NONE); } if (IsLevelCrossing(t)) { - if (!Company::IsValidID(GetTileOwner(t))) FixOwnerOfRailTrack(t); + if (!Company::IsValidID(OldGetTileOwner(t))) FixOwnerOfRailTrack(t); } } else if (IsPlainRailTile(t)) { - if (!Company::IsValidID(GetTileOwner(t))) FixOwnerOfRailTrack(t); + if (!Company::IsValidID(OldGetTileOwner(t))) FixOwnerOfRailTrack(t); } } } @@ -2473,7 +2477,7 @@ bool AfterLoadGame() /* Add (random) colour to all objects. */ if (IsSavegameVersionBefore(SLV_148)) { for (Object *o : Object::Iterate()) { - Owner owner = GetTileOwner(o->location.tile); + Owner owner = OldGetTileOwner(o->location.tile); o->colour = (owner == OLD_OWNER_NONE) ? static_cast(GB(Random(), 0, 4)) : Company::Get(owner)->livery->colour1; } } @@ -2841,7 +2845,7 @@ bool AfterLoadGame() if (IsSavegameVersionBefore(SLV_172)) { for (auto t : Map::Iterate()) { if (!IsBayRoadStopTile(t)) continue; - Owner o = GetTileOwner(t); + Owner o = OldGetTileOwner(t); SetRoadOwner(t, RTT_ROAD, o); SetRoadOwner(t, RTT_TRAM, o); } @@ -3262,6 +3266,15 @@ bool AfterLoadGame() if (IsSavegameVersionBefore(SLV_SCRIPT_RANDOMIZER)) { ScriptObject::InitializeRandomizers(); } + if (IsSavegameVersionBefore(SLV_MORE_COMPANIES)) { + for (auto t : Map::Iterate()) { + if (IsValidTile(t) + && !IsTileType(t, MP_HOUSE) + && !IsTileType(t, MP_INDUSTRY)) { + SetTileOwner(t, OldGetTileOwner(t)); + } + } + } for (Company *c : Company::Iterate()) { UpdateCompanyLiveries(c); diff --git a/src/saveload/company_sl.cpp b/src/saveload/company_sl.cpp index a4e5a35e7b..e56a674b40 100644 --- a/src/saveload/company_sl.cpp +++ b/src/saveload/company_sl.cpp @@ -475,9 +475,11 @@ static const SaveLoad _company_desc[] = { SLE_CONDVAR(CompanyProperties, num_valid_stat_ent, SLE_UINT8, SL_MIN_VERSION, SLV_SAVELOAD_LIST_LENGTH), - SLE_VAR(CompanyProperties, months_of_bankruptcy, SLE_UINT8), - // MYTODO: Fix all the compat issues - SLE_CONDCOMPMASK(CompanyProperties, bankrupt_asked, SLE_UINT8, COMPANY_SIZE_BITS, SLV_179, SL_MAX_VERSION), + SLE_VAR(CompanyProperties, months_of_bankruptcy, SLE_UINT8), +SLE_CONDVARNAME(CompanyProperties, old_bankrupt_asked, "bankrupt_asked", SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104), +SLE_CONDVARNAME(CompanyProperties, old_bankrupt_asked, "bankrupt_asked", SLE_UINT16, SLV_104, SLV_MORE_COMPANIES), +SLE_CONDCOMPMASK(CompanyProperties, bankrupt_asked, MAX_COMPANIES, SLV_MORE_COMPANIES, SL_MAX_VERSION), + SLE_VAR(CompanyProperties, bankrupt_timeout, SLE_INT16), SLE_CONDVAR(CompanyProperties, bankrupt_value, SLE_VAR_I64 | SLE_FILE_I32, SL_MIN_VERSION, SLV_65), SLE_CONDVAR(CompanyProperties, bankrupt_value, SLE_INT64, SLV_65, SL_MAX_VERSION), @@ -520,6 +522,9 @@ struct PLYRChunkHandler : ChunkHandler { Company *c = new (index) Company(); SlObject(c, slt); _company_colours[index] = c->colour; + if (IsSavegameVersionBefore(SLV_MORE_COMPANIES)) { + c->bankrupt_asked = owner_from_int(c->old_bankrupt_asked); + } } } diff --git a/src/saveload/engine_sl.cpp b/src/saveload/engine_sl.cpp index 599803f74d..d6e78d6638 100644 --- a/src/saveload/engine_sl.cpp +++ b/src/saveload/engine_sl.cpp @@ -20,24 +20,32 @@ #include "../safeguards.h" static const SaveLoad _engine_desc[] = { - SLE_CONDVAR(Engine, intro_date, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31), - SLE_CONDVAR(Engine, intro_date, SLE_INT32, SLV_31, SL_MAX_VERSION), - SLE_CONDVAR(Engine, age, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31), - SLE_CONDVAR(Engine, age, SLE_INT32, SLV_31, SL_MAX_VERSION), - SLE_VAR(Engine, reliability, SLE_UINT16), - SLE_VAR(Engine, reliability_spd_dec, SLE_UINT16), - SLE_VAR(Engine, reliability_start, SLE_UINT16), - SLE_VAR(Engine, reliability_max, SLE_UINT16), - SLE_VAR(Engine, reliability_final, SLE_UINT16), - SLE_VAR(Engine, duration_phase_1, SLE_UINT16), - SLE_VAR(Engine, duration_phase_2, SLE_UINT16), - SLE_VAR(Engine, duration_phase_3, SLE_UINT16), - SLE_VAR(Engine, flags, SLE_UINT8), - SLE_CONDCOMPMASK(Engine, preview_asked, SLE_UINT8, COMPANY_SIZE_BITS, SLV_179, SL_MAX_VERSION), - SLE_CONDVAR(Engine, preview_company, SLE_UINT8, SLV_179, SL_MAX_VERSION), - SLE_VAR(Engine, preview_wait, SLE_UINT8), -// MYTODO: Fix all the compatibility here - SLE_CONDCOMPMASK(Engine, company_avail, SLE_UINT8, COMPANY_SIZE_BITS, SLV_179, SL_MAX_VERSION), + SLE_CONDVAR(Engine, intro_date, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31), + SLE_CONDVAR(Engine, intro_date, SLE_INT32, SLV_31, SL_MAX_VERSION), + SLE_CONDVAR(Engine, age, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31), + SLE_CONDVAR(Engine, age, SLE_INT32, SLV_31, SL_MAX_VERSION), + SLE_VAR(Engine, reliability, SLE_UINT16), + SLE_VAR(Engine, reliability_spd_dec, SLE_UINT16), + SLE_VAR(Engine, reliability_start, SLE_UINT16), + SLE_VAR(Engine, reliability_max, SLE_UINT16), + SLE_VAR(Engine, reliability_final, SLE_UINT16), + SLE_VAR(Engine, duration_phase_1, SLE_UINT16), + SLE_VAR(Engine, duration_phase_2, SLE_UINT16), + SLE_VAR(Engine, duration_phase_3, SLE_UINT16), + SLE_VAR(Engine, flags, SLE_UINT8), + + SLE_CONDVARNAME(Engine, old_preview_asked, "preview_asked", SLE_UINT16, SLV_179, SLV_MORE_COMPANIES), +SLE_CONDCOMPMASK(Engine, preview_asked, MAX_COMPANIES, SLV_MORE_COMPANIES, SL_MAX_VERSION), + + SLE_CONDVAR(Engine, preview_company, SLE_UINT8, SLV_179, SL_MAX_VERSION), + SLE_VAR(Engine, preview_wait, SLE_UINT8), + + SLE_CONDVARNAME(Engine, old_company_avail, "company_avail", SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104), + SLE_CONDVARNAME(Engine, old_company_avail, "company_avail", SLE_UINT16, SLV_104, SLV_MORE_COMPANIES), +SLE_CONDCOMPMASK(Engine, company_avail, MAX_COMPANIES, SLV_MORE_COMPANIES, SL_MAX_VERSION), + +SLE_CONDCOMPMASK(Engine, company_hidden, MAX_COMPANIES, SLV_MORE_COMPANIES, SL_MAX_VERSION), + SLE_CONDVARNAME(Engine, old_company_hidden, "company_hidden", SLE_UINT16, SLV_193, SLV_MORE_COMPANIES), SLE_CONDSSTR(Engine, name, SLE_STR, SLV_84, SL_MAX_VERSION), }; @@ -111,6 +119,11 @@ struct ENGNChunkHandler : ChunkHandler { e->preview_company = INVALID_COMPANY; e->preview_asked = MAX_UVALUE(CompanyMask); } + if (IsSavegameVersionBefore(SLV_MORE_COMPANIES)) { + e->preview_asked = owner_from_int(e->old_preview_asked); + e->company_avail = owner_from_int(e->old_company_avail); + e->company_hidden = owner_from_int(e->old_company_hidden); + } } } }; diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index 7e524cfa6e..d3c1a7f308 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -44,8 +44,10 @@ #include "../fios.h" #include "../error.h" #include "company_type.h" +#include "core/bitmath_func.hpp" #include #include +#include #include #include #ifdef __EMSCRIPTEN__ @@ -1114,61 +1116,56 @@ static void SlArray(void *array, size_t length, VarType conv) // MYTODO: Put this somewhere it belongs -std::vector bitset_to_bytes(const CompanyMask& bs) +std::vector bitset_to_bytes(const CompanyMask& mask) { - int N = COMPANY_SIZE_BITS; - std::vector result((N + 7) >> 3); - for (int j=0; j>3] |= (bs[j] << (j & 7)); + std::vector result((MAX_COMPANIES + 7) >> 3); + for (int j = 0; j < MAX_COMPANIES; j++) + result[j>>3] |= (mask[j] << (j & 7)); return result; } -CompanyMask bitset_from_bytes(const std::vector& buf) -{ - size_t N = COMPANY_SIZE_BITS; - assert(buf.size() == ((N + 7) >> 3)); +CompanyMask bitset_from_bytes(const std::vector& buf) { CompanyMask result; - for (int j=0; j>3] >> (j & 7)) & 1); return result; } +CompanyMask owner_from_int(uint16_t old_owner) { + CompanyMask result; + for (int i = 0; i < 16; i++) { + result[i] = GB(old_owner, i, 1) & 1; + } + return result; +} + /** * Save/Load the length of the bitset followed by the array of SL_VAR bits. * @param array The array being manipulated * @param length The length of the bitset in bytes, */ -static void SlCompanyMask(void *array, size_t length, VarType conv) +static void SlCompanyMask(void *array, size_t byte_length, VarType conv) { switch (_sl.action) { case SLA_SAVE: { CompanyMask *bs = static_cast(array); - // We don't save the number of bits in the company mask, - // because it's incompatible with other versions anyway std::vector bytes = bitset_to_bytes(*bs); uint8_t *bytes_arr = &bytes[0]; - - SlWriteArrayLength(bytes.size()); SlArray(bytes_arr, bytes.size(), conv); - return; } case SLA_LOAD_CHECK: case SLA_LOAD: { + assert(byte_length == (MAX_COMPANIES + 7) >> 3); - std::vector buff(length); + std::vector buff((MAX_COMPANIES + 7) >> 3); + SlArray(&buff[0], byte_length, conv); - SlArray(&buff[0], length, conv); - - CompanyMask res = bitset_from_bytes(buff); CompanyMask *bs = static_cast(array); - for (int i = 0; i < COMPANY_SIZE_BITS; i++) { - (*bs)[i] = res[i]; - } - + *bs = bitset_from_bytes(buff); // we don't want to write direc return; } @@ -2248,10 +2245,12 @@ static void SlLoadCheckChunks() const ChunkHandler *ch; for (id = SlReadUint32(); id != 0; id = SlReadUint32()) { - Debug(sl, 2, "Loading chunk {:c}{:c}{:c}{:c}", id >> 24, id >> 16, id >> 8, id); + Debug(sl, 2, "Loading chunk (for checking) {:c}{:c}{:c}{:c}", id >> 24, id >> 16, id >> 8, id); ch = SlFindChunkHandler(id); - if (ch == nullptr) SlErrorCorrupt("Unknown chunk type"); + if (ch == nullptr) { + SlErrorCorrupt("Unknown chunk type"); + } SlLoadCheckChunk(*ch); } } diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index f9b8b06905..28c128b0ed 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -381,6 +381,7 @@ enum SaveLoadVersion : uint16_t { SLV_COMPANY_ALLOW_LIST, ///< 335 PR#12337 Saving of list of client keys that are allowed to join this company. SLV_GROUP_NUMBERS, ///< 336 PR#12297 Add per-company group numbers. + SLV_MORE_COMPANIES, /// Added more companies MYTODO: Fix this comment SL_MAX_VERSION, ///< Highest possible saveload version }; @@ -1003,16 +1004,16 @@ inline constexpr bool SlCheckVarSize(SaveLoadType cmd, VarType type, size_t leng */ #define SLE_ARRNAME(base, variable, name, type, length) SLE_CONDARRNAME(base, variable, name, type, length, SL_MIN_VERSION, SL_MAX_VERSION) + /** - * Storage of a fixed-size array of #SL_VAR elements in some savegame versions. - * @param base Name of the class or struct containing the array. + * Storage of a company mask bitset of #MAX_COMPANIES bits in some savegame versions. + * @param base Name of the class or struct containing the company mask. * @param variable Name of the variable in the class or struct referenced by \a base. - * @param type Storage of the data in memory and in the savegame. - * @param length Number of elements in the array. + * @param bit_length Number of bits in the serialized form. * @param from First savegame version that has the array. * @param to Last savegame version that has the array. */ -#define SLE_CONDCOMPMASK(base, variable, type, length, from, to) SLE_GENERAL(SL_COMPANY_MASK, base, variable, type, length, from, to, 0) +#define SLE_CONDCOMPMASK(base, variable, bit_length, from, to) SLE_GENERAL(SL_COMPANY_MASK, base, variable, SLE_CHAR, (bit_length + 7) >> 3, from, to, 0) /** * Storage of a \c std::string in every savegame version. @@ -1313,6 +1314,7 @@ void SlCopy(void *object, size_t length, VarType conv); std::vector SlTableHeader(const SaveLoadTable &slt); std::vector SlCompatTableHeader(const SaveLoadTable &slt, const SaveLoadCompatTable &slct); void SlObject(void *object, const SaveLoadTable &slt); +CompanyMask owner_from_int(uint16_t old_owner); bool SaveloadCrashWithMissingNewGRFs(); diff --git a/src/saveload/town_sl.cpp b/src/saveload/town_sl.cpp index 2dc3c1162c..ea024634f7 100644 --- a/src/saveload/town_sl.cpp +++ b/src/saveload/town_sl.cpp @@ -215,11 +215,14 @@ static const SaveLoad _town_desc[] = { SLE_CONDSSTR(Town, name, SLE_STR | SLF_ALLOW_CONTROL, SLV_84, SL_MAX_VERSION), SLE_VAR(Town, flags, SLE_UINT8), - // MYTODO: Fix all the compat -SLE_CONDCOMPMASK(Town, statues, SLE_UINT8, COMPANY_SIZE_BITS, SLV_179, SL_MAX_VERSION), +SLE_CONDVARNAME(Town, old_statues, "statues", SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104), +SLE_CONDVARNAME(Town, old_statues, "statues", SLE_UINT16, SLV_104, SLV_MORE_COMPANIES), +SLE_CONDCOMPMASK(Town, statues, MAX_COMPANIES, SLV_MORE_COMPANIES, SL_MAX_VERSION), + +SLE_CONDCOMPMASK(Town, have_ratings, MAX_COMPANIES, SLV_MORE_COMPANIES, SL_MAX_VERSION), +SLE_CONDVARNAME(Town, old_have_ratings, "have_ratings", SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104), +SLE_CONDVARNAME(Town, old_have_ratings, "have_ratings", SLE_UINT16, SLV_104, SLV_MORE_COMPANIES), - // MYTODO: Fix all the compat -SLE_CONDCOMPMASK(Town, have_ratings, SLE_UINT8, COMPANY_SIZE_BITS, SLV_179, SL_MAX_VERSION), SLE_CONDARR(Town, ratings, SLE_INT16, 8, SL_MIN_VERSION, SLV_104), SLE_CONDARR(Town, ratings, SLE_INT16, MAX_COMPANIES, SLV_104, SL_MAX_VERSION), SLE_CONDARR(Town, unwanted, SLE_INT8, 8, SLV_4, SLV_104), @@ -306,6 +309,10 @@ struct CITYChunkHandler : ChunkHandler { if (t->townnamegrfid == 0 && !IsInsideMM(t->townnametype, SPECSTR_TOWNNAME_START, SPECSTR_TOWNNAME_LAST + 1) && GetStringTab(t->townnametype) != TEXT_TAB_OLD_CUSTOM) { SlErrorCorrupt("Invalid town name generator"); } + if (IsSavegameVersionBefore(SLV_MORE_COMPANIES)) { + t->statues = owner_from_int(t->old_statues); + t->have_ratings = owner_from_int(t->old_have_ratings); + } } } diff --git a/src/town.h b/src/town.h index ce930bb180..d8512d1db1 100644 --- a/src/town.h +++ b/src/town.h @@ -16,6 +16,7 @@ #include "subsidy_type.h" #include "newgrf_storage.h" #include "cargotype.h" +#include template struct BuildingCounts { @@ -68,9 +69,11 @@ struct Town : TownPool::PoolItem<&_town_pool> { uint16_t noise_reached; ///< level of noise that all the airports are generating CompanyMask statues; ///< which companies have a statue? + uint16_t old_statues; /* Company ratings. */ CompanyMask have_ratings; ///< which companies have a rating + uint16_t old_have_ratings; uint8_t unwanted[MAX_COMPANIES]; ///< how many months companies aren't wanted by towns (bribe) CompanyID exclusivity; ///< which company has exclusivity uint8_t exclusive_counter; ///< months till the exclusivity expires From d46e49498f5f4eb6eaead8f2b5da687784e3739d Mon Sep 17 00:00:00 2001 From: Andrii Dokhniak Date: Tue, 4 Jun 2024 15:26:10 +0200 Subject: [PATCH 5/9] Fixed the loading of owners with old constants --- src/cargomonitor.h | 6 +++--- src/company_type.h | 2 ++ src/industry_map.h | 6 +++++- src/road_map.h | 4 ++-- src/saveload/afterload.cpp | 37 +++++++++++++++++++++----------- src/saveload/cargomonitor_sl.cpp | 2 +- src/saveload/company_sl.cpp | 2 +- src/saveload/engine_sl.cpp | 6 +++--- src/saveload/group_sl.cpp | 3 +++ src/saveload/industry_sl.cpp | 7 ++++++ src/saveload/map_sl.cpp | 16 ++++++++------ src/saveload/saveload.cpp | 16 +++++++++++++- src/saveload/saveload.h | 3 ++- src/saveload/signs_sl.cpp | 4 ++++ src/saveload/station_sl.cpp | 3 +++ src/saveload/town_sl.cpp | 11 ++++++---- src/saveload/vehicle_sl.cpp | 5 +++++ src/saveload/waypoint_sl.cpp | 4 ++++ 18 files changed, 101 insertions(+), 36 deletions(-) diff --git a/src/cargomonitor.h b/src/cargomonitor.h index 30a87ea320..505ce957e8 100644 --- a/src/cargomonitor.h +++ b/src/cargomonitor.h @@ -25,9 +25,9 @@ struct Station; * - bits 0-15 town or industry number * - bit 16 is set if it is an industry number (else it is a town number). * - bits 19-23 Cargo type. - * - bits 24-COMPANY_BIT_SIZE %Company number. + * - bits 24 - 24 + COMPANY_BIT_SIZE %Company number. */ -typedef uint64_t CargoMonitorID; ///< Type of the cargo monitor number. +typedef uint32_t CargoMonitorID; ///< Type of the cargo monitor number. /** Map type for storing and updating active cargo monitor numbers and their amounts. */ typedef std::map CargoMonitorMap; @@ -49,7 +49,7 @@ enum CargoCompanyBits { }; -static_assert(CCB_COMPANY_LENGTH <= (1 << 30)); // This should never be a limiting factor +static_assert(CCB_COMPANY_LENGTH <= (1 << 8)); static_assert(NUM_CARGO <= (1 << CCB_CARGO_TYPE_LENGTH)); static_assert(MAX_COMPANIES <= (1 << CCB_COMPANY_LENGTH)); diff --git a/src/company_type.h b/src/company_type.h index b283f4b565..42305ecbbd 100644 --- a/src/company_type.h +++ b/src/company_type.h @@ -41,6 +41,8 @@ enum Owner : uint8_t { COMPANY_NEW_COMPANY = 0xF8, ///< The client wants a new company COMPANY_SPECTATOR = 0xF9, ///< The client is spectating }; + + const uint8_t COMPANY_SIZE_BITS = 8; /// Size of the company id in bits static_assert(COMPANY_SIZE_BITS <= 10); /// 32bit m9 can only fit 3 owners of size 10 diff --git a/src/industry_map.h b/src/industry_map.h index ee45ade7c9..0f6021527f 100644 --- a/src/industry_map.h +++ b/src/industry_map.h @@ -10,7 +10,9 @@ #ifndef INDUSTRY_MAP_H #define INDUSTRY_MAP_H +#include "company_type.h" #include "industrytype.h" +#include "tile_map.h" #include "water_map.h" @@ -100,7 +102,7 @@ inline void SetIndustryCompleted(Tile tile) inline uint8_t GetIndustryConstructionStage(Tile tile) { assert(IsTileType(tile, MP_INDUSTRY)); - return IsIndustryCompleted(tile) ? (uint8_t)INDUSTRY_COMPLETED : GB(tile.m1(), 0, 2); + return IsIndustryCompleted(tile) ? (uint8_t)INDUSTRY_COMPLETED : GB(tile.m1(), 0, 2); // MYTODO: Figure this out, seams like it would read bits of the owner } /** @@ -286,6 +288,8 @@ inline void MakeIndustry(Tile t, IndustryID index, IndustryGfx gfx, uint8_t rand SetIndustryTriggers(t, 0); // rest of m6 SetWaterClass(t, wc); t.m7() = 0; + t.m8() = 0; + t.m9() = 0; } #endif /* INDUSTRY_MAP_H */ diff --git a/src/road_map.h b/src/road_map.h index d979f65b78..e5b3a01ceb 100644 --- a/src/road_map.h +++ b/src/road_map.h @@ -240,7 +240,7 @@ inline Owner OldGetRoadOwner(Tile t, RoadTramType rtt) /* Trams don't need OWNER_TOWN, and remapping OWNER_NONE * to OWNER_TOWN makes it use one bit less */ Owner o = (Owner)GB(t.m3(), 4, 4); - return o == OWNER_TOWN ? OWNER_NONE : o; + return o == OLD_OWNER_TOWN ? OLD_OWNER_NONE : o; } /** @@ -284,7 +284,7 @@ inline void OldSetRoadOwner(Tile t, RoadTramType rtt, Owner o) if (rtt == RTT_ROAD) { SB(IsNormalRoadTile(t) ? t.m1() : t.m7(), 0, 5, o); } else { - SB(t.m3(), 4, 4, o == OWNER_NONE ? OWNER_TOWN : o); + SB(t.m3(), 4, 4, o == OLD_OWNER_NONE ? OLD_OWNER_TOWN : o); } } diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index bf1d2c1486..78f14c4a74 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -63,6 +63,8 @@ #include "../timer/timer_game_economy.h" #include "../timer/timer_game_tick.h" +#include "company_type.h" +#include "road_map.h" #include "saveload/saveload.h" #include "saveload_internal.h" @@ -454,8 +456,8 @@ static void FixOwnerOfRailTrack(Tile t) if (IsLevelCrossingTile(t)) { /* else change the crossing to normal road (road vehicles won't care) */ - Owner road = GetRoadOwner(t, RTT_ROAD); - Owner tram = GetRoadOwner(t, RTT_TRAM); + Owner road = OldGetRoadOwner(t, RTT_ROAD); + Owner tram = OldGetRoadOwner(t, RTT_TRAM); RoadBits bits = GetCrossingRoadBits(t); bool hasroad = HasBit(t.m7(), 6); bool hastram = HasBit(t.m7(), 7); @@ -466,7 +468,7 @@ static void FixOwnerOfRailTrack(Tile t) t.m3() = (hasroad ? bits : 0); t.m5() = (hastram ? bits : 0) | ROAD_TILE_NORMAL << 6; SB(t.m6(), 2, 4, 0); - SetRoadOwner(t, RTT_TRAM, tram); + OldSetRoadOwner(t, RTT_TRAM, tram); return; } @@ -1226,7 +1228,7 @@ bool AfterLoadGame() t.m5() = (axis == AXIS_X ? ROAD_Y : ROAD_X) | ROAD_TILE_NORMAL << 6; SB(t.m6(), 2, 4, 0); t.m7() = 1 << 6; - SetRoadOwner(t, RTT_TRAM, OWNER_NONE); + OldSetRoadOwner(t, RTT_TRAM, OWNER_NONE); } } else { if (GB(t.m5(), 3, 2) == 0) { @@ -1883,8 +1885,8 @@ bool AfterLoadGame() /* works for all RoadTileType */ for (RoadTramType rtt : _roadtramtypes) { /* update even non-existing road types to update tile owner too */ - Owner o = GetRoadOwner(t, rtt); - if (o < OLD_MAX_COMPANIES && !Company::IsValidID(o)) SetRoadOwner(t, rtt, OWNER_NONE); + Owner o = OldGetRoadOwner(t, rtt); + if (o < OLD_MAX_COMPANIES && !Company::IsValidID(o)) OldSetRoadOwner(t, rtt, OWNER_NONE); } if (IsLevelCrossing(t)) { if (!Company::IsValidID(OldGetTileOwner(t))) FixOwnerOfRailTrack(t); @@ -2411,7 +2413,6 @@ bool AfterLoadGame() /* We need to properly number/name the depots. * The first step is making sure none of the depots uses the * 'default' names, after that we can assign the names. */ - for (Depot *d : Depot::Iterate()) d->town_cn = UINT16_MAX; for (Depot *d : Depot::Iterate()) MakeDefaultName(d); } @@ -2846,8 +2847,8 @@ bool AfterLoadGame() for (auto t : Map::Iterate()) { if (!IsBayRoadStopTile(t)) continue; Owner o = OldGetTileOwner(t); - SetRoadOwner(t, RTT_ROAD, o); - SetRoadOwner(t, RTT_TRAM, o); + OldSetRoadOwner(t, RTT_ROAD, o); + OldSetRoadOwner(t, RTT_TRAM, o); } } @@ -3268,10 +3269,22 @@ bool AfterLoadGame() } if (IsSavegameVersionBefore(SLV_MORE_COMPANIES)) { for (auto t : Map::Iterate()) { - if (IsValidTile(t) - && !IsTileType(t, MP_HOUSE) + //SB(t.m9(), 0, COMPANY_SIZE_BITS, OWNER_NONE); + if (!IsValidTile(t)) { + continue; + } + if (!IsTileType(t, MP_HOUSE) && !IsTileType(t, MP_INDUSTRY)) { - SetTileOwner(t, OldGetTileOwner(t)); + Owner o =OldGetTileOwner(t) ; + o = ParseOldOwner(o); + SetTileOwner(t, o); + } + if (MayHaveRoad(t)) { + for (RoadTramType rtt : _roadtramtypes) { + Owner o = OldGetRoadOwner(t, rtt); + o = ParseOldOwner(o); + SetRoadOwner(t, rtt, o); + } } } } diff --git a/src/saveload/cargomonitor_sl.cpp b/src/saveload/cargomonitor_sl.cpp index cdd166779b..c932ea18d7 100644 --- a/src/saveload/cargomonitor_sl.cpp +++ b/src/saveload/cargomonitor_sl.cpp @@ -24,7 +24,7 @@ struct TempStorage { /** Description of the #TempStorage structure for the purpose of load and save. */ static const SaveLoad _cargomonitor_pair_desc[] = { - SLE_VAR(TempStorage, number, SLE_UINT64), + SLE_VAR(TempStorage, number, SLE_UINT32), SLE_VAR(TempStorage, amount, SLE_UINT32), }; diff --git a/src/saveload/company_sl.cpp b/src/saveload/company_sl.cpp index e56a674b40..ae58efb6b2 100644 --- a/src/saveload/company_sl.cpp +++ b/src/saveload/company_sl.cpp @@ -523,7 +523,7 @@ struct PLYRChunkHandler : ChunkHandler { SlObject(c, slt); _company_colours[index] = c->colour; if (IsSavegameVersionBefore(SLV_MORE_COMPANIES)) { - c->bankrupt_asked = owner_from_int(c->old_bankrupt_asked); + c->bankrupt_asked = ParseOldCompMask(c->old_bankrupt_asked); } } } diff --git a/src/saveload/engine_sl.cpp b/src/saveload/engine_sl.cpp index d6e78d6638..987fd93fd5 100644 --- a/src/saveload/engine_sl.cpp +++ b/src/saveload/engine_sl.cpp @@ -120,9 +120,9 @@ struct ENGNChunkHandler : ChunkHandler { e->preview_asked = MAX_UVALUE(CompanyMask); } if (IsSavegameVersionBefore(SLV_MORE_COMPANIES)) { - e->preview_asked = owner_from_int(e->old_preview_asked); - e->company_avail = owner_from_int(e->old_company_avail); - e->company_hidden = owner_from_int(e->old_company_hidden); + e->preview_asked = ParseOldCompMask(e->old_preview_asked); + e->company_avail = ParseOldCompMask(e->old_company_avail); + e->company_hidden = ParseOldCompMask(e->old_company_hidden); } } } diff --git a/src/saveload/group_sl.cpp b/src/saveload/group_sl.cpp index 82ef465e08..e4e8674671 100644 --- a/src/saveload/group_sl.cpp +++ b/src/saveload/group_sl.cpp @@ -54,6 +54,9 @@ struct GRPSChunkHandler : ChunkHandler { SlObject(g, slt); if (IsSavegameVersionBefore(SLV_189)) g->parent = INVALID_GROUP; + if (IsSavegameVersionBefore(SLV_MORE_COMPANIES)) { + g->owner = ParseOldOwner(g->owner); + } } } }; diff --git a/src/saveload/industry_sl.cpp b/src/saveload/industry_sl.cpp index 6edea24e05..5cfdf58404 100644 --- a/src/saveload/industry_sl.cpp +++ b/src/saveload/industry_sl.cpp @@ -9,6 +9,7 @@ #include "../stdafx.h" +#include "company_type.h" #include "saveload.h" #include "compat/industry_sl_compat.h" @@ -265,6 +266,12 @@ struct INDYChunkHandler : ChunkHandler { } else if (IsSavegameVersionBefore(SLV_INDUSTRY_CARGO_REORGANISE)) { LoadMoveAcceptsProduced(i, INDUSTRY_NUM_INPUTS, INDUSTRY_NUM_OUTPUTS); } + if (IsSavegameVersionBefore(SLV_MORE_COMPANIES)) { + i->owner = ParseOldOwner(i-> owner); + i->founder = ParseOldOwner(i-> founder); + i->exclusive_supplier = ParseOldOwner(i-> exclusive_supplier); + i->exclusive_consumer = ParseOldOwner(i-> exclusive_consumer); + } Industry::IncIndustryTypeCount(i->type); } } diff --git a/src/saveload/map_sl.cpp b/src/saveload/map_sl.cpp index 8054753908..5869f823b4 100644 --- a/src/saveload/map_sl.cpp +++ b/src/saveload/map_sl.cpp @@ -17,6 +17,7 @@ #include "../fios.h" #include "../safeguards.h" +#include static uint32_t _map_dim_x; static uint32_t _map_dim_y; @@ -128,10 +129,10 @@ struct MAPOChunkHandler : ChunkHandler { std::array buf; uint size = Map::Size(); - for (TileIndex i = 0; i != size;) { - SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) Tile(i++).m1() = buf[j]; - } + for (TileIndex i = 0; i != size;) { + SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) Tile(i++).m1() = buf[j]; + } } void Save() const override @@ -362,7 +363,7 @@ struct MAP9ChunkHandler : ChunkHandler { for (TileIndex i = 0; i != size;) { SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT32); - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) Tile(i++).m8() = buf[j]; + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) Tile(i++).m9() = buf[j]; } } @@ -371,9 +372,10 @@ struct MAP9ChunkHandler : ChunkHandler { std::array buf; uint size = Map::Size(); + std::cout<< "loading m9" << std::endl; SlSetLength(static_cast(size) * sizeof(uint32_t)); for (TileIndex i = 0; i != size;) { - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = Tile(i++).m8(); + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = Tile(i++).m9(); SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT32); } } @@ -390,7 +392,7 @@ static const MAP5ChunkHandler MAP5; static const MAPEChunkHandler MAPE; static const MAP7ChunkHandler MAP7; static const MAP8ChunkHandler MAP8; -static const MAP8ChunkHandler MAP9; +static const MAP9ChunkHandler MAP9; static const ChunkHandlerRef map_chunk_handlers[] = { MAPS, MAPT, diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index d3c1a7f308..a62836060c 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -60,6 +60,7 @@ #include "saveload_filter.h" #include "../safeguards.h" +#include extern const SaveLoadVersion SAVEGAME_VERSION = (SaveLoadVersion)(SL_MAX_VERSION - 1); ///< Current savegame version of OpenTTD. @@ -1096,6 +1097,7 @@ static void SlArray(void *array, size_t length, VarType conv) /* If the SLE_ARR changes size, a savegame bump is required * and the developer should have written conversion lines. * Error out to make this more visible. */ + std::cout << "Corrupted array!!" << std::endl; SlErrorCorrupt("Fixed-length array is of wrong length"); } } @@ -1132,7 +1134,7 @@ CompanyMask bitset_from_bytes(const std::vector& buf) { } -CompanyMask owner_from_int(uint16_t old_owner) { +CompanyMask ParseOldCompMask(uint16_t old_owner) { CompanyMask result; for (int i = 0; i < 16; i++) { result[i] = GB(old_owner, i, 1) & 1; @@ -1140,6 +1142,17 @@ CompanyMask owner_from_int(uint16_t old_owner) { return result; } +Owner ParseOldOwner(Owner old) { + if (old == OLD_OWNER_NONE) { + old = OWNER_NONE; + } else if (old == OLD_OWNER_TOWN){ + old = OWNER_TOWN; + } else if (old == OLD_OWNER_WATER) { + old = OWNER_WATER; + } + return old; +} + /** * Save/Load the length of the bitset followed by the array of SL_VAR bits. @@ -1625,6 +1638,7 @@ size_t SlCalcObjMemberLength(const void *object, const SaveLoad &sld) static bool SlObjectMember(void *object, const SaveLoad &sld) { + std::cout <<"Object: "<< sld.name << std::endl; if (!SlIsObjectValidInSavegame(sld)) return false; VarType conv = GB(sld.conv, 0, 8); diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index 28c128b0ed..458fc5bca0 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -1314,7 +1314,8 @@ void SlCopy(void *object, size_t length, VarType conv); std::vector SlTableHeader(const SaveLoadTable &slt); std::vector SlCompatTableHeader(const SaveLoadTable &slt, const SaveLoadCompatTable &slct); void SlObject(void *object, const SaveLoadTable &slt); -CompanyMask owner_from_int(uint16_t old_owner); +CompanyMask ParseOldCompMask(uint16_t old_owner); +Owner ParseOldOwner(Owner old); bool SaveloadCrashWithMissingNewGRFs(); diff --git a/src/saveload/signs_sl.cpp b/src/saveload/signs_sl.cpp index e3a69c2f5b..a7aa87d373 100644 --- a/src/saveload/signs_sl.cpp +++ b/src/saveload/signs_sl.cpp @@ -9,6 +9,7 @@ #include "../stdafx.h" +#include "company_type.h" #include "saveload.h" #include "compat/signs_sl_compat.h" @@ -65,6 +66,9 @@ struct SIGNChunkHandler : ChunkHandler { if (IsSavegameVersionBefore(SLV_171) && si->owner == OLD_OWNER_NONE && _file_to_saveload.abstract_ftype == FT_SCENARIO) { si->owner = OWNER_DEITY; } + if (IsSavegameVersionBefore(SLV_MORE_COMPANIES)) { + si->owner = ParseOldOwner(si->owner); + } } } }; diff --git a/src/saveload/station_sl.cpp b/src/saveload/station_sl.cpp index c964ceb46a..fc01c80be9 100644 --- a/src/saveload/station_sl.cpp +++ b/src/saveload/station_sl.cpp @@ -502,6 +502,9 @@ struct STNSChunkHandler : ChunkHandler { _waiting_acceptance = 0; SlObject(st, slt); + if (IsSavegameVersionBefore(SLV_MORE_COMPANIES)) { + st->owner = ParseOldOwner(st->owner); + } } } diff --git a/src/saveload/town_sl.cpp b/src/saveload/town_sl.cpp index ea024634f7..66375d663a 100644 --- a/src/saveload/town_sl.cpp +++ b/src/saveload/town_sl.cpp @@ -224,9 +224,12 @@ SLE_CONDVARNAME(Town, old_have_ratings, "have_ratings", SLE_FILE_U8 | SLE_CONDVARNAME(Town, old_have_ratings, "have_ratings", SLE_UINT16, SLV_104, SLV_MORE_COMPANIES), SLE_CONDARR(Town, ratings, SLE_INT16, 8, SL_MIN_VERSION, SLV_104), - SLE_CONDARR(Town, ratings, SLE_INT16, MAX_COMPANIES, SLV_104, SL_MAX_VERSION), + SLE_CONDARR(Town, ratings, SLE_INT16, 15, SLV_104, SLV_MORE_COMPANIES), + SLE_CONDARR(Town, ratings, SLE_INT16, MAX_COMPANIES, SLV_MORE_COMPANIES, SL_MAX_VERSION), + SLE_CONDARR(Town, unwanted, SLE_INT8, 8, SLV_4, SLV_104), - SLE_CONDARR(Town, unwanted, SLE_INT8, MAX_COMPANIES, SLV_104, SL_MAX_VERSION), + SLE_CONDARR(Town, unwanted, SLE_INT8, 15, SLV_104, SLV_MORE_COMPANIES), + SLE_CONDARR(Town, unwanted, SLE_INT8, MAX_COMPANIES, SLV_MORE_COMPANIES, SL_MAX_VERSION), /* Slots 0 and 2 are passengers and mail respectively for old saves. */ SLE_CONDVARNAME(Town, supplied[0].old_max, "supplied[CT_PASSENGERS].old_max", SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_9), @@ -310,8 +313,8 @@ struct CITYChunkHandler : ChunkHandler { SlErrorCorrupt("Invalid town name generator"); } if (IsSavegameVersionBefore(SLV_MORE_COMPANIES)) { - t->statues = owner_from_int(t->old_statues); - t->have_ratings = owner_from_int(t->old_have_ratings); + t->statues = ParseOldCompMask(t->old_statues); + t->have_ratings = ParseOldCompMask(t->old_have_ratings); } } } diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp index 4e42de3962..02989dfe13 100644 --- a/src/saveload/vehicle_sl.cpp +++ b/src/saveload/vehicle_sl.cpp @@ -405,6 +405,11 @@ void AfterLoadVehicles(bool part_of_load) v->economy_age = v->age.base(); } } + if (IsSavegameVersionBefore(SLV_MORE_COMPANIES)) { + for (Vehicle *v : Vehicle::Iterate()) { + v->owner = ParseOldOwner(v->owner); + } + } } CheckValidVehicles(); diff --git a/src/saveload/waypoint_sl.cpp b/src/saveload/waypoint_sl.cpp index 7745c9b6e5..557081faff 100644 --- a/src/saveload/waypoint_sl.cpp +++ b/src/saveload/waypoint_sl.cpp @@ -16,6 +16,7 @@ #include "../newgrf.h" #include "../timer/timer_game_calendar.h" +#include "saveload/saveload.h" #include "table/strings.h" #include "saveload_internal.h" @@ -200,6 +201,9 @@ struct CHKPChunkHandler : ChunkHandler { wp->index = index; SlObject(wp, _old_waypoint_desc); + if (IsSavegameVersionBefore(SLV_MORE_COMPANIES)) { + wp->owner = ParseOldOwner(wp->owner); + } } } From 741257506a81580fd84a06324a42589372857b1f Mon Sep 17 00:00:00 2001 From: Andrii Dokhniak Date: Sat, 8 Jun 2024 16:23:31 +0200 Subject: [PATCH 6/9] Fixed the train depo issue --- src/rail_map.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/rail_map.h b/src/rail_map.h index f31bb0b5ce..3ca6ac1234 100644 --- a/src/rail_map.h +++ b/src/rail_map.h @@ -552,9 +552,7 @@ inline void SetRailDepotExitDirection(Tile tile, DiagDirection dir) */ inline void MakeRailDepot(Tile tile, Owner owner, DepotID depot_id, DiagDirection dir, RailType rail_type) { - SetTileType(tile, MP_RAILWAY); - SetTileOwner(tile, owner); - SetDockingTile(tile, false); + tile.m1() = 0; tile.m2() = depot_id; tile.m3() = 0; tile.m4() = 0; @@ -563,6 +561,9 @@ inline void MakeRailDepot(Tile tile, Owner owner, DepotID depot_id, DiagDirectio tile.m7() = 0; tile.m8() = rail_type; tile.m9() = 0; + SetTileType(tile, MP_RAILWAY); + SetDockingTile(tile, false); + SetTileOwner(tile, owner); } #endif /* RAIL_MAP_H */ From ad28875cfce848ca6eabaa7cdd51c4115436934e Mon Sep 17 00:00:00 2001 From: Andrii Dokhniak Date: Sat, 8 Jun 2024 16:29:10 +0200 Subject: [PATCH 7/9] small fixup --- src/rail_map.h | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/rail_map.h b/src/rail_map.h index 3ca6ac1234..7b2170e3ed 100644 --- a/src/rail_map.h +++ b/src/rail_map.h @@ -528,7 +528,6 @@ inline void MakeRailNormal(Tile t, Owner o, TrackBits b, RailType r) SB(t.m6(), 2, 4, 0); t.m7() = 0; t.m8() = r; - t.m9() = 0; } /** @@ -552,6 +551,9 @@ inline void SetRailDepotExitDirection(Tile tile, DiagDirection dir) */ inline void MakeRailDepot(Tile tile, Owner owner, DepotID depot_id, DiagDirection dir, RailType rail_type) { + SetTileType(tile, MP_RAILWAY); + SetDockingTile(tile, false); + SetTileOwner(tile, owner); tile.m1() = 0; tile.m2() = depot_id; tile.m3() = 0; @@ -560,10 +562,6 @@ inline void MakeRailDepot(Tile tile, Owner owner, DepotID depot_id, DiagDirectio SB(tile.m6(), 2, 4, 0); tile.m7() = 0; tile.m8() = rail_type; - tile.m9() = 0; - SetTileType(tile, MP_RAILWAY); - SetDockingTile(tile, false); - SetTileOwner(tile, owner); } #endif /* RAIL_MAP_H */ From 664c8cd2cf83b251675cefd2a243a3d9b9c96049 Mon Sep 17 00:00:00 2001 From: Andrii Dokhniak Date: Sat, 8 Jun 2024 17:01:30 +0200 Subject: [PATCH 8/9] Fixed the number of AIs --- src/framerate_type.h | 226 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 226 insertions(+) diff --git a/src/framerate_type.h b/src/framerate_type.h index 8dd84c29ce..fc05dd0813 100644 --- a/src/framerate_type.h +++ b/src/framerate_type.h @@ -75,8 +75,234 @@ enum PerformanceElement { PFE_AI12, ///< AI execution for player slot 13 PFE_AI13, ///< AI execution for player slot 14 PFE_AI14, ///< AI execution for player slot 15 + PFE_AI15, ///< AI execution for player slot 16 + PFE_AI16, ///< AI execution for player slot 17 + PFE_AI17, ///< AI execution for player slot 18 + PFE_AI18, ///< AI execution for player slot 19 + PFE_AI19, ///< AI execution for player slot 20 + PFE_AI20, ///< AI execution for player slot 21 + PFE_AI21, ///< AI execution for player slot 22 + PFE_AI22, ///< AI execution for player slot 23 + PFE_AI23, ///< AI execution for player slot 24 + PFE_AI24, ///< AI execution for player slot 25 + PFE_AI25, ///< AI execution for player slot 26 + PFE_AI26, ///< AI execution for player slot 27 + PFE_AI27, ///< AI execution for player slot 28 + PFE_AI28, ///< AI execution for player slot 29 + PFE_AI29, ///< AI execution for player slot 30 + PFE_AI30, ///< AI execution for player slot 31 + PFE_AI31, ///< AI execution for player slot 32 + PFE_AI32, ///< AI execution for player slot 33 + PFE_AI33, ///< AI execution for player slot 34 + PFE_AI34, ///< AI execution for player slot 35 + PFE_AI35, ///< AI execution for player slot 36 + PFE_AI36, ///< AI execution for player slot 37 + PFE_AI37, ///< AI execution for player slot 38 + PFE_AI38, ///< AI execution for player slot 39 + PFE_AI39, ///< AI execution for player slot 40 + PFE_AI40, ///< AI execution for player slot 41 + PFE_AI41, ///< AI execution for player slot 42 + PFE_AI42, ///< AI execution for player slot 43 + PFE_AI43, ///< AI execution for player slot 44 + PFE_AI44, ///< AI execution for player slot 45 + PFE_AI45, ///< AI execution for player slot 46 + PFE_AI46, ///< AI execution for player slot 47 + PFE_AI47, ///< AI execution for player slot 48 + PFE_AI48, ///< AI execution for player slot 49 + PFE_AI49, ///< AI execution for player slot 50 + PFE_AI50, ///< AI execution for player slot 51 + PFE_AI51, ///< AI execution for player slot 52 + PFE_AI52, ///< AI execution for player slot 53 + PFE_AI53, ///< AI execution for player slot 54 + PFE_AI54, ///< AI execution for player slot 55 + PFE_AI55, ///< AI execution for player slot 56 + PFE_AI56, ///< AI execution for player slot 57 + PFE_AI57, ///< AI execution for player slot 58 + PFE_AI58, ///< AI execution for player slot 59 + PFE_AI59, ///< AI execution for player slot 60 + PFE_AI60, ///< AI execution for player slot 61 + PFE_AI61, ///< AI execution for player slot 62 + PFE_AI62, ///< AI execution for player slot 63 + PFE_AI63, ///< AI execution for player slot 64 + PFE_AI64, ///< AI execution for player slot 65 + PFE_AI65, ///< AI execution for player slot 66 + PFE_AI66, ///< AI execution for player slot 67 + PFE_AI67, ///< AI execution for player slot 68 + PFE_AI68, ///< AI execution for player slot 69 + PFE_AI69, ///< AI execution for player slot 70 + PFE_AI70, ///< AI execution for player slot 71 + PFE_AI71, ///< AI execution for player slot 72 + PFE_AI72, ///< AI execution for player slot 73 + PFE_AI73, ///< AI execution for player slot 74 + PFE_AI74, ///< AI execution for player slot 75 + PFE_AI75, ///< AI execution for player slot 76 + PFE_AI76, ///< AI execution for player slot 77 + PFE_AI77, ///< AI execution for player slot 78 + PFE_AI78, ///< AI execution for player slot 79 + PFE_AI79, ///< AI execution for player slot 80 + PFE_AI80, ///< AI execution for player slot 81 + PFE_AI81, ///< AI execution for player slot 82 + PFE_AI82, ///< AI execution for player slot 83 + PFE_AI83, ///< AI execution for player slot 84 + PFE_AI84, ///< AI execution for player slot 85 + PFE_AI85, ///< AI execution for player slot 86 + PFE_AI86, ///< AI execution for player slot 87 + PFE_AI87, ///< AI execution for player slot 88 + PFE_AI88, ///< AI execution for player slot 89 + PFE_AI89, ///< AI execution for player slot 90 + PFE_AI90, ///< AI execution for player slot 91 + PFE_AI91, ///< AI execution for player slot 92 + PFE_AI92, ///< AI execution for player slot 93 + PFE_AI93, ///< AI execution for player slot 94 + PFE_AI94, ///< AI execution for player slot 95 + PFE_AI95, ///< AI execution for player slot 96 + PFE_AI96, ///< AI execution for player slot 97 + PFE_AI97, ///< AI execution for player slot 98 + PFE_AI98, ///< AI execution for player slot 99 + PFE_AI99, ///< AI execution for player slot 100 + PFE_AI100, ///< AI execution for player slot 101 + PFE_AI101, ///< AI execution for player slot 102 + PFE_AI102, ///< AI execution for player slot 103 + PFE_AI103, ///< AI execution for player slot 104 + PFE_AI104, ///< AI execution for player slot 105 + PFE_AI105, ///< AI execution for player slot 106 + PFE_AI106, ///< AI execution for player slot 107 + PFE_AI107, ///< AI execution for player slot 108 + PFE_AI108, ///< AI execution for player slot 109 + PFE_AI109, ///< AI execution for player slot 110 + PFE_AI110, ///< AI execution for player slot 111 + PFE_AI111, ///< AI execution for player slot 112 + PFE_AI112, ///< AI execution for player slot 113 + PFE_AI113, ///< AI execution for player slot 114 + PFE_AI114, ///< AI execution for player slot 115 + PFE_AI115, ///< AI execution for player slot 116 + PFE_AI116, ///< AI execution for player slot 117 + PFE_AI117, ///< AI execution for player slot 118 + PFE_AI118, ///< AI execution for player slot 119 + PFE_AI119, ///< AI execution for player slot 120 + PFE_AI120, ///< AI execution for player slot 121 + PFE_AI121, ///< AI execution for player slot 122 + PFE_AI122, ///< AI execution for player slot 123 + PFE_AI123, ///< AI execution for player slot 124 + PFE_AI124, ///< AI execution for player slot 125 + PFE_AI125, ///< AI execution for player slot 126 + PFE_AI126, ///< AI execution for player slot 127 + PFE_AI127, ///< AI execution for player slot 128 + PFE_AI128, ///< AI execution for player slot 129 + PFE_AI129, ///< AI execution for player slot 130 + PFE_AI130, ///< AI execution for player slot 131 + PFE_AI131, ///< AI execution for player slot 132 + PFE_AI132, ///< AI execution for player slot 133 + PFE_AI133, ///< AI execution for player slot 134 + PFE_AI134, ///< AI execution for player slot 135 + PFE_AI135, ///< AI execution for player slot 136 + PFE_AI136, ///< AI execution for player slot 137 + PFE_AI137, ///< AI execution for player slot 138 + PFE_AI138, ///< AI execution for player slot 139 + PFE_AI139, ///< AI execution for player slot 140 + PFE_AI140, ///< AI execution for player slot 141 + PFE_AI141, ///< AI execution for player slot 142 + PFE_AI142, ///< AI execution for player slot 143 + PFE_AI143, ///< AI execution for player slot 144 + PFE_AI144, ///< AI execution for player slot 145 + PFE_AI145, ///< AI execution for player slot 146 + PFE_AI146, ///< AI execution for player slot 147 + PFE_AI147, ///< AI execution for player slot 148 + PFE_AI148, ///< AI execution for player slot 149 + PFE_AI149, ///< AI execution for player slot 150 + PFE_AI150, ///< AI execution for player slot 151 + PFE_AI151, ///< AI execution for player slot 152 + PFE_AI152, ///< AI execution for player slot 153 + PFE_AI153, ///< AI execution for player slot 154 + PFE_AI154, ///< AI execution for player slot 155 + PFE_AI155, ///< AI execution for player slot 156 + PFE_AI156, ///< AI execution for player slot 157 + PFE_AI157, ///< AI execution for player slot 158 + PFE_AI158, ///< AI execution for player slot 159 + PFE_AI159, ///< AI execution for player slot 160 + PFE_AI160, ///< AI execution for player slot 161 + PFE_AI161, ///< AI execution for player slot 162 + PFE_AI162, ///< AI execution for player slot 163 + PFE_AI163, ///< AI execution for player slot 164 + PFE_AI164, ///< AI execution for player slot 165 + PFE_AI165, ///< AI execution for player slot 166 + PFE_AI166, ///< AI execution for player slot 167 + PFE_AI167, ///< AI execution for player slot 168 + PFE_AI168, ///< AI execution for player slot 169 + PFE_AI169, ///< AI execution for player slot 170 + PFE_AI170, ///< AI execution for player slot 171 + PFE_AI171, ///< AI execution for player slot 172 + PFE_AI172, ///< AI execution for player slot 173 + PFE_AI173, ///< AI execution for player slot 174 + PFE_AI174, ///< AI execution for player slot 175 + PFE_AI175, ///< AI execution for player slot 176 + PFE_AI176, ///< AI execution for player slot 177 + PFE_AI177, ///< AI execution for player slot 178 + PFE_AI178, ///< AI execution for player slot 179 + PFE_AI179, ///< AI execution for player slot 180 + PFE_AI180, ///< AI execution for player slot 181 + PFE_AI181, ///< AI execution for player slot 182 + PFE_AI182, ///< AI execution for player slot 183 + PFE_AI183, ///< AI execution for player slot 184 + PFE_AI184, ///< AI execution for player slot 185 + PFE_AI185, ///< AI execution for player slot 186 + PFE_AI186, ///< AI execution for player slot 187 + PFE_AI187, ///< AI execution for player slot 188 + PFE_AI188, ///< AI execution for player slot 189 + PFE_AI189, ///< AI execution for player slot 190 + PFE_AI190, ///< AI execution for player slot 191 + PFE_AI191, ///< AI execution for player slot 192 + PFE_AI192, ///< AI execution for player slot 193 + PFE_AI193, ///< AI execution for player slot 194 + PFE_AI194, ///< AI execution for player slot 195 + PFE_AI195, ///< AI execution for player slot 196 + PFE_AI196, ///< AI execution for player slot 197 + PFE_AI197, ///< AI execution for player slot 198 + PFE_AI198, ///< AI execution for player slot 199 + PFE_AI199, ///< AI execution for player slot 200 + PFE_AI200, ///< AI execution for player slot 201 + PFE_AI201, ///< AI execution for player slot 202 + PFE_AI202, ///< AI execution for player slot 203 + PFE_AI203, ///< AI execution for player slot 204 + PFE_AI204, ///< AI execution for player slot 205 + PFE_AI205, ///< AI execution for player slot 206 + PFE_AI206, ///< AI execution for player slot 207 + PFE_AI207, ///< AI execution for player slot 208 + PFE_AI208, ///< AI execution for player slot 209 + PFE_AI209, ///< AI execution for player slot 210 + PFE_AI210, ///< AI execution for player slot 211 + PFE_AI211, ///< AI execution for player slot 212 + PFE_AI212, ///< AI execution for player slot 213 + PFE_AI213, ///< AI execution for player slot 214 + PFE_AI214, ///< AI execution for player slot 215 + PFE_AI215, ///< AI execution for player slot 216 + PFE_AI216, ///< AI execution for player slot 217 + PFE_AI217, ///< AI execution for player slot 218 + PFE_AI218, ///< AI execution for player slot 219 + PFE_AI219, ///< AI execution for player slot 220 + PFE_AI220, ///< AI execution for player slot 221 + PFE_AI221, ///< AI execution for player slot 222 + PFE_AI222, ///< AI execution for player slot 223 + PFE_AI223, ///< AI execution for player slot 224 + PFE_AI224, ///< AI execution for player slot 225 + PFE_AI225, ///< AI execution for player slot 226 + PFE_AI226, ///< AI execution for player slot 227 + PFE_AI227, ///< AI execution for player slot 228 + PFE_AI228, ///< AI execution for player slot 229 + PFE_AI229, ///< AI execution for player slot 230 + PFE_AI230, ///< AI execution for player slot 231 + PFE_AI231, ///< AI execution for player slot 232 + PFE_AI232, ///< AI execution for player slot 233 + PFE_AI233, ///< AI execution for player slot 234 + PFE_AI234, ///< AI execution for player slot 235 + PFE_AI235, ///< AI execution for player slot 236 + PFE_AI236, ///< AI execution for player slot 237 + PFE_AI237, ///< AI execution for player slot 238 + PFE_AI238, ///< AI execution for player slot 239 + PFE_AI239, ///< AI execution for player slot 240 PFE_MAX, ///< End of enum, must be last. }; + DECLARE_POSTFIX_INCREMENT(PerformanceElement) /** Type used to hold a performance timing measurement */ From 535f296bd1c0a5fc6f54229a6a5d2c4ad777b77c Mon Sep 17 00:00:00 2001 From: Andrii Dokhniak Date: Sat, 8 Jun 2024 20:58:09 +0200 Subject: [PATCH 9/9] Fixed the number of AIs, again --- src/framerate_gui.cpp | 227 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 226 insertions(+), 1 deletion(-) diff --git a/src/framerate_gui.cpp b/src/framerate_gui.cpp index 56848b060a..3cb42085b0 100644 --- a/src/framerate_gui.cpp +++ b/src/framerate_gui.cpp @@ -217,7 +217,232 @@ namespace { PerformanceData(1), PerformanceData(1), PerformanceData(1), - PerformanceData(1), // PFE_AI14 + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), + PerformanceData(1), // PFE_AI239 }; }