[Scummvm-git-logs] scummvm master -> 21948caada191af9ceb74184fcd5a47fca54216b

bluegr noreply at scummvm.org
Sun Nov 3 07:40:11 UTC 2024


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

Summary:
4700a4110e GRIM: Use the best pixel format for video playback
0825fab676 GRIM: Reduce memory usage for 3bpp textures
88e2764d13 GRIM: Reduce the amount of format conversion for bitmaps
21948caada GRIM: Fix compilation in BE platforms


Commit: 4700a4110e54a20256b5cd8b0c004ec85723ce19
    https://github.com/scummvm/scummvm/commit/4700a4110e54a20256b5cd8b0c004ec85723ce19
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2024-11-03T09:40:07+02:00

Commit Message:
GRIM: Use the best pixel format for video playback

Changed paths:
    engines/grim/gfx_base.cpp
    engines/grim/gfx_base.h
    engines/grim/gfx_opengl.cpp
    engines/grim/gfx_opengl.h
    engines/grim/gfx_opengl_shaders.cpp
    engines/grim/gfx_opengl_shaders.h
    engines/grim/gfx_tinygl.cpp
    engines/grim/gfx_tinygl.h
    engines/grim/grim.cpp
    engines/grim/movie/bink.cpp
    engines/grim/movie/codecs/smush_decoder.cpp
    engines/grim/movie/codecs/smush_decoder.h
    engines/grim/movie/movie.cpp
    engines/grim/movie/movie.h
    engines/grim/movie/mpeg.cpp
    engines/grim/movie/quicktime.cpp
    engines/grim/shaders/grim_smush.fragment


diff --git a/engines/grim/gfx_base.cpp b/engines/grim/gfx_base.cpp
index 6b9f0e725ea..02c2dc486ef 100644
--- a/engines/grim/gfx_base.cpp
+++ b/engines/grim/gfx_base.cpp
@@ -241,4 +241,16 @@ Texture *GfxBase::getSpecialtyTexturePtr(Common::String name) {
 	return &_specialtyTextures[id];
 }
 
+void GfxBase::prepareMovieFrame(Graphics::Surface *frame, const byte *palette) {
+	if (!palette)
+		return prepareMovieFrame(frame);
+
+	Graphics::Surface *converted = frame->convertTo(getMovieFormat(), palette);
+	if (converted) {
+		prepareMovieFrame(converted);
+		converted->free();
+		delete converted;
+	}
+}
+
 }
diff --git a/engines/grim/gfx_base.h b/engines/grim/gfx_base.h
index aab552314f7..77de7cf4e60 100644
--- a/engines/grim/gfx_base.h
+++ b/engines/grim/gfx_base.h
@@ -28,6 +28,7 @@
 #include "common/str.h"
 #include "common/rect.h"
 
+#include "graphics/pixelformat.h"
 #include "graphics/renderer.h"
 
 #include "engines/grim/material.h"
@@ -230,6 +231,8 @@ public:
 	virtual void drawPolygon(const PrimitiveObject *primitive) = 0;
 	virtual void drawDimPlane() {};
 
+	virtual const Graphics::PixelFormat getMovieFormat() const = 0;
+
 	/**
 	 * Prepare a movie-frame for drawing
 	 * performing any necessary conversion
@@ -241,6 +244,7 @@ public:
 	 * @see releaseMovieFrame
 	 */
 	virtual void prepareMovieFrame(Graphics::Surface *frame) = 0;
