mirror of
https://github.com/ACreTeam/ac-decomp
synced 2026-07-09 20:41:31 -04:00
Implement & link ac_countdown
This commit is contained in:
+1
-1
@@ -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"),
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user