summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorPierre Bourdon <delroth@gmail.com>2012-11-14 06:53:36 +0100
committerPierre Bourdon <delroth@gmail.com>2012-11-14 06:53:36 +0100
commit18f3630af50ce5ec5e0be97d7634daaf32d776bb (patch)
tree373e30b5ff8effecea166050a14ee7044289e1d0 /Source/Core
parent7535c6d9038684c2a27f7307dd4f2439829b5a2f (diff)
PBs processing is now done, just need the output to be able to test
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_NewAX.cpp116
-rw-r--r--Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_NewAX.h2
2 files changed, 114 insertions, 4 deletions
diff --git a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_NewAX.cpp b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_NewAX.cpp
index 31799f2675..e4a05c42ba 100644
--- a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_NewAX.cpp
+++ b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_NewAX.cpp
@@ -16,6 +16,7 @@
// http://code.google.com/p/dolphin-emu/
#include "UCode_NewAX.h"
+#include "UCode_AX_Voice.h"
#include "../../DSP.h"
CUCode_NewAX::CUCode_NewAX(DSPHLE* dsp_hle, u32 crc)
@@ -95,7 +96,7 @@ void CUCode_NewAX::HandleCommandList()
break;
case CMD_PROCESS:
- ProcessPB(pb_addr);
+ ProcessPBList(pb_addr);
break;
case CMD_UNK_04: curr_idx += 4; break;
@@ -127,9 +128,118 @@ void CUCode_NewAX::HandleCommandList()
}
}
-void CUCode_NewAX::ProcessPB(u32 pb_addr)
+// From old UCode_AX.cpp.
+static void VoiceHacks(AXPB &pb)
{
- NOTICE_LOG(DSPHLE, "TODO: process pb %08x", pb_addr);
+ // get necessary values
+ const u32 sampleEnd = (pb.audio_addr.end_addr_hi << 16) | pb.audio_addr.end_addr_lo;
+ const u32 loopPos = (pb.audio_addr.loop_addr_hi << 16) | pb.audio_addr.loop_addr_lo;
+ // const u32 updaddr = (u32)(pb.updates.data_hi << 16) | pb.updates.data_lo;
+ // const u16 updpar = HLEMemory_Read_U16(updaddr);
+ // const u16 upddata = HLEMemory_Read_U16(updaddr + 2);
+
+ // =======================================================================================
+ /* Fix problems introduced with the SSBM fix. Sometimes when a music stream ended sampleEnd
+ would end up outside of bounds while the block was still playing resulting in noise
+ a strange noise. This should take care of that.
+ */
+ if ((sampleEnd > (0x017fffff * 2) || loopPos > (0x017fffff * 2))) // ARAM bounds in nibbles
+ {
+ pb.running = 0;
+
+ // also reset all values if it makes any difference
+ pb.audio_addr.cur_addr_hi = 0; pb.audio_addr.cur_addr_lo = 0;
+ pb.audio_addr.end_addr_hi = 0; pb.audio_addr.end_addr_lo = 0;
+ pb.audio_addr.loop_addr_hi = 0; pb.audio_addr.loop_addr_lo = 0;
+
+ pb.src.cur_addr_frac = 0; pb.src.ratio_hi = 0; pb.src.ratio_lo = 0;
+ pb.adpcm.pred_scale = 0; pb.adpcm.yn1 = 0; pb.adpcm.yn2 = 0;
+
+ pb.audio_addr.looping = 0;
+ pb.adpcm_loop_info.pred_scale = 0;
+ pb.adpcm_loop_info.yn1 = 0; pb.adpcm_loop_info.yn2 = 0;
+ }
+
+ /*
+ // the fact that no settings are reset (except running) after a SSBM type music stream or another
+ looping block (for example in Battle Stadium DON) has ended could cause loud garbled sound to be
+ played from one or more blocks. Perhaps it was in conjunction with the old sequenced music fix below,
+ I'm not sure. This was an attempt to prevent that anyway by resetting all. But I'm not sure if this
+ is needed anymore. Please try to play SSBM without it and see if it works anyway.
+ */
+ if (
+ // detect blocks that have recently been running that we should reset
+ pb.running == 0 && pb.audio_addr.looping == 1
+ //pb.running == 0 && pb.adpcm_loop_info.pred_scale
+
+ // this prevents us from ruining sequenced music blocks, may not be needed
+ /*
+ && !(pb.updates.num_updates[0] || pb.updates.num_updates[1] || pb.updates.num_updates[2]
+ || pb.updates.num_updates[3] || pb.updates.num_updates[4])
+ */
+ //&& !(updpar || upddata)
+
+ && pb.mixer_control == 0 // only use this in SSBM
+ )
+ {
+ // reset the detection values
+ pb.audio_addr.looping = 0;
+ pb.adpcm_loop_info.pred_scale = 0;
+ pb.adpcm_loop_info.yn1 = 0; pb.adpcm_loop_info.yn2 = 0;
+
+ //pb.audio_addr.cur_addr_hi = 0; pb.audio_addr.cur_addr_lo = 0;
+ //pb.audio_addr.end_addr_hi = 0; pb.audio_addr.end_addr_lo = 0;
+ //pb.audio_addr.loop_addr_hi = 0; pb.audio_addr.loop_addr_lo = 0;
+
+ //pb.src.cur_addr_frac = 0; PBs[i].src.ratio_hi = 0; PBs[i].src.ratio_lo = 0;
+ //pb.adpcm.pred_scale = 0; pb.adpcm.yn1 = 0; pb.adpcm.yn2 = 0;
+ }
+}
+
+static void ApplyUpdatesForMs(AXPB& pb, int curr_ms)
+{
+ u32 start_idx = 0;
+ for (int i = 0; i < curr_ms; ++i)
+ start_idx += pb.updates.num_updates[i];
+
+ u32 update_addr = (pb.updates.data_hi << 16) | pb.updates.data_lo;
+ for (u32 i = start_idx; i < start_idx + pb.updates.num_updates[curr_ms]; ++i)
+ {
+ u16 update_off = HLEMemory_Read_U16(update_addr + 4 * i);
+ u16 update_val = HLEMemory_Read_U16(update_addr + 4 * i + 2);
+
+ ((u16*)&pb)[update_off] = update_val;
+ }
+}
+
+void CUCode_NewAX::ProcessPBList(u32 pb_addr)
+{
+ static int tmp_mix_buffer_left[5 * 32], tmp_mix_buffer_right[5 * 32];
+
+ AXPB pb;
+
+ while (pb_addr)
+ {
+ if (!ReadPB(pb_addr, pb))
+ break;
+
+ for (int curr_ms = 0; curr_ms < 5; ++curr_ms)
+ {
+ ApplyUpdatesForMs(pb, curr_ms);
+
+ // TODO: is that still needed?
+ if (m_CRC != 0x3389a79e)
+ VoiceHacks(pb);
+
+ MixAddVoice(pb, tmp_mix_buffer_left + 32 * curr_ms,
+ tmp_mix_buffer_right + 32 * curr_ms, 32);
+ }
+
+ WritePB(pb_addr, pb);
+ pb_addr = (pb.next_pb_hi << 16) | pb.next_pb_lo;
+ }
+
+ // TODO: write the 5ms back to a buffer the audio interface can read from
}
void CUCode_NewAX::HandleMail(u32 mail)
diff --git a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_NewAX.h b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_NewAX.h
index 92184fe38f..70a06a7408 100644
--- a/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_NewAX.h
+++ b/Source/Core/Core/Src/HW/DSPHLE/UCodes/UCode_NewAX.h
@@ -90,7 +90,7 @@ private:
void AXThread();
void HandleCommandList();
- void ProcessPB(u32 pb_addr);
+ void ProcessPBList(u32 pb_addr);
};
#endif // !_UCODE_NEWAX_H