Opened 4 years ago
Closed 4 years ago
#13419 closed defect (fixed)
SCUMM: FT: Garbled graphics when Ripburger is running away
| Reported by: | AndywinXp | Owned by: | eriktorbjorn |
|---|---|---|---|
| Priority: | normal | Component: | Engine: SCUMM |
| Version: | Keywords: | ||
| Cc: | Game: | Full Throttle |
Description (last modified by )
Ahoy! Here's the glitch:
I tested this on both 2.6.0git and 2.5.1 stable, on FT Version B eng and ita. I haven't had time to investigate the cause, but being that there's graphics (and possibly decoding routines) involved I think I'm gonna have to nope out of this one. :-)
I'll attach a couple of handy savegames below.
Attachments (3)
Change History (13)
by , 4 years ago
by , 4 years ago
comment:1 by , 4 years ago
| Description: | modified (diff) |
|---|
comment:2 by , 4 years ago
comment:3 by , 4 years ago
I've also used that boot param to confirm that the glitch does not happen in the original.
comment:4 by , 4 years ago
I could be wrong, but it looks to me like the glitched strips are drawn by drawStripBasicV(). (The object seems to use two different methods for different strips.) But I don't see the problem, at least not yet.
comment:5 by , 4 years ago
Thanks! You are right, glitched strips are drawn by drawStripBasicV(), coming from Gdi::decompressBitmap(), case 38.
comment:6 by , 4 years ago
I was able to locate the correspondent function in the disasm, but at a first glance it seems to be engineered slightly differently from ours, so I have to renew my "nope" stance for now :-) if someone else wants to tackle that I can provide all the details.
by , 4 years ago
| Attachment: | scummvm-ft-00002.png added |
|---|
comment:7 by , 4 years ago
It looks to me like it's already pretty close to decoding it correctly. I can fix the rendering with this not-really-a-workaround:
diff --git a/engines/scumm/gfx.cpp b/engines/scumm/gfx.cpp
index c3633121eb6..366103010c3 100644
--- a/engines/scumm/gfx.cpp
+++ b/engines/scumm/gfx.cpp
@@ -3557,8 +3557,17 @@ void Gdi::drawStripBasicV(byte *dst, int dstPitch, const byte *src, int height,
byte bit;
int8 inc = -1;
+ // Not meant as a serious workaround!!!
+ if (height == 120) {
+ height += 6;
+ // _vertStripNextInc can't be modified here. Replaced it with
+ // keeping track of the old dst value instead.
+ // _vertStripNextInc += (6 * dstPitch);
+ }
+
int x = 8;
do {
+ byte *oldDst = dst;
int h = height;
do {
FILL_BITS;
@@ -3579,7 +3588,7 @@ void Gdi::drawStripBasicV(byte *dst, int dstPitch, const byte *src, int height,
color += inc;
}
} while (--h);
- dst -= _vertStripNextInc;
+ dst = oldDst + 1;
} while (--x);
}
So it looks like it's getting the height of the image wrong somehow? This is what it looks like for me with the modification:
comment:8 by , 4 years ago
Here's another maybe-not-a-workaround that could possibly be nearing something correct. This keeps drawObject() from modifying od.height. It's possible that this will break a lot of other games, but it looks to me like those bits are already masked out in most older SCUMM versions.
I'm not in a position to make that judgment thought.
diff --git a/engines/scumm/object.cpp b/engines/scumm/object.cpp
index bfcb58b8d53..cbce6bc9aaa 100644
--- a/engines/scumm/object.cpp
+++ b/engines/scumm/object.cpp
@@ -625,7 +625,7 @@ void ScummEngine::drawObject(int obj, int arg) {
const int ypos = od.y_pos;
width = od.width / 8;
- height = od.height &= 0xFFFFFFF8; // Mask out last 3 bits
+ height = od.height;
// Short circuit for objects which aren't visible at all.
if (width == 0 || xpos > _screenEndStrip || xpos + width < _screenStartStrip)
comment:9 by , 4 years ago
From Discord:
Bosca
Yup, FT, DIG & COMI appear to use the height parameter as-is. If that masking is there, it's probably there for a reason though; so I'd limit the fix to v7-8
comment:10 by , 4 years ago
| Owner: | set to |
|---|---|
| Resolution: | → fixed |
| Status: | new → closed |
I've merged my pull request, so this should work now.



Boot param 850 puts you near the scene, too.
It looks like the open door is drawn by ScummEngine::drawObject() as object number 6. Fortunately, this function doesn't get called more than a couple of times during the scene so it should be doable for someone who understands the image decoding to step through it.