mirror of
https://github.com/ACreTeam/ac-decomp
synced 2026-06-08 11:47:05 -04:00
Add & Link JKernel (#142)
* match and link JKRAram.cpp * match and link JKRExpHeap * match and link JKRAramStream.cpp * match and link JKRFileLoader.cpp * match and link JKRFileFinder.cpp * JKernel Dump * match and link JKRAramArchive.cpp * match and link JKRDvdArchive.cpp * match and link JKRCompArchive.cpp * match but not link JKRDvdAramRipper * small refactors * match and link JKRThread.cpp * fix and link JKRDvdAramStream.cpp * Formatting fixes --------- Co-authored-by: SwareJonge <olaf23okken@gmail.com>
This commit is contained in:
+66
-8
@@ -1,3 +1,5 @@
|
||||
ctors.s:
|
||||
.ctors: [0x800a97b4, 0x800a97c0] # remove trailing 0s from ctor area
|
||||
#dolphin/os/__start.c:
|
||||
# .init: [0x80003100, 0x80003354]
|
||||
dolphin/__ppc_eabi_init.cpp:
|
||||
@@ -114,18 +116,29 @@ JSystem/JKernel/JKRHeap.cpp:
|
||||
.data: [0x800ddf20, 0x800ddf98]
|
||||
.sdata: [0x80217e58, 0x80217e80]
|
||||
.sbss: [0x802186d8, 0x80218700]
|
||||
JSystem/JKernel/JKRExpHeap.cpp:
|
||||
.text: [0x80064028, 0x80065aa0]
|
||||
.data: [0x800ddf98, 0x800de3a8]
|
||||
.sdata: [0x80217e80, 0x80217ec0]
|
||||
.sbss: [0x80218700, 0x80218720]
|
||||
.sdata2: [0x80219278, 0x80219288]
|
||||
JSystem/JKernel/JKRDisposer.cpp:
|
||||
.text: [0x80065aa0, 0x80065b8c]
|
||||
.data: [0x800de3a8, 0x800de3c0]
|
||||
.sdata: [0x80217ec0, 0x80217ec8]
|
||||
#JSystem/JKernel/JKRThread.cpp: # JKRThread linkage disabled until we can resolve the order of RTTI strings in .data
|
||||
# .text: [0x80065b8c, 0x80065ef0]
|
||||
# .ctors: [0x800a978c, 0x800a9790]
|
||||
# .data: [0x800de3c0, 0x800de3f8]
|
||||
# .bss: [0x80207008, 0x80207020]
|
||||
# .sdata: [0x80217ec8, 0x80217ed8]
|
||||
JSystem/JKernel/JKRThread2.cpp: # This exists to fix ordering. It is a hack. AC was likely compiled with CW GC 1.3.
|
||||
.text: [0x80065ef0, 0x80065ef8]
|
||||
JSystem/JKernel/JKRThread.cpp:
|
||||
.text: [0x80065b8c, 0x80065ef0]
|
||||
.ctors: [0x800a978c, 0x800a9790]
|
||||
.data: [0x800de3c0, 0x800de3f8]
|
||||
.bss: [0x80207008, 0x80207020]
|
||||
.sdata: [0x80217ec8, 0x80217ed8]
|
||||
JSystem/JKernel/JKRAram.cpp:
|
||||
.text: [0x80065ef8, 0x80066e84]
|
||||
.ctors: [0x800a9790, 0x800a9794]
|
||||
.data: [0x800de3f8, 0x800de4c0]
|
||||
.bss: [0x80207020, 0x80207038]
|
||||
.sdata: [0x80217ed8, 0x80217ef8]
|
||||
.sbss: [0x80218720, 0x80218758]
|
||||
JSystem/JKernel/JKRAramHeap.cpp:
|
||||
.text: [0x80066e84, 0x80067258]
|
||||
.ctors: [0x800a9794, 0x800a9798]
|
||||
@@ -142,6 +155,45 @@ JSystem/JKernel/JKRAramPiece.cpp:
|
||||
.data: [0x800de510, 0x800de568]
|
||||
.bss: [0x80207050, 0x80207080]
|
||||
.sdata: [0x80217f10, 0x80217f18]
|
||||
JSystem/JKernel/JKRAramStream.cpp:
|
||||
.text: [0x80067a88, 0x80067ff4]
|
||||
.data: [0x800de568, 0x800de608]
|
||||
.sdata: [0x80217f18, 0x80217f38]
|
||||
.sbss: [0x80218758, 0x80218768]
|
||||
JSystem/JKernel/JKRFileLoader.cpp:
|
||||
.text: [0x80067ff4, 0x800685b0]
|
||||
.ctors: [0x800a979c, 0x800a97a0]
|
||||
.data: [0x800de608, 0x800de670]
|
||||
.bss: [0x80207080, 0x80207098]
|
||||
.sdata: [0x80217f38, 0x80217f50]
|
||||
.sbss: [0x80218768, 0x80218770]
|
||||
JSystem/JKernel/JKRFileFinder.cpp:
|
||||
.text: [0x800685b0, 0x80068744]
|
||||
.data: [0x800de670, 0x800de6b0]
|
||||
.sdata: [0x80217f50, 0x80217f60]
|
||||
JSystem/JKernel/JKRArchivePub.cpp:
|
||||
.text: [0x80068744, 0x80068ed0]
|
||||
.data: [0x800de6b0, 0x800de740]
|
||||
.sdata: [0x80217f60, 0x80217f78]
|
||||
JSystem/JKernel/JKRArchivePri.cpp:
|
||||
.text: [0x80068ed0, 0x80069530]
|
||||
.sbss: [0x80218770, 0x80218778]
|
||||
JSystem/JKernel/JKRMemArchive.cpp:
|
||||
.text: [0x80069530, 0x80069a28]
|
||||
.data: [0x800de740, 0x800de828]
|
||||
.sdata: [0x80217f78, 0x80217f98]
|
||||
JSystem/JKernel/JKRAramArchive.cpp:
|
||||
.text: [0x80069a28, 0x8006a4fc]
|
||||
.data: [0x800de828, 0x800de938]
|
||||
.sdata: [0x80217f98, 0x80217fc8]
|
||||
JSystem/JKernel/JKRDvdArchive.cpp:
|
||||
.text: [0x8006a4fc, 0x8006add0]
|
||||
.data: [0x800de938, 0x800dea70]
|
||||
.sdata: [0x80217fc8, 0x80217fe8]
|
||||
JSystem/JKernel/JKRCompArchive.cpp:
|
||||
.text: [0x8006add0, 0x8006b8a4]
|
||||
.data: [0x800dea70, 0x800deba8]
|
||||
.sdata: [0x80217fe8, 0x80218008]
|
||||
JSystem/JKernel/JKRDvdFile.cpp:
|
||||
.text: [0x8006b8a4, 0x8006be0c]
|
||||
.ctors: [0x800a97a0, 0x800a97a4]
|
||||
@@ -155,6 +207,12 @@ JSystem/JKernel/JKRDvdRipper.cpp:
|
||||
.bss: [0x802070b0, 0x802070c8]
|
||||
.sdata: [0x80218028, 0x80218030]
|
||||
.sbss: [0x80218778, 0x802187a8]
|
||||
JSystem/JKernel/JKRDvdAramRipper.cpp:
|
||||
.text: [0x8006c8fc, 0x8006d608]
|
||||
.ctors: [0x800a97a8, 0x800a97ac]
|
||||
.bss: [0x802070c8, 0x802070e0]
|
||||
.sdata: [0x80218030, 0x80218038]
|
||||
.sbss: [0x802187a8, 0x802187e8]
|
||||
JSystem/JKernel/JKRDecomp.cpp:
|
||||
.text: [0x8006d608, 0x8006dd58]
|
||||
.data: [0x800dec90, 0x800ded18]
|
||||
|
||||
@@ -5,9 +5,11 @@
|
||||
#include "dolphin/ar.h"
|
||||
#include "dolphin/os/OSMessage.h"
|
||||
#include "JSystem/JKernel/JKRDisposer.h"
|
||||
#include "JSystem/JKernel/JKREnum.h"
|
||||
#include "JSystem/JKernel/JKRHeap.h"
|
||||
#include "JSystem/JKernel/JKRThread.h"
|
||||
#include "JSystem/JSupport/JSUList.h"
|
||||
#include "JSystem/JSupport/JSUStream.h"
|
||||
|
||||
#define ARAM_GROUP_ID_ALL 0
|
||||
#define ARAM_GROUP_ID_DEFAULT 0xFF
|
||||
@@ -22,7 +24,9 @@ class JKRAramHeap;
|
||||
class JKRDecompCommand;
|
||||
class JKRAMCommand;
|
||||
|
||||
class JKRAramBlock {
|
||||
class JKRAramBlock
|
||||
{
|
||||
public:
|
||||
JKRAramBlock(u32 address, u32 size, u32 freeSize, u8 groupID, bool tempMemory);
|
||||
|
||||
virtual ~JKRAramBlock();
|
||||
@@ -46,33 +50,11 @@ class JKRAramBlock {
|
||||
friend class JKRAramHeap;
|
||||
};
|
||||
|
||||
class JKRAram : public JKRThread {
|
||||
class JKRAramHeap : public JKRDisposer
|
||||
{
|
||||
public:
|
||||
JKRAram(u32, u32, s32);
|
||||
|
||||
virtual ~JKRAram();
|
||||
virtual void* run();
|
||||
|
||||
static JKRAram* sAramObject;
|
||||
static const OSMessageQueue sMessageQueue;
|
||||
static JSUList<JKRAMCommand> sAramCommandList;
|
||||
static u32 sSZSBufferSize;
|
||||
static OSMessage sMessageBuffer[ARAM_MESGBUF_COUNT];
|
||||
|
||||
private:
|
||||
u32 mAudioMemoryPtr;
|
||||
u32 mAudioMemorySize;
|
||||
u32 mGraphMemoryPtr;
|
||||
u32 mGraphMemorySize;
|
||||
u32 mAramMemoryPtr;
|
||||
u32 mAramMemorySize;
|
||||
JKRAramHeap* mAramHeap;
|
||||
u32 mBlockLength;
|
||||
u8 _9C[4];
|
||||
};
|
||||
|
||||
class JKRAramHeap : public JKRDisposer {
|
||||
enum EAllocMode {
|
||||
enum EAllocMode
|
||||
{
|
||||
Head = 0,
|
||||
Tail = 1
|
||||
};
|
||||
@@ -108,7 +90,77 @@ class JKRAramHeap : public JKRDisposer {
|
||||
friend class JKRAramBlock;
|
||||
};
|
||||
|
||||
class JKRAMCommand : public ARQRequest {
|
||||
class JKRAram : public JKRThread
|
||||
{
|
||||
public:
|
||||
JKRAram(u32, u32, long);
|
||||
|
||||
virtual ~JKRAram(); // _08
|
||||
virtual void* run(); // _0C
|
||||
|
||||
static bool checkOkAddress(u8* addr, u32 size, JKRAramBlock* block, u32 param_4);
|
||||
static void changeGroupIdIfNeed(u8* data, int groupId);
|
||||
|
||||
static JKRAram* create(u32, u32, long, long, long);
|
||||
static JKRAramBlock* mainRamToAram(u8*, u32, u32, JKRExpandSwitch, u32, JKRHeap*, int);
|
||||
static JKRAramBlock* mainRamToAram(u8*, JKRAramBlock* block, u32, JKRExpandSwitch, u32, JKRHeap*, int);
|
||||
static u8* aramToMainRam(u32, u8*, u32, JKRExpandSwitch, u32, JKRHeap*, int, u32*);
|
||||
static u8* aramToMainRam(JKRAramBlock*, u8*, u32, u32, JKRExpandSwitch, u32, JKRHeap*, int, u32*);
|
||||
|
||||
void aramSync(JKRAMCommand*, int);
|
||||
|
||||
u32 getAudioMemory() const
|
||||
{
|
||||
return mAudioMemoryPtr;
|
||||
}
|
||||
|
||||
u32 getAudioMemSize() const
|
||||
{
|
||||
return mAudioMemorySize;
|
||||
}
|
||||
|
||||
static u32 getSZSBufferSize()
|
||||
{
|
||||
return sSZSBufferSize;
|
||||
}
|
||||
|
||||
static JKRAramHeap* getAramHeap()
|
||||
{
|
||||
return sAramObject->mAramHeap;
|
||||
}
|
||||
|
||||
static JKRAram* getManager()
|
||||
{
|
||||
return sAramObject;
|
||||
}
|
||||
|
||||
static u8 decideAramGroupId(int id)
|
||||
{
|
||||
if (id < 0)
|
||||
return getAramHeap()->getCurrentGroupID();
|
||||
else
|
||||
return id;
|
||||
}
|
||||
|
||||
static u32 sSZSBufferSize;
|
||||
|
||||
static JKRAram* sAramObject;
|
||||
static OSMessage sMessageBuffer[4];
|
||||
static OSMessageQueue sMessageQueue;
|
||||
static JSUList<JKRAMCommand> sAramCommandList;
|
||||
|
||||
u32 mAudioMemoryPtr; // _7C
|
||||
u32 mAudioMemorySize; // _80
|
||||
u32 mGraphMemoryPtr; // _84
|
||||
u32 mGraphMemorySize; // _88
|
||||
u32 mUserMemoryPtr; // _8C
|
||||
u32 mUserMemorySize; // _90
|
||||
JKRAramHeap* mAramHeap; // _94
|
||||
u32 mStackArray[3]; // _98
|
||||
};
|
||||
|
||||
class JKRAMCommand : public ARQRequest
|
||||
{
|
||||
public:
|
||||
typedef void (*AMCommandCallback)(u32);
|
||||
|
||||
@@ -134,9 +186,11 @@ public:
|
||||
void* _94;
|
||||
};
|
||||
|
||||
class JKRAramCommand {
|
||||
class JKRAramCommand
|
||||
{
|
||||
public:
|
||||
inline void setting(BOOL active, void* arg) {
|
||||
inline void setting(BOOL active, void* arg)
|
||||
{
|
||||
this->mActive = active;
|
||||
this->mArg = arg;
|
||||
}
|
||||
@@ -145,7 +199,8 @@ public:
|
||||
void* mArg;
|
||||
};
|
||||
|
||||
class JKRAramPiece {
|
||||
class JKRAramPiece
|
||||
{
|
||||
public:
|
||||
static JKRAMCommand* prepareCommand(int direction, u32 source, u32 destination, u32 length, JKRAramBlock* aramBlock, JKRAMCommand::AMCommandCallback callback);
|
||||
static void sendCommand(JKRAMCommand* cmd);
|
||||
@@ -163,12 +218,97 @@ private:
|
||||
static void unlock() { OSUnlockMutex(&mMutex); }
|
||||
};
|
||||
|
||||
inline bool JKRAramPcs(int direction, u32 source, u32 destination, u32 length, JKRAramBlock* block) {
|
||||
class JKRAramStreamCommand
|
||||
{
|
||||
public:
|
||||
enum ECommandType
|
||||
{
|
||||
ECT_UNK = 0,
|
||||
ECT_READ = 1,
|
||||
ECT_WRITE = 2,
|
||||
};
|
||||
|
||||
JKRAramStreamCommand();
|
||||
|
||||
ECommandType type; // _00
|
||||
u32 mAddress; // _04
|
||||
u32 mSize; // _08
|
||||
u32 _0C; // _0C
|
||||
JSUFileInputStream* mStream; // _10
|
||||
u32 mOffset; // _14
|
||||
u8* mTransferBuffer; // _18
|
||||
u32 mTransferBufferSize; // _1C
|
||||
JKRHeap* mHeap; // _20
|
||||
bool mAllocatedTransferBuffer; // _24
|
||||
u32 _28; // _28
|
||||
OSMessageQueue mMessageQueue; // _2C
|
||||
void* mMessage; // _4C
|
||||
u32 _50; // _50
|
||||
u32 _54; // _54
|
||||
};
|
||||
|
||||
class JKRAramStream : public JKRThread
|
||||
{
|
||||
public:
|
||||
JKRAramStream(long);
|
||||
|
||||
virtual ~JKRAramStream(); // _08
|
||||
virtual void* run(); // _0C
|
||||
|
||||
static JKRAramStream* create(s32);
|
||||
|
||||
static u32 readFromAram();
|
||||
static s32 writeToAram(JKRAramStreamCommand*);
|
||||
static JKRAramStreamCommand* write_StreamToAram_Async(JSUFileInputStream*, JKRAramBlock*, u32, u32);
|
||||
static JKRAramStreamCommand* write_StreamToAram_Async(JSUFileInputStream*, u32, u32, u32);
|
||||
static JKRAramStreamCommand* sync(JKRAramStreamCommand*, BOOL);
|
||||
static void setTransBuffer(u8*, u32, JKRHeap*);
|
||||
|
||||
static JKRAramStream* sAramStreamObject;
|
||||
static OSMessage sMessageBuffer[4];
|
||||
static OSMessageQueue sMessageQueue;
|
||||
|
||||
static u8* transBuffer;
|
||||
static JKRHeap* transHeap;
|
||||
static u32 transSize;
|
||||
|
||||
// _00 = VTBL
|
||||
// _00-_7C = JKRThread
|
||||
};
|
||||
|
||||
inline JKRAramBlock* JKRAllocFromAram(u32 size, JKRAramHeap::EAllocMode allocMode)
|
||||
{
|
||||
return JKRAram::getAramHeap()->alloc(size, allocMode);
|
||||
}
|
||||
|
||||
inline void JKRFreeToAram(JKRAramBlock* block)
|
||||
{
|
||||
JKRAram::getAramHeap()->free(block);
|
||||
}
|
||||
|
||||
inline u8* JKRAramToMainRam(u32 address, u8* buf, u32 bufSize, JKRExpandSwitch expandSwitch, u32 p5, JKRHeap* heap, int id, u32* pSize)
|
||||
{
|
||||
JKRAram::aramToMainRam(address, buf, bufSize, expandSwitch, p5, heap, id, pSize);
|
||||
}
|
||||
|
||||
inline JKRAramBlock* JKRMainRamToAram(u8* buf, u32 bufSize, u32 alignedSize, JKRExpandSwitch expandSwitch, u32 fileSize, JKRHeap* heap, int id, u32)
|
||||
{
|
||||
return JKRAram::mainRamToAram(buf, bufSize, alignedSize, expandSwitch, fileSize, heap, id);
|
||||
}
|
||||
|
||||
inline JKRAramStream* JKRCreateAramStreamManager(s32 priority)
|
||||
{
|
||||
return JKRAramStream::create(priority);
|
||||
}
|
||||
|
||||
inline bool JKRAramPcs(int direction, u32 source, u32 destination, u32 length, JKRAramBlock* block)
|
||||
{
|
||||
return JKRAramPiece::orderSync(direction, source, destination, length, block);
|
||||
}
|
||||
|
||||
inline void JKRAramPcs_SendCommand(JKRAMCommand* cmd) {
|
||||
inline void JKRAramPcs_SendCommand(JKRAMCommand* cmd)
|
||||
{
|
||||
JKRAramPiece::sendCommand(cmd);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,342 @@
|
||||
#ifndef JKRARCHIVE_H_
|
||||
#define JKRARCHIVE_H_
|
||||
|
||||
#include "JSystem/JKernel/JKRDvdFile.h"
|
||||
#include "JSystem/JKernel/JKRFileLoader.h"
|
||||
#include "JSystem/JKernel/JKRHeap.h"
|
||||
#include "types.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 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**);
|
||||
|
||||
// Unused/inlined:
|
||||
unknown fixedInit(s32, EMountDirection);
|
||||
unknown mountFixed(s32, EMountDirection);
|
||||
unknown mountFixed(const char*, EMountDirection);
|
||||
unknown unmountFixed();
|
||||
|
||||
// _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
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "types.h"
|
||||
#include "dolphin/os/OSMessage.h"
|
||||
#include "JSystem/JKernel/JKRDvdFile.h"
|
||||
#include "JSystem/JKernel/JKRThread.h"
|
||||
#include "JSystem/JKernel/JKRAram.h"
|
||||
|
||||
@@ -78,6 +79,14 @@ inline JKRDecomp* JKRCreateDecompManager(s32 priority) {
|
||||
return JKRDecomp::create(priority);
|
||||
}
|
||||
|
||||
inline int JKRCheckCompressed_noASR(u8* pBuf)
|
||||
{
|
||||
int compression = JKRDecomp::checkCompressed(pBuf);
|
||||
if (compression == JKRCOMPRESSION_ASR)
|
||||
compression = JKRCOMPRESSION_NONE;
|
||||
return compression;
|
||||
}
|
||||
|
||||
inline JKRDecomp::CompressionMode JKRCheckCompressed(u8* buf) {
|
||||
return JKRDecomp::checkCompressed(buf);
|
||||
}
|
||||
@@ -90,4 +99,8 @@ inline void JKRDecompress(u8* src, u8* dst, u32 srcLength, u32 skipCount) {
|
||||
JKRDecomp::orderSync(src, dst, srcLength, skipCount);
|
||||
}
|
||||
|
||||
int JKRDecompressFromDVD(JKRDvdFile* srcFile, void* buf, u32 size, u32 maxDest, u32 fileOffset, u32 srcOffset);
|
||||
int JKRDecompressFromDVDToAram(JKRDvdFile* srcFile, u32 address, u32 fileSize, u32 maxDest, u32 fileOffset, u32 srcOffset);
|
||||
int JKRDecompressFromAramToMainRam(u32 srcAddress, void* dst, u32 fileSize, u32 maxDest, u32 fileOffset);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -14,8 +14,8 @@ public:
|
||||
virtual ~JKRDisposer();
|
||||
|
||||
public:
|
||||
JKRHeap *mRootHeap; // _4
|
||||
JKRHeap* mRootHeap; // _4
|
||||
JSULink<JKRDisposer> mPointerLinks; // _8
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
#ifndef JKRDVDARAMRIPPER_H
|
||||
#define JKRDVDARAMRIPPER_H
|
||||
|
||||
#include "JSystem/JKernel/JKRAram.h"
|
||||
#include "JSystem/JKernel/JKRDvdFile.h"
|
||||
#include "JSystem/JSupport/JSUList.h"
|
||||
#include "types.h"
|
||||
|
||||
class JKRADCommand
|
||||
{
|
||||
public:
|
||||
typedef void (*LoadCallback)(u32);
|
||||
JKRADCommand();
|
||||
~JKRADCommand();
|
||||
|
||||
// Fields might need more swapping
|
||||
JSULink<JKRADCommand> mLink;
|
||||
JKRDvdFile* mDvdFile; // _28
|
||||
u32 _14; // _14
|
||||
u32 _18; // _18, probably size
|
||||
u32 _1C; // _1C
|
||||
JKRAramBlock* mBlock; // _20
|
||||
JKRExpandSwitch mExpandSwitch; // _24
|
||||
u8 _28[0x10]; // _28 - unknown/padding
|
||||
u32* _3C; // _3C
|
||||
s32 _40; // _40
|
||||
LoadCallback mCallBack; // _40
|
||||
u8 _44; // _44
|
||||
JKRAramStreamCommand* mStreamCommand; // _48
|
||||
};
|
||||
|
||||
class JKRDvdAramRipper
|
||||
{
|
||||
public:
|
||||
static JKRAramBlock* loadToAram(char const*, u32, JKRExpandSwitch, u32, u32);
|
||||
static JKRAramBlock* loadToAram(s32, u32, JKRExpandSwitch, u32, u32);
|
||||
static JKRAramBlock* loadToAram(JKRDvdFile*, u32, JKRExpandSwitch, u32, u32);
|
||||
static JKRADCommand* loadToAram_Async(JKRDvdFile*, u32, JKRExpandSwitch, JKRADCommand::LoadCallback, u32, u32);
|
||||
static JKRADCommand* callCommand_Async(JKRADCommand*);
|
||||
static bool syncAram(JKRADCommand*, int);
|
||||
|
||||
// unused/inlined:
|
||||
static JKRADCommand* loadToAram_Async(const char*, u32, JKRExpandSwitch, JKRADCommand::LoadCallback, u32, u32);
|
||||
static JKRADCommand* loadToAram_Async(s32, u32, JKRExpandSwitch, JKRADCommand::LoadCallback, u32, u32);
|
||||
static void syncAramAll(int);
|
||||
static void countLeftSync();
|
||||
static void afterAramAsync(JKRADCommand*);
|
||||
|
||||
static int getSZSBufferSize() { return sSZSBufferSize; }
|
||||
static bool isErrorRetry() { return errorRetry; }
|
||||
|
||||
static bool errorRetry;
|
||||
static int sSZSBufferSize;
|
||||
static JSUList<JKRADCommand> sDvdAramAsyncList;
|
||||
};
|
||||
|
||||
inline JKRAramBlock* JKRDvdToAram(s32 entrynum, u32 p2, JKRExpandSwitch expSwitch, u32 p4, u32 p5)
|
||||
{
|
||||
return JKRDvdAramRipper::loadToAram(entrynum, p2, expSwitch, p4, p5);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef JKRDVDFILE_H
|
||||
#define JKRDVDFILE_H
|
||||
|
||||
#include "JSystem/JKernel/JKRAram.h"
|
||||
#include "JSystem/JKernel/JKRFile.h"
|
||||
#include "JSystem/JSupport/JSUStream.h"
|
||||
|
||||
@@ -30,22 +31,22 @@ public:
|
||||
}
|
||||
|
||||
inline int readDataAsync(void* addr, s32 length, s32 offset) {
|
||||
OSLockMutex(&this->mMutex1);
|
||||
OSLockMutex(&this->mDvdMutex);
|
||||
s32 retAddr;
|
||||
|
||||
if (this->mThread2 != nullptr) {
|
||||
OSUnlockMutex(&this->mMutex1);
|
||||
if (this->mDvdThread != nullptr) {
|
||||
OSUnlockMutex(&this->mDvdMutex);
|
||||
retAddr = -1;
|
||||
}
|
||||
else {
|
||||
this->mThread2 = OSGetCurrentThread();
|
||||
this->mDvdThread = OSGetCurrentThread();
|
||||
retAddr = -1;
|
||||
if (DVDReadAsync(&this->mDvdFileInfo, addr, length, offset, JKRDvdFile::doneProcess)) {
|
||||
retAddr = this->sync();
|
||||
}
|
||||
|
||||
this->mThread2 = nullptr;
|
||||
OSUnlockMutex(&this->mMutex1);
|
||||
this->mDvdThread = nullptr;
|
||||
OSUnlockMutex(&this->mDvdMutex);
|
||||
}
|
||||
|
||||
return retAddr;
|
||||
@@ -60,20 +61,20 @@ public:
|
||||
|
||||
static JSUList<JKRDvdFile> sDvdList;
|
||||
|
||||
protected:
|
||||
OSMutex mMutex1;
|
||||
OSMutex mMutex2;
|
||||
public:
|
||||
OSMutex mDvdMutex;
|
||||
OSMutex mAramMutex;
|
||||
JKRAramBlock* mAramBlock;
|
||||
OSThread* mThread1;
|
||||
OSThread* mAramThread;
|
||||
JSUFileInputStream* mInputStream;
|
||||
u32 _58;
|
||||
JKRDvdFileInfo mDvdFileInfo;
|
||||
OSMessageQueue mMessageQueue1;
|
||||
OSMessage mMsg1;
|
||||
OSMessageQueue mMessageQueue2;
|
||||
OSMessage mMsg2;
|
||||
OSMessageQueue mAramMessageQueue;
|
||||
OSMessage mAramMessage;
|
||||
OSMessageQueue mDvdMessageQueue;
|
||||
OSMessage mDvdMessage;
|
||||
JSULink<JKRDvdFile> mLink;
|
||||
OSThread* mThread2;
|
||||
OSThread* mDvdThread;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,12 +7,18 @@
|
||||
|
||||
#define SZP_BUFFERSIZE 1024
|
||||
#define REF_BUFFERSIZE 0x1120
|
||||
#define DMA_BUFFERSIZE 0x100
|
||||
|
||||
struct SZPHeader {
|
||||
u32 magic;
|
||||
u32 decompSize;
|
||||
};
|
||||
|
||||
struct SYaz0Header {
|
||||
u32 signature;
|
||||
u32 length;
|
||||
};
|
||||
|
||||
class JKRDMCommand {
|
||||
JKRDMCommand();
|
||||
~JKRDMCommand();
|
||||
@@ -37,6 +43,14 @@ public:
|
||||
static bool errorRetry;
|
||||
};
|
||||
|
||||
static int JKRDecompressFromDVD(JKRDvdFile* srcFile, void* buf, u32 size, u32 maxDest, u32 fileOffset, u32 srcOffset);
|
||||
inline void* JKRDvdToMainRam(long entryNum, u8* dst, JKRExpandSwitch expandSwitch, u32 fileSize, JKRHeap* heap, JKRDvdRipper::EAllocDirection allocDirection, u32 startOffset, int* pCompression)
|
||||
{
|
||||
return JKRDvdRipper::loadToMainRAM(entryNum, dst, expandSwitch, fileSize, heap, allocDirection, startOffset, pCompression);
|
||||
}
|
||||
|
||||
inline void* JKRDvdToMainRam(const char* path, u8* dst, JKRExpandSwitch expandSwitch, u32 fileSize, JKRHeap* heap, JKRDvdRipper::EAllocDirection allocDirection, u32 startOffset, int* pCompression)
|
||||
{
|
||||
return JKRDvdRipper::loadToMainRAM(path, dst, expandSwitch, fileSize, heap, allocDirection, startOffset, pCompression);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,10 +7,16 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum JKRExpandSwitch {
|
||||
EXPAND_SWITCH_DEFAULT, /* Do nothing? treated same as 2 */
|
||||
#define JKRCOMPRESSION_NONE 0
|
||||
#define JKRCOMPRESSION_YAY0 1
|
||||
#define JKRCOMPRESSION_YAZ0 2
|
||||
#define JKRCOMPRESSION_ASR 3
|
||||
|
||||
typedef enum JKRExpandSwitch
|
||||
{
|
||||
EXPAND_SWITCH_DEFAULT, /* Do nothing? treated same as 2 */
|
||||
EXPAND_SWITCH_DECOMPRESS, /* Check for compression and decompress */
|
||||
EXPAND_SWITCH_NONE /* Do nothing */
|
||||
EXPAND_SWITCH_NONE /* Do nothing */
|
||||
} JKRExpandSwitch;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
#ifndef JKREXPHEAP_H
|
||||
#define JKREXPHEAP_H
|
||||
|
||||
#include "JSystem/JKernel/JKRHeap.h"
|
||||
#include "types.h"
|
||||
|
||||
class JKRExpHeap : public JKRHeap
|
||||
{
|
||||
public:
|
||||
class CMemBlock
|
||||
{
|
||||
public:
|
||||
CMemBlock* allocBack(u32, u8, u8, u8, u8);
|
||||
CMemBlock* allocFore(u32, u8, u8, u8, u8);
|
||||
void* free(JKRExpHeap*);
|
||||
static CMemBlock* getHeapBlock(void*);
|
||||
void initiate(CMemBlock*, CMemBlock*, u32, u8, u8);
|
||||
|
||||
void newGroupId(u8 groupId) { mGroupID = groupId; }
|
||||
bool isValid() const { return mUsageHeader == 'HM'; }
|
||||
bool _isTempMemBlock() const { return (mFlags & 0x80) ? true : false; }
|
||||
int getAlignment() const { return mFlags & 0x7f; }
|
||||
void* getContent() const { return (void*)(this + 1); }
|
||||
CMemBlock* getPrevBlock() const { return mPrev; }
|
||||
CMemBlock* getNextBlock() const { return mNext; }
|
||||
u32 getSize() const { return mAllocatedSpace; }
|
||||
u8 getGroupId() const { return mGroupID; }
|
||||
static CMemBlock* getBlock(void* data) { return (CMemBlock*)((u32)data + -0x10); }
|
||||
|
||||
u16 mUsageHeader; // _00
|
||||
u8 mFlags; // _02, a|bbbbbbb = a=temp, b=aln
|
||||
u8 mGroupID; // _03
|
||||
int mAllocatedSpace; // _04
|
||||
CMemBlock* mPrev; // _08
|
||||
CMemBlock* mNext; // _0C
|
||||
};
|
||||
|
||||
JKRExpHeap(void*, u32, JKRHeap*, bool);
|
||||
|
||||
virtual ~JKRExpHeap(); // _08
|
||||
virtual void* do_alloc(u32, int); // _10
|
||||
virtual void do_free(void*); // _14
|
||||
virtual void do_freeTail(); // _18
|
||||
virtual void do_freeAll(); // _1C
|
||||
virtual s32 do_resize(void*, u32); // _20
|
||||
virtual s32 do_getSize(void*); // _24
|
||||
virtual s32 do_getFreeSize(); // _28
|
||||
virtual s32 do_getTotalFreeSize(); // _2C
|
||||
virtual bool check(); // _34
|
||||
virtual bool dump_sort(); // _38
|
||||
virtual bool dump(); // _3C
|
||||
virtual s32 do_changeGroupID(u8); // _40
|
||||
virtual void state_register(TState*, u32) const; // _48
|
||||
virtual bool state_compare(const TState&, const TState&) const; // _4C
|
||||
|
||||
virtual u8 do_getCurrentGroupId() { return mCurrentGroupID; } // _44 (weak)
|
||||
virtual u32 getHeapType() { return 'EXPH'; } // _30 (weak)
|
||||
|
||||
void* allocFromHead(u32, int);
|
||||
void* allocFromHead(u32);
|
||||
void* allocFromTail(u32, int);
|
||||
void* allocFromTail(u32);
|
||||
void appendUsedList(CMemBlock*);
|
||||
static JKRExpHeap* create(u32, JKRHeap*, bool);
|
||||
static JKRExpHeap* create(void*, u32, JKRHeap*, bool);
|
||||
static JKRExpHeap* createRoot(int, bool);
|
||||
int freeGroup(u8 groupID);
|
||||
void joinTwoBlocks(CMemBlock*);
|
||||
void recycleFreeBlock(CMemBlock*);
|
||||
void removeFreeBlock(CMemBlock*);
|
||||
void setFreeBlock(CMemBlock*, CMemBlock*, CMemBlock*);
|
||||
|
||||
// unused/inlined:
|
||||
void removeUsedBlock(CMemBlock*);
|
||||
bool isEmpty();
|
||||
s32 getUsedSize(u8 groupId) const;
|
||||
|
||||
CMemBlock* getHeadUsedList() const { return mHeadUsedList; }
|
||||
void setAllocationMode(EAllocMode mode) { mCurrentAllocMode = mode; }
|
||||
|
||||
static s32 getUsedSize_(JKRExpHeap* expHeap)
|
||||
{
|
||||
// s32 totalFreeSize = expHeap->getTotalFreeSize();
|
||||
return expHeap->mSize - expHeap->getTotalFreeSize();
|
||||
}
|
||||
static u32 getState_(TState* state) { return getState_buf_(state); } // might instead be a pointer to a next state?
|
||||
|
||||
private:
|
||||
// _00 = VTBL
|
||||
// _00-_6C = JKRHeap
|
||||
u8 mCurrentAllocMode; // _6C
|
||||
u8 mCurrentGroupID; // _6D
|
||||
u8 _6E; // _6E
|
||||
void* _70; // _70
|
||||
u32 _74; // _74
|
||||
CMemBlock* mHead; // _78, free list
|
||||
CMemBlock* mTail; // _7C, free list
|
||||
CMemBlock* mHeadUsedList; // _80
|
||||
CMemBlock* mTailUsedList; // _84
|
||||
};
|
||||
|
||||
inline JKRExpHeap* JKRCreateExpHeap(u32 size, JKRHeap* parent, bool errorFlag)
|
||||
{
|
||||
return JKRExpHeap::create(size, parent, errorFlag);
|
||||
}
|
||||
|
||||
#endif /* JKREXPHEAP_H */
|
||||
@@ -5,7 +5,6 @@
|
||||
#include "dolphin/dvd.h"
|
||||
#include "dolphin/os.h"
|
||||
#include "JSystem/JSupport/JSUList.h"
|
||||
#include "JSystem/JKernel/JKRAram.h"
|
||||
#include "JSystem/JKernel/JKRDisposer.h"
|
||||
#include "JSystem/JKernel/JKRMacro.h"
|
||||
|
||||
@@ -14,8 +13,8 @@ public:
|
||||
inline JKRFile()
|
||||
: JKRDisposer()
|
||||
, mFileOpen(false)
|
||||
{
|
||||
}
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~JKRFile() { }
|
||||
virtual bool open(const char* path) = 0;
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
#ifndef _JKRFILEFINDER_H
|
||||
#define _JKRFILEFINDER_H
|
||||
|
||||
#include <dolphin/dvd.h>
|
||||
#include <dolphin/os.h>
|
||||
#include "types.h"
|
||||
|
||||
class JKRArchive;
|
||||
|
||||
struct JKRFileFinderBase
|
||||
{
|
||||
char* mFileName; // _00
|
||||
int mFileIndex; // _04
|
||||
u16 mFileID; // _08
|
||||
u16 mFileTypeFlags; // _0A
|
||||
};
|
||||
|
||||
class JKRFileFinder
|
||||
{
|
||||
public:
|
||||
JKRFileFinder()
|
||||
: mIsAvailable(false), mIsFileOrDir(false)
|
||||
{
|
||||
}
|
||||
|
||||
JKRFileFinderBase mBase;
|
||||
|
||||
virtual ~JKRFileFinder() {} // _08 (weak)
|
||||
virtual bool findNextFile() = 0; // _0C
|
||||
|
||||
bool isAvailable() const
|
||||
{
|
||||
return mIsAvailable;
|
||||
}
|
||||
|
||||
// _00 = VTBL
|
||||
|
||||
bool mIsAvailable; // _10
|
||||
bool mIsFileOrDir; // _11
|
||||
};
|
||||
|
||||
class JKRArcFinder : public JKRFileFinder
|
||||
{
|
||||
public:
|
||||
JKRArcFinder(JKRArchive*, long, long);
|
||||
|
||||
virtual ~JKRArcFinder() {} // _08 (weak)
|
||||
virtual bool findNextFile(); // _0C
|
||||
|
||||
// _00 = VTBL
|
||||
// _00-_14 = JKRFileFinder
|
||||
JKRArchive* mArchive; // _14
|
||||
long mStartIndex; // _18
|
||||
long mEndIndex; // _1C
|
||||
long mNextIndex; // _20
|
||||
};
|
||||
|
||||
class JKRDvdFinder : public JKRFileFinder
|
||||
{
|
||||
public:
|
||||
JKRDvdFinder(const char*);
|
||||
|
||||
virtual ~JKRDvdFinder() // _08 (weak)
|
||||
{
|
||||
if (mIsDvdOpen)
|
||||
{
|
||||
DVDCloseDir(&mDir);
|
||||
}
|
||||
}
|
||||
virtual bool findNextFile(); // _0C
|
||||
|
||||
// _00 = VTBL
|
||||
// _00-_14 = JKRFileFinder
|
||||
DVDDir mDir; // _14
|
||||
bool mIsDvdOpen; // _20
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,62 @@
|
||||
#ifndef JKRFILELOADER_H_
|
||||
#define JKRFILELOADER_H_
|
||||
|
||||
#include "JSystem/JKernel/JKREnum.h"
|
||||
#include "JSystem/JKernel/JKRDisposer.h"
|
||||
#include "JSystem/JSupport/JSUList.h"
|
||||
|
||||
class JKRFileFinder;
|
||||
class JKRFileLoader : public JKRDisposer
|
||||
{
|
||||
public:
|
||||
JKRFileLoader();
|
||||
|
||||
virtual ~JKRFileLoader(); // _08
|
||||
virtual void unmount(); // _0C
|
||||
virtual bool becomeCurrent(const char*) = 0; // _10
|
||||
virtual void* getResource(const char* path) = 0; // _14
|
||||
virtual void* getResource(u32 type, const char* name) = 0; // _18
|
||||
virtual size_t readResource(void* resourceBuffer, u32 bufferSize, const char* path, JKRExpandSwitch expandSwitch) = 0; // _1C
|
||||
virtual size_t readResource(void* resourceBuffer, u32 bufferSize, u32 type, const char* name) = 0; // _20
|
||||
virtual void removeResourceAll() = 0; // _24
|
||||
virtual bool removeResource(void*) = 0; // _28
|
||||
virtual bool detachResource(void*) = 0; // _2C
|
||||
virtual long getResSize(const void*) const = 0; // _30
|
||||
virtual u32 countFile(const char*) const = 0; // _34
|
||||
virtual JKRFileFinder* getFirstFile(const char*) const = 0; // _38
|
||||
|
||||
bool isMounted() const { return mIsMounted; }
|
||||
u32 getVolumeType() const { return mVolumeType; }
|
||||
|
||||
static void changeDirectory(const char* dir);
|
||||
|
||||
static void* getGlbResource(const char*);
|
||||
static void* getGlbResource(const char*, JKRFileLoader* fileLoader);
|
||||
static size_t readGlbResource(void* resourceBuffer, u32 bufferSize, const char* path, JKRExpandSwitch expandSwitch);
|
||||
|
||||
static bool removeResource(void* resourceBuffer, JKRFileLoader* fileLoader);
|
||||
static bool detachResource(void* resourceBuffer, JKRFileLoader* fileLoader);
|
||||
|
||||
static JKRFileLoader* findVolume(const char**);
|
||||
static JKRFileFinder* findFirstFile(const char*);
|
||||
static const char* fetchVolumeName(char*, long, const char*);
|
||||
|
||||
static JKRFileLoader* getCurrentVolume() { return sCurrentVolume; }
|
||||
static void setCurrentVolume(JKRFileLoader* fileLoader) { sCurrentVolume = fileLoader; }
|
||||
static JSUList<JKRFileLoader>& getVolumeList() { return sVolumeList; }
|
||||
|
||||
static JKRFileLoader* sCurrentVolume;
|
||||
static JSUList<JKRFileLoader> sVolumeList;
|
||||
|
||||
protected:
|
||||
/* 0x00 */ // vtable
|
||||
/* 0x04 */ // JKRDisposer
|
||||
JSULink<JKRFileLoader> mFileLoaderLink; // 0x18
|
||||
const char* mVolumeName; // 0x28
|
||||
u32 mVolumeType; // 0x2C
|
||||
bool mIsMounted; // 0x30
|
||||
u8 field_0x31[3]; // 0x31
|
||||
u32 mMountCount; // 0x34
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#include "types.h"
|
||||
|
||||
typedef void JKRHeapErrorHandler(void *, u32, int);
|
||||
typedef void JKRHeapErrorHandler(void*, u32, int);
|
||||
|
||||
class JKRHeap : public JKRDisposer
|
||||
{
|
||||
@@ -24,29 +24,29 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
void *_00; // _00
|
||||
void* _00; // _00
|
||||
int _04; // _04
|
||||
};
|
||||
|
||||
struct TArgument
|
||||
{
|
||||
TArgument(const JKRHeap *heap, u32 p2, bool p3)
|
||||
TArgument(const JKRHeap* heap, u32 p2, bool p3)
|
||||
: mHeap((heap) ? heap : JKRHeap::sCurrentHeap), mId(p2), mIsCompareOnDestructed(p3)
|
||||
{
|
||||
}
|
||||
|
||||
const JKRHeap *mHeap; // _00
|
||||
const JKRHeap* mHeap; // _00
|
||||
u32 mId; // _04
|
||||
bool mIsCompareOnDestructed; // _08
|
||||
};
|
||||
|
||||
TState(const JKRHeap *heap, u32 id, bool isCompareOnDestructed)
|
||||
TState(const JKRHeap* heap, u32 id, bool isCompareOnDestructed)
|
||||
: mUsedSize(0), mCheckCode(0), mArgument(heap, id, isCompareOnDestructed)
|
||||
{
|
||||
mArgument.mHeap->state_register(this, mArgument.mId);
|
||||
}
|
||||
|
||||
TState(JKRHeap *heap)
|
||||
TState(JKRHeap* heap)
|
||||
: mUsedSize(0), mCheckCode(0), mArgument(heap, 0xFFFFFFFF, true)
|
||||
{
|
||||
}
|
||||
@@ -57,13 +57,13 @@ public:
|
||||
bool isCompareOnDestructed() const { return mArgument.mIsCompareOnDestructed; };
|
||||
u32 getUsedSize() const { return mUsedSize; }
|
||||
u32 getCheckCode() const { return mCheckCode; }
|
||||
const JKRHeap *getHeap() const { return mArgument.mHeap; }
|
||||
const JKRHeap* getHeap() const { return mArgument.mHeap; }
|
||||
u32 getId() const { return mArgument.mId; }
|
||||
|
||||
// unused/inlined:
|
||||
TState(const JKRHeap::TState::TArgument &arg, const JKRHeap::TState::TLocation &location);
|
||||
TState(const JKRHeap::TState &other, bool p2);
|
||||
TState(const JKRHeap::TState &other, const JKRHeap::TState::TLocation &location, bool p3);
|
||||
TState(const JKRHeap::TState::TArgument& arg, const JKRHeap::TState::TLocation& location);
|
||||
TState(const JKRHeap::TState& other, bool p2);
|
||||
TState(const JKRHeap::TState& other, const JKRHeap::TState::TLocation& location, bool p3);
|
||||
|
||||
static bool bVerbose_;
|
||||
|
||||
@@ -76,19 +76,19 @@ public:
|
||||
};
|
||||
|
||||
public:
|
||||
JKRHeap(void *, u32, JKRHeap *, bool);
|
||||
JKRHeap(void*, u32, JKRHeap*, bool);
|
||||
|
||||
bool setErrorFlag(bool errorFlag);
|
||||
bool isSubHeap(JKRHeap *heap) const;
|
||||
bool isSubHeap(JKRHeap* heap) const;
|
||||
|
||||
virtual ~JKRHeap();
|
||||
virtual void callAllDisposer();
|
||||
virtual void *do_alloc(u32, int) = 0;
|
||||
virtual void do_free(void *) = 0;
|
||||
virtual void* do_alloc(u32, int) = 0;
|
||||
virtual void do_free(void*) = 0;
|
||||
virtual void do_freeAll() = 0;
|
||||
virtual void do_freeTail() = 0;
|
||||
virtual s32 do_resize(void *, u32) = 0;
|
||||
virtual s32 do_getSize(void *) = 0;
|
||||
virtual s32 do_resize(void*, u32) = 0;
|
||||
virtual s32 do_getSize(void*) = 0;
|
||||
virtual s32 do_getFreeSize() = 0;
|
||||
virtual s32 do_getTotalFreeSize() = 0;
|
||||
virtual u32 getHeapType() = 0;
|
||||
@@ -97,54 +97,54 @@ public:
|
||||
virtual bool dump() = 0;
|
||||
virtual s32 do_changeGroupID(u8 newGroupID) { return 0; }
|
||||
virtual u8 do_getCurrentGroupId() { return 0; }
|
||||
virtual void state_register(JKRHeap::TState *, u32) const;
|
||||
virtual bool state_compare(JKRHeap::TState const &, JKRHeap::TState const &) const;
|
||||
virtual void state_dump(JKRHeap::TState const &) const;
|
||||
virtual void state_register(JKRHeap::TState*, u32) const;
|
||||
virtual bool state_compare(JKRHeap::TState const&, JKRHeap::TState const&) const;
|
||||
virtual void state_dump(JKRHeap::TState const&) const;
|
||||
|
||||
JKRHeap *becomeSystemHeap();
|
||||
JKRHeap *becomeCurrentHeap();
|
||||
JKRHeap* becomeSystemHeap();
|
||||
JKRHeap* becomeCurrentHeap();
|
||||
void destroy();
|
||||
void *alloc(u32, int);
|
||||
void free(void *);
|
||||
void* alloc(u32, int);
|
||||
void free(void*);
|
||||
void freeAll();
|
||||
void freeTail();
|
||||
void fillFreeArea();
|
||||
void resize(void *, u32);
|
||||
static s32 getSize(void *, JKRHeap*);
|
||||
void resize(void*, u32);
|
||||
static s32 getSize(void*, JKRHeap*);
|
||||
|
||||
// ... more functions
|
||||
|
||||
s32 getSize(void *ptr);
|
||||
s32 getSize(void* ptr);
|
||||
s32 getFreeSize();
|
||||
void *getMaxFreeBlock();
|
||||
void* getMaxFreeBlock();
|
||||
s32 getTotalFreeSize();
|
||||
u8 getCurrentGroupId();
|
||||
s32 changeGroupID(u8 newGroupId);
|
||||
u32 getMaxAllocatableSize(int alignment);
|
||||
JKRHeap *find(void *) const; // 0x80084640
|
||||
JKRHeap *findAllHeap(void *) const; // 0x8008492c
|
||||
JKRHeap* find(void*) const; // 0x80084640
|
||||
JKRHeap* findAllHeap(void*) const; // 0x8008492c
|
||||
void dispose_subroutine(u32 begin, u32 end);
|
||||
bool dispose(void *, u32); // 0x80084b9c
|
||||
void dispose(void *, void *); // 0x80084c2c
|
||||
bool dispose(void*, u32); // 0x80084b9c
|
||||
void dispose(void*, void*); // 0x80084c2c
|
||||
void dispose(); // 0x80084cb8
|
||||
|
||||
void appendDisposer(JKRDisposer *disposer)
|
||||
void appendDisposer(JKRDisposer* disposer)
|
||||
{
|
||||
mDisposerList.append(&disposer->mPointerLinks);
|
||||
}
|
||||
|
||||
void removeDisposer(JKRDisposer *disposer)
|
||||
void removeDisposer(JKRDisposer* disposer)
|
||||
{
|
||||
mDisposerList.remove(&disposer->mPointerLinks);
|
||||
}
|
||||
|
||||
void setDebugFill(bool debugFill) { mDebugFill = debugFill; }
|
||||
bool getDebugFill() const { return mDebugFill; }
|
||||
void *getStartAddr() const { return (void *)mStart; }
|
||||
void *getEndAddr() const { return (void *)mEnd; }
|
||||
void* getStartAddr() const { return (void*)mStart; }
|
||||
void* getEndAddr() const { return (void*)mEnd; }
|
||||
u32 getHeapSize() const { return mSize; }
|
||||
bool getErrorFlag() const { return mErrorFlag; }
|
||||
void callErrorHandler(JKRHeap *heap, u32 size, int alignment)
|
||||
void callErrorHandler(JKRHeap* heap, u32 size, int alignment)
|
||||
{
|
||||
if (mErrorHandler)
|
||||
{
|
||||
@@ -152,34 +152,59 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// TState related
|
||||
static u32 getState_buf_(TState* state) { return state->mBuf; } // might instead be a pointer to a next state?
|
||||
static void setState_u32ID_(TState* state, u32 id)
|
||||
{
|
||||
state->mArgument.mId = id;
|
||||
}
|
||||
static void setState_uUsedSize_(TState* state, u32 usedSize)
|
||||
{
|
||||
state->mUsedSize = usedSize;
|
||||
}
|
||||
static void setState_u32CheckCode_(TState* state, u32 checkCode) { state->mCheckCode = checkCode; }
|
||||
|
||||
void lock() const { OSLockMutex(const_cast<OSMutex*>(&mMutex)); }
|
||||
void unlock() const { OSUnlockMutex(const_cast<OSMutex*>(&mMutex)); }
|
||||
|
||||
JKRHeap* getParent()
|
||||
{
|
||||
return mChildTree.getParent()->getObject();
|
||||
}
|
||||
|
||||
const JSUTree<JKRHeap>& getHeapTree()
|
||||
{
|
||||
return mChildTree;
|
||||
}
|
||||
|
||||
// Unused
|
||||
void checkMemoryFilled(u8 *, u32 size, u8);
|
||||
void checkMemoryFilled(u8*, u32 size, u8);
|
||||
|
||||
static void destroy(JKRHeap *heap); // fabricated
|
||||
static bool initArena(char **, u32 *, int);
|
||||
static void *alloc(u32, int, JKRHeap *);
|
||||
static void copyMemory(void *, void *, u32);
|
||||
static void free(void *, JKRHeap *);
|
||||
static void state_dumpDifference(const TState &, const TState &);
|
||||
static JKRHeap *findFromRoot(void *);
|
||||
static JKRHeapErrorHandler *setErrorHandler(JKRHeapErrorHandler *);
|
||||
static void destroy(JKRHeap* heap); // fabricated
|
||||
static bool initArena(char**, u32*, int);
|
||||
static void* alloc(u32, int, JKRHeap*);
|
||||
static void copyMemory(void*, void*, u32);
|
||||
static void free(void*, JKRHeap*);
|
||||
static void state_dumpDifference(const TState&, const TState&);
|
||||
static JKRHeap* findFromRoot(void*);
|
||||
static JKRHeapErrorHandler* setErrorHandler(JKRHeapErrorHandler*);
|
||||
|
||||
static void *getCodeStart()
|
||||
static void* getCodeStart()
|
||||
{
|
||||
return mCodeStart;
|
||||
}
|
||||
|
||||
static void *getCodeEnd()
|
||||
static void* getCodeEnd()
|
||||
{
|
||||
return mCodeEnd;
|
||||
}
|
||||
|
||||
static void *getUserRamStart()
|
||||
static void* getUserRamStart()
|
||||
{
|
||||
return mUserRamStart;
|
||||
}
|
||||
|
||||
static void *getUserRamEnd()
|
||||
static void* getUserRamEnd()
|
||||
{
|
||||
return mUserRamEnd;
|
||||
}
|
||||
@@ -189,42 +214,42 @@ public:
|
||||
return mMemorySize;
|
||||
}
|
||||
|
||||
static JKRHeap *getCurrentHeap()
|
||||
static JKRHeap* getCurrentHeap()
|
||||
{
|
||||
return sCurrentHeap;
|
||||
}
|
||||
|
||||
static JKRHeap *getRootHeap()
|
||||
static JKRHeap* getRootHeap()
|
||||
{
|
||||
return sRootHeap;
|
||||
}
|
||||
|
||||
static JKRHeap *getSystemHeap()
|
||||
static JKRHeap* getSystemHeap()
|
||||
{
|
||||
return sSystemHeap;
|
||||
}
|
||||
|
||||
static void *mCodeStart;
|
||||
static void *mCodeEnd;
|
||||
static void *mUserRamStart;
|
||||
static void *mUserRamEnd;
|
||||
static void* mCodeStart;
|
||||
static void* mCodeEnd;
|
||||
static void* mUserRamStart;
|
||||
static void* mUserRamEnd;
|
||||
static u32 mMemorySize;
|
||||
|
||||
static JKRHeap *sSystemHeap;
|
||||
static JKRHeap *sCurrentHeap;
|
||||
static JKRHeap *sRootHeap;
|
||||
static JKRHeap* sSystemHeap;
|
||||
static JKRHeap* sCurrentHeap;
|
||||
static JKRHeap* sRootHeap;
|
||||
|
||||
static bool sDefaultFillFlag;
|
||||
static bool sDefaultFillCheckFlag;
|
||||
|
||||
static JKRHeapErrorHandler *mErrorHandler;
|
||||
static JKRHeapErrorHandler* mErrorHandler;
|
||||
|
||||
protected:
|
||||
/* 0x00 */ // vtable
|
||||
/* 0x04 */ // JKRDisposer
|
||||
/* 0x18 */ OSMutex mMutex;
|
||||
/* 0x30 */ void *mStart;
|
||||
/* 0x34 */ void *mEnd;
|
||||
/* 0x30 */ void* mStart;
|
||||
/* 0x34 */ void* mEnd;
|
||||
/* 0x38 */ u32 mSize;
|
||||
/* 0x3C */ bool mDebugFill;
|
||||
/* 0x3D */ bool mCheckMemoryFilled;
|
||||
@@ -237,52 +262,58 @@ protected:
|
||||
/* 0x6A */ u8 padding_0x6a[2];
|
||||
};
|
||||
|
||||
inline JKRHeap *JKRGetCurrentHeap()
|
||||
inline JKRHeap* JKRGetCurrentHeap()
|
||||
{
|
||||
return JKRHeap::getCurrentHeap();
|
||||
}
|
||||
|
||||
inline JKRHeap *JKRGetSystemHeap()
|
||||
inline JKRHeap* JKRGetSystemHeap()
|
||||
{
|
||||
return JKRHeap::getSystemHeap();
|
||||
}
|
||||
|
||||
inline JKRHeap *JKRGetRootHeap()
|
||||
inline JKRHeap* JKRGetRootHeap()
|
||||
{
|
||||
return JKRHeap::getRootHeap();
|
||||
}
|
||||
|
||||
inline void *JKRAllocFromSysHeap(u32 size, int alignment)
|
||||
inline void* JKRAllocFromSysHeap(u32 size, int alignment)
|
||||
{
|
||||
return JKRHeap::getSystemHeap()->alloc(size, alignment);
|
||||
}
|
||||
|
||||
inline void *JKRAllocFromHeap(JKRHeap *heap, u32 size, int alignment)
|
||||
inline void* JKRAllocFromHeap(JKRHeap* heap, u32 size, int alignment)
|
||||
{
|
||||
return JKRHeap::alloc(size, alignment, heap);
|
||||
}
|
||||
|
||||
inline void JKRFree(void *pBuf)
|
||||
inline void JKRFree(void* pBuf)
|
||||
{
|
||||
JKRHeap::free(pBuf, nullptr);
|
||||
}
|
||||
|
||||
inline void JKRFreeToSysHeap(void *buf)
|
||||
inline void JKRFreeToHeap(JKRHeap* heap, void* ptr)
|
||||
{
|
||||
JKRHeap::free(ptr, heap);
|
||||
}
|
||||
|
||||
inline void JKRFreeToSysHeap(void* buf)
|
||||
{
|
||||
JKRHeap::getSystemHeap()->free(buf);
|
||||
}
|
||||
|
||||
void JKRDefaultMemoryErrorRoutine(void *, u32, int);
|
||||
void JKRDefaultMemoryErrorRoutine(void*, u32, int);
|
||||
|
||||
void *operator new(size_t);
|
||||
void *operator new(size_t, s32);
|
||||
void *operator new(size_t, JKRHeap *, int);
|
||||
void* operator new(size_t);
|
||||
void* operator new(size_t, s32);
|
||||
void* operator new(size_t, JKRHeap*, int);
|
||||
inline void* operator new(size_t, void* buf) { return buf; } // i believe this is actually part of MSL_C?
|
||||
|
||||
void *operator new[](size_t);
|
||||
void *operator new[](size_t, s32);
|
||||
void *operator new[](size_t, JKRHeap *, int);
|
||||
void* operator new[](size_t);
|
||||
void* operator new[](size_t, s32);
|
||||
void* operator new[](size_t, JKRHeap*, int);
|
||||
|
||||
void operator delete(void *);
|
||||
void operator delete[](void *);
|
||||
void operator delete(void*);
|
||||
void operator delete[](void*);
|
||||
|
||||
#endif // !JKRHEAP_H
|
||||
|
||||
@@ -6,16 +6,62 @@
|
||||
#include "dolphin/os/OSThread.h"
|
||||
#include "dolphin/os/OSTime.h"
|
||||
#include "JSystem/JSupport/JSUList.h"
|
||||
#include "JSystem/JUtility/JUTConsole.h"
|
||||
#include "JSystem/JKernel/JKRHeap.h"
|
||||
#include "JSystem/JKernel/JKRDisposer.h"
|
||||
|
||||
struct JKRThread;
|
||||
|
||||
struct JKRThreadName_
|
||||
{
|
||||
s32 id;
|
||||
char* name;
|
||||
};
|
||||
|
||||
typedef void (*JKRThreadSwitch_PreCallback)(OSThread* current, OSThread* next);
|
||||
typedef void (*JKRThreadSwitch_PostCallback)(OSThread* current, OSThread* next);
|
||||
|
||||
class JKRThreadSwitch
|
||||
{
|
||||
public:
|
||||
JKRThreadSwitch(JKRHeap*);
|
||||
virtual void draw(JKRThreadName_* param_1, JUTConsole* param_2);
|
||||
virtual void draw(JKRThreadName_* param_1);
|
||||
virtual ~JKRThreadSwitch();
|
||||
|
||||
static JKRThreadSwitch* createManager(JKRHeap* heap);
|
||||
|
||||
JKRThread* enter(JKRThread* param_1, int param_2);
|
||||
static void callback(OSThread* param_1, OSThread* param_2);
|
||||
|
||||
static u32 getTotalCount() { return sTotalCount; }
|
||||
|
||||
private:
|
||||
static JKRThreadSwitch* sManager;
|
||||
static u32 sTotalCount;
|
||||
static u64 sTotalStart;
|
||||
static JKRThreadSwitch_PreCallback mUserPreCallback;
|
||||
static JKRThreadSwitch_PostCallback mUserPostCallback;
|
||||
|
||||
private:
|
||||
JKRHeap* mHeap; // _04
|
||||
bool mSetNextHeap; // _08
|
||||
u8 _09[3]; // _09, padding?
|
||||
u32 _0C; // _0C
|
||||
u32 _10; // _10
|
||||
u8 _14[4]; // _14 - unknown/padding
|
||||
s64 _18; // _18
|
||||
JUTConsole* mConsole; // _20
|
||||
JKRThreadName_* mThreadName; // _24
|
||||
};
|
||||
|
||||
class JKRThread : public JKRDisposer {
|
||||
public:
|
||||
JKRThread(u32 stackSize, int msgCount, int threadPrio);
|
||||
JKRThread(OSThread* osThread, int msgCount);
|
||||
|
||||
virtual ~JKRThread();
|
||||
__declspec(weak) virtual void* run();
|
||||
virtual void* run() { return nullptr; }
|
||||
|
||||
static void* start(void* param);
|
||||
static JSUList<JKRThread>* getList() { return &JKRThread::sThreadList; }
|
||||
@@ -55,4 +101,78 @@ protected:
|
||||
u32 mStackSize;
|
||||
};
|
||||
|
||||
// Unused class, function definitions from Sunshine and MKDD
|
||||
class JKRTask : public JKRThread
|
||||
{
|
||||
typedef void (*RequestCallback)(void*);
|
||||
|
||||
/**
|
||||
* @fabricated
|
||||
* @size{0xC}
|
||||
*/
|
||||
struct Request
|
||||
{
|
||||
RequestCallback mCb;
|
||||
void* mArg;
|
||||
void* mMsg;
|
||||
};
|
||||
|
||||
JKRTask(); // unused/inlined
|
||||
|
||||
virtual ~JKRTask(); // _08
|
||||
virtual void* run(); // _0C
|
||||
|
||||
bool request(RequestCallback, void*, void*);
|
||||
|
||||
static JKRTask* create();
|
||||
|
||||
// unused/inlined:
|
||||
Request* searchBlank();
|
||||
void requestJam(RequestCallback, void*, void*);
|
||||
void cancelAll();
|
||||
void createTaskEndMessageQueue(int, JKRHeap*);
|
||||
void destroyTaskEndMessageQueue();
|
||||
void waitQueueMessageBlock(OSMessageQueue*, int*);
|
||||
void waitQueueMessage(OSMessageQueue*, int*);
|
||||
|
||||
OSMessage waitMessageBlock()
|
||||
{
|
||||
OSMessage msg;
|
||||
OSReceiveMessage(&mMesgQueue, &msg, OS_MESSAGE_BLOCK);
|
||||
return msg;
|
||||
}
|
||||
|
||||
void destroy();
|
||||
|
||||
// Unused
|
||||
static OSMessage* sEndMesgBuffer;
|
||||
static u32 sEndMesgBufSize;
|
||||
|
||||
// u32 _78; // _78
|
||||
//JSULink<JKRTask> mTaskLink; // _7C, this didn't exist yet
|
||||
Request* mRequest; // _8C - ptr to request array
|
||||
u32 mRequestCnt; // _90 - amount of requests
|
||||
OSMessageQueue* mTaskMsgQueue; // _94
|
||||
|
||||
static JSUList<JKRTask> sTaskList;
|
||||
static u8 sEndMesgQueue[32]; // Unused
|
||||
};
|
||||
|
||||
/** @unused */
|
||||
struct JKRIdleThread : public JKRThread
|
||||
{
|
||||
virtual ~JKRIdleThread() {}; // _08
|
||||
virtual void* run() // _0C
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
}
|
||||
};
|
||||
virtual void destroy() {} // 0x10
|
||||
|
||||
static void create(JKRHeap*, int, u32);
|
||||
|
||||
static JKRIdleThread* sThread;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef JSYSTEM_JSUPPORT_H
|
||||
#define JSYSTEM_JSUPPORT_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
inline u8 JSULoByte(u16 in) { return in & 0xff; }
|
||||
inline u8 JSUHiByte(u16 in) { return in >> 8; }
|
||||
|
||||
#endif
|
||||
@@ -9,7 +9,6 @@ class JSUFileInputStream : public JSURandomInputStream {
|
||||
public:
|
||||
JSUFileInputStream(JKRFile* file);
|
||||
|
||||
virtual ~JSUFileInputStream() { }
|
||||
virtual int readData(void* buf, s32 len);
|
||||
virtual int getLength() const { return ((JKRFile*)this->mObject)->getFileSize(); }
|
||||
virtual int getPosition() const { return this->mPosition; }
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
#ifndef _JSYSTEM_JUT_JUTCONSOLE_H
|
||||
#define _JSYSTEM_JUT_JUTCONSOLE_H
|
||||
|
||||
#include "va_args.h"
|
||||
|
||||
class JUTConsole; // TODO
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
void JUTConsole_print_f_va_(JUTConsole*, const char*, va_list);
|
||||
|
||||
JUTConsole* JUTGetReportConsole();
|
||||
void JUTSetReportConsole(JUTConsole*);
|
||||
JUTConsole* JUTGetWarningConsole();
|
||||
void JUTSetWarningConsole(JUTConsole*);
|
||||
void JUTReportConsole(const char*);
|
||||
void JUTReportConsole_f(const char*, ...);
|
||||
void JUTReportConsole_f_va(const char*, va_list);
|
||||
void JUTWarningConsole(const char*);
|
||||
void JUTWarningConsole_f(const char*, ...);
|
||||
void JUTWarningConsole_f_va(const char*, va_list);
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif // ifdef __cplusplus
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,34 @@
|
||||
#ifndef _CTYPE_H
|
||||
#define _CTYPE_H
|
||||
|
||||
#include "types.h"
|
||||
#include "MSL_C/locale.h"
|
||||
#include "MSL_C/ctype_api.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
__declspec(weak) int isalpha(int __c);
|
||||
__declspec(weak) int isdigit(int __c);
|
||||
__declspec(weak) int isspace(int __c);
|
||||
__declspec(weak) int isupper(int __c);
|
||||
__declspec(weak) int isxdigit(int __c);
|
||||
|
||||
__declspec(weak) int tolower(int __c);
|
||||
__declspec(weak) int toupper(int __c);
|
||||
|
||||
// added underscore to avoid naming conflicts
|
||||
inline int _isalpha(int c) { return (int)(__ctype_map[(u8)c] & __letter); }
|
||||
inline int _isdigit(int c) { return (int)(__ctype_map[(u8)c] & __digit); }
|
||||
inline int _isspace(int c) { return (int)(__ctype_map[(u8)c] & __whitespace); }
|
||||
inline int _isupper(int c) { return (int)(__ctype_map[(u8)c] & __upper_case); }
|
||||
inline int _isxdigit(int c) { return (int)(__ctype_map[(u8)c] & __hex_digit); }
|
||||
inline int _tolower(int c) { return (c == -1 ? -1 : (int)__lower_map[(u8)c]); }
|
||||
inline int _toupper(int c) { return (c == -1 ? -1 : (int)__upper_map[(u8)c]); }
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,35 @@
|
||||
#ifndef _MSL_CTYPE_API_H
|
||||
#define _MSL_CTYPE_API_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif // ifdef __cplusplus
|
||||
|
||||
extern unsigned char __ctype_map[256];
|
||||
extern unsigned char __lower_map[256];
|
||||
extern unsigned char __upper_map[256];
|
||||
|
||||
#define __control_char 0x01
|
||||
#define __motion_char 0x02
|
||||
#define __space_char 0x04
|
||||
#define __punctuation 0x08
|
||||
#define __digit 0x10
|
||||
#define __hex_digit 0x20
|
||||
#define __lower_case 0x40
|
||||
#define __upper_case 0x80
|
||||
|
||||
#define __letter (__lower_case | __upper_case)
|
||||
#define __alphanumeric (__letter | __digit)
|
||||
#define __graphic (__alphanumeric | __punctuation)
|
||||
#define __printable (__graphic | __space_char)
|
||||
#define __whitespace (__motion_char | __space_char)
|
||||
#define __control (__motion_char | __control_char)
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif // ifdef __cplusplus
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,130 @@
|
||||
#ifndef _LOCALE_H
|
||||
#define _LOCALE_H
|
||||
|
||||
#include "types.h"
|
||||
//#include "stdlib.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef int (*__decode_mbyte)(wchar_t *, const char *, size_t);
|
||||
typedef int (*__encode_mbyte)(char *, wchar_t);
|
||||
|
||||
struct lconv
|
||||
{
|
||||
char *decimal_point;
|
||||
char *thousands_sep;
|
||||
char *grouping;
|
||||
char *mon_decimal_point;
|
||||
char *mon_thousands_sep;
|
||||
char *mon_grouping;
|
||||
char *positive_sign;
|
||||
char *negative_sign;
|
||||
char *currency_symbol;
|
||||
char frac_digits;
|
||||
char p_cs_precedes;
|
||||
char n_cs_precedes;
|
||||
char p_sep_by_space;
|
||||
char n_sep_by_space;
|
||||
char p_sign_posn;
|
||||
char n_sign_posn;
|
||||
char *int_curr_symbol;
|
||||
char int_frac_digits;
|
||||
char int_p_cs_precedes;
|
||||
char int_n_cs_precedes;
|
||||
char int_p_sep_by_space;
|
||||
char int_n_sep_by_space;
|
||||
char int_p_sign_posn;
|
||||
char int_n_sign_posn;
|
||||
};
|
||||
|
||||
struct _loc_mon_cmpt
|
||||
{
|
||||
char CmptName[8];
|
||||
char *mon_decimal_point;
|
||||
char *mon_thousands_sep;
|
||||
char *mon_grouping;
|
||||
char *positive_sign;
|
||||
char *negative_sign;
|
||||
char *currency_symbol;
|
||||
char frac_digits;
|
||||
char p_cs_precedes;
|
||||
char n_cs_precedes;
|
||||
char p_sep_by_space;
|
||||
char n_sep_by_space;
|
||||
char p_sign_posn;
|
||||
char n_sign_posn;
|
||||
char *int_curr_symbol;
|
||||
char int_frac_digits;
|
||||
char int_p_cs_precedes;
|
||||
char int_n_cs_precedes;
|
||||
char int_p_sep_by_space;
|
||||
char int_n_sep_by_space;
|
||||
char int_p_sign_posn;
|
||||
char int_n_sign_posn;
|
||||
};
|
||||
|
||||
struct _loc_num_cmpt
|
||||
{
|
||||
char CmptName[8];
|
||||
char *decimal_point;
|
||||
char *thousands_sep;
|
||||
char *grouping;
|
||||
};
|
||||
|
||||
struct _loc_time_cmpt
|
||||
{
|
||||
char CmptName[8];
|
||||
char *am_pm;
|
||||
char *DateTime_Format;
|
||||
char *Twelve_hr_format;
|
||||
char *Date_Format;
|
||||
char *Time_Format;
|
||||
char *Day_Names;
|
||||
char *MonthNames;
|
||||
char *TimeZone;
|
||||
};
|
||||
|
||||
struct _loc_coll_cmpt
|
||||
{
|
||||
char CmptName[8];
|
||||
int char_start_value;
|
||||
int char_coll_tab_size;
|
||||
short char_spec_accents;
|
||||
unsigned short *char_coll_table_ptr;
|
||||
unsigned short *wchar_coll_seq_ptr;
|
||||
};
|
||||
|
||||
struct _loc_ctype_cmpt
|
||||
{
|
||||
char CmptName[8];
|
||||
const unsigned short *ctype_map_ptr;
|
||||
const unsigned char *upper_map_ptr;
|
||||
const unsigned char *lower_map_ptr;
|
||||
const unsigned short *wctype_map_ptr;
|
||||
const wchar_t *wupper_map_ptr;
|
||||
const wchar_t *wlower_map_ptr;
|
||||
__decode_mbyte decode_mb;
|
||||
__encode_mbyte encode_wc;
|
||||
};
|
||||
|
||||
struct __locale
|
||||
{
|
||||
struct __locale *next_locale;
|
||||
char locale_name[48];
|
||||
struct _loc_coll_cmpt *coll_cmpt_ptr;
|
||||
struct _loc_ctype_cmpt *ctype_cmpt_ptr;
|
||||
struct _loc_mon_cmpt *mon_cmpt_ptr;
|
||||
struct _loc_num_cmpt *num_cmpt_ptr;
|
||||
struct _loc_time_cmpt *time_cmpt_ptr;
|
||||
};
|
||||
|
||||
extern struct __locale _current_locale;
|
||||
extern struct lconv __lconv;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -2,7 +2,7 @@
|
||||
#define RAND_H
|
||||
#include "types.h"
|
||||
|
||||
void srand (u32 seeed);
|
||||
void srand(u32 seed);
|
||||
int rand(void);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -48,6 +48,11 @@ typedef u32 unknown;
|
||||
|
||||
#define ALIGN_PREV(u, align) (u & (~(align-1)))
|
||||
#define ALIGN_NEXT(u, align) ((u + (align-1)) & (~(align-1)))
|
||||
#define IS_ALIGNED(X, N) (((X) & ((N)-1)) == 0)
|
||||
#define IS_NOT_ALIGNED(X, N) (((X) & ((N)-1)) != 0)
|
||||
|
||||
#define FLAG_ON(V, F) (((V) & (F)) == 0)
|
||||
#define FLAG_OFF(V, F) (((V) & (F)) != 0)
|
||||
|
||||
#ifndef ATTRIBUTE_ALIGN
|
||||
#if defined(__MWERKS__) || defined(__GNUC__)
|
||||
|
||||
@@ -0,0 +1,509 @@
|
||||
#include <dolphin/ar.h>
|
||||
#include <dolphin/string.h>
|
||||
|
||||
#include "JSystem/JKernel/JKRDecomp.h"
|
||||
#include "JSystem/JKernel/JKRDvdRipper.h"
|
||||
#include "JSystem/JKernel/JKRExpHeap.h"
|
||||
#include "JSystem/JSystem.h"
|
||||
#include "_mem.h"
|
||||
|
||||
JSUList<JKRAMCommand> JKRAram::sAramCommandList;
|
||||
JKRAram* JKRAram::sAramObject;
|
||||
u32 JKRAram::sSZSBufferSize = 0x400;
|
||||
|
||||
JKRAram* JKRAram::create(u32 aram_audio_buffer_size, u32 aram_audio_graph_size,
|
||||
s32 streamPriority, s32 decomp_priority,
|
||||
s32 piece_priority) {
|
||||
if (!sAramObject) {
|
||||
sAramObject = new (JKRGetSystemHeap(), 0)
|
||||
JKRAram(aram_audio_buffer_size, aram_audio_graph_size, piece_priority);
|
||||
}
|
||||
|
||||
JKRCreateAramStreamManager(streamPriority);
|
||||
JKRCreateDecompManager(decomp_priority);
|
||||
sAramObject->resume();
|
||||
return sAramObject;
|
||||
}
|
||||
|
||||
OSMessage JKRAram::sMessageBuffer[4] = {
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
};
|
||||
|
||||
OSMessageQueue JKRAram::sMessageQueue = { 0 };
|
||||
|
||||
JKRAram::JKRAram(u32 bufSize, u32 graphSize, s32 priority)
|
||||
: JKRThread(0x4000, 0x10, priority) {
|
||||
u32 aramBase = ARInit(mStackArray, ARRAY_COUNT(mStackArray));
|
||||
ARQInit();
|
||||
|
||||
u32 aramSize = ARGetSize();
|
||||
mAudioMemorySize = bufSize;
|
||||
if (graphSize == 0xffffffff) {
|
||||
mGraphMemorySize = aramSize - bufSize - aramBase;
|
||||
mUserMemorySize = 0;
|
||||
}
|
||||
else {
|
||||
mGraphMemorySize = graphSize;
|
||||
mUserMemorySize = (aramSize - (bufSize + graphSize) - aramBase);
|
||||
}
|
||||
|
||||
mAudioMemoryPtr = ARAlloc(mAudioMemorySize);
|
||||
mGraphMemoryPtr = ARAlloc(mGraphMemorySize);
|
||||
|
||||
if (mUserMemorySize != 0) { // ternary?
|
||||
mUserMemoryPtr = ARAlloc(mUserMemorySize);
|
||||
}
|
||||
else {
|
||||
mUserMemoryPtr = nullptr;
|
||||
}
|
||||
|
||||
mAramHeap = new (JKRHeap::getSystemHeap(), 0)
|
||||
JKRAramHeap(mGraphMemoryPtr, mGraphMemorySize);
|
||||
}
|
||||
|
||||
JKRAram::~JKRAram() {
|
||||
sAramObject = nullptr;
|
||||
if (mAramHeap) delete mAramHeap;
|
||||
}
|
||||
|
||||
void* JKRAram::run() {
|
||||
int result;
|
||||
JKRAMCommand* command;
|
||||
JKRAramCommand* message;
|
||||
OSInitMessageQueue(&sMessageQueue, sMessageBuffer, 4);
|
||||
do {
|
||||
OSReceiveMessage(&sMessageQueue, (OSMessage*)&message, OS_MESSAGE_BLOCK);
|
||||
result = message->mActive;
|
||||
command = (JKRAMCommand*)message->mArg;
|
||||
delete message;
|
||||
|
||||
switch (result) {
|
||||
case 1:
|
||||
JKRAramPiece::startDMA(command);
|
||||
break;
|
||||
}
|
||||
} while (true);
|
||||
}
|
||||
|
||||
bool JKRAram::checkOkAddress(u8* addr, u32 size, JKRAramBlock* block,
|
||||
u32 blockSize) {
|
||||
if (!IS_ALIGNED((u32)addr, 0x20) && !IS_ALIGNED(size, 0x20)) {
|
||||
JPANIC(225, ":::address not 32Byte aligned.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (block) {
|
||||
if (!IS_ALIGNED(block->getAddress() + blockSize, 0x20)) {
|
||||
JPANIC(234, ":::address not 32Byte aligned.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void JKRAram::changeGroupIdIfNeed(u8* data, int groupId) {
|
||||
JKRHeap* currentHeap = JKRGetCurrentHeap();
|
||||
if (currentHeap->getHeapType() == 'EXPH' && groupId >= 0) {
|
||||
JKRExpHeap::CMemBlock* block = (JKRExpHeap::CMemBlock*)(data + -0x10);
|
||||
block->newGroupId(groupId);
|
||||
}
|
||||
}
|
||||
|
||||
JKRAramBlock* JKRAram::mainRamToAram(u8* buf, u32 address, u32 alignedSize,
|
||||
JKRExpandSwitch expandSwitch, u32 fileSize,
|
||||
JKRHeap* heap, int id) {
|
||||
JKRAramBlock* block = nullptr;
|
||||
checkOkAddress(buf, address, nullptr, 0);
|
||||
if (expandSwitch == EXPAND_SWITCH_DECOMPRESS) {
|
||||
expandSwitch = (JKRCheckCompressed(buf) == JKRCOMPRESSION_NONE)
|
||||
? EXPAND_SWITCH_DEFAULT
|
||||
: EXPAND_SWITCH_DECOMPRESS;
|
||||
}
|
||||
if (expandSwitch == EXPAND_SWITCH_DECOMPRESS) {
|
||||
u32 expandSize = JKRCheckCompressed(buf) != JKRCOMPRESSION_NONE
|
||||
? JKRDecompExpandSize(buf)
|
||||
: 0;
|
||||
if (fileSize == 0 || fileSize > expandSize) {
|
||||
fileSize = expandSize;
|
||||
}
|
||||
if (address == 0) {
|
||||
block = JKRAllocFromAram(fileSize, JKRAramHeap::Head);
|
||||
if (block == nullptr) return nullptr;
|
||||
|
||||
block->newGroupID(decideAramGroupId(id));
|
||||
address = block->getAddress();
|
||||
}
|
||||
if (alignedSize == 0 || alignedSize > expandSize) alignedSize = expandSize;
|
||||
|
||||
if (fileSize > alignedSize) fileSize = alignedSize;
|
||||
|
||||
void* allocatedMem = JKRAllocFromHeap(heap, fileSize, -32);
|
||||
if (allocatedMem == nullptr) {
|
||||
if (block != nullptr) {
|
||||
delete block;
|
||||
}
|
||||
block = nullptr;
|
||||
}
|
||||
else {
|
||||
JKRDecompress(buf, (u8*)allocatedMem, fileSize, 0);
|
||||
JKRAramPcs(0, (u32)allocatedMem, address, alignedSize, block);
|
||||
JKRFreeToHeap(heap, allocatedMem);
|
||||
block = block == nullptr ? (JKRAramBlock*)-1 : block;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (address == 0) {
|
||||
block = JKRAllocFromAram(alignedSize, JKRAramHeap::Head);
|
||||
block->newGroupID(decideAramGroupId(id));
|
||||
if (block == nullptr) return nullptr;
|
||||
|
||||
address = block->getAddress();
|
||||
}
|
||||
|
||||
JKRAramPcs(0, (u32)buf, address, alignedSize, block);
|
||||
block = block == nullptr ? (JKRAramBlock*)-1 : block;
|
||||
}
|
||||
return block;
|
||||
}
|
||||
|
||||
JKRAramBlock* JKRAram::mainRamToAram(u8* buf, JKRAramBlock* block,
|
||||
u32 alignedSize,
|
||||
JKRExpandSwitch expandSwitch, u32 fileSize,
|
||||
JKRHeap* heap, int id) {
|
||||
checkOkAddress(buf, 0, block, 0);
|
||||
|
||||
if (block == nullptr) {
|
||||
return mainRamToAram(buf, (u32)0, alignedSize, expandSwitch, fileSize, heap,
|
||||
id);
|
||||
}
|
||||
|
||||
u32 blockSize = block->getSize();
|
||||
|
||||
if (expandSwitch == EXPAND_SWITCH_DECOMPRESS) {
|
||||
fileSize = fileSize >= blockSize ? blockSize : fileSize;
|
||||
}
|
||||
|
||||
alignedSize = alignedSize > blockSize ? blockSize : alignedSize;
|
||||
|
||||
return mainRamToAram(buf, block->getAddress(), alignedSize, expandSwitch,
|
||||
fileSize, heap, id);
|
||||
}
|
||||
|
||||
// TODO: figure out name of parameter 5
|
||||
u8* JKRAram::aramToMainRam(u32 address, u8* buf, u32 srcSize,
|
||||
JKRExpandSwitch expandSwitch, u32 p5, JKRHeap* heap,
|
||||
int id, u32* pSize) {
|
||||
int compression = JKRCOMPRESSION_NONE;
|
||||
if (pSize) *pSize = 0;
|
||||
|
||||
checkOkAddress(buf, address, nullptr, 0);
|
||||
|
||||
u32 expandSize;
|
||||
if (expandSwitch == EXPAND_SWITCH_DECOMPRESS) {
|
||||
u8 buffer[64];
|
||||
u8* bufPtr = (u8*)ALIGN_NEXT((u32)buffer, 32);
|
||||
JKRAramPcs(1, address, (u32)bufPtr, sizeof(buffer) / 2,
|
||||
nullptr); // probably change sizeof(buffer) / 2 to 32
|
||||
compression = JKRCheckCompressed(bufPtr);
|
||||
expandSize = JKRDecompExpandSize(bufPtr);
|
||||
}
|
||||
|
||||
if (compression == JKRCOMPRESSION_YAZ0) // SZS
|
||||
{
|
||||
if (p5 != 0 && p5 < expandSize) expandSize = p5;
|
||||
|
||||
if (buf == nullptr) buf = (u8*)JKRAllocFromHeap(heap, expandSize, 32);
|
||||
if (buf == nullptr)
|
||||
return nullptr;
|
||||
else {
|
||||
changeGroupIdIfNeed(buf, id);
|
||||
JKRDecompressFromAramToMainRam(address, buf, srcSize, expandSize, 0);
|
||||
if (pSize) {
|
||||
*pSize = expandSize;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
else if (compression == JKRCOMPRESSION_YAY0) // SZP
|
||||
{
|
||||
u8* szpSpace = (u8*)JKRAllocFromHeap(heap, srcSize, -32);
|
||||
if (szpSpace == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
else {
|
||||
JKRAramPcs(1, address, (u32)szpSpace, srcSize, nullptr);
|
||||
if (p5 != 0 && p5 < expandSize) expandSize = p5;
|
||||
|
||||
u8* szpBuffer =
|
||||
buf == nullptr ? (u8*)JKRAllocFromHeap(heap, expandSize, 32) : buf;
|
||||
|
||||
if (szpBuffer == nullptr) {
|
||||
JKRFree(szpSpace);
|
||||
return nullptr;
|
||||
}
|
||||
else {
|
||||
changeGroupIdIfNeed(szpBuffer, id);
|
||||
JKRDecompress(szpSpace, szpBuffer, expandSize, 0);
|
||||
JKRFreeToHeap(heap, szpSpace);
|
||||
if (pSize) {
|
||||
*pSize = expandSize;
|
||||
}
|
||||
return szpBuffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // Not compressed or ASR
|
||||
{
|
||||
if (buf == nullptr) buf = (u8*)JKRAllocFromHeap(heap, srcSize, 32);
|
||||
if (buf == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
else {
|
||||
changeGroupIdIfNeed(buf, id);
|
||||
JKRAramPcs(1, address, (u32)buf, srcSize, nullptr);
|
||||
if (pSize != nullptr) {
|
||||
*pSize = srcSize;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: figure out what p6 does
|
||||
u8* JKRAram::aramToMainRam(JKRAramBlock* block, u8* buf, u32 bufSize,
|
||||
u32 alignedBlockSize, JKRExpandSwitch expandSwitch,
|
||||
u32 p6, JKRHeap* heap, int id, u32* pSize) {
|
||||
int compression = JKRCOMPRESSION_NONE;
|
||||
if (pSize) *pSize = 0;
|
||||
|
||||
checkOkAddress(buf, 0, block, alignedBlockSize);
|
||||
|
||||
if (block == nullptr) {
|
||||
JPANIC(667, ":::Bad Aram Block specified.\n");
|
||||
}
|
||||
|
||||
u32 freeSize = block->getSize();
|
||||
|
||||
if (alignedBlockSize >= freeSize) return nullptr;
|
||||
|
||||
bufSize = bufSize == 0 ? freeSize : bufSize;
|
||||
|
||||
if (alignedBlockSize + bufSize > freeSize) {
|
||||
bufSize = freeSize - alignedBlockSize;
|
||||
}
|
||||
|
||||
return aramToMainRam(alignedBlockSize + block->getAddress(), buf, bufSize,
|
||||
expandSwitch, p6, heap, id, pSize);
|
||||
}
|
||||
|
||||
static OSMutex decompMutex;
|
||||
|
||||
static u8* szpBuf;
|
||||
static u8* szpEnd;
|
||||
static u8* refBuf;
|
||||
static u8* refEnd;
|
||||
static u8* refCurrent;
|
||||
static u32 srcOffset;
|
||||
static u32 transLeft;
|
||||
static u8* srcLimit;
|
||||
static u32 srcAddress;
|
||||
static u32 fileOffset;
|
||||
static u32 readCount;
|
||||
static u32 maxDest;
|
||||
static bool isInitMutex;
|
||||
static u32* tsPtr;
|
||||
static u32 tsArea;
|
||||
|
||||
static u8* firstSrcData();
|
||||
static u8* nextSrcData(u8* current);
|
||||
static int decompSZS_subroutine(u8* src, u8* dest);
|
||||
|
||||
void JKRAram::aramSync(JKRAMCommand*, int) {
|
||||
// JUT_REPORT_MSG("bad aramSync\n");
|
||||
}
|
||||
|
||||
int JKRDecompressFromAramToMainRam(u32 src, void* dst, u32 srcLength,
|
||||
u32 dstLength, u32 offset) {
|
||||
szpBuf = (u8*)JKRAllocFromSysHeap(SZP_BUFFERSIZE, 32);
|
||||
|
||||
// JUT_ASSERT(szpBuf != 0);
|
||||
|
||||
szpEnd = szpBuf + SZP_BUFFERSIZE;
|
||||
if (offset != 0) {
|
||||
refBuf = (u8*)JKRAllocFromSysHeap(0x1120, 0);
|
||||
// JUT_ASSERT(refBuf != 0);
|
||||
refEnd = refBuf + 0x1120;
|
||||
refCurrent = refBuf;
|
||||
}
|
||||
else {
|
||||
refBuf = nullptr;
|
||||
}
|
||||
|
||||
srcAddress = src;
|
||||
srcOffset = 0;
|
||||
transLeft = (srcLength != 0) ? srcLength : -1;
|
||||
fileOffset = offset;
|
||||
readCount = 0;
|
||||
maxDest = dstLength;
|
||||
|
||||
decompSZS_subroutine(firstSrcData(), (u8*)dst);
|
||||
JKRFree(szpBuf);
|
||||
|
||||
if (refBuf) {
|
||||
JKRFree(refBuf);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int decompSZS_subroutine(u8* src, u8* dest) {
|
||||
u8* endPtr;
|
||||
s32 validBitCount = 0;
|
||||
s32 currCodeByte = 0;
|
||||
|
||||
if (src[0] != 'Y' || src[1] != 'a' || src[2] != 'z' || src[3] != '0') {
|
||||
return -1;
|
||||
}
|
||||
|
||||
SYaz0Header* header = (SYaz0Header*)src;
|
||||
endPtr = dest + (header->length - fileOffset);
|
||||
if (endPtr > dest + maxDest) {
|
||||
endPtr = dest + maxDest;
|
||||
}
|
||||
|
||||
src += 0x10;
|
||||
do {
|
||||
if (validBitCount == 0) {
|
||||
if ((src > srcLimit) && transLeft) {
|
||||
src = nextSrcData(src);
|
||||
}
|
||||
currCodeByte = *src;
|
||||
validBitCount = 8;
|
||||
src++;
|
||||
}
|
||||
if (currCodeByte & 0x80) {
|
||||
if (fileOffset != 0) {
|
||||
if (readCount >= fileOffset) {
|
||||
*dest = *src;
|
||||
dest++;
|
||||
if (dest == endPtr) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
*(refCurrent++) = *src;
|
||||
if (refCurrent == refEnd) {
|
||||
refCurrent = refBuf;
|
||||
}
|
||||
src++;
|
||||
}
|
||||
else {
|
||||
*dest = *src;
|
||||
dest++;
|
||||
src++;
|
||||
if (dest == endPtr) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
readCount++;
|
||||
}
|
||||
else {
|
||||
u32 dist = src[1] | (src[0] & 0x0f) << 8;
|
||||
s32 numBytes = src[0] >> 4;
|
||||
src += 2;
|
||||
u8* copySource;
|
||||
if (fileOffset != 0) {
|
||||
copySource = refCurrent - dist - 1;
|
||||
if (copySource < refBuf) {
|
||||
copySource += refEnd - refBuf;
|
||||
}
|
||||
}
|
||||
else {
|
||||
copySource = dest - dist - 1;
|
||||
}
|
||||
if (numBytes == 0) {
|
||||
numBytes = *src + 0x12;
|
||||
src += 1;
|
||||
}
|
||||
else {
|
||||
numBytes += 2;
|
||||
}
|
||||
if (fileOffset != 0) {
|
||||
do {
|
||||
if (readCount >= fileOffset) {
|
||||
*dest = *copySource;
|
||||
dest++;
|
||||
if (dest == endPtr) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
*(refCurrent++) = *copySource;
|
||||
if (refCurrent == refEnd) {
|
||||
refCurrent = refBuf;
|
||||
}
|
||||
copySource++;
|
||||
if (copySource == refEnd) {
|
||||
copySource = refBuf;
|
||||
}
|
||||
readCount++;
|
||||
numBytes--;
|
||||
} while (numBytes != 0);
|
||||
}
|
||||
else {
|
||||
do {
|
||||
*dest = *copySource;
|
||||
dest++;
|
||||
if (dest == endPtr) {
|
||||
break;
|
||||
}
|
||||
readCount++;
|
||||
numBytes--;
|
||||
copySource++;
|
||||
} while (numBytes != 0);
|
||||
}
|
||||
}
|
||||
currCodeByte <<= 1;
|
||||
validBitCount--;
|
||||
} while (dest < endPtr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u8* firstSrcData() {
|
||||
srcLimit = szpEnd - 0x19;
|
||||
u8* buf = szpBuf;
|
||||
u32 maxSize = (szpEnd - szpBuf);
|
||||
u32 transSize = MIN(transLeft, maxSize);
|
||||
|
||||
JKRAramPcs(1, srcAddress + srcOffset, (u32)buf, ALIGN_NEXT(transSize, 32),
|
||||
nullptr);
|
||||
|
||||
srcOffset += transSize;
|
||||
transLeft -= transSize;
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
u8* nextSrcData(u8* current) {
|
||||
u8* dest;
|
||||
u32 left = (u32)(szpEnd - current);
|
||||
if (IS_NOT_ALIGNED(left, 0x20))
|
||||
dest = szpBuf + 0x20 - (left & (0x20 - 1));
|
||||
else
|
||||
dest = szpBuf;
|
||||
|
||||
memcpy(dest, current, left);
|
||||
u32 transSize = (u32)(szpEnd - (dest + left));
|
||||
if (transSize > transLeft) transSize = transLeft;
|
||||
// JUT_ASSERT(transSize > 0);
|
||||
|
||||
JKRAramPcs(1, (u32)(srcAddress + srcOffset), ((u32)dest + left),
|
||||
ALIGN_NEXT(transSize, 0x20), nullptr);
|
||||
srcOffset += transSize;
|
||||
transLeft -= transSize;
|
||||
|
||||
if (transLeft == 0) srcLimit = (dest + left) + transSize;
|
||||
|
||||
return dest;
|
||||
}
|
||||
@@ -0,0 +1,311 @@
|
||||
#include <dolphin/os/OSCache.h>
|
||||
#include <dolphin/string.h>
|
||||
|
||||
#include "JSystem/JKernel/JKRAram.h"
|
||||
#include "JSystem/JKernel/JKRArchive.h"
|
||||
#include "JSystem/JKernel/JKRDecomp.h"
|
||||
#include "JSystem/JKernel/JKRDvdAramRipper.h"
|
||||
#include "JSystem/JKernel/JKRDvdRipper.h"
|
||||
#include "JSystem/JSystem.h"
|
||||
#include "JSystem/JUtility/JUTAssertion.h"
|
||||
|
||||
JKRAramArchive::JKRAramArchive() : JKRArchive() {}
|
||||
|
||||
JKRAramArchive::JKRAramArchive(s32 entryNum, EMountDirection mountDirection)
|
||||
: JKRArchive(entryNum, MOUNT_ARAM) {
|
||||
mMountDirection = mountDirection;
|
||||
if (!open(entryNum)) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
mVolumeType = 'RARC';
|
||||
mVolumeName = &mStrTable[mDirectories->mOffset];
|
||||
sVolumeList.prepend(&mFileLoaderLink);
|
||||
mIsMounted = true;
|
||||
}
|
||||
}
|
||||
|
||||
JKRAramArchive::~JKRAramArchive() {
|
||||
if (mIsMounted == true) {
|
||||
if (mArcInfoBlock) {
|
||||
SDIFileEntry* fileEntries = mFileEntries;
|
||||
for (int i = 0; i < mArcInfoBlock->num_file_entries; i++) {
|
||||
if (fileEntries->mData != nullptr) {
|
||||
JKRFreeToHeap(mHeap, fileEntries->mData);
|
||||
}
|
||||
fileEntries++;
|
||||
}
|
||||
JKRFreeToHeap(mHeap, mArcInfoBlock);
|
||||
mArcInfoBlock = nullptr;
|
||||
}
|
||||
|
||||
if (mDvdFile) {
|
||||
delete mDvdFile;
|
||||
}
|
||||
if (mBlock) {
|
||||
delete mBlock;
|
||||
}
|
||||
|
||||
sVolumeList.remove(&mFileLoaderLink);
|
||||
mIsMounted = false;
|
||||
}
|
||||
}
|
||||
|
||||
void JKRAramArchive::fixedInit(s32 entryNum, EMountDirection direction) {
|
||||
mIsMounted = false;
|
||||
mMountDirection = direction;
|
||||
mMountMode = 2;
|
||||
mMountCount = 1;
|
||||
_54 = 2;
|
||||
mHeap = JKRGetCurrentHeap();
|
||||
mEntryNum = entryNum;
|
||||
|
||||
if (sCurrentVolume) return;
|
||||
sCurrentVolume = this;
|
||||
sCurrentDirID = 0;
|
||||
}
|
||||
|
||||
bool JKRAramArchive::mountFixed(s32 entryNum, EMountDirection direction) {
|
||||
if (entryNum < 0) return false;
|
||||
|
||||
if (check_mount_already(entryNum)) return false;
|
||||
|
||||
fixedInit(entryNum, direction);
|
||||
if (open(entryNum) == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mVolumeType = 'RARC';
|
||||
mVolumeName = &mStrTable[mDirectories->mOffset];
|
||||
sVolumeList.prepend(&mFileLoaderLink);
|
||||
mIsMounted = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool JKRAramArchive::mountFixed(const char* path, EMountDirection direction) {
|
||||
s32 entrynum = DVDConvertPathToEntrynum((char*)path);
|
||||
return mountFixed(entrynum, direction);
|
||||
}
|
||||
|
||||
void JKRAramArchive::unmountFixed() {
|
||||
if (sCurrentVolume == this) sCurrentVolume = nullptr;
|
||||
|
||||
if (mArcInfoBlock) {
|
||||
SDIFileEntry* fileEntries = mFileEntries;
|
||||
for (int i = 0; i < mArcInfoBlock->num_file_entries; i++) {
|
||||
if (fileEntries->mData != nullptr) {
|
||||
JKRFreeToHeap(mHeap, fileEntries->mData);
|
||||
}
|
||||
fileEntries++;
|
||||
}
|
||||
JKRFreeToHeap(mHeap, mArcInfoBlock);
|
||||
mArcInfoBlock = nullptr;
|
||||
}
|
||||
|
||||
if (mDvdFile) delete mDvdFile;
|
||||
|
||||
if (mBlock) delete mBlock;
|
||||
|
||||
sVolumeList.remove(&mFileLoaderLink);
|
||||
mIsMounted = false;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
CW_FORCE_STRINGS(JKRAramArchive_cpp, __FILE__, "isMounted()",
|
||||
"mMountCount == 1")
|
||||
#endif
|
||||
|
||||
bool JKRAramArchive::open(long entryNum) {
|
||||
mArcInfoBlock = nullptr;
|
||||
mDirectories = nullptr;
|
||||
mFileEntries = nullptr;
|
||||
mStrTable = nullptr;
|
||||
mBlock = nullptr;
|
||||
|
||||
mDvdFile =
|
||||
new (JKRGetSystemHeap(), mMountDirection == MOUNT_DIRECTION_HEAD ? 4 : -4)
|
||||
JKRDvdFile(entryNum);
|
||||
if (mDvdFile == nullptr) {
|
||||
mMountMode = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// NOTE: a different struct is used here for sure, unfortunately i can't get
|
||||
// any hits on this address, so gonna leave it like this for now
|
||||
SArcHeader* mem = (SArcHeader*)JKRAllocFromSysHeap(32, -32);
|
||||
if (mem == nullptr) {
|
||||
mMountMode = 0;
|
||||
}
|
||||
else {
|
||||
JKRDvdToMainRam(entryNum, (u8*)mem, EXPAND_SWITCH_DECOMPRESS, 32, nullptr,
|
||||
JKRDvdRipper::ALLOC_DIR_TOP, 0, &mCompression);
|
||||
int alignment = mMountDirection == MOUNT_DIRECTION_HEAD ? 32 : -32;
|
||||
u32 alignedSize = ALIGN_NEXT(mem->file_data_offset, 32);
|
||||
mArcInfoBlock =
|
||||
(SArcDataInfo*)JKRAllocFromHeap(mHeap, alignedSize, alignment);
|
||||
if (mArcInfoBlock == nullptr) {
|
||||
mMountMode = 0;
|
||||
}
|
||||
else {
|
||||
JKRDvdToMainRam(entryNum, (u8*)mArcInfoBlock, EXPAND_SWITCH_DECOMPRESS,
|
||||
alignedSize, nullptr, JKRDvdRipper::ALLOC_DIR_TOP, 32,
|
||||
nullptr);
|
||||
|
||||
mDirectories =
|
||||
(SDIDirEntry*)((u8*)mArcInfoBlock + mArcInfoBlock->node_offset);
|
||||
mFileEntries = (SDIFileEntry*)((u8*)mArcInfoBlock +
|
||||
mArcInfoBlock->file_entry_offset);
|
||||
mStrTable = (const char*)((u8*)mArcInfoBlock +
|
||||
mArcInfoBlock->string_table_offset);
|
||||
|
||||
u32 aramSize = ALIGN_NEXT(mem->file_data_length, 32);
|
||||
mBlock =
|
||||
JKRAllocFromAram(aramSize, mMountDirection == MOUNT_DIRECTION_HEAD
|
||||
? JKRAramHeap::Head
|
||||
: JKRAramHeap::Tail);
|
||||
if (mBlock == nullptr) {
|
||||
mMountMode = 0;
|
||||
}
|
||||
else {
|
||||
JKRDvdToAram(entryNum, mBlock->getAddress(), EXPAND_SWITCH_DECOMPRESS,
|
||||
mem->header_length + mem->file_data_offset, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
cleanup:
|
||||
if (mem != nullptr) {
|
||||
JKRFreeToSysHeap(mem);
|
||||
}
|
||||
if (mMountMode == 0) {
|
||||
JREPORTF(":::[%s: %d] Cannot alloc memory\n", __FILE__,
|
||||
415); // TODO: macro
|
||||
}
|
||||
return mMountMode != 0;
|
||||
}
|
||||
|
||||
void* JKRAramArchive::fetchResource(SDIFileEntry* fileEntry, u32* pSize) {
|
||||
JUT_ASSERT(isMounted());
|
||||
|
||||
u32 sizeRef;
|
||||
u8* data;
|
||||
|
||||
if (fileEntry->mData) {
|
||||
if (pSize) *pSize = fileEntry->mSize;
|
||||
}
|
||||
else {
|
||||
u32 addres = mBlock->getAddress();
|
||||
int compression = JKRConvertAttrToCompressionType(fileEntry->mFlag >> 0x18);
|
||||
u32 size =
|
||||
fetchResource_subroutine(fileEntry->mDataOffset + addres,
|
||||
fileEntry->mSize, mHeap, compression, &data);
|
||||
if (pSize) *pSize = size;
|
||||
fileEntry->mData = (void*)data;
|
||||
}
|
||||
|
||||
return fileEntry->mData;
|
||||
}
|
||||
|
||||
void* JKRAramArchive::fetchResource(void* data, u32 compressedSize,
|
||||
SDIFileEntry* fileEntry, u32* pSize,
|
||||
JKRExpandSwitch expandSwitch) {
|
||||
JUT_ASSERT(isMounted());
|
||||
u32 fileSize = fileEntry->mSize;
|
||||
if (fileSize > compressedSize) {
|
||||
fileSize = compressedSize;
|
||||
}
|
||||
if (fileEntry->mData) {
|
||||
JKRHeap::copyMemory(data, fileEntry->mData, fileSize);
|
||||
}
|
||||
else {
|
||||
int compression = JKRConvertAttrToCompressionType(fileEntry->mFlag >> 0x18);
|
||||
if (expandSwitch != EXPAND_SWITCH_DECOMPRESS) compression = 0;
|
||||
|
||||
fileSize = fetchResource_subroutine(
|
||||
fileEntry->mDataOffset + mBlock->getAddress(), fileSize, (u8*)data,
|
||||
compressedSize, compression);
|
||||
}
|
||||
|
||||
if (pSize != nullptr) {
|
||||
*pSize = fileSize;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
u32 JKRAramArchive::getAramAddress_Entry(SDIFileEntry* fileEntry) {
|
||||
JUT_ASSERT(isMounted());
|
||||
|
||||
if (fileEntry == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
return fileEntry->mDataOffset + mBlock->getAddress();
|
||||
}
|
||||
|
||||
u32 JKRAramArchive::getAramAddress(u32 type, const char* file) {
|
||||
SDIFileEntry* entry = findTypeResource(type, file);
|
||||
return getAramAddress_Entry(entry);
|
||||
}
|
||||
|
||||
u32 JKRAramArchive::fetchResource_subroutine(u32 srcAram, u32 size, u8* data,
|
||||
u32 expandSize, int compression) {
|
||||
JUT_ASSERT((srcAram & 0x1f) == 0);
|
||||
|
||||
u32 sizeRef;
|
||||
|
||||
u32 alignedSize = ALIGN_NEXT(size, 32);
|
||||
u32 prevAlignedSize = ALIGN_PREV(expandSize, 32);
|
||||
switch (compression) {
|
||||
case JKRCOMPRESSION_NONE:
|
||||
if (alignedSize > prevAlignedSize) {
|
||||
alignedSize = prevAlignedSize;
|
||||
}
|
||||
JKRAramToMainRam(srcAram, data, alignedSize, EXPAND_SWITCH_DEFAULT,
|
||||
prevAlignedSize, nullptr, -1, &sizeRef);
|
||||
return sizeRef;
|
||||
case JKRCOMPRESSION_YAY0:
|
||||
case JKRCOMPRESSION_YAZ0:
|
||||
JKRAramToMainRam(srcAram, data, alignedSize, EXPAND_SWITCH_DECOMPRESS,
|
||||
prevAlignedSize, nullptr, -1, &sizeRef);
|
||||
return sizeRef;
|
||||
default:
|
||||
JPANIC(550, ":::??? bad sequence\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
u32 JKRAramArchive::fetchResource_subroutine(u32 srcAram, u32 size,
|
||||
JKRHeap* heap, int compression,
|
||||
u8** pBuf) {
|
||||
u32 resSize;
|
||||
u32 alignedSize = ALIGN_NEXT(size, 32);
|
||||
|
||||
u8* buffer;
|
||||
switch (compression) {
|
||||
case JKRCOMPRESSION_NONE:
|
||||
buffer = (u8*)JKRAllocFromHeap(heap, alignedSize, 32);
|
||||
JUT_ASSERT(buffer != 0);
|
||||
|
||||
JKRAramToMainRam(srcAram, buffer, alignedSize, EXPAND_SWITCH_DEFAULT,
|
||||
alignedSize, nullptr, -1, nullptr);
|
||||
*pBuf = buffer;
|
||||
|
||||
return size;
|
||||
case JKRCOMPRESSION_YAY0:
|
||||
case JKRCOMPRESSION_YAZ0:
|
||||
u8* header = (u8*)JKRAllocFromHeap(heap, 0x20, 0x20);
|
||||
JKRAramToMainRam(srcAram, header, 0x20, EXPAND_SWITCH_DEFAULT, 0, nullptr,
|
||||
-1, nullptr);
|
||||
u32 expandSize = JKRDecompExpandSize(header);
|
||||
JKRFreeToHeap(heap, header);
|
||||
expandSize = ALIGN_NEXT(expandSize, 32);
|
||||
buffer = (u8*)JKRAllocFromHeap(heap, expandSize, 0x20);
|
||||
JUT_ASSERT(buffer);
|
||||
|
||||
JKRAramToMainRam(srcAram, buffer, alignedSize, EXPAND_SWITCH_DECOMPRESS,
|
||||
expandSize, heap, -1, &resSize);
|
||||
*pBuf = buffer;
|
||||
return resSize;
|
||||
default:
|
||||
JPANIC(605, ":::??? bad sequence\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,13 @@
|
||||
#include "JSystem/JKernel/JKRAram.h"
|
||||
|
||||
JKRAramBlock::JKRAramBlock(u32 address, u32 size, u32 freeSize, u8 groupID, bool tempMemory)
|
||||
: mLink(this)
|
||||
, mAddress(address)
|
||||
, mSize(size)
|
||||
, mFreeSize(freeSize)
|
||||
, mGroupID(groupID)
|
||||
, mIsTempMemory(tempMemory)
|
||||
{
|
||||
}
|
||||
JKRAramBlock::JKRAramBlock(u32 address, u32 size, u32 freeSize, u8 groupID,
|
||||
bool tempMemory)
|
||||
: mLink(this),
|
||||
mAddress(address),
|
||||
mSize(size),
|
||||
mFreeSize(freeSize),
|
||||
mGroupID(groupID),
|
||||
mIsTempMemory(tempMemory) {}
|
||||
|
||||
JKRAramBlock::~JKRAramBlock() {
|
||||
JSULink<JKRAramBlock>* prev = this->mLink.getPrev();
|
||||
@@ -28,7 +27,8 @@ JKRAramBlock* JKRAramBlock::allocHead(u32 size, u8 groupID, JKRAramHeap* heap) {
|
||||
u32 address = this->mAddress + this->mSize;
|
||||
u32 freeSize = this->mFreeSize - size;
|
||||
|
||||
JKRAramBlock* block = new(heap->mHeap, nullptr) JKRAramBlock(address, size, freeSize, groupID, false);
|
||||
JKRAramBlock* block = new (heap->mHeap, nullptr)
|
||||
JKRAramBlock(address, size, freeSize, groupID, false);
|
||||
this->mFreeSize = 0;
|
||||
this->mLink.mPtrList->insert(this->mLink.mNext, &block->mLink);
|
||||
return block;
|
||||
@@ -37,7 +37,8 @@ JKRAramBlock* JKRAramBlock::allocHead(u32 size, u8 groupID, JKRAramHeap* heap) {
|
||||
JKRAramBlock* JKRAramBlock::allocTail(u32 size, u8 groupID, JKRAramHeap* heap) {
|
||||
u32 address = this->mAddress + this->mSize + this->mFreeSize - size;
|
||||
|
||||
JKRAramBlock* block = new(heap->mHeap, nullptr) JKRAramBlock(address, size, 0, groupID, true);
|
||||
JKRAramBlock* block =
|
||||
new (heap->mHeap, nullptr) JKRAramBlock(address, size, 0, groupID, true);
|
||||
this->mFreeSize -= size;
|
||||
this->mLink.mPtrList->insert(this->mLink.mNext, &block->mLink);
|
||||
return block;
|
||||
|
||||
@@ -12,13 +12,13 @@ JKRAramHeap::JKRAramHeap(u32 baseAddress, u32 size) : JKRDisposer() {
|
||||
this->mTailAddress = this->mHeadAddress + this->mSize;
|
||||
this->mGroupID = 0xFF;
|
||||
JKRAramBlock* block = new (this->mHeap, nullptr)
|
||||
JKRAramBlock(this->mHeadAddress, 0, this->mSize, 0xFF, false);
|
||||
JKRAramBlock(this->mHeadAddress, 0, this->mSize, 0xFF, false);
|
||||
sAramList.append(&block->mLink);
|
||||
}
|
||||
|
||||
JKRAramHeap::~JKRAramHeap() {
|
||||
for (JSUListIterator<JKRAramBlock> it = sAramList.getFirst();
|
||||
it != sAramList.getEnd();) {
|
||||
it != sAramList.getEnd();) {
|
||||
delete (it++).getObject();
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,8 @@ JKRAramBlock* JKRAramHeap::alloc(u32 size, JKRAramHeap::EAllocMode mode) {
|
||||
|
||||
if (mode == Head) {
|
||||
block = this->allocFromHead(size);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
block = this->allocFromTail(size);
|
||||
}
|
||||
|
||||
@@ -37,10 +38,9 @@ JKRAramBlock* JKRAramHeap::alloc(u32 size, JKRAramHeap::EAllocMode mode) {
|
||||
return block;
|
||||
}
|
||||
|
||||
/* Code retrieved from Twilight Princess Debug version & matched. Unused in AC. */
|
||||
void JKRAramHeap::free(JKRAramBlock* block) {
|
||||
delete block;
|
||||
}
|
||||
/* Code retrieved from Twilight Princess Debug version & matched. Unused in AC.
|
||||
*/
|
||||
void JKRAramHeap::free(JKRAramBlock* block) { delete block; }
|
||||
|
||||
JKRAramBlock* JKRAramHeap::allocFromHead(u32 size) {
|
||||
size = ALIGN_NEXT(size, 32);
|
||||
@@ -48,7 +48,7 @@ JKRAramBlock* JKRAramHeap::allocFromHead(u32 size) {
|
||||
JKRAramBlock* block = nullptr;
|
||||
|
||||
for (JSUListIterator<JKRAramBlock> it = sAramList.getFirst();
|
||||
it != sAramList.getEnd(); it++) {
|
||||
it != sAramList.getEnd(); it++) {
|
||||
JKRAramBlock* n_block = it.getObject();
|
||||
if (n_block->mFreeSize >= size && min_size > n_block->mFreeSize) {
|
||||
min_size = n_block->mFreeSize;
|
||||
@@ -71,7 +71,7 @@ JKRAramBlock* JKRAramHeap::allocFromTail(u32 size) {
|
||||
size = ALIGN_NEXT(size, 32);
|
||||
|
||||
for (JSUListIterator<JKRAramBlock> it = sAramList.getLast();
|
||||
it != sAramList.getEnd(); it--) {
|
||||
it != sAramList.getEnd(); it--) {
|
||||
JKRAramBlock* n_block = it.getObject();
|
||||
|
||||
if (n_block->mFreeSize >= size) {
|
||||
@@ -96,23 +96,23 @@ void JKRAramHeap::dump() {
|
||||
JREPORT(" attr address: size gid\n");
|
||||
|
||||
for (JSUListIterator<JKRAramBlock> listItr = sAramList.getFirst();
|
||||
listItr != sAramList.getEnd(); listItr++) {
|
||||
listItr != sAramList.getEnd(); listItr++) {
|
||||
if (listItr->mSize != 0) {
|
||||
JREPORTF("%s %08x: %08x %3d\n",
|
||||
listItr->isTempMemory() ? " temp" : "alloc", listItr->mAddress,
|
||||
listItr->mSize, listItr->mGroupID);
|
||||
listItr->isTempMemory() ? " temp" : "alloc", listItr->mAddress,
|
||||
listItr->mSize, listItr->mGroupID);
|
||||
}
|
||||
|
||||
if (listItr->mFreeSize != 0) {
|
||||
JREPORTF(" free %08x: %08x 0\n", listItr->mAddress + listItr->mSize,
|
||||
listItr->mFreeSize);
|
||||
listItr->mFreeSize);
|
||||
}
|
||||
|
||||
total_used += listItr->mSize;
|
||||
}
|
||||
|
||||
JREPORTF("%d / %d bytes (%6.2f%%) used\n", total_used, this->mSize,
|
||||
(f32)total_used / (f32)this->mSize);
|
||||
(f32)total_used / (f32)this->mSize);
|
||||
|
||||
this->unlock();
|
||||
}
|
||||
@@ -122,7 +122,8 @@ u32 JKRAramHeap::getFreeSize() {
|
||||
u32 max_free = 0;
|
||||
this->lock();
|
||||
|
||||
for (JSUListIterator<JKRAramBlock> it = sAramList.getFirst(); it != sAramList.getEnd(); it++) {
|
||||
for (JSUListIterator<JKRAramBlock> it = sAramList.getFirst();
|
||||
it != sAramList.getEnd(); it++) {
|
||||
if (it->mFreeSize > max_free) {
|
||||
max_free = it->mFreeSize;
|
||||
}
|
||||
@@ -137,7 +138,8 @@ u32 JKRAramHeap::getTotalFreeSize() {
|
||||
u32 total_free = 0;
|
||||
this->lock();
|
||||
|
||||
for (JSUListIterator<JKRAramBlock> it = sAramList.getFirst(); it != sAramList.getEnd(); it++) {
|
||||
for (JSUListIterator<JKRAramBlock> it = sAramList.getFirst();
|
||||
it != sAramList.getEnd(); it++) {
|
||||
total_free += it->mFreeSize;
|
||||
}
|
||||
|
||||
@@ -154,7 +156,8 @@ u32 JKRAramHeap::getUsedSize(u8 groupID) {
|
||||
total_used = this->mSize - this->getTotalFreeSize();
|
||||
}
|
||||
else {
|
||||
for (JSUListIterator<JKRAramBlock> it = sAramList.getFirst(); it != sAramList.getEnd(); it++) {
|
||||
for (JSUListIterator<JKRAramBlock> it = sAramList.getFirst();
|
||||
it != sAramList.getEnd(); it++) {
|
||||
if (groupID == it->mGroupID) {
|
||||
total_used += it->mSize;
|
||||
}
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
#include "types.h"
|
||||
#include "JSystem/JKernel/JKRAram.h"
|
||||
#include "JSystem/JKernel/JKRDecomp.h"
|
||||
#include "JSystem/JKernel/JKRHeap.h"
|
||||
#include "JSystem/JKernel/JKRMacro.h"
|
||||
#include "JSystem/JSystem.h"
|
||||
#include "dolphin/ar.h"
|
||||
#include "dolphin/os.h" /* TODO: OSReport lives in libforest in AC */
|
||||
#include "dolphin/os/OSCache.h"
|
||||
#include "dolphin/os/OSMessage.h"
|
||||
#include "dolphin/os.h" /* TODO: OSReport lives in libforest in AC */
|
||||
#include "JSystem/JKernel/JKRMacro.h"
|
||||
#include "JSystem/JKernel/JKRHeap.h"
|
||||
#include "JSystem/JKernel/JKRDecomp.h"
|
||||
#include "JSystem/JSystem.h"
|
||||
|
||||
#include "JSystem/JKernel/JKRAram.h"
|
||||
#include "types.h"
|
||||
|
||||
JSUList<JKRAMCommand> JKRAramPiece::sAramPieceCommandList;
|
||||
OSMutex JKRAramPiece::mMutex;
|
||||
|
||||
JKRAMCommand* JKRAramPiece::prepareCommand(int direction, u32 source, u32 destination, u32 length, JKRAramBlock* aramBlock, JKRAMCommand::AMCommandCallback callback) {
|
||||
JKRAMCommand* JKRAramPiece::prepareCommand(
|
||||
int direction, u32 source, u32 destination, u32 length,
|
||||
JKRAramBlock* aramBlock, JKRAMCommand::AMCommandCallback callback) {
|
||||
JKRAMCommand* cmd = new (JKRGetSystemHeap(), -4) JKRAMCommand();
|
||||
cmd->mDirection = direction;
|
||||
cmd->mSource = source;
|
||||
@@ -29,7 +30,9 @@ void JKRAramPiece::sendCommand(JKRAMCommand* cmd) {
|
||||
JKRAramPiece::startDMA(cmd);
|
||||
}
|
||||
|
||||
JKRAMCommand* JKRAramPiece::orderAsync(int direction, u32 source, u32 destination, u32 length, JKRAramBlock* aramBlock, JKRAMCommand::AMCommandCallback callback) {
|
||||
JKRAMCommand* JKRAramPiece::orderAsync(
|
||||
int direction, u32 source, u32 destination, u32 length,
|
||||
JKRAramBlock* aramBlock, JKRAMCommand::AMCommandCallback callback) {
|
||||
JKRAramPiece::lock();
|
||||
|
||||
if (!JKR_ISALIGNED32(source) || !JKR_ISALIGNED32(destination)) {
|
||||
@@ -41,9 +44,11 @@ JKRAMCommand* JKRAramPiece::orderAsync(int direction, u32 source, u32 destinatio
|
||||
}
|
||||
|
||||
JKRAramCommand* aramCmd = new (JKRGetSystemHeap(), -4) JKRAramCommand();
|
||||
JKRAMCommand* cmd = JKRAramPiece::prepareCommand(direction, source, destination, length, aramBlock, callback);
|
||||
JKRAMCommand* cmd = JKRAramPiece::prepareCommand(
|
||||
direction, source, destination, length, aramBlock, callback);
|
||||
aramCmd->setting(TRUE, cmd);
|
||||
OSSendMessage((OSMessageQueue*)&JKRAram::sMessageQueue, (OSMessage)aramCmd, OS_MESSAGE_BLOCK);
|
||||
OSSendMessage((OSMessageQueue*)&JKRAram::sMessageQueue, (OSMessage)aramCmd,
|
||||
OS_MESSAGE_BLOCK);
|
||||
if (cmd->mCallback != nullptr) {
|
||||
JKRAramPiece::sAramPieceCommandList.append(&cmd->mAramPieceCommandLink);
|
||||
}
|
||||
@@ -76,11 +81,12 @@ bool JKRAramPiece::sync(JKRAMCommand* cmd, BOOL noBlock) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool JKRAramPiece::orderSync(int direction, u32 source, u32 destination, u32 length, JKRAramBlock* aramBlock) {
|
||||
bool JKRAramPiece::orderSync(int direction, u32 source, u32 destination,
|
||||
u32 length, JKRAramBlock* aramBlock) {
|
||||
JKRAramPiece::lock();
|
||||
|
||||
JKRAMCommand* cmd = JKRAramPiece::orderAsync(direction, source, destination, length, aramBlock, nullptr);
|
||||
JKRAMCommand* cmd = JKRAramPiece::orderAsync(direction, source, destination,
|
||||
length, aramBlock, nullptr);
|
||||
bool res = JKRAramPiece::sync(cmd, FALSE);
|
||||
delete cmd;
|
||||
|
||||
@@ -96,7 +102,8 @@ void JKRAramPiece::startDMA(JKRAMCommand* cmd) {
|
||||
DCStoreRange((u8*)cmd->mSource, cmd->mLength);
|
||||
}
|
||||
|
||||
ARQPostRequest(cmd, 0, cmd->mDirection, 0, cmd->mSource, cmd->mDestination, cmd->mLength, JKRAramPiece::doneDMA);
|
||||
ARQPostRequest(cmd, 0, cmd->mDirection, 0, cmd->mSource, cmd->mDestination,
|
||||
cmd->mLength, JKRAramPiece::doneDMA);
|
||||
}
|
||||
|
||||
void JKRAramPiece::doneDMA(u32 param) {
|
||||
@@ -115,7 +122,8 @@ void JKRAramPiece::doneDMA(u32 param) {
|
||||
}
|
||||
else {
|
||||
if (cmd->mCompletedMesgQueue != nullptr) {
|
||||
OSSendMessage(cmd->mCompletedMesgQueue, (OSMessage)cmd, OS_MESSAGE_NOBLOCK);
|
||||
OSSendMessage(cmd->mCompletedMesgQueue, (OSMessage)cmd,
|
||||
OS_MESSAGE_NOBLOCK);
|
||||
}
|
||||
else {
|
||||
OSSendMessage(&cmd->mMesgQueue, (OSMessage)cmd, OS_MESSAGE_NOBLOCK);
|
||||
|
||||
@@ -1,4 +1,215 @@
|
||||
#include "JKRAram.h"
|
||||
#include "JSUStream.h"
|
||||
#include <dolphin/os.h>
|
||||
|
||||
#include "JSystem/JKernel/JKRAram.h"
|
||||
#include "JSystem/JSupport/JSUStream.h"
|
||||
#include "JSystem/JSystem.h"
|
||||
#include "JSystem/JUtility/JUTAssertion.h"
|
||||
#include "types.h"
|
||||
|
||||
// From Pikmin Repo
|
||||
|
||||
OSMessage JKRAramStream::sMessageBuffer[4] = { 0 };
|
||||
OSMessageQueue JKRAramStream::sMessageQueue = { 0 };
|
||||
|
||||
JKRAramStream* JKRAramStream::sAramStreamObject = nullptr;
|
||||
u8* JKRAramStream::transBuffer = nullptr;
|
||||
u32 JKRAramStream::transSize = nullptr;
|
||||
JKRHeap* JKRAramStream::transHeap = nullptr;
|
||||
|
||||
JKRAramStream* JKRAramStream::create(s32 param) {
|
||||
if (JKRAramStream::sAramStreamObject == nullptr) {
|
||||
JKRAramStream::sAramStreamObject =
|
||||
new (JKRGetSystemHeap(), 0) JKRAramStream(param);
|
||||
setTransBuffer(nullptr, 0, nullptr);
|
||||
}
|
||||
return JKRAramStream::sAramStreamObject;
|
||||
}
|
||||
|
||||
JKRAramStream::JKRAramStream(s32 priority) : JKRThread(0x4000, 0x10, priority) {
|
||||
OSResumeThread(mThreadRecord);
|
||||
}
|
||||
|
||||
JKRAramStream::~JKRAramStream() {};
|
||||
|
||||
void* JKRAramStream::run() {
|
||||
OSMessage result;
|
||||
OSInitMessageQueue(
|
||||
&JKRAramStream::sMessageQueue, JKRAramStream::sMessageBuffer,
|
||||
ARRAY_COUNT(sMessageBuffer)); // jank cast to void** to satisfy prototype
|
||||
while (true) {
|
||||
OSReceiveMessage(&JKRAramStream::sMessageQueue, &result, OS_MESSAGE_BLOCK);
|
||||
JKRAramStreamCommand* command = static_cast<JKRAramStreamCommand*>(result);
|
||||
switch (command->type) {
|
||||
case JKRAramStreamCommand::ECT_READ:
|
||||
readFromAram();
|
||||
break;
|
||||
case JKRAramStreamCommand::ECT_WRITE:
|
||||
writeToAram(command);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u32 JKRAramStream::readFromAram() {
|
||||
return 1;
|
||||
} // probably a define evaluating to 1
|
||||
|
||||
s32 JKRAramStream::writeToAram(JKRAramStreamCommand* command) {
|
||||
u32 dstSize = command->mSize;
|
||||
u32 offset = command->mOffset;
|
||||
u32 writtenLength = 0;
|
||||
u32 destination = command->mAddress;
|
||||
u8* buffer = command->mTransferBuffer;
|
||||
u32 bufferSize = command->mTransferBufferSize;
|
||||
JKRHeap* heap = command->mHeap;
|
||||
if (buffer) {
|
||||
bufferSize = (bufferSize == nullptr) ? 0x8000 : bufferSize;
|
||||
|
||||
command->mTransferBufferSize = bufferSize;
|
||||
command->mAllocatedTransferBuffer = false;
|
||||
}
|
||||
else {
|
||||
bufferSize = (bufferSize == nullptr) ? 0x8000 : bufferSize;
|
||||
|
||||
if (heap) {
|
||||
buffer = (u8*)JKRAllocFromHeap(heap, bufferSize, -0x20);
|
||||
command->mTransferBuffer = buffer;
|
||||
}
|
||||
else {
|
||||
buffer = (u8*)JKRAllocFromHeap(nullptr, bufferSize, -0x20);
|
||||
command->mTransferBuffer = buffer;
|
||||
}
|
||||
|
||||
command->mTransferBufferSize = bufferSize;
|
||||
command->mAllocatedTransferBuffer = true;
|
||||
}
|
||||
|
||||
if (!buffer) {
|
||||
if (!heap) {
|
||||
JKRGetCurrentHeap()->dump();
|
||||
}
|
||||
else {
|
||||
heap->dump();
|
||||
}
|
||||
JPANIC(169, "abort\n");
|
||||
}
|
||||
|
||||
if (buffer) {
|
||||
command->mStream->seek(offset, SEEK_SET);
|
||||
while (dstSize != 0) {
|
||||
u32 length = (dstSize > bufferSize) ? bufferSize : dstSize;
|
||||
|
||||
s32 readLength = command->mStream->read(buffer, length);
|
||||
|
||||
JKRAramPcs(0, (u32)buffer, destination, length, nullptr);
|
||||
dstSize -= length;
|
||||
writtenLength += length;
|
||||
destination += length;
|
||||
}
|
||||
|
||||
if (command->mAllocatedTransferBuffer) {
|
||||
JKRFree(buffer);
|
||||
command->mAllocatedTransferBuffer = false;
|
||||
}
|
||||
}
|
||||
|
||||
OSSendMessage(&command->mMessageQueue, (OSMessage)writtenLength,
|
||||
OS_MESSAGE_NOBLOCK);
|
||||
return writtenLength;
|
||||
};
|
||||
|
||||
/*
|
||||
* Unused function, made-up contents. Do not take this seriously!
|
||||
* While the function exists in the map, this is almost certainly incorrect.
|
||||
* Should exist to generate JSURandomInputStream::getAvailable() const
|
||||
* afterwards.
|
||||
*/
|
||||
JKRAramStreamCommand* JKRAramStream::write_StreamToAram_Async(
|
||||
JSUFileInputStream* stream, JKRAramBlock* addr, u32 size, u32 offset) {
|
||||
JKRAramStreamCommand* command =
|
||||
new (JKRGetSystemHeap(), -4) JKRAramStreamCommand();
|
||||
command->type = JKRAramStreamCommand::ECT_WRITE;
|
||||
command->mAddress = (u32)addr;
|
||||
command->mSize = size;
|
||||
command->mStream = stream;
|
||||
command->_28 = stream->getAvailable();
|
||||
command->mOffset = offset;
|
||||
command->mTransferBuffer = transBuffer;
|
||||
command->mHeap = transHeap;
|
||||
command->mTransferBufferSize = transSize;
|
||||
|
||||
OSInitMessageQueue(&command->mMessageQueue, &command->mMessage, 1);
|
||||
OSSendMessage(&sMessageQueue, command, OS_MESSAGE_BLOCK);
|
||||
return command;
|
||||
}
|
||||
|
||||
JKRAramStreamCommand* JKRAramStream::write_StreamToAram_Async(
|
||||
JSUFileInputStream* stream, u32 addr, u32 size, u32 offset) {
|
||||
JKRAramStreamCommand* command =
|
||||
new (JKRGetSystemHeap(), -4) JKRAramStreamCommand();
|
||||
command->type = JKRAramStreamCommand::ECT_WRITE;
|
||||
command->mAddress = addr;
|
||||
command->mSize = size;
|
||||
command->mStream = stream;
|
||||
command->_28 = 0;
|
||||
command->mOffset = offset;
|
||||
command->mTransferBuffer = transBuffer;
|
||||
command->mHeap = transHeap;
|
||||
command->mTransferBufferSize = transSize;
|
||||
|
||||
OSInitMessageQueue(&command->mMessageQueue, &command->mMessage, 1);
|
||||
OSSendMessage(&sMessageQueue, command, OS_MESSAGE_BLOCK);
|
||||
return command;
|
||||
}
|
||||
|
||||
JKRAramStreamCommand* JKRAramStream::sync(JKRAramStreamCommand* command,
|
||||
BOOL isNonBlocking) {
|
||||
OSMessage msg;
|
||||
if (isNonBlocking == FALSE) {
|
||||
OSReceiveMessage(&command->mMessageQueue, &msg, OS_MESSAGE_BLOCK);
|
||||
if (msg == nullptr) {
|
||||
command = nullptr;
|
||||
return command;
|
||||
}
|
||||
else {
|
||||
return command;
|
||||
}
|
||||
}
|
||||
else {
|
||||
BOOL receiveResult =
|
||||
OSReceiveMessage(&command->mMessageQueue, &msg, OS_MESSAGE_NOBLOCK);
|
||||
if (receiveResult == FALSE) {
|
||||
command = nullptr;
|
||||
return command;
|
||||
}
|
||||
else if (msg == nullptr) {
|
||||
command = nullptr;
|
||||
return command;
|
||||
}
|
||||
else {
|
||||
return command;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JKRAramStream::setTransBuffer(u8* buffer, u32 bufferSize, JKRHeap* heap) {
|
||||
transBuffer = nullptr;
|
||||
transSize = 0x8000;
|
||||
transHeap = nullptr;
|
||||
|
||||
if (buffer) {
|
||||
transBuffer = (u8*)ALIGN_NEXT((u32)buffer, 0x20);
|
||||
}
|
||||
|
||||
if (bufferSize) {
|
||||
transSize = ALIGN_PREV(bufferSize, 0x20);
|
||||
}
|
||||
|
||||
if (heap && !buffer) {
|
||||
transHeap = heap;
|
||||
}
|
||||
}
|
||||
|
||||
JKRAramStreamCommand::JKRAramStreamCommand() {
|
||||
mAllocatedTransferBuffer = false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,242 @@
|
||||
#include <MSL_C/ctype.h>
|
||||
#include <dolphin/string.h>
|
||||
|
||||
#include "JSystem/JKernel/JKRArchive.h"
|
||||
#include "JSystem/JKernel/JKRFileLoader.h"
|
||||
#include "types.h"
|
||||
|
||||
u32 JKRArchive::sCurrentDirID;
|
||||
|
||||
JKRArchive::JKRArchive()
|
||||
{
|
||||
mIsMounted = false;
|
||||
mMountDirection = MOUNT_DIRECTION_HEAD;
|
||||
}
|
||||
|
||||
JKRArchive::JKRArchive(s32 entryNum, JKRArchive::EMountMode mountMode)
|
||||
: JKRFileLoader()
|
||||
{
|
||||
mIsMounted = false;
|
||||
mMountMode = mountMode;
|
||||
mMountCount = 1;
|
||||
_54 = 1;
|
||||
mHeap = JKRHeap::findFromRoot(this);
|
||||
if (!mHeap)
|
||||
{
|
||||
mHeap = JKRHeap::sCurrentHeap;
|
||||
}
|
||||
mEntryNum = entryNum;
|
||||
if (sCurrentVolume == nullptr)
|
||||
{
|
||||
sCurrentDirID = 0;
|
||||
sCurrentVolume = this;
|
||||
}
|
||||
}
|
||||
|
||||
JKRArchive::JKRArchive(const char* p1, JKRArchive::EMountMode mountMode)
|
||||
{
|
||||
// UNUSED FUNCTION
|
||||
}
|
||||
|
||||
JKRArchive::~JKRArchive() {}
|
||||
|
||||
bool JKRArchive::isSameName(JKRArchive::CArcName& archiveName,
|
||||
u32 nameTableOffset, u16 hash) const
|
||||
{
|
||||
u16 arcHash = archiveName.getHash();
|
||||
if (arcHash != hash)
|
||||
return false;
|
||||
|
||||
return strcmp(&mStrTable[nameTableOffset], archiveName.getString()) == 0;
|
||||
}
|
||||
|
||||
JKRArchive::SDIDirEntry* JKRArchive::findResType(u32 type) const
|
||||
{
|
||||
SDIDirEntry* dirEntry = mDirectories;
|
||||
for (u32 i = 0; i < mArcInfoBlock->num_nodes; i++, dirEntry++)
|
||||
{
|
||||
if (dirEntry->mType == type)
|
||||
{
|
||||
return dirEntry;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JKRArchive::SDIDirEntry* JKRArchive::findDirectory(const char* path,
|
||||
u32 index) const
|
||||
{
|
||||
if (path == nullptr)
|
||||
{
|
||||
return &mDirectories[index];
|
||||
}
|
||||
|
||||
CArcName arcName(&path, '/');
|
||||
SDIDirEntry* dirEntry = &mDirectories[index];
|
||||
SDIFileEntry* entry = &mFileEntries[dirEntry->mFirstIdx];
|
||||
|
||||
for (int i = 0; i < dirEntry->mNum; entry++, i++)
|
||||
{
|
||||
if (isSameName(arcName, entry->mFlag & 0xFFFFFF, entry->mHash))
|
||||
{
|
||||
if ((entry->mFlag >> 24) & 0x02)
|
||||
{
|
||||
return findDirectory(path, entry->mDataOffset);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JKRArchive::SDIFileEntry* JKRArchive::findTypeResource(u32 type,
|
||||
const char* name) const
|
||||
{
|
||||
if (type != 0)
|
||||
{
|
||||
CArcName arcName;
|
||||
arcName.store(name);
|
||||
SDIDirEntry* dirEntry = findResType(type);
|
||||
if (dirEntry != nullptr)
|
||||
{
|
||||
SDIFileEntry* fileEntry = mFileEntries + dirEntry->mFirstIdx;
|
||||
for (int i = 0; i < dirEntry->mNum; fileEntry++, i++)
|
||||
{
|
||||
if (isSameName(arcName, fileEntry->mFlag & 0xFFFFFF,
|
||||
fileEntry->mHash))
|
||||
{
|
||||
return fileEntry;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JKRArchive::SDIFileEntry* JKRArchive::findFsResource(const char* path,
|
||||
u32 index) const
|
||||
{
|
||||
if (path)
|
||||
{
|
||||
CArcName arcName(&path, '/');
|
||||
SDIDirEntry* dirEntry = &mDirectories[index];
|
||||
SDIFileEntry* entry = &mFileEntries[dirEntry->mFirstIdx];
|
||||
for (int i = 0; i < dirEntry->mNum; entry++, i++)
|
||||
{
|
||||
if (isSameName(arcName, entry->mFlag & 0xFFFFFF, entry->mHash))
|
||||
{
|
||||
if (((entry->mFlag >> 0x18) & 2))
|
||||
{
|
||||
return findFsResource(path, entry->mDataOffset);
|
||||
}
|
||||
if (path == 0)
|
||||
{
|
||||
return entry;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JKRArchive::SDIFileEntry* JKRArchive::findIdxResource(u32 idx) const
|
||||
{
|
||||
if (idx < mArcInfoBlock->num_file_entries)
|
||||
{
|
||||
return mFileEntries + idx;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JKRArchive::SDIFileEntry* JKRArchive::findNameResource(const char* name) const
|
||||
{
|
||||
SDIFileEntry* fileEntry = mFileEntries;
|
||||
|
||||
CArcName arcName(name);
|
||||
for (int i = 0; i < mArcInfoBlock->num_file_entries; fileEntry++, i++)
|
||||
{
|
||||
if (isSameName(arcName, fileEntry->mFlag & 0xFFFFFF, fileEntry->mHash))
|
||||
{
|
||||
return fileEntry;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JKRArchive::SDIFileEntry* JKRArchive::findPtrResource(const void* ptr) const
|
||||
{
|
||||
SDIFileEntry* entry = mFileEntries;
|
||||
for (u32 i = 0; i < mArcInfoBlock->num_file_entries; entry++, i++)
|
||||
{
|
||||
if (entry->mData == ptr)
|
||||
{
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JKRArchive::SDIFileEntry* JKRArchive::findIdResource(u16 id) const
|
||||
{
|
||||
SDIFileEntry* entry;
|
||||
if (id != 0xFFFF)
|
||||
{
|
||||
entry = &mFileEntries[id];
|
||||
if (entry->mFileID == id && (entry->getFlag01()))
|
||||
{
|
||||
return entry;
|
||||
}
|
||||
|
||||
entry = mFileEntries;
|
||||
for (int i = 0; i < mArcInfoBlock->num_file_entries; entry++, i++)
|
||||
{
|
||||
if (entry->mFileID == id && (entry->getFlag01()))
|
||||
{
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void JKRArchive::CArcName::store(const char* name)
|
||||
{
|
||||
mHash = 0;
|
||||
int count = 0;
|
||||
while (*name)
|
||||
{
|
||||
int lower = tolower(*name);
|
||||
mHash = lower + mHash * 3;
|
||||
if (count < 0x100)
|
||||
{
|
||||
mString[count++] = lower;
|
||||
}
|
||||
name++;
|
||||
}
|
||||
_02 = count;
|
||||
mString[count] = '\0';
|
||||
}
|
||||
|
||||
const char* JKRArchive::CArcName::store(const char* name, char endChar)
|
||||
{
|
||||
mHash = 0;
|
||||
int count = 0;
|
||||
for (; *name && *name != endChar; name++)
|
||||
{
|
||||
int lower = tolower(*name);
|
||||
mHash = lower + mHash * 3;
|
||||
if (count < 0x100)
|
||||
{
|
||||
mString[count++] = lower;
|
||||
}
|
||||
}
|
||||
_02 = count;
|
||||
mString[count] = '\0';
|
||||
|
||||
if (*name == 0)
|
||||
return nullptr;
|
||||
return name + 1;
|
||||
}
|
||||
@@ -0,0 +1,340 @@
|
||||
#include <dolphin/dvd.h>
|
||||
|
||||
#include "JSystem/JKernel/JKRAram.h"
|
||||
#include "JSystem/JKernel/JKRArchive.h"
|
||||
#include "JSystem/JKernel/JKRDisposer.h"
|
||||
#include "JSystem/JKernel/JKRFileFinder.h"
|
||||
#include "JSystem/JKernel/JKRHeap.h"
|
||||
#include "JSystem/JUtility/JUTAssertion.h"
|
||||
#include "types.h"
|
||||
|
||||
// TODO: this file should emit a vtable but it doesn't, luckily JKRArchivePri
|
||||
// does that and it doesn't cause any issues
|
||||
|
||||
JKRArchive* JKRArchive::check_mount_already(s32 entryNum, JKRHeap* pHeap) {
|
||||
// UNUSED FUNCTION
|
||||
JKRHeap* heap = pHeap;
|
||||
if (heap == nullptr) {
|
||||
heap = JKRGetCurrentHeap();
|
||||
}
|
||||
|
||||
JSUList<JKRFileLoader>& volumeList = JKRArchive::sVolumeList;
|
||||
JSUListIterator<JKRFileLoader> iterator;
|
||||
for (iterator = volumeList.getFirst(); iterator != volumeList.getEnd();
|
||||
++iterator) {
|
||||
if (iterator->getVolumeType() == 'RARC') {
|
||||
JKRArchive* archive =
|
||||
(JKRArchive*)
|
||||
iterator.getObject(); // in TP debug it calls operator-> ?
|
||||
if (archive->mEntryNum == entryNum && archive->mHeap == heap) {
|
||||
archive->mMountCount++;
|
||||
return archive;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JKRArchive* JKRArchive::check_mount_already(s32 entryNum) {
|
||||
JSUList<JKRFileLoader>& volumeList = JKRArchive::sVolumeList;
|
||||
JSUListIterator<JKRFileLoader> iterator;
|
||||
for (iterator = volumeList.getFirst(); iterator != volumeList.getEnd();
|
||||
++iterator) {
|
||||
if (iterator->getVolumeType() == 'RARC') {
|
||||
JKRArchive* archive =
|
||||
(JKRArchive*)
|
||||
iterator.getObject(); // in TP debug it calls operator-> ?
|
||||
if (archive->mEntryNum == entryNum) {
|
||||
archive->mMountCount++;
|
||||
return archive;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JKRArchive* JKRArchive::mount(const char* path, EMountMode mode, JKRHeap* heap,
|
||||
EMountDirection direction) {
|
||||
int entryNum = DVDConvertPathToEntrynum((char*)path);
|
||||
if (entryNum < 0) return nullptr;
|
||||
|
||||
JKRArchive* mountedArchive = check_mount_already(entryNum);
|
||||
if (mountedArchive != nullptr) {
|
||||
return mountedArchive;
|
||||
}
|
||||
|
||||
int alignment = (direction == MOUNT_DIRECTION_HEAD) ? 4 : -4;
|
||||
JKRArchive* archive;
|
||||
switch (mode) {
|
||||
case MOUNT_MEM:
|
||||
if (entryNum == -1)
|
||||
archive = nullptr;
|
||||
else
|
||||
archive = new (heap, alignment) JKRMemArchive(entryNum, direction);
|
||||
break;
|
||||
case MOUNT_ARAM:
|
||||
archive = new (heap, alignment) JKRAramArchive(entryNum, direction);
|
||||
break;
|
||||
case MOUNT_DVD:
|
||||
archive = new (heap, alignment) JKRDvdArchive(entryNum, direction);
|
||||
break;
|
||||
case MOUNT_COMP:
|
||||
archive = new (heap, alignment) JKRCompArchive(entryNum, direction);
|
||||
break;
|
||||
}
|
||||
if (archive != nullptr && archive->getMountMode() == UNKNOWN_MOUNT_MODE) {
|
||||
delete archive;
|
||||
archive = nullptr;
|
||||
}
|
||||
return archive;
|
||||
}
|
||||
|
||||
JKRArchive* JKRArchive::mount(void* p1, JKRHeap* heap,
|
||||
EMountDirection mountDirection) {
|
||||
JKRArchive* archive = check_mount_already((s32)p1, heap);
|
||||
if (archive != nullptr) {
|
||||
return archive;
|
||||
}
|
||||
return new (heap, (mountDirection == MOUNT_DIRECTION_HEAD) ? 4 : -4)
|
||||
JKRMemArchive(p1, 0xFFFF, MBF_0);
|
||||
}
|
||||
|
||||
JKRArchive* JKRArchive::mount(s32 entryNum, EMountMode mountMode, JKRHeap* heap,
|
||||
EMountDirection mountDirection) {
|
||||
JKRArchive* archive = check_mount_already(entryNum, heap);
|
||||
if (archive) {
|
||||
return archive;
|
||||
}
|
||||
else {
|
||||
int i = (mountDirection == MOUNT_DIRECTION_HEAD) ? 4 : -4;
|
||||
JKRArchive* archive;
|
||||
switch (mountMode) {
|
||||
case MOUNT_MEM:
|
||||
archive = new (heap, i) JKRMemArchive(entryNum, mountDirection);
|
||||
break;
|
||||
case MOUNT_ARAM:
|
||||
archive = new (heap, i) JKRAramArchive(entryNum, mountDirection);
|
||||
break;
|
||||
case MOUNT_DVD:
|
||||
archive = new (heap, i) JKRDvdArchive(entryNum, mountDirection);
|
||||
break;
|
||||
case MOUNT_COMP:
|
||||
archive = new (heap, i) JKRCompArchive(entryNum, mountDirection);
|
||||
break;
|
||||
}
|
||||
if (archive != nullptr && archive->getMountMode() == UNKNOWN_MOUNT_MODE) {
|
||||
delete archive;
|
||||
archive = nullptr;
|
||||
}
|
||||
return archive;
|
||||
}
|
||||
}
|
||||
|
||||
bool JKRArchive::becomeCurrent(const char* path) {
|
||||
SDIDirEntry* entry;
|
||||
if (*path == '/') {
|
||||
const char* directoryName = path + 1;
|
||||
if (*directoryName == '\0') {
|
||||
directoryName = nullptr;
|
||||
}
|
||||
entry = findDirectory(directoryName, 0);
|
||||
}
|
||||
else {
|
||||
entry = findDirectory(path, sCurrentDirID);
|
||||
}
|
||||
bool result = (entry != nullptr);
|
||||
if (result) {
|
||||
sCurrentVolume = this;
|
||||
sCurrentDirID = (entry - mDirectories);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool JKRArchive::getDirEntry(JKRArchive::SDirEntry* dirEntry, u32 p2) const {
|
||||
SDIFileEntry* fileEntry = findIdxResource(p2);
|
||||
if (!fileEntry) {
|
||||
return false;
|
||||
}
|
||||
|
||||
dirEntry->mFlags = fileEntry->mFlag >> 0x18;
|
||||
dirEntry->mID = fileEntry->mFileID;
|
||||
dirEntry->mName = (char*)mStrTable + (fileEntry->mFlag & 0xFFFFFF);
|
||||
return true;
|
||||
}
|
||||
|
||||
void* JKRArchive::getGlbResource(u32 type, const char* name,
|
||||
JKRArchive* archive) {
|
||||
void* resource = nullptr;
|
||||
if (archive) {
|
||||
return archive->getResource(type, name);
|
||||
}
|
||||
for (JSULink<JKRFileLoader>* link = sVolumeList.getFirst(); link != nullptr;
|
||||
link = link->getNext()) {
|
||||
if (link->getObject()->getVolumeType() == 'RARC' &&
|
||||
(resource = link->getObject()->getResource(type, name))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return resource;
|
||||
}
|
||||
|
||||
void* JKRArchive::getResource(const char* path) {
|
||||
JUT_ASSERT(isMounted());
|
||||
SDIFileEntry* fileEntry;
|
||||
if (*path == '/') {
|
||||
fileEntry = findFsResource(path + 1, 0);
|
||||
}
|
||||
else {
|
||||
fileEntry = findFsResource(path, sCurrentDirID);
|
||||
}
|
||||
return (fileEntry != nullptr) ? (void*)fetchResource(fileEntry, nullptr)
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
void* JKRArchive::getResource(u32 type, const char* name) {
|
||||
JUT_ASSERT(isMounted());
|
||||
SDIFileEntry* fileEntry;
|
||||
if (type == 0 || type == '????') {
|
||||
fileEntry = findNameResource(name);
|
||||
}
|
||||
else {
|
||||
fileEntry = findTypeResource(type, name);
|
||||
}
|
||||
return (fileEntry != nullptr) ? (void*)fetchResource(fileEntry, nullptr)
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
void* JKRArchive::getIdxResource(u32 index) {
|
||||
SDIFileEntry* fileEntry = findIdxResource(index);
|
||||
return (fileEntry != nullptr) ? (void*)fetchResource(fileEntry, nullptr)
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
size_t JKRArchive::readResource(void* resourceBuffer, u32 bufferSize, u32 type,
|
||||
const char* name) {
|
||||
JUT_ASSERT(isMounted());
|
||||
SDIFileEntry* fileEntry;
|
||||
if (type == 0 || type == '????') {
|
||||
fileEntry = findNameResource(name);
|
||||
}
|
||||
else {
|
||||
fileEntry = findTypeResource(type, name);
|
||||
}
|
||||
if (fileEntry) {
|
||||
u32 resourceSize;
|
||||
fetchResource(resourceBuffer, bufferSize, fileEntry, &resourceSize,
|
||||
EXPAND_SWITCH_DECOMPRESS);
|
||||
return resourceSize;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Returns the size of the resource at the given path, or 0 if not found.
|
||||
size_t JKRArchive::readResource(void* resourceBuffer, u32 bufferSize,
|
||||
const char* path,
|
||||
JKRExpandSwitch expandSwitch) {
|
||||
JUT_ASSERT(isMounted());
|
||||
SDIFileEntry* fileEntry;
|
||||
if (*path == '/') {
|
||||
fileEntry = findFsResource(path + 1, 0);
|
||||
}
|
||||
else {
|
||||
fileEntry = findFsResource(path, sCurrentDirID);
|
||||
}
|
||||
if (fileEntry) {
|
||||
u32 resourceSize;
|
||||
fetchResource(resourceBuffer, bufferSize, fileEntry, &resourceSize,
|
||||
expandSwitch);
|
||||
return resourceSize;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Returns the size of the resource with the given ID, or 0 if not found.
|
||||
size_t JKRArchive::readResource(void* resourceBuffer, u32 bufferSize, u16 id) {
|
||||
JUT_ASSERT(isMounted());
|
||||
SDIFileEntry* fileEntry = findIdResource(id);
|
||||
if (fileEntry) {
|
||||
u32 resSize;
|
||||
fetchResource(resourceBuffer, bufferSize, fileEntry, &resSize,
|
||||
EXPAND_SWITCH_DEFAULT);
|
||||
return resSize;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// This function is currently full off bugs, it doesn't increase the pointer to
|
||||
// the file entries, and sets the pointer of mData to null before it's sent to
|
||||
// free
|
||||
void JKRArchive::removeResourceAll() {
|
||||
if (mArcInfoBlock && mMountMode != MOUNT_MEM) {
|
||||
SDIFileEntry* entry = mFileEntries;
|
||||
for (int i = 0; i < mArcInfoBlock->num_file_entries; i++) {
|
||||
if (entry->mData) {
|
||||
entry->mData = nullptr;
|
||||
JKRFreeToHeap(mHeap, entry->mData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool JKRArchive::removeResource(void* resource) {
|
||||
JUT_ASSERT(resource != 0);
|
||||
SDIFileEntry* entry = findPtrResource(resource);
|
||||
if (entry == nullptr) {
|
||||
return false;
|
||||
}
|
||||
entry->mData = nullptr;
|
||||
JKRHeap::free(resource, mHeap);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool JKRArchive::detachResource(void* resource) {
|
||||
JUT_ASSERT(resource != 0);
|
||||
SDIFileEntry* entry = findPtrResource(resource);
|
||||
if (entry == nullptr) {
|
||||
return false;
|
||||
}
|
||||
entry->mData = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
s32 JKRArchive::getResSize(const void* resource) const {
|
||||
JUT_ASSERT(resource != 0);
|
||||
SDIFileEntry* entry = findPtrResource(resource);
|
||||
return (entry == nullptr) ? -1 : entry->getSize();
|
||||
}
|
||||
|
||||
u32 JKRArchive::countFile(const char* path) const {
|
||||
SDIDirEntry* dirEntry;
|
||||
if (*path == '/') {
|
||||
const char* pathPtr = path + 1;
|
||||
if (*pathPtr == '\0') {
|
||||
pathPtr = nullptr;
|
||||
}
|
||||
dirEntry = findDirectory(pathPtr, 0);
|
||||
}
|
||||
else {
|
||||
dirEntry = findDirectory(path, sCurrentDirID);
|
||||
}
|
||||
return (dirEntry) ? dirEntry->mNum : 0;
|
||||
}
|
||||
|
||||
JKRFileFinder* JKRArchive::getFirstFile(const char* path) const {
|
||||
SDIDirEntry* dirEntry;
|
||||
if (*path == '/') {
|
||||
const char* pathPtr = path + 1;
|
||||
if (*pathPtr == '\0') {
|
||||
pathPtr = nullptr;
|
||||
}
|
||||
dirEntry = findDirectory(pathPtr, 0);
|
||||
}
|
||||
else {
|
||||
dirEntry = findDirectory(path, sCurrentDirID);
|
||||
}
|
||||
if (dirEntry) {
|
||||
return new (JKRGetSystemHeap(), 0) JKRArcFinder(
|
||||
const_cast<JKRArchive*>(this), dirEntry->mFirstIdx, dirEntry->mNum);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@@ -0,0 +1,342 @@
|
||||
#include <dolphin/os/OSCache.h>
|
||||
#include <dolphin/string.h>
|
||||
|
||||
#include "JSystem/JKernel/JKRArchive.h"
|
||||
#include "JSystem/JKernel/JKRDecomp.h"
|
||||
#include "JSystem/JKernel/JKRDvdAramRipper.h"
|
||||
#include "JSystem/JKernel/JKRDvdRipper.h"
|
||||
#include "JSystem/JSystem.h"
|
||||
#include "JSystem/JUtility/JUTAssertion.h"
|
||||
|
||||
JKRCompArchive::JKRCompArchive(long entryNum, EMountDirection mountDirection)
|
||||
: JKRArchive(entryNum, MOUNT_COMP) {
|
||||
mMountDirection = mountDirection;
|
||||
if (!open(entryNum)) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
mVolumeType = 'RARC';
|
||||
mVolumeName = &mStrTable[mDirectories->mOffset];
|
||||
sVolumeList.prepend(&mFileLoaderLink);
|
||||
mIsMounted = true;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void stringGen() {
|
||||
JUT_PANIC("isMounted()");
|
||||
JUT_PANIC("mMountCount == 1");
|
||||
}
|
||||
#endif
|
||||
|
||||
JKRCompArchive::~JKRCompArchive() {
|
||||
if (mArcInfoBlock) {
|
||||
SDIFileEntry* fileEntries = mFileEntries;
|
||||
for (int i = 0; i < mArcInfoBlock->num_file_entries; i++) {
|
||||
u32 flag = (fileEntries->mFlag >> 24);
|
||||
if ((flag & 16) == 0 && fileEntries->mData) {
|
||||
JKRFreeToHeap(mHeap, fileEntries->mData);
|
||||
}
|
||||
fileEntries++;
|
||||
}
|
||||
JKRFreeToHeap(mHeap, mArcInfoBlock);
|
||||
mArcInfoBlock = nullptr;
|
||||
}
|
||||
if (mAramPart) {
|
||||
delete mAramPart;
|
||||
}
|
||||
if (mDvdFile) {
|
||||
delete mDvdFile;
|
||||
}
|
||||
|
||||
sVolumeList.remove(&mFileLoaderLink);
|
||||
mIsMounted = false;
|
||||
}
|
||||
|
||||
bool JKRCompArchive::open(long entryNum) {
|
||||
mArcInfoBlock = nullptr;
|
||||
_60 = 0;
|
||||
mAramPart = nullptr;
|
||||
_68 = 0;
|
||||
mSizeOfMemPart = 0;
|
||||
mSizeOfAramPart = 0;
|
||||
_78 = 0;
|
||||
mDirectories = nullptr;
|
||||
mFileEntries = nullptr;
|
||||
mStrTable = nullptr;
|
||||
|
||||
mDvdFile = new (JKRGetSystemHeap(), 0) JKRDvdFile(entryNum);
|
||||
if (mDvdFile == nullptr) {
|
||||
mMountMode = 0;
|
||||
return 0;
|
||||
}
|
||||
SArcHeader* arcHeader = (SArcHeader*)JKRAllocFromSysHeap(
|
||||
sizeof(SArcHeader), -32); // NOTE: unconfirmed if this struct is used
|
||||
if (arcHeader == nullptr) {
|
||||
mMountMode = 0;
|
||||
}
|
||||
else {
|
||||
int alignment;
|
||||
|
||||
JKRDvdToMainRam(entryNum, (u8*)arcHeader, EXPAND_SWITCH_DECOMPRESS, 32,
|
||||
nullptr, JKRDvdRipper::ALLOC_DIR_TOP, 0, &mCompression);
|
||||
|
||||
mSizeOfMemPart = arcHeader->_14;
|
||||
mSizeOfAramPart = arcHeader->_18;
|
||||
JUT_ASSERT((mSizeOfMemPart & 0x1f) == 0);
|
||||
JUT_ASSERT((mSizeOfAramPart & 0x1f) == 0);
|
||||
|
||||
switch (mCompression) {
|
||||
case JKRCOMPRESSION_NONE:
|
||||
case JKRCOMPRESSION_YAZ0:
|
||||
alignment = mMountDirection == 1 ? 32 : -32;
|
||||
mArcInfoBlock = (SArcDataInfo*)JKRAllocFromHeap(
|
||||
mHeap, arcHeader->file_data_offset + mSizeOfMemPart, alignment);
|
||||
if (mArcInfoBlock == nullptr) {
|
||||
mMountMode = 0;
|
||||
}
|
||||
else {
|
||||
JKRDvdToMainRam(entryNum, (u8*)mArcInfoBlock,
|
||||
EXPAND_SWITCH_DECOMPRESS,
|
||||
(u32)arcHeader->file_data_offset + mSizeOfMemPart,
|
||||
nullptr, JKRDvdRipper::ALLOC_DIR_TOP, 0x20, nullptr);
|
||||
_60 = (u32)mArcInfoBlock + arcHeader->file_data_offset;
|
||||
|
||||
if (mSizeOfAramPart != 0) {
|
||||
mAramPart = JKRAllocFromAram(mSizeOfAramPart, JKRAramHeap::Head);
|
||||
if (mAramPart == nullptr) {
|
||||
mMountMode = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
JKRDvdToAram(entryNum, mAramPart->getAddress(),
|
||||
EXPAND_SWITCH_DECOMPRESS,
|
||||
arcHeader->header_length +
|
||||
arcHeader->file_data_offset + mSizeOfMemPart,
|
||||
0);
|
||||
}
|
||||
|
||||
mDirectories =
|
||||
(SDIDirEntry*)((u32)mArcInfoBlock + mArcInfoBlock->node_offset);
|
||||
mFileEntries = (SDIFileEntry*)((u32)mArcInfoBlock +
|
||||
mArcInfoBlock->file_entry_offset);
|
||||
mStrTable = (const char*)((u32)mArcInfoBlock +
|
||||
mArcInfoBlock->string_table_offset);
|
||||
_68 = arcHeader->header_length + arcHeader->file_data_offset;
|
||||
}
|
||||
break;
|
||||
|
||||
case JKRCOMPRESSION_YAY0:
|
||||
u32 alignedSize = ALIGN_NEXT(mDvdFile->getFileSize(), 32);
|
||||
alignment = ((mMountDirection == 1) ? 32 : -32);
|
||||
u8* buf = (u8*)JKRAllocFromSysHeap(alignedSize, -alignment);
|
||||
|
||||
if (buf == nullptr) {
|
||||
mMountMode = 0;
|
||||
}
|
||||
else {
|
||||
JKRDvdToMainRam(entryNum, buf, EXPAND_SWITCH_NONE, alignedSize,
|
||||
nullptr, JKRDvdRipper::ALLOC_DIR_TOP, 0, nullptr);
|
||||
u32 expandSize = ALIGN_NEXT(JKRDecompExpandSize(buf), 32);
|
||||
u8* mem = (u8*)JKRAllocFromHeap(mHeap, expandSize, -alignment);
|
||||
|
||||
if (mem == nullptr) {
|
||||
mMountMode = 0;
|
||||
}
|
||||
else {
|
||||
arcHeader = (SArcHeader*)mem;
|
||||
JKRDecompress((u8*)buf, (u8*)mem, expandSize, 0);
|
||||
JKRFreeToSysHeap(buf);
|
||||
|
||||
mArcInfoBlock = (SArcDataInfo*)JKRAllocFromHeap(
|
||||
mHeap, arcHeader->file_data_offset + mSizeOfMemPart, alignment);
|
||||
if (mArcInfoBlock == nullptr) {
|
||||
mMountMode = 0;
|
||||
}
|
||||
else {
|
||||
// arcHeader + 1 should lead to 0x20, which is the data after the
|
||||
// header
|
||||
JKRHeap::copyMemory(
|
||||
(u8*)mArcInfoBlock, arcHeader + 1,
|
||||
(arcHeader->file_data_offset + mSizeOfMemPart));
|
||||
_60 = (u32)mArcInfoBlock + arcHeader->file_data_offset;
|
||||
if (mSizeOfAramPart != 0) {
|
||||
mAramPart =
|
||||
JKRAllocFromAram(mSizeOfAramPart, JKRAramHeap::Head);
|
||||
if (mAramPart == nullptr) {
|
||||
mMountMode = 0;
|
||||
}
|
||||
else {
|
||||
JKRMainRamToAram(
|
||||
(u8*)mem + arcHeader->header_length +
|
||||
arcHeader->file_data_offset + mSizeOfMemPart,
|
||||
mAramPart->getAddress(), mSizeOfAramPart,
|
||||
EXPAND_SWITCH_DEFAULT, 0, nullptr, -1, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mDirectories =
|
||||
(SDIDirEntry*)((u32)mArcInfoBlock + mArcInfoBlock->node_offset);
|
||||
mFileEntries = (SDIFileEntry*)((u32)mArcInfoBlock +
|
||||
mArcInfoBlock->file_entry_offset);
|
||||
mStrTable = (const char*)((u32)mArcInfoBlock +
|
||||
mArcInfoBlock->string_table_offset);
|
||||
_68 = arcHeader->header_length + arcHeader->file_data_offset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (arcHeader) {
|
||||
JKRFreeToHeap(mHeap, arcHeader);
|
||||
}
|
||||
if (mMountMode == 0) {
|
||||
JREPORTF(0, ":::[%s: %d] Cannot alloc memory in mounting CompArchive\n",
|
||||
__FILE__, 567); // Macro?
|
||||
if (mDvdFile) {
|
||||
delete mDvdFile;
|
||||
mDvdFile = nullptr;
|
||||
}
|
||||
}
|
||||
return mMountMode != 0;
|
||||
}
|
||||
|
||||
void* JKRCompArchive::fetchResource(SDIFileEntry* fileEntry, u32* pSize) {
|
||||
JUT_ASSERT(isMounted());
|
||||
|
||||
u32 ptrSize;
|
||||
|
||||
if (fileEntry->mData == nullptr) {
|
||||
u32 flag = fileEntry->mFlag >> 0x18;
|
||||
if (flag & 0x10) {
|
||||
fileEntry->mData = (void*)(_60 + fileEntry->mDataOffset);
|
||||
if (pSize) *pSize = fileEntry->mSize;
|
||||
}
|
||||
else if (flag & 0x20) {
|
||||
u32 address = mAramPart->getAddress();
|
||||
int compression =
|
||||
JKRConvertAttrToCompressionType(fileEntry->mFlag >> 0x18);
|
||||
|
||||
u8* data;
|
||||
u32 size = JKRAramArchive::fetchResource_subroutine(
|
||||
fileEntry->mDataOffset + address - mSizeOfMemPart, fileEntry->mSize,
|
||||
mHeap, compression, &data);
|
||||
|
||||
if (pSize) *pSize = size;
|
||||
|
||||
fileEntry->mData = data;
|
||||
|
||||
}
|
||||
else if (flag & 0x40) {
|
||||
int compression =
|
||||
JKRConvertAttrToCompressionType(fileEntry->mFlag >> 0x18);
|
||||
|
||||
u8* data;
|
||||
u32 size = JKRDvdArchive::fetchResource_subroutine(
|
||||
mEntryNum, _68 + fileEntry->mDataOffset, fileEntry->mSize, mHeap,
|
||||
compression, mCompression, &data);
|
||||
|
||||
if (pSize) *pSize = size;
|
||||
|
||||
fileEntry->mData = data;
|
||||
}
|
||||
}
|
||||
else if (pSize) {
|
||||
*pSize = fileEntry->mSize;
|
||||
}
|
||||
return fileEntry->mData;
|
||||
}
|
||||
|
||||
void* JKRCompArchive::fetchResource(void* data, u32 compressedSize,
|
||||
SDIFileEntry* fileEntry, u32* pSize,
|
||||
JKRExpandSwitch expandSwitch) {
|
||||
// u32 size = 0;
|
||||
JUT_ASSERT(isMounted());
|
||||
|
||||
u32 size = ALIGN_NEXT(fileEntry->mSize, 32);
|
||||
u32 expandSize = 0;
|
||||
|
||||
if (size == 0) JPANIC(651, ":::bad resource size. size = 0\n");
|
||||
|
||||
if (fileEntry->mData) {
|
||||
if (size > (compressedSize & ~31)) {
|
||||
size = (compressedSize & ~31);
|
||||
}
|
||||
|
||||
JKRHeap::copyMemory(data, fileEntry->mData, size);
|
||||
expandSize = size;
|
||||
}
|
||||
else {
|
||||
u32 fileFlag = fileEntry->mFlag >> 0x18;
|
||||
int compression = JKRConvertAttrToCompressionType(fileFlag);
|
||||
if (expandSwitch != EXPAND_SWITCH_DECOMPRESS) compression = 0;
|
||||
|
||||
if (fileFlag & 0x10) {
|
||||
if (size > (compressedSize & ~31)) {
|
||||
size = (compressedSize & ~31);
|
||||
}
|
||||
|
||||
if (FLAG_ON(fileFlag, 4)) {
|
||||
JKRHeap::copyMemory(data, (void*)(_60 + fileEntry->mDataOffset), size);
|
||||
}
|
||||
else {
|
||||
u8* header = (u8*)(_60 + fileEntry->mDataOffset);
|
||||
expandSize = JKRDecompExpandSize(header);
|
||||
expandSize =
|
||||
(expandSize > compressedSize) ? compressedSize : expandSize;
|
||||
JKRDecompress(header, (u8*)data, expandSize, 0);
|
||||
}
|
||||
|
||||
expandSize = JKRMemArchive::fetchResource_subroutine(
|
||||
(u8*)(_60 + fileEntry->mDataOffset), size, (u8*)data,
|
||||
compressedSize, compression);
|
||||
}
|
||||
else if (fileFlag & 0x20) {
|
||||
expandSize = JKRAramArchive::fetchResource_subroutine(
|
||||
fileEntry->mDataOffset + mAramPart->getAddress() - mSizeOfMemPart,
|
||||
size, (u8*)data, compressedSize, compression);
|
||||
}
|
||||
else if (fileFlag & 0x40) {
|
||||
expandSize = JKRDvdArchive::fetchResource_subroutine(
|
||||
mEntryNum, _68 + fileEntry->mDataOffset, size, (u8*)data,
|
||||
compressedSize, compression, mCompression);
|
||||
}
|
||||
else {
|
||||
JPANIC(731, ":::CompArchive: bad mode.");
|
||||
}
|
||||
}
|
||||
|
||||
if (pSize) {
|
||||
*pSize = expandSize;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
void JKRCompArchive::removeResourceAll() {
|
||||
if (mArcInfoBlock && mMountMode != MOUNT_MEM) {
|
||||
SDIFileEntry* fileEntry = mFileEntries;
|
||||
for (int i = 0; i < mArcInfoBlock->num_file_entries; i++) {
|
||||
u32 flag = fileEntry->mFlag >> 0x18;
|
||||
if (fileEntry->mData) {
|
||||
if ((flag & 0x10) == 0) {
|
||||
JKRFreeToHeap(mHeap, fileEntry->mData);
|
||||
}
|
||||
|
||||
fileEntry->mData = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool JKRCompArchive::removeResource(void* resource) {
|
||||
SDIFileEntry* fileEntry = findPtrResource(resource);
|
||||
if (!fileEntry) return false;
|
||||
|
||||
if (((fileEntry->mFlag >> 0x18) & 0x10) == 0) {
|
||||
JKRFreeToHeap(mHeap, resource);
|
||||
}
|
||||
|
||||
fileEntry->mData = nullptr;
|
||||
return true;
|
||||
}
|
||||
+151
-155
@@ -1,40 +1,45 @@
|
||||
#include "types.h"
|
||||
#include "dolphin/os/OSMessage.h"
|
||||
#include "JSystem/JSystem.h"
|
||||
#include "JSystem/JKernel/JKRHeap.h"
|
||||
#include "JSystem/JKernel/JKRAram.h"
|
||||
|
||||
#include "JSystem/JKernel/JKRDecomp.h"
|
||||
|
||||
#include "JSystem/JKernel/JKRAram.h"
|
||||
#include "JSystem/JKernel/JKRHeap.h"
|
||||
#include "JSystem/JSystem.h"
|
||||
#include "dolphin/os/OSMessage.h"
|
||||
#include "types.h"
|
||||
|
||||
OSMessage JKRDecomp::sMessageBuffer[JKRDECOMP_MSG_BUF_COUNT] = { 0 };
|
||||
OSMessageQueue JKRDecomp::sMessageQueue = { 0 };
|
||||
JKRDecomp* JKRDecomp::sDecompObject;
|
||||
|
||||
JKRDecomp* JKRDecomp::create(s32 decompPriority) {
|
||||
if (JKRDecomp::sDecompObject == nullptr) {
|
||||
JKRDecomp::sDecompObject = new(JKRGetSystemHeap(), 0) JKRDecomp(decompPriority);
|
||||
JKRDecomp::sDecompObject =
|
||||
new (JKRGetSystemHeap(), 0) JKRDecomp(decompPriority);
|
||||
}
|
||||
|
||||
return JKRDecomp::sDecompObject;
|
||||
}
|
||||
|
||||
JKRDecomp::JKRDecomp(s32 priority) : JKRThread(JKRDECOMP_STACK_SIZE, JKRDECOMP_THREAD_MSG_BUF_COUNT, priority) {
|
||||
JKRDecomp::JKRDecomp(s32 priority)
|
||||
: JKRThread(JKRDECOMP_STACK_SIZE, JKRDECOMP_THREAD_MSG_BUF_COUNT,
|
||||
priority) {
|
||||
OSResumeThread(this->mThreadRecord);
|
||||
}
|
||||
|
||||
JKRDecomp::~JKRDecomp() { }
|
||||
JKRDecomp::~JKRDecomp() {}
|
||||
|
||||
void* JKRDecomp::run() {
|
||||
OSMessage recMesg;
|
||||
JKRDecompCommand* cmd;
|
||||
OSInitMessageQueue(&JKRDecomp::sMessageQueue, JKRDecomp::sMessageBuffer, JKRDECOMP_MSG_BUF_COUNT);
|
||||
OSInitMessageQueue(&JKRDecomp::sMessageQueue, JKRDecomp::sMessageBuffer,
|
||||
JKRDECOMP_MSG_BUF_COUNT);
|
||||
|
||||
while (true) {
|
||||
while (true) {
|
||||
while (true) {
|
||||
OSReceiveMessage(&JKRDecomp::sMessageQueue, &recMesg, OS_MESSAGE_BLOCK);
|
||||
cmd = static_cast<JKRDecompCommand*>(recMesg);
|
||||
JKRDecomp::decode(cmd->mSrcBuffer, cmd->mDstBuffer, cmd->mSrcLength, cmd->mSkipCount);
|
||||
JKRDecomp::decode(cmd->mSrcBuffer, cmd->mDstBuffer, cmd->mSrcLength,
|
||||
cmd->mSkipCount);
|
||||
|
||||
if (cmd->transferType == JKRDecompCommand::MRAM) {
|
||||
break;
|
||||
@@ -61,9 +66,11 @@ void* JKRDecomp::run() {
|
||||
}
|
||||
}
|
||||
|
||||
JKRDecompCommand* JKRDecomp::prepareCommand(u8* srcBuffer, u8* dstBuffer, u32 srcLength, u32 skipCount, DecompCallback* callback) {
|
||||
JKRDecompCommand* cmd = new(JKRGetSystemHeap(), -4) JKRDecompCommand();
|
||||
|
||||
JKRDecompCommand* JKRDecomp::prepareCommand(u8* srcBuffer, u8* dstBuffer,
|
||||
u32 srcLength, u32 skipCount,
|
||||
DecompCallback* callback) {
|
||||
JKRDecompCommand* cmd = new (JKRGetSystemHeap(), -4) JKRDecompCommand();
|
||||
|
||||
cmd->mSrcBuffer = srcBuffer;
|
||||
cmd->mDstBuffer = dstBuffer;
|
||||
cmd->mSrcLength = srcLength;
|
||||
@@ -74,7 +81,8 @@ JKRDecompCommand* JKRDecomp::prepareCommand(u8* srcBuffer, u8* dstBuffer, u32 sr
|
||||
}
|
||||
|
||||
BOOL JKRDecomp::sendCommand(JKRDecompCommand* cmd) {
|
||||
BOOL res = OSSendMessage(&JKRDecomp::sMessageQueue, (OSMessage)cmd, OS_MESSAGE_BLOCK);
|
||||
BOOL res = OSSendMessage(&JKRDecomp::sMessageQueue, (OSMessage)cmd,
|
||||
OS_MESSAGE_BLOCK);
|
||||
|
||||
#ifdef JSYSTEM_DEBUG
|
||||
if (res == FALSE) {
|
||||
@@ -85,8 +93,11 @@ BOOL JKRDecomp::sendCommand(JKRDecompCommand* cmd) {
|
||||
return res;
|
||||
}
|
||||
|
||||
JKRDecompCommand* JKRDecomp::orderAsync(u8* srcBuffer, u8* dstBuffer, u32 srcLength, u32 skipCount, DecompCallback* callback) {
|
||||
JKRDecompCommand* cmd = JKRDecomp::prepareCommand(srcBuffer, dstBuffer, srcLength, skipCount, callback);
|
||||
JKRDecompCommand* JKRDecomp::orderAsync(u8* srcBuffer, u8* dstBuffer,
|
||||
u32 srcLength, u32 skipCount,
|
||||
DecompCallback* callback) {
|
||||
JKRDecompCommand* cmd = JKRDecomp::prepareCommand(
|
||||
srcBuffer, dstBuffer, srcLength, skipCount, callback);
|
||||
JKRDecomp::sendCommand(cmd);
|
||||
return cmd;
|
||||
}
|
||||
@@ -99,18 +110,22 @@ bool JKRDecomp::sync(JKRDecompCommand* cmd, BOOL noBlock) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return OSReceiveMessage(&cmd->mMesgQueue, &msg, OS_MESSAGE_NOBLOCK) != FALSE;
|
||||
return OSReceiveMessage(&cmd->mMesgQueue, &msg, OS_MESSAGE_NOBLOCK) !=
|
||||
FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
bool JKRDecomp::orderSync(u8* srcBuffer, u8* dstBuffer, u32 srcLength, u32 skipCount) {
|
||||
JKRDecompCommand* cmd = JKRDecomp::orderAsync(srcBuffer, dstBuffer, srcLength, skipCount, nullptr);
|
||||
bool JKRDecomp::orderSync(u8* srcBuffer, u8* dstBuffer, u32 srcLength,
|
||||
u32 skipCount) {
|
||||
JKRDecompCommand* cmd = JKRDecomp::orderAsync(srcBuffer, dstBuffer, srcLength,
|
||||
skipCount, nullptr);
|
||||
bool res = JKRDecomp::sync(cmd, FALSE);
|
||||
delete cmd;
|
||||
return res;
|
||||
}
|
||||
|
||||
void JKRDecomp::decode(u8* srcBuffer, u8* dstBuffer, u32 srcLength, u32 skipCount) {
|
||||
void JKRDecomp::decode(u8* srcBuffer, u8* dstBuffer, u32 srcLength,
|
||||
u32 skipCount) {
|
||||
CompressionMode mode = JKRDecomp::checkCompressed(srcBuffer);
|
||||
if (mode == SZP) {
|
||||
JKRDecomp::decodeSZP(srcBuffer, dstBuffer, srcLength, skipCount);
|
||||
@@ -120,154 +135,135 @@ void JKRDecomp::decode(u8* srcBuffer, u8* dstBuffer, u32 srcLength, u32 skipCoun
|
||||
}
|
||||
}
|
||||
|
||||
void JKRDecomp::decodeSZP(u8 *src, u8 *dst, u32 srcLength, u32 skipCount)
|
||||
{
|
||||
int srcChunkOffset;
|
||||
int count;
|
||||
int dstOffset;
|
||||
u32 length;
|
||||
int linkInfo;
|
||||
int offset;
|
||||
int i;
|
||||
void JKRDecomp::decodeSZP(u8* src, u8* dst, u32 srcLength, u32 skipCount) {
|
||||
int srcChunkOffset;
|
||||
int count;
|
||||
int dstOffset;
|
||||
u32 length;
|
||||
int linkInfo;
|
||||
int offset;
|
||||
int i;
|
||||
|
||||
int decodedSize = JKRDECOMP_READU32BE(src, 4);
|
||||
int linkTableOffset = JKRDECOMP_READU32BE(src, 8);
|
||||
int srcDataOffset = JKRDECOMP_READU32BE(src, 12);
|
||||
int decodedSize = JKRDECOMP_READU32BE(src, 4);
|
||||
int linkTableOffset = JKRDECOMP_READU32BE(src, 8);
|
||||
int srcDataOffset = JKRDECOMP_READU32BE(src, 12);
|
||||
|
||||
dstOffset = 0;
|
||||
u32 counter = 0; // curently counter gets assembled before the READ_U32 operations
|
||||
srcChunkOffset = 16;
|
||||
dstOffset = 0;
|
||||
u32 counter =
|
||||
0; // curently counter gets assembled before the READ_U32 operations
|
||||
srcChunkOffset = 16;
|
||||
|
||||
u32 chunkBits;
|
||||
if (srcLength == 0)
|
||||
return;
|
||||
if (skipCount > decodedSize)
|
||||
return;
|
||||
u32 chunkBits;
|
||||
if (srcLength == 0) return;
|
||||
if (skipCount > decodedSize) return;
|
||||
|
||||
length = srcLength;
|
||||
do
|
||||
{
|
||||
if (counter == 0)
|
||||
{
|
||||
chunkBits = JKRDECOMP_READU32BE(src, srcChunkOffset);
|
||||
srcChunkOffset += sizeof(u32);
|
||||
counter = sizeof(u32) * 8;
|
||||
}
|
||||
length = srcLength;
|
||||
do {
|
||||
if (counter == 0) {
|
||||
chunkBits = JKRDECOMP_READU32BE(src, srcChunkOffset);
|
||||
srcChunkOffset += sizeof(u32);
|
||||
counter = sizeof(u32) * 8;
|
||||
}
|
||||
|
||||
if (chunkBits & 0x80000000)
|
||||
{
|
||||
if (skipCount == 0)
|
||||
{
|
||||
dst[dstOffset] = src[srcDataOffset];
|
||||
length--;
|
||||
if (length == 0)
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
skipCount--;
|
||||
}
|
||||
dstOffset++;
|
||||
srcDataOffset++;
|
||||
if (chunkBits & 0x80000000) {
|
||||
if (skipCount == 0) {
|
||||
dst[dstOffset] = src[srcDataOffset];
|
||||
length--;
|
||||
if (length == 0) return;
|
||||
}
|
||||
else {
|
||||
skipCount--;
|
||||
}
|
||||
dstOffset++;
|
||||
srcDataOffset++;
|
||||
}
|
||||
else {
|
||||
linkInfo = src[linkTableOffset] << 8 | src[linkTableOffset + 1];
|
||||
linkTableOffset += sizeof(u16);
|
||||
|
||||
offset = dstOffset - (linkInfo & 0xFFF);
|
||||
count = (linkInfo >> 12);
|
||||
if (count == 0) {
|
||||
count = (u32)src[srcDataOffset++] + 0x12;
|
||||
}
|
||||
else
|
||||
count += 2;
|
||||
|
||||
if ((int)count > decodedSize - dstOffset) count = decodedSize - dstOffset;
|
||||
|
||||
for (i = 0; i < (int)count; i++, dstOffset++, offset++) {
|
||||
if (skipCount == 0) {
|
||||
dst[dstOffset] = dst[offset - 1];
|
||||
length--;
|
||||
if (length == 0) return;
|
||||
}
|
||||
else
|
||||
{
|
||||
linkInfo = src[linkTableOffset] << 8 | src[linkTableOffset + 1];
|
||||
linkTableOffset += sizeof(u16);
|
||||
skipCount--;
|
||||
}
|
||||
}
|
||||
|
||||
offset = dstOffset - (linkInfo & 0xFFF);
|
||||
count = (linkInfo >> 12);
|
||||
if (count == 0)
|
||||
{
|
||||
count = (u32)src[srcDataOffset++] + 0x12;
|
||||
}
|
||||
else
|
||||
count += 2;
|
||||
|
||||
if ((int)count > decodedSize - dstOffset)
|
||||
count = decodedSize - dstOffset;
|
||||
|
||||
for (i = 0; i < (int)count; i++, dstOffset++, offset++)
|
||||
{
|
||||
if (skipCount == 0)
|
||||
{
|
||||
dst[dstOffset] = dst[offset - 1];
|
||||
length--;
|
||||
if (length == 0)
|
||||
return;
|
||||
}
|
||||
else
|
||||
skipCount--;
|
||||
}
|
||||
}
|
||||
|
||||
chunkBits <<= 1;
|
||||
counter--;
|
||||
} while (dstOffset < decodedSize);
|
||||
chunkBits <<= 1;
|
||||
counter--;
|
||||
} while (dstOffset < decodedSize);
|
||||
}
|
||||
|
||||
void JKRDecomp::decodeSZS(u8 *src_buffer, u8 *dst_buffer, u32 srcSize, u32 skipCount) {
|
||||
void JKRDecomp::decodeSZS(u8* src_buffer, u8* dst_buffer, u32 srcSize,
|
||||
u32 skipCount) {
|
||||
u8* decompEnd = dst_buffer + *(u32*)(src_buffer + 4) - skipCount;
|
||||
u8* copyStart;
|
||||
s32 copyByteCount;
|
||||
s32 chunkBitsLeft = 0;
|
||||
s32 chunkBits;
|
||||
|
||||
u8 *decompEnd = dst_buffer + *(u32 *)(src_buffer + 4) - skipCount;
|
||||
u8 *copyStart;
|
||||
s32 copyByteCount;
|
||||
s32 chunkBitsLeft = 0;
|
||||
s32 chunkBits;
|
||||
if (srcSize == 0) return;
|
||||
if (skipCount > *(u32*)src_buffer) return;
|
||||
|
||||
if (srcSize == 0)
|
||||
return;
|
||||
if (skipCount > *(u32 *)src_buffer)
|
||||
return;
|
||||
|
||||
u8 *curSrcPos = src_buffer + 0x10;
|
||||
do {
|
||||
if (chunkBitsLeft == 0) {
|
||||
chunkBits = *curSrcPos++;
|
||||
chunkBitsLeft = 8;
|
||||
}
|
||||
if ((chunkBits & 0x80) != 0) {
|
||||
if (skipCount == 0)
|
||||
{
|
||||
*dst_buffer = *curSrcPos;
|
||||
srcSize--;
|
||||
dst_buffer++;
|
||||
if (srcSize == 0)
|
||||
return;
|
||||
}
|
||||
else {
|
||||
skipCount--;
|
||||
}
|
||||
curSrcPos++;
|
||||
u8* curSrcPos = src_buffer + 0x10;
|
||||
do {
|
||||
if (chunkBitsLeft == 0) {
|
||||
chunkBits = *curSrcPos++;
|
||||
chunkBitsLeft = 8;
|
||||
}
|
||||
if ((chunkBits & 0x80) != 0) {
|
||||
if (skipCount == 0) {
|
||||
*dst_buffer = *curSrcPos;
|
||||
srcSize--;
|
||||
dst_buffer++;
|
||||
if (srcSize == 0) return;
|
||||
}
|
||||
else {
|
||||
skipCount--;
|
||||
}
|
||||
curSrcPos++;
|
||||
}
|
||||
else {
|
||||
u8 curVal = *curSrcPos;
|
||||
copyStart = dst_buffer - (curSrcPos[1] | (curVal & 0xF) << 8);
|
||||
curSrcPos += 2;
|
||||
if (curVal >> 4 == 0) {
|
||||
copyByteCount = *curSrcPos + 0x12;
|
||||
curSrcPos++;
|
||||
}
|
||||
else {
|
||||
copyByteCount = (curVal >> 4) + 2;
|
||||
}
|
||||
do {
|
||||
if (skipCount == 0) {
|
||||
*dst_buffer = *(copyStart - 1);
|
||||
srcSize--;
|
||||
dst_buffer++;
|
||||
if (srcSize == 0) return;
|
||||
}
|
||||
else {
|
||||
u8 curVal = *curSrcPos;
|
||||
copyStart = dst_buffer - (curSrcPos[1] | (curVal & 0xF) << 8);
|
||||
curSrcPos += 2;
|
||||
if (curVal >> 4 == 0) {
|
||||
copyByteCount = *curSrcPos + 0x12;
|
||||
curSrcPos++;
|
||||
}
|
||||
else {
|
||||
copyByteCount = (curVal >> 4) + 2;
|
||||
}
|
||||
do {
|
||||
if (skipCount == 0) {
|
||||
*dst_buffer = *(copyStart - 1);
|
||||
srcSize--;
|
||||
dst_buffer++;
|
||||
if (srcSize == 0)
|
||||
return;
|
||||
}
|
||||
else {
|
||||
skipCount--;
|
||||
}
|
||||
copyByteCount--;
|
||||
copyStart++;
|
||||
} while (copyByteCount != 0);
|
||||
skipCount--;
|
||||
}
|
||||
chunkBits <<= 1;
|
||||
chunkBitsLeft--;
|
||||
} while (dst_buffer != decompEnd);
|
||||
copyByteCount--;
|
||||
copyStart++;
|
||||
} while (copyByteCount != 0);
|
||||
}
|
||||
chunkBits <<= 1;
|
||||
chunkBitsLeft--;
|
||||
} while (dst_buffer != decompEnd);
|
||||
}
|
||||
|
||||
JKRDecomp::CompressionMode JKRDecomp::checkCompressed(u8* buf) {
|
||||
@@ -292,4 +288,4 @@ JKRDecompCommand::JKRDecompCommand() {
|
||||
this->transferType = MRAM;
|
||||
}
|
||||
|
||||
JKRDecompCommand::~JKRDecompCommand() { }
|
||||
JKRDecompCommand::~JKRDecompCommand() {}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "JSystem/JKernel/JKRDisposer.h"
|
||||
|
||||
#include "JSystem/JKernel/JKRHeap.h"
|
||||
|
||||
JKRDisposer::JKRDisposer() : mPointerLinks(this) {
|
||||
|
||||
@@ -0,0 +1,402 @@
|
||||
#include "JSystem/JKernel/JKRDvdAramRipper.h"
|
||||
|
||||
#include <_mem.h>
|
||||
#include <dolphin/string.h>
|
||||
#include <dolphin/vi.h>
|
||||
|
||||
#include "JSystem/JKernel/JKRDecomp.h"
|
||||
#include "JSystem/JKernel/JKRDvdFile.h"
|
||||
#include "JSystem/JKernel/JKRDvdRipper.h"
|
||||
#include "JSystem/JUtility/JUTAssertion.h"
|
||||
|
||||
JSUList<JKRADCommand> JKRDvdAramRipper::sDvdAramAsyncList;
|
||||
|
||||
bool JKRDvdAramRipper::errorRetry = true;
|
||||
int JKRDvdAramRipper::sSZSBufferSize = 0x400;
|
||||
|
||||
JKRAramBlock* JKRDvdAramRipper::loadToAram(s32 entrynum, u32 p2,
|
||||
JKRExpandSwitch expSwitch, u32 p6,
|
||||
u32 p7) {
|
||||
JKRDvdFile dvdFile;
|
||||
if (!dvdFile.open(entrynum))
|
||||
return nullptr;
|
||||
else
|
||||
return loadToAram(&dvdFile, p2, expSwitch, p6, p7);
|
||||
}
|
||||
|
||||
JKRAramBlock* JKRDvdAramRipper::loadToAram(JKRDvdFile* dvdFile, u32 p1,
|
||||
JKRExpandSwitch p2, u32 p3, u32 p4) {
|
||||
JKRADCommand* command = loadToAram_Async(dvdFile, p1, p2, nullptr, p3, p4);
|
||||
syncAram(command, 0);
|
||||
|
||||
if (p1) {
|
||||
delete command;
|
||||
return (JKRAramBlock*)-1;
|
||||
}
|
||||
|
||||
JKRAramBlock* result = command->mBlock;
|
||||
delete command;
|
||||
return result;
|
||||
}
|
||||
|
||||
JKRADCommand* JKRDvdAramRipper::loadToAram_Async(JKRDvdFile* dvdFile, u32 p1,
|
||||
JKRExpandSwitch expSwitch,
|
||||
JKRADCommand::LoadCallback cb,
|
||||
u32 p4, u32 p5) {
|
||||
JKRADCommand* command = new (JKRGetSystemHeap(), -4) JKRADCommand();
|
||||
command->mDvdFile = dvdFile;
|
||||
command->_1C = p1;
|
||||
command->mBlock = nullptr;
|
||||
command->mExpandSwitch = expSwitch;
|
||||
command->mCallBack = cb;
|
||||
|
||||
command->_14 = p4;
|
||||
command->_18 = p5;
|
||||
|
||||
if (!callCommand_Async(command)) {
|
||||
delete command;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
JKRADCommand* JKRDvdAramRipper::callCommand_Async(JKRADCommand* command) {
|
||||
bool isCmdTrdNull = true;
|
||||
JKRDvdFile* dvdFile = command->mDvdFile;
|
||||
int compression = JKRCOMPRESSION_NONE;
|
||||
OSLockMutex(&dvdFile->mAramMutex);
|
||||
|
||||
s32 uncompressedSize;
|
||||
|
||||
if (dvdFile->mAramThread) {
|
||||
isCmdTrdNull = false;
|
||||
}
|
||||
else {
|
||||
dvdFile->mAramThread = OSGetCurrentThread();
|
||||
JSUFileInputStream* stream =
|
||||
new (JKRGetSystemHeap(), -4) JSUFileInputStream(dvdFile);
|
||||
dvdFile->mInputStream = stream;
|
||||
u32 fileSize = dvdFile->getFileSize();
|
||||
if (command->_18 && fileSize > command->_18) {
|
||||
fileSize = command->_18;
|
||||
}
|
||||
fileSize = ALIGN_NEXT(fileSize, 0x20);
|
||||
if (command->mExpandSwitch == EXPAND_SWITCH_DECOMPRESS) {
|
||||
u8 buffer[0x40];
|
||||
u8* bufPtr = (u8*)ALIGN_NEXT((u32)buffer, 0x20);
|
||||
while (true) {
|
||||
if (DVDReadPrio(dvdFile->getFileInfo(), bufPtr, 0x20, 0, 2) >= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (errorRetry == false) {
|
||||
delete stream;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
VIWaitForRetrace();
|
||||
}
|
||||
|
||||
compression = JKRCheckCompressed(bufPtr);
|
||||
u32 expSize = JKRDecompExpandSize(bufPtr);
|
||||
uncompressedSize = expSize;
|
||||
|
||||
if ((command->_18 != 0) && expSize > command->_18) {
|
||||
uncompressedSize = command->_18;
|
||||
}
|
||||
}
|
||||
|
||||
if (compression == JKRCOMPRESSION_NONE) {
|
||||
command->mExpandSwitch = EXPAND_SWITCH_DEFAULT;
|
||||
}
|
||||
|
||||
if (command->mExpandSwitch == EXPAND_SWITCH_DECOMPRESS) {
|
||||
if (command->_1C == 0 && command->mBlock == nullptr) {
|
||||
command->mBlock =
|
||||
JKRAram::getAramHeap()->alloc(uncompressedSize, JKRAramHeap::Head);
|
||||
if (command->mBlock) {
|
||||
command->_1C = command->mBlock->mAddress;
|
||||
}
|
||||
dvdFile->mAramBlock = command->mBlock;
|
||||
}
|
||||
|
||||
if (command->mBlock) {
|
||||
command->_1C = command->mBlock->mAddress;
|
||||
}
|
||||
|
||||
if (command->_1C == 0) {
|
||||
dvdFile->mAramThread = nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (command->_1C == 0 && !command->mBlock) {
|
||||
command->mBlock =
|
||||
JKRAram::getAramHeap()->alloc(fileSize, JKRAramHeap::Head);
|
||||
}
|
||||
|
||||
if (command->mBlock) {
|
||||
command->_1C = command->mBlock->mAddress;
|
||||
}
|
||||
|
||||
if (command->_1C == 0) {
|
||||
dvdFile->mAramThread = nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (compression == 0) {
|
||||
command->mStreamCommand = JKRAramStream::write_StreamToAram_Async(
|
||||
stream, command->_1C, fileSize - command->_14, command->_14);
|
||||
}
|
||||
else if (compression == JKRCOMPRESSION_YAY0) {
|
||||
command->mStreamCommand = JKRAramStream::write_StreamToAram_Async(
|
||||
stream, command->_1C, fileSize - command->_14, command->_14);
|
||||
}
|
||||
else if (compression == JKRCOMPRESSION_YAZ0) {
|
||||
command->mStreamCommand = nullptr;
|
||||
JKRDecompressFromDVDToAram(command->mDvdFile, command->_1C, fileSize,
|
||||
uncompressedSize, command->_14, 0);
|
||||
}
|
||||
|
||||
if (!command->mCallBack) {
|
||||
sDvdAramAsyncList.append(&command->mLink);
|
||||
}
|
||||
else {
|
||||
command->mCallBack((u32)command);
|
||||
}
|
||||
}
|
||||
|
||||
OSUnlockMutex(&dvdFile->mAramMutex);
|
||||
return isCmdTrdNull == true ? command : nullptr;
|
||||
}
|
||||
|
||||
bool JKRDvdAramRipper::syncAram(JKRADCommand* command, int p1) {
|
||||
JKRDvdFile* dvdFile = command->mDvdFile;
|
||||
OSLockMutex(&dvdFile->mAramMutex);
|
||||
|
||||
if (command->mStreamCommand) {
|
||||
JKRAramStreamCommand* var1 =
|
||||
JKRAramStream::sync(command->mStreamCommand, p1);
|
||||
|
||||
if (p1 != 0 && var1 == nullptr) {
|
||||
OSUnlockMutex(&dvdFile->mAramMutex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
sDvdAramAsyncList.remove(&command->mLink);
|
||||
if (command->mStreamCommand) {
|
||||
delete command->mStreamCommand;
|
||||
}
|
||||
|
||||
delete dvdFile->mInputStream;
|
||||
dvdFile->mAramThread = nullptr;
|
||||
OSUnlockMutex(&dvdFile->mAramMutex);
|
||||
return true;
|
||||
}
|
||||
|
||||
JKRADCommand::JKRADCommand() : mLink(this) { _44 = 0; }
|
||||
|
||||
JKRADCommand::~JKRADCommand() {
|
||||
if (_44 == 1) delete mDvdFile;
|
||||
}
|
||||
|
||||
static OSMutex decompMutex;
|
||||
static u8* szpBuf;
|
||||
static u8* szpEnd;
|
||||
static u8* refBuf;
|
||||
static u8* refEnd;
|
||||
static u8* refCurrent;
|
||||
static u8* dmaBuf;
|
||||
static u8* dmaEnd;
|
||||
static u8* dmaCurrent;
|
||||
static u32 srcOffset;
|
||||
static u32 transLeft;
|
||||
static u8* srcLimit;
|
||||
static JKRDvdFile* srcFile;
|
||||
static u32 fileOffset;
|
||||
static int readCount;
|
||||
static u32 maxDest;
|
||||
static bool isInitMutex;
|
||||
static u32* tsPtr;
|
||||
static u32 tsArea;
|
||||
|
||||
static int decompSZS_subroutine(u8*, u32);
|
||||
static u8* firstSrcData();
|
||||
static u8* nextSrcData(u8*);
|
||||
static u32 dmaBufferFlush(u32);
|
||||
|
||||
int JKRDecompressFromDVDToAram(JKRDvdFile* dvdFile, u32 address, u32 fileSize,
|
||||
u32 _maxDest, u32 _fileOffset, u32 _srcOffset) {
|
||||
int result = 0;
|
||||
szpBuf = (u8*)JKRAllocFromSysHeap(SZP_BUFFERSIZE, 32);
|
||||
JUT_ASSERT(szpBuf != 0);
|
||||
szpEnd = szpBuf + SZP_BUFFERSIZE;
|
||||
|
||||
refBuf = (u8*)JKRAllocFromSysHeap(REF_BUFFERSIZE, 0);
|
||||
JUT_ASSERT(refBuf != 0);
|
||||
refEnd = refBuf + REF_BUFFERSIZE;
|
||||
refCurrent = refBuf;
|
||||
|
||||
dmaBuf = (u8*)JKRAllocFromSysHeap(DMA_BUFFERSIZE, 32);
|
||||
JUT_ASSERT(dmaBuf != 0);
|
||||
dmaEnd = dmaBuf + DMA_BUFFERSIZE;
|
||||
dmaCurrent = dmaBuf;
|
||||
|
||||
srcFile = dvdFile;
|
||||
srcOffset = _srcOffset;
|
||||
transLeft = fileSize - _srcOffset;
|
||||
fileOffset = _fileOffset;
|
||||
readCount = 0;
|
||||
maxDest = _maxDest;
|
||||
|
||||
u8* first = firstSrcData();
|
||||
if (first) result = decompSZS_subroutine(first, address);
|
||||
|
||||
JKRFree(szpBuf);
|
||||
JKRFree(refBuf);
|
||||
JKRFree(dmaBuf);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int decompSZS_subroutine(u8* src, u32 dmaAddr) {
|
||||
u32 endPtr;
|
||||
u8* copySource;
|
||||
s32 validBitCount = 0;
|
||||
s32 currCodeByte = 0;
|
||||
s32 numBytes;
|
||||
|
||||
u32 dmaStart = dmaAddr;
|
||||
|
||||
if (src[0] != 'Y' || src[1] != 'a' || src[2] != 'z' || src[3] != '0')
|
||||
return -1;
|
||||
|
||||
SYaz0Header* header = (SYaz0Header*)src;
|
||||
endPtr = dmaAddr + (header->length - fileOffset);
|
||||
if (endPtr > dmaAddr + maxDest) endPtr = dmaAddr + maxDest;
|
||||
|
||||
src += 0x10;
|
||||
|
||||
do {
|
||||
if (validBitCount == 0) {
|
||||
if ((src > srcLimit) && transLeft) src = nextSrcData(src);
|
||||
|
||||
currCodeByte = *src++;
|
||||
validBitCount = 8;
|
||||
}
|
||||
if (currCodeByte & 0x80) {
|
||||
if (readCount >= fileOffset) {
|
||||
dmaAddr++;
|
||||
*dmaCurrent++ = *src;
|
||||
if (dmaCurrent == dmaEnd) dmaStart += dmaBufferFlush(dmaStart);
|
||||
|
||||
if (dmaAddr == endPtr) break;
|
||||
}
|
||||
*(refCurrent++) = *src;
|
||||
if (refCurrent == refEnd) refCurrent = refBuf;
|
||||
|
||||
src++;
|
||||
|
||||
readCount++;
|
||||
}
|
||||
else {
|
||||
int t0 = src[0];
|
||||
int t1 = src[1];
|
||||
copySource = refCurrent - (t1 | (t0 & 0x0f) << 8) - 1;
|
||||
numBytes = t0 >> 4;
|
||||
src += 2;
|
||||
if (copySource < refBuf) copySource = copySource + (refEnd - refBuf);
|
||||
|
||||
if (numBytes == 0)
|
||||
numBytes = *src++ + 0x12;
|
||||
else
|
||||
numBytes += 2;
|
||||
|
||||
do {
|
||||
if (readCount >= fileOffset) {
|
||||
dmaAddr++;
|
||||
*(dmaCurrent++) = *copySource;
|
||||
if (dmaCurrent == dmaEnd) dmaStart += dmaBufferFlush(dmaStart);
|
||||
|
||||
if (dmaAddr == endPtr) break;
|
||||
}
|
||||
*(refCurrent++) = *copySource;
|
||||
if (refCurrent == refEnd) refCurrent = refBuf;
|
||||
|
||||
copySource++;
|
||||
|
||||
if (copySource == refEnd) copySource = refBuf;
|
||||
|
||||
readCount++;
|
||||
numBytes--;
|
||||
} while (numBytes != 0);
|
||||
}
|
||||
currCodeByte <<= 1;
|
||||
validBitCount--;
|
||||
} while (dmaAddr < endPtr);
|
||||
|
||||
dmaBufferFlush(dmaStart);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u8* firstSrcData() {
|
||||
srcLimit = szpEnd - 0x19;
|
||||
u8* buf = szpBuf;
|
||||
u32 max = (szpEnd - szpBuf);
|
||||
u32 transSize = MIN(transLeft, max);
|
||||
|
||||
while (true) {
|
||||
if (0 <= DVDReadPrio(srcFile->getFileInfo(), buf, transSize, 0, 2)) break;
|
||||
if (!JKRDvdAramRipper::isErrorRetry()) return nullptr;
|
||||
VIWaitForRetrace();
|
||||
}
|
||||
srcOffset += transSize;
|
||||
transLeft -= transSize;
|
||||
return buf;
|
||||
}
|
||||
|
||||
u8* nextSrcData(u8* src) {
|
||||
u32 limit = szpEnd - src;
|
||||
u8* buf;
|
||||
if (IS_NOT_ALIGNED(limit, 0x20))
|
||||
buf = szpBuf + 0x20 - (limit & (0x20 - 1));
|
||||
else
|
||||
buf = szpBuf;
|
||||
|
||||
memcpy(buf, src, limit);
|
||||
u32 transSize = (u32)(szpEnd - (buf + limit));
|
||||
if (transSize > transLeft) transSize = transLeft;
|
||||
|
||||
JUT_ASSERT(transSize > 0);
|
||||
while (true) {
|
||||
int result = DVDReadPrio(srcFile->getFileInfo(), (buf + limit), transSize,
|
||||
srcOffset, 2);
|
||||
if (result >= 0) break;
|
||||
|
||||
if (!JKRDvdAramRipper::isErrorRetry()) return nullptr;
|
||||
|
||||
VIWaitForRetrace();
|
||||
}
|
||||
|
||||
srcOffset += transSize;
|
||||
transLeft -= transSize;
|
||||
if (transLeft == 0) srcLimit = transSize + (buf + limit);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
u32 dmaBufferFlush(u32 src) {
|
||||
if (dmaCurrent == dmaBuf) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
u32 length = ALIGN_NEXT((u32)(dmaCurrent - dmaBuf), 32);
|
||||
JKRAramPiece::orderSync(0, (u32)dmaBuf, src, length, nullptr);
|
||||
dmaCurrent = dmaBuf;
|
||||
return length;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,321 @@
|
||||
#include <dolphin/os/OSCache.h>
|
||||
#include <dolphin/string.h>
|
||||
|
||||
#include "JSystem/JKernel/JKRArchive.h"
|
||||
#include "JSystem/JKernel/JKRDecomp.h"
|
||||
#include "JSystem/JKernel/JKRDvdAramRipper.h"
|
||||
#include "JSystem/JKernel/JKRDvdRipper.h"
|
||||
#include "JSystem/JSystem.h"
|
||||
#include "JSystem/JUtility/JUTAssertion.h"
|
||||
|
||||
JKRDvdArchive::JKRDvdArchive() : JKRArchive() {}
|
||||
|
||||
JKRDvdArchive::JKRDvdArchive(s32 entryNum, EMountDirection mountDirection)
|
||||
: JKRArchive(entryNum, MOUNT_DVD)
|
||||
{
|
||||
mMountDirection = mountDirection;
|
||||
if (!open(entryNum))
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
mVolumeType = 'RARC';
|
||||
mVolumeName = &mStrTable[mDirectories->mOffset];
|
||||
sVolumeList.prepend(&mFileLoaderLink);
|
||||
mIsMounted = true;
|
||||
}
|
||||
}
|
||||
|
||||
JKRDvdArchive::~JKRDvdArchive()
|
||||
{
|
||||
if (mIsMounted == true)
|
||||
{
|
||||
if (mArcInfoBlock)
|
||||
{
|
||||
SDIFileEntry* fileEntries = mFileEntries;
|
||||
for (int i = 0; i < mArcInfoBlock->num_file_entries; i++)
|
||||
{
|
||||
if (fileEntries->mData != nullptr)
|
||||
{
|
||||
JKRFreeToHeap(mHeap, fileEntries->mData);
|
||||
}
|
||||
fileEntries++;
|
||||
}
|
||||
JKRFreeToHeap(mHeap, mArcInfoBlock);
|
||||
}
|
||||
|
||||
if (mDvdFile)
|
||||
{
|
||||
delete mDvdFile;
|
||||
}
|
||||
|
||||
sVolumeList.remove(&mFileLoaderLink);
|
||||
mIsMounted = false;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
CW_FORCE_STRINGS(JKRDvdArchive_cpp, __FILE__, "isMounted()", "mMountCount == 1")
|
||||
#endif
|
||||
|
||||
bool JKRDvdArchive::open(long entryNum)
|
||||
{
|
||||
mArcInfoBlock = nullptr;
|
||||
_60 = 0;
|
||||
mDirectories = nullptr;
|
||||
mFileEntries = nullptr;
|
||||
mStrTable = nullptr;
|
||||
|
||||
mDvdFile = new (JKRGetSystemHeap(), 0) JKRDvdFile(entryNum);
|
||||
if (mDvdFile == nullptr)
|
||||
{
|
||||
mMountMode = 0;
|
||||
return 0;
|
||||
}
|
||||
SDIFileEntry* mem = (SDIFileEntry*)JKRAllocFromSysHeap(
|
||||
32, 32); // NOTE: unconfirmed if this struct was used here
|
||||
if (mem == nullptr)
|
||||
{
|
||||
mMountMode = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
JKRDvdToMainRam(entryNum, (u8*)mem, EXPAND_SWITCH_DECOMPRESS, 32, nullptr,
|
||||
JKRDvdRipper::ALLOC_DIR_TOP, 0, &mCompression);
|
||||
int alignment = mMountDirection == MOUNT_DIRECTION_HEAD ? 32 : -32;
|
||||
|
||||
mArcInfoBlock =
|
||||
(SArcDataInfo*)JKRAllocFromHeap(mHeap, mem->mSize, alignment);
|
||||
if (mArcInfoBlock == nullptr)
|
||||
{
|
||||
mMountMode = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
JKRDvdToMainRam(entryNum, (u8*)mArcInfoBlock, EXPAND_SWITCH_DECOMPRESS,
|
||||
mem->mSize, nullptr, JKRDvdRipper::ALLOC_DIR_TOP, 32,
|
||||
nullptr);
|
||||
|
||||
mDirectories =
|
||||
(SDIDirEntry*)((u8*)mArcInfoBlock + mArcInfoBlock->node_offset);
|
||||
mFileEntries = (SDIFileEntry*)((u8*)mArcInfoBlock +
|
||||
mArcInfoBlock->file_entry_offset);
|
||||
mStrTable = (const char*)((u8*)mArcInfoBlock +
|
||||
mArcInfoBlock->string_table_offset);
|
||||
_60 = mem->mDataOffset + mem->mSize; // End of data offset?
|
||||
}
|
||||
}
|
||||
cleanup:
|
||||
if (mem != nullptr)
|
||||
{
|
||||
JKRFreeToSysHeap(mem);
|
||||
}
|
||||
if (mMountMode == 0)
|
||||
{
|
||||
JREPORTF(":::Cannot alloc memory [%s][%d]\n", __FILE__, 397); // Macro?
|
||||
if (mDvdFile != nullptr)
|
||||
{
|
||||
delete mDvdFile;
|
||||
}
|
||||
}
|
||||
return mMountMode != 0;
|
||||
}
|
||||
|
||||
void* JKRDvdArchive::fetchResource(SDIFileEntry* fileEntry, u32* pSize)
|
||||
{
|
||||
JUT_ASSERT(isMounted());
|
||||
|
||||
u32 sizeRef;
|
||||
u8* data;
|
||||
|
||||
if (fileEntry->mData == nullptr)
|
||||
{
|
||||
int compression = JKRConvertAttrToCompressionType(fileEntry->mFlag >> 0x18);
|
||||
u32 size = fetchResource_subroutine(mEntryNum, _60 + fileEntry->mDataOffset,
|
||||
fileEntry->mSize, mHeap,
|
||||
(int)compression, mCompression, &data);
|
||||
|
||||
if (pSize)
|
||||
*pSize = size;
|
||||
|
||||
fileEntry->mData = data;
|
||||
}
|
||||
else if (pSize)
|
||||
{
|
||||
*pSize = fileEntry->mSize;
|
||||
}
|
||||
|
||||
return fileEntry->mData;
|
||||
}
|
||||
|
||||
void* JKRDvdArchive::fetchResource(void* data, u32 compressedSize,
|
||||
SDIFileEntry* fileEntry, u32* pSize,
|
||||
JKRExpandSwitch expandSwitch)
|
||||
{
|
||||
JUT_ASSERT(isMounted());
|
||||
|
||||
u32 fileSize = compressedSize & -32;
|
||||
u32 alignedSize = ALIGN_NEXT(fileEntry->mSize, 32);
|
||||
|
||||
if (alignedSize > fileSize)
|
||||
{
|
||||
alignedSize = fileSize;
|
||||
}
|
||||
|
||||
if (fileEntry->mData == nullptr)
|
||||
{
|
||||
int compression = JKRConvertAttrToCompressionType(fileEntry->mFlag >> 0x18);
|
||||
if (expandSwitch != EXPAND_SWITCH_DECOMPRESS)
|
||||
compression = 0;
|
||||
alignedSize = fetchResource_subroutine(
|
||||
mEntryNum, _60 + fileEntry->mDataOffset, fileEntry->mSize, (u8*)data,
|
||||
fileSize, compression, mCompression);
|
||||
}
|
||||
else
|
||||
{
|
||||
JKRHeap::copyMemory(data, fileEntry->mData, alignedSize);
|
||||
}
|
||||
|
||||
if (pSize)
|
||||
{
|
||||
*pSize = alignedSize;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
u32 JKRDvdArchive::fetchResource_subroutine(long entryNum, u32 offset, u32 size,
|
||||
u8* data, u32 expandSize,
|
||||
int fileCompression,
|
||||
int archiveCompression)
|
||||
{
|
||||
u32 prevAlignedSize, alignedSize;
|
||||
|
||||
alignedSize = ALIGN_NEXT(size, 32);
|
||||
prevAlignedSize = ALIGN_PREV(expandSize, 32);
|
||||
switch (archiveCompression)
|
||||
{
|
||||
case JKRCOMPRESSION_NONE:
|
||||
{
|
||||
switch (fileCompression)
|
||||
{
|
||||
case JKRCOMPRESSION_NONE:
|
||||
|
||||
if (alignedSize > prevAlignedSize)
|
||||
{
|
||||
alignedSize = prevAlignedSize;
|
||||
}
|
||||
JKRDvdRipper::loadToMainRAM(
|
||||
entryNum, data, EXPAND_SWITCH_DEFAULT, alignedSize, nullptr,
|
||||
JKRDvdRipper::ALLOC_DIR_TOP, offset, nullptr);
|
||||
return alignedSize;
|
||||
|
||||
case JKRCOMPRESSION_YAY0:
|
||||
case JKRCOMPRESSION_YAZ0:
|
||||
u8* header = (u8*)JKRAllocFromSysHeap(0x20, 0x20);
|
||||
JKRDvdRipper::loadToMainRAM(
|
||||
entryNum, header, EXPAND_SWITCH_NONE, 0x20, nullptr,
|
||||
JKRDvdRipper::ALLOC_DIR_TOP, offset, nullptr);
|
||||
u32 expandFileSize = JKRDecompExpandSize(header);
|
||||
JKRFreeToSysHeap(header);
|
||||
alignedSize = ALIGN_NEXT(expandFileSize, 32);
|
||||
if (alignedSize > prevAlignedSize)
|
||||
{
|
||||
alignedSize = prevAlignedSize;
|
||||
}
|
||||
JKRDvdRipper::loadToMainRAM(
|
||||
entryNum, data, EXPAND_SWITCH_DECOMPRESS, alignedSize, nullptr,
|
||||
JKRDvdRipper::ALLOC_DIR_TOP, offset, nullptr);
|
||||
return expandFileSize;
|
||||
}
|
||||
}
|
||||
case JKRCOMPRESSION_YAZ0:
|
||||
{
|
||||
if (size > prevAlignedSize)
|
||||
{
|
||||
size = prevAlignedSize;
|
||||
}
|
||||
JKRDvdRipper::loadToMainRAM(entryNum, data, EXPAND_SWITCH_DECOMPRESS,
|
||||
size, nullptr, JKRDvdRipper::ALLOC_DIR_TOP,
|
||||
offset, nullptr);
|
||||
return size;
|
||||
}
|
||||
|
||||
case JKRCOMPRESSION_YAY0:
|
||||
{
|
||||
JPANIC(537, "Sorry, not prepared for SZP archive.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
JPANIC(546, ":::??? bad sequence\n");
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 JKRDvdArchive::fetchResource_subroutine(long entryNum, u32 offset, u32 size,
|
||||
JKRHeap* heap, int fileCompression,
|
||||
int archiveCompression, u8** pBuf)
|
||||
{
|
||||
u32 alignedSize = ALIGN_NEXT(size, 32);
|
||||
|
||||
u8* buffer;
|
||||
switch (archiveCompression)
|
||||
{
|
||||
case JKRCOMPRESSION_NONE:
|
||||
{
|
||||
switch (fileCompression)
|
||||
{
|
||||
case JKRCOMPRESSION_NONE:
|
||||
buffer = (u8*)JKRAllocFromHeap(heap, alignedSize, 32);
|
||||
JUT_ASSERT(buffer != 0);
|
||||
|
||||
JKRDvdToMainRam(entryNum, buffer, EXPAND_SWITCH_DEFAULT, alignedSize,
|
||||
nullptr, JKRDvdRipper::ALLOC_DIR_TOP, offset,
|
||||
nullptr);
|
||||
*pBuf = buffer;
|
||||
return alignedSize;
|
||||
|
||||
case JKRCOMPRESSION_YAY0:
|
||||
case JKRCOMPRESSION_YAZ0:
|
||||
u8* header = (u8*)JKRAllocFromHeap(heap, 0x20, 0x20);
|
||||
JKRDvdToMainRam(entryNum, header, EXPAND_SWITCH_NONE, 0x20, nullptr,
|
||||
JKRDvdRipper::ALLOC_DIR_TOP, offset, nullptr);
|
||||
|
||||
alignedSize = JKRDecompExpandSize(header);
|
||||
JKRFreeToHeap(heap, header);
|
||||
buffer = (u8*)JKRAllocFromHeap(heap, alignedSize, 0x20);
|
||||
JUT_ASSERT(buffer);
|
||||
|
||||
JKRDvdToMainRam(entryNum, buffer, EXPAND_SWITCH_DECOMPRESS,
|
||||
alignedSize, nullptr, JKRDvdRipper::ALLOC_DIR_TOP,
|
||||
offset, nullptr);
|
||||
*pBuf = buffer;
|
||||
return alignedSize;
|
||||
}
|
||||
}
|
||||
case JKRCOMPRESSION_YAZ0:
|
||||
{
|
||||
buffer = (u8*)JKRAllocFromHeap(heap, alignedSize, 32);
|
||||
JUT_ASSERT(buffer);
|
||||
JKRDvdToMainRam(entryNum, buffer, EXPAND_SWITCH_DECOMPRESS, size, nullptr,
|
||||
JKRDvdRipper::ALLOC_DIR_TOP, offset, nullptr);
|
||||
*pBuf = buffer;
|
||||
return alignedSize;
|
||||
}
|
||||
|
||||
case JKRCOMPRESSION_YAY0:
|
||||
{
|
||||
JPANIC(612, "Sorry, not prepared for SZP archive.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
JPANIC(617, ":::??? bad sequence\n");
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -29,12 +29,12 @@ void JKRDvdFile::initiate() {
|
||||
/* Reference to self. Used to retrieve reference in the DVDReadAsync
|
||||
* DVDCallback func. */
|
||||
this->mDvdFileInfo.mFile = this;
|
||||
OSInitMutex(&this->mMutex1);
|
||||
OSInitMutex(&this->mMutex2);
|
||||
OSInitMessageQueue(&this->mMessageQueue2, &this->mMsg2, 1);
|
||||
OSInitMessageQueue(&this->mMessageQueue1, &this->mMsg1, 1);
|
||||
this->mThread2 = nullptr;
|
||||
this->mThread1 = nullptr;
|
||||
OSInitMutex(&this->mDvdMutex);
|
||||
OSInitMutex(&this->mAramMutex);
|
||||
OSInitMessageQueue(&this->mDvdMessageQueue, &this->mDvdMessage, 1);
|
||||
OSInitMessageQueue(&this->mAramMessageQueue, &this->mAramMessage, 1);
|
||||
this->mDvdThread = nullptr;
|
||||
this->mAramThread = nullptr;
|
||||
this->_58 = 0;
|
||||
}
|
||||
|
||||
@@ -68,29 +68,31 @@ bool JKRDvdFile::close() {
|
||||
if (DVDClose(&this->mDvdFileInfo)) {
|
||||
this->mFileOpen = false;
|
||||
return sDvdList.remove(&this->mLink);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
OSErrorLine(212, "cannot close DVD file\n"); /* JKRDvdFile.cpp line 212 */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int JKRDvdFile::readData(void* data, s32 length, s32 ofs) {
|
||||
OSLockMutex(&this->mMutex1);
|
||||
OSLockMutex(&this->mDvdMutex);
|
||||
s32 retAddr;
|
||||
|
||||
if (this->mThread2 != nullptr) {
|
||||
OSUnlockMutex(&this->mMutex1);
|
||||
if (this->mDvdThread != nullptr) {
|
||||
OSUnlockMutex(&this->mDvdMutex);
|
||||
return -1;
|
||||
} else {
|
||||
this->mThread2 = OSGetCurrentThread();
|
||||
}
|
||||
else {
|
||||
this->mDvdThread = OSGetCurrentThread();
|
||||
retAddr = -1;
|
||||
if (DVDReadAsync(&this->mDvdFileInfo, data, length, ofs,
|
||||
JKRDvdFile::doneProcess)) {
|
||||
JKRDvdFile::doneProcess)) {
|
||||
retAddr = this->sync();
|
||||
}
|
||||
|
||||
this->mThread2 = nullptr;
|
||||
OSUnlockMutex(&this->mMutex1);
|
||||
this->mDvdThread = nullptr;
|
||||
OSUnlockMutex(&this->mDvdMutex);
|
||||
}
|
||||
|
||||
return retAddr;
|
||||
@@ -101,14 +103,14 @@ int JKRDvdFile::writeData(const void* data, s32 length, s32 ofs) { return -1; }
|
||||
s32 JKRDvdFile::sync() {
|
||||
OSMessage m;
|
||||
|
||||
OSLockMutex(&this->mMutex1);
|
||||
OSReceiveMessage(&this->mMessageQueue2, &m, OS_MESSAGE_BLOCK);
|
||||
this->mThread2 = nullptr;
|
||||
OSUnlockMutex(&this->mMutex1);
|
||||
OSLockMutex(&this->mDvdMutex);
|
||||
OSReceiveMessage(&this->mDvdMessageQueue, &m, OS_MESSAGE_BLOCK);
|
||||
this->mDvdThread = nullptr;
|
||||
OSUnlockMutex(&this->mDvdMutex);
|
||||
return (s32)m;
|
||||
}
|
||||
|
||||
void JKRDvdFile::doneProcess(s32 result, DVDFileInfo* info) {
|
||||
OSSendMessage(&static_cast<JKRDvdFileInfo*>(info)->mFile->mMessageQueue2,
|
||||
(OSMessage)result, OS_MESSAGE_NOBLOCK);
|
||||
OSSendMessage(&static_cast<JKRDvdFileInfo*>(info)->mFile->mDvdMessageQueue,
|
||||
(OSMessage)result, OS_MESSAGE_NOBLOCK);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ static u8* nextSrcData(u8* nowData);
|
||||
|
||||
void* JKRDvdRipper::loadToMainRAM(const char* file, u8* buf, JKRExpandSwitch expandSwitch, u32 maxDest, JKRHeap* heap, EAllocDirection allocDir, u32 offset, int* compressMode) {
|
||||
JKRDvdFile dvdFile;
|
||||
|
||||
|
||||
if (!dvdFile.open(file)) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -28,7 +28,7 @@ void* JKRDvdRipper::loadToMainRAM(const char* file, u8* buf, JKRExpandSwitch exp
|
||||
|
||||
void* JKRDvdRipper::loadToMainRAM(s32 entrynum, u8* buf, JKRExpandSwitch expandSwitch, u32 maxDest, JKRHeap* heap, EAllocDirection allocDir, u32 offset, int* compressMode) {
|
||||
JKRDvdFile dvdFile;
|
||||
|
||||
|
||||
if (!dvdFile.open(entrynum)) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -108,9 +108,9 @@ void* JKRDvdRipper::loadToMainRAM(JKRDvdFile* file, u8* buf, JKRExpandSwitch exp
|
||||
u8* aligned_buf = (u8*)ALIGN_NEXT((u32)buffer, 32);
|
||||
while (true) {
|
||||
if (DVDReadPrio(file->getFileInfo(), aligned_buf, 32, offset, 2) >= 0) {
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (JKRDvdRipper::errorRetry == false) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -155,7 +155,7 @@ void* JKRDvdRipper::loadToMainRAM(JKRDvdFile* file, u8* buf, JKRExpandSwitch exp
|
||||
}
|
||||
|
||||
/* Looks like a bug here */
|
||||
#ifndef FIXES
|
||||
#ifndef FIXES
|
||||
if (DVDReadPrio(file->getFileInfo(), mem, fileSize, 0, 2) < 0) {
|
||||
if (JKRDvdRipper::errorRetry == false) {
|
||||
VIWaitForRetrace();
|
||||
@@ -169,7 +169,7 @@ void* JKRDvdRipper::loadToMainRAM(JKRDvdFile* file, u8* buf, JKRExpandSwitch exp
|
||||
JKRFree(mem);
|
||||
return buf;
|
||||
}
|
||||
#else
|
||||
#else
|
||||
while (DVDReadPrio(file->getFileInfo(), mem, fileSize, 0, 2) < 0) {
|
||||
if (JKRDvdRipper::errorRetry == false) {
|
||||
if (allocated) {
|
||||
@@ -179,13 +179,13 @@ void* JKRDvdRipper::loadToMainRAM(JKRDvdFile* file, u8* buf, JKRExpandSwitch exp
|
||||
JKRFree(mem);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
VIWaitForRetrace();
|
||||
}
|
||||
|
||||
JKRDecompress(mem, buf, finalSize, 0);
|
||||
JKRFree(mem);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
else if (fileCompressMode == JKRDecomp::SZS) {
|
||||
JKRDecompressFromDVD(file, buf, fileSize, finalSize, offset, 0);
|
||||
@@ -215,12 +215,12 @@ static u32 fileOffset;
|
||||
static u32 readCount;
|
||||
static u32 maxDest;
|
||||
|
||||
static int JKRDecompressFromDVD(JKRDvdFile* _srcFile, void* buf, u32 size, u32 _maxDest, u32 _fileOffset, u32 _srcOffset) {
|
||||
int JKRDecompressFromDVD(JKRDvdFile* _srcFile, void* buf, u32 size, u32 _maxDest, u32 _fileOffset, u32 _srcOffset) {
|
||||
int res = 0;
|
||||
|
||||
szpBuf = (u8*)JKRAllocFromSysHeap(SZP_BUFFERSIZE, -32);
|
||||
szpEnd = szpBuf + SZP_BUFFERSIZE;
|
||||
|
||||
|
||||
if (_fileOffset != 0) {
|
||||
refBuf = (u8*)JKRAllocFromSysHeap(REF_BUFFERSIZE, -4);
|
||||
refEnd = refBuf + REF_BUFFERSIZE;
|
||||
@@ -252,148 +252,148 @@ static int JKRDecompressFromDVD(JKRDvdFile* _srcFile, void* buf, u32 size, u32 _
|
||||
}
|
||||
|
||||
static int decompSZS_subroutine(u8* src, u8* dest) {
|
||||
u8 *endPtr;
|
||||
u8* endPtr;
|
||||
s32 validBitCount = 0;
|
||||
s32 currCodeByte = 0;
|
||||
u32 ts = 0;
|
||||
|
||||
if ((s32)src[0] != 'Y' || (s32)src[1] != 'a' || (s32)src[2] != 'z' || (s32)src[3] != '0')
|
||||
{
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
SZPHeader *header = (SZPHeader *)src;
|
||||
SZPHeader* header = (SZPHeader*)src;
|
||||
endPtr = dest + (header->decompSize - fileOffset);
|
||||
if (endPtr > dest + maxDest)
|
||||
{
|
||||
endPtr = dest + maxDest;
|
||||
endPtr = dest + maxDest;
|
||||
}
|
||||
|
||||
src += 0x10;
|
||||
do
|
||||
{
|
||||
if (validBitCount == 0)
|
||||
if (validBitCount == 0)
|
||||
{
|
||||
if ((src > srcLimit) && transLeft)
|
||||
{
|
||||
if ((src > srcLimit) && transLeft)
|
||||
{
|
||||
src = nextSrcData(src);
|
||||
if (!src)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
currCodeByte = *src;
|
||||
validBitCount = 8;
|
||||
src++;
|
||||
src = nextSrcData(src);
|
||||
if (!src)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (currCodeByte & 0x80)
|
||||
currCodeByte = *src;
|
||||
validBitCount = 8;
|
||||
src++;
|
||||
}
|
||||
if (currCodeByte & 0x80)
|
||||
{
|
||||
if (fileOffset != 0)
|
||||
{
|
||||
if (fileOffset != 0)
|
||||
if (readCount >= fileOffset)
|
||||
{
|
||||
*dest = *src;
|
||||
dest++;
|
||||
ts++;
|
||||
if (dest == endPtr)
|
||||
{
|
||||
if (readCount >= fileOffset)
|
||||
{
|
||||
*dest = *src;
|
||||
dest++;
|
||||
ts++;
|
||||
if (dest == endPtr)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
*(refCurrent++) = *src;
|
||||
if (refCurrent == refEnd)
|
||||
{
|
||||
refCurrent = refBuf;
|
||||
}
|
||||
src++;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
*dest = *src;
|
||||
dest++;
|
||||
src++;
|
||||
ts++;
|
||||
if (dest == endPtr)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
readCount++;
|
||||
}
|
||||
*(refCurrent++) = *src;
|
||||
if (refCurrent == refEnd)
|
||||
{
|
||||
refCurrent = refBuf;
|
||||
}
|
||||
src++;
|
||||
}
|
||||
else
|
||||
{
|
||||
u32 dist = src[1] | (src[0] & 0x0f) << 8;
|
||||
s32 numBytes = src[0] >> 4;
|
||||
src += 2;
|
||||
u8 *copySource;
|
||||
if (fileOffset != 0)
|
||||
{
|
||||
copySource = refCurrent - dist - 1;
|
||||
if (copySource < refBuf)
|
||||
{
|
||||
copySource += refEnd - refBuf;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
copySource = dest - dist - 1;
|
||||
}
|
||||
if (numBytes == 0)
|
||||
{
|
||||
numBytes = *src + 0x12;
|
||||
src += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
numBytes += 2;
|
||||
}
|
||||
if (fileOffset != 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (readCount >= fileOffset)
|
||||
{
|
||||
*dest = *copySource;
|
||||
dest++;
|
||||
ts++;
|
||||
if (dest == endPtr)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
*(refCurrent++) = *copySource;
|
||||
if (refCurrent == refEnd)
|
||||
{
|
||||
refCurrent = refBuf;
|
||||
}
|
||||
copySource++;
|
||||
if (copySource == refEnd)
|
||||
{
|
||||
copySource = refBuf;
|
||||
}
|
||||
readCount++;
|
||||
numBytes--;
|
||||
} while (numBytes != 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
*dest = *copySource;
|
||||
dest++;
|
||||
ts++;
|
||||
if (dest == endPtr)
|
||||
{
|
||||
break;
|
||||
}
|
||||
readCount++;
|
||||
numBytes--;
|
||||
copySource++;
|
||||
} while (numBytes != 0);
|
||||
}
|
||||
*dest = *src;
|
||||
dest++;
|
||||
src++;
|
||||
ts++;
|
||||
if (dest == endPtr)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
currCodeByte <<= 1;
|
||||
validBitCount--;
|
||||
readCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
u32 dist = src[1] | (src[0] & 0x0f) << 8;
|
||||
s32 numBytes = src[0] >> 4;
|
||||
src += 2;
|
||||
u8* copySource;
|
||||
if (fileOffset != 0)
|
||||
{
|
||||
copySource = refCurrent - dist - 1;
|
||||
if (copySource < refBuf)
|
||||
{
|
||||
copySource += refEnd - refBuf;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
copySource = dest - dist - 1;
|
||||
}
|
||||
if (numBytes == 0)
|
||||
{
|
||||
numBytes = *src + 0x12;
|
||||
src += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
numBytes += 2;
|
||||
}
|
||||
if (fileOffset != 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (readCount >= fileOffset)
|
||||
{
|
||||
*dest = *copySource;
|
||||
dest++;
|
||||
ts++;
|
||||
if (dest == endPtr)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
*(refCurrent++) = *copySource;
|
||||
if (refCurrent == refEnd)
|
||||
{
|
||||
refCurrent = refBuf;
|
||||
}
|
||||
copySource++;
|
||||
if (copySource == refEnd)
|
||||
{
|
||||
copySource = refBuf;
|
||||
}
|
||||
readCount++;
|
||||
numBytes--;
|
||||
} while (numBytes != 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
*dest = *copySource;
|
||||
dest++;
|
||||
ts++;
|
||||
if (dest == endPtr)
|
||||
{
|
||||
break;
|
||||
}
|
||||
readCount++;
|
||||
numBytes--;
|
||||
copySource++;
|
||||
} while (numBytes != 0);
|
||||
}
|
||||
}
|
||||
currCodeByte <<= 1;
|
||||
validBitCount--;
|
||||
} while (dest < endPtr);
|
||||
|
||||
return 0;
|
||||
@@ -442,16 +442,16 @@ static u8* nextSrcData(u8* nowData) {
|
||||
break;
|
||||
}
|
||||
// Oopsies, forgot to call the function
|
||||
#ifndef FIXES
|
||||
#ifndef FIXES
|
||||
if (JKRDvdRipper::isErrorRetry == false) {
|
||||
return nullptr;
|
||||
}
|
||||
#else
|
||||
#else
|
||||
if (JKRDvdRipper::isErrorRetry() == false) {
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
VIWaitForRetrace();
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -27,17 +27,17 @@
|
||||
* Nonmatched function. Unused in Animal Crossing.
|
||||
*/
|
||||
void JKRFile::read(void* data, s32 length, s32 ofs) {
|
||||
#ifdef JSYSTEM_DEBUG
|
||||
#ifdef JSYSTEM_DEBUG
|
||||
if (!JKR_ISALIGNED(length, 32)) {
|
||||
JUTAssertion::showAssert(JUTAssertion::getSDevice(), __FILE__, __LINE__, "( length & 0x1f ) == 0");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
while (true) {
|
||||
if (this->readData(data, length, ofs) == length) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
VIWaitForRetrace();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
#include <dolphin/dvd.h>
|
||||
#include "JSystem/JKernel/JKRFileFinder.h"
|
||||
#include "JSystem/JKernel/JKRArchive.h"
|
||||
|
||||
JKRArcFinder::JKRArcFinder(JKRArchive* archive, long startindex, long entries) : JKRFileFinder()
|
||||
{
|
||||
mArchive = archive;
|
||||
|
||||
mIsAvailable = entries > 0;
|
||||
mStartIndex = startindex;
|
||||
mEndIndex = startindex + entries - 1;
|
||||
mNextIndex = mStartIndex;
|
||||
|
||||
findNextFile();
|
||||
}
|
||||
|
||||
bool JKRArcFinder::findNextFile()
|
||||
{
|
||||
if (mIsAvailable)
|
||||
{
|
||||
mIsAvailable = (mNextIndex <= mEndIndex);
|
||||
if (mIsAvailable)
|
||||
{
|
||||
JKRArchive::SDirEntry dirEntry;
|
||||
mIsAvailable = mArchive->getDirEntry(&dirEntry, mNextIndex);
|
||||
mBase.mFileName = dirEntry.mName;
|
||||
mBase.mFileIndex = mNextIndex;
|
||||
mBase.mFileID = dirEntry.mID;
|
||||
mBase.mFileTypeFlags = dirEntry.mFlags;
|
||||
mIsFileOrDir = FLAG_OFF(mBase.mFileTypeFlags, 2);
|
||||
mNextIndex++;
|
||||
}
|
||||
}
|
||||
return mIsAvailable;
|
||||
}
|
||||
|
||||
// UNUSED
|
||||
JKRDvdFinder::JKRDvdFinder(const char* path) : JKRFileFinder()
|
||||
{
|
||||
mIsDvdOpen = DVDOpenDir(const_cast<char*>(path), &mDir);
|
||||
mIsAvailable = mIsDvdOpen;
|
||||
findNextFile();
|
||||
}
|
||||
|
||||
// UNUSED, not sure if it matches
|
||||
bool JKRDvdFinder::findNextFile()
|
||||
{
|
||||
if (mIsAvailable)
|
||||
{
|
||||
DVDDirEntry entry;
|
||||
mIsAvailable = DVDReadDir(&mDir, &entry);
|
||||
if (mIsAvailable)
|
||||
{
|
||||
mIsFileOrDir = (bool)entry.isDir;
|
||||
mBase.mFileName = entry.name;
|
||||
mBase.mFileIndex = entry.entryNum;
|
||||
mBase.mFileID = 0;
|
||||
|
||||
mBase.mFileTypeFlags = mIsFileOrDir ? 2 : 1;
|
||||
}
|
||||
}
|
||||
return mIsAvailable;
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
#include <MSL_C/ctype.h>
|
||||
#include <dolphin/string.h>
|
||||
#include "JSystem/JKernel/JKRFileLoader.h"
|
||||
|
||||
JSUList<JKRFileLoader> JKRFileLoader::sVolumeList;
|
||||
JKRFileLoader* JKRFileLoader::sCurrentVolume;
|
||||
|
||||
JKRFileLoader::JKRFileLoader() : JKRDisposer(), mFileLoaderLink(this)
|
||||
{
|
||||
mVolumeName = nullptr;
|
||||
mVolumeType = 0;
|
||||
mMountCount = 0;
|
||||
}
|
||||
|
||||
JKRFileLoader::~JKRFileLoader()
|
||||
{
|
||||
if (sCurrentVolume == this)
|
||||
sCurrentVolume = nullptr;
|
||||
}
|
||||
|
||||
void JKRFileLoader::unmount()
|
||||
{
|
||||
if (mMountCount != 0)
|
||||
{
|
||||
if (--mMountCount == 0)
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
void JKRFileLoader::changeDirectory(const char* dir)
|
||||
{
|
||||
JKRFileLoader* vol = findVolume(&dir);
|
||||
if (vol)
|
||||
vol->becomeCurrent(dir);
|
||||
}
|
||||
|
||||
void* JKRFileLoader::getGlbResource(const char* path)
|
||||
{
|
||||
const char* components[2];
|
||||
components[0] = path;
|
||||
JKRFileLoader* loader = findVolume(components);
|
||||
return (loader == nullptr) ? nullptr : loader->getResource(components[0]);
|
||||
}
|
||||
|
||||
void* JKRFileLoader::getGlbResource(const char* name, JKRFileLoader* fileLoader)
|
||||
{
|
||||
void* resource = nullptr;
|
||||
if (fileLoader)
|
||||
{
|
||||
return fileLoader->getResource(0, name);
|
||||
}
|
||||
|
||||
JSUList<JKRFileLoader>& volumeList = getVolumeList();
|
||||
JSUListIterator<JKRFileLoader> iterator;
|
||||
for (iterator = volumeList.getFirst(); iterator != volumeList.getEnd(); ++iterator)
|
||||
{
|
||||
resource = iterator->getResource(0, name);
|
||||
if (resource)
|
||||
break;
|
||||
}
|
||||
return resource;
|
||||
}
|
||||
|
||||
size_t JKRFileLoader::readGlbResource(void* resBuf, u32 bufSize, const char* volumeName, JKRExpandSwitch expandSwitch)
|
||||
{
|
||||
JKRFileLoader* vol = findVolume(&volumeName);
|
||||
|
||||
return vol == nullptr ? 0 : vol->readResource(resBuf, bufSize, volumeName, expandSwitch);
|
||||
}
|
||||
|
||||
bool JKRFileLoader::removeResource(void* resourceBuffer, JKRFileLoader* fileLoader)
|
||||
{
|
||||
if (fileLoader)
|
||||
{
|
||||
return fileLoader->removeResource(resourceBuffer);
|
||||
}
|
||||
|
||||
JSUList<JKRFileLoader>& volumeList = getVolumeList();
|
||||
JSUListIterator<JKRFileLoader> iterator;
|
||||
for (iterator = volumeList.getFirst(); iterator != volumeList.getEnd(); ++iterator)
|
||||
{
|
||||
if (iterator->removeResource(resourceBuffer))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool JKRFileLoader::detachResource(void* resourceBuffer, JKRFileLoader* fileLoader)
|
||||
{
|
||||
if (fileLoader)
|
||||
{
|
||||
return fileLoader->detachResource(resourceBuffer);
|
||||
}
|
||||
|
||||
JSUList<JKRFileLoader>& volumeList = getVolumeList();
|
||||
JSUListIterator<JKRFileLoader> iterator;
|
||||
for (iterator = volumeList.getFirst(); iterator != volumeList.getEnd(); ++iterator)
|
||||
{
|
||||
if (iterator->detachResource(resourceBuffer))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
JKRFileLoader* JKRFileLoader::findVolume(const char** volumeName)
|
||||
{
|
||||
if (*volumeName[0] != '/')
|
||||
{
|
||||
return sCurrentVolume;
|
||||
}
|
||||
|
||||
char volumeNameBuffer[0x101];
|
||||
*volumeName = fetchVolumeName(volumeNameBuffer, ARRAY_COUNT(volumeNameBuffer), *volumeName);
|
||||
|
||||
JSUList<JKRFileLoader>& volumeList = sVolumeList;
|
||||
JSUListIterator<JKRFileLoader> iterator;
|
||||
for (iterator = volumeList.getFirst(); iterator != volumeList.getEnd(); ++iterator)
|
||||
{
|
||||
if (strcmp(volumeNameBuffer, iterator->mVolumeName) == 0)
|
||||
return iterator.getObject();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JKRFileFinder* JKRFileLoader::findFirstFile(const char* volumeName)
|
||||
{
|
||||
JKRFileFinder* ret = nullptr;
|
||||
|
||||
JKRFileLoader* vol = findVolume(&volumeName);
|
||||
if (vol)
|
||||
ret = vol->getFirstFile(volumeName);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const char* JKRFileLoader::fetchVolumeName(char* buffer, long bufferSize, const char* path)
|
||||
{
|
||||
static char rootPath[] = "/";
|
||||
if (strcmp(path, "/") == 0)
|
||||
{
|
||||
strcpy(buffer, rootPath);
|
||||
return rootPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
path++;
|
||||
while (*path != 0 && *path != '/')
|
||||
{
|
||||
if (1 < bufferSize)
|
||||
{
|
||||
*buffer = _tolower(*path);
|
||||
buffer++;
|
||||
bufferSize--;
|
||||
}
|
||||
path++;
|
||||
}
|
||||
buffer[0] = '\0';
|
||||
if (path[0] == '\0')
|
||||
path = rootPath;
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
@@ -7,26 +7,26 @@
|
||||
#include "dolphin/os/OSUtil.h"
|
||||
#include "dolphin/os/OSAddress.h"
|
||||
|
||||
JKRHeap *JKRHeap::sSystemHeap;
|
||||
JKRHeap *JKRHeap::sCurrentHeap;
|
||||
JKRHeap *JKRHeap::sRootHeap;
|
||||
JKRHeapErrorHandler *JKRHeap::mErrorHandler;
|
||||
void *JKRHeap::mCodeStart;
|
||||
void *JKRHeap::mCodeEnd;
|
||||
void *JKRHeap::mUserRamStart;
|
||||
void *JKRHeap::mUserRamEnd;
|
||||
JKRHeap* JKRHeap::sSystemHeap;
|
||||
JKRHeap* JKRHeap::sCurrentHeap;
|
||||
JKRHeap* JKRHeap::sRootHeap;
|
||||
JKRHeapErrorHandler* JKRHeap::mErrorHandler;
|
||||
void* JKRHeap::mCodeStart;
|
||||
void* JKRHeap::mCodeEnd;
|
||||
void* JKRHeap::mUserRamStart;
|
||||
void* JKRHeap::mUserRamEnd;
|
||||
u32 JKRHeap::mMemorySize;
|
||||
|
||||
bool JKRHeap::sDefaultFillFlag = true;
|
||||
|
||||
JKRHeap::JKRHeap(void *data, u32 size, JKRHeap *heap, bool errorFlag) : JKRDisposer(),
|
||||
mChildTree(this),
|
||||
mDisposerList()
|
||||
JKRHeap::JKRHeap(void* data, u32 size, JKRHeap* heap, bool errorFlag) : JKRDisposer(),
|
||||
mChildTree(this),
|
||||
mDisposerList()
|
||||
{
|
||||
OSInitMutex(&mMutex);
|
||||
mSize = size;
|
||||
mStart = (u8 *)data;
|
||||
mEnd = ((u8 *)data + size);
|
||||
mStart = (u8*)data;
|
||||
mEnd = ((u8*)data + size);
|
||||
if (heap == nullptr)
|
||||
{
|
||||
becomeSystemHeap();
|
||||
@@ -50,7 +50,7 @@ JKRHeap::JKRHeap(void *data, u32 size, JKRHeap *heap, bool errorFlag) : JKRDispo
|
||||
JKRHeap::~JKRHeap()
|
||||
{
|
||||
mChildTree.getParent()->removeChild(&mChildTree);
|
||||
JSUTree<JKRHeap> *nextRootHeap = sRootHeap->mChildTree.getFirstChild();
|
||||
JSUTree<JKRHeap>* nextRootHeap = sRootHeap->mChildTree.getFirstChild();
|
||||
if (sCurrentHeap == this)
|
||||
sCurrentHeap = !nextRootHeap ? sRootHeap : nextRootHeap->getObject();
|
||||
|
||||
@@ -58,53 +58,53 @@ JKRHeap::~JKRHeap()
|
||||
sSystemHeap = !nextRootHeap ? sRootHeap : nextRootHeap->getObject();
|
||||
}
|
||||
|
||||
bool JKRHeap::initArena(char **outUserRamStart, u32 *outUserRamSize, int numHeaps)
|
||||
bool JKRHeap::initArena(char** outUserRamStart, u32* outUserRamSize, int numHeaps)
|
||||
{
|
||||
void *arenaLo = OSGetArenaLo();
|
||||
void *arenaHi = OSGetArenaHi();
|
||||
void* arenaLo = OSGetArenaLo();
|
||||
void* arenaHi = OSGetArenaHi();
|
||||
if (arenaLo == arenaHi)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
void *arenaStart = OSInitAlloc(arenaLo, arenaHi, numHeaps);
|
||||
arenaHi = (u8 *)OSRoundDown32B(arenaHi);
|
||||
arenaLo = (u8 *)OSRoundUp32B(arenaStart);
|
||||
u8 *start = (u8 *)OSPhysicalToCached(0);
|
||||
mCodeStart = (u8 *)start;
|
||||
mCodeEnd = (u8 *)arenaLo;
|
||||
mUserRamStart = (u8 *)arenaLo;
|
||||
mUserRamEnd = (u8 *)arenaHi;
|
||||
mMemorySize = *(u32 *)((start + 0x28));
|
||||
void* arenaStart = OSInitAlloc(arenaLo, arenaHi, numHeaps);
|
||||
arenaHi = (u8*)OSRoundDown32B(arenaHi);
|
||||
arenaLo = (u8*)OSRoundUp32B(arenaStart);
|
||||
u8* start = (u8*)OSPhysicalToCached(0);
|
||||
mCodeStart = (u8*)start;
|
||||
mCodeEnd = (u8*)arenaLo;
|
||||
mUserRamStart = (u8*)arenaLo;
|
||||
mUserRamEnd = (u8*)arenaHi;
|
||||
mMemorySize = *(u32*)((start + 0x28));
|
||||
OSSetArenaLo(arenaHi);
|
||||
OSSetArenaHi(arenaHi);
|
||||
*outUserRamStart = (char *)arenaLo;
|
||||
*outUserRamStart = (char*)arenaLo;
|
||||
*outUserRamSize = (u32)arenaHi - (u32)arenaLo;
|
||||
return true;
|
||||
}
|
||||
|
||||
JKRHeap *JKRHeap::becomeSystemHeap()
|
||||
JKRHeap* JKRHeap::becomeSystemHeap()
|
||||
{
|
||||
JKRHeap *old = sSystemHeap;
|
||||
JKRHeap* old = sSystemHeap;
|
||||
sSystemHeap = this;
|
||||
return old;
|
||||
}
|
||||
|
||||
JKRHeap *JKRHeap::becomeCurrentHeap()
|
||||
JKRHeap* JKRHeap::becomeCurrentHeap()
|
||||
{
|
||||
JKRHeap *old = sCurrentHeap;
|
||||
JKRHeap* old = sCurrentHeap;
|
||||
sCurrentHeap = this;
|
||||
return old;
|
||||
}
|
||||
|
||||
void JKRHeap::destroy(JKRHeap *heap)
|
||||
void JKRHeap::destroy(JKRHeap* heap)
|
||||
{
|
||||
JUT_ASSERT(200, heap != 0);
|
||||
heap->destroy();
|
||||
}
|
||||
|
||||
void *JKRHeap::alloc(u32 byteCount, int padding, JKRHeap *heap)
|
||||
void* JKRHeap::alloc(u32 byteCount, int padding, JKRHeap* heap)
|
||||
{
|
||||
void *memory = nullptr;
|
||||
void* memory = nullptr;
|
||||
if (heap)
|
||||
{
|
||||
memory = heap->do_alloc(byteCount, padding);
|
||||
@@ -116,13 +116,13 @@ void *JKRHeap::alloc(u32 byteCount, int padding, JKRHeap *heap)
|
||||
return memory;
|
||||
}
|
||||
|
||||
void *JKRHeap::alloc(u32 byteCount, int padding)
|
||||
void* JKRHeap::alloc(u32 byteCount, int padding)
|
||||
{
|
||||
JUT_WARNING_F(317, !mInitFlag, "alloc %x byte in heap %x", byteCount, this);
|
||||
return do_alloc(byteCount, padding);
|
||||
}
|
||||
|
||||
void JKRHeap::free(void *memory, JKRHeap *heap)
|
||||
void JKRHeap::free(void* memory, JKRHeap* heap)
|
||||
{
|
||||
if ((heap) || (heap = findFromRoot(memory), heap))
|
||||
{
|
||||
@@ -130,7 +130,7 @@ void JKRHeap::free(void *memory, JKRHeap *heap)
|
||||
}
|
||||
}
|
||||
|
||||
void JKRHeap::free(void *memory)
|
||||
void JKRHeap::free(void* memory)
|
||||
{
|
||||
JUT_WARNING_F(365, !mInitFlag, "free %x in heap %x", memory, this);
|
||||
do_free(memory);
|
||||
@@ -157,13 +157,13 @@ void JKRHeap::freeTail()
|
||||
do_freeTail();
|
||||
}
|
||||
|
||||
void JKRHeap::resize(void *memoryBlock, u32 newSize)
|
||||
void JKRHeap::resize(void* memoryBlock, u32 newSize)
|
||||
{
|
||||
JUT_WARNING_F(491, !mInitFlag, "resize block %x into %x in heap %x", memoryBlock, newSize, this);
|
||||
do_resize(memoryBlock, newSize);
|
||||
}
|
||||
|
||||
s32 JKRHeap::getSize(void *memoryBlock, JKRHeap *heap)
|
||||
s32 JKRHeap::getSize(void* memoryBlock, JKRHeap* heap)
|
||||
{
|
||||
if (heap == nullptr && (heap = findFromRoot(memoryBlock), heap == nullptr))
|
||||
{
|
||||
@@ -173,7 +173,7 @@ s32 JKRHeap::getSize(void *memoryBlock, JKRHeap *heap)
|
||||
return heap->getSize(memoryBlock);
|
||||
}
|
||||
|
||||
s32 JKRHeap::getSize(void *memoryBlock) { return do_getSize(memoryBlock); }
|
||||
s32 JKRHeap::getSize(void* memoryBlock) { return do_getSize(memoryBlock); }
|
||||
s32 JKRHeap::getFreeSize() { return do_getFreeSize(); }
|
||||
s32 JKRHeap::getTotalFreeSize() { return do_getTotalFreeSize(); }
|
||||
|
||||
@@ -185,7 +185,7 @@ s32 JKRHeap::changeGroupID(u8 newGroupID)
|
||||
|
||||
u8 JKRHeap::getCurrentGroupId() { return do_getCurrentGroupId(); }
|
||||
|
||||
JKRHeap *JKRHeap::findFromRoot(void *ptr)
|
||||
JKRHeap* JKRHeap::findFromRoot(void* ptr)
|
||||
{
|
||||
if (sRootHeap != nullptr)
|
||||
return sRootHeap->find(ptr);
|
||||
@@ -193,7 +193,7 @@ JKRHeap *JKRHeap::findFromRoot(void *ptr)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JKRHeap *JKRHeap::find(void *memory) const
|
||||
JKRHeap* JKRHeap::find(void* memory) const
|
||||
{
|
||||
if ((mStart <= memory) && (memory <= mEnd))
|
||||
{
|
||||
@@ -201,25 +201,25 @@ JKRHeap *JKRHeap::find(void *memory) const
|
||||
{
|
||||
for (JSUTreeIterator<JKRHeap> iterator(mChildTree.getFirstChild()); iterator != mChildTree.getEndChild(); ++iterator)
|
||||
{
|
||||
JKRHeap *result = iterator->find(memory);
|
||||
JKRHeap* result = iterator->find(memory);
|
||||
if (result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return const_cast<JKRHeap *>(this);
|
||||
return const_cast<JKRHeap*>(this);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JKRHeap *JKRHeap::findAllHeap(void *memory) const
|
||||
JKRHeap* JKRHeap::findAllHeap(void* memory) const
|
||||
{
|
||||
if (mChildTree.getNumChildren() != 0)
|
||||
{
|
||||
for (JSUTreeIterator<JKRHeap> iterator(mChildTree.getFirstChild()); iterator != mChildTree.getEndChild(); ++iterator)
|
||||
{
|
||||
JKRHeap *result = iterator->findAllHeap(memory);
|
||||
JKRHeap* result = iterator->findAllHeap(memory);
|
||||
if (result)
|
||||
{
|
||||
return result;
|
||||
@@ -229,7 +229,7 @@ JKRHeap *JKRHeap::findAllHeap(void *memory) const
|
||||
|
||||
if (mStart <= memory && memory < mEnd)
|
||||
{
|
||||
return const_cast<JKRHeap *>(this);
|
||||
return const_cast<JKRHeap*>(this);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
@@ -242,11 +242,11 @@ void JKRHeap::dispose_subroutine(u32 begin, u32 end)
|
||||
JSUListIterator<JKRDisposer> next_iterator;
|
||||
JSUListIterator<JKRDisposer> iterator;
|
||||
for (iterator = mDisposerList.getFirst(); iterator != mDisposerList.getEnd();
|
||||
iterator = next_iterator)
|
||||
iterator = next_iterator)
|
||||
{
|
||||
JKRDisposer *disposer = iterator.getObject();
|
||||
JKRDisposer* disposer = iterator.getObject();
|
||||
|
||||
if ((void *)begin <= disposer && disposer < (void *)end)
|
||||
if ((void*)begin <= disposer && disposer < (void*)end)
|
||||
{
|
||||
disposer->~JKRDisposer();
|
||||
if (last_iterator == nullptr)
|
||||
@@ -268,7 +268,7 @@ void JKRHeap::dispose_subroutine(u32 begin, u32 end)
|
||||
}
|
||||
}
|
||||
|
||||
bool JKRHeap::dispose(void *memory, u32 size)
|
||||
bool JKRHeap::dispose(void* memory, u32 size)
|
||||
{
|
||||
u32 begin = (u32)memory;
|
||||
u32 end = (u32)memory + size;
|
||||
@@ -276,7 +276,7 @@ bool JKRHeap::dispose(void *memory, u32 size)
|
||||
return false;
|
||||
}
|
||||
|
||||
void JKRHeap::dispose(void *begin, void *end)
|
||||
void JKRHeap::dispose(void* begin, void* end)
|
||||
{
|
||||
dispose_subroutine((u32)begin, (u32)end);
|
||||
}
|
||||
@@ -290,12 +290,12 @@ void JKRHeap::dispose()
|
||||
}
|
||||
}
|
||||
|
||||
void JKRHeap::copyMemory(void *dst, void *src, u32 size)
|
||||
void JKRHeap::copyMemory(void* dst, void* src, u32 size)
|
||||
{
|
||||
u32 count = (size + 3) / 4;
|
||||
|
||||
u32 *dst_32 = (u32 *)dst;
|
||||
u32 *src_32 = (u32 *)src;
|
||||
u32* dst_32 = (u32*)dst;
|
||||
u32* src_32 = (u32*)src;
|
||||
while (count > 0)
|
||||
{
|
||||
*dst_32 = *src_32;
|
||||
@@ -305,15 +305,15 @@ void JKRHeap::copyMemory(void *dst, void *src, u32 size)
|
||||
}
|
||||
}
|
||||
|
||||
void JKRDefaultMemoryErrorRoutine(void *heap, u32 size, int alignment)
|
||||
void JKRDefaultMemoryErrorRoutine(void* heap, u32 size, int alignment)
|
||||
{
|
||||
// OSReport("Error: Cannot allocate memory %d(0x%x)byte in %d byte alignment from %08x\n", size, size, alignment, heap);
|
||||
OSErrorLine(710, "abort\n");
|
||||
}
|
||||
|
||||
JKRHeapErrorHandler *JKRHeap::setErrorHandler(JKRHeapErrorHandler *newHandler)
|
||||
JKRHeapErrorHandler* JKRHeap::setErrorHandler(JKRHeapErrorHandler* newHandler)
|
||||
{
|
||||
JKRHeapErrorHandler *oldHandler = mErrorHandler;
|
||||
JKRHeapErrorHandler* oldHandler = mErrorHandler;
|
||||
if (!newHandler)
|
||||
{
|
||||
newHandler = JKRDefaultMemoryErrorRoutine;
|
||||
@@ -322,7 +322,7 @@ JKRHeapErrorHandler *JKRHeap::setErrorHandler(JKRHeapErrorHandler *newHandler)
|
||||
return oldHandler;
|
||||
}
|
||||
|
||||
bool JKRHeap::isSubHeap(JKRHeap *heap) const
|
||||
bool JKRHeap::isSubHeap(JKRHeap* heap) const
|
||||
{
|
||||
if (!heap)
|
||||
return false;
|
||||
@@ -347,35 +347,35 @@ bool JKRHeap::isSubHeap(JKRHeap *heap) const
|
||||
return false;
|
||||
}
|
||||
|
||||
void *operator new(u32 byteCount)
|
||||
void* operator new(u32 byteCount)
|
||||
{
|
||||
return JKRHeap::alloc(byteCount, 4, nullptr);
|
||||
}
|
||||
void *operator new(u32 byteCount, int alignment)
|
||||
void* operator new(u32 byteCount, int alignment)
|
||||
{
|
||||
return JKRHeap::alloc(byteCount, alignment, nullptr);
|
||||
}
|
||||
void *operator new(u32 byteCount, JKRHeap *heap, int alignment)
|
||||
void* operator new(u32 byteCount, JKRHeap* heap, int alignment)
|
||||
{
|
||||
return JKRHeap::alloc(byteCount, alignment, heap);
|
||||
}
|
||||
|
||||
void *operator new[](u32 byteCount)
|
||||
void* operator new[](u32 byteCount)
|
||||
{
|
||||
return JKRHeap::alloc(byteCount, 4, nullptr);
|
||||
}
|
||||
void *operator new[](u32 byteCount, int alignment)
|
||||
void* operator new[](u32 byteCount, int alignment)
|
||||
{
|
||||
return JKRHeap::alloc(byteCount, alignment, nullptr);
|
||||
}
|
||||
void *operator new[](u32 byteCount, JKRHeap *heap, int alignment)
|
||||
void* operator new[](u32 byteCount, JKRHeap* heap, int alignment)
|
||||
{
|
||||
return JKRHeap::alloc(byteCount, alignment, heap);
|
||||
}
|
||||
|
||||
// this is not needed without the other pragma and asm bs
|
||||
void operator delete(void *memory) { JKRHeap::free(memory, nullptr); }
|
||||
void operator delete[](void *memory) { JKRHeap::free(memory, nullptr); }
|
||||
// this is not needed without the other pragma and asm bs
|
||||
void operator delete(void* memory) { JKRHeap::free(memory, nullptr); }
|
||||
void operator delete[](void* memory) { JKRHeap::free(memory, nullptr); }
|
||||
|
||||
/*JKRHeap::TState::TState(const JKRHeap::TState::TArgument &arg, const JKRHeap::TState::TLocation &location)
|
||||
{
|
||||
@@ -392,25 +392,25 @@ JKRHeap::TState::TState(const JKRHeap::TState &other, const JKRHeap::TState::TLo
|
||||
// UNUSED FUNCTION
|
||||
}*/
|
||||
|
||||
JKRHeap::TState::~TState()
|
||||
JKRHeap::TState::~TState()
|
||||
{
|
||||
// Unused, however might need it
|
||||
}
|
||||
|
||||
void JKRHeap::state_register(JKRHeap::TState *p, u32) const
|
||||
void JKRHeap::state_register(JKRHeap::TState* p, u32) const
|
||||
{
|
||||
JUT_ASSERT(1132, p != 0);
|
||||
JUT_ASSERT(1133, p->getHeap() == this);
|
||||
}
|
||||
|
||||
bool JKRHeap::state_compare(const JKRHeap::TState &r1, const JKRHeap::TState &r2) const
|
||||
bool JKRHeap::state_compare(const JKRHeap::TState& r1, const JKRHeap::TState& r2) const
|
||||
{
|
||||
JUT_ASSERT(1141, r1.getHeap() == r2.getHeap());
|
||||
return (r1.getCheckCode() == r2.getCheckCode());
|
||||
}
|
||||
|
||||
// fabricated, but probably matches(except for line numbers)
|
||||
void JKRHeap::state_dumpDifference(const JKRHeap::TState &r1, const JKRHeap::TState &r2)
|
||||
void JKRHeap::state_dumpDifference(const JKRHeap::TState& r1, const JKRHeap::TState& r2)
|
||||
{
|
||||
JUT_LOG_F(1157, "heap : %p / %p", r1.getHeap(), r2.getHeap());
|
||||
JUT_LOG_F(1158, "check-code : 0x%08x / 0x%08x", r1.getCheckCode(), r2.getCheckCode());
|
||||
@@ -418,7 +418,7 @@ void JKRHeap::state_dumpDifference(const JKRHeap::TState &r1, const JKRHeap::TSt
|
||||
JUT_LOG_F(1160, "used size : %10u / %10u", r1.getUsedSize(), r2.getUsedSize());
|
||||
}
|
||||
|
||||
void JKRHeap::state_dump(const TState &state) const
|
||||
void JKRHeap::state_dump(const TState& state) const
|
||||
{
|
||||
JUT_LOG_F(1165, "check-code : 0x%08x", state.getCheckCode());
|
||||
JUT_LOG_F(1166, "id : 0x%08x", state.getId());
|
||||
|
||||
@@ -0,0 +1,247 @@
|
||||
#include <dolphin/string.h>
|
||||
#include <dolphin/os/OSCache.h>
|
||||
|
||||
#include "JSystem/JSystem.h"
|
||||
#include "JSystem/JKernel/JKRArchive.h"
|
||||
#include "JSystem/JKernel/JKRDecomp.h"
|
||||
#include "JSystem/JKernel/JKRDvdRipper.h"
|
||||
#include "JSystem/JUtility/JUTAssertion.h"
|
||||
|
||||
JKRMemArchive::JKRMemArchive() : JKRArchive() {}
|
||||
|
||||
JKRMemArchive::JKRMemArchive(s32 entryNum, EMountDirection mountDirection) : JKRArchive(entryNum, MOUNT_MEM)
|
||||
{
|
||||
mIsMounted = false;
|
||||
mMountDirection = mountDirection;
|
||||
if (!open(entryNum, mMountDirection))
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
mVolumeType = 'RARC';
|
||||
mVolumeName = &mStrTable[mDirectories->mOffset];
|
||||
sVolumeList.prepend(&mFileLoaderLink);
|
||||
mIsMounted = true;
|
||||
}
|
||||
}
|
||||
|
||||
JKRMemArchive::JKRMemArchive(void* mem, u32 size, JKRMemBreakFlag breakFlag) : JKRArchive((s32)mem, MOUNT_MEM)
|
||||
{
|
||||
mIsMounted = false;
|
||||
if (!open(mem, size, breakFlag))
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
mVolumeType = 'RARC';
|
||||
mVolumeName = &mStrTable[mDirectories->mOffset];
|
||||
sVolumeList.prepend(&mFileLoaderLink);
|
||||
mIsMounted = true;
|
||||
}
|
||||
}
|
||||
|
||||
JKRMemArchive::~JKRMemArchive()
|
||||
{
|
||||
if (mIsMounted == true)
|
||||
{
|
||||
if (mIsOpen && mArcHeader)
|
||||
JKRFreeToHeap(mHeap, mArcHeader);
|
||||
|
||||
sVolumeList.remove(&mFileLoaderLink);
|
||||
mIsMounted = false;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG // function is needed to generate certain strings first, however this is not what the original function looks like
|
||||
void JKRMemArchive::fixedInit(s32)
|
||||
{
|
||||
JUT_ASSERT(isMounted());
|
||||
JUT_PANIC("mMountCount == 1"); // some member is called mMountCount, if there's a game with this assert, fix
|
||||
JUT_ASSERT(mArcHeader->signature == 'RARC');
|
||||
}
|
||||
#endif
|
||||
|
||||
bool JKRMemArchive::open(s32 entryNum, JKRArchive::EMountDirection mountDirection)
|
||||
{
|
||||
mArcHeader = nullptr;
|
||||
mArcInfoBlock = nullptr;
|
||||
mArchiveData = nullptr;
|
||||
mDirectories = nullptr;
|
||||
mFileEntries = nullptr;
|
||||
mStrTable = nullptr;
|
||||
mIsOpen = false;
|
||||
mMountDirection = mountDirection;
|
||||
|
||||
if (mMountDirection == JKRArchive::MOUNT_DIRECTION_HEAD)
|
||||
{
|
||||
u32 loadedSize;
|
||||
mArcHeader = (SArcHeader*)JKRDvdRipper::loadToMainRAM(
|
||||
entryNum, nullptr, EXPAND_SWITCH_DECOMPRESS, 0, mHeap, JKRDvdRipper::ALLOC_DIR_TOP,
|
||||
0, (int*)&mCompression);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
u32 loadedSize;
|
||||
mArcHeader = (SArcHeader*)JKRDvdRipper::loadToMainRAM(
|
||||
entryNum, nullptr, EXPAND_SWITCH_DECOMPRESS, 0, mHeap,
|
||||
JKRDvdRipper::ALLOC_DIR_BOTTOM, 0, (int*)&mCompression);
|
||||
}
|
||||
|
||||
if (!mArcHeader)
|
||||
{
|
||||
mMountMode = UNKNOWN_MOUNT_MODE;
|
||||
}
|
||||
else
|
||||
{
|
||||
JUT_ASSERT(mArcHeader->signature == 'RARC');
|
||||
mArcInfoBlock = (SArcDataInfo*)((u8*)mArcHeader + mArcHeader->header_length);
|
||||
mDirectories = (SDIDirEntry*)((u8*)&mArcInfoBlock->num_nodes + mArcInfoBlock->node_offset);
|
||||
mFileEntries = (SDIFileEntry*)((u8*)&mArcInfoBlock->num_nodes + mArcInfoBlock->file_entry_offset);
|
||||
mStrTable = (char*)((u8*)&mArcInfoBlock->num_nodes + mArcInfoBlock->string_table_offset);
|
||||
|
||||
mArchiveData =
|
||||
(u8*)((u32)mArcHeader + mArcHeader->header_length + mArcHeader->file_data_offset);
|
||||
mIsOpen = true;
|
||||
}
|
||||
#if DEBUG
|
||||
// OS Assert?
|
||||
if (mMountMode == UNKNOWN_MOUNT_MODE)
|
||||
{
|
||||
OSReport(":::Cannot alloc memory [%s][%d]\n", __FILE__, 460);
|
||||
}
|
||||
#endif
|
||||
return (mMountMode == UNKNOWN_MOUNT_MODE) ? false : true;
|
||||
}
|
||||
|
||||
bool JKRMemArchive::open(void* buffer, u32 bufferSize, JKRMemBreakFlag flag)
|
||||
{
|
||||
mArcHeader = (SArcHeader*)buffer;
|
||||
JUT_ASSERT(mArcHeader->signature == 'RARC');
|
||||
mArcInfoBlock = (SArcDataInfo*)((u8*)mArcHeader + mArcHeader->header_length);
|
||||
mDirectories = (SDIDirEntry*)((u8*)&mArcInfoBlock->num_nodes + mArcInfoBlock->node_offset);
|
||||
mFileEntries = (SDIFileEntry*)((u8*)&mArcInfoBlock->num_nodes + mArcInfoBlock->file_entry_offset);
|
||||
mStrTable = (char*)((u8*)&mArcInfoBlock->num_nodes + mArcInfoBlock->string_table_offset);
|
||||
mArchiveData = (u8*)(((u32)mArcHeader + mArcHeader->header_length) + mArcHeader->file_data_offset);
|
||||
mIsOpen = (flag == MBF_1) ? true : false; // mIsOpen might be u8
|
||||
mHeap = JKRHeap::findFromRoot(buffer);
|
||||
mCompression = JKRCOMPRESSION_NONE;
|
||||
return true;
|
||||
}
|
||||
|
||||
void* JKRMemArchive::fetchResource(SDIFileEntry* fileEntry, u32* resourceSize)
|
||||
{
|
||||
JUT_ASSERT(isMounted())
|
||||
|
||||
if (!fileEntry->mData)
|
||||
fileEntry->mData = mArchiveData + fileEntry->mDataOffset;
|
||||
|
||||
if (resourceSize)
|
||||
*resourceSize = fileEntry->mSize;
|
||||
|
||||
return fileEntry->mData;
|
||||
}
|
||||
|
||||
void* JKRMemArchive::fetchResource(void* buffer, u32 bufferSize, SDIFileEntry* fileEntry,
|
||||
u32* resourceSize, JKRExpandSwitch expandSwitch)
|
||||
{
|
||||
JUT_ASSERT(isMounted())
|
||||
|
||||
bufferSize = (bufferSize & -32);
|
||||
u32 srcLength = ALIGN_NEXT(fileEntry->mSize, 32);
|
||||
if (srcLength > bufferSize)
|
||||
{
|
||||
srcLength = bufferSize;
|
||||
}
|
||||
|
||||
if (fileEntry->mData != nullptr)
|
||||
{
|
||||
JKRHeap::copyMemory(buffer, fileEntry->mData, srcLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
int compression = JKRConvertAttrToCompressionType(fileEntry->getAttr());
|
||||
if (expandSwitch != EXPAND_SWITCH_DECOMPRESS)
|
||||
compression = JKRCOMPRESSION_NONE;
|
||||
|
||||
void* data = mArchiveData + fileEntry->mDataOffset;
|
||||
srcLength =
|
||||
fetchResource_subroutine((u8*)data, srcLength, (u8*)buffer, bufferSize, compression);
|
||||
}
|
||||
|
||||
if (resourceSize)
|
||||
{
|
||||
*resourceSize = srcLength;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void JKRMemArchive::removeResourceAll(void)
|
||||
{
|
||||
JUT_ASSERT(isMounted());
|
||||
|
||||
if (mArcInfoBlock == nullptr)
|
||||
return;
|
||||
if (mMountMode == MOUNT_MEM)
|
||||
return;
|
||||
|
||||
// !@bug: looping over file entries without incrementing the fileEntry pointer. Thus, only the
|
||||
// first fileEntry will clear/remove the resource data.
|
||||
SDIFileEntry* fileEntry = mFileEntries;
|
||||
for (int i = 0; i < mArcInfoBlock->num_file_entries; i++)
|
||||
{
|
||||
if (fileEntry->mData)
|
||||
{
|
||||
fileEntry->mData = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool JKRMemArchive::removeResource(void* resource)
|
||||
{
|
||||
JUT_ASSERT(isMounted());
|
||||
|
||||
SDIFileEntry* fileEntry = findPtrResource(resource);
|
||||
if (!fileEntry)
|
||||
return false;
|
||||
|
||||
fileEntry->mData = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 JKRMemArchive::fetchResource_subroutine(u8* src, u32 srcLength, u8* dst, u32 dstLength, int compression)
|
||||
{
|
||||
u32 alignedDst = dstLength & -32;
|
||||
u32 alignedSrc = ALIGN_NEXT(srcLength, 32);
|
||||
switch (compression)
|
||||
{
|
||||
case JKRCOMPRESSION_NONE:
|
||||
if (alignedSrc > alignedDst)
|
||||
alignedSrc = alignedDst;
|
||||
|
||||
JKRHeap::copyMemory(dst, src, alignedSrc);
|
||||
return alignedSrc;
|
||||
|
||||
case JKRCOMPRESSION_YAY0:
|
||||
case JKRCOMPRESSION_YAZ0:
|
||||
u32 expandSize = JKRDecompExpandSize(src);
|
||||
|
||||
if (expandSize > alignedDst) {
|
||||
expandSize = alignedDst;
|
||||
}
|
||||
|
||||
JKRDecompress(src, dst, expandSize, 0);
|
||||
return expandSize;
|
||||
|
||||
default:
|
||||
{
|
||||
JPANIC(709, ":::??? bad sequence\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return alignedSrc;
|
||||
}
|
||||
@@ -1,13 +1,12 @@
|
||||
#include "JSystem/JKernel/JKRThread.h"
|
||||
|
||||
#include "JSystem/JSupport/JSUList.h"
|
||||
#include "JSystem/JKernel/JKRHeap.h"
|
||||
#include "JSystem/JKernel/JKRMacro.h"
|
||||
#include "JSystem/JKernel/JKRThread.h"
|
||||
#include "JSystem/JKernel/JKRHeap.h"
|
||||
|
||||
JSUList<JKRThread> JKRThread::sThreadList;
|
||||
|
||||
JKRThread::JKRThread(u32 stackSize, int msgCount, int threadPrio)
|
||||
: JKRDisposer(), mLink(this) {
|
||||
: mLink(this) {
|
||||
this->mHeap = JKRHeap::findFromRoot(this);
|
||||
if (this->mHeap == nullptr) {
|
||||
this->mHeap = JKRHeap::sSystemHeap;
|
||||
@@ -16,26 +15,26 @@ JKRThread::JKRThread(u32 stackSize, int msgCount, int threadPrio)
|
||||
this->mStackSize = JKR_ALIGN32(stackSize);
|
||||
this->mStackMemory = JKRHeap::alloc(this->mStackSize, 32, this->mHeap);
|
||||
this->mThreadRecord =
|
||||
(OSThread *)JKRHeap::alloc(sizeof(OSThread), 32, this->mHeap);
|
||||
(OSThread*)JKRHeap::alloc(sizeof(OSThread), 32, this->mHeap);
|
||||
OSCreateThread(this->mThreadRecord, &JKRThread::start, this,
|
||||
(void *)((u32)this->mStackMemory + this->mStackSize),
|
||||
this->mStackSize, threadPrio, OS_THREAD_ATTR_DETACH);
|
||||
(void*)((u32)this->mStackMemory + this->mStackSize),
|
||||
this->mStackSize, threadPrio, OS_THREAD_ATTR_DETACH);
|
||||
this->mMesgCount = msgCount;
|
||||
this->mMesgBuffer = (OSMessage *)JKRHeap::alloc(
|
||||
mMesgCount * sizeof(OSMessage), 0, this->mHeap);
|
||||
this->mMesgBuffer = (OSMessage*)JKRHeap::alloc(
|
||||
mMesgCount * sizeof(OSMessage), 0, this->mHeap);
|
||||
OSInitMessageQueue(&this->mMesgQueue, this->mMesgBuffer, this->mMesgCount);
|
||||
JKRThread::sThreadList.append(&this->mLink);
|
||||
}
|
||||
|
||||
JKRThread::JKRThread(OSThread *threadRecord, int msgCount)
|
||||
: JKRDisposer(), mLink(this) {
|
||||
JKRThread::JKRThread(OSThread* threadRecord, int msgCount)
|
||||
: mLink(this) {
|
||||
this->mHeap = nullptr;
|
||||
this->mThreadRecord = threadRecord;
|
||||
this->mStackSize = (u32)threadRecord->stackEnd - (u32)threadRecord->stackBase;
|
||||
this->mStackMemory = threadRecord->stackBase;
|
||||
this->mMesgCount = msgCount;
|
||||
this->mMesgBuffer = (OSMessage *)JKRHeap::sSystemHeap->alloc(
|
||||
mMesgCount * sizeof(OSMessage), 4);
|
||||
this->mMesgBuffer = (OSMessage*)JKRHeap::sSystemHeap->alloc(
|
||||
mMesgCount * sizeof(OSMessage), 4);
|
||||
OSInitMessageQueue(&this->mMesgQueue, this->mMesgBuffer, this->mMesgCount);
|
||||
JKRThread::sThreadList.append(&this->mLink);
|
||||
}
|
||||
@@ -56,6 +55,60 @@ JKRThread::~JKRThread() {
|
||||
JKRHeap::free(this->mMesgBuffer, nullptr);
|
||||
}
|
||||
|
||||
void *JKRThread::start(void *thread) {
|
||||
return static_cast<JKRThread*>(thread)->run();
|
||||
void* JKRThread::start(void* thread) {
|
||||
return static_cast<JKRThread*>(thread)->run();
|
||||
}
|
||||
|
||||
// UNUSED FUNCTIONS, REQUIRED FOR RTTI
|
||||
JKRTask::JKRTask() : JKRThread(0x4000, 4, 31)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
JKRTask::~JKRTask() { }
|
||||
|
||||
JKRTask* JKRTask::create()
|
||||
{
|
||||
return new JKRTask();
|
||||
}
|
||||
|
||||
void JKRTask::destroy() {
|
||||
delete this;
|
||||
}
|
||||
|
||||
void* JKRTask::run()
|
||||
{
|
||||
Request* req;
|
||||
//OSInitFastCast();
|
||||
while (true)
|
||||
{
|
||||
req = (Request*)waitMessageBlock();
|
||||
if (req->mCb)
|
||||
{
|
||||
req->mCb(req->mArg);
|
||||
if (mTaskMsgQueue)
|
||||
{
|
||||
OSSendMessage(mTaskMsgQueue, req->mMsg, OS_MESSAGE_NOBLOCK);
|
||||
}
|
||||
}
|
||||
req->mCb = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool JKRTask::request(RequestCallback callback, void* arg, void* msg)
|
||||
{
|
||||
Request* req = searchBlank();
|
||||
if (req == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
req->mCb = callback;
|
||||
req->mArg = arg;
|
||||
req->mMsg = msg;
|
||||
bool sendResult = OSSendMessage(&mMesgQueue, req, OS_MESSAGE_NOBLOCK);
|
||||
if (!sendResult)
|
||||
{
|
||||
req->mCb = nullptr;
|
||||
}
|
||||
return sendResult;
|
||||
}
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
#include "JSystem/JKernel/JKRThread.h"
|
||||
|
||||
__declspec(weak) void* JKRThread::run() { return nullptr; }
|
||||
@@ -0,0 +1 @@
|
||||
# there totally is code in this file, needed to bypass a bug caused by trim_ctors
|
||||
Reference in New Issue
Block a user