Opened 2 months ago

Closed 8 weeks 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 AndywinXp)

Ahoy! Here's the glitch:

https://media.discordapp.net/attachments/711242520415174666/964502682029133844/unknown.png

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)

ft.s78 (16.1 KB ) - added by AndywinXp 2 months ago.
ft.s76 (18.9 KB ) - added by AndywinXp 2 months ago.
scummvm-ft-00002.png (44.3 KB ) - added by eriktorbjorn 2 months ago.

Download all attachments as: .zip

Change History (13)

by AndywinXp, 2 months ago

Attachment: ft.s78 added

by AndywinXp, 2 months ago

Attachment: ft.s76 added

comment:1 by AndywinXp, 2 months ago

Description: modified (diff)

comment:2 by eriktorbjorn, 2 months ago

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.

comment:3 by eriktorbjorn, 2 months ago

I've also used that boot param to confirm that the glitch does not happen in the original.

comment:4 by eriktorbjorn, 2 months 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 AndywinXp, 2 months ago

Thanks! You are right, glitched strips are drawn by drawStripBasicV(), coming from Gdi::decompressBitmap(), case 38.

comment:6 by AndywinXp, 2 months 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 eriktorbjorn, 2 months ago

Attachment: scummvm-ft-00002.png added

comment:7 by eriktorbjorn, 2 months 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:


Last edited 2 months ago by eriktorbjorn (previous) (diff)

comment:8 by eriktorbjorn, 2 months 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 eriktorbjorn, 2 months 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 eriktorbjorn, 8 weeks ago

Owner: set to eriktorbjorn
Resolution: fixed
Status: newclosed

I've merged my pull request, so this should work now.

Note: See TracTickets for help on using tickets.