Zelda HLE: Support both NTSC and PAL IPL.

Add a flag for UCodes that only have four non-Dolby mixing destinations
(instead of the standard six destinations).

NTSC IPL is still hopelessly broken.
This commit is contained in:
Pierre Bourdon 2014-12-22 06:20:48 +01:00
parent 4ace79024d
commit 1807c113b5
2 changed files with 22 additions and 14 deletions

View File

@ -55,7 +55,8 @@ UCodeInterface* UCodeFactory(u32 crc, DSPHLE* dsphle, bool wii)
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 case 0xd643001f: // Super Mario Galaxy - US
case 0x6ba3b3ea: // GC IPL - US case 0x6ba3b3ea: // GC IPL - PAL
case 0x24b22038: // GC IPL - US
return new ZeldaUCode(dsphle, crc); return new ZeldaUCode(dsphle, crc);
case 0x2ea36ce6: // Some Wii demos case 0x2ea36ce6: // Some Wii demos

View File

@ -23,6 +23,10 @@ enum ZeldaUCodeFlag
// Light version of the UCode: no Dolby mixing, different synchronization // Light version of the UCode: no Dolby mixing, different synchronization
// protocol, etc. // protocol, etc.
LIGHT_PROTOCOL = 0x00000004, LIGHT_PROTOCOL = 0x00000004,
// If set, only consider 4 of the 6 non-Dolby mixing outputs. Early
// versions of the Zelda UCode only had 4.
FOUR_MIXING_DESTS = 0x00000008,
}; };
static const std::map<u32, u32> UCODE_FLAGS = { static const std::map<u32, u32> UCODE_FLAGS = {
@ -32,8 +36,10 @@ static const std::map<u32, u32> UCODE_FLAGS = {
{ 0x6CA33A6D, MAKE_DOLBY_LOUDER }, { 0x6CA33A6D, MAKE_DOLBY_LOUDER },
// Super Mario Galaxy. // Super Mario Galaxy.
{ 0xD643001F, NO_ARAM | MAKE_DOLBY_LOUDER }, { 0xD643001F, NO_ARAM | MAKE_DOLBY_LOUDER },
// GameCube IPL/BIOS. // GameCube IPL/BIOS, PAL.
{ 0x6BA3B3EA, LIGHT_PROTOCOL }, { 0x6BA3B3EA, LIGHT_PROTOCOL | FOUR_MIXING_DESTS },
// GameCube IPL/BIOS, NTSC.
{ 0x24B22038, LIGHT_PROTOCOL | FOUR_MIXING_DESTS },
// TODO: Other games that use this UCode (exhaustive list): // TODO: Other games that use this UCode (exhaustive list):
// * Animal Crossing (type ????, CRC ????) // * Animal Crossing (type ????, CRC ????)
@ -973,44 +979,45 @@ void ZeldaAudioRenderer::AddVoice(u16 voice_id)
{ {
// TODO: Store input samples if requested by the VPB. // TODO: Store input samples if requested by the VPB.
int num_channels = (m_flags & FOUR_MIXING_DESTS) ? 4 : 6;
if (vpb.end_requested) if (vpb.end_requested)
{ {
bool all_mute = true; bool all_mute = true;
for (auto& channel : vpb.channels) for (int i = 0; i < num_channels; ++i)
{ {
channel.target_volume = channel.current_volume / 2; vpb.channels[i].target_volume = vpb.channels[i].current_volume / 2;
all_mute &= (channel.target_volume == 0); all_mute &= (vpb.channels[i].target_volume == 0);
} }
if (all_mute) if (all_mute)
vpb.done = true; vpb.done = true;
} }
for (auto& channel : vpb.channels) for (int i = 0; i < num_channels; ++i)
{ {
if (!channel.id) if (!vpb.channels[i].id)
continue; continue;
s16 volume_delta = channel.target_volume - channel.current_volume; s16 volume_delta = vpb.channels[i].target_volume - vpb.channels[i].current_volume;
s32 volume_step = (volume_delta << 16) / (s32)input_samples.size(); // In 1.31 format. s32 volume_step = (volume_delta << 16) / (s32)input_samples.size(); // In 1.31 format.
// TODO: The last value of each channel structure is used to // TODO: The last value of each channel structure is used to
// determine whether a channel should be skipped or not. Not // determine whether a channel should be skipped or not. Not
// implemented yet. // implemented yet.
if (!channel.current_volume && !volume_step) if (!vpb.channels[i].current_volume && !volume_step)
continue; continue;
MixingBuffer* dst_buffer = BufferForID(channel.id); MixingBuffer* dst_buffer = BufferForID(vpb.channels[i].id);
if (!dst_buffer) if (!dst_buffer)
{ {
PanicAlert("Mixing to an unmapped buffer: %04x", channel.id); PanicAlert("Mixing to an unmapped buffer: %04x", vpb.channels[i].id);
continue; continue;
} }
s32 new_volume = AddBuffersWithVolumeRamp( s32 new_volume = AddBuffersWithVolumeRamp(
dst_buffer, input_samples, channel.current_volume << 16, dst_buffer, input_samples, vpb.channels[i].current_volume << 16,
volume_step); volume_step);
channel.current_volume = new_volume >> 16; vpb.channels[i].current_volume = new_volume >> 16;
} }
} }