Improve documentation, add more unknowns

This commit is contained in:
Florian Kaiser 2025-05-04 21:49:08 +02:00
parent 1baaad3da0
commit a36a6cafa4
12 changed files with 129 additions and 57 deletions

View File

@ -43,6 +43,14 @@ Holds a list of MxTickleClient*. Goes though the on Tickle() and calls Tickle()
### MxTickleClient
Holds a MxCore*, Interval, LastUpdateTime and Flags (only used for TICKLE_MANAGER_FLAG_DESTROY?).
### IsleApp
Main class and the entry point of the game.
### MxOmni
#### Start(MxDSAction*)
### MxDSObject : MxCore
Base Object for extracted objects from SI files.
@ -162,6 +170,70 @@ Removes actor from current controller, does through all boundaries, goes through
### LegoPathActor : LegoActor
### MxStreamer : MxCore
MxMisc holds a MxStreamer singleton. Also holds a list of MxStreamController.
#### Open(const char*, MxU16 p_lookupType)
Creates and calls Open() on a MxDiskStreamController or MxRAMStreamController depending on lookupType if not already exists.
### MxDSSubscriber : MxCore
#### Create(MxStreamController* p_controller, MxU32 p_objectId, MxS16 p_unk0x48)
Calls MxStreamController::AddSubscriber() and sets some properties on itself.
### MxStreamController : MxCore
Holds a list of subscriber.
#### AddSubscriber(MxDSSubscriber*)
Puts it into the subscriber list.
#### Open(const char* p_filename)
Removes "<letter>:" and ".SI" from filename and stores it in m_atom.
### MxRAMStreamController : MxStreamController
Holds an MxDSBuffer.
### MxDSBuffer : MxCore
### MxStreamProvider : MxCore
Abstract base class. Holds an MxDSFile.
### MxRAMStreamProvider : MxStreamProvider
#### SetResourceToGet(MxStreamController*)
Gets the stream controllers Atom, adds ".SI". Tries to load it first from HDD and then from disk. Sets BufferSize to MxDSFile.BufferSize. Then reads the entire file into m_pContentsOfFile.
#### MxU32 ReadData(MxU8* p_buffer, MxU32 p_size)
Return total size of MxOb. Rearranged p_buffer so that split chunks are merged.
### MxDSStreamingAction : MxDSAction
Mostly unknown.
### MxDiskStreamProvider : MxStreamProvider
Holds a list of MxDSStreamingAction.
#### SetResourceToGet(MxStreamController*)
Gets the stream controllers Atom, adds ".SI". Tries to load it first from HDD and then from disk. Then starts a MxDiskStreamProviderThread with target this.
#### MxDiskStreamProvider::WaitForWorkToComplete()
Called by the thread. Run indefinitely until object is destroyed. Streams data, code mostly unknown.
### MxThread
Abstract base class for threads. Starts and manages one. Has abstract Run() method.
### MxDiskStreamProviderThread : MxThread
Calls MxDiskStreamProvider::WaitForWorkToComplete.
### MxDSChunk : MxCore
Holds Flags, ObjectId, Time, Data (U8*) and Length. Also some static utility functions.
### MxDSSource : MxCore
Holds a buffer, length and position and offers abstract function to read and write.
### MxDSFile : MxDSSource
Presumably this represents an SI file. Holds a MXIOINFO and on Open() opens m_filename and starts reading the starting chunks ("OMNI" etc.) also checks SI version (2.2). Then it reads the length of the MxOf chunk and puts it into m_pBuffer from parent class.
Also holds the header chunk as ChunkHeader. GetBufferSize() returns the buffer size from the header.
### LegoEdge
Has FaceA (LegoWEEdge*), FaceB (LegoWEEdge*), PointA (Vector3), PointB (Vector3). Also utility functions like CWVertex (LegoWEEdge&), CCWVertex (LegoWEEdge&), GetClockwiseEdge(LegoWEEdge&) and GetCounterclockwiseEdge(LegoWEEdge&).
@ -176,7 +248,7 @@ Has Edges (LegoUnknown100db7f4*)
Adds EdgeNormal, Flags and other lots of other stuff.
### LegoPathBoundary : LegoWEGEdge
Has actors and presenters.
Adds actors and presenters.
### LegoNamedPlane
Has Name (char*), Position, Direction and Up. Can be serialized.

View File

