chore: initial commit

This commit is contained in:
fallenoak 2023-01-02 13:17:18 -06:00
commit 70b00c5c38
No known key found for this signature in database
GPG key ID: 7628F8E61AEA070D
965 changed files with 264882 additions and 0 deletions

143
src/async/AsyncFile.cpp Normal file
View 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
View 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
View 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;
}

View 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

View 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
View 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

View 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
View 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
)