Opened 8 months ago

Closed 3 months ago

#15047 closed defect (fixed)

SCUMM: DIG: "Holding an object"-state gets cancelled by cutscene override

Reported by: mike-SpeedyAdventures Owned by: AndywinXp
Priority: normal Component: Engine: SCUMM
Version: Keywords:
Cc: Game: The Dig

Description

If you 'Use wire with panel' after opening the broken panel of the door that leads to the map spire and then press Esc to cutscene override, Low will drop the wire. You then have to pick it up again and make sure to not use cutscene override to be able to use it on the sparks.

Playing on DOSBox, the cutscene override does not make Low drop the wire and you can immediately proceed to use it with the sparks.

A very similar situation occurs when you try to combine the pole with the pin to build a giant mouse trap. If you use a cutscene override to skip the animation of Low picking up the pole, he will immediately drop it again. Does not occur when playing on DOSBox.

Played on ScummVM 2.9.0git (Mar 15 2024 08:55:38), but I've seen speedruns on ScummVM 2.0.0 where the same thing happens.

Attachments (1)

digsaves.zip (122.9 KB ) - added by mike-SpeedyAdventures 8 months ago.

Download all attachments as: .zip

Change History (7)

comment:1 by AndywinXp, 8 months ago

Hi! Thanks for your ticket! Do you have a savegame for both versions by any chance?

by mike-SpeedyAdventures, 8 months ago

Attachment: digsaves.zip added

in reply to:  1 comment:2 by mike-SpeedyAdventures, 8 months ago

Replying to AndywinXp:

Hi! Thanks for your ticket! Do you have a savegame for both versions by any chance?

Added as attachment

comment:3 by AndywinXp, 6 months ago

Not sure what's causing this. The scripts starting in room 23 (Nexus) as soon as the wire action is started are: 2020, 69 and 211. 2020 is the one setting the override, 69 is the global script handling turning (I think?), and I couldn't find 211.

Here is script 2020 (SCUMM syntax provided by nutcracker):

	script 2020 { ; LSCR LECF_0001\LFLF_0023\ROOM\LSCR_2020
		stop-script 2000
		stop-script 2001
		stop-script 129
		stop-script 130
		class-of 179 is 160
		state-of 211 is 0
		class-of 211 is 160
		cut-scene (2)
		override &[00000150]
		camera-pan-to 100
		wait-for-camera
		actor 3 \
			costume 71 \
			ignore-boxes \
			scale 255 \
			always-zclip 0

		actor 3 \
			talk-animation 4 5

		actor 3 \
			special-draw 1

		actor 3 \
			direction 180

		put-actor 3 at 477,0 in-room 23
		do-animation 3 9
		break-here 19 times
[00000150]:
		if !( s_selectedActor ) jump &[00000415]
		override off
		print-line \
			" "

		stop-script 131
		stop-script 132
		stop-script 133
		stop-script 134
		stop-script 135
		stop-script 136
		do-animation 3 255
		do-animation 3 3
		stop-script 32
		if ( class-of 5 is 136 ) {
			stop-script 143
			stop-script 144
			stop-script 145
			stop-script 146
			stop-script 147
			stop-script 148
			if ( (actor-room 5) == V.10 ) {
				do-animation 5 255
				do-animation 5 3
			}
			stop-script 34
		}
		if ( class-of 4 is 136 ) {
			stop-script 137
			stop-script 138
			stop-script 139
			stop-script 140
			stop-script 141
			stop-script 142
			if ( (actor-room 4) == V.10 ) {
				do-animation 4 255
				do-animation 4 3
			}
			stop-script 33
		}
		actor 3 \
			costume 71 \
			ignore-boxes \
			scale 255 \
			always-zclip 0

		actor 3 \
			talk-animation 4 5

		actor 3 \
			special-draw 1

		actor 3 \
			direction 180

		put-actor 3 at 477,0 in-room 23
		camera-at 100
		jump &[00000416]
[00000415]:
		override off
[00000416]:
		do-animation 3 7
		end-cut-scene
		start-script 18 ( 153 )
		start-script 73 ( 153 )
		say-line 3 "/NEXUS.117/Now I've got the free end of the wire."
		class-of 179 is 160
		V.233 = 2004
		wait-for-message
		end-script
	}

And here is one thing we are currently missing from the override functions from the disasm, but which doesn't seem to fix anything:

void ScummEngine::beginOverride() {
        const int idx = vm.cutSceneStackPointer;
        assert(0 <= idx && idx < kMaxCutsceneNum);

+       if (_game.version >= 5 && !vm.cutScenePtr[idx]) {
+               ++vm.slot[_currentScript].cutsceneOverride;
+       }

        vm.cutScenePtr[idx] = _scriptPointer - _scriptOrgPointer;
        vm.cutSceneScript[idx] = _currentScript;

        // Skip the jump instruction following the override instruction
        // (the jump is responsible for "skipping" cutscenes, and the reason
        // why we record the current script position in vm.cutScenePtr).
        fetchScriptByte();
        fetchScriptWord();

        if (_game.version >= 5)
                VAR(VAR_OVERRIDE) = 0;
}

void ScummEngine::endOverride() {
        const int idx = vm.cutSceneStackPointer;
        assert(0 <= idx && idx < kMaxCutsceneNum);

+       if (_game.version >= 5 && vm.cutScenePtr[idx]) {
+               --vm.slot[_currentScript].cutsceneOverride;
+       }

        vm.cutScenePtr[idx] = 0;
        vm.cutSceneScript[idx] = 0;

        if (_game.version >= 4)
                VAR(VAR_OVERRIDE) = 0;
}

Not sure if I'll continue tackling this for the time being, hence my research being available above for whoever needs it.

Last edited 6 months ago by AndywinXp (previous) (diff)

comment:4 by eriktorbjorn, 3 months ago

Maybe it isn't related to the cutscene handling? If I want for the animation to finish (leaving Boston holding the wire), then press any key or click the mouse, he puts it down on the ground. So maybe Esc both ends the cutscene, and is handled as a keypress afterwards?

At any rate, it does call runInputScript().

(In DOSBox, pressing Esc after the animation has finished also puts down the rope.)

comment:5 by eriktorbjorn, 3 months ago

This seems to fix the problem for me. I have no idea if it's the correct way of doing it, though:

diff --git a/engines/scumm/input.cpp b/engines/scumm/input.cpp
index 6aeb9dc3a0f..b408aad3c79 100644
--- a/engines/scumm/input.cpp
+++ b/engines/scumm/input.cpp
@@ -589,8 +589,8 @@ void ScummEngine_v7::processKeyboard(Common::KeyState lastKeyHit) {
                        abortCutscene();
                }
 
-               _mouseAndKeyboardStat = Common::ASCII_ESCAPE;
-
+               if (!VAR(VAR_OVERRIDE))
+                       _mouseAndKeyboardStat = Common::ASCII_ESCAPE;
        } else {
                // Fall back to V6 behavior
                ScummEngine_v6::processKeyboard(lastKeyHit);

comment:6 by AndywinXp, 3 months ago

Owner: set to AndywinXp
Resolution: fixed
Status: newclosed

In 27e6b811:

SCUMM: DIG: Fix #15047

This fixes and closes #15047:
"SCUMM: DIG: "Holding an object"-state gets cancelled by cutscene override"

Once again this is one of those cases in which v7-v8 shuffled
elements around the main loop.

Fixing this also forced me to remove an hack for v7 which attempted
to fix timing for e.g. the screen shake + breakHere() combination.
This is also properly fixed now.

Note: See TracTickets for help on using tickets.