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 
36 namespace Sci {
37 
38 enum {
39  SCI_SCREEN_UPSCALEDMAXHEIGHT = 200,
40  SCI_SCREEN_UPSCALEDMAXWIDTH = 320
41 };
42 
43 enum GfxScreenUpscaledMode {
44  GFX_SCREEN_UPSCALED_DISABLED = 0,
45  GFX_SCREEN_UPSCALED_480x300 = 1,
46  GFX_SCREEN_UPSCALED_640x400 = 2
47 };
48 
49 enum 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 
56 enum {
57  DITHERED_BG_COLORS_SIZE = 256
58 };
59 
60 class GfxDriver;
61 
70 class GfxScreen {
71 public:
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
100 private:
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 
104 public:
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 
164 private:
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
255 public:
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
void putPixelOnDisplay(int16 x, int16 y, byte color)
Definition: screen.h:352
Definition: font.h:83
Definition: surface.h:67
void putFontPixel(int16 startingY, int16 x, int16 y, byte color)
Definition: screen.h:381
Definition: korfont.h:42
RenderMode
Definition: rendermode.h:48
Definition: rect.h:144
Definition: resource.h:327
Definition: gfxdrivers.h:37
Definition: rect.h:45
Definition: console.h:28
Definition: helpers.h:269
Definition: screen.h:70