made resizing the window in the title screen work properly, ...

...and made basic keyboard shortcuts work in the title scren
This commit is contained in:
Dave White 2004-05-05 00:40:15 +00:00
parent eca141e046
commit 111cd8cbfa
13 changed files with 262 additions and 182 deletions

View file

@ -213,7 +213,7 @@ This unit illuminates the surrounding area, making lawful units fight better, an
Any units adjacent to this unit will fight as if it were dusk when it is night, and as if it were day when it is dusk."
skirmisher_description="Skirmishes:
skirmisher_description="Skirmisher:
This unit is skilled in moving past enemies quickly, and ignores all Enemy Zones of Control."
no_leader_to_recruit="You don't have a leader to recruit with."

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 8 KiB

View file

@ -278,7 +278,7 @@ int display::hex_width() const
double display::zoom(int amount)
{
if(amount == 0) {
if(amount == 0 || !team_valid()) {
return double(zoom_)/double(DefaultZoom);
}
@ -2079,7 +2079,7 @@ void display::add_chat_message(const std::string& speaker, int side, const std::
if(type == MESSAGE_PUBLIC) {
str << "<" << speaker << ">";
} else {
str << "*" << speaker << "*";
str << font::NULL_MARKUP << "*" << speaker << "*";
}
SDL_Color speaker_colour = {255,255,255,255};

View file

@ -66,7 +66,7 @@ namespace {
double location_distance(const gamemap::location loc1, const gamemap::location loc2) {
const double xdiff = loc1.x - loc2.x;
const double ydiff = loc1.y - loc2.y;
const double dist = std::sqrt(xdiff * xdiff + ydiff * ydiff);
const double dist = sqrt(xdiff * xdiff + ydiff * ydiff);
return dist;
}
@ -631,8 +631,8 @@ void map_editor::perform_selection_move() {
gui_.clear_highlighted_locs();
std::set<gamemap::location> new_selection;
// Transfer the terrain to the new position.
for (std::set<gamemap::location>::const_iterator it = selected_hexes_.begin();
it != selected_hexes_.end(); it++) {
std::set<gamemap::location>::const_iterator it;
for(it = selected_hexes_.begin(); it != selected_hexes_.end(); it++) {
const gamemap::location hl_loc =
get_hex_with_offset(*it, x_diff, y_diff);
if (map_.on_board(hl_loc)) {
@ -644,8 +644,7 @@ void map_editor::perform_selection_move() {
}
// Fill the selection with the selected terrain.
for (std::set<gamemap::location>::const_iterator it = selected_hexes_.begin();
it != selected_hexes_.end(); it++) {
for (it = selected_hexes_.begin(); it != selected_hexes_.end(); it++) {
if (map_.on_board(*it) && new_selection.find(*it) == new_selection.end()) {
undo_action.add(map_.get_terrain(*it), palette_.selected_terrain(), *it);
map_.set_terrain(*it, palette_.selected_terrain());

View file

@ -41,6 +41,7 @@
#include "sound.hpp"
#include "statistics.hpp"
#include "team.hpp"
#include "titlescreen.hpp"
#include "util.hpp"
#include "unit_types.hpp"
#include "unit.hpp"
@ -598,7 +599,11 @@ int play_game(int argc, char** argv)
recorder.clear();
std::cerr << "showing title screen...\n";
gui::TITLE_RESULT res = gui::show_title(disp);
gui::TITLE_RESULT res = gui::CONTINUE;
while(res == gui::CONTINUE) {
res = gui::show_title(disp);
}
std::cerr << "title screen returned result\n";

View file

@ -282,15 +282,12 @@ void mp_connect::lists_init()
config::child_iterator sd;
for(sd = sides.first; sd != sides.second; ++sd) {
const int team_num = sd - sides.first;
const std::string& team_name = (**sd)["team_name"];
std::stringstream str;
str << string_table["team"] << " ";
std::string& team_name = (**sd)["team_name"];
if(team_name.empty()) {
team_name = lexical_cast<std::string>(team_num+1);
}
if(team_name.empty() == false)
str << team_name;
else
str << (team_num+1);
player_teams_.push_back(str.str());
player_teams_.push_back(string_table["team"] + " " + team_name);
}
//Colors

View file

@ -284,15 +284,37 @@ void game::send_data(const config& data, network::connection exclude)
}
}
bool game::player_on_team(const std::string& team, network::connection player) const
{
//if the player is the game host, then iterate over all the sides and if any of
//the sides controlled by the game host are on this team, then the game host
//is on this team
if(players_.empty() == false && player == players_.front()) {
const config::child_list& sides = level_.get_children("side");
for(config::child_list::const_iterator i = sides.begin(); i != sides.end(); ++i) {
if((**i)["controller"] == "human" && (**i)["team_name"] == team) {
return true;
}
}
}
//other hosts than the game host
const std::map<network::connection,std::string>::const_iterator side = sides_.find(player);
if(side != sides_.end()) {
const config* const side_cfg = level_.find_child("side","side",side->second);
if(side_cfg != NULL && (*side_cfg)["team_name"] == team) {
return true;
}
}
return false;
}
void game::send_data_team(const config& data, const std::string& team, network::connection exclude)
{
for(std::vector<network::connection>::const_iterator
i = players_.begin(); i != players_.end(); ++i) {
if(*i != exclude && sides_.count(*i) == 1) {
const config* const side = level_.find_child("side","side",sides_[*i]);
if(side != NULL && (*side)["team_name"] == team) {
network::send_data(data,*i);
}
for(std::vector<network::connection>::const_iterator i = players_.begin(); i != players_.end(); ++i) {
if(*i != exclude && player_on_team(team,*i)) {
network::send_data(data,*i);
}
}
}

View file

@ -70,6 +70,9 @@ public:
private:
//function which returns true iff 'player' is on 'team'.
bool player_on_team(const std::string& team, network::connection player) const;
//function which should be called every time a player ends their turn
//(i.e. [end_turn] received). This will update the 'turn' attribute for
//the game's description when appropriate. Will return true if there has

View file

@ -800,157 +800,4 @@ network::connection network_data_dialog(display& disp, const std::string& msg, c
}
}
void fade_logo(display& screen, int xpos, int ypos)
{
const scoped_sdl_surface logo(image::get_image(game_config::game_logo,image::UNSCALED));
if(logo == NULL) {
std::cerr << "Could not find game logo\n";
return;
}
SDL_Surface* const fb = screen.video().getSurface();
if(fb == NULL || xpos < 0 || ypos < 0 || xpos + logo->w > fb->w || ypos + logo->h > fb->h) {
return;
}
//only once, when the game is first started, the logo fades in
static bool faded_in = false;
CKey key;
bool last_button = key[SDLK_ESCAPE] || key[SDLK_SPACE];
std::cerr << "fading logo in....\n";
std::cerr << "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];
if(new_button && !last_button) {
faded_in = true;
}
last_button = new_button;
screen.update_display();
SDL_Delay(10);
events::pump();
}
}
std::cerr << "logo faded in\n";
faded_in = true;
}
TITLE_RESULT show_title(display& screen)
{
cursor::set(cursor::NORMAL);
const events::resize_lock prevent_resizing;
const scoped_sdl_surface title_surface_unscaled(image::get_image(game_config::game_title,image::UNSCALED));
const scoped_sdl_surface title_surface(scale_surface(title_surface_unscaled,screen.x(),screen.y()));
if(title_surface == NULL) {
std::cerr << "Could not find title image\n";
} else {
screen.blit_surface(0,0,title_surface);
update_rect(screen.screen_area());
std::cerr << "displayed title image\n";
}
fade_logo(screen,(game_config::title_logo_x*screen.x())/1024,(game_config::title_logo_y*screen.y())/768);
std::cerr << "faded logo\n";
const std::string& version_str = string_table["version"] + " " +
game_config::version;
const SDL_Rect version_area = font::draw_text(NULL,screen.screen_area(),10,
font::NORMAL_COLOUR,version_str,0,0);
const size_t versiony = screen.y() - version_area.h;
if(versiony < size_t(screen.y())) {
font::draw_text(&screen,screen.screen_area(),
10,font::NORMAL_COLOUR,version_str,0,versiony);
}
std::cerr << "drew version number\n";
//members of this array must correspond to the enumeration TITLE_RESULT
static const std::string button_labels[] = { "tutorial_button", "campaign_button", "multiplayer_button",
"load_button", "language_button", "preferences", "about_button", "quit_button" };
static const size_t nbuttons = sizeof(button_labels)/sizeof(*button_labels);
const int menu_xbase = (game_config::title_buttons_x*screen.x())/1024;
const int menu_xincr = 0;
const int menu_ybase = (game_config::title_buttons_y*screen.y())/768;
const int menu_yincr = 40;
const int padding = game_config::title_buttons_padding;
std::vector<button> buttons;
size_t b, max_width = 0;
for(b = 0; b != nbuttons; ++b) {
buttons.push_back(button(screen,string_table[button_labels[b]]));
buttons.back().set_xy(menu_xbase + b*menu_xincr, menu_ybase + b*menu_yincr);
max_width = maximum<size_t>(max_width,buttons.back().width());
}
std::string style = "mainmenu";
draw_dialog_frame(menu_xbase-padding,menu_ybase-padding,max_width+padding*2,menu_yincr*(nbuttons-1)+buttons.back().height()+padding*2,screen,&style);
for(b = 0; b != nbuttons; ++b) {
buttons.back().draw();
}
std::cerr << "drew buttons dialog\n";
CKey key;
bool last_escape = key[SDLK_ESCAPE];
update_whole_screen();
std::cerr << "entering interactive loop...\n";
for(;;) {
int mousex, mousey;
const int mouse_flags = SDL_GetMouseState(&mousex,&mousey);
const bool left_button = mouse_flags&SDL_BUTTON_LMASK;
for(size_t b = 0; b != buttons.size(); ++b) {
if(buttons[b].process(mousex,mousey,left_button)) {
return TITLE_RESULT(b);
}
}
if(!last_escape && key[SDLK_ESCAPE])
return QUIT_GAME;
last_escape = key[SDLK_ESCAPE];
screen.video().flip();
events::pump();
SDL_Delay(20);
}
return QUIT_GAME;
}
} //end namespace gui

View file

@ -132,11 +132,6 @@ int show_dialog(display& screen, SDL_Surface* image,
network::connection network_data_dialog(display& disp, const std::string& msg, config& cfg, network::connection connection_num=0);
enum TITLE_RESULT { TUTORIAL, NEW_CAMPAIGN, MULTIPLAYER, LOAD_GAME,
CHANGE_LANGUAGE, EDIT_PREFERENCES, SHOW_ABOUT, QUIT_GAME };
TITLE_RESULT show_title(display& screen);
void check_quit(display& screen);
}

184
src/titlescreen.cpp Normal file
View file

@ -0,0 +1,184 @@
#include "cursor.hpp"
#include "display.hpp"
#include "events.hpp"
#include "font.hpp"
#include "game_config.hpp"
#include "hotkeys.hpp"
#include "key.hpp"
#include "language.hpp"
#include "preferences.hpp"
#include "sdl_utils.hpp"
#include "show_dialog.hpp"
#include "titlescreen.hpp"
#include "util.hpp"
#include "video.hpp"
namespace {
void fade_logo(display& screen, int xpos, int ypos)
{
const scoped_sdl_surface logo(image::get_image(game_config::game_logo,image::UNSCALED));
if(logo == NULL) {
std::cerr << "Could not find game logo\n";
return;
}
SDL_Surface* const fb = screen.video().getSurface();
if(fb == NULL || xpos < 0 || ypos < 0 || xpos + logo->w > fb->w || ypos + logo->h > fb->h) {
return;
}
//only once, when the game is first started, the logo fades in
static bool faded_in = false;
CKey key;
bool last_button = key[SDLK_ESCAPE] || key[SDLK_SPACE];
std::cerr << "fading logo in....\n";
std::cerr << "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];
if(new_button && !last_button) {
faded_in = true;
}
last_button = new_button;
screen.update_display();
SDL_Delay(10);
events::pump();
}
}
std::cerr << "logo faded in\n";
faded_in = true;
}
}
namespace gui {
TITLE_RESULT show_title(display& screen)
{
cursor::set(cursor::NORMAL);
const preferences::display_manager disp_manager(&screen);
const hotkey::basic_handler key_handler(&screen);
const video_change_detector disp_change_detector(screen.video());
const scoped_sdl_surface title_surface_unscaled(image::get_image(game_config::game_title,image::UNSCALED));
const scoped_sdl_surface title_surface(scale_surface(title_surface_unscaled,screen.x(),screen.y()));
if(title_surface == NULL) {
std::cerr << "Could not find title image\n";
} else {
screen.blit_surface(0,0,title_surface);
update_rect(screen.screen_area());
std::cerr << "displayed title image\n";
}
fade_logo(screen,(game_config::title_logo_x*screen.x())/1024,(game_config::title_logo_y*screen.y())/768);
std::cerr << "faded logo\n";
const std::string& version_str = string_table["version"] + " " +
game_config::version;
const SDL_Rect version_area = font::draw_text(NULL,screen.screen_area(),10,
font::NORMAL_COLOUR,version_str,0,0);
const size_t versiony = screen.y() - version_area.h;
if(versiony < size_t(screen.y())) {
font::draw_text(&screen,screen.screen_area(),
10,font::NORMAL_COLOUR,version_str,0,versiony);
}
std::cerr << "drew version number\n";
//members of this array must correspond to the enumeration TITLE_RESULT
static const std::string button_labels[] = { "tutorial_button", "campaign_button", "multiplayer_button",
"load_button", "language_button", "preferences", "about_button", "quit_button" };
static const size_t nbuttons = sizeof(button_labels)/sizeof(*button_labels);
const int menu_xbase = (game_config::title_buttons_x*screen.x())/1024;
const int menu_xincr = 0;
const int menu_ybase = (game_config::title_buttons_y*screen.y())/768;
const int menu_yincr = 40;
const int padding = game_config::title_buttons_padding;
std::vector<button> buttons;
size_t b, max_width = 0;
for(b = 0; b != nbuttons; ++b) {
buttons.push_back(button(screen,string_table[button_labels[b]]));
buttons.back().set_xy(menu_xbase + b*menu_xincr, menu_ybase + b*menu_yincr);
max_width = maximum<size_t>(max_width,buttons.back().width());
}
std::string style = "mainmenu";
draw_dialog_frame(menu_xbase-padding,menu_ybase-padding,max_width+padding*2,menu_yincr*(nbuttons-1)+buttons.back().height()+padding*2,screen,&style);
for(b = 0; b != nbuttons; ++b) {
buttons.back().draw();
}
std::cerr << "drew buttons dialog\n";
CKey key;
bool last_escape = key[SDLK_ESCAPE];
update_whole_screen();
std::cerr << "entering interactive loop...\n";
for(;;) {
int mousex, mousey;
const int mouse_flags = SDL_GetMouseState(&mousex,&mousey);
const bool left_button = mouse_flags&SDL_BUTTON_LMASK;
for(size_t b = 0; b != buttons.size(); ++b) {
if(buttons[b].process(mousex,mousey,left_button)) {
return TITLE_RESULT(b);
}
}
if(!last_escape && key[SDLK_ESCAPE])
return QUIT_GAME;
last_escape = key[SDLK_ESCAPE];
screen.video().flip();
events::pump();
//if the resolution has changed due to the user resizing the screen,
//or from changing between windowed and fullscreen
if(disp_change_detector.changed()) {
return CONTINUE;
}
SDL_Delay(20);
}
return QUIT_GAME;
}
}

15
src/titlescreen.hpp Normal file
View file

@ -0,0 +1,15 @@
#ifndef TITLE_HPP_INCLUDED
#define TITLE_HPP_INCLUDED
#include "display.hpp"
namespace gui {
enum TITLE_RESULT { TUTORIAL = 0, NEW_CAMPAIGN, MULTIPLAYER, LOAD_GAME,
CHANGE_LANGUAGE, EDIT_PREFERENCES, SHOW_ABOUT, QUIT_GAME, CONTINUE };
TITLE_RESULT show_title(display& screen);
}
#endif

View file

@ -77,4 +77,17 @@ private:
bool fake_screen;
};
//a structure which will detect if the resolution or fullscreen mode has changed
struct video_change_detector {
video_change_detector(CVideo& video) : video_(video), full_(video.isFullScreen()), x_(video.getx()), y_(video.gety())
{}
bool changed() const { return full_ != video_.isFullScreen() || x_ != video_.getx() || y_ != video_.gety(); }
private:
CVideo& video_;
bool full_;
int x_, y_;
};
#endif