diff --git a/config/assets.yml b/config/assets.yml index 69dd57b6..12d3ae09 100644 --- a/config/assets.yml +++ b/config/assets.yml @@ -181,6 +181,10 @@ config/rel.yml: obj_e_koinobori_b_pal: addrs: [0x806C5920, 0x806C5940] type: pal16 + # ac_mural + obj_mural_v: + addrs: [0x80904600, 0x80904640] + type: vtx # ac_lotus aLOT_obj_01_lotus_pal: addrs: [0x806C59E0, 0x806C5A00] diff --git a/config/rel_disasm_overrides.yml b/config/rel_disasm_overrides.yml index e376c805..7d9d26ab 100644 --- a/config/rel_disasm_overrides.yml +++ b/config/rel_disasm_overrides.yml @@ -11,4 +11,5 @@ symbol_aligns: 0x80F8C460: 32 # mFM_grd_s_rail_tex 0x80657200: 32 # .data msg.o 0x81297E80: 32 # .bss msg.o - 0x81296140: 32 # .bss m_island.o \ No newline at end of file + 0x81296140: 32 # .bss m_island.o + 0x80904700: 32 # rom_myhome1_floor_v diff --git a/config/rel_slices.yml b/config/rel_slices.yml index bd3b9e0f..3a2c846a 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -434,6 +434,11 @@ ac_misin.c: .text: [0x8042DEC8, 0x8042EAE0] .rodata: [0x80644238, 0x80644288] .data: [0x80684CB8, 0x80684D20] +ac_mural.c: + .text: [0x8042EAE0, 0x8042EDC0] + .rodata: [0x80644288, 0x806442A0] + .data: [0x80684D20, 0x80684D48] + .bss: [0x812F9C60, 0x812FBE60] ac_museum_fossil.c: .text: [0x8042EDC0, 0x8042F170] .rodata: [0x806442A0, 0x806442D0] @@ -929,6 +934,8 @@ data/combi/data_combi.c: .data: [0x8080DD80, 0x8080E628] data/item/item_name.c: .data: [0x808BF660, 0x808C8830] +data/model/mural/obj_mural.c: + .data: [0x80904600, 0x80904700] data/npc/default_list.c: .data: [0x8096CD90, 0x8096D328] data/npc/grow_list.c: diff --git a/include/ac_mural.h b/include/ac_mural.h index d4040e51..ca3bef62 100644 --- a/include/ac_mural.h +++ b/include/ac_mural.h @@ -8,6 +8,23 @@ extern "C" { #endif +#define aML_MURAL_X_NUM 4 +#define aML_MURAL_Y_NUM 4 +#define aML_MURAL_NUM (aML_MURAL_X_NUM * aML_MURAL_Y_NUM) + +typedef struct mural_s { + u8 type; + u16* pal_p; + u8* tex_p; +} aML_mural_c; + +typedef struct mural_actor_s MURAL_ACTOR; + +struct mural_actor_s { + ACTOR actor_class; + aML_mural_c mural[aML_MURAL_NUM]; +}; + extern ACTOR_PROFILE Mural_Profile; #ifdef __cplusplus @@ -15,4 +32,3 @@ extern ACTOR_PROFILE Mural_Profile; #endif #endif - diff --git a/include/libforest/gbi_extensions.h b/include/libforest/gbi_extensions.h index 5ba918fe..d1a39e1a 100644 --- a/include/libforest/gbi_extensions.h +++ b/include/libforest/gbi_extensions.h @@ -5,6 +5,8 @@ extern "C" { #endif +// clang-format off + #include "types.h" #include #include "dolphin/gx.h" @@ -578,6 +580,8 @@ do { \ #define gGXCallDisplayList(pkt, dl, nbytes) gDma1p(pkt, G_DL, dl, nbytes, G_DL_GXDL) #define gsGXCallDisplayList(dl, nbytes) gsDma1p(pkt, G_DL, dl, nbytes, G_DL_GXDL) +// clang-format on + #ifdef __cplusplus } #endif diff --git a/include/m_actor.h b/include/m_actor.h index de654032..ce02a3d3 100644 --- a/include/m_actor.h +++ b/include/m_actor.h @@ -450,7 +450,7 @@ typedef enum bank_id { ACTOR_OBJ_BANK_EF_MUSEUM, ACTOR_OBJ_BANK_EF_MINSECT, ACTOR_OBJ_BANK_411, - ACTOR_OBJ_BANK_412, + ACTOR_OBJ_BANK_MURAL, ACTOR_OBJ_BANK_413, ACTOR_OBJ_BANK_414, ACTOR_OBJ_BANK_415, diff --git a/src/ac_mural.c b/src/ac_mural.c new file mode 100644 index 00000000..ee693894 --- /dev/null +++ b/src/ac_mural.c @@ -0,0 +1,91 @@ +#include "ac_mural.h" + +#include "m_debug.h" +#include "m_name_table.h" +#include "m_player_lib.h" +#include "sys_matrix.h" + +static void Mural_Actor_ct(ACTOR* actorx, GAME* game); +static void Mural_Actor_dt(ACTOR* actorx, GAME* game); +static void Mural_Actor_move(ACTOR* actorx, GAME* game); +static void Mural_Actor_draw(ACTOR* actorx, GAME* game); + +ACTOR_PROFILE Mural_Profile = { + mAc_PROFILE_MURAL, + 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_MURAL, + sizeof(MURAL_ACTOR), + &Mural_Actor_ct, + &Mural_Actor_dt, + &Mural_Actor_move, + &Mural_Actor_draw, + NULL, +}; + +static u8 tex[aML_MURAL_NUM][(32 * 32) / 2]; +static u16 pal[aML_MURAL_NUM][16]; + +static void Mural_Actor_ct(ACTOR* actorx, GAME* game) { + MURAL_ACTOR* mural = (MURAL_ACTOR*)actorx; + int i; + + for (i = 0; i < aML_MURAL_NUM; i++) { + mural->mural[i].tex_p = tex[i]; + mural->mural[i].pal_p = pal[i]; + mPlib_Load_PlayerTexAndPallet(mural->mural[i].tex_p, mural->mural[i].pal_p, i); + mural->mural[i].type = 0; + } +} + +static void Mural_Actor_dt(ACTOR* actorx, GAME* game) { + // nothing +} + +static void Mural_Actor_move(ACTOR* actorx, GAME* game) { + MURAL_ACTOR* mural = (MURAL_ACTOR*)actorx; + + if (REGADDR(TAKREG, 10) == 0 || REGADDR(TAKREG, 10) == 1) { + if (REGADDR(TAKREG, 12) >= 0 && REGADDR(TAKREG, 12) < 255) { + if (REGADDR(TAKREG, 11) >= 0 && REGADDR(TAKREG, 11) < aML_MURAL_NUM) { + mural->mural[REGADDR(TAKREG, 11)].type = REGADDR(TAKREG, 10); + mPlib_Load_PlayerTexAndPallet(mural->mural[REGADDR(TAKREG, 11)].tex_p, + mural->mural[REGADDR(TAKREG, 11)].pal_p, REGADDR(TAKREG, 12)); + } + } + } + + actorx->world.position.y = 140.0f; +} + +extern Gfx obj_mural_model[]; + +static void Mural_Actor_draw(ACTOR* actorx, GAME* game) { + MURAL_ACTOR* mural = (MURAL_ACTOR*)actorx; + int y; + int x; + int i; + + i = 0; + for (y = 0; y < aML_MURAL_Y_NUM; y++) { + for (x = 0; x < aML_MURAL_X_NUM; x++, i++) { + OPEN_DISP(game->graph); + + Matrix_translate(actorx->world.position.x + x * 24.0f, actorx->world.position.y - y * 24.0f, + actorx->world.position.z, 0); + Matrix_scale(0.01f, 0.01f, 0.01f, 1); + + /* Segment 8 holds the palette */ + gSPSegment(NEXT_POLY_OPA_DISP, G_MWO_SEGMENT_8, mural->mural[i].pal_p); + + /* Segment 9 holds the texture */ + gSPSegment(NEXT_POLY_OPA_DISP, G_MWO_SEGMENT_9, mural->mural[i].tex_p); + + 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_mural_model); + + CLOSE_DISP(game->graph); + } + } +} diff --git a/src/data/model/mural/obj_mural.c b/src/data/model/mural/obj_mural.c new file mode 100644 index 00000000..c2efa085 --- /dev/null +++ b/src/data/model/mural/obj_mural.c @@ -0,0 +1,30 @@ +#include "libforest/gbi_extensions.h" + +// clang-format off +static Vtx obj_mural_v[] = { +#include "assets/obj_mural_v.inc" +}; + +Gfx obj_mural_model[] = { + gsSPTexture(65535, 65535, 0, G_TX_RENDERTILE, G_ON), + gsDPPipeSync(), + gsDPSetRenderMode(G_RM_FOG_SHADE_A, G_RM_AA_ZB_OPA_SURF2), + gsDPSetCombineLERP(TEXEL0, 0, SHADE, 0, 0, 0, 0, TEXEL0, PRIMITIVE, 0, COMBINED, 0, 0, 0, 0, COMBINED), + gsDPSetTextureLUT(G_TT_RGBA16), + + /* @BUG - These commands were never updated for Dolphin and therefore render broken */ +#ifndef BUGFIXES + gsDPLoadTLUT_pal16(15, 0x08000000), + gsDPLoadTextureBlock_4b(0x09000000, G_IM_FMT_CI, 32, 32, 15, G_TX_MIRROR | G_TX_WRAP, G_TX_MIRROR | G_TX_CLAMP, 5, 5, G_TX_NOLOD, G_TX_NOLOD), +#else + gsDPLoadTLUT_Dolphin(15, 16, 1, 0x08000000), + gsDPLoadTextureBlock_4b_Dolphin(0x09000000, G_IM_FMT_CI, 32, 32, 15, GX_MIRROR, GX_CLAMP, 0, 0), +#endif + gsDPSetPrimColor(0, 128, 255, 255, 255, 255), + gsSPLoadGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BACK | G_FOG | G_LIGHTING | G_SHADING_SMOOTH), + gsSPVertex(&obj_mural_v[0], 4, 0), + gsSP2Triangles(0, 1, 2, 0, 0, 2, 3, 0), + gsSPEndDisplayList(), +}; + +// clang-format on