Menu

#5624 ZAKTOWNS: Opening hostel door (Mars) corrupts cutscene index

open
kirben
5
2011-04-04
2011-04-01
No

If either Leslie or Melissa closes hoster door on Mars from the outside, and then opens it again, vm.cutSceneStackPointer underflows from 0 to 255. Later on in the game, yellow crystal cannot be used due to assertion error on vm.cutSceneStackPointer value (it should be between 0 and 4).

I'm using the FM-TOWNS version of Zak McKracken. ScummVM is built from a source snapshot from date 2011-03-29, on OpenBSD.

Attached is a savegame that triggers the bug. Another attachment is a patch that turns the bug into an immediate crash.

Discussion

  • Juha Erkkilä

    Juha Erkkilä - 2011-04-01

    Zak savegame

     
  • Juha Erkkilä

    Juha Erkkilä - 2011-04-01

    A patch to trigger an immediate crash when opening hostel door

     
  • Filippos Karapetis

    Assigning this to kirben, since he originally fixed this one

     
  • Filippos Karapetis

    • labels: 415217 --> Script bugs
    • assigned_to: nobody --> kirben
     
  • Max Horn

    Max Horn - 2011-04-04

    Checking for cutSceneStackPointer underflows (as in your patch) is a good idea, I just committed a similar change for that.

     
  • Max Horn

    Max Horn - 2011-04-04

    I looked at the script room-27-205 in question, and also at tracker item #1668393, and also at Kirben's fix from SVN rev 42590 (git commit 1d40f784) is quite nailing it.

    Then I took the relevant script, and compared it to the equivalent script roomobj-27-450 from Zak v2. Consider this from the "old" script:

    [0026] (47) clearState08(472);
    [0029] (0F) if (!getState08(463)) {
    [002E] (0F) if (!getState08(465)) {
    [0033] (60) cursorCommand(15, 2);
    [0036] (1A) Var[47] = 3;
    ...
    [0052] (07) setState08(465);
    ...
    [0061] (1C) startSound(25);
    [0063] (07) setState08(463);
    [0066] (07) setState08(449);
    [0069] (2E) delay(60);
    [006D] (60) cursorCommand(247, 1);
    [0070] (18) } else {
    [0073] (18) goto 0061;
    [0076] (**) }

    with this from the new (FM-TOWNS) script:

    [0010] (07) setState(472,0);
    [0014] (0F) if (getState(463) == 0) {
    [001A] (1D) if (classOfIs(465,[0])) {
    [0023] (40) cutscene([2]);
    ...
    [0057] (5D) setClass(465,[1]);
    ...
    [006C] (1C) startSound(23);
    [006E] (07) setState(463,1);
    [0072] (07) setState(449,1);
    [0076] (2E) delay(60);
    [007A] (C0) endCutscene();
    [007B] (18) } else {
    [007E] (18) goto 006C;
    [0081] (**) }

    First off, it becomes clear where the crash originates: the "if() {}" block contains a begin/end cutscene pair (resp. the equivalent cursorCommand in SCUMM v2). The else block jumps into the middle of the "if" block, and so the endCutscene is hit without beginCutscene being triggered.

    Now, if you look closely, it seems that they have translated some setState08(N) calls into setState(N, 1) ; but at least the one for N=465, they converted into a setClass(N,[1]) call. And "!getState08(465)" became classOfIs(465,[0])

    Kirben correctly guessed that the first "classOfIs" was a mistranslation. Correct; but so are several of the later setClass calls.

    So, I made the attached patch which adds a workaround to the setClass opcode.

    The only problem is that this does not solve the issue at hand, because setClass is never called -- it turns out that in the given save state, the state of object 465 (the inner door) has already been set to 1! Maybe this means the savestate is inconsistent (possibly due to the incomplete older workaround), or maybe something else is going on that I am missing... This needs to be investigated some more!

     
  • Max Horn

    Max Horn - 2011-04-04

    I actually just pushed my setClass workaround, instead of attaching here (Kirben, or anybody else, please review).

    Since 465 seems to be the inside door (according to Kirben's workaround comment), I wonder if 463 is the outside door?

    A simple workaround to the crash here would be to ignore the endCutscene call in room-27-205 if no cutscene is active. However, I'd prefer to only do this if we can confirm that the setClass changes really fix the underlying issue.

     
  • Filippos Karapetis

    • summary: Opening hostel door on Mars corrupts cutscene index --> ZAKTOWNS: Opening hostel door (Mars) corrupts cutscene index
     
  • Filippos Karapetis

    Updated description

     
  • dronkit

    dronkit - 2013-08-22

    Sorry guys that I don't understand most of what you say here, but you talk like a workaround has been added to scummvm 2 years ago.

    But I'm having the exact same bug on versions 1.6.0 (jul 9 2013 11:25:59) win32, 1.7.0git1551-ge63b722 (Aug 22 2013 04:28:55) win64, both under windows 7 x64, and in 1.6.0-raring.1_amd64 (under Ubuntu Raring).

    Or hasn't the workaround been added? Can I workaround this error by hand? thanks!

     
  • Anonymous

    Anonymous - 2013-08-23

    ScummVM 1.7.0git (Aug 23 2013 07:45:42)
    Features compiled in: Vorbis FLAC MP3 RGB zLib MPEG2 Theora AAC FreeType2

    This error can still be triggered with todays git build and the attached savegame.

     
  • dronkit

    dronkit - 2013-08-24

    OK guys, I managed to win the game (cheating) by using the console to enter the hostel and retrieve the fuse. Then I knew it wasn't necessary. Whatever.
    The thing is I found out some stuff that might help you debug the script or whatever:

    in room 185 (landing site), object 452 is the door to the hostel (the outside of it)
    in room 181 (hostel airlock) and/or room 180 (hostel), object 463 is the airlock exit door ("door to mars"), ie, object 452's inner part. Object 472 in room 180/181 is the door from airlock to hostel. Another object referred to in the script is one of the lights. So the script piece fingolfin shows must have to do with the inner door automatically closing when you open the outer door or something like that.

    I see that in my save game that triggers the bug, the door looks closed from outside, also looks closed from inside when I cheat-enter the arlock. But the state of object 463 is 0 and the state of object 452 is 1. In theory the states should be the same cause they are the outer and inner counterparts of the same door (?).

    To find out what object is what I play the game, go to debug console with CTRL+D and use "objects" for a list and "object (number) name" to find out what it is. Also "object (number) state" to see it state and "object (number) state (number)" to change it