# misc.cpp

Go to the documentation of this file.

    00001 /* $Id: misc.cpp 12004 2008-01-29 00:27:25Z rubidium $ */
    00002
    00005 #include "stdafx.h"
    00006 #include "openttd.h"
    00007 #include "currency.h"
    00008 #include "landscape.h"
    00009 #include "news.h"
    00010 #include "saveload.h"
    00011 #include "engine.h"
    00012 #include "vehicle_gui.h"
    00013 #include "variables.h"
    00014 #include "ai/ai.h"
    00015 #include "newgrf_house.h"
    00016 #include "cargotype.h"
    00017 #include "group.h"
    00018 #include "viewport_func.h"
    00019 #include "economy_func.h"
    00020 #include "zoom_func.h"
    00021 #include "functions.h"
    00022 #include "map_func.h"
    00023 #include "date_func.h"
    00024 #include "vehicle_func.h"
    00025 #include "texteff.hpp"
    00026 #include "string_func.h"
    00027 #include "gfx_func.h"
    00028 #include "core/alloc_func.hpp"
    00029
    00030 #include "table/strings.h"
    00031 #include "table/sprites.h"
    00032
    00033 char _name_array[512][32];
    00034
    00035 void InitializeVehicles();
    00036 void InitializeWaypoints();
    00037 void InitializeDepots();
    00038 void InitializeEngines();
    00039 void InitializeOrders();
    00040 void InitializeClearLand();
    00041 void InitializeRailGui();
    00042 void InitializeRoadGui();
    00043 void InitializeAirportGui();
    00044 void InitializeDockGui();
    00045 void InitializeIndustries();
    00046 void InitializeMainGui();
    00047 void InitializeTowns();
    00048 void InitializeTrees();
    00049 void InitializeSigns();
    00050 void InitializeStations();
    00051 void InitializeCargoPackets();
    00052 static void InitializeNameMgr();
    00053 void InitializePlayers();
    00054 static void InitializeCheats();
    00055 void InitializeNPF();
    00056
    00057 void InitializeGame(int mode, uint size_x, uint size_y)
    00058 {
    00059   AllocateMap(size_x, size_y);
    00060
    00061   SetObjectToPlace(SPR_CURSOR_ZZZ, PAL_NONE, VHM_NONE, WC_MAIN_WINDOW, 0);
    00062
    00063   _pause_game = 0;
    00064   _fast_forward = 0;
    00065   _tick_counter = 0;
    00066   _realtime_tick = 0;
    00067   _date_fract = 0;
    00068   _cur_tileloop_tile = 0;
    00069
    00070   if ((mode & IG_DATE_RESET) == IG_DATE_RESET) {
    00071     SetDate(ConvertYMDToDate(_patches.starting_year, 0, 1));
    00072   }
    00073
    00074   InitializeEngines();
    00075   InitializeVehicles();
    00076   InitializeWaypoints();
    00077   InitializeDepots();
    00078   InitializeOrders();
    00079   InitializeGroup();
    00080
    00081   InitNewsItemStructs();
    00082   InitializeLandscape();
    00083   InitializeClearLand();
    00084   InitializeRailGui();
    00085   InitializeRoadGui();
    00086   InitializeAirportGui();
    00087   InitializeDockGui();
    00088   InitializeTowns();
    00089   InitializeTrees();
    00090   InitializeSigns();
    00091   InitializeStations();
    00092   InitializeCargoPackets();
    00093   InitializeIndustries();
    00094   InitializeBuildingCounts();
    00095   InitializeMainGui();
    00096
    00097   InitializeNameMgr();
    00098   InitializeVehiclesGuiList();
    00099   InitializeTrains();
    00100   InitializeNPF();
    00101
    00102   AI_Initialize();
    00103   InitializePlayers();
    00104   InitializeCheats();
    00105
    00106   InitTextEffects();
    00107   InitChatMessage();
    00108   InitializeAnimatedTiles();
    00109
    00110   InitializeLandscapeVariables(false);
    00111
    00112   ResetObjectToPlace();
    00113 }
    00114
    00115 bool IsCustomName(StringID id)
    00116 {
    00117   return GB(id, 11, 5) == 15;
    00118 }
    00119
    00120
    00121 static void InitializeCheats()
    00122 {
    00123   memset(&_cheats, 0, sizeof(Cheats));
    00124 }
    00125
    00126
    00127 static void InitializeNameMgr()
    00128 {
    00129   memset(_name_array, 0, sizeof(_name_array));
    00130 }
    00131
    00132 /* Copy and convert old custom names to UTF-8 */
    00133 char *CopyFromOldName(StringID id)
    00134 {
    00135   if (!IsCustomName(id)) return NULL;
    00136
    00137   if (CheckSavegameVersion(37)) {
    00138     /* Old names were 32 characters long, so 128 characters should be
    00139      * plenty to allow for expansion when converted to UTF-8. */
    00140     char tmp[128];
    00141     const char *strfrom = _name_array[GB(id, 0, 9)];
    00142     char *strto = tmp;
    00143
    00144     for (; *strfrom != '\0'; strfrom++) {
    00145       WChar c = (byte)*strfrom;
    00146
    00147       /* Map from non-ISO8859-15 characters to UTF-8. */
    00148       switch (c) {
    00149         case 0xA4: c = 0x20AC; break; // Euro
    00150         case 0xA6: c = 0x0160; break; // S with caron
    00151         case 0xA8: c = 0x0161; break; // s with caron
    00152         case 0xB4: c = 0x017D; break; // Z with caron
    00153         case 0xB8: c = 0x017E; break; // z with caron
    00154         case 0xBC: c = 0x0152; break; // OE ligature
    00155         case 0xBD: c = 0x0153; break; // oe ligature
    00156         case 0xBE: c = 0x0178; break; // Y with diaresis
    00157         default: break;
    00158       }
    00159
    00160       /* Check character will fit into our buffer. */
    00161       if (strto + Utf8CharLen(c) > lastof(tmp)) break;
    00162
    00163       strto += Utf8Encode(strto, c);
    00164     }
    00165
    00166     /* Terminate the new string and copy it back to the name array */
    00167     *strto = '\0';
    00168
    00169     return strdup(tmp);
    00170   } else {
    00171     /* Name will already be in UTF-8. */
    00172     return strdup(_name_array[GB(id, 0, 9)]);
    00173   }
    00174 }
    00175
    00176 /* Calculate constants that depend on the landscape type. */
    00177 void InitializeLandscapeVariables(bool only_constants)
    00178 {
    00179   if (only_constants) return;
    00180
    00181   for (CargoID i = 0; i < NUM_CARGO; i++) {
    00182     _cargo_payment_rates[i] = GetCargo(i)->initial_payment;
    00183     _cargo_payment_rates_frac[i] = 0;
    00184   }
    00185 }
    00186
    00187 static void Load_NAME()
    00188 {
    00189   int index;
    00190
    00191   while ((index = SlIterateArray()) != -1) {
    00192     SlArray(_name_array[index], SlGetFieldLength(), SLE_UINT8);
    00193   }
    00194 }
    00195
    00196 static const SaveLoadGlobVarList _date_desc[] = {
    00197   SLEG_CONDVAR(_date,                   SLE_FILE_U16 | SLE_VAR_I32,  0,  30),
    00198   SLEG_CONDVAR(_date,                   SLE_INT32,                  31, SL_MAX_VERSION),
    00199       SLEG_VAR(_date_fract,             SLE_UINT16),
    00200       SLEG_VAR(_tick_counter,           SLE_UINT16),
    00201       SLEG_VAR(_vehicle_id_ctr_day,     SLE_UINT16),
    00202       SLEG_VAR(_age_cargo_skip_counter, SLE_UINT8),
    00203   SLE_CONDNULL(1, 0, 45),
    00204   SLEG_CONDVAR(_cur_tileloop_tile,      SLE_FILE_U16 | SLE_VAR_U32,  0, 5),
    00205   SLEG_CONDVAR(_cur_tileloop_tile,      SLE_UINT32,                  6, SL_MAX_VERSION),
    00206       SLEG_VAR(_disaster_delay,         SLE_UINT16),
    00207       SLEG_VAR(_station_tick_ctr,       SLE_UINT16),
    00208       SLEG_VAR(_random.state[0],        SLE_UINT32),
    00209       SLEG_VAR(_random.state[1],        SLE_UINT32),
    00210   SLEG_CONDVAR(_cur_town_ctr,           SLE_FILE_U8  | SLE_VAR_U32,  0, 9),
    00211   SLEG_CONDVAR(_cur_town_ctr,           SLE_UINT32,                 10, SL_MAX_VERSION),
    00212       SLEG_VAR(_cur_player_tick_index,  SLE_FILE_U8  | SLE_VAR_U32),
    00213       SLEG_VAR(_next_competitor_start,  SLE_FILE_U16 | SLE_VAR_U32),
    00214       SLEG_VAR(_trees_tick_ctr,         SLE_UINT8),
    00215   SLEG_CONDVAR(_pause_game,             SLE_UINT8,                   4, SL_MAX_VERSION),
    00216   SLEG_CONDVAR(_cur_town_iter,          SLE_UINT32,                 11, SL_MAX_VERSION),
    00217       SLEG_END()
    00218 };
    00219
    00220 /* Save load date related variables as well as persistent tick counters
    00221  * XXX: currently some unrelated stuff is just put here */
    00222 static void SaveLoad_DATE()
    00223 {
    00224   SlGlobList(_date_desc);
    00225 }
    00226
    00227
    00228 static const SaveLoadGlobVarList _view_desc[] = {
    00229   SLEG_CONDVAR(_saved_scrollpos_x,    SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
    00230   SLEG_CONDVAR(_saved_scrollpos_x,    SLE_INT32,                  6, SL_MAX_VERSION),
    00231   SLEG_CONDVAR(_saved_scrollpos_y,    SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
    00232   SLEG_CONDVAR(_saved_scrollpos_y,    SLE_INT32,                  6, SL_MAX_VERSION),
    00233       SLEG_VAR(_saved_scrollpos_zoom, SLE_UINT8),
    00234       SLEG_END()
    00235 };
    00236
    00237 static void SaveLoad_VIEW()
    00238 {
    00239   SlGlobList(_view_desc);
    00240 }
    00241
    00242 static uint32 _map_dim_x;
    00243 static uint32 _map_dim_y;
    00244
    00245 static const SaveLoadGlobVarList _map_dimensions[] = {
    00246   SLEG_CONDVAR(_map_dim_x, SLE_UINT32, 6, SL_MAX_VERSION),
    00247   SLEG_CONDVAR(_map_dim_y, SLE_UINT32, 6, SL_MAX_VERSION),
    00248       SLEG_END()
    00249 };
    00250
    00251 static void Save_MAPS()
    00252 {
    00253   _map_dim_x = MapSizeX();
    00254   _map_dim_y = MapSizeY();
    00255   SlGlobList(_map_dimensions);
    00256 }
    00257
    00258 static void Load_MAPS()
    00259 {
    00260   SlGlobList(_map_dimensions);
    00261   AllocateMap(_map_dim_x, _map_dim_y);
    00262 }
    00263
    00264 enum {
    00265   MAP_SL_BUF_SIZE = 4096
    00266 };
    00267
    00268 static void Load_MAPT()
    00269 {
    00270   SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
    00271   TileIndex size = MapSize();
    00272
    00273   for (TileIndex i = 0; i != size;) {
    00274     SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
    00275     for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].type_height = buf[j];
    00276   }
    00277 }
    00278
    00279 static void Save_MAPT()
    00280 {
    00281   SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
    00282   TileIndex size = MapSize();
    00283
    00284   SlSetLength(size);
    00285   for (TileIndex i = 0; i != size;) {
    00286     for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].type_height;
    00287     SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
    00288   }
    00289 }
    00290
    00291 static void Load_MAP1()
    00292 {
    00293   SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
    00294   TileIndex size = MapSize();
    00295
    00296   for (TileIndex i = 0; i != size;) {
    00297     SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
    00298     for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m1 = buf[j];
    00299   }
    00300 }
    00301
    00302 static void Save_MAP1()
    00303 {
    00304   SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
    00305   TileIndex size = MapSize();
    00306
    00307   SlSetLength(size);
    00308   for (TileIndex i = 0; i != size;) {
    00309     for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m1;
    00310     SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
    00311   }
    00312 }
    00313
    00314 static void Load_MAP2()
    00315 {
    00316   SmallStackSafeStackAlloc<uint16, MAP_SL_BUF_SIZE> buf;
    00317   TileIndex size = MapSize();
    00318
    00319   for (TileIndex i = 0; i != size;) {
    00320     SlArray(buf, MAP_SL_BUF_SIZE,
    00321       /* In those versions the m2 was 8 bits */
    00322       CheckSavegameVersion(5) ? SLE_FILE_U8 | SLE_VAR_U16 : SLE_UINT16
    00323     );
    00324     for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m2 = buf[j];
    00325   }
    00326 }
    00327
    00328 static void Save_MAP2()
    00329 {
    00330   SmallStackSafeStackAlloc<uint16, MAP_SL_BUF_SIZE> buf;
    00331   TileIndex size = MapSize();
    00332
    00333   SlSetLength(size * sizeof(uint16));
    00334   for (TileIndex i = 0; i != size;) {
    00335     for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m2;
    00336     SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT16);
    00337   }
    00338 }
    00339
    00340 static void Load_MAP3()
    00341 {
    00342   SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
    00343   TileIndex size = MapSize();
    00344
    00345   for (TileIndex i = 0; i != size;) {
    00346     SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
    00347     for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m3 = buf[j];
    00348   }
    00349 }
    00350
    00351 static void Save_MAP3()
    00352 {
    00353   SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
    00354   TileIndex size = MapSize();
    00355
    00356   SlSetLength(size);
    00357   for (TileIndex i = 0; i != size;) {
    00358     for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m3;
    00359     SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
    00360   }
    00361 }
    00362
    00363 static void Load_MAP4()
    00364 {
    00365   SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
    00366   TileIndex size = MapSize();
    00367
    00368   for (TileIndex i = 0; i != size;) {
    00369     SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
    00370     for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m4 = buf[j];
    00371   }
    00372 }
    00373
    00374 static void Save_MAP4()
    00375 {
    00376   SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
    00377   TileIndex size = MapSize();
    00378
    00379   SlSetLength(size);
    00380   for (TileIndex i = 0; i != size;) {
    00381     for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m4;
    00382     SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
    00383   }
    00384 }
    00385
    00386 static void Load_MAP5()
    00387 {
    00388   SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
    00389   TileIndex size = MapSize();
    00390
    00391   for (TileIndex i = 0; i != size;) {
    00392     SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
    00393     for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m5 = buf[j];
    00394   }
    00395 }
    00396
    00397 static void Save_MAP5()
    00398 {
    00399   SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
    00400   TileIndex size = MapSize();
    00401
    00402   SlSetLength(size);
    00403   for (TileIndex i = 0; i != size;) {
    00404     for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m5;
    00405     SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
    00406   }
    00407 }
    00408
    00409 static void Load_MAP6()
    00410 {
    00411   SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
    00412   TileIndex size = MapSize();
    00413
    00414   if (CheckSavegameVersion(42)) {
    00415     for (TileIndex i = 0; i != size;) {
    00416       /* 1024, otherwise we overflow on 64x64 maps! */
    00417       SlArray(buf, 1024, SLE_UINT8);
    00418       for (uint j = 0; j != 1024; j++) {
    00419         _m[i++].m6 = GB(buf[j], 0, 2);
    00420         _m[i++].m6 = GB(buf[j], 2, 2);
    00421         _m[i++].m6 = GB(buf[j], 4, 2);
    00422         _m[i++].m6 = GB(buf[j], 6, 2);
    00423       }
    00424     }
    00425   } else {
    00426     for (TileIndex i = 0; i != size;) {
    00427       SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
    00428       for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m6 = buf[j];
    00429     }
    00430   }
    00431 }
    00432
    00433 static void Save_MAP6()
    00434 {
    00435   SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
    00436   TileIndex size = MapSize();
    00437
    00438   SlSetLength(size);
    00439   for (TileIndex i = 0; i != size;) {
    00440     for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m6;
    00441     SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
    00442   }
    00443 }
    00444
    00445 static void Load_MAP7()
    00446 {
    00447   SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
    00448   TileIndex size = MapSize();
    00449
    00450   for (TileIndex i = 0; i != size;) {
    00451     SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
    00452     for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _me[i++].m7 = buf[j];
    00453   }
    00454 }
    00455
    00456 static void Save_MAP7()
    00457 {
    00458   SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
    00459   TileIndex size = MapSize();
    00460
    00461   SlSetLength(size);
    00462   for (TileIndex i = 0; i != size;) {
    00463     for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _me[i++].m7;
    00464     SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
    00465   }
    00466 }
    00467
    00468 static void Save_CHTS()
    00469 {
    00470   byte count = sizeof(_cheats)/sizeof(Cheat);
    00471   Cheat* cht = (Cheat*) &_cheats;
    00472   Cheat* cht_last = &cht[count];
    00473
    00474   SlSetLength(count * 2);
    00475   for (; cht != cht_last; cht++) {
    00476     SlWriteByte(cht->been_used);
    00477     SlWriteByte(cht->value);
    00478   }
    00479 }
    00480
    00481 static void Load_CHTS()
    00482 {
    00483   Cheat* cht = (Cheat*)&_cheats;
    00484   uint count = SlGetFieldLength() / 2;
    00485   uint i;
    00486
    00487   for (i = 0; i < count; i++) {
    00488     cht[i].been_used = (SlReadByte() != 0);
    00489     cht[i].value     = (SlReadByte() != 0);
    00490   }
    00491 }
    00492
    00493
    00494 extern const ChunkHandler _misc_chunk_handlers[] = {
    00495   { 'MAPS', Save_MAPS,     Load_MAPS,     CH_RIFF },
    00496   { 'MAPT', Save_MAPT,     Load_MAPT,     CH_RIFF },
    00497   { 'MAPO', Save_MAP1,     Load_MAP1,     CH_RIFF },
    00498   { 'MAP2', Save_MAP2,     Load_MAP2,     CH_RIFF },
    00499   { 'M3LO', Save_MAP3,     Load_MAP3,     CH_RIFF },
    00500   { 'M3HI', Save_MAP4,     Load_MAP4,     CH_RIFF },
    00501   { 'MAP5', Save_MAP5,     Load_MAP5,     CH_RIFF },
    00502   { 'MAPE', Save_MAP6,     Load_MAP6,     CH_RIFF },
    00503   { 'MAP7', Save_MAP7,     Load_MAP7,     CH_RIFF },
    00504
    00505   { 'NAME', NULL,          Load_NAME,     CH_ARRAY},
    00506   { 'DATE', SaveLoad_DATE, SaveLoad_DATE, CH_RIFF},
    00507   { 'VIEW', SaveLoad_VIEW, SaveLoad_VIEW, CH_RIFF},
    00508   { 'CHTS', Save_CHTS,     Load_CHTS,     CH_RIFF | CH_LAST}
    00509 };