adds support for changing themes ingame

removes replay gui controls from normal gameplay
fixes "corrupted file"-message after single side turn
This commit is contained in:
Jörg Hinrichs 2005-12-06 20:38:00 +00:00
parent baadf6c5b9
commit 9bdb4bbd0a
7 changed files with 296 additions and 33 deletions

View file

@ -43,20 +43,8 @@ height=768
yanchor=fixed
[/panel]
[panel]
id=replay-panel
image=misc/top-bg.png
ref=top-panel
rect="=,+0,+882,+26"
xanchor=left
yanchor=fixed
[/panel]
{themes/macros.cfg}
{REPLAY_THEME}
[main_map]
id=main-map
ref=replay-panel
rect="=,+0,+882,768"
xanchor=left
yanchor=top
@ -66,7 +54,7 @@ height=768
[panel]
id=top-right-panel
image=misc/rightside.png
rect="+0,=-27,1024,+284"
rect="+0,=+0,1024,+284"
xanchor=right
yanchor=fixed
[/panel]
@ -441,8 +429,138 @@ height=768
[/unit_status]
[/status]
[replay]
[change]
id=main-map
ref=top-panel
rect="=,+26,+882,768"
[/change]
[add]
[panel]
id=replay-panel
image=misc/top-bg.png
ref=top-panel
rect="=,+0,+882,+26"
xanchor=left
yanchor=fixed
[/panel]
[/add]
[add]
[label]
id=replay-label
text= _ "Replay"
ref=replay-panel
rect="=+3,=+1,+60,=-4"
xanchor=fixed
yanchor=fixed
[/label]
[/add]
[add]
[menu]
id=button-playreplay
ref=replay-label
type=image
image=play
title= _ "Play"
items=playreplay
rect="+4,=-2,+23,="
xanchor=fixed
yanchor=fixed
[/menu]
[/add]
[add]
[menu]
id=button-stopreplay
ref=button-playreplay
type=image
image=pause
title= _ "Stop"
items=stopreplay
rect="+4,=,+23,="
xanchor=fixed
yanchor=fixed
[/menu]
[/add]
[add]
[menu]
id=button-resetreplay
ref=button-stopreplay
type=image
image=stop
title= _ "Reset"
items=resetreplay
rect="+4,=,+23,="
xanchor=fixed
yanchor=fixed
[/menu]
[/add]
[add]
[menu]
id=button-nextturn
ref=button-resetreplay
type=image
image=fast-fwd
title= _ "Next Turn"
items=replaynextturn
rect="+4,=,+23,="
xanchor=fixed
yanchor=fixed
[/menu]
[/add]
[add]
[menu]
id=button-nextside
ref=button-nextturn
type=image
image=frame-fwd
title= _ "Next Side"
items=replaynextside
rect="+4,=,+23,="
xanchor=fixed
yanchor=fixed
[/menu]
[/add]
[add]
[menu]
id=check-shroud
ref=button-nextside
type=checkbox
title= _ "Shroud"
items=replayswitchshroud
rect="+15,=+3,+180,+10"
xanchor=fixed
yanchor=fixed
[/menu]
[/add]
[add]
[menu]
id=check-fog
ref=check-shroud
type=checkbox
title= _ "Fog"
items=replayswitchfog
rect="+5,=,+80,+10"
xanchor=fixed
yanchor=fixed
[/menu]
[/add]
[add]
[menu]
id=skip-animation
ref=check-fog
type=checkbox
title= _ "Skip animation"
items=replayskipanimation
rect="+5,=,+80,+10"
xanchor=fixed
yanchor=fixed
[/menu]
[/add]
[/replay]
[/resolution]
[partialresolution]
id=1000x600
inherits=1024x768

View file

@ -2257,7 +2257,7 @@ size_t display::playing_team() const
return activeTeam_;
}
const theme& display::get_theme() const
theme& display::get_theme()
{
return theme_;
}

View file

@ -324,7 +324,7 @@ public:
size_t viewing_team() const;
size_t playing_team() const;
const theme& get_theme() const;
theme& get_theme();
const theme::menu* menu_pressed();

View file

