summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorinspectredc <78732756+inspectredc@users.noreply.github.com>2024-04-16 20:31:29 +0100
committerGitHub <noreply@github.com>2024-04-16 12:31:29 -0700
commite6ea51bc3dcf69310c5dcdae5b812dc74e628aaf (patch)
tree406fc1756035e49f5c5252058b949ba5809e9833
parent7f426967efd07046bfbe791ed4e64808ae5a26e2 (diff)
ac_Fuusen OK and documented (#174)
* ac_Fuusen OK and documented * add struct offsets * use null post merge * fix sym stuff * suggestions * act_balloon extracted * remove fake symbol * name object enum * include assets * fgname enum/macro
-rw-r--r--include/683030.h4
-rw-r--r--include/code_variables.h2
-rw-r--r--include/m_actor.h1
-rw-r--r--include/m_clip.h5
-rw-r--r--include/m_collision_bg.h2
-rw-r--r--include/m_field_info.h4
-rw-r--r--include/m_handbill.h4
-rw-r--r--include/m_kankyo.h4
-rw-r--r--include/m_player_lib.h4
-rw-r--r--include/tables/dmatables/dmadata_table_jp.h2
-rw-r--r--include/tables/object_table.h2
-rw-r--r--linker_scripts/jp/ignored_addresses.txt2
-rw-r--r--linker_scripts/jp/symbol_addrs_assets.txt14
-rw-r--r--linker_scripts/jp/symbol_addrs_code.txt24
-rw-r--r--linker_scripts/jp/symbol_addrs_overlays.txt39
-rw-r--r--linker_scripts/jp/undefined_syms.ld8
-rw-r--r--src/code/m_field_info.c4
-rw-r--r--src/objects/act_balloon/act_balloon.c19
-rw-r--r--src/objects/act_balloon/act_balloon.h21
-rw-r--r--src/overlays/actors/ovl_Fuusen/ac_fuusen.c452
-rw-r--r--src/overlays/actors/ovl_Fuusen/ac_fuusen.h34
-rw-r--r--src/overlays/gamestates/ovl_play/m_play.h2
-rw-r--r--yamls/jp/assets.yaml27
-rw-r--r--yamls/jp/overlays.yaml2
24 files changed, 604 insertions, 78 deletions
diff --git a/include/683030.h b/include/683030.h
index a20a1c3..8e0cf17 100644
--- a/include/683030.h
+++ b/include/683030.h
@@ -48,9 +48,9 @@ xyz_t* Camera2_getCenterPos_p(void);
// void func_800608F0_jp();
// void func_80060904_jp();
// void func_80060918_jp();
-// void func_80060970_jp();
+s32 Camera2_CheckCullingMode(void);
// void func_80060A6C_jp();
-// void func_80060B18_jp();
+s32 Camera2_CheckEnterCullingArea(f32, f32, f32);
void Camera2_ClearActorTalking_Cull(struct Game_Play* game_play);
// void func_80060D1C_jp();
// void func_80060D58_jp();
diff --git a/include/code_variables.h b/include/code_variables.h
index 68794be..ef7a780 100644
--- a/include/code_variables.h
+++ b/include/code_variables.h
@@ -459,7 +459,7 @@ extern s32 CanLookGokiCount;
// extern UNK_TYPE D_80106D78_jp;
// extern UNK_TYPE D_80106D8C_jp;
// extern UNK_TYPE D_80106DA0_jp;
-// extern UNK_TYPE D_80106E10_jp;
+extern s32 fuusen_DEBUG_mode_flag;
// extern UNK_TYPE D_80107010_jp;
// extern UNK_TYPE D_80107020_jp;
diff --git a/include/m_actor.h b/include/m_actor.h
index bb52865..0096964 100644
--- a/include/m_actor.h
+++ b/include/m_actor.h
@@ -6,6 +6,7 @@
#include "m_collision_bg.h"
#include "z64math.h"
#include "unk.h"
+#include "m_collision_bg.h"
struct Actor;
struct Game_Play;
diff --git a/include/m_clip.h b/include/m_clip.h
index 844ee70..69c34d1 100644
--- a/include/m_clip.h
+++ b/include/m_clip.h
@@ -86,10 +86,15 @@ typedef struct Clip_unk_070 {
typedef UNK_RET (*Clip_unk_074_unk_00)(UNK_TYPE);
typedef void (*Clip_unk_074_unk_04)(struct Game_Play* game_play, struct ShadowData* shadowData, s16 unk2);
+typedef void (*Clip_unk_074_unk_30)(UNK_TYPE, UNK_TYPE, UNK_TYPE, UNK_TYPE);
typedef struct Clip_unk_074 {
/* 0x00 */ Clip_unk_074_unk_00 unk_00;
/* 0x04 */ Clip_unk_074_unk_04 unk_04;
+ /* 0x08 */ UNK_TYPE1 unk_08[0x28];
+ /* 0x30 */ Clip_unk_074_unk_30 unk_30;
+ /* 0x34 */ UNK_TYPE1 unk_34[0x4];
+ /* 0x38 */ s32 unk_38;
} Clip_unk_074; // size >= 0x8
typedef void (*Clip_unk_07C_unk_4)(struct ObjectExchangeBank*);
diff --git a/include/m_collision_bg.h b/include/m_collision_bg.h
index c3463b6..6080ba5 100644
--- a/include/m_collision_bg.h
+++ b/include/m_collision_bg.h
@@ -248,7 +248,7 @@ s32 func_8007244C_jp(u32);
// void func_80072C60_jp();
s32 mCoBG_SearchWaterLimitDistN(UNK_TYPE* arg0, xyz_t arg1, s16 arg4, f32 arg5, s32 arg6);
// void func_80072E70_jp();
-// void func_80072F9C_jp();
+f32 mCoBG_GetBalloonGroundY(xyz_t*);
// void func_800730C8_jp();
// void func_800731A8_jp();
// void func_800732DC_jp();
diff --git a/include/m_field_info.h b/include/m_field_info.h
index e2b4e5e..b47d9f4 100644
--- a/include/m_field_info.h
+++ b/include/m_field_info.h
@@ -57,9 +57,9 @@ s32 mFI_GetBlockZMax(void);
// void func_800882AC_jp();
// void func_800882FC_jp();
// void func_80088320_jp();
-// void func_80088344_jp();
+s32 mFI_Wpos2UtNum(s32*, s32*, xyz_t);
// void func_80088458_jp();
-// void func_800884E0_jp();
+s32 mFI_Wpos2UtCenterWpos(xyz_t*, xyz_t);
// void func_800885A8_jp();
s32 mFI_Wpos2BlockNum(s32*, s32*, xyz_t);
s32 mFI_Wpos2BkandUtNuminBlock(s32*,s32*, s32* ,s32* ,xyz_t);
diff --git a/include/m_handbill.h b/include/m_handbill.h
index 7bf4641..fe15111 100644
--- a/include/m_handbill.h
+++ b/include/m_handbill.h
@@ -26,8 +26,8 @@ typedef struct HandbillzInfo {
//TODO: move these out of the handbill header
void Balloon_init(struct Game_Play* game_play);
void Balloon_move(struct Game_Play* game_play);
-// void func_80092B7C_jp();
-// void func_80092B8C_jp();
+void Balloon_kill(void);
+void Balloon_look_up(void);
// void func_80092BA0_jp();
// void func_80092BE8_jp();
void mHsRm_GetHuusuiRoom(struct Game* game_play, s32 player_no);
diff --git a/include/m_kankyo.h b/include/m_kankyo.h
index b640d21..109586e 100644
--- a/include/m_kankyo.h
+++ b/include/m_kankyo.h
@@ -61,8 +61,8 @@ void Global_kankyo_set(struct Game_Play* game_play, struct Kankyo* kankyo, struc
void mEnv_DecideWindDirect(struct s_xyz*, s16,s16);
// void func_8009867C_jp();
void mEnv_RandomWeather(s16*, s16*);
-// void func_8009895C_jp();
-// void func_80098980_jp();
+s16 mEnv_GetWindAngleS(void);
+f32 mEnv_GetWindPowerF(void);
// void func_80098990_jp();
// void func_80098A90_jp();
void mEnv_WindMove(void);
diff --git a/include/m_player_lib.h b/include/m_player_lib.h
index acdffe9..d0a5ab7 100644
--- a/include/m_player_lib.h
+++ b/include/m_player_lib.h
@@ -165,8 +165,8 @@ void func_800B594C_jp(void);
// void func_800B5AB8_jp();
// void func_800B5B1C_jp();
// void func_800B5B70_jp();
-// void func_800B5BC0_jp();
-// void func_800B5C10_jp();
+s32 mPlib_Check_tree_shaken_little(xyz_t*);
+s32 mPlib_Check_tree_shaken_big(xyz_t*);
// void func_800B5C60_jp();
// void func_800B5CD4_jp();
// void func_800B5D34_jp();
diff --git a/include/tables/dmatables/dmadata_table_jp.h b/include/tables/dmatables/dmadata_table_jp.h
index dc07943..9528409 100644
--- a/include/tables/dmatables/dmadata_table_jp.h
+++ b/include/tables/dmatables/dmadata_table_jp.h
@@ -2307,7 +2307,7 @@ DEFINE_DMA_ENTRY(segment_011F1000, "segment_011F1000")
DEFINE_DMA_ENTRY(segment_011F2000, "segment_011F2000")
DEFINE_DMA_ENTRY(segment_011F3000, "segment_011F3000")
DEFINE_DMA_ENTRY(object_011F4000, "object_011F4000")
-DEFINE_DMA_ENTRY(object_011F5000, "object_011F5000")
+DEFINE_DMA_ENTRY(act_balloon, "act_balloon")
DEFINE_DMA_ENTRY(segment_011F6000, "segment_011F6000")
DEFINE_DMA_ENTRY(segment_011F8000, "segment_011F8000")
DEFINE_DMA_ENTRY(segment_011FA000, "segment_011FA000")
diff --git a/include/tables/object_table.h b/include/tables/object_table.h
index ee4f5fb..3ae62d5 100644
--- a/include/tables/object_table.h
+++ b/include/tables/object_table.h
@@ -410,7 +410,7 @@
/* 0x18D */ DEFINE_OBJECT(object_00F48000, OBJECT_397)
/* 0x18E */ DEFINE_OBJECT(object_00FD6000, OBJECT_398)
/* 0x18F */ DEFINE_OBJECT(object_00FD9000, OBJECT_399)
-/* 0x190 */ DEFINE_OBJECT(object_011F5000, OBJECT_400)
+/* 0x190 */ DEFINE_OBJECT(act_balloon, OBJECT_ACT_BALLOON)
/* 0x191 */ DEFINE_OBJECT_UNSET(OBJECT_UNSET_401)
/* 0x192 */ DEFINE_OBJECT_UNSET(OBJECT_UNSET_402)
/* 0x193 */ DEFINE_OBJECT_UNSET(OBJECT_UNSET_403)
diff --git a/linker_scripts/jp/ignored_addresses.txt b/linker_scripts/jp/ignored_addresses.txt
index f6d2388..0069d07 100644
--- a/linker_scripts/jp/ignored_addresses.txt
+++ b/linker_scripts/jp/ignored_addresses.txt
@@ -43,4 +43,6 @@ D_6000140 = 0x06000140; // ignore:true
D_6000180 = 0x06000180; // ignore:true
D_6000220 = 0x06000220; // ignore:true
D_60003E8 = 0x060003E8; // ignore:true
+D_6000E78 = 0x06000E78; // ignore:true
+D_6000F58 = 0x06000F58; // ignore:true
D_6001B68 = 0x06001B68; // ignore:true
diff --git a/linker_scripts/jp/symbol_addrs_assets.txt b/linker_scripts/jp/symbol_addrs_assets.txt
index 9b11c49..eb5401a 100644
--- a/linker_scripts/jp/symbol_addrs_assets.txt
+++ b/linker_scripts/jp/symbol_addrs_assets.txt
@@ -1209,3 +1209,17 @@ tol_hata_01_evw_anime_1_anime_ptn = 0x60003D4; // segment:tol_hata_01 rom:0x1130
tol_hata_01_evw_anime_1 = 0x60003D8; // segment:tol_hata_01 rom:0x11303D8
tol_hata_01_evw_anime_2 = 0x60003E8; // segment:tol_hata_01 rom:0x11303E8
tol_hata_01_evw_anime = 0x60003F0; // segment:tol_hata_01 rom:0x11303F0
+
+act_balloon_v = 0x6000000; // segment:act_balloon rom:0x11F5000 size:0x340
+act_balloon_head_model = 0x6000340; // segment:act_balloon rom:0x11F5340
+act_balloon_wireB_model = 0x6000450; // segment:act_balloon rom:0x11F5450
+act_balloon_wireA_model = 0x6000560; // segment:act_balloon rom:0x11F5560
+act_balloon_wire_tex_txt = 0x60005F8; // segment:act_balloon rom:0x11F55F8
+act_balloon_head_tex_rgb_ia16 = 0x6000678; // segment:act_balloon rom:0x11F5678
+cKF_ckcb_r_act_balloon_tbl = 0x60000E78; // segment:act_balloon rom:0x11F5E78
+cKF_kn_act_balloon_tbl = 0x60000E7C; // segment:act_balloon rom:0x11F5E7C
+cKF_c_act_balloon_tbl = 0x60000E88; // segment:act_balloon rom:0x11F5E88
+cKF_ds_act_balloon_tbl = 0x60000E9C; // segment:act_balloon rom:0x11F5E9C
+cKF_ba_r_act_balloon = 0x60000F44; // segment:act_balloon rom:0x11F5F44
+cKF_je_r_act_balloon_tbl = 0x60000F58; // segment:act_balloon rom:0x11F5F58
+cKF_bs_r_act_balloon = 0x60000F88; // segment:act_balloon rom:0x11F5F88
diff --git a/linker_scripts/jp/symbol_addrs_code.txt b/linker_scripts/jp/symbol_addrs_code.txt
index 8acac57..7e3a3f1 100644
--- a/linker_scripts/jp/symbol_addrs_code.txt
+++ b/linker_scripts/jp/symbol_addrs_code.txt
@@ -382,9 +382,9 @@ Camera2_getCenterPos_p = 0x800608DC; // type:func
func_800608F0_jp = 0x800608F0; // type:func
func_80060904_jp = 0x80060904; // type:func
func_80060918_jp = 0x80060918; // type:func
-func_80060970_jp = 0x80060970; // type:func
+Camera2_CheckCullingMode = 0x80060970; // type:func
func_80060A6C_jp = 0x80060A6C; // type:func
-func_80060B18_jp = 0x80060B18; // type:func
+Camera2_CheckEnterCullingArea = 0x80060B18; // type:func
Camera2_ClearActorTalking_Cull = 0x80060CDC; // type:func
func_80060D1C_jp = 0x80060D1C; // type:func
func_80060D58_jp = 0x80060D58; // type:func
@@ -799,7 +799,7 @@ func_80072BE8_jp = 0x80072BE8; // type:func
func_80072C60_jp = 0x80072C60; // type:func
mCoBG_SearchWaterLimitDistN = 0x80072CC4; // type:func
func_80072E70_jp = 0x80072E70; // type:func
-func_80072F9C_jp = 0x80072F9C; // type:func
+mCoBG_GetBalloonGroundY = 0x80072F9C; // type:func
func_800730C8_jp = 0x800730C8; // type:func
func_800731A8_jp = 0x800731A8; // type:func
func_800732DC_jp = 0x800732DC; // type:func
@@ -1314,9 +1314,9 @@ func_80088270_jp = 0x80088270; // type:func
func_800882AC_jp = 0x800882AC; // type:func
func_800882FC_jp = 0x800882FC; // type:func
func_80088320_jp = 0x80088320; // type:func
-func_80088344_jp = 0x80088344; // type:func
+mFI_Wpos2UtNum = 0x80088344; // type:func
func_80088458_jp = 0x80088458; // type:func
-func_800884E0_jp = 0x800884E0; // type:func
+mFI_Wpos2UtCenterWpos = 0x800884E0; // type:func
func_800885A8_jp = 0x800885A8; // type:func
mFI_Wpos2BlockNum = 0x80088710; // type:func
mFI_Wpos2BkandUtNuminBlock = 0x80088780; // type:func
@@ -1590,8 +1590,8 @@ func_80092538_jp = 0x80092538; // type:func
mFont_UnintToString = 0x8009264C; // type:func
Balloon_init = 0x800928C0; // type:func
Balloon_move = 0x800928E8; // type:func
-func_80092B7C_jp = 0x80092B7C; // type:func
-func_80092B8C_jp = 0x80092B8C; // type:func
+Balloon_kill = 0x80092B7C; // type:func
+Balloon_look_up = 0x80092B8C; // type:func
func_80092BA0_jp = 0x80092BA0; // type:func
func_80092BE8_jp = 0x80092BE8; // type:func
mHsRm_GetHuusuiRoom = 0x80092C2C; // type:func
@@ -1739,8 +1739,8 @@ Global_kankyo_set = 0x800984CC; // type:func
mEnv_DecideWindDirect = 0x80098558; // type:func
func_8009867C_jp = 0x8009867C; // type:func
mEnv_RandomWeather = 0x80098794; // type:func
-func_8009895C_jp = 0x8009895C; // type:func
-func_80098980_jp = 0x80098980; // type:func
+mEnv_GetWindAngleS = 0x8009895C; // type:func
+mEnv_GetWindPowerF = 0x80098980; // type:func
func_80098990_jp = 0x80098990; // type:func
func_80098A90_jp = 0x80098A90; // type:func
mEnv_WindMove = 0x80098B50; // type:func
@@ -2660,8 +2660,8 @@ func_800B5AA0_jp = 0x800B5AA0; // type:func
func_800B5AB8_jp = 0x800B5AB8; // type:func
func_800B5B1C_jp = 0x800B5B1C; // type:func
func_800B5B70_jp = 0x800B5B70; // type:func
-func_800B5BC0_jp = 0x800B5BC0; // type:func
-func_800B5C10_jp = 0x800B5C10; // type:func
+mPlib_Check_tree_shaken_little = 0x800B5BC0; // type:func
+mPlib_Check_tree_shaken_big = 0x800B5C10; // type:func
func_800B5C60_jp = 0x800B5C60; // type:func
func_800B5CD4_jp = 0x800B5CD4; // type:func
func_800B5D34_jp = 0x800B5D34; // type:func
@@ -4639,7 +4639,7 @@ D_80106D64_jp = 0x80106D64; //
D_80106D78_jp = 0x80106D78; //
D_80106D8C_jp = 0x80106D8C; //
D_80106DA0_jp = 0x80106DA0; //
-D_80106E10_jp = 0x80106E10; //
+fuusen_DEBUG_mode_flag = 0x80106E10; //
game_dlftbls = 0x80106E20; // type:GameStateOverlay size:0x1E0
game_dlftbls_num = 0x80107000; // size:0x4
diff --git a/linker_scripts/jp/symbol_addrs_overlays.txt b/linker_scripts/jp/symbol_addrs_overlays.txt
index cb67799..079ea80 100644
--- a/linker_scripts/jp/symbol_addrs_overlays.txt
+++ b/linker_scripts/jp/symbol_addrs_overlays.txt
@@ -21577,15 +21577,15 @@ D_80AAD064_jp = 0x80AAD064; //
aFSN_actor_ct = 0x80AAD0E0; // type:func
aFSN_actor_dt = 0x80AAD230; // type:func
-func_80AAD270_jp = 0x80AAD270; // type:func
-func_80AAD490_jp = 0x80AAD490; // type:func
-func_80AAD4A0_jp = 0x80AAD4A0; // type:func
-func_80AAD4DC_jp = 0x80AAD4DC; // type:func
-func_80AAD580_jp = 0x80AAD580; // type:func
-func_80AAD5A4_jp = 0x80AAD5A4; // type:func
-func_80AADB9C_jp = 0x80AADB9C; // type:func
-func_80AADDA8_jp = 0x80AADDA8; // type:func
-func_80AADEC4_jp = 0x80AADEC4; // type:func
+aFSN_birth_init = 0x80AAD270; // type:func
+aFSN_moving_init = 0x80AAD490; // type:func
+aFSN_wood_stop_init = 0x80AAD4A0; // type:func
+aFSN_escape_init = 0x80AAD4DC; // type:func
+aFSN_birth = 0x80AAD580; // type:func
+aFSN_moving = 0x80AAD5A4; // type:func
+aFSN_wood_stop = 0x80AADB9C; // type:func
+aFSN_escape = 0x80AADDA8; // type:func
+aFSN_setupAction = 0x80AADEC4; // type:func
func_80AADF10_jp = 0x80AADF10; // type:func
aFSN_actor_move = 0x80AADF9C; // type:func
func_80AAE10C_jp = 0x80AAE10C; // type:func
@@ -21594,17 +21594,16 @@ aFSN_actor_draw = 0x80AAE198; // type:func
// .data
Fuusen_Profile = 0x80AAE4B0; //
-D_80AAE4D4_jp = 0x80AAE4D4; //
-D_80AAE4E0_jp = 0x80AAE4E0; //
-D_80AAE520_jp = 0x80AAE520; //
-D_FLT_80AAE580_jp = 0x80AAE580; // type:f32
-D_FLT_80AAE588_jp = 0x80AAE588; // type:f32
-D_80AAE5E0_jp = 0x80AAE5E0; // type:u8
-D_80AAE5F4_jp = 0x80AAE5F4; // type:u8
-D_80AAE608_jp = 0x80AAE608; // type:s16
-D_80AAE614_jp = 0x80AAE614; //
-D_80AAE624_jp = 0x80AAE624; //
-D_80AAE634_jp = 0x80AAE634; //
+Init_Size = 0x80AAE4D4; //
+data_index_data = 0x80AAE4E0; //
+birth_pos_data = 0x80AAE520; //
+birth_pos_random_data = 0x80AAE580; // type:f32
+balloon_prim_data = 0x80AAE5E0; // type:u8
+balloon_env_data = 0x80AAE5F4; // type:u8
+senkou_check_data = 0x80AAE608; // type:s16
+init_proc = 0x80AAE614; //
+act_proc = 0x80AAE624; //
+offset0 = 0x80AAE634; //
// .rodata
diff --git a/linker_scripts/jp/undefined_syms.ld b/linker_scripts/jp/undefined_syms.ld
index d008fe5..f9af915 100644
--- a/linker_scripts/jp/undefined_syms.ld
+++ b/linker_scripts/jp/undefined_syms.ld
@@ -5556,10 +5556,10 @@ D_6000D50 = 0x06000D50;
// ovl_Fuusen
-D_4009580 = 0x04009580;
-D_4009620 = 0x04009620;
-D_6000F44 = 0x06000F44;
-D_6000F88 = 0x06000F88;
+present_DL_mode = 0x04009580;
+present_DL_vtx = 0x04009620;
+cKF_ba_r_act_balloon = 0x06000F44;
+cKF_bs_r_act_balloon = 0x06000F88;
// ovl__0096E8E0
diff --git a/src/code/m_field_info.c b/src/code/m_field_info.c
index e48824d..c54b60a 100644
--- a/src/code/m_field_info.c
+++ b/src/code/m_field_info.c
@@ -41,11 +41,11 @@
#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/func_80088320_jp.s")
-#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/func_80088344_jp.s")
+#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/mFI_Wpos2UtNum.s")
#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/func_80088458_jp.s")
-#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/func_800884E0_jp.s")
+#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/mFI_Wpos2UtCenterWpos.s")
#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/func_800885A8_jp.s")
diff --git a/src/objects/act_balloon/act_balloon.c b/src/objects/act_balloon/act_balloon.c
new file mode 100644
index 0000000..3a7e46d
--- /dev/null
+++ b/src/objects/act_balloon/act_balloon.c
@@ -0,0 +1,19 @@
+#include "act_balloon.h"
+
+#include "assets/jp/objects/act_balloon/act_balloon_v.vtx.inc.c"
+#include "assets/jp/objects/act_balloon/act_balloon_head_model.gfx.inc.c"
+#include "assets/jp/objects/act_balloon/act_balloon_wireB_model.gfx.inc.c"
+#include "assets/jp/objects/act_balloon/act_balloon_wireA_model.gfx.inc.c"
+u8 act_balloon_wire_tex_txt[] = {
+#include "assets/jp/objects/act_balloon/act_balloon_wire_tex_txt.i4.inc.c"
+};
+u16 act_balloon_head_tex_rgb_ia16[] = {
+#include "assets/jp/objects/act_balloon/act_balloon_head_tex_rgb_ia16.ia16.inc.c"
+};
+#include "assets/jp/objects/act_balloon/cKF_ckcb_r_act_balloon_tbl.inc.c"
+#include "assets/jp/objects/act_balloon/cKF_kn_act_balloon_tbl.inc.c"
+#include "assets/jp/objects/act_balloon/cKF_c_act_balloon_tbl.inc.c"
+#include "assets/jp/objects/act_balloon/cKF_ds_act_balloon_tbl.inc.c"
+#include "assets/jp/objects/act_balloon/cKF_ba_r_act_balloon.inc.c"
+#include "assets/jp/objects/act_balloon/cKF_je_r_act_balloon_tbl.inc.c"
+#include "assets/jp/objects/act_balloon/cKF_bs_r_act_balloon.inc.c"
diff --git a/src/objects/act_balloon/act_balloon.h b/src/objects/act_balloon/act_balloon.h
new file mode 100644
index 0000000..a3ff00b
--- /dev/null
+++ b/src/objects/act_balloon/act_balloon.h
@@ -0,0 +1,21 @@
+#ifndef OBJECT_ACT_BALLOON_H
+#define OBJECT_ACT_BALLOON_H
+
+#include "gbi.h"
+#include "c_keyframe.h"
+
+extern Vtx act_balloon_v[];
+extern Gfx act_balloon_head_model[];
+extern Gfx act_balloon_wireB_model[];
+extern Gfx act_balloon_wireA_model[];
+extern u8 act_balloon_wire_tex_txt[];
+extern u16 act_balloon_head_tex_rgb_ia16[];
+extern u8 cKF_ckcb_r_act_balloon_tbl[];
+extern s16 cKF_kn_act_balloon_tbl[];
+extern s16 cKF_c_act_balloon_tbl[];
+extern Keyframe cKF_ds_act_balloon_tbl[];
+extern BaseAnimationR cKF_ba_r_act_balloon;
+extern JointElemR cKF_je_r_act_balloon_tbl[];
+extern BaseSkeletonR cKF_bs_r_act_balloon;
+
+#endif
diff --git a/src/overlays/actors/ovl_Fuusen/ac_fuusen.c b/src/overlays/actors/ovl_Fuusen/ac_fuusen.c
index ff4c632..16c8424 100644
--- a/src/overlays/actors/ovl_Fuusen/ac_fuusen.c
+++ b/src/overlays/actors/ovl_Fuusen/ac_fuusen.c
@@ -1,20 +1,37 @@
#include "ac_fuusen.h"
#include "m_actor_dlftbls.h"
+#include "m_actor_shadow.h"
#include "m_object.h"
#include "overlays/gamestates/ovl_play/m_play.h"
+#include "overlays/actors/player_actor/m_player.h"
+#include "libc/math.h"
+#include "macros.h"
+#include "m_handbill.h"
+#include "m_field_info.h"
+#include "m_debug_display.h"
+#include "m_player_lib.h"
+#include "m_rcp.h"
+#include "683030.h"
+#include "audio.h"
+#include "code_variables.h"
+#include "m_name_table.h"
+
+#include "objects/act_balloon/act_balloon.h"
+
+#define THIS ((Fuusen*)thisx)
void aFSN_actor_ct(Actor* thisx, Game_Play* game_play);
void aFSN_actor_dt(Actor* thisx, Game_Play* game_play);
void aFSN_actor_move(Actor* thisx, Game_Play* game_play);
void aFSN_actor_draw(Actor* thisx, Game_Play* game_play);
+void aFSN_setupAction(Fuusen*, s32, Game_Play*);
-#if 0
ActorProfile Fuusen_Profile = {
/* */ ACTOR_FUUSEN,
/* */ ACTOR_PART_7,
/* */ ACTOR_FLAG_10,
/* */ 0x0000,
- /* */ OBJECT_400,
+ /* */ OBJECT_ACT_BALLOON,
/* */ sizeof(Fuusen),
/* */ aFSN_actor_ct,
/* */ aFSN_actor_dt,
@@ -22,34 +39,433 @@ ActorProfile Fuusen_Profile = {
/* */ aFSN_actor_draw,
/* */ NULL,
};
-#endif
-#pragma GLOBAL_ASM("asm/jp/nonmatchings/overlays/actors/ovl_Fuusen/ac_fuusen/aFSN_actor_ct.s")
+void aFSN_actor_ct(Actor* thisx, Game_Play* game_play) {
+ static xyz_t Init_Size = { 0.01f, 0.01f, 0.01f };
+ Fuusen* this = THIS;
+ SkeletonInfoR* skeletonInfo = &this->skeletonInfo;
+ xyz_t size = Init_Size;
+ f32 balloonGroundY = mCoBG_GetBalloonGroundY(&this->actor.world.pos);
+
+ this->escapeTimer = 1000;
+ cKF_SkeletonInfo_R_ct(skeletonInfo, &cKF_bs_r_act_balloon, &cKF_ba_r_act_balloon, this->jointTable,
+ this->morphTable);
+ cKF_SkeletonInfo_R_init_standard_repeat(skeletonInfo, Lib_SegmentedToVirtual(&cKF_ba_r_act_balloon), NULL);
+ Shape_Info_init(&this->actor, 0.0f, mAc_ActorShadowCircle, 10.0f, 10.0f);
+ this->actor.shape.drawShadow = 0;
+ cKF_SkeletonInfo_R_play(skeletonInfo);
+ skeletonInfo->frameControl.speed = 1.0f;
+ xyz_t_move(&this->actor.scale, &size);
+ this->actor.world.pos.y = balloonGroundY + 200.0f;
+ this->heightOffset = 110.0f;
+ this->segment = game_play->objectExchangeBank.status[this->actor.unk_026].segment;
+ this->actor.update = aFSN_actor_move;
+ aFSN_setupAction(this, FSN_PROCESS_BIRTH, game_play);
+}
+
+void aFSN_actor_dt(Actor* thisx, UNUSED Game_Play* game_play) {
+ Fuusen* this = THIS;
+
+ if (this->shouldLookUp) {
+ Balloon_look_up();
+ } else {
+ Balloon_kill();
+ }
+}
+
+void aFSN_birth_init(Fuusen* this, Game_Play* game_play) {
+ static s32 data_index_data[16] = {
+ 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 0,
+ };
+ static xyz_t birth_pos_data[8] = {
+ { 1600.0f, 100.0f, 500.0f }, { 500.0f, 100.0f, 500.0f }, { 500.0f, 100.0f, 1600.0f },
+ { 500.0f, 100.0f, 4620.0f }, { 1600.0f, 100.0f, 4620.0f }, { 3980.0f, 100.0f, 4620.0f },
+ { 3980.0f, 100.0f, 1600.0f }, { 3980.0f, 100.0f, 500.0f },
+ };
+ static xyz_t birth_pos_random_data[8] = {
+ { 1280.0f, 100.0f, 0.0f }, { 960.0f, 100.0f, 960.0f }, { 0.0f, 100.0f, 1920.0f }, { 960.0f, 100.0f, -960.0f },
+ { 1280.0f, 100.0f, 0.0f }, { -960.0f, 100.0f, -960.0f }, { 0.0f, 100.0f, 1920.0f }, { -960.0f, 100.0f, 960.0f },
+ };
+ s16 rotVar;
+ f32 rand;
+ s32 randXOrZ;
+ f32 balloonGroundY = mCoBG_GetBalloonGroundY(&this->actor.world.pos);
+ f32 xPos;
+ f32 zPos;
+
+ this->actor.world.rot.y = mEnv_GetWindAngleS();
+ rotVar = this->actor.world.rot.y & 0xF000;
+ this->dataIndex = (rotVar >> 0xC) & 0xF;
+ this->dataIndex = data_index_data[this->dataIndex];
+ xyz_t_move(&this->actor.world.pos, &birth_pos_data[this->dataIndex]);
+ this->actor.world.pos.y = (f32)(balloonGroundY + 200.0f);
+ this->colorIndex = game_play->unk_1EA0 % 5;
+ this->birthTimer = 10;
+ randXOrZ = FSN_RAND_X;
+ if ((birth_pos_random_data[this->dataIndex].x != 0.0f) && (birth_pos_random_data[this->dataIndex].z != 0.0f)) {
+ randXOrZ = game_play->unk_1EA0 & 1;
+ } else if (birth_pos_random_data[this->dataIndex].z != 0.0f) {
+ randXOrZ = FSN_RAND_Z;
+ }
+ if (randXOrZ == FSN_RAND_X) {
+ if (birth_pos_random_data[this->dataIndex].x != 0.0f) {
+ rand = fqrand();
+ xPos = fabsf(birth_pos_random_data[this->dataIndex].x);
+ if (birth_pos_random_data[this->dataIndex].x > 0.0f) {
+ this->actor.world.pos.x += xPos * rand;
+ } else {
+ this->actor.world.pos.x -= xPos * rand;
+ }
+ }
+ } else {
+ if (birth_pos_random_data[this->dataIndex].z != 0.0f) {
+ rand = fqrand();
+ zPos = fabsf(birth_pos_random_data[this->dataIndex].z);
+ if (birth_pos_random_data[this->dataIndex].z > 0.0f) {
+ this->actor.world.pos.z += zPos * rand;
+ } else {
+ this->actor.world.pos.z -= zPos * rand;
+ }
+ }
+ }
+}
+
+void aFSN_moving_init(Fuusen* this, UNUSED Game_Play* game_play) {
+ this->unk_1A4 = false;
+}
+
+void aFSN_wood_stop_init(Fuusen* this, UNUSED Game_Play* game_play) {
+ this->escapeTimer = 9000 + 777;
+ this->actor.speed = 0.0f;
+ sAdo_OngenTrgStart(0x402, &this->actor.world.pos);
+}
+
+void aFSN_escape_init(Fuusen* this, Game_Play* game_play) {
+ Player* player = get_player_actor_withoutCheck(game_play);
+ f32 xDist = player->actor.world.pos.x - this->actor.world.pos.x;
+ f32 zDist = player->actor.world.pos.z - this->actor.world.pos.z;
+
+ this->unk_18C = 0;
+ this->actor.terminalVelocity = 5.0f;
+ this->actor.gravity = 0.5f;
+ this->shouldLookUp = false;
+ if (this->escapeTimer == 777) {
+ this->unk_18C = 1;
+ if (sqrtf(SQ(xDist) + SQ(zDist)) < 640.0f) {
+ this->shouldLookUp = true;
+ }
+ }
+}
+
+Color_RGBA8 balloon_prim_data[5] = {
+ { 255, 210, 200, 255 }, { 200, 230, 200, 255 }, { 255, 250, 200, 255 },
+ { 220, 255, 200, 255 }, { 240, 210, 255, 255 },
+};
+
+Color_RGBA8 balloon_env_data[5] = {
+ { 255, 40, 0, 255 }, { 0, 180, 255, 255 }, { 255, 200, 0, 255 }, { 100, 255, 0, 255 }, { 200, 30, 255, 255 },
+};
+
+void aFSN_birth(Actor* thisx, Game_Play* game_play) {
+ Fuusen* this = THIS;
+ aFSN_setupAction(this, FSN_PROCESS_MOVING, game_play);
+}
+
+void aFSN_moving(Actor* thisx, Game_Play* game_play) {
+ static Vec2s senkou_check_data[3] = {
+ { -1, -2500 },
+ { 0, 0 },
+ { 0, 2500 },
+ };
+ Fuusen* this = THIS;
+ f32 balloonGroundY = mCoBG_GetBalloonGroundY(&this->actor.world.pos) + this->heightOffset;
+ UNUSED UNK_TYPE1 pad[0x4];
+ u16* unitFG;
+ xyz_t screenPos;
+ f32 distX;
+ f32 distY;
+ f32 distZ;
+ s32 i;
+ s16 yRot;
+
+ if (this->escapeTimer > 0) {
+ this->escapeTimer--;
+ } else {
+ if ((this->actor.world.pos.x <= 660.0f) || (this->actor.world.pos.x >= 3820.0f) ||
+ (this->actor.world.pos.z <= 660.0f) || (this->actor.world.pos.z >= 4460.0f)) {
+ this->escapeTimer = 777;
+ aFSN_setupAction(this, FSN_PROCESS_ESCAPE, game_play);
+ return;
+ } else if ((this->actor.world.pos.x <= 2440.0f) && (this->actor.world.pos.x >= 2040.0f) &&
+ (this->actor.world.pos.z <= 960.0f) && (this->actor.world.pos.z >= 800.0f)) {
+ this->escapeTimer = 777;
+ aFSN_setupAction(this, FSN_PROCESS_ESCAPE, game_play);
+ return;
+ }
+ }
+ this->windPower = mEnv_GetWindPowerF();
+ this->heightAmplitudeCounter += 500;
+ this->actor.speed = this->windPower * 0.5f + 1.0f;
+ add_calc(&this->actor.world.pos.y, (sin_s(this->heightAmplitudeCounter) * 10.0f) + balloonGroundY, 0.3f, 1.0f,
+ 0.0f);
+ Game_play_Projection_Trans(game_play, &this->actor.world.pos, &screenPos);
+ if (!(screenPos.x < -40.0f) && !(screenPos.x > 360.0f) && !(screenPos.y < -40.0f) && !(screenPos.y > 280.0f)) {
+ mCoBG_BgCheckControll(NULL, &this->actor, 12.0f, 0, 0, 0, 0);
+ if (this->actor.colResult.hitWall & 1 || this->actor.colResult.unk1 & 1) {
+ this->heightOffset += 0.01f;
+ if (this->heightOffset >= 300.0f) {
+ this->heightOffset = 300.0f;
+ }
+ } else {
+ if (this->heightOffset > 110.0f) {
+ this->heightOffset -= 0.01f;
+ }
+ }
+ unitFG = mFI_GetUnitFG(this->actor.world.pos);
+ if ((unitFG != NULL) && ((*unitFG == TREE) || (*unitFG == TREE_APPLE_NOFRUIT_0) ||
+ (*unitFG == TREE_ORANGE_NOFRUIT_0) || (*unitFG == TREE_PEACH_NOFRUIT_0) ||
+ (*unitFG == TREE_PEAR_NOFRUIT_0) || (*unitFG == TREE_CHERRY_NOFRUIT_0) ||
+ (*unitFG == TREE_APPLE_NOFRUIT_1) || (*unitFG == TREE_ORANGE_NOFRUIT_1) ||
+ (*unitFG == TREE_PEACH_NOFRUIT_1) || (*unitFG == TREE_PEAR_NOFRUIT_1) ||
+ (*unitFG == TREE_CHERRY_NOFRUIT_1) || (*unitFG == TREE_APPLE_NOFRUIT_2) ||
+ (*unitFG == TREE_ORANGE_NOFRUIT_2) || (*unitFG == TREE_PEACH_NOFRUIT_2) ||
+ (*unitFG == TREE_PEAR_NOFRUIT_2) || (*unitFG == TREE_CHERRY_NOFRUIT_2))) {
+ mFI_Wpos2UtCenterWpos(&screenPos, this->actor.world.pos);
+ screenPos.x -= 2.5f;
+ screenPos.y = mCoBG_GetBgY_OnlyCenter_FromWpos2(this->actor.world.pos, 0.0f) + 97.5f;
+ screenPos.z += 7.5f;
+ distX = screenPos.x - this->actor.world.pos.x;
+ distY = screenPos.y - this->actor.world.pos.y;
+ distZ = screenPos.z - this->actor.world.pos.z;
+ if ((sqrtf(SQ(distX) + SQ(distZ)) < 15.0f) && (sqrtf(SQ(distY)) < 15.0f)) {
+ aFSN_setupAction(this, FSN_PROCESS_WOOD_STOP, game_play);
+ }
+ } else {
+ if (!this->unk_1A4) {
+ // FAKE
+ dummy_label:
+ for (i = 0; i < ARRAY_COUNT(senkou_check_data); i++) {
+ xyz_t_move(&screenPos, &this->actor.world.pos);
+ yRot = senkou_check_data[i].z + this->actor.world.rot.y;
+ screenPos.x += sin_s(yRot) * 80.0f;
+ screenPos.z += cos_s(yRot) * 80.0f;
+ unitFG = mFI_GetUnitFG(screenPos);
+ if ((unitFG != NULL) && ((*unitFG == TREE) || (*unitFG == TREE_APPLE_NOFRUIT_0) ||
+ (*unitFG == TREE_ORANGE_NOFRUIT_0) || (*unitFG == TREE_PEACH_NOFRUIT_0) ||
+ (*unitFG == TREE_PEAR_NOFRUIT_0) || (*unitFG == TREE_CHERRY_NOFRUIT_0) ||
+ (*unitFG == TREE_APPLE_NOFRUIT_1) || (*unitFG == TREE_ORANGE_NOFRUIT_1) ||
+ (*unitFG == TREE_PEACH_NOFRUIT_1) || (*unitFG == TREE_PEAR_NOFRUIT_1) ||
+ (*unitFG == TREE_CHERRY_NOFRUIT_1) || (*unitFG == TREE_APPLE_NOFRUIT_2) ||
+ (*unitFG == TREE_ORANGE_NOFRUIT_2) || (*unitFG == TREE_PEACH_NOFRUIT_2) ||
+ (*unitFG == TREE_PEAR_NOFRUIT_2) || (*unitFG == TREE_CHERRY_NOFRUIT_2))) {
+ this->actor.world.rot.y = yRot;
+ this->unk_1A4 = true;
+ break;
+ }
+ }
+ }
+ if (!this->unk_1A4) {
+ this->actor.world.rot.y = mEnv_GetWindAngleS();
+ }
+ }
+ }
+}
+
+void aFSN_wood_stop(Actor* thisx, Game_Play* game_play) {
+ Fuusen* this = THIS;
+ xyz_t pos;
+ xyz_t posCopy;
+ f32 distX;
+ f32 distZ;
+
+ this->escapeTimer--;
+ if (this->escapeTimer <= 777) {
+ this->escapeTimer = 777;
+ aFSN_setupAction(this, FSN_PROCESS_ESCAPE, game_play);
+ } else {
+ mFI_Wpos2UtCenterWpos(&pos, this->actor.world.pos);
+ xyz_t_move(&posCopy, &pos);
+ pos.x -= 2.5f;
+ pos.y = mCoBG_GetBgY_OnlyCenter_FromWpos2(this->actor.world.pos, 0.0f) + 97.5f;
+ pos.z += 7.5f;
+ distX = this->actor.world.pos.x - pos.x;
+ distZ = this->actor.world.pos.z - pos.z;
+ if (sqrtf(SQ(distX) + SQ(distZ)) > 2.0f) {
+ add_calc(&this->actor.world.pos.x, pos.x, 0.3f, 1.0f, 0.0f);
+ add_calc(&this->actor.world.pos.y, pos.y, 0.3f, 1.0f, 0.0f);
+ add_calc(&this->actor.world.pos.z, pos.z, 0.3f, 1.0f, 0.0f);
+ } else if (mPlib_Check_tree_shaken_big(&posCopy)) {
+ this->actor.shape.rot.z = 0;
+ aFSN_setupAction(this, FSN_PROCESS_ESCAPE, game_play);
+ } else if (mPlib_Check_tree_shaken_little(&posCopy)) {
+ if (!(this->unk_18C & 2)) {
+ this->actor.shape.rot.z = 500;
+ } else {
+ this->actor.shape.rot.z = 0;
+ }
+ this->unk_18C++;
+ } else {
+ this->actor.shape.rot.z = 0;
+ this->unk_18C = 0;
+ }
+ }
+}
+
+void aFSN_escape(Actor* thisx, UNUSED Game_Play* game_play) {
+ Fuusen* this = THIS;
+ f32 balloonGroundY = mCoBG_GetBalloonGroundY(&this->actor.world.pos);
+
+ if (this->unk_18C == 0) {
+ xyz_t pos;
+ s32 utX;
+ s32 utZ;
+
+ mFI_Wpos2UtCenterWpos(&pos, this->actor.world.pos);
+ if ((common_data.clip.unk_074 != NULL) && (common_data.clip.unk_074->unk_38 != 0) &&
+ mFI_Wpos2UtNum(&utX, &utZ, pos)) {
+ common_data.clip.unk_074->unk_30(9500, utX, utZ, 1);
+ this->unk_18C = 1;
+ }
+ }
+ if (this->unk_18C == 1) {
+ if (this->actor.world.pos.y > (balloonGroundY + 500.0f)) {
+ Actor_delete(&this->actor);
+ }
+ }
+}
-#pragma GLOBAL_ASM("asm/jp/nonmatchings/overlays/actors/ovl_Fuusen/ac_fuusen/aFSN_actor_dt.s")
+void aFSN_setupAction(Fuusen* this, s32 processIndex, Game_Play* game_play) {
+ static FuusenInitFunc init_proc[4] = {
+ aFSN_birth_init,
+ aFSN_moving_init,
+ aFSN_wood_stop_init,
+ aFSN_escape_init,
+ };
-#pragma GLOBAL_ASM("asm/jp/nonmatchings/overlays/actors/ovl_Fuusen/ac_fuusen/func_80AAD270_jp.s")
+ static FuusenActionFunc act_proc[4] = {
+ aFSN_birth,
+ aFSN_moving,
+ aFSN_wood_stop,
+ aFSN_escape,
+ };
-#pragma GLOBAL_ASM("asm/jp/nonmatchings/overlays/actors/ovl_Fuusen/ac_fuusen/func_80AAD490_jp.s")
+ this->processNum = processIndex;
+ this->process = act_proc[processIndex];
+ init_proc[processIndex](this, game_play);
+}
-#pragma GLOBAL_ASM("asm/jp/nonmatchings/overlays/actors/ovl_Fuusen/ac_fuusen/func_80AAD4A0_jp.s")
+// Original name unknown.
+void func_80AADF10_jp(Fuusen* this, Game_Play* game_play) {
+ UNUSED UNK_TYPE1 pad[0x4];
+ void* segment;
-#pragma GLOBAL_ASM("asm/jp/nonmatchings/overlays/actors/ovl_Fuusen/ac_fuusen/func_80AAD4DC_jp.s")
+ segment = game_play->objectExchangeBank.status[this->actor.unk_026].segment;
+ if (this->segment != segment) {
+ SkeletonInfoR* skeletonInfo = &this->skeletonInfo;
+ skeletonInfo->skeleton = Lib_SegmentedToVirtual(&cKF_bs_r_act_balloon);
+ skeletonInfo->animation = Lib_SegmentedToVirtual(&cKF_ba_r_act_balloon);
+ this->segment = segment;
+ }
+}
-#pragma GLOBAL_ASM("asm/jp/nonmatchings/overlays/actors/ovl_Fuusen/ac_fuusen/func_80AAD580_jp.s")
+void aFSN_actor_move(Actor* thisx, Game_Play* game_play) {
+ Fuusen* this = THIS;
+ UNUSED UNK_TYPE1 pad[0x8];
-#pragma GLOBAL_ASM("asm/jp/nonmatchings/overlays/actors/ovl_Fuusen/ac_fuusen/func_80AAD5A4_jp.s")
+ func_80AADF10_jp(this, game_play);
+ if (this->birthTimer == 0) {
+ Actor_position_moveF(&this->actor);
+ } else if (this->birthTimer > 0) {
+ this->birthTimer--;
+ }
+ if (fuusen_DEBUG_mode_flag != 0) {
+ Player* player = get_player_actor_withoutCheck(game_play);
+ Debug_Display_new((sin_s(this->actor.yawTowardsPlayer + 0x8000) * 30.0f) + player->actor.world.pos.x,
+ player->actor.world.pos.y + 60.0f,
+ (cos_s(this->actor.yawTowardsPlayer + 0x8000) * 30.0f) + player->actor.world.pos.z, 0,
+ this->actor.yawTowardsPlayer + 0x8000, 0, 1.0f, 1.0f, 1.0f, 250, 100, 120, 128, 4,
+ game_play->state.gfxCtx);
+ }
+ cKF_SkeletonInfo_R_play(&this->skeletonInfo);
+ this->process(&this->actor, game_play);
+ fuusen_DEBUG_mode_flag = 0;
+}
-#pragma GLOBAL_ASM("asm/jp/nonmatchings/overlays/actors/ovl_Fuusen/ac_fuusen/func_80AADB9C_jp.s")
+// Original name unknown.
+Gfx* func_80AAE10C_jp(u8 red, u8 blue, u8 green, u8 alpha, Game_Play* game_play) {
+ GraphicsContext* gfxCtx = game_play->state.gfxCtx;
+ Gfx* gfx = GRAPH_ALLOC(gfxCtx, 1);
-#pragma GLOBAL_ASM("asm/jp/nonmatchings/overlays/actors/ovl_Fuusen/ac_fuusen/func_80AADDA8_jp.s")
+ if (gfx) {
+ gDPSetPrimColor(gfx, 0, 255, red, blue, green, alpha);
+ gSPEndDisplayList(gfx + 1);
+ return gfx;
+ }
+ return NULL;
+}
-#pragma GLOBAL_ASM("asm/jp/nonmatchings/overlays/actors/ovl_Fuusen/ac_fuusen/func_80AADEC4_jp.s")
+extern Gfx present_DL_mode[];
+extern Vtx present_DL_vtx[];
-#pragma GLOBAL_ASM("asm/jp/nonmatchings/overlays/actors/ovl_Fuusen/ac_fuusen/func_80AADF10_jp.s")
+#define OPEN_CUSTOM_POLY_OPA() \
+ { \
+ Gfx* __polyOpa = __gfxCtx->polyOpa.p; \
+ int __opa_opened = 0; \
+ do { \
+ } while (0)
-#pragma GLOBAL_ASM("asm/jp/nonmatchings/overlays/actors/ovl_Fuusen/ac_fuusen/aFSN_actor_move.s")
+#define CLOSE_CUSTOM_POLY_OPA() \
+ __gfxCtx->polyOpa.p = __polyOpa; \
+ (void)__opa_opened; \
+ } \
+ while (0)
-#pragma GLOBAL_ASM("asm/jp/nonmatchings/overlays/actors/ovl_Fuusen/ac_fuusen/func_80AAE10C_jp.s")
+void aFSN_actor_draw(Actor* thisx, Game_Play* game_play) {
+ static xyz_t offset0 = { 0.0f, 0.0f, 0.0f };
+ Fuusen* this = THIS;
+ s32 mtxIndex = game_play->state.frameCounter & 1;
+ UNUSED UNK_TYPE1 pad[0x8];
+ s16 objBankIndex;
+ void* segment;
+ Gfx* balloonGfx;
-#pragma GLOBAL_ASM("asm/jp/nonmatchings/overlays/actors/ovl_Fuusen/ac_fuusen/aFSN_actor_draw.s")
+ objBankIndex = this->actor.unk_026;
+ segment = game_play->objectExchangeBank.status[objBankIndex].segment;
+ balloonGfx =
+ func_80AAE10C_jp(balloon_prim_data[this->colorIndex].r, balloon_prim_data[this->colorIndex].g,
+ balloon_prim_data[this->colorIndex].b, balloon_prim_data[this->colorIndex].a, game_play);
+ if ((balloonGfx != NULL) &&
+ (!Camera2_CheckCullingMode() ||
+ !Camera2_CheckEnterCullingArea(this->actor.world.pos.x, this->actor.world.pos.z, 60.0f))) {
+ func_80AADF10_jp(this, game_play);
+ Matrix_push();
+ if ((this->processNum != FSN_PROCESS_ESCAPE) || (this->escapeTimer == 777) ||
+ ((this->processNum == FSN_PROCESS_ESCAPE) && (this->unk_18C == 0))) {
+ _texture_z_light_fog_prim(game_play->state.gfxCtx);
+ OPEN_DISPS(game_play->state.gfxCtx);
+ OPEN_CUSTOM_POLY_OPA();
+ Matrix_translate(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, 0);
+ Matrix_scale(0.01f, 0.01f, 0.01f, 1);
+ Matrix_RotateX(this->actor.shape.rot.x, MTXMODE_APPLY);
+ Matrix_RotateZ(this->actor.shape.rot.z, MTXMODE_APPLY);
+ Matrix_RotateY(this->actor.shape.rot.y, MTXMODE_APPLY);
+ gSPMatrix(__polyOpa++, _Matrix_to_Mtx_new(game_play->state.gfxCtx),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(__polyOpa++, present_DL_mode);
+ gSPDisplayList(__polyOpa++, present_DL_vtx);
+ CLOSE_CUSTOM_POLY_OPA();
+ CLOSE_DISPS(game_play->state.gfxCtx);
+ }
+ OPEN_DISPS(game_play->state.gfxCtx);
+ gSPSegment(POLY_OPA_DISP++, 0x06, segment);
+ gSPSegment(POLY_OPA_DISP++, 0x08, balloonGfx);
+ gDPPipeSync(POLY_OPA_DISP++);
+ gDPSetEnvColor(POLY_OPA_DISP++, balloon_env_data[this->colorIndex].r, balloon_env_data[this->colorIndex].g,
+ balloon_env_data[this->colorIndex].b, balloon_env_data[this->colorIndex].a);
+ CLOSE_DISPS(game_play->state.gfxCtx);
+ Setpos_HiliteReflect_init(&this->actor.world.pos, game_play);
+ cKF_Si3_draw_R_SV(game_play, &this->skeletonInfo, this->mtx[mtxIndex], NULL, NULL, &this->actor);
+ mAc_ActorShadowDraw_ShadowDrawFlagOn(&this->actor, game_play, 0, offset0, 170.0f);
+ Matrix_pull();
+ }
+}
diff --git a/src/overlays/actors/ovl_Fuusen/ac_fuusen.h b/src/overlays/actors/ovl_Fuusen/ac_fuusen.h
index 172a826..03b555b 100644
--- a/src/overlays/actors/ovl_Fuusen/ac_fuusen.h
+++ b/src/overlays/actors/ovl_Fuusen/ac_fuusen.h
@@ -4,15 +4,45 @@
#include "ultra64.h"
#include "m_actor.h"
#include "unk.h"
+#include "c_keyframe.h"
struct Game_Play;
struct Fuusen;
-typedef void (*FuusenActionFunc)(struct Fuusen*, struct Game_Play*);
+typedef void (*FuusenInitFunc)(struct Fuusen*, struct Game_Play*);
+typedef void (*FuusenActionFunc)(struct Actor*, struct Game_Play*);
+
+typedef enum FuusenProcess {
+ FSN_PROCESS_BIRTH,
+ FSN_PROCESS_MOVING,
+ FSN_PROCESS_WOOD_STOP,
+ FSN_PROCESS_ESCAPE,
+} FuusenProcess;
+
+typedef enum FuusenRand {
+ FSN_RAND_X,
+ FSN_RAND_Z,
+} FuusenRand;
typedef struct Fuusen {
/* 0x000 */ Actor actor;
- /* 0x174 */ UNK_TYPE1 unk_174[0x2D4];
+ /* 0x174 */ FuusenActionFunc process;
+ /* 0x178 */ void* segment;
+ /* 0x17C */ s32 processNum;
+ /* 0x180 */ u32 colorIndex;
+ /* 0x184 */ s32 escapeTimer;
+ /* 0x188 */ s32 birthTimer;
+ /* 0x18C */ s32 unk_18C;
+ /* 0x190 */ s32 shouldLookUp;
+ /* 0x194 */ s32 dataIndex;
+ /* 0x198 */ s16 heightAmplitudeCounter;
+ /* 0x19C */ f32 windPower;
+ /* 0x1A0 */ f32 heightOffset;
+ /* 0x1A4 */ u8 unk_1A4;
+ /* 0x1A8 */ SkeletonInfoR skeletonInfo;
+ /* 0x218 */ s_xyz jointTable[0x4];
+ /* 0x230 */ s_xyz morphTable[0x4];
+ /* 0x248 */ Mtx mtx[2][4];
} Fuusen; // size = 0x448
#endif
diff --git a/src/overlays/gamestates/ovl_play/m_play.h b/src/overlays/gamestates/ovl_play/m_play.h
index 27b28bc..7400a44 100644
--- a/src/overlays/gamestates/ovl_play/m_play.h
+++ b/src/overlays/gamestates/ovl_play/m_play.h
@@ -86,7 +86,7 @@ typedef struct Game_Play {
/* 0x1E1C */ MtxF viewProjectionMtxF;
/* 0x1E5C */ MtxF billboardMtxF;
/* 0x1E9C */ Mtx* unk_1E9C;
- /* 0x1EA0 */ s32 unk_1EA0;
+ /* 0x1EA0 */ u32 unk_1EA0;
/* 0x1EA4 */ UNK_TYPE1 unk_1EA4[0x1];
/* 0x1EA5 */ u8 unk_1EA5;
/* 0x1EA6 */ u8 unk_1EA6;
diff --git a/yamls/jp/assets.yaml b/yamls/jp/assets.yaml
index 824a17f..5428bd5 100644
--- a/yamls/jp/assets.yaml
+++ b/yamls/jp/assets.yaml
@@ -6761,15 +6761,34 @@
# - [0x11F4000, data, assets/objects/object_011F4000/object_011F4000]
- [0x11F4930]
- - name: object_011F5000
- type: bin # code
+ - name: act_balloon
+ dir: objects/act_balloon
+ type: code
start: 0x11F5000
vram: 0x06000000
exclusive_ram_id: segment_06
compress: True
align: 0x1000
- # subsegments:
- # - [0x11F5000, data, assets/objects/object_011F5000/object_011F5000]
+ symbol_name_format: $VRAM_$ROM
+ subsegments:
+ - [auto, c, act_balloon]
+ - start: 0x11F5000
+ type: .data
+ name: act_balloon
+ subsegments:
+ - [0x11F5000, vtx, act_balloon_v]
+ - [0x11F5340, af_gfx, act_balloon_head_model]
+ - [0x11F5450, af_gfx, act_balloon_wireB_model]
+ - [0x11F5560, af_gfx, act_balloon_wireA_model]
+ - [0x11F55F8, i4, act_balloon_wire_tex_txt, 16, 16]
+ - [0x11F5678, ia16, act_balloon_head_tex_rgb_ia16, 32, 32]
+ - [0x11F5E78, ckf_ckcb, cKF_ckcb_r_act_balloon_tbl]
+ - [0x11F5E7C, ckf_kn, cKF_kn_act_balloon_tbl]
+ - [0x11F5E88, ckf_c, cKF_c_act_balloon_tbl]
+ - [0x11F5E9C, ckf_ds, cKF_ds_act_balloon_tbl]
+ - [0x11F5F44, ckf_ba, cKF_ba_r_act_balloon]
+ - [0x11F5F58, ckf_je, cKF_je_r_act_balloon_tbl]
+ - [0x11F5F88, ckf_bs, cKF_bs_r_act_balloon]
- [0x11F5F90]
- name: segment_011F6000
diff --git a/yamls/jp/overlays.yaml b/yamls/jp/overlays.yaml
index 2780829..30ec919 100644
--- a/yamls/jp/overlays.yaml
+++ b/yamls/jp/overlays.yaml
@@ -17067,7 +17067,7 @@
bss_size: 0x0
subsegments:
- [0x96D250, c, overlays/actors/ovl_Fuusen/ac_fuusen]
- - [0x96E620, data, overlays/actors/ovl_Fuusen/ac_fuusen]
+ - [0x96E620, .data, overlays/actors/ovl_Fuusen/ac_fuusen]
- [0x96E7B0, .rodata, overlays/actors/ovl_Fuusen/ac_fuusen]
- name: ovl_Fuusen_reloc
type: code