Implement & link ac_npc_p_sel

This commit is contained in:
Cuyler36
2024-10-28 20:28:46 -04:00
parent ee7bd3bdb0
commit b0c1fabcc4
10 changed files with 515 additions and 7 deletions
+4
View File
@@ -839,6 +839,10 @@ ac_npc_guide2.c:
.text: [0x80554B00, 0x80556714]
.rodata: [0x806496A0, 0x80649720]
.data: [0x806A6508, 0x806A67E0]
ac_npc_p_sel.c:
.text: [0x805662C0, 0x80567000]
.rodata: [0x806498C0, 0x806498F8]
.data: [0x806BE3F0, 0x806BE480]
ac_npc_rcn_guide.c:
.text: [0x8056EED0, 0x8056FFF0]
.rodata: [0x806499C0, 0x806499E8]
+17
View File
@@ -3,11 +3,28 @@
#include "types.h"
#include "m_actor.h"
#include "ac_npc.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct npc_p_sel_s NPC_P_SEL_ACTOR;
typedef void (*aNPS_TALK_PROC)(NPC_P_SEL_ACTOR*, GAME_PLAY*);
/* sizeof(NPC_P_SEL_ACTOR) == 0x9B0 */
struct npc_p_sel_s {
/* 0x000 */ NPC_ACTOR npc_class;
/* 0x994 */ int talk_idx;
/* 0x998 */ int next_talk_idx;
/* 0x99C */ aNPS_TALK_PROC talk_proc;
/* 0x9A0 */ int talk_end_flag;
/* 0x9A4 */ int silent_counter;
/* 0x9A8 */ int strum_timer;
/* 0x9AC */ int bgm_stop_timer;
};
extern ACTOR_PROFILE Npc_P_Sel_Profile;
#ifdef __cplusplus
+1
View File
@@ -45,6 +45,7 @@ extern s32 mCD_GetThisLandSlotNo_code(int* player_no, s32* slot_card_results);
extern void mCD_save_data_aram_malloc();
extern void mCD_set_aram_save_data();
extern void mCD_init_card();
extern s32 mCD_InitGameStart_bg(int chan, int file_no, int sound_mode, s32* mounted_chan);
extern void mCD_PrintErrInfo(gfxprint_t* gfxprint);
extern void mCD_InitAll();
+4 -4
View File
@@ -8,9 +8,9 @@ extern "C" {
#endif
enum {
Config_SOUND_MODE_0,
Config_SOUND_MODE_1,
Config_SOUND_MODE_2,
Config_SOUND_MODE_STEREO,
Config_SOUND_MODE_MONO,
Config_SOUND_MODE_HEADPHONES,
Config_SOUND_MODE_NUM
};
@@ -27,7 +27,7 @@ enum {
typedef struct config_s {
/* 0x00 */ u8 sound_mode; /* mono, stereo, ... */
/* 0x01 */ u8 voice_mode; /* silent, babblese, animalese */
/* 0x02 */ u8 vibration_enabled; /* true/false */
/* 0x02 */ u8 vibration_disabled; /* true/false */
/* 0x03 */ u8 unused; /* might not exist */
} Config_c;
+162
View File
@@ -0,0 +1,162 @@
#include "ac_npc_p_sel.h"
#include "m_config.h"
#include "m_common_data.h"
#include "m_player_lib.h"
#include "m_soncho.h"
#include "m_play.h"
#include "m_card.h"
#include "m_bgm.h"
#include "m_choice.h"
#include "m_msg.h"
#include "m_vibctl.h"
#include "libultra/libultra.h"
#include "dolphin/os/OSRtc.h"
enum {
aNPS_TALK_CHK_SETUP_SOUND,
aNPS_TALK_SETUP_SOUND,
aNPS_TALK_SETUP_VOICE,
aNPS_TALK_CONFIRM_INPUT_DATA,
aNPS_TALK_CONFIRM_INPUT_DATA2,
aNPS_TALK_SETUP_YURE,
aNPS_TALK_WAIT,
aNPS_TALK_NUM
};
typedef void (*aNPS_THINK_PROC)(NPC_ACTOR*, GAME_PLAY*);
static void aNPS_actor_ct(ACTOR* actorx, GAME* game);
static void aNPS_actor_dt(ACTOR* actorx, GAME* game);
static void aNPS_actor_init(ACTOR* actorx, GAME* game);
static void aNPS_actor_save(ACTOR* actorx, GAME* game);
static void aNPS_actor_move(ACTOR* actorx, GAME* game);
static void aNPS_actor_draw(ACTOR* actorx, GAME* game);
static void aNPS_talk_request(ACTOR* actorx, GAME* game);
static void aNPS_change_talk_proc(NPC_P_SEL_ACTOR* p_sel, int talk_idx);
static int aNPS_talk_init(ACTOR* actorx, GAME* game);
static int aNPS_talk_end_chk(ACTOR* actorx, GAME* game);
static void aNPS_schedule_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int type);
// clang-format off
ACTOR_PROFILE Npc_P_Sel_Profile = {
mAc_PROFILE_NPC_P_SEL,
ACTOR_PART_NPC,
ACTOR_STATE_NONE,
SP_NPC_P_SEL,
ACTOR_OBJ_BANK_KEEP,
sizeof(NPC_P_SEL_ACTOR),
&aNPS_actor_ct,
&aNPS_actor_dt,
&aNPS_actor_init,
mActor_NONE_PROC1,
&aNPS_actor_save,
};
// clang-format on
static u8 aNPS_sound_mode[] = { Config_SOUND_MODE_STEREO, Config_SOUND_MODE_MONO, Config_SOUND_MODE_HEADPHONES };
static u8 aNPS_voice_mode[] = { Config_VOICE_MODE_ANIMALESE, Config_VOICE_MODE_CLICK, Config_VOICE_MODE_SILENT };
static void aNPS_actor_ct(ACTOR* actorx, GAME* game) {
// clang-format off
static aNPC_ct_data_c ct_data = {
&aNPS_actor_move,
&aNPS_actor_draw,
5,
(aNPC_TALK_REQUEST_PROC)&none_proc1,
&aNPS_talk_init,
&aNPS_talk_end_chk,
0,
};
// clang-format off
GAME_PLAY* play = (GAME_PLAY*)game;
NPC_P_SEL_ACTOR* p_sel = (NPC_P_SEL_ACTOR*)actorx;
PLAYER_ACTOR* player;
xyz_t center;
xyz_t eye;
if (CLIP(npc_clip)->birth_check_proc(actorx, game) == TRUE) {
p_sel->npc_class.schedule.schedule_proc = &aNPS_schedule_proc;
CLIP(npc_clip)->ct_proc(actorx, game, &ct_data);
actorx->status_data.weight = MASSTYPE_IMMOVABLE;
mPlib_request_main_demo_wait_type1(game, FALSE, NULL);
player = GET_PLAYER_ACTOR(play);
if (player != NULL) {
player->actor_class.state_bitfield |= ACTOR_STATE_INVISIBLE;
}
center.x = 100.0f;
center.y = 60.0f;
center.z = 60.0f;
eye.x = 100.0f;
eye.y = 130.0f;
eye.z = 210.0f;
Camera2_change_priority(play, 0);
Camera2_request_main_lock(play, &center, &eye, 40.0f, 0, 100.0f, 400.0f, 5);
if (OSGetSoundMode() == OS_SOUND_MODE_MONO) {
Save_Get(config).sound_mode = Config_SOUND_MODE_MONO;
} else {
Save_Get(config).sound_mode = Config_SOUND_MODE_STEREO;
}
sAdo_SetOutMode(aNPS_sound_mode[Save_Get(config).sound_mode]);
Save_Get(config).voice_mode = Config_VOICE_MODE_ANIMALESE;
sAdo_SetVoiceMode(aNPS_voice_mode[Save_Get(config).voice_mode]);
p_sel->npc_class.condition_info.hide_request = FALSE;
p_sel->npc_class.talk_info.default_act = aNPC_ACT_INTO_HOUSE;
}
}
static void aNPS_actor_save(ACTOR* actorx, GAME* game) {
CLIP(npc_clip)->save_proc(actorx, game);
}
static void aNPS_actor_dt(ACTOR* actorx, GAME* game) {
CLIP(npc_clip)->dt_proc(actorx, game);
}
static void aNPS_actor_init(ACTOR* actorx, GAME* game) {
CLIP(npc_clip)->init_proc(actorx, game);
}
static void aNPS_actor_move(ACTOR* actorx, GAME* game) {
NPC_P_SEL_ACTOR* p_sel;
cKF_FrameControl_c* fc_p;
f32 speed;
u8 arm_flag;
StaffRollInfo_c staffroll_info;
p_sel = (NPC_P_SEL_ACTOR*)actorx;
fc_p = &p_sel->npc_class.draw.main_animation.keyframe.frame_control;
speed = 0.5f;
arm_flag = TRUE;
if (p_sel->npc_class.draw.animation_id == aNPC_ANIM_4HAKU_E1) {
sAdos_GetStaffRollInfo(&staffroll_info);
if (staffroll_info.staffroll_part != STAFFROLL_PART_FINISH) {
speed = 0.0f;
arm_flag = FALSE;
fc_p->current_frame = 1.0f + 64.0f * (f32)staffroll_info.percent;
}
}
fc_p->speed = speed;
sAdos_TTKK_ARM(arm_flag);
CLIP(npc_clip)->move_proc(actorx, game);
mSC_change_player_freeze((GAME_PLAY*)game); // TODO: mSC_change_player_freeze almost certainly takes a GAME*
}
static void aNPS_actor_draw(ACTOR* actorx, GAME* game) {
CLIP(npc_clip)->draw_proc(actorx, game);
}
#include "../src/ac_npc_p_sel_schedule.c_inc"
#include "../src/ac_npc_p_sel_talk.c_inc"
+88
View File
@@ -0,0 +1,88 @@
static int aNPS_setup_game_start(GAME_PLAY* play) {
static Door_data_c door_data = {
SCENE_START_DEMO, mSc_DIRECT_NORTH, 0, 0, { 120, 0, 340 }, EMPTY_NO, 3, { 0, 0, 0 }
};
s32 chan;
int res = FALSE;
if (mCD_InitGameStart_bg(0, -1, 0, &chan) == 0) {
goto_other_scene(play, &door_data, TRUE);
Common_Set(transition.wipe_type, 3);
Common_Set(map_flag, FALSE);
res = TRUE;
}
return res;
}
static void aNPS_think_main_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
NPC_P_SEL_ACTOR* p_sel = (NPC_P_SEL_ACTOR*)nactorx;
u32 alpha;
if (!p_sel->talk_end_flag) {
if (p_sel->strum_timer == 0) {
nactorx->talk_info.talk_request_proc = &aNPS_talk_request;
} else {
p_sel->strum_timer--;
}
} else {
if (p_sel->strum_timer == 0) {
if (aNPS_setup_game_start(play) == TRUE) {
p_sel->strum_timer = -1;
play->fade_color_value.c.a = 255;
}
} else if (p_sel->strum_timer > 0) {
if (p_sel->strum_timer < 70) {
alpha = 255 * (1.0f - p_sel->strum_timer / 70.0f);
play->fade_color_value.c.a = (u8)alpha;
}
p_sel->strum_timer--;
}
}
if (p_sel->bgm_stop_timer == 0) {
mBGMPsComp_make_ps_wipe(0x421C);
p_sel->bgm_stop_timer = -1;
} else if (p_sel->bgm_stop_timer > 0) {
p_sel->bgm_stop_timer--;
}
}
static void aNPS_think_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
NPC_P_SEL_ACTOR* p_sel = (NPC_P_SEL_ACTOR*)nactorx;
nactorx->request.act_priority = 4;
nactorx->request.act_idx = aNPC_ACT_TALK;
nactorx->request.act_type = aNPC_ACT_TYPE_DEFAULT;
}
static void aNPS_think_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int type) {
static aNPS_THINK_PROC think_proc[] = { &aNPS_think_init_proc, &aNPS_think_main_proc };
(*think_proc[type])(nactorx, play);
}
static void aNPS_schedule_init_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
NPC_P_SEL_ACTOR* p_sel = (NPC_P_SEL_ACTOR*)nactorx;
nactorx->draw._5BE = 1;
nactorx->think.think_proc = &aNPS_think_proc;
nactorx->talk_info.default_animation = aNPC_ANIM_4HAKU_E1;
p_sel->strum_timer = 440;
p_sel->bgm_stop_timer = -1;
CLIP(npc_clip)->think_proc(nactorx, play, aNPC_THINK_IN_BLOCK, 0);
}
static void aNPS_schedule_main_proc(NPC_ACTOR* nactorx, GAME_PLAY* play) {
if (CLIP(npc_clip)->think_proc(nactorx, play, -1, 1) == 0) {
CLIP(npc_clip)->think_proc(nactorx, play, -1, 2);
}
}
static void aNPS_schedule_proc(NPC_ACTOR* nactorx, GAME_PLAY* play, int type) {
static aNPC_SUB_PROC sche_proc[] = { &aNPS_schedule_init_proc, &aNPS_schedule_main_proc };
(*sche_proc[type])(nactorx, play);
}
+236
View File
@@ -0,0 +1,236 @@
static int aNPS_setup_sound_option(void) {
static u8 sound_mode[] = { Config_SOUND_MODE_STEREO, Config_SOUND_MODE_MONO, Config_SOUND_MODE_HEADPHONES };
int order;
int res;
int idx;
order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9);
res = FALSE;
if (order != 0) {
idx = 0;
switch (mChoice_GET_CHOSENUM()) {
case mChoice_CHOICE0:
idx = 0;
break;
case mChoice_CHOICE1:
idx = 1;
break;
case mChoice_CHOICE2:
idx = 2;
break;
}
OSSetSoundMode(sound_mode[idx] == Config_SOUND_MODE_MONO ? OS_SOUND_MODE_MONO : OS_SOUND_MODE_STEREO);
Save_Get(config).sound_mode = sound_mode[idx];
sAdo_SetOutMode(aNPS_sound_mode[idx]);
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
res = TRUE;
}
return res;
}
static int aNPS_setup_voice_option(void) {
static u8 voice_mode[] = { Config_VOICE_MODE_ANIMALESE, Config_VOICE_MODE_CLICK, Config_VOICE_MODE_SILENT };
int order;
int res;
int idx;
order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9);
res = FALSE;
if (order != 0) {
idx = 0;
switch (mChoice_GET_CHOSENUM()) {
case mChoice_CHOICE0:
idx = 0;
break;
case mChoice_CHOICE1:
idx = 1;
break;
case mChoice_CHOICE2:
idx = 2;
break;
}
Save_Get(config).voice_mode = voice_mode[idx];
sAdo_SetVoiceMode(aNPS_voice_mode[idx]);
mMsg_sound_spec_change_voice_force(mMsg_Get_base_window_p());
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
res = TRUE;
}
return res;
}
static int aNPS_setup_yure_option(void) {
int order;
int res;
int disabled;
order = mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 9);
res = FALSE;
if (order != 0) {
disabled = TRUE;
switch (mChoice_GET_CHOSENUM()) {
case mChoice_CHOICE0:
disabled = FALSE;
mVibctl_entry(75, mVibctl_VIB_PROG_NON, mVibctl_VIB_PROG_FFF, mVibctl_VIB_PROG_P, 0, 16, 45, 0.0f);
break;
case mChoice_CHOICE1:
disabled = TRUE;
break;
}
Save_Get(config).vibration_disabled = disabled;
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 9, 0);
res = TRUE;
}
return res;
}
static void aNPS_chk_setup_sound(NPC_P_SEL_ACTOR* p_sel, GAME_PLAY* play) {
if (mMsg_CHECK_MAINNORMALCONTINUE() == TRUE) {
int next_talk_idx = -1;
switch (mChoice_GET_CHOSENUM()) {
case mChoice_CHOICE0:
next_talk_idx = aNPS_TALK_WAIT;
break;
case mChoice_CHOICE1:
next_talk_idx = aNPS_TALK_SETUP_YURE;
p_sel->next_talk_idx = aNPS_TALK_CONFIRM_INPUT_DATA;
break;
}
if (next_talk_idx != -1) {
aNPS_change_talk_proc(p_sel, next_talk_idx);
}
}
}
static void aNPS_setup_sound(NPC_P_SEL_ACTOR* p_sel, GAME_PLAY* play) {
if (aNPS_setup_sound_option() == TRUE) {
aNPS_change_talk_proc(p_sel, aNPS_TALK_SETUP_VOICE);
}
}
static void aNPS_setup_yure(NPC_P_SEL_ACTOR* p_sel, GAME_PLAY* play) {
if (aNPS_setup_yure_option() == TRUE) {
aNPS_change_talk_proc(p_sel, aNPS_TALK_SETUP_SOUND);
}
}
static void aNPS_setup_voice(NPC_P_SEL_ACTOR* p_sel, GAME_PLAY* play) {
if (aNPS_setup_voice_option() == TRUE) {
aNPS_change_talk_proc(p_sel, p_sel->next_talk_idx);
}
}
static void aNPS_confirm_input_data(NPC_P_SEL_ACTOR* p_sel, GAME_PLAY* play) {
if (mMsg_CHECK_MAINNORMALCONTINUE() == TRUE) {
switch (mChoice_GET_CHOSENUM()) {
case mChoice_CHOICE0:
aNPS_change_talk_proc(p_sel, aNPS_TALK_CONFIRM_INPUT_DATA2);
break;
default:
aNPS_change_talk_proc(p_sel, aNPS_TALK_SETUP_VOICE);
break;
}
}
}
static void aNPS_confirm_input_data2(NPC_P_SEL_ACTOR* p_sel, GAME_PLAY* play) {
if (mMsg_CHECK_MAINNORMALCONTINUE() == TRUE) {
switch (mChoice_GET_CHOSENUM()) {
case mChoice_CHOICE0:
aNPS_change_talk_proc(p_sel, aNPS_TALK_WAIT);
break;
default:
aNPS_change_talk_proc(p_sel, aNPS_TALK_SETUP_YURE);
break;
}
}
}
static void aNPS_change_talk_proc(NPC_P_SEL_ACTOR* p_sel, int talk_idx) {
static aNPS_TALK_PROC process[] = {
&aNPS_chk_setup_sound, &aNPS_setup_sound, &aNPS_setup_voice, &aNPS_confirm_input_data,
&aNPS_confirm_input_data2, &aNPS_setup_yure, (aNPS_TALK_PROC)&none_proc1,
};
p_sel->talk_idx = talk_idx;
p_sel->talk_proc = process[talk_idx];
}
static void aNPS_set_talk_info_talk_request(ACTOR* actorx) {
int msg_no = !mFRm_CheckSaveData() ? 0x09C7 : 0x09CA;
mDemo_Set_msg_num(msg_no);
mDemo_Set_camera(CAMERA2_PROCESS_NORMAL);
}
static void aNPS_talk_request(ACTOR* actorx, GAME* game) {
mDemo_Request(mDemo_TYPE_SPEAK, actorx, &aNPS_set_talk_info_talk_request);
}
static int aNPS_talk_init(ACTOR* actorx, GAME* game) {
NPC_P_SEL_ACTOR* p_sel = (NPC_P_SEL_ACTOR*)actorx;
mDemo_Set_ListenAble();
aNPS_change_talk_proc(p_sel, aNPS_TALK_CHK_SETUP_SOUND);
p_sel->npc_class.talk_info.talk_request_proc = (aNPC_TALK_REQUEST_PROC)&none_proc1;
mMsg_SET_IDLING_REQ();
return TRUE;
}
static int aNPS_talk_end_chk(ACTOR* actorx, GAME* game) {
NPC_P_SEL_ACTOR* p_sel = (NPC_P_SEL_ACTOR*)actorx;
GAME_PLAY* play = (GAME_PLAY*)game;
mMsg_Window_c* msg_p = mMsg_Get_base_window_p();
int res = FALSE;
(*p_sel->talk_proc)(p_sel, play);
if (mMsg_Check_idling_now(msg_p) == TRUE) {
mMsg_request_main_disappear_wait_type1(msg_p);
p_sel->strum_timer = 150;
p_sel->bgm_stop_timer = 80;
bzero(&play->fade_color_value, sizeof(rgba8888));
aNPS_think_init_proc(&p_sel->npc_class, play);
p_sel->talk_end_flag = TRUE;
res = TRUE;
} else {
int silent_counter = p_sel->silent_counter;
if (mMsg_Check_MainNormal(msg_p) == TRUE || mChoice_CHECK_MAIN_NORMAL() == TRUE) {
silent_counter++;
if (silent_counter > 600) {
silent_counter = 600;
}
} else {
silent_counter = 0;
}
if (mDemo_Get_OrderValue(mDemo_ORDER_NPC0, 0) == 0) {
if (silent_counter >= 600) {
if (p_sel->npc_class.draw.animation_id != aNPC_ANIM_4HAKU_E1) {
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 0, 255);
}
} else {
if (p_sel->npc_class.draw.animation_id == aNPC_ANIM_4HAKU_E1) {
mDemo_Set_OrderValue(mDemo_ORDER_NPC0, 0, 253);
}
}
}
p_sel->silent_counter = silent_counter;
}
return res;
}
+1 -1
View File
@@ -72,7 +72,7 @@ static void aNRTC_talk_request(ACTOR* actor, GAME*);
static void aNRTC_change_talk_proc(NPC_RTC_ACTOR* rtc, int idx);
static u8 aNRTC_sound_mode[] = { Config_SOUND_MODE_0, Config_SOUND_MODE_1, Config_SOUND_MODE_2 };
static u8 aNRTC_sound_mode[] = { Config_SOUND_MODE_STEREO, Config_SOUND_MODE_MONO, Config_SOUND_MODE_HEADPHONES };
static u8 aNRTC_voice_mode[] = { Config_VOICE_MODE_ANIMALESE, Config_VOICE_MODE_CLICK, Config_VOICE_MODE_SILENT };
static void aNRTC_actor_ct(ACTOR* actor, GAME* game) {
+1 -1
View File
@@ -390,7 +390,7 @@ static void mVibInfo_set_target_elem(mVibInfo_c* vib_info) {
}
static void mVibInfo_force(mVibInfo_c* vib_info) {
if (Save_Get(config.vibration_enabled)) {
if (Save_Get(config.vibration_disabled)) {
mVibInfo_set_force_stop(vib_info, mVibctl_FLAG_FORCE_STOP0);
}
else {
+1 -1
View File
@@ -475,7 +475,7 @@ static int sChk_Config_c_sub(Config_c* config, int depth) {
res = TRUE;
}
if (config->vibration_enabled & (~1)) {
if (config->vibration_disabled & (~1)) {
mFRm_ERRORLINE(1803);
res = TRUE;
}