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 "../error.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  *  167   23504
00235  */
00236 extern const uint16 SAVEGAME_VERSION = SL_EXT_RATING; 
00237 
00238 SavegameType _savegame_type; 
00239 
00240 uint32 _ttdp_version;     
00241 uint16 _sl_version;       
00242 byte   _sl_minor_version; 
00243 char _savegame_format[8]; 
00244 bool _do_autosave;        
00245 
00247 enum SaveLoadAction {
00248   SLA_LOAD,        
00249   SLA_SAVE,        
00250   SLA_PTRS,        
00251   SLA_NULL,        
00252   SLA_LOAD_CHECK,  
00253 };
00254 
00255 enum NeedLength {
00256   NL_NONE = 0,       
00257   NL_WANTLENGTH = 1, 
00258   NL_CALCLENGTH = 2, 
00259 };
00260 
00262 static const size_t MEMORY_CHUNK_SIZE = 128 * 1024;
00263 
00265 struct ReadBuffer {
00266   byte buf[MEMORY_CHUNK_SIZE]; 
00267   byte *bufp;                  
00268   byte *bufe;                  
00269   LoadFilter *reader;          
00270   size_t read;                 
00271 
00276   ReadBuffer(LoadFilter *reader) : bufp(NULL), bufe(NULL), reader(reader), read(0)
00277   {
00278   }
00279 
00280   FORCEINLINE byte ReadByte()
00281   {
00282     if (this->bufp == this->bufe) {
00283       size_t len = this->reader->Read(this->buf, lengthof(this->buf));
00284       if (len == 0) SlErrorCorrupt("Unexpected end of chunk");
00285 
00286       this->read += len;
00287       this->bufp = this->buf;
00288       this->bufe = this->buf + len;
00289     }
00290 
00291     return *this->bufp++;
00292   }
00293 
00298   size_t GetSize() const
00299   {
00300     return this->read - (this->bufe - this->bufp);
00301   }
00302 };
00303 
00304 
00306 struct MemoryDumper {
00307   AutoFreeSmallVector<byte *, 16> blocks; 
00308   byte *buf;                              
00309   byte *bufe;                             
00310 
00312   MemoryDumper() : buf(NULL), bufe(NULL)
00313   {
00314   }
00315 
00320   FORCEINLINE void WriteByte(byte b)
00321   {
00322     /* Are we at the end of this chunk? */
00323     if (this->buf == this->bufe) {
00324       this->buf = CallocT<byte>(MEMORY_CHUNK_SIZE);
00325       *this->blocks.Append() = this->buf;
00326       this->bufe = this->buf + MEMORY_CHUNK_SIZE;
00327     }
00328 
00329     *this->buf++ = b;
00330   }
00331 
00336   void Flush(SaveFilter *writer)
00337   {
00338     uint i = 0;
00339     size_t t = this->GetSize();
00340 
00341     while (t > 0) {
00342       size_t to_write = min(MEMORY_CHUNK_SIZE, t);
00343 
00344       writer->Write(this->blocks[i++], to_write);
00345       t -= to_write;
00346     }
00347 
00348     writer->Finish();
00349   }
00350 
00355   size_t GetSize() const
00356   {
00357     return this->blocks.Length() * MEMORY_CHUNK_SIZE - (this->bufe - this->buf);
00358   }
00359 };
00360 
00362 struct SaveLoadParams {
00363   SaveLoadAction action;               
00364   NeedLength need_length;              
00365   byte block_mode;                     
00366   bool error;                          
00367 
00368   size_t obj_len;                      
00369   int array_index, last_array_index;   
00370 
00371   MemoryDumper *dumper;                
00372   SaveFilter *sf;                      
00373 
00374   ReadBuffer *reader;                  
00375   LoadFilter *lf;                      
00376 
00377   StringID error_str;                  
00378   char *extra_msg;                     
00379 
00380   byte ff_state;                       
00381   bool saveinprogress;                 
00382 };
00383 
00384 static SaveLoadParams _sl; 
00385 
00386 /* these define the chunks */
00387 extern const ChunkHandler _gamelog_chunk_handlers[];
00388 extern const ChunkHandler _map_chunk_handlers[];
00389 extern const ChunkHandler _misc_chunk_handlers[];
00390 extern const ChunkHandler _name_chunk_handlers[];
00391 extern const ChunkHandler _cheat_chunk_handlers[] ;
00392 extern const ChunkHandler _setting_chunk_handlers[];
00393 extern const ChunkHandler _company_chunk_handlers[];
00394 extern const ChunkHandler _engine_chunk_handlers[];
00395 extern const ChunkHandler _veh_chunk_handlers[];
00396 extern const ChunkHandler _waypoint_chunk_handlers[];
00397 extern const ChunkHandler _depot_chunk_handlers[];
00398 extern const ChunkHandler _order_chunk_handlers[];
00399 extern const ChunkHandler _town_chunk_handlers[];
00400 extern const ChunkHandler _sign_chunk_handlers[];
00401 extern const ChunkHandler _station_chunk_handlers[];
00402 extern const ChunkHandler _industry_chunk_handlers[];
00403 extern const ChunkHandler _economy_chunk_handlers[];
00404 extern const ChunkHandler _subsidy_chunk_handlers[];
00405 extern const ChunkHandler _ai_chunk_handlers[];
00406 extern const ChunkHandler _animated_tile_chunk_handlers[];
00407 extern const ChunkHandler _newgrf_chunk_handlers[];
00408 extern const ChunkHandler _group_chunk_handlers[];
00409 extern const ChunkHandler _cargopacket_chunk_handlers[];
00410 extern const ChunkHandler _autoreplace_chunk_handlers[];
00411 extern const ChunkHandler _labelmaps_chunk_handlers[];
00412 extern const ChunkHandler _linkgraph_chunk_handlers[];
00413 extern const ChunkHandler _airport_chunk_handlers[];
00414 extern const ChunkHandler _object_chunk_handlers[];
00415 extern const ChunkHandler _persistent_storage_chunk_handlers[];
00416 
00418 static const ChunkHandler * const _chunk_handlers[] = {
00419   _gamelog_chunk_handlers,
00420   _map_chunk_handlers,
00421   _misc_chunk_handlers,
00422   _name_chunk_handlers,
00423   _cheat_chunk_handlers,
00424   _setting_chunk_handlers,
00425   _veh_chunk_handlers,
00426   _waypoint_chunk_handlers,
00427   _depot_chunk_handlers,
00428   _order_chunk_handlers,
00429   _industry_chunk_handlers,
00430   _economy_chunk_handlers,
00431   _subsidy_chunk_handlers,
00432   _engine_chunk_handlers,
00433   _town_chunk_handlers,
00434   _sign_chunk_handlers,
00435   _station_chunk_handlers,
00436   _company_chunk_handlers,
00437   _ai_chunk_handlers,
00438   _animated_tile_chunk_handlers,
00439   _newgrf_chunk_handlers,
00440   _group_chunk_handlers,
00441   _cargopacket_chunk_handlers,
00442   _autoreplace_chunk_handlers,
00443   _labelmaps_chunk_handlers,
00444   _linkgraph_chunk_handlers,
00445   _airport_chunk_handlers,
00446   _object_chunk_handlers,
00447   _persistent_storage_chunk_handlers,
00448   NULL,
00449 };
00450 
00455 #define FOR_ALL_CHUNK_HANDLERS(ch) \
00456   for (const ChunkHandler * const *chsc = _chunk_handlers; *chsc != NULL; chsc++) \
00457     for (const ChunkHandler *ch = *chsc; ch != NULL; ch = (ch->flags & CH_LAST) ? NULL : ch + 1)
00458 
00460 static void SlNullPointers()
00461 {
00462   _sl.action = SLA_NULL;
00463 
00464   /* We don't want any savegame conversion code to run
00465    * during NULLing; especially those that try to get
00466    * pointers from other pools. */
00467   _sl_version = SAVEGAME_VERSION;
00468 
00469   DEBUG(sl, 1, "Nulling pointers");
00470 
00471   FOR_ALL_CHUNK_HANDLERS(ch) {
00472     if (ch->ptrs_proc != NULL) {
00473       DEBUG(sl, 2, "Nulling pointers for %c%c%c%c", ch->id >> 24, ch->id >> 16, ch->id >> 8, ch->id);
00474       ch->ptrs_proc();
00475     }
00476   }
00477 
00478   DEBUG(sl, 1, "All pointers nulled");
00479 
00480   assert(_sl.action == SLA_NULL);
00481 }
00482 
00491 void NORETURN SlError(StringID string, const char *extra_msg)
00492 {
00493   /* Distinguish between loading into _load_check_data vs. normal save/load. */
00494   if (_sl.action == SLA_LOAD_CHECK) {
00495     _load_check_data.error = string;
00496     free(_load_check_data.error_data);
00497     _load_check_data.error_data = (extra_msg == NULL) ? NULL : strdup(extra_msg);
00498   } else {
00499     _sl.error_str = string;
00500     free(_sl.extra_msg);
00501     _sl.extra_msg = (extra_msg == NULL) ? NULL : strdup(extra_msg);
00502   }
00503 
00504   /* We have to NULL all pointers here; we might be in a state where
00505    * the pointers are actually filled with indices, which means that
00506    * when we access them during cleaning the pool dereferences of
00507    * those indices will be made with segmentation faults as result. */
00508   if (_sl.action == SLA_LOAD || _sl.action == SLA_PTRS) SlNullPointers();
00509   throw std::exception();
00510 }
00511 
00519 void NORETURN SlErrorCorrupt(const char *msg)
00520 {
00521   SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, msg);
00522 }
00523 
00524 
00525 typedef void (*AsyncSaveFinishProc)();                
00526 static AsyncSaveFinishProc _async_save_finish = NULL; 
00527 static ThreadObject *_save_thread;                    
00528 
00533 static void SetAsyncSaveFinish(AsyncSaveFinishProc proc)
00534 {
00535   if (_exit_game) return;
00536   while (_async_save_finish != NULL) CSleep(10);
00537 
00538   _async_save_finish = proc;
00539 }
00540 
00544 void ProcessAsyncSaveFinish()
00545 {
00546   if (_async_save_finish == NULL) return;
00547 
00548   _async_save_finish();
00549 
00550   _async_save_finish = NULL;
00551 
00552   if (_save_thread != NULL) {
00553     _save_thread->Join();
00554     delete _save_thread;
00555     _save_thread = NULL;
00556   }
00557 }
00558 
00563 byte SlReadByte()
00564 {
00565   return _sl.reader->ReadByte();
00566 }
00567 
00572 void SlWriteByte(byte b)
00573 {
00574   _sl.dumper->WriteByte(b);
00575 }
00576 
00577 static inline int SlReadUint16()
00578 {
00579   int x = SlReadByte() << 8;
00580   return x | SlReadByte();
00581 }
00582 
00583 static inline uint32 SlReadUint32()
00584 {
00585   uint32 x = SlReadUint16() << 16;
00586   return x | SlReadUint16();
00587 }
00588 
00589 static inline uint64 SlReadUint64()
00590 {
00591   uint32 x = SlReadUint32();
00592   uint32 y = SlReadUint32();
00593   return (uint64)x << 32 | y;
00594 }
00595 
00596 static inline void SlWriteUint16(uint16 v)
00597 {
00598   SlWriteByte(GB(v, 8, 8));
00599   SlWriteByte(GB(v, 0, 8));
00600 }
00601 
00602 static inline void SlWriteUint32(uint32 v)
00603 {
00604   SlWriteUint16(GB(v, 16, 16));
00605   SlWriteUint16(GB(v,  0, 16));
00606 }
00607 
00608 static inline void SlWriteUint64(uint64 x)
00609 {
00610   SlWriteUint32((uint32)(x >> 32));
00611   SlWriteUint32((uint32)x);
00612 }
00613 
00619 static inline void SlSkipBytes(size_t length)
00620 {
00621   for (; length != 0; length--) SlReadByte();
00622 }
00623 
00633 static uint SlReadSimpleGamma()
00634 {
00635   uint i = SlReadByte();
00636   if (HasBit(i, 7)) {
00637     i &= ~0x80;
00638     if (HasBit(i, 6)) {
00639       i &= ~0x40;
00640       if (HasBit(i, 5)) {
00641         i &= ~0x20;
00642         if (HasBit(i, 4)) {
00643           SlErrorCorrupt("Unsupported gamma");
00644         }
00645         i = (i << 8) | SlReadByte();
00646       }
00647       i = (i << 8) | SlReadByte();
00648     }
00649     i = (i << 8) | SlReadByte();
00650   }
00651   return i;
00652 }
00653 
00666 static void SlWriteSimpleGamma(size_t i)
00667 {
00668   if (i >= (1 << 7)) {
00669     if (i >= (1 << 14)) {
00670       if (i >= (1 << 21)) {
00671         assert(i < (1 << 28));
00672         SlWriteByte((byte)(0xE0 | (i >> 24)));
00673         SlWriteByte((byte)(i >> 16));
00674       } else {
00675         SlWriteByte((byte)(0xC0 | (i >> 16)));
00676       }
00677       SlWriteByte((byte)(i >> 8));
00678     } else {
00679       SlWriteByte((byte)(0x80 | (i >> 8)));
00680     }
00681   }
00682   SlWriteByte((byte)i);
00683 }
00684 
00686 static inline uint SlGetGammaLength(size_t i)
00687 {
00688   return 1 + (i >= (1 << 7)) + (i >= (1 << 14)) + (i >= (1 << 21));
00689 }
00690 
00691 static inline uint SlReadSparseIndex()
00692 {
00693   return SlReadSimpleGamma();
00694 }
00695 
00696 static inline void SlWriteSparseIndex(uint index)
00697 {
00698   SlWriteSimpleGamma(index);
00699 }
00700 
00701 static inline uint SlReadArrayLength()
00702 {
00703   return SlReadSimpleGamma();
00704 }
00705 
00706 static inline void SlWriteArrayLength(size_t length)
00707 {
00708   SlWriteSimpleGamma(length);
00709 }
00710 
00711 static inline uint SlGetArrayLength(size_t length)
00712 {
00713   return SlGetGammaLength(length);
00714 }
00715 
00722 static inline uint SlCalcConvMemLen(VarType conv)
00723 {
00724   static const byte conv_mem_size[] = {1, 1, 1, 2, 2, 4, 4, 8, 8, 0};
00725   byte length = GB(conv, 4, 4);
00726 
00727   switch (length << 4) {
00728     case SLE_VAR_STRB:
00729     case SLE_VAR_STRBQ:
00730     case SLE_VAR_STR:
00731     case SLE_VAR_STRQ:
00732       return SlReadArrayLength();
00733 
00734     default:
00735       assert(length < lengthof(conv_mem_size));
00736       return conv_mem_size[length];
00737   }
00738 }
00739 
00746 static inline byte SlCalcConvFileLen(VarType conv)
00747 {
00748   static const byte conv_file_size[] = {1, 1, 2, 2, 4, 4, 8, 8, 2};
00749   byte length = GB(conv, 0, 4);
00750   assert(length < lengthof(conv_file_size));
00751   return conv_file_size[length];
00752 }
00753 
00755 static inline size_t SlCalcRefLen()
00756 {
00757   return IsSavegameVersionBefore(69) ? 2 : 4;
00758 }
00759 
00760 void SlSetArrayIndex(uint index)
00761 {
00762   _sl.need_length = NL_WANTLENGTH;
00763   _sl.array_index = index;
00764 }
00765 
00766 static size_t _next_offs;
00767 
00772 int SlIterateArray()
00773 {
00774   int index;
00775 
00776   /* After reading in the whole array inside the loop
00777    * we must have read in all the data, so we must be at end of current block. */
00778   if (_next_offs != 0 && _sl.reader->GetSize() != _next_offs) SlErrorCorrupt("Invalid chunk size");
00779 
00780   for (;;) {
00781     uint length = SlReadArrayLength();
00782     if (length == 0) {
00783       _next_offs = 0;
00784       return -1;
00785     }
00786 
00787     _sl.obj_len = --length;
00788     _next_offs = _sl.reader->GetSize() + length;
00789 
00790     switch (_sl.block_mode) {
00791       case CH_SPARSE_ARRAY: index = (int)SlReadSparseIndex(); break;
00792       case CH_ARRAY:        index = _sl.array_index++; break;
00793       default:
00794         DEBUG(sl, 0, "SlIterateArray error");
00795         return -1; // error
00796     }
00797 
00798     if (length != 0) return index;
00799   }
00800 }
00801 
00805 void SlSkipArray()
00806 {
00807   while (SlIterateArray() != -1) {
00808     SlSkipBytes(_next_offs - _sl.reader->GetSize());
00809   }
00810 }
00811 
00817 void SlSetLength(size_t length)
00818 {
00819   assert(_sl.action == SLA_SAVE);
00820 
00821   switch (_sl.need_length) {
00822     case NL_WANTLENGTH:
00823       _sl.need_length = NL_NONE;
00824       switch (_sl.block_mode) {
00825         case CH_RIFF:
00826           /* Ugly encoding of >16M RIFF chunks
00827            * The lower 24 bits are normal
00828            * The uppermost 4 bits are bits 24:27 */
00829           assert(length < (1 << 28));
00830           SlWriteUint32((uint32)((length & 0xFFFFFF) | ((length >> 24) << 28)));
00831           break;
00832         case CH_ARRAY:
00833           assert(_sl.last_array_index <= _sl.array_index);
00834           while (++_sl.last_array_index <= _sl.array_index) {
00835             SlWriteArrayLength(1);
00836           }
00837           SlWriteArrayLength(length + 1);
00838           break;
00839         case CH_SPARSE_ARRAY:
00840           SlWriteArrayLength(length + 1 + SlGetArrayLength(_sl.array_index)); // Also include length of sparse index.
00841           SlWriteSparseIndex(_sl.array_index);
00842           break;
00843         default: NOT_REACHED();
00844       }
00845       break;
00846 
00847     case NL_CALCLENGTH:
00848       _sl.obj_len += (int)length;
00849       break;
00850 
00851     default: NOT_REACHED();
00852   }
00853 }
00854 
00861 static void SlCopyBytes(void *ptr, size_t length)
00862 {
00863   byte *p = (byte *)ptr;
00864 
00865   switch (_sl.action) {
00866     case SLA_LOAD_CHECK:
00867     case SLA_LOAD:
00868       for (; length != 0; length--) *p++ = SlReadByte();
00869       break;
00870     case SLA_SAVE:
00871       for (; length != 0; length--) SlWriteByte(*p++);
00872       break;
00873     default: NOT_REACHED();
00874   }
00875 }
00876 
00878 size_t SlGetFieldLength()
00879 {
00880   return _sl.obj_len;
00881 }
00882 
00890 int64 ReadValue(const void *ptr, VarType conv)
00891 {
00892   switch (GetVarMemType(conv)) {
00893     case SLE_VAR_BL:  return (*(const bool *)ptr != 0);
00894     case SLE_VAR_I8:  return *(const int8  *)ptr;
00895     case SLE_VAR_U8:  return *(const byte  *)ptr;
00896     case SLE_VAR_I16: return *(const int16 *)ptr;
00897     case SLE_VAR_U16: return *(const uint16*)ptr;
00898     case SLE_VAR_I32: return *(const int32 *)ptr;
00899     case SLE_VAR_U32: return *(const uint32*)ptr;
00900     case SLE_VAR_I64: return *(const int64 *)ptr;
00901     case SLE_VAR_U64: return *(const uint64*)ptr;
00902     case SLE_VAR_NULL:return 0;
00903     default: NOT_REACHED();
00904   }
00905 }
00906 
00914 void WriteValue(void *ptr, VarType conv, int64 val)
00915 {
00916   switch (GetVarMemType(conv)) {
00917     case SLE_VAR_BL:  *(bool  *)ptr = (val != 0);  break;
00918     case SLE_VAR_I8:  *(int8  *)ptr = val; break;
00919     case SLE_VAR_U8:  *(byte  *)ptr = val; break;
00920     case SLE_VAR_I16: *(int16 *)ptr = val; break;
00921     case SLE_VAR_U16: *(uint16*)ptr = val; break;
00922     case SLE_VAR_I32: *(int32 *)ptr = val; break;
00923     case SLE_VAR_U32: *(uint32*)ptr = val; break;
00924     case SLE_VAR_I64: *(int64 *)ptr = val; break;
00925     case SLE_VAR_U64: *(uint64*)ptr = val; break;
00926     case SLE_VAR_NAME: *(char**)ptr = CopyFromOldName(val); break;
00927     case SLE_VAR_NULL: break;
00928     default: NOT_REACHED();
00929   }
00930 }
00931 
00940 static void SlSaveLoadConv(void *ptr, VarType conv)
00941 {
00942   switch (_sl.action) {
00943     case SLA_SAVE: {
00944       int64 x = ReadValue(ptr, conv);
00945 
00946       /* Write the value to the file and check if its value is in the desired range */
00947       switch (GetVarFileType(conv)) {
00948         case SLE_FILE_I8: assert(x >= -128 && x <= 127);     SlWriteByte(x);break;
00949         case SLE_FILE_U8: assert(x >= 0 && x <= 255);        SlWriteByte(x);break;
00950         case SLE_FILE_I16:assert(x >= -32768 && x <= 32767); SlWriteUint16(x);break;
00951         case SLE_FILE_STRINGID:
00952         case SLE_FILE_U16:assert(x >= 0 && x <= 65535);      SlWriteUint16(x);break;
00953         case SLE_FILE_I32:
00954         case SLE_FILE_U32:                                   SlWriteUint32((uint32)x);break;
00955         case SLE_FILE_I64:
00956         case SLE_FILE_U64:                                   SlWriteUint64(x);break;
00957         default: NOT_REACHED();
00958       }
00959       break;
00960     }
00961     case SLA_LOAD_CHECK:
00962     case SLA_LOAD: {
00963       int64 x;
00964       /* Read a value from the file */
00965       switch (GetVarFileType(conv)) {
00966         case SLE_FILE_I8:  x = (int8  )SlReadByte();   break;
00967         case SLE_FILE_U8:  x = (byte  )SlReadByte();   break;
00968         case SLE_FILE_I16: x = (int16 )SlReadUint16(); break;
00969         case SLE_FILE_U16: x = (uint16)SlReadUint16(); break;
00970         case SLE_FILE_I32: x = (int32 )SlReadUint32(); break;
00971         case SLE_FILE_U32: x = (uint32)SlReadUint32(); break;
00972         case SLE_FILE_I64: x = (int64 )SlReadUint64(); break;
00973         case SLE_FILE_U64: x = (uint64)SlReadUint64(); break;
00974         case SLE_FILE_STRINGID: x = RemapOldStringID((uint16)SlReadUint16()); break;
00975         default: NOT_REACHED();
00976       }
00977 
00978       /* Write The value to the struct. These ARE endian safe. */
00979       WriteValue(ptr, conv, x);
00980       break;
00981     }
00982     case SLA_PTRS: break;
00983     case SLA_NULL: break;
00984     default: NOT_REACHED();
00985   }
00986 }
00987 
00997 static inline size_t SlCalcNetStringLen(const char *ptr, size_t length)
00998 {
00999   if (ptr == NULL) return 0;
01000   return min(strlen(ptr), length - 1);
01001 }
01002 
01012 static inline size_t SlCalcStringLen(const void *ptr, size_t length, VarType conv)
01013 {
01014   size_t len;
01015   const char *str;
01016 
01017   switch (GetVarMemType(conv)) {
01018     default: NOT_REACHED();
01019     case SLE_VAR_STR:
01020     case SLE_VAR_STRQ:
01021       str = *(const char * const *)ptr;
01022       len = SIZE_MAX;
01023       break;
01024     case SLE_VAR_STRB:
01025     case SLE_VAR_STRBQ:
01026       str = (const char *)ptr;
01027       len = length;
01028       break;
01029   }
01030 
01031   len = SlCalcNetStringLen(str, len);
01032   return len + SlGetArrayLength(len); // also include the length of the index
01033 }
01034 
01041 static void SlString(void *ptr, size_t length, VarType conv)
01042 {
01043   switch (_sl.action) {
01044     case SLA_SAVE: {
01045       size_t len;
01046       switch (GetVarMemType(conv)) {
01047         default: NOT_REACHED();
01048         case SLE_VAR_STRB:
01049         case SLE_VAR_STRBQ:
01050           len = SlCalcNetStringLen((char *)ptr, length);
01051           break;
01052         case SLE_VAR_STR:
01053         case SLE_VAR_STRQ:
01054           ptr = *(char **)ptr;
01055           len = SlCalcNetStringLen((char *)ptr, SIZE_MAX);
01056           break;
01057       }
01058 
01059       SlWriteArrayLength(len);
01060       SlCopyBytes(ptr, len);
01061       break;
01062     }
01063     case SLA_LOAD_CHECK:
01064     case SLA_LOAD: {
01065       size_t len = SlReadArrayLength();
01066 
01067       switch (GetVarMemType(conv)) {
01068         default: NOT_REACHED();
01069         case SLE_VAR_STRB:
01070         case SLE_VAR_STRBQ:
01071           if (len >= length) {
01072             DEBUG(sl, 1, "String length in savegame is bigger than buffer, truncating");
01073             SlCopyBytes(ptr, length);
01074             SlSkipBytes(len - length);
01075             len = length - 1;
01076           } else {
01077             SlCopyBytes(ptr, len);
01078           }
01079           break;
01080         case SLE_VAR_STR:
01081         case SLE_VAR_STRQ: // Malloc'd string, free previous incarnation, and allocate
01082           free(*(char **)ptr);
01083           if (len == 0) {
01084             *(char **)ptr = NULL;
01085           } else {
01086             *(char **)ptr = MallocT<char>(len + 1); // terminating '\0'
01087             ptr = *(char **)ptr;
01088             SlCopyBytes(ptr, len);
01089           }
01090           break;
01091       }
01092 
01093       ((char *)ptr)[len] = '\0'; // properly terminate the string
01094       str_validate((char *)ptr, (char *)ptr + len);
01095       break;
01096     }
01097     case SLA_PTRS: break;
01098     case SLA_NULL: break;
01099     default: NOT_REACHED();
01100   }
01101 }
01102 
01108 static inline size_t SlCalcArrayLen(size_t length, VarType conv)
01109 {
01110   return SlCalcConvFileLen(conv) * length;
01111 }
01112 
01119 void SlArray(void *array, size_t length, VarType conv)
01120 {
01121   if (_sl.action == SLA_PTRS || _sl.action == SLA_NULL) return;
01122 
01123   /* Automatically calculate the length? */
01124   if (_sl.need_length != NL_NONE) {
01125     SlSetLength(SlCalcArrayLen(length, conv));
01126     /* Determine length only? */
01127     if (_sl.need_length == NL_CALCLENGTH) return;
01128   }
01129 
01130   /* NOTICE - handle some buggy stuff, in really old versions everything was saved
01131    * as a byte-type. So detect this, and adjust array size accordingly */
01132   if (_sl.action != SLA_SAVE && _sl_version == 0) {
01133     /* all arrays except difficulty settings */
01134     if (conv == SLE_INT16 || conv == SLE_UINT16 || conv == SLE_STRINGID ||
01135         conv == SLE_INT32 || conv == SLE_UINT32) {
01136       SlCopyBytes(array, length * SlCalcConvFileLen(conv));
01137       return;
01138     }
01139     /* used for conversion of Money 32bit->64bit */
01140     if (conv == (SLE_FILE_I32 | SLE_VAR_I64)) {
01141       for (uint i = 0; i < length; i++) {
01142         ((int64*)array)[i] = (int32)BSWAP32(SlReadUint32());
01143       }
01144       return;
01145     }
01146   }
01147 
01148   /* If the size of elements is 1 byte both in file and memory, no special
01149    * conversion is needed, use specialized copy-copy function to speed up things */
01150   if (conv == SLE_INT8 || conv == SLE_UINT8) {
01151     SlCopyBytes(array, length);
01152   } else {
01153     byte *a = (byte*)array;
01154     byte mem_size = SlCalcConvMemLen(conv);
01155 
01156     for (; length != 0; length --) {
01157       SlSaveLoadConv(a, conv);
01158       a += mem_size; // get size
01159     }
01160   }
01161 }
01162 
01163 
01174 static size_t ReferenceToInt(const void *obj, SLRefType rt)
01175 {
01176   assert(_sl.action == SLA_SAVE);
01177 
01178   if (obj == NULL) return 0;
01179 
01180   switch (rt) {
01181     case REF_VEHICLE_OLD: // Old vehicles we save as new onces
01182     case REF_VEHICLE:   return ((const  Vehicle*)obj)->index + 1;
01183     case REF_STATION:   return ((const  Station*)obj)->index + 1;
01184     case REF_TOWN:      return ((const     Town*)obj)->index + 1;
01185     case REF_ORDER:     return ((const    Order*)obj)->index + 1;
01186     case REF_ROADSTOPS: return ((const RoadStop*)obj)->index + 1;
01187     case REF_ENGINE_RENEWS: return ((const       EngineRenew*)obj)->index + 1;
01188     case REF_CARGO_PACKET:  return ((const       CargoPacket*)obj)->index + 1;
01189     case REF_ORDERLIST:     return ((const         OrderList*)obj)->index + 1;
01190     case REF_STORAGE:       return ((const PersistentStorage*)obj)->index + 1;
01191     default: NOT_REACHED();
01192   }
01193 }
01194 
01205 static void *IntToReference(size_t index, SLRefType rt)
01206 {
01207   assert_compile(sizeof(size_t) <= sizeof(void *));
01208 
01209   assert(_sl.action == SLA_PTRS);
01210 
01211   /* After version 4.3 REF_VEHICLE_OLD is saved as REF_VEHICLE,
01212    * and should be loaded like that */
01213   if (rt == REF_VEHICLE_OLD && !IsSavegameVersionBefore(4, 4)) {
01214     rt = REF_VEHICLE;
01215   }
01216 
01217   /* No need to look up NULL pointers, just return immediately */
01218   if (index == (rt == REF_VEHICLE_OLD ? 0xFFFF : 0)) return NULL;
01219 
01220   /* Correct index. Old vehicles were saved differently:
01221    * invalid vehicle was 0xFFFF, now we use 0x0000 for everything invalid. */
01222   if (rt != REF_VEHICLE_OLD) index--;
01223 
01224   switch (rt) {
01225     case REF_ORDERLIST:
01226       if (OrderList::IsValidID(index)) return OrderList::Get(index);
01227       SlErrorCorrupt("Referencing invalid OrderList");
01228 
01229     case REF_ORDER:
01230       if (Order::IsValidID(index)) return Order::Get(index);
01231       /* in old versions, invalid order was used to mark end of order list */
01232       if (IsSavegameVersionBefore(5, 2)) return NULL;
01233       SlErrorCorrupt("Referencing invalid Order");
01234 
01235     case REF_VEHICLE_OLD:
01236     case REF_VEHICLE:
01237       if (Vehicle::IsValidID(index)) return Vehicle::Get(index);
01238       SlErrorCorrupt("Referencing invalid Vehicle");
01239 
01240     case REF_STATION:
01241       if (Station::IsValidID(index)) return Station::Get(index);
01242       SlErrorCorrupt("Referencing invalid Station");
01243 
01244     case REF_TOWN:
01245       if (Town::IsValidID(index)) return Town::Get(index);
01246       SlErrorCorrupt("Referencing invalid Town");
01247 
01248     case REF_ROADSTOPS:
01249       if (RoadStop::IsValidID(index)) return RoadStop::Get(index);
01250       SlErrorCorrupt("Referencing invalid RoadStop");
01251 
01252     case REF_ENGINE_RENEWS:
01253       if (EngineRenew::IsValidID(index)) return EngineRenew::Get(index);
01254       SlErrorCorrupt("Referencing invalid EngineRenew");
01255 
01256     case REF_CARGO_PACKET:
01257       if (CargoPacket::IsValidID(index)) return CargoPacket::Get(index);
01258       SlErrorCorrupt("Referencing invalid CargoPacket");
01259 
01260     case REF_STORAGE:
01261       if (PersistentStorage::IsValidID(index)) return PersistentStorage::Get(index);
01262       SlErrorCorrupt("Referencing invalid PersistentStorage");
01263 
01264     default: NOT_REACHED();
01265   }
01266 }
01267 
01272 static inline size_t SlCalcListLen(const void *list)
01273 {
01274   const std::list<void *> *l = (const std::list<void *> *) list;
01275 
01276   int type_size = IsSavegameVersionBefore(69) ? 2 : 4;
01277   /* Each entry is saved as type_size bytes, plus type_size bytes are used for the length
01278    * of the list */
01279   return l->size() * type_size + type_size;
01280 }
01281 
01282 
01288 static void SlList(void *list, SLRefType conv)
01289 {
01290   /* Automatically calculate the length? */
01291   if (_sl.need_length != NL_NONE) {
01292     SlSetLength(SlCalcListLen(list));
01293     /* Determine length only? */
01294     if (_sl.need_length == NL_CALCLENGTH) return;
01295   }
01296 
01297   typedef std::list<void *> PtrList;
01298   PtrList *l = (PtrList *)list;
01299 
01300   switch (_sl.action) {
01301     case SLA_SAVE: {
01302       SlWriteUint32((uint32)l->size());
01303 
01304       PtrList::iterator iter;
01305       for (iter = l->begin(); iter != l->end(); ++iter) {
01306         void *ptr = *iter;
01307         SlWriteUint32((uint32)ReferenceToInt(ptr, conv));
01308       }
01309       break;
01310     }
01311     case SLA_LOAD_CHECK:
01312     case SLA_LOAD: {
01313       size_t length = IsSavegameVersionBefore(69) ? SlReadUint16() : SlReadUint32();
01314 
01315       /* Load each reference and push to the end of the list */
01316       for (size_t i = 0; i < length; i++) {
01317         size_t data = IsSavegameVersionBefore(69) ? SlReadUint16() : SlReadUint32();
01318         l->push_back((void *)data);
01319       }
01320       break;
01321     }
01322     case SLA_PTRS: {
01323       PtrList temp = *l;
01324 
01325       l->clear();
01326       PtrList::iterator iter;
01327       for (iter = temp.begin(); iter != temp.end(); ++iter) {
01328         void *ptr = IntToReference((size_t)*iter, conv);
01329         l->push_back(ptr);
01330       }
01331       break;
01332     }
01333     case SLA_NULL:
01334       l->clear();
01335       break;
01336     default: NOT_REACHED();
01337   }
01338 }
01339 
01340 
01342 static inline bool SlIsObjectValidInSavegame(const SaveLoad *sld)
01343 {
01344   if (_sl_version < sld->version_from || _sl_version > sld->version_to) return false;
01345   if (sld->conv & SLF_NOT_IN_SAVE) return false;
01346 
01347   return true;
01348 }
01349 
01355 static inline bool SlSkipVariableOnLoad(const SaveLoad *sld)
01356 {
01357   if ((sld->conv & SLF_NO_NETWORK_SYNC) && _sl.action != SLA_SAVE && _networking && !_network_server) {
01358     SlSkipBytes(SlCalcConvMemLen(sld->conv) * sld->length);
01359     return true;
01360   }
01361 
01362   return false;
01363 }
01364 
01371 size_t SlCalcObjLength(const void *object, const SaveLoad *sld)
01372 {
01373   size_t length = 0;
01374 
01375   /* Need to determine the length and write a length tag. */
01376   for (; sld->cmd != SL_END; sld++) {
01377     length += SlCalcObjMemberLength(object, sld);
01378   }
01379   return length;
01380 }
01381 
01382 size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld)
01383 {
01384   assert(_sl.action == SLA_SAVE);
01385 
01386   switch (sld->cmd) {
01387     case SL_VAR:
01388     case SL_REF:
01389     case SL_ARR:
01390     case SL_STR:
01391     case SL_LST:
01392       /* CONDITIONAL saveload types depend on the savegame version */
01393       if (!SlIsObjectValidInSavegame(sld)) break;
01394 
01395       switch (sld->cmd) {
01396         case SL_VAR: return SlCalcConvFileLen(sld->conv);
01397         case SL_REF: return SlCalcRefLen();
01398         case SL_ARR: return SlCalcArrayLen(sld->length, sld->conv);
01399         case SL_STR: return SlCalcStringLen(GetVariableAddress(object, sld), sld->length, sld->conv);
01400         case SL_LST: return SlCalcListLen(GetVariableAddress(object, sld));
01401         default: NOT_REACHED();
01402       }
01403       break;
01404     case SL_WRITEBYTE: return 1; // a byte is logically of size 1
01405     case SL_VEH_INCLUDE: return SlCalcObjLength(object, GetVehicleDescription(VEH_END));
01406     case SL_ST_INCLUDE: return SlCalcObjLength(object, GetBaseStationDescription());
01407     default: NOT_REACHED();
01408   }
01409   return 0;
01410 }
01411 
01412 
01413 bool SlObjectMember(void *ptr, const SaveLoad *sld)
01414 {
01415   VarType conv = GB(sld->conv, 0, 8);
01416   switch (sld->cmd) {
01417     case SL_VAR:
01418     case SL_REF:
01419     case SL_ARR:
01420     case SL_STR:
01421     case SL_LST:
01422       /* CONDITIONAL saveload types depend on the savegame version */
01423       if (!SlIsObjectValidInSavegame(sld)) return false;
01424       if (SlSkipVariableOnLoad(sld)) return false;
01425 
01426       switch (sld->cmd) {
01427         case SL_VAR: SlSaveLoadConv(ptr, conv); break;
01428         case SL_REF: // Reference variable, translate
01429           switch (_sl.action) {
01430             case SLA_SAVE:
01431               SlWriteUint32((uint32)ReferenceToInt(*(void **)ptr, (SLRefType)conv));
01432               break;
01433             case SLA_LOAD_CHECK:
01434             case SLA_LOAD:
01435               *(size_t *)ptr = IsSavegameVersionBefore(69) ? SlReadUint16() : SlReadUint32();
01436               break;
01437             case SLA_PTRS:
01438               *(void **)ptr = IntToReference(*(size_t *)ptr, (SLRefType)conv);
01439               break;
01440             case SLA_NULL:
01441               *(void **)ptr = NULL;
01442               break;
01443             default: NOT_REACHED();
01444           }
01445           break;
01446         case SL_ARR: SlArray(ptr, sld->length, conv); break;
01447         case SL_STR: SlString(ptr, sld->length, conv); break;
01448         case SL_LST: SlList(ptr, (SLRefType)conv); break;
01449         default: NOT_REACHED();
01450       }
01451       break;
01452 
01453     /* SL_WRITEBYTE translates a value of a variable to another one upon
01454      * saving or loading.
01455      * XXX - variable renaming abuse
01456      * game_value: the value of the variable ingame is abused by sld->version_from
01457      * file_value: the value of the variable in the savegame is abused by sld->version_to */
01458     case SL_WRITEBYTE:
01459       switch (_sl.action) {
01460         case SLA_SAVE: SlWriteByte(sld->version_to); break;
01461         case SLA_LOAD_CHECK:
01462         case SLA_LOAD: *(byte *)ptr = sld->version_from; break;
01463         case SLA_PTRS: break;
01464         case SLA_NULL: break;
01465         default: NOT_REACHED();
01466       }
01467       break;
01468 
01469     /* SL_VEH_INCLUDE loads common code for vehicles */
01470     case SL_VEH_INCLUDE:
01471       SlObject(ptr, GetVehicleDescription(VEH_END));
01472       break;
01473 
01474     case SL_ST_INCLUDE:
01475       SlObject(ptr, GetBaseStationDescription());
01476       break;
01477 
01478     default: NOT_REACHED();
01479   }
01480   return true;
01481 }
01482 
01488 void SlObject(void *object, const SaveLoad *sld)
01489 {
01490   /* Automatically calculate the length? */
01491   if (_sl.need_length != NL_NONE) {
01492     SlSetLength(SlCalcObjLength(object, sld));
01493     if (_sl.need_length == NL_CALCLENGTH) return;
01494   }
01495 
01496   for (; sld->cmd != SL_END; sld++) {
01497     void *ptr = sld->global ? sld->address : GetVariableAddress(object, sld);
01498     SlObjectMember(ptr, sld);
01499   }
01500 }
01501 
01506 void SlGlobList(const SaveLoadGlobVarList *sldg)
01507 {
01508   SlObject(NULL, (const SaveLoad*)sldg);
01509 }
01510 
01516 void SlAutolength(AutolengthProc *proc, void *arg)
01517 {
01518   size_t offs;
01519 
01520   assert(_sl.action == SLA_SAVE);
01521 
01522   /* Tell it to calculate the length */
01523   _sl.need_length = NL_CALCLENGTH;
01524   _sl.obj_len = 0;
01525   proc(arg);
01526 
01527   /* Setup length */
01528   _sl.need_length = NL_WANTLENGTH;
01529   SlSetLength(_sl.obj_len);
01530 
01531   offs = _sl.dumper->GetSize() + _sl.obj_len;
01532 
01533   /* And write the stuff */
01534   proc(arg);
01535 
01536   if (offs != _sl.dumper->GetSize()) SlErrorCorrupt("Invalid chunk size");
01537 }
01538 
01543 static void SlLoadChunk(const ChunkHandler *ch)
01544 {
01545   byte m = SlReadByte();
01546   size_t len;
01547   size_t endoffs;
01548 
01549   _sl.block_mode = m;
01550   _sl.obj_len = 0;
01551 
01552   switch (m) {
01553     case CH_ARRAY:
01554       _sl.array_index = 0;
01555       ch->load_proc();
01556       break;
01557     case CH_SPARSE_ARRAY:
01558       ch->load_proc();
01559       break;
01560     default:
01561       if ((m & 0xF) == CH_RIFF) {
01562         /* Read length */
01563         len = (SlReadByte() << 16) | ((m >> 4) << 24);
01564         len += SlReadUint16();
01565         _sl.obj_len = len;
01566         endoffs = _sl.reader->GetSize() + len;
01567         ch->load_proc();
01568         if (_sl.reader->GetSize() != endoffs) SlErrorCorrupt("Invalid chunk size");
01569       } else {
01570         SlErrorCorrupt("Invalid chunk type");
01571       }
01572       break;
01573   }
01574 }
01575 
01581 static void SlLoadCheckChunk(const ChunkHandler *ch)
01582 {
01583   byte m = SlReadByte();
01584   size_t len;
01585   size_t endoffs;
01586 
01587   _sl.block_mode = m;
01588   _sl.obj_len = 0;
01589 
01590   switch (m) {
01591     case CH_ARRAY:
01592       _sl.array_index = 0;
01593       if (ch->load_check_proc) {
01594         ch->load_check_proc();
01595       } else {
01596         SlSkipArray();
01597       }
01598       break;
01599     case CH_SPARSE_ARRAY:
01600       if (ch->load_check_proc) {
01601         ch->load_check_proc();
01602       } else {
01603         SlSkipArray();
01604       }
01605       break;
01606     default:
01607       if ((m & 0xF) == CH_RIFF) {
01608         /* Read length */
01609         len = (SlReadByte() << 16) | ((m >> 4) << 24);
01610         len += SlReadUint16();
01611         _sl.obj_len = len;
01612         endoffs = _sl.reader->GetSize() + len;
01613         if (ch->load_check_proc) {
01614           ch->load_check_proc();
01615         } else {
01616           SlSkipBytes(len);
01617         }
01618         if (_sl.reader->GetSize() != endoffs) SlErrorCorrupt("Invalid chunk size");
01619       } else {
01620         SlErrorCorrupt("Invalid chunk type");
01621       }
01622       break;
01623   }
01624 }
01625 
01630 static ChunkSaveLoadProc *_stub_save_proc;
01631 
01637 static inline void SlStubSaveProc2(void *arg)
01638 {
01639   _stub_save_proc();
01640 }
01641 
01647 static void SlStubSaveProc()
01648 {
01649   SlAutolength(SlStubSaveProc2, NULL);
01650 }
01651 
01657 static void SlSaveChunk(const ChunkHandler *ch)
01658 {
01659   ChunkSaveLoadProc *proc = ch->save_proc;
01660 
01661   /* Don't save any chunk information if there is no save handler. */
01662   if (proc == NULL) return;
01663 
01664   SlWriteUint32(ch->id);
01665   DEBUG(sl, 2, "Saving chunk %c%c%c%c", ch->id >> 24, ch->id >> 16, ch->id >> 8, ch->id);
01666 
01667   if (ch->flags & CH_AUTO_LENGTH) {
01668     /* Need to calculate the length. Solve that by calling SlAutoLength in the save_proc. */
01669     _stub_save_proc = proc;
01670     proc = SlStubSaveProc;
01671   }
01672 
01673   _sl.block_mode = ch->flags & CH_TYPE_MASK;
01674   switch (ch->flags & CH_TYPE_MASK) {
01675     case CH_RIFF:
01676       _sl.need_length = NL_WANTLENGTH;
01677       proc();
01678       break;
01679     case CH_ARRAY:
01680       _sl.last_array_index = 0;
01681       SlWriteByte(CH_ARRAY);
01682       proc();
01683       SlWriteArrayLength(0); // Terminate arrays
01684       break;
01685     case CH_SPARSE_ARRAY:
01686       SlWriteByte(CH_SPARSE_ARRAY);
01687       proc();
01688       SlWriteArrayLength(0); // Terminate arrays
01689       break;
01690     default: NOT_REACHED();
01691   }
01692 }
01693 
01695 static void SlSaveChunks()
01696 {
01697   FOR_ALL_CHUNK_HANDLERS(ch) {
01698     SlSaveChunk(ch);
01699   }
01700 
01701   /* Terminator */
01702   SlWriteUint32(0);
01703 }
01704 
01711 static const ChunkHandler *SlFindChunkHandler(uint32 id)
01712 {
01713   FOR_ALL_CHUNK_HANDLERS(ch) if (ch->id == id) return ch;
01714   return NULL;
01715 }
01716 
01718 static void SlLoadChunks()
01719 {
01720   uint32 id;
01721   const ChunkHandler *ch;
01722 
01723   for (id = SlReadUint32(); id != 0; id = SlReadUint32()) {
01724     DEBUG(sl, 2, "Loading chunk %c%c%c%c", id >> 24, id >> 16, id >> 8, id);
01725 
01726     ch = SlFindChunkHandler(id);
01727     if (ch == NULL) SlErrorCorrupt("Unknown chunk type");
01728     SlLoadChunk(ch);
01729   }
01730 }
01731 
01733 static void SlLoadCheckChunks()
01734 {
01735   uint32 id;
01736   const ChunkHandler *ch;
01737 
01738   for (id = SlReadUint32(); id != 0; id = SlReadUint32()) {
01739     DEBUG(sl, 2, "Loading chunk %c%c%c%c", id >> 24, id >> 16, id >> 8, id);
01740 
01741     ch = SlFindChunkHandler(id);
01742     if (ch == NULL) SlErrorCorrupt("Unknown chunk type");
01743     SlLoadCheckChunk(ch);
01744   }
01745 }
01746 
01748 static void SlFixPointers()
01749 {
01750   _sl.action = SLA_PTRS;
01751 
01752   DEBUG(sl, 1, "Fixing pointers");
01753 
01754   FOR_ALL_CHUNK_HANDLERS(ch) {
01755     if (ch->ptrs_proc != NULL) {
01756       DEBUG(sl, 2, "Fixing pointers for %c%c%c%c", ch->id >> 24, ch->id >> 16, ch->id >> 8, ch->id);
01757       ch->ptrs_proc();
01758     }
01759   }
01760 
01761   DEBUG(sl, 1, "All pointers fixed");
01762 
01763   assert(_sl.action == SLA_PTRS);
01764 }
01765 
01766 
01768 struct FileReader : LoadFilter {
01769   FILE *file; 
01770   long begin; 
01771 
01776   FileReader(FILE *file) : LoadFilter(NULL), file(file), begin(ftell(file))
01777   {
01778   }
01779 
01781   ~FileReader()
01782   {
01783     if (this->file != NULL) fclose(this->file);
01784     this->file = NULL;
01785 
01786     /* Make sure we don't double free. */
01787     _sl.sf = NULL;
01788   }
01789 
01790   /* virtual */ size_t Read(byte *buf, size_t size)
01791   {
01792     /* We're in the process of shutting down, i.e. in "failure" mode. */
01793     if (this->file == NULL) return 0;
01794 
01795     return fread(buf, 1, size, this->file);
01796   }
01797 
01798   /* virtual */ void Reset()
01799   {
01800     clearerr(this->file);
01801     fseek(this->file, this->begin, SEEK_SET);
01802   }
01803 };
01804 
01806 struct FileWriter : SaveFilter {
01807   FILE *file; 
01808 
01813   FileWriter(FILE *file) : SaveFilter(NULL), file(file)
01814   {
01815   }
01816 
01818   ~FileWriter()
01819   {
01820     this->Finish();
01821 
01822     /* Make sure we don't double free. */
01823     _sl.sf = NULL;
01824   }
01825 
01826   /* virtual */ void Write(byte *buf, size_t size)
01827   {
01828     /* We're in the process of shutting down, i.e. in "failure" mode. */
01829     if (this->file == NULL) return;
01830 
01831     if (fwrite(buf, 1, size, this->file) != size) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE);
01832   }
01833 
01834   /* virtual */ void Finish()
01835   {
01836     if (this->file != NULL) fclose(this->file);
01837     this->file = NULL;
01838   }
01839 };
01840 
01841 /*******************************************
01842  ********** START OF LZO CODE **************
01843  *******************************************/
01844 
01845 #ifdef WITH_LZO
01846 #include <lzo/lzo1x.h>
01847 
01849 static const uint LZO_BUFFER_SIZE = 8192;
01850 
01852 struct LZOLoadFilter : LoadFilter {
01857   LZOLoadFilter(LoadFilter *chain) : LoadFilter(chain)
01858   {
01859     if (lzo_init() != LZO_E_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize decompressor");
01860   }
01861 
01862   /* virtual */ size_t Read(byte *buf, size_t ssize)
01863   {
01864     assert(ssize >= LZO_BUFFER_SIZE);
01865 
01866     /* Buffer size is from the LZO docs plus the chunk header size. */
01867     byte out[LZO_BUFFER_SIZE + LZO_BUFFER_SIZE / 16 + 64 + 3 + sizeof(uint32) * 2];
01868     uint32 tmp[2];
01869     uint32 size;
01870     lzo_uint len;
01871 
01872     /* Read header*/
01873     if (this->chain->Read((byte*)tmp, sizeof(tmp)) != sizeof(tmp)) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE, "File read failed");
01874 
01875     /* Check if size is bad */
01876     ((uint32*)out)[0] = size = tmp[1];
01877 
01878     if (_sl_version != 0) {
01879       tmp[0] = TO_BE32(tmp[0]);
01880       size = TO_BE32(size);
01881     }
01882 
01883     if (size >= sizeof(out)) SlErrorCorrupt("Inconsistent size");
01884 
01885     /* Read block */
01886     if (this->chain->Read(out + sizeof(uint32), size) != size) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
01887 
01888     /* Verify checksum */
01889     if (tmp[0] != lzo_adler32(0, out, size + sizeof(uint32))) SlErrorCorrupt("Bad checksum");
01890 
01891     /* Decompress */
01892     lzo1x_decompress(out + sizeof(uint32) * 1, size, buf, &len, NULL);
01893     return len;
01894   }
01895 };
01896 
01898 struct LZOSaveFilter : SaveFilter {
01904   LZOSaveFilter(SaveFilter *chain, byte compression_level) : SaveFilter(chain)
01905   {
01906     if (lzo_init() != LZO_E_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize compressor");
01907   }
01908 
01909   /* virtual */ void Write(byte *buf, size_t size)
01910   {
01911     const lzo_bytep in = buf;
01912     /* Buffer size is from the LZO docs plus the chunk header size. */
01913     byte out[LZO_BUFFER_SIZE + LZO_BUFFER_SIZE / 16 + 64 + 3 + sizeof(uint32) * 2];
01914     byte wrkmem[LZO1X_1_MEM_COMPRESS];
01915     lzo_uint outlen;
01916 
01917     do {
01918       /* Compress up to LZO_BUFFER_SIZE bytes at once. */
01919       lzo_uint len = size > LZO_BUFFER_SIZE ? LZO_BUFFER_SIZE : (lzo_uint)size;
01920       lzo1x_1_compress(in, len, out + sizeof(uint32) * 2, &outlen, wrkmem);
01921       ((uint32*)out)[1] = TO_BE32((uint32)outlen);
01922       ((uint32*)out)[0] = TO_BE32(lzo_adler32(0, out + sizeof(uint32), outlen + sizeof(uint32)));
01923       this->chain->Write(out, outlen + sizeof(uint32) * 2);
01924 
01925       /* Move to next data chunk. */
01926       size -= len;
01927       in += len;
01928     } while (size > 0);
01929   }
01930 };
01931 
01932 #endif /* WITH_LZO */
01933 
01934 /*********************************************
01935  ******** START OF NOCOMP CODE (uncompressed)*
01936  *********************************************/
01937 
01939 struct NoCompLoadFilter : LoadFilter {
01944   NoCompLoadFilter(LoadFilter *chain) : LoadFilter(chain)
01945   {
01946   }
01947 
01948   /* virtual */ size_t Read(byte *buf, size_t size)
01949   {
01950     return this->chain->Read(buf, size);
01951   }
01952 };
01953 
01955 struct NoCompSaveFilter : SaveFilter {
01961   NoCompSaveFilter(SaveFilter *chain, byte compression_level) : SaveFilter(chain)
01962   {
01963   }
01964 
01965   /* virtual */ void Write(byte *buf, size_t size)
01966   {
01967     this->chain->Write(buf, size);
01968   }
01969 };
01970 
01971 /********************************************
01972  ********** START OF ZLIB CODE **************
01973  ********************************************/
01974 
01975 #if defined(WITH_ZLIB)
01976 #include <zlib.h>
01977 
01979 struct ZlibLoadFilter : LoadFilter {
01980   z_stream z;                        
01981   byte fread_buf[MEMORY_CHUNK_SIZE]; 
01982 
01987   ZlibLoadFilter(LoadFilter *chain) : LoadFilter(chain)
01988   {
01989     memset(&this->z, 0, sizeof(this->z));
01990     if (inflateInit(&this->z) != Z_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize decompressor");
01991   }
01992 
01994   ~ZlibLoadFilter()
01995   {
01996     inflateEnd(&this->z);
01997   }
01998 
01999   /* virtual */ size_t Read(byte *buf, size_t size)
02000   {
02001     this->z.next_out  = buf;
02002     this->z.avail_out = (uint)size;
02003 
02004     do {
02005       /* read more bytes from the file? */
02006       if (this->z.avail_in == 0) {
02007         this->z.next_in = this->fread_buf;
02008         this->z.avail_in = (uint)this->chain->Read(this->fread_buf, sizeof(this->fread_buf));
02009       }
02010 
02011       /* inflate the data */
02012       int r = inflate(&this->z, 0);
02013       if (r == Z_STREAM_END) break;
02014 
02015       if (r != Z_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "inflate() failed");
02016     } while (this->z.avail_out != 0);
02017 
02018     return size - this->z.avail_out;
02019   }
02020 };
02021 
02023 struct ZlibSaveFilter : SaveFilter {
02024   z_stream z; 
02025 
02031   ZlibSaveFilter(SaveFilter *chain, byte compression_level) : SaveFilter(chain)
02032   {
02033     memset(&this->z, 0, sizeof(this->z));
02034     if (deflateInit(&this->z, compression_level) != Z_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize compressor");
02035   }
02036 
02038   ~ZlibSaveFilter()
02039   {
02040     deflateEnd(&this->z);
02041   }
02042 
02049   void WriteLoop(byte *p, size_t len, int mode)
02050   {
02051     byte buf[MEMORY_CHUNK_SIZE]; // output buffer
02052     uint n;
02053     this->z.next_in = p;
02054     this->z.avail_in = (uInt)len;
02055     do {
02056       this->z.next_out = buf;
02057       this->z.avail_out = sizeof(buf);
02058 
02066       int r = deflate(&this->z, mode);
02067 
02068       /* bytes were emitted? */
02069       if ((n = sizeof(buf) - this->z.avail_out) != 0) {
02070         this->chain->Write(buf, n);
02071       }
02072       if (r == Z_STREAM_END) break;
02073 
02074       if (r != Z_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "zlib returned error code");
02075     } while (this->z.avail_in || !this->z.avail_out);
02076   }
02077 
02078   /* virtual */ void Write(byte *buf, size_t size)
02079   {
02080     this->WriteLoop(buf, size, 0);
02081   }
02082 
02083   /* virtual */ void Finish()
02084   {
02085     this->WriteLoop(NULL, 0, Z_FINISH);
02086     this->chain->Finish();
02087   }
02088 };
02089 
02090 #endif /* WITH_ZLIB */
02091 
02092 /********************************************
02093  ********** START OF LZMA CODE **************
02094  ********************************************/
02095 
02096 #if defined(WITH_LZMA)
02097 #include <lzma.h>
02098 
02105 static const lzma_stream _lzma_init = LZMA_STREAM_INIT;
02106 
02108 struct LZMALoadFilter : LoadFilter {
02109   lzma_stream lzma;                  
02110   byte fread_buf[MEMORY_CHUNK_SIZE]; 
02111 
02116   LZMALoadFilter(LoadFilter *chain) : LoadFilter(chain), lzma(_lzma_init)
02117   {
02118     /* Allow saves up to 256 MB uncompressed */
02119     if (lzma_auto_decoder(&this->lzma, 1 << 28, 0) != LZMA_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize decompressor");
02120   }
02121 
02123   ~LZMALoadFilter()
02124   {
02125     lzma_end(&this->lzma);
02126   }
02127 
02128   /* virtual */ size_t Read(byte *buf, size_t size)
02129   {
02130     this->lzma.next_out  = buf;
02131     this->lzma.avail_out = size;
02132 
02133     do {
02134       /* read more bytes from the file? */
02135       if (this->lzma.avail_in == 0) {
02136         this->lzma.next_in  = this->fread_buf;
02137         this->lzma.avail_in = this->chain->Read(this->fread_buf, sizeof(this->fread_buf));
02138       }
02139 
02140       /* inflate the data */
02141       lzma_ret r = lzma_code(&this->lzma, LZMA_RUN);
02142       if (r == LZMA_STREAM_END) break;
02143       if (r != LZMA_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "liblzma returned error code");
02144     } while (this->lzma.avail_out != 0);
02145 
02146     return size - this->lzma.avail_out;
02147   }
02148 };
02149 
02151 struct LZMASaveFilter : SaveFilter {
02152   lzma_stream lzma; 
02153 
02159   LZMASaveFilter(SaveFilter *chain, byte compression_level) : SaveFilter(chain), lzma(_lzma_init)
02160   {
02161     if (lzma_easy_encoder(&this->lzma, compression_level, LZMA_CHECK_CRC32) != LZMA_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize compressor");
02162   }
02163 
02165   ~LZMASaveFilter()
02166   {
02167     lzma_end(&this->lzma);
02168   }
02169 
02176   void WriteLoop(byte *p, size_t len, lzma_action action)
02177   {
02178     byte buf[MEMORY_CHUNK_SIZE]; // output buffer
02179     size_t n;
02180     this->lzma.next_in = p;
02181     this->lzma.avail_in = len;
02182     do {
02183       this->lzma.next_out = buf;
02184       this->lzma.avail_out = sizeof(buf);
02185 
02186       lzma_ret r = lzma_code(&this->lzma, action);
02187 
02188       /* bytes were emitted? */
02189       if ((n = sizeof(buf) - this->lzma.avail_out) != 0) {
02190         this->chain->Write(buf, n);
02191       }
02192       if (r == LZMA_STREAM_END) break;
02193       if (r != LZMA_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "liblzma returned error code");
02194     } while (this->lzma.avail_in || !this->lzma.avail_out);
02195   }
02196 
02197   /* virtual */ void Write(byte *buf, size_t size)
02198   {
02199     this->WriteLoop(buf, size, LZMA_RUN);
02200   }
02201 
02202   /* virtual */ void Finish()
02203   {
02204     this->WriteLoop(NULL, 0, LZMA_FINISH);
02205     this->chain->Finish();
02206   }
02207 };
02208 
02209 #endif /* WITH_LZMA */
02210 
02211 /*******************************************
02212  ************* END OF CODE *****************
02213  *******************************************/
02214 
02216 struct SaveLoadFormat {
02217   const char *name;                     
02218   uint32 tag;                           
02219 
02220   LoadFilter *(*init_load)(LoadFilter *chain);                    
02221   SaveFilter *(*init_write)(SaveFilter *chain, byte compression); 
02222 
02223   byte min_compression;                 
02224   byte default_compression;             
02225   byte max_compression;                 
02226 };
02227 
02229 static const SaveLoadFormat _saveload_formats[] = {
02230 #if defined(WITH_LZO)
02231   /* Roughly 75% larger than zlib level 6 at only ~7% of the CPU usage. */
02232   {"lzo",    TO_BE32X('OTTD'), CreateLoadFilter<LZOLoadFilter>,    CreateSaveFilter<LZOSaveFilter>,    0, 0, 0},
02233 #else
02234   {"lzo",    TO_BE32X('OTTD'), NULL,                               NULL,                               0, 0, 0},
02235 #endif
02236   /* Roughly 5 times larger at only 1% of the CPU usage over zlib level 6. */
02237   {"none",   TO_BE32X('OTTN'), CreateLoadFilter<NoCompLoadFilter>, CreateSaveFilter<NoCompSaveFilter>, 0, 0, 0},
02238 #if defined(WITH_ZLIB)
02239   /* After level 6 the speed reduction is significant (1.5x to 2.5x slower per level), but the reduction in filesize is
02240    * fairly insignificant (~1% for each step). Lower levels become ~5-10% bigger by each level than level 6 while level
02241    * 1 is "only" 3 times as fast. Level 0 results in uncompressed savegames at about 8 times the cost of "none". */
02242   {"zlib",   TO_BE32X('OTTZ'), CreateLoadFilter<ZlibLoadFilter>,   CreateSaveFilter<ZlibSaveFilter>,   0, 6, 9},
02243 #else
02244   {"zlib",   TO_BE32X('OTTZ'), NULL,                               NULL,                               0, 0, 0},
02245 #endif
02246 #if defined(WITH_LZMA)
02247   /* Level 2 compression is speed wise as fast as zlib level 6 compression (old default), but results in ~10% smaller saves.
02248    * Higher compression levels are possible, and might improve savegame size by up to 25%, but are also up to 10 times slower.
02249    * The next significant reduction in file size is at level 4, but that is already 4 times slower. Level 3 is primarily 50%
02250    * slower while not improving the filesize, while level 0 and 1 are faster, but don't reduce savegame size much.
02251    * It's OTTX and not e.g. OTTL because liblzma is part of xz-utils and .tar.xz is prefered over .tar.lzma. */
02252   {"lzma",   TO_BE32X('OTTX'), CreateLoadFilter<LZMALoadFilter>,   CreateSaveFilter<LZMASaveFilter>,   0, 2, 9},
02253 #else
02254   {"lzma",   TO_BE32X('OTTX'), NULL,                               NULL,                               0, 0, 0},
02255 #endif
02256 };
02257 
02265 static const SaveLoadFormat *GetSavegameFormat(char *s, byte *compression_level)
02266 {
02267   const SaveLoadFormat *def = lastof(_saveload_formats);
02268 
02269   /* find default savegame format, the highest one with which files can be written */
02270   while (!def->init_write) def--;
02271 
02272   if (!StrEmpty(s)) {
02273     /* Get the ":..." of the compression level out of the way */
02274     char *complevel = strrchr(s, ':');
02275     if (complevel != NULL) *complevel = '\0';
02276 
02277     for (const SaveLoadFormat *slf = &_saveload_formats[0]; slf != endof(_saveload_formats); slf++) {
02278       if (slf->init_write != NULL && strcmp(s, slf->name) == 0) {
02279         *compression_level = slf->default_compression;
02280         if (complevel != NULL) {
02281           /* There is a compression level in the string.
02282            * First restore the : we removed to do proper name matching,
02283            * then move the the begin of the actual version. */
02284           *complevel = ':';
02285           complevel++;
02286 
02287           /* Get the version and determine whether all went fine. */
02288           char *end;
02289           long level = strtol(complevel, &end, 10);
02290           if (end == complevel || level != Clamp(level, slf->min_compression, slf->max_compression)) {
02291             SetDParamStr(0, complevel);
02292             ShowErrorMessage(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_SAVEGAME_COMPRESSION_LEVEL, WL_CRITICAL);
02293           } else {
02294             *compression_level = level;
02295           }
02296         }
02297         return slf;
02298       }
02299     }
02300 
02301     SetDParamStr(0, s);
02302     SetDParamStr(1, def->name);
02303     ShowErrorMessage(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_SAVEGAME_COMPRESSION_ALGORITHM, WL_CRITICAL);
02304 
02305     /* Restore the string by adding the : back */
02306     if (complevel != NULL) *complevel = ':';
02307   }
02308   *compression_level = def->default_compression;
02309   return def;
02310 }
02311 
02312 /* actual loader/saver function */
02313 void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settings);
02314 extern bool AfterLoadGame();
02315 extern bool LoadOldSaveGame(const char *file);
02316 
02320 static inline void ClearSaveLoadState()
02321 {
02322   delete _sl.dumper;
02323   _sl.dumper = NULL;
02324 
02325   delete _sl.sf;
02326   _sl.sf = NULL;
02327 
02328   delete _sl.reader;
02329   _sl.reader = NULL;
02330 
02331   delete _sl.lf;
02332   _sl.lf = NULL;
02333 }
02334 
02340 static void SaveFileStart()
02341 {
02342   _sl.ff_state = _fast_forward;
02343   _fast_forward = 0;
02344   if (_cursor.sprite == SPR_CURSOR_MOUSE) SetMouseCursor(SPR_CURSOR_ZZZ, PAL_NONE);
02345 
02346   InvalidateWindowData(WC_STATUS_BAR, 0, SBI_SAVELOAD_START);
02347   _sl.saveinprogress = true;
02348 }
02349 
02351 static void SaveFileDone()
02352 {
02353   if (_game_mode != GM_MENU) _fast_forward = _sl.ff_state;
02354   if (_cursor.sprite == SPR_CURSOR_ZZZ) SetMouseCursor(SPR_CURSOR_MOUSE, PAL_NONE);
02355 
02356   InvalidateWindowData(WC_STATUS_BAR, 0, SBI_SAVELOAD_FINISH);
02357   _sl.saveinprogress = false;
02358 }
02359 
02361 void SetSaveLoadError(StringID str)
02362 {
02363   _sl.error_str = str;
02364 }
02365 
02367 const char *GetSaveLoadErrorString()
02368 {
02369   SetDParam(0, _sl.error_str);
02370   SetDParamStr(1, _sl.extra_msg);
02371 
02372   static char err_str[512];
02373   GetString(err_str, _sl.action == SLA_SAVE ? STR_ERROR_GAME_SAVE_FAILED : STR_ERROR_GAME_LOAD_FAILED, lastof(err_str));
02374   return err_str;
02375 }
02376 
02378 static void SaveFileError()
02379 {
02380   SetDParamStr(0, GetSaveLoadErrorString());
02381   ShowErrorMessage(STR_JUST_RAW_STRING, INVALID_STRING_ID, WL_ERROR);
02382   SaveFileDone();
02383 }
02384 
02389 static SaveOrLoadResult SaveFileToDisk(bool threaded)
02390 {
02391   try {
02392     byte compression;
02393     const SaveLoadFormat *fmt = GetSavegameFormat(_savegame_format, &compression);
02394 
02395     /* We have written our stuff to memory, now write it to file! */
02396     uint32 hdr[2] = { fmt->tag, TO_BE32(SAVEGAME_VERSION << 16) };
02397     _sl.sf->Write((byte*)hdr, sizeof(hdr));
02398 
02399     _sl.sf = fmt->init_write(_sl.sf, compression);
02400     _sl.dumper->Flush(_sl.sf);
02401 
02402     ClearSaveLoadState();
02403 
02404     if (threaded) SetAsyncSaveFinish(SaveFileDone);
02405 
02406     return SL_OK;
02407   } catch (...) {
02408     ClearSaveLoadState();
02409 
02410     AsyncSaveFinishProc asfp = SaveFileDone;
02411 
02412     /* We don't want to shout when saving is just
02413      * cancelled due to a client disconnecting. */
02414     if (_sl.error_str != STR_NETWORK_ERROR_LOSTCONNECTION) {
02415       /* Skip the "colour" character */
02416       DEBUG(sl, 0, "%s", GetSaveLoadErrorString() + 3);
02417       asfp = SaveFileError;
02418     }
02419 
02420     if (threaded) {
02421       SetAsyncSaveFinish(asfp);
02422     } else {
02423       asfp();
02424     }
02425     return SL_ERROR;
02426   }
02427 }
02428 
02430 static void SaveFileToDiskThread(void *arg)
02431 {
02432   SaveFileToDisk(true);
02433 }
02434 
02435 void WaitTillSaved()
02436 {
02437   if (_save_thread == NULL) return;
02438 
02439   _save_thread->Join();
02440   delete _save_thread;
02441   _save_thread = NULL;
02442 
02443   /* Make sure every other state is handled properly as well. */
02444   ProcessAsyncSaveFinish();
02445 }
02446 
02455 static SaveOrLoadResult DoSave(SaveFilter *writer, bool threaded)
02456 {
02457   assert(!_sl.saveinprogress);
02458 
02459   _sl.dumper = new MemoryDumper();
02460   _sl.sf = writer;
02461 
02462   _sl_version = SAVEGAME_VERSION;
02463 
02464   SaveViewportBeforeSaveGame();
02465   SlSaveChunks();
02466 
02467   SaveFileStart();
02468   if (!threaded || !ThreadObject::New(&SaveFileToDiskThread, NULL, &_save_thread)) {
02469     if (threaded) DEBUG(sl, 1, "Cannot create savegame thread, reverting to single-threaded mode...");
02470 
02471     SaveOrLoadResult result = SaveFileToDisk(false);
02472     SaveFileDone();
02473 
02474     return result;
02475   }
02476 
02477   return SL_OK;
02478 }
02479 
02486 SaveOrLoadResult SaveWithFilter(SaveFilter *writer, bool threaded)
02487 {
02488   try {
02489     _sl.action = SLA_SAVE;
02490     return DoSave(writer, threaded);
02491   } catch (...) {
02492     ClearSaveLoadState();
02493     return SL_ERROR;
02494   }
02495 }
02496 
02503 static SaveOrLoadResult DoLoad(LoadFilter *reader, bool load_check)
02504 {
02505   _sl.lf = reader;
02506 
02507   if (load_check) {
02508     /* Clear previous check data */
02509     _load_check_data.Clear();
02510     /* Mark SL_LOAD_CHECK as supported for this savegame. */
02511     _load_check_data.checkable = true;
02512   }
02513 
02514   uint32 hdr[2];
02515   if (_sl.lf->Read((byte*)hdr, sizeof(hdr)) != sizeof(hdr)) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
02516 
02517   /* see if we have any loader for this type. */
02518   const SaveLoadFormat *fmt = _saveload_formats;
02519   for (;;) {
02520     /* No loader found, treat as version 0 and use LZO format */
02521     if (fmt == endof(_saveload_formats)) {
02522       DEBUG(sl, 0, "Unknown savegame type, trying to load it as the buggy format");
02523       _sl.lf->Reset();
02524       _sl_version = 0;
02525       _sl_minor_version = 0;
02526 
02527       /* Try to find the LZO savegame format; it uses 'OTTD' as tag. */
02528       fmt = _saveload_formats;
02529       for (;;) {
02530         if (fmt == endof(_saveload_formats)) {
02531           /* Who removed LZO support? Bad bad boy! */
02532           NOT_REACHED();
02533         }
02534         if (fmt->tag == TO_BE32X('OTTD')) break;
02535         fmt++;
02536       }
02537       break;
02538     }
02539 
02540     if (fmt->tag == hdr[0]) {
02541       /* check version number */
02542       _sl_version = TO_BE32(hdr[1]) >> 16;
02543       /* Minor is not used anymore from version 18.0, but it is still needed
02544        * in versions before that (4 cases) which can't be removed easy.
02545        * Therefor it is loaded, but never saved (or, it saves a 0 in any scenario). */
02546       _sl_minor_version = (TO_BE32(hdr[1]) >> 8) & 0xFF;
02547 
02548       DEBUG(sl, 1, "Loading savegame version %d", _sl_version);
02549 
02550       /* Is the version higher than the current? */
02551       if (_sl_version > SAVEGAME_VERSION) SlError(STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME);
02552       break;
02553     }
02554 
02555     fmt++;
02556   }
02557 
02558   /* loader for this savegame type is not implemented? */
02559   if (fmt->init_load == NULL) {
02560     char err_str[64];
02561     snprintf(err_str, lengthof(err_str), "Loader for '%s' is not available.", fmt->name);
02562     SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, err_str);
02563   }
02564 
02565   _sl.lf = fmt->init_load(_sl.lf);
02566   _sl.reader = new ReadBuffer(_sl.lf);
02567   _next_offs = 0;
02568 
02569   if (!load_check) {
02570     /* Old maps were hardcoded to 256x256 and thus did not contain
02571      * any mapsize information. Pre-initialize to 256x256 to not to
02572      * confuse old games */
02573     InitializeGame(256, 256, true, true);
02574 
02575     GamelogReset();
02576 
02577     if (IsSavegameVersionBefore(4)) {
02578       /*
02579        * NewGRFs were introduced between 0.3,4 and 0.3.5, which both
02580        * shared savegame version 4. Anything before that 'obviously'
02581        * does not have any NewGRFs. Between the introduction and
02582        * savegame version 41 (just before 0.5) the NewGRF settings
02583        * were not stored in the savegame and they were loaded by
02584        * using the settings from the main menu.
02585        * So, to recap:
02586        * - savegame version  <  4:  do not load any NewGRFs.
02587        * - savegame version >= 41:  load NewGRFs from savegame, which is
02588        *                            already done at this stage by
02589        *                            overwriting the main menu settings.
02590        * - other savegame versions: use main menu settings.
02591        *
02592        * This means that users *can* crash savegame version 4..40
02593        * savegames if they set incompatible NewGRFs in the main menu,
02594        * but can't crash anymore for savegame version < 4 savegames.
02595        *
02596        * Note: this is done here because AfterLoadGame is also called
02597        * for TTO/TTD/TTDP savegames which have their own NewGRF logic.
02598        */
02599       ClearGRFConfigList(&_grfconfig);
02600     }
02601   }
02602 
02603   if (load_check) {
02604     /* Load chunks into _load_check_data.
02605      * No pools are loaded. References are not possible, and thus do not need resolving. */
02606     SlLoadCheckChunks();
02607   } else {
02608     /* Load chunks and resolve references */
02609     SlLoadChunks();
02610     SlFixPointers();
02611   }
02612 
02613   ClearSaveLoadState();
02614 
02615   _savegame_type = SGT_OTTD;
02616 
02617   if (load_check) {
02618     /* The only part from AfterLoadGame() we need */
02619     _load_check_data.grf_compatibility = IsGoodGRFConfigList(_load_check_data.grfconfig);
02620   } else {
02621     GamelogStartAction(GLAT_LOAD);
02622 
02623     /* After loading fix up savegame for any internal changes that
02624      * might have occurred since then. If it fails, load back the old game. */
02625     if (!AfterLoadGame()) {
02626       GamelogStopAction();
02627       return SL_REINIT;
02628     }
02629 
02630     GamelogStopAction();
02631   }
02632 
02633   return SL_OK;
02634 }
02635 
02641 SaveOrLoadResult LoadWithFilter(LoadFilter *reader)
02642 {
02643   try {
02644     _sl.action = SLA_LOAD;
02645     return DoLoad(reader, false);
02646   } catch (...) {
02647     ClearSaveLoadState();
02648     return SL_REINIT;
02649   }
02650 }
02651 
02661 SaveOrLoadResult SaveOrLoad(const char *filename, int mode, Subdirectory sb, bool threaded)
02662 {
02663   /* An instance of saving is already active, so don't go saving again */
02664   if (_sl.saveinprogress && mode == SL_SAVE && threaded) {
02665     /* if not an autosave, but a user action, show error message */
02666     if (!_do_autosave) ShowErrorMessage(STR_ERROR_SAVE_STILL_IN_PROGRESS, INVALID_STRING_ID, WL_ERROR);
02667     return SL_OK;
02668   }
02669   WaitTillSaved();
02670 
02671   /* Load a TTDLX or TTDPatch game */
02672   if (mode == SL_OLD_LOAD) {
02673     InitializeGame(256, 256, true, true); // set a mapsize of 256x256 for TTDPatch games or it might get confused
02674 
02675     /* TTD/TTO savegames have no NewGRFs, TTDP savegame have them
02676      * and if so a new NewGRF list will be made in LoadOldSaveGame.
02677      * Note: this is done here because AfterLoadGame is also called
02678      * for OTTD savegames which have their own NewGRF logic. */
02679     ClearGRFConfigList(&_grfconfig);
02680     GamelogReset();
02681     if (!LoadOldSaveGame(filename)) return SL_REINIT;
02682     _sl_version = 0;
02683     _sl_minor_version = 0;
02684     GamelogStartAction(GLAT_LOAD);
02685     if (!AfterLoadGame()) {
02686       GamelogStopAction();
02687       return SL_REINIT;
02688     }
02689     GamelogStopAction();
02690     return SL_OK;
02691   }
02692 
02693   switch (mode) {
02694     case SL_LOAD_CHECK: _sl.action = SLA_LOAD_CHECK; break;
02695     case SL_LOAD: _sl.action = SLA_LOAD; break;
02696     case SL_SAVE: _sl.action = SLA_SAVE; break;
02697     default: NOT_REACHED();
02698   }
02699 
02700   try {
02701     FILE *fh = (mode == SL_SAVE) ? FioFOpenFile(filename, "wb", sb) : FioFOpenFile(filename, "rb", sb);
02702 
02703     /* Make it a little easier to load savegames from the console */
02704     if (fh == NULL && mode != SL_SAVE) fh = FioFOpenFile(filename, "rb", SAVE_DIR);
02705     if (fh == NULL && mode != SL_SAVE) fh = FioFOpenFile(filename, "rb", BASE_DIR);
02706     if (fh == NULL && mode != SL_SAVE) fh = FioFOpenFile(filename, "rb", SCENARIO_DIR);
02707 
02708     if (fh == NULL) {
02709       SlError(mode == SL_SAVE ? STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE : STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
02710     }
02711 
02712     if (mode == SL_SAVE) { // SAVE game
02713       DEBUG(desync, 1, "save: %08x; %02x; %s", _date, _date_fract, filename);
02714       if (_network_server || !_settings_client.gui.threaded_saves) threaded = false;
02715 
02716       return DoSave(new FileWriter(fh), threaded);
02717     }
02718 
02719     /* LOAD game */
02720     assert(mode == SL_LOAD || mode == SL_LOAD_CHECK);
02721     DEBUG(desync, 1, "load: %s", filename);
02722     return DoLoad(new FileReader(fh), mode == SL_LOAD_CHECK);
02723   } catch (...) {
02724     ClearSaveLoadState();
02725 
02726     /* Skip the "colour" character */
02727     if (mode != SL_LOAD_CHECK) DEBUG(sl, 0, "%s", GetSaveLoadErrorString() + 3);
02728 
02729     /* A saver/loader exception!! reinitialize all variables to prevent crash! */
02730     return (mode == SL_LOAD) ? SL_REINIT : SL_ERROR;
02731   }
02732 }
02733 
02735 void DoExitSave()
02736 {
02737   SaveOrLoad("exit.sav", SL_SAVE, AUTOSAVE_DIR);
02738 }
02739 
02745 void GenerateDefaultSaveName(char *buf, const char *last)
02746 {
02747   /* Check if we have a name for this map, which is the name of the first
02748    * available company. When there's no company available we'll use
02749    * 'Spectator' as "company" name. */
02750   CompanyID cid = _local_company;
02751   if (!Company::IsValidID(cid)) {
02752     const Company *c;
02753     FOR_ALL_COMPANIES(c) {
02754       cid = c->index;
02755       break;
02756     }
02757   }
02758 
02759   SetDParam(0, cid);
02760 
02761   /* Insert current date */
02762   switch (_settings_client.gui.date_format_in_default_names) {
02763     case 0: SetDParam(1, STR_JUST_DATE_LONG); break;
02764     case 1: SetDParam(1, STR_JUST_DATE_TINY); break;
02765     case 2: SetDParam(1, STR_JUST_DATE_ISO); break;
02766     default: NOT_REACHED();
02767   }
02768   SetDParam(2, _date);
02769 
02770   /* Get the correct string (special string for when there's not company) */
02771   GetString(buf, !Company::IsValidID(cid) ? STR_SAVEGAME_NAME_SPECTATOR : STR_SAVEGAME_NAME_DEFAULT, last);
02772   SanitizeFilename(buf);
02773 }
02774 
02775 #if 0
02776 
02782 int GetSavegameType(char *file)
02783 {
02784   const SaveLoadFormat *fmt;
02785   uint32 hdr;
02786   FILE *f;
02787   int mode = SL_OLD_LOAD;
02788 
02789   f = fopen(file, "rb");
02790   if (fread(&hdr, sizeof(hdr), 1, f) != 1) {
02791     DEBUG(sl, 0, "Savegame is obsolete or invalid format");
02792     mode = SL_LOAD; // don't try to get filename, just show name as it is written
02793   } else {
02794     /* see if we have any loader for this type. */
02795     for (fmt = _saveload_formats; fmt != endof(_saveload_formats); fmt++) {
02796       if (fmt->tag == hdr) {
02797         mode = SL_LOAD; // new type of savegame
02798         break;
02799       }
02800     }
02801   }
02802 
02803   fclose(f);
02804   return mode;
02805 }
02806 #endif