16 #include "addon/manager.hpp"
72 #include <boost/program_options/errors.hpp>
73 #include <boost/algorithm/string/predicate.hpp>
92 #ifdef INADDR_BROADCAST
93 #undef INADDR_BROADCAST
105 #define main SDL_main
108 #ifdef DEBUG_WINDOW_LAYOUT_GRAPHS
117 #define LOG_CONFIG LOG_STREAM(info, log_config)
119 #define LOG_GENERAL LOG_STREAM(info, lg::general())
122 #define LOG_PREPROC LOG_STREAM(info, log_preprocessor)
140 PLAIN_LOG <<
"please specify an existing file. File " << file <<
" doesn't exist.";
144 PLAIN_LOG <<
"Reading cached defines from: " << file;
151 PLAIN_LOG <<
"Caught a config error while parsing file '" << file <<
"':\n" <<
e.message;
159 defines_map[def.first] = def.second;
185 [](
const auto& timer) {
PLAIN_LOG <<
"preprocessing finished. Took " << timer <<
" ticks."; });
187 PLAIN_LOG <<
"added " << defines_map.size() <<
" defines.";
197 PLAIN_LOG <<
"please specify an existing file. File " << file <<
" doesn't exist.";
201 PLAIN_LOG <<
"Reading cached defines from: " << file;
208 PLAIN_LOG <<
"Caught a config error while parsing file '" << file <<
"':\n" <<
e.message;
216 input_macros[def.first] = def.second;
227 [](
const auto& timer) {
PLAIN_LOG <<
"preprocessing finished. Took " << timer <<
" ticks."; });
230 bool skipCore =
false;
231 bool skipTerrainGFX =
false;
247 if(define ==
"SKIP_CORE") {
250 }
else if(define ==
"NO_TERRAIN_GFX") {
251 PLAIN_LOG <<
"'NO_TERRAIN_GFX' defined.";
252 skipTerrainGFX =
true;
260 PLAIN_LOG <<
"added " << defines_map.size() <<
" defines.";
263 if(skipCore ==
false) {
264 PLAIN_LOG <<
"preprocessing common macros from 'data/core' ...";
269 if(skipTerrainGFX ==
false) {
273 PLAIN_LOG <<
"acquired " << (defines_map.size() - input_macros.size()) <<
" 'data/core' defines.";
279 PLAIN_LOG <<
"preprocessing specified resource: " << resourceToProcess <<
" ...";
282 PLAIN_LOG <<
"acquired " << (defines_map.size() - input_macros.size()) <<
" total defines.";
285 std::string outputFileName =
"_MACROS_.cfg";
290 std::string outputPath = targetDir +
"/" + outputFileName;
292 PLAIN_LOG <<
"writing '" << outputPath <<
"' with " << defines_map.size() <<
" defines.";
298 for(
auto& define_pair : defines_map) {
299 define_pair.second.write(writer, define_pair.first);
312 for(
const std::string& define : defines) {
325 std::cout <<
"validation failed\n";
327 std::cout <<
"validation succeeded\n";
336 if(cmdline_opts.
help) {
337 std::cout << cmdline_opts;
382 && !getenv(
"WESNOTH_NO_LOG_FILE")
393 && !cmdline_opts.
nogui
406 else if(!cmdline_opts.no_console) {
411 if(cmdline_opts.
log) {
412 for(
const auto& log_pair : *cmdline_opts.
log) {
413 const std::string log_domain = log_pair.second;
416 PLAIN_LOG <<
"unknown log domain: " << log_domain;
423 const auto now = std::chrono::system_clock::now();
446 game_config::path = SDL_AndroidGetExternalStoragePath() + std::string(
"/gamedata");
453 PLAIN_LOG <<
"Automatically found a possible data directory at: " << auto_dir;
458 PLAIN_LOG <<
"Cannot find game data directory. Specify one with --data-dir";
499 SDL_setenv(
"SDL_VIDEODRIVER",
"dummy", 1);
518 std::ifstream in_left(cmdline_opts.
diff_left);
519 std::ifstream in_right(cmdline_opts.
diff_right);
522 std::ostream* os = &std::cout;
528 if(os != &std::cout)
delete os;
533 std::ifstream in_base(cmdline_opts.
diff_left);
534 std::ifstream in_diff(cmdline_opts.
diff_right);
538 std::ostream* os = &std::cout;
544 if(os != &std::cout)
delete os;
567 std::string schema_path;
572 schema_path = check.value();
574 PLAIN_LOG <<
"Could not find schema file: " << schema_path;
591 PLAIN_LOG <<
"That --preprocess-* option is only supported when using --preprocess or --validate.";
607 #if defined _WIN32 || defined __APPLE__
608 setlocale(LC_ALL,
"English");
610 std::setlocale(LC_ALL,
"C");
633 <<
"An error at this point during initialization usually indicates that the data\n"
634 <<
"directory above was not correctly set or detected. Try passing the correct path\n"
635 <<
"in the command line with the --data-dir switch or as the only argument.";
644 static bool first_time =
true;
652 if(!
game->init_lua_script()) {
663 if(_controlfp_s(&f_control, 0, 0) == 0) {
665 uint32_t rounding_mode = f_control & _MCW_RC;
667 if(rounding_mode != _RC_NEAR) {
668 PLAIN_LOG <<
"Floating point rounding mode is currently '"
669 << ((rounding_mode == _RC_CHOP)
671 : (rounding_mode == _RC_UP)
673 : (rounding_mode == _RC_DOWN)
675 : (rounding_mode == _RC_NEAR) ?
"near" :
"unknown")
676 <<
"' setting to 'near'";
678 if(_controlfp_s(&unused, _RC_NEAR, _MCW_RC)) {
679 PLAIN_LOG <<
"failed to set floating point rounding type to 'near'";
684 uint32_t precision_mode = f_control & _MCW_PC;
685 if(precision_mode != _PC_53) {
686 PLAIN_LOG <<
"Floating point precision mode is currently '"
687 << ((precision_mode == _PC_53)
689 : (precision_mode == _PC_24)
691 : (precision_mode == _PC_64) ?
"double extended" :
"unknown")
692 <<
"' setting to 'double'";
694 if(_controlfp_s(&unused, _PC_53, _MCW_PC)) {
695 PLAIN_LOG <<
"failed to set floating point precision type to 'double'";
707 switch(fegetround()) {
711 STREAMING_LOG <<
"Floating point precision mode is currently 'downward'";
714 STREAMING_LOG <<
"Floating point precision mode is currently 'toward-zero'";
717 STREAMING_LOG <<
"Floating point precision mode is currently 'upward'";
720 STREAMING_LOG <<
"Floating point precision mode is currently 'unknown'";
724 fesetround(FE_TONEAREST);
736 srand(std::time(
nullptr));
738 const auto game = std::make_unique<game_launcher>(cmdline_opts);
749 PLAIN_LOG <<
"could not initialize fonts";
755 res =
game->init_language();
757 PLAIN_LOG <<
"could not initialize the language";
761 res =
game->init_video();
763 PLAIN_LOG <<
"could not initialize display";
771 #if(defined(_X11) && !defined(__APPLE__)) || defined(_WIN32)
772 SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE);
785 std::string
msg =
VGETTEXT(
"Unable to create log files in directory $logdir. This is often caused by incorrect folder permissions, anti-virus software restricting folder access, or using OneDrive to manage your My Documents folder.", symbols);
801 PLAIN_LOG <<
"could not initialize game config";
809 PLAIN_LOG <<
"could not re-initialize fonts for the current language";
841 if(!
game->has_load_data()) {
848 config title_music_config;
850 title_music_config[
"append"] =
true;
851 title_music_config[
"immediate"] =
true;
865 return static_cast<int>(
game->unit_test());
868 if(
game->play_test() ==
false) {
872 if(
game->play_screenshot_mode() ==
false) {
876 if(
game->play_render_image_mode() ==
false) {
881 if(
game->goto_campaign() ==
false) {
882 if(
game->jump_to_campaign_id().empty())
890 if(
game->goto_multiplayer() ==
false) {
895 if(
game->play_multiplayer_commandline() ==
false) {
899 if(
game->goto_editor() ==
false) {
908 if(
game->has_load_data() &&
game->load_game()) {
947 game->start_editor();
962 #define error_exit(res) \
964 if(lg::using_own_console()) { \
965 std::cerr << "Press enter to continue..." << std::endl; \
971 #define error_exit(res) return res
978 int main(
int argc,
char** argv)
983 assert(!args.empty());
986 _putenv(
"PANGOCAIRO_BACKEND=fontconfig");
987 _putenv(
"FONTCONFIG_PATH=fonts");
992 setenv(
"PANGOCAIRO_BACKEND",
"fontconfig", 0);
995 setenv(
"PANGOCAIRO_BACKEND",
"fontconfig", 0);
996 setenv(
"SDL_HINT_AUDIODRIVER",
"android", 0);
1003 if(finished != -1) {
1006 std::cerr <<
"Press enter to continue..." << std::endl;
1013 SDL_SetHint(SDL_HINT_NO_SIGNAL_HANDLERS,
"1");
1015 if(SDL_Init(SDL_INIT_TIMER) < 0) {
1016 PLAIN_LOG <<
"Couldn't initialize SDL: " << SDL_GetError();
1023 #if defined(__APPLE__) && !defined(__IPHONEOS__)
1024 SDL_EventState(SDL_FINGERMOTION, SDL_DISABLE);
1025 SDL_EventState(SDL_FINGERDOWN, SDL_DISABLE);
1026 SDL_EventState(SDL_FINGERUP, SDL_DISABLE);
1033 SDL_StartTextInput();
1037 }
catch(
const boost::program_options::error&
e) {
1039 std::cerr <<
"Error in command line: " <<
e.what() << std::endl;
1040 std::string error =
"Error parsing command line arguments: ";
1042 SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR,
"Error", error.c_str(),
nullptr);
1045 PLAIN_LOG <<
"Video system error: " <<
e.what();
1048 PLAIN_LOG <<
"Could not initialize fonts.\n\n" <<
e.what() <<
"\n\nExiting.";
1056 PLAIN_LOG <<
"caught return_to_play_side_exception, please report this bug (quitting)";
1058 PLAIN_LOG <<
"caught quit_game_exception (quitting)";
1060 PLAIN_LOG <<
"WML exception:\nUser message: " <<
e.user_message <<
"\nDev message: " <<
e.dev_message;
1063 PLAIN_LOG <<
e.what() <<
"\n\nGame will be aborted.";
1071 }
catch(
const std::bad_alloc&) {
1072 PLAIN_LOG <<
"Ran out of memory. Aborted.";
1074 #if !defined(NO_CATCH_AT_GAME_END)
1075 }
catch(
const std::exception&
e) {
1077 PLAIN_LOG <<
"Caught general '" <<
typeid(
e).name() <<
"' exception:\n" <<
e.what();
1079 }
catch(
const std::string&
e) {
1080 PLAIN_LOG <<
"Caught a string thrown as an exception:\n" <<
e;
1082 }
catch(
const char*
e) {
1083 PLAIN_LOG <<
"Caught a string thrown as an exception:\n" <<
e;
int wesnoth_main(int argc, char **argv)
void refresh_addon_version_info_cache()
Refreshes the per-session cache of add-on's version information structs.
Used in parsing config file.
bool nogui
True if –nogui was given on the command line.
utils::optional< std::string > validate_wml
Non-empty if –validate was given on the command line.
bool simple_version
True if –simple-version was given on the command line.
bool report
True if –report was given on the command line.
bool headless_unit_test
True if –unit is used and –showgui is not present.
bool no_log_sanitize
True if –no-log-sanitize was given on the command line.
bool strict_lua
True if –strict-lua was given in the commandline.
utils::optional< std::vector< std::string > > preprocess_defines
Defines that were given to the –preprocess option.
utils::optional< std::string > usercache_dir
Non-empty if –usercache-dir was given on the command line.
utils::optional< std::string > validate_schema
Non-empty if –validate-schema was given on the command line.
utils::optional< std::string > userdata_dir
Non-empty if –userdata-dir was given on the command line.
bool nobanner
True if –nobanner was given on the command line.
utils::optional< std::vector< std::pair< lg::severity, std::string > > > log
Contains parsed arguments of –log-* (e.g.
utils::optional< std::string > generate_spritesheet
Path of which to generate a spritesheet.
utils::optional< std::string > render_image
Image path to render.
utils::optional< std::string > logdomains
Non-empty if –logdomains was given on the command line.
utils::optional< std::string > preprocess_input_macros
Non-empty if –preprocess-input-macros was given on the command line.
bool preprocess
True if –preprocess was given on the command line.
utils::optional< unsigned int > rng_seed
RNG seed specified by –rng-seed option.
std::string diff_left
Files for diffing or patching.
bool data_path
True if –data-path was given on the command line.
bool version
True if –version was given on the command line.
bool allow_insecure
True if –allow-insecure was given in the commandline.
utils::optional< std::string > validate_with
Non-empty if –use-schema was given on the command line.
bool noaddons
True if –noaddons was given on the command line.
utils::optional< std::string > output_file
Output filename for WML diff or preprocessing.
utils::optional< std::string > data_dir
Non-empty if –data-dir was given on the command line.
utils::optional< std::string > preprocess_target
Target (output) path that was given to the –preprocess option.
bool screenshot
True if –screenshot was given on the command line.
bool log_to_file
True if –log-to-file was given on the command line.
bool debug_lua
True if –debug-lua was given in the commandline.
std::vector< std::string > unit_test
Non-empty if –unit was given on the command line.
bool userdata_path
True if –userdata-path was given on the command line.
bool log_precise_timestamps
True if –log-precise was given on the command line.
utils::optional< std::string > preprocess_source_string
String to preprocess.
bool no_log_to_file
True if –no-log-to-file was given on the command line.
utils::optional< std::string > preprocess_output_macros
Non-empty if –preprocess-output-macros was given on the command line.
bool strict_validation
True if –strict-validation was given on the command line.
utils::optional< std::string > preprocess_path
Path to parse that was given to the –preprocess option.
bool help
True if –help was given on the command line.
bool usercache_path
True if –usercache-path was given on the command line.
Class for writing a config out to a file in pieces.
void write(const config &cfg)
A config object defines a single node in a WML file, with access to child nodes.
auto all_children_view() const
In-order iteration over all children.
child_itors child_range(config_key_type key)
void apply_diff(const config &diff, bool track=false)
A function to apply a diff config onto this config object.
config get_diff(const config &c) const
A function to get the differences between this object, and 'c', as another config object.
@ NO_FORCE_RELOAD
Don't reload if the previous defines equal the new defines.
bool init_game_config(FORCE_RELOAD_CONFIG force_reload)
void reload_changed_game_config()
const game_config_view & game_config() const
optional_const_config optional_child(config_key_type key) const
bool play_multiplayer(mp_mode mode)
static void progress(loading_stage stage=loading_stage::none)
Report what is being loaded to the loading screen.
static void display(const std::function< void()> &f)
@ ok_button
Shows an ok button.
bool show(const unsigned auto_close_time=0)
Shows the window.
This class implements the title screen.
std::vector< Reg > reg_vec
std::vector< aReg > areg_vec
void set_callback(const std::string &name, callback_function)
Exception used to escape form the ai or ui code to playsingle_controller::play_side.
Realization of serialization/validator.hpp abstract validator.
std::string str() const
Serializes the version number into string form.
Type that can be thrown as an exception to quit to desktop.
std::vector< std::string > read_argv([[maybe_unused]] int argc, [[maybe_unused]] char **argv)
Definitions for the interface to Wesnoth Markup Language (WML).
Declarations for File-IO.
Contains the exception interfaces used to signal completion of a scenario, campaign or turn.
Interfaces for manipulating version numbers of engine, add-ons, etc.
static std::string _(const char *str)
Standard logging facilities (interface).
auto format_local_timestamp(const std::chrono::system_clock::time_point &time, std::string_view format="%F %T")
void set(CURSOR_TYPE type)
Use the default parameter to reset cursors.
std::string get_cache_dir()
filesystem::scoped_istream istream_file(const std::string &fname, bool treat_failure_as_error)
std::string get_user_data_dir()
static bool file_exists(const bfs::path &fpath)
std::string get_exe_dir()
bool is_directory(const std::string &fname)
Returns true if the given file is a directory.
utils::optional< std::string > get_wml_location(const std::string &path, const utils::optional< std::string > ¤t_dir)
Returns a translated path to the actual file or directory, if it exists.
filesystem::scoped_ostream ostream_file(const std::string &fname, std::ios_base::openmode mode, bool create_directory)
std::string autodetect_game_data_dir(std::string exe_dir)
Try to autodetect the location of the game data dir.
void set_cache_dir(const std::string &newcachedir)
std::string get_logs_dir()
std::unique_ptr< std::ostream > scoped_ostream
bool is_userdata_initialized()
std::string get_intl_dir()
std::string normalize_path(const std::string &fpath, bool normalize_separators, bool resolve_dot_entries)
Returns the absolute path of a file.
void set_user_data_dir(std::string newprefdir)
std::string full_build_report()
Produce a bug report-style info dump.
std::string library_versions_report()
Produce a plain-text report of library versions suitable for stdout/stderr.
const version_info wesnoth_version(VERSION)
std::string build_arch()
Obtain the processor architecture for this build.
std::string optional_features_report()
Produce a plain-text report of features suitable for stdout/stderr.
const std::string revision
void init()
Initializes the GUI subsystems.
void switch_theme(const std::string &theme_id)
Set and activate the given gui2 theme.
void show_message(const std::string &title, const std::string &msg, const std::string &button_caption, const bool auto_close, const bool message_use_markup, const bool title_use_markup)
Shows a message to the user.
retval
Default window/dialog return values.
void build_spritesheet_from(const std::string &entry_point)
config read(std::istream &in, abstract_validator *validator)
bool using_own_console()
Returns true if a console was allocated by the Wesnoth process.
std::string list_log_domains(const std::string &filter)
void set_log_to_file()
Do the initial redirection to a log file if the logs directory is writable.
void set_log_sanitize(bool sanitize)
toggle log sanitization
utils::optional< bool > log_dir_writable()
Returns the result set by check_log_dir_writable().
void do_console_redirect()
Allocates a console if needed and redirects output to CONOUT.
void precise_timestamps(bool pt)
bool set_log_domain_severity(const std::string &name, severity severity)
void set_strict_severity(severity severity)
void play_music_config(const config &music_node, bool allow_interrupt_current_track, int i)
void bind_textdomain(const char *domain, const char *directory, const char *)
void set_default_textdomain(const char *domain)
std::string get_unknown_exception_type()
Utility function for finding the type of thing caught with catch(...).
std::map< std::string, t_string > string_map
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
std::string preprocess_string(const std::string &contents, preproc_map *defines, const std::string &textdomain)
Function to use the WML preprocessor on a string.
void preprocess_resource(const std::string &res_name, preproc_map *defines_map, bool write_cfg, bool write_plain_cfg, const std::string &parent_directory)
filesystem::scoped_istream preprocess_file(const std::string &fname, preproc_map *defines)
Function to use the WML preprocessor on a file.
std::map< std::string, struct preproc_define > preproc_map
One of the realizations of serialization/validator.hpp abstract validator.
Contains a basic exception class for SDL operations.
structure which will hide all current floating labels, and cause floating labels instantiated after i...
Base class for all the errors encountered by the engine.
static preproc_map::value_type read_pair(const config &)
Reports time elapsed at the end of an object scope.
An error specifically indicating video subsystem problems.
Helper class, don't construct this directly.
bool strict_validation_enabled
Some defines: VERSION, PACKAGE, MIN_SAVEGAME_VERSION.
static lg::log_domain log_preprocessor("preprocessor")
static void handle_preprocess_string(const commandline_options &cmdline_opts)
static void safe_exit(int res)
static int do_gameloop(commandline_options &cmdline_opts)
Setups the game environment and enters the titlescreen or game loops.
static int handle_validate_command(const std::string &file, abstract_validator &validator, const std::vector< std::string > &defines)
int main(int argc, char **argv)
static int process_command_args(commandline_options &cmdline_opts)
Process commandline-arguments.
static void handle_preprocess_command(const commandline_options &cmdline_opts)
static void init_locale()
I would prefer to setup locale first so that early error messages can get localized,...
static void handle_lua_script_args(game_launcher *game, commandline_options &)
Handles the lua script command line arguments if present.
static void warn_early_init_failure()
Print an alert and instructions to stderr about early initialization errors.
static lg::log_domain log_config("config")
Add a special kind of assert to validate whether the input from WML doesn't contain any problems that...