Esempio n. 1
0
statistics_dialog::statistics_dialog(game_display &disp,
		const std::string& title,
		const unsigned int team,
		const std::string& team_id,
		const std::string& player) :
	dialog(disp.video(), title, "", gui::NULL_DIALOG),
	detail_btn_(new gui::standard_dialog_button(disp.video(), _("Details"), 0 , false)),
	toggle_btn_(new gui::dialog_button(disp.video(), "", gui::button::TYPE_PRESS, BUTTON_TOGGLE)),
	scene_btn_(new gui::dialog_button(disp.video(), _("Select Scenario"), gui::button::TYPE_PRESS, BUTTON_SCENE)),
	player_name_(player),
	campaign_(statistics::calculate_stats(team_id)),
	scenarios_(statistics::level_stats(team_id)),
	scenario_index_(scenarios_.size() - 1), // current scenario
	team_num_(team),
	unit_count_(5,0)
{
	if ( scenarios_.size() > 1 ) {
		add_button(scene_btn_, gui::dialog::BUTTON_EXTRA_LEFT);
		add_button(toggle_btn_, gui::dialog::BUTTON_EXTRA_LEFT);
	}
	add_button(detail_btn_, gui::dialog::BUTTON_EXTRA);
	add_button(new gui::standard_dialog_button(disp.video(), _("Close"), 1, true),
	           gui::dialog::BUTTON_STANDARD);

	// Initialize the displayed data.
	if ( use_campaign_  ||  scenarios_.size() == 1 )
		display_stats(use_campaign_);
	else {
		// Starting with the scenario stats, but we need to make sure the
		// window is wide enough for the campaign stats.
		display_stats(true);
		layout();
		display_stats(false);
	}
}
Esempio n. 2
0
/**
 *  Fade-in the wesnoth-logo.
 *
 *  Animation-effect: scroll-in from right. \n
 *  Used only once, after the game is started.
 *
 *  @param	screen	surface to operate on
 *  @param	xpos	x-position of logo
 *  @param	ypos	y-position of logo
 *
 *  @return		Result of running the routine
 *  @retval true	operation finished (successful or not)
 *  @retval false	operation failed (because modeChanged), need to retry
 */
static bool fade_logo(game_display& screen, int xpos, int ypos)
{
	const surface logo(image::get_image(game_config::game_logo));
	if(logo == NULL) {
		ERR_DP << "Could not find game logo\n";
		return true;
	}

	surface const fb = screen.video().getSurface();

	if(fb == NULL || xpos < 0 || ypos < 0 || xpos + logo->w > fb->w || ypos + logo->h > fb->h) {
		return true;
	}

	// Only once, when the game is first started, the logo fades in unless
	// it was disabled in adv. preferences
	static bool faded_in = !preferences::startup_effect();
//	static bool faded_in = true;	// for faster startup: mark logo as 'has already faded in'

	CKey key;
	bool last_button = key[SDLK_ESCAPE] || key[SDLK_SPACE];

	LOG_DP << "fading logo in....\n";
	LOG_DP << "logo size: " << logo->w << "," << logo->h << "\n";

	for(int x = 0; x != logo->w; ++x) {
		SDL_Rect srcrect = {x,0,1,logo->h};
		SDL_Rect dstrect = {xpos+x,ypos,1,logo->h};
		SDL_BlitSurface(logo,&srcrect,fb,&dstrect);

		update_rect(dstrect);

		if(!faded_in && (x%5) == 0) {

			const bool new_button = key[SDLK_ESCAPE] || key[SDLK_SPACE] ||
									key[SDLK_RETURN] || key[SDLK_KP_ENTER] ;
			if(new_button && !last_button) {
				faded_in = true;
			}

			last_button = new_button;

			screen.update_display();
			screen.delay(10);

			events::pump();
			if(screen.video().modeChanged()) {
				faded_in = true;
				return false;
			}
		}

	}

	LOG_DP << "logo faded in\n";

	faded_in = true;
	return true;
}
Esempio n. 3
0
wait::wait(game_display& disp, const config& cfg,
		mp::chat& c, config& gamelist) :
	ui(disp, _("Game Lobby"), cfg, c, gamelist),
	cancel_button_(disp.video(), _("Cancel")),
	start_label_(disp.video(), _("Waiting for game to start..."), font::SIZE_SMALL, font::LOBBY_COLOR),
	game_menu_(disp.video(), std::vector<std::string>(), false, -1, -1, NULL, &gui::menu::bluebg_style),
	level_(),
	state_(),
	stop_updates_(false)
{
	game_menu_.set_numeric_keypress_selection(false);
	gamelist_updated();
}
Esempio n. 4
0
	void floating_textbox::tab(std::vector<team>& teams, const unit_map& /*units*/, game_display& gui)
	{
		if(active() == false) {
			return;
		}

		switch(mode_) {
		case gui::TEXTBOX_SEARCH:
		case gui::TEXTBOX_COMMAND:
		case gui::TEXTBOX_MESSAGE:
		{
			std::string text = box_->text();
			std::vector<std::string> matches;
			// Add players
			for(size_t n = 0; n != teams.size(); ++n) {
				if(teams[n].is_empty()) continue;
				matches.push_back(teams[n].current_player());
			}
			// Add observers
			const std::set<std::string>& observers = gui.observers();
			for(std::set<std::string>::const_iterator i = observers.begin();
					i != observers.end(); ++i)
			{
					matches.push_back(*i);
			}
			// Remove duplicates.
			std::sort<std::vector<std::string>::iterator>
					(matches.begin(), matches.end());
			matches.erase(std::unique(matches.begin(), matches.end()), matches.end());
			// Exclude own nick from tab-completion.
			if (mode_ == gui::TEXTBOX_MESSAGE) {
				matches.erase(std::remove(matches.begin(), matches.end(),
						preferences::login()), matches.end());
			}
			const bool line_start = utils::word_completion(text, matches);

			if (matches.empty()) return;
			if (matches.size() == 1 && mode_ == gui::TEXTBOX_MESSAGE) {
				text.append(line_start ? ": " : " ");
			} else {
				std::string completion_list = utils::join(matches, ' ');
				gui.add_chat_message(time(NULL), "", 0, completion_list,
						game_display::MESSAGE_PRIVATE, false);
			}
			box_->set_text(text);
			break;
		}
		default:
			LOG_STREAM(err, display) << "unknown textbox mode\n";
		}
	}
