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 "../fios.h"
00043 #include "../error.h"
00044 
00045 #include "table/strings.h"
00046 
00047 #include "saveload_internal.h"
00048 #include "saveload_filter.h"
00049 
00050 /*
00051  * Previous savegame versions, the trunk revision where they were
00052  * introduced and the released version that had that particular
00053  * savegame version.
00054  * Up to savegame version 18 there is a minor version as well.
00055  *
00056  *    1.0         0.1.x, 0.2.x
00057  *    2.0         0.3.0
00058  *    2.1         0.3.1, 0.3.2
00059  *    3.x         lost
00060  *    4.0     1
00061  *    4.1   122   0.3.3, 0.3.4
00062  *    4.2  1222   0.3.5
00063  *    4.3  1417
00064  *    4.4  1426
00065  *    5.0  1429
00066  *    5.1  1440
00067  *    5.2  1525   0.3.6
00068  *    6.0  1721
00069  *    6.1  1768
00070  *    7.0  1770
00071  *    8.0  1786
00072  *    9.0  1909
00073  *   10.0  2030
00074  *   11.0  2033
00075  *   11.1  2041
00076  *   12.1  2046
00077  *   13.1  2080   0.4.0, 0.4.0.1
00078  *   14.0  2441
00079  *   15.0  2499
00080  *   16.0  2817
00081  *   16.1  3155
00082  *   17.0  3212
00083  *   17.1  3218
00084  *   18    3227
00085  *   19    3396
00086  *   20    3403
00087  *   21    3472   0.4.x
00088  *   22    3726
00089  *   23    3915
00090  *   24    4150
00091  *   25    4259
00092  *   26    4466
00093  *   27    4757
00094  *   28    4987
00095  *   29    5070
00096  *   30    5946
00097  *   31    5999
00098  *   32    6001
00099  *   33    6440
00100  *   34    6455
00101  *   35    6602
00102  *   36    6624
00103  *   37    7182
00104  *   38    7195
00105  *   39    7269
00106  *   40    7326
00107  *   41    7348   0.5.x
00108  *   42    7573
00109  *   43    7642
00110  *   44    8144
00111  *   45    8501
00112  *   46    8705
00113  *   47    8735
00114  *   48    8935
00115  *   49    8969
00116  *   50    8973
00117  *   51    8978
00118  *   52    9066
00119  *   53    9316
00120  *   54    9613
00121  *   55    9638
00122  *   56    9667
00123  *   57    9691
00124  *   58    9762
00125  *   59    9779
00126  *   60    9874
00127  *   61    9892
00128  *   62    9905
00129  *   63    9956
00130  *   64   10006
00131  *   65   10210
00132  *   66   10211
00133  *   67   10236
00134  *   68   10266
00135  *   69   10319
00136  *   70   10541
00137  *   71   10567
00138  *   72   10601
00139  *   73   10903
00140  *   74   11030
00141  *   75   11107
00142  *   76   11139
00143  *   77   11172
00144  *   78   11176
00145  *   79   11188
00146  *   80   11228
00147  *   81   11244
00148  *   82   11410
00149  *   83   11589
00150  *   84   11822
00151  *   85   11874
00152  *   86   12042
00153  *   87   12129
00154  *   88   12134
00155  *   89   12160
00156  *   90   12293
00157  *   91   12347
00158  *   92   12381   0.6.x
00159  *   93   12648
00160  *   94   12816
00161  *   95   12924
00162  *   96   13226
00163  *   97   13256
00164  *   98   13375
00165  *   99   13838
00166  *  100   13952
00167  *  101   14233
00168  *  102   14332
00169  *  103   14598
00170  *  104   14735
00171  *  105   14803
00172  *  106   14919
00173  *  107   15027
00174  *  108   15045
00175  *  109   15075
00176  *  110   15148
00177  *  111   15190
00178  *  112   15290
00179  *  113   15340
00180  *  114   15601
00181  *  115   15695
00182  *  116   15893   0.7.x
00183  *  117   16037
00184  *  118   16129
00185  *  119   16242
00186  *  120   16439
00187  *  121   16694
00188  *  122   16855
00189  *  123   16909
00190  *  124   16993
00191  *  125   17113
00192  *  126   17433
00193  *  127   17439
00194  *  128   18281
00195  *  129   18292
00196  *  130   18404
00197  *  131   18481
00198  *  132   18522
00199  *  133   18674
00200  *  134   18703
00201  *  135   18719
00202  *  136   18764
00203  *  137   18912
00204  *  138   18942   1.0.x
00205  *  139   19346
00206  *  140   19382
00207  *  141   19799
00208  *  142   20003
00209  *  143   20048
00210  *  144   20334
00211  *  145   20376
00212  *  146   20446
00213  *  147   20621
00214  *  148   20659
00215  *  149   20832
00216  *  150   20857
00217  *  151   20918
00218  *  152   21171
00219  *  153   21263
00220  *  154   21426
00221  *  155   21453
00222  *  156   21728
00223  *  157   21862
00224  *  158   21933
00225  *  159   21962
00226  *  160   21974   1.1.x
00227  *  161   22567
00228  *  162   22713
00229  *  163   22767
00230  *  164   23290
00231  *  165   23304
00232  *  166   23415
00233  *  167   23504
00234  *  168   23637
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   inline 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   inline 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 _goal_chunk_handlers[];
00406 extern const ChunkHandler _ai_chunk_handlers[];
00407 extern const ChunkHandler _game_chunk_handlers[];
00408 extern const ChunkHandler _animated_tile_chunk_handlers[];
00409 extern const ChunkHandler _newgrf_chunk_handlers[];
00410 extern const ChunkHandler _group_chunk_handlers[];
00411 extern const ChunkHandler _cargopacket_chunk_handlers[];
00412 extern const ChunkHandler _autoreplace_chunk_handlers[];
00413 extern const ChunkHandler _labelmaps_chunk_handlers[];
00414 extern const ChunkHandler _linkgraph_chunk_handlers[];
00415 extern const ChunkHandler _airport_chunk_handlers[];
00416 extern const ChunkHandler _object_chunk_handlers[];
00417 extern const ChunkHandler _persistent_storage_chunk_handlers[];
00418 
00420 static const ChunkHandler * const _chunk_handlers[] = {
00421   _gamelog_chunk_handlers,
00422   _map_chunk_handlers,
00423   _misc_chunk_handlers,
00424   _name_chunk_handlers,
00425   _cheat_chunk_handlers,
00426   _setting_chunk_handlers,
00427   _veh_chunk_handlers,
00428   _waypoint_chunk_handlers,
00429   _depot_chunk_handlers,
00430   _order_chunk_handlers,
00431   _industry_chunk_handlers,
00432   _economy_chunk_handlers,
00433   _subsidy_chunk_handlers,
00434   _goal_chunk_handlers,
00435   _engine_chunk_handlers,
00436   _town_chunk_handlers,
00437   _sign_chunk_handlers,
00438   _station_chunk_handlers,
00439   _company_chunk_handlers,
00440   _ai_chunk_handlers,
00441   _game_chunk_handlers,
00442   _animated_tile_chunk_handlers,
00443   _newgrf_chunk_handlers,
00444   _group_chunk_handlers,
00445   _cargopacket_chunk_handlers,
00446   _autoreplace_chunk_handlers,
00447   _labelmaps_chunk_handlers,
00448   _linkgraph_chunk_handlers,
00449   _airport_chunk_handlers,
00450   _object_chunk_handlers,
00451   _persistent_storage_chunk_handlers,
00452   NULL,
00453 };
00454 
00459 #define FOR_ALL_CHUNK_HANDLERS(ch) \
00460   for (const ChunkHandler * const *chsc = _chunk_handlers; *chsc != NULL; chsc++) \
00461     for (const ChunkHandler *ch = *chsc; ch != NULL; ch = (ch->flags & CH_LAST) ? NULL : ch + 1)
00462 
00464 static void SlNullPointers()
00465 {
00466   _sl.action = SLA_NULL;
00467 
00468   /* We don't want any savegame conversion code to run
00469    * during NULLing; especially those that try to get
00470    * pointers from other pools. */
00471   _sl_version = SAVEGAME_VERSION;
00472 
00473   DEBUG(sl, 1, "Nulling pointers");
00474 
00475   FOR_ALL_CHUNK_HANDLERS(ch) {
00476     if (ch->ptrs_proc != NULL) {
00477       DEBUG(sl, 2, "Nulling pointers for %c%c%c%c", ch->id >> 24, ch->id >> 16, ch->id >> 8, ch->id);
00478       ch->ptrs_proc();
00479     }
00480   }
00481 
00482   DEBUG(sl, 1, "All pointers nulled");
00483 
00484   assert(_sl.action == SLA_NULL);
00485 }
00486 
00495 void NORETURN SlError(StringID string, const char *extra_msg)
00496 {
00497   /* Distinguish between loading into _load_check_data vs. normal save/load. */
00498   if (_sl.action == SLA_LOAD_CHECK) {
00499     _load_check_data.error = string;
00500     free(_load_check_data.error_data);
00501     _load_check_data.error_data = (extra_msg == NULL) ? NULL : strdup(extra_msg);
00502   } else {
00503     _sl.error_str = string;
00504     free(_sl.extra_msg);
00505     _sl.extra_msg = (extra_msg == NULL) ? NULL : strdup(extra_msg);
00506   }
00507 
00508   /* We have to NULL all pointers here; we might be in a state where
00509    * the pointers are actually filled with indices, which means that
00510    * when we access them during cleaning the pool dereferences of
00511    * those indices will be made with segmentation faults as result. */
00512   if (_sl.action == SLA_LOAD || _sl.action == SLA_PTRS) SlNullPointers();
00513   throw std::exception();
00514 }
00515 
00523 void NORETURN SlErrorCorrupt(const char *msg)
00524 {
00525   SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, msg);
00526 }
00527 
00528 
00529 typedef void (*AsyncSaveFinishProc)();                
00530 static AsyncSaveFinishProc _async_save_finish = NULL; 
00531 static ThreadObject *_save_thread;                    
00532 
00537 static void SetAsyncSaveFinish(AsyncSaveFinishProc proc)
00538 {
00539   if (_exit_game) return;
00540   while (_async_save_finish != NULL) CSleep(10);
00541 
00542   _async_save_finish = proc;
00543 }
00544 
00548 void ProcessAsyncSaveFinish()
00549 {
00550   if (_async_save_finish == NULL) return;
00551 
00552   _async_save_finish();
00553 
00554   _async_save_finish = NULL;
00555 
00556   if (_save_thread != NULL) {
00557     _save_thread->Join();
00558     delete _save_thread;
00559     _save_thread = NULL;
00560   }
00561 }
00562 
00567 byte SlReadByte()
00568 {
00569   return _sl.reader->ReadByte();
00570 }
00571 
00576 void SlWriteByte(byte b)
00577 {
00578   _sl.dumper->WriteByte(b);
00579 }
00580 
00581 static inline int SlReadUint16()
00582 {
00583   int x = SlReadByte() << 8;
00584   return x | SlReadByte();
00585 }
00586 
00587 static inline uint32 SlReadUint32()
00588 {
00589   uint32 x = SlReadUint16() << 16;
00590   return x | SlReadUint16();
00591 }
00592 
00593 static inline uint64 SlReadUint64()
00594 {
00595   uint32 x = SlReadUint32();
00596   uint32 y = SlReadUint32();
00597   return (uint64)x << 32 | y;
00598 }
00599 
00600 static inline void SlWriteUint16(uint16 v)
00601 {
00602   SlWriteByte(GB(v, 8, 8));
00603   SlWriteByte(GB(v, 0, 8));
00604 }
00605 
00606 static inline void SlWriteUint32(uint32 v)
00607 {
00608   SlWriteUint16(GB(v, 16, 16));
00609   SlWriteUint16(GB(v,  0, 16));
00610 }
00611 
00612 static inline void SlWriteUint64(uint64 x)
00613 {
00614   SlWriteUint32((uint32)(x >> 32));
00615   SlWriteUint32((uint32)x);
00616 }
00617 
00623 static inline void SlSkipBytes(size_t length)
00624 {
00625   for (; length != 0; length--) SlReadByte();
00626 }
00627 
00637 static uint SlReadSimpleGamma()
00638 {
00639   uint i = SlReadByte();
00640   if (HasBit(i, 7)) {
00641     i &= ~0x80;
00642     if (HasBit(i, 6)) {
00643       i &= ~0x40;
00644       if (HasBit(i, 5)) {
00645         i &= ~0x20;
00646         if (HasBit(i, 4)) {
00647           SlErrorCorrupt("Unsupported gamma");
00648         }
00649         i = (i << 8) | SlReadByte();
00650       }
00651       i = (i << 8) | SlReadByte();
00652     }
00653     i = (i << 8) | SlReadByte();
00654   }
00655   return i;
00656 }
00657 
00670 static void SlWriteSimpleGamma(size_t i)
00671 {
00672   if (i >= (1 << 7)) {
00673     if (i >= (1 << 14)) {
00674       if (i >= (1 << 21)) {
00675         assert(i < (1 << 28));
00676         SlWriteByte((byte)(0xE0 | (i >> 24)));
00677         SlWriteByte((byte)(i >> 16));
00678       } else {
00679         SlWriteByte((byte)(0xC0 | (i >> 16)));
00680       }
00681       SlWriteByte((byte)(i >> 8));
00682     } else {
00683       SlWriteByte((byte)(0x80 | (i >> 8)));
00684     }
00685   }
00686   SlWriteByte((byte)i);
00687 }
00688 
00690 static inline uint SlGetGammaLength(size_t i)
00691 {
00692   return 1 + (i >= (1 << 7)) + (i >= (1 << 14)) + (i >= (1 << 21));
00693 }
00694 
00695 static inline uint SlReadSparseIndex()
00696 {
00697   return SlReadSimpleGamma();
00698 }
00699 
00700 static inline void SlWriteSparseIndex(uint index)
00701 {
00702   SlWriteSimpleGamma(index);
00703 }
00704 
00705 static inline uint SlReadArrayLength()
00706 {
00707   return SlReadSimpleGamma();
00708 }
00709 
00710 static inline void SlWriteArrayLength(size_t length)
00711 {
00712   SlWriteSimpleGamma(length);
00713 }
00714 
00715 static inline uint SlGetArrayLength(size_t length)
00716 {
00717   return SlGetGammaLength(length);
00718 }
00719 
00726 static inline uint SlCalcConvMemLen(VarType conv)
00727 {
00728   static const byte conv_mem_size[] = {1, 1, 1, 2, 2, 4, 4, 8, 8, 0};
00729   byte length = GB(conv, 4, 4);
00730 
00731   switch (length << 4) {
00732     case SLE_VAR_STRB:
00733     case SLE_VAR_STRBQ:
00734     case SLE_VAR_STR:
00735     case SLE_VAR_STRQ:
00736       return SlReadArrayLength();
00737 
00738     default:
00739       assert(length < lengthof(conv_mem_size));
00740       return conv_mem_size[length];
00741   }
00742 }
00743 
00750 static inline byte SlCalcConvFileLen(VarType conv)
00751 {
00752   static const byte conv_file_size[] = {1, 1, 2, 2, 4, 4, 8, 8, 2};
00753   byte length = GB(conv, 0, 4);
00754   assert(length < lengthof(conv_file_size));
00755   return conv_file_size[length];
00756 }
00757 
00759 static inline size_t SlCalcRefLen()
00760 {
00761   return IsSavegameVersionBefore(69) ? 2 : 4;
00762 }
00763 
00764 void SlSetArrayIndex(uint index)
00765 {
00766   _sl.need_length = NL_WANTLENGTH;
00767   _sl.array_index = index;
00768 }
00769 
00770 static size_t _next_offs;
00771 
00776 int SlIterateArray()
00777 {
00778   int index;
00779 
00780   /* After reading in the whole array inside the loop
00781    * we must have read in all the data, so we must be at end of current block. */
00782   if (_next_offs != 0 && _sl.reader->GetSize() != _next_offs) SlErrorCorrupt("Invalid chunk size");
00783 
00784   for (;;) {
00785     uint length = SlReadArrayLength();
00786     if (length == 0) {
00787       _next_offs = 0;
00788       return -1;
00789     }
00790 
00791     _sl.obj_len = --length;
00792     _next_offs = _sl.reader->GetSize() + length;
00793 
00794     switch (_sl.block_mode) {
00795       case CH_SPARSE_ARRAY: index = (int)SlReadSparseIndex(); break;
00796       case CH_ARRAY:        index = _sl.array_index++; break;
00797       default:
00798         DEBUG(sl, 0, "SlIterateArray error");
00799         return -1; // error
00800     }
00801 
00802     if (length != 0) return index;
00803   }
00804 }
00805 
00809 void SlSkipArray()
00810 {
00811   while (SlIterateArray() != -1) {
00812     SlSkipBytes(_next_offs - _sl.reader->GetSize());
00813   }
00814 }
00815 
00821 void SlSetLength(size_t length)
00822 {
00823   assert(_sl.action == SLA_SAVE);
00824 
00825   switch (_sl.need_length) {
00826     case NL_WANTLENGTH:
00827       _sl.need_length = NL_NONE;
00828       switch (_sl.block_mode) {
00829         case CH_RIFF:
00830           /* Ugly encoding of >16M RIFF chunks
00831            * The lower 24 bits are normal
00832            * The uppermost 4 bits are bits 24:27 */
00833           assert(length < (1 << 28));
00834           SlWriteUint32((uint32)((length & 0xFFFFFF) | ((length >> 24) << 28)));
00835           break;
00836         case CH_ARRAY:
00837           assert(_sl.last_array_index <= _sl.array_index);
00838           while (++_sl.last_array_index <= _sl.array_index) {
00839             SlWriteArrayLength(1);
00840           }
00841           SlWriteArrayLength(length + 1);
00842           break;
00843         case CH_SPARSE_ARRAY:
00844           SlWriteArrayLength(length + 1 + SlGetArrayLength(_sl.array_index)); // Also include length of sparse index.
00845           SlWriteSparseIndex(_sl.array_index);
00846           break;
00847         default: NOT_REACHED();
00848       }
00849       break;
00850 
00851     case NL_CALCLENGTH:
00852       _sl.obj_len += (int)length;
00853       break;
00854 
00855     default: NOT_REACHED();
00856   }
00857 }
00858 
00865 static void SlCopyBytes(void *ptr, size_t length)
00866 {
00867   byte *p = (byte *)ptr;
00868 
00869   switch (_sl.action) {
00870     case SLA_LOAD_CHECK:
00871     case SLA_LOAD:
00872       for (; length != 0; length--) *p++ = SlReadByte();
00873       break;
00874     case SLA_SAVE:
00875       for (; length != 0; length--) SlWriteByte(*p++);
00876       break;
00877     default: NOT_REACHED();
00878   }
00879 }
00880 
00882 size_t SlGetFieldLength()
00883 {
00884   return _sl.obj_len;
00885 }
00886 
00894 int64 ReadValue(const void *ptr, VarType conv)
00895 {
00896   switch (GetVarMemType(conv)) {
00897     case SLE_VAR_BL:  return (*(const bool *)ptr != 0);
00898     case SLE_VAR_I8:  return *(const int8  *)ptr;
00899     case SLE_VAR_U8:  return *(const byte  *)ptr;
00900     case SLE_VAR_I16: return *(const int16 *)ptr;
00901     case SLE_VAR_U16: return *(const uint16*)ptr;
00902     case SLE_VAR_I32: return *(const int32 *)ptr;
00903     case SLE_VAR_U32: return *(const uint32*)ptr;
00904     case SLE_VAR_I64: return *(const int64 *)ptr;
00905     case SLE_VAR_U64: return *(const uint64*)ptr;
00906     case SLE_VAR_NULL:return 0;
00907     default: NOT_REACHED();
00908   }
00909 }
00910 
00918 void WriteValue(void *ptr, VarType conv, int64 val)
00919 {
00920   switch (GetVarMemType(conv)) {
00921     case SLE_VAR_BL:  *(bool  *)ptr = (val != 0);  break;
00922     case SLE_VAR_I8:  *(int8  *)ptr = val; break;
00923     case SLE_VAR_U8:  *(byte  *)ptr = val; break;
00924     case SLE_VAR_I16: *(int16 *)ptr = val; break;
00925     case SLE_VAR_U16: *(uint16*)ptr = val; break;
00926     case SLE_VAR_I32: *(int32 *)ptr = val; break;
00927     case SLE_VAR_U32: *(uint32*)ptr = val; break;
00928     case SLE_VAR_I64: *(int64 *)ptr = val; break;
00929     case SLE_VAR_U64: *(uint64*)ptr = val; break;
00930     case SLE_VAR_NAME: *(char**)ptr = CopyFromOldName(val); break;
00931     case SLE_VAR_NULL: break;
00932     default: NOT_REACHED();
00933   }
00934 }
00935 
00944 static void SlSaveLoadConv(void *ptr, VarType conv)
00945 {
00946   switch (_sl.action) {
00947     case SLA_SAVE: {
00948       int64 x = ReadValue(ptr, conv);
00949 
00950       /* Write the value to the file and check if its value is in the desired range */
00951       switch (GetVarFileType(conv)) {
00952         case SLE_FILE_I8: assert(x >= -128 && x <= 127);     SlWriteByte(x);break;
00953         case SLE_FILE_U8: assert(x >= 0 && x <= 255);        SlWriteByte(x);break;
00954         case SLE_FILE_I16:assert(x >= -32768 && x <= 32767); SlWriteUint16(x);break;
00955         case SLE_FILE_STRINGID:
00956         case SLE_FILE_U16:assert(x >= 0 && x <= 65535);      SlWriteUint16(x);break;
00957         case SLE_FILE_I32:
00958         case SLE_FILE_U32:                                   SlWriteUint32((uint32)x);break;
00959         case SLE_FILE_I64:
00960         case SLE_FILE_U64:                                   SlWriteUint64(x);break;
00961         default: NOT_REACHED();
00962       }
00963       break;
00964     }
00965     case SLA_LOAD_CHECK:
00966     case SLA_LOAD: {
00967       int64 x;
00968       /* Read a value from the file */
00969       switch (GetVarFileType(conv)) {
00970         case SLE_FILE_I8:  x = (int8  )SlReadByte();   break;
00971         case SLE_FILE_U8:  x = (byte  )SlReadByte();   break;
00972         case SLE_FILE_I16: x = (int16 )SlReadUint16(); break;
00973         case SLE_FILE_U16: x = (uint16)SlReadUint16(); break;
00974         case SLE_FILE_I32: x = (int32 )SlReadUint32(); break;
00975         case SLE_FILE_U32: x = (uint32)SlReadUint32(); break;
00976         case SLE_FILE_I64: x = (int64 )SlReadUint64(); break;
00977         case SLE_FILE_U64: x = (uint64)SlReadUint64(); break;
00978         case SLE_FILE_STRINGID: x = RemapOldStringID((uint16)SlReadUint16()); break;
00979         default: NOT_REACHED();
00980       }
00981 
00982       /* Write The value to the struct. These ARE endian safe. */
00983       WriteValue(ptr, conv, x);
00984       break;
00985     }
00986     case SLA_PTRS: break;
00987     case SLA_NULL: break;
00988     default: NOT_REACHED();
00989   }
00990 }
00991 
01001 static inline size_t SlCalcNetStringLen(const char *ptr, size_t length)
01002 {
01003   if (ptr == NULL) return 0;
01004   return min(strlen(ptr), length - 1);
01005 }
01006 
01016 static inline size_t SlCalcStringLen(const void *ptr, size_t length, VarType conv)
01017 {
01018   size_t len;
01019   const char *str;
01020 
01021   switch (GetVarMemType(conv)) {
01022     default: NOT_REACHED();
01023     case SLE_VAR_STR:
01024     case SLE_VAR_STRQ:
01025       str = *(const char * const *)ptr;
01026       len = SIZE_MAX;
01027       break;
01028     case SLE_VAR_STRB:
01029     case SLE_VAR_STRBQ:
01030       str = (const char *)ptr;
01031       len = length;
01032       break;
01033   }
01034 
01035   len = SlCalcNetStringLen(str, len);
01036   return len + SlGetArrayLength(len); // also include the length of the index
01037 }
01038 
01045 static void SlString(void *ptr, size_t length, VarType conv)
01046 {
01047   switch (_sl.action) {
01048     case SLA_SAVE: {
01049       size_t len;
01050       switch (GetVarMemType(conv)) {
01051         default: NOT_REACHED();
01052         case SLE_VAR_STRB:
01053         case SLE_VAR_STRBQ:
01054           len = SlCalcNetStringLen((char *)ptr, length);
01055           break;
01056         case SLE_VAR_STR:
01057         case SLE_VAR_STRQ:
01058           ptr = *(char **)ptr;
01059           len = SlCalcNetStringLen((char *)ptr, SIZE_MAX);
01060           break;
01061       }
01062 
01063       SlWriteArrayLength(len);
01064       SlCopyBytes(ptr, len);
01065       break;
01066     }
01067     case SLA_LOAD_CHECK:
01068     case SLA_LOAD: {
01069       size_t len = SlReadArrayLength();
01070 
01071       switch (GetVarMemType(conv)) {
01072         default: NOT_REACHED();
01073         case SLE_VAR_STRB:
01074         case SLE_VAR_STRBQ:
01075           if (len >= length) {
01076             DEBUG(sl, 1, "String length in savegame is bigger than buffer, truncating");
01077             SlCopyBytes(ptr, length);
01078             SlSkipBytes(len - length);
01079             len = length - 1;
01080           } else {
01081             SlCopyBytes(ptr, len);
01082           }
01083           break;
01084         case SLE_VAR_STR:
01085         case SLE_VAR_STRQ: // Malloc'd string, free previous incarnation, and allocate
01086           free(*(char **)ptr);
01087           if (len == 0) {
01088             *(char **)ptr = NULL;
01089           } else {
01090             *(char **)ptr = MallocT<char>(len + 1); // terminating '\0'
01091             ptr = *(char **)ptr;
01092             SlCopyBytes(ptr, len);
01093           }
01094           break;
01095       }
01096 
01097       ((char *)ptr)[len] = '\0'; // properly terminate the string
01098       StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK;
01099       if ((conv & SLF_ALLOW_CONTROL) != 0) {
01100         settings = settings | SVS_ALLOW_CONTROL_CODE;
01101       }
01102       if ((conv & SLF_ALLOW_NEWLINE) != 0) {
01103         settings = settings | SVS_ALLOW_NEWLINE;
01104       }
01105       str_validate((char *)ptr, (char *)ptr + len, settings);
01106       break;
01107     }
01108     case SLA_PTRS: break;
01109     case SLA_NULL: break;
01110     default: NOT_REACHED();
01111   }
01112 }
01113 
01119 static inline size_t SlCalcArrayLen(size_t length, VarType conv)
01120 {
01121   return SlCalcConvFileLen(conv) * length;
01122 }
01123 
01130 void SlArray(void *array, size_t length, VarType conv)
01131 {
01132   if (_sl.action == SLA_PTRS || _sl.action == SLA_NULL) return;
01133 
01134   /* Automatically calculate the length? */
01135   if (_sl.need_length != NL_NONE) {
01136     SlSetLength(SlCalcArrayLen(length, conv));
01137     /* Determine length only? */
01138     if (_sl.need_length == NL_CALCLENGTH) return;
01139   }
01140 
01141   /* NOTICE - handle some buggy stuff, in really old versions everything was saved
01142    * as a byte-type. So detect this, and adjust array size accordingly */
01143   if (_sl.action != SLA_SAVE && _sl_version == 0) {
01144     /* all arrays except difficulty settings */
01145     if (conv == SLE_INT16 || conv == SLE_UINT16 || conv == SLE_STRINGID ||
01146         conv == SLE_INT32 || conv == SLE_UINT32) {
01147       SlCopyBytes(array, length * SlCalcConvFileLen(conv));
01148       return;
01149     }
01150     /* used for conversion of Money 32bit->64bit */
01151     if (conv == (SLE_FILE_I32 | SLE_VAR_I64)) {
01152       for (uint i = 0; i < length; i++) {
01153         ((int64*)array)[i] = (int32)BSWAP32(SlReadUint32());
01154       }
01155       return;
01156     }
01157   }
01158 
01159   /* If the size of elements is 1 byte both in file and memory, no special
01160    * conversion is needed, use specialized copy-copy function to speed up things */
01161   if (conv == SLE_INT8 || conv == SLE_UINT8) {
01162     SlCopyBytes(array, length);
01163   } else {
01164     byte *a = (byte*)array;
01165     byte mem_size = SlCalcConvMemLen(conv);
01166 
01167     for (; length != 0; length --) {
01168       SlSaveLoadConv(a, conv);
01169       a += mem_size; // get size
01170     }
01171   }
01172 }
01173 
01174 
01185 static size_t ReferenceToInt(const void *obj, SLRefType rt)
01186 {
01187   assert(_sl.action == SLA_SAVE);
01188 
01189   if (obj == NULL) return 0;
01190 
01191   switch (rt) {
01192     case REF_VEHICLE_OLD: // Old vehicles we save as new onces
01193     case REF_VEHICLE:   return ((const  Vehicle*)obj)->index + 1;
01194     case REF_STATION:   return ((const  Station*)obj)->index + 1;
01195     case REF_TOWN:      return ((const     Town*)obj)->index + 1;
01196     case REF_ORDER:     return ((const    Order*)obj)->index + 1;
01197     case REF_ROADSTOPS: return ((const RoadStop*)obj)->index + 1;
01198     case REF_ENGINE_RENEWS: return ((const       EngineRenew*)obj)->index + 1;
01199     case REF_CARGO_PACKET:  return ((const       CargoPacket*)obj)->index + 1;
01200     case REF_ORDERLIST:     return ((const         OrderList*)obj)->index + 1;
01201     case REF_STORAGE:       return ((const PersistentStorage*)obj)->index + 1;
01202     default: NOT_REACHED();
01203   }
01204 }
01205 
01216 static void *IntToReference(size_t index, SLRefType rt)
01217 {
01218   assert_compile(sizeof(size_t) <= sizeof(void *));
01219 
01220   assert(_sl.action == SLA_PTRS);
01221 
01222   /* After version 4.3 REF_VEHICLE_OLD is saved as REF_VEHICLE,
01223    * and should be loaded like that */
01224   if (rt == REF_VEHICLE_OLD && !IsSavegameVersionBefore(4, 4)) {
01225     rt = REF_VEHICLE;
01226   }
01227 
01228   /* No need to look up NULL pointers, just return immediately */
01229   if (index == (rt == REF_VEHICLE_OLD ? 0xFFFF : 0)) return NULL;
01230 
01231   /* Correct index. Old vehicles were saved differently:
01232    * invalid vehicle was 0xFFFF, now we use 0x0000 for everything invalid. */
01233   if (rt != REF_VEHICLE_OLD) index--;
01234 
01235   switch (rt) {
01236     case REF_ORDERLIST:
01237       if (OrderList::IsValidID(index)) return OrderList::Get(index);
01238       SlErrorCorrupt("Referencing invalid OrderList");
01239 
01240     case REF_ORDER:
01241       if (Order::IsValidID(index)) return Order::Get(index);
01242       /* in old versions, invalid order was used to mark end of order list */
01243       if (IsSavegameVersionBefore(5, 2)) return NULL;
01244       SlErrorCorrupt("Referencing invalid Order");
01245 
01246     case REF_VEHICLE_OLD:
01247     case REF_VEHICLE:
01248       if (Vehicle::IsValidID(index)) return Vehicle::Get(index);
01249       SlErrorCorrupt("Referencing invalid Vehicle");
01250 
01251     case REF_STATION:
01252       if (Station::IsValidID(index)) return Station::Get(index);
01253       SlErrorCorrupt("Referencing invalid Station");
01254 
01255     case REF_TOWN:
01256       if (Town::IsValidID(index)) return Town::Get(index);
01257       SlErrorCorrupt("Referencing invalid Town");
01258 
01259     case REF_ROADSTOPS:
01260       if (RoadStop::IsValidID(index)) return RoadStop::Get(index);
01261       SlErrorCorrupt("Referencing invalid RoadStop");
01262 
01263     case REF_ENGINE_RENEWS:
01264       if (EngineRenew::IsValidID(index)) return EngineRenew::Get(index);
01265       SlErrorCorrupt("Referencing invalid EngineRenew");
01266 
01267     case REF_CARGO_PACKET:
01268       if (CargoPacket::IsValidID(index)) return CargoPacket::Get(index);
01269       SlErrorCorrupt("Referencing invalid CargoPacket");
01270 
01271     case REF_STORAGE:
01272       if (PersistentStorage::IsValidID(index)) return PersistentStorage::Get(index);
01273       SlErrorCorrupt("Referencing invalid PersistentStorage");
01274 
01275     default: NOT_REACHED();
01276   }
01277 }
01278 
01283 static inline size_t SlCalcListLen(const void *list)
01284 {
01285   const std::list<void *> *l = (const std::list<void *> *) list;
01286 
01287   int type_size = IsSavegameVersionBefore(69) ? 2 : 4;
01288   /* Each entry is saved as type_size bytes, plus type_size bytes are used for the length
01289    * of the list */
01290   return l->size() * type_size + type_size;
01291 }
01292 
01293 
01299 static void SlList(void *list, SLRefType conv)
01300 {
01301   /* Automatically calculate the length? */
01302   if (_sl.need_length != NL_NONE) {
01303     SlSetLength(SlCalcListLen(list));
01304     /* Determine length only? */
01305     if (_sl.need_length == NL_CALCLENGTH) return;
01306   }
01307 
01308   typedef std::list<void *> PtrList;
01309   PtrList *l = (PtrList *)list;
01310 
01311   switch (_sl.action) {
01312     case SLA_SAVE: {
01313       SlWriteUint32((uint32)l->size());
01314 
01315       PtrList::iterator iter;
01316       for (iter = l->begin(); iter != l->end(); ++iter) {
01317         void *ptr = *iter;
01318         SlWriteUint32((uint32)ReferenceToInt(ptr, conv));
01319       }
01320       break;
01321     }
01322     case SLA_LOAD_CHECK:
01323     case SLA_LOAD: {
01324       size_t length = IsSavegameVersionBefore(69) ? SlReadUint16() : SlReadUint32();
01325 
01326       /* Load each reference and push to the end of the list */
01327       for (size_t i = 0; i < length; i++) {
01328         size_t data = IsSavegameVersionBefore(69) ? SlReadUint16() : SlReadUint32();
01329         l->push_back((void *)data);
01330       }
01331       break;
01332     }
01333     case SLA_PTRS: {
01334       PtrList temp = *l;
01335 
01336       l->clear();
01337       PtrList::iterator iter;
01338       for (iter = temp.begin(); iter != temp.end(); ++iter) {
01339         void *ptr = IntToReference((size_t)*iter, conv);
01340         l->push_back(ptr);
01341       }
01342       break;
01343     }
01344     case SLA_NULL:
01345       l->clear();
01346       break;
01347     default: NOT_REACHED();
01348   }
01349 }
01350 
01351 
01353 static inline bool SlIsObjectValidInSavegame(const SaveLoad *sld)
01354 {
01355   if (_sl_version < sld->version_from || _sl_version > sld->version_to) return false;
01356   if (sld->conv & SLF_NOT_IN_SAVE) return false;
01357 
01358   return true;
01359 }
01360 
01366 static inline bool SlSkipVariableOnLoad(const SaveLoad *sld)
01367 {
01368   if ((sld->conv & SLF_NO_NETWORK_SYNC) && _sl.action != SLA_SAVE && _networking && !_network_server) {
01369     SlSkipBytes(SlCalcConvMemLen(sld->conv) * sld->length);
01370     return true;
01371   }
01372 
01373   return false;
01374 }
01375 
01382 size_t SlCalcObjLength(const void *object, const SaveLoad *sld)
01383 {
01384   size_t length = 0;
01385 
01386   /* Need to determine the length and write a length tag. */
01387   for (; sld->cmd != SL_END; sld++) {
01388     length += SlCalcObjMemberLength(object, sld);
01389   }
01390   return length;
01391 }
01392 
01393 size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld)
01394 {
01395   assert(_sl.action == SLA_SAVE);
01396 
01397   switch (sld->cmd) {
01398     case SL_VAR:
01399     case SL_REF:
01400     case SL_ARR:
01401     case SL_STR:
01402     case SL_LST:
01403       /* CONDITIONAL saveload types depend on the savegame version */
01404       if (!SlIsObjectValidInSavegame(sld)) break;
01405 
01406       switch (sld->cmd) {
01407         case SL_VAR: return SlCalcConvFileLen(sld->conv);
01408         case SL_REF: return SlCalcRefLen();
01409         case SL_ARR: return SlCalcArrayLen(sld->length, sld->conv);
01410         case SL_STR: return SlCalcStringLen(GetVariableAddress(object, sld), sld->length, sld->conv);
01411         case SL_LST: return SlCalcListLen(GetVariableAddress(object, sld));
01412         default: NOT_REACHED();
01413       }
01414       break;
01415     case SL_WRITEBYTE: return 1; // a byte is logically of size 1
01416     case SL_VEH_INCLUDE: return SlCalcObjLength(object, GetVehicleDescription(VEH_END));
01417     case SL_ST_INCLUDE: return SlCalcObjLength(object, GetBaseStationDescription());
01418     default: NOT_REACHED();
01419   }
01420   return 0;
01421 }
01422 
01423 
01424 bool SlObjectMember(void *ptr, const SaveLoad *sld)
01425 {
01426   VarType conv = GB(sld->conv, 0, 8);
01427   switch (sld->cmd) {
01428     case SL_VAR:
01429     case SL_REF:
01430     case SL_ARR:
01431     case SL_STR:
01432     case SL_LST:
01433       /* CONDITIONAL saveload types depend on the savegame version */
01434       if (!SlIsObjectValidInSavegame(sld)) return false;
01435       if (SlSkipVariableOnLoad(sld)) return false;
01436 
01437       switch (sld->cmd) {
01438         case SL_VAR: SlSaveLoadConv(ptr, conv); break;
01439         case SL_REF: // Reference variable, translate
01440           switch (_sl.action) {
01441             case SLA_SAVE:
01442               SlWriteUint32((uint32)ReferenceToInt(*(void **)ptr, (SLRefType)conv));
01443               break;
01444             case SLA_LOAD_CHECK:
01445             case SLA_LOAD:
01446               *(size_t *)ptr = IsSavegameVersionBefore(69) ? SlReadUint16() : SlReadUint32();
01447               break;
01448             case SLA_PTRS:
01449               *(void **)ptr = IntToReference(*(size_t *)ptr, (SLRefType)conv);
01450               break;
01451             case SLA_NULL:
01452               *(void **)ptr = NULL;
01453               break;
01454             default: NOT_REACHED();
01455           }
01456           break;
01457         case SL_ARR: SlArray(ptr, sld->length, conv); break;
01458         case SL_STR: SlString(ptr, sld->length, sld->conv); break;
01459         case SL_LST: SlList(ptr, (SLRefType)conv); break;
01460         default: NOT_REACHED();
01461       }
01462       break;
01463 
01464     /* SL_WRITEBYTE translates a value of a variable to another one upon
01465      * saving or loading.
01466      * XXX - variable renaming abuse
01467      * game_value: the value of the variable ingame is abused by sld->version_from
01468      * file_value: the value of the variable in the savegame is abused by sld->version_to */
01469     case SL_WRITEBYTE:
01470       switch (_sl.action) {
01471         case SLA_SAVE: SlWriteByte(sld->version_to); break;
01472         case SLA_LOAD_CHECK:
01473         case SLA_LOAD: *(byte *)ptr = sld->version_from; break;
01474         case SLA_PTRS: break;
01475         case SLA_NULL: break;
01476         default: NOT_REACHED();
01477       }
01478       break;
01479 
01480     /* SL_VEH_INCLUDE loads common code for vehicles */
01481     case SL_VEH_INCLUDE:
01482       SlObject(ptr, GetVehicleDescription(VEH_END));
01483       break;
01484 
01485     case SL_ST_INCLUDE:
01486       SlObject(ptr, GetBaseStationDescription());
01487       break;
01488 
01489     default: NOT_REACHED();
01490   }
01491   return true;
01492 }
01493 
01499 void SlObject(void *object, const SaveLoad *sld)
01500 {
01501   /* Automatically calculate the length? */
01502   if (_sl.need_length != NL_NONE) {
01503     SlSetLength(SlCalcObjLength(object, sld));
01504     if (_sl.need_length == NL_CALCLENGTH) return;
01505   }
01506 
01507   for (; sld->cmd != SL_END; sld++) {
01508     void *ptr = sld->global ? sld->address : GetVariableAddress(object, sld);
01509     SlObjectMember(ptr, sld);
01510   }
01511 }
01512 
01517 void SlGlobList(const SaveLoadGlobVarList *sldg)
01518 {
01519   SlObject(NULL, (const SaveLoad*)sldg);
01520 }
01521 
01527 void SlAutolength(AutolengthProc *proc, void *arg)
01528 {
01529   size_t offs;
01530 
01531   assert(_sl.action == SLA_SAVE);
01532 
01533   /* Tell it to calculate the length */
01534   _sl.need_length = NL_CALCLENGTH;
01535   _sl.obj_len = 0;
01536   proc(arg);
01537 
01538   /* Setup length */
01539   _sl.need_length = NL_WANTLENGTH;
01540   SlSetLength(_sl.obj_len);
01541 
01542   offs = _sl.dumper->GetSize() + _sl.obj_len;
01543 
01544   /* And write the stuff */
01545   proc(arg);
01546 
01547   if (offs != _sl.dumper->GetSize()) SlErrorCorrupt("Invalid chunk size");
01548 }
01549 
01554 static void SlLoadChunk(const ChunkHandler *ch)
01555 {
01556   byte m = SlReadByte();
01557   size_t len;
01558   size_t endoffs;
01559 
01560   _sl.block_mode = m;
01561   _sl.obj_len = 0;
01562 
01563   switch (m) {
01564     case CH_ARRAY:
01565       _sl.array_index = 0;
01566       ch->load_proc();
01567       break;
01568     case CH_SPARSE_ARRAY:
01569       ch->load_proc();
01570       break;
01571     default:
01572       if ((m & 0xF) == CH_RIFF) {
01573         /* Read length */
01574         len = (SlReadByte() << 16) | ((m >> 4) << 24);
01575         len += SlReadUint16();
01576         _sl.obj_len = len;
01577         endoffs = _sl.reader->GetSize() + len;
01578         ch->load_proc();
01579         if (_sl.reader->GetSize() != endoffs) SlErrorCorrupt("Invalid chunk size");
01580       } else {
01581         SlErrorCorrupt("Invalid chunk type");
01582       }
01583       break;
01584   }
01585 }
01586 
01592 static void SlLoadCheckChunk(const ChunkHandler *ch)
01593 {
01594   byte m = SlReadByte();
01595   size_t len;
01596   size_t endoffs;
01597 
01598   _sl.block_mode = m;
01599   _sl.obj_len = 0;
01600 
01601   switch (m) {
01602     case CH_ARRAY:
01603       _sl.array_index = 0;
01604       if (ch->load_check_proc) {
01605         ch->load_check_proc();
01606       } else {
01607         SlSkipArray();
01608       }
01609       break;
01610     case CH_SPARSE_ARRAY:
01611       if (ch->load_check_proc) {
01612         ch->load_check_proc();
01613       } else {
01614         SlSkipArray();
01615       }
01616       break;
01617     default:
01618       if ((m & 0xF) == CH_RIFF) {
01619         /* Read length */
01620         len = (SlReadByte() << 16) | ((m >> 4) << 24);
01621         len += SlReadUint16();
01622         _sl.obj_len = len;
01623         endoffs = _sl.reader->GetSize() + len;
01624         if (ch->load_check_proc) {
01625           ch->load_check_proc();
01626         } else {
01627           SlSkipBytes(len);
01628         }
01629         if (_sl.reader->GetSize() != endoffs) SlErrorCorrupt("Invalid chunk size");
01630       } else {
01631         SlErrorCorrupt("Invalid chunk type");
01632       }
01633       break;
01634   }
01635 }
01636 
01641 static ChunkSaveLoadProc *_stub_save_proc;
01642 
01648 static inline void SlStubSaveProc2(void *arg)
01649 {
01650   _stub_save_proc();
01651 }
01652 
01658 static void SlStubSaveProc()
01659 {
01660   SlAutolength(SlStubSaveProc2, NULL);
01661 }
01662 
01668 static void SlSaveChunk(const ChunkHandler *ch)
01669 {
01670   ChunkSaveLoadProc *proc = ch->save_proc;
01671 
01672   /* Don't save any chunk information if there is no save handler. */
01673   if (proc == NULL) return;
01674 
01675   SlWriteUint32(ch->id);
01676   DEBUG(sl, 2, "Saving chunk %c%c%c%c", ch->id >> 24, ch->id >> 16, ch->id >> 8, ch->id);
01677 
01678   if (ch->flags & CH_AUTO_LENGTH) {
01679     /* Need to calculate the length. Solve that by calling SlAutoLength in the save_proc. */
01680     _stub_save_proc = proc;
01681     proc = SlStubSaveProc;
01682   }
01683 
01684   _sl.block_mode = ch->flags & CH_TYPE_MASK;
01685   switch (ch->flags & CH_TYPE_MASK) {
01686     case CH_RIFF:
01687       _sl.need_length = NL_WANTLENGTH;
01688       proc();
01689       break;
01690     case CH_ARRAY:
01691       _sl.last_array_index = 0;
01692       SlWriteByte(CH_ARRAY);
01693       proc();
01694       SlWriteArrayLength(0); // Terminate arrays
01695       break;
01696     case CH_SPARSE_ARRAY:
01697       SlWriteByte(CH_SPARSE_ARRAY);
01698       proc();
01699       SlWriteArrayLength(0); // Terminate arrays
01700       break;
01701     default: NOT_REACHED();
01702   }
01703 }
01704 
01706 static void SlSaveChunks()
01707 {
01708   FOR_ALL_CHUNK_HANDLERS(ch) {
01709     SlSaveChunk(ch);
01710   }
01711 
01712   /* Terminator */
01713   SlWriteUint32(0);
01714 }
01715 
01722 static const ChunkHandler *SlFindChunkHandler(uint32 id)
01723 {
01724   FOR_ALL_CHUNK_HANDLERS(ch) if (ch->id == id) return ch;
01725   return NULL;
01726 }
01727 
01729 static void SlLoadChunks()
01730 {
01731   uint32 id;
01732   const ChunkHandler *ch;
01733 
01734   for (id = SlReadUint32(); id != 0; id = SlReadUint32()) {
01735     DEBUG(sl, 2, "Loading chunk %c%c%c%c", id >> 24, id >> 16, id >> 8, id);
01736 
01737     ch = SlFindChunkHandler(id);
01738     if (ch == NULL) SlErrorCorrupt("Unknown chunk type");
01739     SlLoadChunk(ch);
01740   }
01741 }
01742 
01744 static void SlLoadCheckChunks()
01745 {
01746   uint32 id;
01747   const ChunkHandler *ch;
01748 
01749   for (id = SlReadUint32(); id != 0; id = SlReadUint32()) {
01750     DEBUG(sl, 2, "Loading chunk %c%c%c%c", id >> 24, id >> 16, id >> 8, id);
01751 
01752     ch = SlFindChunkHandler(id);
01753     if (ch == NULL) SlErrorCorrupt("Unknown chunk type");
01754     SlLoadCheckChunk(ch);
01755   }
01756 }
01757 
01759 static void SlFixPointers()
01760 {
01761   _sl.action = SLA_PTRS;
01762 
01763   DEBUG(sl, 1, "Fixing pointers");
01764 
01765   FOR_ALL_CHUNK_HANDLERS(ch) {
01766     if (ch->ptrs_proc != NULL) {
01767       DEBUG(sl, 2, "Fixing pointers for %c%c%c%c", ch->id >> 24, ch->id >> 16, ch->id >> 8, ch->id);
01768       ch->ptrs_proc();
01769     }
01770   }
01771 
01772   DEBUG(sl, 1, "All pointers fixed");
01773 
01774   assert(_sl.action == SLA_PTRS);
01775 }
01776 
01777 
01779 struct FileReader : LoadFilter {
01780   FILE *file; 
01781   long begin; 
01782 
01787   FileReader(FILE *file) : LoadFilter(NULL), file(file), begin(ftell(file))
01788   {
01789   }
01790 
01792   ~FileReader()
01793   {
01794     if (this->file != NULL) fclose(this->file);
01795     this->file = NULL;
01796 
01797     /* Make sure we don't double free. */
01798     _sl.sf = NULL;
01799   }
01800 
01801   /* virtual */ size_t Read(byte *buf, size_t size)
01802   {
01803     /* We're in the process of shutting down, i.e. in "failure" mode. */
01804     if (this->file == NULL) return 0;
01805 
01806     return fread(buf, 1, size, this->file);
01807   }
01808 
01809   /* virtual */ void Reset()
01810   {
01811     clearerr(this->file);
01812     fseek(this->file, this->begin, SEEK_SET);
01813   }
01814 };
01815 
01817 struct FileWriter : SaveFilter {
01818   FILE *file; 
01819 
01824   FileWriter(FILE *file) : SaveFilter(NULL), file(file)
01825   {
01826   }
01827 
01829   ~FileWriter()
01830   {
01831     this->Finish();
01832 
01833     /* Make sure we don't double free. */
01834     _sl.sf = NULL;
01835   }
01836 
01837   /* virtual */ void Write(byte *buf, size_t size)
01838   {
01839     /* We're in the process of shutting down, i.e. in "failure" mode. */
01840     if (this->file == NULL) return;
01841 
01842     if (fwrite(buf, 1, size, this->file) != size) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE);
01843   }
01844 
01845   /* virtual */ void Finish()
01846   {
01847     if (this->file != NULL) fclose(this->file);
01848     this->file = NULL;
01849   }
01850 };
01851 
01852 /*******************************************
01853  ********** START OF LZO CODE **************
01854  *******************************************/
01855 
01856 #ifdef WITH_LZO
01857 #include <lzo/lzo1x.h>
01858 
01860 static const uint LZO_BUFFER_SIZE = 8192;
01861 
01863 struct LZOLoadFilter : LoadFilter {
01868   LZOLoadFilter(LoadFilter *chain) : LoadFilter(chain)
01869   {
01870     if (lzo_init() != LZO_E_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize decompressor");
01871   }
01872 
01873   /* virtual */ size_t Read(byte *buf, size_t ssize)
01874   {
01875     assert(ssize >= LZO_BUFFER_SIZE);
01876 
01877     /* Buffer size is from the LZO docs plus the chunk header size. */
01878     byte out[LZO_BUFFER_SIZE + LZO_BUFFER_SIZE / 16 + 64 + 3 + sizeof(uint32) * 2];
01879     uint32 tmp[2];
01880     uint32 size;
01881     lzo_uint len;
01882 
01883     /* Read header*/
01884     if (this->chain->Read((byte*)tmp, sizeof(tmp)) != sizeof(tmp)) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE, "File read failed");
01885 
01886     /* Check if size is bad */
01887     ((uint32*)out)[0] = size = tmp[1];
01888 
01889     if (_sl_version != 0) {
01890       tmp[0] = TO_BE32(tmp[0]);
01891       size = TO_BE32(size);
01892     }
01893 
01894     if (size >= sizeof(out)) SlErrorCorrupt("Inconsistent size");
01895 
01896     /* Read block */
01897     if (this->chain->Read(out + sizeof(uint32), size) != size) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
01898 
01899     /* Verify checksum */
01900     if (tmp[0] != lzo_adler32(0, out, size + sizeof(uint32))) SlErrorCorrupt("Bad checksum");
01901 
01902     /* Decompress */
01903     lzo1x_decompress(out + sizeof(uint32) * 1, size, buf, &len, NULL);
01904     return len;
01905   }
01906 };
01907 
01909 struct LZOSaveFilter : SaveFilter {
01915   LZOSaveFilter(SaveFilter *chain, byte compression_level) : SaveFilter(chain)
01916   {
01917     if (lzo_init() != LZO_E_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize compressor");
01918   }
01919 
01920   /* virtual */ void Write(byte *buf, size_t size)
01921   {
01922     const lzo_bytep in = buf;
01923     /* Buffer size is from the LZO docs plus the chunk header size. */
01924     byte out[LZO_BUFFER_SIZE + LZO_BUFFER_SIZE / 16 + 64 + 3 + sizeof(uint32) * 2];
01925     byte wrkmem[LZO1X_1_MEM_COMPRESS];
01926     lzo_uint outlen;
01927 
01928     do {
01929       /* Compress up to LZO_BUFFER_SIZE bytes at once. */
01930       lzo_uint len = size > LZO_BUFFER_SIZE ? LZO_BUFFER_SIZE : (lzo_uint)size;
01931       lzo1x_1_compress(in, len, out + sizeof(uint32) * 2, &outlen, wrkmem);
01932       ((uint32*)out)[1] = TO_BE32((uint32)outlen);
01933       ((uint32*)out)[0] = TO_BE32(lzo_adler32(0, out + sizeof(uint32), outlen + sizeof(uint32)));
01934       this->chain->Write(out, outlen + sizeof(uint32) * 2);
01935 
01936       /* Move to next data chunk. */
01937       size -= len;
01938       in += len;
01939     } while (size > 0);
01940   }
01941 };
01942 
01943 #endif /* WITH_LZO */
01944 
01945 /*********************************************
01946  ******** START OF NOCOMP CODE (uncompressed)*
01947  *********************************************/
01948 
01950 struct NoCompLoadFilter : LoadFilter {
01955   NoCompLoadFilter(LoadFilter *chain) : LoadFilter(chain)
01956   {
01957   }
01958 
01959   /* virtual */ size_t Read(byte *buf, size_t size)
01960   {
01961     return this->chain->Read(buf, size);
01962   }
01963 };
01964 
01966 struct NoCompSaveFilter : SaveFilter {
01972   NoCompSaveFilter(SaveFilter *chain, byte compression_level) : SaveFilter(chain)
01973   {
01974   }
01975 
01976   /* virtual */ void Write(byte *buf, size_t size)
01977   {
01978     this->chain->Write(buf, size);
01979   }
01980 };
01981 
01982 /********************************************
01983  ********** START OF ZLIB CODE **************
01984  ********************************************/
01985 
01986 #if defined(WITH_ZLIB)
01987 #include <zlib.h>
01988 
01990 struct ZlibLoadFilter : LoadFilter {
01991   z_stream z;                        
01992   byte fread_buf[MEMORY_CHUNK_SIZE]; 
01993 
01998   ZlibLoadFilter(LoadFilter *chain) : LoadFilter(chain)
01999   {
02000     memset(&this->z, 0, sizeof(this->z));
02001     if (inflateInit(&this->z) != Z_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize decompressor");
02002   }
02003 
02005   ~ZlibLoadFilter()
02006   {
02007     inflateEnd(&this->z);
02008   }
02009 
02010   /* virtual */ size_t Read(byte *buf, size_t size)
02011   {
02012     this->z.next_out  = buf;
02013     this->z.avail_out = (uint)size;
02014 
02015     do {
02016       /* read more bytes from the file? */
02017       if (this->z.avail_in == 0) {
02018         this->z.next_in = this->fread_buf;
02019         this->z.avail_in = (uint)this->chain->Read(this->fread_buf, sizeof(this->fread_buf));
02020       }
02021 
02022       /* inflate the data */
02023       int r = inflate(&this->z, 0);
02024       if (r == Z_STREAM_END) break;
02025 
02026       if (r != Z_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "inflate() failed");
02027     } while (this->z.avail_out != 0);
02028 
02029     return size - this->z.avail_out;
02030   }
02031 };
02032 
02034 struct ZlibSaveFilter : SaveFilter {
02035   z_stream z; 
02036 
02042   ZlibSaveFilter(SaveFilter *chain, byte compression_level) : SaveFilter(chain)
02043   {
02044     memset(&this->z, 0, sizeof(this->z));
02045     if (deflateInit(&this->z, compression_level) != Z_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize compressor");
02046   }
02047 
02049   ~ZlibSaveFilter()
02050   {
02051     deflateEnd(&this->z);
02052   }
02053 
02060   void WriteLoop(byte *p, size_t len, int mode)
02061   {
02062     byte buf[MEMORY_CHUNK_SIZE]; // output buffer
02063     uint n;
02064     this->z.next_in = p;
02065     this->z.avail_in = (uInt)len;
02066     do {
02067       this->z.next_out = buf;
02068       this->z.avail_out = sizeof(buf);
02069 
02077       int r = deflate(&this->z, mode);
02078 
02079       /* bytes were emitted? */
02080       if ((n = sizeof(buf) - this->z.avail_out) != 0) {
02081         this->chain->Write(buf, n);
02082       }
02083       if (r == Z_STREAM_END) break;
02084 
02085       if (r != Z_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "zlib returned error code");
02086     } while (this->z.avail_in || !this->z.avail_out);
02087   }
02088 
02089   /* virtual */ void Write(byte *buf, size_t size)
02090   {
02091     this->WriteLoop(buf, size, 0);
02092   }
02093 
02094   /* virtual */ void Finish()
02095   {
02096     this->WriteLoop(NULL, 0, Z_FINISH);
02097     this->chain->Finish();
02098   }
02099 };
02100 
02101 #endif /* WITH_ZLIB */
02102 
02103 /********************************************
02104  ********** START OF LZMA CODE **************
02105  ********************************************/
02106 
02107 #if defined(WITH_LZMA)
02108 #include <lzma.h>
02109 
02116 static const lzma_stream _lzma_init = LZMA_STREAM_INIT;
02117 
02119 struct LZMALoadFilter : LoadFilter {
02120   lzma_stream lzma;                  
02121   byte fread_buf[MEMORY_CHUNK_SIZE]; 
02122 
02127   LZMALoadFilter(LoadFilter *chain) : LoadFilter(chain), lzma(_lzma_init)
02128   {
02129     /* Allow saves up to 256 MB uncompressed */
02130     if (lzma_auto_decoder(&this->lzma, 1 << 28, 0) != LZMA_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize decompressor");
02131   }
02132 
02134   ~LZMALoadFilter()
02135   {
02136     lzma_end(&this->lzma);
02137   }
02138 
02139   /* virtual */ size_t Read(byte *buf, size_t size)
02140   {
02141     this->lzma.next_out  = buf;
02142     this->lzma.avail_out = size;
02143 
02144     do {
02145       /* read more bytes from the file? */
02146       if (this->lzma.avail_in == 0) {
02147         this->lzma.next_in  = this->fread_buf;
02148         this->lzma.avail_in = this->chain->Read(this->fread_buf, sizeof(this->fread_buf));
02149       }
02150 
02151       /* inflate the data */
02152       lzma_ret r = lzma_code(&this->lzma, LZMA_RUN);
02153       if (r == LZMA_STREAM_END) break;
02154       if (r != LZMA_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "liblzma returned error code");
02155     } while (this->lzma.avail_out != 0);
02156 
02157     return size - this->lzma.avail_out;
02158   }
02159 };
02160 
02162 struct LZMASaveFilter : SaveFilter {
02163   lzma_stream lzma; 
02164 
02170   LZMASaveFilter(SaveFilter *chain, byte compression_level) : SaveFilter(chain), lzma(_lzma_init)
02171   {
02172     if (lzma_easy_encoder(&this->lzma, compression_level, LZMA_CHECK_CRC32) != LZMA_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize compressor");
02173   }
02174 
02176   ~LZMASaveFilter()
02177   {
02178     lzma_end(&this->lzma);
02179   }
02180 
02187   void WriteLoop(byte *p, size_t len, lzma_action action)
02188   {
02189     byte buf[MEMORY_CHUNK_SIZE]; // output buffer
02190     size_t n;
02191     this->lzma.next_in = p;
02192     this->lzma.avail_in = len;
02193     do {
02194       this->lzma.next_out = buf;
02195       this->lzma.avail_out = sizeof(buf);
02196 
02197       lzma_ret r = lzma_code(&this->lzma, action);
02198 
02199       /* bytes were emitted? */
02200       if ((n = sizeof(buf) - this->lzma.avail_out) != 0) {
02201         this->chain->Write(buf, n);
02202       }
02203       if (r == LZMA_STREAM_END) break;
02204       if (r != LZMA_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "liblzma returned error code");
02205     } while (this->lzma.avail_in || !this->lzma.avail_out);
02206   }
02207 
02208   /* virtual */ void Write(byte *buf, size_t size)
02209   {
02210     this->WriteLoop(buf, size, LZMA_RUN);
02211   }
02212 
02213   /* virtual */ void Finish()
02214   {
02215     this->WriteLoop(NULL, 0, LZMA_FINISH);
02216     this->chain->Finish();
02217   }
02218 };
02219 
02220 #endif /* WITH_LZMA */
02221 
02222 /*******************************************
02223  ************* END OF CODE *****************
02224  *******************************************/
02225 
02227 struct SaveLoadFormat {
02228   const char *name;                     
02229   uint32 tag;                           
02230 
02231   LoadFilter *(*init_load)(LoadFilter *chain);                    
02232   SaveFilter *(*init_write)(SaveFilter *chain, byte compression); 
02233 
02234   byte min_compression;                 
02235   byte default_compression;             
02236   byte max_compression;                 
02237 };
02238 
02240 static const SaveLoadFormat _saveload_formats[] = {
02241 #if defined(WITH_LZO)
02242   /* Roughly 75% larger than zlib level 6 at only ~7% of the CPU usage. */
02243   {"lzo",    TO_BE32X('OTTD'), CreateLoadFilter<LZOLoadFilter>,    CreateSaveFilter<LZOSaveFilter>,    0, 0, 0},
02244 #else
02245   {"lzo",    TO_BE32X('OTTD'), NULL,                               NULL,                               0, 0, 0},
02246 #endif
02247   /* Roughly 5 times larger at only 1% of the CPU usage over zlib level 6. */
02248   {"none",   TO_BE32X('OTTN'), CreateLoadFilter<NoCompLoadFilter>, CreateSaveFilter<NoCompSaveFilter>, 0, 0, 0},
02249 #if defined(WITH_ZLIB)
02250   /* After level 6 the speed reduction is significant (1.5x to 2.5x slower per level), but the reduction in filesize is
02251    * fairly insignificant (~1% for each step). Lower levels become ~5-10% bigger by each level than level 6 while level
02252    * 1 is "only" 3 times as fast. Level 0 results in uncompressed savegames at about 8 times the cost of "none". */
02253   {"zlib",   TO_BE32X('OTTZ'), CreateLoadFilter<ZlibLoadFilter>,   CreateSaveFilter<ZlibSaveFilter>,   0, 6, 9},
02254 #else
02255   {"zlib",   TO_BE32X('OTTZ'), NULL,                               NULL,                               0, 0, 0},
02256 #endif
02257 #if defined(WITH_LZMA)
02258   /* Level 2 compression is speed wise as fast as zlib level 6 compression (old default), but results in ~10% smaller saves.
02259    * Higher compression levels are possible, and might improve savegame size by up to 25%, but are also up to 10 times slower.
02260    * The next significant reduction in file size is at level 4, but that is already 4 times slower. Level 3 is primarily 50%
02261    * slower while not improving the filesize, while level 0 and 1 are faster, but don't reduce savegame size much.
02262    * It's OTTX and not e.g. OTTL because liblzma is part of xz-utils and .tar.xz is prefered over .tar.lzma. */
02263   {"lzma",   TO_BE32X('OTTX'), CreateLoadFilter<LZMALoadFilter>,   CreateSaveFilter<LZMASaveFilter>,   0, 2, 9},
02264 #else
02265   {"lzma",   TO_BE32X('OTTX'), NULL,                               NULL,                               0, 0, 0},
02266 #endif
02267 };
02268 
02276 static const SaveLoadFormat *GetSavegameFormat(char *s, byte *compression_level)
02277 {
02278   const SaveLoadFormat *def = lastof(_saveload_formats);
02279 
02280   /* find default savegame format, the highest one with which files can be written */
02281   while (!def->init_write) def--;
02282 
02283   if (!StrEmpty(s)) {
02284     /* Get the ":..." of the compression level out of the way */
02285     char *complevel = strrchr(s, ':');
02286     if (complevel != NULL) *complevel = '\0';
02287 
02288     for (const SaveLoadFormat *slf = &_saveload_formats[0]; slf != endof(_saveload_formats); slf++) {
02289       if (slf->init_write != NULL && strcmp(s, slf->name) == 0) {
02290         *compression_level = slf->default_compression;
02291         if (complevel != NULL) {
02292           /* There is a compression level in the string.
02293            * First restore the : we removed to do proper name matching,
02294            * then move the the begin of the actual version. */
02295           *complevel = ':';
02296           complevel++;
02297 
02298           /* Get the version and determine whether all went fine. */
02299           char *end;
02300           long level = strtol(complevel, &end, 10);
02301           if (end == complevel || level != Clamp(level, slf->min_compression, slf->max_compression)) {
02302             SetDParamStr(0, complevel);
02303             ShowErrorMessage(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_SAVEGAME_COMPRESSION_LEVEL, WL_CRITICAL);
02304           } else {
02305             *compression_level = level;
02306           }
02307         }
02308         return slf;
02309       }
02310     }
02311 
02312     SetDParamStr(0, s);
02313     SetDParamStr(1, def->name);
02314     ShowErrorMessage(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_SAVEGAME_COMPRESSION_ALGORITHM, WL_CRITICAL);
02315 
02316     /* Restore the string by adding the : back */
02317     if (complevel != NULL) *complevel = ':';
02318   }
02319   *compression_level = def->default_compression;
02320   return def;
02321 }
02322 
02323 /* actual loader/saver function */
02324 void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settings);
02325 extern bool AfterLoadGame();
02326 extern bool LoadOldSaveGame(const char *file);
02327 
02331 static inline void ClearSaveLoadState()
02332 {
02333   delete _sl.dumper;
02334   _sl.dumper = NULL;
02335 
02336   delete _sl.sf;
02337   _sl.sf = NULL;
02338 
02339   delete _sl.reader;
02340   _sl.reader = NULL;
02341 
02342   delete _sl.lf;
02343   _sl.lf = NULL;
02344 }
02345 
02351 static void SaveFileStart()
02352 {
02353   _sl.ff_state = _fast_forward;
02354   _fast_forward = 0;
02355   if (_cursor.sprite == SPR_CURSOR_MOUSE) SetMouseCursor(SPR_CURSOR_ZZZ, PAL_NONE);
02356 
02357   InvalidateWindowData(WC_STATUS_BAR, 0, SBI_SAVELOAD_START);
02358   _sl.saveinprogress = true;
02359 }
02360 
02362 static void SaveFileDone()
02363 {
02364   if (_game_mode != GM_MENU) _fast_forward = _sl.ff_state;
02365   if (_cursor.sprite == SPR_CURSOR_ZZZ) SetMouseCursor(SPR_CURSOR_MOUSE, PAL_NONE);
02366 
02367   InvalidateWindowData(WC_STATUS_BAR, 0, SBI_SAVELOAD_FINISH);
02368   _sl.saveinprogress = false;
02369 }
02370 
02372 void SetSaveLoadError(StringID str)
02373 {
02374   _sl.error_str = str;
02375 }
02376 
02378 const char *GetSaveLoadErrorString()
02379 {
02380   SetDParam(0, _sl.error_str);
02381   SetDParamStr(1, _sl.extra_msg);
02382 
02383   static char err_str[512];
02384   GetString(err_str, _sl.action == SLA_SAVE ? STR_ERROR_GAME_SAVE_FAILED : STR_ERROR_GAME_LOAD_FAILED, lastof(err_str));
02385   return err_str;
02386 }
02387 
02389 static void SaveFileError()
02390 {
02391   SetDParamStr(0, GetSaveLoadErrorString());
02392   ShowErrorMessage(STR_JUST_RAW_STRING, INVALID_STRING_ID, WL_ERROR);
02393   SaveFileDone();
02394 }
02395 
02400 static SaveOrLoadResult SaveFileToDisk(bool threaded)
02401 {
02402   try {
02403     byte compression;
02404     const SaveLoadFormat *fmt = GetSavegameFormat(_savegame_format, &compression);
02405 
02406     /* We have written our stuff to memory, now write it to file! */
02407     uint32 hdr[2] = { fmt->tag, TO_BE32(SAVEGAME_VERSION << 16) };
02408     _sl.sf->Write((byte*)hdr, sizeof(hdr));
02409 
02410     _sl.sf = fmt->init_write(_sl.sf, compression);
02411     _sl.dumper->Flush(_sl.sf);
02412 
02413     ClearSaveLoadState();
02414 
02415     if (threaded) SetAsyncSaveFinish(SaveFileDone);
02416 
02417     return SL_OK;
02418   } catch (...) {
02419     ClearSaveLoadState();
02420 
02421     AsyncSaveFinishProc asfp = SaveFileDone;
02422 
02423     /* We don't want to shout when saving is just
02424      * cancelled due to a client disconnecting. */
02425     if (_sl.error_str != STR_NETWORK_ERROR_LOSTCONNECTION) {
02426       /* Skip the "colour" character */
02427       DEBUG(sl, 0, "%s", GetSaveLoadErrorString() + 3);
02428       asfp = SaveFileError;
02429     }
02430 
02431     if (threaded) {
02432       SetAsyncSaveFinish(asfp);
02433     } else {
02434       asfp();
02435     }
02436     return SL_ERROR;
02437   }
02438 }
02439 
02441 static void SaveFileToDiskThread(void *arg)
02442 {
02443   SaveFileToDisk(true);
02444 }
02445 
02446 void WaitTillSaved()
02447 {
02448   if (_save_thread == NULL) return;
02449 
02450   _save_thread->Join();
02451   delete _save_thread;
02452   _save_thread = NULL;
02453 
02454   /* Make sure every other state is handled properly as well. */
02455   ProcessAsyncSaveFinish();
02456 }
02457 
02466 static SaveOrLoadResult DoSave(SaveFilter *writer, bool threaded)
02467 {
02468   assert(!_sl.saveinprogress);
02469 
02470   _sl.dumper = new MemoryDumper();
02471   _sl.sf = writer;
02472 
02473   _sl_version = SAVEGAME_VERSION;
02474 
02475   SaveViewportBeforeSaveGame();
02476   SlSaveChunks();
02477 
02478   SaveFileStart();
02479   if (!threaded || !ThreadObject::New(&SaveFileToDiskThread, NULL, &_save_thread)) {
02480     if (threaded) DEBUG(sl, 1, "Cannot create savegame thread, reverting to single-threaded mode...");
02481 
02482     SaveOrLoadResult result = SaveFileToDisk(false);
02483     SaveFileDone();
02484 
02485     return result;
02486   }
02487 
02488   return SL_OK;
02489 }
02490 
02497 SaveOrLoadResult SaveWithFilter(SaveFilter *writer, bool threaded)
02498 {
02499   try {
02500     _sl.action = SLA_SAVE;
02501     return DoSave(writer, threaded);
02502   } catch (...) {
02503     ClearSaveLoadState();
02504     return SL_ERROR;
02505   }
02506 }
02507 
02514 static SaveOrLoadResult DoLoad(LoadFilter *reader, bool load_check)
02515 {
02516   _sl.lf = reader;
02517 
02518   if (load_check) {
02519     /* Clear previous check data */
02520     _load_check_data.Clear();
02521     /* Mark SL_LOAD_CHECK as supported for this savegame. */
02522     _load_check_data.checkable = true;
02523   }
02524 
02525   uint32 hdr[2];
02526   if (_sl.lf->Read((byte*)hdr, sizeof(hdr)) != sizeof(hdr)) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
02527 
02528   /* see if we have any loader for this type. */
02529   const SaveLoadFormat *fmt = _saveload_formats;
02530   for (;;) {
02531     /* No loader found, treat as version 0 and use LZO format */
02532     if (fmt == endof(_saveload_formats)) {
02533       DEBUG(sl, 0, "Unknown savegame type, trying to load it as the buggy format");
02534       _sl.lf->Reset();
02535       _sl_version = 0;
02536       _sl_minor_version = 0;
02537 
02538       /* Try to find the LZO savegame format; it uses 'OTTD' as tag. */
02539       fmt = _saveload_formats;
02540       for (;;) {
02541         if (fmt == endof(_saveload_formats)) {
02542           /* Who removed LZO support? Bad bad boy! */
02543           NOT_REACHED();
02544         }
02545         if (fmt->tag == TO_BE32X('OTTD')) break;
02546         fmt++;
02547       }
02548       break;
02549     }
02550 
02551     if (fmt->tag == hdr[0]) {
02552       /* check version number */
02553       _sl_version = TO_BE32(hdr[1]) >> 16;
02554       /* Minor is not used anymore from version 18.0, but it is still needed
02555        * in versions before that (4 cases) which can't be removed easy.
02556        * Therefor it is loaded, but never saved (or, it saves a 0 in any scenario). */
02557       _sl_minor_version = (TO_BE32(hdr[1]) >> 8) & 0xFF;
02558 
02559       DEBUG(sl, 1, "Loading savegame version %d", _sl_version);
02560 
02561       /* Is the version higher than the current? */
02562       if (_sl_version > SAVEGAME_VERSION) SlError(STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME);
02563       break;
02564     }
02565 
02566     fmt++;
02567   }
02568 
02569   /* loader for this savegame type is not implemented? */
02570   if (fmt->init_load == NULL) {
02571     char err_str[64];
02572     snprintf(err_str, lengthof(err_str), "Loader for '%s' is not available.", fmt->name);
02573     SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, err_str);
02574   }
02575 
02576   _sl.lf = fmt->init_load(_sl.lf);
02577   _sl.reader = new ReadBuffer(_sl.lf);
02578   _next_offs = 0;
02579 
02580   if (!load_check) {
02581     /* Old maps were hardcoded to 256x256 and thus did not contain
02582      * any mapsize information. Pre-initialize to 256x256 to not to
02583      * confuse old games */
02584     InitializeGame(256, 256, true, true);
02585 
02586     GamelogReset();
02587 
02588     if (IsSavegameVersionBefore(4)) {
02589       /*
02590        * NewGRFs were introduced between 0.3,4 and 0.3.5, which both
02591        * shared savegame version 4. Anything before that 'obviously'
02592        * does not have any NewGRFs. Between the introduction and
02593        * savegame version 41 (just before 0.5) the NewGRF settings
02594        * were not stored in the savegame and they were loaded by
02595        * using the settings from the main menu.
02596        * So, to recap:
02597        * - savegame version  <  4:  do not load any NewGRFs.
02598        * - savegame version >= 41:  load NewGRFs from savegame, which is
02599        *                            already done at this stage by
02600        *                            overwriting the main menu settings.
02601        * - other savegame versions: use main menu settings.
02602        *
02603        * This means that users *can* crash savegame version 4..40
02604        * savegames if they set incompatible NewGRFs in the main menu,
02605        * but can't crash anymore for savegame version < 4 savegames.
02606        *
02607        * Note: this is done here because AfterLoadGame is also called
02608        * for TTO/TTD/TTDP savegames which have their own NewGRF logic.
02609        */
02610       ClearGRFConfigList(&_grfconfig);
02611     }
02612   }
02613 
02614   if (load_check) {
02615     /* Load chunks into _load_check_data.
02616      * No pools are loaded. References are not possible, and thus do not need resolving. */
02617     SlLoadCheckChunks();
02618   } else {
02619     /* Load chunks and resolve references */
02620     SlLoadChunks();
02621     SlFixPointers();
02622   }
02623 
02624   ClearSaveLoadState();
02625 
02626   _savegame_type = SGT_OTTD;
02627 
02628   if (load_check) {
02629     /* The only part from AfterLoadGame() we need */
02630     _load_check_data.grf_compatibility = IsGoodGRFConfigList(_load_check_data.grfconfig);
02631   } else {
02632     GamelogStartAction(GLAT_LOAD);
02633 
02634     /* After loading fix up savegame for any internal changes that
02635      * might have occurred since then. If it fails, load back the old game. */
02636     if (!AfterLoadGame()) {
02637       GamelogStopAction();
02638       return SL_REINIT;
02639     }
02640 
02641     GamelogStopAction();
02642   }
02643 
02644   return SL_OK;
02645 }
02646 
02652 SaveOrLoadResult LoadWithFilter(LoadFilter *reader)
02653 {
02654   try {
02655     _sl.action = SLA_LOAD;
02656     return DoLoad(reader, false);
02657   } catch (...) {
02658     ClearSaveLoadState();
02659     return SL_REINIT;
02660   }
02661 }
02662 
02672 SaveOrLoadResult SaveOrLoad(const char *filename, int mode, Subdirectory sb, bool threaded)
02673 {
02674   /* An instance of saving is already active, so don't go saving again */
02675   if (_sl.saveinprogress && mode == SL_SAVE && threaded) {
02676     /* if not an autosave, but a user action, show error message */
02677     if (!_do_autosave) ShowErrorMessage(STR_ERROR_SAVE_STILL_IN_PROGRESS, INVALID_STRING_ID, WL_ERROR);
02678     return SL_OK;
02679   }
02680   WaitTillSaved();
02681 
02682   /* Load a TTDLX or TTDPatch game */
02683   if (mode == SL_OLD_LOAD) {
02684     InitializeGame(256, 256, true, true); // set a mapsize of 256x256 for TTDPatch games or it might get confused
02685 
02686     /* TTD/TTO savegames have no NewGRFs, TTDP savegame have them
02687      * and if so a new NewGRF list will be made in LoadOldSaveGame.
02688      * Note: this is done here because AfterLoadGame is also called
02689      * for OTTD savegames which have their own NewGRF logic. */
02690     ClearGRFConfigList(&_grfconfig);
02691     GamelogReset();
02692     if (!LoadOldSaveGame(filename)) return SL_REINIT;
02693     _sl_version = 0;
02694     _sl_minor_version = 0;
02695     GamelogStartAction(GLAT_LOAD);
02696     if (!AfterLoadGame()) {
02697       GamelogStopAction();
02698       return SL_REINIT;
02699     }
02700     GamelogStopAction();
02701     return SL_OK;
02702   }
02703 
02704   switch (mode) {
02705     case SL_LOAD_CHECK: _sl.action = SLA_LOAD_CHECK; break;
02706     case SL_LOAD: _sl.action = SLA_LOAD; break;
02707     case SL_SAVE: _sl.action = SLA_SAVE; break;
02708     default: NOT_REACHED();
02709   }
02710 
02711   try {
02712     FILE *fh = (mode == SL_SAVE) ? FioFOpenFile(filename, "wb", sb) : FioFOpenFile(filename, "rb", sb);
02713 
02714     /* Make it a little easier to load savegames from the console */
02715     if (fh == NULL && mode != SL_SAVE) fh = FioFOpenFile(filename, "rb", SAVE_DIR);
02716     if (fh == NULL && mode != SL_SAVE) fh = FioFOpenFile(filename, "rb", BASE_DIR);
02717     if (fh == NULL && mode != SL_SAVE) fh = FioFOpenFile(filename, "rb", SCENARIO_DIR);
02718 
02719     if (fh == NULL) {
02720       SlError(mode == SL_SAVE ? STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE : STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
02721     }
02722 
02723     if (mode == SL_SAVE) { // SAVE game
02724       DEBUG(desync, 1, "save: %08x; %02x; %s", _date, _date_fract, filename);
02725       if (_network_server || !_settings_client.gui.threaded_saves) threaded = false;
02726 
02727       return DoSave(new FileWriter(fh), threaded);
02728     }
02729 
02730     /* LOAD game */
02731     assert(mode == SL_LOAD || mode == SL_LOAD_CHECK);
02732     DEBUG(desync, 1, "load: %s", filename);
02733     return DoLoad(new FileReader(fh), mode == SL_LOAD_CHECK);
02734   } catch (...) {
02735     ClearSaveLoadState();
02736 
02737     /* Skip the "colour" character */
02738     if (mode != SL_LOAD_CHECK) DEBUG(sl, 0, "%s", GetSaveLoadErrorString() + 3);
02739 
02740     /* A saver/loader exception!! reinitialize all variables to prevent crash! */
02741     return (mode == SL_LOAD) ? SL_REINIT : SL_ERROR;
02742   }
02743 }
02744 
02746 void DoExitSave()
02747 {
02748   SaveOrLoad("exit.sav", SL_SAVE, AUTOSAVE_DIR);
02749 }
02750 
02756 void GenerateDefaultSaveName(char *buf, const char *last)
02757 {
02758   /* Check if we have a name for this map, which is the name of the first
02759    * available company. When there's no company available we'll use
02760    * 'Spectator' as "company" name. */
02761   CompanyID cid = _local_company;
02762   if (!Company::IsValidID(cid)) {
02763     const Company *c;
02764     FOR_ALL_COMPANIES(c) {
02765       cid = c->index;
02766       break;
02767     }
02768   }
02769 
02770   SetDParam(0, cid);
02771 
02772   /* Insert current date */
02773   switch (_settings_client.gui.date_format_in_default_names) {
02774     case 0: SetDParam(1, STR_JUST_DATE_LONG); break;
02775     case 1: SetDParam(1, STR_JUST_DATE_TINY); break;
02776     case 2: SetDParam(1, STR_JUST_DATE_ISO); break;
02777     default: NOT_REACHED();
02778   }
02779   SetDParam(2, _date);
02780 
02781   /* Get the correct string (special string for when there's not company) */
02782   GetString(buf, !Company::IsValidID(cid) ? STR_SAVEGAME_NAME_SPECTATOR : STR_SAVEGAME_NAME_DEFAULT, last);
02783   SanitizeFilename(buf);
02784 }
02785 
02786 #if 0
02787 
02793 int GetSavegameType(char *file)
02794 {
02795   const SaveLoadFormat *fmt;
02796   uint32 hdr;
02797   FILE *f;
02798   int mode = SL_OLD_LOAD;
02799 
02800   f = fopen(file, "rb");
02801   if (fread(&hdr, sizeof(hdr), 1, f) != 1) {
02802     DEBUG(sl, 0, "Savegame is obsolete or invalid format");
02803     mode = SL_LOAD; // don't try to get filename, just show name as it is written
02804   } else {
02805     /* see if we have any loader for this type. */
02806     for (fmt = _saveload_formats; fmt != endof(_saveload_formats); fmt++) {
02807       if (fmt->tag == hdr) {
02808         mode = SL_LOAD; // new type of savegame
02809         break;
02810       }
02811     }
02812   }
02813 
02814   fclose(f);
02815   return mode;
02816 }
02817 #endif