mirror of
https://github.com/open-goal/jak-project.git
synced 2024-10-20 11:26:18 -04:00
e81431bd21
Some checks are pending
Build / 🖥️ Windows (push) Waiting to run
Build / 🐧 Linux (push) Waiting to run
Build / 🍎 MacOS (push) Waiting to run
Inform Pages Repo / Generate Documentation (push) Waiting to run
Lint / 📝 Required Checks (push) Waiting to run
Lint / 📝 Optional Checks (push) Waiting to run
Lint / 📝 Formatting (push) Waiting to run
1066 lines
32 KiB
C++
1066 lines
32 KiB
C++
#include "spustreams.h"
|
|
|
|
#include <cstring>
|
|
|
|
#include "common/log/log.h"
|
|
#include "common/util/Assert.h"
|
|
|
|
#include "game/overlord/jak3/basefile.h"
|
|
#include "game/overlord/jak3/dma.h"
|
|
#include "game/overlord/jak3/iso.h"
|
|
#include "game/overlord/jak3/iso_queue.h"
|
|
#include "game/overlord/jak3/ssound.h"
|
|
#include "game/overlord/jak3/streamlist.h"
|
|
#include "game/overlord/jak3/vag.h"
|
|
#include "game/sce/iop.h"
|
|
#include "game/sound/sdshim.h"
|
|
|
|
namespace jak3 {
|
|
using namespace iop;
|
|
void jak3_overlord_init_globals_spustreams() {}
|
|
|
|
u32 bswap_read32(u32 param_1) {
|
|
return param_1 >> 0x18 | ((int)param_1 >> 8 & 0xff00U) | (param_1 & 0xff00) << 8 |
|
|
param_1 << 0x18;
|
|
}
|
|
|
|
void UpdateIsoBuffer(ISO_VAGCommand* cmd, int length) {
|
|
ASSERT(cmd);
|
|
ASSERT(cmd->m_pBaseFile);
|
|
|
|
auto* file = cmd->m_pBaseFile;
|
|
int transfer_size = cmd->xfer_size;
|
|
|
|
// advance progress in file
|
|
file->m_Buffer.m_pCurrentData += length;
|
|
|
|
// this part is weird - we've advanced the current data pointer, and now we're updating the
|
|
// size field in the buffer. But, we're potentially adjusting the size in between these.
|
|
// This means that our m_pCurrentData + m_DataLength may go off the end of the buffer??
|
|
int tranferred_already = -length;
|
|
if (transfer_size < length) {
|
|
tranferred_already = -transfer_size;
|
|
length = transfer_size;
|
|
// ASSERT_NOT_REACHED(); // for now...
|
|
}
|
|
cmd->xfer_size = transfer_size + tranferred_already;
|
|
file->m_Buffer.AddData(-length);
|
|
cmd->num_isobuffered_chunks = cmd->num_isobuffered_chunks + 1;
|
|
}
|
|
|
|
/*!
|
|
* Callback for handling VAG data. This transfers data from the Page buffers to SPU memory.
|
|
*/
|
|
EIsoStatus ProcessVAGData(ISO_Hdr* _msg) {
|
|
int spu_addr;
|
|
u32 uVar1;
|
|
int iVar2;
|
|
u32 val;
|
|
uint8_t* iop_mem;
|
|
int* piVar4;
|
|
int iVar5;
|
|
int iVar6;
|
|
ISO_VAGCommand* sibling;
|
|
u32 val2;
|
|
CBuffer* buffer;
|
|
CBaseFile* file;
|
|
int length;
|
|
// int iVar9;
|
|
// undefined4 local_28[2];
|
|
bool got_chunks;
|
|
|
|
ASSERT(_msg);
|
|
auto* msg = (ISO_VAGCommand*)_msg;
|
|
ASSERT(msg->m_pBaseFile);
|
|
file = msg->m_pBaseFile;
|
|
ASSERT(file->m_ProcessDataSemaphore != -1);
|
|
|
|
// lock the semaphore
|
|
// lg::error("--------------- proces vag!!! {}\n", msg->name);
|
|
WaitSema(file->m_ProcessDataSemaphore);
|
|
buffer = &file->m_Buffer;
|
|
|
|
if (msg->unk_gvsp_flag) {
|
|
lg::error("unk gvsp flag set in process data - no more needed??");
|
|
}
|
|
|
|
// reject if errored/stopped - in this case no more data is needed.
|
|
if (msg->unk_gvsp_flag || msg->flags.stop || msg->flags.file_disappeared ||
|
|
msg->flags.stereo_secondary) {
|
|
goto exit;
|
|
}
|
|
|
|
// reject if error.
|
|
if (msg->error != 0) {
|
|
file->m_Buffer.m_nDataLength = 0;
|
|
goto exit;
|
|
}
|
|
|
|
// reject if dma in progress - wait for that to finish first
|
|
if (msg->safe_to_modify_dma == 0) {
|
|
goto exit;
|
|
}
|
|
|
|
// determine the length we need to do an upload.
|
|
sibling = msg->stereo_sibling;
|
|
got_chunks = msg->num_isobuffered_chunks != 0;
|
|
length = 0x2000;
|
|
if (sibling) {
|
|
length = 0x4000;
|
|
}
|
|
|
|
// reject if not enough data.
|
|
if (got_chunks) {
|
|
int desired_length = length;
|
|
if (msg->xfer_size < length) {
|
|
desired_length = msg->xfer_size;
|
|
}
|
|
if ((int)file->m_Buffer.m_nDataLength < desired_length) {
|
|
lg::warn("ProcessVAG data is starved.");
|
|
goto exit;
|
|
}
|
|
}
|
|
|
|
// reject if no buffer
|
|
if (!buffer->m_pPageList || !buffer->m_pPageList->m_pCurrentActivePage)
|
|
goto exit;
|
|
|
|
// update buffer so it handles page crossing
|
|
file->CheckPageBoundary();
|
|
CPage* page;
|
|
|
|
// add ref count to the page.
|
|
if (!buffer->m_pPageList || ((page = buffer->m_pPageList->m_pCurrentActivePage,
|
|
!page || (spu_addr = page->AddRef(), spu_addr < 1))))
|
|
goto exit;
|
|
|
|
// make sure the page has the right state. I think this should never really happen, but I guess
|
|
// they are paranoid.
|
|
if (page->input_state != CPage::State::READ_DONE) {
|
|
int status = page->ReleaseRef();
|
|
ASSERT(status >= 0);
|
|
goto exit;
|
|
}
|
|
|
|
if (got_chunks) { // if we've already started streaming, all way have to do is update.
|
|
if (msg->num_isobuffered_chunks & 1u) {
|
|
int vag_transfer_size = msg->xfer_size;
|
|
if ((length < vag_transfer_size) || ((u32)msg->unk_spu_mem_offset < 0x4000)) {
|
|
VAG_MarkLoopEnd(file->m_Buffer.m_pCurrentData, 0x2000);
|
|
VAG_MarkLoopStart(file->m_Buffer.m_pCurrentData);
|
|
if (sibling) {
|
|
VAG_MarkLoopEnd(file->m_Buffer.m_pCurrentData, 0x4000);
|
|
VAG_MarkLoopStart(file->m_Buffer.m_pCurrentData + 0x2000);
|
|
}
|
|
} else {
|
|
spu_addr = 0x2010;
|
|
if ((0x1f < (int)vag_transfer_size) &&
|
|
(spu_addr = vag_transfer_size + 0x1ff0, sibling != (ISO_VAGCommand*)0x0)) {
|
|
spu_addr = ((int)(vag_transfer_size + (vag_transfer_size >> 0x1f)) >> 1) + 0x1ff0;
|
|
}
|
|
msg->unk_spu_mem_offset = spu_addr;
|
|
if (sibling != (ISO_VAGCommand*)0x0) {
|
|
sibling->unk_spu_mem_offset = msg->unk_spu_mem_offset;
|
|
}
|
|
}
|
|
// CpuSuspendIntr(local_28);
|
|
iop_mem = file->m_Buffer.m_pCurrentData;
|
|
spu_addr = msg->stream_sram + 0x2000;
|
|
} else {
|
|
int vag_transfer_size = msg->xfer_size;
|
|
if ((length < (int)vag_transfer_size) || ((u32)msg->unk_spu_mem_offset < 0x4000)) {
|
|
VAG_MarkLoopEnd(file->m_Buffer.m_pCurrentData, 0x2000);
|
|
VAG_MarkLoopStart(file->m_Buffer.m_pCurrentData);
|
|
if (sibling) {
|
|
VAG_MarkLoopEnd(file->m_Buffer.m_pCurrentData, 0x4000);
|
|
VAG_MarkLoopStart(file->m_Buffer.m_pCurrentData + 0x2000);
|
|
}
|
|
} else {
|
|
spu_addr = 0x10;
|
|
if ((0x1f < (int)vag_transfer_size) &&
|
|
(spu_addr = vag_transfer_size - 0x10, sibling != (ISO_VAGCommand*)0x0)) {
|
|
spu_addr = ((int)(vag_transfer_size + (vag_transfer_size >> 0x1f)) >> 1) + -0x10;
|
|
}
|
|
msg->unk_spu_mem_offset = spu_addr;
|
|
if (sibling != (ISO_VAGCommand*)0x0) {
|
|
sibling->unk_spu_mem_offset = msg->unk_spu_mem_offset;
|
|
}
|
|
}
|
|
// CpuSuspendIntr(local_28);
|
|
iop_mem = file->m_Buffer.m_pCurrentData;
|
|
spu_addr = msg->stream_sram;
|
|
}
|
|
spu_addr = DMA_SendToSPUAndSync(iop_mem, 0x2000, spu_addr, msg, page);
|
|
if (spu_addr != 0) {
|
|
set_active_b(msg, 0);
|
|
goto LAB_000106a0;
|
|
}
|
|
LAB_0001067c:
|
|
//
|
|
{
|
|
int status = page->ReleaseRef();
|
|
ASSERT(status >= 0);
|
|
}
|
|
|
|
} else {
|
|
// we're starting the vag file! check the header:
|
|
piVar4 = (int*)file->m_Buffer.m_pCurrentData;
|
|
if ((*piVar4 != 0x70474156) && (*piVar4 != 0x56414770)) {
|
|
lg::error("Invalid VAG data is 0x{:x}", *piVar4);
|
|
ASSERT_NOT_REACHED(); // invalid data
|
|
msg->error = 1;
|
|
file->m_Buffer.m_nDataLength = 0;
|
|
int status = page->ReleaseRef();
|
|
ASSERT(status >= 0);
|
|
goto exit;
|
|
}
|
|
|
|
// read the rate/xfer size.
|
|
val = piVar4[4];
|
|
msg->vag_file_rate = val;
|
|
val2 = piVar4[3];
|
|
msg->unk_gvsp_cntr = 0;
|
|
msg->xfer_size = val2;
|
|
if (*piVar4 == 0x70474156) {
|
|
uVar1 = bswap_read32(val);
|
|
msg->vag_file_rate = uVar1;
|
|
uVar1 = bswap_read32(val2);
|
|
msg->xfer_size = uVar1;
|
|
}
|
|
|
|
// lg::die("xfer size is {}", msg->xfer_size);
|
|
|
|
// set sibling properties
|
|
if (sibling) {
|
|
spu_addr = msg->xfer_size;
|
|
sibling->vag_file_rate = msg->vag_file_rate;
|
|
sibling->xfer_size = spu_addr;
|
|
sibling->unk_gvsp_cntr = 0;
|
|
}
|
|
|
|
spu_addr = msg->xfer_size;
|
|
if (sibling != (ISO_VAGCommand*)0x0) {
|
|
spu_addr = spu_addr >> 1;
|
|
}
|
|
uVar1 = spu_addr + 0x30;
|
|
if ((uVar1 & 0x1fff) != 0) {
|
|
uVar1 = (uVar1 - (uVar1 & 0x1fff)) + 0x2000;
|
|
}
|
|
if (sibling != (ISO_VAGCommand*)0x0) {
|
|
uVar1 = uVar1 * 2;
|
|
}
|
|
uVar1 = (uVar1 + 0x7fff) >> 0xf;
|
|
if (uVar1 == 0) {
|
|
uVar1 = 1;
|
|
}
|
|
file->m_LengthPages = uVar1;
|
|
iVar6 = msg->vag_file_rate;
|
|
iVar5 = msg->xfer_size;
|
|
spu_addr = iVar5 + 0x30;
|
|
msg->unk_spu_mem_offset = 0x4000;
|
|
msg->xfer_size = spu_addr;
|
|
uVar1 = (u32)(iVar6 << 0xc) / 48000;
|
|
msg->pitch1_file = uVar1;
|
|
msg->pitch1 = uVar1;
|
|
if (spu_addr < 0x2001) {
|
|
iVar2 = 0x10;
|
|
if (0x1f < spu_addr) {
|
|
iVar2 = iVar5 + 0x20;
|
|
}
|
|
msg->unk_spu_mem_offset = iVar2;
|
|
if (sibling != (ISO_VAGCommand*)0x0) {
|
|
sibling->xfer_size = msg->xfer_size;
|
|
sibling->unk_spu_mem_offset = msg->unk_spu_mem_offset;
|
|
sibling->vag_file_rate = iVar6;
|
|
sibling->pitch1 = msg->pitch1;
|
|
sibling->pitch1_file = msg->pitch1_file;
|
|
sibling->xfer_size = msg->xfer_size;
|
|
sibling->unk_spu_mem_offset = msg->unk_spu_mem_offset;
|
|
sibling->unk_gvsp_cntr = 0;
|
|
}
|
|
}
|
|
// CpuSuspendIntr(local_28);
|
|
spu_addr =
|
|
DMA_SendToSPUAndSync(file->m_Buffer.m_pCurrentData, 0x2000, msg->stream_sram, msg, page);
|
|
if (spu_addr == 0)
|
|
goto LAB_0001067c;
|
|
msg->position_for_ee = 0;
|
|
msg->unk_gvsp_len = 0;
|
|
if (sibling) { // added.
|
|
sibling->position_for_ee = 0;
|
|
}
|
|
LAB_000106a0:
|
|
UpdateIsoBuffer(msg, length);
|
|
}
|
|
// CpuResumeIntr(local_28[0]);
|
|
exit:
|
|
SignalSema(file->m_ProcessDataSemaphore);
|
|
return EIsoStatus::OK_2;
|
|
}
|
|
|
|
u32 GetSpuRamAddress(ISO_VAGCommand* cmd) {
|
|
return sceSdGetAddr(SD_VA_NAX | cmd->voice);
|
|
|
|
u32 voice = cmd->voice;
|
|
u32 current_addr = cmd->stream_sram;
|
|
BlockUntilVoiceSafe(voice, 0xf00);
|
|
u32 sce_addr = sceSdGetAddr(voice | 0x2240);
|
|
// lg::info("sce addr {}", sce_addr);
|
|
if ((sce_addr < current_addr) || (current_addr + 0x4040 <= sce_addr)) {
|
|
ASSERT_NOT_REACHED();
|
|
sce_addr = current_addr + 0x4040;
|
|
}
|
|
return sce_addr;
|
|
}
|
|
|
|
u32 GetVAGStreamPos(ISO_VAGCommand* cmd) {
|
|
u32 uVar1;
|
|
int iVar2;
|
|
u32 uVar3;
|
|
u32 uVar4;
|
|
ISO_VAGCommand* sibling;
|
|
u32 uVar5;
|
|
// undefined4 local_20[2];
|
|
|
|
sibling = cmd->stereo_sibling;
|
|
if (cmd->id == 0) {
|
|
cmd->position_for_ee = 0;
|
|
if (sibling == (ISO_VAGCommand*)0x0) {
|
|
return 0;
|
|
}
|
|
sibling->position_for_ee = 0;
|
|
return 0;
|
|
}
|
|
if (cmd->flags.file_disappeared != 0) {
|
|
cmd->position_for_ee = cmd->clockd;
|
|
if (sibling == (ISO_VAGCommand*)0x0) {
|
|
return 0;
|
|
}
|
|
sibling->position_for_ee = sibling->clockd;
|
|
return 0;
|
|
}
|
|
if (((cmd->flags.running == 0) || (cmd->flags.saw_chunks1 == 0)) || (cmd->flags.paused != 0)) {
|
|
cmd->position_for_ee = cmd->clocka;
|
|
if (sibling == (ISO_VAGCommand*)0x0) {
|
|
return 0;
|
|
}
|
|
sibling->position_for_ee = sibling->clocka;
|
|
return 0;
|
|
}
|
|
if (cmd->flags.stereo_secondary != 0) {
|
|
cmd->position_for_ee = cmd->clocka;
|
|
return 0;
|
|
}
|
|
// CpuSuspendIntr(local_20);
|
|
uVar1 = GetSpuRamAddress(cmd);
|
|
uVar5 = 0;
|
|
// lg::info("offset is {}, {} - {}\n", uVar1 - cmd->stream_sram, uVar1, cmd->stream_sram);
|
|
uVar1 = uVar1 - cmd->stream_sram;
|
|
if (sibling != (ISO_VAGCommand*)0x0) {
|
|
uVar5 = GetSpuRamAddress(sibling);
|
|
uVar5 = uVar5 - sibling->stream_sram;
|
|
}
|
|
// CpuResumeIntr(local_20[0]);
|
|
if (sibling != (ISO_VAGCommand*)0x0) {
|
|
if (((uVar1 < 0x4000) && (uVar5 < 0x4000)) &&
|
|
((cmd->flags.bit20 == 0 && (sibling->flags.bit20 == 0)))) {
|
|
iVar2 = (int)((uVar1 - uVar5) * 0x40000) >> 0x12;
|
|
if (iVar2 < 0) {
|
|
iVar2 = -iVar2;
|
|
}
|
|
if (4 < iVar2) {
|
|
PauseVAG(cmd);
|
|
uVar1 = cmd->current_spu_address - cmd->stream_sram;
|
|
uVar5 = sibling->current_spu_address - sibling->stream_sram;
|
|
UnPauseVAG(cmd);
|
|
}
|
|
}
|
|
if (sibling == (ISO_VAGCommand*)0x0)
|
|
goto LAB_00011010;
|
|
// CpuSuspendIntr(local_20);
|
|
// lg::info("inner values are: {} {}", uVar1, uVar5);
|
|
if ((0x4000 < uVar1) && (cmd->flags.bit20 == 0)) {
|
|
cmd->flags.bit20 = 1;
|
|
cmd->flags.bit21 = 0;
|
|
cmd->flags.bit22 = 0;
|
|
sibling->flags.bit20 = 1;
|
|
sibling->flags.bit21 = 0;
|
|
sibling->flags.bit22 = 0;
|
|
}
|
|
if (uVar5 < 0x4001) {
|
|
if (uVar1 < 0x2000) {
|
|
if (cmd->flags.bit21 == 0) {
|
|
cmd->unk_gvsp_cntr = cmd->unk_gvsp_cntr + 1;
|
|
cmd->flags.bit21 = 1;
|
|
cmd->flags.bit22 = 0;
|
|
LAB_000109b8:
|
|
cmd->flags.bit20 = 0;
|
|
}
|
|
} else {
|
|
if (cmd->flags.bit22 == 0) {
|
|
cmd->unk_gvsp_cntr = cmd->unk_gvsp_cntr + 1;
|
|
cmd->flags.bit22 = 1;
|
|
cmd->flags.bit21 = 0;
|
|
goto LAB_000109b8;
|
|
}
|
|
}
|
|
if (uVar5 < 0x2000) {
|
|
if (sibling->flags.bit21 == 0) {
|
|
sibling->unk_gvsp_cntr = sibling->unk_gvsp_cntr + 1;
|
|
sibling->flags.bit21 = 1;
|
|
sibling->flags.bit22 = 0;
|
|
LAB_00010a1c:
|
|
sibling->flags.bit20 = 0;
|
|
}
|
|
} else {
|
|
if (sibling->flags.bit22 == 0) {
|
|
sibling->unk_gvsp_cntr = sibling->unk_gvsp_cntr + 1;
|
|
sibling->flags.bit22 = 1;
|
|
sibling->flags.bit21 = 0;
|
|
goto LAB_00010a1c;
|
|
}
|
|
}
|
|
} else {
|
|
if (sibling->flags.bit20 == 0) {
|
|
cmd->flags.bit20 = 1;
|
|
cmd->flags.bit21 = 0;
|
|
cmd->flags.bit22 = 0;
|
|
sibling->flags.bit20 = 1;
|
|
sibling->flags.bit21 = 0;
|
|
sibling->flags.bit22 = 0;
|
|
}
|
|
}
|
|
// lg::info("bits are {} {} {}\n", cmd->flags.bit20, cmd->flags.bit21, cmd->flags.bit22);
|
|
// CpuResumeIntr(local_20[0]);
|
|
if (cmd->unk_gvsp_flag != 0)
|
|
goto switchD_00010a60_caseD_1;
|
|
|
|
// lg::info("switching {}", cmd->unk_gvsp_state2);
|
|
switch (cmd->unk_gvsp_state2) {
|
|
case 0:
|
|
if ((((cmd->flags.dma_complete_even_chunk_count == 0) || (cmd->flags.bit21 == 0)) ||
|
|
(sibling->flags.dma_complete_even_chunk_count == 0)) ||
|
|
(sibling->flags.bit21 == 0))
|
|
goto switchD_00010a60_caseD_1;
|
|
cmd->flags.dma_complete_even_chunk_count = 0;
|
|
cmd->unk_gvsp_state2 = 2;
|
|
sibling->flags.dma_complete_even_chunk_count = 0;
|
|
sibling->unk_gvsp_state2 = 2;
|
|
case 2:
|
|
if ((cmd->flags.dma_complete_odd_chunk_count == 0) ||
|
|
(sibling->flags.dma_complete_odd_chunk_count == 0)) {
|
|
if ((cmd->flags.bit20 != 0) || (sibling->flags.bit20 != 0)) {
|
|
uVar1 = 0x2000;
|
|
uVar5 = 0x2000;
|
|
cmd->flags.bit17 = 1;
|
|
cmd->flags.bit16 = 0;
|
|
cmd->unk_gvsp_state2 = 4;
|
|
sibling->flags.bit17 = 1;
|
|
sibling->unk_gvsp_state2 = 4;
|
|
LAB_00010efc:
|
|
sibling->flags.bit16 = 0;
|
|
}
|
|
goto switchD_00010a60_caseD_1;
|
|
}
|
|
if ((cmd->flags.bit20 == 0) && (sibling->flags.bit20 == 0)) {
|
|
BlockUntilVoiceSafe(cmd->voice, 0xf00);
|
|
BlockUntilVoiceSafe(sibling->voice, 0xf00);
|
|
// CpuSuspendIntr(local_20);
|
|
// lg::info("sax case 1 (stream)");
|
|
sceSdSetAddr(cmd->voice | 0x2140, cmd->stream_sram + 0x2000);
|
|
sceSdSetAddr(sibling->voice | 0x2140, sibling->stream_sram + 0x2000);
|
|
iVar2 = 3;
|
|
cmd->flags.bit15 = 1;
|
|
cmd->flags.bit14 = 0;
|
|
cmd->flags.bit13 = 0;
|
|
sibling->flags.bit15 = 1;
|
|
sibling->flags.bit14 = 0;
|
|
LAB_00010d78:
|
|
sibling->flags.bit13 = 0;
|
|
LAB_00010e78:
|
|
cmd->unk_gvsp_state2 = iVar2;
|
|
sibling->unk_gvsp_state2 = iVar2;
|
|
// CpuResumeIntr(local_20[0]);
|
|
goto switchD_00010a60_caseD_1;
|
|
}
|
|
LAB_00010bc4:
|
|
RestartVag(cmd, 1);
|
|
uVar1 = 0x2000;
|
|
iVar2 = 9;
|
|
uVar5 = 0x2000;
|
|
break;
|
|
default:
|
|
goto switchD_00010a60_caseD_1;
|
|
case 3:
|
|
// lg::info("case 3 bits: ({} {}) ({} {})\n", cmd->flags.bit20, cmd->flags.bit22,
|
|
// sibling->flags.bit20, sibling->flags.bit22);
|
|
if ((cmd->flags.bit20 != 0) || (sibling->flags.bit20 != 0))
|
|
goto LAB_00010bc4;
|
|
if ((cmd->flags.bit22 == 0) || (sibling->flags.bit22 == 0))
|
|
goto switchD_00010a60_caseD_1;
|
|
BlockUntilVoiceSafe(cmd->voice, 0xf00);
|
|
BlockUntilVoiceSafe(sibling->voice, 0xf00);
|
|
// CpuSuspendIntr(local_20);
|
|
// lg::info("sax case 2 (trap)");
|
|
sceSdSetAddr(cmd->voice | 0x2140, cmd->trap_sram);
|
|
sceSdSetAddr(sibling->voice | 0x2140, sibling->trap_sram);
|
|
iVar2 = 5;
|
|
cmd->flags.bit13 = 1;
|
|
cmd->flags.bit14 = 0;
|
|
cmd->flags.bit15 = 0;
|
|
sibling->flags.bit13 = 1;
|
|
sibling->flags.bit14 = 0;
|
|
sibling->flags.bit15 = 0;
|
|
cmd->flags.dma_complete_odd_chunk_count = 0;
|
|
sibling->flags.dma_complete_odd_chunk_count = 0;
|
|
goto LAB_00010e78;
|
|
case 4:
|
|
uVar1 = cmd->unk_gvsp_len;
|
|
uVar5 = sibling->unk_gvsp_len;
|
|
if ((cmd->flags.dma_complete_odd_chunk_count == 0) ||
|
|
(sibling->flags.dma_complete_odd_chunk_count == 0))
|
|
goto switchD_00010a60_caseD_1;
|
|
RestartVag(cmd, 1);
|
|
iVar2 = 9;
|
|
break;
|
|
case 5:
|
|
if ((cmd->flags.dma_complete_even_chunk_count == 0) ||
|
|
(sibling->flags.dma_complete_even_chunk_count == 0)) {
|
|
if (cmd->flags.bit20 == 0)
|
|
goto switchD_00010a60_caseD_1;
|
|
cmd->flags.bit16 = 1;
|
|
cmd->flags.bit17 = 0;
|
|
cmd->unk_gvsp_state2 = 7;
|
|
uVar1 = 0x4000;
|
|
uVar5 = 0x4000;
|
|
sibling->flags.bit16 = 1;
|
|
sibling->unk_gvsp_state2 = 7;
|
|
goto LAB_00010db0;
|
|
}
|
|
if ((cmd->flags.bit20 != 0) || (sibling->flags.bit20 != 0))
|
|
goto LAB_00010dd8;
|
|
BlockUntilVoiceSafe(cmd->voice, 0xf00);
|
|
BlockUntilVoiceSafe(sibling->voice, 0xf00);
|
|
// CpuSuspendIntr(local_20);
|
|
// lg::info("sax case 3 (stream)");
|
|
sceSdSetAddr(cmd->voice | 0x2140, cmd->stream_sram);
|
|
sceSdSetAddr(sibling->voice | 0x2140, sibling->stream_sram);
|
|
iVar2 = 6;
|
|
cmd->flags.bit14 = 1;
|
|
cmd->flags.bit15 = 0;
|
|
cmd->flags.bit13 = 0;
|
|
sibling->flags.bit14 = 1;
|
|
sibling->flags.bit15 = 0;
|
|
goto LAB_00010d78;
|
|
case 6:
|
|
if ((cmd->flags.bit20 == 0) && (sibling->flags.bit20 == 0)) {
|
|
if ((cmd->flags.bit21 == 0) || (sibling->flags.bit21 == 0))
|
|
goto switchD_00010a60_caseD_1;
|
|
BlockUntilVoiceSafe(cmd->voice, 0xf00);
|
|
BlockUntilVoiceSafe(sibling->voice, 0xf00);
|
|
// CpuSuspendIntr(local_20);
|
|
// lg::info("sax case 4 (trap)");
|
|
sceSdSetAddr(cmd->voice | 0x2140, cmd->trap_sram);
|
|
sceSdSetAddr(sibling->voice | 0x2140, sibling->trap_sram);
|
|
cmd->flags.bit13 = 1;
|
|
cmd->flags.bit14 = 0;
|
|
cmd->flags.bit15 = 0;
|
|
iVar2 = 2;
|
|
sibling->flags.bit13 = 1;
|
|
sibling->flags.bit14 = 0;
|
|
sibling->flags.bit15 = 0;
|
|
cmd->flags.dma_complete_even_chunk_count = 0;
|
|
sibling->flags.dma_complete_even_chunk_count = 0;
|
|
goto LAB_00010e78;
|
|
}
|
|
LAB_00010dd8:
|
|
RestartVag(cmd, 0);
|
|
uVar1 = 0x4000;
|
|
iVar2 = 8;
|
|
uVar5 = 0x4000;
|
|
break;
|
|
case 7:
|
|
uVar1 = cmd->unk_gvsp_len;
|
|
uVar5 = uVar1;
|
|
if ((cmd->flags.dma_complete_even_chunk_count == 0) ||
|
|
(uVar5 = uVar1, sibling->flags.dma_complete_even_chunk_count == 0))
|
|
goto switchD_00010a60_caseD_1;
|
|
RestartVag(cmd, 0);
|
|
iVar2 = 8;
|
|
uVar5 = uVar1;
|
|
break;
|
|
case 8:
|
|
if ((cmd->flags.bit21 == 0) || (sibling->flags.bit21 == 0)) {
|
|
uVar1 = cmd->unk_gvsp_len;
|
|
uVar5 = uVar1;
|
|
goto switchD_00010a60_caseD_1;
|
|
}
|
|
cmd->unk_gvsp_state2 = 6;
|
|
cmd->flags.bit16 = 0;
|
|
sibling->unk_gvsp_state2 = 6;
|
|
goto LAB_00010efc;
|
|
case 9:
|
|
if ((cmd->flags.bit22 == 0) || (sibling->flags.bit22 == 0)) {
|
|
uVar1 = cmd->unk_gvsp_len;
|
|
uVar5 = sibling->unk_gvsp_len;
|
|
goto switchD_00010a60_caseD_1;
|
|
}
|
|
cmd->unk_gvsp_state2 = 3;
|
|
cmd->flags.bit17 = 0;
|
|
sibling->unk_gvsp_state2 = 3;
|
|
LAB_00010db0:
|
|
sibling->flags.bit17 = 0;
|
|
goto switchD_00010a60_caseD_1;
|
|
}
|
|
cmd->unk_gvsp_state2 = iVar2;
|
|
sibling->unk_gvsp_state2 = iVar2;
|
|
switchD_00010a60_caseD_1:
|
|
if (cmd->unk_gvsp_cntr == 0) {
|
|
cmd->clockc = uVar1;
|
|
sibling->clockc = uVar1;
|
|
} else {
|
|
iVar2 = sibling->unk_gvsp_cntr;
|
|
cmd->clockc = uVar1 + cmd->unk_gvsp_cntr * 0x2000 + -0x2000;
|
|
sibling->clockc = uVar5 + iVar2 * 0x2000 + -0x2000;
|
|
if (0x2000 < uVar1) {
|
|
cmd->clockc = cmd->clockc + -0x2000;
|
|
}
|
|
if (0x2000 < uVar5) {
|
|
sibling->clockc = sibling->clockc + -0x2000;
|
|
}
|
|
}
|
|
uVar4 = cmd->vag_file_rate;
|
|
if (uVar4 == 0) {
|
|
uVar3 = 0;
|
|
} else {
|
|
uVar3 = (u32)(cmd->clockc * 0x1c0) / uVar4;
|
|
if (uVar4 == 0) {
|
|
ASSERT_NOT_REACHED();
|
|
}
|
|
}
|
|
iVar2 = sibling->clockc;
|
|
uVar4 = sibling->vag_file_rate;
|
|
cmd->unk_gvsp_len = uVar1;
|
|
cmd->position_for_ee = uVar3 << 2;
|
|
cmd->clocka = uVar3 << 2;
|
|
if (uVar4 == 0) {
|
|
uVar1 = 0;
|
|
} else {
|
|
uVar1 = (u32)(iVar2 * 0x1c0) / uVar4;
|
|
if (uVar4 == 0) {
|
|
ASSERT_NOT_REACHED();
|
|
}
|
|
}
|
|
sibling->unk_gvsp_len = uVar5;
|
|
sibling->position_for_ee = uVar1 << 2;
|
|
sibling->clocka = uVar1 << 2;
|
|
return 0;
|
|
}
|
|
LAB_00011010:
|
|
if (uVar1 < 0x4001) {
|
|
if (uVar1 < 0x2000) {
|
|
if (cmd->flags.bit21 == 0) {
|
|
cmd->unk_gvsp_cntr = cmd->unk_gvsp_cntr + 1;
|
|
cmd->flags.bit21 = 1;
|
|
cmd->flags.bit22 = 0;
|
|
LAB_00011098:
|
|
cmd->flags.bit20 = 0;
|
|
}
|
|
} else {
|
|
if (cmd->flags.bit22 == 0) {
|
|
cmd->unk_gvsp_cntr = cmd->unk_gvsp_cntr + 1;
|
|
cmd->flags.bit22 = 1;
|
|
cmd->flags.bit21 = 0;
|
|
goto LAB_00011098;
|
|
}
|
|
}
|
|
} else {
|
|
if (cmd->flags.bit20 == 0) {
|
|
cmd->flags.bit20 = 1;
|
|
cmd->flags.bit21 = 0;
|
|
cmd->flags.bit22 = 0;
|
|
}
|
|
}
|
|
if (cmd->unk_gvsp_flag != 0)
|
|
goto switchD_000110d0_caseD_1;
|
|
switch (cmd->unk_gvsp_state2) {
|
|
case 0:
|
|
if ((cmd->flags.dma_complete_even_chunk_count == 0) || (cmd->flags.bit21 == 0))
|
|
goto switchD_000110d0_caseD_1;
|
|
cmd->unk_gvsp_state2 = 2;
|
|
cmd->flags.dma_complete_even_chunk_count = 0;
|
|
switchD_000110d0_caseD_2:
|
|
if (cmd->flags.dma_complete_odd_chunk_count == 0) {
|
|
if (cmd->flags.bit20 != 0) {
|
|
uVar1 = 0x2000;
|
|
iVar2 = 4;
|
|
cmd->flags.bit17 = 1;
|
|
LAB_00011368:
|
|
cmd->unk_gvsp_state2 = iVar2;
|
|
cmd->flags.bit16 = 0;
|
|
}
|
|
} else {
|
|
if (cmd->flags.bit20 == 0) {
|
|
BlockUntilVoiceSafe(cmd->voice, 0xf00);
|
|
// CpuSuspendIntr(local_20);
|
|
sceSdSetAddr(cmd->voice | 0x2140, cmd->stream_sram + 0x2000);
|
|
cmd->flags.bit15 = 1;
|
|
cmd->unk_gvsp_state2 = 3;
|
|
cmd->flags.bit14 = 0;
|
|
LAB_00011284:
|
|
cmd->flags.bit13 = 0;
|
|
LAB_00011324:;
|
|
// CpuResumeIntr(local_20[0]);
|
|
} else {
|
|
LAB_00011188:
|
|
RestartVag(cmd, 1);
|
|
uVar1 = 0x2000;
|
|
LAB_0001120c:
|
|
iVar2 = 9;
|
|
LAB_00011350:
|
|
cmd->unk_gvsp_state2 = iVar2;
|
|
}
|
|
}
|
|
switchD_000110d0_caseD_1:
|
|
if (cmd->unk_gvsp_cntr == 0) {
|
|
cmd->clockc = uVar1;
|
|
} else {
|
|
iVar2 = uVar1 + cmd->unk_gvsp_cntr * 0x2000;
|
|
cmd->clockc = iVar2 + -0x2000;
|
|
if (0x2000 < uVar1) {
|
|
cmd->clockc = iVar2 + -0x4000;
|
|
}
|
|
}
|
|
uVar5 = cmd->vag_file_rate;
|
|
if (uVar5 == 0) {
|
|
uVar4 = 0;
|
|
} else {
|
|
uVar4 = (u32)(cmd->clockc * 0x1c0) / uVar5;
|
|
if (uVar5 == 0) {
|
|
// trap(0x1c00);
|
|
ASSERT_NOT_REACHED();
|
|
}
|
|
}
|
|
cmd->unk_gvsp_len = uVar1;
|
|
cmd->position_for_ee = uVar4 << 2;
|
|
cmd->clocka = uVar4 << 2;
|
|
return 0;
|
|
default:
|
|
goto switchD_000110d0_caseD_1;
|
|
case 2:
|
|
goto switchD_000110d0_caseD_2;
|
|
case 3:
|
|
if (cmd->flags.bit20 != 0)
|
|
goto LAB_00011188;
|
|
if (cmd->flags.bit22 == 0)
|
|
goto switchD_000110d0_caseD_1;
|
|
BlockUntilVoiceSafe(cmd->voice, 0xf00);
|
|
// CpuSuspendIntr(local_20);
|
|
sceSdSetAddr(cmd->voice | 0x2140, cmd->trap_sram);
|
|
cmd->flags.bit13 = 1;
|
|
cmd->unk_gvsp_state2 = 5;
|
|
cmd->flags.bit14 = 0;
|
|
cmd->flags.bit15 = 0;
|
|
cmd->flags.dma_complete_odd_chunk_count = 0;
|
|
goto LAB_00011324;
|
|
case 4:
|
|
uVar1 = cmd->unk_gvsp_len;
|
|
if (cmd->flags.dma_complete_odd_chunk_count == 0)
|
|
goto switchD_000110d0_caseD_1;
|
|
RestartVag(cmd, 1);
|
|
goto LAB_0001120c;
|
|
case 5:
|
|
if (cmd->flags.dma_complete_even_chunk_count == 0) {
|
|
if (cmd->flags.bit20 == 0)
|
|
goto switchD_000110d0_caseD_1;
|
|
uVar1 = 0x4000;
|
|
cmd->flags.bit16 = 1;
|
|
iVar2 = 7;
|
|
goto LAB_000112a0;
|
|
}
|
|
if (cmd->flags.bit20 != 0)
|
|
goto LAB_000112bc;
|
|
BlockUntilVoiceSafe(cmd->voice, 0xf00);
|
|
// CpuSuspendIntr(local_20);
|
|
sceSdSetAddr(cmd->voice | 0x2140, cmd->stream_sram);
|
|
cmd->flags.bit14 = 1;
|
|
cmd->unk_gvsp_state2 = 6;
|
|
cmd->flags.bit15 = 0;
|
|
goto LAB_00011284;
|
|
case 6:
|
|
if (cmd->flags.bit20 == 0) {
|
|
if (cmd->flags.bit21 == 0)
|
|
goto switchD_000110d0_caseD_1;
|
|
BlockUntilVoiceSafe(cmd->voice, 0xf00);
|
|
// CpuSuspendIntr(local_20);
|
|
sceSdSetAddr(cmd->voice | 0x2140, cmd->trap_sram);
|
|
cmd->flags.bit13 = 1;
|
|
cmd->unk_gvsp_state2 = 2;
|
|
cmd->flags.bit14 = 0;
|
|
cmd->flags.bit15 = 0;
|
|
cmd->flags.dma_complete_even_chunk_count = 0;
|
|
goto LAB_00011324;
|
|
}
|
|
LAB_000112bc:
|
|
RestartVag(cmd, 0);
|
|
uVar1 = 0x4000;
|
|
goto LAB_0001134c;
|
|
case 7:
|
|
uVar1 = cmd->unk_gvsp_len;
|
|
if (cmd->flags.dma_complete_even_chunk_count == 0)
|
|
goto switchD_000110d0_caseD_1;
|
|
RestartVag(cmd, 0);
|
|
LAB_0001134c:
|
|
iVar2 = 8;
|
|
goto LAB_00011350;
|
|
case 8:
|
|
iVar2 = 6;
|
|
if (cmd->flags.bit21 == 0) {
|
|
LAB_00011374:
|
|
uVar1 = cmd->unk_gvsp_len;
|
|
goto switchD_000110d0_caseD_1;
|
|
}
|
|
goto LAB_00011368;
|
|
case 9:
|
|
iVar2 = 3;
|
|
if (cmd->flags.bit22 == 0)
|
|
goto LAB_00011374;
|
|
LAB_000112a0:
|
|
cmd->unk_gvsp_state2 = iVar2;
|
|
cmd->flags.bit17 = 0;
|
|
goto switchD_000110d0_caseD_1;
|
|
}
|
|
}
|
|
|
|
u32 CheckVAGStreamProgress(ISO_VAGCommand* cmd) {
|
|
u32 uVar1;
|
|
u32 last_offset_in_stream_sram;
|
|
ISO_VAGCommand* pIVar3;
|
|
|
|
if (cmd->flags.file_disappeared == 0) {
|
|
if (cmd->flags.stereo_secondary != 0) {
|
|
return 1;
|
|
}
|
|
if (cmd->error != 0) {
|
|
return 0;
|
|
}
|
|
if ((cmd->flags.bit20 != 0) && (cmd->unk_gvsp_flag != 0)) {
|
|
return 0;
|
|
}
|
|
if (cmd->flags.saw_chunks1 == 0) {
|
|
return 1;
|
|
}
|
|
if (cmd->flags.paused != 0) {
|
|
return 1;
|
|
}
|
|
uVar1 = cmd->unk_spu_mem_offset;
|
|
pIVar3 = cmd->stereo_sibling;
|
|
last_offset_in_stream_sram = cmd->unk_gvsp_len;
|
|
if ((uVar1 < 0x4000) && (((last_offset_in_stream_sram < 0x2001 && (uVar1 < 0x2001)) ||
|
|
((0x1fff < last_offset_in_stream_sram && (0x1fff < uVar1)))))) {
|
|
if (uVar1 <= (last_offset_in_stream_sram & 0xfffffff0)) {
|
|
return 0;
|
|
}
|
|
// CpuSuspendIntr(local_18);
|
|
if ((cmd->unk_gvsp_flag == 0) &&
|
|
(last_offset_in_stream_sram < (u32)cmd->unk_spu_mem_offset)) {
|
|
BlockUntilVoiceSafe(cmd->voice, 0xf00);
|
|
sceSdSetAddr(cmd->voice | 0x2140, cmd->stream_sram + cmd->unk_spu_mem_offset);
|
|
cmd->unk_gvsp_flag = 1;
|
|
if (pIVar3 != (ISO_VAGCommand*)0x0) {
|
|
BlockUntilVoiceSafe(pIVar3->voice, 0xf00);
|
|
sceSdSetAddr(pIVar3->voice | 0x2140, pIVar3->stream_sram + cmd->unk_spu_mem_offset);
|
|
pIVar3->unk_gvsp_flag = 1;
|
|
}
|
|
}
|
|
set_active_a(cmd, 0);
|
|
set_active_b(cmd, 0);
|
|
// CpuResumeIntr(local_18[0]);
|
|
return 1;
|
|
}
|
|
if (cmd->flags.saw_chunks1 == 0) {
|
|
return 1;
|
|
}
|
|
if (cmd->active_b != 0) {
|
|
return 1;
|
|
}
|
|
if (cmd->safe_to_modify_dma == 0) {
|
|
return 1;
|
|
}
|
|
if (cmd->unk_gvsp_flag != 0) {
|
|
return 1;
|
|
}
|
|
if (last_offset_in_stream_sram < 0x2000) {
|
|
uVar1 = cmd->num_isobuffered_chunks;
|
|
} else {
|
|
uVar1 = cmd->num_isobuffered_chunks ^ 1;
|
|
}
|
|
if ((uVar1 & 1) == 0) {
|
|
return 1;
|
|
}
|
|
|
|
set_active_b(cmd, 1);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
void StopVagStream(ISO_VAGCommand* cmd) {
|
|
ISO_VAGCommand* sibling;
|
|
VagStreamData vsd;
|
|
// undefined auStack72 [36];
|
|
// int local_24;
|
|
// int local_20;
|
|
// undefined4 local_18 [2];
|
|
|
|
// CpuSuspendIntr(local_18);
|
|
sibling = cmd->stereo_sibling;
|
|
cmd->flags.saw_chunks1 = 0;
|
|
if (sibling != (ISO_VAGCommand*)0x0) {
|
|
sibling->flags.saw_chunks1 = 0;
|
|
}
|
|
if ((cmd->music_flag == 0) && (cmd->maybe_sound_handler != 0)) {
|
|
PauseVAG(cmd);
|
|
strncpy(vsd.name, cmd->name, 0x30);
|
|
vsd.id = cmd->id;
|
|
// RemoveVagStreamFromList(&vsd, &g_PluginStreamsList);
|
|
RemoveVagStreamFromList(&vsd, &g_EEPlayList);
|
|
// local_20 = cmd->plugin_id;
|
|
// local_24 = cmd->id;
|
|
// RemoveLfoStreamFromList(auStack72,&g_LfoStreamsList);
|
|
} else {
|
|
PauseVAG(cmd);
|
|
cmd->flags.stop = 1;
|
|
if (sibling != (ISO_VAGCommand*)0x0) {
|
|
PauseVAG(sibling);
|
|
cmd->flags.stop = 1;
|
|
}
|
|
}
|
|
// CpuResumeIntr(local_18[0]);
|
|
}
|
|
|
|
void ProcessStreamData() {
|
|
EIsoStatus iVar2;
|
|
CBuffer* pCVar3;
|
|
ISO_VAGCommand* msg;
|
|
int iVar5;
|
|
ISO_VAGCommand** ppIVar6;
|
|
|
|
WaitSema(g_nPriQueueSema);
|
|
if (gPriStack[1].count < 8) {
|
|
iVar5 = gPriStack[1].count + -1;
|
|
if (-1 < iVar5) {
|
|
ppIVar6 = (ISO_VAGCommand**)gPriStack[0].cmds + iVar5;
|
|
do {
|
|
msg = ppIVar6[9];
|
|
if (msg != (ISO_VAGCommand*)0x0) {
|
|
// lg::warn("process stream data for {}, {} {} {}\n", msg->name,
|
|
// (msg->status == EIsoStatus::OK_2), (msg->active_b != 0),
|
|
// (msg->active_c != 0));
|
|
if (((msg->status == EIsoStatus::OK_2) && (msg->active_b != 0)) && (msg->active_c != 0)) {
|
|
auto* file = msg->m_pBaseFile;
|
|
pCVar3 = &file->m_Buffer;
|
|
if (!file) {
|
|
pCVar3 = (CBuffer*)0x0;
|
|
}
|
|
if (((pCVar3 != (CBuffer*)0x0) &&
|
|
(pCVar3->m_eBufferType != CBuffer::BufferType::EBT_FREE)) &&
|
|
(msg->callback == ProcessVAGData)) {
|
|
iVar2 = ProcessVAGData(msg);
|
|
msg->status = iVar2;
|
|
if ((iVar2 != EIsoStatus::OK_2) && (msg->safe_to_modify_dma != 0)) {
|
|
ReleaseMessage(msg);
|
|
}
|
|
}
|
|
}
|
|
if (msg->status != EIsoStatus::OK_2) {
|
|
ReleaseMessage(msg);
|
|
}
|
|
}
|
|
iVar5 = iVar5 + -1;
|
|
ppIVar6 = ppIVar6 + -1;
|
|
} while (-1 < iVar5);
|
|
}
|
|
}
|
|
SignalSema(g_nPriQueueSema);
|
|
}
|
|
|
|
void CheckVagStreamsProgress() {
|
|
int now;
|
|
int iVar1;
|
|
bool* flags;
|
|
int iVar2;
|
|
u32* times;
|
|
ISO_VAGCommand* cmd;
|
|
|
|
if ((g_bVagCmdsInitialized != 0) && (g_bSoundEnable != 0)) {
|
|
now = GetSystemTimeLow();
|
|
times = voice_key_times;
|
|
flags = voice_key_flags;
|
|
iVar2 = 0x2f;
|
|
do {
|
|
iVar2 = iVar2 + -1;
|
|
if ((*flags != 0) && (0x17ff < (u32)(*times - now))) {
|
|
*flags = 0;
|
|
}
|
|
flags = flags + 1;
|
|
times = times + 1;
|
|
} while (-1 < iVar2);
|
|
if ((g_bRecentlyKeyedVoice != 0) && (0x17ff < (u32)(g_nTimeOfLastVoiceKey - now))) {
|
|
g_bRecentlyKeyedVoice = 0;
|
|
}
|
|
iVar2 = 5;
|
|
ProcessStreamData();
|
|
// CpuSuspendIntr(local_18);
|
|
cmd = g_aVagCmds;
|
|
do {
|
|
if (((cmd->flags.saw_chunks1 != 0) ||
|
|
((cmd->flags.running != 0 && (cmd->flags.file_disappeared != 0)))) ||
|
|
((cmd->active_b != 0 && (cmd->id != 0)))) {
|
|
iVar1 = CheckVAGStreamProgress(cmd);
|
|
if (iVar1 == 0) {
|
|
if (cmd->flags.stereo_secondary == 0) {
|
|
StopVagStream(cmd);
|
|
}
|
|
} else {
|
|
GetVAGStreamPos(cmd);
|
|
}
|
|
}
|
|
iVar2 = iVar2 + -1;
|
|
cmd = cmd + 1;
|
|
} while (-1 < iVar2);
|
|
// CpuResumeIntr(local_18[0]);
|
|
}
|
|
}
|
|
|
|
void BlockUntilAllVoicesSafe() {
|
|
int now;
|
|
int last_time;
|
|
|
|
last_time = g_nTimeOfLastVoiceKey;
|
|
if (g_bRecentlyKeyedVoice != 0) {
|
|
do {
|
|
now = GetSystemTimeLow();
|
|
} while ((u32)(now - last_time) < 0x900);
|
|
}
|
|
}
|
|
|
|
void BlockUntilVoiceSafe(int voice, u32 delay) {
|
|
int iVar1;
|
|
int iVar2;
|
|
|
|
if (voice_key_flags[voice] != 0) {
|
|
iVar2 = voice_key_times[voice];
|
|
do {
|
|
iVar1 = GetSystemTimeLow();
|
|
} while ((u32)(iVar1 - iVar2) < delay);
|
|
}
|
|
}
|
|
|
|
void MarkVoiceKeyedOnOff(int voice, u32 time) {
|
|
g_nTimeOfLastVoiceKey = time;
|
|
voice_key_times[voice] = time;
|
|
voice_key_flags[voice] = 1;
|
|
g_bRecentlyKeyedVoice = 1;
|
|
}
|
|
|
|
} // namespace jak3
|