mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2026-07-15 15:19:52 +00:00
Compare commits
4 Commits
6b553caa74
...
1d1c603494
| Author | SHA1 | Date | |
|---|---|---|---|
| 1d1c603494 | |||
| af60d6b7cd | |||
| fe31736981 | |||
| 80d0c7763a |
@@ -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
|
||||
|
||||
@@ -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 <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
|
||||
*/
|
||||
|
||||
/** @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<const char *>(this->data()), this->size()};
|
||||
}
|
||||
|
||||
return FormatArrayAsHex(*this);
|
||||
}
|
||||
@@ -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 <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
|
||||
*/
|
||||
|
||||
/** @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<uint8_t, 4> {
|
||||
/**
|
||||
* 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 <typename Tag>
|
||||
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<Tag> &other) const = default;
|
||||
};
|
||||
|
||||
#endif /* LABEL_TYPE_HPP */
|
||||
@@ -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<ObjectSpec>();
|
||||
@@ -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<ObjectClass::GlobalID>());
|
||||
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);
|
||||
|
||||
@@ -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<RoadStopSpec>();
|
||||
}
|
||||
|
||||
uint32_t classid = buf.ReadDWord();
|
||||
rs->class_index = RoadStopClass::Allocate(std::byteswap(classid));
|
||||
rs->class_index = RoadStopClass::Allocate(buf.ReadLabel<RoadStopClass::GlobalID>());
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x09: // Road stop type
|
||||
rs->stop_type = (RoadStopAvailabilityType)buf.ReadByte();
|
||||
|
||||
@@ -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<StationSpec>();
|
||||
}
|
||||
|
||||
/* 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<StationClass::GlobalID>());
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x09: { // Define sprite layout
|
||||
uint16_t tiles = buf.ReadExtendedByte();
|
||||
|
||||
@@ -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 <typename T> requires std::is_base_of_v<BaseLabel, T>
|
||||
T ReadLabel()
|
||||
{
|
||||
T label{};
|
||||
std::ranges::copy(this->consumer.Read(label.size()), label.data());
|
||||
return label;
|
||||
}
|
||||
|
||||
size_t Remaining() const
|
||||
{
|
||||
return this->consumer.GetBytesLeft();
|
||||
|
||||
@@ -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 <>
|
||||
|
||||
+11
-5
@@ -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<NewGRFClass<Tspec, Tindex>>; ///< 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();
|
||||
|
||||
@@ -29,7 +29,7 @@ void NewGRFClass<Tspec, Tindex>::Reset()
|
||||
* second time, this first allocation will be given.
|
||||
*/
|
||||
template <typename Tspec, typename Tindex>
|
||||
Tindex NewGRFClass<Tspec, Tindex>::Allocate(uint32_t global_id)
|
||||
Tindex NewGRFClass<Tspec, Tindex>::Allocate(GlobalID global_id)
|
||||
{
|
||||
auto found = std::ranges::find(NewGRFClass::classes, global_id, &NewGRFClass::global_id);
|
||||
|
||||
|
||||
@@ -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 <>
|
||||
|
||||
@@ -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<uint16_t, struct RoadStopClassIDTag, UINT16_MAX, UINT16_MAX>;
|
||||
|
||||
@@ -164,6 +161,9 @@ struct RoadStopSpec : NewGRFSpecBase<RoadStopClassID> {
|
||||
|
||||
using RoadStopClass = NewGRFClass<RoadStopSpec, RoadStopClassID>;
|
||||
|
||||
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<SpriteLayoutProcessor> GetRoadStopLayout(TileInfo *ti, const RoadStopSpec *spec, BaseStation *st, StationType type, int view, std::span<int32_t> 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 */
|
||||
|
||||
@@ -98,9 +98,6 @@ struct StationResolverObject : public SpecializedResolverObject<StationRandomTri
|
||||
uint32_t GetDebugID() const override;
|
||||
};
|
||||
|
||||
static const uint32_t STATION_CLASS_LABEL_DEFAULT = 'DFLT';
|
||||
static const uint32_t STATION_CLASS_LABEL_WAYPOINT = 'WAYP';
|
||||
|
||||
/** Class IDs for stations. */
|
||||
using StationClassID = PoolID<uint16_t, struct StationClassIDTag, UINT16_MAX, UINT16_MAX>;
|
||||
|
||||
@@ -188,6 +185,9 @@ struct StationSpec : NewGRFSpecBase<StationClassID> {
|
||||
/** Class containing information relating to station classes. */
|
||||
using StationClass = NewGRFClass<StationSpec, StationClassID>;
|
||||
|
||||
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. */
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -143,7 +143,7 @@ SaveLoadTable GetCargoPacketDesc()
|
||||
}
|
||||
|
||||
struct CAPAChunkHandler : ChunkHandler {
|
||||
CAPAChunkHandler() : ChunkHandler('CAPA', ChunkType::Table) {}
|
||||
CAPAChunkHandler() : ChunkHandler("CAPA", ChunkType::Table) {}
|
||||
|
||||
void Save() const override
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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<RailTypeLabel>, 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<RoadTypeLabel>, label, VarTypes::U32),
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
+11
-11
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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<uint32_t, GRFConfig::MAX_NUM_PARAMS> param;
|
||||
static inline uint8_t num_params;
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
+38
-25
@@ -458,6 +458,17 @@ static inline void SlWriteUint64(uint64_t x)
|
||||
SlWriteUint32(static_cast<uint32_t>(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);
|
||||
}
|
||||
@@ -2814,23 +2819,26 @@ struct LZMASaveFilter : SaveFilter {
|
||||
************* END OF CODE *****************
|
||||
*******************************************/
|
||||
|
||||
/** Unique 4-letter tag for the different saveload formats. */
|
||||
using SaveLoadFormatTag = Label<struct SaveLoadFormatLabelTag>;
|
||||
|
||||
/** The format for a reader/writer type of a savegame */
|
||||
struct SaveLoadFormat {
|
||||
std::shared_ptr<LoadFilter> (*init_load)(std::shared_ptr<LoadFilter> chain); ///< Constructor for the load filter.
|
||||
std::shared_ptr<SaveFilter> (*init_write)(std::shared_ptr<SaveFilter> chain, uint8_t compression); ///< Constructor for the save filter.
|
||||
|
||||
std::string_view name; ///< name of the compressor/decompressor (debug-only)
|
||||
uint32_t tag; ///< the 4-letter tag by which it is identified in the savegame
|
||||
SaveLoadFormatTag tag; ///< the 4-letter tag by which it is identified in the savegame
|
||||
|
||||
uint8_t min_compression; ///< the minimum compression level of this format
|
||||
uint8_t default_compression; ///< the default compression level of this format
|
||||
uint8_t max_compression; ///< the maximum compression level of this format
|
||||
};
|
||||
|
||||
static const uint32_t SAVEGAME_TAG_LZO = TO_BE32('OTTD');
|
||||
static const uint32_t SAVEGAME_TAG_NONE = TO_BE32('OTTN');
|
||||
static const uint32_t SAVEGAME_TAG_ZLIB = TO_BE32('OTTZ');
|
||||
static const uint32_t SAVEGAME_TAG_LZMA = TO_BE32('OTTX');
|
||||
static const SaveLoadFormatTag SAVEGAME_TAG_LZO{"OTTD"}; ///< Tag for a game compressed with LZO
|
||||
static const SaveLoadFormatTag SAVEGAME_TAG_NONE{"OTTN"}; ///< Tag for a game without compression.
|
||||
static const SaveLoadFormatTag SAVEGAME_TAG_ZLIB{"OTTZ"}; ///< Tag for a game with zlib compression.
|
||||
static const SaveLoadFormatTag SAVEGAME_TAG_LZMA{"OTTX"}; ///< Tag for a game with lzma compression.
|
||||
|
||||
/** The different saveload formats known/understood by OpenTTD. */
|
||||
static const SaveLoadFormat _saveload_formats[] = {
|
||||
@@ -3025,8 +3033,10 @@ static SaveLoadResult SaveFileToDisk(bool threaded)
|
||||
auto [fmt, compression] = GetSavegameFormat(_savegame_format);
|
||||
|
||||
/* We have written our stuff to memory, now write it to file! */
|
||||
uint32_t hdr[2] = { fmt.tag, TO_BE32(to_underlying(SAVEGAME_VERSION) << 16) };
|
||||
_sl.sf->Write((uint8_t*)hdr, sizeof(hdr));
|
||||
_sl.sf->Write(fmt.tag.data(), fmt.tag.size());
|
||||
|
||||
uint32_t version = TO_BE32(to_underlying(SAVEGAME_VERSION) << 16);
|
||||
_sl.sf->Write(reinterpret_cast<uint8_t *>(&version), sizeof(version));
|
||||
|
||||
_sl.sf = fmt.init_write(_sl.sf, compression);
|
||||
_sl.dumper->Flush(_sl.sf);
|
||||
@@ -3126,7 +3136,7 @@ SaveLoadResult SaveWithFilter(std::shared_ptr<SaveFilter> writer, bool threaded)
|
||||
* @param raw_version The raw version from the savegame header.
|
||||
* @return The SaveLoadFormat to use for attempting to open the savegame.
|
||||
*/
|
||||
static const SaveLoadFormat *DetermineSaveLoadFormat(uint32_t tag, uint32_t raw_version)
|
||||
static const SaveLoadFormat *DetermineSaveLoadFormat(SaveLoadFormatTag tag, uint32_t raw_version)
|
||||
{
|
||||
auto fmt = std::ranges::find(_saveload_formats, tag, &SaveLoadFormat::tag);
|
||||
if (fmt != std::end(_saveload_formats)) {
|
||||
@@ -3178,11 +3188,14 @@ static SaveLoadResult DoLoad(std::shared_ptr<LoadFilter> reader, bool load_check
|
||||
_load_check_data.checkable = true;
|
||||
}
|
||||
|
||||
uint32_t hdr[2];
|
||||
if (_sl.lf->Read((uint8_t*)hdr, sizeof(hdr)) != sizeof(hdr)) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
|
||||
SaveLoadFormatTag tag{};
|
||||
if (_sl.lf->Read(tag.data(), tag.size()) != tag.size()) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
|
||||
|
||||
uint32_t version;
|
||||
if (_sl.lf->Read(reinterpret_cast<uint8_t*>(&version), sizeof(version)) != sizeof(version)) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
|
||||
|
||||
/* see if we have any loader for this type. */
|
||||
const SaveLoadFormat *fmt = DetermineSaveLoadFormat(hdr[0], hdr[1]);
|
||||
const SaveLoadFormat *fmt = DetermineSaveLoadFormat(tag, version);
|
||||
|
||||
/* loader for this savegame type is not implemented? */
|
||||
if (fmt->init_load == nullptr) {
|
||||
|
||||
+17
-8
@@ -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<struct ChunkIdTag>;;
|
||||
|
||||
/** 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<char>(this->id >> 24)
|
||||
+ static_cast<char>(this->id >> 16)
|
||||
+ static_cast<char>(this->id >> 8)
|
||||
+ static_cast<char>(this->id);
|
||||
return this->id.AsString();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -111,7 +111,7 @@ void InitializeOldNames()
|
||||
}
|
||||
|
||||
struct NAMEChunkHandler : ChunkHandler {
|
||||
NAMEChunkHandler() : ChunkHandler('NAME', ChunkType::ReadOnly) {}
|
||||
NAMEChunkHandler() : ChunkHandler("NAME", ChunkType::ReadOnly) {}
|
||||
|
||||
void Load() const override
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
+20
-5
@@ -8,6 +8,7 @@
|
||||
/** @file soundloader_wav.cpp Loading of wav sounds. */
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "core/label_type.hpp"
|
||||
#include "core/math_func.hpp"
|
||||
#include "debug.h"
|
||||
#include "random_access_file_type.h"
|
||||
@@ -16,6 +17,20 @@
|
||||
|
||||
#include "safeguards.h"
|
||||
|
||||
using WavTag = Label<struct WavTagTag>; ///< Label for different tags in the file
|
||||
|
||||
/**
|
||||
* Read a \c WavTag from the file.
|
||||
* @param file The file to read from.
|
||||
* @return The read \c WavTag.
|
||||
*/
|
||||
WavTag ReadWavTag(RandomAccessFile &file)
|
||||
{
|
||||
WavTag tag;
|
||||
file.ReadBlock(tag.data(), tag.size());
|
||||
return tag;
|
||||
}
|
||||
|
||||
/** Wav file (RIFF/WAVE) sound loader. */
|
||||
class SoundLoader_Wav : public SoundLoader {
|
||||
public:
|
||||
@@ -28,16 +43,16 @@ public:
|
||||
RandomAccessFile &file = *sound.file;
|
||||
|
||||
/* Check RIFF/WAVE header. */
|
||||
if (file.ReadDword() != std::byteswap<uint32_t>('RIFF')) return false;
|
||||
if (ReadWavTag(file) != WavTag{"RIFF"}) return false;
|
||||
file.ReadDword(); // Skip data size
|
||||
if (file.ReadDword() != std::byteswap<uint32_t>('WAVE')) return false;
|
||||
if (ReadWavTag(file) != WavTag{"WAVE"}) return false;
|
||||
|
||||
/* Read riff tags */
|
||||
for (;;) {
|
||||
uint32_t tag = file.ReadDword();
|
||||
WavTag tag = ReadWavTag(file);
|
||||
uint32_t size = file.ReadDword();
|
||||
|
||||
if (tag == std::byteswap<uint32_t>('fmt ')) {
|
||||
if (tag == WavTag{"fmt "}) {
|
||||
uint16_t format = file.ReadWord();
|
||||
if (format != 1) {
|
||||
Debug(grf, 0, "SoundLoader_Wav: Unsupported format {}, expected 1 (uncompressed PCM).", format);
|
||||
@@ -64,7 +79,7 @@ public:
|
||||
|
||||
/* We've read 16 bytes of this chunk, we can skip anything extra. */
|
||||
size -= 16;
|
||||
} else if (tag == std::byteswap<uint32_t>('data')) {
|
||||
} else if (tag == WavTag{"data"}) {
|
||||
uint align = sound.channels * sound.bits_per_sample / 8;
|
||||
if (Align(size, align) != size) {
|
||||
/* Ensure length is aligned correctly for channels and BPS. */
|
||||
|
||||
Reference in New Issue
Block a user