00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "about.hpp"
00019 #include "config.hpp"
00020 #include "construct_dialog.hpp"
00021 #include "display.hpp"
00022 #include "font.hpp"
00023 #include "game_config.hpp"
00024 #include "gettext.hpp"
00025 #include "marked-up_text.hpp"
00026 #include "video.hpp"
00027 #include "show_dialog.hpp"
00028
00029
00030
00031
00032
00033
00034
00035 namespace about
00036 {
00037
00038 static config about_list = config();
00039 static std::map<std::string , std::string> images;
00040 static std::string images_default;
00041
00042
00043
00044 static void add_lines(std::vector<std::string> &res, config const &c) {
00045 std::string title=c["title"];
00046 if(title.size()) {
00047 title = N_("+" + title);
00048 res.push_back(title);
00049 }
00050
00051 std::vector<std::string> lines = utils::split(c["text"], '\n');
00052 for(std::vector<std::string>::iterator line = lines.begin();
00053 line != lines.end(); line++) {
00054 if((*line)[0] == '+' && (*line).size()>1){
00055 *line = N_("+ " + (*line).substr(1,(*line).size()-1));
00056 } else {
00057 *line = "- " + *line;
00058 }
00059 if(line->size()) {
00060 if ((*line)[0] == '_')
00061 *line = gettext(line->substr(1,line->size()-1).c_str());
00062 res.push_back(*line);
00063 }
00064 }
00065
00066 config::child_list entries = c.get_children("entry");
00067 config::child_list::const_iterator entry;
00068 for(entry = entries.begin(); entry != entries.end(); entry++) {
00069 res.push_back("- "+(**entry)["name"]);
00070 }
00071 }
00072
00073
00074 std::vector<std::string> get_text(std::string campaign) {
00075 std::vector< std::string > res;
00076
00077 const config::child_list& children = about::about_list.get_children("about");
00078
00079 for(config::child_list::const_iterator cc = children.begin(); cc != children.end(); ++cc) {
00080
00081 if(campaign.size() && campaign == (**cc)["id"]){
00082 add_lines(res, **cc);
00083 }
00084 }
00085
00086 for(config::child_list::const_iterator acc = children.begin(); acc != children.end(); ++acc) {
00087 add_lines(res, **acc);
00088 }
00089
00090 return res;
00091 }
00092
00093 void set_about(const config& cfg){
00094 config::child_list about = cfg.get_children("about");
00095 for(config::child_list::const_iterator A = about.begin(); A != about.end(); A++) {
00096 config AA = (**A);
00097 about_list.add_child("about",AA);
00098 if(!AA["images"].empty()){
00099 if(images_default.empty()){
00100 images_default=AA["images"];
00101 }else{
00102 images_default+=","+AA["images"];
00103 }
00104 }
00105 }
00106 config::child_list campaigns = cfg.get_children("campaign");
00107 for(config::child_list::const_iterator C = campaigns.begin(); C != campaigns.end(); C++) {
00108 config::child_list about = (**C).get_children("about");
00109 if(about.size()){
00110 config temp;
00111 std::string text;
00112 std::string title;
00113 std::string campaign=(**C)["id"];
00114 title=(**C)["name"];
00115 temp["title"]=title;
00116 temp["id"]=(**C)["id"];
00117 for(config::child_list::const_iterator A = about.begin(); A != about.end(); A++) {
00118 config AA = (**A);
00119 std::string subtitle=AA["title"];
00120 if(subtitle.size()){
00121 if (subtitle[0] == '_')
00122 subtitle = gettext(subtitle.substr(1,subtitle.size()-1).c_str());
00123 text += "+" + subtitle + "\n";
00124 }
00125 std::vector<std::string> lines=utils::split(AA["text"],'\n');
00126 for(std::vector<std::string>::iterator line=lines.begin();
00127 line != lines.end(); line++){
00128 text+=" "+(*line)+"\n";
00129 }
00130
00131 config::child_list entries = AA.get_children("entry");
00132 config::child_list::const_iterator entry;
00133 for(entry = entries.begin(); entry != entries.end(); entry++) {
00134 text+=" "+(**entry)["name"]+"\n";
00135 }
00136
00137 if(!AA["images"].empty()){
00138 if(images[campaign].empty()){
00139 images[campaign]=AA["images"];
00140 }else{
00141 images[campaign]+=","+AA["images"];
00142 }
00143 }
00144 }
00145 temp["text"]=text;
00146 about_list.add_child("about",temp);
00147 }
00148 }
00149 }
00150
00151
00152
00153
00154 void show_about(display &disp, std::string campaign)
00155 {
00156 cursor::set(cursor::WAIT);
00157 CVideo &video = disp.video();
00158 std::vector<std::string> text = about::get_text(campaign);
00159 SDL_Rect rect = {0, 0, video.getx(), video.gety()};
00160
00161 const surface_restorer restorer(&video, rect);
00162
00163
00164 draw_solid_tinted_rectangle(0,0,video.getx()-1,video.gety()-1,
00165 0,0,0,1.0,video.getSurface());
00166 update_whole_screen();
00167 cursor::set(cursor::NORMAL);
00168
00169 std::vector<std::string> image_list;
00170 if(campaign.size() && !images[campaign].empty()){
00171 image_list=utils::split(images[campaign]);
00172 }else{
00173 image_list=utils::split(images_default,',',utils::STRIP_SPACES);
00174 }
00175 surface map_image(scale_surface(image::get_image(image_list[0]), disp.w(), disp.h()));
00176 if(! map_image){
00177 image_list[0]=game_config::game_title;
00178 map_image=surface(scale_surface(image::get_image(image_list[0]), disp.w(), disp.h()));
00179 }
00180
00181 SDL_Rect map_rect;
00182 map_rect.x = video.getx()/2 - map_image->w/2;
00183 map_rect.y = video.gety()/2 - map_image->h/2;
00184 map_rect.w = map_image->w;
00185 map_rect.h = map_image->h;
00186
00187 gui::button close(video,_("Close"));
00188 close.set_location((video.getx()/2)-(close.width()/2), video.gety() - 30);
00189 close.set_volatile(true);
00190
00191
00192 std::string before_header(2, ' ');
00193 before_header[0] = font::LARGE_TEXT;
00194 for(unsigned i = 0; i < text.size(); ++i) {
00195 std::string &s = text[i];
00196 if (s.empty()) continue;
00197 char &first = s[0];
00198 if (first == '-')
00199 first = font::SMALL_TEXT;
00200 else if (first == '+') {
00201 first = font::LARGE_TEXT;
00202 text.insert(text.begin() + i, before_header);
00203 ++i;
00204 }
00205 }
00206 text.insert(text.begin(), 10, before_header);
00207
00208 int startline = 0;
00209
00210
00211 const int top_margin = 60;
00212 const int bottom_margin = 40;
00213
00214 int offset = 0;
00215 bool is_new_line = true;
00216
00217 int first_line_height = 0;
00218
00219
00220
00221 SDL_Rect upper_src = {0, 0, map_rect.w, top_margin};
00222 SDL_Rect upper_dest = {map_rect.x, map_rect.y, map_rect.w, top_margin};
00223 SDL_Rect middle_src = {0, top_margin, map_rect.w, map_rect.h - top_margin - bottom_margin};
00224 SDL_Rect middle_dest = {map_rect.x, map_rect.y + top_margin, map_rect.w, map_rect.h - top_margin - bottom_margin};
00225 SDL_Rect lower_src = {0, map_rect.h - bottom_margin, map_rect.w, bottom_margin};
00226 SDL_Rect lower_dest = {map_rect.x, map_rect.y + map_rect.h - bottom_margin, map_rect.w, bottom_margin};
00227
00228 CKey key;
00229 bool last_escape;
00230 int image_count=0;
00231 do {
00232 last_escape = key[SDLK_ESCAPE] != 0;
00233
00234
00235 if(text.size() && (image_count <
00236 ((startline * static_cast<int>(image_list.size())) /
00237 static_cast<int>(text.size())))){
00238
00239 image_count++;
00240 surface temp=surface(scale_surface(image::get_image(image_list[image_count]), disp.w(), disp.h()));
00241 map_image=temp?temp:map_image;
00242 }
00243
00244
00245 SDL_BlitSurface(map_image,&middle_src,video.getSurface(),&middle_dest);
00246 SDL_Rect frame_area = {
00247 map_rect.x + map_rect.w * 3/32,
00248 map_rect.y + top_margin,
00249 map_rect.w * 13 / 16,
00250 map_rect.h - top_margin - bottom_margin
00251 };
00252 gui::dialog_frame f(disp.video(), "", gui::dialog_frame::titlescreen_style, false);
00253 f.layout(frame_area);
00254 f.draw_background();
00255
00256
00257 const int line_spacing = 5;
00258 int y = map_rect.y + top_margin - offset;
00259 int line = startline;
00260 int cur_line = 0;
00261
00262 do {
00263
00264
00265 SDL_Rect tr = font::draw_text(&video,screen_area(),font::SIZE_XLARGE,font::NORMAL_COLOUR,
00266 text[line], map_rect.x + map_rect.w / 8,y);
00267
00268 if(is_new_line) {
00269 is_new_line = false;
00270 first_line_height = tr.h + line_spacing;
00271 }
00272 line++;
00273 if(size_t(line) > text.size()-1)
00274 line = 0;
00275 y += tr.h + line_spacing;
00276 cur_line++;
00277 } while(y<map_rect.y + map_rect.h - bottom_margin);
00278
00279
00280 const int scroll_speed = 4;
00281
00282 offset += scroll_speed;
00283 if(offset>=first_line_height) {
00284 offset -= first_line_height;
00285 is_new_line = true;
00286 startline++;
00287 if(size_t(startline) == text.size()){
00288 startline = 0;
00289 image_count = -1;
00290 }
00291 }
00292
00293
00294
00295
00296 SDL_BlitSurface(map_image,&upper_src,video.getSurface(),&upper_dest);
00297 SDL_BlitSurface(map_image,&lower_src,video.getSurface(),&lower_dest);
00298
00299
00300 events::pump();
00301 events::raise_process_event();
00302 events::raise_draw_event();
00303
00304
00305 update_rect(map_rect);
00306 close.set_dirty(true);
00307 disp.flip();
00308 disp.delay(20);
00309
00310 } while(!close.pressed() && (last_escape || !key[SDLK_ESCAPE]));
00311
00312 }
00313
00314 }