[Scummvm-git-logs] scummvm master -> b6947c78eb5daa9e290402c5634fc9987b1481ac

sev- noreply at scummvm.org
Sun Oct 29 00:02:16 UTC 2023


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

Summary:
a899ee5519 RISCOS: Add support for hardware palettes
bcc9259382 BACKENDS: Report if the backend supports cursors with alpha channels
b6947c78eb TESTBED: Add a test case for alpha cursors


Commit: a899ee55194728f4e32a2b5f85a4f06d6fde7359
    https://github.com/scummvm/scummvm/commit/a899ee55194728f4e32a2b5f85a4f06d6fde7359
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2023-10-29T02:02:11+02:00

Commit Message:
RISCOS: Add support for hardware palettes

Changed paths:
    backends/graphics/miyoo/miyoomini-graphics.cpp
    backends/graphics/opendingux/opendingux-graphics.cpp
    backends/graphics/opendingux/opendingux-graphics.h
    backends/graphics/riscossdl/riscossdl-graphics.cpp
    backends/graphics/riscossdl/riscossdl-graphics.h
    backends/graphics/surfacesdl/surfacesdl-graphics.cpp
    backends/graphics/surfacesdl/surfacesdl-graphics.h


diff --git a/backends/graphics/miyoo/miyoomini-graphics.cpp b/backends/graphics/miyoo/miyoomini-graphics.cpp
index 575c6c622ba..84f7fb59b11 100644
--- a/backends/graphics/miyoo/miyoomini-graphics.cpp
+++ b/backends/graphics/miyoo/miyoomini-graphics.cpp
@@ -34,6 +34,7 @@ void MiyooMiniGraphicsManager::initGraphicsSurface() {
 					 _realHwScreen->format->Bmask,
 					 _realHwScreen->format->Amask);
 	_isDoubleBuf = false;
