00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef DISPLAY_H_INCLUDED
00019 #define DISPLAY_H_INCLUDED
00020
00021 class config;
00022 class gamestatus;
00023 class team;
00024 class unit;
00025 class unit_map;
00026
00027 #include "builder.hpp"
00028 #include "generic_event.hpp"
00029 #include "image.hpp"
00030 #include "key.hpp"
00031 #include "map.hpp"
00032 #include "map_label.hpp"
00033 #include "reports.hpp"
00034 #include "theme.hpp"
00035 #include "video.hpp"
00036 #include "widgets/button.hpp"
00037
00038 #include "SDL.h"
00039
00040 #include <map>
00041 #include <set>
00042 #include <string>
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 class display
00059 {
00060 public:
00061 display(CVideo& video, const gamemap& map, const config& theme_cfg,
00062 const config& cfg, const config& level);
00063 virtual ~display();
00064
00065 static Uint32 rgb(Uint8 red, Uint8 green, Uint8 blue)
00066 { return 0xFF000000 | (red << 16) | (green << 8) | blue; }
00067
00068
00069 CVideo& video() { return screen_; }
00070
00071
00072 surface get_screen_surface() { return map_screenshot_ ? map_screenshot_surf_ : screen_.getSurface();}
00073
00074 virtual bool in_game() const { return false; }
00075 virtual bool in_editor() const { return false; }
00076
00077
00078
00079
00080 int w() const { return screen_.getx(); }
00081 int h() const { return screen_.gety(); }
00082 const SDL_Rect& minimap_area() const
00083 { return theme_.mini_map_location(screen_area()); }
00084 const SDL_Rect& unit_image_area() const
00085 { return theme_.unit_image_location(screen_area()); }
00086
00087 SDL_Rect screen_area() const
00088 { const SDL_Rect res = {0,0,w(),h()}; return res; }
00089
00090
00091
00092
00093
00094 const SDL_Rect& max_map_area() const;
00095
00096
00097
00098
00099 const SDL_Rect& map_area() const;
00100
00101
00102
00103
00104
00105
00106 const SDL_Rect& map_outside_area() const { return map_screenshot_ ?
00107 max_map_area() : theme_.main_map_location(screen_area()); }
00108
00109
00110 bool outside_area(const SDL_Rect& area, const int x,const int y) const;
00111
00112
00113
00114
00115
00116 int hex_width() const { return (zoom_*3)/4; }
00117
00118
00119
00120 int hex_size() const { return zoom_; }
00121
00122
00123 double get_zoom_factor() { return double(zoom_)/double(image::tile_size); }
00124
00125
00126
00127
00128 const gamemap::location hex_clicked_on(int x, int y,
00129 gamemap::location::DIRECTION* nearest_hex=NULL,
00130 gamemap::location::DIRECTION* second_nearest_hex=NULL) const;
00131
00132
00133
00134
00135 const gamemap::location pixel_position_to_hex(int x, int y,
00136 gamemap::location::DIRECTION* nearest_hex=NULL,
00137 gamemap::location::DIRECTION* second_nearest_hex=NULL) const;
00138
00139
00140
00141
00142 gamemap::location minimap_location_on(int x, int y);
00143
00144 const gamemap::location& selected_hex() { return selectedHex_; }
00145 const gamemap::location& mouseover_hex() { return mouseoverHex_; }
00146
00147 virtual void select_hex(gamemap::location hex);
00148 virtual void highlight_hex(gamemap::location hex);
00149
00150
00151 void invalidate_game_status() { invalidateGameStatus_ = true; }
00152
00153 void get_rect_hex_bounds(SDL_Rect rect, gamemap::location &topleft, gamemap::location &bottomright) const;
00154
00155
00156 int get_location_x(const gamemap::location& loc) const;
00157 int get_location_y(const gamemap::location& loc) const;
00158
00159
00160 bool shrouded(const gamemap::location& loc) const
00161 {return viewpoint_ && viewpoint_->shrouded(loc);}
00162
00163 bool fogged(const gamemap::location& loc) const
00164 {return viewpoint_ && viewpoint_->fogged(loc);}
00165
00166
00167
00168 void set_grid(const bool grid) { grid_ = grid; }
00169
00170
00171
00172 void get_visible_hex_bounds(gamemap::location &topleft, gamemap::location &bottomright) const;
00173
00174
00175 int screenshot(std::string filename, bool map_screenshot = false);
00176
00177
00178 void redraw_everything();
00179
00180 theme& get_theme() { return theme_; }
00181 gui::button* find_button(const std::string& id);
00182 gui::button::TYPE string_to_button_type(std::string type);
00183 void create_buttons();
00184 void invalidate_theme() { panelsDrawn_ = false; }
00185
00186 void refresh_report(reports::TYPE report_num, reports::report report,
00187 bool brightened = false);
00188
00189
00190 virtual void invalidate(const gamemap::location& loc) {invalidated_.insert(loc);};
00191 virtual void invalidate_rectangle(const gamemap::location& first_corner, const gamemap::location& second_corner) ;
00192 virtual void invalidate_zone(const int x1,const int y1, const int x2, const int y2);
00193 virtual void draw_minimap_units() {};
00194
00195 const gamemap& get_map()const { return map_;}
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205 void set_hex_overlay(const gamemap::location& loc, surface image) { hex_overlay_[loc] = image; }
00206 void clear_hex_overlay(const gamemap::location& loc);
00207
00208 void set_selected_hex_overlay(const surface& image) { selected_hex_overlay_ = image; }
00209 void clear_selected_hex_overlay() { selected_hex_overlay_ = NULL; }
00210
00211 void set_mouseover_hex_overlay(const surface& image) { mouseover_hex_overlay_ = image; }
00212 void clear_mouseover_hex_overlay() { mouseover_hex_overlay_ = NULL; }
00213
00214
00215
00216
00217
00218
00219 void sunset(const size_t delay = 0);
00220
00221
00222 void toggle_benchmark();
00223
00224 void flip();
00225
00226
00227 void update_display();
00228
00229
00230 void rebuild_all() { builder_.rebuild_all(); }
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241 void render_unit_image(int x, int y, const bool fake_unit,
00242 const int drawing_order, surface image,
00243 bool hreverse=false, bool greyscale=false,
00244 fixed_t alpha=ftofxp(1.0), Uint32 blendto=0,
00245 double blend_ratio=0, double submerged=0.0,bool vreverse =false);
00246
00247 const theme::menu* menu_pressed();
00248
00249
00250
00251 void enable_menu(const std::string& item, bool enable);
00252
00253 void set_diagnostic(const std::string& msg);
00254
00255
00256 void delay(unsigned int milliseconds) const;
00257
00258
00259
00260 void set_turbo(const bool turbo) { turbo_ = turbo; }
00261
00262 double turbo_speed() const;
00263
00264 void set_turbo_speed(const double speed) { turbo_speed_ = speed; }
00265
00266
00267 void set_idle_anim(bool ison) { idle_anim_ = ison; }
00268 bool idle_anim() const { return idle_anim_; }
00269 void set_idle_anim_rate(int rate);
00270 double idle_anim_rate() const { return idle_anim_rate_; }
00271
00272
00273
00274
00275
00276 void add_highlighted_loc(const gamemap::location &hex);
00277
00278 void clear_highlighted_locs();
00279
00280 void remove_highlighted_loc(const gamemap::location &hex);
00281
00282 void bounds_check_position();
00283 void bounds_check_position(int& xpos, int& ypos);
00284
00285
00286 void invalidate_all();
00287
00288
00289
00290 void scroll(int xmov, int ymov);
00291
00292
00293
00294
00295
00296
00297 void set_zoom(int amount);
00298
00299
00300 void set_default_zoom();
00301
00302 enum SCROLL_TYPE { SCROLL, WARP, ONSCREEN };
00303
00304
00305
00306
00307 void scroll_to_tile(const gamemap::location& loc, SCROLL_TYPE scroll_type=ONSCREEN, bool check_fogged=true);
00308
00309
00310
00311
00312
00313 void scroll_to_tiles(gamemap::location loc1, gamemap::location loc2,
00314 SCROLL_TYPE scroll_type=ONSCREEN, bool check_fogged=true,
00315 double add_spacing=0.0);
00316
00317
00318 void scroll_to_tiles(const std::vector<gamemap::location>& locs,
00319 SCROLL_TYPE scroll_type=ONSCREEN, bool check_fogged=true,
00320 bool only_if_possible=false,
00321 double add_spacing=0.0);
00322
00323
00324 events::generic_event &scroll_event() const { return _scroll_event; }
00325
00326
00327 bool tile_on_screen(const gamemap::location& loc);
00328
00329
00330
00331
00332 virtual void draw(bool update=true,bool force=false) = 0;
00333
00334 map_labels& labels() { return map_labels_; }
00335 const map_labels& labels() const { return map_labels_; }
00336
00337
00338 void announce(const std::string msg,
00339 const SDL_Color& colour = font::GOOD_COLOUR);
00340
00341
00342
00343 void recalculate_minimap() {minimap_ = NULL; redrawMinimap_ = true; };
00344
00345
00346
00347 void redraw_minimap() { redrawMinimap_ = true; }
00348
00349
00350
00351
00352
00353
00354 void set_report_content(const reports::TYPE which_report, const std::string &content);
00355 std::map<reports::TYPE, std::string> get_report_contents() {return report_;};
00356
00357 protected:
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369 virtual void draw_border(const gamemap::location& loc,
00370 const int xpos, const int ypos);
00371
00372 void draw_minimap();
00373
00374 enum ADJACENT_TERRAIN_TYPE { ADJACENT_BACKGROUND, ADJACENT_FOREGROUND, ADJACENT_FOGSHROUD };
00375
00376 std::vector<surface> get_terrain_images(const gamemap::location &loc,
00377 const std::string timeid,
00378 image::TYPE type,
00379 ADJACENT_TERRAIN_TYPE terrain_type);
00380
00381 std::vector<std::string> get_fog_shroud_graphics(const gamemap::location& loc);
00382
00383 void draw_image_for_report(surface& img, SDL_Rect& rect);
00384
00385 void scroll_to_xy(int screenxpos, int screenypos, SCROLL_TYPE scroll_type);
00386
00387 CVideo& screen_;
00388 const gamemap& map_;
00389 const viewpoint *viewpoint_;
00390 int xpos_, ypos_;
00391 theme theme_;
00392 int zoom_;
00393 int last_zoom_;
00394 terrain_builder builder_;
00395 surface minimap_;
00396 SDL_Rect minimap_location_;
00397 bool redrawMinimap_;
00398 bool redraw_background_;
00399 bool invalidateAll_;
00400 bool grid_;
00401 int diagnostic_label_;
00402 bool panelsDrawn_;
00403 double turbo_speed_;
00404 bool turbo_;
00405 bool invalidateGameStatus_;
00406 map_labels map_labels_;
00407
00408 mutable events::generic_event _scroll_event;
00409
00410
00411 int nextDraw_;
00412
00413
00414 SDL_Rect reportRects_[reports::NUM_REPORTS];
00415 surface reportSurfaces_[reports::NUM_REPORTS];
00416 reports::report reports_[reports::NUM_REPORTS];
00417 std::map<reports::TYPE, std::string> report_;
00418 std::vector<gui::button> buttons_;
00419 std::set<gamemap::location> invalidated_;
00420 std::map<gamemap::location, surface> hex_overlay_;
00421 surface selected_hex_overlay_;
00422 surface mouseover_hex_overlay_;
00423 gamemap::location selectedHex_;
00424 gamemap::location mouseoverHex_;
00425 std::set<gamemap::location> highlighted_locations_;
00426 CKey keys_;
00427
00428 public:
00429
00430 struct tblit{
00431 tblit(const int x, const int y) :
00432 x(x),
00433 y(y),
00434 surf(),
00435 clip()
00436 {}
00437
00438 tblit(const int x, const int y, const surface& surf,
00439 const SDL_Rect& clip = SDL_Rect()) :
00440 x(x),
00441 y(y),
00442 surf(1, surf),
00443 clip(clip)
00444 {}
00445
00446 tblit(const int x, const int y, const std::vector<surface>& surf,
00447 const SDL_Rect& clip = SDL_Rect()) :
00448 x(x),
00449 y(y),
00450 surf(surf),
00451 clip(clip)
00452 {}
00453
00454
00455 int x;
00456 int y;
00457 std::vector<surface> surf;
00458 SDL_Rect clip;
00459
00460 };
00461
00462
00463
00464
00465
00466 enum tdrawing_layer{
00467 LAYER_TERRAIN_BG,
00468
00469 LAYER_TERRAIN_TMP_BG,
00470
00471 LAYER_UNIT_BG,
00472 LAYER_UNIT_FIRST,
00473 LAYER_UNIT_LAST=LAYER_UNIT_FIRST+100,
00474 LAYER_UNIT_FG,
00475
00476 LAYER_UNIT_FAKE,
00477 LAYER_TERRAIN_FG,
00478
00479 LAYER_TERRAIN_TMP_FG,
00480
00481 LAYER_UNIT_BAR,
00482
00483 LAYER_LINGER_OVERLAY,
00484
00485 LAYER_LAST_LAYER
00486
00487 };
00488
00489
00490
00491
00492 void draw_text_in_hex(const gamemap::location& loc,
00493 const tdrawing_layer layer, const std::string& text, size_t font_size,
00494 SDL_Color color, double x_in_hex=0.5, double y_in_hex=0.5);
00495
00496 protected:
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519 #if TDRAWING_BUFFER_USES_VECTOR
00520 typedef std::vector<std::map<int , std::vector<tblit> > > tdrawing_buffer;
00521 #else
00522 typedef std::map<tdrawing_layer, std::map<int , std::vector<tblit> > > tdrawing_buffer;
00523 #endif
00524 tdrawing_buffer drawing_buffer_;
00525
00526 public:
00527
00528
00529
00530
00531
00532
00533 void drawing_buffer_add(const tdrawing_layer layer, const int drawing_order, const tblit& blit)
00534 { drawing_buffer_[layer][drawing_order].push_back(blit); }
00535
00536 protected:
00537
00538
00539 void drawing_buffer_commit();
00540
00541
00542 void drawing_buffer_clear();
00543
00544
00545 void draw_all_panels();
00546
00547 void invalidate_locations_in_rect(SDL_Rect r);
00548
00549
00550
00551
00552 struct ordered_draw : public std::binary_function<gamemap::location, gamemap::location, bool> {
00553 bool operator()(gamemap::location a, gamemap::location b) {
00554 return (a.y*2 + a.x%2) * 1024 + a.x < (b.y*2 + b.x%2) * 1024 + b.x;
00555 }
00556 };
00557
00558
00559
00560
00561 bool draw_init();
00562 void draw_wrap(bool update,bool force,bool changed);
00563
00564
00565 bool map_screenshot_;
00566
00567 private:
00568
00569 int fps_handle_;
00570
00571 bool idle_anim_;
00572 double idle_anim_rate_;
00573
00574 surface map_screenshot_surf_;
00575 };
00576
00577
00578
00579 class editor_display : public display
00580 {
00581 public:
00582 editor_display(CVideo& video, const gamemap& map, const config& theme_cfg,
00583 const config& cfg, const config& level);
00584
00585 bool in_editor() const { return true; }
00586
00587
00588
00589 void draw(bool update=true,bool force=false);
00590
00591
00592 void rebuild_terrain(const gamemap::location &loc)
00593 { builder_.rebuild_terrain(loc); }
00594
00595
00596 void update_light_levels();
00597 private:
00598 int lr_, lg_, lb_;
00599 };
00600
00601 #endif
00602