diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 720664aa68..891b9b7568 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -238,6 +238,7 @@ add_files( league_gui.cpp league_type.h livery.h + load_check.h main_gui.cpp map.cpp map_func.h diff --git a/src/fios.h b/src/fios.h index 2742549b71..ca8fb0c0a6 100644 --- a/src/fios.h +++ b/src/fios.h @@ -23,73 +23,6 @@ enum SaveLoadInvalidateWindowData { SLIWD_FILTER_CHANGES, ///< The filename filter has changed (via the editbox) }; -using CompanyPropertiesMap = std::map>; - -/** - * Container for loading in mode SL_LOAD_CHECK. - */ -struct LoadCheckData { - bool checkable; ///< True if the savegame could be checked by SL_LOAD_CHECK. (Old savegames are not checkable.) - StringID error; ///< Error message from loading. INVALID_STRING_ID if no error. - std::string error_msg; ///< Data to pass to SetDParamStr when displaying #error. - - uint32 map_size_x, map_size_y; - Date current_date; - - GameSettings settings; - - CompanyPropertiesMap companies; ///< Company information. - - GRFConfig *grfconfig; ///< NewGrf configuration from save. - bool want_grf_compatibility = true; - GRFListCompatibility grf_compatibility; ///< Summary state of NewGrfs, whether missing files or only compatible found. - - struct LoggedAction *gamelog_action; ///< Gamelog actions - uint gamelog_actions; ///< Number of gamelog actions - - bool want_debug_data = false; - std::string debug_log_data; - std::string debug_config_data; - - bool sl_is_ext_version = false; - - LoadCheckData() : grfconfig(nullptr), - grf_compatibility(GLC_NOT_FOUND), gamelog_action(nullptr), gamelog_actions(0) - { - this->Clear(); - } - - /** - * Don't leak memory at program exit - */ - ~LoadCheckData() - { - this->Clear(); - } - - /** - * Check whether loading the game resulted in errors. - * @return true if errors were encountered. - */ - bool HasErrors() - { - return this->checkable && this->error != INVALID_STRING_ID; - } - - /** - * Check whether the game uses any NewGrfs. - * @return true if NewGrfs are used. - */ - bool HasNewGrfs() - { - return this->checkable && this->error == INVALID_STRING_ID && this->grfconfig != nullptr; - } - - void Clear(); -}; - -extern LoadCheckData _load_check_data; - /** Deals with finding savegames */ struct FiosItem { FiosType type; diff --git a/src/fios_gui.cpp b/src/fios_gui.cpp index b87197993d..5504bba5c5 100644 --- a/src/fios_gui.cpp +++ b/src/fios_gui.cpp @@ -8,6 +8,7 @@ /** @file fios_gui.cpp GUIs for loading/saving games, scenarios, heightmaps, ... */ #include "stdafx.h" +#include "load_check.h" #include "sl/saveload.h" #include "error.h" #include "gui.h" @@ -57,9 +58,7 @@ void LoadCheckData::Clear() companies.clear(); - GamelogFree(this->gamelog_action, this->gamelog_actions); - this->gamelog_action = nullptr; - this->gamelog_actions = 0; + GamelogFree(this->gamelog_actions); ClearGRFConfigList(&this->grfconfig); @@ -790,7 +789,7 @@ public: ShowQuery(STR_SAVELOAD_OVERWRITE_TITLE_DIFFERENT_ID, STR_SAVELOAD_OVERWRITE_WARNING_DIFFERENT_ID, this, SaveLoadWindow::SaveGameConfirmationCallback); } else if (_settings_client.gui.savegame_overwrite_confirm >= (known_id ? 3 : 2) && file_exists) { if (this->selected != nullptr && !_load_check_data.sl_is_ext_version) { - const char *version = GamelogGetLastRevision(_load_check_data.gamelog_action, _load_check_data.gamelog_actions); + const char *version = GamelogGetLastRevision(_load_check_data.gamelog_actions); SetDParam(0, STR_SAVELOAD_OVERWRITE_TITLE); std::string caption = GetString(STR_SAVELOAD_OVERWRITE_TITLE_DIFFERENT_VERSION_SUFFIX); diff --git a/src/gamelog.cpp b/src/gamelog.cpp index 59cf1466be..e22c4cf329 100644 --- a/src/gamelog.cpp +++ b/src/gamelog.cpp @@ -33,8 +33,7 @@ extern byte _sl_minor_version; ///< the minor savegame version, DO NOT USE! static GamelogActionType _gamelog_action_type = GLAT_NONE; ///< action to record if anything changes -LoggedAction *_gamelog_action = nullptr; ///< first logged action -uint _gamelog_actions = 0; ///< number of actions +std::vector _gamelog_actions; ///< logged actions static LoggedAction *_current_action = nullptr; ///< current action we are logging, nullptr when there is no action active @@ -72,19 +71,17 @@ void GamelogStopAnyAction() /** * Frees the memory allocated by a gamelog */ -void GamelogFree(LoggedAction *gamelog_action, uint gamelog_actions) +void GamelogFree(std::vector &gamelog_actions) { - for (uint i = 0; i < gamelog_actions; i++) { - const LoggedAction *la = &gamelog_action[i]; - for (uint j = 0; j < la->changes; j++) { - const LoggedChange *lc = &la->change[j]; - if (lc->ct == GLCT_SETTING) free(lc->setting.name); - if (lc->ct == GLCT_REVISION) free(lc->revision.text); + for (LoggedAction &la : gamelog_actions) { + for (LoggedChange &lc : la.changes) { + if (lc.ct == GLCT_SETTING) free(lc.setting.name); + if (lc.ct == GLCT_REVISION) free(lc.revision.text); + lc.ct = GLCT_NONE; } - free(la->change); } - free(gamelog_action); + gamelog_actions.clear(); } /** @@ -93,10 +90,7 @@ void GamelogFree(LoggedAction *gamelog_action, uint gamelog_actions) void GamelogReset() { assert(_gamelog_action_type == GLAT_NONE); - GamelogFree(_gamelog_action, _gamelog_actions); - - _gamelog_action = nullptr; - _gamelog_actions = 0; + GamelogFree(_gamelog_actions); _current_action = nullptr; } @@ -174,17 +168,14 @@ void GamelogPrint(GamelogPrintProc *proc) proc("---- gamelog start ----"); - const LoggedAction *laend = &_gamelog_action[_gamelog_actions]; + for (const LoggedAction &la : _gamelog_actions) { + assert((uint)la.at < GLAT_END); - for (const LoggedAction *la = _gamelog_action; la != laend; la++) { - assert((uint)la->at < GLAT_END); - - seprintf(buffer, lastof(buffer), "Tick %u: %s", (uint)la->tick, la_text[(uint)la->at]); + seprintf(buffer, lastof(buffer), "Tick %u: %s", (uint)la.tick, la_text[(uint)la.at]); proc(buffer); - const LoggedChange *lcend = &la->change[la->changes]; - - for (const LoggedChange *lc = la->change; lc != lcend; lc++) { + for (const LoggedChange &lchange : la.changes) { + const LoggedChange *lc = &lchange; char *buf = buffer; switch (lc->ct) { @@ -259,12 +250,12 @@ void GamelogPrint(GamelogPrintProc *proc) case GLCT_GRFREM: { /* A NewGRF got removed from the game, either manually or by it missing when loading the game. */ auto gm = grf_names.find(lc->grfrem.grfid); - buf += seprintf(buf, lastof(buffer), la->at == GLAT_LOAD ? "Missing NewGRF: " : "Removed NewGRF: "); + buf += seprintf(buf, lastof(buffer), la.at == GLAT_LOAD ? "Missing NewGRF: " : "Removed NewGRF: "); buf = PrintGrfInfo(buf, lastof(buffer), lc->grfrem.grfid, nullptr, gm != grf_names.end() ? gm->second.gc : nullptr); if (gm == grf_names.end()) { buf += seprintf(buf, lastof(buffer), ". Gamelog inconsistency: GrfID was never added!"); } else { - if (la->at == GLAT_LOAD) { + if (la.at == GLAT_LOAD) { /* Missing grfs on load are not removed from the configuration */ gm->second.was_missing = true; } else { @@ -371,18 +362,14 @@ static LoggedChange *GamelogChange(GamelogChangeType ct) if (_current_action == nullptr) { if (_gamelog_action_type == GLAT_NONE) return nullptr; - _gamelog_action = ReallocT(_gamelog_action, _gamelog_actions + 1); - _current_action = &_gamelog_action[_gamelog_actions++]; + _current_action = &_gamelog_actions.emplace_back(); _current_action->at = _gamelog_action_type; _current_action->tick = _tick_counter; - _current_action->change = nullptr; - _current_action->changes = 0; } - _current_action->change = ReallocT(_current_action->change, _current_action->changes + 1); - - LoggedChange *lc = &_current_action->change[_current_action->changes++]; + _current_action->changes.push_back({}); + LoggedChange *lc = &_current_action->changes.back(); lc->ct = ct; return lc; @@ -406,17 +393,13 @@ void GamelogEmergency() */ bool GamelogTestEmergency() { - const LoggedChange *emergency = nullptr; - - const LoggedAction *laend = &_gamelog_action[_gamelog_actions]; - for (const LoggedAction *la = _gamelog_action; la != laend; la++) { - const LoggedChange *lcend = &la->change[la->changes]; - for (const LoggedChange *lc = la->change; lc != lcend; lc++) { - if (lc->ct == GLCT_EMERGENCY) emergency = lc; + for (LoggedAction &la : _gamelog_actions) { + for (LoggedChange &lc : la.changes) { + if (lc.ct == GLCT_EMERGENCY) return true; } } - return (emergency != nullptr); + return false; } /** @@ -490,11 +473,9 @@ void GamelogTestRevision() { const LoggedChange *rev = nullptr; - const LoggedAction *laend = &_gamelog_action[_gamelog_actions]; - for (const LoggedAction *la = _gamelog_action; la != laend; la++) { - const LoggedChange *lcend = &la->change[la->changes]; - for (const LoggedChange *lc = la->change; lc != lcend; lc++) { - if (lc->ct == GLCT_REVISION) rev = lc; + for (LoggedAction &la : _gamelog_actions) { + for (LoggedChange &lc : la.changes) { + if (lc.ct == GLCT_REVISION) rev = &lc; } } @@ -513,11 +494,9 @@ void GamelogTestMode() { const LoggedChange *mode = nullptr; - const LoggedAction *laend = &_gamelog_action[_gamelog_actions]; - for (const LoggedAction *la = _gamelog_action; la != laend; la++) { - const LoggedChange *lcend = &la->change[la->changes]; - for (const LoggedChange *lc = la->change; lc != lcend; lc++) { - if (lc->ct == GLCT_MODE) mode = lc; + for (LoggedAction &la : _gamelog_actions) { + for (LoggedChange &lc : la.changes) { + if (lc.ct == GLCT_MODE) mode = &lc; } } @@ -554,12 +533,10 @@ static void GamelogGRFBug(uint32 grfid, byte bug, uint64 data) */ bool GamelogGRFBugReverse(uint32 grfid, uint16 internal_id) { - const LoggedAction *laend = &_gamelog_action[_gamelog_actions]; - for (const LoggedAction *la = _gamelog_action; la != laend; la++) { - const LoggedChange *lcend = &la->change[la->changes]; - for (const LoggedChange *lc = la->change; lc != lcend; lc++) { - if (lc->ct == GLCT_GRFBUG && lc->grfbug.grfid == grfid && - lc->grfbug.bug == GBUG_VEH_LENGTH && lc->grfbug.data == internal_id) { + for (LoggedAction &la : _gamelog_actions) { + for (LoggedChange &lc : la.changes) { + if (lc.ct == GLCT_GRFBUG && lc.grfbug.grfid == grfid && + lc.grfbug.bug == GBUG_VEH_LENGTH && lc.grfbug.data == internal_id) { return false; } } @@ -789,18 +766,16 @@ void GamelogGRFUpdate(const GRFConfig *oldc, const GRFConfig *newc) * @param[out] ever_modified Max value of 'modified' from all binaries that ever saved this savegame. * @param[out] removed_newgrfs Set to true if any NewGRFs have been removed. */ -void GamelogInfo(LoggedAction *gamelog_action, uint gamelog_actions, uint32 *last_ottd_rev, byte *ever_modified, bool *removed_newgrfs) +void GamelogInfo(const std::vector &gamelog_actions, uint32 *last_ottd_rev, byte *ever_modified, bool *removed_newgrfs) { - const LoggedAction *laend = &gamelog_action[gamelog_actions]; - for (const LoggedAction *la = gamelog_action; la != laend; la++) { - const LoggedChange *lcend = &la->change[la->changes]; - for (const LoggedChange *lc = la->change; lc != lcend; lc++) { - switch (lc->ct) { + for (const LoggedAction &la : gamelog_actions) { + for (const LoggedChange &lc : la.changes) { + switch (lc.ct) { default: break; case GLCT_REVISION: - *last_ottd_rev = lc->revision.newgrf; - *ever_modified = std::max(*ever_modified, lc->revision.modified); + *last_ottd_rev = lc.revision.newgrf; + *ever_modified = std::max(*ever_modified, lc.revision.modified); break; case GLCT_GRFREM: @@ -811,15 +786,14 @@ void GamelogInfo(LoggedAction *gamelog_action, uint gamelog_actions, uint32 *las } } -const char *GamelogGetLastRevision(const LoggedAction *gamelog_action, uint gamelog_actions) +const char *GamelogGetLastRevision(const std::vector &gamelog_actions) { - for (uint i = gamelog_actions; i > 0; i--) { - const LoggedAction &la = gamelog_action[i - 1]; - const LoggedChange *lcend = &(la.change[la.changes]); - for (const LoggedChange *lc = la.change; lc != lcend; lc++) { - switch (lc->ct) { + for (size_t i = gamelog_actions.size(); i > 0; i--) { + const LoggedAction &la = gamelog_actions[i - 1]; + for (const LoggedChange &lc : la.changes) { + switch (lc.ct) { case GLCT_REVISION: - return lc->revision.text; + return lc.revision.text; break; default: diff --git a/src/gamelog.h b/src/gamelog.h index f9ab0a47e0..48fdac4944 100644 --- a/src/gamelog.h +++ b/src/gamelog.h @@ -12,6 +12,8 @@ #include "newgrf_config.h" +struct LoggedAction; + /** The actions we log. */ enum GamelogActionType : uint8 { GLAT_START, ///< Game created @@ -29,7 +31,7 @@ void GamelogStartAction(GamelogActionType at); void GamelogStopAction(); void GamelogStopAnyAction(); -void GamelogFree(struct LoggedAction *gamelog_action, uint gamelog_actions); +void GamelogFree(std::vector &gamelog_actions); void GamelogReset(); /** @@ -61,7 +63,7 @@ void GamelogTestMode(); bool GamelogGRFBugReverse(uint32 grfid, uint16 internal_id); -void GamelogInfo(struct LoggedAction *gamelog_action, uint gamelog_actions, uint32 *last_ottd_rev, byte *ever_modified, bool *removed_newgrfs); -const char *GamelogGetLastRevision(const struct LoggedAction *gamelog_action, uint gamelog_actions); +void GamelogInfo(const std::vector &gamelog_actions, uint32 *last_ottd_rev, byte *ever_modified, bool *removed_newgrfs); +const char *GamelogGetLastRevision(const std::vector &gamelog_actions); #endif /* GAMELOG_H */ diff --git a/src/gamelog_internal.h b/src/gamelog_internal.h index a6f8780f0e..b49b42a6df 100644 --- a/src/gamelog_internal.h +++ b/src/gamelog_internal.h @@ -12,6 +12,8 @@ #include "gamelog.h" +#include + /** Type of logged change */ enum GamelogChangeType { GLCT_MODE, ///< Scenario editor x Game, different landscape @@ -78,13 +80,11 @@ struct LoggedChange { /** Contains information about one logged action that caused at least one logged change */ struct LoggedAction { - LoggedChange *change; ///< First logged change in this action - uint32 changes; ///< Number of changes in this action + std::vector changes; ///< Changes in this action GamelogActionType at; ///< Type of action uint64 tick; ///< Tick when it happened }; -extern LoggedAction *_gamelog_action; -extern uint _gamelog_actions; +extern std::vector _gamelog_actions; #endif /* GAMELOG_INTERNAL_H */ diff --git a/src/load_check.h b/src/load_check.h new file mode 100644 index 0000000000..fbdae78853 --- /dev/null +++ b/src/load_check.h @@ -0,0 +1,89 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file load_check.h Load check data. */ + +#ifndef LOAD_CHECK_H +#define LOAD_CHECK_H + +#include "company_base.h" +#include "date_type.h" +#include "gamelog_internal.h" +#include "newgrf_config.h" +#include "strings_type.h" +#include "3rdparty/cpp-btree/btree_map.h" +#include +#include +#include + +using CompanyPropertiesMap = btree::btree_map>; + +/** + * Container for loading in mode SL_LOAD_CHECK. + */ +struct LoadCheckData { + bool checkable; ///< True if the savegame could be checked by SL_LOAD_CHECK. (Old savegames are not checkable.) + StringID error; ///< Error message from loading. INVALID_STRING_ID if no error. + std::string error_msg; ///< Data to pass to SetDParamStr when displaying #error. + + uint32 map_size_x, map_size_y; + Date current_date; + + GameSettings settings; + + CompanyPropertiesMap companies; ///< Company information. + + GRFConfig *grfconfig; ///< NewGrf configuration from save. + bool want_grf_compatibility = true; + GRFListCompatibility grf_compatibility; ///< Summary state of NewGrfs, whether missing files or only compatible found. + + std::vector gamelog_actions; ///< Gamelog actions + + bool want_debug_data = false; + std::string debug_log_data; + std::string debug_config_data; + + bool sl_is_ext_version = false; + + LoadCheckData() : grfconfig(nullptr), + grf_compatibility(GLC_NOT_FOUND) + { + this->Clear(); + } + + /** + * Don't leak memory at program exit + */ + ~LoadCheckData() + { + this->Clear(); + } + + /** + * Check whether loading the game resulted in errors. + * @return true if errors were encountered. + */ + bool HasErrors() + { + return this->checkable && this->error != INVALID_STRING_ID; + } + + /** + * Check whether the game uses any NewGrfs. + * @return true if NewGrfs are used. + */ + bool HasNewGrfs() + { + return this->checkable && this->error == INVALID_STRING_ID && this->grfconfig != nullptr; + } + + void Clear(); +}; + +extern LoadCheckData _load_check_data; + +#endif /* LOAD_CHECK_H */ diff --git a/src/openttd.cpp b/src/openttd.cpp index 81919036aa..0ac04903f7 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -25,6 +25,7 @@ #include "command_func.h" #include "news_func.h" #include "fios.h" +#include "load_check.h" #include "aircraft.h" #include "roadveh.h" #include "train.h" @@ -328,7 +329,7 @@ static void WriteSavegameInfo(const char *name) byte ever_modified = 0; bool removed_newgrfs = false; - GamelogInfo(_load_check_data.gamelog_action, _load_check_data.gamelog_actions, &last_ottd_rev, &ever_modified, &removed_newgrfs); + GamelogInfo(_load_check_data.gamelog_actions, &last_ottd_rev, &ever_modified, &removed_newgrfs); char buf[65536]; char *p = buf; diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index ec60fb4c5e..d2d1a0605f 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -389,12 +389,11 @@ static void ResetSignalHandlers() */ static const GRFIdentifier *GetOverriddenIdentifier(const GRFConfig *c) { - const LoggedAction *la = &_gamelog_action[_gamelog_actions - 1]; - if (la->at != GLAT_LOAD) return &c->ident; + const LoggedAction &la = _gamelog_actions.back(); + if (la.at != GLAT_LOAD) return &c->ident; - const LoggedChange *lcend = &la->change[la->changes]; - for (const LoggedChange *lc = la->change; lc != lcend; lc++) { - if (lc->ct == GLCT_GRFCOMPAT && lc->grfcompat.grfid == c->ident.grfid) return &lc->grfcompat; + for (const LoggedChange &lc : la.changes) { + if (lc.ct == GLCT_GRFCOMPAT && lc.grfcompat.grfid == c->ident.grfid) return &lc.grfcompat; } return &c->ident; diff --git a/src/saveload/company_sl.cpp b/src/saveload/company_sl.cpp index fb4f8aa823..213e2d08a4 100644 --- a/src/saveload/company_sl.cpp +++ b/src/saveload/company_sl.cpp @@ -15,6 +15,7 @@ #include "../company_func.h" #include "../company_manager_face.h" #include "../fios.h" +#include "../load_check.h" #include "../tunnelbridge_map.h" #include "../tunnelbridge.h" #include "../station_base.h" diff --git a/src/saveload/gamelog_sl.cpp b/src/saveload/gamelog_sl.cpp index c0ebd3991b..3b0d28dc92 100644 --- a/src/saveload/gamelog_sl.cpp +++ b/src/saveload/gamelog_sl.cpp @@ -14,6 +14,7 @@ #include "../gamelog_internal.h" #include "../fios.h" +#include "../load_check.h" #include "../string_func.h" #include "../safeguards.h" @@ -309,27 +310,26 @@ public: void Save(LoggedAction *la) const override { - SlSetStructListLength(la->changes); + SlSetStructListLength(la->changes.size()); - 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()); + for (LoggedChange &lc : la->changes) { + assert((uint)lc.ct < GLCT_END); + SlObject(&lc, this->GetDescription()); } } void Load(LoggedAction *la) const override { + la->changes.clear(); + 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); - - LoggedChange *lc = &la->change[la->changes++]; - *lc = LoggedChange{}; + la->changes.push_back({}); + LoggedChange *lc = &la->changes.back(); lc->ct = ct; SlObject(lc, this->GetLoadDescription()); @@ -338,12 +338,11 @@ public: } size_t length = SlGetStructListLength(UINT32_MAX); - la->change = ReallocT(la->change, length); - la->changes = (uint32)length; + la->changes.reserve(length); for (size_t i = 0; i < length; i++) { - LoggedChange *lc = &la->change[i]; - *lc = LoggedChange{}; + la->changes.push_back({}); + LoggedChange *lc = &la->changes.back(); lc->ct = (GamelogChangeType)SlReadByte(); SlObject(lc, this->GetLoadDescription()); @@ -363,10 +362,9 @@ static const SaveLoad _gamelog_desc[] = { struct GLOGChunkHandler : ChunkHandler { GLOGChunkHandler() : ChunkHandler('GLOG', CH_TABLE) {} - void LoadCommon(LoggedAction *&gamelog_action, uint &gamelog_actions) const + void LoadCommon(std::vector &gamelog_actions) const { - assert(gamelog_action == nullptr); - assert(gamelog_actions == 0); + assert(gamelog_actions.empty()); const std::vector slt = SlCompatTableHeader(_gamelog_desc, _gamelog_sl_compat); @@ -375,22 +373,18 @@ struct GLOGChunkHandler : ChunkHandler { 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++]; - *la = LoggedAction{}; + LoggedAction &la = gamelog_actions.emplace_back(); - la->at = (GamelogActionType)type; - SlObject(la, slt); + la.at = (GamelogActionType)type; + SlObject(&la, slt); } return; } while (SlIterateArray() != -1) { - gamelog_action = ReallocT(gamelog_action, gamelog_actions + 1); - LoggedAction *la = &gamelog_action[gamelog_actions++]; - *la = LoggedAction{}; + LoggedAction &la = gamelog_actions.emplace_back(); - SlObject(la, slt); + SlObject(&la, slt); } } @@ -398,23 +392,22 @@ struct GLOGChunkHandler : ChunkHandler { { SlTableHeader(_gamelog_desc); - const LoggedAction *laend = &_gamelog_action[_gamelog_actions]; - uint i = 0; - for (LoggedAction *la = _gamelog_action; la != laend; la++, i++) { + for (LoggedAction &la : _gamelog_actions) { SlSetArrayIndex(i); - SlObject(la, _gamelog_desc); + SlObject(&la, _gamelog_desc); + i++; } } void Load() const override { - this->LoadCommon(_gamelog_action, _gamelog_actions); + this->LoadCommon(_gamelog_actions); } void LoadCheck(size_t) const override { - this->LoadCommon(_load_check_data.gamelog_action, _load_check_data.gamelog_actions); + this->LoadCommon(_load_check_data.gamelog_actions); } }; diff --git a/src/saveload/map_sl.cpp b/src/saveload/map_sl.cpp index d974da8322..afea07a59d 100644 --- a/src/saveload/map_sl.cpp +++ b/src/saveload/map_sl.cpp @@ -15,6 +15,7 @@ #include "../map_func.h" #include "../core/bitmath_func.hpp" #include "../fios.h" +#include "../load_check.h" #include #include "../safeguards.h" diff --git a/src/saveload/misc_sl.cpp b/src/saveload/misc_sl.cpp index e597c4a4d4..857a499a85 100644 --- a/src/saveload/misc_sl.cpp +++ b/src/saveload/misc_sl.cpp @@ -20,6 +20,7 @@ #include "../gfx_func.h" #include "../core/random_func.hpp" #include "../fios.h" +#include "../load_check.h" #include "../timer/timer.h" #include "../timer/timer_game_tick.h" diff --git a/src/saveload/newgrf_sl.cpp b/src/saveload/newgrf_sl.cpp index ae36fe7756..99c73d979d 100644 --- a/src/saveload/newgrf_sl.cpp +++ b/src/saveload/newgrf_sl.cpp @@ -14,6 +14,7 @@ #include "newgrf_sl.h" #include "../fios.h" +#include "../load_check.h" #include "../safeguards.h" diff --git a/src/saveload/settings_sl.cpp b/src/saveload/settings_sl.cpp index 5224e01d0f..3a807f2e0b 100644 --- a/src/saveload/settings_sl.cpp +++ b/src/saveload/settings_sl.cpp @@ -17,6 +17,7 @@ #include "../settings_internal.h" #include "../network/network.h" #include "../fios.h" +#include "../load_check.h" #include "../safeguards.h" diff --git a/src/settings.cpp b/src/settings.cpp index b6cb548870..344a3d7f83 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -66,6 +66,7 @@ #include "smallmap_gui.h" #include "roadveh.h" #include "fios.h" +#include "load_check.h" #include "strings_func.h" #include "string_func.h" #include "debug.h" diff --git a/src/sl/company_sl.cpp b/src/sl/company_sl.cpp index 4bf791441c..5a6bb6d970 100644 --- a/src/sl/company_sl.cpp +++ b/src/sl/company_sl.cpp @@ -11,6 +11,7 @@ #include "../company_func.h" #include "../company_manager_face.h" #include "../fios.h" +#include "../load_check.h" #include "../tunnelbridge_map.h" #include "../tunnelbridge.h" #include "../station_base.h" diff --git a/src/sl/debug_sl.cpp b/src/sl/debug_sl.cpp index 7c904d73bf..6bfb1fe77b 100644 --- a/src/sl/debug_sl.cpp +++ b/src/sl/debug_sl.cpp @@ -13,6 +13,7 @@ #include "saveload.h" #include "saveload_buffer.h" #include "../fios.h" +#include "../load_check.h" #include "../safeguards.h" diff --git a/src/sl/gamelog_sl.cpp b/src/sl/gamelog_sl.cpp index 8270190c53..8d4f313409 100644 --- a/src/sl/gamelog_sl.cpp +++ b/src/sl/gamelog_sl.cpp @@ -10,6 +10,7 @@ #include "../stdafx.h" #include "../gamelog_internal.h" #include "../fios.h" +#include "../load_check.h" #include "../string_func.h" #include "saveload.h" @@ -96,37 +97,31 @@ static const SaveLoadTable _glog_desc[] = { static_assert(lengthof(_glog_desc) == GLCT_END); -static void Load_GLOG_common(LoggedAction *&gamelog_action, uint &gamelog_actions) +static void Load_GLOG_common(std::vector &gamelog_actions) { - assert(gamelog_action == nullptr); - assert(gamelog_actions == 0); + assert(gamelog_actions.empty()); byte type; while ((type = SlReadByte()) != GLAT_NONE) { if (type >= GLAT_END) SlErrorCorrupt("Invalid gamelog action type"); GamelogActionType at = (GamelogActionType)type; - gamelog_action = ReallocT(gamelog_action, gamelog_actions + 1); - LoggedAction *la = &gamelog_action[gamelog_actions++]; + LoggedAction &la = gamelog_actions.emplace_back(); - la->at = at; + la.at = at; - SlObject(la, _glog_action_desc); // has to be saved after 'DATE'! - la->change = nullptr; - la->changes = 0; + SlObject(&la, _glog_action_desc); // has to be saved after 'DATE'! 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.changes.push_back({}); + LoggedChange *lc = &la.changes.back(); - LoggedChange *lc = &la->change[la->changes++]; - /* for SLE_STR, pointer has to be valid! so make it nullptr */ - memset(lc, 0, sizeof(*lc)); lc->ct = ct; - SlObject(lc, _glog_desc[ct]); + if (ct == GLCT_REVISION && SlXvIsFeatureMissing(XSLFI_EXTENDED_GAMELOG)) { lc->revision.text = stredup(old_revision_text, lastof(old_revision_text)); } @@ -136,44 +131,30 @@ static void Load_GLOG_common(LoggedAction *&gamelog_action, uint &gamelog_action static void Save_GLOG() { - const LoggedAction *laend = &_gamelog_action[_gamelog_actions]; - size_t length = 0; + SlAutolength([](void *) { + for (LoggedAction &la : _gamelog_actions) { + SlWriteByte(la.at); + SlObject(&la, _glog_action_desc); - 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; + for (LoggedChange &lc : la.changes) { + SlWriteByte(lc.ct); + assert((uint)lc.ct < GLCT_END); + SlObject(&lc, _glog_desc[lc.ct]); + } + SlWriteByte(GLCT_NONE); } - length += 10; - } - length++; - - SlSetLength(length); - - for (LoggedAction *la = _gamelog_action; la != laend; la++) { - SlWriteByte(la->at); - SlObject(la, _glog_action_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); - } - SlWriteByte(GLAT_NONE); + SlWriteByte(GLAT_NONE); + }, nullptr); } static void Load_GLOG() { - Load_GLOG_common(_gamelog_action, _gamelog_actions); + Load_GLOG_common(_gamelog_actions); } static void Check_GLOG() { - Load_GLOG_common(_load_check_data.gamelog_action, _load_check_data.gamelog_actions); + Load_GLOG_common(_load_check_data.gamelog_actions); } static const ChunkHandler gamelog_chunk_handlers[] = { diff --git a/src/sl/map_sl.cpp b/src/sl/map_sl.cpp index 5017b7557e..80d8771fd9 100644 --- a/src/sl/map_sl.cpp +++ b/src/sl/map_sl.cpp @@ -13,6 +13,7 @@ #include "../core/endian_func.hpp" #include "../core/endian_type.hpp" #include "../fios.h" +#include "../load_check.h" #include #include "saveload.h" diff --git a/src/sl/misc_sl.cpp b/src/sl/misc_sl.cpp index ddc64b7ca4..9a4d2551f3 100644 --- a/src/sl/misc_sl.cpp +++ b/src/sl/misc_sl.cpp @@ -16,6 +16,7 @@ #include "../gfx_func.h" #include "../core/random_func.hpp" #include "../fios.h" +#include "../load_check.h" #include "../road_type.h" #include "../core/checksum_func.hpp" #include "../event_logs.h" diff --git a/src/sl/newgrf_sl.cpp b/src/sl/newgrf_sl.cpp index dd5932a750..288ae701e6 100644 --- a/src/sl/newgrf_sl.cpp +++ b/src/sl/newgrf_sl.cpp @@ -9,6 +9,7 @@ #include "../stdafx.h" #include "../fios.h" +#include "../load_check.h" #include "../string_func.h" #include "saveload.h" diff --git a/src/sl/saveload.cpp b/src/sl/saveload.cpp index fc4bf9f1fd..300f015d88 100644 --- a/src/sl/saveload.cpp +++ b/src/sl/saveload.cpp @@ -42,6 +42,7 @@ #include "../string_func.h" #include "../string_func_extra.h" #include "../fios.h" +#include "../load_check.h" #include "../error.h" #include "../scope.h" #include