saveload.c
changeset 1093 4fdc46eaf423
parent 1024 5e446b5b3ec5
child 1094 9a01482df45a
equal deleted inserted replaced
1092:e3b4a131db7c 1093:4fdc46eaf423
    20 enum NeedLengthValues { NL_NONE = 0,NL_WANTLENGTH = 1,NL_CALCLENGTH = 2};
    20 enum NeedLengthValues { NL_NONE = 0,NL_WANTLENGTH = 1,NL_CALCLENGTH = 2};
    21 
    21 
    22 SaverLoader _sl;
    22 SaverLoader _sl;
    23 
    23 
    24 // fill the input buffer
    24 // fill the input buffer
    25 static void SlReadFill()
    25 static void SlReadFill(void)
    26 {
    26 {
    27 	uint len = _sl.read_bytes();
    27 	uint len = _sl.read_bytes();
    28 	assert(len != 0);
    28 	assert(len != 0);
    29 
    29 
    30 	_sl.bufp = _sl.buf;
    30 	_sl.bufp = _sl.buf;
    31 	_sl.bufe = _sl.buf + len;
    31 	_sl.bufe = _sl.buf + len;
    32 	_sl.offs_base += len;
    32 	_sl.offs_base += len;
    33 }
    33 }
    34 
    34 
    35 static uint32 SlGetOffs()
    35 static uint32 SlGetOffs(void)
    36 {
    36 {
    37 	return _sl.offs_base - (_sl.bufe - _sl.bufp);
    37 	return _sl.offs_base - (_sl.bufe - _sl.bufp);
    38 }
    38 }
    39 
    39 
    40 // flush the output buffer
    40 // flush the output buffer
    41 static void SlWriteFill()
    41 static void SlWriteFill(void)
    42 {
    42 {
    43 	// flush current buffer?
    43 	// flush current buffer?
    44 	if (_sl.bufp != NULL) {
    44 	if (_sl.bufp != NULL) {
    45 		uint len = _sl.bufp - _sl.buf;
    45 		uint len = _sl.bufp - _sl.buf;
    46 		_sl.offs_base += len;
    46 		_sl.offs_base += len;
    57 {
    57 {
    58 	_sl.excpt_msg = msg;
    58 	_sl.excpt_msg = msg;
    59 	longjmp(_sl.excpt, 0);
    59 	longjmp(_sl.excpt, 0);
    60 }
    60 }
    61 
    61 
    62 int SlReadByte()
    62 int SlReadByte(void)
    63 {
    63 {
    64 	if (_sl.bufp == _sl.bufe) SlReadFill();
    64 	if (_sl.bufp == _sl.bufe) SlReadFill();
    65 	return *_sl.bufp++;
    65 	return *_sl.bufp++;
    66 }
    66 }
    67 
    67 
    69 {
    69 {
    70 	if (_sl.bufp == _sl.bufe) SlWriteFill();
    70 	if (_sl.bufp == _sl.bufe) SlWriteFill();
    71 	*_sl.bufp++ = v;
    71 	*_sl.bufp++ = v;
    72 }
    72 }
    73 
    73 
    74 static int SlReadUint16()
    74 static int SlReadUint16(void)
    75 {
    75 {
    76 	int x = SlReadByte() << 8;
    76 	int x = SlReadByte() << 8;
    77 	return x | SlReadByte();
    77 	return x | SlReadByte();
    78 }
    78 }
    79 
    79 
    80 static uint32 SlReadUint32()
    80 static uint32 SlReadUint32(void)
    81 {
    81 {
    82 	uint32 x = SlReadUint16() << 16;
    82 	uint32 x = SlReadUint16() << 16;
    83 	return x | SlReadUint16();
    83 	return x | SlReadUint16();
    84 }
    84 }
    85 
    85 
    86 static uint64 SlReadUint64()
    86 static uint64 SlReadUint64(void)
    87 {
    87 {
    88 	uint32 x = SlReadUint32();
    88 	uint32 x = SlReadUint32();
    89 	uint32 y = SlReadUint32();
    89 	uint32 y = SlReadUint32();
    90 	return (uint64)x << 32 | y;
    90 	return (uint64)x << 32 | y;
    91 }
    91 }
   106 {
   106 {
   107 	SlWriteUint32((uint32)(x >> 32));
   107 	SlWriteUint32((uint32)(x >> 32));
   108 	SlWriteUint32((uint32)x);
   108 	SlWriteUint32((uint32)x);
   109 }
   109 }
   110 
   110 
   111 static int SlReadSimpleGamma()
   111 static int SlReadSimpleGamma(void)
   112 {
   112 {
   113 	int x = SlReadByte();
   113 	int x = SlReadByte();
   114 	if (x & 0x80)
   114 	if (x & 0x80)
   115 		x = ((x&0x7F) << 8) + SlReadByte();
   115 		x = ((x&0x7F) << 8) + SlReadByte();
   116 	return x;
   116 	return x;
   129 
   129 
   130 static uint SlGetGammaLength(uint i) {
   130 static uint SlGetGammaLength(uint i) {
   131 	return (i>=0x80) ? 2 : 1;
   131 	return (i>=0x80) ? 2 : 1;
   132 }
   132 }
   133 
   133 
   134 inline int SlReadSparseIndex()
   134 inline int SlReadSparseIndex(void)
   135 {
   135 {
   136 	return SlReadSimpleGamma();
   136 	return SlReadSimpleGamma();
   137 }
   137 }
   138 
   138 
   139 inline void SlWriteSparseIndex(uint index)
   139 inline void SlWriteSparseIndex(uint index)
   140 {
   140 {
   141 	SlWriteSimpleGamma(index);
   141 	SlWriteSimpleGamma(index);
   142 }
   142 }
   143 
   143 
   144 inline int SlReadArrayLength()
   144 inline int SlReadArrayLength(void)
   145 {
   145 {
   146 	return SlReadSimpleGamma();
   146 	return SlReadSimpleGamma();
   147 }
   147 }
   148 
   148 
   149 inline void SlWriteArrayLength(uint length)
   149 inline void SlWriteArrayLength(uint length)
   155 {
   155 {
   156 	_sl.need_length = NL_WANTLENGTH;
   156 	_sl.need_length = NL_WANTLENGTH;
   157 	_sl.array_index = index;
   157 	_sl.array_index = index;
   158 }
   158 }
   159 
   159 
   160 int SlIterateArray()
   160 int SlIterateArray(void)
   161 {
   161 {
   162 	int ind;
   162 	int ind;
   163 	static uint32 next_offs;
   163 	static uint32 next_offs;
   164 
   164 
   165 	// Must be at end of current block.
   165 	// Must be at end of current block.
   247 		SlReadByte();
   247 		SlReadByte();
   248 		length--;
   248 		length--;
   249 	}
   249 	}
   250 }
   250 }
   251 
   251 
   252 uint SlGetFieldLength()
   252 uint SlGetFieldLength(void)
   253 {
   253 {
   254 	return _sl.obj_len;
   254 	return _sl.obj_len;
   255 }
   255 }
   256 
   256 
   257 
   257 
   581 static void SlStubSaveProc2(void *arg)
   581 static void SlStubSaveProc2(void *arg)
   582 {
   582 {
   583 	_tmp_proc_1();
   583 	_tmp_proc_1();
   584 }
   584 }
   585 
   585 
   586 static void SlStubSaveProc()
   586 static void SlStubSaveProc(void)
   587 {
   587 {
   588 	SlAutolength(SlStubSaveProc2, NULL);
   588 	SlAutolength(SlStubSaveProc2, NULL);
   589 }
   589 }
   590 
   590 
   591 static void SlSaveChunk(const ChunkHandler *ch)
   591 static void SlSaveChunk(const ChunkHandler *ch)
   621 	default:
   621 	default:
   622 		NOT_REACHED();
   622 		NOT_REACHED();
   623 	}
   623 	}
   624 }
   624 }
   625 
   625 
   626 static void SlSaveChunks()
   626 static void SlSaveChunks(void)
   627 {
   627 {
   628 	const ChunkHandler *ch;
   628 	const ChunkHandler *ch;
   629 	const ChunkHandler * const * chsc;
   629 	const ChunkHandler * const * chsc;
   630 	uint p;
   630 	uint p;
   631 
   631 
   659 		}
   659 		}
   660 	}
   660 	}
   661 	return NULL;
   661 	return NULL;
   662 }
   662 }
   663 
   663 
   664 static void SlLoadChunks()
   664 static void SlLoadChunks(void)
   665 {
   665 {
   666 	uint32 id;
   666 	uint32 id;
   667 	const ChunkHandler *ch;
   667 	const ChunkHandler *ch;
   668 
   668 
   669 	while(true) {
   669 	while(true) {
   684 //*******************************************
   684 //*******************************************
   685 #define LZO_SIZE 8192
   685 #define LZO_SIZE 8192
   686 
   686 
   687 #include "minilzo.h"
   687 #include "minilzo.h"
   688 
   688 
   689 static uint ReadLZO()
   689 static uint ReadLZO(void)
   690 {
   690 {
   691 	byte out[LZO_SIZE + LZO_SIZE / 64 + 16 + 3 + 8];
   691 	byte out[LZO_SIZE + LZO_SIZE / 64 + 16 + 3 + 8];
   692 	uint32 tmp[2];
   692 	uint32 tmp[2];
   693 	uint32 size;
   693 	uint32 size;
   694 	uint len;
   694 	uint len;
   729 	((uint32*)out)[1] = TO_BE32(outlen);
   729 	((uint32*)out)[1] = TO_BE32(outlen);
   730 	((uint32*)out)[0] = TO_BE32(lzo_adler32(0, out + sizeof(uint32), outlen + sizeof(uint32)));
   730 	((uint32*)out)[0] = TO_BE32(lzo_adler32(0, out + sizeof(uint32), outlen + sizeof(uint32)));
   731 	if (fwrite(out, outlen + sizeof(uint32)*2, 1, _sl.fh) != 1) SlError("file write failed");
   731 	if (fwrite(out, outlen + sizeof(uint32)*2, 1, _sl.fh) != 1) SlError("file write failed");
   732 }
   732 }
   733 
   733 
   734 static bool InitLZO() {
   734 static bool InitLZO(void)
       
   735 {
   735 	_sl.bufsize = LZO_SIZE;
   736 	_sl.bufsize = LZO_SIZE;
   736 	_sl.buf = (byte*)malloc(LZO_SIZE);
   737 	_sl.buf = (byte*)malloc(LZO_SIZE);
   737 	return true;
   738 	return true;
   738 }
   739 }
   739 
   740 
   740 static void UninitLZO() {
   741 static void UninitLZO(void)
       
   742 {
   741 	free(_sl.buf);
   743 	free(_sl.buf);
   742 }
   744 }
   743 
   745 
   744 //*******************************************
   746 //*******************************************
   745 //******** START OF NOCOMP CODE *************
   747 //******** START OF NOCOMP CODE *************
   746 //*******************************************
   748 //*******************************************
   747 static uint ReadNoComp()
   749 static uint ReadNoComp(void)
   748 {
   750 {
   749 	return fread(_sl.buf, 1, LZO_SIZE, _sl.fh);
   751 	return fread(_sl.buf, 1, LZO_SIZE, _sl.fh);
   750 }
   752 }
   751 
   753 
   752 static void WriteNoComp(uint size)
   754 static void WriteNoComp(uint size)
   753 {
   755 {
   754 	fwrite(_sl.buf, 1, size, _sl.fh);
   756 	fwrite(_sl.buf, 1, size, _sl.fh);
   755 }
   757 }
   756 
   758 
   757 static bool InitNoComp()
   759 static bool InitNoComp(void)
   758 {
   760 {
   759 	_sl.bufsize = LZO_SIZE;
   761 	_sl.bufsize = LZO_SIZE;
   760 	_sl.buf = (byte*)malloc(LZO_SIZE);
   762 	_sl.buf = (byte*)malloc(LZO_SIZE);
   761 	return true;
   763 	return true;
   762 }
   764 }
   763 
   765 
   764 static void UninitNoComp()
   766 static void UninitNoComp(void)
   765 {
   767 {
   766 	free(_sl.buf);
   768 	free(_sl.buf);
   767 }
   769 }
   768 
   770 
   769 //********************************************
   771 //********************************************
   772 
   774 
   773 #if defined(WITH_ZLIB)
   775 #if defined(WITH_ZLIB)
   774 #include <zlib.h>
   776 #include <zlib.h>
   775 static z_stream _z;
   777 static z_stream _z;
   776 
   778 
   777 static bool InitReadZlib()
   779 static bool InitReadZlib(void)
   778 {
   780 {
   779 	memset(&_z, 0, sizeof(_z));
   781 	memset(&_z, 0, sizeof(_z));
   780 	if (inflateInit(&_z) != Z_OK) return false;
   782 	if (inflateInit(&_z) != Z_OK) return false;
   781 
   783 
   782 	_sl.bufsize = 4096;
   784 	_sl.bufsize = 4096;
   783 	_sl.buf = (byte*)malloc(4096 + 4096); // also contains fread buffer
   785 	_sl.buf = (byte*)malloc(4096 + 4096); // also contains fread buffer
   784 	return true;
   786 	return true;
   785 }
   787 }
   786 
   788 
   787 static uint ReadZlib()
   789 static uint ReadZlib(void)
   788 {
   790 {
   789 	int r;
   791 	int r;
   790 
   792 
   791 	_z.next_out = _sl.buf;
   793 	_z.next_out = _sl.buf;
   792 	_z.avail_out = 4096;
   794 	_z.avail_out = 4096;
   807 	} while (_z.avail_out);
   809 	} while (_z.avail_out);
   808 
   810 
   809 	return 4096 - _z.avail_out;
   811 	return 4096 - _z.avail_out;
   810 }
   812 }
   811 
   813 
   812 static void UninitReadZlib()
   814 static void UninitReadZlib(void)
   813 {
   815 {
   814 	inflateEnd(&_z);
   816 	inflateEnd(&_z);
   815 	free(_sl.buf);
   817 	free(_sl.buf);
   816 }
   818 }
   817 
   819 
   818 static bool InitWriteZlib()
   820 static bool InitWriteZlib(void)
   819 {
   821 {
   820 	memset(&_z, 0, sizeof(_z));
   822 	memset(&_z, 0, sizeof(_z));
   821 	if (deflateInit(&_z, 6) != Z_OK) return false;
   823 	if (deflateInit(&_z, 6) != Z_OK) return false;
   822 
   824 
   823 	_sl.bufsize = 4096;
   825 	_sl.bufsize = 4096;
   849 static void WriteZlib(uint len)
   851 static void WriteZlib(uint len)
   850 {
   852 {
   851 	WriteZlibLoop(&_z, _sl.buf, len, 0);
   853 	WriteZlibLoop(&_z, _sl.buf, len, 0);
   852 }
   854 }
   853 
   855 
   854 static void UninitWriteZlib()
   856 static void UninitWriteZlib(void)
   855 {
   857 {
   856 	// flush any pending output.
   858 	// flush any pending output.
   857 	if (_sl.fh) WriteZlibLoop(&_z, NULL, 0, Z_FINISH);
   859 	if (_sl.fh) WriteZlibLoop(&_z, NULL, 0, Z_FINISH);
   858 	deflateEnd(&_z);
   860 	deflateEnd(&_z);
   859 	free(_sl.buf);
   861 	free(_sl.buf);
   956 
   958 
   957 typedef struct {
   959 typedef struct {
   958 	const char *name;
   960 	const char *name;
   959 	uint32 tag;
   961 	uint32 tag;
   960 
   962 
   961 	bool (*init_read)();
   963 	bool (*init_read)(void);
   962 	ReaderProc *reader;
   964 	ReaderProc *reader;
   963 	void (*uninit_read)();
   965 	void (*uninit_read)(void);
   964 
   966 
   965 	bool (*init_write)();
   967 	bool (*init_write)(void);
   966 	WriterProc *writer;
   968 	WriterProc *writer;
   967 	void (*uninit_write)();
   969 	void (*uninit_write)(void);
   968 
   970 
   969 } SaveLoadFormat;
   971 } SaveLoadFormat;
   970 
   972 
   971 static const SaveLoadFormat _saveload_formats[] = {
   973 static const SaveLoadFormat _saveload_formats[] = {
   972 	{"lzo", TO_BE32X('OTTD'), InitLZO,ReadLZO, UninitLZO, InitLZO, WriteLZO, UninitLZO},
   974 	{"lzo", TO_BE32X('OTTD'), InitLZO,ReadLZO, UninitLZO, InitLZO, WriteLZO, UninitLZO},
   996 	}
   998 	}
   997 	return def;
   999 	return def;
   998 }
  1000 }
   999 
  1001 
  1000 // actual loader/saver function
  1002 // actual loader/saver function
  1001 extern void InitializeGame();
  1003 extern void InitializeGame(void);
  1002 extern bool AfterLoadGame(uint version);
  1004 extern bool AfterLoadGame(uint version);
  1003 extern void BeforeSaveGame();
  1005 extern void BeforeSaveGame(void);
  1004 extern bool LoadOldSaveGame(const char *file);
  1006 extern bool LoadOldSaveGame(const char *file);
  1005 
  1007 
  1006 //	Save or Load files SL_LOAD, SL_SAVE, SL_OLD_LOAD
  1008 //	Save or Load files SL_LOAD, SL_SAVE, SL_OLD_LOAD
  1007 int SaveOrLoad(const char *filename, int mode)
  1009 int SaveOrLoad(const char *filename, int mode)
  1008 {
  1010 {
  1130 	}
  1132 	}
  1131 
  1133 
  1132 	return SL_OK;
  1134 	return SL_OK;
  1133 }
  1135 }
  1134 
  1136 
  1135 bool EmergencySave()
  1137 bool EmergencySave(void)
  1136 {
  1138 {
  1137 	SaveOrLoad("crash.sav", SL_SAVE);
  1139 	SaveOrLoad("crash.sav", SL_SAVE);
  1138 	return true;
  1140 	return true;
  1139 }
  1141 }
  1140 
  1142 
  1141 void DoExitSave()
  1143 void DoExitSave(void)
  1142 {
  1144 {
  1143 	char buf[200];
  1145 	char buf[200];
  1144 	sprintf(buf, "%s%sexit.sav", _path.autosave_dir, PATHSEP);
  1146 	sprintf(buf, "%s%sexit.sav", _path.autosave_dir, PATHSEP);
  1145 	SaveOrLoad(buf, SL_SAVE);
  1147 	SaveOrLoad(buf, SL_SAVE);
  1146 }
  1148 }