Nils Kneuper | 2 May 2011 21:57
Picon

Re: Release of 1.8.6


Am 07.02.2011 12:18, schrieb Nils Kneuper:
> Hi everybody!
> During FOSDEM we decided that the release of 1.10 is "far off" for the moment
> (something like November or December 2011). Because of this deekay asked me if
> another 1.8.x release would make sense. He found several things that he thinks
> are rather annoying and might be worth fixing if the stable series is going to
> be recent for such a long time. I agreed to releasing a new 1.8.x release (that
> would be 1.8.6) once he has the fixes in. I expect this to be some time around
> the end of February, but am not 100% sure about the schedule so far.

Okay, end of February is now long gone but finally the last changes that I was
waiting for were committed by Crab_. Meaning: 1.8.6 will be out "really soon".

> These changes might introduce some string changes, translators will get an
> additional note if this is really the case. My request to all translation teams
> as well as all developers is to make sure that the stuff they want to see in a
> 1.8.6 release is online or that they commit/send in the stuff missing. Devs
> should not forget to also add the stuff to the changelog(s) ;).

The changes done by Crab_ require a pot-update since some changed strings were
introduced. I plan to do this tomorrow morning. So if you have any fixes left
that change strings, commit them ASAP (meaning: in the next 12 hours). After the
pot-update the translators have at least a week to fix the strings, then I will
release 1.8.6. After the pot-update a *string freeze* is active for trunk!

Currently I consider tagging 1.8.6 maybe on Wednesday next week. Please ping me
ASAP if you got anything I should be waiting for (and obviously tell me what it
is). Yes, I think that 1.8.6 will really be the last 1.8.6 release.

(Continue reading)

Nils Kneuper | 2 May 2011 23:38
Picon

Re: Release of 1.8.6


Am 02.05.2011 21:57, schrieb Nils Kneuper:
> The changes done by Crab_ require a pot-update since some changed strings were
> introduced. I plan to do this tomorrow morning. So if you have any fixes left
> that change strings, commit them ASAP (meaning: in the next 12 hours). After the
> pot-update the translators have at least a week to fix the strings, then I will
> release 1.8.6. After the pot-update a *string freeze* is active for trunk!

Made a mistake, of course there is no freeze on trunk, but on branches/1.8.

Cheers,
Nils Kneuper aka Ivanovic
Nils Kneuper | 3 May 2011 14:37
Picon

Re: Release of 1.8.6


I just committed the pot-update for branches/1.8. My current plan is to release
1.8.6 (the really last 1.8.x release) on Wednesday next week (11th May). If you
have anything left, make sure to commit it before Wednesday. If you find any
blocker, please make sure to inform me immediately.
Cheers,
Nils Kneuper aka Ivanovic
Lukasz Dobrogowski | 12 May 2011 03:19
Picon
Gravatar

Refactoring of game.cpp code

Hello,

When trying to reimplement parsing of the define= and extra_defines= in
the multiplayer code, I stumbled upon a problem, namely: where to put
that extra code and how to communicate with classification() from the
game.cpp with it?

Comments of anybody knowledgeable with architecture of game.cpp are welcome.

The problem is outlined below in more detail:
http://pastebin.com/rJ83TbcN

For the overview of the general goal for those not familiar with it (I'm
a GSoC student), please read
http://wiki.wesnoth.org/Zaroth_Multiplayer_Improvements#Better_integration_of_MP_campaigns
.

Cheers,
Zaroth

_______________________________________________
Wesnoth-dev mailing list
Wesnoth-dev <at> gna.org
https://mail.gna.org/listinfo/wesnoth-dev
jeremy rosen | 12 May 2011 16:47
Picon
Picon

Re: Refactoring of game.cpp code

Thanks for the clarification, it helps a lot, I have a couple of
questions, but we might as well wait until we meet on IRC.

Basically our old split between game.cpp and multiplayer_create.cpp
doesn't really make sense now that all games are handled as
multiplayer games.

from that point of view it makes sense to merge these two... OTOH we
don't want to have one huge game.cpp (been there, done that...)

moreover we currently have three path for creating a game

* the current SP path (game.cpp:new_campaign() => game.cpp:launch_game())
* the current MP path (game.cpp:play_multiplayer() => game.cpp:launch_game())
* your new code (multiplayer_create.cpp => game.cpp:launch_game())

looking at what you pastebined, it seems that if you regroup
everything in game.cpp you would merge most of the code together and
thus the game.cpp file wouldn't increase that much in size. So it
seems to me that merging everything in game.cpp is the most logical
first step. once that is done, we can see how bad it is and if we need
to reorganizee those two files, but let's merge them first...

Boucman
Lukasz Dobrogowski | 25 May 2011 21:45
Picon
Gravatar

Re: Refactoring of game.cpp code

Hello,

Everybody seems to agree that game.cpp is bloated and inflexible in its
current form. I prepared a list of responsibilities that game.cpp is
taking care of (together with functions doing the jobs):

0. Starting and initializing the game (main(), do_gameloop())
  a. Setup of environment (launching SDL, loading fonts...)
