tp/include/JSystem/JKernel/JKRArchive.h

255 lines
8.1 KiB
C++

#ifndef JKRARCHIVE_H
#define JKRARCHIVE_H
#include "JSystem/JKernel/JKRCompression.h"
#include "JSystem/JKernel/JKRFileLoader.h"
#include "global.h"
class JKRHeap;
/**
* @ingroup jsystem-jkernel
*
*/
struct SArcHeader {
/* 0x00 */ u32 signature;
/* 0x04 */ u32 file_length;
/* 0x08 */ u32 header_length;
/* 0x0C */ u32 file_data_offset;
/* 0x10 */ u32 file_data_length;
/* 0x14 */ u32 field_0x14;
/* 0x18 */ u32 field_0x18;
/* 0x1C */ u32 field_0x1c;
};
/**
* @ingroup jsystem-jkernel
*
*/
struct SArcDataInfo {
/* 0x00 */ u32 num_nodes;
/* 0x04 */ u32 node_offset;
/* 0x08 */ u32 num_file_entries;
/* 0x0C */ u32 file_entry_offset;
/* 0x10 */ u32 string_table_length;
/* 0x14 */ u32 string_table_offset;
/* 0x18 */ u16 next_free_file_id;
/* 0x1A */ bool sync_file_ids_and_indices;
/* 0x1B */ u8 field_1b[5];
};
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];
}
inline u16 read_big_endian_u16(void* ptr) {
u8* uptr = (u8*)ptr;
return ((u16)uptr[0] << 8) | ((u16)uptr[1]);
}
extern u32 sCurrentDirID__10JKRArchive; // JKRArchive::sCurrentDirID
/**
* @ingroup jsystem-jkernel
*
*/
class JKRArchive : public JKRFileLoader {
public:
struct SDirEntry {
u8 flags;
u8 padding;
u16 id;
const char* name;
};
struct SDIDirEntry {
u32 type;
u32 name_offset;
u16 field_0x8;
u16 num_entries;
u32 first_file_index;
};
struct SDIFileEntry {
u16 file_id;
u16 name_hash;
u32 type_flags_and_name_offset;
u32 data_offset;
u32 data_size;
void* data;
u32 getNameOffset() const { return type_flags_and_name_offset & 0xFFFFFF; }
u16 getNameHash() const { return name_hash; }
u32 getFlags() const { return type_flags_and_name_offset >> 24; }
u32 getAttr() const { return getFlags(); }
u16 getFileID() const { return file_id; }
bool isDirectory() const { return (getFlags() & 0x02) != 0; }
bool isUnknownFlag1() const { return (getFlags() & 0x01) != 0; }
bool isCompressed() const { return (getFlags() & 0x04) != 0; }
// was needed for open__14JKRAramArchiveFl
u8 getCompressFlag() const { return (getFlags() & 0x04); }
bool isYAZ0Compressed() const { return (getFlags() & 0x80) != 0; }
u32 getSize() const { return data_size; }
};
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() {}
CArcName(char const* data) { this->store(data); }
CArcName(char const** data, char endChar) { *data = this->store(*data, endChar); }
void store(char const* data);
const char* store(char const* data, char endChar);
u16 getHash() const { return mHash; }
const char* getString() const { return mData; }
private:
u16 mHash;
u16 mLength;
char mData[256];
};
protected:
JKRArchive();
JKRArchive(s32, EMountMode);
public:
virtual ~JKRArchive();
bool getDirEntry(SDirEntry*, u32) const;
void* getIdxResource(u32);
void* getResource(u16);
u32 readIdxResource(void*, u32, u32);
u32 readResource(void*, u32, u16);
u32 countResource(void) const;
u32 getFileAttribute(u32) const;
SDIFileEntry* findNameResource(const char*) const;
bool isSameName(CArcName&, u32, u16) const;
SDIDirEntry* findResType(u32) const;
SDIDirEntry* findDirectory(const char*, u32) const;
SDIFileEntry* findTypeResource(u32, const char*) const;
SDIFileEntry* findFsResource(const char*, u32) const;
SDIFileEntry* findIdxResource(u32) const;
SDIFileEntry* findPtrResource(const void*) const;
SDIFileEntry* findIdResource(u16) const;
public:
/* vt[04] */ virtual bool becomeCurrent(const char*); /* override */
/* vt[05] */ virtual void* getResource(const char*); /* override */
/* vt[06] */ virtual void* getResource(u32, const char*); /* override */
/* vt[07] */ virtual u32 readResource(void*, u32, const char*); /* override */
/* vt[08] */ virtual u32 readResource(void*, u32, u32, const char*); /* override */
/* vt[09] */ virtual void removeResourceAll(void); /* override */
/* vt[10] */ virtual bool removeResource(void*); /* override */
/* vt[11] */ virtual bool detachResource(void*); /* override */
/* vt[12] */ virtual u32 getResSize(const void*) const; /* override */
/* vt[13] */ virtual u32 countFile(const char*) const; /* override */
/* vt[14] */ virtual JKRFileFinder* getFirstFile(const char*) const; /* override */
/* vt[15] */ virtual u32 getExpandedResSize(const void* res) const { return getResSize(res); }
/* vt[16] */ virtual void* fetchResource(SDIFileEntry*, u32*) = 0;
/* vt[17] */ virtual void* fetchResource(void*, u32, SDIFileEntry*, u32*) = 0;
/* vt[18] */ virtual void setExpandSize(SDIFileEntry*, u32);
/* vt[19] */ virtual u32 getExpandSize(SDIFileEntry*) const;
u32 countFile() const { return mArcInfoBlock->num_file_entries; }
s32 countDirectory() const { return mArcInfoBlock->num_nodes; }
u8 getMountMode() const { return mMountMode; }
bool isFileEntry(u32 param_0) {
return getFileAttribute(param_0) & 1;
}
public:
/* 0x00 */ // vtable
/* 0x04 */ // JKRFileLoader
/* 0x38 */ JKRHeap* mHeap;
/* 0x3C */ u8 mMountMode;
/* 0x3D */ u8 field_0x3d[3];
/* 0x40 */ s32 mEntryNum;
/* 0x44 */ SArcDataInfo* mArcInfoBlock;
/* 0x48 */ SDIDirEntry* mNodes;
/* 0x4C */ SDIFileEntry* mFiles;
/* 0x50 */ s32* mExpandedSize;
/* 0x54 */ char* mStringTable;
protected:
/* 0x58 */ u32 field_0x58;
/* 0x5C */ JKRCompression mCompression;
/* 0x60 */ EMountDirection mMountDirection;
public:
static JKRArchive* check_mount_already(s32, JKRHeap*);
static JKRArchive* mount(const char*, EMountMode, JKRHeap*, EMountDirection);
static JKRArchive* mount(void*, JKRHeap*, EMountDirection);
static JKRArchive* mount(s32, EMountMode, JKRHeap*, EMountDirection);
static void* getGlbResource(u32, const char*, JKRArchive*);
static JKRCompression convertAttrToCompressionType(u32 attr) {
#define JKRARCHIVE_ATTR_COMPRESSION 0x04
#define JKRARCHIVE_ATTR_YAY0 0x80
JKRCompression compression;
if (FLAG_ON(attr, JKRARCHIVE_ATTR_COMPRESSION)) {
compression = COMPRESSION_NONE;
} else if (!FLAG_ON(attr, JKRARCHIVE_ATTR_YAY0)) {
compression = COMPRESSION_YAZ0;
} else {
compression = COMPRESSION_YAY0;
}
return compression;
}
static u32 getCurrentDirID() { return sCurrentDirID; }
static void setCurrentDirID(u32 dirID) { sCurrentDirID = dirID; }
private:
static u32 sCurrentDirID;
};
inline JKRCompression JKRConvertAttrToCompressionType(u32 attr) {
return JKRArchive::convertAttrToCompressionType(attr);
}
inline void* JKRGetResource(u32 node, const char* path, JKRArchive* archive) {
return JKRArchive::getGlbResource(node, path, archive);
}
inline void* JKRGetTypeResource(u32 tag, const char* name, JKRArchive* arc) {
return JKRArchive::getGlbResource(tag, name, arc);
}
inline bool JKRRemoveResource(void* resource, JKRFileLoader* fileLoader) {
return JKRFileLoader::removeResource(resource, fileLoader);
}
inline JKRArchive* JKRMountArchive(void* ptr, JKRHeap* heap,
JKRArchive::EMountDirection mountDirection) {
return JKRArchive::mount(ptr, heap, mountDirection);
}
inline void JKRUnmountArchive(JKRArchive* arc) {
arc->unmount();
}
inline u32 JKRReadIdxResource(void* buffer, u32 bufsize, u32 resIdx, JKRArchive* archive) {
return archive->readIdxResource(buffer, bufsize, resIdx);
}
#endif