saveload.cpp

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