mirror of
https://github.com/wesnoth/wesnoth
synced 2025-04-28 18:49:28 +00:00

Fixed keys not making it possible to go to the tip buttons. Fixed useless and missing translatable strings.
641 lines
19 KiB
C++
641 lines
19 KiB
C++
/* $Id$ */
|
|
/*
|
|
Copyright (C) 2003 - 2010 by David White <dave@whitevine.net>
|
|
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License version 2
|
|
or at your option any later version.
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY.
|
|
|
|
See the COPYING file for more details.
|
|
*/
|
|
|
|
/**
|
|
* @file
|
|
* Shows the titlescreen, with main-menu and tip-of-the-day.
|
|
*
|
|
* The menu consists of buttons, such als Start-Tutorial, Start-Campaign,
|
|
* Load-Game, etc. As decoration, the wesnoth-logo and a landmap in the
|
|
* background are shown.
|
|
*/
|
|
|
|
#include "global.hpp"
|
|
|
|
#include <algorithm>
|
|
#include <vector>
|
|
|
|
#include "config.hpp"
|
|
#include "construct_dialog.hpp"
|
|
#include "cursor.hpp"
|
|
#include "foreach.hpp"
|
|
#include "game_display.hpp"
|
|
#include "game_preferences.hpp"
|
|
#include "events.hpp"
|
|
#include "filesystem.hpp"
|
|
#include "game_config.hpp"
|
|
#include "hotkeys.hpp"
|
|
#include "key.hpp"
|
|
#include "gettext.hpp"
|
|
#include "log.hpp"
|
|
#include "marked-up_text.hpp"
|
|
#include "preferences_display.hpp"
|
|
#include "sdl_utils.hpp"
|
|
#include "show_dialog.hpp"
|
|
#include "text.hpp"
|
|
#include "titlescreen.hpp"
|
|
#include "video.hpp"
|
|
#include "serialization/parser.hpp"
|
|
#include "serialization/preprocessor.hpp"
|
|
|
|
static lg::log_domain log_engine("engine");
|
|
#define ERR_NG LOG_STREAM(err, log_engine)
|
|
|
|
static lg::log_domain log_display("display");
|
|
#define LOG_DP LOG_STREAM(info, log_display)
|
|
#define ERR_DP LOG_STREAM(err, log_display)
|
|
|
|
static lg::log_domain log_config("config");
|
|
#define LOG_CF LOG_STREAM(info, log_config)
|
|
#define ERR_CF LOG_STREAM(err, log_config)
|
|
|
|
/**
|
|
* 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 xcpos x-position of center of the logo
|
|
* @param ycpos y-position of center of the 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 xcpos, int ycpos)
|
|
{
|
|
surface const fb = screen.video().getSurface();
|
|
if (!fb) return true;
|
|
|
|
surface logo = image::get_image(game_config::images::game_logo);
|
|
if (!logo) {
|
|
ERR_DP << "Could not find game logo\n";
|
|
return true;
|
|
}
|
|
|
|
int xpos = xcpos - logo->w / 2;
|
|
int ypos = ycpos - logo->h / 2;
|
|
|
|
if (xpos < 0 || ypos < 0 || xpos + logo->w > fb->w || ypos + logo->h > fb->h) {
|
|
double scale = 2 * std::min(
|
|
std::min((double)xcpos / logo->w, (double)(fb->w - ycpos) / logo->w),
|
|
std::min((double)ycpos / logo->h, (double)(fb->h - ycpos) / logo->h));
|
|
logo = scale_surface(logo, logo->w * scale, logo->h * scale);
|
|
xpos = xcpos - logo->w / 2;
|
|
ypos = ycpos - logo->h / 2;
|
|
}
|
|
|
|
// 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 = create_rect(x, 0, 1, logo->h);
|
|
SDL_Rect dstrect = create_rect(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;
|
|
}
|
|
|
|
|
|
/** Read the file with the tips-of-the-day. */
|
|
void read_tips_of_day(config& tips_of_day)
|
|
{
|
|
tips_of_day.clear();
|
|
LOG_CF << "Loading tips of day\n";
|
|
try {
|
|
scoped_istream stream = preprocess_file(get_wml_location("hardwired/tips.cfg"));
|
|
read(tips_of_day, *stream);
|
|
} catch(config::error&) {
|
|
ERR_CF << "Could not read data/hardwired/tips.cfg\n";
|
|
}
|
|
|
|
//we shuffle the tips after each initial loading. We only shuffle if
|
|
//the upload_log preference has been set. If it hasn't been set, it's the
|
|
//user's first time playing since this feature has been added, so we'll
|
|
//leave the tips in their default order, which will always contain a tip
|
|
//regarding the upload log first, so the user sees it.
|
|
config::const_child_itors itors = tips_of_day.child_range("tip");
|
|
if (itors.first != itors.second && preferences::has_upload_log()) {
|
|
std::vector<config> tips(itors.first, itors.second);
|
|
std::random_shuffle(tips.begin(), tips.end());
|
|
tips_of_day.clear();
|
|
foreach (const config &tip, tips) {
|
|
tips_of_day.add_child("tip", tip);
|
|
}
|
|
}
|
|
|
|
//Make sure that the upload log preference is set, if it's not already, so
|
|
//that we know next time we've already seen the message about uploads.
|
|
if(!preferences::has_upload_log()) {
|
|
preferences::set_upload_log(preferences::upload_log());
|
|
}
|
|
}
|
|
|
|
/** Go to the next tips-of-the-day */
|
|
void next_tip_of_day(config& tips_of_day, bool reverse)
|
|
{
|
|
// we just rotate the tip list, to avoid the need to keep track
|
|
// of the current one, and keep it valid, cycle it, etc...
|
|
config::const_child_itors itors = tips_of_day.child_range("tip");
|
|
if (itors.first != itors.second) {
|
|
std::vector<config> tips(itors.first, itors.second);
|
|
std::vector<config>::iterator direction =
|
|
reverse ? tips.begin() + 1 : tips.end() - 1;
|
|
std::rotate(tips.begin(), direction, tips.end());
|
|
tips_of_day.clear();
|
|
foreach (const config &tip, tips) {
|
|
tips_of_day.add_child("tip", tip);
|
|
}
|
|
}
|
|
}
|
|
|
|
const config* get_tip_of_day(config& tips_of_day)
|
|
{
|
|
if (tips_of_day.empty()) {
|
|
read_tips_of_day(tips_of_day);
|
|
}
|
|
|
|
// next_tip_of_day rotate tips, so better stay iterator-safe
|
|
for (int nb_tips = tips_of_day.child_count("tip"); nb_tips > 0;
|
|
--nb_tips, next_tip_of_day(tips_of_day))
|
|
{
|
|
const config &tip = tips_of_day.child("tip");
|
|
assert(tip);
|
|
|
|
const std::vector<std::string> needed_units = utils::split(tip["encountered_units"], ',');
|
|
if (needed_units.empty()) {
|
|
return &tip;
|
|
}
|
|
const std::set<std::string>& seen_units = preferences::encountered_units();
|
|
|
|
// test if one of the listed unit types is already encountered
|
|
// if if's a number, test if we have encountered more than this
|
|
for (std::vector<std::string>::const_iterator i = needed_units.begin();
|
|
i != needed_units.end(); ++i) {
|
|
int needed_units_nb = lexical_cast_default<int>(*i,-1);
|
|
if (needed_units_nb !=-1) {
|
|
if (needed_units_nb <= static_cast<int>(seen_units.size())) {
|
|
return &tip;
|
|
}
|
|
} else if (seen_units.find(*i) != seen_units.end()) {
|
|
return &tip;
|
|
}
|
|
}
|
|
}
|
|
// not tip match, someone forget to put an always-match one
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* Show one tip-of-the-day in a frame on the titlescreen.
|
|
* This frame has 2 buttons: Next-Tip, and Show-Help.
|
|
*/
|
|
static void draw_tip_of_day(game_display& screen,
|
|
config& tips_of_day,
|
|
const gui::dialog_frame::style& style,
|
|
gui::button* const previous_tip_button,
|
|
gui::button* const next_tip_button,
|
|
gui::button* const help_tip_button,
|
|
const SDL_Rect* const main_dialog_area,
|
|
surface_restorer& tip_of_day_restorer)
|
|
{
|
|
// Restore the previous tip of day area to its old state (section of the title image).
|
|
tip_of_day_restorer.restore();
|
|
|
|
// Draw tip of the day
|
|
const config* tip = get_tip_of_day(tips_of_day);
|
|
if (!tip) return;
|
|
int tip_width = game_config::title_tip_width * screen.w() / 1024;
|
|
|
|
font::ttext text, source;
|
|
text.set_text((*tip)["text"], true);
|
|
text.set_maximum_width(tip_width);
|
|
text.set_maximum_height(main_dialog_area->h);
|
|
source.set_text((*tip)["source"], false);
|
|
source.set_font_style(font::ttext::STYLE_ITALIC);
|
|
source.set_maximum_width(tip_width);
|
|
source.set_alignment(PANGO_ALIGN_RIGHT);
|
|
|
|
int pad = game_config::title_tip_padding;
|
|
|
|
SDL_Rect area, source_area;
|
|
area.w = tip_width;
|
|
area.h = text.get_height();
|
|
source_area.w = source.get_width();
|
|
source_area.h = source.get_height();
|
|
area.w = std::max<size_t>(area.w, source_area.w) + 2 * pad;
|
|
area.h += source_area.h + next_tip_button->location().h + 3 * pad;
|
|
|
|
area.x = main_dialog_area->x - (game_config::title_tip_x * screen.w() / 1024) - area.w;
|
|
area.y = main_dialog_area->y + main_dialog_area->h - area.h;
|
|
|
|
// Note: The buttons' locations need to be set before the dialog frame is drawn.
|
|
// Otherwise, when the buttons restore their area, they
|
|
// draw parts of the old dialog frame at their old locations.
|
|
// This way, the buttons draw a part of the title image,
|
|
// because the call to restore above restored the area
|
|
// of the old tip of the day to its initial state (the title image).
|
|
int button_x = area.x + area.w - next_tip_button->location().w - pad;
|
|
int button_y = area.y + area.h - pad - next_tip_button->location().h;
|
|
next_tip_button->set_location(button_x, button_y);
|
|
next_tip_button->set_dirty(); //force redraw even if location did not change.
|
|
|
|
button_x -= previous_tip_button->location().w + pad;
|
|
previous_tip_button->set_location(button_x, button_y);
|
|
previous_tip_button->set_dirty();
|
|
|
|
button_x = area.x + pad;
|
|
help_tip_button->set_location(button_x, button_y);
|
|
help_tip_button->set_dirty();
|
|
|
|
gui::dialog_frame f(screen.video(), "", style, false);
|
|
tip_of_day_restorer = surface_restorer(&screen.video(), f.layout(area).exterior);
|
|
f.draw_background();
|
|
f.draw_border();
|
|
|
|
surface text_s = text.render();
|
|
screen.video().blit_surface(area.x + pad, area.y + pad, text_s);
|
|
surface source_s = source.render();
|
|
screen.video().blit_surface(area.x + pad,
|
|
next_tip_button->location().y - source_area.h - pad, source_s);
|
|
|
|
LOG_DP << "drew tip of day\n";
|
|
}
|
|
|
|
/**
|
|
* Draw the map image background, revision number
|
|
* and fade the log the first time
|
|
*/
|
|
static void draw_background(game_display& screen)
|
|
{
|
|
bool fade_failed = false;
|
|
do {
|
|
int logo_x = game_config::title_logo_x * screen.w() / 1024,
|
|
logo_y = game_config::title_logo_y * screen.h() / 768;
|
|
|
|
/*Select a random game_title*/
|
|
std::vector<std::string> game_title_list =
|
|
utils::split(game_config::images::game_title, ',', utils::STRIP_SPACES | utils::REMOVE_EMPTY);
|
|
|
|
if(game_title_list.empty()) {
|
|
ERR_CF << "No title image defined\n";
|
|
} else {
|
|
surface const title_surface(scale_opaque_surface(
|
|
image::get_image(game_title_list[rand()%game_title_list.size()]),
|
|
screen.w(), screen.h()));
|
|
|
|
|
|
if (title_surface.null()) {
|
|
ERR_DP << "Could not find title image\n";
|
|
} else {
|
|
screen.video().blit_surface(0, 0, title_surface);
|
|
update_rect(screen_area());
|
|
LOG_DP << "displayed title image\n";
|
|
}
|
|
}
|
|
|
|
fade_failed = !fade_logo(screen, logo_x, logo_y);
|
|
} while (fade_failed);
|
|
LOG_DP << "faded logo\n";
|
|
|
|
// Display Wesnoth version and (if possible) revision
|
|
const std::string& version_str = _("Version") +
|
|
std::string(" ") + game_config::revision;
|
|
|
|
const SDL_Rect version_area = font::draw_text(NULL, screen_area(),
|
|
font::SIZE_TINY, font::NORMAL_COLOR,
|
|
version_str,0,0);
|
|
const size_t versiony = screen.h() - version_area.h;
|
|
|
|
if(versiony < size_t(screen.h())) {
|
|
draw_solid_tinted_rectangle(0, versiony - 2, version_area.w + 3, version_area.h + 2,0,0,0,0.75,screen.video().getSurface());
|
|
font::draw_text(&screen.video(),screen.screen_area(),
|
|
font::SIZE_TINY, font::NORMAL_COLOR,
|
|
version_str,0,versiony);
|
|
}
|
|
|
|
LOG_DP << "drew version number\n";
|
|
}
|
|
|
|
namespace {
|
|
|
|
/**
|
|
* Handler for forcing a discrete ESC keypress to quit the game (bug #12747)
|
|
* This hack is here because the GUI code used here doesn't handle this yet.
|
|
* Once it does, revert this part of r31758.
|
|
*/
|
|
class titlescreen_handler : public events::handler
|
|
{
|
|
public:
|
|
titlescreen_handler(bool ignore_esc = false)
|
|
: handler(), ignore_esc_(ignore_esc)
|
|
{
|
|
if(ignore_esc) {
|
|
LOG_DP << "ignoring held ESCAPE key\n";
|
|
}
|
|
}
|
|
|
|
bool get_esc_ignore() const { return ignore_esc_; }
|
|
|
|
virtual void handle_event(const SDL_Event& event)
|
|
{
|
|
if(event.type == SDL_KEYUP && event.key.keysym.sym == SDLK_ESCAPE) {
|
|
ignore_esc_ = false;
|
|
LOG_DP << "ESCAPE key no longer ignored\n";
|
|
}
|
|
}
|
|
|
|
private:
|
|
bool ignore_esc_;
|
|
};
|
|
|
|
} // end anon namespace
|
|
|
|
namespace gui {
|
|
|
|
|
|
static bool background_is_dirty_ = true;
|
|
void set_background_dirty() {
|
|
background_is_dirty_ = true;
|
|
}
|
|
|
|
|
|
TITLE_RESULT show_title(game_display& screen, config& tips_of_day)
|
|
{
|
|
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"),
|
|
N_("TitleScreen button^Multiplayer"),
|
|
N_("TitleScreen button^Load"),
|
|
N_("TitleScreen button^Add-ons"),
|
|
#ifndef DISABLE_EDITOR
|
|
N_("TitleScreen button^Map Editor"),
|
|
#endif
|
|
N_("TitleScreen button^Language"),
|
|
N_("TitleScreen button^Preferences"),
|
|
N_("TitleScreen button^Credits"),
|
|
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"),
|
|
N_("Play multiplayer (hotseat, LAN, or Internet), or a single scenario against the AI"),
|
|
N_("Load a saved game"),
|
|
N_("Download usermade campaigns, eras, or map packs"),
|
|
#ifndef DISABLE_EDITOR
|
|
N_("Start the map editor"),
|
|
#endif
|
|
N_("Change the language"),
|
|
N_("Configure the game's settings"),
|
|
N_("View the credits"),
|
|
N_("Quit the game"),
|
|
N_("Show previous tip of the day"),
|
|
N_("Show next tip of the day"),
|
|
N_("Show Battle for Wesnoth help"),
|
|
N_("Help Wesnoth by sending us information")
|
|
};
|
|
|
|
static const size_t nbuttons = sizeof(button_labels)/sizeof(*button_labels);
|
|
const int menu_xbase = (game_config::title_buttons_x*screen.w())/1024;
|
|
const int menu_xincr = 0;
|
|
|
|
#ifdef USE_TINY_GUI
|
|
const int menu_ybase = (game_config::title_buttons_y*screen.h())/768 - 15;
|
|
const int menu_yincr = 15;
|
|
#else
|
|
const int menu_ybase = (game_config::title_buttons_y*screen.h())/768;
|
|
const int menu_yincr = 35;
|
|
#endif
|
|
|
|
const int padding = 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)
|
|
{
|
|
std::string label = sgettext(button_labels[b]);
|
|
if (b + TUTORIAL <= QUIT_GAME) {
|
|
buttons.push_back(button(screen.video(), label));
|
|
max_width = std::max<size_t>(max_width,buttons.back().width ());
|
|
n_menubuttons = b;
|
|
} else if (b + TUTORIAL <= SHOW_HELP) {
|
|
buttons.push_back(button(screen.video(), label,
|
|
button::TYPE_PRESS, "lite_small"));
|
|
} else {
|
|
buttons.push_back(button(screen.video(), label,
|
|
button::TYPE_IMAGE, "menu-button",
|
|
button::MINIMUM_SPACE));
|
|
}
|
|
buttons.back().set_help_string(sgettext(help_button_labels[b]));
|
|
}
|
|
|
|
SDL_Rect main_dialog_area = create_rect(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();
|
|
}
|
|
|
|
for(b = 0; b != nbuttons; ++b) {
|
|
buttons[b].set_width(max_width);
|
|
buttons[b].set_location(menu_xbase + b*menu_xincr, menu_ybase + b*menu_yincr);
|
|
if(b + TUTORIAL == QUIT_GAME) break;
|
|
}
|
|
|
|
gui::button &previous_tip_button = buttons[TIP_PREVIOUS - TUTORIAL];
|
|
gui::button &next_tip_button = buttons[TIP_NEXT - TUTORIAL];
|
|
gui::button &help_tip_button = buttons[SHOW_HELP - TUTORIAL];
|
|
gui::button &beg_button = buttons[BEG_FOR_UPLOAD - TUTORIAL];
|
|
|
|
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, &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";
|
|
|
|
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";
|
|
|
|
for(;;) {
|
|
events::pump();
|
|
for(size_t b = 0; b != buttons.size(); ++b) {
|
|
if(buttons[b].pressed()) {
|
|
return static_cast<TITLE_RESULT>(b + TUTORIAL);
|
|
}
|
|
}
|
|
|
|
if(previous_tip_button.pressed() || (key[SDLK_RETURN] && keyboard_button == TIP_PREVIOUS - TUTORIAL)) {
|
|
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() || (key[SDLK_RETURN] && keyboard_button == TIP_NEXT - TUTORIAL)) {
|
|
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) {
|
|
if (keyboard_button < nbuttons)
|
|
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) {
|
|
if (keyboard_button < nbuttons)
|
|
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();
|
|
events::raise_draw_event();
|
|
|
|
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
|
|
&& keyboard_button != TIP_PREVIOUS - TUTORIAL
|
|
&& keyboard_button != TIP_NEXT - TUTORIAL) {
|
|
return static_cast<TITLE_RESULT>(keyboard_button + TUTORIAL);
|
|
}
|
|
|
|
|
|
|
|
// 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(20);
|
|
}
|
|
|
|
return QUIT_GAME;
|
|
}
|
|
|
|
} // namespace gui
|
|
|
|
//.
|