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 };
78 
79 class grFont;
80 class grTileSprite;
81 class RLEBuffer;
82 class UI_TextParser;
83 
84 class grDispatcher {
85 public:
86  grDispatcher();
87  virtual ~grDispatcher();
88 
89  static bool sys_init();
90 
91  bool init(int sx, int sy, grPixelFormat pixel_format);
92 
93  void toggle_reinit() {
94  _flags |= GR_REINIT;
95  }
96  bool is_in_reinit_mode() const {
97  return _flags & GR_REINIT;
98  }
99 
100  void set_flag(int fl) {
101  _flags |= fl;
102  }
103  void drop_flag(int fl) {
104  _flags &= ~fl;
105  }
106  bool check_flag(int fl) {
107  if (_flags & fl) return true;
108  return false;
109  }
110 
111  bool finit();
112 
113  void *Get_hWnd() const {
114  return _hWnd;
115  }
116  int get_SizeX() const {
117  return _sizeX;
118  }
119  int get_SizeY() const {
120  return _sizeY;
121  }
122 
123  void setClipMode(int m) {
124  _clipMode = m;
125  }
126  int getClipMode() const {
127  return _clipMode;
128  }
129 
130  void setClip() {
131  setClip(0, 0, _sizeX, _sizeY);
132  }
133 
134  void getClip(int &l, int &t, int &r, int &b) const {
135  l = _clipCoords[GR_LEFT];
136  t = _clipCoords[GR_TOP];
137  r = _clipCoords[GR_RIGHT];
138  b = _clipCoords[GR_BOTTOM];
139  }
140 
141  void setClip(int l, int t, int r, int b) {
142  if (l < 0) l = 0;
143  if (r > _sizeX) r = _sizeX;
144 
145  if (t < 0) t = 0;
146  if (b > _sizeY) b = _sizeY;
147 
148  _clipCoords[GR_LEFT] = l;
149  _clipCoords[GR_TOP] = t;
150  _clipCoords[GR_RIGHT] = r;
151  _clipCoords[GR_BOTTOM] = b;
152  }
153 
154  void limitClip(int l, int t, int r, int b) {
155  if (_clipCoords[GR_LEFT] < l) _clipCoords[GR_LEFT] = l;
156  if (_clipCoords[GR_TOP] < t) _clipCoords[GR_TOP] = t;
157  if (_clipCoords[GR_RIGHT] > r) _clipCoords[GR_RIGHT] = r;
158  if (_clipCoords[GR_BOTTOM] > b) _clipCoords[GR_BOTTOM] = b;
159  }
160 
161  int clipCheck(int x, int y) {
162  if (x >= _clipCoords[GR_LEFT] && x < _clipCoords[GR_RIGHT] && y >= _clipCoords[GR_TOP] && y < _clipCoords[GR_BOTTOM])
163  return 1;
164 
165  return 0;
166  }
167 
168  int clipCheck(int x, int y, int sx, int sy) {
169  if (x - sx >= _clipCoords[GR_LEFT] && x + sx < _clipCoords[GR_RIGHT] && y - sy >= _clipCoords[GR_TOP] && y + sy < _clipCoords[GR_BOTTOM])
170  return 1;
171 
172  return 0;
173  }
174 
175 
176  bool flush(int x, int y, int sx, int sy);
177  bool flush();
178  bool flushChanges();
179 
180  void fill(int val);
181 
182  void putSpr(int x, int y, int sx, int sy, const byte *p, int mode, int spriteFormat);
183  void putSpr(int x, int y, int sx, int sy, const byte *p, int mode, int spriteFormat, float scale);
184  void putSpr_rle(int x, int y, int sx, int sy, const RLEBuffer *p, int mode, bool alpha_flag);
185  void putSpr_rle(int x, int y, int sx, int sy, const RLEBuffer *p, int mode, float scale, bool alpha_flag);
186  void putSpr_a(int x, int y, int sx, int sy, const byte *p, int mode);
187  void putSpr_a(int x, int y, int sx, int sy, const byte *p, int mode, float scale);
188 
189  void putSpr_rot(const Vect2i &pos, const Vect2i &size, const byte *data, bool has_alpha, int mode, float angle);
190  void putSpr_rot(const Vect2i &pos, const Vect2i &size, const byte *data, bool has_alpha, int mode, float angle, const Vect2f &scale);
191  void putSpr_rle_rot(const Vect2i &pos, const Vect2i &size, const RLEBuffer *data, bool has_alpha, int mode, float angle);
192  void putSpr_rle_rot(const Vect2i &pos, const Vect2i &size, const RLEBuffer *data, bool has_alpha, int mode, float angle, const Vect2f &scale);
193 
194  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);
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, const Vect2f &scale);
196  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);
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, const Vect2f &scale);
198 
199  void putSprMask(int x, int y, int sx, int sy, const byte *p, uint32 mask_color, int mask_alpha, int mode);
200  void putSprMask(int x, int y, int sx, int sy, const byte *p, uint32 mask_color, int mask_alpha, int mode, float scale);
201  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);
202  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);
203  void putSprMask_a(int x, int y, int sx, int sy, const byte *p, uint32 mask_color, int mask_alpha, int mode);
204  void putSprMask_a(int x, int y, int sx, int sy, const byte *p, uint32 mask_color, int mask_alpha, int mode, float scale);
205 
206  void putTileSpr(int x, int y, const grTileSprite &sprite, bool has_alpha, int mode, Graphics::ManagedSurface *surface = nullptr, bool clip = true);
207 
208  void putChar(int x, int y, uint32 color, int font_sx, int font_sy, const byte *font_alpha, const grScreenRegion &char_region);
209 
210  void drawSprContour_a(int x, int y, int sx, int sy, const byte *p, int contour_color, int mode);
211  void drawSprContour_a(int x, int y, int sx, int sy, const byte *p, int contour_color, int mode, float scale);
212  void drawSprContour(int x, int y, int sx, int sy, const byte *p, int contour_color, int mode);
213  void drawSprContour(int x, int y, int sx, int sy, const byte *p, int contour_color, int mode, float scale);
214  void drawSprContour(int x, int y, int sx, int sy, const RLEBuffer *p, int contour_color, int mode, bool alpha_flag);
215  void drawSprContour(int x, int y, int sx, int sy, const RLEBuffer *p, int contour_color, int mode, float scale, bool alpha_flag);
216 
217  bool drawText(int x, int y, uint32 color, const char *str, int hspace = 0, int vspace = 0, const grFont *font = NULL);
218  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);
219  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);
220  int textWidth(const char *str, int hspace = 0, const grFont *font = NULL, bool first_string_only = false) const;
221  int textHeight(const char *str, int vspace = 0, const grFont *font = NULL) const;
222 
223 #ifdef _GR_ENABLE_ZBUFFER
224  void putSpr_z(int x, int y, int z, int sx, int sy, const byte *p, int mode);
225  void putSpr_z(int x, int y, int z, int sx, int sy, const byte *p, int mode, float scale);
226  void putSpr_rle_z(int x, int y, int z, int sx, int sy, const RLEBuffer *p, int mode, bool alpha_flag);
227  void putSpr_rle_z(int x, int y, int z, int sx, int sy, const RLEBuffer *p, int mode, float scale, bool alpha_flag);
228  void putSpr_a_z(int x, int y, int z, int sx, int sy, const byte *p, int mode);
229  void putSpr_a_z(int x, int y, int z, int sx, int sy, const byte *p, int mode, float scale);
230 #endif
231 
232  void erase(int x, int y, int sx, int sy, int col);
233  void erase(int x, int y, int sx, int sy, int r, int g, int b);
234 
235  void setPixel(int x, int y, int col);
236  void setPixelFast(int x, int y, int col);
237  void setPixelFast(int x, int y, int r, int g, int b);
238 
239  void setPixel(int x, int y, int r, int g, int b);
240 
241  void surfaceOverride(Graphics::ManagedSurface *target);
242  void resetSurfaceOverride();
243 
244  void getPixel(int x, int y, uint16 &col);
245  void getPixel(int x, int y, byte &r, byte &g, byte &b);
246 
247  void line(int x1, int y1, int x2, int y2, int col, int line_style = 0, bool inverse_col = false);
248 
249 #ifdef _GR_ENABLE_ZBUFFER
250  void line_z(int x1, int y1, int z1, int x2, int y2, int z2, int col, int line_style = 0);
251 #endif
252 
253  void lineTo(int x, int y, int len, int dir, int col, int line_style = 0);
254  void rectangle(int x, int y, int sx, int sy, int outcol, int incol, int mode, int line_style = 0);
255  void rectangleAlpha(int x, int y, int sx, int sy, uint32 color, int alpha);
256 
257  int PalettedMode() const {
258  return (_flags & GR_PALETTE);
259  }
260 
261  grPixelFormat pixel_format() const {
262  return _pixel_format;
263  }
264  void set_pixel_format(grPixelFormat mode) {
265  _pixel_format = GR_RGB565;
266  }
267 
268  inline int bytes_per_pixel() const {
269  return 2;
270  }
271 
272  enum { // маски для high color режимов
273  mask_565_r = 0xFFFF & (0x001F << 11),
274  mask_565_g = 0xFFFF & (0x003F << 5),
275  mask_565_b = 0xFFFF & (0x001F << 0),
276 
277  mask_555_r = 0xFFFF & (0x001F << 10),
278  mask_555_g = 0xFFFF & (0x001F << 5),
279  mask_555_b = 0xFFFF & (0x001F << 0)
280  };
281 
282  inline uint32 make_rgb(uint32 color) const {
283  switch (_pixel_format) {
284  case GR_RGB565:
285  return make_rgb565u((color >> 0) & 0xFF, (color >> 8) & 0xFF, (color >> 16) & 0xFF);
286  case GR_ARGB1555:
287  return make_rgb555u((color >> 0) & 0xFF, (color >> 8) & 0xFF, (color >> 16) & 0xFF);
288  case GR_RGB888:
289  case GR_ARGB8888:
290  return color;
291  }
292 
293  return 0;
294  }
295 
296  inline uint32 make_rgb(uint32 r, uint32 g, uint32 b) const {
297  switch (_pixel_format) {
298  case GR_RGB565:
299  return make_rgb565u(r, g, b);
300  case GR_ARGB1555:
301  return make_rgb555u(r, g, b);
302  case GR_RGB888:
303  case GR_ARGB8888:
304  return ((b << 16) | (g << 8) | r);
305  }
306 
307  return 0;
308  }
309 
310 
312  typedef bool (*char_input_hanler_t)(int input);
313  static char_input_hanler_t set_input_handler(char_input_hanler_t h) {
314  char_input_hanler_t old_h = _input_handler;
315  _input_handler = h;
316  return old_h;
317  }
318 
319  static bool handle_char_input(int input) {
320  if (_input_handler) return (*_input_handler)(input);
321  return false;
322  }
323 
324  static inline uint32 make_rgb888(uint32 r, uint32 g, uint32 b) {
325  return ((b << 16) | (g << 8) | r);
326  }
327 
328  static inline uint16 make_rgb565u(uint32 r, uint32 g, uint32 b) {
329  return (((r >> 3) << 11) | ((g >> 2) << 5) | ((b >> 3) << 0));
330  }
331  static inline uint16 make_rgb555u(uint32 r, uint32 g, uint32 b) {
332  return (((r >> 3) << 10) | ((g >> 3) << 5) | ((b >> 3) << 0));
333  }
334 
335  static inline void split_rgb565u(uint32 col, byte &r, byte &g, byte &b) {
336  r = ((col & mask_565_r) >> 11) << 3;
337  g = ((col & mask_565_g) >> 5) << 2;
338  b = ((col & mask_565_b) >> 0) << 3;
339  }
340  static inline void split_rgb555u(uint32 col, byte &r, byte &g, byte &b) {
341  r = ((col & mask_555_r) >> 10) << 3;
342  g = ((col & mask_555_g) >> 5) << 3;
343  b = ((col & mask_555_b) >> 0) << 3;
344  }
345 
346  static inline void split_rgb888(uint32 col, uint32 &r, uint32 &g, uint32 &b) {
347  r = (col >> 0) & 0xFF;
348  g = (col >> 8) & 0xFF;
349  b = (col >> 16) & 0xFF;
350  }
351 
352  static inline uint16 make_rgb565(uint32 r, uint32 g, uint32 b) {
353  return ((r << 11) | (g << 5) | (b << 0));
354  }
355  static inline uint16 make_rgb555(uint32 r, uint32 g, uint32 b) {
356  return ((r << 10) | (g << 5) | (b << 0));
357  }
358 
359  static inline uint16 alpha_blend_565(uint16 pic_col, uint16 scr_col, uint32 a) {
360  if (a != 255) {
361  if (a)
362  return pic_col + (((((scr_col & mask_565_r) * a) >> 8) & mask_565_r) |
363  ((((scr_col & mask_565_g) * a) >> 8) & mask_565_g) |
364  ((((scr_col & mask_565_b) * a) >> 8) & mask_565_b));
365  else
366  return pic_col;
367  } else
368  return scr_col;
369  }
370 
371  static inline uint16 alpha_blend_555(uint16 pic_col, uint16 scr_col, uint32 a) {
372  if (a != 255) {
373  if (a)
374  return pic_col + (((((scr_col & mask_555_r) * a) >> 8) & mask_555_r) |
375  ((((scr_col & mask_555_g) * a) >> 8) & mask_555_g) |
376  ((((scr_col & mask_555_b) * a) >> 8) & mask_555_b));
377  else
378  return pic_col;
379  } else
380  return scr_col;
381  }
382 
383  const void *mouse_cursor() const {
384  return _mouse_cursor;
385  }
386  void set_default_mouse_cursor() {
387  _mouse_cursor = _default_mouse_cursor;
388  }
389  void set_null_mouse_cursor() {
390  _mouse_cursor = NULL;
391  }
392 
393  static grDispatcher *instance(void *hwnd);
394 
395  bool is_mouse_hidden() const {
396  return _hide_mouse;
397  }
398  void hideMouse() {
399  _hide_mouse = true;
400  }
401  void showMouse() {
402  _hide_mouse = false;
403  }
404 
405  bool clip_line(int &x0, int &y0, int &x1, int &y1) const;
406  bool clip_line(int &x0, int &y0, int &z0, int &x1, int &y1, int &z1) const;
407  bool clip_rectangle(int &x, int &y, int &pic_x, int &pic_y, int &pic_sx, int &pic_sy) const;
408 
409  bool is_rectangle_visible(int x, int y, int sx, int sy) const {
410  if (x + sx < 0 || x >= _sizeX || y + sy < 0 || y >= _sizeY) return false;
411  return true;
412  }
413 
414  bool clip_rectangle(int &x, int &y, int &sx, int &sy) const {
415  int x1 = x + sx;
416  int y1 = y + sy;
417 
418  if (x < _clipCoords[0]) x = _clipCoords[0];
419  if (x1 >= _clipCoords[2]) x1 = _clipCoords[2] - 1;
420 
421  if (y < _clipCoords[1]) y = _clipCoords[1];
422  if (y1 >= _clipCoords[3]) y1 = _clipCoords[3] - 1;
423 
424  sx = x1 - x;
425  sy = y1 - y;
426 
427  if (sx <= 0 || sy <= 0)
428  return false;
429 
430  return true;
431  }
432 
433  void clear_changes_mask();
434 
436  typedef regions_container_t::const_iterator region_iterator;
437 
438  const regions_container_t &changed_regions() const {
439  return _changed_regions;
440  }
441  void build_changed_regions();
442  bool invalidate_region(const grScreenRegion &reg);
443 
444  static inline grDispatcher *instance() {
445  return _dispatcher_ptr;
446  }
447  static inline grDispatcher *set_instance(grDispatcher *p) {
448  grDispatcher *old_p = _dispatcher_ptr;
449  _dispatcher_ptr = p;
450  return old_p;
451  }
452 
453  static inline const char *wnd_class_name() {
454  return _wnd_class_name;
455  }
456 
457  typedef void (*restore_handler_t)();
458  static restore_handler_t set_restore_handler(restore_handler_t h) {
459  restore_handler_t old_h = _restore_handler;
460  _restore_handler = h;
461  return old_h;
462  }
463 
464  static bool is_active() {
465  return _is_active;
466  }
467  static void activate(bool state) {
468  if (state && !_is_active) {
469  if (_restore_handler)
470  (*_restore_handler)();
471  }
472  _is_active = state;
473  }
474 
475  char *temp_buffer(int size);
476 
477  static bool convert_sprite(grPixelFormat src_fmt, grPixelFormat &dest_fmt, int sx, int sy, byte *data, bool &has_alpha);
478 
479  static grFont *load_font(const char *file_name);
480  static void set_default_font(grFont *p) {
481  _default_font = p;
482  }
483  static grFont *get_default_font() {
484  return _default_font;
485  }
486 protected:
487 
488  int _flags;
489 
490  int _wndPosX;
491  int _wndPosY;
492  int _wndSizeX;
493  int _wndSizeY;
494 
495  int _sizeX;
496  int _sizeY;
497 
498  grPixelFormat _pixel_format;
499  void *_hWnd;
500 
501  Graphics::ManagedSurface *_screenBuf = nullptr;
502  Graphics::ManagedSurface *_realScreenBuf = nullptr;
503 
504  char *_temp_buffer;
505  int _temp_buffer_size;
506 
507 private:
508 
509  int _clipMode;
510  int _clipCoords[4];
511 
512  bool _hide_mouse;
513  void *_mouse_cursor;
514  static void *_default_mouse_cursor;
515 
516  enum {
517  clLEFT = 1,
518  clRIGHT = 2,
519  clBOTTOM = 4,
520  clTOP = 8
521  };
522 
523  inline int clip_out_code(int x, int y) const {
524  int code = 0;
525  if (y >= _clipCoords[3])
526  code |= clTOP;
527  else if (y < _clipCoords[1])
528  code |= clBOTTOM;
529  if (x >= _clipCoords[2])
530  code |= clRIGHT;
531  else if (x < _clipCoords[0])
532  code |= clLEFT;
533 
534  return code;
535  }
536 
537 #ifdef _GR_ENABLE_ZBUFFER
538  zbuf_t *zbuffer_;
539 
540  bool alloc_zbuffer(int sx, int sy);
541  bool free_zbuffer();
542  bool clear_zbuffer();
543 
544  zbuf_t get_z(int x, int y) {
545  return zbuffer_[x + y * _sizeX];
546  }
547  void put_z(int x, int y, int z) {
548  zbuffer_[x + y * _sizeX] = z;
549  }
550 #endif
551 
553 
554  enum {
555  kChangesMaskTile = 16,
556  kChangesMaskTileShift = 4
557  };
558 
559  int _changes_mask_size_x;
560  int _changes_mask_size_y;
561 
562  changes_mask_t _changes_mask;
563 
564  regions_container_t _changed_regions;
565 
566  static char_input_hanler_t _input_handler;
567 
568  static grFont *_default_font;
569 
570  static bool _is_active;
571  static restore_handler_t _restore_handler;
572 
573  static grDispatcher *_dispatcher_ptr;
574  static char *_wnd_class_name;
575 
576  void putSpr_rot90(const Vect2i &pos, const Vect2i &size, const byte *data, bool has_alpha, int mode, float angle);
577 };
578 
579 } // namespace QDEngine
580 
581 #endif // QDENGINE_SYSTEM_GRAPHICS_GR_DISPATCHER_H
Definition: managed_surface.h:51
Definition: gr_dispatcher.h:84
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