diff --git a/src/newgrf/newgrf_act0_objects.cpp b/src/newgrf/newgrf_act0_objects.cpp index a4478d5413..376825ad18 100644 --- a/src/newgrf/newgrf_act0_objects.cpp +++ b/src/newgrf/newgrf_act0_objects.cpp @@ -96,7 +96,7 @@ static ChangeInfoResult ObjectChangeInfo(uint first, uint last, int prop, ByteRe } switch (prop) { - case 0x08: { // Class ID + case 0x08: // Class ID /* Allocate space for this object. */ if (spec == nullptr) { spec = std::make_unique(); @@ -104,16 +104,12 @@ static ChangeInfoResult ObjectChangeInfo(uint first, uint last, int prop, ByteRe spec->size = OBJECT_SIZE_1X1; // Default for NewGRFs that manage to not set it (1x1) } - /* Swap classid because we read it in BE. */ - uint32_t classid = buf.ReadDWord(); - spec->class_index = ObjectClass::Allocate(std::byteswap(classid)); + spec->class_index = ObjectClass::Allocate(buf.ReadLabel()); break; - } - case 0x09: { // Class name + case 0x09: // Class name AddStringForMapping(GRFStringID{buf.ReadWord()}, [spec = spec.get()](StringID str) { ObjectClass::Get(spec->class_index)->name = str; }); break; - } case 0x0A: // Object name AddStringForMapping(GRFStringID{buf.ReadWord()}, &spec->name); diff --git a/src/newgrf/newgrf_act0_roadstops.cpp b/src/newgrf/newgrf_act0_roadstops.cpp index 7513223b3a..2e637b745f 100644 --- a/src/newgrf/newgrf_act0_roadstops.cpp +++ b/src/newgrf/newgrf_act0_roadstops.cpp @@ -88,15 +88,13 @@ static ChangeInfoResult RoadStopChangeInfo(uint first, uint last, int prop, Byte } switch (prop) { - case 0x08: { // Road Stop Class ID + case 0x08: // Road Stop Class ID if (rs == nullptr) { rs = std::make_unique(); } - uint32_t classid = buf.ReadDWord(); - rs->class_index = RoadStopClass::Allocate(std::byteswap(classid)); + rs->class_index = RoadStopClass::Allocate(buf.ReadLabel()); break; - } case 0x09: // Road stop type rs->stop_type = (RoadStopAvailabilityType)buf.ReadByte(); diff --git a/src/newgrf/newgrf_act0_stations.cpp b/src/newgrf/newgrf_act0_stations.cpp index ba0d9b7c82..8643b25b52 100644 --- a/src/newgrf/newgrf_act0_stations.cpp +++ b/src/newgrf/newgrf_act0_stations.cpp @@ -49,17 +49,14 @@ static ChangeInfoResult StationChangeInfo(uint first, uint last, int prop, ByteR } switch (prop) { - case 0x08: { // Class ID + case 0x08: // Class ID /* Property 0x08 is special; it is where the station is allocated */ if (statspec == nullptr) { statspec = std::make_unique(); } - /* Swap classid because we read it in BE meaning WAYP or DFLT */ - uint32_t classid = buf.ReadDWord(); - statspec->class_index = StationClass::Allocate(std::byteswap(classid)); + statspec->class_index = StationClass::Allocate(buf.ReadLabel()); break; - } case 0x09: { // Define sprite layout uint16_t tiles = buf.ReadExtendedByte(); diff --git a/src/newgrf/newgrf_bytereader.h b/src/newgrf/newgrf_bytereader.h index 73898886e3..8f3db0eb6f 100644 --- a/src/newgrf/newgrf_bytereader.h +++ b/src/newgrf/newgrf_bytereader.h @@ -10,6 +10,7 @@ #ifndef NEWGRF_BYTEREADER_H #define NEWGRF_BYTEREADER_H +#include "../core/label_type.hpp" #include "../core/string_consumer.hpp" class OTTDByteReaderSignal { }; @@ -94,6 +95,18 @@ public: return this->consumer.ReadUntilChar('\0', StringConsumer::SKIP_ONE_SEPARATOR); } + /** + * Read a label. + * @return The read label. + */ + template requires std::is_base_of_v + T ReadLabel() + { + T label{}; + std::ranges::copy(this->consumer.Read(label.size()), label.data()); + return label; + } + size_t Remaining() const { return this->consumer.GetBytesLeft(); diff --git a/src/newgrf_airport.cpp b/src/newgrf_airport.cpp index 32d35581c0..4c00608f8d 100644 --- a/src/newgrf_airport.cpp +++ b/src/newgrf_airport.cpp @@ -30,10 +30,10 @@ template <> /* static */ void AirportClass::InsertDefaults() { - AirportClass::Get(AirportClass::Allocate('SMAL'))->name = STR_AIRPORT_CLASS_SMALL; - AirportClass::Get(AirportClass::Allocate('LARG'))->name = STR_AIRPORT_CLASS_LARGE; - AirportClass::Get(AirportClass::Allocate('HUB_'))->name = STR_AIRPORT_CLASS_HUB; - AirportClass::Get(AirportClass::Allocate('HELI'))->name = STR_AIRPORT_CLASS_HELIPORTS; + AirportClass::Get(AirportClass::Allocate("SMAL"))->name = STR_AIRPORT_CLASS_SMALL; + AirportClass::Get(AirportClass::Allocate("LARG"))->name = STR_AIRPORT_CLASS_LARGE; + AirportClass::Get(AirportClass::Allocate("HUB_"))->name = STR_AIRPORT_CLASS_HUB; + AirportClass::Get(AirportClass::Allocate("HELI"))->name = STR_AIRPORT_CLASS_HELIPORTS; } template <> diff --git a/src/newgrf_class.h b/src/newgrf_class.h index 2cdbeebc4b..6818d3a6a6 100644 --- a/src/newgrf_class.h +++ b/src/newgrf_class.h @@ -10,6 +10,7 @@ #ifndef NEWGRF_CLASS_H #define NEWGRF_CLASS_H +#include "core/label_type.hpp" #include "newgrf_type.h" #include "strings_type.h" @@ -45,12 +46,17 @@ private: public: using spec_type = Tspec; using index_type = Tindex; + using GlobalID = Label>; ///< Type for the global identifier of the class. - uint32_t global_id; ///< Global ID for class, e.g. 'DFLT', 'WAYP', etc. - StringID name; ///< Name of this class. + GlobalID global_id; ///< Global ID for class, e.g. 'DFLT', 'WAYP', etc. + StringID name; ///< Name of this class. - /* Public constructor as emplace_back needs access. */ - NewGRFClass(uint32_t global_id, StringID name) : global_id(global_id), name(name) { } + /** + * Create the class. + * @param global_id The globally unique identifier of the class. + * @param name The name of the class. + */ + NewGRFClass(GlobalID global_id, StringID name) : global_id(global_id), name(name) { } /** * Get read-only span of specs of this class. @@ -90,7 +96,7 @@ public: bool IsUIAvailable(uint index) const; static void Reset(); - static Tindex Allocate(uint32_t global_id); + static Tindex Allocate(GlobalID global_id); static void Assign(Tspec *spec); static uint GetClassCount(); static uint GetUIClassCount(); diff --git a/src/newgrf_class_func.h b/src/newgrf_class_func.h index 40bf3efeda..2e4f69f0b9 100644 --- a/src/newgrf_class_func.h +++ b/src/newgrf_class_func.h @@ -29,7 +29,7 @@ void NewGRFClass::Reset() * second time, this first allocation will be given. */ template -Tindex NewGRFClass::Allocate(uint32_t global_id) +Tindex NewGRFClass::Allocate(GlobalID global_id) { auto found = std::ranges::find(NewGRFClass::classes, global_id, &NewGRFClass::global_id); diff --git a/src/newgrf_object.cpp b/src/newgrf_object.cpp index 88ed1ab64d..5a1f1742cd 100644 --- a/src/newgrf_object.cpp +++ b/src/newgrf_object.cpp @@ -136,8 +136,8 @@ void ResetObjects() } /* Set class for originals. */ - _object_specs[OBJECT_LIGHTHOUSE].class_index = ObjectClass::Allocate('LTHS'); - _object_specs[OBJECT_TRANSMITTER].class_index = ObjectClass::Allocate('TRNS'); + _object_specs[OBJECT_LIGHTHOUSE].class_index = ObjectClass::Allocate("LTHS"); + _object_specs[OBJECT_TRANSMITTER].class_index = ObjectClass::Allocate("TRNS"); /* Reset any overrides that have been set. */ _object_mngr.ResetOverride(); @@ -146,8 +146,8 @@ void ResetObjects() template <> /* static */ void ObjectClass::InsertDefaults() { - ObjectClass::Get(ObjectClass::Allocate('LTHS'))->name = STR_OBJECT_CLASS_LTHS; - ObjectClass::Get(ObjectClass::Allocate('TRNS'))->name = STR_OBJECT_CLASS_TRNS; + ObjectClass::Get(ObjectClass::Allocate("LTHS"))->name = STR_OBJECT_CLASS_LTHS; + ObjectClass::Get(ObjectClass::Allocate("TRNS"))->name = STR_OBJECT_CLASS_TRNS; } template <> diff --git a/src/newgrf_roadstop.h b/src/newgrf_roadstop.h index daaaed749b..ced5f05c0d 100644 --- a/src/newgrf_roadstop.h +++ b/src/newgrf_roadstop.h @@ -25,9 +25,6 @@ struct TileInfo; /** The maximum amount of roadstops a single GRF is allowed to add */ static const int NUM_ROADSTOPS_PER_GRF = UINT16_MAX - 1; -static const uint32_t ROADSTOP_CLASS_LABEL_DEFAULT = 'DFLT'; -static const uint32_t ROADSTOP_CLASS_LABEL_WAYPOINT = 'WAYP'; - /** Class IDs for stations. */ using RoadStopClassID = PoolID; @@ -164,6 +161,9 @@ struct RoadStopSpec : NewGRFSpecBase { using RoadStopClass = NewGRFClass; +static const RoadStopClass::GlobalID ROADSTOP_CLASS_LABEL_DEFAULT{"DFLT"}; ///< Class label for default road stops. +static const RoadStopClass::GlobalID ROADSTOP_CLASS_LABEL_WAYPOINT{"WAYP"}; ///< Class label for default road waypoints. + std::optional GetRoadStopLayout(TileInfo *ti, const RoadStopSpec *spec, BaseStation *st, StationType type, int view, std::span regs100 = {}); void DrawRoadStopTile(int x, int y, RoadType roadtype, const RoadStopSpec *spec, StationType type, int view); @@ -191,7 +191,7 @@ void RoadStopUpdateCachedTriggers(BaseStation *st); */ inline bool IsWaypointClass(const RoadStopClass &cls) { - return cls.global_id == ROADSTOP_CLASS_LABEL_WAYPOINT || GB(cls.global_id, 24, 8) == UINT8_MAX; + return cls.global_id == ROADSTOP_CLASS_LABEL_WAYPOINT || cls.global_id[0] == UINT8_MAX; } #endif /* NEWGRF_ROADSTATION_H */ diff --git a/src/newgrf_station.h b/src/newgrf_station.h index b9042eb6bc..26e965174c 100644 --- a/src/newgrf_station.h +++ b/src/newgrf_station.h @@ -98,9 +98,6 @@ struct StationResolverObject : public SpecializedResolverObject; @@ -188,6 +185,9 @@ struct StationSpec : NewGRFSpecBase { /** Class containing information relating to station classes. */ using StationClass = NewGRFClass; +static const StationClass::GlobalID STATION_CLASS_LABEL_DEFAULT{"DFLT"}; ///< Class label for default rail station. +static const StationClass::GlobalID STATION_CLASS_LABEL_WAYPOINT{"WAYP"}; ///< Class label for default rail waypoints. + const StationSpec *GetStationSpec(TileIndex t); /** @@ -208,7 +208,7 @@ inline uint16_t GetStationLayoutKey(uint8_t platforms, uint8_t length) */ inline bool IsWaypointClass(const StationClass &cls) { - return cls.global_id == STATION_CLASS_LABEL_WAYPOINT || GB(cls.global_id, 24, 8) == UINT8_MAX; + return cls.global_id == STATION_CLASS_LABEL_WAYPOINT || cls.global_id[0] == UINT8_MAX; } /* Evaluate a tile's position within a station, and return the result a bitstuffed format. */