Implement & link ac_needlework_indoor

This commit is contained in:
Cuyler36
2025-05-11 01:11:33 -04:00
parent da0c91fd94
commit 6d1c592645
6 changed files with 450 additions and 5 deletions
+1 -1
View File
@@ -1031,7 +1031,7 @@ config.libs = [
Object(Matching, "actor/ac_my_indoor.c"),
Object(Matching, "actor/ac_my_room.c"),
Object(Matching, "actor/ac_nameplate.c"),
Object(NonMatching, "actor/ac_needlework_indoor.c"),
Object(Matching, "actor/ac_needlework_indoor.c"),
Object(Matching, "actor/ac_needlework_shop.c"),
Object(Matching, "actor/ac_police_box.c"),
Object(Matching, "actor/ac_post_office.c"),
+21 -1
View File
@@ -3,11 +3,32 @@
#include "types.h"
#include "m_actor.h"
#include "m_needlework.h"
#include "ac_needlework_indoor_clip.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct needlework_indoor_movebg_s {
xyz_t pos;
mCoBG_bg_regist_c regist;
int regist_idx;
} aNI_MoveBg_c;
typedef struct needlework_indoor_actor_s NEEDLEWORK_INDOOR_ACTOR;
/* sizeof(NEEDLEWORK_INDOOR_ACTOR) == 0x3F0 */
struct needlework_indoor_actor_s {
/* 0x000 */ ACTOR actor_class;
/* 0x174 */ u8 _174[0x188 - 0x174];
/* 0x188 */ mNW_original_design_c* data[2][mNW_TYPE_NUM][mNW_DESIGN_NUM];
/* 0x1C8 */ int design_buf_idx[mNW_TYPE_NUM][mNW_DESIGN_NUM];
/* 0x1E8 */ aNI_MoveBg_c cloth_move_bg[mNW_CLOTH_DESIGN_NUM];
/* 0x2E8 */ aNI_MoveBg_c umbrella_move_bg[mNW_UMBRELLA_DESIGN_NUM];
/* 0x3E8 */ aNI_Clip_c clip;
};
extern ACTOR_PROFILE Needlework_Indoor_Profile;
#ifdef __cplusplus
@@ -15,4 +36,3 @@ extern ACTOR_PROFILE Needlework_Indoor_Profile;
#endif
#endif
+42
View File
@@ -0,0 +1,42 @@
#ifndef AC_NEEDLEWORK_INDOOR_CLIP_H
#define AC_NEEDLEWORK_INDOOR_CLIP_H
#include "types.h"
#include "m_actor_type.h"
#include "m_needlework.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef int (*aNI_REQUESTCOPYCLOTHDATA_PROC)(int manekin_idx, mNW_original_design_c* design);
typedef int (*aNI_REQUESTCOPYUMBDATA_PROC)(int umbrella_idx, mNW_original_design_c* design);
typedef int (*aNI_REQUESTEXCHANGECLOTHDATA_PROC)(int manekin_idx, int player_org_idx);
typedef int (*aNI_REQUESTEXCHANGEUMBDATA_PROC)(int umbrella_idx, int player_org_idx);
typedef struct needlework_indoor_clip_s {
ACTOR* needlework_indoor_actor_p;
int copy_cloth_data_requested;
aNI_REQUESTCOPYCLOTHDATA_PROC request_copy_cloth_data_proc;
int copy_cloth_data_idx;
mNW_original_design_c* copy_cloth_data_design_p;
int exchange_cloth_data_requested;
aNI_REQUESTEXCHANGECLOTHDATA_PROC request_exchange_cloth_data_proc;
int exchange_cloth_data_idx;
int exchange_cloth_data_player_org_idx;
int copy_umb_data_requested;
aNI_REQUESTCOPYUMBDATA_PROC request_copy_umb_data_proc;
int copy_umb_data_idx;
mNW_original_design_c* copy_umb_data_design_p;
int exchange_umb_data_requested;
aNI_REQUESTEXCHANGEUMBDATA_PROC request_exchange_umb_data_proc;
int exchange_umb_data_idx;
int exchange_umb_data_player_org_idx;
int _44;
} aNI_Clip_c;
#ifdef __cplusplus
}
#endif
#endif /* AC_NEEDLEWORK_INDOOR_CLIP_H */
+2 -1
View File
@@ -35,6 +35,7 @@
#include "ac_hatumode_control.h"
#include "ac_station_clip.h"
#include "ac_mikanbox_clip.h"
#include "ac_needlework_indoor_clip.h"
#ifdef __cplusplus
extern "C" {
@@ -46,7 +47,7 @@ typedef void (*CLIP_NONE_PROC)();
typedef struct clip_s {
/* 0x000 */ BoxTrick01_data_c box_trick_data[4];
/* 0x020 */ int arrange_ftr_num;
/* 0x024 */ void* _024;
/* 0x024 */ aNI_Clip_c* needlework_indoor_clip;
/* 0x028 */ void* misin_clip;
/* 0x02C */ aHTBL_Clip_c* htbl_clip;
/* 0x030 */ void* _030;
+3 -2
View File
@@ -13,8 +13,9 @@ extern "C" {
#define mNW_ORIGINAL_DESIGN_HEIGHT 32 /* height */
#define mNW_DEFAULT_ORIGINAL_TEX_NUM 4 /* number of 'default' player textures which are not blank */
#define mNW_CLOTH_DESIGN_NUM 4 /* number of clothing designs in Able Sisters' */
#define mNW_UMBRELLA_DESIGN_NUM 4 /* number of umbrella designs in Able Sisters' */
#define mNW_DESIGN_NUM 4 // default number of designs
#define mNW_CLOTH_DESIGN_NUM mNW_DESIGN_NUM /* number of clothing designs in Able Sisters' */
#define mNW_UMBRELLA_DESIGN_NUM mNW_DESIGN_NUM /* number of umbrella designs in Able Sisters' */
#define mNW_TOTAL_DESIGN_NUM (mNW_CLOTH_DESIGN_NUM + mNW_UMBRELLA_DESIGN_NUM) /* total designs in Able Sisters' */
#define mNW_DESIGN_TEX_SIZE (mNW_ORIGINAL_DESIGN_HEIGHT * (mNW_ORIGINAL_DESIGN_WIDTH / 2)) /* total texture data size */
+381
View File
@@ -0,0 +1,381 @@
#include "ac_needlework_indoor.h"
#include "m_malloc.h"
#include "m_common_data.h"
#include "m_rcp.h"
#include "sys_matrix.h"
#define aNI_GET_ACTOR() (CLIP(needlework_indoor_clip) != NULL ? CLIP(needlework_indoor_clip)->needlework_indoor_actor_p : NULL)
static void Needlework_Indoor_Actor_ct(ACTOR* actorx, GAME* game);
static void Needlework_Indoor_Actor_dt(ACTOR* actorx, GAME* game);
static void Needlework_Indoor_Actor_move(ACTOR* actorx, GAME* game);
static void Needlework_Indoor_Actor_draw(ACTOR* actorx, GAME* game);
ACTOR_PROFILE Needlework_Indoor_Profile = {
// clang-format off
mAc_PROFILE_NEEDLEWORK_INDOOR,
ACTOR_PART_BG,
ACTOR_STATE_CAN_MOVE_IN_DEMO_SCENES | ACTOR_STATE_NO_DRAW_WHILE_CULLED | ACTOR_STATE_NO_MOVE_WHILE_CULLED,
EMPTY_NO,
ACTOR_OBJ_BANK_KEEP,
sizeof(NEEDLEWORK_INDOOR_ACTOR),
Needlework_Indoor_Actor_ct,
Needlework_Indoor_Actor_dt,
Needlework_Indoor_Actor_move,
Needlework_Indoor_Actor_draw,
NULL,
// clang-format on
};
static void aNI_SetClip(ACTOR* actorx);
static void aNI_CopyClothData(int idx, mNW_original_design_c* design, int se_flag);
static void aNI_ExchangeCloth(int idx, int player_org_idx, int se_flag);
static void aNI_CopyUmbData(int idx, mNW_original_design_c* design, int se_flag);
static void aNI_ExchangeUmb(int idx, int player_org_idx, int se_flag);
static int aNI_RequestCopyClothData(int manekin_idx, mNW_original_design_c* design);
static int aNI_RequestCopyUmbData(int umbrella_idx, mNW_original_design_c* design);
static int aNI_RequestExchangeCloth(int manekin_idx, int player_org_idx);
static int aNI_RequestExchangeUmb(int umbrella_idx, int player_org_idx);
static void aNI_CopyAllData(ACTOR* actorx, GAME* game) {
int i;
for (i = 0; i < mNW_CLOTH_DESIGN_NUM; i++) {
aNI_CopyClothData(i, &Save_Get(needlework).original_design[i & 3], FALSE);
}
for (i = 0; i < mNW_UMBRELLA_DESIGN_NUM; i++) {
aNI_CopyUmbData(i, &Save_Get(needlework).original_design[mNW_CLOTH_DESIGN_NUM + (i & 3)], FALSE);
}
}
static void aNI_MallocRam(ACTOR* actorx) {
NEEDLEWORK_INDOOR_ACTOR* actor = (NEEDLEWORK_INDOOR_ACTOR*)actorx;
int i;
int j;
for (i = 0; i < mNW_CLOTH_DESIGN_NUM; i++) {
for (j = 0; j < 2; j++) {
actor->data[j][mNW_TYPE_MANEKIN][i] =
(mNW_original_design_c*)zelda_malloc_align(sizeof(mNW_original_design_c), 32);
}
}
for (i = 0; i < mNW_UMBRELLA_DESIGN_NUM; i++) {
for (j = 0; j < 2; j++) {
actor->data[j][mNW_TYPE_UMBRELLA][i] =
(mNW_original_design_c*)zelda_malloc_align(sizeof(mNW_original_design_c), 32);
}
}
}
static void aNI_SetMoveBg(ACTOR* actorx) {
static mCoBG_bg_size_c l_manekin_mBgData = { 14.5f, 14.5f, 14.5f, 14.5f };
static s16 dummy_angle = 0;
static xyz_t manekin_pos[4] = {
// clang-format off
{180.0f, 40.0f, 100.0f},
{220.0f, 40.0f, 100.0f},
{260.0f, 40.0f, 100.0f},
{300.0f, 40.0f, 100.0f},
// clang-format on
};
static xyz_t umbrella_pos[4] = {
// clang-format off
{180.0f, 40.0f, 180.0f},
{220.0f, 40.0f, 180.0f},
{260.0f, 40.0f, 180.0f},
{300.0f, 40.0f, 180.0f},
// clang-format on
};
NEEDLEWORK_INDOOR_ACTOR* actor = (NEEDLEWORK_INDOOR_ACTOR*)actorx;
int i;
for (i = 0; i < mNW_CLOTH_DESIGN_NUM; i++) {
actor->cloth_move_bg[i].pos = manekin_pos[i];
actor->cloth_move_bg[i].regist_idx =
mCoBG_RegistMoveBg(&actor->cloth_move_bg[i].regist, &actor->cloth_move_bg[i].pos, NULL, &dummy_angle, 40.0f,
&l_manekin_mBgData, NULL, NULL, NULL, mCoBG_FTR_TYPE_NUM, mCoBG_ATTRIBUTE_STONE, 40.0f);
}
for (i = 0; i < mNW_UMBRELLA_DESIGN_NUM; i++) {
actor->umbrella_move_bg[i].pos = umbrella_pos[i];
actor->umbrella_move_bg[i].regist_idx = mCoBG_RegistMoveBg(
&actor->umbrella_move_bg[i].regist, &actor->umbrella_move_bg[i].pos, NULL, &dummy_angle, 40.0f,
&l_manekin_mBgData, NULL, NULL, NULL, mCoBG_FTR_TYPE_NUM, mCoBG_ATTRIBUTE_STONE, 40.0f);
}
}
static void aNI_SetClip(ACTOR* actorx) {
NEEDLEWORK_INDOOR_ACTOR* actor = (NEEDLEWORK_INDOOR_ACTOR*)actorx;
actor->clip.needlework_indoor_actor_p = actorx;
actor->clip.request_copy_cloth_data_proc = aNI_RequestCopyClothData;
actor->clip.request_copy_umb_data_proc = aNI_RequestCopyUmbData;
actor->clip.request_exchange_cloth_data_proc = aNI_RequestExchangeCloth;
actor->clip.request_exchange_umb_data_proc = aNI_RequestExchangeUmb;
CLIP(needlework_indoor_clip) = &actor->clip;
}
static void Needlework_Indoor_Actor_ct(ACTOR* actorx, GAME* game) {
aNI_SetClip(actorx);
aNI_MallocRam(actorx);
aNI_SetMoveBg(actorx);
aNI_CopyAllData(actorx, game);
}
static void aNI_FreeRam(ACTOR* actorx) {
NEEDLEWORK_INDOOR_ACTOR* actor = (NEEDLEWORK_INDOOR_ACTOR*)actorx;
int i;
int j;
for (i = 0; i < 2; i++) {
for (j = 0; j < mNW_DESIGN_NUM; j++) {
zelda_free(actor->data[i][mNW_TYPE_MANEKIN][j]);
zelda_free(actor->data[i][mNW_TYPE_UMBRELLA][j]);
}
}
}
static void Needlework_Indoor_Actor_dt(ACTOR* actorx, GAME* game) {
NEEDLEWORK_INDOOR_ACTOR* actor = (NEEDLEWORK_INDOOR_ACTOR*)actorx;
int i;
for (i = 0; i < mNW_CLOTH_DESIGN_NUM; i++) {
mCoBG_CrossOffMoveBg(actor->cloth_move_bg[i].regist_idx);
}
for (i = 0; i < mNW_UMBRELLA_DESIGN_NUM; i++) {
mCoBG_CrossOffMoveBg(actor->umbrella_move_bg[i].regist_idx);
}
aNI_FreeRam(actorx);
}
extern Gfx obj_shop_manekin_model[];
static void aNI_DrawManekin(ACTOR* actorx, GAME* game) {
NEEDLEWORK_INDOOR_ACTOR* actor = (NEEDLEWORK_INDOOR_ACTOR*)actorx;
int i;
for (i = 0; i < mNW_CLOTH_DESIGN_NUM; i++) {
int idx = actor->design_buf_idx[mNW_TYPE_MANEKIN][i] & 1;
u8* texture = actor->data[idx][mNW_TYPE_MANEKIN][i]->design.data;
u16* palette = mNW_PaletteIdx2Palette(actor->data[idx][mNW_TYPE_MANEKIN][i]->palette);
OPEN_DISP(game->graph);
_texture_z_light_fog_prim(game->graph);
Matrix_translate(actor->cloth_move_bg[i].pos.x, actor->cloth_move_bg[i].pos.y,
actor->cloth_move_bg[i].pos.z, 0);
Matrix_scale(0.01f, 0.01f, 0.01f, 1);
gSPSegment(NEXT_POLY_OPA_DISP, ANIME_1_TXT_SEG, texture);
gSPSegment(NEXT_POLY_OPA_DISP, ANIME_2_TXT_SEG, palette);
gSPMatrix(NEXT_POLY_OPA_DISP, _Matrix_to_Mtx_new(game->graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(NEXT_POLY_OPA_DISP, obj_shop_manekin_model);
CLOSE_DISP(game->graph);
}
}
extern Gfx obj_shop_umbmy_model[];
static void aNI_DrawUmbrella(ACTOR* actorx, GAME* game) {
NEEDLEWORK_INDOOR_ACTOR* actor = (NEEDLEWORK_INDOOR_ACTOR*)actorx;
int i;
for (i = 0; i < mNW_UMBRELLA_DESIGN_NUM; i++) {
int idx = actor->design_buf_idx[mNW_TYPE_UMBRELLA][i] & 1;
u8* texture = actor->data[idx][mNW_TYPE_UMBRELLA][i]->design.data;
u16* palette = mNW_PaletteIdx2Palette(actor->data[idx][mNW_TYPE_UMBRELLA][i]->palette);
OPEN_DISP(game->graph);
_texture_z_light_fog_prim(game->graph);
Matrix_translate(actor->umbrella_move_bg[i].pos.x, actor->umbrella_move_bg[i].pos.y,
actor->umbrella_move_bg[i].pos.z, 0);
Matrix_scale(0.01f, 0.01f, 0.01f, 1);
gSPSegment(NEXT_POLY_OPA_DISP, ANIME_2_TXT_SEG, texture);
gSPSegment(NEXT_POLY_OPA_DISP, ANIME_1_TXT_SEG, palette);
gSPMatrix(NEXT_POLY_OPA_DISP, _Matrix_to_Mtx_new(game->graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(NEXT_POLY_OPA_DISP, obj_shop_umbmy_model);
CLOSE_DISP(game->graph);
}
}
static void Needlework_Indoor_Actor_draw(ACTOR* actorx, GAME* game) {
aNI_DrawManekin(actorx, game);
aNI_DrawUmbrella(actorx, game);
}
static void Needlework_Indoor_Actor_move(ACTOR* actorx, GAME* game) {
NEEDLEWORK_INDOOR_ACTOR* actor = (NEEDLEWORK_INDOOR_ACTOR*)actorx;
GAME_PLAY* play = (GAME_PLAY*)game;
Submenu* submenu = &play->submenu;
if (submenu->process_status == mSM_PROCESS_WAIT) {
if (actor->clip.copy_cloth_data_requested == TRUE) {
aNI_CopyClothData(actor->clip.copy_cloth_data_idx, actor->clip.copy_cloth_data_design_p, TRUE);
actor->clip.copy_cloth_data_requested = FALSE;
}
if (actor->clip.exchange_cloth_data_requested == TRUE) {
aNI_ExchangeCloth(actor->clip.exchange_cloth_data_idx, actor->clip.exchange_cloth_data_player_org_idx, TRUE);
actor->clip.exchange_cloth_data_requested = FALSE;
}
if (actor->clip.copy_umb_data_requested == TRUE) {
aNI_CopyUmbData(actor->clip.copy_umb_data_idx, actor->clip.copy_umb_data_design_p, TRUE);
actor->clip.copy_umb_data_requested = FALSE;
}
if (actor->clip.exchange_umb_data_requested == TRUE) {
aNI_ExchangeUmb(actor->clip.exchange_umb_data_idx, actor->clip.exchange_umb_data_player_org_idx, TRUE);
actor->clip.exchange_umb_data_requested = FALSE;
}
}
}
static int aNI_RequestCopyClothData(int manekin_idx, mNW_original_design_c* design) {
if (aNI_GET_ACTOR() != NULL) {
NEEDLEWORK_INDOOR_ACTOR* actor = (NEEDLEWORK_INDOOR_ACTOR*)aNI_GET_ACTOR();
if (actor->clip.copy_cloth_data_requested == FALSE) {
actor->clip.copy_cloth_data_idx = manekin_idx;
actor->clip.copy_cloth_data_design_p = design;
actor->clip.copy_cloth_data_requested = TRUE;
return TRUE;
}
}
return FALSE;
}
static void aNI_CopyClothData(int idx, mNW_original_design_c* design, int se_flag) {
idx &= 3;
if (aNI_GET_ACTOR() != NULL) {
NEEDLEWORK_INDOOR_ACTOR* actor = (NEEDLEWORK_INDOOR_ACTOR*)aNI_GET_ACTOR();
int buf_idx;
actor->design_buf_idx[mNW_TYPE_MANEKIN][idx] = (actor->design_buf_idx[mNW_TYPE_MANEKIN][idx] + 1) & 1;
buf_idx = actor->design_buf_idx[mNW_TYPE_MANEKIN][idx];
mNW_CopyOriginalTextureClass(actor->data[buf_idx][mNW_TYPE_MANEKIN][idx & 3], design);
mNW_CopyOriginalTextureClass(&Save_Get(needlework).original_design[idx & 3], design);
if (se_flag == TRUE) {
sAdo_SysTrgStart(NA_SE_461);
}
}
}
static int aNI_RequestExchangeCloth(int manekin_idx, int player_org_idx) {
if (aNI_GET_ACTOR() != NULL) {
NEEDLEWORK_INDOOR_ACTOR* actor = (NEEDLEWORK_INDOOR_ACTOR*)aNI_GET_ACTOR();
if (actor->clip.exchange_cloth_data_requested == FALSE) {
actor->clip.exchange_cloth_data_idx = manekin_idx;
actor->clip.exchange_cloth_data_player_org_idx = player_org_idx;
actor->clip.exchange_cloth_data_requested = TRUE;
return TRUE;
}
}
return FALSE;
}
static void aNI_ExchangeCloth(int idx, int player_org_idx, int se_flag) {
NEEDLEWORK_INDOOR_ACTOR* actor;
int buf_idx;
int tmp_idx;
idx &= 3;
tmp_idx = idx & 3;
if (aNI_GET_ACTOR() != NULL) {
actor = (NEEDLEWORK_INDOOR_ACTOR*)aNI_GET_ACTOR();
buf_idx = actor->design_buf_idx[mNW_TYPE_MANEKIN][idx];
aNI_CopyClothData(idx, &Now_Private->my_org[player_org_idx & 7], FALSE);
mNW_CopyOriginalTextureClass(&Now_Private->my_org[player_org_idx & 7], actor->data[buf_idx][mNW_TYPE_MANEKIN][tmp_idx]);
if (se_flag == TRUE) {
sAdo_SysTrgStart(NA_SE_461);
}
}
}
static int aNI_RequestCopyUmbData(int umbrella_idx, mNW_original_design_c* design) {
if (aNI_GET_ACTOR() != NULL) {
NEEDLEWORK_INDOOR_ACTOR* actor = (NEEDLEWORK_INDOOR_ACTOR*)aNI_GET_ACTOR();
if (actor->clip.copy_umb_data_requested == FALSE) {
actor->clip.copy_umb_data_idx = umbrella_idx;
actor->clip.copy_umb_data_design_p = design;
actor->clip.copy_umb_data_requested = TRUE;
return TRUE;
}
}
return FALSE;
}
static void aNI_CopyUmbData(int idx, mNW_original_design_c* design, int se_flag) {
idx &= 3;
if (aNI_GET_ACTOR() != NULL) {
NEEDLEWORK_INDOOR_ACTOR* actor = (NEEDLEWORK_INDOOR_ACTOR*)aNI_GET_ACTOR();
int buf_idx;
actor->design_buf_idx[mNW_TYPE_UMBRELLA][idx] = (actor->design_buf_idx[mNW_TYPE_UMBRELLA][idx] + 1) & 1;
buf_idx = actor->design_buf_idx[mNW_TYPE_UMBRELLA][idx];
mNW_CopyOriginalTextureClass(actor->data[buf_idx][mNW_TYPE_UMBRELLA][idx & 3], design);
mNW_CopyOriginalTextureClass(&Save_Get(needlework).original_design[mNW_CLOTH_DESIGN_NUM + (idx & 3)], design);
if (se_flag == TRUE) {
sAdo_SysTrgStart(NA_SE_461);
}
}
}
static int aNI_RequestExchangeUmb(int umbrella_idx, int player_org_idx) {
if (aNI_GET_ACTOR() != NULL) {
NEEDLEWORK_INDOOR_ACTOR* actor = (NEEDLEWORK_INDOOR_ACTOR*)aNI_GET_ACTOR();
if (actor->clip.exchange_umb_data_requested == FALSE) {
actor->clip.exchange_umb_data_idx = umbrella_idx;
actor->clip.exchange_umb_data_player_org_idx = player_org_idx;
actor->clip.exchange_umb_data_requested = TRUE;
return TRUE;
}
}
return FALSE;
}
static void aNI_ExchangeUmb(int idx, int player_org_idx, int se_flag) {
NEEDLEWORK_INDOOR_ACTOR* actor;
int buf_idx;
int tmp_idx;
idx &= 3;
tmp_idx = idx & 3;
if (aNI_GET_ACTOR() != NULL) {
actor = (NEEDLEWORK_INDOOR_ACTOR*)aNI_GET_ACTOR();
buf_idx = actor->design_buf_idx[mNW_TYPE_UMBRELLA][idx];
aNI_CopyUmbData(idx, &Now_Private->my_org[player_org_idx & 7], FALSE);
mNW_CopyOriginalTextureClass(&Now_Private->my_org[player_org_idx & 7], actor->data[buf_idx][mNW_TYPE_UMBRELLA][tmp_idx]);
if (se_flag == TRUE) {
sAdo_SysTrgStart(NA_SE_461);
}
}
}