diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index fa76393137..fe7a9a832f 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -13,6 +13,8 @@ add_files( geometry_func.hpp geometry_type.hpp kdtree.hpp + label.cpp + label_type.hpp math_func.cpp math_func.hpp multimap.hpp diff --git a/src/core/label.cpp b/src/core/label.cpp new file mode 100644 index 0000000000..287715f79f --- /dev/null +++ b/src/core/label.cpp @@ -0,0 +1,29 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file label.cpp Implementation of label functions. */ + +#include "../stdafx.h" +#include "label_type.hpp" +#include "../string_func.h" + +#include "../safeguards.h" + +/** + * Get the label as a \c std::string. + * If the label is all \c std::isgraph characters, it will return these characters as string, + * otherwise it will format it as a 8-digit hexadecimal. + * @return The label as string. + */ +std::string BaseLabel::AsString() const +{ + if (std::ranges::all_of(*this, [](uint8_t c) { return std::isgraph(c); })) { + return std::string{reinterpret_cast(this->data()), this->size()}; + } + + return FormatArrayAsHex(*this); +} diff --git a/src/core/label_type.hpp b/src/core/label_type.hpp new file mode 100644 index 0000000000..9baeec3370 --- /dev/null +++ b/src/core/label_type.hpp @@ -0,0 +1,72 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file label_type.hpp A type for 4 character labels/tags/ids in files that should be read/shown as is. */ + +#ifndef LABEL_TYPE_HPP +#define LABEL_TYPE_HPP + +/** Base for a four character label/tag/id. */ +struct BaseLabel : std::array { + /** + * Check whether the label is empty. + * @return \c true iff the label is empty, i.e. all zeros. + */ + constexpr inline bool Empty() const + { + return std::ranges::all_of(*this, [](uint8_t b) { return b == 0; }); + }; + + /** + * Get the label as a \c std::string. + * If the label is all \c std::isgraph characters, it will return these characters as string, + * otherwise it will format it as a 8-digit hexadecimal. + * @return The label as string. + */ + std::string AsString() const; +}; + +/** + * A four character label/tag/id. + * @tparam Tag Type to distinguish labels/tags/ids of different types. + */ +template +struct Label : BaseLabel { + /** Create an empty label, i.e. all zeros. */ + constexpr Label() + { + std::ranges::fill(*this, 0); + } + + /** + * Create a label with the given 4 letter character string. + * @param label The label value. + * @note This defines 5 characters, but the 5th character is assumed to null-terminator. + */ + constexpr Label(const char (&label)[5]) + { + std::copy(label, label + this->size(), this->begin()); + } + + /** + * Create a label with the given 4 bytes. + * @param label The label value. + */ + constexpr Label(const uint8_t (&label)[4]) + { + std::copy(label, label + this->size(), this->begin()); + } + + /** + * Default spaceship operator. + * @param other The label to compare to. + * @return The comparison ordering. + */ + constexpr std::strong_ordering operator<=>(const Label &other) const = default; +}; + +#endif /* LABEL_TYPE_HPP */ diff --git a/src/saveload/ai_sl.cpp b/src/saveload/ai_sl.cpp index e2a7cd88a2..661ce3b83c 100644 --- a/src/saveload/ai_sl.cpp +++ b/src/saveload/ai_sl.cpp @@ -73,7 +73,7 @@ static void SaveReal_AIPL(int arg) } struct AIPLChunkHandler : ChunkHandler { - AIPLChunkHandler() : ChunkHandler('AIPL', ChunkType::Table) {} + AIPLChunkHandler() : ChunkHandler("AIPL", ChunkType::Table) {} void Load() const override { diff --git a/src/saveload/airport_sl.cpp b/src/saveload/airport_sl.cpp index cf7131616f..af867babf4 100644 --- a/src/saveload/airport_sl.cpp +++ b/src/saveload/airport_sl.cpp @@ -15,11 +15,11 @@ #include "../safeguards.h" struct APIDChunkHandler : NewGRFMappingChunkHandler { - APIDChunkHandler() : NewGRFMappingChunkHandler('APID', _airport_mngr) {} + APIDChunkHandler() : NewGRFMappingChunkHandler("APID", _airport_mngr) {} }; struct ATIDChunkHandler : NewGRFMappingChunkHandler { - ATIDChunkHandler() : NewGRFMappingChunkHandler('ATID', _airporttile_mngr) {} + ATIDChunkHandler() : NewGRFMappingChunkHandler("ATID", _airporttile_mngr) {} }; static const ATIDChunkHandler ATID; diff --git a/src/saveload/animated_tile_sl.cpp b/src/saveload/animated_tile_sl.cpp index d28ff4b1e8..2b91f96670 100644 --- a/src/saveload/animated_tile_sl.cpp +++ b/src/saveload/animated_tile_sl.cpp @@ -23,7 +23,7 @@ static const SaveLoad _animated_tile_desc[] = { }; struct ANITChunkHandler : ChunkHandler { - ANITChunkHandler() : ChunkHandler('ANIT', ChunkType::Table) {} + ANITChunkHandler() : ChunkHandler("ANIT", ChunkType::Table) {} void Save() const override { diff --git a/src/saveload/autoreplace_sl.cpp b/src/saveload/autoreplace_sl.cpp index e8eee6e6da..bd460dbfab 100644 --- a/src/saveload/autoreplace_sl.cpp +++ b/src/saveload/autoreplace_sl.cpp @@ -26,7 +26,7 @@ static const SaveLoad _engine_renew_desc[] = { }; struct ERNWChunkHandler : ChunkHandler { - ERNWChunkHandler() : ChunkHandler('ERNW', ChunkType::Table) {} + ERNWChunkHandler() : ChunkHandler("ERNW", ChunkType::Table) {} void Save() const override { diff --git a/src/saveload/cargomonitor_sl.cpp b/src/saveload/cargomonitor_sl.cpp index f0e0cf0249..713be2c625 100644 --- a/src/saveload/cargomonitor_sl.cpp +++ b/src/saveload/cargomonitor_sl.cpp @@ -45,7 +45,7 @@ static CargoMonitorID FixupCargoMonitor(CargoMonitorID number) /** #_cargo_deliveries monitoring map. */ struct CMDLChunkHandler : ChunkHandler { - CMDLChunkHandler() : ChunkHandler('CMDL', ChunkType::Table) {} + CMDLChunkHandler() : ChunkHandler("CMDL", ChunkType::Table) {} void Save() const override { @@ -88,7 +88,7 @@ struct CMDLChunkHandler : ChunkHandler { /** #_cargo_pickups monitoring map. */ struct CMPUChunkHandler : ChunkHandler { - CMPUChunkHandler() : ChunkHandler('CMPU', ChunkType::Table) {} + CMPUChunkHandler() : ChunkHandler("CMPU", ChunkType::Table) {} void Save() const override { diff --git a/src/saveload/cargopacket_sl.cpp b/src/saveload/cargopacket_sl.cpp index b0897056c8..3a6c327d44 100644 --- a/src/saveload/cargopacket_sl.cpp +++ b/src/saveload/cargopacket_sl.cpp @@ -143,7 +143,7 @@ SaveLoadTable GetCargoPacketDesc() } struct CAPAChunkHandler : ChunkHandler { - CAPAChunkHandler() : ChunkHandler('CAPA', ChunkType::Table) {} + CAPAChunkHandler() : ChunkHandler("CAPA", ChunkType::Table) {} void Save() const override { diff --git a/src/saveload/cheat_sl.cpp b/src/saveload/cheat_sl.cpp index f5c8568c8d..ff18184dff 100644 --- a/src/saveload/cheat_sl.cpp +++ b/src/saveload/cheat_sl.cpp @@ -39,7 +39,7 @@ static const SaveLoad _cheats_desc[] = { struct CHTSChunkHandler : ChunkHandler { - CHTSChunkHandler() : ChunkHandler('CHTS', ChunkType::Table) {} + CHTSChunkHandler() : ChunkHandler("CHTS", ChunkType::Table) {} void Save() const override { diff --git a/src/saveload/company_sl.cpp b/src/saveload/company_sl.cpp index 2585103390..de397a656c 100644 --- a/src/saveload/company_sl.cpp +++ b/src/saveload/company_sl.cpp @@ -551,7 +551,7 @@ static const SaveLoad _company_desc[] = { }; struct PLYRChunkHandler : ChunkHandler { - PLYRChunkHandler() : ChunkHandler('PLYR', ChunkType::Table) {} + PLYRChunkHandler() : ChunkHandler("PLYR", ChunkType::Table) {} void Save() const override { diff --git a/src/saveload/depot_sl.cpp b/src/saveload/depot_sl.cpp index 07c17e4f43..7c3b905033 100644 --- a/src/saveload/depot_sl.cpp +++ b/src/saveload/depot_sl.cpp @@ -30,7 +30,7 @@ static const SaveLoad _depot_desc[] = { }; struct DEPTChunkHandler : ChunkHandler { - DEPTChunkHandler() : ChunkHandler('DEPT', ChunkType::Table) {} + DEPTChunkHandler() : ChunkHandler("DEPT", ChunkType::Table) {} void Save() const override { diff --git a/src/saveload/economy_sl.cpp b/src/saveload/economy_sl.cpp index a6e973435a..3ae9bb9e31 100644 --- a/src/saveload/economy_sl.cpp +++ b/src/saveload/economy_sl.cpp @@ -19,7 +19,7 @@ /** Prices in pre 126 savegames */ struct PRICChunkHandler : ChunkHandler { - PRICChunkHandler() : ChunkHandler('PRIC', ChunkType::ReadOnly) {} + PRICChunkHandler() : ChunkHandler("PRIC", ChunkType::ReadOnly) {} void Load() const override { @@ -32,7 +32,7 @@ struct PRICChunkHandler : ChunkHandler { /** Cargo payment rates in pre 126 savegames */ struct CAPRChunkHandler : ChunkHandler { - CAPRChunkHandler() : ChunkHandler('CAPR', ChunkType::ReadOnly) {} + CAPRChunkHandler() : ChunkHandler("CAPR", ChunkType::ReadOnly) {} void Load() const override { @@ -58,7 +58,7 @@ static const SaveLoad _economy_desc[] = { /** Economy variables */ struct ECMYChunkHandler : ChunkHandler { - ECMYChunkHandler() : ChunkHandler('ECMY', ChunkType::Table) {} + ECMYChunkHandler() : ChunkHandler("ECMY", ChunkType::Table) {} void Save() const override { @@ -89,7 +89,7 @@ static const SaveLoad _cargopayment_desc[] = { }; struct CAPYChunkHandler : ChunkHandler { - CAPYChunkHandler() : ChunkHandler('CAPY', ChunkType::Table) {} + CAPYChunkHandler() : ChunkHandler("CAPY", ChunkType::Table) {} void Save() const override { diff --git a/src/saveload/engine_sl.cpp b/src/saveload/engine_sl.cpp index 35543d288e..75131288d8 100644 --- a/src/saveload/engine_sl.cpp +++ b/src/saveload/engine_sl.cpp @@ -62,7 +62,7 @@ Engine *GetTempDataEngine(EngineID index, VehicleType type, uint16_t local_id) } struct ENGNChunkHandler : ChunkHandler { - ENGNChunkHandler() : ChunkHandler('ENGN', ChunkType::Table) {} + ENGNChunkHandler() : ChunkHandler("ENGN", ChunkType::Table) {} void Save() const override { @@ -135,7 +135,7 @@ void ResetTempEngineData() } struct ENGSChunkHandler : ChunkHandler { - ENGSChunkHandler() : ChunkHandler('ENGS', ChunkType::ReadOnly) {} + ENGSChunkHandler() : ChunkHandler("ENGS", ChunkType::ReadOnly) {} void Load() const override { @@ -162,7 +162,7 @@ static const SaveLoad _engine_id_mapping_desc[] = { }; struct EIDSChunkHandler : ChunkHandler { - EIDSChunkHandler() : ChunkHandler('EIDS', ChunkType::Table) {} + EIDSChunkHandler() : ChunkHandler("EIDS", ChunkType::Table) {} void Save() const override { diff --git a/src/saveload/game_sl.cpp b/src/saveload/game_sl.cpp index d58766c4c5..ea37f7bfab 100644 --- a/src/saveload/game_sl.cpp +++ b/src/saveload/game_sl.cpp @@ -52,7 +52,7 @@ static void SaveReal_GSDT(int) } struct GSDTChunkHandler : ChunkHandler { - GSDTChunkHandler() : ChunkHandler('GSDT', ChunkType::Table) {} + GSDTChunkHandler() : ChunkHandler("GSDT", ChunkType::Table) {} void Load() const override { @@ -153,7 +153,7 @@ static const SaveLoad _game_language_desc[] = { }; struct GSTRChunkHandler : ChunkHandler { - GSTRChunkHandler() : ChunkHandler('GSTR', ChunkType::Table) {} + GSTRChunkHandler() : ChunkHandler("GSTR", ChunkType::Table) {} void Load() const override { diff --git a/src/saveload/gamelog_sl.cpp b/src/saveload/gamelog_sl.cpp index f37bd08b87..e555cc513f 100644 --- a/src/saveload/gamelog_sl.cpp +++ b/src/saveload/gamelog_sl.cpp @@ -375,7 +375,7 @@ static const SaveLoad _gamelog_desc[] = { }; struct GLOGChunkHandler : ChunkHandler { - GLOGChunkHandler() : ChunkHandler('GLOG', ChunkType::Table) {} + GLOGChunkHandler() : ChunkHandler("GLOG", ChunkType::Table) {} void LoadCommon(Gamelog &gamelog) const { diff --git a/src/saveload/goal_sl.cpp b/src/saveload/goal_sl.cpp index cdb9bc79e0..0f38a892e3 100644 --- a/src/saveload/goal_sl.cpp +++ b/src/saveload/goal_sl.cpp @@ -26,7 +26,7 @@ static const SaveLoad _goals_desc[] = { }; struct GOALChunkHandler : ChunkHandler { - GOALChunkHandler() : ChunkHandler('GOAL', ChunkType::Table) {} + GOALChunkHandler() : ChunkHandler("GOAL", ChunkType::Table) {} void Save() const override { diff --git a/src/saveload/group_sl.cpp b/src/saveload/group_sl.cpp index 9926c3aa63..7823053bdd 100644 --- a/src/saveload/group_sl.cpp +++ b/src/saveload/group_sl.cpp @@ -30,7 +30,7 @@ static const SaveLoad _group_desc[] = { }; struct GRPSChunkHandler : ChunkHandler { - GRPSChunkHandler() : ChunkHandler('GRPS', ChunkType::Table) {} + GRPSChunkHandler() : ChunkHandler("GRPS", ChunkType::Table) {} void Save() const override { diff --git a/src/saveload/industry_sl.cpp b/src/saveload/industry_sl.cpp index 00838c6b53..67808d1bfc 100644 --- a/src/saveload/industry_sl.cpp +++ b/src/saveload/industry_sl.cpp @@ -211,7 +211,7 @@ static const SaveLoad _industry_desc[] = { }; struct INDYChunkHandler : ChunkHandler { - INDYChunkHandler() : ChunkHandler('INDY', ChunkType::Table) {} + INDYChunkHandler() : ChunkHandler("INDY", ChunkType::Table) {} void Save() const override { @@ -303,11 +303,11 @@ struct INDYChunkHandler : ChunkHandler { }; struct IIDSChunkHandler : NewGRFMappingChunkHandler { - IIDSChunkHandler() : NewGRFMappingChunkHandler('IIDS', _industry_mngr) {} + IIDSChunkHandler() : NewGRFMappingChunkHandler("IIDS", _industry_mngr) {} }; struct TIDSChunkHandler : NewGRFMappingChunkHandler { - TIDSChunkHandler() : NewGRFMappingChunkHandler('TIDS', _industile_mngr) {} + TIDSChunkHandler() : NewGRFMappingChunkHandler("TIDS", _industile_mngr) {} }; /** Description of the data to save and load in #IndustryBuildData. */ @@ -317,7 +317,7 @@ static const SaveLoad _industry_builder_desc[] = { /** Industry builder. */ struct IBLDChunkHandler : ChunkHandler { - IBLDChunkHandler() : ChunkHandler('IBLD', ChunkType::Table) {} + IBLDChunkHandler() : ChunkHandler("IBLD", ChunkType::Table) {} void Save() const override { @@ -348,7 +348,7 @@ static const SaveLoad _industrytype_builder_desc[] = { /** Industry-type build data. */ struct ITBLChunkHandler : ChunkHandler { - ITBLChunkHandler() : ChunkHandler('ITBL', ChunkType::Table) {} + ITBLChunkHandler() : ChunkHandler("ITBL", ChunkType::Table) {} void Save() const override { diff --git a/src/saveload/labelmaps_sl.cpp b/src/saveload/labelmaps_sl.cpp index aee34f5020..89878d38d0 100644 --- a/src/saveload/labelmaps_sl.cpp +++ b/src/saveload/labelmaps_sl.cpp @@ -34,7 +34,7 @@ void AfterLoadLabelMaps() } struct RAILChunkHandler : ChunkHandler { - RAILChunkHandler() : ChunkHandler('RAIL', ChunkType::Table) {} + RAILChunkHandler() : ChunkHandler("RAIL", ChunkType::Table) {} static inline const SaveLoad description[] = { SLE_VAR(LabelObject, label, VarTypes::U32), @@ -69,7 +69,7 @@ struct RAILChunkHandler : ChunkHandler { }; struct ROTTChunkHandler : ChunkHandler { - ROTTChunkHandler() : ChunkHandler('ROTT', ChunkType::Table) {} + ROTTChunkHandler() : ChunkHandler("ROTT", ChunkType::Table) {} static inline const SaveLoad description[] = { SLE_VAR(LabelObject, label, VarTypes::U32), diff --git a/src/saveload/league_sl.cpp b/src/saveload/league_sl.cpp index ab460d8a36..f060b1a1e1 100644 --- a/src/saveload/league_sl.cpp +++ b/src/saveload/league_sl.cpp @@ -27,7 +27,7 @@ static const SaveLoad _league_table_elements_desc[] = { }; struct LEAEChunkHandler : ChunkHandler { - LEAEChunkHandler() : ChunkHandler('LEAE', ChunkType::Table) {} + LEAEChunkHandler() : ChunkHandler("LEAE", ChunkType::Table) {} void Save() const override { @@ -58,7 +58,7 @@ static const SaveLoad _league_tables_desc[] = { }; struct LEATChunkHandler : ChunkHandler { - LEATChunkHandler() : ChunkHandler('LEAT', ChunkType::Table) {} + LEATChunkHandler() : ChunkHandler("LEAT", ChunkType::Table) {} void Save() const override { diff --git a/src/saveload/linkgraph_sl.cpp b/src/saveload/linkgraph_sl.cpp index e55ffc923e..d996755f63 100644 --- a/src/saveload/linkgraph_sl.cpp +++ b/src/saveload/linkgraph_sl.cpp @@ -259,7 +259,7 @@ void AfterLoadLinkGraphs() * All link graphs. */ struct LGRPChunkHandler : ChunkHandler { - LGRPChunkHandler() : ChunkHandler('LGRP', ChunkType::Table) {} + LGRPChunkHandler() : ChunkHandler("LGRP", ChunkType::Table) {} void Save() const override { @@ -287,7 +287,7 @@ struct LGRPChunkHandler : ChunkHandler { * All link graph jobs. */ struct LGRJChunkHandler : ChunkHandler { - LGRJChunkHandler() : ChunkHandler('LGRJ', ChunkType::Table) {} + LGRJChunkHandler() : ChunkHandler("LGRJ", ChunkType::Table) {} void Save() const override { @@ -315,7 +315,7 @@ struct LGRJChunkHandler : ChunkHandler { * Link graph schedule. */ struct LGRSChunkHandler : ChunkHandler { - LGRSChunkHandler() : ChunkHandler('LGRS', ChunkType::Table) {} + LGRSChunkHandler() : ChunkHandler("LGRS", ChunkType::Table) {} void Save() const override { diff --git a/src/saveload/map_sl.cpp b/src/saveload/map_sl.cpp index e3e423e193..983018da39 100644 --- a/src/saveload/map_sl.cpp +++ b/src/saveload/map_sl.cpp @@ -27,7 +27,7 @@ static const SaveLoad _map_desc[] = { }; struct MAPSChunkHandler : ChunkHandler { - MAPSChunkHandler() : ChunkHandler('MAPS', ChunkType::Table) {} + MAPSChunkHandler() : ChunkHandler("MAPS", ChunkType::Table) {} void Save() const override { @@ -67,7 +67,7 @@ struct MAPSChunkHandler : ChunkHandler { static const uint MAP_SL_BUF_SIZE = 4096; struct MAPTChunkHandler : ChunkHandler { - MAPTChunkHandler() : ChunkHandler('MAPT', ChunkType::Riff) {} + MAPTChunkHandler() : ChunkHandler("MAPT", ChunkType::Riff) {} void Load() const override { @@ -94,7 +94,7 @@ struct MAPTChunkHandler : ChunkHandler { }; struct MAPHChunkHandler : ChunkHandler { - MAPHChunkHandler() : ChunkHandler('MAPH', ChunkType::Riff) {} + MAPHChunkHandler() : ChunkHandler("MAPH", ChunkType::Riff) {} void Load() const override { @@ -121,7 +121,7 @@ struct MAPHChunkHandler : ChunkHandler { }; struct MAPOChunkHandler : ChunkHandler { - MAPOChunkHandler() : ChunkHandler('MAPO', ChunkType::Riff) {} + MAPOChunkHandler() : ChunkHandler("MAPO", ChunkType::Riff) {} void Load() const override { @@ -148,7 +148,7 @@ struct MAPOChunkHandler : ChunkHandler { }; struct MAP2ChunkHandler : ChunkHandler { - MAP2ChunkHandler() : ChunkHandler('MAP2', ChunkType::Riff) {} + MAP2ChunkHandler() : ChunkHandler("MAP2", ChunkType::Riff) {} void Load() const override { @@ -178,7 +178,7 @@ struct MAP2ChunkHandler : ChunkHandler { }; struct M3LOChunkHandler : ChunkHandler { - M3LOChunkHandler() : ChunkHandler('M3LO', ChunkType::Riff) {} + M3LOChunkHandler() : ChunkHandler("M3LO", ChunkType::Riff) {} void Load() const override { @@ -205,7 +205,7 @@ struct M3LOChunkHandler : ChunkHandler { }; struct M3HIChunkHandler : ChunkHandler { - M3HIChunkHandler() : ChunkHandler('M3HI', ChunkType::Riff) {} + M3HIChunkHandler() : ChunkHandler("M3HI", ChunkType::Riff) {} void Load() const override { @@ -232,7 +232,7 @@ struct M3HIChunkHandler : ChunkHandler { }; struct MAP5ChunkHandler : ChunkHandler { - MAP5ChunkHandler() : ChunkHandler('MAP5', ChunkType::Riff) {} + MAP5ChunkHandler() : ChunkHandler("MAP5", ChunkType::Riff) {} void Load() const override { @@ -259,7 +259,7 @@ struct MAP5ChunkHandler : ChunkHandler { }; struct MAPEChunkHandler : ChunkHandler { - MAPEChunkHandler() : ChunkHandler('MAPE', ChunkType::Riff) {} + MAPEChunkHandler() : ChunkHandler("MAPE", ChunkType::Riff) {} void Load() const override { @@ -299,7 +299,7 @@ struct MAPEChunkHandler : ChunkHandler { }; struct MAP7ChunkHandler : ChunkHandler { - MAP7ChunkHandler() : ChunkHandler('MAP7', ChunkType::Riff) {} + MAP7ChunkHandler() : ChunkHandler("MAP7", ChunkType::Riff) {} void Load() const override { @@ -326,7 +326,7 @@ struct MAP7ChunkHandler : ChunkHandler { }; struct MAP8ChunkHandler : ChunkHandler { - MAP8ChunkHandler() : ChunkHandler('MAP8', ChunkType::Riff) {} + MAP8ChunkHandler() : ChunkHandler("MAP8", ChunkType::Riff) {} void Load() const override { diff --git a/src/saveload/misc_sl.cpp b/src/saveload/misc_sl.cpp index 185d5a7a3b..9e2e06350e 100644 --- a/src/saveload/misc_sl.cpp +++ b/src/saveload/misc_sl.cpp @@ -121,7 +121,7 @@ static const SaveLoad _date_check_desc[] = { * @note currently some unrelated stuff is just put here. */ struct DATEChunkHandler : ChunkHandler { - DATEChunkHandler() : ChunkHandler('DATE', ChunkType::Table) {} + DATEChunkHandler() : ChunkHandler("DATE", ChunkType::Table) {} void Save() const override { @@ -165,7 +165,7 @@ static const SaveLoad _view_desc[] = { }; struct VIEWChunkHandler : ChunkHandler { - VIEWChunkHandler() : ChunkHandler('VIEW', ChunkType::Table) {} + VIEWChunkHandler() : ChunkHandler("VIEW", ChunkType::Table) {} void Save() const override { diff --git a/src/saveload/newgrf_sl.cpp b/src/saveload/newgrf_sl.cpp index 9aec5bdeac..1c3b6be6b1 100644 --- a/src/saveload/newgrf_sl.cpp +++ b/src/saveload/newgrf_sl.cpp @@ -62,7 +62,7 @@ void NewGRFMappingChunkHandler::Load() const } struct NGRFChunkHandler : ChunkHandler { - NGRFChunkHandler() : ChunkHandler('NGRF', ChunkType::Table) {} + NGRFChunkHandler() : ChunkHandler("NGRF", ChunkType::Table) {} static inline std::array param; static inline uint8_t num_params; diff --git a/src/saveload/newgrf_sl.h b/src/saveload/newgrf_sl.h index 53db695fa8..7c61e95373 100644 --- a/src/saveload/newgrf_sl.h +++ b/src/saveload/newgrf_sl.h @@ -13,10 +13,16 @@ #include "../newgrf_commons.h" #include "saveload.h" +/** Chunk handler for data of the OverrideManagerBase. */ struct NewGRFMappingChunkHandler : ChunkHandler { - OverrideManagerBase &mapping; + OverrideManagerBase &mapping; ///< The override manager to save/load. - NewGRFMappingChunkHandler(uint32_t id, OverrideManagerBase &mapping) : ChunkHandler(id, ChunkType::Table), mapping(mapping) {} + /** + * Create the handler. + * @param id The identifier of the chunk + * @param mapping The override manager to save/load. + */ + NewGRFMappingChunkHandler(ChunkId id, OverrideManagerBase &mapping) : ChunkHandler(id, ChunkType::Table), mapping(mapping) {} void Save() const override; void Load() const override; }; diff --git a/src/saveload/object_sl.cpp b/src/saveload/object_sl.cpp index f7152255a8..c066bd8d5e 100644 --- a/src/saveload/object_sl.cpp +++ b/src/saveload/object_sl.cpp @@ -30,7 +30,7 @@ static const SaveLoad _object_desc[] = { }; struct OBJSChunkHandler : ChunkHandler { - OBJSChunkHandler() : ChunkHandler('OBJS', ChunkType::Table) {} + OBJSChunkHandler() : ChunkHandler("OBJS", ChunkType::Table) {} void Save() const override { @@ -67,7 +67,7 @@ struct OBJSChunkHandler : ChunkHandler { }; struct OBIDChunkHandler : NewGRFMappingChunkHandler { - OBIDChunkHandler() : NewGRFMappingChunkHandler('OBID', _object_mngr) {} + OBIDChunkHandler() : NewGRFMappingChunkHandler("OBID", _object_mngr) {} }; static const OBIDChunkHandler OBID; diff --git a/src/saveload/order_sl.cpp b/src/saveload/order_sl.cpp index 0e7ca32dbd..810978298f 100644 --- a/src/saveload/order_sl.cpp +++ b/src/saveload/order_sl.cpp @@ -159,7 +159,7 @@ SaveLoadTable GetOrderDescription() } struct ORDRChunkHandler : ChunkHandler { - ORDRChunkHandler() : ChunkHandler('ORDR', ChunkType::ReadOnly) {} + ORDRChunkHandler() : ChunkHandler("ORDR", ChunkType::ReadOnly) {} void Load() const override { @@ -249,7 +249,7 @@ SaveLoadTable GetOrderListDescription() } struct ORDLChunkHandler : ChunkHandler { - ORDLChunkHandler() : ChunkHandler('ORDL', ChunkType::Table) {} + ORDLChunkHandler() : ChunkHandler("ORDL", ChunkType::Table) {} void Save() const override { @@ -320,7 +320,7 @@ SaveLoadTable GetOrderBackupDescription() } struct BKORChunkHandler : ChunkHandler { - BKORChunkHandler() : ChunkHandler('BKOR', ChunkType::Table) {} + BKORChunkHandler() : ChunkHandler("BKOR", ChunkType::Table) {} void Save() const override { diff --git a/src/saveload/randomizer_sl.cpp b/src/saveload/randomizer_sl.cpp index 53c849aee0..da7fd82aa1 100644 --- a/src/saveload/randomizer_sl.cpp +++ b/src/saveload/randomizer_sl.cpp @@ -19,7 +19,7 @@ static const SaveLoad _randomizer_desc[] = { }; struct SRNDChunkHandler : ChunkHandler { - SRNDChunkHandler() : ChunkHandler('SRND', ChunkType::Table) + SRNDChunkHandler() : ChunkHandler("SRND", ChunkType::Table) {} void Save() const override diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index 3f82736ecd..51490db732 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -458,6 +458,17 @@ static inline void SlWriteUint64(uint64_t x) SlWriteUint32(static_cast(x)); } +/** + * Read the \c ChunkId. + * @return The read \c ChunkId. + */ +static inline ChunkId SlReadChunkId() +{ + ChunkId label{}; + for (uint8_t &b : label) b = SlReadByte(); + return label; +} + /** * Read in the header descriptor of an object or an array. * If the highest bit is set (7), then the index is bigger than 127 @@ -2275,7 +2286,7 @@ static void SlSaveChunk(const ChunkHandler &ch) { if (ch.type == ChunkType::ReadOnly) return; - SlWriteUint32(ch.id); + for (uint8_t b : ch.id) SlWriteByte(b); Debug(sl, 2, "Saving chunk {}", ch.GetName()); _sl.chunk_type = ch.type; @@ -2323,7 +2334,7 @@ static void SlSaveChunks() * @param id the chunk in question * @return returns the appropriate chunkhandler */ -static const ChunkHandler *SlFindChunkHandler(uint32_t id) +static const ChunkHandler *SlFindChunkHandler(ChunkId id) { for (const ChunkHandler &ch : ChunkHandlers()) if (ch.id == id) return &ch; return nullptr; @@ -2332,13 +2343,10 @@ static const ChunkHandler *SlFindChunkHandler(uint32_t id) /** Load all chunks */ static void SlLoadChunks() { - uint32_t id; - const ChunkHandler *ch; + for (ChunkId id = SlReadChunkId(); !id.Empty(); id = SlReadChunkId()) { + Debug(sl, 2, "Loading chunk {}", id.AsString()); - for (id = SlReadUint32(); id != 0; id = SlReadUint32()) { - Debug(sl, 2, "Loading chunk {:c}{:c}{:c}{:c}", id >> 24, id >> 16, id >> 8, id); - - ch = SlFindChunkHandler(id); + const ChunkHandler *ch = SlFindChunkHandler(id); if (ch == nullptr) SlErrorCorrupt("Unknown chunk type"); SlLoadChunk(*ch); } @@ -2347,13 +2355,10 @@ static void SlLoadChunks() /** Load all chunks for savegame checking */ static void SlLoadCheckChunks() { - uint32_t id; - const ChunkHandler *ch; + for (ChunkId id = SlReadChunkId(); id.Empty(); id = SlReadChunkId()) { + Debug(sl, 2, "Loading chunk {}", id.AsString()); - for (id = SlReadUint32(); id != 0; id = SlReadUint32()) { - Debug(sl, 2, "Loading chunk {:c}{:c}{:c}{:c}", id >> 24, id >> 16, id >> 8, id); - - ch = SlFindChunkHandler(id); + const ChunkHandler *ch = SlFindChunkHandler(id); if (ch == nullptr) SlErrorCorrupt("Unknown chunk type"); SlLoadCheckChunk(*ch); } diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index 6f60194d53..bd181551ef 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -11,6 +11,7 @@ #define SAVELOAD_H #include "saveload_error.hpp" +#include "../core/label_type.hpp" #include "../fileio_type.h" #include "../fios.h" @@ -479,12 +480,20 @@ enum class ChunkType : uint8_t { ReadOnly, ///< Chunk is never saved. }; +/** Label/unique identifier for each of the chunks in the savegame. */ +using ChunkId = Label;; + /** Handlers and description of chunk. */ struct ChunkHandler { - uint32_t id; ///< Unique ID (4 letters). - ChunkType type; ///< Type of the chunk. @see ChunkType + ChunkId id; ///< Unique ID (4 letters). + ChunkType type; ///< Type of the chunk. @see ChunkType - ChunkHandler(uint32_t id, ChunkType type) : id(id), type(type) {} + /** + * Create this ChunkHandler. + * @param id The unique identifier/name of this chunk. + * @param type The type of chunk + */ + ChunkHandler(ChunkId id, ChunkType type) : id(id), type(type) {} /** Ensure the destructor of the sub classes are called as well. */ virtual ~ChunkHandler() = default; @@ -516,13 +525,13 @@ struct ChunkHandler { */ virtual void LoadCheck(size_t len = 0) const; + /** + * Get the name of this chunk. + * @return The chunks 4 letter name/unique identifier. + */ std::string GetName() const { - return std::string() - + static_cast(this->id >> 24) - + static_cast(this->id >> 16) - + static_cast(this->id >> 8) - + static_cast(this->id); + return this->id.AsString(); } }; diff --git a/src/saveload/settings_sl.cpp b/src/saveload/settings_sl.cpp index 52b6b2f0ee..3e0bb2d5da 100644 --- a/src/saveload/settings_sl.cpp +++ b/src/saveload/settings_sl.cpp @@ -142,7 +142,7 @@ static void SaveSettings(const SettingTable &settings, void *object) } struct OPTSChunkHandler : ChunkHandler { - OPTSChunkHandler() : ChunkHandler('OPTS', ChunkType::ReadOnly) {} + OPTSChunkHandler() : ChunkHandler("OPTS", ChunkType::ReadOnly) {} void Load() const override { @@ -156,7 +156,7 @@ struct OPTSChunkHandler : ChunkHandler { }; struct PATSChunkHandler : ChunkHandler { - PATSChunkHandler() : ChunkHandler('PATS', ChunkType::Table) {} + PATSChunkHandler() : ChunkHandler("PATS", ChunkType::Table) {} void Load() const override { diff --git a/src/saveload/signs_sl.cpp b/src/saveload/signs_sl.cpp index c94e8bd465..189651cd4a 100644 --- a/src/saveload/signs_sl.cpp +++ b/src/saveload/signs_sl.cpp @@ -32,7 +32,7 @@ static const SaveLoad _sign_desc[] = { }; struct SIGNChunkHandler : ChunkHandler { - SIGNChunkHandler() : ChunkHandler('SIGN', ChunkType::Table) {} + SIGNChunkHandler() : ChunkHandler("SIGN", ChunkType::Table) {} void Save() const override { diff --git a/src/saveload/station_sl.cpp b/src/saveload/station_sl.cpp index 13239bdf84..4074627c49 100644 --- a/src/saveload/station_sl.cpp +++ b/src/saveload/station_sl.cpp @@ -531,7 +531,7 @@ static const SaveLoad _old_station_desc[] = { }; struct STNSChunkHandler : ChunkHandler { - STNSChunkHandler() : ChunkHandler('STNS', ChunkType::ReadOnly) {} + STNSChunkHandler() : ChunkHandler("STNS", ChunkType::ReadOnly) {} void Load() const override { @@ -722,7 +722,7 @@ static const SaveLoad _station_desc[] = { }; struct STNNChunkHandler : ChunkHandler { - STNNChunkHandler() : ChunkHandler('STNN', ChunkType::Table) {} + STNNChunkHandler() : ChunkHandler("STNN", ChunkType::Table) {} void Save() const override { @@ -765,7 +765,7 @@ struct STNNChunkHandler : ChunkHandler { }; struct ROADChunkHandler : ChunkHandler { - ROADChunkHandler() : ChunkHandler('ROAD', ChunkType::Table) {} + ROADChunkHandler() : ChunkHandler("ROAD", ChunkType::Table) {} void Save() const override { diff --git a/src/saveload/storage_sl.cpp b/src/saveload/storage_sl.cpp index eb0e3d048f..cb29bd0acb 100644 --- a/src/saveload/storage_sl.cpp +++ b/src/saveload/storage_sl.cpp @@ -25,7 +25,7 @@ static const SaveLoad _storage_desc[] = { /** Persistent storage data. */ struct PSACChunkHandler : ChunkHandler { - PSACChunkHandler() : ChunkHandler('PSAC', ChunkType::Table) {} + PSACChunkHandler() : ChunkHandler("PSAC", ChunkType::Table) {} void Load() const override { diff --git a/src/saveload/story_sl.cpp b/src/saveload/story_sl.cpp index 0eee548d3d..7669419189 100644 --- a/src/saveload/story_sl.cpp +++ b/src/saveload/story_sl.cpp @@ -39,7 +39,7 @@ static const SaveLoad _story_page_elements_desc[] = { }; struct STPEChunkHandler : ChunkHandler { - STPEChunkHandler() : ChunkHandler('STPE', ChunkType::Table) {} + STPEChunkHandler() : ChunkHandler("STPE", ChunkType::Table) {} void Save() const override { @@ -81,7 +81,7 @@ static const SaveLoad _story_pages_desc[] = { }; struct STPAChunkHandler : ChunkHandler { - STPAChunkHandler() : ChunkHandler('STPA', ChunkType::Table) {} + STPAChunkHandler() : ChunkHandler("STPA", ChunkType::Table) {} void Save() const override { diff --git a/src/saveload/strings_sl.cpp b/src/saveload/strings_sl.cpp index ef7a16bde6..aa91ec1da5 100644 --- a/src/saveload/strings_sl.cpp +++ b/src/saveload/strings_sl.cpp @@ -111,7 +111,7 @@ void InitializeOldNames() } struct NAMEChunkHandler : ChunkHandler { - NAMEChunkHandler() : ChunkHandler('NAME', ChunkType::ReadOnly) {} + NAMEChunkHandler() : ChunkHandler("NAME", ChunkType::ReadOnly) {} void Load() const override { diff --git a/src/saveload/subsidy_sl.cpp b/src/saveload/subsidy_sl.cpp index b724858286..89fc9188c9 100644 --- a/src/saveload/subsidy_sl.cpp +++ b/src/saveload/subsidy_sl.cpp @@ -30,7 +30,7 @@ static const SaveLoad _subsidies_desc[] = { }; struct SUBSChunkHandler : ChunkHandler { - SUBSChunkHandler() : ChunkHandler('SUBS', ChunkType::Table) {} + SUBSChunkHandler() : ChunkHandler("SUBS", ChunkType::Table) {} void Save() const override { diff --git a/src/saveload/town_sl.cpp b/src/saveload/town_sl.cpp index cc10235861..3cbde2823d 100644 --- a/src/saveload/town_sl.cpp +++ b/src/saveload/town_sl.cpp @@ -370,11 +370,11 @@ static const SaveLoad _town_desc[] = { }; struct HIDSChunkHandler : NewGRFMappingChunkHandler { - HIDSChunkHandler() : NewGRFMappingChunkHandler('HIDS', _house_mngr) {} + HIDSChunkHandler() : NewGRFMappingChunkHandler("HIDS", _house_mngr) {} }; struct CITYChunkHandler : ChunkHandler { - CITYChunkHandler() : ChunkHandler('CITY', ChunkType::Table) {} + CITYChunkHandler() : ChunkHandler("CITY", ChunkType::Table) {} void Save() const override { diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp index b66d559e10..1bd600cc2c 100644 --- a/src/saveload/vehicle_sl.cpp +++ b/src/saveload/vehicle_sl.cpp @@ -1114,7 +1114,7 @@ static const SaveLoad _vehicle_desc[] = { }; struct VEHSChunkHandler : ChunkHandler { - VEHSChunkHandler() : ChunkHandler('VEHS', ChunkType::SparseTable) {} + VEHSChunkHandler() : ChunkHandler("VEHS", ChunkType::SparseTable) {} void Save() const override { diff --git a/src/saveload/water_regions_sl.cpp b/src/saveload/water_regions_sl.cpp index b0e4ec3f1c..7c771c361e 100644 --- a/src/saveload/water_regions_sl.cpp +++ b/src/saveload/water_regions_sl.cpp @@ -17,7 +17,7 @@ extern void SlSkipArray(); /** Water Region savegame data is no longer used, but still needed for old savegames to load without errors. */ struct WaterRegionChunkHandler : ChunkHandler { - WaterRegionChunkHandler() : ChunkHandler('WRGN', ChunkType::ReadOnly) + WaterRegionChunkHandler() : ChunkHandler("WRGN", ChunkType::ReadOnly) {} void Load() const override diff --git a/src/saveload/waypoint_sl.cpp b/src/saveload/waypoint_sl.cpp index f106220434..40167cf4a5 100644 --- a/src/saveload/waypoint_sl.cpp +++ b/src/saveload/waypoint_sl.cpp @@ -186,7 +186,7 @@ static const SaveLoad _old_waypoint_desc[] = { }; struct CHKPChunkHandler : ChunkHandler { - CHKPChunkHandler() : ChunkHandler('CHKP', ChunkType::ReadOnly) {} + CHKPChunkHandler() : ChunkHandler("CHKP", ChunkType::ReadOnly) {} void Load() const override {