Change gamelog to use std::vector

Move LoadCheckData to its own header
This commit is contained in:
Jonathan G Rennison 2023-07-03 22:42:28 +01:00
parent 5ae5ac3701
commit 0bf41dc1ff
23 changed files with 212 additions and 228 deletions

View File

@ -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

View File

@ -23,73 +23,6 @@ enum SaveLoadInvalidateWindowData {
SLIWD_FILTER_CHANGES, ///< The filename filter has changed (via the editbox)
};
using CompanyPropertiesMap = std::map<uint, std::unique_ptr<CompanyProperties>>;
/**
* 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;

View File

@ -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);

View File

@ -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<LoggedAction> _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<LoggedAction> &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<LoggedAction> &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<LoggedAction> &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:

View File

@ -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<LoggedAction> &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<LoggedAction> &gamelog_actions, uint32 *last_ottd_rev, byte *ever_modified, bool *removed_newgrfs);
const char *GamelogGetLastRevision(const std::vector<LoggedAction> &gamelog_actions);
#endif /* GAMELOG_H */

View File

@ -12,6 +12,8 @@
#include "gamelog.h"
#include <vector>
/** 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<LoggedChange> 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<LoggedAction> _gamelog_actions;
#endif /* GAMELOG_INTERNAL_H */

89
src/load_check.h Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
*/
/** @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 <memory>
#include <string>
#include <vector>
using CompanyPropertiesMap = btree::btree_map<uint, std::unique_ptr<CompanyProperties>>;
/**
* 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<LoggedAction> 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 */

View File

@ -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;

View File

@ -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;

View File

@ -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"

View File

@ -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<LoggedAction> &gamelog_actions) const
{
assert(gamelog_action == nullptr);
assert(gamelog_actions == 0);
assert(gamelog_actions.empty());
const std::vector<SaveLoad> 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);
}
};

View File

@ -15,6 +15,7 @@
#include "../map_func.h"
#include "../core/bitmath_func.hpp"
#include "../fios.h"
#include "../load_check.h"
#include <array>
#include "../safeguards.h"

View File

@ -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"

View File

@ -14,6 +14,7 @@
#include "newgrf_sl.h"
#include "../fios.h"
#include "../load_check.h"
#include "../safeguards.h"

View File

@ -17,6 +17,7 @@
#include "../settings_internal.h"
#include "../network/network.h"
#include "../fios.h"
#include "../load_check.h"
#include "../safeguards.h"

View File

@ -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"

View File

@ -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"

View File

@ -13,6 +13,7 @@
#include "saveload.h"
#include "saveload_buffer.h"
#include "../fios.h"
#include "../load_check.h"
#include "../safeguards.h"

View File

@ -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<LoggedAction> &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[] = {

View File

@ -13,6 +13,7 @@
#include "../core/endian_func.hpp"
#include "../core/endian_type.hpp"
#include "../fios.h"
#include "../load_check.h"
#include <array>
#include "saveload.h"

View File

@ -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"

View File

@ -9,6 +9,7 @@
#include "../stdafx.h"
#include "../fios.h"
#include "../load_check.h"
#include "../string_func.h"
#include "saveload.h"

View File

@ -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 <atomic>