Refactor surrounding MxDSChunk utility functions (#1313)

This commit is contained in:
MS 2025-01-06 15:20:47 -05:00 committed by GitHub
parent 7c452e9453
commit 93815ca545
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 127 additions and 111 deletions

View File

@ -68,7 +68,7 @@ public:
// FUNCTION: BETA10 0x10148c60 // FUNCTION: BETA10 0x10148c60
MxU8* GetBuffer() { return m_pBuffer; } MxU8* GetBuffer() { return m_pBuffer; }
MxU8** GetBufferRef() { return &m_pBuffer; } // FUNCTION: BETA10 0x10164240
undefined4 GetUnknown14() { return m_unk0x14; } undefined4 GetUnknown14() { return m_unk0x14; }
// FUNCTION: BETA10 0x10156420 // FUNCTION: BETA10 0x10156420
@ -85,7 +85,10 @@ public:
void SetUnknown14(undefined4 p_unk0x14) { m_unk0x14 = p_unk0x14; } void SetUnknown14(undefined4 p_unk0x14) { m_unk0x14 = p_unk0x14; }
void SetUnknown1c(undefined4 p_unk0x1c) { m_unk0x1c = p_unk0x1c; } void SetUnknown1c(undefined4 p_unk0x1c) { m_unk0x1c = p_unk0x1c; }
// FUNCTION: BETA10 0x10164260
void SetMode(Type p_mode) { m_mode = p_mode; } void SetMode(Type p_mode) { m_mode = p_mode; }
void SetUnk30(MxDSStreamingAction* p_unk0x30) { m_unk0x30 = p_unk0x30; } void SetUnk30(MxDSStreamingAction* p_unk0x30) { m_unk0x30 = p_unk0x30; }
// SYNTHETIC: LEGO1 0x100c6510 // SYNTHETIC: LEGO1 0x100c6510

View File

@ -35,10 +35,12 @@ public:
} }
static MxU32 GetHeaderSize(); static MxU32 GetHeaderSize();
static MxU32* IntoType(MxU8* p_buffer) { return (MxU32*) p_buffer; }
static MxU32* IntoLength(MxU8* p_buffer) { return (MxU32*) (p_buffer + 4); } // FUNCTION: BETA10 0x101641f0
static MxU32 Size(MxU32 p_dataSize) { return (p_dataSize & 1) + p_dataSize + 8; } static MxU32 Size(MxU8* p_buffer) { return (*(MxU32*) (p_buffer + 4) & 1) + *(MxU32*) (p_buffer + 4) + 8; }
static MxU8* End(MxU8* p_buffer) { return p_buffer + Size(*IntoLength(p_buffer)); }
// FUNCTION: BETA10 0x10164220
static MxU8* End(MxU8* p_buffer) { return p_buffer + Size(p_buffer); }
void SetChunkFlags(MxU16 p_flags) { m_flags = p_flags; } void SetChunkFlags(MxU16 p_flags) { m_flags = p_flags; }
void SetObjectId(undefined4 p_objectid) { m_objectId = p_objectid; } void SetObjectId(undefined4 p_objectid) { m_objectId = p_objectid; }

View File

@ -31,17 +31,39 @@ public:
void SetInternalAction(MxDSAction* p_dsAction); void SetInternalAction(MxDSAction* p_dsAction);
void FUN_100cd2d0(); void FUN_100cd2d0();
// FUNCTION: BETA10 0x10156530
MxU32 GetUnknown94() { return m_unk0x94; } MxU32 GetUnknown94() { return m_unk0x94; }
// FUNCTION: BETA10 0x10156380
MxS32 GetUnknown9c() { return m_unk0x9c; } MxS32 GetUnknown9c() { return m_unk0x9c; }
// FUNCTION: BETA10 0x10156630
MxDSBuffer* GetUnknowna0() { return m_unk0xa0; } MxDSBuffer* GetUnknowna0() { return m_unk0xa0; }
// FUNCTION: BETA10 0x101563d0
MxDSBuffer* GetUnknowna4() { return m_unk0xa4; } MxDSBuffer* GetUnknowna4() { return m_unk0xa4; }
// FUNCTION: BETA10 0x10159190
MxLong GetUnknowna8() { return m_unk0xa8; } MxLong GetUnknowna8() { return m_unk0xa8; }
MxDSAction* GetInternalAction() { return m_internalAction; } MxDSAction* GetInternalAction() { return m_internalAction; }
// FUNCTION: BETA10 0x10156580
MxU32 GetBufferOffset() { return m_bufferOffset; } MxU32 GetBufferOffset() { return m_bufferOffset; }
// FUNCTION: BETA10 0x10156550
void SetUnknown94(MxU32 p_unk0x94) { m_unk0x94 = p_unk0x94; } void SetUnknown94(MxU32 p_unk0x94) { m_unk0x94 = p_unk0x94; }
// FUNCTION: BETA10 0x101563a0
void SetUnknown9c(MxS32 p_unk0x9c) { m_unk0x9c = p_unk0x9c; } void SetUnknown9c(MxS32 p_unk0x9c) { m_unk0x9c = p_unk0x9c; }
// FUNCTION: BETA10 0x10156470
void SetUnknowna0(MxDSBuffer* p_unk0xa0) { m_unk0xa0 = p_unk0xa0; } void SetUnknowna0(MxDSBuffer* p_unk0xa0) { m_unk0xa0 = p_unk0xa0; }
// FUNCTION: BETA10 0x101563f0
void SetUnknowna4(MxDSBuffer* p_unk0xa4) { m_unk0xa4 = p_unk0xa4; } void SetUnknowna4(MxDSBuffer* p_unk0xa4) { m_unk0xa4 = p_unk0xa4; }
// FUNCTION: BETA10 0x10151150
void SetBufferOffset(MxU32 p_bufferOffset) { m_bufferOffset = p_bufferOffset; } void SetBufferOffset(MxU32 p_bufferOffset) { m_bufferOffset = p_bufferOffset; }
// FUNCTION: BETA10 0x10156650 // FUNCTION: BETA10 0x10156650

