From f23bcc0faa812c7067147578ca223d24ec93fd0f Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Fri, 27 Mar 2020 01:42:59 +1000 Subject: [PATCH] SPU: Ignore loop start flag when repeat address is explicitly set Fixes dialog/softlock in Thousand Arms. --- src/core/save_state_version.h | 2 +- src/core/spu.cpp | 5 ++++- src/core/spu.h | 1 + 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/core/save_state_version.h b/src/core/save_state_version.h index d8a8f13ba..f45826c4a 100644 --- a/src/core/save_state_version.h +++ b/src/core/save_state_version.h @@ -2,4 +2,4 @@ #include "types.h" static constexpr u32 SAVE_STATE_MAGIC = 0x43435544; -static constexpr u32 SAVE_STATE_VERSION = 14; +static constexpr u32 SAVE_STATE_VERSION = 15; diff --git a/src/core/spu.cpp b/src/core/spu.cpp index 7dfd67120..6682d5541 100644 --- a/src/core/spu.cpp +++ b/src/core/spu.cpp @@ -130,6 +130,7 @@ bool SPU::DoState(StateWrapper& sw) sw.Do(&v.adsr_phase); sw.Do(&v.adsr_target); sw.Do(&v.has_samples); + sw.Do(&v.ignore_loop_address); } sw.DoBytes(m_ram.data(), RAM_SIZE); @@ -584,6 +585,7 @@ void SPU::WriteVoiceRegister(u32 offset, u16 value) { Log_DebugPrintf("SPU voice %u ADPCM repeat address <- 0x%04X", voice_index, value); voice.regs.adpcm_repeat_address = value; + voice.ignore_loop_address = true; } break; @@ -873,6 +875,7 @@ void SPU::Voice::KeyOn() current_address = regs.adpcm_start_address; regs.adsr_volume = 0; has_samples = false; + ignore_loop_address = false; SetADSRPhase(ADSRPhase::Attack); } @@ -1238,7 +1241,7 @@ std::tuple SPU::SampleVoice(u32 voice_index) voice.DecodeBlock(block); voice.has_samples = true; - if (voice.current_block_flags.loop_start) + if (voice.current_block_flags.loop_start && !voice.ignore_loop_address) { Log_TracePrintf("Voice %u loop start @ 0x%08X", voice_index, ZeroExtend32(voice.current_address)); voice.regs.adpcm_repeat_address = voice.current_address; diff --git a/src/core/spu.h b/src/core/spu.h index b947d59ce..3bdc56b5c 100644 --- a/src/core/spu.h +++ b/src/core/spu.h @@ -262,6 +262,7 @@ private: ADSRPhase adsr_phase; s16 adsr_target; bool has_samples; + bool ignore_loop_address; bool IsOn() const { return adsr_phase != ADSRPhase::Off; }