diff --git a/common.py b/common.py index ba7810c9..ecaf7657 100644 --- a/common.py +++ b/common.py @@ -325,7 +325,8 @@ COMMON_DEFINES = [ "-d _LANGUAGE_C", "-d F3DEX_GBI_2", "-d NDEBUG", - "-d DEBUG=0" + "-d DEBUG=0", + "-d MUST_MATCH" ] DOL_DEFINES = COMMON_DEFINES + [] REL_DEFINES = COMMON_DEFINES + [ diff --git a/config/rel_slices.yml b/config/rel_slices.yml index c00d0aaa..ab0c3498 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -12,6 +12,11 @@ m_all_grow.c: .rodata: [0x806412C0, 0x806412E8] .data: [0x8064D598, 0x8064D600] .bss: [0x8125A7C8, 0x8125A7E8] +m_actor.c: + .text: [0x803742B8, 0x8037619C] + .rodata: [0x806412E8, 0x80641328] + .data: [0x8064D600, 0x8064D628] + .bss: [0x8125A7E8, 0x8125A828] m_actor_dlftbls.c: .text: [0x8037619C, 0x803761BC] .data: [0x8064D628, 0x8064F4E8] diff --git a/config/symbols.yml b/config/symbols.yml index 8a4733b9..68fc6112 100644 --- a/config/symbols.yml +++ b/config/symbols.yml @@ -2629,6 +2629,7 @@ global: 0x8009ae38: _savefpr_28 0x8009ae3c: _savefpr_29 0x8009ae4c: __restore_fpr + 0x8009ae88: _restfpr_29 0x8009ae98: __save_gpr 0x8009ae9c: _savegpr_15 0x8009aea0: _savegpr_16 diff --git a/configure.py b/configure.py index 2242a62f..c1f63120 100644 --- a/configure.py +++ b/configure.py @@ -141,7 +141,7 @@ n.rule( n.rule( "disasm_single", - command = "$disassembler $in $out -j $addr -q $disasmflags", + command = "$disassembler $in $out -f $addr -q -i $disasmflags", description = "ppcdis function disassembly $addr" ) diff --git a/include/ac_npc.h b/include/ac_npc.h index 13bb6ea5..dbac88c2 100644 --- a/include/ac_npc.h +++ b/include/ac_npc.h @@ -4,6 +4,8 @@ #include "types.h" #include "m_actor.h" #include "m_play.h" +#include "ac_npc_h.h" +#include "m_actor_dlftbls.h" #ifdef __cplusplus extern "C" { @@ -11,11 +13,34 @@ extern "C" { typedef struct ac_npc_clip_s aNPC_Clip_c; +typedef struct npc_draw_data_s { + s16 model_bank; + s16 texture_bank; + u8 _04[0x68]; // TODO +} aNPC_draw_data_c; + typedef int (*aNPC_SETUP_ACTOR_PROC)(GAME_PLAY*, mActor_name_t, s8, int, s16, int, int, int, int); +typedef void (*aNPC_DMA_DRAW_DATA_PROC)(aNPC_draw_data_c*, mActor_name_t); +typedef void (*aNPC_FREE_OVERLAY_AREA_PROC)(ACTOR_DLFTBL*); +typedef ACTOR* (*aNPC_GET_ACTOR_AREA_PROC)(size_t, const char*, int); +typedef void (*aNPC_FREE_ACTOR_AREA_PROC)(ACTOR*); struct ac_npc_clip_s { aNPC_SETUP_ACTOR_PROC setupActor_proc; - void* _004[(0x12C - 0x004) / sizeof(void*)]; + void* _004; + aNPC_FREE_OVERLAY_AREA_PROC free_overlay_area_proc; + aNPC_GET_ACTOR_AREA_PROC get_actor_area_proc; + aNPC_FREE_ACTOR_AREA_PROC free_actor_area_proc; + aNPC_DMA_DRAW_DATA_PROC dma_draw_data_proc; + void* _018[(0x12C - 0x018) / sizeof(void*)]; +}; + +struct npc_actor_s { + ACTOR actor_class; + // TODO: finish + u8 _174[0x718 - 0x174]; + int texture_bank_idx; // TEMP: this is part of draw struct + u8 _71C[0x9D8 - 0x71C]; }; extern ACTOR_PROFILE Npc_Profile; diff --git a/include/ac_npc_h.h b/include/ac_npc_h.h new file mode 100644 index 00000000..499e5ca7 --- /dev/null +++ b/include/ac_npc_h.h @@ -0,0 +1,16 @@ +#ifndef AC_NPC_H_H +#define AC_NPC_H_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct npc_actor_s NPC_ACTOR; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/ac_structure.h b/include/ac_structure.h index 69f19ec3..61231d27 100644 --- a/include/ac_structure.h +++ b/include/ac_structure.h @@ -223,7 +223,6 @@ typedef struct actor_overlay_info_s { int used; } aSTR_Overlay_info_c; -// TODO: finish clip typedef struct actor_structure_clip_s { aSTR_SETUP_ACTOR_PROC setup_actor_proc; aSTR_GET_OVERLAY_AREA_PROC get_overlay_area_proc; diff --git a/include/m_actor.h b/include/m_actor.h index 5259ae33..cf783186 100644 --- a/include/m_actor.h +++ b/include/m_actor.h @@ -8,6 +8,7 @@ #include "m_lights.h" #include "m_collision_bg.h" #include "m_collision_obj.h" +#include "m_actor_dlftbls.h" #include "libforest/gbi_extensions.h" #ifdef __cplusplus @@ -17,10 +18,16 @@ extern "C" { typedef void (*mActor_proc)(ACTOR*, GAME*); #define NONE_ACTOR_PROC ((mActor_proc)&none_proc1) +#define mAc_MAX_ACTORS 200 + #define ACTOR_STATE_NONE 0 #define ACTOR_STATE_NO_MOVE_WHILE_CULLED (1 << 4) #define ACTOR_STATE_NO_DRAW_WHILE_CULLED (1 << 5) -#define ACTOR_STATE_11 (1 << 11) +#define ACTOR_STATE_NO_CULL (1 << 6) +#define ACTOR_STATE_INVISIBLE (1 << 7) +#define ACTOR_STATE_TA_SET (1 << 11) +#define ACTOR_STATE_LIGHTING (1 << 22) // does lighting NOT affect this actor? +#define ACTOR_STATE_24 (1 << 24) #define ACTOR_STATE_CAN_MOVE_IN_DEMO_SCENES (1 << 29) #define ACTOR_OBJ_BANK_NONE 0 @@ -34,8 +41,8 @@ enum actor_part { ACTOR_PART_FG, ACTOR_PART_ITEM, ACTOR_PART_PLAYER, + ACTOR_PART_3, /* Thought this was for NPCs but maybe not? */ ACTOR_PART_NPC, - ACTOR_PART_4, /* TODO: figure this one out */ ACTOR_PART_BG, ACTOR_PART_EFFECT, ACTOR_PART_CONTROL, @@ -340,16 +347,13 @@ struct actor_s { /* 0x008 */ s8 block_x; /* 0x009 */ s8 block_z; /* 0x00A */ s16 move_actor_list_idx; /* used in aBC_setupCommonMvActor */ - /* 0x00C */ xyz_t home_position; /* actor 'home' pos */ - /* 0x018 */ s_xyz home_rotation; /* actor 'home' rotation */ + /* 0x00C */ PositionAngle home; /* Home position & rotation */ /* 0x020 */ u32 state_bitfield; /* bitfield of current actor state */ /* 0x024 */ s16 actor_specific; /* actor specific temp data */ /* 0x026 */ s16 data_bank_id; /* data bank id actor is in */ - /* 0x028 */ xyz_t world_position; - /* 0x034 */ s_xyz world_rotation; + /* 0x028 */ PositionAngle world; /* World position & rotation */ /* 0x03C */ xyz_t last_world_position; /* previous actor world position */ - /* 0x048 */ xyz_t eye_position; /* actor "eyes" (head/lookat) world position */ - /* 0x054 */ s_xyz eye_rotation; /* actor "eyes" (head/lookat) world rotation */ + /* 0x048 */ PositionAngle eye; /* actor "eyes" (head/lookat) world position & rotation */ /* 0x05C */ xyz_t scale; /* actor size */ /* 0x068 */ xyz_t position_speed; /* actor movement velocity (see Actor_position_speed_set) */ /* 0x074 */ f32 speed; /* movement speed */ @@ -383,7 +387,7 @@ struct actor_s { /* 0x164 */ mActor_proc mv_proc; /* move */ /* 0x168 */ mActor_proc dw_proc; /* draw */ /* 0x16C */ mActor_proc sv_proc; /* save */ - /* 0x170 */ void* dlftbl; /* display list function table */ + /* 0x170 */ ACTOR_DLFTBL* dlftbl; /* display list function table */ }; #define mActor_NONE_PROC1 ((mActor_proc)none_proc1) @@ -398,13 +402,47 @@ typedef struct actor_info_s { Actor_list list[ACTOR_PART_NUM]; } Actor_info; -extern void Actor_delete(ACTOR* actor); -extern ACTOR* Actor_info_fgName_search(Actor_info* actor_info, mActor_name_t fg_name, int part); +typedef struct actor_data_s { + s16 profile; + s_xyz position; + s_xyz rotation; + s16 arg; +} Actor_data; + extern void Actor_world_to_eye(ACTOR* actor, f32 eye_height); -extern void Shape_Info_init(ACTOR* actor, f32 y_ofs, mActor_shadow_proc shadow_proc, f32 shadow_sizeX, f32 shadow_sizeZ); +extern void Actor_position_move(ACTOR* actor); +extern void Actor_position_speed_set(ACTOR* actor); extern void Actor_position_moveF(ACTOR* actor); -extern ACTOR* Actor_info_make_actor(Actor_info* actor_info, GAME* game, s16 profile, f32 x, f32 y, f32 z, short rot_x, short rot_y, short rot_z, s8 block_x, s8 block_z, s16 mvactor_list_no, mActor_name_t actor_name, s16 arg, s8 npc_idx, int data_bank); -extern void Setpos_HiliteReflect_init(xyz_t* wpos, GAME_PLAY* play); +extern int Actor_player_look_direction_check(ACTOR* actor, s16 angle, GAME_PLAY* play); +extern void Shape_Info_init(ACTOR* actor, f32 ofs_y, mActor_shadow_proc shadow_proc, f32 shadow_size_x, f32 shadow_size_z); +extern void Actor_delete(ACTOR* actor); +extern int Actor_draw_actor_no_culling_check(ACTOR* actor); +extern int Actor_draw_actor_no_culling_check2(ACTOR* actor, xyz_t* camera_pos, f32 camera_w); +extern void Actor_info_ct(GAME* game, Actor_info* actor_info, Actor_data* player_data); +extern void Actor_info_dt(Actor_info* actor_info, GAME_PLAY* play); +extern void Actor_info_call_actor(GAME_PLAY* play, Actor_info* actor_info); +extern void Actor_info_draw_actor(GAME_PLAY* play, Actor_info* actor_info); +extern void Actor_free_overlay_area(ACTOR_DLFTBL* dlftbl); +extern void Actor_get_overlay_area(ACTOR_DLFTBL* dlftbl, int unused, size_t alloc_size); +extern void Actor_init_actor_class(ACTOR* actor, ACTOR_PROFILE* profile, ACTOR_DLFTBL* dlftbl, GAME_PLAY* play, int bank_idx, f32 x, f32 y, f32 z, s16 rot_x, s16 rot_y, s16 rot_z, s8 block_x, s8 block_z, s16 move_actor_list_idx, mActor_name_t name_id, s16 arg); +#ifndef MUST_MATCH +extern ACTOR* Actor_info_make_actor(Actor_info* actor_info, GAME* game, s16 profile_no, f32 x, f32 y, f32 z, s16 rot_x, s16 rot_y, s16 rot_z, s8 block_x, s8 block_z, s16 move_actor_list_idx, mActor_name_t name_id, s16 arg, s8 npc_info_idx, int data_bank_idx); +#else +extern asm ACTOR* Actor_info_make_actor(Actor_info* actor_info, GAME* game, s16 profile_no, f32 x, f32 y, f32 z, s16 rot_x, s16 rot_y, s16 rot_z, s8 block_x, s8 block_z, s16 move_actor_list_idx, mActor_name_t name_id, s16 arg, s8 npc_info_idx, int data_bank_idx); +#endif +extern ACTOR* Actor_info_make_child_actor(Actor_info* actor_info, ACTOR* parent_actor, GAME* game, s16 profile, f32 x, f32 y, f32 z, s16 rot_x, s16 rot_y, s16 rot_z, s16 move_actor_list_idx, mActor_name_t name_id, s16 arg, int data_bank_idx); +extern void restore_fgdata_all(GAME_PLAY* play); +extern void Actor_info_save_actor(GAME_PLAY* play); +extern ACTOR* Actor_info_delete(Actor_info* actor_info, ACTOR* actor, GAME* game); +extern ACTOR* Actor_info_name_search_sub(ACTOR* actor, s16 name); +extern ACTOR* Actor_info_name_search(Actor_info* actor_info, s16 name, int part); +extern ACTOR* Actor_info_fgName_search_sub(ACTOR* actor, mActor_name_t fgName); +extern ACTOR* Actor_info_fgName_search(Actor_info* actor_info, mActor_name_t fgName, int part); +extern Gfx* HiliteReflect_new(xyz_t* pos, xyz_t* eye, xyz_t* light_direction, GRAPH* graph, Gfx* gfx, Hilite** hilite); +extern Hilite* HiliteReflect_init(xyz_t* pos, xyz_t* eye, xyz_t* light_direction, GRAPH* graph); +extern Hilite* HiliteReflect_xlu_init(xyz_t* pos, xyz_t* eye, xyz_t* light_direction, GRAPH* graph); +extern void Setpos_HiliteReflect_init(xyz_t* pos, GAME_PLAY* play); +extern void Setpos_HiliteReflect_xlu_init(xyz_t* pos, GAME_PLAY* play); extern void mAc_ActorShadowCircle(ACTOR* actor, LightsN* lightsN, GAME_PLAY* play); extern void mAc_ActorShadowEllipse(ACTOR* actor, LightsN* lightsN, GAME_PLAY* play); diff --git a/include/m_bg_item.h b/include/m_bg_item.h index 9f2ff11f..3129b4c5 100644 --- a/include/m_bg_item.h +++ b/include/m_bg_item.h @@ -8,6 +8,7 @@ extern "C" { #endif extern void mBI_ct(); +extern void mBI_move(GAME_PLAY* play); #ifdef __cplusplus } diff --git a/include/m_collision_obj.h b/include/m_collision_obj.h index a48ad3bb..57efa3b2 100644 --- a/include/m_collision_obj.h +++ b/include/m_collision_obj.h @@ -101,6 +101,8 @@ extern void ClObjPipe_set5(GAME_PLAY* play, ClObjPipe_c* pipe, ACTOR* owner, ClO extern void CollisionCheck_Uty_ActorWorldPosSetPipeC(ACTOR* actor, ClObjPipe_c* col_pipe); extern int CollisionCheck_setOC(GAME_PLAY* play, CollisionCheck_c* collision_check, ClObj_c* col_obj); extern void CollisionCheck_Status_set3(Status_c* status, StatusData_c* data); +extern void CollisionCheck_Status_ct(Status_c* status); +extern void CollisionCheck_Status_Clear(Status_c* status); #ifdef __cplusplus } diff --git a/include/m_common_data.h b/include/m_common_data.h index f536adb3..2d46b1d8 100644 --- a/include/m_common_data.h +++ b/include/m_common_data.h @@ -155,7 +155,9 @@ typedef struct common_data_s { /* 0x02614D */ u8 transFadeDuration; /* 0x02614E */ u8 transWipeSpeed; /* 0x02614F */ u8 wipeType; /* maybe unused? */ - /* 0x02614F */ u8 _26150[0x26164 - 0x26150]; + /* 0x026150 */ s16 bg_item_type; + /* 0x026152 */ s16 bg_item_profile; + /* 0x026154 */ u8 _26154[0x26164 - 0x26154]; /* 0x026164 */ mNpc_NpcList_c npclist[ANIMAL_NUM_MAX]; /* 0x0264AC */ mNpc_NpcList_c unk_264AC; // fits exact size of npc list struct, seems unused /* 0x0264E4 */ mNpc_NpcList_c island_npclist[1]; // TODO: define for island npc count @@ -177,7 +179,7 @@ typedef struct common_data_s { /* 0x028530 */ Door_data_c door_data; /* misc door data */ /* 0x028544 */ Door_data_c structure_exit_door_data; /* door data for when exiting a building */ /* 0x028558 */ u8 tmp1[0x028592 - 0x028558]; - /* 0x028592 */ mActor_name_t demo_profiles[2]; + /* 0x028592 */ s16 demo_profiles[mDemo_CLIP_TYPE_NUM - 1]; /* 0x028596 */ u8 _28596[0x285C0 - 0x28596]; /* 0x0285C0 */ s8 player_decoy_flag; /* 0x0285C1 */ u8 _285C1[0x028838 - 0x0285C1]; diff --git a/include/m_field_info.h b/include/m_field_info.h index 53d70032..a2577cbe 100644 --- a/include/m_field_info.h +++ b/include/m_field_info.h @@ -148,6 +148,9 @@ extern mActor_name_t mFI_GetOtherFruit(); extern int mFI_Wpos2UtNum_inBlock(int* ut_x, int* ut_z, xyz_t wpos); extern int mFI_GetItemNumInBlock(mActor_name_t item_no, mActor_name_t* block_items); extern int mFI_BkNum2WposXZ(f32* wpos_x, f32* wpos_z, int block_x, int block_z); +extern void mFI_SetBearActor(GAME_PLAY* play, xyz_t wpos, int update_before_block_table); +extern void mFI_FieldMove(xyz_t player_wpos); +extern int mFI_search_unit_around(xyz_t* wpos, mActor_name_t item); extern void mFI_PrintNowBGNum(gfxprint_t* gfxprint); extern void mFI_PrintFgAttr(gfxprint_t* gfxprint); diff --git a/include/m_kankyo.h b/include/m_kankyo.h index 79ec3ad0..14200d95 100644 --- a/include/m_kankyo.h +++ b/include/m_kankyo.h @@ -2,6 +2,7 @@ #define M_KANKYO_H #include "types.h" +#include "m_lights.h" #ifdef __cplusplus extern "C" { @@ -26,11 +27,20 @@ enum weather_intensity { mEnv_WEATHER_INTENSITY_NUM, }; -typedef struct kankyo_s{ - /*0x00 */ u8 pad[0x9A]; - /*0x9A */ u8 ambientColor[3]; - /*0x9E */ u8 pad2[0x32]; -}Kankyo; +typedef void (*NATURE_PROC)(ACTOR*); + +typedef struct nature_s { + NATURE_PROC proc; + void* arg; +} Nature; + +typedef struct kankyo_s { + /* 0x00 */ Lights sun_light; + /* 0x0E */ u8 pad[0x9A - 0x0E]; + /* 0x9A */ u8 ambientColor[3]; + /* 0x9E */ u8 pad2[0xC8 - 0x9E]; + /* 0xC8 */ Nature nature; +} Kankyo; extern int mEnv_NowWeather(); diff --git a/include/m_lib.h b/include/m_lib.h index 29e6ca26..934c0297 100644 --- a/include/m_lib.h +++ b/include/m_lib.h @@ -46,6 +46,11 @@ typedef struct rgba_t { //can be put in other place u8 r, g, b, a; } rgba_t; +typedef struct { + xyz_t position; + s_xyz angle; +} PositionAngle; + extern void mem_copy(u8* dst, u8* src, size_t size); extern void mem_clear(u8* dst, size_t size, u8 val); extern int mem_cmp(u8* p1, u8* p2, size_t size); diff --git a/include/m_lights.h b/include/m_lights.h index 42ef4d5a..dfcf50bf 100644 --- a/include/m_lights.h +++ b/include/m_lights.h @@ -73,7 +73,7 @@ extern void LightsN_disp_BG(LightsN* lights, GRAPH* graph); extern void LightsN_disp(LightsN* lights, GRAPH* graph); extern void LightsN_list_check(LightsN* lights, LightNode* node, xyz_t* pos); extern void Global_light_ct(Global_light* glight); -extern void Global_light_read(Global_light* glight, GRAPH* graph); +extern LightsN* Global_light_read(Global_light* glight, GRAPH* graph); extern void Global_light_list_new(GAME_PLAY*, Global_light* glight, Lights* light); extern void Global_light_list_delete(Global_light* glight, LightNode* light); extern void Light_list_point_draw(GAME_PLAY* play); diff --git a/include/m_npc.h b/include/m_npc.h index cd68597f..2732cc82 100644 --- a/include/m_npc.h +++ b/include/m_npc.h @@ -207,6 +207,7 @@ extern u8 mNpc_GetPaperType(); extern void mMl_set_mail_name_npcinfo(Mail_nm_c* mail_name, AnmPersonalID_c* anm_pid); extern int mNpc_ReceiveHPMail(Mail_c* hp_mail); extern void mNpc_SendMailtoNpc(Mail_c* mail); +extern void mNpc_SetNpcinfo(ACTOR* actor, s8 npc_info_idx); extern void mNpc_PrintRemoveInfo(gfxprint_t* gfxprint); extern void mNpc_PrintFriendship_fdebug(gfxprint_t* gfxprint); diff --git a/include/m_play.h b/include/m_play.h index d57e2f7f..009ce773 100644 --- a/include/m_play.h +++ b/include/m_play.h @@ -20,11 +20,13 @@ extern "C" { #endif +typedef int (*DRAW_CHK_PROC)(ACTOR*, GAME_PLAY*); + /* sizeof(struct game_play_s) == 0x2600 */ struct game_play_s { /* 0x0000 */ GAME game; // TODO: finish - /* 0x00E0 */ int _00E0; + /* 0x00E0 */ s16 scene_id; /* 0x00E4 */ mFI_block_tbl_c block_table; /* 0x00F4 */ mFI_block_tbl_c last_block_table; /* 0x0104 */ u8 _0104[0x0110 - 0x0104]; @@ -38,10 +40,20 @@ struct game_play_s { /* 0x1DEC */ Submenu submenu; /* 0x1FA4 */ u8 _1FA4[0x2008 - 0x1FA4]; /* 0x2008 */ int next_scene_no; - /* 0x200C */ MtxF matrix; - /* 0x204C */ u8 _204C[0x2090 - 0x204C]; + /* 0x200C */ MtxF projection_matrix; + /* 0x204C */ MtxF mtx_204C; + /* 0x208C */ int _208C; /* 0x2090 */ u32 game_frame; - /* 0x2094 */ u8 _2094[0x20D0 - 0x2094]; + /* 0x2094 */ u8 _2094; + /* 0x2095 */ u8 actor_data_num; + /* 0x2096 */ u8 ctrl_actor_data_num; + /* 0x2097 */ u8 obj_bank_data_num; + /* 0x2098 */ Actor_data* player_data; + /* 0x209C */ Actor_data* actor_data; + /* 0x20A0 */ s16* ctrl_actor_data; + /* 0x20A4 */ s16* obj_bank_data; + /* 0x20A8 */ int _20A8; + /* 0x20AC */ u8 _20AC[0x20D0 - 0x20AC]; /* 0x20D0 */ u8 fb_fade_type; /* 0x20D1 */ u8 fb_wipe_type; /* 0x20D2 */ u8 fb_mode; @@ -49,7 +61,8 @@ struct game_play_s { /* 0x20D8 */ fbdemo_wipe fbdemo_wipe; /* 0x2318 */ fbdemo_fade color_fade; /* 0x2328 */ CollisionCheck_c collision_check; - /* 0x23F8 */ u8 _23F8[0x2600 - 0x23F8]; + /* 0x23F8 */ DRAW_CHK_PROC draw_chk_proc; // only used by mikanbox actor + /* 0x23FC */ u8 _23FC[0x2600 - 0x23FC]; }; diff --git a/include/m_scene.h b/include/m_scene.h index 89542997..dfbcee91 100644 --- a/include/m_scene.h +++ b/include/m_scene.h @@ -26,14 +26,22 @@ typedef struct object_bank_s { s16 bank_id; char* ram_start; // TODO: others - u8 _08[0x5C - 8]; + u8 _08[0x58 - 0x08]; + s16 num_exist; + u8 _0x5A[0x5C - 0x5A]; } Object_Bank_c; typedef struct object_exchange_s { Object_Bank_c banks[mSc_OBJECT_BANK_NUM]; - u8 _1928[0x1958-0x1928]; + int _1928; + int _192C; + int exchange_id; + u8 _1934[0x1958-0x1934]; } Object_Exchange_c; +extern int mSc_bank_regist_check(Object_Exchange_c* exchange, s16 bank_id); +extern void mSc_regist_initial_exchange_bank(GAME_PLAY* play); + #ifdef __cplusplus } #endif diff --git a/include/m_skin_matrix.h b/include/m_skin_matrix.h index f8caaf74..9f4e91f4 100644 --- a/include/m_skin_matrix.h +++ b/include/m_skin_matrix.h @@ -2,12 +2,13 @@ #define SKIN_MATRIX_H #include "libultra/ultratypes.h" +#include "libu64/u64types.h" #ifdef __cplusplus extern "C"{ #endif -void Skin_Matrix_PrjMulVector(MtxF*, Vec3f*, Vec3f*, f32*); +void Skin_Matrix_PrjMulVector(MtxF*, xyz_t*, xyz_t*, f32*); void Skin_Matrix_MulMatrix(MtxF*, MtxF*, MtxF*); void Skin_Matrix_SetScale(MtxF* , f32 , f32, f32); void Skin_Matrix_SetTranslate(MtxF*, f32, f32, f32); diff --git a/rel/ac_airplane.c b/rel/ac_airplane.c index 3bd74e61..3a7d374e 100644 --- a/rel/ac_airplane.c +++ b/rel/ac_airplane.c @@ -43,7 +43,7 @@ static void Airplane_Actor_ct(ACTOR* actor, GAME* game) { airplane->y_speed = 0.0f; airplane->actor_class.speed = airplane->speed; - airplane->rotY = RAD2DEG(SHORTANGLE2RAD((f32)actor->world_rotation.y)); + airplane->rotY = RAD2DEG(SHORTANGLE2RAD((f32)actor->world.angle.y)); airplane->rotY_goal = airplane->rotY; airplane->rotY_min = airplane->rotY; airplane->rotZ = 0.0f; @@ -54,7 +54,7 @@ static void Airplane_Actor_ct(ACTOR* actor, GAME* game) { airplane->wind_change_frame = 0; airplane->wind = NULL; - actor->world_position.y = mCoBG_GetBgY_AngleS_FromWpos(NULL, actor->world_position, -5.5f); + actor->world.position.y = mCoBG_GetBgY_AngleS_FromWpos(NULL, actor->world.position, -5.5f); } static void Airplane_Actor_dt(ACTOR* actor, GAME* game) { } @@ -105,7 +105,7 @@ static void aAp_GroundFriction(ACTOR* actor, GAME* game) { if (airplane->ground_timer >= 5) { airplane->ground_timer = 0; - (*Common_Get(clip.effect_clip)->effect_make_proc)(eEC_EFFECT_DUST, actor->world_position, 1, actor->world_rotation.y, game, actor->npc_id, 0, 8); + (*Common_Get(clip.effect_clip)->effect_make_proc)(eEC_EFFECT_DUST, actor->world.position, 1, actor->world.angle.y, game, actor->npc_id, 0, 8); } airplane->ground_timer++; @@ -196,9 +196,9 @@ static void aAp_StartFlyMove(ACTOR* actor, GAME* game) { goal_angle_random_tbl = adjusted_y > 50 ? goal_angle_random2 : goal_angle_random; - actor->world_position.y = player->actor_class.world_position.y + 25.0f; - actor->world_position.x = player->actor_class.world_position.x; - actor->world_position.z = player->actor_class.world_position.z; + actor->world.position.y = player->actor_class.world.position.y + 25.0f; + actor->world.position.x = player->actor_class.world.position.x; + actor->world.position.z = player->actor_class.world.position.z; airplane->rotY = RAD2DEG(SHORTANGLE2RAD(player->actor_class.shape_info.rotation.y)); airplane->rotY_goal = airplane->rotY + (RAD2DEG(SHORTANGLE2RAD(goal_angle_random_tbl[goal]))); @@ -226,10 +226,10 @@ static void aAp_FallFlyMove(ACTOR* actor, GAME* game) { aAp_RubberMove(&airplane->rotX, 60.0f, 0.04f); aAp_RubberMove(&airplane->speed, 5.0f, 0.02f); - actor->world_position.y -= 0.15f; + actor->world.position.y -= 0.15f; if (actor->bg_collision_check.result.on_ground) { - Common_Get(clip.effect_clip)->effect_make_proc(eEC_EFFECT_DUST, actor->world_position, 1, actor->world_rotation.y, game, actor->npc_id, 0, 8); + Common_Get(clip.effect_clip)->effect_make_proc(eEC_EFFECT_DUST, actor->world.position, 1, actor->world.angle.y, game, actor->npc_id, 0, 8); airplane->status = aAp_STATUS_STOP_FLY_MOVE; } } @@ -239,10 +239,10 @@ static void aAp_FallFlyMove2(ACTOR* actor, GAME* game) { aAp_RubberMove(&airplane->rotX, 70.0f, 0.15f); aAp_RubberMove(&airplane->speed, 10.0f, 0.02f); - actor->world_position.y -= 0.15f; + actor->world.position.y -= 0.15f; if (actor->bg_collision_check.result.on_ground) { - Common_Get(clip.effect_clip)->effect_make_proc(eEC_EFFECT_DUST, actor->world_position, 1, actor->world_rotation.y, game, actor->npc_id, 0, 8); + Common_Get(clip.effect_clip)->effect_make_proc(eEC_EFFECT_DUST, actor->world.position, 1, actor->world.angle.y, game, actor->npc_id, 0, 8); airplane->status = aAp_STATUS_STOP_FLY_MOVE; } } @@ -302,8 +302,8 @@ static void aAp_CommonHandle(ACTOR* actor, AIRPLANE_ACTOR* airplane, GAME* game) actor->speed = airplane->speed * cosf_table(DEG2RAD(airplane->rotX)); airplane->y_speed = airplane->speed * sinf_table(DEG2RAD(airplane->rotX)); - actor->world_position.y -= airplane->y_speed; - actor->world_rotation.y = RAD2SHORTANGLE(DEG2RAD(airplane->rotY)); + actor->world.position.y -= airplane->y_speed; + actor->world.angle.y = RAD2SHORTANGLE(DEG2RAD(airplane->rotY)); actor->shape_info.rotation.y = RAD2SHORTANGLE(DEG2RAD(airplane->rotY)); Actor_position_moveF(actor); diff --git a/rel/ac_douzou.c b/rel/ac_douzou.c index 2eefc68c..bd7e25e2 100644 --- a/rel/ac_douzou.c +++ b/rel/ac_douzou.c @@ -13,7 +13,7 @@ static void aDOU_actor_draw(ACTOR*, GAME*); ACTOR_PROFILE Douzou_Profile = { mAc_PROFILE_DOUZOU, ACTOR_PART_ITEM, - ACTOR_STATE_11, + ACTOR_STATE_TA_SET, DOUZOU, ACTOR_OBJ_BANK_3, sizeof(STRUCTURE_ACTOR), @@ -172,11 +172,11 @@ static void aDOU_actor_ct(ACTOR* actor, GAME* game) { cKF_SkeletonInfo_R_ct(&douzou->keyframe, skl[douzou->season == mTM_SEASON_WINTER], NULL, douzou->work_area, douzou->morph_area); aDOU_set_bgOffset(actor, 1); - wpos.x = actor->world_position.x + xpostbl[0]; - wpos.y = actor->world_position.y; - wpos.z = actor->world_position.z + zpostbl[0]; + wpos.x = actor->world.position.x + xpostbl[0]; + wpos.y = actor->world.position.y; + wpos.z = actor->world.position.z + zpostbl[0]; - actor->world_position.y = mCoBG_GetBgY_OnlyCenter_FromWpos2(wpos, 0.0f); + actor->world.position.y = mCoBG_GetBgY_OnlyCenter_FromWpos2(wpos, 0.0f); actor->cull_width = 850.0f; actor->cull_radius = 850.0f; diff --git a/rel/ac_douzou_draw.c_inc b/rel/ac_douzou_draw.c_inc index ab08b31e..c8f1f883 100644 --- a/rel/ac_douzou_draw.c_inc +++ b/rel/ac_douzou_draw.c_inc @@ -133,7 +133,7 @@ static void aDOU_actor_draw(ACTOR* actor, GAME* game) { { xyz_t wpos; - xyz_t_move(&wpos, &actor->world_position); + xyz_t_move(&wpos, &actor->world.position); wpos.x += xpostbl[i]; wpos.z += zpostbl[i]; diff --git a/rel/ac_douzou_move.c_inc b/rel/ac_douzou_move.c_inc index b7589ecd..09b6553c 100644 --- a/rel/ac_douzou_move.c_inc +++ b/rel/ac_douzou_move.c_inc @@ -66,7 +66,7 @@ static void aDOU_keep_item(ACTOR* actor) { for (i = 0; i < mHS_HOUSE_NUM; i++) { if (aDOU_set_check(i)) { - xyz_t_move(&wpos, &actor->world_position); + xyz_t_move(&wpos, &actor->world.position); wpos.x += xpostbl[i]; wpos.z += zpostbl[i]; KeepItem(wpos); @@ -98,7 +98,7 @@ static int aDOU_setEffect_sub(ACTOR* actor, GAME* game, int house_no, int color) Matrix_push(); /* Initialize base position */ - xyz_t_move(&wpos, &actor->world_position); + xyz_t_move(&wpos, &actor->world.position); wpos.x += xpostbl[house_no]; wpos.z += zpostbl[house_no]; Matrix_translate(wpos.x, wpos.y, wpos.z, 0); @@ -163,7 +163,7 @@ static void aDOU_set_bgOffset(ACTOR* actor, int height) { int i; for (i = 0; i < mHS_HOUSE_NUM; i++) { if (aDOU_set_check(i)) { - xyz_t_move(&wpos, &actor->home_position); + xyz_t_move(&wpos, &actor->home.position); wpos.x += xpostbl[i]; wpos.z += zpostbl[i]; @@ -212,11 +212,11 @@ static void aDOU_wait(ACTOR* actor, GAME* game) { if (mDemo_Check(mDemo_TYPE_SPEAK, actor) == TRUE) { i = douzou->arg2; - xyz_t_move(&wpos, &actor->world_position); + xyz_t_move(&wpos, &actor->world.position); wpos.x += xpostbl[i]; wpos.z += zpostbl[i]; - target = search_position_angleY(&player->actor_class.world_position, &wpos); + target = search_position_angleY(&player->actor_class.world.position, &wpos); now_angle = player->actor_class.shape_info.rotation.y; add_calc_short_angle2(&now_angle, target, 0.3f, 0x1000, 0); target_rot.x = player->actor_class.shape_info.rotation.x; @@ -232,15 +232,15 @@ static void aDOU_wait(ACTOR* actor, GAME* game) { f32 dist_xz; s16 angle_y; - xyz_t_move(&t_wpos, &actor->world_position); + xyz_t_move(&t_wpos, &actor->world.position); for (i = 0; i < mHS_HOUSE_NUM; i++) { if (aDOU_set_check(i)) { wpos.x = t_wpos.x + xpostbl[i]; wpos.z = t_wpos.z + zpostbl[i]; - dist_xz = search_position_distanceXZ(&player->actor_class.world_position, &wpos); - now_angle = search_position_angleY(&wpos, &player->actor_class.world_position); + dist_xz = search_position_distanceXZ(&player->actor_class.world.position, &wpos); + now_angle = search_position_angleY(&wpos, &player->actor_class.world.position); if (dist_xz > 50.0f) { @@ -291,7 +291,7 @@ static void aDOU_actor_move(ACTOR* actor, GAME* game) { } static void aDOU_actor_init(ACTOR* actor, GAME* game) { - mFI_SetFG_common(DUMMY_DOUZOU, actor->home_position, FALSE); + mFI_SetFG_common(DUMMY_DOUZOU, actor->home.position, FALSE); aDOU_actor_move(actor, game); actor->mv_proc = &aDOU_actor_move; } diff --git a/rel/ac_haniwa.c b/rel/ac_haniwa.c index 0f6d2547..314b40e2 100644 --- a/rel/ac_haniwa.c +++ b/rel/ac_haniwa.c @@ -723,7 +723,7 @@ static void aHNW_pl_approach_door(ACTOR* actor, GAME* game) { if (player != NULL) { int house_idx = haniwa->house_idx; - int stage = ((chk_posX[house_idx] - player->actor_class.world_position.x) * chk_val[house_idx]) <= 0.0f; + int stage = ((chk_posX[house_idx] - player->actor_class.world.position.x) * chk_val[house_idx]) <= 0.0f; xyz_t* goal = goal_pos[house_idx] + stage; if (haniwa->player_approach_door_stage != stage && mPlib_request_main_demo_walk_type1(game, goal->x, goal->z, 3.0f, FALSE)) { @@ -736,11 +736,11 @@ static void aHNW_pl_approach_door(ACTOR* actor, GAME* game) { MY_HOUSE_ACTOR* house_actor = (MY_HOUSE_ACTOR*)Actor_info_fgName_search(&play->actor_info, HOUSE0 + haniwa->house_idx, ACTOR_PART_ITEM); if (house_actor != NULL) { - house_actor->actor_class.world_rotation.z = 1; + house_actor->actor_class.world.angle.z = 1; aHNW_setupAction(actor, game, aHNW_ACTION_WAIT); } } - else if (stage == 1 && search_position_distanceXZ(goal, &player->actor_class.world_position) < 3.0f) { + else if (stage == 1 && search_position_distanceXZ(goal, &player->actor_class.world.position) < 3.0f) { aHNW_setupAction(actor, game, aHNW_ACTION_DOOR_OPEN_WAIT); } } @@ -776,7 +776,7 @@ static void aHNW_door_open_timer(ACTOR* actor, GAME* game) { else { haniwa->door_approach_frame++; if (haniwa->door_approach_frame > 80) { - house_actor->actor_class.world_rotation.z = 1; + house_actor->actor_class.world.angle.z = 1; aHNW_setupAction(actor, game, aHNW_ACTION_WAIT); } } @@ -960,7 +960,7 @@ static void aHNW_actor_init(ACTOR* actor, GAME* game) { HANIWA_ACTOR* haniwa = (HANIWA_ACTOR*)actor; int house_idx = haniwa->house_idx; - mFI_SetFG_common((mActor_name_t)(house_idx + DUMMY_HANIWA0), actor->world_position, FALSE); + mFI_SetFG_common((mActor_name_t)(house_idx + DUMMY_HANIWA0), actor->world.position, FALSE); actor->mv_proc = &aHNW_actor_move; actor->dw_proc = &aHNW_actor_draw; aHNW_setupAction((ACTOR*)haniwa, game, aHNW_ACTION_WAIT); // weird that we have to re-cast to ACTOR so fequently for matches diff --git a/rel/ac_sample.c b/rel/ac_sample.c index 42216fdb..a415cb91 100644 --- a/rel/ac_sample.c +++ b/rel/ac_sample.c @@ -87,7 +87,7 @@ static void Ac_Sample_Actor_main_talk(SAMPLE_ACTOR* actor, GAME_PLAY* play) { if (mDemo_Check(mDemo_TYPE_TALK, (ACTOR*)actor)) { s16 angle = add_calc_short_angle2(&actor->actor_class.shape_info.rotation.y, actor->actor_class.player_angle_y, 1.0f, 5000, 100); - actor->actor_class.world_rotation.y = actor->actor_class.shape_info.rotation.y; + actor->actor_class.world.angle.y = actor->actor_class.shape_info.rotation.y; if (mDemo_Check_ListenAble() == FALSE && mDemo_Check_DiffAngle_forTalk(angle)) { mDemo_Set_ListenAble(); diff --git a/rel/ac_set_manager.c b/rel/ac_set_manager.c index db0827c8..fb78378c 100644 --- a/rel/ac_set_manager.c +++ b/rel/ac_set_manager.c @@ -19,7 +19,7 @@ static int aSetMgr_get_player_block(int* bx, int* bz, GAME_PLAY* play) { PLAYER_ACTOR* player_actor = get_player_actor_withoutCheck(play); if (player_actor != NULL) { - res = mFI_Wpos2BlockNum(bx, bz, player_actor->actor_class.world_position); + res = mFI_Wpos2BlockNum(bx, bz, player_actor->actor_class.world.position); } return res; diff --git a/rel/ac_train0.c b/rel/ac_train0.c index 3a151378..6c359b08 100644 --- a/rel/ac_train0.c +++ b/rel/ac_train0.c @@ -39,7 +39,7 @@ static void aTR0_actor_ct(ACTOR* actor, GAME* GAME){ 1.0f, 25.0f, 1.0f, 0.5f, 0.0f, 1, NULL); cKF_SkeletonInfo_R_play(&train0->keyframe); train0->actor_class.cull_width = 600.0f; - train0->actor_class.world_rotation.y = 16384; + train0->actor_class.world.angle.y = 16384; train0->tr_action = 5; } @@ -49,7 +49,7 @@ static void aTR0_actor_dt(ACTOR* actor, GAME* game){ xyz_t tr_home_pos; - tr_home_pos = train0->actor_class.home_position; + tr_home_pos = train0->actor_class.home.position; mFI_SetFG_common(0, tr_home_pos, 0); @@ -73,13 +73,13 @@ static void aTR0_ctrl_engineer(ACTOR* actor, GAME* game){ if(ac_p == NULL){ if((*Common_Get(clip.npc_clip)->setupActor_proc)(play, SP_NPC_ENGINEER, -1,-1,-1,-1,-1,0,0) == 1){ - train0->tr_actor_p = Actor_info_fgName_search(&play->actor_info, SP_NPC_ENGINEER, ACTOR_PART_4); + train0->tr_actor_p = Actor_info_fgName_search(&play->actor_info, SP_NPC_ENGINEER, ACTOR_PART_NPC); } } else{ - ac_p->world_position.x = -40.0f + train0->actor_class.world_position.x; - ac_p->world_position.y = 47.0f + train0->actor_class.world_position.y; - ac_p->world_position.z = 20.0f + train0->actor_class.world_position.z; + ac_p->world.position.x = -40.0f + train0->actor_class.world.position.x; + ac_p->world.position.y = 47.0f + train0->actor_class.world.position.y; + ac_p->world.position.z = 20.0f + train0->actor_class.world.position.z; } } @@ -97,7 +97,7 @@ static void aTR0_set_effect(ACTOR* actor, GAME* game){ else{ train0->effect_num = 12; } - xyz_t_move(&pos, &train0->actor_class.world_position); + xyz_t_move(&pos, &train0->actor_class.world.position); pos.x += 36.0f; pos.y += 110.0f; @@ -119,9 +119,9 @@ static void aTR0_steam_work_sub(ACTOR* actor, GAME* game, int x_idx){ static f32 setX[] = {15.0f, 22.0f}; static s16 angl[] = {0xd000, 0x0400}; - pos.x = train0->actor_class.world_position.x + setX[x_idx]; - pos.y = train0->actor_class.world_position.y + 21.0f; - pos.z = train0->actor_class.world_position.z + 42.0f; + pos.x = train0->actor_class.world.position.x + setX[x_idx]; + pos.y = train0->actor_class.world.position.y + 21.0f; + pos.z = train0->actor_class.world.position.z + 42.0f; unk2c0 = train0->unk2c0; if(mEv_CheckTitleDemo() == 0){ clip_pos = pos; @@ -169,7 +169,7 @@ static void aTR0_ctrl_back_car(ACTOR* actor){ TRAIN0_ACTOR* train0 = (TRAIN0_ACTOR*)actor; f32 tr_back_calc = train0->tr1_pos; - f32 base_x_pos = -125.0f + train0->actor_class.world_position.x; + f32 base_x_pos = -125.0f + train0->actor_class.world.position.x; tr_back_calc += 0.5f * train0->tr_speed; if((tr_back_calc - base_x_pos) > 2.0f){ @@ -208,8 +208,8 @@ static void aTR0_move(ACTOR* actor){ train0->tr_action = Common_Get(train_action); } pos = Common_Get(train_position); - train0->actor_class.world_position.x = pos.x; - train0->actor_class.world_position.z = pos.z; + train0->actor_class.world.position.x = pos.x; + train0->actor_class.world.position.z = pos.z; train0->actor_class.speed = Common_Get(train_speed); } @@ -222,7 +222,7 @@ static void aTR0_delcheck(ACTOR* actor,GAME* game){ int abs_x; xyz_t pos; - pos = train0->actor_class.world_position; + pos = train0->actor_class.world.position; mFI_Wpos2BlockNum(&x,&z,pos); x -= play->block_table.block_x; @@ -251,7 +251,7 @@ static void aTR0_actor_move(ACTOR* actor, GAME* game){ } if(mEv_CheckTitleDemo() == 1){ - train0->tr1_pos = -125.0f + train0->actor_class.world_position.x; + train0->tr1_pos = -125.0f + train0->actor_class.world.position.x; } else{ aTR0_ctrl_back_car(actor); @@ -284,8 +284,8 @@ static void aTR0_actor_draw(ACTOR* actor, GAME* game){ if (mtx != NULL){ _texture_z_light_fog_prim_npc(graph); Matrix_push(); - Matrix_translate(train0->tr1_pos, train0->actor_class.world_position.y, - train0->actor_class.world_position.z, 0); + Matrix_translate(train0->tr1_pos, train0->actor_class.world.position.y, + train0->actor_class.world.position.z, 0); Matrix_scale(train0->actor_class.scale.x, train0->actor_class.scale.y, train0->actor_class.scale.z, 1); diff --git a/rel/ac_train1.c b/rel/ac_train1.c index fc209acb..6a62b4e2 100644 --- a/rel/ac_train1.c +++ b/rel/ac_train1.c @@ -44,7 +44,7 @@ static void aTR1_actor_ct(ACTOR* actor, GAME* game){ cKF_SkeletonInfo_R_ct(&train1->keyframe, &cKF_bs_r_obj_train1_3, NULL, train1->work, train1->morph); aTR1_setupAction((ACTOR*)train1, 5); train1->anim_state = cKF_SkeletonInfo_R_play(&train1->keyframe); - actor->world_rotation.y = 0x4000; + actor->world.angle.y = 0x4000; train1->tr_speed = 1.0f; } @@ -54,7 +54,7 @@ static void aTR1_actor_dt(ACTOR* actor, GAME* game){ xyz_t tr_home_pos; - tr_home_pos = train1->actor_class.home_position; + tr_home_pos = train1->actor_class.home.position; mFI_SetFG_common(EMPTY_NO, tr_home_pos, FALSE); cKF_SkeletonInfo_R_dt(&train1->keyframe); @@ -63,7 +63,7 @@ static void aTR1_actor_dt(ACTOR* actor, GAME* game){ static void aTR1_OngenTrgStart(ACTOR* actor, u16 id){ TRAIN1_ACTOR* train1 = (TRAIN1_ACTOR*)actor; - sAdo_OngenTrgStart(id, &train1->actor_class.world_position); + sAdo_OngenTrgStart(id, &train1->actor_class.world.position); } static f32 calc_speed1(ACTOR* actor0, ACTOR* actor1) { @@ -96,22 +96,22 @@ static void aTR1_position_move(ACTOR* actor){ f32 tr_back_calc; f32 base_x_pos; - tr_back_calc = train1->actor_class.world_position.x; + tr_back_calc = train1->actor_class.world.position.x; base_x_pos = -125.0f + train0->tr1_pos; tr_back_calc += 0.5f * train1->actor_class.speed; diff = tr_back_calc - base_x_pos; if((diff) <= 0.0f){ train1->actor_class.speed = calc_speed1(actor->parent_actor, actor); - train1->actor_class.world_position.x = base_x_pos; + train1->actor_class.world.position.x = base_x_pos; } else if((diff) > 2.0f){ train1->actor_class.speed = calc_speed2(actor->parent_actor); - train1->actor_class.world_position.x = 2.0f + base_x_pos; + train1->actor_class.world.position.x = 2.0f + base_x_pos; } else{ chase_f(&train1->actor_class.speed, 0.0f, 0.0025f); - train1->actor_class.world_position.x = tr_back_calc; + train1->actor_class.world.position.x = tr_back_calc; } } @@ -140,18 +140,18 @@ static void aTR1_passenger_ctrl(ACTOR* actor){ s_xyz rot; if(train1->player_pass_exists == 1){ - pos.x = train1->actor_class.world_position.x + 60.0f; - pos.y = train1->actor_class.world_position.y + 20.0f; - pos.z = train1->actor_class.world_position.z + 20.0f; + pos.x = train1->actor_class.world.position.x + 60.0f; + pos.y = train1->actor_class.world.position.y + 20.0f; + pos.z = train1->actor_class.world.position.z + 20.0f; rot.x = ZeroSVec.x; rot.y = ZeroSVec.y; rot.z = ZeroSVec.z; get_player_actor_withoutCheck((GAME_PLAY*)gamePT)->Set_force_position_angle_proc(gamePT, &pos, &rot, mPlayer_FORCE_POSITION_ANGLE_POSX | mPlayer_FORCE_POSITION_ANGLE_POSY | mPlayer_FORCE_POSITION_ANGLE_POSZ | mPlayer_FORCE_POSITION_ANGLE_ROTY); } else if(train1->player_pass_leaving == 1){ - pos.x = train1->actor_class.world_position.x + 2.0f; - pos.y = train1->actor_class.world_position.y + 16.0f; - pos.z = train1->actor_class.world_position.z + 20.0f; + pos.x = train1->actor_class.world.position.x + 2.0f; + pos.y = train1->actor_class.world.position.y + 16.0f; + pos.z = train1->actor_class.world.position.z + 20.0f; get_player_actor_withoutCheck((GAME_PLAY*)gamePT)->Set_force_position_angle_proc(gamePT, &pos, NULL, mPlayer_FORCE_POSITION_ANGLE_POSX | mPlayer_FORCE_POSITION_ANGLE_POSY | mPlayer_FORCE_POSITION_ANGLE_POSZ); } diff --git a/rel/ac_train_door.c b/rel/ac_train_door.c index 97d9d687..a95ff034 100644 --- a/rel/ac_train_door.c +++ b/rel/ac_train_door.c @@ -52,7 +52,7 @@ static void aTRD_set_door_SE(ACTOR* actor){ for(i = 0; i < 2; i++){ if(cKF_FrameControl_passCheck_now(&traindoor->keyframe.frame_control,chk_pat[i]) != 0){ - sAdo_OngenTrgStart(se_no[i], &traindoor->actor_class.world_position); + sAdo_OngenTrgStart(se_no[i], &traindoor->actor_class.world.position); return; } } diff --git a/rel/m_actor.c b/rel/m_actor.c new file mode 100644 index 00000000..76fb69a7 --- /dev/null +++ b/rel/m_actor.c @@ -0,0 +1,1031 @@ +#include "m_actor.h" + +#include "m_play.h" +#include "m_player_lib.h" +#include "m_name_table.h" +#include "ac_npc.h" +#include "m_scene.h" +#include "m_lib.h" +#include "m_bg_item.h" +#include "m_lights.h" +#include "m_collision_obj.h" +#include "libforest/gbi_extensions.h" +#include "sys_matrix.h" +#include "libultra/libultra.h" +#include "m_field_info.h" +#include "m_event.h" +#include "m_skin_matrix.h" +#include "m_npc.h" +#include "m_malloc.h" +#include "m_common_data.h" + +#ifdef MUST_MATCH +#include "ppcdis.h" + +void _savefpr_29(); +void _restfpr_29(); +//#include "orderstrings/8064d600_8064d604.inc" +static char lbl_8064d600[] = ""; +//#include "orderfloats/806412e8_806412f0.inc" +asm void FORCESTRIP order_floats_806412e8() { + lfs f1, 1.0; + lfs f1, 0.5; +} +#endif + +extern void Actor_world_to_eye(ACTOR* actor, f32 eye_height) { + /* Update position */ + actor->eye.position.x = actor->world.position.x; + actor->eye.position.y = actor->world.position.y + eye_height; + actor->eye.position.z = actor->world.position.z; + + /* Update rotation */ + actor->eye.angle.x = actor->world.angle.x; + actor->eye.angle.y = actor->world.angle.y; + actor->eye.angle.z = actor->world.angle.z; +} + +extern void Actor_position_move(ACTOR* actor) { + (*((GAME_PLAY*)gamePT)->kankyo.nature.proc)(actor); + + /* divide by 2 because of 30fps -> 60fps? */ + actor->world.position.x += 0.5f * actor->position_speed.x + actor->status_data.collision_vec.x; + actor->world.position.y += 0.5f * actor->position_speed.y + actor->status_data.collision_vec.y; + actor->world.position.z += 0.5f * actor->position_speed.z + actor->status_data.collision_vec.z; +} + +extern void Actor_position_speed_set(ACTOR* actor) { + actor->position_speed.x = actor->speed * sin_s(actor->world.angle.y); + actor->position_speed.z = actor->speed * cos_s(actor->world.angle.y); + + /* divide by 2 because of 30fps -> 60fps? */ + chase_f(&actor->position_speed.y, actor->max_velocity_y, 0.5f * actor->gravity); +} + +extern void Actor_position_moveF(ACTOR* actor) { + Actor_position_speed_set(actor); + Actor_position_move(actor); +} + +extern int Actor_player_look_direction_check(ACTOR* actor, s16 angle, GAME_PLAY* play) { + s16 player_rot_y = get_player_actor_withoutCheck(play)->actor_class.shape_info.rotation.y; + s16 inv_angle = actor->player_angle_y - -0x8000; + s16 diff = inv_angle - player_rot_y; + int delta = ABS(diff); + + return delta < angle; +} + +/* @unused ? Actor_display_position_set(... ?) */ + +static int Actor_data_bank_dma_end_check(ACTOR* actor, GAME_PLAY* play) { + switch (ITEM_NAME_GET_TYPE(actor->npc_id)) { + case NAME_TYPE_SPNPC: + case NAME_TYPE_NPC: + return TRUE; + } + + return TRUE; +} + +extern void Shape_Info_init(ACTOR* actor, f32 ofs_y, mActor_shadow_proc shadow_proc, f32 shadow_size_x, f32 shadow_size_z) { + actor->shape_info.ofs_y = ofs_y; + actor->shape_info.shadow_proc = shadow_proc; + actor->shape_info.shadow_size_x = shadow_size_x; + actor->shape_info.shadow_size_z = shadow_size_z; + actor->shape_info.draw_shadow = TRUE; + actor->shape_info.shadow_position = &actor->world.position; + actor->shape_info.unk_20 = 0; + actor->shape_info.shadow_size_change_rate = 1.0f; + actor->shape_info.shadow_alpha_change_rate = 1.0f; + actor->shape_info.force_shadow_position = FALSE; + + #ifndef BUGFIXES + actor->shape_info.shadow_position = &actor->world.position; // ??? + #endif + + actor->shape_info.unk_28 = -1; + actor->shape_info.unk_2D = 0; +} + +extern void Actor_delete(ACTOR* actor) { + if (actor == NULL) { + return; + } + + actor->mv_proc = NULL; + actor->dw_proc = NULL; +} + +static void Actor_ct(ACTOR* actor, GAME* game) { + GAME_PLAY* play = (GAME_PLAY*)game; + Object_Exchange_c* exchange; + Object_Bank_c* bank; + + exchange = &play->object_exchange; + bank = &exchange->banks[actor->data_bank_id]; + + bank->num_exist++; + if (actor->part == ACTOR_PART_NPC) { + NPC_ACTOR* npc_actor = (NPC_ACTOR*)actor; + aNPC_draw_data_c draw_data; + int tex_bank_id; + + (*Common_Get(clip).npc_clip->dma_draw_data_proc)(&draw_data, actor->npc_id); + tex_bank_id = mSc_bank_regist_check(exchange, draw_data.texture_bank); + npc_actor->texture_bank_idx = tex_bank_id; + + bank = &exchange->banks[tex_bank_id]; + bank->num_exist++; + } + + /* Initialize world position & rotation to home position & rotation */ + actor->world = actor->home; + actor->shape_info.rotation = actor->world.angle; + Actor_world_to_eye(actor, 0.0f); + xyz_t_move(&actor->last_world_position, &actor->world.position); + + actor->scale.x = 0.01f; + actor->scale.y = 0.01f; + actor->scale.z = 0.01f; + actor->max_velocity_y = -20.0f; + actor->player_distance = 3.4028235E+38; + actor->cull_width = 350.0f; + actor->cull_height = 700.0f; + actor->cull_distance = 1000.0f; + actor->cull_radius = 350.0f; + actor->talk_distance = 55.0f; + actor->shape_info.shadow_size_change_rate = 1.0f; + actor->shape_info.shadow_alpha_change_rate = 1.0f; + CollisionCheck_Status_ct(&actor->status_data); + Shape_Info_init(actor, 0.0f, NULL, 0.0f, 0.0f); + + if (Actor_data_bank_dma_end_check(actor, play) == TRUE) { + (*actor->ct_proc)(actor, game); + actor->ct_proc = NULL; + } +} + +static void Actor_dt(ACTOR* actor, GAME* game) { + GAME_PLAY* play = (GAME_PLAY*)game; + Object_Exchange_c* exchange; + ACTOR* t; + + if (actor->sv_proc != NULL) { + (*actor->sv_proc)(actor, game); + actor->sv_proc = NULL; + } + + if (actor->dt_proc != NULL) { + (*actor->dt_proc)(actor, game); + actor->dt_proc = NULL; + } + + t = actor->child_actor; + if (t != NULL && t->parent_actor == actor) { + t->parent_actor = NULL; + } + + t = actor->parent_actor; + if (t != NULL && t->child_actor == actor) { + t->child_actor = NULL; + } + + exchange = &play->object_exchange; + if (ITEM_NAME_GET_TYPE(actor->npc_id) >= NAME_TYPE_PAD15 || ITEM_NAME_GET_TYPE(actor->npc_id) < NAME_TYPE_SPNPC) { + int bank_id = actor->data_bank_id; + + if (bank_id >= exchange->exchange_id && exchange->banks[bank_id].num_exist > 0) { + actor->data_bank_id = -1; + exchange->banks[bank_id].num_exist--; + } + } +} + +static void Actor_draw_ta_set(ACTOR* actor, GAME_PLAY* play) { + GRAPH* g; + + if ((actor->state_bitfield & ACTOR_STATE_TA_SET) == 0) { + return; + } + + g = play->game.graph; + OPEN_DISP(g); + + gDPSetTextureAdjustMode(NOW_POLY_OPA_DISP++, G_SPECIAL_TA_MODE, G_TA_DOLPHIN); + gDPSetTextureAdjustMode(NOW_SHADOW_DISP++, G_SPECIAL_TA_MODE, G_TA_DOLPHIN); + gDPSetTextureAdjustMode(NOW_POLY_XLU_DISP++, G_SPECIAL_TA_MODE, G_TA_DOLPHIN); + + gDPSetTexEdgeAlpha(NOW_POLY_OPA_DISP++, 127); + gDPSetTexEdgeAlpha(NOW_SHADOW_DISP++, 127); + gDPSetTexEdgeAlpha(NOW_POLY_XLU_DISP++, 127); + + CLOSE_DISP(g); +} + +static void Actor_draw_ta_clr(ACTOR* actor, GAME_PLAY* play) { + GRAPH* g; + + if ((actor->state_bitfield & ACTOR_STATE_TA_SET) == 0) { + return; + } + + g = play->game.graph; + OPEN_DISP(g); + + gDPSetTextureAdjustMode(NOW_POLY_OPA_DISP++, G_SPECIAL_TA_MODE, G_TA_N64); + gDPSetTextureAdjustMode(NOW_SHADOW_DISP++, G_SPECIAL_TA_MODE, G_TA_N64); + gDPSetTextureAdjustMode(NOW_POLY_XLU_DISP++, G_SPECIAL_TA_MODE, G_TA_N64); + + gDPSetTexEdgeAlpha(NOW_POLY_OPA_DISP++, 144); + gDPSetTexEdgeAlpha(NOW_SHADOW_DISP++, 144); + gDPSetTexEdgeAlpha(NOW_POLY_XLU_DISP++, 144); + + CLOSE_DISP(g); +} + +static void Actor_draw(GAME_PLAY* play, ACTOR* actor) { + LightsN* lights = Global_light_read(&play->global_light, play->game.graph); + + /* Light actor */ + LightsN_list_check(lights, play->global_light.list, (actor->state_bitfield & ACTOR_STATE_LIGHTING) ? NULL : &actor->world.position); + LightsN_disp(lights, play->game.graph); + LightsN_disp_BG(lights, play->game.graph); + + /* Load actor position/scale matrix */ + Matrix_softcv3_load(&actor->shape_info.rotation, actor->world.position.x, actor->world.position.y + actor->shape_info.ofs_y * actor->scale.y, actor->world.position.z); + Matrix_scale(actor->scale.x, actor->scale.y, actor->scale.z, 1); + + /* Draw actor */ + Actor_draw_ta_set(actor, play); + (*actor->dw_proc)(actor, &play->game); + Actor_draw_ta_clr(actor, play); + + /* Draw shadow */ + if (actor->shape_info.shadow_proc != NULL) { + (*actor->shape_info.shadow_proc)(actor, lights, play); + } +} + +extern int Actor_draw_actor_no_culling_check(ACTOR* actor) { + return Actor_draw_actor_no_culling_check2(actor, &actor->camera_position, actor->camera_w); +} + +extern int Actor_draw_actor_no_culling_check2(ACTOR* actor, xyz_t* camera_pos, f32 camera_w) { + int res = FALSE; + + if (-actor->cull_radius < camera_pos->z && camera_pos->z < actor->cull_distance + actor->cull_radius) { + f32 m = camera_w < 1.0f ? 1.0f : 1.0f / camera_w; + + if ((m * (fabsf(camera_pos->x) - actor->cull_width)) < 1.0f && + (m * (camera_pos->y + actor->cull_height)) > -1.0f && + (m * (camera_pos->y - actor->cull_radius) < 1.0f) + ) { + res = TRUE; + } + } + + return res; +} + +static void Actor_cull_check(ACTOR* actor) { + if (Actor_draw_actor_no_culling_check(actor) == TRUE) { + actor->state_bitfield |= ACTOR_STATE_NO_CULL; + } + else { + actor->state_bitfield &= ~ACTOR_STATE_NO_CULL; + } +} + +static void Actor_delete_check(ACTOR* actor, GAME* game) { + GAME_PLAY* play = (GAME_PLAY*)game; + + if ((actor->state_bitfield & (ACTOR_STATE_NO_MOVE_WHILE_CULLED | ACTOR_STATE_NO_DRAW_WHILE_CULLED | ACTOR_STATE_NO_CULL)) == 0) { + if (actor->npc_id != EMPTY_NO) { + if (actor->block_x >= 0 && actor->block_z >= 0) { + if (actor->block_x != play->block_table.block_x || actor->block_z != play->block_table.block_z) { + Actor_delete(actor); + } + } + } + } +} + +extern void Actor_info_ct(GAME* game, Actor_info* actor_info, Actor_data* player_data) { + GAME_PLAY* play = (GAME_PLAY*)game; + ACTOR* player_actor; + ACTOR_DLFTBL* dlftbl; + int i; + + bzero(actor_info, sizeof(Actor_info)); + actor_dlftbls_init(); + + Matrix_copy_MtxF(&play->mtx_204C, &MtxF_clear); + Matrix_copy_MtxF(&play->projection_matrix, &MtxF_clear); + + /* Reset the actor dlf table info */ + dlftbl = actor_dlftbls; + for (i = 0; i < mAc_PROFILE_NUM; i++) { + dlftbl->alloc_buf = NULL; + dlftbl->num_actors = 0; + dlftbl++; + } + + if (mEv_CheckFirstJob() == TRUE) { + Common_Set(demo_profiles[0], mAc_PROFILE_INTRO_DEMO); // force intro demo to spawn + } + + /* Spawn any demo actors */ + for (i = 0; i < mDemo_CLIP_TYPE_NUM - 1; i++) { + s16 demo_profile = Common_Get(demo_profiles[i]); + + if (demo_profile != mAc_PROFILE_NUM) { + Actor_info_make_actor( + actor_info, + game, + demo_profile, + 0.0f, 0.0f, 0.0f, + 0, 0, 0, + -1, -1, + -1, + EMPTY_NO, + -1, + -1, + -1 + ); + } + + Common_Set(demo_profiles[i], mAc_PROFILE_NUM); + } + + /* Try spawning the player actor */ + player_actor = Actor_info_make_actor( + actor_info, + game, + player_data->profile, + player_data->position.x, player_data->position.y, player_data->position.z, + player_data->rotation.x, player_data->rotation.y, player_data->rotation.z, + -1, -1, + -1, + EMPTY_NO, + player_data->arg, + -1, + -1 + ); + + if (player_actor != NULL) { + player_actor->world.position.y = mCoBG_GetBgY_OnlyCenter_FromWpos2(player_actor->world.position, 0.0f); + mFI_SetBearActor(play, player_actor->world.position, FALSE); + } + + /* Spawn the current bg item type actor */ + if (Common_Get(bg_item_profile) != 0) { + Actor_info_make_actor( + actor_info, + game, + Common_Get(bg_item_profile), + 0.0f, 0.0f, 0.0f, + 0, 0, 0, + -1, -1, + -1, + EMPTY_NO, + -1, + -1, + -1 + ); + } + + /* Spawn all pending control actors */ + if (play->ctrl_actor_data_num != 0) { + s16* ctrl_actor_data = play->ctrl_actor_data; + for (i = 0; i < play->ctrl_actor_data_num; i++) { + Actor_info_make_actor( + &play->actor_info, + game, + *ctrl_actor_data, + 0.0f, 0.0f, 0.0f, + 0, 0, 0, + -1, -1, + -1, + EMPTY_NO, + -1, + -1, + -1 + ); + + ctrl_actor_data++; + } + + play->ctrl_actor_data_num = 0; + } + + mSc_regist_initial_exchange_bank(play); + + /* Spawn all pending actors */ + if (play->actor_data_num != 0) { + Actor_data* actor_data = play->actor_data; + for (i = 0; i < play->actor_data_num; i++) { + + Actor_info_make_actor( + &play->actor_info, + (GAME*)play, + actor_data->profile, + actor_data->position.x, actor_data->position.y, actor_data->position.z, + actor_data->rotation.x, actor_data->rotation.y, actor_data->rotation.z, + -1, -1, + -1, + EMPTY_NO, + actor_data->arg, + -1, + -1 + ); + + actor_data++; + } + + play->actor_data_num = 0; + } +} + +extern void Actor_info_dt(Actor_info* actor_info, GAME_PLAY* play) { + int i; + + for (i = 0; i < ACTOR_PART_NUM; i++) { + ACTOR* actor; + + while (actor = actor_info->list[i].actor, actor != NULL) { + Actor_info_delete(actor_info, actor, (GAME*)play); + } + } + + actor_dlftbls_cleanup(); +} + +extern void Actor_info_call_actor(GAME_PLAY* play, Actor_info* actor_info) { + //GAME* game = (GAME*)play; + PLAYER_ACTOR* player_actor = get_player_actor_withoutCheck(play); + ACTOR* actor; + int i; + + mFI_FieldMove(player_actor->actor_class.world.position); + mBI_move(play); + + for (i = 0; i < ACTOR_PART_NUM; i++) { + ACTOR* next; + actor = actor_info->list[i].actor; + + while (actor != NULL) { + play->game.doing_point = actor->id; + play->game.doing_point_specific = 151; + + if (actor->world.position.y < -25000.0f) { + actor->world.position.y = -25000.0f; + } + + if (actor->ct_proc != NULL) { + if (Actor_data_bank_dma_end_check(actor, play) == TRUE) { + play->game.doing_point_specific = 152; + (*actor->ct_proc)(actor, (GAME*)play); + play->game.doing_point_specific = 153; + actor->ct_proc = NULL; + } + + next = actor->next_actor; + } + else { + if (Actor_data_bank_dma_end_check(actor, play) == FALSE) { + play->game.doing_point_specific = 154; + Actor_delete(actor); + play->game.doing_point_specific = 155; + next = actor->next_actor; + } + else if (actor->mv_proc == NULL) { + if (actor->drawn == FALSE) { + play->game.doing_point_specific = 156; + next = Actor_info_delete(&play->actor_info, actor, (GAME*)play); + play->game.doing_point_specific = 157; + } + else { + play->game.doing_point_specific = 158; + Actor_dt(actor, (GAME*)play); + play->game.doing_point_specific = 159; + next = actor->next_actor; + } + } + else { + play->game.doing_point_specific = 160; + xyz_t_move(&actor->last_world_position, &actor->world.position); + actor->player_distance_xz = search_position_distanceXZ(&actor->world.position, &player_actor->actor_class.world.position); + actor->player_distance_y = player_actor->actor_class.world.position.y - actor->world.position.y; + actor->player_distance = actor->player_distance_xz * actor->player_distance_xz + actor->player_distance_y * actor->player_distance_y; + actor->player_angle_y = search_position_angleY(&actor->world.position, &player_actor->actor_class.world.position); + actor->state_bitfield &= ~ACTOR_STATE_24; + + if ((actor->state_bitfield & (ACTOR_STATE_NO_MOVE_WHILE_CULLED | ACTOR_STATE_NO_CULL)) || actor->part == ACTOR_PART_NPC) { + play->game.doing_point_specific = 161; + (*actor->mv_proc)(actor, (GAME*)play); + play->game.doing_point_specific = 162; + } + + CollisionCheck_Status_Clear(&actor->status_data); + next = actor->next_actor; + } + } + + actor = next; + } + } + + play->game.doing_point_specific = 163; +} + +extern void Actor_info_draw_actor(GAME_PLAY* play, Actor_info* actor_info) { + Actor_list* list; + ACTOR* actor; + int i; + DRAW_CHK_PROC draw_chk_proc = play->draw_chk_proc; + + list = actor_info->list; + for (i = 0; i < ACTOR_PART_NUM; i++) { + int do_not_draw; + + for (actor = list->actor; actor != NULL; actor = actor->next_actor) { + /* Apply projection matrix to actor position */ + Skin_Matrix_PrjMulVector(&play->projection_matrix, &actor->world.position, &actor->camera_position, &actor->camera_w); + + Actor_cull_check(actor); + do_not_draw = (*draw_chk_proc)(actor, play); + actor->drawn = FALSE; + + if (do_not_draw == FALSE && actor->ct_proc == NULL && actor->dw_proc != NULL) { + if ((actor->state_bitfield & (ACTOR_STATE_NO_DRAW_WHILE_CULLED | ACTOR_STATE_NO_CULL))) { + if ((actor->state_bitfield & ACTOR_STATE_INVISIBLE) == 0 && actor->cull_while_talking == FALSE && actor->skip_drawing == FALSE) { + Actor_draw(play, actor); + actor->drawn = TRUE; + } + } + else { + Actor_delete_check(actor, (GAME*)play); + } + } + } + + list++; + } + + Light_list_point_draw(play); +} + +static void Actor_info_part_new(Actor_info* actor_info, ACTOR* actor, u8 part) { + ACTOR* next; + + actor->part = part; + actor_info->total_num++; + actor_info->list[part].num_actors++; + + next = actor_info->list[part].actor; + if (next != NULL) { + next->prev_actor = actor; + } + + actor_info->list[part].actor = actor; + actor->next_actor = next; +} + +static ACTOR* Actor_info_part_delete(Actor_info* actor_info, ACTOR* actor) { + ACTOR* next; + + actor_info->total_num--; + actor_info->list[actor->part].num_actors--; + + if (actor->prev_actor != NULL) { + actor->prev_actor->next_actor = actor->next_actor; + } + else { + actor_info->list[actor->part].actor = actor->next_actor; + } + + next = actor->next_actor; + if (next != NULL) { + next->prev_actor = actor->prev_actor; + } + + actor->prev_actor = NULL; + actor->next_actor = NULL; + + return next; +} + +extern void Actor_free_overlay_area(ACTOR_DLFTBL* dlftbl) { + if ((dlftbl->flags & 2) == 0) { + if ((dlftbl->flags & 1)) { + dlftbl->alloc_buf = NULL; + } + else { + zelda_free(dlftbl->alloc_buf); + dlftbl->alloc_buf = NULL; + } + } +} + +static void actor_free_check(ACTOR_DLFTBL* dlftbl, mActor_name_t id) { + if (dlftbl->num_actors == 0 && dlftbl->alloc_buf != NULL) { + switch (ITEM_NAME_GET_TYPE(id)) { + case NAME_TYPE_SPNPC: + case NAME_TYPE_NPC: + (*Common_Get(clip).npc_clip->free_overlay_area_proc)(dlftbl); + break; + + case NAME_TYPE_STRUCT: + (*Common_Get(clip).structure_clip->free_overlay_area_proc)(dlftbl); + break; + + default: + Actor_free_overlay_area(dlftbl); + break; + } + } +} + +extern void Actor_get_overlay_area(ACTOR_DLFTBL* dlftbl, int unused, size_t alloc_size) { + if ((dlftbl->flags & 2)) { + dlftbl->alloc_buf = (u8*)zelda_malloc_r(alloc_size); + } + else { + dlftbl->alloc_buf = (u8*)zelda_malloc(alloc_size); + } +} + +static int Actor_data_bank_regist_check_npc(int* bank_id, ACTOR_PROFILE* profile, ACTOR_DLFTBL* dlftbl, GAME* game, mActor_name_t name_id) { + return TRUE; +} + +static int Actor_data_bank_regist_check(int* bank_id, ACTOR_PROFILE* profile, ACTOR_DLFTBL* dlftbl, GAME* game, mActor_name_t name_id) { + int res = TRUE; + + if (*bank_id == -1) { + if (profile->part == ACTOR_PART_NPC) { + res = Actor_data_bank_regist_check_npc(bank_id, profile, dlftbl, game, name_id); + } + else { + // in DnM, this was another func call + res = TRUE; + } + } + + return res; +} + +static int Actor_malloc_actor_class(ACTOR** actor_pp, ACTOR_PROFILE* profile, ACTOR_DLFTBL* dlftbl, const char* unk, mActor_name_t id) { + aNPC_draw_data_c draw_data; + + switch (ITEM_NAME_GET_TYPE(id)) { + case NAME_TYPE_SPNPC: + case NAME_TYPE_NPC: + { + *actor_pp = (*Common_Get(clip).npc_clip->get_actor_area_proc)(profile->class_size, unk, 1); + (*Common_Get(clip).npc_clip->dma_draw_data_proc)(&draw_data, id); // leftover? + break; + } + + case NAME_TYPE_STRUCT: + { + *actor_pp = (ACTOR*)((*Common_Get(clip).structure_clip->get_actor_area_proc)()); + break; + } + + default: + { + *actor_pp = (ACTOR*)zelda_malloc(profile->class_size); + break; + } + } + + if (*actor_pp == NULL) { + actor_free_check(dlftbl, id); + return FALSE; + } + + return TRUE; +} + +extern void Actor_init_actor_class(ACTOR* actor, ACTOR_PROFILE* profile, ACTOR_DLFTBL* dlftbl, GAME_PLAY* play, int bank_idx, f32 x, f32 y, f32 z, s16 rot_x, s16 rot_y, s16 rot_z, s8 block_x, s8 block_z, s16 move_actor_list_idx, mActor_name_t name_id, s16 arg) { + mem_clear((u8*)actor, profile->class_size, 0); + actor->dlftbl = dlftbl; + actor->id = profile->id; + actor->state_bitfield = profile->initial_flags_state; + actor->data_bank_id = bank_idx; + actor->ct_proc = profile->ct_proc; + actor->dt_proc = profile->dt_proc; + actor->mv_proc = profile->mv_proc; + actor->dw_proc = profile->dw_proc; + actor->sv_proc = profile->sv_proc; + actor->actor_specific = arg; + actor->scene_id = play->scene_id; + actor->home.position.x = x; + actor->home.position.y = y; + actor->home.position.z = z; + actor->home.angle.x = rot_x; + actor->home.angle.y = rot_y; + actor->home.angle.z = rot_z; + actor->block_x = block_x; + actor->block_z = block_z; + actor->move_actor_list_idx = move_actor_list_idx; + actor->npc_id = name_id; +} + +#ifndef MUST_MATCH +/* @nonmatching */ +extern ACTOR* Actor_info_make_actor(Actor_info* actor_info, GAME* game, s16 profile_no, f32 x, f32 y, f32 z, s16 rot_x, s16 rot_y, s16 rot_z, s8 block_x, s8 block_z, s16 move_actor_list_idx, mActor_name_t name_id, s16 arg, s8 npc_info_idx, int data_bank_idx) { + const char* test = ""; + GAME_PLAY* play = (GAME_PLAY*)game; + ACTOR* actor; + ACTOR_PROFILE* profile; + ACTOR_DLFTBL* dlftbl; + + test = ""; // removing this line helps a bit... + + dlftbl = &actor_dlftbls[profile_no]; + + if (actor_info->total_num > mAc_MAX_ACTORS) { + return NULL; + } + + profile = dlftbl->profile; + if (Actor_data_bank_regist_check(&data_bank_idx, profile, dlftbl, game, name_id) == FALSE) { + return NULL; + } + + if (Actor_malloc_actor_class(&actor, profile, dlftbl, test, name_id) == FALSE) { + return NULL; + } + + dlftbl->num_actors++; + Actor_init_actor_class(actor, profile, dlftbl, play, data_bank_idx, x, y, z, rot_x, rot_y, rot_z, block_x, block_z, move_actor_list_idx, name_id, arg); + Actor_info_part_new(actor_info, actor, profile->part); + mNpc_SetNpcinfo(actor, npc_info_idx); + Actor_ct(actor, (GAME*)play); + + return actor; +} +#else +extern asm ACTOR* Actor_info_make_actor(Actor_info* actor_info, GAME* game, s16 profile_no, f32 x, f32 y, f32 z, s16 rot_x, s16 rot_y, s16 rot_z, s8 block_x, s8 block_z, s16 move_actor_list_idx, mActor_name_t name_id, s16 arg, s8 npc_info_idx, int data_bank_idx) { + #include "asm/80375830.s" +} +#endif + +extern ACTOR* Actor_info_make_child_actor(Actor_info* actor_info, ACTOR* parent_actor, GAME* game, s16 profile, f32 x, f32 y, f32 z, s16 rot_x, s16 rot_y, s16 rot_z, s16 move_actor_list_idx, mActor_name_t name_id, s16 arg, int data_bank_idx) { + ACTOR* actor = Actor_info_make_actor(actor_info, game, profile, x, y, z, rot_x, rot_y, rot_z, -1, -1, move_actor_list_idx, name_id, arg, -1, data_bank_idx); + + if (actor != NULL) { + parent_actor->child_actor = actor; + actor->parent_actor = parent_actor; + } + + return actor; +} + +static void restore_fgdata(ACTOR* actor, GAME_PLAY* play) { + mActor_name_t name = actor->npc_id; + + if (name != EMPTY_NO && actor->move_actor_list_idx == -1 && actor->block_x >= 0 && actor->block_z >= 0) { + if (ITEM_NAME_GET_TYPE(name) == NAME_TYPE_ITEM2) { + xyz_t pos; + + xyz_t_move(&pos, &actor->home.position); + if (mFI_search_unit_around(&pos, EMPTY_NO) == TRUE) { + /* pos now holds the position of the empty unit */ + mFI_SetFG_common(actor->npc_id, pos, FALSE); /* This causes the airplane duplication "bug" */ + } + } + else { + mFI_SetFG_common(name, actor->home.position, FALSE); + } + } +} + +static int restore_flag[ACTOR_PART_NUM] = { + TRUE, /* FG */ + TRUE, /* ITEM */ + FALSE, /* PLAYER */ + FALSE, /* 3 */ + FALSE, /* NPC */ + FALSE, /* BG */ + FALSE, /* EFFECT */ + FALSE /* CONTROL */ +}; + +static void restore_fgdata_one(ACTOR* actor, GAME_PLAY* play) { + if (restore_flag[actor->part] == TRUE) { + restore_fgdata(actor, play); + } + else if (actor->restore_fg == TRUE) { + restore_fgdata(actor, play); + } +} + +extern void restore_fgdata_all(GAME_PLAY* play) { + Actor_info* info; + ACTOR* actor; + int i; + + info = &play->actor_info; + for (i = 0; i < ACTOR_PART_NUM; i++) { + if (restore_flag[i] == TRUE) { + for (actor = info->list[i].actor; actor != NULL; actor = actor->next_actor) { + restore_fgdata(actor, play); + } + } + else { + for (actor = info->list[i].actor; actor != NULL; actor = actor->next_actor) { + if (actor->restore_fg == TRUE) { + restore_fgdata(actor, play); + } + } + } + } +} + +extern void Actor_info_save_actor(GAME_PLAY* play) { + Actor_info* info; + ACTOR* actor; + int i; + + info = &play->actor_info; + for (i = 0; i < ACTOR_PART_NUM; i++) { + for (actor = info->list[i].actor; actor != NULL; actor = actor->next_actor) { + if (actor->sv_proc != NULL) { + (*actor->sv_proc)(actor, (GAME*)play); + actor->sv_proc = NULL; + } + } + } + + restore_fgdata_all(play); +} + +extern ACTOR* Actor_info_delete(Actor_info* actor_info, ACTOR* actor, GAME* game) { + mActor_name_t name_id = actor->npc_id; + ACTOR_DLFTBL* dlftbl = actor->dlftbl; + ACTOR* next_actor; + + restore_fgdata_one(actor, (GAME_PLAY*)game); + Actor_dt(actor, game); + next_actor = Actor_info_part_delete(actor_info, actor); + + switch (ITEM_NAME_GET_TYPE(name_id)) { + case NAME_TYPE_SPNPC: + case NAME_TYPE_NPC: + { + (*Common_Get(clip).npc_clip->free_actor_area_proc)(actor); + break; + } + + case NAME_TYPE_STRUCT: + { + (*Common_Get(clip).structure_clip->free_actor_area_proc)((STRUCTURE_ACTOR*)actor); + break; + } + + default: + { + zelda_free(actor); + break; + } + } + + if (dlftbl->ram_start == NULL) { + dlftbl->num_actors--; + } + else { + dlftbl->num_actors--; + actor_free_check(dlftbl, actor->npc_id); + } + + return next_actor; +} + +extern ACTOR* Actor_info_name_search_sub(ACTOR* actor, s16 name) { + while (actor != NULL) { + if (actor->id == name) { + return actor; + } + + actor = actor->next_actor; + } + + return actor; +} + +extern ACTOR* Actor_info_name_search(Actor_info* actor_info, s16 name, int part) { + ACTOR* actor = actor_info->list[part].actor; + + if (actor != NULL) { + return Actor_info_name_search_sub(actor, name); + } + + return NULL; +} + +extern ACTOR* Actor_info_fgName_search_sub(ACTOR* actor, mActor_name_t fgName) { + while (actor != NULL) { + if (actor->npc_id == fgName) { + return actor; + } + + actor = actor->next_actor; + } + + return actor; +} + +extern ACTOR* Actor_info_fgName_search(Actor_info* actor_info, mActor_name_t fgName, int part) { + ACTOR* actor = actor_info->list[part].actor; + + if (actor != NULL) { + return Actor_info_fgName_search_sub(actor, fgName); + } + + return NULL; +} + +extern Gfx* HiliteReflect_new(xyz_t* pos, xyz_t* eye, xyz_t* light_direction, GRAPH* graph, Gfx* gfx, Hilite** hilite) { + static Mtx work_view_matrix; + + LookAt* lookat = GRAPH_ALLOC_TYPE(graph, LookAt, 1); + int pos_eye_equal = FALSE; + f32 eye_x = eye->x; + + if (eye_x == pos->x && eye->z == pos->z) { + pos_eye_equal = TRUE; + } + + if (pos_eye_equal) { + eye_x = 0.001f + eye_x; + } + + *hilite = GRAPH_ALLOC_TYPE(graph, Hilite, 1); + guLookAtHilite( + &work_view_matrix, + lookat, + *hilite, + eye_x, eye->y, eye->z, + pos->x, pos->y, pos->z, + 0.0f, 1.0f, 0.0f, + light_direction->x, light_direction->y, light_direction->z, + light_direction->x, light_direction->y, light_direction->z, + 16, 16 + ); + + gSPLookAt(gfx++, lookat); + gDPPipeSync(gfx++); + gDPSetTileSize(gfx++, 1, (*hilite)->h.x1, (*hilite)->h.y1, (*hilite)->h.x1 + 60, (*hilite)->h.y1 + 60); + + return gfx; +} + +extern Hilite* HiliteReflect_init(xyz_t* pos, xyz_t* eye, xyz_t* light_direction, GRAPH* graph) { + Hilite* hilite; + + OPEN_DISP(graph); + + SET_POLY_OPA_DISP(HiliteReflect_new(pos, eye, light_direction, graph, NOW_POLY_OPA_DISP, &hilite)); + + CLOSE_DISP(graph); + + return hilite; +} + +extern Hilite* HiliteReflect_xlu_init(xyz_t* pos, xyz_t* eye, xyz_t* light_direction, GRAPH* graph) { + Hilite* hilite; + + OPEN_DISP(graph); + + SET_POLY_XLU_DISP(HiliteReflect_new(pos, eye, light_direction, graph, NOW_POLY_XLU_DISP, &hilite)); + + CLOSE_DISP(graph); + + return hilite; +} + +extern void Setpos_HiliteReflect_init(xyz_t* pos, GAME_PLAY* play) { + Kankyo* kankyo = &play->kankyo; + xyz_t sun_pos; + + sun_pos.x = (int)kankyo->sun_light.lights.diffuse.x; + sun_pos.y = (int)kankyo->sun_light.lights.diffuse.y; + sun_pos.z = (int)kankyo->sun_light.lights.diffuse.z; + + HiliteReflect_init(pos, &play->view.eye, &sun_pos, play->game.graph); +} + +extern void Setpos_HiliteReflect_xlu_init(xyz_t* pos, GAME_PLAY* play) { + Kankyo* kankyo = &play->kankyo; + xyz_t sun_pos; + + sun_pos.x = (int)kankyo->sun_light.lights.diffuse.x; + sun_pos.y = (int)kankyo->sun_light.lights.diffuse.y; + sun_pos.z = (int)kankyo->sun_light.lights.diffuse.z; + + HiliteReflect_xlu_init(pos, &play->view.eye, &sun_pos, play->game.graph); +} diff --git a/rel/m_lib.c b/rel/m_lib.c index 985501a4..13b9cf95 100644 --- a/rel/m_lib.c +++ b/rel/m_lib.c @@ -786,12 +786,12 @@ extern void Game_play_Projection_Trans(GAME_PLAY* const play, xyz_t* world_pos, xyz_t* screen_pos) { f32 w; - Matrix_mult(&play->matrix, 0); + Matrix_mult(&play->projection_matrix, 0); Matrix_Position(world_pos, screen_pos); - w = play->matrix.ww + - ((play->matrix.wx * world_pos->x) + - (play->matrix.wy * world_pos->y) + - (play->matrix.wz * world_pos->z)); + w = play->projection_matrix.ww + + ((play->projection_matrix.wx * world_pos->x) + + (play->projection_matrix.wy * world_pos->y) + + (play->projection_matrix.wz * world_pos->z)); screen_pos->x = (SCREEN_WIDTH_F / 2.0f) + ((screen_pos->x / w) * (SCREEN_WIDTH_F / 2.0f)); screen_pos->y = (SCREEN_HEIGHT_F / 2.0f) - ((screen_pos->y / w) * (SCREEN_HEIGHT_F / 2.0f)); } diff --git a/rel/m_lights.c b/rel/m_lights.c index 7bb98515..63118d0b 100644 --- a/rel/m_lights.c +++ b/rel/m_lights.c @@ -157,7 +157,7 @@ static void LightsN__point_proc(LightsN* lights, LightParams* lightInfo, xyz_t* } } -static void LightsN__P_point_proc(LightsN* lights, LightParams* lightInfo, xyz_t*){ +static void LightsN__P_point_proc(LightsN* lights, LightParams* lightInfo, xyz_t* pos){ f32 rad; xyz_t point; @@ -303,9 +303,8 @@ static void Global_light_fog_set(Global_light* glight, u8 r, u8 g, u8 b, s16 nea } -extern void Global_light_read(Global_light* glight, GRAPH* graph){ - - new_LightsN(graph, glight->ambientColor[0], glight->ambientColor[1], glight->ambientColor[2]); +extern LightsN* Global_light_read(Global_light* glight, GRAPH* graph){ + return new_LightsN(graph, glight->ambientColor[0], glight->ambientColor[1], glight->ambientColor[2]); } static void Global_light_list_ct(Global_light* glight){ @@ -313,7 +312,7 @@ static void Global_light_list_ct(Global_light* glight){ glight->list = NULL; } -extern void Global_light_list_new(GAME_PLAY*, Global_light* glight, Lights* light){ +extern void Global_light_list_new(GAME_PLAY* play, Global_light* glight, Lights* light){ LightNode* clight; diff --git a/rel/m_map_ovl.c b/rel/m_map_ovl.c index 9eb2d0f1..3e9e6414 100644 --- a/rel/m_map_ovl.c +++ b/rel/m_map_ovl.c @@ -591,7 +591,7 @@ static void mMP_set_init_data(mMP_Overlay_c* map_ovl, mSM_MenuInfo_c* menu_info) mFI_Wpos2BlockNum(&block_x, &block_z, pos); } else { - mFI_Wpos2BlockNum(&block_x, &block_z, player->actor_class.world_position); + mFI_Wpos2BlockNum(&block_x, &block_z, player->actor_class.world.position); } map_ovl->player_bx = block_x - 1; diff --git a/rel/m_post_office.c b/rel/m_post_office.c index 87ea8da7..dac9dbcd 100644 --- a/rel/m_post_office.c +++ b/rel/m_post_office.c @@ -415,7 +415,7 @@ static int mPO_make_post_man(GAME_PLAY* play) { ACTOR* post_office_structure = Actor_info_fgName_search(&play->actor_info, POST_OFFICE, ACTOR_PART_ITEM); if (post_office_structure != NULL) { - mFI_Wpos2UtNum_inBlock(&post_utx, &post_utz, post_office_structure->world_position); + mFI_Wpos2UtNum_inBlock(&post_utx, &post_utz, post_office_structure->world.position); spawned_postman = (*Common_Get(clip).npc_clip->setupActor_proc)(play, SP_NPC_POST_MAN, -1, -1, 1, play->block_table.block_x, play->block_table.block_z, post_utx - 3, post_utz); if (spawned_postman == TRUE) { diff --git a/rel/m_titledemo.c b/rel/m_titledemo.c index 51abd5de..9ea77864 100644 --- a/rel/m_titledemo.c +++ b/rel/m_titledemo.c @@ -61,7 +61,7 @@ static void mTD_player_keydata_init(GAME_PLAY* play) { angle = get_demo_header(mEv_CheckTitleDemo() - 1, mTD_HEADER_ROTATION); player->actor_class.shape_info.rotation.y = angle; - player->actor_class.world_rotation.y = angle; + player->actor_class.world.angle.y = angle; } S_tdemo_frame = 0; diff --git a/rel/m_train_control.c b/rel/m_train_control.c index 89d695d6..9f311dd5 100644 --- a/rel/m_train_control.c +++ b/rel/m_train_control.c @@ -27,7 +27,7 @@ static void mTRC_SetMicPos(GAME_PLAY* play, xyz_t* mic_pos) { } else { if (player != NULL) { - xyz_t_move(&pos, &player->actor_class.world_position); + xyz_t_move(&pos, &player->actor_class.world.position); } else { xyz_t_move(&pos, &ZeroVec); @@ -467,7 +467,7 @@ static void mTRC_trainSet(GAME_PLAY* play) { xyz_pos.z = xz_pos.z; xyz_pos.y = mCoBG_GetBgY_OnlyCenter_FromWpos2(xyz_pos, 0.0f); - xyz_t_move(&train_actor->world_position, &xyz_pos); + xyz_t_move(&train_actor->world.position, &xyz_pos); } x -= 250.0f; @@ -484,7 +484,7 @@ static void mTRC_trainSet(GAME_PLAY* play) { xyz_pos.z = 740.0f; xyz_pos.y = mCoBG_GetBgY_OnlyCenter_FromWpos2(xyz_pos, 0.0f); - xyz_t_move(&caboose_actor->world_position, &xyz_pos); + xyz_t_move(&caboose_actor->world.position, &xyz_pos); } Common_Set(train_flag, FALSE); diff --git a/rel/m_watch_my_step.c b/rel/m_watch_my_step.c index 76835f25..adc0e001 100644 --- a/rel/m_watch_my_step.c +++ b/rel/m_watch_my_step.c @@ -131,7 +131,7 @@ extern void watch_my_step_move(GAME_PLAY* play) { } if (S_watch_my_step.mode != 0) { - xyz_t position = player_actor->actor_class.world_position; + xyz_t position = player_actor->actor_class.world.position; xyz_t screen_pos; position.y += 30.0f;