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:
parent
4ace79024d
commit
1807c113b5
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue