OpenTTD Source 20250528-master-g3aca5d62a8
openttd.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6 */
7
10#include "stdafx.h"
11
12#include "blitter/factory.hpp"
16#include "mixer.h"
17
18#include "fontcache.h"
19#include "error.h"
20#include "error_func.h"
21#include "gui.h"
22
23#include "base_media_base.h"
24#include "base_media_graphics.h"
25#include "base_media_music.h"
26#include "base_media_sounds.h"
27#include "saveload/saveload.h"
28#include "company_cmd.h"
29#include "company_func.h"
30#include "company_gui.h"
31#include "command_func.h"
32#include "news_func.h"
33#include "fios.h"
34#include "aircraft.h"
35#include "roadveh.h"
36#include "train.h"
37#include "ship.h"
38#include "console_func.h"
39#include "screenshot.h"
40#include "network/network.h"
42#include "ai/ai.hpp"
43#include "ai/ai_config.hpp"
44#include "settings_func.h"
45#include "genworld.h"
46#include "progress.h"
47#include "strings_func.h"
48#include "vehicle_func.h"
49#include "gamelog.h"
50#include "animated_tile_func.h"
51#include "roadstop_base.h"
52#include "elrail_func.h"
53#include "rev.h"
54#include "highscore.h"
55#include "station_base.h"
56#include "crashlog.h"
57#include "engine_func.h"
58#include "core/random_func.hpp"
59#include "rail_gui.h"
60#include "road_gui.h"
61#include "core/backup_type.hpp"
62#include "hotkeys.h"
63#include "newgrf.h"
64#include "misc/getoptdata.h"
65#include "game/game.hpp"
66#include "game/game_config.hpp"
67#include "town.h"
68#include "subsidy_func.h"
69#include "gfx_layout.h"
70#include "viewport_func.h"
72#include "framerate_type.h"
73#include "industry.h"
74#include "network/network_gui.h"
76#include "misc_cmd.h"
77#include "timer/timer.h"
82#include "social_integration.h"
84
86
87#include <system_error>
88
89#include "table/strings.h"
90
91#include "safeguards.h"
92
93#ifdef __EMSCRIPTEN__
94# include <emscripten.h>
95# include <emscripten/html5.h>
96#endif
97
98void CallLandscapeTick();
99void DoPaletteAnimations();
100void MusicLoop();
102bool HandleBootstrap();
103
104extern void CheckCaches();
105extern Company *DoStartupNewCompany(bool is_ai, CompanyID company = CompanyID::Invalid());
106extern void OSOpenBrowser(const std::string &url);
107extern void ShowOSErrorBox(std::string_view buf, bool system);
108extern std::string _config_file;
109
110bool _save_config = false;
111bool _request_newgrf_scan = false;
112NewGRFScanCallback *_request_newgrf_scan_callback = nullptr;
113
119void UserErrorI(const std::string &str)
120{
121 ShowOSErrorBox(str, false);
123
124#ifdef __EMSCRIPTEN__
125 emscripten_exit_pointerlock();
126 /* In effect, the game ends here. As emscripten_set_main_loop() caused
127 * the stack to be unwound, the code after MainLoop() in
128 * openttd_main() is never executed. */
129 EM_ASM(if (window["openttd_abort"]) openttd_abort());
130#endif
131
132 _exit(1);
133}
134
140void FatalErrorI(const std::string &str)
141{
142 if (VideoDriver::GetInstance() == nullptr || VideoDriver::GetInstance()->HasGUI()) {
143 ShowOSErrorBox(str, true);
144 }
145
146 /* Set the error message for the crash log and then invoke it. */
148 abort();
149}
150
154static void ShowHelp()
155{
156 std::string str;
157 str.reserve(8192);
158
159 std::back_insert_iterator<std::string> output_iterator = std::back_inserter(str);
160 fmt::format_to(output_iterator, "OpenTTD {}\n", _openttd_revision);
161 str +=
162 "\n"
163 "\n"
164 "Command line options:\n"
165 " -v drv = Set video driver (see below)\n"
166 " -s drv = Set sound driver (see below)\n"
167 " -m drv = Set music driver (see below)\n"
168 " -b drv = Set the blitter to use (see below)\n"
169 " -r res = Set resolution (for instance 800x600)\n"
170 " -h = Display this help text\n"
171 " -t year = Set starting year\n"
172 " -d [[fac=]lvl[,...]]= Debug mode\n"
173 " -e = Start Editor\n"
174 " -g [savegame|scenario|heightmap] = Start new/savegame/scenario/heightmap immediately\n"
175 " -G seed = Set random seed\n"
176 " -n host[:port][#company]= Join network game\n"
177 " -p password = Password to join server\n"
178 " -D [host][:port] = Start dedicated server\n"
179#if !defined(_WIN32)
180 " -f = Fork into the background (dedicated only)\n"
181#endif
182 " -I graphics_set = Force the graphics set (see below)\n"
183 " -S sounds_set = Force the sounds set (see below)\n"
184 " -M music_set = Force the music set (see below)\n"
185 " -c config_file = Use 'config_file' instead of 'openttd.cfg'\n"
186 " -x = Never save configuration changes to disk\n"
187 " -X = Don't use global folders to search for files\n"
188 " -q savegame = Write some information about the savegame and exit\n"
189 " -Q = Don't scan for/load NewGRF files on startup\n"
190 " -QQ = Disable NewGRF scanning/loading entirely\n"
191 "\n";
192
193 /* List the graphics packs */
194 BaseGraphics::GetSetsList(output_iterator);
195
196 /* List the sounds packs */
197 BaseSounds::GetSetsList(output_iterator);
198
199 /* List the music packs */
200 BaseMusic::GetSetsList(output_iterator);
201
202 /* List the drivers */
203 DriverFactoryBase::GetDriversInfo(output_iterator);
204
205 /* List the blitters */
206 BlitterFactory::GetBlittersInfo(output_iterator);
207
208 /* List the debug facilities. */
209 DumpDebugFacilityNames(output_iterator);
210
211 /* We need to initialize the AI, so it finds the AIs */
213 AI::GetConsoleList(output_iterator, true);
214 AI::Uninitialize(true);
215
216 /* We need to initialize the GameScript, so it finds the GSs */
218 Game::GetConsoleList(output_iterator, true);
219 Game::Uninitialize(true);
220
221 /* ShowInfo put output to stderr, but version information should go
222 * to stdout; this is the only exception */
223#if !defined(_WIN32)
224 fmt::print("{}\n", str);
225#else
226 ShowInfoI(str);
227#endif
228}
229
230static void WriteSavegameInfo(const std::string &name)
231{
233 uint32_t last_ottd_rev = 0;
234 uint8_t ever_modified = 0;
235 bool removed_newgrfs = false;
236
237 _gamelog.Info(&last_ottd_rev, &ever_modified, &removed_newgrfs);
238
239 std::string message;
240 message.reserve(1024);
241 format_append(message, "Name: {}\n", name);
242 format_append(message, "Savegame ver: {}\n", _sl_version);
243 format_append(message, "NewGRF ver: 0x{:08X}\n", last_ottd_rev);
244 format_append(message, "Modified: {}\n", ever_modified);
245
246 if (removed_newgrfs) {
247 format_append(message, "NewGRFs have been removed\n");
248 }
249
250 message += "NewGRFs:\n";
252 for (const auto &c : _load_check_data.grfconfig) {
253 format_append(message, "{:08X} {} {}\n", std::byteswap(c->ident.grfid),
254 FormatArrayAsHex(c->flags.Test(GRFConfigFlag::Compatible) ? c->original_md5sum : c->ident.md5sum), c->filename);
255 }
256 }
257
258 /* ShowInfo put output to stderr, but version information should go
259 * to stdout; this is the only exception */
260#if !defined(_WIN32)
261 fmt::print("{}\n", message);
262#else
263 ShowInfoI(message);
264#endif
265}
266
267
274static void ParseResolution(Dimension &res, std::string_view s)
275{
276 StringConsumer consumer(s);
277 auto width = consumer.TryReadIntegerBase<uint>(10);
278 auto valid = consumer.ReadIf("x");
279 auto height = consumer.TryReadIntegerBase<uint>(10);
280 if (!width.has_value() || !valid || !height.has_value() || consumer.AnyBytesLeft()) {
281 ShowInfo("Invalid resolution '{}'", s);
282 return;
283 }
284
285 res.width = std::max<uint>(*width, 64);
286 res.height = std::max<uint>(*height, 64);
287}
288
289
294static void ShutdownGame()
295{
296 IConsoleFree();
297
298 if (_network_available) NetworkShutDown(); // Shut down the network and close any open connections
299
302
304
305 /* stop the scripts */
306 AI::Uninitialize(false);
307 Game::Uninitialize(false);
308
309 /* Uninitialize variables that are allocated dynamically */
310 _gamelog.Reset();
311
313 PoolBase::Clean(PT_ALL);
314
315 /* No NewGRFs were loaded when it was still bootstrapping. */
316 if (_game_mode != GM_BOOTSTRAP) ResetNewGRFData();
317
319}
320
325static void LoadIntroGame(bool load_newgrfs = true)
326{
327 _game_mode = GM_MENU;
328
329 if (load_newgrfs) ResetGRFConfig(false);
330
331 /* Setup main window */
334
335 /* Load the default opening screen savegame */
336 if (SaveOrLoad("opntitle.dat", SLO_LOAD, DFT_GAME_FILE, BASESET_DIR) != SL_OK) {
337 GenerateWorld(GWM_EMPTY, 64, 64); // if failed loading, make empty world.
339 } else {
340 SetLocalCompany(CompanyID::Begin());
341 }
342
343 FixTitleGameZoom();
344 _pause_mode = {};
345 _cursor.fix_at = false;
346
348
349 MusicLoop(); // ensure music is correct
350}
351
352void MakeNewgameSettingsLive()
353{
354 for (CompanyID c = CompanyID::Begin(); c < MAX_COMPANIES; ++c) {
356 }
358
359 /* Copy newgame settings to active settings.
360 * Also initialise old settings needed for savegame conversion. */
363}
364
365void OpenBrowser(const std::string &url)
366{
367 /* Make sure we only accept urls that are sure to open a browser. */
368 if (url.starts_with("http://") || url.starts_with("https://")) {
369 OSOpenBrowser(url);
370 }
371}
372
377 std::string dedicated_host;
378 uint16_t dedicated_port = 0;
379 std::string connection_string;
381 bool save_config = true;
382
387 {
388 /* Visual C++ 2015 fails compiling this line (AfterNewGRFScan::generation_seed undefined symbol)
389 * if it's placed outside a member function, directly in the struct body. */
390 static_assert(sizeof(generation_seed) == sizeof(_settings_game.game_creation.generation_seed));
391 }
392
393 void OnNewGRFsScanned() override
394 {
395 ResetGRFConfig(false);
396
398
401
402 /* We want the new (correct) NewGRF count to survive the loading. */
403 uint last_newgrf_count = _settings_client.gui.last_newgrf_count;
405 _settings_client.gui.last_newgrf_count = last_newgrf_count;
406 /* Since the default for the palette might have changed due to
407 * reading the configuration file, recalculate that now. */
409
410 Game::Uninitialize(true);
411 AI::Uninitialize(true);
415
416 /* We have loaded the config, so we may possibly save it. */
417 _save_config = save_config;
418
419 /* restore saved music and effects volumes */
421 SetEffectVolume(_settings_client.music.effect_vol);
422
423 if (startyear != CalendarTime::INVALID_YEAR) IConsoleSetSetting("game_creation.starting_year", startyear.base());
425
426 if (!dedicated_host.empty()) {
427 _network_bind_list.clear();
429 }
431
432 /* initialize the ingame console */
433 IConsoleInit();
434 InitializeGUI();
435 IConsoleCmdExec("exec scripts/autoexec.scr 0");
436
437 /* Make sure _settings is filled with _settings_newgame if we switch to a game directly */
438 if (_switch_mode != SM_NONE) MakeNewgameSettingsLive();
439
440 if (_network_available && !connection_string.empty()) {
442 _switch_mode = SM_NONE;
443
445 }
446
447 /* After the scan we're not used anymore. */
448 delete this;
449 }
450};
451
452void PostMainLoop()
453{
454 WaitTillSaved();
455
456 /* only save config if we have to */
457 if (_save_config) {
458 SaveToConfig();
462 }
463
464 /* Reset windowing system, stop drivers, free used memory, ... */
465 ShutdownGame();
466}
467
468#if defined(UNIX)
469extern void DedicatedFork();
470#endif
471
477static std::vector<OptionData> CreateOptions()
478{
479 std::vector<OptionData> options;
480 /* Options that require a parameter. */
481 for (char c : "GIMSbcmnpqrstv") options.push_back({ .type = ODF_HAS_VALUE, .id = c, .shortname = c });
482
483 /* Options with an optional parameter. */
484 for (char c : "Ddg") options.push_back({ .type = ODF_OPTIONAL_VALUE, .id = c, .shortname = c });
485
486 /* Options without a parameter. */
487 for (char c : "QXehx") options.push_back({ .type = ODF_NO_VALUE, .id = c, .shortname = c });
488#if !defined(_WIN32)
489 options.push_back({ .type = ODF_NO_VALUE, .id = 'f', .shortname = 'f' });
490#endif
491
492 return options;
493}
494
500int openttd_main(std::span<std::string_view> arguments)
501{
502 _game_session_stats.start_time = std::chrono::steady_clock::now();
503 _game_session_stats.savegame_size = std::nullopt;
504
505 std::string musicdriver;
506 std::string sounddriver;
507 std::string videodriver;
508 std::string blitter;
509 std::string graphics_set;
510 std::string sounds_set;
511 std::string music_set;
512 Dimension resolution = {0, 0};
513 std::unique_ptr<AfterNewGRFScan> scanner = std::make_unique<AfterNewGRFScan>();
514 bool dedicated = false;
515 bool only_local_path = false;
516
517 extern bool _dedicated_forks;
518 _dedicated_forks = false;
519
520 _game_mode = GM_MENU;
522
523 auto options = CreateOptions();
524 GetOptData mgo(arguments.subspan(1), options);
525 int ret = 0;
526
527 int i;
528 while ((i = mgo.GetOpt()) != -1) {
529 switch (i) {
530 case 'I': graphics_set = mgo.opt; break;
531 case 'S': sounds_set = mgo.opt; break;
532 case 'M': music_set = mgo.opt; break;
533 case 'm': musicdriver = mgo.opt; break;
534 case 's': sounddriver = mgo.opt; break;
535 case 'v': videodriver = mgo.opt; break;
536 case 'b': blitter = mgo.opt; break;
537 case 'D':
538 musicdriver = "null";
539 sounddriver = "null";
540 videodriver = "dedicated";
541 blitter = "null";
542 dedicated = true;
543 SetDebugString("net=4", ShowInfoI);
544 if (!mgo.opt.empty()) {
545 scanner->dedicated_host = ParseFullConnectionString(mgo.opt, scanner->dedicated_port);
546 }
547 break;
548 case 'f': _dedicated_forks = true; break;
549 case 'n':
550 scanner->connection_string = mgo.opt; // host:port#company parameter
551 break;
552 case 'p':
553 scanner->join_server_password = mgo.opt;
554 break;
555 case 'r': ParseResolution(resolution, mgo.opt); break;
556 case 't':
557 if (auto value = ParseInteger(mgo.opt); value.has_value()) {
558 scanner->startyear = TimerGameCalendar::Year(*value);
559 } else {
560 fmt::print(stderr, "Invalid start year: {}\n", mgo.opt);
561 }
562 break;
563 case 'd': {
564#if defined(_WIN32)
565 CreateConsole();
566#endif
567 if (!mgo.opt.empty()) SetDebugString(mgo.opt, ShowInfoI);
568 break;
569 }
570 case 'e':
571 /* Allow for '-e' before or after '-g'. */
572 switch (_switch_mode) {
573 case SM_MENU: _switch_mode = SM_EDITOR; break;
576 default: break;
577 }
578 break;
579 case 'g':
580 if (!mgo.opt.empty()) {
582
583 std::string extension = FS2OTTD(std::filesystem::path(OTTD2FS(_file_to_saveload.name)).extension().native());
585 if (ft == FIOS_TYPE_INVALID) {
586 std::tie(ft, _) = FiosGetScenarioListCallback(SLO_LOAD, _file_to_saveload.name, extension);
587 }
588 if (ft == FIOS_TYPE_INVALID) {
589 std::tie(ft, _) = FiosGetHeightmapListCallback(SLO_LOAD, _file_to_saveload.name, extension);
590 }
591
592 /* Allow for '-e' before or after '-g'. */
593 switch (ft.abstract) {
597 default: break;
598 }
599
601 break;
602 }
603
605 /* Give a random map if no seed has been given */
606 if (scanner->generation_seed == GENERATE_NEW_SEED) {
607 scanner->generation_seed = InteractiveRandom();
608 }
609 break;
610 case 'q': {
611 DeterminePaths(arguments[0], only_local_path);
612 if (mgo.opt.empty()) {
613 ret = 1;
614 return ret;
615 }
616
617 std::string extension = FS2OTTD(std::filesystem::path(OTTD2FS(mgo.opt)).extension().native());
618 auto [_, title] = FiosGetSavegameListCallback(SLO_LOAD, mgo.opt, extension);
619
622 if (res != SL_OK || _load_check_data.HasErrors()) {
623 fmt::print(stderr, "Failed to open savegame\n");
625 InitializeLanguagePacks(); // A language pack is needed for GetString()
626 fmt::print(stderr, "{}\n", GetString(_load_check_data.error, _load_check_data.error_msg));
627 }
628 return ret;
629 }
630
631 WriteSavegameInfo(title);
632 return ret;
633 }
634 case 'Q': {
635 extern int _skip_all_newgrf_scanning;
637 break;
638 }
639 case 'G':
640 if (auto value = ParseInteger(mgo.opt); value.has_value()) {
641 scanner->generation_seed = *value;
642 } else {
643 fmt::print(stderr, "Invalid generation seed: {}\n", mgo.opt);
644 }
645 break;
646 case 'c': _config_file = mgo.opt; break;
647 case 'x': scanner->save_config = false; break;
648 case 'X': only_local_path = true; break;
649 case 'h':
650 i = -2; // Force printing of help.
651 break;
652 }
653 if (i == -2) break;
654 }
655
656 if (i == -2 || !mgo.arguments.empty()) {
657 /* Either the user typed '-h', they made an error, or they added unrecognized command line arguments.
658 * In all cases, print the help, and exit.
659 *
660 * The next two functions are needed to list the graphics sets. We can't do them earlier
661 * because then we cannot show it on the debug console as that hasn't been configured yet. */
662 DeterminePaths(arguments[0], only_local_path);
667 ShowHelp();
668 return ret;
669 }
670
671 DeterminePaths(arguments[0], only_local_path);
673
674 if (dedicated) Debug(net, 3, "Starting dedicated server, version {}", _openttd_revision);
675 if (_dedicated_forks && !dedicated) _dedicated_forks = false;
676
677#if defined(UNIX)
678 /* We must fork here, or we'll end up without some resources we need (like sockets) */
679 if (_dedicated_forks) DedicatedFork();
680#endif
681
682 LoadFromConfig(true);
683
684 if (resolution.width != 0) _cur_resolution = resolution;
685
686 /* Limit width times height times bytes per pixel to fit a 32 bit
687 * integer, This way all internal drawing routines work correctly.
688 * A resolution that has one component as 0 is treated as a marker to
689 * auto-detect a good window size. */
690 _cur_resolution.width = std::min(_cur_resolution.width, UINT16_MAX / 2u);
691 _cur_resolution.height = std::min(_cur_resolution.height, UINT16_MAX / 2u);
692
693 /* Assume the cursor starts within the game as not all video drivers
694 * get an event that the cursor is within the window when it is opened.
695 * Saying the cursor is there makes no visible difference as it would
696 * just be out of the bounds of the window. */
697 _cursor.in_window = true;
698
699 /* enumerate language files */
701
702 /* Initialize the font cache */
703 InitFontCache(false);
704
705 /* This must be done early, since functions use the SetWindowDirty* calls */
707
709 bool valid_graphics_set;
710 if (!graphics_set.empty()) {
711 valid_graphics_set = BaseGraphics::SetSetByName(graphics_set);
712 } else if (BaseGraphics::ini_data.shortname != 0) {
713 graphics_set = BaseGraphics::ini_data.name;
714 valid_graphics_set = BaseGraphics::SetSetByShortname(BaseGraphics::ini_data.shortname);
715 if (valid_graphics_set && !BaseGraphics::ini_data.extra_params.empty()) {
717 if (extra_cfg.IsCompatible(BaseGraphics::ini_data.extra_version)) {
718 extra_cfg.SetParams(BaseGraphics::ini_data.extra_params);
719 }
720 }
721 } else if (!BaseGraphics::ini_data.name.empty()) {
722 graphics_set = BaseGraphics::ini_data.name;
723 valid_graphics_set = BaseGraphics::SetSetByName(BaseGraphics::ini_data.name);
724 } else {
725 valid_graphics_set = true;
726 BaseGraphics::SetSet(nullptr); // ignore error, continue to bootstrap GUI
727 }
728 if (!valid_graphics_set) {
729 BaseGraphics::SetSet(nullptr);
730
731 ErrorMessageData msg(GetEncodedString(STR_CONFIG_ERROR), GetEncodedString(STR_CONFIG_ERROR_INVALID_BASE_GRAPHICS_NOT_FOUND, graphics_set));
733 }
734
735 /* Initialize game palette */
736 GfxInitPalettes();
737
738 Debug(misc, 1, "Loading blitter...");
739 if (blitter.empty() && !_ini_blitter.empty()) blitter = _ini_blitter;
740 _blitter_autodetected = blitter.empty();
741 /* Activate the initial blitter.
742 * This is only some initial guess, after NewGRFs have been loaded SwitchNewGRFBlitter may switch to a different one.
743 * - Never guess anything, if the user specified a blitter. (_blitter_autodetected)
744 * - Use 32bpp blitter if baseset or 8bpp-support settings says so.
745 * - Use 8bpp blitter otherwise.
746 */
748 (_support8bpp != S8BPP_NONE && (BaseGraphics::GetUsedSet() == nullptr || BaseGraphics::GetUsedSet()->blitter == BLT_8BPP)) ||
749 BlitterFactory::SelectBlitter("32bpp-anim") == nullptr) {
750 if (BlitterFactory::SelectBlitter(blitter) == nullptr) {
751 blitter.empty() ?
752 UserError("Failed to autoprobe blitter") :
753 UserError("Failed to select requested blitter '{}'; does it exist?", blitter);
754 }
755 }
756
757 if (videodriver.empty() && !_ini_videodriver.empty()) videodriver = _ini_videodriver;
759
761
762 /* Initialize the zoom level of the screen to normal */
763 _screen.zoom = ZoomLevel::Min;
764
765 /* The video driver is now selected, now initialise GUI zoom */
767
769 NetworkStartUp(); // initialize network-core
770
771 if (!HandleBootstrap()) {
772 ShutdownGame();
773 return ret;
774 }
775
776 VideoDriver::GetInstance()->ClaimMousePointer();
777
779 if (sounds_set.empty() && !BaseSounds::ini_set.empty()) sounds_set = BaseSounds::ini_set;
780 if (!BaseSounds::SetSetByName(sounds_set)) {
781 if (sounds_set.empty() || !BaseSounds::SetSet({})) {
782 UserError("Failed to find a sounds set. Please acquire a sounds set for OpenTTD. See section 1.4 of README.md.");
783 } else {
784 ErrorMessageData msg(GetEncodedString(STR_CONFIG_ERROR), GetEncodedString(STR_CONFIG_ERROR_INVALID_BASE_SOUNDS_NOT_FOUND, sounds_set));
786 }
787 }
788
790 if (music_set.empty() && !BaseMusic::ini_set.empty()) music_set = BaseMusic::ini_set;
791 if (!BaseMusic::SetSetByName(music_set)) {
792 if (music_set.empty() || !BaseMusic::SetSet({})) {
793 UserError("Failed to find a music set. Please acquire a music set for OpenTTD. See section 1.4 of README.md.");
794 } else {
795 ErrorMessageData msg(GetEncodedString(STR_CONFIG_ERROR), GetEncodedString(STR_CONFIG_ERROR_INVALID_BASE_MUSIC_NOT_FOUND, music_set));
797 }
798 }
799
800 if (sounddriver.empty() && !_ini_sounddriver.empty()) sounddriver = _ini_sounddriver;
802
803 if (musicdriver.empty() && !_ini_musicdriver.empty()) musicdriver = _ini_musicdriver;
805
806 GenerateWorld(GWM_EMPTY, 64, 64); // Make the viewport initialization happy
807 LoadIntroGame(false);
808
809 /* ScanNewGRFFiles now has control over the scanner. */
810 RequestNewGRFScan(scanner.release());
811
813
814 PostMainLoop();
815 return ret;
816}
817
818void HandleExitGameRequest()
819{
820 if (_game_mode == GM_MENU || _game_mode == GM_BOOTSTRAP) { // do not ask to quit on the main screen
821 _exit_game = true;
823 DoExitSave();
825 _exit_game = true;
826 } else {
827 AskExitGame();
828 }
829}
830
834static void OnStartScenario()
835{
836 /* Reset engine pool to simplify changing engine NewGRFs in scenario editor. */
838
839 /* Make sure all industries were built "this year", to avoid too early closures. (#9918) */
840 for (Industry *i : Industry::Iterate()) {
841 i->last_prod_year = TimerGameEconomy::year;
842 }
843}
844
849static void OnStartGame(bool dedicated_server)
850{
851 /* Update the local company for a loaded game. It is either the first available company
852 * or in the case of a dedicated server, a spectator */
854
856
857 /* Execute the game-start script */
858 IConsoleCmdExec("exec scripts/game_start.scr 0");
859}
860
861static void MakeNewGameDone()
862{
864
865 /* In a dedicated server, the server does not play */
866 if (!VideoDriver::GetInstance()->HasGUI()) {
867 OnStartGame(true);
869 return;
870 }
871
872 /* Create a single company */
873 DoStartupNewCompany(false);
874
875 Company *c = Company::Get(CompanyID::Begin());
877
878 /* Overwrite color from settings if needed
879 * COLOUR_END corresponds to Random colour */
880
881 if (_settings_client.gui.starting_colour != COLOUR_END) {
883 }
884
887 }
888
889 OnStartGame(false);
890
893
895
896 CheckEngines();
899}
900
901static void MakeNewGame(bool from_heightmap, bool reset_settings)
902{
903 _game_mode = GM_NORMAL;
904 if (!from_heightmap) {
905 /* "reload" command needs to know what mode we were in. */
906 _file_to_saveload.SetMode(FIOS_TYPE_INVALID, SLO_INVALID);
907 }
908
909 ResetGRFConfig(true);
910
911 GenerateWorldSetCallback(&MakeNewGameDone);
912 GenerateWorld(from_heightmap ? GWM_HEIGHTMAP : GWM_NEWGAME, 1 << _settings_game.game_creation.map_x, 1 << _settings_game.game_creation.map_y, reset_settings);
913}
914
915static void MakeNewEditorWorldDone()
916{
918}
919
920static void MakeNewEditorWorld()
921{
922 _game_mode = GM_EDITOR;
923 /* "reload" command needs to know what mode we were in. */
924 _file_to_saveload.SetMode(FIOS_TYPE_INVALID, SLO_INVALID);
925
926 ResetGRFConfig(true);
927
928 GenerateWorldSetCallback(&MakeNewEditorWorldDone);
930}
931
942bool SafeLoad(const std::string &filename, SaveLoadOperation fop, DetailedFileType dft, GameMode newgm, Subdirectory subdir, std::shared_ptr<LoadFilter> lf = nullptr)
943{
944 assert(fop == SLO_LOAD);
945 assert(dft == DFT_GAME_FILE || (lf == nullptr && dft == DFT_OLD_GAME_FILE));
946 GameMode ogm = _game_mode;
947
948 _game_mode = newgm;
949
950 SaveOrLoadResult result = (lf == nullptr) ? SaveOrLoad(filename, fop, dft, subdir) : LoadWithFilter(std::move(lf));
951 if (result == SL_OK) return true;
952
953 if (_network_dedicated && ogm == GM_MENU) {
954 /*
955 * If we are a dedicated server *and* we just were in the menu, then we
956 * are loading the first savegame. If that fails, not starting the
957 * server is a better reaction than starting the server with a newly
958 * generated map as it is quite likely to be started from a script.
959 */
960 Debug(net, 0, "Loading requested map failed; closing server.");
961 _exit_game = true;
962 return false;
963 }
964
965 if (result != SL_REINIT) {
966 _game_mode = ogm;
967 return false;
968 }
969
970 if (_network_dedicated) {
971 /*
972 * If we are a dedicated server, have already loaded/started a game,
973 * and then loading the savegame fails in a manner that we need to
974 * reinitialize everything. We must not fall back into the menu mode
975 * with the intro game, as that is unjoinable by clients. So there is
976 * nothing else to do than start a new game, as it might have failed
977 * trying to reload the originally loaded savegame/scenario.
978 */
979 Debug(net, 0, "Loading game failed, so a new (random) game will be started");
980 MakeNewGame(false, true);
981 return false;
982 }
983
984 if (_network_server) {
985 /* We can't load the intro game as server, so disconnect first. */
987 }
988
989 switch (ogm) {
990 default:
991 case GM_MENU: LoadIntroGame(); break;
992 case GM_EDITOR: MakeNewEditorWorld(); break;
993 }
994 return false;
995}
996
997static void UpdateSocialIntegration(GameMode game_mode)
998{
999 switch (game_mode) {
1000 case GM_BOOTSTRAP:
1001 case GM_MENU:
1003 break;
1004
1005 case GM_NORMAL:
1006 if (_networking) {
1008 } else {
1010 }
1011 break;
1012
1013 case GM_EDITOR:
1015 break;
1016 }
1017}
1018
1019void SwitchToMode(SwitchMode new_mode)
1020{
1021 /* If we are saving something, the network stays in its current state */
1022 if (new_mode != SM_SAVE_GAME) {
1023 /* If the network is active, make it not-active */
1024 if (_networking) {
1025 if (_network_server && (new_mode == SM_LOAD_GAME || new_mode == SM_NEWGAME || new_mode == SM_RESTARTGAME)) {
1026 NetworkReboot();
1027 } else {
1029 }
1030 }
1031
1032 /* If we are a server, we restart the server */
1033 if (_is_network_server) {
1034 /* But not if we are going to the menu */
1035 if (new_mode != SM_MENU) {
1036 /* check if we should reload the config */
1039 MakeNewgameSettingsLive();
1040 ResetGRFConfig(false);
1041 }
1042 NetworkServerStart();
1043 } else {
1044 /* This client no longer wants to be a network-server */
1045 _is_network_server = false;
1046 }
1047 }
1048 }
1049
1050 /* Make sure all AI controllers are gone at quitting game */
1051 if (new_mode != SM_SAVE_GAME) AI::KillAll();
1052
1053 /* When we change mode, reset the autosave. */
1054 if (new_mode != SM_SAVE_GAME) ChangeAutosaveFrequency(true);
1055
1056 /* Transmit the survey if we were in normal-mode and not saving. It always means we leaving the current game. */
1057 if (_game_mode == GM_NORMAL && new_mode != SM_SAVE_GAME) _survey.Transmit(NetworkSurveyHandler::Reason::LEAVE);
1058
1059 /* Keep track when we last switch mode. Used for survey, to know how long someone was in a game. */
1060 if (new_mode != SM_SAVE_GAME) {
1061 _game_session_stats.start_time = std::chrono::steady_clock::now();
1062 _game_session_stats.savegame_size = std::nullopt;
1063 }
1064
1065 switch (new_mode) {
1066 case SM_EDITOR: // Switch to scenario editor
1067 MakeNewEditorWorld();
1069
1070 UpdateSocialIntegration(GM_EDITOR);
1071 break;
1072
1073 case SM_RELOADGAME: // Reload with what-ever started the game
1075 /* Reload current savegame/scenario */
1076 _switch_mode = _game_mode == GM_EDITOR ? SM_LOAD_SCENARIO : SM_LOAD_GAME;
1077 SwitchToMode(_switch_mode);
1078 break;
1080 /* Restart current heightmap */
1081 _switch_mode = _game_mode == GM_EDITOR ? SM_LOAD_HEIGHTMAP : SM_RESTART_HEIGHTMAP;
1082 SwitchToMode(_switch_mode);
1083 break;
1084 }
1085
1086 MakeNewGame(false, new_mode == SM_NEWGAME);
1088
1089 UpdateSocialIntegration(GM_NORMAL);
1090 break;
1091
1092 case SM_RESTARTGAME: // Restart --> 'Random game' with current settings
1093 case SM_NEWGAME: // New Game --> 'Random game'
1094 MakeNewGame(false, new_mode == SM_NEWGAME);
1096
1097 UpdateSocialIntegration(GM_NORMAL);
1098 break;
1099
1100 case SM_LOAD_GAME: { // Load game, Play Scenario
1101 ResetGRFConfig(true);
1103
1106 } else {
1109 }
1111 /* Decrease pause counter (was increased from opening load dialog) */
1113 }
1114
1115 UpdateSocialIntegration(GM_NORMAL);
1116 break;
1117 }
1118
1119 case SM_RESTART_HEIGHTMAP: // Load a heightmap and start a new game from it with current settings
1120 case SM_START_HEIGHTMAP: // Load a heightmap and start a new game from it
1121 MakeNewGame(true, new_mode == SM_START_HEIGHTMAP);
1123
1124 UpdateSocialIntegration(GM_NORMAL);
1125 break;
1126
1127 case SM_LOAD_HEIGHTMAP: // Load heightmap from scenario editor
1129
1130 _game_mode = GM_EDITOR;
1131
1135
1136 UpdateSocialIntegration(GM_EDITOR);
1137 break;
1138
1139 case SM_LOAD_SCENARIO: { // Load scenario from scenario editor
1144 /* Cancel the saveload pausing */
1146 } else {
1148 }
1149
1150 UpdateSocialIntegration(GM_EDITOR);
1151 break;
1152 }
1153
1154 case SM_JOIN_GAME: // Join a multiplayer game
1155 LoadIntroGame();
1157
1159 break;
1160
1161 case SM_MENU: // Switch to game intro menu
1162 LoadIntroGame();
1163 if (BaseSounds::ini_set.empty() && BaseSounds::GetUsedSet()->fallback && SoundDriver::GetInstance()->HasOutput()) {
1164 ShowErrorMessage(GetEncodedString(STR_WARNING_FALLBACK_SOUNDSET), {}, WL_CRITICAL);
1166 }
1168 /* No matter how often you go back to the main menu, only ask the first time. */
1169 static bool asked_once = false;
1170 if (!asked_once) {
1171 asked_once = true;
1173 }
1174 }
1175
1176 UpdateSocialIntegration(GM_MENU);
1177 break;
1178
1179 case SM_SAVE_GAME: // Save game.
1180 /* Make network saved games on pause compatible to singleplayer mode */
1183 } else {
1185 }
1186 break;
1187
1188 case SM_SAVE_HEIGHTMAP: // Save heightmap.
1191 break;
1192
1193 case SM_GENRANDLAND: // Generate random land within scenario editor
1196 /* XXX: set date */
1198 break;
1199
1200 default: NOT_REACHED();
1201 }
1202}
1203
1204
1205
1212{
1213 if (!_networking || _network_server) {
1215 }
1216
1217 /* Don't execute the state loop during pause or when modal windows are open. */
1218 if (_pause_mode.Any() || HasModalProgress()) {
1226
1228#ifndef DEBUG_DUMP_COMMANDS
1229 if (_game_mode == GM_NORMAL) Game::GameLoop();
1230#endif
1231 return;
1232 }
1233
1236
1237 if (_game_mode == GM_EDITOR) {
1239 RunTileLoop();
1240 CallVehicleTicks();
1241 CallLandscapeTick();
1244
1246 NewsLoop();
1247 } else {
1248 if (_debug_desync_level > 2 && TimerGameEconomy::date_fract == 0 && (TimerGameEconomy::date.base() & 0x1F) == 0) {
1249 /* Save the desync savegame if needed. */
1250 std::string name = fmt::format("dmp_cmds_{:08x}_{:08x}.sav", _settings_game.game_creation.generation_seed, TimerGameEconomy::date);
1252 }
1253
1254 CheckCaches();
1255
1256 /* All these actions has to be done from OWNER_NONE
1257 * for multiplayer compatibility */
1259
1264 }
1267 RunTileLoop();
1268 CallVehicleTicks();
1269 CallLandscapeTick();
1271
1272#ifndef DEBUG_DUMP_COMMANDS
1273 {
1274 PerformanceMeasurer script_framerate(PFE_ALLSCRIPTS);
1275 AI::GameLoop();
1277 }
1278#endif
1280
1282 NewsLoop();
1283 cur_company.Restore();
1284 }
1285
1286 assert(IsLocalCompany());
1287}
1288
1290static IntervalTimer<TimerGameRealtime> _autosave_interval({std::chrono::milliseconds::zero(), TimerGameRealtime::AUTOSAVE}, [](auto)
1291{
1292 /* We reset the command-during-pause mode here, so we don't continue
1293 * to make auto-saves when nothing more is changing. */
1295
1296 _do_autosave = true;
1298
1299 static FiosNumberedSaveName _autosave_ctr("autosave");
1300 DoAutoOrNetsave(_autosave_ctr);
1301
1302 _do_autosave = false;
1304});
1305
1319
1329{
1330 if (_request_newgrf_scan) return false;
1331
1332 _request_newgrf_scan = true;
1333 _request_newgrf_scan_callback = callback;
1334 return true;
1335}
1336
1337void GameLoop()
1338{
1339 if (_game_mode == GM_BOOTSTRAP) {
1340 /* Check for UDP stuff */
1342 return;
1343 }
1344
1345 if (_request_newgrf_scan) {
1346 ScanNewGRFFiles(_request_newgrf_scan_callback);
1347 _request_newgrf_scan = false;
1348 _request_newgrf_scan_callback = nullptr;
1349 /* In case someone closed the game during our scan, don't do anything else. */
1350 if (_exit_game) return;
1351 }
1352
1354
1355 if (_game_mode == GM_NORMAL) {
1356 static auto last_time = std::chrono::steady_clock::now();
1357 auto now = std::chrono::steady_clock::now();
1358 auto delta_ms = std::chrono::duration_cast<std::chrono::milliseconds>(now - last_time);
1359 if (delta_ms.count() != 0) {
1361 last_time = now;
1362 }
1363 }
1364
1365 /* switch game mode? */
1366 if (_switch_mode != SM_NONE && !HasModalProgress()) {
1367 SwitchToMode(_switch_mode);
1368 _switch_mode = SM_NONE;
1369 if (_exit_game) return;
1370 }
1371
1372 IncreaseSpriteLRU();
1373
1374 /* Check for UDP stuff */
1376
1378
1379 if (_networking && !HasModalProgress()) {
1380 /* Multiplayer */
1381 NetworkGameLoop();
1382 } else {
1383 if (_network_reconnect > 0 && --_network_reconnect == 0) {
1384 /* This means that we want to reconnect to the last host
1385 * We do this here, because it means that the network is really closed */
1387 }
1388 /* Singleplayer */
1389 StateGameLoop();
1390 }
1391
1392 if (_pause_mode.None() && HasBit(_display_opt, DO_FULL_ANIMATION)) DoPaletteAnimations();
1393
1395 MusicLoop();
1397}
Base functions for all AIs.
AIConfig stores the configuration settings of every AI.
Base for aircraft.
void AnimateAnimatedTiles()
Animate all tiles in the animated tile list, i.e. call AnimateTile on them.
Tile animation!
Class for backupping variables and making sure they are restored later.
Generic functions for replacing base data (graphics, sounds).
Generic functions for replacing base graphics data.
@ BLT_8BPP
Base set has 8 bpp sprites only.
Generic functions for replacing base music data.
Generic functions for replacing base sounds data.
debug_inline constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
static void Uninitialize(bool keepConfig)
Uninitialize the AI system.
Definition ai_core.cpp:179
static void Initialize()
Initialize the AI system.
Definition ai_core.cpp:165
static void GetConsoleList(std::back_insert_iterator< std::string > &output_iterator, bool newest_only)
Wrapper function for AIScanner::GetAIConsoleList.
Definition ai_core.cpp:288
static void GameLoop()
Called every game-tick to let AIs do something.
Definition ai_core.cpp:74
static void KillAll()
Kill any and all AIs we manage.
Definition ai_core.cpp:155
constexpr bool None() const
Test if none of the values are set.
constexpr Timpl & Reset()
Reset all bits.
constexpr bool Any(const Timpl &other) const
Test if any of the given values are set.
static const GraphicsSet * GetUsedSet()
Return the used set.
static bool SetSetByShortname(uint32_t shortname)
Set the set to be used.
static void GetSetsList(std::back_insert_iterator< std::string > &output_iterator)
Returns a list with the sets.
static uint FindSets()
Do the scan for files.
static bool SetSetByName(const std::string &name)
Set the set to be used.
static bool SetSet(const GraphicsSet *set)
Set the set to be used.
static std::string ini_set
The set as saved in the config file.
static std::string ini_set
The set as saved in the config file.
static void GetBlittersInfo(std::back_insert_iterator< std::string > &output_iterator)
Fill a buffer with information about the blitters.
Definition factory.hpp:147
static Blitter * SelectBlitter(std::string_view name)
Find the requested blitter and return its class.
Definition factory.hpp:96
static void SetErrorMessage(const std::string &message)
Sets a message for the error message handler.
Definition crashlog.cpp:329
static void ShutdownDrivers()
Shuts down all active drivers.
Definition driver.h:123
static void SelectDriver(const std::string &name, Driver::Type type)
Find the requested driver and return its class.
Definition driver.cpp:94
static void GetDriversInfo(std::back_insert_iterator< std::string > &output_iterator)
Build a human readable list of available drivers, grouped by type.
Definition driver.cpp:220
virtual void Stop()=0
Stop this driver.
@ DT_VIDEO
A video driver.
Definition driver.h:42
@ DT_SOUND
A sound driver.
Definition driver.h:41
@ DT_MUSIC
A music driver, needs to be before sound to properly shut down extmidi forked music players.
Definition driver.h:40
The data of the error message.
Definition error.h:31
static void GameLoop()
Called every game-tick to let Game do something.
Definition game_core.cpp:31
static void GetConsoleList(std::back_insert_iterator< std::string > &output_iterator, bool newest_only)
Wrapper function for GameScanner::GetConsoleList.
static void Uninitialize(bool keepConfig)
Uninitialize the Game system.
static void Initialize()
Initialize the Game system.
Definition game_core.cpp:57
void Info(uint32_t *last_ottd_rev, uint8_t *ever_modified, bool *removed_newgrfs)
Get some basic information from the given gamelog.
Definition gamelog.cpp:685
void Reset()
Resets and frees all memory allocated - used before loading or starting a new game.
Definition gamelog.cpp:94
An interval timer will fire every interval, and will continue to fire until it is deleted.
Definition timer.h:76
void SetInterval(const TPeriod interval, bool reset=true)
Set a new interval for the timer.
Definition timer.h:99
static void Clear()
Clear all link graphs and jobs from the schedule.
static MusicDriver * GetInstance()
Get the currently active instance of the music driver.
virtual void SetVolume(uint8_t vol)=0
Set the volume, if possible.
@ EXIT
User is exiting the application.
@ LEAVE
User is leaving the game (but not exiting the application).
void Transmit(Reason reason, bool blocking=false)
Transmit the survey.
static void Reset(PerformanceElement elem)
Store the previous accumulator value and reset for a new cycle of accumulating measurements.
RAII class for measuring simple elements of performance.
static void Paused(PerformanceElement elem)
Indicate that a cycle of "pause" where no processing occurs.
static void EventEnterScenarioEditor(uint map_width, uint map_height)
Event: user entered the Scenario Editor.
static void EventEnterSingleplayer(uint map_width, uint map_height)
Event: user entered a singleplayer game.
static void RunCallbacks()
Allow any social integration library to handle their own events.
static void EventEnterMultiplayer(uint map_width, uint map_height)
Event: user entered a multiplayer game.
static void Shutdown()
Shutdown the social integration system, and all social integration plugins that are loaded.
static void EventEnterMainMenu()
Event: user entered the main menu.
static void EventJoiningMultiplayer()
Event: user is joining a multiplayer game.
static void Initialize()
Initialize the social integration system, loading any social integration plugins that are available.
virtual void MainLoop()
Called once every tick.
static SoundDriver * GetInstance()
Get the currently active instance of the sound driver.
Parse data from a string / buffer.
std::optional< T > TryReadIntegerBase(int base, bool clamp=false)
Try to read and parse an integer in number 'base', and then advance the reader.
bool AnyBytesLeft() const noexcept
Check whether any bytes left to read.
bool ReadIf(std::string_view str)
Check whether the next data matches 'str', and skip it.
@ Scenario
Scan for scenarios and heightmaps.
@ Baseset
Scan for base sets.
uint DoScan(Subdirectory sd)
Perform the scanning of a particular subdirectory.
Definition fileio.cpp:374
static Year year
Current year, starting at 0.
static constexpr TimerGame< struct Calendar >::Year INVALID_YEAR
Representation of an invalid year.
static Date date
Current date in days (day counter).
static Year year
Current year, starting at 0.
static DateFract date_fract
Fractional part of the day.
@ AUTOSAVE
Only run when not paused or there was a Command executed recently.
The TimerManager manages a single Timer-type.
static bool Elapsed(TElapsed value)
Called when time for this timer elapsed.
static VideoDriver * GetInstance()
Get the currently active instance of the video driver.
virtual void MainLoop()=0
Perform the actual drawing.
Functions related to commands.
CompanyID GetFirstPlayableCompanyID()
Get the index of the first available company.
void UpdateLandscapingLimits()
Update the landscaping limits per company.
void SetLocalCompany(CompanyID new_company)
Sets the local company and updates the settings that are set on a per-company basis to reflect the co...
CompanyID _current_company
Company currently doing an action.
Command definitions related to companies.
Functions related to companies.
bool IsLocalCompany()
Is the current company the local company?
GUI Functions related to companies.
static constexpr CompanyID COMPANY_SPECTATOR
The client is spectating.
static constexpr CompanyID COMPANY_NEW_COMPANY
The client wants a new company.
static constexpr Owner OWNER_NONE
The tile has no ownership.
void IConsoleCmdExec(std::string_view command_string, const uint recurse_count)
Execute a given command passed to us.
Definition console.cpp:269
Console functions used outside of the console code.
Functions to be called to log a crash.
void SetDebugString(std::string_view s, SetDebugStringErrorFunc error_func)
Set debugging levels by parsing the text in s.
Definition debug.cpp:144
void DumpDebugFacilityNames(std::back_insert_iterator< std::string > &output_iterator)
Dump the available debug facility names in the help text.
Definition debug.cpp:88
void DebugSendRemoteMessages()
Send the queued Debug messages to either NetworkAdminConsole or IConsolePrint from the GameLoop threa...
Definition debug.cpp:235
#define Debug(category, level, format_string,...)
Output a line of debugging information.
Definition debug.h:37
std::string _ini_videodriver
The video driver a stored in the configuration file.
Definition driver.cpp:27
std::string _ini_musicdriver
The music driver a stored in the configuration file.
Definition driver.cpp:34
Dimension _cur_resolution
The current resolution.
Definition driver.cpp:29
std::string _ini_sounddriver
The sound driver a stored in the configuration file.
Definition driver.cpp:32
void SettingsDisableElrail(int32_t new_value)
_settings_game.disable_elrail callback
Definition elrail.cpp:597
header file for electrified rail specific functions
void CheckEngines()
Check for engines that have an appropriate availability.
Definition engine.cpp:1313
Functions related to engines.
Functions related to errors.
void ScheduleErrorMessage(ErrorList &datas)
Schedule a list of errors.
@ WL_ERROR
Errors (eg. saving/loading failed)
Definition error.h:26
@ WL_CRITICAL
Critical errors, the MessageBox is shown in all cases.
Definition error.h:27
void ShowErrorMessage(EncodedString &&summary_msg, int x, int y, CommandCost &cc)
Display an error message in a window.
Error reporting related functions.
Factory to 'query' all available blitters.
bool _blitter_autodetected
Was the blitter autodetected or specified by the user?
Definition driver.cpp:37
std::string _ini_blitter
The blitter as stored in the configuration file.
Definition driver.cpp:36
void DeterminePaths(std::string_view exe, bool only_local_path)
Acquire the base paths (personal dir and game data dir), fill all other paths (save dir,...
Definition fileio.cpp:877
SaveLoadOperation
Operation performed on the file.
Definition fileio_type.h:51
@ SLO_CHECK
Load file for checking and/or preview.
Definition fileio_type.h:52
@ SLO_SAVE
File is being saved.
Definition fileio_type.h:54
@ SLO_LOAD
File is being loaded.
Definition fileio_type.h:53
@ SLO_INVALID
Unknown file operation.
Definition fileio_type.h:56
DetailedFileType
Kinds of files in each AbstractFileType.
Definition fileio_type.h:27
@ DFT_GAME_FILE
Save game or scenario file.
Definition fileio_type.h:30
@ DFT_OLD_GAME_FILE
Old save game or scenario file.
Definition fileio_type.h:29
Subdirectory
The different kinds of subdirectories OpenTTD uses.
Definition fileio_type.h:87
@ NO_DIRECTORY
A path without any base directory.
@ SAVE_DIR
Base directory for all savegames.
Definition fileio_type.h:89
@ AUTOSAVE_DIR
Subdirectory of save for autosaves.
Definition fileio_type.h:90
@ BASESET_DIR
Subdirectory for all base data (base sets, intro game)
Definition fileio_type.h:95
@ FT_SCENARIO
old or new scenario
Definition fileio_type.h:19
@ FT_HEIGHTMAP
heightmap file
Definition fileio_type.h:20
@ FT_SAVEGAME
old or new savegame
Definition fileio_type.h:18
std::tuple< FiosType, std::string > FiosGetScenarioListCallback(SaveLoadOperation fop, std::string_view file, std::string_view ext)
Callback for FiosGetFileList.
Definition fios.cpp:451
std::tuple< FiosType, std::string > FiosGetSavegameListCallback(SaveLoadOperation fop, std::string_view file, std::string_view ext)
Callback for FiosGetFileList.
Definition fios.cpp:402
Declarations for savegames operations.
LoadCheckData _load_check_data
Data loaded from save during SL_LOAD_CHECK.
Definition fios_gui.cpp:41
void InitFontCache(bool monospace)
(Re)initialize the font cache related things, i.e.
void UninitFontCache()
Free everything allocated w.r.t.
Functions to read fonts from files and cache them.
Types for recording game performance data.
@ PFE_GAMELOOP
Speed of gameloop processing.
@ PFE_GL_SHIPS
Time spent processing ships.
@ PFE_GL_AIRCRAFT
Time spent processing aircraft.
@ PFE_GL_ECONOMY
Time spent processing cargo movement.
@ PFE_GL_LANDSCAPE
Time spent processing other world features.
@ PFE_GL_ROADVEHS
Time spend processing road vehicles.
@ PFE_GL_TRAINS
Time spent processing trains.
@ PFE_ALLSCRIPTS
Sum of all GS/AI scripts.
Base functions for all Games.
GameConfig stores the configuration settings of every Game.
SaveLoadVersion _sl_version
the major savegame version identifier
Definition saveload.cpp:69
Gamelog _gamelog
Gamelog instance.
Definition gamelog.cpp:31
Functions to be called to log fundamental changes to the game.
void GenerateWorldSetCallback(GWDoneProc *proc)
Set here the function, if any, that you want to be called when landscape generation is done.
Definition genworld.cpp:241
void GenerateWorld(GenWorldMode mode, uint size_x, uint size_y, bool reset_settings)
Generate a world.
Definition genworld.cpp:293
Functions related to world/map generation.
static const uint32_t GENERATE_NEW_SEED
Create a new random seed.
Definition genworld.h:25
@ GWM_HEIGHTMAP
Generate a newgame from a heightmap.
Definition genworld.h:32
@ GWM_EMPTY
Generate an empty map (sea-level)
Definition genworld.h:30
@ GWM_RANDOM
Generate a random map for SE.
Definition genworld.h:31
@ GWM_NEWGAME
Generate a map for a new game.
Definition genworld.h:29
Library for parsing command-line options.
@ ODF_OPTIONAL_VALUE
An option with an optional value.
Definition getoptdata.h:17
@ ODF_NO_VALUE
A plain option (no value attached to it).
Definition getoptdata.h:15
@ ODF_HAS_VALUE
An option with a value.
Definition getoptdata.h:16
GameSessionStats _game_session_stats
Statistics about the current session.
Definition gfx.cpp:51
void UpdateGUIZoom()
Resolve GUI zoom level, if auto-suggestion is requested.
Definition gfx.cpp:1776
PauseModes _pause_mode
The current pause mode.
Definition gfx.cpp:50
SwitchMode _switch_mode
The next mainloop command.
Definition gfx.cpp:49
Functions related to laying out the texts.
@ S8BPP_NONE
No support for 8bpp by OS or hardware, force 32bpp blitters.
Definition gfx_type.h:376
void MarkWholeScreenDirty()
This function mark the whole screen as dirty.
Definition gfx.cpp:1535
GUI functions that shouldn't be here.
void LoadFromHighScore()
Initialize the highscore table to 0 and if any file exists, load in values.
void SaveToHighScore()
Save HighScore table to file.
Declaration of functions and types defined in highscore.h and highscore_gui.h.
void LoadHotkeysFromConfig()
Load the hotkeys from the config file.
Definition hotkeys.cpp:332
void SaveHotkeysToConfig()
Save the hotkeys to the config file.
Definition hotkeys.cpp:338
Hotkey related functions.
Base of all industries.
void CheckIndustries()
Verify whether the generated industries are complete, and warn the user if not.
void RunTileLoop()
Gradually iterate over all tiles on the map, calling their TileLoopProcs once every TILE_UPDATE_FREQU...
void StateGameLoop_LinkGraphPauseControl()
Pause the game if in 2 TimerGameEconomy::date_fract ticks, we would do a join with the next link grap...
Declaration of link graph schedule used for cargo distribution.
void SetupColoursAndInitialWindow()
Initialise the default colours (remaps and the likes), and load the main windows.
Definition main_gui.cpp:553
void GenerateSavegameId()
Generate an unique savegame ID.
Definition misc.cpp:87
Miscellaneous command definitions.
Functions to mix sound samples.
Base for all music playback.
void NetworkStartUp()
This tries to launch the network for a given OS.
Definition network.cpp:1286
bool _is_network_server
Does this client wants to be a network-server?
Definition network.cpp:71
void NetworkClientJoinGame()
Actually perform the joining to the server.
Definition network.cpp:819
void NetworkOnGameStart()
Perform tasks when the server is started.
Definition network.cpp:946
bool _network_available
is network mode available?
Definition network.cpp:69
uint8_t _network_reconnect
Reconnect timeout.
Definition network.cpp:74
bool _networking
are we in networking mode?
Definition network.cpp:67
bool _network_dedicated
are we a dedicated server?
Definition network.cpp:70
void NetworkDisconnect(bool close_admins)
We want to disconnect from the host/clients.
Definition network.cpp:1000
bool _network_server
network-server is active
Definition network.cpp:68
void NetworkBackgroundLoop()
We have to do some (simple) background stuff that runs normally, even when we are not in multiplayer.
Definition network.cpp:1081
StringList _network_bind_list
The addresses to bind on.
Definition network.cpp:75
bool NetworkClientConnectGame(std::string_view connection_string, CompanyID default_company, const std::string &join_server_password)
Join a client to the server at with the given connection string.
Definition network.cpp:786
void NetworkShutDown()
This shuts the network down.
Definition network.cpp:1304
std::string_view ParseFullConnectionString(std::string_view connection_string, uint16_t &port, CompanyID *company_id)
Converts a string to ip/port/company Format: IP:port::company.
Definition network.cpp:520
Basic functions/variables used all over the place.
Network functions used by other parts of OpenTTD.
void ShowNetworkAskSurvey()
Show a modal confirmation window with "no" / "preview" / "yes" buttons.
GUIs related to networking.
Part of the network protocol handling opt-in survey.
GRFLoadedFeatures _loaded_newgrf_features
Indicates which are the newgrf features currently loaded ingame.
Definition newgrf.cpp:73
void ResetNewGRFData()
Reset all NewGRF loaded data.
Definition newgrf.cpp:403
Base for the NewGRF implementation.
void UpdateNewGRFConfigPalette(int32_t)
Update the palettes of the graphics from the config file.
void ResetGRFConfig(bool defaults)
Reset the current GRF Config to either blank or newgame settings.
void ScanNewGRFFiles(NewGRFScanCallback *callback)
Scan for all NewGRFs.
int _skip_all_newgrf_scanning
Set this flag to prevent any NewGRF scanning from being done.
@ Compatible
GRF file does not exactly match the requested GRF (different MD5SUM), but grfid matches)
@ PSM_ENTER_GAMELOOP
Enter the gameloop, changes will be permanent.
@ PSM_LEAVE_GAMELOOP
Leave the gameloop, changes will be temporary.
Functions related to news.
void MusicLoop()
Check music playback status and start/stop/song-finished.
void FatalErrorI(const std::string &str)
Error handling for fatal non-user errors.
Definition openttd.cpp:140
int openttd_main(std::span< std::string_view > arguments)
Main entry point for this lovely game.
Definition openttd.cpp:500
static void OnStartScenario()
Triggers everything required to set up a saved scenario for a new game.
Definition openttd.cpp:834
Company * DoStartupNewCompany(bool is_ai, CompanyID company=CompanyID::Invalid())
Create a new company and sets all company variables default values.
static void OnStartGame(bool dedicated_server)
Triggers everything that should be triggered when starting a game.
Definition openttd.cpp:849
static void ParseResolution(Dimension &res, std::string_view s)
Extract the resolution from the given string and store it in the 'res' parameter.
Definition openttd.cpp:274
bool SafeLoad(const std::string &filename, SaveLoadOperation fop, DetailedFileType dft, GameMode newgm, Subdirectory subdir, std::shared_ptr< LoadFilter > lf=nullptr)
Load the specified savegame but on error do different things.
Definition openttd.cpp:942
void ChangeAutosaveFrequency(bool reset)
Reset the interval of the autosave.
Definition openttd.cpp:1315
void StateGameLoop()
State controlling game loop.
Definition openttd.cpp:1211
void UserErrorI(const std::string &str)
Error handling for fatal user errors.
Definition openttd.cpp:119
static void ShowHelp()
Show the help message when someone passed a wrong parameter.
Definition openttd.cpp:154
bool RequestNewGRFScan(NewGRFScanCallback *callback)
Request a new NewGRF scan.
Definition openttd.cpp:1328
static void ShutdownGame()
Uninitializes drivers, frees allocated memory, cleans pools, ... Generally, prepares the game for shu...
Definition openttd.cpp:294
static void LoadIntroGame(bool load_newgrfs=true)
Load the introduction game.
Definition openttd.cpp:325
static std::vector< OptionData > CreateOptions()
Create all the options that OpenTTD supports.
Definition openttd.cpp:477
void CallWindowGameTickEvent()
Dispatch OnGameTick event over all windows.
Definition window.cpp:3294
void CheckCaches()
Check the validity of some of the caches.
std::string _config_file
Configuration file of OpenTTD.
Definition settings.cpp:64
bool HandleBootstrap()
Handle all procedures for bootstrapping OpenTTD without a base graphics set.
static IntervalTimer< TimerGameRealtime > _autosave_interval({std::chrono::milliseconds::zero(), TimerGameRealtime::AUTOSAVE}, [](auto) { _pause_mode.Reset(PauseMode::CommandDuringPause);_do_autosave=true;SetWindowDirty(WC_STATUS_BAR, 0);static FiosNumberedSaveName _autosave_ctr("autosave");DoAutoOrNetsave(_autosave_ctr);_do_autosave=false;SetWindowDirty(WC_STATUS_BAR, 0);})
Interval for regular autosaves.
@ DO_FULL_ANIMATION
Perform palette animation.
Definition openttd.h:49
@ Normal
A game normally paused.
@ CommandDuringPause
A game paused, and a command executed during the pause; resets on autosave.
@ SaveLoad
A game paused for saving/loading.
GameMode
Mode which defines the state of the game.
Definition openttd.h:18
SwitchMode
Mode which defines what mode we're switching to.
Definition openttd.h:26
@ SM_START_HEIGHTMAP
Load a heightmap and start a new game from it.
Definition openttd.h:38
@ SM_RESTART_HEIGHTMAP
Load a heightmap and start a new game from it with current settings.
Definition openttd.h:40
@ SM_LOAD_SCENARIO
Load scenario from scenario editor.
Definition openttd.h:37
@ SM_GENRANDLAND
Generate random land within scenario editor.
Definition openttd.h:36
@ SM_JOIN_GAME
Join a network game.
Definition openttd.h:41
@ SM_MENU
Switch to game intro menu.
Definition openttd.h:33
@ SM_RESTARTGAME
Restart --> 'Random game' with current settings.
Definition openttd.h:29
@ SM_RELOADGAME
Reload the savegame / scenario / heightmap you started the game with.
Definition openttd.h:30
@ SM_SAVE_HEIGHTMAP
Save heightmap.
Definition openttd.h:35
@ SM_LOAD_HEIGHTMAP
Load heightmap from scenario editor.
Definition openttd.h:39
@ SM_SAVE_GAME
Save game.
Definition openttd.h:34
@ SM_LOAD_GAME
Load game, Play Scenario.
Definition openttd.h:32
@ SM_EDITOR
Switch to scenario editor.
Definition openttd.h:31
@ SM_NEWGAME
New Game --> 'Random game'.
Definition openttd.h:28
Functions related to modal progress.
bool HasModalProgress()
Check if we are currently in a modal progress state.
Definition progress.h:17
void InitializeRailGUI()
Resets the rail GUI - sets default railtype to build and resets the signal GUI.
Functions/types etc.
Pseudo random number generator.
declaration of OTTD revision dependent variables
void InitializeRoadGUI()
I really don't know why rail_gui.cpp has this too, shouldn't be included in the other one?
Functions/types related to the road GUIs.
Base class for roadstops.
Road vehicle states.
A number of safeguards to prevent using unsafe methods.
void ProcessAsyncSaveFinish()
Handle async save finishes.
Definition saveload.cpp:382
SaveOrLoadResult LoadWithFilter(std::shared_ptr< LoadFilter > reader)
Load the game using a (reader) filter.
bool _do_autosave
are we doing an autosave at the moment?
Definition saveload.cpp:72
void DoAutoOrNetsave(FiosNumberedSaveName &counter)
Create an autosave or netsave.
EncodedString GetSaveLoadErrorType()
Return the appropriate initial string for an error depending on whether we are saving or loading.
SaveOrLoadResult SaveOrLoad(std::string_view filename, SaveLoadOperation fop, DetailedFileType dft, Subdirectory sb, bool threaded)
Main Save or Load function where the high-level saveload functions are handled.
FileToSaveLoad _file_to_saveload
File to save or load in the openttd loop.
Definition saveload.cpp:66
void DoExitSave()
Do a save when exiting the game (_settings_client.gui.autosave_on_exit)
EncodedString GetSaveLoadErrorMessage()
Return the description of the error.
Functions/types related to saving and loading games.
SaveOrLoadResult
Save or load result codes.
Definition saveload.h:410
@ SL_OK
completed successfully
Definition saveload.h:411
@ SL_REINIT
error that was caught in the middle of updating game state, need to clear it. (can only happen during...
Definition saveload.h:413
SaveLoadVersion
SaveLoad versions Previous savegame versions, the trunk revision where they were introduced and the r...
Definition saveload.h:30
bool MakeHeightmapScreenshot(std::string_view filename)
Make a heightmap of the current map.
Functions to make screenshots.
void LoadFromConfig(bool startup)
Load the values from the configuration files.
void SaveToConfig()
Save the values to the configuration file.
VehicleDefaultSettings _old_vds
Used for loading default vehicles settings from old savegames.
Definition settings.cpp:63
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition settings.cpp:61
GameSettings _settings_newgame
Game settings for new games (updated from the intro screen).
Definition settings.cpp:62
ClientSettings _settings_client
The current settings for this game.
Definition settings.cpp:60
Functions related to setting/changing the settings.
Base for ships.
Interface definitions for game to report/respond to social integration.
Base for all sound drivers.
Base classes/functions for stations.
Definition of base types and functions in a cross-platform compatible way.
std::string FormatArrayAsHex(std::span< const uint8_t > data)
Format a byte array into a continuous hex string.
Definition string.cpp:75
Parse strings.
static std::optional< T > ParseInteger(std::string_view arg, int base=10, bool clamp=false)
Change a string into its number representation.
void CheckForMissingGlyphs(bool base_font, MissingGlyphSearcher *searcher)
Check whether the currently loaded language pack uses characters that the currently loaded font does ...
Definition strings.cpp:2353
EncodedString GetEncodedString(StringID str)
Encode a string with no parameters into an encoded string.
Definition strings.cpp:91
std::string GetString(StringID string)
Resolve the given StringID into a std::string with formatting but no parameters.
Definition strings.cpp:415
void InitializeLanguagePacks()
Make a list of the available language packs.
Definition strings.cpp:2201
Functions related to OTTD's strings.
Callback structure of statements to be executed after the NewGRF scan.
Definition openttd.cpp:374
std::string dedicated_host
Hostname for the dedicated server.
Definition openttd.cpp:377
TimerGameCalendar::Year startyear
The start year.
Definition openttd.cpp:375
void OnNewGRFsScanned() override
Called whenever the NewGRF scan completed.
Definition openttd.cpp:393
uint16_t dedicated_port
Port for the dedicated server.
Definition openttd.cpp:378
bool save_config
The save config setting.
Definition openttd.cpp:381
std::string connection_string
Information about the server to connect to.
Definition openttd.cpp:379
uint32_t generation_seed
Seed for the new game.
Definition openttd.cpp:376
std::string join_server_password
The password to join the server with.
Definition openttd.cpp:380
AfterNewGRFScan()
Create a new callback.
Definition openttd.cpp:386
Class to backup a specific variable and restore it later.
void Restore()
Restore the variable.
uint32_t extra_version
version of the extra GRF
static void SwitchMode(PersistentStorageMode mode, bool ignore_prev_mode=false)
Clear temporary changes made since the last call to SwitchMode, and set whether subsequent changes sh...
std::string name
The name of the base set.
CompanySettings company
default values for per-company settings
MusicSettings music
settings related to music/sound
NetworkSettings network
settings related to the network
GUISettings gui
settings related to the GUI
CompanySettings settings
settings specific for each company
VehicleDefaultSettings vehicle
default settings for vehicles
bool fix_at
mouse is moving, but cursor is not (used for scrolling)
Definition gfx_type.h:129
bool in_window
mouse inside this window, determines drawing logic
Definition gfx_type.h:148
Dimensions (a width and height) of a rectangle in 2D.
static bool ResetToCurrentNewGRFConfig()
Tries to reset the engine mapping to match the current NewGRF configuration.
Definition engine.cpp:585
void SetMode(const FiosType &ft, SaveLoadOperation fop=SLO_LOAD)
Set the mode and file type of the file to save or load.
FiosType ftype
File type.
Definition saveload.h:419
SaveLoadOperation file_op
File operation to perform.
Definition saveload.h:418
std::string name
Name of the file.
Definition saveload.h:420
A savegame name automatically numbered.
Definition fios.h:129
DetailedFileType detailed
Detailed file type.
Definition fileio_type.h:64
AbstractFileType abstract
Abstract file type.
Definition fileio_type.h:63
Information about GRF, used in the game and (part of it) in savegames.
bool IsCompatible(uint32_t old_version) const
Return whether this NewGRF can replace an older version of the same NewGRF.
uint64_t used_liveries
Bitmask of LiveryScheme used by the defined engines.
Definition newgrf.h:190
uint32_t last_newgrf_count
the numbers of NewGRFs we found during the last scan
Colours starting_colour_secondary
default secondary color scheme for the company to start a new game with
bool autosave_on_exit
save an autosave when you quit the game, but do not ask "Do you really want to quit?...
bool pause_on_newgame
whether to start new games paused or not
uint32_t autosave_interval
how often should we do autosaves?
Colours starting_colour
default color scheme for the company to start a new game with
uint8_t map_x
X size of map.
uint8_t map_y
Y size of map.
TimerGameCalendar::Year starting_year
starting date
uint32_t generation_seed
noise seed for world generation
std::chrono::steady_clock::time_point start_time
Time when the current game was started.
Definition openttd.h:56
std::optional< size_t > savegame_size
Size of the last saved savegame in bytes, or std::nullopt if not saved yet.
Definition openttd.h:58
GameCreationSettings game_creation
settings used during the creation of a game (map)
ScriptConfigSettings script_config
AI and Gamescript configuration.
VehicleSettings vehicle
options for vehicles
Data storage for parsing command line options.
Definition getoptdata.h:29
std::string_view opt
Option value, if available (else empty).
Definition getoptdata.h:35
ArgumentSpan arguments
Remaining command line arguments.
Definition getoptdata.h:33
int GetOpt()
Find the next option.
GRFConfig & GetOrCreateExtraConfig() const
Return configuration for the extra GRF, or lazily create it.
Definition gfxinit.cpp:378
Defines the internal data of a functional industry.
Definition industry.h:64
bool HasNewGrfs()
Check whether the game uses any NewGrfs.
Definition fios.h:67
std::string error_msg
Data to pass to string parameters when displaying error.
Definition fios.h:36
StringID error
Error message from loading. INVALID_STRING_ID if no error.
Definition fios.h:35
bool HasErrors()
Check whether loading the game resulted in errors.
Definition fios.h:58
void Clear()
Reset read data.
Definition fios_gui.cpp:49
static uint SizeY()
Get the size of the map along the Y.
Definition map_func.h:278
static debug_inline uint SizeX()
Get the size of the map along the X.
Definition map_func.h:269
uint8_t effect_vol
The requested effects volume.
uint8_t music_vol
The requested music volume.
bool reload_cfg
reload the config file before restarting
uint16_t server_port
port the server listens on
std::string last_joined
Last joined server.
ParticipateSurvey participate_survey
Participate in the automated survey.
Callback for NewGRF scanning.
static void Clean(PoolTypes)
Clean all pools of given type.
Definition pool_func.cpp:30
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
static Titem * Get(auto index)
Returns Titem with given index.
std::unique_ptr< class GameConfig > game
settings for gamescript
ReferenceThroughBaseContainer< std::array< std::unique_ptr< class AIConfig >, MAX_COMPANIES > > ai
settings per company
Templated helper to make a type-safe 'typedef' representing a single POD value.
bool disable_elrails
when true, the elrails are disabled
static void SaveToConfig()
Save all WindowDesc settings to _windows_file.
Definition window.cpp:175
static void LoadFromConfig()
Load all WindowDesc settings from _windows_file.
Definition window.cpp:154
Functions related to subsidies.
Definition of Interval and OneShot timers.
Definition of the game-calendar-timer.
Definition of the game-economy-timer.
Definition of the real time game-timer.
Definition of the tick-based game-timer.
Base of the town class.
Base for the train class.
uint8_t _display_opt
What do we want to draw/do?
void RunVehicleCalendarDayProc()
Age all vehicles, spreading out the action using the current TimerGameCalendar::date_fract.
Definition vehicle.cpp:907
Functions related to vehicles.
Base of all video drivers.
void InitializeSpriteSorter()
Choose the "best" sprite sorter and set _vp_sprite_sorter.
Functions related to (drawing on) viewports.
Types related to sprite sorting.
std::wstring OTTD2FS(std::string_view name)
Convert from OpenTTD's encoding to a wide string.
Definition win32.cpp:354
std::string FS2OTTD(std::wstring_view name)
Convert to OpenTTD's encoding from a wide string.
Definition win32.cpp:337
void CloseWindowById(WindowClass cls, WindowNumber number, bool force, int data)
Close a window by its class and window number (if it is open).
Definition window.cpp:1182
void ResetWindowSystem()
Reset the windowing system, by means of shutting it down followed by re-initialization.
Definition window.cpp:1863
void UnInitWindowSystem()
Close down the windowing system.
Definition window.cpp:1849
void InitWindowSystem()
(re)initialize the windowing system
Definition window.cpp:1827
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting)
Definition window.cpp:3147
@ WC_STATUS_BAR
Statusbar (at the bottom of your screen); Window numbers:
Definition window_type.h:66
@ WC_SAVELOAD
Saveload window; Window numbers:
@ Min
Minimum zoom level.