Opened 6 years ago
Closed 6 years ago
#10751 closed defect (fixed)
QFG4: Rope obscured by bkg when rescuing Igor
Reported by: | Vhati | Owned by: | bluegr |
---|---|---|---|
Priority: | low | Component: | Engine: SCI |
Version: | Keywords: | SCI32 original has-pull-request | |
Cc: | Game: | Quest for Glory 4 |
Description
ScummVM 2.1.0git3770-g15306581ab (Oct 18 2018 04:27:32)
Windows 7 64bit
QFG4 CD (English)
When Igor is trapped in the graveyard...
After climbing a tree and using the grapnel, the rope is briefly obscured by the facade of a background tomb, during a sequence where the hero climbs down and pulls.
File - 5kb MD5 - Full MD5
RESOURCE.000 - 263dce4aa34c49d3ad29bec889007b1c - 1364ba69e3c0abb68cc0170650a56692
RESOURCE.AUD - c39521bffb1d8b19a57394866184a0ca - 71098b9e97e20c8941c0e4812d5f906f
RESOURCE.MAP - aba367f2102e81782d961b14fbe3d630 - 801a04cc6aa5d437681a2dd0b6545248
RESOURCE.SFX - 3cf95e09dab8b11d675e0537e18b499a - 7c858d7253f86dab4cc6066013c5ecec
Attachments (3)
Change History (16)
by , 6 years ago
comment:1 by , 6 years ago
@Vhati: Thanks for the bug report. Could you try testing this with the original SCI interpreter to see if this occurs in the original as well?
comment:3 by , 6 years ago
Keywords: | original added |
---|
comment:4 by , 6 years ago
The floppy edition under ScummVM did not have this bug.
ScummVM 2.1.0git3797-ge7d23d2cd9 (Oct 25 2018 04:17:12)
Windows 7 64bit
QFG4 Floppy 1.1a + note patch (English)
File - 5kb MD5 - Full MD5
RESOURCE.000 - f64fd6aa3977939a86ff30783dd677e1 - ff42260a665995a85aeb277ad80aac8a
RESOURCE.MAP - d10a4cc177d2091d744e2ad8c049b0ae - 3695b1b0a1d15f3d324ea9f0cc325245
RESOURCE.SFX - 3cf95e09dab8b11d675e0537e18b499a - 7c858d7253f86dab4cc6066013c5ecec
comment:5 by , 6 years ago
Quick and dirty way to skip to Igor's rescue.
- Create a rogue.
- Set flag 37 (Heard "Igor is missing!" outside the Burgomeister's office).
- vv g 502 1024
- Give yourself the rope.
- send hero get 16
- Teleport to the graveyard.
- room 500
- Click the rope & grappling hook on the tree branch.
comment:6 by , 6 years ago
SCI Companion says the background Pic has priority regions for the crypt pillars (priority 106).
With some experimentation I learned adjusting priority doesn't update the graphics. Gotta hide/show as well. Batches of commands can be done together from the debugger before dismissing it.
send rope2 setPri 1000
send rope2 hide
send rope2 show
Giving a rope priority 107 was exactly enough to move in front of the pillars.
Breakpoints confirm bigBranch::doVerb(grapnel) is assigning priority (rope1:148, rope2:116).
Start a fresh rescue... climb the tree, click the grapnel on the branch... Sending hide/show is enough to bring both ropes to the front.
When hero comes down, pulling is animated, and the rope comes to the front on its own.
comment:7 by , 6 years ago
Diffing script 500, CD vs floppy, reveals some changes.
Nothing rope-related stands out though.
The speed slider doesn't help. CD always has a problem; floppy never does.
rope1 and rope2 are Actors, whose ancestry is Feature/View/Prop.
script 64998 - View::setPri() is the same.
(method (setPri param1) (cond ((== argc 0) (= fixPriority 1)) ((== param1 -1) (= fixPriority 0)) (else (= priority param1) (= fixPriority 1)) ) )
script 64998 - Actor::doit() changed, but they still have this.
(if (and (& -info- $0008) (self isNotHidden:)) (UpdateScreenItem self) )
script 64950 - View::isNotHidden()
(method (isNotHidden) (return (not (& signal $0008))) )
comment:8 by , 6 years ago
bigBranch::doVerb(grapnel) is calling init() and setPri().
That's the moment it becomes visible, albeit obscured.
script 500 - bigBranch::doVerb(grapnel)
(rope1 init: setPri: 148) (rope2 init: setPri: 116) (global2 setScript: sClimbDown)
rope2 starts out with signal=24576 aka 0x6000.
If I do "send rope2 signal 24577", move the mouse to the icon bar, and dismiss the debugger... the rope remains obscured... until I move the mouse off the icon bar to unpause the game. Then it is immediately repainted, fully.
The script doesn't naturally signal like that until...
script 500 - sTryTree::changeState()
(7 (rope2 signal: (| (rope2 signal?) $0001) setCycle: End self ) ) # ... (12 (global0 view: 7 setLoop: 0 1 setCel: 0 setCycle: Fwd) (rope1 signal: (| (rope1 signal?) $0001) setCycle: End setStep: 1 1 setMotion: MoveTo (rope1 x?) (+ (rope1 y?) 16) ) (rope2 signal: (| (rope2 signal?) $0001) setStep: 1 1 setMotion: MoveTo (+ (rope2 x?) 50) (- (rope1 y?) 50) ) (igor show:) (headStone signal: (| (headStone signal?) $0001) setCycle: Beg self ) )
And those are the moments rope2 and rope1 get painted properly.
"send rope2 doit" didn't help.
"logkernel UpdateScreenItem"
# Floppy when the ropes first appear. kUpdateScreenItem: 0044:3786 (rope1) = 1 kUpdateScreenItem: 0044:381c (rope2) = 1
"bp_method rope2::doit" tripped.
"vo rope2 priority" said 116 already at that moment, and UpdateScreenItem() ran.
# CD, nothing until after hero climbs down and pulls. kUpdateScreenItem: 0044:3cf1 (rope2) = 1 kUpdateScreenItem: 0044:36d5 (moss) = 1 kUpdateScreenItem: 0044:3cf1 (rope2) = 1 kUpdateScreenItem: 0044:3cf1 (rope2) = 1
comment:9 by , 6 years ago
Actor::doit() changed, but they still have this.
Ah. It moved though.
Floppy script 64998 - Actor::doit()
(method (doit &tmp temp0 temp1 temp2 temp3 temp4 temp5 temp6 temp7) (if script (script doit:)) (if code (code doit: self)) # This condition fails, but it doesn't matter. # UpdateScreenItem() is outside. (if (& signal notUpd) (if viewer (viewer doit: self)) (if avoider (avoider doit:)) (if mover (if (and (& scaleSignal $0001) (not (& scaleSignal $0004))) (= temp5 (>> origStep $0008)) (= temp6 (& origStep $00ff)) (= temp3 (if (= temp7 (/ (* temp5 scaleX) 128)) else 1) ) (= temp4 (if (= temp7 (/ (* temp6 scaleY) 128)) else 1) ) (if (or (!= temp3 xStep) (!= temp4 yStep)) (self setStep: temp3 temp4 1) ) ) (if mover (mover doit:)) ) (if scaler (scaler doit:)) (if cycler (= temp1 brLeft) (= temp2 brRight) (cycler doit:) (cond ((not (& signal $0020))) (baseSetter (baseSetter doit: self)) (else (BaseSetter self)) ) ) ) (= xLast x) (= yLast y) (if (and (& -info- $0008) (self isNotHidden:)) (UpdateScreenItem self) ) )
CD script 64998 - Actor::doit()
(method (doit &tmp [temp0 2] temp2 temp3 temp4) (if robot (robot doit:)) (if script (script doit:)) (if code (code doit: self)) # This condition fails as doit() is repeatedly called. (if (& signal notUpd) (if viewer (viewer doit: self)) (if avoider (avoider doit:)) (if mover (mover doit:)) (if cycler (cycler doit:)) (if (& -info- $0008) (if scaler (scaler doit:)) (= xLast x) (= yLast y) # So this doesn't happen. (if (self isNotHidden:) (UpdateScreenItem self)) (if (and (& scaleSignal $0001) (not (& scaleSignal $0004)) (!= scaleX oldScaleX) ) (= oldScaleX scaleX) (= temp2 (if (= temp4 (>> (+ (* (>> origStep $0008) scaleX) 64) $0007) ) else 1 ) ) (= temp3 (if (= temp4 (>> (+ (* (& origStep $00ff) scaleY) 64) $0007) ) else 1 ) ) (if (or (!= temp2 xStep) (!= temp3 yStep)) (self setStep: temp2 temp3 1) ) ) (cond ((not (& signal $0020))) (baseSetter (baseSetter doit: self)) (else (BaseSetter self)) ) ) ) )
Dunno what's up with the label "notUpd".
Disassembly says that's an AND between "signal" and a literal 1.
Which means this notifies the rope to call UpdateScreenItem().
(rope2 signal: (| (rope2 signal?) $0001))
That sets signal's 1 bit to satisfy the condition.
comment:10 by , 6 years ago
Maybe I could tweak the signal value the ropes are instantiated with?
script 500
(instance rope1 of Actor (properties x 100 y -10 view 502 signal $6000 ) ) (instance rope2 of Actor (properties x 127 y -5 view 502 loop 1 signal $6000 ) )
That'd be tidy. Except I don't know how to disassemble/patch those blocks.
Hrm. I think I found them. In heap 500's raw bytes. 127 was a distinctive number.
(In SCI Companion, list the heaps, right-click heap 500 and "view raw data". Hex values coincide with the properties list for an instance in SCI Companion's disassembly.)
Guess that means I can't patch there.
comment:11 by , 6 years ago
Correction, I CAN patch the heap, with no special effort.
Except the "signal" value in particular doesn't survive init().
Gotta set it elsewhere then...
EDIT: No wait, it works! Took a little special effort. My savegame was IN the graveyard. I needed to re-enter the room for my heap patch to work.
comment:12 by , 6 years ago
Keywords: | has-pull-request added |
---|
Pull Request: SCI32: Fix QFG4 obscured ropes when rescuing Igor
comment:13 by , 6 years ago
Owner: | set to |
---|---|
Resolution: | → fixed |
Status: | new → closed |
Thanks for your work! The pull request has been merged, so this can be closed now
SavedGame - Grapnel