00001
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
00133 char *CopyFromOldName(StringID id)
00134 {
00135 if (!IsCustomName(id)) return NULL;
00136
00137 if (CheckSavegameVersion(37)) {
00138
00139
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
00148 switch (c) {
00149 case 0xA4: c = 0x20AC; break;
00150 case 0xA6: c = 0x0160; break;
00151 case 0xA8: c = 0x0161; break;
00152 case 0xB4: c = 0x017D; break;
00153 case 0xB8: c = 0x017E; break;
00154 case 0xBC: c = 0x0152; break;
00155 case 0xBD: c = 0x0153; break;
00156 case 0xBE: c = 0x0178; break;
00157 default: break;
00158 }
00159
00160
00161 if (strto + Utf8CharLen(c) > lastof(tmp)) break;
00162
00163 strto += Utf8Encode(strto, c);
00164 }
00165
00166
00167 *strto = '\0';
00168
00169 return strdup(tmp);
00170 } else {
00171
00172 return strdup(_name_array[GB(id, 0, 9)]);
00173 }
00174 }
00175
00176
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
00221
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
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
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 };