Files
2024-07-26 09:42:28 -04:00

806 lines
23 KiB
C++

#include "vag.h"
#include <cstring>
#include "common/log/log.h"
#include "common/util/Assert.h"
#include "game/overlord/jak2/iso_queue.h"
#include "game/overlord/jak2/spustreams.h"
#include "game/overlord/jak2/srpc.h"
#include "game/overlord/jak2/ssound.h"
#include "game/overlord/jak2/streamlist.h"
#include "game/sound/sdshim.h"
namespace jak2 {
VagCmd VagCmds[N_VAG_CMDS];
int StreamSRAM[N_VAG_CMDS];
int TrapSRAM[N_VAG_CMDS];
int StreamVoice[N_VAG_CMDS];
// sizes seem sketchy
// maybe pri 0 is a special 'free' priority.
VagCmdPriListEntry VagCmdsPriList[11];
int VagCmdsPriCounter[11];
int ActiveVagStreams;
void CalculateVAGVolumes(VagCmd* cmd, u32* l_out, u32* r_out);
void StopVAG(VagCmd* cmd, int /*param_2*/);
enum VolumeCategory {
DIALOGUE = 2, // VAG streams. Copied "dialogue" name from jak 1.
};
int MasterVolume[32];
void vag_init_globals() {
memset(VagCmds, 0, sizeof(VagCmds));
memset(StreamSRAM, 0, sizeof(StreamSRAM));
memset(TrapSRAM, 0, sizeof(TrapSRAM));
memset(StreamVoice, 0, sizeof(StreamVoice));
memset(VagCmdsPriList, 0, sizeof(VagCmdsPriList));
memset(VagCmdsPriCounter, 0, sizeof(VagCmdsPriCounter));
for (auto& x : MasterVolume) {
x = 0x400; // check!!!
}
ActiveVagStreams = 0;
}
void InitVagCmds() {
int cmd_idx = 0;
for (auto& cmd : VagCmds) {
for (auto& x : cmd.status_bytes) {
x = 0;
}
// puVar5 is offset 292
cmd.unk_236 = 0; // puVar5[-0xe] = 0;
cmd.unk_140 = 0; // puVar5[-0x26] = 0;
cmd.sb_paused = 1; // *(undefined*)((int)puVar5 + -0x52) = 1;
cmd.unk_196 = 0; // puVar5[-0x18] = 0;
cmd.unk_200 = 0; // puVar5[-0x17] = 0;
cmd.unk_204 = 0; // puVar5[-0x16] = 0;
cmd.unk_180 = 0; // puVar5[-0x1c] = 0;
cmd.unk_184 = 0; // puVar5[-0x1b] = 0;
cmd.unk_188 = 0; // puVar5[-0x1a] = 0;
cmd.unk_192 = 0; // puVar5[-0x19] = 0;
cmd.status_bytes[VagCmdByte::BYTE5] = 0; // *(undefined*)((int)puVar5 + -0x4f) = 0;
cmd.status_bytes[VagCmdByte::BYTE6] = 0; // *(undefined*)((int)puVar5 + -0x4e) = 0;
cmd.num_processed_chunks = 0; // puVar5[-0xd] = 0;
cmd.safe_to_change_dma_fields = 1; // puVar5[-0x3a] = 1;
cmd.xfer_size = 0; // puVar5[-0xc] = 0;
cmd.sample_rate = 0; // puVar5[-0xb] = 0;
cmd.unk_260 = 0; // puVar5[-8] = 0;
cmd.unk_264 = 0x4000; // puVar5[-7] = 0x4000;
cmd.unk_268 = 0; // puVar5[-6] = 0;
cmd.header.callback_buffer = nullptr; // puVar5[-0x42] = 0;
cmd.header.ready_for_data = 1; // puVar5[-0x43] = 1;
cmd.header.callback = NullCallback; // puVar5[-0x41] = NullCallback;
cmd.header.lse = nullptr; // puVar5[-0x40] = 0;
cmd.stereo_sibling = nullptr; // puVar5[-0x3d] = 0;
cmd.dma_iop_mem_ptr = nullptr; // puVar5[-0x3c] = 0;
cmd.dma_chan = -1; // puVar5[-0x3b] = 0xffffffff;
cmd.unk_256_pitch2 = 0; // puVar5[-9] = 0;
cmd.unk_296 = 0; // puVar5[1] = 0;
cmd.vec3.x = 0; // puVar5[2] = 0;
cmd.vec3.y = 0; // puVar5[3] = 0;
cmd.vec3.z = 0; // puVar5[4] = 0;
cmd.fo_min = 5; // puVar5[5] = 5;
cmd.fo_max = 0x1e; // puVar5[6] = 0x1e;
cmd.fo_curve = 1; // puVar5[7] = 1;
// puVar5[-0x2b] = *(undefined4*)(StreamSRAM + cmd_idx * 4);
cmd.spu_stream_dma_mem_addr = StreamSRAM[cmd_idx];
// puVar5[-0x2a] = *(undefined4*)(TrapSRAM + cmd_idx * 4);
cmd.spu_trap_mem_addr = TrapSRAM[cmd_idx];
// pRVar7 = pRVar7 + 1;
// puVar5[-0x28] = iVar6;
cmd.idx_in_cmd_arr = cmd_idx;
// iVar6 = iVar6 + 1;
cmd.file_record = nullptr; // puVar5[-0x3f] = 0;
cmd.vag_dir_entry = nullptr; // puVar5[-0x3e] = 0;
cmd.sb_playing = 0; // *(undefined*)((int)puVar5 + -0x53) = 0;
cmd.vol_multiplier = 0; // puVar5[-5] = 0;
cmd.unk_256_pitch2 = 0; // puVar5[-9] = 0;
cmd.id = 0; // puVar5[-4] = 0;
cmd.plugin_id = 0; // puVar5[-3] = 0;
cmd.sound_handler = 0; // puVar5[-0x27] = 0;
cmd.unk_176 = 0; // puVar5[-0x1d] = 0;
cmd.priority = 0; // puVar5[-2] = 0;
cmd.unk_288 = 0; // puVar5[-1] = 0;
cmd.unk_292 = 0; // *puVar5 = 0;
cmd.voice = StreamVoice[cmd_idx];
// puVar5[-0x29] = uVar2;
// puVar5 = puVar5 + 0x51;
cmd_idx++;
}
for (auto& entry : VagCmdsPriList) {
for (auto& c : entry.cmds) {
c = nullptr;
}
}
for (auto& c : VagCmdsPriCounter) {
c = 0;
}
VagCmdsPriCounter[0] = 4;
}
/*!
* Get a VagCmd from VagCmds for the given VagCmd.
*/
VagCmd* SmartAllocVagCmd(VagCmd* cmd) {
VagCmd* selected = nullptr;
// first, just try looking for any free commands in the list.
for (auto& c : VagCmds) {
if (c.id == 0) {
// free!
selected = &c;
break;
}
}
// next, try FindNotQueuedVagCmd
if (!selected) {
selected = FindNotQueuedVagCmd();
}
// next, try some existing ones.
if (!selected) {
int our_priority = cmd->priority;
// if we have a nonzero priority, try taking over a lower priority command
if (our_priority) {
int check_priority = 0;
do {
// loop over other commands at this priority
int cmd_at_pri_idx = 0;
do {
auto* potential_cmd = VagCmdsPriList[check_priority].cmds[cmd_at_pri_idx];
if (potential_cmd) {
// this part is a bit strange... as we iterate through lower priority commands, we
// immediately take the first one with byte11 set to 0. But if this isn't 0, we keep
// looking. This means that we won't take the lowest priority free command if they have
// nonzero BYTE11's. (this would make sense if BYTE11 was some exclusive "please don't
// interrupt me" bit)
selected = potential_cmd;
if (selected->status_bytes[VagCmdByte::BYTE11] == 0) {
// exit immediately
cmd_at_pri_idx = 4;
check_priority = cmd->priority;
}
}
cmd_at_pri_idx++;
} while (cmd_at_pri_idx < 4);
check_priority++;
} while (check_priority < our_priority);
}
}
if (!selected) {
// failed.
return nullptr;
}
ActiveVagStreams = ActiveVagStreams + 1;
if (ActiveVagStreams < 2) {
WakeSpuStreamsUp();
}
return selected;
}
void TerminateVAG(VagCmd* cmd, int /*param_2*/) {
VagStrListNode vag_node;
LfoListNode lfo_node;
// undefined4 auStack32 [2];
// if (param_2 == 1) {
// CpuSuspendIntr(auStack32);
//}
auto* sibling = cmd->stereo_sibling;
strncpy(vag_node.name, cmd->name, 0x30);
vag_node.id = cmd->id;
cmd->sb_scanned = '\0';
if (cmd->status_bytes[BYTE5] != '\0') {
StopVAG(cmd, 0);
}
ReleaseMessage(&cmd->header, 0);
RemoveVagCmd(cmd, 0);
FreeVagCmd(cmd, 0);
if (sibling != nullptr) {
sibling->sb_scanned = '\0';
RemoveVagCmd(sibling, 0);
FreeVagCmd(sibling, 0);
}
if (cmd->sound_handler) {
RemoveVagStreamFromList(&vag_node, &PluginStreamsList);
lfo_node.id = cmd->id;
lfo_node.plugin_id = cmd->plugin_id;
RemoveLfoStreamFromList(&lfo_node, &LfoList);
}
// printf("termina removing %s (2)\n", vag_node.name);
RemoveVagStreamFromList(&vag_node, &EEPlayList);
// if (param_2 == 1) {
// CpuResumeIntr(auStack32[0]);
//}
}
void PauseVAG(VagCmd* cmd, int /*param_2*/) {
if (!cmd->sb_paused) {
// if (param_2 == 1) {
// CpuSuspendIntr(local_20);
// }
if (cmd->status_bytes[BYTE11] == '\0') {
auto* stereo_cmd = cmd->stereo_sibling;
if (!stereo_cmd) {
if (cmd->sb_playing != '\0') {
sceSdSetParam(SD_VP_VOLL | cmd->voice, 0);
sceSdSetParam(SD_VP_VOLR | cmd->voice, 0);
}
sceSdSetParam(SD_VP_PITCH | cmd->voice, 0);
sceSdSetSwitch(SD_S_KOFF | CORE_BIT(cmd->voice), VOICE_BIT(cmd->voice));
if (cmd->status_bytes[BYTE5] == '\0') {
cmd->spu_addr_to_start_playing = 0;
} else {
cmd->spu_addr_to_start_playing = GetSpuRamAddress(cmd);
}
cmd->sb_paused = 1;
} else {
if (cmd->sb_playing != '\0') {
sceSdSetParam(SD_VP_VOLL | cmd->voice, 0);
sceSdSetParam(SD_VP_VOLR | cmd->voice, 0);
sceSdSetParam(SD_VP_VOLL | stereo_cmd->voice, 0);
sceSdSetParam(SD_VP_VOLR | stereo_cmd->voice, 0);
}
sceSdSetParam(SD_VP_PITCH | stereo_cmd->voice, 0);
sceSdSetParam(SD_VP_PITCH | cmd->voice, 0);
sceSdSetSwitch(SD_S_KOFF | CORE_BIT(cmd->voice),
VOICE_BIT(cmd->voice) | VOICE_BIT(stereo_cmd->voice));
if (cmd->status_bytes[BYTE5] == '\0') {
cmd->spu_addr_to_start_playing = 0;
stereo_cmd->spu_addr_to_start_playing = 0;
} else {
u32 ram_addr = GetSpuRamAddress(cmd);
cmd->spu_addr_to_start_playing = ram_addr & 0xfffffff8;
stereo_cmd->spu_addr_to_start_playing =
((ram_addr & 0xfffffff8) - cmd->spu_stream_dma_mem_addr) +
stereo_cmd->spu_stream_dma_mem_addr;
}
cmd->sb_paused = 1;
stereo_cmd->sb_paused = 1;
}
}
// if (param_2 == 1) {
// CpuResumeIntr(local_20[0]);
//}
}
}
void UnPauseVAG(VagCmd* param_1, int /*param_2*/) {
if (param_1->sb_paused) {
// if (param_2 == 1) {
// CpuSuspendIntr(&local_30);
//}
if (param_1->status_bytes[BYTE11] == '\0') {
auto* stereo_cmd = param_1->stereo_sibling;
int pitch = CalculateVAGPitch(param_1->pitch1, param_1->unk_256_pitch2);
u32 vol_l, vol_r;
CalculateVAGVolumes(param_1, &vol_l, &vol_r);
if (!stereo_cmd) {
if (param_1->sb_playing != '\0') {
sceSdSetParam(SD_VP_PITCH | param_1->voice, pitch);
if (param_1->spu_addr_to_start_playing != 0) {
sceSdSetAddr(SD_VA_SSA | param_1->voice, param_1->spu_addr_to_start_playing);
}
sceSdSetSwitch(SD_S_KON | CORE_BIT(param_1->voice), VOICE_BIT(param_1->voice));
sceSdSetParam(SD_VP_VOLL | param_1->voice, vol_l);
sceSdSetParam(SD_VP_VOLR | param_1->voice, vol_r);
}
param_1->sb_paused = 0;
} else {
if (param_1->sb_playing != '\0') {
sceSdSetParam(SD_VP_PITCH | param_1->voice, pitch);
sceSdSetParam(SD_VP_PITCH | stereo_cmd->voice, pitch);
if (param_1->spu_addr_to_start_playing != 0) {
sceSdSetAddr(SD_VA_SSA | param_1->voice, param_1->spu_addr_to_start_playing);
sceSdSetAddr(SD_VA_SSA | stereo_cmd->voice, stereo_cmd->spu_addr_to_start_playing);
}
sceSdSetSwitch(SD_S_KON | CORE_BIT(param_1->voice),
VOICE_BIT(param_1->voice) | VOICE_BIT(stereo_cmd->voice));
sceSdSetParam(SD_VP_VOLL | param_1->voice, vol_l);
sceSdSetParam(SD_VP_VOLL | stereo_cmd->voice, 0);
sceSdSetParam(SD_VP_VOLR | param_1->voice, 0);
sceSdSetParam(SD_VP_VOLR | stereo_cmd->voice, vol_r);
}
param_1->sb_paused = 0;
stereo_cmd->sb_paused = 0;
}
}
// if (param_2 == 1) {
// CpuResumeIntr(local_30);
//}
}
}
void RestartVag(VagCmd* param_1, int param_2, int /*param_3*/) {
// u16 uVar1;
// int iVar2;
// RealVagCmd *stereo_sibling;
// u32 uVar4;
// int iVar5;
// undefined4 local_30;
// undefined2 local_2c [2];
// undefined2 local_28 [4];
// if (param_3 == 1) {
// CpuSuspendIntr(&local_30);
//}
u32 vol_l, vol_r;
CalculateVAGVolumes(param_1, &vol_l, &vol_r);
if (param_1->status_bytes[BYTE11] == '\0') {
auto* stereo_sibling = param_1->stereo_sibling;
int sram_offset = param_2 ? 0x2000 : 0;
int voices = VOICE_BIT(param_1->voice);
if (stereo_sibling) {
voices |= VOICE_BIT(stereo_sibling->voice);
}
sceSdSetSwitch(SD_S_KOFF | CORE_BIT(param_1->voice), voices);
sceSdSetParam(SD_VP_VOLL | param_1->voice, 0);
sceSdSetParam(SD_VP_VOLR | param_1->voice, 0);
if (stereo_sibling) {
sceSdSetParam(SD_VP_VOLL | stereo_sibling->voice, 0);
sceSdSetParam(SD_VP_VOLR | stereo_sibling->voice, 0);
}
sceSdSetAddr(SD_VA_SSA | param_1->voice, param_1->spu_stream_dma_mem_addr + sram_offset);
if (stereo_sibling) {
sceSdSetAddr(SD_VA_SSA | stereo_sibling->voice,
stereo_sibling->spu_stream_dma_mem_addr + sram_offset);
}
sceSdSetSwitch(SD_S_KON | CORE_BIT(param_1->voice), voices);
if (!stereo_sibling) {
sceSdSetParam(SD_VP_VOLL | param_1->voice, vol_l);
sceSdSetParam(SD_VP_VOLR | param_1->voice, vol_r);
} else {
sceSdSetParam(SD_VP_VOLL | param_1->voice, vol_l);
sceSdSetParam(SD_VP_VOLL | stereo_sibling->voice, 0);
sceSdSetParam(SD_VP_VOLR | param_1->voice, 0);
sceSdSetParam(SD_VP_VOLR | stereo_sibling->voice, vol_r);
}
}
// if (param_3 == 1) {
// CpuResumeIntr(local_30);
//}
}
void SetVAGVol(VagCmd* cmd, int /*param_2*/) {
VagCmd* stereo_cmd;
u32 lvol, rvol;
if (cmd == nullptr) {
return;
}
if (cmd->byte4 == '\0') {
return;
}
if (cmd->sb_paused != '\0') {
return;
}
if (cmd->byte11 != '\0') {
return;
}
if (!cmd->sound_handler) {
CalculateVAGVolumes(cmd, &lvol, &rvol);
} else {
ASSERT_NOT_REACHED();
// TODO vag 989snd plugin
// SoundHandler* hnd = cmd->sound_handler;
// u32 vol =
// 0x3fff *
// ((((cmd->vol_multiplier * MasterVolume[hnd->VolGroup]) >> 10) * hnd->Current_Vol) >> 10)
// >> 10;
// lvol = (vol * gPanTable[(cmd->unk_176 + 90) % 360].left) >> 10;
// lvol = (vol * gPanTable[(cmd->unk_176 + 90) % 360].right) >> 10;
// if (lvol >= 0x4000) {
// lvol = 0x3fff;
//}
// if (rvol >= 0x4000) {
// rvol = 0x3fff;
//}
}
// Originally used ProcBatch, buts this is easier to read.
stereo_cmd = cmd->stereo_sibling;
if (stereo_cmd) {
sceSdSetParam(SD_VP_VOLL | cmd->voice, lvol);
sceSdSetParam(SD_VP_VOLR | cmd->voice, 0);
sceSdSetParam(SD_VP_VOLL | stereo_cmd->voice, 0);
sceSdSetParam(SD_VP_VOLR | stereo_cmd->voice, rvol);
sceSdSetParam(SD_VP_PITCH | cmd->voice, CalculateVAGPitch(cmd->pitch1, cmd->unk_256_pitch2));
sceSdSetParam(SD_VP_PITCH | stereo_cmd->voice,
CalculateVAGPitch(cmd->pitch1, cmd->unk_256_pitch2));
} else {
sceSdSetParam(SD_VP_VOLL | cmd->voice, lvol);
sceSdSetParam(SD_VP_VOLR | cmd->voice, rvol);
sceSdSetParam(SD_VP_PITCH | cmd->voice, CalculateVAGPitch(cmd->pitch1, cmd->unk_256_pitch2));
}
}
void SetVagStreamsNoStart(int param_1, int /*param_2*/) {
// if (param_2 == 1) {
// CpuSuspendIntr(local_18);
//}
// pRVar2 = VagCmds;
for (auto& cmd : VagCmds) {
cmd.status_bytes[VagCmdByte::BYTE23_NOSTART] = param_1;
}
// if (param_2 == 1) {
// CpuResumeIntr(local_18[0]);
//}
}
void InitVAGCmd(VagCmd* param_1, int param_2) {
for (auto& x : param_1->status_bytes) {
x = 0;
}
param_1->unk_236 = 0;
param_1->unk_140 = 0;
param_1->sb_paused = param_2 ? 1 : 0;
param_1->unk_264 = 0x4000;
(param_1->header).callback = NullCallback;
param_1->dma_chan = -1;
param_1->fo_min = 5;
param_1->unk_196 = 0;
param_1->unk_200 = 0;
param_1->unk_204 = 0;
param_1->unk_180 = 0;
param_1->unk_184 = 0;
param_1->unk_188 = 0;
param_1->unk_192 = 0;
param_1->status_bytes[VagCmdByte::BYTE5] = '\0';
param_1->status_bytes[VagCmdByte::BYTE5] = '\0';
param_1->num_processed_chunks = 0;
param_1->safe_to_change_dma_fields = 1;
param_1->xfer_size = 0;
param_1->sample_rate = 0;
param_1->unk_260 = 0;
param_1->unk_268 = 0;
(param_1->header).callback_buffer = nullptr;
(param_1->header).ready_for_data = 1;
(param_1->header).lse = nullptr;
param_1->stereo_sibling = nullptr;
param_1->dma_iop_mem_ptr = nullptr;
param_1->unk_256_pitch2 = 0;
param_1->unk_296 = 0;
param_1->vec3.x = 0;
param_1->vec3.y = 0;
param_1->vec3.z = 0;
param_1->fo_max = 0x1e;
param_1->fo_curve = 1;
}
void SetVagStreamsNotScanned() {
for (auto& cmd : VagCmds) {
cmd.sb_scanned = 0;
}
}
void RemoveVagCmd(VagCmd* cmd, int /*param_2*/) {
// if (param_2 == 1) {
// CpuSuspendIntr(local_18);
//}
VagCmdsPriList[cmd->priority].cmds[cmd->idx_in_cmd_arr] = nullptr;
if (VagCmdsPriCounter[cmd->priority] < 1) {
printf("IOP: ======================================================================\n");
printf("IOP: vag RemoveVagCmd: VagCmdsPriCounter[%d] is zero\n", cmd->priority);
printf("IOP: ======================================================================\n");
} else {
VagCmdsPriCounter[cmd->priority]--;
}
VagCmdsPriCounter[0]++;
// if (param_2 == 1) {
// CpuResumeIntr(local_18[0]);
//}
}
VagCmd* FindFreeVagCmd() {
for (auto& cmd : VagCmds) {
if (cmd.id == 0) {
return &cmd;
}
}
return nullptr;
}
VagCmd* FindNotQueuedVagCmd() {
for (auto& cmd : VagCmds) {
if (!cmd.sb_scanned && !cmd.status_bytes[BYTE11] && !cmd.status_bytes[BYTE4]) {
return &cmd;
}
}
return nullptr;
}
VagCmd* FindWhosPlaying() {
for (auto& cmd : VagCmds) {
if (!cmd.sb_paused && cmd.sb_playing) {
return &cmd;
}
}
return nullptr;
}
VagCmd* FindVagStreamId(int id) {
if (id) {
for (auto& cmd : VagCmds) {
if (cmd.id == id) {
return &cmd;
}
}
}
return nullptr;
}
VagCmd* FindVagStreamPluginId(int plugin_id) {
if (plugin_id) {
for (auto& cmd : VagCmds) {
if (cmd.plugin_id == plugin_id) {
return &cmd;
}
}
}
return nullptr;
}
VagCmd* FindVagStreamName(const char* name) {
for (auto& cmd : VagCmds) {
if (strcmp(cmd.name, name) == 0) {
return &cmd;
}
}
return nullptr;
}
/*!
* Check the global VagCmds array for an existing command with this name or ID.
*/
VagCmd* FindThisVagStream(const char* name, int id) {
for (auto& cmd : VagCmds) {
if (strcmp(cmd.name, name) == 0 && cmd.id == id) {
return &cmd;
}
}
return nullptr;
}
int AnyVagRunning() {
int cnt = 0;
for (auto& cmd : VagCmds) {
if (cmd.status_bytes[BYTE4]) {
cnt++;
}
}
return cnt;
}
void FreeVagCmd(VagCmd* cmd, int /*param_2*/) {
// if (param_2 == 1) {
// CpuSuspendIntr(local_18);
//}
for (auto& x : cmd->status_bytes) {
x = 0;
}
cmd->sb_playing = '\0';
cmd->sb_paused = 1;
cmd->sb_scanned = '\0';
cmd->unk_180 = 0;
cmd->unk_184 = 0;
cmd->unk_188 = 0;
cmd->unk_192 = 0;
SetVagStreamName(cmd, 0, 0);
cmd->name[0] = '\0';
cmd->unk_264 = 0x4000;
(cmd->header).callback = NullCallback;
cmd->unk_140 = 0;
cmd->pitch1 = 0;
cmd->file_record = nullptr;
cmd->vag_dir_entry = nullptr;
cmd->unk_196 = 0;
cmd->unk_200 = 0;
cmd->unk_204 = 0;
cmd->num_processed_chunks = 0;
cmd->safe_to_change_dma_fields = 1;
cmd->xfer_size = 0;
cmd->sample_rate = 0;
cmd->unk_260 = 0;
cmd->unk_268 = 0;
cmd->vol_multiplier = 0;
cmd->unk_256_pitch2 = 0;
cmd->id = 0;
cmd->plugin_id = 0;
cmd->sound_handler = 0;
cmd->priority = 0;
cmd->unk_288 = 0;
cmd->unk_292 = 0;
cmd->unk_296 = 0;
(cmd->header).callback_buffer = nullptr;
(cmd->header).ready_for_data = 0;
(cmd->header).lse = nullptr;
cmd->dma_iop_mem_ptr = (uint8_t*)0x0;
cmd->dma_chan = -1;
cmd->unk_236 = 0;
if (0 < ActiveVagStreams) {
ActiveVagStreams--;
}
// if (param_2 == 1) {
// CpuResumeIntr(local_18[0]);
//}
}
void SetNewVagCmdPri(VagCmd* cmd, int new_pri, int /*param_3*/) {
// if (param_3 == 1) {
// CpuSuspendIntr(local_20);
//}
if (cmd) {
VagCmdsPriList[cmd->priority].cmds[cmd->idx_in_cmd_arr] = nullptr;
if (VagCmdsPriCounter[cmd->priority] < 1) {
printf("IOP: ======================================================================\n");
printf("IOP: vag SetNewVagCmdPri: VagCmdsPriCounter[%d] is zero\n", cmd->priority);
printf("IOP: ======================================================================\n");
} else {
VagCmdsPriCounter[cmd->priority]--;
}
VagCmdsPriList[new_pri].cmds[cmd->idx_in_cmd_arr] = cmd;
VagCmdsPriCounter[new_pri]++;
cmd->priority = new_pri;
}
// if (param_3 == 1) {
// CpuResumeIntr(local_20[0]);
//}
}
int HowManyBelowThisPriority(int pri, int /*disable_intr*/) {
int cnt = 0;
for (int p = 0; p < pri; p++) {
cnt += VagCmdsPriCounter[p];
}
return cnt;
}
void StopVAG(VagCmd* cmd, int /*param_2*/) {
// int *piVar1;
// int iVar2;
// u32 uVar3;
// RealVagCmd *sibling;
// undefined4 local_20 [2];
// if (param_2 == 1) {
// CpuSuspendIntr(local_20);
//}
auto& sibling = cmd->stereo_sibling;
PauseVAG(cmd, 0);
if (cmd->status_bytes[BYTE5] != '\0') {
int val = VOICE_BIT(cmd->voice);
if (sibling) {
val = val | VOICE_BIT(sibling->voice);
}
sceSdSetSwitch(SD_S_KOFF | CORE_BIT(cmd->voice), val);
}
for (auto& x : cmd->status_bytes) {
x = 0;
}
(cmd->header).callback = NullCallback;
cmd->vol_multiplier = 0;
cmd->unk_256_pitch2 = 0;
cmd->id = 0;
cmd->plugin_id = 0;
(cmd->header).ready_for_data = 0;
cmd->sound_handler = 0;
cmd->unk_140 = 0;
cmd->pitch1 = 0;
cmd->unk_180 = 0;
cmd->unk_184 = 0;
cmd->unk_188 = 0;
cmd->unk_192 = 0;
// if (param_2 == 1) {
// CpuResumeIntr(local_20[0]);
//}
}
void VAG_MarkLoopEnd(int8_t* data, int offset) {
data[offset + -0xf] = '\x03';
}
void VAG_MarkLoopStart(int8_t* param_1) {
param_1[1] = 6;
param_1[0x11] = 2;
}
int CalculateVAGPitch(int param_1, int param_2) {
if (param_2) {
if (param_2 <= 0) {
return 0x5f4 * param_1 / (0x5f4 - param_2);
} else {
return param_1 * (param_2 + 0x5f4) / 0x5f4;
}
}
return param_1;
}
void PauseVagStreams() {
for (auto& cmd : VagCmds) {
if (cmd.status_bytes[BYTE4] && !cmd.sb_paused) {
PauseVAG(&cmd, 1);
}
}
}
void UnPauseVagStreams() {
for (auto& cmd : VagCmds) {
if (cmd.status_bytes[BYTE4] && cmd.sb_paused) {
UnPauseVAG(&cmd, 1);
}
}
}
void SetAllVagsVol(int param_1) {
if (param_1 >= 0) {
for (auto& VagCmd : VagCmds) {
if (VagCmd.sound_handler /* && VagCmd.sound_handler->VolGroup == param_1 */) {
ASSERT_NOT_REACHED();
SetVAGVol(&VagCmd, 1);
}
}
} else {
for (auto& VagCmd : VagCmds) {
SetVAGVol(&VagCmd, 1);
}
}
}
void CalculateVAGVolumes(VagCmd* cmd, u32* l_out, u32* r_out) {
if (cmd->unk_296 == 0) {
u32 vol = (u32)(cmd->vol_multiplier * MasterVolume[VolumeCategory::DIALOGUE]) >> 6;
if (vol >= 0x4000) {
vol = 0x3fff;
}
*l_out = vol;
*r_out = vol;
} else {
int fo_vol =
CalculateFalloffVolume(&cmd->vec3, (u32)(cmd->vol_multiplier * MasterVolume[2]) >> 10,
cmd->fo_curve, cmd->fo_min, cmd->fo_max);
auto* pan = &gPanTable[(630 - CalculateAngle(&cmd->vec3)) % 360];
*l_out = (pan->left * fo_vol) >> 10;
*r_out = (pan->right * fo_vol) >> 10;
if (*l_out >= 0x4000) {
*l_out = 0x3fff;
}
if (*r_out >= 0x4000) {
*r_out = 0x3fff;
}
}
}
} // namespace jak2