View File

@ -286,6 +286,7 @@ MxBool MxDiskStreamProvider::FUN_100d1af0(MxDSStreamingAction* p_action)
} }
// FUNCTION: LEGO1 0x100d1b20 // FUNCTION: LEGO1 0x100d1b20
// FUNCTION: BETA10 0x10163712
MxResult MxDiskStreamProvider::FUN_100d1b20(MxDSStreamingAction* p_action) MxResult MxDiskStreamProvider::FUN_100d1b20(MxDSStreamingAction* p_action)
{ {
MxDSBuffer* buffer = new MxDSBuffer(); MxDSBuffer* buffer = new MxDSBuffer();
@ -294,91 +295,74 @@ MxResult MxDiskStreamProvider::FUN_100d1b20(MxDSStreamingAction* p_action)
return FAILURE; return FAILURE;
} }
MxU32 size = p_action->GetUnknowna0()->GetWriteOffset() - p_action->GetUnknown94() + p_action->GetBufferOffset() + MxU32 size = (p_action->GetUnknowna4() ? p_action->GetUnknowna4()->GetWriteOffset() : 0) +
(p_action->GetUnknowna4() ? p_action->GetUnknowna4()->GetWriteOffset() : 0); p_action->GetUnknowna0()->GetWriteOffset() - (p_action->GetUnknown94() - p_action->GetBufferOffset());
if (buffer->AllocateBuffer(size, MxDSBuffer::e_allocate) != SUCCESS) { if (buffer->AllocateBuffer(size, MxDSBuffer::e_allocate) != SUCCESS) {
if (!buffer) {
return FAILURE;
}
delete buffer; delete buffer;
return FAILURE; return FAILURE;
} }
MxDSBuffer* buffer2 = p_action->GetUnknowna4();
MxU8** pdata;
MxU8* data; MxU8* data;
if (buffer2 == NULL) { if (p_action->GetUnknowna4()) {
pdata = buffer->GetBufferRef(); buffer->FUN_100c7090(p_action->GetUnknowna4());
data = buffer->GetBuffer() + p_action->GetUnknowna4()->GetWriteOffset();
memcpy( memcpy(data, p_action->GetUnknowna0()->GetBuffer(), p_action->GetUnknowna0()->GetWriteOffset());
data = *pdata,
p_action->GetUnknowna0()->GetBuffer() - p_action->GetBufferOffset() + p_action->GetUnknown94(),
size
);
}
else {
buffer->FUN_100c7090(buffer2);
pdata = buffer->GetBufferRef();
memcpy(
data = (p_action->GetUnknowna4()->GetWriteOffset() + *pdata),
p_action->GetUnknowna0()->GetBuffer(),
p_action->GetUnknowna0()->GetWriteOffset()
);
delete p_action->GetUnknowna4(); delete p_action->GetUnknowna4();
} }
else {
data = buffer->GetBuffer();
memcpy(
data,
p_action->GetUnknowna0()->GetBuffer() + (p_action->GetUnknown94() - p_action->GetBufferOffset()),
size
);
}
p_action->SetUnknowna4(buffer); p_action->SetUnknowna4(buffer);
#define IntoType(p) ((MxU32*) (p))
while (data) { while (data) {
if (*MxDSChunk::IntoType(data) != FOURCC('M', 'x', 'O', 'b')) { if (*IntoType(data) != FOURCC('M', 'x', 'O', 'b') &&
if (*MxStreamChunk::IntoTime(data) > p_action->GetUnknown9c()) { *MxStreamChunk::IntoTime(data) > p_action->GetUnknown9c()) {
*MxDSChunk::IntoType(data) = FOURCC('p', 'a', 'd', ' '); *IntoType(data) = FOURCC('p', 'a', 'd', ' ');
memcpy(data + 8, *pdata, buffer->GetWriteOffset() + *pdata - data - 8); // DECOMP: prefer order that matches retail versus beta
size = ReadData(*pdata, buffer->GetWriteOffset()); *(MxU32*) (data + 4) = buffer->GetBuffer() + buffer->GetWriteOffset() - data - 8;
memset(data + 8, 0, *(MxU32*) (data + 4));
size = ReadData(buffer->GetBuffer(), buffer->GetWriteOffset());
MxDSBuffer* buffer3 = new MxDSBuffer(); buffer = new MxDSBuffer();
if (!buffer3) { if (buffer == NULL || buffer->AllocateBuffer(size, MxDSBuffer::e_allocate) != SUCCESS) {
return FAILURE; delete buffer;
} return FAILURE;
if (buffer3->AllocateBuffer(size, MxDSBuffer::e_allocate) == SUCCESS) {
memcpy(buffer3->GetBuffer(), p_action->GetUnknowna4()->GetBuffer(), size);
p_action->GetUnknowna4()->SetMode(MxDSBuffer::e_allocate);
delete p_action->GetUnknowna4();
buffer3->SetMode(MxDSBuffer::e_unknown);
p_action->SetUnknowna4(buffer3);
MxDSBuffer* buffer4 = p_action->GetUnknowna0();
MxU32 unk0x14 = buffer4->GetUnknown14();
MxU8* data2 = buffer4->GetBuffer();
while (TRUE) {
if (*MxStreamChunk::IntoTime(data2) > p_action->GetUnknown9c()) {
break;
}
data += MxDSChunk::Size(*MxDSChunk::IntoLength(data));
unk0x14 += MxDSChunk::Size(*MxDSChunk::IntoLength(data));
}
p_action->SetUnknown94(unk0x14);
p_action->SetBufferOffset(p_action->GetUnknowna0()->GetUnknown14());
delete p_action->GetUnknowna0();
p_action->SetUnknowna0(NULL);
((MxDiskStreamController*) m_pLookup)->FUN_100c7890(p_action);
return SUCCESS;
}
else {
delete buffer3;
return FAILURE;
}
} }
memcpy(buffer->GetBuffer(), p_action->GetUnknowna4()->GetBuffer(), size);
p_action->GetUnknowna4()->SetMode(MxDSBuffer::e_allocate);
delete p_action->GetUnknowna4();
buffer->SetMode(MxDSBuffer::e_unknown);
p_action->SetUnknowna4(buffer);
MxU32 unk0x14 = p_action->GetUnknowna0()->GetUnknown14();
for (data = p_action->GetUnknowna0()->GetBuffer();
*MxStreamChunk::IntoTime(data) <= p_action->GetUnknown9c();
data = MxDSChunk::End(data)) {
unk0x14 += MxDSChunk::Size(data);
}
p_action->SetUnknown94(unk0x14);
p_action->SetBufferOffset(p_action->GetUnknowna0()->GetUnknown14());
delete p_action->GetUnknowna0();
p_action->ClearUnknowna0();
((MxDiskStreamController*) m_pLookup)->FUN_100c7890(p_action);
return SUCCESS;
} }
data = buffer->FUN_100c6fa0(data); data = buffer->FUN_100c6fa0(data);
@ -388,6 +372,8 @@ MxResult MxDiskStreamProvider::FUN_100d1b20(MxDSStreamingAction* p_action)
p_action->SetBufferOffset(GetFileSize() + p_action->GetBufferOffset()); p_action->SetBufferOffset(GetFileSize() + p_action->GetBufferOffset());
FUN_100d1780(p_action); FUN_100d1780(p_action);
return SUCCESS; return SUCCESS;
#undef IntoType
} }
// FUNCTION: LEGO1 0x100d1e90 // FUNCTION: LEGO1 0x100d1e90

