mirror of
https://github.com/ACreTeam/ac-decomp
synced 2026-05-23 14:41:38 -04:00
252 lines
8.6 KiB
C
252 lines
8.6 KiB
C
static void eEL_InitUnchar(u8* unchar_p, int count, u8 val) {
|
|
int i;
|
|
|
|
for (i = 0; i < count; i++) {
|
|
*unchar_p++ = val;
|
|
}
|
|
}
|
|
|
|
static void eEL_VectorRoteteY(xyz_t* vec, f32 angle) {
|
|
xyz_t src = *vec;
|
|
f32 cos = cosf_table(angle);
|
|
f32 sin = sinf_table(angle);
|
|
|
|
vec->x = src.x * cos + src.z * sin;
|
|
vec->z = -src.x * sin + src.z * cos;
|
|
}
|
|
|
|
static s16 eEL_RandomFirstSpeed(xyz_t* speed, f32 y, f32 max_z, f32 max_x) {
|
|
xyz_t vec = { 0.0f, 1.0f, 0.0f };
|
|
f32 angle = 0.0f;
|
|
|
|
vec.y = y;
|
|
|
|
if (max_z != 0.0f) {
|
|
f32 rnd_z = RANDOM_F(max_z) - max_z * 0.5f;
|
|
|
|
angle = rnd_z;
|
|
sMath_RotateZ(&vec, DEG2RAD(rnd_z));
|
|
}
|
|
|
|
if (max_x != 0.0f) {
|
|
f32 rnd_x = RANDOM_F(max_x) - max_x * 0.5f;
|
|
sMath_RotateX(&vec, DEG2RAD(rnd_x));
|
|
}
|
|
|
|
if (speed != NULL) {
|
|
*speed = vec;
|
|
}
|
|
|
|
return RAD2SHORT_ANGLE2(DEG2RAD(angle));
|
|
}
|
|
|
|
static void eEL_SetContiniousEnv(eEC_Effect_c* effect, s16 unused, s16 timer) {
|
|
if (effect->state == eEC_STATE_NORMAL) {
|
|
if (effect->timer <= 1) {
|
|
effect->state = eEC_STATE_CONTINUOUS;
|
|
effect->timer = timer;
|
|
}
|
|
} else if (effect->state == eEC_STATE_CONTINUOUS) {
|
|
if (effect->timer <= 1) {
|
|
effect->state = eEC_STATE_CONTINUOUS;
|
|
effect->timer = timer;
|
|
}
|
|
}
|
|
}
|
|
|
|
static f32 eEL_CalcAdjust(s16 now, s16 start, s16 end, f32 start_val, f32 end_val) {
|
|
|
|
if (start == end) {
|
|
return start_val;
|
|
}
|
|
|
|
if (now <= start) {
|
|
return start_val;
|
|
}
|
|
|
|
if (now >= end) {
|
|
return end_val;
|
|
}
|
|
|
|
return start_val + (f32)(now - start) * ((end_val - start_val) / (f32)(end - start));
|
|
}
|
|
|
|
static void eEL_AutoMatrixXlu(GAME* game, xyz_t* pos, xyz_t* scale) {
|
|
GAME_PLAY* play = (GAME_PLAY*)game;
|
|
Mtx* mtx = (Mtx*)GRAPH_ALLOC_TYPE(game->graph, Mtx, 1);
|
|
f32 adj_scale;
|
|
|
|
OPEN_DISP(game->graph);
|
|
|
|
_texture_z_light_fog_prim_xlu(game->graph);
|
|
adj_scale = 1.0f + ((f32)(int)GETREG(MYKREG, 27)) * 0.01f;
|
|
suMtxMakeTS(mtx, scale->x * adj_scale, scale->y * adj_scale, scale->z * adj_scale, pos->x, pos->y, pos->z);
|
|
|
|
gSPMatrix(NEXT_POLY_XLU_DISP, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
|
gSPMatrix(NEXT_POLY_XLU_DISP, play->billboard_mtx_p, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_MODELVIEW);
|
|
|
|
CLOSE_DISP(game->graph);
|
|
}
|
|
|
|
static void eEL_AutoMatrixXlu_Offset(GAME* game, xyz_t* pos, xyz_t* scale, xyz_t* offset) {
|
|
GAME_PLAY* play = (GAME_PLAY*)game;
|
|
f32 adj_scale;
|
|
|
|
OPEN_DISP(game->graph);
|
|
|
|
_texture_z_light_fog_prim_xlu(game->graph);
|
|
Matrix_translate(pos->x, pos->y, pos->z, 0);
|
|
Matrix_mult(&play->billboard_matrix, 1);
|
|
Matrix_translate(offset->x + (f32)(int)GETREG(MYKREG, 24), offset->y + (f32)(int)GETREG(MYKREG, 25),
|
|
offset->z + (f32)(int)GETREG(MYKREG, 26), 1);
|
|
adj_scale = 1.0f + ((f32)(int)GETREG(MYKREG, 27)) * 0.01f;
|
|
Matrix_scale(scale->x * adj_scale, scale->y * adj_scale, scale->z * adj_scale, 1);
|
|
|
|
gSPMatrix(NEXT_POLY_XLU_DISP, _Matrix_to_Mtx_new(game->graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
|
|
|
CLOSE_DISP(game->graph);
|
|
}
|
|
|
|
static void eEC_MorphCombine(u8* const result, eEC_morph_data_c* const morph_data, s16 now_timer) {
|
|
int i;
|
|
|
|
for (i = 0; i < 9; i++) {
|
|
if (morph_data[i].morph_flag) {
|
|
result[i] = eEL_CalcAdjust(now_timer, morph_data[i].start_frame << 1, morph_data[i].end_frame << 1,
|
|
morph_data[i].start_val, morph_data[i].end_val);
|
|
} else {
|
|
result[i] = morph_data[i].start_val;
|
|
}
|
|
}
|
|
}
|
|
|
|
static int eEL_SpecialBlockCenterPos(xyz_t* pos, u32 block_kind) {
|
|
int bx;
|
|
int bz;
|
|
|
|
*pos = ZeroVec;
|
|
|
|
if (mFI_BlockKind2BkNum(&bx, &bz, block_kind) && mFI_BkNum2WposXZ(&pos->x, &pos->z, bx, bz)) {
|
|
pos->x += mFI_BK_WORLDSIZE_X_F / 2;
|
|
pos->z += mFI_BK_WORLDSIZE_Z_F / 2;
|
|
return TRUE;
|
|
} else {
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
static eEC_light_data_c eEL_light_data;
|
|
static const eEC_light_data_c eEC_light_default = { 0, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, 0, 0, 0, 0 };
|
|
|
|
static int eEL_EffectLightStatus(rgba_t* color, int* shadow_flag) {
|
|
color->r = eEC_ctrl_work.light_info.lights.diffuse.color[0];
|
|
color->g = eEC_ctrl_work.light_info.lights.diffuse.color[1];
|
|
color->b = eEC_ctrl_work.light_info.lights.diffuse.color[2];
|
|
color->a = 0;
|
|
|
|
*shadow_flag = eEL_light_data.shadow_flag;
|
|
return eEL_light_data.light_state;
|
|
}
|
|
|
|
static void eEL_InitEffectLight(void) {
|
|
eEL_light_data = eEC_light_default;
|
|
eEL_light_data.n_frames = 10;
|
|
}
|
|
|
|
static void eEL_CalcEffectLight_Set(GAME* game) {
|
|
int r;
|
|
int g;
|
|
int b;
|
|
|
|
if (eEL_light_data.ctr > eEL_light_data.n_frames) {
|
|
eEL_InitEffectLight();
|
|
eEC_ctrl_work.light_info.lights.diffuse.color[0] = 0;
|
|
eEC_ctrl_work.light_info.lights.diffuse.color[1] = 0;
|
|
eEC_ctrl_work.light_info.lights.diffuse.color[2] = 0;
|
|
eEL_light_data.light_state = eEC_LIGHT_COLOR_DISABLED;
|
|
} else {
|
|
if (eEL_light_data.ctr < eEL_light_data.max_frame) {
|
|
r = (int)eEC_CLIP->calc_adjust_proc(eEL_light_data.ctr, 0, eEL_light_data.max_frame,
|
|
eEL_light_data.start_color.r, eEL_light_data.target_color.r);
|
|
g = (int)eEC_CLIP->calc_adjust_proc(eEL_light_data.ctr, 0, eEL_light_data.max_frame,
|
|
eEL_light_data.start_color.g, eEL_light_data.target_color.g);
|
|
b = (int)eEC_CLIP->calc_adjust_proc(eEL_light_data.ctr, 0, eEL_light_data.max_frame,
|
|
eEL_light_data.start_color.b, eEL_light_data.target_color.b);
|
|
|
|
eEL_light_data.light_state = eEC_LIGHT_COLOR_INCREASING;
|
|
} else {
|
|
r = (int)eEC_CLIP->calc_adjust_proc(eEL_light_data.ctr, eEL_light_data.max_frame, eEL_light_data.n_frames,
|
|
eEL_light_data.target_color.r, 0.0f);
|
|
g = (int)eEC_CLIP->calc_adjust_proc(eEL_light_data.ctr, eEL_light_data.max_frame, eEL_light_data.n_frames,
|
|
eEL_light_data.target_color.g, 0.0f);
|
|
b = (int)eEC_CLIP->calc_adjust_proc(eEL_light_data.ctr, eEL_light_data.max_frame, eEL_light_data.n_frames,
|
|
eEL_light_data.target_color.b, 0.0f);
|
|
|
|
if (eEL_light_data.ctr == eEL_light_data.max_frame) {
|
|
eEL_light_data.light_state = eEC_LIGHT_COLOR_MAXIMUM;
|
|
} else {
|
|
eEL_light_data.light_state = eEC_LIGHT_COLOR_DECREASING;
|
|
}
|
|
}
|
|
|
|
eEC_ctrl_work.light_info.lights.diffuse.color[0] = r;
|
|
eEC_ctrl_work.light_info.lights.diffuse.color[1] = g;
|
|
eEC_ctrl_work.light_info.lights.diffuse.color[2] = b;
|
|
eEL_light_data.ctr++;
|
|
}
|
|
}
|
|
|
|
static void eEL_RegistEffectLight(rgba_t color, s16 max_frames, s16 n_frames, int shadow_flag) {
|
|
eEL_light_data.start_color.r = eEC_ctrl_work.light_info.lights.diffuse.color[0];
|
|
eEL_light_data.start_color.g = eEC_ctrl_work.light_info.lights.diffuse.color[1];
|
|
eEL_light_data.start_color.b = eEC_ctrl_work.light_info.lights.diffuse.color[2];
|
|
|
|
eEL_light_data.ctr = 0;
|
|
eEL_light_data.target_color = color;
|
|
eEL_light_data.max_frame = max_frames;
|
|
eEL_light_data.n_frames = n_frames;
|
|
eEL_light_data.shadow_flag = shadow_flag;
|
|
}
|
|
|
|
static void eEL_DecideLightPower(rgba_t* result_color, rgba_t base_color, xyz_t pos, GAME* game, f32 max_power,
|
|
f32 min_power, f32 max_dist) {
|
|
GAME_PLAY* play = (GAME_PLAY*)game;
|
|
PLAYER_ACTOR* player = GET_PLAYER_ACTOR(play);
|
|
|
|
if (player != NULL) {
|
|
xyz_t player_pos = player->actor_class.world.position;
|
|
f32 dist = search_position_distance(&pos, &player_pos);
|
|
f32 power;
|
|
|
|
if (dist > max_dist) {
|
|
power = min_power;
|
|
} else {
|
|
power = (max_power - min_power) * (1.0f - dist / max_dist);
|
|
power += min_power;
|
|
}
|
|
|
|
result_color->r = (int)(base_color.r * power);
|
|
result_color->g = (int)(base_color.g * power);
|
|
result_color->b = (int)(base_color.b * power);
|
|
result_color->a = 255;
|
|
} else {
|
|
*result_color = base_color;
|
|
}
|
|
}
|
|
|
|
static int mEL_CheckLookAtBlock(xyz_t pos) {
|
|
xyz_t* lookat = Camera2_getCenterPos_p();
|
|
int effect_bx;
|
|
int effect_bz;
|
|
int lookat_bx;
|
|
int lookat_bz;
|
|
|
|
if (mFI_Wpos2BlockNum(&effect_bx, &effect_bz, pos) && mFI_Wpos2BlockNum(&lookat_bx, &lookat_bz, *lookat)) {
|
|
if (effect_bx == lookat_bx && effect_bz == lookat_bz) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|