The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
wesnoth.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2016 by David White <[email protected]>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #include "global.hpp"
16 
17 #include "about.hpp"
18 #include "addon/manager.hpp"
19 #include "addon/manager_ui.hpp"
20 #include "build_info.hpp"
21 #include "commandline_options.hpp" // for commandline_options, etc
22 #include "config.hpp" // for config, config::error, etc
23 #include "cursor.hpp" // for set, CURSOR_TYPE::NORMAL, etc
24 #include "editor/editor_main.hpp"
25 #include "filesystem.hpp" // for filesystem::file_exists, filesystem::io_exception, etc
26 #include "floating_label.hpp"
27 #include "font.hpp" // for load_font_config, etc
28 #include "formula/formula.hpp" // for formula_error
29 #include "game_config.hpp" // for path, debug, debug_lua, etc
30 #include "game_config_manager.hpp" // for game_config_manager, etc
31 #include "game_end_exceptions.hpp"
32 #include "game_launcher.hpp" // for game_launcher, etc
33 #include "gettext.hpp"
34 #include "gui/core/event/handler.hpp" // for tmanager
35 #include "gui/dialogs/core_selection.hpp" // for tcore_selection
37 #include "gui/dialogs/title_screen.hpp" // for ttitle_screen, etc
38 #include "gui/dialogs/message.hpp" // for show_error_message
39 #include "gui/widgets/helper.hpp" // for init
40 #include "help/help.hpp" // for help_manager
41 #include "image.hpp" // for flush_cache, etc
42 #include "log.hpp" // for LOG_STREAM, general, logger, etc
43 #include "preferences.hpp" // for core_id, etc
47 #include "sdl/exception.hpp" // for texception
48 #include "sdl/rect.hpp"
49 #include "serialization/binary_or_text.hpp" // for config_writer
50 #include "serialization/parser.hpp" // for read
51 #include "serialization/preprocessor.hpp" // for preproc_define, etc
53 #include "serialization/validator.hpp" // for strict_validation_enabled
55 #include "sound.hpp" // for commit_music_changes, etc
56 #include "statistics.hpp" // for fresh_stats
57 #include "tstring.hpp" // for operator==, t_string
58 #include "version.hpp" // for version_info
59 #include "video.hpp" // for CVideo
60 #include "wesconfig.h" // for PACKAGE
61 #include "widgets/button.hpp" // for button
62 #include "wml_exception.hpp" // for twml_exception
63 
64 #ifdef _WIN32
65 #include "log_windows.hpp"
66 
67 #include <float.h>
68 #endif // _WIN32
69 
70 #ifndef _MSC_VER
71 #include <fenv.h>
72 #endif // _MSC_VER
73 
74 #include <SDL.h> // for SDL_Init, SDL_INIT_TIMER
75 #include "utils/functional.hpp"
76 #include <boost/iostreams/categories.hpp> // for input, output
77 #include <boost/iostreams/copy.hpp> // for copy
78 #include <boost/iostreams/filter/bzip2.hpp> // for bzip2_compressor, etc
79 #include <boost/iostreams/filter/gzip.hpp> // for gzip_compressor, etc
80 #include <boost/iostreams/filtering_stream.hpp> // for filtering_stream
81 #include <boost/optional.hpp> // for optional
82 #include <boost/program_options/errors.hpp> // for error
83 #include <boost/scoped_ptr.hpp> // for scoped_ptr
84 #include <boost/tuple/tuple.hpp> // for tuple
85 
86 #include <algorithm> // for transform
87 #include <cerrno> // for ENOMEM
88 #include <clocale> // for setlocale, LC_ALL, etc
89 #include <cstdio> // for remove, fprintf, stderr
90 #include <cstdlib> // for srand, exit
91 #include <ctime> // for time, ctime, time_t
92 #include <exception> // for exception
93 #include <fstream> // for operator<<, basic_ostream, etc
94 #include <iostream> // for cerr, cout
95 #include <vector>
96 
97 //#define NO_CATCH_AT_GAME_END
98 
99 #ifdef _WIN32
100 #ifdef INADDR_ANY
101  #undef INADDR_ANY
102 #endif
103 #ifdef INADDR_BROADCAST
104  #undef INADDR_BROADCAST
105 #endif
106 #ifdef INADDR_NONE
107  #undef INADDR_NONE
108 #endif
109 #include <windows.h>
110 #if defined(_OPENMP) && _MSC_VER >= 1600
111  #include <process.h>
112 #endif
113 #endif
114 
115 #ifdef DEBUG_WINDOW_LAYOUT_GRAPHS
116 #include "gui/widgets/debug.hpp"
117 #endif
118 
119 #ifdef HAVE_VISUAL_LEAK_DETECTOR
120 #include "vld.h"
121 #endif
122 
123 class end_level_exception;
124 namespace game { struct error; }
125 
126 static lg::log_domain log_config("config");
127 #define LOG_CONFIG LOG_STREAM(info, log_config)
128 
129 #define LOG_GENERAL LOG_STREAM(info, lg::general())
130 
131 static lg::log_domain log_preprocessor("preprocessor");
132 #define LOG_PREPROC LOG_STREAM(info,log_preprocessor)
133 
134 // this is needed to allow identical functionality with clean refactoring
135 // play_game only returns on an error, all returns within play_game can
136 // be replaced with this
137 static void safe_exit(int res) {
138 
139  LOG_GENERAL << "exiting with code " << res << "\n";
140  exit(res);
141 }
142 
143 // maybe this should go in a util file somewhere?
144 template <typename filter>
145 static void encode(const std::string & input_file, const std::string & output_file)
146 {
147  try {
148  std::ifstream ifile(input_file.c_str(),
150  ifile.peek(); // We need to touch the stream to set the eof bit
151  if(!ifile.good()) {
152  std::cerr << "Input file " << input_file << " is not good for reading. Exiting to prevent bzip2 from segfaulting\n";
153  safe_exit(1);
154  }
155  std::ofstream ofile(output_file.c_str(), std::ios_base::out
157  boost::iostreams::filtering_stream<boost::iostreams::output> stream;
158  stream.push(filter());
159  stream.push(ofile);
160  boost::iostreams::copy(ifile, stream);
161  ifile.close();
162  safe_exit(remove(input_file.c_str()));
163  } catch(filesystem::io_exception& e) {
164  std::cerr << "IO error: " << e.what() << "\n";
165  }
166 }
167 
168 template <typename filter>
169 static void decode(const std::string & input_file, const std::string & output_file)
170 {
171  try {
172  std::ofstream ofile(output_file.c_str(), std::ios_base::out
174  std::ifstream ifile(input_file.c_str(),
176  boost::iostreams::filtering_stream<boost::iostreams::input> stream;
177  stream.push(filter());
178  stream.push(ifile);
179  boost::iostreams::copy(stream, ofile);
180  ifile.close();
181  safe_exit(remove(input_file.c_str()));
182  } catch(filesystem::io_exception& e) {
183  std::cerr << "IO error: " << e.what() << "\n";
184  }
185 }
186 
187 static void gzip_encode(const std::string & input_file, const std::string & output_file)
188 {
189  encode<boost::iostreams::gzip_compressor>(input_file, output_file);
190 }
191 
192 static void gzip_decode(const std::string & input_file, const std::string & output_file)
193 {
194  decode<boost::iostreams::gzip_decompressor>(input_file, output_file);
195 }
196 
197 static void bzip2_encode(const std::string & input_file, const std::string & output_file)
198 {
199  encode<boost::iostreams::bzip2_compressor>(input_file, output_file);
200 }
201 
202 static void bzip2_decode(const std::string & input_file, const std::string & output_file)
203 {
204  decode<boost::iostreams::bzip2_decompressor>(input_file, output_file);
205 }
206 
207 static void handle_preprocess_command(const commandline_options& cmdline_opts)
208 {
209  preproc_map input_macros;
210 
211  if( cmdline_opts.preprocess_input_macros ) {
212  std::string file = *cmdline_opts.preprocess_input_macros;
213  if ( filesystem::file_exists( file ) == false )
214  {
215  std::cerr << "please specify an existing file. File "<< file <<" doesn't exist.\n";
216  return;
217  }
218 
219  std::cerr << SDL_GetTicks() << " Reading cached defines from: " << file << "\n";
220 
221  config cfg;
222 
223  try {
225  read( cfg, *stream );
226  } catch (config::error & e) {
227  std::cerr << "Caught a config error while parsing file '" << file << "':\n" << e.message << std::endl;
228  }
229 
230  int read = 0;
231 
232  // use static preproc_define::read_pair(config) to make a object
233  for (const config::any_child &value : cfg.all_children_range()) {
234  const preproc_map::value_type def = preproc_define::read_pair( value.cfg );
235  input_macros[def.first] = def.second;
236  ++read;
237  }
238  std::cerr << SDL_GetTicks() << " Read " << read << " defines.\n";
239  }
240 
241  const std::string resourceToProcess(*cmdline_opts.preprocess_path);
242  const std::string targetDir(*cmdline_opts.preprocess_target);
243 
244  Uint32 startTime = SDL_GetTicks();
245  // if the users add the SKIP_CORE define we won't preprocess data/core
246  bool skipCore = false;
247  bool skipTerrainGFX = false;
248  // the 'core_defines_map' is the one got from data/core macros
249  preproc_map defines_map( input_macros );
250 
251  if ( cmdline_opts.preprocess_defines ) {
252 
253  // add the specified defines
254  for (const std::string &define : *cmdline_opts.preprocess_defines) {
255  if (define.empty()){
256  std::cerr << "empty define supplied\n";
257  continue;
258  }
259 
260  LOG_PREPROC << "adding define: " << define << '\n';
261  defines_map.insert(std::make_pair(define, preproc_define(define)));
262 
263  if (define == "SKIP_CORE")
264  {
265  std::cerr << "'SKIP_CORE' defined.\n";
266  skipCore = true;
267  }
268  else if (define == "NO_TERRAIN_GFX")
269  {
270  std::cerr << "'NO_TERRAIN_GFX' defined." << std::endl;
271  skipTerrainGFX = true;
272  }
273  }
274  }
275 
276  // add the WESNOTH_VERSION define
277  defines_map["WESNOTH_VERSION"] = preproc_define(game_config::wesnoth_version.str());
278 
279  std::cerr << "added " << defines_map.size() << " defines.\n";
280 
281  // preprocess core macros first if we don't skip the core
282  if (skipCore == false) {
283  std::cerr << "preprocessing common macros from 'data/core' ...\n";
284 
285  // process each folder explicitly to gain speed
286  preprocess_resource(game_config::path + "/data/core/macros",&defines_map);
287  if (skipTerrainGFX == false)
288  preprocess_resource(game_config::path + "/data/core/terrain-graphics",&defines_map);
289 
290  std::cerr << "acquired " << (defines_map.size() - input_macros.size())
291  << " 'data/core' defines.\n";
292  }
293  else
294  std::cerr << "skipped 'data/core'\n";
295 
296  // preprocess resource
297  std::cerr << "preprocessing specified resource: "
298  << resourceToProcess << " ...\n";
299  preprocess_resource(resourceToProcess, &defines_map, true,true, targetDir);
300  std::cerr << "acquired " << (defines_map.size() - input_macros.size())
301  << " total defines.\n";
302 
303  if ( cmdline_opts.preprocess_output_macros )
304  {
305  std::string outputFileName = "_MACROS_.cfg";
306  if (!cmdline_opts.preprocess_output_macros->empty()) {
307  outputFileName = *cmdline_opts.preprocess_output_macros;
308  }
309 
310  std::string outputPath = targetDir + "/" + outputFileName;
311 
312  std::cerr << "writing '" << outputPath << "' with "
313  << defines_map.size() << " defines.\n";
314 
316  if (!out->fail())
317  {
318  config_writer writer(*out,false);
319 
320  for(preproc_map::iterator itor = defines_map.begin();
321  itor != defines_map.end(); ++itor)
322  {
323  (*itor).second.write(writer, (*itor).first);
324  }
325  }
326  else
327  std::cerr << "couldn't open the file.\n";
328  }
329 
330  std::cerr << "preprocessing finished. Took "<< SDL_GetTicks() - startTime << " ticks.\n";
331 }
332 
333 /** Process commandline-arguments */
334 static int process_command_args(const commandline_options& cmdline_opts) {
335 
336  // Options that don't change behavior based on any others should be checked alphabetically below.
337 
338  if(cmdline_opts.userconfig_dir) {
340  }
341  if(cmdline_opts.userconfig_path) {
342  std::cout << filesystem::get_user_config_dir() << '\n';
343  return 0;
344  }
345  if(cmdline_opts.userdata_dir) {
347  }
348  if(cmdline_opts.userdata_path) {
349  std::cout << filesystem::get_user_data_dir() << '\n';
350  return 0;
351  }
352  if(cmdline_opts.data_dir) {
353  const std::string datadir = *cmdline_opts.data_dir;
354  std::cerr << "Overriding data directory with " << datadir << std::endl;
355 #ifdef _WIN32
356  // use c_str to ensure that index 1 points to valid element since c_str() returns null-terminated string
357  if(datadir.c_str()[1] == ':') {
358 #else
359  if(datadir[0] == '/') {
360 #endif
361  game_config::path = datadir;
362  } else {
363  game_config::path = filesystem::get_cwd() + '/' + datadir;
364  }
365 
367  std::cerr << "Could not find directory '" << game_config::path << "'\n";
368  throw config::error("directory not found");
369  }
370  // don't update font as we already updating it in game ctor
371  //font_manager_.update_font_path();
372  }
373  if(cmdline_opts.data_path) {
374  std::cout << game_config::path << '\n';
375  return 0;
376  }
377  if(cmdline_opts.debug_lua) {
378  game_config::debug_lua = true;
379  }
380  if(cmdline_opts.gunzip) {
381  const std::string input_file(*cmdline_opts.gunzip);
382  if(!filesystem::is_gzip_file(input_file)) {
383  std::cerr << "file '" << input_file << "'isn't a .gz file\n";
384  return 2;
385  }
386  const std::string output_file(
387  input_file, 0, input_file.length() - 3);
388  gzip_decode(input_file, output_file);
389  }
390  if(cmdline_opts.bunzip2) {
391  const std::string input_file(*cmdline_opts.bunzip2);
392  if(!filesystem::is_bzip2_file(input_file)) {
393  std::cerr << "file '" << input_file << "'isn't a .bz2 file\n";
394  return 2;
395  }
396  const std::string output_file(
397  input_file, 0, input_file.length() - 4);
398  bzip2_decode(input_file, output_file);
399  }
400  if(cmdline_opts.gzip) {
401  const std::string input_file(*cmdline_opts.gzip);
402  const std::string output_file(*cmdline_opts.gzip + ".gz");
403  gzip_encode(input_file, output_file);
404  }
405  if(cmdline_opts.bzip2) {
406  const std::string input_file(*cmdline_opts.bzip2);
407  const std::string output_file(*cmdline_opts.bzip2 + ".bz2");
408  bzip2_encode(input_file, output_file);
409  }
410  if(cmdline_opts.help) {
411  std::cout << cmdline_opts;
412  return 0;
413  }
414  if(cmdline_opts.log) {
415  for(std::vector<boost::tuple<int, std::string> >::const_iterator it=cmdline_opts.log->begin(); it!=cmdline_opts.log->end(); ++it)
416  {
417  const std::string log_domain = it->get<1>();
418  const int severity = it->get<0>();
419  if (!lg::set_log_domain_severity(log_domain, severity))
420  {
421  std::cerr << "unknown log domain: " << log_domain << '\n';
422  return 2;
423  }
424  }
425  }
426  if(cmdline_opts.logdomains) {
427  std::cout << lg::list_logdomains(*cmdline_opts.logdomains);
428  return 0;
429  }
430  if(cmdline_opts.path) {
431  std::cout << game_config::path << "\n";
432  return 0;
433  }
434  if(cmdline_opts.log_precise_timestamps) {
436  }
437  if(cmdline_opts.rng_seed) {
438  srand(*cmdline_opts.rng_seed);
439  }
440  if(cmdline_opts.screenshot || cmdline_opts.render_image) {
441  SDL_setenv("SDL_VIDEODRIVER", "dummy", 1);
442  }
443  if(cmdline_opts.strict_validation) {
445  }
446  if(cmdline_opts.version) {
447  std::cout << "Battle for Wesnoth" << " " << game_config::version << "\n\n";
448  std::cout << "Library versions:\n" << game_config::library_versions_report() << '\n';
449  std::cout << "Optional features:\n" << game_config::optional_features_report();
450 
451  return 0;
452  }
453 
454  // Options changing their behavior dependent on some others should be checked below.
455 
456  if ( cmdline_opts.preprocess ) {
457  handle_preprocess_command(cmdline_opts);
458  return 0;
459  }
460 
461  // Not the most intuitive solution, but I wanted to leave current semantics for now
462  return -1;
463 }
464 
465 /**
466  * I would prefer to setup locale first so that early error
467  * messages can get localized, but we need the game_launcher
468  * initialized to have filesystem::get_intl_dir() to work. Note: setlocale()
469  * does not take GUI language setting into account.
470  */
471 static void init_locale() {
472  #if defined _WIN32 || defined __APPLE__
473  setlocale(LC_ALL, "English");
474  #else
475  std::setlocale(LC_ALL, "C");
477  #endif
478  const std::string& intl_dir = filesystem::get_intl_dir();
479  translation::bind_textdomain(PACKAGE, intl_dir.c_str(), "UTF-8");
480  translation::bind_textdomain(PACKAGE "-lib", intl_dir.c_str(), "UTF-8");
482 }
483 
484 /**
485  * Print an alert and instructions to stderr about early initialization errors.
486  *
487  * This is provided as an aid for users dealing with potential data dir
488  * configuration issues. The first code to read core WML *has* the
489  * responsibility to call this function in the event of a problem, to inform
490  * the user of the most likely possible cause and suggest a course of action
491  * to solve the issue.
492  */
494 {
495  // NOTE: wrap output to 80 columns.
496  std::cerr << '\n'
497  << "An error at this point during initialization usually indicates that the data\n"
498  << "directory above was not correctly set or detected. Try passing the correct path\n"
499  << "in the command line with the --data-dir switch or as the only argument.\n";
500 }
501 
502 /**
503  * Handles the lua script command line arguments if present.
504  * This function will only run once.
505  */
507 {
508  static bool first_time = true;
509 
510  if (!first_time) return;
511 
512  first_time = false;
513 
514  if (!game->init_lua_script()) {
515  //std::cerr << "error when loading lua scripts at startup\n";
516  //std::cerr << "could not load lua script: " << *cmdline_opts.script_file << std::endl;
517  }
518 }
519 
520 #ifdef _MSC_VER
521 static void check_fpu()
522 {
523  uint32_t f_control;
524  if(_controlfp_s(&f_control, 0, 0) == 0) {
525  uint32_t unused;
526  uint32_t rounding_mode = f_control & _MCW_RC;
527  uint32_t precision_mode = f_control & _MCW_PC;
528  if(rounding_mode != _RC_NEAR) {
529  std::cerr << "Floating point rounding mode is currently '" <<
530  ((rounding_mode == _RC_CHOP) ? "chop" :
531  (rounding_mode == _RC_UP) ? "up" :
532  (rounding_mode == _RC_DOWN) ? "down" :
533  (rounding_mode == _RC_NEAR) ? "near" :
534  "unknown") << "' setting to 'near'\n";
535  if(_controlfp_s(&unused, _RC_NEAR, _MCW_RC)) {
536  std::cerr << "failed to set floating point rounding type to 'near'\n";
537  }
538  }
539  if(precision_mode != _PC_53) {
540  std::cerr << "Floating point precision mode is currently '" <<
541  ((precision_mode == _PC_53) ? "double" :
542  (precision_mode == _PC_24) ? "single" :
543  (precision_mode == _PC_64 ) ? "double extended" :
544  "unknown") << "' setting to 'double'\n";
545  if(_controlfp_s(&unused, _PC_53, _MCW_PC)) {
546  std::cerr << "failed to set floating point precision type to 'double'\n";
547  }
548  }
549  }
550  else {
551  std::cerr << "_controlfp_s failed.\n";
552  }
553 }
554 #else
555 static void check_fpu()
556 {
557  switch (fegetround()) {
558  case FE_TONEAREST: break;
559  case FE_DOWNWARD: std::cerr << "Floating point precision mode is currently 'downward'"; goto reset_fpu;
560  case FE_TOWARDZERO: std::cerr << "Floating point precision mode is currently 'toward-zero'"; goto reset_fpu;
561  case FE_UPWARD: std::cerr << "Floating point precision mode is currently 'upward'"; goto reset_fpu;
562  default: std::cerr << "Floating point precision mode is currently 'unknown'"; goto reset_fpu;
563  reset_fpu:
564  std::cerr << "setting to 'nearest'";
565  fesetround(FE_TONEAREST);
566  break;
567  }
568 }
569 #endif
570 /**
571  * Setups the game environment and enters
572  * the titlescreen or game loops.
573  */
574 static int do_gameloop(const std::vector<std::string>& args)
575 {
576  srand(time(nullptr));
577 
578  commandline_options cmdline_opts = commandline_options(args);
580  int finished = process_command_args(cmdline_opts);
581  if(finished != -1) {
582  return finished;
583  }
584 
585  boost::scoped_ptr<game_launcher> game(
586  new game_launcher(cmdline_opts,args[0].c_str()));
587  const int start_ticks = SDL_GetTicks();
588 
589  init_locale();
590 
591  bool res;
592 
593  // do initialize fonts before reading the game config, to have game
594  // config error messages displayed. fonts will be re-initialized later
595  // when the language is read from the game config.
596  res = font::load_font_config();
597  if(res == false) {
598  std::cerr << "could not initialize fonts\n";
599  // The most common symptom of a bogus data dir path -- warn the user.
601  return 1;
602  }
603 
604  res = game->init_language();
605  if(res == false) {
606  std::cerr << "could not initialize the language\n";
607  return 1;
608  }
609 
610  res = game->init_video();
611  if(res == false) {
612  std::cerr << "could not initialize display\n";
613  return 1;
614  }
615 
617  if(res == false) {
618  std::cerr << "could not initialize image preferences\n";
619  return 1;
620  }
621 
623  res = game->init_joystick();
624  if(res == false) {
625  std::cerr << "could not initialize joystick\n";
626  }
627  }
628 
629  check_fpu();
630  const cursor::manager cursor_manager;
632 
633 #if (defined(_X11) && !defined(__APPLE__)) || defined(_WIN32)
634  SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE);
635 #endif
636 
637  gui2::init();
638  const gui2::event::tmanager gui_event_manager;
639 
640  game_config_manager config_manager(cmdline_opts, game->video(),
641  game->jump_to_editor());
642 
643  gui2::tloadscreen::display(game->video(), [&res, &config_manager]() {
644  gui2::tloadscreen::progress("load config");
645  res = config_manager.init_game_config(game_config_manager::NO_FORCE_RELOAD);
646 
647  if(res == false) {
648  std::cerr << "could not initialize game config\n";
649  return;
650  }
651  gui2::tloadscreen::progress("init fonts");
652 
653  res = font::load_font_config();
654  if(res == false) {
655  std::cerr << "could not re-initialize fonts for the current language\n";
656  return;
657  }
658 
659  gui2::tloadscreen::progress("refresh addons");
661  });
662 
663  if(res == false) {
664  return 1;
665  }
666 
667  config tips_of_day;
668 
669  LOG_CONFIG << "time elapsed: "<< (SDL_GetTicks() - start_ticks) << " ms\n";
670 
671  plugins_manager plugins_man(new application_lua_kernel(&game->video()));
672 
673  plugins_context::Reg const callbacks[] = {
674  { "play_multiplayer", std::bind(&game_launcher::play_multiplayer, game.get())},
675  };
676  plugins_context::aReg const accessors[] = {
677  { "command_line", std::bind(&commandline_options::to_config, &cmdline_opts)},
678  };
679 
680  plugins_context plugins("titlescreen", callbacks, accessors);
681 
682  plugins.set_callback("exit", std::bind(&safe_exit, std::bind(get_int, std::placeholders::_1, "code", 0)), false);
683 
684  for (;;)
685  {
686  // reset the TC, since a game can modify it, and it may be used
687  // by images in add-ons or campaigns dialogs
689 
691 
692  if (!game->is_loading()) {
693  const config &cfg =
694  config_manager.game_config().child("titlescreen_music");
695  if (cfg) {
697  for (const config &i : cfg.child_range("music")) {
699  }
701  } else {
704  }
705  }
706 
707  handle_lua_script_args(&*game,cmdline_opts);
708 
709  plugins.play_slice();
710  plugins.play_slice();
711 
712  if(cmdline_opts.unit_test) {
713  if(cmdline_opts.timeout) {
714  std::cerr << "The wesnoth built-in timeout feature has been removed.\n" << std::endl;
715  std::cerr << "Please use a platform-specific script which will kill the overtime process instead.\n" << std::endl;
716  std::cerr << "For examples in bash, or in windows cmd, see the forums, or the wesnoth repository." << std::endl;
717  std::cerr << "The bash script is called `run_wml_tests`, the windows script is part of the VC project.\n" << std::endl;
718  }
719  int worker_result = game->unit_test();
720  std::cerr << ((worker_result == 0) ? "PASS TEST " : "FAIL TEST ")
721  << ((worker_result == 3) ? "(INVALID REPLAY)" : "")
722  << ((worker_result == 4) ? "(ERRORED REPLAY)" : "")
723  << ": "<<*cmdline_opts.unit_test << std::endl;
724  return worker_result;
725  }
726 
727  if(game->play_test() == false) {
728  return 0;
729  }
730 
731  if(game->play_screenshot_mode() == false) {
732  return 0;
733  }
734 
735  if(game->play_render_image_mode() == false) {
736  return 0;
737  }
738 
739  //Start directly a campaign
740  if(game->goto_campaign() == false){
741  if (game->jump_to_campaign_id().empty())
742  continue; //Go to main menu
743  else
744  return 1; //we got an error starting the campaign from command line
745  }
746 
747  //Start directly a multiplayer
748  //Eventually with a specified server
749  if(game->goto_multiplayer() == false){
750  continue; //Go to main menu
751  }
752 
753  //Start directly a commandline multiplayer game
754  if(game->play_multiplayer_commandline() == false) {
755  return 0;
756  }
757 
758  if (game->goto_editor() == false) {
759  return 0;
760  }
761 
762  gui2::ttitle_screen::tresult res = game->is_loading()
765 
767 
768  const font::floating_label_context label_manager;
769 
771  if(res == gui2::ttitle_screen::NOTHING) {
773  dlg.show(game->video());
774 
775  res = static_cast<gui2::ttitle_screen::tresult>(dlg.get_retval());
776  }
777 
778  game_launcher::RELOAD_GAME_DATA should_reload =
780 
781  if(res == gui2::ttitle_screen::QUIT_GAME) {
782  LOG_GENERAL << "quitting game...\n";
783  return 0;
784  } else if(res == gui2::ttitle_screen::LOAD_GAME) {
785  if(game->load_game() == false) {
786  game->clear_loaded_game();
788  continue;
789  }
790  should_reload = game_launcher::NO_RELOAD_DATA;
791  } else if(res == gui2::ttitle_screen::TUTORIAL) {
792  game->set_tutorial();
793  } else if(res == gui2::ttitle_screen::NEW_CAMPAIGN) {
794  if(game->new_campaign() == false) {
795  continue;
796  }
797  should_reload = game_launcher::NO_RELOAD_DATA;
798  } else if(res == gui2::ttitle_screen::MULTIPLAYER) {
800  if(game->play_multiplayer() == false) {
801  continue;
802  }
803  } else if(res == gui2::ttitle_screen::CHANGE_LANGUAGE) {
804  try {
805  if (game->change_language()) {
806  tips_of_day.clear();
809  }
810  } catch ( std::runtime_error & e ) {
811  gui2::show_error_message(game->video(), e.what());
812  }
813  continue;
814  } else if(res == gui2::ttitle_screen::EDIT_PREFERENCES) {
815  game->show_preferences();
816  continue;
817  } else if(res == gui2::ttitle_screen::SHOW_ABOUT) {
818  about::show_about(game->video());
819  continue;
820  } else if(res == gui2::ttitle_screen::SHOW_HELP) {
821  help::help_manager help_manager(&config_manager.game_config());
822  help::show_help(game->video());
823  continue;
824  } else if(res == gui2::ttitle_screen::GET_ADDONS) {
825  // NOTE: we need the help_manager to get access to the Add-ons
826  // section in the game help!
827  help::help_manager help_manager(&config_manager.game_config());
828  if(manage_addons(game->video())) {
829  config_manager.reload_changed_game_config();
830  }
831  continue;
832  } else if(res == gui2::ttitle_screen::CORES) {
833 
834  int current = 0;
835  std::vector<config> cores;
836  for (const config& core : game_config_manager::get()->game_config().child_range("core")) {
837  cores.push_back(core);
838  if (core["id"] == preferences::core_id())
839  current = cores.size() -1;
840  }
841 
842  gui2::tcore_selection core_dlg(cores, current);
843  if (core_dlg.show(game->video())) {
844  int core_index = core_dlg.get_choice();
845  const std::string& core_id = cores[core_index]["id"];
846  preferences::set_core_id(core_id);
847  config_manager.reload_changed_game_config();
848  }
849  continue;
850  } else if(res == gui2::ttitle_screen::RELOAD_GAME_DATA) {
851  gui2::tloadscreen::display(game->video(), [&config_manager]() {
852  config_manager.reload_changed_game_config();
854  });
855  continue;
856  } else if(res == gui2::ttitle_screen::START_MAP_EDITOR) {
857  game->start_editor();
858  continue;
859  }
860  game->launch_game(should_reload);
861  }
862 }
863 #ifdef _WIN32
864 static bool parse_commandline_argument(const char*& next, const char* end, std::string& res)
865 {
866  //strip leading whitespace
867  while(next != end && *next == ' ')
868  ++next;
869  if(next == end)
870  return false;
871 
872  bool is_excaped = false;
873 
874  for(;next != end; ++next)
875  {
876  if(*next == ' ' && !is_excaped) {
877  break;
878  }
879  else if(*next == '"' && !is_excaped) {
880  is_excaped = true;
881  continue;
882  }
883  else if(*next == '"' && is_excaped && next + 1 != end && *(next + 1) == '"') {
884  res.push_back('"');
885  ++next;
886  continue;
887  }
888  else if(*next == '"' && is_excaped ) {
889  is_excaped = false;
890  continue;
891  }
892  else {
893  res.push_back(*next);
894  }
895  }
896  return true;
897 }
898 
899 static std::vector<std::string> parse_commandline_arguments(std::string input)
900 {
901  const char* start = &input[0];
902  const char* end = start + input.size();
904  std::vector<std::string> res;
905 
906  while(parse_commandline_argument(start, end, buffer))
907  {
908  res.push_back(std::string());
909  res.back().swap(buffer);
910  }
911  return res;
912 }
913 #endif
914 
915 #ifndef _WIN32
916 static void wesnoth_terminate_handler(int) {
917  exit(0);
918 }
919 #endif
920 
921 #if defined(_OPENMP) && _MSC_VER >= 1600
922 static void restart_process(const std::vector<std::string>& commandline)
923 {
924  wchar_t process_path[MAX_PATH];
925  SetLastError(ERROR_SUCCESS);
926  GetModuleFileNameW(nullptr, process_path, MAX_PATH);
927  if (GetLastError() != ERROR_SUCCESS)
928  {
929  throw std::runtime_error("Failed to retrieve the process path");
930  }
931 
932  std::wstring commandline_str = unicode_cast<std::wstring>(utils::join(commandline, " "));
933  // CreateProcessW is allowed to modify the passed command line.
934  // Therefore we need to copy it.
935  wchar_t* commandline_c_str = new wchar_t[commandline_str.length() + 1];
936  commandline_str.copy(commandline_c_str, commandline_str.length());
937  commandline_c_str[commandline_str.length()] = L'\0';
938 
939  STARTUPINFOW startup_info;
940  ZeroMemory(&startup_info, sizeof(startup_info));
941  startup_info.cb = sizeof(startup_info);
942  PROCESS_INFORMATION process_info;
943  ZeroMemory(&process_info, sizeof(process_info));
944 
945  CreateProcessW(process_path, commandline_c_str, nullptr, nullptr,
946  false, 0u, nullptr, nullptr, &startup_info, &process_info);
947 
948  CloseHandle(process_info.hProcess);
949  CloseHandle(process_info.hThread);
950 
951  std::exit(EXIT_SUCCESS);
952 }
953 #endif
954 
955 #if defined(__native_client__) || defined(__APPLE__)
956 extern "C" int wesnoth_main(int argc, char** argv);
957 int wesnoth_main(int argc, char** argv)
958 #else
959 int main(int argc, char** argv)
960 #endif
961 {
962 
963 #ifdef HAVE_VISUAL_LEAK_DETECTOR
964  VLDEnable();
965 #endif
966 
967 #ifdef _WIN32
968  (void)argc;
969  (void)argv;
970 
971  //windows argv is ansi encoded by default
972  std::vector<std::string> args = parse_commandline_arguments(unicode_cast<std::string>(std::wstring(GetCommandLineW())));
973 
974  // HACK: we don't parse command line arguments using program_options until
975  // the startup banner is printed. We need to get a console up and
976  // running before then if requested, so just perform a trivial search
977  // here and let program_options ignore the switch later.
978  for(size_t k = 0; k < args.size(); ++k) {
979  if(args[k] == "--wconsole" || args[k] == "--help" || args[k] == "--nogui" || args[k] == "--logdomains" || args[k] == "--path" || args[k] == "--render-image" || args[k] == "--screenshot" || args[k] == "--data-path" || args[k] == "--userdata-path" || args[k] == "--userconfig-path" || args[k] == "--version") {
981  break;
982  }
983  }
984 
986 #else
987  std::vector<std::string> args;
988  for(int i = 0; i < argc; ++i)
989  {
990  args.push_back(std::string(argv[i]));
991  }
992 #endif
993  assert(!args.empty());
994 
995 #ifdef _OPENMP
996  // Wesnoth is a special case for OMP
997  // OMP wait strategy is to have threads busy-loop for 100ms
998  // if there is nothing to do, they then go to sleep.
999  // this avoids the scheduler putting the thread to sleep when work
1000  // is about to be available
1001  //
1002  // However Wesnoth has a lot of very small jobs that need to be done
1003  // at each redraw => 50fps every 2ms.
1004  // All the threads are thus busy-waiting all the time, hogging the CPU
1005  // To avoid that problem, we need to set the OMP_WAIT_POLICY env var
1006  // but that var is read by OMP at library loading time (before main)
1007  // thus the relaunching of ourselves after setting the variable.
1008 #if !defined(_WIN32) && !defined(__APPLE__)
1009  if (!getenv("OMP_WAIT_POLICY")) {
1010  setenv("OMP_WAIT_POLICY", "PASSIVE", 1);
1011  execv(argv[0], argv);
1012  }
1013 #elif _MSC_VER >= 1600
1014  if (!getenv("OMP_WAIT_POLICY")) {
1015  _putenv_s("OMP_WAIT_POLICY", "PASSIVE");
1016  args[0] = utils::quote(args[0]);
1017  restart_process(args);
1018  }
1019 #endif
1020 #endif //_OPENMP
1021 
1022  if(SDL_Init(SDL_INIT_TIMER) < 0) {
1023  fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
1024  return(1);
1025  }
1026 
1027 #ifndef _WIN32
1028  struct sigaction terminate_handler;
1029  terminate_handler.sa_handler = wesnoth_terminate_handler;
1030  terminate_handler.sa_flags = 0;
1031  sigemptyset(&terminate_handler.sa_mask);
1032  sigaction(SIGTERM, &terminate_handler, nullptr);
1033  sigaction(SIGINT, &terminate_handler, nullptr);
1034 #endif
1035 
1036  try {
1037  std::cerr << "Battle for Wesnoth v" << game_config::revision << '\n';
1038  const time_t t = time(nullptr);
1039  std::cerr << "Started on " << ctime(&t) << "\n";
1040 
1041  const std::string& exe_dir = filesystem::get_exe_dir();
1042  if(!exe_dir.empty()) {
1043  // Try to autodetect the location of the game data dir. Note that
1044  // the root of the source tree currently doubles as the data dir.
1045  std::string auto_dir;
1046 
1047  // scons leaves the resulting binaries at the root of the source
1048  // tree by default.
1049  if(filesystem::file_exists(exe_dir + "/data/_main.cfg")) {
1050  auto_dir = exe_dir;
1051  }
1052  // cmake encourages creating a subdir at the root of the source
1053  // tree for the build, and the resulting binaries are found in it.
1054  else if(filesystem::file_exists(exe_dir + "/../data/_main.cfg")) {
1055  auto_dir = filesystem::normalize_path(exe_dir + "/..");
1056  }
1057  // In Windows debug builds, the EXE is placed away from the game data dir
1058  // (in projectfiles\VCx\Debug), but the working directory is set to the
1059  // game data dir. Thus, check if the working dir is the game data dir.
1060  else if(filesystem::file_exists(filesystem::get_cwd() + "/data/_main.cfg")) {
1061  auto_dir = filesystem::get_cwd();
1062  }
1063 
1064  if(!auto_dir.empty()) {
1065  std::cerr << "Automatically found a possible data directory at "
1066  << auto_dir << '\n';
1067  game_config::path = auto_dir;
1068  }
1069  }
1070 
1071  const int res = do_gameloop(args);
1072  safe_exit(res);
1073  } catch(boost::program_options::error& e) {
1074  std::cerr << "Error in command line: " << e.what() << '\n';
1075  return 1;
1076  } catch(CVideo::error&) {
1077  std::cerr << "Could not initialize video. Exiting.\n";
1078  return 1;
1079  } catch(font::manager::error&) {
1080  std::cerr << "Could not initialize fonts. Exiting.\n";
1081  return 1;
1082  } catch(config::error& e) {
1083  std::cerr << e.message << "\n";
1084  return 1;
1085  } catch(gui::button::error&) {
1086  std::cerr << "Could not create button: Image could not be found\n";
1087  return 1;
1088  } catch(CVideo::quit&) {
1089  //just means the game should quit
1090  } catch(return_to_play_side_exception&) {
1091  std::cerr << "caught return_to_play_side_exception, please report this bug (quitting)\n";
1092  } catch(quit_game_exception&) {
1093  std::cerr << "caught quit_game_exception (quitting)\n";
1094  } catch(twml_exception& e) {
1095  std::cerr << "WML exception:\nUser message: "
1096  << e.user_message << "\nDev message: " << e.dev_message << '\n';
1097  return 1;
1098  } catch(game_logic::formula_error& e) {
1099  std::cerr << e.what()
1100  << "\n\nGame will be aborted.\n";
1101  return 1;
1102  } catch(const sdl::texception& e) {
1103  std::cerr << e.what();
1104  return 1;
1105  } catch(game::error &) {
1106  // A message has already been displayed.
1107  return 1;
1108  } catch(std::bad_alloc&) {
1109  std::cerr << "Ran out of memory. Aborted.\n";
1110  return ENOMEM;
1111 #if !defined(NO_CATCH_AT_GAME_END)
1112  } catch(std::exception & e) {
1113  // Try to catch unexpected exceptions.
1114  std::cerr << "Caught general exception:\n" << e.what() << std::endl;
1115  return 1;
1116  } catch(std::string & e) {
1117  std::cerr << "Caught a string thrown as an exception:\n" << e << std::endl;
1118  return 1;
1119  } catch(const char * e) {
1120  std::cerr << "Caught a string thrown as an exception:\n" << e << std::endl;
1121  return 1;
1122  } catch(...) {
1123  // Ensure that even when we terminate with `throw 42`, the exception
1124  // is caught and all destructors are actually called. (Apparently,
1125  // some compilers will simply terminate without calling destructors if
1126  // the exception isn't caught.)
1127  std::cerr << "Caught unspecified general exception. Terminating." << std::endl;
1128  return 1;
1129 #endif
1130  }
1131 
1132  return 0;
1133 } // end main
void show_about(CVideo &video, const std::string &campaign)
Show credits with list of contributors.
Definition: about.cpp:208
void empty_playlist()
Definition: sound.cpp:480
bool log_precise_timestamps
True if –log-precise was given on the command line. Shows timestamps in log with more precision...
child_itors child_range(const std::string &key)
Definition: config.cpp:613
static void wesnoth_terminate_handler(int)
Definition: wesnoth.cpp:916
void show_error_message(CVideo &video, const std::string &message, bool message_use_markup)
Shows an error message to the user.
Definition: message.cpp:198
void show_help(CVideo &video, const std::string &show_topic, int xloc, int yloc)
Open the help browser, show topic with id show_topic.
Definition: help.cpp:117
void set_callback(const std::string &name, callback_function)
Definition: context.cpp:53
static void reset_translations()
Definition: tstring.cpp:506
Used to reload all game data.
void set_user_data_dir(std::string path)
GLvoid **typedef void(GLAPIENTRY *PFNGLGETVERTEXATTRIBDVPROC)(GLuint
Definition: glew.h:1806
void stop_music()
Definition: sound.cpp:411
int get_retval() const
Definition: dialog.hpp:161
void set(CURSOR_TYPE type)
Use the default parameter to reset cursors.
Definition: cursor.cpp:154
std::string library_versions_report()
Produce a plain-text report of library versions suitable for stdout/stderr.
Definition: build_info.cpp:277
static void bzip2_encode(const std::string &input_file, const std::string &output_file)
Definition: wesnoth.cpp:197
static void bzip2_decode(const std::string &input_file, const std::string &output_file)
Definition: wesnoth.cpp:202
const char * what() const
Definition: exceptions.hpp:35
Play single scenario against humans or AI.
const std::function< int(const config &, const std::string &, int) > get_int
Definition: context.cpp:125
boost::optional< std::string > bzip2
Non-empty if –bzip2 was given on the command line. Compresses a file to .bz2 and exits...
static lg::log_domain log_preprocessor("preprocessor")
void set_team_colors(const std::vector< std::string > *colors)
set the team colors used by the TC image modification use a vector with one string for each team usin...
Definition: image.cpp:722
Add a special kind of assert to validate whether the input from WML doesn't contain any problems that...
std::string optional_features_report()
Produce a plain-text report of features suitable for stdout/stderr.
Definition: build_info.cpp:317
bool show(CVideo &video, const unsigned auto_close_time=0)
Shows the window.
Definition: dialog.cpp:34
static l_noret error(LoadState *S, const char *why)
Definition: lundump.cpp:29
boost::uint32_t uint32_t
Definition: xbrz.hpp:45
ucs4_convert_impl::enableif< TD, typename TS::value_type >::type unicode_cast(const TS &source)
GLenum GLenum GLenum input
Definition: glew.h:10668
bool userdata_path
True if –userdata-path was given on the command line. Prints path to user data directory and exits...
static void gzip_decode(const std::string &input_file, const std::string &output_file)
Definition: wesnoth.cpp:192
boost::optional< std::string > gunzip
Non-empty if –gunzip was given on the command line. Uncompresses a .gz file and exits.
void fresh_stats()
Definition: statistics.cpp:617
void early_log_file_setup()
Sets up the initial temporary log file.
boost::optional< unsigned int > rng_seed
RNG seed specified by –rng-seed option. Initializes RNG with given seed.
bool manage_addons(CVideo &v)
Shows the add-ons server connection dialog, for access to the various management front-ends.
boost::optional< std::string > data_dir
Non-empty if –data-dir was given on the command line. Sets the config dir to the specified one...
Dont reload if the previous defines equal the new defines.
static void safe_exit(int res)
Definition: wesnoth.cpp:137
boost::optional< std::vector< boost::tuple< int, std::string > > > log
Contains parsed arguments of –log-* (e.g.
void clear()
Definition: config.cpp:1055
This file contains information about validation abstract level interface.
Contains the exception interfaces used to signal completion of a scenario, campaign or turn...
Default, nothing done, no redraw needed.
void init()
Definition: gettext.cpp:189
std::string quote(const std::string &str)
Surround the string 'str' with double quotes.
GLdouble GLdouble t
Definition: glew.h:1366
-file util.hpp
Definitions for the interface to Wesnoth Markup Language (WML).
static void decode(const std::string &input_file, const std::string &output_file)
Definition: wesnoth.cpp:169
Start special campaign 'tutorial'.
void bind_textdomain(const char *domain, const char *directory, const char *encoding)
Definition: gettext.cpp:105
std::map< std::string, preproc_define > preproc_map
GLuint in
Definition: glew.h:9261
boost::optional< unsigned int > timeout
Non-empty if –timeout was given on the command line. Dependent on –unit.
std::string user_message
The message for the user explaining what went wrong.
bool preprocess
True if –preprocess was given on the command line. Starts Wesnoth in preprocessor-only mode...
void flush_cache()
Definition: image.cpp:191
std::string get_cwd()
GLuint GLuint stream
Definition: glew.h:5239
bool set_log_domain_severity(std::string const &name, int severity)
Definition: log.cpp:117
static game_config_manager * get()
static void warn_early_init_failure()
Print an alert and instructions to stderr about early initialization errors.
Definition: wesnoth.cpp:493
bool joystick_support_enabled()
GLuint GLuint end
Definition: glew.h:1221
boost::optional< std::string > userconfig_dir
Non-empty if –userconfig-dir was given on the command line. Sets the user config dir to the specifie...
void load_hotkeys()
static void check_fpu()
Definition: wesnoth.cpp:555
Class for writing a config out to a file in pieces.
std::string get_user_data_dir()
std::string get_intl_dir()
const GLuint GLenum const GLvoid * binary
Definition: glew.h:3027
std::string normalize_path(const std::string &path)
Returns the absolute path of a file.
static lg::log_domain log_config("config")
bool strict_validation_enabled
Definition: validator.cpp:19
GLsizei const GLfloat * value
Definition: glew.h:1817
all_children_itors all_children_range() const
In-order iteration over all children.
Definition: config.cpp:1127
std::istream * istream_file(const std::string &fname, bool treat_failure_as_error=true)
boost::optional< std::string > logdomains
Non-empty if –logdomains was given on the command line. Prints possible logdomains filtered by given...
#define LOG_GENERAL
Definition: wesnoth.cpp:129
GLuint start
Definition: glew.h:1221
std::string dev_message
The message for developers telling which problem was triggered, this shouldn't be translated...
void play_music_config(const config &music_node)
Definition: sound.cpp:552
boost::optional< std::string > userdata_dir
Non-empty if –userdata-dir was given on the command line. Sets the user data dir to the specified on...
std::ostream * ostream_file(std::string const &fname, bool create_directory=true)
boost::optional< std::string > gzip
Non-empty if –gzip was given on the command line. Compresses a file to .gz and exits.
void enable_native_console_output()
Switches to using a native console instead of log file redirection.
bool is_directory(const std::string &fname)
Returns true if the given file is a directory.
void set_core_id(const std::string &core_id)
std::string path
boost::optional< std::string > preprocess_output_macros
Non-empty if –preprocess-output-macros was given on the command line. Outputs all preprocessed macro...
void set_default_textdomain(const char *domain)
Definition: gettext.cpp:121
void refresh_addon_version_info_cache()
Refreshes the per-session cache of add-on's version information structs.
Definition: manager.cpp:337
int wesnoth_main(int argc, char **argv)
bool init()
Initializes the gui subsystems.
Definition: helper.cpp:37
bool userconfig_path
True if –userconfig-path was given on the command line. Prints path to user config directory and exi...
static void display(CVideo &video, std::function< void()> f)
Definition: loadscreen.cpp:181
GLenum severity
Definition: glew.h:2497
static void handle_preprocess_command(const commandline_options &cmdline_opts)
Definition: wesnoth.cpp:207
bool path
True if –path was given on the command line. Prints the path to data directory and exits...
This class implements the title screen.
boost::optional< std::string > render_image
Image path to render. First parameter after –render-image.
std::string join(T const &v, const std::string &s=",")
Generates a new string joining container items in a list.
int main(int argc, char **argv)
Definition: wesnoth.cpp:959
GLuint buffer
Definition: glew.h:1648
bool load_font_config()
Definition: font.cpp:1048
#define PACKAGE
Definition: wesconfig.h:23
static int do_gameloop(const std::vector< std::string > &args)
Setups the game environment and enters the titlescreen or game loops.
Definition: wesnoth.cpp:574
static void gzip_encode(const std::string &input_file, const std::string &output_file)
Definition: wesnoth.cpp:187
bool is_gzip_file(const std::string &filename)
Returns true if the file ends with '.gz'.
Some defines: VERSION, PACKAGE, MIN_SAVEGAME_VERSION.
GLuint res
Definition: glew.h:9258
static void progress(const char *stage_name=nullptr)
Definition: loadscreen.cpp:128
tresult
Values for the menu-items of the main menu.
static void handle_lua_script_args(game_launcher *game, commandline_options &)
Handles the lua script command line arguments if present.
Definition: wesnoth.cpp:506
std::string get_exe_dir()
boost::optional< std::string > preprocess_target
Target (output) path that was given to the –preprocess option.
static void init_locale()
I would prefer to setup locale first so that early error messages can get localized, but we need the game_launcher initialized to have filesystem::get_intl_dir() to work.
Definition: wesnoth.cpp:471
Log file control routines for Windows.
std::map< std::string, tfilter >::iterator itor
Definition: filter.cpp:199
bool debug_lua
True if –debug-lua was given in the commandline. Enables some Lua debugging mechanisms.
void set_user_config_dir(std::string path)
const std::string revision
Definition: game_config.cpp:57
boost::optional< std::string > preprocess_path
Path to parse that was given to the –preprocess option.
static int process_command_args(const commandline_options &cmdline_opts)
Process commandline-arguments.
Definition: wesnoth.cpp:334
Game configuration data as global variables.
Definition: build_info.cpp:38
bool play_multiplayer()
An exception object used when an IO error occurs.
Definition: filesystem.hpp:40
boost::optional< std::string > bunzip2
Non-empty if –bunzip2 was given on the command line. Uncompresses a .bz2 file and exits...
structure which will hide all current floating labels, and cause floating labels instantiated after i...
size_t i
Definition: function.cpp:1057
std::string title_music
Definition: game_config.cpp:68
Declarations for File-IO.
void read(config &cfg, std::istream &in, abstract_validator *validator)
Definition: parser.cpp:400
static int writer(lua_State *L, const void *b, size_t size, void *B)
Definition: lstrlib.cpp:166
Contains a basic exception class for SDL operations.
const version_info wesnoth_version(VERSION)
std::string core_id()
#define next(ls)
Definition: llex.cpp:27
Let user select a campaign to play.
bool data_path
True if –data-path was given on the command line. Prints path to data directory and exits...
std::string get_user_config_dir()
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glew.h:3448
bool screenshot
True if –screenshot was given on the command line. Starts Wesnoth in screenshot mode.
boost::optional< std::string > unit_test
Non-empty if –unit was given on the command line. Goes directly into unit test mode, into a scenario, if specified.
bool is_bzip2_file(const std::string &filename)
Returns true if the file ends with '.bz2'.
#define LOG_PREPROC
Definition: wesnoth.cpp:132
Contains the SDL_Rect helper code.
Base class for all the errors encountered by the engine.
Definition: exceptions.hpp:27
std::string list_logdomains(const std::string &filter)
Definition: log.cpp:150
void play_music_repeatedly(const std::string &id)
Definition: sound.cpp:536
config & child(const std::string &key, int n=0)
Returns the nth child with the given key, or a reference to an invalid config if there is none...
Definition: config.cpp:658
bool version
True if –version was given on the command line. Prints version and exits.
#define LOG_CONFIG
Definition: wesnoth.cpp:127
Standard logging facilities (interface).
std::string message
Definition: exceptions.hpp:29
bool strict_validation
True if –strict-validation was given on the command line. Makes Wesnoth trust validation errors as f...
boost::optional< std::vector< std::string > > preprocess_defines
Defines that were given to the –preprocess option.
#define e
static void encode(const std::string &input_file, const std::string &output_file)
Definition: wesnoth.cpp:145
boost::optional< std::string > preprocess_input_macros
Non-empty if –preprocess-input-macros was given on the command line. Specifies a file that contains ...
void commit_music_changes()
Definition: sound.cpp:621
bool update_from_preferences()
initialize any private data, e.g. algorithm choices from preferences
Definition: image.cpp:1274
std::string::const_iterator iterator
Definition: tokenizer.hpp:21
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:83
Helper class, don't construct this directly.
static preproc_map::value_type read_pair(const config &)
Interfaces for manipulating version numbers of engine, add-ons, etc.
bool file_exists(const std::string &name)
Returns true if a file or directory with such name already exists.
const std::string version
Definition: game_config.cpp:48
GLsizei const GLcharARB ** string
Definition: glew.h:4503
void preprocess_resource(const std::string &res_name, preproc_map *defines_map, bool write_cfg, bool write_plain_cfg, std::string target_directory)
bool help
True if –help was given on the command line. Prints help and exits.
bool init_lua_script()
std::string directory_name(const std::string &file)
Returns the directory name of a file, with filename stripped.
std::string wesnoth_program_dir
Definition: game_config.cpp:61
void precise_timestamps(bool pt)
Definition: log.cpp:77
void play_slice()
Definition: context.cpp:104