mirror of
https://github.com/thunderbrewhq/thunderbrew
synced 2025-12-12 11:12:29 +00:00
chore: initial commit
This commit is contained in:
commit
70b00c5c38
965 changed files with 264882 additions and 0 deletions
143
src/async/AsyncFile.cpp
Normal file
143
src/async/AsyncFile.cpp
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
#include "async/AsyncFile.hpp"
|
||||
#include "async/AsyncFileRead.hpp"
|
||||
#include "async/CAsyncQueue.hpp"
|
||||
#include "event/Event.hpp"
|
||||
#include "util/SFile.hpp"
|
||||
#include <common/Prop.hpp>
|
||||
#include <common/Time.hpp>
|
||||
|
||||
CAsyncObject* AsyncFileReadAllocObject() {
|
||||
AsyncFileRead::s_queueLock.Enter();
|
||||
|
||||
CAsyncObject* object = AsyncFileRead::s_asyncFileReadFreeList.Head();
|
||||
|
||||
if (!object) {
|
||||
object = AsyncFileRead::s_asyncFileReadFreeList.NewNode(1, 0, 0x0);
|
||||
}
|
||||
|
||||
object->link.Unlink();
|
||||
|
||||
AsyncFileRead::s_queueLock.Leave();
|
||||
|
||||
object->file = nullptr;
|
||||
object->buffer = nullptr;
|
||||
object->size = 0;
|
||||
object->userArg = nullptr;
|
||||
object->userPostloadCallback = nullptr;
|
||||
object->userFailedCallback = nullptr;
|
||||
object->queue = nullptr;
|
||||
object->isProcessed = 0;
|
||||
object->isRead = 0;
|
||||
object->isCurrent = 0;
|
||||
object->char24 = 0;
|
||||
object->char25 = 0;
|
||||
object->ptr1C = 0;
|
||||
object->priority = 126;
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
void AsyncFileReadDestroyObject(CAsyncObject* object) {
|
||||
AsyncFileRead::s_queueLock.Enter();
|
||||
|
||||
if (object->isCurrent) {
|
||||
// TODO
|
||||
// nullsub_3();
|
||||
|
||||
AsyncFileRead::s_queueLock.Leave();
|
||||
|
||||
while (object->isCurrent) {
|
||||
OsSleep(1);
|
||||
}
|
||||
|
||||
AsyncFileRead::s_queueLock.Enter();
|
||||
}
|
||||
|
||||
object->link.Unlink();
|
||||
|
||||
if (object->file) {
|
||||
SFile::Close(object->file);
|
||||
}
|
||||
|
||||
AsyncFileRead::s_asyncFileReadFreeList.LinkToHead(object);
|
||||
|
||||
AsyncFileRead::s_queueLock.Leave();
|
||||
}
|
||||
|
||||
void AsyncFileReadInitialize(uint32_t threadSleep, uint32_t handlerTimeout) {
|
||||
AsyncFileRead::s_threadSleep = std::min(threadSleep, 100u);
|
||||
AsyncFileRead::s_handlerTimeout = std::max(handlerTimeout, 20u);
|
||||
|
||||
EventRegisterEx(EVENT_ID_POLL, &AsyncFileReadPollHandler, nullptr, 0.0f);
|
||||
if (SFile::IsStreamingMode()) {
|
||||
// TODO
|
||||
// EventRegisterEx(EVENT_ID_IDLE, &Sub4B9F40, nullptr, -1.0f);
|
||||
}
|
||||
|
||||
AsyncFileRead::s_asyncWaitObject = nullptr;
|
||||
AsyncFileRead::s_progressCallback = nullptr;
|
||||
AsyncFileRead::s_progressParam = nullptr;
|
||||
AsyncFileRead::s_ingameProgressCallback = nullptr;
|
||||
AsyncFileRead::s_ingameStartCallback = nullptr;
|
||||
AsyncFileRead::s_propContext = PropGetSelectedContext();
|
||||
|
||||
AsyncFileRead::s_shutdownEvent.Reset();
|
||||
|
||||
int32_t numQueues = SFile::IsStreamingMode() != 0 ? 3 : 1;
|
||||
for (int32_t i = 0; i < numQueues; i++) {
|
||||
CAsyncQueue* queue = AsyncFileReadCreateQueue();
|
||||
const char* queueName = AsyncFileRead::s_asyncQueueNames[i];
|
||||
|
||||
AsyncFileRead::s_asyncQueues[i] = queue;
|
||||
AsyncFileReadCreateThread(queue, queueName);
|
||||
}
|
||||
|
||||
if (SFile::IsStreamingMode()) {
|
||||
AsyncFileRead::s_asyncQueues[2]->int20 = 1;
|
||||
}
|
||||
|
||||
// TODO
|
||||
// - Something related to AsyncFileRead::s_userQueueLock
|
||||
}
|
||||
|
||||
void AsyncFileReadObject(CAsyncObject* object, int32_t a2) {
|
||||
CAsyncQueue* queue = AsyncFileRead::s_asyncQueues[0];
|
||||
|
||||
if (SFile::IsStreamingMode()) {
|
||||
// TODO
|
||||
// int32_t v3 = SFile::FileIsLocal(object->file, 6);
|
||||
//
|
||||
// if (!v3 || v3 == 2) {
|
||||
// int32_t v4 = object->priority <= 127;
|
||||
// object->char24 = 1;
|
||||
// queue = AsyncFileRead::s_asyncQueues[1];
|
||||
//
|
||||
// if (!v4) {
|
||||
// queue = AsyncFileRead::s_asyncQueues[2];
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
AsyncFileRead::s_queueLock.Enter();
|
||||
|
||||
object->queue = queue;
|
||||
|
||||
if (AsyncFileRead::s_asyncWaitObject == object) {
|
||||
object->priority = object->priority > 127 ? 128 : 0;
|
||||
// TODO
|
||||
// object->ptr1C = g_theGxDevicePtr + 3944;
|
||||
object->char25 = 0;
|
||||
} else if (queue->int20) {
|
||||
// TODO
|
||||
// Sub4BA530(object, a2);
|
||||
} else {
|
||||
AsyncFileReadLinkObject(object, a2);
|
||||
}
|
||||
|
||||
AsyncFileRead::s_queueLock.Leave();
|
||||
|
||||
if (SFile::IsStreamingMode()) {
|
||||
// TODO
|
||||
// SFile::LogFileAccess(object->file, 0, 0);
|
||||
}
|
||||
}
|
||||
14
src/async/AsyncFile.hpp
Normal file
14
src/async/AsyncFile.hpp
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
#ifndef ASYNC_ASYNC_FILE_HPP
|
||||
#define ASYNC_ASYNC_FILE_HPP
|
||||
|
||||
#include "async/CAsyncObject.hpp"
|
||||
|
||||
CAsyncObject* AsyncFileReadAllocObject(void);
|
||||
|
||||
void AsyncFileReadDestroyObject(CAsyncObject* object);
|
||||
|
||||
void AsyncFileReadInitialize(uint32_t threadSleep, uint32_t handlerTimeout);
|
||||
|
||||
void AsyncFileReadObject(CAsyncObject* object, int32_t a2);
|
||||
|
||||
#endif
|
||||
196
src/async/AsyncFileRead.cpp
Normal file
196
src/async/AsyncFileRead.cpp
Normal file
|
|
@ -0,0 +1,196 @@
|
|||
#include "async/AsyncFileRead.hpp"
|
||||
#include "util/SFile.hpp"
|
||||
#include <common/Prop.hpp>
|
||||
#include <common/Time.hpp>
|
||||
|
||||
uint32_t AsyncFileRead::s_threadSleep;
|
||||
uint32_t AsyncFileRead::s_handlerTimeout = 100;
|
||||
CAsyncObject* AsyncFileRead::s_asyncWaitObject;
|
||||
void* AsyncFileRead::s_progressCallback;
|
||||
void* AsyncFileRead::s_progressParam;
|
||||
int32_t AsyncFileRead::s_progressCount;
|
||||
void* AsyncFileRead::s_ingameProgressCallback;
|
||||
void* AsyncFileRead::s_ingameStartCallback;
|
||||
void* AsyncFileRead::s_propContext;
|
||||
SEvent AsyncFileRead::s_shutdownEvent = SEvent(1, 0);
|
||||
const char* AsyncFileRead::s_asyncQueueNames[NUM_ASYNC_QUEUES] = {
|
||||
"Disk Queue",
|
||||
"Net Geometry Queue",
|
||||
"Net Texture Queue"
|
||||
};
|
||||
CAsyncQueue* AsyncFileRead::s_asyncQueues[NUM_ASYNC_QUEUES];
|
||||
SCritSect AsyncFileRead::s_queueLock;
|
||||
SCritSect AsyncFileRead::s_userQueueLock;
|
||||
TSList<CAsyncQueue, TSGetLink<CAsyncQueue>> AsyncFileRead::s_asyncQueueList;
|
||||
TSList<CAsyncThread, TSGetLink<CAsyncThread>> AsyncFileRead::s_asyncThreadList;
|
||||
STORM_EXPLICIT_LIST(CAsyncObject, link) AsyncFileRead::s_asyncFileReadPostList;
|
||||
STORM_EXPLICIT_LIST(CAsyncObject, link) AsyncFileRead::s_asyncFileReadFreeList;
|
||||
|
||||
CAsyncQueue* AsyncFileReadCreateQueue() {
|
||||
CAsyncQueue* queue = AsyncFileRead::s_asyncQueueList.NewNode(0, 2, 0x8);
|
||||
return queue;
|
||||
}
|
||||
|
||||
void AsyncFileReadCreateThread(CAsyncQueue* queue, const char* queueName) {
|
||||
CAsyncThread* thread = AsyncFileRead::s_asyncThreadList.NewNode(0, 2, 0x8);
|
||||
|
||||
thread->queue = queue;
|
||||
thread->currentObject = nullptr;
|
||||
|
||||
SThread::Create(AsyncFileReadThread, thread, thread->thread, const_cast<char*>(queueName), 0);
|
||||
}
|
||||
|
||||
void AsyncFileReadLinkObject(CAsyncObject* object, int32_t a2) {
|
||||
if (!object->queue) {
|
||||
return;
|
||||
}
|
||||
|
||||
object->link.Unlink();
|
||||
|
||||
auto& readList = object->queue->readList;
|
||||
|
||||
for (auto currentObject = readList.Head(); currentObject; currentObject = readList.Link(currentObject)->Next()) {
|
||||
uint8_t priority = object->priority;
|
||||
uint8_t currentPriority = currentObject->priority;
|
||||
|
||||
if (priority <= currentPriority && (a2 || priority != currentPriority)) {
|
||||
readList.LinkNode(object, 2, currentObject);
|
||||
object->char25 = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
readList.LinkToTail(object);
|
||||
object->char25 = 0;
|
||||
}
|
||||
|
||||
int32_t AsyncFileReadPollHandler(const void*, void*) {
|
||||
uint32_t start = OsGetAsyncTimeMsPrecise();
|
||||
|
||||
while (1) {
|
||||
AsyncFileRead::s_queueLock.Enter();
|
||||
|
||||
CAsyncObject* object = AsyncFileRead::s_asyncFileReadPostList.Head();
|
||||
|
||||
if (!object) {
|
||||
AsyncFileRead::s_queueLock.Leave();
|
||||
break;
|
||||
}
|
||||
|
||||
AsyncFileRead::s_asyncFileReadPostList.UnlinkNode(object);
|
||||
|
||||
if (AsyncFileRead::s_asyncWaitObject == object) {
|
||||
AsyncFileRead::s_asyncWaitObject = nullptr;
|
||||
}
|
||||
|
||||
object->isProcessed = 1;
|
||||
|
||||
AsyncFileRead::s_queueLock.Leave();
|
||||
|
||||
object->userPostloadCallback(object->userArg);
|
||||
|
||||
AsyncFileRead::s_progressCount--;
|
||||
|
||||
// Check if we're exceeded the allowed running time
|
||||
if (OsGetAsyncTimeMsPrecise() - start > AsyncFileRead::s_handlerTimeout) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO
|
||||
// for (int32_t i = 0; i < DwordB4A224; i++) {
|
||||
// DwordB4A228[i]();
|
||||
// }
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32_t AsyncFileReadThread(void* param) {
|
||||
CAsyncThread* thread = static_cast<CAsyncThread*>(param);
|
||||
|
||||
PropSelectContext(AsyncFileRead::s_propContext);
|
||||
|
||||
while (AsyncFileRead::s_shutdownEvent.Wait(0)) {
|
||||
uint32_t sleep = 0;
|
||||
CAsyncObject* object;
|
||||
|
||||
while (1) {
|
||||
AsyncFileRead::s_queueLock.Enter();
|
||||
|
||||
object = thread->queue->readList.Head();
|
||||
|
||||
if (object && thread->queue->int20 && /* TODO */ true) {
|
||||
// TODO
|
||||
// Sub4BA530(object, 1);
|
||||
|
||||
AsyncFileRead::s_queueLock.Leave();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!object) {
|
||||
object = thread->queue->list14.Head();
|
||||
}
|
||||
|
||||
if (!object) {
|
||||
AsyncFileRead::s_queueLock.Leave();
|
||||
break;
|
||||
}
|
||||
|
||||
object->link.Unlink();
|
||||
object->queue = nullptr;
|
||||
object->isCurrent = 1;
|
||||
thread->currentObject = object;
|
||||
|
||||
AsyncFileRead::s_queueLock.Leave();
|
||||
|
||||
int32_t tries = 10;
|
||||
while (1) {
|
||||
if (SFile::IsStreamingMode() && object->file) {
|
||||
// TODO
|
||||
// Sub421820(object->file, (object->priority > 127) + 1, 1);
|
||||
}
|
||||
|
||||
if (SFile::Read(object->file, object->buffer, object->size, nullptr, nullptr, nullptr)) {
|
||||
break;
|
||||
}
|
||||
|
||||
tries--;
|
||||
|
||||
// Handle failure
|
||||
if (tries == 0) {
|
||||
// TODO
|
||||
// Sub421850((object->file, v17, 512);
|
||||
// v10 = Sub7717E0();
|
||||
// Sub771A80(v10, v18, 512);
|
||||
// nullsub_3(v17);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
AsyncFileRead::s_queueLock.Enter();
|
||||
|
||||
AsyncFileRead::s_asyncFileReadPostList.LinkToTail(object);
|
||||
|
||||
thread->currentObject = nullptr;
|
||||
object->isCurrent = 0;
|
||||
object->isRead = 1;
|
||||
|
||||
AsyncFileRead::s_queueLock.Leave();
|
||||
|
||||
if (AsyncFileRead::s_threadSleep) {
|
||||
sleep++;
|
||||
|
||||
if (sleep == AsyncFileRead::s_threadSleep) {
|
||||
OsSleep(1);
|
||||
sleep = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OsSleep(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
46
src/async/AsyncFileRead.hpp
Normal file
46
src/async/AsyncFileRead.hpp
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
#ifndef ASYNC_ASYNC_FILE_READ_HPP
|
||||
#define ASYNC_ASYNC_FILE_READ_HPP
|
||||
|
||||
#include "async/CAsyncQueue.hpp"
|
||||
#include "async/CAsyncThread.hpp"
|
||||
#include <common/Prop.hpp>
|
||||
#include <storm/Thread.hpp>
|
||||
|
||||
#define NUM_ASYNC_QUEUES 3
|
||||
|
||||
class CAsyncObject;
|
||||
|
||||
class AsyncFileRead {
|
||||
public:
|
||||
// Static variables
|
||||
static uint32_t s_threadSleep;
|
||||
static uint32_t s_handlerTimeout;
|
||||
static CAsyncObject* s_asyncWaitObject;
|
||||
static void* s_progressCallback;
|
||||
static void* s_progressParam;
|
||||
static int32_t s_progressCount;
|
||||
static void* s_ingameProgressCallback;
|
||||
static void* s_ingameStartCallback;
|
||||
static HPROPCONTEXT s_propContext;
|
||||
static SEvent s_shutdownEvent;
|
||||
static const char* s_asyncQueueNames[];
|
||||
static CAsyncQueue* s_asyncQueues[];
|
||||
static SCritSect s_queueLock;
|
||||
static SCritSect s_userQueueLock;
|
||||
static TSList<CAsyncQueue, TSGetLink<CAsyncQueue>> s_asyncQueueList;
|
||||
static TSList<CAsyncThread, TSGetLink<CAsyncThread>> s_asyncThreadList;
|
||||
static STORM_EXPLICIT_LIST(CAsyncObject, link) s_asyncFileReadPostList;
|
||||
static STORM_EXPLICIT_LIST(CAsyncObject, link) s_asyncFileReadFreeList;
|
||||
};
|
||||
|
||||
CAsyncQueue* AsyncFileReadCreateQueue(void);
|
||||
|
||||
void AsyncFileReadCreateThread(CAsyncQueue* queue, const char* queueName);
|
||||
|
||||
void AsyncFileReadLinkObject(CAsyncObject* object, int32_t a2);
|
||||
|
||||
int32_t AsyncFileReadPollHandler(const void*, void*);
|
||||
|
||||
uint32_t AsyncFileReadThread(void* thread);
|
||||
|
||||
#endif
|
||||
30
src/async/CAsyncObject.hpp
Normal file
30
src/async/CAsyncObject.hpp
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef ASYNC_C_ASYNC_OBJECT_HPP
|
||||
#define ASYNC_C_ASYNC_OBJECT_HPP
|
||||
|
||||
#include <storm/List.hpp>
|
||||
|
||||
class SFile;
|
||||
class CAsyncQueue;
|
||||
|
||||
class CAsyncObject {
|
||||
public:
|
||||
// Member variables
|
||||
SFile* file;
|
||||
void* buffer;
|
||||
uint32_t size;
|
||||
void* userArg;
|
||||
void (*userPostloadCallback)(void*);
|
||||
void (*userFailedCallback)(void*);
|
||||
CAsyncQueue* queue;
|
||||
void* ptr1C;
|
||||
uint8_t priority;
|
||||
uint8_t isProcessed;
|
||||
uint8_t isRead;
|
||||
uint8_t isCurrent;
|
||||
uint8_t char24;
|
||||
uint8_t char25;
|
||||
uint8_t padding[2];
|
||||
TSLink<CAsyncObject> link;
|
||||
};
|
||||
|
||||
#endif
|
||||
16
src/async/CAsyncQueue.hpp
Normal file
16
src/async/CAsyncQueue.hpp
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef ASYNC_C_ASYNC_QUEUE_HPP
|
||||
#define ASYNC_C_ASYNC_QUEUE_HPP
|
||||
|
||||
#include "async/CAsyncObject.hpp"
|
||||
#include <cstdint>
|
||||
#include <storm/List.hpp>
|
||||
|
||||
class CAsyncQueue : public TSLinkedNode<CAsyncQueue> {
|
||||
public:
|
||||
// Member variables
|
||||
STORM_EXPLICIT_LIST(CAsyncObject, link) readList;
|
||||
STORM_EXPLICIT_LIST(CAsyncObject, link) list14;
|
||||
int32_t int20;
|
||||
};
|
||||
|
||||
#endif
|
||||
19
src/async/CAsyncThread.hpp
Normal file
19
src/async/CAsyncThread.hpp
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef ASYNC_C_ASYNC_THREAD_HPP
|
||||
#define ASYNC_C_ASYNC_THREAD_HPP
|
||||
|
||||
#include <cstdint>
|
||||
#include <storm/List.hpp>
|
||||
#include <storm/Thread.hpp>
|
||||
|
||||
class CAsyncObject;
|
||||
class CAsyncQueue;
|
||||
|
||||
class CAsyncThread : public TSLinkedNode<CAsyncThread> {
|
||||
public:
|
||||
// Member variables
|
||||
SThread thread;
|
||||
CAsyncQueue* queue;
|
||||
CAsyncObject* currentObject;
|
||||
};
|
||||
|
||||
#endif
|
||||
19
src/async/CMakeLists.txt
Normal file
19
src/async/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
file(GLOB PRIVATE_SOURCES "*.cpp")
|
||||
|
||||
add_library(async STATIC
|
||||
${PRIVATE_SOURCES}
|
||||
)
|
||||
|
||||
target_include_directories(async
|
||||
PRIVATE
|
||||
${CMAKE_SOURCE_DIR}/src
|
||||
)
|
||||
|
||||
target_link_libraries(async
|
||||
PRIVATE
|
||||
event
|
||||
util
|
||||
PUBLIC
|
||||
common
|
||||
storm
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue