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

bluegr noreply at scummvm.org
Sat Oct 1 08:31:45 UTC 2022


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:
d3069f84e8 SCUMM: Fix an original tapestry glitch in Indy3 VGA (Trac#3208)


Commit: d3069f84e8153e56e1e85f275954a25a37119963
    https://github.com/scummvm/scummvm/commit/d3069f84e8153e56e1e85f275954a25a37119963
Author: Donovan Watteau (contrib at dwatteau.fr)
Date: 2022-10-01T11:31:41+03:00

Commit Message:
SCUMM: Fix an original tapestry glitch in Indy3 VGA (Trac#3208)

The 256-color versions of Indy3 have a very strange vertical line on the
big tapestry that's in the middle of room 135, in Castle Brunwald.

It looks like an artist made some wrong click when redrawing this object
for the VGA versions, or maybe the compression routine for those images
had some bug. QA was probably rushed for this port, too, since Indy3 has
various oversights related to the VGA conversion. A similar problem was
fixed in commit 6735e3c0f006730831f020e31b3385ee55f58edb.

The tapestry glitch was a bit harder to fix, because the glitched line
hides several pixels with different colors, and because this resource is
in a compressed format. AFAICS, v3 games have no concept of transparent
pixels for background objects, so that simpler solution wouldn't work
either. We could also trim the leftmost OI strip (since the wall in the
background is fine), but I couldn't get this to safely work with the way
unkDecode11() works.

So I have redrawn a fixed OI_0324 with the old BMRP.EXE tool, diffed
the two resources and then added a small mechanism which patches (for
copyright reasons) the impacted bytes from the original resource, as
it is being read. This is a very low-level trick, so various checks
have been added to make sure that we're not corrupting something
(incl. any fan-made modified Indy3), and also in order to make the
workaround a bit easier to follow.

(The most obsessive players will notice that the tapestry still cuts
through a part of the column in the upper-right corner, but I'm only
interested in fixing the obvious problem which was right in the
middle of the room. Sorry if you wished you hadn't seen this.)

Changed paths:
    engines/scumm/object.cpp


diff --git a/engines/scumm/object.cpp b/engines/scumm/object.cpp
index b44febf8a1f..57f686f4d6d 100644
--- a/engines/scumm/object.cpp
+++ b/engines/scumm/object.cpp
@@ -694,6 +694,38 @@ void ScummEngine::drawObject(int obj, int arg) {
 		numstrip++;
 	}
 
+	byte *patchedBmpPtr = nullptr;
+	// WORKAROUND bug #3208: in all 256-color versions of Indy3, the tapestry
+	// in one of the first rooms of Castle Brunwald has a strange vertical
+	// line at the bottom of its first 'strip' (purple in the DOS version,
+	// blue on the FM-TOWNS). We can't include the whole redrawn resource for
+	// copyright reasons, so we just patch the impacted bytes from a fixed OI
+	// (made with BMRP.EXE).
+	if (_game.id == GID_INDY3 && (_game.features & GF_OLD256) && _currentRoom == 135
+	    && od.obj_nr == 324 && numstrip == od.width / 8 && _enableEnhancements) {
+		// Extra safety: make sure that the OI has the expected length. Indy3
+		// should always be GF_SMALL_HEADER, but that's implicit, so do an
+		// explicit check, since we're doing some low-level byte tricks.
+		const uint32 origOILen = 6184, firstPartLen = 123, droppedPartLen = 3, patchLen = 8;
+		const int nextObjIdx = getObjectIndex(od.obj_nr + 1);
+		if ((_game.features & GF_SMALL_HEADER) && nextObjIdx != -1 &&
+		    _objs[nextObjIdx].OBIMoffset - od.OBIMoffset == origOILen && READ_LE_UINT32(ptr) == 6146) {
+			// Copy the original (compressed) OI and patch the faulty content
+			patchedBmpPtr = new byte[origOILen - 8 + patchLen - droppedPartLen];
+			memcpy(patchedBmpPtr, ptr, firstPartLen);
+			memcpy(patchedBmpPtr + firstPartLen, "\x08\xAF\xE0\xC7\x47\xB8\xF1\x11", patchLen);
+			memcpy(patchedBmpPtr + firstPartLen + patchLen, ptr + (firstPartLen + droppedPartLen),
+			    origOILen - 8 - (firstPartLen + droppedPartLen));
+
+			// Adjust the offsets for the new OI size
+			WRITE_LE_UINT32(patchedBmpPtr, READ_LE_UINT32(patchedBmpPtr) + (patchLen - droppedPartLen));
+			for (int i = 2; i <= od.width / 8; i++)
+				WRITE_LE_UINT32(patchedBmpPtr + i * 4, READ_LE_UINT32(patchedBmpPtr + i * 4) + (patchLen - droppedPartLen));
+
+			ptr = patchedBmpPtr;
+		}
+	}
+
 	if (numstrip != 0) {
 		byte flags = od.flags | Gdi::dbObjectMode;
 
@@ -710,6 +742,9 @@ void ScummEngine::drawObject(int obj, int arg) {
 #endif
 			_gdi->drawBitmap(ptr, &_virtscr[kMainVirtScreen], x, ypos, width * 8, height, x - xpos, numstrip, flags);
 	}
+
+	if (patchedBmpPtr)
+		delete[] patchedBmpPtr;
 }
 
 void ScummEngine::clearRoomObjects() {




More information about the Scummvm-git-logs mailing list