diff --git a/Source/Core/Core/DSP/DSPCore.cpp b/Source/Core/Core/DSP/DSPCore.cpp index 6cab6e48f5..84620d9ba0 100644 --- a/Source/Core/Core/DSP/DSPCore.cpp +++ b/Source/Core/Core/DSP/DSPCore.cpp @@ -44,38 +44,8 @@ bool init_hax = false; DSPEmitter *dspjit = nullptr; Common::Event step_event; -static bool LoadRom(const std::string& fname, int size_in_words, u16 *rom) -{ - File::IOFile pFile(fname, "rb"); - const size_t size_in_bytes = size_in_words * sizeof(u16); - if (pFile) - { - pFile.ReadArray(rom, size_in_words); - pFile.Close(); - - // Byteswap the rom. - for (int i = 0; i < size_in_words; i++) - rom[i] = Common::swap16(rom[i]); - - // Always keep ROMs write protected. - WriteProtectMemory(rom, size_in_bytes, false); - return true; - } - - PanicAlertT( - "Failed to load DSP ROM:\t%s\n" - "\n" - "This file is required to use DSP LLE.\n" - "It is not included with Dolphin as it contains copyrighted data.\n" - "Use DSPSpy to dump the file from your physical console.\n" - "\n" - "You may use the DSP HLE engine which does not require ROM dumps.\n" - "(Choose it from the \"Audio\" tab of the configuration dialog.)", fname.c_str()); - return false; -} - // Returns false if the hash fails and the user hits "Yes" -static bool VerifyRoms(const std::string& irom_filename, const std::string& coef_filename) +static bool VerifyRoms() { struct DspRomHashes { @@ -136,7 +106,7 @@ static void DSPCore_FreeMemoryPages() g_dsp.irom = g_dsp.iram = g_dsp.dram = g_dsp.coef = nullptr; } -bool DSPCore_Init(const std::string& irom_filename, const std::string& coef_filename, bool bUsingJIT) +bool DSPCore_Init(const DSPInitOptions& opts) { g_dsp.step_counter = 0; cyclesLeft = 0; @@ -148,14 +118,11 @@ bool DSPCore_Init(const std::string& irom_filename, const std::string& coef_file g_dsp.dram = (u16*)AllocateMemoryPages(DSP_DRAM_BYTE_SIZE); g_dsp.coef = (u16*)AllocateMemoryPages(DSP_COEF_BYTE_SIZE); - // Fill roms with zeros. - memset(g_dsp.irom, 0, DSP_IROM_BYTE_SIZE); - memset(g_dsp.coef, 0, DSP_COEF_BYTE_SIZE); + memcpy(g_dsp.irom, opts.irom_contents.data(), DSP_IROM_BYTE_SIZE); + memcpy(g_dsp.coef, opts.coef_contents.data(), DSP_COEF_BYTE_SIZE); // Try to load real ROM contents. - if (!LoadRom(irom_filename, DSP_IROM_SIZE, g_dsp.irom) || - !LoadRom(coef_filename, DSP_COEF_SIZE, g_dsp.coef) || - !VerifyRoms(irom_filename, coef_filename)) + if (!VerifyRoms()) { DSPCore_FreeMemoryPages(); return false; @@ -201,7 +168,7 @@ bool DSPCore_Init(const std::string& irom_filename, const std::string& coef_file WriteProtectMemory(g_dsp.iram, DSP_IRAM_BYTE_SIZE, false); // Initialize JIT, if necessary - if (bUsingJIT) + if (opts.core_type == DSPInitOptions::CORE_JIT) dspjit = new DSPEmitter(); core_state = DSPCORE_RUNNING; diff --git a/Source/Core/Core/DSP/DSPCore.h b/Source/Core/Core/DSP/DSPCore.h index 31b8830c2d..e7ae1ca89d 100644 --- a/Source/Core/Core/DSP/DSPCore.h +++ b/Source/Core/Core/DSP/DSPCore.h @@ -25,6 +25,7 @@ #pragma once +#include #include #include "Common/Thread.h" @@ -270,7 +271,31 @@ extern DSPEmitter *dspjit; extern u16 cyclesLeft; extern bool init_hax; -bool DSPCore_Init(const std::string& irom_filename, const std::string& coef_filename, bool bUsingJIT); +struct DSPInitOptions +{ + // DSP IROM blob, which is where the DSP boots from. Embedded into the DSP. + std::array irom_contents; + + // DSP DROM blob, which contains resampling coefficients. + std::array coef_contents; + + // Core used to emulate the DSP. + enum CoreType + { + CORE_INTERPRETER, + CORE_JIT, + }; + CoreType core_type; + + // Provide default option values. + DSPInitOptions() : core_type(CORE_JIT) + { + } +}; + +// Initializes the DSP emulator using the provided options. Takes ownership of +// all the pointers contained in the options structure. +bool DSPCore_Init(const DSPInitOptions& opts); void DSPCore_Reset(); void DSPCore_Shutdown(); // Frees all allocated memory. diff --git a/Source/Core/Core/HW/DSPLLE/DSPLLE.cpp b/Source/Core/Core/HW/DSPLLE/DSPLLE.cpp index 8ada666527..607958ecfa 100644 --- a/Source/Core/Core/HW/DSPLLE/DSPLLE.cpp +++ b/Source/Core/Core/HW/DSPLLE/DSPLLE.cpp @@ -108,11 +108,28 @@ void DSPLLE::dsp_thread(DSPLLE *dsp_lle) } } -bool DSPLLE::Initialize(void *hWnd, bool bWii, bool bDSPThread) +static bool LoadDSPRom(u16* rom, const std::string& filename, u32 size_in_bytes) { - m_bWii = bWii; - m_bDSPThread = bDSPThread; + std::string bytes; + if (!File::ReadFileToString(filename, bytes)) + return false; + if (bytes.size() != size_in_bytes) + { + ERROR_LOG(DSPLLE, "%s has a wrong size (%u, expected %u)", + filename.c_str(), (u32)bytes.size(), size_in_bytes); + return false; + } + + const u16* words = reinterpret_cast(bytes.c_str()); + for (u32 i = 0; i < size_in_bytes / 2; ++i) + rom[i] = Common::swap16(words[i]); + + return true; +} + +static bool FillDSPInitOptions(DSPInitOptions* opts) +{ std::string irom_file = File::GetUserPath(D_GCUSER_IDX) + DSP_IROM; std::string coef_file = File::GetUserPath(D_GCUSER_IDX) + DSP_COEF; @@ -121,8 +138,26 @@ bool DSPLLE::Initialize(void *hWnd, bool bWii, bool bDSPThread) if (!File::Exists(coef_file)) coef_file = File::GetSysDirectory() + GC_SYS_DIR DIR_SEP DSP_COEF; - bool use_jit = SConfig::GetInstance().m_DSPEnableJIT; - if (!DSPCore_Init(irom_file, coef_file, use_jit)) + if (!LoadDSPRom(opts->irom_contents.data(), irom_file, DSP_IROM_BYTE_SIZE)) + return false; + if (!LoadDSPRom(opts->coef_contents.data(), coef_file, DSP_COEF_BYTE_SIZE)) + return false; + + opts->core_type = SConfig::GetInstance().m_DSPEnableJIT ? + DSPInitOptions::CORE_JIT : DSPInitOptions::CORE_INTERPRETER; + + return true; +} + +bool DSPLLE::Initialize(void *hWnd, bool bWii, bool bDSPThread) +{ + m_bWii = bWii; + m_bDSPThread = bDSPThread; + + DSPInitOptions opts; + if (!FillDSPInitOptions(&opts)) + return false; + if (!DSPCore_Init(opts)) return false; g_dsp.cpu_ram = Memory::GetPointer(0);