ScummVM API documentation
gr_dispatcher.h
1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef QDENGINE_SYSTEM_GRAPHICS_GR_DISPATCHER_H
23 #define QDENGINE_SYSTEM_GRAPHICS_GR_DISPATCHER_H
24 
25 #include "common/std/vector.h"
26 #include "qdengine/xmath.h"
27 #include "qdengine/system/graphics/gr_screen_region.h"
28 
29 namespace Graphics {
30 class ManagedSurface;
31 }
32 
33 namespace QDEngine {
34 
35 // Directions for LineTo()
36 enum GR_LINEDIR {
37  GR_LEFT,
38  GR_TOP,
39  GR_RIGHT,
40  GR_BOTTOM
41 };
42 
43 // Modes for putSpr()
44 const int GR_BLACK_FON = 0x01;
45 const int GR_CLIPPED = 0x02;
46 const int GR_NOCLIP = 0x04;
47 const int GR_FLIP_HORIZONTAL = 0x08;
48 const int GR_FLIP_VERTICAL = 0x10;
49 const int GR_IGNORE_ALPHA = 0x20;
50 
51 // Modes for Rectangle()
52 const int GR_FILLED = 0x00;
53 const int GR_OUTLINED = 0x01;
54 
55 // grDispatcher::_flags
56 const int GR_INITED = 0x01;
57 const int GR_PALETTE = 0x02;
58 const int GR_REINIT = 0x04;
59 
60 #ifdef _GR_ENABLE_ZBUFFER
61 typedef int16 zbuf_t;
62 const GR_ZBUFFFER_MASK = 0xFFFF;
63 const GR_ZBUFFER_MAX_Z = 30000;
64 #endif
65 
66 enum grTextAlign {
67  GR_ALIGN_LEFT,
68  GR_ALIGN_CENTER,
69  GR_ALIGN_RIGHT
70 };
71 
72 enum grPixelFormat {
73  GR_RGB565 = 0,
74  GR_ARGB1555,
75  GR_RGB888,
76  GR_ARGB8888,
77  GR_RGBA8888
78 };
79 
80 class grFont;
81 class grTileSprite;
82 class RLEBuffer;
83 class UI_TextParser;
84 
85 class grDispatcher {
86 public:
87  grDispatcher();
88  virtual ~grDispatcher();
89 
90  static bool sys_init();
91 
92  bool init(int sx, int sy, grPixelFormat pixel_format);
93 
94  void toggle_reinit() {
95  _flags |= GR_REINIT;
96  }
97  bool is_in_reinit_mode() const {
98  return _flags & GR_REINIT;
99  }
100 
101  void set_flag(int fl) {
102  _flags |= fl;
103  }
104  void drop_flag(int fl) {
105  _flags &= ~fl;
106  }
107  bool check_flag(int fl) {
108  if (_flags & fl) return true;
109  return false;
110  }
111 
112  bool finit();
113 
114  void *Get_hWnd() const {
115  return _hWnd;
116  }
117  int get_SizeX() const {
118  return _sizeX;
119  }
120  int get_SizeY() const {
121  return _sizeY;
122  }
123 
124  void setClipMode(int m) {
125  _clipMode = m;
126  }
127  int getClipMode() const {
128  return _clipMode;
129  }
130 
131  void setClip() {
132  setClip(0, 0, _sizeX, _sizeY);
133  }
134 
135  void getClip(int &l, int &t, int &r, int &b) const {
136  l = _clipCoords[GR_LEFT];
137  t = _clipCoords[GR_TOP];
138  r = _clipCoords[GR_RIGHT];
139  b = _clipCoords[GR_BOTTOM];
140  }
141 
142  void setClip(int l, int t, int r, int b) {
143  if (l < 0) l = 0;
144  if (r > _sizeX) r = _sizeX;
145 
146  if (t < 0) t = 0;
147  if (b > _sizeY) b = _sizeY;
148 
149  _clipCoords[GR_LEFT] = l;
150  _clipCoords[GR_TOP] = t;
151  _clipCoords[GR_RIGHT] = r;
152  _clipCoords[GR_BOTTOM] = b;
153  }
154 
155  void limitClip(int l, int t, int r, int b) {
156  if (_clipCoords[GR_LEFT] < l) _clipCoords[GR_LEFT] = l;
157  if (_clipCoords[GR_TOP] < t) _clipCoords[GR_TOP] = t;
158  if (_clipCoords[GR_RIGHT] > r) _clipCoords[GR_RIGHT] = r;
159  if (_clipCoords[GR_BOTTOM] > b) _clipCoords[GR_BOTTOM] = b;
160  }
161 
162  int clipCheck(int x, int y) {
163  if (x >= _clipCoords[GR_LEFT] && x < _clipCoords[GR_RIGHT] && y >= _clipCoords[GR_TOP] && y < _clipCoords[GR_BOTTOM])
164  return 1;
165 
166  return 0;
167  }
168 
169  int clipCheck(int x, int y, int sx, int sy) {
170  if (x - sx >= _clipCoords[GR_LEFT] && x + sx < _clipCoords[GR_RIGHT] && y - sy >= _clipCoords[GR_TOP] && y + sy < _clipCoords[GR_BOTTOM])
171  return 1;
172 
173  return 0;
174  }
175 
176 
177  bool flush(int x, int y, int sx, int sy);
178  bool flush();
179  bool flushChanges();
180 
181  void fill(int val);
182 
183  void putSpr(int x, int y, int sx, int sy, const byte *p, int mode, int spriteFormat);
184  void putSpr(int x, int y, int sx, int sy, const byte *p, int mode, int spriteFormat, float scale);
185  void putSpr_rle(int x, int y, int sx, int sy, const RLEBuffer *p, int mode, bool alpha_flag);
186  void putSpr_rle(int x, int y, int sx, int sy, const RLEBuffer *p, int mode, float scale, bool alpha_flag);
187  void putSpr_a(int x, int y, int sx, int sy, const byte *p, int mode);
188  void putSpr_a(int x, int y, int sx, int sy, const byte *p, int mode, float scale);
189 
190  void putSpr_rot(const Vect2i &pos, const Vect2i &size, const byte *data, bool has_alpha, int mode, float angle);
191  void putSpr_rot(const Vect2i &pos, const Vect2i &size, const byte *data, bool has_alpha, int mode, float angle, const Vect2f &scale);
192  void putSpr_rle_rot(const Vect2i &pos, const Vect2i &size, const RLEBuffer *data, bool has_alpha, int mode, float angle);
193  void putSpr_rle_rot(const Vect2i &pos, const Vect2i &size, const RLEBuffer *data, bool has_alpha, int mode, float angle, const Vect2f &scale);
194 
195  void putSprMask_rot(const Vect2i &pos, const Vect2i &size, const byte *data, bool has_alpha, uint32 mask_color, int mask_alpha, int mode, float angle);
196  void putSprMask_rot(const Vect2i &pos, const Vect2i &size, const byte *data, bool has_alpha, uint32 mask_color, int mask_alpha, int mode, float angle, const Vect2f &scale);
197  void putSprMask_rle_rot(const Vect2i &pos, const Vect2i &size, const RLEBuffer *data, bool has_alpha, uint32 mask_color, int mask_alpha, int mode, float angle);
198  void putSprMask_rle_rot(const Vect2i &pos, const Vect2i &size, const RLEBuffer *data, bool has_alpha, uint32 mask_color, int mask_alpha, int mode, float angle, const Vect2f &scale);
199 
200  void putSprMask(int x, int y, int sx, int sy, const byte *p, uint32 mask_color, int mask_alpha, int mode);
201  void putSprMask(int x, int y, int sx, int sy, const byte *p, uint32 mask_color, int mask_alpha, int mode, float scale);
202  void putSprMask_rle(int x, int y, int sx, int sy, const RLEBuffer *p, uint32 mask_color, int mask_alpha, int mode, bool alpha_flag);
203  void putSprMask_rle(int x, int y, int sx, int sy, const RLEBuffer *p, uint32 mask_color, int mask_alpha, int mode, float scale, bool alpha_flag);
204  void putSprMask_a(int x, int y, int sx, int sy, const byte *p, uint32 mask_color, int mask_alpha, int mode);
205  void putSprMask_a(int x, int y, int sx, int sy, const byte *p, uint32 mask_color, int mask_alpha, int mode, float scale);
206 
207  void putTileSpr(int x, int y, const grTileSprite &sprite, bool has_alpha, int mode, Graphics::ManagedSurface *surface = nullptr, bool clip = true);
208 
209  void putChar(int x, int y, uint32 color, int font_sx, int font_sy, const byte *font_alpha, const grScreenRegion &char_region);
210 
211  void drawSprContour_a(int x, int y, int sx, int sy, const byte *p, int contour_color, int mode);
212  void drawSprContour_a(int x, int y, int sx, int sy, const byte *p, int contour_color, int mode, float scale);
213  void drawSprContour(int x, int y, int sx, int sy, const byte *p, int contour_color, int mode);
214  void drawSprContour(int x, int y, int sx, int sy, const byte *p, int contour_color, int mode, float scale);
215  void drawSprContour(int x, int y, int sx, int sy, const RLEBuffer *p, int contour_color, int mode, bool alpha_flag);
216  void drawSprContour(int x, int y, int sx, int sy, const RLEBuffer *p, int contour_color, int mode, float scale, bool alpha_flag);
217 
218  bool drawText(int x, int y, uint32 color, const char *str, int hspace = 0, int vspace = 0, const grFont *font = NULL);
219  bool drawAlignedText(int x, int y, int sx, int sy, uint32 color, const char *str, grTextAlign align = GR_ALIGN_LEFT, int hspace = 0, int vspace = 0, const grFont *font = NULL);
220  bool drawParsedText(int x, int y, int sx, int sy, uint32 color, const UI_TextParser *parser, grTextAlign align = GR_ALIGN_LEFT, const grFont *font = NULL);
221  int textWidth(const char *str, int hspace = 0, const grFont *font = NULL, bool first_string_only = false) const;
222  int textHeight(const char *str, int vspace = 0, const grFont *font = NULL) const;
223 
224 #ifdef _GR_ENABLE_ZBUFFER
225  void putSpr_z(int x, int y, int z, int sx, int sy, const byte *p, int mode);
226  void putSpr_z(int x, int y, int z, int sx, int sy, const byte *p, int mode, float scale);
227  void putSpr_rle_z(int x, int y, int z, int sx, int sy, const RLEBuffer *p, int mode, bool alpha_flag);
228  void putSpr_rle_z(int x, int y, int z, int sx, int sy, const RLEBuffer *p, int mode, float scale, bool alpha_flag);
229  void putSpr_a_z(int x, int y, int z, int sx, int sy, const byte *p, int mode);
230  void putSpr_a_z(int x, int y, int z, int sx, int sy, const byte *p, int mode, float scale);
231 #endif
232 
233  void erase(int x, int y, int sx, int sy, int col);
234  void erase(int x, int y, int sx, int sy, int r, int g, int b);
235 
236  void setPixel(int x, int y, int col);
237  void setPixelFast(byte *buf, uint32 col);
238  void setPixelFast(int x, int y, int col);
239  void setPixelFast(int x, int y, int r, int g, int b);
240 
241  void setPixel(int x, int y, int r, int g, int b);
242 
243  void surfaceOverride(Graphics::ManagedSurface *target);
244  void resetSurfaceOverride();
245 
246  void getPixel(int x, int y, uint32 &col);
247  void getPixel(int x, int y, uint16 &col);
248  void getPixel(int x, int y, byte &r, byte &g, byte &b);
249 
250  void line(int x1, int y1, int x2, int y2, int col, int line_style = 0, bool inverse_col = false);
251 
252 #ifdef _GR_ENABLE_ZBUFFER
253  void line_z(int x1, int y1, int z1, int x2, int y2, int z2, int col, int line_style = 0);
254 #endif
255 
256  void lineTo(int x, int y, int len, int dir, int col, int line_style = 0);
257  void rectangle(int x, int y, int sx, int sy, int outcol, int incol, int mode, int line_style = 0);
258  void rectangleAlpha(int x, int y, int sx, int sy, uint32 color, int alpha);
259 
260  int PalettedMode() const {
261  return (_flags & GR_PALETTE);
262  }
263 
264  grPixelFormat pixel_format() const {
265  return _pixel_format;
266  }
267  void set_pixel_format(grPixelFormat mode) {
268  _pixel_format = GR_RGB565;
269  }
270 
271  inline int bytes_per_pixel() const {
272  switch (_pixel_format) {
273  case GR_ARGB1555:
274  case GR_RGB565:
275  return 2;
276  case GR_RGB888:
277  return 3;
278  case GR_ARGB8888:
279  case GR_RGBA8888:
280  return 4;
281  default:
282  return 0;
283  }
284  }
285 
286  enum { // маски для high color режимов
287  mask_565_r = 0xFFFF & (0x001F << 11),
288  mask_565_g = 0xFFFF & (0x003F << 5),
289  mask_565_b = 0xFFFF & (0x001F << 0),
290 
291  mask_555_r = 0xFFFF & (0x001F << 10),
292  mask_555_g = 0xFFFF & (0x001F << 5),
293  mask_555_b = 0xFFFF & (0x001F << 0)
294  };
295 
296  inline uint32 make_rgb(uint32 color) const {
297  switch (_pixel_format) {
298  case GR_RGB565:
299  return make_rgb565u((color >> 0) & 0xFF, (color >> 8) & 0xFF, (color >> 16) & 0xFF);
300  case GR_ARGB1555:
301  return make_rgb555u((color >> 0) & 0xFF, (color >> 8) & 0xFF, (color >> 16) & 0xFF);
302  case GR_RGB888:
303  case GR_ARGB8888:
304  case GR_RGBA8888:
305  return color;
306  }
307 
308  return 0;
309  }
310 
311  inline uint32 make_rgb(uint32 r, uint32 g, uint32 b) const {
312  switch (_pixel_format) {
313  case GR_RGB565:
314  return make_rgb565u(r, g, b);
315  case GR_ARGB1555:
316  return make_rgb555u(r, g, b);
317  case GR_RGB888:
318  case GR_ARGB8888:
319  return ((b << 16) | (g << 8) | r);
320  case GR_RGBA8888:
321  return ((r << 16) | (g << 8) | b);
322  }
323 
324  return 0;
325  }
326 
327 
329  typedef bool (*char_input_hanler_t)(int input);
330  static char_input_hanler_t set_input_handler(char_input_hanler_t h) {
331  char_input_hanler_t old_h = _input_handler;
332  _input_handler = h;
333  return old_h;
334  }
335 
336  static bool handle_char_input(int input) {
337  if (_input_handler) return (*_input_handler)(input);
338  return false;
339  }
340 
341  static inline uint32 make_rgb888(uint32 r, uint32 g, uint32 b) {
342  return ((b << 16) | (g << 8) | r);
343  }
344 
345  static inline uint16 make_rgb565u(uint32 r, uint32 g, uint32 b) {
346  return (((r >> 3) << 11) | ((g >> 2) << 5) | ((b >> 3) << 0));
347  }
348  static inline uint16 make_rgb555u(uint32 r, uint32 g, uint32 b) {
349  return (((r >> 3) << 10) | ((g >> 3) << 5) | ((b >> 3) << 0));
350  }
351 
352  static inline void split_rgb565u(uint32 col, byte &r, byte &g, byte &b) {
353  r = ((col & mask_565_r) >> 11) << 3;
354  g = ((col & mask_565_g) >> 5) << 2;
355  b = ((col & mask_565_b) >> 0) << 3;
356  }
357  static inline void split_rgb555u(uint32 col, byte &r, byte &g, byte &b) {
358  r = ((col & mask_555_r) >> 10) << 3;
359  g = ((col & mask_555_g) >> 5) << 3;
360  b = ((col & mask_555_b) >> 0) << 3;
361  }
362 
363  static inline void split_rgb888(uint32 col, byte &r, byte &g, byte &b) {
364  r = (col >> 0) & 0xFF;
365  g = (col >> 8) & 0xFF;
366  b = (col >> 16) & 0xFF;
367  }
368 
369  static inline uint16 make_rgb565(uint32 r, uint32 g, uint32 b) {
370  return ((r << 11) | (g << 5) | (b << 0));
371  }
372  static inline uint16 make_rgb555(uint32 r, uint32 g, uint32 b) {
373  return ((r << 10) | (g << 5) | (b << 0));
374  }
375 
376  static inline uint16 alpha_blend_565(uint16 pic_col, uint16 scr_col, uint32 a) {
377  if (a != 255) {
378  if (a)
379  return pic_col + (((((scr_col & mask_565_r) * a) >> 8) & mask_565_r) |
380  ((((scr_col & mask_565_g) * a) >> 8) & mask_565_g) |
381  ((((scr_col & mask_565_b) * a) >> 8) & mask_565_b));
382  else
383  return pic_col;
384  } else
385  return scr_col;
386  }
387 
388  static inline uint16 alpha_blend_555(uint16 pic_col, uint16 scr_col, uint32 a) {
389  if (a != 255) {
390  if (a)
391  return pic_col + (((((scr_col & mask_555_r) * a) >> 8) & mask_555_r) |
392  ((((scr_col & mask_555_g) * a) >> 8) & mask_555_g) |
393  ((((scr_col & mask_555_b) * a) >> 8) & mask_555_b));
394  else
395  return pic_col;
396  } else
397  return scr_col;
398  }
399 
400  const void *mouse_cursor() const {
401  return _mouse_cursor;
402  }
403  void set_default_mouse_cursor() {
404  _mouse_cursor = _default_mouse_cursor;
405  }
406  void set_null_mouse_cursor() {
407  _mouse_cursor = NULL;
408  }
409 
410  static grDispatcher *instance(void *hwnd);
411 
412  bool is_mouse_hidden() const {
413  return _hide_mouse;
414  }
415  void hideMouse() {
416  _hide_mouse = true;
417  }
418  void showMouse() {
419  _hide_mouse = false;
420  }
421 
422  bool clip_line(int &x0, int &y0, int &x1, int &y1) const;
423  bool clip_line(int &x0, int &y0, int &z0, int &x1, int &y1, int &z1) const;
424  bool clip_rectangle(int &x, int &y, int &pic_x, int &pic_y, int &pic_sx, int &pic_sy) const;
425 
426  bool is_rectangle_visible(int x, int y, int sx, int sy) const {
427  if (x + sx < 0 || x >= _sizeX || y + sy < 0 || y >= _sizeY) return false;
428  return true;
429  }
430 
431  bool clip_rectangle(int &x, int &y, int &sx, int &sy) const {
432  int x1 = x + sx;
433  int y1 = y + sy;
434 
435  if (x < _clipCoords[0]) x = _clipCoords[0];
436  if (x1 >= _clipCoords[2]) x1 = _clipCoords[2] - 1;
437 
438  if (y < _clipCoords[1]) y = _clipCoords[1];
439  if (y1 >= _clipCoords[3]) y1 = _clipCoords[3] - 1;
440 
441  sx = x1 - x;
442  sy = y1 - y;
443 
444  if (sx <= 0 || sy <= 0)
445  return false;
446 
447  return true;
448  }
449 
450  void clear_changes_mask();
451 
453  typedef regions_container_t::const_iterator region_iterator;
454 
455  const regions_container_t &changed_regions() const {
456  return _changed_regions;
457  }
458  void build_changed_regions();
459  bool invalidate_region(const grScreenRegion &reg);
460 
461  static inline grDispatcher *instance() {
462  return _dispatcher_ptr;
463  }
464  static inline grDispatcher *set_instance(grDispatcher *p) {
465  grDispatcher *old_p = _dispatcher_ptr;
466  _dispatcher_ptr = p;
467  return old_p;
468  }
469 
470  static inline const char *wnd_class_name() {
471  return _wnd_class_name;
472  }
473 
474  typedef void (*restore_handler_t)();
475  static restore_handler_t set_restore_handler(restore_handler_t h) {
476  restore_handler_t old_h = _restore_handler;
477  _restore_handler = h;
478  return old_h;
479  }
480 
481  static bool is_active() {
482  return _is_active;
483  }
484  static void activate(bool state) {
485  if (state && !_is_active) {
486  if (_restore_handler)
487  (*_restore_handler)();
488  }
489  _is_active = state;
490  }
491 
492  char *temp_buffer(int size);
493 
494  static bool convert_sprite(grPixelFormat src_fmt, grPixelFormat &dest_fmt, int sx, int sy, byte *data, bool &has_alpha);
495 
496  static grFont *load_font(const char *file_name);
497  static void set_default_font(grFont *p) {
498  _default_font = p;
499  }
500  static grFont *get_default_font() {
501  return _default_font;
502  }
503 protected:
504 
505  int _flags;
506 
507  int _wndPosX;
508  int _wndPosY;
509  int _wndSizeX;
510  int _wndSizeY;
511 
512  int _sizeX;
513  int _sizeY;
514 
515  grPixelFormat _pixel_format;
516  void *_hWnd;
517 
518  Graphics::ManagedSurface *_screenBuf = nullptr;
519  Graphics::ManagedSurface *_realScreenBuf = nullptr;
520 
521  char *_temp_buffer;
522  int _temp_buffer_size;
523 
524 private:
525 
526  int _clipMode;
527  int _clipCoords[4];
528 
529  bool _hide_mouse;
530  void *_mouse_cursor;
531  static void *_default_mouse_cursor;
532 
533  enum {
534  clLEFT = 1,
535  clRIGHT = 2,
536  clBOTTOM = 4,
537  clTOP = 8
538  };
539 
540  inline int clip_out_code(int x, int y) const {
541  int code = 0;
542  if (y >= _clipCoords[3])
543  code |= clTOP;
544  else if (y < _clipCoords[1])
545  code |= clBOTTOM;
546  if (x >= _clipCoords[2])
547  code |= clRIGHT;
548  else if (x < _clipCoords[0])
549  code |= clLEFT;
550 
551  return code;
552  }
553 
554 #ifdef _GR_ENABLE_ZBUFFER
555  zbuf_t *zbuffer_;
556 
557  bool alloc_zbuffer(int sx, int sy);
558  bool free_zbuffer();
559  bool clear_zbuffer();
560 
561  zbuf_t get_z(int x, int y) {
562  return zbuffer_[x + y * _sizeX];
563  }
564  void put_z(int x, int y, int z) {
565  zbuffer_[x + y * _sizeX] = z;
566  }
567 #endif
568 
570 
571  enum {
572  kChangesMaskTile = 16,
573  kChangesMaskTileShift = 4
574  };
575 
576  int _changes_mask_size_x;
577  int _changes_mask_size_y;
578 
579  changes_mask_t _changes_mask;
580 
581  regions_container_t _changed_regions;
582 
583  static char_input_hanler_t _input_handler;
584 
585  static grFont *_default_font;
586 
587  static bool _is_active;
588  static restore_handler_t _restore_handler;
589 
590  static grDispatcher *_dispatcher_ptr;
591  static char *_wnd_class_name;
592 
593  void putSpr_rot90(const Vect2i &pos, const Vect2i &size, const byte *data, bool has_alpha, int mode, float angle);
594 };
595 
596 } // namespace QDEngine
597 
598 #endif // QDENGINE_SYSTEM_GRAPHICS_GR_DISPATCHER_H
Definition: managed_surface.h:51
Definition: gr_dispatcher.h:85
Definition: xmath.h:117
Graphics::Surface * scale(const Graphics::Surface &srcImage, int xSize, int ySize)
Массив, сжатый методом RLE.
Definition: rle_compress.h:29
Базовый класс для игровых ресурсов.
Definition: console.h:28
Definition: xmath.h:268
Definition: formatinfo.h:28
Definition: UI_TextParser.h:55
signed char * fill(signed char *first, signed char *last, Value val)
Definition: algorithm.h:168
Прямоугольная область на экране.
Definition: gr_screen_region.h:31
Definition: gr_font.h:34
Тайл-спрайт
Definition: gr_tile_sprite.h:44