From 887fcfc99a5e4aa674f0e325df3dc699e3f778ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Mon, 12 Jul 2021 21:27:16 +0200 Subject: [PATCH 1/2] DSPHLE: Remove redundant accelerator end check for AX Wii --- Source/Core/Core/HW/DSPHLE/UCodes/AXVoice.h | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/AXVoice.h b/Source/Core/Core/HW/DSPHLE/UCodes/AXVoice.h index b8b96a00b4..aa9c56fe05 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/AXVoice.h +++ b/Source/Core/Core/HW/DSPHLE/UCodes/AXVoice.h @@ -146,7 +146,6 @@ void WritePB(u32 addr, const PB_TYPE& pb, u32 crc) // Simulated accelerator state. static PB_TYPE* acc_pb; -static bool acc_end_reached; class HLEAccelerator final : public Accelerator { @@ -177,15 +176,6 @@ protected: { // Non looping voice reached the end -> running = 0. acc_pb->running = 0; - -#ifdef AX_WII - // One of the few meaningful differences between AXGC and AXWii: - // while AXGC handles non looping voices ending by relying on the - // accelerator to stop reads once the loop address is reached, - // AXWii has the 0000 samples internally in DRAM and use an internal - // pointer to it (loop addr does not contain 0000 samples on AXWii!). - acc_end_reached = true; -#endif } } @@ -206,7 +196,6 @@ void AcceleratorSetup(PB_TYPE* pb) s_accelerator->SetYn1(pb->adpcm.yn1); s_accelerator->SetYn2(pb->adpcm.yn2); s_accelerator->SetPredScale(pb->adpcm.pred_scale); - acc_end_reached = false; } // Reads a sample from the accelerator. Also handles looping and @@ -214,10 +203,6 @@ void AcceleratorSetup(PB_TYPE* pb) // by the accelerator on real hardware). u16 AcceleratorGetSample() { - // See below for explanations about acc_end_reached. - if (acc_end_reached) - return 0; - return s_accelerator->Read(acc_pb->adpcm.coefs); } From 5021a13aa94a758e32cdf548e21077604f080005 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Wed, 14 Jul 2021 13:24:10 +0200 Subject: [PATCH 2/2] DSPHLE: Fix running and is_stream checks in AX HLE A voice is considered running if and only if `running` equals 1, not if `running` is not equal to 0. This fixes https://bugs.dolphin-emu.org/issues/12508 because for some reason *The Sims 2 - Castaway* sets `running` to 8 when a stream finishes playing; previously our AX HLE would just loop the voice and eventually crash after accessing invalid memory addresses. Thanks to JMC47 and delroth's help, I've verified that this is the correct check for the following ucodes: GC: * 0x3ad3b7ac * 0x3daf59b9 * 0x4e8a8b21 * 0x07f88145 * 0xe2136399 * 0x3389a79e Wii: * 0x347112ba * 0xfa450138 * 0xadbc06bd And while I was fixing the running check, I noticed that the is_stream field was also being handled incorrectly, so I've fixed that as well. --- Source/Core/Core/HW/DSPHLE/UCodes/AXStructs.h | 4 ++-- Source/Core/Core/HW/DSPHLE/UCodes/AXVoice.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/AXStructs.h b/Source/Core/Core/HW/DSPHLE/UCodes/AXStructs.h index c575423315..bbb8e67770 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/AXStructs.h +++ b/Source/Core/Core/HW/DSPHLE/UCodes/AXStructs.h @@ -236,8 +236,8 @@ struct AXPB u16 coef_select; u16 mixer_control; - u16 running; // 1=RUN 0=STOP - u16 is_stream; // 1 = stream, 0 = one shot + u16 running; // 1 = playing, anything else = stopped + u16 is_stream; // 1 = stream, anything else = one shot PBMixer mixer; PBInitialTimeDelay initial_time_delay; diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/AXVoice.h b/Source/Core/Core/HW/DSPHLE/UCodes/AXVoice.h index aa9c56fe05..b35016c7b6 100644 --- a/Source/Core/Core/HW/DSPHLE/UCodes/AXVoice.h +++ b/Source/Core/Core/HW/DSPHLE/UCodes/AXVoice.h @@ -156,7 +156,7 @@ protected: { // Set the ADPCM info to continue processing at loop_addr. SetPredScale(acc_pb->adpcm_loop_info.pred_scale); - if (!acc_pb->is_stream) + if (acc_pb->is_stream != 1) { SetYn1(acc_pb->adpcm_loop_info.yn1); SetYn2(acc_pb->adpcm_loop_info.yn2); @@ -403,7 +403,7 @@ void ProcessVoice(PB_TYPE& pb, const AXBuffers& buffers, u16 count, AXMixControl const s16* coeffs) { // If the voice is not running, nothing to do. - if (!pb.running) + if (pb.running != 1) return; // Read input samples, performing sample rate conversion if needed.