mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-04 08:17:40 +00:00
Added workaround in FMOPL for the pathological case where a note was turned off
while still at the very beginning of the "attack" phase. This is the very lowest point on the attack curve, yet it would continue from the beginning of the release curve, i.e. its very highest point. This is what caused Kyra to often play low-frequency notes at the very beginning of a new song. (That, and a truly bizarre function for initialising the channels.) The proper fix would be to locate the correct point on the release curve and continue from there. For now, though, only handle the trivial case. svn-id: r21302
This commit is contained in:
parent
59b6f0f715
commit
839b5d3e86
@ -808,18 +808,17 @@ void AdlibDriver::unkOutput2(uint8 chan) {
|
||||
// including the two most significant frequency bit, and the octave -
|
||||
// set to zero.
|
||||
//
|
||||
// This is very strange behaviour, and appears to be the cause of the
|
||||
// bug where low-frequent notes are played at the beginning of a new
|
||||
// sound. However, this is what the original does, and the bug does not
|
||||
// seem to happen with current versions of the FMOPL code.
|
||||
// This is very strange behaviour, and causes problems with the ancient
|
||||
// FMOPL code we borrowed from AdPlug. I've added a workaround. See
|
||||
// fmopl.cpp for more details.
|
||||
//
|
||||
// Unfortunately, we cannot use more recent versions because of license
|
||||
// incompatibilities.
|
||||
// More recent versions of the MAME FMOPL don't seem to have this
|
||||
// problem, but cannot currently be used because of licensing and
|
||||
// performance issues.
|
||||
//
|
||||
// Ken Silverman's Adlib emulator (which can be found on his Web page -
|
||||
// http://www.advsys.net/ken - and as part of AdPlug) also seems to be
|
||||
// proof against this particular bug, but is apparently not as feature
|
||||
// complete as MAME's.
|
||||
// immune, but is apparently not as feature complete as MAME's.
|
||||
|
||||
writeOPL(0xB0 + chan, 0x20);
|
||||
}
|
||||
|
@ -304,12 +304,41 @@ inline void OPL_KEYON(OPL_SLOT *SLOT) {
|
||||
inline void OPL_KEYOFF(OPL_SLOT *SLOT) {
|
||||
if( SLOT->evm > ENV_MOD_RR) {
|
||||
/* set envelope counter from envleope output */
|
||||
SLOT->evm = ENV_MOD_RR;
|
||||
if( !(SLOT->evc & EG_DST) )
|
||||
|
||||
// WORKAROUND: The Kyra engine does something very strange when
|
||||
// starting a new song. For each channel:
|
||||
//
|
||||
// * The release rate is set to "fastest".
|
||||
// * Any note is keyed off.
|
||||
// * A very low-frequency note is keyed on.
|
||||
//
|
||||
// Usually, what happens next is that the real notes is keyed
|
||||
// on immediately, in which case there's no problem.
|
||||
//
|
||||
// However, if the note is again keyed off (because the channel
|
||||
// begins on a rest rather than a note), the envelope counter
|
||||
// was moved from the very lowest point on the attack curve to
|
||||
// the very highest point on the release curve.
|
||||
//
|
||||
// Again, this might not be a problem, if the release rate is
|
||||
// still set to "fastest". But in many cases, it had already
|
||||
// been increased. And, possibly because of inaccuracies in the
|
||||
// envelope generator, that would cause the note to "fade out"
|
||||
// for quite a long time.
|
||||
//
|
||||
// What we really need is a way to find the correct starting
|
||||
// point for the envelope counter, and that may be what the
|
||||
// commented-out line below is meant to do. For now, simply
|
||||
// handle the pathological case.
|
||||
|
||||
if (SLOT->evm == ENV_MOD_AR && SLOT->evc == EG_AST)
|
||||
SLOT->evc = EG_DED;
|
||||
else if( !(SLOT->evc & EG_DST) )
|
||||
//SLOT->evc = (ENV_CURVE[SLOT->evc>>ENV_BITS]<<ENV_BITS) + EG_DST;
|
||||
SLOT->evc = EG_DST;
|
||||
SLOT->eve = EG_DED;
|
||||
SLOT->evs = SLOT->evsr;
|
||||
SLOT->evm = ENV_MOD_RR;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user