[Scummvm-git-logs] scummvm master -> 1acd4afedf2641965432a4085b8ba0507f624318

sev- noreply at scummvm.org
Wed Apr 24 23:04:27 UTC 2024


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:
1acd4afedf ULTIMA4: Support pixel formats other than RGB565


Commit: 1acd4afedf2641965432a4085b8ba0507f624318
    https://github.com/scummvm/scummvm/commit/1acd4afedf2641965432a4085b8ba0507f624318
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2024-04-25T01:04:23+02:00

Commit Message:
ULTIMA4: Support pixel formats other than RGB565

Changed paths:
    engines/ultima/ultima4/controllers/intro_controller.cpp
    engines/ultima/ultima4/gfx/image.cpp
    engines/ultima/ultima4/gfx/image.h
    engines/ultima/ultima4/gfx/imagemgr.cpp
    engines/ultima/ultima4/gfx/scale.cpp
    engines/ultima/ultima4/gfx/screen.cpp
    engines/ultima/ultima4/map/tile.cpp
    engines/ultima/ultima4/views/tileview.cpp
    engines/ultima/ultima4/views/view.cpp


diff --git a/engines/ultima/ultima4/controllers/intro_controller.cpp b/engines/ultima/ultima4/controllers/intro_controller.cpp
index 9fba5da2c07..5ebdf3dac1c 100644
--- a/engines/ultima/ultima4/controllers/intro_controller.cpp
+++ b/engines/ultima/ultima4/controllers/intro_controller.cpp
@@ -189,7 +189,7 @@ IntroController::IntroController() : Controller(1),
 	Common::fill(&_questionTree[0], &_questionTree[15], -1);
 
 	// Setup a separate image surface for rendering the animated map on
-	_mapScreen = Image::create(g_screen->w, g_screen->h, false, Image::HARDWARE);
+	_mapScreen = Image::create(g_screen->w, g_screen->h, g_screen->format);
 	_mapArea.setDest(_mapScreen);
 
 	// initialize menus
@@ -1493,8 +1493,7 @@ void IntroController::getTitleSourceData() {
 			_titles[i]._srcImage = Image::create(
 				_titles[i]._rw * info->_prescale,
 				_titles[i]._rh * info->_prescale,
-			    info->_image->isIndexed() && _titles[i]._method != MAP,
-				Image::HARDWARE);
+				_titles[i]._method == MAP ? _mapScreen->format() : info->_image->format());
 			if (_titles[i]._srcImage->isIndexed())
 				_titles[i]._srcImage->setPaletteFromImage(info->_image);
 
@@ -1590,14 +1589,12 @@ void IntroController::getTitleSourceData() {
 		if (_titles[i]._srcImage)
 			_titles[i]._srcImage->alphaOff();
 
-		bool indexed = info->_image->isIndexed() && _titles[i]._method != MAP;
 		// create the initial animation frame
 		_titles[i]._destImage = Image::create(
 			2 + (_titles[i]._prescaled ? SCALED(_titles[i]._rw) : _titles[i]._rw) * info->_prescale ,
-		    2 + (_titles[i]._prescaled ? SCALED(_titles[i]._rh) : _titles[i]._rh) * info->_prescale,
-		    indexed,
-			Image::HARDWARE);
-		if (indexed)
+			2 + (_titles[i]._prescaled ? SCALED(_titles[i]._rh) : _titles[i]._rh) * info->_prescale,
+			_titles[i]._method == MAP ? _mapScreen->format() : info->_image->format());
+		if (_titles[i]._destImage->isIndexed())
 			_titles[i]._destImage->setPaletteFromImage(info->_image);
 	}
 
diff --git a/engines/ultima/ultima4/gfx/image.cpp b/engines/ultima/ultima4/gfx/image.cpp
index a6b9670f2d2..c9a55cec71e 100644
--- a/engines/ultima/ultima4/gfx/image.cpp
+++ b/engines/ultima/ultima4/gfx/image.cpp
@@ -36,18 +36,23 @@ Image::Image() : _surface(nullptr), _disposeAfterUse(DisposeAfterUse::NO),
 		_paletted(false) {
 }
 
