Implement & link ac_set_manager

This commit is contained in:
Cuyler36
2023-05-16 21:13:49 -04:00
parent ccf81c3c8d
commit 2af13706e7
9 changed files with 469 additions and 1 deletions
+4
View File
@@ -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]
+75
View File
@@ -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
+17
View File
@@ -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
+16
View File
@@ -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
+22
View File
@@ -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
View File
@@ -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);
+27
View File
@@ -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
+17
View File
@@ -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
+281
View File
@@ -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
};