Opened 21 years ago

Closed 20 years ago

#885 closed defect (fixed)

COMI: Wally's Fake piratehook still on ground after pick up

Reported by: SF/zafos Owned by: Kirben
Priority: low Component: Engine: SCUMM
Version: Keywords:
Cc: Game: Monkey Island 3

Description

ScummVM : 0.4.2cvs June 14 2003, Win32 version English (European) version of COMI

At the Beginning of the game, after making Wally cry, if you try to pick up Wally's fake pirate hook, although it is inserted in the inventory, the hook sprite remains on the ground. By looking outside the ship and inside again the sprite disappears from the ground.

Ticket imported from: #754419. Ticket imported from: bugs/885.

Attachments (2)

hook.zip (52.7 KB ) - added by SF/zafos 21 years ago.
Saved state when the bug appeared
chore-hack.diff (661 bytes ) - added by eriktorbjorn 20 years ago.
Patch against a July 15 CVS snapshot

Download all attachments as: .zip

Change History (18)

by SF/zafos, 21 years ago

Attachment: hook.zip added

Saved state when the bug appeared

comment:1 by fingolfin, 21 years ago

Summary: COMI:Wally's Fake piratehook still on ground after pick upCOMI: Wally's Fake piratehook still on ground after pick up

comment:2 by SF/ender, 21 years ago

Priority: normallow

comment:3 by SF/ender, 21 years ago

Lowering priority as it's a cosmetic bug. The hook is actually I believe part of the actor costume and not a seperate sprite - so I assume the problem is due to issues with our implementation of the setActorChoreLimbFrame kernelOp.

comment:4 by eriktorbjorn, 21 years ago

I've looked some more at this, and while I still don't know the correct way of fixing it I do believe I understand it a little better than before. By the way, it looks like Wally's floating head is caused by the same problem.

As far as I can see, it's script-28 that uses the setActorChoreLimbFrame() opcode. Here's the fragment from it that I believe is relevant for Wally:

[0BFC] (65) while ((VAR_TALK_ACTOR == 2) && (VAR_HAVE_MSG == 1)) { [0C18] (65) if (localvar2 == 13) { [0C28] (6D) localvar4 = (kernelGetFunctions.lipSyncWidth([]) / 22) [0C3E] (65) if (localvar4 > 3) { [0C4E] (6D) localvar4 = 3 [0C58] (**) } [0C58] (6D) localvar5 = (kernelGetFunctions.lipSyncHeight([]) / 35) [0C6E] (65) if (localvar5 > 2) { [0C7E] (6D) localvar5 = 2 [0C88] (**) } [0C88] (6D) localvar1 = (localvar4 + (localvar5 * 4)) [0C9E] (6D) localvar2 = kernelGetFunctions.actorTalkAnimation([VAR_TALK_ACTOR]) [0CB3] (6D) localvar3 = 0 [0CBD] (66) } else { [0CC2] (6D) localvar4 = (kernelGetFunctions.lipSyncWidth([]) / 28) [0CD8] (65) if (localvar4 > 3) { [0CE8] (6D) localvar4 = 3 [0CF2] (**) } [0CF2] (6D) localvar5 = (kernelGetFunctions.lipSyncHeight([]) / 39) [0D08] (65) if (localvar5 > 2) { [0D18] (6D) localvar5 = 2 [0D22] (**) } [0D22] (6D) localvar1 = (localvar4 + (localvar5 * 4)) [0D38] (6D) localvar2 = kernelGetFunctions.actorTalkAnimation([VAR_TALK_ACTOR]) [0D4D] (6D) localvar3 = 1 [0D57] (**) } [0D57] (BA)
kernelSetFunctions.setActorChoreLimbFrame([localvar0,localvar2,localvar3,localvar1]) [0D76] (67) breakHere() [0D7C] (**) } [0D77] (A4) animateActor(2,1005)

It should be noted that localvar0 has already been set to VAR_TALK_ACTOR at this point, but it's the second parameter that's the most interesting because that's the one that gets passed to startAnimActor().

Wally's crying is done in "MUMBLE" mode, which as far as I can understand means that there is no specific "talk" animation for it. Yet setActorChoreLimbFrame() will run his talk animation because that's the frame it gets from actorTalkAnimation().

If I change the actorTalkAnimation() opcode from

push(a->talkStartFrame);

to

push(_useTalkAnims ? a->talkStartFrame : a->frame);

it almost works. Almost. The floating head appears again, briefly, right after using the cannon. Probably because Guybrush is talking while Wally is crying, so I guess _useTalkAnims is probably true again.

