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 // Graphics maniuplation routines - private header file
23 
24 #ifndef SAGA_GFX_H
25 #define SAGA_GFX_H
26 
27 #include "common/rect.h"
28 #include "graphics/surface.h"
29 
30 namespace Saga {
31 
32 using Common::Point;
33 using Common::Rect;
34 
35 enum CursorType {
36  kCursorNormal,
37  kCursorBusy
38 };
39 
40 struct ClipData {
41  // input members
42  Rect sourceRect;
43  Rect destRect;
44  Point destPoint;
45 
46  // output members
47  Point drawSource;
48  Point drawDest;
49  int drawWidth;
50  int drawHeight;
51 
52  bool calcClip() {
53  Common::Rect s;
54 
55  // Adjust the rect to draw to its screen coordinates
56  s = sourceRect;
57  s.left += destPoint.x;
58  s.right += destPoint.x;
59  s.top += destPoint.y;
60  s.bottom += destPoint.y;
61 
62  s.clip(destRect);
63 
64  if ((s.width() <= 0) || (s.height() <= 0)) {
65  return false;
66  }
67 
68  drawSource.x = s.left - sourceRect.left - destPoint.x;
69  drawSource.y = s.top - sourceRect.top - destPoint.y;
70  drawDest.x = s.left;
71  drawDest.y = s.top;
72  drawWidth = s.width();
73  drawHeight = s.height();
74 
75  return true;
76  }
77 };
78 
79 #include "common/pack-start.h" // START STRUCT PACKING
80 
81 struct PalEntry {
82  byte red;
83  byte green;
84  byte blue;
85 } PACKED_STRUCT;
86 
87 #include "common/pack-end.h" // END STRUCT PACKING
88 
89 struct Color {
90  int red;
91  int green;
92  int blue;
93  int alpha;
94 };
95 
97 
98  void transitionDissolve(const byte *sourceBuffer, const Common::Rect &sourceRect, int flags, double percent);
99  void drawPalette();
100  void drawPolyLine(const Point *points, int count, int color);
101  void blit(const Common::Rect &destRect, const byte *sourceBuffer);
102 
103  void getRect(Common::Rect &rect) {
104  rect.left = rect.top = 0;
105  rect.right = w;
106  rect.bottom = h;
107  }
108 
109  void drawRect(const Common::Rect &destRect, int color) {
110  Common::Rect rect(w , h);
111  rect.clip(destRect);
112 
113  if (rect.isValidRect()) {
114  fillRect(rect, color);
115  }
116  }
117 
118  void clearRect2x(Common::Rect r) {
119  // This clears a 2x scaled rect (used for Japanese font removal).
120  // The pixels buffer only gets allocated for game versions that actually require it.
121  if (!pixels)
122  return;
123  fillRect(Common::Rect(r.left << 1, r.top << 1, r.right << 1, r.bottom << 1), 0);
124  }
125 };
126 
127 #define PAL_ENTRIES 256
128 
129 #define CURSOR_W 7
130 #define CURSOR_H 7
131 #define CURSOR_PC98_W 16
132 #define CURSOR_PC98_H 16
133 
134 #define CURSOR_ORIGIN_X 4
135 #define CURSOR_ORIGIN_Y 4
136 
137 bool hitTestPoly(const Point *points, unsigned int npoints, const Point& test_point);
138 class SagaEngine;
139 
140 class Gfx {
141 public:
142 
143  Gfx(SagaEngine *vm, OSystem *system, int width, int height);
144  ~Gfx();
145 
146  void initPalette();
147  void setPalette(const PalEntry *pal, bool full = false);
148  void loadECSExtraPalettes();
149  void setPaletteColor(int n, int r, int g, int b);
150  void getCurrentPal(PalEntry *src_pal);
151  void savePalette() { getCurrentPal(_savedPalette); }
152  void restorePalette() { setPalette(_savedPalette, true); }
153  void palToBlack(PalEntry *src_pal, double percent);
154  void blackToPal(PalEntry *src_pal, double percent);
155  void palFade(PalEntry *srcPal, int16 from, int16 to, int16 start, int16 numColors, double percent);
156  void showCursor(bool state);
157  void setCursor(CursorType cursorType = kCursorNormal);
158 
159  // Back buffer access methods. These all take care of adding the necessary dirty rectangles
160  // APART FROM setPixelColor() and getBackBufferPixels()
161 
162  // This method adds a dirty rectangle automatically
163  void drawFrame(const Common::Point &p1, const Common::Point &p2, int color);
164 
165  // This method adds a dirty rectangle automatically
166  void drawRect(const Common::Rect &destRect, int color);
167 
168  // This method adds a dirty rectangle automatically
169  void fillRect(const Common::Rect &destRect, uint32 color);
170 
171  // This method adds a dirty rectangle automatically
172  void drawRegion(const Common::Rect &destRect, const byte *sourceBuffer);
173 
174  // This method does not add a dirty rectangle automatically
175  void drawBgRegion(const Common::Rect &destRect, const byte *sourceBuffer);
176 
177  // Used for testing
178  void drawPalette() {
179  _backBuffer.drawPalette();
180  }
181 
182  // WARNING: This method does not add a dirty rectangle automatically.
183  // Whenever it gets called, the corresponding caller must take care
184  // to add the corresponding dirty rectangle itself
185  void hLine(int x, int y, int x2, uint32 color) {
186  _backBuffer.hLine(x, y, x2, color);
187  // Clear corresponding area of the sjis text layer (if the pixels buffer was actually created)
188  _sjisBackBuffer.clearRect2x(Common::Rect(x, y, x2, y + 1));
189  }
190 
191  // WARNING: This method does not add a dirty rectangle automatically.
192  // Whenever it gets called, the corresponding caller must take care
193  // to add the corresponding dirty rectangle itself
194  void vLine(int x, int y, int y2, uint32 color) {
195  _backBuffer.vLine(x, y, y2, color);
196  // Clear corresponding area of the sjis text layer (if the pixels buffer was actually created)
197  _sjisBackBuffer.clearRect2x(Common::Rect(x, y, x + 1, y2));
198  }
199 
200  // WARNING: This method does not add a dirty rectangle automatically.
201  // Whenever it gets called, the corresponding caller must take care
202  // to add the corresponding dirty rectangle itself
203  void setPixelColor(int x, int y, byte color) {
204  ((byte *)_backBuffer.getBasePtr(x, y))[0] = color;
205  // Clear corresponding area of the sjis text layer (if the pixels buffer was actually created)
206  if (_sjisBackBuffer.getPixels()) {
207  *((uint16 *)_sjisBackBuffer.getBasePtr(x << 1, y << 1)) = 0;
208  *((uint16 *)_sjisBackBuffer.getBasePtr(x << 1, (y << 1) + 1)) = 0;
209  }
210  }
211 
212  // WARNING: This method does not add a dirty rectangle automatically.
213  // Whenever it gets called, the corresponding caller must take care
214  // to add the corresponding dirty rectangle itself
215  void drawPolyLine(const Common::Point *points, int count, int color) {
216  _backBuffer.drawPolyLine(points, count, color);
217  }
218 
219  // WARNING: This method allows direct modification of the back buffer
220  // Whenever it gets called, the corresponding caller must take care
221  // to add the corresponding dirty rectangle itself
222  byte *getBackBufferPixels() {
223  return (byte *)_backBuffer.getPixels();
224  }
225 
226  // Same as getBackBufferPixels(), but for the hires sjis buffer
227  byte *getSJISBackBufferPixels() {
228  return (byte *)_sjisBackBuffer.getPixels();
229  }
230 
231  // Expose the sjis buffer directly. One of the two implementations of Graphics::FontSJIS::drawChar()
232  // allows a Common::Surface as a parameter which makes the rendering a bit nicer compared to using
233  // the raw pixel buffer.
234  Surface &getSJISBackBuffer() {
235  return _sjisBackBuffer;
236  }
237 
238  uint16 getBackBufferWidth() {
239  return _backBuffer.w;
240  }
241 
242  uint16 getSJISBackBufferWidth() {
243  return _sjisBackBuffer.w;
244  }
245 
246  uint16 getBackBufferHeight() {
247  return _backBuffer.h;
248  }
249 
250  uint16 getSJISBackBufferHeight() {
251  return _sjisBackBuffer.h;
252  }
253 
254  uint16 getBackBufferPitch() {
255  return _backBuffer.pitch;
256  }
257 
258  uint16 getSJISBackBufferPitch() {
259  return _sjisBackBuffer.pitch;
260  }
261 
262  void getBackBufferRect(Common::Rect &rect) {
263  _backBuffer.getRect(rect);
264  }
265 
266 private:
267  Surface _backBuffer;
268  Surface _sjisBackBuffer;
269  byte _currentPal[PAL_ENTRIES * 3];
270  OSystem *_system;
271  SagaEngine *_vm;
272 
273  PalEntry _globalPalette[PAL_ENTRIES];
274  PalEntry _savedPalette[PAL_ENTRIES];
275 };
276 
277 } // End of namespace Saga
278 
279 #endif
Definition: saga.h:497
Definition: surface.h:67
Definition: gfx.h:81
int16 right
Definition: rect.h:146
Definition: gfx.h:96
Definition: rect.h:144
Definition: gfx.h:40
Definition: actor.h:34
int16 width() const
Definition: rect.h:191
Definition: gfx.h:89
Definition: rect.h:45
int16 left
Definition: rect.h:145
int16 x
Definition: rect.h:46
bool isValidRect() const
Definition: rect.h:337
int16 y
Definition: rect.h:47
int16 w
Definition: surface.h:71
void clip(const Rect &r)
Definition: rect.h:300
Definition: system.h:161
Definition: gfx.h:140
int16 height() const
Definition: rect.h:192