00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "about.hpp"
00022
00023 #include "construct_dialog.hpp"
00024 #include "display.hpp"
00025 #include "foreach.hpp"
00026 #include "gettext.hpp"
00027 #include "marked-up_text.hpp"
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 namespace about
00038 {
00039 static config about_list = config();
00040 static std::map<std::string , std::string> images;
00041 static std::string images_default;
00042
00043
00044
00045
00046
00047 static void add_lines(std::vector<std::string> &res, config const &c) {
00048 std::string title = c["title"];
00049 if (!title.empty()) {
00050 title = "+" + title;
00051 res.push_back(title);
00052 }
00053
00054 std::vector<std::string> lines = utils::split(c["text"], '\n');
00055 foreach (std::string &line, lines)
00056 {
00057 if (line.size() > 1 && line[0] == '+')
00058 line = "+ " + line.substr(1);
00059 else
00060 line = "- " + line;
00061
00062 if (!line.empty())
00063 {
00064 if (line[0] == '_')
00065 line = gettext(line.substr(1).c_str());
00066 res.push_back(line);
00067 }
00068 }
00069
00070 foreach (const config &entry, c.child_range("entry")) {
00071 res.push_back("- "+ entry["name"].str());
00072 }
00073 }
00074
00075
00076 std::vector<std::string> get_text(const std::string &campaign)
00077 {
00078 std::vector< std::string > res;
00079
00080 config::child_itors about_entries = about_list.child_range("about");
00081
00082 if (!campaign.empty()) {
00083 foreach (const config &about, about_entries) {
00084
00085 if (campaign == about["id"]) {
00086 add_lines(res, about);
00087 }
00088 }
00089 }
00090
00091 foreach (const config &about, about_entries) {
00092 add_lines(res, about);
00093 }
00094
00095 return res;
00096 }
00097
00098 void set_about(const config &cfg)
00099 {
00100 about_list.clear();
00101 images.clear();
00102 images_default = "";
00103
00104 foreach (const config &about, cfg.child_range("about"))
00105 {
00106 about_list.add_child("about", about);
00107 const std::string &im = about["images"];
00108 if (!images.empty())
00109 {
00110 if (images_default.empty())
00111 images_default = im;
00112 else
00113 images_default += ',' + im;
00114 }
00115 }
00116
00117 foreach (const config &campaign, cfg.child_range("campaign"))
00118 {
00119 config::const_child_itors abouts = campaign.child_range("about");
00120 if (abouts.first == abouts.second) continue;
00121
00122 config temp;
00123 std::ostringstream text;
00124 const std::string &id = campaign["id"];
00125 temp["title"] = campaign["name"];
00126 temp["id"] = id;
00127 std::string campaign_images;
00128
00129 foreach (const config &about, abouts)
00130 {
00131 const std::string &subtitle = about["title"];
00132 if (!subtitle.empty())
00133 {
00134 text << '+';
00135 if (subtitle[0] == '_')
00136 text << gettext(subtitle.substr(1, subtitle.size() - 1).c_str());
00137 else
00138 text << subtitle;
00139 text << '\n';
00140 }
00141
00142 foreach (const std::string &line, utils::split(about["text"], '\n'))
00143 {
00144 text << " " << line << '\n';
00145 }
00146
00147 foreach (const config &entry, about.child_range("entry"))
00148 {
00149 text << " " << entry["name"] << '\n';
00150 }
00151
00152 const std::string &im = about["images"];
00153 if (!im.empty())
00154 {
00155 if (campaign_images.empty())
00156 campaign_images = im;
00157 else
00158 campaign_images += ',' + im;
00159 }
00160 }
00161
00162 images[id] = campaign_images;
00163 temp["text"] = text.str();
00164 about_list.add_child("about",temp);
00165 }
00166 }
00167
00168
00169
00170
00171
00172
00173
00174 void show_about(display &disp, const std::string &campaign)
00175 {
00176 cursor::set(cursor::WAIT);
00177 CVideo &video = disp.video();
00178 surface screen = video.getSurface();
00179 if (screen == NULL) return;
00180
00181 std::vector<std::string> text = about::get_text(campaign);
00182 SDL_Rect screen_rect = create_rect(0, 0, screen->w, screen->h);
00183
00184 const surface_restorer restorer(&video, screen_rect);
00185
00186 cursor::set(cursor::NORMAL);
00187
00188 std::vector<std::string> image_list;
00189 if(campaign.size() && !images[campaign].empty()){
00190 image_list = utils::parenthetical_split(images[campaign], ',');
00191 } else{
00192 image_list = utils::parenthetical_split(images_default, ',');
00193 }
00194
00195 surface map_image;
00196
00197 if(!image_list.empty()) {
00198 map_image = scale_surface(image::get_image(image_list[0]), screen->w, screen->h);
00199 } else {
00200 image_list.push_back("");
00201 }
00202
00203 if(!map_image){
00204 image_list[0]=game_config::images::game_title;
00205 map_image=surface(scale_surface(image::get_image(image_list[0]), screen->w, screen->h));
00206 }
00207
00208 gui::button close(video,_("Close"));
00209 close.set_location((screen->w/2)-(close.width()/2), screen->h - 30);
00210 close.set_volatile(true);
00211
00212 const int def_size = font::SIZE_XLARGE;
00213 const SDL_Color def_color = font::NORMAL_COLOR;
00214
00215
00216 std::string before_header(2, ' ');
00217 before_header[0] = font::LARGE_TEXT;
00218 for(unsigned i = 0; i < text.size(); ++i) {
00219 std::string &s = text[i];
00220 if (s.empty()) continue;
00221 char &first = s[0];
00222 if (first == '-')
00223 first = font::SMALL_TEXT;
00224 else if (first == '+') {
00225 first = font::LARGE_TEXT;
00226 text.insert(text.begin() + i, before_header);
00227 ++i;
00228 }
00229 }
00230 text.insert(text.begin(), 10, before_header);
00231
00232 int startline = 0;
00233
00234
00235
00236 const int top_margin = 60;
00237
00238 const int bottom_margin = 40;
00239
00240 const int text_left_padding = screen->w/32;
00241
00242 int offset = 0;
00243 bool is_new_line = true;
00244
00245 int first_line_height = 0;
00246
00247 SDL_Rect frame_area = create_rect(
00248 screen->w * 3 / 32
00249 , top_margin
00250 , screen->w * 13 / 16
00251 , screen->h - top_margin - bottom_margin);
00252
00253
00254
00255 gui::dialog_frame f(video, "", gui::dialog_frame::titlescreen_style, false);
00256
00257
00258 SDL_Rect text_rect = f.layout(frame_area).interior;
00259 text_rect.x += text_left_padding;
00260 text_rect.w -= text_left_padding;
00261
00262 SDL_Rect text_rect_blit = text_rect;
00263
00264 CKey key;
00265 bool last_escape;
00266
00267 surface text_surf = create_compatible_surface(screen, text_rect.w, text_rect.h);
00268 SDL_SetAlpha(text_surf, SDL_RLEACCEL, SDL_ALPHA_OPAQUE);
00269
00270 int image_count = 0;
00271 int scroll_speed = 4;
00272
00273
00274 bool redraw_mapimage = true;
00275 int max_text_width = text_rect.w;
00276
00277 do {
00278 last_escape = key[SDLK_ESCAPE] != 0;
00279
00280
00281 if(text.size() && (image_count <
00282 ((startline * static_cast<int>(image_list.size())) /
00283 static_cast<int>(text.size())))){
00284
00285 image_count++;
00286 surface temp=surface(scale_surface(image::get_image(image_list[image_count]), screen->w, screen->h));
00287 map_image=temp?temp:map_image;
00288 redraw_mapimage = true;
00289 }
00290
00291 if (redraw_mapimage) {
00292
00293 sdl_blit(map_image, NULL, screen, NULL);
00294 update_rect(screen_rect);
00295
00296
00297 f.draw_background();
00298 f.draw_border();
00299
00300 sdl_blit(screen, &text_rect, text_surf, NULL);
00301 redraw_mapimage = false;
00302 } else {
00303
00304
00305 SDL_Rect modified = create_rect(0, 0, max_text_width, text_rect.h);
00306 sdl_blit(text_surf, &modified, screen, &text_rect_blit);
00307 update_rect(text_rect);
00308 }
00309
00310 const int line_spacing = 5;
00311
00312 int y = text_rect.y - offset;
00313 int line = startline;
00314 max_text_width = 0;
00315
00316 {
00317
00318 clip_rect_setter set_clip_rect(screen, &text_rect);
00319 do {
00320
00321
00322 int w = font::draw_text(&video, text_rect, def_size, def_color,
00323 text[line], text_rect.x, y).w;
00324 max_text_width = std::max<int>(max_text_width, w);
00325
00326
00327
00328 const int line_height = font::draw_text(NULL, text_rect, def_size, def_color,
00329 text[line], 0,0).h;
00330
00331 if(is_new_line) {
00332 is_new_line = false;
00333 first_line_height = line_height + line_spacing;
00334 }
00335 line++;
00336 if(size_t(line) > text.size()-1)
00337 line = 0;
00338 y += line_height + line_spacing;
00339 } while(y < text_rect.y + text_rect.h);
00340 }
00341
00342
00343 offset += scroll_speed;
00344 if (offset>=first_line_height) {
00345 offset -= first_line_height;
00346 is_new_line = true;
00347 startline++;
00348 if(size_t(startline) == text.size()){
00349 startline = 0;
00350 image_count = -1;
00351 }
00352 }
00353
00354
00355 if (key[SDLK_UP] && scroll_speed < 20) {
00356 ++scroll_speed;
00357 }
00358 if (key[SDLK_DOWN] && scroll_speed > 0) {
00359 --scroll_speed;
00360 }
00361
00362 events::pump();
00363 events::raise_process_event();
00364 events::raise_draw_event();
00365
00366
00367 disp.flip();
00368 disp.delay(20);
00369
00370 } while(!close.pressed() && (last_escape || !key[SDLK_ESCAPE]));
00371 }
00372
00373 }