mirror of
https://github.com/ACreTeam/ac-decomp
synced 2026-05-23 06:34:18 -04:00
263 lines
8.3 KiB
C
263 lines
8.3 KiB
C
#ifndef AC_FURNITURE_H
|
|
#define AC_FURNITURE_H
|
|
|
|
#include "types.h"
|
|
#include "m_collision_bg.h"
|
|
#include "c_keyframe.h"
|
|
#include "m_actor.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
typedef struct furniture_actor_s FTR_ACTOR;
|
|
|
|
#define aFTR_KEEP_ITEM_COUNT (mCoBG_LAYER_NUM - 1)
|
|
#define aFTR_CHECK_INTERACTION(inter, type) (((inter) >> (type)) & 1)
|
|
|
|
#define aFTR_EDGE_COL_NUM 4
|
|
|
|
enum {
|
|
aFTR_STATE_STOP,
|
|
aFTR_STATE_WAIT_PUSH,
|
|
aFTR_STATE_WAIT_PUSH2,
|
|
aFTR_STATE_WAIT_PUSH3,
|
|
aFTR_STATE_PUSH,
|
|
aFTR_STATE_WAIT_PULL,
|
|
aFTR_STATE_WAIT_PULL2,
|
|
aFTR_STATE_PULL,
|
|
aFTR_STATE_WAIT_LROTATE,
|
|
aFTR_STATE_LROTATE,
|
|
aFTR_STATE_WAIT_RROTATE,
|
|
aFTR_STATE_RROTATE,
|
|
aFTR_STATE_BIRTH_WAIT,
|
|
aFTR_STATE_BIRTH,
|
|
aFTR_STATE_BYE,
|
|
aFTR_STATE_DEATH,
|
|
|
|
aFTR_STATE_NUM
|
|
};
|
|
|
|
enum {
|
|
aFTR_CTR_TYPE_GAME,
|
|
aFTR_CTR_TYPE_GAME_PLAY,
|
|
|
|
aFTR_CTR_TYPE_NUM
|
|
};
|
|
|
|
enum {
|
|
aFTR_HNW_STATE_WAIT_TURN_ON,
|
|
aFTR_HNW_STATE_TURN_ON,
|
|
aFTR_HNW_STATE_ON,
|
|
aFTR_HNW_STATE_OFF,
|
|
|
|
aFTR_HNW_STATE_NUM
|
|
};
|
|
|
|
enum {
|
|
aFTR_SHAPE_TYPEB_90, /* 2x1 (facing up)*/
|
|
aFTR_SHAPE_TYPEB_180, /* 2x1 [- *] */
|
|
aFTR_SHAPE_TYPEB_270, /* 2x1 (facing down) */
|
|
aFTR_SHAPE_TYPEB_0, /* 2x1 [* -] */
|
|
aFTR_SHAPE_TYPEA, /* 1x1 */
|
|
aFTR_SHAPE_TYPEC, /* 2x2 */
|
|
|
|
aFTR_SHAPE_TYPE_NUM
|
|
};
|
|
|
|
enum {
|
|
aFTR_INTERACTION_NONE = 0,
|
|
aFTR_INTERACTION_STORAGE_DRAWERS = 1, // dressers
|
|
aFTR_INTERACTION_STORAGE_WARDROBE = 2, // double doors
|
|
aFTR_INTERACTION_STORAGE_CLOSET = 4, // single door
|
|
aFTR_INTERACTION_MUSIC_DISK = 8,
|
|
aFTR_INTERACTION_NO_COLLISION = 0x10,
|
|
aFTR_INTERACTION_HANIWA = 0x20,
|
|
aFTR_INTERACTION_FISH = 0x40,
|
|
aFTR_INTERACTION_INSECT = 0x80,
|
|
aFTR_INTERACTION_MANNEKIN = 0x100,
|
|
aFTR_INTERACTION_UMBRELLA = 0x200,
|
|
aFTR_INTERACTION_FOSSIL = 0x400,
|
|
aFTR_INTERACTION_FAMICOM = 0x800,
|
|
aFTR_INTERACTION_START_DISABLED = 0x1000, // mainly used for TVs to be off when placed
|
|
// there may be more types, but I didn't see any
|
|
aFTR_INTERACTION_FAMICOM_ITEM = 0x2000,
|
|
aFTR_INTERACTION_RADIO_AEROBICS = 0x4000,
|
|
aFTR_INTERACTION_TOGGLE = 0x8000,
|
|
};
|
|
|
|
enum {
|
|
aFTR_INTERACTION_TYPE_DRAWERS,
|
|
aFTR_INTERACTION_TYPE_WARDROBE,
|
|
aFTR_INTERACTION_TYPE_CLOSET,
|
|
aFTR_INTERACTION_TYPE_MUSIC_DISK,
|
|
aFTR_INTERACTION_TYPE_NO_COLLISION,
|
|
aFTR_INTERACTION_TYPE_HANIWA,
|
|
aFTR_INTERACTION_TYPE_FISH,
|
|
aFTR_INTERACTION_TYPE_INSECT,
|
|
aFTR_INTERACTION_TYPE_MANNEKIN,
|
|
aFTR_INTERACTION_TYPE_UMBRELLA,
|
|
aFTR_INTERACTION_TYPE_FOSSIL,
|
|
aFTR_INTERACTION_TYPE_FAMICOM,
|
|
aFTR_INTERACTION_TYPE_START_DISABLED,
|
|
aFTR_INTERACTION_TYPE_FAMICOM_ITEM,
|
|
aFTR_INTERACTION_TYPE_RADIO_AEROBICS,
|
|
aFTR_INTERACTION_TYPE_TOGGLE,
|
|
|
|
aFTR_INTERACTION_NUM,
|
|
};
|
|
|
|
#define aFTR_IS_STORAGE(profile) \
|
|
(aFTR_CHECK_INTERACTION((profile)->interaction_type, aFTR_INTERACTION_TYPE_DRAWERS) || \
|
|
aFTR_CHECK_INTERACTION((profile)->interaction_type, aFTR_INTERACTION_TYPE_WARDROBE) || \
|
|
aFTR_CHECK_INTERACTION((profile)->interaction_type, aFTR_INTERACTION_TYPE_CLOSET) || \
|
|
aFTR_CHECK_INTERACTION((profile)->interaction_type, aFTR_INTERACTION_TYPE_MUSIC_DISK))
|
|
enum {
|
|
aFTR_CONTACT_ACTION_NONE = 0,
|
|
aFTR_CONTACT_ACTION_CHAIR_UNIDIRECTIONAL = 1, // only can sit from the front
|
|
aFTR_CONTACT_ACTION_CHAIR_MULTIDIRECTIONAL = 2, // can sit from any direction
|
|
aFTR_CONTACT_ACTION_CHAIR_SOFA = 4, // cam sit anywhere from the front
|
|
aFTR_CONTACT_ACTION_BED_SINGLE = 8, // single bed (can't roll)
|
|
aFTR_CONTACT_ACTION_BED_DOUBLE = 0x10, // double bed (can roll)
|
|
|
|
aFTR_CONTACT_ACTION_NUM
|
|
};
|
|
|
|
enum {
|
|
aFTR_CONTACT_ACTION_TYPE_CHAIR1,
|
|
aFTR_CONTACT_ACTION_TYPE_CHAIR4,
|
|
aFTR_CONTACT_ACTION_TYPE_SOFA,
|
|
aFTR_CONTACT_ACTION_TYPE_BED_SINGLE,
|
|
aFTR_CONTACT_ACTION_TYPE_BED_DOUBLE,
|
|
|
|
aFTR_CONTACT_ACTION_TYPE_NUM
|
|
};
|
|
|
|
#define aFTR_CHK_CONTACT_ACTION(cnt, action) (((cnt) >> (aFTR_CONTACT_ACTION_TYPE_##action)) & 1)
|
|
#define aFTR_CHK_CHAIR(cnt) \
|
|
(aFTR_CHK_CONTACT_ACTION(cnt, CHAIR1) || aFTR_CHK_CONTACT_ACTION(cnt, CHAIR4) || aFTR_CHK_CONTACT_ACTION(cnt, SOFA))
|
|
#define aFTR_CHK_BED(cnt) (aFTR_CHK_CONTACT_ACTION(cnt, BED_SINGLE) || aFTR_CHK_CONTACT_ACTION(cnt, BED_DOUBLE))
|
|
|
|
enum {
|
|
aFTR_SET_TYPE_NORMAL, /* Can't be placed on top and is not a table (layer0) */
|
|
aFTR_SET_TYPE_SURFACE, /* Is a surface (layer0) */
|
|
aFTR_SET_TYPE_ON_SURFACE, /* Can be placed on a surface (layer0/layer1) */
|
|
|
|
aFTR_SET_TYPE_NUM
|
|
};
|
|
|
|
enum {
|
|
aFTR_KANKYO_MAP_NONE,
|
|
aFTR_KANKYO_MAP_OPA,
|
|
aFTR_KANKYO_MAP_XLU,
|
|
|
|
aFTR_KANKYO_MAP_NUM
|
|
};
|
|
|
|
typedef void (*aFTR_FTR_CT_PROC)(FTR_ACTOR*, u8*);
|
|
typedef void (*aFTR_FTR_MOVE_PROC)(FTR_ACTOR*, ACTOR*, GAME*, u8*);
|
|
typedef void (*aFTR_FTR_DRAW_PROC)(FTR_ACTOR*, ACTOR*, GAME*, u8*);
|
|
typedef void (*aFTR_FTR_DT_PROC)(FTR_ACTOR*, u8*);
|
|
typedef void (*aFTR_FTR_DMA_PROC)(mActor_name_t, u8*);
|
|
|
|
typedef struct ftr_vtbl_s {
|
|
aFTR_FTR_CT_PROC ct_proc;
|
|
aFTR_FTR_MOVE_PROC move_proc;
|
|
aFTR_FTR_DRAW_PROC draw_proc;
|
|
aFTR_FTR_DT_PROC dt_proc;
|
|
aFTR_FTR_DMA_PROC dma_proc;
|
|
} aFTR_vtable_c;
|
|
|
|
typedef struct ftr_rig_s {
|
|
cKF_Skeleton_R_c* skeleton;
|
|
cKF_Animation_R_c* animation;
|
|
f32 speed;
|
|
} aFTR_rig_c;
|
|
|
|
typedef struct ftr_tex_animation_s {
|
|
u8** animation;
|
|
int animation_count;
|
|
} aFTR_tex_anim_c;
|
|
|
|
typedef struct ftr_profile_s {
|
|
Gfx* opaque0;
|
|
Gfx* opaque1;
|
|
Gfx* translucent0;
|
|
Gfx* translucent1;
|
|
u8* texture;
|
|
u16* palette;
|
|
aFTR_rig_c* rig;
|
|
aFTR_tex_anim_c* tex_anim;
|
|
f32 height;
|
|
f32 scale;
|
|
u8 shape; /* aFTR_SHAPE_TYPE* */
|
|
u8 move_bg_type; /* mCoBG_FTR_TYPE* */
|
|
u8 check_rotation; /* when non-zero extra checks are performed for items in the way during rotation? */
|
|
u8 kankyo_map; /* lighting map */
|
|
u8 contact_action; /* action on contact */
|
|
u16 interaction_type; /* action when interacting */
|
|
aFTR_vtable_c* vtable; /* unique furniture functions */
|
|
} aFTR_PROFILE;
|
|
|
|
typedef struct furniture_collision_s {
|
|
f32 start[2]; /* starting xz pos */
|
|
f32 end[2]; /* ending xz pos */
|
|
f32 normal[2]; /* xz normal */
|
|
f32 height; /* collision y */
|
|
f32 edge_contact_ratio; /* percentage of the xz collision in contact with edge to count as collision */
|
|
} aFTR_collision_c;
|
|
|
|
struct furniture_actor_s {
|
|
u16 name;
|
|
s16 ctr_type; // 0 = GAME's frame counter, 1 = GAME_PLAY's frame counter
|
|
int id;
|
|
xyz_t position;
|
|
xyz_t last_position;
|
|
xyz_t target_position;
|
|
int target_direction; /* direction to target position */
|
|
f32 player_distance; /* distance to the player */
|
|
f32 angle_y; /* current Y angle */
|
|
f32 angle_y_target; /* goal Y angle */
|
|
s16 state;
|
|
u8 shape_type; /* current size & shape (rotation) */
|
|
u8 original_shape_type; /* original size & shape (rotation) */
|
|
xyz_t base_position;
|
|
aFTR_collision_c edge_collision[aFTR_EDGE_COL_NUM]; /* collision for each edge */
|
|
s16 collision_direction;
|
|
int move_bg_idx;
|
|
mCoBG_bg_regist_c bg_register;
|
|
mCoBG_bg_contact_c bg_contact;
|
|
s16 s_angle_y; /* current Y angle but 'binangle' format */
|
|
f32 collision_scale;
|
|
u8 switch_bit; /* furniture on/off state */
|
|
u8 switch_changed_flag; /* signal that the on/off state is toggled */
|
|
s8 haniwa_step;
|
|
s16 haniwa_state;
|
|
cKF_SkeletonInfo_R_c keyframe; /* for actor animations */
|
|
s_xyz joint[9];
|
|
s_xyz morph[9];
|
|
Mtx skeleton_mtx[2][12];
|
|
cKF_TextureAnimation_c tex_animation; /* used for texture animations like TVs */
|
|
xyz_t scale;
|
|
f32 birth_scale_modifier; /* modifies scale for "birth" animation */
|
|
s16 birth_anim_counter;
|
|
s16 birth_anim_step;
|
|
s16 rotation_delay_timer;
|
|
s16 dynamic_work_s[5]; /* reserved for any use by each unique furniture actor */
|
|
f32 dynamic_work_f[2]; /* reserved for any use by each unique furniture actor */
|
|
s16 layer; /* layer the furniture actor resides on */
|
|
s16 _83E;
|
|
s16 demo_status; /* set when a music player is interacted with */
|
|
s16 dust_timer;
|
|
mActor_name_t items[aFTR_KEEP_ITEM_COUNT]; /* used for holding items (music players & wardrobes) */
|
|
int _84C;
|
|
u16* pal_p; /* used for furniture actors with dynamic palettes such as the structure model items */
|
|
int _854;
|
|
};
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|