diff --git a/Source/Core/Core/Src/HW/DSPHLE/DSPHLE.cpp b/Source/Core/Core/Src/HW/DSPHLE/DSPHLE.cpp index 069bbedc63..65362a19a0 100644 --- a/Source/Core/Core/Src/HW/DSPHLE/DSPHLE.cpp +++ b/Source/Core/Core/Src/HW/DSPHLE/DSPHLE.cpp @@ -131,7 +131,51 @@ void DSPHLE::SwapUCode(u32 _crc) void DSPHLE::DoState(PointerWrap &p) { p.Do(m_InitMixer); - GetUCode()->DoState(p); + p.Do(m_DSPControl); + p.Do(m_dspState); + + int ucode_crc = IUCode::GetCRC(m_pUCode); + int ucode_crc_beforeLoad = ucode_crc; + int lastucode_crc = IUCode::GetCRC(m_lastUCode); + int lastucode_crc_beforeLoad = lastucode_crc; + + p.Do(ucode_crc); + p.Do(lastucode_crc); + + // if a different type of ucode was being used when the savestate was created, + // we have to reconstruct the old type of ucode so that we have a valid thing to call DoState on. + IUCode* ucode = (ucode_crc == ucode_crc_beforeLoad) ? m_pUCode : UCodeFactory( ucode_crc, this, m_bWii); + IUCode* lastucode = (lastucode_crc != lastucode_crc_beforeLoad) ? m_lastUCode : UCodeFactory(lastucode_crc, this, m_bWii); + + if (ucode) + ucode->DoState(p); + if (lastucode) + lastucode->DoState(p); + + // if a different type of ucode was being used when the savestate was created, + // discard it if we're not loading, otherwise discard the old one and keep the new one. + if (ucode != m_pUCode) + { + if (p.GetMode() != PointerWrap::MODE_READ) + delete ucode; + else + { + delete m_pUCode; + m_pUCode = ucode; + } + } + if (lastucode != m_lastUCode) + { + if (p.GetMode() != PointerWrap::MODE_READ) + delete lastucode; + else + { + delete m_lastUCode; + m_lastUCode = lastucode; + } + } + + m_MailHandler.DoState(p); } // Mailbox fuctions diff --git a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AX.cpp b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AX.cpp index 8c88217494..33f0d2f1e6 100644 --- a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AX.cpp +++ b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AX.cpp @@ -28,9 +28,8 @@ #include "UCode_AX_Voice.h" CUCode_AX::CUCode_AX(DSPHLE *dsp_hle, u32 l_CRC) - : IUCode(dsp_hle) + : IUCode(dsp_hle, l_CRC) , m_addressPBs(0xFFFFFFFF) - , _CRC(l_CRC) { // we got loaded m_rMailHandler.PushMail(DSP_INIT); @@ -175,7 +174,7 @@ void CUCode_AX::MixAdd(short* _pBuffer, int _iSize) ProcessUpdates(PB); - if (_CRC != 0x3389a79e) + if (m_CRC != 0x3389a79e) VoiceHacks(PB); MixAddVoice(PB, templbuffer, temprbuffer, _iSize); @@ -463,11 +462,8 @@ void CUCode_AX::DoState(PointerWrap &p) { std::lock_guard lk(m_csMix); - p.Do(_CRC); p.Do(numPBaddr); p.Do(m_addressPBs); p.Do(PBaddr); p.Do(m_UploadSetupInProgress); - - m_rMailHandler.DoState(p); } diff --git a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AX.h b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AX.h index 6386e3ce6a..edb52a2801 100644 --- a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AX.h +++ b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AX.h @@ -41,7 +41,6 @@ public: u8 numPBaddr; u32 PBaddr[8]; //2 needed for MP2 u32 m_addressPBs; - u32 _CRC; private: enum diff --git a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AXWii.cpp b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AXWii.cpp index 41f044f9be..6300b35b4a 100644 --- a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AXWii.cpp +++ b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_AXWii.cpp @@ -28,9 +28,8 @@ CUCode_AXWii::CUCode_AXWii(DSPHLE *dsp_hle, u32 l_CRC) - : IUCode(dsp_hle) + : IUCode(dsp_hle, l_CRC) , m_addressPBs(0xFFFFFFFF) - , _CRC(l_CRC) { // we got loaded m_rMailHandler.PushMail(DSP_INIT); @@ -38,7 +37,7 @@ CUCode_AXWii::CUCode_AXWii(DSPHLE *dsp_hle, u32 l_CRC) templbuffer = new int[1024 * 1024]; temprbuffer = new int[1024 * 1024]; - wiisportsHack = _CRC == 0xfa450138; + wiisportsHack = m_CRC == 0xfa450138; } CUCode_AXWii::~CUCode_AXWii() @@ -260,10 +259,7 @@ void CUCode_AXWii::DoState(PointerWrap &p) { std::lock_guard lk(m_csMix); - p.Do(_CRC); p.Do(m_addressPBs); p.Do(wiisportsHack); p.Do(m_UploadSetupInProgress); - - m_rMailHandler.DoState(p); } diff --git a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_CARD.cpp b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_CARD.cpp index 442d77ab85..dcd4e24e3f 100644 --- a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_CARD.cpp +++ b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_CARD.cpp @@ -21,8 +21,8 @@ #include "../../DSP.h" -CUCode_CARD::CUCode_CARD(DSPHLE *dsp_hle) - : IUCode(dsp_hle) +CUCode_CARD::CUCode_CARD(DSPHLE *dsp_hle, u32 crc) + : IUCode(dsp_hle, crc) { DEBUG_LOG(DSPHLE, "CUCode_CARD - initialized"); m_rMailHandler.PushMail(DSP_INIT); diff --git a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_CARD.h b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_CARD.h index 0246d4680a..a6f90124ad 100644 --- a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_CARD.h +++ b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_CARD.h @@ -23,7 +23,7 @@ class CUCode_CARD : public IUCode { public: - CUCode_CARD(DSPHLE *dsp_hle); + CUCode_CARD(DSPHLE *dsp_hle, u32 crc); virtual ~CUCode_CARD(); void HandleMail(u32 _uMail); diff --git a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_GBA.cpp b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_GBA.cpp index b82c7ac0b2..42bc18ff49 100644 --- a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_GBA.cpp +++ b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_GBA.cpp @@ -20,8 +20,8 @@ #include "../../DSP.h" -CUCode_GBA::CUCode_GBA(DSPHLE *dsp_hle) -: IUCode(dsp_hle) +CUCode_GBA::CUCode_GBA(DSPHLE *dsp_hle, u32 crc) +: IUCode(dsp_hle, crc) { m_rMailHandler.PushMail(DSP_INIT); } diff --git a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_GBA.h b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_GBA.h index 412036835d..c61917339f 100644 --- a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_GBA.h +++ b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_GBA.h @@ -21,7 +21,7 @@ struct CUCode_GBA : public IUCode { - CUCode_GBA(DSPHLE *dsp_hle); + CUCode_GBA(DSPHLE *dsp_hle, u32 crc); virtual ~CUCode_GBA(); void HandleMail(u32 _uMail); diff --git a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_InitAudioSystem.cpp b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_InitAudioSystem.cpp index 663d4beadd..ae7716012a 100644 --- a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_InitAudioSystem.cpp +++ b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_InitAudioSystem.cpp @@ -18,8 +18,8 @@ #include "UCodes.h" #include "UCode_InitAudioSystem.h" -CUCode_InitAudioSystem::CUCode_InitAudioSystem(DSPHLE *dsp_hle) - : IUCode(dsp_hle) +CUCode_InitAudioSystem::CUCode_InitAudioSystem(DSPHLE *dsp_hle, u32 crc) + : IUCode(dsp_hle, crc) { DEBUG_LOG(DSPHLE, "CUCode_InitAudioSystem - initialized"); } diff --git a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_InitAudioSystem.h b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_InitAudioSystem.h index 09b54a4a4b..8dc237f1d0 100644 --- a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_InitAudioSystem.h +++ b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_InitAudioSystem.h @@ -23,7 +23,7 @@ class CUCode_InitAudioSystem : public IUCode { public: - CUCode_InitAudioSystem(DSPHLE *dsp_hle); + CUCode_InitAudioSystem(DSPHLE *dsp_hle, u32 crc); virtual ~CUCode_InitAudioSystem(); void HandleMail(u32 _uMail); diff --git a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_ROM.cpp b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_ROM.cpp index 48dba7e28b..c1544792f5 100644 --- a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_ROM.cpp +++ b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_ROM.cpp @@ -20,8 +20,8 @@ #include "Hash.h" #include "../../Memmap.h" -CUCode_Rom::CUCode_Rom(DSPHLE *dsp_hle) - : IUCode(dsp_hle) +CUCode_Rom::CUCode_Rom(DSPHLE *dsp_hle, u32 crc) + : IUCode(dsp_hle, crc) , m_CurrentUCode() , m_BootTask_numSteps(0) , m_NextParameter(0) @@ -117,4 +117,10 @@ void CUCode_Rom::BootUCode() m_DSPHLE->SetUCode(ector_crc); } +void CUCode_Rom::DoState(PointerWrap &p) +{ + p.Do(m_CurrentUCode); + p.Do(m_BootTask_numSteps); + p.Do(m_NextParameter); +} diff --git a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_ROM.h b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_ROM.h index ecec9f87ea..f1e7b8ec7a 100644 --- a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_ROM.h +++ b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_ROM.h @@ -23,12 +23,14 @@ class CUCode_Rom : public IUCode { public: - CUCode_Rom(DSPHLE *dsp_hle); + CUCode_Rom(DSPHLE *dsp_hle, u32 _crc); virtual ~CUCode_Rom(); void HandleMail(u32 _uMail); void Update(int cycles); + void DoState(PointerWrap &p); + private: struct SUCode { diff --git a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_Zelda.cpp b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_Zelda.cpp index 913de7107b..713236180d 100644 --- a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_Zelda.cpp +++ b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_Zelda.cpp @@ -31,8 +31,7 @@ CUCode_Zelda::CUCode_Zelda(DSPHLE *dsp_hle, u32 _CRC) : - IUCode(dsp_hle), - m_CRC(_CRC), + IUCode(dsp_hle, _CRC), m_bSyncInProgress(false), m_MaxVoice(0), @@ -572,8 +571,6 @@ void CUCode_Zelda::DoState(PointerWrap &p) // It's bad if we try to save during Mix() std::lock_guard lk(m_csMix); - p.Do(m_CRC); - p.Do(m_AFCCoefTable); p.Do(m_MiscTable); @@ -616,6 +613,4 @@ void CUCode_Zelda::DoState(PointerWrap &p) p.Do(m_PBAddress2); p.Do(m_UploadSetupInProgress); - - m_rMailHandler.DoState(p); } diff --git a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_Zelda.h b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_Zelda.h index 3abe711c5b..f8a69536c2 100644 --- a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_Zelda.h +++ b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_Zelda.h @@ -212,8 +212,6 @@ private: } } - u32 m_CRC; - // These are the only dynamically allocated things allowed in the ucode. s32* m_VoiceBuffer; s16* m_ResampleBuffer; diff --git a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCodes.cpp b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCodes.cpp index c982b97f51..62620253aa 100644 --- a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCodes.cpp +++ b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCodes.cpp @@ -32,19 +32,19 @@ IUCode* UCodeFactory(u32 _CRC, DSPHLE *dsp_hle, bool bWii) { case UCODE_ROM: INFO_LOG(DSPHLE, "Switching to ROM ucode"); - return new CUCode_Rom(dsp_hle); + return new CUCode_Rom(dsp_hle, _CRC); case UCODE_INIT_AUDIO_SYSTEM: INFO_LOG(DSPHLE, "Switching to INIT ucode"); - return new CUCode_InitAudioSystem(dsp_hle); + return new CUCode_InitAudioSystem(dsp_hle, _CRC); case 0x65d6cc6f: // CARD INFO_LOG(DSPHLE, "Switching to CARD ucode"); - return new CUCode_CARD(dsp_hle); + return new CUCode_CARD(dsp_hle, _CRC); case 0xdd7e72d5: INFO_LOG(DSPHLE, "Switching to GBA ucode"); - return new CUCode_GBA(dsp_hle); + return new CUCode_GBA(dsp_hle, _CRC); case 0x3ad3b7ac: // Naruto3, Paper Mario - The Thousand Year Door case 0x3daf59b9: // Alien Hominid @@ -103,6 +103,9 @@ IUCode* UCodeFactory(u32 _CRC, DSPHLE *dsp_hle, bool bWii) PanicAlert("DSPHLE: Unknown ucode (CRC = %08x) - forcing AX.\n\nTry LLE emulator if this is homebrew.", _CRC); return new CUCode_AX(dsp_hle, _CRC); } + + case UCODE_NULL: + break; } return NULL; diff --git a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCodes.h b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCodes.h index cb3bc6a4f0..faea895609 100644 --- a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCodes.h +++ b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCodes.h @@ -25,8 +25,9 @@ #include "../DSPHLE.h" #include "../../Memmap.h" -#define UCODE_ROM 0x0000000 -#define UCODE_INIT_AUDIO_SYSTEM 0x0000001 +#define UCODE_ROM 0x00000000 +#define UCODE_INIT_AUDIO_SYSTEM 0x00000001 +#define UCODE_NULL 0xFFFFFFFF class CMailHandler; @@ -73,10 +74,11 @@ inline void* HLEMemory_Get_Pointer(u32 _uAddress) class IUCode { public: - IUCode(DSPHLE *dsphle) + IUCode(DSPHLE *dsphle, u32 _crc) : m_rMailHandler(dsphle->AccessMailHandler()) , m_UploadSetupInProgress(false) , m_DSPHLE(dsphle) + , m_CRC(_crc) , m_NextUCode() , m_NextUCode_steps(0) , m_NeedsResumeMail(false) @@ -93,6 +95,8 @@ public: virtual void DoState(PointerWrap &p) {} + static u32 GetCRC(IUCode* pUCode) { return pUCode ? pUCode->m_CRC : UCODE_NULL; } + protected: void PrepareBootUCode(u32 mail); @@ -121,6 +125,10 @@ protected: // Need a pointer back to DSPHLE to switch ucodes. DSPHLE *m_DSPHLE; + // used for reconstruction when loading saves, + // and for variations within certain ucodes. + u32 m_CRC; + private: struct SUCode {