/** * Setups the game environment and enters * the titlescreen or game loops. */ static int do_gameloop(const std::vector<std::string>& args) { srand(time(nullptr)); commandline_options cmdline_opts = commandline_options(args); game_config::wesnoth_program_dir = filesystem::directory_name(args[0]); int finished = process_command_args(cmdline_opts); if(finished != -1) { return finished; } boost::scoped_ptr<game_launcher> game( new game_launcher(cmdline_opts,args[0].c_str())); const int start_ticks = SDL_GetTicks(); init_locale(); bool res; // do initialize fonts before reading the game config, to have game // config error messages displayed. fonts will be re-initialized later // when the language is read from the game config. res = font::load_font_config(); if(res == false) { std::cerr << "could not initialize fonts\n"; // The most common symptom of a bogus data dir path -- warn the user. warn_early_init_failure(); return 1; } res = game->init_language(); if(res == false) { std::cerr << "could not initialize the language\n"; return 1; } res = game->init_video(); if(res == false) { std::cerr << "could not initialize display\n"; return 1; } res = image::update_from_preferences(); if(res == false) { std::cerr << "could not initialize image preferences\n"; return 1; } if(preferences::joystick_support_enabled()) { res = game->init_joystick(); if(res == false) { std::cerr << "could not initialize joystick\n"; } } check_fpu(); const cursor::manager cursor_manager; cursor::set(cursor::WAIT); #if (defined(_X11) && !defined(__APPLE__)) || defined(_WIN32) SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE); #endif gui2::init(); const gui2::event::tmanager gui_event_manager; game_config_manager config_manager(cmdline_opts, game->video(), game->jump_to_editor()); gui2::tloadscreen::display(game->video(), [&res, &config_manager]() { gui2::tloadscreen::progress("load config"); res = config_manager.init_game_config(game_config_manager::NO_FORCE_RELOAD); if(res == false) { std::cerr << "could not initialize game config\n"; return; } gui2::tloadscreen::progress("init fonts"); res = font::load_font_config(); if(res == false) { std::cerr << "could not re-initialize fonts for the current language\n"; return; } gui2::tloadscreen::progress("refresh addons"); refresh_addon_version_info_cache(); }); if(res == false) { return 1; } config tips_of_day; LOG_CONFIG << "time elapsed: "<< (SDL_GetTicks() - start_ticks) << " ms\n"; plugins_manager plugins_man(new application_lua_kernel(&game->video())); plugins_context::Reg const callbacks[] = { { "play_multiplayer", std::bind(&game_launcher::play_multiplayer, game.get())}, }; plugins_context::aReg const accessors[] = { { "command_line", std::bind(&commandline_options::to_config, &cmdline_opts)}, }; plugins_context plugins("titlescreen", callbacks, accessors); plugins.set_callback("exit", std::bind(&safe_exit, std::bind(get_int, std::placeholders::_1, "code", 0)), false); for (;;) { // reset the TC, since a game can modify it, and it may be used // by images in add-ons or campaigns dialogs image::set_team_colors(); statistics::fresh_stats(); if (!game->is_loading()) { const config &cfg = config_manager.game_config().child("titlescreen_music"); if (cfg) { sound::play_music_repeatedly(game_config::title_music); for (const config &i : cfg.child_range("music")) { sound::play_music_config(i); } sound::commit_music_changes(); } else { sound::empty_playlist(); sound::stop_music(); } } handle_lua_script_args(&*game,cmdline_opts); plugins.play_slice(); plugins.play_slice(); if(cmdline_opts.unit_test) { if(cmdline_opts.timeout) { std::cerr << "The wesnoth built-in timeout feature has been removed.\n" << std::endl; std::cerr << "Please use a platform-specific script which will kill the overtime process instead.\n" << std::endl; std::cerr << "For examples in bash, or in windows cmd, see the forums, or the wesnoth repository." << std::endl; std::cerr << "The bash script is called `run_wml_tests`, the windows script is part of the VC project.\n" << std::endl; } int worker_result = game->unit_test(); std::cerr << ((worker_result == 0) ? "PASS TEST " : "FAIL TEST ") << ((worker_result == 3) ? "(INVALID REPLAY)" : "") << ((worker_result == 4) ? "(ERRORED REPLAY)" : "") << ": "<<*cmdline_opts.unit_test << std::endl; return worker_result; } if(game->play_test() == false) { return 0; } if(game->play_screenshot_mode() == false) { return 0; } if(game->play_render_image_mode() == false) { return 0; } //Start directly a campaign if(game->goto_campaign() == false){ if (game->jump_to_campaign_id().empty()) continue; //Go to main menu else return 1; //we got an error starting the campaign from command line } //Start directly a multiplayer //Eventually with a specified server if(game->goto_multiplayer() == false){ continue; //Go to main menu } //Start directly a commandline multiplayer game if(game->play_multiplayer_commandline() == false) { return 0; } if (game->goto_editor() == false) { return 0; } gui2::ttitle_screen::tresult res = game->is_loading() ? gui2::ttitle_screen::LOAD_GAME : gui2::ttitle_screen::NOTHING; preferences::load_hotkeys(); const font::floating_label_context label_manager; cursor::set(cursor::NORMAL); if(res == gui2::ttitle_screen::NOTHING) { gui2::ttitle_screen dlg; dlg.show(game->video()); res = static_cast<gui2::ttitle_screen::tresult>(dlg.get_retval()); } game_launcher::RELOAD_GAME_DATA should_reload = game_launcher::RELOAD_DATA; if(res == gui2::ttitle_screen::QUIT_GAME) { LOG_GENERAL << "quitting game...\n"; return 0; } else if(res == gui2::ttitle_screen::LOAD_GAME) { if(game->load_game() == false) { game->clear_loaded_game(); res = gui2::ttitle_screen::NOTHING; continue; } should_reload = game_launcher::NO_RELOAD_DATA; } else if(res == gui2::ttitle_screen::TUTORIAL) { game->set_tutorial(); } else if(res == gui2::ttitle_screen::NEW_CAMPAIGN) { if(game->new_campaign() == false) { continue; } should_reload = game_launcher::NO_RELOAD_DATA; } else if(res == gui2::ttitle_screen::MULTIPLAYER) { game_config::debug = game_config::mp_debug; if(game->play_multiplayer() == false) { continue; } } else if(res == gui2::ttitle_screen::CHANGE_LANGUAGE) { try { if (game->change_language()) { tips_of_day.clear(); t_string::reset_translations(); image::flush_cache(); } } catch ( std::runtime_error & e ) { gui2::show_error_message(game->video(), e.what()); } continue; } else if(res == gui2::ttitle_screen::EDIT_PREFERENCES) { game->show_preferences(); continue; } else if(res == gui2::ttitle_screen::SHOW_ABOUT) { about::show_about(game->video()); continue; } else if(res == gui2::ttitle_screen::SHOW_HELP) { help::help_manager help_manager(&config_manager.game_config()); help::show_help(game->video()); continue; } else if(res == gui2::ttitle_screen::GET_ADDONS) { // NOTE: we need the help_manager to get access to the Add-ons // section in the game help! help::help_manager help_manager(&config_manager.game_config()); if(manage_addons(game->video())) { config_manager.reload_changed_game_config(); } continue; } else if(res == gui2::ttitle_screen::CORES) { int current = 0; std::vector<config> cores; for (const config& core : game_config_manager::get()->game_config().child_range("core")) { cores.push_back(core); if (core["id"] == preferences::core_id()) current = cores.size() -1; } gui2::tcore_selection core_dlg(cores, current); if (core_dlg.show(game->video())) { int core_index = core_dlg.get_choice(); const std::string& core_id = cores[core_index]["id"]; preferences::set_core_id(core_id); config_manager.reload_changed_game_config(); } continue; } else if(res == gui2::ttitle_screen::RELOAD_GAME_DATA) { gui2::tloadscreen::display(game->video(), [&config_manager]() { config_manager.reload_changed_game_config(); image::flush_cache(); }); continue; } else if(res == gui2::ttitle_screen::START_MAP_EDITOR) { game->start_editor(); continue; } game->launch_game(should_reload); } }
void title_screen::pre_show(window& win) { win.set_click_dismiss(false); win.set_enter_disabled(true); win.set_escape_disabled(true); // Each time the dialog shows, we set this to false redraw_background_ = false; #ifdef DEBUG_TOOLTIP win.connect_signal<event::SDL_MOUSE_MOTION>( std::bind(debug_tooltip, std::ref(win), _3, _5), event::dispatcher::front_child); #endif win.connect_signal<event::SDL_VIDEO_RESIZE>(std::bind(&title_screen::on_resize, this, std::ref(win))); // // General hotkeys // win.register_hotkey(hotkey::TITLE_SCREEN__RELOAD_WML, [](event::dispatcher& w, hotkey::HOTKEY_COMMAND) { dynamic_cast<window&>(w).set_retval(RELOAD_GAME_DATA); return true; }); win.register_hotkey(hotkey::HOTKEY_FULLSCREEN, std::bind(fullscreen, std::ref(win.video()))); win.register_hotkey(hotkey::LUA_CONSOLE, std::bind(&launch_lua_console, std::ref(win))); // // Background and logo images // if(game_config::images::game_title.empty()) { ERR_CF << "No title image defined" << std::endl; } win.get_canvas()[0].set_variable("title_image", variant(game_config::images::game_title)); if(game_config::images::game_title_background.empty()) { ERR_CF << "No title background image defined" << std::endl; } win.get_canvas()[0].set_variable("background_image", variant(game_config::images::game_title_background)); find_widget<image>(&win, "logo-bg", false).set_image(game_config::images::game_logo_background); find_widget<image>(&win, "logo", false).set_image(game_config::images::game_logo); // // Version string // const std::string version_string = formatter() << ("Version") << " " << game_config::revision; if(label* version_label = find_widget<label>(&win, "revision_number", false, false)) { version_label->set_label(version_string); } win.get_canvas()[0].set_variable("revision_number", variant(version_string)); // // Tip-of-the-day browser // multi_page& tip_pages = find_widget<multi_page>(&win, "tips", false); std::vector<game_tip> tips(settings::get_tips()); if(tips.empty()) { WRN_CF << "There are no tips of day available." << std::endl; } for(const auto& tip : tips) { string_map widget; std::map<std::string, string_map> page; widget["use_markup"] = "true"; widget["label"] = tip.text(); page.emplace("tip", widget); widget["label"] = tip.source(); page.emplace("source", widget); tip_pages.add_page(page); } update_tip(win, true); register_button(win, "next_tip", hotkey::TITLE_SCREEN__NEXT_TIP, std::bind(&title_screen::update_tip, this, std::ref(win), true)); register_button(win, "previous_tip", hotkey::TITLE_SCREEN__PREVIOUS_TIP, std::bind(&title_screen::update_tip, this, std::ref(win), false)); // // Help // register_button(win, "help", hotkey::HOTKEY_HELP, [this](window&) { help::help_manager help_manager(&game_config_manager::get()->game_config()); help::show_help(game_.video()); }); // // About // register_button(win, "about", hotkey::HOTKEY_NULL, std::bind(&game_version::display, std::ref(win.video()))); // // Tutorial // register_button(win, "tutorial", hotkey::TITLE_SCREEN__TUTORIAL, [this](window& w) { game_.set_tutorial(); w.set_retval(LAUNCH_GAME); }); // // Campaign // register_button(win, "campaign", hotkey::TITLE_SCREEN__CAMPAIGN, [this](window& w) { try{ if(game_.new_campaign()) { w.set_retval(LAUNCH_GAME); } } catch (const config::error& e) { gui2::show_error_message(game_.video(), e.what()); } }); // // Multiplayer // register_button(win, "multiplayer", hotkey::TITLE_SCREEN__MULTIPLAYER, [this](window& w) { while(true) { gui2::dialogs::mp_method_selection dlg; dlg.show(game_.video()); if(dlg.get_retval() != gui2::window::OK) { return; } const int res = dlg.get_choice(); if(res == 2 && preferences::mp_server_warning_disabled() < 2) { if(!gui2::dialogs::mp_host_game_prompt::execute(game_.video())) { continue; } } switch(res) { case 0: game_.select_mp_server(preferences::server_list().front().address); w.set_retval(MP_CONNECT); break; case 1: game_.select_mp_server(""); w.set_retval(MP_CONNECT); break; case 2: game_.select_mp_server("localhost"); w.set_retval(MP_HOST); break; case 3: w.set_retval(MP_LOCAL); break; } return; } }); // // Load game // register_button(win, "load", hotkey::HOTKEY_LOAD_GAME, [this](window& w) { if(game_.load_game()) { w.set_retval(LAUNCH_GAME); } else { game_.clear_loaded_game(); } }); // // Addons // register_button(win, "addons", hotkey::TITLE_SCREEN__ADDONS, [this](window&) { // NOTE: we need the help_manager to get access to the Add-ons section in the game help! help::help_manager help_manager(&game_config_manager::get()->game_config()); if(manage_addons(game_.video())) { game_config_manager::get()->reload_changed_game_config(); } }); // // Editor // register_button(win, "editor", hotkey::TITLE_SCREEN__EDITOR, [&](window& w) { w.set_retval(MAP_EDITOR); }); // // Cores // register_button(win, "cores", hotkey::TITLE_SCREEN__CORES, [this](window&) { int current = 0; std::vector<config> cores; for(const config& core : game_config_manager::get()->game_config().child_range("core")) { cores.push_back(core); if(core["id"] == preferences::core_id()) { current = cores.size() - 1; } } gui2::dialogs::core_selection core_dlg(cores, current); if(core_dlg.show(game_.video())) { const std::string& core_id = cores[core_dlg.get_choice()]["id"]; preferences::set_core_id(core_id); game_config_manager::get()->reload_changed_game_config(); } }); if(game_config_manager::get()->game_config().child_range("core").size() <= 1) { find_widget<button>(&win, "cores", false).set_visible(window::visibility::invisible); } // // Language // register_button(win, "language", hotkey::HOTKEY_LANGUAGE, [this](window& w) { try { if(game_.change_language()) { t_string::reset_translations(); ::image::flush_cache(); on_resize(w); } } catch(std::runtime_error& e) { gui2::show_error_message(game_.video(), e.what()); } }); // // Preferences // register_button(win, "preferences", hotkey::HOTKEY_PREFERENCES, [this](window&) { game_.show_preferences(); }); // // Credits // register_button(win, "credits", hotkey::TITLE_SCREEN__CREDITS, [&](window& w) { w.set_retval(SHOW_ABOUT); }); // // Quit // register_button(win, "quit", hotkey::HOTKEY_QUIT_TO_DESKTOP, [&](window& w) { w.set_retval(QUIT_GAME); }); // // Debug clock // register_button(win, "clock", hotkey::HOTKEY_NULL, std::bind(&title_screen::show_debug_clock_window, this, std::ref(win.video()))); find_widget<button>(&win, "clock", false).set_visible(show_debug_clock_button ? widget::visibility::visible : widget::visibility::invisible); }