[Scummvm-tracker] [ScummVM] #9806: SCI: SQ4 Windows: Stuck when picking up matches

ScummVM trac at scummvm.org
Thu Feb 21 07:44:50 CET 2019


#9806: SCI: SQ4 Windows: Stuck when picking up matches
----------------------------+-------------------------
  Reporter:  dafioram       |      Owner:  (none)
      Type:  defect         |     Status:  new
  Priority:  normal         |  Component:  Engine: SCI
Resolution:                 |   Keywords:
      Game:  Space Quest 4  |
----------------------------+-------------------------

Comment (by Vhati):

 HAND invokes door::doverb(4), which schedules enterBar.

 WALK is handled by rm610::doit() inRect() tests, one of which schedules
 enterBar. The debugger can cause the bug by directly repositioning ego
 onto the bar's entrance as the biker approaches, interrupting theDodgeR
 without a WALK event, just as HAND would. Ego only faces east. Getting the
 matches will stall.

 * send ego posn 192 135
 \\
 \\
 Ah! Grooper::doit() is aborting its duties because when View::setLoop() is
 given a numeric value, it sets a noTurn bit (0x800) on ego's 'signal'
 property.
 \\
 \\
 When the biker is approaching, theDodgeR is idling after state 1, awaiting
 a WALK event to advance, via theDodgeR::handleEvent().

 theDodgeR::changeState(1)
 {{{
 (1
         (proc0_3)
         (g0_ego view: 635 setLoop: 0 setCel: 0)
 )
 }}}
 There's setLoop(0).
 \\
 \\
 script 998 - Actor::setLoop()
 {{{
 (method (setLoop param1 &tmp temp0)
         (if
                 (= temp0
                         (cond
                                 ((== argc 0) (super setLoop:) 0)
                                 ((not (IsObject param1)) (super setLoop:
 param1 &rest) 0)
                                 ((& (param1 -info-?) $8000) (param1 new:))
                                 (else param1)
                         )
                 )
                 (if looper (looper dispose:))
                 ((= looper temp0) init: self &rest)
         )
 )
 }}}
 Numbers are handled by the superclass...
 \\
 \\
 script 998 - View::setLoop()
 {{{
 (method (setLoop param1)
         (cond
                 ((== argc 0) (= signal (| signal noTurn)))
                 ((== param1 -1) (= signal (& signal $f7ff)))
                 (else (= loop param1) (= signal (| signal noTurn)))
         )
         (self forceUpd:)
 )
 }}}
 Where ego gets the noTurn (0x800) bit set.
 \\
 \\
 Once inside the bar, ego's 'signal' is normally 24642; 26690 when bugged.
 That bit is the difference. The following fixes the sprite and makes the
 matches gettable.

 * send ego 24642
 \\
 \\
 If theDodgeR were allowed to advance...

 script 706 - theDodgeR::changeState(3)
 {{{
 (3
         (proc0_11 77 5)
         (proc0_1 (g0_ego loop?) 0)
         (g0_ego
                 posn: (+ (g0_ego x?) 24) (+ (g0_ego y?) 5)
                 heading: 90 self
         )
 )
 }}}
 proc0_11() scores points.
 proc0_1() normalizes ego.
 \\
 \\
 script 0 - proc0_1()
 {{{
 (procedure (proc0_1 param1 param2 param3 &tmp temp0)
         (= temp0 0)
         (if (> argc 0)
                 (g0_ego loop: param1)
                 (if (> argc 1)
                         (g0_ego view: param2)
                         (if (> argc 2) (= temp0 param3))
                 )
         )
         (if (not temp0) (= temp0 4))
         (g0_ego
                 normal: 1
                 moveHead: 1
                 setLoop: -1
                 setLoop: stopGroop
                 setPri: -1
                 setMotion: 0
                 setCycle: StopWalk temp0
                 setStep: 3 2
                 illegalBits: 0
                 ignoreActors: 0
                 setSpeed: global199
         )
 )
 }}}
 setLoop(-1) resets ego's 'signal' bits.
 Ego can turn. The matches are gettable.

 The next room does some bit twiddling of its own, but doesn't completely
 reset the 'signal' property, so when bugged, the noTurn bit persists.

-- 
Ticket URL: <https://bugs.scummvm.org/ticket/9806#comment:6>
ScummVM <https://bugs.scummvm.org>
ScummVM


More information about the Scummvm-tracker mailing list