src/saveload.cpp
branchNewGRF_ports
changeset 10991 d8811e327d12
parent 10731 67db0d431d5e
child 10994 cd9968b6f96b
equal deleted inserted replaced
10731:67db0d431d5e 10991:d8811e327d12
    30 #include "core/endian_func.hpp"
    30 #include "core/endian_func.hpp"
    31 #include "vehicle_base.h"
    31 #include "vehicle_base.h"
    32 #include "autoreplace_base.h"
    32 #include "autoreplace_base.h"
    33 #include "statusbar_gui.h"
    33 #include "statusbar_gui.h"
    34 #include <list>
    34 #include <list>
       
    35 #include "gamelog.h"
    35 
    36 
    36 #include "table/strings.h"
    37 #include "table/strings.h"
    37 
    38 
    38 extern const uint16 SAVEGAME_VERSION = NEWGRF_AIRPORTS_SAVEGAME;
    39 extern const uint16 SAVEGAME_VERSION = NEWGRF_AIRPORTS_SAVEGAME;
    39 
    40 
    41 
    42 
    42 uint32 _ttdp_version;     ///< version of TTDP savegame (if applicable)
    43 uint32 _ttdp_version;     ///< version of TTDP savegame (if applicable)
    43 uint16 _sl_version;       ///< the major savegame version identifier
    44 uint16 _sl_version;       ///< the major savegame version identifier
    44 byte   _sl_minor_version; ///< the minor savegame version, DO NOT USE!
    45 byte   _sl_minor_version; ///< the minor savegame version, DO NOT USE!
    45 
    46 
    46 typedef void WriterProc(uint len);
    47 typedef void WriterProc(size_t len);
    47 typedef uint ReaderProc();
    48 typedef size_t ReaderProc();
    48 
    49 
    49 /** The saveload struct, containing reader-writer functions, bufffer, version, etc. */
    50 /** The saveload struct, containing reader-writer functions, bufffer, version, etc. */
    50 static struct {
    51 static struct {
    51 	bool save;                           ///< are we doing a save or a load atm. True when saving
    52 	bool save;                           ///< are we doing a save or a load atm. True when saving
    52 	byte need_length;                    ///< ???
    53 	byte need_length;                    ///< ???
    53 	byte block_mode;                     ///< ???
    54 	byte block_mode;                     ///< ???
    54 	bool error;                          ///< did an error occur or not
    55 	bool error;                          ///< did an error occur or not
    55 
    56 
    56 	int obj_len;                         ///< the length of the current object we are busy with
    57 	size_t obj_len;                      ///< the length of the current object we are busy with
    57 	int array_index, last_array_index;   ///< in the case of an array, the current and last positions
    58 	int array_index, last_array_index;   ///< in the case of an array, the current and last positions
    58 
    59 
    59 	uint32 offs_base;                    ///< the offset in number of bytes since we started writing data (eg uncompressed savegame size)
    60 	size_t offs_base;                    ///< the offset in number of bytes since we started writing data (eg uncompressed savegame size)
    60 
    61 
    61 	WriterProc *write_bytes;             ///< savegame writer function
    62 	WriterProc *write_bytes;             ///< savegame writer function
    62 	ReaderProc *read_bytes;              ///< savegame loader function
    63 	ReaderProc *read_bytes;              ///< savegame loader function
    63 
    64 
    64 	const ChunkHandler* const *chs;      ///< the chunk of data that is being processed atm (vehicles, signs, etc.)
    65 	const ChunkHandler* const *chs;      ///< the chunk of data that is being processed atm (vehicles, signs, etc.)
   121 /**
   122 /**
   122  * Fill the input buffer by reading from the file with the given reader
   123  * Fill the input buffer by reading from the file with the given reader
   123  */
   124  */
   124 static void SlReadFill()
   125 static void SlReadFill()
   125 {
   126 {
   126 	uint len = _sl.read_bytes();
   127 	size_t len = _sl.read_bytes();
   127 	if (len == 0) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Unexpected end of chunk");
   128 	if (len == 0) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Unexpected end of chunk");
   128 
   129 
   129 	_sl.bufp = _sl.buf;
   130 	_sl.bufp = _sl.buf;
   130 	_sl.bufe = _sl.buf + len;
   131 	_sl.bufe = _sl.buf + len;
   131 	_sl.offs_base += len;
   132 	_sl.offs_base += len;
   132 }
   133 }
   133 
   134 
   134 static inline uint32 SlGetOffs() {return _sl.offs_base - (_sl.bufe - _sl.bufp);}
   135 static inline size_t SlGetOffs() {return _sl.offs_base - (_sl.bufe - _sl.bufp);}
   135 
   136 
   136 /** Return the size in bytes of a certain type of normal/atomic variable
   137 /** Return the size in bytes of a certain type of normal/atomic variable
   137  * as it appears in memory. See VarTypes
   138  * as it appears in memory. See VarTypes
   138  * @param conv VarType type of variable that is used for calculating the size
   139  * @param conv VarType type of variable that is used for calculating the size
   139  * @return Return the size of this type in bytes */
   140  * @return Return the size of this type in bytes */
   281  * 110xxxxx xxxxxxxx xxxxxxxx
   282  * 110xxxxx xxxxxxxx xxxxxxxx
   282  * 1110xxxx xxxxxxxx xxxxxxxx xxxxxxxx
   283  * 1110xxxx xxxxxxxx xxxxxxxx xxxxxxxx
   283  * @param i Index being written
   284  * @param i Index being written
   284  */
   285  */
   285 
   286 
   286 static void SlWriteSimpleGamma(uint i)
   287 static void SlWriteSimpleGamma(size_t i)
   287 {
   288 {
   288 	if (i >= (1 << 7)) {
   289 	if (i >= (1 << 7)) {
   289 		if (i >= (1 << 14)) {
   290 		if (i >= (1 << 14)) {
   290 			if (i >= (1 << 21)) {
   291 			if (i >= (1 << 21)) {
   291 				assert(i < (1 << 28));
   292 				assert(i < (1 << 28));
   292 				SlWriteByte((byte)0xE0 | (i >> 24));
   293 				SlWriteByte((byte)(0xE0 | (i >> 24)));
   293 				SlWriteByte((byte)(i >> 16));
   294 				SlWriteByte((byte)(i >> 16));
   294 			} else {
   295 			} else {
   295 				SlWriteByte((byte)0xC0 | (i >> 16));
   296 				SlWriteByte((byte)(0xC0 | (i >> 16)));
   296 			}
   297 			}
   297 			SlWriteByte((byte)(i >> 8));
   298 			SlWriteByte((byte)(i >> 8));
   298 		} else {
   299 		} else {
   299 			SlWriteByte((byte)(0x80 | (i >> 8)));
   300 			SlWriteByte((byte)(0x80 | (i >> 8)));
   300 		}
   301 		}
   301 	}
   302 	}
   302 	SlWriteByte(i);
   303 	SlWriteByte((byte)i);
   303 }
   304 }
   304 
   305 
   305 /** Return how many bytes used to encode a gamma value */
   306 /** Return how many bytes used to encode a gamma value */
   306 static inline uint SlGetGammaLength(uint i)
   307 static inline uint SlGetGammaLength(size_t i)
   307 {
   308 {
   308 	return 1 + (i >= (1 << 7)) + (i >= (1 << 14)) + (i >= (1 << 21));
   309 	return 1 + (i >= (1 << 7)) + (i >= (1 << 14)) + (i >= (1 << 21));
   309 }
   310 }
   310 
   311 
   311 static inline uint SlReadSparseIndex() {return SlReadSimpleGamma();}
   312 static inline uint SlReadSparseIndex() {return SlReadSimpleGamma();}
   312 static inline void SlWriteSparseIndex(uint index) {SlWriteSimpleGamma(index);}
   313 static inline void SlWriteSparseIndex(uint index) {SlWriteSimpleGamma(index);}
   313 
   314 
   314 static inline uint SlReadArrayLength() {return SlReadSimpleGamma();}
   315 static inline uint SlReadArrayLength() {return SlReadSimpleGamma();}
   315 static inline void SlWriteArrayLength(uint length) {SlWriteSimpleGamma(length);}
   316 static inline void SlWriteArrayLength(size_t length) {SlWriteSimpleGamma(length);}
   316 static inline uint SlGetArrayLength(uint length) {return SlGetGammaLength(length);}
   317 static inline uint SlGetArrayLength(size_t length) {return SlGetGammaLength(length);}
   317 
   318 
   318 void SlSetArrayIndex(uint index)
   319 void SlSetArrayIndex(uint index)
   319 {
   320 {
   320 	_sl.need_length = NL_WANTLENGTH;
   321 	_sl.need_length = NL_WANTLENGTH;
   321 	_sl.array_index = index;
   322 	_sl.array_index = index;
   322 }
   323 }
   323 
   324 
   324 static uint32 _next_offs;
   325 static size_t _next_offs;
   325 
   326 
   326 /**
   327 /**
   327  * Iterate through the elements of an array and read the whole thing
   328  * Iterate through the elements of an array and read the whole thing
   328  * @return The index of the object, or -1 if we have reached the end of current block
   329  * @return The index of the object, or -1 if we have reached the end of current block
   329  */
   330  */
   373 		case CH_RIFF:
   374 		case CH_RIFF:
   374 			/* Ugly encoding of >16M RIFF chunks
   375 			/* Ugly encoding of >16M RIFF chunks
   375 			 * The lower 24 bits are normal
   376 			 * The lower 24 bits are normal
   376 			 * The uppermost 4 bits are bits 24:27 */
   377 			 * The uppermost 4 bits are bits 24:27 */
   377 			assert(length < (1 << 28));
   378 			assert(length < (1 << 28));
   378 			SlWriteUint32((length & 0xFFFFFF) | ((length >> 24) << 28));
   379 			SlWriteUint32((uint32)((length & 0xFFFFFF) | ((length >> 24) << 28)));
   379 			break;
   380 			break;
   380 		case CH_ARRAY:
   381 		case CH_ARRAY:
   381 			assert(_sl.last_array_index <= _sl.array_index);
   382 			assert(_sl.last_array_index <= _sl.array_index);
   382 			while (++_sl.last_array_index <= _sl.array_index)
   383 			while (++_sl.last_array_index <= _sl.array_index)
   383 				SlWriteArrayLength(1);
   384 				SlWriteArrayLength(1);
   388 			SlWriteSparseIndex(_sl.array_index);
   389 			SlWriteSparseIndex(_sl.array_index);
   389 			break;
   390 			break;
   390 		default: NOT_REACHED();
   391 		default: NOT_REACHED();
   391 		} break;
   392 		} break;
   392 	case NL_CALCLENGTH:
   393 	case NL_CALCLENGTH:
   393 		_sl.obj_len += length;
   394 		_sl.obj_len += (int)length;
   394 		break;
   395 		break;
   395 	}
   396 	}
   396 }
   397 }
   397 
   398 
   398 /**
   399 /**
   420 {
   421 {
   421 	for (; length != 0; length--) SlReadByte();
   422 	for (; length != 0; length--) SlReadByte();
   422 }
   423 }
   423 
   424 
   424 /* Get the length of the current object */
   425 /* Get the length of the current object */
   425 uint SlGetFieldLength() {return _sl.obj_len;}
   426 size_t SlGetFieldLength() {return _sl.obj_len;}
   426 
   427 
   427 /** Return a signed-long version of the value of a setting
   428 /** Return a signed-long version of the value of a setting
   428  * @param ptr pointer to the variable
   429  * @param ptr pointer to the variable
   429  * @param conv type of variable, can be a non-clean
   430  * @param conv type of variable, can be a non-clean
   430  * type, eg one with other flags because it is parsed
   431  * type, eg one with other flags because it is parsed
   626 /**
   627 /**
   627  * Return the size in bytes of a certain type of atomic array
   628  * Return the size in bytes of a certain type of atomic array
   628  * @param length The length of the array counted in elements
   629  * @param length The length of the array counted in elements
   629  * @param conv VarType type of the variable that is used in calculating the size
   630  * @param conv VarType type of the variable that is used in calculating the size
   630  */
   631  */
   631 static inline size_t SlCalcArrayLen(uint length, VarType conv)
   632 static inline size_t SlCalcArrayLen(size_t length, VarType conv)
   632 {
   633 {
   633 	return SlCalcConvFileLen(conv) * length;
   634 	return SlCalcConvFileLen(conv) * length;
   634 }
   635 }
   635 
   636 
   636 /**
   637 /**
   637  * Save/Load an array.
   638  * Save/Load an array.
   638  * @param array The array being manipulated
   639  * @param array The array being manipulated
   639  * @param length The length of the array in elements
   640  * @param length The length of the array in elements
   640  * @param conv VarType type of the atomic array (int, byte, uint64, etc.)
   641  * @param conv VarType type of the atomic array (int, byte, uint64, etc.)
   641  */
   642  */
   642 void SlArray(void *array, uint length, VarType conv)
   643 void SlArray(void *array, size_t length, VarType conv)
   643 {
   644 {
   644 	/* Automatically calculate the length? */
   645 	/* Automatically calculate the length? */
   645 	if (_sl.need_length != NL_NONE) {
   646 	if (_sl.need_length != NL_NONE) {
   646 		SlSetLength(SlCalcArrayLen(length, conv));
   647 		SlSetLength(SlCalcArrayLen(length, conv));
   647 		/* Determine length only? */
   648 		/* Determine length only? */
   649 	}
   650 	}
   650 
   651 
   651 	/* NOTICE - handle some buggy stuff, in really old versions everything was saved
   652 	/* NOTICE - handle some buggy stuff, in really old versions everything was saved
   652 	 * as a byte-type. So detect this, and adjust array size accordingly */
   653 	 * as a byte-type. So detect this, and adjust array size accordingly */
   653 	if (!_sl.save && _sl_version == 0) {
   654 	if (!_sl.save && _sl_version == 0) {
       
   655 		/* all arrays except difficulty settings */
   654 		if (conv == SLE_INT16 || conv == SLE_UINT16 || conv == SLE_STRINGID ||
   656 		if (conv == SLE_INT16 || conv == SLE_UINT16 || conv == SLE_STRINGID ||
   655 				conv == SLE_INT32 || conv == SLE_UINT32) {
   657 				conv == SLE_INT32 || conv == SLE_UINT32) {
   656 			length *= SlCalcConvFileLen(conv);
   658 			SlCopyBytes(array, length * SlCalcConvFileLen(conv));
   657 			conv = SLE_INT8;
   659 			return;
       
   660 		}
       
   661 		/* used for conversion of Money 32bit->64bit */
       
   662 		if (conv == (SLE_FILE_I32 | SLE_VAR_I64)) {
       
   663 			for (uint i = 0; i < length; i++) {
       
   664 				((int64*)array)[i] = (int32)BSWAP32(SlReadUint32());
       
   665 			}
       
   666 			return;
   658 		}
   667 		}
   659 	}
   668 	}
   660 
   669 
   661 	/* If the size of elements is 1 byte both in file and memory, no special
   670 	/* If the size of elements is 1 byte both in file and memory, no special
   662 	 * conversion is needed, use specialized copy-copy function to speed up things */
   671 	 * conversion is needed, use specialized copy-copy function to speed up things */
   708 	}
   717 	}
   709 
   718 
   710 	std::list<void *> *l = (std::list<void *> *) list;
   719 	std::list<void *> *l = (std::list<void *> *) list;
   711 
   720 
   712 	if (_sl.save) {
   721 	if (_sl.save) {
   713 		SlWriteUint32(l->size());
   722 		SlWriteUint32((uint32)l->size());
   714 
   723 
   715 		std::list<void *>::iterator iter;
   724 		std::list<void *>::iterator iter;
   716 		for (iter = l->begin(); iter != l->end(); ++iter) {
   725 		for (iter = l->begin(); iter != l->end(); ++iter) {
   717 			void *ptr = *iter;
   726 			void *ptr = *iter;
   718 			SlWriteUint32(ReferenceToInt(ptr, conv));
   727 			SlWriteUint32(ReferenceToInt(ptr, conv));
   755  * Calculate the size of an object.
   764  * Calculate the size of an object.
   756  * @param object to be measured
   765  * @param object to be measured
   757  * @param sld The SaveLoad description of the object so we know how to manipulate it
   766  * @param sld The SaveLoad description of the object so we know how to manipulate it
   758  * @return size of given objetc
   767  * @return size of given objetc
   759  */
   768  */
   760 static size_t SlCalcObjLength(const void *object, const SaveLoad *sld)
   769 size_t SlCalcObjLength(const void *object, const SaveLoad *sld)
   761 {
   770 {
   762 	size_t length = 0;
   771 	size_t length = 0;
   763 
   772 
   764 	/* Need to determine the length and write a length tag. */
   773 	/* Need to determine the length and write a length tag. */
   765 	for (; sld->cmd != SL_END; sld++) {
   774 	for (; sld->cmd != SL_END; sld++) {
   882  * @param proc The callback procedure that is called
   891  * @param proc The callback procedure that is called
   883  * @param arg The variable that will be used for the callback procedure
   892  * @param arg The variable that will be used for the callback procedure
   884  */
   893  */
   885 void SlAutolength(AutolengthProc *proc, void *arg)
   894 void SlAutolength(AutolengthProc *proc, void *arg)
   886 {
   895 {
   887 	uint32 offs;
   896 	size_t offs;
   888 
   897 
   889 	assert(_sl.save);
   898 	assert(_sl.save);
   890 
   899 
   891 	/* Tell it to calculate the length */
   900 	/* Tell it to calculate the length */
   892 	_sl.need_length = NL_CALCLENGTH;
   901 	_sl.need_length = NL_CALCLENGTH;
   910  * @param ch The chunkhandler that will be used for the operation
   919  * @param ch The chunkhandler that will be used for the operation
   911  */
   920  */
   912 static void SlLoadChunk(const ChunkHandler *ch)
   921 static void SlLoadChunk(const ChunkHandler *ch)
   913 {
   922 {
   914 	byte m = SlReadByte();
   923 	byte m = SlReadByte();
   915 	uint32 len;
   924 	size_t len;
   916 	uint32 endoffs;
   925 	size_t endoffs;
   917 
   926 
   918 	_sl.block_mode = m;
   927 	_sl.block_mode = m;
   919 	_sl.obj_len = 0;
   928 	_sl.obj_len = 0;
   920 
   929 
   921 	switch (m) {
   930 	switch (m) {
  1050  *******************************************/
  1059  *******************************************/
  1051 #define LZO_SIZE 8192
  1060 #define LZO_SIZE 8192
  1052 
  1061 
  1053 #include "minilzo.h"
  1062 #include "minilzo.h"
  1054 
  1063 
  1055 static uint ReadLZO()
  1064 static size_t ReadLZO()
  1056 {
  1065 {
  1057 	byte out[LZO_SIZE + LZO_SIZE / 64 + 16 + 3 + 8];
  1066 	byte out[LZO_SIZE + LZO_SIZE / 64 + 16 + 3 + 8];
  1058 	uint32 tmp[2];
  1067 	uint32 tmp[2];
  1059 	uint32 size;
  1068 	uint32 size;
  1060 	uint len;
  1069 	uint len;
  1083 	return len;
  1092 	return len;
  1084 }
  1093 }
  1085 
  1094 
  1086 /* p contains the pointer to the buffer, len contains the pointer to the length.
  1095 /* p contains the pointer to the buffer, len contains the pointer to the length.
  1087  * len bytes will be written, p and l will be updated to reflect the next buffer. */
  1096  * len bytes will be written, p and l will be updated to reflect the next buffer. */
  1088 static void WriteLZO(uint size)
  1097 static void WriteLZO(size_t size)
  1089 {
  1098 {
  1090 	byte out[LZO_SIZE + LZO_SIZE / 64 + 16 + 3 + 8];
  1099 	byte out[LZO_SIZE + LZO_SIZE / 64 + 16 + 3 + 8];
  1091 	byte wrkmem[sizeof(byte*)*4096];
  1100 	byte wrkmem[sizeof(byte*)*4096];
  1092 	uint outlen;
  1101 	uint outlen;
  1093 
  1102 
  1094 	lzo1x_1_compress(_sl.buf, size, out + sizeof(uint32)*2, &outlen, wrkmem);
  1103 	lzo1x_1_compress(_sl.buf, (lzo_uint)size, out + sizeof(uint32)*2, &outlen, wrkmem);
  1095 	((uint32*)out)[1] = TO_BE32(outlen);
  1104 	((uint32*)out)[1] = TO_BE32(outlen);
  1096 	((uint32*)out)[0] = TO_BE32(lzo_adler32(0, out + sizeof(uint32), outlen + sizeof(uint32)));
  1105 	((uint32*)out)[0] = TO_BE32(lzo_adler32(0, out + sizeof(uint32), outlen + sizeof(uint32)));
  1097 	if (fwrite(out, outlen + sizeof(uint32)*2, 1, _sl.fh) != 1) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE);
  1106 	if (fwrite(out, outlen + sizeof(uint32)*2, 1, _sl.fh) != 1) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE);
  1098 }
  1107 }
  1099 
  1108 
  1110 }
  1119 }
  1111 
  1120 
  1112 /*********************************************
  1121 /*********************************************
  1113  ******** START OF NOCOMP CODE (uncompressed)*
  1122  ******** START OF NOCOMP CODE (uncompressed)*
  1114  *********************************************/
  1123  *********************************************/
  1115 static uint ReadNoComp()
  1124 static size_t ReadNoComp()
  1116 {
  1125 {
  1117 	return fread(_sl.buf, 1, LZO_SIZE, _sl.fh);
  1126 	return fread(_sl.buf, 1, LZO_SIZE, _sl.fh);
  1118 }
  1127 }
  1119 
  1128 
  1120 static void WriteNoComp(uint size)
  1129 static void WriteNoComp(size_t size)
  1121 {
  1130 {
  1122 	if (fwrite(_sl.buf, 1, size, _sl.fh) != size) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE);
  1131 	if (fwrite(_sl.buf, 1, size, _sl.fh) != size) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE);
  1123 }
  1132 }
  1124 
  1133 
  1125 static bool InitNoComp()
  1134 static bool InitNoComp()
  1168 static void UnInitMem()
  1177 static void UnInitMem()
  1169 {
  1178 {
  1170 	_Savegame_pool.CleanPool();
  1179 	_Savegame_pool.CleanPool();
  1171 }
  1180 }
  1172 
  1181 
  1173 static void WriteMem(uint size)
  1182 static void WriteMem(size_t size)
  1174 {
  1183 {
  1175 	_ts.count += size;
  1184 	_ts.count += (uint)size;
  1176 	/* Allocate new block and new buffer-pointer */
  1185 	/* Allocate new block and new buffer-pointer */
  1177 	_Savegame_pool.AddBlockIfNeeded(_ts.count);
  1186 	_Savegame_pool.AddBlockIfNeeded(_ts.count);
  1178 	_sl.buf = GetSavegame(_ts.count);
  1187 	_sl.buf = GetSavegame(_ts.count);
  1179 }
  1188 }
  1180 
  1189 
  1195 	_sl.bufsize = 4096;
  1204 	_sl.bufsize = 4096;
  1196 	_sl.buf = _sl.buf_ori = MallocT<byte>(4096 + 4096); // also contains fread buffer
  1205 	_sl.buf = _sl.buf_ori = MallocT<byte>(4096 + 4096); // also contains fread buffer
  1197 	return true;
  1206 	return true;
  1198 }
  1207 }
  1199 
  1208 
  1200 static uint ReadZlib()
  1209 static size_t ReadZlib()
  1201 {
  1210 {
  1202 	int r;
  1211 	int r;
  1203 
  1212 
  1204 	_z.next_out = _sl.buf;
  1213 	_z.next_out = _sl.buf;
  1205 	_z.avail_out = 4096;
  1214 	_z.avail_out = 4096;
  1235 	_sl.bufsize = 4096;
  1244 	_sl.bufsize = 4096;
  1236 	_sl.buf = _sl.buf_ori = MallocT<byte>(4096); // also contains fread buffer
  1245 	_sl.buf = _sl.buf_ori = MallocT<byte>(4096); // also contains fread buffer
  1237 	return true;
  1246 	return true;
  1238 }
  1247 }
  1239 
  1248 
  1240 static void WriteZlibLoop(z_streamp z, byte *p, uint len, int mode)
  1249 static void WriteZlibLoop(z_streamp z, byte *p, size_t len, int mode)
  1241 {
  1250 {
  1242 	byte buf[1024]; // output buffer
  1251 	byte buf[1024]; // output buffer
  1243 	int r;
  1252 	int r;
  1244 	uint n;
  1253 	uint n;
  1245 	z->next_in = p;
  1254 	z->next_in = p;
  1246 	z->avail_in = len;
  1255 	z->avail_in = (uInt)len;
  1247 	do {
  1256 	do {
  1248 		z->next_out = buf;
  1257 		z->next_out = buf;
  1249 		z->avail_out = sizeof(buf);
  1258 		z->avail_out = sizeof(buf);
  1250 		r = deflate(z, mode);
  1259 		r = deflate(z, mode);
  1251 			/* bytes were emitted? */
  1260 			/* bytes were emitted? */
  1256 			break;
  1265 			break;
  1257 		if (r != Z_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "zlib returned error code");
  1266 		if (r != Z_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "zlib returned error code");
  1258 	} while (z->avail_in || !z->avail_out);
  1267 	} while (z->avail_in || !z->avail_out);
  1259 }
  1268 }
  1260 
  1269 
  1261 static void WriteZlib(uint len)
  1270 static void WriteZlib(size_t len)
  1262 {
  1271 {
  1263 	WriteZlibLoop(&_z, _sl.buf, len, 0);
  1272 	WriteZlibLoop(&_z, _sl.buf, len, 0);
  1264 }
  1273 }
  1265 
  1274 
  1266 static void UninitWriteZlib()
  1275 static void UninitWriteZlib()
  1276 /*******************************************
  1285 /*******************************************
  1277  ************* END OF CODE *****************
  1286  ************* END OF CODE *****************
  1278  *******************************************/
  1287  *******************************************/
  1279 
  1288 
  1280 /* these define the chunks */
  1289 /* these define the chunks */
       
  1290 extern const ChunkHandler _gamelog_chunk_handlers[];
  1281 extern const ChunkHandler _misc_chunk_handlers[];
  1291 extern const ChunkHandler _misc_chunk_handlers[];
  1282 extern const ChunkHandler _name_chunk_handlers[];
  1292 extern const ChunkHandler _name_chunk_handlers[];
  1283 extern const ChunkHandler _cheat_chunk_handlers[] ;
  1293 extern const ChunkHandler _cheat_chunk_handlers[] ;
  1284 extern const ChunkHandler _setting_chunk_handlers[];
  1294 extern const ChunkHandler _setting_chunk_handlers[];
  1285 extern const ChunkHandler _player_chunk_handlers[];
  1295 extern const ChunkHandler _player_chunk_handlers[];
  1297 extern const ChunkHandler _newgrf_chunk_handlers[];
  1307 extern const ChunkHandler _newgrf_chunk_handlers[];
  1298 extern const ChunkHandler _group_chunk_handlers[];
  1308 extern const ChunkHandler _group_chunk_handlers[];
  1299 extern const ChunkHandler _cargopacket_chunk_handlers[];
  1309 extern const ChunkHandler _cargopacket_chunk_handlers[];
  1300 
  1310 
  1301 static const ChunkHandler * const _chunk_handlers[] = {
  1311 static const ChunkHandler * const _chunk_handlers[] = {
       
  1312 	_gamelog_chunk_handlers,
  1302 	_misc_chunk_handlers,
  1313 	_misc_chunk_handlers,
  1303 	_name_chunk_handlers,
  1314 	_name_chunk_handlers,
  1304 	_cheat_chunk_handlers,
  1315 	_cheat_chunk_handlers,
  1305 	_setting_chunk_handlers,
  1316 	_setting_chunk_handlers,
  1306 	_veh_chunk_handlers,
  1317 	_veh_chunk_handlers,
  1469 	}
  1480 	}
  1470 	return def;
  1481 	return def;
  1471 }
  1482 }
  1472 
  1483 
  1473 /* actual loader/saver function */
  1484 /* actual loader/saver function */
  1474 void InitializeGame(int mode, uint size_x, uint size_y);
  1485 void InitializeGame(uint size_x, uint size_y, bool reset_date);
  1475 extern bool AfterLoadGame();
  1486 extern bool AfterLoadGame();
  1476 extern void BeforeSaveGame();
  1487 extern void SaveViewportBeforeSaveGame();
  1477 extern bool LoadOldSaveGame(const char *file);
  1488 extern bool LoadOldSaveGame(const char *file);
  1478 
  1489 
  1479 /** Small helper function to close the to be loaded savegame an signal error */
  1490 /** Small helper function to close the to be loaded savegame an signal error */
  1480 static inline SaveOrLoadResult AbortSaveLoad()
  1491 static inline SaveOrLoadResult AbortSaveLoad()
  1481 {
  1492 {
  1594 		}
  1605 		}
  1595 		return SL_ERROR;
  1606 		return SL_ERROR;
  1596 	}
  1607 	}
  1597 }
  1608 }
  1598 
  1609 
  1599 static void * CDECL SaveFileToDiskThread(void *arg)
  1610 static void SaveFileToDiskThread(void *arg)
  1600 {
  1611 {
  1601 	SaveFileToDisk(true);
  1612 	SaveFileToDisk(true);
  1602 	return NULL;
       
  1603 }
  1613 }
  1604 
  1614 
  1605 void WaitTillSaved()
  1615 void WaitTillSaved()
  1606 {
  1616 {
  1607 	if (_save_thread == NULL) return;
  1617 	if (_save_thread == NULL) return;
  1632 
  1642 
  1633 	_next_offs = 0;
  1643 	_next_offs = 0;
  1634 
  1644 
  1635 	/* Load a TTDLX or TTDPatch game */
  1645 	/* Load a TTDLX or TTDPatch game */
  1636 	if (mode == SL_OLD_LOAD) {
  1646 	if (mode == SL_OLD_LOAD) {
  1637 		InitializeGame(IG_DATE_RESET, 256, 256); // set a mapsize of 256x256 for TTDPatch games or it might get confused
  1647 		InitializeGame(256, 256, true); // set a mapsize of 256x256 for TTDPatch games or it might get confused
       
  1648 		GamelogReset();
  1638 		if (!LoadOldSaveGame(filename)) return SL_REINIT;
  1649 		if (!LoadOldSaveGame(filename)) return SL_REINIT;
  1639 		_sl_version = 0;
  1650 		_sl_version = 0;
  1640 		_sl_minor_version = 0;
  1651 		_sl_minor_version = 0;
  1641 		if (!AfterLoadGame()) return SL_REINIT;
  1652 		GamelogStartAction(GLAT_LOAD);
       
  1653 		if (!AfterLoadGame()) {
       
  1654 			GamelogStopAction();
       
  1655 			return SL_REINIT;
       
  1656 		}
       
  1657 		GamelogStopAction();
  1642 		return SL_OK;
  1658 		return SL_OK;
  1643 	}
  1659 	}
  1644 
  1660 
  1645 	_sl.excpt_uninit = NULL;
  1661 	_sl.excpt_uninit = NULL;
  1646 	try {
  1662 	try {
  1671 				return AbortSaveLoad();
  1687 				return AbortSaveLoad();
  1672 			}
  1688 			}
  1673 
  1689 
  1674 			_sl_version = SAVEGAME_VERSION;
  1690 			_sl_version = SAVEGAME_VERSION;
  1675 
  1691 
  1676 			BeforeSaveGame();
  1692 			SaveViewportBeforeSaveGame();
  1677 			SlSaveChunks();
  1693 			SlSaveChunks();
  1678 			SlWriteFill(); // flush the save buffer
  1694 			SlWriteFill(); // flush the save buffer
  1679 
  1695 
  1680 			SaveFileStart();
  1696 			SaveFileStart();
  1681 			if (_network_server ||
  1697 			if (_network_server ||
  1745 			}
  1761 			}
  1746 
  1762 
  1747 			/* Old maps were hardcoded to 256x256 and thus did not contain
  1763 			/* Old maps were hardcoded to 256x256 and thus did not contain
  1748 			 * any mapsize information. Pre-initialize to 256x256 to not to
  1764 			 * any mapsize information. Pre-initialize to 256x256 to not to
  1749 			 * confuse old games */
  1765 			 * confuse old games */
  1750 			InitializeGame(IG_DATE_RESET, 256, 256);
  1766 			InitializeGame(256, 256, true);
       
  1767 
       
  1768 			GamelogReset();
  1751 
  1769 
  1752 			SlLoadChunks();
  1770 			SlLoadChunks();
  1753 			fmt->uninit_read();
  1771 			fmt->uninit_read();
  1754 			fclose(_sl.fh);
  1772 			fclose(_sl.fh);
  1755 
  1773 
       
  1774 			GamelogStartAction(GLAT_LOAD);
       
  1775 
  1756 			_savegame_type = SGT_OTTD;
  1776 			_savegame_type = SGT_OTTD;
  1757 
  1777 
  1758 			/* After loading fix up savegame for any internal changes that
  1778 			/* After loading fix up savegame for any internal changes that
  1759 			 * might've occured since then. If it fails, load back the old game */
  1779 			 * might've occured since then. If it fails, load back the old game */
  1760 			if (!AfterLoadGame()) return SL_REINIT;
  1780 			if (!AfterLoadGame()) {
       
  1781 				GamelogStopAction();
       
  1782 				return SL_REINIT;
       
  1783 			}
       
  1784 
       
  1785 			GamelogStopAction();
  1761 		}
  1786 		}
  1762 
  1787 
  1763 		return SL_OK;
  1788 		return SL_OK;
  1764 	}
  1789 	}
  1765 	catch (...) {
  1790 	catch (...) {
  1774 		/* A saver/loader exception!! reinitialize all variables to prevent crash! */
  1799 		/* A saver/loader exception!! reinitialize all variables to prevent crash! */
  1775 		return (mode == SL_LOAD) ? SL_REINIT : SL_ERROR;
  1800 		return (mode == SL_LOAD) ? SL_REINIT : SL_ERROR;
  1776 	}
  1801 	}
  1777 }
  1802 }
  1778 
  1803 
  1779 /** Do a save when exiting the game (patch option) _settings.gui.autosave_on_exit */
  1804 /** Do a save when exiting the game (patch option) _settings_client.gui.autosave_on_exit */
  1780 void DoExitSave()
  1805 void DoExitSave()
  1781 {
  1806 {
  1782 	SaveOrLoad("exit.sav", SL_SAVE, AUTOSAVE_DIR);
  1807 	SaveOrLoad("exit.sav", SL_SAVE, AUTOSAVE_DIR);
  1783 }
  1808 }
  1784 
  1809