mirror of
https://github.com/SMGCommunity/Petari.git
synced 2025-02-16 12:09:49 +00:00
'Finished' JKRArchive
This commit is contained in:
parent
b61a9326b4
commit
61da1a2c60
@ -243,12 +243,12 @@ __dt__10JKRArchiveFv,JKRArchivePri.o,JKernel.a,true
|
||||
isSameName__10JKRArchiveCFRQ210JKRArchive8CArcNameUlUs,JKRArchivePri.o,JKernel.a,true
|
||||
findResType__10JKRArchiveCFUl,JKRArchivePri.o,JKernel.a,true
|
||||
findDirectory__10JKRArchiveCFPCcUl,JKRArchivePri.o,JKernel.a,false
|
||||
findTypeResource__10JKRArchiveCFUlPCc,JKRArchivePri.o,JKernel.a,false
|
||||
findTypeResource__10JKRArchiveCFUlPCc,JKRArchivePri.o,JKernel.a,true
|
||||
findFsResource__10JKRArchiveCFPCcUl,JKRArchivePri.o,JKernel.a,false
|
||||
findIdxResource__10JKRArchiveCFUl,JKRArchivePri.o,JKernel.a,false
|
||||
findNameResource__10JKRArchiveCFPCc,JKRArchivePri.o,JKernel.a,false
|
||||
findPtrResource__10JKRArchiveCFPCv,JKRArchivePri.o,JKernel.a,false
|
||||
findIdResource__10JKRArchiveCFUs,JKRArchivePri.o,JKernel.a,false
|
||||
findIdxResource__10JKRArchiveCFUl,JKRArchivePri.o,JKernel.a,true
|
||||
findNameResource__10JKRArchiveCFPCc,JKRArchivePri.o,JKernel.a,true
|
||||
findPtrResource__10JKRArchiveCFPCv,JKRArchivePri.o,JKernel.a,true
|
||||
findIdResource__10JKRArchiveCFUs,JKRArchivePri.o,JKernel.a,true
|
||||
store__Q210JKRArchive8CArcNameFPCc,JKRArchivePri.o,JKernel.a,false
|
||||
store__Q210JKRArchive8CArcNameFPCcc,JKRArchivePri.o,JKernel.a,false
|
||||
setExpandSize__10JKRArchiveFPQ210JKRArchive12SDIFileEntryUl,JKRArchivePri.o,JKernel.a,false
|
||||
|
|
@ -23,6 +23,16 @@ public:
|
||||
MOUNT_MODE_COMP = 4
|
||||
};
|
||||
|
||||
enum EFileFlag {
|
||||
FILE_FLAG_FILE = 1 << 0,
|
||||
FILE_FLAG_FOLDER = 1 << 1,
|
||||
FILE_FLAG_COMPRESSED = 1 << 2,
|
||||
FILE_FLAG_MRAM = 1 << 4,
|
||||
FILE_FLAG_ARAM = 1 << 5,
|
||||
FILE_FLAG_DVD = 1 << 6,
|
||||
FILE_FLAG_YAZ0 = 1 << 7
|
||||
};
|
||||
|
||||
struct RarcHeader {
|
||||
u32 mMagic; // _0
|
||||
u32 mFileSize; // _4
|
||||
@ -49,7 +59,8 @@ public:
|
||||
struct SDIFileEntry {
|
||||
u16 mFileID; // _0
|
||||
u16 mHash; // _2
|
||||
u32 mFlag; // _4
|
||||
u32 mFlag : 8; // _4
|
||||
u32 mNameOffset : 24; // _5
|
||||
union {
|
||||
u32 mDataOffset; // _8
|
||||
u32 mDirIndex; // _8
|
||||
@ -58,9 +69,6 @@ public:
|
||||
u32 mDataSize; // _C
|
||||
};
|
||||
void *mAllocatedData; // _10
|
||||
|
||||
u32 mTestFlag : 8;
|
||||
u32 mTestNameOffset : 24;
|
||||
};
|
||||
|
||||
struct SDirEntry {
|
||||
@ -89,8 +97,8 @@ public:
|
||||
|
||||
}
|
||||
|
||||
void store(const char *);
|
||||
void store(const char *, char);
|
||||
const char *store(const char *);
|
||||
const char *store(const char *, char);
|
||||
|
||||
u16 mHash; // _0
|
||||
u16 mLength; // _2
|
||||
|
@ -3,6 +3,56 @@
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef NON_MATCHING
|
||||
// tolower() is inlined
|
||||
const char *JKRArchive::CArcName::store(const char *pName) {
|
||||
mHash = 0;
|
||||
u32 length = 0;
|
||||
|
||||
for (; *pName != 0; pName++) {
|
||||
char lowerChar = tolower(*pName);
|
||||
|
||||
mHash = lowerChar + mHash * 3;
|
||||
|
||||
if (length < MAX_NAME_LENGTH) {
|
||||
mName[length++] = lowerChar;
|
||||
}
|
||||
}
|
||||
|
||||
mLength = static_cast<u16>(length);
|
||||
mName[length] = 0;
|
||||
|
||||
return &mLength[length];
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef NON_MATCHING
|
||||
// tolower() is inlined
|
||||
const char *JKRArchive::CArcName::store(const char *pName, char stopChar) {
|
||||
mHash = 0;
|
||||
u32 length = 0;
|
||||
|
||||
for (; *pName != stopChar; pName++) {
|
||||
char lowerChar = tolower(*pName);
|
||||
|
||||
mHash = lowerChar + mHash * 3;
|
||||
|
||||
if (length < MAX_NAME_LENGTH) {
|
||||
mName[length++] = lowerChar;
|
||||
}
|
||||
}
|
||||
|
||||
mLength = static_cast<u16>(length);
|
||||
mName[length] = 0;
|
||||
|
||||
if (*pName == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pName + 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
JKRArchive::JKRArchive() {
|
||||
_30 = false;
|
||||
_60 = 1;
|
||||
@ -31,108 +81,6 @@ JKRArchive::~JKRArchive() {
|
||||
|
||||
}
|
||||
|
||||
bool JKRArchive::isSameName(CArcName &rName, unsigned long nameOffset, unsigned short hash) const {
|
||||
if (rName.mHash != hash) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return strcmp(mStringTable + nameOffset, rName.mName) == 0;
|
||||
}
|
||||
|
||||
JKRArchive::SDirEntry *JKRArchive::findResType(unsigned long a1) const {
|
||||
SDirEntry *current = mDirs;
|
||||
|
||||
for (u32 i = 0; i < mInfoBlock->mNrDirs; i++) {
|
||||
if (current->mID == a1) {
|
||||
return current;
|
||||
}
|
||||
|
||||
current++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JKRArchive::SDirEntry *JKRArchive::findDirectory(const char *pName, unsigned long dirIndex) const {
|
||||
if (pName == NULL) {
|
||||
return &mDirs[dirIndex];
|
||||
}
|
||||
|
||||
CArcName name;
|
||||
name.store(pName, '/');
|
||||
|
||||
SDIFileEntry *current = &mFiles[mDirs[dirIndex].mFirstFileIndex];
|
||||
|
||||
for (u32 i = 0; i < mDirs[dirIndex].mNrFiles; i++) {
|
||||
//if (isSameName(name, current->mFlag & 0xFFFFFF, current->mHash)) {
|
||||
// if ((current->mTestFlag & 2) != 0) {
|
||||
// return NULL;
|
||||
// }
|
||||
//}
|
||||
|
||||
current++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef NON_MATCHING
|
||||
// tolower() is inlined
|
||||
void JKRArchive::CArcName::store(const char *pName) {
|
||||
mHash = 0;
|
||||
u32 length = 0;
|
||||
|
||||
for (; *pName != 0; pName++) {
|
||||
char lowerChar = tolower(*pName);
|
||||
|
||||
mHash = lowerChar + mHash * 3;
|
||||
|
||||
if (length < MAX_NAME_LENGTH) {
|
||||
mName[length++] = lowerChar;
|
||||
}
|
||||
}
|
||||
|
||||
mLength = static_cast<u16>(length);
|
||||
mName[length] = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef NON_MATCHING
|
||||
// tolower() is inlined
|
||||
void JKRArchive::CArcName::store(const char *pName, char stopChar) {
|
||||
mHash = 0;
|
||||
u32 length = 0;
|
||||
|
||||
for (; *pName != stopChar; pName++) {
|
||||
char lowerChar = tolower(*pName);
|
||||
|
||||
mHash = lowerChar + mHash * 3;
|
||||
|
||||
if (length < MAX_NAME_LENGTH) {
|
||||
mName[length++] = lowerChar;
|
||||
}
|
||||
}
|
||||
|
||||
mLength = static_cast<u16>(length);
|
||||
mName[length] = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef NON_MATCHING
|
||||
// blt ..., blr is optimized to bgelr
|
||||
void JKRArchive::setExpandSize(SDIFileEntry *pFile, unsigned long size) {
|
||||
@ -159,3 +107,177 @@ u32 JKRArchive::getExpandSize(SDIFileEntry *pFile) const {
|
||||
|
||||
return mExpandSizes[fileIndex];
|
||||
}
|
||||
|
||||
|
||||
bool JKRArchive::isSameName(CArcName &rName, unsigned long nameOffset, unsigned short hash) const {
|
||||
if (rName.mHash != hash) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return strcmp(mStringTable + nameOffset, rName.mName) == 0;
|
||||
}
|
||||
|
||||
JKRArchive::SDirEntry *JKRArchive::findResType(unsigned long a1) const {
|
||||
SDirEntry *current = mDirs;
|
||||
|
||||
for (u32 i = 0; i < mInfoBlock->mNrDirs; i++) {
|
||||
if (current->mID == a1) {
|
||||
return current;
|
||||
}
|
||||
|
||||
current++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef NON_MATCHING
|
||||
// Register mismatch
|
||||
JKRArchive::SDirEntry *JKRArchive::findDirectory(const char *pName, unsigned long dirIndex) const {
|
||||
SDirEntry *dir;
|
||||
SDIFileEntry *currentFile;
|
||||
s32 i;
|
||||
|
||||
if (pName == NULL) {
|
||||
return &mDirs[dirIndex];
|
||||
}
|
||||
|
||||
CArcName name;
|
||||
const char *next = name.store(pName, '/');
|
||||
|
||||
dir = &mDirs[dirIndex];
|
||||
currentFile = &mFiles[dir->mFirstFileIndex];
|
||||
|
||||
for (i = 0; i < dir->mNrFiles; i++) {
|
||||
if (isSameName(name, currentFile->mNameOffset, currentFile->mHash)) {
|
||||
if ((currentFile->mFlag & FILE_FLAG_FOLDER) != 0) {
|
||||
return findDirectory(next, currentFile->mDirIndex);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
currentFile++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
JKRArchive::SDIFileEntry *JKRArchive::findTypeResource(unsigned long a1, const char *pName) const {
|
||||
if (a1 != 0) {
|
||||
CArcName name;
|
||||
name.store(pName);
|
||||
|
||||
SDirEntry *dir = findResType(a1);
|
||||
|
||||
if (dir != NULL) {
|
||||
SDIFileEntry *current = &mFiles[dir->mFirstFileIndex];
|
||||
|
||||
for (s32 i = 0; i < dir->mNrFiles; i++) {
|
||||
if (isSameName(name, current->mNameOffset, current->mHash)) {
|
||||
return current;
|
||||
}
|
||||
|
||||
current++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef NON_MATCHING
|
||||
// Register mismatch
|
||||
JKRArchive::SDIFileEntry *JKRArchive::findFsResource(const char *pName, unsigned long dirIndex) const {
|
||||
if (pName != NULL) {
|
||||
SDirEntry *dir;
|
||||
SDIFileEntry *currentFile;
|
||||
s32 i;
|
||||
|
||||
CArcName name;
|
||||
const char *next = name.store(pName, '/');
|
||||
|
||||
dir = &mDirs[dirIndex];
|
||||
currentFile = &mFiles[dir->mFirstFileIndex];
|
||||
|
||||
for (s32 i = 0; i < dir->mNrFiles; i++) {
|
||||
if (isSameName(name, currentFile->mNameOffset, currentFile->mHash)) {
|
||||
if ((currentFile->mFlag & FILE_FLAG_FOLDER) != 0) {
|
||||
return findFsResource(next, currentFile->mDirIndex);
|
||||
}
|
||||
else if (next == NULL) {
|
||||
return currentFile;
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
currentFile++;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
JKRArchive::SDIFileEntry *JKRArchive::findIdxResource(unsigned long index) const {
|
||||
if (index < mInfoBlock->mNrFiles) {
|
||||
return &mFiles[index];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JKRArchive::SDIFileEntry *JKRArchive::findNameResource(const char *pName) const {
|
||||
SDIFileEntry *current = mFiles;
|
||||
|
||||
CArcName name;
|
||||
name.store(pName);
|
||||
|
||||
for (s32 i = 0; i < mInfoBlock->mNrFiles; i++) {
|
||||
if (isSameName(name, current->mNameOffset, current->mHash)) {
|
||||
return current;
|
||||
}
|
||||
|
||||
current++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JKRArchive::SDIFileEntry *JKRArchive::findPtrResource(const void *pResource) const {
|
||||
SDIFileEntry *current = mFiles;
|
||||
|
||||
for (s32 i = 0; i < mInfoBlock->mNrFiles; i++) {
|
||||
if (current->mAllocatedData == pResource) {
|
||||
return current;
|
||||
}
|
||||
|
||||
current++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JKRArchive::SDIFileEntry *JKRArchive::findIdResource(unsigned short fileID) const {
|
||||
if (fileID != 0xFFFF) {
|
||||
SDIFileEntry *current = mFiles;
|
||||
SDIFileEntry *indexed = &mFiles[fileID];
|
||||
|
||||
if (indexed->mFileID == fileID && (indexed->mFlag & FILE_FLAG_FILE) != 0) {
|
||||
return indexed;
|
||||
}
|
||||
|
||||
for (s32 i = 0; i < mInfoBlock->mNrFiles; i++) {
|
||||
if (current->mFileID == fileID && (current->mFlag & FILE_FLAG_FILE) != 0) {
|
||||
return current;
|
||||
}
|
||||
|
||||
current++;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -276,9 +276,9 @@ bool JKRArchive::getDirEntry(SDirEntry *pDir, unsigned long fileIndex) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
pDir->_0.mFileFlag = static_cast<u8>(file->mFlag >> 24);
|
||||
pDir->_0.mFileFlag = file->mFlag;
|
||||
pDir->_0.mFileID = file->mFileID;
|
||||
pDir->mName = mStringTable + (file->mFlag & 0xFFFFFF);
|
||||
pDir->mName = mStringTable + file->mNameOffset;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -320,7 +320,7 @@ u32 JKRArchive::countResource() const {
|
||||
u32 count = 0;
|
||||
|
||||
for (u32 i = 0; i < mInfoBlock->mNrFiles; i++) {
|
||||
if (((mFiles[i].mFlag >> 24) & 1) != 0) {
|
||||
if ((mFiles[i].mFlag & FILE_FLAG_FILE) != 0) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
@ -332,7 +332,7 @@ u32 JKRArchive::getFileAttribute(unsigned long fileIndex) const {
|
||||
SDIFileEntry *file = findIdxResource(fileIndex);
|
||||
|
||||
if (file != NULL) {
|
||||
return file->mFlag >> 24;
|
||||
return file->mFlag;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user