aboutsummaryrefslogtreecommitdiff
path: root/engines/scumm
diff options
context:
space:
mode:
authorathrxx2011-06-15 22:01:24 +0200
committerathrxx2011-06-15 22:30:04 +0200
commit0a42a7d6257cedfe461ef65de565b8007e3a0c72 (patch)
tree180fa90d5e3f7b1d5ed64d3c92476b7bc6a774bb /engines/scumm
parente0efde7cf65e0f22d5afa830339fb1dc6ca91479 (diff)
downloadscummvm-rg350-0a42a7d6257cedfe461ef65de565b8007e3a0c72.tar.gz
scummvm-rg350-0a42a7d6257cedfe461ef65de565b8007e3a0c72.tar.bz2
scummvm-rg350-0a42a7d6257cedfe461ef65de565b8007e3a0c72.zip
SCUMM: hopefully fix 16bit mode support for SCUMM FM-TOWNS games and LOOM PCE on Android
This mostly reverts 5b7754e3f095eb8a469dd4b7de5a6379f8e13c27. Instead, we try to use other 16bit modes after 555 fails.
Diffstat (limited to 'engines/scumm')
-rw-r--r--engines/scumm/cursor.cpp24
-rw-r--r--engines/scumm/gfx.cpp2
-rw-r--r--engines/scumm/gfx.h4
-rw-r--r--engines/scumm/gfx_towns.cpp34
-rw-r--r--engines/scumm/palette.cpp20
-rw-r--r--engines/scumm/saveload.cpp2
-rw-r--r--engines/scumm/scumm.cpp49
-rw-r--r--engines/scumm/scumm.h2
8 files changed, 68 insertions, 69 deletions
diff --git a/engines/scumm/cursor.cpp b/engines/scumm/cursor.cpp
index 8676c857ea..a8adb4d5c5 100644
--- a/engines/scumm/cursor.cpp
+++ b/engines/scumm/cursor.cpp
@@ -114,21 +114,17 @@ void ScummEngine_v6::setCursorTransparency(int a) {
void ScummEngine::updateCursor() {
int transColor = (_game.heversion >= 80) ? 5 : 255;
#ifdef USE_RGB_COLOR
- if (_bytesPerPixelOutput == 2) {
- Graphics::PixelFormat format = _system->getScreenFormat();
- CursorMan.replaceCursor(_grabbedCursor, _cursor.width, _cursor.height,
- _cursor.hotspotX, _cursor.hotspotY,
- (_game.platform == Common::kPlatformNES ? _grabbedCursor[63] : transColor),
- (_game.heversion == 70 ? 2 : 1),
- &format);
- } else {
-#endif
+ Graphics::PixelFormat format = _system->getScreenFormat();
+ CursorMan.replaceCursor(_grabbedCursor, _cursor.width, _cursor.height,
+ _cursor.hotspotX, _cursor.hotspotY,
+ (_game.platform == Common::kPlatformNES ? _grabbedCursor[63] : transColor),
+ (_game.heversion == 70 ? 2 : 1),
+ &format);
+#else
CursorMan.replaceCursor(_grabbedCursor, _cursor.width, _cursor.height,
_cursor.hotspotX, _cursor.hotspotY,
(_game.platform == Common::kPlatformNES ? _grabbedCursor[63] : transColor),
(_game.heversion == 70 ? 2 : 1));
-#ifdef USE_RGB_COLOR
- }
#endif
}
@@ -555,7 +551,7 @@ void ScummEngine_v5::setBuiltinCursor(int idx) {
uint16 color;
const uint16 *src = _cursorImages[_currentCursor];
- if (_bytesPerPixelOutput == 2) {
+ if (_outputPixelFormat.bytesPerPixel == 2) {
if (_game.id == GID_LOOM && _game.platform == Common::kPlatformPCEngine) {
byte r, g, b;
colorPCEToRGB(default_pce_cursor_colors[idx], &r, &g, &b);
@@ -581,14 +577,14 @@ void ScummEngine_v5::setBuiltinCursor(int idx) {
_cursor.width = 16 * _textSurfaceMultiplier;
_cursor.height = 16 * _textSurfaceMultiplier;
- int scl = _bytesPerPixelOutput * _textSurfaceMultiplier;
+ int scl = _outputPixelFormat.bytesPerPixel * _textSurfaceMultiplier;
for (i = 0; i < 16; i++) {
for (j = 0; j < 16; j++) {
if (src[i] & (1 << j)) {
byte *dst1 = _grabbedCursor + 16 * scl * i * _textSurfaceMultiplier + (15 - j) * scl;
byte *dst2 = (_textSurfaceMultiplier == 2) ? dst1 + 16 * scl : dst1;
- if (_bytesPerPixelOutput == 2) {
+ if (_outputPixelFormat.bytesPerPixel == 2) {
for (int b = 0; b < scl; b += 2) {
*((uint16*)dst1) = *((uint16*)dst2) = color;
dst1 += 2;
diff --git a/engines/scumm/gfx.cpp b/engines/scumm/gfx.cpp
index 1b913e16b4..98d447fdaf 100644
--- a/engines/scumm/gfx.cpp
+++ b/engines/scumm/gfx.cpp
@@ -661,7 +661,7 @@ void ScummEngine::drawStripToScreen(VirtScreen *vs, int x, int width, int top, i
return;
} else
#endif
- if (_bytesPerPixelOutput == 2) {
+ if (_outputPixelFormat.bytesPerPixel == 2) {
const byte *srcPtr = (const byte *)src;
const byte *textPtr = (byte *)_textSurface.getBasePtr(x * m, y * m);
byte *dstPtr = _compositeBuf;
diff --git a/engines/scumm/gfx.h b/engines/scumm/gfx.h
index 6da07efd18..54ce724da1 100644
--- a/engines/scumm/gfx.h
+++ b/engines/scumm/gfx.h
@@ -443,7 +443,7 @@ public:
// switching graphics layers on and off).
class TownsScreen {
public:
- TownsScreen(OSystem *system, int width, int height, int bpp);
+ TownsScreen(OSystem *system, int width, int height, Graphics::PixelFormat &format);
~TownsScreen();
void setupLayer(int layer, int width, int height, int numCol, void *srcPal = 0);
@@ -490,7 +490,7 @@ private:
int _height;
int _width;
int _pitch;
- int _bpp;
+ Graphics::PixelFormat _pixelFormat;
int _numDirtyRects;
Common::List<Common::Rect> _dirtyRects;
diff --git a/engines/scumm/gfx_towns.cpp b/engines/scumm/gfx_towns.cpp
index cdccd3e193..3c96be8b9c 100644
--- a/engines/scumm/gfx_towns.cpp
+++ b/engines/scumm/gfx_towns.cpp
@@ -50,10 +50,10 @@ void ScummEngine::towns_drawStripToScreen(VirtScreen *vs, int dstX, int dstY, in
if (vs->number == kMainVirtScreen || _game.id == GID_INDY3 || _game.id == GID_ZAK) {
for (int h = 0; h < height; ++h) {
- if (_bytesPerPixelOutput == 2) {
+ if (_outputPixelFormat.bytesPerPixel == 2) {
for (int w = 0; w < width; ++w) {
*(uint16*)dst1 = _16BitPalette[*src1++];
- dst1 += _bytesPerPixelOutput;
+ dst1 += _outputPixelFormat.bytesPerPixel;
}
src1 += sp1;
@@ -197,8 +197,8 @@ const uint8 ScummEngine::_townsLayer2Mask[] = {
#define DIRTY_RECTS_MAX 20
#define FULL_REDRAW (DIRTY_RECTS_MAX + 1)
-TownsScreen::TownsScreen(OSystem *system, int width, int height, int bpp) :
- _system(system), _width(width), _height(height), _bpp(bpp), _pitch(width * bpp) {
+TownsScreen::TownsScreen(OSystem *system, int width, int height, Graphics::PixelFormat &format) :
+ _system(system), _width(width), _height(height), _pixelFormat(format), _pitch(width * format.bytesPerPixel) {
memset(&_layers[0], 0, sizeof(TownsScreenLayer));
memset(&_layers[1], 0, sizeof(TownsScreenLayer));
_outBuffer = new byte[_pitch * _height];
@@ -247,7 +247,7 @@ void TownsScreen::setupLayer(int layer, int width, int height, int numCol, void
l->pitch = width * l->bpp;
l->palette = (uint8*)pal;
- if (l->palette && _bpp == 1)
+ if (l->palette && _pixelFormat.bytesPerPixel == 1)
warning("TownsScreen::setupLayer(): Layer palette usage requires 16 bit graphics setting.\nLayer palette will be ignored.");
delete[] l->pixels;
@@ -267,7 +267,7 @@ void TownsScreen::setupLayer(int layer, int width, int height, int numCol, void
l->bltInternY[i] = l->pixels + (i / l->scaleH) * l->pitch;
delete[] l->bltTmpPal;
- l->bltTmpPal = (l->bpp == 1 && _bpp == 2) ? new uint16[l->numCol] : 0;
+ l->bltTmpPal = (l->bpp == 1 && _pixelFormat.bytesPerPixel == 2) ? new uint16[l->numCol] : 0;
l->enabled = true;
_layers[0].onBottom = true;
@@ -449,20 +449,20 @@ void TownsScreen::updateOutputBuffer() {
if (!l->enabled || !l->ready)
continue;
- uint8 *dst = _outBuffer + r->top * _pitch + r->left * _bpp;
- int ptch = _pitch - (r->right - r->left + 1) * _bpp;
+ uint8 *dst = _outBuffer + r->top * _pitch + r->left * _pixelFormat.bytesPerPixel;
+ int ptch = _pitch - (r->right - r->left + 1) * _pixelFormat.bytesPerPixel;
- if (_bpp == 2 && l->bpp == 1) {
+ if (_pixelFormat.bytesPerPixel == 2 && l->bpp == 1) {
for (int ic = 0; ic < l->numCol; ic++)
l->bltTmpPal[ic] = calc16BitColor(&l->palette[ic * 3]);
}
for (int y = r->top; y <= r->bottom; ++y) {
- if (l->bpp == _bpp && l->scaleW == 1 && l->onBottom && l->numCol & 0xff00) {
- memcpy(dst, &l->bltInternY[y][l->bltInternX[r->left]], (r->right + 1 - r->left) * _bpp);
+ if (l->bpp == _pixelFormat.bytesPerPixel && l->scaleW == 1 && l->onBottom && l->numCol & 0xff00) {
+ memcpy(dst, &l->bltInternY[y][l->bltInternX[r->left]], (r->right + 1 - r->left) * _pixelFormat.bytesPerPixel);
dst += _pitch;
- } else if (_bpp == 2) {
+ } else if (_pixelFormat.bytesPerPixel == 2) {
for (int x = r->left; x <= r->right; ++x) {
uint8 *src = &l->bltInternY[y][l->bltInternX[x]];
if (l->bpp == 1) {
@@ -498,17 +498,13 @@ void TownsScreen::updateOutputBuffer() {
void TownsScreen::outputToScreen() {
for (Common::List<Common::Rect>::iterator i = _dirtyRects.begin(); i != _dirtyRects.end(); ++i)
- _system->copyRectToScreen(_outBuffer + i->top * _pitch + i->left * _bpp, _pitch, i->left, i->top, i->right - i->left + 1, i->bottom - i->top + 1);
+ _system->copyRectToScreen(_outBuffer + i->top * _pitch + i->left * _pixelFormat.bytesPerPixel, _pitch, i->left, i->top, i->right - i->left + 1, i->bottom - i->top + 1);
_dirtyRects.clear();
_numDirtyRects = 0;
}
-uint16 TownsScreen::calc16BitColor(const uint8 *palEntry) {
- uint16 ar = (palEntry[0] & 0xf8) << 7;
- uint16 ag = (palEntry[1] & 0xf8) << 2;
- uint16 ab = (palEntry[2] >> 3);
- uint16 col = ar | ag | ab;
- return col;
+uint16 TownsScreen::calc16BitColor(const uint8 *palEntry) {
+ return _pixelFormat.RGBToColor(palEntry[0], palEntry[1], palEntry[2]);
}
#undef DIRTY_RECTS_MAX
diff --git a/engines/scumm/palette.cpp b/engines/scumm/palette.cpp
index 3e8c35cfd8..51ba2195d7 100644
--- a/engines/scumm/palette.cpp
+++ b/engines/scumm/palette.cpp
@@ -48,11 +48,7 @@ uint8 *ScummEngine::getHEPaletteSlot(uint16 palSlot) {
}
uint16 ScummEngine::get16BitColor(uint8 r, uint8 g, uint8 b) {
- uint16 ar = (r >> 3) << 10;
- uint16 ag = (g >> 3) << 5;
- uint16 ab = (b >> 3) << 0;
- uint16 col = ar | ag | ab;
- return col;
+ return _outputPixelFormat.RGBToColor(r, g, b);
}
void ScummEngine::resetPalette() {
@@ -222,12 +218,10 @@ void ScummEngine::resetPalette() {
if (_game.id == GID_INDY4 || _game.id == GID_MONKEY2)
_townsClearLayerFlag = 0;
#ifdef USE_RGB_COLOR
- else if (_bytesPerPixelOutput == 2) {
- if (_game.id == GID_LOOM)
- towns_setTextPaletteFromPtr(tableTownsLoomPalette);
- else if (_game.version == 3)
- towns_setTextPaletteFromPtr(tableTownsV3Palette);
- }
+ else if (_game.id == GID_LOOM)
+ towns_setTextPaletteFromPtr(tableTownsLoomPalette);
+ else if (_game.version == 3)
+ towns_setTextPaletteFromPtr(tableTownsV3Palette);
#endif
_townsScreen->toggleLayers(_townsActiveLayerFlags);
@@ -1016,7 +1010,7 @@ void ScummEngine::setCurrentPalette(int palindex) {
setPCEPaletteFromPtr(pals);
#ifdef USE_RGB_COLOR
#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE
- } else if (_game.platform == Common::kPlatformFMTowns && _bytesPerPixelOutput == 2) {
+ } else if (_game.platform == Common::kPlatformFMTowns) {
towns_setPaletteFromPtr(pals);
#endif
#endif
@@ -1119,7 +1113,7 @@ void ScummEngine::updatePalette() {
#ifdef USE_RGB_COLOR
#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE
- if (_game.platform == Common::kPlatformFMTowns && _bytesPerPixelOutput == 2) {
+ if (_game.platform == Common::kPlatformFMTowns) {
p = palette_colors;
for (i = first; i < first + num; ++i) {
_16BitPalette[i] = get16BitColor(p[0], p[1], p[2]);
diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp
index 19834cb35d..2be032d496 100644
--- a/engines/scumm/saveload.cpp
+++ b/engines/scumm/saveload.cpp
@@ -1489,7 +1489,7 @@ void ScummEngine_v5::saveOrLoad(Serializer *s) {
// Reset cursors for old FM-Towns savegames saved with 256 color setting.
// Otherwise the cursor will be messed up when displayed in the new hi color setting.
- if (_game.platform == Common::kPlatformFMTowns && _bytesPerPixelOutput == 2 && s->isLoading() && s->getVersion() < VER(82)) {
+ if (_game.platform == Common::kPlatformFMTowns && _outputPixelFormat.bytesPerPixel == 2 && s->isLoading() && s->getVersion() < VER(82)) {
if (_game.id == GID_LOOM) {
redefineBuiltinCursorFromChar(1, 1);
redefineBuiltinCursorHotspot(1, 0, 0);
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 97dd68af7c..d4983397e4 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -260,7 +260,7 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
_switchRoomEffect2 = 0;
_switchRoomEffect = 0;
- _bytesPerPixelOutput = _bytesPerPixel = 1;
+ _bytesPerPixel = 1;
_doEffect = false;
_snapScroll = false;
_currentLights = 0;
@@ -545,18 +545,19 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
_screenHeight = 200;
}
- _bytesPerPixelOutput = _bytesPerPixel = (_game.features & GF_16BIT_COLOR) ? 2 : 1;
+ _bytesPerPixel = (_game.features & GF_16BIT_COLOR) ? 2 : 1;
+ uint8 sizeMult = _bytesPerPixel;
#ifdef USE_RGB_COLOR
#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE
if (_game.platform == Common::kPlatformFMTowns)
- _bytesPerPixelOutput = 2;
+ sizeMult = 2;
#endif
#endif
// Allocate gfx compositing buffer (not needed for V7/V8 games).
if (_game.version < 7)
- _compositeBuf = (byte *)malloc(_screenWidth * _screenHeight * _bytesPerPixelOutput);
+ _compositeBuf = (byte *)malloc(_screenWidth * _screenHeight * sizeMult);
else
_compositeBuf = 0;
@@ -1154,17 +1155,27 @@ Common::Error ScummEngine::init() {
#endif
) {
#ifdef USE_RGB_COLOR
- Graphics::PixelFormat format = Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0);
- initGraphics(screenWidth, screenHeight, screenWidth > 320, &format);
- if (format != _system->getScreenFormat()) {
- if (_game.platform == Common::kPlatformFMTowns && _game.version == 3) {
- warning("Your ScummVM build does not support the type of 16bit color mode required by this target.\nStarting game in 8bit color mode...\nYou may experience color glitches");
- _bytesPerPixelOutput = 1;
- initGraphics(screenWidth, screenHeight, (screenWidth > 320));
- } else {
- return Common::kUnsupportedColorMode;
- }
+ _outputPixelFormat = Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0);
+ Common::List<Graphics::PixelFormat> tryModes = _system->getSupportedFormats();
+ // Try default 555 mode first
+ tryModes.push_front(_outputPixelFormat);
+
+ for (Common::List<Graphics::PixelFormat>::iterator g = tryModes.begin(); g != tryModes.end(); ++g) {
+ if (g->bytesPerPixel != 2 || g->aBits())
+ continue;
+ _outputPixelFormat = *g;
+ initGraphics(screenWidth, screenHeight, screenWidth > 320, &_outputPixelFormat);
+ // athrxx-06/15/2011: To avoid regressions I add support for other modes than 555 only
+ // for FM-TOWNS games and for LOOM PCE atm.
+ // TODO: Someone knowledgeable about HE games might check whether other modes can be
+ // supported for these games, too. Quick tests with SPYOZON indicate that this should
+ // not be a problem.
+ if (*g == _system->getScreenFormat() || (_game.platform != Common::kPlatformFMTowns && _game.platform != Common::kPlatformPCEngine))
+ break;
}
+
+ if (_outputPixelFormat != _system->getScreenFormat())
+ return Common::kUnsupportedColorMode;
#else
if (_game.platform == Common::kPlatformFMTowns && _game.version == 3) {
warning("Starting game without the required 16bit color support.\nYou may experience color glitches");
@@ -1182,6 +1193,8 @@ Common::Error ScummEngine::init() {
}
}
+ _outputPixelFormat = _system->getScreenFormat();
+
setupScumm();
readIndexFile();
@@ -1290,7 +1303,7 @@ void ScummEngine::setupScumm() {
_res->setHeapThreshold(400000, maxHeapThreshold);
free(_compositeBuf);
- _compositeBuf = (byte *)malloc(_screenWidth * _textSurfaceMultiplier * _screenHeight * _textSurfaceMultiplier * _bytesPerPixelOutput);
+ _compositeBuf = (byte *)malloc(_screenWidth * _textSurfaceMultiplier * _screenHeight * _textSurfaceMultiplier * _outputPixelFormat.bytesPerPixel);
}
#ifdef ENABLE_SCUMM_7_8
@@ -1371,7 +1384,7 @@ void ScummEngine::resetScumm() {
#ifdef USE_RGB_COLOR
if (_game.features & GF_16BIT_COLOR
#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE
- || (_game.platform == Common::kPlatformFMTowns && _bytesPerPixelOutput == 2)
+ || (_game.platform == Common::kPlatformFMTowns)
#endif
)
_16BitPalette = (uint16 *)calloc(512, sizeof(uint16));
@@ -1380,8 +1393,8 @@ void ScummEngine::resetScumm() {
#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE
if (_game.platform == Common::kPlatformFMTowns) {
delete _townsScreen;
- _townsScreen = new TownsScreen(_system, _screenWidth * _textSurfaceMultiplier, _screenHeight * _textSurfaceMultiplier, _bytesPerPixelOutput);
- _townsScreen->setupLayer(0, _screenWidth, _screenHeight, (_bytesPerPixelOutput == 2) ? 32767 : 256);
+ _townsScreen = new TownsScreen(_system, _screenWidth * _textSurfaceMultiplier, _screenHeight * _textSurfaceMultiplier, _outputPixelFormat);
+ _townsScreen->setupLayer(0, _screenWidth, _screenHeight, (_outputPixelFormat.bytesPerPixel == 2) ? 32767 : 256);
_townsScreen->setupLayer(1, _screenWidth * _textSurfaceMultiplier, _screenHeight * _textSurfaceMultiplier, 16, _textPalette);
}
#endif
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index 6e75f47d77..5700271911 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -897,7 +897,7 @@ public:
Common::RenderMode _renderMode;
uint8 _bytesPerPixel;
- uint8 _bytesPerPixelOutput;
+ Graphics::PixelFormat _outputPixelFormat;
protected:
ColorCycle _colorCycle[16]; // Palette cycles