diff --git a/config/rel_slices.yml b/config/rel_slices.yml index af405dea..3e3c8b00 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -389,6 +389,10 @@ ef_lamp_light.c: .text: [0x804CEC5C, 0x804CEF2C] .rodata: [0x806463C8, 0x806463D8] .data: [0x8069BFD0, 0x8069C028] +ef_room_sunshine.c: + .text: [0x804CEF2C, 0x804CF784] + .rodata: [0x806463D8, 0x80646420] + .data: [0x8069C028, 0x8069C050] m_huusui_room_ovl.c: .text: [0x804D1BBC, 0x804D2164] .rodata: [0x80646558, 0x806465C8] diff --git a/include/ef_room_sunshine.h b/include/ef_room_sunshine.h index d28c0841..21d5ea54 100644 --- a/include/ef_room_sunshine.h +++ b/include/ef_room_sunshine.h @@ -10,6 +10,11 @@ extern "C" { extern ACTOR_PROFILE Room_Sunshine_Profile; +typedef struct effect_room_sunshine_s{ + ACTOR actor_class; + u8 unk_174; +} ROOMSUNSHINE_ACTOR; + #ifdef __cplusplus } #endif diff --git a/include/m_actor.h b/include/m_actor.h index 4bc10994..4a9f1ded 100644 --- a/include/m_actor.h +++ b/include/m_actor.h @@ -33,6 +33,7 @@ typedef void (*mActor_proc)(ACTOR*, GAME*); #define ACTOR_OBJ_BANK_NONE 0 #define ACTOR_OBJ_BANK_3 3 /* TODO: rename, also likely an enum */ +#define ACTOR_OBJ_BANK_5 5 #define ACTOR_OBJ_BANK_6 6 #define ACTOR_OBJ_BANK_7 7 #define ACTOR_OBJ_BANK_10 10 diff --git a/include/m_collision_bg.h b/include/m_collision_bg.h index 5aef2ba8..c89a8982 100644 --- a/include/m_collision_bg.h +++ b/include/m_collision_bg.h @@ -154,6 +154,7 @@ extern f32 mCoBG_GetBgY_AngleS_FromWpos(s_xyz* angle_to_ground, xyz_t wpos, f32 extern f32 mCoBG_GetShadowBgY_AngleS_FromWpos(f32, s_xyz*, xyz_t); extern int mCoBG_CheckWaterAttribute_OutOfSea(u32 attribute); extern int mCoBG_CheckHole_OrgAttr(u32 attribute); +extern f32 mCoBG_GetBgY_OnlyCenter_FromWpos(f32 dist, xyz_t* wpos); extern f32 mCoBG_GetBgY_OnlyCenter_FromWpos2(xyz_t wpos, f32 foot_dist); extern int mCoBG_Attribute2CheckPlant(u32 attribute, const xyz_t* wpos); extern void mCoBG_BgCheckControll(xyz_t* reverse_pos, ACTOR* actor, f32 check_range, f32 offset_y, s16 wall_attr_check, s16 no_reverse, s16 check_type); diff --git a/include/m_kankyo.h b/include/m_kankyo.h index 2f0b73ab..9f45d609 100644 --- a/include/m_kankyo.h +++ b/include/m_kankyo.h @@ -31,6 +31,30 @@ enum weather_intensity { #define mEnv_SAVE_GET_WEATHER_TYPE(w) (((w) & 0xF0) >> 4) #define mEnv_SAVE_GET_WEATHER_INTENSITY(w) ((w) & 0xF) +typedef struct base_light_s { + u8 ambient_color[3]; + s8 sun_dir[3]; + u8 sun_color[3]; + s8 moon_dir[3]; + u8 moon_color[3]; + u8 fog_color[3]; + s16 fog_near; + s16 fog_far; + u8 shadow_color[3]; + u8 room_color[3]; + u8 sun_color_window[3]; + u8 moon_color_window[3]; + u8 background_color[3]; +} BaseLight; + +typedef struct add_light_info_s { + s16 ambient_color[3]; + s16 diffuse_color[3]; + s16 fog_color[3]; + s16 fog_near; + s16 fog_far; +} AddLightInfo; + typedef void (*NATURE_PROC)(ACTOR*); typedef struct nature_s { @@ -38,16 +62,19 @@ typedef struct nature_s { void* arg; } Nature; - typedef struct kankyo_s { /* 0x00 */ Lights sun_light; - /* 0x0E */ u8 pad[0x1C - 0x0E]; - /* 0x1C */ Lights* lights_p; - /* 0x20 */ u8 pad3[0x9A - 0x20]; - /* 0x9A */ u8 ambientColor[3]; - /* 0x9E */ u8 pad2[0xC0 - 0x9E]; - /* 0xC0 */ f32 unkC0; - /* 0xC4 */ u8 unkC4; + /* 0x0E */ Lights moon_light; + /* 0x1C */ Lights* lamp_light; + /* 0x20 */ Lights point_light; + /* 0x2E */ u8 _2E[0x78 - 0x2e]; + /* 0x78 */ AddLightInfo add_light_info; /* extra values added to specific light parameters */ + /* 0x90 */ int _90; + /* 0x94 */ BaseLight base_light; + /* 0xBA */ u8 _BA[0xC0 - 0xBA]; + /* 0xC0 */ f32 shadow_pos; + /* 0xC4 */ u8 shadow_alpha; + /* 0xC5 */ u8 countdown_timer; /* 0xC8 */ Nature nature; } Kankyo; @@ -57,6 +84,7 @@ extern int mEnv_WindMove(); extern void mEnv_ManagePointLight(GAME_PLAY*, Kankyo*, Global_light*); extern void Global_kankyo_set(GAME_PLAY*, Kankyo*, Global_light*); extern void mEnv_GetShadowPrimColor_Light(u8*,u8*,u8*,GAME*); +extern f32 mKK_windowlight_alpha_get(); #ifdef __cplusplus } #endif diff --git a/rel/ac_train_window.c b/rel/ac_train_window.c index eafc637b..15891415 100644 --- a/rel/ac_train_window.c +++ b/rel/ac_train_window.c @@ -505,7 +505,7 @@ static void aTrainWindow_SetLightPrimColorDetail(GAME* game, u32 r, u32 g, u32 b GRAPH* graph; for(i = 0; i < 3; i++){ - current_color = play->global_light.ambientColor[i] + play->kankyo.ambientColor[i]; + current_color = play->global_light.ambientColor[i] + play->kankyo.base_light.sun_color[i]; switch(i){ case 0: current_color += r; diff --git a/rel/ef_lamp_light.c b/rel/ef_lamp_light.c index c8d7bd20..82563a4a 100644 --- a/rel/ef_lamp_light.c +++ b/rel/ef_lamp_light.c @@ -26,7 +26,7 @@ ACTOR_PROFILE Lamp_Light_Profile = { static void Ef_Lamp_Light_actor_ct(ACTOR* actor, GAME_PLAY* play) { LAMPLIGHT_ACTOR* lamp = (LAMPLIGHT_ACTOR*)actor; - play->kankyo.lights_p = &lamp->lights; + play->kankyo.lamp_light = &lamp->lights; Light_diffuse_ct(&lamp->lights, 0, 0x50, 0, 0, 0, 0); lamp->node_p = Global_light_list_new(play, &play->global_light, &lamp->lights); } @@ -34,7 +34,7 @@ static void Ef_Lamp_Light_actor_ct(ACTOR* actor, GAME_PLAY* play) { static void Ef_Lamp_Light_actor_dt(ACTOR* actor, GAME_PLAY* play) { LAMPLIGHT_ACTOR* lamp = (LAMPLIGHT_ACTOR*)actor; - play->kankyo.lights_p = NULL; + play->kankyo.lamp_light = NULL; Global_light_list_delete(&play->global_light, lamp->node_p); } diff --git a/rel/ef_room_sunshine.c b/rel/ef_room_sunshine.c new file mode 100644 index 00000000..49bebaf9 --- /dev/null +++ b/rel/ef_room_sunshine.c @@ -0,0 +1,216 @@ +#include "ef_room_sunshine.h" + +#include "m_common_data.h" +#include "m_name_table.h" +#include "m_debug.h" +#include "m_collision_bg.h" +#include "sys_matrix.h" + +void Ef_Room_Sunshine_actor_ct(ACTOR* actor, GAME* play); +void Ef_Room_SunshineL_actor_move(ACTOR* actor, GAME* play); +void Ef_Room_SunshineL_actor_draw(ACTOR* actor, GAME* play); +void Ef_Room_SunshineR_actor_move(ACTOR* actor, GAME* play); +void Ef_Room_SunshineR_actor_draw(ACTOR* actor, GAME* play); + +extern Gfx light_floor01_mode[]; +extern Vtx light_floorL01_vtx[]; +extern Vtx light_floorR01_vtx[]; +extern Gfx light_shine01_mode[]; +extern Vtx light_shineL01_vtx[]; +extern Vtx light_shineR01_vtx[]; + +ACTOR_PROFILE Room_Sunshine_Profile = { + mAc_PROFILE_ROOM_SUNSHINE, + ACTOR_PART_EFFECT, + ACTOR_STATE_NO_MOVE_WHILE_CULLED | ACTOR_STATE_NO_DRAW_WHILE_CULLED, + EMPTY_NO, + ACTOR_OBJ_BANK_5, + sizeof(ROOMSUNSHINE_ACTOR), + Ef_Room_Sunshine_actor_ct, + NONE_ACTOR_PROC, + Ef_Room_SunshineR_actor_move, + Ef_Room_SunshineR_actor_draw, + NULL, +}; + +void Ef_Room_Sunshine_actor_ct(ACTOR* actor, GAME* game){ + ROOMSUNSHINE_ACTOR* sunshine = (ROOMSUNSHINE_ACTOR*)actor; + xyz_t pos; + xyz_t pos2; + xyz_t pos3; + + sunshine->unk_174 = 0; + + if(sunshine->actor_class.actor_specific == 0){ + sunshine->actor_class.mv_proc = Ef_Room_SunshineL_actor_move; + sunshine->actor_class.dw_proc = Ef_Room_SunshineL_actor_draw; + } + else{ + sunshine->actor_class.world.position.x -= 1.0f; + } + + pos = sunshine->actor_class.world.position; + + sunshine->actor_class.world.position.y = mCoBG_GetBgY_OnlyCenter_FromWpos(0.0f, &pos); + + sunshine->actor_class.scale.x = 1.0f; + sunshine->actor_class.scale.y = 1.0f; + sunshine->actor_class.scale.z = 1.0f; + + switch(sunshine->actor_class.actor_specific){ + + case 2: + + sunshine->actor_class.mv_proc = Ef_Room_SunshineL_actor_move; + sunshine->actor_class.dw_proc = Ef_Room_SunshineL_actor_draw; + sunshine->actor_class.world.position.x += 5.0f; + pos2 = sunshine->actor_class.world.position; + sunshine->actor_class.world.position.y = 1.0f + mCoBG_GetBgY_OnlyCenter_FromWpos(0.0f, &pos2); + sunshine->actor_class.world.position.x -= 6.0f; + break; + + case 3: + sunshine->actor_class.world.position.x -= 5.0f; + pos3 = sunshine->actor_class.world.position; + sunshine->actor_class.world.position.y = 1.0f + mCoBG_GetBgY_OnlyCenter_FromWpos(0.0f, &pos3); + sunshine->actor_class.world.position.x += 6.0f; + break; + } +} + + +f32 calc_scale_Ef_Room_Sunshine(int flag, int sec){ + + if(flag == 0){ + return 1.5f * sin_s((sec << 14) / 28800.0f); + } + else{ + return 1.5f * sin_s((sec << 14) / 14400.0f); + } +} + +int calc_alpha_Ef_Room_Sunshine(){ + f32 ret; + int sec; + + if(Common_Get(time.now_sec) < 14400){ + ret = (120.0f + GETREG(TAKREG,30)) * ((14400 - Common_Get(time.now_sec)) / 14400.0f); + } + else if(Common_Get(time.now_sec) < 72000){ + sec = (Common_Get(time.now_sec) - 43200) >= 0 ? + (Common_Get(time.now_sec) - 43200U) : -(Common_Get(time.now_sec) - 43200U); + + ret = 255.0f * ((28800 - sec) / 28800.0f); + } + else{ + ret = (120.0f + GETREG(TAKREG,30)) * ((14400 - (86400 - Common_Get(time.now_sec))) / 14400.0f); + } + + if((Common_Get(weather) == 1) || (Common_Get(weather) == 2)){ + ret *= 0.6f; + } + + return (u8)ret; +} + +void Ef_Room_SunshineL_actor_move(ACTOR* actor, GAME* game){ + ROOMSUNSHINE_ACTOR* sunshine = (ROOMSUNSHINE_ACTOR*)actor; + + if(Common_Get(time.now_sec) < 14400){ + sunshine->actor_class.scale.x = calc_scale_Ef_Room_Sunshine(1, Common_Get(time.now_sec)); + } + else if ((Common_Get(time.now_sec) >= 43200) && (Common_Get(time.now_sec) < 72000)){ + sunshine->actor_class.scale.x = calc_scale_Ef_Room_Sunshine(0, Common_Get(time.now_sec) - 43200); + } + else{ + sunshine->actor_class.scale.x = 0.0f; + } +} + +void Ef_Room_SunshineR_actor_move(ACTOR* actor, GAME* game){ + ROOMSUNSHINE_ACTOR* sunshine = (ROOMSUNSHINE_ACTOR*)actor; + + if((Common_Get(time.now_sec) >= 14400) && (Common_Get(time.now_sec) < 43200)){ + sunshine->actor_class.scale.x = calc_scale_Ef_Room_Sunshine(0, 43200 - Common_Get(time.now_sec)); + } + else if (Common_Get(time.now_sec) >= 72000){ + sunshine->actor_class.scale.x = calc_scale_Ef_Room_Sunshine(1, 86400 -Common_Get(time.now_sec)); + } + else{ + sunshine->actor_class.scale.x = 0.0f; + } +} + +void setup_mode_Ef_Room_Sunshine(ACTOR* actor, GAME_PLAY* play){ + ROOMSUNSHINE_ACTOR* sunshine = (ROOMSUNSHINE_ACTOR*)actor; + u8* color; + f32 alpha; + + GRAPH* graph = play->game.graph; + + OPEN_DISP(graph); + + Matrix_translate(sunshine->actor_class.world.position.x, 0.1f +sunshine->actor_class.world.position.y, + sunshine->actor_class.world.position.z, 0); + Matrix_scale(sunshine->actor_class.scale.x, sunshine->actor_class.scale.y, sunshine->actor_class.scale.z,1); + + gDPPipeSync(NEXT_POLY_XLU_DISP); + + gSPMatrix(NEXT_POLY_XLU_DISP, _Matrix_to_Mtx_new(play->game.graph), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + if((Common_Get(time.now_sec) >= 14400) && (Common_Get(time.now_sec) < 72000)){ + color =play->kankyo.base_light.sun_color_window; + } + else{ + color =play->kankyo.base_light.moon_color_window; + } + + alpha = (u8)calc_alpha_Ef_Room_Sunshine() * mKK_windowlight_alpha_get(); + + gDPSetPrimColor(NEXT_POLY_XLU_DISP, 0,0, color[0], color[1], color[2], (int)(alpha)); + CLOSE_DISP(graph); + +} + +void Ef_Room_SunshineL_actor_draw(ACTOR* actor, GAME* game){ + GAME_PLAY* play = (GAME_PLAY*)game; + + GRAPH* graph; + + if((mKK_windowlight_alpha_get() < 9.99999974738e-05f) || (actor->scale.x == 0.0f)){ + return; + } + graph = play->game.graph; + setup_mode_Ef_Room_Sunshine(actor, play); + + OPEN_DISP(graph); + + gSPDisplayList(NEXT_POLY_XLU_DISP, light_floor01_mode); + gSPDisplayList(NEXT_POLY_XLU_DISP, light_floorL01_vtx); + gSPDisplayList(NEXT_POLY_XLU_DISP, light_shine01_mode); + gSPDisplayList(NEXT_POLY_XLU_DISP, light_shineL01_vtx); + + CLOSE_DISP(graph); +} + + +void Ef_Room_SunshineR_actor_draw(ACTOR* actor, GAME* game){ + GAME_PLAY* play = (GAME_PLAY*)game; + + GRAPH* graph; + + if((mKK_windowlight_alpha_get() < 9.99999974738e-05f) || (actor->scale.x == 0.0f)){ + return; + } + graph = play->game.graph; + setup_mode_Ef_Room_Sunshine(actor, play); + + OPEN_DISP(graph); + + gSPDisplayList(NEXT_POLY_XLU_DISP, light_floor01_mode); + gSPDisplayList(NEXT_POLY_XLU_DISP, light_floorR01_vtx); + gSPDisplayList(NEXT_POLY_XLU_DISP, light_shine01_mode); + gSPDisplayList(NEXT_POLY_XLU_DISP, light_shineR01_vtx); + + CLOSE_DISP(graph); +} \ No newline at end of file diff --git a/rel/m_actor_shadow.c b/rel/m_actor_shadow.c index c2e118bd..0a955160 100644 --- a/rel/m_actor_shadow.c +++ b/rel/m_actor_shadow.c @@ -54,7 +54,7 @@ void mActorShadow_AdjustRate(f32* rate) { void mActorShadow_GetTimeAngleY_TimeAlpha(Shadow_Info* shadow, GAME_PLAY* play){ f32 timef; int timesec = Common_Get(time.now_sec); - shadow->unk1C = play->kankyo.unkC4; + shadow->unk1C = play->kankyo.shadow_alpha; // Between 4 a.m and 8 p.m if((timesec >= 14400) && ( timesec < 72000)){