oldloader.cpp

Go to the documentation of this file.
00001 /* $Id: oldloader.cpp 13916 2008-08-01 19:37:10Z rubidium $ */
00002 
00005 #include "stdafx.h"
00006 #include "openttd.h"
00007 #include "station_map.h"
00008 #include "town.h"
00009 #include "industry.h"
00010 #include "station.h"
00011 #include "player_func.h"
00012 #include "player_base.h"
00013 #include "engine.h"
00014 #include "aircraft.h"
00015 #include "roadveh.h"
00016 #include "ship.h"
00017 #include "train.h"
00018 #include "signs.h"
00019 #include "debug.h"
00020 #include "depot.h"
00021 #include "newgrf_config.h"
00022 #include "ai/ai.h"
00023 #include "ai/default/default.h"
00024 #include "zoom_func.h"
00025 #include "functions.h"
00026 #include "date_func.h"
00027 #include "vehicle_func.h"
00028 #include "variables.h"
00029 
00030 #include "table/strings.h"
00031 
00032 enum {
00033   HEADER_SIZE = 49,
00034   BUFFER_SIZE = 4096,
00035 
00036   OLD_MAP_SIZE = 256 * 256
00037 };
00038 
00039 struct LoadgameState {
00040   FILE *file;
00041 
00042   uint chunk_size;
00043 
00044   bool decoding;
00045   byte decode_char;
00046 
00047   uint buffer_count;
00048   uint buffer_cur;
00049   byte buffer[BUFFER_SIZE];
00050 
00051   uint total_read;
00052   bool failed;
00053 };
00054 
00055 /* OldChunk-Type */
00056 enum OldChunkType {
00057   OC_SIMPLE    = 0,
00058   OC_NULL      = 1,
00059   OC_CHUNK     = 2,
00060   OC_ASSERT    = 3,
00061   /* 8 bytes allocated (256 max) */
00062 
00063   OC_VAR_I8    = 1 << 8,
00064   OC_VAR_U8    = 2 << 8,
00065   OC_VAR_I16   = 3 << 8,
00066   OC_VAR_U16   = 4 << 8,
00067   OC_VAR_I32   = 5 << 8,
00068   OC_VAR_U32   = 6 << 8,
00069   OC_VAR_I64   = 7 << 8,
00070   /* 8 bytes allocated (256 max) */
00071 
00072   OC_FILE_I8   = 1 << 16,
00073   OC_FILE_U8   = 2 << 16,
00074   OC_FILE_I16  = 3 << 16,
00075   OC_FILE_U16  = 4 << 16,
00076   OC_FILE_I32  = 5 << 16,
00077   OC_FILE_U32  = 6 << 16,
00078   /* 8 bytes allocated (256 max) */
00079 
00080   OC_INT8      = OC_VAR_I8   | OC_FILE_I8,
00081   OC_UINT8     = OC_VAR_U8   | OC_FILE_U8,
00082   OC_INT16     = OC_VAR_I16  | OC_FILE_I16,
00083   OC_UINT16    = OC_VAR_U16  | OC_FILE_U16,
00084   OC_INT32     = OC_VAR_I32  | OC_FILE_I32,
00085   OC_UINT32    = OC_VAR_U32  | OC_FILE_U32,
00086 
00087   OC_TILE      = OC_VAR_U32  | OC_FILE_U16,
00088 
00089   OC_END       = 0 
00090 };
00091 
00092 DECLARE_ENUM_AS_BIT_SET(OldChunkType);
00093 
00094 typedef bool OldChunkProc(LoadgameState *ls, int num);
00095 
00096 struct OldChunks {
00097   OldChunkType type;   
00098   uint32 amount;       
00099 
00100   void *ptr;           
00101   uint offset;         
00102   OldChunkProc *proc;  
00103 };
00104 
00105 /* If it fails, check lines above.. */
00106 assert_compile(sizeof(TileIndex) == 4);
00107 
00108 static uint32 _bump_assert_value;
00109 static bool   _read_ttdpatch_flags;
00110 
00111 static OldChunkType GetOldChunkType(OldChunkType type)     {return (OldChunkType)GB(type, 0, 8);}
00112 static OldChunkType GetOldChunkVarType(OldChunkType type)  {return (OldChunkType)(GB(type, 8, 8) << 8);}
00113 static OldChunkType GetOldChunkFileType(OldChunkType type) {return (OldChunkType)(GB(type, 16, 8) << 16);}
00114 
00115 static inline byte CalcOldVarLen(OldChunkType type)
00116 {
00117   static const byte type_mem_size[] = {0, 1, 1, 2, 2, 4, 4, 8};
00118   byte length = GB(type, 8, 8);
00119   assert(length != 0 && length < lengthof(type_mem_size));
00120   return type_mem_size[length];
00121 }
00122 
00128 static byte ReadByteFromFile(LoadgameState *ls)
00129 {
00130   /* To avoid slow reads, we read BUFFER_SIZE of bytes per time
00131   and just return a byte per time */
00132   if (ls->buffer_cur >= ls->buffer_count) {
00133     /* Read some new bytes from the file */
00134     int count = (int)fread(ls->buffer, 1, BUFFER_SIZE, ls->file);
00135 
00136     /* We tried to read, but there is nothing in the file anymore.. */
00137     if (count == 0) {
00138       DEBUG(oldloader, 0, "Read past end of file, loading failed");
00139       ls->failed = true;
00140     }
00141 
00142     ls->buffer_count = count;
00143     ls->buffer_cur   = 0;
00144   }
00145 
00146   return ls->buffer[ls->buffer_cur++];
00147 }
00148 
00154 static byte ReadByte(LoadgameState *ls)
00155 {
00156   /* Old savegames have a nice compression algorithm (RLE)
00157   which means that we have a chunk, which starts with a length
00158   byte. If that byte is negative, we have to repeat the next byte
00159   that many times ( + 1). Else, we need to read that amount of bytes.
00160   Works pretty good if you have many zero's behind eachother */
00161 
00162   if (ls->chunk_size == 0) {
00163     /* Read new chunk */
00164     int8 new_byte = ReadByteFromFile(ls);
00165 
00166     if (new_byte < 0) {
00167       /* Repeat next char for new_byte times */
00168       ls->decoding    = true;
00169       ls->decode_char = ReadByteFromFile(ls);
00170       ls->chunk_size  = -new_byte + 1;
00171     } else {
00172       ls->decoding    = false;
00173       ls->chunk_size  = new_byte + 1;
00174     }
00175   }
00176 
00177   ls->total_read++;
00178   ls->chunk_size--;
00179 
00180   return ls->decoding ? ls->decode_char : ReadByteFromFile(ls);
00181 }
00182 
00183 static inline uint16 ReadUint16(LoadgameState *ls)
00184 {
00185   byte x = ReadByte(ls);
00186   return x | ReadByte(ls) << 8;
00187 }
00188 
00189 static inline uint32 ReadUint32(LoadgameState *ls)
00190 {
00191   uint16 x = ReadUint16(ls);
00192   return x | ReadUint16(ls) << 16;
00193 }
00194 
00200 static bool LoadChunk(LoadgameState *ls, void *base, const OldChunks *chunks)
00201 {
00202   const OldChunks *chunk = chunks;
00203   byte *base_ptr = (byte*)base;
00204 
00205   while (chunk->type != OC_END) {
00206     byte* ptr = (byte*)chunk->ptr;
00207     uint i;
00208 
00209     for (i = 0; i < chunk->amount; i++) {
00210       if (ls->failed) return false;
00211 
00212       /* Handle simple types */
00213       if (GetOldChunkType(chunk->type) != 0) {
00214         switch (GetOldChunkType(chunk->type)) {
00215           /* Just read the byte and forget about it */
00216           case OC_NULL: ReadByte(ls); break;
00217 
00218           case OC_CHUNK:
00219             /* Call function, with 'i' as parameter to tell which item we
00220              * are going to read */
00221             if (!chunk->proc(ls, i)) return false;
00222             break;
00223 
00224           case OC_ASSERT:
00225             DEBUG(oldloader, 4, "Assert point: 0x%X / 0x%X", ls->total_read, chunk->offset + _bump_assert_value);
00226             if (ls->total_read != chunk->offset + _bump_assert_value) ls->failed = true;
00227           default: break;
00228         }
00229       } else {
00230         uint64 res = 0;
00231 
00232         /* Reading from the file: bits 16 to 23 have the FILE type */
00233         switch (GetOldChunkFileType(chunk->type)) {
00234           case OC_FILE_I8:  res = (int8)ReadByte(ls); break;
00235           case OC_FILE_U8:  res = ReadByte(ls); break;
00236           case OC_FILE_I16: res = (int16)ReadUint16(ls); break;
00237           case OC_FILE_U16: res = ReadUint16(ls); break;
00238           case OC_FILE_I32: res = (int32)ReadUint32(ls); break;
00239           case OC_FILE_U32: res = ReadUint32(ls); break;
00240           default: NOT_REACHED();
00241         }
00242 
00243         /* Sanity check */
00244         assert(base_ptr != NULL || chunk->ptr != NULL);
00245 
00246         /* Writing to the var: bits 8 to 15 have the VAR type */
00247         if (chunk->ptr == NULL) ptr = base_ptr + chunk->offset;
00248 
00249         /* Write the data */
00250         switch (GetOldChunkVarType(chunk->type)) {
00251           case OC_VAR_I8: *(int8  *)ptr = GB(res, 0, 8); break;
00252           case OC_VAR_U8: *(uint8 *)ptr = GB(res, 0, 8); break;
00253           case OC_VAR_I16:*(int16 *)ptr = GB(res, 0, 16); break;
00254           case OC_VAR_U16:*(uint16*)ptr = GB(res, 0, 16); break;
00255           case OC_VAR_I32:*(int32 *)ptr = res; break;
00256           case OC_VAR_U32:*(uint32*)ptr = res; break;
00257           case OC_VAR_I64:*(int64 *)ptr = res; break;
00258           default: NOT_REACHED();
00259         }
00260 
00261         /* Increase pointer base for arrays when looping */
00262         if (chunk->amount > 1 && chunk->ptr != NULL) ptr += CalcOldVarLen(chunk->type);
00263       }
00264     }
00265 
00266     chunk++;
00267   }
00268 
00269   return true;
00270 }
00271 
00277 static void InitLoading(LoadgameState *ls)
00278 {
00279   ls->chunk_size   = 0;
00280   ls->total_read   = 0;
00281   ls->failed       = false;
00282 
00283   ls->decoding     = false;
00284   ls->decode_char  = 0;
00285 
00286   ls->buffer_cur   = 0;
00287   ls->buffer_count = 0;
00288   memset(ls->buffer, 0, BUFFER_SIZE);
00289 
00290   _bump_assert_value = 0;
00291 
00292   _read_ttdpatch_flags = false;
00293 }
00294 
00295 
00296 /*
00297  * Begin -- Stuff to fix the savegames to be OpenTTD compatible
00298  */
00299 
00300 extern uint32 GetOldTownName(uint32 townnameparts, byte old_town_name_type);
00301 
00302 static void FixOldTowns()
00303 {
00304   Town *town;
00305 
00306   /* Convert town-names if needed */
00307   FOR_ALL_TOWNS(town) {
00308     if (IsInsideMM(town->townnametype, 0x20C1, 0x20C3)) {
00309       town->townnametype = SPECSTR_TOWNNAME_ENGLISH + _opt.town_name;
00310       town->townnameparts = GetOldTownName(town->townnameparts, _opt.town_name);
00311     }
00312   }
00313 }
00314 
00315 static void FixOldStations()
00316 {
00317   Station *st;
00318 
00319   FOR_ALL_STATIONS(st) {
00320     /* Check if we need to swap width and height for the station */
00321     if (st->train_tile != 0 && GetRailStationAxis(st->train_tile) != AXIS_X) {
00322       Swap(st->trainst_w, st->trainst_h);
00323     }
00324   }
00325 }
00326 
00327 static StringID *_old_vehicle_names = NULL;
00328 
00329 static void FixOldVehicles()
00330 {
00331   /* Check for shared orders, and link them correctly */
00332   Vehicle* v;
00333 
00334   FOR_ALL_VEHICLES(v) {
00335     Vehicle *u;
00336 
00337     v->name = CopyFromOldName(_old_vehicle_names[v->index]);
00338 
00339     /* We haven't used this bit for stations for ages */
00340     if (v->type == VEH_ROAD &&
00341         v->u.road.state != RVSB_IN_DEPOT &&
00342         v->u.road.state != RVSB_WORMHOLE) {
00343       ClrBit(v->u.road.state, RVS_IS_STOPPING);
00344     }
00345 
00346     /* The subtype should be 0, but it sometimes isn't :( */
00347     if (v->type == VEH_ROAD) v->subtype = 0;
00348 
00349     /* Sometimes primary vehicles would have a nothing (invalid) order
00350      * or vehicles that could not have an order would still have a
00351      * (loading) order which causes assertions and the like later on.
00352      */
00353     if (!IsPlayerBuildableVehicleType(v) ||
00354         (v->IsPrimaryVehicle() && v->current_order.type == OT_NOTHING)) {
00355       v->current_order.type = OT_DUMMY;
00356     }
00357 
00358     FOR_ALL_VEHICLES_FROM(u, v->index + 1) {
00359       /* If a vehicle has the same orders, add the link to eachother
00360        * in both vehicles */
00361       if (v->orders == u->orders) {
00362         v->next_shared = u;
00363         u->prev_shared = v;
00364         break;
00365       }
00366     }
00367   }
00368 }
00369 
00370 /*
00371  * End -- Stuff to fix the savegames to be OpenTTD compatible
00372  */
00373 
00374 
00375 /* Help:
00376  *  - OCL_SVAR: load 'type' to offset 'offset' in a struct of type 'base', which must also
00377  *       be given via base in LoadChunk() as real pointer
00378  *  - OCL_VAR: load 'type' to a global var
00379  *  - OCL_END: every struct must end with this
00380  *  - OCL_NULL: read 'amount' of bytes and send them to /dev/null or something
00381  *  - OCL_CHUNK: load an other proc to load a part of the savegame, 'amount' times
00382  *  - OCL_ASSERT: to check if we are really at the place we expect to be.. because old savegames are too binary to be sure ;)
00383  */
00384 #define OCL_SVAR(type, base, offset)         { type,          1, NULL,    (uint)cpp_offsetof(base, offset), NULL }
00385 #define OCL_VAR(type, amount, pointer)       { type,     amount, pointer, 0,                      NULL }
00386 #define OCL_END()                                   { OC_END,        0, NULL,    0,                      NULL }
00387 #define OCL_NULL(amount)                            { OC_NULL,  amount, NULL,    0,                      NULL }
00388 #define OCL_CHUNK(amount, proc)                     { OC_CHUNK, amount, NULL,    0,                      proc }
00389 #define OCL_ASSERT(size)                            { OC_ASSERT,     1, NULL, size,                      NULL }
00390 
00391 /* The savegames has some hard-coded pointers, because it always enters the same
00392     piece of memory.. we don't.. so we need to remap ;)
00393    Old Towns are 94 bytes big
00394    Old Orders are 2 bytes big */
00395 #define REMAP_TOWN_IDX(x) ((x) - (0x0459154 - 0x0458EF0)) / 94
00396 #define REMAP_ORDER_IDX(x) ((x) - (0x045AB08 - 0x0458EF0)) / 2
00397 
00398 extern TileIndex *_animated_tile_list;
00399 extern uint _animated_tile_count;
00400 extern char _name_array[512][32];
00401 
00402 static byte   _old_vehicle_multiplier;
00403 static uint8  _old_map3[OLD_MAP_SIZE * 2];
00404 static bool   _new_ttdpatch_format;
00405 static uint32 _old_town_index;
00406 static uint16 _old_string_id;
00407 static uint16 _old_string_id_2;
00408 static uint16 _old_extra_chunk_nums;
00409 
00410 static void ReadTTDPatchFlags()
00411 {
00412   int i;
00413 
00414   if (_read_ttdpatch_flags) return;
00415 
00416   _read_ttdpatch_flags = true;
00417 
00418   /* TTDPatch misuses _old_map3 for flags.. read them! */
00419   _old_vehicle_multiplier = _old_map3[0];
00420   /* Somehow.... there was an error in some savegames, so 0 becomes 1
00421   and 1 becomes 2. The rest of the values are okay */
00422   if (_old_vehicle_multiplier < 2) _old_vehicle_multiplier++;
00423 
00424   _old_vehicle_names = MallocT<StringID>(_old_vehicle_multiplier * 850);
00425 
00426   /* TTDPatch increases the Vehicle-part in the middle of the game,
00427   so if the multipler is anything else but 1, the assert fails..
00428   bump the assert value so it doesn't!
00429   (1 multipler == 850 vehicles
00430   1 vehicle   == 128 bytes */
00431   _bump_assert_value = (_old_vehicle_multiplier - 1) * 850 * 128;
00432 
00433   /* Check if we have a modern TTDPatch savegame (has extra data all around) */
00434   _new_ttdpatch_format = (memcmp(&_old_map3[0x1FFFA], "TTDp", 4) == 0);
00435 
00436   _old_extra_chunk_nums = _old_map3[_new_ttdpatch_format ? 0x1FFFE : 0x2];
00437 
00438   /* Clean the misused places */
00439   for (i = 0;       i < 17;      i++) _old_map3[i] = 0;
00440   for (i = 0x1FE00; i < 0x20000; i++) _old_map3[i] = 0;
00441 
00442   if (_new_ttdpatch_format) DEBUG(oldloader, 2, "Found TTDPatch game");
00443 
00444   DEBUG(oldloader, 3, "Vehicle-multiplier is set to %d (%d vehicles)", _old_vehicle_multiplier, _old_vehicle_multiplier * 850);
00445 }
00446 
00447 static const OldChunks town_chunk[] = {
00448   OCL_SVAR(   OC_TILE, Town, xy ),
00449   OCL_NULL( 2 ),         
00450   OCL_SVAR( OC_UINT16, Town, townnametype ),
00451   OCL_SVAR( OC_UINT32, Town, townnameparts ),
00452   OCL_SVAR(  OC_UINT8, Town, grow_counter ),
00453   OCL_NULL( 1 ),         
00454   OCL_NULL( 4 ),         
00455   OCL_NULL( 2 ),         
00456   OCL_SVAR( OC_UINT16, Town, flags12 ),
00457   OCL_NULL( 10 ),        
00458 
00459   OCL_SVAR( OC_UINT16, Town, ratings[0] ),
00460   OCL_SVAR( OC_UINT16, Town, ratings[1] ),
00461   OCL_SVAR( OC_UINT16, Town, ratings[2] ),
00462   OCL_SVAR( OC_UINT16, Town, ratings[3] ),
00463   OCL_SVAR( OC_UINT16, Town, ratings[4] ),
00464   OCL_SVAR( OC_UINT16, Town, ratings[5] ),
00465   OCL_SVAR( OC_UINT16, Town, ratings[6] ),
00466   OCL_SVAR( OC_UINT16, Town, ratings[7] ),
00467 
00468   /* XXX - This is pretty odd.. we read 32bit, but only write 8bit.. sure there is
00469   nothing changed ? ? */
00470   OCL_SVAR( OC_FILE_U32 | OC_VAR_U8, Town, have_ratings ),
00471   OCL_SVAR( OC_FILE_U32 | OC_VAR_U8, Town, statues ),
00472   OCL_NULL( 2 ),         
00473   OCL_SVAR(  OC_UINT8, Town, time_until_rebuild ),
00474   OCL_SVAR(  OC_UINT8, Town, growth_rate ),
00475 
00476   OCL_SVAR( OC_UINT16, Town, new_max_pass ),
00477   OCL_SVAR( OC_UINT16, Town, new_max_mail ),
00478   OCL_SVAR( OC_UINT16, Town, new_act_pass ),
00479   OCL_SVAR( OC_UINT16, Town, new_act_mail ),
00480   OCL_SVAR( OC_UINT16, Town, max_pass ),
00481   OCL_SVAR( OC_UINT16, Town, max_mail ),
00482   OCL_SVAR( OC_UINT16, Town, act_pass ),
00483   OCL_SVAR( OC_UINT16, Town, act_mail ),
00484 
00485   OCL_SVAR(  OC_UINT8, Town, pct_pass_transported ),
00486   OCL_SVAR(  OC_UINT8, Town, pct_mail_transported ),
00487 
00488   OCL_SVAR( OC_UINT16, Town, new_act_food ),
00489   OCL_SVAR( OC_UINT16, Town, new_act_water ),
00490   OCL_SVAR( OC_UINT16, Town, act_food ),
00491   OCL_SVAR( OC_UINT16, Town, act_water ),
00492 
00493   OCL_SVAR(  OC_UINT8, Town, road_build_months ),
00494   OCL_SVAR(  OC_UINT8, Town, fund_buildings_months ),
00495 
00496   OCL_NULL( 8 ),         
00497 
00498   OCL_END()
00499 };
00500 static bool LoadOldTown(LoadgameState *ls, int num)
00501 {
00502   return LoadChunk(ls, new (num) Town(), town_chunk);
00503 }
00504 
00505 static uint16 _old_order;
00506 static const OldChunks order_chunk[] = {
00507   OCL_VAR ( OC_UINT16,   1, &_old_order ),
00508   OCL_END()
00509 };
00510 
00511 static bool LoadOldOrder(LoadgameState *ls, int num)
00512 {
00513   if (!LoadChunk(ls, NULL, order_chunk)) return false;
00514 
00515   AssignOrder(new (num) Order(), UnpackOldOrder(_old_order));
00516 
00517   /* Relink the orders to eachother (in TTD(Patch) the orders for one
00518   vehicle are behind eachother, with an invalid order (OT_NOTHING) as indication that
00519   it is the last order */
00520   if (num > 0 && GetOrder(num)->IsValid())
00521     GetOrder(num - 1)->next = GetOrder(num);
00522 
00523   return true;
00524 }
00525 
00526 static bool LoadOldAnimTileList(LoadgameState *ls, int num)
00527 {
00528   /* This is sligthly hackish - we must load a chunk into an array whose
00529    * address isn't static, but instead pointed to by _animated_tile_list.
00530    * To achieve that, create an OldChunks list on the stack on the fly.
00531    * The list cannot be static because the value of _animated_tile_list
00532    * can change between calls. */
00533 
00534   const OldChunks anim_chunk[] = {
00535     OCL_VAR (   OC_TILE, 256, _animated_tile_list ),
00536     OCL_END ()
00537   };
00538 
00539   if (!LoadChunk(ls, NULL, anim_chunk)) return false;
00540 
00541   /* Update the animated tile counter by counting till the first zero in the array */
00542   for (_animated_tile_count = 0; _animated_tile_count < 256; _animated_tile_count++) {
00543     if (_animated_tile_list[_animated_tile_count] == 0) break;
00544   }
00545 
00546   return true;
00547 }
00548 
00549 static const OldChunks depot_chunk[] = {
00550   OCL_SVAR(   OC_TILE, Depot, xy ),
00551   OCL_VAR ( OC_UINT32,   1, &_old_town_index ),
00552   OCL_END()
00553 };
00554 
00555 static bool LoadOldDepot(LoadgameState *ls, int num)
00556 {
00557   if (!LoadChunk(ls, new (num) Depot(), depot_chunk)) return false;
00558 
00559   if (IsValidDepotID(num)) {
00560     GetDepot(num)->town_index = REMAP_TOWN_IDX(_old_town_index);
00561   }
00562 
00563   return true;
00564 }
00565 
00566 static int32 _old_price;
00567 static uint16 _old_price_frac;
00568 static const OldChunks price_chunk[] = {
00569   OCL_VAR (  OC_INT32,   1, &_old_price ),
00570   OCL_VAR ( OC_UINT16,   1, &_old_price_frac ),
00571   OCL_END()
00572 };
00573 
00574 static bool LoadOldPrice(LoadgameState *ls, int num)
00575 {
00576   if (!LoadChunk(ls, NULL, price_chunk)) return false;
00577 
00578   /* We use a struct to store the prices, but they are ints in a row..
00579   so just access the struct as an array of int32's */
00580   ((Money*)&_price)[num] = _old_price;
00581   _price_frac[num] = _old_price_frac;
00582 
00583   return true;
00584 }
00585 
00586 static const OldChunks cargo_payment_rate_chunk[] = {
00587   OCL_VAR (  OC_INT32,   1, &_old_price ),
00588   OCL_VAR ( OC_UINT16,   1, &_old_price_frac ),
00589 
00590   OCL_NULL( 2 ),         
00591   OCL_END()
00592 };
00593 
00594 static bool LoadOldCargoPaymentRate(LoadgameState *ls, int num)
00595 {
00596   if (!LoadChunk(ls, NULL, cargo_payment_rate_chunk)) return false;
00597 
00598   _cargo_payment_rates[num] = -_old_price;
00599   _cargo_payment_rates_frac[num] = _old_price_frac;
00600 
00601   return true;
00602 }
00603 
00604 static uint8  _old_platforms;
00605 static uint   _current_station_id;
00606 static uint16 _waiting_acceptance;
00607 static uint8  _cargo_source;
00608 static uint8  _cargo_days;
00609 
00610 static const OldChunks goods_chunk[] = {
00611   OCL_VAR ( OC_UINT16, 1,          &_waiting_acceptance ),
00612   OCL_SVAR(  OC_UINT8, GoodsEntry, days_since_pickup ),
00613   OCL_SVAR(  OC_UINT8, GoodsEntry, rating ),
00614   OCL_VAR (  OC_UINT8, 1,          &_cargo_source ),
00615   OCL_VAR (  OC_UINT8, 1,          &_cargo_days ),
00616   OCL_SVAR(  OC_UINT8, GoodsEntry, last_speed ),
00617   OCL_SVAR(  OC_UINT8, GoodsEntry, last_age ),
00618 
00619   OCL_END()
00620 };
00621 
00622 static bool LoadOldGood(LoadgameState *ls, int num)
00623 {
00624   Station *st = GetStation(_current_station_id);
00625   GoodsEntry *ge = &st->goods[num];
00626   bool ret = LoadChunk(ls, ge, goods_chunk);
00627   if (!ret) return false;
00628 
00629   SB(ge->acceptance_pickup, GoodsEntry::ACCEPTANCE, 1, HasBit(_waiting_acceptance, 15));
00630   SB(ge->acceptance_pickup, GoodsEntry::PICKUP, 1, _cargo_source != 0xFF);
00631   if (GB(_waiting_acceptance, 0, 12) != 0) {
00632     CargoPacket *cp = new CargoPacket();
00633     cp->source          = (_cargo_source == 0xFF) ? INVALID_STATION : _cargo_source;
00634     cp->count           = GB(_waiting_acceptance, 0, 12);
00635     cp->days_in_transit = _cargo_days;
00636     ge->cargo.Append(cp);
00637   }
00638   return ret;
00639 }
00640 
00641 static const OldChunks station_chunk[] = {
00642   OCL_SVAR(   OC_TILE, Station, xy ),
00643   OCL_VAR ( OC_UINT32,   1, &_old_town_index ),
00644 
00645   OCL_NULL( 4 ), 
00646   OCL_SVAR(   OC_TILE, Station, train_tile ),
00647   OCL_SVAR(   OC_TILE, Station, airport_tile ),
00648   OCL_SVAR(   OC_TILE, Station, dock_tile ),
00649 
00650   OCL_VAR (  OC_UINT8,   1, &_old_platforms ),
00651 
00652   OCL_NULL( 1 ),         
00653   OCL_NULL( 2 ),         
00654 
00655   OCL_VAR ( OC_UINT16,   1, &_old_string_id ),
00656 
00657   OCL_NULL( 4 ),         
00658 
00659   OCL_SVAR( OC_UINT16, Station, had_vehicle_of_type ),
00660 
00661   OCL_CHUNK( 12, LoadOldGood ),
00662 
00663   OCL_SVAR(  OC_UINT8, Station, time_since_load ),
00664   OCL_SVAR(  OC_UINT8, Station, time_since_unload ),
00665   OCL_SVAR(  OC_UINT8, Station, delete_ctr ),
00666   OCL_SVAR(  OC_UINT8, Station, owner ),
00667   OCL_SVAR(  OC_UINT8, Station, facilities ),
00668   OCL_SVAR(  OC_UINT8, Station, airport_type ),
00669   /* Bus/truck status, no longer in use
00670    * Blocked months
00671    * Unknown
00672    */
00673   OCL_NULL( 4 ),
00674   OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Station, airport_flags ),
00675   OCL_NULL( 2 ),         
00676 
00677   OCL_NULL( 4 ),         
00678 
00679   OCL_END()
00680 };
00681 static bool LoadOldStation(LoadgameState *ls, int num)
00682 {
00683   Station *st = new (num) Station();
00684   _current_station_id = num;
00685 
00686   if (!LoadChunk(ls, st, station_chunk))
00687     return false;
00688 
00689   if (st->IsValid()) {
00690     if (st->train_tile) {
00691       /* Calculate the trainst_w and trainst_h */
00692       uint w = GB(_old_platforms, 3, 3);
00693       uint h = GB(_old_platforms, 0, 3);
00694       st->trainst_w = w;
00695       st->trainst_h = h;
00696     }
00697 
00698     st->town    = GetTown(REMAP_TOWN_IDX(_old_town_index));
00699     st->string_id = RemapOldStringID(_old_string_id);
00700   }
00701 
00702   return true;
00703 }
00704 
00705 static const OldChunks industry_chunk[] = {
00706   OCL_SVAR(   OC_TILE, Industry, xy ),
00707   OCL_VAR ( OC_UINT32,   1, &_old_town_index ),
00708   OCL_SVAR(  OC_UINT8, Industry, width ),
00709   OCL_SVAR(  OC_UINT8, Industry, height ),
00710   OCL_NULL( 2 ),  
00711 
00712   OCL_SVAR( OC_UINT16, Industry, produced_cargo_waiting[0] ),
00713   OCL_SVAR( OC_UINT16, Industry, produced_cargo_waiting[1] ),
00714 
00715   OCL_SVAR(  OC_UINT8, Industry, production_rate[0] ),
00716   OCL_SVAR(  OC_UINT8, Industry, production_rate[1] ),
00717 
00718   OCL_NULL( 3 ),  
00719 
00720   OCL_SVAR(  OC_UINT8, Industry, prod_level ),
00721 
00722   OCL_SVAR( OC_UINT16, Industry, this_month_production[0] ),
00723   OCL_SVAR( OC_UINT16, Industry, this_month_production[1] ),
00724   OCL_SVAR( OC_UINT16, Industry, this_month_transported[0] ),
00725   OCL_SVAR( OC_UINT16, Industry, this_month_transported[1] ),
00726 
00727   OCL_SVAR(  OC_UINT8, Industry, last_month_pct_transported[0] ),
00728   OCL_SVAR(  OC_UINT8, Industry, last_month_pct_transported[1] ),
00729 
00730   OCL_SVAR( OC_UINT16, Industry, last_month_production[0] ),
00731   OCL_SVAR( OC_UINT16, Industry, last_month_production[1] ),
00732   OCL_SVAR( OC_UINT16, Industry, last_month_transported[0] ),
00733   OCL_SVAR( OC_UINT16, Industry, last_month_transported[1] ),
00734 
00735   OCL_SVAR(  OC_UINT8, Industry, type ),
00736   OCL_SVAR(  OC_UINT8, Industry, owner ),
00737   OCL_SVAR(  OC_UINT8, Industry, random_color ),
00738   OCL_SVAR( OC_FILE_U8 | OC_VAR_I32, Industry, last_prod_year ),
00739   OCL_SVAR( OC_UINT16, Industry, counter ),
00740   OCL_SVAR(  OC_UINT8, Industry, was_cargo_delivered ),
00741 
00742   OCL_NULL( 9 ), 
00743 
00744   OCL_END()
00745 };
00746 
00747 static bool LoadOldIndustry(LoadgameState *ls, int num)
00748 {
00749   Industry *i = new (num) Industry();
00750   if (!LoadChunk(ls, i, industry_chunk)) return false;
00751 
00752   if (i->IsValid()) {
00753     i->town = GetTown(REMAP_TOWN_IDX(_old_town_index));
00754     IncIndustryTypeCount(i->type);
00755   }
00756 
00757   return true;
00758 }
00759 
00760 static PlayerID _current_player_id;
00761 static int32 _old_yearly;
00762 
00763 static const OldChunks player_yearly_chunk[] = {
00764   OCL_VAR(  OC_INT32,   1, &_old_yearly ),
00765   OCL_END()
00766 };
00767 
00768 static bool OldPlayerYearly(LoadgameState *ls, int num)
00769 {
00770   int i;
00771   Player *p = GetPlayer(_current_player_id);
00772 
00773   for (i = 0; i < 13; i++) {
00774     if (!LoadChunk(ls, NULL, player_yearly_chunk)) return false;
00775 
00776     p->yearly_expenses[num][i] = _old_yearly;
00777   }
00778 
00779   return true;
00780 }
00781 
00782 static const OldChunks player_economy_chunk[] = {
00783   OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, PlayerEconomyEntry, income ),
00784   OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, PlayerEconomyEntry, expenses ),
00785   OCL_SVAR( OC_INT32, PlayerEconomyEntry, delivered_cargo ),
00786   OCL_SVAR( OC_INT32, PlayerEconomyEntry, performance_history ),
00787   OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, PlayerEconomyEntry, company_value ),
00788 
00789   OCL_END()
00790 };
00791 
00792 static bool OldPlayerEconomy(LoadgameState *ls, int num)
00793 {
00794   int i;
00795   Player *p = GetPlayer(_current_player_id);
00796 
00797   if (!LoadChunk(ls, &p->cur_economy, player_economy_chunk)) return false;
00798 
00799   /* Don't ask, but the number in TTD(Patch) are inversed to OpenTTD */
00800   p->cur_economy.income   = -p->cur_economy.income;
00801   p->cur_economy.expenses = -p->cur_economy.expenses;
00802 
00803   for (i = 0; i < 24; i++) {
00804     if (!LoadChunk(ls, &p->old_economy[i], player_economy_chunk)) return false;
00805 
00806     p->old_economy[i].income   = -p->old_economy[i].income;
00807     p->old_economy[i].expenses = -p->old_economy[i].expenses;
00808   }
00809 
00810   return true;
00811 }
00812 
00813 static const OldChunks player_ai_build_rec_chunk[] = {
00814   OCL_SVAR(   OC_TILE, AiBuildRec, spec_tile ),
00815   OCL_SVAR(   OC_TILE, AiBuildRec, use_tile ),
00816   OCL_SVAR(  OC_UINT8, AiBuildRec, rand_rng ),
00817   OCL_SVAR(  OC_UINT8, AiBuildRec, cur_building_rule ),
00818   OCL_SVAR(  OC_UINT8, AiBuildRec, unk6 ),
00819   OCL_SVAR(  OC_UINT8, AiBuildRec, unk7 ),
00820   OCL_SVAR(  OC_UINT8, AiBuildRec, buildcmd_a ),
00821   OCL_SVAR(  OC_UINT8, AiBuildRec, buildcmd_b ),
00822   OCL_SVAR(  OC_UINT8, AiBuildRec, direction ),
00823   OCL_SVAR(  OC_UINT8, AiBuildRec, cargo ),
00824 
00825   OCL_NULL( 8 ),  
00826 
00827   OCL_END()
00828 };
00829 
00830 static bool OldLoadAIBuildRec(LoadgameState *ls, int num)
00831 {
00832   Player *p = GetPlayer(_current_player_id);
00833 
00834   switch (num) {
00835     case 0: return LoadChunk(ls, &_players_ai[p->index].src, player_ai_build_rec_chunk);
00836     case 1: return LoadChunk(ls, &_players_ai[p->index].dst, player_ai_build_rec_chunk);
00837     case 2: return LoadChunk(ls, &_players_ai[p->index].mid1, player_ai_build_rec_chunk);
00838     case 3: return LoadChunk(ls, &_players_ai[p->index].mid2, player_ai_build_rec_chunk);
00839   }
00840 
00841   return false;
00842 }
00843 static const OldChunks player_ai_chunk[] = {
00844   OCL_SVAR(  OC_UINT8, PlayerAI, state ),
00845   OCL_NULL( 1 ),         
00846   OCL_SVAR(  OC_UINT8, PlayerAI, state_mode ),
00847   OCL_SVAR( OC_UINT16, PlayerAI, state_counter ),
00848   OCL_SVAR( OC_UINT16, PlayerAI, timeout_counter ),
00849 
00850   OCL_CHUNK( 4, OldLoadAIBuildRec ),
00851 
00852   OCL_NULL( 20 ),        
00853 
00854   OCL_SVAR(  OC_UINT8, PlayerAI, cargo_type ),
00855   OCL_SVAR(  OC_UINT8, PlayerAI, num_wagons ),
00856   OCL_SVAR(  OC_UINT8, PlayerAI, build_kind ),
00857   OCL_SVAR(  OC_UINT8, PlayerAI, num_build_rec ),
00858   OCL_SVAR(  OC_UINT8, PlayerAI, num_loco_to_build ),
00859   OCL_SVAR(  OC_UINT8, PlayerAI, num_want_fullload ),
00860 
00861   OCL_NULL( 14 ),        
00862 
00863   OCL_NULL( 2 ),         
00864 
00865   OCL_SVAR( OC_UINT16, PlayerAI, wagon_list[0] ),
00866   OCL_SVAR( OC_UINT16, PlayerAI, wagon_list[1] ),
00867   OCL_SVAR( OC_UINT16, PlayerAI, wagon_list[2] ),
00868   OCL_SVAR( OC_UINT16, PlayerAI, wagon_list[3] ),
00869   OCL_SVAR( OC_UINT16, PlayerAI, wagon_list[4] ),
00870   OCL_SVAR( OC_UINT16, PlayerAI, wagon_list[5] ),
00871   OCL_SVAR( OC_UINT16, PlayerAI, wagon_list[6] ),
00872   OCL_SVAR( OC_UINT16, PlayerAI, wagon_list[7] ),
00873   OCL_SVAR( OC_UINT16, PlayerAI, wagon_list[8] ),
00874   OCL_SVAR(  OC_UINT8, PlayerAI, order_list_blocks[0] ),
00875   OCL_SVAR(  OC_UINT8, PlayerAI, order_list_blocks[1] ),
00876   OCL_SVAR(  OC_UINT8, PlayerAI, order_list_blocks[2] ),
00877   OCL_SVAR(  OC_UINT8, PlayerAI, order_list_blocks[3] ),
00878   OCL_SVAR(  OC_UINT8, PlayerAI, order_list_blocks[4] ),
00879   OCL_SVAR(  OC_UINT8, PlayerAI, order_list_blocks[5] ),
00880   OCL_SVAR(  OC_UINT8, PlayerAI, order_list_blocks[6] ),
00881   OCL_SVAR(  OC_UINT8, PlayerAI, order_list_blocks[7] ),
00882   OCL_SVAR(  OC_UINT8, PlayerAI, order_list_blocks[8] ),
00883   OCL_SVAR(  OC_UINT8, PlayerAI, order_list_blocks[9] ),
00884   OCL_SVAR(  OC_UINT8, PlayerAI, order_list_blocks[10] ),
00885   OCL_SVAR(  OC_UINT8, PlayerAI, order_list_blocks[11] ),
00886   OCL_SVAR(  OC_UINT8, PlayerAI, order_list_blocks[12] ),
00887   OCL_SVAR(  OC_UINT8, PlayerAI, order_list_blocks[13] ),
00888   OCL_SVAR(  OC_UINT8, PlayerAI, order_list_blocks[14] ),
00889   OCL_SVAR(  OC_UINT8, PlayerAI, order_list_blocks[15] ),
00890   OCL_SVAR(  OC_UINT8, PlayerAI, order_list_blocks[16] ),
00891   OCL_SVAR(  OC_UINT8, PlayerAI, order_list_blocks[17] ),
00892   OCL_SVAR(  OC_UINT8, PlayerAI, order_list_blocks[18] ),
00893   OCL_SVAR(  OC_UINT8, PlayerAI, order_list_blocks[19] ),
00894 
00895   OCL_SVAR( OC_UINT16, PlayerAI, start_tile_a ),
00896   OCL_SVAR( OC_UINT16, PlayerAI, start_tile_b ),
00897   OCL_SVAR( OC_UINT16, PlayerAI, cur_tile_a ),
00898   OCL_SVAR( OC_UINT16, PlayerAI, cur_tile_b ),
00899 
00900   OCL_SVAR(  OC_UINT8, PlayerAI, start_dir_a ),
00901   OCL_SVAR(  OC_UINT8, PlayerAI, start_dir_b ),
00902   OCL_SVAR(  OC_UINT8, PlayerAI, cur_dir_a ),
00903   OCL_SVAR(  OC_UINT8, PlayerAI, cur_dir_b ),
00904 
00905   OCL_SVAR(  OC_UINT8, PlayerAI, banned_tile_count ),
00906 
00907   OCL_SVAR(   OC_TILE, PlayerAI, banned_tiles[0] ),
00908   OCL_SVAR(  OC_UINT8, PlayerAI, banned_val[0] ),
00909   OCL_SVAR(   OC_TILE, PlayerAI, banned_tiles[1] ),
00910   OCL_SVAR(  OC_UINT8, PlayerAI, banned_val[1] ),
00911   OCL_SVAR(   OC_TILE, PlayerAI, banned_tiles[2] ),
00912   OCL_SVAR(  OC_UINT8, PlayerAI, banned_val[2] ),
00913   OCL_SVAR(   OC_TILE, PlayerAI, banned_tiles[3] ),
00914   OCL_SVAR(  OC_UINT8, PlayerAI, banned_val[3] ),
00915   OCL_SVAR(   OC_TILE, PlayerAI, banned_tiles[4] ),
00916   OCL_SVAR(  OC_UINT8, PlayerAI, banned_val[4] ),
00917   OCL_SVAR(   OC_TILE, PlayerAI, banned_tiles[5] ),
00918   OCL_SVAR(  OC_UINT8, PlayerAI, banned_val[5] ),
00919   OCL_SVAR(   OC_TILE, PlayerAI, banned_tiles[6] ),
00920   OCL_SVAR(  OC_UINT8, PlayerAI, banned_val[6] ),
00921   OCL_SVAR(   OC_TILE, PlayerAI, banned_tiles[7] ),
00922   OCL_SVAR(  OC_UINT8, PlayerAI, banned_val[7] ),
00923   OCL_SVAR(   OC_TILE, PlayerAI, banned_tiles[8] ),
00924   OCL_SVAR(  OC_UINT8, PlayerAI, banned_val[8] ),
00925   OCL_SVAR(   OC_TILE, PlayerAI, banned_tiles[9] ),
00926   OCL_SVAR(  OC_UINT8, PlayerAI, banned_val[9] ),
00927   OCL_SVAR(   OC_TILE, PlayerAI, banned_tiles[10] ),
00928   OCL_SVAR(  OC_UINT8, PlayerAI, banned_val[10] ),
00929   OCL_SVAR(   OC_TILE, PlayerAI, banned_tiles[11] ),
00930   OCL_SVAR(  OC_UINT8, PlayerAI, banned_val[11] ),
00931   OCL_SVAR(   OC_TILE, PlayerAI, banned_tiles[12] ),
00932   OCL_SVAR(  OC_UINT8, PlayerAI, banned_val[12] ),
00933   OCL_SVAR(   OC_TILE, PlayerAI, banned_tiles[13] ),
00934   OCL_SVAR(  OC_UINT8, PlayerAI, banned_val[13] ),
00935   OCL_SVAR(   OC_TILE, PlayerAI, banned_tiles[14] ),
00936   OCL_SVAR(  OC_UINT8, PlayerAI, banned_val[14] ),
00937   OCL_SVAR(   OC_TILE, PlayerAI, banned_tiles[15] ),
00938   OCL_SVAR(  OC_UINT8, PlayerAI, banned_val[15] ),
00939 
00940   OCL_SVAR(  OC_UINT8, PlayerAI, railtype_to_use ),
00941   OCL_SVAR(  OC_UINT8, PlayerAI, route_type_mask ),
00942 
00943   OCL_END()
00944 };
00945 
00946 static bool OldPlayerAI(LoadgameState *ls, int num)
00947 {
00948   return LoadChunk(ls, &_players_ai[_current_player_id], player_ai_chunk);
00949 }
00950 
00951 uint8 ai_tick;
00952 static const OldChunks player_chunk[] = {
00953   OCL_VAR ( OC_UINT16,   1, &_old_string_id ),
00954   OCL_SVAR( OC_UINT32, Player, name_2 ),
00955   OCL_SVAR( OC_UINT32, Player, face ),
00956   OCL_VAR ( OC_UINT16,   1, &_old_string_id_2 ),
00957   OCL_SVAR( OC_UINT32, Player, president_name_2 ),
00958 
00959   OCL_SVAR(  OC_INT32, Player, player_money ),
00960   OCL_SVAR(  OC_INT32, Player, current_loan ),
00961 
00962   OCL_SVAR(  OC_UINT8, Player, player_color ),
00963   OCL_SVAR(  OC_UINT8, Player, player_money_fraction ),
00964   OCL_SVAR(  OC_UINT8, Player, quarters_of_bankrupcy ),
00965   OCL_SVAR(  OC_UINT8, Player, bankrupt_asked ),
00966   OCL_SVAR( OC_FILE_U32 | OC_VAR_I64, Player, bankrupt_value ),
00967   OCL_SVAR( OC_UINT16, Player, bankrupt_timeout ),
00968 
00969   OCL_SVAR( OC_FILE_U32 | OC_VAR_U16, Player, cargo_types ),
00970 
00971   OCL_CHUNK( 3, OldPlayerYearly ),
00972   OCL_CHUNK( 1, OldPlayerEconomy ),
00973 
00974   OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Player, inaugurated_year),
00975   OCL_SVAR(                  OC_TILE, Player, last_build_coordinate ),
00976   OCL_SVAR(                 OC_UINT8, Player, num_valid_stat_ent ),
00977 
00978   OCL_CHUNK( 1, OldPlayerAI ),
00979 
00980   OCL_SVAR(  OC_UINT8, Player, block_preview ),
00981    OCL_VAR(  OC_UINT8,   1, &ai_tick ),
00982   OCL_SVAR(  OC_UINT8, Player, avail_railtypes ),
00983   OCL_SVAR(   OC_TILE, Player, location_of_house ),
00984   OCL_SVAR(  OC_UINT8, Player, share_owners[0] ),
00985   OCL_SVAR(  OC_UINT8, Player, share_owners[1] ),
00986   OCL_SVAR(  OC_UINT8, Player, share_owners[2] ),
00987   OCL_SVAR(  OC_UINT8, Player, share_owners[3] ),
00988 
00989   OCL_NULL( 8 ), 
00990 
00991   OCL_END()
00992 };
00993 
00994 static bool LoadOldPlayer(LoadgameState *ls, int num)
00995 {
00996   Player *p = GetPlayer((PlayerID)num);
00997 
00998   _current_player_id = (PlayerID)num;
00999 
01000   if (!LoadChunk(ls, p, player_chunk)) return false;
01001 
01002   if (_old_string_id == 0) {
01003     p->is_active = false;
01004     return true;
01005   }
01006 
01007   p->name_1 = RemapOldStringID(_old_string_id);
01008   p->president_name_1 = RemapOldStringID(_old_string_id_2);
01009   _players_ai[_current_player_id].tick = ai_tick;
01010 
01011   if (num == 0) {
01012     /* If the first player has no name, make sure we call it UNNAMED */
01013     if (p->name_1 == 0)
01014       p->name_1 = STR_SV_UNNAMED;
01015   } else {
01016     /* Beside some multiplayer maps (1 on 1), which we don't official support,
01017     all other players are an AI.. mark them as such */
01018     p->is_ai = true;
01019   }
01020 
01021   /* Sometimes it is better to not ask.. in old scenarios, the money
01022   was always 893288 pounds. In the newer versions this is correct,
01023   but correct for those oldies
01024   Ps: this also means that if you had exact 893288 pounds, you will go back
01025   to 10000.. this is a very VERY small chance ;) */
01026   if (p->player_money == 893288)
01027     p->player_money = p->current_loan = 100000;
01028 
01029   _player_colors[num] = p->player_color;
01030   p->inaugurated_year -= ORIGINAL_BASE_YEAR;
01031   if (p->location_of_house == 0xFFFF)
01032     p->location_of_house = 0;
01033 
01034   /* State 20 for AI players is sell vehicle. Since the AI struct is not
01035    * really figured out as of now, _players_ai[p->index].cur_veh; needed for 'sell vehicle'
01036    * is NULL and the function will crash. To fix this, just change the state
01037    * to some harmless state, like 'loop vehicle'; 1 */
01038   if (!IsHumanPlayer((PlayerID)num) && _players_ai[p->index].state == 20) _players_ai[p->index].state = 1;
01039 
01040   if (p->is_ai && (!_networking || _network_server) && _ai.enabled)
01041     AI_StartNewAI(p->index);
01042 
01043   return true;
01044 }
01045 
01046 static uint32 _old_order_ptr;
01047 static uint16 _old_next_ptr;
01048 static uint32 _current_vehicle_id;
01049 
01050 static const OldChunks vehicle_train_chunk[] = {
01051   OCL_SVAR(  OC_UINT8, VehicleRail, track ),
01052   OCL_SVAR(  OC_UINT8, VehicleRail, force_proceed ),
01053   OCL_SVAR( OC_UINT16, VehicleRail, crash_anim_pos ),
01054   OCL_SVAR(  OC_UINT8, VehicleRail, railtype ),
01055 
01056   OCL_NULL( 5 ), 
01057 
01058   OCL_END()
01059 };
01060 
01061 static const OldChunks vehicle_road_chunk[] = {
01062   OCL_SVAR(  OC_UINT8, VehicleRoad, state ),
01063   OCL_SVAR(  OC_UINT8, VehicleRoad, frame ),
01064   OCL_SVAR( OC_UINT16, VehicleRoad, blocked_ctr ),
01065   OCL_SVAR(  OC_UINT8, VehicleRoad, overtaking ),
01066   OCL_SVAR(  OC_UINT8, VehicleRoad, overtaking_ctr ),
01067   OCL_SVAR( OC_UINT16, VehicleRoad, crashed_ctr ),
01068   OCL_SVAR(  OC_UINT8, VehicleRoad, reverse_ctr ),
01069 
01070   OCL_NULL( 1 ), 
01071 
01072   OCL_END()
01073 };
01074 
01075 static const OldChunks vehicle_ship_chunk[] = {
01076   OCL_SVAR(  OC_UINT8, VehicleShip, state ),
01077 
01078   OCL_NULL( 9 ), 
01079 
01080   OCL_END()
01081 };
01082 
01083 static const OldChunks vehicle_air_chunk[] = {
01084   OCL_SVAR(  OC_UINT8, VehicleAir, pos ),
01085   OCL_SVAR(  OC_FILE_U8 | OC_VAR_U16, VehicleAir, targetairport ),
01086   OCL_SVAR( OC_UINT16, VehicleAir, crashed_counter ),
01087   OCL_SVAR(  OC_UINT8, VehicleAir, state ),
01088 
01089   OCL_NULL( 5 ), 
01090 
01091   OCL_END()
01092 };
01093 
01094 static const OldChunks vehicle_special_chunk[] = {
01095   OCL_SVAR( OC_UINT16, VehicleSpecial, animation_state ),
01096   OCL_SVAR(  OC_UINT8, VehicleSpecial, animation_substate ),
01097 
01098   OCL_NULL( 7 ), // Junk
01099 
01100   OCL_END()
01101 };
01102 
01103 static const OldChunks vehicle_disaster_chunk[] = {
01104   OCL_SVAR( OC_UINT16, VehicleDisaster, image_override ),
01105   OCL_SVAR( OC_UINT16, VehicleDisaster, big_ufo_destroyer_target ),
01106 
01107   OCL_NULL( 6 ), 
01108 
01109   OCL_END()
01110 };
01111 
01112 static const OldChunks vehicle_empty_chunk[] = {
01113   OCL_NULL( 10 ), 
01114 
01115   OCL_END()
01116 };
01117 
01118 static bool LoadOldVehicleUnion(LoadgameState *ls, int num)
01119 {
01120   Vehicle *v = GetVehicle(_current_vehicle_id);
01121   uint temp = ls->total_read;
01122   bool res;
01123 
01124   switch (v->type) {
01125     default: NOT_REACHED();
01126     case VEH_INVALID : res = LoadChunk(ls, NULL,           vehicle_empty_chunk);    break;
01127     case VEH_TRAIN   : res = LoadChunk(ls, &v->u.rail,     vehicle_train_chunk);    break;
01128     case VEH_ROAD    : res = LoadChunk(ls, &v->u.road,     vehicle_road_chunk);     break;
01129     case VEH_SHIP    : res = LoadChunk(ls, &v->u.ship,     vehicle_ship_chunk);     break;
01130     case VEH_AIRCRAFT: res = LoadChunk(ls, &v->u.air,      vehicle_air_chunk);      break;
01131     case VEH_SPECIAL : res = LoadChunk(ls, &v->u.special,  vehicle_special_chunk);  break;
01132     case VEH_DISASTER: res = LoadChunk(ls, &v->u.disaster, vehicle_disaster_chunk); break;
01133   }
01134 
01135   /* This chunk size should always be 10 bytes */
01136   if (ls->total_read - temp != 10) {
01137     DEBUG(oldloader, 0, "Assert failed in VehicleUnion: invalid chunk size");
01138     return false;
01139   }
01140 
01141   return res;
01142 }
01143 
01144 static uint16 _cargo_count;
01145 
01146 static const OldChunks vehicle_chunk[] = {
01147   OCL_SVAR(  OC_UINT8, Vehicle, subtype ),
01148 
01149   OCL_NULL( 2 ),         
01150   OCL_NULL( 2 ),         
01151 
01152   OCL_VAR ( OC_UINT32,   1, &_old_order_ptr ),
01153   OCL_VAR ( OC_UINT16,   1, &_old_order ),
01154 
01155   OCL_SVAR(  OC_UINT8, Vehicle, num_orders ),
01156   OCL_SVAR(  OC_UINT8, Vehicle, cur_order_index ),
01157   OCL_SVAR(   OC_TILE, Vehicle, dest_tile ),
01158   OCL_SVAR( OC_UINT16, Vehicle, load_unload_time_rem ),
01159   OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, date_of_last_service ),
01160   OCL_SVAR( OC_UINT16, Vehicle, service_interval ),
01161   OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Vehicle, last_station_visited ),
01162   OCL_SVAR(  OC_UINT8, Vehicle, tick_counter ),
01163   OCL_SVAR( OC_UINT16, Vehicle, max_speed ),
01164 
01165   OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Vehicle, x_pos ),
01166   OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Vehicle, y_pos ),
01167   OCL_SVAR(  OC_UINT8, Vehicle, z_pos ),
01168   OCL_SVAR(  OC_UINT8, Vehicle, direction ),
01169   OCL_NULL( 2 ),         
01170   OCL_NULL( 2 ),         
01171   OCL_NULL( 1 ),         
01172 
01173   OCL_SVAR(  OC_UINT8, Vehicle, owner ),
01174   OCL_SVAR(   OC_TILE, Vehicle, tile ),
01175   OCL_SVAR( OC_UINT16, Vehicle, cur_image ),
01176 
01177   OCL_NULL( 8 ),        
01178 
01179   OCL_SVAR( OC_FILE_U16 | OC_VAR_U8, Vehicle, vehstatus ),
01180   OCL_SVAR( OC_UINT16, Vehicle, cur_speed ),
01181   OCL_SVAR(  OC_UINT8, Vehicle, subspeed ),
01182   OCL_SVAR(  OC_UINT8, Vehicle, acceleration ),
01183   OCL_SVAR(  OC_UINT8, Vehicle, progress ),
01184 
01185   OCL_SVAR(  OC_UINT8, Vehicle, cargo_type ),
01186   OCL_SVAR( OC_UINT16, Vehicle, cargo_cap ),
01187   OCL_VAR ( OC_UINT16, 1,       &_cargo_count ),
01188   OCL_VAR (  OC_UINT8, 1,       &_cargo_source ),
01189   OCL_VAR (  OC_UINT8, 1,       &_cargo_days ),
01190 
01191   OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, age ),
01192   OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, max_age ),
01193   OCL_SVAR( OC_FILE_U8 | OC_VAR_I32, Vehicle, build_year ),
01194   OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Vehicle, unitnumber ),
01195 
01196   OCL_SVAR( OC_UINT16, Vehicle, engine_type ),
01197 
01198   OCL_SVAR(  OC_UINT8, Vehicle, spritenum ),
01199   OCL_SVAR(  OC_UINT8, Vehicle, day_counter ),
01200 
01201   OCL_SVAR(  OC_UINT8, Vehicle, breakdowns_since_last_service ),
01202   OCL_SVAR(  OC_UINT8, Vehicle, breakdown_ctr ),
01203   OCL_SVAR(  OC_UINT8, Vehicle, breakdown_delay ),
01204   OCL_SVAR(  OC_UINT8, Vehicle, breakdown_chance ),
01205 
01206   OCL_SVAR( OC_UINT16, Vehicle, reliability ),
01207   OCL_SVAR( OC_UINT16, Vehicle, reliability_spd_dec ),
01208 
01209   OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, Vehicle, profit_this_year ),
01210   OCL_SVAR( OC_FILE_I32 | OC_VAR_I64, Vehicle, profit_last_year ),
01211 
01212   OCL_VAR ( OC_UINT16,   1, &_old_next_ptr ),
01213 
01214   OCL_SVAR( OC_UINT32, Vehicle, value ),
01215 
01216   OCL_VAR ( OC_UINT16,   1, &_old_string_id ),
01217 
01218   OCL_CHUNK( 1, LoadOldVehicleUnion ),
01219 
01220   OCL_NULL( 20 ), 
01221 
01222   OCL_END()
01223 };
01224 
01225 bool LoadOldVehicle(LoadgameState *ls, int num)
01226 {
01227   uint i;
01228 
01229   /* Read the TTDPatch flags, because we need some info from it */
01230   ReadTTDPatchFlags();
01231 
01232   for (i = 0; i < _old_vehicle_multiplier; i++) {
01233     _current_vehicle_id = num * _old_vehicle_multiplier + i;
01234 
01235     /* Read the vehicle type and allocate the right vehicle */
01236     Vehicle *v;
01237     switch (ReadByte(ls)) {
01238       default: NOT_REACHED();
01239       case 0x00 /*VEH_INVALID */: v = new (_current_vehicle_id) InvalidVehicle();  break;
01240       case 0x10 /*VEH_TRAIN   */: v = new (_current_vehicle_id) Train();           break;
01241       case 0x11 /*VEH_ROAD    */: v = new (_current_vehicle_id) RoadVehicle();     break;
01242       case 0x12 /*VEH_SHIP    */: v = new (_current_vehicle_id) Ship();            break;
01243       case 0x13 /*VEH_AIRCRAFT*/: v = new (_current_vehicle_id) Aircraft();        break;
01244       case 0x14 /*VEH_SPECIAL */: v = new (_current_vehicle_id) SpecialVehicle();  break;
01245       case 0x15 /*VEH_DISASTER*/: v = new (_current_vehicle_id) DisasterVehicle(); break;
01246     }
01247     if (!LoadChunk(ls, v, vehicle_chunk)) return false;
01248 
01249     /* This should be consistent, else we have a big problem... */
01250     if (v->index != _current_vehicle_id) {
01251       DEBUG(oldloader, 0, "Loading failed - vehicle-array is invalid");
01252       return false;
01253     }
01254 
01255     if (_old_order_ptr != 0 && _old_order_ptr != 0xFFFFFFFF) {
01256       uint old_id = REMAP_ORDER_IDX(_old_order_ptr);
01257       /* There is a maximum of 5000 orders in old savegames, so *if*
01258        * we go over that limit something is very wrong. In that case
01259        * we just assume there are no orders for the vehicle.
01260        */
01261       if (old_id < 5000) v->orders = GetOrder(old_id);
01262     }
01263     AssignOrder(&v->current_order, UnpackOldOrder(_old_order));
01264 
01265     /* For some reason we need to correct for this */
01266     switch (v->spritenum) {
01267       case 0xfd: break;
01268       case 0xff: v->spritenum = 0xfe; break;
01269       default:   v->spritenum >>= 1; break;
01270     }
01271 
01272     if (_old_next_ptr != 0xFFFF) v->next = GetVehiclePoolSize() <= _old_next_ptr ? new (_old_next_ptr) InvalidVehicle() : GetVehicle(_old_next_ptr);
01273 
01274     _old_vehicle_names[_current_vehicle_id] = RemapOldStringID(_old_string_id);
01275     v->name = NULL;
01276 
01277     /* Vehicle-subtype is different in TTD(Patch) */
01278     if (v->type == VEH_SPECIAL) v->subtype = v->subtype >> 1;
01279 
01280     if (_cargo_count != 0) {
01281       CargoPacket *cp = new CargoPacket((_cargo_source == 0xFF) ? INVALID_STATION : _cargo_source, _cargo_count);
01282       cp->days_in_transit = _cargo_days;
01283       v->cargo.Append(cp);
01284     }
01285   }
01286 
01287   return true;
01288 }
01289 
01290 static const OldChunks sign_chunk[] = {
01291   OCL_VAR ( OC_UINT16, 1, &_old_string_id ),
01292   OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Sign, x ),
01293   OCL_SVAR( OC_FILE_U16 | OC_VAR_I32, Sign, y ),
01294   OCL_SVAR( OC_FILE_U16 | OC_VAR_I8, Sign, z ),
01295 
01296   OCL_NULL( 6 ),         
01297 
01298   OCL_END()
01299 };
01300 
01301 static bool LoadOldSign(LoadgameState *ls, int num)
01302 {
01303   Sign *si = new (num) Sign();
01304   if (!LoadChunk(ls, si, sign_chunk)) return false;
01305 
01306   _old_string_id = RemapOldStringID(_old_string_id);
01307   si->name = CopyFromOldName(_old_string_id);
01308 
01309   return true;
01310 }
01311 
01312 static const OldChunks engine_chunk[] = {
01313   OCL_SVAR( OC_UINT16, Engine, player_avail ),
01314   OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Engine, intro_date ),
01315   OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Engine, age ),
01316   OCL_SVAR( OC_UINT16, Engine, reliability ),
01317   OCL_SVAR( OC_UINT16, Engine, reliability_spd_dec ),
01318   OCL_SVAR( OC_UINT16, Engine, reliability_start ),
01319   OCL_SVAR( OC_UINT16, Engine, reliability_max ),
01320   OCL_SVAR( OC_UINT16, Engine, reliability_final ),
01321   OCL_SVAR( OC_UINT16, Engine, duration_phase_1 ),
01322   OCL_SVAR( OC_UINT16, Engine, duration_phase_2 ),
01323   OCL_SVAR( OC_UINT16, Engine, duration_phase_3 ),
01324 
01325   OCL_SVAR(  OC_UINT8, Engine, lifelength ),
01326   OCL_SVAR(  OC_UINT8, Engine, flags ),
01327   OCL_SVAR(  OC_UINT8, Engine, preview_player_rank ),
01328   OCL_SVAR(  OC_UINT8, Engine, preview_wait ),
01329 
01330   OCL_NULL( 2 ), 
01331 
01332   OCL_END()
01333 };
01334 
01335 static bool LoadOldEngine(LoadgameState *ls, int num)
01336 {
01337   if (!LoadChunk(ls, GetEngine(num), engine_chunk)) return false;
01338 
01339   /* Make sure wagons are marked as do-not-age */
01340   if ((num >= 27 && num < 54) || (num >= 57 && num < 84) || (num >= 89 && num < 116))
01341     GetEngine(num)->age = 0xFFFF;
01342 
01343   return true;
01344 }
01345 
01346 static bool LoadOldEngineName(LoadgameState *ls, int num)
01347 {
01348   Engine *e = GetEngine(num);
01349   e->name = CopyFromOldName(RemapOldStringID(ReadUint16(ls)));
01350   return true;
01351 }
01352 
01353 static const OldChunks subsidy_chunk[] = {
01354   OCL_SVAR(  OC_UINT8, Subsidy, cargo_type ),
01355   OCL_SVAR(  OC_UINT8, Subsidy, age ),
01356   OCL_SVAR(  OC_FILE_U8 | OC_VAR_U16, Subsidy, from ),
01357   OCL_SVAR(  OC_FILE_U8 | OC_VAR_U16, Subsidy, to ),
01358 
01359   OCL_END()
01360 };
01361 
01362 static inline bool LoadOldSubsidy(LoadgameState *ls, int num)
01363 {
01364   return LoadChunk(ls, &_subsidies[num], subsidy_chunk);
01365 }
01366 
01367 static const OldChunks game_difficulty_chunk[] = {
01368   OCL_SVAR( OC_UINT16, GameDifficulty, max_no_competitors ),
01369   OCL_SVAR( OC_UINT16, GameDifficulty, competitor_start_time ),
01370   OCL_SVAR( OC_UINT16, GameDifficulty, number_towns ),
01371   OCL_SVAR( OC_UINT16, GameDifficulty, number_industries ),
01372   OCL_SVAR( OC_UINT16, GameDifficulty, max_loan ),
01373   OCL_SVAR( OC_UINT16, GameDifficulty, initial_interest ),
01374   OCL_SVAR( OC_UINT16, GameDifficulty, vehicle_costs ),
01375   OCL_SVAR( OC_UINT16, GameDifficulty, competitor_speed ),
01376   OCL_SVAR( OC_UINT16, GameDifficulty, competitor_intelligence ),
01377   OCL_SVAR( OC_UINT16, GameDifficulty, vehicle_breakdowns ),
01378   OCL_SVAR( OC_UINT16, GameDifficulty, subsidy_multiplier ),
01379   OCL_SVAR( OC_UINT16, GameDifficulty, construction_cost ),
01380   OCL_SVAR( OC_UINT16, GameDifficulty, terrain_type ),
01381   OCL_SVAR( OC_UINT16, GameDifficulty, quantity_sea_lakes ),
01382   OCL_SVAR( OC_UINT16, GameDifficulty, economy ),
01383   OCL_SVAR( OC_UINT16, GameDifficulty, line_reverse_mode ),
01384   OCL_SVAR( OC_UINT16, GameDifficulty, disasters ),
01385   OCL_END()
01386 };
01387 
01388 static inline bool LoadOldGameDifficulty(LoadgameState *ls, int num)
01389 {
01390   return LoadChunk(ls, &_opt.diff, game_difficulty_chunk);
01391 }
01392 
01393 
01394 static bool LoadOldMapPart1(LoadgameState *ls, int num)
01395 {
01396   uint i;
01397 
01398   for (i = 0; i < OLD_MAP_SIZE; i++) {
01399     _m[i].m1 = ReadByte(ls);
01400   }
01401   for (i = 0; i < OLD_MAP_SIZE; i++) {
01402     _m[i].m2 = ReadByte(ls);
01403   }
01404   for (i = 0; i < OLD_MAP_SIZE; i++) {
01405     _old_map3[i * 2] = ReadByte(ls);
01406     _old_map3[i * 2 + 1] = ReadByte(ls);
01407   }
01408   for (i = 0; i < OLD_MAP_SIZE / 4; i++) {
01409     byte b = ReadByte(ls);
01410     _m[i * 4 + 0].m6 = GB(b, 0, 2);
01411     _m[i * 4 + 1].m6 = GB(b, 2, 2);
01412     _m[i * 4 + 2].m6 = GB(b, 4, 2);
01413     _m[i * 4 + 3].m6 = GB(b, 6, 2);
01414   }
01415 
01416   return !ls->failed;
01417 }
01418 
01419 static bool LoadOldMapPart2(LoadgameState *ls, int num)
01420 {
01421   uint i;
01422 
01423   for (i = 0; i < OLD_MAP_SIZE; i++) {
01424     _m[i].type_height = ReadByte(ls);
01425   }
01426   for (i = 0; i < OLD_MAP_SIZE; i++) {
01427     _m[i].m5 = ReadByte(ls);
01428   }
01429 
01430   return !ls->failed;
01431 }
01432 
01433 static bool LoadTTDPatchExtraChunks(LoadgameState *ls, int num)
01434 {
01435   ReadTTDPatchFlags();
01436 
01437   DEBUG(oldloader, 2, "Found %d extra chunk(s)", _old_extra_chunk_nums);
01438 
01439   for (int i = 0; i != _old_extra_chunk_nums; i++) {
01440     uint16 id = ReadUint16(ls);
01441     uint32 len = ReadUint32(ls);
01442 
01443     switch (id) {
01444       /* List of GRFIDs, used in the savegame. 0x8004 is the new ID
01445        * They are saved in a 'GRFID:4 active:1' format, 5 bytes for each entry */
01446       case 0x2:
01447       case 0x8004: {
01448         /* Skip the first element: TTDP hack for the Action D special variables (FFFF0000 01) */
01449         ReadUint32(ls); ReadByte(ls); len -= 5;
01450 
01451         ClearGRFConfigList(&_grfconfig);
01452         while (len != 0) {
01453           uint32 grfid = ReadUint32(ls);
01454 
01455           if (ReadByte(ls) == 1) {
01456             GRFConfig *c = CallocT<GRFConfig>(1);
01457             c->grfid = grfid;
01458             c->filename = strdup("TTDP game, no information");
01459 
01460             AppendToGRFConfigList(&_grfconfig, c);
01461             DEBUG(oldloader, 3, "TTDPatch game using GRF file with GRFID %0X", BSWAP32(c->grfid));
01462           }
01463           len -= 5;
01464         };
01465 
01466         /* Append static NewGRF configuration */
01467         AppendStaticGRFConfigs(&_grfconfig);
01468       } break;
01469 
01470       /* TTDPatch version and configuration */
01471       case 0x3: {
01472         uint32 ttdpv = ReadUint32(ls);
01473         DEBUG(oldloader, 3, "Game saved with TTDPatch version %d.%d.%d r%d", GB(ttdpv, 24, 8), GB(ttdpv, 20, 4), GB(ttdpv, 16, 4), GB(ttdpv, 0, 16));
01474         len -= 4;
01475         while (len-- != 0) ReadByte(ls); // skip the configuration
01476       } break;
01477 
01478       default:
01479         DEBUG(oldloader, 4, "Skipping unknown extra chunk %X", id);
01480         while (len-- != 0) ReadByte(ls);
01481         break;
01482     }
01483   }
01484 
01485   return !ls->failed;
01486 }
01487 
01488 static uint32 _old_cur_town_ctr;
01489 static const OldChunks main_chunk[] = {
01490   OCL_ASSERT( 0 ),
01491   OCL_VAR ( OC_FILE_U16 | OC_VAR_U32, 1, &_date ),
01492   OCL_VAR ( OC_UINT16,   1, &_date_fract ),
01493   OCL_NULL( 600 ),            
01494   OCL_VAR ( OC_UINT32,   2, &_random.state ),
01495 
01496   OCL_ASSERT( 0x264 ),
01497   OCL_CHUNK(  70, LoadOldTown ),
01498   OCL_ASSERT( 0x1C18 ),
01499   OCL_CHUNK(5000, LoadOldOrder ),
01500   OCL_ASSERT( 0x4328 ),
01501 
01502   OCL_CHUNK( 1, LoadOldAnimTileList ),
01503   OCL_NULL( 4 ),              
01504 
01505   OCL_CHUNK( 255, LoadOldDepot ),
01506   OCL_ASSERT( 0x4B26 ),
01507 
01508   OCL_VAR ( OC_UINT32,   1, &_old_cur_town_ctr ),
01509   OCL_NULL( 2 ),              
01510   OCL_NULL( 2 ),              
01511 
01512   OCL_VAR ( OC_FILE_U16 | OC_VAR_U8, 1, &_age_cargo_skip_counter ),
01513   OCL_VAR ( OC_UINT16,   1, &_tick_counter ),
01514   OCL_VAR (   OC_TILE,   1, &_cur_tileloop_tile ),
01515 
01516   OCL_CHUNK( 49, LoadOldPrice ),
01517   OCL_CHUNK( 12, LoadOldCargoPaymentRate ),
01518 
01519   OCL_ASSERT( 0x4CBA ),
01520 
01521   OCL_CHUNK( 1, LoadOldMapPart1 ),
01522 
01523   OCL_ASSERT( 0x48CBA ),
01524 
01525   OCL_CHUNK(250, LoadOldStation ),
01526   OCL_CHUNK( 90, LoadOldIndustry ),
01527   OCL_CHUNK(  8, LoadOldPlayer ),
01528 
01529   OCL_ASSERT( 0x547F2 ),
01530 
01531   OCL_CHUNK( 850, LoadOldVehicle ),
01532 
01533   OCL_ASSERT( 0x6F0F2 ),
01534 
01535   OCL_VAR (  OC_UINT8, 32 * 500, &_name_array[0] ),
01536 
01537   OCL_NULL( 0x2000 ),            
01538 
01539   OCL_CHUNK( 40, LoadOldSign ),
01540   OCL_CHUNK(256, LoadOldEngine ),
01541 
01542   OCL_VAR ( OC_UINT16,    1, &_vehicle_id_ctr_day ),
01543 
01544   OCL_CHUNK(  8, LoadOldSubsidy ),
01545 
01546   OCL_VAR ( OC_FILE_U16 | OC_VAR_U32,   1, &_next_competitor_start ),
01547   OCL_VAR ( OC_FILE_I16 | OC_VAR_I32,   1, &_saved_scrollpos_x ),
01548   OCL_VAR ( OC_FILE_I16 | OC_VAR_I32,   1, &_saved_scrollpos_y ),
01549   OCL_VAR ( OC_FILE_U16 | OC_VAR_U8,    1, &_saved_scrollpos_zoom ),
01550 
01551   OCL_VAR ( OC_FILE_U32 | OC_VAR_I64,   1, &_economy.max_loan ),
01552   OCL_VAR ( OC_FILE_U32 | OC_VAR_I64,   1, &_economy.max_loan_unround ),
01553   OCL_VAR (  OC_INT16,    1, &_economy.fluct ),
01554 
01555   OCL_VAR ( OC_UINT16,    1, &_disaster_delay ),
01556 
01557   OCL_NULL( 144 ),             
01558 
01559   OCL_CHUNK(256, LoadOldEngineName ),
01560 
01561   OCL_NULL( 144 ),             
01562   OCL_NULL( 2 ),               
01563 
01564   OCL_VAR ( OC_FILE_U8 | OC_VAR_U16,    1, &_station_tick_ctr ),
01565 
01566   OCL_VAR (  OC_UINT8,    1, &_opt.currency ),
01567   OCL_VAR (  OC_UINT8,    1, &_opt.units ),
01568   OCL_VAR ( OC_FILE_U8 | OC_VAR_U32,    1, &_cur_player_tick_index ),
01569 
01570   OCL_NULL( 2 ),               
01571   OCL_NULL( 8 ),               
01572 
01573   OCL_VAR (  OC_UINT8,    1, &_economy.infl_amount ),
01574   OCL_VAR (  OC_UINT8,    1, &_economy.infl_amount_pr ),
01575   OCL_VAR (  OC_UINT8,    1, &_economy.interest_rate ),
01576   OCL_NULL( 1 ), // available airports
01577   OCL_VAR (  OC_UINT8,    1, &_opt.road_side ),
01578   OCL_VAR (  OC_UINT8,    1, &_opt.town_name ),
01579 
01580   OCL_CHUNK( 1, LoadOldGameDifficulty ),
01581 
01582   OCL_ASSERT( 0x77130 ),
01583 
01584   OCL_VAR (  OC_UINT8,    1, &_opt.diff_level ),
01585   OCL_VAR (  OC_UINT8,    1, &_opt.landscape ),
01586   OCL_VAR (  OC_UINT8,    1, &_trees_tick_ctr ),
01587 
01588   OCL_NULL( 1 ),               
01589   OCL_VAR (  OC_UINT8,    1, &_opt.snow_line ),
01590 
01591   OCL_NULL( 32 ),              
01592   OCL_NULL( 36 ),              
01593 
01594   OCL_ASSERT( 0x77179 ),
01595 
01596   OCL_CHUNK( 1, LoadOldMapPart2 ),
01597 
01598   OCL_ASSERT( 0x97179 ),
01599 
01600   /* Below any (if available) extra chunks from TTDPatch can follow */
01601   OCL_CHUNK(1, LoadTTDPatchExtraChunks),
01602 
01603   OCL_END()
01604 };
01605 
01606 static bool LoadOldMain(LoadgameState *ls)
01607 {
01608   int i;
01609 
01610   /* The first 49 is the name of the game + checksum, skip it */
01611   fseek(ls->file, HEADER_SIZE, SEEK_SET);
01612 
01613   DEBUG(oldloader, 3, "Reading main chunk...");
01614   /* Load the biggest chunk */
01615   _old_vehicle_names = NULL;
01616   if (!LoadChunk(ls, NULL, main_chunk)) {
01617     DEBUG(oldloader, 0, "Loading failed");
01618     free(_old_vehicle_names);
01619     return false;
01620   }
01621   DEBUG(oldloader, 3, "Done, converting game data...");
01622 
01623   /* Fix some general stuff */
01624   _opt.landscape = _opt.landscape & 0xF;
01625 
01626   /* Remap some pointers */
01627   _cur_town_ctr      = REMAP_TOWN_IDX(_old_cur_town_ctr);
01628 
01629   /* _old_map3 is changed in _map3_lo and _map3_hi */
01630   for (i = 0; i < OLD_MAP_SIZE; i++) {
01631     _m[i].m3 = _old_map3[i * 2];
01632     _m[i].m4 = _old_map3[i * 2 + 1];
01633   }
01634 
01635   for (i = 0; i < OLD_MAP_SIZE; i ++) {
01636     switch (GetTileType(i)) {
01637       case MP_STATION:
01638         _m[i].m4 = 0; // We do not understand this TTDP station mapping (yet)
01639         switch (_m[i].m5) {
01640           /* We have drive through stops at a totally different place */
01641           case 0x53: case 0x54: _m[i].m5 += 170 - 0x53; break; // Bus drive through
01642           case 0x57: case 0x58: _m[i].m5 += 168 - 0x57; break; // Truck drive through
01643           case 0x55: case 0x56: _m[i].m5 += 170 - 0x55; break; // Bus tram stop
01644           case 0x59: case 0x5A: _m[i].m5 += 168 - 0x59; break; // Truck tram stop
01645           default: break;
01646         }
01647         break;
01648 
01649       case MP_RAILWAY:
01650         /* We save presignals different from TTDPatch, convert them */
01651         if (GetRailTileType(i) == RAIL_TILE_SIGNALS) {
01652           /* This byte is always zero in TTD for this type of tile */
01653           if (_m[i].m4) /* Convert the presignals to our own format */
01654             _m[i].m4 = (_m[i].m4 >> 1) & 7;
01655         }
01656         /* TTDPatch stores PBS things in L6 and all elsewhere; so we'll just
01657          * clear it for ourselves and let OTTD's rebuild PBS itself */
01658         _m[i].m4 &= 0xF; /* Only keep the lower four bits; upper four is PBS */
01659         break;
01660 
01661       case MP_WATER:
01662         if (GetWaterClass(i) == 3) MakeRiver(i, Random());
01663         break;
01664 
01665       default:
01666         break;
01667     }
01668   }
01669 
01670   /* Make sure the available engines are really available, otherwise
01671    * we will get a "new vehicle"-spree. */
01672   Engine *e;
01673   FOR_ALL_ENGINES(e) {
01674     if (_date >= (e->intro_date + 365)) {
01675       e->flags = (e->flags & ~ENGINE_EXCLUSIVE_PREVIEW) | ENGINE_AVAILABLE;
01676       e->player_avail = (byte)-1;
01677     }
01678   }
01679 
01680   /* Fix the game to be compatible with OpenTTD */
01681   FixOldTowns();
01682   FixOldStations();
01683   FixOldVehicles();
01684 
01685   /* We have a new difficulty setting */
01686   _opt.diff.town_council_tolerance = Clamp(_opt.diff_level, 0, 2);
01687 
01688   DEBUG(oldloader, 3, "Finished converting game data");
01689   DEBUG(oldloader, 1, "TTD(Patch) savegame successfully converted");
01690 
01691   free(_old_vehicle_names);
01692 
01693   return true;
01694 }
01695 
01696 bool LoadOldSaveGame(const char *file)
01697 {
01698   LoadgameState ls;
01699 
01700   DEBUG(oldloader, 3, "Trying to load a TTD(Patch) savegame");
01701 
01702   InitLoading(&ls);
01703 
01704   /* Open file */
01705   ls.file = fopen(file, "rb");
01706 
01707   if (ls.file == NULL) {
01708     DEBUG(oldloader, 0, "Cannot open file '%s'", file);
01709     return false;
01710   }
01711 
01712   /* Load the main chunk */
01713   if (!LoadOldMain(&ls)) return false;
01714 
01715   fclose(ls.file);
01716 
01717   /* Some old TTDP savegames could have buoys at tile 0
01718    * (without assigned station struct)
01719    * MakeWater() can be used as long as sea has the same
01720    * format as old savegames (eg. everything is zeroed) */
01721   MakeWater(0);
01722 
01723   _pause_game = 2;
01724 
01725   return true;
01726 }
01727 
01728 void GetOldSaveGameName(char *title, const char *path, const char *file)
01729 {
01730   char filename[MAX_PATH];
01731   FILE *f;
01732 
01733   snprintf(filename, lengthof(filename), "%s" PATHSEP "%s", path, file);
01734   f = fopen(filename, "rb");
01735   title[0] = '\0';
01736   title[48] = '\0';
01737 
01738   if (f == NULL) return;
01739 
01740   if (fread(title, 1, 48, f) != 48) snprintf(title, 48, "Corrupt file");
01741 
01742   fclose(f);
01743 }

Generated on Wed Oct 1 17:03:22 2008 for openttd by  doxygen 1.5.6