|
OpenTTD Source
13.0-beta2
|
Go to the documentation of this file.
23 #include "../stdafx.h"
25 #include "../station_base.h"
26 #include "../thread.h"
28 #include "../network/network.h"
29 #include "../window_func.h"
30 #include "../strings_func.h"
31 #include "../core/endian_func.hpp"
32 #include "../vehicle_base.h"
33 #include "../company_func.h"
34 #include "../date_func.h"
35 #include "../autoreplace_base.h"
36 #include "../roadstop_base.h"
37 #include "../linkgraph/linkgraph.h"
38 #include "../linkgraph/linkgraphjob.h"
39 #include "../statusbar_gui.h"
40 #include "../fileio_func.h"
41 #include "../gamelog.h"
42 #include "../string_func.h"
50 # include <emscripten.h>
53 #include "table/strings.h"
58 #include "../safeguards.h"
105 inline byte ReadByte()
107 if (this->bufp == this->bufe) {
108 size_t len = this->reader->
Read(this->buf,
lengthof(this->buf));
112 this->bufp = this->
buf;
113 this->bufe = this->buf + len;
116 return *this->bufp++;
125 return this->read - (this->bufe - this->
bufp);
143 for (
auto p : this->blocks) {
155 if (this->buf == this->bufe) {
157 this->blocks.push_back(this->buf);
176 writer->
Write(this->blocks[i++], to_write);
259 _gamelog_chunk_handlers,
261 _misc_chunk_handlers,
262 _name_chunk_handlers,
263 _cheat_chunk_handlers,
264 _setting_chunk_handlers,
266 _waypoint_chunk_handlers,
267 _depot_chunk_handlers,
268 _order_chunk_handlers,
269 _industry_chunk_handlers,
270 _economy_chunk_handlers,
271 _subsidy_chunk_handlers,
272 _cargomonitor_chunk_handlers,
273 _goal_chunk_handlers,
274 _story_page_chunk_handlers,
275 _league_chunk_handlers,
276 _engine_chunk_handlers,
277 _town_chunk_handlers,
278 _sign_chunk_handlers,
279 _station_chunk_handlers,
280 _company_chunk_handlers,
282 _game_chunk_handlers,
283 _animated_tile_chunk_handlers,
284 _newgrf_chunk_handlers,
285 _group_chunk_handlers,
286 _cargopacket_chunk_handlers,
287 _autoreplace_chunk_handlers,
288 _labelmaps_chunk_handlers,
289 _linkgraph_chunk_handlers,
290 _airport_chunk_handlers,
291 _object_chunk_handlers,
292 _persistent_storage_chunk_handlers,
295 static std::vector<ChunkHandlerRef> _chunk_handlers;
297 if (_chunk_handlers.empty()) {
298 for (
auto &chunk_handler_table : _chunk_handler_tables) {
299 for (
auto &chunk_handler : chunk_handler_table) {
300 _chunk_handlers.push_back(chunk_handler);
305 return _chunk_handlers;
319 Debug(sl, 3,
"Nulling pointers for {:c}{:c}{:c}{:c}", ch.id >> 24, ch.id >> 16, ch.id >> 8, ch.id);
354 GamelogStopAnyAction();
356 throw std::exception();
368 SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, msg);
383 va_start(ap, format);
401 if (_exit_game)
return;
413 if (proc ==
nullptr)
return;
440 static inline int SlReadUint16()
446 static inline uint32 SlReadUint32()
448 uint32 x = SlReadUint16() << 16;
449 return x | SlReadUint16();
452 static inline uint64 SlReadUint64()
454 uint32 x = SlReadUint32();
455 uint32 y = SlReadUint32();
456 return (uint64)x << 32 | y;
459 static inline void SlWriteUint16(uint16 v)
465 static inline void SlWriteUint32(uint32 v)
467 SlWriteUint16(
GB(v, 16, 16));
468 SlWriteUint16(
GB(v, 0, 16));
471 static inline void SlWriteUint64(uint64 x)
473 SlWriteUint32((uint32)(x >> 32));
474 SlWriteUint32((uint32)x);
531 if (i >= (1 << 14)) {
532 if (i >= (1 << 21)) {
533 if (i >= (1 << 28)) {
534 assert(i <= UINT32_MAX);
555 return 1 + (i >= (1 << 7)) + (i >= (1 << 14)) + (i >= (1 << 21)) + (i >= (1 << 28));
558 static inline uint SlReadSparseIndex()
563 static inline void SlWriteSparseIndex(uint index)
568 static inline uint SlReadArrayLength()
573 static inline void SlWriteArrayLength(
size_t length)
578 static inline uint SlGetArrayLength(
size_t length)
612 default: NOT_REACHED();
624 static const byte conv_mem_size[] = {1, 1, 1, 2, 2, 4, 4, 8, 8, 0};
630 return SlReadArrayLength();
634 assert(type <
lengthof(conv_mem_size));
635 return conv_mem_size[type];
647 static const byte conv_file_size[] = {0, 1, 1, 2, 2, 4, 4, 8, 8, 2};
650 assert(type <
lengthof(conv_file_size));
651 return conv_file_size[type];
660 void SlSetArrayIndex(uint index)
663 _sl.array_index = index;
666 static size_t _next_offs;
681 uint length = SlReadArrayLength();
697 case CH_SPARSE_TABLE:
698 case CH_SPARSE_ARRAY: index = (int)SlReadSparseIndex();
break;
700 case CH_ARRAY: index =
_sl.array_index++;
break;
702 Debug(sl, 0,
"SlIterateArray error");
706 if (length != 0)
return index;
734 SlWriteArrayLength(length + 1);
743 assert(length < (1 << 28));
744 SlWriteUint32((uint32)((length & 0xFFFFFF) | ((length >> 24) << 28)));
750 SlWriteArrayLength(1);
752 SlWriteArrayLength(length + 1);
754 case CH_SPARSE_TABLE:
755 case CH_SPARSE_ARRAY:
756 SlWriteArrayLength(length + 1 + SlGetArrayLength(
_sl.array_index));
757 SlWriteSparseIndex(
_sl.array_index);
759 default: NOT_REACHED();
767 default: NOT_REACHED();
779 byte *p = (
byte *)ptr;
784 for (; length != 0; length--) *p++ =
SlReadByte();
789 default: NOT_REACHED();
809 case SLE_VAR_BL:
return (*(
const bool *)ptr != 0);
810 case SLE_VAR_I8:
return *(
const int8 *)ptr;
811 case SLE_VAR_U8:
return *(
const byte *)ptr;
812 case SLE_VAR_I16:
return *(
const int16 *)ptr;
813 case SLE_VAR_U16:
return *(
const uint16*)ptr;
814 case SLE_VAR_I32:
return *(
const int32 *)ptr;
815 case SLE_VAR_U32:
return *(
const uint32*)ptr;
816 case SLE_VAR_I64:
return *(
const int64 *)ptr;
817 case SLE_VAR_U64:
return *(
const uint64*)ptr;
819 default: NOT_REACHED();
833 case SLE_VAR_BL: *(
bool *)ptr = (val != 0);
break;
834 case SLE_VAR_I8: *(int8 *)ptr = val;
break;
835 case SLE_VAR_U8: *(
byte *)ptr = val;
break;
836 case SLE_VAR_I16: *(int16 *)ptr = val;
break;
837 case SLE_VAR_U16: *(uint16*)ptr = val;
break;
838 case SLE_VAR_I32: *(int32 *)ptr = val;
break;
839 case SLE_VAR_U32: *(uint32*)ptr = val;
break;
840 case SLE_VAR_I64: *(int64 *)ptr = val;
break;
841 case SLE_VAR_U64: *(uint64*)ptr = val;
break;
844 default: NOT_REACHED();
864 case SLE_FILE_I8: assert(x >= -128 && x <= 127);
SlWriteByte(x);
break;
865 case SLE_FILE_U8: assert(x >= 0 && x <= 255);
SlWriteByte(x);
break;
866 case SLE_FILE_I16:assert(x >= -32768 && x <= 32767); SlWriteUint16(x);
break;
868 case SLE_FILE_U16:assert(x >= 0 && x <= 65535); SlWriteUint16(x);
break;
870 case SLE_FILE_U32: SlWriteUint32((uint32)x);
break;
872 case SLE_FILE_U64: SlWriteUint64(x);
break;
873 default: NOT_REACHED();
882 case SLE_FILE_I8: x = (int8 )
SlReadByte();
break;
883 case SLE_FILE_U8: x = (byte )
SlReadByte();
break;
884 case SLE_FILE_I16: x = (int16 )SlReadUint16();
break;
885 case SLE_FILE_U16: x = (uint16)SlReadUint16();
break;
886 case SLE_FILE_I32: x = (int32 )SlReadUint32();
break;
887 case SLE_FILE_U32: x = (uint32)SlReadUint32();
break;
888 case SLE_FILE_I64: x = (int64 )SlReadUint64();
break;
889 case SLE_FILE_U64: x = (uint64)SlReadUint64();
break;
891 default: NOT_REACHED();
900 default: NOT_REACHED();
915 if (ptr ==
nullptr)
return 0;
916 return std::min(strlen(ptr), length - 1);
934 default: NOT_REACHED();
937 str = *(
const char *
const *)ptr;
941 str = (
const char *)ptr;
947 return len + SlGetArrayLength(len);
959 const std::string *str =
reinterpret_cast<const std::string *
>(ptr);
961 size_t len = str->length();
962 return len + SlGetArrayLength(len);
971 static void SlString(
void *ptr,
size_t length, VarType conv)
977 default: NOT_REACHED();
988 SlWriteArrayLength(len);
994 size_t len = SlReadArrayLength();
997 default: NOT_REACHED();
1002 if (len >= length) {
1003 Debug(sl, 1,
"String length in savegame is bigger than buffer, truncating");
1013 free(*(
char **)ptr);
1015 *(
char **)ptr =
nullptr;
1018 *(
char **)ptr = MallocT<char>(len + 1);
1019 ptr = *(
char **)ptr;
1025 ((
char *)ptr)[len] =
'\0';
1041 default: NOT_REACHED();
1052 std::string *str =
reinterpret_cast<std::string *
>(ptr);
1056 size_t len = str->length();
1057 SlWriteArrayLength(len);
1058 SlCopyBytes(
const_cast<void *
>(
static_cast<const void *
>(str->c_str())), len);
1064 size_t len = SlReadArrayLength();
1070 char *buf =
AllocaM(
char, len + 1);
1092 default: NOT_REACHED();
1116 if (conv == SLE_INT16 || conv == SLE_UINT16 || conv == SLE_STRINGID ||
1117 conv == SLE_INT32 || conv == SLE_UINT32) {
1122 if (conv == (SLE_FILE_I32 | SLE_VAR_I64)) {
1123 for (uint i = 0; i < length; i++) {
1124 ((int64*)
object)[i] = (int32)
BSWAP32(SlReadUint32());
1132 if (conv == SLE_INT8 || conv == SLE_UINT8) {
1135 byte *a = (
byte*)
object;
1138 for (; length != 0; length --) {
1153 void SlCopy(
void *
object,
size_t length, VarType conv)
1183 static void SlArray(
void *array,
size_t length, VarType conv)
1187 SlWriteArrayLength(length);
1194 size_t sv_length = SlReadArrayLength();
1198 }
else if (sv_length != length) {
1233 if (obj ==
nullptr)
return 0;
1248 default: NOT_REACHED();
1264 static_assert(
sizeof(
size_t) <=
sizeof(
void *));
1329 default: NOT_REACHED();
1352 *(
void **)ptr =
nullptr;
1354 default: NOT_REACHED();
1361 template <
template<
typename,
typename>
typename Tstorage,
typename Tvar,
typename Tallocator = std::allocator<Tvar>>
1363 typedef Tstorage<Tvar, Tallocator> SlStorageT;
1375 const SlStorageT *list =
static_cast<const SlStorageT *
>(storage);
1377 int type_size = SlGetArrayLength(list->size());
1379 return list->size() * item_size + type_size;
1382 static void SlSaveLoadMember(
SaveLoadType cmd, Tvar *item, VarType conv)
1402 SlStorageT *list =
static_cast<SlStorageT *
>(storage);
1406 SlWriteArrayLength(list->size());
1408 for (
auto &item : *list) {
1409 SlSaveLoadMember(cmd, &item, conv);
1419 default: NOT_REACHED();
1423 for (
size_t i = 0; i < length; i++) {
1424 Tvar &data = list->emplace_back();
1425 SlSaveLoadMember(cmd, &data, conv);
1431 for (
auto &item : *list) {
1432 SlSaveLoadMember(cmd, &item, conv);
1440 default: NOT_REACHED();
1489 default: NOT_REACHED();
1510 default: NOT_REACHED();
1522 case SLE_VAR_BL: NOT_REACHED();
1531 default: NOT_REACHED();
1543 case SLE_VAR_BL: NOT_REACHED();
1552 default: NOT_REACHED();
1571 for (
auto &sld : slt) {
1580 for (
auto &sld : slt) {
1601 for (
auto &sld : slt) {
1602 length += SlCalcObjMemberLength(
object, sld);
1607 size_t SlCalcObjMemberLength(
const void *
object,
const SaveLoad &sld)
1636 sld.
handler->Save(
const_cast<void *
>(
object));
1643 length += SlGetArrayLength(1);
1649 default: NOT_REACHED();
1667 return sld.
size ==
sizeof(bool);
1670 return sld.
size ==
sizeof(int8);
1673 return sld.
size ==
sizeof(int16);
1676 return sld.
size ==
sizeof(int32);
1679 return sld.
size ==
sizeof(int64);
1681 return sld.
size ==
sizeof(std::string);
1683 return sld.
size ==
sizeof(
void *);
1687 return sld.
size ==
sizeof(
void *);
1695 return sld.
size ==
sizeof(std::string);
1702 static bool SlObjectMember(
void *
object,
const SaveLoad &sld)
1708 VarType conv =
GB(sld.
conv, 0, 8);
1729 default: NOT_REACHED();
1746 default: NOT_REACHED();
1760 default: NOT_REACHED();
1781 sld.
handler->LoadCheck(
object);
1794 sld.
handler->FixPointers(
object);
1798 default: NOT_REACHED();
1802 default: NOT_REACHED();
1819 SlWriteArrayLength(length);
1829 size_t length = SlReadArrayLength();
1848 for (
auto &sld : slt) {
1849 SlObjectMember(
object, sld);
1858 void Save(
void *
object)
const override
1863 void Load(
void *
object)
const override
1866 for (; length > 0; length--) {
1901 std::vector<SaveLoad> saveloads;
1904 std::map<std::string, const SaveLoad *> key_lookup;
1905 for (
auto &sld : slt) {
1909 assert(key_lookup.find(sld.
name) == key_lookup.end());
1910 key_lookup[sld.
name] = &sld;
1921 auto sld_it = key_lookup.find(key);
1922 if (sld_it == key_lookup.end()) {
1926 std::shared_ptr<SaveLoadHandler> handler =
nullptr;
1929 case SLE_FILE_STRING:
1934 case SLE_FILE_STRUCT:
1937 handler = std::make_shared<SlSkipHandler>();
1956 if (correct_type != type) {
1957 Debug(sl, 1,
"Field type for '{}' was expected to be 0x{:02x} but 0x{:02x} was found", key, correct_type, type);
1960 saveloads.push_back(*sld_it->second);
1963 for (
auto &sld : saveloads) {
1979 for (
auto &sld : slt) {
1982 assert(!sld.
name.empty());
1996 for (
auto &sld : slt) {
2012 default: NOT_REACHED();
2015 return std::vector<SaveLoad>();
2037 std::vector<SaveLoad> saveloads;
2040 std::map<std::string, std::vector<const SaveLoad *>> key_lookup;
2041 for (
auto &sld : slt) {
2043 assert(!sld.
name.empty());
2045 key_lookup[sld.
name].push_back(&sld);
2048 for (
auto &slc : slct) {
2049 if (slc.name.empty()) {
2053 saveloads.push_back({
"",
SL_NULL, SLE_FILE_U8 |
SLE_VAR_NULL, slc.length, slc.version_from, slc.version_to, 0,
nullptr, 0,
nullptr});
2055 auto sld_it = key_lookup.find(slc.name);
2059 if (sld_it == key_lookup.end()) {
2062 Debug(sl, 0,
"internal error: saveload compatibility field '{}' not found", slc.name);
2065 for (
auto &sld : sld_it->second) {
2066 saveloads.push_back(*sld);
2071 for (
auto &sld : saveloads) {
2122 case CH_SPARSE_TABLE:
2126 case CH_SPARSE_ARRAY:
2160 _sl.array_index = 0;
2164 case CH_SPARSE_TABLE:
2165 case CH_SPARSE_ARRAY:
2171 len = (
SlReadByte() << 16) | ((m >> 4) << 24);
2172 len += SlReadUint16();
2210 _sl.array_index = 0;
2213 case CH_SPARSE_TABLE:
2214 case CH_SPARSE_ARRAY:
2219 len = (
SlReadByte() << 16) | ((m >> 4) << 24);
2220 len += SlReadUint16();
2243 SlWriteUint32(ch.
id);
2244 Debug(sl, 2,
"Saving chunk {:c}{:c}{:c}{:c}", ch.
id >> 24, ch.
id >> 16, ch.
id >> 8, ch.
id);
2260 SlWriteArrayLength(0);
2262 case CH_SPARSE_TABLE:
2263 case CH_SPARSE_ARRAY:
2266 SlWriteArrayLength(0);
2268 default: NOT_REACHED();
2303 for (
id = SlReadUint32();
id != 0;
id = SlReadUint32()) {
2304 Debug(sl, 2,
"Loading chunk {:c}{:c}{:c}{:c}",
id >> 24,
id >> 16,
id >> 8,
id);
2318 for (
id = SlReadUint32();
id != 0;
id = SlReadUint32()) {
2319 Debug(sl, 2,
"Loading chunk {:c}{:c}{:c}{:c}",
id >> 24,
id >> 16,
id >> 8,
id);
2333 Debug(sl, 3,
"Fixing pointers for {:c}{:c}{:c}{:c}", ch.id >> 24, ch.id >> 16, ch.id >> 8, ch.id);
2357 if (this->file !=
nullptr) fclose(this->file);
2358 this->file =
nullptr;
2364 size_t Read(
byte *buf,
size_t size)
override
2367 if (this->file ==
nullptr)
return 0;
2369 return fread(buf, 1, size, this->file);
2374 clearerr(this->file);
2375 if (fseek(this->file, this->begin, SEEK_SET)) {
2376 Debug(sl, 1,
"Could not reset the file reading");
2402 void Write(
byte *buf,
size_t size)
override
2405 if (this->file ==
nullptr)
return;
2407 if (fwrite(buf, 1, size, this->file) != size)
SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE);
2412 if (this->file !=
nullptr) fclose(this->file);
2413 this->file =
nullptr;
2422 #include <lzo/lzo1x.h>
2435 if (lzo_init() != LZO_E_OK)
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR,
"cannot initialize decompressor");
2438 size_t Read(
byte *buf,
size_t ssize)
override
2446 lzo_uint len = ssize;
2449 if (this->
chain->
Read((
byte*)tmp,
sizeof(tmp)) !=
sizeof(tmp))
SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE,
"File read failed");
2452 ((uint32*)out)[0] = size = tmp[1];
2455 tmp[0] = TO_BE32(tmp[0]);
2456 size = TO_BE32(size);
2462 if (this->
chain->
Read(out +
sizeof(uint32), size) != size)
SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
2465 if (tmp[0] != lzo_adler32(0, out, size +
sizeof(uint32)))
SlErrorCorrupt(
"Bad checksum");
2468 int ret = lzo1x_decompress_safe(out +
sizeof(uint32) * 1, size, buf, &len,
nullptr);
2469 if (ret != LZO_E_OK)
SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
2483 if (lzo_init() != LZO_E_OK)
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR,
"cannot initialize compressor");
2486 void Write(
byte *buf,
size_t size)
override
2488 const lzo_bytep in = buf;
2491 byte wrkmem[LZO1X_1_MEM_COMPRESS];
2497 lzo1x_1_compress(in, len, out +
sizeof(uint32) * 2, &outlen, wrkmem);
2498 ((uint32*)out)[1] = TO_BE32((uint32)outlen);
2499 ((uint32*)out)[0] = TO_BE32(lzo_adler32(0, out +
sizeof(uint32), outlen +
sizeof(uint32)));
2500 this->
chain->
Write(out, outlen +
sizeof(uint32) * 2);
2525 size_t Read(
byte *buf,
size_t size)
override
2527 return this->chain->
Read(buf, size);
2542 void Write(
byte *buf,
size_t size)
override
2544 this->chain->Write(buf, size);
2552 #if defined(WITH_ZLIB)
2566 memset(&this->z, 0,
sizeof(this->z));
2567 if (inflateInit(&this->z) != Z_OK)
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR,
"cannot initialize decompressor");
2573 inflateEnd(&this->z);
2576 size_t Read(
byte *buf,
size_t size)
override
2578 this->z.next_out = buf;
2579 this->z.avail_out = (uint)size;
2583 if (this->z.avail_in == 0) {
2585 this->z.avail_in = (uint)this->chain->
Read(this->fread_buf,
sizeof(this->fread_buf));
2589 int r = inflate(&this->z, 0);
2590 if (r == Z_STREAM_END)
break;
2592 if (r != Z_OK)
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR,
"inflate() failed");
2593 }
while (this->z.avail_out != 0);
2595 return size - this->z.avail_out;
2610 memset(&this->z, 0,
sizeof(this->z));
2611 if (deflateInit(&this->z, compression_level) != Z_OK)
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR,
"cannot initialize compressor");
2617 deflateEnd(&this->z);
2630 this->z.next_in = p;
2631 this->z.avail_in = (uInt)len;
2633 this->z.next_out = buf;
2634 this->z.avail_out =
sizeof(buf);
2643 int r = deflate(&this->z, mode);
2646 if ((n =
sizeof(buf) - this->z.avail_out) != 0) {
2647 this->chain->Write(buf, n);
2649 if (r == Z_STREAM_END)
break;
2651 if (r != Z_OK)
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR,
"zlib returned error code");
2652 }
while (this->z.avail_in || !this->z.avail_out);
2655 void Write(
byte *buf,
size_t size)
override
2663 this->chain->Finish();
2673 #if defined(WITH_LIBLZMA)
2696 if (lzma_auto_decoder(&this->lzma, 1 << 28, 0) != LZMA_OK)
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR,
"cannot initialize decompressor");
2702 lzma_end(&this->lzma);
2705 size_t Read(
byte *buf,
size_t size)
override
2707 this->lzma.next_out = buf;
2708 this->lzma.avail_out = size;
2712 if (this->lzma.avail_in == 0) {
2714 this->lzma.avail_in = this->chain->
Read(this->fread_buf,
sizeof(this->fread_buf));
2718 lzma_ret r = lzma_code(&this->lzma, LZMA_RUN);
2719 if (r == LZMA_STREAM_END)
break;
2720 if (r != LZMA_OK)
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR,
"liblzma returned error code");
2721 }
while (this->lzma.avail_out != 0);
2723 return size - this->lzma.avail_out;
2738 if (lzma_easy_encoder(&this->lzma, compression_level, LZMA_CHECK_CRC32) != LZMA_OK)
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR,
"cannot initialize compressor");
2744 lzma_end(&this->lzma);
2757 this->lzma.next_in = p;
2758 this->lzma.avail_in = len;
2760 this->lzma.next_out = buf;
2761 this->lzma.avail_out =
sizeof(buf);
2763 lzma_ret r = lzma_code(&this->lzma, action);
2766 if ((n =
sizeof(buf) - this->lzma.avail_out) != 0) {
2767 this->chain->Write(buf, n);
2769 if (r == LZMA_STREAM_END)
break;
2770 if (r != LZMA_OK)
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR,
"liblzma returned error code");
2771 }
while (this->lzma.avail_in || !this->lzma.avail_out);
2774 void Write(
byte *buf,
size_t size)
override
2781 this->
WriteLoop(
nullptr, 0, LZMA_FINISH);
2782 this->chain->Finish();
2807 #if defined(WITH_LZO)
2809 {
"lzo", TO_BE32X(
'OTTD'), CreateLoadFilter<LZOLoadFilter>, CreateSaveFilter<LZOSaveFilter>, 0, 0, 0},
2811 {
"lzo", TO_BE32X(
'OTTD'),
nullptr,
nullptr, 0, 0, 0},
2814 {
"none", TO_BE32X(
'OTTN'), CreateLoadFilter<NoCompLoadFilter>, CreateSaveFilter<NoCompSaveFilter>, 0, 0, 0},
2815 #if defined(WITH_ZLIB)
2819 {
"zlib", TO_BE32X(
'OTTZ'), CreateLoadFilter<ZlibLoadFilter>, CreateSaveFilter<ZlibSaveFilter>, 0, 6, 9},
2821 {
"zlib", TO_BE32X(
'OTTZ'),
nullptr,
nullptr, 0, 0, 0},
2823 #if defined(WITH_LIBLZMA)
2829 {
"lzma", TO_BE32X(
'OTTX'), CreateLoadFilter<LZMALoadFilter>, CreateSaveFilter<LZMASaveFilter>, 0, 2, 9},
2831 {
"lzma", TO_BE32X(
'OTTX'),
nullptr,
nullptr, 0, 0, 0},
2849 if (!full_name.empty()) {
2851 size_t separator = full_name.find(
':');
2852 bool has_comp_level = separator != std::string::npos;
2853 const std::string name(full_name, 0, has_comp_level ? separator : full_name.size());
2856 if (slf->init_write !=
nullptr && name.compare(slf->name) == 0) {
2857 *compression_level = slf->default_compression;
2858 if (has_comp_level) {
2859 const std::string complevel(full_name, separator + 1);
2863 long level = std::stol(complevel, &processed, 10);
2864 if (processed == 0 || level !=
Clamp(level, slf->min_compression, slf->max_compression)) {
2868 *compression_level = level;
2884 void InitializeGame(uint size_x, uint size_y,
bool reset_date,
bool reset_settings);
2886 extern bool LoadOldSaveGame(
const std::string &file);
2893 ResetTempEngineData();
2895 ResetOldWaypoints();
2940 #ifdef __EMSCRIPTEN__
2941 EM_ASM(
if (window[
"openttd_syncfs"]) openttd_syncfs());
2957 static char err_str[512];
2958 GetString(err_str,
_sl.
action ==
SLA_SAVE ? STR_ERROR_GAME_SAVE_FAILED : STR_ERROR_GAME_LOAD_FAILED,
lastof(err_str));
2999 if (
_sl.
error_str != STR_NETWORK_ERROR_LOSTCONNECTION) {
3014 void WaitTillSaved()
3041 SaveViewportBeforeSaveGame();
3047 if (threaded)
Debug(sl, 1,
"Cannot create savegame thread, reverting to single-threaded mode...");
3068 return DoSave(writer, threaded);
3093 if (
_sl.
lf->
Read((
byte*)hdr,
sizeof(hdr)) !=
sizeof(hdr))
SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
3100 Debug(sl, 0,
"Unknown savegame type, trying to load it as the buggy format");
3112 if (fmt->
tag == TO_BE32X(
'OTTD'))
break;
3118 if (fmt->
tag == hdr[0]) {
3141 SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, err_str);
3154 InitializeGame(256, 256,
true,
true);
3226 return DoLoad(reader,
false);
3257 InitializeGame(256, 256,
true,
true);
3265 if (!LoadOldSaveGame(filename))
return SL_REINIT;
3291 default: NOT_REACHED();
3301 if (fh ==
nullptr) {
3302 SlError(fop ==
SLO_SAVE ? STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE : STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
3314 Debug(desync, 1,
"load: {}", filename);
3344 Debug(sl, 2,
"Autosaving to '{}'", buf);
3379 case 0:
SetDParam(1, STR_JUST_DATE_LONG);
break;
3380 case 1:
SetDParam(1, STR_JUST_DATE_TINY);
break;
3381 case 2:
SetDParam(1, STR_JUST_DATE_ISO);
break;
3382 default: NOT_REACHED();
3387 GetString(buf, !
Company::IsValidID(cid) ? STR_SAVEGAME_NAME_SPECTATOR : STR_SAVEGAME_NAME_DEFAULT, last);
3440 assert(this->load_description.has_value());
3441 return *this->load_description;
char title[255]
Internal name of the game.
@ SL_NULL
Save null-bytes and load to nowhere.
byte fread_buf[MEMORY_CHUNK_SIZE]
Buffer for reading from the file.
static void SlLoadChunks()
Load all chunks.
static size_t SlCalcTableHeader(const SaveLoadTable &slt)
Calculate the size of the table header.
static void ResetSaveloadData()
Clear temporary data that is passed between various saveload phases.
static bool IsVariableSizeRight(const SaveLoad &sld)
Check whether the variable size of the variable in the saveload configuration matches with the actual...
static void SlSaveLoad(void *storage, VarType conv, SaveLoadType cmd=SL_VAR)
Internal templated helper to save/load a list-like type.
void SetMouseCursorBusy(bool busy)
Set or unset the ZZZ cursor.
SaveLoadVersion version_to
Save/load the variable before this savegame version.
FileWriter(FILE *file)
Create the file writer, so it writes to a specific file.
static bool SlIsObjectValidInSavegame(const SaveLoad &sld)
Are we going to save this object or not?
lzma_stream lzma
Stream state that we are writing to.
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-...
static const uint LZO_BUFFER_SIZE
Buffer size for the LZO compressor.
@ REF_ORDER
Load/save a reference to an order.
SaveLoadType
Type of data saved.
static void SlDeque(void *deque, VarType conv)
Save/load a std::deque.
static void SlLoadChunk(const ChunkHandler &ch)
Load a chunk of data (eg vehicles, stations, etc.)
bool checkable
True if the savegame could be checked by SL_LOAD_CHECK. (Old savegames are not checkable....
void SetSaveLoadError(StringID str)
Set the error message from outside of the actual loading/saving of the game (AfterLoadGame and friend...
~ZlibLoadFilter()
Clean everything up.
static Titem * Get(size_t index)
Returns Titem with given index.
@ SAVE_DIR
Base directory for all savegames.
static void SlArray(void *array, size_t length, VarType conv)
Save/Load the length of the array followed by the array of SL_VAR elements.
@ SVS_ALLOW_NEWLINE
Allow newlines.
A connected component of a link graph.
static std::thread _save_thread
The thread we're using to compress and write a savegame.
@ SLE_VAR_STR
string pointer
static uint GB(const T x, const uint8 s, const uint8 n)
Fetch n bits from x, started at bit s.
LZMALoadFilter(LoadFilter *chain)
Initialise this filter.
static VarType GetVarFileType(VarType type)
Get the FileType of a setting.
LZMASaveFilter(SaveFilter *chain, byte compression_level)
Initialise this filter.
Filter without any compression.
byte _sl_minor_version
the minor savegame version, DO NOT USE!
byte fread_buf[MEMORY_CHUNK_SIZE]
Buffer for reading from the file.
StringID RemapOldStringID(StringID s)
Remap a string ID from the old format to the new format.
void CSleep(int milliseconds)
Sleep on the current thread for a defined time.
@ SL_MIN_VERSION
First savegame version.
@ REF_TOWN
Load/save a reference to a town.
void DoExitSave()
Do a save when exiting the game (_settings_client.gui.autosave_on_exit)
void ClearGRFConfigList(GRFConfig **config)
Clear a GRF Config list, freeing all nodes.
NoCompLoadFilter(LoadFilter *chain)
Initialise this filter.
uint8 date_format_in_default_names
should the default savegame/screenshot name use long dates (31th Dec 2008), short dates (31-12-2008) ...
NoCompSaveFilter(SaveFilter *chain, byte compression_level)
Initialise this filter.
@ SL_STR
Save/load a string.
@ REF_ROADSTOPS
Load/save a reference to a bus/truck stop.
void SetTitle(const char *title)
Set the title of the file.
@ SLE_FILE_END
Used to mark end-of-header in tables.
size_t Read(byte *buf, size_t size) override
Read a given number of bytes from the savegame.
void SlSkipArray()
Skip an array or sparse array.
Class for calculation jobs to be run on link graphs.
SaveOrLoadResult SaveOrLoad(const std::string &filename, SaveLoadOperation fop, DetailedFileType dft, Subdirectory sb, bool threaded)
Main Save or Load function where the high-level saveload functions are handled.
DateFract _date_fract
Fractional part of the day.
bool _network_server
network-server is active
SaveLoadOperation
Operation performed on the file.
void SlCopy(void *object, size_t length, VarType conv)
Copy a list of SL_VARs to/from a savegame.
std::string name
Name of the file.
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.
long begin
The begin of the file.
size_t size
The sizeof size.
LoadCheckData _load_check_data
Data loaded from save during SL_LOAD_CHECK.
LZOLoadFilter(LoadFilter *chain)
Initialise this filter.
bool AfterLoadGame()
Perform a (large) amount of savegame conversion magic in order to load older savegames and to fill th...
@ SLF_ALLOW_NEWLINE
Allow new lines in the strings.
ZlibLoadFilter(LoadFilter *chain)
Initialise this filter.
static void SlSaveChunks()
Save all chunks.
@ SLA_LOAD_CHECK
partial loading into _load_check_data
@ SLO_CHECK
Load file for checking and/or preview.
#define SLE_STR(base, variable, type, length)
Storage of a string in every savegame version.
static bool HasBit(const T x, const uint8 y)
Checks if a bit in a value is set.
MemoryDumper()
Initialise our variables.
bool _do_autosave
are we doing an autosave at the moment?
LZOSaveFilter(SaveFilter *chain, byte compression_level)
Initialise this filter.
size_t GetSize() const
Get the size of the memory dump made so far.
@ DFT_GAME_FILE
Save game or scenario file.
Deals with the type of the savegame, independent of extension.
GRFConfig * grfconfig
NewGrf configuration from save.
void SetName(const char *name)
Set the name of the file.
@ SLE_VAR_NULL
useful to write zeros in savegame.
size_t Read(byte *buf, size_t ssize) override
Read a given number of bytes from the savegame.
static uint8 GetSavegameFileType(const SaveLoad &sld)
Return the type as saved/loaded inside the savegame.
SaveLoadTable GetLoadDescription() const
Get the description for how to load the chunk.
ChunkType type
Type of the chunk.
uint16 length
(Conditional) length of the variable (eg. arrays) (max array size is 65536 elements).
A buffer for reading (and buffering) savegame data.
static Station * Get(size_t index)
Gets station with given index.
@ AUTOSAVE_DIR
Subdirectory of save for autosaves.
ClientSettings _settings_client
The current settings for this game.
DetailedFileType GetDetailedFileType(FiosType fios_type)
Extract the detailed file type from a FiosType.
static void SlNullPointers()
Null all pointers (convert index -> nullptr)
static bool IsValidID(size_t index)
Tests whether given index is a valid index for station of this type.
ReadBuffer * reader
Savegame reading buffer.
Filter using Zlib compression.
SaveOrLoadResult LoadWithFilter(LoadFilter *reader)
Load the game using a (reader) filter.
Handlers and description of chunk.
VarType conv
Type of the variable to be saved; this field combines both FileVarType and MemVarType.
void WriteLoop(byte *p, size_t len, lzma_action action)
Helper loop for writing the data.
Owner
Enum for all companies/owners.
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.
SaveLoadAction
What are we currently doing?
virtual void Reset()
Reset this filter to read from the beginning of the file.
SaveFilter * sf
Filter to write the savegame to.
Handler for saving/loading an object to/from disk.
void Load(void *object) const override
Load the object from disk.
static void SetDParam(uint n, uint64 v)
Set a string parameter v at index n in the global string parameter array.
static size_t SlCalcStdStringLen(const void *ptr)
Calculate the gross length of the string that it will occupy in the savegame.
@ NL_NONE
not working in NeedLength mode
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.
size_t Read(byte *buf, size_t size) override
Read a given number of bytes from the savegame.
z_stream z
Stream state we are writing to.
static uint SlReadSimpleGamma()
Read in the header descriptor of an object or an array.
@ SLE_FILE_TYPE_MASK
Mask to get the file-type (and not any flags).
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.
LoadFilter * reader
The filter used to actually read.
byte * buf
Buffer we're going to write to.
void SlGlobList(const SaveLoadTable &slt)
Save or Load (a list of) global variables.
Filter without any compression.
@ REF_STATION
Load/save a reference to a station.
Filter without any compression.
@ SLE_VAR_STRB
string (with pre-allocated buffer)
static uint SlCalcConvMemLen(VarType conv)
Return the size in bytes of a certain type of normal/atomic variable as it appears in memory.
AbstractFileType
The different abstract types of files that the system knows about.
virtual size_t Read(byte *buf, size_t len)=0
Read a given number of bytes from the savegame.
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,...
AbstractFileType abstract_ftype
Abstract type of file (scenario, heightmap, etc).
byte buf[MEMORY_CHUNK_SIZE]
Buffer we're going to read from.
FILE * file
The file to write to.
@ SVS_ALLOW_CONTROL_CODE
Allow the special control codes.
@ BASE_DIR
Base directory for all subdirectories.
@ SLV_5
5.0 1429 5.1 1440 5.2 1525 0.3.6
@ SL_SAVEBYTE
Save (but not load) a byte.
static void SaveFileDone()
Update the gui accordingly when saving is done and release locks on saveload.
@ SLF_ALLOW_CONTROL
Allow control codes in the strings.
Handler that is assigned when there is a struct read in the savegame which is not known to the code.
void WriteByte(byte b)
Write a single byte into the dumper.
@ SLE_FILE_HAS_LENGTH_FIELD
Bit stored in savegame to indicate field has a length field for each entry.
@ SLO_LOAD
File is being loaded.
static void SaveFileError()
Show a gui message when saving has failed.
GRFListCompatibility IsGoodGRFConfigList(GRFConfig *grfconfig)
Check if all GRFs in the GRF config from a savegame can be loaded.
SaveLoadVersion _sl_version
the major savegame version identifier
static void SlFixPointers()
Fix all pointers (convert index -> pointer)
SavegameType
Types of save games.
Date _date
Current date in days (day counter)
const SaveLoadVersion SAVEGAME_VERSION
Current savegame version of OpenTTD.
Filter using Zlib compression.
@ SLO_SAVE
File is being saved.
@ SBI_SAVELOAD_FINISH
finished saving
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 SlSaveLoadRef(void *ptr, VarType conv)
Handle conversion for references.
@ CH_TYPE_MASK
All ChunkType values have to be within this mask.
A trimmed down version of what std::span will be in C++20.
@ NL_CALCLENGTH
need to calculate the length
virtual void Finish()
Prepare everything to finish writing the savegame.
virtual void Save() const
Save the chunk.
@ CH_READONLY
Chunk is never saved.
static size_t SlCalcDequeLen(const void *deque, VarType conv)
Return the size in bytes of a std::deque.
void SlWriteByte(byte b)
Wrapper for writing a byte to the dumper.
uint32 id
Unique ID (4 letters).
@ SL_VAR
Save/load a variable.
void StrMakeValidInPlace(char *str, const char *last, StringValidationSettings settings)
Scans the string for invalid characters and replaces then with a question mark '?' (if not ignored).
std::string _savegame_format
how to compress savegames
FILE * FioFOpenFile(const std::string &filename, const char *mode, Subdirectory subdir, size_t *filesize)
Opens a OpenTTD file somewhere in a personal or global directory.
char * error_data
Data to pass to SetDParamStr when displaying error.
void Write(byte *buf, size_t size) override
Write a given number of bytes into the savegame.
@ NL_WANTLENGTH
writing length and data
const char * GetSaveLoadErrorString()
Get the string representation of the error message.
size_t Read(byte *buf, size_t size) override
Read a given number of bytes from the savegame.
static void SlCopyInternal(void *object, size_t length, VarType conv)
Internal function to save/Load a list of SL_VARs.
virtual void Write(byte *buf, size_t len)=0
Write a given number of bytes into the savegame.
Class for pooled persistent storage of data.
SavegameType _savegame_type
type of savegame we are loading
static void SlLoadCheckChunks()
Load all chunks for savegame checking.
ZlibSaveFilter(SaveFilter *chain, byte compression_level)
Initialise this filter.
std::string CopyFromOldName(StringID id)
Copy and convert old custom names to UTF-8.
static void SlVector(void *vector, VarType conv)
Save/load a std::vector.
FILE * file
The file to read from.
@ SL_REINIT
error that was caught in the middle of updating game state, need to clear it. (can only happen during...
SaveLoadType cmd
The action to take with the saved/loaded type, All types need different action.
@ SLV_END_PATCHPACKS
286 Last known patchpack to use a version just above ours.
SLRefType
Type of reference (SLE_REF, SLE_CONDREF).
bool StartNewThread(std::thread *thr, const char *name, TFn &&_Fx, TArgs &&... _Ax)
Start a new thread.
static void SlSaveLoadConv(void *ptr, VarType conv)
Handle all conversion and typechecking of variables here.
void WriteLoop(byte *p, size_t len, int mode)
Helper loop for writing the data.
void Write(byte *buf, size_t size) override
Write a given number of bytes into the savegame.
void GamelogStartAction(GamelogActionType at)
Stores information about new action, but doesn't allocate it Action is allocated only when there is a...
static const SaveLoadFormat * GetSavegameFormat(const std::string &full_name, byte *compression_level)
Return the savegameformat of the game.
LoadFilter * lf
Filter to read the savegame from.
void Write(byte *buf, size_t size) override
Write a given number of bytes into the savegame.
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
static SaveOrLoadResult SaveFileToDisk(bool threaded)
We have written the whole game into memory, _memory_savegame, now find and appropriate compressor and...
static size_t SlCalcRefListLen(const void *list, VarType conv)
Return the size in bytes of a list.
bool keep_all_autosave
name the autosave in a different way
static const std::vector< ChunkHandlerRef > & ChunkHandlers()
@ SL_ARR
Save/load a fixed-size array of SL_VAR elements.
@ SLE_FILE_STRINGID
StringID offset into strings-array.
@ REF_STORAGE
Load/save a reference to a persistent storage.
@ SCENARIO_DIR
Base directory for all scenarios.
@ FT_INVALID
Invalid or unknown file type.
SaveLoadVersion
SaveLoad versions Previous savegame versions, the trunk revision where they were introduced and the r...
fluid_settings_t * settings
FluidSynth settings handle.
@ SLA_PTRS
fixing pointers
static bool IsSavegameVersionBefore(SaveLoadVersion major, byte minor=0)
Checks whether the savegame is below major.
void Flush(SaveFilter *writer)
Flush this dumper into a writer.
static void SaveFileStart()
Update the gui accordingly when starting saving and set locks on saveload.
@ REF_ENGINE_RENEWS
Load/save a reference to an engine renewal (autoreplace).
@ DFT_OLD_GAME_FILE
Old save game or scenario file.
int CDECL vseprintf(char *str, const char *last, const char *format, va_list ap)
Safer implementation of vsnprintf; same as vsnprintf except:
@ REF_VEHICLE
Load/save a reference to a vehicle.
@ SL_REF
Save/load a reference.
void DoAutoOrNetsave(FiosNumberedSaveName &counter)
Create an autosave or netsave.
@ REF_CARGO_PACKET
Load/save a reference to a cargo packet.
@ SL_STRUCT
Save/load a struct.
static SaveOrLoadResult DoSave(SaveFilter *writer, bool threaded)
Actually perform the saving of the savegame.
@ SBI_SAVELOAD_START
started saving
lzma_stream lzma
Stream state that we are reading from.
byte * bufp
Location we're at reading the buffer.
void SlAutolength(AutolengthProc *proc, void *arg)
Do something of which I have no idea what it is :P.
Struct to store engine replacements.
@ REF_VEHICLE_OLD
Load/save an old-style reference to a vehicle (for pre-4.4 savegames).
StringID error_str
the translatable error message to show
virtual void Load() const =0
Load the chunk.
void Write(byte *buf, size_t size) override
Write a given number of bytes into the savegame.
static uint32 BSWAP32(uint32 x)
Perform a 32 bits endianness bitswap on x.
virtual SaveLoadTable GetDescription() const override
Get the description of the fields in the savegame.
static void SlString(void *ptr, size_t length, VarType conv)
Save/Load a string.
void GamelogStopAction()
Stops logging of any changes.
StringValidationSettings
Settings for the string validation.
size_t SlGetStructListLength(size_t limit)
Get the length of this list; if it exceeds the limit, error out.
std::shared_ptr< SaveLoadHandler > handler
Custom handler for Save/Load procs.
StringID error
Error message from loading. INVALID_STRING_ID if no error.
void GenerateDefaultSaveName(char *buf, const char *last)
Fill the buffer with the default name for a savegame or screenshot.
void WriteValue(void *ptr, VarType conv, int64 val)
Write the value of a setting.
@ SL_VECTOR
Save/load a vector of SL_VAR elements.
static size_t SlCalcVectorLen(const void *vector, VarType conv)
Return the size in bytes of a std::vector.
byte * bufe
End of the buffer we write to.
bool expect_table_header
In the case of a table, if the header is saved/loaded.
@ SL_MAX_VERSION
Highest possible saveload version.
static void SlLoadCheckChunk(const ChunkHandler &ch)
Load a chunk of data for checking savegames.
void NORETURN SlError(StringID string, const char *extra_msg)
Error handler.
@ REF_LINK_GRAPH_JOB
Load/save a reference to a link graph job.
static size_t SlCalcNetStringLen(const char *ptr, size_t length)
Calculate the net length of a string.
z_stream z
Stream state we are reading from.
~LZMALoadFilter()
Clean everything up.
ReadBuffer(LoadFilter *reader)
Initialise our variables.
@ DFT_INVALID
Unknown or invalid file.
static SaveLoadParams _sl
Parameters used for/at saveload.
uint32 StringID
Numeric value that represents a string, independent of the selected language.
NeedLength need_length
working in NeedLength (Autolength) mode?
void NORETURN SlErrorCorruptFmt(const char *format,...)
Issue an SlErrorCorrupt with a format string.
static T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
static size_t SlCalcLen(const void *storage, VarType conv, SaveLoadType cmd=SL_VAR)
Internal templated helper to return the size in bytes of a list-like type.
bool threaded_saves
should we do threaded saves?
A savegame name automatically numbered.
@ REF_ORDERLIST
Load/save a reference to an orderlist.
The saveload struct, containing reader-writer functions, buffer, version, etc.
size_t Read(byte *buf, size_t size) override
Read a given number of bytes from the savegame.
size_t SlGetFieldLength()
Get the length of the current object.
static size_t SlCalcArrayLen(size_t length, VarType conv)
Return the size in bytes of a certain type of atomic array.
DetailedFileType
Kinds of files in each AbstractFileType.
void Clear()
Reset read data.
Template class to help with list-like types.
static SaveOrLoadResult DoLoad(LoadFilter *reader, bool load_check)
Actually perform the loading of a "non-old" savegame.
static const SaveLoadFormat _saveload_formats[]
The different saveload formats known/understood by OpenTTD.
void Reset() override
Reset this filter to read from the beginning of the file.
@ SL_REFLIST
Save/load a list of SL_REF elements.
void NORETURN SlErrorCorrupt(const char *msg)
Error handler for corrupt savegames.
Interface for filtering a savegame till it is written.
static void SetAsyncSaveFinish(AsyncSaveFinishProc proc)
Called by save thread to tell we finished saving.
static VarType GetVarMemType(VarType type)
Get the NumberType of a setting.
SaveLoadAction action
are we doing a save or a load atm.
#define endof(x)
Get the end element of an fixed size array.
FileToSaveLoad _file_to_saveload
File to save or load in the openttd loop.
Shared order list linking together the linked list of orders and the list of vehicles sharing this or...
void SanitizeFilename(char *filename)
Sanitizes a filename, i.e.
SaveOrLoadResult SaveWithFilter(SaveFilter *writer, bool threaded)
Save the game using a (writer) filter.
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.
void Finish() override
Prepare everything to finish writing the savegame.
Filter using LZO compression.
size_t obj_len
the length of the current object we are busy with
void LoadCheck(void *object) const override
Similar to load, but used only to validate savegames.
~LZMASaveFilter()
Clean up what we allocated.
int CDECL seprintf(char *str, const char *last, const char *format,...)
Safer implementation of snprintf; same as snprintf except:
Subdirectory
The different kinds of subdirectories OpenTTD uses.
static void SlWriteSimpleGamma(size_t i)
Write the header descriptor of an object or an array.
SaveLoadVersion version_from
Save/load the variable starting from this savegame version.
GRFListCompatibility grf_compatibility
Summary state of NewGrfs, whether missing files or only compatible found.
SaveOrLoadResult
Save or load result codes.
void GamelogReset()
Resets and frees all memory allocated - used before loading or starting a new game.
@ WL_ERROR
Errors (eg. saving/loading failed)
FiosType
Elements of a file system that are recognized.
@ SLE_VAR_STRQ
string pointer enclosed in quotes
bool saveinprogress
Whether there is currently a save in progress.
SaveFilter * chain
Chained to the (savegame) filters.
uint16 game_speed
The game speed when saving started.
char * stredup(const char *s, const char *last)
Create a duplicate of the given string.
void Save(void *object) const override
Save the object to disk.
static void SlRefList(void *list, VarType conv)
Save/Load a list.
size_t read
The amount of read bytes so far from the filter.
GRFConfig * _grfconfig
First item in list of current GRF set up.
@ REF_LINK_GRAPH
Load/save a reference to a link graph.
@ SLO_INVALID
Unknown file operation.
@ SLA_NULL
null all pointers (on loading error)
#define Debug(name, level, format_string,...)
Ouptut a line of debugging information.
static void SlStdString(void *ptr, VarType conv)
Save/Load a std::string.
Interface for filtering a savegame till it is loaded.
#define lengthof(x)
Return the length of an fixed size array.
bool error
did an error occur or not
Container for cargo from the same location and time.
@ SL_DEQUE
Save/load a deque of SL_VAR elements.
MemoryDumper * dumper
Memory dumper to write the savegame to.
~FileReader()
Make sure everything is cleaned up.
@ SLV_SAVELOAD_LIST_LENGTH
293 PR#9374 Consistency in list length with SL_STRUCT / SL_STRUCTLIST / SL_DEQUE / SL_REFLIST.
static void * GetVariableAddress(const void *object, const SaveLoad &sld)
Get the address of the variable.
AbstractFileType GetAbstractFileType(FiosType fios_type)
Extract the abstract file type from a FiosType.
std::vector< SaveLoad > SlCompatTableHeader(const SaveLoadTable &slt, const SaveLoadCompatTable &slct)
Load a table header in a savegame compatible way.
static void SlCopyBytes(void *ptr, size_t length)
Save/Load bytes.
Filter using LZO compression.
static const size_t MEMORY_CHUNK_SIZE
Save in chunks of 128 KiB.
void ProcessAsyncSaveFinish()
Handle async save finishes.
std::vector< byte * > blocks
Buffer with blocks of allocated memory.
char * extra_msg
the error message
Yes, simply reading from a file.
static const ChunkHandler * SlFindChunkHandler(uint32 id)
Find the ChunkHandler that will be used for processing the found chunk in the savegame or in memory.
uint32 _ttdp_version
version of TTDP savegame (if applicable)
int64 ReadValue(const void *ptr, VarType conv)
Return a signed-long version of the value of a setting.
int last_array_index
in the case of an array, the current and last positions
static size_t SlCalcRefLen()
Return the size in bytes of a reference (pointer)
void Finish() override
Prepare everything to finish writing the savegame.
static std::atomic< AsyncSaveFinishProc > _async_save_finish
Callback to call when the savegame loading is finished.
@ SL_ERROR
error that was caught before internal structures were modified
DetailedFileType detail_ftype
Concrete file type (PNG, BMP, old save, etc).
static bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
@ WC_STATUS_BAR
Statusbar (at the bottom of your screen); Window numbers:
size_t GetSize() const
Get the size of the memory dump made so far.
A Stop for a Road Vehicle.
std::string Extension()
Generate an extension for a savegame name.
std::string name
Name of this field (optional, used for tables).
void SlObject(void *object, const SaveLoadTable &slt)
Main SaveLoad function.
~ZlibSaveFilter()
Clean up what we allocated.
virtual void LoadCheck(size_t len=0) const
Load the chunk for game preview.
Filter using LZMA compression.
@ SLV_START_PATCHPACKS
220 First known patchpack to use a version just above ours.
std::vector< SaveLoad > SlTableHeader(const SaveLoadTable &slt)
Save or Load a table header.
char * strecpy(char *dst, const char *src, const char *last)
Copies characters from one buffer to another.
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
void SlSetStructListLength(size_t length)
Set the length of this list.
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.
@ SLV_4
4.0 1 4.1 122 0.3.3, 0.3.4 4.2 1222 0.3.5 4.3 1417 4.4 1426
char * strecat(char *dst, const char *src, const char *last)
Appends characters from one string to another.
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...
virtual SaveLoadCompatTable GetCompatDescription() const override
Get the pre-header description of the fields in the savegame.
void Write(byte *buf, size_t size) override
Write a given number of bytes into the savegame.
static void ClearSaveLoadState()
Clear/free saveload state.
LoadFilter * chain
Chained to the (savegame) filters.
LoadFilter(LoadFilter *chain)
Initialise this filter.
#define lastof(x)
Get the last element of an fixed size array.
@ SL_OK
completed successfully
@ SVS_REPLACE_WITH_QUESTION_MARK
Replace the unknown/bad bits with question marks.
std::string Filename()
Generate a savegame name and number according to _settings_client.gui.max_num_autosaves.
@ SL_STDSTR
Save/load a std::string.
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...
static const lzma_stream _lzma_init
Have a copy of an initialised LZMA stream.
@ SLE_VAR_NAME
old custom name to be converted to a char pointer
~FileWriter()
Make sure everything is cleaned up.
size_t SlCalcObjLength(const void *object, const SaveLoadTable &slt)
Calculate the size of an object.
uint16 _game_speed
Current game-speed; 100 is 1x, 0 is infinite.
int SlIterateArray()
Iterate through the elements of an array and read the whole thing.
void SetDParamStr(uint n, const char *str)
This function is used to "bind" a C string to a OpenTTD dparam slot.
FileReader(FILE *file)
Create the file reader, so it reads from a specific file.
static const StringID INVALID_STRING_ID
Constant representing an invalid string (16bit in case it is used in savegames)
static void SlSaveChunk(const ChunkHandler &ch)
Save a chunk of data (eg.
GUISettings gui
settings related to the GUI
@ WL_CRITICAL
Critical errors, the MessageBox is shown in all cases.
void Finish() override
Prepare everything to finish writing the savegame.
SaveLoadOperation file_op
File operation to perform.
Yes, simply writing to a file.
byte * bufe
End of the buffer we can read from.
Container for dumping the savegame (quickly) to memory.
@ SL_STRUCTLIST
Save/load a list of structs.
#define AllocaM(T, num_elements)
alloca() has to be called in the parent function, so define AllocaM() as a macro