Is this any help in finding the correct bugfix?

comment:5 by eriktorbjorn, 21 years ago

I asked aquadran, and he said it the SO_PRINT_MUMBLE and actorTalkAnimation() opcodes looked correct to him.

setActorChoreLimbFrame() looks too simple to be wrong all by itself, but I guess the functions it calls might be. Or maybe the original sets talkStartFrame where we don't.

comment:6 by SF/thedarkprophet, 21 years ago

Also, in the same room, when he cries, an image of his head appears talking above the cannon.

comment:7 by SF/lechimp, 21 years ago

It appears that with the latest tarball (23/1/2004), the hook disappears from the floor when picked up just as it should. Wally's head is still appearing at the cannon, though.

comment:8 by eriktorbjorn, 21 years ago

I thought the hook always disappeared when you picked it up, and that the bug was that it reappears briefly when Wally speaks (sobs, actually). By leaving the room and re-entering you can change the behaviour of the bug, i.e. now it's his head that appears rather than the hook.

(At least that's how it worked when I wrote my comment on January 10.)

comment:9 by SF/lechimp, 21 years ago

Hmmm...very strange.... I know I should make sure a bug is reproducible before posting a bug report, but it seems that also goes for bug fix reports. :-)

I just tried again a few and I get a different result - still with the
same tarball as before - from Jan 23rd. This time the hook sprite stays still on the floor right after picking it up. When Wally sobs the sprite 'blinks' shortly at the start of the sobbing. Walking past the cannon and back makes the hook disappear and I never see it reappear when Wally sobs (as you mention - actually I've never seen that!), but part of Wally's 'This'll make you rue the day' talking animation appears shortly at the cannon.

It seems like you see the opposite of me - when Wally sobs (before leaving and entering) I see the hook temporarily going OUT of view, and you see it come INTO view. Hmmm... I'm running it on MacOS X - could it be related to endianness here?

comment:10 by eriktorbjorn, 21 years ago

Well, I may be misremembering the exact details of the pirate hook, come to think of it. I do remember for certain that the floating head didn't appear until after I had left and re-entered the room though.

comment:11 by SF/monkeybutter, 21 years ago

This is still reproducable using the 20040222 daily, built against debian testing. Hook reappears during a Wally dialog even (sobbing), but when you leave the room and return, it's a disembodied head that appears on dialog events. Just so you know :-)

comment:12 by SF/ender, 21 years ago

We know, we know :)

comment:13 by SF/bigmuzzy, 21 years ago

Guess, something is wrong with the script that animates Wally's cries. Wally doesn't almost move: just freeze sitting on the floor with his eyes closed; and he is only slighly animated (say, one time in five seconds) when cries and sobs; the "fake" hook on the floor "moves" the same way.

Also think, Torbjrn Andersson is right and problem with Wally's second head appearing near cannon could be connected with this one.

by eriktorbjorn, 20 years ago

Attachment: chore-hack.diff added

Patch against a July 15 CVS snapshot

comment:14 by eriktorbjorn, 20 years ago

I had another look at this today, and while I didn't get much further this time than last time, there was one thing I did notice:

In actorTalk(), we check if the string has the no_talk_anim. Only if it doesn't do we call startAnimActor(talkStartFrame). At this point we also set _useTalkAnims to true. In stopTalk(), we check _useTalkAnims before allowing startAnimActor(talkStopFrame) to be called.

So both when starting and stopping the talking, we check if there actually is supposed to be a talk animation for that string.

However, when the game uses the "actor chore frame" opcode to move the actor's mouth - and COMI does that all the time! - we do not check if the message is being "mumbled" or not.

When the crying starts, Wally's talkStartFrame is one that shows the hook on the ground, which is fairly unnoticeable. But once you leave and re-enter the room, startTalkFrame is set (by the entry script, or at least by a script invoked by it) to the talking head again. Try as I might, I can't find any sign that the scripts try to set it to anything else, so I can only assume that the frame is "correct", but should not be shown.

I'm attaching a possible hack/workaround. I haven't had the time to test it much, so it may have issues, but it does seem like an improvement. I also have no idea if the original interpreter did it like this or not, but surely it had to do *something* like this to keep Wally's mouth shut and his head attached to his shoulders?

comment:15 by Kirben, 20 years ago

Owner: set to Kirben

comment:16 by Kirben, 20 years ago

Resolution: fixed
Status: newclosed
Note: See TracTickets for help on using tickets.