[Scummvm-cvs-logs] scummvm master -> 0a42a7d6257cedfe461ef65de565b8007e3a0c72

athrxx athrxx at scummvm.org
Wed Jun 15 22:45:24 CEST 2011


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
0a42a7d625 SCUMM: hopefully fix 16bit mode support for SCUMM FM-TOWNS games and LOOM PCE on Android


Commit: 0a42a7d6257cedfe461ef65de565b8007e3a0c72
    https://github.com/scummvm/scummvm/commit/0a42a7d6257cedfe461ef65de565b8007e3a0c72
Author: athrxx (athrxx at scummvm.org)
Date: 2011-06-15T13:30:04-07:00

Commit Message:
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.

Changed paths:
    engines/scumm/cursor.cpp
    engines/scumm/gfx.cpp
    engines/scumm/gfx.h
    engines/scumm/gfx_towns.cpp
    engines/scumm/palette.cpp
    engines/scumm/saveload.cpp
    engines/scumm/scumm.cpp
    engines/scumm/scumm.h



diff --git a/engines/scumm/cursor.cpp b/engines/scumm/cursor.cpp
index 8676c85..a8adb4d 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 1b913e1..98d447f 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 6da07ef..54ce724 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 cdccd3e..3c96be8 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 3e8c35c..51ba219 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 19834cb..2be032d 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 97dd68a..d498339 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 6e75f47..5700271 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






More information about the Scummvm-git-logs mailing list