Go to the documentation of this file.
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"
49 # include <emscripten.h>
52 #include "table/strings.h"
57 #include "../safeguards.h"
104 inline byte ReadByte()
106 if (this->bufp == this->bufe) {
107 size_t len = this->reader->
Read(this->buf,
lengthof(this->buf));
111 this->bufp = this->
buf;
112 this->bufe = this->buf + len;
115 return *this->bufp++;
124 return this->read - (this->bufe - this->
bufp);
142 for (
auto p : this->blocks) {
154 if (this->buf == this->bufe) {
156 this->blocks.push_back(this->buf);
175 writer->
Write(this->blocks[i++], to_write);
245 extern const ChunkHandler _autoreplace_chunk_handlers[];
254 _gamelog_chunk_handlers,
256 _misc_chunk_handlers,
259 _setting_chunk_handlers,
261 _waypoint_chunk_handlers,
262 _depot_chunk_handlers,
263 _order_chunk_handlers,
264 _industry_chunk_handlers,
265 _economy_chunk_handlers,
266 _subsidy_chunk_handlers,
268 _goal_chunk_handlers,
269 _story_page_chunk_handlers,
270 _engine_chunk_handlers,
273 _station_chunk_handlers,
274 _company_chunk_handlers,
276 _game_chunk_handlers,
278 _newgrf_chunk_handlers,
279 _group_chunk_handlers,
281 _autoreplace_chunk_handlers,
282 _labelmaps_chunk_handlers,
283 _linkgraph_chunk_handlers,
284 _airport_chunk_handlers,
285 _object_chunk_handlers,
294 #define FOR_ALL_CHUNK_HANDLERS(ch) \
295 for (const ChunkHandler * const *chsc = _chunk_handlers; *chsc != nullptr; chsc++) \
296 for (const ChunkHandler *ch = *chsc; ch != nullptr; ch = (ch->flags & CH_LAST) ? nullptr : ch + 1)
309 if (ch->ptrs_proc !=
nullptr) {
310 DEBUG(sl, 3,
"Nulling pointers for %c%c%c%c", ch->id >> 24, ch->id >> 16, ch->id >> 8, ch->id);
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;
405 if (proc ==
nullptr)
return;
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);
523 if (i >= (1 << 14)) {
524 if (i >= (1 << 21)) {
525 if (i >= (1 << 28)) {
526 assert(i <= UINT32_MAX);
547 return 1 + (i >= (1 << 7)) + (i >= (1 << 14)) + (i >= (1 << 21)) + (i >= (1 << 28));
550 static inline uint SlReadSparseIndex()
555 static inline void SlWriteSparseIndex(uint index)
560 static inline uint SlReadArrayLength()
565 static inline void SlWriteArrayLength(
size_t length)
570 static inline uint SlGetArrayLength(
size_t length)
583 static const byte conv_mem_size[] = {1, 1, 1, 2, 2, 4, 4, 8, 8, 0};
584 byte length =
GB(conv, 4, 4);
586 switch (length << 4) {
591 return SlReadArrayLength();
594 assert(length <
lengthof(conv_mem_size));
595 return conv_mem_size[length];
607 static const byte conv_file_size[] = {1, 1, 2, 2, 4, 4, 8, 8, 2};
608 byte length =
GB(conv, 0, 4);
609 assert(length <
lengthof(conv_file_size));
610 return conv_file_size[length];
619 void SlSetArrayIndex(uint index)
622 _sl.array_index = index;
625 static size_t _next_offs;
640 uint length = SlReadArrayLength();
650 case CH_SPARSE_ARRAY: index = (int)SlReadSparseIndex();
break;
651 case CH_ARRAY: index =
_sl.array_index++;
break;
653 DEBUG(sl, 0,
"SlIterateArray error");
657 if (length != 0)
return index;
688 assert(length < (1 << 28));
689 SlWriteUint32((uint32)((length & 0xFFFFFF) | ((length >> 24) << 28)));
694 SlWriteArrayLength(1);
696 SlWriteArrayLength(length + 1);
698 case CH_SPARSE_ARRAY:
699 SlWriteArrayLength(length + 1 + SlGetArrayLength(
_sl.array_index));
700 SlWriteSparseIndex(
_sl.array_index);
702 default: NOT_REACHED();
710 default: NOT_REACHED();
722 byte *p = (
byte *)ptr;
727 for (; length != 0; length--) *p++ =
SlReadByte();
732 default: NOT_REACHED();
752 case SLE_VAR_BL:
return (*(
const bool *)ptr != 0);
753 case SLE_VAR_I8:
return *(
const int8 *)ptr;
754 case SLE_VAR_U8:
return *(
const byte *)ptr;
755 case SLE_VAR_I16:
return *(
const int16 *)ptr;
756 case SLE_VAR_U16:
return *(
const uint16*)ptr;
757 case SLE_VAR_I32:
return *(
const int32 *)ptr;
758 case SLE_VAR_U32:
return *(
const uint32*)ptr;
759 case SLE_VAR_I64:
return *(
const int64 *)ptr;
760 case SLE_VAR_U64:
return *(
const uint64*)ptr;
762 default: NOT_REACHED();
776 case SLE_VAR_BL: *(
bool *)ptr = (val != 0);
break;
777 case SLE_VAR_I8: *(int8 *)ptr = val;
break;
778 case SLE_VAR_U8: *(
byte *)ptr = val;
break;
779 case SLE_VAR_I16: *(int16 *)ptr = val;
break;
780 case SLE_VAR_U16: *(uint16*)ptr = val;
break;
781 case SLE_VAR_I32: *(int32 *)ptr = val;
break;
782 case SLE_VAR_U32: *(uint32*)ptr = val;
break;
783 case SLE_VAR_I64: *(int64 *)ptr = val;
break;
784 case SLE_VAR_U64: *(uint64*)ptr = val;
break;
787 default: NOT_REACHED();
807 case SLE_FILE_I8: assert(x >= -128 && x <= 127);
SlWriteByte(x);
break;
808 case SLE_FILE_U8: assert(x >= 0 && x <= 255);
SlWriteByte(x);
break;
809 case SLE_FILE_I16:assert(x >= -32768 && x <= 32767); SlWriteUint16(x);
break;
811 case SLE_FILE_U16:assert(x >= 0 && x <= 65535); SlWriteUint16(x);
break;
813 case SLE_FILE_U32: SlWriteUint32((uint32)x);
break;
815 case SLE_FILE_U64: SlWriteUint64(x);
break;
816 default: NOT_REACHED();
825 case SLE_FILE_I8: x = (int8 )
SlReadByte();
break;
826 case SLE_FILE_U8: x = (byte )
SlReadByte();
break;
827 case SLE_FILE_I16: x = (int16 )SlReadUint16();
break;
828 case SLE_FILE_U16: x = (uint16)SlReadUint16();
break;
829 case SLE_FILE_I32: x = (int32 )SlReadUint32();
break;
830 case SLE_FILE_U32: x = (uint32)SlReadUint32();
break;
831 case SLE_FILE_I64: x = (int64 )SlReadUint64();
break;
832 case SLE_FILE_U64: x = (uint64)SlReadUint64();
break;
834 default: NOT_REACHED();
843 default: NOT_REACHED();
858 if (ptr ==
nullptr)
return 0;
859 return std::min(strlen(ptr), length - 1);
877 default: NOT_REACHED();
880 str = *(
const char *
const *)ptr;
885 str = (
const char *)ptr;
891 return len + SlGetArrayLength(len);
903 const std::string *str =
reinterpret_cast<const std::string *
>(ptr);
905 size_t len = str->length();
906 return len + SlGetArrayLength(len);
915 static void SlString(
void *ptr,
size_t length, VarType conv)
921 default: NOT_REACHED();
933 SlWriteArrayLength(len);
939 size_t len = SlReadArrayLength();
942 default: NOT_REACHED();
946 DEBUG(sl, 1,
"String length in savegame is bigger than buffer, truncating");
958 *(
char **)ptr =
nullptr;
961 *(
char **)ptr = MallocT<char>(len + 1);
968 ((
char *)ptr)[len] =
'\0';
984 default: NOT_REACHED();
995 std::string *str =
reinterpret_cast<std::string *
>(ptr);
999 size_t len = str->length();
1000 SlWriteArrayLength(len);
1001 SlCopyBytes(
const_cast<void *
>(
static_cast<const void *
>(str->c_str())), len);
1007 size_t len = SlReadArrayLength();
1008 char *buf =
AllocaM(
char, len + 1);
1031 default: NOT_REACHED();
1051 void SlArray(
void *array,
size_t length, VarType conv)
1066 if (conv == SLE_INT16 || conv == SLE_UINT16 || conv == SLE_STRINGID ||
1067 conv == SLE_INT32 || conv == SLE_UINT32) {
1072 if (conv == (SLE_FILE_I32 | SLE_VAR_I64)) {
1073 for (uint i = 0; i < length; i++) {
1074 ((int64*)array)[i] = (int32)
BSWAP32(SlReadUint32());
1082 if (conv == SLE_INT8 || conv == SLE_UINT8) {
1085 byte *a = (
byte*)array;
1088 for (; length != 0; length --) {
1110 if (obj ==
nullptr)
return 0;
1125 default: NOT_REACHED();
1141 static_assert(
sizeof(
size_t) <=
sizeof(
void *));
1206 default: NOT_REACHED();
1216 const std::list<void *> *l = (
const std::list<void *> *) list;
1221 return l->size() * type_size + type_size;
1239 typedef std::list<void *> PtrList;
1240 PtrList *l = (PtrList *)list;
1244 SlWriteUint32((uint32)l->size());
1246 PtrList::iterator iter;
1247 for (iter = l->begin(); iter != l->end(); ++iter) {
1258 for (
size_t i = 0; i < length; i++) {
1260 l->push_back((
void *)data);
1268 PtrList::iterator iter;
1269 for (iter = temp.begin(); iter != temp.end(); ++iter) {
1278 default: NOT_REACHED();
1286 template <
typename T>
1288 typedef std::deque<T> SlDequeT;
1297 const SlDequeT *l = (
const SlDequeT *)deque;
1312 SlDequeT *l = (SlDequeT *)deque;
1316 SlWriteUint32((uint32)l->size());
1318 typename SlDequeT::iterator iter;
1319 for (iter = l->begin(); iter != l->end(); ++iter) {
1326 size_t length = SlReadUint32();
1329 for (
size_t i = 0; i < length; i++) {
1341 default: NOT_REACHED();
1369 default: NOT_REACHED();
1401 default: NOT_REACHED();
1441 for (; sld->
cmd != SL_END; sld++) {
1442 length += SlCalcObjMemberLength(
object, sld);
1447 size_t SlCalcObjMemberLength(
const void *
object,
const SaveLoad *sld)
1470 default: NOT_REACHED();
1473 case SL_WRITEBYTE:
return 1;
1476 default: NOT_REACHED();
1494 return sld->
size ==
sizeof(bool);
1497 return sld->
size ==
sizeof(int8);
1500 return sld->
size ==
sizeof(int16);
1503 return sld->
size ==
sizeof(int32);
1506 return sld->
size ==
sizeof(int64);
1508 return sld->
size ==
sizeof(std::string);
1510 return sld->
size ==
sizeof(
void *);
1514 return sld->
size ==
sizeof(
void *);
1522 return sld->
size ==
sizeof(std::string);
1531 bool SlObjectMember(
void *ptr,
const SaveLoad *sld)
1537 VarType conv =
GB(sld->
conv, 0, 8);
1565 *(
void **)ptr =
nullptr;
1567 default: NOT_REACHED();
1575 default: NOT_REACHED();
1589 default: NOT_REACHED();
1594 case SL_VEH_INCLUDE:
1602 default: NOT_REACHED();
1620 for (; sld->
cmd != SL_END; sld++) {
1622 SlObjectMember(ptr, sld);
1678 _sl.array_index = 0;
1682 case CH_SPARSE_ARRAY:
1687 if ((m & 0xF) == CH_RIFF) {
1689 len = (
SlReadByte() << 16) | ((m >> 4) << 24);
1690 len += SlReadUint16();
1718 _sl.array_index = 0;
1725 case CH_SPARSE_ARRAY:
1733 if ((m & 0xF) == CH_RIFF) {
1735 len = (
SlReadByte() << 16) | ((m >> 4) << 24);
1736 len += SlReadUint16();
1759 ChunkSaveLoadProc *proc = ch->
save_proc;
1762 if (proc ==
nullptr)
return;
1764 SlWriteUint32(ch->
id);
1765 DEBUG(sl, 2,
"Saving chunk %c%c%c%c", ch->
id >> 24, ch->
id >> 16, ch->
id >> 8, ch->
id);
1768 switch (ch->
flags & CH_TYPE_MASK) {
1777 SlWriteArrayLength(0);
1779 case CH_SPARSE_ARRAY:
1782 SlWriteArrayLength(0);
1784 default: NOT_REACHED();
1817 for (
id = SlReadUint32();
id != 0;
id = SlReadUint32()) {
1818 DEBUG(sl, 2,
"Loading chunk %c%c%c%c",
id >> 24,
id >> 16,
id >> 8,
id);
1832 for (
id = SlReadUint32();
id != 0;
id = SlReadUint32()) {
1833 DEBUG(sl, 2,
"Loading chunk %c%c%c%c",
id >> 24,
id >> 16,
id >> 8,
id);
1847 if (ch->ptrs_proc !=
nullptr) {
1848 DEBUG(sl, 3,
"Fixing pointers for %c%c%c%c", ch->id >> 24, ch->id >> 16, ch->id >> 8, ch->id);
1873 if (this->file !=
nullptr) fclose(this->file);
1874 this->file =
nullptr;
1880 size_t Read(
byte *buf,
size_t size)
override
1883 if (this->file ==
nullptr)
return 0;
1885 return fread(buf, 1, size, this->file);
1890 clearerr(this->file);
1891 if (fseek(this->file, this->begin, SEEK_SET)) {
1892 DEBUG(sl, 1,
"Could not reset the file reading");
1918 void Write(
byte *buf,
size_t size)
override
1921 if (this->file ==
nullptr)
return;
1923 if (fwrite(buf, 1, size, this->file) != size)
SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE);
1928 if (this->file !=
nullptr) fclose(this->file);
1929 this->file =
nullptr;
1938 #include <lzo/lzo1x.h>
1951 if (lzo_init() != LZO_E_OK)
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR,
"cannot initialize decompressor");
1954 size_t Read(
byte *buf,
size_t ssize)
override
1962 lzo_uint len = ssize;
1965 if (this->
chain->
Read((
byte*)tmp,
sizeof(tmp)) !=
sizeof(tmp))
SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE,
"File read failed");
1968 ((uint32*)out)[0] = size = tmp[1];
1971 tmp[0] = TO_BE32(tmp[0]);
1972 size = TO_BE32(size);
1978 if (this->
chain->
Read(out +
sizeof(uint32), size) != size)
SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
1981 if (tmp[0] != lzo_adler32(0, out, size +
sizeof(uint32)))
SlErrorCorrupt(
"Bad checksum");
1984 int ret = lzo1x_decompress_safe(out +
sizeof(uint32) * 1, size, buf, &len,
nullptr);
1985 if (ret != LZO_E_OK)
SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
1999 if (lzo_init() != LZO_E_OK)
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR,
"cannot initialize compressor");
2002 void Write(
byte *buf,
size_t size)
override
2004 const lzo_bytep in = buf;
2007 byte wrkmem[LZO1X_1_MEM_COMPRESS];
2013 lzo1x_1_compress(in, len, out +
sizeof(uint32) * 2, &outlen, wrkmem);
2014 ((uint32*)out)[1] = TO_BE32((uint32)outlen);
2015 ((uint32*)out)[0] = TO_BE32(lzo_adler32(0, out +
sizeof(uint32), outlen +
sizeof(uint32)));
2016 this->
chain->
Write(out, outlen +
sizeof(uint32) * 2);
2041 size_t Read(
byte *buf,
size_t size)
override
2043 return this->chain->
Read(buf, size);
2058 void Write(
byte *buf,
size_t size)
override
2060 this->chain->Write(buf, size);
2068 #if defined(WITH_ZLIB)
2082 memset(&this->z, 0,
sizeof(this->z));
2083 if (inflateInit(&this->z) != Z_OK)
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR,
"cannot initialize decompressor");
2089 inflateEnd(&this->z);
2092 size_t Read(
byte *buf,
size_t size)
override
2094 this->z.next_out = buf;
2095 this->z.avail_out = (uint)size;
2099 if (this->z.avail_in == 0) {
2101 this->z.avail_in = (uint)this->chain->
Read(this->fread_buf,
sizeof(this->fread_buf));
2105 int r = inflate(&this->z, 0);
2106 if (r == Z_STREAM_END)
break;
2108 if (r != Z_OK)
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR,
"inflate() failed");
2109 }
while (this->z.avail_out != 0);
2111 return size - this->z.avail_out;
2126 memset(&this->z, 0,
sizeof(this->z));
2127 if (deflateInit(&this->z, compression_level) != Z_OK)
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR,
"cannot initialize compressor");
2133 deflateEnd(&this->z);
2146 this->z.next_in = p;
2147 this->z.avail_in = (uInt)len;
2149 this->z.next_out = buf;
2150 this->z.avail_out =
sizeof(buf);
2159 int r = deflate(&this->z, mode);
2162 if ((n =
sizeof(buf) - this->z.avail_out) != 0) {
2163 this->chain->Write(buf, n);
2165 if (r == Z_STREAM_END)
break;
2167 if (r != Z_OK)
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR,
"zlib returned error code");
2168 }
while (this->z.avail_in || !this->z.avail_out);
2171 void Write(
byte *buf,
size_t size)
override
2179 this->chain->Finish();
2189 #if defined(WITH_LIBLZMA)
2212 if (lzma_auto_decoder(&this->lzma, 1 << 28, 0) != LZMA_OK)
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR,
"cannot initialize decompressor");
2218 lzma_end(&this->lzma);
2221 size_t Read(
byte *buf,
size_t size)
override
2223 this->lzma.next_out = buf;
2224 this->lzma.avail_out = size;
2228 if (this->lzma.avail_in == 0) {
2230 this->lzma.avail_in = this->chain->
Read(this->fread_buf,
sizeof(this->fread_buf));
2234 lzma_ret r = lzma_code(&this->lzma, LZMA_RUN);
2235 if (r == LZMA_STREAM_END)
break;
2236 if (r != LZMA_OK)
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR,
"liblzma returned error code");
2237 }
while (this->lzma.avail_out != 0);
2239 return size - this->lzma.avail_out;
2254 if (lzma_easy_encoder(&this->lzma, compression_level, LZMA_CHECK_CRC32) != LZMA_OK)
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR,
"cannot initialize compressor");
2260 lzma_end(&this->lzma);
2273 this->lzma.next_in = p;
2274 this->lzma.avail_in = len;
2276 this->lzma.next_out = buf;
2277 this->lzma.avail_out =
sizeof(buf);
2279 lzma_ret r = lzma_code(&this->lzma, action);
2282 if ((n =
sizeof(buf) - this->lzma.avail_out) != 0) {
2283 this->chain->Write(buf, n);
2285 if (r == LZMA_STREAM_END)
break;
2286 if (r != LZMA_OK)
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR,
"liblzma returned error code");
2287 }
while (this->lzma.avail_in || !this->lzma.avail_out);
2290 void Write(
byte *buf,
size_t size)
override
2297 this->
WriteLoop(
nullptr, 0, LZMA_FINISH);
2298 this->chain->Finish();
2323 #if defined(WITH_LZO)
2325 {
"lzo", TO_BE32X(
'OTTD'), CreateLoadFilter<LZOLoadFilter>, CreateSaveFilter<LZOSaveFilter>, 0, 0, 0},
2327 {
"lzo", TO_BE32X(
'OTTD'),
nullptr,
nullptr, 0, 0, 0},
2330 {
"none", TO_BE32X(
'OTTN'), CreateLoadFilter<NoCompLoadFilter>, CreateSaveFilter<NoCompSaveFilter>, 0, 0, 0},
2331 #if defined(WITH_ZLIB)
2335 {
"zlib", TO_BE32X(
'OTTZ'), CreateLoadFilter<ZlibLoadFilter>, CreateSaveFilter<ZlibSaveFilter>, 0, 6, 9},
2337 {
"zlib", TO_BE32X(
'OTTZ'),
nullptr,
nullptr, 0, 0, 0},
2339 #if defined(WITH_LIBLZMA)
2345 {
"lzma", TO_BE32X(
'OTTX'), CreateLoadFilter<LZMALoadFilter>, CreateSaveFilter<LZMASaveFilter>, 0, 2, 9},
2347 {
"lzma", TO_BE32X(
'OTTX'),
nullptr,
nullptr, 0, 0, 0},
2367 char *complevel = strrchr(s,
':');
2368 if (complevel !=
nullptr) *complevel =
'\0';
2371 if (slf->init_write !=
nullptr && strcmp(s, slf->name) == 0) {
2372 *compression_level = slf->default_compression;
2373 if (complevel !=
nullptr) {
2382 long level = strtol(complevel, &end, 10);
2383 if (end == complevel || level !=
Clamp(level, slf->min_compression, slf->max_compression)) {
2387 *compression_level = level;
2399 if (complevel !=
nullptr) *complevel =
':';
2406 void InitializeGame(uint size_x, uint size_y,
bool reset_date,
bool reset_settings);
2408 extern bool LoadOldSaveGame(
const std::string &file);
2415 ResetTempEngineData();
2417 ResetOldWaypoints();
2462 #ifdef __EMSCRIPTEN__
2463 EM_ASM(
if (window[
"openttd_syncfs"]) openttd_syncfs());
2479 static char err_str[512];
2480 GetString(err_str,
_sl.
action ==
SLA_SAVE ? STR_ERROR_GAME_SAVE_FAILED : STR_ERROR_GAME_LOAD_FAILED,
lastof(err_str));
2521 if (
_sl.
error_str != STR_NETWORK_ERROR_LOSTCONNECTION) {
2536 void WaitTillSaved()
2563 SaveViewportBeforeSaveGame();
2569 if (threaded)
DEBUG(sl, 1,
"Cannot create savegame thread, reverting to single-threaded mode...");
2590 return DoSave(writer, threaded);
2615 if (
_sl.
lf->
Read((
byte*)hdr,
sizeof(hdr)) !=
sizeof(hdr))
SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
2622 DEBUG(sl, 0,
"Unknown savegame type, trying to load it as the buggy format");
2634 if (fmt->
tag == TO_BE32X(
'OTTD'))
break;
2640 if (fmt->
tag == hdr[0]) {
2663 SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, err_str);
2676 InitializeGame(256, 256,
true,
true);
2748 return DoLoad(reader,
false);
2779 InitializeGame(256, 256,
true,
true);
2787 if (!LoadOldSaveGame(filename))
return SL_REINIT;
2813 default: NOT_REACHED();
2823 if (fh ==
nullptr) {
2824 SlError(fop ==
SLO_SAVE ? STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE : STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
2836 DEBUG(desync, 1,
"load: %s", filename.c_str());
2878 case 0:
SetDParam(1, STR_JUST_DATE_LONG);
break;
2879 case 1:
SetDParam(1, STR_JUST_DATE_TINY);
break;
2880 case 2:
SetDParam(1, STR_JUST_DATE_ISO);
break;
2881 default: NOT_REACHED();
2886 GetString(buf, !
Company::IsValidID(cid) ? STR_SAVEGAME_NAME_SPECTATOR : STR_SAVEGAME_NAME_DEFAULT, last);
char title[255]
Internal name of the game.
byte fread_buf[MEMORY_CHUNK_SIZE]
Buffer for reading from the file.
static void SlLoadChunks()
Load all chunks.
static void ResetSaveloadData()
Clear temporary data that is passed between various saveload phases.
void SetMouseCursorBusy(bool busy)
Set or unset the ZZZ cursor.
SaveLoadVersion version_to
save/load the variable until this savegame version
FileWriter(FILE *file)
Create the file writer, so it writes to a specific file.
lzma_stream lzma
Stream state that we are writing to.
static void SlLoadChunk(const ChunkHandler *ch)
Load a chunk of data (eg vehicles, stations, etc.)
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.
static void SlDeque(void *deque, VarType conv)
Save/load a std::deque.
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.
@ SVS_ALLOW_NEWLINE
Allow newlines.
A connected component of a link graph.
@ SLF_NOT_IN_SAVE
do not save with savegame, basically client-based
static std::thread _save_thread
The thread we're using to compress and write a savegame.
const ChunkHandler _name_chunk_handlers[]
Chunk handlers related to strings.
@ 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.
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...
@ 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.
static void SlLoadCheckChunk(const ChunkHandler *ch)
Load a chunk of data for checking savegames.
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.
const ChunkHandler _town_chunk_handlers[]
Chunk handler for towns.
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.
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.
static bool HasBit(const T x, const uint8 y)
Checks if a bit in a value is set.
@ SLE_VAR_STRBQ
string enclosed in quotes (with pre-allocated buffer)
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.
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)
char _savegame_format[8]
how to compress savegames
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, int
void WriteLoop(byte *p, size_t len, lzma_action action)
Helper loop for writing the data.
@ SLF_NO_NETWORK_SYNC
do not synchronize over network (but it is saved if SLF_NOT_IN_SAVE is not set)
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.
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.
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.
Filter without any compression.
static const SaveLoadFormat * GetSavegameFormat(char *s, byte *compression_level)
Return the savegameformat of the game.
@ 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
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
void WriteByte(byte b)
Write a single byte into the dumper.
@ 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
ChunkSaveLoadProc * load_check_proc
Load procedure for game preview.
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...
@ NL_CALCLENGTH
need to calculate the length
virtual void Finish()
Prepare everything to finish writing the savegame.
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.
#define DEBUG(name, level,...)
Output a line of debugging information.
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.
const ChunkHandler _cheat_chunk_handlers[]
Chunk handlers related to cheats.
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.
const ChunkHandler _persistent_storage_chunk_handlers[]
Chunk handler for persistent storages.
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...
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...
uint32 flags
Flags of the chunk.
@ SL_ARR
Save/load an array.
@ 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...
static bool StrEmpty(const char *s)
Check if a string buffer is empty.
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.
const ChunkHandler _sign_chunk_handlers[]
Chunk handlers related to signs.
static void SlList(void *list, SLRefType conv)
Save/Load a list.
bool _networking
are we in networking mode?
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:
void SlObject(void *object, const SaveLoad *sld)
Main SaveLoad function.
@ REF_VEHICLE
Load/save a reference to a vehicle.
@ SL_REF
Save/load a reference.
@ REF_CARGO_PACKET
Load/save a reference to a cargo packet.
static const ChunkHandler *const _chunk_handlers[]
Array of all chunks in a savegame, nullptr terminated.
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).
ChunkSaveLoadProc * load_proc
Load procedure of the chunk.
static size_t SlCalcListLen(const void *list)
Return the size in bytes of a list.
StringID error_str
the translatable error message to show
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.
static void SlString(void *ptr, size_t length, VarType conv)
Save/Load a string.
static size_t SlCalcDequeLen(const void *deque, VarType conv)
Internal templated helper to return the size in bytes of a std::deque.
void GamelogStopAction()
Stops logging of any changes.
StringValidationSettings
Settings for the string validation.
#define FOR_ALL_CHUNK_HANDLERS(ch)
Iterate over all chunk handlers.
StringID error
Error message from loading. INVALID_STRING_ID if no error.
void SlGlobList(const SaveLoadGlobVarList *sldg)
Save or Load (a list of) global variables.
const ChunkHandler _animated_tile_chunk_handlers[]
"Definition" imported by the saveload code to be able to load and save the animated tile table.
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.
byte * bufe
End of the buffer we write to.
@ SL_MAX_VERSION
Highest possible saveload version.
void NORETURN SlError(StringID string, const char *extra_msg)
Error handler.
size_t SlCalcObjLength(const void *object, const SaveLoad *sld)
Calculate the size of an object.
@ 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 bool SlSkipVariableOnLoad(const SaveLoad *sld)
Are we going to load this variable when loading a savegame or not?
bool threaded_saves
should we do threaded saves?
@ 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.
static void SlDeque(void *deque, VarType conv)
Internal templated helper to save/load a std::deque.
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.
ChunkSaveLoadProc * save_proc
Save procedure of the chunk.
void Reset() override
Reset this filter to read from the beginning of the file.
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.
@ SL_LST
Save/load a list.
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
~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.
static bool SlIsObjectValidInSavegame(const SaveLoad *sld)
Are we going to save this object or not?
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.
const ChunkHandler _cargomonitor_chunk_handlers[]
Chunk definition of the cargomonitoring maps.
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.
const ChunkHandler _cargopacket_chunk_handlers[]
Chunk handlers related to cargo packets.
@ SLO_INVALID
Unknown file operation.
@ SLA_NULL
null all pointers (on loading error)
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.
MemoryDumper * dumper
Memory dumper to write the savegame to.
const SaveLoad * GetVehicleDescription(VehicleType vt)
Make it possible to make the saveload tables "friends" of other classes.
~FileReader()
Make sure everything is cleaned up.
AbstractFileType GetAbstractFileType(FiosType fios_type)
Extract the abstract file type from a FiosType.
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.
static void SlSaveChunk(const ChunkHandler *ch)
Save a chunk of data (eg.
~ZlibSaveFilter()
Clean up what we allocated.
Filter using LZMA compression.
@ SLV_START_PATCHPACKS
220 First known patchpack to use a version just above ours.
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.
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
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...
void Write(byte *buf, size_t size) override
Write a given number of bytes into the savegame.
static void ClearSaveLoadState()
Clear/free saveload state.
void SlArray(void *array, size_t length, VarType conv)
Save/Load an array.
LoadFilter * chain
Chained to the (savegame) filters.
const SaveLoad * GetBaseStationDescription()
Get the base station description to be used for SL_ST_INCLUDE.
static void * GetVariableAddress(const void *object, const SaveLoad *sld)
Get the address of the variable.
LoadFilter(LoadFilter *chain)
Initialise this filter.
#define lastof(x)
Get the last element of an fixed size array.
Template class to help with std::deque.
@ SL_OK
completed successfully
@ SVS_REPLACE_WITH_QUESTION_MARK
Replace the unknown/bad bits with question marks.
@ 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.
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)
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.
static bool IsVariableSizeRight(const SaveLoad *sld)
Check whether the variable size of the variable in the saveload configuration matches with the actual...
#define AllocaM(T, num_elements)
alloca() has to be called in the parent function, so define AllocaM() as a macro