+	_isHwPalette = false;
 }
 
 void MiyooMiniGraphicsManager::unloadGFXMode() {
diff --git a/backends/graphics/opendingux/opendingux-graphics.cpp b/backends/graphics/opendingux/opendingux-graphics.cpp
index 7986d3a570e..827d339b459 100644
--- a/backends/graphics/opendingux/opendingux-graphics.cpp
+++ b/backends/graphics/opendingux/opendingux-graphics.cpp
@@ -22,13 +22,16 @@
 #include "backends/graphics/opendingux/opendingux-graphics.h"
 
 void OpenDinguxGraphicsManager::initGraphicsSurface() {
-	Uint32 flags = _videoMode.isHwPalette ? (SDL_HWSURFACE | SDL_HWPALETTE | SDL_DOUBLEBUF) : SDL_SWSURFACE;
-#ifndef RS90
-	flags |= SDL_FULLSCREEN;
+#ifdef RS90
+	Uint32 flags = SDL_HWSURFACE | SDL_HWPALETTE | SDL_DOUBLEBUF;
+	int bpp = 8;
+#else
+	Uint32 flags = SDL_SWSURFACE | SDL_FULLSCREEN;
+	int bpp = 16;
 #endif
-	_hwScreen = SDL_SetVideoMode(_videoMode.hardwareWidth, _videoMode.hardwareHeight, _videoMode.isHwPalette ? 8 : 16,
-				     flags);
+	_hwScreen = SDL_SetVideoMode(_videoMode.hardwareWidth, _videoMode.hardwareHeight, bpp, flags);
 	_isDoubleBuf = flags & SDL_DOUBLEBUF;
+	_isHwPalette = flags & SDL_HWPALETTE;
 }
 
 void OpenDinguxGraphicsManager::getDefaultResolution(uint &w, uint &h) {
@@ -58,13 +61,3 @@ void OpenDinguxGraphicsManager::getDefaultResolution(uint &w, uint &h) {
 	h = 200;
 #endif
 }
-
-void OpenDinguxGraphicsManager::setupHardwareSize() {
-#ifdef RS90
-	_videoMode.isHwPalette = true;
-	_videoMode.scaleFactor = 1;
-#else
-	_videoMode.isHwPalette = false;
-#endif
-	SurfaceSdlGraphicsManager::setupHardwareSize();
-}
diff --git a/backends/graphics/opendingux/opendingux-graphics.h b/backends/graphics/opendingux/opendingux-graphics.h
index 80c4452934e..a3899edfbf4 100644
--- a/backends/graphics/opendingux/opendingux-graphics.h
+++ b/backends/graphics/opendingux/opendingux-graphics.h
@@ -30,7 +30,6 @@ public:
 
 	void initGraphicsSurface() override;
 	void getDefaultResolution(uint &w, uint &h) override;
-	void setupHardwareSize() override;
 };
 
 #endif /* BACKENDS_GRAPHICS_OPENDINGUX_H */
diff --git a/backends/graphics/riscossdl/riscossdl-graphics.cpp b/backends/graphics/riscossdl/riscossdl-graphics.cpp
index 16e36c311f2..442e27ec4d4 100644
--- a/backends/graphics/riscossdl/riscossdl-graphics.cpp
+++ b/backends/graphics/riscossdl/riscossdl-graphics.cpp
@@ -24,6 +24,17 @@
 #if defined(RISCOS) && defined(SDL_BACKEND)
 
 #include "backends/graphics/riscossdl/riscossdl-graphics.h"
+#include "common/translation.h"
+
+static OSystem::GraphicsMode s_supportedGraphicsModes[] = {
+	{"surfacesdl", _s("SDL Surface"),                    GFX_SURFACESDL},
+	{"palettesdl", _s("SDL Surface (forced 8bpp mode)"), GFX_PALETTESDL},
+	{nullptr, nullptr, 0}
+};
+
+const OSystem::GraphicsMode *RISCOSSdlGraphicsManager::getSupportedGraphicsModes() const {
+	return s_supportedGraphicsModes;
+}
 
 bool RISCOSSdlGraphicsManager::hasFeature(OSystem::Feature f) const {
 	if (f == OSystem::kFeatureVSync)
@@ -33,6 +44,7 @@ bool RISCOSSdlGraphicsManager::hasFeature(OSystem::Feature f) const {
 
 void RISCOSSdlGraphicsManager::initGraphicsSurface() {
 	Uint32 flags = 0;
+	int bpp = 0;
 
 	if (_videoMode.fullscreen)
 		flags |= SDL_FULLSCREEN;
@@ -44,8 +56,22 @@ void RISCOSSdlGraphicsManager::initGraphicsSurface() {
 		flags |= SDL_SWSURFACE;
 	}
 
-	_hwScreen = SDL_SetVideoMode(_videoMode.hardwareWidth, _videoMode.hardwareHeight, 16, flags);
+	switch (_videoMode.mode) {
+	case GFX_SURFACESDL:
+		bpp = 16;
+		flags |= SDL_ANYFORMAT;
+		break;
+	case GFX_PALETTESDL:
+		bpp = 8;
+		flags |= SDL_HWPALETTE;
+		break;
+	default:
+		break;
+	}
+
+	_hwScreen = SDL_SetVideoMode(_videoMode.hardwareWidth, _videoMode.hardwareHeight, bpp, flags);
 	_isDoubleBuf = flags & SDL_DOUBLEBUF;
+	_isHwPalette = flags & SDL_HWPALETTE;
 }
 
 #endif
diff --git a/backends/graphics/riscossdl/riscossdl-graphics.h b/backends/graphics/riscossdl/riscossdl-graphics.h
index 307b17a8a44..20f71f35c8e 100644
--- a/backends/graphics/riscossdl/riscossdl-graphics.h
+++ b/backends/graphics/riscossdl/riscossdl-graphics.h
@@ -24,10 +24,16 @@
 
 #include "backends/graphics/surfacesdl/surfacesdl-graphics.h"
 
+enum {
+	GFX_PALETTESDL = 1
+};
+
+
 class RISCOSSdlGraphicsManager : public SurfaceSdlGraphicsManager {
 public:
 	RISCOSSdlGraphicsManager(SdlEventSource *sdlEventSource, SdlWindow *window) : SurfaceSdlGraphicsManager(sdlEventSource, window) {}
 
+	const OSystem::GraphicsMode *getSupportedGraphicsModes() const override;
 	bool hasFeature(OSystem::Feature f) const override;
 	void initGraphicsSurface() override;
 };
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
index 07560f0d5ab..f9779af3bdf 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
@@ -122,7 +122,7 @@ SurfaceSdlGraphicsManager::SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSou
 	_screen(nullptr), _tmpscreen(nullptr),
 	_screenFormat(Graphics::PixelFormat::createFormatCLUT8()),
 	_cursorFormat(Graphics::PixelFormat::createFormatCLUT8()),
-	_useOldSrc(false),
+	_useOldSrc(false), _isHwPalette(false),
 	_overlayscreen(nullptr), _tmpscreen2(nullptr),
 	_screenChangeCount(0),
 	_mouseSurface(nullptr), _mouseScaler(nullptr),
@@ -163,8 +163,6 @@ SurfaceSdlGraphicsManager::SurfaceSdlGraphicsManager(SdlEventSource *sdlEventSou
 		_enableFocusRectDebugCode = ConfMan.getBool("use_sdl_debug_focusrect");
 #endif
 
-	_videoMode.isHwPalette = false;
-
 #if defined(USE_ASPECT)
 	_videoMode.aspectRatioCorrection = ConfMan.getBool("aspect_ratio");
 	_videoMode.desiredAspectRatio = getDesiredAspectRatio();
@@ -286,11 +284,37 @@ int SurfaceSdlGraphicsManager::getDefaultGraphicsMode() const {
 }
 
 bool SurfaceSdlGraphicsManager::setGraphicsMode(int mode, uint flags) {
-	return (mode == GFX_SURFACESDL);
+	Common::StackLock lock(_graphicsMutex);
+
+	assert(_transactionMode == kTransactionActive);
+
+	if (_oldVideoMode.setup && _oldVideoMode.mode == mode)
+		return true;
+
+	// Check this is a valid mode
+	const OSystem::GraphicsMode *sm = getSupportedGraphicsModes();
+	bool found = false;
+	while (sm->name) {
+		if (sm->id == mode) {
+			found = true;
+			break;
+		}
+		sm++;
+	}
+	if (!found) {
+		warning("unknown mode %d", mode);
+		return false;
+	}
+
+	_transactionDetails.needUpdatescreen = true;
+
+	_videoMode.mode = mode;
+
+	return true;
 }
 
 int SurfaceSdlGraphicsManager::getGraphicsMode() const {
-	return GFX_SURFACESDL;
+	return _videoMode.mode;
 }
 
 void SurfaceSdlGraphicsManager::beginGFXTransaction() {
@@ -320,6 +344,12 @@ OSystem::TransactionError SurfaceSdlGraphicsManager::endGFXTransaction() {
 	assert(_transactionMode != kTransactionNone);
 
 	if (_transactionMode == kTransactionRollback) {
+		if (_videoMode.mode != _oldVideoMode.mode) {
+			errors |= OSystem::kTransactionModeSwitchFailed;
+
+			_videoMode.mode = _oldVideoMode.mode;
+		}
+
 		if (_videoMode.fullscreen != _oldVideoMode.fullscreen) {
 			errors |= OSystem::kTransactionFullscreenFailed;
 
@@ -533,7 +563,7 @@ void SurfaceSdlGraphicsManager::detectSupportedFormats() {
 #endif
 	}
 
-	if (!_videoMode.isHwPalette) {
+	if (!_isHwPalette) {
 		// Some tables with standard formats that we always list
 		// as "supported". If frontend code tries to use one of
 		// these, we will perform the necessary format
@@ -875,27 +905,23 @@ void SurfaceSdlGraphicsManager::setupHardwareSize() {
 }
 
 void SurfaceSdlGraphicsManager::initGraphicsSurface() {
-#if SDL_VERSION_ATLEAST(2, 0, 0)
 	Uint32 flags = SDL_SWSURFACE;
-#else
-	Uint32 flags = _videoMode.isHwPalette ? (SDL_HWSURFACE | SDL_HWPALETTE | SDL_DOUBLEBUF) : SDL_SWSURFACE;
-#endif
 	if (_videoMode.fullscreen)
 		flags |= SDL_FULLSCREEN;
-	_hwScreen = SDL_SetVideoMode(_videoMode.hardwareWidth, _videoMode.hardwareHeight, _videoMode.isHwPalette ? 8 : 16,
-				     flags);
+
+	_hwScreen = SDL_SetVideoMode(_videoMode.hardwareWidth, _videoMode.hardwareHeight, 16, flags);
 #if SDL_VERSION_ATLEAST(2, 0, 0)
 	_isDoubleBuf = false;
+	_isHwPalette = false;
 #else
 	_isDoubleBuf = flags & SDL_DOUBLEBUF;
+	_isHwPalette = flags & SDL_HWPALETTE;
 #endif
 }
 
 bool SurfaceSdlGraphicsManager::loadGFXMode() {
 	_forceRedraw = true;
 
-	// Init isHwPalette. Allow setupHardwareSize to override it.
-	_videoMode.isHwPalette = false;
 	setupHardwareSize();
 
 	//
@@ -1020,7 +1046,7 @@ bool SurfaceSdlGraphicsManager::loadGFXMode() {
 	if (_tmpscreen2 == nullptr)
 		error("allocating _tmpscreen2 failed");
 
-	if (_videoMode.isHwPalette) {
+	if (_isHwPalette) {
 		SDL_SetColors(_tmpscreen2, _overlayPalette, 0, 256);
 		SDL_SetColors(_overlayscreen, _overlayPalette, 0, 256);
 	}
@@ -1217,11 +1243,11 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
 		SDL_SetColors(_screen, _currentPalette + _paletteDirtyStart,
 			_paletteDirtyStart,
 			_paletteDirtyEnd - _paletteDirtyStart);
-		if (_videoMode.isHwPalette)
+		if (_isHwPalette)
 			SDL_SetColors(_tmpscreen, _currentPalette + _paletteDirtyStart,
 				      _paletteDirtyStart,
 				      _paletteDirtyEnd - _paletteDirtyStart);
-		if (_videoMode.isHwPalette && !_isInOverlayPalette)
+		if (_isHwPalette && !_isInOverlayPalette)
 			SDL_SetColors(_hwScreen, _currentPalette + _paletteDirtyStart,
 				       _paletteDirtyStart,
 				       _paletteDirtyEnd - _paletteDirtyStart);
@@ -1271,7 +1297,7 @@ void SurfaceSdlGraphicsManager::internUpdateScreen() {
 	updateOSD();
 #endif
 
-	if (_videoMode.isHwPalette && _isInOverlayPalette != _overlayVisible) {
+	if (_isHwPalette && _isInOverlayPalette != _overlayVisible) {
 		SDL_SetColors(_hwScreen, _overlayVisible ? _overlayPalette : _currentPalette, 0, 256);
 		_forceRedraw = true;
 		_isInOverlayPalette = _overlayVisible;
@@ -1893,7 +1919,7 @@ void SurfaceSdlGraphicsManager::clearOverlay() {
 	SDL_LockSurface(_overlayscreen);
 
 	// Transpose from game palette to RGB332 (overlay palette)
-	if (_videoMode.isHwPalette) {
+	if (_isHwPalette) {
 		byte *p = (byte *)(_tmpscreen->pixels) + _maxExtraPixels * _tmpscreen->pitch + _maxExtraPixels * _tmpscreen->format->BytesPerPixel;
 		int pitchSkip = _tmpscreen->pitch - _videoMode.screenWidth;
 		for (int y = 0; y < _videoMode.screenHeight; y++) {
@@ -2097,7 +2123,7 @@ void SurfaceSdlGraphicsManager::setMouseCursor(const void *buf, uint w, uint h,
 #ifndef USE_RGB_COLOR
 		assert(format->bytesPerPixel == 1);
 #else
-		assert(format->bytesPerPixel == 1 || !_videoMode.isHwPalette);
+		assert(format->bytesPerPixel == 1 || !_isHwPalette);
 #endif
 
 		if (format->bytesPerPixel != _cursorFormat.bytesPerPixel) {
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.h b/backends/graphics/surfacesdl/surfacesdl-graphics.h
index be5035c78c4..25f00da2ddc 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.h
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.h
@@ -219,7 +219,7 @@ protected:
 	SDL_Surface *_overlayscreen;
 	bool _useOldSrc;
 	Graphics::PixelFormat _overlayFormat;
-	bool _isDoubleBuf;
+	bool _isDoubleBuf, _isHwPalette;
 
 	enum {
 		kTransactionNone = 0,
@@ -262,8 +262,8 @@ protected:
 		bool aspectRatioCorrection;
 		AspectRatio desiredAspectRatio;
 		bool filtering;
-		bool isHwPalette;
 
+		int mode;
 #if SDL_VERSION_ATLEAST(2, 0, 0)
 		int stretchMode;
 #endif
@@ -286,6 +286,7 @@ protected:
 			// desiredAspectRatio set to (0, 0) by AspectRatio constructor
 			filtering = false;
 
+			mode = GFX_SURFACESDL;
 #if SDL_VERSION_ATLEAST(2, 0, 0)
 			stretchMode = 0;
 #endif


Commit: bcc92593825aba9e3e8e87cf615168ab016dcb54
    https://github.com/scummvm/scummvm/commit/bcc92593825aba9e3e8e87cf615168ab016dcb54
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2023-10-29T02:02:11+02:00

Commit Message:
BACKENDS: Report if the backend supports cursors with alpha channels

Changed paths:
    backends/graphics/opengl/opengl-graphics.cpp
    backends/graphics/surfacesdl/surfacesdl-graphics.cpp
    backends/graphics3d/android/android-graphics3d.cpp
    backends/graphics3d/ios/ios-graphics3d.cpp
    backends/platform/3ds/osystem-graphics.cpp
    backends/platform/dc/dcmain.cpp
    backends/platform/ds/ds-graphics.cpp
    backends/platform/ios7/ios7_osys_main.cpp
    backends/platform/libretro/src/libretro-os-base.cpp
    backends/platform/psp/osys_psp.cpp
    backends/platform/wii/osystem.cpp
    common/system.h
    graphics/cursorman.cpp
    gui/ThemeEngine.cpp
    gui/ThemeEngine.h


diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 5fa991e78d8..fd573a58fec 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -112,6 +112,7 @@ bool OpenGLGraphicsManager::hasFeature(OSystem::Feature f) const {
 	switch (f) {
 	case OSystem::kFeatureAspectRatioCorrection:
 	case OSystem::kFeatureCursorPalette:
+	case OSystem::kFeatureCursorAlpha:
 	case OSystem::kFeatureFilteringMode:
 	case OSystem::kFeatureStretchMode:
 	case OSystem::kFeatureCursorMask:
diff --git a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
index f9779af3bdf..6d9d8d062dd 100644
--- a/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
+++ b/backends/graphics/surfacesdl/surfacesdl-graphics.cpp
@@ -218,6 +218,7 @@ bool SurfaceSdlGraphicsManager::hasFeature(OSystem::Feature f) const {
 		(f == OSystem::kFeatureVSync) ||
 #endif
 		(f == OSystem::kFeatureCursorPalette) ||
+		(f == OSystem::kFeatureCursorAlpha && !_isHwPalette) ||
 		(f == OSystem::kFeatureIconifyWindow) ||
 		(f == OSystem::kFeatureCursorMask);
 }
@@ -2066,7 +2067,7 @@ void SurfaceSdlGraphicsManager::setMouseCursor(const void *buf, uint w, uint h,
 	}
 
 #ifdef USE_RGB_COLOR
-	if (mask && format && format->bytesPerPixel > 1) {
+	if (mask && format && format->bytesPerPixel > 1 && !_isHwPalette) {
 		const uint numPixels = w * h;
 		const uint inBPP = format->bytesPerPixel;
 
@@ -2120,11 +2121,7 @@ void SurfaceSdlGraphicsManager::setMouseCursor(const void *buf, uint w, uint h,
 	bool formatChanged = false;
 
 	if (format) {
-#ifndef USE_RGB_COLOR
-		assert(format->bytesPerPixel == 1);
-#else
 		assert(format->bytesPerPixel == 1 || !_isHwPalette);
-#endif
 
 		if (format->bytesPerPixel != _cursorFormat.bytesPerPixel) {
 			formatChanged = true;
diff --git a/backends/graphics3d/android/android-graphics3d.cpp b/backends/graphics3d/android/android-graphics3d.cpp
index d4a95f79fa5..f3aa931aff8 100644
--- a/backends/graphics3d/android/android-graphics3d.cpp
+++ b/backends/graphics3d/android/android-graphics3d.cpp
@@ -500,6 +500,7 @@ int AndroidGraphics3dManager::getGraphicsMode() const {
 
 bool AndroidGraphics3dManager::hasFeature(OSystem::Feature f) const {
 	if (f == OSystem::kFeatureCursorPalette ||
+	        f == OSystem::kFeatureCursorAlpha ||
 	        f == OSystem::kFeatureOpenGLForGame ||
 	        f == OSystem::kFeatureAspectRatioCorrection) {
 		return true;
diff --git a/backends/graphics3d/ios/ios-graphics3d.cpp b/backends/graphics3d/ios/ios-graphics3d.cpp
index 17b0345cbfa..0bcab86afd8 100644
--- a/backends/graphics3d/ios/ios-graphics3d.cpp
+++ b/backends/graphics3d/ios/ios-graphics3d.cpp
@@ -172,6 +172,7 @@ bool iOSGraphics3dManager::hasFeature(OSystem::Feature f) const {
 	if ((f == OSystem::kFeatureOpenGLForGame) ||
 		(f == OSystem::kFeatureAspectRatioCorrection) ||
 		(f == OSystem::kFeatureStretchMode) ||
+		(f == OSystem::kFeatureCursorAlpha) ||
 		(f == OSystem::kFeatureOverlaySupportsAlpha && _overlayFormat.aBits() > 3)) {
 		return true;
 	}
diff --git a/backends/platform/3ds/osystem-graphics.cpp b/backends/platform/3ds/osystem-graphics.cpp
index 3094f93ef07..6743f6d2972 100644
--- a/backends/platform/3ds/osystem-graphics.cpp
+++ b/backends/platform/3ds/osystem-graphics.cpp
@@ -127,6 +127,7 @@ void OSystem_3DS::destroy3DSGraphics() {
 
 bool OSystem_3DS::hasFeature(OSystem::Feature f) {
 	return (f == OSystem::kFeatureCursorPalette ||
+	        f == OSystem::kFeatureCursorAlpha ||
 	        f == OSystem::kFeatureFilteringMode ||
 	        f == OSystem::kFeatureOverlaySupportsAlpha ||
 	        f == OSystem::kFeatureKbdMouseSpeed ||
diff --git a/backends/platform/dc/dcmain.cpp b/backends/platform/dc/dcmain.cpp
index 0acc1098022..f40aca0efed 100644
--- a/backends/platform/dc/dcmain.cpp
+++ b/backends/platform/dc/dcmain.cpp
@@ -166,6 +166,7 @@ bool OSystem_Dreamcast::hasFeature(Feature f)
   case kFeatureVirtualKeyboard:
   case kFeatureOverlaySupportsAlpha:
   case kFeatureCursorPalette:
+  case kFeatureCursorAlpha:
 	return true;
   default:
 	return false;
diff --git a/backends/platform/ds/ds-graphics.cpp b/backends/platform/ds/ds-graphics.cpp
index 658cd12b373..c3202654e83 100644
--- a/backends/platform/ds/ds-graphics.cpp
+++ b/backends/platform/ds/ds-graphics.cpp
@@ -219,7 +219,7 @@ void OSystem_DS::setSubScreen(int32 x, int32 y, int32 sx, int32 sy) {
 }
 
 bool OSystem_DS::hasFeature(Feature f) {
-	return (f == kFeatureCursorPalette) || (f == kFeatureStretchMode) || (f == kFeatureVirtualKeyboard) || (f == kFeatureTouchscreen);
+	return (f == kFeatureCursorPalette) || (f == kFeatureCursorAlpha) || (f == kFeatureStretchMode) || (f == kFeatureVirtualKeyboard) || (f == kFeatureTouchscreen);
 }
 
 void OSystem_DS::setFeatureState(Feature f, bool enable) {
diff --git a/backends/platform/ios7/ios7_osys_main.cpp b/backends/platform/ios7/ios7_osys_main.cpp
index 09c83692e30..0be4d416c9a 100644
--- a/backends/platform/ios7/ios7_osys_main.cpp
+++ b/backends/platform/ios7/ios7_osys_main.cpp
@@ -143,6 +143,7 @@ void OSystem_iOS7::initBackend() {
 bool OSystem_iOS7::hasFeature(Feature f) {
 	switch (f) {
 	case kFeatureCursorPalette:
+	case kFeatureCursorAlpha:
 	case kFeatureFilteringMode:
 	case kFeatureVirtualKeyboard:
 #if TARGET_OS_IOS
diff --git a/backends/platform/libretro/src/libretro-os-base.cpp b/backends/platform/libretro/src/libretro-os-base.cpp
index bbc20de335e..6b2962f2906 100644
--- a/backends/platform/libretro/src/libretro-os-base.cpp
+++ b/backends/platform/libretro/src/libretro-os-base.cpp
@@ -130,7 +130,7 @@ void OSystem_libretro::engineDone() {
 }
 
 bool OSystem_libretro::hasFeature(Feature f) {
-	return (f == OSystem::kFeatureCursorPalette);
+	return (f == OSystem::kFeatureCursorPalette) || (f == OSystem::kFeatureCursorAlpha);
 }
 
 void OSystem_libretro::setFeatureState(Feature f, bool enable) {
diff --git a/backends/platform/psp/osys_psp.cpp b/backends/platform/psp/osys_psp.cpp
index e6324fe063c..de541fc4a9f 100644
--- a/backends/platform/psp/osys_psp.cpp
+++ b/backends/platform/psp/osys_psp.cpp
@@ -107,7 +107,7 @@ void OSystem_PSP::engineDone() {
 }
 
 bool OSystem_PSP::hasFeature(Feature f) {
-	return (f == kFeatureOverlaySupportsAlpha || f == kFeatureCursorPalette ||
+	return (f == kFeatureOverlaySupportsAlpha || f == kFeatureCursorPalette || f == kFeatureCursorAlpha ||
 			f == kFeatureKbdMouseSpeed || f == kFeatureJoystickDeadzone);
 }
 
diff --git a/backends/platform/wii/osystem.cpp b/backends/platform/wii/osystem.cpp
index d9b54826371..070ca17d7a0 100644
--- a/backends/platform/wii/osystem.cpp
+++ b/backends/platform/wii/osystem.cpp
@@ -176,6 +176,7 @@ bool OSystem_Wii::hasFeature(Feature f) {
 	return (f == kFeatureFullscreenMode) ||
 			(f == kFeatureAspectRatioCorrection) ||
 			(f == kFeatureCursorPalette) ||
+			(f == kFeatureCursorAlpha) ||
 			(f == kFeatureOverlaySupportsAlpha) ||
 			(f == kFeatureTouchscreen);
 }
diff --git a/common/system.h b/common/system.h
index 578c0eb6162..291e34ab1b9 100644
--- a/common/system.h
+++ b/common/system.h
@@ -460,6 +460,12 @@ public:
 		 */
 		kFeatureCursorPalette,
 
+		/**
+		 * Backends supporting this feature allow cursors to contain an alpha
+		 * channel.
+		 */
+		kFeatureCursorAlpha,
+
 		/**
 		 * Backends supporting this feature allow specifying a mask for a
 		 * cursor instead of a key color.
diff --git a/graphics/cursorman.cpp b/graphics/cursorman.cpp
index 8dc7784d352..6727422433d 100644
--- a/graphics/cursorman.cpp
+++ b/graphics/cursorman.cpp
@@ -61,11 +61,9 @@ bool CursorManager::showMouse(bool visible) {
 
 void CursorManager::pushCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format, const byte *mask) {
 	PixelFormat pixelFormat;
-#ifdef USE_RGB_COLOR
 	if (format)
 		pixelFormat = *format;
 	else
-#endif
 		pixelFormat = PixelFormat::createFormatCLUT8();
 
 	Surface surf;
@@ -124,11 +122,9 @@ void CursorManager::popAllCursors() {
 
 void CursorManager::replaceCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format, const byte *mask) {
 	PixelFormat pixelFormat;
-#ifdef USE_RGB_COLOR
 	if (format)
 		pixelFormat = *format;
 	else
-#endif
 		pixelFormat = PixelFormat::createFormatCLUT8();
 
 	Surface surf;
@@ -280,12 +276,8 @@ void CursorManager::lock(bool locked) {
 }
 
 CursorManager::Cursor::Cursor(const Surface &surf, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const byte *mask) {
-#ifdef USE_RGB_COLOR
 	const uint32 keycolor_mask = (((uint32) -1) >> (sizeof(uint32) * 8 - surf.format.bytesPerPixel * 8));
 	_keycolor = keycolor & keycolor_mask;
-#else
-	_keycolor = keycolor & 0xFF;
-#endif
 	_size = surf.w * surf.h * surf.format.bytesPerPixel;
 
 	// make sure that the width * bytesPerPixel == pitch
diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp
index 1e42e0cd9cc..bffdcbd9de0 100644
--- a/gui/ThemeEngine.cpp
+++ b/gui/ThemeEngine.cpp
@@ -230,10 +230,8 @@ ThemeEngine::ThemeEngine(Common::String id, GraphicsMode mode) :
 	_cursorHotspotX = _cursorHotspotY = 0;
 	_cursorWidth = _cursorHeight = 0;
 	_cursorTransparent = 255;
-#ifndef USE_RGB_COLOR
 	_cursorFormat = Graphics::PixelFormat::createFormatCLUT8();
 	_cursorPalSize = 0;
-#endif
 
 	// We prefer files in archive bundles over the common search paths.
 	_themeFiles.add("default", &SearchMan, 0, false);
@@ -396,9 +394,8 @@ void ThemeEngine::refresh() {
 		_system->showOverlay();
 
 		if (_useCursor) {
-#ifndef USE_RGB_COLOR
-			CursorMan.replaceCursorPalette(_cursorPal, 0, _cursorPalSize);
-#endif
+			if (_cursorPalSize)
+				CursorMan.replaceCursorPalette(_cursorPal, 0, _cursorPalSize);
 			CursorMan.replaceCursor(_cursor, _cursorWidth, _cursorHeight, _cursorHotspotX, _cursorHotspotY, _cursorTransparent, true, &_cursorFormat);
 		}
 	}
@@ -1575,20 +1572,26 @@ bool ThemeEngine::createCursor(const Common::String &filename, int hotspotX, int
 	_cursorWidth = cursor->w;
 	_cursorHeight = cursor->h;
 
-#ifdef USE_RGB_COLOR
-	_cursorFormat = cursor->format;
-	_cursorTransparent = _cursorFormat.RGBToColor(0xFF, 0, 0xFF);
+	_cursorTransparent = 255;
+	_cursorFormat = Graphics::PixelFormat::createFormatCLUT8();
+	_cursorPalSize = 0;
 
-	// Allocate a new buffer for the cursor
-	delete[] _cursor;
-	_cursor = new byte[_cursorWidth * _cursorHeight * _cursorFormat.bytesPerPixel];
-	assert(_cursor);
-	Graphics::copyBlit(_cursor, (const byte *)cursor->getPixels(),
-	                   _cursorWidth * _cursorFormat.bytesPerPixel, cursor->pitch,
-	                   _cursorWidth, _cursorHeight, _cursorFormat.bytesPerPixel);
+	if (_system->hasFeature(OSystem::kFeatureCursorAlpha)) {
+		_cursorFormat = cursor->format;
+		_cursorTransparent = _cursorFormat.RGBToColor(0xFF, 0, 0xFF);
+
+		// Allocate a new buffer for the cursor
+		delete[] _cursor;
+		_cursor = new byte[_cursorWidth * _cursorHeight * _cursorFormat.bytesPerPixel];
+		assert(_cursor);
+		Graphics::copyBlit(_cursor, (const byte *)cursor->getPixels(),
+		                   _cursorWidth * _cursorFormat.bytesPerPixel, cursor->pitch,
+		                   _cursorWidth, _cursorHeight, _cursorFormat.bytesPerPixel);
+
+		_useCursor = true;
+		return true;
+	}
 
-	_useCursor = true;
-#else
 	if (!_system->hasFeature(OSystem::kFeatureCursorPalette))
 		return true;
 
@@ -1654,7 +1657,6 @@ bool ThemeEngine::createCursor(const Common::String &filename, int hotspotX, int
 
 	_useCursor = true;
 	_cursorPalSize = colorsFound;
-#endif
 
 	return true;
 }
@@ -2116,9 +2118,8 @@ Common::String ThemeEngine::getThemeId(const Common::String &filename) {
 
 void ThemeEngine::showCursor() {
 	if (_useCursor) {
-#ifndef USE_RGB_COLOR
-		CursorMan.pushCursorPalette(_cursorPal, 0, _cursorPalSize);
-#endif
+		if (_cursorPalSize)
+			CursorMan.pushCursorPalette(_cursorPal, 0, _cursorPalSize);
 		CursorMan.pushCursor(_cursor, _cursorWidth, _cursorHeight, _cursorHotspotX, _cursorHotspotY, _cursorTransparent, true, &_cursorFormat);
 		CursorMan.showMouse(true);
 	}
@@ -2126,9 +2127,8 @@ void ThemeEngine::showCursor() {
 
 void ThemeEngine::hideCursor() {
 	if (_useCursor) {
-#ifndef USE_RGB_COLOR
-		CursorMan.popCursorPalette();
-#endif
+		if (_cursorPalSize)
+			CursorMan.popCursorPalette();
 		CursorMan.popCursor();
 	}
 }
diff --git a/gui/ThemeEngine.h b/gui/ThemeEngine.h
index e6649b9cf15..04e6cc65dbe 100644
--- a/gui/ThemeEngine.h
+++ b/gui/ThemeEngine.h
@@ -821,13 +821,12 @@ protected:
 	uint32 _cursorTransparent;
 	byte *_cursor;
 	uint _cursorWidth, _cursorHeight;
-#ifndef USE_RGB_COLOR
+
 	enum {
 		MAX_CURS_COLORS = 255
 	};
 	byte _cursorPal[3 * MAX_CURS_COLORS];
 	byte _cursorPalSize;
-#endif
 
 	Common::Rect _clip;
 };


Commit: b6947c78eb5daa9e290402c5634fc9987b1481ac
    https://github.com/scummvm/scummvm/commit/b6947c78eb5daa9e290402c5634fc9987b1481ac
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2023-10-29T02:02:11+02:00

Commit Message:
TESTBED: Add a test case for alpha cursors

Changed paths:
    engines/testbed/graphics.cpp
    engines/testbed/graphics.h


diff --git a/engines/testbed/graphics.cpp b/engines/testbed/graphics.cpp
index 4e00e39e6ff..fc626d488c8 100644
--- a/engines/testbed/graphics.cpp
+++ b/engines/testbed/graphics.cpp
@@ -58,6 +58,7 @@ GFXTestSuite::GFXTestSuite() {
 
 	// Mouse Layer tests (Palettes and movements)
 	addTest("PalettizedCursors", &GFXtests::palettizedCursors);
+	addTest("AlphaCursors", &GFXtests::alphaCursors);
 	addTest("MaskedCursors", &GFXtests::maskedCursors);
 	addTest("MouseMovements", &GFXtests::mouseMovements);
 	// FIXME: Scaled cursor crash with odd dimmensions
@@ -724,6 +725,78 @@ TestExitStatus GFXtests::palettizedCursors() {
 	return passed;
 }
 
+/**
+ * Tests Alpha cursors.
+ * Method: Create a purple colored cursor with alpha transparency, should be able to move it. Once you click test terminates
+ */
+TestExitStatus GFXtests::alphaCursors() {
+
+	Testsuite::clearScreen();
+	Common::String info = "Alpha Cursors test.\n "
+		"Here you should expect to see a purple mouse cursor rendered with mouse graphics.\n"
+		"You would be able to move the cursor. The cursor should be round, and the background should be visible underneath it.\n"
+		"The test finishes when mouse (L/R) is clicked.";
+
+
+	if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) {
+		Testsuite::logPrintf("Info! Skipping test : Alpha Cursors\n");
+		return kTestSkipped;
+	}
+
+	TestExitStatus passed = kTestPassed;
+	bool isFeaturePresent = g_system->hasFeature(OSystem::kFeatureCursorAlpha);
+
+	if (isFeaturePresent) {
+		const uint32 cursorData[] = {
+			0xFF00FF00, 0xFF00FF00, 0xFF00FF00, 0xFF00FF3F, 0xFF00FF00, 0xFF00FF00, 0xFF00FF00,
+			0xFF00FF00, 0xFF00FF3F, 0xFF00FF5F, 0xFF00FF7F, 0xFF00FF5F, 0xFF00FF3F, 0xFF00FF00,
+			0xFF00FF00, 0xFF00FF5F, 0xFF00FF7F, 0xFF00FF9F, 0xFF00FF7F, 0xFF00FF5F, 0xFF00FF00,
+			0xFF00FF3F, 0xFF00FF7F, 0xFF00FF9F, 0xFF00FFBF, 0xFF00FF9F, 0xFF00FF7F, 0xFF00FF3F,
+			0xFF00FF00, 0xFF00FF5F, 0xFF00FF7F, 0xFF00FF9F, 0xFF00FF7F, 0xFF00FF5F, 0xFF00FF00,
+			0xFF00FF00, 0xFF00FF3F, 0xFF00FF5F, 0xFF00FF7F, 0xFF00FF5F, 0xFF00FF3F, 0xFF00FF00,
+			0xFF00FF00, 0xFF00FF00, 0xFF00FF00, 0xFF00FF3F, 0xFF00FF00, 0xFF00FF00, 0xFF00FF00
+		};
+
+		Graphics::PixelFormat format(4, 8, 8, 8, 8, 24, 16, 8, 0);
+		CursorMan.replaceCursor(cursorData, 7, 7, 3, 3, 0, false, &format);
+		CursorMan.showMouse(true);
+
+		bool waitingForClick = true;
+		while (waitingForClick) {
+			Common::Event event;
+			while (g_system->getEventManager()->pollEvent(event)) {
+				if (event.type == Common::EVENT_LBUTTONDOWN || event.type == Common::EVENT_RBUTTONDOWN) {
+					waitingForClick = false;
+				}
+			}
+
+			g_system->delayMillis(10);
+			g_system->updateScreen();
+		}
+
+		if (Testsuite::handleInteractiveInput("Which color did the cursor appear to you?", "Purple", "Any other", kOptionRight)) {
+			Testsuite::logDetailedPrintf("Couldn't use alpha transparency for rendering cursor\n");
+			passed = kTestFailed;
+		}
+
+		if (Testsuite::handleInteractiveInput("Which shape did the cursor appear to you?", "Round", "Any other", kOptionRight)) {
+			Testsuite::logDetailedPrintf("Couldn't use alpha transparency for rendering cursor\n");
+			passed = kTestFailed;
+		}
+
+		if (!Testsuite::handleInteractiveInput("     Did test run as was described?     ")) {
+			passed = kTestFailed;
+		}
+
+		// Done with cursors, make them invisible, any other test the could simply make it visible
+		CursorMan.showMouse(false);
+	} else {
+		Testsuite::displayMessage("feature not supported");
+	}
+
+	return passed;
+}
+
 /**
  * Tests Masked cursors.
  * Method: Create a cursor with a transparent, mask, inverted, and color-inverted areas, it should behave properly over colored areas. Once you click test terminates
@@ -743,6 +816,7 @@ TestExitStatus GFXtests::maskedCursors() {
 	TestExitStatus passed = kTestPassed;
 	bool isFeaturePresent = g_system->hasFeature(OSystem::kFeatureCursorMask);
 	bool haveCursorPalettes = g_system->hasFeature(OSystem::kFeatureCursorPalette);
+	bool haveCursorAlpha = g_system->hasFeature(OSystem::kFeatureCursorAlpha);
 
 	g_system->delayMillis(1000);
 
@@ -880,60 +954,62 @@ TestExitStatus GFXtests::maskedCursors() {
 			}
 		}
 
-#ifdef USE_RGB_COLOR
 		Common::String rgbInfo = "Try again with a cursor using RGB data?";
 
 		if (!Testsuite::handleInteractiveInput(rgbInfo, "OK", "Skip", kOptionRight)) {
-			g_system->delayMillis(500);
+			if (haveCursorAlpha) {
+				g_system->delayMillis(500);
 
-			Graphics::PixelFormat rgbaFormat = Graphics::createPixelFormat<8888>();
+				Graphics::PixelFormat rgbaFormat = Graphics::createPixelFormat<8888>();
 
-			uint32 rgbaCursorData[16 * 16];
-			for (uint i = 0; i < 16 * 16; i++) {
-				byte colorByte = cursorData[i];
-				byte r = newPalette[colorByte * 3 + 0];
-				byte g = newPalette[colorByte * 3 + 1];
-				byte b = newPalette[colorByte * 3 + 2];
+				uint32 rgbaCursorData[16 * 16];
+				for (uint i = 0; i < 16 * 16; i++) {
+					byte colorByte = cursorData[i];
+					byte r = newPalette[colorByte * 3 + 0];
+					byte g = newPalette[colorByte * 3 + 1];
+					byte b = newPalette[colorByte * 3 + 2];
 
-				rgbaCursorData[i] = rgbaFormat.ARGBToColor(255, r, g, b);
-			}
-
-			CursorMan.replaceCursor(rgbaCursorData, 16, 16, 1, 1, 0, false, &rgbaFormat, maskData);
-
-			waitingForClick = true;
-			while (waitingForClick) {
-				Common::Event event;
-				while (g_system->getEventManager()->pollEvent(event)) {
-					if (event.type == Common::EVENT_LBUTTONDOWN || event.type == Common::EVENT_RBUTTONDOWN) {
-						waitingForClick = false;
-					}
+					rgbaCursorData[i] = rgbaFormat.ARGBToColor(255, r, g, b);
 				}
 
-				g_system->delayMillis(10);
-				g_system->updateScreen();
-			}
+				CursorMan.replaceCursor(rgbaCursorData, 16, 16, 1, 1, 0, false, &rgbaFormat, maskData);
 
-			if (!Testsuite::handleInteractiveInput("Was the part of the cursor to the right of the 'T' transparent?", "Yes", "No", kOptionLeft)) {
-				return kTestFailed;
-			}
+				waitingForClick = true;
+				while (waitingForClick) {
+					Common::Event event;
+					while (g_system->getEventManager()->pollEvent(event)) {
+						if (event.type == Common::EVENT_LBUTTONDOWN || event.type == Common::EVENT_RBUTTONDOWN) {
+							waitingForClick = false;
+						}
+					}
 
-			if (!Testsuite::handleInteractiveInput("Was the part of the cursor to the right of the 'O' opaque?", "Yes", "No", kOptionLeft)) {
-				return kTestFailed;
-			}
+					g_system->delayMillis(10);
+					g_system->updateScreen();
+				}
 
-			if (haveInverted) {
-				if (!Testsuite::handleInteractiveInput("Was the part of the cursor to the right of the 'I' inverted?", "Yes", "No", kOptionLeft)) {
+				if (!Testsuite::handleInteractiveInput("Was the part of the cursor to the right of the 'T' transparent?", "Yes", "No", kOptionLeft)) {
 					return kTestFailed;
 				}
-			}
 
-			if (haveColorXorBlend) {
-				if (!Testsuite::handleInteractiveInput("Was the part of the cursor to the right of the 'C' inverted according to the color to the left of it?", "Yes", "No", kOptionLeft)) {
+				if (!Testsuite::handleInteractiveInput("Was the part of the cursor to the right of the 'O' opaque?", "Yes", "No", kOptionLeft)) {
 					return kTestFailed;
 				}
+
+				if (haveInverted) {
+					if (!Testsuite::handleInteractiveInput("Was the part of the cursor to the right of the 'I' inverted?", "Yes", "No", kOptionLeft)) {
+						return kTestFailed;
+					}
+				}
+
+				if (haveColorXorBlend) {
+					if (!Testsuite::handleInteractiveInput("Was the part of the cursor to the right of the 'C' inverted according to the color to the left of it?", "Yes", "No", kOptionLeft)) {
+						return kTestFailed;
+					}
+				}
+			} else {
+				Testsuite::displayMessage("feature not supported");
 			}
 		}
-#endif
 
 		CursorMan.showMouse(false);
 	} else {
diff --git a/engines/testbed/graphics.h b/engines/testbed/graphics.h
index d7b2525c589..118ab47e936 100644
--- a/engines/testbed/graphics.h
+++ b/engines/testbed/graphics.h
@@ -45,6 +45,7 @@ TestExitStatus fullScreenMode();
 TestExitStatus filteringMode();
 TestExitStatus aspectRatio();
 TestExitStatus palettizedCursors();
+TestExitStatus alphaCursors();
 TestExitStatus maskedCursors();
 TestExitStatus mouseMovements();
 TestExitStatus copyRectToScreen();




More information about the Scummvm-git-logs mailing list