diff --git a/include/macros.h b/include/macros.h index a5aa2754fb..126d5d990e 100644 --- a/include/macros.h +++ b/include/macros.h @@ -214,7 +214,6 @@ extern struct GraphicsContext* __gfxCtx; #define ZELDA_ARENA_FREE(size, file, line) ZeldaArena_FreeDebug(size, file, line) #define LOG_UTILS_CHECK_NULL_POINTER(exp, ptr, file, line) LogUtils_CheckNullPointer(exp, ptr, file, line) #define LOG_UTILS_CHECK_VALID_POINTER(exp, ptr, file, line) LogUtils_CheckValidPointer(exp, ptr, file, line) -#define HUNGUP_AND_CRASH(file, line) Fault_AddHungupAndCrash(file, line) #define GAME_ALLOC_MALLOC(alloc, size, file, line) GameAlloc_MallocDebug(alloc, size, file, line) #else @@ -247,10 +246,15 @@ extern struct GraphicsContext* __gfxCtx; #define ZELDA_ARENA_FREE(size, file, line) ZeldaArena_Free(size) #define LOG_UTILS_CHECK_NULL_POINTER(exp, ptr, file, line) (void)0 #define LOG_UTILS_CHECK_VALID_POINTER(exp, ptr, file, line) (void)0 -#define HUNGUP_AND_CRASH(file, line) LogUtils_HungupThread(file, line) #define GAME_ALLOC_MALLOC(alloc, size, file, line) GameAlloc_Malloc(alloc, size) -#endif /* OOT_DEBUG */ +#endif + +#if PLATFORM_N64 || OOT_DEBUG +#define HUNGUP_AND_CRASH(file, line) Fault_AddHungupAndCrash(file, line) +#else +#define HUNGUP_AND_CRASH(file, line) LogUtils_HungupThread(file, line) +#endif #if OOT_NTSC #define LANGUAGE_ARRAY(jpn, eng, ger, fra) { jpn, eng } diff --git a/include/n64dd.h b/include/n64dd.h index d744711849..6a9867fcdc 100644 --- a/include/n64dd.h +++ b/include/n64dd.h @@ -2,12 +2,16 @@ #define N64DD_H #include "ultra64.h" -#include "z64dma.h" -#include "z64pause.h" #include "z64scene.h" +struct GameState; +union Gfx; +struct PlayState; +struct PauseMapMarksData; struct RegEditor; +struct RoomContext; struct SaveContext; +struct Scene; // TODO Use the specific pointer types instead of void* typedef struct n64ddStruct_800FF4B0_pointers { @@ -20,21 +24,27 @@ typedef struct n64ddStruct_800FF4B0_pointers { } n64ddStruct_800FF4B0_pointers; // size = 0xB0 struct n64ddStruct_80121AF0; -struct PlayState; typedef struct n64ddStruct_80121AF0 { void (*unk_00)(n64ddStruct_800FF4B0_pointers*, struct n64ddStruct_80121AF0*); void (*unk_04)(void); - char unk_08[0x2C]; - void (*unk_34)(PauseMapMarksData**); - void (*unk_38)(PauseMapMarksData**); + void (*unk_08)(struct PlayState* play, struct RoomContext* roomCtx, s32 roomNum); + void (*unk_0C)(struct PlayState* play); + void (*unk_10)(struct PlayState* play); + void (*unk_14)(struct PlayState* play); + char unk_18[0x1C]; + void (*unk_34)(struct PauseMapMarksData**); + void (*unk_38)(struct PauseMapMarksData**); void (*unk_3C)(void); void (*unk_40)(void); s32 (*unk_44)(struct PlayState*); - char unk_48[0x24]; + struct SceneTableEntry* (*unk_48)(s32 sceneId, struct SceneTableEntry* sceneTable); + char unk_4C[0x08]; + s32 (*unk_54)(struct PlayState*); + char unk_58[0x14]; void (*unk_6C)(struct PlayState*, SceneDrawConfigFunc*); - s32 (*unk_70)(DmaRequest* req, void* ram, uintptr_t vrom, size_t size, u32 unk, OSMesgQueue* queue, OSMesg msg); - char unk_74[4]; + s32 (*unk_70)(struct DmaRequest* req, void* ram, uintptr_t vrom, size_t size, u32 unk, OSMesgQueue* queue, OSMesg msg); + void (*unk_74)(struct GameState*); s32 (*unk_78)(struct PlayState*, void*, void*); } n64ddStruct_80121AF0; // size = ? @@ -46,6 +56,10 @@ n64ddStruct_800FF4B0_pointers* func_800ADBD0(void); void func_800ADC00(void); void func_800ADC08(s32 arg0, s32 arg1, s32 arg2); +void func_801C8510_unknown(void* dest, s32 offset, s32 size); +void func_801C86F0_unknown(void); +void func_801C7760_unknown(union Gfx** gfx); + extern n64ddStruct_800FF4B0_pointers D_800FF4B0; extern n64ddStruct_80121AF0* B_80121AF0; diff --git a/src/code/code_n64dd_800AD4C0.c b/src/code/code_n64dd_800AD4C0.c index 315b6fdd1c..ed1477f93c 100644 --- a/src/code/code_n64dd_800AD4C0.c +++ b/src/code/code_n64dd_800AD4C0.c @@ -3,7 +3,6 @@ #include "n64dd.h" // TODO functions of unknown prototype -extern char func_801C8510_unknown[]; extern char osGetIntMask[]; extern char osSetTime[]; diff --git a/src/code/game.c b/src/code/game.c index 3fe16c8182..ffb8bc8471 100644 --- a/src/code/game.c +++ b/src/code/game.c @@ -1,8 +1,9 @@ #include "global.h" -#if OOT_DEBUG #include "fault.h" -#endif #include "terminal.h" +#if PLATFORM_N64 +#include "n64dd.h" +#endif #pragma increment_block_number "gc-eu:128 gc-eu-mq:128 gc-jp:128 gc-jp-ce:128 gc-jp-mq:128 gc-us:128 gc-us-mq:128" @@ -70,7 +71,11 @@ void GameState_SetFBFilter(Gfx** gfxP) { } void func_800C4344(GameState* gameState) { -#if OOT_DEBUG +#if PLATFORM_N64 + if (B_80121AE2 != 0) { + func_801C86F0_unknown(); + } +#elif OOT_DEBUG Input* selectedInput; s32 hexDumpSize; u16 inputCompareValue; @@ -238,6 +243,12 @@ void func_800C49F4(GraphicsContext* gfxCtx) { newDlist = Gfx_Open(polyOpaP = POLY_OPA_DISP); gSPDisplayList(OVERLAY_DISP++, newDlist); +#if PLATFORM_N64 + if (B_80121AE2 != 0) { + func_801C7760_unknown(&newDlist); + } +#endif + gSPEndDisplayList(newDlist++); Gfx_Close(polyOpaP, newDlist); POLY_OPA_DISP = newDlist; @@ -258,6 +269,15 @@ void GameState_Update(GameState* gameState) { gameState->main(gameState); +#if PLATFORM_N64 + if (B_80121AE2 != 0) { + func_801C86F0_unknown(); + } + if ((B_80121AF0 != NULL) && (B_80121AF0->unk_74 != NULL)) { + B_80121AF0->unk_74(gameState); + } +#endif + func_800C4344(gameState); #if OOT_DEBUG @@ -356,7 +376,11 @@ void GameState_InitArena(GameState* gameState, size_t size) { } else { THA_Init(&gameState->tha, NULL, 0); PRINTF(T("ハイラル確保失敗\n", "Failure to secure Hyrule\n")); +#if PLATFORM_N64 + HUNGUP_AND_CRASH("../game.c", 985); +#else HUNGUP_AND_CRASH("../game.c", 999); +#endif } } @@ -396,7 +420,12 @@ void GameState_Realloc(GameState* gameState, size_t size) { #if OOT_DEBUG SystemArena_Display(); #endif + +#if PLATFORM_N64 + HUNGUP_AND_CRASH("../game.c", 1030); +#else HUNGUP_AND_CRASH("../game.c", 1044); +#endif } } diff --git a/src/code/z_play.c b/src/code/z_play.c index 0c106f6102..084ef4ddce 100644 --- a/src/code/z_play.c +++ b/src/code/z_play.c @@ -1,11 +1,12 @@ #include "global.h" -#if OOT_DEBUG #include "fault.h" -#endif #include "quake.h" #include "terminal.h" #include "versions.h" +#if PLATFORM_N64 +#include "n64dd.h" +#endif #include "z64frame_advance.h" @@ -175,7 +176,9 @@ void Play_SetupTransition(PlayState* this, s32 transitionType) { break; default: -#if OOT_VERSION < GC_EU_MQ_DBG +#if PLATFORM_N64 + HUNGUP_AND_CRASH("../z_play.c", 2269); +#elif OOT_VERSION < GC_EU_MQ_DBG HUNGUP_AND_CRASH("../z_play.c", 2287); #elif OOT_VERSION < GC_JP_CE HUNGUP_AND_CRASH("../z_play.c", 2290); @@ -239,6 +242,12 @@ void Play_Destroy(GameState* thisx) { KaleidoManager_Destroy(); ZeldaArena_Cleanup(); +#if PLATFORM_N64 + if ((B_80121AF0 != NULL) && (B_80121AF0->unk_14 != NULL)) { + B_80121AF0->unk_14(this); + } +#endif + #if OOT_DEBUG Fault_RemoveClient(&D_801614B8); #endif @@ -268,6 +277,13 @@ void Play_Init(GameState* thisx) { #endif GameState_Realloc(&this->state, 0x1D4790); + +#if PLATFORM_N64 + if ((B_80121AF0 != NULL) && (B_80121AF0->unk_10 != NULL)) { + B_80121AF0->unk_10(this); + } +#endif + KaleidoManager_Init(this); View_Init(&this->view, gfxCtx); Audio_SetExtraFilter(0); @@ -360,6 +376,7 @@ void Play_Init(GameState* thisx) { PRINTF("\nSCENE_NO=%d COUNTER=%d\n", ((void)0, gSaveContext.save.entranceIndex), gSaveContext.sceneLayer); +#if PLATFORM_GC // When entering Gerudo Valley in the credits, trigger the GC emulator to play the ending movie. // The emulator constantly checks whether PC is 0x81000000, so this works even though it's not a valid address. if ((gEntranceTable[((void)0, gSaveContext.save.entranceIndex)].sceneId == SCENE_GERUDO_VALLEY) && @@ -368,8 +385,17 @@ void Play_Init(GameState* thisx) { ((void (*)(void))0x81000000)(); PRINTF(T("出戻り?\n", "Return?\n")); } +#endif +#if PLATFORM_N64 + if ((B_80121AF0 != NULL && B_80121AF0->unk_54 != NULL && B_80121AF0->unk_54(this))) { + } else { + Cutscene_HandleEntranceTriggers(this); + } +#else Cutscene_HandleEntranceTriggers(this); +#endif + KaleidoScopeCall_Init(this); Interface_Init(this); @@ -1058,6 +1084,10 @@ skip: } void Play_DrawOverlayElements(PlayState* this) { +#if PLATFORM_N64 + s32 pad; +#endif + if (IS_PAUSED(&this->pauseCtx)) { KaleidoScopeCall_Draw(this); } @@ -1147,7 +1177,12 @@ void Play_Draw(PlayState* this) { TransitionFade_Draw(&this->transitionFadeFlash, &gfxP); - if (gVisMonoColor.a > 0) { +#if PLATFORM_N64 + if (gVisMonoColor.a != 0) +#else + if (gVisMonoColor.a > 0) +#endif + { gPlayVisMono.vis.primColor.rgba = gVisMonoColor.rgba; VisMono_Draw(&gPlayVisMono, &gfxP); } @@ -1457,6 +1492,19 @@ void* Play_LoadFile(PlayState* this, RomFile* file) { return allocp; } +#if PLATFORM_N64 +void* Play_LoadFileFromDiskDrive(PlayState* this, RomFile* file) { + u32 size; + void* allocp; + + size = file->vromEnd - file->vromStart; + allocp = THA_AllocTailAlign16(&this->state.tha, size); + func_801C8510_unknown(allocp, file->vromStart, size); + + return allocp; +} +#endif + void Play_InitEnvironment(PlayState* this, s16 skyboxId) { Skybox_Init(&this->state, &this->skyboxCtx, skyboxId); Environment_Init(this, &this->envCtx, 0); @@ -1485,24 +1533,52 @@ void Play_InitScene(PlayState* this, s32 spawn) { } void Play_SpawnScene(PlayState* this, s32 sceneId, s32 spawn) { - SceneTableEntry* scene = &gSceneTable[sceneId]; + SceneTableEntry* scene; u32 size; +#if PLATFORM_N64 + if ((B_80121AF0 != NULL) && (B_80121AF0->unk_48 != NULL)) { + scene = B_80121AF0->unk_48(sceneId, gSceneTable); + } else { + scene = &gSceneTable[sceneId]; + scene->unk_13 = 0; + } +#else + scene = &gSceneTable[sceneId]; scene->unk_13 = 0; +#endif + this->loadedScene = scene; this->sceneId = sceneId; this->sceneDrawConfig = scene->drawConfig; PRINTF("\nSCENE SIZE %fK\n", (scene->sceneFile.vromEnd - scene->sceneFile.vromStart) / 1024.0f); +#if PLATFORM_N64 + if ((B_80121AF0 != NULL) && (scene->unk_12 > 0)) { + this->sceneSegment = Play_LoadFileFromDiskDrive(this, &scene->sceneFile); + scene->unk_13 = 1; + } else { + this->sceneSegment = Play_LoadFile(this, &scene->sceneFile); + scene->unk_13 = 0; + } +#else this->sceneSegment = Play_LoadFile(this, &scene->sceneFile); scene->unk_13 = 0; +#endif + ASSERT(this->sceneSegment != NULL, "this->sceneSegment != NULL", "../z_play.c", 4960); gSegments[2] = VIRTUAL_TO_PHYSICAL(this->sceneSegment); Play_InitScene(this, spawn); +#if PLATFORM_N64 + if ((B_80121AF0 != NULL) && (B_80121AF0->unk_0C != NULL)) { + B_80121AF0->unk_0C(this); + } +#endif + size = func_80096FE8(this, &this->roomCtx); PRINTF("ROOM SIZE=%fK\n", size / 1024.0f); @@ -1798,11 +1874,13 @@ void Play_LoadToLastEntrance(PlayState* this) { (this->sceneId == SCENE_INSIDE_GANONS_CASTLE_COLLAPSE) || (this->sceneId == SCENE_GANON_BOSS)) { this->nextEntranceIndex = ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_0; Item_Give(this, ITEM_SWORD_MASTER); +#if OOT_VERSION >= PAL_1_1 } else if ((gSaveContext.save.entranceIndex == ENTR_HYRULE_FIELD_11) || (gSaveContext.save.entranceIndex == ENTR_HYRULE_FIELD_12) || (gSaveContext.save.entranceIndex == ENTR_HYRULE_FIELD_13) || (gSaveContext.save.entranceIndex == ENTR_HYRULE_FIELD_15)) { this->nextEntranceIndex = ENTR_HYRULE_FIELD_6; +#endif } else { this->nextEntranceIndex = gSaveContext.save.entranceIndex; } diff --git a/src/code/z_room.c b/src/code/z_room.c index a660d41a33..2b727deea9 100644 --- a/src/code/z_room.c +++ b/src/code/z_room.c @@ -1,5 +1,9 @@ #include "global.h" +#include "fault.h" #include "terminal.h" +#if PLATFORM_N64 +#include "n64dd.h" +#endif Vec3f D_801270A0 = { 0.0f, 0.0f, 0.0f }; @@ -295,6 +299,7 @@ void Room_DrawBackground2D(Gfx** gfxP, void* tex, void* tlut, u16 width, u16 hei bg = (uObjBg*)(gfx + 1); gSPBranchList(gfx, (Gfx*)(bg + 1)); + gfx = (Gfx*)(bg + 1); bg->b.imageX = 0; bg->b.imageW = width * (1 << 2); @@ -309,8 +314,6 @@ void Room_DrawBackground2D(Gfx** gfxP, void* tex, void* tlut, u16 width, u16 hei bg->b.imagePal = 0; bg->b.imageFlip = 0; - gfx = (Gfx*)(bg + 1); - if (fmt == G_IM_FMT_CI) { gDPLoadTLUT(gfx++, tlutCount, 256, tlut); } else { @@ -441,7 +444,11 @@ RoomShapeImageMultiBgEntry* Room_GetImageMultiBgEntry(RoomShapeImageMulti* roomS PRINTF(VT_COL(RED, WHITE) T("z_room.c:カメラIDに一致するデータが存在しません camid=%d\n", "z_room.c: Data consistent with camera id does not exist camid=%d\n") VT_RST, bgCamIndex); +#if PLATFORM_N64 + Fault_AddHungupAndCrash("../z_room.c", 721); +#else LogUtils_HungupThread("../z_room.c", 726); +#endif return NULL; } @@ -521,7 +528,11 @@ void Room_DrawImage(PlayState* play, Room* room, u32 flags) { } else if (roomShape->amountType == ROOM_SHAPE_IMAGE_AMOUNT_MULTI) { Room_DrawImageMulti(play, room, flags); } else { +#if PLATFORM_N64 + Fault_AddHungupAndCrash("../z_room.c", 836); +#else LogUtils_HungupThread("../z_room.c", 841); +#endif } } @@ -610,10 +621,20 @@ s32 func_8009728C(PlayState* play, RoomContext* roomCtx, s32 roomNum) { (void*)ALIGN16((uintptr_t)roomCtx->bufPtrs[roomCtx->unk_30] - ((size + 8) * roomCtx->unk_30 + 7)); osCreateMesgQueue(&roomCtx->loadQueue, &roomCtx->loadMsg, 1); + +#if PLATFORM_N64 + if ((B_80121AF0 != NULL) && (B_80121AF0->unk_08 != NULL)) { + B_80121AF0->unk_08(play, roomCtx, roomNum); + } else { + DMA_REQUEST_ASYNC(&roomCtx->dmaRequest, roomCtx->unk_34, play->roomList[roomNum].vromStart, size, 0, + &roomCtx->loadQueue, NULL, "../z_room.c", 1036); + } +#else DMA_REQUEST_ASYNC(&roomCtx->dmaRequest, roomCtx->unk_34, play->roomList[roomNum].vromStart, size, 0, &roomCtx->loadQueue, NULL, "../z_room.c", 1036); - roomCtx->unk_30 ^= 1; +#endif + roomCtx->unk_30 ^= 1; return true; } diff --git a/tools/disasm/ntsc-1.2/functions.txt b/tools/disasm/ntsc-1.2/functions.txt index 60bc1a729f..457c53d6eb 100644 --- a/tools/disasm/ntsc-1.2/functions.txt +++ b/tools/disasm/ntsc-1.2/functions.txt @@ -1990,7 +1990,7 @@ Play_Main = 0x8009D1B8; // type:func Play_InCsMode = 0x8009D1F8; // type:func func_800BFCB8 = 0x8009D22C; // type:func Play_LoadFile = 0x8009D3D8; // type:func -func_8009D434_unknown = 0x8009D434; // type:func +Play_LoadFileFromDiskDrive = 0x8009D434; // type:func Play_InitEnvironment = 0x8009D490; // type:func Play_InitScene = 0x8009D4D8; // type:func Play_SpawnScene = 0x8009D5DC; // type:func diff --git a/undefined_syms.txt b/undefined_syms.txt index 94e26b9045..7ce3eb5ae1 100644 --- a/undefined_syms.txt +++ b/undefined_syms.txt @@ -26,6 +26,10 @@ func_801C8510_unknown = 0x801C8510; D_801DA410 = 0x801DA410; D_801E8090 = 0x801E8090; +// game.c +func_801C86F0_unknown = 0x801C86F0; +func_801C7760_unknown = 0x801C7760; + // z_en_mag.c func_801C79BC_unknown = 0x801C79BC;