From d00c846ce05a6255d4127fad95f6846896254aad Mon Sep 17 00:00:00 2001 From: scudo <96631443+scudo005@users.noreply.github.com> Date: Wed, 15 Apr 2026 13:44:39 +0200 Subject: [PATCH 1/5] Redoing stuff from scratch because merging messed it all up --- include/n64dd.h | 38 ++--- src/code/code_n64dd_800AD410.c | 2 +- src/code/game.c | 2 +- src/n64dd/n64dd_801C8000.c | 32 ++-- src/n64dd/n64dd_801C8940.c | 34 ++-- src/n64dd/z_n64dd.c | 299 +++++++++++++++++---------------- 6 files changed, 206 insertions(+), 201 deletions(-) diff --git a/include/n64dd.h b/include/n64dd.h index e5b1b7aa311..56b08702f9f 100644 --- a/include/n64dd.h +++ b/include/n64dd.h @@ -68,7 +68,7 @@ typedef struct n64ddStruct_80121220 { s32 (*unk_78)(struct PlayState*, void*, void*); } n64ddStruct_80121220; // size = ? -typedef struct struct_801E0D18 { +typedef struct n64dd_driveCmdQueue { /* 0x00 */ LEOCmd unk_00; /* 0x1C */ OSMesgQueue unk_1C; /* 0x38 */ LEODiskID diskId; @@ -80,9 +80,9 @@ typedef struct struct_801E0D18 { /* 0x66 */ u8 unk_66; /* 0x68 */ s32 unk_68; /* 0x6C */ s32 unk_6C; -} struct_801E0D18; // size = 0x70 +} n64dd_driveCmdQueue; // size = 0x70 -typedef struct struct_801D9D50 { +typedef struct n64dd_drivePacketData { /* 0x00 */ u8 unk_00; // command enum /* 0x04 */ s32 unk_04; /* 0x08 */ u8 unk_08; @@ -95,7 +95,7 @@ typedef struct struct_801D9D50 { /* 0x24 */ OSId unk_24; /* 0x28 */ void* unk_28; /* 0x2C */ OSPri unk_2C; -} struct_801D9D50; // size = 0x30 +} n64dd_drivePacketData; // size = 0x30 void func_800AD410(void); void func_800AD488(void); @@ -105,8 +105,8 @@ n64ddStruct_800FEE70_pointers* func_800AD560(void); void func_800AD590(void); void func_800AD598(s32 arg0, s32 arg1, s32 arg2); -u32 func_801C6E80(void); -void func_801C6EA0(Gfx** gfxP); +u32 n64dd_isDrivePresent(void); +void n64dd_gfxHook(Gfx** gfxP); s32 func_801C70FC(void); void func_801C7268(void); s32 func_801C7658(void); @@ -115,21 +115,21 @@ void func_801C7C1C(void* dest, s32 offset, s32 size); void func_801C7E78(void); void n64dd_SetDiskVersion(s32 arg0); -s32 func_801C8000(struct_801D9D50* arg0); +s32 func_801C8000(n64dd_drivePacketData* arg0); s32 func_801C81C4(void); -void func_801C81EC(struct_801E0D18* arg0); -void func_801C8298(struct_801E0D18* arg0); -void func_801C82E0(struct_801E0D18* arg0); -void func_801C832C(struct_801E0D18* arg0); -void func_801C83A0(struct_801E0D18* arg0); -void func_801C8414(struct_801E0D18* arg0); -s32 func_801C873C(struct_801E0D18* arg0); +void func_801C81EC(n64dd_driveCmdQueue* arg0); +void func_801C8298(n64dd_driveCmdQueue* arg0); +void func_801C82E0(n64dd_driveCmdQueue* arg0); +void func_801C832C(n64dd_driveCmdQueue* arg0); +void func_801C83A0(n64dd_driveCmdQueue* arg0); +void func_801C8414(n64dd_driveCmdQueue* arg0); +s32 func_801C873C(n64dd_driveCmdQueue* arg0); void func_801C8AA8(void); -s32 func_801C91E0(struct_801E0D18*); -s32 func_801C9260(struct_801E0D18*); -s32 func_801C9334(struct_801E0D18*); -s32 func_801C93C4(struct_801E0D18*); +s32 func_801C91E0(n64dd_driveCmdQueue*); +s32 func_801C9260(n64dd_driveCmdQueue*); +s32 func_801C9334(n64dd_driveCmdQueue*); +s32 func_801C93C4(n64dd_driveCmdQueue*); void func_801C94F8(u8* arg0, u16 arg1); void func_801C9A10(u8* arg0, s32 arg1, u8* str); @@ -153,7 +153,7 @@ extern u8 D_80121212; extern vu8 D_80121213; extern vu8 D_80121214; -extern s32 (*D_801D2E54)(struct_801E0D18*); +extern s32 (*pCheckIfDiskIsValid)(n64dd_driveCmdQueue*); extern u8 gN64DDDiskReadTemporaryBuffer[]; diff --git a/src/code/code_n64dd_800AD410.c b/src/code/code_n64dd_800AD410.c index 1509b7223ba..a4518356b00 100644 --- a/src/code/code_n64dd_800AD410.c +++ b/src/code/code_n64dd_800AD410.c @@ -15,7 +15,7 @@ void func_800AD410(void) { _n64ddSegmentRomEnd - _n64ddSegmentRomStart, UNK_FILE, UNK_LINE); bzero(_n64ddSegmentBssStart, _n64ddSegmentBssEnd - _n64ddSegmentBssStart); D_80121210 = true; - D_80121211 = func_801C6E80(); + D_80121211 = n64dd_isDrivePresent(); if (D_80121211) {} } } diff --git a/src/code/game.c b/src/code/game.c index 1636633f97d..06fc5c5e3ce 100644 --- a/src/code/game.c +++ b/src/code/game.c @@ -276,7 +276,7 @@ void func_800C49F4(GraphicsContext* gfxCtx) { #if PLATFORM_N64 if (D_80121212 != 0) { - func_801C6EA0(&newDlist); + n64dd_gfxHook(&newDlist); } #endif diff --git a/src/n64dd/n64dd_801C8000.c b/src/n64dd/n64dd_801C8000.c index 2212fe43fb4..8ea9148a956 100644 --- a/src/n64dd/n64dd_801C8000.c +++ b/src/n64dd/n64dd_801C8000.c @@ -22,8 +22,8 @@ s32 D_801D2E60 = 0; s32 D_801D2E64 = 0; typedef struct struct_801D2E68 { - /* 0x0 */ void (*unk_0)(struct_801E0D18*); - /* 0x4 */ s32 (*unk_4)(struct_801E0D18*); + /* 0x0 */ void (*unk_0)(n64dd_driveCmdQueue*); + /* 0x4 */ s32 (*unk_4)(n64dd_driveCmdQueue*); } struct_801D2E68; // size = 0x8 struct_801D2E68 D_801D2E68[5] = { @@ -34,12 +34,12 @@ struct_801D2E68 D_801D2E68[5] = { s32 D_801D2E90 = 0; OSMesgQueue* B_801E0D10[2]; -struct_801E0D18 B_801E0D18; +n64dd_driveCmdQueue B_801E0D18; OSMesg B_801E0D88[1]; OSMesg B_801E0D90[8]; OSThread B_801E0DB0; -s32 func_801C8000(struct_801D9D50* arg0) { +s32 func_801C8000(n64dd_drivePacketData* arg0) { switch (arg0->unk_00) { case 0: if (func_801C8844() != 0) { @@ -107,7 +107,7 @@ s32 func_801C81D4(void) { return D_801D2E64 == 1; } -void func_801C81EC(struct_801E0D18* arg0) { +void func_801C81EC(n64dd_driveCmdQueue* arg0) { osCreateMesgQueue(&arg0->unk_1C, B_801E0D88, ARRAY_COUNT(B_801E0D88)); if (gCurrentRegion == 1) { @@ -121,7 +121,7 @@ void func_801C81EC(struct_801E0D18* arg0) { } } -void func_801C8298(struct_801E0D18* arg0) { +void func_801C8298(n64dd_driveCmdQueue* arg0) { LEOCmd sp1C; // TODO: passing a pointer as a logical block address? @@ -129,14 +129,14 @@ void func_801C8298(struct_801E0D18* arg0) { osRecvMesg(&arg0->unk_1C, (OSMesg*)&arg0->unk_68, OS_MESG_BLOCK); } -void func_801C82E0(struct_801E0D18* arg0) { +void func_801C82E0(n64dd_driveCmdQueue* arg0) { LEOCmd sp1C; LeoSpdlMotor(&sp1C, 4, &arg0->unk_1C); osRecvMesg(&arg0->unk_1C, (OSMesg*)&arg0->unk_68, OS_MESG_BLOCK); } -void func_801C832C(struct_801E0D18* arg0) { +void func_801C832C(n64dd_driveCmdQueue* arg0) { s32 sp34; s32 startLBA = arg0->unk_5C; @@ -148,7 +148,7 @@ void func_801C832C(struct_801E0D18* arg0) { } } -void func_801C83A0(struct_801E0D18* arg0) { +void func_801C83A0(n64dd_driveCmdQueue* arg0) { s32 sp34; s32 startLBA = arg0->unk_58; @@ -160,14 +160,14 @@ void func_801C83A0(struct_801E0D18* arg0) { } } -void func_801C8414(struct_801E0D18* arg0) { +void func_801C8414(n64dd_driveCmdQueue* arg0) { arg0->unk_68 = 9; } -void func_801C8424(struct_801E0D18* arg0) { +void func_801C8424(n64dd_driveCmdQueue* arg0) { struct_801D2E68* temp_v0; - s32 (*temp_s2)(struct_801E0D18*); - void (*aux)(struct_801E0D18*); + s32 (*temp_s2)(n64dd_driveCmdQueue*); + void (*aux)(n64dd_driveCmdQueue*); s32 temp_v0_2; arg0->unk_68 = -1; @@ -190,7 +190,7 @@ void func_801C8424(struct_801E0D18* arg0) { void func_801C84D4(void* arg) { while (true) { - struct_801E0D18* sp24; + n64dd_driveCmdQueue* sp24; osRecvMesg(B_801E0D10[0], (OSMesg*)&sp24, OS_MESG_BLOCK); func_801C8424(sp24); @@ -209,7 +209,7 @@ void func_801C8578(void* arg0, void* arg1, OSId id, void* sp, OSPri pri) { osStartThread(&B_801E0DB0); } -void func_801C85F0(struct_801E0D18* arg0, s32 arg1) { +void func_801C85F0(n64dd_driveCmdQueue* arg0, s32 arg1) { if (arg1 == 1) { func_801C8424(arg0); } else { @@ -250,7 +250,7 @@ void func_801C868C(void* arg0, void* arg1, void* arg2, u8 arg3) { func_801C85F0(&B_801E0D18, 0); } -s32 func_801C873C(struct_801E0D18* arg0) { +s32 func_801C873C(n64dd_driveCmdQueue* arg0) { u8 sp1F; arg0->unk_68 = LeoTestUnitReady(&sp1F); diff --git a/src/n64dd/n64dd_801C8940.c b/src/n64dd/n64dd_801C8940.c index 132222b689e..cf1f495fe5e 100644 --- a/src/n64dd/n64dd_801C8940.c +++ b/src/n64dd/n64dd_801C8940.c @@ -85,7 +85,7 @@ void func_801C8B90(void) { func_801C8A64(); } -s32 func_801C8BC0(struct_801E0D18* arg0) { +s32 func_801C8BC0(n64dd_driveCmdQueue* arg0) { if ((arg0->unk_68 < 0x25) || (arg0->unk_68 >= 0x29)) { if ((arg0->unk_68 != 0x1F) && (arg0->unk_68 != 0x20)) { func_801C8940(arg0->unk_68); @@ -96,7 +96,7 @@ s32 func_801C8BC0(struct_801E0D18* arg0) { return 4; } -s32 func_801C8C1C(struct_801E0D18* arg0) { +s32 func_801C8C1C(n64dd_driveCmdQueue* arg0) { s32 var_s0; do { @@ -125,7 +125,7 @@ s32 func_801C8C1C(struct_801E0D18* arg0) { return func_801C8BC0(arg0); } -s32 func_801C8CEC(struct_801E0D18* arg0) { +s32 func_801C8CEC(n64dd_driveCmdQueue* arg0) { switch (arg0->unk_68) { case 0x22: func_801C8B90(); @@ -153,7 +153,7 @@ s32 func_801C8CEC(struct_801E0D18* arg0) { } } -s32 func_801C8DC0(struct_801E0D18* arg0) { +s32 func_801C8DC0(n64dd_driveCmdQueue* arg0) { s32 temp_v0; while (true) { @@ -175,7 +175,7 @@ s32 func_801C8DC0(struct_801E0D18* arg0) { } } -s32 func_801C8E70(struct_801E0D18* arg0) { +s32 func_801C8E70(n64dd_driveCmdQueue* arg0) { s32 temp_a0; s32 temp_v0; @@ -202,14 +202,14 @@ s32 func_801C8E70(struct_801E0D18* arg0) { } } -s32 func_801C8F1C(struct_801E0D18* arg0) { - if (D_801D2E54 != NULL) { - return D_801D2E54(arg0); +s32 func_801C8F1C(n64dd_driveCmdQueue* arg0) { + if (pCheckIfDiskIsValid != NULL) { + return pCheckIfDiskIsValid(arg0); } return 1; } -s32 func_801C8F58(struct_801E0D18* arg0) { +s32 func_801C8F58(n64dd_driveCmdQueue* arg0) { s32 temp_v0; while (true) { @@ -233,7 +233,7 @@ s32 func_801C8F58(struct_801E0D18* arg0) { } } -s32 func_801C9000(struct_801E0D18* arg0) { +s32 func_801C9000(n64dd_driveCmdQueue* arg0) { s32 phi_s0; s32 temp_s4; @@ -269,18 +269,18 @@ s32 func_801C9000(struct_801E0D18* arg0) { } } -s32 func_801C90C4(struct_801E0D18* arg0) { +s32 func_801C90C4(n64dd_driveCmdQueue* arg0) { func_801C8940(arg0->unk_68); func_801C89B8(2); return func_801C9000(arg0); } -s32 func_801C90FC(struct_801E0D18* arg0) { +s32 func_801C90FC(n64dd_driveCmdQueue* arg0) { func_801C8940(arg0->unk_68); return func_801C9000(arg0); } -s32 func_801C912C(struct_801E0D18* arg0) { +s32 func_801C912C(n64dd_driveCmdQueue* arg0) { s32 i = 0; s32 temp_v0; @@ -305,7 +305,7 @@ s32 func_801C912C(struct_801E0D18* arg0) { return func_801C8BC0(arg0); } -s32 func_801C91E0(struct_801E0D18* arg0) { +s32 func_801C91E0(n64dd_driveCmdQueue* arg0) { if (arg0->unk_68 == 0x29) { return func_801C8BC0(arg0); } @@ -322,7 +322,7 @@ s32 func_801C91E0(struct_801E0D18* arg0) { return 0; } -s32 func_801C9260(struct_801E0D18* arg0) { +s32 func_801C9260(n64dd_driveCmdQueue* arg0) { s32 temp_v0; switch (arg0->unk_68) { @@ -361,7 +361,7 @@ s32 func_801C9260(struct_801E0D18* arg0) { return func_801C8BC0(arg0); } -s32 func_801C9334(struct_801E0D18* arg0) { +s32 func_801C9334(n64dd_driveCmdQueue* arg0) { while (true) { u32 temp_v0 = func_801C8DC0(arg0); @@ -381,7 +381,7 @@ s32 func_801C9334(struct_801E0D18* arg0) { } } -s32 func_801C93C4(struct_801E0D18* arg0) { +s32 func_801C93C4(n64dd_driveCmdQueue* arg0) { s32 temp_v0; s32 temp_v0_2; diff --git a/src/n64dd/z_n64dd.c b/src/n64dd/z_n64dd.c index c05bf3ad8b5..afba70c8171 100644 --- a/src/n64dd/z_n64dd.c +++ b/src/n64dd/z_n64dd.c @@ -18,49 +18,54 @@ #pragma increment_block_number "ntsc-1.0:64 ntsc-1.1:64 ntsc-1.2:64 pal-1.0:64 pal-1.1:64" -typedef struct struct_801D9C30 { - /* 0x000 */ s32 unk_000; // disk start - /* 0x004 */ s32 unk_004; // disk end - /* 0x008 */ uintptr_t unk_008; // ram start - /* 0x00C */ uintptr_t unk_00C; // ram end - /* 0x010 */ UNK_PTR unk_010; - /* 0x014 */ char unk_014[0x104]; -} struct_801D9C30; // size = 0x118 - -typedef struct struct_801D9B90 { - /* 0x00 */ OSMesg unk_00[30]; - /* 0x78 */ OSMesgQueue unk_78; - /* 0x90 */ IrqMgrClient unk_90; - /* 0x98 */ IrqMgr* unk_98; -} struct_801D9B90; // size = 0x9C - -s32 func_801C7A1C(struct_801E0D18* arg0); - -void* D_801D2E50 = &gN64DDDiskReadTemporaryBuffer; -s32 (*D_801D2E54)(struct_801E0D18*) = func_801C7A1C; - -struct_801D9B90 B_801D9B90; -struct_801D9C30 B_801D9C30; -struct_801D9C30* B_801D9D48; -struct_801D9D50 B_801D9D50; -OSMesgQueue B_801D9D80; -OSMesgQueue B_801D9D98; -OSMesg B_801D9DB0[1]; -OSMesg B_801D9DB4[1]; -volatile u8 B_801D9DB8; -volatile OSTime B_801D9DC0; -s32 B_801D9DC8; // 1 if disk gameName is correct, 2 otherwise -void* B_801D9DCC; -void* B_801D9DD0; -void* B_801D9DD4; -OSThread B_801D9DD8; -STACK(B_801D9F88, 0x1000); -StackEntry B_801DAF88; -STACK(B_801DAFA8, 0x1000); -StackEntry B_801DBFA8; +typedef struct n64dd_CopyToRAM { + /* 0x000 */ s32 diskStart; // disk start + /* 0x004 */ s32 diskEnd; // disk end + /* 0x008 */ uintptr_t ramStart; // ram start + /* 0x00C */ uintptr_t ramEnd; // ram end + /* 0x010 */ UNK_PTR unk_010; // s32? + /* 0x014 */ char padding[0x104]; +} n64dd_CopyToRAM; // size = 0x118 + +typedef struct n64dd_QueuedTransfersList { // This basically has a list of queued disk read commands + // ready to be passed to an OSMesgQueue + /* 0x00 */ OSMesg messages[30]; + /* 0x78 */ OSMesgQueue msgQueue; + /* 0x90 */ IrqMgrClient IRQMgrC; + /* 0x98 */ IrqMgr* pIRQMgr; +} n64dd_QueuedTransfersList; // size = 0x9C + +s32 n64dd_CheckIfDiskIsValid(n64dd_driveCmdQueue* arg0); + +void* pTmpReadBuf = &gN64DDDiskReadTemporaryBuffer; +s32 (*pCheckIfDiskIsValid)(n64dd_driveCmdQueue*) = n64dd_CheckIfDiskIsValid; + +n64dd_QueuedTransfersList queuedDDTransfers; +n64dd_CopyToRAM DDLoad0; +n64dd_CopyToRAM* pDDLoad0; +n64dd_drivePacketData drivePacketData; +OSMesgQueue msgQueue0; +OSMesgQueue msgQueue1; +OSMesg queuedMessages0[1]; +OSMesg queuedMessages1[1]; +volatile u8 isNewFBAvailable; // bool? +volatile OSTime currentTime; +s32 isGameDiskCorrect; // 1 if disk gameName is correct, 2 otherwise +void* pUnkTxt0; // pointers to some text +void* pUnkTxt1; +void* pUnkTxt2; +OSThread diskReadThread; +STACK(pStackTransfTrhead, 0x1000); // stack pointer of the transfer thread +StackEntry transfStackEntry; +STACK(pStackDDCommThread, 0x1000); // stack pointer of the communication thread (to send commands to the drive) +StackEntry commStackEntry; UNK_TYPE B_801DBFC4; // unused? -u32 func_801C6E80(void) { +/** + * Checks if the DD is present. + * @returns Disk drive status +*/ +u32 n64dd_isDrivePresent(void) { #if OOT_NTSC return LeoDriveExist(); #else @@ -68,7 +73,7 @@ u32 func_801C6E80(void) { #endif } -void func_801C6EA0(Gfx** gfxP) { +void n64dd_gfxHook(Gfx** gfxP) { // see game.c } void func_801C6EAC(void) { @@ -129,8 +134,8 @@ void func_801C7018(void) { } s32 func_801C7064(void) { - B_801D9D50.unk_00 = 5; - return (&func_801C8000)(&B_801D9D50); + drivePacketData.messages = 5; + return (&func_801C8000)(&drivePacketData); } s32 func_801C7098(void) { @@ -140,8 +145,8 @@ s32 func_801C7098(void) { if (0) {} #endif - B_801D9D50.unk_00 = 10; - phi_v1 = (&func_801C8000)(&B_801D9D50); + drivePacketData.messages = 10; + phi_v1 = (&func_801C8000)(&drivePacketData); if (phi_v1 < 0) { Freeze_CurrentThread(); } @@ -149,7 +154,7 @@ s32 func_801C7098(void) { } s32 func_801C70E4(void) { - return B_801D9DC8 == 1; + return isGameDiskCorrect == 1; } // Used by EnMag and FileChoose @@ -159,24 +164,24 @@ s32 func_801C70FC(void) { void func_801C711C(void* arg) { static void* B_801DBFC8; - struct_801D9B90* arg0 = (struct_801D9B90*)arg; + n64dd_QueuedTransfersList* arg0 = (n64dd_QueuedTransfersList*)arg; s16* sp58; s32 var_s0; void* temp_v0; sp58 = NULL; - arg0->unk_98 = &gIrqMgr; - osCreateMesgQueue(&arg0->unk_78, arg0->unk_00, ARRAY_COUNT(arg0->unk_00)); - IrqMgr_AddClient(arg0->unk_98, &arg0->unk_90, &arg0->unk_78); + arg0->pIRQMgr = &gIrqMgr; + osCreateMesgQueue(&arg0->msgQueue, arg0->messages, ARRAY_COUNT(arg0->messages)); + IrqMgr_AddClient(arg0->pIRQMgr, &arg0->IRQMgrC, &arg0->msgQueue); var_s0 = 0; do { - osRecvMesg(&arg0->unk_78, (OSMesg*)&sp58, OS_MESG_BLOCK); + osRecvMesg(&arg0->msgQueue, (OSMesg*)&sp58, OS_MESG_BLOCK); switch (*sp58) { case 1: temp_v0 = osViGetNextFramebuffer(); if (B_801DBFC8 != temp_v0) { B_801DBFC8 = temp_v0; - B_801D9DB8 = 1; + isNewFBAvailable = 1; } func_801C8AA8(); break; @@ -188,15 +193,15 @@ void func_801C711C(void* arg) { break; } } while (var_s0 == 0); - IrqMgr_RemoveClient(arg0->unk_98, &arg0->unk_90); + IrqMgr_RemoveClient(arg0->pIRQMgr, &arg0->IRQMgrC); } #if OOT_VERSION >= NTSC_1_1 void func_801C7B28_ne2(void) { s32 temp; - if (B_801D9DC0 != 0) { - temp = (osGetTime() - B_801D9DC0) * 64 / 3000; + if (currentTime != 0) { + temp = (osGetTime() - currentTime) * 64 / 3000; if (1000000 - temp > 0) { Sleep_Usec(1000000 - temp); } @@ -213,21 +218,21 @@ void func_801C7268(void) { if (sp20 == 0) { func_801C6F30(); } - B_801D9DB8 = 1; - B_801D9DC0 = 0; + isNewFBAvailable = 1; + currentTime = 0; if (func_801C7064() == 1) { func_801C7098(); - } else if (B_801D9DC8 != 0) { - B_801D9DC8 = 0; + } else if (isGameDiskCorrect != 0) { + isGameDiskCorrect = 0; } #if OOT_VERSION < NTSC_1_1 - if (B_801D9DC0 != 0) { - sp1C = (osGetTime() - B_801D9DC0) * 64 / 3000; + if (currentTime != 0) { + sp1C = (osGetTime() - currentTime) * 64 / 3000; // Remnants from debug statements? - (void)(osGetTime() - B_801D9DC0); - (void)((osGetTime() - B_801D9DC0) * 64 / 3000); - (void)((osGetTime() - B_801D9DC0) * 64 / 3000); + (void)(osGetTime() - currentTime); + (void)((osGetTime() - currentTime) * 64 / 3000); + (void)((osGetTime() - currentTime) * 64 / 3000); if (1000000 - sp1C > 0) { Sleep_Usec(1000000 - sp1C); @@ -235,7 +240,7 @@ void func_801C7268(void) { } #else if (D_801D2EA8 == 1 || B_801E0F60 == 1 || B_801E0F64 == 1) { - B_801D9DC0 = osGetTime(); + currentTime = osGetTime(); } func_801C7B28_ne2(); #endif @@ -259,10 +264,10 @@ void func_801C746C(void* arg0, void* arg1, void* arg2) { if (arg0 != NULL || arg1 != NULL || arg2 != NULL) { sp2C = (u8*)osViGetNextFramebuffer() + 0x20000000; if ((u32)sp2C & 0xFFFFFF) { - if (B_801D9DB8 != 0) { - B_801D9DB8 = 0; + if (isNewFBAvailable != 0) { + isNewFBAvailable = 0; func_801C7438(sp2C); - B_801D9DC0 = osGetTime(); + currentTime = osGetTime(); } if (arg0 != NULL) { func_801CA1F0(arg0, 96, 32, 192, 16, 11, sp2C, SCREEN_WIDTH); @@ -287,23 +292,23 @@ void func_801C75BC(void* arg0, void* arg1, void* arg2) { return; } - if (B_801D9DB8) {} + if (isNewFBAvailable) {} if (arg0 != 0) { - B_801D9DCC = arg0; + pUnkTxt0 = arg0; } if (arg1 != 0) { - B_801D9DD0 = arg1; + pUnkTxt1 = arg1; } if (arg2 != 0) { - B_801D9DD4 = arg2; + pUnkTxt2 = arg2; } func_801C746C(arg0, arg1, arg2); } void func_801C761C(void) { Sleep_Msec(100); - func_801C746C(B_801D9DCC, B_801D9DD0, B_801D9DD4); + func_801C746C(pUnkTxt0, pUnkTxt1, pUnkTxt2); } s32 func_801C7658(void) { @@ -312,41 +317,41 @@ s32 func_801C7658(void) { } #if OOT_VERSION < PAL_1_0 - StackCheck_Init(&B_801DAF88, B_801D9F88, STACK_TOP(B_801D9F88), 0, 0x100, "ddmsg"); - osCreateThread(&B_801D9DD8, THREAD_ID_DDMSG, &func_801C711C, &B_801D9B90, STACK_TOP(B_801D9F88), THREAD_PRI_DDMSG); - osStartThread(&B_801D9DD8); + StackCheck_Init(&transfStackEntry, pStackTransfTrhead, STACK_TOP(pStackTransfTrhead), 0, 0x100, "ddmsg"); + osCreateThread(&diskReadThread, THREAD_ID_DDMSG, &func_801C711C, &queuedDDTransfers, STACK_TOP(pStackTransfTrhead), THREAD_PRI_DDMSG); + osStartThread(&diskReadThread); #endif - osCreateMesgQueue(&B_801D9D80, B_801D9DB0, ARRAY_COUNT(B_801D9DB0)); - osCreateMesgQueue(&B_801D9D98, B_801D9DB4, ARRAY_COUNT(B_801D9DB4)); + osCreateMesgQueue(&msgQueue0, queuedMessages0, ARRAY_COUNT(queuedMessages0)); + osCreateMesgQueue(&msgQueue1, queuedMessages1, ARRAY_COUNT(queuedMessages1)); - StackCheck_Init(&B_801DBFA8, B_801DAFA8, STACK_TOP(B_801DAFA8), 0, 0x100, "n64dd"); + StackCheck_Init(&commStackEntry, pStackDDCommThread, STACK_TOP(pStackDDCommThread), 0, 0x100, "n64dd"); - B_801D9D50.unk_1C = &B_801D9D80; - B_801D9D50.unk_20 = &B_801D9D98; - B_801D9D50.unk_24 = THREAD_ID_N64DD; - B_801D9D50.unk_28 = STACK_TOP(B_801DAFA8); - B_801D9D50.unk_2C = THREAD_PRI_N64DD; - B_801D9D50.unk_00 = 1; + drivePacketData.unk_1C = &msgQueue0; + drivePacketData.unk_20 = &msgQueue1; + drivePacketData.unk_24 = THREAD_ID_N64DD; + drivePacketData.unk_28 = STACK_TOP(pStackDDCommThread); + drivePacketData.unk_2C = THREAD_PRI_N64DD; + drivePacketData.messages = 1; - (&func_801C8000)(&B_801D9D50); + (&func_801C8000)(&drivePacketData); D_80121213 = 1; func_801C6FD8(); - B_801D9D50.unk_00 = 2; - B_801D9D50.unk_10 = 6; - B_801D9D50.unk_14 = &DmaMgr_DmaFromDriveRom; - B_801D9D50.unk_0C = &func_801C75BC; - (&func_801C8000)(&B_801D9D50); + drivePacketData.messages = 2; + drivePacketData.unk_10 = 6; + drivePacketData.unk_14 = &DmaMgr_DmaFromDriveRom; + drivePacketData.unk_0C = &func_801C75BC; + (&func_801C8000)(&drivePacketData); - B_801D9D50.unk_00 = 13; - (&func_801C8000)(&B_801D9D50); + drivePacketData.messages = 13; + (&func_801C8000)(&drivePacketData); #if OOT_VERSION >= PAL_1_0 - StackCheck_Init(&B_801DAF88, B_801D9F88, STACK_TOP(B_801D9F88), 0, 0x100, "ddmsg"); - osCreateThread(&B_801D9DD8, THREAD_ID_DDMSG, &func_801C711C, &B_801D9B90, STACK_TOP(B_801D9F88), THREAD_PRI_DDMSG); - osStartThread(&B_801D9DD8); + StackCheck_Init(&transfStackEntry, pStackTransfTrhead, STACK_TOP(pStackTransfTrhead), 0, 0x100, "ddmsg"); + osCreateThread(&diskReadThread, THREAD_ID_DDMSG, &func_801C711C, &queuedDDTransfers, STACK_TOP(pStackTransfTrhead), THREAD_PRI_DDMSG); + osStartThread(&diskReadThread); #endif return 0; @@ -354,12 +359,12 @@ s32 func_801C7658(void) { s32 func_801C7818(void) { #if OOT_VERSION >= NTSC_1_1 - B_801D9DB8 = 1; - B_801D9DC0 = 0; + isNewFBAvailable = 1; + currentTime = 0; #endif - B_801D9D50.unk_00 = 12; - (&func_801C8000)(&B_801D9D50); + drivePacketData.messages = 12; + (&func_801C8000)(&drivePacketData); while (func_801C81C4() == 0) { // the number 16666 sounds like it could be 1 frame (at 60 frames per second) @@ -368,7 +373,7 @@ s32 func_801C7818(void) { #if OOT_VERSION >= NTSC_1_1 if (D_801D2EA8 == 1 || B_801E0F60 == 1 || B_801E0F64 == 1) { - B_801D9DC0 = osGetTime(); + currentTime = osGetTime(); } func_801C7B28_ne2(); #endif @@ -394,40 +399,40 @@ s32 func_801C78B8(void) { } s32 func_801C78F0(void) { - B_801D9D50.unk_00 = 0; - return (&func_801C8000)(&B_801D9D50); + drivePacketData.messages = 0; + return (&func_801C8000)(&drivePacketData); } void func_801C7920(s32 arg0, void* arg1, s32 arg2) { - B_801D9D50.unk_18 = arg1; - B_801D9D50.unk_1C = (void*)arg0; - B_801D9D50.unk_20 = (void*)arg2; - B_801D9D50.unk_00 = 3; - (&func_801C8000)(&B_801D9D50); + drivePacketData.unk_18 = arg1; + drivePacketData.unk_1C = (void*)arg0; + drivePacketData.unk_20 = (void*)arg2; + drivePacketData.messages = 3; + (&func_801C8000)(&drivePacketData); osGetTime(); - B_801D9D50.unk_00 = 6; - while ((&func_801C8000)(&B_801D9D50) != 0) { + drivePacketData.messages = 6; + while ((&func_801C8000)(&drivePacketData) != 0) { Sleep_Usec(16666); // 100000 / 6 } - B_801D9D50.unk_00 = 7; - if ((&func_801C8000)(&B_801D9D50) != 0) { + drivePacketData.messages = 7; + if ((&func_801C8000)(&drivePacketData) != 0) { Freeze_CurrentThread(); } } void func_801C79CC(void* arg0, s32 arg1, s32 arg2) { - B_801D9D50.unk_18 = arg0; - B_801D9D50.unk_1C = (void*)arg1; - B_801D9D50.unk_20 = (void*)arg2; - B_801D9D50.unk_00 = 4; - (&func_801C8000)(&B_801D9D50); + drivePacketData.unk_18 = arg0; + drivePacketData.unk_1C = (void*)arg1; + drivePacketData.unk_20 = (void*)arg2; + drivePacketData.messages = 4; + (&func_801C8000)(&drivePacketData); } void func_801C7A10(LEODiskID* arg0) { } -// Checks diskId, sets B_801D9DC8 and returns true if diskId is correct -s32 func_801C7A1C(struct_801E0D18* arg0) { +// Checks diskId, sets isGameDiskCorrect and returns true if diskId is correct +s32 n64dd_CheckIfDiskIsValid(n64dd_driveCmdQueue* arg0) { static LEODiskID B_801DBFD0; static s32 B_801DBFF0; // bool @@ -441,16 +446,16 @@ s32 func_801C7A1C(struct_801E0D18* arg0) { { B_801DBFD0 = arg0->diskId; B_801DBFF0 = true; - B_801D9DC8 = 1; + isGameDiskCorrect = 1; } else { - B_801D9DC8 = 2; + isGameDiskCorrect = 2; } } else if (bcmp(&B_801DBFD0, &arg0->diskId, sizeof(LEODiskID)) == 0) { - B_801D9DC8 = 1; + isGameDiskCorrect = 1; } else { - B_801D9DC8 = 2; + isGameDiskCorrect = 2; } - return B_801D9DC8 == 1; + return isGameDiskCorrect == 1; } // Translates byte position to LBA and byte offset @@ -501,11 +506,11 @@ void func_801C7C1C(void* dest, s32 offset, s32 size) { func_801C6FD8(); func_801C6F30(); - B_801D9DB8 = 1; - B_801D9DC0 = 0; + isNewFBAvailable = 1; + currentTime = 0; func_801C7B48(offset, &sp5C, &sp54); func_801C7B48(offset + size, &sp58, &sp50); - sp4C = D_801D2E50; + sp4C = pTmpReadBuf; if (sp5C == sp58) { func_801C7920(sp5C, sp4C, func_801C7BEC(sp5C)); bcopy((u8*)sp4C + sp54, dest, size); @@ -525,8 +530,8 @@ void func_801C7C1C(void* dest, s32 offset, s32 size) { } } #if OOT_VERSION < NTSC_1_1 - if (B_801D9DC0 != 0) { - temp_v1_2 = (osGetTime() - B_801D9DC0) * 64 / 3000; + if (currentTime != 0) { + temp_v1_2 = (osGetTime() - currentTime) * 64 / 3000; if (1000000 - temp_v1_2 > 0) { Sleep_Usec(1000000 - temp_v1_2); } @@ -547,45 +552,45 @@ s32 func_801C7E80(void) { s32 sp1C; uintptr_t sp18; - if (B_801D9D48 != NULL) { + if (pDDLoad0 != NULL) { return -1; } - B_801D9D48 = &B_801D9C30; - func_801C7C1C(B_801D9D48, 0x1060, 0x118); - sp24 = B_801D9D48->unk_004 - B_801D9D48->unk_000; - sp20 = B_801D9D48->unk_00C - B_801D9D48->unk_008; - sp18 = B_801D9D48->unk_008 + sp24; - func_801C7C1C((void*)B_801D9D48->unk_008, B_801D9D48->unk_000, sp24); + pDDLoad0 = &DDLoad0; + func_801C7C1C(pDDLoad0, 0x1060, 0x118); + sp24 = pDDLoad0->diskEnd - pDDLoad0->diskStart; + sp20 = pDDLoad0->ramEnd - pDDLoad0->ramStart; + sp18 = pDDLoad0->ramStart + sp24; + func_801C7C1C((void*)pDDLoad0->ramStart, pDDLoad0->diskStart, sp24); bzero((void*)sp18, sp20 - sp24); - func_800AD4C0(B_801D9D48->unk_010); + func_800AD4C0(pDDLoad0->unk_010); return 0; } s32 func_801C7F24(void) { uintptr_t temp_a0; - struct_801D9C30* temp_v0; + n64dd_CopyToRAM* temp_v0; - if (B_801D9D48 == 0) { + if (pDDLoad0 == 0) { return -1; } // Function from code func_800AD51C(); - temp_v0 = B_801D9D48; - temp_a0 = temp_v0->unk_008; - bzero((void*)temp_a0, temp_v0->unk_00C - temp_a0); - bzero(B_801D9D48, sizeof(struct_801D9C30)); - B_801D9D48 = 0; + temp_v0 = pDDLoad0; + temp_a0 = temp_v0->ramStart; + bzero((void*)temp_a0, temp_v0->ramEnd - temp_a0); + bzero(pDDLoad0, sizeof(n64dd_CopyToRAM)); + pDDLoad0 = 0; return 0; } void n64dd_SetDiskVersion(s32 arg0) { if (arg0 != 0) { - if (B_801D9D48 == 0) { + if (pDDLoad0 == 0) { func_801C7E80(); } - } else if (B_801D9D48 != 0) { + } else if (pDDLoad0 != 0) { func_801C7F24(); } } From 9c315eb2a30b75fa3782c7e02de17c996b3c330a Mon Sep 17 00:00:00 2001 From: scudo <96631443+scudo005@users.noreply.github.com> Date: Wed, 15 Apr 2026 14:37:29 +0200 Subject: [PATCH 2/5] Some more work --- include/n64dd.h | 28 +- src/boot/z_std_dma.c | 4 +- src/code/code_n64dd_800AD410.c | 6 +- src/code/game.c | 6 +- src/n64dd/n64dd_801C8000.c | 108 ++++--- src/n64dd/z_n64dd.c | 297 ++++++++++-------- src/overlays/actors/ovl_En_Mag/z_en_mag.c | 2 +- .../ovl_file_choose/z_file_choose.c | 8 +- src/overlays/gamestates/ovl_select/z_select.c | 4 +- src/overlays/gamestates/ovl_title/z_title.c | 4 +- 10 files changed, 253 insertions(+), 214 deletions(-) diff --git a/include/n64dd.h b/include/n64dd.h index 56b08702f9f..af04e6bcc66 100644 --- a/include/n64dd.h +++ b/include/n64dd.h @@ -83,18 +83,18 @@ typedef struct n64dd_driveCmdQueue { } n64dd_driveCmdQueue; // size = 0x70 typedef struct n64dd_drivePacketData { - /* 0x00 */ u8 unk_00; // command enum + /* 0x00 */ u8 cmdType; // command enum /* 0x04 */ s32 unk_04; /* 0x08 */ u8 unk_08; - /* 0x0C */ void (*unk_0C)(void*, void*, void*); + /* 0x0C */ void (*pPrintText)(void*, void*, void*); /* 0x10 */ s32 unk_10; - /* 0x14 */ void (*unk_14)(void*, uintptr_t, size_t); - /* 0x18 */ void* unk_18; - /* 0x1C */ void* unk_1C; // either OSMesgQueue* (command 0) or integer LBA (commands 2 and 3) - /* 0x20 */ void* unk_20; // either OSMesgQueue* (command 0) or integer byte size (commands 3 and 4) - /* 0x24 */ OSId unk_24; - /* 0x28 */ void* unk_28; - /* 0x2C */ OSPri unk_2C; + /* 0x14 */ void (*pDmaMgr)(void*, uintptr_t, size_t); + /* 0x18 */ void* pReadBuf; + /* 0x1C */ void* pCmdParam1; // either OSMesgQueue* (command 0) or integer LBA (commands 2 and 3) + /* 0x20 */ void* pCmdParam2; // either OSMesgQueue* (command 0) or integer byte size (commands 3 and 4) + /* 0x24 */ OSId threadId; + /* 0x28 */ void* pStackCommThread; + /* 0x2C */ OSPri threadPriority; } n64dd_drivePacketData; // size = 0x30 void func_800AD410(void); @@ -107,15 +107,15 @@ void func_800AD598(s32 arg0, s32 arg1, s32 arg2); u32 n64dd_isDrivePresent(void); void n64dd_gfxHook(Gfx** gfxP); -s32 func_801C70FC(void); +s32 n64dd_isDiskCorrect(void); void func_801C7268(void); -s32 func_801C7658(void); +s32 n64dd_setupTransferThread(void); s32 func_801C7818(void); void func_801C7C1C(void* dest, s32 offset, s32 size); void func_801C7E78(void); void n64dd_SetDiskVersion(s32 arg0); -s32 func_801C8000(n64dd_drivePacketData* arg0); +s32 n64dd_parsePacketData(n64dd_drivePacketData* arg0); s32 func_801C81C4(void); void func_801C81EC(n64dd_driveCmdQueue* arg0); void func_801C8298(n64dd_driveCmdQueue* arg0); @@ -149,9 +149,9 @@ extern n64ddStruct_80121220* B_80121220; extern u8 D_80121210; extern u8 D_80121211; -extern u8 D_80121212; +extern u8 n64dd_isDiskContentRunning; extern vu8 D_80121213; -extern vu8 D_80121214; +extern vu8 isSoundStopped; extern s32 (*pCheckIfDiskIsValid)(n64dd_driveCmdQueue*); diff --git a/src/boot/z_std_dma.c b/src/boot/z_std_dma.c index 226465a3f6e..5b4ad5a4c7e 100644 --- a/src/boot/z_std_dma.c +++ b/src/boot/z_std_dma.c @@ -221,8 +221,8 @@ s32 DmaMgr_AudioDmaHandler(OSPiHandle* pihandle, OSIoMesg* mb, s32 direction) { ASSERT(mb != NULL, "mb != NULL", "../z_std_dma.c", 532); #if PLATFORM_N64 - if (D_80121212) { - while (D_80121214) { + if (n64dd_isDiskContentRunning) { + while (isSoundStopped) { Sleep_Msec(1000); } } diff --git a/src/code/code_n64dd_800AD410.c b/src/code/code_n64dd_800AD410.c index a4518356b00..c97c17df993 100644 --- a/src/code/code_n64dd_800AD410.c +++ b/src/code/code_n64dd_800AD410.c @@ -5,9 +5,9 @@ u8 D_80121210; u8 D_80121211; -u8 D_80121212; +u8 n64dd_isDiskContentRunning; vu8 D_80121213; -vu8 D_80121214; +vu8 isSoundStopped; void func_800AD410(void) { if (!D_80121210) { @@ -21,7 +21,7 @@ void func_800AD410(void) { } void func_800AD488(void) { - if (D_80121210 && (D_80121212 == 0)) { + if (D_80121210 && (n64dd_isDiskContentRunning == 0)) { D_80121210 = false; } } diff --git a/src/code/game.c b/src/code/game.c index 06fc5c5e3ce..adb4ecd72ac 100644 --- a/src/code/game.c +++ b/src/code/game.c @@ -153,7 +153,7 @@ void func_800C4344(GameState* gameState) { #endif #if PLATFORM_N64 - if (D_80121212 != 0) { + if (n64dd_isDiskContentRunning != 0) { func_801C7E78(); } #endif @@ -275,7 +275,7 @@ void func_800C49F4(GraphicsContext* gfxCtx) { gSPDisplayList(OVERLAY_DISP++, newDlist); #if PLATFORM_N64 - if (D_80121212 != 0) { + if (n64dd_isDiskContentRunning != 0) { n64dd_gfxHook(&newDlist); } #endif @@ -301,7 +301,7 @@ void GameState_Update(GameState* gameState) { gameState->main(gameState); #if PLATFORM_N64 - if (D_80121212 != 0) { + if (n64dd_isDiskContentRunning != 0) { func_801C7E78(); } if ((B_80121220 != NULL) && (B_80121220->unk_74 != NULL)) { diff --git a/src/n64dd/n64dd_801C8000.c b/src/n64dd/n64dd_801C8000.c index 8ea9148a956..d7d21635bfd 100644 --- a/src/n64dd/n64dd_801C8000.c +++ b/src/n64dd/n64dd_801C8000.c @@ -39,8 +39,13 @@ OSMesg B_801E0D88[1]; OSMesg B_801E0D90[8]; OSThread B_801E0DB0; -s32 func_801C8000(n64dd_drivePacketData* arg0) { - switch (arg0->unk_00) { +/** + * Parses a drive packet and acts accordingly to its command ID. + * @param ddPacket A drive packet. + * @returns It depends on the command sent. Default return value is 0 (for unknown command). + */ +s32 n64dd_parsePacketData(n64dd_drivePacketData* ddPacket) { + switch (ddPacket->cmdType) { case 0: if (func_801C8844() != 0) { return 1; @@ -48,33 +53,34 @@ s32 func_801C8000(n64dd_drivePacketData* arg0) { func_801C8554(); break; case 1: - func_801C8578(arg0->unk_1C, arg0->unk_20, arg0->unk_24, arg0->unk_28, arg0->unk_2C); + func_801C8578(ddPacket->pCmdParam1, ddPacket->pCmdParam2, ddPacket->threadId, ddPacket->pStackCommThread, + ddPacket->threadPriority); break; case 2: - func_801C8638(arg0->unk_0C, arg0->unk_10, arg0->unk_14); + func_801C8638(ddPacket->pPrintText, ddPacket->unk_10, ddPacket->pDmaMgr); break; case 3: if (func_801C8844() != 0) { return 1; } - func_801C868C(arg0->unk_18, arg0->unk_1C, arg0->unk_20, 1); + func_801C868C(ddPacket->pReadBuf, ddPacket->pCmdParam1, ddPacket->pCmdParam2, 1); break; case 4: if (func_801C8844() != 0) { return 1; } - func_801C868C(arg0->unk_18, arg0->unk_1C, arg0->unk_20, 2); + func_801C868C(ddPacket->pReadBuf, ddPacket->pCmdParam1, ddPacket->pCmdParam2, 2); break; case 5: - arg0->unk_08 = func_801C8770(); - return arg0->unk_08; + ddPacket->unk_08 = func_801C8770(); + return ddPacket->unk_08; case 7: return func_801C87FC(); case 6: return func_801C8844(); case 8: - arg0->unk_04 = func_801C87C0(); - return arg0->unk_04; + ddPacket->unk_04 = func_801C87C0(); + return ddPacket->unk_04; case 9: return func_801C885C(); case 10: @@ -107,84 +113,86 @@ s32 func_801C81D4(void) { return D_801D2E64 == 1; } -void func_801C81EC(n64dd_driveCmdQueue* arg0) { - osCreateMesgQueue(&arg0->unk_1C, B_801E0D88, ARRAY_COUNT(B_801E0D88)); +void func_801C81EC(n64dd_driveCmdQueue* ddPacket) { + osCreateMesgQueue(&ddPacket->pCmdParam1, B_801E0D88, ARRAY_COUNT(B_801E0D88)); if (gCurrentRegion == 1) { - arg0->unk_68 = LeoCJCreateLeoManager(LEO_PRIORITY_WRK, LEO_PRIORITY_INT, B_801E0D90, ARRAY_COUNT(B_801E0D90)); + ddPacket->unk_68 = + LeoCJCreateLeoManager(LEO_PRIORITY_WRK, LEO_PRIORITY_INT, B_801E0D90, ARRAY_COUNT(B_801E0D90)); } else { - arg0->unk_68 = LeoCACreateLeoManager(LEO_PRIORITY_WRK, LEO_PRIORITY_INT, B_801E0D90, ARRAY_COUNT(B_801E0D90)); + ddPacket->unk_68 = + LeoCACreateLeoManager(LEO_PRIORITY_WRK, LEO_PRIORITY_INT, B_801E0D90, ARRAY_COUNT(B_801E0D90)); } - if ((arg0->unk_68 == LEO_ERROR_DEVICE_COMMUNICATION_FAILURE) || (arg0->unk_68 == LEO_ERROR_GOOD)) { + if ((ddPacket->unk_68 == LEO_ERROR_DEVICE_COMMUNICATION_FAILURE) || (ddPacket->unk_68 == LEO_ERROR_GOOD)) { D_801D2E64 = 1; } } -void func_801C8298(n64dd_driveCmdQueue* arg0) { +void func_801C8298(n64dd_driveCmdQueue* ddPacket) { LEOCmd sp1C; // TODO: passing a pointer as a logical block address? - LeoSeek(&sp1C, (u32)&arg0->diskId, &arg0->unk_1C); - osRecvMesg(&arg0->unk_1C, (OSMesg*)&arg0->unk_68, OS_MESG_BLOCK); + LeoSeek(&sp1C, (u32)&ddPacket->diskId, &ddPacket->pCmdParam1); + osRecvMesg(&ddPacket->pCmdParam1, (OSMesg*)&ddPacket->unk_68, OS_MESG_BLOCK); } -void func_801C82E0(n64dd_driveCmdQueue* arg0) { +void func_801C82E0(n64dd_driveCmdQueue* ddPacket) { LEOCmd sp1C; - LeoSpdlMotor(&sp1C, 4, &arg0->unk_1C); - osRecvMesg(&arg0->unk_1C, (OSMesg*)&arg0->unk_68, OS_MESG_BLOCK); + LeoSpdlMotor(&sp1C, 4, &ddPacket->pCmdParam1); + osRecvMesg(&ddPacket->pCmdParam1, (OSMesg*)&ddPacket->unk_68, OS_MESG_BLOCK); } -void func_801C832C(n64dd_driveCmdQueue* arg0) { +void func_801C832C(n64dd_driveCmdQueue* ddPacket) { s32 sp34; - s32 startLBA = arg0->unk_5C; + s32 startLBA = ddPacket->unk_5C; - if (LeoByteToLBA(startLBA, arg0->unk_60, &sp34) == LEO_ERROR_GOOD) { - OSMesgQueue* sp28 = &arg0->unk_1C; + if (LeoByteToLBA(startLBA, ddPacket->unk_60, &sp34) == LEO_ERROR_GOOD) { + OSMesgQueue* sp28 = &ddPacket->pCmdParam1; - LeoReadWrite(&arg0->unk_00, OS_READ, startLBA, (void*)arg0->unk_58, sp34, sp28); - osRecvMesg(sp28, (OSMesg*)&arg0->unk_68, OS_MESG_BLOCK); + LeoReadWrite(&ddPacket->cmdType, OS_READ, startLBA, (void*)ddPacket->unk_58, sp34, sp28); + osRecvMesg(sp28, (OSMesg*)&ddPacket->unk_68, OS_MESG_BLOCK); } } -void func_801C83A0(n64dd_driveCmdQueue* arg0) { +void func_801C83A0(n64dd_driveCmdQueue* ddPacket) { s32 sp34; - s32 startLBA = arg0->unk_58; + s32 startLBA = ddPacket->unk_58; - if (LeoByteToLBA(startLBA, arg0->unk_60, &sp34) == LEO_ERROR_GOOD) { - OSMesgQueue* sp28 = &arg0->unk_1C; + if (LeoByteToLBA(startLBA, ddPacket->unk_60, &sp34) == LEO_ERROR_GOOD) { + OSMesgQueue* sp28 = &ddPacket->pCmdParam1; - LeoReadWrite(&arg0->unk_00, OS_WRITE, startLBA, (void*)arg0->unk_5C, sp34, sp28); - osRecvMesg(sp28, (OSMesg*)&arg0->unk_68, OS_MESG_BLOCK); + LeoReadWrite(&ddPacket->cmdType, OS_WRITE, startLBA, (void*)ddPacket->unk_5C, sp34, sp28); + osRecvMesg(sp28, (OSMesg*)&ddPacket->unk_68, OS_MESG_BLOCK); } } -void func_801C8414(n64dd_driveCmdQueue* arg0) { - arg0->unk_68 = 9; +void func_801C8414(n64dd_driveCmdQueue* ddPacket) { + ddPacket->unk_68 = 9; } -void func_801C8424(n64dd_driveCmdQueue* arg0) { +void func_801C8424(n64dd_driveCmdQueue* ddPacket) { struct_801D2E68* temp_v0; s32 (*temp_s2)(n64dd_driveCmdQueue*); void (*aux)(n64dd_driveCmdQueue*); s32 temp_v0_2; - arg0->unk_68 = -1; - if ((func_801C81D4() != 0) || (arg0->unk_64 == 0)) { - arg0->unk_66 = 1; - temp_v0 = &D_801D2E68[arg0->unk_64]; + ddPacket->unk_68 = -1; + if ((func_801C81D4() != 0) || (ddPacket->unk_64 == 0)) { + ddPacket->unk_66 = 1; + temp_v0 = &D_801D2E68[ddPacket->unk_64]; aux = temp_v0->unk_0; temp_s2 = temp_v0->unk_4; do { - aux(arg0); - temp_v0_2 = temp_s2(arg0); + aux(ddPacket); + temp_v0_2 = temp_s2(ddPacket); } while (temp_v0_2 == 2); - arg0->unk_6C = temp_v0_2; - if (arg0->unk_64 == 0) { + ddPacket->unk_6C = temp_v0_2; + if (ddPacket->unk_64 == 0) { func_801C819C(temp_v0_2); } - arg0->unk_66 = 0; + ddPacket->unk_66 = 0; } } @@ -209,11 +217,11 @@ void func_801C8578(void* arg0, void* arg1, OSId id, void* sp, OSPri pri) { osStartThread(&B_801E0DB0); } -void func_801C85F0(n64dd_driveCmdQueue* arg0, s32 arg1) { +void func_801C85F0(n64dd_driveCmdQueue* ddPacket, s32 arg1) { if (arg1 == 1) { - func_801C8424(arg0); + func_801C8424(ddPacket); } else { - osSendMesg(B_801E0D10[0], arg0, OS_MESG_BLOCK); + osSendMesg(B_801E0D10[0], ddPacket, OS_MESG_BLOCK); } } @@ -250,10 +258,10 @@ void func_801C868C(void* arg0, void* arg1, void* arg2, u8 arg3) { func_801C85F0(&B_801E0D18, 0); } -s32 func_801C873C(n64dd_driveCmdQueue* arg0) { +s32 func_801C873C(n64dd_driveCmdQueue* ddPacket) { u8 sp1F; - arg0->unk_68 = LeoTestUnitReady(&sp1F); + ddPacket->unk_68 = LeoTestUnitReady(&sp1F); return !(sp1F & LEO_TEST_UNIT_MR); } diff --git a/src/n64dd/z_n64dd.c b/src/n64dd/z_n64dd.c index afba70c8171..4809b07f2ba 100644 --- a/src/n64dd/z_n64dd.c +++ b/src/n64dd/z_n64dd.c @@ -19,15 +19,15 @@ #pragma increment_block_number "ntsc-1.0:64 ntsc-1.1:64 ntsc-1.2:64 pal-1.0:64 pal-1.1:64" typedef struct n64dd_CopyToRAM { - /* 0x000 */ s32 diskStart; // disk start - /* 0x004 */ s32 diskEnd; // disk end + /* 0x000 */ s32 diskStart; // disk start + /* 0x004 */ s32 diskEnd; // disk end /* 0x008 */ uintptr_t ramStart; // ram start - /* 0x00C */ uintptr_t ramEnd; // ram end - /* 0x010 */ UNK_PTR unk_010; // s32? + /* 0x00C */ uintptr_t ramEnd; // ram end + /* 0x010 */ UNK_PTR unk_010; // s32? /* 0x014 */ char padding[0x104]; } n64dd_CopyToRAM; // size = 0x118 -typedef struct n64dd_QueuedTransfersList { // This basically has a list of queued disk read commands +typedef struct n64dd_QueuedTransfersList { // This basically has a list of queued disk read commands // ready to be passed to an OSMesgQueue /* 0x00 */ OSMesg messages[30]; /* 0x78 */ OSMesgQueue msgQueue; @@ -51,7 +51,7 @@ OSMesg queuedMessages1[1]; volatile u8 isNewFBAvailable; // bool? volatile OSTime currentTime; s32 isGameDiskCorrect; // 1 if disk gameName is correct, 2 otherwise -void* pUnkTxt0; // pointers to some text +void* pUnkTxt0; // pointers to some text void* pUnkTxt1; void* pUnkTxt2; OSThread diskReadThread; @@ -64,7 +64,7 @@ UNK_TYPE B_801DBFC4; // unused? /** * Checks if the DD is present. * @returns Disk drive status -*/ + */ u32 n64dd_isDrivePresent(void) { #if OOT_NTSC return LeoDriveExist(); @@ -76,35 +76,42 @@ u32 n64dd_isDrivePresent(void) { void n64dd_gfxHook(Gfx** gfxP) { // see game.c } -void func_801C6EAC(void) { - if (D_80121214 == 0) { - func_800F6BDC(); - D_80121214 = 1; +/** + * Stops currently playing audio sequences. + */ +void n64dd_stopSound(void) { + if (isSoundStopped == 0) { + func_800F6BDC(); // <- audio engine code. + isSoundStopped = 1; } } -s32 func_801C6EF0(void) { - return D_80121214 != 0; +s32 n64dd_isSoundStopped(void) { + return isSoundStopped != 0; } -s32 func_801C6F08(void) { - if (D_80121214 != 0) { +// same as before +s32 n64dd_isSoundStopped2(void) { + if (isSoundStopped != 0) { return 1; } return 1; } -void func_801C6F30(void) { - func_801C6EAC(); - while (func_801C6F08() == 0) { +/** + * Wait for all sound to finish playing. + */ +void n64dd_waitForSound(void) { + n64dd_stopSound(); + while (n64dd_isSoundStopped2() == 0) { Sleep_Usec(16666); // 100000 / 6 } } -void func_801C6F78(void) { - if (D_80121214 != 0) { - D_80121214 = 0; - func_800F6B3C(); +void n64dd_playSfx(void) { + if (isSoundStopped != 0) { + isSoundStopped = 0; + func_800F6B3C(); // <- audio engine code. } } @@ -133,54 +140,62 @@ void func_801C7018(void) { D_80121213 = 1; } -s32 func_801C7064(void) { - drivePacketData.messages = 5; - return (&func_801C8000)(&drivePacketData); +s32 n64dd_sendCmd5(void) { + drivePacketData.cmdType = 5; + return (&n64dd_parsePacketData)(&drivePacketData); } -s32 func_801C7098(void) { +s32 n64dd_sendCmd10(void) { s32 phi_v1; #if OOT_VERSION < PAL_1_0 if (0) {} #endif - drivePacketData.messages = 10; - phi_v1 = (&func_801C8000)(&drivePacketData); + drivePacketData.cmdType = 10; + phi_v1 = (&n64dd_parsePacketData)(&drivePacketData); if (phi_v1 < 0) { Freeze_CurrentThread(); } return phi_v1; } -s32 func_801C70E4(void) { +s32 n64dd_isDiskCorrectInternal(void) { return isGameDiskCorrect == 1; } // Used by EnMag and FileChoose -s32 func_801C70FC(void) { - return func_801C70E4(); +s32 n64dd_isDiskCorrect(void) { + return n64dd_isDiskCorrectInternal(); } -void func_801C711C(void* arg) { - static void* B_801DBFC8; - n64dd_QueuedTransfersList* arg0 = (n64dd_QueuedTransfersList*)arg; - s16* sp58; - s32 var_s0; - void* temp_v0; - - sp58 = NULL; - arg0->pIRQMgr = &gIrqMgr; - osCreateMesgQueue(&arg0->msgQueue, arg0->messages, ARRAY_COUNT(arg0->messages)); - IrqMgr_AddClient(arg0->pIRQMgr, &arg0->IRQMgrC, &arg0->msgQueue); - var_s0 = 0; +/** + * Enqueues all queued disk transfers to be automatically performed + * when the drive is ready. + * @param queuedDiskTransfers A queue of all the disk transfers to be performed + **/ +void n64dd_enqueueDiskTransfers(void* queuedDiskTransfers) { + static void* pSomeFramebuf; + n64dd_QueuedTransfersList* pTransferList = (n64dd_QueuedTransfersList*)queuedDiskTransfers; + s16* pOSRecvMesg; + s32 exit; + void* pNextFramebuf; + + pOSRecvMesg = NULL; + pTransferList->pIRQMgr = &gIrqMgr; + osCreateMesgQueue(&pTransferList->msgQueue, pTransferList->messages, ARRAY_COUNT(pTransferList->messages)); + IrqMgr_AddClient(pTransferList->pIRQMgr, &pTransferList->IRQMgrC, &pTransferList->msgQueue); + exit = 0; do { - osRecvMesg(&arg0->msgQueue, (OSMesg*)&sp58, OS_MESG_BLOCK); - switch (*sp58) { - case 1: - temp_v0 = osViGetNextFramebuffer(); - if (B_801DBFC8 != temp_v0) { - B_801DBFC8 = temp_v0; + osRecvMesg(&pTransferList->msgQueue, (OSMesg*)&pOSRecvMesg, OS_MESG_BLOCK); + // The idea behind this is to wait for messages from the disk drive; + // If there is an error, it is displayed on screen or the drive is reset + // (maybe to try again?) or everything is fine and we do nothing else. + switch (*pOSRecvMesg) { + case 1: // Clear FB and display an error + pNextFramebuf = osViGetNextFramebuffer(); + if (pSomeFramebuf != pNextFramebuf) { + pSomeFramebuf = pNextFramebuf; isNewFBAvailable = 1; } func_801C8AA8(); @@ -189,15 +204,16 @@ void func_801C711C(void* arg) { LeoReset(); break; case 3: - var_s0 = 1; + exit = 1; break; } - } while (var_s0 == 0); - IrqMgr_RemoveClient(arg0->pIRQMgr, &arg0->IRQMgrC); + } while (exit == 0); + IrqMgr_RemoveClient(pTransferList->pIRQMgr, &pTransferList->IRQMgrC); } +// seems to be waiting for the end of the frame. #if OOT_VERSION >= NTSC_1_1 -void func_801C7B28_ne2(void) { +void n64dd_waitFrameEnd(void) { s32 temp; if (currentTime != 0) { @@ -211,17 +227,17 @@ void func_801C7B28_ne2(void) { void func_801C7268(void) { s32 pad; - s32 sp20; + s32 isSoundStopped; s32 sp1C; - sp20 = func_801C6EF0(); - if (sp20 == 0) { - func_801C6F30(); + isSoundStopped = n64dd_isSoundStopped(); + if (isSoundStopped == 0) { + n64dd_waitForSound(); } isNewFBAvailable = 1; currentTime = 0; - if (func_801C7064() == 1) { - func_801C7098(); + if (n64dd_sendCmd5() == 1) { + n64dd_sendCmd10(); } else if (isGameDiskCorrect != 0) { isGameDiskCorrect = 0; } @@ -242,41 +258,50 @@ void func_801C7268(void) { if (D_801D2EA8 == 1 || B_801E0F60 == 1 || B_801E0F64 == 1) { currentTime = osGetTime(); } - func_801C7B28_ne2(); + n64dd_waitFrameEnd(); #endif - if (sp20 == 0) { - func_801C6F78(); + if (isSoundStopped == 0) { + n64dd_playSfx(); } } -// Clears framebuffer -void func_801C7438(void* arg0) { - u16* var_v0; +/** + * Initializes a framebuffer. + * @param buf The framebuffer + */ +void n64dd_initFB(void* arg0) { + u16* curData; - for (var_v0 = (u16*)arg0; var_v0 < (u16*)arg0 + SCREEN_WIDTH * SCREEN_HEIGHT; var_v0++) { - *var_v0 = 1; + for (curData = (u16*)arg0; curData < (u16*)arg0 + SCREEN_WIDTH * SCREEN_HEIGHT; curData++) { + *curData = 1; } } -void func_801C746C(void* arg0, void* arg1, void* arg2) { - void* sp2C; - - if (arg0 != NULL || arg1 != NULL || arg2 != NULL) { - sp2C = (u8*)osViGetNextFramebuffer() + 0x20000000; - if ((u32)sp2C & 0xFFFFFF) { +/** + * Prints up to 3 rows of text to the screen. + * @param pCharsRow1 The first row of text + * @param pCharsRow2 The second row of text + * @param pCharsRow3 The third row of text + **/ +void n64dd_printText(void* pCharsRow1, void* pCharsRow2, void* pCharsRow3) { + void* pNextFrameBuf; + + if (pCharsRow1 != NULL || pCharsRow2 != NULL || pCharsRow3 != NULL) { + pNextFrameBuf = (u8*)osViGetNextFramebuffer() + 0x20000000; + if ((u32)pNextFrameBuf & 0xFFFFFF) { if (isNewFBAvailable != 0) { isNewFBAvailable = 0; - func_801C7438(sp2C); + n64dd_initFB(pNextFrameBuf); currentTime = osGetTime(); } - if (arg0 != NULL) { - func_801CA1F0(arg0, 96, 32, 192, 16, 11, sp2C, SCREEN_WIDTH); + if (pCharsRow1 != NULL) { + func_801CA1F0(pCharsRow1, 96, 32, 192, 16, 11, pNextFrameBuf, SCREEN_WIDTH); } - if (arg1 != NULL) { - func_801CA1F0(arg1, 0, 80, 320, 64, 11, sp2C, SCREEN_WIDTH); + if (pCharsRow2 != NULL) { + func_801CA1F0(pCharsRow2, 0, 80, 320, 64, 11, pNextFrameBuf, SCREEN_WIDTH); } - if (arg2 != NULL) { - func_801CA1F0(arg2, 0, 176, 320, 32, 11, sp2C, SCREEN_WIDTH); + if (pCharsRow3 != NULL) { + func_801CA1F0(pCharsRow3, 0, 176, 320, 32, 11, pNextFrameBuf, SCREEN_WIDTH); } #if OOT_VERSION < PAL_1_0 osViBlack(0); @@ -285,40 +310,45 @@ void func_801C746C(void* arg0, void* arg1, void* arg2) { } } -void func_801C75BC(void* arg0, void* arg1, void* arg2) { +void n64dd_setUnkTextPtrsAndPrint(void* newUnkTexPtr0, void* newUnkTexPtr1, void* newUnkTexPtr2) { s32 temp; - if (arg0 == NULL && arg1 == NULL && arg2 == NULL) { + if (newUnkTexPtr0 == NULL && newUnkTexPtr1 == NULL && newUnkTexPtr2 == NULL) { return; } if (isNewFBAvailable) {} - if (arg0 != 0) { - pUnkTxt0 = arg0; + if (newUnkTexPtr0 != 0) { + pUnkTxt0 = newUnkTexPtr0; } - if (arg1 != 0) { - pUnkTxt1 = arg1; + if (newUnkTexPtr1 != 0) { + pUnkTxt1 = newUnkTexPtr1; } - if (arg2 != 0) { - pUnkTxt2 = arg2; + if (newUnkTexPtr2 != 0) { + pUnkTxt2 = newUnkTexPtr2; } - func_801C746C(arg0, arg1, arg2); + n64dd_printText(newUnkTexPtr0, newUnkTexPtr1, newUnkTexPtr2); } -void func_801C761C(void) { +void n64dd_waitPrintText(void) { Sleep_Msec(100); - func_801C746C(pUnkTxt0, pUnkTxt1, pUnkTxt2); + n64dd_printText(pUnkTxt0, pUnkTxt1, pUnkTxt2); } -s32 func_801C7658(void) { - if (D_80121212 != 0) { +/** + * Sets up and starts the data transfer thread. Returns immediately if the disk extras are already running. + * @returns 0 on exit +*/ +s32 n64dd_setupTransferThread(void) { + if (n64dd_isDiskContentRunning != 0) { return 0; } #if OOT_VERSION < PAL_1_0 StackCheck_Init(&transfStackEntry, pStackTransfTrhead, STACK_TOP(pStackTransfTrhead), 0, 0x100, "ddmsg"); - osCreateThread(&diskReadThread, THREAD_ID_DDMSG, &func_801C711C, &queuedDDTransfers, STACK_TOP(pStackTransfTrhead), THREAD_PRI_DDMSG); + osCreateThread(&diskReadThread, THREAD_ID_DDMSG, &n64dd_enqueueDiskTransfers, &queuedDDTransfers, + STACK_TOP(pStackTransfTrhead), THREAD_PRI_DDMSG); osStartThread(&diskReadThread); #endif @@ -327,30 +357,31 @@ s32 func_801C7658(void) { StackCheck_Init(&commStackEntry, pStackDDCommThread, STACK_TOP(pStackDDCommThread), 0, 0x100, "n64dd"); - drivePacketData.unk_1C = &msgQueue0; - drivePacketData.unk_20 = &msgQueue1; - drivePacketData.unk_24 = THREAD_ID_N64DD; - drivePacketData.unk_28 = STACK_TOP(pStackDDCommThread); - drivePacketData.unk_2C = THREAD_PRI_N64DD; - drivePacketData.messages = 1; + drivePacketData.pCmdParam1 = &msgQueue0; + drivePacketData.pCmdParam2 = &msgQueue1; + drivePacketData.threadId = THREAD_ID_N64DD; + drivePacketData.pStackCommThread = STACK_TOP(pStackDDCommThread); + drivePacketData.threadPriority = THREAD_PRI_N64DD; + drivePacketData.cmdType = 1; - (&func_801C8000)(&drivePacketData); + (&n64dd_parsePacketData)(&drivePacketData); D_80121213 = 1; func_801C6FD8(); - drivePacketData.messages = 2; + drivePacketData.cmdType = 2; drivePacketData.unk_10 = 6; - drivePacketData.unk_14 = &DmaMgr_DmaFromDriveRom; - drivePacketData.unk_0C = &func_801C75BC; - (&func_801C8000)(&drivePacketData); + drivePacketData.pDmaMgr = &DmaMgr_DmaFromDriveRom; + drivePacketData.pPrintText = &n64dd_setUnkTextPtrsAndPrint; + (&n64dd_parsePacketData)(&drivePacketData); - drivePacketData.messages = 13; - (&func_801C8000)(&drivePacketData); + drivePacketData.cmdType = 13; + (&n64dd_parsePacketData)(&drivePacketData); #if OOT_VERSION >= PAL_1_0 StackCheck_Init(&transfStackEntry, pStackTransfTrhead, STACK_TOP(pStackTransfTrhead), 0, 0x100, "ddmsg"); - osCreateThread(&diskReadThread, THREAD_ID_DDMSG, &func_801C711C, &queuedDDTransfers, STACK_TOP(pStackTransfTrhead), THREAD_PRI_DDMSG); + osCreateThread(&diskReadThread, THREAD_ID_DDMSG, &n64dd_enqueueDiskTransfers, &queuedDDTransfers, + STACK_TOP(pStackTransfTrhead), THREAD_PRI_DDMSG); osStartThread(&diskReadThread); #endif @@ -363,8 +394,8 @@ s32 func_801C7818(void) { currentTime = 0; #endif - drivePacketData.messages = 12; - (&func_801C8000)(&drivePacketData); + drivePacketData.cmdType = 12; + (&n64dd_parsePacketData)(&drivePacketData); while (func_801C81C4() == 0) { // the number 16666 sounds like it could be 1 frame (at 60 frames per second) @@ -375,22 +406,22 @@ s32 func_801C7818(void) { if (D_801D2EA8 == 1 || B_801E0F60 == 1 || B_801E0F64 == 1) { currentTime = osGetTime(); } - func_801C7B28_ne2(); + n64dd_waitFrameEnd(); #endif if (func_801C81C4() != 2) { - func_801C761C(); + n64dd_waitPrintText(); Freeze_CurrentThread(); return -3; } func_801C7018(); - D_80121212 = 1; + n64dd_isDiskContentRunning = 1; return 0; } s32 func_801C78B8(void) { - s32 phi_v1 = func_801C7658(); + s32 phi_v1 = n64dd_setupTransferThread(); if (phi_v1 == 0) { phi_v1 = func_801C7818(); @@ -399,33 +430,33 @@ s32 func_801C78B8(void) { } s32 func_801C78F0(void) { - drivePacketData.messages = 0; - return (&func_801C8000)(&drivePacketData); + drivePacketData.cmdType = 0; + return (&n64dd_parsePacketData)(&drivePacketData); } void func_801C7920(s32 arg0, void* arg1, s32 arg2) { - drivePacketData.unk_18 = arg1; - drivePacketData.unk_1C = (void*)arg0; - drivePacketData.unk_20 = (void*)arg2; - drivePacketData.messages = 3; - (&func_801C8000)(&drivePacketData); + drivePacketData.pReadBuf = arg1; + drivePacketData.pCmdParam1 = (void*)arg0; + drivePacketData.pCmdParam2 = (void*)arg2; + drivePacketData.cmdType = 3; + (&n64dd_parsePacketData)(&drivePacketData); osGetTime(); - drivePacketData.messages = 6; - while ((&func_801C8000)(&drivePacketData) != 0) { + drivePacketData.cmdType = 6; + while ((&n64dd_parsePacketData)(&drivePacketData) != 0) { Sleep_Usec(16666); // 100000 / 6 } - drivePacketData.messages = 7; - if ((&func_801C8000)(&drivePacketData) != 0) { + drivePacketData.cmdType = 7; + if ((&n64dd_parsePacketData)(&drivePacketData) != 0) { Freeze_CurrentThread(); } } void func_801C79CC(void* arg0, s32 arg1, s32 arg2) { - drivePacketData.unk_18 = arg0; - drivePacketData.unk_1C = (void*)arg1; - drivePacketData.unk_20 = (void*)arg2; - drivePacketData.messages = 4; - (&func_801C8000)(&drivePacketData); + drivePacketData.pReadBuf = arg0; + drivePacketData.pCmdParam1 = (void*)arg1; + drivePacketData.pCmdParam2 = (void*)arg2; + drivePacketData.cmdType = 4; + (&n64dd_parsePacketData)(&drivePacketData); } void func_801C7A10(LEODiskID* arg0) { @@ -505,7 +536,7 @@ void func_801C7C1C(void* dest, s32 offset, s32 size) { s32 temp_v1_2; func_801C6FD8(); - func_801C6F30(); + n64dd_waitForSound(); isNewFBAvailable = 1; currentTime = 0; func_801C7B48(offset, &sp5C, &sp54); @@ -537,10 +568,10 @@ void func_801C7C1C(void* dest, s32 offset, s32 size) { } } #else - func_801C7B28_ne2(); + n64dd_waitFrameEnd(); #endif func_801C7018(); - func_801C6F78(); + n64dd_playSfx(); } void func_801C7E78(void) { diff --git a/src/overlays/actors/ovl_En_Mag/z_en_mag.c b/src/overlays/actors/ovl_En_Mag/z_en_mag.c index e52a54d5e44..f59741b9b12 100644 --- a/src/overlays/actors/ovl_En_Mag/z_en_mag.c +++ b/src/overlays/actors/ovl_En_Mag/z_en_mag.c @@ -493,7 +493,7 @@ void EnMag_DrawImageRGBA32(Gfx** gfxP, s16 centerX, s16 centerY, u8* source, u32 #if PLATFORM_N64 void func_80AEEA48_unknown(Gfx** gfxP, s16 arg1, s16 arg2, u32 arg3) { - if ((D_80121212 != 0) && (func_801C70FC() != 0)) { + if ((n64dd_isDiskContentRunning != 0) && (n64dd_isDiskCorrect() != 0)) { Gfx* gfx = *gfxP; s32 temp_a3 = (arg1 + 0x40) << 2; s32 temp_t0 = (arg2 + 5) << 2; diff --git a/src/overlays/gamestates/ovl_file_choose/z_file_choose.c b/src/overlays/gamestates/ovl_file_choose/z_file_choose.c index 2e6dc9afdef..950f3325c6c 100644 --- a/src/overlays/gamestates/ovl_file_choose/z_file_choose.c +++ b/src/overlays/gamestates/ovl_file_choose/z_file_choose.c @@ -555,7 +555,7 @@ void FileSelect_UpdateMainMenu(GameState* thisx) { SFX_PLAY_CENTERED(NA_SE_SY_FSEL_ERROR); } else { #if PLATFORM_N64 - if (D_80121212 != 0) { + if (n64dd_isDiskContentRunning != 0) { func_801C7268(); // Setting ioData to 1 and writing it to ioPort 7 will skip the harp intro Audio_PlaySequenceWithSeqPlayerIO(SEQ_PLAYER_BGM_MAIN, NA_BGM_FILE_SELECT, 0, 7, 1); @@ -1953,7 +1953,7 @@ void FileSelect_LoadGame(GameState* thisx) { } #if PLATFORM_N64 - if (D_80121212 != 0) { + if (n64dd_isDiskContentRunning != 0) { s32 fileNum = gSaveContext.fileNum; n64dd_SetDiskVersion(this->n64ddFlags[fileNum]); @@ -2044,7 +2044,7 @@ void FileSelect_Main(GameState* thisx) { OPEN_DISPS(this->state.gfxCtx, "../z_file_choose.c", 2898); #if PLATFORM_N64 - if ((D_80121212 != 0) && (func_801C70FC() != 0)) { + if ((n64dd_isDiskContentRunning != 0) && (n64dd_isDiskCorrect() != 0)) { this->n64ddFlag = 1; } else { this->n64ddFlag = 0; @@ -2334,7 +2334,7 @@ void FileSelect_Init(GameState* thisx) { u32 size = (uintptr_t)_title_staticSegmentRomEnd - (uintptr_t)_title_staticSegmentRomStart; #if PLATFORM_N64 - if (D_80121212 != 0) { + if (n64dd_isDiskContentRunning != 0) { func_801C7268(); } #endif diff --git a/src/overlays/gamestates/ovl_select/z_select.c b/src/overlays/gamestates/ovl_select/z_select.c index a8d5f1ecc77..d3519b4ff3e 100644 --- a/src/overlays/gamestates/ovl_select/z_select.c +++ b/src/overlays/gamestates/ovl_select/z_select.c @@ -66,13 +66,13 @@ void MapSelect_LoadGame(MapSelectState* this, s32 entranceIndex) { #if PLATFORM_N64 void func_80800AD0_unknown(MapSelectState* this, s32 arg1) { - if (D_80121212 != 0) { + if (n64dd_isDiskContentRunning != 0) { n64dd_SetDiskVersion(1); } } void func_80800B08_unknown(MapSelectState* this, s32 arg1) { - if (D_80121212 != 0) { + if (n64dd_isDiskContentRunning != 0) { n64dd_SetDiskVersion(0); } } diff --git a/src/overlays/gamestates/ovl_title/z_title.c b/src/overlays/gamestates/ovl_title/z_title.c index a17bd0f4d84..6e1a8f4f3d6 100644 --- a/src/overlays/gamestates/ovl_title/z_title.c +++ b/src/overlays/gamestates/ovl_title/z_title.c @@ -221,8 +221,8 @@ void ConsoleLogo_Init(GameState* thisx) { ConsoleLogoState* this = (ConsoleLogoState*)thisx; #if PLATFORM_N64 - if ((D_80121210 != 0) && (D_80121211 != 0) && (D_80121212 == 0)) { - if (func_801C7658() != 0) { + if ((D_80121210 != 0) && (D_80121211 != 0) && (n64dd_isDiskContentRunning == 0)) { + if (n64dd_setupTransferThread() != 0) { Freeze_CurrentThread(); } this->unk_1E0 = true; From a2d259f083c644fc78c4b71ab288af95f30d317f Mon Sep 17 00:00:00 2001 From: scudo <96631443+scudo005@users.noreply.github.com> Date: Thu, 16 Apr 2026 16:03:32 +0200 Subject: [PATCH 3/5] Renamed more functions --- include/n64dd.h | 4 +- src/code/code_n64dd_800AD4C0.c | 2 +- src/code/game.c | 4 +- src/code/z_play.c | 2 +- src/n64dd/z_n64dd.c | 198 ++++++++++++++++++--------------- 5 files changed, 117 insertions(+), 93 deletions(-) diff --git a/include/n64dd.h b/include/n64dd.h index af04e6bcc66..3e78ff89c91 100644 --- a/include/n64dd.h +++ b/include/n64dd.h @@ -111,8 +111,8 @@ s32 n64dd_isDiskCorrect(void); void func_801C7268(void); s32 n64dd_setupTransferThread(void); s32 func_801C7818(void); -void func_801C7C1C(void* dest, s32 offset, s32 size); -void func_801C7E78(void); +void n64dd_loadData(void* dest, s32 offset, s32 size); +void n64dd_empty2(void); void n64dd_SetDiskVersion(s32 arg0); s32 n64dd_parsePacketData(n64dd_drivePacketData* arg0); diff --git a/src/code/code_n64dd_800AD4C0.c b/src/code/code_n64dd_800AD4C0.c index 4b2d17e72c3..f88102545ff 100644 --- a/src/code/code_n64dd_800AD4C0.c +++ b/src/code/code_n64dd_800AD4C0.c @@ -7,7 +7,7 @@ #include "save.h" n64ddStruct_800FEE70_pointers D_800FEE70 = { - func_801C7C1C, + n64dd_loadData, NULL, NULL, Fault_RemoveClient, diff --git a/src/code/game.c b/src/code/game.c index adb4ecd72ac..a2a333369f8 100644 --- a/src/code/game.c +++ b/src/code/game.c @@ -154,7 +154,7 @@ void func_800C4344(GameState* gameState) { #if PLATFORM_N64 if (n64dd_isDiskContentRunning != 0) { - func_801C7E78(); + n64dd_empty2(); } #endif } @@ -302,7 +302,7 @@ void GameState_Update(GameState* gameState) { #if PLATFORM_N64 if (n64dd_isDiskContentRunning != 0) { - func_801C7E78(); + n64dd_empty2(); } if ((B_80121220 != NULL) && (B_80121220->unk_74 != NULL)) { B_80121220->unk_74(gameState); diff --git a/src/code/z_play.c b/src/code/z_play.c index 8d73e9e5658..8a44d0c151a 100644 --- a/src/code/z_play.c +++ b/src/code/z_play.c @@ -1535,7 +1535,7 @@ void* Play_LoadFileFromDiskDrive(PlayState* this, RomFile* file) { size = file->vromEnd - file->vromStart; allocp = GAME_STATE_ALLOC(&this->state, size, "../z_play.c", UNK_LINE); - func_801C7C1C(allocp, file->vromStart, size); + n64dd_loadData(allocp, file->vromStart, size); return allocp; } diff --git a/src/n64dd/z_n64dd.c b/src/n64dd/z_n64dd.c index 4809b07f2ba..d854bb5afb5 100644 --- a/src/n64dd/z_n64dd.c +++ b/src/n64dd/z_n64dd.c @@ -339,7 +339,7 @@ void n64dd_waitPrintText(void) { /** * Sets up and starts the data transfer thread. Returns immediately if the disk extras are already running. * @returns 0 on exit -*/ + */ s32 n64dd_setupTransferThread(void) { if (n64dd_isDiskContentRunning != 0) { return 0; @@ -420,16 +420,16 @@ s32 func_801C7818(void) { return 0; } -s32 func_801C78B8(void) { - s32 phi_v1 = n64dd_setupTransferThread(); +s32 n64dd_transfThreadStatus(void) { + s32 status = n64dd_setupTransferThread(); - if (phi_v1 == 0) { - phi_v1 = func_801C7818(); + if (status == 0) { + status = func_801C7818(); } - return phi_v1; + return status; } -s32 func_801C78F0(void) { +s32 n64dd_cmd0(void) { drivePacketData.cmdType = 0; return (&n64dd_parsePacketData)(&drivePacketData); } @@ -459,29 +459,33 @@ void func_801C79CC(void* arg0, s32 arg1, s32 arg2) { (&n64dd_parsePacketData)(&drivePacketData); } -void func_801C7A10(LEODiskID* arg0) { +void n64dd_empty(LEODiskID* arg0) { } -// Checks diskId, sets isGameDiskCorrect and returns true if diskId is correct -s32 n64dd_CheckIfDiskIsValid(n64dd_driveCmdQueue* arg0) { - static LEODiskID B_801DBFD0; - static s32 B_801DBFF0; // bool +/** + * Checks diskId, sets isGameDiskCorrect and returns true if diskId is correct. + * @param diskData A communication packet from the disk drive. This gets us info about the currently inserted disk. + * @returns true if diskId is correct + **/ +s32 n64dd_CheckIfDiskIsValid(n64dd_driveCmdQueue* diskData) { + static LEODiskID curDiskId; + static s32 isDiskIdSet; // bool - func_801C7A10(&arg0->diskId); - if (!B_801DBFF0) { + n64dd_empty(&diskData->diskId); + if (!isDiskIdSet) { #if OOT_NTSC - if (bcmp(arg0->diskId.gameName, "EZLJ", 4) == 0 || bcmp(arg0->diskId.gameName, "EZLE", 4) == 0) + if (bcmp(diskData->diskId.gameName, "EZLJ", 4) == 0 || bcmp(diskData->diskId.gameName, "EZLE", 4) == 0) #else - if (bcmp(arg0->diskId.gameName, "EZLP", 4) == 0) + if (bcmp(diskData->diskId.gameName, "EZLP", 4) == 0) #endif { - B_801DBFD0 = arg0->diskId; - B_801DBFF0 = true; + curDiskId = diskData->diskId; + isDiskIdSet = true; isGameDiskCorrect = 1; } else { isGameDiskCorrect = 2; } - } else if (bcmp(&B_801DBFD0, &arg0->diskId, sizeof(LEODiskID)) == 0) { + } else if (bcmp(&curDiskId, &diskData->diskId, sizeof(LEODiskID)) == 0) { isGameDiskCorrect = 1; } else { isGameDiskCorrect = 2; @@ -489,49 +493,64 @@ s32 n64dd_CheckIfDiskIsValid(n64dd_driveCmdQueue* arg0) { return isGameDiskCorrect == 1; } -// Translates byte position to LBA and byte offset -s32 func_801C7B48(s32 arg0, s32* arg1, s32* arg2) { - s32 sp2C; - s32 temp_v0_2; - s32 sp24; - s32 sp20; - s32 temp_v0; - - temp_v0_2 = LeoByteToLBA(1, arg0 + 1, &sp2C); - if (temp_v0_2 != LEO_ERROR_GOOD) { - return temp_v0_2; - } - sp24 = sp2C - 1; - if (sp2C == 1) { - sp20 = 0; +/** + * Translates byte position to LBA and byte offset. + * @param startLba The LBA to start reading from + * @param adjustedLbaCount The resultant LBA, accounting for the first (reserved) disk sector. + * @param lba A pointer to the byte offset? + * @returns The drive status. + **/ +s32 n64dd_offsetToBlock(s32 startLba, s32* adjustedLbaCount, s32* lba) { + s32 diskData2; + s32 diskReadStatus; + s32 lbaCount; + s32 diskData; + s32 diskReadStatus2; + + diskReadStatus = LeoByteToLBA(1, startLba + 1, &diskData2); // accounts for disk header + if (diskReadStatus != LEO_ERROR_GOOD) { + return diskReadStatus; + } + lbaCount = diskData2 - 1; + if (diskData2 == 1) { + diskData = 0; } else { - temp_v0 = LeoLBAToByte(1, sp24, &sp20); - if (temp_v0 != LEO_ERROR_GOOD) { - return temp_v0; + diskReadStatus2 = LeoLBAToByte(1, lbaCount, &diskData); + if (diskReadStatus2 != LEO_ERROR_GOOD) { + return diskReadStatus2; } } - *arg1 = sp24 + 1; - *arg2 = arg0 - sp20; + *adjustedLbaCount = lbaCount + 1; + *lba = startLba - diskData; return LEO_ERROR_GOOD; } -s32 func_801C7BEC(s32 startLBA) { - s32 bytes; +/** + * Wrapper for LeoLBAToByte. + * @param startLba The starting LBA + * @returns The corresponding byte offset if the read was successful, else returns 0. + */ +s32 n64dd_LbaToByte(s32 startLba) s32 bytes; - if (LeoLBAToByte(startLBA, 1, &bytes) == LEO_ERROR_GOOD) { - return bytes; - } - return 0; +if (LeoLBAToByte(startLba, 1, &bytes) == LEO_ERROR_GOOD) { + return bytes; +} +return 0; } -// Copies bytes from disk to arg0 -void func_801C7C1C(void* dest, s32 offset, s32 size) { - s32 sp5C; - s32 sp58; - s32 sp54; - s32 sp50; - void* sp4C; - s32 var_s0; +/** + * Copies bytes from disk to a destination buffer. + * @param dest A pointer to the destination buffer + * @param offset The offset from the start of the disk to read from + * @param size How many bytes to read + **/ +void n64dd_loadData(void* dest, s32 offset, s32 size) { + s32 pLbaData; + s32 pLbaData2; + s32 pReadByteOffset; + s32 pReadByteOffset2; + void* pTmpDDReadBuf; + s32 lbaBlockNum; s32 var_s1; s32 temp_v1_2; @@ -539,25 +558,26 @@ void func_801C7C1C(void* dest, s32 offset, s32 size) { n64dd_waitForSound(); isNewFBAvailable = 1; currentTime = 0; - func_801C7B48(offset, &sp5C, &sp54); - func_801C7B48(offset + size, &sp58, &sp50); - sp4C = pTmpReadBuf; - if (sp5C == sp58) { - func_801C7920(sp5C, sp4C, func_801C7BEC(sp5C)); - bcopy((u8*)sp4C + sp54, dest, size); + n64dd_offsetToBlock(offset, &pLbaData, &pReadByteOffset); + n64dd_offsetToBlock(offset + size, &pLbaData2, &pReadByteOffset2); + pTmpDDReadBuf = pTmpReadBuf; + if (pLbaData == pLbaData2) { + func_801C7920(pLbaData, pTmpDDReadBuf, n64dd_LbaToByte(pLbaData)); + bcopy((u8*)pTmpDDReadBuf + pReadByteOffset, dest, size); } else { var_s1 = 0; - func_801C7920(sp5C, sp4C, func_801C7BEC(sp5C)); - bcopy((u8*)sp4C + sp54, dest, func_801C7BEC(sp5C) - sp54); - if (sp5C + 1 < sp58) { - for (var_s0 = sp5C + 1; var_s0 < sp58; var_s0++) { - var_s1 += func_801C7BEC(var_s0); + func_801C7920(pLbaData, pTmpDDReadBuf, n64dd_LbaToByte(pLbaData)); + bcopy((u8*)pTmpDDReadBuf + pReadByteOffset, dest, n64dd_LbaToByte(pLbaData) - pReadByteOffset); + if (pLbaData + 1 < pLbaData2) { + for (lbaBlockNum = pLbaData + 1; lbaBlockNum < pLbaData2; lbaBlockNum++) { + var_s1 += n64dd_LbaToByte(lbaBlockNum); } - func_801C7920(sp5C + 1, (u8*)dest + func_801C7BEC(sp5C) - sp54, var_s1); + func_801C7920(pLbaData + 1, (u8*)dest + n64dd_LbaToByte(pLbaData) - pReadByteOffset, var_s1); } - if (sp50 > 0) { - func_801C7920(sp58, sp4C, func_801C7BEC(sp58)); - bcopy((u8*)sp4C, (u8*)dest + func_801C7BEC(sp5C) - sp54 + var_s1, sp50); + if (pReadByteOffset2 > 0) { + func_801C7920(pLbaData2, pTmpDDReadBuf, n64dd_LbaToByte(pLbaData2)); + bcopy((u8*)pTmpDDReadBuf, (u8*)dest + n64dd_LbaToByte(pLbaData) - pReadByteOffset + var_s1, + pReadByteOffset2); } } #if OOT_VERSION < NTSC_1_1 @@ -574,32 +594,36 @@ void func_801C7C1C(void* dest, s32 offset, s32 size) { n64dd_playSfx(); } -void func_801C7E78(void) { +void n64dd_empty2(void) { } -s32 func_801C7E80(void) { - s32 sp24; - s32 sp20; +/** + * Sets up buffers and reads data from the disk given a global DDLoad structure...? + * @returns -1 if the pointer to the DDLoad struct already exists, 0 on success + **/ +s32 n64dd_setupDiskRead(void) { + s32 diskReadSize; + s32 ramWriteSize; s32 sp1C; - uintptr_t sp18; + uintptr_t pLoadOffset; if (pDDLoad0 != NULL) { return -1; } pDDLoad0 = &DDLoad0; - func_801C7C1C(pDDLoad0, 0x1060, 0x118); - sp24 = pDDLoad0->diskEnd - pDDLoad0->diskStart; - sp20 = pDDLoad0->ramEnd - pDDLoad0->ramStart; - sp18 = pDDLoad0->ramStart + sp24; - func_801C7C1C((void*)pDDLoad0->ramStart, pDDLoad0->diskStart, sp24); - bzero((void*)sp18, sp20 - sp24); + n64dd_loadData(pDDLoad0, 0x1060, 0x118); + diskReadSize = pDDLoad0->diskEnd - pDDLoad0->diskStart; + ramWriteSize = pDDLoad0->ramEnd - pDDLoad0->ramStart; + pLoadOffset = pDDLoad0->ramStart + diskReadSize; + n64dd_loadData((void*)pDDLoad0->ramStart, pDDLoad0->diskStart, diskReadSize); + bzero((void*)pLoadOffset, ramWriteSize - diskReadSize); func_800AD4C0(pDDLoad0->unk_010); return 0; } -s32 func_801C7F24(void) { - uintptr_t temp_a0; - n64dd_CopyToRAM* temp_v0; +s32 n64dd_clearCopyBufs(void) { + uintptr_t pRamStart; + n64dd_CopyToRAM* pCpyToRam; if (pDDLoad0 == 0) { return -1; @@ -608,9 +632,9 @@ s32 func_801C7F24(void) { // Function from code func_800AD51C(); - temp_v0 = pDDLoad0; - temp_a0 = temp_v0->ramStart; - bzero((void*)temp_a0, temp_v0->ramEnd - temp_a0); + pCpyToRam = pDDLoad0; + pRamStart = pCpyToRam->ramStart; + bzero((void*)pRamStart, pCpyToRam->ramEnd - pRamStart); bzero(pDDLoad0, sizeof(n64dd_CopyToRAM)); pDDLoad0 = 0; return 0; @@ -619,9 +643,9 @@ s32 func_801C7F24(void) { void n64dd_SetDiskVersion(s32 arg0) { if (arg0 != 0) { if (pDDLoad0 == 0) { - func_801C7E80(); + n64dd_setupDiskRead(); } } else if (pDDLoad0 != 0) { - func_801C7F24(); + n64dd_clearCopyBufs(); } } From 4283f4394dc388b5cb2b269a6fb6240fc12eb2a5 Mon Sep 17 00:00:00 2001 From: scudo <96631443+scudo005@users.noreply.github.com> Date: Thu, 16 Apr 2026 16:21:01 +0200 Subject: [PATCH 4/5] Tackled some audio code --- include/audio.h | 4 +- include/sequence.h | 131 ++++++++++++++++++------------------ src/audio/game/general.c | 8 +-- src/audio/internal/thread.c | 28 +++++--- src/n64dd/z_n64dd.c | 4 +- 5 files changed, 91 insertions(+), 84 deletions(-) diff --git a/include/audio.h b/include/audio.h index 0b3e6fa55c1..95a28ce3901 100644 --- a/include/audio.h +++ b/include/audio.h @@ -1096,7 +1096,7 @@ u8* AudioThread_GetFontsForSequence(s32 seqId, u32* outNumFonts); s32 func_800E5EDC(void); s32 AudioThread_ResetAudioHeap(s32 specId); void AudioThread_PreNMIInternal(void); -s32 func_800E6680(void); +s32 AudioThread_GetActiveNotes(void); u32 AudioThread_NextRandom(void); void AudioThread_InitMesgQueues(void); @@ -1214,7 +1214,7 @@ void Audio_PlaySfxIfNotInCutscene(u16 sfxId); void func_800F6964(u16); void Audio_StopBgmAndFanfare(u16 fadeOutDuration); void func_800F6B3C(void); -void func_800F6BDC(void); +void Audio_StopWaitAllSeq(void); void Audio_PreNMI(void); void Audio_SetNatureAmbienceChannelIO(u8 channelIdxRange, u8 ioPort, u8 ioData); void Audio_PlayNatureAmbienceSequence(u8 natureAmbienceId); diff --git a/include/sequence.h b/include/sequence.h index d405e323620..229f372e2f1 100644 --- a/include/sequence.h +++ b/include/sequence.h @@ -17,11 +17,12 @@ typedef enum { #undef DEFINE_SEQUENCE #undef DEFINE_SEQUENCE_PTR +// What kind of sequence player is this typedef enum SequencePlayerId { - /* 0 */ SEQ_PLAYER_BGM_MAIN, - /* 1 */ SEQ_PLAYER_FANFARE, - /* 2 */ SEQ_PLAYER_SFX, - /* 3 */ SEQ_PLAYER_BGM_SUB + /* 0 */ SEQ_PLAYER_BGM_MAIN, // This sequence player is for the main BGM + /* 1 */ SEQ_PLAYER_FANFARE, // This sequence player is for a fanfare (opening chests, etc...) + /* 2 */ SEQ_PLAYER_SFX, // This sequence player is for a sfx + /* 3 */ SEQ_PLAYER_BGM_SUB // This sequence player is for the sub BGM (?) } SequencePlayerId; typedef enum SequenceMode { @@ -32,22 +33,22 @@ typedef enum SequenceMode { } SequenceMode; typedef enum SequenceCutsceneEffects { - /* 0x0 */ SEQ_CS_EFFECTS_SWORD_GLOW, // Master sword glow + /* 0x0 */ SEQ_CS_EFFECTS_SWORD_GLOW, // Master sword glow /* 0x1 */ SEQ_CS_EFFECTS_SHEIK_TRANSFORM, // Sheik's transformation to Zelda - /* 0x2 */ SEQ_CS_EFFECTS_SAGE_SEAL, // Sages accumulating their power - /* 0x3 */ SEQ_CS_EFFECTS_FARORE_MAGIC, // Farore's magic creating life - /* 0x4 */ SEQ_CS_EFFECTS_NAYRU_MAGIC, // Nayru's magic establishing order - /* 0x5 */ SEQ_CS_EFFECTS_DIN_MAGIC, // Din's building of the earth - /* 0x6 */ SEQ_CS_EFFECTS_LAVA_ERUPT, // Lava erupting from Volvagia's pit + /* 0x2 */ SEQ_CS_EFFECTS_SAGE_SEAL, // Sages accumulating their power + /* 0x3 */ SEQ_CS_EFFECTS_FARORE_MAGIC, // Farore's magic creating life + /* 0x4 */ SEQ_CS_EFFECTS_NAYRU_MAGIC, // Nayru's magic establishing order + /* 0x5 */ SEQ_CS_EFFECTS_DIN_MAGIC, // Din's building of the earth + /* 0x6 */ SEQ_CS_EFFECTS_LAVA_ERUPT, // Lava erupting from Volvagia's pit /* 0x7 */ SEQ_CS_EFFECTS_BONGO_HURL_LINK, // Link screaming while attacked by invisible Bongo Bongo - /* 0x8 */ SEQ_CS_EFFECTS_BONGO_HOVER, // Bongo Bongo hovering menacingly - /* 0x9 */ SEQ_CS_EFFECTS_BONGO_EMERGES, // Bongo Bongo emerging from the well - /* 0xA */ SEQ_CS_EFFECTS_TRIAL_WARP, // Warping from one of the trial barriers - /* 0xB */ SEQ_CS_EFFECTS_TRIAL_DESTROY, // Destroying one of the trial barriers - /* 0xC */ SEQ_CS_EFFECTS_DISPEL_BARRIER, // Dispelling the Tower barrier - /* 0xD */ SEQ_CS_EFFECTS_TOWER_COLLAPSE, // Ganon's Tower's collapse - /* 0xE */ SEQ_CS_EFFECTS_LINK_SCREAM, // Child Link screaming (unused) - /* 0xF */ SEQ_CS_EFFECTS_RAINFALL // Rain with thunder effects + /* 0x8 */ SEQ_CS_EFFECTS_BONGO_HOVER, // Bongo Bongo hovering menacingly + /* 0x9 */ SEQ_CS_EFFECTS_BONGO_EMERGES, // Bongo Bongo emerging from the well + /* 0xA */ SEQ_CS_EFFECTS_TRIAL_WARP, // Warping from one of the trial barriers + /* 0xB */ SEQ_CS_EFFECTS_TRIAL_DESTROY, // Destroying one of the trial barriers + /* 0xC */ SEQ_CS_EFFECTS_DISPEL_BARRIER, // Dispelling the Tower barrier + /* 0xD */ SEQ_CS_EFFECTS_TOWER_COLLAPSE, // Ganon's Tower's collapse + /* 0xE */ SEQ_CS_EFFECTS_LINK_SCREAM, // Child Link screaming (unused) + /* 0xF */ SEQ_CS_EFFECTS_RAINFALL // Rain with thunder effects } SequenceCutsceneEffects; typedef enum ChannelIOPort { @@ -94,19 +95,19 @@ typedef struct ActiveSequence { /* 0x020 */ f32 tempoTarget; /* 0x024 */ f32 tempoStep; /* 0x028 */ u16 tempoTimer; - /* 0x02C */ u32 setupCmd[8]; // a queue of cmds to execute once the player is disabled + /* 0x02C */ u32 setupCmd[8]; // a queue of cmds to execute once the player is disabled /* 0x04C */ u8 setupCmdTimer; // only execute setup commands when the timer is at 0. - /* 0x04D */ u8 setupCmdNum; // number of setup commands requested once the player is disabled + /* 0x04D */ u8 setupCmdNum; // number of setup commands requested once the player is disabled /* 0x04E */ u8 setupFadeTimer; /* 0x050 */ ActiveSequenceChannelData channelData[16]; /* 0x250 */ u16 freqScaleChannelFlags; /* 0x252 */ u16 volChannelFlags; - /* 0x254 */ u16 seqId; // active seqId currently playing. Resets when sequence stops + /* 0x254 */ u16 seqId; // active seqId currently playing. Resets when sequence stops /* 0x256 */ u16 prevSeqId; // last seqId played on a player. Does not reset when sequence stops /* 0x258 */ u16 channelPortMask; - /* 0x25C */ u32 startSeqCmd; // This name comes from MM + /* 0x25C */ u32 startSeqCmd; // This name comes from MM /* 0x260 */ u8 isWaitingForFonts; // This name comes from MM -} ActiveSequence; // size = 0x264 +} ActiveSequence; // size = 0x264 typedef enum NatureChannelIndex { /* 0x0 */ NATURE_CHANNEL_STREAM_0, @@ -178,48 +179,48 @@ typedef enum NatureAmimalId { /* 0x13 */ NATURE_CRITTER_BIRD_CHIRP_1_ALT5 } NatureAmimalId; -#define NATURE_IO_CRITTER_0_TYPE(type) NATURE_CHANNEL_CRITTER_0, CHANNEL_IO_PORT_2, type -#define NATURE_IO_CRITTER_0_BEND_PITCH(bend) NATURE_CHANNEL_CRITTER_0, CHANNEL_IO_PORT_3, bend -#define NATURE_IO_CRITTER_0_NUM_LAYERS(num) NATURE_CHANNEL_CRITTER_0, CHANNEL_IO_PORT_4, num -#define NATURE_IO_CRITTER_0_PORT5(reverb) NATURE_CHANNEL_CRITTER_0, CHANNEL_IO_PORT_5, reverb - -#define NATURE_IO_CRITTER_1_TYPE(type) NATURE_CHANNEL_CRITTER_1, CHANNEL_IO_PORT_2, type -#define NATURE_IO_CRITTER_1_BEND_PITCH(bend) NATURE_CHANNEL_CRITTER_1, CHANNEL_IO_PORT_3, bend -#define NATURE_IO_CRITTER_1_NUM_LAYERS(num) NATURE_CHANNEL_CRITTER_1, CHANNEL_IO_PORT_4, num -#define NATURE_IO_CRITTER_1_PORT5(reverb) NATURE_CHANNEL_CRITTER_1, CHANNEL_IO_PORT_5, reverb - -#define NATURE_IO_CRITTER_2_TYPE(type) NATURE_CHANNEL_CRITTER_2, CHANNEL_IO_PORT_2, type -#define NATURE_IO_CRITTER_2_BEND_PITCH(bend) NATURE_CHANNEL_CRITTER_2, CHANNEL_IO_PORT_3, bend -#define NATURE_IO_CRITTER_2_NUM_LAYERS(num) NATURE_CHANNEL_CRITTER_2, CHANNEL_IO_PORT_4, num -#define NATURE_IO_CRITTER_2_PORT5(reverb) NATURE_CHANNEL_CRITTER_2, CHANNEL_IO_PORT_5, reverb - -#define NATURE_IO_CRITTER_3_TYPE(type) NATURE_CHANNEL_CRITTER_3, CHANNEL_IO_PORT_2, type -#define NATURE_IO_CRITTER_3_BEND_PITCH(bend) NATURE_CHANNEL_CRITTER_3, CHANNEL_IO_PORT_3, bend -#define NATURE_IO_CRITTER_3_NUM_LAYERS(num) NATURE_CHANNEL_CRITTER_3, CHANNEL_IO_PORT_4, num -#define NATURE_IO_CRITTER_3_PORT5(reverb) NATURE_CHANNEL_CRITTER_3, CHANNEL_IO_PORT_5, reverb - -#define NATURE_IO_CRITTER_4_TYPE(type) NATURE_CHANNEL_CRITTER_4, CHANNEL_IO_PORT_2, type -#define NATURE_IO_CRITTER_4_BEND_PITCH(bend) NATURE_CHANNEL_CRITTER_4, CHANNEL_IO_PORT_3, bend -#define NATURE_IO_CRITTER_4_NUM_LAYERS(num) NATURE_CHANNEL_CRITTER_4, CHANNEL_IO_PORT_4, num -#define NATURE_IO_CRITTER_4_PORT5(reverb) NATURE_CHANNEL_CRITTER_4, CHANNEL_IO_PORT_5, reverb - -#define NATURE_IO_CRITTER_5_TYPE(type) NATURE_CHANNEL_CRITTER_5, CHANNEL_IO_PORT_2, type -#define NATURE_IO_CRITTER_5_BEND_PITCH(bend) NATURE_CHANNEL_CRITTER_5, CHANNEL_IO_PORT_3, bend -#define NATURE_IO_CRITTER_5_NUM_LAYERS(num) NATURE_CHANNEL_CRITTER_5, CHANNEL_IO_PORT_4, num -#define NATURE_IO_CRITTER_5_PORT5(reverb) NATURE_CHANNEL_CRITTER_5, CHANNEL_IO_PORT_5, reverb - -#define NATURE_IO_CRITTER_6_TYPE(type) NATURE_CHANNEL_CRITTER_6, CHANNEL_IO_PORT_2, type -#define NATURE_IO_CRITTER_6_BEND_PITCH(bend) NATURE_CHANNEL_CRITTER_6, CHANNEL_IO_PORT_3, bend -#define NATURE_IO_CRITTER_6_NUM_LAYERS(num) NATURE_CHANNEL_CRITTER_6, CHANNEL_IO_PORT_4, num -#define NATURE_IO_CRITTER_6_PORT5(reverb) NATURE_CHANNEL_CRITTER_6, CHANNEL_IO_PORT_5, reverb - -#define NATURE_IO_STREAM_0_TYPE(type) NATURE_CHANNEL_STREAM_0, CHANNEL_IO_PORT_2, type -#define NATURE_IO_STREAM_0_PORT3(data) NATURE_CHANNEL_STREAM_0, CHANNEL_IO_PORT_3, data -#define NATURE_IO_STREAM_0_PORT4(data) NATURE_CHANNEL_STREAM_0, CHANNEL_IO_PORT_4, data - -#define NATURE_IO_STREAM_1_TYPE(type) NATURE_CHANNEL_STREAM_1, CHANNEL_IO_PORT_2, type -#define NATURE_IO_STREAM_1_PORT3(data) NATURE_CHANNEL_STREAM_1, CHANNEL_IO_PORT_3, data -#define NATURE_IO_STREAM_1_PORT4(data) NATURE_CHANNEL_STREAM_1, CHANNEL_IO_PORT_4, data +#define NATURE_IO_CRITTER_0_TYPE(type) NATURE_CHANNEL_CRITTER_0, CHANNEL_IO_PORT_2, type +#define NATURE_IO_CRITTER_0_BEND_PITCH(bend) NATURE_CHANNEL_CRITTER_0, CHANNEL_IO_PORT_3, bend +#define NATURE_IO_CRITTER_0_NUM_LAYERS(num) NATURE_CHANNEL_CRITTER_0, CHANNEL_IO_PORT_4, num +#define NATURE_IO_CRITTER_0_PORT5(reverb) NATURE_CHANNEL_CRITTER_0, CHANNEL_IO_PORT_5, reverb + +#define NATURE_IO_CRITTER_1_TYPE(type) NATURE_CHANNEL_CRITTER_1, CHANNEL_IO_PORT_2, type +#define NATURE_IO_CRITTER_1_BEND_PITCH(bend) NATURE_CHANNEL_CRITTER_1, CHANNEL_IO_PORT_3, bend +#define NATURE_IO_CRITTER_1_NUM_LAYERS(num) NATURE_CHANNEL_CRITTER_1, CHANNEL_IO_PORT_4, num +#define NATURE_IO_CRITTER_1_PORT5(reverb) NATURE_CHANNEL_CRITTER_1, CHANNEL_IO_PORT_5, reverb + +#define NATURE_IO_CRITTER_2_TYPE(type) NATURE_CHANNEL_CRITTER_2, CHANNEL_IO_PORT_2, type +#define NATURE_IO_CRITTER_2_BEND_PITCH(bend) NATURE_CHANNEL_CRITTER_2, CHANNEL_IO_PORT_3, bend +#define NATURE_IO_CRITTER_2_NUM_LAYERS(num) NATURE_CHANNEL_CRITTER_2, CHANNEL_IO_PORT_4, num +#define NATURE_IO_CRITTER_2_PORT5(reverb) NATURE_CHANNEL_CRITTER_2, CHANNEL_IO_PORT_5, reverb + +#define NATURE_IO_CRITTER_3_TYPE(type) NATURE_CHANNEL_CRITTER_3, CHANNEL_IO_PORT_2, type +#define NATURE_IO_CRITTER_3_BEND_PITCH(bend) NATURE_CHANNEL_CRITTER_3, CHANNEL_IO_PORT_3, bend +#define NATURE_IO_CRITTER_3_NUM_LAYERS(num) NATURE_CHANNEL_CRITTER_3, CHANNEL_IO_PORT_4, num +#define NATURE_IO_CRITTER_3_PORT5(reverb) NATURE_CHANNEL_CRITTER_3, CHANNEL_IO_PORT_5, reverb + +#define NATURE_IO_CRITTER_4_TYPE(type) NATURE_CHANNEL_CRITTER_4, CHANNEL_IO_PORT_2, type +#define NATURE_IO_CRITTER_4_BEND_PITCH(bend) NATURE_CHANNEL_CRITTER_4, CHANNEL_IO_PORT_3, bend +#define NATURE_IO_CRITTER_4_NUM_LAYERS(num) NATURE_CHANNEL_CRITTER_4, CHANNEL_IO_PORT_4, num +#define NATURE_IO_CRITTER_4_PORT5(reverb) NATURE_CHANNEL_CRITTER_4, CHANNEL_IO_PORT_5, reverb + +#define NATURE_IO_CRITTER_5_TYPE(type) NATURE_CHANNEL_CRITTER_5, CHANNEL_IO_PORT_2, type +#define NATURE_IO_CRITTER_5_BEND_PITCH(bend) NATURE_CHANNEL_CRITTER_5, CHANNEL_IO_PORT_3, bend +#define NATURE_IO_CRITTER_5_NUM_LAYERS(num) NATURE_CHANNEL_CRITTER_5, CHANNEL_IO_PORT_4, num +#define NATURE_IO_CRITTER_5_PORT5(reverb) NATURE_CHANNEL_CRITTER_5, CHANNEL_IO_PORT_5, reverb + +#define NATURE_IO_CRITTER_6_TYPE(type) NATURE_CHANNEL_CRITTER_6, CHANNEL_IO_PORT_2, type +#define NATURE_IO_CRITTER_6_BEND_PITCH(bend) NATURE_CHANNEL_CRITTER_6, CHANNEL_IO_PORT_3, bend +#define NATURE_IO_CRITTER_6_NUM_LAYERS(num) NATURE_CHANNEL_CRITTER_6, CHANNEL_IO_PORT_4, num +#define NATURE_IO_CRITTER_6_PORT5(reverb) NATURE_CHANNEL_CRITTER_6, CHANNEL_IO_PORT_5, reverb + +#define NATURE_IO_STREAM_0_TYPE(type) NATURE_CHANNEL_STREAM_0, CHANNEL_IO_PORT_2, type +#define NATURE_IO_STREAM_0_PORT3(data) NATURE_CHANNEL_STREAM_0, CHANNEL_IO_PORT_3, data +#define NATURE_IO_STREAM_0_PORT4(data) NATURE_CHANNEL_STREAM_0, CHANNEL_IO_PORT_4, data + +#define NATURE_IO_STREAM_1_TYPE(type) NATURE_CHANNEL_STREAM_1, CHANNEL_IO_PORT_2, type +#define NATURE_IO_STREAM_1_PORT3(data) NATURE_CHANNEL_STREAM_1, CHANNEL_IO_PORT_3, data +#define NATURE_IO_STREAM_1_PORT4(data) NATURE_CHANNEL_STREAM_1, CHANNEL_IO_PORT_4, data #define NATURE_IO_ENTRIES_END 0xFF diff --git a/src/audio/game/general.c b/src/audio/game/general.c index 2e58289d27b..45854c4443f 100644 --- a/src/audio/game/general.c +++ b/src/audio/game/general.c @@ -3907,15 +3907,15 @@ void Audio_DisableAllSeq(void) { AudioThread_ScheduleProcessCmds(); } -s8 func_800F6BB8(void) { - return func_800E6680(); +s8 Audio_GetActiveNotes(void) { + return AudioThread_GetActiveNotes(); } -void func_800F6BDC(void) { +void Audio_StopWaitAllSeq(void) { Audio_DisableAllSeq(); AudioThread_ScheduleProcessCmds(); while (true) { - if (!func_800F6BB8()) { + if (!Audio_GetActiveNotes()) { return; } } diff --git a/src/audio/internal/thread.c b/src/audio/internal/thread.c index f1461179e18..38f641f48cc 100644 --- a/src/audio/internal/thread.c +++ b/src/audio/internal/thread.c @@ -17,7 +17,7 @@ void AudioThread_SetFadeOutTimer(s32 seqPlayerIndex, s32 fadeTimer); void AudioThread_ProcessCmds(u32); void AudioThread_ProcessSeqPlayerCmd(SequencePlayer* seqPlayer, AudioCmd* cmd); void AudioThread_ProcessChannelCmd(SequenceChannel* channel, AudioCmd* cmd); -s32 func_800E66C0(s32 flags); +s32 AudioThread_NoteReleaseCheck(s32 flags); // AudioMgr_Retrace AudioTask* AudioThread_Update(void) { @@ -322,7 +322,7 @@ void AudioThread_ProcessGlobalCmd(AudioCmd* cmd) { } } } - func_800E66C0(flags); + AudioThread_NoteReleaseCheck(flags); break; case AUDIOCMD_OP_GLOBAL_POP_PERSISTENT_CACHE: @@ -890,27 +890,33 @@ s32 func_800E6590(s32 seqPlayerIndex, s32 channelIndex, s32 layerIndex) { /** * original name possibly "Nap_SilenceCheck" + * @returns The number of actively playing notes. */ -s32 func_800E6680(void) { - return func_800E66C0(0); +s32 AudioThread_GetActiveNotes(void) { + return AudioThread_NoteReleaseCheck(0); } -void func_800E66A0(void) { - func_800E66C0(2); +void AudioThread_GetActiveNonsynthNotes(void) { + AudioThread_NoteReleaseCheck(2); } /** * original name: Nap_SilenceCheck_Inner + * Deals with releasing notes. + * @param flags If this is >= 2, synthetic notes already loaded in RAM are skipped. If this has its first bit set, + * all the notes that are currently playing are set to release at the same speed. + * @returns The number of active notes (notes that are still going through their ADSR envelope). + * If the first bit of flags is set, it's the number of notes that have been set to release. */ -s32 func_800E66C0(s32 flags) { - s32 phi_v1; +s32 AudioThread_NoteReleaseCheck(s32 flags) { + s32 numReleasedNotes; NotePlaybackState* playbackState; NoteSubEu* noteSubEu; s32 i; Note* note; TunedSample* tunedSample; - phi_v1 = 0; + numReleasedNotes = 0; for (i = 0; i < gAudioCtx.numNotes; i++) { note = &gAudioCtx.notes[i]; playbackState = ¬e->playbackState; @@ -927,7 +933,7 @@ s32 func_800E66C0(s32 flags) { } } - phi_v1++; + numReleasedNotes++; if ((flags & 1) == 1) { playbackState->adsr.fadeOutVel = gAudioCtx.audioBufferParameters.ticksPerUpdateInv; playbackState->adsr.action.s.release = 1; @@ -935,7 +941,7 @@ s32 func_800E66C0(s32 flags) { } } } - return phi_v1; + return numReleasedNotes; } /** diff --git a/src/n64dd/z_n64dd.c b/src/n64dd/z_n64dd.c index d854bb5afb5..2992e9c46c1 100644 --- a/src/n64dd/z_n64dd.c +++ b/src/n64dd/z_n64dd.c @@ -81,7 +81,7 @@ void n64dd_gfxHook(Gfx** gfxP) { // see game.c */ void n64dd_stopSound(void) { if (isSoundStopped == 0) { - func_800F6BDC(); // <- audio engine code. + Audio_StopWaitAllSeq(); isSoundStopped = 1; } } @@ -111,7 +111,7 @@ void n64dd_waitForSound(void) { void n64dd_playSfx(void) { if (isSoundStopped != 0) { isSoundStopped = 0; - func_800F6B3C(); // <- audio engine code. + func_800F6B3C(); // play sfx #0 with a 5s fadein } } From ca0a4bbdb7dcdcad475997862af101f2f9bfb8eb Mon Sep 17 00:00:00 2001 From: scudo <96631443+scudo005@users.noreply.github.com> Date: Sat, 25 Apr 2026 12:11:20 +0200 Subject: [PATCH 5/5] Textbox work --- include/n64dd.h | 2 +- src/n64dd/n64dd_801CA0B0.c | 190 ++++++++++++++++++++++--------------- src/n64dd/z_n64dd.c | 21 ++-- 3 files changed, 127 insertions(+), 86 deletions(-) diff --git a/include/n64dd.h b/include/n64dd.h index 3e78ff89c91..d39c1ce8fdf 100644 --- a/include/n64dd.h +++ b/include/n64dd.h @@ -142,7 +142,7 @@ u8* func_801C9FFC(void); u8* func_801CA030(s32 errorNum); u8* func_801CA070(void); -void func_801CA1F0(void* charTexBuf, s32 posX, s32 posY, s32 dx, s32 dy, s32 cy, void* frameBuf, s32 screenWidth); +void n64dd_printTextFB(void* charTexBuf, s32 posX, s32 posY, s32 dx, s32 dy, s32 cy, void* frameBuf, s32 screenWidth); extern n64ddStruct_800FEE70_pointers D_800FEE70; extern n64ddStruct_80121220* B_80121220; diff --git a/src/n64dd/n64dd_801CA0B0.c b/src/n64dd/n64dd_801CA0B0.c index 8252def9e54..5d250915d04 100644 --- a/src/n64dd/n64dd_801CA0B0.c +++ b/src/n64dd/n64dd_801CA0B0.c @@ -6,7 +6,7 @@ #include "color.h" // Draws text to framebuffer -typedef struct struct_801CA704 { +typedef struct n64dd_Textbox { /* 0x00 */ PrintCallback callback; /* 0x04 */ void* charTexBuf; /* 0x08 */ u16 unk_08; @@ -21,10 +21,10 @@ typedef struct struct_801CA704 { /* 0x20 */ void* frameBuf; /* 0x24 */ u16 screenWidth; /* 0x26 */ u16 screenHeight; -} struct_801CA704; +} n64dd_Textbox; // clang-format off -u32 D_801D8BE0[0x5F] = { +u32 charTexOffset[0x5F] = { 0x00009D14, 0x00232A14, 0x00296314, 0x002F8A14, 0x00457E18, 0x0063CA14, 0x0084AA14, 0x00A03314, 0x00A45E14, 0x00BB4E14, 0x00CA6514, 0x00D3770E, 0x00E33302, 0x00E78108, 0x00EB2102, 0x00EC6C14, 0x01008A14, 0x01163A14, 0x01217A14, 0x01377A14, 0x014D8A14, 0x01638A14, 0x01798A14, 0x018F7A14, @@ -40,8 +40,15 @@ u32 D_801D8BE0[0x5F] = { }; // clang-format on -// Loads character texture to buffer -s32 func_801CA0B0(s32 charCode, void* charTexBuf, int* dx, int* dy, int* cy) { +/** + * Loads character texture to buffer. + * @param charCode What character + * @param charTexBuf Buffer for loading the character texture + * @param dx x offset for the character in the textbox + * @param dy y offset for the character in the textbox + * @param cy y offset of the textbox (?) + */ +s32 n64dd_loadCharTex(s32 charCode, void* charTexBuf, int* dx, int* dy, int* cy) { s32 offset; OSPiHandle* handle; OSMesgQueue queue; @@ -50,7 +57,7 @@ s32 func_801CA0B0(s32 charCode, void* charTexBuf, int* dx, int* dy, int* cy) { handle = osDriveRomInit(); if (charCode >= 0x20 && charCode < 0x7F) { // ASCII - offset = LeoGetAAdr2(D_801D8BE0[charCode - 0x20], dx, dy, cy); + offset = LeoGetAAdr2(charTexOffset[charCode - 0x20], dx, dy, cy); } else if (charCode >= 0x8140) { // Shift-JIS offset = LeoGetKAdr(charCode); *dx = 16; @@ -77,17 +84,28 @@ s32 func_801CA0B0(s32 charCode, void* charTexBuf, int* dx, int* dy, int* cy) { return 0; } -const u16 D_801D9390[16] = { +const u16 intensColorMap[16] = { 0x0001, 0x1085, 0x2109, 0x318D, 0x4211, 0x5295, 0x6319, 0x739D, 0x8C63, 0x9CE7, 0xAD6B, 0xBDEF, 0xCE73, 0xDEF7, 0xEF7B, 0xFFFF, }; // Maps 4-bit intensity to a 16-bit color -u16 func_801CA1D4(u32 arg0) { - return D_801D9390[arg0 % ARRAY_COUNT(D_801D9390)]; +u16 n64dd_mapIntensToColor(u32 arg0) { + return intensColorMap[arg0 % ARRAY_COUNT(intensColorMap)]; } -void func_801CA1F0(void* charTexBuf, s32 posX, s32 posY, s32 dx, s32 dy, s32 cy, void* frameBuf, s32 screenWidth) { +/** + * Prints text to the framebuffer. + * @param charTexBuf Buffer with all the characters to print + * @param posX x position of the textbox + * @param posY y position of the textbox + * @param dx x offset of the characters in the textbox + * @param dy y offset of the characters in the textbox + * @param cy y offset of the textbox (?) + * @param frameBuf Framebuffer + * @param screenWidth The width of the screen + */ +void n64dd_printTextFB(void* charTexBuf, s32 posX, s32 posY, s32 dx, s32 dy, s32 cy, void* frameBuf, s32 screenWidth) { s32 intensity; s32 x; s32 y; @@ -102,7 +120,7 @@ void func_801CA1F0(void* charTexBuf, s32 posX, s32 posY, s32 dx, s32 dy, s32 cy, intensity = *src & 0xF; src++; } - dst[posX + x + ((posY + (11 - cy) + y) * screenWidth)] = func_801CA1D4(intensity); + dst[posX + x + ((posY + (11 - cy) + y) * screenWidth)] = n64dd_mapIntensToColor(intensity); } if (dx & 1) { src++; @@ -110,83 +128,87 @@ void func_801CA1F0(void* charTexBuf, s32 posX, s32 posY, s32 dx, s32 dy, s32 cy, } } -void func_801CA2F8(struct_801CA704* arg0, u32 r, u32 g, u32 b, u32 a) { - arg0->color.r = r; - arg0->color.g = g; - arg0->color.b = b; - arg0->color.a = a; +void n64dd_setTextboxColor(n64dd_Textbox* textbox, u32 r, u32 g, u32 b, u32 a) { + textbox->color.r = r; + textbox->color.g = g; + textbox->color.b = b; + textbox->color.a = a; } -void func_801CA314(struct_801CA704* arg0, s32 arg1, s32 arg2) { - arg0->posX = arg0->baseX + arg1; - arg0->posY = arg0->baseY + arg2; +void n64dd_setTextboxOffset(n64dd_Textbox* textbox, s32 arg1, s32 arg2) { + textbox->posX = textbox->baseX + arg1; + textbox->posY = textbox->baseY + arg2; } -void func_801CA334(struct_801CA704* arg0, s32 baseX, s32 baseY, s32 endX, s32 endY) { - arg0->baseX = baseX; - arg0->baseY = baseY; - arg0->endX = endX; - arg0->endY = endY; +void n64dd_setTextboxBaseDimension(n64dd_Textbox* textbox, s32 baseX, s32 baseY, s32 endX, s32 endY) { + textbox->baseX = baseX; + textbox->baseY = baseY; + textbox->endX = endX; + textbox->endY = endY; } -void func_801CA350(struct_801CA704* arg0, void* frameBuf, s32 screenWidth, s32 screenHeight) { - arg0->frameBuf = (u8*)frameBuf + 0x20000000; - arg0->screenWidth = screenWidth; - arg0->screenHeight = screenHeight; - func_801CA334(arg0, 0, 0, screenWidth - 1, screenHeight - 1); +// moves the textbox to a secondary framebuffer +void n64dd_moveTextboxFB(n64dd_Textbox* textbox, void* frameBuf, s32 screenWidth, s32 screenHeight) { + textbox->frameBuf = (u8*)frameBuf + 0x20000000; + textbox->screenWidth = screenWidth; + textbox->screenHeight = screenHeight; + n64dd_setTextboxBaseDimension(textbox, 0, 0, screenWidth - 1, screenHeight - 1); } -void func_801CA3B4(struct_801CA704* arg0, void* charTexBuf, s32 arg2) { - arg0->charTexBuf = (u8*)charTexBuf + 0x20000000; - arg0->unk_08 = arg2; +void func_801CA3B4(n64dd_Textbox* textbox, void* charTexBuf, s32 arg2) { + textbox->charTexBuf = (u8*)charTexBuf + 0x20000000; + textbox->unk_08 = arg2; } -void func_801CA3CC(struct_801CA704* arg0, char c) { +// remove invalid characters, insert spaces +void n64dd_textboxPrintSpaces(n64dd_Textbox* textbox, char c) { s32 charCode; int dx; int dy; int cy; - if (arg0->sjisPrevByte != 0) { - charCode = (arg0->sjisPrevByte << 8) | c; + if (textbox->sjisPrevByte != 0) { + charCode = (textbox->sjisPrevByte << 8) | c; } else { if (c >= 0x80 && c < 0x99) { - arg0->sjisPrevByte = c; + textbox->sjisPrevByte = c; return; } charCode = c; } - arg0->sjisPrevByte = 0; - if (func_801CA0B0(charCode, arg0->charTexBuf, &dx, &dy, &cy) == 0) { - if (arg0->posX + dx > arg0->endX) { - arg0->posX = arg0->baseX; - if (arg0->posY + 16 > arg0->endY) { - arg0->posY = arg0->baseY; + textbox->sjisPrevByte = 0; + if (n64dd_loadCharTex(charCode, textbox->charTexBuf, &dx, &dy, &cy) == 0) { + if (textbox->posX + dx > textbox->endX) { + textbox->posX = textbox->baseX; + if (textbox->posY + 16 > textbox->endY) { + textbox->posY = textbox->baseY; } else { - arg0->posY += 16; + textbox->posY += 16; } } - func_801CA1F0(arg0->charTexBuf, arg0->posX, arg0->posY, dx, dy, cy, arg0->frameBuf, arg0->screenWidth); - arg0->posX += (dx == 16 ? dx : dx + 2); + n64dd_printTextFB(textbox->charTexBuf, textbox->posX, textbox->posY, dx, dy, cy, textbox->frameBuf, + textbox->screenWidth); + textbox->posX += (dx == 16 ? dx : dx + 2); } } -void func_801CA4F4(struct_801CA704* arg0, char c) { +// escape tabs, newlines, carriage returns +void n64dd_textboxEscapeChar(n64dd_Textbox* textbox, char c) { if (c >= ' ' && c <= 0xFF) { - func_801CA3CC(arg0, c); + n64dd_textboxPrintSpaces(textbox, c); } else { switch (c) { case '\n': - arg0->posY += 32; + textbox->posY += 32; FALLTHROUGH; case '\r': - arg0->posX = arg0->baseX; + textbox->posX = textbox->baseX; break; case '\t': do { - func_801CA3CC(arg0, ' '); - } while ((arg0->posX - arg0->baseX) % 256); + n64dd_textboxPrintSpaces(textbox, ' '); + } while ((textbox->posX - textbox->baseX) % 256); break; case '\0': break; @@ -194,53 +216,71 @@ void func_801CA4F4(struct_801CA704* arg0, char c) { } } -void func_801CA5BC(struct_801CA704* arg0, const char* str, s32 arg2, size_t count) { +/** + * Escapes all whitespaces, tabs, carriage returns, newlines, etc. from a textbox. + * @param textbox The textbox + * @param str The string to escape + * @param nChars The number of characters in the string + * @param count sizeof(char) + */ +void n64dd_textboxEscapeText(n64dd_Textbox* textbox, const char* str, s32 nChars, size_t count) { const char* s = str; - s32 n = arg2 * count; + s32 n = nChars * count; while (n != 0) { - func_801CA4F4(arg0, *s++); + n64dd_textboxEscapeChar(textbox, *s++); n--; } } -void func_801CA618(struct_801CA704* arg0, const char* str) { +/** + * Escapes all whitespaces, tabs, carriage returns, newlines, etc. from a textbox. + * Equivalent to n64dd_textboxEscapeText + */ +void n64dd_textboxEscapeStrings(n64dd_Textbox* textbox, const char* str) { while (*str != 0) { - func_801CA4F4(arg0, *str++); + n64dd_textboxEscapeChar(textbox, *str++); } } -void* func_801CA670(void* arg, const char* str, size_t count) { - func_801CA5BC(arg, str, 1, count); - return arg; +/** + * Escape a textbox. + * @param textbox the textbox + * @param str the string to escape + * @param count sizeof(char) + * @returns the escaped textbox + */ +void* n64dd_getEscapedTextbox(void* textbox, const char* str, size_t count) { + n64dd_textboxEscapeText(textbox, str, 1, count); + return textbox; } -void func_801CA6A0(struct_801CA704* arg0) { - arg0->callback = &func_801CA670; - arg0->posX = 0; - arg0->posY = 0; - arg0->baseX = 0; - arg0->baseY = 0; - arg0->endX = 0; - arg0->endY = 0; - arg0->color.rgba = 0; - arg0->sjisPrevByte = 0; - arg0->charTexBuf = NULL; +void n64dd_initTextbox(n64dd_Textbox* textbox) { + textbox->callback = &n64dd_getEscapedTextbox; + textbox->posX = 0; + textbox->posY = 0; + textbox->baseX = 0; + textbox->baseY = 0; + textbox->endX = 0; + textbox->endY = 0; + textbox->color.rgba = 0; + textbox->sjisPrevByte = 0; + textbox->charTexBuf = NULL; } -void func_801CA6D8(struct_801CA704* arg0) { +void n64dd_textboxEmpty(n64dd_Textbox* textbox) { } -s32 func_801CA6E4(struct_801CA704* arg0, const char* fmt, va_list args) { - return PrintUtils_VPrintf(&arg0->callback, fmt, args); +s32 n64dd_textboxVPrintfInternal(n64dd_Textbox* textbox, const char* fmt, va_list args) { + return PrintUtils_VPrintf(&textbox->callback, fmt, args); } -s32 func_801CA704(struct_801CA704* arg0, const char* fmt, ...) { +s32 n64dd_textboxVPrintf(n64dd_Textbox* textbox, const char* fmt, ...) { s32 ret; va_list args; va_start(args, fmt); - ret = func_801CA6E4(arg0, fmt, args); + ret = n64dd_textboxVPrintfInternal(textbox, fmt, args); va_end(args); return ret; diff --git a/src/n64dd/z_n64dd.c b/src/n64dd/z_n64dd.c index 2992e9c46c1..332b70a542d 100644 --- a/src/n64dd/z_n64dd.c +++ b/src/n64dd/z_n64dd.c @@ -295,13 +295,13 @@ void n64dd_printText(void* pCharsRow1, void* pCharsRow2, void* pCharsRow3) { currentTime = osGetTime(); } if (pCharsRow1 != NULL) { - func_801CA1F0(pCharsRow1, 96, 32, 192, 16, 11, pNextFrameBuf, SCREEN_WIDTH); + n64dd_printTextFB(pCharsRow1, 96, 32, 192, 16, 11, pNextFrameBuf, SCREEN_WIDTH); } if (pCharsRow2 != NULL) { - func_801CA1F0(pCharsRow2, 0, 80, 320, 64, 11, pNextFrameBuf, SCREEN_WIDTH); + n64dd_printTextFB(pCharsRow2, 0, 80, 320, 64, 11, pNextFrameBuf, SCREEN_WIDTH); } if (pCharsRow3 != NULL) { - func_801CA1F0(pCharsRow3, 0, 176, 320, 32, 11, pNextFrameBuf, SCREEN_WIDTH); + n64dd_printTextFB(pCharsRow3, 0, 176, 320, 32, 11, pNextFrameBuf, SCREEN_WIDTH); } #if OOT_VERSION < PAL_1_0 osViBlack(0); @@ -451,8 +451,8 @@ void func_801C7920(s32 arg0, void* arg1, s32 arg2) { } } -void func_801C79CC(void* arg0, s32 arg1, s32 arg2) { - drivePacketData.pReadBuf = arg0; +void n64dd_cmd4(void* readBuf, s32 arg1, s32 arg2) { + drivePacketData.pReadBuf = readBuf; drivePacketData.pCmdParam1 = (void*)arg1; drivePacketData.pCmdParam2 = (void*)arg2; drivePacketData.cmdType = 4; @@ -530,12 +530,13 @@ s32 n64dd_offsetToBlock(s32 startLba, s32* adjustedLbaCount, s32* lba) { * @param startLba The starting LBA * @returns The corresponding byte offset if the read was successful, else returns 0. */ -s32 n64dd_LbaToByte(s32 startLba) s32 bytes; +s32 n64dd_LbaToByte(s32 startLba) { + s32 bytes; -if (LeoLBAToByte(startLba, 1, &bytes) == LEO_ERROR_GOOD) { - return bytes; -} -return 0; + if (LeoLBAToByte(startLba, 1, &bytes) == LEO_ERROR_GOOD) { + return bytes; + } + return 0; } /**