mirror of
https://github.com/isledecomp/isle.git
synced 2025-10-25 01:14:19 +00:00
Reorganize sources and files (#414)
* Reorganize sources * Refactor * Remove relative paths * Renames * Fix gitignore * Remove stuff * Try fixing format script * Fix format * Fix format * Fix naming script * Test format * Fix format
This commit is contained in:
committed by
GitHub
parent
6a85e62406
commit
c47206617d
443
LEGO1/omni/src/stream/mxdiskstreamcontroller.cpp
Normal file
443
LEGO1/omni/src/stream/mxdiskstreamcontroller.cpp
Normal file
@@ -0,0 +1,443 @@
|
||||
#include "mxdiskstreamcontroller.h"
|
||||
|
||||
#include "mxactionnotificationparam.h"
|
||||
#include "mxautolocker.h"
|
||||
#include "mxdiskstreamprovider.h"
|
||||
#include "mxdsstreamingaction.h"
|
||||
#include "mxomni.h"
|
||||
#include "mxticklemanager.h"
|
||||
|
||||
DECOMP_SIZE_ASSERT(MxDiskStreamController, 0xc8);
|
||||
|
||||
// FUNCTION: LEGO1 0x100c7120
|
||||
MxDiskStreamController::MxDiskStreamController()
|
||||
{
|
||||
m_unk0x8c = 0;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c7530
|
||||
MxDiskStreamController::~MxDiskStreamController()
|
||||
{
|
||||
MxAutoLocker lock(&this->m_criticalSection);
|
||||
|
||||
m_unk0xc4 = FALSE;
|
||||
m_unk0x70 = FALSE;
|
||||
|
||||
if (m_provider) {
|
||||
#ifdef COMPAT_MODE
|
||||
{
|
||||
MxDSAction action;
|
||||
m_provider->VTable0x20(&action);
|
||||
}
|
||||
#else
|
||||
m_provider->VTable0x20(&MxDSAction());
|
||||
#endif
|
||||
}
|
||||
|
||||
MxDSAction* action;
|
||||
while (m_unk0x3c.PopFront(action))
|
||||
delete action;
|
||||
|
||||
if (m_provider) {
|
||||
delete m_provider;
|
||||
m_provider = NULL;
|
||||
}
|
||||
|
||||
FUN_100c8720();
|
||||
|
||||
while (m_list0x80.PopFront(action))
|
||||
FUN_100c7cb0((MxDSStreamingAction*) action);
|
||||
|
||||
while (m_list0x64.PopFront(action))
|
||||
FUN_100c7cb0((MxDSStreamingAction*) action);
|
||||
|
||||
while (!m_list0x74.empty()) {
|
||||
MxDSBuffer* buffer = m_list0x74.front();
|
||||
m_list0x74.pop_front();
|
||||
FUN_100c7ce0(buffer);
|
||||
}
|
||||
|
||||
TickleManager()->UnregisterClient(this);
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c7790
|
||||
MxResult MxDiskStreamController::Open(const char* p_filename)
|
||||
{
|
||||
MxAutoLocker lock(&this->m_criticalSection);
|
||||
MxResult result = MxStreamController::Open(p_filename);
|
||||
|
||||
if (result == SUCCESS) {
|
||||
m_provider = new MxDiskStreamProvider();
|
||||
if (m_provider == NULL) {
|
||||
result = FAILURE;
|
||||
}
|
||||
else {
|
||||
result = m_provider->SetResourceToGet(this);
|
||||
if (result != SUCCESS) {
|
||||
delete m_provider;
|
||||
m_provider = NULL;
|
||||
}
|
||||
else {
|
||||
TickleManager()->RegisterClient(this, 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c7880
|
||||
MxResult MxDiskStreamController::VTable0x18(undefined4, undefined4)
|
||||
{
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c7890
|
||||
MxResult MxDiskStreamController::FUN_100c7890(MxDSStreamingAction* p_action)
|
||||
{
|
||||
MxAutoLocker lock(&this->m_criticalSection);
|
||||
if (p_action == NULL) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
m_list0x80.push_back(p_action);
|
||||
FUN_100c7970();
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c7960
|
||||
MxResult MxDiskStreamController::VTable0x34(undefined4)
|
||||
{
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c7970
|
||||
void MxDiskStreamController::FUN_100c7970()
|
||||
{
|
||||
// Empty
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c7980
|
||||
void MxDiskStreamController::FUN_100c7980()
|
||||
{
|
||||
MxDSBuffer* buffer;
|
||||
MxDSStreamingAction* action = NULL;
|
||||
|
||||
{
|
||||
MxAutoLocker lock(&this->m_criticalSection);
|
||||
|
||||
if (m_unk0x3c.size() && m_unk0x8c < m_provider->GetStreamBuffersNum()) {
|
||||
buffer = new MxDSBuffer();
|
||||
|
||||
if (buffer->AllocateBuffer(m_provider->GetFileSize(), MxDSBufferType_Chunk) != SUCCESS) {
|
||||
if (buffer)
|
||||
delete buffer;
|
||||
return;
|
||||
}
|
||||
|
||||
action = VTable0x28();
|
||||
if (!action) {
|
||||
if (buffer)
|
||||
delete buffer;
|
||||
return;
|
||||
}
|
||||
|
||||
action->SetUnknowna0(buffer);
|
||||
m_unk0x8c++;
|
||||
}
|
||||
}
|
||||
|
||||
if (action) {
|
||||
((MxDiskStreamProvider*) m_provider)->FUN_100d1780(action);
|
||||
}
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c7ac0
|
||||
MxDSStreamingAction* MxDiskStreamController::VTable0x28()
|
||||
{
|
||||
MxAutoLocker lock(&this->m_criticalSection);
|
||||
MxDSAction* oldAction;
|
||||
MxDSStreamingAction* result = NULL;
|
||||
MxU32 filesize = m_provider->GetFileSize();
|
||||
|
||||
if (m_unk0x3c.PopFront(oldAction)) {
|
||||
result = new MxDSStreamingAction((MxDSStreamingAction&) *oldAction);
|
||||
if (result) {
|
||||
MxU32 offset = result->GetBufferOffset() + filesize;
|
||||
((MxDSStreamingAction*) oldAction)->SetUnknown94(offset);
|
||||
((MxDSStreamingAction*) oldAction)->SetBufferOffset(offset);
|
||||
m_unk0x3c.push_back(oldAction);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c7c00
|
||||
MxResult MxDiskStreamController::VTable0x30(MxDSAction* p_action)
|
||||
{
|
||||
MxAutoLocker lock(&this->m_criticalSection);
|
||||
MxResult result = MxStreamController::VTable0x30(p_action);
|
||||
|
||||
MxDSStreamingAction* item;
|
||||
while (TRUE) {
|
||||
item = (MxDSStreamingAction*) m_list0x90.Find(p_action, TRUE);
|
||||
if (item == NULL) {
|
||||
break;
|
||||
}
|
||||
FUN_100c7cb0(item);
|
||||
}
|
||||
|
||||
while (TRUE) {
|
||||
item = (MxDSStreamingAction*) m_list0x64.Find(p_action, TRUE);
|
||||
if (item == NULL) {
|
||||
break;
|
||||
}
|
||||
FUN_100c7cb0(item);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c7cb0
|
||||
void MxDiskStreamController::FUN_100c7cb0(MxDSStreamingAction* p_action)
|
||||
{
|
||||
if (p_action->GetUnknowna0()) {
|
||||
FUN_100c7ce0(p_action->GetUnknowna0());
|
||||
}
|
||||
p_action->SetUnknowna0(NULL);
|
||||
delete p_action;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c7ce0
|
||||
void MxDiskStreamController::FUN_100c7ce0(MxDSBuffer* p_buffer)
|
||||
{
|
||||
switch (p_buffer->GetMode()) {
|
||||
case MxDSBufferType_Chunk:
|
||||
m_unk0x8c--;
|
||||
case MxDSBufferType_Allocate:
|
||||
case MxDSBufferType_Unknown:
|
||||
delete p_buffer;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c7d10
|
||||
MxResult MxDiskStreamController::FUN_100c7d10()
|
||||
{
|
||||
MxAutoLocker lock(&this->m_criticalSection);
|
||||
MxDSStreamingAction* action = FUN_100c7db0();
|
||||
|
||||
if (!action)
|
||||
return FAILURE;
|
||||
|
||||
if (FUN_100c8360(action) != SUCCESS) {
|
||||
VTable0x24(action);
|
||||
FUN_100c7cb0(action);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c7db0
|
||||
MxDSStreamingAction* MxDiskStreamController::FUN_100c7db0()
|
||||
{
|
||||
MxAutoLocker lock(&this->m_criticalSection);
|
||||
|
||||
for (MxStreamListMxNextActionDataStart::iterator it = m_nextActionList.begin(); it != m_nextActionList.end();
|
||||
it++) {
|
||||
MxNextActionDataStart* data = *it;
|
||||
for (MxStreamListMxDSAction::iterator it2 = m_list0x64.begin(); it2 != m_list0x64.end(); it2++) {
|
||||
MxDSStreamingAction* streamingAction = (MxDSStreamingAction*) *it2;
|
||||
if (streamingAction->GetObjectId() == data->GetObjectId() &&
|
||||
streamingAction->GetUnknown24() == data->GetUnknown24() &&
|
||||
streamingAction->GetBufferOffset() == data->GetData()) {
|
||||
m_nextActionList.erase(it);
|
||||
|
||||
data->SetData(m_provider->GetFileSize() + data->GetData());
|
||||
m_nextActionList.push_back(data);
|
||||
|
||||
m_list0x64.erase(it2);
|
||||
return streamingAction;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c7f40
|
||||
void MxDiskStreamController::FUN_100c7f40(MxDSStreamingAction* p_streamingaction)
|
||||
{
|
||||
MxAutoLocker lock(&this->m_criticalSection);
|
||||
if (p_streamingaction) {
|
||||
m_list0x64.push_back(p_streamingaction);
|
||||
}
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c7ff0
|
||||
MxResult MxDiskStreamController::VTable0x20(MxDSAction* p_action)
|
||||
{
|
||||
MxAutoLocker lock(&this->m_criticalSection);
|
||||
MxDSStreamingAction* entry =
|
||||
(MxDSStreamingAction*) m_list0x80.Find(p_action, FALSE); // TODO: is this a seperate class?
|
||||
if (entry) {
|
||||
MxDSStreamingAction* action = new MxDSStreamingAction(*p_action, 0);
|
||||
action->SetUnknown28(entry->GetUnknown28());
|
||||
action->SetUnknown84(entry->GetUnknown84());
|
||||
action->SetOrigin(entry->GetOrigin());
|
||||
action->SetUnknowna0(entry->GetUnknowna4());
|
||||
|
||||
FUN_100c7f40(action);
|
||||
|
||||
if (VTable0x2c(p_action, entry->GetUnknown94()) != SUCCESS)
|
||||
return FAILURE;
|
||||
}
|
||||
else if (MxStreamController::VTable0x20(p_action) != SUCCESS)
|
||||
return FAILURE;
|
||||
|
||||
m_unk0x70 = TRUE;
|
||||
m_unk0xc4 = TRUE;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c8160
|
||||
MxResult MxDiskStreamController::VTable0x24(MxDSAction* p_action)
|
||||
{
|
||||
MxAutoLocker lock(&this->m_criticalSection);
|
||||
if (m_unk0x54.Find(p_action, FALSE) == NULL) {
|
||||
if (VTable0x30(p_action) == SUCCESS) {
|
||||
#ifdef COMPAT_MODE
|
||||
{
|
||||
MxEndActionNotificationParam param(c_notificationEndAction, NULL, p_action, TRUE);
|
||||
MxOmni::GetInstance()->NotifyCurrentEntity(¶m);
|
||||
}
|
||||
#else
|
||||
MxOmni::GetInstance()->NotifyCurrentEntity(
|
||||
&MxEndActionNotificationParam(c_notificationEndAction, NULL, p_action, TRUE)
|
||||
);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
MxDSAction action;
|
||||
if (m_provider) {
|
||||
m_provider->VTable0x20(p_action);
|
||||
}
|
||||
|
||||
do {
|
||||
if (m_action0x60 != NULL) {
|
||||
delete m_action0x60;
|
||||
m_action0x60 = NULL;
|
||||
}
|
||||
|
||||
action = *p_action;
|
||||
MxStreamController::VTable0x24(&action);
|
||||
} while (m_action0x60 != NULL);
|
||||
|
||||
if (m_unk0x3c.empty()) {
|
||||
m_unk0x70 = FALSE;
|
||||
m_unk0xc4 = FALSE;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c8360
|
||||
MxResult MxDiskStreamController::FUN_100c8360(MxDSStreamingAction* p_action)
|
||||
{
|
||||
MxAutoLocker lock(&this->m_criticalSection);
|
||||
MxDSBuffer* buffer = p_action->GetUnknowna0();
|
||||
MxDSStreamingAction* action2 = (MxDSStreamingAction*) m_list0x90.Find(p_action, TRUE);
|
||||
buffer->FUN_100c6f80(p_action->GetUnknown94() - p_action->GetBufferOffset());
|
||||
buffer->FUN_100c67b0(this, p_action, &action2);
|
||||
|
||||
if (buffer->GetRefCount()) {
|
||||
p_action->SetUnknowna0(NULL);
|
||||
InsertToList74(buffer);
|
||||
}
|
||||
|
||||
if (action2) {
|
||||
if (action2->GetUnknowna0() == NULL) {
|
||||
FUN_100c7cb0(action2);
|
||||
}
|
||||
else {
|
||||
if (action2->GetObjectId() == -1) {
|
||||
action2->SetObjectId(p_action->GetObjectId());
|
||||
}
|
||||
|
||||
m_list0x90.push_back(action2);
|
||||
}
|
||||
}
|
||||
|
||||
FUN_100c7cb0(p_action);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c84a0
|
||||
void MxDiskStreamController::InsertToList74(MxDSBuffer* p_buffer)
|
||||
{
|
||||
MxAutoLocker lock(&this->m_criticalSection);
|
||||
m_list0x74.push_back(p_buffer);
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c8540
|
||||
void MxDiskStreamController::FUN_100c8540()
|
||||
{
|
||||
MxAutoLocker lock(&this->m_criticalSection);
|
||||
for (list<MxDSBuffer*>::iterator it = m_list0x74.begin(); it != m_list0x74.end();) {
|
||||
MxDSBuffer* buf = *it;
|
||||
if (buf->GetRefCount() == 0) {
|
||||
m_list0x74.erase(it++);
|
||||
FUN_100c7ce0(buf);
|
||||
}
|
||||
else
|
||||
it++;
|
||||
}
|
||||
|
||||
if (m_nextActionList.empty()) {
|
||||
while (!m_list0x64.empty()) {
|
||||
MxDSStreamingAction* action = (MxDSStreamingAction*) m_list0x64.front();
|
||||
m_list0x64.pop_front();
|
||||
FUN_100c7cb0(action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c8640
|
||||
MxResult MxDiskStreamController::Tickle()
|
||||
{
|
||||
if (m_unk0xc4) {
|
||||
FUN_100c7d10();
|
||||
}
|
||||
|
||||
FUN_100c8540();
|
||||
FUN_100c8720();
|
||||
|
||||
if (m_unk0x70) {
|
||||
FUN_100c7980();
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c8670
|
||||
void MxDiskStreamController::FUN_100c8670(MxDSStreamingAction* p_streamingAction)
|
||||
{
|
||||
MxAutoLocker lock(&this->m_critical9c);
|
||||
m_list0xb8.push_back(p_streamingAction);
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c8720
|
||||
void MxDiskStreamController::FUN_100c8720()
|
||||
{
|
||||
MxAutoLocker lock(&this->m_critical9c);
|
||||
|
||||
MxDSStreamingAction* action;
|
||||
while (!m_list0xb8.empty()) {
|
||||
action = (MxDSStreamingAction*) m_list0xb8.front();
|
||||
m_list0xb8.pop_front();
|
||||
|
||||
FUN_100c7cb0(action);
|
||||
}
|
||||
}
|
||||
298
LEGO1/omni/src/stream/mxdiskstreamprovider.cpp
Normal file
298
LEGO1/omni/src/stream/mxdiskstreamprovider.cpp
Normal file
@@ -0,0 +1,298 @@
|
||||
#include "mxdiskstreamprovider.h"
|
||||
|
||||
#include "mxautolocker.h"
|
||||
#include "mxdiskstreamcontroller.h"
|
||||
#include "mxdsbuffer.h"
|
||||
#include "mxdsstreamingaction.h"
|
||||
#include "mxomni.h"
|
||||
#include "mxstreamcontroller.h"
|
||||
#include "mxstring.h"
|
||||
#include "mxthread.h"
|
||||
|
||||
DECOMP_SIZE_ASSERT(MxDiskStreamProviderThread, 0x1c)
|
||||
DECOMP_SIZE_ASSERT(MxDiskStreamProvider, 0x60);
|
||||
|
||||
// GLOBAL: LEGO1 0x10102878
|
||||
MxU32 g_unk0x10102878 = 0;
|
||||
|
||||
// FUNCTION: LEGO1 0x100d0f30
|
||||
MxResult MxDiskStreamProviderThread::Run()
|
||||
{
|
||||
if (m_target)
|
||||
((MxDiskStreamProvider*) m_target)->WaitForWorkToComplete();
|
||||
MxThread::Run();
|
||||
// They should probably have writen "return MxThread::Run()" but they didn't.
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100d0f50
|
||||
MxResult MxDiskStreamProviderThread::StartWithTarget(MxDiskStreamProvider* p_target)
|
||||
{
|
||||
m_target = p_target;
|
||||
return Start(0x1000, 0);
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100d0f70
|
||||
MxDiskStreamProvider::MxDiskStreamProvider()
|
||||
{
|
||||
this->m_pFile = NULL;
|
||||
this->m_remainingWork = FALSE;
|
||||
this->m_unk0x35 = FALSE;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100d1240
|
||||
MxDiskStreamProvider::~MxDiskStreamProvider()
|
||||
{
|
||||
MxDSStreamingAction* action;
|
||||
m_unk0x35 = FALSE;
|
||||
|
||||
do {
|
||||
action = NULL;
|
||||
|
||||
{
|
||||
MxAutoLocker lock(&m_criticalSection);
|
||||
m_list.PopFrontStreamingAction(action);
|
||||
}
|
||||
|
||||
if (!action)
|
||||
break;
|
||||
|
||||
if (action->GetUnknowna0()->GetWriteOffset() < 0x20000)
|
||||
g_unk0x10102878--;
|
||||
|
||||
((MxDiskStreamController*) m_pLookup)->FUN_100c8670(action);
|
||||
} while (action);
|
||||
|
||||
if (m_remainingWork) {
|
||||
m_remainingWork = FALSE;
|
||||
m_busySemaphore.Release(1);
|
||||
m_thread.Terminate();
|
||||
}
|
||||
|
||||
if (m_pFile)
|
||||
delete m_pFile;
|
||||
|
||||
m_pFile = NULL;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100d13d0
|
||||
MxResult MxDiskStreamProvider::SetResourceToGet(MxStreamController* p_resource)
|
||||
{
|
||||
MxResult result = FAILURE;
|
||||
MxString path;
|
||||
m_pLookup = p_resource;
|
||||
|
||||
path = (MxString(MxOmni::GetHD()) + p_resource->GetAtom().GetInternal() + ".si");
|
||||
|
||||
m_pFile = new MxDSFile(path.GetData(), 0);
|
||||
if (m_pFile != NULL) {
|
||||
if (m_pFile->Open(0) != 0) {
|
||||
path = MxString(MxOmni::GetCD()) + p_resource->GetAtom().GetInternal() + ".si";
|
||||
m_pFile->SetFileName(path.GetData());
|
||||
|
||||
if (m_pFile->Open(0) != 0)
|
||||
goto done;
|
||||
}
|
||||
|
||||
m_remainingWork = TRUE;
|
||||
m_busySemaphore.Init(0, 100);
|
||||
|
||||
if (m_thread.StartWithTarget(this) == SUCCESS && p_resource != NULL) {
|
||||
result = SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
return result;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100d15e0
|
||||
void MxDiskStreamProvider::VTable0x20(MxDSAction* p_action)
|
||||
{
|
||||
MxDSStreamingAction* action;
|
||||
|
||||
if (p_action->GetObjectId() == -1) {
|
||||
m_unk0x35 = FALSE;
|
||||
|
||||
do {
|
||||
action = NULL;
|
||||
|
||||
{
|
||||
MxAutoLocker lock(&m_criticalSection);
|
||||
m_list.PopFrontStreamingAction(action);
|
||||
}
|
||||
|
||||
if (!action)
|
||||
return;
|
||||
|
||||
if (action->GetUnknowna0()->GetWriteOffset() < 0x20000)
|
||||
g_unk0x10102878--;
|
||||
|
||||
((MxDiskStreamController*) m_pLookup)->FUN_100c8670(action);
|
||||
} while (action);
|
||||
}
|
||||
else {
|
||||
do {
|
||||
{
|
||||
MxAutoLocker lock(&m_criticalSection);
|
||||
action = (MxDSStreamingAction*) m_list.Find(p_action, TRUE);
|
||||
}
|
||||
|
||||
if (!action)
|
||||
return;
|
||||
|
||||
if (action->GetUnknowna0()->GetWriteOffset() < 0x20000)
|
||||
g_unk0x10102878--;
|
||||
|
||||
((MxDiskStreamController*) m_pLookup)->FUN_100c8670(action);
|
||||
} while (action);
|
||||
}
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100d1750
|
||||
MxResult MxDiskStreamProvider::WaitForWorkToComplete()
|
||||
{
|
||||
while (m_remainingWork) {
|
||||
m_busySemaphore.Wait(INFINITE);
|
||||
if (m_unk0x35)
|
||||
PerformWork();
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100d1780
|
||||
MxResult MxDiskStreamProvider::FUN_100d1780(MxDSStreamingAction* p_action)
|
||||
{
|
||||
if (!m_remainingWork)
|
||||
return FAILURE;
|
||||
|
||||
if (p_action->GetUnknown9c() > 0 && !p_action->GetUnknowna0()) {
|
||||
MxDSBuffer* buffer = new MxDSBuffer();
|
||||
|
||||
if (!buffer)
|
||||
return FAILURE;
|
||||
|
||||
if (buffer->AllocateBuffer(GetFileSize(), MxDSBufferType_Allocate) != SUCCESS) {
|
||||
delete buffer;
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
p_action->SetUnknowna0(buffer);
|
||||
}
|
||||
|
||||
if (p_action->GetUnknowna0()->GetWriteOffset() < 0x20000) {
|
||||
g_unk0x10102878++;
|
||||
}
|
||||
|
||||
{
|
||||
MxAutoLocker lock(&m_criticalSection);
|
||||
m_list.push_back(p_action);
|
||||
}
|
||||
|
||||
m_unk0x35 = TRUE;
|
||||
m_busySemaphore.Release(1);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100d18f0
|
||||
void MxDiskStreamProvider::PerformWork()
|
||||
{
|
||||
MxDiskStreamController* controller = (MxDiskStreamController*) m_pLookup;
|
||||
MxDSStreamingAction* streamingAction = NULL;
|
||||
|
||||
{
|
||||
MxAutoLocker lock(&m_criticalSection);
|
||||
if (!m_list.empty()) {
|
||||
streamingAction = (MxDSStreamingAction*) m_list.front();
|
||||
|
||||
if (streamingAction && !FUN_100d1af0(streamingAction)) {
|
||||
m_thread.Sleep(500);
|
||||
m_busySemaphore.Release(1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
MxAutoLocker lock(&m_criticalSection);
|
||||
|
||||
if (!m_list.PopFrontStreamingAction(streamingAction))
|
||||
return;
|
||||
}
|
||||
|
||||
if (streamingAction->GetUnknowna0()->GetWriteOffset() < 0x20000) {
|
||||
g_unk0x10102878--;
|
||||
}
|
||||
|
||||
MxDSBuffer* buffer = streamingAction->GetUnknowna0();
|
||||
|
||||
if (m_pFile->GetPosition() == streamingAction->GetBufferOffset() ||
|
||||
m_pFile->Seek(streamingAction->GetBufferOffset(), 0) == 0) {
|
||||
buffer->SetUnknown14(m_pFile->GetPosition());
|
||||
|
||||
if (m_pFile->ReadToBuffer(buffer) == SUCCESS) {
|
||||
buffer->SetUnknown1c(m_pFile->GetPosition());
|
||||
|
||||
if (streamingAction->GetUnknown9c() > 0) {
|
||||
FUN_100d1b20(streamingAction);
|
||||
}
|
||||
else {
|
||||
if (m_pLookup == NULL || !((MxDiskStreamController*) m_pLookup)->GetUnk0xc4()) {
|
||||
controller->FUN_100c8670(streamingAction);
|
||||
}
|
||||
else {
|
||||
controller->FUN_100c7f40(streamingAction);
|
||||
}
|
||||
}
|
||||
|
||||
streamingAction = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (streamingAction) {
|
||||
controller->FUN_100c8670(streamingAction);
|
||||
}
|
||||
|
||||
m_thread.Sleep(0);
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100d1af0
|
||||
MxBool MxDiskStreamProvider::FUN_100d1af0(MxDSStreamingAction* p_action)
|
||||
{
|
||||
if (p_action->GetUnknowna0()->GetWriteOffset() == 0x20000) {
|
||||
return g_unk0x10102878 == 0;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// STUB: LEGO1 0x100d1b20
|
||||
MxResult MxDiskStreamProvider::FUN_100d1b20(MxDSStreamingAction* p_action)
|
||||
{
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100d1e90
|
||||
MxU32 MxDiskStreamProvider::GetFileSize()
|
||||
{
|
||||
return m_pFile->GetBufferSize();
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100d1ea0
|
||||
MxS32 MxDiskStreamProvider::GetStreamBuffersNum()
|
||||
{
|
||||
return m_pFile->GetStreamBuffersNum();
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100d1eb0
|
||||
MxU32 MxDiskStreamProvider::GetLengthInDWords()
|
||||
{
|
||||
return m_pFile->GetLengthInDWords();
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100d1ec0
|
||||
MxU32* MxDiskStreamProvider::GetBufferForDWords()
|
||||
{
|
||||
return m_pFile->GetBuffer();
|
||||
}
|
||||
493
LEGO1/omni/src/stream/mxdsbuffer.cpp
Normal file
493
LEGO1/omni/src/stream/mxdsbuffer.cpp
Normal file
@@ -0,0 +1,493 @@
|
||||
#include "mxdsbuffer.h"
|
||||
|
||||
#include "mxdiskstreamcontroller.h"
|
||||
#include "mxdschunk.h"
|
||||
#include "mxdsstreamingaction.h"
|
||||
#include "mxomni.h"
|
||||
#include "mxstreamchunk.h"
|
||||
#include "mxstreamcontroller.h"
|
||||
#include "mxstreamer.h"
|
||||
|
||||
DECOMP_SIZE_ASSERT(MxDSBuffer, 0x34);
|
||||
|
||||
// FUNCTION: LEGO1 0x100c6470
|
||||
MxDSBuffer::MxDSBuffer()
|
||||
{
|
||||
m_refcount = 0;
|
||||
m_pBuffer = NULL;
|
||||
m_pIntoBuffer = NULL;
|
||||
m_pIntoBuffer2 = NULL;
|
||||
m_unk0x14 = 0;
|
||||
m_unk0x18 = 0;
|
||||
m_unk0x1c = 0;
|
||||
m_writeOffset = 0;
|
||||
m_bytesRemaining = 0;
|
||||
m_mode = MxDSBufferType_Preallocated;
|
||||
m_unk0x30 = 0;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c6530
|
||||
MxDSBuffer::~MxDSBuffer()
|
||||
{
|
||||
if (m_pBuffer != NULL) {
|
||||
switch (m_mode) {
|
||||
case MxDSBufferType_Allocate:
|
||||
case MxDSBufferType_Unknown:
|
||||
delete[] m_pBuffer;
|
||||
break;
|
||||
|
||||
case MxDSBufferType_Chunk: {
|
||||
MxU32 offset = m_writeOffset / 1024;
|
||||
MxStreamer* streamer = Streamer();
|
||||
|
||||
switch (offset) {
|
||||
case 0x40: {
|
||||
MxU32 a =
|
||||
(m_pBuffer - streamer->GetSubclass1().GetBuffer()) / (streamer->GetSubclass1().GetSize() << 10);
|
||||
|
||||
MxU32 bit = 1 << ((MxU8) a & 0x1f);
|
||||
MxU32 index = (a & ~0x18u) >> 3;
|
||||
|
||||
if ((*(MxU32*) (&streamer->GetSubclass1().GetUnk08Ref()[index])) & bit) {
|
||||
MxU32* ptr = (MxU32*) (&streamer->GetSubclass1().GetUnk08Ref()[index]);
|
||||
*ptr = *ptr ^ bit;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x80: {
|
||||
MxU32 a =
|
||||
(m_pBuffer - streamer->GetSubclass1().GetBuffer()) / (streamer->GetSubclass1().GetSize() << 10);
|
||||
|
||||
MxU32 bit = 1 << ((MxU8) a & 0x1f);
|
||||
MxU32 index = (a & ~0x18u) >> 3;
|
||||
|
||||
if ((*(MxU32*) (&streamer->GetSubclass2().GetUnk08Ref()[index])) & bit) {
|
||||
MxU32* ptr = (MxU32*) (&streamer->GetSubclass2().GetUnk08Ref()[index]);
|
||||
*ptr = *ptr ^ bit;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_unk0x14 = 0;
|
||||
m_unk0x1c = 0;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c6640
|
||||
MxResult MxDSBuffer::AllocateBuffer(MxU32 p_bufferSize, MxDSBufferType p_mode)
|
||||
{
|
||||
MxResult result = FAILURE;
|
||||
|
||||
switch (p_mode) {
|
||||
case MxDSBufferType_Allocate:
|
||||
m_pBuffer = new MxU8[p_bufferSize];
|
||||
break;
|
||||
|
||||
case MxDSBufferType_Chunk: {
|
||||
MxStreamer* streamer = Streamer();
|
||||
|
||||
switch (p_bufferSize / 1024) {
|
||||
case 0x40: {
|
||||
for (MxU32 i = 0; i < 22; i++) {
|
||||
if (((1 << (i & 0x1f)) & (*(MxU32*) &streamer->GetSubclass1().GetUnk08Ref()[(i & ~0x18u) >> 3])) == 0) {
|
||||
MxU32* ptr = (MxU32*) &streamer->GetSubclass1().GetUnk08Ref()[(i & 0xffffffe7) >> 3];
|
||||
|
||||
*ptr = *ptr ^ 1 << (i & 0x1f);
|
||||
|
||||
m_pBuffer =
|
||||
(MxU8*) (streamer->GetSubclass1().GetSize() * i * 0x400 + streamer->GetSubclass1().GetBuffer());
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
m_pBuffer = NULL;
|
||||
break;
|
||||
}
|
||||
case 0x80: {
|
||||
for (MxU32 i = 0; i < 2; i++) {
|
||||
if (((1 << (i & 0x1f)) & (*(MxU32*) &streamer->GetSubclass2().GetUnk08Ref()[(i & ~0x18u) >> 3])) == 0) {
|
||||
MxU32* ptr = (MxU32*) &streamer->GetSubclass2().GetUnk08Ref()[(i & 0xffffffe7) >> 3];
|
||||
|
||||
*ptr = *ptr ^ 1 << (i & 0x1f);
|
||||
|
||||
m_pBuffer =
|
||||
(MxU8*) (streamer->GetSubclass2().GetSize() * i * 0x400 + streamer->GetSubclass2().GetBuffer());
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
m_pBuffer = NULL;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
m_pBuffer = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
m_pIntoBuffer = m_pBuffer;
|
||||
m_pIntoBuffer2 = m_pBuffer;
|
||||
|
||||
if (m_pBuffer != NULL) {
|
||||
m_mode = p_mode;
|
||||
m_bytesRemaining = p_bufferSize;
|
||||
m_writeOffset = p_bufferSize;
|
||||
result = SUCCESS;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c6780
|
||||
MxResult MxDSBuffer::SetBufferPointer(MxU32* p_buffer, MxU32 p_size)
|
||||
{
|
||||
m_pBuffer = (MxU8*) p_buffer;
|
||||
m_pIntoBuffer = (MxU8*) p_buffer;
|
||||
m_pIntoBuffer2 = (MxU8*) p_buffer;
|
||||
m_bytesRemaining = p_size;
|
||||
m_writeOffset = p_size;
|
||||
m_mode = MxDSBufferType_Preallocated;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c67b0
|
||||
MxResult MxDSBuffer::FUN_100c67b0(
|
||||
MxStreamController* p_controller,
|
||||
MxDSAction* p_action,
|
||||
MxDSStreamingAction** p_streamingAction
|
||||
)
|
||||
{
|
||||
MxResult result = FAILURE;
|
||||
|
||||
m_unk0x30 = (MxDSStreamingAction*) p_controller->GetUnk0x3c().Find(p_action, FALSE);
|
||||
if (m_unk0x30 == NULL)
|
||||
return FAILURE;
|
||||
|
||||
MxU8* data;
|
||||
while (data = (MxU8*) SkipToData()) {
|
||||
if (*p_streamingAction == NULL) {
|
||||
result = CreateObject(p_controller, (MxU32*) data, p_action, p_streamingAction);
|
||||
|
||||
if (result == FAILURE)
|
||||
return result;
|
||||
// TODO: Not a MxResult value?
|
||||
if (result == 1)
|
||||
break;
|
||||
}
|
||||
else {
|
||||
MxDSBuffer* buffer = (*p_streamingAction)->GetUnknowna0();
|
||||
|
||||
if (buffer->CalcBytesRemaining(data) != SUCCESS) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (buffer->GetBytesRemaining() == 0) {
|
||||
buffer->SetUnk30(m_unk0x30);
|
||||
|
||||
result = buffer->CreateObject(p_controller, (MxU32*) buffer->GetBuffer(), p_action, p_streamingAction);
|
||||
if (result != SUCCESS) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (buffer->GetRefCount() != 0) {
|
||||
// Note: *p_streamingAction is always null in MxRamStreamProvider
|
||||
((MxDiskStreamController*) p_controller)->InsertToList74(buffer);
|
||||
(*p_streamingAction)->SetUnknowna0(NULL);
|
||||
}
|
||||
|
||||
((MxDiskStreamController*) p_controller)->FUN_100c7cb0(*p_streamingAction);
|
||||
*p_streamingAction = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c68a0
|
||||
MxResult MxDSBuffer::CreateObject(
|
||||
MxStreamController* p_controller,
|
||||
MxU32* p_data,
|
||||
MxDSAction* p_action,
|
||||
MxDSStreamingAction** p_streamingAction
|
||||
)
|
||||
{
|
||||
if (p_data == NULL) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
MxCore* header = ReadChunk(this, p_data, p_action->GetUnknown24());
|
||||
|
||||
if (header == NULL) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if (*p_data == FOURCC('M', 'x', 'O', 'b'))
|
||||
return StartPresenterFromAction(p_controller, p_action, (MxDSAction*) header);
|
||||
else if (*p_data == FOURCC('M', 'x', 'C', 'h')) {
|
||||
MxStreamChunk* chunk = (MxStreamChunk*) header;
|
||||
if (!m_unk0x30->HasId((chunk)->GetObjectId())) {
|
||||
delete header;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
return ParseChunk(p_controller, p_data, p_action, p_streamingAction, chunk);
|
||||
}
|
||||
|
||||
delete header;
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c6960
|
||||
MxResult MxDSBuffer::StartPresenterFromAction(
|
||||
MxStreamController* p_controller,
|
||||
MxDSAction* p_action1,
|
||||
MxDSAction* p_objectheader
|
||||
)
|
||||
{
|
||||
if (!m_unk0x30->GetInternalAction()) {
|
||||
p_objectheader->SetAtomId(p_action1->GetAtomId());
|
||||
p_objectheader->SetUnknown28(p_action1->GetUnknown28());
|
||||
p_objectheader->SetUnknown84(p_action1->GetUnknown84());
|
||||
p_objectheader->SetOrigin(p_action1->GetOrigin());
|
||||
p_objectheader->SetUnknown90(p_action1->GetUnknown90());
|
||||
p_objectheader->MergeFrom(*p_action1);
|
||||
|
||||
m_unk0x30->SetInternalAction(p_objectheader->Clone());
|
||||
|
||||
p_controller->InsertActionToList54(p_objectheader);
|
||||
|
||||
if (MxOmni::GetInstance()->CreatePresenter(p_controller, *p_objectheader) != SUCCESS) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
m_unk0x30->SetLoopCount(p_objectheader->GetLoopCount());
|
||||
m_unk0x30->SetFlags(p_objectheader->GetFlags());
|
||||
m_unk0x30->SetDuration(p_objectheader->GetDuration());
|
||||
|
||||
if (m_unk0x30->GetInternalAction() == NULL) {
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
else if (p_objectheader) {
|
||||
delete p_objectheader;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c6a50
|
||||
MxResult MxDSBuffer::ParseChunk(
|
||||
MxStreamController* p_controller,
|
||||
MxU32* p_data,
|
||||
MxDSAction* p_action,
|
||||
MxDSStreamingAction** p_streamingAction,
|
||||
MxStreamChunk* p_header
|
||||
)
|
||||
{
|
||||
MxResult result = SUCCESS;
|
||||
|
||||
if (m_unk0x30->GetFlags() & MxDSAction::Flag_Bit3 && m_unk0x30->GetUnknowna8() && p_header->GetTime() < 0) {
|
||||
delete p_header;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
p_header->SetTime(p_header->GetTime() + m_unk0x30->GetUnknowna8());
|
||||
|
||||
if (p_header->GetFlags() & MxDSChunk::Flag_Split) {
|
||||
MxU32 length = p_header->GetLength() + MxDSChunk::ReturnE() + 8;
|
||||
MxDSBuffer* buffer = new MxDSBuffer();
|
||||
|
||||
if (buffer && buffer->AllocateBuffer(length, MxDSBufferType_Allocate) == SUCCESS &&
|
||||
buffer->CalcBytesRemaining((MxU8*) p_data) == SUCCESS) {
|
||||
*p_streamingAction = new MxDSStreamingAction((MxDSStreamingAction&) *p_action);
|
||||
|
||||
if (*p_streamingAction) {
|
||||
MxU16* flags = MxStreamChunk::IntoFlags(buffer->GetBuffer());
|
||||
*flags = p_header->GetFlags() & ~MxDSChunk::Flag_Split;
|
||||
|
||||
delete p_header;
|
||||
(*p_streamingAction)->SetUnknowna0(buffer);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if (buffer)
|
||||
delete buffer;
|
||||
|
||||
delete p_header;
|
||||
return FAILURE;
|
||||
}
|
||||
else {
|
||||
if (p_header->GetFlags() & MxDSChunk::Flag_End) {
|
||||
if (m_unk0x30->HasId(p_header->GetObjectId())) {
|
||||
if (m_unk0x30->GetFlags() & MxDSAction::Flag_Bit3 &&
|
||||
(m_unk0x30->GetLoopCount() > 1 || m_unk0x30->GetDuration() == -1)) {
|
||||
|
||||
if (p_action->GetObjectId() == p_header->GetObjectId()) {
|
||||
MxU32 val = p_controller->GetProvider()->GetBufferForDWords()[m_unk0x30->GetObjectId()];
|
||||
|
||||
m_unk0x30->SetUnknown94(val);
|
||||
m_unk0x30->SetBufferOffset(m_writeOffset * (val / m_writeOffset));
|
||||
|
||||
MxNextActionDataStart* data =
|
||||
p_controller->FindNextActionDataStartFromStreamingAction(m_unk0x30);
|
||||
|
||||
if (data)
|
||||
data->SetData(m_unk0x30->GetBufferOffset());
|
||||
|
||||
m_unk0x30->FUN_100cd2d0();
|
||||
}
|
||||
|
||||
delete p_header;
|
||||
p_header = NULL;
|
||||
}
|
||||
else {
|
||||
if (p_action->GetObjectId() == p_header->GetObjectId() &&
|
||||
p_controller->VTable0x30(p_action) == SUCCESS) {
|
||||
p_controller->GetProvider()->VTable0x20(p_action);
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (p_header) {
|
||||
if (p_header->SendChunk(p_controller->GetSubscriberList(), TRUE, p_action->GetUnknown24()) != SUCCESS) {
|
||||
delete p_header;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
return result;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c6d00
|
||||
MxCore* MxDSBuffer::ReadChunk(MxDSBuffer* p_buffer, MxU32* p_chunkData, MxU16 p_flags)
|
||||
{
|
||||
// This function reads a chunk. If it is an object, this function returns an MxDSObject. If it is a chunk,
|
||||
// returns a MxDSChunk.
|
||||
MxCore* result = NULL;
|
||||
MxU8* dataStart = (MxU8*) p_chunkData + 8;
|
||||
|
||||
switch (*p_chunkData) {
|
||||
case FOURCC('M', 'x', 'O', 'b'):
|
||||
result = DeserializeDSObjectDispatch(&dataStart, p_flags);
|
||||
break;
|
||||
case FOURCC('M', 'x', 'C', 'h'):
|
||||
result = new MxStreamChunk();
|
||||
if (result != NULL && ((MxStreamChunk*) result)->ReadChunk(p_buffer, (MxU8*) p_chunkData) != SUCCESS) {
|
||||
delete result;
|
||||
result = NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c6df0
|
||||
MxU8* MxDSBuffer::SkipToData()
|
||||
{
|
||||
MxU8* result = NULL;
|
||||
|
||||
if (m_pIntoBuffer != NULL) {
|
||||
do {
|
||||
MxU32* ptr = (MxU32*) m_pIntoBuffer;
|
||||
switch (*ptr) {
|
||||
case FOURCC('L', 'I', 'S', 'T'):
|
||||
case FOURCC('R', 'I', 'F', 'F'):
|
||||
m_pIntoBuffer = (MxU8*) (ptr + 3);
|
||||
break;
|
||||
case FOURCC('M', 'x', 'O', 'b'):
|
||||
case FOURCC('M', 'x', 'C', 'h'):
|
||||
result = m_pIntoBuffer;
|
||||
m_pIntoBuffer = (MxU8*) ((ptr[1] & 1) + ptr[1] + (MxU32) ptr);
|
||||
m_pIntoBuffer = (MxU8*) ((MxU32*) m_pIntoBuffer + 2);
|
||||
if (m_pBuffer + (m_writeOffset - 8) < m_pIntoBuffer) {
|
||||
m_pIntoBuffer2 = result;
|
||||
m_pIntoBuffer = NULL;
|
||||
return result;
|
||||
}
|
||||
goto done;
|
||||
case FOURCC('M', 'x', 'D', 'a'):
|
||||
case FOURCC('M', 'x', 'S', 't'):
|
||||
m_pIntoBuffer = (MxU8*) (ptr + 2);
|
||||
break;
|
||||
case FOURCC('M', 'x', 'H', 'd'):
|
||||
m_pIntoBuffer = (MxU8*) ((MxU32) ptr + ptr[1] + 8);
|
||||
break;
|
||||
default:
|
||||
m_pIntoBuffer = NULL;
|
||||
m_pIntoBuffer2 = NULL;
|
||||
return NULL;
|
||||
}
|
||||
} while (m_pIntoBuffer <= m_pBuffer + (m_writeOffset - 8));
|
||||
}
|
||||
done:
|
||||
m_pIntoBuffer2 = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c6ec0
|
||||
MxU8 MxDSBuffer::ReleaseRef(MxDSChunk*)
|
||||
{
|
||||
if (m_refcount != 0) {
|
||||
m_refcount--;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c6ee0
|
||||
void MxDSBuffer::AddRef(MxDSChunk* p_chunk)
|
||||
{
|
||||
if (p_chunk) {
|
||||
m_refcount++;
|
||||
}
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c6ef0
|
||||
MxResult MxDSBuffer::CalcBytesRemaining(MxU8* p_data)
|
||||
{
|
||||
MxResult result = FAILURE;
|
||||
|
||||
if (m_mode == MxDSBufferType_Allocate && m_bytesRemaining != 0) {
|
||||
MxU32 bytesRead;
|
||||
MxU8* ptr;
|
||||
|
||||
if (m_writeOffset == m_bytesRemaining) {
|
||||
bytesRead = *(MxU32*) (p_data + 4) + 8;
|
||||
ptr = p_data;
|
||||
}
|
||||
else {
|
||||
ptr = &p_data[MxStreamChunk::ReturnE() + 8];
|
||||
bytesRead = (*(MxU32*) (p_data + 4)) - MxStreamChunk::ReturnE();
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
m_bytesRemaining -= bytesRead;
|
||||
result = SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c6f80
|
||||
void MxDSBuffer::FUN_100c6f80(MxU32 p_writeOffset)
|
||||
{
|
||||
if (p_writeOffset < m_writeOffset) {
|
||||
m_pIntoBuffer2 = m_pBuffer + p_writeOffset;
|
||||
m_pIntoBuffer = m_pBuffer + p_writeOffset;
|
||||
}
|
||||
}
|
||||
26
LEGO1/omni/src/stream/mxdschunk.cpp
Normal file
26
LEGO1/omni/src/stream/mxdschunk.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
#include "mxdschunk.h"
|
||||
|
||||
DECOMP_SIZE_ASSERT(MxDSChunk, 0x1c);
|
||||
|
||||
// FUNCTION: LEGO1 0x100be050
|
||||
MxDSChunk::MxDSChunk()
|
||||
{
|
||||
m_flags = 0;
|
||||
m_data = NULL;
|
||||
m_objectId = -1;
|
||||
m_time = 0;
|
||||
m_length = 0;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100be170
|
||||
MxDSChunk::~MxDSChunk()
|
||||
{
|
||||
if (m_flags & Flag_Bit1)
|
||||
delete[] m_data;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100be1e0
|
||||
MxU32 MxDSChunk::ReturnE()
|
||||
{
|
||||
return 0xe;
|
||||
}
|
||||
124
LEGO1/omni/src/stream/mxdsfile.cpp
Normal file
124
LEGO1/omni/src/stream/mxdsfile.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
#include "mxdsfile.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define SI_MAJOR_VERSION 2
|
||||
#define SI_MINOR_VERSION 2
|
||||
|
||||
// FUNCTION: LEGO1 0x100bfed0
|
||||
MxDSFile::~MxDSFile()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100cc4b0
|
||||
MxDSFile::MxDSFile(const char* p_filename, MxULong p_skipReadingChunks)
|
||||
{
|
||||
m_filename = p_filename;
|
||||
m_skipReadingChunks = p_skipReadingChunks;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100cc590
|
||||
MxLong MxDSFile::Open(MxULong p_uStyle)
|
||||
{
|
||||
MXIOINFO& io = m_io;
|
||||
MxLong longResult = 1;
|
||||
memset(&io, 0, sizeof(MXIOINFO));
|
||||
|
||||
if (io.Open(m_filename.GetData(), p_uStyle) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
io.SetBuffer(NULL, 0, 0);
|
||||
m_position = 0;
|
||||
|
||||
if (m_skipReadingChunks == 0) {
|
||||
longResult = ReadChunks();
|
||||
}
|
||||
|
||||
if (longResult != 0) {
|
||||
Close(); // vtable + 0x18
|
||||
}
|
||||
else {
|
||||
Seek(0, 0); // vtable + 0x24
|
||||
}
|
||||
|
||||
return longResult;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100cc620
|
||||
MxLong MxDSFile::ReadChunks()
|
||||
{
|
||||
_MMCKINFO topChunk;
|
||||
_MMCKINFO childChunk;
|
||||
char tempBuffer[80];
|
||||
|
||||
topChunk.fccType = FOURCC('O', 'M', 'N', 'I');
|
||||
if (m_io.Descend(&topChunk, NULL, MMIO_FINDRIFF) != 0) {
|
||||
return -1;
|
||||
}
|
||||
childChunk.ckid = FOURCC('M', 'x', 'H', 'd');
|
||||
if (m_io.Descend(&childChunk, &topChunk, 0) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
m_io.Read(&m_header, 0xc);
|
||||
if ((m_header.m_majorVersion == SI_MAJOR_VERSION) && (m_header.m_minorVersion == SI_MINOR_VERSION)) {
|
||||
childChunk.ckid = FOURCC('M', 'x', 'O', 'f');
|
||||
if (m_io.Descend(&childChunk, &topChunk, 0) != 0) {
|
||||
return -1;
|
||||
}
|
||||
MxULong* pLengthInDWords = &m_lengthInDWords;
|
||||
m_io.Read(pLengthInDWords, 4);
|
||||
m_pBuffer = new MxU32[*pLengthInDWords];
|
||||
m_io.Read(m_pBuffer, *pLengthInDWords * 4);
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
sprintf(tempBuffer, "Wrong SI file version. %d.%d expected.", SI_MAJOR_VERSION, SI_MINOR_VERSION);
|
||||
MessageBoxA(NULL, tempBuffer, NULL, MB_ICONERROR);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100cc740
|
||||
MxLong MxDSFile::Close()
|
||||
{
|
||||
m_io.Close(0);
|
||||
m_position = -1;
|
||||
memset(&m_header, 0, sizeof(m_header));
|
||||
if (m_lengthInDWords != 0) {
|
||||
m_lengthInDWords = 0;
|
||||
delete[] m_pBuffer;
|
||||
m_pBuffer = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100cc780
|
||||
MxResult MxDSFile::Read(unsigned char* p_buf, MxULong p_nbytes)
|
||||
{
|
||||
if (m_io.Read(p_buf, p_nbytes) != p_nbytes)
|
||||
return FAILURE;
|
||||
|
||||
m_position += p_nbytes;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100cc7b0
|
||||
MxLong MxDSFile::Seek(MxLong p_lOffset, MxS32 p_iOrigin)
|
||||
{
|
||||
return (m_position = m_io.Seek(p_lOffset, p_iOrigin)) == -1 ? -1 : 0;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100cc7e0
|
||||
MxULong MxDSFile::GetBufferSize()
|
||||
{
|
||||
return m_header.m_bufferSize;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100cc7f0
|
||||
MxULong MxDSFile::GetStreamBuffersNum()
|
||||
{
|
||||
return m_header.m_streamBuffersNum;
|
||||
}
|
||||
23
LEGO1/omni/src/stream/mxdssource.cpp
Normal file
23
LEGO1/omni/src/stream/mxdssource.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#include "mxdssource.h"
|
||||
|
||||
#include "mxdsbuffer.h"
|
||||
|
||||
DECOMP_SIZE_ASSERT(MxDSSource, 0x14)
|
||||
|
||||
// FUNCTION: LEGO1 0x100bffd0
|
||||
MxResult MxDSSource::ReadToBuffer(MxDSBuffer* p_buffer)
|
||||
{
|
||||
return Read(p_buffer->GetBuffer(), p_buffer->GetWriteOffset());
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100bfff0
|
||||
MxLong MxDSSource::GetLengthInDWords()
|
||||
{
|
||||
return m_lengthInDWords;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c0000
|
||||
MxU32* MxDSSource::GetBuffer()
|
||||
{
|
||||
return m_pBuffer;
|
||||
}
|
||||
125
LEGO1/omni/src/stream/mxdssubscriber.cpp
Normal file
125
LEGO1/omni/src/stream/mxdssubscriber.cpp
Normal file
@@ -0,0 +1,125 @@
|
||||
#include "mxdssubscriber.h"
|
||||
|
||||
#include "mxstreamcontroller.h"
|
||||
|
||||
DECOMP_SIZE_ASSERT(MxDSSubscriber, 0x4c);
|
||||
|
||||
// FUNCTION: LEGO1 0x100b7bb0
|
||||
MxDSSubscriber::MxDSSubscriber()
|
||||
{
|
||||
m_unk0x48 = -1;
|
||||
m_objectId = -1;
|
||||
m_unk0x20 = NULL;
|
||||
m_unk0x3c = NULL;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100b7e00
|
||||
MxDSSubscriber::~MxDSSubscriber()
|
||||
{
|
||||
if (m_controller)
|
||||
m_controller->RemoveSubscriber(this);
|
||||
|
||||
DeleteChunks();
|
||||
|
||||
if (m_unk0x20)
|
||||
delete m_unk0x20;
|
||||
m_unk0x20 = NULL;
|
||||
|
||||
if (m_unk0x3c)
|
||||
delete m_unk0x3c;
|
||||
m_unk0x3c = NULL;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100b7ed0
|
||||
MxResult MxDSSubscriber::Create(MxStreamController* p_controller, MxU32 p_objectId, MxS16 p_unk0x48)
|
||||
{
|
||||
m_objectId = p_objectId;
|
||||
m_unk0x48 = p_unk0x48;
|
||||
|
||||
if (!p_controller)
|
||||
return FAILURE;
|
||||
m_controller = p_controller;
|
||||
|
||||
m_unk0x20 = new MxStreamChunkListCursor(&m_unk0x08);
|
||||
if (!m_unk0x20)
|
||||
return FAILURE;
|
||||
|
||||
m_unk0x3c = new MxStreamChunkListCursor(&m_unk0x24);
|
||||
if (!m_unk0x3c)
|
||||
return FAILURE;
|
||||
|
||||
m_controller->AddSubscriber(this);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100b8030
|
||||
void MxDSSubscriber::DeleteChunks()
|
||||
{
|
||||
if (m_controller) {
|
||||
MxStreamChunk* chunk = NULL;
|
||||
|
||||
while (m_unk0x20->First(chunk)) {
|
||||
m_unk0x20->Detach();
|
||||
delete chunk;
|
||||
}
|
||||
|
||||
while (m_unk0x3c->First(chunk)) {
|
||||
m_unk0x3c->Detach();
|
||||
delete chunk;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100b8150
|
||||
MxResult MxDSSubscriber::AddChunk(MxStreamChunk* p_chunk, MxBool p_append)
|
||||
{
|
||||
if (m_unk0x20) {
|
||||
if (p_append)
|
||||
m_unk0x08.Append(p_chunk);
|
||||
else
|
||||
m_unk0x08.Prepend(p_chunk);
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100b8250
|
||||
MxStreamChunk* MxDSSubscriber::FUN_100b8250()
|
||||
{
|
||||
MxStreamChunk* chunk = NULL;
|
||||
|
||||
if (m_unk0x20)
|
||||
m_unk0x20->First(chunk);
|
||||
|
||||
if (chunk) {
|
||||
m_unk0x20->Detach();
|
||||
m_unk0x24.Append(chunk);
|
||||
}
|
||||
|
||||
return chunk;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100b8360
|
||||
MxStreamChunk* MxDSSubscriber::FUN_100b8360()
|
||||
{
|
||||
MxStreamChunk* chunk = NULL;
|
||||
|
||||
if (m_unk0x20)
|
||||
m_unk0x20->First(chunk);
|
||||
|
||||
return chunk;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100b8390
|
||||
void MxDSSubscriber::FUN_100b8390(MxStreamChunk* p_chunk)
|
||||
{
|
||||
if (p_chunk) {
|
||||
if (m_unk0x3c->Find(p_chunk)) {
|
||||
m_unk0x3c->Detach();
|
||||
if (p_chunk)
|
||||
delete p_chunk;
|
||||
}
|
||||
else if (p_chunk->GetFlags() & MxDSChunk::Flag_Bit1 && p_chunk)
|
||||
delete p_chunk;
|
||||
}
|
||||
}
|
||||
460
LEGO1/omni/src/stream/mxioinfo.cpp
Normal file
460
LEGO1/omni/src/stream/mxioinfo.cpp
Normal file
@@ -0,0 +1,460 @@
|
||||
#include "mxioinfo.h"
|
||||
|
||||
#include "decomp.h"
|
||||
|
||||
// This class should be 72 bytes in size, same as the MMIOINFO struct.
|
||||
// The current implementation has MMIOINFO as the only member of the class,
|
||||
// but this assert will enforce the size if we decide to change that.
|
||||
DECOMP_SIZE_ASSERT(MXIOINFO, sizeof(MMIOINFO));
|
||||
|
||||
// FUNCTION: LEGO1 0x100cc800
|
||||
MXIOINFO::MXIOINFO()
|
||||
{
|
||||
memset(&m_info, 0, sizeof(m_info));
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100cc820
|
||||
MXIOINFO::~MXIOINFO()
|
||||
{
|
||||
Close(0);
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100cc830
|
||||
MxU16 MXIOINFO::Open(const char* p_filename, MxULong p_flags)
|
||||
{
|
||||
OFSTRUCT unused;
|
||||
MxU16 result = 0;
|
||||
|
||||
m_info.lBufOffset = 0;
|
||||
m_info.lDiskOffset = 0;
|
||||
|
||||
// DECOMP: Cast of p_flags to u16 forces the `movzx` instruction
|
||||
m_info.hmmio = (HMMIO) OpenFile(p_filename, &unused, (MxU16) p_flags);
|
||||
|
||||
if ((HFILE) m_info.hmmio != HFILE_ERROR) {
|
||||
m_info.dwFlags = p_flags;
|
||||
if (p_flags & MMIO_ALLOCBUF) {
|
||||
|
||||
// Default buffer length of 8k if none specified
|
||||
MxLong len = m_info.cchBuffer ? m_info.cchBuffer : 8192;
|
||||
HPSTR buf = new char[len];
|
||||
|
||||
if (!buf) {
|
||||
result = MMIOERR_OUTOFMEMORY;
|
||||
m_info.cchBuffer = 0;
|
||||
m_info.dwFlags &= ~MMIO_ALLOCBUF;
|
||||
m_info.pchBuffer = 0;
|
||||
}
|
||||
else {
|
||||
m_info.pchBuffer = buf;
|
||||
m_info.cchBuffer = len;
|
||||
}
|
||||
|
||||
m_info.pchEndRead = m_info.pchBuffer;
|
||||
m_info.pchNext = m_info.pchBuffer;
|
||||
m_info.pchEndWrite = m_info.pchBuffer + m_info.cchBuffer;
|
||||
}
|
||||
}
|
||||
else {
|
||||
result = MMIOERR_CANNOTOPEN;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100cc8e0
|
||||
MxU16 MXIOINFO::Close(MxLong p_unused)
|
||||
{
|
||||
MxU16 result = 0;
|
||||
|
||||
if (m_info.hmmio) {
|
||||
result = Flush(0);
|
||||
_lclose((HFILE) m_info.hmmio);
|
||||
m_info.hmmio = 0;
|
||||
|
||||
if (m_info.dwFlags & MMIO_ALLOCBUF)
|
||||
delete[] m_info.pchBuffer;
|
||||
|
||||
m_info.pchEndWrite = 0;
|
||||
m_info.pchEndRead = 0;
|
||||
m_info.pchBuffer = 0;
|
||||
m_info.dwFlags = 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100cc930
|
||||
MxLong MXIOINFO::Read(void* p_buf, MxLong p_len)
|
||||
{
|
||||
MxLong bytesRead = 0;
|
||||
|
||||
if (m_info.pchBuffer) {
|
||||
|
||||
MxLong bytesLeft = m_info.pchEndRead - m_info.pchNext;
|
||||
while (p_len > 0) {
|
||||
|
||||
if (bytesLeft > 0) {
|
||||
if (p_len < bytesLeft)
|
||||
bytesLeft = p_len;
|
||||
|
||||
memcpy(p_buf, m_info.pchNext, bytesLeft);
|
||||
p_len -= bytesLeft;
|
||||
|
||||
m_info.pchNext += bytesLeft;
|
||||
bytesRead += bytesLeft;
|
||||
}
|
||||
|
||||
if (p_len <= 0 || Advance(0))
|
||||
break;
|
||||
|
||||
bytesLeft = m_info.pchEndRead - m_info.pchNext;
|
||||
if (bytesLeft <= 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (m_info.hmmio && p_len > 0) {
|
||||
bytesRead = _hread((HFILE) m_info.hmmio, p_buf, p_len);
|
||||
|
||||
if (bytesRead == -1) {
|
||||
bytesRead = 0;
|
||||
m_info.lDiskOffset = _llseek((HFILE) m_info.hmmio, 0, SEEK_CUR);
|
||||
}
|
||||
else {
|
||||
m_info.lDiskOffset += bytesRead;
|
||||
}
|
||||
}
|
||||
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100cca00
|
||||
MxLong MXIOINFO::Seek(MxLong p_offset, MxLong p_origin)
|
||||
{
|
||||
MxLong result = -1;
|
||||
|
||||
// If buffered I/O
|
||||
if (m_info.pchBuffer) {
|
||||
if (p_origin == SEEK_CUR) {
|
||||
if (!p_offset) {
|
||||
// don't seek at all and just return where we are.
|
||||
return m_info.lBufOffset + (m_info.pchNext - m_info.pchBuffer);
|
||||
}
|
||||
else {
|
||||
// With SEEK_CUR, p_offset is a relative offset.
|
||||
// Get the absolute position instead and use SEEK_SET.
|
||||
p_offset += m_info.lBufOffset + (m_info.pchNext - m_info.pchBuffer);
|
||||
p_origin = SEEK_SET;
|
||||
}
|
||||
}
|
||||
else if (p_origin == SEEK_END) {
|
||||
// not possible with buffered I/O
|
||||
return -1;
|
||||
}
|
||||
|
||||
// else p_origin == SEEK_SET.
|
||||
|
||||
// is p_offset between the start and end of the buffer?
|
||||
// i.e. can we do the seek without reading more from disk?
|
||||
if (p_offset >= m_info.lBufOffset && p_offset < m_info.lBufOffset + m_info.cchBuffer) {
|
||||
m_info.pchNext = m_info.pchBuffer + (p_offset - m_info.lBufOffset);
|
||||
result = p_offset;
|
||||
}
|
||||
else {
|
||||
// we have to read another chunk from disk.
|
||||
if (m_info.hmmio && !Flush(0)) {
|
||||
m_info.lDiskOffset = _llseek((HFILE) m_info.hmmio, p_offset, p_origin);
|
||||
|
||||
if (m_info.lDiskOffset == -1) {
|
||||
m_info.lDiskOffset = _llseek((HFILE) m_info.hmmio, 0, SEEK_CUR);
|
||||
}
|
||||
else {
|
||||
|
||||
// align offset to buffer size
|
||||
MxLong newOffset = p_offset - (p_offset % m_info.cchBuffer);
|
||||
m_info.lBufOffset = newOffset;
|
||||
|
||||
// do we need to seek again?
|
||||
// (i.e. are we already aligned to buffer size?)
|
||||
if (p_offset != newOffset) {
|
||||
m_info.lDiskOffset = _llseek((HFILE) m_info.hmmio, newOffset, SEEK_SET);
|
||||
|
||||
if (m_info.lDiskOffset == -1) {
|
||||
m_info.lDiskOffset = _llseek((HFILE) m_info.hmmio, 0, SEEK_CUR);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_info.lBufOffset == m_info.lDiskOffset) {
|
||||
// is the file open for writing only?
|
||||
if ((m_info.dwFlags & MMIO_RWMODE) && ((m_info.dwFlags & MMIO_RWMODE) != MMIO_READWRITE)) {
|
||||
|
||||
m_info.pchNext = m_info.pchBuffer - m_info.lBufOffset + p_offset;
|
||||
|
||||
result = p_offset;
|
||||
}
|
||||
else {
|
||||
// We can read from the file. Fill the buffer.
|
||||
MxLong bytesRead = _hread((HFILE) m_info.hmmio, m_info.pchBuffer, m_info.cchBuffer);
|
||||
|
||||
if (bytesRead == -1) {
|
||||
m_info.lDiskOffset = _llseek((HFILE) m_info.hmmio, 0, SEEK_CUR);
|
||||
}
|
||||
else {
|
||||
m_info.lDiskOffset += bytesRead;
|
||||
m_info.pchNext = p_offset - m_info.lBufOffset + m_info.pchBuffer;
|
||||
m_info.pchEndRead = m_info.pchBuffer + bytesRead;
|
||||
|
||||
if (m_info.pchNext < m_info.pchEndRead) {
|
||||
result = p_offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// No buffer so just seek the file directly (if we have a valid handle)
|
||||
if (m_info.hmmio) {
|
||||
// i.e. if we just want to get the current file position
|
||||
if (p_origin == SEEK_CUR && p_offset == 0) {
|
||||
return m_info.lDiskOffset;
|
||||
}
|
||||
else {
|
||||
m_info.lDiskOffset = _llseek((HFILE) m_info.hmmio, p_offset, p_origin);
|
||||
|
||||
result = m_info.lDiskOffset;
|
||||
|
||||
if (result == -1) {
|
||||
m_info.lDiskOffset = _llseek((HFILE) m_info.hmmio, 0, SEEK_CUR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100ccbc0
|
||||
MxU16 MXIOINFO::SetBuffer(char* p_buf, MxLong p_len, MxLong p_unused)
|
||||
{
|
||||
MxU16 result = Flush(0);
|
||||
|
||||
if (m_info.dwFlags & MMIO_ALLOCBUF) {
|
||||
m_info.dwFlags &= ~MMIO_ALLOCBUF;
|
||||
delete[] m_info.pchBuffer;
|
||||
}
|
||||
|
||||
m_info.pchBuffer = p_buf;
|
||||
m_info.cchBuffer = p_len;
|
||||
m_info.pchEndWrite = m_info.pchBuffer + m_info.cchBuffer;
|
||||
m_info.pchEndRead = m_info.pchBuffer;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100ccc10
|
||||
MxU16 MXIOINFO::Flush(MxU16 p_unused)
|
||||
{
|
||||
MxU16 result = 0;
|
||||
|
||||
// if buffer is dirty
|
||||
if (m_info.dwFlags & MMIO_DIRTY) {
|
||||
// if we have allocated an IO buffer
|
||||
if (m_info.pchBuffer) {
|
||||
// if we have a file open for writing
|
||||
if (m_info.hmmio && (m_info.dwFlags & MMIO_RWMODE)) {
|
||||
// DECOMP: pulling this value out into a variable forces it into EBX
|
||||
MxLong cchBuffer = m_info.cchBuffer;
|
||||
if (cchBuffer > 0) {
|
||||
if (m_info.lBufOffset != m_info.lDiskOffset) {
|
||||
m_info.lDiskOffset = _llseek((HFILE) m_info.hmmio, m_info.lBufOffset, SEEK_SET);
|
||||
}
|
||||
|
||||
// Was the previous seek (if required) successful?
|
||||
if (m_info.lBufOffset != m_info.lDiskOffset) {
|
||||
result = MMIOERR_CANNOTSEEK;
|
||||
m_info.lDiskOffset = _llseek((HFILE) m_info.hmmio, 0, SEEK_CUR);
|
||||
}
|
||||
else {
|
||||
MxLong bytesWritten = _hwrite((HFILE) m_info.hmmio, m_info.pchBuffer, cchBuffer);
|
||||
|
||||
if (bytesWritten != -1 && bytesWritten == cchBuffer) {
|
||||
m_info.lDiskOffset += bytesWritten;
|
||||
m_info.pchNext = m_info.pchBuffer;
|
||||
m_info.dwFlags &= ~MMIO_DIRTY;
|
||||
}
|
||||
else {
|
||||
result = MMIOERR_CANNOTWRITE;
|
||||
m_info.lDiskOffset = _llseek((HFILE) m_info.hmmio, 0, SEEK_CUR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
result = MMIOERR_CANNOTWRITE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
result = MMIOERR_UNBUFFERED;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100ccd00
|
||||
MxU16 MXIOINFO::Advance(MxU16 p_option)
|
||||
{
|
||||
MxU16 result = 0;
|
||||
MxULong rwmode = m_info.dwFlags & MMIO_RWMODE;
|
||||
|
||||
if (m_info.pchBuffer) {
|
||||
MxLong cch = m_info.cchBuffer;
|
||||
|
||||
// If we can and should write to the file,
|
||||
// if we are being asked to write to the file,
|
||||
// and if there is a buffer *to* write:
|
||||
if ((rwmode == MMIO_WRITE || rwmode == MMIO_READWRITE) && (m_info.dwFlags & MMIO_DIRTY) &&
|
||||
((p_option & MMIO_WRITE) || (rwmode == MMIO_READWRITE)) && cch > 0) {
|
||||
|
||||
if (m_info.lBufOffset != m_info.lDiskOffset) {
|
||||
m_info.lDiskOffset = _llseek((HFILE) m_info.hmmio, m_info.lBufOffset, SEEK_SET);
|
||||
}
|
||||
|
||||
if (m_info.lBufOffset != m_info.lDiskOffset) {
|
||||
result = MMIOERR_CANNOTSEEK;
|
||||
}
|
||||
else {
|
||||
MxLong bytesWritten = _hwrite((HFILE) m_info.hmmio, m_info.pchBuffer, cch);
|
||||
|
||||
if (bytesWritten != -1 && bytesWritten == cch) {
|
||||
m_info.lDiskOffset += bytesWritten;
|
||||
m_info.pchNext = m_info.pchBuffer;
|
||||
m_info.pchEndRead = m_info.pchBuffer;
|
||||
m_info.dwFlags &= ~MMIO_DIRTY;
|
||||
}
|
||||
else {
|
||||
result = MMIOERR_CANNOTWRITE;
|
||||
}
|
||||
}
|
||||
|
||||
m_info.lDiskOffset = _llseek((HFILE) m_info.hmmio, 0, SEEK_CUR);
|
||||
}
|
||||
|
||||
m_info.lBufOffset += cch;
|
||||
if ((!rwmode || rwmode == MMIO_READWRITE) && cch > 0) {
|
||||
if (m_info.lBufOffset != m_info.lDiskOffset) {
|
||||
m_info.lDiskOffset = _llseek((HFILE) m_info.hmmio, m_info.lBufOffset, SEEK_SET);
|
||||
}
|
||||
|
||||
// if previous seek failed
|
||||
if (m_info.lBufOffset != m_info.lDiskOffset) {
|
||||
result = MMIOERR_CANNOTSEEK;
|
||||
m_info.lDiskOffset = _llseek((HFILE) m_info.hmmio, 0, SEEK_CUR);
|
||||
}
|
||||
else {
|
||||
MxLong bytesRead = _hread((HFILE) m_info.hmmio, m_info.pchBuffer, cch);
|
||||
|
||||
if (bytesRead == -1) {
|
||||
result = MMIOERR_CANNOTREAD;
|
||||
m_info.lDiskOffset = _llseek((HFILE) m_info.hmmio, 0, SEEK_CUR);
|
||||
}
|
||||
else {
|
||||
m_info.lDiskOffset += bytesRead;
|
||||
m_info.pchNext = m_info.pchBuffer;
|
||||
m_info.pchEndRead = m_info.pchBuffer + bytesRead;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
result = MMIOERR_UNBUFFERED;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100cce60
|
||||
MxU16 MXIOINFO::Descend(MMCKINFO* p_chunkInfo, const MMCKINFO* p_parentInfo, MxU16 p_descend)
|
||||
{
|
||||
MxU16 result = 0;
|
||||
|
||||
if (!p_chunkInfo)
|
||||
return MMIOERR_BASE; // ?
|
||||
|
||||
if (!p_descend) {
|
||||
p_chunkInfo->dwFlags = 0;
|
||||
if (Read(p_chunkInfo, 8) != 8) {
|
||||
result = MMIOERR_CANNOTREAD;
|
||||
}
|
||||
else {
|
||||
if (m_info.pchBuffer) {
|
||||
p_chunkInfo->dwDataOffset = m_info.pchNext - m_info.pchBuffer + m_info.lBufOffset;
|
||||
}
|
||||
else {
|
||||
p_chunkInfo->dwDataOffset = m_info.lDiskOffset;
|
||||
}
|
||||
|
||||
if ((p_chunkInfo->ckid == FOURCC_RIFF || p_chunkInfo->ckid == FOURCC_LIST) &&
|
||||
Read(&p_chunkInfo->fccType, 4) != 4) {
|
||||
result = MMIOERR_CANNOTREAD;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
MxULong ofs = MAXLONG;
|
||||
|
||||
if (p_parentInfo)
|
||||
ofs = p_parentInfo->cksize + p_parentInfo->dwDataOffset;
|
||||
|
||||
BOOL running = TRUE;
|
||||
BOOL readOk = FALSE;
|
||||
MMCKINFO tmp;
|
||||
tmp.dwFlags = 0;
|
||||
|
||||
while (running) {
|
||||
if (Read(&tmp, 8) != 8) {
|
||||
// If the first read fails, report read error. Else EOF.
|
||||
result = readOk ? MMIOERR_CHUNKNOTFOUND : MMIOERR_CANNOTREAD;
|
||||
running = FALSE;
|
||||
}
|
||||
else {
|
||||
readOk = TRUE;
|
||||
if (m_info.pchBuffer) {
|
||||
tmp.dwDataOffset = m_info.pchNext - m_info.pchBuffer + m_info.lBufOffset;
|
||||
}
|
||||
else {
|
||||
tmp.dwDataOffset = m_info.lDiskOffset;
|
||||
}
|
||||
|
||||
if (ofs < tmp.dwDataOffset) {
|
||||
result = MMIOERR_CHUNKNOTFOUND;
|
||||
running = FALSE;
|
||||
}
|
||||
else if ((p_descend == MMIO_FINDLIST && tmp.ckid == FOURCC_LIST) || (p_descend == MMIO_FINDRIFF && tmp.ckid == FOURCC_RIFF)) {
|
||||
if (Read(&tmp.fccType, 4) != 4) {
|
||||
result = MMIOERR_CANNOTREAD;
|
||||
running = FALSE;
|
||||
}
|
||||
else if (p_chunkInfo->fccType == tmp.fccType) {
|
||||
running = FALSE;
|
||||
}
|
||||
}
|
||||
else if (p_chunkInfo->ckid == tmp.ckid) {
|
||||
running = FALSE;
|
||||
}
|
||||
else if (Seek((tmp.cksize & 1) + tmp.cksize, SEEK_CUR) == -1) {
|
||||
result = MMIOERR_CANNOTSEEK;
|
||||
running = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!result)
|
||||
memcpy(p_chunkInfo, &tmp, sizeof(MMCKINFO));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
103
LEGO1/omni/src/stream/mxramstreamcontroller.cpp
Normal file
103
LEGO1/omni/src/stream/mxramstreamcontroller.cpp
Normal file
@@ -0,0 +1,103 @@
|
||||
#include "mxramstreamcontroller.h"
|
||||
|
||||
#include "mxautolocker.h"
|
||||
#include "mxdsstreamingaction.h"
|
||||
#include "mxramstreamprovider.h"
|
||||
|
||||
DECOMP_SIZE_ASSERT(MxRAMStreamController, 0x98);
|
||||
|
||||
undefined* __cdecl ReadData(MxU32* p_fileSizeBuffer, MxU32 p_fileSize);
|
||||
|
||||
// FUNCTION: LEGO1 0x100c6110
|
||||
MxResult MxRAMStreamController::Open(const char* p_filename)
|
||||
{
|
||||
MxAutoLocker lock(&m_criticalSection);
|
||||
if (MxStreamController::Open(p_filename) != SUCCESS) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
m_provider = new MxRAMStreamProvider();
|
||||
if (((MxRAMStreamProvider*) m_provider) != NULL) {
|
||||
if (m_provider->SetResourceToGet(this) != SUCCESS) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
ReadData(
|
||||
((MxRAMStreamProvider*) m_provider)->GetBufferOfFileSize(),
|
||||
((MxRAMStreamProvider*) m_provider)->GetFileSize()
|
||||
);
|
||||
m_buffer.SetBufferPointer(
|
||||
((MxRAMStreamProvider*) m_provider)->GetBufferOfFileSize(),
|
||||
((MxRAMStreamProvider*) m_provider)->GetFileSize()
|
||||
);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c6210
|
||||
MxResult MxRAMStreamController::VTable0x20(MxDSAction* p_action)
|
||||
{
|
||||
MxAutoLocker lock(&m_criticalSection);
|
||||
MxS32 unk0x24 = 0;
|
||||
MxResult result = FAILURE;
|
||||
|
||||
if (p_action->GetUnknown24() == -1) {
|
||||
p_action->SetUnknown24(-3);
|
||||
MxDSAction* action = m_unk0x54.Find(p_action, FALSE);
|
||||
if (action != NULL) {
|
||||
unk0x24 = action->GetUnknown24() + 1;
|
||||
}
|
||||
p_action->SetUnknown24(unk0x24);
|
||||
}
|
||||
else {
|
||||
if (m_unk0x54.Find(p_action, FALSE)) {
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (MxStreamController::VTable0x20(p_action) == SUCCESS) {
|
||||
MxDSStreamingAction* action = (MxDSStreamingAction*) m_unk0x3c.Find(p_action, FALSE);
|
||||
MxDSStreamingAction streamingaction(*action);
|
||||
result = DeserializeObject(streamingaction);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c6320
|
||||
MxResult MxRAMStreamController::VTable0x24(MxDSAction* p_action)
|
||||
{
|
||||
MxDSAction action;
|
||||
do {
|
||||
if (m_action0x60 != NULL) {
|
||||
delete m_action0x60;
|
||||
m_action0x60 = NULL;
|
||||
}
|
||||
action = *p_action;
|
||||
MxStreamController::VTable0x24(&action);
|
||||
} while (m_action0x60 != NULL);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c63c0
|
||||
MxResult MxRAMStreamController::DeserializeObject(MxDSStreamingAction& p_action)
|
||||
{
|
||||
MxAutoLocker lock(&m_criticalSection);
|
||||
MxResult result;
|
||||
MxDSStreamingAction* value = NULL;
|
||||
|
||||
do {
|
||||
m_buffer.FUN_100c6f80(p_action.GetUnknown94());
|
||||
// Probably not MxResult, see below
|
||||
result = m_buffer.FUN_100c67b0(this, &p_action, &value);
|
||||
} while (m_unk0x3c.Find(&p_action, FALSE) != NULL);
|
||||
|
||||
return result == SUCCESS ? SUCCESS : FAILURE;
|
||||
}
|
||||
|
||||
// STUB: LEGO1 0x100d0d80
|
||||
undefined* __cdecl ReadData(MxU32* p_fileSizeBuffer, MxU32 p_fileSize)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
98
LEGO1/omni/src/stream/mxramstreamprovider.cpp
Normal file
98
LEGO1/omni/src/stream/mxramstreamprovider.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
#include "mxramstreamprovider.h"
|
||||
|
||||
#include "decomp.h"
|
||||
#include "mxomni.h"
|
||||
#include "mxstreamcontroller.h"
|
||||
|
||||
DECOMP_SIZE_ASSERT(MxRAMStreamProvider, 0x24);
|
||||
|
||||
// FUNCTION: LEGO1 0x100d0730
|
||||
MxRAMStreamProvider::MxRAMStreamProvider()
|
||||
{
|
||||
m_bufferSize = 0;
|
||||
m_fileSize = 0;
|
||||
m_pBufferOfFileSize = NULL;
|
||||
m_lengthInDWords = 0;
|
||||
m_bufferForDWords = NULL;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100d0930
|
||||
MxU32 MxRAMStreamProvider::GetFileSize()
|
||||
{
|
||||
return m_fileSize;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100d0940
|
||||
MxS32 MxRAMStreamProvider::GetStreamBuffersNum()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100d0950
|
||||
MxU32 MxRAMStreamProvider::GetLengthInDWords()
|
||||
{
|
||||
return m_lengthInDWords;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100d0960
|
||||
MxU32* MxRAMStreamProvider::GetBufferForDWords()
|
||||
{
|
||||
return m_bufferForDWords;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100d0a50
|
||||
MxRAMStreamProvider::~MxRAMStreamProvider()
|
||||
{
|
||||
m_bufferSize = 0;
|
||||
m_fileSize = 0;
|
||||
|
||||
free(m_pBufferOfFileSize);
|
||||
m_pBufferOfFileSize = NULL;
|
||||
|
||||
m_lengthInDWords = 0;
|
||||
|
||||
free(m_bufferForDWords);
|
||||
m_bufferForDWords = NULL;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100d0ae0
|
||||
MxResult MxRAMStreamProvider::SetResourceToGet(MxStreamController* p_resource)
|
||||
{
|
||||
MxResult result = FAILURE;
|
||||
MxString path;
|
||||
m_pLookup = p_resource;
|
||||
|
||||
path = (MxString(MxOmni::GetHD()) + p_resource->GetAtom().GetInternal() + ".si");
|
||||
|
||||
m_pFile = new MxDSFile(path.GetData(), 0);
|
||||
if (m_pFile != NULL) {
|
||||
if (m_pFile->Open(0) != 0) {
|
||||
path = MxString(MxOmni::GetCD()) + p_resource->GetAtom().GetInternal() + ".si";
|
||||
m_pFile->SetFileName(path.GetData());
|
||||
|
||||
if (m_pFile->Open(0) != 0)
|
||||
goto done;
|
||||
}
|
||||
|
||||
m_fileSize = m_pFile->CalcFileSize();
|
||||
if (m_fileSize != 0) {
|
||||
m_bufferSize = m_pFile->GetBufferSize();
|
||||
m_pBufferOfFileSize = (MxU32*) new MxU8[m_fileSize];
|
||||
if (m_pBufferOfFileSize != NULL &&
|
||||
m_pFile->Read((unsigned char*) m_pBufferOfFileSize, m_fileSize) == SUCCESS) {
|
||||
m_lengthInDWords = m_pFile->GetLengthInDWords();
|
||||
m_bufferForDWords = new MxU32[m_lengthInDWords];
|
||||
|
||||
if (m_bufferForDWords != NULL) {
|
||||
memcpy(m_bufferForDWords, m_pFile->GetBuffer(), m_lengthInDWords * sizeof(MxU32));
|
||||
result = SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
delete m_pFile;
|
||||
m_pFile = NULL;
|
||||
return result;
|
||||
}
|
||||
99
LEGO1/omni/src/stream/mxstreamchunk.cpp
Normal file
99
LEGO1/omni/src/stream/mxstreamchunk.cpp
Normal file
@@ -0,0 +1,99 @@
|
||||
#include "mxstreamchunk.h"
|
||||
|
||||
#include "legoutil.h"
|
||||
#include "mxdsbuffer.h"
|
||||
#include "mxstreamlist.h"
|
||||
|
||||
// FUNCTION: LEGO1 0x100c2fe0
|
||||
MxStreamChunk::~MxStreamChunk()
|
||||
{
|
||||
if (m_buffer) {
|
||||
m_buffer->ReleaseRef(this);
|
||||
}
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c3050
|
||||
MxResult MxStreamChunk::ReadChunk(MxDSBuffer* p_buffer, MxU8* p_chunkData)
|
||||
{
|
||||
MxResult result = FAILURE;
|
||||
|
||||
if (p_chunkData != NULL && *(MxU32*) p_chunkData == FOURCC('M', 'x', 'C', 'h')) {
|
||||
if (ReadChunkHeader(p_chunkData + 8)) {
|
||||
if (p_buffer) {
|
||||
SetBuffer(p_buffer);
|
||||
p_buffer->AddRef(this);
|
||||
}
|
||||
result = SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c30a0
|
||||
MxU32 MxStreamChunk::ReadChunkHeader(MxU8* p_chunkData)
|
||||
{
|
||||
MxU32 headersize = 0;
|
||||
if (p_chunkData) {
|
||||
MxU8* chunkData = p_chunkData;
|
||||
// Note: the alpha debug version uses memcpy calls here,
|
||||
// but the code generation is the same.
|
||||
GetScalar(&p_chunkData, m_flags);
|
||||
GetScalar(&p_chunkData, m_objectId);
|
||||
GetScalar(&p_chunkData, m_time);
|
||||
GetScalar(&p_chunkData, m_length);
|
||||
m_data = p_chunkData;
|
||||
headersize = p_chunkData - chunkData;
|
||||
}
|
||||
|
||||
return headersize;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c30e0
|
||||
MxResult MxStreamChunk::SendChunk(MxStreamListMxDSSubscriber& p_subscriberList, MxBool p_append, MxS16 p_obj24val)
|
||||
{
|
||||
for (MxStreamListMxDSSubscriber::iterator it = p_subscriberList.begin(); it != p_subscriberList.end(); it++) {
|
||||
if ((*it)->GetObjectId() == m_objectId && (*it)->GetUnknown48() == p_obj24val) {
|
||||
if (m_flags & MxDSChunk::Flag_End && m_buffer) {
|
||||
m_buffer->ReleaseRef(this);
|
||||
m_buffer = NULL;
|
||||
}
|
||||
|
||||
(*it)->AddChunk(this, p_append);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c3170
|
||||
void MxStreamChunk::SetBuffer(MxDSBuffer* p_buffer)
|
||||
{
|
||||
m_buffer = p_buffer;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c3180
|
||||
MxU16* MxStreamChunk::IntoFlags(MxU8* p_buffer)
|
||||
{
|
||||
return (MxU16*) (p_buffer + 0x08);
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c3190
|
||||
MxU32* MxStreamChunk::IntoObjectId(MxU8* p_buffer)
|
||||
{
|
||||
return (MxU32*) (p_buffer + 0x0a);
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c31a0
|
||||
MxLong* MxStreamChunk::IntoTime(MxU8* p_buffer)
|
||||
{
|
||||
return (MxLong*) (p_buffer + 0x0e);
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c31b0
|
||||
MxU32* MxStreamChunk::IntoLength(MxU8* p_buffer)
|
||||
{
|
||||
return (MxU32*) (p_buffer + 0x12);
|
||||
}
|
||||
318
LEGO1/omni/src/stream/mxstreamcontroller.cpp
Normal file
318
LEGO1/omni/src/stream/mxstreamcontroller.cpp
Normal file
@@ -0,0 +1,318 @@
|
||||
#include "mxstreamcontroller.h"
|
||||
|
||||
#include "legoomni.h"
|
||||
#include "legoutil.h"
|
||||
#include "mxautolocker.h"
|
||||
#include "mxdsmultiaction.h"
|
||||
#include "mxdsstreamingaction.h"
|
||||
#include "mxnextactiondatastart.h"
|
||||
#include "mxstl/stlcompat.h"
|
||||
#include "mxstreamchunk.h"
|
||||
#include "mxtimer.h"
|
||||
|
||||
DECOMP_SIZE_ASSERT(MxStreamController, 0x64)
|
||||
DECOMP_SIZE_ASSERT(MxNextActionDataStart, 0x14)
|
||||
|
||||
// FUNCTION: LEGO1 0x100b9400
|
||||
MxResult MxStreamController::VTable0x18(undefined4, undefined4)
|
||||
{
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100b9410
|
||||
MxResult MxStreamController::VTable0x1c(undefined4, undefined4)
|
||||
{
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100b9420
|
||||
MxDSStreamingAction* MxStreamController::VTable0x28()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c0b90
|
||||
MxStreamController::MxStreamController()
|
||||
{
|
||||
m_provider = NULL;
|
||||
m_unk0x2c = NULL;
|
||||
m_action0x60 = NULL;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c1290
|
||||
MxStreamController::~MxStreamController()
|
||||
{
|
||||
MxAutoLocker lock(&m_criticalSection);
|
||||
|
||||
MxDSSubscriber* subscriber;
|
||||
while (m_subscriberList.PopFront(subscriber))
|
||||
delete subscriber;
|
||||
|
||||
MxDSAction* action;
|
||||
while (m_unk0x3c.PopFront(action))
|
||||
delete action;
|
||||
|
||||
if (m_provider) {
|
||||
MxStreamProvider* provider = m_provider;
|
||||
m_provider = NULL;
|
||||
#ifdef COMPAT_MODE
|
||||
{
|
||||
MxDSAction action;
|
||||
provider->VTable0x20(&action);
|
||||
}
|
||||
#else
|
||||
provider->VTable0x20(&MxDSAction());
|
||||
#endif
|
||||
delete provider;
|
||||
}
|
||||
|
||||
if (m_unk0x2c) {
|
||||
delete m_unk0x2c;
|
||||
m_unk0x2c = NULL;
|
||||
}
|
||||
|
||||
while (m_unk0x54.PopFront(action))
|
||||
delete action;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c1520
|
||||
MxResult MxStreamController::Open(const char* p_filename)
|
||||
{
|
||||
char sourceName[256];
|
||||
MxAutoLocker lock(&m_criticalSection);
|
||||
|
||||
MakeSourceName(sourceName, p_filename);
|
||||
this->m_atom = MxAtomId(sourceName, LookupMode_LowerCase2);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c15d0
|
||||
void MxStreamController::AddSubscriber(MxDSSubscriber* p_subscriber)
|
||||
{
|
||||
m_subscriberList.push_back(p_subscriber);
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c1620
|
||||
void MxStreamController::RemoveSubscriber(MxDSSubscriber* p_subscriber)
|
||||
{
|
||||
m_subscriberList.remove(p_subscriber);
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c1690
|
||||
MxResult MxStreamController::VTable0x20(MxDSAction* p_action)
|
||||
{
|
||||
MxAutoLocker lock(&m_criticalSection);
|
||||
|
||||
MxResult result;
|
||||
MxU32 offset = 0;
|
||||
|
||||
MxS32 objectId = p_action->GetObjectId();
|
||||
MxStreamProvider* provider = m_provider;
|
||||
|
||||
if ((MxS32) provider->GetLengthInDWords() > objectId)
|
||||
offset = provider->GetBufferForDWords()[objectId];
|
||||
|
||||
if (offset)
|
||||
result = VTable0x2c(p_action, offset);
|
||||
else
|
||||
result = FAILURE;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c1740
|
||||
MxResult MxStreamController::VTable0x24(MxDSAction* p_action)
|
||||
{
|
||||
MxAutoLocker lock(&m_criticalSection);
|
||||
VTable0x30(p_action);
|
||||
m_action0x60 = m_unk0x54.Find(p_action, TRUE);
|
||||
if (m_action0x60 == NULL) {
|
||||
return FAILURE;
|
||||
}
|
||||
else {
|
||||
p_action->SetUnknown24(m_action0x60->GetUnknown24());
|
||||
p_action->SetObjectId(m_action0x60->GetObjectId());
|
||||
return FUN_100c1f00(m_action0x60);
|
||||
}
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c1800
|
||||
MxResult MxStreamController::FUN_100c1800(MxDSAction* p_action, MxU32 p_val)
|
||||
{
|
||||
MxNextActionDataStart* dataActionStart =
|
||||
new MxNextActionDataStart(p_action->GetObjectId(), p_action->GetUnknown24(), p_val);
|
||||
if (dataActionStart == NULL) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
m_nextActionList.push_back(dataActionStart);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c1a00
|
||||
MxResult MxStreamController::FUN_100c1a00(MxDSAction* p_action, MxU32 p_offset)
|
||||
{
|
||||
if (p_action->GetUnknown24() == -1) {
|
||||
MxS16 newUnknown24 = -1;
|
||||
|
||||
// These loops might be a template function in the list classes
|
||||
for (MxStreamListMxDSAction::iterator it = m_unk0x54.begin(); it != m_unk0x54.end(); it++) {
|
||||
MxDSAction* action = *it;
|
||||
|
||||
if (action->GetObjectId() == p_action->GetObjectId())
|
||||
newUnknown24 = Max(newUnknown24, action->GetUnknown24());
|
||||
}
|
||||
|
||||
if (newUnknown24 == -1) {
|
||||
for (MxStreamListMxDSAction::iterator it = m_unk0x3c.begin(); it != m_unk0x3c.end(); it++) {
|
||||
MxDSAction* action = *it;
|
||||
|
||||
if (action->GetObjectId() == p_action->GetObjectId())
|
||||
newUnknown24 = Max(newUnknown24, action->GetUnknown24());
|
||||
}
|
||||
|
||||
if (newUnknown24 == -1) {
|
||||
for (MxStreamListMxDSSubscriber::iterator it = m_subscriberList.begin(); it != m_subscriberList.end();
|
||||
it++) {
|
||||
MxDSSubscriber* subscriber = *it;
|
||||
|
||||
if (subscriber->GetObjectId() == p_action->GetObjectId())
|
||||
newUnknown24 = Max(newUnknown24, subscriber->GetUnknown48());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
p_action->SetUnknown24(newUnknown24 + 1);
|
||||
}
|
||||
else {
|
||||
if (m_unk0x3c.Find(p_action, FALSE))
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
MxDSStreamingAction* streamingAction = new MxDSStreamingAction(*p_action, p_offset);
|
||||
|
||||
if (!streamingAction)
|
||||
return FAILURE;
|
||||
|
||||
MxU32 fileSize = m_provider->GetFileSize();
|
||||
streamingAction->SetBufferOffset(fileSize * (p_offset / fileSize));
|
||||
streamingAction->SetObjectId(p_action->GetObjectId());
|
||||
|
||||
MxLong time = Timer()->GetTime();
|
||||
streamingAction->SetUnknown90(time);
|
||||
|
||||
m_unk0x3c.push_back(streamingAction);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c1c10
|
||||
MxResult MxStreamController::VTable0x2c(MxDSAction* p_action, MxU32 p_bufferval)
|
||||
{
|
||||
MxAutoLocker lock(&m_criticalSection);
|
||||
if (FUN_100c1a00(p_action, p_bufferval) != SUCCESS) {
|
||||
return FAILURE;
|
||||
}
|
||||
return FUN_100c1800(p_action, (p_bufferval / m_provider->GetFileSize()) * m_provider->GetFileSize());
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c1ce0
|
||||
MxResult MxStreamController::VTable0x30(MxDSAction* p_action)
|
||||
{
|
||||
MxAutoLocker lock(&m_criticalSection);
|
||||
MxResult result = FAILURE;
|
||||
MxDSAction* action = m_unk0x3c.Find(p_action, TRUE);
|
||||
if (action != NULL) {
|
||||
MxNextActionDataStart* data = m_nextActionList.FindAndErase(action->GetObjectId(), action->GetUnknown24());
|
||||
delete action;
|
||||
delete data;
|
||||
result = SUCCESS;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c1da0
|
||||
MxResult MxStreamController::InsertActionToList54(MxDSAction* p_action)
|
||||
{
|
||||
MxAutoLocker lock(&m_criticalSection);
|
||||
MxDSAction* action = p_action->Clone();
|
||||
|
||||
if (action == NULL) {
|
||||
return FAILURE;
|
||||
}
|
||||
else {
|
||||
m_unk0x54.push_back(action);
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c1e70
|
||||
MxPresenter* MxStreamController::FUN_100c1e70(MxDSAction& p_action)
|
||||
{
|
||||
MxAutoLocker lock(&m_criticalSection);
|
||||
MxPresenter* result = NULL;
|
||||
if (p_action.GetObjectId() != -1) {
|
||||
MxDSAction* action = m_unk0x3c.Find(&p_action, FALSE);
|
||||
if (action != NULL) {
|
||||
result = action->GetUnknown28();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c1f00
|
||||
MxResult MxStreamController::FUN_100c1f00(MxDSAction* p_action)
|
||||
{
|
||||
MxAutoLocker lock(&m_criticalSection);
|
||||
|
||||
MxU32 objectId = p_action->GetObjectId();
|
||||
MxStreamChunk* chunk = new MxStreamChunk;
|
||||
|
||||
if (!chunk)
|
||||
return FAILURE;
|
||||
|
||||
chunk->SetFlags(MxDSChunk::Flag_Bit3);
|
||||
chunk->SetObjectId(objectId);
|
||||
|
||||
if (chunk->SendChunk(m_subscriberList, FALSE, p_action->GetUnknown24()) != SUCCESS)
|
||||
delete chunk;
|
||||
|
||||
if (p_action->IsA("MxDSMultiAction")) {
|
||||
MxDSActionList* actions = ((MxDSMultiAction*) p_action)->GetActionList();
|
||||
MxDSActionListCursor cursor(actions);
|
||||
MxDSAction* action;
|
||||
|
||||
while (cursor.Next(action)) {
|
||||
if (FUN_100c1f00(action) != SUCCESS)
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c20b0
|
||||
MxNextActionDataStart* MxStreamController::FindNextActionDataStartFromStreamingAction(MxDSStreamingAction* p_action)
|
||||
{
|
||||
return m_nextActionList.Find(p_action->GetObjectId(), p_action->GetUnknown24());
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c20d0
|
||||
MxBool MxStreamController::FUN_100c20d0(MxDSObject& p_obj)
|
||||
{
|
||||
if (m_subscriberList.Find(&p_obj))
|
||||
return FALSE;
|
||||
|
||||
if (p_obj.IsA("MxDSMultiAction")) {
|
||||
MxDSActionList* actions = ((MxDSMultiAction&) p_obj).GetActionList();
|
||||
MxDSActionListCursor cursor(actions);
|
||||
MxDSAction* action;
|
||||
|
||||
while (cursor.Next(action)) {
|
||||
if (!FUN_100c20d0(*action))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
209
LEGO1/omni/src/stream/mxstreamer.cpp
Normal file
209
LEGO1/omni/src/stream/mxstreamer.cpp
Normal file
@@ -0,0 +1,209 @@
|
||||
#include "mxstreamer.h"
|
||||
|
||||
#include "legoomni.h"
|
||||
#include "mxdiskstreamcontroller.h"
|
||||
#include "mxnotificationmanager.h"
|
||||
#include "mxramstreamcontroller.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
DECOMP_SIZE_ASSERT(MxStreamer, 0x2c);
|
||||
|
||||
// FUNCTION: LEGO1 0x100b8f00
|
||||
MxStreamer::MxStreamer()
|
||||
{
|
||||
NotificationManager()->Register(this);
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100b9190
|
||||
MxResult MxStreamer::Create()
|
||||
{
|
||||
undefined* b = new undefined[m_subclass1.GetSize() * 0x5800];
|
||||
m_subclass1.SetBuffer(b);
|
||||
if (b) {
|
||||
b = new undefined[m_subclass2.GetSize() * 0x800];
|
||||
m_subclass2.SetBuffer(b);
|
||||
if (b) {
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100b91d0
|
||||
MxStreamer::~MxStreamer()
|
||||
{
|
||||
while (!m_openStreams.empty()) {
|
||||
MxStreamController* c = m_openStreams.front();
|
||||
m_openStreams.pop_front();
|
||||
delete c;
|
||||
}
|
||||
|
||||
NotificationManager()->Unregister(this);
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100b92c0
|
||||
MxStreamController* MxStreamer::Open(const char* p_name, MxU16 p_lookupType)
|
||||
{
|
||||
MxStreamController* stream = NULL;
|
||||
|
||||
if (!GetOpenStream(p_name)) {
|
||||
switch (p_lookupType) {
|
||||
case e_DiskStream:
|
||||
stream = new MxDiskStreamController();
|
||||
break;
|
||||
case e_RAMStream:
|
||||
stream = new MxRAMStreamController();
|
||||
break;
|
||||
}
|
||||
|
||||
if (stream && (stream->Open(p_name) != SUCCESS || AddStreamControllerToOpenList(stream) != SUCCESS)) {
|
||||
delete stream;
|
||||
stream = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100b9570
|
||||
MxLong MxStreamer::Close(const char* p_name)
|
||||
{
|
||||
MxDSAction ds;
|
||||
ds.SetUnknown24(-2);
|
||||
|
||||
for (list<MxStreamController*>::iterator it = m_openStreams.begin(); it != m_openStreams.end(); it++) {
|
||||
MxStreamController* c = *it;
|
||||
|
||||
if (!p_name || !strcmp(p_name, c->GetAtom().GetInternal())) {
|
||||
m_openStreams.erase(it);
|
||||
|
||||
if (c->FUN_100c20d0(ds))
|
||||
delete c;
|
||||
else {
|
||||
#ifdef COMPAT_MODE
|
||||
{
|
||||
MxStreamerNotification notification(MXSTREAMER_DELETE_NOTIFY, NULL, c);
|
||||
NotificationManager()->Send(this, ¬ification);
|
||||
}
|
||||
#else
|
||||
NotificationManager()->Send(this, &MxStreamerNotification(MXSTREAMER_DELETE_NOTIFY, NULL, c));
|
||||
#endif
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100b9700
|
||||
MxNotificationParam* MxStreamerNotification::Clone()
|
||||
{
|
||||
return new MxStreamerNotification(m_type, m_sender, m_controller);
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100b9870
|
||||
MxStreamController* MxStreamer::GetOpenStream(const char* p_name)
|
||||
{
|
||||
for (list<MxStreamController*>::iterator it = m_openStreams.begin(); it != m_openStreams.end(); it++) {
|
||||
MxStreamController* c = *it;
|
||||
MxAtomId& atom = c->GetAtom();
|
||||
if (p_name) {
|
||||
if (!strcmp(atom.GetInternal(), p_name)) {
|
||||
return *it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100b9930
|
||||
MxResult MxStreamer::AddStreamControllerToOpenList(MxStreamController* p_stream)
|
||||
{
|
||||
if (find(m_openStreams.begin(), m_openStreams.end(), p_stream) == m_openStreams.end()) {
|
||||
m_openStreams.push_back(p_stream);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100b99b0
|
||||
MxResult MxStreamer::FUN_100b99b0(MxDSAction* p_action)
|
||||
{
|
||||
MxStreamController* controller;
|
||||
if (p_action != NULL && p_action->GetAtomId().GetInternal() != NULL && p_action->GetObjectId() != -1) {
|
||||
controller = GetOpenStream(p_action->GetAtomId().GetInternal());
|
||||
if (controller == NULL) {
|
||||
return FAILURE;
|
||||
}
|
||||
return controller->VTable0x20(p_action);
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100b99f0
|
||||
MxResult MxStreamer::DeleteObject(MxDSAction* p_dsAction)
|
||||
{
|
||||
MxDSAction tempAction;
|
||||
|
||||
if (p_dsAction == NULL) {
|
||||
tempAction.SetUnknown24(-2);
|
||||
}
|
||||
else {
|
||||
tempAction.SetObjectId(p_dsAction->GetObjectId());
|
||||
tempAction.SetAtomId(p_dsAction->GetAtomId());
|
||||
tempAction.SetUnknown24(p_dsAction->GetUnknown24());
|
||||
}
|
||||
|
||||
MxResult result = FAILURE;
|
||||
for (list<MxStreamController*>::iterator it = m_openStreams.begin(); it != m_openStreams.end(); it++) {
|
||||
const char* id = p_dsAction->GetAtomId().GetInternal();
|
||||
if (!id || id == (*it)->GetAtom().GetInternal()) {
|
||||
tempAction.SetAtomId((*it)->GetAtom());
|
||||
result = (*it)->VTable0x24(&tempAction);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100b9b30
|
||||
MxBool MxStreamer::FUN_100b9b30(MxDSObject& p_dsObject)
|
||||
{
|
||||
MxStreamController* controller = GetOpenStream(p_dsObject.GetAtomId().GetInternal());
|
||||
if (controller)
|
||||
return controller->FUN_100c20d0(p_dsObject);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100b9b60
|
||||
MxLong MxStreamer::Notify(MxParam& p_param)
|
||||
{
|
||||
if (((MxNotificationParam&) p_param).GetNotification() == MXSTREAMER_DELETE_NOTIFY) {
|
||||
MxDSAction ds;
|
||||
|
||||
ds.SetUnknown24(-2);
|
||||
|
||||
MxStreamController* c = static_cast<MxStreamerNotification&>(p_param).GetController();
|
||||
|
||||
if (c->FUN_100c20d0(ds))
|
||||
delete c;
|
||||
else {
|
||||
#ifdef COMPAT_MODE
|
||||
{
|
||||
MxStreamerNotification notification(MXSTREAMER_DELETE_NOTIFY, NULL, c);
|
||||
NotificationManager()->Send(this, ¬ification);
|
||||
}
|
||||
#else
|
||||
NotificationManager()->Send(this, &MxStreamerNotification(MXSTREAMER_DELETE_NOTIFY, NULL, c));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
77
LEGO1/omni/src/stream/mxstreamlist.cpp
Normal file
77
LEGO1/omni/src/stream/mxstreamlist.cpp
Normal file
@@ -0,0 +1,77 @@
|
||||
#include "mxstreamlist.h"
|
||||
|
||||
// Wrappers around STL list that are used by the MxStream* classes.
|
||||
DECOMP_SIZE_ASSERT(MxStreamListMxDSAction, 0xc);
|
||||
DECOMP_SIZE_ASSERT(MxStreamListMxNextActionDataStart, 0xc);
|
||||
DECOMP_SIZE_ASSERT(MxStreamListMxDSSubscriber, 0xc);
|
||||
|
||||
// FUNCTION: LEGO1 0x100b8450
|
||||
MxDSSubscriber* MxStreamListMxDSSubscriber::Find(MxDSObject* p_object)
|
||||
{
|
||||
for (iterator it = begin(); it != end(); it++) {
|
||||
if (p_object->GetObjectId() == -1 || p_object->GetObjectId() == (*it)->GetObjectId()) {
|
||||
if (p_object->GetUnknown24() == -2 || p_object->GetUnknown24() == (*it)->GetUnknown48()) {
|
||||
return *it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100bfa80
|
||||
MxDSAction* MxStreamListMxDSAction::Find(MxDSAction* p_action, MxBool p_delete)
|
||||
{
|
||||
// DECOMP ALPHA 0x1008b99d ?
|
||||
|
||||
MxDSAction* found = NULL;
|
||||
|
||||
#ifdef COMPAT_MODE
|
||||
iterator it;
|
||||
for (it = begin(); it != end(); it++) {
|
||||
#else
|
||||
for (iterator it = begin(); it != end(); it++) {
|
||||
#endif
|
||||
if (p_action->GetObjectId() == -1 || p_action->GetObjectId() == (*it)->GetObjectId()) {
|
||||
if (p_action->GetUnknown24() == -2 || p_action->GetUnknown24() == -3 ||
|
||||
p_action->GetUnknown24() == (*it)->GetUnknown24()) {
|
||||
found = *it;
|
||||
if (p_action->GetUnknown24() != -3)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (p_delete && found != NULL) {
|
||||
erase(it);
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c21e0
|
||||
MxNextActionDataStart* MxStreamListMxNextActionDataStart::Find(MxU32 p_id, MxS16 p_value)
|
||||
{
|
||||
for (iterator it = begin(); it != end(); it++) {
|
||||
if (p_id == (*it)->GetObjectId() && p_value == (*it)->GetUnknown24())
|
||||
return *it;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100c2240
|
||||
MxNextActionDataStart* MxStreamListMxNextActionDataStart::FindAndErase(MxU32 p_id, MxS16 p_value)
|
||||
{
|
||||
MxNextActionDataStart* match = NULL;
|
||||
|
||||
for (iterator it = begin(); it != end(); it++) {
|
||||
if (p_id == (*it)->GetObjectId() && (p_value == -2 || p_value == (*it)->GetUnknown24())) {
|
||||
match = *it;
|
||||
erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return match;
|
||||
}
|
||||
17
LEGO1/omni/src/stream/mxstreamprovider.cpp
Normal file
17
LEGO1/omni/src/stream/mxstreamprovider.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#include "mxstreamprovider.h"
|
||||
|
||||
#include "decomp.h"
|
||||
|
||||
DECOMP_SIZE_ASSERT(MxStreamProvider, 0x10);
|
||||
|
||||
// FUNCTION: LEGO1 0x100d07c0
|
||||
MxResult MxStreamProvider::SetResourceToGet(MxStreamController* p_resource)
|
||||
{
|
||||
m_pLookup = p_resource;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100d07d0
|
||||
void MxStreamProvider::VTable0x20(MxDSAction* p_action)
|
||||
{
|
||||
}
|
||||
Reference in New Issue
Block a user