From d5c7105c78bd42f36f7b607f274bd1fc39244dde Mon Sep 17 00:00:00 2001 From: luigi2us Date: Fri, 17 Jul 2009 22:57:56 +0000 Subject: [PATCH] Zelda uCode: try to fix Super Mario Sunshine (hard since I don't have the game). Let's hope it'll work. If yes, we can open the champagne :D (BTW: yeah, again a HandleMail() clone) git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3823 8ced0084-cf51-0410-be5f-012b33b47a6e --- .../Plugin_DSP_HLE/Src/UCodes/UCode_Zelda.cpp | 94 +++++++++++++++++++ .../Plugin_DSP_HLE/Src/UCodes/UCode_Zelda.h | 31 +++++- 2 files changed, 124 insertions(+), 1 deletion(-) diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda.cpp index bfbdde2686..e98b47c42f 100644 --- a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda.cpp +++ b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda.cpp @@ -123,6 +123,8 @@ void CUCode_Zelda::HandleMail(u32 _uMail) { if (IsLightVersion()) HandleMail_LightVersion(_uMail); + else if (IsSMSVersion()) + HandleMail_SMSVersion(_uMail); else HandleMail_NormalVersion(_uMail); } @@ -184,6 +186,98 @@ void CUCode_Zelda::HandleMail_LightVersion(u32 _uMail) } } +void CUCode_Zelda::HandleMail_SMSVersion(u32 _uMail) +{ + if (m_bSyncCmdPending) + { + if (m_bSyncInProgress) + { + m_bSyncInProgress = false; + + m_SyncFlags[2] = _uMail >> 16; + m_SyncFlags[3] = _uMail & 0xFFFF; + + m_CurBuffer++; + + m_rMailHandler.PushMail(DSP_SYNC); + g_dspInitialize.pGenerateDSPInterrupt(); + m_rMailHandler.PushMail(0xF355FF00 | m_CurBuffer); + + if (m_CurBuffer == m_NumBuffers) + { + m_rMailHandler.PushMail(DSP_FRAME_END); + //g_dspInitialize.pGenerateDSPInterrupt(); + + soundStream->GetMixer()->SetHLEReady(true); + DEBUG_LOG(DSPHLE, "Update the SoundThread to be in sync"); + soundStream->Update(); //do it in this thread to avoid sync problems + + m_bSyncCmdPending = false; + } + } + else + { + m_bSyncInProgress = true; + + m_SyncFlags[0] = _uMail >> 16; + m_SyncFlags[1] = _uMail & 0xFFFF; + } + + return; + } + + if (m_bListInProgress) + { + if (m_step < 0 || m_step >= sizeof(m_Buffer) / 4) + PanicAlert("m_step out of range"); + + ((u32*)m_Buffer)[m_step] = _uMail; + m_step++; + + if (m_step >= m_numSteps) + { + ExecuteList(); + m_bListInProgress = false; + } + + return; + } + + // Here holds: m_bSyncInProgress == false && m_bListInProgress == false + + if ((_uMail >> 16) == 0) + { + m_bListInProgress = true; + m_numSteps = _uMail; + m_step = 0; + } + else if ((_uMail >> 16) == 0xCDD1) // A 0xCDD1000X mail should come right after we send a DSP_SYNCEND mail + { + // The low part of the mail tells the operation to perform + // Seeing as every possible operation number halts the uCode, + // except 3, that thing seems to be intended for debugging + switch (_uMail & 0xFFFF) + { + case 0x0003: // Do nothing + return; + + case 0x0000: // Halt + case 0x0001: // Dump memory? and halt + case 0x0002: // Do something and halt + WARN_LOG(DSPHLE, "Zelda uCode(SMS version): received halting operation %04X", _uMail & 0xFFFF); + return; + + default: // Invalid (the real ucode would likely crash) + WARN_LOG(DSPHLE, "Zelda uCode(SMS version): received invalid operation %04X", _uMail & 0xFFFF); + return; + } + } + else + { + WARN_LOG(DSPHLE, "Zelda uCode (SMS version): unknown mail %08X", _uMail); + } +} + void CUCode_Zelda::HandleMail_NormalVersion(u32 _uMail) { // WARN_LOG(DSPHLE, "Zelda uCode: Handle mail %08X", _uMail); diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda.h b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda.h index 5f927b8732..0a745cc4d0 100644 --- a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda.h +++ b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda.h @@ -28,7 +28,8 @@ union ZeldaVoicePB { - struct { + struct + { // Read-Write part u16 Status; // 0x00 | 1 = play, 0 = stop u16 KeyOff; // 0x01 | writing 1 stops voice? @@ -115,6 +116,18 @@ union ZeldaVoicePB u16 raw[0xc0]; // WARNING-do not use on parts of the 32-bit values - they are swapped! }; +union ZeldaUnkPB +{ + struct + { + u16 Control; // 0x00 | control + u16 Unk01; // 0x01 | unknown + u32 SrcAddr; // 0x02 | some address + u16 Unk04[0xC]; // 0x04 | unknown + }; + u16 raw[16]; +}; + namespace { // If this miscompiles, adjust the size of ZeldaVoicePB to 0x180 bytes (0xc0 shorts). CompileTimeAssert ensure_zpb_size_correct; @@ -128,6 +141,7 @@ public: void HandleMail(u32 _uMail); void HandleMail_LightVersion(u32 _uMail); + void HandleMail_SMSVersion(u32 _uMail); void HandleMail_NormalVersion(u32 _uMail); void Update(int cycles); @@ -195,6 +209,21 @@ private: } } + // SMS version + // - sync mails are sent every frame, not every 16 PBs + // (named SMS because it's used by Super Mario Sunshine + // and I couldn't find a better name) + bool IsSMSVersion() const + { + switch (m_CRC) + { + case 0x56d36052: + return true; + default: + return false; + } + } + u32 m_CRC; // These are the only dynamically allocated things allowed in the ucode.