diff --git a/src/async/AsyncFileRead.cpp b/src/async/AsyncFileRead.cpp index 7022daf..a83b9ca 100644 --- a/src/async/AsyncFileRead.cpp +++ b/src/async/AsyncFileRead.cpp @@ -2,6 +2,7 @@ #include "util/SFile.hpp" #include #include +#include uint32_t AsyncFileRead::s_threadSleep; uint32_t AsyncFileRead::s_handlerTimeout = 100; @@ -25,6 +26,7 @@ TSList> AsyncFileRead::s_asyncQueueList; TSList> AsyncFileRead::s_asyncThreadList; STORM_EXPLICIT_LIST(CAsyncObject, link) AsyncFileRead::s_asyncFileReadPostList; STORM_EXPLICIT_LIST(CAsyncObject, link) AsyncFileRead::s_asyncFileReadFreeList; +int32_t AsyncFileRead::s_waiting; CAsyncQueue* AsyncFileReadCreateQueue() { CAsyncQueue* queue = AsyncFileRead::s_asyncQueueList.NewNode(0, 2, 0x8); @@ -194,3 +196,51 @@ uint32_t AsyncFileReadThread(void* param) { return 0; } + +void AsyncFileReadWait(CAsyncObject* object) { + STORM_ASSERT(object); + + AsyncFileRead::s_waiting++; + + AsyncFileRead::s_queueLock.Enter(); + + if (object->isProcessed) { + AsyncFileRead::s_queueLock.Leave(); + return; + } + + AsyncFileRead::s_asyncWaitObject = object; + + if (!object->isCurrent && !object->isRead) { + object->link.Unlink(); + object->queue->readList.LinkToHead(object); + } + + AsyncFileRead::s_queueLock.Leave(); + + if (SFile::IsStreamingMode()) { + // TODO + } + + // TODO + + if (AsyncFileRead::s_ingameStartCallback) { + // TODO AsyncFileRead::s_ingameStartCallback(); + } + + while (true) { + if (AsyncFileRead::s_ingameProgressCallback) { + // TODO AsyncFileRead::s_ingameProgressCallback(0.0, 0); + } + + AsyncFileReadPollHandler(nullptr, nullptr); + + if (!AsyncFileRead::s_asyncWaitObject) { + break; + } + + OsSleep(1); + } + + AsyncFileRead::s_waiting--; +} diff --git a/src/async/AsyncFileRead.hpp b/src/async/AsyncFileRead.hpp index 8ee147d..81f993c 100644 --- a/src/async/AsyncFileRead.hpp +++ b/src/async/AsyncFileRead.hpp @@ -31,6 +31,7 @@ class AsyncFileRead { static TSList> s_asyncThreadList; static STORM_EXPLICIT_LIST(CAsyncObject, link) s_asyncFileReadPostList; static STORM_EXPLICIT_LIST(CAsyncObject, link) s_asyncFileReadFreeList; + static int32_t s_waiting; }; CAsyncQueue* AsyncFileReadCreateQueue(); @@ -43,4 +44,6 @@ int32_t AsyncFileReadPollHandler(const void* a1, void* a2); uint32_t AsyncFileReadThread(void* thread); +void AsyncFileReadWait(CAsyncObject* object); + #endif diff --git a/src/model/CM2Model.cpp b/src/model/CM2Model.cpp index 0caf26f..85404df 100644 --- a/src/model/CM2Model.cpp +++ b/src/model/CM2Model.cpp @@ -1,4 +1,5 @@ #include "model/CM2Model.hpp" +#include "async/AsyncFileRead.hpp" #include "math/Types.hpp" #include "model/CM2Scene.hpp" #include "model/CM2Shared.hpp" @@ -1020,7 +1021,33 @@ int32_t CM2Model::IsBatchDoodadCompatible(M2Batch* batch) { } int32_t CM2Model::IsDrawable(int32_t a2, int32_t a3) { - // TODO + if (!this->m_loaded && a2) { + this->WaitForLoad(nullptr); + } + + if (!this->m_flag2) { + if (!this->m_loaded) { + return 0; + } + + for (uint32_t i = 0; i < this->m_shared->m_data->textures.Count(); i++) { + auto texture = this->m_textures[i]; + + if (!texture) { + continue; + } + + if (!TextureGetGxTex(texture, a2, nullptr)) { + return 0; + } + } + + this->m_flag2 = 1; + } + + if (!this->m_flag200 && a3) { + // TODO + } return 1; } @@ -1501,5 +1528,15 @@ void CM2Model::UpdateLoaded() { } void CM2Model::WaitForLoad(const char* a2) { - // TODO + if (this->m_shared->asyncObject) { + AsyncFileReadWait(this->m_shared->asyncObject); + } + + if (this->m_shared->asyncObject) { + AsyncFileReadWait(this->m_shared->asyncObject); + } + + if (this->m_flags & 0x20) { + this->InitializeLoaded(); + } }