Esempio n. 5
0
static void enter_create_mode(game_display& disp, const config& game_config, hero_map& heros, hero_map& heros_start, 
		card_map& cards, config& gamelist, mp::controller default_controller, bool local_players_only)
{
	mp::ui::result res;
	mp_game_settings params;
	int num_turns;

	// if (gui2::new_widgets) {
		gui2::tmp_create_game dlg(disp, game_config);
		dlg.show(disp.video());
		int retval = dlg.get_retval();
		if (retval == gui2::twindow::OK) {
			res = mp::ui::CREATE;
		} else {
			res = mp::ui::QUIT;
		}
		params = dlg.get_parameters();
		num_turns = dlg.num_turns();

		// network::send_data(config("refresh_lobby"), 0);

	switch (res) {
	case mp::ui::CREATE:
		enter_connect_mode(disp, game_config, heros, heros_start, cards, gamelist, params, num_turns, default_controller, local_players_only);
		break;
	case mp::ui::QUIT:
	default:
		//update lobby content
		network::send_data(config("refresh_lobby"), 0);
		break;
	}
}
static void enter_create_mode(game_display& disp, const config& game_config, mp::chat& chat, config& gamelist, mp::controller default_controller, bool local_players_only)
{
	if (0 && gui2::new_widgets) {

		gui2::tmp_create_game dlg(game_config);

		dlg.show(disp.video());

		network::send_data(config("refresh_lobby"), 0, true);
	} else {

		mp::ui::result res;
		mp_game_settings params;
		int num_turns;

		{
			mp::create ui(disp, game_config, chat, gamelist);
			run_lobby_loop(disp, ui);
			res = ui.get_result();
			params = ui.get_parameters();
			num_turns = ui.num_turns();
		}

		switch (res) {
		case mp::ui::CREATE:
			enter_connect_mode(disp, game_config, chat, gamelist, params, num_turns, default_controller, local_players_only);
			break;
		case mp::ui::QUIT:
		default:
			//update lobby content
			network::send_data(config("refresh_lobby"), 0, true);
			break;
		}
	}
}
Esempio n. 7
0
static void enter_wait_mode(game_display& disp, const config& game_config, hero_map& heros, hero_map& heros_start, card_map& cards, config& gamelist, bool observe)
{
	mp::ui::result res;
	game_state state;
	network_game_manager m;

	gamelist.clear();
	statistics::fresh_stats();

	gui2::tmp_side_wait dlg(heros, disp, *resources::game_map, game_config, gamelist, observe);
	dlg.show(disp.video());
	switch (dlg.get_legacy_result()) {
	case gui2::tmp_side_wait::PLAY:
		res = mp::ui::PLAY;
		dlg.start_game();
		state = dlg.get_state();
		// lobby may modify hero's side_feature
		heros_start = heros;
		break;
	default:
		res = mp::ui::QUIT;
	}

	switch (res) {
	case mp::ui::PLAY:
		play_game(disp, state, game_config, heros, heros_start, cards, IO_CLIENT,
			preferences::skip_mp_replay() && observe);
		recorder.clear();

		break;
	case mp::ui::QUIT:
	default:
		break;
	}
}
	void floating_textbox::show(gui::TEXTBOX_MODE mode, const std::string& label,
		const std::string& check_label, bool checked, game_display& gui)
	{
		close(gui);

		label_string_ = label;
		mode_ = mode;

		if(check_label != "") {
			check_.assign(new gui::button(gui.video(),check_label,gui::button::TYPE_CHECK));
			check_->set_check(checked);
		}


		box_.assign(new gui::textbox(gui.video(),100,"",true,256,0.8,0.6));

		update_location(gui);
	}
create_engine::create_engine(game_display& disp, saved_game& state) :
	current_level_type_(),
	current_level_index_(0),
	current_era_index_(0),
	current_mod_index_(0),
	level_name_filter_(),
	player_count_filter_(1),
	scenarios_(),
	user_maps_(),
	user_scenarios_(),
	campaigns_(),
	sp_campaigns_(),
	random_maps_(),
	user_map_names_(),
	user_scenario_names_(),
	eras_(),
	mods_(),
	state_(state),
	dependency_manager_(resources::config_manager->game_config(), disp.video()),
	generator_(NULL)
{
	DBG_MP << "restoring game config\n";

	// Restore game config for multiplayer.
	state_ = saved_game();
	state_.classification().campaign_type = game_classification::MULTIPLAYER;
	resources::config_manager->
		load_game_config_for_game(state_.classification());

	//TODO the editor dir is already configurable, is the preferences value
	get_files_in_dir(get_user_data_dir() + "/editor/maps", &user_map_names_,
		NULL, FILE_NAME_ONLY);

	get_files_in_dir(get_user_data_dir() + "/editor/scenarios", &user_scenario_names_,
		NULL, FILE_NAME_ONLY);

	DBG_MP << "initializing all levels, eras and mods\n";

	init_all_levels();
	init_extras(ERA);
	init_extras(MOD);

	state_.mp_settings().saved_game = false;

	BOOST_FOREACH (const std::string& str, preferences::modifications()) {
		if (resources::config_manager->
				game_config().find_child("modification", "id", str))
			state_.mp_settings().active_mods.push_back(str);
	}

	if (current_level_type_ != level::CAMPAIGN &&
		current_level_type_ != level::SP_CAMPAIGN) {
		dependency_manager_.try_modifications(state_.mp_settings().active_mods, true);
	}

	reset_level_filters();
}
Esempio n. 10
0
wait::wait(game_display& disp, const config& cfg, saved_game& state,
	mp::chat& c, config& gamelist, const bool first_scenario) :
	ui(disp, _("Game Lobby"), cfg, c, gamelist),
	cancel_button_(disp.video(), first_scenario ? _("Cancel") : _("Quit")),
	start_label_(disp.video(), _("Waiting for game to start..."), font::SIZE_SMALL, font::LOBBY_COLOR),
	game_menu_(disp.video(), std::vector<std::string>(), false, -1, -1, NULL, &gui::menu::bluebg_style),
	level_(),
	state_(state),
	first_scenario_(first_scenario),
	stop_updates_(false)
{
	game_menu_.set_numeric_keypress_selection(false);
	gamelist_updated();

	plugins_context_.reset(new plugins_context("Multiplayer Wait"));

	//These structure initializers create a lobby::process_data_event
	plugins_context_->set_callback("quit", 		boost::bind(&wait::process_event_impl, this, true), 						false);
	plugins_context_->set_callback("chat",		boost::bind(&wait::send_chat_message, this, boost::bind(get_str, _1, "message"), false),	true);
}
Esempio n. 11
0
static void enter_create_mode(game_display& disp, const config& game_config,
	game_state& state, bool local_players_only)
{
	DBG_MP << "entering create mode" << std::endl;

	bool configure_canceled;
	bool connect_canceled;

	do {
		configure_canceled = false;
		connect_canceled = false;

		if (gui2::new_widgets) {

			gui2::tmp_create_game dlg(game_config);

			dlg.show(disp.video());

			network::send_data(config("refresh_lobby"), 0);
		} else {

			mp::ui::result res;
			mp_game_settings new_params;

			{
				mp::create ui(disp, game_config, state, gamechat, gamelist);
				run_lobby_loop(disp, ui);
				res = ui.get_result();
				new_params = ui.get_parameters();
			}

			switch (res) {
			case mp::ui::CREATE:
				configure_canceled = !enter_configure_mode(disp, game_config,
					state, new_params, local_players_only);
				break;
			case mp::ui::LOAD_GAME:
				connect_canceled = !enter_connect_mode(disp, game_config,
					state, new_params, local_players_only);
				break;
			case mp::ui::QUIT:
			default:
				//update lobby content
				network::send_data(config("refresh_lobby"), 0);
				break;
			}
		}
	} while(configure_canceled || connect_canceled);
}
	void floating_textbox::update_location(game_display& gui)
	{
		if (box_ == NULL)
			return;

		const SDL_Rect& area = gui.map_outside_area();

		const int border_size = 10;

		const int ypos = area.y+area.h-30 - (check_ != NULL ? check_->height() + border_size : 0);

		if (label_ != 0)
			font::remove_floating_label(label_);

		font::floating_label flabel(label_string_);
		flabel.set_color(font::YELLOW_COLOR);
		flabel.set_position(area.x + border_size, ypos);
		flabel.set_alignment(font::LEFT_ALIGN);
		flabel.set_clip_rect(area);

		label_ = font::add_floating_label(flabel);

		if (label_ == 0)
			return;

		const SDL_Rect& label_area = font::get_floating_label_rect(label_);
		const int textbox_width = area.w - label_area.w - border_size*3;

		if(textbox_width <= 0) {
			font::remove_floating_label(label_);
			return;
		}

		if(box_ != NULL) {
			box_->set_volatile(true);
			const SDL_Rect rect = create_rect(
				  area.x + label_area.w + border_size * 2
				, ypos
				, textbox_width
				, box_->height());

			box_->set_location(rect);
		}

		if(check_ != NULL) {
			check_->set_volatile(true);
			check_->set_location(box_->location().x,box_->location().y + box_->location().h + border_size);
		}
	}
	void floating_textbox::close(game_display& gui)
	{
		if(!active()) {
			return;
		}
		if(check_ != NULL) {
			if(mode_ == TEXTBOX_MESSAGE) {
				preferences::set_message_private(check_->checked());
			}
		}
		box_.assign(NULL);
		check_.assign(NULL);
		font::remove_floating_label(label_);
		mode_ = TEXTBOX_NONE;
		gui.invalidate_all();
	}
