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 "../linkgraph/linkgraph.h"
00039 #include "../linkgraph/linkgraphjob.h"
00040 #include "../statusbar_gui.h"
00041 #include "../fileio_func.h"
00042 #include "../gamelog.h"
00043 #include "../string_func.h"
00044 #include "../fios.h"
00045 #include "../error.h"
00046 
00047 #include "table/strings.h"
00048 
00049 #include "saveload_internal.h"
00050 #include "saveload_filter.h"
00051 
00052 /*
00053  * Previous savegame versions, the trunk revision where they were
00054  * introduced and the released version that had that particular
00055  * savegame version.
00056  * Up to savegame version 18 there is a minor version as well.
00057  *
00058  *    1.0         0.1.x, 0.2.x
00059  *    2.0         0.3.0
00060  *    2.1         0.3.1, 0.3.2
00061  *    3.x         lost
00062  *    4.0     1
00063  *    4.1   122   0.3.3, 0.3.4
00064  *    4.2  1222   0.3.5
00065  *    4.3  1417
00066  *    4.4  1426
00067  *    5.0  1429
00068  *    5.1  1440
00069  *    5.2  1525   0.3.6
00070  *    6.0  1721
00071  *    6.1  1768
00072  *    7.0  1770
00073  *    8.0  1786
00074  *    9.0  1909
00075  *   10.0  2030
00076  *   11.0  2033
00077  *   11.1  2041
00078  *   12.1  2046
00079  *   13.1  2080   0.4.0, 0.4.0.1
00080  *   14.0  2441
00081  *   15.0  2499
00082  *   16.0  2817
00083  *   16.1  3155
00084  *   17.0  3212
00085  *   17.1  3218
00086  *   18    3227
00087  *   19    3396
00088  *   20    3403
00089  *   21    3472   0.4.x
00090  *   22    3726
00091  *   23    3915
00092  *   24    4150
00093  *   25    4259
00094  *   26    4466
00095  *   27    4757
00096  *   28    4987
00097  *   29    5070
00098  *   30    5946
00099  *   31    5999
00100  *   32    6001
00101  *   33    6440
00102  *   34    6455
00103  *   35    6602
00104  *   36    6624
00105  *   37    7182
00106  *   38    7195
00107  *   39    7269
00108  *   40    7326
00109  *   41    7348   0.5.x
00110  *   42    7573
00111  *   43    7642
00112  *   44    8144
00113  *   45    8501
00114  *   46    8705
00115  *   47    8735
00116  *   48    8935
00117  *   49    8969
00118  *   50    8973
00119  *   51    8978
00120  *   52    9066
00121  *   53    9316
00122  *   54    9613
00123  *   55    9638
00124  *   56    9667
00125  *   57    9691
00126  *   58    9762
00127  *   59    9779
00128  *   60    9874
00129  *   61    9892
00130  *   62    9905
00131  *   63    9956
00132  *   64   10006
00133  *   65   10210
00134  *   66   10211
00135  *   67   10236
00136  *   68   10266
00137  *   69   10319
00138  *   70   10541
00139  *   71   10567
00140  *   72   10601
00141  *   73   10903
00142  *   74   11030
00143  *   75   11107
00144  *   76   11139
00145  *   77   11172
00146  *   78   11176
00147  *   79   11188
00148  *   80   11228
00149  *   81   11244
00150  *   82   11410
00151  *   83   11589
00152  *   84   11822
00153  *   85   11874
00154  *   86   12042
00155  *   87   12129
00156  *   88   12134
00157  *   89   12160
00158  *   90   12293
00159  *   91   12347
00160  *   92   12381   0.6.x
00161  *   93   12648
00162  *   94   12816
00163  *   95   12924
00164  *   96   13226
00165  *   97   13256
00166  *   98   13375
00167  *   99   13838
00168  *  100   13952
00169  *  101   14233
00170  *  102   14332
00171  *  103   14598
00172  *  104   14735
00173  *  105   14803
00174  *  106   14919
00175  *  107   15027
00176  *  108   15045
00177  *  109   15075
00178  *  110   15148
00179  *  111   15190
00180  *  112   15290
00181  *  113   15340
00182  *  114   15601
00183  *  115   15695
00184  *  116   15893   0.7.x
00185  *  117   16037
00186  *  118   16129
00187  *  119   16242
00188  *  120   16439
00189  *  121   16694
00190  *  122   16855
00191  *  123   16909
00192  *  124   16993
00193  *  125   17113
00194  *  126   17433
00195  *  127   17439
00196  *  128   18281
00197  *  129   18292
00198  *  130   18404
00199  *  131   18481
00200  *  132   18522
00201  *  133   18674
00202  *  134   18703
00203  *  135   18719
00204  *  136   18764
00205  *  137   18912
00206  *  138   18942   1.0.x
00207  *  139   19346
00208  *  140   19382
00209  *  141   19799
00210  *  142   20003
00211  *  143   20048
00212  *  144   20334
00213  *  145   20376
00214  *  146   20446
00215  *  147   20621
00216  *  148   20659
00217  *  149   20832
00218  *  150   20857
00219  *  151   20918
00220  *  152   21171
00221  *  153   21263
00222  *  154   21426
00223  *  155   21453
00224  *  156   21728
00225  *  157   21862
00226  *  158   21933
00227  *  159   21962
00228  *  160   21974   1.1.x
00229  *  161   22567
00230  *  162   22713
00231  *  163   22767
00232  *  164   23290
00233  *  165   23304
00234  *  166   23415
00235  *  167   23504
00236  *  168   23637
00237  *  169   23816
00238  *  170   23826
00239  *  171   23835
00240  *  172   23947
00241  *  173   23967   1.2.0-RC1
00242  *  174   23973   1.2.x
00243  *  175   24136
00244  *  176   24446
00245  *  177   24619
00246  *  178   24789
00247  *  179   24810
00248  *  180   24998   1.3.x
00249  *  181   25012
00250  *  182   25259
00251  */
00252 extern const uint16 SAVEGAME_VERSION = SL_EXT_RATING; 
00253 
00254 SavegameType _savegame_type; 
00255 
00256 uint32 _ttdp_version;     
00257 uint16 _sl_version;       
00258 byte   _sl_minor_version; 
00259 char _savegame_format[8]; 
00260 bool _do_autosave;        
00261 
00263 enum SaveLoadAction {
00264   SLA_LOAD,        
00265   SLA_SAVE,        
00266   SLA_PTRS,        
00267   SLA_NULL,        
00268   SLA_LOAD_CHECK,  
00269 };
00270 
00271 enum NeedLength {
00272   NL_NONE = 0,       
00273   NL_WANTLENGTH = 1, 
00274   NL_CALCLENGTH = 2, 
00275 };
00276 
00278 static const size_t MEMORY_CHUNK_SIZE = 128 * 1024;
00279 
00281 struct ReadBuffer {
00282   byte buf[MEMORY_CHUNK_SIZE]; 
00283   byte *bufp;                  
00284   byte *bufe;                  
00285   LoadFilter *reader;          
00286   size_t read;                 
00287 
00292   ReadBuffer(LoadFilter *reader) : bufp(NULL), bufe(NULL), reader(reader), read(0)
00293   {
00294   }
00295 
00296   inline byte ReadByte()
00297   {
00298     if (this->bufp == this->bufe) {
00299       size_t len = this->reader->Read(this->buf, lengthof(this->buf));
00300       if (len == 0) SlErrorCorrupt("Unexpected end of chunk");
00301 
00302       this->read += len;
00303       this->bufp = this->buf;
00304       this->bufe = this->buf + len;
00305     }
00306 
00307     return *this->bufp++;
00308   }
00309 
00314   size_t GetSize() const
00315   {
00316     return this->read - (this->bufe - this->bufp);
00317   }
00318 };
00319 
00320 
00322 struct MemoryDumper {
00323   AutoFreeSmallVector<byte *, 16> blocks; 
00324   byte *buf;                              
00325   byte *bufe;                             
00326 
00328   MemoryDumper() : buf(NULL), bufe(NULL)
00329   {
00330   }
00331 
00336   inline void WriteByte(byte b)
00337   {
00338     /* Are we at the end of this chunk? */
00339     if (this->buf == this->bufe) {
00340       this->buf = CallocT<byte>(MEMORY_CHUNK_SIZE);
00341       *this->blocks.Append() = this->buf;
00342       this->bufe = this->buf + MEMORY_CHUNK_SIZE;
00343     }
00344 
00345     *this->buf++ = b;
00346   }
00347 
00352   void Flush(SaveFilter *writer)
00353   {
00354     uint i = 0;
00355     size_t t = this->GetSize();
00356 
00357     while (t > 0) {
00358       size_t to_write = min(MEMORY_CHUNK_SIZE, t);
00359 
00360       writer->Write(this->blocks[i++], to_write);
00361       t -= to_write;
00362     }
00363 
00364     writer->Finish();
00365   }
00366 
00371   size_t GetSize() const
00372   {
00373     return this->blocks.Length() * MEMORY_CHUNK_SIZE - (this->bufe - this->buf);
00374   }
00375 };
00376 
00378 struct SaveLoadParams {
00379   SaveLoadAction action;               
00380   NeedLength need_length;              
00381   byte block_mode;                     
00382   bool error;                          
00383 
00384   size_t obj_len;                      
00385   int array_index, last_array_index;   
00386 
00387   MemoryDumper *dumper;                
00388   SaveFilter *sf;                      
00389 
00390   ReadBuffer *reader;                  
00391   LoadFilter *lf;                      
00392 
00393   StringID error_str;                  
00394   char *extra_msg;                     
00395 
00396   byte ff_state;                       
00397   bool saveinprogress;                 
00398 };
00399 
00400 static SaveLoadParams _sl; 
00401 
00402 /* these define the chunks */
00403 extern const ChunkHandler _gamelog_chunk_handlers[];
00404 extern const ChunkHandler _map_chunk_handlers[];
00405 extern const ChunkHandler _misc_chunk_handlers[];
00406 extern const ChunkHandler _name_chunk_handlers[];
00407 extern const ChunkHandler _cheat_chunk_handlers[] ;
00408 extern const ChunkHandler _setting_chunk_handlers[];
00409 extern const ChunkHandler _company_chunk_handlers[];
00410 extern const ChunkHandler _engine_chunk_handlers[];
00411 extern const ChunkHandler _veh_chunk_handlers[];
00412 extern const ChunkHandler _waypoint_chunk_handlers[];
00413 extern const ChunkHandler _depot_chunk_handlers[];
00414 extern const ChunkHandler _order_chunk_handlers[];
00415 extern const ChunkHandler _town_chunk_handlers[];
00416 extern const ChunkHandler _sign_chunk_handlers[];
00417 extern const ChunkHandler _station_chunk_handlers[];
00418 extern const ChunkHandler _industry_chunk_handlers[];
00419 extern const ChunkHandler _economy_chunk_handlers[];
00420 extern const ChunkHandler _subsidy_chunk_handlers[];
00421 extern const ChunkHandler _cargomonitor_chunk_handlers[];
00422 extern const ChunkHandler _goal_chunk_handlers[];
00423 extern const ChunkHandler _ai_chunk_handlers[];
00424 extern const ChunkHandler _game_chunk_handlers[];
00425 extern const ChunkHandler _animated_tile_chunk_handlers[];
00426 extern const ChunkHandler _newgrf_chunk_handlers[];
00427 extern const ChunkHandler _group_chunk_handlers[];
00428 extern const ChunkHandler _cargopacket_chunk_handlers[];
00429 extern const ChunkHandler _autoreplace_chunk_handlers[];
00430 extern const ChunkHandler _labelmaps_chunk_handlers[];
00431 extern const ChunkHandler _linkgraph_chunk_handlers[];
00432 extern const ChunkHandler _airport_chunk_handlers[];
00433 extern const ChunkHandler _object_chunk_handlers[];
00434 extern const ChunkHandler _persistent_storage_chunk_handlers[];
00435 
00437 static const ChunkHandler * const _chunk_handlers[] = {
00438   _gamelog_chunk_handlers,
00439   _map_chunk_handlers,
00440   _misc_chunk_handlers,
00441   _name_chunk_handlers,
00442   _cheat_chunk_handlers,
00443   _setting_chunk_handlers,
00444   _veh_chunk_handlers,
00445   _waypoint_chunk_handlers,
00446   _depot_chunk_handlers,
00447   _order_chunk_handlers,
00448   _industry_chunk_handlers,
00449   _economy_chunk_handlers,
00450   _subsidy_chunk_handlers,
00451   _cargomonitor_chunk_handlers,
00452   _goal_chunk_handlers,
00453   _engine_chunk_handlers,
00454   _town_chunk_handlers,
00455   _sign_chunk_handlers,
00456   _station_chunk_handlers,
00457   _company_chunk_handlers,
00458   _ai_chunk_handlers,
00459   _game_chunk_handlers,
00460   _animated_tile_chunk_handlers,
00461   _newgrf_chunk_handlers,
00462   _group_chunk_handlers,
00463   _cargopacket_chunk_handlers,
00464   _autoreplace_chunk_handlers,
00465   _labelmaps_chunk_handlers,
00466   _linkgraph_chunk_handlers,
00467   _airport_chunk_handlers,
00468   _object_chunk_handlers,
00469   _persistent_storage_chunk_handlers,
00470   NULL,
00471 };
00472 
00477 #define FOR_ALL_CHUNK_HANDLERS(ch) \
00478   for (const ChunkHandler * const *chsc = _chunk_handlers; *chsc != NULL; chsc++) \
00479     for (const ChunkHandler *ch = *chsc; ch != NULL; ch = (ch->flags & CH_LAST) ? NULL : ch + 1)
00480 
00482 static void SlNullPointers()
00483 {
00484   _sl.action = SLA_NULL;
00485 
00486   /* We don't want any savegame conversion code to run
00487    * during NULLing; especially those that try to get
00488    * pointers from other pools. */
00489   _sl_version = SAVEGAME_VERSION;
00490 
00491   DEBUG(sl, 1, "Nulling pointers");
00492 
00493   FOR_ALL_CHUNK_HANDLERS(ch) {
00494     if (ch->ptrs_proc != NULL) {
00495       DEBUG(sl, 2, "Nulling pointers for %c%c%c%c", ch->id >> 24, ch->id >> 16, ch->id >> 8, ch->id);
00496       ch->ptrs_proc();
00497     }
00498   }
00499 
00500   DEBUG(sl, 1, "All pointers nulled");
00501 
00502   assert(_sl.action == SLA_NULL);
00503 }
00504 
00513 void NORETURN SlError(StringID string, const char *extra_msg)
00514 {
00515   /* Distinguish between loading into _load_check_data vs. normal save/load. */
00516   if (_sl.action == SLA_LOAD_CHECK) {
00517     _load_check_data.error = string;
00518     free(_load_check_data.error_data);
00519     _load_check_data.error_data = (extra_msg == NULL) ? NULL : strdup(extra_msg);
00520   } else {
00521     _sl.error_str = string;
00522     free(_sl.extra_msg);
00523     _sl.extra_msg = (extra_msg == NULL) ? NULL : strdup(extra_msg);
00524   }
00525 
00526   /* We have to NULL all pointers here; we might be in a state where
00527    * the pointers are actually filled with indices, which means that
00528    * when we access them during cleaning the pool dereferences of
00529    * those indices will be made with segmentation faults as result. */
00530   if (_sl.action == SLA_LOAD || _sl.action == SLA_PTRS) SlNullPointers();
00531   throw std::exception();
00532 }
00533 
00541 void NORETURN SlErrorCorrupt(const char *msg)
00542 {
00543   SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, msg);
00544 }
00545 
00546 
00547 typedef void (*AsyncSaveFinishProc)();                
00548 static AsyncSaveFinishProc _async_save_finish = NULL; 
00549 static ThreadObject *_save_thread;                    
00550 
00555 static void SetAsyncSaveFinish(AsyncSaveFinishProc proc)
00556 {
00557   if (_exit_game) return;
00558   while (_async_save_finish != NULL) CSleep(10);
00559 
00560   _async_save_finish = proc;
00561 }
00562 
00566 void ProcessAsyncSaveFinish()
00567 {
00568   if (_async_save_finish == NULL) return;
00569 
00570   _async_save_finish();
00571 
00572   _async_save_finish = NULL;
00573 
00574   if (_save_thread != NULL) {
00575     _save_thread->Join();
00576     delete _save_thread;
00577     _save_thread = NULL;
00578   }
00579 }
00580 
00585 byte SlReadByte()
00586 {
00587   return _sl.reader->ReadByte();
00588 }
00589 
00594 void SlWriteByte(byte b)
00595 {
00596   _sl.dumper->WriteByte(b);
00597 }
00598 
00599 static inline int SlReadUint16()
00600 {
00601   int x = SlReadByte() << 8;
00602   return x | SlReadByte();
00603 }
00604 
00605 static inline uint32 SlReadUint32()
00606 {
00607   uint32 x = SlReadUint16() << 16;
00608   return x | SlReadUint16();
00609 }
00610 
00611 static inline uint64 SlReadUint64()
00612 {
00613   uint32 x = SlReadUint32();
00614   uint32 y = SlReadUint32();
00615   return (uint64)x << 32 | y;
00616 }
00617 
00618 static inline void SlWriteUint16(uint16 v)
00619 {
00620   SlWriteByte(GB(v, 8, 8));
00621   SlWriteByte(GB(v, 0, 8));
00622 }
00623 
00624 static inline void SlWriteUint32(uint32 v)
00625 {
00626   SlWriteUint16(GB(v, 16, 16));
00627   SlWriteUint16(GB(v,  0, 16));
00628 }
00629 
00630 static inline void SlWriteUint64(uint64 x)
00631 {
00632   SlWriteUint32((uint32)(x >> 32));
00633   SlWriteUint32((uint32)x);
00634 }
00635 
00641 static inline void SlSkipBytes(size_t length)
00642 {
00643   for (; length != 0; length--) SlReadByte();
00644 }
00645 
00655 static uint SlReadSimpleGamma()
00656 {
00657   uint i = SlReadByte();
00658   if (HasBit(i, 7)) {
00659     i &= ~0x80;
00660     if (HasBit(i, 6)) {
00661       i &= ~0x40;
00662       if (HasBit(i, 5)) {
00663         i &= ~0x20;
00664         if (HasBit(i, 4)) {
00665           SlErrorCorrupt("Unsupported gamma");
00666         }
00667         i = (i << 8) | SlReadByte();
00668       }
00669       i = (i << 8) | SlReadByte();
00670     }
00671     i = (i << 8) | SlReadByte();
00672   }
00673   return i;
00674 }
00675 
00688 static void SlWriteSimpleGamma(size_t i)
00689 {
00690   if (i >= (1 << 7)) {
00691     if (i >= (1 << 14)) {
00692       if (i >= (1 << 21)) {
00693         assert(i < (1 << 28));
00694         SlWriteByte((byte)(0xE0 | (i >> 24)));
00695         SlWriteByte((byte)(i >> 16));
00696       } else {
00697         SlWriteByte((byte)(0xC0 | (i >> 16)));
00698       }
00699       SlWriteByte((byte)(i >> 8));
00700     } else {
00701       SlWriteByte((byte)(0x80 | (i >> 8)));
00702     }
00703   }
00704   SlWriteByte((byte)i);
00705 }
00706 
00708 static inline uint SlGetGammaLength(size_t i)
00709 {
00710   return 1 + (i >= (1 << 7)) + (i >= (1 << 14)) + (i >= (1 << 21));
00711 }
00712 
00713 static inline uint SlReadSparseIndex()
00714 {
00715   return SlReadSimpleGamma();
00716 }
00717 
00718 static inline void SlWriteSparseIndex(uint index)
00719 {
00720   SlWriteSimpleGamma(index);
00721 }
00722 
00723 static inline uint SlReadArrayLength()
00724 {
00725   return SlReadSimpleGamma();
00726 }
00727 
00728 static inline void SlWriteArrayLength(size_t length)
00729 {
00730   SlWriteSimpleGamma(length);
00731 }
00732 
00733 static inline uint SlGetArrayLength(size_t length)
00734 {
00735   return SlGetGammaLength(length);
00736 }
00737 
00744 static inline uint SlCalcConvMemLen(VarType conv)
00745 {
00746   static const byte conv_mem_size[] = {1, 1, 1, 2, 2, 4, 4, 8, 8, 0};
00747   byte length = GB(conv, 4, 4);
00748 
00749   switch (length << 4) {
00750     case SLE_VAR_STRB:
00751     case SLE_VAR_STRBQ:
00752     case SLE_VAR_STR:
00753     case SLE_VAR_STRQ:
00754       return SlReadArrayLength();
00755 
00756     default:
00757       assert(length < lengthof(conv_mem_size));
00758       return conv_mem_size[length];
00759   }
00760 }
00761 
00768 static inline byte SlCalcConvFileLen(VarType conv)
00769 {
00770   static const byte conv_file_size[] = {1, 1, 2, 2, 4, 4, 8, 8, 2};
00771   byte length = GB(conv, 0, 4);
00772   assert(length < lengthof(conv_file_size));
00773   return conv_file_size[length];
00774 }
00775 
00777 static inline size_t SlCalcRefLen()
00778 {
00779   return IsSavegameVersionBefore(69) ? 2 : 4;
00780 }
00781 
00782 void SlSetArrayIndex(uint index)
00783 {
00784   _sl.need_length = NL_WANTLENGTH;
00785   _sl.array_index = index;
00786 }
00787 
00788 static size_t _next_offs;
00789 
00794 int SlIterateArray()
00795 {
00796   int index;
00797 
00798   /* After reading in the whole array inside the loop
00799    * we must have read in all the data, so we must be at end of current block. */
00800   if (_next_offs != 0 && _sl.reader->GetSize() != _next_offs) SlErrorCorrupt("Invalid chunk size");
00801 
00802   for (;;) {
00803     uint length = SlReadArrayLength();
00804     if (length == 0) {
00805       _next_offs = 0;
00806       return -1;
00807     }
00808 
00809     _sl.obj_len = --length;
00810     _next_offs = _sl.reader->GetSize() + length;
00811 
00812     switch (_sl.block_mode) {
00813       case CH_SPARSE_ARRAY: index = (int)SlReadSparseIndex(); break;
00814       case CH_ARRAY:        index = _sl.array_index++; break;
00815       default:
00816         DEBUG(sl, 0, "SlIterateArray error");
00817         return -1; // error
00818     }
00819 
00820     if (length != 0) return index;
00821   }
00822 }
00823 
00827 void SlSkipArray()
00828 {
00829   while (SlIterateArray() != -1) {
00830     SlSkipBytes(_next_offs - _sl.reader->GetSize());
00831   }
00832 }
00833 
00839 void SlSetLength(size_t length)
00840 {
00841   assert(_sl.action == SLA_SAVE);
00842 
00843   switch (_sl.need_length) {
00844     case NL_WANTLENGTH:
00845       _sl.need_length = NL_NONE;
00846       switch (_sl.block_mode) {
00847         case CH_RIFF:
00848           /* Ugly encoding of >16M RIFF chunks
00849            * The lower 24 bits are normal
00850            * The uppermost 4 bits are bits 24:27 */
00851           assert(length < (1 << 28));
00852           SlWriteUint32((uint32)((length & 0xFFFFFF) | ((length >> 24) << 28)));
00853           break;
00854         case CH_ARRAY:
00855           assert(_sl.last_array_index <= _sl.array_index);
00856           while (++_sl.last_array_index <= _sl.array_index) {
00857             SlWriteArrayLength(1);
00858           }
00859           SlWriteArrayLength(length + 1);
00860           break;
00861         case CH_SPARSE_ARRAY:
00862           SlWriteArrayLength(length + 1 + SlGetArrayLength(_sl.array_index)); // Also include length of sparse index.
00863           SlWriteSparseIndex(_sl.array_index);
00864           break;
00865         default: NOT_REACHED();
00866       }
00867       break;
00868 
00869     case NL_CALCLENGTH:
00870       _sl.obj_len += (int)length;
00871       break;
00872 
00873     default: NOT_REACHED();
00874   }
00875 }
00876 
00883 static void SlCopyBytes(void *ptr, size_t length)
00884 {
00885   byte *p = (byte *)ptr;
00886 
00887   switch (_sl.action) {
00888     case SLA_LOAD_CHECK:
00889     case SLA_LOAD:
00890       for (; length != 0; length--) *p++ = SlReadByte();
00891       break;
00892     case SLA_SAVE:
00893       for (; length != 0; length--) SlWriteByte(*p++);
00894       break;
00895     default: NOT_REACHED();
00896   }
00897 }
00898 
00900 size_t SlGetFieldLength()
00901 {
00902   return _sl.obj_len;
00903 }
00904 
00912 int64 ReadValue(const void *ptr, VarType conv)
00913 {
00914   switch (GetVarMemType(conv)) {
00915     case SLE_VAR_BL:  return (*(const bool *)ptr != 0);
00916     case SLE_VAR_I8:  return *(const int8  *)ptr;
00917     case SLE_VAR_U8:  return *(const byte  *)ptr;
00918     case SLE_VAR_I16: return *(const int16 *)ptr;
00919     case SLE_VAR_U16: return *(const uint16*)ptr;
00920     case SLE_VAR_I32: return *(const int32 *)ptr;
00921     case SLE_VAR_U32: return *(const uint32*)ptr;
00922     case SLE_VAR_I64: return *(const int64 *)ptr;
00923     case SLE_VAR_U64: return *(const uint64*)ptr;
00924     case SLE_VAR_NULL:return 0;
00925     default: NOT_REACHED();
00926   }
00927 }
00928 
00936 void WriteValue(void *ptr, VarType conv, int64 val)
00937 {
00938   switch (GetVarMemType(conv)) {
00939     case SLE_VAR_BL:  *(bool  *)ptr = (val != 0);  break;
00940     case SLE_VAR_I8:  *(int8  *)ptr = val; break;
00941     case SLE_VAR_U8:  *(byte  *)ptr = val; break;
00942     case SLE_VAR_I16: *(int16 *)ptr = val; break;
00943     case SLE_VAR_U16: *(uint16*)ptr = val; break;
00944     case SLE_VAR_I32: *(int32 *)ptr = val; break;
00945     case SLE_VAR_U32: *(uint32*)ptr = val; break;
00946     case SLE_VAR_I64: *(int64 *)ptr = val; break;
00947     case SLE_VAR_U64: *(uint64*)ptr = val; break;
00948     case SLE_VAR_NAME: *(char**)ptr = CopyFromOldName(val); break;
00949     case SLE_VAR_NULL: break;
00950     default: NOT_REACHED();
00951   }
00952 }
00953 
00962 static void SlSaveLoadConv(void *ptr, VarType conv)
00963 {
00964   switch (_sl.action) {
00965     case SLA_SAVE: {
00966       int64 x = ReadValue(ptr, conv);
00967 
00968       /* Write the value to the file and check if its value is in the desired range */
00969       switch (GetVarFileType(conv)) {
00970         case SLE_FILE_I8: assert(x >= -128 && x <= 127);     SlWriteByte(x);break;
00971         case SLE_FILE_U8: assert(x >= 0 && x <= 255);        SlWriteByte(x);break;
00972         case SLE_FILE_I16:assert(x >= -32768 && x <= 32767); SlWriteUint16(x);break;
00973         case SLE_FILE_STRINGID:
00974         case SLE_FILE_U16:assert(x >= 0 && x <= 65535);      SlWriteUint16(x);break;
00975         case SLE_FILE_I32:
00976         case SLE_FILE_U32:                                   SlWriteUint32((uint32)x);break;
00977         case SLE_FILE_I64:
00978         case SLE_FILE_U64:                                   SlWriteUint64(x);break;
00979         default: NOT_REACHED();
00980       }
00981       break;
00982     }
00983     case SLA_LOAD_CHECK:
00984     case SLA_LOAD: {
00985       int64 x;
00986       /* Read a value from the file */
00987       switch (GetVarFileType(conv)) {
00988         case SLE_FILE_I8:  x = (int8  )SlReadByte();   break;
00989         case SLE_FILE_U8:  x = (byte  )SlReadByte();   break;
00990         case SLE_FILE_I16: x = (int16 )SlReadUint16(); break;
00991         case SLE_FILE_U16: x = (uint16)SlReadUint16(); break;
00992         case SLE_FILE_I32: x = (int32 )SlReadUint32(); break;
00993         case SLE_FILE_U32: x = (uint32)SlReadUint32(); break;
00994         case SLE_FILE_I64: x = (int64 )SlReadUint64(); break;
00995         case SLE_FILE_U64: x = (uint64)SlReadUint64(); break;
00996         case SLE_FILE_STRINGID: x = RemapOldStringID((uint16)SlReadUint16()); break;
00997         default: NOT_REACHED();
00998       }
00999 
01000       /* Write The value to the struct. These ARE endian safe. */
01001       WriteValue(ptr, conv, x);
01002       break;
01003     }
01004     case SLA_PTRS: break;
01005     case SLA_NULL: break;
01006     default: NOT_REACHED();
01007   }
01008 }
01009 
01019 static inline size_t SlCalcNetStringLen(const char *ptr, size_t length)
01020 {
01021   if (ptr == NULL) return 0;
01022   return min(strlen(ptr), length - 1);
01023 }
01024 
01034 static inline size_t SlCalcStringLen(const void *ptr, size_t length, VarType conv)
01035 {
01036   size_t len;
01037   const char *str;
01038 
01039   switch (GetVarMemType(conv)) {
01040     default: NOT_REACHED();
01041     case SLE_VAR_STR:
01042     case SLE_VAR_STRQ:
01043       str = *(const char * const *)ptr;
01044       len = SIZE_MAX;
01045       break;
01046     case SLE_VAR_STRB:
01047     case SLE_VAR_STRBQ:
01048       str = (const char *)ptr;
01049       len = length;
01050       break;
01051   }
01052 
01053   len = SlCalcNetStringLen(str, len);
01054   return len + SlGetArrayLength(len); // also include the length of the index
01055 }
01056 
01063 static void SlString(void *ptr, size_t length, VarType conv)
01064 {
01065   switch (_sl.action) {
01066     case SLA_SAVE: {
01067       size_t len;
01068       switch (GetVarMemType(conv)) {
01069         default: NOT_REACHED();
01070         case SLE_VAR_STRB:
01071         case SLE_VAR_STRBQ:
01072           len = SlCalcNetStringLen((char *)ptr, length);
01073           break;
01074         case SLE_VAR_STR:
01075         case SLE_VAR_STRQ:
01076           ptr = *(char **)ptr;
01077           len = SlCalcNetStringLen((char *)ptr, SIZE_MAX);
01078           break;
01079       }
01080 
01081       SlWriteArrayLength(len);
01082       SlCopyBytes(ptr, len);
01083       break;
01084     }
01085     case SLA_LOAD_CHECK:
01086     case SLA_LOAD: {
01087       size_t len = SlReadArrayLength();
01088 
01089       switch (GetVarMemType(conv)) {
01090         default: NOT_REACHED();
01091         case SLE_VAR_STRB:
01092         case SLE_VAR_STRBQ:
01093           if (len >= length) {
01094             DEBUG(sl, 1, "String length in savegame is bigger than buffer, truncating");
01095             SlCopyBytes(ptr, length);
01096             SlSkipBytes(len - length);
01097             len = length - 1;
01098           } else {
01099             SlCopyBytes(ptr, len);
01100           }
01101           break;
01102         case SLE_VAR_STR:
01103         case SLE_VAR_STRQ: // Malloc'd string, free previous incarnation, and allocate
01104           free(*(char **)ptr);
01105           if (len == 0) {
01106             *(char **)ptr = NULL;
01107             return;
01108           } else {
01109             *(char **)ptr = MallocT<char>(len + 1); // terminating '\0'
01110             ptr = *(char **)ptr;
01111             SlCopyBytes(ptr, len);
01112           }
01113           break;
01114       }
01115 
01116       ((char *)ptr)[len] = '\0'; // properly terminate the string
01117       StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK;
01118       if ((conv & SLF_ALLOW_CONTROL) != 0) {
01119         settings = settings | SVS_ALLOW_CONTROL_CODE;
01120         if (IsSavegameVersionBefore(169)) {
01121           str_fix_scc_encoded((char *)ptr, (char *)ptr + len);
01122         }
01123       }
01124       if ((conv & SLF_ALLOW_NEWLINE) != 0) {
01125         settings = settings | SVS_ALLOW_NEWLINE;
01126       }
01127       str_validate((char *)ptr, (char *)ptr + len, settings);
01128       break;
01129     }
01130     case SLA_PTRS: break;
01131     case SLA_NULL: break;
01132     default: NOT_REACHED();
01133   }
01134 }
01135 
01141 static inline size_t SlCalcArrayLen(size_t length, VarType conv)
01142 {
01143   return SlCalcConvFileLen(conv) * length;
01144 }
01145 
01152 void SlArray(void *array, size_t length, VarType conv)
01153 {
01154   if (_sl.action == SLA_PTRS || _sl.action == SLA_NULL) return;
01155 
01156   /* Automatically calculate the length? */
01157   if (_sl.need_length != NL_NONE) {
01158     SlSetLength(SlCalcArrayLen(length, conv));
01159     /* Determine length only? */
01160     if (_sl.need_length == NL_CALCLENGTH) return;
01161   }
01162 
01163   /* NOTICE - handle some buggy stuff, in really old versions everything was saved
01164    * as a byte-type. So detect this, and adjust array size accordingly */
01165   if (_sl.action != SLA_SAVE && _sl_version == 0) {
01166     /* all arrays except difficulty settings */
01167     if (conv == SLE_INT16 || conv == SLE_UINT16 || conv == SLE_STRINGID ||
01168         conv == SLE_INT32 || conv == SLE_UINT32) {
01169       SlCopyBytes(array, length * SlCalcConvFileLen(conv));
01170       return;
01171     }
01172     /* used for conversion of Money 32bit->64bit */
01173     if (conv == (SLE_FILE_I32 | SLE_VAR_I64)) {
01174       for (uint i = 0; i < length; i++) {
01175         ((int64*)array)[i] = (int32)BSWAP32(SlReadUint32());
01176       }
01177       return;
01178     }
01179   }
01180 
01181   /* If the size of elements is 1 byte both in file and memory, no special
01182    * conversion is needed, use specialized copy-copy function to speed up things */
01183   if (conv == SLE_INT8 || conv == SLE_UINT8) {
01184     SlCopyBytes(array, length);
01185   } else {
01186     byte *a = (byte*)array;
01187     byte mem_size = SlCalcConvMemLen(conv);
01188 
01189     for (; length != 0; length --) {
01190       SlSaveLoadConv(a, conv);
01191       a += mem_size; // get size
01192     }
01193   }
01194 }
01195 
01196 
01207 static size_t ReferenceToInt(const void *obj, SLRefType rt)
01208 {
01209   assert(_sl.action == SLA_SAVE);
01210 
01211   if (obj == NULL) return 0;
01212 
01213   switch (rt) {
01214     case REF_VEHICLE_OLD: // Old vehicles we save as new ones
01215     case REF_VEHICLE:   return ((const  Vehicle*)obj)->index + 1;
01216     case REF_STATION:   return ((const  Station*)obj)->index + 1;
01217     case REF_TOWN:      return ((const     Town*)obj)->index + 1;
01218     case REF_ORDER:     return ((const    Order*)obj)->index + 1;
01219     case REF_ROADSTOPS: return ((const RoadStop*)obj)->index + 1;
01220     case REF_ENGINE_RENEWS:  return ((const       EngineRenew*)obj)->index + 1;
01221     case REF_CARGO_PACKET:   return ((const       CargoPacket*)obj)->index + 1;
01222     case REF_ORDERLIST:      return ((const         OrderList*)obj)->index + 1;
01223     case REF_STORAGE:        return ((const PersistentStorage*)obj)->index + 1;
01224     case REF_LINK_GRAPH:     return ((const         LinkGraph*)obj)->index + 1;
01225     case REF_LINK_GRAPH_JOB: return ((const      LinkGraphJob*)obj)->index + 1;
01226     default: NOT_REACHED();
01227   }
01228 }
01229 
01240 static void *IntToReference(size_t index, SLRefType rt)
01241 {
01242   assert_compile(sizeof(size_t) <= sizeof(void *));
01243 
01244   assert(_sl.action == SLA_PTRS);
01245 
01246   /* After version 4.3 REF_VEHICLE_OLD is saved as REF_VEHICLE,
01247    * and should be loaded like that */
01248   if (rt == REF_VEHICLE_OLD && !IsSavegameVersionBefore(4, 4)) {
01249     rt = REF_VEHICLE;
01250   }
01251 
01252   /* No need to look up NULL pointers, just return immediately */
01253   if (index == (rt == REF_VEHICLE_OLD ? 0xFFFF : 0)) return NULL;
01254 
01255   /* Correct index. Old vehicles were saved differently:
01256    * invalid vehicle was 0xFFFF, now we use 0x0000 for everything invalid. */
01257   if (rt != REF_VEHICLE_OLD) index--;
01258 
01259   switch (rt) {
01260     case REF_ORDERLIST:
01261       if (OrderList::IsValidID(index)) return OrderList::Get(index);
01262       SlErrorCorrupt("Referencing invalid OrderList");
01263 
01264     case REF_ORDER:
01265       if (Order::IsValidID(index)) return Order::Get(index);
01266       /* in old versions, invalid order was used to mark end of order list */
01267       if (IsSavegameVersionBefore(5, 2)) return NULL;
01268       SlErrorCorrupt("Referencing invalid Order");
01269 
01270     case REF_VEHICLE_OLD:
01271     case REF_VEHICLE:
01272       if (Vehicle::IsValidID(index)) return Vehicle::Get(index);
01273       SlErrorCorrupt("Referencing invalid Vehicle");
01274 
01275     case REF_STATION:
01276       if (Station::IsValidID(index)) return Station::Get(index);
01277       SlErrorCorrupt("Referencing invalid Station");
01278 
01279     case REF_TOWN:
01280       if (Town::IsValidID(index)) return Town::Get(index);
01281       SlErrorCorrupt("Referencing invalid Town");
01282 
01283     case REF_ROADSTOPS:
01284       if (RoadStop::IsValidID(index)) return RoadStop::Get(index);
01285       SlErrorCorrupt("Referencing invalid RoadStop");
01286 
01287     case REF_ENGINE_RENEWS:
01288       if (EngineRenew::IsValidID(index)) return EngineRenew::Get(index);
01289       SlErrorCorrupt("Referencing invalid EngineRenew");
01290 
01291     case REF_CARGO_PACKET:
01292       if (CargoPacket::IsValidID(index)) return CargoPacket::Get(index);
01293       SlErrorCorrupt("Referencing invalid CargoPacket");
01294 
01295     case REF_STORAGE:
01296       if (PersistentStorage::IsValidID(index)) return PersistentStorage::Get(index);
01297       SlErrorCorrupt("Referencing invalid PersistentStorage");
01298 
01299     case REF_LINK_GRAPH:
01300       if (LinkGraph::IsValidID(index)) return LinkGraph::Get(index);
01301       SlErrorCorrupt("Referencing invalid LinkGraph");
01302 
01303     case REF_LINK_GRAPH_JOB:
01304       if (LinkGraphJob::IsValidID(index)) return LinkGraphJob::Get(index);
01305       SlErrorCorrupt("Referencing invalid LinkGraphJob");
01306 
01307     default: NOT_REACHED();
01308   }
01309 }
01310 
01315 static inline size_t SlCalcListLen(const void *list)
01316 {
01317   const std::list<void *> *l = (const std::list<void *> *) list;
01318 
01319   int type_size = IsSavegameVersionBefore(69) ? 2 : 4;
01320   /* Each entry is saved as type_size bytes, plus type_size bytes are used for the length
01321    * of the list */
01322   return l->size() * type_size + type_size;
01323 }
01324 
01325 
01331 static void SlList(void *list, SLRefType conv)
01332 {
01333   /* Automatically calculate the length? */
01334   if (_sl.need_length != NL_NONE) {
01335     SlSetLength(SlCalcListLen(list));
01336     /* Determine length only? */
01337     if (_sl.need_length == NL_CALCLENGTH) return;
01338   }
01339 
01340   typedef std::list<void *> PtrList;
01341   PtrList *l = (PtrList *)list;
01342 
01343   switch (_sl.action) {
01344     case SLA_SAVE: {
01345       SlWriteUint32((uint32)l->size());
01346 
01347       PtrList::iterator iter;
01348       for (iter = l->begin(); iter != l->end(); ++iter) {
01349         void *ptr = *iter;
01350         SlWriteUint32((uint32)ReferenceToInt(ptr, conv));
01351       }
01352       break;
01353     }
01354     case SLA_LOAD_CHECK:
01355     case SLA_LOAD: {
01356       size_t length = IsSavegameVersionBefore(69) ? SlReadUint16() : SlReadUint32();
01357 
01358       /* Load each reference and push to the end of the list */
01359       for (size_t i = 0; i < length; i++) {
01360         size_t data = IsSavegameVersionBefore(69) ? SlReadUint16() : SlReadUint32();
01361         l->push_back((void *)data);
01362       }
01363       break;
01364     }
01365     case SLA_PTRS: {
01366       PtrList temp = *l;
01367 
01368       l->clear();
01369       PtrList::iterator iter;
01370       for (iter = temp.begin(); iter != temp.end(); ++iter) {
01371         void *ptr = IntToReference((size_t)*iter, conv);
01372         l->push_back(ptr);
01373       }
01374       break;
01375     }
01376     case SLA_NULL:
01377       l->clear();
01378       break;
01379     default: NOT_REACHED();
01380   }
01381 }
01382 
01383 
01385 static inline bool SlIsObjectValidInSavegame(const SaveLoad *sld)
01386 {
01387   if (_sl_version < sld->version_from || _sl_version > sld->version_to) return false;
01388   if (sld->conv & SLF_NOT_IN_SAVE) return false;
01389 
01390   return true;
01391 }
01392 
01398 static inline bool SlSkipVariableOnLoad(const SaveLoad *sld)
01399 {
01400   if ((sld->conv & SLF_NO_NETWORK_SYNC) && _sl.action != SLA_SAVE && _networking && !_network_server) {
01401     SlSkipBytes(SlCalcConvMemLen(sld->conv) * sld->length);
01402     return true;
01403   }
01404 
01405   return false;
01406 }
01407 
01414 size_t SlCalcObjLength(const void *object, const SaveLoad *sld)
01415 {
01416   size_t length = 0;
01417 
01418   /* Need to determine the length and write a length tag. */
01419   for (; sld->cmd != SL_END; sld++) {
01420     length += SlCalcObjMemberLength(object, sld);
01421   }
01422   return length;
01423 }
01424 
01425 size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld)
01426 {
01427   assert(_sl.action == SLA_SAVE);
01428 
01429   switch (sld->cmd) {
01430     case SL_VAR:
01431     case SL_REF:
01432     case SL_ARR:
01433     case SL_STR:
01434     case SL_LST:
01435       /* CONDITIONAL saveload types depend on the savegame version */
01436       if (!SlIsObjectValidInSavegame(sld)) break;
01437 
01438       switch (sld->cmd) {
01439         case SL_VAR: return SlCalcConvFileLen(sld->conv);
01440         case SL_REF: return SlCalcRefLen();
01441         case SL_ARR: return SlCalcArrayLen(sld->length, sld->conv);
01442         case SL_STR: return SlCalcStringLen(GetVariableAddress(object, sld), sld->length, sld->conv);
01443         case SL_LST: return SlCalcListLen(GetVariableAddress(object, sld));
01444         default: NOT_REACHED();
01445       }
01446       break;
01447     case SL_WRITEBYTE: return 1; // a byte is logically of size 1
01448     case SL_VEH_INCLUDE: return SlCalcObjLength(object, GetVehicleDescription(VEH_END));
01449     case SL_ST_INCLUDE: return SlCalcObjLength(object, GetBaseStationDescription());
01450     default: NOT_REACHED();
01451   }
01452   return 0;
01453 }
01454 
01455 
01456 bool SlObjectMember(void *ptr, const SaveLoad *sld)
01457 {
01458   VarType conv = GB(sld->conv, 0, 8);
01459   switch (sld->cmd) {
01460     case SL_VAR:
01461     case SL_REF:
01462     case SL_ARR:
01463     case SL_STR:
01464     case SL_LST:
01465       /* CONDITIONAL saveload types depend on the savegame version */
01466       if (!SlIsObjectValidInSavegame(sld)) return false;
01467       if (SlSkipVariableOnLoad(sld)) return false;
01468 
01469       switch (sld->cmd) {
01470         case SL_VAR: SlSaveLoadConv(ptr, conv); break;
01471         case SL_REF: // Reference variable, translate
01472           switch (_sl.action) {
01473             case SLA_SAVE:
01474               SlWriteUint32((uint32)ReferenceToInt(*(void **)ptr, (SLRefType)conv));
01475               break;
01476             case SLA_LOAD_CHECK:
01477             case SLA_LOAD:
01478               *(size_t *)ptr = IsSavegameVersionBefore(69) ? SlReadUint16() : SlReadUint32();
01479               break;
01480             case SLA_PTRS:
01481               *(void **)ptr = IntToReference(*(size_t *)ptr, (SLRefType)conv);
01482               break;
01483             case SLA_NULL:
01484               *(void **)ptr = NULL;
01485               break;
01486             default: NOT_REACHED();
01487           }
01488           break;
01489         case SL_ARR: SlArray(ptr, sld->length, conv); break;
01490         case SL_STR: SlString(ptr, sld->length, sld->conv); break;
01491         case SL_LST: SlList(ptr, (SLRefType)conv); break;
01492         default: NOT_REACHED();
01493       }
01494       break;
01495 
01496     /* SL_WRITEBYTE translates a value of a variable to another one upon
01497      * saving or loading.
01498      * XXX - variable renaming abuse
01499      * game_value: the value of the variable ingame is abused by sld->version_from
01500      * file_value: the value of the variable in the savegame is abused by sld->version_to */
01501     case SL_WRITEBYTE:
01502       switch (_sl.action) {
01503         case SLA_SAVE: SlWriteByte(sld->version_to); break;
01504         case SLA_LOAD_CHECK:
01505         case SLA_LOAD: *(byte *)ptr = sld->version_from; break;
01506         case SLA_PTRS: break;
01507         case SLA_NULL: break;
01508         default: NOT_REACHED();
01509       }
01510       break;
01511 
01512     /* SL_VEH_INCLUDE loads common code for vehicles */
01513     case SL_VEH_INCLUDE:
01514       SlObject(ptr, GetVehicleDescription(VEH_END));
01515       break;
01516 
01517     case SL_ST_INCLUDE:
01518       SlObject(ptr, GetBaseStationDescription());
01519       break;
01520 
01521     default: NOT_REACHED();
01522   }
01523   return true;
01524 }
01525 
01531 void SlObject(void *object, const SaveLoad *sld)
01532 {
01533   /* Automatically calculate the length? */
01534   if (_sl.need_length != NL_NONE) {
01535     SlSetLength(SlCalcObjLength(object, sld));
01536     if (_sl.need_length == NL_CALCLENGTH) return;
01537   }
01538 
01539   for (; sld->cmd != SL_END; sld++) {
01540     void *ptr = sld->global ? sld->address : GetVariableAddress(object, sld);
01541     SlObjectMember(ptr, sld);
01542   }
01543 }
01544 
01549 void SlGlobList(const SaveLoadGlobVarList *sldg)
01550 {
01551   SlObject(NULL, (const SaveLoad*)sldg);
01552 }
01553 
01559 void SlAutolength(AutolengthProc *proc, void *arg)
01560 {
01561   size_t offs;
01562 
01563   assert(_sl.action == SLA_SAVE);
01564 
01565   /* Tell it to calculate the length */
01566   _sl.need_length = NL_CALCLENGTH;
01567   _sl.obj_len = 0;
01568   proc(arg);
01569 
01570   /* Setup length */
01571   _sl.need_length = NL_WANTLENGTH;
01572   SlSetLength(_sl.obj_len);
01573 
01574   offs = _sl.dumper->GetSize() + _sl.obj_len;
01575 
01576   /* And write the stuff */
01577   proc(arg);
01578 
01579   if (offs != _sl.dumper->GetSize()) SlErrorCorrupt("Invalid chunk size");
01580 }
01581 
01586 static void SlLoadChunk(const ChunkHandler *ch)
01587 {
01588   byte m = SlReadByte();
01589   size_t len;
01590   size_t endoffs;
01591 
01592   _sl.block_mode = m;
01593   _sl.obj_len = 0;
01594 
01595   switch (m) {
01596     case CH_ARRAY:
01597       _sl.array_index = 0;
01598       ch->load_proc();
01599       break;
01600     case CH_SPARSE_ARRAY:
01601       ch->load_proc();
01602       break;
01603     default:
01604       if ((m & 0xF) == CH_RIFF) {
01605         /* Read length */
01606         len = (SlReadByte() << 16) | ((m >> 4) << 24);
01607         len += SlReadUint16();
01608         _sl.obj_len = len;
01609         endoffs = _sl.reader->GetSize() + len;
01610         ch->load_proc();
01611         if (_sl.reader->GetSize() != endoffs) SlErrorCorrupt("Invalid chunk size");
01612       } else {
01613         SlErrorCorrupt("Invalid chunk type");
01614       }
01615       break;
01616   }
01617 }
01618 
01624 static void SlLoadCheckChunk(const ChunkHandler *ch)
01625 {
01626   byte m = SlReadByte();
01627   size_t len;
01628   size_t endoffs;
01629 
01630   _sl.block_mode = m;
01631   _sl.obj_len = 0;
01632 
01633   switch (m) {
01634     case CH_ARRAY:
01635       _sl.array_index = 0;
01636       if (ch->load_check_proc) {
01637         ch->load_check_proc();
01638       } else {
01639         SlSkipArray();
01640       }
01641       break;
01642     case CH_SPARSE_ARRAY:
01643       if (ch->load_check_proc) {
01644         ch->load_check_proc();
01645       } else {
01646         SlSkipArray();
01647       }
01648       break;
01649     default:
01650       if ((m & 0xF) == CH_RIFF) {
01651         /* Read length */
01652         len = (SlReadByte() << 16) | ((m >> 4) << 24);
01653         len += SlReadUint16();
01654         _sl.obj_len = len;
01655         endoffs = _sl.reader->GetSize() + len;
01656         if (ch->load_check_proc) {
01657           ch->load_check_proc();
01658         } else {
01659           SlSkipBytes(len);
01660         }
01661         if (_sl.reader->GetSize() != endoffs) SlErrorCorrupt("Invalid chunk size");
01662       } else {
01663         SlErrorCorrupt("Invalid chunk type");
01664       }
01665       break;
01666   }
01667 }
01668 
01673 static ChunkSaveLoadProc *_stub_save_proc;
01674 
01680 static inline void SlStubSaveProc2(void *arg)
01681 {
01682   _stub_save_proc();
01683 }
01684 
01690 static void SlStubSaveProc()
01691 {
01692   SlAutolength(SlStubSaveProc2, NULL);
01693 }
01694 
01700 static void SlSaveChunk(const ChunkHandler *ch)
01701 {
01702   ChunkSaveLoadProc *proc = ch->save_proc;
01703 
01704   /* Don't save any chunk information if there is no save handler. */
01705   if (proc == NULL) return;
01706 
01707   SlWriteUint32(ch->id);
01708   DEBUG(sl, 2, "Saving chunk %c%c%c%c", ch->id >> 24, ch->id >> 16, ch->id >> 8, ch->id);
01709 
01710   if (ch->flags & CH_AUTO_LENGTH) {
01711     /* Need to calculate the length. Solve that by calling SlAutoLength in the save_proc. */
01712     _stub_save_proc = proc;
01713     proc = SlStubSaveProc;
01714   }
01715 
01716   _sl.block_mode = ch->flags & CH_TYPE_MASK;
01717   switch (ch->flags & CH_TYPE_MASK) {
01718     case CH_RIFF:
01719       _sl.need_length = NL_WANTLENGTH;
01720       proc();
01721       break;
01722     case CH_ARRAY:
01723       _sl.last_array_index = 0;
01724       SlWriteByte(CH_ARRAY);
01725       proc();
01726       SlWriteArrayLength(0); // Terminate arrays
01727       break;
01728     case CH_SPARSE_ARRAY:
01729       SlWriteByte(CH_SPARSE_ARRAY);
01730       proc();
01731       SlWriteArrayLength(0); // Terminate arrays
01732       break;
01733     default: NOT_REACHED();
01734   }
01735 }
01736 
01738 static void SlSaveChunks()
01739 {
01740   FOR_ALL_CHUNK_HANDLERS(ch) {
01741     SlSaveChunk(ch);
01742   }
01743 
01744   /* Terminator */
01745   SlWriteUint32(0);
01746 }
01747 
01754 static const ChunkHandler *SlFindChunkHandler(uint32 id)
01755 {
01756   FOR_ALL_CHUNK_HANDLERS(ch) if (ch->id == id) return ch;
01757   return NULL;
01758 }
01759 
01761 static void SlLoadChunks()
01762 {
01763   uint32 id;
01764   const ChunkHandler *ch;
01765 
01766   for (id = SlReadUint32(); id != 0; id = SlReadUint32()) {
01767     DEBUG(sl, 2, "Loading chunk %c%c%c%c", id >> 24, id >> 16, id >> 8, id);
01768 
01769     ch = SlFindChunkHandler(id);
01770     if (ch == NULL) SlErrorCorrupt("Unknown chunk type");
01771     SlLoadChunk(ch);
01772   }
01773 }
01774 
01776 static void SlLoadCheckChunks()
01777 {
01778   uint32 id;
01779   const ChunkHandler *ch;
01780 
01781   for (id = SlReadUint32(); id != 0; id = SlReadUint32()) {
01782     DEBUG(sl, 2, "Loading chunk %c%c%c%c", id >> 24, id >> 16, id >> 8, id);
01783 
01784     ch = SlFindChunkHandler(id);
01785     if (ch == NULL) SlErrorCorrupt("Unknown chunk type");
01786     SlLoadCheckChunk(ch);
01787   }
01788 }
01789 
01791 static void SlFixPointers()
01792 {
01793   _sl.action = SLA_PTRS;
01794 
01795   DEBUG(sl, 1, "Fixing pointers");
01796 
01797   FOR_ALL_CHUNK_HANDLERS(ch) {
01798     if (ch->ptrs_proc != NULL) {
01799       DEBUG(sl, 2, "Fixing pointers for %c%c%c%c", ch->id >> 24, ch->id >> 16, ch->id >> 8, ch->id);
01800       ch->ptrs_proc();
01801     }
01802   }
01803 
01804   DEBUG(sl, 1, "All pointers fixed");
01805 
01806   assert(_sl.action == SLA_PTRS);
01807 }
01808 
01809 
01811 struct FileReader : LoadFilter {
01812   FILE *file; 
01813   long begin; 
01814 
01819   FileReader(FILE *file) : LoadFilter(NULL), file(file), begin(ftell(file))
01820   {
01821   }
01822 
01824   ~FileReader()
01825   {
01826     if (this->file != NULL) fclose(this->file);
01827     this->file = NULL;
01828 
01829     /* Make sure we don't double free. */
01830     _sl.sf = NULL;
01831   }
01832 
01833   /* virtual */ size_t Read(byte *buf, size_t size)
01834   {
01835     /* We're in the process of shutting down, i.e. in "failure" mode. */
01836     if (this->file == NULL) return 0;
01837 
01838     return fread(buf, 1, size, this->file);
01839   }
01840 
01841   /* virtual */ void Reset()
01842   {
01843     clearerr(this->file);
01844     fseek(this->file, this->begin, SEEK_SET);
01845   }
01846 };
01847 
01849 struct FileWriter : SaveFilter {
01850   FILE *file; 
01851 
01856   FileWriter(FILE *file) : SaveFilter(NULL), file(file)
01857   {
01858   }
01859 
01861   ~FileWriter()
01862   {
01863     this->Finish();
01864 
01865     /* Make sure we don't double free. */
01866     _sl.sf = NULL;
01867   }
01868 
01869   /* virtual */ void Write(byte *buf, size_t size)
01870   {
01871     /* We're in the process of shutting down, i.e. in "failure" mode. */
01872     if (this->file == NULL) return;
01873 
01874     if (fwrite(buf, 1, size, this->file) != size) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE);
01875   }
01876 
01877   /* virtual */ void Finish()
01878   {
01879     if (this->file != NULL) fclose(this->file);
01880     this->file = NULL;
01881   }
01882 };
01883 
01884 /*******************************************
01885  ********** START OF LZO CODE **************
01886  *******************************************/
01887 
01888 #ifdef WITH_LZO
01889 #include <lzo/lzo1x.h>
01890 
01892 static const uint LZO_BUFFER_SIZE = 8192;
01893 
01895 struct LZOLoadFilter : LoadFilter {
01900   LZOLoadFilter(LoadFilter *chain) : LoadFilter(chain)
01901   {
01902     if (lzo_init() != LZO_E_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize decompressor");
01903   }
01904 
01905   /* virtual */ size_t Read(byte *buf, size_t ssize)
01906   {
01907     assert(ssize >= LZO_BUFFER_SIZE);
01908 
01909     /* Buffer size is from the LZO docs plus the chunk header size. */
01910     byte out[LZO_BUFFER_SIZE + LZO_BUFFER_SIZE / 16 + 64 + 3 + sizeof(uint32) * 2];
01911     uint32 tmp[2];
01912     uint32 size;
01913     lzo_uint len;
01914 
01915     /* Read header*/
01916     if (this->chain->Read((byte*)tmp, sizeof(tmp)) != sizeof(tmp)) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE, "File read failed");
01917 
01918     /* Check if size is bad */
01919     ((uint32*)out)[0] = size = tmp[1];
01920 
01921     if (_sl_version != 0) {
01922       tmp[0] = TO_BE32(tmp[0]);
01923       size = TO_BE32(size);
01924     }
01925 
01926     if (size >= sizeof(out)) SlErrorCorrupt("Inconsistent size");
01927 
01928     /* Read block */
01929     if (this->chain->Read(out + sizeof(uint32), size) != size) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
01930 
01931     /* Verify checksum */
01932     if (tmp[0] != lzo_adler32(0, out, size + sizeof(uint32))) SlErrorCorrupt("Bad checksum");
01933 
01934     /* Decompress */
01935     lzo1x_decompress_safe(out + sizeof(uint32) * 1, size, buf, &len, NULL);
01936     return len;
01937   }
01938 };
01939 
01941 struct LZOSaveFilter : SaveFilter {
01947   LZOSaveFilter(SaveFilter *chain, byte compression_level) : SaveFilter(chain)
01948   {
01949     if (lzo_init() != LZO_E_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize compressor");
01950   }
01951 
01952   /* virtual */ void Write(byte *buf, size_t size)
01953   {
01954     const lzo_bytep in = buf;
01955     /* Buffer size is from the LZO docs plus the chunk header size. */
01956     byte out[LZO_BUFFER_SIZE + LZO_BUFFER_SIZE / 16 + 64 + 3 + sizeof(uint32) * 2];
01957     byte wrkmem[LZO1X_1_MEM_COMPRESS];
01958     lzo_uint outlen;
01959 
01960     do {
01961       /* Compress up to LZO_BUFFER_SIZE bytes at once. */
01962       lzo_uint len = size > LZO_BUFFER_SIZE ? LZO_BUFFER_SIZE : (lzo_uint)size;
01963       lzo1x_1_compress(in, len, out + sizeof(uint32) * 2, &outlen, wrkmem);
01964       ((uint32*)out)[1] = TO_BE32((uint32)outlen);
01965       ((uint32*)out)[0] = TO_BE32(lzo_adler32(0, out + sizeof(uint32), outlen + sizeof(uint32)));
01966       this->chain->Write(out, outlen + sizeof(uint32) * 2);
01967 
01968       /* Move to next data chunk. */
01969       size -= len;
01970       in += len;
01971     } while (size > 0);
01972   }
01973 };
01974 
01975 #endif /* WITH_LZO */
01976 
01977 /*********************************************
01978  ******** START OF NOCOMP CODE (uncompressed)*
01979  *********************************************/
01980 
01982 struct NoCompLoadFilter : LoadFilter {
01987   NoCompLoadFilter(LoadFilter *chain) : LoadFilter(chain)
01988   {
01989   }
01990 
01991   /* virtual */ size_t Read(byte *buf, size_t size)
01992   {
01993     return this->chain->Read(buf, size);
01994   }
01995 };
01996 
01998 struct NoCompSaveFilter : SaveFilter {
02004   NoCompSaveFilter(SaveFilter *chain, byte compression_level) : SaveFilter(chain)
02005   {
02006   }
02007 
02008   /* virtual */ void Write(byte *buf, size_t size)
02009   {
02010     this->chain->Write(buf, size);
02011   }
02012 };
02013 
02014 /********************************************
02015  ********** START OF ZLIB CODE **************
02016  ********************************************/
02017 
02018 #if defined(WITH_ZLIB)
02019 #include <zlib.h>
02020 
02022 struct ZlibLoadFilter : LoadFilter {
02023   z_stream z;                        
02024   byte fread_buf[MEMORY_CHUNK_SIZE]; 
02025 
02030   ZlibLoadFilter(LoadFilter *chain) : LoadFilter(chain)
02031   {
02032     memset(&this->z, 0, sizeof(this->z));
02033     if (inflateInit(&this->z) != Z_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize decompressor");
02034   }
02035 
02037   ~ZlibLoadFilter()
02038   {
02039     inflateEnd(&this->z);
02040   }
02041 
02042   /* virtual */ size_t Read(byte *buf, size_t size)
02043   {
02044     this->z.next_out  = buf;
02045     this->z.avail_out = (uint)size;
02046 
02047     do {
02048       /* read more bytes from the file? */
02049       if (this->z.avail_in == 0) {
02050         this->z.next_in = this->fread_buf;
02051         this->z.avail_in = (uint)this->chain->Read(this->fread_buf, sizeof(this->fread_buf));
02052       }
02053 
02054       /* inflate the data */
02055       int r = inflate(&this->z, 0);
02056       if (r == Z_STREAM_END) break;
02057 
02058       if (r != Z_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "inflate() failed");
02059     } while (this->z.avail_out != 0);
02060 
02061     return size - this->z.avail_out;
02062   }
02063 };
02064 
02066 struct ZlibSaveFilter : SaveFilter {
02067   z_stream z; 
02068 
02074   ZlibSaveFilter(SaveFilter *chain, byte compression_level) : SaveFilter(chain)
02075   {
02076     memset(&this->z, 0, sizeof(this->z));
02077     if (deflateInit(&this->z, compression_level) != Z_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize compressor");
02078   }
02079 
02081   ~ZlibSaveFilter()
02082   {
02083     deflateEnd(&this->z);
02084   }
02085 
02092   void WriteLoop(byte *p, size_t len, int mode)
02093   {
02094     byte buf[MEMORY_CHUNK_SIZE]; // output buffer
02095     uint n;
02096     this->z.next_in = p;
02097     this->z.avail_in = (uInt)len;
02098     do {
02099       this->z.next_out = buf;
02100       this->z.avail_out = sizeof(buf);
02101 
02109       int r = deflate(&this->z, mode);
02110 
02111       /* bytes were emitted? */
02112       if ((n = sizeof(buf) - this->z.avail_out) != 0) {
02113         this->chain->Write(buf, n);
02114       }
02115       if (r == Z_STREAM_END) break;
02116 
02117       if (r != Z_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "zlib returned error code");
02118     } while (this->z.avail_in || !this->z.avail_out);
02119   }
02120 
02121   /* virtual */ void Write(byte *buf, size_t size)
02122   {
02123     this->WriteLoop(buf, size, 0);
02124   }
02125 
02126   /* virtual */ void Finish()
02127   {
02128     this->WriteLoop(NULL, 0, Z_FINISH);
02129     this->chain->Finish();
02130   }
02131 };
02132 
02133 #endif /* WITH_ZLIB */
02134 
02135 /********************************************
02136  ********** START OF LZMA CODE **************
02137  ********************************************/
02138 
02139 #if defined(WITH_LZMA)
02140 #include <lzma.h>
02141 
02148 static const lzma_stream _lzma_init = LZMA_STREAM_INIT;
02149 
02151 struct LZMALoadFilter : LoadFilter {
02152   lzma_stream lzma;                  
02153   byte fread_buf[MEMORY_CHUNK_SIZE]; 
02154 
02159   LZMALoadFilter(LoadFilter *chain) : LoadFilter(chain), lzma(_lzma_init)
02160   {
02161     /* Allow saves up to 256 MB uncompressed */
02162     if (lzma_auto_decoder(&this->lzma, 1 << 28, 0) != LZMA_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize decompressor");
02163   }
02164 
02166   ~LZMALoadFilter()
02167   {
02168     lzma_end(&this->lzma);
02169   }
02170 
02171   /* virtual */ size_t Read(byte *buf, size_t size)
02172   {
02173     this->lzma.next_out  = buf;
02174     this->lzma.avail_out = size;
02175 
02176     do {
02177       /* read more bytes from the file? */
02178       if (this->lzma.avail_in == 0) {
02179         this->lzma.next_in  = this->fread_buf;
02180         this->lzma.avail_in = this->chain->Read(this->fread_buf, sizeof(this->fread_buf));
02181       }
02182 
02183       /* inflate the data */
02184       lzma_ret r = lzma_code(&this->lzma, LZMA_RUN);
02185       if (r == LZMA_STREAM_END) break;
02186       if (r != LZMA_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "liblzma returned error code");
02187     } while (this->lzma.avail_out != 0);
02188 
02189     return size - this->lzma.avail_out;
02190   }
02191 };
02192 
02194 struct LZMASaveFilter : SaveFilter {
02195   lzma_stream lzma; 
02196 
02202   LZMASaveFilter(SaveFilter *chain, byte compression_level) : SaveFilter(chain), lzma(_lzma_init)
02203   {
02204     if (lzma_easy_encoder(&this->lzma, compression_level, LZMA_CHECK_CRC32) != LZMA_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize compressor");
02205   }
02206 
02208   ~LZMASaveFilter()
02209   {
02210     lzma_end(&this->lzma);
02211   }
02212 
02219   void WriteLoop(byte *p, size_t len, lzma_action action)
02220   {
02221     byte buf[MEMORY_CHUNK_SIZE]; // output buffer
02222     size_t n;
02223     this->lzma.next_in = p;
02224     this->lzma.avail_in = len;
02225     do {
02226       this->lzma.next_out = buf;
02227       this->lzma.avail_out = sizeof(buf);
02228 
02229       lzma_ret r = lzma_code(&this->lzma, action);
02230 
02231       /* bytes were emitted? */
02232       if ((n = sizeof(buf) - this->lzma.avail_out) != 0) {
02233         this->chain->Write(buf, n);
02234       }
02235       if (r == LZMA_STREAM_END) break;
02236       if (r != LZMA_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "liblzma returned error code");
02237     } while (this->lzma.avail_in || !this->lzma.avail_out);
02238   }
02239 
02240   /* virtual */ void Write(byte *buf, size_t size)
02241   {
02242     this->WriteLoop(buf, size, LZMA_RUN);
02243   }
02244 
02245   /* virtual */ void Finish()
02246   {
02247     this->WriteLoop(NULL, 0, LZMA_FINISH);
02248     this->chain->Finish();
02249   }
02250 };
02251 
02252 #endif /* WITH_LZMA */
02253 
02254 /*******************************************
02255  ************* END OF CODE *****************
02256  *******************************************/
02257 
02259 struct SaveLoadFormat {
02260   const char *name;                     
02261   uint32 tag;                           
02262 
02263   LoadFilter *(*init_load)(LoadFilter *chain);                    
02264   SaveFilter *(*init_write)(SaveFilter *chain, byte compression); 
02265 
02266   byte min_compression;                 
02267   byte default_compression;             
02268   byte max_compression;                 
02269 };
02270 
02272 static const SaveLoadFormat _saveload_formats[] = {
02273 #if defined(WITH_LZO)
02274   /* Roughly 75% larger than zlib level 6 at only ~7% of the CPU usage. */
02275   {"lzo",    TO_BE32X('OTTD'), CreateLoadFilter<LZOLoadFilter>,    CreateSaveFilter<LZOSaveFilter>,    0, 0, 0},
02276 #else
02277   {"lzo",    TO_BE32X('OTTD'), NULL,                               NULL,                               0, 0, 0},
02278 #endif
02279   /* Roughly 5 times larger at only 1% of the CPU usage over zlib level 6. */
02280   {"none",   TO_BE32X('OTTN'), CreateLoadFilter<NoCompLoadFilter>, CreateSaveFilter<NoCompSaveFilter>, 0, 0, 0},
02281 #if defined(WITH_ZLIB)
02282   /* After level 6 the speed reduction is significant (1.5x to 2.5x slower per level), but the reduction in filesize is
02283    * fairly insignificant (~1% for each step). Lower levels become ~5-10% bigger by each level than level 6 while level
02284    * 1 is "only" 3 times as fast. Level 0 results in uncompressed savegames at about 8 times the cost of "none". */
02285   {"zlib",   TO_BE32X('OTTZ'), CreateLoadFilter<ZlibLoadFilter>,   CreateSaveFilter<ZlibSaveFilter>,   0, 6, 9},
02286 #else
02287   {"zlib",   TO_BE32X('OTTZ'), NULL,                               NULL,                               0, 0, 0},
02288 #endif
02289 #if defined(WITH_LZMA)
02290   /* Level 2 compression is speed wise as fast as zlib level 6 compression (old default), but results in ~10% smaller saves.
02291    * Higher compression levels are possible, and might improve savegame size by up to 25%, but are also up to 10 times slower.
02292    * The next significant reduction in file size is at level 4, but that is already 4 times slower. Level 3 is primarily 50%
02293    * slower while not improving the filesize, while level 0 and 1 are faster, but don't reduce savegame size much.
02294    * It's OTTX and not e.g. OTTL because liblzma is part of xz-utils and .tar.xz is preferred over .tar.lzma. */
02295   {"lzma",   TO_BE32X('OTTX'), CreateLoadFilter<LZMALoadFilter>,   CreateSaveFilter<LZMASaveFilter>,   0, 2, 9},
02296 #else
02297   {"lzma",   TO_BE32X('OTTX'), NULL,                               NULL,                               0, 0, 0},
02298 #endif
02299 };
02300 
02308 static const SaveLoadFormat *GetSavegameFormat(char *s, byte *compression_level)
02309 {
02310   const SaveLoadFormat *def = lastof(_saveload_formats);
02311 
02312   /* find default savegame format, the highest one with which files can be written */
02313   while (!def->init_write) def--;
02314 
02315   if (!StrEmpty(s)) {
02316     /* Get the ":..." of the compression level out of the way */
02317     char *complevel = strrchr(s, ':');
02318     if (complevel != NULL) *complevel = '\0';
02319 
02320     for (const SaveLoadFormat *slf = &_saveload_formats[0]; slf != endof(_saveload_formats); slf++) {
02321       if (slf->init_write != NULL && strcmp(s, slf->name) == 0) {
02322         *compression_level = slf->default_compression;
02323         if (complevel != NULL) {
02324           /* There is a compression level in the string.
02325            * First restore the : we removed to do proper name matching,
02326            * then move the the begin of the actual version. */
02327           *complevel = ':';
02328           complevel++;
02329 
02330           /* Get the version and determine whether all went fine. */
02331           char *end;
02332           long level = strtol(complevel, &end, 10);
02333           if (end == complevel || level != Clamp(level, slf->min_compression, slf->max_compression)) {
02334             SetDParamStr(0, complevel);
02335             ShowErrorMessage(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_SAVEGAME_COMPRESSION_LEVEL, WL_CRITICAL);
02336           } else {
02337             *compression_level = level;
02338           }
02339         }
02340         return slf;
02341       }
02342     }
02343 
02344     SetDParamStr(0, s);
02345     SetDParamStr(1, def->name);
02346     ShowErrorMessage(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_SAVEGAME_COMPRESSION_ALGORITHM, WL_CRITICAL);
02347 
02348     /* Restore the string by adding the : back */
02349     if (complevel != NULL) *complevel = ':';
02350   }
02351   *compression_level = def->default_compression;
02352   return def;
02353 }
02354 
02355 /* actual loader/saver function */
02356 void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settings);
02357 extern bool AfterLoadGame();
02358 extern bool LoadOldSaveGame(const char *file);
02359 
02363 static inline void ClearSaveLoadState()
02364 {
02365   delete _sl.dumper;
02366   _sl.dumper = NULL;
02367 
02368   delete _sl.sf;
02369   _sl.sf = NULL;
02370 
02371   delete _sl.reader;
02372   _sl.reader = NULL;
02373 
02374   delete _sl.lf;
02375   _sl.lf = NULL;
02376 }
02377 
02383 static void SaveFileStart()
02384 {
02385   _sl.ff_state = _fast_forward;
02386   _fast_forward = 0;
02387   if (_cursor.sprite == SPR_CURSOR_MOUSE) SetMouseCursor(SPR_CURSOR_ZZZ, PAL_NONE);
02388 
02389   InvalidateWindowData(WC_STATUS_BAR, 0, SBI_SAVELOAD_START);
02390   _sl.saveinprogress = true;
02391 }
02392 
02394 static void SaveFileDone()
02395 {
02396   if (_game_mode != GM_MENU) _fast_forward = _sl.ff_state;
02397   if (_cursor.sprite == SPR_CURSOR_ZZZ) SetMouseCursor(SPR_CURSOR_MOUSE, PAL_NONE);
02398 
02399   InvalidateWindowData(WC_STATUS_BAR, 0, SBI_SAVELOAD_FINISH);
02400   _sl.saveinprogress = false;
02401 }
02402 
02404 void SetSaveLoadError(StringID str)
02405 {
02406   _sl.error_str = str;
02407 }
02408 
02410 const char *GetSaveLoadErrorString()
02411 {
02412   SetDParam(0, _sl.error_str);
02413   SetDParamStr(1, _sl.extra_msg);
02414 
02415   static char err_str[512];
02416   GetString(err_str, _sl.action == SLA_SAVE ? STR_ERROR_GAME_SAVE_FAILED : STR_ERROR_GAME_LOAD_FAILED, lastof(err_str));
02417   return err_str;
02418 }
02419 
02421 static void SaveFileError()
02422 {
02423   SetDParamStr(0, GetSaveLoadErrorString());
02424   ShowErrorMessage(STR_JUST_RAW_STRING, INVALID_STRING_ID, WL_ERROR);
02425   SaveFileDone();
02426 }
02427 
02432 static SaveOrLoadResult SaveFileToDisk(bool threaded)
02433 {
02434   try {
02435     byte compression;
02436     const SaveLoadFormat *fmt = GetSavegameFormat(_savegame_format, &compression);
02437 
02438     /* We have written our stuff to memory, now write it to file! */
02439     uint32 hdr[2] = { fmt->tag, TO_BE32(SAVEGAME_VERSION << 16) };
02440     _sl.sf->Write((byte*)hdr, sizeof(hdr));
02441 
02442     _sl.sf = fmt->init_write(_sl.sf, compression);
02443     _sl.dumper->Flush(_sl.sf);
02444 
02445     ClearSaveLoadState();
02446 
02447     if (threaded) SetAsyncSaveFinish(SaveFileDone);
02448 
02449     return SL_OK;
02450   } catch (...) {
02451     ClearSaveLoadState();
02452 
02453     AsyncSaveFinishProc asfp = SaveFileDone;
02454 
02455     /* We don't want to shout when saving is just
02456      * cancelled due to a client disconnecting. */
02457     if (_sl.error_str != STR_NETWORK_ERROR_LOSTCONNECTION) {
02458       /* Skip the "colour" character */
02459       DEBUG(sl, 0, "%s", GetSaveLoadErrorString() + 3);
02460       asfp = SaveFileError;
02461     }
02462 
02463     if (threaded) {
02464       SetAsyncSaveFinish(asfp);
02465     } else {
02466       asfp();
02467     }
02468     return SL_ERROR;
02469   }
02470 }
02471 
02473 static void SaveFileToDiskThread(void *arg)
02474 {
02475   SaveFileToDisk(true);
02476 }
02477 
02478 void WaitTillSaved()
02479 {
02480   if (_save_thread == NULL) return;
02481 
02482   _save_thread->Join();
02483   delete _save_thread;
02484   _save_thread = NULL;
02485 
02486   /* Make sure every other state is handled properly as well. */
02487   ProcessAsyncSaveFinish();
02488 }
02489 
02498 static SaveOrLoadResult DoSave(SaveFilter *writer, bool threaded)
02499 {
02500   assert(!_sl.saveinprogress);
02501 
02502   _sl.dumper = new MemoryDumper();
02503   _sl.sf = writer;
02504 
02505   _sl_version = SAVEGAME_VERSION;
02506 
02507   SaveViewportBeforeSaveGame();
02508   SlSaveChunks();
02509 
02510   SaveFileStart();
02511   if (!threaded || !ThreadObject::New(&SaveFileToDiskThread, NULL, &_save_thread)) {
02512     if (threaded) DEBUG(sl, 1, "Cannot create savegame thread, reverting to single-threaded mode...");
02513 
02514     SaveOrLoadResult result = SaveFileToDisk(false);
02515     SaveFileDone();
02516 
02517     return result;
02518   }
02519 
02520   return SL_OK;
02521 }
02522 
02529 SaveOrLoadResult SaveWithFilter(SaveFilter *writer, bool threaded)
02530 {
02531   try {
02532     _sl.action = SLA_SAVE;
02533     return DoSave(writer, threaded);
02534   } catch (...) {
02535     ClearSaveLoadState();
02536     return SL_ERROR;
02537   }
02538 }
02539 
02546 static SaveOrLoadResult DoLoad(LoadFilter *reader, bool load_check)
02547 {
02548   _sl.lf = reader;
02549 
02550   if (load_check) {
02551     /* Clear previous check data */
02552     _load_check_data.Clear();
02553     /* Mark SL_LOAD_CHECK as supported for this savegame. */
02554     _load_check_data.checkable = true;
02555   }
02556 
02557   uint32 hdr[2];
02558   if (_sl.lf->Read((byte*)hdr, sizeof(hdr)) != sizeof(hdr)) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
02559 
02560   /* see if we have any loader for this type. */
02561   const SaveLoadFormat *fmt = _saveload_formats;
02562   for (;;) {
02563     /* No loader found, treat as version 0 and use LZO format */
02564     if (fmt == endof(_saveload_formats)) {
02565       DEBUG(sl, 0, "Unknown savegame type, trying to load it as the buggy format");
02566       _sl.lf->Reset();
02567       _sl_version = 0;
02568       _sl_minor_version = 0;
02569 
02570       /* Try to find the LZO savegame format; it uses 'OTTD' as tag. */
02571       fmt = _saveload_formats;
02572       for (;;) {
02573         if (fmt == endof(_saveload_formats)) {
02574           /* Who removed LZO support? Bad bad boy! */
02575           NOT_REACHED();
02576         }
02577         if (fmt->tag == TO_BE32X('OTTD')) break;
02578         fmt++;
02579       }
02580       break;
02581     }
02582 
02583     if (fmt->tag == hdr[0]) {
02584       /* check version number */
02585       _sl_version = TO_BE32(hdr[1]) >> 16;
02586       /* Minor is not used anymore from version 18.0, but it is still needed
02587        * in versions before that (4 cases) which can't be removed easy.
02588        * Therefore it is loaded, but never saved (or, it saves a 0 in any scenario). */
02589       _sl_minor_version = (TO_BE32(hdr[1]) >> 8) & 0xFF;
02590 
02591       DEBUG(sl, 1, "Loading savegame version %d", _sl_version);
02592 
02593       /* Is the version higher than the current? */
02594       if (_sl_version > SAVEGAME_VERSION) SlError(STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME);
02595       break;
02596     }
02597 
02598     fmt++;
02599   }
02600 
02601   /* loader for this savegame type is not implemented? */
02602   if (fmt->init_load == NULL) {
02603     char err_str[64];
02604     snprintf(err_str, lengthof(err_str), "Loader for '%s' is not available.", fmt->name);
02605     SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, err_str);
02606   }
02607 
02608   _sl.lf = fmt->init_load(_sl.lf);
02609   _sl.reader = new ReadBuffer(_sl.lf);
02610   _next_offs = 0;
02611 
02612   if (!load_check) {
02613     /* Old maps were hardcoded to 256x256 and thus did not contain
02614      * any mapsize information. Pre-initialize to 256x256 to not to
02615      * confuse old games */
02616     InitializeGame(256, 256, true, true);
02617 
02618     GamelogReset();
02619 
02620     if (IsSavegameVersionBefore(4)) {
02621       /*
02622        * NewGRFs were introduced between 0.3,4 and 0.3.5, which both
02623        * shared savegame version 4. Anything before that 'obviously'
02624        * does not have any NewGRFs. Between the introduction and
02625        * savegame version 41 (just before 0.5) the NewGRF settings
02626        * were not stored in the savegame and they were loaded by
02627        * using the settings from the main menu.
02628        * So, to recap:
02629        * - savegame version  <  4:  do not load any NewGRFs.
02630        * - savegame version >= 41:  load NewGRFs from savegame, which is
02631        *                            already done at this stage by
02632        *                            overwriting the main menu settings.
02633        * - other savegame versions: use main menu settings.
02634        *
02635        * This means that users *can* crash savegame version 4..40
02636        * savegames if they set incompatible NewGRFs in the main menu,
02637        * but can't crash anymore for savegame version < 4 savegames.
02638        *
02639        * Note: this is done here because AfterLoadGame is also called
02640        * for TTO/TTD/TTDP savegames which have their own NewGRF logic.
02641        */
02642       ClearGRFConfigList(&_grfconfig);
02643     }
02644   }
02645 
02646   if (load_check) {
02647     /* Load chunks into _load_check_data.
02648      * No pools are loaded. References are not possible, and thus do not need resolving. */
02649     SlLoadCheckChunks();
02650   } else {
02651     /* Load chunks and resolve references */
02652     SlLoadChunks();
02653     SlFixPointers();
02654   }
02655 
02656   ClearSaveLoadState();
02657 
02658   _savegame_type = SGT_OTTD;
02659 
02660   if (load_check) {
02661     /* The only part from AfterLoadGame() we need */
02662     _load_check_data.grf_compatibility = IsGoodGRFConfigList(_load_check_data.grfconfig);
02663   } else {
02664     GamelogStartAction(GLAT_LOAD);
02665 
02666     /* After loading fix up savegame for any internal changes that
02667      * might have occurred since then. If it fails, load back the old game. */
02668     if (!AfterLoadGame()) {
02669       GamelogStopAction();
02670       return SL_REINIT;
02671     }
02672 
02673     GamelogStopAction();
02674   }
02675 
02676   return SL_OK;
02677 }
02678 
02684 SaveOrLoadResult LoadWithFilter(LoadFilter *reader)
02685 {
02686   try {
02687     _sl.action = SLA_LOAD;
02688     return DoLoad(reader, false);
02689   } catch (...) {
02690     ClearSaveLoadState();
02691     return SL_REINIT;
02692   }
02693 }
02694 
02704 SaveOrLoadResult SaveOrLoad(const char *filename, int mode, Subdirectory sb, bool threaded)
02705 {
02706   /* An instance of saving is already active, so don't go saving again */
02707   if (_sl.saveinprogress && mode == SL_SAVE && threaded) {
02708     /* if not an autosave, but a user action, show error message */
02709     if (!_do_autosave) ShowErrorMessage(STR_ERROR_SAVE_STILL_IN_PROGRESS, INVALID_STRING_ID, WL_ERROR);
02710     return SL_OK;
02711   }
02712   WaitTillSaved();
02713 
02714   /* Load a TTDLX or TTDPatch game */
02715   if (mode == SL_OLD_LOAD) {
02716     InitializeGame(256, 256, true, true); // set a mapsize of 256x256 for TTDPatch games or it might get confused
02717 
02718     /* TTD/TTO savegames have no NewGRFs, TTDP savegame have them
02719      * and if so a new NewGRF list will be made in LoadOldSaveGame.
02720      * Note: this is done here because AfterLoadGame is also called
02721      * for OTTD savegames which have their own NewGRF logic. */
02722     ClearGRFConfigList(&_grfconfig);
02723     GamelogReset();
02724     if (!LoadOldSaveGame(filename)) return SL_REINIT;
02725     _sl_version = 0;
02726     _sl_minor_version = 0;
02727     GamelogStartAction(GLAT_LOAD);
02728     if (!AfterLoadGame()) {
02729       GamelogStopAction();
02730       return SL_REINIT;
02731     }
02732     GamelogStopAction();
02733     return SL_OK;
02734   }
02735 
02736   switch (mode) {
02737     case SL_LOAD_CHECK: _sl.action = SLA_LOAD_CHECK; break;
02738     case SL_LOAD: _sl.action = SLA_LOAD; break;
02739     case SL_SAVE: _sl.action = SLA_SAVE; break;
02740     default: NOT_REACHED();
02741   }
02742 
02743   try {
02744     FILE *fh = (mode == SL_SAVE) ? FioFOpenFile(filename, "wb", sb) : FioFOpenFile(filename, "rb", sb);
02745 
02746     /* Make it a little easier to load savegames from the console */
02747     if (fh == NULL && mode != SL_SAVE) fh = FioFOpenFile(filename, "rb", SAVE_DIR);
02748     if (fh == NULL && mode != SL_SAVE) fh = FioFOpenFile(filename, "rb", BASE_DIR);
02749     if (fh == NULL && mode != SL_SAVE) fh = FioFOpenFile(filename, "rb", SCENARIO_DIR);
02750 
02751     if (fh == NULL) {
02752       SlError(mode == SL_SAVE ? STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE : STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
02753     }
02754 
02755     if (mode == SL_SAVE) { // SAVE game
02756       DEBUG(desync, 1, "save: %08x; %02x; %s", _date, _date_fract, filename);
02757       if (_network_server || !_settings_client.gui.threaded_saves) threaded = false;
02758 
02759       return DoSave(new FileWriter(fh), threaded);
02760     }
02761 
02762     /* LOAD game */
02763     assert(mode == SL_LOAD || mode == SL_LOAD_CHECK);
02764     DEBUG(desync, 1, "load: %s", filename);
02765     return DoLoad(new FileReader(fh), mode == SL_LOAD_CHECK);
02766   } catch (...) {
02767     ClearSaveLoadState();
02768 
02769     /* Skip the "colour" character */
02770     if (mode != SL_LOAD_CHECK) DEBUG(sl, 0, "%s", GetSaveLoadErrorString() + 3);
02771 
02772     /* A saver/loader exception!! reinitialize all variables to prevent crash! */
02773     return (mode == SL_LOAD) ? SL_REINIT : SL_ERROR;
02774   }
02775 }
02776 
02778 void DoExitSave()
02779 {
02780   SaveOrLoad("exit.sav", SL_SAVE, AUTOSAVE_DIR);
02781 }
02782 
02788 void GenerateDefaultSaveName(char *buf, const char *last)
02789 {
02790   /* Check if we have a name for this map, which is the name of the first
02791    * available company. When there's no company available we'll use
02792    * 'Spectator' as "company" name. */
02793   CompanyID cid = _local_company;
02794   if (!Company::IsValidID(cid)) {
02795     const Company *c;
02796     FOR_ALL_COMPANIES(c) {
02797       cid = c->index;
02798       break;
02799     }
02800   }
02801 
02802   SetDParam(0, cid);
02803 
02804   /* Insert current date */
02805   switch (_settings_client.gui.date_format_in_default_names) {
02806     case 0: SetDParam(1, STR_JUST_DATE_LONG); break;
02807     case 1: SetDParam(1, STR_JUST_DATE_TINY); break;
02808     case 2: SetDParam(1, STR_JUST_DATE_ISO); break;
02809     default: NOT_REACHED();
02810   }
02811   SetDParam(2, _date);
02812 
02813   /* Get the correct string (special string for when there's not company) */
02814   GetString(buf, !Company::IsValidID(cid) ? STR_SAVEGAME_NAME_SPECTATOR : STR_SAVEGAME_NAME_DEFAULT, last);
02815   SanitizeFilename(buf);
02816 }
02817 
02818 #if 0
02819 
02825 int GetSavegameType(char *file)
02826 {
02827   const SaveLoadFormat *fmt;
02828   uint32 hdr;
02829   FILE *f;
02830   int mode = SL_OLD_LOAD;
02831 
02832   f = fopen(file, "rb");
02833   if (fread(&hdr, sizeof(hdr), 1, f) != 1) {
02834     DEBUG(sl, 0, "Savegame is obsolete or invalid format");
02835     mode = SL_LOAD; // don't try to get filename, just show name as it is written
02836   } else {
02837     /* see if we have any loader for this type. */
02838     for (fmt = _saveload_formats; fmt != endof(_saveload_formats); fmt++) {
02839       if (fmt->tag == hdr) {
02840         mode = SL_LOAD; // new type of savegame
02841         break;
02842       }
02843     }
02844   }
02845 
02846   fclose(f);
02847   return mode;
02848 }
02849 #endif