mirror of
https://github.com/zeldaret/ss
synced 2026-05-23 15:01:38 -04:00
d_dylink for the most part
This commit is contained in:
@@ -66,8 +66,11 @@ d/d_dvd_unk.cpp:
|
||||
d/d_dylink.cpp:
|
||||
.text start:0x80052E00 end:0x80053A30
|
||||
.ctors start:0x804DB674 end:0x804DB678
|
||||
.data start:0x8050D2D8 end:0x8050D30C
|
||||
.rodata start:0x804DDFD0 end:0x804DDFF0
|
||||
.data start:0x8050D2D8 end:0x8050D348
|
||||
.sdata start:0x80571C40 end:0x80571C50
|
||||
.sbss start:0x805750E0 end:0x805750FC
|
||||
.bss start:0x805975B0 end:0x80597608
|
||||
|
||||
d/d_fader.cpp:
|
||||
.text start:0x80053A30 end:0x80053E70
|
||||
|
||||
+28
-28
@@ -2167,23 +2167,23 @@ fn_80052D00 = .text:0x80052D00; // type:function size:0x14
|
||||
fn_80052D20 = .text:0x80052D20; // type:function size:0x30
|
||||
fn_80052D50 = .text:0x80052D50; // type:function size:0x78
|
||||
fn_80052DD0 = .text:0x80052DD0; // type:function size:0x2C
|
||||
fn_80052E00 = .text:0x80052E00; // type:function size:0x1A0
|
||||
fn_80052FA0 = .text:0x80052FA0; // type:function size:0x30
|
||||
initDylinkHeap__4dDylFiPC10RelNamePtriPQ23EGG4Heap = .text:0x80052E00; // type:function size:0x1A0
|
||||
isLinked__4dDylFUs = .text:0x80052FA0; // type:function size:0x30
|
||||
Unlink__4dDylFUs = .text:0x80052FD0; // type:function size:0x20
|
||||
fn_80052FF0 = .text:0x80052FF0; // type:function size:0x84
|
||||
fn_80053080 = .text:0x80053080; // type:function size:0x58
|
||||
fn_800530E0 = .text:0x800530E0; // type:function size:0x7C
|
||||
fn_80053160 = .text:0x80053160; // type:function size:0xDC
|
||||
tryLink__4dDylFUs = .text:0x80052FF0; // type:function size:0x84
|
||||
nandCallback__4dDylFlP16NANDCommandBlock = .text:0x80053080; // type:function size:0x58
|
||||
dvdCallback__4dDylFlP11DVDFileInfo = .text:0x800530E0; // type:function size:0x7C
|
||||
startDvdRead__4dDylFPQ24dDyl13UnkNandStructPvll = .text:0x80053160; // type:function size:0xDC
|
||||
fn_80053240 = .text:0x80053240; // type:function size:0x35C
|
||||
fn_800535A0 = .text:0x800535A0; // type:function size:0xB0
|
||||
fn_80053650 = .text:0x80053650; // type:function size:0xDC
|
||||
fn_80053730 = .text:0x80053730; // type:function size:0x48
|
||||
fn_80053780 = .text:0x80053780; // type:function size:0x54
|
||||
fn_800537E0 = .text:0x800537E0; // type:function size:0x30
|
||||
fn_80053810 = .text:0x80053810; // type:function size:0x6C
|
||||
fn_80053880 = .text:0x80053880; // type:function size:0xC
|
||||
do_link__21dDynamicModuleControlFv = .text:0x80053890; // type:function size:0xA0
|
||||
fn_80053930 = .text:0x80053930; // type:function size:0x9C
|
||||
loadRelsArcCallback__4dDylFPv = .text:0x800535A0; // type:function size:0xB0
|
||||
dvdCallback__4dDylFPv = .text:0x80053650; // type:function size:0xDC
|
||||
initModule__4dDylFv = .text:0x80053730; // type:function size:0x48
|
||||
destroy__4dDylFv = .text:0x80053780; // type:function size:0x54
|
||||
initRelsArc__4dDylFv = .text:0x800537E0; // type:function size:0x30
|
||||
__dt__21dDynamicModuleControlFv = .text:0x80053810; // type:function size:0x6C
|
||||
set__21dDynamicModuleControlFPUsi = .text:0x80053880; // type:function size:0xC
|
||||
do_link__21dDynamicModuleControlCFv = .text:0x80053890; // type:function size:0xA0
|
||||
do_unlink__21dDynamicModuleControlFv = .text:0x80053930; // type:function size:0x9C
|
||||
__sinit_\d_dylink_cpp = .text:0x800539D0; // type:function size:0x54
|
||||
fn_80053A30 = .text:0x80053A30; // type:function size:0xE4
|
||||
fn_80053B20 = .text:0x80053B20; // type:function size:0x128
|
||||
@@ -17756,9 +17756,9 @@ __ct__14mDvd_command_cFv = .text:0x802EF460; // type:function size:0x1C
|
||||
do_delete__14mDvd_command_cFv = .text:0x802EF480; // type:function size:0x20
|
||||
destroy__14mDvd_command_cFPP14mDvd_command_c = .text:0x802EF4A0; // type:function size:0x54
|
||||
__dt__15mDvd_callback_cFv = .text:0x802EF500; // type:function size:0x58
|
||||
__ct__15mDvd_callback_cFPFPv_bPv = .text:0x802EF560; // type:function size:0x64
|
||||
create__15mDvd_callback_cFPFPv_bPv = .text:0x802EF5D0; // type:function size:0x78
|
||||
fn_802EF650 = .text:0x802EF650; // type:function size:0x30
|
||||
__ct__15mDvd_callback_cFPFPv_UlPv = .text:0x802EF560; // type:function size:0x64
|
||||
create__15mDvd_callback_cFPFPv_UlPv = .text:0x802EF5D0; // type:function size:0x78
|
||||
createOrFail__15mDvd_callback_cFPFPv_UlPv = .text:0x802EF650; // type:function size:0x30
|
||||
execute__15mDvd_callback_cFv = .text:0x802EF680; // type:function size:0x54
|
||||
__dt__22mDvd_mountMemArchive_cFv = .text:0x802EF6E0; // type:function size:0x58
|
||||
__ct__22mDvd_mountMemArchive_cFi = .text:0x802EF740; // type:function size:0x74
|
||||
@@ -21967,7 +21967,7 @@ fn_803A94D0 = .text:0x803A94D0; // type:function size:0x4
|
||||
fn_803A94E0 = .text:0x803A94E0; // type:function size:0x4
|
||||
fn_803A94F0 = .text:0x803A94F0; // type:function size:0x4
|
||||
fn_803A9500 = .text:0x803A9500; // type:function size:0x4
|
||||
fn_803A9510 = .text:0x803A9510; // type:function size:0xC
|
||||
OSSetStringTable = .text:0x803A9510; // type:function size:0xC
|
||||
fn_803A9520 = .text:0x803A9520; // type:function size:0x2C4
|
||||
fn_803A97F0 = .text:0x803A97F0; // type:function size:0x2E8
|
||||
OSLink = .text:0x803A9AE0; // type:function size:0x8
|
||||
@@ -22633,10 +22633,10 @@ fn_803D0790 = .text:0x803D0790; // type:function size:0x40
|
||||
fn_803D07D0 = .text:0x803D07D0; // type:function size:0x14C
|
||||
fn_803D0920 = .text:0x803D0920; // type:function size:0x1F4
|
||||
fn_803D0B20 = .text:0x803D0B20; // type:function size:0x140
|
||||
fn_803D0C60 = .text:0x803D0C60; // type:function size:0x74
|
||||
NANDCreate = .text:0x803D0C60; // type:function size:0x74
|
||||
fn_803D0CE0 = .text:0x803D0CE0; // type:function size:0x74
|
||||
fn_803D0D60 = .text:0x803D0D60; // type:function size:0x78
|
||||
fn_803D0DE0 = .text:0x803D0DE0; // type:function size:0xB0
|
||||
NANDDelete = .text:0x803D0DE0; // type:function size:0xB0
|
||||
fn_803D0E90 = .text:0x803D0E90; // type:function size:0x98
|
||||
fn_803D0F30 = .text:0x803D0F30; // type:function size:0xC0
|
||||
NANDRead = .text:0x803D0FF0; // type:function size:0x68
|
||||
@@ -22657,8 +22657,8 @@ fn_803D1910 = .text:0x803D1910; // type:function size:0x154
|
||||
fn_803D1A70 = .text:0x803D1A70; // type:function size:0x74
|
||||
fn_803D1AF0 = .text:0x803D1AF0; // type:function size:0x64
|
||||
fn_803D1B60 = .text:0x803D1B60; // type:function size:0x84
|
||||
fn_803D1BF0 = .text:0x803D1BF0; // type:function size:0x8
|
||||
fn_803D1C00 = .text:0x803D1C00; // type:function size:0x8
|
||||
NANDSetUserData = .text:0x803D1BF0; // type:function size:0x8
|
||||
NANDGetUserData = .text:0x803D1C00; // type:function size:0x8
|
||||
fn_803D1C10 = .text:0x803D1C10; // type:function size:0x334
|
||||
nandOpen = .text:0x803D1F50; // type:function size:0x110 scope:local
|
||||
NANDOpen = .text:0x803D2060; // type:function size:0x8C
|
||||
@@ -26132,7 +26132,7 @@ removeList__Q23EGG7ArchiveFPQ23EGG7Archive = .text:0x80493850; // type:function
|
||||
mount__Q23EGG7ArchiveFPvPQ23EGG4Heapi = .text:0x80493860; // type:function size:0xE4
|
||||
mountType2__Q23EGG7ArchiveFPvPQ23EGG4Heapi = .text:0x80493950; // type:function size:0xE4
|
||||
mountNandFile__EGG__Archive = .text:0x80493A40; // type:function size:0x7C
|
||||
getNandFile__EGG__Ardhive = .text:0x80493AC0; // type:function size:0xBC
|
||||
loadFST__Q23EGG7ArchiveFPCcPQ23EGG4Heapl = .text:0x80493AC0; // type:function size:0xBC
|
||||
unmount__Q23EGG7ArchiveFv = .text:0x80493B80; // type:function size:0x94
|
||||
getFile__Q23EGG7ArchiveFPCcPQ33EGG7Archive8FileInfo = .text:0x80493C20; // type:function size:0xC4
|
||||
convertPathToEntryID__Q23EGG7ArchiveFPCc = .text:0x80493CF0; // type:function size:0x8
|
||||
@@ -27833,7 +27833,7 @@ lbl_804DC948 = .rodata:0x804DC948; // type:object size:0xDC
|
||||
lbl_804DCA24 = .rodata:0x804DCA24; // type:object size:0x80
|
||||
lbl_804DCAA4 = .rodata:0x804DCAA4; // type:object size:0x80
|
||||
lbl_804DCB24 = .rodata:0x804DCB24; // type:object size:0xCC
|
||||
lbl_804DCBF0 = .rodata:0x804DCBF0; // type:object size:0x13E0
|
||||
DYNAMIC_NAME_TABLE = .rodata:0x804DCBF0; // type:object size:0x13E0
|
||||
lbl_804DDFD0 = .rodata:0x804DDFD0; // type:object size:0xC data:4byte
|
||||
lbl_804DDFDC = .rodata:0x804DDFDC; // type:object size:0x14 data:4byte
|
||||
lbl_804DDFF0 = .rodata:0x804DDFF0; // type:object size:0x18
|
||||
@@ -30698,7 +30698,7 @@ lbl_8050D2CC = .data:0x8050D2CC; // type:object size:0xC
|
||||
lbl_8050D2D8 = .data:0x8050D2D8; // type:object size:0x32 data:string
|
||||
lbl_8050D30C = .data:0x8050D30C; // type:object size:0x14
|
||||
lbl_8050D320 = .data:0x8050D320; // type:object size:0x10
|
||||
lbl_8050D330 = .data:0x8050D330; // type:object size:0xC
|
||||
__vt__21dDynamicModuleControl = .data:0x8050D330; // type:object size:0xC
|
||||
lbl_8050D33C = .data:0x8050D33C; // type:object size:0xC
|
||||
lbl_8050D348 = .data:0x8050D348; // type:object size:0x10
|
||||
lbl_8050D358 = .data:0x8050D358; // type:object size:0x10 data:string
|
||||
@@ -37576,8 +37576,8 @@ lbl_80571C20 = .sdata:0x80571C20; // type:object size:0x8 data:string
|
||||
lbl_80571C28 = .sdata:0x80571C28; // type:object size:0x8
|
||||
lbl_80571C30 = .sdata:0x80571C30; // type:object size:0x8 data:string
|
||||
lbl_80571C38 = .sdata:0x80571C38; // type:object size:0x8 data:string
|
||||
lbl_80571C40 = .sdata:0x80571C40; // type:object size:0x4 data:4byte
|
||||
lbl_80571C44 = .sdata:0x80571C44; // type:object size:0x4 data:4byte
|
||||
status_1__4dDyl = .sdata:0x80571C40; // type:object size:0x4 data:4byte
|
||||
status_2__4dDyl = .sdata:0x80571C44; // type:object size:0x4 data:4byte
|
||||
lbl_80571C48 = .sdata:0x80571C48; // type:object size:0x8
|
||||
lbl_80571C50 = .sdata:0x80571C50; // type:object size:0x8 data:float
|
||||
lbl_80571C58 = .sdata:0x80571C58; // type:object size:0x8 data:byte
|
||||
|
||||
@@ -61,7 +61,7 @@ struct DynamicModuleControl : DynamicModuleControlBase {
|
||||
/* 802dfa60 */ virtual bool do_unlink();
|
||||
/* 802df3d0 */ DynamicModuleControl(char const*, EGG::ExpHeap *);
|
||||
/* 802df4d0 */ static void initialize(EGG::ExpHeap *heap);
|
||||
/* 802df530 */ static bool callback(void*);
|
||||
/* 802df530 */ static u32 callback(void*);
|
||||
void checkHeapStatus();
|
||||
|
||||
/* 0x10 */ UNKWORD unk_16;
|
||||
|
||||
+11
-3
@@ -3,10 +3,18 @@
|
||||
|
||||
#include <common.h>
|
||||
|
||||
namespace dDyl {
|
||||
class dDynamicModuleControl {
|
||||
public:
|
||||
dDynamicModuleControl() {}
|
||||
virtual ~dDynamicModuleControl();
|
||||
|
||||
bool Unlink(u16 relId);
|
||||
void set(u16 *ptr, int count);
|
||||
BOOL do_link() const;
|
||||
BOOL do_unlink();
|
||||
|
||||
} // dDyl
|
||||
private:
|
||||
u16 *mPtr;
|
||||
int mCount;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+3
-2
@@ -69,7 +69,7 @@ public:
|
||||
u8 mCompressionType;
|
||||
};
|
||||
|
||||
typedef bool (*dvdReadCallback)(void *);
|
||||
typedef u32 (*dvdReadCallback)(void *);
|
||||
|
||||
class mDvd_callback_c : public mDvd_command_c {
|
||||
public:
|
||||
@@ -78,10 +78,11 @@ public:
|
||||
virtual u32 execute() override;
|
||||
|
||||
static mDvd_callback_c *create(dvdReadCallback cb, void *cbData);
|
||||
static mDvd_callback_c *createOrFail(dvdReadCallback cb, void *cbData);
|
||||
|
||||
dvdReadCallback mCallback;
|
||||
void *mCallbackData;
|
||||
BOOL mSuccess;
|
||||
u32 mCallbackResult;
|
||||
};
|
||||
|
||||
class mDvd_mountMemArchive_c : public mDvd_command_c {
|
||||
|
||||
+2
-2
@@ -32,7 +32,7 @@ public:
|
||||
}
|
||||
/* 802f12b0 */ mHeap(EGG::Heap *heap);
|
||||
/* 802f12f0 */ ~mHeap();
|
||||
/* 802f1350 */ static EGG::Heap *createHeap(size_t size, EGG::Heap *, const char *name);
|
||||
/* 802f1350 */ static EGG::ExpHeap *createHeap(size_t size, EGG::Heap *, const char *name);
|
||||
/* 802f13d0 */ static void saveCurrentHeap();
|
||||
/* 802f13e0 */ static void restoreCurrentHeap();
|
||||
/* 802f1410 */ static EGG::FrmHeap *makeFrmHeapAndUpdate(size_t size, EGG::Heap *parentHeap, const char *name,
|
||||
@@ -56,7 +56,7 @@ public:
|
||||
static EGG::Heap *s_SavedCurrentHeap;
|
||||
static EGG::Heap *g_archiveHeap;
|
||||
static EGG::Heap *g_commandHeap;
|
||||
static EGG::Heap *g_dylinkHeap;
|
||||
static EGG::ExpHeap *g_dylinkHeap;
|
||||
static EGG::AssertHeap *g_assertHeap;
|
||||
static u8 g_DefaultGameHeapId;
|
||||
static const char *const s_GameHeapNames[4];
|
||||
|
||||
+1
-1
@@ -129,7 +129,7 @@ void DynamicModuleControl::initialize(EGG::ExpHeap *heap) {
|
||||
sTotalFreeSize = heap->getTotalFreeSize();
|
||||
}
|
||||
|
||||
bool DynamicModuleControl::callback(void *arg) {
|
||||
u32 DynamicModuleControl::callback(void *arg) {
|
||||
return static_cast<DynamicModuleControl *>(arg)->do_load();
|
||||
}
|
||||
|
||||
|
||||
+308
-11
@@ -1,8 +1,10 @@
|
||||
#include <common.h>
|
||||
#include <DynamicLink.h>
|
||||
#include <common.h>
|
||||
#include <d/d_dylink.h>
|
||||
#include <m/m_dvd.h>
|
||||
#include <m/m_heap.h>
|
||||
#include <rvl/DVD.h>
|
||||
#include <rvl/NAND.h>
|
||||
// clang-format off
|
||||
#include <MSL_C/string.h>
|
||||
// clang-format on
|
||||
@@ -12,9 +14,13 @@ struct RelNamePtr {
|
||||
const char *name;
|
||||
};
|
||||
|
||||
static RelNamePtr *pDynamicNameTable;
|
||||
extern const RelNamePtr DYNAMIC_NAME_TABLE[];
|
||||
|
||||
static const RelNamePtr *pDynamicNameTable;
|
||||
static int nDynamicNameTable;
|
||||
|
||||
DynamicModuleControl g_DMC("d_profile", nullptr);
|
||||
|
||||
namespace dDyl {
|
||||
|
||||
DynamicModuleControl **pDMC;
|
||||
@@ -23,8 +29,21 @@ EGG::Heap *cCc_frmHeap;
|
||||
u32 Initialized;
|
||||
mDvd_callback_c *DVD;
|
||||
|
||||
// initDylinkHeap
|
||||
extern "C" int fn_80052E00(int maxRelId, RelNamePtr *dynNameTable, int dynNameTableNum, EGG::Heap *parentHeap) {
|
||||
enum NandChunkStatus {
|
||||
Success = 1,
|
||||
DVDPending = 2,
|
||||
NANDPending = 4,
|
||||
Error = 8,
|
||||
|
||||
FinalizedMask = Success | Error,
|
||||
};
|
||||
|
||||
NandChunkStatus status_1 = Success;
|
||||
NandChunkStatus status_2 = Success;
|
||||
char relsDir[] = "/rels";
|
||||
|
||||
/** 80052E00 */
|
||||
int initDylinkHeap(int maxRelId, const RelNamePtr *dynNameTable, int dynNameTableNum, EGG::Heap *parentHeap) {
|
||||
cCc_frmHeap = mHeap::createFrmHeap(maxRelId * 0x10 + dynNameTableNum * 0x48, parentHeap,
|
||||
"ダイナミックリンク制御用ヒープ(dDyl::cCc_frmHeap)", 0x20, 0);
|
||||
|
||||
@@ -38,7 +57,7 @@ extern "C" int fn_80052E00(int maxRelId, RelNamePtr *dynNameTable, int dynNameTa
|
||||
nDynamicNameTable = dynNameTableNum;
|
||||
|
||||
for (int i = 0; i < nDynamicNameTable; i++) {
|
||||
RelNamePtr *rel = &pDynamicNameTable[i];
|
||||
const RelNamePtr *rel = &pDynamicNameTable[i];
|
||||
if (rel->name != nullptr) {
|
||||
for (int j = 0; j < nDMC; j++) {
|
||||
DynamicModuleControl **dmc = &pDMC[j];
|
||||
@@ -59,12 +78,12 @@ extern "C" int fn_80052E00(int maxRelId, RelNamePtr *dynNameTable, int dynNameTa
|
||||
return 1;
|
||||
}
|
||||
|
||||
// isLoaded?
|
||||
extern "C" bool fn_80052FA0(u16 relId) {
|
||||
/** 80052FA0 */
|
||||
bool isLinked(u16 relId) {
|
||||
return pDMC[relId] != nullptr ? pDMC[relId]->isLinked() : true;
|
||||
}
|
||||
|
||||
bool dDyl::Unlink(u16 relId) {
|
||||
BOOL Unlink(u16 relId) {
|
||||
DynamicModuleControl *dmc = pDMC[relId];
|
||||
if (dmc != nullptr) {
|
||||
return dmc->unlink();
|
||||
@@ -73,7 +92,7 @@ bool dDyl::Unlink(u16 relId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
extern "C" int fn_80052FF0(u16 relId) {
|
||||
int tryLink(u16 relId) {
|
||||
if (!Initialized) {
|
||||
return 0;
|
||||
}
|
||||
@@ -81,8 +100,7 @@ extern "C" int fn_80052FF0(u16 relId) {
|
||||
DynamicModuleControl *dmc = pDMC[relId];
|
||||
if (dmc != nullptr) {
|
||||
if (dmc->load_async()) {
|
||||
// what is going on here?
|
||||
return (bool)dmc->link() + 2;
|
||||
return dmc->link() ? 1 : 2;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
@@ -91,4 +109,283 @@ extern "C" int fn_80052FF0(u16 relId) {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO prevent moves
|
||||
struct UnkNandStruct {
|
||||
/* 0x00 */ NandChunkStatus status;
|
||||
/* 0x04 */ OSThreadQueue queue;
|
||||
/* 0x0C */ DVDFileInfo dvdFileInfo;
|
||||
/* 0x48 */ NANDFileInfo *nandFileInfo;
|
||||
/* 0x4C */ NANDCommandBlock nandBlock;
|
||||
|
||||
UnkNandStruct() {
|
||||
status = status_2;
|
||||
OSInitThreadQueue(&queue);
|
||||
nandFileInfo = nullptr;
|
||||
updateStatus(status_1);
|
||||
nandFileInfo = nullptr;
|
||||
dvdFileInfo.block.userData = this;
|
||||
NANDSetUserData(&nandBlock, this);
|
||||
}
|
||||
|
||||
void waitForFinalization() {
|
||||
if (!isFinalized()) {
|
||||
BOOL enabled = OSDisableInterrupts();
|
||||
while (!isFinalized()) {
|
||||
OSSleepThread(&queue);
|
||||
}
|
||||
OSRestoreInterrupts(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
bool isFinalized() {
|
||||
return (status & FinalizedMask) != 0;
|
||||
}
|
||||
|
||||
void updateStatus(NandChunkStatus newStatus) {
|
||||
if (status != newStatus) {
|
||||
status = newStatus;
|
||||
OSWakeupThread(&queue);
|
||||
}
|
||||
}
|
||||
|
||||
void open(s32 entryNum, NANDFileInfo *fInfo) {
|
||||
DVDFastOpen(entryNum, &dvdFileInfo);
|
||||
nandFileInfo = fInfo;
|
||||
}
|
||||
|
||||
bool isError() {
|
||||
return (status & Error) != 0;
|
||||
}
|
||||
};
|
||||
|
||||
void nandCallback(s32 result, NANDCommandBlock *block) {
|
||||
UnkNandStruct *s = reinterpret_cast<UnkNandStruct *>(NANDGetUserData(block));
|
||||
NandChunkStatus status = result >= 0 ? Success : Error;
|
||||
s->updateStatus(status);
|
||||
}
|
||||
|
||||
void dvdCallback(s32 result, DVDFileInfo *dvdInfo) {
|
||||
NandChunkStatus status = Error;
|
||||
UnkNandStruct *s = reinterpret_cast<UnkNandStruct *>(dvdInfo->block.userData);
|
||||
u32 length = dvdInfo->block.length;
|
||||
if (result == length) {
|
||||
if (!NANDWriteAsync(s->nandFileInfo, dvdInfo->block.addr, length, nandCallback, &s->nandBlock)) {
|
||||
status = NANDPending;
|
||||
}
|
||||
}
|
||||
s->updateStatus(status);
|
||||
}
|
||||
|
||||
bool startDvdRead(UnkNandStruct *s, void *dst, s32 size, s32 offset) {
|
||||
s->waitForFinalization();
|
||||
|
||||
if ((s->status & 8) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
BOOL dvdResult = DVDReadAsyncPrio(&s->dvdFileInfo, dst, size, offset, dvdCallback, 2);
|
||||
NandChunkStatus status = dvdResult != 0 ? DVDPending : Error;
|
||||
s->updateStatus(status);
|
||||
return dvdResult;
|
||||
}
|
||||
|
||||
extern "C" void fn_802DEFE0(const char *fmt, ...);
|
||||
|
||||
extern "C" bool fn_80053240(char *relPath, char *tmpRelPath, EGG::Heap *heap) {
|
||||
DVDFileInfo dvdFileInfo;
|
||||
NANDFileInfo nandFileInfo;
|
||||
|
||||
s32 entryNum = DVDConvertPathToEntrynum(relPath);
|
||||
if (entryNum < 0 || !DVDFastOpen(entryNum, &dvdFileInfo)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
u32 sizeRead = 0;
|
||||
|
||||
u32 fileSize = ROUND_UP(dvdFileInfo.size, 0x20);
|
||||
NANDResult deleteResult = NANDDelete(tmpRelPath);
|
||||
if (deleteResult != NAND_RESULT_OK && deleteResult != NAND_RESULT_NOEXISTS) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (NANDCreate(tmpRelPath, NAND_PERM_RUSR | NAND_PERM_WUSR, 0) || NANDOpen(tmpRelPath, &nandFileInfo, 2)) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
fn_802DEFE0("BufferSize %u KB\n", 0x200);
|
||||
|
||||
void *buf = heap->alloc(0x80000, 0x20);
|
||||
if (buf == nullptr) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
// Weird part start (everything above this is regshuffles)
|
||||
|
||||
// TODO the initialization of this value is a bit
|
||||
// weird because it essentially computes the signed
|
||||
// division 0x80000 / 2
|
||||
// (which adds +1 to the dividend if the result is negative to
|
||||
// ensure rounding to 0 behavior)
|
||||
// and the optimizer fails to constant propagate these through
|
||||
// to realize that 0x80000 is actually always positive
|
||||
int totalBufSize = 0x80000;
|
||||
int chunkSize = 0x80000 / 2;
|
||||
|
||||
// TODO this initalization happens slightly differently
|
||||
UnkNandStruct nandStructs[2];
|
||||
|
||||
// Weird part end (most below this is regshuffles)
|
||||
|
||||
nandStructs[0].open(entryNum, &nandFileInfo);
|
||||
nandStructs[1].open(entryNum, &nandFileInfo);
|
||||
|
||||
// dispatch multiple requests to load parts of the profile REL in parallel
|
||||
int whichThread = 0;
|
||||
for (; sizeRead < fileSize; sizeRead += chunkSize) {
|
||||
if (chunkSize > fileSize - sizeRead) {
|
||||
chunkSize = fileSize - sizeRead;
|
||||
}
|
||||
// NB the whichThread * totalBufSize / 2 match relies on whichThread * totalBufSize being able to overflow
|
||||
if (!startDvdRead(&nandStructs[whichThread], ((u8 *)buf) + whichThread * totalBufSize / 2, chunkSize,
|
||||
/* offset */ sizeRead)) {
|
||||
break;
|
||||
}
|
||||
|
||||
whichThread ^= 1;
|
||||
}
|
||||
|
||||
nandStructs[0].waitForFinalization();
|
||||
nandStructs[1].waitForFinalization();
|
||||
|
||||
if (nandStructs[0].isError() || nandStructs[1].isError()) {
|
||||
sizeRead = 0;
|
||||
}
|
||||
|
||||
// Yes this condition is extremely weird but in the binary
|
||||
// this literally checks if a stack address isn't zero
|
||||
// There's also a bit of a weird addressing going on here
|
||||
if ((u32)&nandStructs[1]) {
|
||||
nandStructs[1].waitForFinalization();
|
||||
}
|
||||
nandStructs[0].waitForFinalization();
|
||||
|
||||
heap->free(buf);
|
||||
if (NANDClose(&nandFileInfo) != NAND_RESULT_OK) {
|
||||
sizeRead = 0;
|
||||
}
|
||||
|
||||
end:
|
||||
DVDClose(&dvdFileInfo);
|
||||
return sizeRead >= fileSize;
|
||||
|
||||
err:
|
||||
return false;
|
||||
}
|
||||
|
||||
u32 loadRelsArcCallback(void *arg) {
|
||||
EGG::Archive *arc = nullptr;
|
||||
EGG::Heap *heap = DynamicModuleControl::sDylinkHeap;
|
||||
|
||||
char rels[] = "/rels.arc";
|
||||
char tmpRels[] = "/tmp/rels.arc";
|
||||
|
||||
if (fn_80053240(rels, tmpRels, heap)) {
|
||||
arc = EGG::Archive::loadFST(tmpRels, heap, 0x20);
|
||||
}
|
||||
if (arc != nullptr) {
|
||||
DynamicModuleControl::sArchive = arc;
|
||||
}
|
||||
return (u32)arc;
|
||||
}
|
||||
|
||||
u32 dvdCallback(void *arg) {
|
||||
DynamicModuleControl::initialize(mHeap::g_dylinkHeap);
|
||||
DynamicModuleControl::sRelsDir = relsDir;
|
||||
DVDFileInfo info;
|
||||
|
||||
if (DVDOpen("/RVZELDANP.str", &info)) {
|
||||
if (info.size != 0) {
|
||||
u32 size = ROUND_UP(info.size, 0x20);
|
||||
void *destination = DynamicModuleControl::sDylinkHeap->alloc(size, 0x20);
|
||||
DVDReadPrio(&info, destination, size, 0, 2);
|
||||
OSSetStringTable(destination);
|
||||
}
|
||||
DVDClose(&info);
|
||||
}
|
||||
|
||||
BOOL result = g_DMC.link();
|
||||
do {
|
||||
} while (!result);
|
||||
Initialized = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
void initModule() {
|
||||
initDylinkHeap(0x2bf, DYNAMIC_NAME_TABLE, 0x27c, mHeap::g_dylinkHeap);
|
||||
DVD = mDvd_callback_c::createOrFail(dvdCallback, mHeap::g_dylinkHeap);
|
||||
}
|
||||
|
||||
void initRelsArc() {
|
||||
DVD = mDvd_callback_c::createOrFail(loadRelsArcCallback, nullptr);
|
||||
}
|
||||
|
||||
bool destroy() {
|
||||
if (DVD == nullptr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (DVD->mStatus != 0) {
|
||||
DVD->do_delete();
|
||||
DVD = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace dDyl
|
||||
|
||||
dDynamicModuleControl::~dDynamicModuleControl() {
|
||||
if (mPtr != nullptr) {
|
||||
do_unlink();
|
||||
}
|
||||
}
|
||||
|
||||
void dDynamicModuleControl::set(u16 *ptr, int count) {
|
||||
mPtr = ptr;
|
||||
mCount = count;
|
||||
}
|
||||
|
||||
BOOL dDynamicModuleControl::do_link() const {
|
||||
if (mPtr == nullptr) {
|
||||
return true;
|
||||
}
|
||||
bool result = true;
|
||||
u16 *rel = mPtr;
|
||||
for (int i = 0; i < mCount; i++) {
|
||||
bool linked = dDyl::isLinked(*rel);
|
||||
if (!linked && dDyl::tryLink(*rel) != 1) {
|
||||
result = false;
|
||||
goto end;
|
||||
}
|
||||
rel++;
|
||||
}
|
||||
end:
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOL dDynamicModuleControl::do_unlink() {
|
||||
u16 *rel = mPtr;
|
||||
if (rel == nullptr) {
|
||||
return true;
|
||||
}
|
||||
for (int i = 0; i < mCount; i++) {
|
||||
bool linked = dDyl::isLinked(*rel);
|
||||
if (linked && dDyl::Unlink(*rel) == 0) {
|
||||
return false;
|
||||
}
|
||||
rel++;
|
||||
}
|
||||
mPtr = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
+4
-4
@@ -330,7 +330,7 @@ mDvd_callback_c::~mDvd_callback_c() {}
|
||||
mDvd_callback_c::mDvd_callback_c(dvdReadCallback cb, void *cbData) {
|
||||
mCallback = cb;
|
||||
mCallbackData = cbData;
|
||||
mSuccess = false;
|
||||
mCallbackResult = 0;
|
||||
}
|
||||
|
||||
/* 802ef5d0 */
|
||||
@@ -343,7 +343,7 @@ mDvd_callback_c *mDvd_callback_c::create(dvdReadCallback cb, void *cbData) {
|
||||
}
|
||||
|
||||
/** 802ef650 */
|
||||
extern "C" mDvd_callback_c *fn_802EF650(dvdReadCallback cb, void *cbData) {
|
||||
mDvd_callback_c *mDvd_callback_c::createOrFail(dvdReadCallback cb, void *cbData) {
|
||||
mDvd_callback_c *cmd = mDvd_callback_c::create(cb, cbData);
|
||||
while (!cmd) {}
|
||||
return cmd;
|
||||
@@ -351,9 +351,9 @@ extern "C" mDvd_callback_c *fn_802EF650(dvdReadCallback cb, void *cbData) {
|
||||
|
||||
/** 802ef680 */
|
||||
u32 mDvd_callback_c::execute() {
|
||||
mSuccess = (mCallback)(mCallbackData);
|
||||
mCallbackResult = (mCallback)(mCallbackData);
|
||||
waitDone();
|
||||
return (bool)mSuccess;
|
||||
return (bool)mCallbackResult;
|
||||
}
|
||||
|
||||
/** 802ef6e0 */
|
||||
|
||||
+2
-2
@@ -11,7 +11,7 @@ EGG::Heap *mHeap::g_gameHeaps[4];
|
||||
EGG::Heap *mHeap::s_SavedCurrentHeap;
|
||||
EGG::Heap *mHeap::g_archiveHeap;
|
||||
EGG::Heap *mHeap::g_commandHeap;
|
||||
EGG::Heap *mHeap::g_dylinkHeap;
|
||||
EGG::ExpHeap *mHeap::g_dylinkHeap;
|
||||
EGG::AssertHeap *mHeap::g_assertHeap;
|
||||
const char *const mHeap::s_GameHeapNames[4] = {
|
||||
0,
|
||||
@@ -144,7 +144,7 @@ mHeap::~mHeap() {
|
||||
heap->becomeCurrentHeap();
|
||||
}
|
||||
|
||||
EGG::Heap *mHeap::createHeap(size_t size, EGG::Heap *block, const char *name) {
|
||||
EGG::ExpHeap *mHeap::createHeap(size_t size, EGG::Heap *block, const char *name) {
|
||||
EGG::ExpHeap *heap = EGG::ExpHeap::create(size, block, 4);
|
||||
if (heap != nullptr) {
|
||||
heap->setGroupID(0);
|
||||
|
||||
Reference in New Issue
Block a user