Merge branch 'save_ext' into template_train_replacement

# Conflicts:
#	src/saveload/saveload.cpp
#	src/vehicle_gui.cpp
This commit is contained in:
Jonathan G Rennison
2018-05-25 19:12:10 +01:00
483 changed files with 17875 additions and 7611 deletions

View File

@@ -154,7 +154,7 @@ static void ConvertTownOwner()
if (GB(_m[tile].m5, 4, 2) == ROAD_TILE_CROSSING && HasBit(_m[tile].m3, 7)) {
_m[tile].m3 = OWNER_TOWN;
}
/* FALL THROUGH */
FALLTHROUGH;
case MP_TUNNELBRIDGE:
if (_m[tile].m1 & 0x80) SetTileOwner(tile, OWNER_TOWN);
@@ -718,12 +718,14 @@ bool AfterLoadGame()
if (IsSavegameVersionBefore(95)) _settings_game.vehicle.dynamic_engines = 0;
if (IsSavegameVersionBefore(96)) _settings_game.economy.station_noise_level = false;
if (IsSavegameVersionBefore(133)) {
_settings_game.vehicle.roadveh_acceleration_model = 0;
_settings_game.vehicle.train_slope_steepness = 3;
}
if (IsSavegameVersionBefore(134)) _settings_game.economy.feeder_payment_share = 75;
if (IsSavegameVersionBefore(138)) _settings_game.vehicle.plane_crashes = 2;
if (IsSavegameVersionBefore(139)) _settings_game.vehicle.roadveh_slope_steepness = 7;
if (IsSavegameVersionBefore(139)) {
_settings_game.vehicle.roadveh_acceleration_model = 0;
_settings_game.vehicle.roadveh_slope_steepness = 7;
}
if (IsSavegameVersionBefore(143)) _settings_game.economy.allow_town_level_crossings = true;
if (IsSavegameVersionBefore(159)) {
_settings_game.vehicle.max_train_length = 50;
@@ -2158,22 +2160,21 @@ bool AfterLoadGame()
/* Animated tiles would sometimes not be actually animated or
* in case of old savegames duplicate. */
extern TileIndex *_animated_tile_list;
extern uint _animated_tile_count;
extern SmallVector<TileIndex, 256> _animated_tiles;
for (uint i = 0; i < _animated_tile_count; /* Nothing */) {
for (TileIndex *tile = _animated_tiles.Begin(); tile < _animated_tiles.End(); /* Nothing */) {
/* Remove if tile is not animated */
bool remove = _tile_type_procs[GetTileType(_animated_tile_list[i])]->animate_tile_proc == NULL;
bool remove = _tile_type_procs[GetTileType(*tile)]->animate_tile_proc == NULL;
/* and remove if duplicate */
for (uint j = 0; !remove && j < i; j++) {
remove = _animated_tile_list[i] == _animated_tile_list[j];
for (TileIndex *j = _animated_tiles.Begin(); !remove && j < tile; j++) {
remove = *tile == *j;
}
if (remove) {
DeleteAnimatedTile(_animated_tile_list[i]);
DeleteAnimatedTile(*tile);
} else {
i++;
tile++;
}
}
}
@@ -2971,6 +2972,19 @@ bool AfterLoadGame()
#endif
}
if (IsSavegameVersionBefore(198)) {
/* Convert towns growth_rate and grow_counter to ticks */
Town *t;
FOR_ALL_TOWNS(t) {
/* 0x8000 = TOWN_GROWTH_RATE_CUSTOM previously */
if (t->growth_rate & 0x8000) SetBit(t->flags, TOWN_CUSTOM_GROWTH);
if (t->growth_rate != TOWN_GROWTH_RATE_NONE) {
t->growth_rate = TownTicksToGameTicks(t->growth_rate & ~0x8000);
}
/* Add t->index % TOWN_GROWTH_TICKS to spread growth across ticks. */
t->grow_counter = TownTicksToGameTicks(t->grow_counter) + t->index % TOWN_GROWTH_TICKS;
}
}
/* Station acceptance is some kind of cache */
if (IsSavegameVersionBefore(127)) {

View File

@@ -12,22 +12,21 @@
#include "../stdafx.h"
#include "../tile_type.h"
#include "../core/alloc_func.hpp"
#include "../core/smallvec_type.hpp"
#include "saveload.h"
#include "../safeguards.h"
extern TileIndex *_animated_tile_list;
extern uint _animated_tile_count;
extern uint _animated_tile_allocated;
extern SmallVector<TileIndex, 256> _animated_tiles;
/**
* Save the ANIT chunk.
*/
static void Save_ANIT()
{
SlSetLength(_animated_tile_count * sizeof(*_animated_tile_list));
SlArray(_animated_tile_list, _animated_tile_count, SLE_UINT32);
SlSetLength(_animated_tiles.Length() * sizeof(*_animated_tiles.Begin()));
SlArray(_animated_tiles.Begin(), _animated_tiles.Length(), SLE_UINT32);
}
/**
@@ -38,22 +37,20 @@ static void Load_ANIT()
/* Before version 80 we did NOT have a variable length animated tile table */
if (IsSavegameVersionBefore(80)) {
/* In pre version 6, we has 16bit per tile, now we have 32bit per tile, convert it ;) */
SlArray(_animated_tile_list, 256, IsSavegameVersionBefore(6) ? (SLE_FILE_U16 | SLE_VAR_U32) : SLE_UINT32);
TileIndex anim_list[256];
SlArray(anim_list, 256, IsSavegameVersionBefore(6) ? (SLE_FILE_U16 | SLE_VAR_U32) : SLE_UINT32);
for (_animated_tile_count = 0; _animated_tile_count < 256; _animated_tile_count++) {
if (_animated_tile_list[_animated_tile_count] == 0) break;
for (int i = 0; i < 256; i++) {
if (anim_list[i] == 0) break;
*_animated_tiles.Append() = anim_list[i];
}
return;
}
_animated_tile_count = (uint)SlGetFieldLength() / sizeof(*_animated_tile_list);
/* Determine a nice rounded size for the amount of allocated tiles */
_animated_tile_allocated = 256;
while (_animated_tile_allocated < _animated_tile_count) _animated_tile_allocated *= 2;
_animated_tile_list = ReallocT<TileIndex>(_animated_tile_list, _animated_tile_allocated);
SlArray(_animated_tile_list, _animated_tile_count, SLE_UINT32);
uint count = (uint)SlGetFieldLength() / sizeof(*_animated_tiles.Begin());
_animated_tiles.Clear();
_animated_tiles.Append(count);
SlArray(_animated_tiles.Begin(), count, SLE_UINT32);
}
/**

View File

@@ -16,6 +16,7 @@
#include "../tunnelbridge_map.h"
#include "../tunnelbridge.h"
#include "../station_base.h"
#include "../strings_func.h"
#include "../settings_func.h"
#include "saveload.h"
@@ -185,7 +186,7 @@ void AfterLoadCompanyStats()
}
}
}
/* FALL THROUGH */
FALLTHROUGH;
case MP_OBJECT:
if (GetWaterClass(tile) == WATER_CLASS_CANAL) {
@@ -244,7 +245,7 @@ static const SaveLoad _company_desc[] = {
SLE_VAR(CompanyProperties, name_1, SLE_STRINGID),
SLE_CONDSTR(CompanyProperties, name, SLE_STR | SLF_ALLOW_CONTROL, 0, 84, SL_MAX_VERSION),
SLE_VAR(CompanyProperties, president_name_1, SLE_UINT16),
SLE_VAR(CompanyProperties, president_name_1, SLE_STRINGID),
SLE_VAR(CompanyProperties, president_name_2, SLE_UINT32),
SLE_CONDSTR(CompanyProperties, president_name, SLE_STR | SLF_ALLOW_CONTROL, 0, 84, SL_MAX_VERSION),
@@ -259,7 +260,7 @@ static const SaveLoad _company_desc[] = {
SLE_VAR(CompanyProperties, colour, SLE_UINT8),
SLE_VAR(CompanyProperties, money_fraction, SLE_UINT8),
SLE_CONDVAR(CompanyProperties, avail_railtypes, SLE_VAR_I32 | SLE_FILE_I8, 0, 57),
SLE_CONDNULL(1, 0, 57), ///< avail_railtypes
SLE_VAR(CompanyProperties, block_preview, SLE_UINT8),
SLE_CONDNULL(2, 0, 93), ///< cargo_types
@@ -503,11 +504,11 @@ static void Check_PLYR()
/* We do not load old custom names */
if (IsSavegameVersionBefore(84)) {
if (GB(cprops->name_1, 11, 5) == 15) {
if (GetStringTab(cprops->name_1) == TEXT_TAB_OLD_CUSTOM) {
cprops->name_1 = STR_GAME_SAVELOAD_NOT_AVAILABLE;
}
if (GB(cprops->president_name_1, 11, 5) == 15) {
if (GetStringTab(cprops->president_name_1) == TEXT_TAB_OLD_CUSTOM) {
cprops->president_name_1 = STR_GAME_SAVELOAD_NOT_AVAILABLE;
}
}

View File

@@ -61,6 +61,8 @@ bool SlXvFeatureTest::IsFeaturePresent(uint16 savegame_version, uint16 savegame_
{
bool savegame_version_ok = savegame_version >= savegame_version_from && savegame_version <= savegame_version_to;
if (this->functor) return (*this->functor)(savegame_version, savegame_version_ok);
if (this->feature == XSLFI_NULL) return savegame_version_ok;
bool feature_ok = SlXvIsFeaturePresent(this->feature, this->min_version, this->max_version);
@@ -87,6 +89,20 @@ bool SlXvIsFeaturePresent(SlXvFeatureIndex feature, uint16 min_version, uint16 m
return _sl_xv_feature_versions[feature] >= min_version && _sl_xv_feature_versions[feature] <= max_version;
}
/**
* Returns true if @p feature is present and has a version inclusively bounded by @p min_version and @p max_version
*/
const char *SlXvGetFeatureName(SlXvFeatureIndex feature)
{
const SlxiSubChunkInfo *info = _sl_xv_sub_chunk_infos;
for (; info->index != XSLFI_NULL; ++info) {
if (info->index == feature) {
return info->name;
}
}
return "(unknown feature)";
}
/**
* Resets all extended feature versions to 0
*/
@@ -94,6 +110,7 @@ void SlXvResetState()
{
_sl_is_ext_version = false;
_sl_is_faked_ext = false;
_sl_xv_discardable_chunk_ids.clear();
memset(_sl_xv_feature_versions, 0, sizeof(_sl_xv_feature_versions));
}
@@ -116,9 +133,7 @@ void SlXvSetCurrentState()
*/
void SlXvCheckSpecialSavegameVersions()
{
extern uint16 _sl_version;
// TODO: check for savegame versions
// Checks for special savegame versions go here
}
/**

View File

@@ -40,11 +40,14 @@ enum SlXvFeatureTestOperator {
* Structure to describe an extended feature version test, and how it combines with a traditional savegame version test
*/
struct SlXvFeatureTest {
using TestFunctorPtr = bool (*)(uint16, bool); ///< Return true if feature present, first parameter is standard savegame version, second is whether standard savegame version is within bounds
private:
uint16 min_version;
uint16 max_version;
SlXvFeatureIndex feature;
SlXvFeatureTestOperator op;
TestFunctorPtr functor = nullptr;
public:
SlXvFeatureTest()
@@ -53,6 +56,9 @@ struct SlXvFeatureTest {
SlXvFeatureTest(SlXvFeatureTestOperator op_, SlXvFeatureIndex feature_, uint16 min_version_ = 1, uint16 max_version_ = 0xFFFF)
: min_version(min_version_), max_version(max_version_), feature(feature_), op(op_) { }
SlXvFeatureTest(TestFunctorPtr functor_)
: min_version(0), max_version(0), feature(XSLFI_NULL), op(XSLFTO_OR), functor(functor_) { }
bool IsFeaturePresent(uint16 savegame_version, uint16 savegame_version_from, uint16 savegame_version_to) const;
};
@@ -66,6 +72,8 @@ inline bool SlXvIsFeatureMissing(SlXvFeatureIndex feature)
return !SlXvIsFeaturePresent(feature);
}
const char *SlXvGetFeatureName(SlXvFeatureIndex feature);
/**
* sub chunk flags, this is saved as-is
* (XSCF_EXTRA_DATA_PRESENT and XSCF_CHUNK_ID_LIST_PRESENT must only be set by the save code, and read by the load code)

View File

@@ -57,7 +57,7 @@ static const SaveLoad _industry_desc[] = {
SLEG_CONDARR(_old_ind_persistent_storage.storage, SLE_UINT32, 16, 76, 160),
SLE_CONDREF(Industry, psa, REF_STORAGE, 161, SL_MAX_VERSION),
SLE_CONDVAR(Industry, random_triggers, SLE_UINT8, 82, SL_MAX_VERSION),
SLE_CONDNULL(1, 82, 196), // random_triggers
SLE_CONDVAR(Industry, random, SLE_UINT16, 82, SL_MAX_VERSION),
SLE_CONDNULL(32, 2, 143), // old reserved space

View File

@@ -96,8 +96,16 @@ static void Load_NGRF()
{
Load_NGRF_common(_grfconfig);
/* Append static NewGRF configuration, but only if there are some NewGRFs. */
if (_game_mode != GM_MENU || _all_grfs != NULL) AppendStaticGRFConfigs(&_grfconfig);
if (_game_mode == GM_MENU) {
/* Intro game must not have NewGRF. */
if (_grfconfig != NULL) SlErrorCorrupt("The intro game must not use NewGRF");
/* Activate intro NewGRFs (townnames) */
ResetGRFConfig(false);
} else {
/* Append static NewGRF configuration */
AppendStaticGRFConfigs(&_grfconfig);
}
}
static void Check_NGRF()

View File

@@ -28,6 +28,7 @@
#include "../engine_func.h"
#include "../company_base.h"
#include "../disaster_vehicle.h"
#include "../core/smallvec_type.hpp"
#include "saveload_internal.h"
#include "oldloader.h"
@@ -490,8 +491,7 @@ static inline uint RemapOrderIndex(uint x)
return _savegame_type == SGT_TTO ? (x - 0x1AC4) / 2 : (x - 0x1C18) / 2;
}
extern TileIndex *_animated_tile_list;
extern uint _animated_tile_count;
extern SmallVector<TileIndex, 256> _animated_tiles;
extern char *_old_name_array;
static uint32 _old_town_index;
@@ -640,22 +640,18 @@ static bool LoadOldOrder(LoadgameState *ls, int num)
static bool LoadOldAnimTileList(LoadgameState *ls, int num)
{
/* This is slightly hackish - we must load a chunk into an array whose
* address isn't static, but instead pointed to by _animated_tile_list.
* To achieve that, create an OldChunks list on the stack on the fly.
* The list cannot be static because the value of _animated_tile_list
* can change between calls. */
TileIndex anim_list[256];
const OldChunks anim_chunk[] = {
OCL_VAR ( OC_TILE, 256, _animated_tile_list ),
OCL_VAR ( OC_TILE, 256, anim_list ),
OCL_END ()
};
if (!LoadChunk(ls, NULL, anim_chunk)) return false;
/* Update the animated tile counter by counting till the first zero in the array */
for (_animated_tile_count = 0; _animated_tile_count < 256; _animated_tile_count++) {
if (_animated_tile_list[_animated_tile_count] == 0) break;
/* The first zero in the loaded array indicates the end of the list. */
for (int i = 0; i < 256; i++) {
if (anim_list[i] == 0) break;
*_animated_tiles.Append() = anim_list[i];
}
return true;
@@ -950,7 +946,7 @@ static const OldChunks _company_chunk[] = {
OCL_SVAR( OC_UINT8, Company, block_preview ),
OCL_CNULL( OC_TTD, 1 ), // Old AI
OCL_SVAR( OC_TTD | OC_UINT8, Company, avail_railtypes ),
OCL_CNULL( OC_TTD, 1 ), // avail_railtypes
OCL_SVAR( OC_TILE, Company, location_of_HQ ),
OCL_SVAR( OC_TTD | OC_UINT8, Company, share_owners[0] ),
OCL_SVAR( OC_TTD | OC_UINT8, Company, share_owners[1] ),

View File

@@ -41,6 +41,7 @@
#include "../fileio_func.h"
#include "../gamelog.h"
#include "../string_func.h"
#include "../string_func_extra.h"
#include "../fios.h"
#include "../error.h"
@@ -54,6 +55,7 @@
#include "../safeguards.h"
#include <deque>
#include <vector>
/*
@@ -268,8 +270,11 @@
* 193 26802
* 194 26881 1.5.x, 1.6.0
* 195 27572 1.6.x
* 196 27778 1.7.x
* 197 27978 1.8.x
* 198
*/
extern const uint16 SAVEGAME_VERSION = 195; ///< Current savegame version of OpenTTD.
extern const uint16 SAVEGAME_VERSION = 198; ///< Current savegame version of OpenTTD.
const uint16 SAVEGAME_VERSION_EXT = 0x8000; ///< Savegame extension indicator mask
SavegameType _savegame_type; ///< type of savegame we are loading
@@ -1082,6 +1087,18 @@ static inline size_t SlCalcNetStringLen(const char *ptr, size_t length)
return min(strlen(ptr), length - 1);
}
/**
* Calculate the gross length of the std::string that it
* will occupy in the savegame. This includes the real length,
* and the length that the index will occupy.
* @param str reference to the std::string
* @return return the gross length of the string
*/
static inline size_t SlCalcStdStrLen(const std::string &str)
{
return str.size() + SlGetArrayLength(str.size()); // also include the length of the index
}
/**
* Calculate the gross length of the string that it
* will occupy in the savegame. This includes the real length, returned
@@ -1193,6 +1210,41 @@ static void SlString(void *ptr, size_t length, VarType conv)
}
}
/**
* Save/Load a std::string.
* @param ptr the std::string being manipulated
* @param conv must be SLE_FILE_STRING
*/
static void SlStdString(std::string &str, VarType conv)
{
switch (_sl.action) {
case SLA_SAVE: {
SlWriteArrayLength(str.size());
SlCopyBytes(const_cast<char *>(str.data()), str.size());
break;
}
case SLA_LOAD_CHECK:
case SLA_LOAD: {
size_t len = SlReadArrayLength();
str.resize(len);
SlCopyBytes(const_cast<char *>(str.c_str()), len);
StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK;
if ((conv & SLF_ALLOW_CONTROL) != 0) {
settings = settings | SVS_ALLOW_CONTROL_CODE;
}
if ((conv & SLF_ALLOW_NEWLINE) != 0) {
settings = settings | SVS_ALLOW_NEWLINE;
}
str_validate(str, settings);
break;
}
case SLA_PTRS: break;
case SLA_NULL: break;
default: NOT_REACHED();
}
}
/**
* Return the size in bytes of a certain type of atomic array
* @param length The length of the array counted in elements
@@ -1377,9 +1429,10 @@ static void *IntToReference(size_t index, SLRefType rt)
* Return the size in bytes of a list
* @param list The std::list to find the size of
*/
template<typename PtrList>
static inline size_t SlCalcListLen(const void *list)
{
const std::list<void *> *l = (const std::list<void *> *) list;
const PtrList *l = (const PtrList *) list;
int type_size = IsSavegameVersionBefore(69) ? 2 : 4;
/* Each entry is saved as type_size bytes, plus type_size bytes are used for the length
@@ -1393,23 +1446,23 @@ static inline size_t SlCalcListLen(const void *list)
* @param list The list being manipulated
* @param conv SLRefType type of the list (Vehicle *, Station *, etc)
*/
template<typename PtrList>
static void SlList(void *list, SLRefType conv)
{
/* Automatically calculate the length? */
if (_sl.need_length != NL_NONE) {
SlSetLength(SlCalcListLen(list));
SlSetLength(SlCalcListLen<PtrList>(list));
/* Determine length only? */
if (_sl.need_length == NL_CALCLENGTH) return;
}
typedef std::list<void *> PtrList;
PtrList *l = (PtrList *)list;
switch (_sl.action) {
case SLA_SAVE: {
SlWriteUint32((uint32)l->size());
PtrList::iterator iter;
typename PtrList::iterator iter;
for (iter = l->begin(); iter != l->end(); ++iter) {
void *ptr = *iter;
SlWriteUint32((uint32)ReferenceToInt(ptr, conv));
@@ -1431,7 +1484,7 @@ static void SlList(void *list, SLRefType conv)
PtrList temp = *l;
l->clear();
PtrList::iterator iter;
typename PtrList::iterator iter;
for (iter = temp.begin(); iter != temp.end(); ++iter) {
void *ptr = IntToReference((size_t)*iter, conv);
l->push_back(ptr);
@@ -1497,6 +1550,9 @@ size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld)
case SL_ARR:
case SL_STR:
case SL_LST:
case SL_DEQ:
case SL_VEC:
case SL_STDSTR:
/* CONDITIONAL saveload types depend on the savegame version */
if (!SlIsObjectValidInSavegame(sld)) break;
@@ -1505,7 +1561,10 @@ size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld)
case SL_REF: return SlCalcRefLen();
case SL_ARR: return SlCalcArrayLen(sld->length, sld->conv);
case SL_STR: return SlCalcStringLen(GetVariableAddress(object, sld), sld->length, sld->conv);
case SL_LST: return SlCalcListLen(GetVariableAddress(object, sld));
case SL_LST: return SlCalcListLen<std::list<void *>>(GetVariableAddress(object, sld));
case SL_DEQ: return SlCalcListLen<std::deque<void *>>(GetVariableAddress(object, sld));
case SL_VEC: return SlCalcListLen<std::vector<void *>>(GetVariableAddress(object, sld));
case SL_STDSTR: return SlCalcStdStrLen(*static_cast<std::string *>(GetVariableAddress(object, sld)));
default: NOT_REACHED();
}
break;
@@ -1517,6 +1576,8 @@ size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld)
return 0;
}
#ifdef OTTD_ASSERT
/**
* Check whether the variable size of the variable in the saveload configuration
* matches with the actual variable size.
@@ -1552,14 +1613,21 @@ static bool IsVariableSizeRight(const SaveLoad *sld)
/* These should be pointer sized, or fixed array. */
return sld->size == sizeof(void *) || sld->size == sld->length;
case SL_STDSTR:
return sld->size == sizeof(std::string);
default:
return true;
}
}
#endif /* OTTD_ASSERT */
bool SlObjectMember(void *ptr, const SaveLoad *sld)
{
#ifdef OTTD_ASSERT
assert(IsVariableSizeRight(sld));
#endif
VarType conv = GB(sld->conv, 0, 8);
switch (sld->cmd) {
@@ -1568,6 +1636,9 @@ bool SlObjectMember(void *ptr, const SaveLoad *sld)
case SL_ARR:
case SL_STR:
case SL_LST:
case SL_DEQ:
case SL_VEC:
case SL_STDSTR:
/* CONDITIONAL saveload types depend on the savegame version */
if (!SlIsObjectValidInSavegame(sld)) return false;
if (SlSkipVariableOnLoad(sld)) return false;
@@ -1594,7 +1665,10 @@ bool SlObjectMember(void *ptr, const SaveLoad *sld)
break;
case SL_ARR: SlArray(ptr, sld->length, conv); break;
case SL_STR: SlString(ptr, sld->length, sld->conv); break;
case SL_LST: SlList(ptr, (SLRefType)conv); break;
case SL_LST: SlList<std::list<void *>>(ptr, (SLRefType)conv); break;
case SL_DEQ: SlList<std::deque<void *>>(ptr, (SLRefType)conv); break;
case SL_VEC: SlList<std::vector<void *>>(ptr, (SLRefType)conv); break;
case SL_STDSTR: SlStdString(*static_cast<std::string *>(ptr), sld->conv); break;
default: NOT_REACHED();
}
break;
@@ -2076,7 +2150,7 @@ struct LZOLoadFilter : LoadFilter {
byte out[LZO_BUFFER_SIZE + LZO_BUFFER_SIZE / 16 + 64 + 3 + sizeof(uint32) * 2];
uint32 tmp[2];
uint32 size;
lzo_uint len;
lzo_uint len = ssize;
/* Read header*/
if (this->chain->Read((byte*)tmp, sizeof(tmp)) != sizeof(tmp)) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE, "File read failed");
@@ -2098,7 +2172,8 @@ struct LZOLoadFilter : LoadFilter {
if (tmp[0] != lzo_adler32(0, out, size + sizeof(uint32))) SlErrorCorrupt("Bad checksum");
/* Decompress */
lzo1x_decompress_safe(out + sizeof(uint32) * 1, size, buf, &len, NULL);
int ret = lzo1x_decompress_safe(out + sizeof(uint32) * 1, size, buf, &len, NULL);
if (ret != LZO_E_OK) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
return len;
}
};
@@ -2848,10 +2923,9 @@ static SaveOrLoadResult DoLoad(LoadFilter *reader, bool load_check)
}
GamelogStopAction();
SlXvSetCurrentState();
}
SlXvSetCurrentState();
return SL_OK;
}

View File

@@ -52,7 +52,7 @@ enum SavegameType {
extern FileToSaveLoad _file_to_saveload;
void GenerateDefaultSaveName(char *buf, const char *last);
void SetSaveLoadError(uint16 str);
void SetSaveLoadError(StringID str);
const char *GetSaveLoadErrorString();
SaveOrLoadResult SaveOrLoad(const char *filename, SaveLoadOperation fop, DetailedFileType dft, Subdirectory sb, bool threaded = true);
void WaitTillSaved();
@@ -172,7 +172,7 @@ enum VarTypes {
SLE_INT64 = SLE_FILE_I64 | SLE_VAR_I64,
SLE_UINT64 = SLE_FILE_U64 | SLE_VAR_U64,
SLE_CHAR = SLE_FILE_I8 | SLE_VAR_CHAR,
SLE_STRINGID = SLE_FILE_STRINGID | SLE_VAR_U16,
SLE_STRINGID = SLE_FILE_STRINGID | SLE_VAR_U32,
SLE_STRINGBUF = SLE_FILE_STRING | SLE_VAR_STRB,
SLE_STRINGBQUOTE = SLE_FILE_STRING | SLE_VAR_STRBQ,
SLE_STRING = SLE_FILE_STRING | SLE_VAR_STR,
@@ -206,6 +206,9 @@ enum SaveLoadTypes {
SL_ARR = 2, ///< Save/load an array.
SL_STR = 3, ///< Save/load a string.
SL_LST = 4, ///< Save/load a list.
SL_DEQ = 5, ///< Save/load a deque.
SL_VEC = 6, ///< Save/load a vector.
SL_STDSTR = 7, ///< Save/load a std::string.
/* non-normal save-load types */
SL_WRITEBYTE = 8,
SL_VEH_INCLUDE = 9,
@@ -299,6 +302,18 @@ typedef SaveLoad SaveLoadGlobVarList;
#define SLE_CONDSTR_X(base, variable, type, length, from, to, extver) SLE_GENERAL_X(SL_STR, base, variable, type, length, from, to, extver)
#define SLE_CONDSTR(base, variable, type, length, from, to) SLE_CONDSTR_X(base, variable, type, length, from, to, SlXvFeatureTest())
/**
* Storage of a std::string in some savegame versions.
* @param base Name of the class or struct containing the string.
* @param variable Name of the variable in the class or struct referenced by \a base.
* @param type Storage of the data in memory and in the savegame.
* @param from First savegame version that has the string.
* @param to Last savegame version that has the string.
* @param extver SlXvFeatureTest to test (along with from and to) which savegames have the field
*/
#define SLE_CONDSTDSTR_X(base, variable, type, from, to, extver) SLE_GENERAL_X(SL_STDSTR, base, variable, type, 0, from, to, extver)
#define SLE_CONDSTDSTR(base, variable, type, from, to) SLE_CONDSTDSTR_X(base, variable, type, from, to, SlXvFeatureTest())
/**
* Storage of a list in some savegame versions.
* @param base Name of the class or struct containing the list.
@@ -311,6 +326,30 @@ typedef SaveLoad SaveLoadGlobVarList;
#define SLE_CONDLST_X(base, variable, type, from, to, extver) SLE_GENERAL_X(SL_LST, base, variable, type, 0, from, to, extver)
#define SLE_CONDLST(base, variable, type, from, to) SLE_CONDLST_X(base, variable, type, from, to, SlXvFeatureTest())
/**
* Storage of a deque in some savegame versions.
* @param base Name of the class or struct containing the list.
* @param variable Name of the variable in the class or struct referenced by \a base.
* @param type Storage of the data in memory and in the savegame.
* @param from First savegame version that has the list.
* @param to Last savegame version that has the list.
* @param extver SlXvFeatureTest to test (along with from and to) which savegames have the field
*/
#define SLE_CONDDEQ_X(base, variable, type, from, to, extver) SLE_GENERAL_X(SL_DEQ, base, variable, type, 0, from, to, extver)
#define SLE_CONDDEQ(base, variable, type, from, to) SLE_CONDDEQ_X(base, variable, type, from, to, SlXvFeatureTest())
/**
* Storage of a vector in some savegame versions.
* @param base Name of the class or struct containing the list.
* @param variable Name of the variable in the class or struct referenced by \a base.
* @param type Storage of the data in memory and in the savegame.
* @param from First savegame version that has the list.
* @param to Last savegame version that has the list.
* @param extver SlXvFeatureTest to test (along with from and to) which savegames have the field
*/
#define SLE_CONDVEC_X(base, variable, type, from, to, extver) SLE_GENERAL_X(SL_VEC, base, variable, type, 0, from, to, extver)
#define SLE_CONDVEC(base, variable, type, from, to) SLE_CONDVEC_X(base, variable, type, from, to, SlXvFeatureTest())
/**
* Storage of a variable in every version of a savegame.
* @param base Name of the class or struct containing the variable.
@@ -345,6 +384,14 @@ typedef SaveLoad SaveLoadGlobVarList;
*/
#define SLE_STR(base, variable, type, length) SLE_CONDSTR(base, variable, type, length, 0, SL_MAX_VERSION)
/**
* Storage of a std::string in every savegame version.
* @param base Name of the class or struct containing the string.
* @param variable Name of the variable in the class or struct referenced by \a base.
* @param type Storage of the data in memory and in the savegame.
*/
#define SLE_STDSTR(base, variable, type) SLE_CONDSTDSTR(base, variable, type, 0, SL_MAX_VERSION)
/**
* Storage of a list in every savegame version.
* @param base Name of the class or struct containing the list.
@@ -353,6 +400,22 @@ typedef SaveLoad SaveLoadGlobVarList;
*/
#define SLE_LST(base, variable, type) SLE_CONDLST(base, variable, type, 0, SL_MAX_VERSION)
/**
* Storage of a deque in every savegame version.
* @param base Name of the class or struct containing the list.
* @param variable Name of the variable in the class or struct referenced by \a base.
* @param type Storage of the data in memory and in the savegame.
*/
#define SLE_DEQ(base, variable, type) SLE_CONDDEQ(base, variable, type, 0, SL_MAX_VERSION)
/**
* Storage of a vector in every savegame version.
* @param base Name of the class or struct containing the list.
* @param variable Name of the variable in the class or struct referenced by \a base.
* @param type Storage of the data in memory and in the savegame.
*/
#define SLE_VEC(base, variable, type) SLE_CONDVEC(base, variable, type, 0, SL_MAX_VERSION)
/**
* Empty space in every savegame version.
* @param length Length of the empty space.
@@ -448,6 +511,28 @@ typedef SaveLoad SaveLoadGlobVarList;
#define SLEG_CONDLST_X(variable, type, from, to, extver) SLEG_GENERAL_X(SL_LST, variable, type, 0, from, to, extver)
#define SLEG_CONDLST(variable, type, from, to) SLEG_CONDLST_X(variable, type, from, to, SlXvFeatureTest())
/**
* Storage of a global deque in some savegame versions.
* @param variable Name of the global variable.
* @param type Storage of the data in memory and in the savegame.
* @param from First savegame version that has the list.
* @param to Last savegame version that has the list.
* @param extver SlXvFeatureTest to test (along with from and to) which savegames have the field
*/
#define SLEG_CONDDEQ_X(variable, type, from, to, extver) SLEG_GENERAL_X(SL_DEQ, variable, type, 0, from, to, extver)
#define SLEG_CONDDEQ(variable, type, from, to) SLEG_CONDDEQ_X(variable, type, from, to, SlXvFeatureTest())
/**
* Storage of a global vector in some savegame versions.
* @param variable Name of the global variable.
* @param type Storage of the data in memory and in the savegame.
* @param from First savegame version that has the list.
* @param to Last savegame version that has the list.
* @param extver SlXvFeatureTest to test (along with from and to) which savegames have the field
*/
#define SLEG_CONDVEC_X(variable, type, from, to, extver) SLEG_GENERAL_X(SL_VEC, variable, type, 0, from, to, extver)
#define SLEG_CONDVEC(variable, type, from, to) SLEG_CONDVEC_X(variable, type, from, to, SlXvFeatureTest())
/**
* Storage of a global variable in every savegame version.
* @param variable Name of the global variable.
@@ -483,6 +568,20 @@ typedef SaveLoad SaveLoadGlobVarList;
*/
#define SLEG_LST(variable, type) SLEG_CONDLST(variable, type, 0, SL_MAX_VERSION)
/**
* Storage of a global deque in every savegame version.
* @param variable Name of the global variable.
* @param type Storage of the data in memory and in the savegame.
*/
#define SLEG_DEQ(variable, type) SLEG_CONDDEQ(variable, type, 0, SL_MAX_VERSION)
/**
* Storage of a global vector in every savegame version.
* @param variable Name of the global variable.
* @param type Storage of the data in memory and in the savegame.
*/
#define SLEG_VEC(variable, type) SLEG_CONDVEC(variable, type, 0, SL_MAX_VERSION)
/**
* Empty global space in some savegame versions.
* @param length Length of the empty space.

View File

@@ -325,6 +325,10 @@ static void SwapPackets(GoodsEntry *ge)
static void Load_STNS()
{
_cargo_source_xy = 0;
_cargo_days = 0;
_cargo_feeder_share = 0;
int index;
while ((index = SlIterateArray()) != -1) {
Station *st = new (index) Station();
@@ -514,8 +518,9 @@ static void Save_STNN()
static void Load_STNN()
{
int index;
_num_flows = 0;
int index;
while ((index = SlIterateArray()) != -1) {
bool waypoint = (SlReadByte() & FACIL_WAYPOINT) != 0;

View File

@@ -11,6 +11,7 @@
#include "../stdafx.h"
#include "../string_func.h"
#include "../strings_func.h"
#include "saveload_internal.h"
#include "table/strings.h"
@@ -60,7 +61,7 @@ char *_old_name_array = NULL;
char *CopyFromOldName(StringID id)
{
/* Is this name an (old) custom name? */
if (GB(id, 11, 5) != 15) return NULL;
if (GetStringTab(id) != TEXT_TAB_OLD_CUSTOM) return NULL;
if (IsSavegameVersionBefore(37)) {
/* Allow for expansion when converted to UTF-8. */

View File

@@ -14,6 +14,7 @@
#include "../town.h"
#include "../landscape.h"
#include "../subsidy_func.h"
#include "../strings_func.h"
#include "saveload.h"
#include "newgrf_sl.h"
@@ -285,7 +286,7 @@ static void Load_TOWN()
SlObject(&t->received[i], _town_received_desc);
}
if (t->townnamegrfid == 0 && !IsInsideMM(t->townnametype, SPECSTR_TOWNNAME_START, SPECSTR_TOWNNAME_LAST + 1) && GB(t->townnametype, 11, 5) != 15) {
if (t->townnamegrfid == 0 && !IsInsideMM(t->townnametype, SPECSTR_TOWNNAME_START, SPECSTR_TOWNNAME_LAST + 1) && GetStringTab(t->townnametype) != TEXT_TAB_OLD_CUSTOM) {
SlErrorCorrupt("Invalid town name generator");
}
@@ -294,7 +295,7 @@ static void Load_TOWN()
SlObject(&t->cargo_accepted, GetTileMatrixDesc());
if (t->cargo_accepted.area.w != 0) {
uint arr_len = t->cargo_accepted.area.w / AcceptanceMatrix::GRID * t->cargo_accepted.area.h / AcceptanceMatrix::GRID;
t->cargo_accepted.data = MallocT<uint32>(arr_len);
t->cargo_accepted.data = MallocT<CargoTypes>(arr_len);
SlArray(t->cargo_accepted.data, arr_len, SLE_UINT32);
/* Rebuild total cargo acceptance. */

View File

@@ -375,6 +375,8 @@ void AfterLoadVehicles(bool part_of_load)
FOR_ALL_VEHICLES(v) {
assert(v->first != NULL);
v->trip_occupancy = CalcPercentVehicleFilled(v, NULL);
switch (v->type) {
case VEH_TRAIN: {
Train *t = Train::From(v);
@@ -431,7 +433,7 @@ void AfterLoadVehicles(bool part_of_load)
RoadVehicle *rv = RoadVehicle::From(v);
rv->roadtype = HasBit(EngInfo(v->First()->engine_type)->misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD;
rv->compatible_roadtypes = RoadTypeToRoadTypes(rv->roadtype);
/* FALL THROUGH */
FALLTHROUGH;
}
case VEH_TRAIN:
@@ -459,7 +461,7 @@ void AfterLoadVehicles(bool part_of_load)
default: break;
}
v->UpdateDeltaXY(v->direction);
v->UpdateDeltaXY();
v->coord.left = INVALID_COORD;
v->UpdatePosition();
v->UpdateViewport(false);