mirror of
https://github.com/open-goal/jak-project
synced 2026-08-06 18:03:30 -04:00
d3cc739e43
This attempts to get into master whatever work was done in this PR / it's earlier PR https://github.com/open-goal/jak-project/pull/3965 I don't want this work to be lost / floating around in massive PRs. However the changes are: - switch to ntsc_v1 instead of PAL as the development target, as we have done for all other games - remove most of the copied-from-jak2/3 changes as they need to be confirmed during the decompilation process not just assumed - avoids committing any changes to `game/kernel/common` as it was not clear to me if these were changes made in jak x's kernel that were not properly broken out into it's own functions. We don't want to accidentally introduce bugs into jak1-3's kernel code. - in other words, if the change in the kernel only happens in jak x...it should likely be specific to jak x's kernel, not common. --------- Co-authored-by: VodBox <dillon@vodbox.io> Co-authored-by: yodah <greenboyyodah@gmail.com>
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/jakx/basefile.h"
|
|
#include "game/overlord/jakx/dma.h"
|
|
#include "game/overlord/jakx/iso.h"
|
|
#include "game/overlord/jakx/iso_queue.h"
|
|
#include "game/overlord/jakx/ssound.h"
|
|
#include "game/overlord/jakx/streamlist.h"
|
|
#include "game/overlord/jakx/vag.h"
|
|
#include "game/sce/iop.h"
|
|
#include "game/sound/sdshim.h"
|
|
|
|
namespace jakx {
|
|
using namespace iop;
|
|
void jakx_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 jakx
|