When ripping the audio tracks from CD, you may not get quite what the
game expects, e.g. my copy of Loom has less silence at the start of the
track than the CDDA.SOU file from the Steam version. And the MI1 intro
appears to be timed with the assumption that there is no silence at all
at the start of that track.
This makes it possible to compensate for that without having to edit the
audio file. It may also be of some help with fan soundtrack replacements
for MI1, though I have little experience with that.
Now that VAR_TIMER_TOTAL is reliable, use that for timing the Loom
replacement audio tracks instead. This saves us the bother of handling
pausing and things like that.
I think it should work even with older savegames, but at the moment
resuming the track from where it was saved isn't working for me. It
seems to be doing the right ting, but then the track gets restarted.
This may be because of recent changes to Loom save/restore?
LucasArts released (at least) an official Japanese version with Japanese
text and English voices; plus, there are some fan-made translations made
for the original English Talkie version. They appear to use the same
MONSTER.SOU (or INDY4.SOU) file.
So, instead of only applying the Trac#10559 workaround to Common::EN_ANY
releases, accept any (talkie) version, as long as we can find the broken
VOC header at that offset.
Don't try to update the _musicTimer in saveLoadWithSerializer(), because
we haven't yet loaded all of the savegame. Instead, do that in a new
restoreAfterLoad() method.
As an extra bonus, if an audio track was playing when the game was
saved, try to resume it from approximately that point.
Unfortunately, it turns out that _currentCDSound was not properly reset
when the song ended so loading a savegame made with an earlier version
of this feature may cause it to play music that it shouldn't. But that's
the kind of thing you should count on on the bleeding edge. Savegames
made after this change should be fine.
Before, the music timer was based on the number of SCUMM ticks that had
passed since the track started. But this meant that the timing could
differ by several seconds depending on your hardware.
Now it's instead based on the amount of time that has passed since the
replacement track started playing. Time that passes while the game is
paused does not count. Of course, if the player suspends the process that
time still counts. But the player was clearly asking for it then!
Would it be better to tie it to the current position in the audio track?
Possibly, but the CD audio manager doesn't provide that information.
Even if it did, the timer has to run even if the track ends prematurely,
because we can't just assume that every available recording has the
expected length.
But at least, we now have a well defined unit of measurement: We
hard-code the point in time where the Overture transition should happen
with the Ozawa recording. Ten ticks on the settings slider moves this
point by one second, allowing the user to adjust it by 20 seconds in
each direction. Surely that should be enough?
It's hard to make this appear only on EGA Loom, so the tooltip has to
document the fact that it's only useful there. The setting is made
relative to the default tempo, which I feel is a much more sensible way
of presenting it to the user than the raw ticks value.
I can only conclude that SCUMM ticks aren't accurate enough to match the
original timer, but at least the transition now happens almost at the
same point as with the MT-32 version, when using the Ozawa version of
the music. Maybe this should be configurable, to accommodate for
different recordings?
I mistakenly thought they should be looped, but after testing (both with
ScummVM and DOSBox) I have come to the conclusion that they should not.
The music ends whenever there is a sound effect anyway, so having the
music play to the end of the track is the exception, not the rule.
In the FM Towns version, music does play continuously. Personally I find
this makes the game much harder, since the music can drown out the sound
effects.
Also tweaked the expected length of the Overture so that it syncs up
nicely with Act II: No. 10 Scène (Moderato) from the Seiji Ozawa
recording. It was apparently used as tempo reference for the Loom
soundtrack, though I don't know if this was the actual track used for
the Overture since No. 14 is almost identical.
The way the code is written, it should still work fine even if the track
is longer or shorter than expected. And, let's face it, most players
will probably skip the Overture once they've heard it a few times.
This track is a bit harder to isolate from the ballet recording, since
it's in the middle of a piece of music. But since all enhanced tracks
are optional, that's not really a problem.
For the Loom Overture to end, the music timer has to reach at least 278.
Keep the music timer updated for as long as there is a current CD sound,
even if the track itself has ended. If the track ends very early during
the Overture, skip ahead to the scene change. There will be several
seconds of silence, but this seems unlikely to ever happen to begin
with.
This is currently hard-coded for the Loom Overture, and counts the
number of SCUMM ticks that have passed since the song started. Perhaps
it would make more sence to query the CD position, but our CD audio
manager doesn't support that at the time of writing.
This allows EGA Loom and Mac Loom to use replacement audio tracks, e.g.
from the FM Towns or TurboGrafx-16 versions or, with a bit work, any
recording of the original ballet.
Currently the Ouverture doesn't work, since it relies on the music
timer being updated.
If the game is a talkie version, on which the verbs reference sounds, but
it is missing the sound file, and the user chose Voice Only, a warning
appears for every playback attempt.
Force subtitles on this case, to avoid these warnings.
Fixes trac 13151
I have checked the behavior of original INDY4 and also DOTT (since it is a later SCUMM version). Both games do actually suppress the whole dialogue line when pressing '.', even when it is a multi part line (containing one or more '3' command codes). So we don't have a bug here. But this applies to speech enabled setting only. In text only mode the original allows to step through the dialogue line by line (and also through the message parts separated by the '3' command). I have fixed this from disasm so that it matches the original behavior. I've also confirmed for SAMNMAX from disasm (not extensively, just checked whether it has the voicemode == 2 check at the beginning of startTalkSound()).
This warning will not only show up if a tag is actually unrecognized but also in cases where the tag is recognized, but the resource size is 0. This happens quite a lot in the Amiga version of MI2 with 'SOU ' tags.
The speech sample at VCTL offset 0x76ccbca ("Hey you!") which is used
when Indy gets caught on the German submarine seems to not be a VOC
but raw PCM s16be at (this is a guess) 44.1 kHz with a bogus VOC header.
To work around this we skip the VOC header and decode the raw PCM data.
Fixes Trac#10559
This commit introduces the following (seemingly non-invasive) changes
to make the 'imuse play' debugger command more useful (i.e. don't crash
when trying to load the wrong kind of (sound) resource.
* ScummEngine::readSoundResource()
Instead of fatally error()'ing upon hitting a non-sound resource type,
e.g. a room header (0x524d4844 aka RMHD), we now only issue a warning().
This enables the already existing dead code which properly returns 0
(aka no resource loaded).
* ResourceManager::validateResource()
Instead of fatally error()'ing upon hitting an illegal glob type we now
only issue a warning() and return false (also existing dead code).
All methods calling validateResource() check its return value so this
seems like the right thing to do anyway.
* ScummDebugger::Cmd_IMuse()
Instead of directly calling ensureResourceLoaded() we now call
getResourceAddress() instead (which in turn calls ensureResourceLoaded()
and handles other edge cases) and only attempt to play a sound if the
returned pointer actually is valid.
Fixes Trac#10527.
It looks like the code was there, but it was never fully implemented
because _curSoundPos was never being incremented. Experimentally,
it looks like it works if it is a 60FPS counter.