diff --git a/assets/xml/interface/icon_item_dungeon_static.xml b/assets/xml/interface/icon_item_dungeon_static.xml new file mode 100644 index 000000000..04ba39338 --- /dev/null +++ b/assets/xml/interface/icon_item_dungeon_static.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/interface/icon_item_field_static.xml b/assets/xml/interface/icon_item_field_static.xml new file mode 100644 index 000000000..8fe3a9299 --- /dev/null +++ b/assets/xml/interface/icon_item_field_static.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/interface/icon_item_jpn_static.xml b/assets/xml/interface/icon_item_jpn_static.xml new file mode 100644 index 000000000..aff93d07e --- /dev/null +++ b/assets/xml/interface/icon_item_jpn_static.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/interface/parameter_static.xml b/assets/xml/interface/parameter_static.xml index 7532a95b8..e5e0808c0 100644 --- a/assets/xml/interface/parameter_static.xml +++ b/assets/xml/interface/parameter_static.xml @@ -127,6 +127,7 @@ + diff --git a/assets/xml/objects/object_bee.xml b/assets/xml/objects/object_bee.xml index 735d191f3..8fcd930fa 100644 --- a/assets/xml/objects/object_bee.xml +++ b/assets/xml/objects/object_bee.xml @@ -1,28 +1,38 @@  + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_kamejima.xml b/assets/xml/objects/object_kamejima.xml index e8368051d..cce285475 100644 --- a/assets/xml/objects/object_kamejima.xml +++ b/assets/xml/objects/object_kamejima.xml @@ -1,81 +1,99 @@  + - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_umajump.xml b/assets/xml/objects/object_umajump.xml index 6d86b4298..cec43c3a6 100644 --- a/assets/xml/objects/object_umajump.xml +++ b/assets/xml/objects/object_umajump.xml @@ -2,7 +2,7 @@ - + diff --git a/assets/xml/overlays/ovl_Dm_Char08.xml b/assets/xml/overlays/ovl_Dm_Char08.xml new file mode 100644 index 000000000..4d96a8eb4 --- /dev/null +++ b/assets/xml/overlays/ovl_Dm_Char08.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/docs/tutorial/other_functions.md b/docs/tutorial/other_functions.md index 255ae9eb4..1c8ba6b5b 100644 --- a/docs/tutorial/other_functions.md +++ b/docs/tutorial/other_functions.md @@ -401,7 +401,7 @@ There remains one thing we need to fix before trying to compile it, namely `*(&g ```C /* 0x0EF8 */ u8 weekEventReg[100]; // "week_event_reg" - /* 0x0F5C */ u32 mapsVisited; // "area_arrival" + /* 0x0F5C */ u32 regionsVisited; // "area_arrival" ``` so it's somewhere in `weekEventReg`. `0xF37 - 0xEF8 = 0x3F = 63`, and it's a byte array, so the access is actually `gSaveContext.save.weekEventReg[63] & 0x80`. Now it will compile. We also don't use `!= 0` for flag comparisons: just `if (gSaveContext.save.weekEventReg[63] & 0x80)` will do. diff --git a/include/PR/gbi.h b/include/PR/gbi.h index 2c29420ea..632ca3caf 100644 --- a/include/PR/gbi.h +++ b/include/PR/gbi.h @@ -3572,7 +3572,7 @@ _DW({ \ #define gDPLoadTextureBlock(pkt, timg, fmt, siz, width, height, \ pal, cms, cmt, masks, maskt, shifts, shiftt) \ -{ \ +_DW({ \ gDPSetTextureImage(pkt, fmt, siz##_LOAD_BLOCK, 1, timg); \ gDPSetTile(pkt, fmt, siz##_LOAD_BLOCK, 0, 0, G_TX_LOADTILE, \ 0 , cmt, maskt, shiftt, cms, masks, shifts); \ @@ -3588,7 +3588,7 @@ _DW({ \ gDPSetTileSize(pkt, G_TX_RENDERTILE, 0, 0, \ ((width)-1) << G_TEXTURE_IMAGE_FRAC, \ ((height)-1) << G_TEXTURE_IMAGE_FRAC); \ -} +}) #define gDPLoadTextureBlockYuv(pkt, timg, fmt, siz, width, height, \ pal, cms, cmt, masks, maskt, shifts, shiftt) \ diff --git a/include/functions.h b/include/functions.h index dbbcc07df..f238824d5 100644 --- a/include/functions.h +++ b/include/functions.h @@ -882,6 +882,7 @@ void func_800C636C(PlayState* play, DynaCollisionContext* dyna, s32 bgId); void func_800C63C4(PlayState* play, DynaCollisionContext* dyna, s32 bgId); void func_800C641C(PlayState* play, DynaCollisionContext* dyna, s32 bgId); void func_800C6474(PlayState* play, DynaCollisionContext* dyna, s32 bgId); +void func_800C6554(PlayState* play, DynaCollisionContext* dyna); void DynaPoly_DeleteBgActor(PlayState* play, DynaCollisionContext* dyna, s32 bgId); void BgCheck_CalcWaterboxDimensions(Vec3f* minPos, Vec3f* maxXPos, Vec3f* maxZPos, Vec3s* minPosOut, s16* xLength, s16* zLength); void DynaPoly_ExpandSRT(PlayState* play, DynaCollisionContext* dyna, s32 bgId, s32* vtxStartIndex, s32* polyStartIndex, s32* waterBoxStartIndex); @@ -1672,8 +1673,8 @@ void func_80106644(PlayState* play, s16 arg1, s16 arg2, s16 arg3); // void func_80108558(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6, UNK_TYPE4 param_7); // void func_80108A10(void); // void func_80108A64(void); -// void func_80108AF8(void); -// void func_801090B0(void); +void func_80108AF8(PlayState* play); +s32 func_801090B0(s32 arg0); s32 func_80109124(s16 arg0); // void func_801091F0(void); // void func_80109428(void); @@ -1805,15 +1806,15 @@ Vec3f* OLib_Vec3fDiffDegF(Vec3f* dest, Vec3f* a, Vec3f* b); Vec3s* OLib_Vec3fDiffBinAng(Vec3s* dest, Vec3f* a, Vec3f* b); void OLib_DbCameraVec3fDiff(PosRot* a, Vec3f* b, Vec3f* dest, s16 mode); void OLib_DbCameraVec3fSum(PosRot* a, Vec3f* b, Vec3f* dest, s16 mode); -// void func_8010CB80(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5, UNK_TYPE2 param_6, UNK_TYPE2 param_7, UNK_TYPE2 param_8, UNK_TYPE2 param_9, UNK_TYPE2 param_10); -Gfx* func_8010CD98(Gfx* displayListHead, void* texture, s16 textureWidth, s16 textureHeight, s16 rectLeft, s16 rectTop, s16 rectWidth, s16 rectHeight, u16 dsdx, u16 dtdy); +Gfx* func_8010CB80(Gfx* gfx, TexturePtr texture, s16 textureWidth, s16 textureHeight, s16 rectLeft, s16 rectTop, s16 rectWidth, s16 rectHeight, u16 dsdx, u16 dtdy); +Gfx* func_8010CD98(Gfx* gfx, TexturePtr texture, s16 textureWidth, s16 textureHeight, s16 rectLeft, s16 rectTop, s16 rectWidth, s16 rectHeight, u16 dsdx, u16 dtdy); // void func_8010CFBC(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5, UNK_TYPE2 param_6, UNK_TYPE2 param_7, UNK_TYPE2 param_8, UNK_TYPE2 param_9, UNK_TYPE2 param_10, UNK_TYPE2 param_11, UNK_TYPE2 param_12, UNK_TYPE2 param_13, UNK_TYPE2 param_14); // void func_8010D2D4(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5, UNK_TYPE2 param_6, UNK_TYPE2 param_7, UNK_TYPE2 param_8, UNK_TYPE2 param_9, UNK_TYPE2 param_10, UNK_TYPE2 param_11); // void func_8010D480(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5, UNK_TYPE2 param_6, UNK_TYPE2 param_7, UNK_TYPE2 param_8, UNK_TYPE2 param_9, UNK_TYPE2 param_10, UNK_TYPE2 param_11, UNK_TYPE2 param_12, UNK_TYPE2 param_13, UNK_TYPE2 param_14, UNK_TYPE4 param_15, UNK_TYPE4 param_16); -Gfx* func_8010D7D0(Gfx* displayListHead, void* texture, s16 textureWidth, s16 textureHeight, s16 rectLeft, s16 rectTop, s16 rectWidth, s16 rectHeight, u16 dsdx, u16 dtdy); +Gfx* func_8010D7D0(Gfx* gfx, TexturePtr texture, s16 textureWidth, s16 textureHeight, s16 rectLeft, s16 rectTop, s16 rectWidth, s16 rectHeight, u16 dsdx, u16 dtdy); // void func_8010D9F4(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5, UNK_TYPE2 param_6, UNK_TYPE2 param_7, UNK_TYPE2 param_8, UNK_TYPE2 param_9, UNK_TYPE4 param_10, UNK_TYPE4 param_11, UNK_TYPE4 param_12, UNK_TYPE2 param_13, UNK_TYPE2 param_14); -Gfx* func_8010DC58(Gfx* displayListHead, void* texture, s16 textureWidth, s16 textureHeight, u16 i); -// void func_8010DE38(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5, UNK_TYPE2 param_6); +Gfx* func_8010DC58(Gfx* gfx, TexturePtr texture, s16 textureWidth, s16 textureHeight, u16 i); +Gfx* func_8010DE38(Gfx* gfx, TexturePtr texture, s32 fmt, s16 textureWidth, s16 textureHeight, u16 point); // void func_8010E028(void); void Interface_StartTimer(s16 timerId, s16 seconds); void Interface_StartPostmanTimer(s16 seconds, s16 bunnyHoodState); @@ -2056,7 +2057,7 @@ void Inventory_ChangeEquipment(s16 value); u8 Inventory_DeleteEquipment(PlayState* play, s16 equipment); void Inventory_ChangeUpgrade(s16 upgrade, u32 value); s32 Inventory_IsMapVisible(s16 sceneId); -void Inventory_SetMapVisibility(s16 tingleIndex); +void Inventory_SetWorldMapCloudVisibility(s16 tingleIndex); void Inventory_SaveDekuPlaygroundHighScore(s16 timerId); void Inventory_IncrementSkullTokenCount(s16 sceneIndex); s16 Inventory_GetSkullTokenCount(s16 sceneIndex); @@ -2098,7 +2099,7 @@ void Scene_HeaderCmdActorCutsceneList(PlayState* play, SceneCmd* cmd); void Scene_HeaderCmdMiniMap(PlayState* play, SceneCmd* cmd); void Scene_HeaderCmd1D(PlayState* play, SceneCmd* cmd); void Scene_HeaderCmdMiniMapCompassInfo(PlayState* play, SceneCmd* cmd); -void Scene_HeaderCmdSetAreaVisitedFlag(PlayState* play, SceneCmd* cmd); +void Scene_HeaderCmdSetRegionVisitedFlag(PlayState* play, SceneCmd* cmd); void Scene_HeaderCmdAnimatedMaterials(PlayState* play, SceneCmd* cmd); void Scene_SetExitFade(PlayState* play); s32 Scene_ProcessHeader(PlayState* play, SceneCmd* header); @@ -2360,7 +2361,7 @@ void Message_FindMessageNES(PlayState* play, u16 textId); // void Message_LoadLocalizedRupeesNES(void); // void Message_LoadRupeesNES(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5); // void Message_LoadTimeNES(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); -// void Message_LoadAreaTextNES(void); +// void Message_LoadOwlWarpTextNES(void); // void func_80159438(void); void func_8015966C(PlayState* play, UNK_PTR puParm2, UNK_TYPE arg3); // void func_8015A144(void); diff --git a/include/regs.h b/include/regs.h index cf15b236a..4ad6acbfb 100644 --- a/include/regs.h +++ b/include/regs.h @@ -47,8 +47,9 @@ #define R_RUN_SPEED_LIMIT REG(45) #define R_UPDATE_RATE SREG(30) #define R_PAUSE_MENU_MODE SREG(94) -#define R_C_UP_ICON_X YREG(88) -#define R_C_UP_ICON_Y YREG(89) +#define R_PAUSE_WORLD_MAP_YAW YREG(24) +#define R_PAUSE_WORLD_MAP_Y_OFFSET YREG(25) +#define R_PAUSE_WORLD_MAP_DEPTH YREG(26) #define R_MAGIC_FILL_COLOR(i) ZREG(0 + i) #define R_C_BTN_COLOR(i) ZREG(39 + i) #define R_B_BTN_COLOR(i) ZREG(43 + i) @@ -71,8 +72,13 @@ #define R_A_ICON_X XREG(20) #define R_A_BTN_COLOR(i) XREG(22 + i) #define R_MAGIC_CONSUME_TIMER_GIANTS_MASK XREG(41) +#define R_PAUSE_DBG_MAP_CLOUD_ON XREG(50) +#define R_PAUSE_DBG_MAP_CLOUD_X XREG(52) +#define R_PAUSE_DBG_MAP_CLOUD_Y XREG(53) #define R_MOON_CRASH_TIMER_Y XREG(80) #define R_MOON_CRASH_TIMER_X XREG(81) +#define R_PAUSE_OWLWARP_ALPHA XREG(87) +#define R_REVERSE_FLOOR_INDEX XREG(94) #define R_MINIMAP_DISABLED XREG(95) #define R_B_LABEL_DD WREG(0) #define R_OW_MINIMAP_X WREG(29) diff --git a/include/z64.h b/include/z64.h index d03879072..b18ab8d86 100644 --- a/include/z64.h +++ b/include/z64.h @@ -439,7 +439,7 @@ typedef struct { /* 0x238 */ s16 cursorPoint[5]; /* 0x242 */ s16 cursorXIndex[5]; /* 0x24C */ s16 cursorYIndex[5]; - /* 0x256 */ s16 unk_256; + /* 0x256 */ s16 unk_256; // Uses DungeonItem enum /* 0x258 */ s16 cursorSpecialPos; /* 0x25A */ s16 pageSwitchTimer; /* 0x25C */ u16 unk_25C; @@ -472,8 +472,8 @@ typedef struct { /* 0x2BA */ s16 equipAnimScale; // scale of item icon while moving being equipped to c-button /* 0x2BC */ s16 equipAnimShrinkRate; // rate the scale is shrinking for the item icon while moving being equipped to c-button /* 0x2BE */ s16 unk_2BE[5]; - /* 0x2C8 */ u16 unk_2C8; - /* 0x2CA */ s16 unk_2CA; + /* 0x2C8 */ u16 unk_2C8; // Uses PauseMenuPage enum for Owl Warp. Never set. + /* 0x2CA */ s16 unk_2CA; // Uses OwlStatueId enum for Owl Warp. Never set. } PauseContext; // size = 0x2D0 typedef struct { diff --git a/include/z64item.h b/include/z64item.h index d8a2185cc..7c6b719ca 100644 --- a/include/z64item.h +++ b/include/z64item.h @@ -65,6 +65,19 @@ typedef enum { /* 0x1C */ QUEST_HEART_PIECE_COUNT = 0x1C } QuestItem; +typedef enum { + /* -1 */ DUNGEON_NONE = -1, + /* 0 */ DUNGEON_BOSS_KEY, + /* 1 */ DUNGEON_COMPASS, + /* 2 */ DUNGEON_MAP, + /* 3 */ DUNGEON_STRAY_FAIRIES, + /* 4 */ DUNGEON_FLOOR_INDEX_4, // Top Floor + /* 5 */ DUNGEON_FLOOR_INDEX_3, + /* 6 */ DUNGEON_FLOOR_INDEX_2, + /* 7 */ DUNGEON_FLOOR_INDEX_1, + /* 8 */ DUNGEON_FLOOR_INDEX_0 // Bottom Floor +} DungeonItem; + typedef enum { /* 0x00 */ SLOT_OCARINA, /* 0x01 */ SLOT_BOW, @@ -550,6 +563,6 @@ typedef enum { /* 0x74 */ GID_PICTO_BOX, /* 0x75 */ GID_MASK_FIERCE_DEITY, /* 0x76 */ GID_MAX -} GetItemDrawID; +} GetItemDrawId; #endif diff --git a/include/z64save.h b/include/z64save.h index 436e410e6..fa65031eb 100644 --- a/include/z64save.h +++ b/include/z64save.h @@ -272,8 +272,8 @@ typedef struct Save { /* 0x0EF0 */ u32 lotteryCodeGuess; // Lottery code chosen by player (only uses lower three hex digits) /* 0x0EF4 */ u32 shootingGalleryHighScores; // High scores for both shooting galleries. Town uses lower 16 bits, Swamp uses higher 16 bits. /* 0x0EF8 */ u8 weekEventReg[100]; // "week_event_reg" - /* 0x0F5C */ u32 mapsVisited; // "area_arrival" - /* 0x0F60 */ u32 mapsVisible; // "cloud_clear" + /* 0x0F5C */ u32 regionsVisited; // "area_arrival" + /* 0x0F60 */ u32 worldMapCloudVisibility; // "cloud_clear" /* 0x0F64 */ u8 unk_F64; // "oca_rec_flag" has scarecrows song /* 0x0F65 */ u8 unk_F65; // "oca_rec_flag8" scarecrows song set? /* 0x0F66 */ u8 scarecrowSpawnSong[128]; diff --git a/include/z64scene.h b/include/z64scene.h index 9658c4f4d..bb82574f8 100644 --- a/include/z64scene.h +++ b/include/z64scene.h @@ -174,9 +174,9 @@ typedef struct { typedef struct { /* 0x0 */ u8 code; - /* 0x1 */ u8 cameraMovement; - /* 0x4 */ u32 area; -} SCmdMiscSettings; // size = 0x8 + /* 0x1 */ u8 sceneCsCount; + /* 0x4 */ void* segment; +} SCmdCutsceneList; // size = 0x8 typedef struct { /* 0x0 */ u8 code; @@ -186,9 +186,8 @@ typedef struct { typedef struct { /* 0x0 */ u8 code; - /* 0x1 */ u8 data1; - /* 0x4 */ u32 data2; -} SCmdWorldMapVisited; // size = 0x8 + /* 0x1 */ UNK_TYPE1 pad[7]; +} SCmdRegionVisited; // size = 0x8 typedef struct { /* 0x0 */ u8 code; @@ -523,9 +522,9 @@ typedef union { /* Command: 0x14 */ SCmdEndMarker endMarker; /* Command: 0x15 */ SCmdSoundSettings soundSettings; /* Command: 0x16 */ SCmdEchoSettings echoSettings; - /* Command: 0x17 */ SCmdMiscSettings miscSettings; + /* Command: 0x17 */ SCmdCutsceneList cutsceneList; /* Command: 0x18 */ SCmdAltHeaders altHeaders; - /* Command: 0x19 */ SCmdWorldMapVisited worldMapVisited; + /* Command: 0x19 */ SCmdRegionVisited regionVisited; /* Command: 0x1A */ SCmdTextureAnimations textureAnimations; /* Command: 0x1B */ SCmdCutsceneActorList cutsceneActorList; /* Command: 0x1C */ SCmdMinimapSettings minimapSettings; @@ -533,6 +532,49 @@ typedef union { /* Command: 0x1E */ SCmdMinimapChests minimapChests; } SceneCmd; // size = 0x8 +// Sets cursor point options on the world map +typedef enum { + /* 0x0 */ REGION_GREAT_BAY, + /* 0x1 */ REGION_ZORA_HALL, + /* 0x2 */ REGION_ROMANI_RANCH, + /* 0x3 */ REGION_DEKU_PALACE, + /* 0x4 */ REGION_WOODFALL, + /* 0x5 */ REGION_CLOCK_TOWN, + /* 0x6 */ REGION_SNOWHEAD, + /* 0x7 */ REGION_IKANA_GRAVEYARD, + /* 0x8 */ REGION_IKANA_CANYON, + /* 0x9 */ REGION_GORON_VILLAGE, + /* 0xA */ REGION_STONE_TOWER, + /* 0xB */ REGION_MAX +} RegionId; + +// Sets warp points for owl statues +typedef enum { + /* 0x0 */ OWL_WARP_GREAT_BAY_COAST, + /* 0x1 */ OWL_WARP_ZORA_CAPE, + /* 0x2 */ OWL_WARP_SNOWHEAD, + /* 0x3 */ OWL_WARP_MOUNTAIN_VILLAGE, + /* 0x4 */ OWL_WARP_CLOCK_TOWN, + /* 0x5 */ OWL_WARP_MILK_ROAD, + /* 0x6 */ OWL_WARP_WOODFALL, + /* 0x7 */ OWL_WARP_SOUTHERN_SWAMP, + /* 0x8 */ OWL_WARP_IKANA_CANYON, + /* 0x9 */ OWL_WARP_STONE_TOWER, + /* 0xA */ OWL_WARP_ENTRANCE, // Special index for warping to the entrance of a scene + /* 0xB */ OWL_WARP_MAX +} OwlWarpId; + +// Sets cloud visibility on the world map +typedef enum { + /* 0 */ TINGLE_MAP_CLOCK_TOWN, + /* 1 */ TINGLE_MAP_WOODFALL, + /* 2 */ TINGLE_MAP_SNOWHEAD, + /* 3 */ TINGLE_MAP_ROMANI_RANCH, + /* 4 */ TINGLE_MAP_GREAT_BAY, + /* 5 */ TINGLE_MAP_STONE_TOWER, + /* 6 */ TINGLE_MAP_MAX +} TingleMapId; + typedef enum { /* 0x00 */ SCENE_20SICHITAI2, // Southern Swamp (Clear) /* 0x01 */ SCENE_UNSET_1, @@ -810,7 +852,7 @@ typedef enum { /* 0x16 */ SCENE_CMD_ID_ECHO_SETTINGS, /* 0x17 */ SCENE_CMD_ID_CUTSCENE_LIST, /* 0x18 */ SCENE_CMD_ID_ALTERNATE_HEADER_LIST, - /* 0x19 */ SCENE_CMD_ID_MISC_SETTINGS, + /* 0x19 */ SCENE_CMD_ID_SET_REGION_VISITED, /* 0x1A */ SCENE_CMD_ID_ANIMATED_MATERIAL_LIST, /* 0x1B */ SCENE_CMD_ID_ACTOR_CUTSCENE_LIST, /* 0x1C */ SCENE_CMD_ID_MINIMAP_INFO, @@ -899,8 +941,9 @@ typedef enum { #define SCENE_CMD_ALTERNATE_HEADER_LIST(alternateHeaderList) \ { SCENE_CMD_ID_ALTERNATE_HEADER_LIST, 0, CMD_PTR(alternateHeaderList) } -#define SCENE_CMD_MISC_SETTINGS() \ - { SCENE_CMD_ID_MISC_SETTINGS, 0, CMD_W(0) } +#define SCENE_CMD_MISC_SETTINGS SCENE_CMD_SET_REGION_VISITED // TODO: ZAPD Capatability +#define SCENE_CMD_SET_REGION_VISITED() \ + { SCENE_CMD_ID_SET_REGION_VISITED, 0, CMD_W(0) } #define SCENE_CMD_ANIMATED_MATERIAL_LIST(matAnimList) \ { SCENE_CMD_ID_ANIMATED_MATERIAL_LIST, 0, CMD_PTR(matAnimList) } diff --git a/spec b/spec index 33f635b8f..a59e3f0f4 100644 --- a/spec +++ b/spec @@ -293,14 +293,16 @@ beginseg name "icon_item_field_static" compress romalign 0x1000 - include "build/baserom/icon_item_field_static.o" + include "build/assets/interface/icon_item_field_static/icon_item_field_static.o" + number 12 endseg beginseg name "icon_item_dungeon_static" compress romalign 0x1000 - include "build/baserom/icon_item_dungeon_static.o" + include "build/assets/interface/icon_item_dungeon_static/icon_item_dungeon_static.o" + number 12 endseg beginseg @@ -315,7 +317,8 @@ beginseg name "icon_item_jpn_static" compress romalign 0x1000 - include "build/baserom/icon_item_jpn_static.o" + include "build/assets/interface/icon_item_jpn_static/icon_item_jpn_static.o" + number 13 endseg beginseg @@ -1283,8 +1286,7 @@ beginseg name "ovl_Bg_Umajump" compress include "build/src/overlays/actors/ovl_Bg_Umajump/z_bg_umajump.o" - include "build/data/ovl_Bg_Umajump/ovl_Bg_Umajump.data.o" - include "build/data/ovl_Bg_Umajump/ovl_Bg_Umajump.reloc.o" + include "build/src/overlays/actors/ovl_Bg_Umajump/ovl_Bg_Umajump_reloc.o" endseg beginseg @@ -3105,8 +3107,7 @@ beginseg name "ovl_Dm_Char08" compress include "build/src/overlays/actors/ovl_Dm_Char08/z_dm_char08.o" - include "build/data/ovl_Dm_Char08/ovl_Dm_Char08.data.o" - include "build/data/ovl_Dm_Char08/ovl_Dm_Char08.reloc.o" + include "build/src/overlays/actors/ovl_Dm_Char08/ovl_Dm_Char08_reloc.o" endseg beginseg @@ -4362,8 +4363,7 @@ beginseg name "ovl_En_Stone_heishi" compress include "build/src/overlays/actors/ovl_En_Stone_heishi/z_en_stone_heishi.o" - include "build/data/ovl_En_Stone_heishi/ovl_En_Stone_heishi.data.o" - include "build/data/ovl_En_Stone_heishi/ovl_En_Stone_heishi.reloc.o" + include "build/src/overlays/actors/ovl_En_Stone_heishi/ovl_En_Stone_heishi_reloc.o" endseg beginseg diff --git a/src/code/code_8012EC80.c b/src/code/code_8012EC80.c index 278ef0830..eb70cfbc8 100644 --- a/src/code/code_8012EC80.c +++ b/src/code/code_8012EC80.c @@ -96,7 +96,7 @@ u32 gGsFlagsShift[] = { }; // TODO: use symbols for these icon textures once textures are properly in C -void* gItemIcons[] = { +TexturePtr gItemIcons[] = { 0x08000000, // ITEM_OCARINA 0x08001000, // ITEM_BOW 0x08002000, // ITEM_ARROW_FIRE @@ -249,7 +249,7 @@ u8 gItemSlots[] = { SLOT_LENS, // ITEM_LENS SLOT_HOOKSHOT, // ITEM_HOOKSHOT SLOT_SWORD_GREAT_FAIRY, // ITEM_SWORD_GREAT_FAIRY - SLOT_BOTTLE_1, // + SLOT_BOTTLE_1, // ITEM_LONGSHOT SLOT_BOTTLE_1, // ITEM_BOTTLE SLOT_BOTTLE_1, // ITEM_POTION_RED SLOT_BOTTLE_1, // ITEM_POTION_GREEN @@ -365,8 +365,8 @@ s16 gItemPrices[] = { }; // Used to map scene indexes to their region in Termina -u16 gSceneIdsPerRegion[11][27] = { - // Great Bay +u16 gSceneIdsPerRegion[REGION_MAX][27] = { + // REGION_GREAT_BAY { SCENE_30GYOSON, SCENE_LABO, @@ -378,15 +378,15 @@ u16 gSceneIdsPerRegion[11][27] = { SCENE_PIRATE, SCENE_35TAKI, SCENE_KINDAN2, - -1, + 0xFFFF, }, - // Zora Hall + // REGION_ZORA_HALL { SCENE_33ZORACITY, SCENE_BANDROOM, - -1, + 0xFFFF, }, - // Romani Ranch + // REGION_ROMANI_RANCH { SCENE_F01, SCENE_ROMANYMAE, @@ -394,17 +394,17 @@ u16 gSceneIdsPerRegion[11][27] = { SCENE_F01C, SCENE_F01_B, SCENE_KOEPONARACE, - -1, + 0xFFFF, }, - // Deku Palace + // REGION_DEKU_PALACE { SCENE_22DEKUCITY, SCENE_DEKU_KING, SCENE_26SARUNOMORI, SCENE_DANPEI, - -1, + 0xFFFF, }, - // Southern Swamp + // REGION_WOODFALL { SCENE_20SICHITAI, SCENE_20SICHITAI2, @@ -412,21 +412,18 @@ u16 gSceneIdsPerRegion[11][27] = { SCENE_WITCH_SHOP, SCENE_21MITURINMAE, SCENE_KINSTA1, - -1, + 0xFFFF, }, - // Clock Town + // REGION_CLOCK_TOWN { - SCENE_00KEIKOKU, SCENE_TENMON_DAI, SCENE_13HUBUKINOMITI, - SCENE_24KEMONOMITI, SCENE_SYATEKI_MORI, SCENE_IKANAMAE, - SCENE_TOWN, SCENE_SYATEKI_MIZU, SCENE_BOWLING, - SCENE_TAKARAYA, SCENE_YADOYA, SCENE_SONCHONOIE, - SCENE_MILK_BAR, SCENE_ICHIBA, SCENE_BOMYA, - SCENE_AYASHIISHOP, SCENE_8ITEMSHOP, SCENE_DOUJOU, - SCENE_POSTHOUSE, SCENE_TAKARAKUJI, SCENE_BACKTOWN, - SCENE_CLOCKTOWER, SCENE_INSIDETOWER, SCENE_OKUJOU, - SCENE_ALLEY, SCENE_DEKUTES, -1, + SCENE_00KEIKOKU, SCENE_TENMON_DAI, SCENE_13HUBUKINOMITI, SCENE_24KEMONOMITI, SCENE_SYATEKI_MORI, + SCENE_IKANAMAE, SCENE_TOWN, SCENE_SYATEKI_MIZU, SCENE_BOWLING, SCENE_TAKARAYA, + SCENE_YADOYA, SCENE_SONCHONOIE, SCENE_MILK_BAR, SCENE_ICHIBA, SCENE_BOMYA, + SCENE_AYASHIISHOP, SCENE_8ITEMSHOP, SCENE_DOUJOU, SCENE_POSTHOUSE, SCENE_TAKARAKUJI, + SCENE_BACKTOWN, SCENE_CLOCKTOWER, SCENE_INSIDETOWER, SCENE_OKUJOU, SCENE_ALLEY, + SCENE_DEKUTES, 0xFFFF, }, - // Snowhead + // REGION_SNOWHEAD { SCENE_10YUKIYAMANOMURA, SCENE_10YUKIYAMANOMURA2, @@ -437,15 +434,15 @@ u16 gSceneIdsPerRegion[11][27] = { SCENE_GORON_HAKA, SCENE_17SETUGEN, SCENE_17SETUGEN2, - -1, + 0xFFFF, }, - // Ikana Graveyard + // REGION_IKANA_GRAVEYARD { SCENE_BOTI, SCENE_DANPEI2TEST, - -1, + 0xFFFF, }, - // Ikana Canyon + // REGION_IKANA_CANYON { SCENE_CASTLE, SCENE_IKNINSIDE, @@ -456,21 +453,21 @@ u16 gSceneIdsPerRegion[11][27] = { SCENE_REDEAD, SCENE_TOUGITES, SCENE_HAKASHITA, - -1, + 0xFFFF, }, - // Goron Village + // REGION_GORON_VILLAGE { SCENE_11GORONNOSATO, SCENE_11GORONNOSATO2, SCENE_16GORON_HOUSE, SCENE_GORONSHOP, - -1, + 0xFFFF, }, - // Stone Tower + // REGION_STONE_TOWER { SCENE_F40, SCENE_F41, - -1, + 0xFFFF, }, }; @@ -553,9 +550,9 @@ s32 Inventory_IsMapVisible(s16 sceneId) { return false; } -static u16 sSceneIdsPerTingleMap[6][12] = { +static u16 sSceneIdsPerTingleMap[TINGLE_MAP_MAX][12] = { { - // Clock Town Tingle Map + // TINGLE_MAP_CLOCK_TOWN SCENE_00KEIKOKU, SCENE_BOTI, SCENE_13HUBUKINOMITI, @@ -566,20 +563,20 @@ static u16 sSceneIdsPerTingleMap[6][12] = { SCENE_BACKTOWN, SCENE_CLOCKTOWER, SCENE_ALLEY, - -1, + 0xFFFF, }, { - // Woodfall Tingle Map + // TINGLE_MAP_WOODFALL SCENE_20SICHITAI, SCENE_20SICHITAI2, SCENE_21MITURINMAE, SCENE_22DEKUCITY, SCENE_DEKU_KING, SCENE_KINSTA1, - -1, + 0xFFFF, }, { - // Snowhead Tingle Map + // TINGLE_MAP_SNOWHEAD SCENE_10YUKIYAMANOMURA, SCENE_10YUKIYAMANOMURA2, SCENE_11GORONNOSATO, @@ -590,20 +587,20 @@ static u16 sSceneIdsPerTingleMap[6][12] = { SCENE_GORONRACE, SCENE_17SETUGEN, SCENE_17SETUGEN2, - -1, + 0xFFFF, }, { - // Romani Ranch Tingle Map + // TINGLE_MAP_ROMANI_RANCH SCENE_F01, SCENE_ROMANYMAE, SCENE_OMOYA, SCENE_F01C, SCENE_F01_B, SCENE_KOEPONARACE, - -1, + 0xFFFF, }, { - // Great Bay Tingle Map + // TINGLE_MAP_GREAT_BAY SCENE_30GYOSON, SCENE_SINKAI, SCENE_31MISAKI, @@ -611,28 +608,28 @@ static u16 sSceneIdsPerTingleMap[6][12] = { SCENE_KAIZOKU, SCENE_33ZORACITY, SCENE_35TAKI, - -1, + 0xFFFF, }, { - // Stone Tower Tingle Map + // TINGLE_MAP_STONE_TOWER SCENE_F40, SCENE_F41, SCENE_CASTLE, SCENE_IKANA, SCENE_REDEAD, - -1, + 0xFFFF, }, }; /** - * Map visibility is achieved by purchasing a tingle map + * Removing clouds from the World Map is achieved by purchasing a tingle map */ -void Inventory_SetMapVisibility(s16 tingleIndex) { +void Inventory_SetWorldMapCloudVisibility(s16 tingleIndex) { s16 i = 0; s16 index = 0; u16(*tingleMapSceneIds)[] = &sSceneIdsPerTingleMap[tingleIndex]; - if ((tingleIndex >= 0) && (tingleIndex < 6)) { + if ((tingleIndex >= 0) && (tingleIndex < TINGLE_MAP_MAX)) { while (true) { if ((*tingleMapSceneIds)[i] == 0xFFFF) { break; @@ -665,21 +662,21 @@ void Inventory_SetMapVisibility(s16 tingleIndex) { } if ((*tingleMapSceneIds) == sSceneIdsPerTingleMap[0]) { - gSaveContext.save.mapsVisible |= 3; + gSaveContext.save.worldMapCloudVisibility |= 3; } else if ((*tingleMapSceneIds) == sSceneIdsPerTingleMap[1]) { - gSaveContext.save.mapsVisible |= 0x1C; + gSaveContext.save.worldMapCloudVisibility |= 0x1C; } else if ((*tingleMapSceneIds) == sSceneIdsPerTingleMap[2]) { - gSaveContext.save.mapsVisible |= 0xE0; + gSaveContext.save.worldMapCloudVisibility |= 0xE0; } else if ((*tingleMapSceneIds) == sSceneIdsPerTingleMap[3]) { - gSaveContext.save.mapsVisible |= 0x100; + gSaveContext.save.worldMapCloudVisibility |= 0x100; } else if ((*tingleMapSceneIds) == sSceneIdsPerTingleMap[4]) { - gSaveContext.save.mapsVisible |= 0x1E00; + gSaveContext.save.worldMapCloudVisibility |= 0x1E00; } else if ((*tingleMapSceneIds) == sSceneIdsPerTingleMap[5]) { - gSaveContext.save.mapsVisible |= 0x6000; + gSaveContext.save.worldMapCloudVisibility |= 0x6000; } } - XREG(95) = 0; + R_MINIMAP_DISABLED = false; } /** diff --git a/src/code/title_setup.c b/src/code/title_setup.c index dad3c6458..641160ea8 100644 --- a/src/code/title_setup.c +++ b/src/code/title_setup.c @@ -23,13 +23,13 @@ void Setup_SetRegs(void) { XREG(77) = 0x3C; XREG(78) = 0x2F; XREG(79) = 0x62; - XREG(87) = 0; + R_PAUSE_OWLWARP_ALPHA = 0; XREG(88) = 0x56; XREG(89) = 0x258; XREG(90) = 0x1C2; XREG(91) = 0; - XREG(94) = 0; - XREG(95) = 0; + R_REVERSE_FLOOR_INDEX = 0; + R_MINIMAP_DISABLED = false; YREG(32) = 0x50; YREG(33) = 0x3C; diff --git a/src/code/z_actor.c b/src/code/z_actor.c index 84616f083..c5783f4d7 100644 --- a/src/code/z_actor.c +++ b/src/code/z_actor.c @@ -861,10 +861,11 @@ void TitleCard_Draw(GameState* gameState, TitleCardContext* titleCtx) { OPEN_DISPS(gameState->gfxCtx); - height = (width * height > TMEM_SIZE) ? TMEM_SIZE / width : height; - spB4 = spB8 + (height * 4); + if (width * height > TMEM_SIZE) { + height = TMEM_SIZE / width; + } - if (1) {} + spB4 = spB8 + (height * 4); OVERLAY_DISP = func_8012C014(OVERLAY_DISP); diff --git a/src/code/z_kaleido_setup.c b/src/code/z_kaleido_setup.c index 0109dc4ab..2f2e3c388 100644 --- a/src/code/z_kaleido_setup.c +++ b/src/code/z_kaleido_setup.c @@ -22,19 +22,19 @@ void func_800F4A10(PlayState* play) { pauseCtx->unk_27E = -40; for (i = 0; i < ARRAY_COUNT(pauseCtx->worldMapPoints); i++) { - pauseCtx->worldMapPoints[i] = 0; + pauseCtx->worldMapPoints[i] = false; } if (pauseCtx->state == 1) { - for (i = 0; i < 11; i++) { - if ((gSaveContext.save.mapsVisited >> i) & 1) { - pauseCtx->worldMapPoints[i] = 1; + for (i = 0; i < REGION_MAX; i++) { + if ((gSaveContext.save.regionsVisited >> i) & 1) { + pauseCtx->worldMapPoints[i] = true; } } } else { - for (i = 9; i >= 0; i--) { + for (i = OWL_WARP_STONE_TOWER; i >= OWL_WARP_GREAT_BAY_COAST; i--) { if ((gSaveContext.save.playerData.owlActivationFlags >> i) & 1) { - pauseCtx->worldMapPoints[i] = 1; + pauseCtx->worldMapPoints[i] = true; pauseCtx->cursorPoint[PAUSE_WORLD_MAP] = i; } } @@ -57,9 +57,9 @@ void func_800F4A10(PlayState* play) { YREG(21) = -0x0622; YREG(22) = -0x0C44; YREG(23) = 0x0622; - YREG(24) = -0x0622; - YREG(25) = -0x005A; - YREG(26) = -0x3840; + R_PAUSE_WORLD_MAP_YAW = -0x622; + R_PAUSE_WORLD_MAP_Y_OFFSET = -90; + R_PAUSE_WORLD_MAP_DEPTH = -14400; } void KaleidoSetup_Update(PlayState* play) { @@ -124,18 +124,18 @@ void KaleidoSetup_Init(PlayState* play) { pauseCtx->unk_20C = 936.0f; pauseCtx->unk_220 = -314.0f; - pauseCtx->cursorPoint[PAUSE_MAP] = XREG(94) + 3; + pauseCtx->cursorPoint[PAUSE_MAP] = R_REVERSE_FLOOR_INDEX + (DUNGEON_FLOOR_INDEX_4 - 1); pauseCtx->cursorSpecialPos = PAUSE_CURSOR_PAGE_RIGHT; pauseCtx->pageSwitchTimer = 0; pauseCtx->cursorItem[PAUSE_ITEM] = PAUSE_ITEM_NONE; - pauseCtx->cursorItem[PAUSE_MAP] = XREG(94) + 3; + pauseCtx->cursorItem[PAUSE_MAP] = R_REVERSE_FLOOR_INDEX + (DUNGEON_FLOOR_INDEX_4 - 1); pauseCtx->cursorItem[PAUSE_QUEST] = PAUSE_ITEM_NONE; pauseCtx->cursorItem[PAUSE_MASK] = PAUSE_ITEM_NONE; pauseCtx->cursorSlot[PAUSE_ITEM] = 0; - pauseCtx->cursorSlot[PAUSE_MAP] = XREG(94) + 3; + pauseCtx->cursorSlot[PAUSE_MAP] = R_REVERSE_FLOOR_INDEX + (DUNGEON_FLOOR_INDEX_4 - 1); pauseCtx->cursorColorSet = 2; pauseCtx->unk_2A0 = -1; diff --git a/src/code/z_map_exp.c b/src/code/z_map_exp.c index 2b5eb1aac..57f51a20a 100644 --- a/src/code/z_map_exp.c +++ b/src/code/z_map_exp.c @@ -245,14 +245,14 @@ void Map_Update(PlayState* play) { if (floor != -1) { gSaveContext.save.permanentSceneFlags[Play_GetOriginalSceneId(play->sceneId)].unk_14 |= gBitFlags[FLOOR_INDEX_MAX - floor]; - XREG(94) = FLOOR_INDEX_MAX - floor; + R_REVERSE_FLOOR_INDEX = FLOOR_INDEX_MAX - floor; if (interfaceCtx->mapRoomNum != sLastRoomNum) { sLastRoomNum = interfaceCtx->mapRoomNum; } } } else if (Map_IsInBossArea(play)) { func_80105294(); - XREG(94) = FLOOR_INDEX_MAX - func_80105318(); + R_REVERSE_FLOOR_INDEX = FLOOR_INDEX_MAX - func_80105318(); } } } diff --git a/src/code/z_message.c b/src/code/z_message.c index 94f1e5992..de3a81c73 100644 --- a/src/code/z_message.c +++ b/src/code/z_message.c @@ -256,34 +256,33 @@ void func_8014CCB4(PlayState* play, s16* decodedBufPos, s32* offset, f32* arg3) #pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_8014D304.s") -extern u16 D_801D0188[][9]; -extern s16 D_801D0250[]; +extern u16 D_801D0188[OWL_WARP_MAX][9]; +extern s16 D_801D0250[OWL_WARP_MAX]; void func_8014D62C(PlayState* play, s32* arg1, f32* arg2, s16* arg3) { MessageContext* msgCtx = &play->msgCtx; PauseContext* pauseCtx = &play->pauseCtx; - s16 temp_s6; + s16 stringLimit; s16 temp_s1 = *arg3; s32 temp_s2 = *arg1; f32 sp3C = *arg2; - s16 phi_v0; + s16 owlWarpId; s16 phi_s0; - if ((func_8010A0A4(play) != 0) || (play->sceneId == SCENE_SECOM)) { - phi_v0 = 0xA; + if (func_8010A0A4(play) || (play->sceneId == SCENE_SECOM)) { + owlWarpId = OWL_WARP_ENTRANCE; } else { - phi_v0 = pauseCtx->cursorPoint[PAUSE_WORLD_MAP]; + owlWarpId = pauseCtx->cursorPoint[PAUSE_WORLD_MAP]; } + stringLimit = D_801D0250[owlWarpId]; - temp_s6 = D_801D0250[phi_v0]; - - for (phi_s0 = 0; phi_s0 < temp_s6; phi_s0++, temp_s1++, temp_s2 += 0x80) { - msgCtx->decodedBuffer.wchar[temp_s1] = D_801D0188[phi_v0][phi_s0]; - Font_LoadChar(play, D_801D0188[phi_v0][phi_s0], temp_s2); + for (phi_s0 = 0; phi_s0 < stringLimit; phi_s0++, temp_s1++, temp_s2 += 0x80) { + msgCtx->decodedBuffer.wchar[temp_s1] = D_801D0188[owlWarpId][phi_s0]; + Font_LoadChar(play, D_801D0188[owlWarpId][phi_s0], temp_s2); } temp_s1--; - sp3C += (temp_s6 - 1) * (16.0f * msgCtx->unk12098); + sp3C += (stringLimit - 1) * (16.0f * msgCtx->unk12098); *arg3 = temp_s1; *arg1 = temp_s2; diff --git a/src/code/z_message_nes.c b/src/code/z_message_nes.c index fef293b46..fb8dbfcbf 100644 --- a/src/code/z_message_nes.c +++ b/src/code/z_message_nes.c @@ -17,31 +17,43 @@ u8 D_801D06F0[4][8] = { { "rupee(s)" }, //EN // rupeesTextLength u8 D_801D0710[4] = {8,8,5,8}; -//TextArea -char D_801D0714[11][16] = { - "Great Bay Coast", - "Zora Cape", - "Snowhead", - "Mountain Village", - "Clock Town", - "Milk Road", - "Woodfall", - "Southern Swamp", - "Ikana Canyon", - "Stone Tower", - "Entrance" - }; +// sOwlWarpText +char D_801D0714[OWL_WARP_MAX][16] = { + "Great Bay Coast", // OWL_WARP_GREAT_BAY_COAST + "Zora Cape", // OWL_WARP_ZORA_CAPE + "Snowhead", // OWL_WARP_SNOWHEAD + "Mountain Village", // OWL_WARP_MOUNTAIN_VILLAGE + "Clock Town", // OWL_WARP_CLOCK_TOWN + "Milk Road", // OWL_WARP_MILK_ROAD + "Woodfall", // OWL_WARP_WOODFALL + "Southern Swamp", // OWL_WARP_SOUTHERN_SWAMP + "Ikana Canyon", // OWL_WARP_IKANA_CANYON + "Stone Tower", // OWL_WARP_STONE_TOWER + "Entrance", // OWL_WARP_ENTRANCE +}; -//TextAreaLength -s16 D_801D07C4[11] = {15,9,8,16,10,9,8,14,12,11,8}; +// sOwlWarpTextLength +s16 D_801D07C4[OWL_WARP_MAX] = { + 15, // OWL_WARP_GREAT_BAY_COAST + 9, // OWL_WARP_ZORA_CAPE + 8, // OWL_WARP_SNOWHEAD + 16, // OWL_WARP_MOUNTAIN_VILLAGE + 10, // OWL_WARP_CLOCK_TOWN + 9, // OWL_WARP_MILK_ROAD + 8, // OWL_WARP_WOODFALL + 14, // OWL_WARP_SOUTHERN_SWAMP + 12, // OWL_WARP_IKANA_CANYON + 11, // OWL_WARP_STONE_TOWER + 8, // OWL_WARP_ENTRANCE +}; #endif extern f32 D_801D0470[159]; extern u8 D_801D06F0[4][8]; extern u8 D_801D0710[4]; -extern u8 D_801D0714[11][16]; -extern s16 D_801D07C4[11]; +extern u8 D_801D0714[OWL_WARP_MAX][16]; +extern s16 D_801D07C4[OWL_WARP_MAX]; void Message_FindMessageNES(PlayState* play, u16 textId) { MessageContext* msgCtx = &play->msgCtx; @@ -244,28 +256,28 @@ void Message_LoadTimeNES(PlayState* play, u8 arg1, s32* offset, f32* arg3, s16* *arg3 = f; } -void Message_LoadAreaTextNES(PlayState* play, s32* offset, f32* arg2, s16* decodedBufPos) { +void Message_LoadOwlWarpTextNES(PlayState* play, s32* offset, f32* arg2, s16* decodedBufPos) { MessageContext* msgCtx = &play->msgCtx; s16 p = *decodedBufPos; s32 o = *offset; f32 f = *arg2; s16 i; u8 currentChar; - s16 currentArea; + s16 owlWarpId; s16 stringLimit; - if ((func_8010A0A4(play) != 0) || (play->sceneId == SCENE_SECOM)) { - currentArea = 10; + if (func_8010A0A4(play) || (play->sceneId == SCENE_SECOM)) { + owlWarpId = OWL_WARP_ENTRANCE; } else { - currentArea = play->pauseCtx.cursorPoint[PAUSE_WORLD_MAP]; + owlWarpId = play->pauseCtx.cursorPoint[PAUSE_WORLD_MAP]; } - stringLimit = D_801D07C4[currentArea]; + stringLimit = D_801D07C4[owlWarpId]; for (i = 0; i < stringLimit; i++) { - msgCtx->decodedBuffer.schar[p] = D_801D0714[currentArea][i]; + msgCtx->decodedBuffer.schar[p] = D_801D0714[owlWarpId][i]; currentChar = msgCtx->decodedBuffer.schar[p]; if (currentChar != ' ') { - Font_LoadCharNES(play, D_801D0714[currentArea][i], o); + Font_LoadCharNES(play, D_801D0714[owlWarpId][i], o); o += FONT_CHAR_TEX_SIZE; } currentChar = msgCtx->decodedBuffer.schar[p]; diff --git a/src/code/z_scene.c b/src/code/z_scene.c index c32a2271d..1167f14ab 100644 --- a/src/code/z_scene.c +++ b/src/code/z_scene.c @@ -468,8 +468,8 @@ void Scene_HeaderCmdAltHeaderList(PlayState* play, SceneCmd* cmd) { // SceneTableEntry Header Command 0x17: Cutscene List void Scene_HeaderCmdCutsceneList(PlayState* play, SceneCmd* cmd) { - play->csCtx.sceneCsCount = cmd->base.data1; - play->csCtx.sceneCsList = Lib_SegmentedToVirtual(cmd->base.data2); + play->csCtx.sceneCsCount = cmd->cutsceneList.sceneCsCount; + play->csCtx.sceneCsList = Lib_SegmentedToVirtual(cmd->cutsceneList.segment); } // SceneTableEntry Header Command 0x1B: Actor Cutscene List @@ -492,8 +492,8 @@ void Scene_HeaderCmdMiniMapCompassInfo(PlayState* play, SceneCmd* cmd) { func_8010565C(play, cmd->minimapChests.num, cmd->minimapChests.segment); } -// SceneTableEntry Header Command 0x1A: Sets Area Visited Flag -void Scene_HeaderCmdSetAreaVisitedFlag(PlayState* play, SceneCmd* cmd) { +// SceneTableEntry Header Command 0x19: Sets Region Visited Flag +void Scene_HeaderCmdSetRegionVisitedFlag(PlayState* play, SceneCmd* cmd) { s16 j = 0; s16 i = 0; @@ -502,7 +502,7 @@ void Scene_HeaderCmdSetAreaVisitedFlag(PlayState* play, SceneCmd* cmd) { i++; j = 0; - if (i == ARRAY_COUNT(gSceneIdsPerRegion)) { + if (i == REGION_MAX) { break; } } @@ -514,8 +514,9 @@ void Scene_HeaderCmdSetAreaVisitedFlag(PlayState* play, SceneCmd* cmd) { j++; } - if (i < ARRAY_COUNT(gSceneIdsPerRegion)) { - gSaveContext.save.mapsVisited = (gBitFlags[i] | gSaveContext.save.mapsVisited) | gSaveContext.save.mapsVisited; + if (i < REGION_MAX) { + gSaveContext.save.regionsVisited = + (gBitFlags[i] | gSaveContext.save.regionsVisited) | gSaveContext.save.regionsVisited; } } @@ -561,7 +562,7 @@ s32 Scene_ProcessHeader(PlayState* play, SceneCmd* header) { Scene_HeaderCmdEchoSetting, Scene_HeaderCmdCutsceneList, Scene_HeaderCmdAltHeaderList, - Scene_HeaderCmdSetAreaVisitedFlag, + Scene_HeaderCmdSetRegionVisitedFlag, Scene_HeaderCmdAnimatedMaterials, Scene_HeaderCmdActorCutsceneList, Scene_HeaderCmdMiniMap, diff --git a/src/overlays/actors/ovl_Bg_Umajump/z_bg_umajump.c b/src/overlays/actors/ovl_Bg_Umajump/z_bg_umajump.c index 894ced552..2a584bb31 100644 --- a/src/overlays/actors/ovl_Bg_Umajump/z_bg_umajump.c +++ b/src/overlays/actors/ovl_Bg_Umajump/z_bg_umajump.c @@ -5,6 +5,7 @@ */ #include "z_bg_umajump.h" +#include "assets/objects/object_umajump/object_umajump.h" #define FLAGS 0x00000000 @@ -13,8 +14,10 @@ void BgUmajump_Init(Actor* thisx, PlayState* play); void BgUmajump_Destroy(Actor* thisx, PlayState* play); void BgUmajump_Update(Actor* thisx, PlayState* play); +void BgUmajump_Draw(Actor* thisx, PlayState* play); + +void func_8091A5A0(Actor* thisx, PlayState* play); -#if 0 const ActorInit Bg_Umajump_InitVars = { ACTOR_BG_UMAJUMP, ACTORCAT_PROP, @@ -27,34 +30,190 @@ const ActorInit Bg_Umajump_InitVars = { (ActorFunc)NULL, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_8091A810[] = { +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneScale, 1200, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 300, ICHAIN_CONTINUE), ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), }; -#endif +void func_80919F30(BgUmajump* this, PlayState* play) { + if (this->rotationTimer >= 90) { + this->rotationTimer = 0; + } -extern InitChainEntry D_8091A810[]; + this->rotationTimer++; + this->dyna.actor.shape.yOffset = + Math_SinS((this->rotationTimer / 90.0f) * 0x10000) * (20.0f / this->dyna.actor.scale.y); +} -extern UNK_TYPE D_06001220; -extern UNK_TYPE D_06001558; +void BgUmajump_StopCutscene(BgUmajump* this, PlayState* play) { + if ((play->csCtx.frames >= 6) && !this->hasSoundPlayed) { + this->hasSoundPlayed = true; + play_sound(NA_SE_EV_KID_HORSE_NEIGH); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Umajump/func_80919F30.s") + if (play->csCtx.state == CS_STATE_0) { + ActorCutscene_Stop(this->dyna.actor.cutscene); + this->dyna.actor.update = Actor_Noop; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Umajump/func_80919FC8.s") +void BgUmajump_PlayCutscene(BgUmajump* this, PlayState* play) { + if (ActorCutscene_GetCanPlayNext(this->dyna.actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->dyna.actor.cutscene, &this->dyna.actor); + gSaveContext.save.weekEventReg[89] |= 0x20; + this->actionFunc = BgUmajump_StopCutscene; + } else { + ActorCutscene_SetIntentToPlay(this->dyna.actor.cutscene); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Umajump/func_8091A044.s") +void BgUmajump_CheckDistance(BgUmajump* this, PlayState* play) { + Player* player = GET_PLAYER(play); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Umajump/func_8091A0B8.s") + if ((this->horse != NULL) && (player != NULL) && + (Math3D_XZDistance(this->horse->world.pos.x, this->horse->world.pos.z, player->actor.world.pos.x, + player->actor.world.pos.z) < 1400.0f)) { + this->actionFunc = BgUmajump_PlayCutscene; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Umajump/BgUmajump_Init.s") +void BgUmajump_Init(Actor* thisx, PlayState* play) { + BgUmajump* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Umajump/BgUmajump_Destroy.s") + Actor_ProcessInitChain(thisx, sInitChain); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Umajump/BgUmajump_Update.s") + this->actionFunc = NULL; + this->horse = NULL; + this->hasSoundPlayed = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Umajump/func_8091A5A0.s") + DynaPolyActor_Init(&this->dyna, 0); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Umajump/func_8091A7B0.s") + this->objectIndex = BG_UMAJUMP_GET_OBJECT_INDEX(thisx); + thisx->params = BG_UMAJUMP_GET_FF(thisx); + + if ((thisx->params == BG_UMAJUMP_TYPE_2)) { + if ((((play->sceneId == SCENE_F01) && !(gSaveContext.save.weekEventReg[89] & 0x20)) && + !CHECK_QUEST_ITEM(QUEST_SONG_EPONA)) && + (thisx->cutscene != -1)) { + this->actionFunc = BgUmajump_CheckDistance; + thisx->update = func_8091A5A0; + thisx->flags |= ACTOR_FLAG_10; + this->horse = SubS_FindActor(play, this->horse, ACTORCAT_BG, ACTOR_EN_HORSE); + } else { + thisx->update = Actor_Noop; + } + } else { + this->objectIndex = Object_GetIndex(&play->objectCtx, OBJECT_UMAJUMP); + + if (this->objectIndex < 0) { + Actor_MarkForDeath(thisx); + } + + if ((thisx->params == BG_UMAJUMP_TYPE_3) && CHECK_QUEST_ITEM(QUEST_SONG_EPONA)) { + Actor_Spawn(&play->actorCtx, play, ACTOR_EN_KANBAN, thisx->world.pos.x, thisx->world.pos.y, + thisx->world.pos.z, thisx->shape.rot.x, thisx->shape.rot.y, thisx->shape.rot.z, 0x3E); + Actor_MarkForDeath(thisx); + } + } +} + +void BgUmajump_Destroy(Actor* thisx, PlayState* play) { + BgUmajump* this = THIS; + + DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, this->dyna.bgId); +} + +void BgUmajump_Update(Actor* thisx, PlayState* play) { + BgUmajump* this = THIS; + + if (Object_IsLoaded(&play->objectCtx, this->objectIndex)) { + this->dyna.actor.objBankIndex = this->objectIndex; + this->dyna.actor.draw = BgUmajump_Draw; + + Actor_SetObjectDependency(play, &this->dyna.actor); + + if (this->dyna.actor.params == BG_UMAJUMP_TYPE_5) { + if (gSaveContext.save.weekEventReg[22] & 1) { + DynaPolyActor_LoadMesh(play, &this->dyna, &object_umajump_Colheader_001558); + } + } else if (this->dyna.actor.params == BG_UMAJUMP_TYPE_6) { + if (!(gSaveContext.save.weekEventReg[22] & 1)) { + DynaPolyActor_LoadMesh(play, &this->dyna, &object_umajump_Colheader_001558); + } + } else if ((this->dyna.actor.params == BG_UMAJUMP_TYPE_4) || (this->dyna.actor.params == BG_UMAJUMP_TYPE_3)) { + DynaPolyActor_LoadMesh(play, &this->dyna, &object_umajump_Colheader_001558); + } else { + DynaPolyActor_LoadMesh(play, &this->dyna, &object_umajump_Colheader_001438); + } + + if (this->dyna.actor.params == BG_UMAJUMP_TYPE_1) { + this->rotationTimer = 0; + this->actionFunc = func_80919F30; + this->dyna.actor.update = func_8091A5A0; + } else if (this->dyna.actor.params == BG_UMAJUMP_TYPE_3) { + this->dyna.actor.update = func_8091A5A0; + } else if ((this->dyna.actor.params == BG_UMAJUMP_TYPE_5) || (this->dyna.actor.params == BG_UMAJUMP_TYPE_6)) { + if (this->dyna.actor.params == BG_UMAJUMP_TYPE_5) { + if ((this->dyna.bgId == BGACTOR_NEG_ONE) && (gSaveContext.save.weekEventReg[22] & 1)) { + DynaPolyActor_LoadMesh(play, &this->dyna, &object_umajump_Colheader_001558); + } + } else if ((this->dyna.actor.params == BG_UMAJUMP_TYPE_6) && (this->dyna.bgId == BGACTOR_NEG_ONE) && + (!(gSaveContext.save.weekEventReg[22] & 1) || + ((gSaveContext.save.day == 2) && (gSaveContext.save.isNight == true) && + ((gSaveContext.save.time >= CLOCK_TIME(5, 30)) && + (gSaveContext.save.time <= CLOCK_TIME(6, 0)))))) { + DynaPolyActor_LoadMesh(play, &this->dyna, &object_umajump_Colheader_001558); + } + func_800C641C(play, &play->colCtx.dyna, this->dyna.bgId); + this->dyna.actor.update = func_8091A5A0; + } else if (this->dyna.actor.params == BG_UMAJUMP_TYPE_4) { + func_800C641C(play, &play->colCtx.dyna, this->dyna.bgId); + this->dyna.actor.update = Actor_Noop; + } else { + this->dyna.actor.update = Actor_Noop; + } + } +} + +void func_8091A5A0(Actor* thisx, PlayState* play) { + BgUmajump* this = THIS; + + if (this->actionFunc != NULL) { + this->actionFunc(this, play); + } + + if ((this->dyna.actor.params == BG_UMAJUMP_TYPE_3) && CHECK_QUEST_ITEM(QUEST_SONG_EPONA)) { + Actor_Spawn(&play->actorCtx, play, ACTOR_EN_KANBAN, this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, + this->dyna.actor.world.pos.z, this->dyna.actor.shape.rot.x, this->dyna.actor.shape.rot.y, + this->dyna.actor.shape.rot.z, 0x3E); + Actor_MarkForDeath(&this->dyna.actor); + } + + if (this->dyna.actor.params == BG_UMAJUMP_TYPE_5) { + if ((this->dyna.bgId == BGACTOR_NEG_ONE) && (gSaveContext.save.weekEventReg[22] & 1)) { + DynaPolyActor_LoadMesh(play, &this->dyna, &object_umajump_Colheader_001558); + } else if ((this->dyna.bgId != BGACTOR_NEG_ONE) && !(gSaveContext.save.weekEventReg[22] & 1)) { + DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, this->dyna.bgId); + } + } else if (this->dyna.actor.params == BG_UMAJUMP_TYPE_6) { + if ((this->dyna.bgId == BGACTOR_NEG_ONE) && + (!(gSaveContext.save.weekEventReg[22] & 1) || + ((gSaveContext.save.day == 2) && (gSaveContext.save.isNight == true) && + (gSaveContext.save.time >= CLOCK_TIME(5, 30)) && (gSaveContext.save.time <= CLOCK_TIME(6, 0))))) { + DynaPolyActor_LoadMesh(play, &this->dyna, &object_umajump_Colheader_001558); + } else if ((this->dyna.bgId != BGACTOR_NEG_ONE) && (gSaveContext.save.weekEventReg[22] & 1) && + ((gSaveContext.save.day != 2) || (gSaveContext.save.isNight != true) || + (gSaveContext.save.time < CLOCK_TIME(5, 30)) || (gSaveContext.save.time > CLOCK_TIME(6, 0)))) { + DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, this->dyna.bgId); + } + } +} + +void BgUmajump_Draw(Actor* thisx, PlayState* play) { + BgUmajump* this = THIS; + + if (this->dyna.bgId != BGACTOR_NEG_ONE) { + Gfx_DrawDListOpa(play, gHorseJumpFenceDL); + } +} diff --git a/src/overlays/actors/ovl_Bg_Umajump/z_bg_umajump.h b/src/overlays/actors/ovl_Bg_Umajump/z_bg_umajump.h index 22fe9ca44..733bf77da 100644 --- a/src/overlays/actors/ovl_Bg_Umajump/z_bg_umajump.h +++ b/src/overlays/actors/ovl_Bg_Umajump/z_bg_umajump.h @@ -3,11 +3,31 @@ #include "global.h" +#define BG_UMAJUMP_GET_OBJECT_INDEX(thisx) (((thisx)->params >> 8) & 0xFF) +#define BG_UMAJUMP_GET_FF(thisx) ((thisx)->params & 0xFF) + +typedef enum { + BG_UMAJUMP_TYPE_1 = 1, + BG_UMAJUMP_TYPE_2, + BG_UMAJUMP_TYPE_3, + BG_UMAJUMP_TYPE_4, + BG_UMAJUMP_TYPE_5, + BG_UMAJUMP_TYPE_6, +} BgUmaJumpType; + struct BgUmajump; +typedef void (*BgUmajumpActionFunc)(struct BgUmajump*, PlayState*); + typedef struct BgUmajump { - /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x28]; + /* 0x000 */ DynaPolyActor dyna; + /* 0x15C */ BgUmajumpActionFunc actionFunc; + /* 0x160 */ union { + s32 objectIndex; + s32 rotationTimer; // y rotation + }; + /* 0x164 */ s32 hasSoundPlayed; + /* 0x168 */ Actor* horse; } BgUmajump; // size = 0x16C extern const ActorInit Bg_Umajump_InitVars; diff --git a/src/overlays/actors/ovl_Dm_Char08/z_dm_char08.c b/src/overlays/actors/ovl_Dm_Char08/z_dm_char08.c index ed8625795..94d15be60 100644 --- a/src/overlays/actors/ovl_Dm_Char08/z_dm_char08.c +++ b/src/overlays/actors/ovl_Dm_Char08/z_dm_char08.c @@ -5,17 +5,52 @@ */ #include "z_dm_char08.h" +#include "objects/object_kamejima/object_kamejima.h" #define FLAGS (ACTOR_FLAG_2000000) #define THIS ((DmChar08*)thisx) -void DmChar08_Init(Actor* thisx, PlayState* play); +void DmChar08_Init(Actor* thisx, PlayState* play2); void DmChar08_Destroy(Actor* thisx, PlayState* play); void DmChar08_Update(Actor* thisx, PlayState* play); void DmChar08_Draw(Actor* thisx, PlayState* play); -#if 0 +void func_80AAFAC4(DmChar08* this, PlayState* play); +void DmChar08_WaitForSong(DmChar08* this, PlayState* play); +void func_80AAF8F4(DmChar08* this, PlayState* play); +void func_80AAFAE4(DmChar08* this, PlayState* play); +void DmChar08_DoNothing(DmChar08* this, PlayState* play); +void func_80AAFA18(DmChar08* this, PlayState* play); +void DmChar08_SetupAppearCs(DmChar08* this, PlayState* play); +void func_80AAF884(DmChar08* this, PlayState* play); +void func_80AAFB04(DmChar08* this, PlayState* play); +void func_80AAFB94(DmChar08* this, PlayState* play); +void func_80AAFE88(DmChar08* this, PlayState* play); +void func_80AB023C(DmChar08* this, PlayState* play); +void func_80AB01E8(DmChar08* this, PlayState* play); +void DmChar08_SpawnBubbles(DmChar08* this, PlayState* play); +void func_80AAFCCC(DmChar08* this, PlayState* play); + +typedef enum { + /* 0 */ TURTLE_EYEMODE_BLINK_LEFT, + /* 1 */ TURTLE_EYEMODE_BLINK_STRAIGHT, + /* 2 */ TURTLE_EYEMODE_CLOSED, + /* 3 */ TURTLE_EYEMODE_LOOK_STRAIGHT, + /* 4 */ TURTLE_EYEMODE_UNUSED, + /* 5 */ TURTLE_EYEMODE_LOOK_RIGHT, +} EyeMode; + +typedef enum { + /* 0 */ TURTLE_ANIM_IDLE, + /* 1 */ TURTLE_ANIM_SWIM, + /* 2 */ TURTLE_ANIM_FLOAT, + /* 3 */ TURTLE_ANIM_SPEAK1, + /* 4 */ TURTLE_ANIM_COUGH, + /* 5 */ TURTLE_ANIM_SPEAK2, + /* 6 */ TURTLE_ANIM_YAWN, +} TurtleAnimation; + const ActorInit Dm_Char08_InitVars = { ACTOR_DM_CHAR08, ACTORCAT_BG, @@ -28,71 +63,1061 @@ const ActorInit Dm_Char08_InitVars = { (ActorFunc)DmChar08_Draw, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80AB1764[] = { +#include "overlays/ovl_Dm_Char08/ovl_Dm_Char08.c" + +static AnimationInfo sAnimationInfo[] = { + { &gTurtleIdleAnim, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, -24.0f }, + { &gTurtleSwimAnim, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, -24.0f }, + { &gTurtleFloatAnim, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, -24.0f }, + { &gTurtleSpeak1Anim, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, -24.0f }, + { &gTurtleCoughAnim, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, -24.0f }, + { &gTurtleSpeak2Anim, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, -24.0f }, + { &gTurtleYawnAnim, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, -24.0f }, +}; + +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 4000, ICHAIN_STOP), }; -#endif +void DmChar08_UpdateEyes(DmChar08* this) { + switch (this->eyeMode) { + case TURTLE_EYEMODE_BLINK_LEFT: + this->eyeIndex = 0; + if (this->blinkTimer > 0) { + this->blinkTimer--; + } else { + this->blinkTimer = 0; + } + if (this->blinkTimer < 4) { + this->eyeIndex = this->blinkTimer; + } + if (this->blinkTimer == 0) { + this->blinkTimer = Rand_S16Offset(30, 30); + } + break; -extern InitChainEntry D_80AB1764[]; + case TURTLE_EYEMODE_BLINK_STRAIGHT: + this->eyeIndex = 4; + if (this->blinkTimer > 0) { + this->blinkTimer--; + } else { + this->blinkTimer = 0; + } + if (this->blinkTimer < 4) { + this->eyeIndex = this->blinkTimer + 4; + } + if (this->blinkTimer == 0) { + this->blinkTimer = Rand_S16Offset(30, 30); + } + break; -extern UNK_TYPE D_06002470; -extern UNK_TYPE D_06004E70; -extern UNK_TYPE D_0600E748; + case TURTLE_EYEMODE_CLOSED: + this->eyeIndex = 2; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AAF050.s") + case TURTLE_EYEMODE_LOOK_STRAIGHT: + this->eyeIndex = 4; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AAF15C.s") + case TURTLE_EYEMODE_LOOK_RIGHT: + this->eyeIndex = 8; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/DmChar08_Init.s") + default: + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/DmChar08_Destroy.s") +void DmChar08_ChangeAnim(SkelAnime* skelAnime, AnimationInfo* animationInfo, u16 animIndex) { + f32 endFrame; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AAF610.s") + animationInfo += animIndex; + if (animationInfo->frameCount < 0.0f) { + endFrame = Animation_GetLastFrame(animationInfo->animation); + } else { + endFrame = animationInfo->frameCount; + } + Animation_Change(skelAnime, animationInfo->animation, animationInfo->playSpeed, animationInfo->startFrame, endFrame, + animationInfo->mode, animationInfo->morphFrames); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AAF79C.s") +void DmChar08_Init(Actor* thisx, PlayState* play2) { + PlayState* play = play2; + DmChar08* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AAF884.s") + thisx->targetMode = 5; + this->eyeMode = TURTLE_EYEMODE_CLOSED; + thisx->targetArrowOffset = 120.0f; + ActorShape_Init(&thisx->shape, 0.0f, ActorShadow_DrawCircle, 24.0f); + SkelAnime_InitFlex(play, &this->skelAnime, &gTurtleSkel, NULL, NULL, NULL, 0); + Actor_ProcessInitChain(thisx, sInitChain); + Actor_SetScale(thisx, 0.1f); + this->unk_1F4 = 0; + this->bubbleCount = 0; + this->unk_1FF = 0; + this->alpha = 0; + this->animIndex = TURTLE_ANIM_IDLE; + this->unk_1FC = 0xFFFF; + this->dynapolyInitialized = false; + this->targetYPos = thisx->world.pos.y; + this->unk_1F0 = 0.0f; + if (play->sceneId == SCENE_31MISAKI) { + if (gSaveContext.save.weekEventReg[53] & 0x20) { + DynaPolyActor_Init(&this->dyna, 3); + DynaPolyActor_LoadMesh(play, &this->dyna, &gTurtleZoraCapeAwakeCol); + } else { + DynaPolyActor_Init(&this->dyna, 3); + DynaPolyActor_LoadMesh(play, &this->dyna, &gTurtleZoraCapeAsleepCol); + } + this->dynapolyInitialized = true; + } else if (play->sceneId == SCENE_SEA) { + DynaPolyActor_Init(&this->dyna, 3); + DynaPolyActor_LoadMesh(play, &this->dyna, &sTurtleGreatBayTempleCol); + this->dynapolyInitialized = true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AAF8F4.s") + this->palmTree1 = Actor_Spawn(&play->actorCtx, play, ACTOR_OBJ_YASI, thisx->world.pos.x + -80.0f, + thisx->world.pos.y + 390.0f, thisx->world.pos.z, 0, 0, 0, 1); + this->palmTree2 = Actor_Spawn(&play->actorCtx, play, ACTOR_OBJ_YASI, thisx->world.pos.x + 68.0f, + thisx->world.pos.y + 368.0f, thisx->world.pos.z - 174.0f, 0, 0x7530, 0, 1); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AAFA18.s") + switch (play->sceneId) { + case SCENE_31MISAKI: + if (gSaveContext.save.weekEventReg[53] & 0x20) { + thisx->world.pos.x = -6480.0f; + this->targetYPos = -120.0f; + thisx->world.pos.z = 1750.0f; + thisx->world.rot.x = 0; + thisx->world.rot.y = -0x7234; + thisx->world.rot.z = 0; + thisx->shape.rot.x = 0; + thisx->shape.rot.y = -0x7234; + thisx->shape.rot.z = 0; + this->unk_1F0 = 1.0f; + this->unk_1FF = 2; + this->animIndex = TURTLE_ANIM_FLOAT; + this->unk_203 = 0x63; + this->eyeMode = TURTLE_EYEMODE_BLINK_STRAIGHT; + this->unk_207 = 0; + this->unk_208 = 0; + thisx->flags |= ACTOR_FLAG_1; + if (gSaveContext.save.entrance == ENTRANCE(ZORA_CAPE, 8)) { + this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT; + this->actionFunc = func_80AAFAC4; + } else { + this->actionFunc = func_80AAF8F4; + } + } else { + this->actionFunc = DmChar08_WaitForSong; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AAFAC4.s") + case SCENE_SEA: + this->unk_1FF = 2; + this->animIndex = TURTLE_ANIM_FLOAT; + this->unk_203 = 0x63; + this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT; + this->unk_207 = 0; + this->unk_208 = 0; + thisx->flags |= ACTOR_FLAG_1; + this->actionFunc = func_80AAFAE4; + this->unk_1F0 = 1.0f; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AAFAE4.s") + case SCENE_KONPEKI_ENT: + this->unk_1FF = 2; + this->animIndex = TURTLE_ANIM_FLOAT; + this->unk_203 = 0x63; + this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT; + this->unk_207 = 0; + this->unk_208 = 0; + this->actionFunc = DmChar08_DoNothing; + this->unk_1F0 = 1.0f; + break; + } + DmChar08_ChangeAnim(&this->skelAnime, &sAnimationInfo[this->animIndex], 0); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AAFB04.s") +void DmChar08_Destroy(Actor* thisx, PlayState* play) { + DmChar08* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AAFB94.s") + if (this->dynapolyInitialized) { + DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, this->dyna.bgId); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AAFBA4.s") +static s16 sSuccessSoundAlreadyPlayed = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AAFCCC.s") +void DmChar08_WaitForSong(DmChar08* this, PlayState* play) { + Player* player = GET_PLAYER(play); + Player* player2 = GET_PLAYER(play); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AAFE78.s") + if ((player2->stateFlags2 & PLAYER_STATE2_8000000) && + ((player2->actor.world.pos.x > -5780.0f) && (player2->actor.world.pos.x < -5385.0f) && + (player2->actor.world.pos.z > 1120.0f) && (player2->actor.world.pos.z < 2100.0f))) { + if (!sSuccessSoundAlreadyPlayed) { + play_sound(NA_SE_SY_TRE_BOX_APPEAR); + sSuccessSoundAlreadyPlayed = true; + } + } else { + sSuccessSoundAlreadyPlayed = false; + } + if ((player->transformation == PLAYER_FORM_ZORA) && (play->msgCtx.ocarinaMode == 3) && + (play->msgCtx.lastPlayedSong == OCARINA_SONG_NEW_WAVE)) { + if ((player2->actor.world.pos.x > -5780.0f) && (player2->actor.world.pos.x < -5385.0f)) { + if ((player2->actor.world.pos.z > 1120.0f) && (player2->actor.world.pos.z < 2100.0f)) { + this->actionFunc = DmChar08_SetupAppearCs; + } + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AAFE88.s") +void DmChar08_SetupAppearCs(DmChar08* this, PlayState* play) { + s16 cs1 = this->dyna.actor.cutscene; + s16 cs = ActorCutscene_GetAdditionalCutscene( + ActorCutscene_GetAdditionalCutscene(ActorCutscene_GetAdditionalCutscene(cs1))); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AB01E8.s") + if (gSaveContext.save.weekEventReg[93] & 8) { + cs1 = cs; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AB023C.s") + if (ActorCutscene_GetCanPlayNext(cs1)) { + ActorCutscene_Start(cs1, &this->dyna.actor); + gSaveContext.save.weekEventReg[53] |= 0x20; + gSaveContext.save.weekEventReg[93] |= 8; + DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, this->dyna.bgId); + this->actionFunc = func_80AAF884; + } else { + ActorCutscene_SetIntentToPlay(cs1); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AB032C.s") +void func_80AAF884(DmChar08* this, PlayState* play) { + if (play->csCtx.state == CS_STATE_0) { + DynaPolyActor_Init(&this->dyna, 3); + DynaPolyActor_LoadMesh(play, &this->dyna, &gTurtleZoraCapeAwakeCol); + this->dyna.actor.flags |= ACTOR_FLAG_1; + this->actionFunc = func_80AAF8F4; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AB096C.s") +void func_80AAF8F4(DmChar08* this, PlayState* play) { + s32 pad; + f32 yOffset; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AB0A10.s") + if (fabsf(this->dyna.actor.xzDistToPlayer) < 200.0f) { + this->actionFunc = func_80AAFA18; + } + this->unk_1FA += 200; + yOffset = 50.0f; + yOffset *= Math_SinS(this->unk_1FA); + Math_SmoothStepToF(&this->dyna.actor.world.pos.x, -6400.0f, 0.2f, 2.0f, 0.1f); + Math_SmoothStepToF(&this->targetYPos, -180.0f + yOffset, 0.5f, 5.0f, 0.1f); + Math_SmoothStepToF(&this->dyna.actor.world.pos.z, 1750.0f, 0.5f, 20.0f, 0.1f); + Math_SmoothStepToS(&this->dyna.actor.world.rot.y, -0x7234, 0xA, 0xDC, 1); + Math_SmoothStepToS(&this->dyna.actor.shape.rot.y, -0x7234, 0xA, 0xDC, 1); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/DmChar08_Update.s") +void func_80AAFA18(DmChar08* this, PlayState* play) { + s16 nextCs; + s16 nextCs2; + s16 nextCs1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AB0E3C.s") + nextCs1 = ActorCutscene_GetAdditionalCutscene(this->dyna.actor.cutscene); + nextCs2 = nextCs1; + nextCs1 = ActorCutscene_GetAdditionalCutscene(nextCs1); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AB0E7C.s") + nextCs = ((void)0, gSaveContext.save.weekEventReg[53] & 0x40) ? nextCs1 : nextCs2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/func_80AB0F90.s") + if (ActorCutscene_GetCanPlayNext(nextCs) != 0) { + gSaveContext.save.weekEventReg[53] |= 0x40; + ActorCutscene_Start(nextCs, &this->dyna.actor); + this->actionFunc = DmChar08_DoNothing; + } else { + ActorCutscene_SetIntentToPlay(nextCs); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char08/DmChar08_Draw.s") +void func_80AAFAC4(DmChar08* this, PlayState* play) { + if (play->csCtx.state == 0) { + this->actionFunc = func_80AAF8F4; + } +} + +void func_80AAFAE4(DmChar08* this, PlayState* play) { + if (play->csCtx.state == 0) { + this->actionFunc = func_80AAFB04; + } +} + +void func_80AAFB04(DmChar08* this, PlayState* play) { + Player* player = GET_PLAYER(play); + + if ((fabsf(this->dyna.actor.xzDistToPlayer) < 200.0f) && (player->actor.world.pos.y > 0.0f)) { + play->nextEntrance = ENTRANCE(ZORA_CAPE, 7); + play->transitionTrigger = TRANS_TRIGGER_START; + Scene_SetExitFade(play); + this->actionFunc = func_80AAFB94; + } +} + +void func_80AAFB94(DmChar08* this, PlayState* play) { +} + +Color_RGBA8 sLargeTurtleBubblePrimColor = { 250, 200, 250, 100 }; +Color_RGBA8 sLargeTurtleBubbleEnvColor = { 80, 80, 80, 0 }; +Vec3f sLargeTurtleBubbleAccel = { 0.0f, -0.8f, 0.0f }; + +void DmChar08_SpawnBubbles(DmChar08* this, PlayState* play) { + s32 i; + Vec3f velocity; + + velocity.x = (Rand_ZeroOne() - 0.5f) * 24.0f; + velocity.y = -5.2f; + velocity.z = 4.0f; + sLargeTurtleBubbleAccel.x = 0.0f; + sLargeTurtleBubbleAccel.y = 1.18f; + sLargeTurtleBubbleAccel.z = 0.0f; + for (i = 0; i < this->bubbleCount; i++) { + EffectSsDtBubble_SpawnCustomColor(play, &this->bubblePos, &velocity, &sLargeTurtleBubbleAccel, + &sLargeTurtleBubblePrimColor, &sLargeTurtleBubbleEnvColor, + Rand_S16Offset(80, 130), 30, 0); + } +} + +void func_80AAFCCC(DmChar08* this, PlayState* play) { + switch (play->sceneId) { + case SCENE_31MISAKI: + if (!(gSaveContext.save.weekEventReg[55] & 0x80)) { + switch (this->unk_206) { + case 0: + break; + + case 1: + // Fire hookshot + Message_StartTextbox(play, 0x102A, &this->dyna.actor); + this->unk_206++; + break; + + case 2: + // I know your name + if (Message_GetState(&play->msgCtx) == TEXT_STATE_CLOSING) { + Message_StartTextbox(play, 0x102B, &this->dyna.actor); + this->unk_206 = 0; + } + break; + } + } else { + switch (this->unk_206) { + case 0: + break; + + case 1: + // Going to the temple again + Message_StartTextbox(play, 0x103B, &this->dyna.actor); + this->unk_206++; + break; + + case 2: + if (Message_GetState(&play->msgCtx) == TEXT_STATE_CLOSING) { + func_801477B4(play); + this->unk_206 = 0; + } + break; + } + } + return; + + case SCENE_SEA: + switch (this->unk_206) { + case 0: + break; + + case 1: + Message_StartTextbox(play, 0x102E, &this->dyna.actor); + this->unk_206++; + break; + + case 2: + if (Message_GetState(&play->msgCtx) == TEXT_STATE_CLOSING) { + Message_StartTextbox(play, 0x102F, &this->dyna.actor); + this->unk_206 = 0; + } + break; + } + break; + } +} + +void DmChar08_DoNothing(DmChar08* this, PlayState* play) { +} + +void func_80AAFE88(DmChar08* this, PlayState* play) { + s32 actorActionIndex; + CsCmdActorAction* csAction; + f32 phi_f12; + + if (Cutscene_CheckActorAction(play, 474)) { + actorActionIndex = Cutscene_GetActorActionIndex(play, 474); + if (this->unk_1F6 != play->csCtx.actorActions[actorActionIndex]->action) { + this->unk_1F6 = play->csCtx.actorActions[actorActionIndex]->action; + switch (play->csCtx.actorActions[actorActionIndex]->action) { + case 1: + this->animIndex = TURTLE_ANIM_IDLE; + break; + + case 3: + this->bubbleCount = 2; + break; + + case 4: + this->animIndex = TURTLE_ANIM_FLOAT; + break; + + case 5: + this->animIndex = TURTLE_ANIM_SWIM; + break; + + case 6: + this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT; + break; + + case 7: + this->eyeMode = TURTLE_EYEMODE_CLOSED; + break; + + case 8: + this->animIndex = TURTLE_ANIM_YAWN; + break; + + case 9: + this->animIndex = TURTLE_ANIM_FLOAT; + break; + + case 10: + this->animIndex = TURTLE_ANIM_COUGH; + break; + + case 12: + this->animIndex = TURTLE_ANIM_SPEAK2; + break; + + case 13: + this->bubbleCount = 0; + break; + + case 14: + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_BIG_TORTOISE_ROLL); + this->animIndex = TURTLE_ANIM_FLOAT; + break; + } + } + switch (play->csCtx.actorActions[actorActionIndex]->action) { + case 2: + this->unk_1FF = 1; + phi_f12 = 2.0f * Environment_LerpWeight(play->csCtx.actorActions[actorActionIndex]->endFrame, + play->csCtx.actorActions[actorActionIndex]->startFrame, + play->csCtx.frames); + if (phi_f12 > 1.0f) { + phi_f12 = 1.0f; + } + + this->alpha = (1.0f - phi_f12) * 255.0f; + if (this->alpha < 6) { + this->unk_1FF = 2; + } + + Cutscene_ActorTranslateAndYaw(&this->dyna.actor, play, actorActionIndex); + break; + + case 5: + Cutscene_ActorTranslateAndYawSmooth(&this->dyna.actor, play, actorActionIndex); + break; + + case 14: + Cutscene_ActorTranslate(&this->dyna.actor, play, actorActionIndex); + Math_SmoothStepToS(&this->dyna.actor.world.rot.y, play->csCtx.actorActions[actorActionIndex]->rot.y, + 0xA, 0xDC, 1); + this->dyna.actor.shape.rot.y = this->dyna.actor.world.rot.y; + break; + + default: + Cutscene_ActorTranslateAndYaw(&this->dyna.actor, play, actorActionIndex); + break; + } + this->targetYPos = this->dyna.actor.world.pos.y; + if ((this->unk_1FF >= 2) || (play->csCtx.actorActions[actorActionIndex]->action == 2)) { + Math_SmoothStepToF(&this->unk_1F0, 1.0f, 0.02f, 0.1f, 0.00001f); + } + } else { + this->unk_1F6 = 99; + } +} + +void func_80AB01E8(DmChar08* this, PlayState* play) { + if (this->animIndex != this->unk_203) { + this->unk_203 = this->animIndex; + DmChar08_ChangeAnim(&this->skelAnime, &sAnimationInfo[this->animIndex], 0); + } +} + +void func_80AB023C(DmChar08* this, PlayState* play) { + if ((play->msgCtx.currentTextId != this->unk_1FC) && (play->msgCtx.currentTextId != 0)) { + this->unk_1FC = play->msgCtx.currentTextId; + this->unk_208 = 0; + switch (play->msgCtx.currentTextId) { + case 0x1025: // Slept well + this->unk_207 = 1; + break; + + case 0x1026: // Time Flies + this->unk_207 = 2; + break; + + case 0x1027: // See Everything + this->unk_207 = 3; + break; + + case 0x1028: // No time + this->unk_207 = 4; + break; + + case 0x1029: // Quick lets go + this->unk_207 = 10; + break; + + case 0x102C: // Having trouble + this->unk_207 = 5; + break; + + case 0x102D: // Ready, climb + this->unk_207 = 8; + break; + + case 0x102A: // Fire hookshot + this->unk_207 = 6; + break; + + case 0x102B: // I know your name + this->unk_207 = 2; + break; + + case 0x102E: // Returning to shore + this->unk_207 = 9; + break; + + case 0x102F: // It is okay to retreat + this->unk_207 = 7; + break; + + case 0x103B: // Going to the temple again + this->unk_207 = 6; + + break; + case 0x1030: // Return to sleep + this->unk_207 = 4; + break; + } + } +} + +void func_80AB032C(DmChar08* this, PlayState* play) { + switch (this->unk_207) { + case 1: + switch (this->unk_208) { + case 0: + this->animIndex = TURTLE_ANIM_YAWN; + this->eyeMode = TURTLE_EYEMODE_CLOSED; + this->unk_208++; + break; + + case 1: + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->animIndex = TURTLE_ANIM_FLOAT; + this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT; + this->unk_207 = 0; + this->unk_208 = 0; + } + break; + } + break; + + case 2: + switch (this->unk_208) { + case 0: + this->animIndex = TURTLE_ANIM_COUGH; + this->eyeMode = TURTLE_EYEMODE_CLOSED; + this->unk_208++; + break; + + case 1: + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->animIndex = TURTLE_ANIM_SPEAK1; + this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT; + this->unk_208++; + } + break; + + case 2: + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->animIndex = TURTLE_ANIM_FLOAT; + this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT; + this->unk_207 = 0; + this->unk_208 = 0; + } + break; + } + break; + + case 3: + case 4: + case 8: + switch (this->unk_208) { + case 0: + this->animIndex = TURTLE_ANIM_SPEAK1; + if (this->unk_207 >= 5) { + this->eyeMode = TURTLE_EYEMODE_CLOSED; + } else { + this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT; + } + this->unk_208 = 2; + break; + + case 2: + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->animIndex = TURTLE_ANIM_SPEAK2; + this->eyeMode = TURTLE_EYEMODE_CLOSED; + this->unk_208++; + } + break; + + case 3: + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + if (this->unk_207 != 4) { + this->animIndex = TURTLE_ANIM_FLOAT; + this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT; + this->unk_207 = 0; + this->unk_208 = 0; + } else { + this->animIndex = TURTLE_ANIM_SPEAK1; + this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT; + this->unk_208++; + } + } + break; + + case 4: + case 5: + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->unk_208++; + } + break; + + case 6: + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->animIndex = TURTLE_ANIM_FLOAT; + this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT; + this->unk_207 = 0; + this->unk_208 = 0; + } + break; + } + break; + + case 5: + switch (this->unk_208) { + case 0: + this->animIndex = TURTLE_ANIM_SPEAK1; + this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT; + this->unk_208++; + break; + + case 2: + case 3: + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->unk_208++; + } + break; + + case 4: + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->animIndex = TURTLE_ANIM_SPEAK2; + this->eyeMode = TURTLE_EYEMODE_CLOSED; + this->unk_208++; + } + break; + + case 5: + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->animIndex = TURTLE_ANIM_FLOAT; + this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT; + this->unk_207 = 0; + this->unk_208 = 0; + } + break; + } + break; + + case 6: + switch (this->unk_208) { + case 0: + this->animIndex = TURTLE_ANIM_SPEAK1; + this->eyeMode = TURTLE_EYEMODE_LOOK_RIGHT; + this->unk_208++; + break; + + case 1: + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->unk_208++; + } + break; + + case 2: + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->animIndex = TURTLE_ANIM_FLOAT; + this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT; + this->unk_207 = 0; + this->unk_208 = 0; + } + break; + } + break; + + case 7: + switch (this->unk_208) { + case 0: + this->animIndex = TURTLE_ANIM_SPEAK2; + this->eyeMode = TURTLE_EYEMODE_CLOSED; + this->unk_208++; + break; + + case 1: + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->animIndex = TURTLE_ANIM_SPEAK1; + this->eyeMode = TURTLE_EYEMODE_CLOSED; + this->unk_208++; + } + break; + + case 2: + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->animIndex = TURTLE_ANIM_FLOAT; + this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT; + this->unk_207 = 0; + this->unk_208 = 0; + } + break; + } + break; + + case 9: + switch (this->unk_208) { + case 0: + this->animIndex = TURTLE_ANIM_SPEAK1; + this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT; + this->unk_208++; + break; + + case 1: + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->unk_208++; + } + if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play)) { + this->unk_208 = 3; + } + break; + + case 2: + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->animIndex = TURTLE_ANIM_FLOAT; + this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT; + this->unk_208++; + } + if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play)) { + this->unk_208 = 3; + } + break; + + case 3: + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->animIndex = TURTLE_ANIM_COUGH; + this->eyeMode = TURTLE_EYEMODE_CLOSED; + this->unk_208++; + } + break; + + case 4: + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->animIndex = TURTLE_ANIM_FLOAT; + this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT; + this->unk_207 = 0; + this->unk_208 = 0; + } + break; + } + break; + case 10: + switch (this->unk_208) { + case 0: + this->animIndex = TURTLE_ANIM_SPEAK1; + this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT; + this->unk_208++; + break; + case 1: + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->animIndex = TURTLE_ANIM_SPEAK2; + this->eyeMode = TURTLE_EYEMODE_CLOSED; + this->unk_208++; + } + break; + case 2: + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->animIndex = TURTLE_ANIM_SPEAK1; + this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT; + this->unk_208++; + } + break; + case 3: + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->animIndex = TURTLE_ANIM_FLOAT; + this->eyeMode = TURTLE_EYEMODE_BLINK_LEFT; + this->unk_207 = 0; + this->unk_208 = 0; + } + break; + } + break; + } +} + +void func_80AB096C(DmChar08* this, PlayState* play) { + if ((play->csCtx.state != 0) && (play->sceneId == SCENE_31MISAKI) && (gSaveContext.sceneLayer == 0) && + (play->csCtx.currentCsIndex == 0)) { + if ((play->csCtx.frames >= 890) && (play->csCtx.frames < 922)) { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_EARTHQUAKE_LAST2 - SFX_FLAG); + } + } + if ((this->animIndex == TURTLE_ANIM_SWIM) && Animation_OnFrame(&this->skelAnime, 16.0f)) { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_BIG_TORTOISE_SWIM); + } +} + +void DmChar08_UpdateCollision(DmChar08* this, PlayState* play) { + Player* player = GET_PLAYER(play); + f32 curFrame; + f32 phi_f2; + f32 phi_f0; + f32 phi_f12; + s32 i; + + if (player->actor.world.pos.x > 0.0f) { + curFrame = this->skelAnime.curFrame; + if (curFrame <= 19.0f) { + phi_f12 = 19.0f; + phi_f2 = curFrame / 19.0f; + } else { + phi_f2 = (29.0f - curFrame) / 9.0f; + phi_f12 = 29.0f; + } + + sTurtleGreatBayTempleCol.polyList = sTurtleGreatBayTempleColPolygons; + + for (i = 0; i < ARRAY_COUNT(sTurtleGreatBayTempleColVertices); i++) { + sTurtleGreatBayTempleColVertices[i].x = sTurtleGreatBayTempleColVertices2[i].x; + } + + sTurtleGreatBayTempleColVertices[0].y = (100.0f * phi_f2) + 900.0f; + sTurtleGreatBayTempleColVertices[1].y = (100.0f * phi_f2) + 900.0f; + sTurtleGreatBayTempleColVertices[2].y = (500.0f * phi_f2) + -200.0f; + sTurtleGreatBayTempleColVertices[3].y = (900.0f * phi_f2) + -800.0f; + sTurtleGreatBayTempleColVertices[5].y = 0x4B0; + sTurtleGreatBayTempleColVertices[9].y = 0x6A4; + } else { + phi_f0 = this->skelAnime.curFrame + 26.0f; + if (phi_f0 > 29.0f) { + phi_f12 = 29.0f; + phi_f0 -= 29.0f; + } + + if (phi_f0 <= 18.0f) { + phi_f2 = phi_f0 / 18.0f; + } else { + phi_f2 = (29.0f - phi_f0) / 10.0f; + } + + sTurtleGreatBayTempleCol.polyList = sTurtleGreatBayTempleColPolygons2; + + for (i = 0; i < ARRAY_COUNT(sTurtleGreatBayTempleColVertices); i++) { + sTurtleGreatBayTempleColVertices[i].x = -sTurtleGreatBayTempleColVertices2[i].x; + } + + sTurtleGreatBayTempleColVertices[0].y = (500.0f * phi_f2) + 720.0f; + sTurtleGreatBayTempleColVertices[1].y = (660.0f * phi_f2) + 420.0f; + sTurtleGreatBayTempleColVertices[2].y = (1130.0f * phi_f2) + -430.0f; + sTurtleGreatBayTempleColVertices[3].y = (1430.0f * phi_f2) + -1060.0f; + sTurtleGreatBayTempleColVertices[5].y = 0x4B0; + sTurtleGreatBayTempleColVertices[9].y = 0x6A4; + } + func_800C6554(play, &play->colCtx.dyna); +} + +void DmChar08_Update(Actor* thisx, PlayState* play) { + DmChar08* this = THIS; + + this->dyna.actor.focus.pos.x = this->focusPos.x; + this->dyna.actor.focus.pos.y = this->focusPos.y + this->dyna.actor.targetArrowOffset; + this->dyna.actor.focus.pos.z = this->focusPos.z; + this->dyna.actor.focus.rot.x = this->dyna.actor.world.rot.x; + this->dyna.actor.focus.rot.y = this->dyna.actor.world.rot.y; + this->dyna.actor.focus.rot.z = this->dyna.actor.world.rot.z; + + if (Actor_ProcessTalkRequest(&this->dyna.actor, &play->state)) { + this->unk_206 = 1; + } + + DmChar08_UpdateEyes(this); + this->actionFunc(this, play); + func_80AAFE88(this, play); + func_80AB023C(this, play); + func_80AB032C(this, play); + func_80AB01E8(this, play); + SkelAnime_Update(&this->skelAnime); + DmChar08_SpawnBubbles(this, play); + this->dyna.actor.world.pos.y = this->targetYPos; + if (play->sceneId == SCENE_31MISAKI) { + if (this->dyna.actor.xzDistToPlayer > 1300.0f) { + func_800C62BC(play, &play->colCtx.dyna, this->dyna.bgId); + } else { + func_800C6314(play, &play->colCtx.dyna, this->dyna.bgId); + } + } + if (this->unk_1FF != 0) { + func_80AAFCCC(this, play); + func_800B8614(&this->dyna.actor, play, 400.0f); + } + func_80AB096C(this, play); + DmChar08_UpdateCollision(this, play); +} + +s32 DmChar08_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + if ((play->csCtx.state == 0) && (play->sceneId == SCENE_31MISAKI) && + (limbIndex == TURTLE_LIMB_FRONT_RIGHT_UPPER_FLIPPER)) { + rot->z = -0x5E24; + } + return false; +} + +void DmChar08_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + DmChar08* this = THIS; + Vec3f src; + + if (limbIndex == TURTLE_LIMB_SHELL) { + src.x = 800.0f; + src.y = 2600.0f; + src.z = -800.0f; + Matrix_MultVec3f(&src, &this->tree1Pos); + src.x = 2600.0f; + src.y = 2500.0f; + src.z = 700.0f; + Matrix_MultVec3f(&src, &this->tree2Pos); + } else if (limbIndex == TURTLE_LIMB_LOWER_MOUTH) { + src.x = 1600.0f; + src.y = -200.0f; + src.z = 0.0f; + Matrix_MultVec3f(&src, &this->bubblePos); + } else if (limbIndex == TURTLE_LIMB_UPPER_MOUTH) { + src.x = 600.0f; + src.y = 700.0f; + src.z = 0.0f; + Matrix_MultVec3f(&src, &this->focusPos); + } +} + +void DmChar08_TransformLimbDraw(PlayState* play, s32 limbIndex, Actor* thisx) { + DmChar08* this = THIS; + f32 one; + + switch (limbIndex) { + case TURTLE_LIMB_SHELL: + break; + + case TURTLE_LIMB_NECK: + Matrix_Pop(); + one = 1.0f; + Matrix_Scale(((one - 0.7f) * this->unk_1F0) + 0.7f, ((one - 0.7f) * this->unk_1F0) + 0.7f, 1.0f, + MTXMODE_APPLY); + Matrix_Push(); + break; + + case TURTLE_LIMB_FRONT_LEFT_UPPER_FLIPPER: + case TURTLE_LIMB_FRONT_LEFT_LOWER_FLIPPER: + case TURTLE_LIMB_FRONT_RIGHT_UPPER_FLIPPER: + case TURTLE_LIMB_FRONT_RIGHT_LOWER_FLIPPER: + Matrix_Pop(); + Matrix_Scale((this->unk_1F0 * 0.4f) + 0.6f, (this->unk_1F0 * 0.4f) + 0.6f, (this->unk_1F0 * 0.4f) + 0.6f, + MTXMODE_APPLY); + Matrix_Push(); + break; + + case TURTLE_LIMB_FRONT_LEFT_END_FLIPPER: + case TURTLE_LIMB_FRONT_RIGHT_END_FLIPPER: + Matrix_Scale((this->unk_1F0 * 0.4f) + 0.6f, (this->unk_1F0 * 0.4f) + 0.6f, (this->unk_1F0 * 0.4f) + 0.6f, + MTXMODE_APPLY); + break; + + case TURTLE_TAIL_LIMB: + Matrix_Pop(); + Matrix_Scale((this->unk_1F0 * 0.52f) + 0.48f, (this->unk_1F0 * 0.52f) + 0.48f, + (this->unk_1F0 * 0.52f) + 0.48f, MTXMODE_APPLY); + Matrix_Push(); + break; + + case TURTLE_LIMB_BACK_LEFT_FLIPPER: + case TURTLE_LIMB_BACK_RIGHT_FLIPPER: + Matrix_Scale((this->unk_1F0 * 0.55f) + 0.45f, (this->unk_1F0 * 0.2f) + 0.8f, + (this->unk_1F0 * 0.55f) + 0.45f, MTXMODE_APPLY); + break; + } +} + +TexturePtr sBigTurtleEyeTextures[] = { + gTurtleEyeOpenLeftTex, gTurtleEyeHalfLeftTex, gTurtleEyeClosedTex, + gTurtleEyeHalfLeftTex, gTurtleEyeOpenStraightTex, gTurtleEyeHalfStraightTex, + gTurtleEyeClosedTex, gTurtleEyeHalfStraightTex, gTurtleEyeOpenRightTex, +}; + +void DmChar08_Draw(Actor* thisx, PlayState* play) { + s32 pad; + DmChar08* this = THIS; + + OPEN_DISPS(play->state.gfxCtx); + func_8012C28C(play->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(sBigTurtleEyeTextures[this->eyeIndex])); + gSPSegment(POLY_OPA_DISP++, 0x09, Lib_SegmentedToVirtual(sBigTurtleEyeTextures[this->eyeIndex])); + if ((this->unk_1FF > 0) || (play->csCtx.state != CS_STATE_0)) { + SkelAnime_DrawTransformFlexOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, DmChar08_OverrideLimbDraw, DmChar08_PostLimbDraw, + DmChar08_TransformLimbDraw, &this->dyna.actor); + this->palmTree1->world.pos.x = this->tree1Pos.x; + this->palmTree1->world.pos.y = this->tree1Pos.y; + this->palmTree1->world.pos.z = this->tree1Pos.z; + this->palmTree2->world.pos.x = this->tree2Pos.x; + this->palmTree2->world.pos.y = this->tree2Pos.y; + this->palmTree2->world.pos.z = this->tree2Pos.z; + } + if (this->unk_1FF == 0) { + Scene_SetRenderModeXlu(play, 0, 1); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gTurtleAsleepDL); + } else if (this->unk_1FF == 1) { + func_8012C2DC(play->state.gfxCtx); + Scene_SetRenderModeXlu(play, 2, 2); + gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, this->alpha); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gTurtleAsleepDL); + } + CLOSE_DISPS(play->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Dm_Char08/z_dm_char08.h b/src/overlays/actors/ovl_Dm_Char08/z_dm_char08.h index 1718a9fb0..2cdbb52c7 100644 --- a/src/overlays/actors/ovl_Dm_Char08/z_dm_char08.h +++ b/src/overlays/actors/ovl_Dm_Char08/z_dm_char08.h @@ -8,10 +8,36 @@ struct DmChar08; typedef void (*DmChar08ActionFunc)(struct DmChar08*, PlayState*); typedef struct DmChar08 { - /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x5C]; + /* 0x000 */ DynaPolyActor dyna; + /* 0x15C */ SkelAnime skelAnime; /* 0x1A0 */ DmChar08ActionFunc actionFunc; - /* 0x1A4 */ char unk_1A4[0x68]; + /* 0x1A4 */ Actor* palmTree1; + /* 0x1A8 */ Actor* palmTree2; + /* 0x1AC */ Vec3f tree1Pos; + /* 0x1B8 */ Vec3f tree2Pos; + /* 0x1C4 */ Vec3f bubblePos; + /* 0x1D0 */ Vec3f focusPos; + /* 0x1DC */ UNK_TYPE1 unk_1DC[8]; + /* 0x1E4 */ f32 targetYPos; + /* 0x1E8 */ UNK_TYPE1 unk_1E8[8]; + /* 0x1F0 */ f32 unk_1F0; + /* 0x1F4 */ s16 unk_1F4; + /* 0x1F6 */ s16 unk_1F6; + /* 0x1F6 */ s16 blinkTimer; + /* 0x1FA */ s16 unk_1FA; + /* 0x1FC */ u16 unk_1FC; + /* 0x1FE */ u8 bubbleCount; + /* 0x1FF */ u8 unk_1FF; + /* 0x200 */ u8 eyeMode; + /* 0x201 */ u8 eyeIndex; + /* 0x202 */ u8 animIndex; + /* 0x203 */ u8 unk_203; + /* 0x204 */ UNK_TYPE1 unk_204; + /* 0x205 */ u8 alpha; + /* 0x206 */ u8 unk_206; + /* 0x207 */ u8 unk_207; + /* 0x208 */ u8 unk_208; + /* 0x209 */ u8 dynapolyInitialized; } DmChar08; // size = 0x20C extern const ActorInit Dm_Char08_InitVars; diff --git a/src/overlays/actors/ovl_Dm_Char09/z_dm_char09.c b/src/overlays/actors/ovl_Dm_Char09/z_dm_char09.c index 8f02a8bb4..0bb112b43 100644 --- a/src/overlays/actors/ovl_Dm_Char09/z_dm_char09.c +++ b/src/overlays/actors/ovl_Dm_Char09/z_dm_char09.c @@ -31,7 +31,7 @@ const ActorInit Dm_Char09_InitVars = { }; static AnimationInfo sAnimationInfo[] = { - { &object_bee_Anim_00005C, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, 0.0f }, + { &gBeeFlyingAnim, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, 0.0f }, }; void DmChar09_ChangeAnim(SkelAnime* skelAnime, AnimationInfo* animationInfo, u16 animIndex) { @@ -53,8 +53,8 @@ void DmChar09_Init(Actor* thisx, PlayState* play) { DmChar09* this = THIS; ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 19.0f); - SkelAnime_Init(play, &this->skelAnime, &object_bee_Skel_001398, &object_bee_Anim_00005C, this->jointTable, - this->morphTable, OBJECT_BEE_LIMB_MAX); + SkelAnime_Init(play, &this->skelAnime, &gBeeSkel, &gBeeFlyingAnim, this->jointTable, this->morphTable, + OBJECT_BEE_LIMB_MAX); DmChar09_ChangeAnim(&this->skelAnime, sAnimationInfo, 0); Actor_SetScale(&this->actor, 0.01f); this->unk_228 = Rand_ZeroOne() * 65535.0f; diff --git a/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c b/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c index d7e9424e5..d7913b775 100644 --- a/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c +++ b/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c @@ -373,7 +373,7 @@ void func_808A1090(DoorShutter* this, PlayState* play) { } } else if (this->unk_166 != 0) { if (this->doorType == 5) { - if (!CHECK_DUNGEON_ITEM(0, gSaveContext.mapIndex)) { + if (!CHECK_DUNGEON_ITEM(DUNGEON_BOSS_KEY, gSaveContext.mapIndex)) { player->doorType = -1; this->actor.textId = 0x1803; } diff --git a/src/overlays/actors/ovl_Eff_Kamejima_Wave/z_eff_kamejima_wave.c b/src/overlays/actors/ovl_Eff_Kamejima_Wave/z_eff_kamejima_wave.c index 83842569f..2de3d8604 100644 --- a/src/overlays/actors/ovl_Eff_Kamejima_Wave/z_eff_kamejima_wave.c +++ b/src/overlays/actors/ovl_Eff_Kamejima_Wave/z_eff_kamejima_wave.c @@ -56,7 +56,7 @@ void EffKamejimaWave_Init(Actor* thisx, PlayState* play) { this->actionFunc = func_80BCEC6C; sVtxAlpha = 255; } - D_80BCF1C4 = Lib_SegmentedToVirtual(object_kamejima_Matanimheader_001AF0); + D_80BCF1C4 = Lib_SegmentedToVirtual(gTurtleWaveTexAnim); } void EffKamejimaWave_Destroy(Actor* thisx, PlayState* play) { @@ -137,7 +137,7 @@ void EffKamejimaWave_Update(Actor* thisx, PlayState* play) { } void EffKamejimaWave_SetVtxAlpha(u8 alpha) { - Vtx* vtx = Lib_SegmentedToVirtual(&object_kamejima_Vtx_000000); + Vtx* vtx = Lib_SegmentedToVirtual(&gTurtleWaveVtx); vtx[2].v.cn[3] = alpha; vtx[6].v.cn[3] = alpha; @@ -165,7 +165,7 @@ void EffKamejimaWave_Draw(Actor* thisx, PlayState* play) { AnimatedMat_Draw(play, D_80BCF1C4); gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, primColor.r, primColor.g, primColor.b, 255); gDPSetEnvColor(POLY_XLU_DISP++, envColor.r, envColor.g, envColor.b, 255); - gSPDisplayList(POLY_XLU_DISP++, object_kamejima_DL_000140); + gSPDisplayList(POLY_XLU_DISP++, gTurtleWaveDL); CLOSE_DISPS(play->state.gfxCtx); } diff --git a/src/overlays/actors/ovl_En_Bee/z_en_bee.c b/src/overlays/actors/ovl_En_Bee/z_en_bee.c index 0a0c6dd3f..7d40e9931 100644 --- a/src/overlays/actors/ovl_En_Bee/z_en_bee.c +++ b/src/overlays/actors/ovl_En_Bee/z_en_bee.c @@ -15,12 +15,12 @@ void EnBee_Destroy(Actor* thisx, PlayState* play); void EnBee_Update(Actor* thisx, PlayState* play); void EnBee_Draw(Actor* thisx, PlayState* play); -void func_80B5A9E8(EnBee* this, PlayState* play); -void func_80B5AC3C(EnBee* this, PlayState* play); -void func_80B5A854(EnBee* this); -void func_80B5ABC4(EnBee* this); +void EnBee_SetupFlyIdle(EnBee* this); +void EnBee_FlyIdle(EnBee* this, PlayState* play); +void EnBee_SetupAttack(EnBee* this); +void EnBee_Attack(EnBee* this, PlayState* play); -s32 D_80B5B1F0 = 0; +s32 sNumLoadedBees = 0; const ActorInit En_Bee_InitVars = { ACTOR_EN_BEE, @@ -94,14 +94,14 @@ void EnBee_Init(Actor* thisx, PlayState* play) { this->actor.colChkInfo.mass = 10; ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 19.0f); - SkelAnime_Init(play, &this->skelAnime, &object_bee_Skel_001398, &object_bee_Anim_00005C, this->morphTable, - this->jointTable, OBJECT_BEE_LIMB_MAX); + SkelAnime_Init(play, &this->skelAnime, &gBeeSkel, &gBeeFlyingAnim, this->morphTable, this->jointTable, + OBJECT_BEE_LIMB_MAX); this->actor.colChkInfo.health = 1; this->actor.colChkInfo.damageTable = &sDamageTable; this->actor.targetMode = 6; Collider_InitAndSetCylinder(play, &this->collider, &this->actor, &sCylinderInit); - this->unk_218 = D_80B5B1F0; - D_80B5B1F0++; + this->instanceId = sNumLoadedBees; + sNumLoadedBees++; this->actor.shape.shadowScale = 12.0f; if (ActorCutscene_GetCurrentIndex() != -1) { @@ -109,7 +109,7 @@ void EnBee_Init(Actor* thisx, PlayState* play) { } this->actor.hintId = TATL_HINT_ID_GIANT_BEE; - func_80B5A854(this); + EnBee_SetupFlyIdle(this); } void EnBee_Destroy(Actor* thisx, PlayState* play) { @@ -118,121 +118,122 @@ void EnBee_Destroy(Actor* thisx, PlayState* play) { Collider_DestroyCylinder(play, &this->collider); } -void func_80B5A854(EnBee* this) { +void EnBee_SetupFlyIdle(EnBee* this) { s32 pad; - Vec3f sp48; - s16 sp46; + Vec3f tempPos; + s16 yawOffset; - Animation_Change(&this->skelAnime, &object_bee_Anim_00005C, 1.0f, 0.0f, - Animation_GetLastFrame(&object_bee_Anim_00005C), 0, -10.0f); - Math_Vec3f_Copy(&sp48, &this->actor.home.pos); + Animation_Change(&this->skelAnime, &gBeeFlyingAnim, 1.0f, 0.0f, Animation_GetLastFrame(&gBeeFlyingAnim), 0, -10.0f); + Math_Vec3f_Copy(&tempPos, &this->actor.home.pos); - sp46 = (this->unk_218 * 0x700) + 0x2000; - sp48.x += Math_SinS(sp46) * 50.0f; - sp48.y = Rand_ZeroFloat(50.0f) + (this->actor.floorHeight + 30.0f); - sp48.z += Math_CosS(sp46) * 50.0f; + yawOffset = (this->instanceId * 0x700) + 0x2000; + tempPos.x += Math_SinS(yawOffset) * 50.0f; + tempPos.y = Rand_ZeroFloat(50.0f) + (this->actor.floorHeight + 30.0f); + tempPos.z += Math_CosS(yawOffset) * 50.0f; - Math_Vec3f_Copy(&this->unk_21C[0], &sp48); - Math_Vec3f_Copy(&sp48, &this->actor.home.pos); + Math_Vec3f_Copy(&this->targetPos[0], &tempPos); + Math_Vec3f_Copy(&tempPos, &this->actor.home.pos); - sp48.x += Math_SinS(sp46 - 0x4000) * 50.0f; - sp48.y = Rand_ZeroFloat(50.0f) + (this->actor.floorHeight + 30.0f); - sp48.z += Math_CosS(sp46 - 0x4000) * 50.0f; + tempPos.x += Math_SinS(yawOffset - 0x4000) * 50.0f; + tempPos.y = Rand_ZeroFloat(50.0f) + (this->actor.floorHeight + 30.0f); + tempPos.z += Math_CosS(yawOffset - 0x4000) * 50.0f; - Math_Vec3f_Copy(&this->unk_21C[1], &sp48); + Math_Vec3f_Copy(&this->targetPos[1], &tempPos); - this->unk_204 = Rand_S16Offset(0x14, 0x1E); - this->unk_208 = 0; - this->actionFunc = func_80B5A9E8; + this->attackDelayTimer = Rand_S16Offset(20, 30); + this->isHostile = false; + this->actionFunc = EnBee_FlyIdle; } -void func_80B5A9E8(EnBee* this, PlayState* play) { - Vec3f sp3C; +void EnBee_FlyIdle(EnBee* this, PlayState* play) { + Vec3f nextPos; s32 pad[2]; if ((this->actor.category != ACTORCAT_ENEMY) && (ActorCutscene_GetCurrentIndex() == -1)) { func_800BC154(play, &play->actorCtx, &this->actor, ACTORCAT_ENEMY); } - Math_Vec3f_Copy(&sp3C, &this->unk_21C[this->unk_214]); - sp3C.x += Math_SinS(this->unk_20C) * 30.0f; - sp3C.z += Math_CosS(this->unk_20C) * 30.0f; + Math_Vec3f_Copy(&nextPos, &this->targetPos[this->posIndex]); + nextPos.x += Math_SinS(this->targetYaw) * 30.0f; + nextPos.z += Math_CosS(this->targetYaw) * 30.0f; - if (!(this->unk_218 & 1)) { - this->unk_20C += (s16)((s32)randPlusMinusPoint5Scaled(1000.0f) + 4000); + if ((this->instanceId % 2) == 0) { + this->targetYaw += (s16)((s32)randPlusMinusPoint5Scaled(1000.0f) + 4000); } else { - this->unk_20C -= (s16)((s32)randPlusMinusPoint5Scaled(1000.0f) + 4000); + this->targetYaw -= (s16)((s32)randPlusMinusPoint5Scaled(1000.0f) + 4000); } - this->unk_210 += 1000; - this->actor.velocity.y = Math_SinS(this->unk_210); + this->flightHoverOffset += 1000; + this->actor.velocity.y = Math_SinS(this->flightHoverOffset); - if (this->unk_20C > 0x10000) { - this->unk_20C = 0; - this->unk_214++; - this->unk_214 &= 1; + if (this->targetYaw > 0x10000) { + this->targetYaw = 0; + this->posIndex++; + this->posIndex &= 1; } - Math_SmoothStepToS(&this->actor.world.rot.y, Math_Vec3f_Yaw(&this->actor.world.pos, &sp3C), 1, 0x7D0, 0); + Math_SmoothStepToS(&this->actor.world.rot.y, Math_Vec3f_Yaw(&this->actor.world.pos, &nextPos), 1, 0x7D0, 0); Math_ApproachF(&this->actor.speedXZ, 3.0f, 0.3f, 1.0f); - if ((this->unk_204 == 0) && (this->actor.params != 0)) { - func_80B5ABC4(this); + if ((this->attackDelayTimer == 0) && (this->actor.params != BEE_BEHAVIOR_IDLE)) { + EnBee_SetupAttack(this); } } -void func_80B5ABC4(EnBee* this) { - Animation_Change(&this->skelAnime, &object_bee_Anim_00005C, 1.0f, 0.0f, - Animation_GetLastFrame(&object_bee_Anim_00005C), 0, -10.0f); - this->unk_208 = 1; - this->actionFunc = func_80B5AC3C; +void EnBee_SetupAttack(EnBee* this) { + Animation_Change(&this->skelAnime, &gBeeFlyingAnim, 1.0f, 0.0f, Animation_GetLastFrame(&gBeeFlyingAnim), 0, -10.0f); + this->isHostile = true; + this->actionFunc = EnBee_Attack; } -void func_80B5AC3C(EnBee* this, PlayState* play) { +void EnBee_Attack(EnBee* this, PlayState* play) { Player* player = GET_PLAYER(play); - Vec3f sp88; - f32 rnd; - f32 phi_fs1; + Vec3f nextPos; + f32 rand; + f32 yawOffset; s32 i; - Math_Vec3f_Copy(&sp88, &player->actor.world.pos); - phi_fs1 = (this->unk_218 * 0x700) + 0x2000; + Math_Vec3f_Copy(&nextPos, &player->actor.world.pos); + yawOffset = (this->instanceId * 0x700) + 0x2000; for (i = 0; i < 2; i++) { - rnd = randPlusMinusPoint5Scaled(20.0f); - sp88.x += Math_SinS((this->actor.yawTowardsPlayer + ((f32)this->unk_20C)) + phi_fs1) * (rnd + 30.0f); - sp88.y = (Math_SinS(this->unk_210) * 10.0f) + (player->actor.floorHeight + 40.0f); - rnd = randPlusMinusPoint5Scaled(20.0f); - sp88.z += Math_CosS((f32)this->actor.yawTowardsPlayer + this->unk_20C + phi_fs1) * (rnd + 30.0f); - Math_Vec3f_Copy(&this->unk_21C[i], &sp88); - phi_fs1 -= 16384.0f; + rand = randPlusMinusPoint5Scaled(20.0f); + nextPos.x += Math_SinS((f32)this->actor.yawTowardsPlayer + this->targetYaw + yawOffset) * (rand + 30.0f); + nextPos.y = (Math_SinS(this->flightHoverOffset) * 10.0f) + (player->actor.floorHeight + 40.0f); + rand = randPlusMinusPoint5Scaled(20.0f); + + nextPos.z += Math_CosS((f32)this->actor.yawTowardsPlayer + this->targetYaw + yawOffset) * (rand + 30.0f); + Math_Vec3f_Copy(&this->targetPos[i], &nextPos); + yawOffset -= 0x4000; } - Math_Vec3f_Copy(&sp88, &this->unk_21C[this->unk_214]); + Math_Vec3f_Copy(&nextPos, &this->targetPos[this->posIndex]); - if (!(this->unk_218 & 1)) { - this->unk_20C += (this->unk_218 * 0x700) + (s32)randPlusMinusPoint5Scaled((this->unk_218 * 0x700) * 0.5f); + if ((this->instanceId % 2) == 0) { + this->targetYaw += + (this->instanceId * 0x700) + (s32)randPlusMinusPoint5Scaled((this->instanceId * 0x700) * 0.5f); } else { - this->unk_20C -= (this->unk_218 * 0x700) + (s32)randPlusMinusPoint5Scaled((this->unk_218 * 0x700) * 0.5f); + this->targetYaw -= + (this->instanceId * 0x700) + (s32)randPlusMinusPoint5Scaled((this->instanceId * 0x700) * 0.5f); } - this->unk_210 += (s32)randPlusMinusPoint5Scaled(500.0f) + 1000; + this->flightHoverOffset += (s32)randPlusMinusPoint5Scaled(500.0f) + 1000; - if (this->unk_20C > 0x10000) { - this->unk_20C = 0; - this->unk_214++; - this->unk_214 &= 1; + if (this->targetYaw > 0x10000) { + this->targetYaw = 0; + this->posIndex++; + this->posIndex &= 1; } - Math_SmoothStepToS(&this->actor.world.rot.y, Math_Vec3f_Yaw(&this->actor.world.pos, &sp88), 1, 0x1388, 0); - Math_ApproachF(&this->actor.world.pos.y, sp88.y, 0.3f, 3.0f); + Math_SmoothStepToS(&this->actor.world.rot.y, Math_Vec3f_Yaw(&this->actor.world.pos, &nextPos), 1, 0x1388, 0); + Math_ApproachF(&this->actor.world.pos.y, nextPos.y, 0.3f, 3.0f); Math_ApproachF(&this->actor.speedXZ, 5.0f, 0.3f, 1.0f); } -void func_80B5AF80(EnBee* this, PlayState* play) { - if ((this->unk_206 == 0) && (this->collider.base.atFlags & AC_HIT)) { +void EnBee_UpdateDamage(EnBee* this, PlayState* play) { + if ((this->sfxHitTimer == 0) && (this->collider.base.atFlags & AT_HIT)) { AudioSfx_StopByPosAndId(&this->actor.projectedPos, NA_SE_EN_BEE_FLY - SFX_FLAG); - this->unk_206 = 5; + this->sfxHitTimer = 5; } if (this->collider.base.acFlags & AC_HIT) { @@ -253,16 +254,16 @@ void EnBee_Update(Actor* thisx, PlayState* play) { SkelAnime_Update(&this->skelAnime); if (this->actor.category == ACTORCAT_ENEMY) { - if (this->unk_204 != 0) { - this->unk_204--; + if (this->attackDelayTimer != 0) { + this->attackDelayTimer--; } - if (this->unk_206 != 0) { - this->unk_206--; + if (this->sfxHitTimer != 0) { + this->sfxHitTimer--; } } Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BEE_FLY - SFX_FLAG); - func_80B5AF80(this, play); + EnBee_UpdateDamage(this, play); Math_Vec3s_Copy(&this->actor.shape.rot, &this->actor.world.rot); Actor_SetFocus(&this->actor, 0.0f); Actor_SetScale(&this->actor, 0.01f); diff --git a/src/overlays/actors/ovl_En_Bee/z_en_bee.h b/src/overlays/actors/ovl_En_Bee/z_en_bee.h index 1638407ee..851a0a216 100644 --- a/src/overlays/actors/ovl_En_Bee/z_en_bee.h +++ b/src/overlays/actors/ovl_En_Bee/z_en_bee.h @@ -8,20 +8,25 @@ struct EnBee; typedef void (*EnBeeActionFunc)(struct EnBee*, PlayState*); +typedef enum { + /* 0 */ BEE_BEHAVIOR_IDLE = 0, + /* 1 */ BEE_BEHAVIOR_ATTACK, +} BeeBehaviorType; + typedef struct EnBee { /* 0x000 */ Actor actor; /* 0x144 */ SkelAnime skelAnime; /* 0x188 */ Vec3s morphTable[OBJECT_BEE_LIMB_MAX]; /* 0x1C4 */ Vec3s jointTable[OBJECT_BEE_LIMB_MAX]; /* 0x200 */ EnBeeActionFunc actionFunc; - /* 0x204 */ s16 unk_204; - /* 0x206 */ s16 unk_206; - /* 0x208 */ s16 unk_208; - /* 0x20C */ s32 unk_20C; - /* 0x210 */ s32 unk_210; - /* 0x214 */ s32 unk_214; - /* 0x218 */ s32 unk_218; - /* 0x21C */ Vec3f unk_21C[2]; + /* 0x204 */ s16 attackDelayTimer; + /* 0x206 */ s16 sfxHitTimer; + /* 0x208 */ s16 isHostile; // set and not used + /* 0x20C */ s32 targetYaw; + /* 0x210 */ s32 flightHoverOffset; + /* 0x214 */ s32 posIndex; + /* 0x218 */ s32 instanceId; + /* 0x21C */ Vec3f targetPos[2]; /* 0x234 */ UNK_TYPE1 pad234[8]; /* 0x23C */ ColliderCylinder collider; } EnBee; // size = 0x288 diff --git a/src/overlays/actors/ovl_En_Stone_heishi/z_en_stone_heishi.c b/src/overlays/actors/ovl_En_Stone_heishi/z_en_stone_heishi.c index fe4882947..121d73c51 100644 --- a/src/overlays/actors/ovl_En_Stone_heishi/z_en_stone_heishi.c +++ b/src/overlays/actors/ovl_En_Stone_heishi/z_en_stone_heishi.c @@ -17,12 +17,16 @@ void EnStoneheishi_Draw(Actor* thisx, PlayState* play); void func_80BC9560(EnStoneheishi* this, PlayState* play); void func_80BC9680(EnStoneheishi* this, PlayState* play); -void func_80BC9908(EnStoneheishi* this, PlayState* play); -void func_80BC9A2C(EnStoneheishi* this, PlayState* play); +void EnStoneheishi_CheckGivenItem(EnStoneheishi* this, PlayState* play); +void EnStoneheishi_DrinkBottleProcess(EnStoneheishi* this, PlayState* play); void func_80BC9D28(EnStoneheishi* this, PlayState* play); void func_80BC9E50(EnStoneheishi* this, PlayState* play); +void func_80BC94B0(EnStoneheishi* this); +void func_80BC9660(EnStoneheishi* this); +void EnStoneheishi_SetupCheckGivenItem(EnStoneheishi*); +void EnStoneheishi_GiveItemReward(EnStoneheishi* this, PlayState* play); +void EnStoneheishi_SetupDrinkBottleProcess(EnStoneheishi* this); -#if 0 const ActorInit En_Stone_heishi_InitVars = { ACTOR_EN_STONE_HEISHI, ACTORCAT_NPC, @@ -35,54 +39,496 @@ const ActorInit En_Stone_heishi_InitVars = { (ActorFunc)EnStoneheishi_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80BCA3A0 = { - { COLTYPE_NONE, AT_NONE, AC_NONE, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_NONE, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 15, 70, 0, { 0, 0, 0 } }, }; -#endif +static u16 sEnStoneHeishiTextIds[] = { 0x1473, 0x1474, 0x1475, 0x1476, 0x1477, 0x1478, 0x1479, 0x147A, 0x1472 }; -extern ColliderCylinderInit D_80BCA3A0; +static AnimationHeader* sAnimations[] = { + &gSoldierStandHandOnHip, &gSoldierDrink, &gSoldierCheerWithSpear, &gSoldierWave, + &gSoldierSitAndReach, &gSoldierDrink, &gSoldierStandUp, +}; -extern UNK_TYPE D_06000768; -extern UNK_TYPE D_06003BFC; +static u8 sAnimationModes[] = { + ANIMMODE_LOOP, ANIMMODE_ONCE, ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_ONCE, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Stone_heishi/EnStoneheishi_Init.s") +typedef enum { + /* 0 */ EN_STONE_ACTION_0, + /* 1 */ EN_STONE_ACTION_1, + /* 2 */ EN_STONE_ACTION_CHECK_ITEM, + /* 3 */ EN_STONE_ACTION_DRINK_BOTTLE, + /* 4 */ EN_STONE_ACTION_4 +} EnStoneHeishiAction; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Stone_heishi/EnStoneheishi_Destroy.s") +typedef enum { + /* 0 */ EN_STONE_DRINK_BOTTLE_INITIAL, + /* 1 */ EN_STONE_DRINK_BOTTLE_DRINKING, + /* 2 */ EN_STONE_DRINK_BOTTLE_EMPTY, + /* 3 */ EN_STONE_DRINK_BOTTLE_STAND_UP, + /* 4 */ EN_STONE_DRINK_BOTTLE_STANDING +} EnStoneHeishiDrinkBottle; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Stone_heishi/func_80BC935C.s") +typedef enum { + /* 0 */ EN_STONE_BOTTLE_NONE, + /* 1 */ EN_STONE_BOTTLE_RED_POTION, + /* 2 */ EN_STONE_BOTTLE_EMPTY, + /* 3 */ EN_STONE_BOTTLE_BLUE_POTION, +} EnStoneHeishiBottle; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Stone_heishi/func_80BC941C.s") +typedef enum { + /* 0 */ EN_STONE_HEISHI_ANIM_STAND_HAND_ON_HIP, + /* 1 */ EN_STONE_HEISHI_ANIM_DRINK_1, + /* 2 */ EN_STONE_HEISHI_ANIM_CHEER_WITH_SPEAR, + /* 3 */ EN_STONE_HEISHI_ANIM_WAVE, + /* 4 */ EN_STONE_HEISHI_ANIM_SIT_AND_REACH, + /* 5 */ EN_STONE_HEISHI_ANIM_DRINK_2, + /* 6 */ EN_STONE_HEISHI_ANIM_STAND_UP, +} EnStoneHeishiAnimations; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Stone_heishi/func_80BC94B0.s") +void EnStoneheishi_Init(Actor* thisx, PlayState* play) { + EnStoneheishi* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Stone_heishi/func_80BC9560.s") + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 25.0f); + SkelAnime_InitFlex(play, &this->skelAnime, &gSoldierSkel, &gSoldierWave, this->jointTable, this->morphTable, + SOLDIER_LIMB_MAX); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Stone_heishi/func_80BC9660.s") + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + this->actor.targetMode = 6; + this->actor.gravity = -3.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Stone_heishi/func_80BC9680.s") + Collider_InitAndSetCylinder(play, &this->collider, &this->actor, &sCylinderInit); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Stone_heishi/func_80BC98EC.s") + this->collider.dim.radius = 40; + this->collider.dim.height = 40; + this->collider.dim.yShift = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Stone_heishi/func_80BC9908.s") + func_80BC94B0(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Stone_heishi/func_80BC9A10.s") +void EnStoneheishi_Destroy(Actor* thisx, PlayState* play) { + EnStoneheishi* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Stone_heishi/func_80BC9A2C.s") + Collider_DestroyCylinder(play, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Stone_heishi/func_80BC9C88.s") +void EnStoneheishi_ChangeAnim(EnStoneheishi* this, s32 animIndex) { + f32 startFrame = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Stone_heishi/func_80BC9D28.s") + this->animIndex = animIndex; + this->endFrame = Animation_GetLastFrame(sAnimations[animIndex]); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Stone_heishi/func_80BC9E50.s") + // This will never pass since this animation index is never used. + if (animIndex == EN_STONE_HEISHI_ANIM_DRINK_2) { + startFrame = 55.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Stone_heishi/EnStoneheishi_Update.s") + Animation_Change(&this->skelAnime, sAnimations[this->animIndex], 1.0f, startFrame, this->endFrame, + sAnimationModes[this->animIndex], -10.0f); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Stone_heishi/func_80BCA0AC.s") +void EnStoneheishi_TrackPlayer(EnStoneheishi* this) { + s32 yawDiff = ABS_ALT((s16)(this->actor.yawTowardsPlayer - this->actor.world.rot.y)); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Stone_heishi/func_80BCA104.s") + this->targetHeadRot.y = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Stone_heishi/EnStoneheishi_Draw.s") + if ((this->actor.xzDistToPlayer < 200.0f) && (yawDiff < 0x4E20)) { + this->targetHeadRot.y = this->actor.yawTowardsPlayer - this->actor.world.rot.y; + if (this->targetHeadRot.y > 0x2710) { + this->targetHeadRot.y = 0x2710; + } else if (this->targetHeadRot.y < -0x2710) { + this->targetHeadRot.y = -0x2710; + } + } +} + +void func_80BC94B0(EnStoneheishi* this) { + this->textIdIndex = 0; + if (gSaveContext.save.weekEventReg[41] & 0x40) { // After drinking bottle + EnStoneheishi_ChangeAnim(this, EN_STONE_HEISHI_ANIM_CHEER_WITH_SPEAR); + this->textIdIndex = 8; + this->actor.flags &= ~ACTOR_FLAG_80; + } else { // Initial configuration + EnStoneheishi_ChangeAnim(this, EN_STONE_HEISHI_ANIM_WAVE); + if (gSaveContext.save.weekEventReg[41] & 0x80) { + this->textIdIndex = 2; + } + } + this->actor.textId = sEnStoneHeishiTextIds[this->textIdIndex]; + this->action = EN_STONE_ACTION_0; + this->actionFunc = func_80BC9560; +} + +void func_80BC9560(EnStoneheishi* this, PlayState* play) { + Player* player = GET_PLAYER(play); + s32 yawDiff; + + if (Actor_ProcessTalkRequest(&this->actor, &play->state)) { + func_80BC9660(this); + return; + } + + if (!(gSaveContext.save.weekEventReg[41] & 0x40) && (play->actorCtx.lensMaskSize != 100)) { + this->actor.flags |= ACTOR_FLAG_8000000; + return; + } + + SkelAnime_Update(&this->skelAnime); + + this->actor.flags &= ~ACTOR_FLAG_8000000; + + yawDiff = ABS_ALT((s16)(this->actor.yawTowardsPlayer - this->actor.world.rot.y)); + + if ((yawDiff <= 0x18F0) && !(player->stateFlags1 & PLAYER_STATE1_800000)) { + func_800B8614(&this->actor, play, 70.0f); + } +} + +void func_80BC9660(EnStoneheishi* this) { + this->textIdSet = false; + this->action = EN_STONE_ACTION_1; + this->actionFunc = func_80BC9680; +} + +void func_80BC9680(EnStoneheishi* this, PlayState* play) { + f32 currentFrame = this->skelAnime.curFrame; + + if ((this->textIdIndex == 0) || (this->textIdIndex == 2)) { + if (this->animIndex != EN_STONE_HEISHI_ANIM_SIT_AND_REACH) { + if (fabsf(this->headRot.x - this->targetHeadRot.x) < 50.0f) { + EnStoneheishi_ChangeAnim(this, EN_STONE_HEISHI_ANIM_SIT_AND_REACH); + } + return; + } + } else if (this->textIdIndex == 3) { + if (this->animIndex != EN_STONE_HEISHI_ANIM_WAVE) { + if ((this->timer == 0) && (fabsf(this->headRot.x - this->targetHeadRot.x) < 50.0f)) { + EnStoneheishi_ChangeAnim(this, EN_STONE_HEISHI_ANIM_WAVE); + } + return; + } else if (!this->textIdSet && (this->endFrame <= currentFrame)) { + Player* player = GET_PLAYER(play); + + this->textIdSet = true; + player->actor.textId = sEnStoneHeishiTextIds[this->textIdIndex]; + + func_80151938(play, sEnStoneHeishiTextIds[this->textIdIndex]); + func_80151BB4(play, 0x12); + } + } + + SkelAnime_Update(&this->skelAnime); + + if ((Message_GetState(&play->msgCtx) == TEXT_STATE_5) && Message_ShouldAdvance(play)) { + func_801477B4(play); + + if (this->textIdIndex == 2) { + func_80151938(play, 0xFF); + EnStoneheishi_SetupCheckGivenItem(this); + } else if (this->textIdIndex == 3) { + func_80BC94B0(this); + } else if (this->textIdIndex == 6) { + EnStoneheishi_GiveItemReward(this, play); + } else { + if (this->textIdIndex < 7) { + this->textIdIndex++; + } else { + func_80151BB4(play, 0x12); + func_80BC94B0(this); + return; + } + func_80151938(play, sEnStoneHeishiTextIds[this->textIdIndex]); + } + } +} + +void EnStoneheishi_SetupCheckGivenItem(EnStoneheishi* this) { + this->action = EN_STONE_ACTION_CHECK_ITEM; + this->actionFunc = EnStoneheishi_CheckGivenItem; +} + +void EnStoneheishi_CheckGivenItem(EnStoneheishi* this, PlayState* play) { + s32 itemActionParam; + + SkelAnime_Update(&this->skelAnime); + + if (Message_GetState(&play->msgCtx) == TEXT_STATE_16) { + itemActionParam = func_80123810(play); + if (itemActionParam > PLAYER_AP_NONE) { + this->timer = 40; + func_801477B4(play); + + if ((itemActionParam == PLAYER_AP_BOTTLE_POTION_RED) || (itemActionParam == PLAYER_AP_BOTTLE_POTION_BLUE)) { + this->playerGivesBluePotion = false; + if (itemActionParam == PLAYER_AP_BOTTLE_POTION_BLUE) { + this->playerGivesBluePotion = true; + } + EnStoneheishi_SetupDrinkBottleProcess(this); + } else { + Player* player = GET_PLAYER(play); + + this->textIdIndex = 3; + player->actor.textId = 0; + gSaveContext.save.weekEventReg[41] |= 0x80; + this->action = EN_STONE_ACTION_1; + this->actionFunc = func_80BC9680; + } + } else if (itemActionParam < PLAYER_AP_NONE) { + func_801477B4(play); + func_80151BB4(play, 0x12); + func_80BC94B0(this); + } + } +} + +void EnStoneheishi_SetupDrinkBottleProcess(EnStoneheishi* this) { + this->action = EN_STONE_ACTION_DRINK_BOTTLE; + this->actionFunc = EnStoneheishi_DrinkBottleProcess; +} + +void EnStoneheishi_DrinkBottleProcess(EnStoneheishi* this, PlayState* play) { + f32 currentFrame = this->skelAnime.curFrame; + Player* player = GET_PLAYER(play); + + SkelAnime_Update(&this->skelAnime); + + switch (this->drinkBottleState) { + case EN_STONE_DRINK_BOTTLE_INITIAL: + if (this->timer == 0) { + this->textIdIndex = 4; + func_80151938(play, sEnStoneHeishiTextIds[this->textIdIndex]); + player->actor.textId = sEnStoneHeishiTextIds[this->textIdIndex]; + this->drinkBottleState++; + } + + default: + break; + + case EN_STONE_DRINK_BOTTLE_DRINKING: + if ((Message_GetState(&play->msgCtx) == TEXT_STATE_5) && Message_ShouldAdvance(play)) { + Player* player = GET_PLAYER(play); + + play->msgCtx.msgLength = 0; + player->actor.textId = 0; + player->exchangeItemId = PLAYER_AP_NONE; + this->bottleDisplay = EN_STONE_BOTTLE_RED_POTION; + + if (this->playerGivesBluePotion) { + this->bottleDisplay = EN_STONE_BOTTLE_BLUE_POTION; + } + + Player_SetModels(player, 3); + EnStoneheishi_ChangeAnim(this, EN_STONE_HEISHI_ANIM_DRINK_1); + this->timer = 30; + this->drinkBottleState++; + } + break; + + case EN_STONE_DRINK_BOTTLE_EMPTY: + if (this->timer != 0) { + if ((this->timer < 10) && (this->bottleDisplay != EN_STONE_BOTTLE_EMPTY)) { + this->bottleDisplay = EN_STONE_BOTTLE_EMPTY; + Actor_PlaySfxAtPos(&this->actor, NA_SE_VO_NP_DRINK); + func_80123D50(play, GET_PLAYER(play), ITEM_BOTTLE, PLAYER_AP_BOTTLE); + } + } else { + this->drinkBottleState++; + } + break; + + case EN_STONE_DRINK_BOTTLE_STAND_UP: + if (this->endFrame <= currentFrame) { + Audio_PlayFanfare(NA_BGM_GET_ITEM | 0x900); + this->bottleDisplay = EN_STONE_BOTTLE_NONE; + EnStoneheishi_ChangeAnim(this, EN_STONE_HEISHI_ANIM_STAND_UP); + this->drinkBottleState++; + } + break; + + case EN_STONE_DRINK_BOTTLE_STANDING: + if (this->endFrame <= currentFrame) { + this->textIdIndex = 5; + func_80151938(play, sEnStoneHeishiTextIds[this->textIdIndex]); + player->actor.textId = sEnStoneHeishiTextIds[this->textIdIndex]; + EnStoneheishi_ChangeAnim(this, EN_STONE_HEISHI_ANIM_STAND_HAND_ON_HIP); + this->action = EN_STONE_ACTION_1; + this->actionFunc = func_80BC9680; + } + break; + } +} + +void EnStoneheishi_GiveItemReward(EnStoneheishi* this, PlayState* play) { + func_801477B4(play); + + if (INV_CONTENT(ITEM_MASK_STONE) == ITEM_MASK_STONE) { + Actor_PickUp(&this->actor, play, GI_RUPEE_BLUE, 300.0f, 300.0f); + } else { + Actor_PickUp(&this->actor, play, GI_MASK_STONE, 300.0f, 300.0f); + } + + this->action = EN_STONE_ACTION_4; + this->actionFunc = func_80BC9D28; +} + +void func_80BC9D28(EnStoneheishi* this, PlayState* play) { + SkelAnime_Update(&this->skelAnime); + + if (Actor_HasParent(&this->actor, play)) { + this->actor.parent = NULL; + this->textIdIndex++; + this->actor.textId = sEnStoneHeishiTextIds[this->textIdIndex]; + gSaveContext.save.weekEventReg[41] |= 0x40; + Actor_ProcessTalkRequest(&this->actor, &play->state); + func_800B8500(&this->actor, play, 400.0f, 400.0f, PLAYER_AP_MINUS1); + this->actionFunc = func_80BC9E50; + } else if (INV_CONTENT(ITEM_MASK_STONE) == ITEM_MASK_STONE) { + Actor_PickUp(&this->actor, play, GI_RUPEE_BLUE, 300.0f, 300.0f); + } else { + Actor_PickUp(&this->actor, play, GI_MASK_STONE, 300.0f, 300.0f); + } +} + +void func_80BC9E50(EnStoneheishi* this, PlayState* play) { + SkelAnime_Update(&this->skelAnime); + + if (Actor_ProcessTalkRequest(&this->actor, &play->state)) { + func_80151BB4(play, 0x35); + func_80151BB4(play, 0x12); + this->action = EN_STONE_ACTION_1; + this->actionFunc = func_80BC9680; + } else { + func_800B8500(&this->actor, play, 400.0f, 400.0f, PLAYER_AP_MINUS1); + } +} + +void EnStoneheishi_Update(Actor* thisx, PlayState* play) { + s32 pad; + EnStoneheishi* this = THIS; + Player* player = GET_PLAYER(play); + + if (this->timer != 0) { + this->timer--; + } + + this->actor.shape.rot.y = this->actor.world.rot.y; + this->actionFunc(this, play); + + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(play, &this->actor, 20.0f, 20.0f, 50.0f, 0x1D); + Actor_SetScale(&this->actor, 0.01f); + + if (((gSaveContext.save.weekEventReg[41] & 0x40) || (play->actorCtx.lensMaskSize == 100)) && + !(player->stateFlags1 & PLAYER_STATE1_800000)) { + if ((this->animIndex != EN_STONE_HEISHI_ANIM_WAVE) && + ((((this->action == EN_STONE_ACTION_0) || (this->action == EN_STONE_ACTION_1)) || + (this->action == EN_STONE_ACTION_CHECK_ITEM)) || + ((this->action == EN_STONE_ACTION_DRINK_BOTTLE) && + (this->drinkBottleState <= EN_STONE_DRINK_BOTTLE_DRINKING)))) { + EnStoneheishi_TrackPlayer(this); + } else { + this->targetHeadRot.y = 0; + } + + if (!(gSaveContext.save.weekEventReg[41] & 0x40)) { + Actor_SetFocus(&this->actor, 30.0f); + } else { + Actor_SetFocus(&this->actor, 60.0f); + } + + Math_SmoothStepToS(&this->headRot.y, this->targetHeadRot.y, 1, 0xBB8, 0); + Math_SmoothStepToS(&this->headRot.x, this->targetHeadRot.x, 1, 0x3E8, 0); + + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); + } +} + +s32 EnStoneheishi_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx, + Gfx** gfxp) { + EnStoneheishi* this = THIS; + + if (limbIndex == SOLDIER_LIMB_HEAD) { + rot->x += this->headRot.y; + rot->y += this->headRot.x; + rot->z += this->headRot.z; + } + + return false; +} + +void EnStoneheishi_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx, Gfx** gfxp) { + static Vec3f sLeftHandPos = { 0.0f, 0.0f, 0.0f }; + EnStoneheishi* this = THIS; + Gfx* gfx; + + if ((limbIndex == SOLDIER_LIMB_LEFT_HAND) && (this->bottleDisplay != EN_STONE_BOTTLE_NONE)) { + gfx = func_8012C2B4(*gfxp); + + sLeftHandPos.x = 320.0f; + sLeftHandPos.y = 210.0f; + sLeftHandPos.z = 440.0f; + + Matrix_Translate(sLeftHandPos.x, sLeftHandPos.y, sLeftHandPos.z, MTXMODE_APPLY); + + gDPPipeSync(gfx++); + + Matrix_RotateYS(-0x1770, MTXMODE_APPLY); + Matrix_RotateXS(0x7D0, MTXMODE_APPLY); + Matrix_RotateZS(-0x7530, MTXMODE_APPLY); + + if (this->bottleDisplay != EN_STONE_BOTTLE_EMPTY) { + if (this->bottleDisplay == EN_STONE_BOTTLE_BLUE_POTION) { + gDPSetEnvColor(gfx++, 0, 0, 200, 0); // Blue Potion + } else { + gDPSetEnvColor(gfx++, 200, 0, 0, 0); // Red Potion + } + gSPMatrix(gfx++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(gfx++, gSoldierBottleContentsDL); + } + + gSPMatrix(gfx++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(gfx++, gSoldierBottleDL); + + *gfxp = gfx++; + } +} + +void EnStoneheishi_Draw(Actor* thisx, PlayState* play) { + EnStoneheishi* this = THIS; + + OPEN_DISPS(play->state.gfxCtx); + + if (!(gSaveContext.save.weekEventReg[41] & 0x40)) { + func_8012C2DC(play->state.gfxCtx); + + POLY_XLU_DISP = + SkelAnime_DrawFlex(play, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnStoneheishi_OverrideLimbDraw, EnStoneheishi_PostLimbDraw, &this->actor, POLY_XLU_DISP); + } else { + func_8012C28C(play->state.gfxCtx); + + POLY_OPA_DISP = + SkelAnime_DrawFlex(play, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnStoneheishi_OverrideLimbDraw, EnStoneheishi_PostLimbDraw, &this->actor, POLY_OPA_DISP); + } + + CLOSE_DISPS(play->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Stone_heishi/z_en_stone_heishi.h b/src/overlays/actors/ovl_En_Stone_heishi/z_en_stone_heishi.h index f4eb8e5f2..7b09d32bb 100644 --- a/src/overlays/actors/ovl_En_Stone_heishi/z_en_stone_heishi.h +++ b/src/overlays/actors/ovl_En_Stone_heishi/z_en_stone_heishi.h @@ -2,6 +2,7 @@ #define Z_EN_STONE_HEISHI_H #include "global.h" +#include "assets/objects/object_sdn/object_sdn.h" struct EnStoneheishi; @@ -9,9 +10,22 @@ typedef void (*EnStoneheishiActionFunc)(struct EnStoneheishi*, PlayState*); typedef struct EnStoneheishi { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x110]; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ Vec3s jointTable[SOLDIER_LIMB_MAX]; + /* 0x1EE */ Vec3s morphTable[SOLDIER_LIMB_MAX]; /* 0x254 */ EnStoneheishiActionFunc actionFunc; - /* 0x258 */ char unk_258[0x6C]; + /* 0x258 */ Vec3s headRot; + /* 0x25E */ Vec3s targetHeadRot; + /* 0x264 */ s32 animIndex; + /* 0x268 */ s16 timer; + /* 0x26A */ s16 drinkBottleState; + /* 0x26C */ f32 endFrame; + /* 0x270 */ s16 action; + /* 0x272 */ s16 textIdIndex; + /* 0x274 */ s16 textIdSet; + /* 0x276 */ u8 bottleDisplay; + /* 0x277 */ u8 playerGivesBluePotion; + /* 0x278 */ ColliderCylinder collider; } EnStoneheishi; // size = 0x2C4 extern const ActorInit En_Stone_heishi_InitVars; diff --git a/src/overlays/actors/ovl_En_Tanron1/z_en_tanron1.c b/src/overlays/actors/ovl_En_Tanron1/z_en_tanron1.c index d45cc854c..fbc74cb10 100644 --- a/src/overlays/actors/ovl_En_Tanron1/z_en_tanron1.c +++ b/src/overlays/actors/ovl_En_Tanron1/z_en_tanron1.c @@ -406,6 +406,8 @@ void func_80BB5AAC(EnTanron1* this, PlayState* play) { Matrix_RotateXS(ptr->unk_18 * -1, MTXMODE_APPLY); Matrix_Scale(1.0f, ptr->unk_2C, 1.0f, MTXMODE_APPLY); + if (1) {} + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_OPA_DISP++, ovl_En_Tanron1_DL_001900); } diff --git a/src/overlays/actors/ovl_Obj_Hgdoor/z_obj_hgdoor.c b/src/overlays/actors/ovl_Obj_Hgdoor/z_obj_hgdoor.c index 72aaa3e12..ae528e3ea 100644 --- a/src/overlays/actors/ovl_Obj_Hgdoor/z_obj_hgdoor.c +++ b/src/overlays/actors/ovl_Obj_Hgdoor/z_obj_hgdoor.c @@ -16,15 +16,15 @@ void ObjHgdoor_Destroy(Actor* thisx, PlayState* play); void ObjHgdoor_Update(Actor* thisx, PlayState* play); void ObjHgdoor_Draw(Actor* thisx, PlayState* play); -void ObjHgdoor_SetupCheckShouldOpen(ObjHgdoor* this); -void ObjHgdoor_CheckShouldOpen(ObjHgdoor* this, PlayState* play); -void func_80BD42AC(ObjHgdoor* this); -void func_80BD42C0(ObjHgdoor* this, PlayState* play); -void func_80BD433C(ObjHgdoor* this); -void func_80BD4358(ObjHgdoor* this, PlayState* play); -void func_80BD4460(ObjHgdoor* this); -void func_80BD4478(ObjHgdoor* this, PlayState* play); -s32 func_80BD44D0(ObjHgdoor* this, PlayState* play); +void ObjHgdoor_SetupIdle(ObjHgdoor* this); +void ObjHgdoor_Idle(ObjHgdoor* this, PlayState* play); +void ObjHgdoor_SetupCutscene(ObjHgdoor* this); +void ObjHgdoor_PlayCutscene(ObjHgdoor* this, PlayState* play); +void ObjHgdoor_SetupCsAction(ObjHgdoor* this); +void ObjHgdoor_HandleCsAction(ObjHgdoor* this, PlayState* play); +void ObjHgdoor_SetupStopCs(ObjHgdoor* this); +void ObjHgdoor_StopCs(ObjHgdoor* this, PlayState* play); +s32 ObjHgdoor_Rotate(ObjHgdoor* this, PlayState* play); const ActorInit Obj_Hgdoor_InitVars = { ACTOR_OBJ_HGDOOR, @@ -38,9 +38,7 @@ const ActorInit Obj_Hgdoor_InitVars = { (ActorFunc)ObjHgdoor_Draw, }; -static s16 D_80BD4690 = 0; -static s32 unused = 0; -static s32 unused2 = 0; +static s16 sOpenFlag = 0; void ObjHgdoor_SetChild(ObjHgdoor* this, PlayState* play) { Actor* actorIterator = play->actorCtx.actorLists[ACTORCAT_PROP].first; @@ -82,7 +80,7 @@ void ObjHgdoor_Init(Actor* thisx, PlayState* play) { this->rotation = 0; this->timer = 0; this->cutscene = this->dyna.actor.cutscene; - ObjHgdoor_SetupCheckShouldOpen(this); + ObjHgdoor_SetupIdle(this); } void ObjHgdoor_Destroy(Actor* thisx, PlayState* play) { @@ -91,29 +89,29 @@ void ObjHgdoor_Destroy(Actor* thisx, PlayState* play) { DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, this->dyna.bgId); } -void ObjHgdoor_SetupCheckShouldOpen(ObjHgdoor* this) { - this->actionFunc = ObjHgdoor_CheckShouldOpen; +void ObjHgdoor_SetupIdle(ObjHgdoor* this) { + this->actionFunc = ObjHgdoor_Idle; } -void ObjHgdoor_CheckShouldOpen(ObjHgdoor* this, PlayState* play) { +void ObjHgdoor_Idle(ObjHgdoor* this, PlayState* play) { if (!(gSaveContext.save.weekEventReg[75] & 0x20) && !(gSaveContext.save.weekEventReg[52] & 0x20) && (this->dyna.actor.xzDistToPlayer < 100.0f) && (this->dyna.actor.playerHeightRel < 40.0f) && OBJHGDOOR_IS_RIGHT_DOOR(&this->dyna.actor)) { ObjHgdoor_SetChild(this, play); ObjHgdoor_SetParent(this, play); - func_80BD42AC(this); + ObjHgdoor_SetupCutscene(this); } } -void func_80BD42AC(ObjHgdoor* this) { - this->actionFunc = func_80BD42C0; +void ObjHgdoor_SetupCutscene(ObjHgdoor* this) { + this->actionFunc = ObjHgdoor_PlayCutscene; } -void func_80BD42C0(ObjHgdoor* this, PlayState* play) { +void ObjHgdoor_PlayCutscene(ObjHgdoor* this, PlayState* play) { if (ActorCutscene_GetCanPlayNext(this->cutscene)) { ActorCutscene_Start(this->cutscene, &this->dyna.actor); - func_80BD433C(this); - func_80BD433C((ObjHgdoor*)this->dyna.actor.child); + ObjHgdoor_SetupCsAction(this); + ObjHgdoor_SetupCsAction((ObjHgdoor*)this->dyna.actor.child); } else { if (ActorCutscene_GetCurrentIndex() == 0x7C) { ActorCutscene_Stop(0x7C); @@ -122,50 +120,58 @@ void func_80BD42C0(ObjHgdoor* this, PlayState* play) { } } -void func_80BD433C(ObjHgdoor* this) { - this->unk166 = 0x63; - this->actionFunc = func_80BD4358; +void ObjHgdoor_SetupCsAction(ObjHgdoor* this) { + this->csAction = 0x63; + this->actionFunc = ObjHgdoor_HandleCsAction; } -void func_80BD4358(ObjHgdoor* this, PlayState* play) { +void ObjHgdoor_HandleCsAction(ObjHgdoor* this, PlayState* play) { s32 actionIndex; if (Cutscene_CheckActorAction(play, 483)) { actionIndex = Cutscene_GetActorActionIndex(play, 483); - if (this->unk166 != play->csCtx.actorActions[actionIndex]->action) { - this->unk166 = play->csCtx.actorActions[actionIndex]->action; + if (this->csAction != play->csCtx.actorActions[actionIndex]->action) { + this->csAction = play->csCtx.actorActions[actionIndex]->action; switch (play->csCtx.actorActions[actionIndex]->action) { case 1: Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_WOOD_DOOR_OPEN_SPEEDY); if ((this->dyna.actor.parent != NULL) && (this->dyna.actor.parent->id == ACTOR_EN_HG)) { this->dyna.actor.parent->colChkInfo.health = 1; } - D_80BD4690 = 1; + sOpenFlag = 1; break; + case 2: break; } } - if ((D_80BD4690 == 1) && (func_80BD44D0(this, play))) { - func_80BD4460(this); + if ((sOpenFlag == 1) && ObjHgdoor_Rotate(this, play)) { + ObjHgdoor_SetupStopCs(this); } } else { - this->unk166 = 0x63; + this->csAction = 0x63; } } -void func_80BD4460(ObjHgdoor* this) { +void ObjHgdoor_SetupStopCs(ObjHgdoor* this) { this->timer = 0; - this->actionFunc = func_80BD4478; + this->actionFunc = ObjHgdoor_StopCs; } -void func_80BD4478(ObjHgdoor* this, PlayState* play) { - if (this->timer++ > 80 && !ActorCutscene_GetCanPlayNext(this->cutscene)) { - ActorCutscene_Stop(this->cutscene); +void ObjHgdoor_StopCs(ObjHgdoor* this, PlayState* play) { + if (this->timer++ > 80) { + if (!ActorCutscene_GetCanPlayNext(this->cutscene)) { + ActorCutscene_Stop(this->cutscene); + } } } -s32 func_80BD44D0(ObjHgdoor* this, PlayState* play) { +/** + * @brief Function to increment the rotation angle of the door + * + * @return true when door is fully open, false otherwise + */ +s32 ObjHgdoor_Rotate(ObjHgdoor* this, PlayState* play) { if (this->rotation < 0x5555) { this->rotation += 0x1388; } else { @@ -175,7 +181,7 @@ s32 func_80BD44D0(ObjHgdoor* this, PlayState* play) { return false; } -void func_80BD4500(ObjHgdoor* this) { +void ObjHgdoor_Open(ObjHgdoor* this) { this->dyna.actor.shape.rot.y = this->dyna.actor.home.rot.y; if (OBJHGDOOR_IS_RIGHT_DOOR(&this->dyna.actor)) { this->dyna.actor.shape.rot.y += this->rotation; @@ -188,7 +194,7 @@ void ObjHgdoor_Update(Actor* thisx, PlayState* play) { ObjHgdoor* this = THIS; this->actionFunc(this, play); - func_80BD4500(this); + ObjHgdoor_Open(this); } void ObjHgdoor_Draw(Actor* thisx, PlayState* play) { diff --git a/src/overlays/actors/ovl_Obj_Hgdoor/z_obj_hgdoor.h b/src/overlays/actors/ovl_Obj_Hgdoor/z_obj_hgdoor.h index 803236ac1..3e0af9e8c 100644 --- a/src/overlays/actors/ovl_Obj_Hgdoor/z_obj_hgdoor.h +++ b/src/overlays/actors/ovl_Obj_Hgdoor/z_obj_hgdoor.h @@ -16,7 +16,7 @@ typedef struct ObjHgdoor { /* 0x160 */ s16 cutscene; /* 0x162 */ s16 rotation; /* 0x164 */ s16 timer; - /* 0x166 */ u16 unk166; + /* 0x166 */ u16 csAction; } ObjHgdoor; // size = 0x168 extern const ActorInit Obj_Hgdoor_InitVars; diff --git a/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_map.c b/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_map.c index 6e23e8f6f..5f4c136e0 100644 --- a/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_map.c +++ b/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_map.c @@ -1,108 +1,974 @@ /* * File: z_kaleido_map.c * Overlay: ovl_kaleido_scope - * Description: + * Description: Pause Menu: Map Page */ #include "z_kaleido_scope.h" +#include "interface/parameter_static/parameter_static.h" +#include "interface/icon_item_field_static/icon_item_field_static.h" +#include "interface/icon_item_dungeon_static/icon_item_dungeon_static.h" +#include "interface/icon_item_jpn_static/icon_item_jpn_static.h" -extern UNK_TYPE D_02001360; -extern UNK_TYPE D_020044A0; -extern UNK_TYPE D_02004AA0; -extern UNK_TYPE D_0200B998; -extern UNK_TYPE D_08062000; -extern UNK_TYPE D_08064340; -extern UNK_TYPE D_0B000000; -extern UNK_TYPE D_0C000000; -extern UNK_TYPE D_0C006C00; +extern s16 D_8082B7F0[]; +extern s16 D_8082B838[]; -s32 D_8082B4A0[] = { 0x09003600, 0x09003F00, 0x09004800 }; +extern TexturePtr D_09007500; // gPlayerFace -s32 D_8082B4AC[] = { - 0x0D000000, - 0x0D000800, - 0x0D001000, - 0x0D001800, +#define WORLD_MAP_IMAGE_TEX_WIDTH 216 +#define WORLD_MAP_IMAGE_TEX_HEIGHT 128 + +void KaleidoScope_DrawDungeonStrayFairyCount(PlayState* play) { + s16 counterDigits[2]; + s16 rectLeft; + s16 digitIndex; + + OPEN_DISPS(play->state.gfxCtx); + + // Get digits for max number of stray fairies + counterDigits[1] = 15; + counterDigits[0] = counterDigits[1] / 10; + counterDigits[1] -= (s16)(counterDigits[0] * 10); + + // Draw max number of stray fairies + for (rectLeft = 116, digitIndex = 0; digitIndex < 2; digitIndex++, rectLeft += 8) { + gDPPipeSync(POLY_OPA_DISP++); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 0, 0, 0, 255); + + POLY_OPA_DISP = func_8010D7D0(POLY_OPA_DISP, (u8*)gCounterDigit0Tex + (8 * 16 * counterDigits[digitIndex]), 8, + 16, rectLeft + 1, 146, 8, 16, 1 << 10, 1 << 10); + + gDPPipeSync(POLY_OPA_DISP++); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, 255); + + gSPTextureRectangle(POLY_OPA_DISP++, rectLeft * 4, 145 << 2, (rectLeft + 8) * 4, 161 << 2, G_TX_RENDERTILE, 0, + 0, 1 << 10, 1 << 10); + } + + // Draw Counter slash + gDPPipeSync(POLY_OPA_DISP++); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 0, 0, 0, 255); + + POLY_OPA_DISP = + func_8010D7D0(POLY_OPA_DISP, gStrayFairyMapCounterSlashTex, 8, 16, 107, 146, 8, 16, 1 << 10, 1 << 10); + + gDPPipeSync(POLY_OPA_DISP++); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, 255); + + gSPTextureRectangle(POLY_OPA_DISP++, 106 << 2, 145 << 2, 114 << 2, 161 << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, + 1 << 10); + + // Get digits for current number of stray fairies collected + counterDigits[1] = gSaveContext.save.inventory.strayFairies[(void)0, gSaveContext.dungeonIndex]; + counterDigits[0] = counterDigits[1] / 10; + counterDigits[1] -= (s16)(counterDigits[0] * 10); + + // Draw digits for current number of stray fairies collected + for (rectLeft = 88, digitIndex = 0; digitIndex < 2; digitIndex++, rectLeft += 8) { + gDPPipeSync(POLY_OPA_DISP++); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 0, 0, 0, 255); + + POLY_OPA_DISP = func_8010D7D0(POLY_OPA_DISP, (u8*)gCounterDigit0Tex + (8 * 16 * counterDigits[digitIndex]), 8, + 16, rectLeft + 1, 146, 8, 16, 1 << 10, 1 << 10); + + gDPPipeSync(POLY_OPA_DISP++); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, 255); + + gSPTextureRectangle(POLY_OPA_DISP++, rectLeft * 4, 145 << 2, (rectLeft + 8) * 4, 161 << 2, G_TX_RENDERTILE, 0, + 0, 1 << 10, 1 << 10); + } + + CLOSE_DISPS(play->state.gfxCtx); +} + +TexturePtr sDungeonItemTextures[] = { + 0x09003600, // `gBossKeyIconTex`: DUNGEON_BOSS_KEY + 0x09003F00, // `gCompassIconTex`: DUNGEON_COMPASS + 0x09004800, // `gDungeonMapIconTex`: DUNGEON_MAP }; -s16 D_8082B4BC[] = { - 0x0043, - 0x0051, - 0x005F, - 0x006D, +TexturePtr sDungeonTitleTextures[] = { + gPauseWoodfallTitleENGTex, // DUNGEON_INDEX_WOODFALL_TEMPLE + gPauseSnowheadTitleENGTex, // DUNGEON_INDEX_SNOWHEAD_TEMPLE + gPauseGreatBayTitleENGTex, // DUNGEON_INDEX_GREAT_BAY_TEMPLE + gPauseStoneTowerTitleENGTex, // DUNGEON_INDEX_STONE_TOWER_TEMPLE }; -s16 D_8082B4C4 = 0x7B; -s16 D_8082B4C8 = 30; -s16 D_8082B4CC = 0; -s16 D_8082B4D0 = 0xF; -s16 D_8082B4D4 = 0; -s16 D_8082B4D8 = 0xFF; -f32 D_8082B4DC = 100.0f; +s16 sDungeonMapFloorIconPosY[] = { 67, 81, 95, 109, 123 }; -s32 D_8082B4E0[] = { - 0x02008998, 0x0C001B80, 0x02008998, 0x0C001B80, 0x02009598, 0x0C002780, 0x02009598, 0x0C002780, - 0x0200A198, 0x0C003380, 0x0200A198, 0x0C003380, 0x0200AD98, 0x0C003F80, 0x0200AD98, 0x0C003F80, +void KaleidoScope_DrawDungeonMap(PlayState* play) { + static s16 sStrayFairyIconTimer = 30; + static s16 sStrayFairyIconIndex = 0; + static s16 sStrayFairyIconAlphaScaleTimer = 15; + static s16 sStrayFairyIconAlphaScaleState = 0; + static s16 sStrayFairyIconAlpha = 255; + static f32 sStrayFairyIconScale = 100.0f; + static TexturePtr sStrayFairyIconTextures[][4] = { + // DUNGEON_INDEX_WOODFALL_TEMPLE + { gStrayFairyWoodfallIconTex, gDungeonStrayFairyWoodfallIconTex, gStrayFairyWoodfallIconTex, + gDungeonStrayFairyWoodfallIconTex }, + // DUNGEON_INDEX_SNOWHEAD_TEMPLE + { gStrayFairySnowheadIconTex, gDungeonStrayFairySnowheadIconTex, gStrayFairySnowheadIconTex, + gDungeonStrayFairySnowheadIconTex }, + // DUNGEON_INDEX_GREAT_BAY_TEMPLE + { gStrayFairyGreatBayIconTex, gDungeonStrayFairyGreatBayIconTex, gStrayFairyGreatBayIconTex, + gDungeonStrayFairyGreatBayIconTex }, + // DUNGEON_INDEX_STONE_TOWER_TEMPLE + { gStrayFairyStoneTowerIconTex, gDungeonStrayFairyStoneTowerIconTex, gStrayFairyStoneTowerIconTex, + gDungeonStrayFairyStoneTowerIconTex }, + }; + static u8 sStrayFairyIconPrimColors[][3] = { + { 255, 110, 160 }, // DUNGEON_INDEX_WOODFALL_TEMPLE + { 90, 255, 100 }, // DUNGEON_INDEX_SNOWHEAD_TEMPLE + { 120, 255, 255 }, // DUNGEON_INDEX_GREAT_BAY_TEMPLE + { 245, 245, 90 }, // DUNGEON_INDEX_STONE_TOWER_TEMPLE + }; + static u8 sStrayFairyIconEnvColors[][3] = { + { 255, 255, 255 }, // DUNGEON_INDEX_WOODFALL_TEMPLE + { 255, 255, 255 }, // DUNGEON_INDEX_SNOWHEAD_TEMPLE + { 255, 255, 255 }, // DUNGEON_INDEX_GREAT_BAY_TEMPLE + { 225, 170, 0 }, // DUNGEON_INDEX_STONE_TOWER_TEMPLE + }; + static s32 sStrayFairyIconRectS[] = { + 1 << 10, // mirror texture horizontally + 0, // default + 0, // default + 0 // default + }; + PauseContext* pauseCtx = &play->pauseCtx; + s16 i; + s16 j; + f32 scale; + + OPEN_DISPS(play->state.gfxCtx); + + j = 72 + (pauseCtx->cursorSlot[PAUSE_MAP] * 4); + KaleidoScope_SetCursorVtx(pauseCtx, j, pauseCtx->mapPageVtx); + + pauseCtx->cursorItem[PAUSE_MAP] = PAUSE_ITEM_NONE; + if (pauseCtx->cursorSpecialPos == 0) { + if (pauseCtx->cursorPoint[PAUSE_MAP] <= DUNGEON_STRAY_FAIRIES) { + pauseCtx->cursorItem[PAUSE_MAP] = ITEM_KEY_BOSS + pauseCtx->cursorPoint[PAUSE_MAP]; + } + pauseCtx->cursorSlot[PAUSE_MAP] = pauseCtx->cursorPoint[PAUSE_MAP]; + } + + gSPVertex(POLY_OPA_DISP++, &pauseCtx->mapPageVtx[60], 16, 0); + gDPPipeSync(POLY_OPA_DISP++); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, pauseCtx->alpha); + gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA, G_CC_MODULATEIA); + + POLY_OPA_DISP = + func_8010DC58(POLY_OPA_DISP, sDungeonTitleTextures[((void)0, gSaveContext.dungeonIndex)], 128, 16, 0); + + gDPPipeSync(POLY_OPA_DISP++); + + gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); + + // Loop over dungeonItems (i) and vtxIndex (j) + for (i = DUNGEON_BOSS_KEY, j = 4; i <= DUNGEON_STRAY_FAIRIES; i++, j += 4) { + if (i == DUNGEON_STRAY_FAIRIES) { + if ((pauseCtx->pageIndex == PAUSE_MAP) && (pauseCtx->unk_200 == 0)) { + // If (pauseCtx->state == 6), then the other conditions are redundant and + // always return true + if ((pauseCtx->state == 6) && (pauseCtx->state != 7) && + !((pauseCtx->state >= 8) && (pauseCtx->state <= 0x12))) { + KaleidoScope_SetView(pauseCtx, 0.0f, 0.0f, 64.0f); + + if (!sStrayFairyIconAlphaScaleState) { + sStrayFairyIconAlpha -= 6; + sStrayFairyIconScale -= 1.0f; + } else { + sStrayFairyIconAlpha += 6; + sStrayFairyIconScale += 1.0f; + } + + sStrayFairyIconAlphaScaleTimer--; + if (sStrayFairyIconAlphaScaleTimer == 0) { + sStrayFairyIconAlphaScaleState ^= 1; + sStrayFairyIconAlphaScaleTimer = 15; + } + + func_8012C8AC(play->state.gfxCtx); + + gDPSetCombineLERP(POLY_OPA_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, + PRIMITIVE, 0, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, + 0); + + gDPSetPrimColor( + POLY_OPA_DISP++, 0, 0, sStrayFairyIconPrimColors[((void)0, gSaveContext.dungeonIndex)][0], + sStrayFairyIconPrimColors[((void)0, gSaveContext.dungeonIndex)][1], + sStrayFairyIconPrimColors[((void)0, gSaveContext.dungeonIndex)][2], sStrayFairyIconAlpha); + gDPSetEnvColor(POLY_OPA_DISP++, sStrayFairyIconEnvColors[((void)0, gSaveContext.dungeonIndex)][0], + sStrayFairyIconEnvColors[((void)0, gSaveContext.dungeonIndex)][1], + sStrayFairyIconEnvColors[((void)0, gSaveContext.dungeonIndex)][2], 0); + + scale = sStrayFairyIconScale / 100.0f; + + Matrix_Translate(-83.0f, -29.0f, -128.0f, MTXMODE_NEW); + Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + pauseCtx->mapPageVtx[76].v.ob[0] = pauseCtx->mapPageVtx[78].v.ob[0] = -16; + + pauseCtx->mapPageVtx[77].v.ob[0] = pauseCtx->mapPageVtx[79].v.ob[0] = + pauseCtx->mapPageVtx[76].v.ob[0] + 32; + + pauseCtx->mapPageVtx[76].v.ob[1] = pauseCtx->mapPageVtx[77].v.ob[1] = 12; + + pauseCtx->mapPageVtx[78].v.ob[1] = pauseCtx->mapPageVtx[79].v.ob[1] = + pauseCtx->mapPageVtx[76].v.ob[1] - 24; + + gSPVertex(POLY_OPA_DISP++, &pauseCtx->mapPageVtx[76], 4, 0); + + POLY_OPA_DISP = + func_8010DE38(POLY_OPA_DISP, gStrayFairyGlowingCircleIconTex, G_IM_FMT_I, 32, 24, 0); + KaleidoScope_SetView(pauseCtx, pauseCtx->eye.x, pauseCtx->eye.y, pauseCtx->eye.z); + func_8012C628(play->state.gfxCtx); + + gDPPipeSync(POLY_OPA_DISP++); + + gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); + + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, sStrayFairyIconAlpha); + + sStrayFairyIconTimer--; + + if (sStrayFairyIconTimer == 0) { + sStrayFairyIconIndex = (sStrayFairyIconIndex + 1) & 3; + sStrayFairyIconTimer = 34; + } + + gDPLoadTextureBlock( + POLY_OPA_DISP++, + sStrayFairyIconTextures[((void)0, gSaveContext.dungeonIndex)][sStrayFairyIconIndex], + G_IM_FMT_RGBA, G_IM_SIZ_32b, 32, 24, 0, G_TX_MIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 5, + G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); + gSPTextureRectangle(POLY_OPA_DISP++, 54 << 2, 140 << 2, 86 << 2, 164 << 2, G_TX_RENDERTILE, + sStrayFairyIconRectS[sStrayFairyIconIndex], 0, 1 << 10, 1 << 10); + + KaleidoScope_DrawDungeonStrayFairyCount(play); + func_8012C8AC(play->state.gfxCtx); + } + } + } else if (CHECK_DUNGEON_ITEM(i, gSaveContext.dungeonIndex)) { + gDPLoadTextureBlock(POLY_OPA_DISP++, sDungeonItemTextures[i], G_IM_FMT_RGBA, G_IM_SIZ_32b, 24, 24, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, + G_TX_NOLOD, G_TX_NOLOD); + + gSP1Quadrangle(POLY_OPA_DISP++, j, j + 2, j + 3, j + 1, 0); + } + } + + func_80108AF8(play); + + if ((pauseCtx->pageIndex == PAUSE_MAP) && (pauseCtx->unk_200 == 0)) { + // If (pauseCtx->state == 6), then the other conditions are redundant and always return + // true + if ((pauseCtx->state == 6) && (pauseCtx->state != 7) && + !((pauseCtx->state >= 8) && (pauseCtx->state <= 0x12))) { + + func_8012C628(play->state.gfxCtx); + + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, pauseCtx->alpha); + + // Draw Player's face next to the dungeon floor icon currently in. + POLY_OPA_DISP = func_8010CB80(POLY_OPA_DISP, &D_09007500, 16, 16, 62, + sDungeonMapFloorIconPosY[R_REVERSE_FLOOR_INDEX], 16, 16, 1 << 10, 1 << 10); + + if (CHECK_DUNGEON_ITEM(DUNGEON_COMPASS, gSaveContext.dungeonIndex)) { + POLY_OPA_DISP = func_8010CB80(POLY_OPA_DISP, gDungeonMapSkullTex, 16, 16, 108, + sDungeonMapFloorIconPosY[FLOOR_INDEX_MAX - func_80105318()], 16, 16, + 1 << 10, 1 << 10); + } + + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, pauseCtx->alpha); + + func_8012C8AC(play->state.gfxCtx); + } + } + + gDPPipeSync(POLY_OPA_DISP++); + + gDPSetTextureFilter(POLY_OPA_DISP++, G_TF_BILERP); + + CLOSE_DISPS(play->state.gfxCtx); +} + +void KaleidoScope_UpdateDungeonCursor(PlayState* play) { + s32 pad; + PauseContext* pauseCtx = &play->pauseCtx; + MessageContext* msgCtx = &play->msgCtx; + s16 i; + s16 oldCursorPoint; + + if (pauseCtx->state == 6) { + if ((pauseCtx->unk_200 == 0) && (pauseCtx->pageIndex == PAUSE_MAP)) { + pauseCtx->cursorColorSet = 0; + oldCursorPoint = pauseCtx->cursorPoint[PAUSE_MAP]; + if (pauseCtx->stickAdjX > 30) { + pauseCtx->unk_298 = 4.0f; + if (pauseCtx->cursorSpecialPos == PAUSE_CURSOR_PAGE_LEFT) { + func_80821A04(play); + pauseCtx->cursorXIndex[PAUSE_MAP] = 0; + pauseCtx->cursorSlot[PAUSE_MAP] = pauseCtx->unk_256; + pauseCtx->cursorPoint[PAUSE_MAP] = pauseCtx->unk_256; + } else if (pauseCtx->cursorSpecialPos == 0) { + if (pauseCtx->cursorXIndex[PAUSE_MAP] == 0) { + pauseCtx->cursorXIndex[PAUSE_MAP] = 1; + pauseCtx->cursorPoint[PAUSE_MAP] = DUNGEON_STRAY_FAIRIES; + } else { + if (pauseCtx->cursorPoint[PAUSE_MAP] == DUNGEON_STRAY_FAIRIES) { + pauseCtx->cursorPoint[PAUSE_MAP] = DUNGEON_NONE; + } + + while (true) { + pauseCtx->cursorPoint[PAUSE_MAP]++; + if (pauseCtx->cursorPoint[PAUSE_MAP] == DUNGEON_STRAY_FAIRIES) { + KaleidoScope_MoveCursorToSpecialPos(play, PAUSE_CURSOR_PAGE_RIGHT); + break; + } + if (CHECK_DUNGEON_ITEM(pauseCtx->cursorPoint[PAUSE_MAP], gSaveContext.dungeonIndex)) { + break; + } + } + } + } + } else if (pauseCtx->stickAdjX < -30) { + pauseCtx->unk_298 = 4.0f; + if (pauseCtx->cursorSpecialPos == PAUSE_CURSOR_PAGE_RIGHT) { + func_80821A04(play); + pauseCtx->cursorXIndex[PAUSE_MAP] = 1; + pauseCtx->cursorPoint[PAUSE_MAP] = DUNGEON_MAP; + if (!CHECK_DUNGEON_ITEM(DUNGEON_MAP, gSaveContext.dungeonIndex)) { + pauseCtx->cursorPoint[PAUSE_MAP]--; // DUNGEON_COMPASS + if (!CHECK_DUNGEON_ITEM(DUNGEON_COMPASS, gSaveContext.dungeonIndex)) { + pauseCtx->cursorPoint[PAUSE_MAP]--; // DUNGEON_BOSS_KEY + if (!CHECK_DUNGEON_ITEM(DUNGEON_BOSS_KEY, gSaveContext.dungeonIndex)) { + pauseCtx->cursorSlot[PAUSE_MAP] = DUNGEON_STRAY_FAIRIES; + pauseCtx->cursorPoint[PAUSE_MAP] = DUNGEON_STRAY_FAIRIES; + } + } + } else { + pauseCtx->cursorSlot[PAUSE_MAP] = pauseCtx->cursorPoint[PAUSE_MAP]; + } + } else if (pauseCtx->cursorSpecialPos == 0) { + if (pauseCtx->cursorXIndex[PAUSE_MAP] == 0) { + KaleidoScope_MoveCursorToSpecialPos(play, PAUSE_CURSOR_PAGE_LEFT); + } else if (pauseCtx->cursorPoint[PAUSE_MAP] == DUNGEON_STRAY_FAIRIES) { + pauseCtx->cursorXIndex[PAUSE_MAP] = 0; + pauseCtx->cursorSlot[PAUSE_MAP] = pauseCtx->unk_256; + pauseCtx->cursorPoint[PAUSE_MAP] = pauseCtx->unk_256; + } else { + while (true) { + pauseCtx->cursorPoint[PAUSE_MAP]--; + if (pauseCtx->cursorPoint[PAUSE_MAP] <= DUNGEON_NONE) { + pauseCtx->cursorSlot[PAUSE_MAP] = DUNGEON_STRAY_FAIRIES; + pauseCtx->cursorPoint[PAUSE_MAP] = DUNGEON_STRAY_FAIRIES; + break; + } + if (CHECK_DUNGEON_ITEM(pauseCtx->cursorPoint[PAUSE_MAP], gSaveContext.dungeonIndex)) { + break; + } + } + } + } + } else if ((pauseCtx->cursorSpecialPos == 0) && (pauseCtx->stickAdjY > 30)) { + if (pauseCtx->cursorPoint[PAUSE_MAP] >= DUNGEON_FLOOR_INDEX_4) { + for (i = pauseCtx->cursorPoint[PAUSE_MAP] - (DUNGEON_FLOOR_INDEX_4 + 1); i >= 0; i--) { + if ((gSaveContext.save.permanentSceneFlags[(void)0, gSaveContext.dungeonIndex].unk_14 & + gBitFlags[i]) || + func_801090B0(FLOOR_INDEX_MAX - i)) { + pauseCtx->cursorPoint[PAUSE_MAP] = i + DUNGEON_FLOOR_INDEX_4; + pauseCtx->unk_298 = 4.0f; + break; + } + } + } else if (pauseCtx->cursorPoint[PAUSE_MAP] == DUNGEON_STRAY_FAIRIES) { + pauseCtx->cursorXIndex[PAUSE_MAP] = 0; + pauseCtx->cursorSlot[PAUSE_MAP] = pauseCtx->unk_256; + pauseCtx->cursorPoint[PAUSE_MAP] = pauseCtx->unk_256; + } else { + pauseCtx->cursorSlot[PAUSE_MAP] = DUNGEON_STRAY_FAIRIES; + pauseCtx->cursorPoint[PAUSE_MAP] = DUNGEON_STRAY_FAIRIES; + } + } else if ((pauseCtx->cursorSpecialPos == 0) && (pauseCtx->stickAdjY < -30)) { + if ((pauseCtx->cursorPoint[PAUSE_MAP] >= DUNGEON_FLOOR_INDEX_4) && + (pauseCtx->cursorPoint[PAUSE_MAP] <= DUNGEON_FLOOR_INDEX_1)) { + for (i = pauseCtx->cursorPoint[PAUSE_MAP] - (DUNGEON_FLOOR_INDEX_4 - 1); i <= DUNGEON_FLOOR_INDEX_0; + i++) { + if ((gSaveContext.save.permanentSceneFlags[(void)0, gSaveContext.dungeonIndex].unk_14 & + gBitFlags[i]) || + func_801090B0(FLOOR_INDEX_MAX - i)) { + pauseCtx->cursorPoint[PAUSE_MAP] = i + DUNGEON_FLOOR_INDEX_4; + pauseCtx->unk_298 = 4.0f; + break; + } + } + + } else if (pauseCtx->cursorXIndex[PAUSE_MAP] == 0) { + pauseCtx->cursorXIndex[PAUSE_MAP] = 1; + pauseCtx->cursorPoint[PAUSE_MAP] = DUNGEON_STRAY_FAIRIES; + } else { + if (pauseCtx->cursorPoint[PAUSE_MAP] == DUNGEON_STRAY_FAIRIES) { + pauseCtx->cursorPoint[PAUSE_MAP] = DUNGEON_NONE; + } + + while (true) { + pauseCtx->cursorPoint[PAUSE_MAP]++; + if (pauseCtx->cursorPoint[PAUSE_MAP] == DUNGEON_FLOOR_INDEX_4) { + KaleidoScope_MoveCursorToSpecialPos(play, PAUSE_CURSOR_PAGE_RIGHT); + break; + } + if (CHECK_DUNGEON_ITEM(pauseCtx->cursorPoint[PAUSE_MAP], gSaveContext.dungeonIndex)) { + break; + } + } + } + } + if ((pauseCtx->cursorPoint[PAUSE_MAP] <= DUNGEON_STRAY_FAIRIES) && (pauseCtx->cursorSpecialPos == 0)) { + if (gSaveContext.buttonStatus[EQUIP_SLOT_A] == BTN_DISABLED) { + gSaveContext.buttonStatus[EQUIP_SLOT_A] = BTN_ENABLED; + gSaveContext.hudVisibility = HUD_VISIBILITY_IDLE; + Interface_SetHudVisibility(HUD_VISIBILITY_ALL); + } + } else if (gSaveContext.buttonStatus[EQUIP_SLOT_A] != BTN_DISABLED) { + gSaveContext.buttonStatus[EQUIP_SLOT_A] = BTN_DISABLED; + gSaveContext.hudVisibility = HUD_VISIBILITY_IDLE; + Interface_SetHudVisibility(HUD_VISIBILITY_ALL); + } + + if ((pauseCtx->cursorXIndex[PAUSE_MAP] == 0) && (pauseCtx->cursorSpecialPos == 0)) { + pauseCtx->unk_256 = pauseCtx->cursorPoint[PAUSE_MAP]; + } + + if (pauseCtx->cursorSpecialPos == 0) { + if (CHECK_BTN_ALL(CONTROLLER1(&play->state)->press.button, BTN_A) && (msgCtx->msgLength == 0) && + (pauseCtx->cursorPoint[PAUSE_MAP] == DUNGEON_STRAY_FAIRIES)) { + pauseCtx->itemDescriptionOn = true; + func_801514B0(play, 0x17AF, 1); + } else if (CHECK_BTN_ALL(CONTROLLER1(&play->state)->press.button, BTN_A) && (msgCtx->msgLength == 0) && + CHECK_DUNGEON_ITEM(pauseCtx->cursorPoint[PAUSE_MAP], gSaveContext.dungeonIndex)) { + pauseCtx->itemDescriptionOn = true; + func_801514B0(play, 0x17AC + pauseCtx->cursorPoint[PAUSE_MAP], 1); + } + } + + if (oldCursorPoint != pauseCtx->cursorPoint[PAUSE_MAP]) { + play_sound(NA_SE_SY_CURSOR); + } + } + } +} + +TexturePtr sCloudTextures[] = { + gWorldMapClockTownCloud1Tex, // TINGLE_MAP_CLOCK_TOWN + gWorldMapClockTownCloud2Tex, // TINGLE_MAP_CLOCK_TOWN + gWorldMapWoodfallCloud1Tex, // TINGLE_MAP_WOODFALL + gWorldMapWoodfallCloud2Tex, // TINGLE_MAP_WOODFALL + gWorldMapWoodfallCloud3Tex, // TINGLE_MAP_WOODFALL + gWorldMapSnowheadCloud1Tex, // TINGLE_MAP_SNOWHEAD + gWorldMapSnowheadCloud2Tex, // TINGLE_MAP_SNOWHEAD + gWorldMapSnowheadCloud3Tex, // TINGLE_MAP_SNOWHEAD + gWorldMapRomaniRanchCloudTex, // TINGLE_MAP_ROMANI_RANCH + gWorldMapGreatBayCloud1Tex, // TINGLE_MAP_GREAT_BAY + gWorldMapGreatBayCloud2Tex, // TINGLE_MAP_GREAT_BAY + gWorldMapGreatBayCloud3Tex, // TINGLE_MAP_GREAT_BAY + gWorldMapGreatBayCloud4Tex, // TINGLE_MAP_GREAT_BAY + gWorldMapStoneTowerCloud1Tex, // TINGLE_MAP_STONE_TOWER + gWorldMapStoneTowerCloud2Tex, // TINGLE_MAP_STONE_TOWER }; -s32 D_8082B520[] = { - 0xFF6EA05A, - 0xFF6478FF, - 0xFFF5F55A, +s16 sWorldMapDotPrimColors[][3] = { + { 0, 0, 255 }, + { 255, 255, 0 }, +}; +s16 sWorldMapDotEnvColors[][3] = { + { 255, 255, 0 }, + { 0, 0, 255 }, }; -s32 D_8082B52C[] = { - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFE1AA00, +s16 sWorldMapCursorsRectLeft[REGION_MAX] = { + 86, // REGION_GREAT_BAY + 104, // REGION_ZORA_HALL + 145, // REGION_ROMANI_RANCH + 153, // REGION_DEKU_PALACE + 163, // REGION_WOODFALL + 159, // REGION_CLOCK_TOWN + 157, // REGION_SNOWHEAD + 199, // REGION_IKANA_GRAVEYARD + 208, // REGION_IKANA_CANYON + 210, // REGION_GORON_VILLAGE + 218, // REGION_STONE_TOWER }; -s32 D_8082B538[] = { - 0x00000400, - 0x00000000, - 0x00000000, - 0x00000000, +s16 sWorldMapCursorsRectTop[REGION_MAX] = { + 127, // REGION_GREAT_BAY + 153, // REGION_ZORA_HALL + 138, // REGION_ROMANI_RANCH + 171, // REGION_DEKU_PALACE + 146, // REGION_WOODFALL + 119, // REGION_CLOCK_TOWN + 77, // REGION_SNOWHEAD + 106, // REGION_IKANA_GRAVEYARD + 120, // REGION_IKANA_CANYON + 73, // REGION_GORON_VILLAGE + 99, // REGION_STONE_TOWER }; -s16 D_8082B548[] = { - 0x0C00, 0x8418, 0x0C00, 0x9098, 0x0C01, 0x2898, 0x0C01, 0x35D8, 0x0C01, 0x4318, - 0x0C00, 0xDE58, 0x0C00, 0xEB58, 0x0C00, 0xFAA8, 0x0C00, 0x9858, 0x0C00, 0x9E58, - 0x0C00, 0xAE58, 0x0C00, 0xBE58, 0x0C00, 0xCE58, 0x0C01, 0x09F8, 0x0C01, 0x1958, +s16 sGreatFairySpawnRegions[] = { + REGION_CLOCK_TOWN, REGION_WOODFALL, REGION_SNOWHEAD, REGION_GREAT_BAY, REGION_IKANA_CANYON, + REGION_CLOCK_TOWN, REGION_WOODFALL, REGION_SNOWHEAD, REGION_GREAT_BAY, REGION_IKANA_CANYON, }; -s16 D_8082B584[] = { - 0x0000, 0x0000, 0x00FF, 0x00FF, 0x00FF, 0x0000, +void KaleidoScope_DrawWorldMap(PlayState* play) { + s16 sceneId; + s16 t; + s16 n; + s16 j; + s16 k; + s16 i; + PauseContext* pauseCtx = &play->pauseCtx; + s16 rectLeft; + s16 rectRight; + + OPEN_DISPS(play->state.gfxCtx); + + KaleidoScope_SetCursorVtx(pauseCtx, pauseCtx->cursorSlot[PAUSE_MAP] * 4, pauseCtx->mapPageVtx); + + // Draw the world map image + if ((pauseCtx->pageIndex == PAUSE_MAP) && (pauseCtx->state == 6) && + ((pauseCtx->unk_200 == 0) || (pauseCtx->unk_200 == 3)) && YREG(6) && (pauseCtx->state != 7) && + !((pauseCtx->state >= 8) && (pauseCtx->state <= 0x12))) { + + // Draw the world map image flat + // Because it is flat, the texture is loaded by filling it in 8 rows at a time. + // 8 is chosen because it is smaller than `TMEM_SIZE / 2 / textureWidth` and divides the texture's height. + // Each loaded chunk must have `size <= TMEM_SIZE / 2` + // because the texture is color-indexed, so the TLUT uses the other half of TMEM. + + func_8012C628(play->state.gfxCtx); + + gDPSetTextureFilter(POLY_OPA_DISP++, G_TF_POINT); + gDPLoadTLUT_pal256(POLY_OPA_DISP++, gWorldMapImageTLUT); + gDPSetTextureLUT(POLY_OPA_DISP++, G_TT_RGBA16); + + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, pauseCtx->alpha); + + // Process the 128 rows of pixels for gWorldMapImageTex, 8 rows at a time over 16 iterations + // Loop over yPos (t), textureIndex (j) + for (t = 62, j = 0; j < 16; j++, t += 8) { + gDPLoadTextureBlock(POLY_OPA_DISP++, (u8*)gWorldMapImageTex + j * (WORLD_MAP_IMAGE_TEX_WIDTH * 8), + G_IM_FMT_CI, G_IM_SIZ_8b, WORLD_MAP_IMAGE_TEX_WIDTH, 8, 0, G_TX_NOMIRROR | G_TX_WRAP, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); + + rectLeft = 51 << 2; + rectRight = rectLeft + (WORLD_MAP_IMAGE_TEX_WIDTH << 2); + gSPTextureRectangle(POLY_OPA_DISP++, rectLeft, t << 2, rectRight, (t << 2) + (8 << 2), G_TX_RENDERTILE, 0, + 0, 1 << 10, 1 << 10); + } + + func_8012C8AC(play->state.gfxCtx); + + } else { + // Draw the world map angled + // Because it is at an angle, vertices are used to place it. + // The structure of the loops here is to satisfy the constraints of both TMEM and the size of the vertex cache. + // - Each loop iteration loads 9 rows, because 9 is the largest number smaller than + // `TMEM_SIZE / 2 / textureWidth`. + // - Each loop is at most 8 iterations long because each row uses 4 vertices and the vertex cache has size + // `32 = 8 * 4`. + // . + // Hence there is one loop of length 8, one of length 6, and then the remaining `128 - (8 + 6) * 9 = 2` rows are + // drawn at the end. + + gDPPipeSync(POLY_OPA_DISP++); + gDPSetTextureFilter(POLY_OPA_DISP++, G_TF_POINT); + gDPLoadTLUT_pal256(POLY_OPA_DISP++, gWorldMapImageTLUT); + gDPSetTextureLUT(POLY_OPA_DISP++, G_TT_RGBA16); + + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, pauseCtx->alpha); + + // Set the vertices for the first 8 quads attached to the world map texture. + gSPVertex(POLY_OPA_DISP++, &pauseCtx->mapPageVtx[204], 8 * 4, 0); + + // Process the first 72 rows of pixels for gWorldMapImageTex, 9 rows at a time over 8 iterations + // Loop over quadIndex of this loop (i), quadIndex of the entire texture (k), vtxIndex (j) + for (i = 0, k = 0, j = 0; i < 8; i++, k++, j += 4) { + gDPLoadTextureBlock(POLY_OPA_DISP++, (u8*)gWorldMapImageTex + k * (WORLD_MAP_IMAGE_TEX_WIDTH * 9), + G_IM_FMT_CI, G_IM_SIZ_8b, WORLD_MAP_IMAGE_TEX_WIDTH, 9, 0, G_TX_NOMIRROR | G_TX_WRAP, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); + + gSP1Quadrangle(POLY_OPA_DISP++, j, j + 2, j + 3, j + 1, 0); + } + + // Set the vertices for the last 7 quads attached to the world map texture: + // 6 quads with a height of 9, 1 quad with a height of 2 + gSPVertex(POLY_OPA_DISP++, &pauseCtx->mapPageVtx[236], (6 + 1) * 4, 0); + + // Process the next 54 rows of pixels for gWorldMapImageTex, 9 rows at a time over 6 iterations + // Loop over quadIndex of this loop (i), quadIndex of the entire texture (k), vtxIndex (j) + for (i = 0, j = 0; i < 6; i++, k++, j += 4) { + gDPLoadTextureBlock(POLY_OPA_DISP++, (u8*)gWorldMapImageTex + k * (WORLD_MAP_IMAGE_TEX_WIDTH * 9), + G_IM_FMT_CI, G_IM_SIZ_8b, WORLD_MAP_IMAGE_TEX_WIDTH, 9, 0, G_TX_NOMIRROR | G_TX_WRAP, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); + + gSP1Quadrangle(POLY_OPA_DISP++, j, j + 2, j + 3, j + 1, 0); + } + + // Process the last 2 rows of pixels for gWorldMapImageTex + gDPLoadTextureBlock(POLY_OPA_DISP++, (u8*)gWorldMapImageTex + k * (WORLD_MAP_IMAGE_TEX_WIDTH * 9), G_IM_FMT_CI, + G_IM_SIZ_8b, WORLD_MAP_IMAGE_TEX_WIDTH, 2, 0, G_TX_NOMIRROR | G_TX_WRAP, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); + + gSP1Quadrangle(POLY_OPA_DISP++, j, j + 2, j + 3, j + 1, 0); + } + + func_8012C8AC(play->state.gfxCtx); + + gDPPipeSync(POLY_OPA_DISP++); + + gDPSetTextureFilter(POLY_OPA_DISP++, G_TF_BILERP); + + gDPSetCombineLERP(POLY_OPA_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0, PRIMITIVE, + ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0); + + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 215, 235, 235, pauseCtx->alpha); + gDPSetEnvColor(POLY_OPA_DISP++, 40, 60, 100, 0); + + // Draw clouds over the world map + // Iterate over cloud bits (n) + for (n = 0; n < 15; n++) { + if (!(((void)0, gSaveContext.save.worldMapCloudVisibility) & gBitFlags[n])) { + + gSPVertex(POLY_OPA_DISP++, &pauseCtx->mapPageVtx[60 + n * 4], 4, 0); + + POLY_OPA_DISP = func_8010DC58(POLY_OPA_DISP, sCloudTextures[n], D_8082B7F0[n], D_8082B838[n], 0); + } + } + + if ((pauseCtx->state >= 0x15) && (pauseCtx->state <= 0x19)) { + gDPPipeSync(POLY_OPA_DISP++); + gDPSetRenderMode(POLY_OPA_DISP++, G_RM_XLU_SURF, G_RM_XLU_SURF2); + gDPSetCombineMode(POLY_OPA_DISP++, G_CC_PRIMITIVE, G_CC_PRIMITIVE); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 0, 0, 0, R_PAUSE_OWLWARP_ALPHA); + gDPFillRectangle(POLY_OPA_DISP++, 50, 62, 270, 190); + } + + func_8012C8AC(play->state.gfxCtx); + + if (!((pauseCtx->state >= 0x15) && (pauseCtx->state <= 0x19))) { + // Browsing the world map regions on the pause menu + gDPLoadTextureBlock(POLY_OPA_DISP++, gWorldMapDotTex, G_IM_FMT_IA, G_IM_SIZ_8b, 8, 8, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, + G_TX_NOLOD); + gDPSetCombineLERP(POLY_OPA_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0, + PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0); + + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, sWorldMapDotPrimColors[0][0], sWorldMapDotPrimColors[0][1], + sWorldMapDotPrimColors[0][2], pauseCtx->alpha); + gDPSetEnvColor(POLY_OPA_DISP++, sWorldMapDotEnvColors[0][0], sWorldMapDotEnvColors[0][1], + sWorldMapDotEnvColors[0][2], 0); + + if (R_PAUSE_DBG_MAP_CLOUD_ON) { + gSaveContext.save.worldMapCloudVisibility |= (u16)~0x8000; + + pauseCtx->mapPageVtx[120].v.ob[0] = pauseCtx->mapPageVtx[122].v.ob[0] = R_PAUSE_DBG_MAP_CLOUD_X; + + pauseCtx->mapPageVtx[121].v.ob[0] = pauseCtx->mapPageVtx[123].v.ob[0] = + pauseCtx->mapPageVtx[120].v.ob[0] + 8; + + pauseCtx->mapPageVtx[120].v.ob[1] = pauseCtx->mapPageVtx[121].v.ob[1] = R_PAUSE_DBG_MAP_CLOUD_Y; + + pauseCtx->mapPageVtx[122].v.ob[1] = pauseCtx->mapPageVtx[123].v.ob[1] = + pauseCtx->mapPageVtx[120].v.ob[1] - 8; + } + + // Loop over RegionId (i), unused vtxIndex (j), unused (k) + for (i = 0, j = 0; i < REGION_MAX; i++, k++, j += 4) { + if (pauseCtx->worldMapPoints[i]) { + gSPVertex(POLY_OPA_DISP++, &pauseCtx->mapPageVtx[120 + i * 4], 4, 0); + gSP1Quadrangle(POLY_OPA_DISP++, 0, 2, 3, 1, 0); + } + } + + } else { + // Selecting an owl warp + gDPPipeSync(POLY_OPA_DISP++); + gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); + gDPLoadTextureBlock(POLY_OPA_DISP++, gWorldMapOwlFaceTex, G_IM_FMT_RGBA, G_IM_SIZ_32b, 24, 12, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, + G_TX_NOLOD); + + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, pauseCtx->alpha); + + if (R_PAUSE_DBG_MAP_CLOUD_ON) { + gSaveContext.save.worldMapCloudVisibility |= (u16)~0x8000; + + pauseCtx->mapPageVtx[164].v.ob[0] = pauseCtx->mapPageVtx[166].v.ob[0] = R_PAUSE_DBG_MAP_CLOUD_X; + + pauseCtx->mapPageVtx[165].v.ob[0] = pauseCtx->mapPageVtx[167].v.ob[0] = + pauseCtx->mapPageVtx[164].v.ob[0] + 24; + + pauseCtx->mapPageVtx[164].v.ob[1] = pauseCtx->mapPageVtx[165].v.ob[1] = R_PAUSE_DBG_MAP_CLOUD_Y; + + pauseCtx->mapPageVtx[166].v.ob[1] = pauseCtx->mapPageVtx[167].v.ob[1] = + pauseCtx->mapPageVtx[164].v.ob[1] - 12; + } + + // Loop over OwlWarpId (i), unused vtxIndex (j), unused (k) + for (i = 0, j = 0; i < OWL_WARP_ENTRANCE; i++, k++, j += 4) { + if (pauseCtx->worldMapPoints[i]) { + gSPVertex(POLY_OPA_DISP++, &pauseCtx->mapPageVtx[164 + i * 4], 4, 0); + gSP1Quadrangle(POLY_OPA_DISP++, 0, 2, 3, 1, 0); + } + } + } + + // Find and draw Player's face at the current region based on the current scene + // If (pauseCtx->state == 6), then the other pauseCtx->state conditions are redundant + // and always return true + if ((pauseCtx->pageIndex == PAUSE_MAP) && (pauseCtx->unk_200 == 0) && (pauseCtx->state == 6) && + (pauseCtx->state != 7) && !((pauseCtx->state >= 8) && (pauseCtx->state <= 0x12))) { + j = 0; + n = 0; + + sceneId = play->sceneId; + + // Map grottos/shrines to sceneId's to be used in different regions + if (sceneId == SCENE_KAKUSIANA) { + if (play->roomCtx.curRoom.num == 5) { + sceneId = SCENE_11GORONNOSATO; + } else if ((play->roomCtx.curRoom.num == 6) || (play->roomCtx.curRoom.num == 8) || + (play->roomCtx.curRoom.num == 12)) { + sceneId = SCENE_22DEKUCITY; + } else { + sceneId = Entrance_GetSceneIdAbsolute(((void)0, gSaveContext.respawn[RESPAWN_MODE_UNK_3].entrance)); + } + } + + // Find the regionId that player is currently in + // Loop over regionId (n) and regionIdIndex (j) + while (true) { + if ((gSceneIdsPerRegion[n][j] == 0xFFFF)) { + n++; + j = 0; + if (n == REGION_MAX) { + n = 0; + + // Special case for fairy fountains + if (sceneId == SCENE_YOUSEI_IZUMI) { + j = play->curSpawn; + n = sGreatFairySpawnRegions[j]; + break; + } + + while (true) { + if (gSceneIdsPerRegion[n][j] == 0xFFFF) { + n++; + if (n == REGION_MAX) { + break; + } + j = 0; + if (Entrance_GetSceneIdAbsolute( + ((void)0, gSaveContext.respawn[RESPAWN_MODE_UNK_3].entrance)) == + gSceneIdsPerRegion[n][j]) { + break; + } + } + j++; + } + break; + } + } + + if (sceneId == gSceneIdsPerRegion[n][j]) { + break; + } + j++; + } + + // Draw Player's face at the current region + if (n != REGION_MAX) { + KaleidoScope_SetView(pauseCtx, pauseCtx->eye.x, pauseCtx->eye.y, pauseCtx->eye.z); + func_8012C628(play->state.gfxCtx); + + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, pauseCtx->alpha); + + POLY_OPA_DISP = func_8010CB80(POLY_OPA_DISP, &D_09007500, 16, 16, sWorldMapCursorsRectLeft[n], + sWorldMapCursorsRectTop[n], 16, 16, 1 << 10, 1 << 10); + } + } + + gDPPipeSync(POLY_OPA_DISP++); + + CLOSE_DISPS(play->state.gfxCtx); +} + +u16 sOwlWarpPauseItems[] = { + 0xAF, // OWL_WARP_GREAT_BAY_COAST + 0xB3, // OWL_WARP_ZORA_CAPE + 0xAA, // OWL_WARP_SNOWHEAD + 0xB1, // OWL_WARP_MOUNTAIN_VILLAGE + 0xA9, // OWL_WARP_CLOCK_TOWN + 0xB2, // OWL_WARP_MILK_ROAD + 0xA8, // OWL_WARP_WOODFALL + 0xB0, // OWL_WARP_SOUTHERN_SWAMP + 0xAC, // OWL_WARP_IKANA_CANYON + 0xAE, // OWL_WARP_STONE_TOWER }; -s16 D_8082B590[] = { - 0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x00FF, -}; +void KaleidoScope_UpdateWorldMapCursor(PlayState* play) { + static u16 sStickAdjTimer = 0; // unused timer that counts up every frame. Resets on reading a stickAdj. + PauseContext* pauseCtx = &play->pauseCtx; + s16 oldCursorPoint; -s16 D_8082B59C[] = { - 0x0056, 0x0068, 0x0091, 0x0099, 0x00A3, 0x009F, 0x009D, 0x00C7, 0x00D0, 0x00D2, 0x00DA, 0x0000, -}; + if ((pauseCtx->state == 6) && (pauseCtx->unk_200 == 0) && (pauseCtx->pageIndex == PAUSE_MAP)) { + pauseCtx->cursorColorSet = 0; + oldCursorPoint = pauseCtx->cursorPoint[PAUSE_WORLD_MAP]; -s16 D_8082B5B4[] = { - 0x007F, 0x0099, 0x008A, 0x00AB, 0x0092, 0x0077, 0x004D, 0x006A, 0x0078, 0x0049, 0x0063, 0x0000, -}; + if (gSaveContext.buttonStatus[EQUIP_SLOT_A] != BTN_DISABLED) { + gSaveContext.buttonStatus[EQUIP_SLOT_A] = BTN_DISABLED; + gSaveContext.hudVisibility = HUD_VISIBILITY_IDLE; + Interface_SetHudVisibility(HUD_VISIBILITY_ALL); + } -s16 D_8082B5CC[] = { - 0x0005, 0x0004, 0x0006, 0x0000, 0x0008, 0x0005, 0x0004, 0x0006, 0x0000, 0x0008, -}; + if (pauseCtx->cursorSpecialPos == 0) { + if (pauseCtx->stickAdjX > 30) { + pauseCtx->unk_298 = 4.0f; + sStickAdjTimer = 0; -u16 D_8082B5E0[] = { - 0xAF, 0xB3, 0xAA, 0xB1, 0xA9, 0xB2, 0xA8, 0xB0, 0xAC, 0xAE, -}; -u16 D_8082B5F4 = 0; + while (true) { + pauseCtx->cursorPoint[PAUSE_WORLD_MAP]++; + if (pauseCtx->cursorPoint[PAUSE_WORLD_MAP] >= REGION_MAX) { + KaleidoScope_MoveCursorToSpecialPos(play, PAUSE_CURSOR_PAGE_RIGHT); + pauseCtx->cursorItem[PAUSE_MAP] = PAUSE_ITEM_NONE; + break; + } + if (pauseCtx->worldMapPoints[pauseCtx->cursorPoint[PAUSE_WORLD_MAP]]) { + break; + } + } + } else if (pauseCtx->stickAdjX < -30) { + pauseCtx->unk_298 = 4.0f; + sStickAdjTimer = 0; -s32 D_8082B5F8[] = { 0, 0 }; + while (true) { + pauseCtx->cursorPoint[PAUSE_WORLD_MAP]--; + if (pauseCtx->cursorPoint[PAUSE_WORLD_MAP] < REGION_GREAT_BAY) { + KaleidoScope_MoveCursorToSpecialPos(play, PAUSE_CURSOR_PAGE_LEFT); + pauseCtx->cursorItem[PAUSE_MAP] = PAUSE_ITEM_NONE; + break; + } + if (pauseCtx->worldMapPoints[pauseCtx->cursorPoint[PAUSE_WORLD_MAP]]) { + break; + } + } + } else { + sStickAdjTimer++; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_kaleido_scope/func_8081D240.s") + if (pauseCtx->cursorSpecialPos == 0) { + pauseCtx->cursorItem[PAUSE_MAP] = pauseCtx->cursorPoint[PAUSE_WORLD_MAP]; + // Used as cursor vtxIndex + pauseCtx->cursorSlot[PAUSE_MAP] = 31 + pauseCtx->cursorPoint[PAUSE_WORLD_MAP]; + } + } else { + pauseCtx->cursorItem[PAUSE_MAP] = PAUSE_ITEM_NONE; + if (pauseCtx->cursorSpecialPos == PAUSE_CURSOR_PAGE_LEFT) { + if (pauseCtx->stickAdjX > 30) { + pauseCtx->cursorPoint[PAUSE_WORLD_MAP] = -1; + pauseCtx->cursorSpecialPos = 0; + pauseCtx->unk_298 = 4.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_kaleido_scope/func_8081D6DC.s") + while (true) { + pauseCtx->cursorPoint[PAUSE_WORLD_MAP]++; + if (pauseCtx->cursorPoint[PAUSE_WORLD_MAP] > REGION_STONE_TOWER) { + KaleidoScope_MoveCursorToSpecialPos(play, PAUSE_CURSOR_PAGE_RIGHT); + pauseCtx->cursorItem[PAUSE_MAP] = PAUSE_ITEM_NONE; + break; + } + if (pauseCtx->worldMapPoints[pauseCtx->cursorPoint[PAUSE_WORLD_MAP]]) { + break; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_kaleido_scope/func_8081E118.s") + if (pauseCtx->cursorSpecialPos == 0) { + pauseCtx->cursorItem[PAUSE_MAP] = pauseCtx->cursorPoint[PAUSE_WORLD_MAP]; + // Used as cursor vtxIndex + pauseCtx->cursorSlot[PAUSE_MAP] = 31 + pauseCtx->cursorPoint[PAUSE_WORLD_MAP]; + } + play_sound(NA_SE_SY_CURSOR); + sStickAdjTimer = 0; + } + } else if (pauseCtx->stickAdjX < -30) { + pauseCtx->cursorPoint[PAUSE_WORLD_MAP] = 11; + pauseCtx->cursorSpecialPos = 0; + pauseCtx->unk_298 = 4.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_kaleido_scope/func_8081E7D8.s") + while (true) { + pauseCtx->cursorPoint[PAUSE_WORLD_MAP]--; + if (pauseCtx->cursorPoint[PAUSE_WORLD_MAP] < 0) { + KaleidoScope_MoveCursorToSpecialPos(play, PAUSE_CURSOR_PAGE_LEFT); + pauseCtx->cursorItem[PAUSE_MAP] = PAUSE_ITEM_NONE; + break; + } + if (pauseCtx->worldMapPoints[pauseCtx->cursorPoint[PAUSE_WORLD_MAP]]) { + break; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_kaleido_scope/func_8081FB1C.s") + if (pauseCtx->cursorSpecialPos == 0) { + pauseCtx->cursorItem[PAUSE_MAP] = pauseCtx->cursorPoint[PAUSE_WORLD_MAP]; + // Used as cursor vtxIndex + pauseCtx->cursorSlot[PAUSE_MAP] = 31 + pauseCtx->cursorPoint[PAUSE_WORLD_MAP]; + } + play_sound(NA_SE_SY_CURSOR); + sStickAdjTimer = 0; + } + } + + if (!pauseCtx->worldMapPoints[pauseCtx->cursorPoint[PAUSE_WORLD_MAP]]) { + pauseCtx->cursorItem[PAUSE_MAP] = PAUSE_ITEM_NONE; + } + if (oldCursorPoint != pauseCtx->cursorPoint[PAUSE_WORLD_MAP]) { + play_sound(NA_SE_SY_CURSOR); + } + } else if (pauseCtx->state == 0x17) { + pauseCtx->cursorColorSet = 4; + oldCursorPoint = pauseCtx->cursorPoint[PAUSE_WORLD_MAP]; + + if (pauseCtx->stickAdjX > 30) { + pauseCtx->unk_298 = 4.0f; + sStickAdjTimer = 0; + do { + pauseCtx->cursorPoint[PAUSE_WORLD_MAP]++; + if (pauseCtx->cursorPoint[PAUSE_WORLD_MAP] > OWL_WARP_STONE_TOWER) { + pauseCtx->cursorPoint[PAUSE_WORLD_MAP] = OWL_WARP_GREAT_BAY_COAST; + } + } while (!pauseCtx->worldMapPoints[pauseCtx->cursorPoint[PAUSE_WORLD_MAP]]); + } else if (pauseCtx->stickAdjX < -30) { + pauseCtx->unk_298 = 4.0f; + sStickAdjTimer = 0; + do { + pauseCtx->cursorPoint[PAUSE_WORLD_MAP]--; + if (pauseCtx->cursorPoint[PAUSE_WORLD_MAP] < OWL_WARP_GREAT_BAY_COAST) { + pauseCtx->cursorPoint[PAUSE_WORLD_MAP] = OWL_WARP_STONE_TOWER; + } + } while (!pauseCtx->worldMapPoints[pauseCtx->cursorPoint[PAUSE_WORLD_MAP]]); + } else { + sStickAdjTimer++; + } + + //! TODO: Is the `0xA4` here related to `0xA3` being the last recored item in the `ItemId` enum? + pauseCtx->cursorItem[PAUSE_MAP] = sOwlWarpPauseItems[pauseCtx->cursorPoint[PAUSE_WORLD_MAP]] - 0xA4; + // Used as cursor vtxIndex + pauseCtx->cursorSlot[PAUSE_MAP] = 31 + pauseCtx->cursorPoint[PAUSE_WORLD_MAP]; + + if (oldCursorPoint != pauseCtx->cursorPoint[PAUSE_WORLD_MAP]) { + play_sound(NA_SE_SY_CURSOR); + } + } +} diff --git a/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope.h b/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope.h index 94724154f..72392390b 100644 --- a/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope.h +++ b/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope.h @@ -51,9 +51,16 @@ typedef enum { // NES void KaleidoScope_MoveCursorToSpecialPos(PlayState* play, s16 cursorSpecialPos); -void KaleidoScope_DrawQuadTextureRGBA32(GraphicsContext* gfxCtx, void* texture, u16 width, u16 height, u16 point); +void KaleidoScope_DrawQuadTextureRGBA32(GraphicsContext* gfxCtx, TexturePtr texture, u16 width, u16 height, u16 point); +void KaleidoScope_SetView(PauseContext* pauseCtx, f32 x, f32 y, f32 z); void func_80821A04(PlayState* play); +// Map +void KaleidoScope_DrawDungeonMap(PlayState* play); +void KaleidoScope_UpdateDungeonCursor(PlayState* play); +void KaleidoScope_DrawWorldMap(PlayState* play); +void KaleidoScope_UpdateWorldMapCursor(PlayState* play); + // Item void KaleidoScope_SetCursorVtx(PauseContext* pauseCtx, u16 index, Vtx* vtx); void KaleidoScope_DrawItemSelect(PlayState* play); diff --git a/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope_NES.c b/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope_NES.c index 3b3de5937..6c6754b3d 100644 --- a/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope_NES.c +++ b/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope_NES.c @@ -345,7 +345,7 @@ s32 D_8082BEB8[] = { 0, 0 }; #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_kaleido_scope/func_8082585C.s") -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_kaleido_scope/func_808259D4.s") +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_kaleido_scope/KaleidoScope_SetView.s") #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_kaleido_scope/func_80825A50.s") diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index 403d163e3..558efc8fb 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -2410,7 +2410,7 @@ 0x8012ED78:("Inventory_DeleteEquipment",), 0x8012EDE8:("Inventory_ChangeUpgrade",), 0x8012EE34:("Inventory_IsMapVisible",), - 0x8012EF0C:("Inventory_SetMapVisibility",), + 0x8012EF0C:("Inventory_SetWorldMapCloudVisibility",), 0x8012F0EC:("Inventory_SaveDekuPlaygroundHighScore",), 0x8012F1BC:("Inventory_IncrementSkullTokenCount",), 0x8012F22C:("Inventory_GetSkullTokenCount",), @@ -2452,7 +2452,7 @@ 0x80130540:("Scene_HeaderCmdMiniMap",), 0x80130578:("Scene_HeaderCmd1D",), 0x80130588:("Scene_HeaderCmdMiniMapCompassInfo",), - 0x801305B0:("Scene_HeaderCmdSetAreaVisitedFlag",), + 0x801305B0:("Scene_HeaderCmdSetRegionVisitedFlag",), 0x80130674:("Scene_HeaderCmdAnimatedMaterials",), 0x801306A4:("Scene_SetExitFade",), 0x801306E8:("Scene_ProcessHeader",), @@ -2880,7 +2880,7 @@ 0x80158C04:("Message_LoadLocalizedRupeesNES",), 0x80158D98:("Message_LoadRupeesNES",), 0x80158FB0:("Message_LoadTimeNES",), - 0x8015926C:("Message_LoadAreaTextNES",), + 0x8015926C:("Message_LoadOwlWarpTextNES",), 0x80159438:("func_80159438",), 0x8015966C:("func_8015966C",), 0x8015B198:("func_8015B198",), @@ -4209,11 +4209,11 @@ 0x8081B6EC:("KaleidoScope_DrawItemSelect",), 0x8081BCA8:("KaleidoScope_UpdateItemCursor",), 0x8081C684:("KaleidoScope_UpdateItemEquip",), - 0x8081D240:("func_8081D240",), - 0x8081D6DC:("func_8081D6DC",), - 0x8081E118:("func_8081E118",), - 0x8081E7D8:("func_8081E7D8",), - 0x8081FB1C:("func_8081FB1C",), + 0x8081D240:("KaleidoScope_DrawDungeonStrayFairyCount",), + 0x8081D6DC:("KaleidoScope_DrawDungeonMap",), + 0x8081E118:("KaleidoScope_UpdateDungeonCursor",), + 0x8081E7D8:("KaleidoScope_DrawWorldMap",), + 0x8081FB1C:("KaleidoScope_UpdateWorldMapCursor",), 0x8081FF80:("KaleidoScope_DrawMaskSelect",), 0x808204AC:("KaleidoScope_UpdateMaskCursor",), 0x80820FA4:("KaleidoScope_UpdateMaskEquip",), @@ -4234,7 +4234,7 @@ 0x80824B90:("func_80824B90",), 0x808256E4:("func_808256E4",), 0x8082585C:("func_8082585C",), - 0x808259D4:("func_808259D4",), + 0x808259D4:("KaleidoScope_SetView",), 0x80825A50:("func_80825A50",), 0x80825E28:("func_80825E28",), 0x808274DC:("func_808274DC",), @@ -6903,14 +6903,14 @@ 0x809199FC:("func_809199FC",), 0x80919D68:("EffDust_Draw",), 0x80919F30:("func_80919F30",), - 0x80919FC8:("func_80919FC8",), - 0x8091A044:("func_8091A044",), - 0x8091A0B8:("func_8091A0B8",), + 0x80919FC8:("BgUmajump_StopCutscene",), + 0x8091A044:("BgUmajump_PlayCutscene",), + 0x8091A0B8:("BgUmajump_CheckDistance",), 0x8091A124:("BgUmajump_Init",), 0x8091A2D8:("BgUmajump_Destroy",), 0x8091A30C:("BgUmajump_Update",), 0x8091A5A0:("func_8091A5A0",), - 0x8091A7B0:("func_8091A7B0",), + 0x8091A7B0:("BgUmajump_Draw",), 0x8091A8A0:("func_8091A8A0",), 0x8091A8C4:("EnInsect_XZDistanceSquared",), 0x8091A8F4:("EnInsect_InBottleRange",), @@ -11629,12 +11629,12 @@ 0x80AAEABC:("DmChar07_DoNothing",), 0x80AAEACC:("DmChar07_Update",), 0x80AAEAF0:("DmChar07_Draw",), - 0x80AAF050:("func_80AAF050",), - 0x80AAF15C:("func_80AAF15C",), + 0x80AAF050:("DmChar08_UpdateEyes",), + 0x80AAF15C:("DmChar08_ChangeAnimation",), 0x80AAF1F8:("DmChar08_Init",), 0x80AAF5D8:("DmChar08_Destroy",), - 0x80AAF610:("func_80AAF610",), - 0x80AAF79C:("func_80AAF79C",), + 0x80AAF610:("DmChar08_WaitForSong",), + 0x80AAF79C:("DmChar08_SetupAppearCs",), 0x80AAF884:("func_80AAF884",), 0x80AAF8F4:("func_80AAF8F4",), 0x80AAFA18:("func_80AAFA18",), @@ -11642,19 +11642,19 @@ 0x80AAFAE4:("func_80AAFAE4",), 0x80AAFB04:("func_80AAFB04",), 0x80AAFB94:("func_80AAFB94",), - 0x80AAFBA4:("func_80AAFBA4",), + 0x80AAFBA4:("DmChar08_SpawnBubbles",), 0x80AAFCCC:("func_80AAFCCC",), - 0x80AAFE78:("func_80AAFE78",), + 0x80AAFE78:("DmChar08_DoNothing",), 0x80AAFE88:("func_80AAFE88",), 0x80AB01E8:("func_80AB01E8",), 0x80AB023C:("func_80AB023C",), 0x80AB032C:("func_80AB032C",), 0x80AB096C:("func_80AB096C",), - 0x80AB0A10:("func_80AB0A10",), + 0x80AB0A10:("DmChar08_UpdateCollision",), 0x80AB0CC8:("DmChar08_Update",), - 0x80AB0E3C:("func_80AB0E3C",), - 0x80AB0E7C:("func_80AB0E7C",), - 0x80AB0F90:("func_80AB0F90",), + 0x80AB0E3C:("DmChar08_OverrideLimbDraw",), + 0x80AB0E7C:("DmChar08_PostLimbDraw",), + 0x80AB0F90:("DmChar08_TransformLimbDraw",), 0x80AB1124:("DmChar08_Draw",), 0x80AB1E10:("DmChar09_ChangeAnim",), 0x80AB1EAC:("DmChar09_Init",), @@ -15595,22 +15595,22 @@ 0x80BC7BBC:("OceffWipe5_Draw",), 0x80BC9270:("EnStoneheishi_Init",), 0x80BC9330:("EnStoneheishi_Destroy",), - 0x80BC935C:("func_80BC935C",), - 0x80BC941C:("func_80BC941C",), + 0x80BC935C:("EnStoneheishi_ChangeAnim",), + 0x80BC941C:("EnStoneheishi_TrackPlayer",), 0x80BC94B0:("func_80BC94B0",), 0x80BC9560:("func_80BC9560",), 0x80BC9660:("func_80BC9660",), 0x80BC9680:("func_80BC9680",), - 0x80BC98EC:("func_80BC98EC",), - 0x80BC9908:("func_80BC9908",), - 0x80BC9A10:("func_80BC9A10",), - 0x80BC9A2C:("func_80BC9A2C",), - 0x80BC9C88:("func_80BC9C88",), + 0x80BC98EC:("EnStoneheishi_SetupCheckGivenItem",), + 0x80BC9908:("EnStoneheishi_CheckGivenItem",), + 0x80BC9A10:("EnStoneheishi_SetupDrinkBottleProcess",), + 0x80BC9A2C:("EnStoneheishi_DrinkBottleProcess",), + 0x80BC9C88:("EnStoneheishi_GiveItemReward",), 0x80BC9D28:("func_80BC9D28",), 0x80BC9E50:("func_80BC9E50",), 0x80BC9EE4:("EnStoneheishi_Update",), - 0x80BCA0AC:("func_80BCA0AC",), - 0x80BCA104:("func_80BCA104",), + 0x80BCA0AC:("EnStoneheishi_OverrideLimbDraw",), + 0x80BCA104:("EnStoneheishi_PostLimbDraw",), 0x80BCA2AC:("EnStoneheishi_Draw",), 0x80BCA5A0:("OceffWipe6_Init",), 0x80BCA5F8:("OceffWipe6_Destroy",), @@ -15765,16 +15765,16 @@ 0x80BD40D0:("func_80BD40D0",), 0x80BD4108:("ObjHgdoor_Init",), 0x80BD41B4:("ObjHgdoor_Destroy",), - 0x80BD41E8:("ObjHgdoor_SetupCheckShouldOpen",), - 0x80BD41FC:("ObjHgdoor_CheckShouldOpen",), - 0x80BD42AC:("func_80BD42AC",), - 0x80BD42C0:("func_80BD42C0",), - 0x80BD433C:("func_80BD433C",), - 0x80BD4358:("func_80BD4358",), - 0x80BD4460:("func_80BD4460",), - 0x80BD4478:("func_80BD4478",), - 0x80BD44D0:("func_80BD44D0",), - 0x80BD4500:("func_80BD4500",), + 0x80BD41E8:("ObjHgdoor_SetupIdle",), + 0x80BD41FC:("ObjHgdoor_Idle",), + 0x80BD42AC:("ObjHgdoor_SetupCutscene",), + 0x80BD42C0:("ObjHgdoor_PlayCutscene",), + 0x80BD433C:("ObjHgdoor_SetupCsAction",), + 0x80BD4358:("ObjHgdoor_HandleCsAction",), + 0x80BD4460:("ObjHgdoor_SetupStopCs",), + 0x80BD4478:("ObjHgdoor_StopCs",), + 0x80BD44D0:("ObjHgdoor_Rotate",), + 0x80BD4500:("ObjHgdoor_Open",), 0x80BD4540:("ObjHgdoor_Update",), 0x80BD4570:("ObjHgdoor_Draw",), 0x80BD4720:("func_80BD4720",), diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index 5c8147eef..f8023eb2c 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -4703,28 +4703,28 @@ 0x8082B484:("sCButtonPosX","UNK_TYPE1","",0x1), 0x8082B48C:("sCButtonPosY","UNK_TYPE1","",0x1), 0x8082B494:("sEquipMagicArrowBowSlotHoldTimer","UNK_TYPE2","",0x2), - 0x8082B4A0:("D_8082B4A0","UNK_TYPE4","",0x4), - 0x8082B4AC:("D_8082B4AC","UNK_TYPE1","",0x1), - 0x8082B4BC:("D_8082B4BC","UNK_TYPE1","",0x1), + 0x8082B4A0:("sDungeonItemTextures","UNK_TYPE4","",0x4), + 0x8082B4AC:("sDungeonTitleTextures","UNK_TYPE1","",0x1), + 0x8082B4BC:("sDungeonMapFloorIconPosY","UNK_TYPE1","",0x1), 0x8082B4C4:("D_8082B4C4","UNK_TYPE1","",0x1), - 0x8082B4C8:("D_8082B4C8","UNK_TYPE2","",0x2), - 0x8082B4CC:("D_8082B4CC","UNK_TYPE2","",0x2), - 0x8082B4D0:("D_8082B4D0","UNK_TYPE2","",0x2), - 0x8082B4D4:("D_8082B4D4","UNK_TYPE2","",0x2), - 0x8082B4D8:("D_8082B4D8","UNK_TYPE2","",0x2), - 0x8082B4DC:("D_8082B4DC","f32","",0x4), - 0x8082B4E0:("D_8082B4E0","UNK_TYPE1","",0x1), - 0x8082B520:("D_8082B520","UNK_TYPE1","",0x1), - 0x8082B52C:("D_8082B52C","UNK_TYPE1","",0x1), - 0x8082B538:("D_8082B538","UNK_TYPE1","",0x1), - 0x8082B548:("D_8082B548","s16","[30]",0x3C), - 0x8082B584:("D_8082B584","UNK_TYPE2","",0x2), - 0x8082B590:("D_8082B590","UNK_TYPE2","",0x2), - 0x8082B59C:("D_8082B59C","UNK_TYPE1","",0x1), - 0x8082B5B4:("D_8082B5B4","UNK_TYPE1","",0x1), - 0x8082B5CC:("D_8082B5CC","UNK_TYPE1","",0x1), - 0x8082B5E0:("D_8082B5E0","UNK_TYPE1","",0x1), - 0x8082B5F4:("D_8082B5F4","UNK_TYPE2","",0x2), + 0x8082B4C8:("sStrayFairyIconTimer","UNK_TYPE2","",0x2), + 0x8082B4CC:("sStrayFairyIconIndex","UNK_TYPE2","",0x2), + 0x8082B4D0:("sStrayFairyIconAlphaScaleTimer","UNK_TYPE2","",0x2), + 0x8082B4D4:("sStrayFairyIconAlphaScaleState","UNK_TYPE2","",0x2), + 0x8082B4D8:("sStrayFairyIconAlpha","UNK_TYPE2","",0x2), + 0x8082B4DC:("sStrayFairyIconScale","f32","",0x4), + 0x8082B4E0:("sStrayFairyIconTextures","UNK_TYPE1","",0x1), + 0x8082B520:("sStrayFairyIconPrimColors","UNK_TYPE1","",0x1), + 0x8082B52C:("sStrayFairyIconEnvColors","UNK_TYPE1","",0x1), + 0x8082B538:("sStrayFairyIconRectS","UNK_TYPE1","",0x1), + 0x8082B548:("sCloudTextures","s16","[30]",0x3C), + 0x8082B584:("sWorldMapDotPrimColors","UNK_TYPE2","",0x2), + 0x8082B590:("sWorldMapDotEnvColors","UNK_TYPE2","",0x2), + 0x8082B59C:("sWorldMapCursorsRectLeft","UNK_TYPE1","",0x1), + 0x8082B5B4:("sWorldMapCursorsRectTop","UNK_TYPE1","",0x1), + 0x8082B5CC:("sGreatFairySpawnRegions","UNK_TYPE1","",0x1), + 0x8082B5E0:("sOwlWarpPauseItems","UNK_TYPE1","",0x1), + 0x8082B5F4:("sStickAdjTimer","UNK_TYPE2","",0x2), 0x8082B600:("sMaskEquipState","UNK_TYPE2","",0x2), 0x8082B604:("sMaskEquipMagicArrowSlotHoldTimer","UNK_TYPE2","",0x2), 0x8082B608:("sMaskEquipAnimTimer","UNK_TYPE2","",0x2), @@ -12659,21 +12659,21 @@ 0x80AAE960:("Dm_Char06_InitVars","UNK_TYPE1","",0x1), 0x80AAEFF0:("Dm_Char07_InitVars","UNK_TYPE1","",0x1), 0x80AB1370:("Dm_Char08_InitVars","UNK_TYPE1","",0x1), - 0x80AB1390:("D_80AB1390","UNK_TYPE1","",0x1), - 0x80AB1398:("D_80AB1398","UNK_TYPE1","",0x1), - 0x80AB13A0:("D_80AB13A0","UNK_TYPE1","",0x1), - 0x80AB14D0:("D_80AB14D0","UNK_TYPE1","",0x1), - 0x80AB1600:("D_80AB1600","UNK_TYPE2","",0x2), - 0x80AB1648:("D_80AB1648","UNK_TYPE2","",0x2), - 0x80AB1690:("D_80AB1690","UNK_TYPE1","",0x1), + 0x80AB1390:("D_80AB1390","CamData","",0x8), + 0x80AB1398:("D_80AB1398","SurfaceType","",0x8), + 0x80AB13A0:("D_80AB13A0","CollisionPoly","19",0xCC), + 0x80AB14D0:("sTurtleGreatBayTempleColPolygons2","CollisionPoly[]","19",0xCC), + 0x80AB1600:("D_80AB1600","Vec3s[]","12",0x48), + 0x80AB1648:("D_80AB1648","Vec3s[]","12",0x48), + 0x80AB1690:("sTurtleGreatBayTempleCol","CollisionHeader","",0x2C), 0x80AB16A8:("D_80AB16A8","UNK_PTR","",0x4), - 0x80AB16BC:("D_80AB16BC","UNK_TYPE1","",0x1), - 0x80AB1764:("D_80AB1764","UNK_TYPE1","",0x1), - 0x80AB1770:("D_80AB1770","UNK_TYPE2","",0x2), - 0x80AB1774:("D_80AB1774","UNK_TYPE1","",0x1), - 0x80AB1778:("D_80AB1778","UNK_TYPE1","",0x1), - 0x80AB177C:("D_80AB177C","UNK_TYPE4","",0x4), - 0x80AB1788:("D_80AB1788","UNK_TYPE1","",0x1), + 0x80AB16BC:("sLargeTurtleAnimationInfo","AnimationInfo[]","0x7",0xE0), + 0x80AB1764:("sInitChain","InitChainEntry","",0x1), + 0x80AB1770:("D_80AB1770","s16","",0x2), + 0x80AB1774:("sLargeTurtleBubblePrimColor","Color_RGBA8","",0x4), + 0x80AB1778:("sLargeTurtleBubbleEnvColor","Color_RGBA8","",0x4), + 0x80AB177C:("sLargeTurtleBubbelAccel","Vec3f","",0xC), + 0x80AB1788:("sLargeTurtleEyeTextures","TexturePtr","9",0x1), 0x80AB17B0:("jtbl_80AB17B0","UNK_PTR","",0x4), 0x80AB17C8:("D_80AB17C8","f32","",0x4), 0x80AB17CC:("D_80AB17CC","f32","",0x4), @@ -14305,7 +14305,7 @@ 0x80B3FE50:("D_80B3FE50","f32","",0x4), 0x80B3FE54:("D_80B3FE54","f32","",0x4), 0x80B3FE58:("D_80B3FE58","UNK_TYPE1","",0x1), - 0x80B3FE70:("D_80B3FE70","UNK_TYPE1","",0x1), + 0x80B3FE70:("sEyeTextures","TexturePtr[]","0x9",0x4), 0x80B3FE90:("D_80B3FE90","f32","",0x4), 0x80B3FE94:("D_80B3FE94","f32","",0x4), 0x80B40760:("Bg_Goron_Oyu_InitVars","UNK_TYPE1","",0x1), diff --git a/tools/namefixer.py b/tools/namefixer.py index a5d13493b..4f596ecef 100755 --- a/tools/namefixer.py +++ b/tools/namefixer.py @@ -597,7 +597,7 @@ wordReplace = { "func_80158C04": "Message_LoadLocalizedRupeesNES", "func_80158D98": "Message_LoadRupeesNES", "func_80158FB0": "Message_LoadTimeNES", - "func_8015926C": "Message_LoadAreaTextNES", + "func_8015926C": "Message_LoadOwlWarpTextNES", "func_8015E750": "Message_FindCreditsMessage", "func_80133038": "Schedule_RunScript", diff --git a/tools/permuter_settings.toml b/tools/permuter_settings.toml index bf61be341..380acbfc2 100644 --- a/tools/permuter_settings.toml +++ b/tools/permuter_settings.toml @@ -1,3 +1,5 @@ +compiler_type = "ido" + [preserve_macros] "g[DS]P.*" = "void" "gs[DS]P.*" = "void" diff --git a/tools/sizes/code_functions.csv b/tools/sizes/code_functions.csv index acec92239..d18b02616 100644 --- a/tools/sizes/code_functions.csv +++ b/tools/sizes/code_functions.csv @@ -1924,7 +1924,7 @@ asm/non_matchings/code/code_8012EC80/Inventory_ChangeEquipment.s,Inventory_Chang asm/non_matchings/code/code_8012EC80/Inventory_DeleteEquipment.s,Inventory_DeleteEquipment,0x8012ED78,0x1C asm/non_matchings/code/code_8012EC80/Inventory_ChangeUpgrade.s,Inventory_ChangeUpgrade,0x8012EDE8,0x13 asm/non_matchings/code/code_8012EC80/Inventory_IsMapVisible.s,Inventory_IsMapVisible,0x8012EE34,0x36 -asm/non_matchings/code/code_8012EC80/Inventory_SetMapVisibility.s,Inventory_SetMapVisibility,0x8012EF0C,0x78 +asm/non_matchings/code/code_8012EC80/Inventory_SetWorldMapCloudVisibility.s,Inventory_SetWorldMapCloudVisibility,0x8012EF0C,0x78 asm/non_matchings/code/code_8012EC80/Inventory_SaveDekuPlaygroundHighScore.s,Inventory_SaveDekuPlaygroundHighScore,0x8012F0EC,0x34 asm/non_matchings/code/code_8012EC80/Inventory_IncrementSkullTokenCount.s,Inventory_IncrementSkullTokenCount,0x8012F1BC,0x1C asm/non_matchings/code/code_8012EC80/Inventory_GetSkullTokenCount.s,Inventory_GetSkullTokenCount,0x8012F22C,0x13 @@ -1966,7 +1966,7 @@ asm/non_matchings/code/z_scene/Scene_HeaderCmdActorCutsceneList.s,Scene_HeaderCm asm/non_matchings/code/z_scene/Scene_HeaderCmdMiniMap.s,Scene_HeaderCmdMiniMap,0x80130540,0xE asm/non_matchings/code/z_scene/Scene_HeaderCmd1D.s,Scene_HeaderCmd1D,0x80130578,0x4 asm/non_matchings/code/z_scene/Scene_HeaderCmdMiniMapCompassInfo.s,Scene_HeaderCmdMiniMapCompassInfo,0x80130588,0xA -asm/non_matchings/code/z_scene/Scene_HeaderCmdSetAreaVisitedFlag.s,Scene_HeaderCmdSetAreaVisitedFlag,0x801305B0,0x31 +asm/non_matchings/code/z_scene/Scene_HeaderCmdSetRegionVisitedFlag.s,Scene_HeaderCmdSetRegionVisitedFlag,0x801305B0,0x31 asm/non_matchings/code/z_scene/Scene_HeaderCmdAnimatedMaterials.s,Scene_HeaderCmdAnimatedMaterials,0x80130674,0xC asm/non_matchings/code/z_scene/Scene_SetExitFade.s,Scene_SetExitFade,0x801306A4,0x11 asm/non_matchings/code/z_scene/Scene_ProcessHeader.s,Scene_ProcessHeader,0x801306E8,0x20 @@ -2394,7 +2394,7 @@ asm/non_matchings/code/z_message_nes/Message_LoadPluralRupeesNES.s,Message_LoadP asm/non_matchings/code/z_message_nes/Message_LoadLocalizedRupeesNES.s,Message_LoadLocalizedRupeesNES,0x80158C04,0x65 asm/non_matchings/code/z_message_nes/Message_LoadRupeesNES.s,Message_LoadRupeesNES,0x80158D98,0x86 asm/non_matchings/code/z_message_nes/Message_LoadTimeNES.s,Message_LoadTimeNES,0x80158FB0,0xAF -asm/non_matchings/code/z_message_nes/Message_LoadAreaTextNES.s,Message_LoadAreaTextNES,0x8015926C,0x73 +asm/non_matchings/code/z_message_nes/Message_LoadOwlWarpTextNES.s,Message_LoadOwlWarpTextNES,0x8015926C,0x73 asm/non_matchings/code/z_message_nes/func_80159438.s,func_80159438,0x80159438,0x8D asm/non_matchings/code/z_message_nes/func_8015966C.s,func_8015966C,0x8015966C,0x6CB asm/non_matchings/code/z_message_nes/func_8015B198.s,func_8015B198,0x8015B198,0xD6E