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

moralrecordings noreply at scummvm.org
Tue May 28 08:46:01 UTC 2024


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

Summary:
bde3fe3f77 DIRECTOR: Reset palette in use on movie switch


Commit: bde3fe3f77bb201d4a90d3883a7be7c62435496e
    https://github.com/scummvm/scummvm/commit/bde3fe3f77bb201d4a90d3883a7be7c62435496e
Author: Scott Percival (code at moral.net.au)
Date: 2024-05-28T16:43:43+08:00

Commit Message:
DIRECTOR: Reset palette in use on movie switch

Previously if there was a movie switch, and the two movies used
different custom palettes with the same cast ID, there was no
mechanism to force a swap to the new palette.

Fixes palette glitches in Die Hexenakademie.

Changed paths:
    engines/director/castmember/palette.cpp
    engines/director/castmember/palette.h
    engines/director/graphics.cpp
    engines/director/window.cpp


diff --git a/engines/director/castmember/palette.cpp b/engines/director/castmember/palette.cpp
index 027069ea297..e6ef96e646e 100644
--- a/engines/director/castmember/palette.cpp
+++ b/engines/director/castmember/palette.cpp
@@ -41,6 +41,13 @@ PaletteCastMember::PaletteCastMember(Cast *cast, uint16 castId, PaletteCastMembe
 	_palette = source._palette ? new PaletteV4(*source._palette) : nullptr;
 }
 
+PaletteCastMember::~PaletteCastMember() {
+	if (_palette) {
+		delete[] _palette->palette;
+		delete _palette;
+	}
+}
+
 Common::String PaletteCastMember::formatInfo() {
 	Common::String result;
 	if (_palette) {
@@ -84,7 +91,7 @@ void PaletteCastMember::load() {
 			PaletteV4 palData = _cast->loadPalette(*pal, paletteId);
 			CastMemberID cid(_castId, _cast->_castLibID);
 			g_director->addPalette(cid, palData.palette, palData.length);
-			_palette = g_director->getPalette(cid);
+			_palette = new PaletteV4(palData);
 			delete pal;
 		} else {
 			warning("PaletteCastMember::load(): no CLUT palette %d for cast index %d found", paletteId, _castId);
diff --git a/engines/director/castmember/palette.h b/engines/director/castmember/palette.h
index 43f44b61ea4..d669d78b82b 100644
--- a/engines/director/castmember/palette.h
+++ b/engines/director/castmember/palette.h
@@ -30,6 +30,7 @@ class PaletteCastMember : public CastMember {
 public:
 	PaletteCastMember(Cast *cast, uint16 castId, Common::SeekableReadStreamEndian &stream, uint16 version);
 	PaletteCastMember(Cast *cast, uint16 castId, PaletteCastMember &source);
+	~PaletteCastMember();
 	CastMemberID getPaletteId() { return _palette ? _palette->id : CastMemberID(0, 0); }
 	void activatePalette() { if (_palette) g_director->setPalette(_palette->id); }
 
diff --git a/engines/director/graphics.cpp b/engines/director/graphics.cpp
index 7f52cea2145..39f106c27ff 100644
--- a/engines/director/graphics.cpp
+++ b/engines/director/graphics.cpp
@@ -150,8 +150,10 @@ void DirectorEngine::addPalette(CastMemberID &id, byte *palette, int length) {
 	}
 
 	debugC(3, kDebugLoading, "DirectorEngine::addPalette(): Registered palette %s of size %d, hash: %x", id.asString().c_str(), length, id.hash());
+	byte *palCopy = new byte[length * 3]; // freed by clearPalettes()
+	memcpy(palCopy, palette, length * 3);
 
-	_loadedPalettes[id] = PaletteV4(id, palette, length);
+	_loadedPalettes[id] = PaletteV4(id, palCopy, length);
 }
 
 bool DirectorEngine::setPalette(const CastMemberID &id) {
@@ -163,6 +165,7 @@ bool DirectorEngine::setPalette(const CastMemberID &id) {
 	PaletteV4 *pal = getPalette(id);
 	if (!pal)
 		return false;
+	debugC(5, kDebugImages, "DirectorEngine::setPalettes(): setting palette %d, %d", id.member, id.castLib);
 	setPalette(pal->palette, pal->length);
 	return true;
 }
@@ -172,6 +175,13 @@ void DirectorEngine::setPalette(byte *palette, uint16 count) {
 	memset(_currentPalette, 0, 768);
 	memmove(_currentPalette, palette, count * 3);
 	_currentPaletteLength = count;
+	if (debugChannelSet(8, kDebugImages)) {
+		Common::String palData;
+		for (size_t i = 0; i < (size_t)_currentPaletteLength; i++) {
+			palData += Common::String::format("%02X%02X%02X", _currentPalette[3 * i], _currentPalette[3 * i + 1], _currentPalette[3 * i + 2]);
+		}
+		debugC(8, kDebugImages, "DirectorEngine::setPalette(): Setting current palette: %s", palData.c_str());
+	}
 
 	// Pass the palette to OSystem only for 8bpp mode
 	if (_pixelformat.bytesPerPixel == 1)
@@ -203,6 +213,14 @@ void DirectorEngine::shiftPalette(int startIndex, int endIndex, bool reverse) {
 		memcpy(_currentPalette + 3 * startIndex, temp, 3);
 	}
 
+	if (debugChannelSet(8, kDebugImages)) {
+		Common::String palData;
+		for (size_t i = 0; i < (size_t)_currentPaletteLength; i++) {
+			palData += Common::String::format("%02X%02X%02X", _currentPalette[3 * i], _currentPalette[3 * i + 1], _currentPalette[3 * i + 2]);
+		}
+		debugC(8, kDebugImages, "DirectorEngine::shiftPalette(): Rotating current palette (start: %d, end: %d, reverse: %d): %s", startIndex, endIndex, reverse, palData.c_str());
+	}
+
 	// Pass the palette to OSystem only for 8bpp mode
 	if (_pixelformat.bytesPerPixel == 1)
 		_system->getPaletteManager()->setPalette(_currentPalette, 0, _currentPaletteLength);
@@ -211,10 +229,16 @@ void DirectorEngine::shiftPalette(int startIndex, int endIndex, bool reverse) {
 }
 
 void DirectorEngine::clearPalettes() {
+	// FIXME: Ideally we would run this every time we switch movie; but that would need to take
+	// into account e.g. shared casts that haven't changed, multiple windows...
 	for (auto it = _loadedPalettes.begin(); it != _loadedPalettes.end(); ++it) {
-		if (it->_value.id.castLib > 0)
+		if (it->_value.id.castLib > 0) {
+			debugC(5, kDebugImages, "DirectorEngine::clearPalettes(): erasing palette %d, %d", it->_value.id.member, it->_value.id.castLib);
 			delete[] it->_value.palette;
+			_loadedPalettes.erase(it);
+		}
 	}
+	_lastPalette = CastMemberID();
 }
 
 void DirectorEngine::setCursor(DirectorCursor type) {
diff --git a/engines/director/window.cpp b/engines/director/window.cpp
index 7d5daff6546..480de2eae51 100644
--- a/engines/director/window.cpp
+++ b/engines/director/window.cpp
@@ -510,6 +510,7 @@ bool Window::step() {
 			return (_vm->getGameGID() == GID_TESTALL);
 
 		g_lingo->resetLingo();
+		g_director->_lastPalette = CastMemberID();
 	}
 
 	// play current movie




More information about the Scummvm-git-logs mailing list