mirror of
https://github.com/ACreTeam/ac-decomp
synced 2026-05-23 06:34:18 -04:00
Implement & link ac_set_manager
This commit is contained in:
@@ -96,6 +96,10 @@ zurumode.c:
|
||||
sys_ucode.c:
|
||||
.text: [0x8040F008, 0x8040F048]
|
||||
.data: [0x8065FA30, 0x8065FA40]
|
||||
ac_set_manager.c:
|
||||
.text: [0x80496AB8, 0x80496F50]
|
||||
.rodata: [0x80644DB8, 0x80644DC8]
|
||||
.data: [0x8068BBE0, 0x8068BC18]
|
||||
m_huusui_room_ovl.c:
|
||||
.text: [0x804D1BBC, 0x804D2164]
|
||||
.rodata: [0x80646558, 0x806465C8]
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
#ifndef AC_SET_MANAGER_H
|
||||
#define AC_SET_MANAGER_H
|
||||
|
||||
#include "types.h"
|
||||
#include "m_actor.h"
|
||||
#include "m_play.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct actor_set_manager_s SET_MANAGER;
|
||||
|
||||
#define aSetMgr_SET_OVERLAY_BUF_SIZE 0x4000
|
||||
#define aSetMgr_KEEP_SIZE 0x354
|
||||
|
||||
#define aSetMgr_WAIT_TIME 5 // wait time between aSetMgr_move_check_wait -> aSetMgr_move_set
|
||||
|
||||
typedef void (*aSetMgr_ovl_proc)(SET_MANAGER*, GAME_PLAY*);
|
||||
|
||||
enum set_overlay_type {
|
||||
aSetMgr_OVERLAY_BEGIN = 0,
|
||||
|
||||
aSetMgr_OVERLAY_INSECT = aSetMgr_OVERLAY_BEGIN,
|
||||
aSetMgr_OVERLAY_GYOEI,
|
||||
|
||||
aSetMgr_OVERLAY_NUM
|
||||
};
|
||||
|
||||
enum set_manager_move_proc_type {
|
||||
aSetMgr_MOVE_move_check_set,
|
||||
aSetMgr_MOVE_move_check_wait,
|
||||
aSetMgr_MOVE_move_set,
|
||||
|
||||
aSetMgr_MOVE_PROC_NUM
|
||||
};
|
||||
|
||||
/* sizeof(aSetMgr_keep_c) == 0x354 */
|
||||
typedef struct actor_set_manager_keep_s {
|
||||
/* 0x000 */ u8 unk[aSetMgr_KEEP_SIZE];
|
||||
} aSetMgr_keep_c;
|
||||
|
||||
/* sizeof(aSetMgr_set_ovl_c) == 0x4004 */
|
||||
typedef struct actor_set_manager_ovl_s {
|
||||
/* 0x0000 */ u8 buf[aSetMgr_SET_OVERLAY_BUF_SIZE];
|
||||
/* 0x4000 */ aSetMgr_ovl_proc ovl_proc;
|
||||
} aSetMgr_set_ovl_c;
|
||||
|
||||
/* sizeof(aSetMgr_player_pos) == 0x18 */
|
||||
typedef struct actor_set_manager_player_pos_s {
|
||||
/* 0x00 */ int next_bx, next_bz;
|
||||
/* 0x08 */ int now_bx, now_bz;
|
||||
/* 0x10 */ int last_bx, last_bz;
|
||||
} aSetMgr_player_pos_c;
|
||||
|
||||
/* sizeof(SET_MANAGER) == 0x44F0 */
|
||||
struct actor_set_manager_s {
|
||||
/* 0x0000 */ ACTOR actor_class;
|
||||
/* 0x0174 */ u8 move_proc;
|
||||
/* 0x0175 */ u8 next_move_proc;
|
||||
/* 0x0176 */ u8 set_ovl_type;
|
||||
/* 0x0178 */ aSetMgr_set_ovl_c set_overlay;
|
||||
/* 0x417C */ int unk_417C;
|
||||
/* 0x4180 */ aSetMgr_player_pos_c player_pos;
|
||||
/* 0x4198 */ aSetMgr_keep_c keep;
|
||||
/* 0x44EC */ s16 wait_timer;
|
||||
};
|
||||
|
||||
extern ACTOR_PROFILE Set_Manager_Profile;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef AC_SET_OVL_GYOEI_H
|
||||
#define AC_SET_OVL_GYOEI_H
|
||||
|
||||
#include "types.h"
|
||||
#include "ac_set_manager.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void aSOG_gyoei_set(SET_MANAGER* set_manager, GAME_PLAY* play);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef AC_SET_OVL_INSECT_H
|
||||
#define AC_SET_OVL_INSECT_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void aSOI_insect_set(SET_MANAGER* set_manager, GAME_PLAY* play);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -12,6 +12,26 @@ extern "C" {
|
||||
|
||||
typedef void (*mActor_proc)(ACTOR*, GAME*);
|
||||
|
||||
#define ACTOR_STATE_NO_MOVE_WHILE_CULLED (1 << 4)
|
||||
#define ACTOR_STATE_NO_DRAW_WHILE_CULLED (1 << 5)
|
||||
#define ACTOR_STATE_CAN_MOVE_IN_DEMO_SCENES (1 << 29)
|
||||
|
||||
#define ACTOR_OBJ_BANK_NONE 0
|
||||
#define ACTOR_OBJ_BANK_3 3 /* TODO: rename, also likely an enum */
|
||||
|
||||
enum actor_part {
|
||||
ACTOR_PART_FG,
|
||||
ACTOR_PART_ITEM,
|
||||
ACTOR_PART_PLAYER,
|
||||
ACTOR_PART_NPC,
|
||||
ACTOR_PART_4, /* TODO: figure this one out */
|
||||
ACTOR_PART_BG,
|
||||
ACTOR_PART_EFFECT,
|
||||
ACTOR_PART_CONTROL,
|
||||
|
||||
ACTOR_PART_NUM
|
||||
};
|
||||
|
||||
/* sizeof(ACTOR_PROFILE) == 0x24 */
|
||||
typedef struct actor_profile_s {
|
||||
/* 0x00 */ s16 id; /* unique actor type ID */
|
||||
@@ -105,6 +125,8 @@ struct actor_s {
|
||||
/* 0x170 */ void* dlftbl; /* display list function table */
|
||||
};
|
||||
|
||||
#define mActor_NONE_PROC1 ((mActor_proc)none_proc1)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
+10
-1
@@ -45,6 +45,14 @@ enum field_room {
|
||||
((field_id) == mFI_FIELD_PLAYER0_ROOM || (field_id) == mFI_FIELD_PLAYER1_ROOM || \
|
||||
(field_id) == mFI_FIELD_PLAYER2_ROOM || (field_id) == mFI_FIELD_PLAYER3_ROOM)
|
||||
|
||||
/* "wade" between acres (acre transition) */
|
||||
enum player_wade_state {
|
||||
mFI_WADE_NONE,
|
||||
mFI_WADE_START,
|
||||
mFI_WADE_INPROGRESS,
|
||||
mFI_WADE_END
|
||||
};
|
||||
|
||||
/* Not sure about these other than the island one */
|
||||
enum {
|
||||
mFI_CLIMATE_0,
|
||||
@@ -75,7 +83,8 @@ extern void mFI_GetSpecialBlockNum(int* block_pos_tbl, u32* kind_list, int kind_
|
||||
extern int mFI_SetTreasure(int* block_x, int* block_z, mActor_name_t item_no);
|
||||
extern void mFI_SetFGUpData();
|
||||
extern int mFI_ClearBlockItemRandom_common(mActor_name_t item_no, int count, mActor_name_t* fg_items, u16* deposit, int include_deposited);
|
||||
extern void mFI_Wpos2BlockNum(int* block_x, int* block_z, xyz_t world_pos);
|
||||
extern int mFI_Wpos2BlockNum(int* block_x, int* block_z, xyz_t world_pos);
|
||||
extern int mFI_CheckPlayerWade(int wade_state);
|
||||
|
||||
extern void mFI_PrintNowBGNum(gfxprint_t* gfxprint);
|
||||
extern void mFI_PrintFgAttr(gfxprint_t* gfxprint);
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
#ifndef M_PLAYER_H
|
||||
#define M_PLAYER_H
|
||||
|
||||
#include "types.h"
|
||||
#include "m_actor.h"
|
||||
#include "m_lib.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct player_actor_s PLAYER_ACTOR;
|
||||
|
||||
/* sizeof(struct player_actor_s) == 0x13A8 */
|
||||
struct player_actor_s {
|
||||
/* 0x0000 */ ACTOR actor_class;
|
||||
/* 0x0174 */ u8 tmp0174[0x1318 - 0x0174];
|
||||
/* 0x1318 */ int (*Get_WadeEndPos_proc)(GAME*, xyz_t*);
|
||||
/* 0x131C */ u8 tmp131C[0x13A8 - 0x131C];
|
||||
/* TODO: finish */
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef M_PLAYER_LIB_H
|
||||
#define M_PLAYER_LIB_H
|
||||
|
||||
#include "types.h"
|
||||
#include "m_player.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern PLAYER_ACTOR* get_player_actor_withoutCheck(GAME_PLAY* play);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,281 @@
|
||||
#include "ac_set_manager.h"
|
||||
#include "m_name_table.h"
|
||||
#include "m_lib.h"
|
||||
#include "m_field_info.h"
|
||||
#include "m_player_lib.h"
|
||||
#include "libultra/libultra.h"
|
||||
#include "ac_set_ovl_insect.h"
|
||||
#include "ac_set_ovl_gyoei.h"
|
||||
|
||||
/**
|
||||
* @brief Gets the X & Z acre the player is currently in.
|
||||
*
|
||||
* @param bx Out player X-acre
|
||||
* @param bz Out player Z-acre
|
||||
* @return TRUE/FALSE successfully updated the acre
|
||||
**/
|
||||
static int aSetMgr_get_player_block(int* bx, int* bz, GAME_PLAY* play) {
|
||||
int res = FALSE;
|
||||
PLAYER_ACTOR* player_actor = get_player_actor_withoutCheck(play);
|
||||
|
||||
if (player_actor != NULL) {
|
||||
res = mFI_Wpos2BlockNum(bx, bz, player_actor->actor_class.world_position);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the next X & Z acre which the player is currently transitioning into.
|
||||
*
|
||||
* @param next_bx Out next player X-acre
|
||||
* @param next_bz Out next player Z-acre
|
||||
* @return TRUE/FALSE successfully updated next acre
|
||||
**/
|
||||
static int aSetMgr_renewal_player_next_pos(int* next_bx, int* next_bz) {
|
||||
int wade_end_pos_res;
|
||||
int wpos_2_blocknum_res;
|
||||
xyz_t endpos = { 0.0f, 0.0f, 0.0f };
|
||||
GAME_PLAY* play = (GAME_PLAY*)gamePT;
|
||||
|
||||
wade_end_pos_res = get_player_actor_withoutCheck(play)->Get_WadeEndPos_proc((GAME*)play, &endpos); // maybe make this a macro like GET_PLAYER_ACTOR() ?
|
||||
wpos_2_blocknum_res = mFI_Wpos2BlockNum(next_bx, next_bz, endpos);
|
||||
return wpos_2_blocknum_res | wade_end_pos_res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Updates the set manager's internal player acre and updates the previous player acre.
|
||||
*
|
||||
* @param play GAME_PLAY pointer
|
||||
* @param player_pos Pointer to SET_MANAGER internal player position structure
|
||||
**/
|
||||
static void aSetMgr_renewal_player_pos(GAME_PLAY* play, aSetMgr_player_pos_c* player_pos) {
|
||||
int bx, bz;
|
||||
|
||||
player_pos->last_bx = player_pos->now_bx;
|
||||
player_pos->last_bz = player_pos->now_bz;
|
||||
|
||||
if (aSetMgr_get_player_block(&bx, &bz, play) == TRUE) {
|
||||
player_pos->now_bx = bx;
|
||||
player_pos->now_bz = bz;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks if the player's wade state is 'starting'.
|
||||
*
|
||||
* @return TRUE when the player is beginning an acre transition, FALSE otherwise
|
||||
**/
|
||||
static int aSetMgr_check_player_wade_start() {
|
||||
return mFI_CheckPlayerWade(mFI_WADE_START);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks if the player's wade state is 'ending'.
|
||||
*
|
||||
* @return TRUE when the player is finishing an acre transition, FALSE otherwise
|
||||
**/
|
||||
static int aSetMgr_check_player_wade_end() {
|
||||
return mFI_CheckPlayerWade(mFI_WADE_END);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clears the set overlay buffer.
|
||||
*
|
||||
* @param set_ovl Pointer to SET_MANAGER's internal aSetMgr_set_ovl_c overlay structure
|
||||
**/
|
||||
static void aSetMgr_clear_set_ovl(aSetMgr_set_ovl_c* set_ovl) {
|
||||
bzero(set_ovl->buf, aSetMgr_SET_OVERLAY_BUF_SIZE);
|
||||
set_ovl->ovl_proc = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Updates the SET_MANAGER's current set overlay process.
|
||||
*
|
||||
* @param set_ovl Pointer to SET_MANAGER's internal aSetMgr_set_ovl_c overlay structure
|
||||
* @param type The aSetMgr_OVERLAY_* type which will be executed
|
||||
* @return TRUE
|
||||
**/
|
||||
static int aSetMgr_ovl(aSetMgr_set_ovl_c* set_ovl, int type) {
|
||||
static aSetMgr_ovl_proc proc_table[aSetMgr_OVERLAY_NUM] = { &aSOI_insect_set, &aSOG_gyoei_set };
|
||||
|
||||
if (type < aSetMgr_OVERLAY_BEGIN || type >= aSetMgr_OVERLAY_NUM) {
|
||||
type = aSetMgr_OVERLAY_BEGIN;
|
||||
}
|
||||
|
||||
set_ovl->ovl_proc = proc_table[type];
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clears the SET_MANAGER's "kept" data buffer.
|
||||
*
|
||||
* @param keep Pointer to the SET_MANAGER's internal aSetMgr_keep_c structure
|
||||
**/
|
||||
static void aSetMgr_clear_keep(aSetMgr_keep_c* keep) {
|
||||
bzero(keep, aSetMgr_KEEP_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if the 'move' func state should be updated to 'check_wait'.
|
||||
*
|
||||
* This check is succeeded by the player entering an acre transition state.
|
||||
*
|
||||
* @param play GAME_PLAY pointer
|
||||
* @param set_manager SET_MANAGER pointer
|
||||
* @return TRUE when updated, FALSE otherwise
|
||||
**/
|
||||
static int aSetMgr_move_check_set(GAME_PLAY* play, SET_MANAGER* set_manager) {
|
||||
int wading = FALSE;
|
||||
aSetMgr_renewal_player_pos(play, &set_manager->player_pos);
|
||||
|
||||
/* update the next acre position if player is starting acre transition state */
|
||||
if (aSetMgr_check_player_wade_start() == TRUE) {
|
||||
aSetMgr_renewal_player_next_pos(&set_manager->player_pos.next_bx, &set_manager->player_pos.next_bz);
|
||||
set_manager->next_move_proc = aSetMgr_MOVE_move_check_wait;
|
||||
wading = TRUE;
|
||||
}
|
||||
|
||||
return wading;
|
||||
}
|
||||
|
||||
typedef int (*aSetMgr_move_proc)(GAME_PLAY*, SET_MANAGER*);
|
||||
|
||||
/**
|
||||
* @brief Checks whether or not to update the move proc to 'set'.
|
||||
*
|
||||
* The SET_MANAGER's internal wait timer must be zero to pass this check.
|
||||
*
|
||||
* @param play GAME_PLAY pointer
|
||||
* @param set_manager SET_MANAGER pointer
|
||||
* @return TRUE when updated, FALSE otherwise
|
||||
**/
|
||||
static int aSetMgr_move_check_wait(GAME_PLAY* play, SET_MANAGER* set_manager) {
|
||||
int wait_timer;
|
||||
int res = FALSE;
|
||||
|
||||
if (set_manager->next_move_proc == aSetMgr_MOVE_move_check_wait) {
|
||||
if (set_manager->wait_timer == 0) {
|
||||
wait_timer = 0;
|
||||
}
|
||||
else {
|
||||
wait_timer = --set_manager->wait_timer;
|
||||
}
|
||||
|
||||
if (wait_timer == 0) {
|
||||
set_manager->next_move_proc = aSetMgr_MOVE_move_set;
|
||||
set_manager->wait_timer = aSetMgr_WAIT_TIME;
|
||||
res = TRUE;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Processes SET_MANAGER's overlay actors & checks whether to update move func state.
|
||||
*
|
||||
* All SET_MANAGER overlay processes must have been executed OR the player must
|
||||
* finish transitioning between acres for this check to pass.
|
||||
*
|
||||
* @param play GAME_PLAY pointer
|
||||
* @param set_manager SET_MANAGER pointer
|
||||
* @return TRUE when updated, FALSE otherwise
|
||||
**/
|
||||
static int aSetMgr_move_set(GAME_PLAY* play, SET_MANAGER* set_manager) {
|
||||
int res = FALSE;
|
||||
|
||||
if (aSetMgr_ovl(&set_manager->set_overlay, set_manager->set_ovl_type) == TRUE &&
|
||||
set_manager->set_overlay.ovl_proc != NULL) {
|
||||
set_manager->set_overlay.ovl_proc(set_manager, play);
|
||||
set_manager->set_ovl_type++;
|
||||
}
|
||||
else {
|
||||
set_manager->set_ovl_type++;
|
||||
}
|
||||
|
||||
if (set_manager->set_ovl_type >= aSetMgr_OVERLAY_NUM) {
|
||||
set_manager->next_move_proc = aSetMgr_MOVE_move_check_set;
|
||||
set_manager->set_ovl_type = aSetMgr_OVERLAY_BEGIN;
|
||||
res = TRUE;
|
||||
}
|
||||
|
||||
if (aSetMgr_check_player_wade_end() == TRUE) {
|
||||
set_manager->next_move_proc = aSetMgr_MOVE_move_check_set;
|
||||
set_manager->set_ovl_type = aSetMgr_OVERLAY_BEGIN;
|
||||
res = TRUE;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SET_MANAGER move process.
|
||||
*
|
||||
* @param actor Pointer to the SET_MANAGER actor
|
||||
* @param game GAME pointer
|
||||
**/
|
||||
static void aSetMgr_move(ACTOR* actor, GAME* game) {
|
||||
static aSetMgr_move_proc move[aSetMgr_MOVE_PROC_NUM] = {
|
||||
&aSetMgr_move_check_set,
|
||||
&aSetMgr_move_check_wait,
|
||||
&aSetMgr_move_set
|
||||
};
|
||||
|
||||
SET_MANAGER* set_manager = (SET_MANAGER*)actor;
|
||||
GAME_PLAY* play = (GAME_PLAY*)game;
|
||||
|
||||
if ((*move[set_manager->move_proc])(play, set_manager) == TRUE) {
|
||||
set_manager->move_proc = set_manager->next_move_proc;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SET_MANAGER constructor.
|
||||
*
|
||||
* @param actor Pointer to the SET_MANAGER actor
|
||||
* @param game GAME pointer
|
||||
**/
|
||||
static void aSetMgr_ct(ACTOR* actor, GAME* game) {
|
||||
SET_MANAGER* set_manager = (SET_MANAGER*)actor;
|
||||
GAME_PLAY* play = (GAME_PLAY*)game;
|
||||
|
||||
set_manager->move_proc = aSetMgr_MOVE_move_check_set;
|
||||
set_manager->next_move_proc = aSetMgr_MOVE_move_check_set;
|
||||
set_manager->set_ovl_type = aSetMgr_OVERLAY_BEGIN;
|
||||
|
||||
aSetMgr_clear_set_ovl(&set_manager->set_overlay);
|
||||
|
||||
set_manager->player_pos.next_bx = 0;
|
||||
set_manager->player_pos.next_bz = 0;
|
||||
set_manager->player_pos.now_bx = 0;
|
||||
set_manager->player_pos.now_bz = 0;
|
||||
set_manager->player_pos.last_bx = 0;
|
||||
set_manager->player_pos.last_bz = 0;
|
||||
|
||||
set_manager->wait_timer = aSetMgr_WAIT_TIME;
|
||||
|
||||
aSetMgr_clear_keep(&set_manager->keep);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SET_MANAGER destructor.
|
||||
*
|
||||
* @param actor Pointer to the SET_MANAGER actor
|
||||
* @param game GAME pointer
|
||||
**/
|
||||
static void aSetMgr_dt(ACTOR* actor, GAME* game) { }
|
||||
|
||||
/* actor profile for SET_MANAGER */
|
||||
ACTOR_PROFILE Set_Manager_Profile = {
|
||||
0x72, /* TODO: replace with enum */
|
||||
ACTOR_PART_CONTROL, /* control actor type */
|
||||
ACTOR_STATE_NO_MOVE_WHILE_CULLED | ACTOR_STATE_NO_DRAW_WHILE_CULLED | ACTOR_STATE_CAN_MOVE_IN_DEMO_SCENES,
|
||||
EMPTY_NO,
|
||||
ACTOR_OBJ_BANK_3,
|
||||
sizeof(SET_MANAGER),
|
||||
aSetMgr_ct,
|
||||
aSetMgr_dt,
|
||||
aSetMgr_move,
|
||||
mActor_NONE_PROC1,
|
||||
NULL
|
||||
};
|
||||
Reference in New Issue
Block a user