-Image *Image::create(int w, int h, bool paletted, Image::Type type) {
+Image *Image::create(int w, int h) {
 	Image *im = new Image();
-	im->create(w, h, paletted);
+	im->createInternal(w, h, Graphics::PixelFormat::createFormatCLUT8());
 
 	return im;
 }
 
-void Image::create(int w, int h, bool paletted) {
-	_paletted = paletted;
-	_surface = new Graphics::ManagedSurface(w, h, paletted ?
-		Graphics::PixelFormat::createFormatCLUT8() :
-		Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0));
+Image *Image::create(int w, int h, const Graphics::PixelFormat &format) {
+	Image *im = new Image();
+	im->createInternal(w, h, format);
+
+	return im;
+}
+
+void Image::createInternal(int w, int h, const Graphics::PixelFormat &format) {
+	_paletted = format.isCLUT8();
+	_surface = new Graphics::ManagedSurface(w, h, format);
 	_disposeAfterUse = DisposeAfterUse::YES;
 }
 
@@ -64,12 +69,12 @@ Image *Image::createScreenImage() {
 	return screen;
 }
 
-Image *Image::duplicate(Image *image) {
+Image *Image::duplicate(Image *image, const Graphics::PixelFormat &format) {
 	bool alphaOn = image->isAlphaOn();
-	Image *im = create(image->width(), image->height(), false, HARDWARE);
+	Image *im = create(image->width(), image->height(), format);
 
-//    if (image->isIndexed())
-//        im->setPaletteFromImage(image);
+	if (im->isIndexed())
+		im->setPaletteFromImage(image);
 
 	/* Turn alpha off before blitting to non-screen surfaces */
 	if (alphaOn)
@@ -224,7 +229,7 @@ void Image::alphaOff() {
 
 void Image::putPixel(int x, int y, int r, int g, int b, int a) {
 	uint32 color = getColor(r, g, b, a);
-	putPixelIndex(x, y, color);
+	_surface->setPixel(x, y, color);
 }
 
 uint Image::getColor(byte r, byte g, byte b, byte a) {
@@ -322,28 +327,7 @@ void Image::setTransparentIndex(uint index) {
 }
 
 void Image::putPixelIndex(int x, int y, uint index) {
-	int bpp;
-	byte *p;
-
-	bpp = _surface->format.bytesPerPixel;
-	p = (byte *)_surface->getBasePtr(x, y);
-
-	switch (bpp) {
-	case 1:
-		*p = index;
-		break;
-
-	case 2:
-		*((uint16 *)p) = index;
-		break;
-
-	case 4:
-		*reinterpret_cast<uint32 *>(p) = index;
-		break;
-
-	default:
-		error("Unsupported format");
-	}
+	_surface->setPixel(x, y, index);
 }
 
 void Image::fillRect(int x, int y, int w, int h, int r, int g, int b, int a) {
@@ -355,7 +339,7 @@ void Image::getPixel(int x, int y, uint &r, uint &g, uint &b, uint &a) const {
 	uint index;
 	byte r1, g1, b1, a1;
 
-	getPixelIndex(x, y, index);
+	index = _surface->getPixel(x, y);
 
 	if (_surface->format.bytesPerPixel == 1) {
 		uint8 pal[1 * 3];
@@ -374,26 +358,7 @@ void Image::getPixel(int x, int y, uint &r, uint &g, uint &b, uint &a) const {
 }
 
 void Image::getPixelIndex(int x, int y, uint &index) const {
-	int bpp = _surface->format.bytesPerPixel;
-
-	byte *p = (byte *)_surface->getBasePtr(x, y);
-
-	switch (bpp) {
-	case 1:
-		index = *p;
-		break;
-
-	case 2:
-		index = *reinterpret_cast<uint16 *>(p);
-		break;
-
-	case 4:
-		index = *reinterpret_cast<uint32 *>(p);
-		break;
-
-	default:
-		error("Unsupported format");
-	}
+	index = _surface->getPixel(x, y);
 }
 
 Graphics::ManagedSurface *Image::getSurface(Image *d) const {
diff --git a/engines/ultima/ultima4/gfx/image.h b/engines/ultima/ultima4/gfx/image.h
index f68a12981b7..62b9f557249 100644
--- a/engines/ultima/ultima4/gfx/image.h
+++ b/engines/ultima/ultima4/gfx/image.h
@@ -78,19 +78,17 @@ private:
 
 	uint getColor(byte r, byte g, byte b, byte a);
 public:
-	enum Type {
-		HARDWARE,
-		SOFTWARE
-	};
+	/**
+	 * Creates a new palette based image.  Scale is stored to allow drawing
+	 * using U4 (320x200) coordinates, regardless of the actual image scale.
+	 */
+	static Image *create(int w, int h);
 
 	/**
-	 * Creates a new image.  Scale is stored to allow drawing using U4
+	 * Creates a new RGB image.  Scale is stored to allow drawing using U4
 	 * (320x200) coordinates, regardless of the actual image scale.
-	 * Indexed is true for palette based images, or false for RGB images.
-	 * Image type determines whether to create a hardware (i.e. video ram)
-	 * or software (i.e. normal ram) image.
 	 */
-	static Image *create(int w, int h, bool paletted, Type type);
+	static Image *create(int w, int h, const Graphics::PixelFormat &format);
 
 	/**
 	 * Create a special purpose image the represents the whole screen.
@@ -100,14 +98,14 @@ public:
 	/**
 	 * Creates a duplicate of another image
 	 */
-	static Image *duplicate(Image *image);
+	static Image *duplicate(Image *image, const Graphics::PixelFormat &format);
 
 	/**
 	 * Frees the image.
 	 */
 	~Image();
 
-	void create(int w, int h, bool paletted);
+	void createInternal(int w, int h, const Graphics::PixelFormat &format);
 
 	/* palette handling */
 	/**
@@ -247,6 +245,9 @@ public:
 	int height() const {
 		return _surface->h;
 	}
+	Graphics::PixelFormat format() const {
+		return _surface->format;
+	}
 	bool isIndexed() const {
 		return _paletted;
 	}
diff --git a/engines/ultima/ultima4/gfx/imagemgr.cpp b/engines/ultima/ultima4/gfx/imagemgr.cpp
index 549b921d124..887fa8baa7a 100644
--- a/engines/ultima/ultima4/gfx/imagemgr.cpp
+++ b/engines/ultima/ultima4/gfx/imagemgr.cpp
@@ -562,7 +562,7 @@ ImageInfo *ImageMgr::get(const Common::String &name, bool returnUnscaled) {
 				warning("can't load image \"%s\" with type \"%s\"", info->_filename.c_str(), filetype.c_str());
 			} else {
 				const Graphics::Surface *surface = decoder->getSurface();
-				unscaled = Image::create(surface->w, surface->h, decoder->hasPalette(), Image::HARDWARE);
+				unscaled = Image::create(surface->w, surface->h, surface->format);
 				unscaled->blitFrom(*surface);
 
 				if (decoder->hasPalette()) {
@@ -620,10 +620,12 @@ ImageInfo *ImageMgr::get(const Common::String &name, bool returnUnscaled) {
 		break;
 	case FIXUP_BLACKTRANSPARENCYHACK:
 		//Apply transparency shadow hack to ultima4 ega and vga upgrade classic graphics.
-		Image *unscaled_original = unscaled;
-		unscaled = Image::duplicate(unscaled);
-		delete unscaled_original;
 		if (Settings::getInstance()._enhancements && Settings::getInstance()._enhancementsOptions._u4TileTransparencyHack) {
+			// TODO: Pick a more optimal pixel format?
+			Image *unscaled_original = unscaled;
+			unscaled = Image::duplicate(unscaled, Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0));
+			delete unscaled_original;
+
 			int transparency_shadow_size = Settings::getInstance()._enhancementsOptions._u4TrileTransparencyHackShadowBreadth;
 			int black_index = 0;
 			int opacity = Settings::getInstance()._enhancementsOptions._u4TileTransparencyHackPixelShadowOpacity;
diff --git a/engines/ultima/ultima4/gfx/scale.cpp b/engines/ultima/ultima4/gfx/scale.cpp
index 2d62fd5de7e..33537fe2fa1 100644
--- a/engines/ultima/ultima4/gfx/scale.cpp
+++ b/engines/ultima/ultima4/gfx/scale.cpp
@@ -22,6 +22,7 @@
 #include "ultima/ultima4/gfx/image.h"
 #include "ultima/ultima4/gfx/scale.h"
 #include "ultima/ultima4/core/utils.h"
+#include "common/system.h"
 
 namespace Ultima {
 namespace Ultima4 {
@@ -58,7 +59,7 @@ Image *scalePoint(Image *src, int scale, int n) {
 	int x, y, i, j;
 	Image *dest;
 
-	dest = Image::create(src->width() * scale, src->height() * scale, src->isIndexed(), Image::HARDWARE);
+	dest = Image::create(src->width() * scale, src->height() * scale, src->format());
 	if (!dest)
 		return nullptr;
 
@@ -92,7 +93,8 @@ Image *scale2xBilinear(Image *src, int scale, int n) {
 	/* this scaler works only with images scaled by 2x */
 	assertMsg(scale == 2, "invalid scale: %d", scale);
 
-	dest = Image::create(src->width() * scale, src->height() * scale, false, Image::HARDWARE);
+	Graphics::PixelFormat format = src->isIndexed() ? g_system->getScreenFormat() : src->format();
+	dest = Image::create(src->width() * scale, src->height() * scale, format);
 	if (!dest)
 		return nullptr;
 
@@ -194,7 +196,8 @@ Image *scale2xSaI(Image *src, int scale, int N) {
 	/* this scaler works only with images scaled by 2x */
 	assertMsg(scale == 2, "invalid scale: %d", scale);
 
-	dest = Image::create(src->width() * scale, src->height() * scale, false, Image::HARDWARE);
+	Graphics::PixelFormat format = src->isIndexed() ? g_system->getScreenFormat() : src->format();
+	dest = Image::create(src->width() * scale, src->height() * scale, format);
 	if (!dest)
 		return nullptr;
 
@@ -360,7 +363,7 @@ Image *scaleScale2x(Image *src, int scale, int n) {
 	/* this scaler works only with images scaled by 2x or 3x */
 	assertMsg(scale == 2 || scale == 3, "invalid scale: %d", scale);
 
-	dest = Image::create(src->width() * scale, src->height() * scale, src->isIndexed(), Image::HARDWARE);
+	dest = Image::create(src->width() * scale, src->height() * scale, src->format());
 	if (!dest)
 		return nullptr;
 
diff --git a/engines/ultima/ultima4/gfx/screen.cpp b/engines/ultima/ultima4/gfx/screen.cpp
index ece26fe20eb..d4f332ea041 100644
--- a/engines/ultima/ultima4/gfx/screen.cpp
+++ b/engines/ultima/ultima4/gfx/screen.cpp
@@ -83,11 +83,10 @@ Screen::~Screen() {
 }
 
 void Screen::init() {
-	Graphics::PixelFormat SCREEN_FORMAT(2, 5, 6, 5, 0, 11, 5, 0, 0);
 	Common::Point size(SCREEN_WIDTH * settings._scale, SCREEN_HEIGHT * settings._scale);
 
-	initGraphics(size.x, size.y, &SCREEN_FORMAT);
-	create(size.x, size.y, SCREEN_FORMAT);
+	initGraphics(size.x, size.y, nullptr);
+	create(size.x, size.y, g_system->getScreenFormat());
 
 	loadMouseCursors();
 	screenLoadGraphicsFromConf();
@@ -1344,7 +1343,7 @@ Image *Screen::screenScale(Image *src, int scale, int n, int filter) {
 		dest = (*scalerGet("point"))(src, scale, n);
 
 	if (!dest)
-		dest = Image::duplicate(src);
+		dest = Image::duplicate(src, src->format());
 
 	if (isTransparent)
 		dest->setTransparentIndex(transparentIndex);
@@ -1366,7 +1365,7 @@ Image *Screen::screenScaleDown(Image *src, int scale) {
 
 	src->alphaOff();
 
-	dest = Image::create(src->width() / scale, src->height() / scale, src->isIndexed(), Image::HARDWARE);
+	dest = Image::create(src->width() / scale, src->height() / scale, src->format());
 	if (!dest)
 		return nullptr;
 
diff --git a/engines/ultima/ultima4/map/tile.cpp b/engines/ultima/ultima4/map/tile.cpp
index 1505e740bbd..faecfa7bbb2 100644
--- a/engines/ultima/ultima4/map/tile.cpp
+++ b/engines/ultima/ultima4/map/tile.cpp
@@ -158,17 +158,19 @@ void Tile::loadImage() {
 			info->_image->alphaOff();
 
 		if (info) {
+			// Draw the tile from the image we found to our tile image
+			Image *tiles = info->_image;
+			assert(tiles);
+
 			_w = (subimage ? subimage->width() *_scale : info->_width * _scale / info->_prescale);
 			_h = (subimage ? (subimage->height() * _scale) / _frames : (info->_height * _scale / info->_prescale) / _frames);
-			_image = Image::create(_w, _h * _frames, false, Image::HARDWARE);
+			_image = Image::create(_w, _h * _frames, tiles->format());
 
+			if (_image->isIndexed())
+				_image->setPaletteFromImage(tiles);
 
 			//info->image->alphaOff();
 
-			// Draw the tile from the image we found to our tile image
-			Image *tiles = info->_image;
-			assert(tiles);
-
 			if (subimage) {
 				tiles->drawSubRectOn(_image, 0, 0,
 					subimage->left * _scale, subimage->top * _scale,
diff --git a/engines/ultima/ultima4/views/tileview.cpp b/engines/ultima/ultima4/views/tileview.cpp
index 96c0a9837d3..83ec817ff44 100644
--- a/engines/ultima/ultima4/views/tileview.cpp
+++ b/engines/ultima/ultima4/views/tileview.cpp
@@ -30,6 +30,7 @@
 #include "ultima/ultima4/map/tileset.h"
 #include "ultima/ultima4/views/tileview.h"
 #include "ultima/ultima4/ultima4.h"
+#include "common/system.h"
 
 namespace Ultima {
 namespace Ultima4 {
@@ -41,7 +42,7 @@ TileView::TileView(int x, int y, int columns, int rows) :
 	_tileWidth = TILE_WIDTH;
 	_tileHeight = TILE_HEIGHT;
 	_tileSet = g_tileSets->get("base");
-	_animated = Image::create(SCALED(_tileWidth), SCALED(_tileHeight), false, Image::HARDWARE);
+	_animated = Image::create(SCALED(_tileWidth), SCALED(_tileHeight), g_system->getScreenFormat());
 	_dest = nullptr;
 }
 
@@ -52,7 +53,7 @@ TileView::TileView(int x, int y, int columns, int rows, const Common::String &ti
 	_tileWidth = TILE_WIDTH;
 	_tileHeight = TILE_HEIGHT;
 	_tileSet = g_tileSets->get(tileset);
-	_animated = Image::create(SCALED(_tileWidth), SCALED(_tileHeight), false, Image::HARDWARE);
+	_animated = Image::create(SCALED(_tileWidth), SCALED(_tileHeight), g_system->getScreenFormat());
 	_dest = nullptr;
 }
 
@@ -69,7 +70,7 @@ void TileView::reinit() {
 		delete _animated;
 		_animated = nullptr;
 	}
-	_animated = Image::create(SCALED(_tileWidth), SCALED(_tileHeight), false, Image::HARDWARE);
+	_animated = Image::create(SCALED(_tileWidth), SCALED(_tileHeight), _dest ? _dest->format() : g_system->getScreenFormat());
 }
 
 void TileView::loadTile(MapTile &mapTile) {
diff --git a/engines/ultima/ultima4/views/view.cpp b/engines/ultima/ultima4/views/view.cpp
index ef12fcb159d..e98e4b3d276 100644
--- a/engines/ultima/ultima4/views/view.cpp
+++ b/engines/ultima/ultima4/views/view.cpp
@@ -81,7 +81,7 @@ void View::drawHighlighted() {
 	Image *screen = imageMgr->get("screen")->_image;
 
 	Image *tmp = Image::create(SCALED(_highlightBounds.width()),
-		SCALED(_highlightBounds.height()), false, Image::SOFTWARE);
+		SCALED(_highlightBounds.height()), screen->format());
 	if (!tmp)
 		return;
 




More information about the Scummvm-git-logs mailing list