diff options
author | Patric Stout <truebrain@openttd.org> | 2021-06-12 17:12:35 +0200 |
---|---|---|
committer | Patric Stout <github@truebrain.nl> | 2021-06-15 19:36:15 +0200 |
commit | 4c4b55ecbdb6206afef7f20d905de2f2a343959a (patch) | |
tree | 3026e60419708cb77d77ce3ddeba2d7decbe84a1 | |
parent | 88edfd4ef16bedd98a07a2142e693ab50fbdcef2 (diff) | |
download | openttd-4c4b55ecbdb6206afef7f20d905de2f2a343959a.tar.xz |
Change: rework GLOG chunk to be more like the rest
Basically it is very similar to Vehicles, where there first is
a type field, followed by data of that type. So this commit makes
it looks like how Vehicles solved that.
This removes a lot of custom "keeping track of length" stuff.
-rw-r--r-- | src/gamelog.h | 2 | ||||
-rw-r--r-- | src/gamelog_internal.h | 2 | ||||
-rw-r--r-- | src/saveload/gamelog_sl.cpp | 366 |
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); |