jak-project/game/overlord/jak2/spustreams.cpp
Tyler Wilding 60db0e5ef9
deps: update fmt to latest version (#3403)
This updates `fmt` to the latest version and moves to just being a copy
of their repo to make updating easier (no editing their cmake / figuring
out which files to minimally include).

The motivation for this is now that we switched to C++ 20, there were a
ton of deprecated function usages that is going away in future compiler
versions. This gets rid of all those warnings.
2024-03-05 22:11:52 -05:00

947 lines
29 KiB
C++

#include "spustreams.h"
#include <cstring>
#include "common/common_types.h"
#include "common/util/Assert.h"
#include "game/overlord/jak2/dma.h"
#include "game/overlord/jak2/iso.h"
#include "game/overlord/jak2/iso_queue.h"
#include "game/overlord/jak2/streamlist.h"
#include "game/overlord/jak2/vag.h"
#include "game/sce/iop.h"
#include "game/sound/sdshim.h"
using namespace iop;
namespace jak2 {
void ProcessStreamData();
void StopVagStream(VagCmd* cmd, int suspend_irq);
s32 StreamsThread = 0;
void spusstreams_init_globals() {
StreamsThread = 0;
}
int ProcessVAGData(CmdHeader* param_1_in, Buffer* param_2) {
VagCmd* param_1 = (VagCmd*)param_1_in;
int iVar1;
int iVar2;
u32 uVar3;
int iVar4;
u32 uVar5;
int* piVar6;
VagCmd* pRVar7;
// undefined4 local_18[2];
if (param_1->status_bytes[BYTE6] != '\0') {
// printf("ProcessVAG didn't want the data: byte 6 is set\n");
return -1;
}
if (param_1->status_bytes[BYTE11] != '\0') {
// printf("ProcessVAG didn't want the data: byte 11 is set\n");
return -1;
}
if (param_1->unk_260 != 0) {
// printf("ProcessVAG didn't want the data: unk_260 is set, indicating INVALID data.\n");
param_2->decompressed_size = 0;
return -1;
}
if (!param_1->safe_to_change_dma_fields) {
return -1;
}
// CpuSuspendIntr(local_18);
CheckForIsoPageBoundaryCrossing(param_2);
// added this check
if (!param_2->page) {
// printf("ProcessVAG didn't want the data: the buffer has no page (added check)\n");
return -1;
}
iVar2 = (int)param_2->page->state;
if ((iVar2 != 6) && (iVar2 != 4)) {
// printf("ProcessVAG didn't want the data: the buffer isn't full.\n");
goto LAB_0000fecc;
}
param_2->page->state = PageState::SIX;
pRVar7 = param_1->stereo_sibling;
iVar2 = 0x2000;
if (pRVar7 != 0x0) {
iVar2 = 0x4000;
}
uVar3 = param_1->num_processed_chunks;
if (uVar3 == 0) {
piVar6 = (int*)param_2->decomp_buffer;
if ((*piVar6 != 0x70474156) && (*piVar6 != 0x56414770)) {
param_1->unk_260 = 1;
param_2->decompressed_size = 0;
goto LAB_0000fecc;
}
param_1->sample_rate = piVar6[4];
iVar2 = piVar6[3];
param_1->unk_204 = 0;
param_1->xfer_size = iVar2;
if (*piVar6 == 0x70474156) {
uVar3 = param_1->sample_rate;
uVar5 = param_1->xfer_size;
param_1->sample_rate =
uVar3 >> 0x18 | ((int)uVar3 >> 8 & 0xff00U) | (uVar3 & 0xff00) << 8 | uVar3 << 0x18;
param_1->xfer_size =
uVar5 >> 0x18 | ((int)uVar5 >> 8 & 0xff00U) | (uVar5 & 0xff00) << 8 | uVar5 << 0x18;
}
if (pRVar7 != 0x0) {
pRVar7->sample_rate = piVar6[4];
iVar2 = piVar6[3];
pRVar7->unk_204 = 0;
pRVar7->xfer_size = iVar2;
}
iVar4 = param_1->xfer_size;
iVar2 = iVar4 + 0x30;
param_1->unk_264 = 0x4000;
param_1->xfer_size = iVar2;
param_1->pitch1 = (u32)(param_1->sample_rate << 0xc) / 48000;
if ((iVar2 < 0x2001) && (0x3fff < (u32)param_1->unk_264)) {
iVar1 = 0x10;
if (0x1f < iVar2) {
iVar1 = iVar4 + 0x20;
}
param_1->unk_264 = iVar1;
if (pRVar7 != 0x0) {
pRVar7->sample_rate = param_1->sample_rate;
iVar2 = param_1->xfer_size;
pRVar7->unk_204 = 0;
pRVar7->xfer_size = iVar2;
pRVar7->unk_264 = param_1->unk_264;
pRVar7->pitch1 = param_1->pitch1;
pRVar7->xfer_size = param_1->xfer_size;
pRVar7->unk_264 = param_1->unk_264;
}
}
iVar2 = DMA_SendToSPUAndSync(param_2->decomp_buffer, 0x2000, param_1->spu_stream_dma_mem_addr,
param_1, 0);
if (iVar2 == 0)
goto LAB_0000fecc;
param_1->unk_196 = 0;
param_1->unk_200 = 0;
if (pRVar7) { // added
pRVar7->unk_200 = 0;
}
LAB_0000fbdc:
iVar2 = 0x2000;
if (pRVar7 != 0x0) {
iVar2 = 0x4000;
}
param_2->decomp_buffer = param_2->decomp_buffer + iVar2;
iVar4 = param_1->xfer_size - iVar2;
if (iVar2 < param_1->xfer_size)
goto LAB_0000fe98;
param_1->xfer_size = 0;
LAB_0000feb4:
param_2->decompressed_size = 0;
} else {
if (uVar3 == 1) {
iVar4 = param_1->xfer_size;
if ((iVar2 < iVar4) || ((u32)param_1->unk_264 < 0x4000)) {
VAG_MarkLoopEnd((int8_t*)param_2->decomp_buffer, 0x2000);
VAG_MarkLoopStart((int8_t*)param_2->decomp_buffer);
if (pRVar7 != 0x0) {
VAG_MarkLoopEnd((int8_t*)param_2->decomp_buffer, 0x4000);
VAG_MarkLoopStart((int8_t*)(param_2->decomp_buffer + 0x2000));
}
} else {
iVar2 = 0x2010;
if (0x1f < iVar4) {
if (pRVar7 == 0x0) {
iVar2 = iVar4 + 0x1ff0;
} else {
iVar2 = iVar4 / 2 + 0x1ff0;
}
}
param_1->unk_264 = iVar2;
if (pRVar7 != 0x0) {
pRVar7->unk_264 = param_1->unk_264;
}
}
iVar2 = DMA_SendToSPUAndSync(param_2->decomp_buffer, 0x2000,
param_1->spu_stream_dma_mem_addr + 0x2000, param_1, 0);
if (iVar2 == 0)
goto LAB_0000fecc;
(param_1->header).ready_for_data = 0;
goto LAB_0000fbdc;
}
if ((uVar3 & 1) != 0) {
iVar4 = param_1->xfer_size;
if ((iVar2 < iVar4) || ((u32)param_1->unk_264 < 0x4000)) {
VAG_MarkLoopEnd((int8_t*)param_2->decomp_buffer, 0x2000);
VAG_MarkLoopStart((int8_t*)param_2->decomp_buffer);
if (pRVar7 != 0x0) {
VAG_MarkLoopEnd((int8_t*)param_2->decomp_buffer, 0x4000);
VAG_MarkLoopStart((int8_t*)(param_2->decomp_buffer + 0x2000));
}
} else {
iVar2 = 0x2010;
if (0x1f < iVar4) {
if (pRVar7 == 0x0) {
iVar2 = iVar4 + 0x1ff0;
} else {
iVar2 = iVar4 / 2 + 0x1ff0;
}
}
param_1->unk_264 = iVar2;
if (pRVar7 != 0x0) {
pRVar7->unk_264 = param_1->unk_264;
}
}
iVar2 = DMA_SendToSPUAndSync(param_2->decomp_buffer, 0x2000,
param_1->spu_stream_dma_mem_addr + 0x2000, param_1, 0);
if (iVar2 == 0)
goto LAB_0000fecc;
(param_1->header).ready_for_data = 0;
goto LAB_0000fbdc;
}
iVar4 = param_1->xfer_size;
if ((iVar2 < iVar4) || ((u32)param_1->unk_264 < 0x4000)) {
VAG_MarkLoopEnd((int8_t*)param_2->decomp_buffer, 0x2000);
VAG_MarkLoopStart((int8_t*)param_2->decomp_buffer);
if (pRVar7 != 0x0) {
VAG_MarkLoopEnd((int8_t*)param_2->decomp_buffer, 0x4000);
VAG_MarkLoopStart((int8_t*)(param_2->decomp_buffer + 0x2000));
}
} else {
iVar2 = 0x10;
if (0x1f < iVar4) {
if (pRVar7 == 0x0) {
iVar2 = iVar4 + -0x10;
} else {
iVar2 = iVar4 / 2 + -0x10;
}
}
param_1->unk_264 = iVar2;
if (pRVar7 != 0x0) {
pRVar7->unk_264 = param_1->unk_264;
}
}
iVar2 = DMA_SendToSPUAndSync(param_2->decomp_buffer, 0x2000, param_1->spu_stream_dma_mem_addr,
param_1, 0);
if (iVar2 == 0)
goto LAB_0000fecc;
(param_1->header).ready_for_data = 0;
iVar2 = 0x2000;
if (pRVar7 != 0x0) {
iVar2 = 0x4000;
}
param_2->decomp_buffer = param_2->decomp_buffer + iVar2;
iVar4 = param_1->xfer_size - iVar2;
if (param_1->xfer_size <= iVar2) {
param_1->xfer_size = 0;
goto LAB_0000feb4;
}
LAB_0000fe98:
param_1->xfer_size = iVar4;
param_2->decompressed_size = param_2->decompressed_size - iVar2;
}
param_1->num_processed_chunks++;
LAB_0000fecc:
// CpuResumeIntr(local_18[0]);
return -1;
}
int GetVAGStreamPos(VagCmd* param_1) {
u32 primary_dma_offset;
int iVar6;
VagCmd* pRVar7;
u32 secondary_dma_offset;
u32 uVar9;
u32 uVar10;
pRVar7 = param_1->stereo_sibling;
if (param_1->id == 0) {
param_1->unk_200 = 0;
if (pRVar7 == 0x0) {
return 0;
}
pRVar7->unk_200 = 0;
return 0;
}
if (param_1->byte6 != '\0') {
param_1->unk_200 = param_1->unk_192;
if (pRVar7 == 0x0) {
return 0;
}
pRVar7->unk_200 = pRVar7->unk_192;
return 0;
}
if (((param_1->byte4 == '\0') || (param_1->sb_playing == '\0')) || (param_1->sb_paused != '\0')) {
param_1->unk_200 = param_1->unk_180;
if (pRVar7 == 0x0) {
return 0;
}
pRVar7->unk_200 = pRVar7->unk_180;
return 0;
}
// this is inheriting what was calculated from the primary, if we're the "Stereo" second stream.
if (param_1->byte11 != '\0') {
param_1->unk_200 = param_1->unk_180;
return 0;
}
// CpuSuspendIntr(local_30);
primary_dma_offset = GetSpuRamAddress(param_1);
primary_dma_offset = primary_dma_offset - param_1->spu_stream_dma_mem_addr;
if (pRVar7 == 0x0) {
secondary_dma_offset = 0;
} else {
secondary_dma_offset = GetSpuRamAddress(pRVar7);
secondary_dma_offset = secondary_dma_offset - pRVar7->spu_stream_dma_mem_addr;
}
// CpuResumeIntr(local_30[0]);
if (pRVar7 != 0x0) {
if ((((primary_dma_offset < 0x4000) && (secondary_dma_offset < 0x4000)) &&
(param_1->byte20 == '\0')) &&
(pRVar7->byte20 == '\0')) {
iVar6 = (int)((primary_dma_offset - secondary_dma_offset) * 0x40000) >> 0x12;
if (iVar6 < 0) {
iVar6 = -iVar6;
}
if (4 < iVar6) {
PauseVAG(param_1, 1);
primary_dma_offset = param_1->spu_addr_to_start_playing - param_1->spu_stream_dma_mem_addr;
secondary_dma_offset = pRVar7->spu_addr_to_start_playing - pRVar7->spu_stream_dma_mem_addr;
UnPauseVAG(param_1, 1);
}
}
if (pRVar7 == 0x0)
goto LAB_00010860;
// CpuSuspendIntr(local_30);
if ((0x4000 < primary_dma_offset) && (param_1->byte20 == '\0')) {
param_1->byte20 = '\x01';
param_1->byte21 = '\0';
param_1->byte22 = '\0';
pRVar7->byte20 = '\x01';
pRVar7->byte21 = '\0';
pRVar7->byte22 = '\0';
}
if (secondary_dma_offset < 0x4001) {
if (primary_dma_offset < 0x2000) {
if (param_1->byte21 == '\0') {
iVar6 = param_1->unk_204;
param_1->byte21 = '\x01';
param_1->byte22 = '\0';
LAB_00010234:
param_1->byte20 = '\0';
param_1->unk_204 = iVar6 + 1;
}
} else if (param_1->byte22 == '\0') {
iVar6 = param_1->unk_204;
param_1->byte22 = '\x01';
param_1->byte21 = '\0';
goto LAB_00010234;
}
if (secondary_dma_offset < 0x2000) {
if (pRVar7->byte21 == '\0') {
iVar6 = pRVar7->unk_204;
pRVar7->byte21 = '\x01';
pRVar7->byte22 = '\0';
LAB_00010288:
pRVar7->byte20 = '\0';
pRVar7->unk_204 = iVar6 + 1;
}
} else if (pRVar7->byte22 == '\0') {
iVar6 = pRVar7->unk_204;
pRVar7->byte22 = '\x01';
pRVar7->byte21 = '\0';
goto LAB_00010288;
} else {
}
} else if (pRVar7->byte20 == '\0') {
param_1->byte20 = '\x01';
param_1->byte21 = '\0';
param_1->byte22 = '\0';
pRVar7->byte20 = '\x01';
pRVar7->byte21 = '\0';
pRVar7->byte22 = '\0';
}
// CpuResumeIntr(local_30[0]);
switch (param_1->unk_236) {
case 0:
if ((((param_1->sb_odd_buffer_dma_complete == '\0') || (param_1->byte21 == '\0')) ||
(pRVar7->sb_odd_buffer_dma_complete == '\0')) ||
(pRVar7->byte21 == '\0'))
goto switchD_000102c4_caseD_1;
param_1->sb_odd_buffer_dma_complete = '\0';
pRVar7->sb_odd_buffer_dma_complete = '\0';
param_1->unk_236 = 2;
pRVar7->unk_236 = 2;
case 2:
if ((param_1->sb_even_buffer_dma_complete == '\0') ||
(pRVar7->sb_even_buffer_dma_complete == '\0')) {
if ((param_1->byte20 == '\0') && (pRVar7->byte20 == '\0'))
goto switchD_000102c4_caseD_1;
primary_dma_offset = 0x2000;
secondary_dma_offset = 0x2000;
param_1->byte17 = '\x01';
param_1->byte16 = '\0';
pRVar7->byte17 = '\x01';
iVar6 = 4;
LAB_00010744:
pRVar7->byte16 = '\0';
} else {
if ((param_1->byte20 == '\0') && (pRVar7->byte20 == '\0')) {
// CpuSuspendIntr(local_30);
sceSdSetAddr(*(u16*)&param_1->voice | 0x2140,
param_1->spu_stream_dma_mem_addr + 0x2000);
sceSdSetAddr(*(u16*)&pRVar7->voice | 0x2140, pRVar7->spu_stream_dma_mem_addr + 0x2000);
param_1->byte15 = '\x01';
param_1->byte14 = '\0';
param_1->byte13 = '\0';
pRVar7->byte15 = '\x01';
pRVar7->byte14 = '\0';
pRVar7->byte13 = '\0';
iVar6 = 3;
LAB_000106d4:
param_1->unk_236 = iVar6;
pRVar7->unk_236 = iVar6;
// CpuResumeIntr(local_30[0]);
goto switchD_000102c4_caseD_1;
}
primary_dma_offset = 0x2000;
secondary_dma_offset = 0x2000;
RestartVag(param_1, 1, 1);
iVar6 = 9;
}
break;
default:
goto switchD_000102c4_caseD_1;
case 3:
if ((param_1->byte20 != '\0') || (pRVar7->byte20 != '\0')) {
primary_dma_offset = 0x2000;
secondary_dma_offset = 0x2000;
RestartVag(param_1, 1, 1);
iVar6 = 9;
break;
}
if ((param_1->byte22 == '\0') || (pRVar7->byte22 == '\0'))
goto switchD_000102c4_caseD_1;
// CpuSuspendIntr(local_30);
sceSdSetAddr(*(u16*)&param_1->voice | 0x2140, param_1->spu_trap_mem_addr);
sceSdSetAddr(*(u16*)&pRVar7->voice | 0x2140, pRVar7->spu_trap_mem_addr);
param_1->byte13 = '\x01';
param_1->byte14 = '\0';
param_1->byte15 = '\0';
pRVar7->byte13 = '\x01';
pRVar7->byte14 = '\0';
pRVar7->byte15 = '\0';
param_1->sb_even_buffer_dma_complete = '\0';
pRVar7->sb_even_buffer_dma_complete = '\0';
iVar6 = 5;
goto LAB_000106d4;
case 4:
primary_dma_offset = param_1->unk_196;
secondary_dma_offset = pRVar7->unk_196;
if ((param_1->sb_even_buffer_dma_complete == '\0') ||
(pRVar7->sb_even_buffer_dma_complete == '\0'))
goto switchD_000102c4_caseD_1;
RestartVag(param_1, 1, 1);
iVar6 = 9;
break;
case 5:
if ((param_1->sb_odd_buffer_dma_complete == '\0') ||
(pRVar7->sb_odd_buffer_dma_complete == '\0')) {
if (param_1->byte20 == '\0')
goto switchD_000102c4_caseD_1;
primary_dma_offset = 0x4000;
secondary_dma_offset = 0x4000;
param_1->byte16 = '\x01';
param_1->byte17 = '\0';
pRVar7->byte16 = '\x01';
iVar6 = 7;
pRVar7->byte17 = '\0';
} else {
if ((param_1->byte20 == '\0') && (pRVar7->byte20 == '\0')) {
// CpuSuspendIntr(local_30);
sceSdSetAddr(*(u16*)&param_1->voice | 0x2140, param_1->spu_stream_dma_mem_addr);
sceSdSetAddr(*(u16*)&pRVar7->voice | 0x2140, pRVar7->spu_stream_dma_mem_addr);
param_1->byte14 = '\x01';
param_1->byte15 = '\0';
param_1->byte13 = '\0';
pRVar7->byte14 = '\x01';
pRVar7->byte15 = '\0';
pRVar7->byte13 = '\0';
iVar6 = 6;
goto LAB_000106d4;
}
primary_dma_offset = 0x4000;
secondary_dma_offset = 0x4000;
RestartVag(param_1, 0, 1);
iVar6 = 8;
}
break;
case 6:
if ((param_1->byte20 == '\0') && (pRVar7->byte20 == '\0')) {
if ((param_1->byte21 == '\0') || (pRVar7->byte21 == '\0'))
goto switchD_000102c4_caseD_1;
// CpuSuspendIntr(local_30);
sceSdSetAddr(*(u16*)&param_1->voice | 0x2140, param_1->spu_trap_mem_addr);
sceSdSetAddr(*(u16*)&pRVar7->voice | 0x2140, pRVar7->spu_trap_mem_addr);
param_1->byte13 = '\x01';
param_1->byte14 = '\0';
param_1->byte15 = '\0';
pRVar7->byte13 = '\x01';
pRVar7->byte14 = '\0';
pRVar7->byte15 = '\0';
param_1->sb_odd_buffer_dma_complete = '\0';
pRVar7->sb_odd_buffer_dma_complete = '\0';
iVar6 = 2;
goto LAB_000106d4;
}
primary_dma_offset = 0x4000;
secondary_dma_offset = 0x4000;
RestartVag(param_1, 0, 1);
iVar6 = 8;
break;
case 7:
secondary_dma_offset = param_1->unk_196;
primary_dma_offset = secondary_dma_offset;
if ((param_1->sb_odd_buffer_dma_complete == '\0') ||
(pRVar7->sb_odd_buffer_dma_complete == '\0'))
goto switchD_000102c4_caseD_1;
RestartVag(param_1, 0, 1);
iVar6 = 8;
break;
case 8:
if ((param_1->byte21 == '\0') || (iVar6 = 6, pRVar7->byte21 == '\0')) {
secondary_dma_offset = param_1->unk_196;
primary_dma_offset = secondary_dma_offset;
goto switchD_000102c4_caseD_1;
}
param_1->byte16 = '\0';
goto LAB_00010744;
case 9:
if ((param_1->byte22 == '\0') || (iVar6 = 3, pRVar7->byte22 == '\0')) {
secondary_dma_offset = pRVar7->unk_196;
primary_dma_offset = param_1->unk_196;
goto switchD_000102c4_caseD_1;
}
param_1->byte17 = '\0';
pRVar7->byte17 = '\0';
}
param_1->unk_236 = iVar6;
pRVar7->unk_236 = iVar6;
switchD_000102c4_caseD_1:
if (param_1->unk_204 == 0) {
param_1->unk_188 = primary_dma_offset;
pRVar7->unk_188 = primary_dma_offset;
} else {
param_1->unk_188 = primary_dma_offset + (param_1->unk_204 + -1) * 0x2000;
pRVar7->unk_188 = secondary_dma_offset + (pRVar7->unk_204 + -1) * 0x2000;
if (0x2000 < primary_dma_offset) {
param_1->unk_188 = param_1->unk_188 + -0x2000;
}
if (0x2000 < secondary_dma_offset) {
pRVar7->unk_188 = pRVar7->unk_188 + -0x2000;
}
}
uVar9 = param_1->sample_rate;
if (uVar9 == 0) {
uVar10 = 0;
} else {
uVar10 = (u32)(param_1->unk_188 * 0x1c0) / uVar9;
if (uVar9 == 0) {
// trap(0x1c00);
ASSERT_NOT_REACHED();
}
}
param_1->unk_180 = uVar10 << 2;
param_1->unk_200 = uVar10 << 2;
param_1->unk_196 = primary_dma_offset;
uVar9 = pRVar7->sample_rate;
if (uVar9 == 0) {
uVar10 = 0;
} else {
uVar10 = (u32)(pRVar7->unk_188 * 0x1c0) / uVar9;
if (uVar9 == 0) {
// trap(0x1c00);
ASSERT_NOT_REACHED();
}
}
pRVar7->unk_180 = uVar10 << 2;
pRVar7->unk_200 = uVar10 << 2;
pRVar7->unk_196 = secondary_dma_offset;
return 0;
}
LAB_00010860:
if (primary_dma_offset < 0x4001) {
if (primary_dma_offset < 0x2000) {
if (param_1->byte21 == '\0') {
iVar6 = param_1->unk_204;
param_1->byte21 = '\x01';
param_1->byte22 = '\0';
LAB_000108cc:
param_1->byte20 = '\0';
param_1->unk_204 = iVar6 + 1;
}
} else if (param_1->byte22 == '\0') {
iVar6 = param_1->unk_204;
param_1->byte22 = '\x01';
param_1->byte21 = '\0';
goto LAB_000108cc;
}
} else if (param_1->byte20 == '\0') {
param_1->byte20 = '\x01';
param_1->byte21 = '\0';
param_1->byte22 = '\0';
}
switch (param_1->unk_236) {
case 0:
if ((param_1->sb_odd_buffer_dma_complete == '\0') || (param_1->byte21 == '\0'))
goto switchD_000108fc_caseD_1;
param_1->sb_odd_buffer_dma_complete = '\0';
param_1->unk_236 = 2;
case 2:
if (param_1->sb_even_buffer_dma_complete == '\0') {
if (param_1->byte20 != '\0') {
primary_dma_offset = 0x2000;
param_1->byte17 = '\x01';
iVar6 = 4;
LAB_00010b7c:
param_1->byte16 = '\0';
param_1->unk_236 = iVar6;
}
} else if (param_1->byte20 == '\0') {
// CpuSuspendIntr(local_30);
sceSdSetAddr(*(u16*)&param_1->voice | 0x2140, param_1->spu_stream_dma_mem_addr + 0x2000);
param_1->byte15 = '\x01';
param_1->byte14 = '\0';
param_1->byte13 = '\0';
iVar6 = 3;
LAB_00010b30:
param_1->unk_236 = iVar6;
// CpuResumeIntr(local_30[0]);
} else {
primary_dma_offset = 0x2000;
LAB_00010a1c:
RestartVag(param_1, 1, 1);
param_1->unk_236 = 9;
}
default:
goto switchD_000108fc_caseD_1;
case 3:
if (param_1->byte20 != '\0') {
primary_dma_offset = 0x2000;
goto LAB_00010a1c;
}
if (param_1->byte22 == '\0')
goto switchD_000108fc_caseD_1;
// CpuSuspendIntr(local_30);
sceSdSetAddr(*(u16*)&param_1->voice | 0x2140, param_1->spu_trap_mem_addr);
param_1->byte13 = '\x01';
param_1->byte14 = '\0';
param_1->byte15 = '\0';
param_1->sb_even_buffer_dma_complete = '\0';
iVar6 = 5;
goto LAB_00010b30;
case 4:
primary_dma_offset = param_1->unk_196;
if (param_1->sb_even_buffer_dma_complete == '\0')
goto switchD_000108fc_caseD_1;
goto LAB_00010a1c;
case 5:
if (param_1->sb_odd_buffer_dma_complete == '\0') {
if (param_1->byte20 == '\0')
goto switchD_000108fc_caseD_1;
primary_dma_offset = 0x4000;
param_1->byte16 = '\x01';
iVar6 = 7;
param_1->byte17 = '\0';
goto LAB_00010acc;
}
if (param_1->byte20 == '\0') {
// CpuSuspendIntr(local_30);
sceSdSetAddr(*(u16*)&param_1->voice | 0x2140, param_1->spu_stream_dma_mem_addr);
param_1->byte14 = '\x01';
param_1->byte15 = '\0';
param_1->byte13 = '\0';
iVar6 = 6;
goto LAB_00010b30;
}
primary_dma_offset = 0x4000;
break;
case 6:
if (param_1->byte20 == '\0') {
if (param_1->byte21 == '\0')
goto switchD_000108fc_caseD_1;
// CpuSuspendIntr(local_30);
sceSdSetAddr(*(u16*)&param_1->voice | 0x2140, param_1->spu_trap_mem_addr);
param_1->byte13 = '\x01';
param_1->byte14 = '\0';
param_1->byte15 = '\0';
param_1->sb_odd_buffer_dma_complete = '\0';
iVar6 = 2;
goto LAB_00010b30;
}
primary_dma_offset = 0x4000;
break;
case 7:
primary_dma_offset = param_1->unk_196;
if (param_1->sb_odd_buffer_dma_complete == '\0')
goto switchD_000108fc_caseD_1;
break;
case 8:
iVar6 = 6;
if (param_1->byte21 == '\0') {
LAB_00010b88:
primary_dma_offset = param_1->unk_196;
goto switchD_000108fc_caseD_1;
}
goto LAB_00010b7c;
case 9:
iVar6 = 3;
if (param_1->byte22 == '\0')
goto LAB_00010b88;
param_1->byte17 = '\0';
LAB_00010acc:
param_1->unk_236 = iVar6;
goto switchD_000108fc_caseD_1;
}
RestartVag(param_1, 0, 1);
param_1->unk_236 = 8;
switchD_000108fc_caseD_1:
if (param_1->unk_204 == 0) {
param_1->unk_188 = primary_dma_offset;
} else {
iVar6 = primary_dma_offset + (param_1->unk_204 + -1) * 0x2000;
param_1->unk_188 = iVar6;
if (0x2000 < primary_dma_offset) {
param_1->unk_188 = iVar6 + -0x2000;
}
}
secondary_dma_offset = param_1->sample_rate;
if (secondary_dma_offset == 0) {
uVar9 = 0;
} else {
uVar9 = (u32)(param_1->unk_188 * 0x1c0) / secondary_dma_offset;
if (secondary_dma_offset == 0) {
// trap(0x1c00);
ASSERT_NOT_REACHED();
}
}
param_1->unk_180 = uVar9 << 2;
param_1->unk_200 = uVar9 << 2;
param_1->unk_196 = primary_dma_offset;
return 0;
}
int CheckVAGStreamProgress(VagCmd* param_1) {
int uVar1;
u32 uVar2;
u32 uVar3;
VagCmd* pRVar4;
// undefined4 local_18 [2];
if (param_1->byte11 != '\0') {
return 1;
}
if (param_1->unk_260 != 0) {
return 0;
}
if (param_1->sb_playing == '\0') {
return 1;
}
if (param_1->sb_paused != '\0') {
return 1;
}
uVar2 = param_1->unk_264;
pRVar4 = param_1->stereo_sibling;
uVar3 = param_1->unk_196;
if (uVar2 < 0x4000) {
if ((0x2000 < uVar3) || (0x2000 < uVar2)) {
if ((uVar3 < 0x2000) || (uVar2 < 0x2000))
goto LAB_00010d58;
uVar2 = param_1->unk_264;
}
uVar1 = 0;
if ((uVar3 & 0xfffffff0) < uVar2) {
// CpuSuspendIntr(local_18);
if ((param_1->unk_268 == 0) && (uVar3 < (u32)param_1->unk_264)) {
sceSdSetAddr(*(u16*)&param_1->voice | 0x2140,
param_1->spu_stream_dma_mem_addr + param_1->unk_264);
param_1->unk_268 = 1;
if (pRVar4 != 0x0) {
sceSdSetAddr(*(u16*)&pRVar4->voice | 0x2140,
pRVar4->spu_stream_dma_mem_addr + param_1->unk_264);
pRVar4->unk_268 = 1;
}
}
(param_1->header).ready_for_data = 0;
// CpuResumeIntr(local_18[0]);
uVar1 = 1;
}
} else {
LAB_00010d58:
uVar1 = 1;
if ((((param_1->sb_playing != '\0') && (uVar1 = 1, (param_1->header).ready_for_data == 0)) &&
param_1->safe_to_change_dma_fields) &&
(uVar1 = 1, param_1->unk_268 == 0)) {
if (uVar3 < 0x2000) {
uVar1 = 1;
if ((param_1->num_processed_chunks & 1U) != 0) {
(param_1->header).ready_for_data = 1;
}
} else {
uVar1 = 1;
if ((param_1->num_processed_chunks & 1U) == 0) {
(param_1->header).ready_for_data = 1;
}
}
}
}
return uVar1;
}
u32 CheckVagStreamsProgress() {
while (true) {
ProcessStreamData();
for (auto& cmd : VagCmds) {
if (cmd.sb_playing || (cmd.byte4 && cmd.byte6) ||
(cmd.header.ready_for_data == 1 && cmd.id)) {
if (CheckVAGStreamProgress(&cmd)) {
GetVAGStreamPos(&cmd);
} else {
StopVagStream(&cmd, 1);
}
}
};
if (ActiveVagStreams < 1) {
SleepThread();
} else {
DelayThread(1000);
}
};
return 0;
}
void StopVagStream(VagCmd* param_1, int param_2) {
VagCmd* cmd;
VagStrListNode VStack184;
LfoListNode LStack80;
// undefined4 local_20 [2];
if (param_2 == 1) {
// CpuSuspendIntr(local_20);
}
cmd = param_1->stereo_sibling;
param_1->sb_playing = '\0';
if (cmd != 0x0) {
cmd->sb_playing = '\0';
}
if (param_1->sound_handler == 0) {
PauseVAG(param_1, 0);
param_1->byte9 = '\x01';
if (cmd != 0x0) {
PauseVAG(cmd, 0);
param_1->byte9 = '\x01';
}
} else {
PauseVAG(param_1, 0);
strncpy(VStack184.name, param_1->name, 0x30);
VStack184.id = param_1->id;
RemoveVagStreamFromList(&VStack184, &PluginStreamsList);
RemoveVagStreamFromList(&VStack184, &EEPlayList);
LStack80.id = param_1->id;
LStack80.plugin_id = param_1->plugin_id;
RemoveLfoStreamFromList(&LStack80, &LfoList);
}
if (param_2 == 1) {
// CpuResumeIntr(local_20[0]);
}
}
void InitSpuStreamsThread() {
ThreadParam local_20;
local_20.attr = 0x2000000;
local_20.entry = CheckVagStreamsProgress;
local_20.initPriority = 0x32;
local_20.stackSize = 0x800;
local_20.option = 0;
StreamsThread = CreateThread(&local_20);
if (StreamsThread < 1) {
printf("IOP: ======================================================================\n");
printf("IOP: spustreams InitSpuStreamsThread: Cannot create streams thread\n");
printf("IOP: ======================================================================\n");
ASSERT_NOT_REACHED();
}
StartThread(StreamsThread, 0);
}
void WakeSpuStreamsUp() {
iWakeupThread(StreamsThread);
}
u32 GetSpuRamAddress(VagCmd* param_1) {
// this is simplified a lot from the original.
// they seem to sanity check if the value is reasonable or not, but the sanity check can fail
// if the overlord thread isn't keeping up.
// as far as I can tell, it's totally fine to discard these checks because our sceSdGetAddr
// works perfectly.
return sceSdGetAddr(SD_VA_NAX | param_1->voice);
}
u32 bswap(u32 param_1) {
return param_1 >> 0x18 | ((int)param_1 >> 8 & 0xff00U) | (param_1 & 0xff00) << 8 |
param_1 << 0x18;
}
void ProcessStreamData() {
int iVar1;
VagCmd* pRVar2;
Buffer* pBVar3;
int iVar4;
CmdHeader** ppCVar5;
iVar4 = gPriStack[3].count + -1;
if ((gPriStack[3].count < 8) && (-1 < iVar4)) {
ppCVar5 = gPriStack[3].entries + gPriStack[3].count + -1;
do {
pRVar2 = (VagCmd*)*ppCVar5;
if (pRVar2 != 0x0) {
if ((pRVar2->header).status == -1) {
if ((((pRVar2->header).ready_for_data != 0) &&
(pBVar3 = (pRVar2->header).callback_buffer, pBVar3 != (Buffer*)0x0)) &&
((pRVar2->header).callback == ProcessVAGData)) {
iVar1 = ProcessVAGData(&pRVar2->header, pBVar3);
(pRVar2->header).status = iVar1;
if ((pBVar3->decompressed_size == 0) && pRVar2->safe_to_change_dma_fields) {
(pRVar2->header).callback_buffer = pBVar3->next;
FreeBuffer(pBVar3, 1);
}
if ((pRVar2->header).status == -1)
goto LAB_0001151c;
if (pRVar2->safe_to_change_dma_fields) {
ReleaseMessage((CmdHeader*)pRVar2, 1);
}
}
if ((pRVar2->header).status == -1)
goto LAB_0001151c;
}
ReleaseMessage((CmdHeader*)pRVar2, 1);
}
LAB_0001151c:
iVar4 = iVar4 + -1;
ppCVar5 = ppCVar5 + -1;
} while (-1 < iVar4);
}
}
} // namespace jak2