Stop sharing requirement_unit_state_ereq().
[freeciv.git] / client / mapview_common.h
blobbfd98e1f8828aba3756eaca03207d0363859687b
1 /**********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12 ***********************************************************************/
14 #ifndef FC__MAPVIEW_COMMON_H
15 #define FC__MAPVIEW_COMMON_H
17 #ifdef __cplusplus
18 extern "C" {
19 #endif /* __cplusplus */
21 /* utility */
22 #include "support.h" /* bool type */
24 /* common */
25 #include "fc_types.h"
26 #include "featured_text.h" /* enum text_link_type type */
27 #include "map.h"
29 /* include */
30 #include "colors_g.h"
32 #include "tilespec.h"
34 struct canvas_store; /* opaque type, real type is gui-dep */
36 struct view {
37 float gui_x0, gui_y0;
38 int width, height; /* Size in pixels. */
39 int tile_width, tile_height; /* Size in tiles. Rounded up. */
40 int store_width, store_height;
41 bool can_do_cached_drawing; /* TRUE if cached drawing is possible. */
42 struct canvas *store, *tmp_store;
45 void mapdeco_init(void);
46 void mapdeco_free(void);
47 void mapdeco_set_highlight(const struct tile *ptile, bool highlight);
48 bool mapdeco_is_highlight_set(const struct tile *ptile);
49 void mapdeco_clear_highlights(void);
50 void mapdeco_set_crosshair(const struct tile *ptile, bool crosshair);
51 bool mapdeco_is_crosshair_set(const struct tile *ptile);
52 void mapdeco_clear_crosshairs(void);
53 void mapdeco_set_gotoroute(const struct unit *punit);
54 void mapdeco_add_gotoline(const struct tile *ptile,
55 enum direction8 dir);
56 void mapdeco_remove_gotoline(const struct tile *ptile,
57 enum direction8 dir);
58 bool mapdeco_is_gotoline_set(const struct tile *ptile,
59 enum direction8 dir);
60 void mapdeco_clear_gotoroutes(void);
63 extern struct view mapview;
65 /* HACK: Callers can set this to FALSE to disable sliding. It should be
66 * reenabled afterwards. */
67 extern bool can_slide;
69 #define BORDER_WIDTH 2
70 #define GOTO_WIDTH 2
73 * Iterate over all map tiles that intersect with the given GUI rectangle.
74 * The order of iteration is guaranteed to satisfy the painter's algorithm.
75 * The iteration covers not only tiles but tile edges and corners.
77 * GRI_x0, GRI_y0: gives the GUI origin of the rectangle.
79 * GRI_width, GRI_height: gives the GUI width and height of the rectangle.
80 * These values may be negative.
82 * _t, _e, _c: the tile, edge, or corner that is being iterated, declared
83 * inside the macro. Usually, only one of them will be non-NULL at a time.
84 * These values may be passed directly to fill_sprite_array().
86 * _x, _y: the canvas position of the current element, declared inside
87 * the macro. Each element is assumed to be tileset_tile_width(tileset) *
88 * tileset_tile_height(tileset) in size. If an element is larger, the
89 * caller needs to use a larger rectangle of iteration.
91 * The grid of iteration is rather complicated. For a picture of it see
92 * http://article.gmane.org/gmane.games.freeciv.devel/50449
93 * (formerly newgrid.png in PR#12085).
95 #define gui_rect_iterate(GRI_x0, GRI_y0, GRI_width, GRI_height, \
96 _t, _e, _c, _zoom) \
97 { \
98 int _x_##_0 = (GRI_x0), _y_##_0 = (GRI_y0); \
99 int _x_##_w = (GRI_width), _y_##_h = (GRI_height); \
101 if (_x_##_w < 0) { \
102 _x_##_0 += _x_##_w; \
103 _x_##_w = -_x_##_w; \
105 if (_y_##_h < 0) { \
106 _y_##_0 += _y_##_h; \
107 _y_##_h = -_y_##_h; \
109 if (_x_##_w > 0 && _y_##_h > 0) { \
110 struct tile_edge _t##_e; \
111 struct tile_corner _t##_c; \
112 int _t##_xi, _t##_yi, _t##_si, _t##_di; \
113 const int _t##_r1 = (tileset_is_isometric(tileset) ? 2 : 1); \
114 const int _t##_r2 = _t##_r1 * 2; /* double the ratio */ \
115 const int _t##_w = tileset_tile_width(tileset) * _zoom; \
116 const int _t##_h = tileset_tile_height(tileset) * _zoom; \
117 /* Don't divide by _r2 yet, to avoid integer rounding errors. */ \
118 const int _t##_x0 = DIVIDE(_x_##_0 * _t##_r2, _t##_w) - _t##_r1 / 2;\
119 const int _t##_y0 = DIVIDE(_y_##_0 * _t##_r2, _t##_h) - _t##_r1 / 2;\
120 const int _t##_x1 = DIVIDE((_x_##_0 + _x_##_w) * _t##_r2 + _t##_w - 1,\
121 _t##_w) + _t##_r1; \
122 const int _t##_y1 = DIVIDE((_y_##_0 + _y_##_h) * _t##_r2 + _t##_h - 1,\
123 _t##_h) + _t##_r1; \
124 const int _t##_count = (_t##_x1 - _t##_x0) * (_t##_y1 - _t##_y0); \
125 int _t##_index = 0; \
127 log_debug("Iterating over %d-%d x %d-%d rectangle.", \
128 _t##_x1, _t##_x0, _t##_y1, _t##_y0); \
129 for (; _t##_index < _t##_count; _t##_index++) { \
130 struct tile *_t = NULL; \
131 struct tile_edge *_e = NULL; \
132 struct tile_corner *_c = NULL; \
134 _t##_xi = _t##_x0 + (_t##_index % (_t##_x1 - _t##_x0)); \
135 _t##_yi = _t##_y0 + (_t##_index / (_t##_x1 - _t##_x0)); \
136 _t##_si = _t##_xi + _t##_yi; \
137 _t##_di = _t##_yi - _t##_xi; \
138 if (2 == _t##_r1 /*tileset_is_isometric(tileset)*/) { \
139 if ((_t##_xi + _t##_yi) % 2 != 0) { \
140 continue; \
142 if (_t##_xi % 2 == 0 && _t##_yi % 2 == 0) { \
143 if ((_t##_xi + _t##_yi) % 4 == 0) { \
144 /* Tile */ \
145 _t = map_pos_to_tile(_t##_si / 4 - 1, _t##_di / 4); \
146 } else { \
147 /* Corner */ \
148 _c = &_t##_c; \
149 _c->tile[0] = map_pos_to_tile((_t##_si - 6) / 4, \
150 (_t##_di - 2) / 4); \
151 _c->tile[1] = map_pos_to_tile((_t##_si - 2) / 4, \
152 (_t##_di - 2) / 4); \
153 _c->tile[2] = map_pos_to_tile((_t##_si - 2) / 4, \
154 (_t##_di + 2) / 4); \
155 _c->tile[3] = map_pos_to_tile((_t##_si - 6) / 4, \
156 (_t##_di + 2) / 4); \
157 if (tileset_hex_width(tileset) > 0) { \
158 _e = &_t##_e; \
159 _e->type = EDGE_UD; \
160 _e->tile[0] = _c->tile[0]; \
161 _e->tile[1] = _c->tile[2]; \
162 } else if (tileset_hex_height(tileset) > 0) { \
163 _e = &_t##_e; \
164 _e->type = EDGE_LR; \
165 _e->tile[0] = _c->tile[1]; \
166 _e->tile[1] = _c->tile[3]; \
169 } else { \
170 /* Edge. */ \
171 _e = &_t##_e; \
172 if (_t##_si % 4 == 0) { \
173 _e->type = EDGE_NS; \
174 _e->tile[0] = map_pos_to_tile((_t##_si - 4) / 4, \
175 (_t##_di - 2) / 4); /*N*/ \
176 _e->tile[1] = map_pos_to_tile((_t##_si - 4) / 4, \
177 (_t##_di + 2) / 4); /*S*/ \
178 } else { \
179 _e->type = EDGE_WE; \
180 _e->tile[0] = map_pos_to_tile((_t##_si - 6) / 4, \
181 _t##_di / 4); /*W*/ \
182 _e->tile[1] = map_pos_to_tile((_t##_si - 2) / 4, \
183 _t##_di / 4); /*E*/ \
186 } else { \
187 if (_t##_si % 2 == 0) { \
188 if (_t##_xi % 2 == 0) { \
189 /* Corner. */ \
190 _c = &_t##_c; \
191 _c->tile[0] = map_pos_to_tile(_t##_xi / 2 - 1, \
192 _t##_yi / 2 - 1); /*NW*/ \
193 _c->tile[1] = map_pos_to_tile(_t##_xi / 2, \
194 _t##_yi / 2 - 1); /*NE*/ \
195 _c->tile[2] = map_pos_to_tile(_t##_xi / 2, \
196 _t##_yi / 2); /*SE*/ \
197 _c->tile[3] = map_pos_to_tile(_t##_xi / 2 - 1, \
198 _t##_yi / 2); /*SW*/ \
199 } else { \
200 /* Tile. */ \
201 _t = map_pos_to_tile((_t##_xi - 1) / 2, \
202 (_t##_yi - 1) / 2); \
204 } else { \
205 /* Edge. */ \
206 _e = &_t##_e; \
207 if (_t##_yi % 2 == 0) { \
208 _e->type = EDGE_NS; \
209 _e->tile[0] = map_pos_to_tile((_t##_xi - 1) / 2, \
210 _t##_yi / 2 - 1); /*N*/ \
211 _e->tile[1] = map_pos_to_tile((_t##_xi - 1) / 2, \
212 _t##_yi / 2); /*S*/ \
213 } else { \
214 _e->type = EDGE_WE; \
215 _e->tile[0] = map_pos_to_tile(_t##_xi / 2 - 1, \
216 (_t##_yi - 1) / 2); /*W*/ \
217 _e->tile[1] = map_pos_to_tile(_t##_xi / 2, \
218 (_t##_yi - 1) / 2); /*E*/ \
223 #define gui_rect_iterate_end \
228 #define gui_rect_iterate_coord(GRI_x0, GRI_y0, GRI_width, GRI_height, \
229 _t, _e, _c, _x, _y, _zoom) \
230 gui_rect_iterate(GRI_x0, GRI_y0, GRI_width, GRI_height, \
231 _t, _e, _c, _zoom) { \
232 int _x, _y; \
234 _x = _t##_xi * _t##_w / _t##_r2 - _t##_w / 2; \
235 _y = _t##_yi * _t##_h / _t##_r2 - _t##_h / 2;
237 #define gui_rect_iterate_coord_end \
238 } gui_rect_iterate_end
240 void refresh_tile_mapcanvas(struct tile *ptile,
241 bool full_refresh, bool write_to_screen);
242 void refresh_unit_mapcanvas(struct unit *punit, struct tile *ptile,
243 bool full_refresh, bool write_to_screen);
244 void refresh_city_mapcanvas(struct city *pcity, struct tile *ptile,
245 bool full_refresh, bool write_to_screen);
247 void unqueue_mapview_updates(bool write_to_screen);
249 void map_to_gui_vector(const struct tileset *t, float zoom,
250 float *gui_dx, float *gui_dy, int map_dx, int map_dy);
251 bool tile_to_canvas_pos(float *canvas_x, float *canvas_y, struct tile *ptile);
252 struct tile *canvas_pos_to_tile(float canvas_x, float canvas_y);
253 struct tile *canvas_pos_to_nearest_tile(float canvas_x, float canvas_y);
255 void get_mapview_scroll_window(float *xmin, float *ymin,
256 float *xmax, float *ymax,
257 int *xsize, int *ysize);
258 void get_mapview_scroll_step(int *xstep, int *ystep);
259 void get_mapview_scroll_pos(int *scroll_x, int *scroll_y);
260 void set_mapview_scroll_pos(int scroll_x, int scroll_y);
262 void set_mapview_origin(float gui_x0, float gui_y0);
263 struct tile *get_center_tile_mapcanvas(void);
264 void center_tile_mapcanvas(struct tile *ptile);
266 bool tile_visible_mapcanvas(struct tile *ptile);
267 bool tile_visible_and_not_on_border_mapcanvas(struct tile *ptile);
269 void put_unit(const struct unit *punit, struct canvas *pcanvas, float zoom,
270 int canvas_x, int canvas_y);
271 void put_unittype(const struct unit_type *putype, struct canvas *pcanvas, float zoom,
272 int canvas_x, int canvas_y);
273 void put_city(struct city *pcity, struct canvas *pcanvas, float zoom,
274 int canvas_x, int canvas_y);
275 void put_terrain(struct tile *ptile, struct canvas *pcanvas, float zoom,
276 int canvas_x, int canvas_y);
278 void put_unit_city_overlays(struct unit *punit,
279 struct canvas *pcanvas,
280 int canvas_x, int canvas_y, int *upkeep_cost,
281 int happy_cost);
282 void toggle_city_color(struct city *pcity);
283 void toggle_unit_color(struct unit *punit);
285 void put_nuke_mushroom_pixmaps(struct tile *ptile);
287 void put_one_element(struct canvas *pcanvas, float zoom,
288 enum mapview_layer layer,
289 const struct tile *ptile,
290 const struct tile_edge *pedge,
291 const struct tile_corner *pcorner,
292 const struct unit *punit, const struct city *pcity,
293 int canvas_x, int canvas_y,
294 const struct city *citymode,
295 const struct unit_type *putype);
297 void put_drawn_sprites(struct canvas *pcanvas, float zoom,
298 int canvas_x, int canvas_y,
299 int count, struct drawn_sprite *pdrawn,
300 bool fog);
302 void update_map_canvas(int canvas_x, int canvas_y, int width, int height);
303 void update_map_canvas_visible(void);
304 void update_city_description(struct city *pcity);
305 void update_tile_label(struct tile *ptile);
307 void show_city_descriptions(int canvas_base_x, int canvas_base_y,
308 int width_base, int height_base);
309 void show_tile_labels(int canvas_base_x, int canvas_base_y,
310 int width_base, int height_base);
311 bool show_unit_orders(struct unit *punit);
313 void draw_segment(struct tile *ptile, enum direction8 dir);
314 void undraw_segment(struct tile *ptile, enum direction8 dir);
316 void decrease_unit_hp_smooth(struct unit *punit0, int hp0,
317 struct unit *punit1, int hp1);
318 void move_unit_map_canvas(struct unit *punit,
319 struct tile *ptile, int dx, int dy);
321 struct city *find_city_or_settler_near_tile(const struct tile *ptile,
322 struct unit **punit);
323 struct city *find_city_near_tile(const struct tile *ptile);
325 void get_city_mapview_production(struct city *pcity,
326 char *buf, size_t buf_len);
327 void get_city_mapview_name_and_growth(struct city *pcity,
328 char *name_buffer,
329 size_t name_buffer_len,
330 char *growth_buffer,
331 size_t growth_buffer_len,
332 enum color_std *growth_color,
333 enum color_std *production_color);
334 void get_city_mapview_trade_routes(struct city *pcity,
335 char *trade_routes_buffer,
336 size_t trade_routes_buffer_len,
337 enum color_std *trade_routes_color);
339 bool map_canvas_resized(int width, int height);
340 void init_mapcanvas_and_overview(void);
341 void free_mapcanvas_and_overview(void);
343 void get_spaceship_dimensions(int *width, int *height);
344 void put_spaceship(struct canvas *pcanvas, int canvas_x, int canvas_y,
345 const struct player *pplayer);
347 void link_marks_init(void);
348 void link_marks_free(void);
350 void link_marks_draw_all(void);
351 void link_marks_clear_all(void);
352 void link_marks_decrease_turn_counters(void);
354 void link_mark_add_new(enum text_link_type type, int id);
355 void link_mark_restore(enum text_link_type type, int id);
357 bool tileset_map_topo_compatible(int topology_id, struct tileset *tset);
359 #ifdef __cplusplus
361 #endif /* __cplusplus */
363 #endif /* FC__MAPVIEW_COMMON_H */