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);
|
return new AXUCode(dsphle, crc);
|
||||||
|
|
||||||
case 0x86840740: // Zelda WW - US
|
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);
|
return new ZeldaUCode(dsphle, crc);
|
||||||
|
|
||||||
case 0x2ea36ce6: // Some Wii demos
|
case 0x2ea36ce6: // Some Wii demos
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
// * Mario Kart: Double Dash!! (type ????, CRC ????)
|
// * Mario Kart: Double Dash!! (type ????, CRC ????)
|
||||||
// * Pikmin (type ????, CRC ????)
|
// * Pikmin (type ????, CRC ????)
|
||||||
// * Pikmin 2 (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 Galaxy 2 (type ????, CRC ????)
|
||||||
// * Super Mario Sunshine (type ????, CRC ????)
|
// * Super Mario Sunshine (type ????, CRC ????)
|
||||||
// * The Legend of Zelda: Four Swords Adventures (type ????, CRC ????)
|
// * The Legend of Zelda: Four Swords Adventures (type ????, CRC ????)
|
||||||
|
@ -191,7 +191,6 @@ void ZeldaUCode::RunPendingCommands()
|
||||||
case 0x0A:
|
case 0x0A:
|
||||||
case 0x0B:
|
case 0x0B:
|
||||||
case 0x0C:
|
case 0x0C:
|
||||||
case 0x0E:
|
|
||||||
case 0x0F:
|
case 0x0F:
|
||||||
// NOP commands. Log anyway in case we encounter a new version
|
// NOP commands. Log anyway in case we encounter a new version
|
||||||
// where these are not NOPs anymore.
|
// where these are not NOPs anymore.
|
||||||
|
@ -268,6 +267,16 @@ void ZeldaUCode::RunPendingCommands()
|
||||||
SendCommandAck(CommandAck::STANDARD, sync);
|
SendCommandAck(CommandAck::STANDARD, sync);
|
||||||
break;
|
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:
|
default:
|
||||||
NOTICE_LOG(DSPHLE, "Received a non-existing command (%d), halting.", command);
|
NOTICE_LOG(DSPHLE, "Received a non-existing command (%d), halting.", command);
|
||||||
SetMailState(MailState::HALTED);
|
SetMailState(MailState::HALTED);
|
||||||
|
@ -1066,6 +1075,14 @@ void ZeldaAudioRenderer::Resample(VPB* vpb, const s16* src, MixingBuffer* dst)
|
||||||
vpb->current_pos_frac = pos & 0xFFF;
|
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(
|
void ZeldaAudioRenderer::DownloadPCM8SamplesFromARAM(
|
||||||
s16* dst, VPB* vpb, u16 requested_samples_count)
|
s16* dst, VPB* vpb, u16 requested_samples_count)
|
||||||
{
|
{
|
||||||
|
@ -1100,7 +1117,7 @@ void ZeldaAudioRenderer::DownloadPCM8SamplesFromARAM(
|
||||||
vpb->SetCurrentARAMAddr(
|
vpb->SetCurrentARAMAddr(
|
||||||
vpb->GetBaseAddress() + vpb->GetCurrentPosition());
|
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(),
|
u16 samples_to_download = std::min(vpb->GetRemainingLength(),
|
||||||
(u32)requested_samples_count);
|
(u32)requested_samples_count);
|
||||||
|
|
||||||
|
@ -1230,7 +1247,7 @@ void ZeldaAudioRenderer::DownloadAFCSamplesFromARAM(
|
||||||
void ZeldaAudioRenderer::DecodeAFC(VPB* vpb, s16* dst, size_t block_count)
|
void ZeldaAudioRenderer::DecodeAFC(VPB* vpb, s16* dst, size_t block_count)
|
||||||
{
|
{
|
||||||
u32 addr = vpb->GetCurrentARAMAddr();
|
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);
|
vpb->SetCurrentARAMAddr(addr + (u32)block_count * vpb->samples_source_type);
|
||||||
|
|
||||||
for (size_t b = 0; b < block_count; ++b)
|
for (size_t b = 0; b < block_count; ++b)
|
||||||
|
|
|
@ -24,6 +24,7 @@ public:
|
||||||
void SetOutputVolume(u16 volume) { m_output_volume = volume; }
|
void SetOutputVolume(u16 volume) { m_output_volume = volume; }
|
||||||
void SetOutputLeftBufferAddr(u32 addr) { m_output_lbuf_addr = addr; }
|
void SetOutputLeftBufferAddr(u32 addr) { m_output_lbuf_addr = addr; }
|
||||||
void SetOutputRightBufferAddr(u32 addr) { m_output_rbuf_addr = addr; }
|
void SetOutputRightBufferAddr(u32 addr) { m_output_rbuf_addr = addr; }
|
||||||
|
void SetARAMBaseAddr(u32 addr) { m_aram_base_addr = addr; }
|
||||||
|
|
||||||
void DoState(PointerWrap& p);
|
void DoState(PointerWrap& p);
|
||||||
|
|
||||||
|
@ -144,6 +145,12 @@ private:
|
||||||
// Coefficients used for resampling.
|
// Coefficients used for resampling.
|
||||||
std::array<s16, 0x100> m_resampling_coeffs{};
|
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
|
// Downloads PCM8 encoded samples from ARAM. Handles looping and other
|
||||||
// parameters appropriately.
|
// parameters appropriately.
|
||||||
void DownloadPCM8SamplesFromARAM(s16* dst, VPB* vpb, u16 requested_samples_count);
|
void DownloadPCM8SamplesFromARAM(s16* dst, VPB* vpb, u16 requested_samples_count);
|
||||||
|
@ -182,6 +189,11 @@ public:
|
||||||
|
|
||||||
void DoState(PointerWrap &p) override;
|
void DoState(PointerWrap &p) override;
|
||||||
|
|
||||||
|
bool IsWiiDAC() const
|
||||||
|
{
|
||||||
|
return m_crc == 0xd643001f;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// UCode state machine. The control flow in the Zelda UCode family is quite
|
// UCode state machine. The control flow in the Zelda UCode family is quite
|
||||||
// complex, using interrupt handlers heavily to handle incoming messages
|
// complex, using interrupt handlers heavily to handle incoming messages
|
||||||
|
|
Loading…
Reference in New Issue