src/saveload.cpp
changeset 6117 6507b2a7e71d
parent 6012 065d7234a7a9
child 6118 e7d7787afb9b
equal deleted inserted replaced
6116:0a63874accb6 6117:6507b2a7e71d
     1 /* $Id$ */
     1 /* $Id$ */
     2 
     2 
     3 /** @file
     3 /** @file saveload.cpp
     4  * All actions handling saving and loading goes on in this file. The general actions
     4  * All actions handling saving and loading goes on in this file. The general actions
     5  * are as follows for saving a game (loading is analogous):
     5  * are as follows for saving a game (loading is analogous):
     6  * <ol>
     6  * <ol>
     7  * <li>initialize the writer by creating a temporary memory-buffer for it
     7  * <li>initialize the writer by creating a temporary memory-buffer for it
     8  * <li>go through all to-be saved elements, each 'chunk' (ChunkHandler) prefixed by a label
     8  * <li>go through all to-be saved elements, each 'chunk' (ChunkHandler) prefixed by a label
    10  *    of the game it was active (used when loading)
    10  *    of the game it was active (used when loading)
    11  * <li>write all data byte-by-byte to the temporary buffer so it is endian-safe
    11  * <li>write all data byte-by-byte to the temporary buffer so it is endian-safe
    12  * <li>when the buffer is full; flush it to the output (eg save to file) (_sl.buf, _sl.bufp, _sl.bufe)
    12  * <li>when the buffer is full; flush it to the output (eg save to file) (_sl.buf, _sl.bufp, _sl.bufe)
    13  * <li>repeat this until everything is done, and flush any remaining output to file
    13  * <li>repeat this until everything is done, and flush any remaining output to file
    14  * </ol>
    14  * </ol>
    15  * @see ChunkHandler
       
    16  * @see SaveLoad
       
    17  */
    15  */
    18 #include "stdafx.h"
    16 #include "stdafx.h"
    19 #include "openttd.h"
    17 #include "openttd.h"
    20 #include "debug.h"
    18 #include "debug.h"
    21 #include "functions.h"
    19 #include "functions.h"
    29 #include "network/network.h"
    27 #include "network/network.h"
    30 #include "variables.h"
    28 #include "variables.h"
    31 #include <setjmp.h>
    29 #include <setjmp.h>
    32 
    30 
    33 extern const uint16 SAVEGAME_VERSION = 47;
    31 extern const uint16 SAVEGAME_VERSION = 47;
    34 uint16 _sl_version;       /// the major savegame version identifier
    32 uint16 _sl_version;       ///< the major savegame version identifier
    35 byte   _sl_minor_version; /// the minor savegame version, DO NOT USE!
    33 byte   _sl_minor_version; ///< the minor savegame version, DO NOT USE!
    36 
    34 
    37 typedef void WriterProc(uint len);
    35 typedef void WriterProc(uint len);
    38 typedef uint ReaderProc(void);
    36 typedef uint ReaderProc(void);
    39 
    37 
    40 /** The saveload struct, containing reader-writer functions, bufffer, version, etc. */
    38 /** The saveload struct, containing reader-writer functions, bufffer, version, etc. */
    41 static struct {
    39 static struct {
    42 	bool save;                           /// are we doing a save or a load atm. True when saving
    40 	bool save;                           ///< are we doing a save or a load atm. True when saving
    43 	byte need_length;                    /// ???
    41 	byte need_length;                    ///< ???
    44 	byte block_mode;                     /// ???
    42 	byte block_mode;                     ///< ???
    45 	bool error;                          /// did an error occur or not
    43 	bool error;                          ///< did an error occur or not
    46 
    44 
    47 	int obj_len;                         /// the length of the current object we are busy with
    45 	int obj_len;                         ///< the length of the current object we are busy with
    48 	int array_index, last_array_index;   /// in the case of an array, the current and last positions
    46 	int array_index, last_array_index;   ///< in the case of an array, the current and last positions
    49 
    47 
    50 	uint32 offs_base;                    /// the offset in number of bytes since we started writing data (eg uncompressed savegame size)
    48 	uint32 offs_base;                    ///< the offset in number of bytes since we started writing data (eg uncompressed savegame size)
    51 
    49 
    52 	WriterProc *write_bytes;             /// savegame writer function
    50 	WriterProc *write_bytes;             ///< savegame writer function
    53 	ReaderProc *read_bytes;              /// savegame loader function
    51 	ReaderProc *read_bytes;              ///< savegame loader function
    54 
    52 
    55 	const ChunkHandler* const *chs;      /// the chunk of data that is being processed atm (vehicles, signs, etc.)
    53 	const ChunkHandler* const *chs;      ///< the chunk of data that is being processed atm (vehicles, signs, etc.)
    56 	const SaveLoad* const *includes;     /// the internal layouf of the given chunk
    54 	const SaveLoad* const *includes;     ///< the internal layouf of the given chunk
    57 
    55 
    58 	/** When saving/loading savegames, they are always saved to a temporary memory-place
    56 	/* When saving/loading savegames, they are always saved to a temporary memory-place
    59 	 * to be flushed to file (save) or to final place (load) when full. */
    57 	 * to be flushed to file (save) or to final place (load) when full. */
    60 	byte *bufp, *bufe;                   /// bufp(ointer) gives the current position in the buffer bufe(nd) gives the end of the buffer
    58 	byte *bufp, *bufe;                   ///< bufp(ointer) gives the current position in the buffer bufe(nd) gives the end of the buffer
    61 
    59 
    62 	// these 3 may be used by compressor/decompressors.
    60 	/* these 3 may be used by compressor/decompressors. */
    63 	byte *buf;                           /// pointer to temporary memory to read/write, initialized by SaveLoadFormat->initread/write
    61 	byte *buf;                           ///< pointer to temporary memory to read/write, initialized by SaveLoadFormat->initread/write
    64 	byte *buf_ori;                       /// pointer to the original memory location of buf, used to free it afterwards
    62 	byte *buf_ori;                       ///< pointer to the original memory location of buf, used to free it afterwards
    65 	uint bufsize;                        /// the size of the temporary memory *buf
    63 	uint bufsize;                        ///< the size of the temporary memory *buf
    66 	FILE *fh;                            /// the file from which is read or written to
    64 	FILE *fh;                            ///< the file from which is read or written to
    67 
    65 
    68 	void (*excpt_uninit)(void);          /// the function to execute on any encountered error
    66 	void (*excpt_uninit)(void);          ///< the function to execute on any encountered error
    69 	const char *excpt_msg;               /// the error message
    67 	const char *excpt_msg;               ///< the error message
    70 	jmp_buf excpt;                       /// @todo used to jump to "exception handler";  really ugly
    68 	jmp_buf excpt;                       ///< @todo used to jump to "exception handler";  really ugly
    71 } _sl;
    69 } _sl;
    72 
    70 
    73 
    71 
    74 enum NeedLengthValues {NL_NONE = 0, NL_WANTLENGTH = 1, NL_CALCLENGTH = 2};
    72 enum NeedLengthValues {NL_NONE = 0, NL_WANTLENGTH = 1, NL_CALCLENGTH = 2};
    75 
    73 
    87 }
    85 }
    88 
    86 
    89 static inline uint32 SlGetOffs(void) {return _sl.offs_base - (_sl.bufe - _sl.bufp);}
    87 static inline uint32 SlGetOffs(void) {return _sl.offs_base - (_sl.bufe - _sl.bufp);}
    90 
    88 
    91 /** Return the size in bytes of a certain type of normal/atomic variable
    89 /** Return the size in bytes of a certain type of normal/atomic variable
    92  * as it appears in memory. @see VarTypes
    90  * as it appears in memory. See VarTypes
    93  * @param conv @VarType type of variable that is used for calculating the size
    91  * @param conv VarType type of variable that is used for calculating the size
    94  * @return Return the size of this type in bytes */
    92  * @return Return the size of this type in bytes */
    95 static inline byte SlCalcConvMemLen(VarType conv)
    93 static inline byte SlCalcConvMemLen(VarType conv)
    96 {
    94 {
    97 	static const byte conv_mem_size[] = {1, 1, 1, 2, 2, 4, 4, 8, 8, 0};
    95 	static const byte conv_mem_size[] = {1, 1, 1, 2, 2, 4, 4, 8, 8, 0};
    98 	byte length = GB(conv, 4, 4);
    96 	byte length = GB(conv, 4, 4);
    99 	assert(length < lengthof(conv_mem_size));
    97 	assert(length < lengthof(conv_mem_size));
   100 	return conv_mem_size[length];
    98 	return conv_mem_size[length];
   101 }
    99 }
   102 
   100 
   103 /** Return the size in bytes of a certain type of normal/atomic variable
   101 /** Return the size in bytes of a certain type of normal/atomic variable
   104  * as it appears in a saved game. @see VarTypes
   102  * as it appears in a saved game. See VarTypes
   105  * @param conv @VarType type of variable that is used for calculating the size
   103  * @param conv VarType type of variable that is used for calculating the size
   106  * @return Return the size of this type in bytes */
   104  * @return Return the size of this type in bytes */
   107 static inline byte SlCalcConvFileLen(VarType conv)
   105 static inline byte SlCalcConvFileLen(VarType conv)
   108 {
   106 {
   109 	static const byte conv_file_size[] = {1, 1, 2, 2, 4, 4, 8, 8, 2};
   107 	static const byte conv_file_size[] = {1, 1, 2, 2, 4, 4, 8, 8, 2};
   110 	byte length = GB(conv, 0, 4);
   108 	byte length = GB(conv, 0, 4);
   111 	assert(length < lengthof(conv_file_size));
   109 	assert(length < lengthof(conv_file_size));
   112 	return conv_file_size[length];
   110 	return conv_file_size[length];
   113 }
   111 }
   114 
   112 
   115 /* Return the size in bytes of a reference (pointer) */
   113 /** Return the size in bytes of a reference (pointer) */
   116 static inline size_t SlCalcRefLen(void) {return 2;}
   114 static inline size_t SlCalcRefLen(void) {return 2;}
   117 
   115 
   118 /** Flush the output buffer by writing to disk with the given reader.
   116 /** Flush the output buffer by writing to disk with the given reader.
   119  * If the buffer pointer has not yet been set up, set it up now. Usually
   117  * If the buffer pointer has not yet been set up, set it up now. Usually
   120  * only called when the buffer is full, or there is no more data to be processed
   118  * only called when the buffer is full, or there is no more data to be processed
   121  */
   119  */
   122 static void SlWriteFill(void)
   120 static void SlWriteFill(void)
   123 {
   121 {
   124 	// flush the buffer to disk (the writer)
   122 	/* flush the buffer to disk (the writer) */
   125 	if (_sl.bufp != NULL) {
   123 	if (_sl.bufp != NULL) {
   126 		uint len = _sl.bufp - _sl.buf;
   124 		uint len = _sl.bufp - _sl.buf;
   127 		_sl.offs_base += len;
   125 		_sl.offs_base += len;
   128 		if (len) _sl.write_bytes(len);
   126 		if (len) _sl.write_bytes(len);
   129 	}
   127 	}
   130 
   128 
   131 	/* All the data from the buffer has been written away, rewind to the beginning
   129 	/* All the data from the buffer has been written away, rewind to the beginning
   132 	* to start reading in more data */
   130 	 * to start reading in more data */
   133 	_sl.bufp = _sl.buf;
   131 	_sl.bufp = _sl.buf;
   134 	_sl.bufe = _sl.buf + _sl.bufsize;
   132 	_sl.bufe = _sl.buf + _sl.bufsize;
   135 }
   133 }
   136 
   134 
   137 /** Error handler, calls longjmp to simulate an exception.
   135 /** Error handler, calls longjmp to simulate an exception.
   331 	switch (_sl.need_length) {
   329 	switch (_sl.need_length) {
   332 	case NL_WANTLENGTH:
   330 	case NL_WANTLENGTH:
   333 		_sl.need_length = NL_NONE;
   331 		_sl.need_length = NL_NONE;
   334 		switch (_sl.block_mode) {
   332 		switch (_sl.block_mode) {
   335 		case CH_RIFF:
   333 		case CH_RIFF:
   336 			// Ugly encoding of >16M RIFF chunks
   334 			/* Ugly encoding of >16M RIFF chunks
   337 			// The lower 24 bits are normal
   335 			 * The lower 24 bits are normal
   338 			// The uppermost 4 bits are bits 24:27
   336 			 * The uppermost 4 bits are bits 24:27 */
   339 			assert(length < (1<<28));
   337 			assert(length < (1<<28));
   340 			SlWriteUint32((length & 0xFFFFFF) | ((length >> 24) << 28));
   338 			SlWriteUint32((length & 0xFFFFFF) | ((length >> 24) << 28));
   341 			break;
   339 			break;
   342 		case CH_ARRAY:
   340 		case CH_ARRAY:
   343 			assert(_sl.last_array_index <= _sl.array_index);
   341 			assert(_sl.last_array_index <= _sl.array_index);
   437  * Handle all conversion and typechecking of variables here.
   435  * Handle all conversion and typechecking of variables here.
   438  * In the case of saving, read in the actual value from the struct
   436  * In the case of saving, read in the actual value from the struct
   439  * and then write them to file, endian safely. Loading a value
   437  * and then write them to file, endian safely. Loading a value
   440  * goes exactly the opposite way
   438  * goes exactly the opposite way
   441  * @param ptr The object being filled/read
   439  * @param ptr The object being filled/read
   442  * @param conv @VarType type of the current element of the struct
   440  * @param conv VarType type of the current element of the struct
   443  */
   441  */
   444 static void SlSaveLoadConv(void *ptr, VarType conv)
   442 static void SlSaveLoadConv(void *ptr, VarType conv)
   445 {
   443 {
   446 	int64 x = 0;
   444 	int64 x = 0;
   447 
   445 
   448 	if (_sl.save) { /* SAVE values */
   446 	if (_sl.save) { // SAVE values
   449 		/* Read a value from the struct. These ARE endian safe. */
   447 		/* Read a value from the struct. These ARE endian safe. */
   450 		x = ReadValue(ptr, conv);
   448 		x = ReadValue(ptr, conv);
   451 
   449 
   452 		/* Write the value to the file and check if its value is in the desired range */
   450 		/* Write the value to the file and check if its value is in the desired range */
   453 		switch (GetVarFileType(conv)) {
   451 		switch (GetVarFileType(conv)) {
   460 		case SLE_FILE_U32:                                   SlWriteUint32((uint32)x);break;
   458 		case SLE_FILE_U32:                                   SlWriteUint32((uint32)x);break;
   461 		case SLE_FILE_I64:
   459 		case SLE_FILE_I64:
   462 		case SLE_FILE_U64:                                   SlWriteUint64(x);break;
   460 		case SLE_FILE_U64:                                   SlWriteUint64(x);break;
   463 		default: NOT_REACHED();
   461 		default: NOT_REACHED();
   464 		}
   462 		}
   465 	} else { /* LOAD values */
   463 	} else { // LOAD values
   466 
   464 
   467 		/* Read a value from the file */
   465 		/* Read a value from the file */
   468 		switch (GetVarFileType(conv)) {
   466 		switch (GetVarFileType(conv)) {
   469 		case SLE_FILE_I8:  x = (int8  )SlReadByte();   break;
   467 		case SLE_FILE_I8:  x = (int8  )SlReadByte();   break;
   470 		case SLE_FILE_U8:  x = (byte  )SlReadByte();   break;
   468 		case SLE_FILE_U8:  x = (byte  )SlReadByte();   break;
   531  * @param conv must be SLE_FILE_STRING */
   529  * @param conv must be SLE_FILE_STRING */
   532 static void SlString(void *ptr, size_t length, VarType conv)
   530 static void SlString(void *ptr, size_t length, VarType conv)
   533 {
   531 {
   534 	size_t len;
   532 	size_t len;
   535 
   533 
   536 	if (_sl.save) { /* SAVE string */
   534 	if (_sl.save) { // SAVE string
   537 		switch (GetVarMemType(conv)) {
   535 		switch (GetVarMemType(conv)) {
   538 			default: NOT_REACHED();
   536 			default: NOT_REACHED();
   539 			case SLE_VAR_STRB:
   537 			case SLE_VAR_STRB:
   540 			case SLE_VAR_STRBQ:
   538 			case SLE_VAR_STRBQ:
   541 				len = SlCalcNetStringLen((char*)ptr, length);
   539 				len = SlCalcNetStringLen((char*)ptr, length);
   547 				break;
   545 				break;
   548 		}
   546 		}
   549 
   547 
   550 		SlWriteArrayLength(len);
   548 		SlWriteArrayLength(len);
   551 		SlCopyBytes(ptr, len);
   549 		SlCopyBytes(ptr, len);
   552 	} else { /* LOAD string */
   550 	} else { // LOAD string
   553 		len = SlReadArrayLength();
   551 		len = SlReadArrayLength();
   554 
   552 
   555 		switch (GetVarMemType(conv)) {
   553 		switch (GetVarMemType(conv)) {
   556 			default: NOT_REACHED();
   554 			default: NOT_REACHED();
   557 			case SLE_VAR_STRB:
   555 			case SLE_VAR_STRB:
   564 				} else {
   562 				} else {
   565 					SlCopyBytes(ptr, len);
   563 					SlCopyBytes(ptr, len);
   566 				}
   564 				}
   567 				break;
   565 				break;
   568 			case SLE_VAR_STR:
   566 			case SLE_VAR_STR:
   569 			case SLE_VAR_STRQ: /* Malloc'd string, free previous incarnation, and allocate */
   567 			case SLE_VAR_STRQ: // Malloc'd string, free previous incarnation, and allocate
   570 				free(*(char**)ptr);
   568 				free(*(char**)ptr);
   571 				*(char**)ptr = (char*)malloc(len + 1); // terminating '\0'
   569 				*(char**)ptr = (char*)malloc(len + 1); // terminating '\0'
   572 				ptr = *(char**)ptr;
   570 				ptr = *(char**)ptr;
   573 				SlCopyBytes(ptr, len);
   571 				SlCopyBytes(ptr, len);
   574 				break;
   572 				break;
   579 }
   577 }
   580 
   578 
   581 /**
   579 /**
   582  * Return the size in bytes of a certain type of atomic array
   580  * Return the size in bytes of a certain type of atomic array
   583  * @param length The length of the array counted in elements
   581  * @param length The length of the array counted in elements
   584  * @param conv @VarType type of the variable that is used in calculating the size
   582  * @param conv VarType type of the variable that is used in calculating the size
   585  */
   583  */
   586 static inline size_t SlCalcArrayLen(uint length, VarType conv)
   584 static inline size_t SlCalcArrayLen(uint length, VarType conv)
   587 {
   585 {
   588 	return SlCalcConvFileLen(conv) * length;
   586 	return SlCalcConvFileLen(conv) * length;
   589 }
   587 }
   590 
   588 
   591 /**
   589 /**
   592  * Save/Load an array.
   590  * Save/Load an array.
   593  * @param array The array being manipulated
   591  * @param array The array being manipulated
   594  * @param length The length of the array in elements
   592  * @param length The length of the array in elements
   595  * @param conv @VarType type of the atomic array (int, byte, uint64, etc.)
   593  * @param conv VarType type of the atomic array (int, byte, uint64, etc.)
   596  */
   594  */
   597 void SlArray(void *array, uint length, VarType conv)
   595 void SlArray(void *array, uint length, VarType conv)
   598 {
   596 {
   599 	// Automatically calculate the length?
   597 	/* Automatically calculate the length? */
   600 	if (_sl.need_length != NL_NONE) {
   598 	if (_sl.need_length != NL_NONE) {
   601 		SlSetLength(SlCalcArrayLen(length, conv));
   599 		SlSetLength(SlCalcArrayLen(length, conv));
   602 		// Determine length only?
   600 		/* Determine length only? */
   603 		if (_sl.need_length == NL_CALCLENGTH) return;
   601 		if (_sl.need_length == NL_CALCLENGTH) return;
   604 	}
   602 	}
   605 
   603 
   606 	/* NOTICE - handle some buggy stuff, in really old versions everything was saved
   604 	/* NOTICE - handle some buggy stuff, in really old versions everything was saved
   607 	 * as a byte-type. So detect this, and adjust array size accordingly */
   605 	 * as a byte-type. So detect this, and adjust array size accordingly */
   626 			a += mem_size; // get size
   624 			a += mem_size; // get size
   627 		}
   625 		}
   628 	}
   626 	}
   629 }
   627 }
   630 
   628 
   631 /* Are we going to save this object or not? */
   629 /** Are we going to save this object or not? */
   632 static inline bool SlIsObjectValidInSavegame(const SaveLoad *sld)
   630 static inline bool SlIsObjectValidInSavegame(const SaveLoad *sld)
   633 {
   631 {
   634 	if (_sl_version < sld->version_from || _sl_version > sld->version_to) return false;
   632 	if (_sl_version < sld->version_from || _sl_version > sld->version_to) return false;
   635 	if (sld->conv & SLF_SAVE_NO) return false;
   633 	if (sld->conv & SLF_SAVE_NO) return false;
   636 
   634 
   650 	return false;
   648 	return false;
   651 }
   649 }
   652 
   650 
   653 /**
   651 /**
   654  * Calculate the size of an object.
   652  * Calculate the size of an object.
   655  * @param sld The @SaveLoad description of the object so we know how to manipulate it
   653  * @param sld The SaveLoad description of the object so we know how to manipulate it
   656  */
   654  */
   657 static size_t SlCalcObjLength(const void *object, const SaveLoad *sld)
   655 static size_t SlCalcObjLength(const void *object, const SaveLoad *sld)
   658 {
   656 {
   659 	size_t length = 0;
   657 	size_t length = 0;
   660 
   658 
   661 	// Need to determine the length and write a length tag.
   659 	/* Need to determine the length and write a length tag. */
   662 	for (; sld->cmd != SL_END; sld++) {
   660 	for (; sld->cmd != SL_END; sld++) {
   663 		length += SlCalcObjMemberLength(object, sld);
   661 		length += SlCalcObjMemberLength(object, sld);
   664 	}
   662 	}
   665 	return length;
   663 	return length;
   666 }
   664 }
   709 		if (!SlIsObjectValidInSavegame(sld)) return false;
   707 		if (!SlIsObjectValidInSavegame(sld)) return false;
   710 		if (SlSkipVariableOnLoad(sld)) return false;
   708 		if (SlSkipVariableOnLoad(sld)) return false;
   711 
   709 
   712 		switch (sld->cmd) {
   710 		switch (sld->cmd) {
   713 		case SL_VAR: SlSaveLoadConv(ptr, conv); break;
   711 		case SL_VAR: SlSaveLoadConv(ptr, conv); break;
   714 		case SL_REF: /* Reference variable, translate */
   712 		case SL_REF: // Reference variable, translate
   715 			/// @todo XXX - another artificial limitof 65K elements of pointers?
   713 			/* @todo XXX - another artificial limitof 65K elements of pointers? */
   716 			if (_sl.save) { // XXX - read/write pointer as uint16? What is with higher indeces?
   714 			if (_sl.save) { // XXX - read/write pointer as uint16? What is with higher indeces?
   717 				SlWriteUint16(ReferenceToInt(*(void**)ptr, (SLRefType)conv));
   715 				SlWriteUint16(ReferenceToInt(*(void**)ptr, (SLRefType)conv));
   718 			} else {
   716 			} else {
   719 				*(void**)ptr = IntToReference(SlReadUint16(), (SLRefType)conv);
   717 				*(void**)ptr = IntToReference(SlReadUint16(), (SLRefType)conv);
   720 			}
   718 			}
   724 		default: NOT_REACHED();
   722 		default: NOT_REACHED();
   725 		}
   723 		}
   726 		break;
   724 		break;
   727 
   725 
   728 	/* SL_WRITEBYTE translates a value of a variable to another one upon
   726 	/* SL_WRITEBYTE translates a value of a variable to another one upon
   729    * saving or loading.
   727 	 * saving or loading.
   730    * XXX - variable renaming abuse
   728 	 * XXX - variable renaming abuse
   731    * game_value: the value of the variable ingame is abused by sld->version_from
   729 	 * game_value: the value of the variable ingame is abused by sld->version_from
   732    * file_value: the value of the variable in the savegame is abused by sld->version_to */
   730 	 * file_value: the value of the variable in the savegame is abused by sld->version_to */
   733 	case SL_WRITEBYTE:
   731 	case SL_WRITEBYTE:
   734 		if (_sl.save) {
   732 		if (_sl.save) {
   735 			SlWriteByte(sld->version_to);
   733 			SlWriteByte(sld->version_to);
   736 		} else {
   734 		} else {
   737 			*(byte*)ptr = sld->version_from;
   735 			*(byte*)ptr = sld->version_from;
   750 }
   748 }
   751 
   749 
   752 /**
   750 /**
   753  * Main SaveLoad function.
   751  * Main SaveLoad function.
   754  * @param object The object that is being saved or loaded
   752  * @param object The object that is being saved or loaded
   755  * @param sld The @SaveLoad description of the object so we know how to manipulate it
   753  * @param sld The SaveLoad description of the object so we know how to manipulate it
   756  */
   754  */
   757 void SlObject(void *object, const SaveLoad *sld)
   755 void SlObject(void *object, const SaveLoad *sld)
   758 {
   756 {
   759 	// Automatically calculate the length?
   757 	/* Automatically calculate the length? */
   760 	if (_sl.need_length != NL_NONE) {
   758 	if (_sl.need_length != NL_NONE) {
   761 		SlSetLength(SlCalcObjLength(object, sld));
   759 		SlSetLength(SlCalcObjLength(object, sld));
   762 		if (_sl.need_length == NL_CALCLENGTH) return;
   760 		if (_sl.need_length == NL_CALCLENGTH) return;
   763 	}
   761 	}
   764 
   762 
   793 {
   791 {
   794 	uint32 offs;
   792 	uint32 offs;
   795 
   793 
   796 	assert(_sl.save);
   794 	assert(_sl.save);
   797 
   795 
   798 	// Tell it to calculate the length
   796 	/* Tell it to calculate the length */
   799 	_sl.need_length = NL_CALCLENGTH;
   797 	_sl.need_length = NL_CALCLENGTH;
   800 	_sl.obj_len = 0;
   798 	_sl.obj_len = 0;
   801 	proc(arg);
   799 	proc(arg);
   802 
   800 
   803 	// Setup length
   801 	/* Setup length */
   804 	_sl.need_length = NL_WANTLENGTH;
   802 	_sl.need_length = NL_WANTLENGTH;
   805 	SlSetLength(_sl.obj_len);
   803 	SlSetLength(_sl.obj_len);
   806 
   804 
   807 	offs = SlGetOffs() + _sl.obj_len;
   805 	offs = SlGetOffs() + _sl.obj_len;
   808 
   806 
   809 	// And write the stuff
   807 	/* And write the stuff */
   810 	proc(arg);
   808 	proc(arg);
   811 
   809 
   812 	assert(offs == SlGetOffs());
   810 	assert(offs == SlGetOffs());
   813 }
   811 }
   814 
   812 
   833 	case CH_SPARSE_ARRAY:
   831 	case CH_SPARSE_ARRAY:
   834 		ch->load_proc();
   832 		ch->load_proc();
   835 		break;
   833 		break;
   836 	default:
   834 	default:
   837 		if ((m & 0xF) == CH_RIFF) {
   835 		if ((m & 0xF) == CH_RIFF) {
   838 			// Read length
   836 			/* Read length */
   839 			len = (SlReadByte() << 16) | ((m >> 4) << 24);
   837 			len = (SlReadByte() << 16) | ((m >> 4) << 24);
   840 			len += SlReadUint16();
   838 			len += SlReadUint16();
   841 			_sl.obj_len = len;
   839 			_sl.obj_len = len;
   842 			endoffs = SlGetOffs() + len;
   840 			endoffs = SlGetOffs() + len;
   843 			ch->load_proc();
   841 			ch->load_proc();
   864 
   862 
   865 	SlWriteUint32(ch->id);
   863 	SlWriteUint32(ch->id);
   866 	DEBUG(sl, 2, "Saving chunk %c%c%c%c", ch->id >> 24, ch->id >> 16, ch->id >> 8, ch->id);
   864 	DEBUG(sl, 2, "Saving chunk %c%c%c%c", ch->id >> 24, ch->id >> 16, ch->id >> 8, ch->id);
   867 
   865 
   868 	if (ch->flags & CH_AUTO_LENGTH) {
   866 	if (ch->flags & CH_AUTO_LENGTH) {
   869 		// Need to calculate the length. Solve that by calling SlAutoLength in the save_proc.
   867 		/* Need to calculate the length. Solve that by calling SlAutoLength in the save_proc. */
   870 		_tmp_proc_1 = proc;
   868 		_tmp_proc_1 = proc;
   871 		proc = SlStubSaveProc;
   869 		proc = SlStubSaveProc;
   872 	}
   870 	}
   873 
   871 
   874 	_sl.block_mode = ch->flags & CH_TYPE_MASK;
   872 	_sl.block_mode = ch->flags & CH_TYPE_MASK;
   909 				ch++;
   907 				ch++;
   910 			}
   908 			}
   911 		}
   909 		}
   912 	}
   910 	}
   913 
   911 
   914 	// Terminator
   912 	/* Terminator */
   915 	SlWriteUint32(0);
   913 	SlWriteUint32(0);
   916 }
   914 }
   917 
   915 
   918 /** Find the ChunkHandler that will be used for processing the found
   916 /** Find the ChunkHandler that will be used for processing the found
   919  * chunk in the savegame or in memory
   917  * chunk in the savegame or in memory
   947 		if (ch == NULL) SlError("found unknown tag in savegame (sync error)");
   945 		if (ch == NULL) SlError("found unknown tag in savegame (sync error)");
   948 		SlLoadChunk(ch);
   946 		SlLoadChunk(ch);
   949 	}
   947 	}
   950 }
   948 }
   951 
   949 
   952 //*******************************************
   950 /*******************************************
   953 //********** START OF LZO CODE **************
   951  ********** START OF LZO CODE **************
   954 //*******************************************
   952  *******************************************/
   955 #define LZO_SIZE 8192
   953 #define LZO_SIZE 8192
   956 
   954 
   957 #include "minilzo.h"
   955 #include "minilzo.h"
   958 
   956 
   959 static uint ReadLZO(void)
   957 static uint ReadLZO(void)
   961 	byte out[LZO_SIZE + LZO_SIZE / 64 + 16 + 3 + 8];
   959 	byte out[LZO_SIZE + LZO_SIZE / 64 + 16 + 3 + 8];
   962 	uint32 tmp[2];
   960 	uint32 tmp[2];
   963 	uint32 size;
   961 	uint32 size;
   964 	uint len;
   962 	uint len;
   965 
   963 
   966 	// Read header
   964 	/* Read header*/
   967 	if (fread(tmp, sizeof(tmp), 1, _sl.fh) != 1) SlError("file read failed");
   965 	if (fread(tmp, sizeof(tmp), 1, _sl.fh) != 1) SlError("file read failed");
   968 
   966 
   969 	// Check if size is bad
   967 	/* Check if size is bad */
   970 	((uint32*)out)[0] = size = tmp[1];
   968 	((uint32*)out)[0] = size = tmp[1];
   971 
   969 
   972 	if (_sl_version != 0) {
   970 	if (_sl_version != 0) {
   973 		tmp[0] = TO_BE32(tmp[0]);
   971 		tmp[0] = TO_BE32(tmp[0]);
   974 		size = TO_BE32(size);
   972 		size = TO_BE32(size);
   975 	}
   973 	}
   976 
   974 
   977 	if (size >= sizeof(out)) SlError("inconsistent size");
   975 	if (size >= sizeof(out)) SlError("inconsistent size");
   978 
   976 
   979 	// Read block
   977 	/* Read block */
   980 	if (fread(out + sizeof(uint32), size, 1, _sl.fh) != 1) SlError("file read failed");
   978 	if (fread(out + sizeof(uint32), size, 1, _sl.fh) != 1) SlError("file read failed");
   981 
   979 
   982 	// Verify checksum
   980 	/* Verify checksum */
   983 	if (tmp[0] != lzo_adler32(0, out, size + sizeof(uint32))) SlError("bad checksum");
   981 	if (tmp[0] != lzo_adler32(0, out, size + sizeof(uint32))) SlError("bad checksum");
   984 
   982 
   985 	// Decompress
   983 	/* Decompress */
   986 	lzo1x_decompress(out + sizeof(uint32)*1, size, _sl.buf, &len, NULL);
   984 	lzo1x_decompress(out + sizeof(uint32)*1, size, _sl.buf, &len, NULL);
   987 	return len;
   985 	return len;
   988 }
   986 }
   989 
   987 
   990 // p contains the pointer to the buffer, len contains the pointer to the length.
   988 /* p contains the pointer to the buffer, len contains the pointer to the length.
   991 // len bytes will be written, p and l will be updated to reflect the next buffer.
   989  * len bytes will be written, p and l will be updated to reflect the next buffer. */
   992 static void WriteLZO(uint size)
   990 static void WriteLZO(uint size)
   993 {
   991 {
   994 	byte out[LZO_SIZE + LZO_SIZE / 64 + 16 + 3 + 8];
   992 	byte out[LZO_SIZE + LZO_SIZE / 64 + 16 + 3 + 8];
   995 	byte wrkmem[sizeof(byte*)*4096];
   993 	byte wrkmem[sizeof(byte*)*4096];
   996 	uint outlen;
   994 	uint outlen;
  1011 static void UninitLZO(void)
  1009 static void UninitLZO(void)
  1012 {
  1010 {
  1013 	free(_sl.buf_ori);
  1011 	free(_sl.buf_ori);
  1014 }
  1012 }
  1015 
  1013 
  1016 //*********************************************
  1014 /*********************************************
  1017 //******** START OF NOCOMP CODE (uncompressed)*
  1015  ******** START OF NOCOMP CODE (uncompressed)*
  1018 //*********************************************
  1016  *********************************************/
  1019 static uint ReadNoComp(void)
  1017 static uint ReadNoComp(void)
  1020 {
  1018 {
  1021 	return fread(_sl.buf, 1, LZO_SIZE, _sl.fh);
  1019 	return fread(_sl.buf, 1, LZO_SIZE, _sl.fh);
  1022 }
  1020 }
  1023 
  1021 
  1036 static void UninitNoComp(void)
  1034 static void UninitNoComp(void)
  1037 {
  1035 {
  1038 	free(_sl.buf_ori);
  1036 	free(_sl.buf_ori);
  1039 }
  1037 }
  1040 
  1038 
  1041 //********************************************
  1039 /********************************************
  1042 //********** START OF MEMORY CODE (in ram)****
  1040  ********** START OF MEMORY CODE (in ram)****
  1043 //********************************************
  1041  ********************************************/
  1044 
  1042 
  1045 #include "table/strings.h"
  1043 #include "table/strings.h"
  1046 #include "table/sprites.h"
  1044 #include "table/sprites.h"
  1047 #include "gfx.h"
  1045 #include "gfx.h"
  1048 #include "gui.h"
  1046 #include "gui.h"
  1082 	/* Allocate new block and new buffer-pointer */
  1080 	/* Allocate new block and new buffer-pointer */
  1083 	AddBlockIfNeeded(&_Savegame_pool, _ts.count);
  1081 	AddBlockIfNeeded(&_Savegame_pool, _ts.count);
  1084 	_sl.buf = GetSavegame(_ts.count);
  1082 	_sl.buf = GetSavegame(_ts.count);
  1085 }
  1083 }
  1086 
  1084 
  1087 //********************************************
  1085 /********************************************
  1088 //********** START OF ZLIB CODE **************
  1086  ********** START OF ZLIB CODE **************
  1089 //********************************************
  1087  ********************************************/
  1090 
  1088 
  1091 #if defined(WITH_ZLIB)
  1089 #if defined(WITH_ZLIB)
  1092 #include <zlib.h>
  1090 #include <zlib.h>
  1093 
  1091 
  1094 static z_stream _z;
  1092 static z_stream _z;
  1109 
  1107 
  1110 	_z.next_out = _sl.buf;
  1108 	_z.next_out = _sl.buf;
  1111 	_z.avail_out = 4096;
  1109 	_z.avail_out = 4096;
  1112 
  1110 
  1113 	do {
  1111 	do {
  1114 		// read more bytes from the file?
  1112 		/* read more bytes from the file?*/
  1115 		if (_z.avail_in == 0) {
  1113 		if (_z.avail_in == 0) {
  1116 			_z.avail_in = fread(_z.next_in = _sl.buf + 4096, 1, 4096, _sl.fh);
  1114 			_z.avail_in = fread(_z.next_in = _sl.buf + 4096, 1, 4096, _sl.fh);
  1117 		}
  1115 		}
  1118 
  1116 
  1119 		// inflate the data
  1117 		/* inflate the data */
  1120 		r = inflate(&_z, 0);
  1118 		r = inflate(&_z, 0);
  1121 		if (r == Z_STREAM_END)
  1119 		if (r == Z_STREAM_END)
  1122 			break;
  1120 			break;
  1123 
  1121 
  1124 		if (r != Z_OK)
  1122 		if (r != Z_OK)
  1153 	z->avail_in = len;
  1151 	z->avail_in = len;
  1154 	do {
  1152 	do {
  1155 		z->next_out = buf;
  1153 		z->next_out = buf;
  1156 		z->avail_out = sizeof(buf);
  1154 		z->avail_out = sizeof(buf);
  1157 		r = deflate(z, mode);
  1155 		r = deflate(z, mode);
  1158 			// bytes were emitted?
  1156 			/* bytes were emitted? */
  1159 		if ((n=sizeof(buf) - z->avail_out) != 0) {
  1157 		if ((n=sizeof(buf) - z->avail_out) != 0) {
  1160 			if (fwrite(buf, n, 1, _sl.fh) != 1) SlError("file write error");
  1158 			if (fwrite(buf, n, 1, _sl.fh) != 1) SlError("file write error");
  1161 		}
  1159 		}
  1162 		if (r == Z_STREAM_END)
  1160 		if (r == Z_STREAM_END)
  1163 			break;
  1161 			break;
  1170 	WriteZlibLoop(&_z, _sl.buf, len, 0);
  1168 	WriteZlibLoop(&_z, _sl.buf, len, 0);
  1171 }
  1169 }
  1172 
  1170 
  1173 static void UninitWriteZlib(void)
  1171 static void UninitWriteZlib(void)
  1174 {
  1172 {
  1175 	// flush any pending output.
  1173 	/* flush any pending output. */
  1176 	if (_sl.fh) WriteZlibLoop(&_z, NULL, 0, Z_FINISH);
  1174 	if (_sl.fh) WriteZlibLoop(&_z, NULL, 0, Z_FINISH);
  1177 	deflateEnd(&_z);
  1175 	deflateEnd(&_z);
  1178 	free(_sl.buf_ori);
  1176 	free(_sl.buf_ori);
  1179 }
  1177 }
  1180 
  1178 
  1181 #endif /* WITH_ZLIB */
  1179 #endif /* WITH_ZLIB */
  1182 
  1180 
  1183 //*******************************************
  1181 /*******************************************
  1184 //************* END OF CODE *****************
  1182  ************* END OF CODE *****************
  1185 //*******************************************
  1183  *******************************************/
  1186 
  1184 
  1187 // these define the chunks
  1185 /* these define the chunks */
  1188 extern const ChunkHandler _misc_chunk_handlers[];
  1186 extern const ChunkHandler _misc_chunk_handlers[];
  1189 extern const ChunkHandler _setting_chunk_handlers[];
  1187 extern const ChunkHandler _setting_chunk_handlers[];
  1190 extern const ChunkHandler _player_chunk_handlers[];
  1188 extern const ChunkHandler _player_chunk_handlers[];
  1191 extern const ChunkHandler _engine_chunk_handlers[];
  1189 extern const ChunkHandler _engine_chunk_handlers[];
  1192 extern const ChunkHandler _veh_chunk_handlers[];
  1190 extern const ChunkHandler _veh_chunk_handlers[];
  1218 	_animated_tile_chunk_handlers,
  1216 	_animated_tile_chunk_handlers,
  1219 	_newgrf_chunk_handlers,
  1217 	_newgrf_chunk_handlers,
  1220 	NULL,
  1218 	NULL,
  1221 };
  1219 };
  1222 
  1220 
  1223 // used to include a vehicle desc in another desc.
  1221 /* used to include a vehicle desc in another desc. */s
  1224 extern const SaveLoad _common_veh_desc[];
  1222 extern const SaveLoad _common_veh_desc[];
  1225 static const SaveLoad* const _desc_includes[] = {
  1223 static const SaveLoad* const _desc_includes[] = {
  1226 	_common_veh_desc
  1224 	_common_veh_desc
  1227 };
  1225 };
  1228 
  1226 
  1231  * the index of the item, and if not available, it hussles with
  1229  * the index of the item, and if not available, it hussles with
  1232  * pointers (looks really bad :()
  1230  * pointers (looks really bad :()
  1233  * Remember that a NULL item has value 0, and all
  1231  * Remember that a NULL item has value 0, and all
  1234  * indeces have +1, so vehicle 0 is saved as index 1.
  1232  * indeces have +1, so vehicle 0 is saved as index 1.
  1235  * @param obj The object that we want to get the index of
  1233  * @param obj The object that we want to get the index of
  1236  * @param rt @SLRefType type of the object the index is being sought of
  1234  * @param rt SLRefType type of the object the index is being sought of
  1237  * @return Return the pointer converted to an index of the type pointed to
  1235  * @return Return the pointer converted to an index of the type pointed to
  1238  */
  1236  */
  1239 static uint ReferenceToInt(const void *obj, SLRefType rt)
  1237 static uint ReferenceToInt(const void *obj, SLRefType rt)
  1240 {
  1238 {
  1241 	if (obj == NULL) return 0;
  1239 	if (obj == NULL) return 0;
  1259  * gets the index from the savegame and returns the appropiate
  1257  * gets the index from the savegame and returns the appropiate
  1260  * pointer from the already loaded base.
  1258  * pointer from the already loaded base.
  1261  * Remember that an index of 0 is a NULL pointer so all indeces
  1259  * Remember that an index of 0 is a NULL pointer so all indeces
  1262  * are +1 so vehicle 0 is saved as 1.
  1260  * are +1 so vehicle 0 is saved as 1.
  1263  * @param index The index that is being converted to a pointer
  1261  * @param index The index that is being converted to a pointer
  1264  * @param rt @SLRefType type of the object the pointer is sought of
  1262  * @param rt SLRefType type of the object the pointer is sought of
  1265  * @return Return the index converted to a pointer of any type
  1263  * @return Return the index converted to a pointer of any type
  1266  */
  1264  */
  1267 static void *IntToReference(uint index, SLRefType rt)
  1265 static void *IntToReference(uint index, SLRefType rt)
  1268 {
  1266 {
  1269 	/* After version 4.3 REF_VEHICLE_OLD is saved as REF_VEHICLE,
  1267 	/* After version 4.3 REF_VEHICLE_OLD is saved as REF_VEHICLE,
  1327 	return NULL;
  1325 	return NULL;
  1328 }
  1326 }
  1329 
  1327 
  1330 /** The format for a reader/writer type of a savegame */
  1328 /** The format for a reader/writer type of a savegame */
  1331 typedef struct {
  1329 typedef struct {
  1332 	const char *name;           /// name of the compressor/decompressor (debug-only)
  1330 	const char *name;           ///< name of the compressor/decompressor (debug-only)
  1333 	uint32 tag;                 /// the 4-letter tag by which it is identified in the savegame
  1331 	uint32 tag;                 ///< the 4-letter tag by which it is identified in the savegame
  1334 
  1332 
  1335 	bool (*init_read)(void);    /// function executed upon initalization of the loader
  1333 	bool (*init_read)(void);    ///< function executed upon initalization of the loader
  1336 	ReaderProc *reader;         /// function that loads the data from the file
  1334 	ReaderProc *reader;         ///< function that loads the data from the file
  1337 	void (*uninit_read)(void);  /// function executed when reading is finished
  1335 	void (*uninit_read)(void);  ///< function executed when reading is finished
  1338 
  1336 
  1339 	bool (*init_write)(void);   /// function executed upon intialization of the saver
  1337 	bool (*init_write)(void);   ///< function executed upon intialization of the saver
  1340 	WriterProc *writer;         /// function that saves the data to the file
  1338 	WriterProc *writer;         ///< function that saves the data to the file
  1341 	void (*uninit_write)(void); /// function executed when writing is done
  1339 	void (*uninit_write)(void); ///< function executed when writing is done
  1342 } SaveLoadFormat;
  1340 } SaveLoadFormat;
  1343 
  1341 
  1344 static const SaveLoadFormat _saveload_formats[] = {
  1342 static const SaveLoadFormat _saveload_formats[] = {
  1345 	{"memory", 0,                NULL,         NULL,       NULL,           InitMem,       WriteMem,    UnInitMem},
  1343 	{"memory", 0,                NULL,         NULL,       NULL,           InitMem,       WriteMem,    UnInitMem},
  1346 	{"lzo",    TO_BE32X('OTTD'), InitLZO,      ReadLZO,    UninitLZO,      InitLZO,       WriteLZO,    UninitLZO},
  1344 	{"lzo",    TO_BE32X('OTTD'), InitLZO,      ReadLZO,    UninitLZO,      InitLZO,       WriteLZO,    UninitLZO},
  1354 
  1352 
  1355 /**
  1353 /**
  1356  * Return the savegameformat of the game. Whether it was create with ZLIB compression
  1354  * Return the savegameformat of the game. Whether it was create with ZLIB compression
  1357  * uncompressed, or another type
  1355  * uncompressed, or another type
  1358  * @param s Name of the savegame format. If NULL it picks the first available one
  1356  * @param s Name of the savegame format. If NULL it picks the first available one
  1359  * @return Pointer to @SaveLoadFormat struct giving all characteristics of this type of savegame
  1357  * @return Pointer to SaveLoadFormat struct giving all characteristics of this type of savegame
  1360  */
  1358  */
  1361 static const SaveLoadFormat *GetSavegameFormat(const char *s)
  1359 static const SaveLoadFormat *GetSavegameFormat(const char *s)
  1362 {
  1360 {
  1363 	const SaveLoadFormat *def = endof(_saveload_formats) - 1;
  1361 	const SaveLoadFormat *def = endof(_saveload_formats) - 1;
  1364 
  1362 
  1365 	// find default savegame format, the highest one with which files can be written
  1363 	/* find default savegame format, the highest one with which files can be written */
  1366 	while (!def->init_write) def--;
  1364 	while (!def->init_write) def--;
  1367 
  1365 
  1368 	if (s != NULL && s[0] != '\0') {
  1366 	if (s != NULL && s[0] != '\0') {
  1369 		const SaveLoadFormat *slf;
  1367 		const SaveLoadFormat *slf;
  1370 		for (slf = &_saveload_formats[0]; slf != endof(_saveload_formats); slf++) {
  1368 		for (slf = &_saveload_formats[0]; slf != endof(_saveload_formats); slf++) {
  1375 		ShowInfoF("Savegame format '%s' is not available. Reverting to '%s'.", s, def->name);
  1373 		ShowInfoF("Savegame format '%s' is not available. Reverting to '%s'.", s, def->name);
  1376 	}
  1374 	}
  1377 	return def;
  1375 	return def;
  1378 }
  1376 }
  1379 
  1377 
  1380 // actual loader/saver function
  1378 /* actual loader/saver function */
  1381 void InitializeGame(int mode, uint size_x, uint size_y);
  1379 void InitializeGame(int mode, uint size_x, uint size_y);
  1382 extern bool AfterLoadGame(void);
  1380 extern bool AfterLoadGame(void);
  1383 extern void BeforeSaveGame(void);
  1381 extern void BeforeSaveGame(void);
  1384 extern bool LoadOldSaveGame(const char *file);
  1382 extern bool LoadOldSaveGame(const char *file);
  1385 
  1383 
  1507 	uint32 hdr[2];
  1505 	uint32 hdr[2];
  1508 	const SaveLoadFormat *fmt;
  1506 	const SaveLoadFormat *fmt;
  1509 
  1507 
  1510 	/* An instance of saving is already active, so don't go saving again */
  1508 	/* An instance of saving is already active, so don't go saving again */
  1511 	if (_ts.saveinprogress && mode == SL_SAVE) {
  1509 	if (_ts.saveinprogress && mode == SL_SAVE) {
  1512 		// if not an autosave, but a user action, show error message
  1510 		/* if not an autosave, but a user action, show error message */
  1513 		if (!_do_autosave) ShowErrorMessage(INVALID_STRING_ID, STR_SAVE_STILL_IN_PROGRESS, 0, 0);
  1511 		if (!_do_autosave) ShowErrorMessage(INVALID_STRING_ID, STR_SAVE_STILL_IN_PROGRESS, 0, 0);
  1514 		return SL_OK;
  1512 		return SL_OK;
  1515 	}
  1513 	}
  1516 	WaitTillSaved();
  1514 	WaitTillSaved();
  1517 
  1515 
  1539 	/* XXX - Setup setjmp error handler if an error occurs anywhere deep during
  1537 	/* XXX - Setup setjmp error handler if an error occurs anywhere deep during
  1540 	 * loading/saving execute a longjmp() and continue execution here */
  1538 	 * loading/saving execute a longjmp() and continue execution here */
  1541 	if (setjmp(_sl.excpt)) {
  1539 	if (setjmp(_sl.excpt)) {
  1542 		AbortSaveLoad();
  1540 		AbortSaveLoad();
  1543 
  1541 
  1544 		// deinitialize compressor.
  1542 		/* deinitialize compressor. */
  1545 		_sl.excpt_uninit();
  1543 		_sl.excpt_uninit();
  1546 
  1544 
  1547 		/* A saver/loader exception!! reinitialize all variables to prevent crash! */
  1545 		/* A saver/loader exception!! reinitialize all variables to prevent crash! */
  1548 		if (mode == SL_LOAD) {
  1546 		if (mode == SL_LOAD) {
  1549 			ShowInfoF("Load game failed: %s.", _sl.excpt_msg);
  1547 			ShowInfoF("Load game failed: %s.", _sl.excpt_msg);
  1588 		if (fread(hdr, sizeof(hdr), 1, _sl.fh) != 1) {
  1586 		if (fread(hdr, sizeof(hdr), 1, _sl.fh) != 1) {
  1589 			DEBUG(sl, 0, "Cannot read savegame header, aborting");
  1587 			DEBUG(sl, 0, "Cannot read savegame header, aborting");
  1590 			return AbortSaveLoad();
  1588 			return AbortSaveLoad();
  1591 		}
  1589 		}
  1592 
  1590 
  1593 		// see if we have any loader for this type.
  1591 		/* see if we have any loader for this type. */
  1594 		for (fmt = _saveload_formats; ; fmt++) {
  1592 		for (fmt = _saveload_formats; ; fmt++) {
  1595 			/* No loader found, treat as version 0 and use LZO format */
  1593 			/* No loader found, treat as version 0 and use LZO format */
  1596 			if (fmt == endof(_saveload_formats)) {
  1594 			if (fmt == endof(_saveload_formats)) {
  1597 				DEBUG(sl, 0, "Unknown savegame type, trying to load it as the buggy format");
  1595 				DEBUG(sl, 0, "Unknown savegame type, trying to load it as the buggy format");
  1598 #if defined(WINCE)
  1596 #if defined(WINCE)
  1607 				fmt = _saveload_formats + 1; // LZO
  1605 				fmt = _saveload_formats + 1; // LZO
  1608 				break;
  1606 				break;
  1609 			}
  1607 			}
  1610 
  1608 
  1611 			if (fmt->tag == hdr[0]) {
  1609 			if (fmt->tag == hdr[0]) {
  1612 				// check version number
  1610 				/* check version number */
  1613 				_sl_version = TO_BE32(hdr[1]) >> 16;
  1611 				_sl_version = TO_BE32(hdr[1]) >> 16;
  1614 				/* Minor is not used anymore from version 18.0, but it is still needed
  1612 				/* Minor is not used anymore from version 18.0, but it is still needed
  1615 				 *  in versions before that (4 cases) which can't be removed easy.
  1613 				 * in versions before that (4 cases) which can't be removed easy.
  1616 				 *  Therefor it is loaded, but never saved (or, it saves a 0 in any scenario).
  1614 				 * Therefor it is loaded, but never saved (or, it saves a 0 in any scenario).
  1617 				 *  So never EVER use this minor version again. -- TrueLight -- 22-11-2005 */
  1615 				 * So never EVER use this minor version again. -- TrueLight -- 22-11-2005 */
  1618 				_sl_minor_version = (TO_BE32(hdr[1]) >> 8) & 0xFF;
  1616 				_sl_minor_version = (TO_BE32(hdr[1]) >> 8) & 0xFF;
  1619 
  1617 
  1620 				DEBUG(sl, 1, "Loading savegame version %d", _sl_version);
  1618 				DEBUG(sl, 1, "Loading savegame version %d", _sl_version);
  1621 
  1619 
  1622 				/* Is the version higher than the current? */
  1620 				/* Is the version higher than the current? */
  1629 		}
  1627 		}
  1630 
  1628 
  1631 		_sl.read_bytes = fmt->reader;
  1629 		_sl.read_bytes = fmt->reader;
  1632 		_sl.excpt_uninit = fmt->uninit_read;
  1630 		_sl.excpt_uninit = fmt->uninit_read;
  1633 
  1631 
  1634 		// loader for this savegame type is not implemented?
  1632 		/* loader for this savegame type is not implemented? */
  1635 		if (fmt->init_read == NULL) {
  1633 		if (fmt->init_read == NULL) {
  1636 			ShowInfoF("Loader for '%s' is not available.", fmt->name);
  1634 			ShowInfoF("Loader for '%s' is not available.", fmt->name);
  1637 			return AbortSaveLoad();
  1635 			return AbortSaveLoad();
  1638 		}
  1636 		}
  1639 
  1637 
  1684 	f = fopen(file, "rb");
  1682 	f = fopen(file, "rb");
  1685 	if (fread(&hdr, sizeof(hdr), 1, f) != 1) {
  1683 	if (fread(&hdr, sizeof(hdr), 1, f) != 1) {
  1686 		DEBUG(sl, 0, "Savegame is obsolete or invalid format");
  1684 		DEBUG(sl, 0, "Savegame is obsolete or invalid format");
  1687 		mode = SL_LOAD; // don't try to get filename, just show name as it is written
  1685 		mode = SL_LOAD; // don't try to get filename, just show name as it is written
  1688 	} else {
  1686 	} else {
  1689 		// see if we have any loader for this type.
  1687 		/* see if we have any loader for this type. */
  1690 		for (fmt = _saveload_formats; fmt != endof(_saveload_formats); fmt++) {
  1688 		for (fmt = _saveload_formats; fmt != endof(_saveload_formats); fmt++) {
  1691 			if (fmt->tag == hdr) {
  1689 			if (fmt->tag == hdr) {
  1692 				mode = SL_LOAD; // new type of savegame
  1690 				mode = SL_LOAD; // new type of savegame
  1693 				break;
  1691 				break;
  1694 			}
  1692 			}