Fixes KQ4 introduction not automatically ending
Thanks to @athrxx for locating the correct behavior in disassembly
Thanks to @eriktorbjorn for reporting this
This cleans up some things I noticed when I implemented the mute flag handling. It removes the hack that manually forces flag 2 on all channels with number 9, regardless of the device.
I presume the hack was done for the earliest SCI 1 games, due to improper handling of flag 1.
…once)
I am not sure if this bug ticket is about just one or about several bugs. This is at least something I could reproduce. The reason is that there can be channels that should start up muted. We didn't support that. I also fixed a couple of other things about the mute state that I noticed.
This mainly concerns restoring sounds after loading savefiles, but it should make the whole relationship between playing and paused sounds more accurate.
The test case which I was told about was KQ4, room 21, picking up the golden ball under the bridge, saving during playback of the pickup sound and then loading that savegame. It would result in hanging note due toe the sound being triggered multiple times by reconstructPlaylist() and updateSci0Cues(). Now, the sound should only start once.
I've changed the code to be more in line with disasm and tested some situations that sluicebox told me about or that I found in the comments (ICEMAN room 14, LSL3 start scene). I got rid of isQueued, since the original doesn't have that, it has caused some confusion and doesn't even get saved with the savegames.
I cleaned up updateSci0Cues(), so that it (together with processUpdateCues()) does a bit more what the original Midi timer proc does there. An exception is the sound fade out code in processUpdateCues(). It seems that we need that, as we don't have the fading code in the drivers like the original.
The original SCI0 code is actually much simpler than our code. It relies on a correctly sorted playlist (based on priority), but my impression is that we got that right, even if we do it slightly differently. I added a sortPlayList() to the sound init, since the original inserts the node at the right position, too.
When _mainThreadCalled is set the function call should be enqueued just like the Midi messages that get sent before the start of a new track, so that everything happens in the right order.
I put this in an separate commit to make it easier to review/revert. I've tried to make this as minimum invasive as possible. That's why I put this in place of the former call to onNewSound().
SCI_0_LATE sound drivers (probably also SCI_0_EARLY, but I don't know that) do some midi track initialization, mostly resetting certain values and assigning voices (hardware channels) to midi parts. The information for this comes from the track header.
The SCI0 version of the PC-98 sound driver relies on this code. The driver checks the channel flags with two different masks and assigns different sound channel types accordingly. This can't be done with the 0x4B event. Using the 0x4B event is sort of counter intuitive anyway, since only some of the SCI0 drivers even support that event.
It seems that the only driver making use of onNewSound() was MT-32. I've adapted the driver to my changes, although I am quite sure that the sound will be unaffected. The only thing that the MT-32 driver does with the header information is checking whether a midi part should play or not and assign exactly one timbre (with exactly the same number) to that part if required.
Set the default reverb configuration present in either the MT-32
patch data or MT32.DRV of SCI0 games before playing each sound, as
a previously played sound may have changed it.
Also, do not perform a general reverb init, since the start of a
sound will do that now.
Closes gh-1023.
Upon investigation of Sound code across SCI32 games, it was
determined that there are actually (at least) 3 different
revisions, not just a single SCI2.1 version. This patch only
changes the parts of Sound code that are relevant to the correct
use of Audio32.
Fixes Trac#9736, Trac#9756, Trac#9767, Trac#9791.
1. KQ4 sound 104 has an extra 0xFC (MIDI Stop command/kEndOfTrack)
at the end of the resource, which causes an out-of-bounds read
because the filtering loop continues after the first 0xFC and
unconditionally attempts to read 2 bytes (expecting there to
always be a delta value + a command, whereas in this file there
is only another kEndOfTrack command). This is corrected by
exiting the filtering loop when a kEndOfTrack is encountered
and there is not enough data remaining in the resource to
continue reading.
2. KQ5 sound 699 is truncated, which causes the parser to attempt
to read past the end of the resource. This is addressed by
adding bounds checks that exit the mix loop early if there is
no more data available to read. This allows truncated sounds
to be played as far as possible (previously, trying to read
truncated resources would result in a fatal error).
3. midiMixChannels allocates an arbitrary amount of raw memory
for the mixed MIDI sequence, without performing any bounds
checking when writing to this memory, potentially leading to
a crash or silent corruption of adjacent memory. This is
mitigated by using SciSpan instead of a raw pointer for the
mixed data.
Fixes Trac#9727.
The eventual proper fix for this is to change the current MIDI
parser to work the same as in SSCI, but for now this workaround
allows the game to continue.
Fixes Trac#9696.
- Detection works via signatures (couldn't find a better way)
- new kString subcalls were introduced SCI2.1 LATE
- kString now has signatures and is split via subcall table
- kString fix, so that KQ7 doesn't crash, when starting a chapter
- Sci2StringFunctionType removed, because no longer needed
This is only supported since SCI1 middle, as verified with xmas1990, SCI1 mgoose, SQ4 floppy, LSL1, Jones floppy.
Fixes missing sounds in Jones floppy.
add workaround for eq2
the issue is known, but can't be properly fixed without rewriting the midiparser into a channel specific parser
previous commit caused issues in kq5/french and others
we start at offset 10 for sound SCI1 games. This is hardcoded in the interpreter. Also removing not handling signals on tick 0. This fixes Eco Quest 2 / Gonzales dancing in room 530. Thanks to wjp for the help.
we set signal in parseNextEvent on dataInc events, which then effectively triggered 2 cues through kDoSoundUpdateCues instead of one. Fixes Freddy Pharkas Ballad intro on floppy + demos
We now do the jumpToTick() for hold events after waiting for the delta
of the current event, like we do for the signal set events. This keeps
the fixes for the hold timings in QFG3, while not breaking LSL6.
Many thanks to wjp for pinpointing the actual cause of the issue.
We now accept signals from all channels if channel 15 is missing. This
is a very rare edge case, but our behavior is now somewhat closer to what
the original interpreter seems to be doing. Mordack's appearance animation
is now synced properly. The more generic workaround works for songs 1840
and 1843, but not for 1849, which is still problematic and we still resort
to manually changing its dataInc selector