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; |
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 } |
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) |
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 } |