Esempio n. 14
0
static void enter_connect_mode(game_display& disp, const config& game_config, hero_map& heros, hero_map& heros_start,
		card_map& cards,
		config& gamelist, const mp_game_settings& params,
		const int num_turns, mp::controller default_controller, bool local_players_only = false)
{
	mp::ui::result res;
	game_state state;
	const network::manager net_manager(1,1);
	network_game_manager m;

	gamelist.clear();
	statistics::fresh_stats();

	// if (gui2::new_widgets) {
		gui2::tmp_side_creator dlg(heros, disp, *resources::game_map, game_config, gamelist, params, num_turns, default_controller, local_players_only);
		dlg.show(disp.video());
		switch (dlg.get_legacy_result()) {
		case gui2::tmp_side_creator::PLAY:
			res = mp::ui::PLAY;
			dlg.start_game();
			state = dlg.get_state();
			// lobby may modify hero's side_feature
			heros_start = heros;
			break;
		case gui2::tmp_side_creator::CREATE:
			res = mp::ui::CREATE;
			break;
		default:
			res = mp::ui::QUIT;
		}

	switch (res) {
	case mp::ui::PLAY:
		play_game(disp, state, game_config, heros, heros_start, cards, IO_SERVER);
		recorder.clear();

		break;
	case mp::ui::CREATE:
		enter_create_mode(disp, game_config, heros, heros_start, cards, gamelist, default_controller, local_players_only);
		break;
	case mp::ui::QUIT:
	default:
		network::send_data(config("refresh_lobby"), 0);
		break;
	}
}
Esempio n. 15
0
static void do_preferences_dialog(game_display& disp, const config& game_config)
{
	const preferences::display_manager disp_manager(&disp);
	preferences::show_preferences_dialog(disp,game_config);

	/**
	 * The screen size might have changed force an update of the size.
	 *
	 * @todo This might no longer be needed when gui2 is done.
	 */
	const SDL_Rect rect = screen_area();
	preferences::set_resolution(disp.video(), rect.w, rect.h);

	gui2::settings::gamemap_width += rect.w - gui2::settings::screen_width ;
	gui2::settings::gamemap_height += rect.h - gui2::settings::screen_height ;
	gui2::settings::screen_width = rect.w;
	gui2::settings::screen_height = rect.h;
}
Esempio n. 16
0
	void floating_textbox::update_location(game_display& gui)
	{
		if (box_ == NULL)
			return;

		const SDL_Rect& area = gui.map_outside_area();

		const int border_size = 10;

		const int ypos = area.y+area.h-30 - (check_ != NULL ? check_->height() + border_size : 0);

		if (label_ != 0)
			font::remove_floating_label(label_);

		label_ = font::add_floating_label(label_string_,font::SIZE_NORMAL,
				font::YELLOW_COLOUR,area.x+border_size,ypos,0,0,-1, area,font::LEFT_ALIGN);

		if (label_ == 0)
			return;

		const SDL_Rect& label_area = font::get_floating_label_rect(label_);
		const int textbox_width = area.w - label_area.w - border_size*3;

		if(textbox_width <= 0) {
			font::remove_floating_label(label_);
			return;
		}

		if(box_ != NULL) {
			box_->set_volatile(true);
			const SDL_Rect rect = {
				area.x + label_area.w + border_size*2, ypos,
				textbox_width, box_->height()
			};
			box_->set_location(rect);
		}

		if(check_ != NULL) {
			check_->set_volatile(true);
			check_->set_location(box_->location().x,box_->location().y + box_->location().h + border_size);
		}
	}
