diff --git a/config/rel_slices.yml b/config/rel_slices.yml index 2cb5f071..426dc846 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -891,6 +891,10 @@ ac_weather_leaf.c: .text: [0x8060420C, 0x806048B8] .rodata: [0x8064BBE8, 0x8064BC40] .data: [0x806D1E28, 0x806D1E48] +ef_flash.c: + .text: [0x8060B7B4, 0x8060BCB0] + .rodata: [0x8064C078, 0x8064C0B0] + .data: [0x806D2350, 0x806D2430] ef_killer.c: .text: [0x80614178, 0x8061481C] .rodata: [0x8064C680, 0x8064C6C0] diff --git a/src/ef_flash.c b/src/ef_flash.c index a6a3d756..faea2416 100644 --- a/src/ef_flash.c +++ b/src/ef_flash.c @@ -1,20 +1,13 @@ #include "ef_effect_control.h" -static void eFlash_init(xyz_t pos, int prio, s16 angle, GAME* game, u16 item_name, s16 arg0, s16 arg1) { - // TODO -} +#include "m_common_data.h" +#include "m_rcp.h" +#include "sys_matrix.h" -static void eFlash_ct(eEC_Effect_c* effect, GAME* game, void* ct_arg) { - // TODO -} - -static void eFlash_mv(eEC_Effect_c* effect, GAME* game) { - // TODO -} - -static void eFlash_dw(eEC_Effect_c* effect, GAME* game) { - // TODO -} +static void eFlash_init(xyz_t pos, int prio, s16 angle, GAME* game, u16 item_name, s16 arg0, s16 arg1); +static void eFlash_ct(eEC_Effect_c* effect, GAME* game, void* ct_arg); +static void eFlash_mv(eEC_Effect_c* effect, GAME* game); +static void eFlash_dw(eEC_Effect_c* effect, GAME* game); eEC_PROFILE_c iam_ef_flash = { // clang-format off @@ -28,22 +21,65 @@ eEC_PROFILE_c iam_ef_flash = { // clang-format on }; -static void eFlashC_init(xyz_t pos, int prio, s16 angle, GAME* game, u16 item_name, s16 arg0, s16 arg1) { - // TODO +static void eFlash_init(xyz_t pos, int prio, s16 angle, GAME* game, u16 item_name, s16 arg0, s16 arg1) { + (*eEC_CLIP->make_effect_proc)(eEC_EFFECT_FLASH, pos, NULL, game, NULL, item_name, prio, arg0, angle); } -static void eFlashC_ct(eEC_Effect_c* effect, GAME* game, void* ct_arg) { - // TODO +static void eFlash_ct(eEC_Effect_c* effect, GAME* game, void* ct_arg) { + s16 flash_length = 3.0f + RANDOM_F(7.0f); + s16 end_frame = flash_length >> 1; + + if (effect->arg0 == 1) { + static rgba_t light_color = { 27, 27, 27, 255 }; + + (*eEC_CLIP->regist_effect_light)(light_color, flash_length, end_frame, TRUE); + } + + effect->timer = 5; + effect->acceleration.x = 0.3f + RANDOM_F(0.7f); } -static void eFlashC_mv(eEC_Effect_c* effect, GAME* game) { - // TODO +static void eFlash_mv(eEC_Effect_c* effect, GAME* game) { + s16 elapsed_time = 5 - effect->timer; + f32 scale; + + if (elapsed_time <= 4) { + scale = (*eEC_CLIP->calc_adjust_proc)(elapsed_time, 0, 2, effect->acceleration.x * 0.005f, 0.01f); + } else { + scale = (*eEC_CLIP->calc_adjust_proc)(elapsed_time, 3, 4, effect->acceleration.x * 0.01f, 0.0f); + } + + effect->scale.x = scale; + effect->scale.y = scale; + effect->scale.z = scale; } -static void eFlashC_dw(eEC_Effect_c* effect, GAME* game) { - // TODO +extern Gfx ef_takurami01_normal_render_mode[]; +extern Gfx ef_takurami01_kira_modelT[]; + +static void eFlash_dw(eEC_Effect_c* effect, GAME* game) { + GAME_PLAY* play = (GAME_PLAY*)game; + + Matrix_translate(effect->position.x, effect->position.y, effect->position.z, 0); + Matrix_mult(&play->billboard_matrix, 1); + Matrix_scale(effect->scale.x, effect->scale.y, effect->scale.z, 1); + _texture_z_light_fog_prim_xlu(game->graph); + + OPEN_DISP(game->graph); + + gSPMatrix(NEXT_POLY_XLU_DISP, _Matrix_to_Mtx_new(game->graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(NEXT_POLY_XLU_DISP, 0, 255, 255, 255, 255, 200); + gSPSegment(NEXT_POLY_XLU_DISP, G_MWO_SEGMENT_8, ef_takurami01_normal_render_mode); + gSPDisplayList(NEXT_POLY_XLU_DISP, ef_takurami01_kira_modelT); + + CLOSE_DISP(game->graph); } +static void eFlashC_init(xyz_t pos, int prio, s16 angle, GAME* game, u16 item_name, s16 arg0, s16 arg1); +static void eFlashC_ct(eEC_Effect_c* effect, GAME* game, void* ct_arg); +static void eFlashC_mv(eEC_Effect_c* effect, GAME* game); +static void eFlashC_dw(eEC_Effect_c* effect, GAME* game); + eEC_PROFILE_c iam_ef_flashC = { // clang-format off &eFlashC_init, @@ -55,3 +91,58 @@ eEC_PROFILE_c iam_ef_flashC = { eEC_IGNORE_DEATH_DIST, // clang-format on }; + +static void eFlashC_init(xyz_t pos, int prio, s16 angle, GAME* game, u16 item_name, s16 arg0, s16 arg1) { + (*eEC_CLIP->make_effect_proc)(eEC_EFFECT_FLASHC, pos, NULL, game, NULL, item_name, prio, arg0, angle); +} + +static void eFlashC_ct(eEC_Effect_c* effect, GAME* game, void* ct_arg) { + effect->timer = 240; + effect->effect_specific[0] = 0; +} + +static void eFlashC_mv(eEC_Effect_c* effect, GAME* game) { + if ((effect->timer & 7) == 0) { + int size; + + switch (Save_Get(scene_no)) { + case SCENE_MY_ROOM_S: + size = 4; + break; + case SCENE_NPC_HOUSE: + case SCENE_MY_ROOM_M: + case SCENE_MY_ROOM_LL2: + case SCENE_COTTAGE_NPC: + size = 6; + break; + case SCENE_MY_ROOM_L: + case SCENE_MY_ROOM_LL1: + case SCENE_MY_ROOM_BASEMENT_S: + case SCENE_MY_ROOM_BASEMENT_M: + case SCENE_MY_ROOM_BASEMENT_L: + case SCENE_MY_ROOM_BASEMENT_LL1: + case SCENE_COTTAGE_MY: + size = 8; + break; + default: + size = -1; + break; + } + + if (size != -1) { + xyz_t pos; + + pos.z = 43.0f; + pos.x = 40.0f + RANDOM_F(size) * 40.0f; + pos.y = -10.0f + RANDOM_F(20.0f) + 75.0f; + + (*eEC_CLIP->effect_make_proc)(eEC_EFFECT_FLASH, pos, effect->prio, 0, game, (u16)effect->item_name, + effect->effect_specific[0] & 1, 0); + effect->effect_specific[0]++; + } + } +} + +static void eFlashC_dw(eEC_Effect_c* effect, GAME* game) { + // nothing +}