-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Header & JKRArchive.hpp might be completely wrong idk
- Loading branch information
Showing
5 changed files
with
455 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,339 @@ | ||
#ifndef JKR_ARCHIVE_H | ||
#define JKR_ARCHIVE_H | ||
|
||
#include <JSystem/JKernel/JKRFileLoader.hpp> | ||
#include <JSystem/JKernel/JKRHeap.hpp> | ||
#include <macros.h> | ||
|
||
|
||
// NOTE: Vtable offsets are off | ||
|
||
#define JKRARCHIVE_ATTR_COMPRESSION 0x04 | ||
#define JKRARCHIVE_ATTR_YAY0 0x80 | ||
|
||
inline u32 read_big_endian_u32(void* ptr) | ||
{ | ||
u8* uptr = (u8*)ptr; | ||
return ((u32)uptr[0] << 0x18) | ((u32)uptr[1] << 0x10) | ((u32)uptr[2] << 8) | (u32)uptr[3]; | ||
} | ||
|
||
class JKRAramBlock; | ||
class JKRFile; | ||
|
||
class JKRArchive : public JKRFileLoader | ||
{ | ||
public: | ||
enum EMountMode | ||
{ | ||
UNKNOWN_MOUNT_MODE = 0, | ||
MOUNT_MEM = 1, | ||
MOUNT_ARAM = 2, | ||
MOUNT_DVD = 3, | ||
MOUNT_COMP = 4, | ||
}; | ||
|
||
enum EMountDirection | ||
{ | ||
UNKNOWN_MOUNT_DIRECTION = 0, | ||
MOUNT_DIRECTION_HEAD = 1, | ||
MOUNT_DIRECTION_TAIL = 2, | ||
}; | ||
|
||
class CArcName | ||
{ | ||
public: | ||
CArcName(const char** p1, char p2) { p1[0] = store(p1[0], p2); } | ||
|
||
const char* getString() const { return mString; } | ||
u16 getHash() const { return mHash; } | ||
void store(const char*); | ||
const char* store(const char*, char); | ||
|
||
// Unused/inlined: | ||
CArcName() {} | ||
CArcName(const char* data) { store(data); } | ||
|
||
u16 mHash; // _00 | ||
u16 _02; // _02 | ||
char mString[256]; // _04 | ||
u8 _104[4]; // _104, unknown, used to fix stack size | ||
}; | ||
|
||
struct SDIFileEntry | ||
{ | ||
u16 getNameHash() const { return mHash; } | ||
u32 getNameOffset() const { return mFlag & 0xFFFFFF; } | ||
u32 getFlags() const { return mFlag >> 24; } | ||
u32 getAttr() const { return getFlags(); } | ||
u32 getSize() { return mSize; } | ||
u16 getFileID() const { return mFileID; } | ||
bool isDirectory() const { return (getFlags() & 0x02) != 0; } | ||
bool isCompressed() const { return (getFlags() & 0x04) != 0; } | ||
u8 getCompressFlag() const { return (getFlags() & 0x04); } // apparently both necessary? | ||
bool isYAZ0Compressed() const { return (getFlags() & 0x80) != 0; } | ||
|
||
bool getFlag01() const { return (getFlags() & 0x01) != 0; } | ||
bool getFlag04() { return mFlag >> 0x18 & 0x04; } | ||
bool getFlag10() { return mFlag >> 0x18 & 0x10; } | ||
bool getFlag80() { return mFlag >> 0x18 & 0x80; } | ||
|
||
u16 mFileID; // _00 | ||
u16 mHash; // _02 | ||
u32 mFlag; // _04 | ||
u32 mDataOffset; // _08 | ||
u32 mSize; // _0C | ||
void* mData; // _10 | ||
}; | ||
|
||
struct SDirEntry | ||
{ | ||
u8 mFlags; // _00 | ||
u8 _01; // _01 | ||
u16 mID; // _02 | ||
char* mName; // _04 | ||
}; | ||
|
||
struct SDIDirEntry | ||
{ | ||
u32 mType; // _00 | ||
u32 mOffset; // _04 | ||
u16 _08; // _08 | ||
u16 mNum; // _0A | ||
u32 mFirstIdx; // _0C | ||
}; | ||
|
||
// NB: Fabricated name | ||
struct SArcDataInfo | ||
{ | ||
u32 num_nodes; // _00 | ||
u32 node_offset; // _04 | ||
u32 num_file_entries; // _08 | ||
u32 file_entry_offset; // _0C | ||
u32 string_table_length; // _10 | ||
u32 string_table_offset; // _14 | ||
u16 nextFreeFileID; // _18 | ||
bool isSyncIDs; // _1A | ||
u8 _1B[5]; // _1B, unknown | ||
}; | ||
|
||
// NB: Fabricated name - need to check size | ||
struct SArcHeader | ||
{ | ||
u32 signature; // _00 | ||
u32 file_length; // _04 | ||
u32 header_length; // _08 | ||
u32 file_data_offset; // _0C | ||
u32 file_data_length; // _10 | ||
u32 _14; // _14 | ||
u32 _18; // _18 | ||
u32 _1C; // _1C | ||
}; | ||
|
||
JKRArchive(s32, EMountMode); | ||
|
||
virtual ~JKRArchive(); // _08 | ||
virtual bool becomeCurrent(const char*); // _10 | ||
virtual void* getResource(const char* path); // _14 | ||
virtual void* getResource(u32 type, const char* name); // _18 | ||
virtual size_t readResource(void* resourceBuffer, u32 bufferSize, const char* path, JKRExpandSwitch expandSwitch); // _1C | ||
virtual size_t readResource(void* resourceBuffer, u32 bufferSize, u32 type, const char* name); // _20 | ||
virtual void removeResourceAll(); // _24 | ||
virtual bool removeResource(void*); // _28 | ||
virtual bool detachResource(void*); // _2C | ||
virtual s32 getResSize(const void*) const; // _30 | ||
virtual u32 countFile(const char*) const; // _34 | ||
virtual JKRFileFinder* getFirstFile(const char*) const; // _38 | ||
virtual void* fetchResource(SDIFileEntry* entry, u32* outSize) = 0; // _40 | ||
virtual void* fetchResource(void* resourceBuffer, u32 bufferSize, SDIFileEntry* entry, u32* resSize, JKRExpandSwitch expandSwitch) = 0; // _44 | ||
|
||
SDIDirEntry* findDirectory(const char*, u32) const; | ||
SDIFileEntry* findFsResource(const char*, u32) const; | ||
SDIFileEntry* findIdResource(u16) const; | ||
SDIFileEntry* findIdxResource(u32) const; | ||
SDIFileEntry* findNameResource(const char*) const; | ||
SDIFileEntry* findPtrResource(const void*) const; | ||
SDIFileEntry* findTypeResource(u32, const char*) const; | ||
bool isSameName(CArcName&, u32, u16) const; | ||
|
||
bool getDirEntry(SDirEntry*, u32) const; | ||
void* getIdxResource(u32 index); | ||
size_t readResource(void* resourceBuffer, u32 bufferSize, u16 id); | ||
|
||
static JKRArchive* mount(char const*, EMountMode, JKRHeap*, EMountDirection); | ||
static JKRArchive* mount(void*, JKRHeap*, EMountDirection); | ||
static JKRArchive* mount(s32, EMountMode, JKRHeap*, EMountDirection); | ||
static void* getGlbResource(u32 type, const char* name, JKRArchive* archive); | ||
|
||
// Unused/inlined: | ||
JKRArchive(); | ||
JKRArchive(const char* p1, EMountMode mountMode); | ||
static JKRArchive* check_mount_already(s32); | ||
static JKRArchive* check_mount_already(s32, JKRHeap*); | ||
SDIDirEntry* findResType(u32) const; | ||
SDIFileEntry* findTypeResource(u32, u32) const; | ||
|
||
static int convertAttrToCompressionType(int attr) | ||
{ | ||
int compression; | ||
if (FLAG_ON(attr, JKRARCHIVE_ATTR_COMPRESSION)) | ||
compression = JKRCOMPRESSION_NONE; | ||
else if (!FLAG_ON(attr, JKRARCHIVE_ATTR_YAY0)) | ||
compression = JKRCOMPRESSION_YAZ0; | ||
else | ||
compression = JKRCOMPRESSION_YAY0; | ||
|
||
return compression; | ||
} | ||
|
||
u32 getMountMode() const { return mMountMode; } | ||
u32 countFile() const { return mArcInfoBlock->num_file_entries; } | ||
int countDirectory() const { return mArcInfoBlock->num_nodes; } | ||
static u32 getCurrentDirID() { return sCurrentDirID; } | ||
static void setCurrentDirID(u32 dirID) { sCurrentDirID = dirID; } | ||
|
||
static u32 sCurrentDirID; | ||
|
||
protected: | ||
// _00 = VTBL | ||
// _00-_38 = JKRFileLoader | ||
JKRHeap* mHeap; // _38 | ||
u8 mMountMode; // _3C | ||
s32 mEntryNum; // _40 | ||
SArcDataInfo* mArcInfoBlock; // _44 | ||
SDIDirEntry* mDirectories; // _48 | ||
SDIFileEntry* mFileEntries; // _4C | ||
const char* mStrTable; // _50 | ||
int _54; // _54 | ||
int mCompression; // _58 | ||
EMountDirection mMountDirection; // _5C | ||
}; | ||
|
||
enum JKRMemBreakFlag | ||
{ | ||
MBF_0 = 0, | ||
MBF_1 = 1 | ||
}; | ||
|
||
class JKRAramArchive : public JKRArchive | ||
{ | ||
public: | ||
JKRAramArchive(); | ||
JKRAramArchive(s32, EMountDirection); | ||
|
||
virtual ~JKRAramArchive(); // _08 | ||
virtual void* fetchResource(SDIFileEntry*, u32*); // _40 | ||
virtual void* fetchResource(void*, u32, SDIFileEntry*, u32*, JKRExpandSwitch expandSwitch); // _44 | ||
|
||
bool open(s32); | ||
u32 getAramAddress_Entry(SDIFileEntry* fileEntry); | ||
u32 getAramAddress(u32, const char* file); | ||
static u32 fetchResource_subroutine(u32, u32, u8*, u32, int); | ||
static u32 fetchResource_subroutine(u32, u32, JKRHeap*, int, u8**); | ||
|
||
void fixedInit(s32 entryNum, EMountDirection direction); | ||
bool mountFixed(s32 entryNum, EMountDirection direction); | ||
bool mountFixed(const char* path, EMountDirection direction); | ||
void unmountFixed(); | ||
|
||
// _00 = VTBL | ||
// _00-_60 = JKRArchive | ||
JKRAramBlock* mBlock; // _60 | ||
JKRFile* mDvdFile; // _64 | ||
}; | ||
|
||
struct JKRCompArchive : public JKRArchive | ||
{ | ||
JKRCompArchive(s32, EMountDirection); | ||
|
||
virtual ~JKRCompArchive(); // _08 | ||
virtual void removeResourceAll(); // _24 | ||
virtual bool removeResource(void*); // _28 | ||
virtual void* fetchResource(SDIFileEntry* entry, u32* outSize); // _40 | ||
virtual void* fetchResource(void* resourceBuffer, u32 bufferSize, SDIFileEntry* entry, u32* resSize, JKRExpandSwitch expandSwitch); // _44 | ||
|
||
bool open(s32); | ||
|
||
// Unused/inlined: | ||
void fixedInit(s32); | ||
void mountFixed(s32); | ||
void mountFixed(const char*); | ||
void unmountFixed(); | ||
|
||
// _00 = VTBL | ||
// _00-_5C = JKRArchive | ||
u32 _60; // _60 | ||
JKRAramBlock* mAramPart; // _64 | ||
u32 _68; // _68 | ||
JKRFile* mDvdFile; // _6C | ||
u32 mSizeOfMemPart; // _70 | ||
u32 mSizeOfAramPart; // _74 | ||
u32 _78; // _78 | ||
}; | ||
|
||
struct JKRDvdArchive : public JKRArchive | ||
{ | ||
JKRDvdArchive(); | ||
JKRDvdArchive(s32, JKRArchive::EMountDirection); | ||
|
||
virtual ~JKRDvdArchive(); // _00 | ||
virtual void* fetchResource(SDIFileEntry* entry, u32* outSize); // _38 | ||
virtual void* fetchResource(void* resourceBuffer, u32 bufferSize, SDIFileEntry* entry, u32* resSize, JKRExpandSwitch expandSwitch); // _3C | ||
|
||
bool open(s32); | ||
static u32 fetchResource_subroutine(s32, u32, u32, u8*, u32, int, int); | ||
static u32 fetchResource_subroutine(s32, u32, u32, JKRHeap*, int, int, u8**); | ||
|
||
// _00 = VTBL | ||
// _00-_5C = JKRArchive | ||
int _60; // _60 | ||
JKRFile* mDvdFile; // _64 | ||
}; | ||
|
||
struct JKRMemArchive : public JKRArchive | ||
{ | ||
JKRMemArchive(); // unused/inlined | ||
JKRMemArchive(s32, EMountDirection); | ||
JKRMemArchive(void*, u32, JKRMemBreakFlag); | ||
JKRMemArchive(const char*, EMountDirection); // unused/inlined | ||
|
||
virtual ~JKRMemArchive(); // _08 | ||
virtual void removeResourceAll(); // _24 | ||
virtual bool removeResource(void*); // _28 | ||
virtual void* fetchResource(SDIFileEntry* entry, u32* outSize); // _40 | ||
virtual void* fetchResource(void* resourceBuffer, u32 bufferSize, SDIFileEntry* entry, u32* resSize, JKRExpandSwitch expandSwitch); // _44 | ||
|
||
bool open(s32, EMountDirection); | ||
bool open(void*, u32, JKRMemBreakFlag); | ||
static u32 fetchResource_subroutine(u8*, u32, u8*, u32, int); | ||
|
||
// Unused/inlined: | ||
void fixedInit(s32); | ||
void mountFixed(s32, EMountDirection); | ||
void mountFixed(const char*, EMountDirection); | ||
void mountFixed(void*, JKRMemBreakFlag); | ||
void unmountFixed(); | ||
void open(const char*, EMountDirection); | ||
|
||
// _00 = VTBL | ||
// _00-_60 = JKRArchive | ||
SArcHeader* mArcHeader; // _60 | ||
u8* mArchiveData; // _64 | ||
bool mIsOpen; // _68 | ||
}; | ||
|
||
inline int JKRConvertAttrToCompressionType(int attr) | ||
{ | ||
return JKRArchive::convertAttrToCompressionType(attr); | ||
} | ||
|
||
inline JKRArchive* JKRMountArchive(const char* path, JKRArchive::EMountMode mountMode, JKRHeap* heap, JKRArchive::EMountDirection mountDirection) | ||
{ | ||
return JKRArchive::mount(path, mountMode, heap, mountDirection); | ||
} | ||
|
||
inline JKRArchive* JKRMountArchive(void* inBuf, JKRHeap* heap, JKRArchive::EMountDirection mountDirection) | ||
{ | ||
return JKRArchive::mount(inBuf, heap, mountDirection); | ||
} | ||
|
||
#endif |
Oops, something went wrong.