src/saveload.cpp
branchcpp_gui
changeset 6308 646711c5feaa
parent 6307 f40e88cff863
equal deleted inserted replaced
6307:f40e88cff863 6308:646711c5feaa
    25 #include "player.h"
    25 #include "player.h"
    26 #include "saveload.h"
    26 #include "saveload.h"
    27 #include "network/network.h"
    27 #include "network/network.h"
    28 #include "variables.h"
    28 #include "variables.h"
    29 #include <setjmp.h>
    29 #include <setjmp.h>
    30 
    30 #include <list>
    31 extern const uint16 SAVEGAME_VERSION = 54;
    31 
       
    32 extern const uint16 SAVEGAME_VERSION = 57;
    32 uint16 _sl_version;       ///< the major savegame version identifier
    33 uint16 _sl_version;       ///< the major savegame version identifier
    33 byte   _sl_minor_version; ///< the minor savegame version, DO NOT USE!
    34 byte   _sl_minor_version; ///< the minor savegame version, DO NOT USE!
    34 
    35 
    35 typedef void WriterProc(uint len);
    36 typedef void WriterProc(uint len);
    36 typedef uint ReaderProc();
    37 typedef uint ReaderProc();
   249 {
   250 {
   250 	if (i >= (1 << 7)) {
   251 	if (i >= (1 << 7)) {
   251 		if (i >= (1 << 14)) {
   252 		if (i >= (1 << 14)) {
   252 			if (i >= (1 << 21)) {
   253 			if (i >= (1 << 21)) {
   253 				assert(i < (1 << 28));
   254 				assert(i < (1 << 28));
   254 				SlWriteByte((byte)0xE0 | (i>>24));
   255 				SlWriteByte((byte)0xE0 | (i >> 24));
   255 				SlWriteByte((byte)(i>>16));
   256 				SlWriteByte((byte)(i >> 16));
   256 			} else {
   257 			} else {
   257 				SlWriteByte((byte)0xC0 | (i>>16));
   258 				SlWriteByte((byte)0xC0 | (i >> 16));
   258 			}
   259 			}
   259 			SlWriteByte((byte)(i>>8));
   260 			SlWriteByte((byte)(i >> 8));
   260 		} else {
   261 		} else {
   261 			SlWriteByte((byte)(0x80 | (i>>8)));
   262 			SlWriteByte((byte)(0x80 | (i >> 8)));
   262 		}
   263 		}
   263 	}
   264 	}
   264 	SlWriteByte(i);
   265 	SlWriteByte(i);
   265 }
   266 }
   266 
   267 
   625 			a += mem_size; // get size
   626 			a += mem_size; // get size
   626 		}
   627 		}
   627 	}
   628 	}
   628 }
   629 }
   629 
   630 
       
   631 
       
   632 static uint ReferenceToInt(const void* obj, SLRefType rt);
       
   633 static void* IntToReference(uint index, SLRefType rt);
       
   634 
       
   635 
       
   636 /**
       
   637  * Return the size in bytes of a list
       
   638  * @param list The std::list to find the size of
       
   639  */
       
   640 static inline size_t SlCalcListLen(const void *list)
       
   641 {
       
   642 	std::list<void *> *l = (std::list<void *> *) list;
       
   643 
       
   644 	/* Each entry is saved as 2 bytes, plus 2 bytes are used for the length
       
   645 	 * of the list */
       
   646 	return l->size() * 2 + 2;
       
   647 }
       
   648 
       
   649 
       
   650 /**
       
   651  * Save/Load a list.
       
   652  * @param list The list being manipulated
       
   653  * @param conv SLRefType type of the list (Vehicle *, Station *, etc)
       
   654  */
       
   655 void SlList(void *list, SLRefType conv)
       
   656 {
       
   657 	/* Automatically calculate the length? */
       
   658 	if (_sl.need_length != NL_NONE) {
       
   659 		SlSetLength(SlCalcListLen(list));
       
   660 		/* Determine length only? */
       
   661 		if (_sl.need_length == NL_CALCLENGTH) return;
       
   662 	}
       
   663 
       
   664 	std::list<void *> *l = (std::list<void *> *) list;
       
   665 
       
   666 	if (_sl.save) {
       
   667 		SlWriteUint16(l->size());
       
   668 
       
   669 		std::list<void *>::iterator iter;
       
   670 		for (iter = l->begin(); iter != l->end(); ++iter) {
       
   671 			void *ptr = *iter;
       
   672 			SlWriteUint16(ReferenceToInt(ptr, conv));
       
   673 		}
       
   674 	} else {
       
   675 		uint length = SlReadUint16();
       
   676 
       
   677 		/* Load each reference and push to the end of the list */
       
   678 		for (uint i = 0; i < length; i++) {
       
   679 			void *ptr = IntToReference(SlReadUint16(), conv);
       
   680 			l->push_back(ptr);
       
   681 		}
       
   682 	}
       
   683 }
       
   684 
       
   685 
   630 /** Are we going to save this object or not? */
   686 /** Are we going to save this object or not? */
   631 static inline bool SlIsObjectValidInSavegame(const SaveLoad *sld)
   687 static inline bool SlIsObjectValidInSavegame(const SaveLoad *sld)
   632 {
   688 {
   633 	if (_sl_version < sld->version_from || _sl_version > sld->version_to) return false;
   689 	if (_sl_version < sld->version_from || _sl_version > sld->version_to) return false;
   634 	if (sld->conv & SLF_SAVE_NO) return false;
   690 	if (sld->conv & SLF_SAVE_NO) return false;
   673 	switch (sld->cmd) {
   729 	switch (sld->cmd) {
   674 		case SL_VAR:
   730 		case SL_VAR:
   675 		case SL_REF:
   731 		case SL_REF:
   676 		case SL_ARR:
   732 		case SL_ARR:
   677 		case SL_STR:
   733 		case SL_STR:
       
   734 		case SL_LST:
   678 			/* CONDITIONAL saveload types depend on the savegame version */
   735 			/* CONDITIONAL saveload types depend on the savegame version */
   679 			if (!SlIsObjectValidInSavegame(sld)) break;
   736 			if (!SlIsObjectValidInSavegame(sld)) break;
   680 
   737 
   681 			switch (sld->cmd) {
   738 			switch (sld->cmd) {
   682 			case SL_VAR: return SlCalcConvFileLen(sld->conv);
   739 			case SL_VAR: return SlCalcConvFileLen(sld->conv);
   683 			case SL_REF: return SlCalcRefLen();
   740 			case SL_REF: return SlCalcRefLen();
   684 			case SL_ARR: return SlCalcArrayLen(sld->length, sld->conv);
   741 			case SL_ARR: return SlCalcArrayLen(sld->length, sld->conv);
   685 			case SL_STR: return SlCalcStringLen(GetVariableAddress(object, sld), sld->length, sld->conv);
   742 			case SL_STR: return SlCalcStringLen(GetVariableAddress(object, sld), sld->length, sld->conv);
       
   743 			case SL_LST: return SlCalcListLen(GetVariableAddress(object, sld));
   686 			default: NOT_REACHED();
   744 			default: NOT_REACHED();
   687 			}
   745 			}
   688 			break;
   746 			break;
   689 		case SL_WRITEBYTE: return 1; // a byte is logically of size 1
   747 		case SL_WRITEBYTE: return 1; // a byte is logically of size 1
   690 		case SL_INCLUDE: return SlCalcObjLength(object, _sl.includes[sld->version_from]);
   748 		case SL_INCLUDE: return SlCalcObjLength(object, _sl.includes[sld->version_from]);
   692 	}
   750 	}
   693 	return 0;
   751 	return 0;
   694 }
   752 }
   695 
   753 
   696 
   754 
   697 static uint ReferenceToInt(const void* obj, SLRefType rt);
       
   698 static void* IntToReference(uint index, SLRefType rt);
       
   699 
       
   700 
       
   701 bool SlObjectMember(void *ptr, const SaveLoad *sld)
   755 bool SlObjectMember(void *ptr, const SaveLoad *sld)
   702 {
   756 {
   703 	VarType conv = GB(sld->conv, 0, 8);
   757 	VarType conv = GB(sld->conv, 0, 8);
   704 	switch (sld->cmd) {
   758 	switch (sld->cmd) {
   705 	case SL_VAR:
   759 	case SL_VAR:
   706 	case SL_REF:
   760 	case SL_REF:
   707 	case SL_ARR:
   761 	case SL_ARR:
   708 	case SL_STR:
   762 	case SL_STR:
       
   763 	case SL_LST:
   709 		/* CONDITIONAL saveload types depend on the savegame version */
   764 		/* CONDITIONAL saveload types depend on the savegame version */
   710 		if (!SlIsObjectValidInSavegame(sld)) return false;
   765 		if (!SlIsObjectValidInSavegame(sld)) return false;
   711 		if (SlSkipVariableOnLoad(sld)) return false;
   766 		if (SlSkipVariableOnLoad(sld)) return false;
   712 
   767 
   713 		switch (sld->cmd) {
   768 		switch (sld->cmd) {
   720 				*(void**)ptr = IntToReference(SlReadUint16(), (SLRefType)conv);
   775 				*(void**)ptr = IntToReference(SlReadUint16(), (SLRefType)conv);
   721 			}
   776 			}
   722 			break;
   777 			break;
   723 		case SL_ARR: SlArray(ptr, sld->length, conv); break;
   778 		case SL_ARR: SlArray(ptr, sld->length, conv); break;
   724 		case SL_STR: SlString(ptr, sld->length, conv); break;
   779 		case SL_STR: SlString(ptr, sld->length, conv); break;
       
   780 		case SL_LST: SlList(ptr, (SLRefType)conv); break;
   725 		default: NOT_REACHED();
   781 		default: NOT_REACHED();
   726 		}
   782 		}
   727 		break;
   783 		break;
   728 
   784 
   729 	/* SL_WRITEBYTE translates a value of a variable to another one upon
   785 	/* SL_WRITEBYTE translates a value of a variable to another one upon
   923  */
   979  */
   924 static const ChunkHandler *SlFindChunkHandler(uint32 id)
   980 static const ChunkHandler *SlFindChunkHandler(uint32 id)
   925 {
   981 {
   926 	const ChunkHandler *ch;
   982 	const ChunkHandler *ch;
   927 	const ChunkHandler *const *chsc;
   983 	const ChunkHandler *const *chsc;
   928 	for (chsc = _sl.chs; (ch=*chsc++) != NULL;) {
   984 	for (chsc = _sl.chs; (ch = *chsc++) != NULL;) {
   929 		for (;;) {
   985 		for (;;) {
   930 			if (ch->id == id) return ch;
   986 			if (ch->id == id) return ch;
   931 			if (ch->flags & CH_LAST) break;
   987 			if (ch->flags & CH_LAST) break;
   932 			ch++;
   988 			ch++;
   933 		}
   989 		}
  1028 }
  1084 }
  1029 
  1085 
  1030 static bool InitNoComp()
  1086 static bool InitNoComp()
  1031 {
  1087 {
  1032 	_sl.bufsize = LZO_SIZE;
  1088 	_sl.bufsize = LZO_SIZE;
  1033 	_sl.buf = _sl.buf_ori =(byte*)malloc(LZO_SIZE);
  1089 	_sl.buf = _sl.buf_ori = (byte*)malloc(LZO_SIZE);
  1034 	return true;
  1090 	return true;
  1035 }
  1091 }
  1036 
  1092 
  1037 static void UninitNoComp()
  1093 static void UninitNoComp()
  1038 {
  1094 {