Esempio n. 17
0
create::create(game_display& disp, const config& cfg, saved_game& state,
	chat& c, config& gamelist) :
	ui(disp, _("Create Game"), cfg, c, gamelist),
	tooltip_manager_(disp.video()),
	era_selection_(-1),
	mod_selection_(-1),
	level_selection_(-1),
	eras_menu_(disp.video(), std::vector<std::string>()),
	levels_menu_(disp.video(), std::vector<std::string>()),
	mods_menu_(disp.video(), std::vector<std::string>()),
	filter_name_label_(disp.video(), _("Filter:"), font::SIZE_SMALL, font::LOBBY_COLOR),
	filter_num_players_label_(disp.video(), _("Number of players: any"), font::SIZE_SMALL, font::LOBBY_COLOR),
	map_generator_label_(disp.video(), _("Random map options:"), font::SIZE_SMALL, font::LOBBY_COLOR),
	era_label_(disp.video(), _("Era:"), font::SIZE_SMALL, font::LOBBY_COLOR),
	no_era_label_(disp.video(), _("No eras available\nfor this game."),
		font::SIZE_SMALL, font::LOBBY_COLOR),
	mod_label_(disp.video(), _("Modifications:"), font::SIZE_SMALL, font::LOBBY_COLOR),
	map_size_label_(disp.video(), "", font::SIZE_SMALL, font::LOBBY_COLOR),
	num_players_label_(disp.video(), "", font::SIZE_SMALL, font::LOBBY_COLOR),
	level_type_label_(disp.video(), "Game type:", font::SIZE_SMALL, font::LOBBY_COLOR),
	launch_game_(disp.video(), _("Next")),
	cancel_game_(disp.video(), _("Cancel")),
	regenerate_map_(disp.video(), _("Regenerate")),
	generator_settings_(disp.video(), _("Settings...")),
	load_game_(disp.video(), _("Load Game...")),
	level_type_combo_(disp, std::vector<std::string>()),
	filter_num_players_slider_(disp.video()),
	description_(disp.video(), 100, "", false),
	filter_name_(disp.video(), 100, "", true, 256, font::SIZE_SMALL),
	image_restorer_(NULL),
	image_rect_(null_rect),
	available_level_types_(),
	engine_(disp, state)
{
	filter_num_players_slider_.set_min(1);
	filter_num_players_slider_.set_max(9);
	filter_num_players_slider_.set_increment(1);

	DBG_MP << "constructing multiplayer create dialog" << std::endl;

	levels_menu_.set_numeric_keypress_selection(false);

	typedef std::pair<ng::level::TYPE, std::string> level_type_info;
	std::vector<level_type_info> all_level_types;
	all_level_types.push_back(std::make_pair(ng::level::TYPE::SCENARIO, _("Scenarios")));
	all_level_types.push_back(std::make_pair(ng::level::TYPE::CAMPAIGN, _("Campaigns")));
	all_level_types.push_back(std::make_pair(ng::level::TYPE::USER_MAP, _("User Maps")));
	all_level_types.push_back(std::make_pair(ng::level::TYPE::USER_SCENARIO, _("User Scenarios")));
	all_level_types.push_back(std::make_pair(ng::level::TYPE::RANDOM_MAP, _("Random Maps")));

	if (game_config::debug) {
		all_level_types.push_back(std::make_pair(ng::level::TYPE::SP_CAMPAIGN,
			"SP Campaigns"));
	}

	std::vector<std::string> combo_level_names;

	BOOST_FOREACH(level_type_info type_info, all_level_types) {
		if (!engine_.get_levels_by_type_unfiltered(type_info.first).empty()) {
			available_level_types_.push_back(type_info.first);
			combo_level_names.push_back(type_info.second);
		}
	}

	if (available_level_types_.empty()) {
		gui2::show_transient_message(disp.video(), "", _("No games found."));
		throw game::error(_("No games found."));
	}

	level_type_combo_.set_items(combo_level_names);

	size_t combo_new_selection = 0;
	size_t level_new_selection = 0;

	// Set level selection according to the preferences, if possible.
	size_t type_index = 0;
	BOOST_FOREACH(ng::level::TYPE type, available_level_types_) {
		if (preferences::level_type() == type.cast<int>()) {
			break;
		}
		type_index++;
	}
	if (type_index < available_level_types_.size()) {
		combo_new_selection = type_index;

		int level_index = engine_.find_level_by_id(preferences::level());
		if (level_index != -1) {
			level_new_selection = level_index;
		}
	}

	level_type_combo_.set_selected(combo_new_selection);
	init_level_type_changed(level_new_selection);

	const std::vector<std::string>& era_names =
		engine_.extras_menu_item_names(ng::create_engine::ERA);
	if(era_names.empty()) {
		gui2::show_transient_message(disp.video(), "", _("No eras found."));
		throw config::error(_("No eras found"));
	}
	eras_menu_.set_items(era_names);

	// Set era selection according to the preferences, if possible.
	int era_new_selection = engine_.find_extra_by_id(ng::create_engine::ERA,
		preferences::era());
	eras_menu_.move_selection((era_new_selection != -1) ? era_new_selection : 0);

	std::vector<std::string> mods = engine_.extras_menu_item_names(ng::create_engine::MOD);
	mods_menu_.set_items(mods);
	mods_menu_.move_selection(0);
	// don't set 0 explicitly, because move_selection(0) may fail if there's
	// no modifications at all
	mod_selection_ = mods_menu_.selection();

	if (mod_selection_ == -1) {
		mod_label_.set_text(_("Modifications:\nNone found."));
	}

	gamelist_updated();

	plugins_context_.reset(new plugins_context("Multiplayer Create"));

	//These structure initializers create a lobby::process_data_event
	plugins_context_->set_callback("create", 	boost::bind(&create::plugin_event_helper, this, process_event_data (true, false, false)));
	plugins_context_->set_callback("load", 		boost::bind(&create::plugin_event_helper, this, process_event_data (false, true, false)));
	plugins_context_->set_callback("quit", 		boost::bind(&create::plugin_event_helper, this, process_event_data (false, false, true)));
	plugins_context_->set_callback("chat",		boost::bind(&create::send_chat_message, this, boost::bind(get_str, _1, "message"), false),	true);
	plugins_context_->set_callback("select_level",	boost::bind(&gui::menu::move_selection, &levels_menu_, boost::bind(get_size_t, _1, "index", 0u)), true);
	plugins_context_->set_callback("select_type",	boost::bind(&create::select_level_type_helper, this, boost::bind(get_str, _1, "type")), true);

	plugins_context_->set_accessor("game_config",	boost::bind(&create::game_config, this));
	plugins_context_->set_accessor("get_selected",  boost::bind(&get_selected_helper, &engine_));
	plugins_context_->set_accessor("find_level",  	boost::bind(&find_helper, &engine_, _1));
}
Esempio n. 18
0
static void enter_lobby_mode(game_display& disp, const config& game_config, mp::chat& chat, config& gamelist)
{


	mp::ui::result res;

	while (true) {
		const config &cfg = game_config.child("lobby_music");
		if (cfg) {
			foreach (const config &i, cfg.child_range("music")) {
				sound::play_music_config(i);
			}
			sound::commit_music_changes();
		} else {
			sound::empty_playlist();
			sound::stop_music();
		}
		lobby_info li(game_config);
		gui2::tlobby_main dlg(game_config, li, disp);
		dlg.set_preferences_callback(
			boost::bind(do_preferences_dialog,
				boost::ref(disp), boost::ref(game_config)));
		dlg.show(disp.video());
		//ugly kludge for launching other dialogs like the old lobby
		switch (dlg.get_legacy_result()) {
			case gui2::tlobby_main::CREATE:
				res = mp::ui::CREATE;
				break;
			case gui2::tlobby_main::JOIN:
				res = mp::ui::JOIN;
				break;
			case gui2::tlobby_main::OBSERVE:
				res = mp::ui::OBSERVE;
				break;
			default:
				res = mp::ui::QUIT;
		}

		switch (res) {
		case mp::ui::JOIN:
			try {
				enter_wait_mode(disp, game_config, chat, gamelist, false);
			} catch(config::error& error) {
				if(!error.message.empty()) {
					gui2::show_error_message(disp.video(), error.message);
				}
				//update lobby content
				network::send_data(config("refresh_lobby"), 0, true);
			}
			break;
		case mp::ui::OBSERVE:
			try {
				enter_wait_mode(disp, game_config, chat, gamelist, true);
			} catch(config::error& error) {
				if(!error.message.empty()) {
					gui2::show_error_message(disp.video(), error.message);
				}
			}
			// update lobby content unconditionally because we might have left only after the
			// game ended in which case we ignored the gamelist and need to request it again
			network::send_data(config("refresh_lobby"), 0, true);
			break;
		case mp::ui::CREATE:
			try {
				enter_create_mode(disp, game_config, chat, gamelist, mp::CNTR_NETWORK);
			} catch(config::error& error) {
				if (!error.message.empty())
					gui2::show_error_message(disp.video(), error.message);
				//update lobby content
				network::send_data(config("refresh_lobby"), 0, true);
			}
			break;
		case mp::ui::QUIT:
			return;
		case mp::ui::PREFERENCES:
			{
				do_preferences_dialog(disp, game_config);
				//update lobby content
				network::send_data(config("refresh_lobby"), 0, true);
			}
			break;
		default:
			return;
		}
	}
statistics_dialog::statistics_dialog(game_display &disp,
		const std::string& title,
		const unsigned int team,
		const std::string& team_id,
		const std::string& player) :
	dialog(disp, title, "", gui::NULL_DIALOG),
	detail_btn_(new gui::standard_dialog_button(disp.video(), _("Details"), 0 , false)),
	player_name_(player),
	stats_(),
	team_num_(team),
	unit_count_(5,0)
{
	add_button(detail_btn_, gui::dialog::BUTTON_EXTRA);
	add_button(new gui::standard_dialog_button(disp.video(), _("Close"), 1, true),
				gui::dialog::BUTTON_STANDARD);

	stats_ = statistics::calculate_stats(0, team_id);
	int n, cost;
	std::vector<std::string> items;
	// Prepare the menu items
	{
		std::stringstream str;
		n = statistics::sum_str_int_map(stats_.recruits);
		cost = stats_.recruit_cost;
		unit_count_[0] = n;
		str << _("Recruits") << COLUMN_SEPARATOR << n
		    << COLUMN_SEPARATOR
		    << COLUMN_SEPARATOR << IMAGE_PREFIX << "themes/gold-t.png"
		    << COLUMN_SEPARATOR << cost;
		items.push_back(str.str());
	}
	{
		std::stringstream str;
		n = statistics::sum_str_int_map(stats_.recalls);
		cost = stats_.recall_cost;
		unit_count_[1] = n;
		str << _("Recalls") << COLUMN_SEPARATOR << n
		    << COLUMN_SEPARATOR
		    << COLUMN_SEPARATOR << IMAGE_PREFIX << "themes/gold-t.png"
		    << COLUMN_SEPARATOR << cost;
		items.push_back(str.str());
	}
	{
		std::stringstream str;
		n = statistics::sum_str_int_map(stats_.advanced_to);
		unit_count_[2] = n;
		str << _("Advancements") << COLUMN_SEPARATOR << n;
		items.push_back(str.str());
	}
	{
		std::stringstream str;
		n = statistics::sum_str_int_map(stats_.deaths);
		unit_count_[3] = n;
		cost = statistics::sum_cost_str_int_map(stats_.deaths);
		str << _("Losses") << COLUMN_SEPARATOR << n
		    << COLUMN_SEPARATOR
		    << COLUMN_SEPARATOR << IMAGE_PREFIX << "themes/gold-t.png"
		    << COLUMN_SEPARATOR << cost;
		items.push_back(str.str());
	}
	{
		std::stringstream str;
		n = statistics::sum_str_int_map(stats_.killed);
		unit_count_[4] = n;
		cost = statistics::sum_cost_str_int_map(stats_.killed);
		str << _("Kills") << COLUMN_SEPARATOR << n
		    << COLUMN_SEPARATOR
		    << COLUMN_SEPARATOR << IMAGE_PREFIX << "themes/gold-t.png"
		    << COLUMN_SEPARATOR << cost;
		items.push_back(str.str());
	}
	items.push_back("");
	{
		std::stringstream str;
		str << font::BOLD_TEXT << _("Damage")
		    << COLUMN_SEPARATOR << _("Overall") << COLUMN_SEPARATOR
		    << COLUMN_SEPARATOR
		    << COLUMN_SEPARATOR << _("This Turn");
		items.push_back(str.str());
	}

	statistics_dialog::make_damage_line(items, _("Inflicted"),
			stats_.damage_inflicted,
			stats_.expected_damage_inflicted,
			stats_.turn_damage_inflicted,
			stats_.turn_expected_damage_inflicted);
	statistics_dialog::make_damage_line(items, _("Taken"),
			stats_.damage_taken,
			stats_.expected_damage_taken,
			stats_.turn_damage_taken,
			stats_.turn_expected_damage_taken);

	set_menu(items);
}
Esempio n. 20
0
static server_type open_connection(game_display& disp, const std::string& original_host)
{
	std::string h = original_host;

	if(h.empty()) {
		gui2::tmp_connect dlg;

		dlg.show(disp.video());
		if(dlg.get_retval() == gui2::twindow::OK) {
			h = preferences::network_host();
		} else {
			return ABORT_SERVER;
		}
	}

	network::connection sock;

	const int pos = h.find_first_of(":");
	std::string host;
	unsigned int port;

	if(pos == -1) {
		host = h;
		port = 15000;
	} else {
		host = h.substr(0, pos);
		port = lexical_cast_default<unsigned int>(h.substr(pos + 1), 15000);
	}

	// shown_hosts is used to prevent the client being locked in a redirect
	// loop.
	typedef std::pair<std::string, int> hostpair;
	std::set<hostpair> shown_hosts;
	shown_hosts.insert(hostpair(host, port));

	config data;
	sock = dialogs::network_connect_dialog(disp,_("Connecting to Server..."),host,port);

	do {

		if (!sock) {
			return ABORT_SERVER;
		}

		data.clear();
		network::connection data_res = dialogs::network_receive_dialog(
				disp,_("Reading from Server..."),data);
		if (!data_res) return ABORT_SERVER;
		mp::check_response(data_res, data);

		// Backwards-compatibility "version" attribute
		const std::string& version = data["version"];
		if(version.empty() == false && version != game_config::version) {
			utils::string_map i18n_symbols;
			i18n_symbols["version1"] = version;
			i18n_symbols["version2"] = game_config::version;
			const std::string errorstring = vgettext("The server requires version '$version1' while you are using version '$version2'", i18n_symbols);
			throw network::error(errorstring);
		}

		// Check for "redirect" messages
		if (const config &redirect = data.child("redirect"))
		{
			host = redirect["host"];
			port = lexical_cast_default<unsigned int>(redirect["port"], 15000);

			if(shown_hosts.find(hostpair(host,port)) != shown_hosts.end()) {
				throw network::error(_("Server-side redirect loop"));
			}
			shown_hosts.insert(hostpair(host, port));

			if(network::nconnections() > 0)
				network::disconnect();
			sock = dialogs::network_connect_dialog(disp,_("Connecting to Server..."),host,port);
			continue;
		}

		if(data.child("version")) {
			config cfg;
			config res;
			cfg["version"] = game_config::version;
			res.add_child("version", cfg);
			network::send_data(res, 0, true);
		}

		//if we got a direction to login
		if(data.child("mustlogin")) {

			for(;;) {
				std::string password_reminder = "";

				std::string login = preferences::login();

				config response ;
				config &sp = response.add_child("login") ;
				sp["username"] = login ;

				// Login and enable selective pings -- saves server bandwidth
				// If ping_timeout has a non-zero value, do not enable
				// selective pings as this will cause clients to falsely
				// believe the server has died and disconnect.
				if( preferences::get_ping_timeout() ) {
				  // Pings required so disable selective pings
				  sp["selective_ping"] = "0" ;
				} else {
				  // Client is bandwidth friendly so allow
				  // server to optimize ping frequency as needed.
				  sp["selective_ping"] = "1" ;
				}
				network::send_data(response, 0, true);

				// Get response for our login request...
				network::connection data_res = network::receive_data(data, 0, 3000);
				if(!data_res) {
					throw network::error(_("Connection timed out"));
				}

				config *error = &data.child("error");

				// ... and get us out of here if the server did not complain
				if (!*error) break;

				do {
					std::string password = preferences::password();

					bool fall_through = (*error)["force_confirmation"] == "yes" ?
						(gui::dialog(disp,_("Confirm"),(*error)["message"],gui::OK_CANCEL).show() != 0) :
						false;

					const bool is_pw_request = !((*error)["password_request"].empty()) && !(password.empty());

					// If the server asks for a password, provide one if we can
					// or request a password reminder.
					// Otherwise or if the user pressed 'cancel' in the confirmation dialog
					// above go directly to the username/password dialog
					if((is_pw_request || !password_reminder.empty()) && !fall_through) {
						if(is_pw_request) {
							if((*error)["phpbb_encryption"] == "yes") {

								// Apparently HTML key-characters are passed to the hashing functions of phpbb in this escaped form.
								// I will do closer investigations on this, for now let's just hope these are all of them.

								// Note: we must obviously replace '&' first, I wasted some time before I figured that out... :)
								for(std::string::size_type pos = 0; (pos = password.find('&', pos)) != std::string::npos; ++pos )
									password.replace(pos, 1, "&amp;");
								for(std::string::size_type pos = 0; (pos = password.find('\"', pos)) != std::string::npos; ++pos )
									password.replace(pos, 1, "&quot;");
								for(std::string::size_type pos = 0; (pos = password.find('<', pos)) != std::string::npos; ++pos )
									password.replace(pos, 1, "&lt;");
								for(std::string::size_type pos = 0; (pos = password.find('>', pos)) != std::string::npos; ++pos )
									password.replace(pos, 1, "&gt;");

								const std::string salt = (*error)["salt"];

								if (salt.length() < 12) {
									//TODO gettextify after end of stringfreeze
									throw network::error("Bad data received from server");
								}

								sp["password"] = util::create_hash(util::create_hash(password, util::get_salt(salt),
										util::get_iteration_count(salt)), salt.substr(12, 8));

							} else {
								sp["password"] = password;
							}
						}

						sp["password_reminder"] = password_reminder;

						// Once again send our request...
						network::send_data(response, 0, true);

						network::connection data_res = network::receive_data(data, 0, 3000);
						if(!data_res) {
							throw network::error(_("Connection timed out"));
						}

						error = &data.child("error");

						// ... and get us out of here if the server is happy now
						if (!*error) break;


					}

					password_reminder = "";

					// Providing a password either was not attempted because we did not
					// have any or failed:
					// Now show a dialog that displays the error and allows to
					// enter a new user name and/or password

					std::string error_message;
					utils::string_map i18n_symbols;
					i18n_symbols["nick"] = login;

					if((*error)["error_code"] == MP_MUST_LOGIN) {
						error_message = _("You must login first.");
					} else if((*error)["error_code"] == MP_NAME_TAKEN_ERROR) {
						error_message = vgettext("The nick '$nick' is already taken.", i18n_symbols);
					} else if((*error)["error_code"] == MP_INVALID_CHARS_IN_NAME_ERROR) {
						error_message = vgettext("The nick '$nick' contains invalid "
								"characters. Only alpha-numeric characters, underscores and "
								"hyphens are allowed.", i18n_symbols);
					} else if((*error)["error_code"] == MP_NAME_TOO_LONG_ERROR) {
						error_message = vgettext("The nick '$nick' is too long. Nicks must "
								"be 18 characters or less.", i18n_symbols);
					} else if((*error)["error_code"] == MP_NAME_RESERVED_ERROR) {
						error_message = vgettext("The nick '$nick' is reserved and cannot be used by players.", i18n_symbols);
					} else if((*error)["error_code"] == MP_NAME_UNREGISTERED_ERROR) {
						error_message = vgettext("The nick '$nick' is not registered on this server.", i18n_symbols)
								+ _(" This server disallows unregistered nicks.");
					} else if((*error)["error_code"] == MP_PASSWORD_REQUEST) {
						error_message = vgettext("The nick '$nick' is registered on this server.", i18n_symbols);
					} else if((*error)["error_code"] == MP_PASSWORD_REQUEST_FOR_LOGGED_IN_NAME) {
						error_message = vgettext("The nick '$nick' is registered on this server.", i18n_symbols)
								+ "\n\n" + _("WARNING: There is already a client using this nick, "
								"logging in will cause that client to be kicked!");
					} else if((*error)["error_code"] == MP_NO_SEED_ERROR) {
						error_message = _("Error in the login procedure (the server had no "
								"seed for your connection).");
					} else if((*error)["error_code"] == MP_INCORRECT_PASSWORD_ERROR) {
						error_message = _("The password you provided was incorrect.");
					} else {
						error_message = (*error)["message"];
					}

					gui2::tmp_login dlg(error_message, !((*error)["password_request"].empty()));
					dlg.show(disp.video());

					switch(dlg.get_retval()) {
						//Log in with password
						case gui2::twindow::OK:
							break;
						//Request a password reminder
						case 1:
							password_reminder = "yes";
							break;
						// Cancel
						default: return ABORT_SERVER;
					}

				// If we have got a new username we have to start all over again
				} while(login == preferences::login());

				// Somewhat hacky...
				// If we broke out of the do-while loop above error
				// is still going to be NULL
				if(!*error) break;
			} // end login loop
		}
	} while(!(data.child("join_lobby") || data.child("join_game")));

	if (h != preferences::server_list().front().address)
		preferences::set_network_host(h);

	if (data.child("join_lobby")) {
		return WESNOTHD_SERVER;
	} else {
		return SIMPLE_SERVER;
	}

}
Esempio n. 21
0
bool enter_create_mode(game_display& disp, const config& game_config,
	saved_game& state, jump_to_campaign_info jump_to_campaign, bool local_players_only) {

	bool configure_canceled = false;

	do {

		ng::create_engine create_eng(disp, state);
		create_eng.set_current_level_type(ng::level::TYPE::SP_CAMPAIGN);

		std::vector<ng::create_engine::level_ptr> campaigns(
			create_eng.get_levels_by_type_unfiltered(ng::level::TYPE::SP_CAMPAIGN));
		
		if (campaigns.empty()) {
		  gui2::show_error_message(disp.video(),
					  _("No campaigns are available.\n"));
			return false;
		}

		bool use_deterministic_mode = false;
		// No campaign selected from command line
		if (jump_to_campaign.campaign_id_.empty() == true)
		{
			gui2::tcampaign_selection dlg(create_eng);

			try {
				dlg.show(disp.video());
			} catch(twml_exception& e) {
				e.show(disp);
				return false;
			}

			if(dlg.get_retval() != gui2::twindow::OK) {
				return false;
			}

			use_deterministic_mode = dlg.get_deterministic();

		}
		else
		{
			// don't reset the campaign_id_ so we can know
			// if we should quit the game or return to the main menu

			// checking for valid campaign name
			bool not_found = true;
			for(size_t i = 0; i < campaigns.size(); ++i)
			{
				if (campaigns[i]->data()["id"] == jump_to_campaign.campaign_id_)
				{
					create_eng.set_current_level(i);
					not_found = false;
					break;
				}

			}

			// didn't find any campaign with that id
			if (not_found)
			{
				//TODO: use ERR_NG or similar
				std::cerr<<"No such campaign id to jump to: ["<<jump_to_campaign.campaign_id_<<"]\n";
				return false;
			}

		}

		std::string random_mode = use_deterministic_mode ? "deterministic" : "";
		state.classification().random_mode = random_mode;

		std::string selected_difficulty = create_eng.select_campaign_difficulty(jump_to_campaign.difficulty_);

		if (selected_difficulty == "FAIL") return false;
		if (selected_difficulty == "CANCEL") {
			if (jump_to_campaign.campaign_id_.empty() == false)
			{
				jump_to_campaign.campaign_id_ = "";
			}
			// canceled difficulty dialog, relaunch the campaign selection dialog
			return enter_create_mode(disp, game_config, state, jump_to_campaign, local_players_only);
		}

		create_eng.prepare_for_era_and_mods();
		create_eng.prepare_for_campaign(selected_difficulty);

		if(!jump_to_campaign.scenario_id_.empty()) {
			state.set_carryover_sides_start(
				config_of("next_scenario", jump_to_campaign.scenario_id_)
			);
		}
		create_eng.prepare_for_new_level();

		create_eng.get_parameters();
		if(!state.valid())
		{
			//TODO: use ERR_NG or similar
			std::cerr << "Cannot load scenario with id=" << state.get_scenario_id() << "\n";
			return false;
		}
		configure_canceled = !enter_configure_mode(disp, game_config_manager::get()->game_config(), state, local_players_only);

	} while (configure_canceled);

	return true;
}
Esempio n. 22
0
static void enter_lobby_mode(game_display& disp, const config& game_config,
	game_state& state)
{
	DBG_MP << "entering lobby mode" << std::endl;

	mp::ui::result res;

	while (true) {
		const config &cfg = game_config.child("lobby_music");
		if (cfg) {
			BOOST_FOREACH(const config &i, cfg.child_range("music")) {
				sound::play_music_config(i);
			}
			sound::commit_music_changes();
		} else {
			sound::empty_playlist();
			sound::stop_music();
		}
		lobby_info li(game_config);

		// Force a black background
		const Uint32 color = SDL_MapRGBA(disp.video().getSurface()->format
				, 0
				, 0
				, 0
				, 255);

		sdl_fill_rect(disp.video().getSurface(), NULL, color);

		if(preferences::new_lobby()) {
			gui2::tlobby_main dlg(game_config, li, disp);
			dlg.set_preferences_callback(
				boost::bind(do_preferences_dialog,
					boost::ref(disp), boost::ref(game_config)));
			dlg.show(disp.video());
			//ugly kludge for launching other dialogs like the old lobby
			switch (dlg.get_legacy_result()) {
				case gui2::tlobby_main::CREATE:
					res = mp::ui::CREATE;
					break;
				case gui2::tlobby_main::JOIN:
					res = mp::ui::JOIN;
					break;
				case gui2::tlobby_main::OBSERVE:
					res = mp::ui::OBSERVE;
					break;
				default:
					res = mp::ui::QUIT;
			}
		} else {
			mp::lobby ui(disp, game_config, gamechat, gamelist);
			run_lobby_loop(disp, ui);
			res = ui.get_result();
		}

		switch (res) {
		case mp::ui::JOIN:
			try {
				enter_wait_mode(disp, game_config, state, false);
			} catch(config::error& error) {
				if(!error.message.empty()) {
					gui2::show_error_message(disp.video(), error.message);
				}
				//update lobby content
				network::send_data(config("refresh_lobby"), 0);
			}
			break;
		case mp::ui::OBSERVE:
			try {
				enter_wait_mode(disp, game_config, state, true);
			} catch(config::error& error) {
				if(!error.message.empty()) {
					gui2::show_error_message(disp.video(), error.message);
				}
			}
			// update lobby content unconditionally because we might have left only after the
			// game ended in which case we ignored the gamelist and need to request it again
			network::send_data(config("refresh_lobby"), 0);
			break;
		case mp::ui::CREATE:
			try {
				enter_create_mode(disp, game_config, state, false);
			} catch(config::error& error) {
				if (!error.message.empty())
					gui2::show_error_message(disp.video(), error.message);
				//update lobby content
				network::send_data(config("refresh_lobby"), 0);
			}
			break;
		case mp::ui::QUIT:
			return;
		case mp::ui::PREFERENCES:
			{
				do_preferences_dialog(disp, game_config);
				//update lobby content
				network::send_data(config("refresh_lobby"), 0);
			}
			break;
		default:
			return;
		}
	}
Esempio n. 23
0
TITLE_RESULT show_title(game_display& screen, config& tips_of_day)
{
	disableTerrainCache();
	
	free_all_caches();
	
	cursor::set(cursor::NORMAL);

	const preferences::display_manager disp_manager(&screen);
	const hotkey::basic_handler key_handler(&screen);

	const font::floating_label_context label_manager;

	screen.video().modeChanged(); // resets modeChanged value

//	if (background_is_dirty_) 
	{
		draw_background(screen);
	}

	//- Texts for the menu-buttons.
	//- Members of this array must correspond to the enumeration TITLE_RESULT
	static const char* button_labels[] = {
					       //N_("TitleScreen button^Tutorial"),
					       N_("TitleScreen button^Campaign"),
#ifndef FREE_VERSION		
							N_("TitleScreen button^Skirmish"),
					       N_("TitleScreen button^Multiplayer"),
#endif
					       N_("TitleScreen button^Load"),
//					       N_("TitleScreen button^Add-ons"),
//#ifndef DISABLE_EDITOR2
					       //N_("TitleScreen button^Map Editor"),
//#endif
					       //N_("TitleScreen button^Language"),
					       N_("TitleScreen button^Preferences"),
							N_("Sync Saves"),
#ifndef DISABLE_OPENFEINT
							N_("TitleScreen button^OpenFeint"),
#endif
					       N_("TitleScreen button^Help"),
					       //N_("TitleScreen button^Quit"),
								// Only the above buttons go into the menu-frame
								// Next 2 buttons go into frame for the tip-of-the-day:
					       N_("TitleScreen button^Previous"),
					       N_("TitleScreen button^Next"),
					       //N_("TitleScreen button^Help"),
								// Next entry is no button, but shown as a mail-icon instead:
					       //N_("TitleScreen button^Help Wesnoth") 
							};
	//- Texts for the tooltips of the menu-buttons
	static const char* help_button_labels[] = { 
							//N_("Start a tutorial to familiarize yourself with the game"),
						    N_("Start a new single player campaign"),
#ifndef FREE_VERSION
							N_("Play a single scenario against the AI"),
						    N_("Play multiplayer (hotseat or Internet)"),
#endif
						    N_("Load a saved game"),
//						    N_("Download usermade campaigns, eras, or map packs"),
//#ifndef DISABLE_EDITOR2
						    //N_("Start the map editor"),
//#endif
						    //N_("Change the language"),
						    N_("Configure the game's settings"),
							N_("Sync saved games"),
#ifndef DISABLE_OPENFEINT
							N_("Launch the OpenFeint dashboard"),
#endif

							N_("Show Battle for Wesnoth help"),
							//N_("Quit the game"),
						    N_("Show next tip of the day"),
						    //N_("Upload statistics") 
							};

	//static const size_t nbuttons = sizeof(button_labels)/sizeof(*button_labels);
#ifdef FREE_VERSION	
	int nbuttons = 10;
#else
	int nbuttons = 8;
#endif
	
#ifdef DISABLE_OPENFEINT
	nbuttons--;
#endif
	
#ifndef __IPAD__
	nbuttons--;	// because help is off to the left now
#endif
	
	int menu_xbase = CVideo::getx()-108-10; //380; //(game_config::title_buttons_x*screen.w())/1024;
	const int menu_xincr = 0;

#ifdef USE_TINY_GUI
	//const int menu_ybase = 15; //(330*screen.h())/768 - 50; //15;
	const int menu_yincr = 36+5; //(35*3)/4;//15;
	const int menu_ybase = (screen.h() - (36+5)*nbuttons - 5) / 2 + 4;
#else
	const int menu_ybase = (screen.h() - (36+5)*nbuttons - 5) / 2 + 4;
	const int menu_yincr = 36+5;
#endif
	
#ifdef __IPAD__
	menu_xbase -= 10;
#endif

	const int padding = 4; //game_config::title_buttons_padding;

	std::vector<button> buttons;
	size_t b, max_width = 0;
	size_t n_menubuttons = 0;
	for(b = 0; b != nbuttons; ++b) 
	{
//#ifdef __IPHONEOS__		
//		if (b + TUTORIAL == TUTORIAL || b + TUTORIAL == START_MAP_EDITOR || b+TUTORIAL == CHANGE_LANGUAGE)
//			continue;
//#endif		
		buttons.push_back(button(screen.video(),sgettext(button_labels[b])));
		buttons.back().set_help_string(sgettext(help_button_labels[b]));
		max_width = std::max<size_t>(max_width,buttons.back().width());

		n_menubuttons = b;
#ifdef __IPAD__
		if(b + NEW_CAMPAIGN == SHOW_HELP) break;
#else
		if(b + NEW_CAMPAIGN == SHOW_OPENFEINT) break;		
#endif
	}

	SDL_Rect main_dialog_area = {menu_xbase-padding, menu_ybase-padding, max_width+padding*2,
								 menu_yincr*(n_menubuttons)+buttons.back().height()+padding*2};

	gui::dialog_frame main_frame(screen.video(), "", gui::dialog_frame::titlescreen_style, false);
	main_frame.layout(main_dialog_area);

	// we only redraw transparent parts when asked,
	// to prevent alpha growing
	if (background_is_dirty_) {
		main_frame.draw_background();
		main_frame.draw_border();
	}

	int i=0;
	for(b = 0; b != nbuttons; ++b) 
	{
//#ifdef __IPHONEOS__		
//		if (b + TUTORIAL == TUTORIAL || b + TUTORIAL == START_MAP_EDITOR || b+TUTORIAL == CHANGE_LANGUAGE)
//			continue;
//#endif		
		buttons[i].set_width(max_width);
		buttons[i].set_location(menu_xbase + i*menu_xincr, menu_ybase + i*menu_yincr);
#ifdef __IPAD__
		if(b + NEW_CAMPAIGN == SHOW_HELP) break;
#else
		if(b + NEW_CAMPAIGN == SHOW_OPENFEINT) break;		
#endif
		i++;
	}
	
#ifndef __IPAD__
	buttons.push_back(button(screen.video(),sgettext(button_labels[i+1])));
	buttons.back().set_help_string(sgettext(help_button_labels[i+1]));
	buttons[i+1].set_width(max_width);
	buttons[i+1].set_location(5, 320-menu_yincr);	
#endif

//	b = TIP_PREVIOUS - NEW_CAMPAIGN;
//	gui::button previous_tip_button(screen.video(),sgettext(button_labels[b]),button::TYPE_PRESS,"lite_small");
//	previous_tip_button.set_help_string( sgettext(button_labels[b] ));

//	b = TIP_NEXT - NEW_CAMPAIGN;
//	gui::button next_tip_button(screen.video(),sgettext(button_labels[b]),button::TYPE_PRESS,"lite_small");
//	next_tip_button.set_help_string( sgettext(button_labels[b] ));

//	b = SHOW_HELP - NEW_CAMPAIGN;
//	gui::button help_tip_button(screen.video(),sgettext(button_labels[b]),button::TYPE_PRESS,"lite_small");
//	help_tip_button.set_help_string( sgettext(button_labels[b] ));

//	gui::button beg_button(screen.video(),_("Help Wesnoth"),button::TYPE_IMAGE,"menu-button",button::MINIMUM_SPACE);
//	beg_button.set_help_string(_("Help Wesnoth by sending us information"));

//	next_tip_of_day(tips_of_day);

//	surface_restorer tip_of_day_restorer;

//	draw_tip_of_day(screen, tips_of_day, gui::dialog_frame::titlescreen_style,
//					&previous_tip_button, &next_tip_button, NULL/*&help_tip_button*/, &main_dialog_area, tip_of_day_restorer);

//	const int pad = game_config::title_tip_padding;
//	beg_button.set_location(screen.w() - pad - beg_button.location().w,
//		screen.h() - pad - beg_button.location().h);
	events::raise_draw_event();

	LOG_DP << "drew buttons dialog\n";
	
	
	// draw logo over everything
#ifdef __IPAD__	
	std::string path = game_config::path + "/data/core/images/misc/logo.png";
#else
	std::string path = game_config::path + "/data/core/images/misc/logo_small.png";
#endif	
	surface logo_surface = IMG_Load(path.c_str());
	//blit_surface(480-logo_surface.get()->w, 0, logo_surface);
	
	

	CKey key;

	size_t keyboard_button = nbuttons;
	bool key_processed = false;

//	update_whole_screen();
	background_is_dirty_ = false;

	titlescreen_handler ts_handler(key[SDLK_ESCAPE] != 0); //!= 0 to avoid a MSVC warning C4800

	LOG_DP << "entering interactive loop...\n";
	
	
	memory_stats("At titlescreen");
	
	// Initialize OpenFeint now
	of_init();

	
	for(;;) {
		events::pump();
		for(size_t b = 0; b != buttons.size(); ++b) {
			if(buttons[b].pressed()) {
				free_title();
				return static_cast<TITLE_RESULT>(b + NEW_CAMPAIGN);
			}
		}

/*		if(previous_tip_button.pressed()) {
			next_tip_of_day(tips_of_day, true);
			draw_tip_of_day(screen, tips_of_day, gui::dialog_frame::titlescreen_style,
						&previous_tip_button, &next_tip_button, &help_tip_button, &main_dialog_area, tip_of_day_restorer);
		}
		if(next_tip_button.pressed()) {
			next_tip_of_day(tips_of_day, false);
			draw_tip_of_day(screen, tips_of_day, gui::dialog_frame::titlescreen_style,
						&previous_tip_button, &next_tip_button, &help_tip_button, &main_dialog_area, tip_of_day_restorer);
		}
*/
//		if(help_tip_button.pressed()) {
//			return SHOW_HELP;
//		}
//		if(beg_button.pressed()) {
//			return BEG_FOR_UPLOAD;
//		}
		if (key[SDLK_UP]) {
			if (!key_processed) {
				buttons[keyboard_button].set_active(false);
				if (keyboard_button == 0) {
					keyboard_button = nbuttons - 1;
				} else {
					keyboard_button--;
				}
				key_processed = true;
				buttons[keyboard_button].set_active(true);
			}
		} else if (key[SDLK_DOWN]) {
			if (!key_processed) {
				buttons[keyboard_button].set_active(false);
				if (keyboard_button > nbuttons - 1) {
					keyboard_button = 0;
				} else {
					keyboard_button++;
				}
				key_processed = true;
				buttons[keyboard_button].set_active(true);
			}
		} else {
			key_processed = false;
		}

		events::raise_process_event();
		
		
		// KP: redraw
		draw_background(screen);
		main_frame.draw_background();
		main_frame.draw_border();
		events::raise_draw_event();
		//blit_surface(480-logo_surface.get()->w, 0, logo_surface);
#ifdef __IPAD__
		blit_surface(-10, 0, logo_surface);
#else
		blit_surface(-15, -10, logo_surface);
#endif
		
		screen.flip();

//		if (key[SDLK_ESCAPE] && !ts_handler.get_esc_ignore())
//			return QUIT_GAME;
		if (key[SDLK_F5])
			return RELOAD_GAME_DATA;

		if (key[SDLK_RETURN] && keyboard_button < nbuttons) {
			return static_cast<TITLE_RESULT>(keyboard_button + NEW_CAMPAIGN);
		}



		// If the resolution has changed due to the user resizing the screen,
		// or from changing between windowed and fullscreen:
		if(screen.video().modeChanged()) {
			return REDRAW_BACKGROUND;
		}
		
		screen.delay(10);
	}

	free_title();
	return REDRAW_BACKGROUND;
}