Implement & link ac_countdown

This commit is contained in:
Cuyler36
2025-05-11 02:31:12 -04:00
parent 6d1c592645
commit 1e380d8442
9 changed files with 354 additions and 4 deletions
+1 -1
View File
@@ -963,7 +963,7 @@ config.libs = [
Object(Matching, "actor/ac_conveni.c"),
Object(Matching, "actor/ac_cottage.c"),
Object(NonMatching, "actor/ac_count02.c"),
Object(NonMatching, "actor/ac_countdown.c"),
Object(Matching, "actor/ac_countdown.c"),
Object(Matching, "actor/ac_depart.c"),
Object(Matching, "actor/ac_douzou.c"),
Object(Matching, "actor/ac_dummy.c"),
+8 -2
View File
@@ -2,12 +2,19 @@
#define AC_COUNTDOWN_H
#include "types.h"
#include "m_actor.h"
#include "ac_structure.h"
#include "ac_countdown_clip.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct countdown_actor_s COUNT_ACTOR;
struct countdown_actor_s {
/* 0x000 */ STRUCTURE_ACTOR structure_class;
};
extern ACTOR_PROFILE Count_Profile;
#ifdef __cplusplus
@@ -15,4 +22,3 @@ extern ACTOR_PROFILE Count_Profile;
#endif
#endif
+21
View File
@@ -0,0 +1,21 @@
#ifndef AC_COUNTDOWN_CLIP_H
#define AC_COUNTDOWN_CLIP_H
#include "types.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef void (*aCOU_ANIME_PLAY_PROC)(void);
typedef struct countdown_clip_s {
aCOU_ANIME_PLAY_PROC anime_play_proc;
int anime_play_flag;
} aCOU_Clip_c;
#ifdef __cplusplus
}
#endif
#endif /* AC_COUNTDOWN_CLIP_H */
+2 -1
View File
@@ -36,6 +36,7 @@
#include "ac_station_clip.h"
#include "ac_mikanbox_clip.h"
#include "ac_needlework_indoor_clip.h"
#include "ac_countdown_clip.h"
#ifdef __cplusplus
extern "C" {
@@ -90,7 +91,7 @@ typedef struct clip_s {
/* 0x0C4 */ aHTMD_clip_c* hatumode_clip;
/* 0x0C8 */ void* shrine_clip;
/* 0x0CC */ void* _0CC;
/* 0x0D0 */ void* _0D0;
/* 0x0D0 */ aCOU_Clip_c* countdown_clip;
/* 0x0D4 */ CLIP_NONE_PROC ball_redma_proc; /* removed in DnM+ */
/* 0x0D8 */ aMKBC_Clip_c* mikanbox_clip;
/* 0x0DC */ aAL_Clip_c* animal_logo_clip;
+1
View File
@@ -3388,6 +3388,7 @@ extern int mNT_check_unknown(mActor_name_t item_no);
#define DUMMY_YATAI 0xF10A
#define DUMMY_TUKIMI 0xF10A
#define DUMMY_MIKUJI 0xF10D
#define DUMMY_COUNT 0xF10E
#define DUMMY_TAMA 0xF110
#define DUMMY_TURI 0xF111
#define DUMMY_KOINOBORI 0xF114
+79
View File
@@ -0,0 +1,79 @@
#include "ac_countdown.h"
#include "m_common_data.h"
#include "m_name_table.h"
#include "m_player_lib.h"
#include "m_rcp.h"
#include "sys_matrix.h"
enum {
aCOU_ACT_WAIT,
aCOU_ACT_MOVE,
aCOU_ACT_HAPPY_NEW_YEAR,
aCOU_ACT_NUM
};
static void aCOU_actor_ct(ACTOR* actorx, GAME* game);
static void aCOU_actor_dt(ACTOR* actorx, GAME* game);
static void aCOU_actor_draw(ACTOR* actorx, GAME* game);
static void aCOU_actor_init(ACTOR* actorx, GAME* game);
ACTOR_PROFILE Count_Profile = {
// clang-format off
mAc_PROFILE_COUNT,
ACTOR_PART_ITEM,
ACTOR_STATE_TA_SET,
NEWYEAR_COUNTDOWN0,
ACTOR_OBJ_BANK_KEEP,
sizeof(COUNT_ACTOR),
aCOU_actor_ct,
aCOU_actor_dt,
aCOU_actor_init,
aCOU_actor_draw,
NULL,
// clang-format on
};
// @ 8056df2c
static u8 aCOU_shadow_vtx_fix_flg_table[4] = { 0x00, 0x01, 0x01, 0x00 };
extern Vtx obj_e_count_shadow_v[];
extern Gfx obj_e_count_shadow_model[];
static bIT_ShadowData_c aCOU_shadow_data = { ARRAY_COUNT(aCOU_shadow_vtx_fix_flg_table), aCOU_shadow_vtx_fix_flg_table,
60.0f, obj_e_count_shadow_v, obj_e_count_shadow_model };
static aCOU_Clip_c aCOU_clip;
extern cKF_Skeleton_R_c cKF_bs_r_obj_e_count01;
extern cKF_Animation_R_c cKF_ba_r_obj_e_count01;
static void aCOU_set_bgOffset(ACTOR* actorx, int idx);
static void aCOU_init_clip_area(void);
static void aCOU_free_clip_area(void);
static void aCOU_setup_action(COUNT_ACTOR* actor, int action);
static void aCOU_actor_ct(ACTOR* actorx, GAME* game) {
COUNT_ACTOR* actor = (COUNT_ACTOR*)actorx;
cKF_SkeletonInfo_R_ct(&actor->structure_class.keyframe, &cKF_bs_r_obj_e_count01, NULL,
actor->structure_class.work_area, actor->structure_class.morph_area);
aCOU_set_bgOffset(actorx, 1);
aCOU_setup_action(actor, aCOU_ACT_WAIT);
cKF_SkeletonInfo_R_play(&actor->structure_class.keyframe);
actor->structure_class.arg1 = 0;
actor->structure_class.arg2 = 0;
aCOU_init_clip_area();
}
static void aCOU_actor_dt(ACTOR* actorx, GAME* game) {
COUNT_ACTOR* actor = (COUNT_ACTOR*)actorx;
cKF_SkeletonInfo_R_dt(&actor->structure_class.keyframe);
aCOU_free_clip_area();
}
#include "../src/actor/ac_countdown_clip.c_inc"
#include "../src/actor/ac_countdown_move.c_inc"
#include "../src/actor/ac_countdown_draw.c_inc"
+17
View File
@@ -0,0 +1,17 @@
static void aCOU_anime_play(void) {
CLIP(countdown_clip)->anime_play_flag = TRUE;
}
static void aCOU_init_clip_area(void) {
if (CLIP(countdown_clip) == NULL) {
CLIP(countdown_clip) = &aCOU_clip;
CLIP(countdown_clip)->anime_play_proc = aCOU_anime_play;
CLIP(countdown_clip)->anime_play_flag = FALSE;
}
}
static void aCOU_free_clip_area(void) {
if (CLIP(countdown_clip) != NULL) {
CLIP(countdown_clip) = NULL;
}
}
+106
View File
@@ -0,0 +1,106 @@
static int aCOU_actor_draw_before(GAME* game, cKF_SkeletonInfo_R_c* keyframe, int joint_idx, Gfx** joint_shape,
u8* joint_flags, void* arg, s_xyz* joint_rot, xyz_t* joint_pos) {
static rgba_t prmcolor[10] = {
// clang-format off
{0xFF, 0xFF, 0xFF, 0xFF},
{0x64, 0x46, 0xC8, 0xFF},
{0x50, 0xC8, 0x00, 0xFF},
{0xFF, 0xFF, 0x00, 0xFF},
{0x00, 0x00, 0x00, 0xFF},
{0xFF, 0xFF, 0xFF, 0xFF},
{0x00, 0x00, 0x46, 0xFF},
{0x00, 0x28, 0x00, 0xFF},
{0x32, 0x0A, 0x00, 0xFF},
{0x00, 0x00, 0x00, 0xFF},
// clang-format on
};
static rgba_t envcolor[5] = {
// clang-format off
{0x00, 0x00, 0x00, 0x00},
{0x0A, 0x0A, 0x50, 0xFF},
{0x00, 0x50, 0x00, 0xFF},
{0xB4, 0x00, 0x00, 0xFF},
{0x00, 0x00, 0x00, 0x00},
// clang-format on
};
COUNT_ACTOR* actor = (COUNT_ACTOR*)arg;
int prim_l = 0;
int col_idx;
rgba_t* color;
OPEN_POLY_OPA_DISP(game->graph);
if (actor->structure_class.arg0 == aCOU_ACT_HAPPY_NEW_YEAR) {
col_idx = actor->structure_class.action / 20;
col_idx += 1;
if (joint_idx != 4) {
col_idx += 5;
}
} else {
col_idx = joint_idx == 4 ? 1 : 4;
}
switch (joint_idx) {
case 4:
prim_l = 128;
break;
case 5:
prim_l = 40;
break;
case 6:
prim_l = 20;
break;
}
if (prim_l != 0) {
gDPPipeSync(POLY_OPA_DISP++);
if (joint_idx == 4) {
gDPSetEnvColor(POLY_OPA_DISP++, envcolor[col_idx].r, envcolor[col_idx].g, envcolor[col_idx].b, envcolor[col_idx].a);
} else {
gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 60, 255);
}
gDPSetPrimColor(POLY_OPA_DISP++, 0, prim_l, prmcolor[col_idx].r, prmcolor[col_idx].g, prmcolor[col_idx].b, prmcolor[col_idx].a);
}
CLOSE_POLY_OPA_DISP(game->graph);
return TRUE;
}
static void aCOU_actor_draw(ACTOR* actorx, GAME* game) {
GRAPH* graph = game->graph;
cKF_SkeletonInfo_R_c* keyframe;
Mtx* mtx;
COUNT_ACTOR* actor = (COUNT_ACTOR*)actorx;
keyframe = &actor->structure_class.keyframe;
mtx = GRAPH_ALLOC_TYPE(graph, Mtx, keyframe->skeleton->num_shown_joints);
if (mtx != NULL) {
Gfx* scroll = two_tex_scroll(graph, 0, 16, 0, 16, 16, 1, 72, actor->structure_class.arg1, 16, 16);
if (scroll != NULL) {
u16* palette = CLIP(structure_clip)->get_pal_segment_proc(aSTR_PAL_COUNT);
_texture_z_light_fog_prim(graph);
OPEN_POLY_OPA_DISP(graph);
gSPSegment(POLY_OPA_DISP++, ANIME_2_TXT_SEG, palette);
CLOSE_POLY_OPA_DISP(graph);
_texture_z_light_fog_prim_xlu(graph);
OPEN_POLY_XLU_DISP(graph);
gSPSegment(POLY_XLU_DISP++, ANIME_1_TXT_SEG, scroll);
CLOSE_POLY_XLU_DISP(graph);
cKF_Si3_draw_R_SV(game, keyframe, mtx, aCOU_actor_draw_before, NULL, actorx);
CLIP(bg_item_clip)->draw_shadow_proc(game, &aCOU_shadow_data, FALSE);
}
}
}
+119
View File
@@ -0,0 +1,119 @@
static void aCOU_set_bgOffset(ACTOR* actorx, int idx) {
// @ 8056df44
static mCoBG_OffsetTable_c height_table_ct[6] = {
// clang-format off
{mCoBG_ATTRIBUTE_NONE, 9, 0, 9, 9, 9, TRUE},
{mCoBG_ATTRIBUTE_NONE, 9, 9, 9, 9, 9, FALSE},
{mCoBG_ATTRIBUTE_NONE, 9, 9, 9, 9, 0, TRUE},
{mCoBG_ATTRIBUTE_NONE, 9, 9, 9, 9, 9, FALSE},
{mCoBG_ATTRIBUTE_NONE, 9, 9, 9, 9, 9, FALSE},
{mCoBG_ATTRIBUTE_NONE, 9, 9, 9, 9, 9, FALSE},
// clang-format on
};
static mCoBG_OffsetTable_c* height_table[2] = { height_table_ct, height_table_ct };
static float addX[3] = { -40.0f, 0.0f, 40.0f };
static float addZ[2] = { -40.0f, 0.0f };
mCoBG_OffsetTable_c* table_p = height_table[idx];
xyz_t pos;
int i;
for (i = 0; i < 2; i++) {
pos.z = actorx->home.position.z + addZ[i];
pos.x = actorx->home.position.x + addX[0];
mCoBG_SetPluss5PointOffset_file(pos, *table_p, __FILE__, 113);
table_p++;
pos.x = actorx->home.position.x + addX[1];
mCoBG_SetPluss5PointOffset_file(pos, *table_p, __FILE__, 117);
table_p++;
pos.x = actorx->home.position.x + addX[2];
mCoBG_SetPluss5PointOffset_file(pos, *table_p, __FILE__, 121);
table_p++;
}
}
static void aCOU_wait(COUNT_ACTOR* actor) {
int action = aCOU_ACT_HAPPY_NEW_YEAR;
if (CLIP(countdown_clip)->anime_play_flag) {
lbRTC_time_c* time = Common_GetPointer(time.rtc_time);
if (time->month == lbRTC_DECEMBER && time->day == 31 && time->hour == 23 && time->min == 59) {
action = aCOU_ACT_MOVE;
}
aCOU_setup_action(actor, action);
}
}
static void aCOU_move(COUNT_ACTOR* actor) {
if (actor->structure_class.keyframe_saved_keyframe == 61) {
aCOU_setup_action(actor, aCOU_ACT_HAPPY_NEW_YEAR);
}
}
static void aCOU_happy_new_year(COUNT_ACTOR* actor) {
int action = actor->structure_class.action;
actor->structure_class.action = action >= 59 ? 0 : action + 1;
}
static void aCOU_setup_action(COUNT_ACTOR* actor, int action) {
static aSTR_MOVE_PROC process[] = {
// clang-format off
(aSTR_MOVE_PROC)aCOU_wait,
(aSTR_MOVE_PROC)aCOU_move,
(aSTR_MOVE_PROC)aCOU_happy_new_year,
// clang-format on
};
static float anime_start[] = { 1.0f, 1.0f, 61.0f };
static float anime_spd[] = { 0.0f, 0.5f, 0.0f };
cKF_SkeletonInfo_R_init(&actor->structure_class.keyframe, actor->structure_class.keyframe.skeleton,
&cKF_ba_r_obj_e_count01, anime_start[action], 61.0f, anime_start[action], anime_spd[action],
0.0f, cKF_FRAMECONTROL_STOP, NULL);
actor->structure_class.action_proc = process[action];
actor->structure_class.arg0 = action;
actor->structure_class.action = 0;
}
static void aCOU_actor_move(ACTOR* actorx, GAME* game) {
COUNT_ACTOR* actor = (COUNT_ACTOR*)actorx;
GAME_PLAY* play = (GAME_PLAY*)game;
ACTOR* playerx = GET_PLAYER_ACTOR_ACTOR(play);
int count_bx;
int count_bz;
int player_bx;
int player_bz;
mFI_Wpos2BlockNum(&count_bx, &count_bz, actorx->world.position);
mFI_Wpos2BlockNum(&player_bx, &player_bz, playerx->world.position);
if (!mDemo_Check(mDemo_TYPE_SCROLL, playerx) && !mDemo_Check(mDemo_TYPE_SCROLL2, playerx) &&
!mDemo_Check(mDemo_TYPE_SCROLL3, playerx) && (count_bx != player_bx || count_bz != player_bz)) {
Actor_delete(actorx);
return;
}
actor->structure_class.keyframe_state = cKF_SkeletonInfo_R_play(&actor->structure_class.keyframe);
actor->structure_class.keyframe_saved_keyframe = actor->structure_class.keyframe.frame_control.current_frame;
actor->structure_class.action_proc((STRUCTURE_ACTOR*)actor, play);
if ((++actor->structure_class.arg2) & 1) {
actor->structure_class.arg1--;
}
}
static void aCOU_actor_init(ACTOR* actorx, GAME* game) {
COUNT_ACTOR* actor = (COUNT_ACTOR*)actorx;
mFI_SetFG_common(DUMMY_COUNT, actorx->home.position, FALSE);
aCOU_actor_move(actorx, game);
actorx->mv_proc = aCOU_actor_move;
}