Zelda HLE: Add initial support for Wii DAC and SMG1.
SMG1 boots but quickly PanicAlerts due to an unimplemented sample source.
This commit is contained in:
parent
ea1ac5f596
commit
0dc5a925b0
|
@ -53,7 +53,8 @@ UCodeInterface* UCodeFactory(u32 crc, DSPHLE* dsphle, bool wii)
|
|||
return new AXUCode(dsphle, crc);
|
||||
|
||||
case 0x86840740: // Zelda WW - US
|
||||
case 0x6CA33A6D: // Zelda TP GC - US
|
||||
case 0x6ca33a6d: // Zelda TP GC - US
|
||||
case 0xd643001f: // Super Mario Galaxy - US
|
||||
return new ZeldaUCode(dsphle, crc);
|
||||
|
||||
case 0x2ea36ce6: // Some Wii demos
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
// * Mario Kart: Double Dash!! (type ????, CRC ????)
|
||||
// * Pikmin (type ????, CRC ????)
|
||||
// * Pikmin 2 (type ????, CRC ????)
|
||||
// * Super Mario Galaxy (type ????, CRC ????)
|
||||
// * Super Mario Galaxy (type Wii-DAC, CRC D643001F)
|
||||
// * Super Mario Galaxy 2 (type ????, CRC ????)
|
||||
// * Super Mario Sunshine (type ????, CRC ????)
|
||||
// * The Legend of Zelda: Four Swords Adventures (type ????, CRC ????)
|
||||
|
@ -191,7 +191,6 @@ void ZeldaUCode::RunPendingCommands()
|
|||
case 0x0A:
|
||||
case 0x0B:
|
||||
case 0x0C:
|
||||
case 0x0E:
|
||||
case 0x0F:
|
||||
// NOP commands. Log anyway in case we encounter a new version
|
||||
// where these are not NOPs anymore.
|
||||
|
@ -268,6 +267,16 @@ void ZeldaUCode::RunPendingCommands()
|
|||
SendCommandAck(CommandAck::STANDARD, sync);
|
||||
break;
|
||||
|
||||
// Command 0E: Sets the base address of the ARAM for Wii UCodes. Used
|
||||
// because the Wii does not have an ARAM, so it simulates it with MRAM
|
||||
// and DMAs.
|
||||
case 0x0E:
|
||||
if (!IsWiiDAC())
|
||||
PanicAlert("Setting base ARAM addr on non Wii DAC.");
|
||||
m_renderer.SetARAMBaseAddr(Read32());
|
||||
SendCommandAck(CommandAck::STANDARD, sync);
|
||||
break;
|
||||
|
||||
default:
|
||||
NOTICE_LOG(DSPHLE, "Received a non-existing command (%d), halting.", command);
|
||||
SetMailState(MailState::HALTED);
|
||||
|
@ -1066,6 +1075,14 @@ void ZeldaAudioRenderer::Resample(VPB* vpb, const s16* src, MixingBuffer* dst)
|
|||
vpb->current_pos_frac = pos & 0xFFF;
|
||||
}
|
||||
|
||||
void* ZeldaAudioRenderer::GetARAMPtr() const
|
||||
{
|
||||
if (m_aram_base_addr)
|
||||
return HLEMemory_Get_Pointer(m_aram_base_addr);
|
||||
else
|
||||
return DSP::GetARAMPtr();
|
||||
}
|
||||
|
||||
void ZeldaAudioRenderer::DownloadPCM8SamplesFromARAM(
|
||||
s16* dst, VPB* vpb, u16 requested_samples_count)
|
||||
{
|
||||
|
@ -1100,7 +1117,7 @@ void ZeldaAudioRenderer::DownloadPCM8SamplesFromARAM(
|
|||
vpb->SetCurrentARAMAddr(
|
||||
vpb->GetBaseAddress() + vpb->GetCurrentPosition());
|
||||
|
||||
s8* src_ptr = (s8*)DSP::GetARAMPtr() + vpb->GetCurrentARAMAddr();
|
||||
s8* src_ptr = (s8*)GetARAMPtr() + vpb->GetCurrentARAMAddr();
|
||||
u16 samples_to_download = std::min(vpb->GetRemainingLength(),
|
||||
(u32)requested_samples_count);
|
||||
|
||||
|
@ -1230,7 +1247,7 @@ void ZeldaAudioRenderer::DownloadAFCSamplesFromARAM(
|
|||
void ZeldaAudioRenderer::DecodeAFC(VPB* vpb, s16* dst, size_t block_count)
|
||||
{
|
||||
u32 addr = vpb->GetCurrentARAMAddr();
|
||||
u8* src = (u8*)DSP::GetARAMPtr() + addr;
|
||||
u8* src = (u8*)GetARAMPtr() + addr;
|
||||
vpb->SetCurrentARAMAddr(addr + (u32)block_count * vpb->samples_source_type);
|
||||
|
||||
for (size_t b = 0; b < block_count; ++b)
|
||||
|
|
|
@ -24,6 +24,7 @@ public:
|
|||
void SetOutputVolume(u16 volume) { m_output_volume = volume; }
|
||||
void SetOutputLeftBufferAddr(u32 addr) { m_output_lbuf_addr = addr; }
|
||||
void SetOutputRightBufferAddr(u32 addr) { m_output_rbuf_addr = addr; }
|
||||
void SetARAMBaseAddr(u32 addr) { m_aram_base_addr = addr; }
|
||||
|
||||
void DoState(PointerWrap& p);
|
||||
|
||||
|
@ -144,6 +145,12 @@ private:
|
|||
// Coefficients used for resampling.
|
||||
std::array<s16, 0x100> m_resampling_coeffs{};
|
||||
|
||||
// If non zero, base MRAM address for sound data transfers from ARAM. On
|
||||
// the Wii, this points to some MRAM location since there is no ARAM to be
|
||||
// used. If zero, use the top of ARAM.
|
||||
u32 m_aram_base_addr = 0;
|
||||
void* GetARAMPtr() const;
|
||||
|
||||
// Downloads PCM8 encoded samples from ARAM. Handles looping and other
|
||||
// parameters appropriately.
|
||||
void DownloadPCM8SamplesFromARAM(s16* dst, VPB* vpb, u16 requested_samples_count);
|
||||
|
@ -182,6 +189,11 @@ public:
|
|||
|
||||
void DoState(PointerWrap &p) override;
|
||||
|
||||
bool IsWiiDAC() const
|
||||
{
|
||||
return m_crc == 0xd643001f;
|
||||
}
|
||||
|
||||
private:
|
||||
// UCode state machine. The control flow in the Zelda UCode family is quite
|
||||
// complex, using interrupt handlers heavily to handle incoming messages
|
||||
|
|
Loading…
Reference in New Issue