void CUCode_AXWii::HandleCommandList() { // Temp variables for addresses computation u16 addr_hi, addr_lo; u16 addr2_hi, addr2_lo; u16 volume; u32 pb_addr = 0; // WARN_LOG(DSPHLE, "Command list:"); // for (u32 i = 0; m_cmdlist[i] != CMD_END; ++i) // WARN_LOG(DSPHLE, "%04x", m_cmdlist[i]); // WARN_LOG(DSPHLE, "-------------"); u32 curr_idx = 0; bool end = false; while (!end) { u16 cmd = m_cmdlist[curr_idx++]; if (m_old_axwii) { switch (cmd) { // Some of these commands are unknown, or unused in this AX HLE. // We still need to skip their arguments using "curr_idx += N". case CMD_SETUP_OLD: addr_hi = m_cmdlist[curr_idx++]; addr_lo = m_cmdlist[curr_idx++]; SetupProcessing(HILO_TO_32(addr)); break; case CMD_ADD_TO_LR_OLD: case CMD_SUB_TO_LR_OLD: addr_hi = m_cmdlist[curr_idx++]; addr_lo = m_cmdlist[curr_idx++]; AddToLR(HILO_TO_32(addr), cmd == CMD_SUB_TO_LR_OLD); break; case CMD_ADD_SUB_TO_LR_OLD: addr_hi = m_cmdlist[curr_idx++]; addr_lo = m_cmdlist[curr_idx++]; AddSubToLR(HILO_TO_32(addr)); break; case CMD_PB_ADDR_OLD: addr_hi = m_cmdlist[curr_idx++]; addr_lo = m_cmdlist[curr_idx++]; pb_addr = HILO_TO_32(addr); break; case CMD_PROCESS_OLD: ProcessPBList(pb_addr); break; case CMD_MIX_AUXA_OLD: case CMD_MIX_AUXB_OLD: case CMD_MIX_AUXC_OLD: volume = m_cmdlist[curr_idx++]; addr_hi = m_cmdlist[curr_idx++]; addr_lo = m_cmdlist[curr_idx++]; addr2_hi = m_cmdlist[curr_idx++]; addr2_lo = m_cmdlist[curr_idx++]; MixAUXSamples(cmd - CMD_MIX_AUXA_OLD, HILO_TO_32(addr), HILO_TO_32(addr2), volume); 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. case CMD_UNK_0B_OLD: curr_idx += 4; break; case CMD_OUTPUT_OLD: case CMD_OUTPUT_DPL2_OLD: addr_hi = m_cmdlist[curr_idx++]; addr_lo = m_cmdlist[curr_idx++]; addr2_hi = m_cmdlist[curr_idx++]; addr2_lo = m_cmdlist[curr_idx++]; OutputSamples(HILO_TO_32(addr2), HILO_TO_32(addr), 0x8000, cmd == CMD_OUTPUT_DPL2_OLD); break; case CMD_WM_OUTPUT_OLD: { u32 addresses[4] = { (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], }; curr_idx += 8; OutputWMSamples(addresses); break; } case CMD_END_OLD: end = true; break; } } else { switch (cmd) { // Some of these commands are unknown, or unused in this AX HLE. // We still need to skip their arguments using "curr_idx += N". case CMD_SETUP: addr_hi = m_cmdlist[curr_idx++]; addr_lo = m_cmdlist[curr_idx++]; SetupProcessing(HILO_TO_32(addr)); break; case CMD_ADD_TO_LR: case CMD_SUB_TO_LR: addr_hi = m_cmdlist[curr_idx++]; addr_lo = m_cmdlist[curr_idx++]; AddToLR(HILO_TO_32(addr), cmd == CMD_SUB_TO_LR); break; case CMD_ADD_SUB_TO_LR: addr_hi = m_cmdlist[curr_idx++]; addr_lo = m_cmdlist[curr_idx++]; AddSubToLR(HILO_TO_32(addr)); break; case CMD_PROCESS: addr_hi = m_cmdlist[curr_idx++]; addr_lo = m_cmdlist[curr_idx++]; ProcessPBList(HILO_TO_32(addr)); break; case CMD_MIX_AUXA: case CMD_MIX_AUXB: case CMD_MIX_AUXC: volume = m_cmdlist[curr_idx++]; addr_hi = m_cmdlist[curr_idx++]; addr_lo = m_cmdlist[curr_idx++]; addr2_hi = m_cmdlist[curr_idx++]; addr2_lo = m_cmdlist[curr_idx++]; MixAUXSamples(cmd - CMD_MIX_AUXA, HILO_TO_32(addr), HILO_TO_32(addr2), volume); 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. case CMD_UNK_0A: curr_idx += 4; break; case CMD_OUTPUT: case CMD_OUTPUT_DPL2: volume = m_cmdlist[curr_idx++]; addr_hi = m_cmdlist[curr_idx++]; addr_lo = m_cmdlist[curr_idx++]; addr2_hi = m_cmdlist[curr_idx++]; addr2_lo = m_cmdlist[curr_idx++]; OutputSamples(HILO_TO_32(addr2), HILO_TO_32(addr), volume, cmd == CMD_OUTPUT_DPL2); break; case CMD_WM_OUTPUT: { u32 addresses[4] = { (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], }; curr_idx += 8; OutputWMSamples(addresses); break; } case CMD_END: end = true; break; } } } }
void CUCode_AXWii::ProcessPBList(u32 pb_addr) { AXPBWii pb; while (pb_addr) { AXBuffers buffers = {{ m_samples_left, m_samples_right, m_samples_surround, m_samples_auxA_left, m_samples_auxA_right, m_samples_auxA_surround, m_samples_auxB_left, m_samples_auxB_right, m_samples_auxB_surround, m_samples_auxC_left, m_samples_auxC_right, m_samples_auxC_surround, m_samples_wm0, m_samples_aux0, m_samples_wm1, m_samples_aux1, m_samples_wm2, m_samples_aux2, m_samples_wm3, m_samples_aux3 }}; if (!ReadPB(pb_addr, pb)) break; u16 num_updates[3]; u16 updates[1024]; u32 updates_addr; if (ExtractUpdatesFields(pb, num_updates, updates, &updates_addr)) { for (int curr_ms = 0; curr_ms < 3; ++curr_ms) { ApplyUpdatesForMs(curr_ms, (u16*)&pb, num_updates, updates); ProcessVoice(pb, buffers, 32, ConvertMixerControl(HILO_TO_32(pb.mixer_control)), m_coeffs_available ? m_coeffs : NULL); // Forward the buffers for (u32 i = 0; i < sizeof (buffers.ptrs) / sizeof (buffers.ptrs[0]); ++i) buffers.ptrs[i] += 32; } ReinjectUpdatesFields(pb, num_updates, updates_addr); } else { ProcessVoice(pb, buffers, 96, ConvertMixerControl(HILO_TO_32(pb.mixer_control)), m_coeffs_available ? m_coeffs : NULL); } WritePB(pb_addr, pb); pb_addr = HILO_TO_32(pb.next_pb); } }
void CUCode_AX::HandleCommandList() { // Temp variables for addresses computation u16 addr_hi, addr_lo; u16 addr2_hi, addr2_lo; u16 size; u32 pb_addr = 0; #if 0 WARN_LOG(DSPHLE, "Command list:"); for (u32 i = 0; m_cmdlist[i] != CMD_END; ++i) WARN_LOG(DSPHLE, "%04x", m_cmdlist[i]); WARN_LOG(DSPHLE, "-------------"); #endif u32 curr_idx = 0; bool end = false; while (!end) { u16 cmd = m_cmdlist[curr_idx++]; switch (cmd) { // Some of these commands are unknown, or unused in this AX HLE. // We still need to skip their arguments using "curr_idx += N". case CMD_SETUP: addr_hi = m_cmdlist[curr_idx++]; addr_lo = m_cmdlist[curr_idx++]; SetupProcessing(HILO_TO_32(addr)); break; case CMD_DL_AND_VOL_MIX: { addr_hi = m_cmdlist[curr_idx++]; addr_lo = m_cmdlist[curr_idx++]; u16 vol_main = m_cmdlist[curr_idx++]; u16 vol_auxa = m_cmdlist[curr_idx++]; u16 vol_auxb = m_cmdlist[curr_idx++]; DownloadAndMixWithVolume(HILO_TO_32(addr), vol_main, vol_auxa, vol_auxb); break; } case CMD_PB_ADDR: addr_hi = m_cmdlist[curr_idx++]; addr_lo = m_cmdlist[curr_idx++]; pb_addr = HILO_TO_32(addr); break; case CMD_PROCESS: ProcessPBList(pb_addr); break; case CMD_MIX_AUXA: case CMD_MIX_AUXB: // These two commands are handled almost the same internally. addr_hi = m_cmdlist[curr_idx++]; addr_lo = m_cmdlist[curr_idx++]; addr2_hi = m_cmdlist[curr_idx++]; addr2_lo = m_cmdlist[curr_idx++]; MixAUXSamples(cmd - CMD_MIX_AUXA, HILO_TO_32(addr), HILO_TO_32(addr2)); break; case CMD_UPLOAD_LRS: addr_hi = m_cmdlist[curr_idx++]; addr_lo = m_cmdlist[curr_idx++]; UploadLRS(HILO_TO_32(addr)); break; case CMD_SET_LR: addr_hi = m_cmdlist[curr_idx++]; addr_lo = m_cmdlist[curr_idx++]; SetMainLR(HILO_TO_32(addr)); break; case CMD_UNK_08: curr_idx += 10; break; // TODO: check case CMD_MIX_AUXB_NOWRITE: addr_hi = m_cmdlist[curr_idx++]; addr_lo = m_cmdlist[curr_idx++]; MixAUXSamples(false, 0, HILO_TO_32(addr)); break; case CMD_COMPRESSOR_TABLE_ADDR: curr_idx += 2; break; case CMD_UNK_0B: break; // TODO: check other versions case CMD_UNK_0C: break; // TODO: check other versions case CMD_MORE: addr_hi = m_cmdlist[curr_idx++]; addr_lo = m_cmdlist[curr_idx++]; size = m_cmdlist[curr_idx++]; CopyCmdList(HILO_TO_32(addr), size); curr_idx = 0; break; case CMD_OUTPUT: addr_hi = m_cmdlist[curr_idx++]; addr_lo = m_cmdlist[curr_idx++]; addr2_hi = m_cmdlist[curr_idx++]; addr2_lo = m_cmdlist[curr_idx++]; OutputSamples(HILO_TO_32(addr2), HILO_TO_32(addr)); break; case CMD_END: end = true; break; case CMD_MIX_AUXB_LR: addr_hi = m_cmdlist[curr_idx++]; addr_lo = m_cmdlist[curr_idx++]; addr2_hi = m_cmdlist[curr_idx++]; addr2_lo = m_cmdlist[curr_idx++]; MixAUXBLR(HILO_TO_32(addr), HILO_TO_32(addr2)); break; case CMD_UNK_11: curr_idx += 2; break; case CMD_UNK_12: { u16 samp_val = m_cmdlist[curr_idx++]; u16 idx = m_cmdlist[curr_idx++]; addr_hi = m_cmdlist[curr_idx++]; addr_lo = m_cmdlist[curr_idx++]; // TODO (void)samp_val; (void)idx; break; } // Send the contents of MAIN LRS, AUXA LRS and AUXB S to RAM, and // mix data to MAIN LR and AUXB LR. case CMD_SEND_AUX_AND_MIX: { // Address for Main + AUXA LRS upload u16 main_auxa_up_hi = m_cmdlist[curr_idx++]; u16 main_auxa_up_lo = m_cmdlist[curr_idx++]; // Address for AUXB S upload u16 auxb_s_up_hi = m_cmdlist[curr_idx++]; u16 auxb_s_up_lo = m_cmdlist[curr_idx++]; // Address to read data for Main L u16 main_l_dl_hi = m_cmdlist[curr_idx++]; u16 main_l_dl_lo = m_cmdlist[curr_idx++]; // Address to read data for Main R u16 main_r_dl_hi = m_cmdlist[curr_idx++]; u16 main_r_dl_lo = m_cmdlist[curr_idx++]; // Address to read data for AUXB L u16 auxb_l_dl_hi = m_cmdlist[curr_idx++]; u16 auxb_l_dl_lo = m_cmdlist[curr_idx++]; // Address to read data for AUXB R u16 auxb_r_dl_hi = m_cmdlist[curr_idx++]; u16 auxb_r_dl_lo = m_cmdlist[curr_idx++]; SendAUXAndMix(HILO_TO_32(main_auxa_up), HILO_TO_32(auxb_s_up), HILO_TO_32(main_l_dl), HILO_TO_32(main_r_dl), HILO_TO_32(auxb_l_dl), HILO_TO_32(auxb_r_dl)); break; } default: ERROR_LOG(DSPHLE, "Unknown command in AX cmdlist: %04x", cmd); end = true; break; } } }