Implement AXWii commands 08/09, aka. "upload AUXA/AUXB and use it as a temp buffer to mix to MAIN L/R/S and AUXC L", aka. "what the fuck were they thinking?!"

This commit is contained in:
Pierre Bourdon 2013-04-02 04:12:17 +02:00
parent 0220fd1940
commit 6e708005df
2 changed files with 81 additions and 10 deletions

View File

@ -110,9 +110,22 @@ void CUCode_AXWii::HandleCommandList()
MixAUXSamples(cmd - CMD_MIX_AUXA_OLD, HILO_TO_32(addr), HILO_TO_32(addr2), volume);
break;
// These two go together and manipulate some AUX buffers.
case CMD_UNK_09_OLD: curr_idx += 13; break;
case CMD_UNK_0A_OLD: curr_idx += 13; break;
case CMD_UPL_AUXA_MIX_LRSC_OLD:
case CMD_UPL_AUXB_MIX_LRSC_OLD:
{
volume = m_cmdlist[curr_idx++];
u32 addresses[6] = {
(u32)(m_cmdlist[curr_idx + 0] << 16) | m_cmdlist[curr_idx + 1],
(u32)(m_cmdlist[curr_idx + 2] << 16) | m_cmdlist[curr_idx + 3],
(u32)(m_cmdlist[curr_idx + 4] << 16) | m_cmdlist[curr_idx + 5],
(u32)(m_cmdlist[curr_idx + 6] << 16) | m_cmdlist[curr_idx + 7],
(u32)(m_cmdlist[curr_idx + 8] << 16) | m_cmdlist[curr_idx + 9],
(u32)(m_cmdlist[curr_idx + 10] << 16) | m_cmdlist[curr_idx + 11],
};
curr_idx += 12;
UploadAUXMixLRSC(cmd == CMD_UPL_AUXB_MIX_LRSC_OLD, addresses, volume);
break;
}
// TODO(delroth): figure this one out, it's used by almost every
// game I've tested so far.
@ -189,9 +202,22 @@ void CUCode_AXWii::HandleCommandList()
MixAUXSamples(cmd - CMD_MIX_AUXA, HILO_TO_32(addr), HILO_TO_32(addr2), volume);
break;
// These two go together and manipulate some AUX buffers.
case CMD_UNK_08: curr_idx += 13; break;
case CMD_UNK_09: curr_idx += 13; break;
case CMD_UPL_AUXA_MIX_LRSC:
case CMD_UPL_AUXB_MIX_LRSC:
{
volume = m_cmdlist[curr_idx++];
u32 addresses[6] = {
(u32)(m_cmdlist[curr_idx + 0] << 16) | m_cmdlist[curr_idx + 1],
(u32)(m_cmdlist[curr_idx + 2] << 16) | m_cmdlist[curr_idx + 3],
(u32)(m_cmdlist[curr_idx + 4] << 16) | m_cmdlist[curr_idx + 5],
(u32)(m_cmdlist[curr_idx + 6] << 16) | m_cmdlist[curr_idx + 7],
(u32)(m_cmdlist[curr_idx + 8] << 16) | m_cmdlist[curr_idx + 9],
(u32)(m_cmdlist[curr_idx + 10] << 16) | m_cmdlist[curr_idx + 11],
};
curr_idx += 12;
UploadAUXMixLRSC(cmd == CMD_UPL_AUXB_MIX_LRSC, addresses, volume);
break;
}
// TODO(delroth): figure this one out, it's used by almost every
// game I've tested so far.
@ -524,6 +550,50 @@ void CUCode_AXWii::MixAUXSamples(int aux_id, u32 write_addr, u32 read_addr, u16
}
}
void CUCode_AXWii::UploadAUXMixLRSC(int aux_id, u32* addresses, u16 volume)
{
int* aux_left = aux_id ? m_samples_auxB_left : m_samples_auxA_left;
int* aux_right = aux_id ? m_samples_auxB_right : m_samples_auxA_right;
int* aux_surround = aux_id ? m_samples_auxB_surround : m_samples_auxA_surround;
int* auxc_buffer = aux_id ? m_samples_auxC_surround : m_samples_auxC_right;
int* upload_ptr = (int*)HLEMemory_Get_Pointer(addresses[0]);
for (u32 i = 0; i < 96; ++i)
*upload_ptr++ = Common::swap32(aux_left[i]);
for (u32 i = 0; i < 96; ++i)
*upload_ptr++ = Common::swap32(aux_right[i]);
for (u32 i = 0; i < 96; ++i)
*upload_ptr++ = Common::swap32(aux_surround[i]);
upload_ptr = (int*)HLEMemory_Get_Pointer(addresses[1]);
for (u32 i = 0; i < 96; ++i)
*upload_ptr++ = Common::swap32(auxc_buffer[i]);
u16 volume_ramp[96];
GenerateVolumeRamp(volume_ramp, m_last_aux_volumes[aux_id], volume, 96);
m_last_aux_volumes[aux_id] = volume;
int* mix_dest[4] = {
m_samples_left,
m_samples_right,
m_samples_surround,
m_samples_auxC_left
};
for (u32 mix_i = 0; mix_i < 4; ++mix_i)
{
int* dl_ptr = (int*)HLEMemory_Get_Pointer(addresses[2 + mix_i]);
for (u32 i = 0; i < 96; ++i)
aux_left[i] = Common::swap32(dl_ptr[i]);
for (u32 i = 0; i < 96; ++i)
{
s64 sample = (s64)(s32)aux_left[i];
sample *= volume_ramp[i];
mix_dest[mix_i][i] += (s32)(sample >> 15);
}
}
}
void CUCode_AXWii::OutputSamples(u32 lr_addr, u32 surround_addr, u16 volume,
bool upload_auxc)
{

View File

@ -75,6 +75,7 @@ protected:
void AddSubToLR(u32 val_addr);
void ProcessPBList(u32 pb_addr);
void MixAUXSamples(int aux_id, u32 write_addr, u32 read_addr, u16 volume);
void UploadAUXMixLRSC(int aux_id, u32* addresses, u16 volume);
void OutputSamples(u32 lr_addr, u32 surround_addr, u16 volume,
bool upload_auxc);
void OutputWMSamples(u32* addresses); // 4 addresses
@ -90,8 +91,8 @@ private:
CMD_MIX_AUXA = 0x05,
CMD_MIX_AUXB = 0x06,
CMD_MIX_AUXC = 0x07,
CMD_UNK_08 = 0x08,
CMD_UNK_09 = 0x09,
CMD_UPL_AUXA_MIX_LRSC = 0x08,
CMD_UPL_AUXB_MIX_LRSC = 0x09,
CMD_UNK_0A = 0x0A,
CMD_OUTPUT = 0x0B,
CMD_OUTPUT_DPL2 = 0x0C,
@ -113,8 +114,8 @@ private:
CMD_MIX_AUXA_OLD = 0x06,
CMD_MIX_AUXB_OLD = 0x07,
CMD_MIX_AUXC_OLD = 0x08,
CMD_UNK_09_OLD = 0x09,
CMD_UNK_0A_OLD = 0x0A,
CMD_UPL_AUXA_MIX_LRSC_OLD = 0x09,
CMD_UPL_AUXB_MIX_LRSC_OLD = 0x0a,
CMD_UNK_0B_OLD = 0x0B,
CMD_OUTPUT_OLD = 0x0C, // no volume!
CMD_OUTPUT_DPL2_OLD = 0x0D,