Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "global.hpp"
00023 #include "storyscreen/controller.hpp"
00024 #include "storyscreen/part.hpp"
00025 #include "storyscreen/render.hpp"
00026
00027 #include "asserts.hpp"
00028 #include "foreach.hpp"
00029 #include "variable.hpp"
00030
00031 #include "display.hpp"
00032 #include "game_events.hpp"
00033 #include "gamestatus.hpp"
00034 #include "gettext.hpp"
00035 #include "intro.hpp"
00036 #include "log.hpp"
00037 #include "resources.hpp"
00038 #include "widgets/button.hpp"
00039
00040 static lg::log_domain log_engine("engine");
00041 #define ERR_NG LOG_STREAM(err, log_engine)
00042 #define LOG_NG LOG_STREAM(info, log_engine)
00043
00044 namespace storyscreen {
00045
00046 controller::controller(display& disp, const vconfig& data, const std::string& scenario_name,
00047 int segment_index, int total_segments)
00048 : disp_(disp)
00049 , disp_resize_lock_()
00050 , evt_context_()
00051 , scenario_name_(scenario_name)
00052 , segment_index_(segment_index)
00053 , total_segments_(total_segments)
00054 , parts_()
00055 {
00056 ASSERT_LOG(resources::state_of_game != NULL, "Ouch: gamestate is NULL when initializing storyscreen controller");
00057 resolve_wml(data);
00058 }
00059
00060 void controller::resolve_wml(const vconfig& cfg)
00061 {
00062 for(vconfig::all_children_iterator i = cfg.ordered_begin(); i != cfg.ordered_end(); ++i)
00063 {
00064
00065 const std::string key = i->first;
00066 const vconfig node = i->second;
00067
00068 if(key == "part" && !node.empty()) {
00069 part_pointer_type const story_part(new part(node));
00070
00071 if((*story_part).show_title() && (*story_part).title().empty()) {
00072 (*story_part).set_title( scenario_name_ );
00073 }
00074 parts_.push_back(story_part);
00075 }
00076
00077 else if(key == "if") {
00078 const std::string branch_label =
00079 game_events::conditional_passed(node) ?
00080 "then" : "else";
00081 if(node.has_child(branch_label)) {
00082 const vconfig branch = node.child(branch_label);
00083 resolve_wml(branch);
00084 }
00085 }
00086
00087 else if(key == "switch") {
00088 const std::string var_name = node["variable"];
00089 const std::string var_actual_value = resources::state_of_game->get_variable_const(var_name);
00090 bool case_not_found = true;
00091
00092 for(vconfig::all_children_iterator j = node.ordered_begin(); j != node.ordered_end(); ++j) {
00093 if(j->first != "case") continue;
00094
00095
00096 const std::string var_expected_value = (j->second)["value"];
00097 if(var_actual_value == var_expected_value) {
00098 case_not_found = false;
00099 resolve_wml(j->second);
00100 }
00101 }
00102
00103 if(case_not_found) {
00104 for(vconfig::all_children_iterator j = node.ordered_begin(); j != node.ordered_end(); ++j) {
00105 if(j->first != "else") continue;
00106
00107
00108 resolve_wml(j->second);
00109 }
00110 }
00111 }
00112
00113 else if(key == "deprecated_message") {
00114
00115 game_events::handle_deprecated_message(node.get_parsed_config());
00116 }
00117
00118 else if(key == "wml_message") {
00119
00120
00121 game_events::handle_wml_log_message(node.get_parsed_config());
00122 }
00123 }
00124 }
00125
00126 STORY_RESULT controller::show(START_POSITION startpos)
00127 {
00128 if(parts_.empty()) {
00129 LOG_NG << "no storyscreen parts to show\n";
00130 return NEXT;
00131 }
00132
00133 gui::button back_button (disp_.video(), "", gui::button::TYPE_PRESS, "big-arrow-button-left");
00134 gui::button next_button (disp_.video(), "", gui::button::TYPE_PRESS, "big-arrow-button-right");
00135 gui::button play_button (disp_.video(), _("Skip"));
00136
00137
00138
00139 #ifndef LOW_MEM
00140 std::vector< render_pointer_type > uis_;
00141 foreach(part_pointer_type p, parts_) {
00142 ASSERT_LOG( p != NULL, "Ouch: hit NULL storyscreen part in collection" );
00143 render_pointer_type const rpt(new part_ui(*p, disp_, next_button, back_button, play_button));
00144 uis_.push_back(rpt);
00145 }
00146 #endif
00147
00148 size_t k = 0;
00149 switch(startpos) {
00150 case START_BEGINNING:
00151 break;
00152 case START_END:
00153 k = parts_.size() -1;
00154 break;
00155 default:
00156 assert(false);
00157 break;
00158 }
00159
00160 while(k < parts_.size()) {
00161 #ifndef LOW_MEM
00162 part_ui &render_interface = *uis_[k];
00163 #else
00164 part_ui render_interface(*parts_[k], disp_, next_button, back_button, play_button);
00165 #endif
00166
00167 LOG_NG << "displaying storyscreen part " << k+1 << " of " << parts_.size() << '\n';
00168
00169 back_button.enable(segment_index_ != 0 || k != 0);
00170
00171 switch(render_interface.show()) {
00172 case part_ui::NEXT:
00173 ++k;
00174 break;
00175 case part_ui::BACK:
00176 if(k > 0) {
00177 --k;
00178 }
00179 else if(segment_index_ > 0) {
00180 return BACK;
00181 }
00182 break;
00183 case part_ui::QUIT:
00184 return QUIT;
00185 }
00186 }
00187 return NEXT;
00188 }
00189
00190 }