summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gamelog.h2
-rw-r--r--src/gamelog_internal.h2
-rw-r--r--src/saveload/gamelog_sl.cpp366
3 files changed, 270 insertions, 100 deletions
diff --git a/src/gamelog.h b/src/gamelog.h
index d9e0dd529..cfa6c626a 100644
--- a/src/gamelog.h
+++ b/src/gamelog.h
@@ -13,7 +13,7 @@
#include "newgrf_config.h"
/** The actions we log. */
-enum GamelogActionType {
+enum GamelogActionType : uint8 {
GLAT_START, ///< Game created
GLAT_LOAD, ///< Game loaded
GLAT_GRF, ///< GRF changed
diff --git a/src/gamelog_internal.h b/src/gamelog_internal.h
index 2b5c6ed0a..fb7c88e48 100644
--- a/src/gamelog_internal.h
+++ b/src/gamelog_internal.h
@@ -13,7 +13,7 @@
#include "gamelog.h"
/** Type of logged change */
-enum GamelogChangeType {
+enum GamelogChangeType : uint8 {
GLCT_MODE, ///< Scenario editor x Game, different landscape
GLCT_REVISION, ///< Changed game revision string
GLCT_OLDVER, ///< Loaded from savegame without logged data
diff --git a/src/saveload/gamelog_sl.cpp b/src/saveload/gamelog_sl.cpp
index 6569954f8..9f7f4f140 100644
--- a/src/saveload/gamelog_sl.cpp
+++ b/src/saveload/gamelog_sl.cpp
@@ -15,147 +15,317 @@
#include "../safeguards.h"
-static const SaveLoad _glog_action_desc[] = {
- SLE_VAR(LoggedAction, tick, SLE_UINT16),
-};
-static const SaveLoad _glog_mode_desc[] = {
- SLE_VAR(LoggedChange, mode.mode, SLE_UINT8),
- SLE_VAR(LoggedChange, mode.landscape, SLE_UINT8),
-};
+class SlGamelogMode : public DefaultSaveLoadHandler<SlGamelogMode, LoggedChange> {
+public:
+ inline static const SaveLoad description[] = {
+ SLE_VAR(LoggedChange, mode.mode, SLE_UINT8),
+ SLE_VAR(LoggedChange, mode.landscape, SLE_UINT8),
+ };
+
+ void GenericSaveLoad(LoggedChange *lc) const
+ {
+ if (lc->ct != GLCT_MODE) return;
+ SlObject(lc, this->GetDescription());
+ }
-static const SaveLoad _glog_revision_desc[] = {
- SLE_ARR(LoggedChange, revision.text, SLE_UINT8, GAMELOG_REVISION_LENGTH),
- SLE_VAR(LoggedChange, revision.newgrf, SLE_UINT32),
- SLE_VAR(LoggedChange, revision.slver, SLE_UINT16),
- SLE_VAR(LoggedChange, revision.modified, SLE_UINT8),
+ void Save(LoggedChange *lc) const override { this->GenericSaveLoad(lc); }
+ void Load(LoggedChange *lc) const override { this->GenericSaveLoad(lc); }
+ void LoadCheck(LoggedChange *lc) const override { this->GenericSaveLoad(lc); }
};
-static const SaveLoad _glog_oldver_desc[] = {
- SLE_VAR(LoggedChange, oldver.type, SLE_UINT32),
- SLE_VAR(LoggedChange, oldver.version, SLE_UINT32),
-};
+class SlGamelogRevision : public DefaultSaveLoadHandler<SlGamelogRevision, LoggedChange> {
+public:
+ inline static const SaveLoad description[] = {
+ SLE_ARR(LoggedChange, revision.text, SLE_UINT8, GAMELOG_REVISION_LENGTH),
+ SLE_VAR(LoggedChange, revision.newgrf, SLE_UINT32),
+ SLE_VAR(LoggedChange, revision.slver, SLE_UINT16),
+ SLE_VAR(LoggedChange, revision.modified, SLE_UINT8),
+ };
+
+ void GenericSaveLoad(LoggedChange *lc) const
+ {
+ if (lc->ct != GLCT_REVISION) return;
+ SlObject(lc, this->GetDescription());
+ }
-static const SaveLoad _glog_setting_desc[] = {
- SLE_STR(LoggedChange, setting.name, SLE_STR, 128),
- SLE_VAR(LoggedChange, setting.oldval, SLE_INT32),
- SLE_VAR(LoggedChange, setting.newval, SLE_INT32),
+ void Save(LoggedChange *lc) const override { this->GenericSaveLoad(lc); }
+ void Load(LoggedChange *lc) const override { this->GenericSaveLoad(lc); }
+ void LoadCheck(LoggedChange *lc) const override { this->GenericSaveLoad(lc); }
};
-static const SaveLoad _glog_grfadd_desc[] = {
- SLE_VAR(LoggedChange, grfadd.grfid, SLE_UINT32 ),
- SLE_ARR(LoggedChange, grfadd.md5sum, SLE_UINT8, 16),
+class SlGamelogOldver : public DefaultSaveLoadHandler<SlGamelogOldver, LoggedChange> {
+public:
+ inline static const SaveLoad description[] = {
+ SLE_VAR(LoggedChange, oldver.type, SLE_UINT32),
+ SLE_VAR(LoggedChange, oldver.version, SLE_UINT32),
+ };
+
+ void GenericSaveLoad(LoggedChange *lc) const
+ {
+ if (lc->ct != GLCT_OLDVER) return;
+ SlObject(lc, this->GetDescription());
+ }
+
+ void Save(LoggedChange *lc) const override { this->GenericSaveLoad(lc); }
+ void Load(LoggedChange *lc) const override { this->GenericSaveLoad(lc); }
+ void LoadCheck(LoggedChange *lc) const override { this->GenericSaveLoad(lc); }
};
-static const SaveLoad _glog_grfrem_desc[] = {
- SLE_VAR(LoggedChange, grfrem.grfid, SLE_UINT32),
+class SlGamelogSetting : public DefaultSaveLoadHandler<SlGamelogSetting, LoggedChange> {
+public:
+ inline static const SaveLoad description[] = {
+ SLE_STR(LoggedChange, setting.name, SLE_STR, 128),
+ SLE_VAR(LoggedChange, setting.oldval, SLE_INT32),
+ SLE_VAR(LoggedChange, setting.newval, SLE_INT32),
+ };
+
+ void GenericSaveLoad(LoggedChange *lc) const
+ {
+ if (lc->ct != GLCT_SETTING) return;
+ SlObject(lc, this->GetDescription());
+ }
+
+ void Save(LoggedChange *lc) const override { this->GenericSaveLoad(lc); }
+ void Load(LoggedChange *lc) const override { this->GenericSaveLoad(lc); }
+ void LoadCheck(LoggedChange *lc) const override { this->GenericSaveLoad(lc); }
};
-static const SaveLoad _glog_grfcompat_desc[] = {
- SLE_VAR(LoggedChange, grfcompat.grfid, SLE_UINT32 ),
- SLE_ARR(LoggedChange, grfcompat.md5sum, SLE_UINT8, 16),
+class SlGamelogGrfadd : public DefaultSaveLoadHandler<SlGamelogGrfadd, LoggedChange> {
+public:
+ inline static const SaveLoad description[] = {
+ SLE_VAR(LoggedChange, grfadd.grfid, SLE_UINT32 ),
+ SLE_ARR(LoggedChange, grfadd.md5sum, SLE_UINT8, 16),
+ };
+
+ void GenericSaveLoad(LoggedChange *lc) const
+ {
+ if (lc->ct != GLCT_GRFADD) return;
+ SlObject(lc, this->GetDescription());
+ }
+
+ void Save(LoggedChange *lc) const override { this->GenericSaveLoad(lc); }
+ void Load(LoggedChange *lc) const override { this->GenericSaveLoad(lc); }
+ void LoadCheck(LoggedChange *lc) const override { this->GenericSaveLoad(lc); }
};
-static const SaveLoad _glog_grfparam_desc[] = {
- SLE_VAR(LoggedChange, grfparam.grfid, SLE_UINT32),
+class SlGamelogGrfrem : public DefaultSaveLoadHandler<SlGamelogGrfrem, LoggedChange> {
+public:
+ inline static const SaveLoad description[] = {
+ SLE_VAR(LoggedChange, grfrem.grfid, SLE_UINT32),
+ };
+
+ void GenericSaveLoad(LoggedChange *lc) const
+ {
+ if (lc->ct != GLCT_GRFREM) return;
+ SlObject(lc, this->GetDescription());
+ }
+
+ void Save(LoggedChange *lc) const override { this->GenericSaveLoad(lc); }
+ void Load(LoggedChange *lc) const override { this->GenericSaveLoad(lc); }
+ void LoadCheck(LoggedChange *lc) const override { this->GenericSaveLoad(lc); }
};
-static const SaveLoad _glog_grfmove_desc[] = {
- SLE_VAR(LoggedChange, grfmove.grfid, SLE_UINT32),
- SLE_VAR(LoggedChange, grfmove.offset, SLE_INT32),
+class SlGamelogGrfcompat : public DefaultSaveLoadHandler<SlGamelogGrfcompat, LoggedChange> {
+public:
+ inline static const SaveLoad description[] = {
+ SLE_VAR(LoggedChange, grfcompat.grfid, SLE_UINT32 ),
+ SLE_ARR(LoggedChange, grfcompat.md5sum, SLE_UINT8, 16),
+ };
+
+ void GenericSaveLoad(LoggedChange *lc) const
+ {
+ if (lc->ct != GLCT_GRFCOMPAT) return;
+ SlObject(lc, this->GetDescription());
+ }
+
+ void Save(LoggedChange *lc) const override { this->GenericSaveLoad(lc); }
+ void Load(LoggedChange *lc) const override { this->GenericSaveLoad(lc); }
+ void LoadCheck(LoggedChange *lc) const override { this->GenericSaveLoad(lc); }
};
-static const SaveLoad _glog_grfbug_desc[] = {
- SLE_VAR(LoggedChange, grfbug.data, SLE_UINT64),
- SLE_VAR(LoggedChange, grfbug.grfid, SLE_UINT32),
- SLE_VAR(LoggedChange, grfbug.bug, SLE_UINT8),
+class SlGamelogGrfparam : public DefaultSaveLoadHandler<SlGamelogGrfparam, LoggedChange> {
+public:
+ inline static const SaveLoad description[] = {
+ SLE_VAR(LoggedChange, grfparam.grfid, SLE_UINT32),
+ };
+
+ void GenericSaveLoad(LoggedChange *lc) const
+ {
+ if (lc->ct != GLCT_GRFPARAM) return;
+ SlObject(lc, this->GetDescription());
+ }
+
+ void Save(LoggedChange *lc) const override { this->GenericSaveLoad(lc); }
+ void Load(LoggedChange *lc) const override { this->GenericSaveLoad(lc); }
+ void LoadCheck(LoggedChange *lc) const override { this->GenericSaveLoad(lc); }
};
-static const SaveLoad _glog_emergency_desc[] = {
- SLE_CONDNULL(0, SL_MIN_VERSION, SL_MIN_VERSION), // Just an empty list, to keep the rest of the code easier.
+class SlGamelogGrfmove : public DefaultSaveLoadHandler<SlGamelogGrfmove, LoggedChange> {
+public:
+ inline static const SaveLoad description[] = {
+ SLE_VAR(LoggedChange, grfmove.grfid, SLE_UINT32),
+ SLE_VAR(LoggedChange, grfmove.offset, SLE_INT32),
+ };
+
+ void GenericSaveLoad(LoggedChange *lc) const
+ {
+ if (lc->ct != GLCT_GRFMOVE) return;
+ SlObject(lc, this->GetDescription());
+ }
+
+ void Save(LoggedChange *lc) const override { this->GenericSaveLoad(lc); }
+ void Load(LoggedChange *lc) const override { this->GenericSaveLoad(lc); }
+ void LoadCheck(LoggedChange *lc) const override { this->GenericSaveLoad(lc); }
};
-static const SaveLoadTable _glog_desc[] = {
- _glog_mode_desc,
- _glog_revision_desc,
- _glog_oldver_desc,
- _glog_setting_desc,
- _glog_grfadd_desc,
- _glog_grfrem_desc,
- _glog_grfcompat_desc,
- _glog_grfparam_desc,
- _glog_grfmove_desc,
- _glog_grfbug_desc,
- _glog_emergency_desc,
+class SlGamelogGrfbug : public DefaultSaveLoadHandler<SlGamelogGrfbug, LoggedChange> {
+public:
+ inline static const SaveLoad description[] = {
+ SLE_VAR(LoggedChange, grfbug.data, SLE_UINT64),
+ SLE_VAR(LoggedChange, grfbug.grfid, SLE_UINT32),
+ SLE_VAR(LoggedChange, grfbug.bug, SLE_UINT8),
+ };
+
+ void GenericSaveLoad(LoggedChange *lc) const
+ {
+ if (lc->ct != GLCT_GRFBUG) return;
+ SlObject(lc, this->GetDescription());
+ }
+
+ void Save(LoggedChange *lc) const override { this->GenericSaveLoad(lc); }
+ void Load(LoggedChange *lc) const override { this->GenericSaveLoad(lc); }
+ void LoadCheck(LoggedChange *lc) const override { this->GenericSaveLoad(lc); }
};
-static_assert(lengthof(_glog_desc) == GLCT_END);
+static bool _is_emergency_save = true;
-static void Load_GLOG_common(LoggedAction *&gamelog_action, uint &gamelog_actions)
-{
- assert(gamelog_action == nullptr);
- assert(gamelog_actions == 0);
+class SlGamelogEmergency : public DefaultSaveLoadHandler<SlGamelogEmergency, LoggedChange> {
+public:
+ /* We need to store something, so store a "true" value. */
+ inline static const SaveLoad description[] = {
+ SLEG_CONDVAR(_is_emergency_save, SLE_BOOL, SLV_RIFF_TO_ARRAY, SL_MAX_VERSION),
+ };
- byte type;
- while ((type = SlReadByte()) != GLAT_NONE) {
- if (type >= GLAT_END) SlErrorCorrupt("Invalid gamelog action type");
- GamelogActionType at = (GamelogActionType)type;
+ void GenericSaveLoad(LoggedChange *lc) const
+ {
+ if (lc->ct != GLCT_EMERGENCY) return;
- gamelog_action = ReallocT(gamelog_action, gamelog_actions + 1);
- LoggedAction *la = &gamelog_action[gamelog_actions++];
+ _is_emergency_save = true;
+ SlObject(lc, this->GetDescription());
+ }
- la->at = at;
+ void Save(LoggedChange *lc) const override { this->GenericSaveLoad(lc); }
+ void Load(LoggedChange *lc) const override { this->GenericSaveLoad(lc); }
+ void LoadCheck(LoggedChange *lc) const override { this->GenericSaveLoad(lc); }
+};
- SlObject(la, _glog_action_desc); // has to be saved after 'DATE'!
- la->change = nullptr;
- la->changes = 0;
+class SlGamelogAction : public DefaultSaveLoadHandler<SlGamelogAction, LoggedAction> {
+public:
+ inline static const SaveLoad description[] = {
+ SLE_SAVEBYTE(LoggedChange, ct),
+ SLEG_STRUCT(SlGamelogMode),
+ SLEG_STRUCT(SlGamelogRevision),
+ SLEG_STRUCT(SlGamelogOldver),
+ SLEG_STRUCT(SlGamelogSetting),
+ SLEG_STRUCT(SlGamelogGrfadd),
+ SLEG_STRUCT(SlGamelogGrfrem),
+ SLEG_STRUCT(SlGamelogGrfcompat),
+ SLEG_STRUCT(SlGamelogGrfparam),
+ SLEG_STRUCT(SlGamelogGrfmove),
+ SLEG_STRUCT(SlGamelogGrfbug),
+ SLEG_STRUCT(SlGamelogEmergency),
+ };
+
+ void Save(LoggedAction *la) const override
+ {
+ SlSetStructListLength(la->changes);
- while ((type = SlReadByte()) != GLCT_NONE) {
- if (type >= GLCT_END) SlErrorCorrupt("Invalid gamelog change type");
- GamelogChangeType ct = (GamelogChangeType)type;
+ const LoggedChange *lcend = &la->change[la->changes];
+ for (LoggedChange *lc = la->change; lc != lcend; lc++) {
+ assert((uint)lc->ct < GLCT_END);
+ SlObject(lc, this->GetDescription());
+ }
+ }
+
+ void Load(LoggedAction *la) const override
+ {
+ if (IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY)) {
+ byte type;
+ while ((type = SlReadByte()) != GLCT_NONE) {
+ if (type >= GLCT_END) SlErrorCorrupt("Invalid gamelog change type");
+ GamelogChangeType ct = (GamelogChangeType)type;
- la->change = ReallocT(la->change, la->changes + 1);
+ la->change = ReallocT(la->change, la->changes + 1);
- LoggedChange *lc = &la->change[la->changes++];
- /* for SLE_STR, pointer has to be valid! so make it nullptr */
+ LoggedChange *lc = &la->change[la->changes++];
+ memset(lc, 0, sizeof(*lc));
+ lc->ct = ct;
+
+ SlObject(lc, this->GetDescription());
+ }
+ return;
+ }
+
+ size_t length = SlGetStructListLength(UINT32_MAX);
+ la->change = ReallocT(la->change, length);
+
+ for (size_t i = 0; i < length; i++) {
+ LoggedChange *lc = &la->change[i];
memset(lc, 0, sizeof(*lc));
- lc->ct = ct;
- SlObject(lc, _glog_desc[ct]);
+ lc->ct = (GamelogChangeType)SlReadByte();
+ SlObject(lc, this->GetDescription());
}
}
-}
-static void Save_GLOG()
+ void LoadCheck(LoggedAction *la) const override { this->Load(la); }
+};
+
+static const SaveLoad _gamelog_desc[] = {
+ SLE_CONDVAR(LoggedAction, at, SLE_UINT8, SLV_RIFF_TO_ARRAY, SL_MAX_VERSION),
+ SLE_VAR(LoggedAction, tick, SLE_UINT16),
+ SLEG_STRUCTLIST(SlGamelogAction),
+};
+
+static void Load_GLOG_common(LoggedAction *&gamelog_action, uint &gamelog_actions)
{
- const LoggedAction *laend = &_gamelog_action[_gamelog_actions];
- size_t length = 0;
+ assert(gamelog_action == nullptr);
+ assert(gamelog_actions == 0);
- for (const LoggedAction *la = _gamelog_action; la != laend; la++) {
- const LoggedChange *lcend = &la->change[la->changes];
- for (LoggedChange *lc = la->change; lc != lcend; lc++) {
- assert((uint)lc->ct < lengthof(_glog_desc));
- length += SlCalcObjLength(lc, _glog_desc[lc->ct]) + 1;
+ if (IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY)) {
+ byte type;
+ while ((type = SlReadByte()) != GLAT_NONE) {
+ if (type >= GLAT_END) SlErrorCorrupt("Invalid gamelog action type");
+
+ gamelog_action = ReallocT(gamelog_action, gamelog_actions + 1);
+ LoggedAction *la = &gamelog_action[gamelog_actions++];
+ memset(la, 0, sizeof(*la));
+
+ la->at = (GamelogActionType)type;
+ SlObject(la, _gamelog_desc);
}
- length += 4;
+ return;
}
- length++;
- SlSetLength(length);
+ while (SlIterateArray() != -1) {
+ gamelog_action = ReallocT(gamelog_action, gamelog_actions + 1);
+ LoggedAction *la = &gamelog_action[gamelog_actions++];
+ memset(la, 0, sizeof(*la));
- for (LoggedAction *la = _gamelog_action; la != laend; la++) {
- SlWriteByte(la->at);
- SlObject(la, _glog_action_desc);
+ SlObject(la, _gamelog_desc);
+ }
+}
- const LoggedChange *lcend = &la->change[la->changes];
- for (LoggedChange *lc = la->change; lc != lcend; lc++) {
- SlWriteByte(lc->ct);
- assert((uint)lc->ct < GLCT_END);
- SlObject(lc, _glog_desc[lc->ct]);
- }
- SlWriteByte(GLCT_NONE);
+static void Save_GLOG()
+{
+ const LoggedAction *laend = &_gamelog_action[_gamelog_actions];
+
+ uint i = 0;
+ for (LoggedAction *la = _gamelog_action; la != laend; la++, i++) {
+ SlSetArrayIndex(i);
+ SlObject(la, _gamelog_desc);
}
- SlWriteByte(GLAT_NONE);
}
static void Load_GLOG()
@@ -169,7 +339,7 @@ static void Check_GLOG()
}
static const ChunkHandler gamelog_chunk_handlers[] = {
- { 'GLOG', Save_GLOG, Load_GLOG, nullptr, Check_GLOG, CH_RIFF }
+ { 'GLOG', Save_GLOG, Load_GLOG, nullptr, Check_GLOG, CH_ARRAY }
};
extern const ChunkHandlerTable _gamelog_chunk_handlers(gamelog_chunk_handlers);