CurrentStageArcManager WIP

This commit is contained in:
robojumper
2024-05-28 23:15:30 +02:00
parent 82d7176ed1
commit be163e6de7
6 changed files with 251 additions and 37 deletions
+2 -2
View File
@@ -251,7 +251,7 @@ bool dRawArcTable_c::init(u16 count, void *callbackArg, EGG::Heap *heap) {
return true;
}
bool dRawArcTable_c::getArcOrLoadFromDisk(const char *name, const char *dirName, u8 mountDirection, EGG::Heap *heap) {
u32 dRawArcTable_c::getArcOrLoadFromDisk(const char *name, const char *dirName, u8 mountDirection, EGG::Heap *heap) {
dRawArcEntry_c *entry = findEntry(name);
if (entry == nullptr) {
entry = findEmptySlot();
@@ -305,7 +305,7 @@ bool dRawArcTable_c::hasEntry(const char *name) {
return findEntry(name) != nullptr;
}
bool dRawArcTable_c::decreaseRefCount(const char *name) {
u32 dRawArcTable_c::decreaseRefCount(const char *name) {
dRawArcEntry_c *entry = findEntry(name);
if (entry == nullptr) {
return false;
@@ -0,0 +1,205 @@
#include <d/d_heap.h>
#include <d/d_rawarchive.h>
#include <egg/core/eggHeap.h>
// clang-format off
#include <MSL_C/string.h>
// clang-format on
template <size_t Size>
struct SizedString {
SizedString() {
mChars[0] = '\0';
}
char mChars[Size];
char *operator&() {
return mChars;
}
const char *operator&() const {
return mChars;
}
inline void set(const char *src) {
if (src != mChars) {
mChars[0] = '\0';
append(src);
}
}
inline void append(const char *src) {
if (src != nullptr) {
size_t destLen = strlen(mChars);
size_t copyLen = strlen(src);
// Make sure copy length isnt more than destination length
if (destLen + copyLen + 1 >= Size) {
size_t tmpLen = Size - destLen;
copyLen = tmpLen - 1;
}
strncpy(mChars + destLen, src, copyLen);
// make sure string is null terminated
size_t offset = destLen + copyLen;
mChars[offset] = '\0';
}
}
void sprintf(const char *fmt, ...);
};
class CurrentStageArcManager {
CurrentStageArcManager();
virtual ~CurrentStageArcManager();
SizedString<32> mStageName;
SizedString<32> mCurrentLoadingStageArcName;
SizedString<32> mStageExtraLayerArcName;
dRawArcTable_c mArcTable;
static CurrentStageArcManager *sInstance;
static bool create(EGG::Heap *heap);
void init(EGG::Heap *heap);
bool setStage(const char *stage);
bool decrement();
void *getData(const char *fileName);
void *getFileFromCurrentLay0Arc(const char *fileName);
bool loadFileFromExtraLayerArc(int layer);
bool unloadExtraLayerArc();
bool loadRoomArc(int room);
bool addEntryFromSuperArc(const char *name, void *data);
bool unloadRoomArc(int room);
bool decrement(const char *path);
void *loadFromRoomArc(int roomId, const char *fileName);
void *getDataFromRoomArc(int roomId, const char *fileName);
const char *getCurrentStageDirectory();
const char *getRoomArcDirectory(int room) const;
static EGG::ExpHeap *getHeap();
};
CurrentStageArcManager *CurrentStageArcManager::sInstance;
CurrentStageArcManager::CurrentStageArcManager() {
sInstance = this;
}
CurrentStageArcManager::~CurrentStageArcManager() {
sInstance = nullptr;
}
extern char lbl_80575250;
void CurrentStageArcManager::init(EGG::Heap *heap) {
mArcTable.init(18, &lbl_80575250, heap);
}
// sprintf
extern "C" void fn_8001F820(char *str, const char *src, ...);
bool CurrentStageArcManager::setStage(const char *newStage) {
mStageName.set(newStage);
mCurrentLoadingStageArcName.sprintf("%s_stg_l0", mStageName);
if (dRawArcEntry_c::checkArcExistsOnDisk(&mCurrentLoadingStageArcName, getCurrentStageDirectory())) {
return (bool)mArcTable.getArcOrLoadFromDisk(&mCurrentLoadingStageArcName, getCurrentStageDirectory(), 0,
dHeap::work2Heap.heap);
} else {
mCurrentLoadingStageArcName.sprintf("%s_stg", mStageName);
return (bool)mArcTable.getArcOrLoadFromDisk(&mCurrentLoadingStageArcName, getCurrentStageDirectory(), 0,
dHeap::work2Heap.heap);
}
}
bool CurrentStageArcManager::decrement() {
return mArcTable.decreaseRefCount(&mCurrentLoadingStageArcName);
}
void *CurrentStageArcManager::getData(const char *fileName) {
return mArcTable.getDataFromOarc(&mCurrentLoadingStageArcName, fileName);
}
void *CurrentStageArcManager::getFileFromCurrentLay0Arc(const char *fileName) {
return mArcTable.getSubEntryData(&mCurrentLoadingStageArcName, fileName);
}
bool CurrentStageArcManager::loadFileFromExtraLayerArc(int layer) {
if (layer == 0) {
return true;
}
mStageExtraLayerArcName.sprintf("%s_stg_l%d", mStageName, layer);
if (dRawArcEntry_c::checkArcExistsOnDisk(&mStageExtraLayerArcName, getCurrentStageDirectory())) {
return (bool)mArcTable.getArcOrLoadFromDisk(&mStageExtraLayerArcName, getCurrentStageDirectory(), 0,
dHeap::work2Heap.heap);
} else {
return true;
}
}
bool CurrentStageArcManager::unloadExtraLayerArc() {
if (mArcTable.hasEntry(&mStageExtraLayerArcName)) {
return mArcTable.decreaseRefCount(&mStageExtraLayerArcName);
}
return true;
}
bool CurrentStageArcManager::loadRoomArc(int room) {
return (bool)mArcTable.getArcOrLoadFromDisk(getRoomArcDirectory(room), getCurrentStageDirectory(), 0, dHeap::work2Heap.heap);
}
bool CurrentStageArcManager::addEntryFromSuperArc(const char *path, void *data) {
return (bool)mArcTable.addEntryFromSuperArc(path, data, 0, EGG::Heap::sCurrentHeap);
}
bool CurrentStageArcManager::unloadRoomArc(int room) {
mArcTable.decreaseRefCount(getRoomArcDirectory(room));
return true;
}
bool CurrentStageArcManager::decrement(const char *path) {
mArcTable.decreaseRefCount(path);
return true;
}
void *CurrentStageArcManager::loadFromRoomArc(int roomId, const char *fileName) {
return mArcTable.getDataFromOarc(getRoomArcDirectory(roomId), fileName);
}
void *CurrentStageArcManager::getDataFromRoomArc(int roomId, const char *fileName) {
return mArcTable.getSubEntryData(getRoomArcDirectory(roomId), fileName);
}
EGG::ExpHeap *getHeap() {
return dHeap::workExHeap.heap;
}
const char *CurrentStageArcManager::getCurrentStageDirectory() {
static SizedString<64> sStageDirTmp;
sStageDirTmp.set("Stage/");
sStageDirTmp.append(&mStageName);
return &sStageDirTmp;
}
static SizedString<32> s_roomArcTmp;
const char *CurrentStageArcManager::getRoomArcDirectory(int room) const {
s_roomArcTmp.sprintf("%s_r%02d", mStageName, room);
return &s_roomArcTmp;
}
bool CurrentStageArcManager::create(EGG::Heap *heap) {
new (heap, 0x04) CurrentStageArcManager();
if (CurrentStageArcManager::sInstance == nullptr) {
return false;
}
CurrentStageArcManager::sInstance->init(heap);
return true;
}