mirror of
https://github.com/zeldaret/oot.git
synced 2024-11-25 09:45:02 +00:00
[ntsc-1.2] Import n64dd code from Decompollaborate/n64dd (#2136)
* Import n64dd code from Decompollaborate/n64dd Co-authored-by: Anghelo Carvajal <angheloalf95@gmail.com> Co-authored-by: Elliptic Ellipsis <elliptic.ellipsis@gmail.com> * Don't stub out missing textures * Remove @brief * Add low-effort file comments * Match OoT if style * Fix n64dd matching due to int vs long * Fix English n64dd error textures * Compress n64dd segment * Align n64dd to 0x40 --------- Co-authored-by: Anghelo Carvajal <angheloalf95@gmail.com> Co-authored-by: Elliptic Ellipsis <elliptic.ellipsis@gmail.com>
This commit is contained in:
parent
c27b83ac29
commit
e52d135e15
22 changed files with 2199 additions and 30 deletions
8
assets/xml/n64dd/error_textures.xml
Normal file
8
assets/xml/n64dd/error_textures.xml
Normal file
|
@ -0,0 +1,8 @@
|
|||
<Root>
|
||||
<File Name="n64dd" OutName="n64dd_error_textures">
|
||||
<Texture Name="gN64DDError41JPNTex" OutName="n64dd_error_41_jpn" Format="i4" Width="192" Height="16" Offset="0x0"/>
|
||||
<Texture Name="gN64DDError41ENGTex" OutName="n64dd_error_41_eng" Format="i4" Width="192" Height="16" Offset="0x600"/>
|
||||
<Texture Name="gN64DDPleaseReadManualJPNTex" OutName="n64dd_please_read_manual_jpn" Format="i4" Width="320" Height="64" Offset="0xC00"/>
|
||||
<Texture Name="gN64DDPleaseReadManualENGTex" OutName="n64dd_please_read_manual_eng" Format="i4" Width="320" Height="64" Offset="0x3400"/>
|
||||
</File>
|
||||
</Root>
|
|
@ -75,6 +75,10 @@ assets:
|
|||
xml_path: assets/xml/code/fbdemo_wipe1.xml
|
||||
start_offset: 0xEB610
|
||||
end_offset: 0xEBFA0
|
||||
- name: n64dd/error_textures
|
||||
xml_path: assets/xml/n64dd/error_textures.xml
|
||||
start_offset: 0xC120
|
||||
end_offset: 0x11D20
|
||||
- name: misc/link_animetion
|
||||
xml_path: assets/xml/misc/link_animetion.xml
|
||||
- name: misc/z_select_static
|
||||
|
|
|
@ -32,7 +32,7 @@ def ExtractFile(assetConfig: version_config.AssetConfig, outputPath: Path, outpu
|
|||
|
||||
execStr = f"{zapdPath} e -eh -i {xmlPath} -b {globalBaseromSegmentsDir} -o {outputPath} -osf {outputSourcePath} -gsf 1 -rconf {configPath} --cs-float both {ZAPDArgs}"
|
||||
|
||||
if name.startswith("code/") or name.startswith("overlays/"):
|
||||
if name.startswith("code/") or name.startswith("n64dd/") or name.startswith("overlays/"):
|
||||
assert assetConfig.start_offset is not None
|
||||
assert assetConfig.end_offset is not None
|
||||
|
||||
|
|
|
@ -1395,6 +1395,8 @@ void Audio_SetCutsceneFlag(s8 flag);
|
|||
void Audio_PlaySfxIfNotInCutscene(u16 sfxId);
|
||||
void func_800F6964(u16);
|
||||
void Audio_StopBgmAndFanfare(u16 fadeOutDuration);
|
||||
void func_800F6B3C(void);
|
||||
void func_800F6BDC(void);
|
||||
void Audio_PreNMI(void);
|
||||
void Audio_SetNatureAmbienceChannelIO(u8 channelIdxRange, u8 ioPort, u8 ioData);
|
||||
void Audio_PlayNatureAmbienceSequence(u8 natureAmbienceId);
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define N64DD_H
|
||||
|
||||
#include "ultra64.h"
|
||||
#include "ultra64/leo.h"
|
||||
#include "z64pause.h"
|
||||
#include "z64scene.h"
|
||||
#include "z64map_mark.h"
|
||||
|
@ -59,6 +60,35 @@ typedef struct n64ddStruct_80121220 {
|
|||
s32 (*unk_78)(struct PlayState*, void*, void*);
|
||||
} n64ddStruct_80121220; // size = ?
|
||||
|
||||
typedef struct struct_801E0D18 {
|
||||
/* 0x00 */ LEOCmd unk_00;
|
||||
/* 0x1C */ OSMesgQueue unk_1C;
|
||||
/* 0x38 */ LEODiskID diskId;
|
||||
/* 0x58 */ UNK_TYPE unk_58;
|
||||
/* 0x5C */ UNK_TYPE unk_5C;
|
||||
/* 0x60 */ u32 unk_60;
|
||||
/* 0x64 */ u8 unk_64;
|
||||
/* 0x65 */ u8 unk_65;
|
||||
/* 0x66 */ u8 unk_66;
|
||||
/* 0x68 */ s32 unk_68;
|
||||
/* 0x6C */ s32 unk_6C;
|
||||
} struct_801E0D18; // size = 0x70
|
||||
|
||||
typedef struct struct_801D9D50 {
|
||||
/* 0x00 */ u8 unk_00; // command enum
|
||||
/* 0x04 */ s32 unk_04;
|
||||
/* 0x08 */ u8 unk_08;
|
||||
/* 0x0C */ void (*unk_0C)(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;
|
||||
} struct_801D9D50; // size = 0x30
|
||||
|
||||
void func_800AD410(void);
|
||||
void func_800AD488(void);
|
||||
n64ddStruct_80121220* func_800AD4C0(n64ddStruct_80121220* arg0);
|
||||
|
@ -77,6 +107,35 @@ 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_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_801C8AA8(void);
|
||||
s32 func_801C91E0(struct_801E0D18*);
|
||||
s32 func_801C9260(struct_801E0D18*);
|
||||
s32 func_801C9334(struct_801E0D18*);
|
||||
s32 func_801C93C4(struct_801E0D18*);
|
||||
|
||||
void func_801C94F8(u8* arg0, u16 arg1);
|
||||
void func_801C9A10(u8* arg0, s32 arg1, u8* str);
|
||||
void func_801C9B50(s32 arg0, void (*arg1)(void*, uintptr_t, size_t));
|
||||
|
||||
u8* func_801C9E28(s32 errorNum);
|
||||
u8* func_801C9EC0(void);
|
||||
u8* func_801C9F90(s32 errorNum);
|
||||
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);
|
||||
|
||||
extern n64ddStruct_800FEE70_pointers D_800FEE70;
|
||||
extern n64ddStruct_80121220* B_80121220;
|
||||
|
||||
|
@ -86,4 +145,25 @@ extern u8 D_80121212;
|
|||
extern vu8 D_80121213;
|
||||
extern vu8 D_80121214;
|
||||
|
||||
extern s32 (*D_801D2E54)(struct_801E0D18*);
|
||||
|
||||
extern u8 B_801DC000[];
|
||||
|
||||
extern s32 D_801D2E90;
|
||||
extern OSMesgQueue* B_801E0D10[2];
|
||||
|
||||
extern s32 D_801D2EA0;
|
||||
extern s32 D_801D2EA8;
|
||||
extern s32 B_801E0F60;
|
||||
extern s32 B_801E0F64;
|
||||
extern void (*D_801D2EB4)(void*, void*, void*);
|
||||
|
||||
// Error messages
|
||||
extern const char* D_801D2ED0[]; // "Error Number " array
|
||||
extern const char* D_801D2EE0[2][8][4]; // Array of error message strings
|
||||
|
||||
// Error textures
|
||||
extern u64 gN64DDError41Texs[2][0x600 / sizeof(u64)];
|
||||
extern u64 gN64DDPleaseReadManualTexs[2][0x2800 / sizeof(u64)];
|
||||
|
||||
#endif
|
||||
|
|
|
@ -203,6 +203,7 @@ extern PreNmiBuff* gAppNmiBufferPtr;
|
|||
extern uintptr_t gSegments[NUM_SEGMENTS];
|
||||
extern Scheduler gScheduler;
|
||||
extern PadMgr gPadMgr;
|
||||
extern IrqMgr gIrqMgr;
|
||||
extern volatile OSTime gAudioThreadUpdateTimeTotalPerGfxTask;
|
||||
extern volatile OSTime gGfxTaskSentToNextReadyMinusAudioThreadUpdateTime;
|
||||
extern volatile OSTime gRSPAudioTimeTotal;
|
||||
|
|
|
@ -76,6 +76,8 @@
|
|||
#define THREAD_PRI_DMAMGR_LOW 10 // Used when decompressing files
|
||||
#define THREAD_PRI_GRAPH 11
|
||||
#define THREAD_PRI_AUDIOMGR 12
|
||||
#define THREAD_PRI_N64DD 13
|
||||
#define THREAD_PRI_DDMSG 13
|
||||
#define THREAD_PRI_PADMGR 14
|
||||
#define THREAD_PRI_MAIN 15
|
||||
#define THREAD_PRI_SCHED 15
|
||||
|
@ -90,6 +92,8 @@
|
|||
#define THREAD_ID_GRAPH 4
|
||||
#define THREAD_ID_SCHED 5
|
||||
#define THREAD_ID_PADMGR 7
|
||||
#define THREAD_ID_N64DD 8
|
||||
#define THREAD_ID_DDMSG 9
|
||||
#define THREAD_ID_AUDIOMGR 10
|
||||
#define THREAD_ID_DMAMGR 18
|
||||
#define THREAD_ID_IRQMGR 19
|
||||
|
|
13
spec
13
spec
|
@ -788,7 +788,18 @@ endseg
|
|||
#if PLATFORM_N64
|
||||
beginseg
|
||||
name "n64dd"
|
||||
// TODO: remaining n64dd files
|
||||
compress
|
||||
align 0x40
|
||||
include "$(BUILD_DIR)/src/n64dd/z_n64dd.o"
|
||||
include "$(BUILD_DIR)/src/n64dd/n64dd_data_buffer.o"
|
||||
include "$(BUILD_DIR)/src/n64dd/n64dd_801C8000.o"
|
||||
include "$(BUILD_DIR)/src/n64dd/n64dd_801C8940.o"
|
||||
include "$(BUILD_DIR)/src/n64dd/n64dd_801C9440.o"
|
||||
include "$(BUILD_DIR)/src/n64dd/n64dd_801C9B70.o"
|
||||
include "$(BUILD_DIR)/src/n64dd/n64dd_error_headers.o"
|
||||
include "$(BUILD_DIR)/src/n64dd/n64dd_error_bodies.o"
|
||||
include "$(BUILD_DIR)/src/n64dd/n64dd_error_textures.o"
|
||||
include "$(BUILD_DIR)/src/n64dd/n64dd_801CA0B0.o"
|
||||
include "$(BUILD_DIR)/src/libleo/api/readwrite.o"
|
||||
include "$(BUILD_DIR)/src/libleo/leo/leofunc.o"
|
||||
include "$(BUILD_DIR)/src/libleo/leo/leoram.o"
|
||||
|
|
345
src/n64dd/n64dd_801C8000.c
Normal file
345
src/n64dd/n64dd_801C8000.c
Normal file
|
@ -0,0 +1,345 @@
|
|||
// Does some command processing
|
||||
#include "global.h"
|
||||
#include "n64dd.h"
|
||||
#include "versions.h"
|
||||
|
||||
void func_801C8554(void);
|
||||
void func_801C8578(void* arg0, void* arg1, OSId id, void* sp, OSPri pri);
|
||||
void func_801C8638(void (*arg0)(void*, void*, void*), s32 arg1, void (*arg2)(void*, uintptr_t, size_t));
|
||||
void func_801C868C(void* arg0, void* arg1, void* arg2, u8 arg3);
|
||||
s8 func_801C8770(void);
|
||||
s32 func_801C87C0(void);
|
||||
s32 func_801C87FC(void);
|
||||
s32 func_801C8844(void);
|
||||
s32 func_801C885C(void);
|
||||
s32 func_801C88AC(void);
|
||||
s32 func_801C88FC(void);
|
||||
|
||||
s32 D_801D2E60 = 0;
|
||||
s32 D_801D2E64 = 0;
|
||||
|
||||
typedef struct struct_801D2E68 {
|
||||
/* 0x0 */ void (*unk_0)(struct_801E0D18*);
|
||||
/* 0x4 */ s32 (*unk_4)(struct_801E0D18*);
|
||||
} struct_801D2E68; // size = 0x8
|
||||
|
||||
struct_801D2E68 D_801D2E68[5] = {
|
||||
{ func_801C81EC, func_801C91E0 }, { func_801C832C, func_801C9260 }, { func_801C83A0, func_801C9260 },
|
||||
{ func_801C8414, func_801C9334 }, { func_801C8414, func_801C93C4 },
|
||||
};
|
||||
|
||||
s32 D_801D2E90 = 0;
|
||||
|
||||
OSMesgQueue* B_801E0D10[2];
|
||||
struct_801E0D18 B_801E0D18;
|
||||
OSMesg B_801E0D88[1];
|
||||
OSMesg B_801E0D90[8];
|
||||
OSThread B_801E0DB0;
|
||||
|
||||
s32 func_801C8000(struct_801D9D50* arg0) {
|
||||
switch (arg0->unk_00) {
|
||||
case 0:
|
||||
if (func_801C8844() != 0) {
|
||||
return 1;
|
||||
}
|
||||
func_801C8554();
|
||||
break;
|
||||
case 1:
|
||||
func_801C8578(arg0->unk_1C, arg0->unk_20, arg0->unk_24, arg0->unk_28, arg0->unk_2C);
|
||||
break;
|
||||
case 2:
|
||||
func_801C8638(arg0->unk_0C, arg0->unk_10, arg0->unk_14);
|
||||
break;
|
||||
case 3:
|
||||
if (func_801C8844() != 0) {
|
||||
return 1;
|
||||
}
|
||||
func_801C868C(arg0->unk_18, arg0->unk_1C, arg0->unk_20, 1);
|
||||
break;
|
||||
case 4:
|
||||
if (func_801C8844() != 0) {
|
||||
return 1;
|
||||
}
|
||||
func_801C868C(arg0->unk_18, arg0->unk_1C, arg0->unk_20, 2);
|
||||
break;
|
||||
case 5:
|
||||
arg0->unk_08 = func_801C8770();
|
||||
return arg0->unk_08;
|
||||
case 7:
|
||||
return func_801C87FC();
|
||||
case 6:
|
||||
return func_801C8844();
|
||||
case 8:
|
||||
arg0->unk_04 = func_801C87C0();
|
||||
return arg0->unk_04;
|
||||
case 9:
|
||||
return func_801C885C();
|
||||
case 10:
|
||||
return func_801C88AC();
|
||||
case 11:
|
||||
return func_801C88FC();
|
||||
case 12:
|
||||
D_801D2EA0 = 0;
|
||||
break;
|
||||
case 13:
|
||||
D_801D2EA0 = 1;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void func_801C819C(UNK_TYPE arg0) {
|
||||
if (arg0 != 0) {
|
||||
D_801D2E60 = 1;
|
||||
} else {
|
||||
D_801D2E60 = 2;
|
||||
}
|
||||
}
|
||||
|
||||
s32 func_801C81C4(void) {
|
||||
return D_801D2E60;
|
||||
}
|
||||
|
||||
s32 func_801C81D4(void) {
|
||||
return D_801D2E64 == 1;
|
||||
}
|
||||
|
||||
void func_801C81EC(struct_801E0D18* arg0) {
|
||||
osCreateMesgQueue(&arg0->unk_1C, 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));
|
||||
} else {
|
||||
arg0->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)) {
|
||||
D_801D2E64 = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void func_801C8298(struct_801E0D18* arg0) {
|
||||
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);
|
||||
}
|
||||
|
||||
void func_801C82E0(struct_801E0D18* 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) {
|
||||
s32 sp34;
|
||||
s32 startLBA = arg0->unk_5C;
|
||||
|
||||
if (LeoByteToLBA(startLBA, arg0->unk_60, &sp34) == LEO_ERROR_GOOD) {
|
||||
OSMesgQueue* sp28 = &arg0->unk_1C;
|
||||
|
||||
LeoReadWrite(&arg0->unk_00, OS_READ, startLBA, (void*)arg0->unk_58, sp34, sp28);
|
||||
osRecvMesg(sp28, (OSMesg*)&arg0->unk_68, OS_MESG_BLOCK);
|
||||
}
|
||||
}
|
||||
|
||||
void func_801C83A0(struct_801E0D18* arg0) {
|
||||
s32 sp34;
|
||||
s32 startLBA = arg0->unk_58;
|
||||
|
||||
if (LeoByteToLBA(startLBA, arg0->unk_60, &sp34) == LEO_ERROR_GOOD) {
|
||||
OSMesgQueue* sp28 = &arg0->unk_1C;
|
||||
|
||||
LeoReadWrite(&arg0->unk_00, OS_WRITE, startLBA, (void*)arg0->unk_5C, sp34, sp28);
|
||||
osRecvMesg(sp28, (OSMesg*)&arg0->unk_68, OS_MESG_BLOCK);
|
||||
}
|
||||
}
|
||||
|
||||
void func_801C8414(struct_801E0D18* arg0) {
|
||||
arg0->unk_68 = 9;
|
||||
}
|
||||
|
||||
void func_801C8424(struct_801E0D18* arg0) {
|
||||
struct_801D2E68* temp_v0;
|
||||
s32 (*temp_s2)(struct_801E0D18*);
|
||||
void (*aux)(struct_801E0D18*);
|
||||
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];
|
||||
aux = temp_v0->unk_0;
|
||||
temp_s2 = temp_v0->unk_4;
|
||||
do {
|
||||
aux(arg0);
|
||||
temp_v0_2 = temp_s2(arg0);
|
||||
} while (temp_v0_2 == 2);
|
||||
arg0->unk_6C = temp_v0_2;
|
||||
if (arg0->unk_64 == 0) {
|
||||
func_801C819C(temp_v0_2);
|
||||
}
|
||||
arg0->unk_66 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void func_801C84D4(void* arg) {
|
||||
while (true) {
|
||||
struct_801E0D18* sp24;
|
||||
|
||||
osRecvMesg(B_801E0D10[0], (OSMesg*)&sp24, OS_MESG_BLOCK);
|
||||
func_801C8424(sp24);
|
||||
osSendMesg(B_801E0D10[1], NULL, OS_MESG_BLOCK);
|
||||
}
|
||||
}
|
||||
|
||||
void func_801C8554(void) {
|
||||
osDestroyThread(&B_801E0DB0);
|
||||
}
|
||||
|
||||
void func_801C8578(void* arg0, void* arg1, OSId id, void* sp, OSPri pri) {
|
||||
B_801E0D10[0] = (OSMesgQueue*)arg0;
|
||||
B_801E0D10[1] = (OSMesgQueue*)arg1;
|
||||
osCreateThread(&B_801E0DB0, id, &func_801C84D4, NULL, sp, pri);
|
||||
osStartThread(&B_801E0DB0);
|
||||
}
|
||||
|
||||
void func_801C85F0(struct_801E0D18* arg0, s32 arg1) {
|
||||
if (arg1 == 1) {
|
||||
func_801C8424(arg0);
|
||||
} else {
|
||||
osSendMesg(B_801E0D10[0], arg0, OS_MESG_BLOCK);
|
||||
}
|
||||
}
|
||||
|
||||
void func_801C8638(void (*arg0)(void*, void*, void*), s32 arg1, void (*arg2)(void*, uintptr_t, size_t)) {
|
||||
s32 var0 = 0;
|
||||
|
||||
func_801C9B50(arg1, arg2);
|
||||
D_801D2EB4 = arg0;
|
||||
B_801E0D18.unk_64 = var0;
|
||||
B_801E0D18.unk_65 = var0;
|
||||
func_801C85F0(&B_801E0D18, 0);
|
||||
}
|
||||
|
||||
void func_801C868C(void* arg0, void* arg1, void* arg2, u8 arg3) {
|
||||
s32 var0 = (s32)arg0;
|
||||
s32 var1 = (s32)arg1;
|
||||
s32 var2 = (s32)arg2;
|
||||
s32 var3 = arg3;
|
||||
s32 var4 = 4;
|
||||
|
||||
if (D_801D2E90 == 1) {
|
||||
D_801D2E90 = 0;
|
||||
B_801E0D18.unk_64 = var4;
|
||||
func_801C85F0(&B_801E0D18, 1);
|
||||
if (B_801E0D18.unk_6C == 3 || B_801E0D18.unk_6C == 4) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
B_801E0D18.unk_58 = var0;
|
||||
B_801E0D18.unk_5C = var1;
|
||||
B_801E0D18.unk_60 = var2;
|
||||
B_801E0D18.unk_64 = var3;
|
||||
func_801C85F0(&B_801E0D18, 0);
|
||||
}
|
||||
|
||||
s32 func_801C873C(struct_801E0D18* arg0) {
|
||||
u8 sp1F;
|
||||
|
||||
arg0->unk_68 = LeoTestUnitReady(&sp1F);
|
||||
return !(sp1F & LEO_TEST_UNIT_MR);
|
||||
}
|
||||
|
||||
s8 func_801C8770(void) {
|
||||
s32 temp = func_801C873C(&B_801E0D18);
|
||||
|
||||
if (B_801E0D18.unk_68 == LEO_ERROR_BUSY) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!temp) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
s32 func_801C87C0(void) {
|
||||
if (func_801C8844() == 0) {
|
||||
if (B_801E0D18.unk_68 != 0) {
|
||||
return B_801E0D18.unk_68;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
s32 func_801C87FC(void) {
|
||||
s32* new_var = &B_801E0D18.unk_68;
|
||||
s32 temp_v0;
|
||||
|
||||
if (func_801C8844() == 0) {
|
||||
temp_v0 = B_801E0D18.unk_6C;
|
||||
|
||||
if ((temp_v0 == 3) || (temp_v0 == 4)) {
|
||||
return *new_var;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 func_801C8844(void) {
|
||||
return B_801E0D18.unk_66 == 1;
|
||||
}
|
||||
|
||||
s32 func_801C885C(void) {
|
||||
B_801E0D18.unk_64 = 3;
|
||||
func_801C85F0(&B_801E0D18, 1);
|
||||
|
||||
#if OOT_VERSION > NTSC_1_0
|
||||
D_801D2E90 = 0;
|
||||
#endif
|
||||
|
||||
if ((B_801E0D18.unk_6C == 3) || (B_801E0D18.unk_6C == 4)) {
|
||||
return -1;
|
||||
}
|
||||
return B_801E0D18.unk_6C == 0;
|
||||
}
|
||||
|
||||
s32 func_801C88AC(void) {
|
||||
s32 phi_v0;
|
||||
|
||||
B_801E0D18.unk_64 = 4;
|
||||
func_801C85F0(&B_801E0D18, 1);
|
||||
|
||||
#if OOT_VERSION > NTSC_1_0
|
||||
D_801D2E90 = 0;
|
||||
#endif
|
||||
|
||||
if ((B_801E0D18.unk_6C == 3) || (B_801E0D18.unk_6C == 4)) {
|
||||
return -1;
|
||||
}
|
||||
return B_801E0D18.unk_6C == 0;
|
||||
}
|
||||
|
||||
s32 func_801C88FC(void) {
|
||||
s32 temp = 0;
|
||||
s32 phi_v1;
|
||||
|
||||
if (LeoDriveExist()) {
|
||||
phi_v1 = 8;
|
||||
} else {
|
||||
phi_v1 = 0;
|
||||
}
|
||||
|
||||
temp = phi_v1 == temp;
|
||||
|
||||
B_801E0D18.unk_68 = phi_v1;
|
||||
|
||||
return temp;
|
||||
}
|
398
src/n64dd/n64dd_801C8940.c
Normal file
398
src/n64dd/n64dd_801C8940.c
Normal file
|
@ -0,0 +1,398 @@
|
|||
// Lower-level command processing in a background thread
|
||||
#include "global.h"
|
||||
#include "n64dd.h"
|
||||
|
||||
s32 D_801D2EA0 = 0;
|
||||
u8* D_801D2EA4 = NULL;
|
||||
s32 D_801D2EA8 = 0;
|
||||
u8* D_801D2EAC = NULL;
|
||||
u8* D_801D2EB0 = NULL;
|
||||
void (*D_801D2EB4)(void*, void*, void*) = NULL;
|
||||
|
||||
s32 B_801E0F60;
|
||||
s32 B_801E0F64;
|
||||
|
||||
// Set error message title texture?
|
||||
void func_801C8940(s32 errorNum) {
|
||||
D_801D2EA4 = func_801C9E28(errorNum);
|
||||
D_801D2EA8 = 1;
|
||||
}
|
||||
|
||||
// Clear error message title texture?
|
||||
void func_801C8974(void) {
|
||||
if (D_801D2EA8 == 1) {
|
||||
D_801D2EA4 = func_801C9EC0();
|
||||
D_801D2EA8 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Set error message something
|
||||
void func_801C89B8(s32 errorNum) {
|
||||
D_801D2EAC = func_801C9F90(errorNum);
|
||||
B_801E0F60 = 1;
|
||||
}
|
||||
|
||||
// Clear error message something
|
||||
void func_801C89EC(void) {
|
||||
if (B_801E0F60 == 1) {
|
||||
D_801D2EAC = func_801C9FFC();
|
||||
B_801E0F60 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Set error message something
|
||||
void func_801C8A30(s32 errorNum) {
|
||||
D_801D2EB0 = func_801CA030(errorNum);
|
||||
B_801E0F64 = 1;
|
||||
}
|
||||
|
||||
// Clear error message something
|
||||
void func_801C8A64(void) {
|
||||
if (B_801E0F64 == 1) {
|
||||
D_801D2EB0 = func_801CA070();
|
||||
B_801E0F64 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void func_801C8AA8(void) {
|
||||
osRecvMesg(B_801E0D10[1], NULL, OS_MESG_NOBLOCK);
|
||||
|
||||
if ((D_801D2EB4 != NULL) && (D_801D2EA0 == 0)) {
|
||||
u32 temp_v0 = osSetIntMask(OS_IM_NONE);
|
||||
void* sp20 = D_801D2EA4;
|
||||
void* sp1C = D_801D2EAC;
|
||||
void* sp18 = D_801D2EB0;
|
||||
|
||||
D_801D2EA4 = NULL;
|
||||
D_801D2EAC = NULL;
|
||||
D_801D2EB0 = NULL;
|
||||
osSetIntMask(temp_v0);
|
||||
D_801D2EB4(sp20, sp1C, sp18);
|
||||
}
|
||||
}
|
||||
|
||||
void func_801C8B58(s32 arg0, s32 arg1, s32 arg2) {
|
||||
func_801C8940(arg0);
|
||||
func_801C89B8(arg1);
|
||||
func_801C8A30(arg2);
|
||||
}
|
||||
|
||||
void func_801C8B90(void) {
|
||||
func_801C8974();
|
||||
func_801C89EC();
|
||||
func_801C8A64();
|
||||
}
|
||||
|
||||
s32 func_801C8BC0(struct_801E0D18* arg0) {
|
||||
if ((arg0->unk_68 < 0x25) || (arg0->unk_68 >= 0x29)) {
|
||||
if ((arg0->unk_68 != 0x1F) && (arg0->unk_68 != 0x20)) {
|
||||
func_801C8940(arg0->unk_68);
|
||||
func_801C89B8(3);
|
||||
}
|
||||
}
|
||||
LeoClearQueue();
|
||||
return 4;
|
||||
}
|
||||
|
||||
s32 func_801C8C1C(struct_801E0D18* arg0) {
|
||||
s32 var_s0;
|
||||
|
||||
do {
|
||||
var_s0 = 0;
|
||||
Sleep_Msec(60);
|
||||
func_801C82E0(arg0);
|
||||
|
||||
switch (arg0->unk_68) {
|
||||
case 0x2A:
|
||||
func_801C8A64();
|
||||
return 0;
|
||||
case 0x22:
|
||||
func_801C8A64();
|
||||
LeoClearQueue();
|
||||
return 3;
|
||||
case 0:
|
||||
func_801C8A30(6);
|
||||
FALLTHROUGH;
|
||||
case 0x23:
|
||||
var_s0 = 1;
|
||||
break;
|
||||
}
|
||||
} while (var_s0 != 0);
|
||||
|
||||
func_801C8A64();
|
||||
return func_801C8BC0(arg0);
|
||||
}
|
||||
|
||||
s32 func_801C8CEC(struct_801E0D18* arg0) {
|
||||
switch (arg0->unk_68) {
|
||||
case 0x22:
|
||||
func_801C8B90();
|
||||
LeoClearQueue();
|
||||
return 3;
|
||||
case 0x2:
|
||||
func_801C8940(arg0->unk_68);
|
||||
func_801C8A30(5);
|
||||
return 9;
|
||||
case 0x0:
|
||||
func_801C8B90();
|
||||
return 0;
|
||||
case 0x2B:
|
||||
if (arg0->unk_65 == 0) {
|
||||
func_801C8B90();
|
||||
arg0->unk_65 = 2;
|
||||
return 1;
|
||||
}
|
||||
FALLTHROUGH;
|
||||
default:
|
||||
func_801C8B90();
|
||||
return func_801C8BC0(arg0);
|
||||
case 0x23:
|
||||
return 9;
|
||||
}
|
||||
}
|
||||
|
||||
s32 func_801C8DC0(struct_801E0D18* arg0) {
|
||||
s32 temp_v0;
|
||||
|
||||
while (true) {
|
||||
func_801C8298(arg0);
|
||||
switch (arg0->unk_68) {
|
||||
case 0x31:
|
||||
func_801C8940(arg0->unk_68);
|
||||
func_801C89B8(2);
|
||||
return 5;
|
||||
case 0x2A:
|
||||
func_801C8B90();
|
||||
return 5;
|
||||
}
|
||||
temp_v0 = func_801C8CEC(arg0);
|
||||
if (temp_v0 != 9) {
|
||||
return temp_v0;
|
||||
}
|
||||
Sleep_Msec(60);
|
||||
}
|
||||
}
|
||||
|
||||
s32 func_801C8E70(struct_801E0D18* arg0) {
|
||||
s32 temp_a0;
|
||||
s32 temp_v0;
|
||||
|
||||
while (true) {
|
||||
Sleep_Msec(60);
|
||||
func_801C8298(arg0);
|
||||
|
||||
switch (arg0->unk_68) {
|
||||
case 0x23:
|
||||
continue;
|
||||
case 0x31:
|
||||
func_801C8940(arg0->unk_68);
|
||||
func_801C89B8(2);
|
||||
FALLTHROUGH;
|
||||
case 0x2A:
|
||||
func_801C8A30(4);
|
||||
continue;
|
||||
}
|
||||
|
||||
temp_v0 = func_801C8CEC(arg0);
|
||||
if (temp_v0 != 9) {
|
||||
return temp_v0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
s32 func_801C8F1C(struct_801E0D18* arg0) {
|
||||
if (D_801D2E54 != NULL) {
|
||||
return D_801D2E54(arg0);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
s32 func_801C8F58(struct_801E0D18* arg0) {
|
||||
s32 temp_v0;
|
||||
|
||||
while (true) {
|
||||
temp_v0 = func_801C8E70(arg0);
|
||||
if (temp_v0 == 3 || temp_v0 == 4) {
|
||||
return temp_v0;
|
||||
}
|
||||
|
||||
// Fake match?
|
||||
if ((temp_v0 & 0xFFFFFFFF) == 0) {
|
||||
if (func_801C8F1C(arg0) != 0) {
|
||||
return 2;
|
||||
}
|
||||
func_801C89B8(1);
|
||||
temp_v0 = func_801C8C1C(arg0);
|
||||
if (temp_v0 != 0) {
|
||||
return temp_v0;
|
||||
}
|
||||
func_801C89EC();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
s32 func_801C9000(struct_801E0D18* arg0) {
|
||||
s32 phi_s0;
|
||||
s32 temp_s4;
|
||||
|
||||
while (true) {
|
||||
phi_s0 = func_801C8E70(arg0);
|
||||
if (phi_s0 == 3 || phi_s0 == 4) {
|
||||
return phi_s0;
|
||||
}
|
||||
|
||||
// Fake match?
|
||||
if ((phi_s0 & 0xFFFFFFFF) == 0) {
|
||||
func_801C8B90();
|
||||
|
||||
temp_s4 = func_801C8F1C(arg0);
|
||||
if (temp_s4 == 3 || temp_s4 == 4) {}
|
||||
if (temp_s4 != 0) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
func_801C89B8(1);
|
||||
|
||||
phi_s0 = func_801C8C1C(arg0);
|
||||
if (phi_s0 == 3 || phi_s0 == 4) {}
|
||||
if (phi_s0 != 0) {
|
||||
return phi_s0;
|
||||
}
|
||||
|
||||
func_801C89EC();
|
||||
if (temp_s4 != 0) {
|
||||
return phi_s0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
s32 func_801C90C4(struct_801E0D18* arg0) {
|
||||
func_801C8940(arg0->unk_68);
|
||||
func_801C89B8(2);
|
||||
return func_801C9000(arg0);
|
||||
}
|
||||
|
||||
s32 func_801C90FC(struct_801E0D18* arg0) {
|
||||
func_801C8940(arg0->unk_68);
|
||||
return func_801C9000(arg0);
|
||||
}
|
||||
|
||||
s32 func_801C912C(struct_801E0D18* arg0) {
|
||||
s32 i = 0;
|
||||
s32 temp_v0;
|
||||
|
||||
do {
|
||||
LeoResetClear();
|
||||
|
||||
temp_v0 = func_801C8DC0(arg0);
|
||||
if (temp_v0 == 3 || temp_v0 == 4) {
|
||||
return temp_v0;
|
||||
}
|
||||
if (temp_v0 != 1) {
|
||||
if (temp_v0 == 0) {
|
||||
return temp_v0;
|
||||
} else {
|
||||
return temp_v0;
|
||||
}
|
||||
}
|
||||
|
||||
Sleep_Msec(250);
|
||||
} while (i++ < 30);
|
||||
|
||||
return func_801C8BC0(arg0);
|
||||
}
|
||||
|
||||
s32 func_801C91E0(struct_801E0D18* arg0) {
|
||||
if (arg0->unk_68 == 0x29) {
|
||||
return func_801C8BC0(arg0);
|
||||
}
|
||||
|
||||
if (osMemSize < 0x800000) {
|
||||
// LEO_ERROR_RAMPACK_NOT_CONNECTED?
|
||||
func_801C8B58(0x2C, 0, 3);
|
||||
return 4;
|
||||
}
|
||||
|
||||
if (func_801C912C(arg0) == 0) {
|
||||
D_801D2E90 = 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 func_801C9260(struct_801E0D18* arg0) {
|
||||
s32 temp_v0;
|
||||
|
||||
switch (arg0->unk_68) {
|
||||
case 0x17:
|
||||
func_801C873C(arg0);
|
||||
temp_v0 = func_801C8C1C(arg0);
|
||||
if (temp_v0 != 0) {
|
||||
return temp_v0;
|
||||
}
|
||||
func_801C8B90();
|
||||
return 2;
|
||||
|
||||
case 0x2:
|
||||
return func_801C8F58(arg0);
|
||||
|
||||
case 0x22:
|
||||
LeoClearQueue();
|
||||
return 3;
|
||||
|
||||
case 0x31:
|
||||
return func_801C90C4(arg0);
|
||||
|
||||
case 0x2F:
|
||||
return func_801C9000(arg0);
|
||||
|
||||
case 0x2A:
|
||||
return func_801C90FC(arg0);
|
||||
|
||||
case 0x0:
|
||||
return 0;
|
||||
|
||||
case 0x23:
|
||||
return 2;
|
||||
}
|
||||
|
||||
return func_801C8BC0(arg0);
|
||||
}
|
||||
|
||||
s32 func_801C9334(struct_801E0D18* arg0) {
|
||||
while (true) {
|
||||
u32 temp_v0 = func_801C8DC0(arg0);
|
||||
|
||||
if (temp_v0 == 3 || temp_v0 == 4 || temp_v0 == 5) {
|
||||
return temp_v0;
|
||||
}
|
||||
|
||||
// Fake match?
|
||||
if ((temp_v0 & 0xFFFFFFFF) == 0) {
|
||||
if (func_801C8F1C(arg0) != 0) {
|
||||
return 0;
|
||||
}
|
||||
return 7;
|
||||
}
|
||||
|
||||
if (1) {}
|
||||
}
|
||||
}
|
||||
|
||||
s32 func_801C93C4(struct_801E0D18* arg0) {
|
||||
s32 temp_v0;
|
||||
s32 temp_v0_2;
|
||||
|
||||
while (true) {
|
||||
temp_v0_2 = func_801C9334(arg0);
|
||||
if (temp_v0_2 != 7) {
|
||||
return temp_v0_2;
|
||||
}
|
||||
func_801C89B8(1);
|
||||
temp_v0 = func_801C8C1C(arg0);
|
||||
if (temp_v0 != 0) {
|
||||
return temp_v0;
|
||||
}
|
||||
func_801C89EC();
|
||||
}
|
||||
}
|
263
src/n64dd/n64dd_801C9440.c
Normal file
263
src/n64dd/n64dd_801C9440.c
Normal file
|
@ -0,0 +1,263 @@
|
|||
// Some text-handling functions
|
||||
#include "global.h"
|
||||
#include "n64dd.h"
|
||||
|
||||
void (*D_801D2EC0)(void*, uintptr_t, size_t) = NULL;
|
||||
|
||||
s32 B_801E0F70;
|
||||
|
||||
/**
|
||||
* Seems to work out if a pair of bytes is a valid EUC-JP character, although there may be additions to the font that
|
||||
* make the strange first check make more sense.
|
||||
*
|
||||
* @param bytes Array 2 bytes to test
|
||||
* @return boolean
|
||||
*/
|
||||
int func_801C9440(u8* bytes) {
|
||||
// This is every possible first byte. May make more sense what was intended with the font files?
|
||||
if (((*bytes >= 0x8E) && (*bytes <= 0xFE)) || ((*bytes != 0x8F) && (*bytes != 0xA0))) {
|
||||
bytes++;
|
||||
return (*bytes >= 0xA0) && (*bytes <= 0xFE);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* A crude check for a valid 2-byte Shift-JIS character
|
||||
*
|
||||
* @param bytes Array containing a pair of bytes to test
|
||||
* @return boolean
|
||||
*/
|
||||
int func_801C9494(u8* bytes) {
|
||||
// Allowable first bytes.
|
||||
if (((*bytes >= 0x81) && (*bytes <= 0x9F)) || ((*bytes >= 0xE0) && (*bytes <= 0xFC))) {
|
||||
bytes++;
|
||||
// Allowable second bytes.
|
||||
return (*bytes >= 0x40) && (*bytes <= 0xFC) && *bytes != 0x7F;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Extracts 2 bytes from a bytepacked big-endian short.
|
||||
void func_801C94F8(u8* arg0, u16 arg1) {
|
||||
arg0[0] = arg1 >> 8;
|
||||
arg0[1] = arg1 & 0xFF;
|
||||
}
|
||||
|
||||
// Convert EUC-JP to JIS X 0208
|
||||
u16 func_801C9514(u16 eucjpCh) {
|
||||
return eucjpCh - 0x8080;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a JIS X 0208 codepoint to a Shift-JIS one.
|
||||
*
|
||||
* @param jisCodepoint Two bytes, each between 0x21 and 0x7E, packed big-endian into a short.
|
||||
* @return u16 Shift-JIS character representation (expected to be big-endian)
|
||||
*/
|
||||
u16 func_801C9534(u16 jisCodepoint) {
|
||||
u8 hiByte = (jisCodepoint >> 8) & 0xFF;
|
||||
u8 loByte = jisCodepoint & 0xFF;
|
||||
|
||||
if (hiByte & 1) {
|
||||
loByte += 0x1F;
|
||||
if (loByte >= 0x7F) {
|
||||
loByte++;
|
||||
}
|
||||
} else {
|
||||
loByte += 0x7E;
|
||||
}
|
||||
|
||||
hiByte = (hiByte - 0x21) / 2 + 0x81;
|
||||
if (hiByte >= 0xA0) {
|
||||
hiByte += 0x40;
|
||||
}
|
||||
|
||||
return (hiByte << 8) + loByte;
|
||||
}
|
||||
|
||||
void func_801C95C0(void* arg0, uintptr_t arg1, size_t arg2) {
|
||||
if (D_801D2EC0 != NULL) {
|
||||
D_801D2EC0(arg0, arg1, arg2);
|
||||
}
|
||||
}
|
||||
|
||||
s32 func_801C95F0(u8* arg0) {
|
||||
return LeoGetKAdr(func_801C9534(func_801C9514((arg0[0] << 8) | arg0[1]))) + DDROM_FONT_START;
|
||||
}
|
||||
|
||||
s32 func_801C963C(s32* arg0, int* dx, int* dy, int* cy, u8 arg4) {
|
||||
s32 temp_v0;
|
||||
s32 temp_v1;
|
||||
|
||||
u16 temp = arg4 - 0x20;
|
||||
temp += 0xC0 * B_801E0F70;
|
||||
|
||||
temp_v0 = LeoGetAAdr(temp, dx, dy, cy);
|
||||
temp_v1 = temp_v0 & 0xF;
|
||||
*arg0 = (temp_v0 - temp_v1) + DDROM_FONT_START;
|
||||
return temp_v1;
|
||||
}
|
||||
|
||||
s32 func_801C969C(void* arg0, int* dx, int* dy, int* cy, u8* arg4) {
|
||||
s32 sp24;
|
||||
s32 phi_v1;
|
||||
|
||||
if (func_801C9440(arg4)) {
|
||||
sp24 = func_801C95F0(arg4);
|
||||
*dx = 16;
|
||||
*dy = 16;
|
||||
*cy = 11;
|
||||
phi_v1 = 0;
|
||||
} else {
|
||||
phi_v1 = func_801C963C(&sp24, dx, dy, cy, *arg4);
|
||||
}
|
||||
|
||||
func_801C95C0(arg0, sp24, 0x80);
|
||||
return phi_v1;
|
||||
}
|
||||
|
||||
// return boolean
|
||||
s32 func_801C9740(u8* arg0, s32 arg1, u8 arg2) {
|
||||
if (arg1 == 1) {
|
||||
*arg0 = arg2 << 4;
|
||||
return false;
|
||||
} else {
|
||||
*arg0 |= arg2;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
u8* func_801C9778(u8* arg0, s32* arg1, s32 arg2) {
|
||||
arg0 += (arg2 >> 1);
|
||||
|
||||
if (((*arg1 == 1) && !(arg2 & 1)) || ((*arg1 == 0) && (arg2 & 1))) {
|
||||
arg0 += arg2 & 1;
|
||||
*arg1 = 1;
|
||||
} else {
|
||||
*arg1 = 0;
|
||||
}
|
||||
return arg0;
|
||||
}
|
||||
|
||||
s32 func_801C97C4(u8** arg0, s32 arg1, s32 arg2, s32 arg3, s32 arg4, u8* arg5, s32 dx, s32 dy, s32 cy) {
|
||||
u8* var_fp;
|
||||
u8* var_s0;
|
||||
s32 var_s1;
|
||||
s32 x;
|
||||
s32 sp4C;
|
||||
s32 var_s4;
|
||||
s32 sp44;
|
||||
|
||||
sp4C = arg2;
|
||||
sp44 = dx + arg3 + arg4;
|
||||
var_s4 = 1;
|
||||
var_fp = func_801C9778(*arg0, &sp4C, arg3);
|
||||
arg1 >>= 1;
|
||||
var_fp += ((11 - cy) * arg1);
|
||||
if (dx & 1) {
|
||||
dx++;
|
||||
}
|
||||
while (dy--) {
|
||||
var_s0 = var_fp;
|
||||
var_s1 = sp4C;
|
||||
for (x = 0; x < dx; x++) {
|
||||
if (var_s4 == 1) {
|
||||
if (func_801C9740(var_s0, var_s1, *arg5 >> 4)) {
|
||||
var_s0++;
|
||||
}
|
||||
} else {
|
||||
if (func_801C9740(var_s0, var_s1, *arg5 & 0xF)) {
|
||||
var_s0++;
|
||||
}
|
||||
arg5++;
|
||||
}
|
||||
var_s4 ^= 1;
|
||||
var_s1 ^= 1;
|
||||
}
|
||||
var_fp += arg1;
|
||||
}
|
||||
*arg0 = func_801C9778(*arg0, &arg2, sp44);
|
||||
return arg2;
|
||||
}
|
||||
|
||||
void func_801C9954(u8* bytes, s32* arg1, s32* arg2) {
|
||||
u8 prevCh;
|
||||
u8 nextCh;
|
||||
|
||||
if (func_801C9440(bytes)) {
|
||||
*arg1 = *arg2 = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
*arg1 = *arg2 = 0;
|
||||
|
||||
prevCh = bytes[-1];
|
||||
nextCh = bytes[1];
|
||||
|
||||
switch (bytes[0]) {
|
||||
case ' ':
|
||||
*arg1 = *arg2 = 0;
|
||||
return;
|
||||
|
||||
case 'I':
|
||||
case 'i':
|
||||
#if OOT_NTSC
|
||||
*arg2 = 2;
|
||||
if (1) {}
|
||||
#endif
|
||||
|
||||
*arg1 = 2;
|
||||
*arg2 = 2;
|
||||
|
||||
if (prevCh == ' ') {
|
||||
*arg1 = 0;
|
||||
}
|
||||
if (nextCh == ' ') {
|
||||
*arg2 = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#if OOT_NTSC
|
||||
*arg2 = 1;
|
||||
if (1) {}
|
||||
#endif
|
||||
|
||||
*arg1 = 1;
|
||||
*arg2 = 1;
|
||||
}
|
||||
|
||||
void func_801C9A10(u8* arg0, s32 arg1, u8* str) {
|
||||
u8 sp80[0xA0];
|
||||
u8* temp_s1;
|
||||
int dx;
|
||||
int dy;
|
||||
int cy;
|
||||
s32 var_s2;
|
||||
s32 sp68;
|
||||
s32 sp64;
|
||||
s32 temp_v1;
|
||||
|
||||
temp_s1 = (u8*)((((uintptr_t)&sp80 + 0xF) / 0x10) * 0x10);
|
||||
var_s2 = 1;
|
||||
if (str != NULL) {
|
||||
while (*str != '\0') {
|
||||
func_801C9954(str, &sp68, &sp64);
|
||||
temp_v1 = func_801C969C(temp_s1, &dx, &dy, &cy, str);
|
||||
if (dx & 1) {
|
||||
dx++;
|
||||
}
|
||||
var_s2 = func_801C97C4(&arg0, arg1, var_s2, sp68, sp64, &temp_s1[temp_v1], dx, dy, cy);
|
||||
if (func_801C9440(str)) {
|
||||
str++;
|
||||
}
|
||||
str++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void func_801C9B50(s32 arg0, void (*arg1)(void*, uintptr_t, size_t)) {
|
||||
B_801E0F70 = arg0;
|
||||
D_801D2EC0 = arg1;
|
||||
}
|
172
src/n64dd/n64dd_801C9B70.c
Normal file
172
src/n64dd/n64dd_801C9B70.c
Normal file
|
@ -0,0 +1,172 @@
|
|||
// User-facing error handling
|
||||
#include "global.h"
|
||||
#include "n64dd.h"
|
||||
|
||||
u8 B_801E0F80[0x600];
|
||||
u8 B_801E1580[0x2800];
|
||||
u8 B_801E3D80[0x1400];
|
||||
|
||||
/**
|
||||
* Converts a number in decimal to a hexadecimal number with the same digits, e.g. 1234 -> 0x1234.
|
||||
*
|
||||
* Will only work on nonnegative numbers.
|
||||
*
|
||||
* @param decNumber Number in decimal to convert, e.g. 1234
|
||||
* @return s32 Hexadecimal number with the same digits as decNumber, e.g. 0x1234
|
||||
*/
|
||||
s32 func_801C9B70(s32 decNumber) {
|
||||
s32 currPlaceValue;
|
||||
s32 currExponent = 0;
|
||||
s32 accumulatedHexDigits = 0;
|
||||
s32 remainingDecDigits;
|
||||
|
||||
// Nothing to do if only one digit.
|
||||
if (decNumber < 10) {
|
||||
return decNumber;
|
||||
}
|
||||
|
||||
// Find the place value / exponent of the most significant digit in decNumber.
|
||||
for (currPlaceValue = 1; 10 * currPlaceValue <= decNumber; currPlaceValue *= 10) {
|
||||
currExponent++;
|
||||
}
|
||||
|
||||
remainingDecDigits = decNumber;
|
||||
|
||||
// Transfer the digits to hex one at a time.
|
||||
while (currExponent--) {
|
||||
// Place the most significant remaining digit at the end of the hex output.
|
||||
accumulatedHexDigits |= remainingDecDigits / currPlaceValue;
|
||||
accumulatedHexDigits *= 0x10; // Shift left one hex digit.
|
||||
|
||||
remainingDecDigits %= currPlaceValue; // Remove most significant of the remaining digits.
|
||||
|
||||
currPlaceValue /= 10;
|
||||
}
|
||||
|
||||
accumulatedHexDigits += remainingDecDigits; // Only one digit left in the remainingDecDigits.
|
||||
return accumulatedHexDigits;
|
||||
}
|
||||
|
||||
// n64ddError_GetLanguage
|
||||
s32 func_801C9C48(void) {
|
||||
return (gCurrentRegion == 1) ? 0 : 1;
|
||||
}
|
||||
|
||||
// n64ddError_Memset
|
||||
void func_801C9C74(u8* dest, u8 value, u32 count) {
|
||||
while (count--) {
|
||||
*dest++ = value;
|
||||
}
|
||||
}
|
||||
|
||||
// n64ddError_GetErrorHeader
|
||||
const char* func_801C9CA4(void) {
|
||||
return D_801D2ED0[func_801C9C48()];
|
||||
}
|
||||
|
||||
// n64ddError_WriteNumberJP
|
||||
// Writes a 2-digit number to the char buffer provided
|
||||
// Character indices for numbers in the error code (EUC-JP)
|
||||
void func_801C9CD4(u8* buf, s32 number) {
|
||||
s32 temp_v0 = func_801C9B70(number);
|
||||
u16 character;
|
||||
|
||||
if (number >= 10) {
|
||||
character = ((temp_v0 >> 4) + 0xA3B0); // '0'
|
||||
} else {
|
||||
character = 0xA1A1; // ' '
|
||||
}
|
||||
|
||||
func_801C94F8(buf, character);
|
||||
buf += 2;
|
||||
func_801C94F8(buf, ((temp_v0 & 0xF) + 0xA3B0)); // '0'
|
||||
}
|
||||
|
||||
// n64ddError_WriteNumberEN
|
||||
// Writes a 2-digit number to the char buffer provided
|
||||
// Character indices for numbers in the error code (ASCII)
|
||||
void func_801C9D54(u8* buf, s32 number) {
|
||||
s32 temp_v0 = func_801C9B70(number);
|
||||
|
||||
if (number >= 10) {
|
||||
*buf = (temp_v0 >> 4) + '0';
|
||||
} else {
|
||||
*buf = ' ';
|
||||
}
|
||||
buf++;
|
||||
*buf = (temp_v0 & 0xF) + '0';
|
||||
}
|
||||
|
||||
void func_801C9DB8(u8* arg0, s32 errorNum) {
|
||||
u8* errorHeader = (u8*)func_801C9CA4();
|
||||
|
||||
//! @bug: both of these functions will write to the pointer target, but errorHeader points to a string literal,
|
||||
//! which is meant to be const.
|
||||
if (gCurrentRegion == 1) {
|
||||
func_801C9CD4(&errorHeader[12], errorNum);
|
||||
} else {
|
||||
func_801C9D54(&errorHeader[13], errorNum);
|
||||
}
|
||||
func_801C9A10(arg0, 192, errorHeader);
|
||||
}
|
||||
|
||||
u8* func_801C9E28(s32 errorNum) {
|
||||
func_801C9EC0();
|
||||
|
||||
if (errorNum == 41) {
|
||||
return (u8*)gN64DDError41Texs[func_801C9C48()];
|
||||
}
|
||||
|
||||
// 31,32, 37,38,39,40
|
||||
if (((errorNum >= 37) && (errorNum < 41)) || (errorNum == 31) || (errorNum == 32)) {
|
||||
return B_801E0F80;
|
||||
} else {
|
||||
func_801C9DB8(B_801E0F80, errorNum);
|
||||
return B_801E0F80;
|
||||
}
|
||||
}
|
||||
|
||||
// Clear something
|
||||
u8* func_801C9EC0(void) {
|
||||
func_801C9C74(B_801E0F80, 0, 0x600);
|
||||
return B_801E0F80;
|
||||
}
|
||||
|
||||
// Prints the error message body (?)
|
||||
void func_801C9EF4(u8* arg0, s32 errorNum, s32 lineCount) {
|
||||
s32 i;
|
||||
|
||||
for (i = 0; i < lineCount; i++, arg0 += 0xA00) {
|
||||
u8* line = (u8*)D_801D2EE0[func_801C9C48()][errorNum][i];
|
||||
|
||||
if (1) {}
|
||||
func_801C9A10(arg0, 320, line);
|
||||
}
|
||||
}
|
||||
|
||||
u8* func_801C9F90(s32 errorNum) {
|
||||
func_801C9FFC();
|
||||
if (errorNum == 3) {
|
||||
return (u8*)gN64DDPleaseReadManualTexs[func_801C9C48()];
|
||||
}
|
||||
func_801C9EF4(B_801E1580, errorNum, 4);
|
||||
return B_801E1580;
|
||||
}
|
||||
|
||||
// Clear something
|
||||
u8* func_801C9FFC(void) {
|
||||
func_801C9C74(B_801E1580, 0, 0x2800);
|
||||
return B_801E1580;
|
||||
}
|
||||
|
||||
u8* func_801CA030(s32 errorNum) {
|
||||
func_801CA070();
|
||||
func_801C9EF4(B_801E3D80, errorNum, 2);
|
||||
return B_801E3D80;
|
||||
}
|
||||
|
||||
// Clear something
|
||||
u8* func_801CA070(void) {
|
||||
func_801C9C74(B_801E3D80, 0, 0x1400);
|
||||
return B_801E3D80;
|
||||
}
|
243
src/n64dd/n64dd_801CA0B0.c
Normal file
243
src/n64dd/n64dd_801CA0B0.c
Normal file
|
@ -0,0 +1,243 @@
|
|||
#include "global.h"
|
||||
#include "n64dd.h"
|
||||
|
||||
// Draws text to framebuffer
|
||||
typedef struct struct_801CA704 {
|
||||
/* 0x00 */ PrintCallback callback;
|
||||
/* 0x04 */ void* charTexBuf;
|
||||
/* 0x08 */ u16 unk_08;
|
||||
/* 0x0A */ u16 posX;
|
||||
/* 0x0C */ u16 posY;
|
||||
/* 0x10 */ Color_RGBA8_u32 color;
|
||||
/* 0x14 */ u16 baseX;
|
||||
/* 0x16 */ u16 baseY;
|
||||
/* 0x18 */ u16 endX;
|
||||
/* 0x1A */ u16 endY;
|
||||
/* 0x1C */ u8 sjisPrevByte;
|
||||
/* 0x20 */ void* frameBuf;
|
||||
/* 0x24 */ u16 screenWidth;
|
||||
/* 0x26 */ u16 screenHeight;
|
||||
} struct_801CA704;
|
||||
|
||||
// clang-format off
|
||||
u32 D_801D8BE0[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,
|
||||
0x01A58A14, 0x01BB8A14, 0x01D1170E, 0x01D5490E, 0x01DF770E, 0x01EF740A, 0x01F9770E, 0x02097A14,
|
||||
0x021FDC16, 0x024DBA14, 0x026E7A14, 0x0284BA14, 0x02A59A14, 0x02C16A14, 0x02D26A14, 0x02E3BA14,
|
||||
0x03048A14, 0x031A1A14, 0x03206A14, 0x03318A14, 0x03476A14, 0x0358CA14, 0x03799A14, 0x0395CA14,
|
||||
0x03B67A14, 0x03CCCA14, 0x03ED8A14, 0x04037A14, 0x04196A14, 0x042A8A14, 0x0440AA14, 0x045CDA14,
|
||||
0x04839A14, 0x049F9A14, 0x04BB7A14, 0x04D14D14, 0x04DF5C14, 0x04F33D14, 0x05015216, 0x050681FA,
|
||||
0x050A9D14, 0x052D9810, 0x05449A14, 0x05609810, 0x05779A14, 0x05939810, 0x05AA5A14, 0x05BB9C10,
|
||||
0x05DC7A14, 0x05F22A14, 0x05F83D14, 0x06067A14, 0x061C2A14, 0x0622D810, 0x06427810, 0x06549810,
|
||||
0x066B9B10, 0x06899B10, 0x06A74810, 0x06B06810, 0x06BE5A14, 0x06CF770E, 0x06DF870E, 0x06EFB70E,
|
||||
0x0707670E, 0x07138A0E, 0x0729670E, 0x07356D14, 0x074A1F16, 0x07526D14, 0x07675216,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
// Loads character texture to buffer
|
||||
s32 func_801CA0B0(s32 charCode, void* charTexBuf, int* dx, int* dy, int* cy) {
|
||||
s32 offset;
|
||||
OSPiHandle* handle;
|
||||
OSMesgQueue queue;
|
||||
OSMesg msgBuf[1];
|
||||
OSIoMesg mesg;
|
||||
|
||||
handle = osDriveRomInit();
|
||||
if (charCode >= 0x20 && charCode < 0x7F) { // ASCII
|
||||
offset = LeoGetAAdr2(D_801D8BE0[charCode - 0x20], dx, dy, cy);
|
||||
} else if (charCode >= 0x8140) { // Shift-JIS
|
||||
offset = LeoGetKAdr(charCode);
|
||||
*dx = 16;
|
||||
*dy = 16;
|
||||
*cy = 11;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
osCreateMesgQueue(&queue, msgBuf, ARRAY_COUNT(msgBuf));
|
||||
|
||||
// clang-format off
|
||||
mesg.hdr.retQueue = &queue; \
|
||||
mesg.devAddr = offset + DDROM_FONT_START; \
|
||||
mesg.dramAddr = charTexBuf; \
|
||||
mesg.size = 0x80; \
|
||||
mesg.hdr.pri = 0;
|
||||
// clang-format on
|
||||
|
||||
handle->transferInfo.cmdType = 2;
|
||||
osEPiStartDma(handle, &mesg, 0);
|
||||
osRecvMesg(&queue, NULL, OS_MESG_BLOCK);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const u16 D_801D9390[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)];
|
||||
}
|
||||
|
||||
void func_801CA1F0(void* charTexBuf, s32 posX, s32 posY, s32 dx, s32 dy, s32 cy, void* frameBuf, s32 screenWidth) {
|
||||
s32 intensity;
|
||||
s32 x;
|
||||
s32 y;
|
||||
u8* src = charTexBuf;
|
||||
u16* dst = frameBuf;
|
||||
|
||||
for (y = 0; y < dy; y++) {
|
||||
for (x = 0; x < dx; x++) {
|
||||
if (!(x & 1)) {
|
||||
intensity = *src >> 4;
|
||||
} else {
|
||||
intensity = *src & 0xF;
|
||||
src++;
|
||||
}
|
||||
dst[posX + x + ((posY + (11 - cy) + y) * screenWidth)] = func_801CA1D4(intensity);
|
||||
}
|
||||
if (dx & 1) {
|
||||
src++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 func_801CA314(struct_801CA704* arg0, s32 arg1, s32 arg2) {
|
||||
arg0->posX = arg0->baseX + arg1;
|
||||
arg0->posY = arg0->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 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);
|
||||
}
|
||||
|
||||
void func_801CA3B4(struct_801CA704* arg0, void* charTexBuf, s32 arg2) {
|
||||
arg0->charTexBuf = (u8*)charTexBuf + 0x20000000;
|
||||
arg0->unk_08 = arg2;
|
||||
}
|
||||
|
||||
void func_801CA3CC(struct_801CA704* arg0, char c) {
|
||||
s32 charCode;
|
||||
int dx;
|
||||
int dy;
|
||||
int cy;
|
||||
|
||||
if (arg0->sjisPrevByte != 0) {
|
||||
charCode = (arg0->sjisPrevByte << 8) | c;
|
||||
} else {
|
||||
if (c >= 0x80 && c < 0x99) {
|
||||
arg0->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;
|
||||
} else {
|
||||
arg0->posY += 16;
|
||||
}
|
||||
}
|
||||
func_801CA1F0(arg0->charTexBuf, arg0->posX, arg0->posY, dx, dy, cy, arg0->frameBuf, arg0->screenWidth);
|
||||
arg0->posX += (dx == 16 ? dx : dx + 2);
|
||||
}
|
||||
}
|
||||
|
||||
void func_801CA4F4(struct_801CA704* arg0, char c) {
|
||||
if (c >= ' ' && c <= 0xFF) {
|
||||
func_801CA3CC(arg0, c);
|
||||
} else {
|
||||
switch (c) {
|
||||
case '\n':
|
||||
arg0->posY += 32;
|
||||
FALLTHROUGH;
|
||||
case '\r':
|
||||
arg0->posX = arg0->baseX;
|
||||
break;
|
||||
case '\t':
|
||||
do {
|
||||
func_801CA3CC(arg0, ' ');
|
||||
} while ((arg0->posX - arg0->baseX) % 256);
|
||||
break;
|
||||
case '\0':
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void func_801CA5BC(struct_801CA704* arg0, const char* str, s32 arg2, size_t count) {
|
||||
const char* s = str;
|
||||
s32 n = arg2 * count;
|
||||
|
||||
while (n != 0) {
|
||||
func_801CA4F4(arg0, *s++);
|
||||
n--;
|
||||
}
|
||||
}
|
||||
|
||||
void func_801CA618(struct_801CA704* arg0, const char* str) {
|
||||
while (*str != 0) {
|
||||
func_801CA4F4(arg0, *str++);
|
||||
}
|
||||
}
|
||||
|
||||
void* func_801CA670(void* arg, const char* str, size_t count) {
|
||||
func_801CA5BC(arg, str, 1, count);
|
||||
return arg;
|
||||
}
|
||||
|
||||
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 func_801CA6D8(struct_801CA704* arg0) {
|
||||
}
|
||||
|
||||
s32 func_801CA6E4(struct_801CA704* arg0, const char* fmt, va_list args) {
|
||||
return PrintUtils_VPrintf(&arg0->callback, fmt, args);
|
||||
}
|
||||
|
||||
s32 func_801CA704(struct_801CA704* arg0, const char* fmt, ...) {
|
||||
s32 ret;
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
ret = func_801CA6E4(arg0, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
return ret;
|
||||
}
|
5
src/n64dd/n64dd_data_buffer.c
Normal file
5
src/n64dd/n64dd_data_buffer.c
Normal file
|
@ -0,0 +1,5 @@
|
|||
#include "global.h"
|
||||
#include "n64dd.h"
|
||||
|
||||
// Buffer used for reading from the disk?
|
||||
u8 B_801DC000[0x4D10];
|
47
src/n64dd/n64dd_error_bodies.c
Normal file
47
src/n64dd/n64dd_error_bodies.c
Normal file
|
@ -0,0 +1,47 @@
|
|||
#include "global.h"
|
||||
#include "n64dd.h"
|
||||
|
||||
const char* D_801D2EE0[2][8][4] = {
|
||||
{
|
||||
{ " メモリー拡張パックが正しく差し込", " んでありますか? ", NULL, NULL },
|
||||
{ " 間違ったディスクが差し込まれてい", " る可能性があります。正しいディス",
|
||||
" クに交換してください。 ", NULL },
|
||||
{ " 注意:アクセスランプ点滅中にディ", " スクを抜かないでください。詳しく",
|
||||
" は、取扱説明書をお読みください。", NULL },
|
||||
{ " 詳しくは、取扱説明書をお読みくだ", " さい。 ", NULL, NULL },
|
||||
{ " ディスクを差し込んでください。", NULL, NULL, NULL },
|
||||
{ " ディスクを差し込み直してください。", NULL, NULL, NULL },
|
||||
{ " ディスクを取り出してください。", NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL },
|
||||
},
|
||||
{
|
||||
{
|
||||
" Are you sure the Expansion",
|
||||
" Pak is inserted correctly?",
|
||||
NULL,
|
||||
NULL,
|
||||
},
|
||||
{
|
||||
" Check to see if the proper",
|
||||
" disk is inserted.",
|
||||
" Please insert the disk the",
|
||||
" correct disk.",
|
||||
},
|
||||
{
|
||||
" Do not remove the disk when",
|
||||
" the access light is flashing.",
|
||||
" Please read the instruction",
|
||||
" manual for details.",
|
||||
},
|
||||
{
|
||||
" Please read the instruction",
|
||||
" manual for details.",
|
||||
NULL,
|
||||
NULL,
|
||||
},
|
||||
{ " Please insert a disk.", NULL, NULL, NULL },
|
||||
{ " Please insert the disk again.", NULL, NULL, NULL },
|
||||
{ " Please remove the disk.", NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL },
|
||||
},
|
||||
};
|
5
src/n64dd/n64dd_error_headers.c
Normal file
5
src/n64dd/n64dd_error_headers.c
Normal file
|
@ -0,0 +1,5 @@
|
|||
#include "global.h"
|
||||
#include "n64dd.h"
|
||||
|
||||
// Padding in .rodata suggests that these are in a separate file
|
||||
const char* D_801D2ED0[4] = { "エラー番号 ", "Error Number ", NULL, NULL };
|
23
src/n64dd/n64dd_error_textures.c
Normal file
23
src/n64dd/n64dd_error_textures.c
Normal file
|
@ -0,0 +1,23 @@
|
|||
#include "ultra64.h"
|
||||
|
||||
#if PLATFORM_N64
|
||||
|
||||
u64 gN64DDError41Texs[2][0x600 / sizeof(u64)] = {
|
||||
{
|
||||
#include "assets/n64dd/error_textures/n64dd_error_41_jpn.i4.inc.c"
|
||||
},
|
||||
{
|
||||
#include "assets/n64dd/error_textures/n64dd_error_41_eng.i4.inc.c"
|
||||
},
|
||||
};
|
||||
|
||||
u64 gN64DDPleaseReadManualTexs[2][0x2800 / sizeof(u64)] = {
|
||||
{
|
||||
#include "assets/n64dd/error_textures/n64dd_please_read_manual_jpn.i4.inc.c"
|
||||
},
|
||||
{
|
||||
#include "assets/n64dd/error_textures/n64dd_please_read_manual_eng.i4.inc.c"
|
||||
},
|
||||
};
|
||||
|
||||
#endif
|
584
src/n64dd/z_n64dd.c
Normal file
584
src/n64dd/z_n64dd.c
Normal file
|
@ -0,0 +1,584 @@
|
|||
// Main interface for the 64DD from the rest of the game. Starts background
|
||||
// threads and provides functions to submit commands to them.
|
||||
#include "global.h"
|
||||
#include "fault.h"
|
||||
#include "n64dd.h"
|
||||
#include "stack.h"
|
||||
#include "versions.h"
|
||||
|
||||
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 = &B_801DC000;
|
||||
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;
|
||||
UNK_TYPE B_801DBFC4; // unused?
|
||||
|
||||
u32 func_801C6E80(void) {
|
||||
#if OOT_NTSC
|
||||
return LeoDriveExist();
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void func_801C6EA0(Gfx** gfxP) {
|
||||
}
|
||||
|
||||
void func_801C6EAC(void) {
|
||||
if (D_80121214 == 0) {
|
||||
func_800F6BDC();
|
||||
D_80121214 = 1;
|
||||
}
|
||||
}
|
||||
|
||||
s32 func_801C6EF0(void) {
|
||||
return D_80121214 != 0;
|
||||
}
|
||||
|
||||
s32 func_801C6F08(void) {
|
||||
if (D_80121214 != 0) {
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void func_801C6F30(void) {
|
||||
func_801C6EAC();
|
||||
while (func_801C6F08() == 0) {
|
||||
Sleep_Usec(16666); // 100000 / 6
|
||||
}
|
||||
}
|
||||
|
||||
void func_801C6F78(void) {
|
||||
if (D_80121214 != 0) {
|
||||
D_80121214 = 0;
|
||||
func_800F6B3C();
|
||||
}
|
||||
}
|
||||
|
||||
// boolean
|
||||
s32 func_801C6FAC(void) {
|
||||
if (D_80121213 == 0) {
|
||||
return false;
|
||||
} else {
|
||||
D_80121213 = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void func_801C6FD8(void) {
|
||||
while (!func_801C6FAC()) {
|
||||
Sleep_Usec(16666); // 100000 / 6
|
||||
}
|
||||
}
|
||||
|
||||
// Adds a HungupAndCrash
|
||||
void func_801C7018(void) {
|
||||
if (D_80121213 != 0) {
|
||||
#if OOT_VERSION == NTSC_1_0
|
||||
Fault_AddHungupAndCrash("../z_n64dd.c", 503);
|
||||
#elif OOT_VERSION == NTSC_1_1
|
||||
Fault_AddHungupAndCrash("../z_n64dd.c", 551);
|
||||
#else
|
||||
Fault_AddHungupAndCrash("../z_n64dd.c", 573);
|
||||
#endif
|
||||
}
|
||||
D_80121213 = 1;
|
||||
}
|
||||
|
||||
s32 func_801C7064(void) {
|
||||
B_801D9D50.unk_00 = 5;
|
||||
return (&func_801C8000)(&B_801D9D50);
|
||||
}
|
||||
|
||||
s32 func_801C7098(void) {
|
||||
s32 phi_v1;
|
||||
|
||||
#if OOT_VERSION <= NTSC_1_1
|
||||
if (0) {}
|
||||
#endif
|
||||
|
||||
B_801D9D50.unk_00 = 10;
|
||||
phi_v1 = (&func_801C8000)(&B_801D9D50);
|
||||
if (phi_v1 < 0) {
|
||||
func_800D31A0();
|
||||
}
|
||||
return phi_v1;
|
||||
}
|
||||
|
||||
s32 func_801C70E4(void) {
|
||||
return B_801D9DC8 == 1;
|
||||
}
|
||||
|
||||
// Used by EnMag and FileChoose
|
||||
s32 func_801C70FC(void) {
|
||||
return func_801C70E4();
|
||||
}
|
||||
|
||||
void func_801C711C(void* arg) {
|
||||
static void* B_801DBFC8;
|
||||
struct_801D9B90* arg0 = (struct_801D9B90*)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);
|
||||
var_s0 = 0;
|
||||
do {
|
||||
osRecvMesg(&arg0->unk_78, (OSMesg*)&sp58, OS_MESG_BLOCK);
|
||||
switch (*sp58) {
|
||||
case 1:
|
||||
temp_v0 = osViGetNextFramebuffer();
|
||||
if (B_801DBFC8 != temp_v0) {
|
||||
B_801DBFC8 = temp_v0;
|
||||
B_801D9DB8 = 1;
|
||||
}
|
||||
func_801C8AA8();
|
||||
break;
|
||||
case 4:
|
||||
LeoReset();
|
||||
break;
|
||||
case 3:
|
||||
var_s0 = 1;
|
||||
break;
|
||||
}
|
||||
} while (var_s0 == 0);
|
||||
IrqMgr_RemoveClient(arg0->unk_98, &arg0->unk_90);
|
||||
}
|
||||
|
||||
#if OOT_VERSION > NTSC_1_0
|
||||
void func_801C7B28_ne2(void) {
|
||||
s32 temp;
|
||||
|
||||
if (B_801D9DC0 != 0) {
|
||||
temp = (osGetTime() - B_801D9DC0) * 64 / 3000;
|
||||
if (1000000 - temp > 0) {
|
||||
Sleep_Usec(1000000 - temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void func_801C7268(void) {
|
||||
s32 pad;
|
||||
s32 sp20;
|
||||
s32 sp1C;
|
||||
|
||||
sp20 = func_801C6EF0();
|
||||
if (sp20 == 0) {
|
||||
func_801C6F30();
|
||||
}
|
||||
B_801D9DB8 = 1;
|
||||
B_801D9DC0 = 0;
|
||||
if (func_801C7064() == 1) {
|
||||
func_801C7098();
|
||||
} else if (B_801D9DC8 != 0) {
|
||||
B_801D9DC8 = 0;
|
||||
}
|
||||
#if OOT_VERSION == NTSC_1_0
|
||||
if (B_801D9DC0 != 0) {
|
||||
sp1C = (osGetTime() - B_801D9DC0) * 64 / 3000;
|
||||
|
||||
// Remnants from debug statements?
|
||||
(void)(osGetTime() - B_801D9DC0);
|
||||
(void)((osGetTime() - B_801D9DC0) * 64 / 3000);
|
||||
(void)((osGetTime() - B_801D9DC0) * 64 / 3000);
|
||||
|
||||
if (1000000 - sp1C > 0) {
|
||||
Sleep_Usec(1000000 - sp1C);
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (D_801D2EA8 == 1 || B_801E0F60 == 1 || B_801E0F64 == 1) {
|
||||
B_801D9DC0 = osGetTime();
|
||||
}
|
||||
func_801C7B28_ne2();
|
||||
#endif
|
||||
if (sp20 == 0) {
|
||||
func_801C6F78();
|
||||
}
|
||||
}
|
||||
|
||||
// Clears framebuffer
|
||||
void func_801C7438(void* arg0) {
|
||||
u16* var_v0;
|
||||
|
||||
for (var_v0 = (u16*)arg0; var_v0 < (u16*)arg0 + SCREEN_WIDTH * SCREEN_HEIGHT; var_v0++) {
|
||||
*var_v0 = 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) {
|
||||
if (B_801D9DB8 != 0) {
|
||||
B_801D9DB8 = 0;
|
||||
func_801C7438(sp2C);
|
||||
B_801D9DC0 = osGetTime();
|
||||
}
|
||||
if (arg0 != NULL) {
|
||||
func_801CA1F0(arg0, 96, 32, 192, 16, 11, sp2C, SCREEN_WIDTH);
|
||||
}
|
||||
if (arg1 != NULL) {
|
||||
func_801CA1F0(arg1, 0, 80, 320, 64, 11, sp2C, SCREEN_WIDTH);
|
||||
}
|
||||
if (arg2 != NULL) {
|
||||
func_801CA1F0(arg2, 0, 176, 320, 32, 11, sp2C, SCREEN_WIDTH);
|
||||
}
|
||||
#if OOT_VERSION <= NTSC_1_1
|
||||
osViBlack(0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void func_801C75BC(void* arg0, void* arg1, void* arg2) {
|
||||
s32 temp;
|
||||
|
||||
if (arg0 == NULL && arg1 == NULL && arg2 == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (B_801D9DB8) {}
|
||||
|
||||
if (arg0 != 0) {
|
||||
B_801D9DCC = arg0;
|
||||
}
|
||||
if (arg1 != 0) {
|
||||
B_801D9DD0 = arg1;
|
||||
}
|
||||
if (arg2 != 0) {
|
||||
B_801D9DD4 = arg2;
|
||||
}
|
||||
func_801C746C(arg0, arg1, arg2);
|
||||
}
|
||||
|
||||
void func_801C761C(void) {
|
||||
Sleep_Msec(100);
|
||||
func_801C746C(B_801D9DCC, B_801D9DD0, B_801D9DD4);
|
||||
}
|
||||
|
||||
s32 func_801C7658(void) {
|
||||
if (D_80121212 != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if OOT_VERSION <= NTSC_1_1
|
||||
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);
|
||||
#endif
|
||||
|
||||
osCreateMesgQueue(&B_801D9D80, B_801D9DB0, ARRAY_COUNT(B_801D9DB0));
|
||||
osCreateMesgQueue(&B_801D9D98, B_801D9DB4, ARRAY_COUNT(B_801D9DB4));
|
||||
|
||||
StackCheck_Init(&B_801DBFA8, B_801DAFA8, STACK_TOP(B_801DAFA8), 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;
|
||||
|
||||
(&func_801C8000)(&B_801D9D50);
|
||||
|
||||
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);
|
||||
|
||||
B_801D9D50.unk_00 = 13;
|
||||
(&func_801C8000)(&B_801D9D50);
|
||||
|
||||
#if OOT_VERSION > NTSC_1_1
|
||||
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);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 func_801C7818(void) {
|
||||
#if OOT_VERSION > NTSC_1_0
|
||||
B_801D9DB8 = 1;
|
||||
B_801D9DC0 = 0;
|
||||
#endif
|
||||
|
||||
B_801D9D50.unk_00 = 12;
|
||||
(&func_801C8000)(&B_801D9D50);
|
||||
|
||||
while (func_801C81C4() == 0) {
|
||||
// the number 16666 sounds like it could be 1 frame (at 60 frames per second)
|
||||
Sleep_Usec(1000000 * 1 / 60);
|
||||
}
|
||||
|
||||
#if OOT_VERSION > NTSC_1_0
|
||||
if (D_801D2EA8 == 1 || B_801E0F60 == 1 || B_801E0F64 == 1) {
|
||||
B_801D9DC0 = osGetTime();
|
||||
}
|
||||
func_801C7B28_ne2();
|
||||
#endif
|
||||
|
||||
if (func_801C81C4() != 2) {
|
||||
func_801C761C();
|
||||
func_800D31A0();
|
||||
return -3;
|
||||
}
|
||||
|
||||
func_801C7018();
|
||||
D_80121212 = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 func_801C78B8(void) {
|
||||
s32 phi_v1 = func_801C7658();
|
||||
|
||||
if (phi_v1 == 0) {
|
||||
phi_v1 = func_801C7818();
|
||||
}
|
||||
return phi_v1;
|
||||
}
|
||||
|
||||
s32 func_801C78F0(void) {
|
||||
B_801D9D50.unk_00 = 0;
|
||||
return (&func_801C8000)(&B_801D9D50);
|
||||
}
|
||||
|
||||
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);
|
||||
osGetTime();
|
||||
B_801D9D50.unk_00 = 6;
|
||||
while ((&func_801C8000)(&B_801D9D50) != 0) {
|
||||
Sleep_Usec(16666); // 100000 / 6
|
||||
}
|
||||
B_801D9D50.unk_00 = 7;
|
||||
if ((&func_801C8000)(&B_801D9D50) != 0) {
|
||||
func_800D31A0();
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void func_801C7A10(LEODiskID* arg0) {
|
||||
}
|
||||
|
||||
// Checks diskId, sets B_801D9DC8 and returns true if diskId is correct
|
||||
s32 func_801C7A1C(struct_801E0D18* arg0) {
|
||||
static LEODiskID B_801DBFD0;
|
||||
static s32 B_801DBFF0; // bool
|
||||
|
||||
func_801C7A10(&arg0->diskId);
|
||||
if (!B_801DBFF0) {
|
||||
#if OOT_NTSC
|
||||
if (bcmp(arg0->diskId.gameName, "EZLJ", 4) == 0 || bcmp(arg0->diskId.gameName, "EZLE", 4) == 0)
|
||||
#else
|
||||
if (bcmp(arg0->diskId.gameName, "EZLP", 4) == 0)
|
||||
#endif
|
||||
{
|
||||
B_801DBFD0 = arg0->diskId;
|
||||
B_801DBFF0 = true;
|
||||
B_801D9DC8 = 1;
|
||||
} else {
|
||||
B_801D9DC8 = 2;
|
||||
}
|
||||
} else if (bcmp(&B_801DBFD0, &arg0->diskId, sizeof(LEODiskID)) == 0) {
|
||||
B_801D9DC8 = 1;
|
||||
} else {
|
||||
B_801D9DC8 = 2;
|
||||
}
|
||||
return B_801D9DC8 == 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;
|
||||
} else {
|
||||
temp_v0 = LeoLBAToByte(1, sp24, &sp20);
|
||||
if (temp_v0 != LEO_ERROR_GOOD) {
|
||||
return temp_v0;
|
||||
}
|
||||
}
|
||||
*arg1 = sp24 + 1;
|
||||
*arg2 = arg0 - sp20;
|
||||
return LEO_ERROR_GOOD;
|
||||
}
|
||||
|
||||
s32 func_801C7BEC(s32 startLBA) {
|
||||
s32 bytes;
|
||||
|
||||
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;
|
||||
s32 var_s1;
|
||||
s32 temp_v1_2;
|
||||
|
||||
func_801C6FD8();
|
||||
func_801C6F30();
|
||||
B_801D9DB8 = 1;
|
||||
B_801D9DC0 = 0;
|
||||
func_801C7B48(offset, &sp5C, &sp54);
|
||||
func_801C7B48(offset + size, &sp58, &sp50);
|
||||
sp4C = D_801D2E50;
|
||||
if (sp5C == sp58) {
|
||||
func_801C7920(sp5C, sp4C, func_801C7BEC(sp5C));
|
||||
bcopy((u8*)sp4C + sp54, 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(sp5C + 1, (u8*)dest + func_801C7BEC(sp5C) - sp54, 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 OOT_VERSION == NTSC_1_0
|
||||
if (B_801D9DC0 != 0) {
|
||||
temp_v1_2 = (osGetTime() - B_801D9DC0) * 64 / 3000;
|
||||
if (1000000 - temp_v1_2 > 0) {
|
||||
Sleep_Usec(1000000 - temp_v1_2);
|
||||
}
|
||||
}
|
||||
#else
|
||||
func_801C7B28_ne2();
|
||||
#endif
|
||||
func_801C7018();
|
||||
func_801C6F78();
|
||||
}
|
||||
|
||||
void func_801C7E78(void) {
|
||||
}
|
||||
|
||||
s32 func_801C7E80(void) {
|
||||
s32 sp24;
|
||||
s32 sp20;
|
||||
s32 sp1C;
|
||||
uintptr_t sp18;
|
||||
|
||||
if (B_801D9D48 != 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);
|
||||
bzero((void*)sp18, sp20 - sp24);
|
||||
func_800AD4C0(B_801D9D48->unk_010);
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 func_801C7F24(void) {
|
||||
uintptr_t temp_a0;
|
||||
struct_801D9C30* temp_v0;
|
||||
|
||||
if (B_801D9D48 == 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;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void n64dd_SetDiskVersion(s32 arg0) {
|
||||
if (arg0 != 0) {
|
||||
if (B_801D9D48 == 0) {
|
||||
func_801C7E80();
|
||||
}
|
||||
} else if (B_801D9D48 != 0) {
|
||||
func_801C7F24();
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@
|
|||
#include "cic6105.h"
|
||||
#endif
|
||||
|
||||
#pragma increment_block_number "gc-eu:149 gc-eu-mq:149 gc-jp:151 gc-jp-ce:151 gc-jp-mq:151 gc-us:151 gc-us-mq:151"
|
||||
#pragma increment_block_number "gc-eu:148 gc-eu-mq:148 gc-jp:150 gc-jp-ce:150 gc-jp-mq:150 gc-us:150 gc-us-mq:150"
|
||||
|
||||
#define FLAGS ACTOR_FLAG_4
|
||||
|
||||
|
|
|
@ -19,8 +19,6 @@ D_80121212 = 0x80121AE2; // size:0x1 type:u8
|
|||
_n64ddSegmentStart = 0x801C7740;
|
||||
_n64ddSegmentRomStart = 0x00B8ADA0;
|
||||
_n64ddSegmentRomEnd = 0x00B9DA70;
|
||||
D_801DA410 = 0x801DA410;
|
||||
D_801E8090 = 0x801E8090;
|
||||
D_800FEE70 = 0x800FF4B0; // size:0xB0 type:n64ddStruct_800FEE70_pointers
|
||||
gPadMgr = 0x8011DBD0; // size:0x468 type:PadMgr
|
||||
gFaultMgr = 0x80121B60; // size:0x5D8 type:FaultMgr_v1
|
||||
|
|
|
@ -189,6 +189,7 @@ def compare_pointers(version: str) -> dict[Path, BssSection]:
|
|||
if not (
|
||||
mapfile_segment.name.startswith("..boot")
|
||||
or mapfile_segment.name.startswith("..code")
|
||||
or mapfile_segment.name.startswith("..n64dd")
|
||||
or mapfile_segment.name.startswith("..ovl_")
|
||||
):
|
||||
continue
|
||||
|
|
|
@ -9,28 +9,3 @@ D_0F000000 = 0x0F000000;
|
|||
|
||||
// z_bg_mjin
|
||||
D_06000000 = 0x06000000;
|
||||
|
||||
#if PLATFORM_N64
|
||||
|
||||
// code_n64dd_800AD410.c
|
||||
func_801C6E80 = 0x801C7740;
|
||||
func_801C7C1C = 0x801C8510;
|
||||
D_801DA410 = 0x801DA410;
|
||||
D_801E8090 = 0x801E8090;
|
||||
|
||||
// game.c
|
||||
func_801C7E78 = 0x801C86F0;
|
||||
func_801C6EA0 = 0x801C7760;
|
||||
|
||||
// z_en_mag.c
|
||||
func_801C70FC = 0x801C79BC;
|
||||
|
||||
// z_setup.c
|
||||
n64dd_SetDiskVersion = 0x801C8808;
|
||||
|
||||
// z_title.c
|
||||
func_801C7818 = 0x801C8090;
|
||||
func_801C7268 = 0x801C7BC4;
|
||||
func_801C7658 = 0x801C7ED0;
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue