00001
00002
00005 #include "stdafx.h"
00006
00007 #define VARDEF
00008 #include "variables.h"
00009 #undef VARDEF
00010
00011 #include "openttd.h"
00012
00013 #include "blitter/factory.hpp"
00014 #include "sound/sound_driver.hpp"
00015 #include "music/music_driver.hpp"
00016 #include "video/video_driver.hpp"
00017
00018 #include "fontcache.h"
00019 #include "gfxinit.h"
00020 #include "gui.h"
00021 #include "mixer.h"
00022 #include "sound_func.h"
00023 #include "window_func.h"
00024
00025 #include "saveload/saveload.h"
00026 #include "landscape.h"
00027 #include "company_func.h"
00028 #include "command_func.h"
00029 #include "news_func.h"
00030 #include "fileio_func.h"
00031 #include "fios.h"
00032 #include "aircraft.h"
00033 #include "console_func.h"
00034 #include "screenshot.h"
00035 #include "network/network.h"
00036 #include "network/network_func.h"
00037 #include "signs_base.h"
00038 #include "ai/ai.hpp"
00039 #include "ai/ai_config.hpp"
00040 #include "settings_func.h"
00041 #include "genworld.h"
00042 #include "group.h"
00043 #include "strings_func.h"
00044 #include "date_func.h"
00045 #include "vehicle_func.h"
00046 #include "gamelog.h"
00047 #include "cheat_type.h"
00048 #include "animated_tile_func.h"
00049 #include "functions.h"
00050 #include "elrail_func.h"
00051 #include "rev.h"
00052 #include "highscore.h"
00053 #include "thread.h"
00054
00055 #include "newgrf_commons.h"
00056
00057 #include "town.h"
00058 #include "industry.h"
00059
00060 #include <stdarg.h>
00061
00062 #include "table/strings.h"
00063
00064 StringID _switch_mode_errorstr;
00065
00066 void CallLandscapeTick();
00067 void IncreaseDate();
00068 void DoPaletteAnimations();
00069 void MusicLoop();
00070 void ResetMusic();
00071 void ProcessAsyncSaveFinish();
00072 void CallWindowTickEvent();
00073
00074 extern void SetDifficultyLevel(int mode, DifficultySettings *gm_opt);
00075 extern Company *DoStartupNewCompany(bool is_ai);
00076 extern void ShowOSErrorBox(const char *buf, bool system);
00077 extern void InitializeRailGUI();
00078
00084 void CDECL usererror(const char *s, ...)
00085 {
00086 va_list va;
00087 char buf[512];
00088
00089 va_start(va, s);
00090 vsnprintf(buf, lengthof(buf), s, va);
00091 va_end(va);
00092
00093 ShowOSErrorBox(buf, false);
00094 if (_video_driver != NULL) _video_driver->Stop();
00095
00096 exit(1);
00097 }
00098
00104 void CDECL error(const char *s, ...)
00105 {
00106 va_list va;
00107 char buf[512];
00108
00109 va_start(va, s);
00110 vsnprintf(buf, lengthof(buf), s, va);
00111 va_end(va);
00112
00113 ShowOSErrorBox(buf, true);
00114 if (_video_driver != NULL) _video_driver->Stop();
00115
00116 assert(0);
00117 exit(1);
00118 }
00119
00124 void CDECL ShowInfoF(const char *str, ...)
00125 {
00126 va_list va;
00127 char buf[1024];
00128 va_start(va, str);
00129 vsnprintf(buf, lengthof(buf), str, va);
00130 va_end(va);
00131 ShowInfo(buf);
00132 }
00133
00137 static void ShowHelp()
00138 {
00139 char buf[8192];
00140 char *p = buf;
00141
00142 p += seprintf(p, lastof(buf), "OpenTTD %s\n", _openttd_revision);
00143 p = strecpy(p,
00144 "\n"
00145 "\n"
00146 "Command line options:\n"
00147 " -v drv = Set video driver (see below)\n"
00148 " -s drv = Set sound driver (see below) (param bufsize,hz)\n"
00149 " -m drv = Set music driver (see below)\n"
00150 " -b drv = Set the blitter to use (see below)\n"
00151 " -a ai = Force use of specific AI (see below)\n"
00152 " -r res = Set resolution (for instance 800x600)\n"
00153 " -h = Display this help text\n"
00154 " -t year = Set starting year\n"
00155 " -d [[fac=]lvl[,...]]= Debug mode\n"
00156 " -e = Start Editor\n"
00157 " -g [savegame] = Start new/save game immediately\n"
00158 " -G seed = Set random seed\n"
00159 #if defined(ENABLE_NETWORK)
00160 " -n [ip:port#company]= Start networkgame\n"
00161 " -D [ip][:port] = Start dedicated server\n"
00162 " -l ip[:port] = Redirect DEBUG()\n"
00163 #if !defined(__MORPHOS__) && !defined(__AMIGA__) && !defined(WIN32)
00164 " -f = Fork into the background (dedicated only)\n"
00165 #endif
00166 #endif
00167 " -i palette = Force to use the DOS (0) or Windows (1) palette\n"
00168 " (defines default setting when adding newgrfs)\n"
00169 " Default value (2) lets OpenTTD use the palette\n"
00170 " specified in graphics set file (see below)\n"
00171 " -I graphics_set = Force the graphics set (see below)\n"
00172 " -c config_file = Use 'config_file' instead of 'openttd.cfg'\n"
00173 " -x = Do not automatically save to config file on exit\n"
00174 "\n",
00175 lastof(buf)
00176 );
00177
00178
00179 p = GetGraphicsSetsList(p, lastof(buf));
00180
00181
00182 p = VideoDriverFactoryBase::GetDriversInfo(p, lastof(buf));
00183
00184
00185 p = BlitterFactoryBase::GetBlittersInfo(p, lastof(buf));
00186
00187
00188 AI::Initialize();
00189 p = AI::GetConsoleList(p, lastof(buf));
00190 AI::Uninitialize(true);
00191
00192
00193
00194 #if !defined(WIN32) && !defined(WIN64)
00195 printf("%s\n", buf);
00196 #else
00197 ShowInfo(buf);
00198 #endif
00199 }
00200
00201
00202 struct MyGetOptData {
00203 char *opt;
00204 int numleft;
00205 char **argv;
00206 const char *options;
00207 const char *cont;
00208
00209 MyGetOptData(int argc, char **argv, const char *options)
00210 {
00211 opt = NULL;
00212 numleft = argc;
00213 this->argv = argv;
00214 this->options = options;
00215 cont = NULL;
00216 }
00217 };
00218
00219 static int MyGetOpt(MyGetOptData *md)
00220 {
00221 const char *s, *r, *t;
00222
00223 s = md->cont;
00224 if (s != NULL)
00225 goto md_continue_here;
00226
00227 for (;;) {
00228 if (--md->numleft < 0) return -1;
00229
00230 s = *md->argv++;
00231 if (*s == '-') {
00232 md_continue_here:;
00233 s++;
00234 if (*s != 0) {
00235
00236 if (*s == ':' || (r = strchr(md->options, *s)) == NULL) {
00237
00238 return -2;
00239 }
00240 if (r[1] == ':') {
00241
00242 if (!*(t = s + 1)) {
00243
00244 if (--md->numleft < 0 || *(t = *md->argv) == '-') {
00245
00246 if (r[2] != ':')
00247 return -2;
00248 md->numleft++;
00249 t = NULL;
00250 } else {
00251 md->argv++;
00252 }
00253 }
00254 md->opt = (char*)t;
00255 md->cont = NULL;
00256 return *s;
00257 }
00258 md->opt = NULL;
00259 md->cont = s;
00260 return *s;
00261 }
00262 } else {
00263
00264 return -2;
00265 }
00266 }
00267 }
00268
00275 static void ParseResolution(Dimension *res, const char *s)
00276 {
00277 const char *t = strchr(s, 'x');
00278 if (t == NULL) {
00279 ShowInfoF("Invalid resolution '%s'", s);
00280 return;
00281 }
00282
00283 res->width = max(strtoul(s, NULL, 0), 64UL);
00284 res->height = max(strtoul(t + 1, NULL, 0), 64UL);
00285 }
00286
00287 static void InitializeDynamicVariables()
00288 {
00289
00290 _engine_mngr.ResetToDefaultMapping();
00291 _house_mngr.ResetMapping();
00292 _industry_mngr.ResetMapping();
00293 _industile_mngr.ResetMapping();
00294 _Company_pool.AddBlockToPool();
00295 }
00296
00297
00301 static void ShutdownGame()
00302 {
00303 IConsoleFree();
00304
00305 if (_network_available) NetworkShutDown();
00306
00307 DriverFactoryBase::ShutdownDrivers();
00308
00309 UnInitWindowSystem();
00310
00311
00312 AI::Uninitialize(false);
00313
00314
00315 UnInitializeAirports();
00316
00317
00318 GamelogReset();
00319 _Town_pool.CleanPool();
00320 _Industry_pool.CleanPool();
00321 _Station_pool.CleanPool();
00322 _Vehicle_pool.CleanPool();
00323 _Sign_pool.CleanPool();
00324 _Order_pool.CleanPool();
00325 _Group_pool.CleanPool();
00326 _CargoPacket_pool.CleanPool();
00327 _Engine_pool.CleanPool();
00328 _Company_pool.CleanPool();
00329
00330 free(_config_file);
00331
00332
00333 FioCloseAll();
00334 }
00335
00336 static void LoadIntroGame()
00337 {
00338 _game_mode = GM_MENU;
00339
00340 ResetGRFConfig(false);
00341
00342
00343 ResetWindowSystem();
00344 SetupColoursAndInitialWindow();
00345
00346
00347 if (SaveOrLoad("opntitle.dat", SL_LOAD, DATA_DIR) != SL_OK) {
00348 GenerateWorld(GW_EMPTY, 64, 64);
00349 WaitTillGeneratedWorld();
00350 SetLocalCompany(COMPANY_SPECTATOR);
00351 } else {
00352 SetLocalCompany(COMPANY_FIRST);
00353 }
00354
00355 _pause_game = 0;
00356 _cursor.fix_at = false;
00357
00358 CheckForMissingGlyphsInLoadedLanguagePack();
00359
00360
00361 if (_music_driver->IsSongPlaying()) ResetMusic();
00362 }
00363
00364 void MakeNewgameSettingsLive()
00365 {
00366 for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
00367 if (_settings_game.ai_config[c] != NULL) {
00368 delete _settings_game.ai_config[c];
00369 }
00370 }
00371
00372 _settings_game = _settings_newgame;
00373
00374 for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
00375 _settings_game.ai_config[c] = NULL;
00376 if (_settings_newgame.ai_config[c] != NULL) {
00377 _settings_game.ai_config[c] = new AIConfig(_settings_newgame.ai_config[c]);
00378 }
00379 }
00380 }
00381
00382 byte _savegame_sort_order;
00383 #if defined(UNIX) && !defined(__MORPHOS__)
00384 extern void DedicatedFork();
00385 #endif
00386
00387 int ttd_main(int argc, char *argv[])
00388 {
00389 int i;
00390 const char *optformat;
00391 char *musicdriver = NULL;
00392 char *sounddriver = NULL;
00393 char *videodriver = NULL;
00394 char *blitter = NULL;
00395 char *graphics_set = NULL;
00396 Dimension resolution = {0, 0};
00397 Year startyear = INVALID_YEAR;
00398 uint generation_seed = GENERATE_NEW_SEED;
00399 bool save_config = true;
00400 #if defined(ENABLE_NETWORK)
00401 bool dedicated = false;
00402 bool network = false;
00403 char *network_conn = NULL;
00404 char *debuglog_conn = NULL;
00405 char *dedicated_host = NULL;
00406 uint16 dedicated_port = 0;
00407 #endif
00408
00409 _game_mode = GM_MENU;
00410 _switch_mode = SM_MENU;
00411 _switch_mode_errorstr = INVALID_STRING_ID;
00412 _dedicated_forks = false;
00413 _config_file = NULL;
00414
00415
00416
00417
00418
00419 optformat = "m:s:v:b:hD::n::ei::I:t:d::r:g::G:c:xl:"
00420 #if !defined(__MORPHOS__) && !defined(__AMIGA__) && !defined(WIN32)
00421 "f"
00422 #endif
00423 ;
00424
00425 MyGetOptData mgo(argc - 1, argv + 1, optformat);
00426
00427 while ((i = MyGetOpt(&mgo)) != -1) {
00428 switch (i) {
00429 case 'I': free(graphics_set); graphics_set = strdup(mgo.opt); break;
00430 case 'm': free(musicdriver); musicdriver = strdup(mgo.opt); break;
00431 case 's': free(sounddriver); sounddriver = strdup(mgo.opt); break;
00432 case 'v': free(videodriver); videodriver = strdup(mgo.opt); break;
00433 case 'b': free(blitter); blitter = strdup(mgo.opt); break;
00434 #if defined(ENABLE_NETWORK)
00435 case 'D':
00436 free(musicdriver);
00437 free(sounddriver);
00438 free(videodriver);
00439 free(blitter);
00440 musicdriver = strdup("null");
00441 sounddriver = strdup("null");
00442 videodriver = strdup("dedicated");
00443 blitter = strdup("null");
00444 dedicated = true;
00445 SetDebugString("net=6");
00446 if (mgo.opt != NULL) {
00447
00448
00449 const char *temp = NULL;
00450 const char *port = NULL;
00451 ParseConnectionString(&temp, &port, mgo.opt);
00452 if (!StrEmpty(mgo.opt)) dedicated_host = mgo.opt;
00453 if (port != NULL) dedicated_port = atoi(port);
00454 }
00455 break;
00456 case 'f': _dedicated_forks = true; break;
00457 case 'n':
00458 network = true;
00459 network_conn = mgo.opt;
00460 break;
00461 case 'l':
00462 debuglog_conn = mgo.opt;
00463 break;
00464 #endif
00465 case 'r': ParseResolution(&resolution, mgo.opt); break;
00466 case 't': startyear = atoi(mgo.opt); break;
00467 case 'd': {
00468 #if defined(WIN32)
00469 CreateConsole();
00470 #endif
00471 if (mgo.opt != NULL) SetDebugString(mgo.opt);
00472 } break;
00473 case 'e': _switch_mode = SM_EDITOR; break;
00474 case 'i':
00475
00476 if (!StrEmpty(mgo.opt) && mgo.opt[1] == '\0') {
00477 _use_palette = (PaletteType)(mgo.opt[0] - '0');
00478 if (_use_palette <= MAX_PAL) break;
00479 }
00480 usererror("Valid value for '-i' is 0, 1 or 2");
00481 case 'g':
00482 if (mgo.opt != NULL) {
00483 strecpy(_file_to_saveload.name, mgo.opt, lastof(_file_to_saveload.name));
00484 _switch_mode = SM_LOAD;
00485 _file_to_saveload.mode = SL_LOAD;
00486
00487
00488 const char *t = strrchr(_file_to_saveload.name, '.');
00489 if (t != NULL) {
00490 FiosType ft = FiosGetSavegameListCallback(SLD_LOAD_GAME, _file_to_saveload.name, t, NULL, NULL);
00491 if (ft != FIOS_TYPE_INVALID) SetFiosType(ft);
00492 }
00493
00494 break;
00495 }
00496
00497 _switch_mode = SM_NEWGAME;
00498
00499 if (generation_seed == GENERATE_NEW_SEED) {
00500 generation_seed = InteractiveRandom();
00501 }
00502 break;
00503 case 'G': generation_seed = atoi(mgo.opt); break;
00504 case 'c': _config_file = strdup(mgo.opt); break;
00505 case 'x': save_config = false; break;
00506 case -2:
00507 case 'h':
00508
00509
00510
00511 DeterminePaths(argv[0]);
00512 FindGraphicsSets();
00513 ShowHelp();
00514 return 0;
00515 }
00516 }
00517
00518 #if defined(WINCE) && defined(_DEBUG)
00519
00520 SetDebugString("4");
00521 #endif
00522
00523 DeterminePaths(argv[0]);
00524 FindGraphicsSets();
00525
00526 #if defined(UNIX) && !defined(__MORPHOS__)
00527
00528 if (_dedicated_forks)
00529 DedicatedFork();
00530 #endif
00531
00532 AI::Initialize();
00533 LoadFromConfig();
00534 AI::Uninitialize(true);
00535 CheckConfig();
00536 LoadFromHighScore();
00537
00538 if (resolution.width != 0) { _cur_resolution = resolution; }
00539 if (startyear != INVALID_YEAR) _settings_newgame.game_creation.starting_year = startyear;
00540 if (generation_seed != GENERATE_NEW_SEED) _settings_newgame.game_creation.generation_seed = generation_seed;
00541
00542
00543
00544 if (_cur_resolution.width <= 0) _cur_resolution.width = 1;
00545 if (_cur_resolution.height <= 0) _cur_resolution.height = 1;
00546
00547 #if defined(ENABLE_NETWORK)
00548 if (dedicated_host) snprintf(_settings_client.network.server_bind_ip, sizeof(_settings_client.network.server_bind_ip), "%s", dedicated_host);
00549 if (dedicated_port) _settings_client.network.server_port = dedicated_port;
00550 if (_dedicated_forks && !dedicated) _dedicated_forks = false;
00551 #endif
00552
00553
00554 InitializeLanguagePacks();
00555
00556
00557 InitializeScreenshotFormats();
00558
00559
00560 InitializeAirports();
00561
00562
00563 InitializeDynamicVariables();
00564
00565
00566 DEBUG(misc, 1, "Loading sound effects...");
00567 MxInitialize(11025);
00568 SoundInitialize("sample.cat");
00569
00570
00571 InitFreeType();
00572
00573
00574 InitWindowSystem();
00575
00576 if (graphics_set == NULL) graphics_set = _ini_graphics_set;
00577 if (!SetGraphicsSet(graphics_set)) {
00578 StrEmpty(graphics_set) ?
00579 usererror("Failed to find a graphics set. Please acquire a graphics set for OpenTTD.") :
00580 usererror("Failed to select requested graphics set '%s'", graphics_set);
00581 }
00582
00583
00584 GfxInitPalettes();
00585
00586 DEBUG(misc, 1, "Loading blitter...");
00587 if (blitter == NULL) blitter = _ini_blitter;
00588 if (BlitterFactoryBase::SelectBlitter(blitter) == NULL)
00589 StrEmpty(blitter) ?
00590 usererror("Failed to autoprobe blitter") :
00591 usererror("Failed to select requested blitter '%s'; does it exist?", blitter);
00592
00593 DEBUG(driver, 1, "Loading drivers...");
00594
00595 if (sounddriver == NULL) sounddriver = _ini_sounddriver;
00596 _sound_driver = (SoundDriver*)SoundDriverFactoryBase::SelectDriver(sounddriver, Driver::DT_SOUND);
00597 if (_sound_driver == NULL) {
00598 StrEmpty(sounddriver) ?
00599 usererror("Failed to autoprobe sound driver") :
00600 usererror("Failed to select requested sound driver '%s'", sounddriver);
00601 }
00602
00603 if (musicdriver == NULL) musicdriver = _ini_musicdriver;
00604 _music_driver = (MusicDriver*)MusicDriverFactoryBase::SelectDriver(musicdriver, Driver::DT_MUSIC);
00605 if (_music_driver == NULL) {
00606 StrEmpty(musicdriver) ?
00607 usererror("Failed to autoprobe music driver") :
00608 usererror("Failed to select requested music driver '%s'", musicdriver);
00609 }
00610
00611 if (videodriver == NULL) videodriver = _ini_videodriver;
00612 _video_driver = (VideoDriver*)VideoDriverFactoryBase::SelectDriver(videodriver, Driver::DT_VIDEO);
00613 if (_video_driver == NULL) {
00614 StrEmpty(videodriver) ?
00615 usererror("Failed to autoprobe video driver") :
00616 usererror("Failed to select requested video driver '%s'", videodriver);
00617 }
00618
00619 _savegame_sort_order = SORT_BY_DATE | SORT_DESCENDING;
00620
00621 _screen.zoom = ZOOM_LVL_NORMAL;
00622
00623
00624 _music_driver->SetVolume(msf.music_vol);
00625
00626 NetworkStartUp();
00627
00628 #if defined(ENABLE_NETWORK)
00629 if (debuglog_conn != NULL && _network_available) {
00630 const char *not_used = NULL;
00631 const char *port = NULL;
00632 uint16 rport;
00633
00634 rport = NETWORK_DEFAULT_DEBUGLOG_PORT;
00635
00636 ParseConnectionString(¬_used, &port, debuglog_conn);
00637 if (port != NULL) rport = atoi(port);
00638
00639 NetworkStartDebugLog(NetworkAddress(debuglog_conn, rport));
00640 }
00641 #endif
00642
00643 ScanNewGRFFiles();
00644
00645 ResetGRFConfig(false);
00646
00647
00648 if (_switch_mode != SM_NONE) MakeNewgameSettingsLive();
00649
00650
00651 IConsoleInit();
00652 _cursor.in_window = true;
00653 InitializeGUI();
00654 IConsoleCmdExec("exec scripts/autoexec.scr 0");
00655
00656
00657 _genworld_paint_mutex->BeginCritical();
00658 _genworld_mapgen_mutex->BeginCritical();
00659
00660 GenerateWorld(GW_EMPTY, 64, 64);
00661 WaitTillGeneratedWorld();
00662
00663 CheckForMissingGlyphsInLoadedLanguagePack();
00664
00665 #ifdef ENABLE_NETWORK
00666 if (network && _network_available) {
00667 if (network_conn != NULL) {
00668 const char *port = NULL;
00669 const char *company = NULL;
00670 uint16 rport;
00671
00672 rport = NETWORK_DEFAULT_PORT;
00673 _network_playas = COMPANY_NEW_COMPANY;
00674
00675 ParseConnectionString(&company, &port, network_conn);
00676
00677 if (company != NULL) {
00678 _network_playas = (CompanyID)atoi(company);
00679
00680 if (_network_playas != COMPANY_SPECTATOR) {
00681 _network_playas--;
00682 if (_network_playas >= MAX_COMPANIES) return false;
00683 }
00684 }
00685 if (port != NULL) rport = atoi(port);
00686
00687 LoadIntroGame();
00688 _switch_mode = SM_NONE;
00689 NetworkClientConnectGame(NetworkAddress(network_conn, rport));
00690 }
00691 }
00692 #endif
00693
00694 _video_driver->MainLoop();
00695
00696 WaitTillSaved();
00697
00698
00699 if (save_config) {
00700 SaveToConfig();
00701 SaveToHighScore();
00702 }
00703
00704
00705 ShutdownGame();
00706
00707 return 0;
00708 }
00709
00710 void HandleExitGameRequest()
00711 {
00712 if (_game_mode == GM_MENU) {
00713 _exit_game = true;
00714 } else if (_settings_client.gui.autosave_on_exit) {
00715 DoExitSave();
00716 _exit_game = true;
00717 } else {
00718 AskExitGame();
00719 }
00720 }
00721
00722 static void ShowScreenshotResult(bool b)
00723 {
00724 if (b) {
00725 extern char _screenshot_name[];
00726 SetDParamStr(0, _screenshot_name);
00727 ShowErrorMessage(INVALID_STRING_ID, STR_031B_SCREENSHOT_SUCCESSFULLY, 0, 0);
00728 } else {
00729 ShowErrorMessage(INVALID_STRING_ID, STR_031C_SCREENSHOT_FAILED, 0, 0);
00730 }
00731
00732 }
00733
00734 static void MakeNewGameDone()
00735 {
00736 SettingsDisableElrail(_settings_game.vehicle.disable_elrails);
00737
00738
00739 if (BlitterFactoryBase::GetCurrentBlitter()->GetScreenDepth() == 0) {
00740 SetLocalCompany(COMPANY_SPECTATOR);
00741 IConsoleCmdExec("exec scripts/game_start.scr 0");
00742 return;
00743 }
00744
00745
00746 DoStartupNewCompany(false);
00747
00748 Company *c = GetCompany(COMPANY_FIRST);
00749 c->engine_renew = _settings_client.gui.autorenew;
00750 c->engine_renew_months = _settings_client.gui.autorenew_months;
00751 c->engine_renew_money = _settings_client.gui.autorenew_money;
00752
00753 IConsoleCmdExec("exec scripts/game_start.scr 0");
00754
00755 SetLocalCompany(COMPANY_FIRST);
00756 _current_company = _local_company;
00757 DoCommandP(0, (_settings_client.gui.autorenew << 15 ) | (_settings_client.gui.autorenew_months << 16) | 4, _settings_client.gui.autorenew_money, CMD_SET_AUTOREPLACE);
00758
00759 InitializeRailGUI();
00760
00761 #ifdef ENABLE_NETWORK
00762
00763
00764 if (_network_server && !StrEmpty(_settings_client.network.default_company_pass)) {
00765 char *password = _settings_client.network.default_company_pass;
00766 NetworkChangeCompanyPassword(1, &password);
00767 }
00768 #endif
00769
00770 MarkWholeScreenDirty();
00771 }
00772
00773 static void MakeNewGame(bool from_heightmap)
00774 {
00775 _game_mode = GM_NORMAL;
00776
00777 ResetGRFConfig(true);
00778 _engine_mngr.ResetToDefaultMapping();
00779 _house_mngr.ResetMapping();
00780 _industile_mngr.ResetMapping();
00781 _industry_mngr.ResetMapping();
00782
00783 GenerateWorldSetCallback(&MakeNewGameDone);
00784 GenerateWorld(from_heightmap ? GW_HEIGHTMAP : GW_NEWGAME, 1 << _settings_game.game_creation.map_x, 1 << _settings_game.game_creation.map_y);
00785 }
00786
00787 static void MakeNewEditorWorldDone()
00788 {
00789 SetLocalCompany(OWNER_NONE);
00790 }
00791
00792 static void MakeNewEditorWorld()
00793 {
00794 _game_mode = GM_EDITOR;
00795
00796 ResetGRFConfig(true);
00797
00798 GenerateWorldSetCallback(&MakeNewEditorWorldDone);
00799 GenerateWorld(GW_EMPTY, 1 << _settings_game.game_creation.map_x, 1 << _settings_game.game_creation.map_y);
00800 }
00801
00802 void StartupCompanies();
00803 void StartupDisasters();
00804 extern void StartupEconomy();
00805
00811 static void StartScenario()
00812 {
00813 _game_mode = GM_NORMAL;
00814
00815
00816 if (_file_to_saveload.mode == SL_INVALID) {
00817 DEBUG(sl, 0, "Savegame is obsolete or invalid format: '%s'", _file_to_saveload.name);
00818 SetDParamStr(0, GetSaveLoadErrorString());
00819 ShowErrorMessage(INVALID_STRING_ID, STR_JUST_RAW_STRING, 0, 0);
00820 _game_mode = GM_MENU;
00821 return;
00822 }
00823
00824
00825 ResetWindowSystem();
00826
00827 SetupColoursAndInitialWindow();
00828
00829 ResetGRFConfig(true);
00830
00831
00832 if (SaveOrLoad(_file_to_saveload.name, _file_to_saveload.mode, SCENARIO_DIR) != SL_OK) {
00833 LoadIntroGame();
00834 SetDParamStr(0, GetSaveLoadErrorString());
00835 ShowErrorMessage(INVALID_STRING_ID, STR_JUST_RAW_STRING, 0, 0);
00836 }
00837
00838 _settings_game.difficulty = _settings_newgame.difficulty;
00839
00840
00841 StartupEconomy();
00842 StartupCompanies();
00843 StartupEngines();
00844 StartupDisasters();
00845
00846 SetLocalCompany(COMPANY_FIRST);
00847 _current_company = _local_company;
00848 DoCommandP(0, (_settings_client.gui.autorenew << 15 ) | (_settings_client.gui.autorenew_months << 16) | 4, _settings_client.gui.autorenew_money, CMD_SET_AUTOREPLACE);
00849
00850 MarkWholeScreenDirty();
00851 }
00852
00861 bool SafeSaveOrLoad(const char *filename, int mode, GameMode newgm, Subdirectory subdir)
00862 {
00863 GameMode ogm = _game_mode;
00864
00865 _game_mode = newgm;
00866 assert(mode == SL_LOAD || mode == SL_OLD_LOAD);
00867 switch (SaveOrLoad(filename, mode, subdir)) {
00868 case SL_OK: return true;
00869
00870 case SL_REINIT:
00871 switch (ogm) {
00872 default:
00873 case GM_MENU: LoadIntroGame(); break;
00874 case GM_EDITOR: MakeNewEditorWorld(); break;
00875 }
00876 return false;
00877
00878 default:
00879 _game_mode = ogm;
00880 return false;
00881 }
00882 }
00883
00884 void SwitchToMode(SwitchMode new_mode)
00885 {
00886 #ifdef ENABLE_NETWORK
00887
00888 if (new_mode != SM_SAVE) {
00889
00890 if (_networking) {
00891 if (_network_server && (new_mode == SM_LOAD || new_mode == SM_NEWGAME)) {
00892 NetworkReboot();
00893 } else {
00894 NetworkDisconnect();
00895 }
00896 }
00897
00898
00899 if (_is_network_server) {
00900
00901 if (new_mode != SM_MENU) {
00902
00903 if (_settings_client.network.reload_cfg) {
00904 LoadFromConfig();
00905 MakeNewgameSettingsLive();
00906 ResetGRFConfig(false);
00907 }
00908 NetworkServerStart();
00909 } else {
00910
00911 _is_network_server = false;
00912 }
00913 }
00914 }
00915 #endif
00916
00917 if (new_mode != SM_SAVE) AI::KillAll();
00918
00919 switch (new_mode) {
00920 case SM_EDITOR:
00921 MakeNewEditorWorld();
00922 break;
00923
00924 case SM_NEWGAME:
00925 #ifdef ENABLE_NETWORK
00926 if (_network_server) {
00927 snprintf(_network_game_info.map_name, lengthof(_network_game_info.map_name), "Random Map");
00928 }
00929 #endif
00930 MakeNewGame(false);
00931 break;
00932
00933 case SM_START_SCENARIO:
00934 #ifdef ENABLE_NETWORK
00935 if (_network_server) {
00936 snprintf(_network_game_info.map_name, lengthof(_network_game_info.map_name), "%s (Loaded scenario)", _file_to_saveload.title);
00937 }
00938 #endif
00939 StartScenario();
00940 break;
00941
00942 case SM_LOAD: {
00943 ResetGRFConfig(true);
00944 ResetWindowSystem();
00945
00946 if (!SafeSaveOrLoad(_file_to_saveload.name, _file_to_saveload.mode, GM_NORMAL, NO_DIRECTORY)) {
00947 LoadIntroGame();
00948 SetDParamStr(0, GetSaveLoadErrorString());
00949 ShowErrorMessage(INVALID_STRING_ID, STR_JUST_RAW_STRING, 0, 0);
00950 } else {
00951 if (_saveload_mode == SLD_LOAD_SCENARIO) {
00952 StartupEngines();
00953 }
00954
00955
00956 SetLocalCompany(_network_dedicated ? COMPANY_SPECTATOR : COMPANY_FIRST);
00957
00958 IConsoleCmdExec("exec scripts/game_start.scr 0");
00959
00960 DoCommandP(0, 0, 0, CMD_PAUSE);
00961 #ifdef ENABLE_NETWORK
00962 if (_network_server) {
00963 snprintf(_network_game_info.map_name, lengthof(_network_game_info.map_name), "%s (Loaded game)", _file_to_saveload.title);
00964 }
00965 #endif
00966 }
00967 break;
00968 }
00969
00970 case SM_START_HEIGHTMAP:
00971 #ifdef ENABLE_NETWORK
00972 if (_network_server) {
00973 snprintf(_network_game_info.map_name, lengthof(_network_game_info.map_name), "%s (Heightmap)", _file_to_saveload.title);
00974 }
00975 #endif
00976 MakeNewGame(true);
00977 break;
00978
00979 case SM_LOAD_HEIGHTMAP:
00980 SetLocalCompany(OWNER_NONE);
00981
00982 GenerateWorld(GW_HEIGHTMAP, 1 << _settings_game.game_creation.map_x, 1 << _settings_game.game_creation.map_y);
00983 MarkWholeScreenDirty();
00984 break;
00985
00986 case SM_LOAD_SCENARIO: {
00987 if (SafeSaveOrLoad(_file_to_saveload.name, _file_to_saveload.mode, GM_EDITOR, NO_DIRECTORY)) {
00988 SetLocalCompany(OWNER_NONE);
00989 _settings_newgame.game_creation.starting_year = _cur_year;
00990 } else {
00991 SetDParamStr(0, GetSaveLoadErrorString());
00992 ShowErrorMessage(INVALID_STRING_ID, STR_JUST_RAW_STRING, 0, 0);
00993 }
00994 break;
00995 }
00996
00997 case SM_MENU:
00998 LoadIntroGame();
00999 break;
01000
01001 case SM_SAVE:
01002
01003 if (_networking && _pause_game == 1) _pause_game = 2;
01004 if (SaveOrLoad(_file_to_saveload.name, SL_SAVE, NO_DIRECTORY) != SL_OK) {
01005 SetDParamStr(0, GetSaveLoadErrorString());
01006 ShowErrorMessage(INVALID_STRING_ID, STR_JUST_RAW_STRING, 0, 0);
01007 } else {
01008 DeleteWindowById(WC_SAVELOAD, 0);
01009 }
01010 if (_networking && _pause_game == 2) _pause_game = 1;
01011 break;
01012
01013 case SM_GENRANDLAND:
01014 SetLocalCompany(OWNER_NONE);
01015 GenerateWorld(GW_RANDOM, 1 << _settings_game.game_creation.map_x, 1 << _settings_game.game_creation.map_y);
01016
01017 MarkWholeScreenDirty();
01018 break;
01019
01020 default: NOT_REACHED();
01021 }
01022
01023 if (_switch_mode_errorstr != INVALID_STRING_ID) {
01024 ShowErrorMessage(INVALID_STRING_ID, _switch_mode_errorstr, 0, 0);
01025 }
01026 }
01027
01028
01034 void StateGameLoop()
01035 {
01036
01037 if (_pause_game) {
01038 CallWindowTickEvent();
01039 return;
01040 }
01041 if (IsGeneratingWorld()) return;
01042
01043 ClearStorageChanges(false);
01044
01045 if (_game_mode == GM_EDITOR) {
01046 RunTileLoop();
01047 CallVehicleTicks();
01048 CallLandscapeTick();
01049 ClearStorageChanges(true);
01050
01051 CallWindowTickEvent();
01052 NewsLoop();
01053 } else {
01054 if (_debug_desync_level > 1) {
01055 Vehicle *v;
01056 FOR_ALL_VEHICLES(v) {
01057 if (v != v->First()) continue;
01058
01059 switch (v->type) {
01060 case VEH_ROAD: {
01061 extern byte GetRoadVehLength(const Vehicle *v);
01062 if (GetRoadVehLength(v) != v->u.road.cached_veh_length) {
01063 DEBUG(desync, 2, "cache mismatch: vehicle %i, company %i, unit number %i\n", v->index, (int)v->owner, v->unitnumber);
01064 }
01065 } break;
01066
01067 case VEH_TRAIN: {
01068 uint length = 0;
01069 for (Vehicle *u = v; u != NULL; u = u->Next()) length++;
01070
01071 VehicleRail *wagons = MallocT<VehicleRail>(length);
01072 length = 0;
01073 for (Vehicle *u = v; u != NULL; u = u->Next()) wagons[length++] = u->u.rail;
01074
01075 TrainConsistChanged(v, true);
01076
01077 length = 0;
01078 for (Vehicle *u = v; u != NULL; u = u->Next()) {
01079 if (memcmp(&wagons[length], &u->u.rail, sizeof(VehicleRail)) != 0) {
01080 DEBUG(desync, 2, "cache mismatch: vehicle %i, company %i, unit number %i, wagon %i\n", v->index, (int)v->owner, v->unitnumber, length);
01081 }
01082 length++;
01083 }
01084
01085 free(wagons);
01086 } break;
01087
01088 case VEH_AIRCRAFT: {
01089 uint speed = v->u.air.cached_max_speed;
01090 UpdateAircraftCache(v);
01091 if (speed != v->u.air.cached_max_speed) {
01092 DEBUG(desync, 2, "cache mismatch: vehicle %i, company %i, unit number %i\n", v->index, (int)v->owner, v->unitnumber);
01093 }
01094 } break;
01095
01096 default:
01097 break;
01098 }
01099 }
01100 }
01101
01102
01103
01104 CompanyID old_company = _current_company;
01105 _current_company = OWNER_NONE;
01106
01107 AnimateAnimatedTiles();
01108 IncreaseDate();
01109 RunTileLoop();
01110 CallVehicleTicks();
01111 CallLandscapeTick();
01112 ClearStorageChanges(true);
01113
01114 AI::GameLoop();
01115
01116 CallWindowTickEvent();
01117 NewsLoop();
01118 _current_company = old_company;
01119 }
01120 }
01121
01124 static void DoAutosave()
01125 {
01126 char buf[MAX_PATH];
01127
01128 #if defined(PSP)
01129
01130 if (_networking) return;
01131 #endif
01132
01133 if (_settings_client.gui.keep_all_autosave) {
01134 GenerateDefaultSaveName(buf, lastof(buf));
01135 strecat(buf, ".sav", lastof(buf));
01136 } else {
01137
01138 snprintf(buf, sizeof(buf), "autosave%d.sav", _autosave_ctr);
01139
01140 if (++_autosave_ctr >= _settings_client.gui.max_num_autosaves) _autosave_ctr = 0;
01141 }
01142
01143 DEBUG(sl, 2, "Autosaving to '%s'", buf);
01144 if (SaveOrLoad(buf, SL_SAVE, AUTOSAVE_DIR) != SL_OK) {
01145 ShowErrorMessage(INVALID_STRING_ID, STR_AUTOSAVE_FAILED, 0, 0);
01146 }
01147 }
01148
01149 void GameLoop()
01150 {
01151 ProcessAsyncSaveFinish();
01152
01153
01154 if (_do_autosave) {
01155 _do_autosave = false;
01156 DoAutosave();
01157 RedrawAutosave();
01158 }
01159
01160
01161 if (IsScreenshotRequested()) ShowScreenshotResult(MakeScreenshot());
01162
01163
01164 if (_switch_mode != SM_NONE) {
01165 SwitchToMode(_switch_mode);
01166 _switch_mode = SM_NONE;
01167 }
01168
01169 IncreaseSpriteLRU();
01170 InteractiveRandom();
01171
01172 extern int _caret_timer;
01173 _caret_timer += 3;
01174 _palette_animation_counter += 8;
01175 CursorTick();
01176
01177 #ifdef ENABLE_NETWORK
01178
01179 if (_network_available) NetworkUDPGameLoop();
01180
01181 if (_networking && !IsGeneratingWorld()) {
01182
01183 NetworkGameLoop();
01184 } else {
01185 if (_network_reconnect > 0 && --_network_reconnect == 0) {
01186
01187
01188 _network_playas = COMPANY_SPECTATOR;
01189 NetworkClientConnectGame(NetworkAddress(_settings_client.network.last_host, _settings_client.network.last_port));
01190 }
01191
01192 StateGameLoop();
01193 }
01194 #else
01195 StateGameLoop();
01196 #endif
01197
01198 if (!_pause_game && HasBit(_display_opt, DO_FULL_ANIMATION)) DoPaletteAnimations();
01199
01200 if (!_pause_game || _cheats.build_in_pause.value) MoveAllTextEffects();
01201
01202 InputLoop();
01203
01204 _sound_driver->MainLoop();
01205 MusicLoop();
01206 }