The first track in the LotT introduction fades out before the second track
starts. The fade-out is implemented by reducing the velocity of the new notes
that are being played. Because this does not affect notes that are already
playing, the fade-out effect is not very good. I've replaced this by a fade-out
using MIDI channel volume.
The animation that plays when you fall through the sewage chute near the start
of the game had some issues. Fades were missing at several points, the middle
part of the animation was played only once and too slow, and when skipping the
animation it would only skip the currently playing part instead of the entire
animation.
To fix these issues, I've added an option to AnimationSequence to loop the
animation a number of times.
When pausing the game by bringing up the ScummVM menu, the MIDI notes would
hang. I've added code to pause and resume the active MIDI parsers, which stops
the active notes.
This change adds the MT-32/GM multisource MidiDriver to LotT. This adds the
following functionality:
- MT-32 initialization using the SysEx queue. ScummVM will remain responsive
while the SysExes are sent and the user can abort the process when skipping the
introduction or quitting the game.
- Use of Roland GS MT-32 instrument mapping.
It also allows for a proper implementation of music fade-outs. Some
functionality previously implemented in SoundManager is now done by the driver.
Some sound effects in LotT loop, like the thunderstorm in the beginning of the
game. This is indicated by the high bit of the sound number. This change adds
support for these looping sound effects.
Lure of the Temptress defines a volume level for each sound resource. This is a
byte value which can increase or decrease the volume of the sound as specified
in the MIDI data (80h is the neutral value). The original interpreter applies
this as a scaling factor to the Note On velocity for the MT-32. ScummVM used it
to scale the MIDI volume control change values instead, causing incorrect
volume levels.
This change applies the sound resource volume to note velocity instead, which
results in the same volume as the original interpreter. I've left the old
method in place for AdLib, because I'm not sure how the original interpeter
handles sound resource volume in this case.
Distinction between music and SFX was made based on the most significant bit in
the sound number byte. This does not accurately reflect which MIDI sequences
are music or a sound effect.
Instead, I've added a flag which can be passed to
SoundManager::musicInterface_Play to indicate whether the sound is music or a
sound effect. All music is started from hard-coded animation sequences, so this
flag can be passed from ScummVM code when appropriate.
The regression affected AGOS and maybe some others; specifically,
the real MidiDriver would have been deleted twice -- I previously
missed that the Engine instances takes care of freeing the real
MidiDriver, not the MidiPlayer wrapping it.
This commit should clarify the ownership of the real MidiDriver for
most pseudo MidiDrivers.
Many engines follow the advice in audio/midiparser.h and create a
"pseudo-MidiDriver" subclass. But MidiParser really only needs a tiny
subset of the MidiDriver capabilities, namely those found in
MidiDriver_BASE. So we try to subclass from that whenever possible; this
allows us to remove many stub methods, and enables further future
simplifications.
This in turn enables modifying MidiDriver_MPU401::close() to allow
it to be called on a midi driver that has not yet been opened.
The specific issue that triggered me to make these changes was a
crash-upon-quit in HUGO, caused by it instantiating a midi driver,
then encountering an error (missing hugo.dat) *before* having
opened the new midi driver; the general cleanup code then tries
to close the (not yet opened) midi driver -> kaboom
Also fixed some engines which were leaking MidiDriver instances.
two different classes, use the value in SoundManager instead. As a consequence
the engine now remaps the instruments from MT-32 to General MIDI for me, since
isRoland() is true and hasNativeMT32() is false. Earlier, it didn't since the
uninitialised _nativeMT32 happened to be true for me.
svn-id: r29878