[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