ScummVM API documentation
screen.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 SCI_GRAPHICS_SCREEN_H
23#define SCI_GRAPHICS_SCREEN_H
24
25#include "sci/sci.h"
26#include "sci/graphics/helpers.h"
27#include "sci/graphics/view.h"
28
29#include "graphics/font.h"
30#include "graphics/sjis.h"
31#include "graphics/korfont.h"
32#include "graphics/pixelformat.h"
33
34#include "common/rendermode.h"
35
36namespace Sci {
37
38enum {
39 SCI_SCREEN_UPSCALEDMAXHEIGHT = 200,
40 SCI_SCREEN_UPSCALEDMAXWIDTH = 320
41};
42
43enum GfxScreenUpscaledMode {
44 GFX_SCREEN_UPSCALED_DISABLED = 0,
45 GFX_SCREEN_UPSCALED_480x300 = 1,
46 GFX_SCREEN_UPSCALED_640x400 = 2
47};
48
49enum GfxScreenMasks {
50 GFX_SCREEN_MASK_VISUAL = 1,
51 GFX_SCREEN_MASK_PRIORITY = 2,
52 GFX_SCREEN_MASK_CONTROL = 4,
53 GFX_SCREEN_MASK_ALL = GFX_SCREEN_MASK_VISUAL|GFX_SCREEN_MASK_PRIORITY|GFX_SCREEN_MASK_CONTROL
54};
55
56enum {
57 DITHERED_BG_COLORS_SIZE = 256
58};
59
60class GfxDriver;
61
70class GfxScreen {
71public:
72 GfxScreen(ResourceManager *resMan, Common::RenderMode renderMode);
73 ~GfxScreen();
74
75 uint16 getWidth() { return _width; }
76 uint16 getHeight() { return _height; }
77 uint16 getScriptWidth() { return _scriptWidth; }
78 uint16 getScriptHeight() { return _scriptHeight; }
79 uint16 getDisplayWidth() { return _displayWidth; }
80 uint16 getDisplayHeight() { return _displayHeight; }
81 byte getColorWhite() { return _colorWhite; }
82 byte getColorDefaultVectorData() { return _colorDefaultVectorData; }
83
84 void clearForRestoreGame();
85 void copyToScreen();
86 void kernelSyncWithFramebuffer();
87 void copyRectToScreen(const Common::Rect &rect);
88 void copyHiResRectToScreen(const byte *srcBuffer, int pitch, int x, int y, int w, int h, const byte *colorMap);
89 void copyRectToScreen(const Common::Rect &rect, int16 x, int16 y);
90
91 // functions to manipulate a backup copy of the screen (for transitions)
92 void bakCreateBackup();
93 void bakCopyRectToScreen(const Common::Rect &rect, int16 x, int16 y);
94 void bakDiscard();
95
96 // video frame displaying
97 void copyVideoFrameToScreen(const byte *buffer, int pitch, const Common::Rect &rect);
98
99 // Vector drawing
100private:
101 void vectorPutLinePixel(int16 x, int16 y, byte drawMask, byte color, byte priority, byte control);
102 void vectorPutLinePixel480x300(int16 x, int16 y, byte drawMask, byte color, byte priority, byte control);
103
104public:
105 void vectorAdjustLineCoordinates(int16 *left, int16 *top, int16 *right, int16 *bottom, byte drawMask, byte color, byte priority, byte control);
106 byte vectorIsFillMatch(int16 x, int16 y, byte screenMask, byte checkForColor, byte checkForPriority, byte checkForControl, bool isEGA);
107
108 byte getDrawingMask(byte color, byte prio, byte control);
109 void drawLine(Common::Point startPoint, Common::Point endPoint, byte color, byte prio, byte control);
110 void drawLine(int16 left, int16 top, int16 right, int16 bottom, byte color, byte prio, byte control) {
111 drawLine(Common::Point(left, top), Common::Point(right, bottom), color, prio, control);
112 }
113
114 GfxScreenUpscaledMode getUpscaledHires() const {
115 return _upscaledHires;
116 }
117
118 bool isUnditheringEnabled() const {
119 return _unditheringEnabled;
120 }
121 void enableUndithering(bool flag);
122
123 void putMacChar(const Graphics::Font *commonFont, int16 x, int16 y, uint16 chr, byte color);
124 void putKanjiChar(Graphics::FontSJIS *commonFont, int16 x, int16 y, uint16 chr, byte color);
125 void putHangulChar(Graphics::FontKorean *commonFont, int16 x, int16 y, uint16 chr, byte color);
126
127 int bitsGetDataSize(Common::Rect rect, byte mask);
128 void bitsSave(Common::Rect rect, byte mask, byte *memoryPtr);
129 void bitsGetRect(const byte *memoryPtr, Common::Rect *destRect);
130 void bitsRestore(const byte *memoryPtr);
131
132 void scale2x(const SciSpan<const byte> &src, SciSpan<byte> &dst, int16 srcWidth, int16 srcHeight, byte bytesPerPixel = 1);
133
134 void adjustToUpscaledCoordinates(int16 &y, int16 &x);
135 void adjustBackUpscaledCoordinates(int16 &y, int16 &x);
136
137 void dither(bool addToFlag);
138
139 // Force a color combination as a dithered color
140 void ditherForceDitheredColor(byte color);
141 int16 *unditherGetDitheredBgColors();
142
143 void debugShowMap(int mapNo);
144
145 int _picNotValid; // possible values 0, 1 and 2
146 int _picNotValidSci11; // another variable that is used by kPicNotValid in sci1.1
147
148 int16 kernelPicNotValid(int16 newPicNotValid);
149 void kernelShakeScreen(uint16 shakeCount, uint16 direction);
150
151 void setFontIsUpscaled(bool isUpscaled) { _fontIsUpscaled = isUpscaled; }
152 bool fontIsUpscaled() const { return _fontIsUpscaled; }
153
154 void grabPalette(byte *buffer, uint start, uint num) const;
155 void setPalette(const byte *buffer, uint start, uint num, bool update = true);
156
157 byte getCurPaletteMapValue() const { return _curPaletteMapValue; }
158 void setCurPaletteMapValue(byte val) { _curPaletteMapValue = val; }
159 void setPaletteMods(const PaletteMod *mods, unsigned int count);
160 bool paletteModsEnabled() const { return _paletteModsEnabled; }
161
162 GfxDriver *gfxDriver() const { return _gfxDrv; }
163
164private:
165 uint16 _width;
166 uint16 _height;
167 uint _pixels;
168 uint16 _scriptWidth;
169 uint16 _scriptHeight;
170 uint16 _displayWidth;
171 uint16 _displayHeight;
172 uint _displayPixels;
173
174 byte _colorWhite;
175 byte _colorDefaultVectorData;
176
177 void bitsRestoreScreen(Common::Rect rect, const byte *&memoryPtr, byte *screen, uint16 screenWidth);
178 void bitsRestoreDisplayScreen(Common::Rect rect, const byte *&memoryPtr, byte *screen);
179 void bitsSaveScreen(Common::Rect rect, const byte *screen, uint16 screenWidth, byte *&memoryPtr);
180 void bitsSaveDisplayScreen(Common::Rect rect, const byte *screen, byte *&memoryPtr);
181
182 void setShakePos(uint16 shakeXOffset, uint16 shakeYOffset);
183
187 bool _unditheringEnabled;
188 int16 _ditheredPicColors[DITHERED_BG_COLORS_SIZE];
189
190 // These screens have the real resolution of the game engine (320x200 for
191 // SCI0/SCI1/SCI11 PC games, other resolutions on Mac). SCI0 games will be
192 // dithered in here at any time.
193 byte *_visualScreen;
194 byte *_priorityScreen;
195 byte *_controlScreen;
196
202 byte *_displayScreen;
203 Graphics::Surface _displayScreenSurface;
204
209 GfxDriver *_gfxDrv;
210
211 // For RGB per-view/pic palette mods
212 byte *_paletteMapScreen;
213 byte _curPaletteMapValue;
214 PaletteMod _paletteMods[256];
215 bool _paletteModsEnabled;
216
217 byte *_backupScreen; // for bak* functions
218
219 void displayRect(const Common::Rect &rect, int x, int y);
220
221 ResourceManager *_resMan;
222
227 byte *_activeScreen;
228
233 GfxScreenUpscaledMode _upscaledHires;
234
238 byte *_hiresGlyphBuffer;
239
244 int16 _upscaledHeightMapping[SCI_SCREEN_UPSCALEDMAXHEIGHT + 1];
245 int16 _upscaledWidthMapping[SCI_SCREEN_UPSCALEDMAXWIDTH + 1];
246
251 bool _fontIsUpscaled;
252
253
254 // pixel related code, in header so that it can be inlined for performance
255public:
256 void putPixel(int16 x, int16 y, byte drawMask, byte color, byte priority, byte control) {
257 if (_upscaledHires == GFX_SCREEN_UPSCALED_480x300) {
258 putPixel480x300(x, y, drawMask, color, priority, control);
259 return;
260 }
261
262 // Set pixel for visual, priority and control map directly, those are not upscaled
263 const int offset = y * _width + x;
264
265 if (drawMask & GFX_SCREEN_MASK_VISUAL) {
266 _visualScreen[offset] = color;
267 if (_paletteMapScreen)
268 _paletteMapScreen[offset] = _curPaletteMapValue;
269
270 switch (_upscaledHires) {
271 case GFX_SCREEN_UPSCALED_DISABLED:
272 _displayScreen[offset] = color;
273 break;
274
275 case GFX_SCREEN_UPSCALED_640x400:
276 putScaledPixelOnDisplay(x, y, color);
277 break;
278 default:
279 break;
280 }
281 }
282 if (drawMask & GFX_SCREEN_MASK_PRIORITY) {
283 _priorityScreen[offset] = priority;
284 }
285 if (drawMask & GFX_SCREEN_MASK_CONTROL) {
286 _controlScreen[offset] = control;
287 }
288 }
289
290 void putPixel480x300(int16 x, int16 y, byte drawMask, byte color, byte priority, byte control) {
291 const int offset = ((y * 3) / 2 * _width) + ((x * 3) / 2);
292
293 // All maps are upscaled
294 // TODO: figure out, what Sierra exactly did on Mac for these games
295 if (drawMask & GFX_SCREEN_MASK_VISUAL) {
296 putPixel480x300Worker(x, y, offset, _visualScreen, color);
297 putPixel480x300Worker(x, y, offset, _displayScreen, color);
298 }
299 if (drawMask & GFX_SCREEN_MASK_PRIORITY) {
300 putPixel480x300Worker(x, y, offset, _priorityScreen, priority);
301 }
302 if (drawMask & GFX_SCREEN_MASK_CONTROL) {
303 putPixel480x300Worker(x, y, offset, _controlScreen, control);
304 }
305 }
306 void putPixel480x300Worker(int16 x, int16 y, int offset, byte *screen, byte byteToSet) {
307 screen[offset] = byteToSet;
308 if (x & 1)
309 screen[offset + 1] = byteToSet;
310 if (y & 1)
311 screen[offset + _width] = byteToSet;
312 if ((x & 1) && (y & 1))
313 screen[offset + _width + 1] = byteToSet;
314 }
315
316 // This is called from vector drawing to put a pixel at a certain location
317 void vectorPutPixel(int16 x, int16 y, byte drawMask, byte color, byte priority, byte control) {
318 switch (_upscaledHires) {
319 case GFX_SCREEN_UPSCALED_640x400:
320 // For regular upscaled modes forward to the regular putPixel
321 putPixel(x, y, drawMask, color, priority, control);
322 return;
323 break;
324
325 default:
326 break;
327 }
328
329 // For non-upscaled mode and 480x300 Mac put pixels directly
330 int offset = y * _width + x;
331
332 if (drawMask & GFX_SCREEN_MASK_VISUAL) {
333 _visualScreen[offset] = color;
334 _displayScreen[offset] = color;
335 if (_paletteMapScreen)
336 _paletteMapScreen[offset] = _curPaletteMapValue;
337
338 }
339 if (drawMask & GFX_SCREEN_MASK_PRIORITY) {
340 _priorityScreen[offset] = priority;
341 }
342 if (drawMask & GFX_SCREEN_MASK_CONTROL) {
343 _controlScreen[offset] = control;
344 }
345 }
346
352 void putPixelOnDisplay(int16 x, int16 y, byte color) {
353 int offset = y * _displayWidth + x;
354 _displayScreen[offset] = color;
355 }
356
357 // Upscales a pixel and puts it on display screen only
358 void putScaledPixelOnDisplay(int16 x, int16 y, byte color) {
359 int displayOffset = 0;
360
361 switch (_upscaledHires) {
362 case GFX_SCREEN_UPSCALED_640x400:
363 displayOffset = (y * 2) * _displayWidth + x * 2; // straight 1 pixel -> 2 mapping
364
365 _displayScreen[displayOffset] = color;
366 _displayScreen[displayOffset + 1] = color;
367 _displayScreen[displayOffset + _displayWidth] = color;
368 _displayScreen[displayOffset + _displayWidth + 1] = color;
369 break;
370
371 default:
372 break;
373 }
374 }
375
381 void putFontPixel(int16 startingY, int16 x, int16 y, byte color) {
382 int16 actualY = startingY + y;
383 if (_fontIsUpscaled) {
384 // Do not scale ourselves, but put it on the display directly
385 putPixelOnDisplay(x, actualY, color);
386 } else {
387 if (_upscaledHires == GFX_SCREEN_UPSCALED_480x300) {
388 putPixel480x300(x, actualY, GFX_SCREEN_MASK_VISUAL, color, 0, 0);
389 return;
390 }
391
392 int offset = actualY * _width + x;
393
394 _visualScreen[offset] = color;
395 switch (_upscaledHires) {
396 case GFX_SCREEN_UPSCALED_DISABLED:
397 _displayScreen[offset] = color;
398 break;
399 case GFX_SCREEN_UPSCALED_640x400: {
400 // to 1-> 4 pixels upscaling for all of those, so that fonts won't look weird
401 int displayOffset = (_upscaledHeightMapping[startingY] + y * 2) * _displayWidth + x * 2;
402 _displayScreen[displayOffset] = color;
403 _displayScreen[displayOffset + 1] = color;
404 displayOffset += _displayWidth;
405 _displayScreen[displayOffset] = color;
406 _displayScreen[displayOffset + 1] = color;
407 break;
408 }
409 default:
410 putScaledPixelOnDisplay(x, actualY, color);
411 break;
412 }
413 }
414 }
415
416 byte getPixel(byte *screen, int16 x, int16 y) {
417 switch (_upscaledHires) {
418 case GFX_SCREEN_UPSCALED_480x300: {
419 int offset = ((y * 3) / 2) * _width + ((y * 3) / 2);
420
421 return screen[offset];
422 break;
423 }
424 default:
425 break;
426 }
427 return screen[y * _width + x];
428 }
429
430 byte getVisual(int16 x, int16 y) {
431 return getPixel(_visualScreen, x, y);
432 }
433 byte getPriority(int16 x, int16 y) {
434 return getPixel(_priorityScreen, x, y);
435 }
436 byte getControl(int16 x, int16 y) {
437 return getPixel(_controlScreen, x, y);
438 }
439
440 // Vector related public code - in here, so that it can be inlined
441 byte vectorGetPixel(byte *screen, int16 x, int16 y) {
442 return screen[y * _width + x];
443 }
444
445 byte vectorGetVisual(int16 x, int16 y) {
446 return vectorGetPixel(_visualScreen, x, y);
447 }
448 byte vectorGetPriority(int16 x, int16 y) {
449 return vectorGetPixel(_priorityScreen, x, y);
450 }
451 byte vectorGetControl(int16 x, int16 y) {
452 return vectorGetPixel(_controlScreen, x, y);
453 }
454
455 void vectorAdjustCoordinate(int16 *x, int16 *y) {
456 switch (_upscaledHires) {
457 case GFX_SCREEN_UPSCALED_480x300:
458 *x = (*x * 3) / 2;
459 *y = (*y * 3) / 2;
460 break;
461 default:
462 break;
463 }
464 }
465};
466
467} // End of namespace Sci
468
469#endif // SCI_GRAPHICS_SCREEN_H
Definition: font.h:83
Definition: korfont.h:42
Definition: gfxdriver.h:39
Definition: screen.h:70
void putPixelOnDisplay(int16 x, int16 y, byte color)
Definition: screen.h:352
void putFontPixel(int16 startingY, int16 x, int16 y, byte color)
Definition: screen.h:381
Definition: resource.h:327
Definition: util.h:251
RenderMode
Definition: rendermode.h:48
Definition: console.h:28
Definition: rect.h:144
Definition: rect.h:536
Definition: surface.h:67
Definition: helpers.h:269