aboutsummaryrefslogtreecommitdiff
path: root/engines/mohawk/myst_graphics.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/mohawk/myst_graphics.cpp')
-rw-r--r--engines/mohawk/myst_graphics.cpp165
1 files changed, 114 insertions, 51 deletions
diff --git a/engines/mohawk/myst_graphics.cpp b/engines/mohawk/myst_graphics.cpp
index 9ea9f15444..49f97cca63 100644
--- a/engines/mohawk/myst_graphics.cpp
+++ b/engines/mohawk/myst_graphics.cpp
@@ -28,6 +28,7 @@
#include "common/system.h"
#include "common/textconsole.h"
#include "engines/util.h"
+#include "graphics/palette.h"
#include "image/pict.h"
namespace Mohawk {
@@ -37,16 +38,20 @@ MystGraphics::MystGraphics(MohawkEngine_Myst* vm) : GraphicsManager(), _vm(vm) {
_viewport = Common::Rect(544, 332);
- // The original version of Myst could run in 8bpp color too.
- // However, it dithered videos to 8bpp and they looked considerably
- // worse (than they already did :P). So we're not even going to
- // support 8bpp mode in Myst (Myst ME required >8bpp anyway).
- initGraphics(_viewport.width(), _viewport.height(), true, NULL); // What an odd screen size!
+ if (_vm->getFeatures() & GF_ME) {
+ // High color
+ initGraphics(_viewport.width(), _viewport.height(), true, NULL);
- _pixelFormat = _vm->_system->getScreenFormat();
+ if (_vm->_system->getScreenFormat().bytesPerPixel == 1)
+ error("Myst ME requires greater than 256 colors to run");
+ } else {
+ // Paletted
+ initGraphics(_viewport.width(), _viewport.height(), true);
+ setBasePalette();
+ setPaletteToScreen();
+ }
- if (_pixelFormat.bytesPerPixel == 1)
- error("Myst requires greater than 256 colors to run");
+ _pixelFormat = _vm->_system->getScreenFormat();
// Initialize our buffer
_backBuffer = new Graphics::Surface();
@@ -101,7 +106,9 @@ MohawkSurface *MystGraphics::decodeImage(uint16 id) {
mhkSurface = new MohawkSurface(pict.getSurface()->convertTo(_pixelFormat));
} else {
mhkSurface = _bmpDecoder->decodeImage(dataStream);
- mhkSurface->convertToTrueColor();
+
+ if (_vm->getFeatures() & GF_ME)
+ mhkSurface->convertToTrueColor();
}
assert(mhkSurface);
@@ -151,7 +158,8 @@ void MystGraphics::copyImageSectionToScreen(uint16 image, Common::Rect src, Comm
}
void MystGraphics::copyImageSectionToBackBuffer(uint16 image, Common::Rect src, Common::Rect dest) {
- Graphics::Surface *surface = findImage(image)->getSurface();
+ MohawkSurface *mhkSurface = findImage(image);
+ Graphics::Surface *surface = mhkSurface->getSurface();
// Make sure the image is bottom aligned in the dest rect
dest.top = dest.bottom - MIN<int>(surface->h, dest.height());
@@ -190,6 +198,13 @@ void MystGraphics::copyImageSectionToBackBuffer(uint16 image, Common::Rect src,
for (uint16 i = 0; i < height; i++)
memcpy(_backBuffer->getBasePtr(dest.left, i + dest.top), surface->getBasePtr(src.left, top + i), width * surface->format.bytesPerPixel);
+
+ if (!(_vm->getFeatures() & GF_ME)) {
+ // Make sure the palette is set
+ assert(mhkSurface->getPalette());
+ memcpy(_palette + 10 * 3, mhkSurface->getPalette() + 10 * 3, (256 - 10 * 2) * 3);
+ setPaletteToScreen();
+ }
}
void MystGraphics::copyImageToScreen(uint16 image, Common::Rect dest) {
@@ -419,12 +434,16 @@ void MystGraphics::transitionDissolve(Common::Rect rect, uint step) {
for (uint16 x = rect.left; x < rect.right; x++) {
if (linePattern[x % 4]) {
- if (_pixelFormat.bytesPerPixel == 2) {
- uint16 *dst = (uint16 *)screen->getBasePtr(x, y);
- *dst = *(const uint16 *)_backBuffer->getBasePtr(x, y);
- } else {
- uint32 *dst = (uint32 *)screen->getBasePtr(x, y);
- *dst = *(const uint32 *)_backBuffer->getBasePtr(x, y);
+ switch (_pixelFormat.bytesPerPixel) {
+ case 1:
+ *((byte *)screen->getBasePtr(x, y)) = *((const byte *)_backBuffer->getBasePtr(x, y));
+ break;
+ case 2:
+ *((uint16 *)screen->getBasePtr(x, y)) = *((const uint16 *)_backBuffer->getBasePtr(x, y));
+ break;
+ case 4:
+ *((uint32 *)screen->getBasePtr(x, y)) = *((const uint32 *)_backBuffer->getBasePtr(x, y));
+ break;
}
}
}
@@ -588,11 +607,11 @@ void MystGraphics::drawRect(Common::Rect rect, RectState state) {
Graphics::Surface *screen = _vm->_system->lockScreen();
if (state == kRectEnabled)
- screen->frameRect(rect, _pixelFormat.RGBToColor(0, 255, 0));
+ screen->frameRect(rect, (_vm->getFeatures() & GF_ME) ? _pixelFormat.RGBToColor(0, 255, 0) : 250);
else if (state == kRectUnreachable)
- screen->frameRect(rect, _pixelFormat.RGBToColor(0, 0, 255));
+ screen->frameRect(rect, (_vm->getFeatures() & GF_ME) ? _pixelFormat.RGBToColor(0, 0, 255) : 252);
else
- screen->frameRect(rect, _pixelFormat.RGBToColor(255, 0, 0));
+ screen->frameRect(rect, (_vm->getFeatures() & GF_ME) ? _pixelFormat.RGBToColor(255, 0, 0) : 249);
_vm->_system->unlockScreen();
}
@@ -629,50 +648,94 @@ void MystGraphics::simulatePreviousDrawDelay(const Common::Rect &dest) {
_nextAllowedDrawTime = time + _constantDrawDelay + dest.height() * dest.width() / _proportionalDrawDelay;
}
-void MystGraphics::copyBackBufferToScreenWithSaturation(int16 saturation) {
- Graphics::Surface *screen = _vm->_system->lockScreen();
+void MystGraphics::fadeToBlack() {
+ // This is only for the demo
+ assert(!(_vm->getFeatures() & GF_ME));
- for (uint16 y = 0; y < _viewport.height(); y++)
- for (uint16 x = 0; x < _viewport.width(); x++) {
- uint32 color;
- uint8 r, g, b;
+ // Linear fade in 64 steps
+ for (int i = 63; i >= 0; i--) {
+ byte palette[256 * 3];
+ byte *src = _palette;
+ byte *dst = palette;
- if (_pixelFormat.bytesPerPixel == 2)
- color = *(const uint16 *)_backBuffer->getBasePtr(x, y);
- else
- color = *(const uint32 *)_backBuffer->getBasePtr(x, y);
+ for (uint j = 0; j < sizeof(palette); j++)
+ *dst++ = *src++ * i / 64;
- _pixelFormat.colorToRGB(color, r, g, b);
+ _vm->_system->getPaletteManager()->setPalette(palette, 0, 256);
+ _vm->_system->updateScreen();
+ }
+}
- r = CLIP<int16>((int16)r - saturation, 0, 255);
- g = CLIP<int16>((int16)g - saturation, 0, 255);
- b = CLIP<int16>((int16)b - saturation, 0, 255);
+void MystGraphics::fadeFromBlack() {
+ // This is only for the demo
+ assert(!(_vm->getFeatures() & GF_ME));
- color = _pixelFormat.RGBToColor(r, g, b);
+ copyBackBufferToScreen(_viewport);
- if (_pixelFormat.bytesPerPixel == 2) {
- uint16 *dst = (uint16 *)screen->getBasePtr(x, y);
- *dst = color;
- } else {
- uint32 *dst = (uint32 *)screen->getBasePtr(x, y);
- *dst = color;
- }
- }
+ // Linear fade in 64 steps
+ for (int i = 0; i < 64; i++) {
+ byte palette[256 * 3];
+ byte *src = _palette;
+ byte *dst = palette;
- _vm->_system->unlockScreen();
+ for (uint j = 0; j < sizeof(palette); j++)
+ *dst++ = *src++ * i / 64;
+
+ _vm->_system->getPaletteManager()->setPalette(palette, 0, 256);
+ _vm->_system->updateScreen();
+ }
+
+ // Set the full palette
+ _vm->_system->getPaletteManager()->setPalette(_palette, 0, 256);
_vm->_system->updateScreen();
}
-void MystGraphics::fadeToBlack() {
- for (int16 i = 0; i < 256; i += 32) {
- copyBackBufferToScreenWithSaturation(i);
- }
+void MystGraphics::clearScreenPalette() {
+ // Set the palette to all black
+ byte palette[256 * 3];
+ memset(palette, 0, sizeof(palette));
+ _vm->_system->getPaletteManager()->setPalette(palette, 0, 256);
}
-void MystGraphics::fadeFromBlack() {
- for (int16 i = 256; i >= 0; i -= 32) {
- copyBackBufferToScreenWithSaturation(i);
- }
+void MystGraphics::setBasePalette() {
+ // Entries [0, 9] of the palette
+ static const byte lowPalette[] = {
+ 0xFF, 0xFF, 0xFF,
+ 0x80, 0x00, 0x00,
+ 0x00, 0x80, 0x00,
+ 0x80, 0x80, 0x00,
+ 0x00, 0x00, 0x80,
+ 0x80, 0x00, 0x80,
+ 0x00, 0x80, 0x80,
+ 0xC0, 0xC0, 0xC0,
+ 0xC0, 0xDC, 0xC0,
+ 0xA6, 0xCA, 0xF0
+ };
+
+ // Entries [246, 255] of the palette
+ static const byte highPalette[] = {
+ 0xFF, 0xFB, 0xF0,
+ 0xA0, 0xA0, 0xA4,
+ 0x80, 0x80, 0x80,
+ 0xFF, 0x00, 0x00,
+ 0x00, 0xFF, 0x00,
+ 0xFF, 0xFF, 0x00,
+ 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0xFF,
+ 0x00, 0xFF, 0xFF,
+ 0x00, 0x00, 0x00
+ };
+
+ // Note that 0 and 255 are different from normal Windows.
+ // Myst seems to hack that to white, resp. black (probably for Mac compat).
+
+ memcpy(_palette, lowPalette, sizeof(lowPalette));
+ memset(_palette + sizeof(lowPalette), 0, sizeof(_palette) - sizeof(lowPalette) - sizeof(highPalette));
+ memcpy(_palette + sizeof(_palette) - sizeof(highPalette), highPalette, sizeof(highPalette));
+}
+
+void MystGraphics::setPaletteToScreen() {
+ _vm->_system->getPaletteManager()->setPalette(_palette, 0, 256);
}
} // End of namespace Mohawk