1 /*
2 * Copyright (c) 2001 Hansjörg Malthaner
3 *
4 * This file is part of the Simutrans project under the artistic license.
5 */
6
7 /*
8 * Attempt of graphics for the Simulation game
9 * Hj. Malthaner, Aug. 1997
10 *
11 *
12 * 3D, isometric representation
13 */
14 #ifndef simgraph_h
15 #define simgraph_h
16
17 #include "../simcolor.h"
18 #include "../unicode.h"
19 #include "../simtypes.h"
20 #include "clip_num.h"
21 #include "simimg.h"
22 #include "scr_coord.h"
23
24
25 extern int large_font_ascent;
26 extern int large_font_total_height;
27
28 #define LINEASCENT (large_font_ascent)
29 #define LINESPACE (large_font_total_height)
30
31 /**
32 * Alignment enum to align controls against each other
33 * Vertical and horizontal alignment can be masked together
34 * Unused bits are reserved for future use, set to 0.
35 *
36 * @author Max Kielland
37 */
38 enum control_alignments_t {
39
40 ALIGN_NONE = 0x00,
41
42 ALIGN_TOP = 0x01,
43 ALIGN_CENTER_V = 0x02,
44 ALIGN_BOTTOM = 0x03,
45 ALIGN_INTERIOR_V = 0x00,
46 ALIGN_EXTERIOR_V = 0x10,
47 ALIGN_STRETCH_V = 0x20,
48
49 ALIGN_LEFT = 0x04,
50 ALIGN_CENTER_H = 0x08,
51 ALIGN_RIGHT = 0x0C,
52 ALIGN_INTERIOR_H = 0x00,
53 ALIGN_EXTERIOR_H = 0x40,
54 ALIGN_STRETCH_H = 0x80,
55
56 // These flags does not belong in here but
57 // are defined here until we sorted this out.
58 // They are only used in display_text_proportional_len_clip_rgb()
59 // DT_DIRTY = 0x8000,
60 DT_CLIP = 0x4000
61 };
62 typedef uint16 control_alignment_t;
63
64 // size of koordinates
65 typedef short KOORD_VAL;
66
67
68 struct clip_dimension {
69 KOORD_VAL x, xx, w, y, yy, h;
70 };
71
72 // helper macros
73
74 // save the current clipping and set a new one
75 #define PUSH_CLIP(x,y,w,h) \
76 {\
77 clip_dimension const p_cr = display_get_clip_wh(); \
78 display_set_clip_wh(x, y, w, h);
79
80 // save the current clipping and set a new one
81 // fit it to old clipping region
82 #define PUSH_CLIP_FIT(x,y,w,h) \
83 {\
84 clip_dimension const p_cr = display_get_clip_wh(); \
85 display_set_clip_wh(x, y, w, h CLIP_NUM_DEFAULT, true);
86
87 // restore a saved clipping rect
88 #define POP_CLIP() \
89 display_set_clip_wh(p_cr.x, p_cr.y, p_cr.w, p_cr.h); \
90 }
91
92 /**
93 *
94 */
95 PIXVAL color_idx_to_rgb(PIXVAL idx);
96 PIXVAL color_rgb_to_idx(PIXVAL color);
97
98 /*
99 * Get 24bit RGB888 colour from an index of the old 8bit palette
100 */
101 uint32 get_color_rgb(uint8 idx);
102
103 /*
104 * Environment colours from RGB888 to system format
105 */
106 void env_t_rgb_to_system_colors();
107
108 /**
109 * Helper functions for clipping along tile borders.
110 * @author Dwachs
111 */
112 void add_poly_clip(int x0_,int y0_, int x1, int y1, int ribi CLIP_NUM_DEF);
113 void clear_all_poly_clip(CLIP_NUM_DEF0);
114 void activate_ribi_clip(int ribi CLIP_NUM_DEF);
115
116 /* Do no access directly, use the get_tile_raster_width()
117 * macro instead.
118 * @author Hj. Malthaner
119 */
120 #define get_tile_raster_width() (tile_raster_width)
121 extern KOORD_VAL tile_raster_width;
122
123 #define get_base_tile_raster_width() (base_tile_raster_width)
124 extern KOORD_VAL base_tile_raster_width;
125
126 /* changes the raster width after loading */
127 KOORD_VAL display_set_base_raster_width(KOORD_VAL new_raster);
128
129
130 int zoom_factor_up();
131 int zoom_factor_down();
132
133
134 /**
135 * Initialises the graphics module
136 * @author Hj. Malthaner
137 */
138 void simgraph_init(KOORD_VAL width, KOORD_VAL height, int fullscreen);
139 int is_display_init();
140 void simgraph_exit();
141 void simgraph_resize(KOORD_VAL w, KOORD_VAL h);
142 void reset_textur(void *new_textur);
143
144 /**
145 * Loads the font, returns the number of characters in it
146 * @param reload if true forces reload
147 */
148 uint16 display_load_font(const char* fname, bool reload = false);
149
150 image_id get_image_count();
151 void register_image(class image_t *);
152
153 // delete all images above a certain number ...
154 void display_free_all_images_above( image_id above );
155
156 // unzoomed offsets
157 void display_get_base_image_offset( image_id image, scr_coord_val *xoff, scr_coord_val *yoff, scr_coord_val *xw, scr_coord_val *yw );
158 // zoomed offsets
159 void display_get_image_offset( image_id image, KOORD_VAL *xoff, KOORD_VAL *yoff, KOORD_VAL *xw, KOORD_VAL *yw );
160 void display_mark_img_dirty( image_id image, KOORD_VAL x, KOORD_VAL y );
161
162 void mark_rect_dirty_wc(KOORD_VAL x1, KOORD_VAL y1, KOORD_VAL x2, KOORD_VAL y2); // clips to screen only
163 void mark_rect_dirty_clip(KOORD_VAL x1, KOORD_VAL y1, KOORD_VAL x2, KOORD_VAL y2 CLIP_NUM_DEF); // clips to clip_rect
164 void mark_screen_dirty();
165
166 KOORD_VAL display_get_width();
167 KOORD_VAL display_get_height();
168 void display_set_height(KOORD_VAL);
169 void display_set_actual_width(KOORD_VAL);
170
171 // force a certain size on a image (for rescaling tool images)
172 void display_fit_img_to_width( const image_id n, sint16 new_w );
173
174 void display_day_night_shift(int night);
175
176 // scrolls horizontally, will ignore clipping etc.
177 void display_scroll_band( const KOORD_VAL start_y, const KOORD_VAL x_offset, const KOORD_VAL h );
178
179 // set first and second company color for player
180 void display_set_player_color_scheme(const int player, const uint8 col1, const uint8 col2 );
181
182 // only used for GUI, display image inside a rect
183 void display_img_aligned( const image_id n, scr_rect area, int align, const int dirty);
184
185 // display image with day and night change
186 void display_img_aux(const image_id n, KOORD_VAL xp, KOORD_VAL yp, const signed char player_nr, const int daynight, const int dirty CLIP_NUM_DEF);
187
188 /**
189 * draws the images with alpha, either blended or as outline
190 * @author kierongreen
191 */
192 void display_rezoomed_img_blend(const image_id n, KOORD_VAL xp, KOORD_VAL yp, const signed char player_nr, const FLAGGED_PIXVAL color_index, const int daynight, const int dirty CLIP_NUM_DEF);
193 #define display_img_blend( n, x, y, c, dn, d ) display_rezoomed_img_blend( (n), (x), (y), 0, (c), (dn), (d) CLIP_NUM_DEFAULT)
194
195 #define ALPHA_RED 0x1
196 #define ALPHA_GREEN 0x2
197 #define ALPHA_BLUE 0x4
198
199 void display_rezoomed_img_alpha(const image_id n, const image_id alpha_n, const unsigned alpha_flags, KOORD_VAL xp, KOORD_VAL yp, const signed char player_nr, const FLAGGED_PIXVAL color_index, const int daynight, const int dirty CLIP_NUM_DEF);
200 #define display_img_alpha( n, a, f, x, y, c, dn, d ) display_rezoomed_img_alpha( (n), (a), (f), (x), (y), 0, (c), (dn), (d) CLIP_NUM_DEFAULT)
201
202 // display image with color (if there) and optional day and night change
203 void display_color_img(const image_id n, KOORD_VAL xp, KOORD_VAL yp, const signed char player_nr, const int daynight, const int dirty CLIP_NUM_DEF CLIP_NUM_DEFAULT_ZERO);
204
205 // display unzoomed image
206 void display_base_img(const image_id n, KOORD_VAL xp, KOORD_VAL yp, const signed char player_nr, const int daynight, const int dirty CLIP_NUM_DEF CLIP_NUM_DEFAULT_ZERO);
207
208 typedef image_id stretch_map_t[3][3];
209
210 // this displays a 3x3 array of images to fit the scr_rect
211 void display_img_stretch( const stretch_map_t &imag, scr_rect area );
212
213 // this displays a 3x3 array of images to fit the scr_rect like above, but blend the color
214 void display_img_stretch_blend( const stretch_map_t &imag, scr_rect area, FLAGGED_PIXVAL color );
215
216 // Knightly : display unzoomed image with alpha, either blended or as outline
217 void display_base_img_blend(const image_id n, KOORD_VAL xp, KOORD_VAL yp, const signed char player_nr, const FLAGGED_PIXVAL color_index, const int daynight, const int dirty CLIP_NUM_DEF CLIP_NUM_DEFAULT_ZERO);
218 void display_base_img_alpha(const image_id n, const image_id alpha_n, const unsigned alpha_flags, KOORD_VAL xp, KOORD_VAL yp, const signed char player_nr, const FLAGGED_PIXVAL color_index, const int daynight, const int dirty CLIP_NUM_DEF CLIP_NUM_DEFAULT_ZERO);
219
220 // Knightly : pointer to image display procedures
221 typedef void (*display_image_proc)(const image_id n, KOORD_VAL xp, KOORD_VAL yp, const signed char player_nr, const int daynight, const int dirty CLIP_NUM_DEF);
222 typedef void (*display_blend_proc)(const image_id n, KOORD_VAL xp, KOORD_VAL yp, const signed char player_nr, const FLAGGED_PIXVAL color_index, const int daynight, const int dirty CLIP_NUM_DEF);
223 typedef void (*display_alpha_proc)(const image_id n, const image_id alpha_n, const unsigned alpha_flags, KOORD_VAL xp, KOORD_VAL yp, const signed char player_nr, const FLAGGED_PIXVAL color_index, const int daynight, const int dirty CLIP_NUM_DEF);
224
225 // Knightly : variables for storing currently used image procedure set and tile raster width
226 extern display_image_proc display_normal;
227 extern display_image_proc display_color;
228 extern display_blend_proc display_blend;
229 extern display_alpha_proc display_alpha;
230 extern signed short current_tile_raster_width;
231
232 // Knightly : call this instead of referring to current_tile_raster_width directly
233 #define get_current_tile_raster_width() (current_tile_raster_width)
234
235 // Knightly : for switching between image procedure sets and setting current tile raster width
display_set_image_proc(bool is_global)236 inline void display_set_image_proc( bool is_global )
237 {
238 if( is_global ) {
239 display_normal = display_img_aux;
240 display_color = display_color_img;
241 display_blend = display_rezoomed_img_blend;
242 display_alpha = display_rezoomed_img_alpha;
243 current_tile_raster_width = get_tile_raster_width();
244 }
245 else {
246 display_normal = display_base_img;
247 display_color = display_base_img;
248 display_blend = display_base_img_blend;
249 display_alpha = display_base_img_alpha;
250 current_tile_raster_width = get_base_tile_raster_width();
251 }
252 }
253
254 // Blends two colors
255 PIXVAL display_blend_colors(PIXVAL background, PIXVAL foreground, int percent_blend);
256
257 // blends a rectangular region
258 void display_blend_wh_rgb(KOORD_VAL xp, KOORD_VAL yp, KOORD_VAL w, KOORD_VAL h, PIXVAL color, int percent_blend );
259
260 void display_fillbox_wh_rgb(KOORD_VAL xp, KOORD_VAL yp, KOORD_VAL w, KOORD_VAL h, PIXVAL color, bool dirty);
261
262 void display_fillbox_wh_clip_rgb(KOORD_VAL xp, KOORD_VAL yp, KOORD_VAL w, KOORD_VAL h, PIXVAL color, bool dirty CLIP_NUM_DEF CLIP_NUM_DEFAULT_ZERO);
263
264 void display_vline_wh_clip_rgb(KOORD_VAL xp, KOORD_VAL yp, KOORD_VAL h, PIXVAL c, bool dirty CLIP_NUM_DEF CLIP_NUM_DEFAULT_ZERO);
265
266 void display_clear();
267
268 void display_flush_buffer();
269
270 void display_show_pointer(int yesno);
271 void display_set_pointer(int pointer);
272 void display_show_load_pointer(int loading);
273
274
275 void display_array_wh(KOORD_VAL xp, KOORD_VAL yp, KOORD_VAL w, KOORD_VAL h, const PIXVAL *arr);
276
277 // compound painting routines
278 void display_outline_proportional_rgb(KOORD_VAL xpos, KOORD_VAL ypos, PIXVAL text_color, PIXVAL shadow_color, const char *text, int dirty, sint32 len=-1);
279 void display_shadow_proportional_rgb(KOORD_VAL xpos, KOORD_VAL ypos, PIXVAL text_color, PIXVAL shadow_color, const char *text, int dirty, sint32 len=-1);
280 void display_ddd_box_rgb(KOORD_VAL x1, KOORD_VAL y1, KOORD_VAL w, KOORD_VAL h, PIXVAL tl_color, PIXVAL rd_color, bool dirty);
281 void display_ddd_box_clip_rgb(KOORD_VAL x1, KOORD_VAL y1, KOORD_VAL w, KOORD_VAL h, PIXVAL tl_color, PIXVAL rd_color);
282
283
284 // unicode save moving in strings
285 size_t get_next_char(const char* text, size_t pos);
286 sint32 get_prev_char(const char* text, sint32 pos);
287
288 KOORD_VAL display_get_char_width(utf32 c);
289
290 /* returns true, if this is a valid character */
291 bool has_character( utf16 char_code );
292
293 /**
294 * Returns the width of the widest character in a string.
295 * @param text pointer to a string of characters to evaluate.
296 * @param len length of text buffer to evaluate. If set to 0,
297 * evaluate until null termination.
298 * @author Max Kielland
299 */
300 KOORD_VAL display_get_char_max_width(const char* text, size_t len=0);
301
302 /**
303 * For the next logical character in the text, returns the character code
304 * as well as retrieves the char byte count and the screen pixel width
305 * CAUTION : The text pointer advances to point to the next logical character
306 * @author Knightly
307 */
308 utf32 get_next_char_with_metrics(const char* &text, unsigned char &byte_length, unsigned char &pixel_width);
309
310 /**
311 * For the previous logical character in the text, returns the character code
312 * as well as retrieves the char byte count and the screen pixel width
313 * CAUTION : The text pointer recedes to point to the previous logical character
314 * @author Knightly
315 */
316 utf32 get_prev_char_with_metrics(const char* &text, const char *const text_start, unsigned char &byte_length, unsigned char &pixel_width);
317
318 /*
319 * returns the index of the last character that would fit within the width
320 * If an ellipsis len is given, it will only return the last character up to this len if the full length cannot be fitted
321 * @returns index of next character. if text[index]==0 the whole string fits
322 */
323 size_t display_fit_proportional( const char *text, scr_coord_val max_width, scr_coord_val ellipsis_width=0 );
324
325 /* routines for string len (macros for compatibility with old calls) */
326 #define proportional_string_width(text) display_calc_proportional_string_len_width(text, 0x7FFF)
327 #define proportional_string_len_width(text, len) display_calc_proportional_string_len_width(text, len)
328 // length of a string in pixel
329 int display_calc_proportional_string_len_width(const char* text, size_t len);
330
331 /*
332 * len parameter added - use -1 for previous behaviour.
333 * completely renovated for unicode and 10 bit width and variable height
334 * @author Volker Meyer, prissi
335 * @date 15.06.2003, 2.1.2005
336 */
337
338 // #ifdef MULTI_THREAD
339 int display_text_proportional_len_clip_rgb(KOORD_VAL x, KOORD_VAL y, const char* txt, control_alignment_t flags, const PIXVAL color, bool dirty, sint32 len CLIP_NUM_DEF CLIP_NUM_DEFAULT_ZERO);
340 /* macro are for compatibility */
341 #define display_proportional_rgb( x, y, txt, align, color, dirty) display_text_proportional_len_clip_rgb( x, y, txt, align, color, dirty, -1 )
342 #define display_proportional_clip_rgb( x, y, txt, align, color, dirty) display_text_proportional_len_clip_rgb( x, y, txt, align | DT_CLIP, color, dirty, -1 )
343
344
345 /*
346 * Display a string that if abbreviated by the (language specific) ellipsis character if too wide
347 * If enough space is given, it just display the full string
348 * @returns screen_width
349 */
350 KOORD_VAL display_proportional_ellipsis_rgb( scr_rect r, const char *text, int align, const PIXVAL color, const bool dirty, bool shadowed = false, PIXVAL shadow_color = 0 );
351
352 void display_ddd_proportional_clip(KOORD_VAL xpos, KOORD_VAL ypos, KOORD_VAL width, KOORD_VAL hgt, FLAGGED_PIXVAL ddd_farbe, FLAGGED_PIXVAL text_farbe, const char *text, int dirty CLIP_NUM_DEF CLIP_NUM_DEFAULT_ZERO);
353
354
355 int display_multiline_text_rgb(KOORD_VAL x, KOORD_VAL y, const char *inbuf, PIXVAL color);
356
357 // line drawing primitives
358 void display_direct_line_rgb(const KOORD_VAL x, const KOORD_VAL y, const KOORD_VAL xx, const KOORD_VAL yy, const PIXVAL color);
359 void display_direct_line_dotted_rgb(const KOORD_VAL x, const KOORD_VAL y, const KOORD_VAL xx, const KOORD_VAL yy, const KOORD_VAL draw, const KOORD_VAL dontDraw, const PIXVAL color);
360 void display_circle_rgb( KOORD_VAL x0, KOORD_VAL y0, int radius, const PIXVAL color );
361 void display_filled_circle_rgb( KOORD_VAL x0, KOORD_VAL y0, int radius, const PIXVAL color );
362 void draw_bezier_rgb(KOORD_VAL Ax, KOORD_VAL Ay, KOORD_VAL Bx, KOORD_VAL By, KOORD_VAL ADx, KOORD_VAL ADy, KOORD_VAL BDx, KOORD_VAL BDy, const PIXVAL colore, KOORD_VAL draw, KOORD_VAL dontDraw);
363
364 void display_set_clip_wh(KOORD_VAL x, KOORD_VAL y, KOORD_VAL w, KOORD_VAL h CLIP_NUM_DEF CLIP_NUM_DEFAULT_ZERO, bool fit = false);
365 clip_dimension display_get_clip_wh(CLIP_NUM_DEF0 CLIP_NUM_DEFAULT_ZERO);
366
367 void display_push_clip_wh(KOORD_VAL x, KOORD_VAL y, KOORD_VAL w, KOORD_VAL h CLIP_NUM_DEF CLIP_NUM_DEFAULT_ZERO);
368 void display_swap_clip_wh(CLIP_NUM_DEF0);
369 void display_pop_clip_wh(CLIP_NUM_DEF0);
370
371
372 void display_snapshot( int x, int y, int w, int h );
373
374 #if COLOUR_DEPTH != 0
375 extern uint8 display_day_lights[ LIGHT_COUNT * 3];
376 extern uint8 display_night_lights[LIGHT_COUNT * 3];
377 #endif
378
379 #endif
380