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:
Pierre Bourdon 2014-12-21 18:45:34 +01:00
parent ea1ac5f596
commit 0dc5a925b0
3 changed files with 35 additions and 5 deletions

View File

@ -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

View File

@ -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)

View File

@ -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