24 #include "../stdafx.h" 26 #include "../station_base.h" 27 #include "../thread.h" 29 #include "../network/network.h" 30 #include "../window_func.h" 31 #include "../strings_func.h" 32 #include "../core/endian_func.hpp" 33 #include "../vehicle_base.h" 34 #include "../company_func.h" 35 #include "../date_func.h" 36 #include "../autoreplace_base.h" 37 #include "../roadstop_base.h" 38 #include "../linkgraph/linkgraph.h" 39 #include "../linkgraph/linkgraphjob.h" 40 #include "../statusbar_gui.h" 41 #include "../fileio_func.h" 42 #include "../gamelog.h" 43 #include "../string_func.h" 48 #include "table/strings.h" 53 #include "../safeguards.h" 100 inline byte ReadByte()
102 if (this->bufp == this->bufe) {
103 size_t len = this->reader->
Read(this->buf,
lengthof(this->buf));
107 this->bufp = this->
buf;
108 this->bufe = this->buf + len;
111 return *this->bufp++;
120 return this->read - (this->bufe - this->
bufp);
138 for (
auto p : this->blocks) {
150 if (this->buf == this->bufe) {
152 this->blocks.push_back(this->buf);
169 size_t to_write =
min(MEMORY_CHUNK_SIZE, t);
171 writer->
Write(this->blocks[i++], to_write);
184 return this->blocks.size() * MEMORY_CHUNK_SIZE - (this->bufe - this->
buf);
241 extern const ChunkHandler _autoreplace_chunk_handlers[];
250 _gamelog_chunk_handlers,
252 _misc_chunk_handlers,
255 _setting_chunk_handlers,
257 _waypoint_chunk_handlers,
258 _depot_chunk_handlers,
259 _order_chunk_handlers,
260 _industry_chunk_handlers,
261 _economy_chunk_handlers,
262 _subsidy_chunk_handlers,
264 _goal_chunk_handlers,
265 _story_page_chunk_handlers,
266 _engine_chunk_handlers,
269 _station_chunk_handlers,
270 _company_chunk_handlers,
272 _game_chunk_handlers,
274 _newgrf_chunk_handlers,
275 _group_chunk_handlers,
277 _autoreplace_chunk_handlers,
278 _labelmaps_chunk_handlers,
279 _linkgraph_chunk_handlers,
280 _airport_chunk_handlers,
281 _object_chunk_handlers,
290 #define FOR_ALL_CHUNK_HANDLERS(ch) \ 291 for (const ChunkHandler * const *chsc = _chunk_handlers; *chsc != nullptr; chsc++) \ 292 for (const ChunkHandler *ch = *chsc; ch != nullptr; ch = (ch->flags & CH_LAST) ? nullptr : ch + 1) 304 DEBUG(sl, 1,
"Nulling pointers");
307 if (ch->ptrs_proc !=
nullptr) {
308 DEBUG(sl, 2,
"Nulling pointers for %c%c%c%c", ch->id >> 24, ch->id >> 16, ch->id >> 8, ch->id);
313 DEBUG(sl, 1,
"All pointers nulled");
346 GamelogStopAnyAction();
348 throw std::exception();
360 SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, msg);
375 va_start(ap, format);
393 if (_exit_game)
return;
394 while (_async_save_finish.load(std::memory_order_acquire) !=
nullptr)
CSleep(10);
396 _async_save_finish.store(proc, std::memory_order_release);
404 AsyncSaveFinishProc proc = _async_save_finish.exchange(
nullptr, std::memory_order_acq_rel);
405 if (proc ==
nullptr)
return;
409 if (_save_thread.joinable()) {
420 return _sl.
reader->ReadByte();
432 static inline int SlReadUint16()
438 static inline uint32 SlReadUint32()
440 uint32 x = SlReadUint16() << 16;
441 return x | SlReadUint16();
444 static inline uint64 SlReadUint64()
446 uint32 x = SlReadUint32();
447 uint32 y = SlReadUint32();
448 return (uint64)x << 32 | y;
451 static inline void SlWriteUint16(uint16 v)
457 static inline void SlWriteUint32(uint32 v)
459 SlWriteUint16(
GB(v, 16, 16));
460 SlWriteUint16(
GB(v, 0, 16));
463 static inline void SlWriteUint64(uint64 x)
465 SlWriteUint32((uint32)(x >> 32));
466 SlWriteUint32((uint32)x);
533 if (i >= (1 << 14)) {
534 if (i >= (1 << 21)) {
535 if (i >= (1 << 28)) {
536 assert(i <= UINT32_MAX);
557 return 1 + (i >= (1 << 7)) + (i >= (1 << 14)) + (i >= (1 << 21)) + (i >= (1 << 28));
560 static inline uint SlReadSparseIndex()
565 static inline void SlWriteSparseIndex(uint index)
570 static inline uint SlReadArrayLength()
575 static inline void SlWriteArrayLength(
size_t length)
580 static inline uint SlGetArrayLength(
size_t length)
593 static const byte conv_mem_size[] = {1, 1, 1, 2, 2, 4, 4, 8, 8, 0};
594 byte length =
GB(conv, 4, 4);
596 switch (length << 4) {
601 return SlReadArrayLength();
604 assert(length <
lengthof(conv_mem_size));
605 return conv_mem_size[length];
617 static const byte conv_file_size[] = {1, 1, 2, 2, 4, 4, 8, 8, 2};
618 byte length =
GB(conv, 0, 4);
619 assert(length <
lengthof(conv_file_size));
620 return conv_file_size[length];
629 void SlSetArrayIndex(uint index)
632 _sl.array_index = index;
635 static size_t _next_offs;
650 uint length = SlReadArrayLength();
660 case CH_SPARSE_ARRAY: index = (int)SlReadSparseIndex();
break;
661 case CH_ARRAY: index = _sl.array_index++;
break;
663 DEBUG(sl, 0,
"SlIterateArray error");
667 if (length != 0)
return index;
698 assert(length < (1 << 28));
699 SlWriteUint32((uint32)((length & 0xFFFFFF) | ((length >> 24) << 28)));
704 SlWriteArrayLength(1);
706 SlWriteArrayLength(length + 1);
708 case CH_SPARSE_ARRAY:
709 SlWriteArrayLength(length + 1 + SlGetArrayLength(_sl.array_index));
710 SlWriteSparseIndex(_sl.array_index);
712 default: NOT_REACHED();
720 default: NOT_REACHED();
732 byte *p = (byte *)ptr;
737 for (; length != 0; length--) *p++ =
SlReadByte();
742 default: NOT_REACHED();
762 case SLE_VAR_BL:
return (*(
const bool *)ptr != 0);
763 case SLE_VAR_I8:
return *(
const int8 *)ptr;
764 case SLE_VAR_U8:
return *(
const byte *)ptr;
765 case SLE_VAR_I16:
return *(
const int16 *)ptr;
766 case SLE_VAR_U16:
return *(
const uint16*)ptr;
767 case SLE_VAR_I32:
return *(
const int32 *)ptr;
768 case SLE_VAR_U32:
return *(
const uint32*)ptr;
769 case SLE_VAR_I64:
return *(
const int64 *)ptr;
770 case SLE_VAR_U64:
return *(
const uint64*)ptr;
772 default: NOT_REACHED();
786 case SLE_VAR_BL: *(
bool *)ptr = (val != 0);
break;
787 case SLE_VAR_I8: *(int8 *)ptr = val;
break;
788 case SLE_VAR_U8: *(byte *)ptr = val;
break;
789 case SLE_VAR_I16: *(int16 *)ptr = val;
break;
790 case SLE_VAR_U16: *(uint16*)ptr = val;
break;
791 case SLE_VAR_I32: *(int32 *)ptr = val;
break;
792 case SLE_VAR_U32: *(uint32*)ptr = val;
break;
793 case SLE_VAR_I64: *(int64 *)ptr = val;
break;
794 case SLE_VAR_U64: *(uint64*)ptr = val;
break;
797 default: NOT_REACHED();
817 case SLE_FILE_I8: assert(x >= -128 && x <= 127);
SlWriteByte(x);
break;
818 case SLE_FILE_U8: assert(x >= 0 && x <= 255);
SlWriteByte(x);
break;
819 case SLE_FILE_I16:assert(x >= -32768 && x <= 32767); SlWriteUint16(x);
break;
821 case SLE_FILE_U16:assert(x >= 0 && x <= 65535); SlWriteUint16(x);
break;
823 case SLE_FILE_U32: SlWriteUint32((uint32)x);
break;
825 case SLE_FILE_U64: SlWriteUint64(x);
break;
826 default: NOT_REACHED();
835 case SLE_FILE_I8: x = (int8 )
SlReadByte();
break;
836 case SLE_FILE_U8: x = (byte )
SlReadByte();
break;
837 case SLE_FILE_I16: x = (int16 )SlReadUint16();
break;
838 case SLE_FILE_U16: x = (uint16)SlReadUint16();
break;
839 case SLE_FILE_I32: x = (int32 )SlReadUint32();
break;
840 case SLE_FILE_U32: x = (uint32)SlReadUint32();
break;
841 case SLE_FILE_I64: x = (int64 )SlReadUint64();
break;
842 case SLE_FILE_U64: x = (uint64)SlReadUint64();
break;
844 default: NOT_REACHED();
853 default: NOT_REACHED();
868 if (ptr ==
nullptr)
return 0;
869 return min(strlen(ptr), length - 1);
887 default: NOT_REACHED();
890 str = *(
const char *
const *)ptr;
895 str = (
const char *)ptr;
901 return len + SlGetArrayLength(len);
910 static void SlString(
void *ptr,
size_t length, VarType conv)
916 default: NOT_REACHED();
928 SlWriteArrayLength(len);
934 size_t len = SlReadArrayLength();
937 default: NOT_REACHED();
941 DEBUG(sl, 1,
"String length in savegame is bigger than buffer, truncating");
953 *(
char **)ptr =
nullptr;
956 *(
char **)ptr = MallocT<char>(len + 1);
963 ((
char *)ptr)[len] =
'\0';
979 default: NOT_REACHED();
999 void SlArray(
void *array,
size_t length, VarType conv)
1014 if (conv == SLE_INT16 || conv == SLE_UINT16 || conv == SLE_STRINGID ||
1015 conv == SLE_INT32 || conv == SLE_UINT32) {
1020 if (conv == (SLE_FILE_I32 | SLE_VAR_I64)) {
1021 for (uint i = 0; i < length; i++) {
1022 ((int64*)array)[i] = (int32)
BSWAP32(SlReadUint32());
1030 if (conv == SLE_INT8 || conv == SLE_UINT8) {
1033 byte *a = (byte*)array;
1036 for (; length != 0; length --) {
1058 if (obj ==
nullptr)
return 0;
1073 default: NOT_REACHED();
1089 assert_compile(
sizeof(
size_t) <=
sizeof(
void *));
1154 default: NOT_REACHED();
1164 const std::list<void *> *l = (
const std::list<void *> *) list;
1169 return l->size() * type_size + type_size;
1187 typedef std::list<void *> PtrList;
1188 PtrList *l = (PtrList *)list;
1192 SlWriteUint32((uint32)l->size());
1194 PtrList::iterator iter;
1195 for (iter = l->begin(); iter != l->end(); ++iter) {
1206 for (
size_t i = 0; i < length; i++) {
1208 l->push_back((
void *)data);
1216 PtrList::iterator iter;
1217 for (iter = temp.begin(); iter != temp.end(); ++iter) {
1226 default: NOT_REACHED();
1234 template <
typename T>
1236 typedef std::deque<T> SlDequeT;
1245 const SlDequeT *l = (
const SlDequeT *)deque;
1260 SlDequeT *l = (SlDequeT *)deque;
1264 SlWriteUint32((uint32)l->size());
1266 typename SlDequeT::iterator iter;
1267 for (iter = l->begin(); iter != l->end(); ++iter) {
1274 size_t length = SlReadUint32();
1277 for (
size_t i = 0; i < length; i++) {
1289 default: NOT_REACHED();
1317 default: NOT_REACHED();
1349 default: NOT_REACHED();
1357 if (_sl_version < sld->version_from || _sl_version >= sld->
version_to)
return false;
1389 for (; sld->
cmd != SL_END; sld++) {
1390 length += SlCalcObjMemberLength(
object, sld);
1395 size_t SlCalcObjMemberLength(
const void *
object,
const SaveLoad *sld)
1416 default: NOT_REACHED();
1419 case SL_WRITEBYTE:
return 1;
1422 default: NOT_REACHED();
1440 return sld->
size ==
sizeof(bool);
1443 return sld->
size ==
sizeof(int8);
1446 return sld->
size ==
sizeof(int16);
1449 return sld->
size ==
sizeof(int32);
1452 return sld->
size ==
sizeof(int64);
1454 return sld->
size ==
sizeof(
void *);
1458 return sld->
size ==
sizeof(
void *);
1471 bool SlObjectMember(
void *ptr,
const SaveLoad *sld)
1477 VarType conv =
GB(sld->
conv, 0, 8);
1504 *(
void **)ptr =
nullptr;
1506 default: NOT_REACHED();
1513 default: NOT_REACHED();
1527 default: NOT_REACHED();
1532 case SL_VEH_INCLUDE:
1540 default: NOT_REACHED();
1558 for (; sld->
cmd != SL_END; sld++) {
1560 SlObjectMember(ptr, sld);
1616 _sl.array_index = 0;
1620 case CH_SPARSE_ARRAY:
1625 if ((m & 0xF) == CH_RIFF) {
1627 len = (
SlReadByte() << 16) | ((m >> 4) << 24);
1628 len += SlReadUint16();
1656 _sl.array_index = 0;
1663 case CH_SPARSE_ARRAY:
1671 if ((m & 0xF) == CH_RIFF) {
1673 len = (
SlReadByte() << 16) | ((m >> 4) << 24);
1674 len += SlReadUint16();
1723 ChunkSaveLoadProc *proc = ch->
save_proc;
1726 if (proc ==
nullptr)
return;
1728 SlWriteUint32(ch->
id);
1729 DEBUG(sl, 2,
"Saving chunk %c%c%c%c", ch->
id >> 24, ch->
id >> 16, ch->
id >> 8, ch->
id);
1731 if (ch->
flags & CH_AUTO_LENGTH) {
1733 _stub_save_proc = proc;
1738 switch (ch->
flags & CH_TYPE_MASK) {
1747 SlWriteArrayLength(0);
1749 case CH_SPARSE_ARRAY:
1752 SlWriteArrayLength(0);
1754 default: NOT_REACHED();
1787 for (
id = SlReadUint32();
id != 0;
id = SlReadUint32()) {
1788 DEBUG(sl, 2,
"Loading chunk %c%c%c%c",
id >> 24,
id >> 16,
id >> 8,
id);
1802 for (
id = SlReadUint32();
id != 0;
id = SlReadUint32()) {
1803 DEBUG(sl, 2,
"Loading chunk %c%c%c%c",
id >> 24,
id >> 16,
id >> 8,
id);
1816 DEBUG(sl, 1,
"Fixing pointers");
1819 if (ch->ptrs_proc !=
nullptr) {
1820 DEBUG(sl, 2,
"Fixing pointers for %c%c%c%c", ch->id >> 24, ch->id >> 16, ch->id >> 8, ch->id);
1825 DEBUG(sl, 1,
"All pointers fixed");
1847 if (this->file !=
nullptr) fclose(this->file);
1848 this->file =
nullptr;
1857 if (this->file ==
nullptr)
return 0;
1859 return fread(buf, 1, size, this->file);
1864 clearerr(this->file);
1865 if (fseek(this->file, this->begin, SEEK_SET)) {
1866 DEBUG(sl, 1,
"Could not reset the file reading");
1895 if (this->file ==
nullptr)
return;
1897 if (fwrite(buf, 1, size, this->file) != size)
SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE);
1902 if (this->file !=
nullptr) fclose(this->file);
1903 this->file =
nullptr;
1912 #include <lzo/lzo1x.h> 1925 if (lzo_init() != LZO_E_OK)
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR,
"cannot initialize decompressor");
1930 assert(ssize >= LZO_BUFFER_SIZE);
1933 byte out[LZO_BUFFER_SIZE + LZO_BUFFER_SIZE / 16 + 64 + 3 +
sizeof(uint32) * 2];
1936 lzo_uint len = ssize;
1939 if (this->chain->Read((byte*)tmp,
sizeof(tmp)) !=
sizeof(tmp))
SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE,
"File read failed");
1942 ((uint32*)out)[0] = size = tmp[1];
1945 tmp[0] = TO_BE32(tmp[0]);
1946 size = TO_BE32(size);
1952 if (this->chain->Read(out +
sizeof(uint32), size) != size)
SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
1955 if (tmp[0] != lzo_adler32(0, out, size +
sizeof(uint32)))
SlErrorCorrupt(
"Bad checksum");
1958 int ret = lzo1x_decompress_safe(out +
sizeof(uint32) * 1, size, buf, &len,
nullptr);
1959 if (ret != LZO_E_OK)
SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
1973 if (lzo_init() != LZO_E_OK)
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR,
"cannot initialize compressor");
1978 const lzo_bytep in =
buf;
1980 byte out[LZO_BUFFER_SIZE + LZO_BUFFER_SIZE / 16 + 64 + 3 +
sizeof(uint32) * 2];
1981 byte wrkmem[LZO1X_1_MEM_COMPRESS];
1986 lzo_uint len = size > LZO_BUFFER_SIZE ?
LZO_BUFFER_SIZE : (lzo_uint)size;
1987 lzo1x_1_compress(in, len, out +
sizeof(uint32) * 2, &outlen, wrkmem);
1988 ((uint32*)out)[1] = TO_BE32((uint32)outlen);
1989 ((uint32*)out)[0] = TO_BE32(lzo_adler32(0, out +
sizeof(uint32), outlen +
sizeof(uint32)));
1990 this->chain->Write(out, outlen +
sizeof(uint32) * 2);
2017 return this->chain->Read(buf, size);
2034 this->chain->Write(buf, size);
2042 #if defined(WITH_ZLIB) 2056 memset(&this->z, 0,
sizeof(this->z));
2057 if (inflateInit(&this->z) != Z_OK)
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR,
"cannot initialize decompressor");
2063 inflateEnd(&this->z);
2068 this->z.next_out =
buf;
2069 this->z.avail_out = (uint)size;
2073 if (this->z.avail_in == 0) {
2074 this->z.next_in = this->fread_buf;
2075 this->z.avail_in = (uint)this->chain->Read(this->fread_buf,
sizeof(this->fread_buf));
2079 int r = inflate(&this->z, 0);
2080 if (r == Z_STREAM_END)
break;
2082 if (r != Z_OK)
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR,
"inflate() failed");
2083 }
while (this->z.avail_out != 0);
2085 return size - this->z.avail_out;
2100 memset(&this->z, 0,
sizeof(this->z));
2101 if (deflateInit(&this->z, compression_level) != Z_OK)
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR,
"cannot initialize compressor");
2107 deflateEnd(&this->z);
2120 this->z.next_in = p;
2121 this->z.avail_in = (uInt)len;
2123 this->z.next_out =
buf;
2124 this->z.avail_out =
sizeof(
buf);
2133 int r = deflate(&this->z, mode);
2136 if ((n =
sizeof(buf) - this->z.avail_out) != 0) {
2137 this->chain->Write(buf, n);
2139 if (r == Z_STREAM_END)
break;
2141 if (r != Z_OK)
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR,
"zlib returned error code");
2142 }
while (this->z.avail_in || !this->z.avail_out);
2147 this->WriteLoop(buf, size, 0);
2152 this->WriteLoop(
nullptr, 0, Z_FINISH);
2153 this->chain->Finish();
2163 #if defined(WITH_LIBLZMA) 2186 if (lzma_auto_decoder(&this->lzma, 1 << 28, 0) != LZMA_OK)
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR,
"cannot initialize decompressor");
2192 lzma_end(&this->lzma);
2197 this->lzma.next_out =
buf;
2198 this->lzma.avail_out = size;
2202 if (this->lzma.avail_in == 0) {
2203 this->lzma.next_in = this->fread_buf;
2204 this->lzma.avail_in = this->chain->Read(this->fread_buf,
sizeof(this->fread_buf));
2208 lzma_ret r = lzma_code(&this->lzma, LZMA_RUN);
2209 if (r == LZMA_STREAM_END)
break;
2210 if (r != LZMA_OK)
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR,
"liblzma returned error code");
2211 }
while (this->lzma.avail_out != 0);
2213 return size - this->lzma.avail_out;
2228 if (lzma_easy_encoder(&this->lzma, compression_level, LZMA_CHECK_CRC32) != LZMA_OK)
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR,
"cannot initialize compressor");
2234 lzma_end(&this->lzma);
2247 this->lzma.next_in = p;
2248 this->lzma.avail_in = len;
2250 this->lzma.next_out =
buf;
2251 this->lzma.avail_out =
sizeof(
buf);
2253 lzma_ret r = lzma_code(&this->lzma, action);
2256 if ((n =
sizeof(buf) - this->lzma.avail_out) != 0) {
2257 this->chain->Write(buf, n);
2259 if (r == LZMA_STREAM_END)
break;
2260 if (r != LZMA_OK)
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR,
"liblzma returned error code");
2261 }
while (this->lzma.avail_in || !this->lzma.avail_out);
2266 this->WriteLoop(buf, size, LZMA_RUN);
2271 this->WriteLoop(
nullptr, 0, LZMA_FINISH);
2272 this->chain->Finish();
2297 #if defined(WITH_LZO) 2299 {
"lzo", TO_BE32X(
'OTTD'), CreateLoadFilter<LZOLoadFilter>, CreateSaveFilter<LZOSaveFilter>, 0, 0, 0},
2301 {
"lzo", TO_BE32X(
'OTTD'),
nullptr,
nullptr, 0, 0, 0},
2304 {
"none", TO_BE32X(
'OTTN'), CreateLoadFilter<NoCompLoadFilter>, CreateSaveFilter<NoCompSaveFilter>, 0, 0, 0},
2305 #if defined(WITH_ZLIB) 2309 {
"zlib", TO_BE32X(
'OTTZ'), CreateLoadFilter<ZlibLoadFilter>, CreateSaveFilter<ZlibSaveFilter>, 0, 6, 9},
2311 {
"zlib", TO_BE32X(
'OTTZ'),
nullptr,
nullptr, 0, 0, 0},
2313 #if defined(WITH_LIBLZMA) 2319 {
"lzma", TO_BE32X(
'OTTX'), CreateLoadFilter<LZMALoadFilter>, CreateSaveFilter<LZMASaveFilter>, 0, 2, 9},
2321 {
"lzma", TO_BE32X(
'OTTX'),
nullptr,
nullptr, 0, 0, 0},
2341 char *complevel = strrchr(s,
':');
2342 if (complevel !=
nullptr) *complevel =
'\0';
2344 for (
const SaveLoadFormat *slf = &_saveload_formats[0]; slf !=
endof(_saveload_formats); slf++) {
2345 if (slf->init_write !=
nullptr && strcmp(s, slf->name) == 0) {
2346 *compression_level = slf->default_compression;
2347 if (complevel !=
nullptr) {
2356 long level = strtol(complevel, &end, 10);
2357 if (end == complevel || level !=
Clamp(level, slf->min_compression, slf->max_compression)) {
2361 *compression_level = level;
2373 if (complevel !=
nullptr) *complevel =
':';
2380 void InitializeGame(uint size_x, uint size_y,
bool reset_date,
bool reset_settings);
2382 extern bool LoadOldSaveGame(
const char *file);
2389 ResetTempEngineData();
2391 ResetOldWaypoints();
2430 if (_game_mode != GM_MENU) _fast_forward = _sl.
ff_state;
2449 static char err_str[512];
2450 GetString(err_str, _sl.
action ==
SLA_SAVE ? STR_ERROR_GAME_SAVE_FAILED : STR_ERROR_GAME_LOAD_FAILED,
lastof(err_str));
2474 _sl.
sf->
Write((byte*)hdr,
sizeof(hdr));
2491 if (_sl.
error_str != STR_NETWORK_ERROR_LOSTCONNECTION) {
2506 void WaitTillSaved()
2508 if (!_save_thread.joinable())
return;
2510 _save_thread.join();
2533 SaveViewportBeforeSaveGame();
2539 if (threaded)
DEBUG(sl, 1,
"Cannot create savegame thread, reverting to single-threaded mode...");
2560 return DoSave(writer, threaded);
2585 if (_sl.
lf->
Read((byte*)hdr,
sizeof(hdr)) !=
sizeof(hdr))
SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
2591 if (fmt ==
endof(_saveload_formats)) {
2592 DEBUG(sl, 0,
"Unknown savegame type, trying to load it as the buggy format");
2595 _sl_minor_version = 0;
2600 if (fmt ==
endof(_saveload_formats)) {
2604 if (fmt->
tag == TO_BE32X(
'OTTD'))
break;
2610 if (fmt->
tag == hdr[0]) {
2616 _sl_minor_version = (TO_BE32(hdr[1]) >> 8) & 0xFF;
2618 DEBUG(sl, 1,
"Loading savegame version %d", _sl_version);
2632 SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, err_str);
2645 InitializeGame(256, 256,
true,
true);
2717 return DoLoad(reader,
false);
2748 InitializeGame(256, 256,
true,
true);
2756 if (!LoadOldSaveGame(filename))
return SL_REINIT;
2758 _sl_minor_version = 0;
2782 default: NOT_REACHED();
2792 if (fh ==
nullptr) {
2793 SlError(fop ==
SLO_SAVE ? STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE : STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
2805 DEBUG(desync, 1,
"load: %s", filename);
2847 case 0:
SetDParam(1, STR_JUST_DATE_LONG);
break;
2848 case 1:
SetDParam(1, STR_JUST_DATE_TINY);
break;
2849 case 2:
SetDParam(1, STR_JUST_DATE_ISO);
break;
2850 default: NOT_REACHED();
2855 GetString(buf, !
Company::IsValidID(cid) ? STR_SAVEGAME_NAME_SPECTATOR : STR_SAVEGAME_NAME_DEFAULT, last);
2883 this->file_op = fop;
2884 this->detail_ftype = dft;
2885 this->abstract_ftype = aft;
FiosType
Elements of a file system that are recognized.
~FileWriter()
Make sure everything is cleaned up.
void Write(byte *buf, size_t size) override
Write a given number of bytes into the savegame.
Owner
Enum for all companies/owners.
AbstractFileType
The different abstract types of files that the system knows about.
const ChunkHandler _name_chunk_handlers[]
Chunk handlers related to strings.
static SaveOrLoadResult DoLoad(LoadFilter *reader, bool load_check)
Actually perform the loading of a "non-old" savegame.
static void SlFixPointers()
Fix all pointers (convert index -> pointer)
static size_t SlCalcNetStringLen(const char *ptr, size_t length)
Calculate the net length of a string.
static void SlLoadCheckChunks()
Load all chunks for savegame checking.
void Finish() override
Prepare everything to finish writing the savegame.
static SaveOrLoadResult SaveFileToDisk(bool threaded)
We have written the whole game into memory, _memory_savegame, now find and appropriate compressor and...
bool _networking
are we in networking mode?
static SaveLoadParams _sl
Parameters used for/at saveload.
ChunkSaveLoadProc * load_check_proc
Load procedure for game preview.
const SaveLoad * GetVehicleDescription(VehicleType vt)
Make it possible to make the saveload tables "friends" of other classes.
static size_t SlCalcDequeLen(const void *deque, VarType conv)
Return the size in bytes of a std::deque.
static bool IsSavegameVersionBefore(SaveLoadVersion major, byte minor=0)
Checks whether the savegame is below major.
byte * bufe
End of the buffer we can read from.
GRFConfig * _grfconfig
First item in list of current GRF set up.
static uint SlCalcConvMemLen(VarType conv)
Return the size in bytes of a certain type of normal/atomic variable as it appears in memory...
Subdirectory
The different kinds of subdirectories OpenTTD uses.
LZMALoadFilter(LoadFilter *chain)
Initialise this filter.
Filter using Zlib compression.
void GenerateDefaultSaveName(char *buf, const char *last)
Fill the buffer with the default name for a savegame or screenshot.
NeedLength need_length
working in NeedLength (Autolength) mode?
z_stream z
Stream state we are reading from.
void WriteByte(byte b)
Write a single byte into the dumper.
void SetMouseCursorBusy(bool busy)
Set or unset the ZZZ cursor.
SaveLoadVersion
SaveLoad versions Previous savegame versions, the trunk revision where they were introduced and the r...
void NORETURN SlErrorCorrupt(const char *msg)
Error handler for corrupt savegames.
Yes, simply writing to a file.
static Titem * Get(size_t index)
Returns Titem with given index.
static bool SlSkipVariableOnLoad(const SaveLoad *sld)
Are we going to load this variable when loading a savegame or not?
string (with pre-allocated buffer)
void SetName(const char *name)
Set the name of the file.
uint32 flags
Flags of the chunk.
void ClearGRFConfigList(GRFConfig **config)
Clear a GRF Config list, freeing all nodes.
int CDECL seprintf(char *str, const char *last, const char *format,...)
Safer implementation of snprintf; same as snprintf except:
lzma_stream lzma
Stream state that we are reading from.
lzma_stream lzma
Stream state that we are writing to.
do not synchronize over network (but it is saved if SLF_NOT_IN_SAVE is not set)
static void SlList(void *list, SLRefType conv)
Save/Load a list.
static size_t SlCalcArrayLen(size_t length, VarType conv)
Return the size in bytes of a certain type of atomic array.
void NORETURN SlError(StringID string, const char *extra_msg)
Error handler.
FileToSaveLoad _file_to_saveload
File to save or load in the openttd loop.
ZlibLoadFilter(LoadFilter *chain)
Initialise this filter.
fluid_settings_t * settings
FluidSynth settings handle.
void GamelogStartAction(GamelogActionType at)
Stores information about new action, but doesn't allocate it Action is allocated only when there is a...
static uint SlReadSimpleGamma()
Read in the header descriptor of an object or an array.
uint32 id
Unique ID (4 letters).
int CDECL vseprintf(char *str, const char *last, const char *format, va_list ap)
Safer implementation of vsnprintf; same as vsnprintf except:
char * CopyFromOldName(StringID id)
Copy and convert old custom names to UTF-8.
LZMASaveFilter(SaveFilter *chain, byte compression_level)
Initialise this filter.
Filter using LZO compression.
bool saveinprogress
Whether there is currently a save in progress.
GRFListCompatibility IsGoodGRFConfigList(GRFConfig *grfconfig)
Check if all GRFs in the GRF config from a savegame can be loaded.
Load/save a reference to a link graph job.
Declaration of filters used for saving and loading savegames.
GRFConfig * grfconfig
NewGrf configuration from save.
long begin
The begin of the file.
int64 ReadValue(const void *ptr, VarType conv)
Return a signed-long version of the value of a setting.
byte buf[MEMORY_CHUNK_SIZE]
Buffer we're going to read from.
SaveOrLoadResult SaveWithFilter(SaveFilter *writer, bool threaded)
Save the game using a (writer) filter.
Load/save an old-style reference to a vehicle (for pre-4.4 savegames).
void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, WarningLevel wl, int x=0, int y=0, const GRFFile *textref_stack_grffile=nullptr, uint textref_stack_size=0, const uint32 *textref_stack=nullptr)
Display an error message in a window.
std::vector< byte * > blocks
Buffer with blocks of allocated memory.
static const SaveLoadFormat _saveload_formats[]
The different saveload formats known/understood by OpenTTD.
partial loading into _load_check_data
void CSleep(int milliseconds)
Sleep on the current thread for a defined time.
void Write(byte *buf, size_t size) override
Write a given number of bytes into the savegame.
void * address
address of variable OR offset of variable in the struct (max offset is 65536)
static void SaveFileDone()
Update the gui accordingly when saving is done and release locks on saveload.
DetailedFileType GetDetailedFileType(FiosType fios_type)
Extract the detailed file type from a FiosType.
const ChunkHandler _town_chunk_handlers[]
Chunk handler for towns.
void DoExitSave()
Do a save when exiting the game (_settings_client.gui.autosave_on_exit)
SaveLoadVersion _sl_version
the major savegame version identifier
Load/save a reference to a town.
#define lastof(x)
Get the last element of an fixed size array.
static void SetAsyncSaveFinish(AsyncSaveFinishProc proc)
Called by save thread to tell we finished saving.
const ChunkHandler _sign_chunk_handlers[]
Chunk handlers related to signs.
LoadFilter * reader
The filter used to actually read.
Filter without any compression.
virtual void Write(byte *buf, size_t len)=0
Write a given number of bytes into the savegame.
SavegameType
Types of save games.
void NORETURN SlErrorCorruptFmt(const char *format,...)
Issue an SlErrorCorrupt with a format string.
byte ff_state
The state of fast-forward when saving started.
static bool SlIsObjectValidInSavegame(const SaveLoad *sld)
Are we going to save this object or not?
size_t Read(byte *buf, size_t size) override
Read a given number of bytes from the savegame.
Deals with the type of the savegame, independent of extension.
size_t size
the sizeof size.
~ZlibLoadFilter()
Clean everything up.
size_t Read(byte *buf, size_t size) override
Read a given number of bytes from the savegame.
const char * GetSaveLoadErrorString()
Get the string representation of the error message.
FILE * file
The file to write to.
size_t SlGetFieldLength()
Get the length of the current object.
Load file for checking and/or preview.
void Write(byte *buf, size_t size) override
Write a given number of bytes into the savegame.
StringValidationSettings
Settings for the string validation.
not working in NeedLength mode
A connected component of a link graph.
static void SlSaveChunk(const ChunkHandler *ch)
Save a chunk of data (eg.
void SlArray(void *array, size_t length, VarType conv)
Save/Load an array.
void ProcessAsyncSaveFinish()
Handle async save finishes.
z_stream z
Stream state we are writing to.
Save game or scenario file.
Interface for filtering a savegame till it is loaded.
bool checkable
True if the savegame could be checked by SL_LOAD_CHECK. (Old savegames are not checkable.)
uint16 length
(conditional) length of the variable (eg. arrays) (max array size is 65536 elements) ...
Load/save a reference to a bus/truck stop.
virtual void Finish()
Prepare everything to finish writing the savegame.
Critical errors, the MessageBox is shown in all cases.
bool StartNewThread(std::thread *thr, const char *name, TFn &&_Fx, TArgs &&... _Ax)
Start a new thread.
Filter using Zlib compression.
static size_t SlCalcStringLen(const void *ptr, size_t length, VarType conv)
Calculate the gross length of the string that it will occupy in the savegame.
Shared order list linking together the linked list of orders and the list of vehicles sharing this or...
void SetDParamStr(uint n, const char *str)
This function is used to "bind" a C string to a OpenTTD dparam slot.
LoadCheckData _load_check_data
Data loaded from save during SL_LOAD_CHECK.
void WriteLoop(byte *p, size_t len, lzma_action action)
Helper loop for writing the data.
Base directory for all scenarios.
bool global
should we load a global variable or a non-global one
char _savegame_format[8]
how to compress savegames
void GamelogReset()
Resets and frees all memory allocated - used before loading or starting a new game.
void SetTitle(const char *title)
Set the title of the file.
Load/save a reference to an engine renewal (autoreplace).
ReadBuffer * reader
Savegame reading buffer.
VarType conv
type of the variable to be saved, int
static void SlCopyBytes(void *ptr, size_t length)
Save/Load bytes.
SLRefType
Type of reference (SLE_REF, SLE_CONDREF).
FILE * file
The file to read from.
const ChunkHandler _persistent_storage_chunk_handlers[]
Chunk handler for persistent storages.
DateFract _date_fract
Fractional part of the day.
allow new lines in the strings
Highest possible saveload version.
SaveOrLoadResult
Save or load result codes.
Filter using LZO compression.
void str_validate(char *str, const char *last, StringValidationSettings settings)
Scans the string for valid characters and if it finds invalid ones, replaces them with a question mar...
do not save with savegame, basically client-based
static void SlDeque(void *deque, VarType conv)
Save/load a std::deque.
Filter without any compression.
Old save game or scenario file.
~ZlibSaveFilter()
Clean up what we allocated.
allow control codes in the strings
static void SlSaveChunks()
Save all chunks.
5.0 1429 5.1 1440 5.2 1525 0.3.6
byte _sl_minor_version
the minor savegame version, DO NOT USE!
StringID offset into strings-array.
need to calculate the length
ClientSettings _settings_client
The current settings for this game.
static bool IsVariableSizeRight(const SaveLoad *sld)
Check whether the variable size of the variable in the saveload configuration matches with the actual...
FILE * FioFOpenFile(const char *filename, const char *mode, Subdirectory subdir, size_t *filesize)
Opens a OpenTTD file somewhere in a personal or global directory.
byte * bufe
End of the buffer we write to.
static std::atomic< AsyncSaveFinishProc > _async_save_finish
Callback to call when the savegame loading is finished.
Container for cargo from the same location and time.
static void SlDeque(void *deque, VarType conv)
Internal templated helper to save/load a std::deque.
uint8 date_format_in_default_names
should the default savegame/screenshot name use long dates (31th Dec 2008), short dates (31-12-2008) ...
void Clear()
Reset read data.
size_t SlCalcObjLength(const void *object, const SaveLoad *sld)
Calculate the size of an object.
Filter without any compression.
virtual void Reset()
Reset this filter to read from the beginning of the file.
const SaveLoad * GetBaseStationDescription()
Get the base station description to be used for SL_ST_INCLUDE.
Load/save a reference to a station.
const ChunkHandler _animated_tile_chunk_handlers[]
"Definition" imported by the saveload code to be able to load and save the animated tile table...
size_t obj_len
the length of the current object we are busy with
Base directory for all savegames.
Subdirectory of save for autosaves.
ReadBuffer(LoadFilter *reader)
Initialise our variables.
void SanitizeFilename(char *filename)
Sanitizes a filename, i.e.
Base directory for all subdirectories.
char * stredup(const char *s, const char *last)
Create a duplicate of the given string.
Class for pooled persistent storage of data.
static void SlLoadCheckChunk(const ChunkHandler *ch)
Load a chunk of data for checking savegames.
char * error_data
Data to pass to SetDParamStr when displaying error.
Load/save a reference to an order.
static std::thread _save_thread
The thread we're using to compress and write a savegame.
static void SlWriteSimpleGamma(size_t i)
Write the header descriptor of an object or an array.
void Write(byte *buf, size_t size) override
Write a given number of bytes into the savegame.
const SaveLoadVersion SAVEGAME_VERSION
Current savegame version of OpenTTD.
void Finish() override
Prepare everything to finish writing the savegame.
ZlibSaveFilter(SaveFilter *chain, byte compression_level)
Initialise this filter.
SaveOrLoadResult LoadWithFilter(LoadFilter *reader)
Load the game using a (reader) filter.
void SetSaveLoadError(StringID str)
Set the error message from outside of the actual loading/saving of the game (AfterLoadGame and friend...
static VarType GetVarFileType(VarType type)
Get the FileType of a setting.
AbstractFileType GetAbstractFileType(FiosType fios_type)
Extract the abstract file type from a FiosType.
MemoryDumper * dumper
Memory dumper to write the savegame to.
SaveOrLoadResult SaveOrLoad(const char *filename, SaveLoadOperation fop, DetailedFileType dft, Subdirectory sb, bool threaded)
Main Save or Load function where the high-level saveload functions are handled.
size_t GetSize() const
Get the size of the memory dump made so far.
static void SlLoadChunks()
Load all chunks.
void Write(byte *buf, size_t size) override
Write a given number of bytes into the savegame.
A buffer for reading (and buffering) savegame data.
#define lengthof(x)
Return the length of an fixed size array.
byte * buf
Buffer we're going to write to.
virtual size_t Read(byte *buf, size_t len)=0
Read a given number of bytes from the savegame.
static T min(const T a, const T b)
Returns the minimum of two values.
static const uint LZO_BUFFER_SIZE
Buffer size for the LZO compressor.
static uint SlGetGammaLength(size_t i)
Return how many bytes used to encode a gamma value.
byte SlReadByte()
Wrapper for reading a byte from the buffer.
StringID error
Error message from loading. INVALID_STRING_ID if no error.
static VarType GetVarMemType(VarType type)
Get the NumberType of a setting.
uint32 StringID
Numeric value that represents a string, independent of the selected language.
static void ResetSaveloadData()
Clear temporary data that is passed between various saveload phases.
static void SaveFileError()
Show a gui message when saving has failed.
ChunkSaveLoadProc * save_proc
Save procedure of the chunk.
SaveLoadOperation
Operation performed on the file.
int SlIterateArray()
Iterate through the elements of an array and read the whole thing.
ChunkSaveLoadProc * load_proc
Load procedure of the chunk.
Load/save a reference to a vehicle.
static const ChunkHandler * SlFindChunkHandler(uint32 id)
Find the ChunkHandler that will be used for processing the found chunk in the savegame or in memory...
void Reset() override
Reset this filter to read from the beginning of the file.
Handlers and description of chunk.
static void SlSkipBytes(size_t length)
Read in bytes from the file/data structure but don't do anything with them, discarding them in effect...
void SlSkipArray()
Skip an array or sparse array.
The saveload struct, containing reader-writer functions, buffer, version, etc.
byte * bufp
Location we're at reading the buffer.
static size_t SlCalcDequeLen(const void *deque, VarType conv)
Internal templated helper to return the size in bytes of a std::deque.
static T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
void GamelogStopAction()
Stops logging of any changes.
#define DEBUG(name, level,...)
Output a line of debugging information.
StringID RemapOldStringID(StringID s)
Remap a string ID from the old format to the new format.
string enclosed in quotes (with pre-allocated buffer)
static void ClearSaveLoadState()
Clear/free saveload state.
size_t Read(byte *buf, size_t size) override
Read a given number of bytes from the savegame.
static void * GetVariableAddress(const void *object, const SaveLoad *sld)
Get the address of the variable.
MemoryDumper()
Initialise our variables.
static const lzma_stream _lzma_init
Have a copy of an initialised LZMA stream.
bool AfterLoadGame()
Perform a (large) amount of savegame conversion magic in order to load older savegames and to fill th...
static void SlStubSaveProc2(void *arg)
Stub Chunk handlers to only calculate length and do nothing else.
SaveLoadAction action
are we doing a save or a load atm.
static const SaveLoadFormat * GetSavegameFormat(char *s, byte *compression_level)
Return the savegameformat of the game.
Load/save a reference to a cargo packet.
bool error
did an error occur or not
GUISettings gui
settings related to the GUI
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
const ChunkHandler _cargopacket_chunk_handlers[]
Chunk handlers related to cargo packets.
static const size_t MEMORY_CHUNK_SIZE
Save in chunks of 128 KiB.
static bool StrEmpty(const char *s)
Check if a string buffer is empty.
SaveLoadVersion version_to
save/load the variable until this savegame version
const ChunkHandler _cargomonitor_chunk_handlers[]
Chunk definition of the cargomonitoring maps.
static void SlNullPointers()
Null all pointers (convert index -> nullptr)
Replace the unknown/bad bits with question marks.
~LZMALoadFilter()
Clean everything up.
useful to write zeros in savegame.
string pointer enclosed in quotes
Invalid or unknown file type.
~FileReader()
Make sure everything is cleaned up.
Struct to store engine replacements.
static void SaveFileStart()
Update the gui accordingly when starting saving and set locks on saveload.
static uint GB(const T x, const uint8 s, const uint8 n)
Fetch n bits from x, started at bit s.
SaveLoadType cmd
the action to take with the saved/loaded type, All types need different action
char * strecpy(char *dst, const char *src, const char *last)
Copies characters from one buffer to another.
void SlObject(void *object, const SaveLoad *sld)
Main SaveLoad function.
#define endof(x)
Get the end element of an fixed size array.
static byte SlCalcConvFileLen(VarType conv)
Return the size in bytes of a certain type of normal/atomic variable as it appears in a saved game...
size_t Read(byte *buf, size_t size) override
Read a given number of bytes from the savegame.
Statusbar (at the bottom of your screen); Window numbers:
static bool IsValidID(size_t index)
Tests whether given index is a valid index for station of this type.
FileReader(FILE *file)
Create the file reader, so it reads from a specific file.
bool _network_server
network-server is active
A Stop for a Road Vehicle.
static bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
StringID error_str
the translatable error message to show
void SlGlobList(const SaveLoadGlobVarList *sldg)
Save or Load (a list of) global variables.
LZOSaveFilter(SaveFilter *chain, byte compression_level)
Initialise this filter.
char * extra_msg
the error message
void SlAutolength(AutolengthProc *proc, void *arg)
Do something of which I have no idea what it is :P.
const ChunkHandler _cheat_chunk_handlers[]
Chunk handlers related to cheats.
void str_fix_scc_encoded(char *str, const char *last)
Scan the string for old values of SCC_ENCODED and fix it to it's new, static value.
Allow the special control codes.
static const StringID INVALID_STRING_ID
Constant representing an invalid string (16bit in case it is used in savegames)
static size_t SlCalcListLen(const void *list)
Return the size in bytes of a list.
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
void Flush(SaveFilter *writer)
Flush this dumper into a writer.
SavegameType _savegame_type
type of savegame we are loading
SaveLoadAction
What are we currently doing?
SaveFilter * sf
Filter to write the savegame to.
bool threaded_saves
should we do threaded saves?
Load/save a reference to an orderlist.
Filter using LZMA compression.
static bool HasBit(const T x, const uint8 y)
Checks if a bit in a value is set.
Template class to help with std::deque.
Load/save a reference to a link graph.
FileWriter(FILE *file)
Create the file writer, so it writes to a specific file.
static void SlStubSaveProc()
Stub Chunk handlers to only calculate length and do nothing else.
void(* AsyncSaveFinishProc)()
Callback for when the savegame loading is finished.
void SlSetLength(size_t length)
Sets the length of either a RIFF object or the number of items in an array.
void SetMode(FiosType ft)
Set the mode and file type of the file to save or load based on the type of file entry at the file sy...
static void SlLoadChunk(const ChunkHandler *ch)
Load a chunk of data (eg vehicles, stations, etc.)
static uint32 BSWAP32(uint32 x)
Perform a 32 bits endianness bitswap on x.
size_t GetSize() const
Get the size of the memory dump made so far.
Interface for filtering a savegame till it is written.
static SaveOrLoadResult DoSave(SaveFilter *writer, bool threaded)
Actually perform the saving of the savegame.
NoCompSaveFilter(SaveFilter *chain, byte compression_level)
Initialise this filter.
LoadFilter * lf
Filter to read the savegame from.
Errors (eg. saving/loading failed)
static void SlString(void *ptr, size_t length, VarType conv)
Save/Load a string.
error that was caught before internal structures were modified
static Station * Get(size_t index)
Gets station with given index.
Date _date
Current date in days (day counter)
void Finish() override
Prepare everything to finish writing the savegame.
null all pointers (on loading error)
LZOLoadFilter(LoadFilter *chain)
Initialise this filter.
~LZMASaveFilter()
Clean up what we allocated.
size_t read
The amount of read bytes so far from the filter.
Declaration of functions used in more save/load files.
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
DetailedFileType
Kinds of files in each AbstractFileType.
size_t Read(byte *buf, size_t ssize) override
Read a given number of bytes from the savegame.
Container for dumping the savegame (quickly) to memory.
void WriteValue(void *ptr, VarType conv, int64 val)
Write the value of a setting.
void SlWriteByte(byte b)
Wrapper for writing a byte to the dumper.
GRFListCompatibility grf_compatibility
Summary state of NewGrfs, whether missing files or only compatible found.
static const ChunkHandler *const _chunk_handlers[]
Array of all chunks in a savegame, nullptr terminated.
static ChunkSaveLoadProc * _stub_save_proc
Stub Chunk handlers to only calculate length and do nothing else.
bool _do_autosave
are we doing an autosave at the moment?
NoCompLoadFilter(LoadFilter *chain)
Initialise this filter.
static size_t ReferenceToInt(const void *obj, SLRefType rt)
Pointers cannot be saved to a savegame, so this functions gets the index of the item, and if not available, it hussles with pointers (looks really bad :() Remember that a nullptr item has value 0, and all indices have +1, so vehicle 0 is saved as index 1.
int last_array_index
in the case of an array, the current and last positions
static void SlSaveLoadConv(void *ptr, VarType conv)
Handle all conversion and typechecking of variables here.
Class for calculation jobs to be run on link graphs.
static void * IntToReference(size_t index, SLRefType rt)
Pointers cannot be loaded from a savegame, so this function gets the index from the savegame and retu...
void InvalidateWindowData(WindowClass cls, WindowNumber number, int data, bool gui_scope)
Mark window data of the window of a given class and specific window number as invalid (in need of re-...
old custom name to be converted to a char pointer
4.0 1 4.1 122 0.3.3, 0.3.4 4.2 1222 0.3.5 4.3 1417 4.4 1426
uint32 _ttdp_version
version of TTDP savegame (if applicable)
static size_t SlCalcRefLen()
Return the size in bytes of a reference (pointer)
Load/save a reference to a persistent storage.
void WriteLoop(byte *p, size_t len, int mode)
Helper loop for writing the data.
#define FOR_ALL_CHUNK_HANDLERS(ch)
Iterate over all chunk handlers.
static void SetDParam(uint n, uint64 v)
Set a string parameter v at index n in the global string parameter array.
Yes, simply reading from a file.
error that was caught in the middle of updating game state, need to clear it. (can only happen during...