1. Parsing command line (game_controller::game_controller(),
game_controller::play_multiplayer_mode(), process_command_args())
2. Running the game_loop (do_gameloop()):
  a. Controlling titlescreen and tips of the day
  b. Playing music
  c. Maintaining jumps caused by choices on title screen
3. Parsing the whole game config (everything in data/ and user addons/
directory) (game_controller::load_game_cfg())
  Note: this is the part which makes game.cpp gamestate-dependant. Most
of the things it parses should be moved into game_instance.cpp
  a. Showing loading screen
  b. Generating data tree checksum which isn't used (? - correct me if
I'm wrong)
  c. Parsing data/ directory inside a locked transaction into cache_
  d. Calling functions to find user campaign directories in filesystem
and parsing *.cfg in there as well
  e. Extracting preload scripts from [lua] from lua.hpp
  f. Setting color range and color palette (it stays in the game_config)
  g. Generating multiplayer hashes
  h. Calling unit manager to initialize unit types
  i. Setting terrain rules of terrain_builder
  j. Initializing "certain English strings"
(Continue reading)

Gabriel Morin | 28 May 2011 21:51
Picon

Re: Refactoring of game.cpp code

2011/5/25 Lukasz Dobrogowski <lukasz.dobrogowski <at> gmail.com>
Hello,

Everybody seems to agree that game.cpp is bloated and inflexible in its
current form. I prepared a list of responsibilities that game.cpp is
taking care of (together with functions doing the jobs):
[...]

Just one thing to keep in mind: last year I tried to introduce a feature so that local players ("hot-seat" players) could be named instead of showing in-game as "Anonymous Local Player".

