diff --git a/Source/Core/Core/HW/DSPHLE/DSPHLE.cpp b/Source/Core/Core/HW/DSPHLE/DSPHLE.cpp index 34e7394727..10ab940314 100644 --- a/Source/Core/Core/HW/DSPHLE/DSPHLE.cpp +++ b/Source/Core/Core/HW/DSPHLE/DSPHLE.cpp @@ -21,10 +21,10 @@ bool DSPHLE::Initialize(bool wii, bool dsp_thread) m_wii = wii; m_ucode = nullptr; m_last_ucode = nullptr; - m_halt = false; - m_assert_interrupt = false; SetUCode(UCODE_ROM); + + m_dsp_control.Hex = 0; m_dsp_control.DSPHalt = 1; m_dsp_control.DSPInit = 1; diff --git a/Source/Core/Core/HW/DSPHLE/DSPHLE.h b/Source/Core/Core/HW/DSPHLE/DSPHLE.h index c10c8ca901..af684655d9 100644 --- a/Source/Core/Core/HW/DSPHLE/DSPHLE.h +++ b/Source/Core/Core/HW/DSPHLE/DSPHLE.h @@ -66,8 +66,5 @@ private: DSP::UDSPControl m_dsp_control; CMailHandler m_mail_handler; - - bool m_halt; - bool m_assert_interrupt; }; } // namespace DSP::HLE diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp b/Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp index 942ded787b..d9619a0408 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp +++ b/Source/Core/Core/HW/DSPHLE/UCodes/AX.cpp @@ -5,14 +5,17 @@ #include #include +#include #include #include "Common/ChunkFile.h" #include "Common/CommonTypes.h" #include "Common/FileUtil.h" +#include "Common/Hash.h" #include "Common/IOFile.h" #include "Common/Logging/Log.h" #include "Common/Swap.h" +#include "Core/Core.h" #include "Core/DolphinAnalytics.h" #include "Core/HW/DSP.h" #include "Core/HW/DSPHLE/DSPHLE.h" @@ -24,8 +27,7 @@ namespace DSP::HLE { -AXUCode::AXUCode(DSPHLE* dsphle, u32 crc) - : UCodeInterface(dsphle, crc), m_cmdlist_size(0), m_compressor_pos(0) +AXUCode::AXUCode(DSPHLE* dsphle, u32 crc) : UCodeInterface(dsphle, crc) { INFO_LOG_FMT(DSPHLE, "Instantiating AXUCode: crc={:08x}", crc); } @@ -39,41 +41,44 @@ void AXUCode::Initialize() { m_mail_handler.PushMail(DSP_INIT, true); - LoadResamplingCoefficients(); + LoadResamplingCoefficients(false, 0); } -void AXUCode::LoadResamplingCoefficients() +bool AXUCode::LoadResamplingCoefficients(bool require_same_checksum, u32 desired_checksum) { - m_coeffs_available = false; + constexpr size_t raw_coeffs_size = 0x800 * 2; + m_coeffs_checksum = std::nullopt; const std::array filenames{ File::GetUserPath(D_GCUSER_IDX) + "dsp_coef.bin", File::GetSysDirectory() + "/GC/dsp_coef.bin", }; - size_t fidx; - std::string filename; - for (fidx = 0; fidx < filenames.size(); ++fidx) + for (const std::string& filename : filenames) { - filename = filenames[fidx]; - if (File::GetSize(filename) != 0x1000) + INFO_LOG_FMT(DSPHLE, "Checking for polyphase resampling coeffs at {}", filename); + + if (File::GetSize(filename) != raw_coeffs_size) continue; - break; + File::IOFile fp(filename, "rb"); + std::array raw_coeffs; + fp.ReadBytes(raw_coeffs.data(), raw_coeffs_size); + + u32 checksum = Common::HashAdler32(raw_coeffs.data(), raw_coeffs_size); + if (require_same_checksum && checksum != desired_checksum) + continue; + + std::memcpy(m_coeffs.data(), raw_coeffs.data(), raw_coeffs_size); + for (auto& coef : m_coeffs) + coef = Common::swap16(coef); + + INFO_LOG_FMT(DSPHLE, "Using polyphase resampling coeffs from {}", filename); + m_coeffs_checksum = checksum; + return true; } - if (fidx >= filenames.size()) - return; - - INFO_LOG_FMT(DSPHLE, "Loading polyphase resampling coeffs from {}", filename); - - File::IOFile fp(filename, "rb"); - fp.ReadBytes(m_coeffs, 0x1000); - - for (auto& coef : m_coeffs) - coef = Common::swap16(coef); - - m_coeffs_available = true; + return false; } void AXUCode::SignalWorkEnd() @@ -433,7 +438,7 @@ void AXUCode::ProcessPBList(u32 pb_addr) ApplyUpdatesForMs(curr_ms, pb, pb.updates.num_updates, updates); ProcessVoice(pb, buffers, spms, ConvertMixerControl(pb.mixer_control), - m_coeffs_available ? m_coeffs : nullptr); + m_coeffs_checksum ? m_coeffs.data() : nullptr); // Forward the buffers for (auto& ptr : buffers.ptrs) @@ -750,6 +755,22 @@ void AXUCode::DoAXState(PointerWrap& p) p.Do(m_samples_auxB_right); p.Do(m_samples_auxB_surround); + auto old_checksum = m_coeffs_checksum; + p.Do(m_coeffs_checksum); + + if (p.GetMode() == PointerWrap::MODE_READ && m_coeffs_checksum && + old_checksum != m_coeffs_checksum) + { + if (!LoadResamplingCoefficients(true, *m_coeffs_checksum)) + { + Core::DisplayMessage("Could not find the DSP polyphase resampling coefficients used by the " + "savestate. Aborting load state.", + 3000); + p.SetMode(PointerWrap::MODE_VERIFY); + return; + } + } + p.Do(m_compressor_pos); } diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/AX.h b/Source/Core/Core/HW/DSPHLE/UCodes/AX.h index dea125d78c..d0f73a6c2e 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/AX.h +++ b/Source/Core/Core/HW/DSPHLE/UCodes/AX.h @@ -11,6 +11,9 @@ #pragma once +#include +#include + #include "Common/BitUtils.h" #include "Common/CommonTypes.h" #include "Common/Swap.h" @@ -90,17 +93,17 @@ protected: int m_samples_auxB_surround[32 * 5]; u16 m_cmdlist[512]; - u32 m_cmdlist_size; + u32 m_cmdlist_size = 0; // Table of coefficients for polyphase sample rate conversion. // The coefficients aren't always available (they are part of the DSP DROM) // so we also need to know if they are valid or not. - bool m_coeffs_available; - s16 m_coeffs[0x800]; + std::optional m_coeffs_checksum = std::nullopt; + std::array m_coeffs; - u16 m_compressor_pos; + u16 m_compressor_pos = 0; - void LoadResamplingCoefficients(); + bool LoadResamplingCoefficients(bool require_same_checksum, u32 desired_checksum); // Copy a command list from memory to our temp buffer void CopyCmdList(u32 addr, u16 size); diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/AXWii.cpp b/Source/Core/Core/HW/DSPHLE/UCodes/AXWii.cpp index f5839a055a..a960f5c6c7 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/AXWii.cpp +++ b/Source/Core/Core/HW/DSPHLE/UCodes/AXWii.cpp @@ -472,7 +472,7 @@ void AXWiiUCode::ProcessPBList(u32 pb_addr) { ApplyUpdatesForMs(curr_ms, pb, num_updates, updates); ProcessVoice(pb, buffers, spms, ConvertMixerControl(HILO_TO_32(pb.mixer_control)), - m_coeffs_available ? m_coeffs : nullptr); + m_coeffs_checksum ? m_coeffs.data() : nullptr); // Forward the buffers for (auto& ptr : buffers.ptrs) @@ -483,7 +483,7 @@ void AXWiiUCode::ProcessPBList(u32 pb_addr) else { ProcessVoice(pb, buffers, 96, ConvertMixerControl(HILO_TO_32(pb.mixer_control)), - m_coeffs_available ? m_coeffs : nullptr); + m_coeffs_checksum ? m_coeffs.data() : nullptr); } WritePB(pb_addr, pb, m_crc); diff --git a/Source/Core/Core/State.cpp b/Source/Core/Core/State.cpp index a9cf8694e9..3b59b18907 100644 --- a/Source/Core/Core/State.cpp +++ b/Source/Core/Core/State.cpp @@ -73,7 +73,7 @@ static Common::Event g_compressAndDumpStateSyncEvent; static std::thread g_save_thread; // Don't forget to increase this after doing changes on the savestate system -constexpr u32 STATE_VERSION = 135; // Last changed in PR 9976 +constexpr u32 STATE_VERSION = 136; // Last changed in PR 10058 // Maps savestate versions to Dolphin versions. // Versions after 42 don't need to be added to this list,