Finish StreamProvider classes (#420)

* Finish StreamProvider classes

* Fix variable name

* Use FOURCC

* Match FUN_100c7090

* Changes

* Readability

---------

Co-authored-by: Christian Semmler <mail@csemmler.com>
This commit is contained in:
Nathan M Gilbert
2024-01-10 06:55:25 -05:00
committed by GitHub
parent 872c62fd39
commit 5a2be934be
10 changed files with 253 additions and 34 deletions

View File

@@ -5,6 +5,7 @@
#include "mxdsbuffer.h"
#include "mxdsstreamingaction.h"
#include "mxomni.h"
#include "mxramstreamprovider.h"
#include "mxstreamcontroller.h"
#include "mxstring.h"
#include "mxthread.h"
@@ -267,10 +268,103 @@ MxBool MxDiskStreamProvider::FUN_100d1af0(MxDSStreamingAction* p_action)
return TRUE;
}
// STUB: LEGO1 0x100d1b20
// FUNCTION: LEGO1 0x100d1b20
MxResult MxDiskStreamProvider::FUN_100d1b20(MxDSStreamingAction* p_action)
{
return FAILURE;
MxDSBuffer* buffer = new MxDSBuffer();
if (!buffer)
return FAILURE;
MxU32 size = p_action->GetUnknowna0()->GetWriteOffset() - p_action->GetUnknown94() + p_action->GetBufferOffset() +
(p_action->GetUnknowna4() ? p_action->GetUnknowna4()->GetWriteOffset() : 0);
if (buffer->AllocateBuffer(size, MxDSBufferType_Allocate) != SUCCESS) {
if (!buffer)
return FAILURE;
delete buffer;
return FAILURE;
}
MxDSBuffer* buffer2 = p_action->GetUnknowna4();
MxU8** pdata;
MxU8* data;
if (buffer2 == NULL) {
pdata = buffer->GetBufferRef();
memcpy(
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();
}
p_action->SetUnknowna4(buffer);
while (data) {
if (*MxDSChunk::IntoType(data) != FOURCC('M', 'x', 'O', 'b')) {
if (*MxStreamChunk::IntoTime(data) > p_action->GetUnknown9c()) {
*MxDSChunk::IntoType(data) = FOURCC('p', 'a', 'd', ' ');
memcpy(data + 8, *pdata, buffer->GetWriteOffset() + *pdata - data - 8);
size = ReadData(*pdata, buffer->GetWriteOffset());
MxDSBuffer* buffer3 = new MxDSBuffer();
if (!buffer3)
return FAILURE;
if (buffer3->AllocateBuffer(size, MxDSBufferType_Allocate) == SUCCESS) {
memcpy(buffer3->GetBuffer(), p_action->GetUnknowna4()->GetBuffer(), size);
p_action->GetUnknowna4()->SetMode(MxDSBufferType_Allocate);
delete p_action->GetUnknowna4();
buffer3->SetMode(MxDSBufferType_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();
return SUCCESS;
}
else {
delete buffer3;
return FAILURE;
}
}
}
data = buffer->FUN_100c6fa0(data);
}
p_action->SetUnknown94(GetFileSize() + p_action->GetBufferOffset());
p_action->SetBufferOffset(GetFileSize() + p_action->GetBufferOffset());
FUN_100d1780(p_action);
return SUCCESS;
}
// FUNCTION: LEGO1 0x100d1e90

View File

@@ -143,11 +143,11 @@ done:
}
// FUNCTION: LEGO1 0x100c6780
MxResult MxDSBuffer::SetBufferPointer(MxU32* p_buffer, MxU32 p_size)
MxResult MxDSBuffer::SetBufferPointer(MxU8* p_buffer, MxU32 p_size)
{
m_pBuffer = (MxU8*) p_buffer;
m_pIntoBuffer = (MxU8*) p_buffer;
m_pIntoBuffer2 = (MxU8*) p_buffer;
m_pBuffer = p_buffer;
m_pIntoBuffer = p_buffer;
m_pIntoBuffer2 = p_buffer;
m_bytesRemaining = p_size;
m_writeOffset = p_size;
m_mode = MxDSBufferType_Preallocated;
@@ -299,7 +299,7 @@ MxResult MxDSBuffer::ParseChunk(
p_header->SetTime(p_header->GetTime() + m_unk0x30->GetUnknowna8());
if (p_header->GetFlags() & MxDSChunk::Flag_Split) {
MxU32 length = p_header->GetLength() + MxDSChunk::ReturnE() + 8;
MxU32 length = p_header->GetLength() + MxDSChunk::GetHeaderSize() + 8;
MxDSBuffer* buffer = new MxDSBuffer();
if (buffer && buffer->AllocateBuffer(length, MxDSBufferType_Allocate) == SUCCESS &&
@@ -465,15 +465,15 @@ MxResult MxDSBuffer::CalcBytesRemaining(MxU8* p_data)
ptr = p_data;
}
else {
ptr = &p_data[MxStreamChunk::ReturnE() + 8];
bytesRead = (*(MxU32*) (p_data + 4)) - MxStreamChunk::ReturnE();
ptr = &p_data[MxStreamChunk::GetHeaderSize() + 8];
bytesRead = (*(MxU32*) (p_data + 4)) - MxStreamChunk::GetHeaderSize();
}
if (bytesRead <= m_bytesRemaining) {
memcpy(m_pBuffer + m_writeOffset - m_bytesRemaining, ptr, bytesRead);
if (m_writeOffset == m_bytesRemaining)
*(MxU32*) (m_pBuffer + 4) = *MxStreamChunk::IntoLength(m_pBuffer) + MxStreamChunk::ReturnE();
*(MxU32*) (m_pBuffer + 4) = *MxStreamChunk::IntoLength(m_pBuffer) + MxStreamChunk::GetHeaderSize();
m_bytesRemaining -= bytesRead;
result = SUCCESS;
@@ -491,3 +491,61 @@ void MxDSBuffer::FUN_100c6f80(MxU32 p_writeOffset)
m_pIntoBuffer = m_pBuffer + p_writeOffset;
}
}
// FUNCTION: LEGO1 0x100c6fa0
MxU8* MxDSBuffer::FUN_100c6fa0(MxU8* p_data)
{
MxU8* current = p_data ? p_data : m_pBuffer;
MxU8* end = m_writeOffset + m_pBuffer - 8;
while (current <= end) {
switch (*((MxU32*) current)) {
case FOURCC('L', 'I', 'S', 'T'):
case FOURCC('R', 'I', 'F', 'F'):
current += 12;
break;
case FOURCC('M', 'x', 'D', 'a'):
case FOURCC('M', 'x', 'S', 't'):
current += 8;
break;
case FOURCC('M', 'x', 'O', 'b'):
case FOURCC('M', 'x', 'C', 'h'):
if (current != p_data)
return current;
current = ((MxU32) current & 1) + current;
current += 8;
break;
case FOURCC('M', 'x', 'H', 'd'):
current += (((MxU32*) current)[1] + 8);
break;
}
}
return NULL;
}
// FUNCTION: LEGO1 0x100c7090
MxResult MxDSBuffer::FUN_100c7090(MxDSBuffer* p_buf)
{
MxResult result = FAILURE;
if (m_writeOffset >= p_buf->m_writeOffset) {
memcpy(m_pBuffer, p_buf->m_pBuffer, p_buf->m_writeOffset);
result = SUCCESS;
}
m_unk0x1c = p_buf->m_unk0x1c;
return result;
}
// FUNCTION: LEGO1 0x100c70d0
MxResult MxDSBuffer::Append(MxU8* p_buffer1, MxU8* p_buffer2)
{
if (p_buffer1 && p_buffer2) {
MxU32 size = ((MxU32*) p_buffer2)[1] - MxDSChunk::GetHeaderSize();
memcpy(p_buffer1 + ((MxU32*) p_buffer1)[1] + 8, p_buffer2 + MxDSChunk::GetHeaderSize() + 8, size);
((MxU32*) p_buffer1)[1] += size;
return SUCCESS;
}
return FAILURE;
}

View File

@@ -20,7 +20,7 @@ MxDSChunk::~MxDSChunk()
}
// FUNCTION: LEGO1 0x100be1e0
MxU32 MxDSChunk::ReturnE()
MxU32 MxDSChunk::GetHeaderSize()
{
return 0xe;
}

View File

@@ -6,8 +6,6 @@
DECOMP_SIZE_ASSERT(MxRAMStreamController, 0x98);
undefined* __cdecl ReadData(MxU32* p_fileSizeBuffer, MxU32 p_fileSize);
// FUNCTION: LEGO1 0x100c6110
MxResult MxRAMStreamController::Open(const char* p_filename)
{
@@ -95,9 +93,3 @@ MxResult MxRAMStreamController::DeserializeObject(MxDSStreamingAction& p_action)
return result == SUCCESS ? SUCCESS : FAILURE;
}
// STUB: LEGO1 0x100d0d80
undefined* __cdecl ReadData(MxU32* p_fileSizeBuffer, MxU32 p_fileSize)
{
return NULL;
}

View File

@@ -1,6 +1,7 @@
#include "mxramstreamprovider.h"
#include "decomp.h"
#include "mxdsbuffer.h"
#include "mxomni.h"
#include "mxstreamcontroller.h"
@@ -77,7 +78,7 @@ MxResult MxRAMStreamProvider::SetResourceToGet(MxStreamController* p_resource)
m_fileSize = m_pFile->CalcFileSize();
if (m_fileSize != 0) {
m_bufferSize = m_pFile->GetBufferSize();
m_pBufferOfFileSize = (MxU32*) new MxU8[m_fileSize];
m_pBufferOfFileSize = new MxU8[m_fileSize];
if (m_pBufferOfFileSize != NULL &&
m_pFile->Read((unsigned char*) m_pBufferOfFileSize, m_fileSize) == SUCCESS) {
m_lengthInDWords = m_pFile->GetLengthInDWords();
@@ -96,3 +97,60 @@ done:
m_pFile = NULL;
return result;
}
// FUNCTION: LEGO1 0x100d0d80
MxU32 ReadData(MxU8* p_buffer, MxU32 p_size)
{
MxU32 id;
MxU8* data = p_buffer;
MxU8* end = p_buffer + p_size;
MxU8* data2;
if (p_buffer < end) {
do {
if (*MxDSChunk::IntoType(data) == FOURCC('M', 'x', 'O', 'b')) {
data2 = data;
data += 8;
MxDSObject* obj = DeserializeDSObjectDispatch(&data, -1);
id = obj->GetObjectId();
delete obj;
data = MxDSChunk::End(data2);
while (data < end) {
if (*MxDSChunk::IntoType(data) == FOURCC('M', 'x', 'C', 'h')) {
MxU8* data3 = data;
MxU32* psize = MxDSChunk::IntoLength(data);
data += MxDSChunk::Size(*psize);
if ((*MxDSChunk::IntoType(data2) == FOURCC('M', 'x', 'C', 'h')) &&
(*MxStreamChunk::IntoFlags(data2) & MxDSChunk::Flag_Split)) {
if (*MxStreamChunk::IntoObjectId(data2) == *MxStreamChunk::IntoObjectId(data3) &&
(*MxStreamChunk::IntoFlags(data3) & MxDSChunk::Flag_Split) &&
*MxStreamChunk::IntoTime(data2) == *MxStreamChunk::IntoTime(data3)) {
MxDSBuffer::Append(data2, data3);
continue;
}
else
*MxStreamChunk::IntoFlags(data2) &= ~MxDSChunk::Flag_Split;
}
data2 += MxDSChunk::Size(*MxDSChunk::IntoLength(data2));
memcpy(data2, data3, MxDSChunk::Size(*psize));
if (*MxStreamChunk::IntoObjectId(data2) == id &&
(*MxStreamChunk::IntoFlags(data2) & MxDSChunk::Flag_End))
break;
}
else
data++;
}
}
else
data++;
} while (data < end);
}
*MxStreamChunk::IntoFlags(data2) &= ~MxDSChunk::Flag_Split;
return MxDSChunk::End(data2) - p_buffer;
}