At first I added a button* that allowed you to add a named local player, but if you picked a name that was the same as that of a network player (i.e. usually someone registered on the server) who later joined, problems ensued. I envisioned  some refactoring but most of my ideas (which I don't remember precisely by now) clashed with the unification of every game mode as a multiplayer game in the code. Basically Ivanovic told me that many of my ideas amounted to splitting hotseat games from multiplayer ones again.

So, since you're doing major refactoring in the area, please keep this needed feature in mind, it would be very nice if you made it possible or even implemented it as a side-effect of something else.

Wesnoth is actually pretty unique amond strategy games as it supports network games where some slots are filled with hot-seat players, and I think it's a great feature. We just need to fix that nagging name issue without causing trouble on the public wesnoth server.

Gabba

*said button is actually still in the multiplayer lobby, but is invisible.
_______________________________________________
Wesnoth-dev mailing list
Wesnoth-dev <at> gna.org
https://mail.gna.org/listinfo/wesnoth-dev
Lukasz Dobrogowski | 29 May 2011 21:14
Picon
Gravatar

Move of command line parsing code and new dependency (Boost.Program_options)

Hello,

I'm moving all the command line parsing code to a new class,
commandline_options. The code is currently spread between
game.cpp:process_command_args(), game_controller::game_controller() and
game_controller::play_multiplayer_mode().

As an added bonus, it will use Boost.Program_options library to do the
job, which should result in a less error-prone and more consistent parsing.
Slight syntax changes of command line parameters may occur, so please
check your scripts using Wesnoth binary for compatibility when the
changes are done. I will post list of changes (if any) here, as well.

Cheers,
Zaroth

_______________________________________________
Wesnoth-dev mailing list
Wesnoth-dev <at> gna.org
https://mail.gna.org/listinfo/wesnoth-dev
Lukasz Dobrogowski | 30 May 2011 09:19
Picon
Gravatar

Template problem: help needed

Hello,

I encountered a weird template specialization linking problem when
coding, connected to util.hpp and util.cpp.

Moving the template to the header didn't fix it. Obviously, it now
complains a thousand times about multiple definitions of the same template.

Steps to reproduce:
* apply attached patch against r49705
* wesnoth should compile
* uncomment line line 128 in game_controller.cpp ( // int fps = 0;) and
comment line 127 (the lexical_cast_default)
* wesnoth should stop compiling (linking, to be precise) at this point,
producing following error: http://pastebin.com/84PMcxjU

Please, help: I'm not that advanced with solving C++ template problems
and it may take me quite a while until I find a solution. The bug is
certainly isolated to this one line: before commenting use of
lexical_cast_default it happens, afterwards not.

For full information about the problem, my and Crab_ IRC discussion
about it was
http://www.wesnoth.org/irclogs/2011/05/%23wesnoth-dev.2011-05-30.log
from 0:30 to 1:54.

Cheers,
Zaroth
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 601d587..1a2499f 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
 <at>  <at>  -70,6 +70,7  <at>  <at>  else(MSVC)
 		${SDL_LIBRARY}
 		${Boost_IOSTREAMS_LIBRARY}
 		${Boost_REGEX_LIBRARY}
+		${Boost_PROGRAM_OPTIONS_LIBRARY}
 	)
 endif(MSVC)

diff --git a/src/commandline_options.cpp b/src/commandline_options.cpp
index 5c056d3..a1f44f6 100644
--- a/src/commandline_options.cpp
+++ b/src/commandline_options.cpp
 <at>  <at>  -15,7 +15,9  <at>  <at> 

 #include "commandline_options.hpp"

-commandline_options::commandline_options ( int /* argc*/, char** /*argv*/ ) :
+namespace po = boost::program_options;
+
+commandline_options::commandline_options ( int argc, char** argv ) :
 	bpp(),
 	campaign(),
 	campaign_difficulty(),
 <at>  <at>  -34,6 +36,7  <at>  <at>  commandline_options::commandline_options ( int /* argc*/, char** /*argv*/ ) :
 	fullscreen(false),
 	gunzip(),
 	gzip(),
+	help(),
 	log(),
 	load(),
 	logdomains(),
 <at>  <at>  -70,7 +73,85  <at>  <at>  commandline_options::commandline_options ( int /* argc*/, char** /*argv*/ ) :
 	validcache(false),
 	version(false),
 	windowed(false),
-	with_replay(false)
+	with_replay(false),
+	argc_(argc),
+	argv_(argv),
+	all_(),
+	visible_(),
+	hidden_()
 {
+	// When adding items don't forget to update doc/man/wesnoth.6
+	// Options are sorted alphabetically by --long-option.
+	po::options_description general_opts("General options");
+	general_opts.add_options()
+		("config-dir", po::value<std::string>(), "sets the path of the user config directory to
$HOME/<arg> or My Documents\\My Games\\<arg> for Windows. You can specify also an absolute path outside
the $HOME or My Documents\\My Games directory.")
+		("data-dir", po::value<std::string>(), "overrides the data directory with the one specified.")
+		("debug,d", "enables additional command mode options in-game.")
+		("help,h", "prints this message and exits.")
+		("load,l", po::value<std::string>(), "loads the save <arg> from the standard save game
directory.\nWhen launching the map editor via -e, the map <arg> is loaded, relative to the current
directory. If it is a directory, the editor will start with a load map dialog opened there.")
+		("new-syntax", "enables the new campaign syntax parsing.")
+		("nocache", "disables caching of game data.")
+		("path", "prints the path to the data directory and exits.")
+		("validcache", "assumes that the cache is valid. (dangerous)")
+		("version,v", "prints the game's version number and exits.")
+		("with-replay", "replays the file loaded with the --load option.")
+		;
+	po::options_description display_opts("Display options");
+	display_opts.add_options()
+		("bpp", po::value<int>(), "sets BitsPerPixel value. Example: --bpp 32")
+		("fps", "displays the number of frames per second the game is currently running at, in a corner of the screen.")
+		("max-fps", "the maximum fps the game tries to run at. Values should be between 1 and 1000, the default is 50.")
+		;
+	
+	hidden_.add_options()
+		("new_storyscreens", "")
+		("new-widgets", "")
+		;
+	
+	visible_.add(general_opts).add(display_opts);
+	
+	all_.add(visible_).add(hidden_);
+	
+	po::variables_map vm;
+	po::store(po::parse_command_line(argc_,argv_,all_),vm);
+
+	if (vm.count("bpp"))
+		bpp = vm["bpp"].as<int>();
+	if (vm.count("config-dir"))
+		config_dir = vm["config-dir"].as<std::string>();
+	if (vm.count("data-dir"))
+		data_dir = vm["data-dir"].as<std::string>();
+	if (vm.count("debug"))
+		debug = true;
+	if (vm.count("fps"))
+		fps = true;
+	if (vm.count("help"))
+		help = true;
+	if (vm.count("load"))
+		load = vm["load"].as<std::string>();
+	if (vm.count("max-fps"))
+		max_fps = vm["max-fps"].as<int>();
+	if (vm.count("new-storyscreens"))
+		new_storyscreens = true;
+	if (vm.count("new-syntax"))
+		new_syntax = true;
+	if (vm.count("new-widgets"))
+		new_widgets = true;
+	if (vm.count("nocache"))
+		nocache = true;
+	if (vm.count("path"))
+		path = true;
+	if (vm.count("validcache"))
+		validcache = true;
+	if (vm.count("version"))
+		version = true;
+	if (vm.count("with-replay"))
+		with_replay = true;
+}

+std::ostream& operator<<(std::ostream &os, const commandline_options& cmdline_opts)
+{
+	os << "Usage: " << cmdline_opts.argv_[0] << " [<options>] [<data-directory>]\n";
+	os << cmdline_opts.visible_;
+	return os;
 }
diff --git a/src/commandline_options.hpp b/src/commandline_options.hpp
index 70442ea..e68c8ce 100644
--- a/src/commandline_options.hpp
+++ b/src/commandline_options.hpp
 <at>  <at>  -25,6 +25,9  <at>  <at> 

 class commandline_options
 {
+/// To be used for printing help to the commandline.
+friend std::ostream& operator<<(std::ostream &os, const commandline_options& cmdline_opts);
+
 public:
 	commandline_options(int argc, char **argv);

 <at>  <at>  -62,6 +65,8  <at>  <at>  public:
 	boost::optional<std::string> gunzip;
 	/// Non-empty if --gzip was given on the command line. Compresses a file to .gz and exits.
 	boost::optional<std::string> gzip;
+	/// True if --help was given on the command line. Prints help and exits.
+	bool help;
 	/// Contains parsed arguments of --log-* (e.g. --log-debug).
 	/// Vector of pairs (severity, log domain).
 	boost::optional<std::vector<std::pair<int, std::string> > > log;
 <at>  <at>  -138,6 +143,11  <at>  <at>  public:
 	/// True if --with-replay was given on the command line. Shows replay of the loaded file.
 	bool with_replay;
 private:
+	int argc_;
+	char **argv_;
+	boost::program_options::options_description all_;
+	boost::program_options::options_description visible_;
+	boost::program_options::options_description hidden_;
 };

 #endif
diff --git a/src/game.cpp b/src/game.cpp
index 28f77c9..24e9cd7 100644
--- a/src/game.cpp
+++ b/src/game.cpp
 <at>  <at>  -20,6 +20,7  <at>  <at> 

 #include "about.hpp"
 #include "addon/manager.hpp"
+#include "commandline_options.hpp"
 //#include "ai/configuration.hpp"
 //#include "config.hpp"
 //#include "config_cache.hpp"
 <at>  <at>  -161,172 +162,59  <at>  <at>  public:
 };

 /** Process commandline-arguments */
-static int process_command_args(int argc, char** argv) {
+static int process_command_args(int argc, char** argv, const commandline_options& cmdline_opts) {
 	const std::string program = argv[0];
 	game_config::wesnoth_program_dir = directory_name(program);
 	preprocess_options preproc;

+	if(cmdline_opts.config_dir) {
+		set_preferences_dir(*cmdline_opts.config_dir);
+	}
+	if(cmdline_opts.data_dir) {
+		const std::string datadir = *cmdline_opts.data_dir;
+		std::cerr << "Overriding data directory with " << datadir << std::endl;
+#ifdef _WIN32
+		// use c_str to ensure that index 1 points to valid element since c_str() returns null-terminated string
+		if(datadir.c_str()[1] == ':') {
+#else
+		if(datadir[0] == '/') {
+#endif
+			game_config::path = datadir;
+		} else {
+			game_config::path = get_cwd() + '/' + datadir;
+		}
+
+		if(!is_directory(game_config::path)) {
+			std::cerr << "Could not find directory '" << game_config::path << "'\n";
+			throw config::error("directory not found");
+		}
+	// don't update font as we already updating it in game ctor
+	}
+	if(cmdline_opts.help) {
+		std::cout << cmdline_opts;
+		return 0;
+	}
+	if(cmdline_opts.new_syntax) {
+		game_config::new_syntax = true;
+	}
+	if(cmdline_opts.path) {
+		std::cout <<  game_config::path << "\n";
+		return 0;
+	}
+	if(cmdline_opts.version) {
+		std::cout << "Battle for Wesnoth" << " " << game_config::version << "\n";
+		return 0;
+	}
+
 	//parse arguments that shouldn't require a display device
 	int arg;
 	for(arg = 1; arg != argc; ++arg) {
 		const std::string val(argv[arg]);
 		if(val.empty()) {
 			continue;
-		}
-
-		if(val == "--help" || val == "-h") {
-			// When adding items don't forget to update doc/man/wesnoth.6
-			// Options are sorted alphabetically by --long-option.
-			// Please keep the output to 80 chars per line.
-			std::cout << "usage: " << argv[0]
-			<< " [<options>] [<data-directory>]\n"
-			<< "Available options:\n"
-			<< "  --bpp <number>               sets BitsPerPixel value. Example: --bpp 32\n"
-			<< "  -c, --campaign[[<difficulty>] <id_c> [<id_s>]]\n"
-			<< "                               goes directly to the campaign.\n"
-			<< "                               - difficulty : the difficulty of the specified\n"
-			<< "                                          campaign (1 to max - Default is 1)\n"
-			<< "                               - id_c: the id of the campaign. A selection \n"
-			<< "                                       menu will appear if none specified\n"
-			<< "                               - id_s: the id of the scenario from the\n"
-			<< "                                       specified campaign\n"
-			<< "                               Note: When using this switch please ensure that\n"
-			<< "                               you specify the data directory path as the\n"
-			<< "                               final argument aswell, otherwise the game\n"
-			<< "                               will take the campaign/scenario id as the data dir.\n"
-			<< "  --config-dir <name>          sets the path of the user config directory to\n"
-			<< "                               $HOME/<name> or My Documents\\My Games\\<name> for windows.\n"
-			<< "                               You can specify also an absolute path outside the\n"
-			<< "                               $HOME or My Documents\\My Games directory.\n"
-			<< "  --config-path                prints the path of the user config directory and\n"
-			<< "                               exits.\n"
-			<< "  --data-dir <directory>       overrides the data directory with the one specified.\n"
-			<< "  -d, --debug                  enables additional command mode options in-game.\n"
-#ifdef DEBUG_WINDOW_LAYOUT_GRAPHS
-			<< "  --debug-dot-level=<level1>,<level2>,...\n"
-			<< "                               sets the level of the debug dot files.\n"
-			<< "                               These files are used for debugging the widgets\n"
-			<< "                               especially the for the layout engine. When enabled\n"
-			<< "                               the engine will produce dot files which can be\n"
-			<< "                               converted to images with the dot tool.\n"
-			<< "                               Available levels:\n"
-			<< "                               - size  : generate the size info of the widget.\n"
-			<< "                               - state : generate the state info of the widget.\n"
-			<< "  --debug-dot-domain=<domain1>,<domain2>,...\n"
-			<< "                               sets the domain of the debug dot files.\n"
-			<< "                               see --debug-dot-level for more info.\n"
-			<< "                               Available domains:\n"
-			<< "                               show   : generate the data when the dialog is\n"
-			<< "                                        about to be shown.\n"
-			<< "                               layout : generate the data during the layout\n"
-			<< "                                        phase (might result in multiple files. \n"
-			<< "                               The data can also be generated when the F12 is\n"
-			<< "                               pressed in a dialog.\n"
-#endif
-			<< "  -e, --editor [<file>]        starts the in-game map editor directly. If <file>\n"
-			<< "                               is specified, equivalent to -e --load <file>.\n"
-			<< "  --fps                        displays the number of frames per second the\n"
-			<< "                               game is currently running at, in a corner of\n"
-			<< "                               the screen.\n"
-			<< "  -f, --fullscreen             runs the game in full screen mode.\n"
-			<< "  --gunzip <infile>.gz         decompresses a file (<infile>.gz) in gzip format\n"
-			<< "                               and stores it without the .gz suffix.\n"
-			<< "                               <infile>.gz will be removed.\n"
-			<< "  --gzip <infile>              compresses a file (<infile>) in gzip format,\n"
-			<< "                               stores it as <infile>.gz and removes <infile>.\n"
-			<< "  -h, --help                   prints this message and exits.\n"
-			<< "  -l, --load <file>            loads the save <file> from the standard save\n"
-			<< "                               game directory.\n"
-			<< "                               When launching the map editor via -e, the map\n"
-			<< "                               <file> is loaded, relative to the current\n"
-			<< "                               directory. If it is a directory, the editor\n"
-			<< "                               will start with a load map dialog opened there.\n"
-			<< "  --log-≤level>=<domain1>,<domain2>,...\n"
-			<< "                               sets the severity level of the log domains.\n"
-			<< "                               'all' can be used to match any log domain.\n"
-			<< "                               Available levels: error, warning, info, debug.\n"
-			<< "                               By default the 'error' level is used.\n"
-			<< "  --logdomains [filter]        lists defined log domains (only the ones containing\n"
-			<< "                               [filter] if used) and exits.\n"
-			<< "  --max-fps                    the maximum fps the game tries to run at. Values\n"
-			<< "                               should be between 1 and 1000, the default is 50.\n"
-			<< "  -m, --multiplayer            starts a multiplayer game. There are additional\n"
-			<< "                               options that can be used as explained below:\n"
-			<< "    --ai_config<number>=value  selects a configuration file to load for this side.\n"
-			<< "    --algorithm<number>=value  selects a non-standard algorithm to be used by\n"
-			<< "                               the AI controller for this side.\n"
-			<< "    --controller<number>=value selects the controller for this side.\n"
-			<< "    --era=value                selects the era to be played in by its id.\n"
-			<< "    --exit-at-end              exit Wesnoth at the end of the scenario.\n"
-			<< "    --nogui                    runs the game without the GUI. Must appear before\n"
-			<< "                               --multiplayer to have the desired effect.\n"
-			<< "    --parm<number>=name:value  sets additional parameters for this side.\n"
-			<< "    --scenario=value           selects a multiplayer scenario. The default\n"
-			<< "                               scenario is \"multiplayer_The_Freelands\".\n"
-			<< "    --side<number>=value       selects a faction of the current era for this\n"
-			<< "                               side by id.\n"
-			<< "    --turns=value              sets the number of turns. The default is \"50\".\n"
-			<< "  --new-syntax                 enables the new campaign syntax parsing.\n"
-			<< "  --no-delay                   runs the game without any delays.\n"
-			<< "  --nocache                    disables caching of game data.\n"
-			<< "  --nomusic                    runs the game without music.\n"
-			<< "  --nosound                    runs the game without sounds and music.\n"
-			<< "  --path                       prints the path to the data directory and exits.\n"
-			<< "  --preprocess, -p[=<define1>,<define2>,...] <file/folder> <target directory>\n"
-			<< "                               preprocesses a specified file/folder. The preprocessed\n"
-			<< "                               file(s) will be written in the specified target\n"
-			<< "                               directory: a plain cfg file and a processed cfg file.\n"
-			<< "                               define1,define2,...  - the extra defines will\n"
-			<< "                               be added before processing the files. If you add\n"
-			<< "                               them you must add the '=' character before.\n"
-			<< "                               If 'SKIP_CORE' is in the define list the\n"
-			<< "                               data/core won't be preprocessed.\n"
-			<< " --preprocess-input-macros <source file>\n"
-			<< "                               used only by the '--preprocess' command.\n"
-			<< "                               Specifies a file that contains [preproc_define]s\n"
-			<< "                               to be included before preprocessing.\n"
-			<< " --preprocess-output-macros [<target file>]\n"
-			<< "                               used only by the '--preprocess' command.\n"
-			<< "                               Will output all preprocessed macros in the target file.\n"
-			<< "                               If the file is not specified the output will be\n"
-			<< "                               file '_MACROS_.cfg' in the target directory of\n"
-			<< "                               preprocess's command. This switch should be typed\n"
-			<< "                               before the --preprocess command.\n"
-			<< "  -r, --resolution XxY         sets the screen resolution. Example: -r 800x600\n"
-			<< "  --rng-seed <number>          seeds the random number generator with number\n"
-			<< "                               Example: --rng-seed 0\n"
-			<< "  --screenshot <map> <output>  Saves a screenshot of <map> to <output> without\n"
-			<< "                               initializing a screen. Editor must be compiled\n"
-			<< "                               in for this to work.\n"
-			<< "  -s, --server [<host>]        connects to the host if specified\n"
-			<< "                               or to the first host in your preferences.\n"
-			<< "  -t, --test                   runs the game in a small test scenario.\n"
-			<< "  --validcache                 assumes that the cache is valid. (dangerous)\n"
-			<< "  -v, --version                prints the game's version number and exits.\n"
-			<< "  -w, --windowed               runs the game in windowed mode.\n"
-			<< "  --with-replay                replays the file loaded with the --load option.\n"
-			<< "  --new-widgets                there is a new WIP widget toolkit this switch\n"
-			<< "                               enables the new toolkit (VERY EXPERIMENTAL don't\n"
-			<< "                               file bug reports since most are known).\n"
-			<< "                               Parts of the library are deemed stable and will\n"
-			<< "                               work without this switch.\n"
-			<< "  --clock                      Adds the option to show a clock for testing the\n"
-			<< "                               drawing timer.\n"
-			;
-			return 0;
-		} else if(val == "--version" || val == "-v") {
-			std::cout << "Battle for Wesnoth" << " " << game_config::version
-			          << "\n";
-			return 0;
-		} else if (val == "--new-syntax") {
-			game_config::new_syntax = true;
 		} else if (val == "--config-path") {
 			std::cout << get_user_data_dir() << '\n';
 			return 0;
-		} else if(val == "--path") {
-			std::cout <<  game_config::path
-			          << "\n";
-			return 0;
 		}
 		else if (val == "--screenshot" ) {
 			if(!(argc > arg + 2)) {
 <at>  <at>  -335,36 +223,6  <at>  <at>  static int process_command_args(int argc, char** argv) {
 			}
 			static char opt[] = "SDL_VIDEODRIVER=dummy";
 			SDL_putenv(opt);
-		}
-		else if(val == "--config-dir") {
-			if (argc <= ++arg)
-				break;
-			set_preferences_dir(argv[arg]);
-		} else if(val == "--data-dir") {
-			if(arg +1 != argc) {
-				++arg;
-				const std::string datadir(argv[arg]);
-				std::cerr << "Overriding data directory with " << datadir << std::endl;
-#ifdef _WIN32
-				// use c_str to ensure that index 1 points to valid element since c_str() returns null-terminated string
-				if(datadir.c_str()[1] == ':') {
-#else
-				if(datadir[0] == '/') {
-#endif
-					game_config::path = datadir;
-				} else {
-					game_config::path = get_cwd() + '/' + datadir;
-				}
-
-				if(!is_directory(game_config::path)) {
-					std::cerr << "Could not find directory '" << game_config::path << "'\n";
-					throw config::error("directory not found");
-				}
-
-				// don't update font as we already updating it in game ctor
-			}
-			else
-				std::cerr << "please specify a data directory\n";
 		} else if (val.substr(0, 6) == "--log-") {
 			size_t p = val.find('=');
 			if (p == std::string::npos) {
 <at>  <at>  -614,7 +472,8  <at>  <at>  static int do_gameloop(int argc, char** argv)
 {
 	srand(time(NULL));

-	int finished = process_command_args(argc, argv);
+	commandline_options cmdline_opts = commandline_options(argc,argv);
+	int finished = process_command_args(argc, argv,cmdline_opts);
 	if(finished != -1) {
 		return finished;
 	}
 <at>  <at>  -626,7 +485,7  <at>  <at>  static int do_gameloop(int argc, char** argv)
 	if (game_config::new_syntax)
 		game = boost::shared_ptr<game_controller_abstract>(new game_controller_new());
 	else
-		game = boost::shared_ptr<game_controller_abstract>(new game_controller(argc,argv));
+		game = boost::shared_ptr<game_controller_abstract>(new game_controller(argc,argv,cmdline_opts));
 	const int start_ticks = SDL_GetTicks();

 	init_locale();
diff --git a/src/game_controller.cpp b/src/game_controller.cpp
index 37e6717..27c6d40 100644
--- a/src/game_controller.cpp
+++ b/src/game_controller.cpp
 <at>  <at>  -66,10 +66,11  <at>  <at>  static bool less_campaigns_rank(const config &a, const config &b) {
 	return a["rank"].to_int(1000) < b["rank"].to_int(1000);
 }

-game_controller::game_controller(int argc, char** argv) :
+game_controller::game_controller(int argc, char** argv, const commandline_options&
cmdline_opts) :
 	argc_(argc),
 	arg_(1),
 	argv_(argv),
+	cmdline_opts_(cmdline_opts),
 	thread_manager(),
 	font_manager_(),
 	prefs_manager_(),
 <at>  <at>  -116,32 +117,44  <at>  <at>  game_controller::game_controller(int argc, char** argv) :
 	const std::string app_basename = file_name(argv[0]);
 	jump_to_editor_ = app_basename.find("editor") != std::string::npos;

+	if (cmdline_opts_.bpp)
+		force_bpp_ = *cmdline_opts_.bpp;
+	if (cmdline_opts_.fps)
+		preferences::set_show_fps(true);
+	if (cmdline_opts_.load)
+		game::load_game_exception::game = *cmdline_opts_.load;
+	if (cmdline_opts_.max_fps) {
+		int fps = lexical_cast_default<int>(argv_[arg_], 50);
+// 		int fps = 0;
+		fps = std::min<int>(fps, 1000);
+		fps = std::max<int>(fps, 1);
+		fps = 1000 / fps;
+		// increase the delay to avoid going above the maximum
+		if(1000 % fps != 0) {
+			++fps;
+		}
+		preferences::set_draw_delay(fps);
+	} 
+	if (cmdline_opts_.new_storyscreens)
+		// This is a hidden option to help testing
+		// the work-in-progress new storyscreen code.
+		// Don't document.
+		set_new_storyscreen(true);
+	if (cmdline_opts_.new_widgets)
+		gui2::new_widgets = true;
+	if (cmdline_opts_.nocache)
+		cache_.set_use_cache(false);
+	if (cmdline_opts_.validcache)
+		cache_.set_force_valid_cache(true);
+	if (cmdline_opts_.with_replay)
+		game::load_game_exception::show_replay = true;
+
 	for(arg_ = 1; arg_ != argc_; ++arg_) {
 		const std::string val(argv_[arg_]);
 		if(val.empty()) {
 			continue;
 		}
-
-		if(val == "--fps") {
-			preferences::set_show_fps(true);
-		} else if(val == "--nocache") {
-			cache_.set_use_cache(false);
-		} else if(val == "--max-fps") {
-			if(arg_+1 != argc_) {
-				++arg_;
-				int fps = lexical_cast_default<int>(argv_[arg_], 50);
-				fps = std::min<int>(fps, 1000);
-				fps = std::max<int>(fps, 1);
-				fps = 1000 / fps;
-				// increase the delay to avoid going above the maximum
-				if(1000 % fps != 0) {
-					++fps;
-				}
-				preferences::set_draw_delay(fps);
-			}
-		} else if(val == "--validcache") {
-			cache_.set_force_valid_cache(true);
-		} else if(val == "--resolution" || val == "-r") {
+		else if(val == "--resolution" || val == "-r") {
 			if(arg_+1 != argc_) {
 				++arg_;
 				const std::string val(argv_[arg_]);
 <at>  <at>  -155,19 +168,6  <at>  <at>  game_controller::game_controller(int argc, char** argv) :
 					}
 				}
 			}
-		} else if(val == "--bpp") {
-			if(arg_+1 != argc_) {
-				++arg_;
-				force_bpp_ = lexical_cast_default<int>(argv_[arg_],-1);
-			}
-		} else if(val == "--load" || val == "-l") {
-			if(arg_+1 != argc_) {
-				++arg_;
-				game::load_game_exception::game = argv_[arg_];
-			}
-		} else if(val == "--with-replay") {
-			game::load_game_exception::show_replay = true;
-
 		} else if(val == "--nogui") {
 			no_gui_ = true;
 			no_sound = true;
 <at>  <at>  -269,15 +269,10  <at>  <at>  game_controller::game_controller(int argc, char** argv) :
 			no_sound = true;
 		} else if(val == "--nomusic") {
 			no_music = true;
-		} else if(val == "--new-storyscreens") {
-			// This is a hidden option to help testing
-			// the work-in-progress new storyscreen code.
-			// Don't document.
-			set_new_storyscreen(true);
-        }  //These commented lines should be used to implement support of connection
-             //through a proxy via command line options.
-             //The ANA network module should implement these methods (while the SDL_net won't.)
-            else if(val == "--proxy") {
+		}   //These commented lines should be used to implement support of connection
+            //through a proxy via command line options.
+            //The ANA network module should implement these methods (while the SDL_net won't.)
+        else if(val == "--proxy") {
             network::enable_connection_through_proxy();
         } else if(val == "--proxy-address") {
             if ( argv_[ arg_ + 1][0] != '-')
 <at>  <at>  -312,10 +307,7  <at>  <at>  game_controller::game_controller(int argc, char** argv) :
             }
             else
                 throw std::runtime_error("Proxy password option requires password");
-        } else if(val == "--new-widgets") {
-			// This is a hidden option to enable the new widget toolkit.
-			gui2::new_widgets = true;
-		}
+        }
 		else if(val == "--clock") {
 			gui2::show_debug_clock_button = true;
 		} else if(val == "-e" || val == "--editor") {
 <at>  <at>  -328,7 +320,7  <at>  <at>  game_controller::game_controller(int argc, char** argv) :
 			}
 		} else if(val[0] == '-') {
 			std::cerr << "unknown option: " << val << std::endl;
-			throw config::error("unknown option");
+			//throw config::error("unknown option"); TODO will be unnecessary here once commandline_options
is completed
 		} else {
 			std::cerr << "Overriding data directory with " << val << std::endl;
 #ifdef _WIN32
diff --git a/src/game_controller.hpp b/src/game_controller.hpp
index b6ea8d7..b3383ae 100644
--- a/src/game_controller.hpp
+++ b/src/game_controller.hpp
 <at>  <at>  -17,6 +17,7  <at>  <at> 

 #include "game_controller_abstract.hpp"

+#include "commandline_options.hpp"
 #include "config_cache.hpp"
 #include "filesystem.hpp"
 #include "gamestatus.hpp"
 <at>  <at>  -45,7 +46,7  <at>  <at>  public:
 class game_controller : public game_controller_abstract
 {
 public:
-	game_controller(int argc, char** argv);
+	game_controller(int argc, char** argv, const commandline_options& cmdline_opts);
 	~game_controller();

 	bool init_config() { return init_config(false); }
 <at>  <at>  -96,6 +97,7  <at>  <at>  private:
 	const int argc_;
 	int arg_;
 	const char* const * const argv_;
+	const commandline_options& cmdline_opts_;

 	//this should get destroyed *after* the video, since we want
 	//to clean up threads after the display disappears.
_______________________________________________
Wesnoth-dev mailing list
Wesnoth-dev <at> gna.org
https://mail.gna.org/listinfo/wesnoth-dev
christopher hopman | 30 May 2011 11:35
Picon

Re: Template problem: help needed

Hey Zaroth,


This isn't actually a template specialization problem. It is actually a linker problem. That is, the way that those functions are specialized and explicitly instantiated is correct and the symbols appear correctly in the libwesnoth.a archive.

So, I think the actual problem is due to a slight subtlety in the linking. We basically link in the order: libwesnoth_extras.a   libwesnoth_core.a   libwesnoth.a (with some other stuff mixed in). Now, with the GNU ld linker, these are linked in that order and after linking a library unneeded symbols are discarded. Now, game_controller.cpp is in _extras, util.cpp is in _core, and  hotkeys.cpp and image_modifications.cpp are in libwesnoth.a. It seems that the only use of those lexical_casts in _extras come from game_controller.cpp:128 and so by removing that line, the symbols are discarded after linking in libwesnoth_core, and then are not present when linking in libwesnoth. 

Two simple solutions that seem to work for me are either swapping the order of linking libwesnoth_core.a and libwesnoth.a, or moving util.cpp to libwesnoth.a. I personally prefer swapping the order of linking as I feel that _core implies that it should not depend on anything else (and thus should be linked in last).

Hope that helps,
Chris Hopman


On Mon, May 30, 2011 at 12:19 AM, Lukasz Dobrogowski <lukasz.dobrogowski <at> gmail.com> wrote:
Hello,

I encountered a weird template specialization linking problem when
coding, connected to util.hpp and util.cpp.

Moving the template to the header didn't fix it. Obviously, it now
complains a thousand times about multiple definitions of the same template.

Steps to reproduce:
* apply attached patch against r49705
* wesnoth should compile
* uncomment line line 128 in game_controller.cpp ( // int fps = 0;) and
comment line 127 (the lexical_cast_default)
* wesnoth should stop compiling (linking, to be precise) at this point,
producing following error: http://pastebin.com/84PMcxjU

Please, help: I'm not that advanced with solving C++ template problems
and it may take me quite a while until I find a solution. The bug is
certainly isolated to this one line: before commenting use of
lexical_cast_default it happens, afterwards not.

For full information about the problem, my and Crab_ IRC discussion
about it was
http://www.wesnoth.org/irclogs/2011/05/%23wesnoth-dev.2011-05-30.log
from 0:30 to 1:54.

Cheers,
Zaroth

_______________________________________________
Wesnoth-dev mailing list
Wesnoth-dev <at> gna.org
https://mail.gna.org/listinfo/wesnoth-dev


_______________________________________________
Wesnoth-dev mailing list
Wesnoth-dev <at> gna.org
https://mail.gna.org/listinfo/wesnoth-dev

Gmane