@ -84,7 +84,7 @@ class LegoBuildingManager : public MxCore {
MxBool FUN_10030110(LegoBuildingInfo* p_data);
void ScheduleAnimation(LegoEntity* p_entity, MxLong p_length, MxBool p_haveSound, MxBool p_unk0x28);
void FUN_10030590();
void AdjustHeight(MxS32 p_index);
void AdjustY(MxS32 p_index);
MxResult FUN_10030630();
LegoBuildingInfo* GetInfoArray(MxS32& p_length);
void FUN_100307b0(LegoEntity* p_entity, MxS32 p_adjust);

View File

@ -299,7 +299,7 @@ void LegoBuildingManager::CreateBuilding(MxS32 p_index, LegoWorld* p_world)
entity->SetType(LegoEntity::e_building);
g_buildingInfo[p_index].m_entity = entity;
LegoROI* roi = entity->GetROI();
AdjustHeight(p_index);
AdjustY(p_index);
MxMatrix mat = roi->GetLocal2World();
mat[3][1] = g_buildingInfo[p_index].m_downshiftScale;
roi->UpdateTransformationRelativeToParent(mat);
@ -381,7 +381,7 @@ MxResult LegoBuildingManager::Read(LegoStorage* p_storage)
}
info->m_initialUnk0x11 = info->m_Downshift;
AdjustHeight(i);
AdjustY(i);
}
if (p_storage->Read(&m_nextVariant, sizeof(m_nextVariant)) != SUCCESS) {
@ -400,7 +400,7 @@ MxResult LegoBuildingManager::Read(LegoStorage* p_storage)
// FUNCTION: LEGO1 0x1002fcc0
// FUNCTION: BETA10 0x10063f1a
void LegoBuildingManager::AdjustHeight(MxS32 p_index)
void LegoBuildingManager::AdjustY(MxS32 p_index)
{
if (g_buildingInfo[p_index].m_Downshift > 0) {
float value = g_buildingInfoDownshift[p_index] - g_buildingInfo[p_index].m_Downshift;
@ -637,7 +637,7 @@ MxBool LegoBuildingManager::FUN_10030030(MxS32 p_index)
roi->SetVisibility(FALSE);
}
else {
AdjustHeight(p_index);
AdjustY(p_index);
MxMatrix mat = roi->GetLocal2World();
mat[3][1] = g_buildingInfo[p_index].m_downshiftScale;
roi->UpdateTransformationRelativeToParent(mat);
@ -743,7 +743,7 @@ MxResult LegoBuildingManager::Tickle()
if (info->m_Downshift && !m_unk0x28) {
MxS32 index = info - g_buildingInfo;
AdjustHeight(index);
AdjustY(index);
MxMatrix mat = entry->m_roi->GetLocal2World();
mat[3][1] = g_buildingInfo[index].m_downshiftScale;
entry->m_roi->UpdateTransformationRelativeToParent(mat);
@ -779,7 +779,7 @@ void LegoBuildingManager::FUN_10030590()
for (MxS32 i = 0; i < sizeOfArray(g_buildingInfo); i++) {
g_buildingInfo[i].m_Downshift = -1;
g_buildingInfo[i].m_initialUnk0x11 = -1;
AdjustHeight(i);
AdjustY(i);
if (g_buildingInfo[i].m_entity != NULL) {
LegoROI* roi = g_buildingInfo[i].m_entity->GetROI();

View File

@ -50,7 +50,7 @@ class MxDiskStreamController : public MxStreamController {
void FUN_100c7f40(MxDSStreamingAction* p_streamingaction);
void FUN_100c8120(MxDSAction* p_action);
void InsertToList74(MxDSBuffer* p_buffer);
void FUN_100c8670(MxDSStreamingAction* p_streamingAction);
void AddStreamingAction(MxDSStreamingAction* p_streamingAction);
private:
MxDSObjectList m_list0x64; // 0x64

View File

@ -31,12 +31,12 @@ class MxRAMStreamProvider : public MxStreamProvider {
MxU32 GetLengthInDWords() override; // vtable+0x24
MxU32* GetBufferForDWords() override; // vtable+0x28
MxU8* GetBufferOfFileSize() { return m_pBufferOfFileSize; }
MxU8* GetBufferOfFileSize() { return m_pContentsOfFile; }
protected:
MxU32 m_bufferSize; // 0x10
MxU32 m_fileSize; // 0x14
MxU8* m_pBufferOfFileSize; // 0x18
MxU8* m_pContentsOfFile; // 0x18
MxU32 m_lengthInDWords; // 0x1c
MxU32* m_bufferForDWords; // 0x20
};

View File

@ -73,7 +73,7 @@ class MxStreamController : public MxCore {
MxAtomId& GetAtom() { return m_atom; }
MxStreamProvider* GetProvider() { return m_provider; }
MxDSObjectList& GetUnk0x3c() { return m_unk0x3c; }
MxDSObjectList& GetUnk0x54() { return m_unk0x54; }
MxDSObjectList& GetUnk0x54() { return m_actionListUnknown; }
MxDSSubscriberList& GetSubscriberList() { return m_subscribers; }
protected:
@ -84,7 +84,7 @@ class MxStreamController : public MxCore {
MxDSSubscriberList m_subscribers; // 0x30
MxDSObjectList m_unk0x3c; // 0x3c
MxNextActionDataStartList m_nextActionList; // 0x48
MxDSObjectList m_unk0x54; // 0x54
MxDSObjectList m_actionListUnknown; // 0x54
MxDSAction* m_action0x60; // 0x60
};

View File

@ -345,7 +345,7 @@ void MxDiskStreamController::FUN_100c8120(MxDSAction* p_action)
}
while (TRUE) {
MxDSObject* found = m_unk0x54.FindAndErase(p_action);
MxDSObject* found = m_actionListUnknown.FindAndErase(p_action);
if (!found) {
break;
}
@ -357,7 +357,7 @@ void MxDiskStreamController::FUN_100c8120(MxDSAction* p_action)
MxResult MxDiskStreamController::VTable0x24(MxDSAction* p_action)
{
AUTOLOCK(m_criticalSection);
if (m_unk0x54.Find(p_action) == NULL) {
if (m_actionListUnknown.Find(p_action) == NULL) {
if (VTable0x30(p_action) == SUCCESS) {
MxOmni::GetInstance()->NotifyCurrentEntity(
MxEndActionNotificationParam(c_notificationEndAction, NULL, p_action, TRUE)
@ -470,7 +470,7 @@ MxResult MxDiskStreamController::Tickle()
}
// FUNCTION: LEGO1 0x100c8670
void MxDiskStreamController::FUN_100c8670(MxDSStreamingAction* p_streamingAction)
void MxDiskStreamController::AddStreamingAction(MxDSStreamingAction* p_streamingAction)
{
AUTOLOCK(m_critical9c);
m_list0xb8.push_back(p_streamingAction);

View File

@ -65,7 +65,7 @@ MxDiskStreamProvider::~MxDiskStreamProvider()
g_unk0x10102878--;
}
((MxDiskStreamController*) m_pLookup)->FUN_100c8670((MxDSStreamingAction*) action);
((MxDiskStreamController*) m_pLookup)->AddStreamingAction((MxDSStreamingAction*) action);
} while (action);
if (m_remainingWork) {
@ -137,7 +137,7 @@ void MxDiskStreamProvider::VTable0x20(MxDSAction* p_action)
g_unk0x10102878--;
}
((MxDiskStreamController*) m_pLookup)->FUN_100c8670((MxDSStreamingAction*) action);
((MxDiskStreamController*) m_pLookup)->AddStreamingAction((MxDSStreamingAction*) action);
} while (action);
}
else {
@ -155,7 +155,7 @@ void MxDiskStreamProvider::VTable0x20(MxDSAction* p_action)
g_unk0x10102878--;
}
((MxDiskStreamController*) m_pLookup)->FUN_100c8670((MxDSStreamingAction*) action);
((MxDiskStreamController*) m_pLookup)->AddStreamingAction((MxDSStreamingAction*) action);
} while (action);
}
}
@ -256,7 +256,7 @@ void MxDiskStreamProvider::PerformWork()
}
else {
if (m_pLookup == NULL || !((MxDiskStreamController*) m_pLookup)->GetUnk0xc4()) {
controller->FUN_100c8670(((MxDSStreamingAction*) streamingAction));
controller->AddStreamingAction(((MxDSStreamingAction*) streamingAction));
}
else {
controller->FUN_100c7f40(((MxDSStreamingAction*) streamingAction));
@ -269,7 +269,7 @@ void MxDiskStreamProvider::PerformWork()
done:
if (streamingAction) {
controller->FUN_100c8670(((MxDSStreamingAction*) streamingAction));
controller->AddStreamingAction(((MxDSStreamingAction*) streamingAction));
}
m_thread.Sleep(0);

View File

@ -38,19 +38,19 @@ MxResult MxRAMStreamController::Open(const char* p_filename)
MxResult MxRAMStreamController::VTable0x20(MxDSAction* p_action)
{
AUTOLOCK(m_criticalSection);
MxS32 unk0x24 = 0;
MxS32 flags = 0;
MxResult result = FAILURE;
if (p_action->GetFlags() == -1) {
p_action->SetFlags(-3);
MxDSObject* action = m_unk0x54.Find(p_action);
MxDSObject* action = m_actionListUnknown.Find(p_action);
if (action != NULL) {
unk0x24 = action->GetFlags() + 1;
flags = action->GetFlags() + 1;
}
p_action->SetFlags(unk0x24);
p_action->SetFlags(flags);
}
else {
if (m_unk0x54.Find(p_action)) {
if (m_actionListUnknown.Find(p_action)) {
return FAILURE;
}
}

View File

@ -14,7 +14,7 @@ MxRAMStreamProvider::MxRAMStreamProvider()
{
m_bufferSize = 0;
m_fileSize = 0;
m_pBufferOfFileSize = NULL;
m_pContentsOfFile = NULL;
m_lengthInDWords = 0;
m_bufferForDWords = NULL;
}
@ -49,8 +49,8 @@ MxRAMStreamProvider::~MxRAMStreamProvider()
m_bufferSize = 0;
m_fileSize = 0;
delete[] m_pBufferOfFileSize;
m_pBufferOfFileSize = NULL;
delete[] m_pContentsOfFile;
m_pContentsOfFile = NULL;
m_lengthInDWords = 0;
@ -81,9 +81,9 @@ MxResult MxRAMStreamProvider::SetResourceToGet(MxStreamController* p_resource)
m_fileSize = m_pFile->CalcFileSize();
if (m_fileSize != 0) {
m_bufferSize = m_pFile->GetBufferSize();
m_pBufferOfFileSize = new MxU8[m_fileSize];
if (m_pBufferOfFileSize != NULL &&
m_pFile->Read((unsigned char*) m_pBufferOfFileSize, m_fileSize) == SUCCESS) {
m_pContentsOfFile = new MxU8[m_fileSize];
if (m_pContentsOfFile != NULL &&
m_pFile->Read((unsigned char*) m_pContentsOfFile, m_fileSize) == SUCCESS) {
m_lengthInDWords = m_pFile->GetLengthInDWords();
m_bufferForDWords = new MxU32[m_lengthInDWords];
@ -107,43 +107,43 @@ MxU32 ReadData(MxU8* p_buffer, MxU32 p_size)
{
MxU32 id;
MxU8* data = p_buffer;
MxU8* data2;
MxU8* startOfChunk;
#define IntoType(p) ((MxU32*) (p))
while (data < p_buffer + p_size) {
if (*IntoType(data) == FOURCC('M', 'x', 'O', 'b')) {
data2 = data;
data = data2 + 8;
startOfChunk = data;
data = startOfChunk + 8;
MxDSObject* obj = DeserializeDSObjectDispatch(data, -1);
id = obj->GetObjectId();
delete obj;
data = MxDSChunk::End(data2);
data = MxDSChunk::End(startOfChunk);
while (data < p_buffer + p_size) {
if (*IntoType(data) == FOURCC('M', 'x', 'C', 'h')) {
MxU8* data3 = data;
data = MxDSChunk::End(data3);
MxU8* startOfSubChunk = data;
data = MxDSChunk::End(startOfSubChunk);
if ((*IntoType(data2) == FOURCC('M', 'x', 'C', 'h')) &&
(*MxStreamChunk::IntoFlags(data2) & DS_CHUNK_SPLIT)) {
if (*MxStreamChunk::IntoObjectId(data2) == *MxStreamChunk::IntoObjectId(data3) &&
(*MxStreamChunk::IntoFlags(data3) & DS_CHUNK_SPLIT) &&
*MxStreamChunk::IntoTime(data2) == *MxStreamChunk::IntoTime(data3)) {
MxDSBuffer::Append(data2, data3);
if ((*IntoType(startOfChunk) == FOURCC('M', 'x', 'C', 'h')) &&
(*MxStreamChunk::IntoFlags(startOfChunk) & DS_CHUNK_SPLIT)) {
if (*MxStreamChunk::IntoObjectId(startOfChunk) == *MxStreamChunk::IntoObjectId(startOfSubChunk) &&
(*MxStreamChunk::IntoFlags(startOfSubChunk) & DS_CHUNK_SPLIT) &&
*MxStreamChunk::IntoTime(startOfChunk) == *MxStreamChunk::IntoTime(startOfSubChunk)) {
MxDSBuffer::Append(startOfChunk, startOfSubChunk);
continue;
}
else {
*MxStreamChunk::IntoFlags(data2) &= ~DS_CHUNK_SPLIT;
*MxStreamChunk::IntoFlags(startOfChunk) &= ~DS_CHUNK_SPLIT;
}
}
data2 = MxDSChunk::End(data2);
memcpy(data2, data3, MxDSChunk::Size(data3));
startOfChunk = MxDSChunk::End(startOfChunk);
memcpy(startOfChunk, startOfSubChunk, MxDSChunk::Size(startOfSubChunk));
if (*MxStreamChunk::IntoObjectId(data2) == id &&
(*MxStreamChunk::IntoFlags(data2) & DS_CHUNK_END_OF_STREAM)) {
if (*MxStreamChunk::IntoObjectId(startOfChunk) == id &&
(*MxStreamChunk::IntoFlags(startOfChunk) & DS_CHUNK_END_OF_STREAM)) {
break;
}
}
@ -157,8 +157,8 @@ MxU32 ReadData(MxU8* p_buffer, MxU32 p_size)
}
}
*MxStreamChunk::IntoFlags(data2) &= ~DS_CHUNK_SPLIT;
return MxDSChunk::Size(data2) + (MxU32) (data2 - p_buffer);
*MxStreamChunk::IntoFlags(startOfChunk) &= ~DS_CHUNK_SPLIT;
return MxDSChunk::Size(startOfChunk) + (MxU32) (startOfChunk - p_buffer);
#undef IntoType
}

View File

@ -60,7 +60,7 @@ MxStreamController::~MxStreamController()
m_unk0x2c = NULL;
}
while (m_unk0x54.PopFront(action)) {
while (m_actionListUnknown.PopFront(action)) {
delete action;
}
}
@ -121,7 +121,7 @@ MxResult MxStreamController::VTable0x24(MxDSAction* p_action)
{
AUTOLOCK(m_criticalSection);
VTable0x30(p_action);
m_action0x60 = (MxDSAction*) m_unk0x54.FindAndErase(p_action);
m_action0x60 = (MxDSAction*) m_actionListUnknown.FindAndErase(p_action);
if (m_action0x60 == NULL) {
return FAILURE;
@ -155,7 +155,7 @@ MxResult MxStreamController::FUN_100c1a00(MxDSAction* p_action, MxU32 p_offset)
MxS16 newUnknown24 = -1;
// These loops might be a template function in the list classes
for (MxDSObjectList::iterator it = m_unk0x54.begin(); it != m_unk0x54.end(); it++) {
for (MxDSObjectList::iterator it = m_actionListUnknown.begin(); it != m_actionListUnknown.end(); it++) {
MxDSObject* action = *it;
if (action->GetObjectId() == p_action->GetObjectId()) {
@ -250,7 +250,7 @@ MxResult MxStreamController::InsertActionToList54(MxDSAction* p_action)
return FAILURE;
}
else {
m_unk0x54.PushBack(action);
m_actionListUnknown.PushBack(action);
return SUCCESS;
}
}

View File

@ -25,13 +25,13 @@ MxThread::~MxThread()
typedef unsigned(__stdcall* ThreadFunc)(void*);
// FUNCTION: LEGO1 0x100bf610
MxResult MxThread::Start(MxS32 p_stack, MxS32 p_flag)
MxResult MxThread::Start(MxS32 p_stackSize, MxS32 p_flag)
{
MxResult result = FAILURE;
if (m_semaphore.Init(0, 1) == SUCCESS) {
if ((m_hThread =
_beginthreadex(NULL, p_stack << 2, (ThreadFunc) &MxThread::ThreadProc, this, p_flag, &m_threadId))) {
_beginthreadex(NULL, p_stackSize << 2, (ThreadFunc) &MxThread::ThreadProc, this, p_flag, &m_threadId))) {
result = SUCCESS;
}
}