diff --git a/CHANGES b/CHANGES index 8aafdbee5..3159777c7 100644 --- a/CHANGES +++ b/CHANGES @@ -5,6 +5,7 @@ Emulation fixes: - GB Audio: Fix channels 1/2 staying muted if restarted after long silence - GB Audio: Fix channel 1 restarting if sweep applies after stop (fixes mgba.io/i/2965) - GB Audio: Fix restarting envelope when writing to register (fixes mgba.io/i/3067) + - GB Audio: Improve "zombie mode" emulation in CGB mode (fixes mgba.io/i/2029) - GB I/O: Read back proper SVBK value after writing 0 (fixes mgba.io/i/2921) - GB SIO: Disabling SIO should cancel pending transfers (fixes mgba.io/i/2537) - GBA Audio: Fix sample timing drifting when changing sample interval diff --git a/src/gb/audio.c b/src/gb/audio.c index 7fbd0d532..6f2535a65 100644 --- a/src/gb/audio.c +++ b/src/gb/audio.c @@ -881,12 +881,25 @@ void _writeDuty(struct GBAudioEnvelope* envelope, uint8_t value) { } bool _writeEnvelope(struct GBAudioEnvelope* envelope, uint8_t value, enum GBAudioStyle style) { + bool oldDirection = envelope->direction; envelope->stepTime = GBAudioRegisterSweepGetStepTime(value); envelope->direction = GBAudioRegisterSweepGetDirection(value); envelope->initialVolume = GBAudioRegisterSweepGetInitialVolume(value); - if (style == GB_AUDIO_DMG && !envelope->stepTime) { + if (!envelope->stepTime) { // TODO: Improve "zombie" mode - ++envelope->currentVolume; + if (style == GB_AUDIO_DMG) { + ++envelope->currentVolume; + } else if (style == GB_AUDIO_CGB) { + if (envelope->direction == oldDirection) { + if (envelope->direction) { + ++envelope->currentVolume; + } else { + envelope->currentVolume += 2; + } + } else { + envelope->currentVolume = 0; + } + } envelope->currentVolume &= 0xF; } _updateEnvelopeDead(envelope);