@ -142,6 +142,8 @@ void replay_controller::init(CVideo& video, const std::vector<config*>& story){
LOG_NG << "initializing display... " << (SDL_GetTicks() - ticks) << "\n";
const config* theme_cfg = get_theme(game_config_, level_["theme"]);
gui_ = new display(units_,video,map_,status_,teams_,*theme_cfg, game_config_, level_);
const config* replay_theme_cfg = theme_cfg->child("resolution")->child("replay");
gui_->get_theme().modify(replay_theme_cfg);
mouse_handler_.set_gui(gui_);
theme::set_known_themes(&game_config_);
LOG_NG << "done initializing display... " << (SDL_GetTicks() - ticks) << "\n";
@ -288,6 +290,7 @@ void replay_controller::show_help(){
void replay_controller::reset_replay(){
is_playing_ = false;
current_turn_ = 1;
player_number_ = 1;
recorder.start_replay();
units_ = *(new unit_map(units_start_));
status_ = *(new gamestatus(status_start_));

View file

@ -36,7 +36,6 @@ namespace {
const size_t DefaultFontSize = font::SIZE_NORMAL;
const Uint32 DefaultFontRGB = 0x00C8C8C8;
typedef struct { size_t x1,y1,x2,y2; } _rect;
_rect ref_rect = { 0, 0, 0, 0 };
size_t compute(std::string expr, size_t ref1, size_t ref2=0 ) {
@ -264,7 +263,8 @@ theme::object::object() : loc_(empty_rect), relative_loc_(empty_rect),
{}
theme::object::object(const config& cfg)
: loc_(read_sdl_rect(cfg)), relative_loc_(empty_rect),
: id_(cfg["id"]),
loc_(read_sdl_rect(cfg)), relative_loc_(empty_rect),
last_screen_(empty_rect),
xanchor_(read_anchor(cfg["xanchor"])),
yanchor_(read_anchor(cfg["yanchor"]))
@ -332,6 +332,10 @@ const SDL_Rect& theme::object::get_location(void) const
return loc_;
}
const std::string& theme::object::get_id() const{
return id_;
}
theme::object::ANCHORING theme::object::read_anchor(const std::string& str)
{
static const std::string top_anchor = "top", left_anchor = "left",
@ -347,6 +351,31 @@ theme::object::ANCHORING theme::object::read_anchor(const std::string& str)
return FIXED;
}
void theme::object::modify_location(const _rect rect){
loc_.x = rect.x1;
loc_.y = rect.y1;
loc_.w = rect.x2 - rect.x1;
loc_.h = rect.y2 - rect.y1;
}
void theme::object::modify_location(std::string rect_str, SDL_Rect ref_rect){
_rect rect = { 0, 0, 0, 0 };
const std::vector<std::string> items = utils::split(rect_str.c_str());
if(items.size() >= 1) {
rect.x1 = compute(items[0], ref_rect.x, ref_rect.x + ref_rect.w);
}
if(items.size() >= 2) {
rect.y1 = compute(items[1], ref_rect.y, ref_rect.y + ref_rect.h);
}
if(items.size() >= 3) {
rect.x2 = compute(items[2], ref_rect.x + ref_rect.w, rect.x1);
}
if(items.size() >= 4) {
rect.y2 = compute(items[3], ref_rect.y + ref_rect.h, rect.y1);
}
modify_location(rect);
}
theme::label::label()
{}
@ -555,19 +584,24 @@ bool theme::set_resolution(const SDL_Rect& screen)
menus_.clear();
const config& cfg = **current;
add_object(cfg);
return result;
}
theme::object& theme::add_object(const config& cfg){
theme::object& result = *(new theme::object());
const config* const main_map_cfg = cfg.child("main_map");
if(main_map_cfg != NULL) {
main_map_ = object(*main_map_cfg);
} else {
main_map_ = object();
result = main_map_;
}
const config* const mini_map_cfg = cfg.child("mini_map");
if(mini_map_cfg != NULL) {
mini_map_ = object(*mini_map_cfg);
} else {
mini_map_ = object();
result = mini_map_;
}
const config* const status_cfg = cfg.child("status");
@ -583,33 +617,125 @@ bool theme::set_resolution(const SDL_Rect& screen)
} else {
unit_image_ = object();
}
result = unit_image_;
}
const config::child_list& panel_list = cfg.get_children("panel");
for(config::child_list::const_iterator p = panel_list.begin(); p != panel_list.end(); ++p) {
panels_.push_back(panel(**p));
panel new_panel(**p);
set_object_location(new_panel, (**p)["rect"], (**p)["ref"]);
panels_.push_back(new_panel);
result = new_panel;
}
const config::child_list& label_list = cfg.get_children("label");
for(config::child_list::const_iterator lb = label_list.begin(); lb != label_list.end(); ++lb) {
labels_.push_back(label(**lb));
label new_label(**lb);
set_object_location(new_label, (**lb)["rect"], (**lb)["ref"]);
labels_.push_back(new_label);
result = new_label;
}
const config::child_list& menu_list = cfg.get_children("menu");
for(config::child_list::const_iterator m = menu_list.begin(); m != menu_list.end(); ++m) {
const menu new_menu(**m);
menu new_menu(**m);
LOG_DP << "adding menu: " << (new_menu.is_context() ? "is context" : "not context") << "\n";
if(new_menu.is_context())
context_ = new_menu;
else
else{
set_object_location(new_menu, (**m)["rect"], (**m)["ref"]);
menus_.push_back(new_menu);
}
LOG_DP << "done adding menu...\n";
result = new_menu;
}
return result;
}
void theme::remove_object(std::string id){
for(std::vector<theme::panel>::iterator p = panels_.begin(); p != panels_.end(); ++p) {
if (p->get_id() == id){
panels_.erase(p);
return;
}
}
for(std::vector<theme::label>::iterator l = labels_.begin(); l != labels_.end(); ++l) {
if (l->get_id() == id){
labels_.erase(l);
return;
}
}
for(std::vector<theme::menu>::iterator m = menus_.begin(); m != menus_.end(); ++m) {
if (m->get_id() == id){
menus_.erase(m);
return;
}
}
}
void theme::set_object_location(theme::object& element, std::string rect_str, std::string ref_id){
theme::object& ref_element = *(new object());
if (ref_id.empty()) {
ref_id = element.get_id();
ref_element = element;
}
else {
ref_element = find_element(ref_id);
}
if (ref_element.get_id() == ref_id){
SDL_Rect ref_rect = ref_element.get_location();
element.modify_location(rect_str, ref_rect);
}
}
void theme::modify(const config* cfg){
{
//changes to existing theme objects
const config::child_list& c = cfg->get_children("change");
for(config::child_list::const_iterator j = c.begin(); j != c.end(); ++j) {
std::string id = (**j)["id"];
std::string ref_id = (**j)["ref"];
theme::object& element = find_element(id);
if (element.get_id() == id){
set_object_location(element, (**j)["rect"], ref_id);
}
}
}
//adding new theme objects
{
const config::child_list& c = cfg->get_children("add");
for(config::child_list::const_iterator j = c.begin(); j != c.end(); ++j) {
add_object(**j);
}
}
//removing existent theme objects
{
const config::child_list& c = cfg->get_children("remove");
for(config::child_list::const_iterator j = c.begin(); j != c.end(); ++j) {
remove_object((**j)["id"]);
}
}
}
theme::object& theme::find_element(std::string id){
theme::object* res = new theme::object();
for (std::vector<theme::panel>::iterator p = panels_.begin(); p != panels_.end(); ++p){
if (p->get_id() == id) { res = p; }
}
for (std::vector<theme::label>::iterator l = labels_.begin(); l != labels_.end(); ++l){
if (l->get_id() == id) { res = l; }
}
for (std::vector<theme::menu>::iterator m = menus_.begin(); m != menus_.end(); ++m){
if (m->get_id() == id) { res = m; }
}
if (id == "main-map") { res = &main_map_; }
if (id == "mini-map") { res = &mini_map_; }
if (id == "unit-image") { res = &unit_image_; }
return *res;
}
const std::vector<theme::panel>& theme::panels() const
{
return panels_;

View file

@ -22,6 +22,8 @@ class config;
#include "SDL.h"
typedef struct { size_t x1,y1,x2,y2; } _rect;
class theme
{
@ -33,6 +35,12 @@ class theme
SDL_Rect& location(const SDL_Rect& screen) const;
const SDL_Rect& get_location(void) const;
const std::string& get_id() const;
//this supports relocating of theme elements ingame.
//It is needed for [change] tags in theme WML.
void modify_location(const _rect rect);
void modify_location(std::string rect_str, SDL_Rect rect_ref);
//all on-screen objects have 'anchoring' in the x and y dimensions
//'fixed' means that they have fixed co-ordinates and don't move
@ -51,12 +59,14 @@ class theme
ANCHORING xanchor_, yanchor_;
std::string id_;
static ANCHORING read_anchor(const std::string& str);
};
public:
class label : private object
class label : public object
{
public:
label();
@ -79,7 +89,7 @@ public:
Uint32 font_rgb_;
};
class status_item : private object
class status_item : public object
{
public:
@ -105,7 +115,7 @@ public:
Uint32 font_rgb_;
};
class panel : private object
class panel : public object
{
public:
explicit panel(const config& cfg);
@ -118,7 +128,7 @@ public:
std::string image_;
};
class menu : private object
class menu : public object
{
public:
menu();
@ -143,6 +153,7 @@ public:
explicit theme(const config& cfg, const SDL_Rect& screen);
bool set_resolution(const SDL_Rect& screen);
void modify(const config* cfg);
const std::vector<panel>& panels() const;
const std::vector<label>& labels() const;
@ -156,10 +167,15 @@ public:
const SDL_Rect& mini_map_location(const SDL_Rect& screen) const;
const SDL_Rect& unit_image_location(const SDL_Rect& screen) const;
static void set_known_themes(const config* cfg);
static std::vector<std::string> get_known_themes();
static void set_known_themes(const config* cfg);
static std::vector<std::string> get_known_themes();
private:
theme::object& find_element(std::string id);
theme::object& add_object(const config& cfg);
void remove_object(std::string id);
void set_object_location(theme::object& element, std::string rect_str, std::string ref_id);
static std::map<std::string, config> known_themes;
std::string cur_theme;
config cfg_;

View file

@ -80,7 +80,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib SDL.lib SDLmain.lib SDL_mixer.lib SDL_net.lib SDL_image.lib libintl.lib freetype219ST_D.lib Ws2_32.lib /nologo /subsystem:windows /debug /machine:I386 /out:"wesnoth.exe" /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib SDL.lib SDLmain.lib SDL_mixer.lib SDL_net.lib SDL_image.lib libintl.lib freetype.lib Ws2_32.lib /nologo /subsystem:windows /debug /machine:I386 /out:"wesnoth.exe" /pdbtype:sept
!ENDIF