+	virtual void prepareMovieFrame(Graphics::Surface *frame, const byte *palette);
 	virtual void drawMovieFrame(int offsetX, int offsetY) = 0;
 
 	/**
diff --git a/engines/grim/gfx_opengl.cpp b/engines/grim/gfx_opengl.cpp
index 4950976f917..d182f0f830f 100644
--- a/engines/grim/gfx_opengl.cpp
+++ b/engines/grim/gfx_opengl.cpp
@@ -1666,6 +1666,14 @@ void GfxOpenGL::drawDepthBitmap(int x, int y, int w, int h, const char *data) {
 	glDepthFunc(_depthFunc);
 }
 
+const Graphics::PixelFormat GfxOpenGL::getMovieFormat() const {
+#ifdef SCUMM_BIG_ENDIAN
+	return Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
+#else
+	return Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24);
+#endif
+}
+
 void GfxOpenGL::prepareMovieFrame(Graphics::Surface *frame) {
 	int height = frame->h;
 	int width = frame->w;
@@ -1683,29 +1691,11 @@ void GfxOpenGL::prepareMovieFrame(Graphics::Surface *frame) {
 	GLenum dataType;
 	int bytesPerPixel = frame->format.bytesPerPixel;
 
-	// Aspyr Logo format
-	if (frame->format == Graphics::PixelFormat(4, 8, 8, 8, 0, 8, 16, 24, 0)) {
-#if !defined(__amigaos4__)
-		format = GL_BGRA;
-		dataType = GL_UNSIGNED_INT_8_8_8_8;
-#else
-		// MiniGL on AmigaOS4 doesn't understand GL_UNSIGNED_INT_8_8_8_8 yet.
-		format = GL_BGRA;
+	// Used by Bink, QuickTime, MPEG, Theora and paletted SMUSH
+	if (frame->format == getMovieFormat()) {
+		format = GL_RGBA;
 		dataType = GL_UNSIGNED_BYTE;
-#endif
-	// Used by Grim Fandango Remastered
-	} else if (frame->format == Graphics::PixelFormat(4, 8, 8, 8, 8, 8, 16, 24, 0)) {
-#if !defined(__amigaos4__)
-		format = GL_BGRA;
-		dataType = GL_UNSIGNED_INT_8_8_8_8;
-#else
-		// MiniGL on AmigaOS4 doesn't understand GL_UNSIGNED_INT_8_8_8_8 yet.
-		format = GL_BGRA;
-		dataType = GL_UNSIGNED_BYTE;
-#endif
-	} else if (frame->format == Graphics::PixelFormat(4, 8, 8, 8, 0, 16, 8, 0, 0)) {
-		format = GL_BGRA;
-		dataType = GL_UNSIGNED_INT_8_8_8_8_REV;
+	// Used by 16-bit SMUSH
 	} else if (frame->format == Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0)) {
 		format = GL_RGB;
 		dataType = GL_UNSIGNED_SHORT_5_6_5;
diff --git a/engines/grim/gfx_opengl.h b/engines/grim/gfx_opengl.h
index 5ec9d3e017a..fae50c8f9e7 100644
--- a/engines/grim/gfx_opengl.h
+++ b/engines/grim/gfx_opengl.h
@@ -119,6 +119,7 @@ public:
 	void drawPolygon(const PrimitiveObject *primitive) override;
 	void drawDimPlane() override;
 
+	const Graphics::PixelFormat getMovieFormat() const override;
 	void prepareMovieFrame(Graphics::Surface *frame) override;
 	void drawMovieFrame(int offsetX, int offsetY) override;
 	void releaseMovieFrame() override;
diff --git a/engines/grim/gfx_opengl_shaders.cpp b/engines/grim/gfx_opengl_shaders.cpp
index 27ef39c0131..02cb5a63369 100644
--- a/engines/grim/gfx_opengl_shaders.cpp
+++ b/engines/grim/gfx_opengl_shaders.cpp
@@ -1987,6 +1987,14 @@ void GfxOpenGLS::drawPolygon(const PrimitiveObject *primitive) {
 	drawGenericPrimitive(data, 8, primitive);
 }
 
+const Graphics::PixelFormat GfxOpenGLS::getMovieFormat() const {
+#ifdef SCUMM_BIG_ENDIAN
+	return Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
+#else
+	return Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24);
+#endif
+}
+
 void GfxOpenGLS::prepareMovieFrame(Graphics::Surface* frame) {
 	int width = frame->w;
 	int height = frame->h;
@@ -1994,40 +2002,14 @@ void GfxOpenGLS::prepareMovieFrame(Graphics::Surface* frame) {
 
 	GLenum frameType, frameFormat;
 
-	// GLES2 support is needed here, so:
-	// - frameFormat GL_BGRA is not supported, so use GL_RGBA
-	// - no format conversion, so same format is used for internal storage, so swizzle in shader
-	// - GL_UNSIGNED_INT_8_8_8_8[_REV] do not exist, so use _BYTE and fix
-	//   endianness in shader.
-	if (frame->format == Graphics::PixelFormat(4, 8, 8, 8, 0, 8, 16, 24, 0) || frame->format == Graphics::PixelFormat(4, 8, 8, 8, 8, 8, 16, 24, 0)) {
-		// frame->format: GBRA
-		// read in little endian: {A, R, G, B}, swap: {B, G, R, A}, swizzle: {R, G, B, A}
-		// read in big endian: {B, G, R, A}, swizzle: {R, G, B, A}
-		frameType = GL_UNSIGNED_BYTE;
-		frameFormat = GL_RGBA;
-		_smushSwizzle = true;
-#ifdef SCUMM_LITTLE_ENDIAN
-		_smushSwap = true;
-#else
-		_smushSwap = false;
-#endif
-	} else if (frame->format == Graphics::PixelFormat(4, 8, 8, 8, 0, 16, 8, 0, 0) || frame->format == Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24)) {
-		// frame->format: ARGB
-		// read in little endian: {B, G, R, A}, swizzle: {R, G, B, A}
-		// read in big endian: {A, R, G, B}, swap: {B, G, R, A}, swizzle: {R, G, B, A}
+	// Used by Bink, QuickTime, MPEG, Theora and paletted SMUSH
+	if (frame->format == getMovieFormat()) {
 		frameType = GL_UNSIGNED_BYTE;
 		frameFormat = GL_RGBA;
-		_smushSwizzle = true;
-#ifdef SCUMM_LITTLE_ENDIAN
-		_smushSwap = false;
-#else
-		_smushSwap = true;
-#endif
+	// Used by 16-bit SMUSH
 	} else if (frame->format == Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0)) {
 		frameType = GL_UNSIGNED_SHORT_5_6_5;
 		frameFormat = GL_RGB;
-		_smushSwizzle = false;
-		_smushSwap = false;
 	} else {
 		error("Unknown pixelformat: Bpp: %d RBits: %d GBits: %d BBits: %d ABits: %d RShift: %d GShift: %d BShift: %d AShift: %d",
 			frame->format.bytesPerPixel,
@@ -2068,8 +2050,6 @@ void GfxOpenGLS::drawMovieFrame(int offsetX, int offsetY) {
 	_smushProgram->setUniform("texcrop", Math::Vector2d(float(_smushWidth) / nextHigher2(_smushWidth), float(_smushHeight) / nextHigher2(_smushHeight)));
 	_smushProgram->setUniform("scale", Math::Vector2d(float(_smushWidth)/ float(_gameWidth), float(_smushHeight) / float(_gameHeight)));
 	_smushProgram->setUniform("offset", Math::Vector2d(float(offsetX) / float(_gameWidth), float(offsetY) / float(_gameHeight)));
-	_smushProgram->setUniform("swap", _smushSwap);
-	_smushProgram->setUniform("swizzle", _smushSwizzle);
 	glBindTexture(GL_TEXTURE_2D, _smushTexId);
 
 	glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);
diff --git a/engines/grim/gfx_opengl_shaders.h b/engines/grim/gfx_opengl_shaders.h
index 086235c4337..54df9adda3c 100644
--- a/engines/grim/gfx_opengl_shaders.h
+++ b/engines/grim/gfx_opengl_shaders.h
@@ -177,6 +177,8 @@ public:
 	void drawLine(const PrimitiveObject *primitive) override;
 	void drawPolygon(const PrimitiveObject *primitive) override;
 
+	const Graphics::PixelFormat getMovieFormat() const override;
+
 	/**
 	 * Prepare a movie-frame for drawing
 	 * performing any necessary conversion
@@ -241,8 +243,6 @@ private:
 	int _smushWidth;
 	int _smushHeight;
 	GLuint _smushTexId;
-	bool _smushSwizzle;
-	bool _smushSwap;
 	void setupTexturedQuad();
 	void setupQuadEBO();
 
diff --git a/engines/grim/gfx_tinygl.cpp b/engines/grim/gfx_tinygl.cpp
index 4c828f6e463..60a64fd91b5 100644
--- a/engines/grim/gfx_tinygl.cpp
+++ b/engines/grim/gfx_tinygl.cpp
@@ -1170,6 +1170,10 @@ void GfxTinyGL::destroyTexture(Texture *texture) {
 	}
 }
 
+const Graphics::PixelFormat GfxTinyGL::getMovieFormat() const {
+	return g_system->getScreenFormat();
+}
+
 void GfxTinyGL::prepareMovieFrame(Graphics::Surface *frame) {
 	if (_smushImage == nullptr)
 		_smushImage = tglGenBlitImage();
diff --git a/engines/grim/gfx_tinygl.h b/engines/grim/gfx_tinygl.h
index 65ce4d4a2ec..b4566bcd0b1 100644
--- a/engines/grim/gfx_tinygl.h
+++ b/engines/grim/gfx_tinygl.h
@@ -120,6 +120,7 @@ public:
 	void drawPolygon(const PrimitiveObject *primitive) override;
 	void drawDimPlane() override;
 
+	const Graphics::PixelFormat getMovieFormat() const override;
 	void prepareMovieFrame(Graphics::Surface *frame) override;
 	void drawMovieFrame(int offsetX, int offsetY) override;
 	void releaseMovieFrame() override;
diff --git a/engines/grim/grim.cpp b/engines/grim/grim.cpp
index 9525248f3b1..dcc096ad11b 100644
--- a/engines/grim/grim.cpp
+++ b/engines/grim/grim.cpp
@@ -845,7 +845,7 @@ void GrimEngine::updateDisplayScene() {
 		if (g_movie->isPlaying()) {
 			_movieTime = g_movie->getMovieTime();
 			if (g_movie->isUpdateNeeded()) {
-				g_driver->prepareMovieFrame(g_movie->getDstSurface());
+				g_driver->prepareMovieFrame(g_movie->getDstSurface(), g_movie->getDstPalette());
 				g_movie->clearUpdateNeeded();
 			}
 			int frame = g_movie->getFrame();
@@ -914,7 +914,7 @@ void GrimEngine::drawNormalMode() {
 	if (g_movie->isPlaying() && _movieSetup == _currSet->getCurrSetup()->_name) {
 		_movieTime = g_movie->getMovieTime();
 		if (g_movie->isUpdateNeeded()) {
-			g_driver->prepareMovieFrame(g_movie->getDstSurface());
+			g_driver->prepareMovieFrame(g_movie->getDstSurface(), g_movie->getDstPalette());
 			g_movie->clearUpdateNeeded();
 		}
 		if (g_movie->getFrame() >= 0)
diff --git a/engines/grim/movie/bink.cpp b/engines/grim/movie/bink.cpp
index 8baed9b3a6c..6f8cdee82d1 100644
--- a/engines/grim/movie/bink.cpp
+++ b/engines/grim/movie/bink.cpp
@@ -204,10 +204,7 @@ bool BinkPlayer::loadFile(const Common::String &filename) {
 
 	Common::SeekableReadStream *bink = nullptr;
 	bink = new Common::SeekableSubReadStream(stream, startBinkPos, stream->size(), DisposeAfterUse::YES);
-	if (!_videoDecoder->loadStream(bink))
-		return false;
-	_videoDecoder->setOutputPixelFormat(Graphics::PixelFormat(4, 8, 8, 8, 0, 8, 16, 24, 0));
-	return true;
+	return _videoDecoder->loadStream(bink);
 }
 
 } // end of namespace Grim
diff --git a/engines/grim/movie/codecs/smush_decoder.cpp b/engines/grim/movie/codecs/smush_decoder.cpp
index 933ba6d0df4..c7ed9ba8780 100644
--- a/engines/grim/movie/codecs/smush_decoder.cpp
+++ b/engines/grim/movie/codecs/smush_decoder.cpp
@@ -445,15 +445,13 @@ bool SmushDecoder::seekIntern(const Audio::Timestamp &time) {
 }
 
 SmushDecoder::SmushVideoTrack::SmushVideoTrack(int width, int height, int fps, int numFrames, bool is16Bit) {
-	// Set color-format statically here for SMUSH (5650), to allow for differing
-	// PixelFormat in engine and renderer (and conversion from Surface there)
-	// Which means 16 bpp, 565, shift of 11, 5, 0, 0 for RGBA
-	_format = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0);
 	if (!is16Bit) { // Demo
+		_format = Graphics::PixelFormat::createFormatCLUT8();
 		_codec48 = new Codec48Decoder();
 		_blocky8 = new Blocky8();
 		_blocky16 = nullptr;
 	} else {
+		_format = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0);
 		_codec48 = nullptr;
 		_blocky8 = nullptr;
 		_blocky16 = new Blocky16();
@@ -468,8 +466,9 @@ SmushDecoder::SmushVideoTrack::SmushVideoTrack(int width, int height, int fps, i
 	setMsPerFrame(fps);
 	_curFrame = 0;
 	for (int i = 0; i < 0x300; i++) {
-		_pal[i] = 0;
+		_palette[i] = 0;
 		_deltaPal[i] = 0;
+		_dirtyPalette = false;
 	}
 	_frameStart = 0;
 }
@@ -490,9 +489,6 @@ void SmushDecoder::SmushVideoTrack::init() {
 }
 
 void SmushDecoder::SmushVideoTrack::finishFrame() {
-	if (!_is16Bit) {
-		convertDemoFrame();
-	}
 	_curFrame++;
 }
 
@@ -500,19 +496,6 @@ void SmushDecoder::SmushVideoTrack::setFrameStart(int frame) {
 	_frameStart = frame - 1;
 }
 
-void SmushDecoder::SmushVideoTrack::convertDemoFrame() {
-	Graphics::Surface conversion;
-	conversion.create(0, 0, _format); // Avoid issues with copyFrom, by creating an empty surface.
-	conversion.copyFrom(_surface);
-
-	uint16 *d = (uint16 *)_surface.getPixels();
-	for (int l = 0; l < _width * _height; l++) {
-		int index = ((byte *)conversion.getPixels())[l];
-		d[l] = ((_pal[(index * 3) + 0] & 0xF8) << 8) | ((_pal[(index * 3) + 1] & 0xFC) << 3) | (_pal[(index * 3) + 2] >> 3);
-	}
-	conversion.free();
-}
-
 void SmushDecoder::SmushVideoTrack::handleBlocky16(Common::SeekableReadStream *stream, uint32 size) {
 	if (_curFrame < _frameStart) {
 		return;
@@ -573,11 +556,13 @@ void SmushDecoder::SmushVideoTrack::handleDeltaPalette(Common::SeekableReadStrea
 		for (int i = 0; i < 0x300; i++) {
 			_deltaPal[i] = stream->readUint16LE();
 		}
-		stream->read(_pal, 0x300);
+		stream->read(_palette, 0x300);
+		_dirtyPalette = true;
 	} else if (size == 6) {
 		for (int i = 0; i < 0x300; i++) {
-			_pal[i] = delta_color(_pal[i], _deltaPal[i]);
+			_palette[i] = delta_color(_palette[i], _deltaPal[i]);
 		}
+		_dirtyPalette = true;
 	} else {
 		error("SmushDecoder::handleDeltaPalette() Wrong size for DeltaPalette");
 	}
diff --git a/engines/grim/movie/codecs/smush_decoder.h b/engines/grim/movie/codecs/smush_decoder.h
index e53d92e70ae..74739d88ca8 100644
--- a/engines/grim/movie/codecs/smush_decoder.h
+++ b/engines/grim/movie/codecs/smush_decoder.h
@@ -85,15 +85,18 @@ protected:
 		void handleDeltaPalette(Common::SeekableReadStream *stream, int32 size);
 		void init();
 		Graphics::Surface *decodeNextFrame() override;
+		const byte *getPalette() const override { _dirtyPalette = false; return _palette; }
+		bool hasDirtyPalette() const override { return _dirtyPalette; }
 
-		byte *getPal() { return _pal; }
+		byte *getPal() { _dirtyPalette = true; return _palette; }
 		int _x, _y;
 	private:
 		void convertDemoFrame();
 		bool _is16Bit;
 		int32 _curFrame;
-		byte _pal[0x300];
+		byte _palette[0x300];
 		int16 _deltaPal[0x300];
+		mutable bool _dirtyPalette;
 		int _width, _height;
 		Graphics::Surface _surface;
 		Graphics::PixelFormat _format;
diff --git a/engines/grim/movie/movie.cpp b/engines/grim/movie/movie.cpp
index a9b911de933..cce21ff2bce 100644
--- a/engines/grim/movie/movie.cpp
+++ b/engines/grim/movie/movie.cpp
@@ -25,6 +25,7 @@
 #include "common/timer.h"
 
 #include "engines/grim/movie/movie.h"
+#include "engines/grim/gfx_base.h"
 #include "engines/grim/grim.h"
 #include "engines/grim/debug.h"
 #include "engines/grim/savegame.h"
@@ -47,7 +48,9 @@ MoviePlayer::MoviePlayer() {
 	_y = 0;
 	_videoDecoder = nullptr;
 	_internalSurface = nullptr;
+	_internalPalette = nullptr;
 	_externalSurface = new Graphics::Surface();
+	_externalPalette = nullptr;
 	_timerStarted = false;
 }
 
@@ -60,6 +63,7 @@ MoviePlayer::~MoviePlayer() {
 	deinit();
 	delete _videoDecoder;
 	delete _externalSurface;
+	delete[] _externalPalette;
 }
 
 void MoviePlayer::pause(bool p) {
@@ -103,6 +107,7 @@ bool MoviePlayer::prepareFrame() {
 
 	handleFrame();
 	_internalSurface = _videoDecoder->decodeNextFrame();
+	_internalPalette = _videoDecoder->getPalette();
 	if (_frame != _videoDecoder->getCurFrame()) {
 		_updateNeeded = true;
 	}
@@ -122,6 +127,17 @@ Graphics::Surface *MoviePlayer::getDstSurface() {
 	return _externalSurface;
 }
 
+const byte *MoviePlayer::getDstPalette() {
+	Common::StackLock lock(_frameMutex);
+	if (_updateNeeded && _internalPalette) {
+		if (!_externalPalette)
+			_externalPalette = new byte[0x300];
+		memcpy(_externalPalette, _internalPalette, 0x300);
+	}
+
+	return _externalPalette;
+}
+
 void MoviePlayer::drawMovieSubtitle() {
 	Common::StackLock lock(_frameMutex);
 	g_grim->drawMovieSubtitle();
@@ -146,9 +162,12 @@ void MoviePlayer::deinit() {
 		_videoDecoder->close();
 
 	_internalSurface = nullptr;
+	_internalPalette = nullptr;
 
 	if (_externalSurface)
 		_externalSurface->free();
+	delete[] _externalPalette;
+	_externalPalette = nullptr;
 
 	_videoPause = false;
 	_videoFinished = true;
@@ -166,10 +185,13 @@ bool MoviePlayer::play(const Common::String &filename, bool looping, int x, int
 	if (!loadFile(_fname))
 		return false;
 
+	_videoDecoder->setOutputPixelFormat(g_driver->getMovieFormat());
+
 	Debug::debug(Debug::Movie, "Playing video '%s'.\n", filename.c_str());
 
 	init();
 	_internalSurface = nullptr;
+	_internalPalette = nullptr;
 
 	if (start) {
 		_videoDecoder->start();
diff --git a/engines/grim/movie/movie.h b/engines/grim/movie/movie.h
index 058d47e3a1a..940a3fd9f27 100644
--- a/engines/grim/movie/movie.h
+++ b/engines/grim/movie/movie.h
@@ -38,6 +38,8 @@ protected:
 	Video::VideoDecoder *_videoDecoder;     //< Initialize this to your needed subclass of VideoDecoder in the constructor
 	const Graphics::Surface *_internalSurface;
 	Graphics::Surface *_externalSurface;
+	const byte *_internalPalette;
+	byte *_externalPalette;
 	int32 _frame;
 	bool _updateNeeded;
 	bool _showSubtitles;
@@ -72,6 +74,7 @@ public:
 	virtual bool isPlaying() { return !_videoFinished; }
 	virtual bool isUpdateNeeded() { return _updateNeeded; }
 	virtual Graphics::Surface *getDstSurface();
+	virtual const byte *getDstPalette();
 	virtual int getX() { return _x; }
 	virtual int getY() { return _y; }
 	virtual int getFrame() { return _frame; }
diff --git a/engines/grim/movie/mpeg.cpp b/engines/grim/movie/mpeg.cpp
index 8175b1a1f68..2951d923535 100644
--- a/engines/grim/movie/mpeg.cpp
+++ b/engines/grim/movie/mpeg.cpp
@@ -46,8 +46,6 @@ bool MpegPlayer::loadFile(const Common::String &filename) {
 		return false;
 
 	_videoDecoder->loadStream(stream);
-	_videoDecoder->setOutputPixelFormat(Graphics::PixelFormat(4, 8, 8, 8, 0, 8, 16, 24, 0));
-	_videoDecoder->start();
 
 	return true;
 }
diff --git a/engines/grim/movie/quicktime.cpp b/engines/grim/movie/quicktime.cpp
index 695e9e98fcc..a9f086a068d 100644
--- a/engines/grim/movie/quicktime.cpp
+++ b/engines/grim/movie/quicktime.cpp
@@ -44,7 +44,6 @@ bool QuickTimePlayer::loadFile(const Common::String &filename) {
 		return false;
 
 	_videoDecoder->loadStream(stream);
-	_videoDecoder->start();
 
 	return true;
 }
diff --git a/engines/grim/shaders/grim_smush.fragment b/engines/grim/shaders/grim_smush.fragment
index e08b02880c9..ee048a1e915 100644
--- a/engines/grim/shaders/grim_smush.fragment
+++ b/engines/grim/shaders/grim_smush.fragment
@@ -3,16 +3,8 @@ in vec2 Texcoord;
 OUTPUT
 
 uniform sampler2D tex;
-uniform UBOOL swap;
-uniform UBOOL swizzle;
 
 void main() {
 	vec4 color = texture(tex, Texcoord);
-	if (UBOOL_TEST(swap)) {
-		color.rgba = color.abgr;
-	}
-	if (UBOOL_TEST(swizzle)) {
-		color.rgba = color.bgra;
-	}
 	outColor = vec4(color.rgb, 1.0);
 }


Commit: 0825fab676d16a44515df6fb4e291d42862868e0
    https://github.com/scummvm/scummvm/commit/0825fab676d16a44515df6fb4e291d42862868e0
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2024-11-03T09:40:07+02:00

Commit Message:
GRIM: Reduce memory usage for 3bpp textures

Changed paths:
    engines/grim/gfx_base.cpp
    engines/grim/gfx_opengl.cpp
    engines/grim/gfx_opengl_shaders.cpp
    engines/grim/gfx_tinygl.cpp
    engines/grim/material.cpp
    engines/grim/material.h


diff --git a/engines/grim/gfx_base.cpp b/engines/grim/gfx_base.cpp
index 02c2dc486ef..3238e4157c7 100644
--- a/engines/grim/gfx_base.cpp
+++ b/engines/grim/gfx_base.cpp
@@ -164,7 +164,6 @@ void GfxBase::createSpecialtyTexture(uint id, const uint8 *data, int width, int
 	_specialtyTextures[id]._width = width;
 	_specialtyTextures[id]._height = height;
 	_specialtyTextures[id]._bpp = 4;
-	_specialtyTextures[id]._colorFormat = BM_RGBA;
 	createTexture(&_specialtyTextures[id], data, nullptr, true);
 }
 
diff --git a/engines/grim/gfx_opengl.cpp b/engines/grim/gfx_opengl.cpp
index d182f0f830f..8350c21e8a6 100644
--- a/engines/grim/gfx_opengl.cpp
+++ b/engines/grim/gfx_opengl.cpp
@@ -1574,11 +1574,28 @@ void GfxOpenGL::destroyTextObject(TextObject *text) {
 void GfxOpenGL::createTexture(Texture *texture, const uint8 *data, const CMap *cmap, bool clamp) {
 	texture->_texture = new GLuint[1];
 	glGenTextures(1, (GLuint *)texture->_texture);
-	uint8 *texdata = new uint8[texture->_width * texture->_height * 4];
-	uint8 *texdatapos = texdata;
+
+	GLuint *textures = (GLuint *)texture->_texture;
+	glBindTexture(GL_TEXTURE_2D, textures[0]);
+
+	// Remove darkened lines in EMI intro
+	if (g_grim->getGameType() == GType_MONKEY4 && clamp) {
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+	} else {
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+	}
+
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 
 	if (cmap != nullptr) { // EMI doesn't have colour-maps
 		int bytes = 4;
+
+		uint8 *texdata = new uint8[texture->_width * texture->_height * bytes];
+		uint8 *texdatapos = texdata;
+
 		for (int y = 0; y < texture->_height; y++) {
 			for (int x = 0; x < texture->_width; x++) {
 				uint8 col = *data;
@@ -1595,26 +1612,13 @@ void GfxOpenGL::createTexture(Texture *texture, const uint8 *data, const CMap *c
 				data++;
 			}
 		}
-	} else {
-		memcpy(texdata, data, texture->_width * texture->_height * texture->_bpp);
-	}
-
-	GLuint *textures = (GLuint *)texture->_texture;
-	glBindTexture(GL_TEXTURE_2D, textures[0]);
 
-	// Remove darkened lines in EMI intro
-	if (g_grim->getGameType() == GType_MONKEY4 && clamp) {
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->_width, texture->_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texdata);
+		delete[] texdata;
 	} else {
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+		GLint format = (texture->_bpp == 4) ? GL_RGBA : GL_RGB;
+		glTexImage2D(GL_TEXTURE_2D, 0, format, texture->_width, texture->_height, 0, format, GL_UNSIGNED_BYTE, data);
 	}
-
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->_width, texture->_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texdata);
-	delete[] texdata;
 }
 
 void GfxOpenGL::selectTexture(const Texture *texture) {
diff --git a/engines/grim/gfx_opengl_shaders.cpp b/engines/grim/gfx_opengl_shaders.cpp
index 02cb5a63369..d97feb6a5f8 100644
--- a/engines/grim/gfx_opengl_shaders.cpp
+++ b/engines/grim/gfx_opengl_shaders.cpp
@@ -1260,11 +1260,28 @@ void GfxOpenGLS::turnOffLight(int lightId) {
 void GfxOpenGLS::createTexture(Texture *texture, const uint8 *data, const CMap *cmap, bool clamp) {
 	texture->_texture = new GLuint[1];
 	glGenTextures(1, (GLuint *)texture->_texture);
-	char *texdata = new char[texture->_width * texture->_height * 4];
-	char *texdatapos = texdata;
+
+	GLuint *textures = (GLuint *)texture->_texture;
+	glBindTexture(GL_TEXTURE_2D, textures[0]);
+
+	// Remove darkened lines in EMI intro
+	if (g_grim->getGameType() == GType_MONKEY4 && clamp) {
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+	} else {
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+	}
+
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 
 	if (cmap != nullptr) { // EMI doesn't have colour-maps
 		int bytes = 4;
+
+		char *texdata = new char[texture->_width * texture->_height * bytes];
+		char *texdatapos = texdata;
+
 		for (int y = 0; y < texture->_height; y++) {
 			for (int x = 0; x < texture->_width; x++) {
 				uint8 col = *(const uint8 *)(data);
@@ -1281,26 +1298,13 @@ void GfxOpenGLS::createTexture(Texture *texture, const uint8 *data, const CMap *
 				data++;
 			}
 		}
-	} else {
-		memcpy(texdata, data, texture->_width * texture->_height * texture->_bpp);
-	}
-
-	GLuint *textures = (GLuint *)texture->_texture;
-	glBindTexture(GL_TEXTURE_2D, textures[0]);
 
-	// Remove darkened lines in EMI intro
-	if (g_grim->getGameType() == GType_MONKEY4 && clamp) {
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->_width, texture->_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texdata);
+		delete[] texdata;
 	} else {
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+		GLint format = (texture->_bpp == 4) ? GL_RGBA : GL_RGB;
+		glTexImage2D(GL_TEXTURE_2D, 0, format, texture->_width, texture->_height, 0, format, GL_UNSIGNED_BYTE, data);
 	}
-
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->_width, texture->_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texdata);
-	delete[] texdata;
 }
 
 void GfxOpenGLS::selectTexture(const Texture *texture) {
diff --git a/engines/grim/gfx_tinygl.cpp b/engines/grim/gfx_tinygl.cpp
index 60a64fd91b5..f038c383674 100644
--- a/engines/grim/gfx_tinygl.cpp
+++ b/engines/grim/gfx_tinygl.cpp
@@ -1109,10 +1109,21 @@ void GfxTinyGL::destroyTextObject(TextObject *text) {
 void GfxTinyGL::createTexture(Texture *texture, const uint8 *data, const CMap *cmap, bool clamp) {
 	texture->_texture = new TGLuint[1];
 	tglGenTextures(1, (TGLuint *)texture->_texture);
-	uint8 *texdata = new uint8[texture->_width * texture->_height * 4];
-	uint8 *texdatapos = texdata;
+
+	TGLuint *textures = (TGLuint *)texture->_texture;
+	tglBindTexture(TGL_TEXTURE_2D, textures[0]);
+
+	// TinyGL doesn't have issues with dark lines in EMI intro so doesn't need TGL_CLAMP_TO_EDGE
+	tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_WRAP_S, TGL_REPEAT);
+	tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_WRAP_T, TGL_REPEAT);
+
+	tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_MAG_FILTER, TGL_LINEAR);
+	tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_MIN_FILTER, TGL_LINEAR);
 
 	if (cmap != nullptr) { // EMI doesn't have colour-maps
+		uint8 *texdata = new uint8[texture->_width * texture->_height * 4];
+		uint8 *texdatapos = texdata;
+
 		for (int y = 0; y < texture->_height; y++) {
 			for (int x = 0; x < texture->_width; x++) {
 				uint8 col = *data;
@@ -1129,21 +1140,14 @@ void GfxTinyGL::createTexture(Texture *texture, const uint8 *data, const CMap *c
 				data++;
 			}
 		}
-	} else {
-		memcpy(texdata, data, texture->_width * texture->_height * texture->_bpp);
-	}
-
-	TGLuint *textures = (TGLuint *)texture->_texture;
-	tglBindTexture(TGL_TEXTURE_2D, textures[0]);
 
-	// TinyGL doesn't have issues with dark lines in EMI intro so doesn't need TGL_CLAMP_TO_EDGE
-	tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_WRAP_S, TGL_REPEAT);
-	tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_WRAP_T, TGL_REPEAT);
+		tglTexImage2D(TGL_TEXTURE_2D, 0, TGL_RGBA, texture->_width, texture->_height, 0, TGL_RGBA, TGL_UNSIGNED_BYTE, texdata);
+		delete[] texdata;
+	} else {
+		TGLint format = (texture->_bpp == 4) ? TGL_RGBA : TGL_RGB;
 
-	tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_MAG_FILTER, TGL_LINEAR);
-	tglTexParameteri(TGL_TEXTURE_2D, TGL_TEXTURE_MIN_FILTER, TGL_LINEAR);
-	tglTexImage2D(TGL_TEXTURE_2D, 0, TGL_RGBA, texture->_width, texture->_height, 0, TGL_RGBA, TGL_UNSIGNED_BYTE, texdata);
-	delete[] texdata;
+		tglTexImage2D(TGL_TEXTURE_2D, 0, format, texture->_width, texture->_height, 0, format, TGL_UNSIGNED_BYTE, data);
+	}
 }
 
 void GfxTinyGL::selectTexture(const Texture *texture) {
diff --git a/engines/grim/material.cpp b/engines/grim/material.cpp
index ee4d039170d..e48928b5a27 100644
--- a/engines/grim/material.cpp
+++ b/engines/grim/material.cpp
@@ -24,6 +24,7 @@
 #include "image/tga.h"
 #include "image/png.h"
 
+#include "graphics/blit.h"
 #include "graphics/surface.h"
 
 #include "engines/grim/grim.h"
@@ -48,35 +49,66 @@ MaterialData::MaterialData(const Common::String &filename, Common::SeekableReadS
 	}
 }
 
-void loadPNG(Common::SeekableReadStream *data, Texture *t) {
-	Image::PNGDecoder *pngDecoder = new Image::PNGDecoder();
-	pngDecoder->loadStream(*data);
+static void loadImage(Image::ImageDecoder *decoder, Texture *t) {
+#ifdef SCUMM_BIG_ENDIAN
+	const Graphics::PixelFormat format_3bpp(3, 8, 8, 8, 0, 16, 8,  0, 0);
+	const Graphics::PixelFormat format_4bpp(4, 8, 8, 8, 8, 24, 16, 8, 0);
+#else
+	const Graphics::PixelFormat format_3bpp(3, 8, 8, 8, 0, 0, 8, 16, 0);
+	const Graphics::PixelFormat format_4bpp(4, 8, 8, 8, 8, 0, 8, 16, 24);
+#endif
 
-	Graphics::Surface *pngSurface =pngDecoder->getSurface()->convertTo(Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24), pngDecoder->getPalette());
+	const Graphics::Surface *surface = decoder->getSurface();
 
-	t->_width = pngSurface->w;
-	t->_height = pngSurface->h;
+	t->_width = surface->w;
+	t->_height = surface->h;
 	t->_texture = nullptr;
 
-	int bpp = pngSurface->format.bytesPerPixel;
-	assert(bpp == 4); // Assure we have 32 bpp
-
-	t->_colorFormat = BM_RGBA;
-	t->_bpp = 4;
-	t->_hasAlpha = true;
-
+	int bpp = surface->format.bytesPerPixel;
+	assert(decoder->hasPalette() || bpp == 3 || bpp == 4); // Assure we have 8/24/32 bpp
 
 	// Allocate room for the texture.
-	t->_data = new uint8[t->_width * t->_height * (bpp)];
+	if (bpp == 4) {
+		t->_bpp = bpp;
+		t->_hasAlpha = true;
+	} else {
+		t->_bpp = 3;
+		t->_hasAlpha = false;
+	}
+	t->_data = new uint8[t->_width * t->_height * t->_bpp];
 
 	// Copy the texture data, as the decoder owns the current copy.
-	memcpy(t->_data, pngSurface->getPixels(), t->_width * t->_height * (bpp));
+	if (decoder->hasPalette()) {
+		uint32 map[256];
+		Graphics::convertPaletteToMap(map,
+		                              decoder->getPalette(),
+		                              decoder->getPaletteColorCount(),
+		                              format_3bpp);
+		Graphics::crossBlitMap(t->_data, (const byte *)surface->getPixels(),
+		                       t->_width * t->_bpp, surface->pitch,
+		                       t->_width, t->_height, t->_bpp, map);
+	} else {
+		Graphics::crossBlit(t->_data, (const byte *)surface->getPixels(),
+		                    t->_width * t->_bpp, surface->pitch,
+		                    t->_width, t->_height,
+		                   (t->_bpp == 4) ? format_4bpp : format_3bpp, surface->format);
+	}
+}
 
-	pngSurface->free();
-	delete pngSurface;
+static void loadPNG(Common::SeekableReadStream *data, Texture *t) {
+	Image::PNGDecoder *pngDecoder = new Image::PNGDecoder();
+	pngDecoder->loadStream(*data);
+	loadImage(pngDecoder, t);
 	delete pngDecoder;
 }
 
+static void loadTGA(Common::SeekableReadStream *data, Texture *t) {
+	Image::TGADecoder *tgaDecoder = new Image::TGADecoder();
+	tgaDecoder->loadStream(*data);
+	loadImage(tgaDecoder, t);
+	delete tgaDecoder;
+}
+
 void MaterialData::initGrim(Common::SeekableReadStream *data) {
 	 if (_fname.hasSuffix(".png")) {
 		_numImages = 1;
@@ -111,51 +143,19 @@ void MaterialData::initGrim(Common::SeekableReadStream *data) {
 		t->_height = data->readUint32LE();
 		t->_hasAlpha = data->readUint32LE();
 		t->_texture = nullptr;
-		t->_colorFormat = BM_RGBA;
 		t->_data = nullptr;
 		if (t->_width == 0 || t->_height == 0) {
 			Debug::warning(Debug::Materials, "skip load texture: bad texture size (%dx%d) for texture %d of material %s",
 						   t->_width, t->_height, i, _fname.c_str());
 			break;
 		}
+		t->_bpp = 1;
 		t->_data = new uint8[t->_width * t->_height];
 		data->seek(12, SEEK_CUR);
 		data->read(t->_data, t->_width * t->_height);
 	}
 }
 
-static void loadTGA(Common::SeekableReadStream *data, Texture *t) {
-	Image::TGADecoder *tgaDecoder = new Image::TGADecoder();
-	tgaDecoder->loadStream(*data);
-	const Graphics::Surface *tgaSurface = tgaDecoder->getSurface();
-
-	t->_width = tgaSurface->w;
-	t->_height = tgaSurface->h;
-	t->_texture = nullptr;
-
-	int bpp = tgaSurface->format.bytesPerPixel;
-	assert(bpp == 3 || bpp == 4); // Assure we have 24/32 bpp
-
-	// Allocate room for the texture.
-	t->_data = new uint8[t->_width * t->_height * 4];
-	t->_colorFormat = BM_RGBA;
-	t->_bpp = 4;
-	if (bpp == 4) {
-		t->_hasAlpha = true;
-	} else {
-		t->_hasAlpha = false;
-	}
-#ifdef SCUMM_BIG_ENDIAN
-	auto newSurface = tgaSurface->convertTo(Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0));
-#else
-	auto newSurface = tgaSurface->convertTo(Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
-#endif
-	memcpy(t->_data, newSurface->getPixels(), t->_width * t->_height * (t->_bpp));
-	newSurface->free();
-	delete newSurface;
-	delete tgaDecoder;
-}
-
 void MaterialData::initEMI(Common::SeekableReadStream *data) {
 	if (_fname.hasSuffix(".sur")) {  // This expects that we want all the materials in the sur-file
 		Common::Array<Common::String> texFileNames;
diff --git a/engines/grim/material.h b/engines/grim/material.h
index 84d9b7a555c..348429f35c5 100644
--- a/engines/grim/material.h
+++ b/engines/grim/material.h
@@ -31,10 +31,9 @@ class CMap;
 class Texture {
 public:
 	Texture() :
-		_width(0), _height(0), _colorFormat(0), _bpp(0), _hasAlpha(false), _texture(nullptr), _data(nullptr), _isShared(false) {};
+		_width(0), _height(0), _bpp(0), _hasAlpha(false), _texture(nullptr), _data(nullptr), _isShared(false) {};
 	int _width;
 	int _height;
-	int _colorFormat;
 	int _bpp;
 	bool _hasAlpha;
 	void *_texture;


Commit: 88e2764d1335a5679166b2d5d84c1b00d79d3c56
    https://github.com/scummvm/scummvm/commit/88e2764d1335a5679166b2d5d84c1b00d79d3c56
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2024-11-03T09:40:07+02:00

Commit Message:
GRIM: Reduce the amount of format conversion for bitmaps

Changed paths:
    engines/grim/bitmap.cpp
    engines/grim/bitmap.h
    engines/grim/emi/lua_v2.cpp
    engines/grim/gfx_base.h
    engines/grim/gfx_opengl.cpp
    engines/grim/gfx_opengl_shaders.cpp
    engines/grim/gfx_tinygl.cpp
    engines/grim/grim.cpp


diff --git a/engines/grim/bitmap.cpp b/engines/grim/bitmap.cpp
index cf7784def3d..25b47bdde6b 100644
--- a/engines/grim/bitmap.cpp
+++ b/engines/grim/bitmap.cpp
@@ -67,7 +67,6 @@ BitmapData::BitmapData(const Common::String &fname) {
 	_format = 0;
 	_numTex = 0;
 	_bpp = 0;
-	_colorFormat = 0;
 	_texIds = nullptr;
 	_hasTransparency = 0;
 
@@ -134,7 +133,6 @@ bool BitmapData::loadGrimBm(Common::SeekableReadStream *data) {
 	data->seek(128, SEEK_SET);
 	_width = data->readUint32LE();
 	_height = data->readUint32LE();
-	_colorFormat = BM_RGB565;
 	_hasTransparency = false;
 
 	_data = new Graphics::Surface[_numImages];
@@ -157,11 +155,9 @@ bool BitmapData::loadGrimBm(Common::SeekableReadStream *data) {
 			Debug::error(Debug::Bitmaps, "Unknown image codec in BitmapData ctor!");
 
 #ifdef SCUMM_BIG_ENDIAN
-		if (_format == 1) {
-			uint16 *d = (uint16 *)_data[i].getPixels();
-			for (int j = 0; j < _width * _height; ++j) {
-				d[j] = SWAP_BYTES_16(d[j]);
-			}
+		uint16 *d = (uint16 *)_data[i].getPixels();
+		for (int j = 0; j < _width * _height; ++j) {
+			d[j] = SWAP_BYTES_16(d[j]);
 		}
 #endif
 	}
@@ -188,7 +184,6 @@ BitmapData::BitmapData(const Graphics::Surface &buf, int w, int h, const char *f
 	_texIds = nullptr;
 	_bpp = buf.format.bytesPerPixel * 8;
 	_hasTransparency = false;
-	_colorFormat = BM_RGB565;
 	_data = new Graphics::Surface[_numImages];
 	_data[0].copyFrom(buf);
 	_loaded = true;
@@ -204,7 +199,7 @@ BitmapData::BitmapData(const Graphics::Surface &buf, int w, int h, const char *f
 
 BitmapData::BitmapData() :
 		_numImages(0), _width(0), _height(0), _x(0), _y(0), _format(0), _numTex(0),
-		_bpp(0), _colorFormat(0), _texIds(nullptr), _hasTransparency(false), _data(nullptr),
+		_bpp(0), _texIds(nullptr), _hasTransparency(false), _data(nullptr),
 		_refCount(1), _loaded(false), _keepData(false), _texc(nullptr), _verts(nullptr),
 		_layers(nullptr), _numCoords(0), _numVerts(0), _numLayers(0), _userData(nullptr) {
 }
@@ -246,24 +241,20 @@ bool BitmapData::loadTGA(Common::SeekableReadStream *data) {
 	if (!success)
 		return false;
 
-	const Graphics::Surface *origSurf = dec.getSurface();
-	Graphics::PixelFormat pixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24);
-	Graphics::Surface *surf = origSurf->convertTo(pixelFormat);
+	const Graphics::Surface *surf = dec.getSurface();
 
 	_width = surf->w;
 	_height = surf->h;
 	_format = 1;
 	_x = _y = 0;
-	_bpp = 4;
-	_colorFormat = BM_RGBA;
+	_bpp = surf->format.bytesPerPixel * 8;
 	_numImages = 1;
 	_data = new Graphics::Surface[1];
-	_data[0].init(surf->w, surf->h, surf->pitch, surf->getPixels(), surf->format);
+	_data[0].copyFrom(*surf);
 
 	g_driver->createBitmap(this);
 
 	freeData();
-	delete surf;
 
 	return true;
 }
@@ -316,36 +307,41 @@ bool BitmapData::loadTile(Common::SeekableReadStream *o) {
 	o->seek(-8, SEEK_CUR);
 
 	_data = new Graphics::Surface[_numImages];
-	Graphics::PixelFormat pixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24);
+
+	Graphics::PixelFormat format_16bpp = Graphics::PixelFormat(2, 5, 5, 5, 1, 0, 5, 10, 15);
+#ifdef SCUMM_BIG_ENDIAN
+	Graphics::PixelFormat format_32bpp = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
+#else
+	Graphics::PixelFormat format_32bpp = Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24);
+#endif
+
 	int width = 256;
 	int height = 256;
 
 	for (int i = 0; i < _numImages; ++i) {
-		_data[i].create(width, height, pixelFormat);
+		_data[i].create(width, height, (_bpp == 16) ? format_16bpp : format_32bpp);
+		uint8 *d = (uint8 *)_data[i].getPixels();
 		o->seek(8, SEEK_CUR);
-		if (_bpp == 16) {
-			uint32 *d = (uint32 *)_data[i].getPixels();
-			for (int j = 0; j < _width * _height; ++j) {
-				uint16 p = o->readUint16LE();
-				// These values are shifted left by 3 so that they saturate the color channel
-				uint8 b = (p & 0x7C00) >> 7;
-				uint8 g = (p & 0x03E0) >> 2;
-				uint8 r = (p & 0x001F) << 3;
-				uint8 a = (p & 0x8000) ? 0xFF : 0x00;
-				// Recombine the color components into a 32 bit RGB value
-				uint32 tmp = (r << 24) | (g << 16) | (b << 8) | a;
-				WRITE_BE_UINT32(&d[j], tmp);
+		switch (_bpp) {
+		case 16:
+#ifndef SCUMM_LITTLE_ENDIAN
+			for (int y = 0; y < _height; ++y) {
+				uint16 *d16 = (uint16 *)d;
+				for (int x = 0; x < _width; ++x) {
+					d16[x] = o->readUint16LE();
+				d += _data[i].pitch;
 			}
-		} else if (_bpp == 32) {
-			uint32 *d = (uint32 *)_data[i].getPixels();
-			for (int j = 0; j < _width * _height; ++j) {
-				o->read(&(d[j]), 4);
+			break;
+#endif
+		case 32:
+			for (int y = 0; y < _height; ++y) {
+				o->read(d, _width * (_bpp / 8));
+				d += _data[i].pitch;
 			}
+			break;
 		}
 	}
 
-	_bpp = 32;
-	_colorFormat = BM_RGBA;
 	_width = width;
 	_height = height;
 
diff --git a/engines/grim/bitmap.h b/engines/grim/bitmap.h
index f58440289b6..2e8d07f637e 100644
--- a/engines/grim/bitmap.h
+++ b/engines/grim/bitmap.h
@@ -93,7 +93,6 @@ public:
 	int _format;
 	int _numTex;
 	int _bpp;
-	int _colorFormat;
 	void *_texIds;
 	bool _hasTransparency;
 	bool _loaded;
diff --git a/engines/grim/emi/lua_v2.cpp b/engines/grim/emi/lua_v2.cpp
index 51b245e04f2..302566f6ef6 100644
--- a/engines/grim/emi/lua_v2.cpp
+++ b/engines/grim/emi/lua_v2.cpp
@@ -503,7 +503,11 @@ void Lua_V2::ThumbnailFromFile() {
 		return;
 	}
 
+#ifdef SCUMM_BIG_ENDIAN
+	screenshot->_data->convertToColorFormat(Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0));
+#else
 	screenshot->_data->convertToColorFormat(Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
+#endif
 	g_driver->createSpecialtyTexture(index, (const uint8 *)screenshot->getData(0).getPixels(), width, height);
 	delete screenshot;
 	delete[] data;
diff --git a/engines/grim/gfx_base.h b/engines/grim/gfx_base.h
index 77de7cf4e60..d7589ebd006 100644
--- a/engines/grim/gfx_base.h
+++ b/engines/grim/gfx_base.h
@@ -59,16 +59,6 @@ class Sprite;
 class Texture;
 class Overlay;
 
-/**
- * The Color-formats used for bitmaps in Grim Fandango/Escape From Monkey Island
- */
-enum colorFormat {
-	BM_RGB565 = 1,    // Grim Fandango
-	BM_RGB1555 = 2,   // EMI-PS2
-	BM_RGBA = 3,      // EMI-PC (Also internal Material-format for Grim)
-	BM_BGR888 = 4,    // EMI-TGA-materials (888)
-	BM_BGRA = 5       // EMI-TGA-materials with alpha
-};
 class GfxBase {
 public:
 	GfxBase();
diff --git a/engines/grim/gfx_opengl.cpp b/engines/grim/gfx_opengl.cpp
index 8350c21e8a6..c7396f9e668 100644
--- a/engines/grim/gfx_opengl.cpp
+++ b/engines/grim/gfx_opengl.cpp
@@ -1042,7 +1042,7 @@ void GfxOpenGL::createBitmap(BitmapData *bitmap) {
 		for (int pic = 0; pic < bitmap->_numImages; pic++) {
 			uint16 *zbufPtr = reinterpret_cast<uint16 *>(const_cast<void  *>(bitmap->getImageData(pic).getPixels()));
 			for (int i = 0; i < (bitmap->_width * bitmap->_height); i++) {
-				uint16 val = READ_LE_UINT16(zbufPtr + i);
+				uint16 val = zbufPtr[i];
 				// fix the value if it is incorrectly set to the bitmap transparency color
 				if (val == 0xf81f) {
 					val = 0;
@@ -1087,13 +1087,21 @@ void GfxOpenGL::createBitmap(BitmapData *bitmap) {
 		glPixelStorei(GL_UNPACK_ALIGNMENT, bytes);
 		glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap->_width);
 
+		const Graphics::PixelFormat format_16bpp(2, 5, 6, 5, 0, 11, 5, 0, 0);
+#ifdef SCUMM_BIG_ENDIAN
+		const Graphics::PixelFormat format_32bpp(4, 8, 8, 8, 8, 24, 16, 8, 0);
+#else
+		const Graphics::PixelFormat format_32bpp(4, 8, 8, 8, 8, 0, 8, 16, 24);
+#endif
+
 		for (int pic = 0; pic < bitmap->_numImages; pic++) {
-			if (bitmap->_format == 1 && bitmap->_bpp == 16 && bitmap->_colorFormat != BM_RGB1555) {
+			const Graphics::Surface &imageData = bitmap->getImageData(pic);
+			if (bitmap->_format == 1 && imageData.format == format_16bpp) {
 				if (texData == nullptr)
 					texData = new byte[bytes * bitmap->_width * bitmap->_height];
 				// Convert data to 32-bit RGBA format
 				byte *texDataPtr = texData;
-				uint16 *bitmapData = (uint16 *)const_cast<void *>(bitmap->getImageData(pic).getPixels());
+				uint16 *bitmapData = (uint16 *)const_cast<void *>(imageData.getPixels());
 				for (int i = 0; i < bitmap->_width * bitmap->_height; i++, texDataPtr += bytes, bitmapData++) {
 					uint16 pixel = *bitmapData;
 					int r = pixel >> 11;
@@ -1110,11 +1118,11 @@ void GfxOpenGL::createBitmap(BitmapData *bitmap) {
 					}
 				}
 				texOut = texData;
-			} else if (bitmap->_format == 1 && bitmap->_colorFormat == BM_RGB1555) {
-				bitmap->convertToColorFormat(pic, Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
-				texOut = (byte *)const_cast<void *>(bitmap->getImageData(pic).getPixels());
+			} else if (bitmap->_format == 1 && imageData.format != format_32bpp) {
+				bitmap->convertToColorFormat(pic, format_32bpp);
+				texOut = (byte *)const_cast<void *>(imageData.getPixels());
 			} else {
-				texOut = (byte *)const_cast<void *>(bitmap->getImageData(pic).getPixels());
+				texOut = (byte *)const_cast<void *>(imageData.getPixels());
 			}
 
 			for (int i = 0; i < bitmap->_numTex; i++) {
@@ -1863,7 +1871,11 @@ void GfxOpenGL::drawEmergString(int x, int y, const char *text, const Color &fgC
 
 Bitmap *GfxOpenGL::getScreenshot(int w, int h, bool useStored) {
 	Graphics::Surface src;
+#ifdef SCUMM_BIG_ENDIAN
+	src.create(_screenWidth, _screenHeight, Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0));
+#else
 	src.create(_screenWidth, _screenHeight, Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
+#endif
 	if (useStored) {
 		memcpy(src.getPixels(), _storedDisplay, _screenWidth * _screenHeight * 4);
 	} else {
diff --git a/engines/grim/gfx_opengl_shaders.cpp b/engines/grim/gfx_opengl_shaders.cpp
index d97feb6a5f8..87fb5c1b8e0 100644
--- a/engines/grim/gfx_opengl_shaders.cpp
+++ b/engines/grim/gfx_opengl_shaders.cpp
@@ -1331,7 +1331,7 @@ void GfxOpenGLS::createBitmap(BitmapData *bitmap) {
 		for (int pic = 0; pic < bitmap->_numImages; pic++) {
 			uint16 *zbufPtr = reinterpret_cast<uint16 *>(const_cast<void *>(bitmap->getImageData(pic).getPixels()));
 			for (int i = 0; i < (bitmap->_width * bitmap->_height); i++) {
-				uint16 val = READ_LE_UINT16(zbufPtr + i);
+				uint16 val = zbufPtr[i];
 				// fix the value if it is incorrectly set to the bitmap transparency color
 				if (val == 0xf81f) {
 					val = 0;
@@ -1359,13 +1359,21 @@ void GfxOpenGLS::createBitmap(BitmapData *bitmap) {
 
 		glPixelStorei(GL_UNPACK_ALIGNMENT, bytes);
 
+		const Graphics::PixelFormat format_16bpp(2, 5, 6, 5, 0, 11, 5, 0, 0);
+#ifdef SCUMM_BIG_ENDIAN
+		const Graphics::PixelFormat format_32bpp(4, 8, 8, 8, 8, 24, 16, 8, 0);
+#else
+		const Graphics::PixelFormat format_32bpp(4, 8, 8, 8, 8, 0, 8, 16, 24);
+#endif
+
 		for (int pic = 0; pic < bitmap->_numImages; pic++) {
-			if (bitmap->_format == 1 && bitmap->_bpp == 16 && bitmap->_colorFormat != BM_RGB1555) {
+			const Graphics::Surface &imageData = bitmap->getImageData(pic);
+			if (bitmap->_format == 1 && imageData.format == format_16bpp) {
 				if (texData == nullptr)
 					texData = new byte[bytes * bitmap->_width * bitmap->_height];
 				// Convert data to 32-bit RGBA format
 				byte *texDataPtr = texData;
-				const uint16 *bitmapData = reinterpret_cast<const uint16 *>(bitmap->getImageData(pic).getPixels());
+				const uint16 *bitmapData = reinterpret_cast<const uint16 *>(imageData.getPixels());
 				for (int i = 0; i < bitmap->_width * bitmap->_height; i++, texDataPtr += bytes, bitmapData++) {
 					uint16 pixel = *bitmapData;
 					int r = pixel >> 11;
@@ -1382,11 +1390,11 @@ void GfxOpenGLS::createBitmap(BitmapData *bitmap) {
 					}
 				}
 				texOut = texData;
-			} else if (bitmap->_format == 1 && bitmap->_colorFormat == BM_RGB1555) {
-				bitmap->convertToColorFormat(pic, Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
-				texOut = (const byte *)bitmap->getImageData(pic).getPixels();
+			} else if (bitmap->_format == 1 && imageData.format != format_32bpp) {
+				bitmap->convertToColorFormat(pic, format_32bpp);
+				texOut = (const byte *)imageData.getPixels();
 			} else {
-				texOut = (const byte *)bitmap->getImageData(pic).getPixels();
+				texOut = (const byte *)imageData.getPixels();
 			}
 
 			int actualWidth = nextHigher2(bitmap->_width);
@@ -2215,7 +2223,11 @@ static void readPixels(int x, int y, int width, int height, byte *buffer) {
 
 Bitmap *GfxOpenGLS::getScreenshot(int w, int h, bool useStored) {
 	Graphics::Surface src;
+#ifdef SCUMM_BIG_ENDIAN
+	src.create(_screenWidth, _screenHeight, Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0));
+#else
 	src.create(_screenWidth, _screenHeight, Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
+#endif
 	Bitmap *bmp;
 
 	if (useStored) {
diff --git a/engines/grim/gfx_tinygl.cpp b/engines/grim/gfx_tinygl.cpp
index f038c383674..23ad4e0fb21 100644
--- a/engines/grim/gfx_tinygl.cpp
+++ b/engines/grim/gfx_tinygl.cpp
@@ -912,7 +912,7 @@ void GfxTinyGL::createBitmap(BitmapData *bitmap) {
 			uint32 *buf = (uint32 *)buffer.getPixels();
 			const uint16 *bufPtr = (const uint16 *)(bitmap->getImageData(pic).getPixels());
 			for (int i = 0; i < (bitmap->_width * bitmap->_height); i++) {
-				uint16 val = READ_LE_UINT16(bufPtr + i);
+				uint16 val = bufPtr[i];
 				// fix the value if it is incorrectly set to the bitmap transparency color
 				if (val == 0xf81f) {
 					val = 0;
@@ -928,34 +928,7 @@ void GfxTinyGL::createBitmap(BitmapData *bitmap) {
 		for (int i = 0; i < bitmap->_numImages; ++i) {
 			imgs[i] = tglGenBlitImage();
 			const Graphics::Surface &imageBuffer = bitmap->getImageData(i);
-#ifdef SCUMM_BIG_ENDIAN
-			if (g_grim->getGameType() == GType_MONKEY4 && imageBuffer.format.bytesPerPixel == 2) {
-				Graphics::Surface buffer;
-				buffer.create(bitmap->_width, bitmap->_height, imageBuffer.format);
-				uint16 *bufSrc = (uint16 *)const_cast<void *>(imageBuffer.getPixels());
-				uint16 *bufDst = (uint16 *)(buffer.getPixels());
-				for (int f = 0; f < (bitmap->_width * bitmap->_height); f++) {
-					uint16 val = SWAP_BYTES_16(bufSrc[f]);
-					bufDst[f] = val;
-				}
-				tglUploadBlitImage(imgs[i], buffer, buffer.format.ARGBToColor(0, 255, 0, 255), true);
-				buffer.free();
-			} else if (g_grim->getGameType() == GType_MONKEY4 && imageBuffer.format.bytesPerPixel == 4) {
-				Graphics::Surface buffer;
-				buffer.create(bitmap->_width, bitmap->_height, imageBuffer.format);
-				uint32 *bufSrc = (uint32 *)const_cast<void *>(imageBuffer.getPixels());
-				uint32 *bufDst = (uint32 *)(buffer.getPixels());
-				for (int f = 0; f < (bitmap->_width * bitmap->_height); f++) {
-					uint32 val = SWAP_BYTES_32(bufSrc[f]);
-					bufDst[f] = val;
-				}
-				tglUploadBlitImage(imgs[i], buffer, buffer.format.ARGBToColor(0, 255, 0, 255), true);
-				buffer.free();
-			} else
-#endif
-			{
-				tglUploadBlitImage(imgs[i], imageBuffer, imageBuffer.format.ARGBToColor(0, 255, 0, 255), true);
-			}
+			tglUploadBlitImage(imgs[i], imageBuffer, imageBuffer.format.ARGBToColor(0, 255, 0, 255), true);
 		}
 	}
 }
diff --git a/engines/grim/grim.cpp b/engines/grim/grim.cpp
index dcc096ad11b..f091a6d1989 100644
--- a/engines/grim/grim.cpp
+++ b/engines/grim/grim.cpp
@@ -1685,19 +1685,6 @@ void GrimEngine::pauseEngineIntern(bool pause) {
 	}
 }
 
-
-Graphics::Surface *loadPNG(const Common::Path &filename) {
-	Image::PNGDecoder d;
-	Common::SeekableReadStream *s = SearchMan.createReadStreamForMember(filename);
-	if (!s)
-		return nullptr;
-	d.loadStream(*s);
-	delete s;
-
-	Graphics::Surface *srf = d.getSurface()->convertTo(Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
-	return srf;
-}
-
 void GrimEngine::debugLua(const Common::String &str) {
 	lua_dostring(str.c_str());
 }


Commit: 21948caada191af9ceb74184fcd5a47fca54216b
    https://github.com/scummvm/scummvm/commit/21948caada191af9ceb74184fcd5a47fca54216b
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2024-11-03T09:40:07+02:00

Commit Message:
GRIM: Fix compilation in BE platforms

Changed paths:
    engines/grim/bitmap.cpp


diff --git a/engines/grim/bitmap.cpp b/engines/grim/bitmap.cpp
index 25b47bdde6b..35cbd6cbf11 100644
--- a/engines/grim/bitmap.cpp
+++ b/engines/grim/bitmap.cpp
@@ -327,7 +327,7 @@ bool BitmapData::loadTile(Common::SeekableReadStream *o) {
 #ifndef SCUMM_LITTLE_ENDIAN
 			for (int y = 0; y < _height; ++y) {
 				uint16 *d16 = (uint16 *)d;
-				for (int x = 0; x < _width; ++x) {
+				for (int x = 0; x < _width; ++x)
 					d16[x] = o->readUint16LE();
 				d += _data[i].pitch;
 			}




More information about the Scummvm-git-logs mailing list