ScummVM API documentation
gfx.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 SCUMM_GFX_H
23 #define SCUMM_GFX_H
24 
25 #include "common/system.h"
26 #include "common/list.h"
27 
28 #include "graphics/surface.h"
29 
30 namespace Scumm {
31 
32 class ScummEngine;
33 
34 /*
35  * Bitmap compression algorithm labels
36  */
37 
38 #define BMCOMP_RAW256 1 // Raw pixels
39 #define BMCOMP_TOWNS_2 2
40 #define BMCOMP_TOWNS_3 3
41 #define BMCOMP_TOWNS_4 4
42 #define BMCOMP_TOWNS_7 7
43 #define BMCOMP_TRLE8BIT 8
44 #define BMCOMP_RLE8BIT 9
45 
46 #define BMCOMP_PIX32 10 // Amiga 16/32 color compression
47 
48 #define BMCOMP_ZIGZAG_V0 10 // Vertical
49 #define BMCOMP_ZIGZAG_V4 14
50 #define BMCOMP_ZIGZAG_V5 15
51 #define BMCOMP_ZIGZAG_V6 16
52 #define BMCOMP_ZIGZAG_V7 17
53 #define BMCOMP_ZIGZAG_V8 18
54 
55 #define BMCOMP_ZIGZAG_H0 20 // Horizontal
56 #define BMCOMP_ZIGZAG_H4 24
57 #define BMCOMP_ZIGZAG_H5 25
58 #define BMCOMP_ZIGZAG_H6 26
59 #define BMCOMP_ZIGZAG_H7 27
60 #define BMCOMP_ZIGZAG_H8 28
61 
62 #define BMCOMP_ZIGZAG_VT0 30 // Vertical with transparency
63 #define BMCOMP_ZIGZAG_VT4 34
64 #define BMCOMP_ZIGZAG_VT5 35
65 #define BMCOMP_ZIGZAG_VT6 36
66 #define BMCOMP_ZIGZAG_VT7 37
67 #define BMCOMP_ZIGZAG_VT8 38
68 
69 #define BMCOMP_ZIGZAG_HT0 40 // Horizontal with transparency
70 #define BMCOMP_ZIGZAG_HT4 44
71 #define BMCOMP_ZIGZAG_HT5 45
72 #define BMCOMP_ZIGZAG_HT6 46
73 #define BMCOMP_ZIGZAG_HT7 47
74 #define BMCOMP_ZIGZAG_HT8 48
75 
76 #define BMCOMP_MAJMIN_H0 60 // Major-Minor jump algorithm (-4 to +3)
77 #define BMCOMP_MAJMIN_H4 64
78 #define BMCOMP_MAJMIN_H5 65
79 #define BMCOMP_MAJMIN_H6 66
80 #define BMCOMP_MAJMIN_H7 67
81 #define BMCOMP_MAJMIN_H8 68
82 
83 #define BMCOMP_MAJMIN_HT0 80 // Major-Minor jump algorithm (-4 to +3, with transparency)
84 #define BMCOMP_MAJMIN_HT4 84
85 #define BMCOMP_MAJMIN_HT5 85
86 #define BMCOMP_MAJMIN_HT6 86
87 #define BMCOMP_MAJMIN_HT7 87
88 #define BMCOMP_MAJMIN_HT8 88
89 
90 #define BMCOMP_RMAJMIN_H0 100 // Run Major-Minor jump algorithm (-4 to +3)
91 #define BMCOMP_RMAJMIN_H4 104
92 #define BMCOMP_RMAJMIN_H5 105
93 #define BMCOMP_RMAJMIN_H6 106
94 #define BMCOMP_RMAJMIN_H7 107
95 #define BMCOMP_RMAJMIN_H8 108
96 
97 #define BMCOMP_RMAJMIN_HT0 120 // Run Major-Minor jump algorithm (-4 to +3, with transparency)
98 #define BMCOMP_RMAJMIN_HT4 124
99 #define BMCOMP_RMAJMIN_HT5 125
100 #define BMCOMP_RMAJMIN_HT6 126
101 #define BMCOMP_RMAJMIN_HT7 127
102 #define BMCOMP_RMAJMIN_HT8 128
103 
104 #define BMCOMP_NMAJMIN_H0 130 // New Major-Minor jump algorithm (-4 to +4)
105 #define BMCOMP_NMAJMIN_H4 134
106 #define BMCOMP_NMAJMIN_H5 135
107 #define BMCOMP_NMAJMIN_H6 136
108 #define BMCOMP_NMAJMIN_H7 137
109 #define BMCOMP_NMAJMIN_H8 138
110 
111 #define BMCOMP_NMAJMIN_HT0 140 // New Major-Minor jump algorithm (-4 to +4, with transparency)
112 #define BMCOMP_NMAJMIN_HT4 144
113 #define BMCOMP_NMAJMIN_HT5 145
114 #define BMCOMP_NMAJMIN_HT6 146
115 #define BMCOMP_NMAJMIN_HT7 147
116 #define BMCOMP_NMAJMIN_HT8 148
117 
118 #define BMCOMP_TPIX256 149 // Transparent raw pixels
119 
120 #define BMCOMP_SOLID_COLOR_FILL 150
121 
122 #define BMCOMP_CUSTOM_RU_TR 143
123 
124 
125 enum HerculesDimensions {
126  kHercWidth = 720,
127  kHercHeight = 350
128 };
129 
131 enum {
132  kNormalCameraMode = 1,
133  kFollowActorCameraMode = 2,
134  kPanningCameraMode = 3
135 };
136 
138 struct CameraData {
139  Common::Point _cur;
140  Common::Point _dest;
141  Common::Point _accel;
142  Common::Point _last;
143  int _leftTrigger, _rightTrigger;
144  byte _follows, _mode;
145  bool _movingToActor;
146 
147  void reset() {
148  _cur.x = _cur.y = 0;
149  _dest.x = _dest.y = 0;
150  _accel.x = _accel.y = 0;
151  _last.x = _last.y = 0;
152  _leftTrigger = 0;
153  _rightTrigger = 0;
154  _follows = 0;
155  _mode = 0;
156  _movingToActor = 0;
157  }
158 };
159 
162  kMainVirtScreen = 0, // The 'stage'
163  kTextVirtScreen = 1, // In V0-V3 games: the area where text is printed
164  kVerbVirtScreen = 2, // The verb area
165  kBannerVirtScreen = 3 // The centered pause/restart/message banner area
166 };
167 
191 
196  uint16 topline;
197 
203  uint16 xstart;
204 
214 
223  byte *backBuf;
224 
232  uint16 tdirty[80 + 1];
233 
241  uint16 bdirty[80 + 1];
242 
243  void clear() {
244  // FIXME: Call Graphics::Surface clear / constructor?
245  number = kMainVirtScreen;
246  topline = 0;
247  xstart = 0;
248  hasTwoBuffers = false;
249  backBuf = nullptr;
250  for (uint i = 0; i < ARRAYSIZE(tdirty); i++) tdirty[i] = 0;
251  for (uint i = 0; i < ARRAYSIZE(bdirty); i++) bdirty[i] = 0;
252  }
253 
262  void setDirtyRange(int top, int bottom) {
263  for (int i = 0; i < 80 + 1; i++) {
264  tdirty[i] = top;
265  bdirty[i] = bottom;
266  }
267  }
268 
269  byte *getPixels(int x, int y) const {
270  return (byte *)pixels + y * pitch + (xstart + x) * format.bytesPerPixel;
271  }
272 
273  byte *getBackPixels(int x, int y) const {
274  return (byte *)backBuf + y * pitch + (xstart + x) * format.bytesPerPixel;
275  }
276 };
277 
279 struct ColorCycle {
280  uint16 delay;
281  uint16 counter;
282  uint16 flags;
283  byte start;
284  byte end;
285 };
286 
287 struct StripTable;
288 
289 #define CHARSET_MASK_TRANSPARENCY 0xFD
290 #define CHARSET_MASK_TRANSPARENCY_32 0xFDFDFDFD
291 
292 class Gdi {
293 protected:
294  ScummEngine *_vm;
295 
296  byte _paletteMod;
297  byte *_roomPalette;
298  byte _transparentColor;
299  byte _decomp_shr, _decomp_mask;
300  uint32 _vertStripNextInc;
301 
302  bool _zbufferDisabled;
303 
306 
307 public:
309  bool _distaff;
310 
311  int _numZBuffer;
312  int _imgBufOffs[8];
313  int32 _numStrips;
314 
315 protected:
316  /* Bitmap decompressors */
317  bool decompressBitmap(byte *dst, int dstPitch, const byte *src, int numLinesToProcess);
318 
319  void drawStripEGA(byte *dst, int dstPitch, const byte *src, int height) const;
320 
321  void drawStripComplex(byte *dst, int dstPitch, const byte *src, int height, const bool transpCheck) const;
322  void drawStripBasicH(byte *dst, int dstPitch, const byte *src, int height, const bool transpCheck) const;
323  void drawStripBasicV(byte *dst, int dstPitch, const byte *src, int height, const bool transpCheck) const;
324 
325  void drawStripRaw(byte *dst, int dstPitch, const byte *src, int height, const bool transpCheck) const;
326  void unkDecode8(byte *dst, int dstPitch, const byte *src, int height) const;
327  void unkDecode9(byte *dst, int dstPitch, const byte *src, int height) const;
328  void unkDecode10(byte *dst, int dstPitch, const byte *src, int height) const;
329  void unkDecode11(byte *dst, int dstPitch, const byte *src, int height) const;
330  void drawStrip3DO(byte *dst, int dstPitch, const byte *src, int height, const bool transpCheck) const;
331 
332  void drawStripHE(byte *dst, int dstPitch, const byte *src, int width, int height, const bool transpCheck) const;
333  virtual void writeRoomColor(byte *dst, byte color) const;
334 
335  /* Mask decompressors */
336  void decompressMaskImgOr(byte *dst, const byte *src, int height) const;
337  void decompressMaskImg(byte *dst, const byte *src, int height) const;
338 
339  /* Misc */
340  int getZPlanes(const byte *smap_ptr, const byte *zplane_list[9], bool bmapImage) const;
341 
342  virtual bool drawStrip(byte *dstPtr, VirtScreen *vs,
343  int x, int y, const int width, const int height,
344  int stripnr, const byte *smap_ptr);
345 
346  virtual void decodeMask(int x, int y, const int width, const int height,
347  int stripnr, int numzbuf, const byte *zplane_list[9],
348  bool transpStrip, byte flag);
349 
350  virtual void prepareDrawBitmap(const byte *ptr, VirtScreen *vs,
351  const int x, const int y, const int width, const int height,
352  int stripnr, int numstrip);
353 
354 public:
355  Gdi(ScummEngine *vm);
356  virtual ~Gdi();
357 
358  virtual void setRenderModeColorMap(const byte *map) {}
359  virtual byte remapColorToRenderMode(byte col) const { return col; }
360 
361  virtual void init();
362  virtual void roomChanged(byte *roomptr);
363  virtual void loadTiles(byte *roomptr);
364  void setTransparentColor(byte transparentColor) { _transparentColor = transparentColor; }
365 
366  void drawBitmap(const byte *ptr, VirtScreen *vs, int x, int y, const int width, const int height,
367  int stripnr, int numstrip, byte flag);
368 
369 #ifdef ENABLE_HE
370  void drawBMAPBg(const byte *ptr, VirtScreen *vs);
371  void drawBMAPObject(const byte *ptr, VirtScreen *vs, int obj, int x, int y, int w, int h);
372 #endif
373 
374  byte *getMaskBuffer(int x, int y, int z);
375  void disableZBuffer() { _zbufferDisabled = true; }
376  void enableZBuffer() { _zbufferDisabled = false; }
377 
378  void resetBackground(int top, int bottom, int strip);
379 
380  enum DrawBitmapFlags {
381  dbAllowMaskOr = 1 << 0,
382  dbDrawMaskOnAll = 1 << 1,
383  dbObjectMode = 2 << 2
384  };
385 };
386 
387 class GdiHE : public Gdi {
388 protected:
389  const byte *_tmskPtr;
390 
391 protected:
392  void decompressTMSK(byte *dst, const byte *tmsk, const byte *src, int height) const;
393 
394  void decodeMask(int x, int y, const int width, const int height,
395  int stripnr, int numzbuf, const byte *zplane_list[9],
396  bool transpStrip, byte flag) override;
397 
398  void prepareDrawBitmap(const byte *ptr, VirtScreen *vs,
399  const int x, const int y, const int width, const int height,
400  int stripnr, int numstrip) override;
401 public:
402  GdiHE(ScummEngine *vm);
403 };
404 
405 class GdiNES : public Gdi {
406 protected:
407  struct {
408  byte nametable[16][64], nametableObj[16][64];
409  byte attributes[64], attributesObj[64];
410  byte masktable[16][8], masktableObj[16][8];
411  int objX;
412  bool hasmask;
413  } _NES;
414 
415 protected:
416  void decodeNESGfx(const byte *room);
417  void decodeNESObject(const byte *ptr, int xpos, int ypos, int width, int height);
418 
419  void drawStripNES(byte *dst, byte *mask, int dstPitch, int stripnr, int top, int height);
420  void drawStripNESMask(byte *dst, int stripnr, int top, int height) const;
421 
422  bool drawStrip(byte *dstPtr, VirtScreen *vs,
423  int x, int y, const int width, const int height,
424  int stripnr, const byte *smap_ptr) override;
425 
426  void decodeMask(int x, int y, const int width, const int height,
427  int stripnr, int numzbuf, const byte *zplane_list[9],
428  bool transpStrip, byte flag) override;
429 
430  void prepareDrawBitmap(const byte *ptr, VirtScreen *vs,
431  const int x, const int y, const int width, const int height,
432  int stripnr, int numstrip) override;
433 
434 public:
435  GdiNES(ScummEngine *vm);
436 
437  void roomChanged(byte *roomptr) override;
438 };
439 
440 #ifdef USE_RGB_COLOR
441 class GdiPCEngine : public Gdi {
442 protected:
443  struct {
444  uint16 nametable[4096], nametableObj[512];
445  byte colortable[4096], colortableObj[512];
446  uint16 masktable[4096], masktableObj[512];
447  int maskIDSize;
448  int numTiles;
449  int numMasks;
450  byte *roomTiles, *staffTiles;
451  byte *masks;
452  } _PCE;
453 
454 protected:
455  void decodePCEngineGfx(const byte *room);
456  void decodeStrip(const byte *ptr, uint16 *tiles, byte *colors, uint16 *masks, int numRows, bool isObject);
457  void setTileData(byte *tile, int index, byte byte0, byte byte1);
458  void decodePCEngineTileData(const byte *ptr);
459  void decodePCEngineMaskData(const byte *ptr);
460  void decodePCEngineObject(const byte *ptr, int xpos, int ypos, int width, int height);
461 
462  void drawStripPCEngine(byte *dst, byte *mask, int dstPitch, int stripnr, int top, int height);
463  void drawStripPCEngineMask(byte *dst, int stripnr, int top, int height) const;
464 
465  bool drawStrip(byte *dstPtr, VirtScreen *vs,
466  int x, int y, const int width, const int height,
467  int stripnr, const byte *smap_ptr) override;
468 
469  void decodeMask(int x, int y, const int width, const int height,
470  int stripnr, int numzbuf, const byte *zplane_list[9],
471  bool transpStrip, byte flag) override;
472 
473  void prepareDrawBitmap(const byte *ptr, VirtScreen *vs,
474  const int x, const int y, const int width, const int height,
475  int stripnr, int numstrip) override;
476 
477 public:
478  GdiPCEngine(ScummEngine *vm);
479  ~GdiPCEngine() override;
480 
481  void loadTiles(byte *roomptr) override;
482  void roomChanged(byte *roomptr) override;
483 };
484 #endif
485 
486 class GdiV1 : public Gdi {
487 protected:
489  struct {
490  byte colors[4];
491  byte charMap[2048], objectMap[2048], picMap[4096], colorMap[4096];
492  byte maskMap[4096], maskChar[4096];
493  } _V1;
494 
495  const byte *_colorMap = 0;
496 
497 protected:
498  void decodeV1Gfx(const byte *src, byte *dst, int size) const;
499 
500  void drawStripV1Object(byte *dst, int dstPitch, int stripnr, int width, int height);
501  void drawStripV1Background(byte *dst, int dstPitch, int stripnr, int height);
502  void drawStripV1Mask(byte *dst, int stripnr, int width, int height) const;
503 
504  bool drawStrip(byte *dstPtr, VirtScreen *vs,
505  int x, int y, const int width, const int height,
506  int stripnr, const byte *smap_ptr) override;
507 
508  void decodeMask(int x, int y, const int width, const int height,
509  int stripnr, int numzbuf, const byte *zplane_list[9],
510  bool transpStrip, byte flag) override;
511 
512  void prepareDrawBitmap(const byte *ptr, VirtScreen *vs,
513  const int x, const int y, const int width, const int height,
514  int stripnr, int numstrip) override;
515 
516 public:
517  GdiV1(ScummEngine *vm);
518 
519  void setRenderModeColorMap(const byte *map) override;
520  byte remapColorToRenderMode(byte col) const override;
521 
522  void roomChanged(byte *roomptr) override;
523 };
524 
525 class GdiV2 : public Gdi {
526 protected:
528  StripTable *_roomStrips;
529 
530 protected:
531  StripTable *generateStripTable(const byte *src, int width, int height, StripTable *table) const;
532 
533  bool drawStrip(byte *dstPtr, VirtScreen *vs,
534  int x, int y, const int width, const int height,
535  int stripnr, const byte *smap_ptr) override;
536 
537  void decodeMask(int x, int y, const int width, const int height,
538  int stripnr, int numzbuf, const byte *zplane_list[9],
539  bool transpStrip, byte flag) override;
540 
541  void prepareDrawBitmap(const byte *ptr, VirtScreen *vs,
542  const int x, const int y, const int width, const int height,
543  int stripnr, int numstrip) override;
544 
545 public:
546  GdiV2(ScummEngine *vm);
547  ~GdiV2() override;
548 
549  void roomChanged(byte *roomptr) override;
550 };
551 
552 #ifdef USE_RGB_COLOR
553 class GdiHE16bit : public GdiHE {
554 protected:
555  void writeRoomColor(byte *dst, byte color) const override;
556 public:
557  GdiHE16bit(ScummEngine *vm);
558 };
559 #endif
560 
561 #ifndef DISABLE_TOWNS_DUAL_LAYER_MODE
562 // Helper class for FM-Towns output (required for specific hardware effects like switching graphics layers on and off).
563 class TownsScreen {
564 public:
565  enum {
566  kDirtyRectsMax = 50,
567  kFullRedraw = (kDirtyRectsMax + 1)
568  };
569 public:
570  TownsScreen(OSystem *system);
571  ~TownsScreen();
572 
573  void setupLayer(int layer, int width, int height, int scaleW, int scaleH, int numCol, void *srcPal = 0);
574  void clearLayer(int layer);
575  void fillRect(int layer, int x, int y, int w, int h, int col);
576  void swapAreaWithBuffer(int layer, int x, int y, int w, int h, byte *buffer);
577  void addDirtyRect(int x, int y, int w, int h);
578  void toggleLayers(int flags);
579  void scrollLayer(int layer, int offset, int top, int bottom, bool fast);
580  void update();
581  bool isScrolling(int layer, int direction, int threshold = 0) const {
582  return (layer & ~1) ? false :
583  (direction == 0 ? (_layers[layer].scrollRemainder != threshold) :
584  (direction == 1 ? (_layers[layer].scrollRemainder > threshold) : (_layers[layer].scrollRemainder < threshold)));
585  }
586 
587  uint8 *getLayerPixels(int layer, int x, int y) const;
588  int getLayerPitch(int layer) const { assert (layer >= 0 && layer < 2); return _layers[layer].pitch; }
589  int getLayerWidth(int layer) const { assert (layer >= 0 && layer < 2); return _layers[layer].width; }
590  int getLayerHeight(int layer) const { assert (layer >= 0 && layer < 2); return _layers[layer].height; }
591  int getLayerBpp(int layer) const { assert (layer >= 0 && layer < 2); return _layers[layer].bpp; }
592  int getLayerScaleW(int layer) const { assert (layer >= 0 && layer < 2); return _layers[layer].scaleW; }
593  int getLayerScaleH(int layer) const { assert (layer >= 0 && layer < 2); return _layers[layer].scaleH; }
594 
595 private:
596  struct TownsScreenLayer {
597  uint8 *pixels = nullptr;
598  uint8 *palette = nullptr;
599  int pitch = 0;
600  int width = 0;
601  int height = 0;
602  int bpp = 0;
603  int numCol = 0;
604  uint16 hScroll = 0;
605  uint8 scaleW = 0;
606  uint8 scaleH = 0;
607  int scrollRemainder = 0;
608  bool onBottom = false;
609  bool enabled = false;
610  bool ready = false;
611  uint16 *bltTmpPal= nullptr;
612  } _layers[2];
613 
614  template<typename dstPixelType, typename srcPixelType, int scaleW, int scaleH, bool col4bit> void transferRect(uint8 *dst, int pitch, TownsScreenLayer *l, int x, int y, int w, int h);
615  template<typename dstPixelType> void updateScreenBuffer();
616 
617 #ifdef USE_RGB_COLOR
618  void update16BitPalette();
619  uint16 calc16BitColor(const uint8 *palEntry);
620 #endif
621 
622  int _height;
623  int _width;
624  bool _semiSmoothScroll;
625  Graphics::PixelFormat _pixelFormat;
626 
627  int _numDirtyRects;
628  Common::List<Common::Rect> _dirtyRects;
629  OSystem *_system;
630 };
631 #endif // DISABLE_TOWNS_DUAL_LAYER_MODE
632 
633 class MajMinCodec {
634 public:
635 
636  struct {
637  bool repeatMode;
638  int repeatCount;
639  byte color;
640  byte shift;
641  uint16 bits;
642  byte numBits;
643  const byte *dataPtr;
644  byte buffer[336];
645  } _majMinData;
646 
647  void setupBitReader(byte shift, const byte *src);
648  void skipData(int32 numSkip);
649  void decodeLine(byte *buf, int32 numBytes, int32 dir);
650  inline byte readBits(byte n);
651 };
652 
653 } // End of namespace Scumm
654 
655 #endif
#define ARRAYSIZE(x)
Definition: util.h:91
VirtScreenNumber
Definition: gfx.h:161
Definition: gfx.h:563
Definition: surface.h:67
bool _distaff
Definition: gfx.h:309
void setDirtyRange(int top, int bottom)
Definition: gfx.h:262
bool _objectMode
Definition: gfx.h:305
Definition: gfx.h:138
Definition: pixelformat.h:138
StripTable * _roomStrips
Definition: gfx.h:528
uint16 xstart
Definition: gfx.h:203
byte * backBuf
Definition: gfx.h:223
uint16 topline
Definition: gfx.h:196
Definition: scumm.h:519
Definition: gfx.h:185
Definition: gfx.h:486
Definition: gfx.h:405
Definition: rect.h:45
Definition: gfx.h:387
VirtScreenNumber number
Definition: gfx.h:190
Definition: gfx.h:525
int16 x
Definition: rect.h:46
Definition: gfx.h:292
int16 y
Definition: rect.h:47
Definition: gfx.h:633
Definition: system.h:161
bool hasTwoBuffers
Definition: gfx.h:213
Definition: actor.h:30
Definition: gfx.h:279