From 155719dc36cabfed9b4dd675e3ee269904a2ef8b Mon Sep 17 00:00:00 2001 From: ayuanx Date: Fri, 27 Nov 2009 15:07:52 +0000 Subject: [PATCH] Very small but very COOL fix. This commit fixed the Hang-up in many games, like "New Super Mario Bros. Wii", "Resident Evil: The Darkside Chronicles", "Fatal Frame 4: Tsukihami no Kamen", "Muramasa: The Demon Blade", and etc. You name it. OH YEAH! This little issue really cost me some *serious* debugging time, phew... git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4616 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Core/Src/HW/DSP.cpp | 28 ++--------- .../Plugin_DSP_HLE/Src/MailHandler.cpp | 22 +-------- .../Plugins/Plugin_DSP_HLE/Src/MailHandler.h | 1 - .../Src/UCodes/UCode_AXStructs.h | 47 +++++++++---------- .../Src/UCodes/UCode_AX_Voice.h | 12 ++++- Source/Plugins/Plugin_DSP_HLE/Src/main.cpp | 28 ++--------- 6 files changed, 41 insertions(+), 97 deletions(-) diff --git a/Source/Core/Core/Src/HW/DSP.cpp b/Source/Core/Core/Src/HW/DSP.cpp index 5b261e4c3c..46cff2980f 100644 --- a/Source/Core/Core/Src/HW/DSP.cpp +++ b/Source/Core/Core/Src/HW/DSP.cpp @@ -111,12 +111,9 @@ union UDSPControl // DSPState struct DSPState { - u32 IntControl; UDSPControl DSPControl; - DSPState() { - IntControl = 0; DSPControl.Hex = 0; } }; @@ -411,20 +408,12 @@ void Write16(const u16 _Value, const u32 _Address) break; case AUDIO_DMA_CONTROL_LEN: // called by AIStartDMA() - { - UAudioDMAControl old_control = g_audioDMA.AudioDMAControl; g_audioDMA.AudioDMAControl.Hex = _Value; - - if (!old_control.Enabled && g_audioDMA.AudioDMAControl.Enabled) - { - // Enabled bit was flipped to true, let's latch address & length and call the interrupt. - g_audioDMA.BlocksLeft = g_audioDMA.AudioDMAControl.NumBlocks; - g_audioDMA.ReadAddress = g_audioDMA.SourceAddress; - GenerateDSPInterrupt(DSP::INT_AID); - INFO_LOG(DSPINTERFACE, "AID DMA started - source address %08x, length %i blocks", g_audioDMA.SourceAddress, g_audioDMA.AudioDMAControl.NumBlocks); - } + g_audioDMA.BlocksLeft = g_audioDMA.AudioDMAControl.NumBlocks; + g_audioDMA.ReadAddress = g_audioDMA.SourceAddress; + INFO_LOG(DSPINTERFACE, "AID DMA started - source address %08x, length %i blocks", g_audioDMA.SourceAddress, g_audioDMA.AudioDMAControl.NumBlocks); break; - } + case AUDIO_DMA_BYTES_LEFT: _dbg_assert_(DSPINTERFACE,0); break; @@ -449,11 +438,6 @@ void UpdateAudioDMA() g_audioDMA.ReadAddress += 32; g_audioDMA.BlocksLeft--; if (!g_audioDMA.BlocksLeft) { - // No need to turn off the DMA - we can only get here if we had - // blocks left when we entered this function, and no longer have - // any. Latch new parameters - g_audioDMA.BlocksLeft = g_audioDMA.AudioDMAControl.NumBlocks; - g_audioDMA.ReadAddress = g_audioDMA.SourceAddress; // DEBUG_LOG(DSPLLE, "ADMA read addresses: %08x", g_audioDMA.ReadAddress); GenerateDSPInterrupt(DSP::INT_AID); } @@ -469,10 +453,6 @@ void Read32(u32& _uReturnValue, const u32 _iAddress) INFO_LOG(DSPINTERFACE, "DSPInterface(r) 0x%08x", _iAddress); switch (_iAddress & 0xFFFF) { - case DSP_INTERRUPT_CONTROL: - _uReturnValue = g_dspState.IntControl; - return; - default: _dbg_assert_(DSPINTERFACE,0); break; diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/MailHandler.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/MailHandler.cpp index 9d1185e100..7666c43cfe 100644 --- a/Source/Plugins/Plugin_DSP_HLE/Src/MailHandler.cpp +++ b/Source/Plugins/Plugin_DSP_HLE/Src/MailHandler.cpp @@ -18,9 +18,7 @@ #include "MailHandler.h" CMailHandler::CMailHandler() -{ - -} +{} CMailHandler::~CMailHandler() { @@ -31,7 +29,6 @@ void CMailHandler::PushMail(u32 _Mail) { m_Mails.push(_Mail); DEBUG_LOG(DSP_MAIL, "DSP writes 0x%08x", _Mail); - Update(); } u16 CMailHandler::ReadDSPMailboxHigh() @@ -40,10 +37,8 @@ u16 CMailHandler::ReadDSPMailboxHigh() if (!m_Mails.empty()) { u16 result = (m_Mails.front() >> 16) & 0xFFFF; - Update(); return result; } - return 0x00; } @@ -53,14 +48,9 @@ u16 CMailHandler::ReadDSPMailboxLow() if (!m_Mails.empty()) { u16 result = m_Mails.front() & 0xFFFF; - m_Mails.pop(); - - Update(); - return result; } - return 0x00; } @@ -82,16 +72,6 @@ void CMailHandler::Halt(bool _Halt) Clear(); m_Mails.push(0x80544348); } - - Update(); -} - -void CMailHandler::Update() -{ - if (!IsEmpty()) - { - // g_dspInitialize.pGenerateDSPInterrupt(); - } } void CMailHandler::DoState(PointerWrap &p) diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/MailHandler.h b/Source/Plugins/Plugin_DSP_HLE/Src/MailHandler.h index b414f5275d..34a28a9038 100644 --- a/Source/Plugins/Plugin_DSP_HLE/Src/MailHandler.h +++ b/Source/Plugins/Plugin_DSP_HLE/Src/MailHandler.h @@ -37,7 +37,6 @@ public: u16 ReadDSPMailboxHigh(); u16 ReadDSPMailboxLow(); - void Update(); u32 GetNextMail() { diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AXStructs.h b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AXStructs.h index 6142eaa727..6d194e69be 100644 --- a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AXStructs.h +++ b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AXStructs.h @@ -206,31 +206,28 @@ struct AXParamBlockWii struct AXParamBlockWii_ // new CRC version { - u16 next_pb_hi; - u16 next_pb_lo; - - u16 this_pb_hi; - u16 this_pb_lo; - - u16 src_type; // Type of sample rate converter (none, ?, linear) - u16 coef_select; - u32 mixer_control; - - u16 running; // 1=RUN 0=STOP - u16 is_stream; // 1 = stream, 0 = one shot - -/* 10 */ PBMixerWii mixer; -/* 34 */ PBInitialTimeDelay initial_time_delay; -/* 41 */ PBUpdatesWii updates; -/* 46 */ PBDpopWii_ dpop; -/* 53 */ PBVolumeEnvelope vol_env; -/* 55 */ PBAudioAddr audio_addr; -/* 63 */ PBADPCMInfo adpcm; -/* 83 */ PBSampleRateConverter src; -/* 90 */ PBADPCMLoopInfo adpcm_loop_info; -/* 93 */ PBLpf lpf; -/* 97 */ PBHpf hpf; -/* 101 */ u16 pad[27]; +/* 0x000 */ u16 next_pb_hi; +/* 0x002 */ u16 next_pb_lo; +/* 0x004 */ u16 this_pb_hi; +/* 0x006 */ u16 this_pb_lo; +/* 0x008 */ u16 src_type; // Type of sample rate converter (none, ?, linear) +/* 0x00A */ u16 coef_select; +/* 0x00C */ u32 mixer_control; +/* 0x010 */ u16 running; // 1=RUN 0=STOP +/* 0x012 */ u16 is_stream; // 1 = stream, 0 = one shot +/* 0x014 */ PBMixerWii mixer; +/* 0x044 */ PBInitialTimeDelay initial_time_delay; +/* 0x052 */ PBUpdatesWii updates; +/* 0x05C */ PBDpopWii_ dpop; +/* 0x06A */ PBVolumeEnvelope vol_env; +/* 0x06E */ PBAudioAddr audio_addr; +/* 0x07E */ PBADPCMInfo adpcm; +/* 0x0A6 */ PBSampleRateConverter src; +/* 0x0B4 */ PBADPCMLoopInfo adpcm_loop_info; +/* 0x0BA */ PBLpf lpf; +/* 0x0C2 */ PBHpf hpf; +/* 0x0CA */ u16 pad[27]; +/* 0x100 */ }; enum { diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AX_Voice.h b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AX_Voice.h index 7eaf19bb45..e247f1db33 100644 --- a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AX_Voice.h +++ b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_AX_Voice.h @@ -245,7 +245,17 @@ inline void MixAddVoice(ParamBlockType &pb, int *templbuffer, int *temprbuffer, } else { - pb.running = 0; + // This accurate boundary wrapping will fix the hangup in many Wii games like: + // New Super Mario Bros.Wii, Fatal Frame 4, + // Resident Evil Darkside Chronicles, Muramasa The Demon Blade, etc. + samplePos = newSamplePos - sampleEnd + loopPos; + + // AyuanX: DSP should not touch this running state + // even when a non-looping voice reaches the end of current sample + // because some game checks this flag and will turn it off when necessary + // + //pb.running = 0; + break; } } diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/main.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/main.cpp index 87cdfc5e6c..6ecd47705d 100644 --- a/Source/Plugins/Plugin_DSP_HLE/Src/main.cpp +++ b/Source/Plugins/Plugin_DSP_HLE/Src/main.cpp @@ -49,19 +49,11 @@ SoundStream *soundStream = NULL; struct DSPState { u32 CPUMailbox; - bool CPUMailbox_Written[2]; - u32 DSPMailbox; - bool DSPMailbox_Read[2]; void Reset() { CPUMailbox = 0x00000000; - CPUMailbox_Written[0] = false; - CPUMailbox_Written[1] = false; - DSPMailbox = 0x00000000; - DSPMailbox_Read[0] = true; - DSPMailbox_Read[1] = true; } DSPState() @@ -281,25 +273,11 @@ unsigned short DSP_ReadMailboxLow(bool _CPUMailbox) } } -void Update_DSP_WriteRegister() -{ - // check if the whole message is complete and if we can send it - if (g_dspState.CPUMailbox_Written[0] && g_dspState.CPUMailbox_Written[1]) - { - CDSPHandler::GetInstance().SendMailToDSP(g_dspState.CPUMailbox); - g_dspState.CPUMailbox_Written[0] = g_dspState.CPUMailbox_Written[1] = false; - g_dspState.CPUMailbox = 0; // Mail sent so clear it to show that it is progressed - } -} - void DSP_WriteMailboxHigh(bool _CPUMailbox, unsigned short _Value) { if (_CPUMailbox) { g_dspState.CPUMailbox = (g_dspState.CPUMailbox & 0xFFFF) | (_Value << 16); - g_dspState.CPUMailbox_Written[0] = true; - - Update_DSP_WriteRegister(); } else { @@ -312,9 +290,9 @@ void DSP_WriteMailboxLow(bool _CPUMailbox, unsigned short _Value) if (_CPUMailbox) { g_dspState.CPUMailbox = (g_dspState.CPUMailbox & 0xFFFF0000) | _Value; - g_dspState.CPUMailbox_Written[1] = true; - - Update_DSP_WriteRegister(); + CDSPHandler::GetInstance().SendMailToDSP(g_dspState.CPUMailbox); + // Mail sent so clear MSB to show that it is progressed + g_dspState.CPUMailbox &= 0x7FFFFFFF; } else {