From d88da93a55bdd4e994eb9a21b8f72ee4f2091ba3 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Fri, 11 Oct 2019 16:54:21 +1000 Subject: [PATCH] SPU: Save state support --- src/common/audio_stream.cpp | 2 ++ src/core/spu.cpp | 33 ++++++++++++++++++++++++++++++++- src/core/system.cpp | 2 +- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/common/audio_stream.cpp b/src/common/audio_stream.cpp index 6dbe60f48..42d4619f3 100644 --- a/src/common/audio_stream.cpp +++ b/src/common/audio_stream.cpp @@ -204,6 +204,8 @@ void AudioStream::DropBuffer() void AudioStream::EmptyBuffers() { + std::unique_lock lock(m_buffer_mutex); + for (Buffer& buffer : m_buffers) { buffer.read_position = 0; diff --git a/src/core/spu.cpp b/src/core/spu.cpp index cad45910e..429198801 100644 --- a/src/core/spu.cpp +++ b/src/core/spu.cpp @@ -53,6 +53,37 @@ bool SPU::DoState(StateWrapper& sw) sw.Do(&m_SPUSTAT.bits); sw.Do(&m_transfer_address); sw.Do(&m_transfer_address_reg); + sw.Do(&m_irq_address); + sw.Do(&m_main_volume_left.bits); + sw.Do(&m_main_volume_right.bits); + sw.Do(&m_key_on_register); + sw.Do(&m_key_off_register); + sw.Do(&m_endx_register); + sw.Do(&m_reverb_on_register); + sw.Do(&m_ticks_carry); + for (u32 i = 0; i < NUM_VOICES; i++) + { + Voice& v = m_voices[i]; + sw.Do(&v.current_address); + sw.DoArray(v.regs.index, NUM_VOICE_REGISTERS); + sw.Do(&v.counter.bits); + sw.Do(&v.current_block_flags.bits); + sw.Do(&v.current_block_samples); + sw.Do(&v.previous_block_last_samples); + sw.Do(&v.adpcm_last_samples); + sw.Do(&v.adsr_phase); + sw.DoPOD(&v.adsr_target); + sw.Do(&v.adsr_ticks); + sw.Do(&v.adsr_ticks_remaining); + sw.Do(&v.adsr_step); + sw.Do(&v.has_samples); + } + + sw.DoBytes(m_ram.data(), RAM_SIZE); + + if (sw.IsReading()) + m_audio_stream->EmptyBuffers(); + return !sw.HasError(); } @@ -485,7 +516,7 @@ void SPU::Voice::SetADSRPhase(ADSRPhase phase) break; } - const s32 step = adsr_target.decreasing ? (-8 + adsr_target.step) : (7 - adsr_target.step); + const s16 step = adsr_target.decreasing ? (-8 + adsr_target.step) : (7 - adsr_target.step); adsr_ticks = 1 << std::max(0, adsr_target.shift - 11); adsr_ticks_remaining = adsr_ticks; adsr_step = step << std::max(0, 11 - adsr_target.shift); diff --git a/src/core/system.cpp b/src/core/system.cpp index 8e4605756..10072f5de 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -112,7 +112,7 @@ bool System::DoState(StateWrapper& sw) if (!sw.DoMarker("Timers") || !m_timers->DoState(sw)) return false; - if (!sw.DoMarker("SPU") || !m_timers->DoState(sw)) + if (!sw.DoMarker("SPU") || !m_spu->DoState(sw)) return false; if (!sw.DoMarker("MDEC") || !m_mdec->DoState(sw))