d_rawarchive mostly matching

This commit is contained in:
robojumper
2024-05-25 19:30:32 +02:00
parent fda931e2ae
commit 6da4bb94c5
10 changed files with 574 additions and 75 deletions
+1
View File
@@ -107,6 +107,7 @@ d/d_player.cpp:
d/d_rawarchive.cpp:
.text start:0x80061B10 end:0x800629D0
.data start:0x8050DDD8 end:0x8050DDF8
d/d_scene.cpp:
.text start:0x800629D0 end:0x80062E40
+32 -32
View File
@@ -2741,35 +2741,35 @@ fn_80061AB0 = .text:0x80061AB0; // type:function size:0x5C
fn_80061B10 = .text:0x80061B10; // type:function size:0x88
fn_80061BA0 = .text:0x80061BA0; // type:function size:0x34
fn_80061BE0 = .text:0x80061BE0; // type:function size:0x10
fn_80061BF0 = .text:0x80061BF0; // type:function size:0x28
fn_80061C20 = .text:0x80061C20; // type:function size:0x80
fn_80061CA0 = .text:0x80061CA0; // type:function size:0xA0
fn_80061D40 = .text:0x80061D40; // type:function size:0x8
fn_80061D50 = .text:0x80061D50; // type:function size:0x8
fn_80061D60 = .text:0x80061D60; // type:function size:0x104
fn_80061E70 = .text:0x80061E70; // type:function size:0x74
fn_80061EF0 = .text:0x80061EF0; // type:function size:0xD0
fn_80061FC0 = .text:0x80061FC0; // type:function size:0x34
fn_80062000 = .text:0x80062000; // type:function size:0x9C
fn_800620A0 = .text:0x800620A0; // type:function size:0x104
fn_800621B0 = .text:0x800621B0; // type:function size:0x14C
fn_80062300 = .text:0x80062300; // type:function size:0x5C
fn_80062360 = .text:0x80062360; // type:function size:0x14
fn_80062380 = .text:0x80062380; // type:function size:0x74
fn_80062400 = .text:0x80062400; // type:function size:0x90
fn_80062490 = .text:0x80062490; // type:function size:0xAC
fn_80062540 = .text:0x80062540; // type:function size:0xB0
fn_800625F0 = .text:0x800625F0; // type:function size:0x44
fn_80062640 = .text:0x80062640; // type:function size:0x44
fn_80062690 = .text:0x80062690; // type:function size:0x2C
fn_800626C0 = .text:0x800626C0; // type:function size:0x5C
fn_80062720 = .text:0x80062720; // type:function size:0x60
fn_80062780 = .text:0x80062780; // type:function size:0x80
fn_80062800 = .text:0x80062800; // type:function size:0x34
fn_80062840 = .text:0x80062840; // type:function size:0x80
fn_800628C0 = .text:0x800628C0; // type:function size:0x90
fn_80062950 = .text:0x80062950; // type:function size:0x34
fn_80062990 = .text:0x80062990; // type:function size:0x40
__ct__14dRawArcEntry_cFv = .text:0x80061BF0; // type:function size:0x28
__dt__14dRawArcEntry_cFv = .text:0x80061C20; // type:function size:0x80
searchCallback__14dRawArcEntry_cFPvPvPC11ARCDirEntryPCcb = .text:0x80061CA0; // type:function size:0xA0
searchCallback1__14dRawArcEntry_cFPvPvPC11ARCDirEntryPCc = .text:0x80061D40; // type:function size:0x8
searchCallback2__14dRawArcEntry_cFPvPvPC11ARCDirEntryPCc = .text:0x80061D50; // type:function size:0x8
destroy__14dRawArcEntry_cFPv = .text:0x80061D60; // type:function size:0x104
loadArcFromDiskChecked__14dRawArcEntry_cFPCcPCcUcPQ23EGG4Heap = .text:0x80061E70; // type:function size:0x74
loadArcFromDisk__14dRawArcEntry_cFPCcPCcUcPQ23EGG4Heap = .text:0x80061EF0; // type:function size:0xD0
checkArcExistsOnDisk__14dRawArcEntry_cFPCcPCc = .text:0x80061FC0; // type:function size:0x34
checkArcExistsOnDiskInner__14dRawArcEntry_cFPcPCcPCc = .text:0x80062000; // type:function size:0x9C
mount__14dRawArcEntry_cFPCcPvPvUcPQ23EGG4Heap = .text:0x800620A0; // type:function size:0x104
ensureLoadedMaybe__14dRawArcEntry_cFPv = .text:0x800621B0; // type:function size:0x14C
onMount__14dRawArcEntry_cFPv = .text:0x80062300; // type:function size:0x5C
__ct__14dRawArcTable_cFv = .text:0x80062360; // type:function size:0x14
__dt__14dRawArcTable_cFv = .text:0x80062380; // type:function size:0x74
init__14dRawArcTable_cFUsPvPQ23EGG4Heap = .text:0x80062400; // type:function size:0x90
getArcOrLoadFromDisk__14dRawArcTable_cFPCcPCcUcPQ23EGG4Heap = .text:0x80062490; // type:function size:0xAC
addEntryFromSuperArc__14dRawArcTable_cFPCcPvUcPQ23EGG4Heap = .text:0x80062540; // type:function size:0xB0
ensureLoadedMaybe2__14dRawArcTable_cFPCc = .text:0x800625F0; // type:function size:0x44
ensureLoadedMaybe__14dRawArcTable_cFPCc = .text:0x80062640; // type:function size:0x44
hasEntry__14dRawArcTable_cFPCc = .text:0x80062690; // type:function size:0x2C
decreaseRefCount__14dRawArcTable_cFPCc = .text:0x800626C0; // type:function size:0x5C
getDataFromOarc__14dRawArcTable_cFPCcPCc = .text:0x80062720; // type:function size:0x60
getSubEntryData__14dRawArcTable_cFPCcPCc = .text:0x80062780; // type:function size:0x80
getLoadedArcData__14dRawArcTable_cFPCc = .text:0x80062800; // type:function size:0x34
ensureAllEntriesLoaded__14dRawArcTable_cFv = .text:0x80062840; // type:function size:0x80
findEntry__14dRawArcTable_cCFPCc = .text:0x800628C0; // type:function size:0x90
findEmptySlot__14dRawArcTable_cFv = .text:0x80062950; // type:function size:0x34
findLoadedEntry__14dRawArcTable_cFPCc = .text:0x80062990; // type:function size:0x40
fn_800629D0 = .text:0x800629D0; // type:function size:0x60
fn_80062A30 = .text:0x80062A30; // type:function size:0x50
fn_80062A80 = .text:0x80062A80; // type:function size:0x58
@@ -26141,7 +26141,7 @@ getFileFast__Q23EGG7ArchiveFlPQ23EGG4Heapl = .text:0x80493DC0; // type:function
countFileCallbackFunc__3EGGFPvPvUlPC11ARCDirEntryPCc = .text:0x80493F10; // type:function size:0x18
countFile__Q23EGG7ArchiveFv = .text:0x80493F30; // type:function size:0x38
searchInsideWithPath__3EGGFPQ23EGG7ArchiveP9ARCHandlePFPvPvUlPC11ARCDirEntryPCc_vPvPcUl = .text:0x80493F70; // type:function size:0x144
searchInside__Q23EGG7ArchiveFPFPvPvUlPC11ARCDirEntryPCc_vPv = .text:0x804940C0; // type:function size:0x74
searchInside__Q23EGG7ArchiveFPFPvPvPC11ARCDirEntryPCc_vPv = .text:0x804940C0; // type:function size:0x74
loadFromDisc__EGG__Archive = .text:0x80494140; // type:function size:0x114
initialize__Q23EGG7DvdFileFv = .text:0x80494260; // type:function size:0x40
__ct__Q23EGG7DvdFileFv = .text:0x804942A0; // type:function size:0x44
@@ -27385,11 +27385,11 @@ strlen = .text:0x804C64DC; // type:function size:0x1C scope:weak
__va_arg = .text:0x804C64F8; // type:function size:0xC8 scope:global
__register_global_object = .text:0x804C65C0; // type:function size:0x18 scope:global
__destroy_global_chain = .text:0x804C65D8; // type:function size:0x48 scope:global
fn_804C6620 = .text:0x804C6620; // type:function size:0x104
__construct_new_array = .text:0x804C6620; // type:function size:0x104
fn_804C6724 = .text:0x804C6724; // type:function size:0xBC
__construct_array = .text:0x804C67E0; // type:function size:0xF8
__destroy_arr = .text:0x804C68D8; // type:function size:0x78
fn_804C6950 = .text:0x804C6950; // type:function size:0x80
__destroy_new_array = .text:0x804C6950; // type:function size:0x80
__ptmf_test = .text:0x804C69D0; // type:function size:0x30
fn_804C6A00 = .text:0x804C6A00; // type:function size:0x3C
__ptmf_scall = .text:0x804C6A3C; // type:function size:0x28
+1
View File
@@ -287,6 +287,7 @@ config.libs = [
Object(NonMatching, "d/d_dvd_unk.cpp"),
Object(NonMatching, "d/d_dylink.cpp"),
Object(NonMatching, "d/d_heap.cpp"),
Object(NonMatching, "d/d_rawarchive.cpp"),
Object(NonMatching, "d/d_stage.cpp"),
Object(NonMatching, "d/d_sys.cpp"),
Object(NonMatching, "d/a/d_a_base.cpp"),
+104
View File
@@ -0,0 +1,104 @@
#ifndef D_RAWARCHIVE_H
#define D_RAWARCHIVE_H
#include <common.h>
#include <m/m_dvd.h>
// TODO: loading status could be an enum (-2/-1/0/+1)
// Ghidra: ArcManagerEntry
// size: 0x40
class dRawArcEntry_c {
public:
dRawArcEntry_c();
~dRawArcEntry_c();
bool destroy(void *arg);
bool loadArcFromDiskChecked(const char *fileName, const char *dirName, u8 mountDirection, EGG::Heap *heap);
bool loadArcFromDisk(const char *fileName, const char *dirName, u8 mountDirection, EGG::Heap *heap);
static bool checkArcExistsOnDisk(const char *fileName, const char *dirName);
static bool checkArcExistsOnDiskInner(char *outBuf, const char *fileName, const char *dirName);
int mount(const char *name, void *data, void *callbackArg, u8 mountDirection, EGG::Heap *heap);
int onMount(void *callbackArg);
int ensureLoadedMaybe(void *callbackArg);
inline bool isReferenced() {
return mRefCount != 0;
}
inline const char *name() {
return mArcName;
}
inline bool isNotLoaded() {
return mpArc == nullptr;
}
inline bool isLoading() {
return mpDvdReq != nullptr;
}
inline void increaseRefCount() {
mRefCount++;
}
inline void decreaseRefCount() {
mRefCount--;
}
inline void *getData() {
return mpData;
}
inline EGG::Archive *getArc() {
return mpArc;
}
private:
static void searchCallback(void *, void *, const ARCDirEntry *, const char *, bool);
static void searchCallback1(void *, void *, const ARCDirEntry *, const char *);
static void searchCallback2(void *, void *, const ARCDirEntry *, const char *);
private:
/* 0x00 */ char mArcName[0x20];
/* 0x20 */ u16 mRefCount;
/* 0x24 */ mDvd_mountMemArchive_c *mpDvdReq;
/* 0x28 */ EGG::Archive *mpArc;
/* 0x2C */ EGG::Heap *mpCommandHeap;
/* 0x30 */ void *mpData;
/* 0x34 */ u32 mAmountRead;
/* 0x38 */ u32 mChecksum;
/* 0x3C */ EGG::FrmHeap *mpFrmHeap;
};
// Ghidra: ArcManagerEntryTable
// size: 0xC
class dRawArcTable_c {
public:
dRawArcTable_c();
~dRawArcTable_c();
bool init(u16 count, void *callbackArg, EGG::Heap *heap);
bool getArcOrLoadFromDisk(const char *name, const char *dirName, u8 mountDirection, EGG::Heap *heap);
bool addEntryFromSuperArc(const char *name, void *data, u8 mountDirection, EGG::Heap *heap);
int ensureLoadedMaybe2(const char *name);
int ensureLoadedMaybe(const char *name);
bool hasEntry(const char *name);
bool decreaseRefCount(const char *name);
void *getDataFromOarc(const char *name, const char *path);
void *getSubEntryData(const char *name, const char *path);
void *getLoadedArcData(const char *name);
int ensureAllEntriesLoaded();
dRawArcEntry_c *findEntry(const char *name) const;
dRawArcEntry_c *findEmptySlot();
dRawArcEntry_c *findLoadedEntry(const char *name);
private:
/* 0x0 */ dRawArcEntry_c *mpEntries;
/* 0x4 */ u16 mCount;
/* 0x8 */ void *mCallbackArg;
};
#endif;
+1 -1
View File
@@ -45,7 +45,7 @@ public:
/* 80493a40 */ static Archive *mountNandFile(NANDFileInfo *, Heap *heap, s32 align);
/* 80493ac0 */ static Archive *loadFST(const char *fileName, Heap *heap, s32 align);
/* 80493b80 */ void unmount();
/* 80493c20 */ u32 getFile(const char *name, FileInfo *out);
/* 80493c20 */ void *getFile(const char *name, FileInfo *out);
/* 80493cf0 */ s32 convertPathToEntryID(const char *path);
/* 80493d00 */ void *getFileFast(s32 entryId, FileInfo *fileinfo);
/* 80493dc0 */ void *getFileFast(s32 entryId, Heap *heap, s32 align);
+1 -1
View File
@@ -44,7 +44,7 @@ public:
/* 802f1590 */ static void createCommandHeap(size_t size, EGG::Heap *parentHeap);
/* 802f15c0 */ static void createDylinkHeap(size_t size, EGG::Heap *parentHeap);
/* 802f15f0 */ static EGG::AssertHeap *createAssertHeap(EGG::Heap *parentHeap);
/* 802f1640 */ static EGG::Heap *makeHeapOnCurrentGameHeap(size_t size, const char *name, u32 align, u32 flags);
/* 802f1640 */ static EGG::FrmHeap *makeHeapOnCurrentGameHeap(size_t size, const char *name, u32 align, u32 flags);
static int getDefaultGameHeapId();
+3 -3
View File
@@ -74,9 +74,9 @@ typedef struct ARCEntry {
typedef struct ARCDirEntry {
ARCHandle *handle; // at 0x0
u32 path_begin; // at 0x4
u32 path_it; // at 0x8
u32 path_end; // at 0xC
u32 entryNum; // at 0x4
u32 isDir; // at 0x8
const char *name; // at 0xC
} ARCDirEntry;
BOOL ARCGetCurrentDir(ARCHandle *handle, char *string, u32 maxlen);
-37
View File
@@ -1,37 +0,0 @@
#ifndef ARC_MANAGER_H
#define ARC_MANAGER_H
#include <common.h>
// Ghidra: ArcManagerEntry
// size: 0x40
struct ArcManagerEntry {
/* 0x00 */ char arc_name[0x20];
/* 0x20 */ u16 ref_count;
/* 0x24 */ int dvd_req_ptr;
/* 0x28 */ int archive_ptr;
/* 0x2C */ int heap_ptr_0;
/* 0x30 */ char field_0x30[0x3C - 0x30];
/* 0x3C */ int heap_ptr_1;
};
// Ghidra: ArcManagerEntryTable
// size: 0xC
class ArcMangerEntryTable {
public:
/* 0x0 */ ArcManagerEntry *entries;
/* 0x4 */ u16 count;
/* 0x8 */ u32 field_0x8;
public:
ArcMangerEntryTable();
};
class OarcManager {
public:
void *getDataFromOarc(char *oarcName, char *fileName);
};
OarcManager g_OarcManager;
#endif;
+430
View File
@@ -0,0 +1,430 @@
#include <d/d_rawarchive.h>
#include <rvl/VI.h>
// clang-format off
#include <MSL_C/string.h>
// clang-format on
class UnkManager {
public:
/* vtable at 8050df50 */
/** 800651c0 */
virtual void CreateArc(void *data, const char *path);
/** 800653d0 */
virtual void DestroyArc(const char *path);
u32 stage;
};
extern "C" int fn_80061B10(void *d, u32 len) {
u32 *data = (u32*)d;
u32 result = 0;
// Compiler will unroll this loop
for (u32 len_words = len / 4; len_words != 0; len_words--) {
result += *data++;
}
return result;
}
extern "C" int fn_80061BA0(void *data, u32 len) {
int result = fn_80061B10(data, len);
return result != 0 ? result : -1;
}
extern "C" void fn_80061BE0(UnkManager *mgr, const char *name, size_t len) {
// Sets stage to all spaces
mgr->stage = 0x20202020;
// copies the stage name?
memcpy((char*)&mgr->stage, name, len);
}
dRawArcEntry_c::dRawArcEntry_c() {
mArcName[0] = '\0';
mRefCount = 0;
mpDvdReq = nullptr;
mpArc = nullptr;
mpCommandHeap = nullptr;
mpData = nullptr;
mChecksum = 0;
mpFrmHeap = 0;
}
dRawArcEntry_c::~dRawArcEntry_c() {
// Wait for request to complete before destroying
if (mpDvdReq->mStatus == 0) {
do {
VIWaitForRetrace();
} while (mpDvdReq->mStatus == 0);
}
destroy(nullptr);
}
void dRawArcEntry_c::searchCallback(void *arg, void *data, const ARCDirEntry *entry, const char *path, bool ctrl) {
UnkManager *mgr = (UnkManager *)arg;
if (entry->isDir) {
int len = strlen(entry->name);
fn_80061BE0(mgr, entry->name, len <= 4 ? len : 4);
} else {
// dolphin: arg vtable at 8050df50
// any others?
if (ctrl) {
mgr->CreateArc(data, path);
// branch to 800651c0, sets up room
} else {
mgr->DestroyArc(path);
// branch to 800653d0, destroys room
}
}
}
void dRawArcEntry_c::searchCallback1(void *a, void *b, const ARCDirEntry *c, const char *d) {
searchCallback(a, b, c, d, true);
}
void dRawArcEntry_c::searchCallback2(void *a, void *b, const ARCDirEntry *c, const char *d) {
searchCallback(a, b, c, d, false);
}
bool dRawArcEntry_c::destroy(void *arg) {
if (mpDvdReq != nullptr) {
if (mpDvdReq->mStatus == 0) {
// Can't destroy if the request is still ongoing
return false;
}
mpArc = mpDvdReq->mDataPtr;
mpData = mpDvdReq->getArcBinary();
mAmountRead = mpDvdReq->mAmountRead;
mpCommandHeap = mpDvdReq->mHeap;
mpDvdReq->do_delete();
mpDvdReq = nullptr;
}
if (mpArc != nullptr) {
if (arg != nullptr) {
mpArc->searchInside(searchCallback2, arg);
}
if (mpFrmHeap != nullptr) {
mHeap::destroyFrmHeap(mpFrmHeap);
mpFrmHeap = nullptr;
}
mpArc->unmount();
mpArc = nullptr;
}
if (mpData != nullptr) {
EGG::Heap::free(mpData, nullptr);
mpData = nullptr;
}
mAmountRead = 0;
mChecksum = 0;
mpCommandHeap = 0;
return true;
}
bool dRawArcEntry_c::loadArcFromDiskChecked(const char *fileName, const char *dirName, u8 mountDirection,
EGG::Heap *heap) {
char arcPath[128];
arcPath[0] = '\0';
if (checkArcExistsOnDiskInner(arcPath, fileName, dirName)) {
return loadArcFromDisk(fileName, arcPath, mountDirection, heap);
}
return false;
}
// Regswap
inline void inline_strncat(char *dest, const char *src, size_t destSize) {
if (src != nullptr) {
size_t destLen = strlen(dest);
size_t srcLen = strlen(src);
size_t count = destLen + srcLen + 1 >= destSize ? destSize - destLen - 1 : srcLen;
strncpy(dest + destLen, src, count);
size_t offset = destLen + count;
dest[offset] = '\0';
}
}
inline void inline_strncpy(char *dest, const char *src, size_t destSize) {
if (src != dest) {
dest[0] = '\0';
inline_strncat(dest, src, destSize);
}
}
bool dRawArcEntry_c::loadArcFromDisk(const char *arcName, const char *arcPath, u8 mountDirection, EGG::Heap *heap) {
mpDvdReq = mDvd_mountMemArchive_c::create(arcPath, mountDirection, heap);
if (mpDvdReq == nullptr) {
return false;
}
inline_strncpy(mArcName, arcName, sizeof(mArcName));
return true;
}
bool dRawArcEntry_c::checkArcExistsOnDisk(const char *fileName, const char *dirName) {
char path[128];
path[0] = '\0';
return checkArcExistsOnDiskInner(path, fileName, dirName);
}
// sprintf2
extern "C" void fn_8003D650(char *out, const char *fmt, ...);
bool dRawArcEntry_c::checkArcExistsOnDiskInner(char *outBuf, const char *fileName, const char *dirName) {
fn_8003D650(outBuf, "/US/%s/%s.arc", dirName, fileName);
if (!mDvd::IsExistPath(outBuf)) {
fn_8003D650(outBuf, "/%s/%s.arc", dirName, fileName);
if (!mDvd::IsExistPath(outBuf)) {
return false;
}
}
return true;
}
int dRawArcEntry_c::mount(const char *name, void *data, void *callbackArg, u8 mountDirection, EGG::Heap *heap) {
inline_strncpy(mArcName, name, sizeof(mArcName));
// TODO this conditional uses a few more instructions in the original binary
mpArc = EGG::Archive::mount(data, heap, mountDirection != 1 ? 4 : -4);
if (mpArc == nullptr) {
return -1;
} else {
int result = onMount(callbackArg);
int ret = 0;
if (result == -1) {
ret = result;
}
return ret;
}
}
int dRawArcEntry_c::ensureLoadedMaybe(void *callbackArg) {
if (mpArc == nullptr) {
if (mpDvdReq == nullptr) {
return -1;
}
if (mpDvdReq->mStatus == 0) {
return 1;
}
mpArc = mpDvdReq->mDataPtr;
mpData = mpDvdReq->getArcBinary();
mAmountRead = mpDvdReq->mAmountRead;
if (mpData != nullptr) {
u32 blockSize = EGG::ExpHeap::getSizeForMBlock(mpData);
if (mAmountRead != blockSize) {
mAmountRead = blockSize;
}
}
mpCommandHeap = mpDvdReq->mHeap;
mpDvdReq->do_delete();
mpDvdReq = nullptr;
if (mpArc == nullptr) {
return -1;
}
mpFrmHeap = mHeap::makeHeapOnCurrentGameHeap(-1, this->mArcName, 0x20, 0);
if (mpFrmHeap == nullptr) {
return -1;
}
int result = onMount(callbackArg);
mHeap::restoreCurrentHeap();
mHeap::adjustFrmHeap(mpFrmHeap);
mChecksum = fn_80061BA0(mpData, mAmountRead);
if (result == -1) {
return result;
}
DCStoreRange(mpFrmHeap, mpFrmHeap->mHeapHandle->end - (u8*)mpFrmHeap);
}
return 0;
}
int dRawArcEntry_c::onMount(void *callbackArg) {
mpArc->countFile();
if (callbackArg != nullptr) {
mpArc->searchInside(searchCallback1, callbackArg);
}
return 0;
}
dRawArcTable_c::dRawArcTable_c() {
mpEntries = nullptr;
mCount = 0;
mCallbackArg = nullptr;
}
dRawArcTable_c::~dRawArcTable_c() {
if (mpEntries) {
delete[] mpEntries;
mpEntries = nullptr;
mCount = 0;
}
}
bool dRawArcTable_c::init(u16 count, void *callbackArg, EGG::Heap *heap) {
mpEntries = new (heap, 0x04) dRawArcEntry_c[count]();
if (mpEntries == nullptr) {
return false;
}
mCount = count;
mCallbackArg = callbackArg;
return true;
}
bool dRawArcTable_c::getArcOrLoadFromDisk(const char *name, const char *dirName, u8 mountDirection, EGG::Heap *heap) {
dRawArcEntry_c *entry = findEntry(name);
if (entry == nullptr) {
entry = findEmptySlot();
if (entry == nullptr) {
return false;
}
bool result = entry->loadArcFromDiskChecked(name, dirName, mountDirection, heap);
if (!result) {
entry->destroy(mCallbackArg);
return false;
}
}
entry->increaseRefCount();
return true;
}
bool dRawArcTable_c::addEntryFromSuperArc(const char *name, void *data, u8 mountDirection, EGG::Heap *heap) {
dRawArcEntry_c *entry = findEntry(name);
if (entry == nullptr) {
entry = findEmptySlot();
if (entry == nullptr) {
return false;
}
int result = entry->mount(name, data, mCallbackArg, mountDirection, heap);
if (result != 0) {
entry->destroy(mCallbackArg);
return false;
}
}
entry->increaseRefCount();
return true;
}
int dRawArcTable_c::ensureLoadedMaybe2(const char *name) {
dRawArcEntry_c *entry = findEntry(name);
if (entry == nullptr) {
return -2;
}
return entry->ensureLoadedMaybe(mCallbackArg);
}
int dRawArcTable_c::ensureLoadedMaybe(const char *name) {
dRawArcEntry_c *entry = findEntry(name);
if (entry == nullptr) {
return -2;
}
return entry->ensureLoadedMaybe(mCallbackArg);
}
bool dRawArcTable_c::hasEntry(const char *name) {
return findEntry(name) != nullptr;
}
bool dRawArcTable_c::decreaseRefCount(const char *name) {
dRawArcEntry_c *entry = findEntry(name);
if (entry == nullptr) {
return false;
}
entry->decreaseRefCount();
if (!entry->isReferenced()) {
entry->destroy(mCallbackArg);
}
return true;
}
void *dRawArcTable_c::getDataFromOarc(const char *name, const char *path) {
void *data = nullptr;
dRawArcEntry_c *entry = findLoadedEntry(name);
if (entry != nullptr) {
EGG::Archive *arc = entry->getArc();
if (arc != nullptr) {
data = arc->getFile(path, nullptr);
}
}
return data;
}
void *dRawArcTable_c::getSubEntryData(const char *name, const char *path) {
void *data = nullptr;
dRawArcEntry_c *entry = findLoadedEntry(name);
if (entry != nullptr) {
EGG::Archive *arc = entry->getArc();
if (arc != nullptr) {
int num = arc->convertPathToEntryID(path);
if (num >= 0) {
data = arc->getFileFast(num, nullptr);
}
}
}
return data;
}
void *dRawArcTable_c::getLoadedArcData(const char *name) {
dRawArcEntry_c *entry = findLoadedEntry(name);
return entry == nullptr ? nullptr : entry->getData();
}
int dRawArcTable_c::ensureAllEntriesLoaded() {
dRawArcEntry_c *entry = mpEntries;
int result = 0;
for (int i = 0; i < mCount; i++) {
if (entry->isLoading()) {
result = entry->ensureLoadedMaybe(mCallbackArg);
if (result != 0) {
return result;
}
}
entry++;
}
return 0;
}
extern "C" bool strequals(const char *, const char*);
// TODO the load from self can happen earlier
dRawArcEntry_c *dRawArcTable_c::findEntry(const char *name) const {
dRawArcEntry_c *entry = mpEntries;
for (int i = 0; i < mCount; i++) {
if (entry->isReferenced() && strequals(entry->name(), name)) {
return entry;
}
entry++;
}
return nullptr;
}
dRawArcEntry_c *dRawArcTable_c::findEmptySlot() {
dRawArcEntry_c *entry = mpEntries;
for (int i = 0; i < mCount; i++) {
if (!entry->isReferenced()) {
return entry;
}
entry++;
}
return nullptr;
}
dRawArcEntry_c *dRawArcTable_c::findLoadedEntry(const char *name) {
dRawArcEntry_c *entry = findEntry(name);
if (entry == nullptr) {
return nullptr;
} else if (entry->isNotLoaded()) {
return nullptr;
}
return entry;
}
+1 -1
View File
@@ -207,6 +207,6 @@ EGG::AssertHeap *mHeap::createAssertHeap(EGG::Heap *parent) {
return g_assertHeap;
}
EGG::Heap *mHeap::makeHeapOnCurrentGameHeap(size_t size, const char *name, u32 align, u32 flags) {
EGG::FrmHeap *mHeap::makeHeapOnCurrentGameHeap(size_t size, const char *name, u32 align, u32 flags) {
return makeFrmHeapAndUpdate(size, g_gameHeaps[0], name, align, flags);
}