Merge pull request #5211 from MerryMage/ax
AX: Implement loop_counter and support UCodes without LPF
This commit is contained in:
commit
e863604b7e
|
@ -3,17 +3,11 @@
|
||||||
[Core]
|
[Core]
|
||||||
# Values set here will override the main Dolphin settings.
|
# Values set here will override the main Dolphin settings.
|
||||||
MMU = 1
|
MMU = 1
|
||||||
# LLE audio enabled by default for a listenable output
|
|
||||||
DSPHLE = False
|
|
||||||
|
|
||||||
[DSP]
|
|
||||||
# Ensure the LLE recompiler gets selected and not interpreter.
|
|
||||||
EnableJIT = True
|
|
||||||
|
|
||||||
[EmuState]
|
[EmuState]
|
||||||
# The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
# The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||||
EmulationStateId = 4
|
EmulationStateId = 4
|
||||||
EmulationIssues = Needs LLE audio for proper sound.
|
EmulationIssues =
|
||||||
|
|
||||||
[OnLoad]
|
[OnLoad]
|
||||||
# Add memory patches to be loaded once on boot here.
|
# Add memory patches to be loaded once on boot here.
|
||||||
|
|
|
@ -3,16 +3,10 @@
|
||||||
[Core]
|
[Core]
|
||||||
# Values set here will override the main Dolphin settings.
|
# Values set here will override the main Dolphin settings.
|
||||||
MMU = 1
|
MMU = 1
|
||||||
# LLE audio enabled by default for a listenable output
|
|
||||||
DSPHLE = False
|
|
||||||
|
|
||||||
[DSP]
|
|
||||||
# Ensure the LLE recompiler gets selected and not interpreter.
|
|
||||||
EnableJIT = True
|
|
||||||
|
|
||||||
[EmuState]
|
[EmuState]
|
||||||
# The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
# The Emulation State. 1 is worst, 5 is best, 0 is not set.
|
||||||
EmulationIssues = Needs LLE audio for proper sound.
|
EmulationIssues =
|
||||||
EmulationStateId = 4
|
EmulationStateId = 4
|
||||||
|
|
||||||
[OnLoad]
|
[OnLoad]
|
||||||
|
|
|
@ -422,7 +422,7 @@ void AXUCode::ProcessPBList(u32 pb_addr)
|
||||||
m_samples_auxA_right, m_samples_auxA_surround, m_samples_auxB_left,
|
m_samples_auxA_right, m_samples_auxA_surround, m_samples_auxB_left,
|
||||||
m_samples_auxB_right, m_samples_auxB_surround}};
|
m_samples_auxB_right, m_samples_auxB_surround}};
|
||||||
|
|
||||||
ReadPB(pb_addr, pb);
|
ReadPB(pb_addr, pb, m_crc);
|
||||||
|
|
||||||
u32 updates_addr = HILO_TO_32(pb.updates.data);
|
u32 updates_addr = HILO_TO_32(pb.updates.data);
|
||||||
u16* updates = (u16*)HLEMemory_Get_Pointer(updates_addr);
|
u16* updates = (u16*)HLEMemory_Get_Pointer(updates_addr);
|
||||||
|
@ -439,7 +439,7 @@ void AXUCode::ProcessPBList(u32 pb_addr)
|
||||||
buffers.ptrs[i] += spms;
|
buffers.ptrs[i] += spms;
|
||||||
}
|
}
|
||||||
|
|
||||||
WritePB(pb_addr, pb);
|
WritePB(pb_addr, pb, m_crc);
|
||||||
pb_addr = HILO_TO_32(pb.next_pb);
|
pb_addr = HILO_TO_32(pb.next_pb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -252,9 +252,10 @@ struct AXPB
|
||||||
PBADPCMInfo adpcm;
|
PBADPCMInfo adpcm;
|
||||||
PBSampleRateConverter src;
|
PBSampleRateConverter src;
|
||||||
PBADPCMLoopInfo adpcm_loop_info;
|
PBADPCMLoopInfo adpcm_loop_info;
|
||||||
PBLowPassFilter lpf;
|
PBLowPassFilter lpf; // Skipped when writing to/reading from MRAM/ARAM for certain AX UCodes
|
||||||
|
u16 loop_counter;
|
||||||
|
|
||||||
u16 padding[25];
|
u16 padding[24];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PBBiquadFilter
|
struct PBBiquadFilter
|
||||||
|
|
|
@ -80,19 +80,64 @@ union AXBuffers
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Determines if this version of the UCode has a PBLowPassFilter in its AXPB layout.
|
||||||
|
bool HasLpf(u32 crc)
|
||||||
|
{
|
||||||
|
switch (crc)
|
||||||
|
{
|
||||||
|
case 0x4E8A8B21:
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Read a PB from MRAM/ARAM
|
// Read a PB from MRAM/ARAM
|
||||||
void ReadPB(u32 addr, PB_TYPE& pb)
|
void ReadPB(u32 addr, PB_TYPE& pb, u32 crc)
|
||||||
|
{
|
||||||
|
if (HasLpf(crc))
|
||||||
{
|
{
|
||||||
u16* dst = (u16*)&pb;
|
u16* dst = (u16*)&pb;
|
||||||
Memory::CopyFromEmuSwapped<u16>(dst, addr, sizeof(pb));
|
Memory::CopyFromEmuSwapped<u16>(dst, addr, sizeof(pb));
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// The below is a terrible hack in order to support two different AXPB layouts.
|
||||||
|
// We skip lpf in this layout.
|
||||||
|
|
||||||
|
char* dst = (char*)&pb;
|
||||||
|
|
||||||
|
constexpr size_t lpf_off = offsetof(AXPB, lpf);
|
||||||
|
constexpr size_t lc_off = offsetof(AXPB, loop_counter);
|
||||||
|
|
||||||
|
Memory::CopyFromEmuSwapped<u16>((u16*)dst, addr, lpf_off);
|
||||||
|
memset(dst + lpf_off, 0, lc_off - lpf_off);
|
||||||
|
Memory::CopyFromEmuSwapped<u16>((u16*)(dst + lc_off), addr + lpf_off, sizeof(pb) - lc_off);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Write a PB back to MRAM/ARAM
|
// Write a PB back to MRAM/ARAM
|
||||||
void WritePB(u32 addr, const PB_TYPE& pb)
|
void WritePB(u32 addr, const PB_TYPE& pb, u32 crc)
|
||||||
|
{
|
||||||
|
if (HasLpf(crc))
|
||||||
{
|
{
|
||||||
const u16* src = (const u16*)&pb;
|
const u16* src = (const u16*)&pb;
|
||||||
Memory::CopyToEmuSwapped<u16>(addr, src, sizeof(pb));
|
Memory::CopyToEmuSwapped<u16>(addr, src, sizeof(pb));
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// The below is a terrible hack in order to support two different AXPB layouts.
|
||||||
|
// We skip lpf in this layout.
|
||||||
|
|
||||||
|
const char* src = (const char*)&pb;
|
||||||
|
|
||||||
|
constexpr size_t lpf_off = offsetof(AXPB, lpf);
|
||||||
|
constexpr size_t lc_off = offsetof(AXPB, loop_counter);
|
||||||
|
|
||||||
|
Memory::CopyToEmuSwapped<u16>(addr, (const u16*)src, lpf_off);
|
||||||
|
Memory::CopyToEmuSwapped<u16>(addr + lpf_off, (const u16*)(src + lc_off), sizeof(pb) - lc_off);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
// Dump the value of a PB for debugging
|
// Dump the value of a PB for debugging
|
||||||
|
@ -234,6 +279,13 @@ u16 AcceleratorGetSample()
|
||||||
acc_pb->adpcm.yn1 = acc_pb->adpcm_loop_info.yn1;
|
acc_pb->adpcm.yn1 = acc_pb->adpcm_loop_info.yn1;
|
||||||
acc_pb->adpcm.yn2 = acc_pb->adpcm_loop_info.yn2;
|
acc_pb->adpcm.yn2 = acc_pb->adpcm_loop_info.yn2;
|
||||||
}
|
}
|
||||||
|
#ifdef AX_GC
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If we're streaming, increment the loop counter.
|
||||||
|
acc_pb->loop_counter++;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -451,7 +451,7 @@ void AXWiiUCode::ProcessPBList(u32 pb_addr)
|
||||||
m_samples_aux1, m_samples_wm2, m_samples_aux2,
|
m_samples_aux1, m_samples_wm2, m_samples_aux2,
|
||||||
m_samples_wm3, m_samples_aux3}};
|
m_samples_wm3, m_samples_aux3}};
|
||||||
|
|
||||||
ReadPB(pb_addr, pb);
|
ReadPB(pb_addr, pb, m_crc);
|
||||||
|
|
||||||
u16 num_updates[3];
|
u16 num_updates[3];
|
||||||
u16 updates[1024];
|
u16 updates[1024];
|
||||||
|
@ -476,7 +476,7 @@ void AXWiiUCode::ProcessPBList(u32 pb_addr)
|
||||||
m_coeffs_available ? m_coeffs : nullptr);
|
m_coeffs_available ? m_coeffs : nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
WritePB(pb_addr, pb);
|
WritePB(pb_addr, pb, m_crc);
|
||||||
pb_addr = HILO_TO_32(pb.next_pb);
|
pb_addr = HILO_TO_32(pb.next_pb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue