When selecting a new menu while another menu open, the new menu
will be drawn before inverting the old item selection. In the
next loop iteration, when the inversion happens, it now inverts
the brand new white item.
(cherry picked from commit f7c44a452953415c3ba4dbdf96162f83efde8f51)
This adds support for the Casio MIDI devices originally supported by several
SCI0 games:
- Space Quest III
- Hoyle's Book Of Games I
- Quest For Glory I
- Leisure Suit Larry III
- The Colonel's Bequest
- Codename: Iceman
- Conquests Of Camelot
This code attempted to skip calling the function that finds script 0's
export block, but this never happened because it tests the wrong offset.
Even if it tested the right offset, it would have just been duplicating
what the function does.
This restores kGetEvent throttling (10ms delay) during inner loops that
don't throttle themselves. For example, the event processing loop in
Dialog:doit doesn't include a kWait(1) call in some games.
In these games, dialogs max out CPU, and if they run animations then
they run too fast. This happens in the CD version of JONES, bug #14020.
I had considered doing something like this earlier, but it wasn't clear
how to best detect these loops. What I didn't realize is that the SCI32
code already does this by counting kGetEvent calls in between kFrameout.
Now that technique is adapted for SCI16. Combined with the existing
"fast cast" detection, this throttles event-polling inner loops while
keeping the kGetEvent and kGameIsRestarting throttling separate so that
they don't overlap and conflict.
See: e09010f7d8b7cc30ae3c8477d1a8b61b24d96306
SCI's fallback detection didn't populate ADDetectedGame::matchedFiles.
Now it does, and the Unknown Game report that it generates includes all
the relevant files.
These files were mistaken as a pirate release, but they're just the
output of the popular "GK2 HD/DVD Installer" fan tool when used on
GK2 German. Anyone can produce these files from original files.
They are not the "GOG.com version with German data", GOG just used
the same tool to produce their version from GK2 English files.
These rooms disabled the control panel to prevent the player from
accessing the game's speed setting. Ego is set to a fixed speed and
the timing of the room scripts depend on that speed.
See: 11ca903f606e0b5d155652e9b8c80f3a4d0ddbec
This heuristic was originally how all SCI16 speed tests were handled.
It has been gradually replaced with script patches, until all games
were patched in: ea48986006a1d85b5302f0c3d2ac828e29a66813
At the time, I left this in because it had the benefit of speeding up
the SCI11 test variants so that they didn't produce a startup delay.
Now we know that this heuristic has been identifying regular rooms as
speed tests and unthrottling them too, causing unintended effects.
Some of this behavior was masked by fast-cast throttling occurring
everywhere, until: e09010f7d8b7cc30ae3c8477d1a8b61b24d96306
For example, the QFG1VGA Sierra logo animation changes speed and runs
very fast as soon as the sparkle is finished. The Longbow map rooms
were also detected as speed test rooms and animated too fast. Cast-less
rooms like LB2's title screen run unthrottled and consume CPU.
There are only a few SCI11 speed test rooms, so now they're explicitly
unthrottled in kGameIsRestarting with the other throttling exceptions.
Speed throttling was disabled on LONGBOW maps because they were treated
as speed tests by the heuristic in GfxAnimate::throttleSpeed. This bug
was masked by fast-cast throttling being applied everywhere, but that
was changed in e09010f7d8b7cc30ae3c8477d1a8b61b24d96306
Now the map rooms trigger throttling so that they don't run too fast.
But the game scripts also attempt to throttle the animations based on
speed test results, causing them to run too slow, so that's patched out.
Fixes bug #13966
The VM has been treating the entire area between the frame pointer and
the stack pointer as temp variables for the current function. There are
two problems with this:
1. The VM hasn't been updating the frame pointer correctly when multiple
methods are called within the same send/self/super instruction.
2. The VM has been recalculating the number of temp variables on every
instruction as the difference between the two pointers.
This is incorrect, as this changes with almost every instruction in
ways have nothing to do with the number of temp variables allocated
by the link instruction. Meanwhile, the VM has not been recording
the number of variables allocated by the link instruction.
The first discrepancy caused scripts to behave differently than in SSCI
when reading parameters out of bounds in certain situations.
It also prevented our uninitialized variable detection from detecting
certain reads. The second made the temp-count used for out of bounds
detection too large, made debugger output such as `stack` incorrect,
and made stepping through the link instruction in the debugger appear
to do nothing until stepping through the following instruction.
When multiple methods are called by a send/self/super instruction, each
method's link instruction increases the stack pointer further.
Method B's variables appear after method A's. The VM has been setting
the stack pointer correctly but it kept using the previous frame
pointer, so method B would re-use method A's stack area instead of the
area the VM had just allocated for B. If a script correctly initializes
variables before using them and doesn't use out of bounds parameters or
temp variables then this discrepancy doesn't make a difference.
But a lot of scripts do these bad things and accidentally rely on the
undefined values they read.
Now we update the frame pointer correctly when "carrying over" to
subsequent method calls from the same send/self/super instruction.
This matches SSCI behavior. We also now record the number of temp
variables that have been allocated by the link instruction and use
that instead of incorrectly recalculating on every instruction.
Fixes the KQ6 black widow lockup, and other KQ6 music bugs, where
scripts call Sound:fade without the required fourth parameter.
Sound:fade expects a fourth parameter, so reads it out of bounds,
and passes it as the stop-after-completion boolean to kDoSoundFade.
Scripts that called Sound:fade as the only method in a send got the same
results as in SSCI, but scripts that called Sound:play first didn't.
Fixes bugs #5625#5653#6120#6210#6252#13944
Recent fixes to the sound fading code have exposed this bug again.
It was first fixed 12 years ago, and then again 10 years ago.
Both times, the bug was fixed by changing kDoSoundFade behavior.
But those changes added behavior that was different from SSCI, and
those differences caused problems in LB2. kDoSoundFade is now
accurate, and so the bug has returned, but it was never a sound bug.
The black widow lockup is due to a script bug that accidentally relies
on undefined values from non-existent parameters. ScummVM produces
different undefined values than SSCI in certain situations, and this
is one of them. The undefined values are then passed to kDoSoundFade
as real values in a correct kernel call.
Now this is fixed with a script patch that removes all five broken
Sound:fade calls. They were redundant because they attempted to fade in
to the same volume they had just set.
Perhaps we can replicate SSCI's undefined behavior someday, but in
the meantime this bug is fixed.
Fixes bugs #5625#5653#6120#6210#6252#13944