View File

@ -491,6 +491,7 @@ MxU8* MxDSBuffer::FUN_100c6fa0(MxU8* p_data)
} }
// FUNCTION: LEGO1 0x100c7090 // FUNCTION: LEGO1 0x100c7090
// FUNCTION: BETA10 0x1015842d
MxResult MxDSBuffer::FUN_100c7090(MxDSBuffer* p_buf) MxResult MxDSBuffer::FUN_100c7090(MxDSBuffer* p_buf)
{ {
MxResult result = FAILURE; MxResult result = FAILURE;

View File

@ -102,62 +102,63 @@ done:
} }
// FUNCTION: LEGO1 0x100d0d80 // FUNCTION: LEGO1 0x100d0d80
// FUNCTION: BETA10 0x1016492f
MxU32 ReadData(MxU8* p_buffer, MxU32 p_size) MxU32 ReadData(MxU8* p_buffer, MxU32 p_size)
{ {
MxU32 id; MxU32 id;
MxU8* data = p_buffer; MxU8* data = p_buffer;
MxU8* end = p_buffer + p_size;
MxU8* data2; MxU8* data2;
if (p_buffer < end) { #define IntoType(p) ((MxU32*) (p))
do {
if (*MxDSChunk::IntoType(data) == FOURCC('M', 'x', 'O', 'b')) {
data2 = data;
data += 8;
MxDSObject* obj = DeserializeDSObjectDispatch(data, -1); while (data < p_buffer + p_size) {
id = obj->GetObjectId(); if (*IntoType(data) == FOURCC('M', 'x', 'O', 'b')) {
delete obj; data2 = data;
data = data2 + 8;
data = MxDSChunk::End(data2); MxDSObject* obj = DeserializeDSObjectDispatch(data, -1);
while (data < end) { id = obj->GetObjectId();
if (*MxDSChunk::IntoType(data) == FOURCC('M', 'x', 'C', 'h')) { delete obj;
MxU8* data3 = data;
MxU32* psize = MxDSChunk::IntoLength(data);
data += MxDSChunk::Size(*psize);
if ((*MxDSChunk::IntoType(data2) == FOURCC('M', 'x', 'C', 'h')) && data = MxDSChunk::End(data2);
(*MxStreamChunk::IntoFlags(data2) & DS_CHUNK_SPLIT)) { while (data < p_buffer + p_size) {
if (*MxStreamChunk::IntoObjectId(data2) == *MxStreamChunk::IntoObjectId(data3) && if (*IntoType(data) == FOURCC('M', 'x', 'C', 'h')) {
(*MxStreamChunk::IntoFlags(data3) & DS_CHUNK_SPLIT) && MxU8* data3 = data;
*MxStreamChunk::IntoTime(data2) == *MxStreamChunk::IntoTime(data3)) { data = MxDSChunk::End(data3);
MxDSBuffer::Append(data2, data3);
continue; if ((*IntoType(data2) == FOURCC('M', 'x', 'C', 'h')) &&
} (*MxStreamChunk::IntoFlags(data2) & DS_CHUNK_SPLIT)) {
else { if (*MxStreamChunk::IntoObjectId(data2) == *MxStreamChunk::IntoObjectId(data3) &&
*MxStreamChunk::IntoFlags(data2) &= ~DS_CHUNK_SPLIT; (*MxStreamChunk::IntoFlags(data3) & DS_CHUNK_SPLIT) &&
} *MxStreamChunk::IntoTime(data2) == *MxStreamChunk::IntoTime(data3)) {
MxDSBuffer::Append(data2, data3);
continue;
} }
else {
data2 += MxDSChunk::Size(*MxDSChunk::IntoLength(data2)); *MxStreamChunk::IntoFlags(data2) &= ~DS_CHUNK_SPLIT;
memcpy(data2, data3, MxDSChunk::Size(*psize));
if (*MxStreamChunk::IntoObjectId(data2) == id &&
(*MxStreamChunk::IntoFlags(data2) & DS_CHUNK_END_OF_STREAM)) {
break;
} }
} }
else {
data++; data2 = MxDSChunk::End(data2);
memcpy(data2, data3, MxDSChunk::Size(data3));
if (*MxStreamChunk::IntoObjectId(data2) == id &&
(*MxStreamChunk::IntoFlags(data2) & DS_CHUNK_END_OF_STREAM)) {
break;
} }
} }
else {
data++;
}
} }
else { }
data++; else {
} data++;
} while (data < end); }
} }
*MxStreamChunk::IntoFlags(data2) &= ~DS_CHUNK_SPLIT; *MxStreamChunk::IntoFlags(data2) &= ~DS_CHUNK_SPLIT;
return MxDSChunk::End(data2) - p_buffer; return MxDSChunk::Size(data2) + (MxU32) (data2 - p_buffer);
#undef IntoType
} }

View File

@ -96,6 +96,7 @@ MxU32* MxStreamChunk::IntoObjectId(MxU8* p_buffer)
} }
// FUNCTION: LEGO1 0x100c31a0 // FUNCTION: LEGO1 0x100c31a0
// FUNCTION: BETA10 0x10151626
MxLong* MxStreamChunk::IntoTime(MxU8* p_buffer) MxLong* MxStreamChunk::IntoTime(MxU8* p_buffer)
{ {
return (MxLong*) (p_buffer + 0x0e); return (MxLong*) (p_buffer + 0x0e);