saveload.cpp

Go to the documentation of this file.
00001 /* $Id$ */
00002 
00003 /*
00004  * This file is part of OpenTTD.
00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
00008  */
00009 
00024 #include "../stdafx.h"
00025 #include "../debug.h"
00026 #include "../station_base.h"
00027 #include "../thread/thread.h"
00028 #include "../town.h"
00029 #include "../network/network.h"
00030 #include "../window_func.h"
00031 #include "../strings_func.h"
00032 #include "../core/endian_func.hpp"
00033 #include "../vehicle_base.h"
00034 #include "../company_func.h"
00035 #include "../date_func.h"
00036 #include "../autoreplace_base.h"
00037 #include "../roadstop_base.h"
00038 #include "../statusbar_gui.h"
00039 #include "../fileio_func.h"
00040 #include "../gamelog.h"
00041 #include "../string_func.h"
00042 #include "../engine_base.h"
00043 #include "../fios.h"
00044 #include "../gui.h"
00045 
00046 #include "table/strings.h"
00047 
00048 #include "saveload_internal.h"
00049 #include "saveload_filter.h"
00050 
00051 /*
00052  * Previous savegame versions, the trunk revision where they were
00053  * introduced and the released version that had that particular
00054  * savegame version.
00055  * Up to savegame version 18 there is a minor version as well.
00056  *
00057  *    1.0         0.1.x, 0.2.x
00058  *    2.0         0.3.0
00059  *    2.1         0.3.1, 0.3.2
00060  *    3.x         lost
00061  *    4.0     1
00062  *    4.1   122   0.3.3, 0.3.4
00063  *    4.2  1222   0.3.5
00064  *    4.3  1417
00065  *    4.4  1426
00066  *    5.0  1429
00067  *    5.1  1440
00068  *    5.2  1525   0.3.6
00069  *    6.0  1721
00070  *    6.1  1768
00071  *    7.0  1770
00072  *    8.0  1786
00073  *    9.0  1909
00074  *   10.0  2030
00075  *   11.0  2033
00076  *   11.1  2041
00077  *   12.1  2046
00078  *   13.1  2080   0.4.0, 0.4.0.1
00079  *   14.0  2441
00080  *   15.0  2499
00081  *   16.0  2817
00082  *   16.1  3155
00083  *   17.0  3212
00084  *   17.1  3218
00085  *   18    3227
00086  *   19    3396
00087  *   20    3403
00088  *   21    3472   0.4.x
00089  *   22    3726
00090  *   23    3915
00091  *   24    4150
00092  *   25    4259
00093  *   26    4466
00094  *   27    4757
00095  *   28    4987
00096  *   29    5070
00097  *   30    5946
00098  *   31    5999
00099  *   32    6001
00100  *   33    6440
00101  *   34    6455
00102  *   35    6602
00103  *   36    6624
00104  *   37    7182
00105  *   38    7195
00106  *   39    7269
00107  *   40    7326
00108  *   41    7348   0.5.x
00109  *   42    7573
00110  *   43    7642
00111  *   44    8144
00112  *   45    8501
00113  *   46    8705
00114  *   47    8735
00115  *   48    8935
00116  *   49    8969
00117  *   50    8973
00118  *   51    8978
00119  *   52    9066
00120  *   53    9316
00121  *   54    9613
00122  *   55    9638
00123  *   56    9667
00124  *   57    9691
00125  *   58    9762
00126  *   59    9779
00127  *   60    9874
00128  *   61    9892
00129  *   62    9905
00130  *   63    9956
00131  *   64   10006
00132  *   65   10210
00133  *   66   10211
00134  *   67   10236
00135  *   68   10266
00136  *   69   10319
00137  *   70   10541
00138  *   71   10567
00139  *   72   10601
00140  *   73   10903
00141  *   74   11030
00142  *   75   11107
00143  *   76   11139
00144  *   77   11172
00145  *   78   11176
00146  *   79   11188
00147  *   80   11228
00148  *   81   11244
00149  *   82   11410
00150  *   83   11589
00151  *   84   11822
00152  *   85   11874
00153  *   86   12042
00154  *   87   12129
00155  *   88   12134
00156  *   89   12160
00157  *   90   12293
00158  *   91   12347
00159  *   92   12381   0.6.x
00160  *   93   12648
00161  *   94   12816
00162  *   95   12924
00163  *   96   13226
00164  *   97   13256
00165  *   98   13375
00166  *   99   13838
00167  *  100   13952
00168  *  101   14233
00169  *  102   14332
00170  *  103   14598
00171  *  104   14735
00172  *  105   14803
00173  *  106   14919
00174  *  107   15027
00175  *  108   15045
00176  *  109   15075
00177  *  110   15148
00178  *  111   15190
00179  *  112   15290
00180  *  113   15340
00181  *  114   15601
00182  *  115   15695
00183  *  116   15893   0.7.x
00184  *  117   16037
00185  *  118   16129
00186  *  119   16242
00187  *  120   16439
00188  *  121   16694
00189  *  122   16855
00190  *  123   16909
00191  *  124   16993
00192  *  125   17113
00193  *  126   17433
00194  *  127   17439
00195  *  128   18281
00196  *  129   18292
00197  *  130   18404
00198  *  131   18481
00199  *  132   18522
00200  *  133   18674
00201  *  134   18703
00202  *  135   18719
00203  *  136   18764
00204  *  137   18912
00205  *  138   18942   1.0.x
00206  *  139   19346
00207  *  140   19382
00208  *  141   19799
00209  *  142   20003
00210  *  143   20048
00211  *  144   20334
00212  *  145   20376
00213  *  146   20446
00214  *  147   20621
00215  *  148   20659
00216  *  149   20832
00217  *  150   20857
00218  *  151   20918
00219  *  152   21171
00220  *  153   21263
00221  *  154   21426
00222  *  155   21453
00223  *  156   21728
00224  *  157   21862
00225  *  158   21933
00226  *  159   21962
00227  *  160   21974   1.1.x
00228  *  161   22567
00229  *  162   22713
00230  *  163   22767
00231  *  164   23290
00232  *  165   23304
00233  *  166   23415
00234  */
00235 extern const uint16 SAVEGAME_VERSION = SL_EXT_RATING; 
00236 
00237 SavegameType _savegame_type; 
00238 
00239 uint32 _ttdp_version;     
00240 uint16 _sl_version;       
00241 byte   _sl_minor_version; 
00242 char _savegame_format[8]; 
00243 bool _do_autosave;        
00244 
00246 enum SaveLoadAction {
00247   SLA_LOAD,        
00248   SLA_SAVE,        
00249   SLA_PTRS,        
00250   SLA_NULL,        
00251   SLA_LOAD_CHECK,  
00252 };
00253 
00254 enum NeedLength {
00255   NL_NONE = 0,       
00256   NL_WANTLENGTH = 1, 
00257   NL_CALCLENGTH = 2, 
00258 };
00259 
00261 static const size_t MEMORY_CHUNK_SIZE = 128 * 1024;
00262 
00264 struct ReadBuffer {
00265   byte buf[MEMORY_CHUNK_SIZE]; 
00266   byte *bufp;                  
00267   byte *bufe;                  
00268   LoadFilter *reader;          
00269   size_t read;                 
00270 
00275   ReadBuffer(LoadFilter *reader) : bufp(NULL), bufe(NULL), reader(reader), read(0)
00276   {
00277   }
00278 
00279   FORCEINLINE byte ReadByte()
00280   {
00281     if (this->bufp == this->bufe) {
00282       size_t len = this->reader->Read(this->buf, lengthof(this->buf));
00283       if (len == 0) SlErrorCorrupt("Unexpected end of chunk");
00284 
00285       this->read += len;
00286       this->bufp = this->buf;
00287       this->bufe = this->buf + len;
00288     }
00289 
00290     return *this->bufp++;
00291   }
00292 
00297   size_t GetSize() const
00298   {
00299     return this->read - (this->bufe - this->bufp);
00300   }
00301 };
00302 
00303 
00305 struct MemoryDumper {
00306   AutoFreeSmallVector<byte *, 16> blocks; 
00307   byte *buf;                              
00308   byte *bufe;                             
00309 
00311   MemoryDumper() : buf(NULL), bufe(NULL)
00312   {
00313   }
00314 
00319   FORCEINLINE void WriteByte(byte b)
00320   {
00321     /* Are we at the end of this chunk? */
00322     if (this->buf == this->bufe) {
00323       this->buf = CallocT<byte>(MEMORY_CHUNK_SIZE);
00324       *this->blocks.Append() = this->buf;
00325       this->bufe = this->buf + MEMORY_CHUNK_SIZE;
00326     }
00327 
00328     *this->buf++ = b;
00329   }
00330 
00335   void Flush(SaveFilter *writer)
00336   {
00337     uint i = 0;
00338     size_t t = this->GetSize();
00339 
00340     while (t > 0) {
00341       size_t to_write = min(MEMORY_CHUNK_SIZE, t);
00342 
00343       writer->Write(this->blocks[i++], to_write);
00344       t -= to_write;
00345     }
00346 
00347     writer->Finish();
00348   }
00349 
00354   size_t GetSize() const
00355   {
00356     return this->blocks.Length() * MEMORY_CHUNK_SIZE - (this->bufe - this->buf);
00357   }
00358 };
00359 
00361 struct SaveLoadParams {
00362   SaveLoadAction action;               
00363   NeedLength need_length;              
00364   byte block_mode;                     
00365   bool error;                          
00366 
00367   size_t obj_len;                      
00368   int array_index, last_array_index;   
00369 
00370   MemoryDumper *dumper;                
00371   SaveFilter *sf;                      
00372 
00373   ReadBuffer *reader;                  
00374   LoadFilter *lf;                      
00375 
00376   StringID error_str;                  
00377   char *extra_msg;                     
00378 
00379   byte ff_state;                       
00380   bool saveinprogress;                 
00381 };
00382 
00383 static SaveLoadParams _sl; 
00384 
00385 /* these define the chunks */
00386 extern const ChunkHandler _gamelog_chunk_handlers[];
00387 extern const ChunkHandler _map_chunk_handlers[];
00388 extern const ChunkHandler _misc_chunk_handlers[];
00389 extern const ChunkHandler _name_chunk_handlers[];
00390 extern const ChunkHandler _cheat_chunk_handlers[] ;
00391 extern const ChunkHandler _setting_chunk_handlers[];
00392 extern const ChunkHandler _company_chunk_handlers[];
00393 extern const ChunkHandler _engine_chunk_handlers[];
00394 extern const ChunkHandler _veh_chunk_handlers[];
00395 extern const ChunkHandler _waypoint_chunk_handlers[];
00396 extern const ChunkHandler _depot_chunk_handlers[];
00397 extern const ChunkHandler _order_chunk_handlers[];
00398 extern const ChunkHandler _town_chunk_handlers[];
00399 extern const ChunkHandler _sign_chunk_handlers[];
00400 extern const ChunkHandler _station_chunk_handlers[];
00401 extern const ChunkHandler _industry_chunk_handlers[];
00402 extern const ChunkHandler _economy_chunk_handlers[];
00403 extern const ChunkHandler _subsidy_chunk_handlers[];
00404 extern const ChunkHandler _ai_chunk_handlers[];
00405 extern const ChunkHandler _animated_tile_chunk_handlers[];
00406 extern const ChunkHandler _newgrf_chunk_handlers[];
00407 extern const ChunkHandler _group_chunk_handlers[];
00408 extern const ChunkHandler _cargopacket_chunk_handlers[];
00409 extern const ChunkHandler _autoreplace_chunk_handlers[];
00410 extern const ChunkHandler _labelmaps_chunk_handlers[];
00411 extern const ChunkHandler _linkgraph_chunk_handlers[];
00412 extern const ChunkHandler _airport_chunk_handlers[];
00413 extern const ChunkHandler _object_chunk_handlers[];
00414 extern const ChunkHandler _persistent_storage_chunk_handlers[];
00415 
00417 static const ChunkHandler * const _chunk_handlers[] = {
00418   _gamelog_chunk_handlers,
00419   _map_chunk_handlers,
00420   _misc_chunk_handlers,
00421   _name_chunk_handlers,
00422   _cheat_chunk_handlers,
00423   _setting_chunk_handlers,
00424   _veh_chunk_handlers,
00425   _waypoint_chunk_handlers,
00426   _depot_chunk_handlers,
00427   _order_chunk_handlers,
00428   _industry_chunk_handlers,
00429   _economy_chunk_handlers,
00430   _subsidy_chunk_handlers,
00431   _engine_chunk_handlers,
00432   _town_chunk_handlers,
00433   _sign_chunk_handlers,
00434   _station_chunk_handlers,
00435   _company_chunk_handlers,
00436   _ai_chunk_handlers,
00437   _animated_tile_chunk_handlers,
00438   _newgrf_chunk_handlers,
00439   _group_chunk_handlers,
00440   _cargopacket_chunk_handlers,
00441   _autoreplace_chunk_handlers,
00442   _labelmaps_chunk_handlers,
00443   _linkgraph_chunk_handlers,
00444   _airport_chunk_handlers,
00445   _object_chunk_handlers,
00446   _persistent_storage_chunk_handlers,
00447   NULL,
00448 };
00449 
00454 #define FOR_ALL_CHUNK_HANDLERS(ch) \
00455   for (const ChunkHandler * const *chsc = _chunk_handlers; *chsc != NULL; chsc++) \
00456     for (const ChunkHandler *ch = *chsc; ch != NULL; ch = (ch->flags & CH_LAST) ? NULL : ch + 1)
00457 
00459 static void SlNullPointers()
00460 {
00461   _sl.action = SLA_NULL;
00462 
00463   /* We don't want any savegame conversion code to run
00464    * during NULLing; especially those that try to get
00465    * pointers from other pools. */
00466   _sl_version = SAVEGAME_VERSION;
00467 
00468   DEBUG(sl, 1, "Nulling pointers");
00469 
00470   FOR_ALL_CHUNK_HANDLERS(ch) {
00471     if (ch->ptrs_proc != NULL) {
00472       DEBUG(sl, 2, "Nulling pointers for %c%c%c%c", ch->id >> 24, ch->id >> 16, ch->id >> 8, ch->id);
00473       ch->ptrs_proc();
00474     }
00475   }
00476 
00477   DEBUG(sl, 1, "All pointers nulled");
00478 
00479   assert(_sl.action == SLA_NULL);
00480 }
00481 
00490 void NORETURN SlError(StringID string, const char *extra_msg)
00491 {
00492   /* Distinguish between loading into _load_check_data vs. normal save/load. */
00493   if (_sl.action == SLA_LOAD_CHECK) {
00494     _load_check_data.error = string;
00495     free(_load_check_data.error_data);
00496     _load_check_data.error_data = (extra_msg == NULL) ? NULL : strdup(extra_msg);
00497   } else {
00498     _sl.error_str = string;
00499     free(_sl.extra_msg);
00500     _sl.extra_msg = (extra_msg == NULL) ? NULL : strdup(extra_msg);
00501   }
00502 
00503   /* We have to NULL all pointers here; we might be in a state where
00504    * the pointers are actually filled with indices, which means that
00505    * when we access them during cleaning the pool dereferences of
00506    * those indices will be made with segmentation faults as result. */
00507   if (_sl.action == SLA_LOAD || _sl.action == SLA_PTRS) SlNullPointers();
00508   throw std::exception();
00509 }
00510 
00518 void NORETURN SlErrorCorrupt(const char *msg)
00519 {
00520   SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, msg);
00521 }
00522 
00523 
00524 typedef void (*AsyncSaveFinishProc)();                
00525 static AsyncSaveFinishProc _async_save_finish = NULL; 
00526 static ThreadObject *_save_thread;                    
00527 
00532 static void SetAsyncSaveFinish(AsyncSaveFinishProc proc)
00533 {
00534   if (_exit_game) return;
00535   while (_async_save_finish != NULL) CSleep(10);
00536 
00537   _async_save_finish = proc;
00538 }
00539 
00543 void ProcessAsyncSaveFinish()
00544 {
00545   if (_async_save_finish == NULL) return;
00546 
00547   _async_save_finish();
00548 
00549   _async_save_finish = NULL;
00550 
00551   if (_save_thread != NULL) {
00552     _save_thread->Join();
00553     delete _save_thread;
00554     _save_thread = NULL;
00555   }
00556 }
00557 
00562 byte SlReadByte()
00563 {
00564   return _sl.reader->ReadByte();
00565 }
00566 
00571 void SlWriteByte(byte b)
00572 {
00573   _sl.dumper->WriteByte(b);
00574 }
00575 
00576 static inline int SlReadUint16()
00577 {
00578   int x = SlReadByte() << 8;
00579   return x | SlReadByte();
00580 }
00581 
00582 static inline uint32 SlReadUint32()
00583 {
00584   uint32 x = SlReadUint16() << 16;
00585   return x | SlReadUint16();
00586 }
00587 
00588 static inline uint64 SlReadUint64()
00589 {
00590   uint32 x = SlReadUint32();
00591   uint32 y = SlReadUint32();
00592   return (uint64)x << 32 | y;
00593 }
00594 
00595 static inline void SlWriteUint16(uint16 v)
00596 {
00597   SlWriteByte(GB(v, 8, 8));
00598   SlWriteByte(GB(v, 0, 8));
00599 }
00600 
00601 static inline void SlWriteUint32(uint32 v)
00602 {
00603   SlWriteUint16(GB(v, 16, 16));
00604   SlWriteUint16(GB(v,  0, 16));
00605 }
00606 
00607 static inline void SlWriteUint64(uint64 x)
00608 {
00609   SlWriteUint32((uint32)(x >> 32));
00610   SlWriteUint32((uint32)x);
00611 }
00612 
00618 static inline void SlSkipBytes(size_t length)
00619 {
00620   for (; length != 0; length--) SlReadByte();
00621 }
00622 
00632 static uint SlReadSimpleGamma()
00633 {
00634   uint i = SlReadByte();
00635   if (HasBit(i, 7)) {
00636     i &= ~0x80;
00637     if (HasBit(i, 6)) {
00638       i &= ~0x40;
00639       if (HasBit(i, 5)) {
00640         i &= ~0x20;
00641         if (HasBit(i, 4)) {
00642           SlErrorCorrupt("Unsupported gamma");
00643         }
00644         i = (i << 8) | SlReadByte();
00645       }
00646       i = (i << 8) | SlReadByte();
00647     }
00648     i = (i << 8) | SlReadByte();
00649   }
00650   return i;
00651 }
00652 
00665 static void SlWriteSimpleGamma(size_t i)
00666 {
00667   if (i >= (1 << 7)) {
00668     if (i >= (1 << 14)) {
00669       if (i >= (1 << 21)) {
00670         assert(i < (1 << 28));
00671         SlWriteByte((byte)(0xE0 | (i >> 24)));
00672         SlWriteByte((byte)(i >> 16));
00673       } else {
00674         SlWriteByte((byte)(0xC0 | (i >> 16)));
00675       }
00676       SlWriteByte((byte)(i >> 8));
00677     } else {
00678       SlWriteByte((byte)(0x80 | (i >> 8)));
00679     }
00680   }
00681   SlWriteByte((byte)i);
00682 }
00683 
00685 static inline uint SlGetGammaLength(size_t i)
00686 {
00687   return 1 + (i >= (1 << 7)) + (i >= (1 << 14)) + (i >= (1 << 21));
00688 }
00689 
00690 static inline uint SlReadSparseIndex()
00691 {
00692   return SlReadSimpleGamma();
00693 }
00694 
00695 static inline void SlWriteSparseIndex(uint index)
00696 {
00697   SlWriteSimpleGamma(index);
00698 }
00699 
00700 static inline uint SlReadArrayLength()
00701 {
00702   return SlReadSimpleGamma();
00703 }
00704 
00705 static inline void SlWriteArrayLength(size_t length)
00706 {
00707   SlWriteSimpleGamma(length);
00708 }
00709 
00710 static inline uint SlGetArrayLength(size_t length)
00711 {
00712   return SlGetGammaLength(length);
00713 }
00714 
00721 static inline uint SlCalcConvMemLen(VarType conv)
00722 {
00723   static const byte conv_mem_size[] = {1, 1, 1, 2, 2, 4, 4, 8, 8, 0};
00724   byte length = GB(conv, 4, 4);
00725 
00726   switch (length << 4) {
00727     case SLE_VAR_STRB:
00728     case SLE_VAR_STRBQ:
00729     case SLE_VAR_STR:
00730     case SLE_VAR_STRQ:
00731       return SlReadArrayLength();
00732 
00733     default:
00734       assert(length < lengthof(conv_mem_size));
00735       return conv_mem_size[length];
00736   }
00737 }
00738 
00745 static inline byte SlCalcConvFileLen(VarType conv)
00746 {
00747   static const byte conv_file_size[] = {1, 1, 2, 2, 4, 4, 8, 8, 2};
00748   byte length = GB(conv, 0, 4);
00749   assert(length < lengthof(conv_file_size));
00750   return conv_file_size[length];
00751 }
00752 
00754 static inline size_t SlCalcRefLen()
00755 {
00756   return IsSavegameVersionBefore(69) ? 2 : 4;
00757 }
00758 
00759 void SlSetArrayIndex(uint index)
00760 {
00761   _sl.need_length = NL_WANTLENGTH;
00762   _sl.array_index = index;
00763 }
00764 
00765 static size_t _next_offs;
00766 
00771 int SlIterateArray()
00772 {
00773   int index;
00774 
00775   /* After reading in the whole array inside the loop
00776    * we must have read in all the data, so we must be at end of current block. */
00777   if (_next_offs != 0 && _sl.reader->GetSize() != _next_offs) SlErrorCorrupt("Invalid chunk size");
00778 
00779   for (;;) {
00780     uint length = SlReadArrayLength();
00781     if (length == 0) {
00782       _next_offs = 0;
00783       return -1;
00784     }
00785 
00786     _sl.obj_len = --length;
00787     _next_offs = _sl.reader->GetSize() + length;
00788 
00789     switch (_sl.block_mode) {
00790       case CH_SPARSE_ARRAY: index = (int)SlReadSparseIndex(); break;
00791       case CH_ARRAY:        index = _sl.array_index++; break;
00792       default:
00793         DEBUG(sl, 0, "SlIterateArray error");
00794         return -1; // error
00795     }
00796 
00797     if (length != 0) return index;
00798   }
00799 }
00800 
00804 void SlSkipArray()
00805 {
00806   while (SlIterateArray() != -1) {
00807     SlSkipBytes(_next_offs - _sl.reader->GetSize());
00808   }
00809 }
00810 
00816 void SlSetLength(size_t length)
00817 {
00818   assert(_sl.action == SLA_SAVE);
00819 
00820   switch (_sl.need_length) {
00821     case NL_WANTLENGTH:
00822       _sl.need_length = NL_NONE;
00823       switch (_sl.block_mode) {
00824         case CH_RIFF:
00825           /* Ugly encoding of >16M RIFF chunks
00826            * The lower 24 bits are normal
00827            * The uppermost 4 bits are bits 24:27 */
00828           assert(length < (1 << 28));
00829           SlWriteUint32((uint32)((length & 0xFFFFFF) | ((length >> 24) << 28)));
00830           break;
00831         case CH_ARRAY:
00832           assert(_sl.last_array_index <= _sl.array_index);
00833           while (++_sl.last_array_index <= _sl.array_index) {
00834             SlWriteArrayLength(1);
00835           }
00836           SlWriteArrayLength(length + 1);
00837           break;
00838         case CH_SPARSE_ARRAY:
00839           SlWriteArrayLength(length + 1 + SlGetArrayLength(_sl.array_index)); // Also include length of sparse index.
00840           SlWriteSparseIndex(_sl.array_index);
00841           break;
00842         default: NOT_REACHED();
00843       }
00844       break;
00845 
00846     case NL_CALCLENGTH:
00847       _sl.obj_len += (int)length;
00848       break;
00849 
00850     default: NOT_REACHED();
00851   }
00852 }
00853 
00860 static void SlCopyBytes(void *ptr, size_t length)
00861 {
00862   byte *p = (byte *)ptr;
00863 
00864   switch (_sl.action) {
00865     case SLA_LOAD_CHECK:
00866     case SLA_LOAD:
00867       for (; length != 0; length--) *p++ = SlReadByte();
00868       break;
00869     case SLA_SAVE:
00870       for (; length != 0; length--) SlWriteByte(*p++);
00871       break;
00872     default: NOT_REACHED();
00873   }
00874 }
00875 
00877 size_t SlGetFieldLength()
00878 {
00879   return _sl.obj_len;
00880 }
00881 
00889 int64 ReadValue(const void *ptr, VarType conv)
00890 {
00891   switch (GetVarMemType(conv)) {
00892     case SLE_VAR_BL:  return (*(const bool *)ptr != 0);
00893     case SLE_VAR_I8:  return *(const int8  *)ptr;
00894     case SLE_VAR_U8:  return *(const byte  *)ptr;
00895     case SLE_VAR_I16: return *(const int16 *)ptr;
00896     case SLE_VAR_U16: return *(const uint16*)ptr;
00897     case SLE_VAR_I32: return *(const int32 *)ptr;
00898     case SLE_VAR_U32: return *(const uint32*)ptr;
00899     case SLE_VAR_I64: return *(const int64 *)ptr;
00900     case SLE_VAR_U64: return *(const uint64*)ptr;
00901     case SLE_VAR_NULL:return 0;
00902     default: NOT_REACHED();
00903   }
00904 }
00905 
00913 void WriteValue(void *ptr, VarType conv, int64 val)
00914 {
00915   switch (GetVarMemType(conv)) {
00916     case SLE_VAR_BL:  *(bool  *)ptr = (val != 0);  break;
00917     case SLE_VAR_I8:  *(int8  *)ptr = val; break;
00918     case SLE_VAR_U8:  *(byte  *)ptr = val; break;
00919     case SLE_VAR_I16: *(int16 *)ptr = val; break;
00920     case SLE_VAR_U16: *(uint16*)ptr = val; break;
00921     case SLE_VAR_I32: *(int32 *)ptr = val; break;
00922     case SLE_VAR_U32: *(uint32*)ptr = val; break;
00923     case SLE_VAR_I64: *(int64 *)ptr = val; break;
00924     case SLE_VAR_U64: *(uint64*)ptr = val; break;
00925     case SLE_VAR_NAME: *(char**)ptr = CopyFromOldName(val); break;
00926     case SLE_VAR_NULL: break;
00927     default: NOT_REACHED();
00928   }
00929 }
00930 
00939 static void SlSaveLoadConv(void *ptr, VarType conv)
00940 {
00941   switch (_sl.action) {
00942     case SLA_SAVE: {
00943       int64 x = ReadValue(ptr, conv);
00944 
00945       /* Write the value to the file and check if its value is in the desired range */
00946       switch (GetVarFileType(conv)) {
00947         case SLE_FILE_I8: assert(x >= -128 && x <= 127);     SlWriteByte(x);break;
00948         case SLE_FILE_U8: assert(x >= 0 && x <= 255);        SlWriteByte(x);break;
00949         case SLE_FILE_I16:assert(x >= -32768 && x <= 32767); SlWriteUint16(x);break;
00950         case SLE_FILE_STRINGID:
00951         case SLE_FILE_U16:assert(x >= 0 && x <= 65535);      SlWriteUint16(x);break;
00952         case SLE_FILE_I32:
00953         case SLE_FILE_U32:                                   SlWriteUint32((uint32)x);break;
00954         case SLE_FILE_I64:
00955         case SLE_FILE_U64:                                   SlWriteUint64(x);break;
00956         default: NOT_REACHED();
00957       }
00958       break;
00959     }
00960     case SLA_LOAD_CHECK:
00961     case SLA_LOAD: {
00962       int64 x;
00963       /* Read a value from the file */
00964       switch (GetVarFileType(conv)) {
00965         case SLE_FILE_I8:  x = (int8  )SlReadByte();   break;
00966         case SLE_FILE_U8:  x = (byte  )SlReadByte();   break;
00967         case SLE_FILE_I16: x = (int16 )SlReadUint16(); break;
00968         case SLE_FILE_U16: x = (uint16)SlReadUint16(); break;
00969         case SLE_FILE_I32: x = (int32 )SlReadUint32(); break;
00970         case SLE_FILE_U32: x = (uint32)SlReadUint32(); break;
00971         case SLE_FILE_I64: x = (int64 )SlReadUint64(); break;
00972         case SLE_FILE_U64: x = (uint64)SlReadUint64(); break;
00973         case SLE_FILE_STRINGID: x = RemapOldStringID((uint16)SlReadUint16()); break;
00974         default: NOT_REACHED();
00975       }
00976 
00977       /* Write The value to the struct. These ARE endian safe. */
00978       WriteValue(ptr, conv, x);
00979       break;
00980     }
00981     case SLA_PTRS: break;
00982     case SLA_NULL: break;
00983     default: NOT_REACHED();
00984   }
00985 }
00986 
00996 static inline size_t SlCalcNetStringLen(const char *ptr, size_t length)
00997 {
00998   if (ptr == NULL) return 0;
00999   return min(strlen(ptr), length - 1);
01000 }
01001 
01011 static inline size_t SlCalcStringLen(const void *ptr, size_t length, VarType conv)
01012 {
01013   size_t len;
01014   const char *str;
01015 
01016   switch (GetVarMemType(conv)) {
01017     default: NOT_REACHED();
01018     case SLE_VAR_STR:
01019     case SLE_VAR_STRQ:
01020       str = *(const char * const *)ptr;
01021       len = SIZE_MAX;
01022       break;
01023     case SLE_VAR_STRB:
01024     case SLE_VAR_STRBQ:
01025       str = (const char *)ptr;
01026       len = length;
01027       break;
01028   }
01029 
01030   len = SlCalcNetStringLen(str, len);
01031   return len + SlGetArrayLength(len); // also include the length of the index
01032 }
01033 
01040 static void SlString(void *ptr, size_t length, VarType conv)
01041 {
01042   switch (_sl.action) {
01043     case SLA_SAVE: {
01044       size_t len;
01045       switch (GetVarMemType(conv)) {
01046         default: NOT_REACHED();
01047         case SLE_VAR_STRB:
01048         case SLE_VAR_STRBQ:
01049           len = SlCalcNetStringLen((char *)ptr, length);
01050           break;
01051         case SLE_VAR_STR:
01052         case SLE_VAR_STRQ:
01053           ptr = *(char **)ptr;
01054           len = SlCalcNetStringLen((char *)ptr, SIZE_MAX);
01055           break;
01056       }
01057 
01058       SlWriteArrayLength(len);
01059       SlCopyBytes(ptr, len);
01060       break;
01061     }
01062     case SLA_LOAD_CHECK:
01063     case SLA_LOAD: {
01064       size_t len = SlReadArrayLength();
01065 
01066       switch (GetVarMemType(conv)) {
01067         default: NOT_REACHED();
01068         case SLE_VAR_STRB:
01069         case SLE_VAR_STRBQ:
01070           if (len >= length) {
01071             DEBUG(sl, 1, "String length in savegame is bigger than buffer, truncating");
01072             SlCopyBytes(ptr, length);
01073             SlSkipBytes(len - length);
01074             len = length - 1;
01075           } else {
01076             SlCopyBytes(ptr, len);
01077           }
01078           break;
01079         case SLE_VAR_STR:
01080         case SLE_VAR_STRQ: // Malloc'd string, free previous incarnation, and allocate
01081           free(*(char **)ptr);
01082           if (len == 0) {
01083             *(char **)ptr = NULL;
01084           } else {
01085             *(char **)ptr = MallocT<char>(len + 1); // terminating '\0'
01086             ptr = *(char **)ptr;
01087             SlCopyBytes(ptr, len);
01088           }
01089           break;
01090       }
01091 
01092       ((char *)ptr)[len] = '\0'; // properly terminate the string
01093       str_validate((char *)ptr, (char *)ptr + len);
01094       break;
01095     }
01096     case SLA_PTRS: break;
01097     case SLA_NULL: break;
01098     default: NOT_REACHED();
01099   }
01100 }
01101 
01107 static inline size_t SlCalcArrayLen(size_t length, VarType conv)
01108 {
01109   return SlCalcConvFileLen(conv) * length;
01110 }
01111 
01118 void SlArray(void *array, size_t length, VarType conv)
01119 {
01120   if (_sl.action == SLA_PTRS || _sl.action == SLA_NULL) return;
01121 
01122   /* Automatically calculate the length? */
01123   if (_sl.need_length != NL_NONE) {
01124     SlSetLength(SlCalcArrayLen(length, conv));
01125     /* Determine length only? */
01126     if (_sl.need_length == NL_CALCLENGTH) return;
01127   }
01128 
01129   /* NOTICE - handle some buggy stuff, in really old versions everything was saved
01130    * as a byte-type. So detect this, and adjust array size accordingly */
01131   if (_sl.action != SLA_SAVE && _sl_version == 0) {
01132     /* all arrays except difficulty settings */
01133     if (conv == SLE_INT16 || conv == SLE_UINT16 || conv == SLE_STRINGID ||
01134         conv == SLE_INT32 || conv == SLE_UINT32) {
01135       SlCopyBytes(array, length * SlCalcConvFileLen(conv));
01136       return;
01137     }
01138     /* used for conversion of Money 32bit->64bit */
01139     if (conv == (SLE_FILE_I32 | SLE_VAR_I64)) {
01140       for (uint i = 0; i < length; i++) {
01141         ((int64*)array)[i] = (int32)BSWAP32(SlReadUint32());
01142       }
01143       return;
01144     }
01145   }
01146 
01147   /* If the size of elements is 1 byte both in file and memory, no special
01148    * conversion is needed, use specialized copy-copy function to speed up things */
01149   if (conv == SLE_INT8 || conv == SLE_UINT8) {
01150     SlCopyBytes(array, length);
01151   } else {
01152     byte *a = (byte*)array;
01153     byte mem_size = SlCalcConvMemLen(conv);
01154 
01155     for (; length != 0; length --) {
01156       SlSaveLoadConv(a, conv);
01157       a += mem_size; // get size
01158     }
01159   }
01160 }
01161 
01162 
01173 static size_t ReferenceToInt(const void *obj, SLRefType rt)
01174 {
01175   assert(_sl.action == SLA_SAVE);
01176 
01177   if (obj == NULL) return 0;
01178 
01179   switch (rt) {
01180     case REF_VEHICLE_OLD: // Old vehicles we save as new onces
01181     case REF_VEHICLE:   return ((const  Vehicle*)obj)->index + 1;
01182     case REF_STATION:   return ((const  Station*)obj)->index + 1;
01183     case REF_TOWN:      return ((const     Town*)obj)->index + 1;
01184     case REF_ORDER:     return ((const    Order*)obj)->index + 1;
01185     case REF_ROADSTOPS: return ((const RoadStop*)obj)->index + 1;
01186     case REF_ENGINE_RENEWS: return ((const       EngineRenew*)obj)->index + 1;
01187     case REF_CARGO_PACKET:  return ((const       CargoPacket*)obj)->index + 1;
01188     case REF_ORDERLIST:     return ((const         OrderList*)obj)->index + 1;
01189     case REF_STORAGE:       return ((const PersistentStorage*)obj)->index + 1;
01190     default: NOT_REACHED();
01191   }
01192 }
01193 
01204 static void *IntToReference(size_t index, SLRefType rt)
01205 {
01206   assert_compile(sizeof(size_t) <= sizeof(void *));
01207 
01208   assert(_sl.action == SLA_PTRS);
01209 
01210   /* After version 4.3 REF_VEHICLE_OLD is saved as REF_VEHICLE,
01211    * and should be loaded like that */
01212   if (rt == REF_VEHICLE_OLD && !IsSavegameVersionBefore(4, 4)) {
01213     rt = REF_VEHICLE;
01214   }
01215 
01216   /* No need to look up NULL pointers, just return immediately */
01217   if (index == (rt == REF_VEHICLE_OLD ? 0xFFFF : 0)) return NULL;
01218 
01219   /* Correct index. Old vehicles were saved differently:
01220    * invalid vehicle was 0xFFFF, now we use 0x0000 for everything invalid. */
01221   if (rt != REF_VEHICLE_OLD) index--;
01222 
01223   switch (rt) {
01224     case REF_ORDERLIST:
01225       if (OrderList::IsValidID(index)) return OrderList::Get(index);
01226       SlErrorCorrupt("Referencing invalid OrderList");
01227 
01228     case REF_ORDER:
01229       if (Order::IsValidID(index)) return Order::Get(index);
01230       /* in old versions, invalid order was used to mark end of order list */
01231       if (IsSavegameVersionBefore(5, 2)) return NULL;
01232       SlErrorCorrupt("Referencing invalid Order");
01233 
01234     case REF_VEHICLE_OLD:
01235     case REF_VEHICLE:
01236       if (Vehicle::IsValidID(index)) return Vehicle::Get(index);
01237       SlErrorCorrupt("Referencing invalid Vehicle");
01238 
01239     case REF_STATION:
01240       if (Station::IsValidID(index)) return Station::Get(index);
01241       SlErrorCorrupt("Referencing invalid Station");
01242 
01243     case REF_TOWN:
01244       if (Town::IsValidID(index)) return Town::Get(index);
01245       SlErrorCorrupt("Referencing invalid Town");
01246 
01247     case REF_ROADSTOPS:
01248       if (RoadStop::IsValidID(index)) return RoadStop::Get(index);
01249       SlErrorCorrupt("Referencing invalid RoadStop");
01250 
01251     case REF_ENGINE_RENEWS:
01252       if (EngineRenew::IsValidID(index)) return EngineRenew::Get(index);
01253       SlErrorCorrupt("Referencing invalid EngineRenew");
01254 
01255     case REF_CARGO_PACKET:
01256       if (CargoPacket::IsValidID(index)) return CargoPacket::Get(index);
01257       SlErrorCorrupt("Referencing invalid CargoPacket");
01258 
01259     case REF_STORAGE:
01260       if (PersistentStorage::IsValidID(index)) return PersistentStorage::Get(index);
01261       SlErrorCorrupt("Referencing invalid PersistentStorage");
01262 
01263     default: NOT_REACHED();
01264   }
01265 }
01266 
01271 static inline size_t SlCalcListLen(const void *list)
01272 {
01273   const std::list<void *> *l = (const std::list<void *> *) list;
01274 
01275   int type_size = IsSavegameVersionBefore(69) ? 2 : 4;
01276   /* Each entry is saved as type_size bytes, plus type_size bytes are used for the length
01277    * of the list */
01278   return l->size() * type_size + type_size;
01279 }
01280 
01281 
01287 static void SlList(void *list, SLRefType conv)
01288 {
01289   /* Automatically calculate the length? */
01290   if (_sl.need_length != NL_NONE) {
01291     SlSetLength(SlCalcListLen(list));
01292     /* Determine length only? */
01293     if (_sl.need_length == NL_CALCLENGTH) return;
01294   }
01295 
01296   typedef std::list<void *> PtrList;
01297   PtrList *l = (PtrList *)list;
01298 
01299   switch (_sl.action) {
01300     case SLA_SAVE: {
01301       SlWriteUint32((uint32)l->size());
01302 
01303       PtrList::iterator iter;
01304       for (iter = l->begin(); iter != l->end(); ++iter) {
01305         void *ptr = *iter;
01306         SlWriteUint32((uint32)ReferenceToInt(ptr, conv));
01307       }
01308       break;
01309     }
01310     case SLA_LOAD_CHECK:
01311     case SLA_LOAD: {
01312       size_t length = IsSavegameVersionBefore(69) ? SlReadUint16() : SlReadUint32();
01313 
01314       /* Load each reference and push to the end of the list */
01315       for (size_t i = 0; i < length; i++) {
01316         size_t data = IsSavegameVersionBefore(69) ? SlReadUint16() : SlReadUint32();
01317         l->push_back((void *)data);
01318       }
01319       break;
01320     }
01321     case SLA_PTRS: {
01322       PtrList temp = *l;
01323 
01324       l->clear();
01325       PtrList::iterator iter;
01326       for (iter = temp.begin(); iter != temp.end(); ++iter) {
01327         void *ptr = IntToReference((size_t)*iter, conv);
01328         l->push_back(ptr);
01329       }
01330       break;
01331     }
01332     case SLA_NULL:
01333       l->clear();
01334       break;
01335     default: NOT_REACHED();
01336   }
01337 }
01338 
01339 
01341 static inline bool SlIsObjectValidInSavegame(const SaveLoad *sld)
01342 {
01343   if (_sl_version < sld->version_from || _sl_version > sld->version_to) return false;
01344   if (sld->conv & SLF_NOT_IN_SAVE) return false;
01345 
01346   return true;
01347 }
01348 
01354 static inline bool SlSkipVariableOnLoad(const SaveLoad *sld)
01355 {
01356   if ((sld->conv & SLF_NO_NETWORK_SYNC) && _sl.action != SLA_SAVE && _networking && !_network_server) {
01357     SlSkipBytes(SlCalcConvMemLen(sld->conv) * sld->length);
01358     return true;
01359   }
01360 
01361   return false;
01362 }
01363 
01370 size_t SlCalcObjLength(const void *object, const SaveLoad *sld)
01371 {
01372   size_t length = 0;
01373 
01374   /* Need to determine the length and write a length tag. */
01375   for (; sld->cmd != SL_END; sld++) {
01376     length += SlCalcObjMemberLength(object, sld);
01377   }
01378   return length;
01379 }
01380 
01381 size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld)
01382 {
01383   assert(_sl.action == SLA_SAVE);
01384 
01385   switch (sld->cmd) {
01386     case SL_VAR:
01387     case SL_REF:
01388     case SL_ARR:
01389     case SL_STR:
01390     case SL_LST:
01391       /* CONDITIONAL saveload types depend on the savegame version */
01392       if (!SlIsObjectValidInSavegame(sld)) break;
01393 
01394       switch (sld->cmd) {
01395         case SL_VAR: return SlCalcConvFileLen(sld->conv);
01396         case SL_REF: return SlCalcRefLen();
01397         case SL_ARR: return SlCalcArrayLen(sld->length, sld->conv);
01398         case SL_STR: return SlCalcStringLen(GetVariableAddress(object, sld), sld->length, sld->conv);
01399         case SL_LST: return SlCalcListLen(GetVariableAddress(object, sld));
01400         default: NOT_REACHED();
01401       }
01402       break;
01403     case SL_WRITEBYTE: return 1; // a byte is logically of size 1
01404     case SL_VEH_INCLUDE: return SlCalcObjLength(object, GetVehicleDescription(VEH_END));
01405     case SL_ST_INCLUDE: return SlCalcObjLength(object, GetBaseStationDescription());
01406     default: NOT_REACHED();
01407   }
01408   return 0;
01409 }
01410 
01411 
01412 bool SlObjectMember(void *ptr, const SaveLoad *sld)
01413 {
01414   VarType conv = GB(sld->conv, 0, 8);
01415   switch (sld->cmd) {
01416     case SL_VAR:
01417     case SL_REF:
01418     case SL_ARR:
01419     case SL_STR:
01420     case SL_LST:
01421       /* CONDITIONAL saveload types depend on the savegame version */
01422       if (!SlIsObjectValidInSavegame(sld)) return false;
01423       if (SlSkipVariableOnLoad(sld)) return false;
01424 
01425       switch (sld->cmd) {
01426         case SL_VAR: SlSaveLoadConv(ptr, conv); break;
01427         case SL_REF: // Reference variable, translate
01428           switch (_sl.action) {
01429             case SLA_SAVE:
01430               SlWriteUint32((uint32)ReferenceToInt(*(void **)ptr, (SLRefType)conv));
01431               break;
01432             case SLA_LOAD_CHECK:
01433             case SLA_LOAD:
01434               *(size_t *)ptr = IsSavegameVersionBefore(69) ? SlReadUint16() : SlReadUint32();
01435               break;
01436             case SLA_PTRS:
01437               *(void **)ptr = IntToReference(*(size_t *)ptr, (SLRefType)conv);
01438               break;
01439             case SLA_NULL:
01440               *(void **)ptr = NULL;
01441               break;
01442             default: NOT_REACHED();
01443           }
01444           break;
01445         case SL_ARR: SlArray(ptr, sld->length, conv); break;
01446         case SL_STR: SlString(ptr, sld->length, conv); break;
01447         case SL_LST: SlList(ptr, (SLRefType)conv); break;
01448         default: NOT_REACHED();
01449       }
01450       break;
01451 
01452     /* SL_WRITEBYTE translates a value of a variable to another one upon
01453      * saving or loading.
01454      * XXX - variable renaming abuse
01455      * game_value: the value of the variable ingame is abused by sld->version_from
01456      * file_value: the value of the variable in the savegame is abused by sld->version_to */
01457     case SL_WRITEBYTE:
01458       switch (_sl.action) {
01459         case SLA_SAVE: SlWriteByte(sld->version_to); break;
01460         case SLA_LOAD_CHECK:
01461         case SLA_LOAD: *(byte *)ptr = sld->version_from; break;
01462         case SLA_PTRS: break;
01463         case SLA_NULL: break;
01464         default: NOT_REACHED();
01465       }
01466       break;
01467 
01468     /* SL_VEH_INCLUDE loads common code for vehicles */
01469     case SL_VEH_INCLUDE:
01470       SlObject(ptr, GetVehicleDescription(VEH_END));
01471       break;
01472 
01473     case SL_ST_INCLUDE:
01474       SlObject(ptr, GetBaseStationDescription());
01475       break;
01476 
01477     default: NOT_REACHED();
01478   }
01479   return true;
01480 }
01481 
01487 void SlObject(void *object, const SaveLoad *sld)
01488 {
01489   /* Automatically calculate the length? */
01490   if (_sl.need_length != NL_NONE) {
01491     SlSetLength(SlCalcObjLength(object, sld));
01492     if (_sl.need_length == NL_CALCLENGTH) return;
01493   }
01494 
01495   for (; sld->cmd != SL_END; sld++) {
01496     void *ptr = sld->global ? sld->address : GetVariableAddress(object, sld);
01497     SlObjectMember(ptr, sld);
01498   }
01499 }
01500 
01505 void SlGlobList(const SaveLoadGlobVarList *sldg)
01506 {
01507   SlObject(NULL, (const SaveLoad*)sldg);
01508 }
01509 
01515 void SlAutolength(AutolengthProc *proc, void *arg)
01516 {
01517   size_t offs;
01518 
01519   assert(_sl.action == SLA_SAVE);
01520 
01521   /* Tell it to calculate the length */
01522   _sl.need_length = NL_CALCLENGTH;
01523   _sl.obj_len = 0;
01524   proc(arg);
01525 
01526   /* Setup length */
01527   _sl.need_length = NL_WANTLENGTH;
01528   SlSetLength(_sl.obj_len);
01529 
01530   offs = _sl.dumper->GetSize() + _sl.obj_len;
01531 
01532   /* And write the stuff */
01533   proc(arg);
01534 
01535   if (offs != _sl.dumper->GetSize()) SlErrorCorrupt("Invalid chunk size");
01536 }
01537 
01542 static void SlLoadChunk(const ChunkHandler *ch)
01543 {
01544   byte m = SlReadByte();
01545   size_t len;
01546   size_t endoffs;
01547 
01548   _sl.block_mode = m;
01549   _sl.obj_len = 0;
01550 
01551   switch (m) {
01552     case CH_ARRAY:
01553       _sl.array_index = 0;
01554       ch->load_proc();
01555       break;
01556     case CH_SPARSE_ARRAY:
01557       ch->load_proc();
01558       break;
01559     default:
01560       if ((m & 0xF) == CH_RIFF) {
01561         /* Read length */
01562         len = (SlReadByte() << 16) | ((m >> 4) << 24);
01563         len += SlReadUint16();
01564         _sl.obj_len = len;
01565         endoffs = _sl.reader->GetSize() + len;
01566         ch->load_proc();
01567         if (_sl.reader->GetSize() != endoffs) SlErrorCorrupt("Invalid chunk size");
01568       } else {
01569         SlErrorCorrupt("Invalid chunk type");
01570       }
01571       break;
01572   }
01573 }
01574 
01580 static void SlLoadCheckChunk(const ChunkHandler *ch)
01581 {
01582   byte m = SlReadByte();
01583   size_t len;
01584   size_t endoffs;
01585 
01586   _sl.block_mode = m;
01587   _sl.obj_len = 0;
01588 
01589   switch (m) {
01590     case CH_ARRAY:
01591       _sl.array_index = 0;
01592       if (ch->load_check_proc) {
01593         ch->load_check_proc();
01594       } else {
01595         SlSkipArray();
01596       }
01597       break;
01598     case CH_SPARSE_ARRAY:
01599       if (ch->load_check_proc) {
01600         ch->load_check_proc();
01601       } else {
01602         SlSkipArray();
01603       }
01604       break;
01605     default:
01606       if ((m & 0xF) == CH_RIFF) {
01607         /* Read length */
01608         len = (SlReadByte() << 16) | ((m >> 4) << 24);
01609         len += SlReadUint16();
01610         _sl.obj_len = len;
01611         endoffs = _sl.reader->GetSize() + len;
01612         if (ch->load_check_proc) {
01613           ch->load_check_proc();
01614         } else {
01615           SlSkipBytes(len);
01616         }
01617         if (_sl.reader->GetSize() != endoffs) SlErrorCorrupt("Invalid chunk size");
01618       } else {
01619         SlErrorCorrupt("Invalid chunk type");
01620       }
01621       break;
01622   }
01623 }
01624 
01629 static ChunkSaveLoadProc *_stub_save_proc;
01630 
01636 static inline void SlStubSaveProc2(void *arg)
01637 {
01638   _stub_save_proc();
01639 }
01640 
01646 static void SlStubSaveProc()
01647 {
01648   SlAutolength(SlStubSaveProc2, NULL);
01649 }
01650 
01656 static void SlSaveChunk(const ChunkHandler *ch)
01657 {
01658   ChunkSaveLoadProc *proc = ch->save_proc;
01659 
01660   /* Don't save any chunk information if there is no save handler. */
01661   if (proc == NULL) return;
01662 
01663   SlWriteUint32(ch->id);
01664   DEBUG(sl, 2, "Saving chunk %c%c%c%c", ch->id >> 24, ch->id >> 16, ch->id >> 8, ch->id);
01665 
01666   if (ch->flags & CH_AUTO_LENGTH) {
01667     /* Need to calculate the length. Solve that by calling SlAutoLength in the save_proc. */
01668     _stub_save_proc = proc;
01669     proc = SlStubSaveProc;
01670   }
01671 
01672   _sl.block_mode = ch->flags & CH_TYPE_MASK;
01673   switch (ch->flags & CH_TYPE_MASK) {
01674     case CH_RIFF:
01675       _sl.need_length = NL_WANTLENGTH;
01676       proc();
01677       break;
01678     case CH_ARRAY:
01679       _sl.last_array_index = 0;
01680       SlWriteByte(CH_ARRAY);
01681       proc();
01682       SlWriteArrayLength(0); // Terminate arrays
01683       break;
01684     case CH_SPARSE_ARRAY:
01685       SlWriteByte(CH_SPARSE_ARRAY);
01686       proc();
01687       SlWriteArrayLength(0); // Terminate arrays
01688       break;
01689     default: NOT_REACHED();
01690   }
01691 }
01692 
01694 static void SlSaveChunks()
01695 {
01696   FOR_ALL_CHUNK_HANDLERS(ch) {
01697     SlSaveChunk(ch);
01698   }
01699 
01700   /* Terminator */
01701   SlWriteUint32(0);
01702 }
01703 
01710 static const ChunkHandler *SlFindChunkHandler(uint32 id)
01711 {
01712   FOR_ALL_CHUNK_HANDLERS(ch) if (ch->id == id) return ch;
01713   return NULL;
01714 }
01715 
01717 static void SlLoadChunks()
01718 {
01719   uint32 id;
01720   const ChunkHandler *ch;
01721 
01722   for (id = SlReadUint32(); id != 0; id = SlReadUint32()) {
01723     DEBUG(sl, 2, "Loading chunk %c%c%c%c", id >> 24, id >> 16, id >> 8, id);
01724 
01725     ch = SlFindChunkHandler(id);
01726     if (ch == NULL) SlErrorCorrupt("Unknown chunk type");
01727     SlLoadChunk(ch);
01728   }
01729 }
01730 
01732 static void SlLoadCheckChunks()
01733 {
01734   uint32 id;
01735   const ChunkHandler *ch;
01736 
01737   for (id = SlReadUint32(); id != 0; id = SlReadUint32()) {
01738     DEBUG(sl, 2, "Loading chunk %c%c%c%c", id >> 24, id >> 16, id >> 8, id);
01739 
01740     ch = SlFindChunkHandler(id);
01741     if (ch == NULL) SlErrorCorrupt("Unknown chunk type");
01742     SlLoadCheckChunk(ch);
01743   }
01744 }
01745 
01747 static void SlFixPointers()
01748 {
01749   _sl.action = SLA_PTRS;
01750 
01751   DEBUG(sl, 1, "Fixing pointers");
01752 
01753   FOR_ALL_CHUNK_HANDLERS(ch) {
01754     if (ch->ptrs_proc != NULL) {
01755       DEBUG(sl, 2, "Fixing pointers for %c%c%c%c", ch->id >> 24, ch->id >> 16, ch->id >> 8, ch->id);
01756       ch->ptrs_proc();
01757     }
01758   }
01759 
01760   DEBUG(sl, 1, "All pointers fixed");
01761 
01762   assert(_sl.action == SLA_PTRS);
01763 }
01764 
01765 
01767 struct FileReader : LoadFilter {
01768   FILE *file; 
01769   long begin; 
01770 
01775   FileReader(FILE *file) : LoadFilter(NULL), file(file), begin(ftell(file))
01776   {
01777   }
01778 
01780   ~FileReader()
01781   {
01782     if (this->file != NULL) fclose(this->file);
01783     this->file = NULL;
01784 
01785     /* Make sure we don't double free. */
01786     _sl.sf = NULL;
01787   }
01788 
01789   /* virtual */ size_t Read(byte *buf, size_t size)
01790   {
01791     /* We're in the process of shutting down, i.e. in "failure" mode. */
01792     if (this->file == NULL) return 0;
01793 
01794     return fread(buf, 1, size, this->file);
01795   }
01796 
01797   /* virtual */ void Reset()
01798   {
01799     clearerr(this->file);
01800     fseek(this->file, this->begin, SEEK_SET);
01801   }
01802 };
01803 
01805 struct FileWriter : SaveFilter {
01806   FILE *file; 
01807 
01812   FileWriter(FILE *file) : SaveFilter(NULL), file(file)
01813   {
01814   }
01815 
01817   ~FileWriter()
01818   {
01819     this->Finish();
01820 
01821     /* Make sure we don't double free. */
01822     _sl.sf = NULL;
01823   }
01824 
01825   /* virtual */ void Write(byte *buf, size_t size)
01826   {
01827     /* We're in the process of shutting down, i.e. in "failure" mode. */
01828     if (this->file == NULL) return;
01829 
01830     if (fwrite(buf, 1, size, this->file) != size) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE);
01831   }
01832 
01833   /* virtual */ void Finish()
01834   {
01835     if (this->file != NULL) fclose(this->file);
01836     this->file = NULL;
01837   }
01838 };
01839 
01840 /*******************************************
01841  ********** START OF LZO CODE **************
01842  *******************************************/
01843 
01844 #ifdef WITH_LZO
01845 #include <lzo/lzo1x.h>
01846 
01848 static const uint LZO_BUFFER_SIZE = 8192;
01849 
01851 struct LZOLoadFilter : LoadFilter {
01856   LZOLoadFilter(LoadFilter *chain) : LoadFilter(chain)
01857   {
01858     if (lzo_init() != LZO_E_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize decompressor");
01859   }
01860 
01861   /* virtual */ size_t Read(byte *buf, size_t ssize)
01862   {
01863     assert(ssize >= LZO_BUFFER_SIZE);
01864 
01865     /* Buffer size is from the LZO docs plus the chunk header size. */
01866     byte out[LZO_BUFFER_SIZE + LZO_BUFFER_SIZE / 16 + 64 + 3 + sizeof(uint32) * 2];
01867     uint32 tmp[2];
01868     uint32 size;
01869     lzo_uint len;
01870 
01871     /* Read header*/
01872     if (this->chain->Read((byte*)tmp, sizeof(tmp)) != sizeof(tmp)) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE, "File read failed");
01873 
01874     /* Check if size is bad */
01875     ((uint32*)out)[0] = size = tmp[1];
01876 
01877     if (_sl_version != 0) {
01878       tmp[0] = TO_BE32(tmp[0]);
01879       size = TO_BE32(size);
01880     }
01881 
01882     if (size >= sizeof(out)) SlErrorCorrupt("Inconsistent size");
01883 
01884     /* Read block */
01885     if (this->chain->Read(out + sizeof(uint32), size) != size) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
01886 
01887     /* Verify checksum */
01888     if (tmp[0] != lzo_adler32(0, out, size + sizeof(uint32))) SlErrorCorrupt("Bad checksum");
01889 
01890     /* Decompress */
01891     lzo1x_decompress(out + sizeof(uint32) * 1, size, buf, &len, NULL);
01892     return len;
01893   }
01894 };
01895 
01897 struct LZOSaveFilter : SaveFilter {
01903   LZOSaveFilter(SaveFilter *chain, byte compression_level) : SaveFilter(chain)
01904   {
01905     if (lzo_init() != LZO_E_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize compressor");
01906   }
01907 
01908   /* virtual */ void Write(byte *buf, size_t size)
01909   {
01910     const lzo_bytep in = buf;
01911     /* Buffer size is from the LZO docs plus the chunk header size. */
01912     byte out[LZO_BUFFER_SIZE + LZO_BUFFER_SIZE / 16 + 64 + 3 + sizeof(uint32) * 2];
01913     byte wrkmem[LZO1X_1_MEM_COMPRESS];
01914     lzo_uint outlen;
01915 
01916     do {
01917       /* Compress up to LZO_BUFFER_SIZE bytes at once. */
01918       lzo_uint len = size > LZO_BUFFER_SIZE ? LZO_BUFFER_SIZE : (lzo_uint)size;
01919       lzo1x_1_compress(in, len, out + sizeof(uint32) * 2, &outlen, wrkmem);
01920       ((uint32*)out)[1] = TO_BE32((uint32)outlen);
01921       ((uint32*)out)[0] = TO_BE32(lzo_adler32(0, out + sizeof(uint32), outlen + sizeof(uint32)));
01922       this->chain->Write(out, outlen + sizeof(uint32) * 2);
01923 
01924       /* Move to next data chunk. */
01925       size -= len;
01926       in += len;
01927     } while (size > 0);
01928   }
01929 };
01930 
01931 #endif /* WITH_LZO */
01932 
01933 /*********************************************
01934  ******** START OF NOCOMP CODE (uncompressed)*
01935  *********************************************/
01936 
01938 struct NoCompLoadFilter : LoadFilter {
01943   NoCompLoadFilter(LoadFilter *chain) : LoadFilter(chain)
01944   {
01945   }
01946 
01947   /* virtual */ size_t Read(byte *buf, size_t size)
01948   {
01949     return this->chain->Read(buf, size);
01950   }
01951 };
01952 
01954 struct NoCompSaveFilter : SaveFilter {
01960   NoCompSaveFilter(SaveFilter *chain, byte compression_level) : SaveFilter(chain)
01961   {
01962   }
01963 
01964   /* virtual */ void Write(byte *buf, size_t size)
01965   {
01966     this->chain->Write(buf, size);
01967   }
01968 };
01969 
01970 /********************************************
01971  ********** START OF ZLIB CODE **************
01972  ********************************************/
01973 
01974 #if defined(WITH_ZLIB)
01975 #include <zlib.h>
01976 
01978 struct ZlibLoadFilter : LoadFilter {
01979   z_stream z;                        
01980   byte fread_buf[MEMORY_CHUNK_SIZE]; 
01981 
01986   ZlibLoadFilter(LoadFilter *chain) : LoadFilter(chain)
01987   {
01988     memset(&this->z, 0, sizeof(this->z));
01989     if (inflateInit(&this->z) != Z_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize decompressor");
01990   }
01991 
01993   ~ZlibLoadFilter()
01994   {
01995     inflateEnd(&this->z);
01996   }
01997 
01998   /* virtual */ size_t Read(byte *buf, size_t size)
01999   {
02000     this->z.next_out  = buf;
02001     this->z.avail_out = (uint)size;
02002 
02003     do {
02004       /* read more bytes from the file? */
02005       if (this->z.avail_in == 0) {
02006         this->z.next_in = this->fread_buf;
02007         this->z.avail_in = (uint)this->chain->Read(this->fread_buf, sizeof(this->fread_buf));
02008       }
02009 
02010       /* inflate the data */
02011       int r = inflate(&this->z, 0);
02012       if (r == Z_STREAM_END) break;
02013 
02014       if (r != Z_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "inflate() failed");
02015     } while (this->z.avail_out != 0);
02016 
02017     return size - this->z.avail_out;
02018   }
02019 };
02020 
02022 struct ZlibSaveFilter : SaveFilter {
02023   z_stream z; 
02024 
02030   ZlibSaveFilter(SaveFilter *chain, byte compression_level) : SaveFilter(chain)
02031   {
02032     memset(&this->z, 0, sizeof(this->z));
02033     if (deflateInit(&this->z, compression_level) != Z_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize compressor");
02034   }
02035 
02037   ~ZlibSaveFilter()
02038   {
02039     deflateEnd(&this->z);
02040   }
02041 
02048   void WriteLoop(byte *p, size_t len, int mode)
02049   {
02050     byte buf[MEMORY_CHUNK_SIZE]; // output buffer
02051     uint n;
02052     this->z.next_in = p;
02053     this->z.avail_in = (uInt)len;
02054     do {
02055       this->z.next_out = buf;
02056       this->z.avail_out = sizeof(buf);
02057 
02065       int r = deflate(&this->z, mode);
02066 
02067       /* bytes were emitted? */
02068       if ((n = sizeof(buf) - this->z.avail_out) != 0) {
02069         this->chain->Write(buf, n);
02070       }
02071       if (r == Z_STREAM_END) break;
02072 
02073       if (r != Z_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "zlib returned error code");
02074     } while (this->z.avail_in || !this->z.avail_out);
02075   }
02076 
02077   /* virtual */ void Write(byte *buf, size_t size)
02078   {
02079     this->WriteLoop(buf, size, 0);
02080   }
02081 
02082   /* virtual */ void Finish()
02083   {
02084     this->WriteLoop(NULL, 0, Z_FINISH);
02085     this->chain->Finish();
02086   }
02087 };
02088 
02089 #endif /* WITH_ZLIB */
02090 
02091 /********************************************
02092  ********** START OF LZMA CODE **************
02093  ********************************************/
02094 
02095 #if defined(WITH_LZMA)
02096 #include <lzma.h>
02097 
02104 static const lzma_stream _lzma_init = LZMA_STREAM_INIT;
02105 
02107 struct LZMALoadFilter : LoadFilter {
02108   lzma_stream lzma;                  
02109   byte fread_buf[MEMORY_CHUNK_SIZE]; 
02110 
02115   LZMALoadFilter(LoadFilter *chain) : LoadFilter(chain), lzma(_lzma_init)
02116   {
02117     /* Allow saves up to 256 MB uncompressed */
02118     if (lzma_auto_decoder(&this->lzma, 1 << 28, 0) != LZMA_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize decompressor");
02119   }
02120 
02122   ~LZMALoadFilter()
02123   {
02124     lzma_end(&this->lzma);
02125   }
02126 
02127   /* virtual */ size_t Read(byte *buf, size_t size)
02128   {
02129     this->lzma.next_out  = buf;
02130     this->lzma.avail_out = size;
02131 
02132     do {
02133       /* read more bytes from the file? */
02134       if (this->lzma.avail_in == 0) {
02135         this->lzma.next_in  = this->fread_buf;
02136         this->lzma.avail_in = this->chain->Read(this->fread_buf, sizeof(this->fread_buf));
02137       }
02138 
02139       /* inflate the data */
02140       lzma_ret r = lzma_code(&this->lzma, LZMA_RUN);
02141       if (r == LZMA_STREAM_END) break;
02142       if (r != LZMA_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "liblzma returned error code");
02143     } while (this->lzma.avail_out != 0);
02144 
02145     return size - this->lzma.avail_out;
02146   }
02147 };
02148 
02150 struct LZMASaveFilter : SaveFilter {
02151   lzma_stream lzma; 
02152 
02158   LZMASaveFilter(SaveFilter *chain, byte compression_level) : SaveFilter(chain), lzma(_lzma_init)
02159   {
02160     if (lzma_easy_encoder(&this->lzma, compression_level, LZMA_CHECK_CRC32) != LZMA_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize compressor");
02161   }
02162 
02164   ~LZMASaveFilter()
02165   {
02166     lzma_end(&this->lzma);
02167   }
02168 
02175   void WriteLoop(byte *p, size_t len, lzma_action action)
02176   {
02177     byte buf[MEMORY_CHUNK_SIZE]; // output buffer
02178     size_t n;
02179     this->lzma.next_in = p;
02180     this->lzma.avail_in = len;
02181     do {
02182       this->lzma.next_out = buf;
02183       this->lzma.avail_out = sizeof(buf);
02184 
02185       lzma_ret r = lzma_code(&this->lzma, action);
02186 
02187       /* bytes were emitted? */
02188       if ((n = sizeof(buf) - this->lzma.avail_out) != 0) {
02189         this->chain->Write(buf, n);
02190       }
02191       if (r == LZMA_STREAM_END) break;
02192       if (r != LZMA_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "liblzma returned error code");
02193     } while (this->lzma.avail_in || !this->lzma.avail_out);
02194   }
02195 
02196   /* virtual */ void Write(byte *buf, size_t size)
02197   {
02198     this->WriteLoop(buf, size, LZMA_RUN);
02199   }
02200 
02201   /* virtual */ void Finish()
02202   {
02203     this->WriteLoop(NULL, 0, LZMA_FINISH);
02204     this->chain->Finish();
02205   }
02206 };
02207 
02208 #endif /* WITH_LZMA */
02209 
02210 /*******************************************
02211  ************* END OF CODE *****************
02212  *******************************************/
02213 
02215 struct SaveLoadFormat {
02216   const char *name;                     
02217   uint32 tag;                           
02218 
02219   LoadFilter *(*init_load)(LoadFilter *chain);                    
02220   SaveFilter *(*init_write)(SaveFilter *chain, byte compression); 
02221 
02222   byte min_compression;                 
02223   byte default_compression;             
02224   byte max_compression;                 
02225 };
02226 
02228 static const SaveLoadFormat _saveload_formats[] = {
02229 #if defined(WITH_LZO)
02230   /* Roughly 75% larger than zlib level 6 at only ~7% of the CPU usage. */
02231   {"lzo",    TO_BE32X('OTTD'), CreateLoadFilter<LZOLoadFilter>,    CreateSaveFilter<LZOSaveFilter>,    0, 0, 0},
02232 #else
02233   {"lzo",    TO_BE32X('OTTD'), NULL,                               NULL,                               0, 0, 0},
02234 #endif
02235   /* Roughly 5 times larger at only 1% of the CPU usage over zlib level 6. */
02236   {"none",   TO_BE32X('OTTN'), CreateLoadFilter<NoCompLoadFilter>, CreateSaveFilter<NoCompSaveFilter>, 0, 0, 0},
02237 #if defined(WITH_ZLIB)
02238   /* After level 6 the speed reduction is significant (1.5x to 2.5x slower per level), but the reduction in filesize is
02239    * fairly insignificant (~1% for each step). Lower levels become ~5-10% bigger by each level than level 6 while level
02240    * 1 is "only" 3 times as fast. Level 0 results in uncompressed savegames at about 8 times the cost of "none". */
02241   {"zlib",   TO_BE32X('OTTZ'), CreateLoadFilter<ZlibLoadFilter>,   CreateSaveFilter<ZlibSaveFilter>,   0, 6, 9},
02242 #else
02243   {"zlib",   TO_BE32X('OTTZ'), NULL,                               NULL,                               0, 0, 0},
02244 #endif
02245 #if defined(WITH_LZMA)
02246   /* Level 2 compression is speed wise as fast as zlib level 6 compression (old default), but results in ~10% smaller saves.
02247    * Higher compression levels are possible, and might improve savegame size by up to 25%, but are also up to 10 times slower.
02248    * The next significant reduction in file size is at level 4, but that is already 4 times slower. Level 3 is primarily 50%
02249    * slower while not improving the filesize, while level 0 and 1 are faster, but don't reduce savegame size much.
02250    * It's OTTX and not e.g. OTTL because liblzma is part of xz-utils and .tar.xz is prefered over .tar.lzma. */
02251   {"lzma",   TO_BE32X('OTTX'), CreateLoadFilter<LZMALoadFilter>,   CreateSaveFilter<LZMASaveFilter>,   0, 2, 9},
02252 #else
02253   {"lzma",   TO_BE32X('OTTX'), NULL,                               NULL,                               0, 0, 0},
02254 #endif
02255 };
02256 
02264 static const SaveLoadFormat *GetSavegameFormat(char *s, byte *compression_level)
02265 {
02266   const SaveLoadFormat *def = lastof(_saveload_formats);
02267 
02268   /* find default savegame format, the highest one with which files can be written */
02269   while (!def->init_write) def--;
02270 
02271   if (!StrEmpty(s)) {
02272     /* Get the ":..." of the compression level out of the way */
02273     char *complevel = strrchr(s, ':');
02274     if (complevel != NULL) *complevel = '\0';
02275 
02276     for (const SaveLoadFormat *slf = &_saveload_formats[0]; slf != endof(_saveload_formats); slf++) {
02277       if (slf->init_write != NULL && strcmp(s, slf->name) == 0) {
02278         *compression_level = slf->default_compression;
02279         if (complevel != NULL) {
02280           /* There is a compression level in the string.
02281            * First restore the : we removed to do proper name matching,
02282            * then move the the begin of the actual version. */
02283           *complevel = ':';
02284           complevel++;
02285 
02286           /* Get the version and determine whether all went fine. */
02287           char *end;
02288           long level = strtol(complevel, &end, 10);
02289           if (end == complevel || level != Clamp(level, slf->min_compression, slf->max_compression)) {
02290             ShowInfoF("Compression level '%s' is not valid.", complevel);
02291           } else {
02292             *compression_level = level;
02293           }
02294         }
02295         return slf;
02296       }
02297     }
02298 
02299     ShowInfoF("Savegame format '%s' is not available. Reverting to '%s'.", s, def->name);
02300 
02301     /* Restore the string by adding the : back */
02302     if (complevel != NULL) *complevel = ':';
02303   }
02304   *compression_level = def->default_compression;
02305   return def;
02306 }
02307 
02308 /* actual loader/saver function */
02309 void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settings);
02310 extern bool AfterLoadGame();
02311 extern bool LoadOldSaveGame(const char *file);
02312 
02316 static inline void ClearSaveLoadState()
02317 {
02318   delete _sl.dumper;
02319   _sl.dumper = NULL;
02320 
02321   delete _sl.sf;
02322   _sl.sf = NULL;
02323 
02324   delete _sl.reader;
02325   _sl.reader = NULL;
02326 
02327   delete _sl.lf;
02328   _sl.lf = NULL;
02329 }
02330 
02336 static void SaveFileStart()
02337 {
02338   _sl.ff_state = _fast_forward;
02339   _fast_forward = 0;
02340   if (_cursor.sprite == SPR_CURSOR_MOUSE) SetMouseCursor(SPR_CURSOR_ZZZ, PAL_NONE);
02341 
02342   InvalidateWindowData(WC_STATUS_BAR, 0, SBI_SAVELOAD_START);
02343   _sl.saveinprogress = true;
02344 }
02345 
02347 static void SaveFileDone()
02348 {
02349   if (_game_mode != GM_MENU) _fast_forward = _sl.ff_state;
02350   if (_cursor.sprite == SPR_CURSOR_ZZZ) SetMouseCursor(SPR_CURSOR_MOUSE, PAL_NONE);
02351 
02352   InvalidateWindowData(WC_STATUS_BAR, 0, SBI_SAVELOAD_FINISH);
02353   _sl.saveinprogress = false;
02354 }
02355 
02357 void SetSaveLoadError(StringID str)
02358 {
02359   _sl.error_str = str;
02360 }
02361 
02363 const char *GetSaveLoadErrorString()
02364 {
02365   SetDParam(0, _sl.error_str);
02366   SetDParamStr(1, _sl.extra_msg);
02367 
02368   static char err_str[512];
02369   GetString(err_str, _sl.action == SLA_SAVE ? STR_ERROR_GAME_SAVE_FAILED : STR_ERROR_GAME_LOAD_FAILED, lastof(err_str));
02370   return err_str;
02371 }
02372 
02374 static void SaveFileError()
02375 {
02376   SetDParamStr(0, GetSaveLoadErrorString());
02377   ShowErrorMessage(STR_JUST_RAW_STRING, INVALID_STRING_ID, WL_ERROR);
02378   SaveFileDone();
02379 }
02380 
02385 static SaveOrLoadResult SaveFileToDisk(bool threaded)
02386 {
02387   try {
02388     byte compression;
02389     const SaveLoadFormat *fmt = GetSavegameFormat(_savegame_format, &compression);
02390 
02391     /* We have written our stuff to memory, now write it to file! */
02392     uint32 hdr[2] = { fmt->tag, TO_BE32(SAVEGAME_VERSION << 16) };
02393     _sl.sf->Write((byte*)hdr, sizeof(hdr));
02394 
02395     _sl.sf = fmt->init_write(_sl.sf, compression);
02396     _sl.dumper->Flush(_sl.sf);
02397 
02398     ClearSaveLoadState();
02399 
02400     if (threaded) SetAsyncSaveFinish(SaveFileDone);
02401 
02402     return SL_OK;
02403   } catch (...) {
02404     ClearSaveLoadState();
02405 
02406     AsyncSaveFinishProc asfp = SaveFileDone;
02407 
02408     /* We don't want to shout when saving is just
02409      * cancelled due to a client disconnecting. */
02410     if (_sl.error_str != STR_NETWORK_ERROR_LOSTCONNECTION) {
02411       /* Skip the "colour" character */
02412       DEBUG(sl, 0, "%s", GetSaveLoadErrorString() + 3);
02413       asfp = SaveFileError;
02414     }
02415 
02416     if (threaded) {
02417       SetAsyncSaveFinish(asfp);
02418     } else {
02419       asfp();
02420     }
02421     return SL_ERROR;
02422   }
02423 }
02424 
02426 static void SaveFileToDiskThread(void *arg)
02427 {
02428   SaveFileToDisk(true);
02429 }
02430 
02431 void WaitTillSaved()
02432 {
02433   if (_save_thread == NULL) return;
02434 
02435   _save_thread->Join();
02436   delete _save_thread;
02437   _save_thread = NULL;
02438 
02439   /* Make sure every other state is handled properly as well. */
02440   ProcessAsyncSaveFinish();
02441 }
02442 
02451 static SaveOrLoadResult DoSave(SaveFilter *writer, bool threaded)
02452 {
02453   assert(!_sl.saveinprogress);
02454 
02455   _sl.dumper = new MemoryDumper();
02456   _sl.sf = writer;
02457 
02458   _sl_version = SAVEGAME_VERSION;
02459 
02460   SaveViewportBeforeSaveGame();
02461   SlSaveChunks();
02462 
02463   SaveFileStart();
02464   if (!threaded || !ThreadObject::New(&SaveFileToDiskThread, NULL, &_save_thread)) {
02465     if (threaded) DEBUG(sl, 1, "Cannot create savegame thread, reverting to single-threaded mode...");
02466 
02467     SaveOrLoadResult result = SaveFileToDisk(false);
02468     SaveFileDone();
02469 
02470     return result;
02471   }
02472 
02473   return SL_OK;
02474 }
02475 
02482 SaveOrLoadResult SaveWithFilter(SaveFilter *writer, bool threaded)
02483 {
02484   try {
02485     _sl.action = SLA_SAVE;
02486     return DoSave(writer, threaded);
02487   } catch (...) {
02488     ClearSaveLoadState();
02489     return SL_ERROR;
02490   }
02491 }
02492 
02499 static SaveOrLoadResult DoLoad(LoadFilter *reader, bool load_check)
02500 {
02501   _sl.lf = reader;
02502 
02503   if (load_check) {
02504     /* Clear previous check data */
02505     _load_check_data.Clear();
02506     /* Mark SL_LOAD_CHECK as supported for this savegame. */
02507     _load_check_data.checkable = true;
02508   }
02509 
02510   uint32 hdr[2];
02511   if (_sl.lf->Read((byte*)hdr, sizeof(hdr)) != sizeof(hdr)) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
02512 
02513   /* see if we have any loader for this type. */
02514   const SaveLoadFormat *fmt = _saveload_formats;
02515   for (;;) {
02516     /* No loader found, treat as version 0 and use LZO format */
02517     if (fmt == endof(_saveload_formats)) {
02518       DEBUG(sl, 0, "Unknown savegame type, trying to load it as the buggy format");
02519       _sl.lf->Reset();
02520       _sl_version = 0;
02521       _sl_minor_version = 0;
02522 
02523       /* Try to find the LZO savegame format; it uses 'OTTD' as tag. */
02524       fmt = _saveload_formats;
02525       for (;;) {
02526         if (fmt == endof(_saveload_formats)) {
02527           /* Who removed LZO support? Bad bad boy! */
02528           NOT_REACHED();
02529         }
02530         if (fmt->tag == TO_BE32X('OTTD')) break;
02531         fmt++;
02532       }
02533       break;
02534     }
02535 
02536     if (fmt->tag == hdr[0]) {
02537       /* check version number */
02538       _sl_version = TO_BE32(hdr[1]) >> 16;
02539       /* Minor is not used anymore from version 18.0, but it is still needed
02540        * in versions before that (4 cases) which can't be removed easy.
02541        * Therefor it is loaded, but never saved (or, it saves a 0 in any scenario). */
02542       _sl_minor_version = (TO_BE32(hdr[1]) >> 8) & 0xFF;
02543 
02544       DEBUG(sl, 1, "Loading savegame version %d", _sl_version);
02545 
02546       /* Is the version higher than the current? */
02547       if (_sl_version > SAVEGAME_VERSION) SlError(STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME);
02548       break;
02549     }
02550 
02551     fmt++;
02552   }
02553 
02554   /* loader for this savegame type is not implemented? */
02555   if (fmt->init_load == NULL) {
02556     char err_str[64];
02557     snprintf(err_str, lengthof(err_str), "Loader for '%s' is not available.", fmt->name);
02558     SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, err_str);
02559   }
02560 
02561   _sl.lf = fmt->init_load(_sl.lf);
02562   _sl.reader = new ReadBuffer(_sl.lf);
02563   _next_offs = 0;
02564 
02565   if (!load_check) {
02566     /* Old maps were hardcoded to 256x256 and thus did not contain
02567      * any mapsize information. Pre-initialize to 256x256 to not to
02568      * confuse old games */
02569     InitializeGame(256, 256, true, true);
02570 
02571     GamelogReset();
02572 
02573     if (IsSavegameVersionBefore(4)) {
02574       /*
02575        * NewGRFs were introduced between 0.3,4 and 0.3.5, which both
02576        * shared savegame version 4. Anything before that 'obviously'
02577        * does not have any NewGRFs. Between the introduction and
02578        * savegame version 41 (just before 0.5) the NewGRF settings
02579        * were not stored in the savegame and they were loaded by
02580        * using the settings from the main menu.
02581        * So, to recap:
02582        * - savegame version  <  4:  do not load any NewGRFs.
02583        * - savegame version >= 41:  load NewGRFs from savegame, which is
02584        *                            already done at this stage by
02585        *                            overwriting the main menu settings.
02586        * - other savegame versions: use main menu settings.
02587        *
02588        * This means that users *can* crash savegame version 4..40
02589        * savegames if they set incompatible NewGRFs in the main menu,
02590        * but can't crash anymore for savegame version < 4 savegames.
02591        *
02592        * Note: this is done here because AfterLoadGame is also called
02593        * for TTO/TTD/TTDP savegames which have their own NewGRF logic.
02594        */
02595       ClearGRFConfigList(&_grfconfig);
02596     }
02597   }
02598 
02599   if (load_check) {
02600     /* Load chunks into _load_check_data.
02601      * No pools are loaded. References are not possible, and thus do not need resolving. */
02602     SlLoadCheckChunks();
02603   } else {
02604     /* Load chunks and resolve references */
02605     SlLoadChunks();
02606     SlFixPointers();
02607   }
02608 
02609   ClearSaveLoadState();
02610 
02611   _savegame_type = SGT_OTTD;
02612 
02613   if (load_check) {
02614     /* The only part from AfterLoadGame() we need */
02615     _load_check_data.grf_compatibility = IsGoodGRFConfigList(_load_check_data.grfconfig);
02616   } else {
02617     GamelogStartAction(GLAT_LOAD);
02618 
02619     /* After loading fix up savegame for any internal changes that
02620      * might have occurred since then. If it fails, load back the old game. */
02621     if (!AfterLoadGame()) {
02622       GamelogStopAction();
02623       return SL_REINIT;
02624     }
02625 
02626     GamelogStopAction();
02627   }
02628 
02629   return SL_OK;
02630 }
02631 
02637 SaveOrLoadResult LoadWithFilter(LoadFilter *reader)
02638 {
02639   try {
02640     _sl.action = SLA_LOAD;
02641     return DoLoad(reader, false);
02642   } catch (...) {
02643     ClearSaveLoadState();
02644     return SL_REINIT;
02645   }
02646 }
02647 
02657 SaveOrLoadResult SaveOrLoad(const char *filename, int mode, Subdirectory sb, bool threaded)
02658 {
02659   /* An instance of saving is already active, so don't go saving again */
02660   if (_sl.saveinprogress && mode == SL_SAVE && threaded) {
02661     /* if not an autosave, but a user action, show error message */
02662     if (!_do_autosave) ShowErrorMessage(STR_ERROR_SAVE_STILL_IN_PROGRESS, INVALID_STRING_ID, WL_ERROR);
02663     return SL_OK;
02664   }
02665   WaitTillSaved();
02666 
02667   /* Load a TTDLX or TTDPatch game */
02668   if (mode == SL_OLD_LOAD) {
02669     InitializeGame(256, 256, true, true); // set a mapsize of 256x256 for TTDPatch games or it might get confused
02670 
02671     /* TTD/TTO savegames have no NewGRFs, TTDP savegame have them
02672      * and if so a new NewGRF list will be made in LoadOldSaveGame.
02673      * Note: this is done here because AfterLoadGame is also called
02674      * for OTTD savegames which have their own NewGRF logic. */
02675     ClearGRFConfigList(&_grfconfig);
02676     GamelogReset();
02677     if (!LoadOldSaveGame(filename)) return SL_REINIT;
02678     _sl_version = 0;
02679     _sl_minor_version = 0;
02680     GamelogStartAction(GLAT_LOAD);
02681     if (!AfterLoadGame()) {
02682       GamelogStopAction();
02683       return SL_REINIT;
02684     }
02685     GamelogStopAction();
02686     return SL_OK;
02687   }
02688 
02689   switch (mode) {
02690     case SL_LOAD_CHECK: _sl.action = SLA_LOAD_CHECK; break;
02691     case SL_LOAD: _sl.action = SLA_LOAD; break;
02692     case SL_SAVE: _sl.action = SLA_SAVE; break;
02693     default: NOT_REACHED();
02694   }
02695 
02696   try {
02697     FILE *fh = (mode == SL_SAVE) ? FioFOpenFile(filename, "wb", sb) : FioFOpenFile(filename, "rb", sb);
02698 
02699     /* Make it a little easier to load savegames from the console */
02700     if (fh == NULL && mode != SL_SAVE) fh = FioFOpenFile(filename, "rb", SAVE_DIR);
02701     if (fh == NULL && mode != SL_SAVE) fh = FioFOpenFile(filename, "rb", BASE_DIR);
02702 
02703     if (fh == NULL) {
02704       SlError(mode == SL_SAVE ? STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE : STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
02705     }
02706 
02707     if (mode == SL_SAVE) { // SAVE game
02708       DEBUG(desync, 1, "save: %08x; %02x; %s", _date, _date_fract, filename);
02709       if (_network_server || !_settings_client.gui.threaded_saves) threaded = false;
02710 
02711       return DoSave(new FileWriter(fh), threaded);
02712     }
02713 
02714     /* LOAD game */
02715     assert(mode == SL_LOAD || mode == SL_LOAD_CHECK);
02716     DEBUG(desync, 1, "load: %s", filename);
02717     return DoLoad(new FileReader(fh), mode == SL_LOAD_CHECK);
02718   } catch (...) {
02719     ClearSaveLoadState();
02720 
02721     /* Skip the "colour" character */
02722     if (mode != SL_LOAD_CHECK) DEBUG(sl, 0, "%s", GetSaveLoadErrorString() + 3);
02723 
02724     /* A saver/loader exception!! reinitialize all variables to prevent crash! */
02725     return (mode == SL_LOAD) ? SL_REINIT : SL_ERROR;
02726   }
02727 }
02728 
02730 void DoExitSave()
02731 {
02732   SaveOrLoad("exit.sav", SL_SAVE, AUTOSAVE_DIR);
02733 }
02734 
02740 void GenerateDefaultSaveName(char *buf, const char *last)
02741 {
02742   /* Check if we have a name for this map, which is the name of the first
02743    * available company. When there's no company available we'll use
02744    * 'Spectator' as "company" name. */
02745   CompanyID cid = _local_company;
02746   if (!Company::IsValidID(cid)) {
02747     const Company *c;
02748     FOR_ALL_COMPANIES(c) {
02749       cid = c->index;
02750       break;
02751     }
02752   }
02753 
02754   SetDParam(0, cid);
02755 
02756   /* Insert current date */
02757   switch (_settings_client.gui.date_format_in_default_names) {
02758     case 0: SetDParam(1, STR_JUST_DATE_LONG); break;
02759     case 1: SetDParam(1, STR_JUST_DATE_TINY); break;
02760     case 2: SetDParam(1, STR_JUST_DATE_ISO); break;
02761     default: NOT_REACHED();
02762   }
02763   SetDParam(2, _date);
02764 
02765   /* Get the correct string (special string for when there's not company) */
02766   GetString(buf, !Company::IsValidID(cid) ? STR_SAVEGAME_NAME_SPECTATOR : STR_SAVEGAME_NAME_DEFAULT, last);
02767   SanitizeFilename(buf);
02768 }
02769 
02770 #if 0
02771 
02777 int GetSavegameType(char *file)
02778 {
02779   const SaveLoadFormat *fmt;
02780   uint32 hdr;
02781   FILE *f;
02782   int mode = SL_OLD_LOAD;
02783 
02784   f = fopen(file, "rb");
02785   if (fread(&hdr, sizeof(hdr), 1, f) != 1) {
02786     DEBUG(sl, 0, "Savegame is obsolete or invalid format");
02787     mode = SL_LOAD; // don't try to get filename, just show name as it is written
02788   } else {
02789     /* see if we have any loader for this type. */
02790     for (fmt = _saveload_formats; fmt != endof(_saveload_formats); fmt++) {
02791       if (fmt->tag == hdr) {
02792         mode = SL_LOAD; // new type of savegame
02793         break;
02794       }
02795     }
02796   }
02797 
02798   fclose(f);
02799   return mode;
02800 }
02801 #endif