diff --git a/common.py b/common.py index 1803ac9c..178d8457 100644 --- a/common.py +++ b/common.py @@ -327,7 +327,7 @@ COMMON_DEFINES = [ ] DOL_DEFINES = COMMON_DEFINES + [] REL_DEFINES = COMMON_DEFINES + [ - "-d OPTIMIZED_SQRTF", + #"-d OPTIMIZED_SQRTF", "-d IS_REL" ] BASE_DOL_CFLAGS = CFLAGS + [ diff --git a/config/rel_slices.yml b/config/rel_slices.yml index 75da17f7..8e3c4236 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -122,6 +122,11 @@ m_kabu_manager.c: .text: [0x803B5CC4, 0x803B6280] .rodata: [0x80642480, 0x806424C0] .data: [0x80655D48, 0x80655D78] +m_kankyo.c: + .text: [0x803B6280, 0x803BAB0C] + .rodata: [0x806424C0, 0x80642640] + .data: [0x80655D78, 0x80656670] + .bss: [0x81297A68, 0x81297B18] m_lights.c: .text: [0x803BB960, 0x803BC510] .rodata: [0x80642680, 0x806426D8] diff --git a/include/ac_weather.h b/include/ac_weather.h index a11c2d61..940aa82b 100644 --- a/include/ac_weather.h +++ b/include/ac_weather.h @@ -8,6 +8,8 @@ extern "C" { #endif +extern int aWeather_ChangingWeather(); + extern ACTOR_PROFILE Weather_Profile; #ifdef __cplusplus diff --git a/include/ef_effect_control.h b/include/ef_effect_control.h index e9d3d153..1edd904f 100644 --- a/include/ef_effect_control.h +++ b/include/ef_effect_control.h @@ -19,11 +19,25 @@ enum effect_type { eEC_EFFECT_NUM = 126 }; +enum { + eEC_LIGHT_COLOR_DISABLED, + eEC_LIGHT_COLOR_INCREASING, + eEC_LIGHT_COLOR_MAXIMUM, + eEC_LIGHT_COLOR_DECREASING, + + eEC_LIGHT_COLOR_NUM +}; + typedef void (*eEC_NAME2EFFECTMAKE_PROC)(int, xyz_t, int, short, GAME*, u16, s16, s16); +typedef int (*eEC_EFFECTLIGHTSTATUS_PROC)(rgba_t*, int*); // returns eEC_LIGHT_COLOR_* + typedef struct effect_control_clip_s { - eEC_NAME2EFFECTMAKE_PROC effect_make_proc; - /* TODO: finish */ + /* 0x00 */ eEC_NAME2EFFECTMAKE_PROC effect_make_proc; + /* 0x04 */ u8 _04[0x3C - 0x04]; + /* 0x3C */ eEC_EFFECTLIGHTSTATUS_PROC effect_light_status; + /* 0x40 */ void* _40; + /* 0x44 */ void* _44; } eEC_EffectControl_Clip_c; typedef struct effect_control_s EFFECT_CONTROL_ACTOR; diff --git a/include/m_actor.h b/include/m_actor.h index 4bc10994..10f81920 100644 --- a/include/m_actor.h +++ b/include/m_actor.h @@ -307,6 +307,13 @@ enum actor_profile_table { mAc_PROFILE_NUM }; +enum { + mAc_HILITE_OPAQUE, + mAc_HILITE_TRANSLUCENT, + + mAc_HILITE_NUM +}; + /* sizeof(ACTOR_PROFILE) == 0x24 */ struct actor_profile_s { /* 0x00 */ s16 id; /* unique actor type ID */ diff --git a/include/m_common_data.h b/include/m_common_data.h index 0c03f3a8..b971b93c 100644 --- a/include/m_common_data.h +++ b/include/m_common_data.h @@ -151,7 +151,11 @@ typedef struct Save_s { /* 0x024177 */ u8 gyoei_term_transition_offset; /* days offset from end of term to begin transition */ /* 0x024178 */ mFAs_GoodField_c good_field; /* field assessment last info */ /* 0x024184 */ u8 bg_tex_idx; /* Grass type */ - /* 0x024185 */ u8 _24185[0x2418A - 0x24185]; + /* 0x024185 */ lbRTC_month_t rainbow_month; + /* 0x024186 */ lbRTC_day_t rainbow_day; + /* 0x024187 */ u8 rainbow_reserved; + /* 0x024188 */ u8 _24188; + /* 0x024189 */ u8 _24189; /* 0x02418A */ u8 town_day; /* 0x02418B */ u8 _2418B[0x241A0 - 0x2418B]; /* 0x0241A0 */ lbRTC_time_c saved_auto_nwrite_time; /* save data notice time used for fishing tourney results? */ @@ -163,6 +167,13 @@ typedef union save_u { //u8 raw[0x26000]; /* Temp to force length */ } Save; +typedef struct transition_s { + u8 _00; // only set in Global_kankyo_ct? + u8 fade_rate; + u8 wipe_rate; + u8 wipe_type; +} Transition_c; + /* sizeof(common_data_t) == 0x2DC00 */ typedef struct common_data_s { /* 0x000000 */ Save save; @@ -178,10 +189,10 @@ typedef struct common_data_s { /* 0x026140 */ mHm_hs_c* now_home; /* 0x026144 */ u8 map_flag; /* 0x026145 */ u8 fish_location; - /* 0x026146 */ u8 tmp0[0x2614D - 0x26146]; - /* 0x02614D */ u8 transFadeDuration; - /* 0x02614E */ u8 transWipeSpeed; - /* 0x02614F */ u8 wipeType; /* maybe unused? */ + /* 0x026146 */ u8 npc_is_summercamper; + /* 0x026147 */ u8 player_select_animal_no; + /* 0x026148 */ u8 _26148[0x2614C - 0x26148]; + /* 0x02614C */ Transition_c transition; /* 0x026150 */ s16 bg_item_type; /* 0x026152 */ s16 bg_item_profile; /* 0x026154 */ u8 _26154[0x26164 - 0x26154]; @@ -273,7 +284,10 @@ typedef struct common_data_s { /* 0x02DB40 */ u8 auto_nwrite_set; /* when true, saved nwrite time will be utilized. Seems to be used to keep same date for fishing tourney stuff. */ /* 0x02DB42 */ u16 select_last_select_no; /* 0x02DB44 */ u16 select_last_top_no; - /* 0x02DB46 */ u8 tmp3[0x2DBAC - 0x2DB46]; + /* 0x02DB46 */ u8 _2DB46[0x2DBA2 - 0x2DB46]; + /* 0x02DBA2 */ s16 island_weather; + /* 0x02DBA4 */ s16 island_weather_intensity; + /* 0x02DBA6 */ u8 _2DBA6[0x2DBAC - 0x2DBA6]; /* 0X02DBAC */ int famicom_2DBAC; /* 0x02DBB0 */ s16 can_look_goki_count; /* 0x02DBB4 */ f32 rainbow_opacity; /* current opacity of rainbow (0.0f - 1.0f) */ diff --git a/include/m_event.h b/include/m_event.h index f91ec0b9..87bab987 100644 --- a/include/m_event.h +++ b/include/m_event.h @@ -496,6 +496,9 @@ extern void mEv_EventON(u32 event_kind); extern int mEv_CheckGateway(); extern int mEv_check_schedule(int event); extern mEv_place_data_c* mEv_get_common_place(int type, s8 id); +extern void mEv_set_status(int event, s16 status); +extern void mEv_GetEventWeather(s16* weather, s16* intensity); +extern int mEv_CheckRealArbeit(); extern int mEv_weekday2day(lbRTC_month_t month, int week_type, lbRTC_weekday_t weekday); extern void mEv_ClearEventInfo(); diff --git a/include/m_kankyo.h b/include/m_kankyo.h index 76b8bf70..d901ed11 100644 --- a/include/m_kankyo.h +++ b/include/m_kankyo.h @@ -3,12 +3,27 @@ #include "types.h" #include "m_lights.h" -#include "game.h" +#include "m_play_h.h" #ifdef __cplusplus extern "C" { #endif +#define mEnv_POINT_LIGHT_NUM 4 +#define mEnv_RAINBOW_TIME_START (9 * mTM_SECONDS_IN_HOUR) +#define mEnv_RAINBOW_TIME_END (15 * mTM_SECONDS_IN_HOUR) +#define mEnv_RAINBOW_TIME_BYE (15 * mTM_SECONDS_IN_HOUR + 30 * mTM_SECONDS_IN_MINUTE) +#define mEnv_TERM_NUM 8 +#define mEnv_FOG_NEAR_MAX 996 +#define mEnv_FOG_FAR_MAX 1600 +#define mEnv_LIGHT_ANIME_FRAMES 20 +#define mEnv_NPC_LIGHTS_OFF_TIME (5 * mTM_SECONDS_IN_HOUR) +#define mEnv_NPC_LIGHTS_ON_TIME (18 * mTM_SECONDS_IN_HOUR) + +#define mEnv_WEATHER_TERM_NUM 20 +#define mEnv_WIND_TERM_NUM 4u +#define mEnv_WIND_CHANGE_RATE (f32)(10*mTM_SECONDS_IN_MINUTE*60) // 60fps, 10 minutes + enum weather { mEnv_WEATHER_CLEAR, mEnv_WEATHER_RAIN, @@ -28,9 +43,59 @@ enum weather_intensity { mEnv_WEATHER_INTENSITY_NUM, }; +enum { + mEnv_LIGHT_TYPE_PLAYER, + mEnv_LIGHT_TYPE_TENT, + mEnv_LIGHT_TYPE_LIGHTHOUSE, + + mEnv_LIGHT_TYPE_NUM +}; + +enum { + mEnv_SWITCH_STATUS_ON, + mEnv_SWITCH_STATUS_OFF, + mEnv_SWITCH_STATUS_TURNING_OFF, + mEnv_SWITCH_STATUS_TURNING_ON, + + mEnv_SWITCH_STATUS_NUM +}; + +enum { + mEnv_WIND_STATE_STEADY, + mEnv_WIND_STATE_FAST, + mEnv_WIND_STATE_SLOW, + mEnv_WIND_STATE_REDUCING, + + mEnv_WIND_STATE_NUM +}; + #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 { @@ -40,20 +105,59 @@ typedef struct nature_s { typedef struct kankyo_s { /* 0x00 */ Lights sun_light; - /* 0x0E */ u8 pad[0x9A - 0x0E]; - /* 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; + /* 0x30 */ int _30; + /* 0x34 */ u8 _34[0x78 - 0x34]; + /* 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; -extern void Global_kankyo_ct(GAME_PLAY*, Kankyo*); +extern void mEnv_regist_nature(Kankyo* kankyo, NATURE_PROC nature_proc, void* arg); +extern int mEnv_unregist_nature(Kankyo* kankyo, NATURE_PROC nature_proc); +extern void Global_kankyo_ct(GAME_PLAY* play, Kankyo* kankyo); +extern void mEnv_GetRoomPrimColor(u8* r, u8* g, u8* b, GAME_PLAY* play); +extern void Global_kankyo_set_room_prim(GAME_PLAY* play); +extern int mEnv_RequestChangeLightON(GAME_PLAY* play, int light_on_type, int play_sfx); +extern int mEnv_RequestChangeLightOFF(GAME_PLAY* play, int light_off_type, f32 step); +extern void mEnv_ManagePointLight(GAME_PLAY* play, Kankyo* kankyo, Global_light* global_light); +extern void Global_kankyo_set(GAME_PLAY* play, Kankyo* kankyo, Global_light* global_light); +extern void staffroll_light_init(GAME_PLAY* play); +extern void staffroll_light_proc_start(GAME_PLAY* play); +extern int staffroll_light_proc_end(GAME_PLAY* play); +extern void staffroll_light_dt(GAME_PLAY* play); +extern void mEnv_GetShadowPrimColor_Light(u8* r, u8* g, u8* b, GAME* game); +extern int mEnv_PointLightMin(); +extern int mEnv_HereIsPlayerSelect(); +extern f32 mKK_windowlight_alpha_get(); +extern int mEnv_ReqeustChangeWeatherEnviroment(s16 now_weather, s16 next_weather); +extern int mEnv_ReservePointLight(GAME_PLAY* play, xyz_t* pos, u8 r, u8 g, u8 b, s16 power); +extern void mEnv_OperateReservedPointLight_Position(int point_light_idx, xyz_t* pos); +extern void mEnv_OperateReservedPointLight_Color(int point_light_idx, u8 r, u8 g, u8 b); +extern void mEnv_OperateReservedPointLight_Power(int point_light_idx, s16 power); +extern void mEnv_OperateReservedPointLight(int point_light_idx, xyz_t* pos, u8 r, u8 g, u8 b, s16 power); +extern int mEnv_CancelReservedPointLight(int point_light_idx, GAME_PLAY* play); +extern void mEnv_DecideWindDirect(s_xyz* dir, s16 x, s16 z); +extern void mEnv_RandomWeather(s16* next_weather, s16* next_intensity); +extern s16 mEnv_GetWindAngleS(); +extern f32 mEnv_GetWindPowerF(); +extern f32 mEnv_GetWindPowerF_Windmill(); +extern void mEnv_DecideTodayWindPowerRange(); +extern void mEnv_ChangeWind(); +extern void mEnv_WindMove(); +extern void mEnv_DecideWeather_GameStart(); +extern void mEnv_DecideWeather_FirstGameStart(); +extern void mEnv_PreRainNowFine_Init(); +extern void mEnv_DecideWeather_NormalGameStart(); extern int mEnv_NowWeather(); -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*); + #ifdef __cplusplus } #endif diff --git a/include/m_lights.h b/include/m_lights.h index dfcf50bf..98d2d20c 100644 --- a/include/m_lights.h +++ b/include/m_lights.h @@ -37,27 +37,26 @@ typedef struct lights_s { } Lights; -typedef struct LightNode { +typedef struct light_list { /* 0x0 */ Lights* info; - /* 0x4 */ struct LightNode* prev; - /* 0x8 */ struct LightNode* next; -} LightNode; // size = 0xC + /* 0x4 */ struct light_list* prev; + /* 0x8 */ struct light_list* next; +} Light_list; // size = 0xC typedef struct light_buf_s{ int current; int idx; - LightNode lights[32]; -}Light_buffer; - + Light_list lights[32]; +} Light_buffer; typedef struct lightsn_s{ u8 diffuse_count; Ambient a; Light_new l[7]; -}LightsN; +} LightsN; typedef struct global_light_s { - /* 0x0 */ LightNode* list; + /* 0x0 */ Light_list* list; /* 0x4 */ u8 ambientColor[3]; /* 0x7 */ u8 fogColor[3]; /* 0xA */ s16 fogNear; @@ -71,11 +70,11 @@ extern void Light_point_ct(Lights* lights, s16 x, s16 y, s16 z, u8 r, u8 g, u8 b extern void Light_diffuse_ct(Lights* lights, s8 x, s8 y, s8 z, u8 r, u8 g, u8 b); extern void LightsN_disp_BG(LightsN* lights, GRAPH* graph); extern void LightsN_disp(LightsN* lights, GRAPH* graph); -extern void LightsN_list_check(LightsN* lights, LightNode* node, xyz_t* pos); +extern void LightsN_list_check(LightsN* lights, Light_list* node, xyz_t* pos); extern void Global_light_ct(Global_light* glight); extern LightsN* Global_light_read(Global_light* glight, GRAPH* graph); -extern void Global_light_list_new(GAME_PLAY*, Global_light* glight, Lights* light); -extern void Global_light_list_delete(Global_light* glight, LightNode* light); +extern Light_list* Global_light_list_new(GAME_PLAY*, Global_light* glight, Lights* light); +extern void Global_light_list_delete(Global_light* glight, Light_list* light); extern void Light_list_point_draw(GAME_PLAY* play); #ifdef __cplusplus diff --git a/include/m_npc.h b/include/m_npc.h index 892ae82e..ec6f9c87 100644 --- a/include/m_npc.h +++ b/include/m_npc.h @@ -240,6 +240,7 @@ extern void mNpc_SetNpcFurnitureRandom(mFM_fg_data_c** fg_data_list, int fg_name extern void mNpc_SetNpcHomeYpos(); extern void mNpc_SendRegisteredGoodbyMail(); extern void mNpc_IslandNpcRoomDataSet(mFM_fg_data_c** sorted_fg_data_list, int fg_name_start); +extern Animal_c* mNpc_GetAnimalInfoP(mActor_name_t npc_name); extern void mNpc_PrintRemoveInfo(gfxprint_t* gfxprint); extern void mNpc_PrintFriendship_fdebug(gfxprint_t* gfxprint); diff --git a/include/m_npc_schedule.h b/include/m_npc_schedule.h index 27fc28a1..8b8142ea 100644 --- a/include/m_npc_schedule.h +++ b/include/m_npc_schedule.h @@ -8,7 +8,11 @@ extern "C" { #endif - +extern mNPS_schedule_c* mNPS_get_schedule_area(AnmPersonalID_c* anm_id); +extern void mNPS_set_island_schedule_area(AnmPersonalID_c* anm_id); +extern void mNPS_reset_schedule_area(AnmPersonalID_c* anm_id); +extern void mNPS_schedule_manager(); +extern void mNPS_set_all_schedule_area(); #ifdef __cplusplus } diff --git a/include/m_room_type.h b/include/m_room_type.h index 86d81b25..53066466 100644 --- a/include/m_room_type.h +++ b/include/m_room_type.h @@ -111,6 +111,24 @@ typedef struct room_type_place_info_s { #define FTR1_NO_START 0x3000 +enum { + mRmTp_LIGHT_SWITCH_HOUSE0_MAIN_UPPER, + mRmTp_LIGHT_SWITCH_HOUSE0_BASEMENT, + mRmTp_LIGHT_SWITCH_HOUSE1_MAIN_UPPER, + mRmTp_LIGHT_SWITCH_HOUSE1_BASEMENT, + mRmTp_LIGHT_SWITCH_HOUSE2_MAIN_UPPER, + mRmTp_LIGHT_SWITCH_HOUSE2_BASEMENT, + mRmTp_LIGHT_SWITCH_HOUSE3_MAIN_UPPER, + mRmTp_LIGHT_SWITCH_HOUSE3_BASEMENT, + mRmTp_LIGHT_SWITCH_COTTAGE_MY, + mRmTp_LIGHT_SWITCH_9, + mRmTp_LIGHT_SWITCH_NPC, + mRmTp_LIGHT_SWITCH_LIGHTHOUSE, + mRmTp_LIGHT_SWITCH_TENT, + + mRmTp_LIGHT_SWITCH_NUM +}; + extern void mRmTp_DrawFamicomInfo(gfxprint_t* gfxprint); extern void mRmTp_MakeFamicom_Fdebug(); @@ -125,5 +143,11 @@ extern void mRmTp_SetDefaultLightSwitchData(int state); extern int mRmTp_GetEntranceBasePosition(xyz_t* pos); extern mActor_name_t mRmTp_GetPlayerRoomCollisionIdx(mActor_name_t field_name, mActor_name_t bg_name); extern u8 mRmTp_GetFloorIdx(); +extern int mRmTp_GetNowSceneLightSwitchIndex(); +extern void mRmTp_IndexLightSwitchOFF(int index); +extern void mRmTp_IndexLightSwitchON(int index); +extern int mRmTp_Index2LightSwitchStatus(int index); +extern int mRmTp_NowSceneLightSwitchON(); +extern int mRmTp_NowSceneLightSwitchOFF(); #endif \ No newline at end of file diff --git a/include/m_scene_table.h b/include/m_scene_table.h index b6136b11..46177b80 100644 --- a/include/m_scene_table.h +++ b/include/m_scene_table.h @@ -85,6 +85,12 @@ enum scene_table { (scene) == SCENE_MY_ROOM_BASEMENT_M || (scene) == (SCENE_MY_ROOM_BASEMENT_L) || (scene) == SCENE_MY_ROOM_BASEMENT_LL1 || \ (scene) == SCENE_COTTAGE_MY) +#define mSc_IS_SCENE_BASEMENT(scene) \ + ((scene) == SCENE_MY_ROOM_BASEMENT_S || \ + (scene) == SCENE_MY_ROOM_BASEMENT_M || \ + (scene) == SCENE_MY_ROOM_BASEMENT_L || \ + (scene) == SCENE_MY_ROOM_BASEMENT_LL1) + #define mSc_IS_SCENE_MUSEUM_ROOM(scene) \ ((scene) >= SCENE_MUSEUM_ENTRANCE && (scene) <= SCENE_MUSEUM_ROOM_FISH) diff --git a/include/m_time.h b/include/m_time.h index 986767c6..6ade8858 100644 --- a/include/m_time.h +++ b/include/m_time.h @@ -58,8 +58,8 @@ enum { #define mTM_SECONDS_IN_MINUTE 60 #define mTM_SECONDS_IN_HOUR 60*60 -#define mTM_SECONDS_IN_HALFDAY 12*60*60 -#define mTM_SECONDS_IN_DAY 24*60*60 +#define mTM_SECONDS_IN_HALFDAY (12*60*60) +#define mTM_SECONDS_IN_DAY (24*60*60) #define mTM_MINUTES_IN_HOUR 60 diff --git a/rel/ac_animal_logo.c b/rel/ac_animal_logo.c index ed60cfaf..8a50f9b3 100644 --- a/rel/ac_animal_logo.c +++ b/rel/ac_animal_logo.c @@ -130,7 +130,7 @@ static void aAL_title_game_data_init_start_select(ANIMAL_LOGO_ACTOR* actor, GAME play->fb_fade_type = 8; play->fb_wipe_type = 3; - Common_Set(wipeType, 3); + Common_Set(transition.wipe_type, 3); mBGMPsComp_make_ps_wipe(0x1168); } 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/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)){ diff --git a/rel/m_common_data.c b/rel/m_common_data.c index e1ab6590..ad6458d9 100644 --- a/rel/m_common_data.c +++ b/rel/m_common_data.c @@ -10,7 +10,7 @@ extern void common_data_reinit(){ state = Common_Get(pad_connected); bzero(&common_data, sizeof(common_data)); - Common_Set(wipeType, -1); + Common_Set(transition.wipe_type, -1); Common_Set(game_started,1); Common_Set(last_scene_no, -1); Common_Set(demo_profiles[0], mAc_PROFILE_NUM); /* cleared state */ diff --git a/rel/m_fbdemo_fade.c b/rel/m_fbdemo_fade.c index 8c12671f..8b26f73a 100644 --- a/rel/m_fbdemo_fade.c +++ b/rel/m_fbdemo_fade.c @@ -33,8 +33,8 @@ void fbdemo_fade_move(fbdemo_fade* this, int rate) { if (this->type != 7) { this->frame += rate; - if (this->frame >= Common_Get(transFadeDuration)) { - this->frame = Common_Get(transFadeDuration); + if (this->frame >= Common_Get(transition).fade_rate) { + this->frame = Common_Get(transition).fade_rate; this->isDone = 1; } ftimer = (f32)this->frame; @@ -42,7 +42,7 @@ void fbdemo_fade_move(fbdemo_fade* this, int rate) { ftimer = 0.0f; } - alpha = (255.0f * ftimer) / Common_Get(transFadeDuration); + alpha = (255.0f * ftimer) / Common_Get(transition).fade_rate; if (this->type == 1) { this->color.a = 255 - alpha; } else { diff --git a/rel/m_fbdemo_wipe1.c b/rel/m_fbdemo_wipe1.c index 2e7002d0..db187569 100644 --- a/rel/m_fbdemo_wipe1.c +++ b/rel/m_fbdemo_wipe1.c @@ -53,13 +53,13 @@ fbdemo_wipe1* fbdemo_wipe1_init(fbdemo_wipe1* this) { void fbdemo_wipe1_move(fbdemo_wipe1* this, int rate) { if (this->direction != 0) { - this->texY += (((void)0, Common_Get(transWipeSpeed)) * 3) / rate; + this->texY += (((void)0, Common_Get(transition).wipe_rate) * 3) / rate; if (this->texY >= (int)(153 * (1 << 2))) { this->texY = (int)(153 * (1 << 2)); this->finished = 1; } } else { - this->texY -= (((void)0, Common_Get(transWipeSpeed)) * 3) / rate; + this->texY -= (((void)0, Common_Get(transition).wipe_rate) * 3) / rate; if (this->texY <= (int)(83.25f * (1 << 2))) { this->texY = (int)(83.25f * (1 << 2)); this->finished = 1; diff --git a/rel/m_kankyo.c b/rel/m_kankyo.c new file mode 100644 index 00000000..25bbc539 --- /dev/null +++ b/rel/m_kankyo.c @@ -0,0 +1,2536 @@ +#include "m_kankyo.h" + +#include "m_room_type.h" +#include "m_scene_table.h" +#include "m_common_data.h" +#include "m_debug.h" +#include "m_npc_schedule.h" +#include "m_player_lib.h" + +#define mEnv_TIME_TO_SECS(hour, min, sec) ((hour) * mTM_SECONDS_IN_HOUR + (min) * mTM_SECONDS_IN_MINUTE + (sec)) + +static int klight_chg_time[mEnv_TERM_NUM + 1] = { + mEnv_TIME_TO_SECS(0, 0, 0), + mEnv_TIME_TO_SECS(4, 0, 0), + mEnv_TIME_TO_SECS(6, 0, 0), + mEnv_TIME_TO_SECS(8, 0, 0), + mEnv_TIME_TO_SECS(12, 0, 0), + mEnv_TIME_TO_SECS(16, 0, 0), + mEnv_TIME_TO_SECS(18, 0, 0), + mEnv_TIME_TO_SECS(20, 0, 0), + mEnv_TIME_TO_SECS(24, 0, 0) +}; + +static BaseLight l_mEnv_kcolor_fine_data[mEnv_TERM_NUM] = { + /* 00:00 -> 03:59 */ + { + { 20, 10, 120 }, // ambient color + + { 73, 73, 73 }, // sun direction + { 0, 0, 0 }, // sun color + + { 73, 73, 73 }, // moon direction + { 120, 180, 80 }, // moon color + + { 20, 20, 80 }, // fog color + 1799, // fog near + 1000, // fog far + + { 0, 0, 50 }, // shadow color + { 120, 160, 150 }, // room color + { 120, 160, 150 }, // window sun color + { 230, 230, 120 }, // window moon color + { 28, 32, 92 } // background color + }, + + { + { 0, 10, 120 }, // ambient color + + { 73, 73, 73 }, // sun direction + { 0, 20, 40 }, // sun color + + { 73, 73, 73 }, // moon direction + { 150, 200, 100 }, // moon color + + { 80, 100, 120 }, // fog color + 1774, // fog near + 1000, // fog far + + { 0, 0, 60 }, // shadow color + { 140, 190, 190 }, // room color + { 150, 170, 170 }, // window sun color + { 230, 230, 120 }, // window moon color + { 44, 52, 112 } // background color + }, + + { + { 60, 60, 120 }, // ambient color + + { 73, 73, 73 }, // sun direction + { 255, 255, 200 }, // sun color + + { 73, 73, 73 }, // moon direction + { 10, 40, 60 }, // moon color + + { 120, 150, 150 }, // fog color + 1749, // fog near + 950, // fog far + + { 0, 10, 70 }, // shadow color + { 180, 210, 210 }, // room color + { 160, 180, 180 }, // window sun color + { 230, 230, 120 }, // window moon color + { 60, 76, 120 } // background color + }, + + { + { 80, 80, 150 }, // ambient color + + { 73, 73, 73 }, // sun direction + { 180, 220, 220 }, // sun color + + { 73, 73, 73 }, // moon direction + { 0, 10, 20 }, // moon color + + { 80, 120, 150 }, // fog color + 1749, // fog near + 1000, // fog far + + { 0, 20, 70 }, // shadow color + { 210, 240, 240 }, // room color + { 190, 220, 220 }, // window sun color + { 230, 230, 120 }, // window moon color + { 56, 72, 140 } // background color + }, + + { + { 80, 80, 150 }, // ambient color + + { 73, 73, 73 }, // sun direction + { 200, 240, 240 }, // sun color + + { 73, 73, 73 }, // moon direction + { 0, 0, 0 }, // moon color + + { 80, 120, 150 }, // fog color + 1749, // fog near + 1000, // fog far + + { 0, 30, 70 }, // shadow color + { 220, 250, 250 }, // room color + { 210, 240, 240 }, // window sun color + { 230, 230, 120 }, // window moon color + { 52, 78, 144 } // background color + }, + + { + { 80, 80, 150 }, // ambient color + + { 73, 73, 73 }, // sun direction + { 200, 240, 240 }, // sun color + + { 73, 73, 73 }, // moon direction + { 10, 0, 30 }, // moon color + + { 80, 120, 150 }, // fog color + 1749, // fog near + 1000, // fog far + + { 0, 30, 90 }, // shadow color + { 220, 250, 250 }, // room color + { 220, 240, 240 }, // window sun color + { 230, 230, 120 }, // window moon color + { 48, 72, 140 } // background color + }, + + { + { 60, 60, 150 }, // ambient color + + { 73, 73, 73 }, // sun direction + { 200, 120, 0 }, // sun color + + { 73, 73, 73 }, // moon direction + { 20, 0, 80 }, // moon color + + { 20, 20, 80 }, // fog color + 1774, // fog near + 1000, // fog far + + { 0, 10, 70 }, // shadow color + { 190, 120, 120 }, // room color + { 180, 120, 120 }, // window sun color + { 230, 230, 120 }, // window moon color + { 32, 32, 92 } // background color + }, + + { + { 30, 30, 120 }, // ambient color + + { 73, 73, 73 }, // sun direction + { 60, 60, 0 }, // sun color + + { 73, 73, 73 }, // moon direction + { 120, 180, 80 }, // moon color + + { 20, 20, 80 }, // fog color + 1774, // fog near + 1000, // fog far + + { 0, 0, 60 }, // shadow color + { 130, 160, 160 }, // room color + { 180, 120, 120 }, // window sun color + { 230, 230, 120 }, // window moon color + { 28, 28, 92 } // background color + } +}; + +static BaseLight l_mEnv_kcolor_insect_fine_data[mEnv_TERM_NUM] = { + { + { 12, 6, 72 }, // ambient color + + { 73, 73, 73 }, // sun direction + { 0, 0, 0 }, // sun color + + { 73, 73, 73 }, // moon direction + { 72, 108, 48 }, // moon color + + { 20, 20, 80 }, // fog color + 1799, // fog near + 1000, // fog far + + { 0, 0, 50 }, // shadow color + { 72, 96, 90 }, // room color + { 120, 160, 150 }, // window sun color + { 230, 230, 120 }, // window moon color + { 28, 32, 92 } // background color + }, + + { + { 0, 6, 72 }, // ambient color + + { 73, 73, 73 }, // sun direction + { 0, 12, 24 }, // sun color + + { 73, 73, 73 }, // moon direction + { 90, 120, 60 }, // moon color + + { 80, 100, 120 }, // fog color + 1774, // fog near + 1000, // fog far + + { 0, 0, 60 }, // shadow color + { 84, 114, 114 }, // room color + { 150, 170, 170 }, // window sun color + { 230, 230, 120 }, // window moon color + { 44, 52, 112 } // background color + }, + + { + { 36, 36, 72 }, // ambient color + + { 73, 73, 73 }, // sun direction + { 153, 153, 120 }, // sun color + + { 73, 73, 73 }, // moon direction + { 6, 24, 36 }, // moon color + + { 120, 150, 150 }, // fog color + 1749, // fog near + 950, // fog far + + { 0, 10, 70 }, // shadow color + { 108, 126, 126 }, // room color + { 160, 180, 180 }, // window sun color + { 230, 230, 120 }, // window moon color + { 60, 76, 120 } // background color + }, + + { + { 80, 80, 150 }, // ambient color + + { 73, 73, 73 }, // sun direction + { 180, 220, 220 }, // sun color + + { 73, 73, 73 }, // moon direction + { 0, 10, 20 }, // moon color + + { 80, 120, 150 }, // fog color + 1749, // fog near + 1000, // fog far + + { 0, 20, 70 }, // shadow color + { 210, 240, 240 }, // room color + { 190, 220, 220 }, // window sun color + { 230, 230, 120 }, // window moon color + { 56, 72, 140 } // background color + }, + + { + { 80, 80, 150 }, // ambient color + + { 73, 73, 73 }, // sun direction + { 200, 240, 240 }, // sun color + + { 73, 73, 73 }, // moon direction + { 0, 0, 0 }, // moon color + + { 80, 120, 150 }, // fog color + 1749, // fog near + 1000, // fog far + + { 0, 30, 70 }, // shadow color + { 220, 250, 250 }, // room color + { 210, 240, 240 }, // window sun color + { 230, 230, 120 }, // window moon color + { 52, 78, 144 } // background color + }, + + { + { 80, 80, 150 }, // ambient color + + { 73, 73, 73 }, // sun direction + { 200, 240, 240 }, // sun color + + { 73, 73, 73 }, // moon direction + { 10, 0, 30 }, // moon color + + { 80, 120, 150 }, // fog color + 1749, // fog near + 1000, // fog far + + { 0, 30, 90 }, // shadow color + { 220, 250, 250 }, // room color + { 220, 240, 240 }, // window sun color + { 230, 230, 120 }, // window moon color + { 48, 72, 140 } // background color + }, + + { + { 36, 36, 90 }, // ambient color + + { 73, 73, 73 }, // sun direction + { 120, 72, 0 }, // sun color + + { 73, 73, 73 }, // moon direction + { 12, 0, 48 }, // moon color + + { 20, 20, 80 }, // fog color + 1774, // fog near + 1000, // fog far + + { 0, 10, 70 }, // shadow color + { 114, 72, 72 }, // room color + { 180, 120, 120 }, // window sun color + { 230, 230, 120 }, // window moon color + { 32, 32, 92 } // background color + }, + + { + { 18, 18, 72 }, // ambient color + + { 73, 73, 73 }, // sun direction + { 36, 36, 0 }, // sun color + + { 73, 73, 73 }, // moon direction + { 72, 108, 48 }, // moon color + + { 20, 20, 80 }, // fog color + 1774, // fog near + 1000, // fog far + + { 0, 0, 60 }, // shadow color + { 78, 96, 96 }, // room color + { 180, 120, 120 }, // window sun color + { 230, 230, 120 }, // window moon color + { 28, 28, 92 } // background color + } +}; + +static BaseLight l_mEnv_kcolor_rain_data[mEnv_TERM_NUM] = { + { + { 18, 9, 108 }, // ambient color + + { 73, 73, 73 }, // sun direction + { 0, 0, 0 }, // sun color + + { 73, 73, 73 }, // moon direction + { 108, 162, 72 }, // moon color + + { 20, 20, 80 }, // fog color + 1799, // fog near + 1000, // fog far + + { 0, 0, 50 }, // shadow color + { 108, 144, 135 }, // room color + { 120, 160, 150 }, // window sun color + { 230, 230, 120 }, // window moon color + { 28, 32, 92 } // background color + }, + + { + { 0, 9, 108 }, // ambient color + + { 73, 73, 73 }, // sun direction + { 0, 18, 36 }, // sun color + + { 73, 73, 73 }, // moon direction + { 135, 180, 90 }, // moon color + + { 80, 100, 120 }, // fog color + 1774, // fog near + 1000, // fog far + + { 0, 0, 60 }, // shadow color + { 126, 171, 171 }, // room color + { 150, 170, 170 }, // window sun color + { 230, 230, 120 }, // window moon color + { 44, 52, 112 } // background color + }, + + { + { 54, 54, 108 }, // ambient color + + { 73, 73, 73 }, // sun direction + { 229, 229, 180 }, // sun color + + { 73, 73, 73 }, // moon direction + { 9, 36, 54 }, // moon color + + { 120, 150, 150 }, // fog color + 1749, // fog near + 950, // fog far + + { 0, 10, 70 }, // shadow color + { 162, 189, 189 }, // room color + { 160, 180, 180 }, // window sun color + { 230, 230, 120 }, // window moon color + { 60, 76, 120 } // background color + }, + + { + { 72, 72, 135 }, // ambient color + + { 73, 73, 73 }, // sun direction + { 162, 198, 198 }, // sun color + + { 73, 73, 73 }, // moon direction + { 0, 9, 18 }, // moon color + + { 80, 120, 150 }, // fog color + 1749, // fog near + 1000, // fog far + + { 0, 20, 70 }, // shadow color + { 189, 216, 216 }, // room color + { 190, 220, 220 }, // window sun color + { 230, 230, 120 }, // window moon color + { 56, 72, 140 } // background color + }, + + { + { 72, 72, 135 }, // ambient color + + { 73, 73, 73 }, // sun direction + { 180, 216, 216 }, // sun color + + { 73, 73, 73 }, // moon direction + { 0, 0, 0 }, // moon color + + { 80, 120, 150 }, // fog color + 1749, // fog near + 1000, // fog far + + { 0, 30, 70 }, // shadow color + { 198, 225, 225 }, // room color + { 210, 240, 240 }, // window sun color + { 230, 230, 120 }, // window moon color + { 52, 78, 144 } // background color + }, + + { + { 72, 72, 135 }, // ambient color + + { 73, 73, 73 }, // sun direction + { 180, 216, 216 }, // sun color + + { 73, 73, 73 }, // moon direction + { 9, 0, 27 }, // moon color + + { 80, 120, 150 }, // fog color + 1749, // fog near + 1000, // fog far + + { 0, 30, 90 }, // shadow color + { 198, 225, 225 }, // room color + { 220, 240, 240 }, // window sun color + { 230, 230, 120 }, // window moon color + { 48, 72, 140 } // background color + }, + + { + { 54, 54, 135 }, // ambient color + + { 73, 73, 73 }, // sun direction + { 180, 108, 0 }, // sun color + + { 73, 73, 73 }, // moon direction + { 18, 0, 72 }, // moon color + + { 20, 20, 80 }, // fog color + 1774, // fog near + 1000, // fog far + + { 0, 10, 70 }, // shadow color + { 171, 108, 108 }, // room color + { 180, 120, 120 }, // window sun color + { 230, 230, 120 }, // window moon color + { 32, 32, 92 } // background color + }, + + { + { 27, 27, 108 }, // ambient color + + { 73, 73, 73 }, // sun direction + { 54, 54, 0 }, // sun color + + { 73, 73, 73 }, // moon direction + { 108, 162, 72 }, // moon color + + { 20, 20, 80 }, // fog color + 1774, // fog near + 1000, // fog far + + { 0, 0, 60 }, // shadow color + { 117, 144, 144 }, // room color + { 180, 120, 120 }, // window sun color + { 230, 230, 120 }, // window moon color + { 28, 28, 92 } // background color + } +}; + +static BaseLight l_mEnv_kcolor_insect_rain_data[mEnv_TERM_NUM] = { + { + { 10, 5, 64 }, // ambient color + + { 73, 73, 73 }, // sun direction + { 0, 0, 0 }, // sun color + + { 73, 73, 73 }, // moon direction + { 64, 97, 43 }, // moon color + + { 20, 20, 80 }, // fog color + 1799, // fog near + 1000, // fog far + + { 0, 0, 50 }, // shadow color + { 64, 86, 81 }, // room color + { 120, 160, 150 }, // window sun color + { 230, 230, 120 }, // window moon color + { 28, 32, 92 } // background color + }, + + { + { 0, 5, 64 }, // ambient color + + { 73, 73, 73 }, // sun direction + { 0, 10, 21 }, // sun color + + { 73, 73, 73 }, // moon direction + { 81, 108, 54 }, // moon color + + { 80, 100, 120 }, // fog color + 1774, // fog near + 1000, // fog far + + { 0, 0, 60 }, // shadow color + { 75, 102, 102 }, // room color + { 150, 170, 170 }, // window sun color + { 230, 230, 120 }, // window moon color + { 44, 52, 112 } // background color + }, + + { + { 32, 32, 64 }, // ambient color + + { 73, 73, 73 }, // sun direction + { 137, 137, 108 }, // sun color + + { 73, 73, 73 }, // moon direction + { 5, 21, 32 }, // moon color + + { 120, 150, 150 }, // fog color + 1749, // fog near + 950, // fog far + + { 0, 10, 70 }, // shadow color + { 97, 113, 113 }, // room color + { 160, 180, 180 }, // window sun color + { 230, 230, 120 }, // window moon color + { 60, 76, 120 } // background color + }, + + { + { 72, 72, 135 }, // ambient color + + { 73, 73, 73 }, // sun direction + { 162, 198, 198 }, // sun color + + { 73, 73, 73 }, // moon direction + { 0, 9, 18 }, // moon color + + { 80, 120, 150 }, // fog color + 1749, // fog near + 1000, // fog far + + { 0, 20, 70 }, // shadow color + { 189, 216, 216 }, // room color + { 190, 220, 220 }, // window sun color + { 230, 230, 120 }, // window moon color + { 56, 72, 140 } // background color + }, + + { + { 72, 72, 135 }, // ambient color + + { 73, 73, 73 }, // sun direction + { 180, 216, 216 }, // sun color + + { 73, 73, 73 }, // moon direction + { 0, 0, 0 }, // moon color + + { 80, 120, 150 }, // fog color + 1749, // fog near + 1000, // fog far + + { 0, 30, 70 }, // shadow color + { 198, 225, 225 }, // room color + { 210, 240, 240 }, // window sun color + { 230, 230, 120 }, // window moon color + { 52, 78, 144 } // background color + }, + + { + { 72, 72, 135 }, // ambient color + + { 73, 73, 73 }, // sun direction + { 180, 216, 216 }, // sun color + + { 73, 73, 73 }, // moon direction + { 9, 0, 27 }, // moon color + + { 80, 120, 150 }, // fog color + 1749, // fog near + 1000, // fog far + + { 0, 30, 90 }, // shadow color + { 198, 225, 225 }, // room color + { 220, 240, 240 }, // window sun color + { 230, 230, 120 }, // window moon color + { 48, 72, 140 } // background color + }, + + { + { 32, 32, 81 }, // ambient color + + { 73, 73, 73 }, // sun direction + { 108, 64, 0 }, // sun color + + { 73, 73, 73 }, // moon direction + { 10, 0, 43 }, // moon color + + { 20, 20, 80 }, // fog color + 1774, // fog near + 1000, // fog far + + { 0, 10, 70 }, // shadow color + { 102, 64, 64 }, // room color + { 180, 120, 120 }, // window sun color + { 230, 230, 120 }, // window moon color + { 32, 32, 92 } // background color + }, + + { + { 16, 16, 64 }, // ambient color + + { 73, 73, 73 }, // sun direction + { 32, 32, 0 }, // sun color + + { 73, 73, 73 }, // moon direction + { 64, 97, 43 }, // moon color + + { 20, 20, 80 }, // fog color + 1774, // fog near + 1000, // fog far + + { 0, 0, 60 }, // shadow color + { 70, 86, 86 }, // room color + { 180, 120, 120 }, // window sun color + { 230, 230, 120 }, // window moon color + { 28, 28, 92 } // background color + } +}; + +static BaseLight l_mEnv_kcolor_data_p_sel = { + { 30, 30, 80 }, // ambient color + + { 0, 89, 79 }, // sun direction + { 255, 255, 200 }, // sun color + + { 0, 185, 160 }, // moon direction + { 0, 0, 0 }, // moon color + + { 100, 100, 120 }, // fog color + 2000, // fog near + 1280, // fog far + + { 0, 30, 70 }, // shadow color + { 255, 255, 255 }, // room color + { 0, 0, 0 }, // window sun color + { 0, 0, 0 }, // window moon color + { 22, 27, 94 } // background color +}; + +static BaseLight l_mEnv_kcolor_shop = { + { 20, 10, 100 }, // ambient color + + { 0, 69, 97 }, // sun direction + { 150, 160, 130 }, // sun color + + { 0, 223, 115 }, // moon direction + { 50, 40, 20 }, // moon color + + { 100, 100, 120 }, // fog color + 2000, // fog near + 1280, // fog far + + { 0, 30, 70 }, // shadow color + { 255, 255, 255 }, // room color + { 0, 0, 0 }, // window sun color + { 0, 0, 0 }, // window moon color + { 22, 27, 94 } // background color +}; + +static BaseLight l_mEnv_kcolor_buggy = { + { 30, 30, 30 }, // ambient color + + { 0, 69, 97 }, // sun direction + { 0, 0, 0 }, // sun color + + { 0, 223, 115 }, // moon direction + { 0, 60, 90 }, // moon color + + { 100, 100, 120 }, // fog color + 2000, // fog near + 1280, // fog far + + { 0, 20, 30 }, // shadow color + { 175, 175, 155 }, // room color + { 0, 0, 0 }, // window sun color + { 0, 0, 0 }, // window moon color + { 22, 27, 94 } // background color +}; + +static BaseLight l_mEnv_kcolor_broker = { + { 20, 30, 40 }, // ambient color + + { 0, 69, 97 }, // sun direction + { 100, 80, 80 }, // sun color + + { 0, 223, 115 }, // moon direction + { 20, 10, 0 }, // moon color + + { 100, 100, 120 }, // fog color + 2000, // fog near + 1280, // fog far + + { 0, 0, 20 }, // shadow color + { 140, 120, 120 }, // room color + { 0, 0, 0 }, // window sun color + { 0, 0, 0 }, // window moon color + { 22, 27, 94 } // background color +}; + +static BaseLight l_mEnv_kcolor_kamakura = { + { 50, 25, 20 }, // ambient color + + { 0, 69, 97 }, // sun direction + { 50, 40, 5 }, // sun color + + { 0, 223, 115 }, // moon direction + { 50, 80, 85 }, // moon color + + { 100, 100, 120 }, // fog color + 2000, // fog near + 1280, // fog far + + { 40, 50, 80 }, // shadow color + { 250, 240, 160 }, // room color + { 0, 0, 0 }, // window sun color + { 0, 0, 0 }, // window moon color + { 22, 27, 94 } // background color +}; + +static BaseLight l_mEnv_kcolor_museum_fossil = { + { 50, 50, 60 }, // ambient color + + { 0, 69, 97 }, // sun direction + { 60, 60, 80 }, // sun color + + { 0, 223, 115 }, // moon direction + { 20, 10, 0 }, // moon color + + { 0, 0, 0 }, // fog color + 2000, // fog near + 1280, // fog far + + { 0, 10, 60 }, // shadow color + { 255, 255, 255 }, // room color + { 0, 0, 0 }, // window sun color + { 0, 0, 0 }, // window moon color + { 22, 27, 94 } // background color +}; + +static BaseLight l_mEnv_kcolor_museum_fish = { + { 40, 50, 60 }, // ambient color + + { 0, 69, 97 }, // sun direction + { 20, 30, 40 }, // sun color + + { 0, 223, 115 }, // moon direction + { 0, 10, 20 }, // moon color + + { 0, 0, 0 }, // fog color + 2000, // fog near + 1280, // fog far + + { 0, 20, 30 }, // shadow color + { 120, 90, 100 }, // room color + { 0, 0, 0 }, // window sun color + { 0, 0, 0 }, // window moon color + { 22, 27, 94 } // background color +}; + +static BaseLight l_mEnv_kcolor_museum_picture = { + { 30, 30, 60 }, // ambient color + + { 0, 69, 97 }, // sun direction + { 120, 100, 80 }, // sun color + + { 0, 223, 115 }, // moon direction + { 0, 10, 20 }, // moon color + + { 0, 0, 0 }, // fog color + 2000, // fog near + 1280, // fog far + + { 0, 10, 50 }, // shadow color + { 255, 255, 255 }, // room color + { 0, 0, 0 }, // window sun color + { 0, 0, 0 }, // window moon color + { 22, 27, 94 } // background color +}; + +static BaseLight l_mEnv_kcolor_basement = { + { 35, 30, 25 }, // ambient color + + { 0, 69, 97 }, // sun direction + { 0, 0, 0 }, // sun color + + { 0, 223, 115 }, // moon direction + { 0, 0, 0 }, // moon color + + { 0, 0, 0 }, // fog color + 2000, // fog near + 1280, // fog far + + { 0, 5, 10 }, // shadow color + { 53, 53, 33 }, // room color + { 0, 0, 0 }, // window sun color + { 0, 0, 0 }, // window moon color + { 22, 27, 94 } // background color +}; + +static BaseLight l_mEnv_kcolor_lighthouse = { + { 35, 30, 25 }, // ambient color + + { 0, 69, 97 }, // sun direction + { 0, 0, 0 }, // sun color + + { 0, 223, 115 }, // moon direction + { 0, 0, 0 }, // moon color + + { 0, 0, 0 }, // fog color + 2000, // fog near + 1280, // fog far + + { 0, 20, 30 }, // shadow color + { 135, 125, 105 }, // room color + { 0, 0, 0 }, // window sun color + { 0, 0, 0 }, // window moon color + { 0, 0, 0 } // background color +}; + +static BaseLight* l_mEnv_normal_kcolor_data[4] = { + l_mEnv_kcolor_fine_data, /* clear */ + l_mEnv_kcolor_rain_data, /* rain */ + l_mEnv_kcolor_rain_data, /* snow */ + l_mEnv_kcolor_fine_data /* cherry blossoms */ +}; + +static BaseLight* l_mEnv_normal_kcolor_insect_data[4] = { + l_mEnv_kcolor_insect_fine_data, /* clear */ + l_mEnv_kcolor_insect_rain_data, /* rain */ + l_mEnv_kcolor_insect_rain_data, /* snow */ + l_mEnv_kcolor_insect_fine_data /* cherry blossoms */ +}; + +typedef struct electric_light_s { + f32 point_light_percent; + u8 point_light_color[3]; + s16 _08; + s16 now_weather; + s16 next_weather; + f32 change_weather_env_rate; + s16 light_animating_on; + s16 light_anime_frame; + int point_light_on_type; + int point_light_off_type; + f32 point_light_off_step; + s16 point_light_is_flame; /* flickering effect when non-zero */ + f32 staffroll_fade_rate; + f32 sun_percent; + f32 shadow_adjust; + f32 windowlight_alpha; + Light_list* current_point_light; + s16 add_moon_color[3]; + Light_list* point_light_list_buf[mEnv_POINT_LIGHT_NUM]; + Lights point_lights[mEnv_POINT_LIGHT_NUM]; + int switch_status; + f32 point_light_min; + f32 diffuse_light_effect_rate; + s16 _98; + s16 shadow_alpha; + f32 diffuse_adjust; + u8 shadow_alpha_adjust; +} mEnv_electric_light_c; + +static mEnv_electric_light_c l_mEnv_electric_light; + +static int mEnv_CheckNpcRoomPointLightNiceStatus(); +static void mEnv_set_time(Kankyo* kankyo); +static void mEnv_MakeWindowLightAlpha(int enabled); +static void mEnv_InitWind(); +static int mEnv_Pointlight_on_check(); + +static f32 mEnv_DiffuseLightEffectRate() { + if (mRmTp_GetNowSceneLightSwitchIndex() != -1) { + if ( + !mSc_IS_SCENE_BASEMENT(Save_Get(scene_no)) && + Save_Get(scene_no) != SCENE_LIGHTHOUSE && + Save_Get(scene_no) != SCENE_TENT + ) { + return 0.7f; + } + } + return l_mEnv_electric_light.diffuse_light_effect_rate; +} + +#include "../rel/m_kankyo_weather.c_inc" + +extern void mEnv_regist_nature(Kankyo* kankyo, NATURE_PROC nature_proc, void* arg) { + kankyo->nature.proc = nature_proc; + kankyo->nature.arg = arg; +} + +extern int mEnv_unregist_nature(Kankyo* kankyo, NATURE_PROC nature_proc) { + int res = FALSE; + + if (nature_proc == kankyo->nature.proc) { + mEnv_regist_nature(kankyo, (NATURE_PROC)&none_proc1, NULL); + res = TRUE; + } + + return res; +} + +static int mEnv_GetNowRoomPointLightInfo(GAME_PLAY* play, s_xyz* pos, u8* color, s16* power, s16* is_flame) { + int res = TRUE; + + switch (Common_Get(field_draw_type)) { + case FIELD_DRAW_TYPE_INDOORS: + { + color[0] = 160; // r + color[1] = 160; // g + color[2] = 160; // b + power[0] = 1000; + + switch (Save_Get(scene_no)) { + case SCENE_MY_ROOM_S: + { + color[0] = 220; // r + color[1] = 220; // g + color[2] = 200; // b + + pos->x = 120; + pos->y = 180; + pos->z = 180; + + break; + } + + case SCENE_MY_ROOM_M: + case SCENE_MY_ROOM_LL2: + { + color[0] = 220; // r + color[1] = 220; // g + color[2] = 200; // b + + pos->x = 160; + pos->y = 180; + pos->z = 240; + + break; + } + + case SCENE_SHOP0: + case SCENE_POST_OFFICE: + { + color[0] = 220; // r + color[1] = 220; // g + color[2] = 200; // b + + pos->x = 160; + pos->y = 180; + pos->z = 240; + + break; + } + + case SCENE_NPC_HOUSE: + case SCENE_COTTAGE_NPC: + { + pos->x = 160; + pos->y = 180; + pos->z = 240; + + color[0] = 220; // r + color[1] = 220; // g + color[2] = 200; // b + + break; + } + + case SCENE_BUGGY: + { + pos->x = 160; + pos->y = 80; + pos->z = 200; + + color[0] = 205; // r + color[1] = 165; // g + color[2] = 110; // b + + power[0] = 155; + is_flame[0] = TRUE; + + break; + } + + case SCENE_MY_ROOM_BASEMENT_S: + case SCENE_MY_ROOM_BASEMENT_M: + case SCENE_MY_ROOM_BASEMENT_L: + case SCENE_MY_ROOM_BASEMENT_LL1: + { + color[0] = 220; // r + color[1] = 190; // g + color[2] = 190; // b + + pos->x = 200; + pos->y = 220; + pos->z = 300; + + break; + } + + case SCENE_MY_ROOM_L: + case SCENE_MY_ROOM_LL1: + case SCENE_COTTAGE_MY: + { + color[0] = 220; // r + color[1] = 220; // g + color[2] = 200; // b + + pos->x = 200; + pos->y = 220; + pos->z = 300; + + break; + } + + case SCENE_POLICE_BOX: + { + color[0] = 220; // r + color[1] = 220; // g + color[2] = 200; // b + + pos->x = 200; + pos->y = 220; + pos->z = 300; + + break; + } + + case SCENE_KAMAKURA: + { + pos->x = 160; + pos->y = 80; + pos->z = 38; + + color[0] = 250; // r + color[1] = 240; // g + color[2] = 120; // b + + power[0] = 300; + is_flame[0] = TRUE; + + break; + } + + case SCENE_MUSEUM_ENTRANCE: + { + color[0] = 220; // r + color[1] = 220; // g + color[2] = 200; // b + + pos->x = 240; + pos->y = 220; + pos->z = 280; + + break; + } + + case SCENE_MUSEUM_ROOM_PAINTING: + { + color[0] = 180; // r + color[1] = 180; // g + color[2] = 150; // b + + pos->x = 320; + pos->y = 220; + pos->z = 280; + + power[0] = 800; + + break; + } + + case SCENE_MUSEUM_ROOM_FOSSIL: + { + color[0] = 200; // r + color[1] = 200; // g + color[2] = 180; // b + + pos->x = 320; + pos->y = 220; + pos->z = 280; + + power[0] = 800; + + break; + } + + case SCENE_MUSEUM_ROOM_INSECT: + { + color[0] = 50; // r + color[1] = 50; // g + color[2] = 50; // b + + pos->x = 280; + pos->y = 220; + pos->z = 320; + + break; + } + + case SCENE_MUSEUM_ROOM_FISH: + { + pos->x = 320; + pos->y = 220; + pos->z = 320; + + color[0] = 100; // r + color[1] = 120; // g + color[2] = 130; // b + + break; + } + + case SCENE_NEEDLEWORK: + { + color[0] = 220; // r + color[1] = 220; // g + color[2] = 200; // b + + pos->x = 200; + pos->y = 160; + pos->z = 280; + + break; + } + + case SCENE_LIGHTHOUSE: + { + pos->x = 120; + pos->y = 80; + pos->z = 160; + + color[0] = 235; // r + color[1] = 190; // g + color[2] = 185; // b + + power[0] = 6000; + + break; + } + + case SCENE_TENT: + { + pos->x = 120; + pos->y = 80; + pos->z = 120; + + color[0] = 235; // r + color[1] = 190; // g + color[2] = 185; // b + + power[0] = 6000; + + break; + } + + case SCENE_BROKER_SHOP: + { + color[0] = 170; // r + color[1] = 170; // g + color[2] = 160; // b + + pos->x = 250; + pos->y = 1000; + pos->z = 378; + + power[0] = 8000; + + break; + } + + default: + { + pos->x = 250; + pos->y = 1000; + pos->z = 378; + + power[0] = 8000; + + break; + } + } + + break; + } + + case FIELD_DRAW_TYPE_TRAIN: + { + switch (Save_Get(scene_no)) { + case SCENE_START_DEMO: + case SCENE_START_DEMO3: + { + Common_Set(sunlight_flag, FALSE); + + break; + } + } + + l_mEnv_electric_light.sun_percent = 0.0f; + + pos->x = 80; + pos->y = 120; + pos->z = 510; + + color[0] = 255; + color[1] = 255; + color[2] = 160; + + power[0] = 1200; + + break; + } + + default: + res = FALSE; + break; + } + + return res; +} + +static void mEnv_RoomTypePointLightSet(GAME_PLAY* play) { + s_xyz pos; + u8 color[3]; + s16 power; + int light_switch; + + if (Save_Get(scene_no) == SCENE_TITLE_DEMO) { + mRmTp_SetDefaultLightSwitchData(FALSE); + mRmTp_IndexLightSwitchOFF(mRmTp_LIGHT_SWITCH_9); + } + else if (Save_Get(scene_no) == SCENE_NPC_HOUSE || Save_Get(scene_no) == SCENE_COTTAGE_NPC) { + if (mEnv_CheckNpcRoomPointLightNiceStatus() == FALSE) { + mRmTp_IndexLightSwitchOFF(mRmTp_LIGHT_SWITCH_NPC); + } + else { + mRmTp_IndexLightSwitchON(mRmTp_LIGHT_SWITCH_NPC); + } + } + + l_mEnv_electric_light.point_light_is_flame = FALSE; + l_mEnv_electric_light.point_light_percent = 0.0f; + + if (mEnv_GetNowRoomPointLightInfo(play, &pos, color, &power, &l_mEnv_electric_light.point_light_is_flame) == TRUE) { + Light_point_ct(&play->kankyo.point_light, pos.x, pos.y, pos.z, color[0], color[1], color[2], power); + l_mEnv_electric_light.point_light_color[0] = color[0]; + l_mEnv_electric_light.point_light_color[1] = color[1]; + l_mEnv_electric_light.point_light_color[2] = color[2]; + l_mEnv_electric_light.current_point_light = Global_light_list_new(play, &play->global_light, &play->kankyo.point_light); + + light_switch = mRmTp_GetNowSceneLightSwitchIndex(); + + if (light_switch != -1) { + int switch_status = mRmTp_Index2LightSwitchStatus(light_switch); + + l_mEnv_electric_light.point_light_percent = switch_status != 0 ? 1.0f : l_mEnv_electric_light.point_light_min; + } + else { + l_mEnv_electric_light.point_light_percent = 1.0f; + } + } +} + +static void mEnv_RoomTypediffuseLightSet(GAME_PLAY* play, Kankyo* kankyo) { + Light_diffuse_ct(&kankyo->sun_light, 1, 0, 0, 0, 0, 0); + Global_light_list_new(play, &play->global_light, &kankyo->sun_light); + + Light_diffuse_ct(&kankyo->moon_light, 1, 0, 0, 0, 0, 0); + Global_light_list_new(play, &play->global_light, &kankyo->moon_light); +} + +static void mEnv_RoomTypeLightSet(GAME_PLAY* play, Kankyo* kankyo) { + mEnv_RoomTypePointLightSet(play); + mEnv_RoomTypediffuseLightSet(play, kankyo); +} + +static void mEnv_rainbow_check_set() { + if (mFI_CheckFieldData() != FALSE && mFI_GET_TYPE(mFI_GetFieldId()) == mFI_FIELD_FG && mEv_CheckTitleDemo() <= 0) { + if (Save_Get(rainbow_reserved)) { + if ( + Common_Get(time).rtc_time.month == Save_Get(rainbow_month) && + Common_Get(time).rtc_time.day == Save_Get(rainbow_day) + ) { + int now_sec = Common_Get(time).now_sec; + if ( + now_sec >= mEnv_RAINBOW_TIME_START && + now_sec < mEnv_RAINBOW_TIME_END + ) { + Save_Set(rainbow_reserved, FALSE); + + if (Common_Get(time).season == mTM_SEASON_SUMMER) { + Common_Set(rainbow_opacity, 1.0f); + } + } + } + else { + Save_Set(rainbow_reserved, FALSE); + } + } + else if (Common_Get(rainbow_opacity) > 0.0f) { + if ( + Common_Get(time).rtc_time.month != Save_Get(rainbow_month) || + Common_Get(time).rtc_time.day != Save_Get(rainbow_day) || + Common_Get(time).now_sec < mEnv_RAINBOW_TIME_START || // might need to break out time.now_sec into its own variable + Common_Get(time).now_sec >= mEnv_RAINBOW_TIME_BYE || + Common_Get(time).season != mTM_SEASON_SUMMER + ) { + Common_Set(rainbow_opacity, 0.0f); + } + } + } +} + +extern void Global_kankyo_ct(GAME_PLAY* play, Kankyo* kankyo) { + bzero(&l_mEnv_electric_light, sizeof(l_mEnv_electric_light)); + mRmTp_IndexLightSwitchOFF(mRmTp_LIGHT_SWITCH_NPC); + + l_mEnv_electric_light.staffroll_fade_rate = 1.0f; + l_mEnv_electric_light.shadow_adjust = 1.0f; + l_mEnv_electric_light.sun_percent = 1.0f; + l_mEnv_electric_light.current_point_light = NULL; + + if (Save_Get(scene_no) == SCENE_MUSEUM_ROOM_INSECT) { + l_mEnv_electric_light.diffuse_adjust = 0.5f; + } + else { + l_mEnv_electric_light.diffuse_adjust = 0.4f; + } + + if (Save_Get(scene_no) == SCENE_MUSEUM_ROOM_INSECT) { + l_mEnv_electric_light.shadow_alpha_adjust = 100; + } + else { + l_mEnv_electric_light.shadow_alpha_adjust = 150; + } + + l_mEnv_electric_light.change_weather_env_rate = 0.0f; + + switch (Save_Get(scene_no)) { + case SCENE_LIGHTHOUSE: + case SCENE_TENT: + { + l_mEnv_electric_light.point_light_min = 0.14f; + break; + } + + default: + { + l_mEnv_electric_light.point_light_min = 0.14f; + break; + } + } + + l_mEnv_electric_light.diffuse_light_effect_rate = 1.0f; + + bzero(kankyo, sizeof(Kankyo)); + SETREG(MYKREG, 28, 100); + Common_Set(transition._00, 0); + mEnv_set_time(kankyo); + kankyo->countdown_timer = 0xFF; + mEnv_RoomTypeLightSet(play, kankyo); + mEnv_regist_nature(kankyo, (NATURE_PROC)none_proc1, NULL); + mEnv_MakeWindowLightAlpha(FALSE); + mEnv_InitWind(); + l_mEnv_electric_light.switch_status = (u8)mEnv_Pointlight_on_check() ? mEnv_SWITCH_STATUS_TURNING_OFF : mEnv_SWITCH_STATUS_TURNING_ON; + mEnv_rainbow_check_set(); +} + +static void mEnv_MakeShadowInfo(Kankyo* kankyo) { + f32 time_adjust; + f32 weather_base_adjust; + f32 weather_change_adjust; + f32 shadow_pos; + lbRTC_time_c* rtc_time = Common_GetPointer(time.rtc_time); + int now_sec; + u8 transition_zero = FALSE; + int switch_index; + int min_sec = (rtc_time->min) * mTM_SECONDS_IN_MINUTE; + int hour_sec = (rtc_time->hour) * mTM_SECONDS_IN_HOUR; + + now_sec = hour_sec + min_sec + rtc_time->sec; + switch_index = mRmTp_GetNowSceneLightSwitchIndex(); // unused + + /* + * Time period overview for shadows + * [0] 00:00:00 - 03:59:29 | 0.4 (rate normal) + * [1] 03:59:30 - 04:00:02 | 0.4 (rate reduced) + * [2] 04:00:03 - 06:00:00 | 0.4 -> 1.0 (rate normal) + * [3] 06:00:01 - 17:59:59 | 1.0 (rate normal) + * [4] 18:00:00 - 19:59:30 | 1.0 -> 0.4 (rate normal) + * [5] 19:59:31 - 20:00:03 | 0.4 (rate reduced) + * [6] 20:00:04 - 23:59:59 | 0.4 (rate normal) + */ + + if (now_sec > mEnv_TIME_TO_SECS(6, 0, 0) && now_sec < mEnv_TIME_TO_SECS(18, 0, 0)) { + time_adjust = 1.0f; + } + else if (now_sec < mEnv_TIME_TO_SECS(3, 59, 30) || now_sec > mEnv_TIME_TO_SECS(20, 0, 3)) { + time_adjust = 0.4f; + } + else if (now_sec >= mEnv_TIME_TO_SECS(4, 0, 3) && now_sec <= mEnv_TIME_TO_SECS(6, 0, 0)) { + time_adjust = 0.4f + ((f32)(now_sec - mEnv_TIME_TO_SECS(4, 0, 3)) / (f32)(mEnv_TIME_TO_SECS(6, 0, 0) - mEnv_TIME_TO_SECS(4, 0, 3))) * 0.6f; + } + else if (now_sec >= mEnv_TIME_TO_SECS(18, 0, 0) && now_sec <= mEnv_TIME_TO_SECS(19, 59, 30)) { + time_adjust = 0.4f + ((1.0f - (f32)(now_sec - mEnv_TIME_TO_SECS(18, 0, 0)) / (f32)(mEnv_TIME_TO_SECS(19, 59, 30) - mEnv_TIME_TO_SECS(18, 0, 0)))) * 0.6f; + } + else { + transition_zero = TRUE; + time_adjust = 0.4f; + } + + if (transition_zero == TRUE) { + if ( + (now_sec > mEnv_TIME_TO_SECS(3, 59, 55) && now_sec < mEnv_TIME_TO_SECS(4, 0, 3)) || + (now_sec > mEnv_TIME_TO_SECS(19, 59, 55) && now_sec < mEnv_TIME_TO_SECS(20, 0, 3)) + ) { + add_calc(&l_mEnv_electric_light.shadow_adjust, 0.0f, 1.0f - sqrtf(0.5), 0.005f, 0.005f); + } + else { + add_calc(&l_mEnv_electric_light.shadow_adjust, 0.0f, 1.0f - sqrtf(0.9), 0.0006f, 0.0004f); + } + } + else { + add_calc(&l_mEnv_electric_light.shadow_adjust, 1.0f, 1.0f - sqrtf(0.9), 0.0005f, 0.00005f); + } + + weather_base_adjust = (l_mEnv_electric_light.now_weather == mEnv_WEATHER_RAIN || l_mEnv_electric_light.now_weather == mEnv_WEATHER_SNOW) ? 0.75f : 1.0f; + weather_change_adjust = (l_mEnv_electric_light.next_weather == mEnv_WEATHER_RAIN || l_mEnv_electric_light.next_weather == mEnv_WEATHER_SNOW) ? 0.75f : 1.0f; + + time_adjust *= (weather_base_adjust + l_mEnv_electric_light.change_weather_env_rate * (weather_change_adjust - weather_base_adjust)); + kankyo->shadow_alpha = (time_adjust * 255.0f * l_mEnv_electric_light.shadow_adjust * 0.75f) * l_mEnv_electric_light.staffroll_fade_rate; + + if (l_mEnv_electric_light.shadow_alpha != 0) { + kankyo->shadow_alpha = l_mEnv_electric_light.shadow_alpha; + } + else if (Save_Get(scene_no) != SCENE_FG && Save_Get(scene_no) != SCENE_MUSEUM_ROOM_INSECT) { + kankyo->shadow_alpha = (f32)kankyo->shadow_alpha + l_mEnv_electric_light.point_light_percent * ((f32)l_mEnv_electric_light.shadow_alpha_adjust - (f32)kankyo->shadow_alpha); + } + + if (now_sec >= mEnv_TIME_TO_SECS(4, 0, 0) && now_sec <= mEnv_TIME_TO_SECS(20, 0, 0)) { + f32 diff = now_sec - mEnv_TIME_TO_SECS(4, 0, 0); + shadow_pos = diff / (f32)(mEnv_TIME_TO_SECS(20, 0, 0) - mEnv_TIME_TO_SECS(4, 0, 0)); + } + else { + if (now_sec < mEnv_TIME_TO_SECS(20, 0, 0)) { + now_sec += mTM_SECONDS_IN_DAY; + } + + shadow_pos = (f32)(now_sec - mEnv_TIME_TO_SECS(20, 0, 0)) / (f32)((mEnv_TIME_TO_SECS(4, 0, 0) + mTM_SECONDS_IN_DAY) - mEnv_TIME_TO_SECS(20, 0, 0)); + } + + kankyo->shadow_pos = shadow_pos * 200.0f - 100.0f; +} + +static void mEnv_set_time(Kankyo* kankyo) { + rgba_t light_color; + int shadows_affected; + + /* Convert day seconds from [0, 86400) -> [-0.5, 0.5) -> [-32768, 32768) (seconds -> bin-angle) */ + s16 time_angle = ((Common_Get(time).now_sec - mTM_SECONDS_IN_HALFDAY) / (f32)mTM_SECONDS_IN_DAY) * 65536.0f; + f32 sin = sin_s(time_angle); // unused + f32 cos = cos_s(time_angle); // unused + mEnv_MakeShadowInfo(kankyo); + + if ( + Common_Get(clip).effect_clip != NULL && + Common_Get(clip).effect_clip->effect_light_status(&light_color, &shadows_affected) != eEC_LIGHT_COLOR_DISABLED && + shadows_affected == TRUE + ) { + f32 color_add = light_color.r + light_color.g + light_color.b; + f32 adjusted_shadow_alpha = kankyo->shadow_alpha; + + color_add = color_add > 200.0f ? 200.0f : color_add; + + adjusted_shadow_alpha += (color_add / 200.0f) * 110.0f; + adjusted_shadow_alpha = adjusted_shadow_alpha > 255.0f ? 255.0f : adjusted_shadow_alpha; + adjusted_shadow_alpha = adjusted_shadow_alpha < 0.0f ? 0.0f : adjusted_shadow_alpha; + + kankyo->shadow_alpha = adjusted_shadow_alpha; + } + + mNPS_schedule_manager(); // This is a very odd place to put this. It would be better suited in game_play_Move(). +} + +static void mEnv_ChangeRGBLight(u8* dst, u8* src_nxt_w0, u8* src_nxt_w1, u8* src_now_w0, u8* src_now_w1, f32 f0, f32 f1) { + f32 weather_change_bias = l_mEnv_electric_light.change_weather_env_rate; + f32 inverse_weather_change_bias = 1.0f - weather_change_bias; + int i; + + for (i = 0; i < 3; i++) { + dst[0] = + weather_change_bias * (f1 * (src_nxt_w0[0] + f0 * ((f32)src_nxt_w1[0] - (f32)src_nxt_w0[0]))) + + inverse_weather_change_bias * (f1 * (src_now_w0[0] + f0 * ((f32)src_now_w1[0] - (f32)src_now_w0[0]))); + + dst++; + src_nxt_w0++; + src_nxt_w1++; + src_now_w0++; + src_now_w1++; + } +} + +static void mEnv_ChangeDiffuseVctlSet(BaseLight* base_light) { + switch (Save_Get(scene_no)) { + case SCENE_BROKER_SHOP: + case SCENE_BUGGY: + case SCENE_CONVENI: + case SCENE_SUPER: + case SCENE_DEPART: + case SCENE_DEPART_2: + case SCENE_KAMAKURA: + case SCENE_MUSEUM_ROOM_PAINTING: + case SCENE_MUSEUM_ROOM_FOSSIL: + case SCENE_MUSEUM_ROOM_FISH: + 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_LIGHTHOUSE: + { + base_light->sun_dir[0] = 0; // x + base_light->sun_dir[1] = 69; // y + base_light->sun_dir[2] = 97; // z + + base_light->moon_dir[0] = 0; // x + base_light->moon_dir[1] = -33; // y + base_light->moon_dir[2] = 115; // z + + break; + } + + default: + { + f32 dir_x; + f32 dir_y; + f32 dir_z; + + switch (Common_Get(field_draw_type)) { + case FIELD_DRAW_TYPE_TRAIN: + case FIELD_DRAW_TYPE_PLAYER_SELECT: + { + dir_x = 0.0f; + dir_y = 60.0f; + dir_z = 60.0f; + + break; + } + + default: + { + /* second in the day -> [-32768, 32767] */ + s16 bin_sec_radial = ((f32)(Common_Get(time).now_sec - mTM_SECONDS_IN_HALFDAY) / (f32)mTM_SECONDS_IN_HALFDAY) * (SHT_MAX + 1.0f); + + dir_x = sin_s(bin_sec_radial) * 60.0f; + dir_y = cos_s(bin_sec_radial) * 60.0f; + dir_z = cos_s(bin_sec_radial) * 60.0f; + + break; + } + } + + base_light->sun_dir[0] = -dir_x; // x + base_light->sun_dir[1] = dir_y + 30.0f; // y + base_light->sun_dir[2] = dir_z + 20.0f; // z + + base_light->moon_dir[0] = dir_x; // x + base_light->moon_dir[1] = 30.0f - dir_y; // y + base_light->moon_dir[2] = 20.0f - dir_z; // z + + break; + } + } +} + +static void mEnv_ChangeDiffuseLight(BaseLight* dst, BaseLight* src_nxt_w0, BaseLight* src_nxt_w1, BaseLight* src_now_w0, BaseLight* src_now_w1, f32 f0) { + f32 diffuse_light_effect_rate = mEnv_DiffuseLightEffectRate(); + f32 f1; + + mEnv_ChangeDiffuseVctlSet(dst); + if (Common_Get(sunlight_flag) == TRUE) { + add_calc(&l_mEnv_electric_light.sun_percent, 1.0f, 1.0f - sqrtf(0.5), 0.1f, 0.005f); + } + else { + add_calc(&l_mEnv_electric_light.sun_percent, 0.0f, 1.0f - sqrtf(0.5), 0.1f, 0.005f); + } + + mEnv_ChangeRGBLight(dst->sun_color, src_nxt_w0->sun_color, src_nxt_w1->sun_color, src_now_w0->sun_color, src_now_w1->sun_color, f0, l_mEnv_electric_light.sun_percent * diffuse_light_effect_rate * l_mEnv_electric_light.staffroll_fade_rate); + mEnv_ChangeRGBLight(dst->moon_color, src_nxt_w0->moon_color, src_nxt_w1->moon_color, src_now_w0->moon_color, src_now_w1->moon_color, f0, l_mEnv_electric_light.sun_percent * diffuse_light_effect_rate * l_mEnv_electric_light.staffroll_fade_rate); + + if (mRmTp_GetNowSceneLightSwitchIndex() != -1) { + /* If the room has a light switch point light, combine its power with the celestial body colors */ + f32 celestial_adjust = (l_mEnv_electric_light.diffuse_adjust - 1.0f) * l_mEnv_electric_light.point_light_percent + 1.0f; + + dst->sun_color[0] *= celestial_adjust; + dst->sun_color[1] *= celestial_adjust; + dst->sun_color[2] *= celestial_adjust; + + dst->moon_color[0] *= celestial_adjust; + dst->moon_color[1] *= celestial_adjust; + dst->moon_color[2] *= celestial_adjust; + } +} + +static void mEnv_ChangeFogLight(BaseLight* dst, BaseLight* src_nxt_w0, BaseLight* src_nxt_w1, BaseLight* src_now_w0, BaseLight* src_now_w1, f32 f0) { + f32 weather_change_bias = l_mEnv_electric_light.change_weather_env_rate; + f32 inverse_weather_change_bias = 1.0f - weather_change_bias; + f32 f1 = l_mEnv_electric_light.sun_percent * l_mEnv_electric_light.staffroll_fade_rate; + f32 fog_near; + f32 fog_far; + + mEnv_ChangeRGBLight(dst->fog_color, src_nxt_w0->fog_color, src_nxt_w1->fog_color, src_now_w0->fog_color, src_now_w1->fog_color, f0, f1); + + fog_near = weather_change_bias * ((f32)(src_nxt_w0->fog_near & 0x3FF) + f0 * ((f32)(src_nxt_w1->fog_near & 0x3FF) - (f32)(src_nxt_w0->fog_near & 0x3FF))) + + inverse_weather_change_bias * ((f32)(src_now_w0->fog_near & 0x3FF) + f0 * ((f32)(src_now_w1->fog_near & 0x3FF) - (f32)(src_now_w0->fog_near & 0x3FF))); + + dst->fog_near = fog_near; + fog_far = weather_change_bias * ((f32)src_nxt_w0->fog_far + f0 * ((f32)src_nxt_w1->fog_far - (f32)src_nxt_w0->fog_far)) + + inverse_weather_change_bias * ((f32)src_now_w0->fog_far + f0 * ((f32)src_now_w1->fog_far - (f32)src_now_w0->fog_far)); + + dst->fog_far = fog_far; +} + +static void mEnv_CalcSetLight_train(BaseLight* light) { + if (Save_Get(scene_no) == SCENE_START_DEMO || Save_Get(scene_no) == SCENE_START_DEMO3) { + if (l_mEnv_electric_light.sun_percent < 1.0f) { + f32 inv = 1.0f - l_mEnv_electric_light.sun_percent; + int add_r = inv * 35.0f; + int add_g = inv * 30.0f; + int add_b = inv * 40.0f; + + light->ambient_color[0] += (u8)add_r; + light->ambient_color[1] += (u8)add_g; + light->ambient_color[2] += (u8)add_b; + } + } +} + +static void mEnv_CalcSetLight(BaseLight* dst, BaseLight* src_nxt_w0, BaseLight* src_nxt_w1, BaseLight* src_now_w0, BaseLight* src_now_w1, Kankyo* kankyo, f32 f0) { + mEnv_ChangeRGBLight(dst->ambient_color, src_nxt_w0->ambient_color, src_nxt_w1->ambient_color, src_now_w0->ambient_color, src_now_w1->ambient_color, f0, l_mEnv_electric_light.sun_percent * l_mEnv_electric_light.staffroll_fade_rate); + mEnv_CalcSetLight_train(dst); + mEnv_ChangeDiffuseLight(dst, src_nxt_w0, src_nxt_w1, src_now_w0, src_now_w1, f0); + mEnv_ChangeFogLight(dst, src_nxt_w0, src_nxt_w1, src_now_w0, src_now_w1, f0); + + /* @BUG - devs accidently used the wrong light parameter, should've been src_nxt_w1 but wrote src_now_w1 */ + #ifndef BUGFIXES + mEnv_ChangeRGBLight(dst->shadow_color, src_nxt_w0->shadow_color, src_now_w1->shadow_color, src_now_w0->shadow_color, src_now_w1->shadow_color, f0, l_mEnv_electric_light.sun_percent * l_mEnv_electric_light.staffroll_fade_rate); + #else + mEnv_ChangeRGBLight(dst->shadow_color, src_nxt_w0->shadow_color, src_nxt_w1->shadow_color, src_now_w0->shadow_color, src_now_w1->shadow_color, f0, l_mEnv_electric_light.sun_percent * l_mEnv_electric_light.staffroll_fade_rate); + #endif + mEnv_ChangeRGBLight(dst->room_color, src_nxt_w0->room_color, src_nxt_w1->room_color, src_now_w0->room_color, src_now_w1->room_color, f0, l_mEnv_electric_light.sun_percent * l_mEnv_electric_light.staffroll_fade_rate); + mEnv_ChangeRGBLight(dst->sun_color_window, src_nxt_w0->sun_color_window, src_nxt_w1->sun_color_window, src_now_w0->sun_color_window, src_now_w1->sun_color_window, f0, l_mEnv_electric_light.sun_percent * l_mEnv_electric_light.staffroll_fade_rate); + mEnv_ChangeRGBLight(dst->moon_color_window, src_nxt_w0->moon_color_window, src_nxt_w1->moon_color_window, src_now_w0->moon_color_window, src_now_w1->moon_color_window, f0, l_mEnv_electric_light.sun_percent * l_mEnv_electric_light.staffroll_fade_rate); + mEnv_ChangeRGBLight(dst->background_color, src_nxt_w0->background_color, src_nxt_w1->background_color, src_now_w0->background_color, src_now_w1->background_color, f0, l_mEnv_electric_light.sun_percent * l_mEnv_electric_light.staffroll_fade_rate); +} + +static int mEnv_GetNowTerm() { + int now_sec = Common_Get(time).now_sec; + int i; + + for (i = 0; i < mEnv_TERM_NUM; i++) { + if (klight_chg_time[i + 1] >= now_sec) { + return i; + } + } + + return 0; +} + +static void mEnv_SetBaseLight(Kankyo* kankyo) { + int now_sec = Common_Get(time).now_sec; + int term = mEnv_GetNowTerm(); + int weather = l_mEnv_electric_light.now_weather; + int fog_disabled = TRUE; + int next_term = term + 1; + f32 percent_towards_next_term = get_percent(klight_chg_time[next_term], klight_chg_time[term], now_sec); + + switch (Common_Get(field_draw_type)) { + case FIELD_DRAW_TYPE_TRAIN: + { + int next_term = (term + 1) % mEnv_TERM_NUM; + BaseLight* src_w1 = l_mEnv_normal_kcolor_data[weather] + next_term; + BaseLight* src_w0 = l_mEnv_normal_kcolor_data[weather] + term; + + mEnv_CalcSetLight(&kankyo->base_light, src_w0, src_w1, src_w0, src_w1, kankyo, percent_towards_next_term); + break; + } + + case FIELD_DRAW_TYPE_PLAYER_SELECT: + { + mEnv_CalcSetLight(&kankyo->base_light, &l_mEnv_kcolor_data_p_sel, &l_mEnv_kcolor_data_p_sel, &l_mEnv_kcolor_data_p_sel, &l_mEnv_kcolor_data_p_sel, kankyo, 0.5f); + l_mEnv_electric_light.shadow_alpha = 200; + + break; + } + + default: + { + if (Save_Get(scene_no) == SCENE_CONVENI || Save_Get(scene_no) == SCENE_SUPER || Save_Get(scene_no) == SCENE_DEPART || Save_Get(scene_no) == SCENE_DEPART_2) { + mEnv_CalcSetLight(&kankyo->base_light, &l_mEnv_kcolor_shop, &l_mEnv_kcolor_shop, &l_mEnv_kcolor_shop, &l_mEnv_kcolor_shop, kankyo, 0.5f); + l_mEnv_electric_light.shadow_alpha = 150; + } + else if (Save_Get(scene_no) == SCENE_BUGGY) { + mEnv_CalcSetLight(&kankyo->base_light, &l_mEnv_kcolor_buggy, &l_mEnv_kcolor_buggy, &l_mEnv_kcolor_buggy, &l_mEnv_kcolor_buggy, kankyo, 0.5f); + l_mEnv_electric_light.shadow_alpha = 150; + } + else if (Save_Get(scene_no) == SCENE_KAMAKURA) { + mEnv_CalcSetLight(&kankyo->base_light, &l_mEnv_kcolor_kamakura, &l_mEnv_kcolor_kamakura, &l_mEnv_kcolor_kamakura, &l_mEnv_kcolor_kamakura, kankyo, 0.5f); + l_mEnv_electric_light.shadow_alpha = 150; + } + else if (Save_Get(scene_no) == SCENE_BROKER_SHOP) { + mEnv_CalcSetLight(&kankyo->base_light, &l_mEnv_kcolor_broker, &l_mEnv_kcolor_broker, &l_mEnv_kcolor_broker, &l_mEnv_kcolor_broker, kankyo, 0.5f); + l_mEnv_electric_light.shadow_alpha = 150; + } + else if (Save_Get(scene_no) == SCENE_MUSEUM_ROOM_FISH) { + mEnv_CalcSetLight(&kankyo->base_light, &l_mEnv_kcolor_museum_fish, &l_mEnv_kcolor_museum_fish, &l_mEnv_kcolor_museum_fish, &l_mEnv_kcolor_museum_fish, kankyo, 0.5f); + l_mEnv_electric_light.shadow_alpha = 150; + } + else if (Save_Get(scene_no) == SCENE_MUSEUM_ROOM_FOSSIL) { + mEnv_CalcSetLight(&kankyo->base_light, &l_mEnv_kcolor_museum_fossil, &l_mEnv_kcolor_museum_fossil, &l_mEnv_kcolor_museum_fossil, &l_mEnv_kcolor_museum_fossil, kankyo, 0.5f); + l_mEnv_electric_light.shadow_alpha = 150; + } + else if (Save_Get(scene_no) == SCENE_MUSEUM_ROOM_PAINTING) { + mEnv_CalcSetLight(&kankyo->base_light, &l_mEnv_kcolor_museum_picture, &l_mEnv_kcolor_museum_picture, &l_mEnv_kcolor_museum_picture, &l_mEnv_kcolor_museum_picture, kankyo, 0.5f); + l_mEnv_electric_light.shadow_alpha = 150; + } + else if (Save_Get(scene_no) == SCENE_MY_ROOM_BASEMENT_S || Save_Get(scene_no) == SCENE_MY_ROOM_BASEMENT_M || Save_Get(scene_no) == SCENE_MY_ROOM_BASEMENT_L || Save_Get(scene_no) == SCENE_MY_ROOM_BASEMENT_LL1) { + mEnv_CalcSetLight(&kankyo->base_light, &l_mEnv_kcolor_basement, &l_mEnv_kcolor_basement, &l_mEnv_kcolor_basement, &l_mEnv_kcolor_basement, kankyo, 0.5f); + l_mEnv_electric_light.shadow_alpha = 150; + } + else if (Save_Get(scene_no) == SCENE_LIGHTHOUSE) { + mEnv_CalcSetLight(&kankyo->base_light, &l_mEnv_kcolor_lighthouse, &l_mEnv_kcolor_lighthouse, &l_mEnv_kcolor_lighthouse, &l_mEnv_kcolor_lighthouse, kankyo, 0.5f); + l_mEnv_electric_light.shadow_alpha = 115; + } + else if (Save_Get(scene_no) == SCENE_MUSEUM_ROOM_INSECT) { + BaseLight* now = l_mEnv_normal_kcolor_insect_data[l_mEnv_electric_light.now_weather]; + BaseLight* nxt = l_mEnv_normal_kcolor_insect_data[l_mEnv_electric_light.next_weather]; + int next_term = (term + 1) % mEnv_TERM_NUM; + BaseLight* nxt_w0 = nxt + term; + BaseLight* nxt_w1 = nxt + next_term; + BaseLight* now_w0 = now + term; + BaseLight* now_w1 = now + next_term; + + mEnv_CalcSetLight( + &kankyo->base_light, + nxt_w0, + nxt_w1, + now_w0, + now_w1, + kankyo, + percent_towards_next_term + ); + } + else { + BaseLight* now = l_mEnv_normal_kcolor_data[l_mEnv_electric_light.now_weather]; + BaseLight* nxt = l_mEnv_normal_kcolor_data[l_mEnv_electric_light.next_weather]; + int next_term = (term + 1) % mEnv_TERM_NUM; + BaseLight* nxt_w0 = nxt + term; + BaseLight* nxt_w1 = nxt + next_term; + BaseLight* now_w0 = now + term; + BaseLight* now_w1 = now + next_term; + + mEnv_CalcSetLight( + &kankyo->base_light, + nxt_w0, + nxt_w1, + now_w0, + now_w1, + kankyo, + percent_towards_next_term + ); + } + + if (Common_Get(field_type) == mFI_FIELDTYPE2_FG) { + fog_disabled = FALSE; + } + + break; + } + } + + if (fog_disabled == TRUE) { + kankyo->base_light.fog_color[2] = 0; + kankyo->base_light.fog_color[1] = 0; + kankyo->base_light.fog_color[0] = 0; + kankyo->base_light.fog_near = 2020; + kankyo->base_light.fog_far = 1000; + } +} + +static u8 mEnv_LimitChkRGBColor(int c) { + if (c > 255) { + c = 255; + } + else if (c < 0) { + c = 0; + } + + return c; +} + +static void mEnv_AddAndSetRGBColor(u8* dst, u8* src0, s16* src1) { + int i; + + for (i = 0; i < 3; i++) { + dst[0] = mEnv_LimitChkRGBColor(src0[0] + src1[0]); + + dst++; + src0++; + src1++; + } +} + +static void mEnv_SetDiffuseLight(Kankyo* kankyo) { + mEnv_AddAndSetRGBColor(kankyo->sun_light.lights.diffuse.color, kankyo->base_light.sun_color, kankyo->add_light_info.diffuse_color); + mEnv_AddAndSetRGBColor(kankyo->moon_light.lights.diffuse.color, kankyo->base_light.moon_color, l_mEnv_electric_light.add_moon_color); + + kankyo->sun_light.lights.diffuse.x = kankyo->base_light.sun_dir[0]; + kankyo->sun_light.lights.diffuse.y = kankyo->base_light.sun_dir[1]; + kankyo->sun_light.lights.diffuse.z = kankyo->base_light.sun_dir[2]; + + kankyo->moon_light.lights.diffuse.x = kankyo->base_light.moon_dir[0]; + kankyo->moon_light.lights.diffuse.y = kankyo->base_light.moon_dir[1]; + kankyo->moon_light.lights.diffuse.z = kankyo->base_light.moon_dir[2]; +} + +static void mEnv_SetFog(Kankyo* kankyo, Global_light* global_light) { + int field_id = mFI_GetFieldId(); + int fog_near; + int fog_far; + + mEnv_AddAndSetRGBColor(global_light->fogColor, kankyo->base_light.fog_color, kankyo->add_light_info.fog_color); + + fog_near = kankyo->base_light.fog_near + kankyo->add_light_info.fog_near; + if (fog_near <= mEnv_FOG_NEAR_MAX) { + global_light->fogNear = fog_near; + } + else { + global_light->fogNear = mEnv_FOG_NEAR_MAX; + } + + fog_far = kankyo->base_light.fog_far + kankyo->add_light_info.fog_far; + if (fog_far <= mEnv_FOG_FAR_MAX) { + global_light->fogFar = fog_far; + } + else { + global_light->fogFar = mEnv_FOG_FAR_MAX; + } + + if (mFI_GET_TYPE(field_id) != mFI_FIELD_FG) { + global_light->fogFar = 1000; + global_light->fogNear = 1000; + } +} + +static void mEnv_PermitCheckDiffuseLight(Kankyo* kankyo) { + if ( + kankyo->sun_light.lights.diffuse.x == 0 && + kankyo->sun_light.lights.diffuse.y == 0 && + kankyo->sun_light.lights.diffuse.z == 0 + ) { + kankyo->sun_light.lights.diffuse.x = 1; + } + + if ( + kankyo->moon_light.lights.diffuse.x == 0 && + kankyo->moon_light.lights.diffuse.y == 0 && + kankyo->moon_light.lights.diffuse.z == 0 + ) { + kankyo->moon_light.lights.diffuse.x = 1; + } +} + +extern void mEnv_GetRoomPrimColor(u8* r, u8* g, u8* b, GAME_PLAY* play) { + u8 color[3]; + + f32 point_light_percent = l_mEnv_electric_light.point_light_percent; + f32 diffuse_light_effect_rate = mEnv_DiffuseLightEffectRate(); + int c; + f32 f0 = 1.0f + point_light_percent * -0.3f; + f32 f1 = point_light_percent * 0.6f; + s16 flame = l_mEnv_electric_light.point_light_is_flame; + u8* point_light_color = l_mEnv_electric_light.point_light_color; + u8* room_color = play->kankyo.base_light.room_color; + int i; + + for (i = 0; i < 3; i++) { + + if (flame) { + c = (point_light_color[0] >> 1) + (room_color[0] >> 1); // take the average + } + else { + c = room_color[0] * f0 * diffuse_light_effect_rate + point_light_color[0] * f1; + } + + if (c < 0) { + c = 0; + } + else if (c >= 256) { + c = 255; + } + + color[i] = c; + + point_light_color++; + room_color++; + } + + r[0] = color[0]; + g[0] = color[1]; + b[0] = color[2]; +} + +extern void Global_kankyo_set_room_prim(GAME_PLAY* play) { + u8 r; + u8 g; + u8 b; + GRAPH* graph; + + mEnv_GetRoomPrimColor(&r, &g, &b, play); + + { + graph = play->game.graph; + OPEN_DISP(graph); + + gDPPipeSync(NOW_POLY_OPA_DISP++); + gDPSetPrimColor(NOW_POLY_OPA_DISP++, 0, 128, r, g, b, 255); + gDPPipeSync(NOW_POLY_XLU_DISP++); + gDPSetPrimColor(NOW_POLY_XLU_DISP++, 0, 128, r, g, b, 255); + gDPPipeSync(NOW_BG_OPA_DISP++); + gDPSetPrimColor(NOW_BG_OPA_DISP++, 0, 128, r, g, b, 255); + + CLOSE_DISP(graph); + } +} + +static void mEnv_check_countdown_start(GAME_PLAY* play) { + if (mEv_check_status(mEv_EVENT_NEW_YEARS_EVE_COUNTDOWN, mEv_STATUS_PLAYSOUND) == FALSE) { + int bx; + int bz; + + mFI_BlockKind2BkNum(&bx, &bz, mRF_BLOCKKIND_POOL); + + if (bx != play->block_table.block_x || bz != play->block_table.block_z) { + if (Common_Get(time).now_sec >= mEnv_TIME_TO_SECS(23, 59, 0)) { + mEv_set_status(mEv_EVENT_NEW_YEARS_EVE_COUNTDOWN, mEv_STATUS_PLAYSOUND); + } + } + } +} + +static void mEnv_countdown_proc(GAME_PLAY* play) { + if (Common_Get(field_draw_type) == FIELD_DRAW_TYPE_TRAIN || Common_Get(field_draw_type) == FIELD_DRAW_TYPE_PLAYER_SELECT) { + return; + } + + if (mEv_check_status(mEv_EVENT_NEW_YEARS_EVE_COUNTDOWN, mEv_STATUS_ACTIVE) == TRUE) { + mEnv_check_countdown_start(play); + + if (mEv_check_status(mEv_EVENT_NEW_YEARS_EVE_COUNTDOWN, mEv_STATUS_PLAYSOUND) == TRUE) { + u8 countdown_timer; + u8 now_countdown = play->kankyo.countdown_timer; + + if (Common_Get(time.rtc_time).month != lbRTC_DECEMBER) { + countdown_timer = 0; + } + else { + countdown_timer = mTM_SECONDS_IN_DAY - Common_Get(time).now_sec; + } + + if (countdown_timer != now_countdown) { + u16 sfx; + + if (countdown_timer == 0) { + sfx = 0x151; + } + else if (countdown_timer <= 10) { + sfx = 0x150; + } + else { + sfx = 0x431; + } + + sAdo_SysTrgStart(sfx); + play->kankyo.countdown_timer = countdown_timer; + } + } + } +} + +extern int mEnv_RequestChangeLightON(GAME_PLAY* play, int light_on_type, int play_sfx) { + if (mRmTp_NowSceneLightSwitchON()) { + l_mEnv_electric_light.point_light_on_type = light_on_type; + + if (light_on_type == mEnv_LIGHT_TYPE_PLAYER) { + PLAYER_ACTOR* player = get_player_actor_withoutCheck(play); // unused + + l_mEnv_electric_light.light_animating_on = TRUE; + l_mEnv_electric_light.light_anime_frame = 0; + + if (play_sfx == TRUE) { + sAdo_SysTrgStart(0x16); + } + } + + return TRUE; + } + return FALSE; +} + +extern int mEnv_RequestChangeLightOFF(GAME_PLAY* play, int light_off_type, f32 step) { + if (mRmTp_NowSceneLightSwitchOFF()) { + l_mEnv_electric_light.point_light_off_type = light_off_type; + l_mEnv_electric_light.point_light_off_step = ABS(step); + + if (light_off_type == mEnv_LIGHT_TYPE_PLAYER) { + PLAYER_ACTOR* player = get_player_actor_withoutCheck(play); // unused + + sAdo_SysTrgStart(0x17); + } + return TRUE; + } + + return FALSE; +} + +static void mEnv_LightAnimeToSwitchON() { + static f32 switch_on_anime_percent_table[mEnv_LIGHT_ANIME_FRAMES] = { + 0.00f, + 0.05f, + 0.10f, + 0.15f, + 0.20f, + 0.25f, + 0.30f, + 0.25f, + 0.20f, + 0.15f, + 0.10f, + 0.30f, + 0.35f, + 0.40f, + 0.45f, + 0.50f, + 0.45f, + 0.40f, + 0.35f, + 0.30f + }; + + int frame = l_mEnv_electric_light.light_anime_frame; + + if (frame >= mEnv_LIGHT_ANIME_FRAMES) { + l_mEnv_electric_light.light_animating_on = FALSE; + return; + } + + l_mEnv_electric_light.point_light_percent = l_mEnv_electric_light.point_light_min + (1.0f - l_mEnv_electric_light.point_light_min) * switch_on_anime_percent_table[frame]; + l_mEnv_electric_light.light_anime_frame++; +} + +extern void mEnv_ManagePointLight(GAME_PLAY* play, Kankyo* kankyo, Global_light* global_light) { + PLAYER_ACTOR* player = get_player_actor_withoutCheck(play); // unused + + int lightswitch_on = mRmTp_Index2LightSwitchStatus(mRmTp_GetNowSceneLightSwitchIndex()); + + if (lightswitch_on) { + if (l_mEnv_electric_light.light_animating_on == TRUE) { + mEnv_LightAnimeToSwitchON(); + } + else { + if (l_mEnv_electric_light.point_light_on_type == mEnv_LIGHT_TYPE_LIGHTHOUSE) { + add_calc(&l_mEnv_electric_light.point_light_percent, 1.0f, 0.02f, 0.02f, 0.00007f); + } + else { + add_calc(&l_mEnv_electric_light.point_light_percent, 1.0f, 0.01f, 0.01f, 0.01f); + } + + if (chkTrigger(BUTTON_Z) && mRmTp_PleaseDrawLightSwitch()) { + mEnv_RequestChangeLightOFF(play, mEnv_LIGHT_TYPE_PLAYER, 0.0f); + } + } + } + else { + mActor_name_t field_id = mFI_GetFieldId(); + + if (l_mEnv_electric_light.point_light_off_type == mEnv_LIGHT_TYPE_PLAYER) { + add_calc(&l_mEnv_electric_light.point_light_percent, l_mEnv_electric_light.point_light_min, 0.2f, 0.2f, 0.02f); + } + else { + l_mEnv_electric_light.point_light_percent -= l_mEnv_electric_light.point_light_off_step; + + if (l_mEnv_electric_light.point_light_percent < l_mEnv_electric_light.point_light_min) { + l_mEnv_electric_light.point_light_percent = l_mEnv_electric_light.point_light_min; + } + else if (l_mEnv_electric_light.point_light_percent > 1.0f) { + l_mEnv_electric_light.point_light_percent = 1.0f; + } + } + + if (chkTrigger(BUTTON_Z) && mRmTp_PleaseDrawLightSwitch()) { + mEnv_RequestChangeLightON(play, mEnv_LIGHT_TYPE_PLAYER, TRUE); + } + else if (mFI_GET_TYPE(field_id) == mFI_FIELD_NPCROOM0 && Common_Get(last_scene_no) == SCENE_FG) { + mEnv_CheckNpcRoomPointLightNiceStatus(); + } + } + + if (mRmTp_GetNowSceneLightSwitchIndex() != -1) { + u8* color = play->kankyo.point_light.lights.point.color; + int i; + + for (i = 0; i < 3; i++) { + color[i] = l_mEnv_electric_light.point_light_color[i] * l_mEnv_electric_light.point_light_percent; + } + } +} + +static void mEnv_ManageChangeWeatherEnvRate() { + if (l_mEnv_electric_light.now_weather != l_mEnv_electric_light.next_weather) { + l_mEnv_electric_light.change_weather_env_rate += (1.0f / 600.0f); + + if (l_mEnv_electric_light.change_weather_env_rate >= 1.0f) { + l_mEnv_electric_light.change_weather_env_rate = 1.0f; + + if (aWeather_ChangingWeather() == FALSE) { + l_mEnv_electric_light.now_weather = l_mEnv_electric_light.next_weather; + l_mEnv_electric_light.change_weather_env_rate = 0.0f; + } + } + } + else { + l_mEnv_electric_light.change_weather_env_rate = 0.0f; + + if (aWeather_ChangingWeather() == FALSE) { + l_mEnv_electric_light.now_weather = Common_Get(weather); + l_mEnv_electric_light.next_weather = Common_Get(weather); + } + } +} + +static void mEnv_JudgeSwitchStatus() { + switch (l_mEnv_electric_light.switch_status) { + case mEnv_SWITCH_STATUS_ON: + l_mEnv_electric_light.switch_status = mEnv_SWITCH_STATUS_TURNING_OFF; + break; + + case mEnv_SWITCH_STATUS_OFF: + l_mEnv_electric_light.switch_status = mEnv_SWITCH_STATUS_TURNING_ON; + break; + + case mEnv_SWITCH_STATUS_TURNING_OFF: + if (mRmTp_Index2LightSwitchStatus(mRmTp_GetNowSceneLightSwitchIndex()) == FALSE) { + l_mEnv_electric_light.switch_status = mEnv_SWITCH_STATUS_OFF; + } + break; + + case mEnv_SWITCH_STATUS_TURNING_ON: + if (mRmTp_Index2LightSwitchStatus(mRmTp_GetNowSceneLightSwitchIndex()) != FALSE) { + l_mEnv_electric_light.switch_status = mEnv_SWITCH_STATUS_ON; + } + break; + } +} + +static void mEnv_rainbow_power_calc() { + if ( + Save_Get(rainbow_reserved) && + mFI_CheckFieldData() && + mFI_GET_TYPE(mFI_GetFieldId()) == mFI_FIELD_FG && + mEv_CheckTitleDemo() <= 0 && + Common_Get(time.rtc_time).month == Save_Get(rainbow_month) && + Common_Get(time.rtc_time).day == Save_Get(rainbow_day) && + Common_Get(time).now_sec >= mEnv_RAINBOW_TIME_START && Common_Get(time).now_sec < mEnv_RAINBOW_TIME_END && + Common_Get(time).season == mTM_SEASON_SUMMER + ) { + if (chase_f(Common_GetPointer(rainbow_opacity), 1.0f, (1.0f / 1800.0f)) != FALSE) { + Save_Set(rainbow_reserved, FALSE); // rainbow has been shown + } + } + else { + chase_f(Common_GetPointer(rainbow_opacity), 0.0f, (1.0f / 108000.0f)); // slowly fade out rainbow + } +} + +static void mEnv_TaimatuPointLightWaveMoveProc(GAME_PLAY* play); +static void mEnv_CheckNpcLight_ToSwitchON(GAME_PLAY* play); + +extern void Global_kankyo_set(GAME_PLAY* play, Kankyo* kankyo, Global_light* global_light) { + mEnv_JudgeSwitchStatus(); + mEnv_ManageChangeWeatherEnvRate(); + mEnv_set_time(kankyo); + mEnv_SetBaseLight(kankyo); + mEnv_AddAndSetRGBColor(global_light->ambientColor, kankyo->base_light.ambient_color, kankyo->add_light_info.ambient_color); + mEnv_SetDiffuseLight(kankyo); + mEnv_SetFog(kankyo, global_light); + mEnv_PermitCheckDiffuseLight(kankyo); + mEnv_TaimatuPointLightWaveMoveProc(play); + mEnv_CheckNpcLight_ToSwitchON(play); + mEnv_countdown_proc(play); + mEnv_MakeWindowLightAlpha(TRUE); + mEnv_rainbow_power_calc(); + + if (l_mEnv_electric_light._98 < 10) { + l_mEnv_electric_light._98++; + } +} + +static int mEnv_CheckNpcRoomPointLightNiceStatus() { + mNPS_schedule_c* schedule; + Animal_c* animal; + + if (Save_Get(scene_no) == SCENE_COTTAGE_NPC) { + animal = Save_GetPointer(island.animal); + schedule = Common_GetPointer(npc_schedule[ANIMAL_NUM_MAX]); + + if (schedule != NULL) { + if ( + schedule->current_type == mNPS_SCHED_IN_HOUSE && + animal->is_home == TRUE && + (Common_Get(time).now_sec < mEnv_NPC_LIGHTS_OFF_TIME || Common_Get(time).now_sec >= mEnv_NPC_LIGHTS_ON_TIME) + ) { + return TRUE; + } + } + } + else { + animal = mNpc_GetAnimalInfoP(Common_Get(house_owner_name)); + + if ( + animal != NULL + ) { + schedule = mNPS_get_schedule_area(&animal->id); + + if (schedule != NULL) { + if ( + schedule->current_type == mNPS_SCHED_IN_HOUSE && + animal->is_home == TRUE && + (Common_Get(time).now_sec < mEnv_NPC_LIGHTS_OFF_TIME || Common_Get(time).now_sec >= mEnv_NPC_LIGHTS_ON_TIME) + ) { + return TRUE; + } + } + } + } + + return FALSE; +} + +static void mEnv_TaimatuPointLightWaveMoveProc(GAME_PLAY* play) { + static s16 point_light_wave_counter; + u8* point_light_color; + + point_light_wave_counter += 400; + point_light_color = l_mEnv_electric_light.point_light_color; + + if (l_mEnv_electric_light.point_light_is_flame) { + f32 wave = sin_s(point_light_wave_counter); + u8 c; + + if (wave >= 0.0f) { + wave = sin_s(point_light_wave_counter); + } + else { + wave = -sin_s(point_light_wave_counter); + } + + c = (wave * 40.0f) + 40.0f; + point_light_color[0] = 255 - c; // r + point_light_color[1] = 240 - c; // g + } +} + +static void mEnv_CheckNpcLight_ToSwitchON(GAME_PLAY* play) { + // stubbed +} + +static void mEnv_PointLightSet(GAME_PLAY* play, f32 fade_rate) { + PLAYER_ACTOR* player = get_player_actor_withoutCheck(play); + s16* kk_event_data = (s16*)mEv_get_save_area(mEv_EVENT_KK_SLIDER, 10); + + Light_point_ct( + &play->kankyo.point_light, + player->actor_class.world.position.x, + player->actor_class.world.position.y, + player->actor_class.world.position.z - 25.0f, + 255, + 255, + 220, + (f32)kk_event_data[0] * (1.0f - fade_rate) + ); + + l_mEnv_electric_light.point_light_color[0] = 255; + l_mEnv_electric_light.point_light_color[1] = 255; + l_mEnv_electric_light.point_light_color[2] = 220; +} + +static Light_list* S_get_light_list; + +extern void staffroll_light_init(GAME_PLAY* play) { + l_mEnv_electric_light.staffroll_fade_rate = 1.0f; + mEnv_PointLightSet(play, 1.0f); + S_get_light_list = Global_light_list_new(play, &play->global_light, &play->kankyo.point_light); +} + +static void mEnv_DecideStaffrollFadeOutRate() { + l_mEnv_electric_light.staffroll_fade_rate -= 1.0f / (((f32)GETREG(CRV, 91) * 0.01f + 2.8f) * 60.0f); + + if (l_mEnv_electric_light.staffroll_fade_rate <= 0.0f) { + l_mEnv_electric_light.staffroll_fade_rate = 0.0f; + } +} + +static void mEnv_DecideStaffrollFadeInRate() { + l_mEnv_electric_light.staffroll_fade_rate += 1.0f / (((f32)GETREG(CRV, 91) * 0.01f + 2.8f) * 60.0f); + + if (l_mEnv_electric_light.staffroll_fade_rate > 1.0f) { + l_mEnv_electric_light.staffroll_fade_rate = 1.0f; + } +} + +extern void staffroll_light_proc_start(GAME_PLAY* play) { + mEnv_DecideStaffrollFadeOutRate(); + mEnv_PointLightSet(play, l_mEnv_electric_light.staffroll_fade_rate); +} + +extern int staffroll_light_proc_end(GAME_PLAY* play) { + mEnv_DecideStaffrollFadeInRate(); + mEnv_PointLightSet(play, l_mEnv_electric_light.staffroll_fade_rate); + + return l_mEnv_electric_light.staffroll_fade_rate == 1.0f; +} + +extern void staffroll_light_dt(GAME_PLAY* play) { + Global_light_list_delete(&play->global_light, S_get_light_list); +} + +extern void mEnv_GetShadowPrimColor_Light(u8* r, u8* g, u8* b, GAME* game) { + GAME_PLAY* play = (GAME_PLAY*)game; + + r[0] = play->kankyo.base_light.shadow_color[0]; + g[0] = play->kankyo.base_light.shadow_color[1]; + b[0] = play->kankyo.base_light.shadow_color[2]; +} + +static int mEnv_Pointlight_on_check() { + return (l_mEnv_electric_light.point_light_percent <= l_mEnv_electric_light.point_light_min) ? FALSE : TRUE; +} + +extern int mEnv_PointLightMin() { + return l_mEnv_electric_light.point_light_percent <= l_mEnv_electric_light.point_light_min; +} + +/* @unused @fabricated - likely incorrect, real size is 0x68 (DnM+), this is 0x44 */ +extern MATCH_FORCESTRIP int mEnv_HereIsPlayerSelect() { + static int place_chk[4] = { SCENE_PLAYERSELECT, SCENE_PLAYERSELECT_2, SCENE_PLAYERSELECT_3, SCENE_PLAYERSELECT_SAVE }; + + int i; + + for (i = 0; i < 4; i++) { + if (place_chk[i] == Save_Get(scene_no)) { + return TRUE; + } + } + + return FALSE; +} + +static void mEnv_MakeWindowLightAlpha(int enabled) { + f32 step = 1.0f / 100.0f; + f32 target = 0.0f; + + if (Common_Get(field_draw_type) == FIELD_DRAW_TYPE_INDOORS) { + int switch_idx = mRmTp_GetNowSceneLightSwitchIndex(); + + if (enabled == FALSE) { + l_mEnv_electric_light.windowlight_alpha = 0.0f; + step = 1.0f; + } + + if ( + ABS((s16)Common_Get(time).now_sec) < 120 || + ABS((s16)(Common_Get(time).now_sec - mTM_SECONDS_IN_DAY)) < 120 || + ABS((s16)(Common_Get(time).now_sec - mTM_SECONDS_IN_HALFDAY)) < 120 + ) { + target = 0.0f; + } + else if (switch_idx != -1) { + target = (1.0f - l_mEnv_electric_light.point_light_percent) * 0.78f + 0.22f; + } + else if (Common_Get(time).now_sec >= mEnv_NPC_LIGHTS_OFF_TIME && Common_Get(time).now_sec < mEnv_NPC_LIGHTS_ON_TIME) { + target = 1.0f; + } + + add_calc(&l_mEnv_electric_light.windowlight_alpha, target, 1.0f - sqrtf(0.8), 0.5f * step, 0.5f * step); + } +} + +extern f32 mKK_windowlight_alpha_get() { + return l_mEnv_electric_light.windowlight_alpha; +} + +extern int mEnv_ReqeustChangeWeatherEnviroment(s16 now_weather, s16 next_weather) { + if (l_mEnv_electric_light.now_weather == l_mEnv_electric_light.next_weather) { + if (l_mEnv_normal_kcolor_data[now_weather & 3] != l_mEnv_normal_kcolor_data[next_weather & 3]) { + l_mEnv_electric_light.change_weather_env_rate = 0.0f; + l_mEnv_electric_light.now_weather = now_weather & 3; + l_mEnv_electric_light.next_weather = next_weather & 3; + } + + return TRUE; + } + + return FALSE; +} + +extern int mEnv_ReservePointLight(GAME_PLAY* play, xyz_t* pos, u8 r, u8 g, u8 b, s16 power) { + Light_list* list; + Lights* point_light; + int i; + + for (i = 0; i < mEnv_POINT_LIGHT_NUM; i++) { + if (l_mEnv_electric_light.point_light_list_buf[i] == NULL) { + point_light = &l_mEnv_electric_light.point_lights[i]; + + Light_point_ct(point_light, pos->x, pos->y, pos->z, r, g, b, power); + list = Global_light_list_new(play, &play->global_light, point_light); + + if (list != NULL) { + l_mEnv_electric_light.point_light_list_buf[i] = list; + return i; + } + } + } + + return -1; +} + +extern void mEnv_OperateReservedPointLight_Position(int point_light_idx, xyz_t* pos) { + if (point_light_idx >= 0 && point_light_idx < mEnv_POINT_LIGHT_NUM) { + Lights* l = &l_mEnv_electric_light.point_lights[point_light_idx]; + + l->lights.point.x = pos->x; + l->lights.point.y = pos->y; + l->lights.point.z = pos->z; + } +} + +extern void mEnv_OperateReservedPointLight_Color(int point_light_idx, u8 r, u8 g, u8 b) { + if (point_light_idx >= 0 && point_light_idx < mEnv_POINT_LIGHT_NUM) { + Lights* l = &l_mEnv_electric_light.point_lights[point_light_idx]; + + l->lights.point.color[0] = r; + l->lights.point.color[1] = g; + l->lights.point.color[2] = b; + } +} + +extern void mEnv_OperateReservedPointLight_Power(int point_light_idx, s16 power) { + if (point_light_idx >= 0 && point_light_idx < mEnv_POINT_LIGHT_NUM) { + Lights* l = &l_mEnv_electric_light.point_lights[point_light_idx]; + + l->lights.point.radius = power; + } +} + +extern void mEnv_OperateReservedPointLight(int point_light_idx, xyz_t* pos, u8 r, u8 g, u8 b, s16 power) { + mEnv_OperateReservedPointLight_Position(point_light_idx, pos); + mEnv_OperateReservedPointLight_Color(point_light_idx, r, g, b); + mEnv_OperateReservedPointLight_Power(point_light_idx, power); +} + +extern int mEnv_CancelReservedPointLight(int point_light_idx, GAME_PLAY* play) { + if (point_light_idx >= 0 && point_light_idx < mEnv_POINT_LIGHT_NUM) { + Light_list** list = l_mEnv_electric_light.point_light_list_buf; + + Global_light_list_delete(&play->global_light, list[point_light_idx]); + list[point_light_idx] = NULL; + point_light_idx = -1; + } + + return point_light_idx; +} diff --git a/rel/m_kankyo_weather.c_inc b/rel/m_kankyo_weather.c_inc new file mode 100644 index 00000000..f102be81 --- /dev/null +++ b/rel/m_kankyo_weather.c_inc @@ -0,0 +1,554 @@ +extern void mEnv_DecideWindDirect(s_xyz* dir, s16 x, s16 z) { + xyz_t wind_dir = { 0.0f, -100.0f, 0.0f }; + f32 x_f = x; + f32 z_f = z; + s16 rot_x = (RANDOM_F(x_f) - x_f); // range of [-x, x) + s16 rot_z = (RANDOM_F(z_f) - z_f); // range of [-z, z) + + sMath_RotateX(&wind_dir, SHORTANGLE2RAD(rot_x)); + sMath_RotateZ(&wind_dir, SHORTANGLE2RAD(rot_z)); + + dir->x = wind_dir.x; + dir->y = wind_dir.y; + dir->z = wind_dir.z; +} + +static int mEnv_GetWeatherChangeStep() { + static u8 weather_term_table[mEnv_WEATHER_TERM_NUM][2] = { + { lbRTC_JANUARY, 7 }, // January 1st - January 7th + { lbRTC_FEBRUARY, 24 }, // January 8th - February 24th + { lbRTC_MARCH, 31 }, // February 25th - March 31st + { lbRTC_APRIL, 4 }, // April 1st - April 4th + { lbRTC_APRIL, 7 }, // April 5th - April 7th + { lbRTC_APRIL, 8 }, // April 8th - April 8th + { lbRTC_APRIL, 19 }, // April 9th - April 19th + { lbRTC_APRIL, 20 }, // April 20th - April 20th + { lbRTC_JUNE, 25 }, // April 21st - June 25th + { lbRTC_JULY, 15 }, // June 26th - July 15th + { lbRTC_AUGUST, 31 }, // July 16th - August 31st + { lbRTC_SEPTEMBER, 30 }, // September 1st - September 30th + { lbRTC_OCTOBER, 30 }, // October 1st - October 30th + { lbRTC_OCTOBER, 31 }, // October 31st - Octber 31st + { lbRTC_NOVEMBER, 15 }, // November 1st - November 15th + { lbRTC_DECEMBER, 9 }, // November 16th - December 9th + { lbRTC_DECEMBER, 10 }, // December 10th - December 10th + { lbRTC_DECEMBER, 23 }, // December 11th - December 23rd + { lbRTC_DECEMBER, 30 }, // December 24th - December 30th + { lbRTC_DECEMBER, 31 } // December 31st - December 31st + }; + + lbRTC_month_t month = Common_Get(time.rtc_time).month; + lbRTC_day_t day = Common_Get(time.rtc_time).day; + int i; + + for (i = 0; i < mEnv_WEATHER_TERM_NUM; i++) { + if (month < weather_term_table[i][0]) { + return i; + } + else if (month == weather_term_table[i][0] && day <= weather_term_table[i][1]) { + return i; + } + } + + return 1; /* default is between Jan 8 & Feb 24 */ +} + +#define mEnv_MAKE_WEATHER_TABLE_ENTRY(clear, rain, thunder, snow, blizzard, sakura, heavy_sakura) \ + ( \ + (((clear) & 0xF) << 24) | \ + (((rain) & 0xF) << 16) | \ + (((thunder) & 0xF) << 20) | \ + (((snow) & 0xF) << 8) | \ + (((blizzard) & 0xF) << 12) | \ + (((sakura) & 0xF) << 0) | \ + (((heavy_sakura) & 0xF) << 4) \ + ) + +extern void mEnv_RandomWeather(s16* next_weather, s16* next_intensity) { + /* note: entries must add up to 10 for this to function properly */ + static const u32 weather_table[mEnv_WEATHER_TERM_NUM] = { + mEnv_MAKE_WEATHER_TABLE_ENTRY(10, 0, 0, 0, 0, 0, 0), // 100% chance of clear weather + mEnv_MAKE_WEATHER_TABLE_ENTRY( 7, 0, 0, 2, 1, 0, 0), // 70% chance of clear weather, 20% chance of snow, 10% chance of blizzard + mEnv_MAKE_WEATHER_TABLE_ENTRY( 8, 2, 0, 0, 0, 0, 0), // 80% chance of clear weather, 20% chance of rain + mEnv_MAKE_WEATHER_TABLE_ENTRY(10, 0, 0, 0, 0, 0, 0), // 100% chance of clear weather + mEnv_MAKE_WEATHER_TABLE_ENTRY(0, 0, 0, 0, 0, 10, 0), // 100% chance of light cherry blossoms + mEnv_MAKE_WEATHER_TABLE_ENTRY(0, 0, 0, 0, 0, 0, 10), // 100% chance of heavy cherry blossoms + mEnv_MAKE_WEATHER_TABLE_ENTRY( 8, 2, 0, 0, 0, 0, 0), // 80% chance of clear weather, 20% chance of rain + mEnv_MAKE_WEATHER_TABLE_ENTRY(10, 0, 0, 0, 0, 0, 0), // 100% chance of clear weather + mEnv_MAKE_WEATHER_TABLE_ENTRY( 7, 2, 1, 0, 0, 0, 0), // 70% chance of clear weather, 20% chance of rain, 10% chance of thunderstorms + mEnv_MAKE_WEATHER_TABLE_ENTRY( 5, 3, 2, 0, 0, 0, 0), // 50% chance of clear weather, 30% chance of rain, 20% chance of thunderstorms + mEnv_MAKE_WEATHER_TABLE_ENTRY( 9, 0, 1, 0, 0, 0, 0), // 90% chance of clear weather, 10% chance of thunderstorms + mEnv_MAKE_WEATHER_TABLE_ENTRY( 6, 0, 4, 0, 0, 0, 0), // 60% chance of clear weather, 40% chance of thunderstorms + mEnv_MAKE_WEATHER_TABLE_ENTRY( 8, 2, 0, 0, 0, 0, 0), // 80% chance of clear weather, 20% chance of rain + mEnv_MAKE_WEATHER_TABLE_ENTRY(10, 0, 0, 0, 0, 0, 0), // 100% chance of clear weather + mEnv_MAKE_WEATHER_TABLE_ENTRY( 8, 1, 0, 1, 0, 0, 0), // 80% chance of clear weather, 10% chance of rain, 10% chance of snow + mEnv_MAKE_WEATHER_TABLE_ENTRY( 7, 0, 0, 3, 0, 0, 0), // 70% chance of clear weather, 30% chance of snow + mEnv_MAKE_WEATHER_TABLE_ENTRY(0, 0, 0, 0, 10, 0, 0), // 100% chance of blizzard + mEnv_MAKE_WEATHER_TABLE_ENTRY( 4, 0, 0, 4, 2, 0, 0), // 40% chance of clear weather, 40% chance of snow, 20% chance of blizzard + mEnv_MAKE_WEATHER_TABLE_ENTRY( 0, 0, 0, 6, 4, 0, 0), // 60% chance of snow, 40% chance of blizzard + mEnv_MAKE_WEATHER_TABLE_ENTRY(10, 0, 0, 0, 0, 0, 0) // 100% chance of clear weather + }; + + int step = mEnv_GetWeatherChangeStep(); + + u32 weather = weather_table[step]; + u32 selected; + u32 c0; + u32 c1; + u32 c2; + u32 c3; + u32 c4; + u32 c5; + + c0 = (weather >> 24) & 0xF; // clear + c1 = (weather >> 16) & 0xF; // light rain + c2 = (weather >> 20) & 0xF; // thunderstorm + c3 = (weather >> 8) & 0xF; // light snow + c4 = (weather >> 12) & 0xF; // blizzard + #ifndef BUGFIXES + c5 = (weather >> 8) & 0xF; // @BUG - this is almost certainly supposed to be (weather >> 0) & 0xF + #else + c5 = (weather >> 0) & 0xF; // light cherry blossoms + #endif + + selected = RANDOM_F(10.0f); + + if (selected < c0) { + next_weather[0] = mEnv_WEATHER_CLEAR; + next_intensity[0] = mEnv_WEATHER_INTENSITY_LIGHT; + } + else if (selected < c0 + c1) { + next_weather[0] = mEnv_WEATHER_RAIN; + next_intensity[0] = mEnv_WEATHER_INTENSITY_LIGHT; + } + else if (selected < c0 + c1 + c2) { + next_weather[0] = mEnv_WEATHER_RAIN; + next_intensity[0] = mEnv_WEATHER_INTENSITY_HEAVY; + } + else if (selected < c0 + c1 + c2 + c3) { + next_weather[0] = mEnv_WEATHER_SNOW; + next_intensity[0] = mEnv_WEATHER_INTENSITY_LIGHT; + } + else if (selected < c0 + c1 + c2 + c3 + c4) { + next_weather[0] = mEnv_WEATHER_SNOW; + next_intensity[0] = mEnv_WEATHER_INTENSITY_HEAVY; + } + else if (selected < c0 + c1 + c2 + c3 + c4 + c5) { + next_weather[0] = mEnv_WEATHER_SAKURA; + next_intensity[0] = mEnv_WEATHER_INTENSITY_LIGHT; + } + else { + next_weather[0] = mEnv_WEATHER_SAKURA; + next_intensity[0] = mEnv_WEATHER_INTENSITY_HEAVY; + } +} + +typedef struct wind_power_range_s { + int calm_percent; + int normal_percent; + int gusty_percent; +} mEnv_wind_power_range_c; + +typedef struct wind_info_s { + int wind_change_timer; /* timer until wind direction & base power changes */ + + f32 target_wind_angle; + f32 wind_angle; + f32 wind_angle_step; + + f32 wind_power_range_max; + f32 wind_power_range_min; + + f32 target_wind_power; + f32 wind_power; /* base wind power */ + f32 wind_power_step; + + int wind_state; + int gust_timer; + s16 wind_power_timer; + + f32 gust_wind_power; /* power during gusts */ + f32 last_wind_power; /* saved base power for returning from gusts */ +} mEnv_wind_info_c; + +static mEnv_wind_info_c mEnv_wind_info = { + 0, + + /* angle */ + DEG2SHORT_ANGLE(45.0f), /* 0x2000 */ + DEG2SHORT_ANGLE(45.0f), + 0.0f, + + /* power range */ + 1.0f, + 0.0f, + + /* power */ + 0.5f, + 0.5f, + 0.0f, + + mEnv_WIND_STATE_STEADY, + 0, + 0, + + 0.0f, + 0.0f +}; + +extern s16 mEnv_GetWindAngleS() { + return mEnv_wind_info.wind_angle; /* angle is stored as a binangle (short angle), but in float type */ +} + +extern f32 mEnv_GetWindPowerF() { + if (mEnv_wind_info.wind_power < 0.0f) { + return 0.0f; + } + else if (mEnv_wind_info.wind_power > 1.0f) { + return 1.0f; + } + else { + return mEnv_wind_info.wind_power; + } +} + +extern f32 mEnv_GetWindPowerF_Windmill() { + return mEnv_wind_info.wind_power; // unclamped for gusts/luls +} + +static u8 wind_term[mEnv_WIND_TERM_NUM][2] = { + { lbRTC_JANUARY, 7 }, /* January 1st - January 7th */ + { lbRTC_APRIL, 5 }, /* January 8th - April 5th */ + { lbRTC_AUGUST, 19 }, /* April 6th - August 19th */ + { lbRTC_SEPTEMBER, 30 } /* August 20th - September 30th */ + /* October 1st - December 31st */ +}; + +static int mEnv_GetWindPowerTableTerm(lbRTC_time_c* time) { + lbRTC_month_t month = time->month; + lbRTC_day_t day = time->day; + int i; + + for (i = 0; i < mEnv_WIND_TERM_NUM; i++) { + if (month < wind_term[i][0]) { + return i; + } + else if (month == wind_term[i][0] && day <= wind_term[i][1]) { + return i; + } + } + + return i; /* must be the final term */ +} + +static int mEnv_GetWindPowerPercent(lbRTC_time_c* time, mEnv_wind_power_range_c* wind_power_range) { + static mEnv_wind_power_range_c pow_table[mEnv_WIND_TERM_NUM + 1] = { + { 10, 80, 10 }, + { 0, 70, 30 }, + { 10, 80, 10 }, + { 0, 70, 30 }, + { 10, 80, 10 } + }; + + static mEnv_wind_power_range_c error_data = { 33, 33, 34 }; + + int power_table_term = mEnv_GetWindPowerTableTerm(time); + *wind_power_range = error_data; + + if (power_table_term >= 0 && power_table_term < mEnv_WIND_TERM_NUM) { + *wind_power_range = pow_table[power_table_term]; + return TRUE; + } + + return FALSE; +} + +extern void mEnv_DecideTodayWindPowerRange() { + mEnv_wind_power_range_c power_range_percents; + int selected = RANDOM(100); + + mEnv_GetWindPowerPercent(Common_GetPointer(time.rtc_time), &power_range_percents); + + if (selected < power_range_percents.calm_percent) { + mEnv_wind_info.wind_power_range_max = 0.4f; + mEnv_wind_info.wind_power_range_min = 0.0f; + } + else if (selected < power_range_percents.calm_percent + power_range_percents.normal_percent) { + mEnv_wind_info.wind_power_range_max = 0.6f; + mEnv_wind_info.wind_power_range_min = 0.4f; + } + else { + mEnv_wind_info.wind_power_range_max = 1.0f; + mEnv_wind_info.wind_power_range_min = 0.6f; + } +} + +extern void mEnv_ChangeWind() { + if (mEv_check_schedule(mEv_EVENT_KOINOBORI)) { + mEnv_wind_info.target_wind_angle = DEG2SHORT_ANGLE(135.0f); /* 0x6000 */ + mEnv_wind_info.wind_angle = DEG2SHORT_ANGLE(135.0f); + mEnv_wind_info.target_wind_power = 1.0f; + mEnv_wind_info.wind_power = 1.0f; + mEnv_wind_info.wind_angle_step = 0.0f; + mEnv_wind_info.wind_power_step = 0.0f; + } + else { + f32 wind_angle_adjust = RANDOM_F(DEG2SHORT_ANGLE(30.0f)) - (f32)DEG2SHORT_ANGLE(30.0f) / 2.0f; + f32 w = fqrand(); + f32 min = mEnv_wind_info.wind_power_range_min; + f32 max = mEnv_wind_info.wind_power_range_max; + + mEnv_wind_info.target_wind_angle = mEnv_wind_info.wind_angle + wind_angle_adjust; + mEnv_wind_info.wind_angle_step = wind_angle_adjust / mEnv_WIND_CHANGE_RATE; + mEnv_wind_info.target_wind_power = min + w * (max - min); + mEnv_wind_info.wind_power_step = (mEnv_wind_info.target_wind_power - mEnv_wind_info.wind_power) / mEnv_WIND_CHANGE_RATE; + } +} + +static void mEnv_InitWind() { + if (mEv_check_schedule(mEv_EVENT_KOINOBORI)) { + mEnv_wind_info.target_wind_angle = DEG2SHORT_ANGLE(135.0f); /* 0x6000 */ + mEnv_wind_info.target_wind_power = 1.0f; + } + else { + f32 angle = RANDOM_F(65536); + f32 t = fqrand(); + f32 min = mEnv_wind_info.wind_power_range_min; + f32 max = mEnv_wind_info.wind_power_range_max; + + mEnv_wind_info.target_wind_angle = angle; /* completely random wind direction */ + mEnv_wind_info.target_wind_power = min + t * (max - min); + } + + mEnv_wind_info.wind_state = mEnv_WIND_STATE_STEADY; + mEnv_wind_info.wind_change_timer = mEnv_WIND_CHANGE_RATE; + mEnv_wind_info.wind_angle = mEnv_wind_info.target_wind_angle; + mEnv_wind_info.wind_angle_step = 0.0f; + mEnv_wind_info.wind_power = mEnv_wind_info.target_wind_power; + mEnv_wind_info.wind_power_step = 0.0f; +} + +extern void mEnv_WindMove() { + if (mEnv_wind_info.wind_state == mEnv_WIND_STATE_STEADY) { + if ( + (mEnv_wind_info.target_wind_angle > mEnv_wind_info.wind_angle && mEnv_wind_info.wind_angle_step < 0.0f) || + (mEnv_wind_info.target_wind_angle < mEnv_wind_info.wind_angle && mEnv_wind_info.wind_angle_step > 0.0f) + ) { + mEnv_wind_info.wind_angle_step *= -1.0f; // invert wind angle step direction + } + + if ( + (mEnv_wind_info.target_wind_power > mEnv_wind_info.wind_power && mEnv_wind_info.wind_power_step < 0.0f) || + (mEnv_wind_info.target_wind_power < mEnv_wind_info.wind_power && mEnv_wind_info.wind_power_step > 0.0f) + ) { + mEnv_wind_info.wind_power_step *= -1.0f; // invert wind power step direction + } + + /* process change in wind angle */ + if (mEnv_wind_info.target_wind_angle != mEnv_wind_info.wind_angle) { + mEnv_wind_info.wind_angle += mEnv_wind_info.wind_angle_step; + + /* stop wind angle step once target is reached */ + if (mEnv_wind_info.wind_angle_step > 0.0f) { + if (mEnv_wind_info.wind_angle >= mEnv_wind_info.target_wind_angle) { + mEnv_wind_info.wind_angle_step = 0.0f; + } + } + else if (mEnv_wind_info.wind_angle_step < 0.0f) { + if (mEnv_wind_info.wind_angle <= mEnv_wind_info.target_wind_angle) { + mEnv_wind_info.wind_angle_step = 0.0f; + } + } + } + + /* process change in wind power */ + if (mEnv_wind_info.target_wind_power != mEnv_wind_info.wind_power) { + mEnv_wind_info.wind_power += mEnv_wind_info.wind_power_step; + + /* stop wind power step once target is reached */ + if (mEnv_wind_info.wind_power_step > 0.0f) { + if (mEnv_wind_info.wind_power >= mEnv_wind_info.target_wind_power) { + mEnv_wind_info.wind_power_step = 0.0f; + } + } + else if (mEnv_wind_info.wind_power_step < 0.0f) { + if (mEnv_wind_info.wind_power <= mEnv_wind_info.target_wind_power) { + mEnv_wind_info.wind_power_step = 0.0f; + } + } + } + + if (mEnv_wind_info.gust_timer <= 0) { + int res = (int)(fqrand() * 100.0f) & 1; + f32 rng1 = fqrand(); + f32 rng2 = fqrand(); + + mEnv_wind_info.wind_state = (res == 1 || mEnv_wind_info.wind_power_range_min == 0.0f) ? mEnv_WIND_STATE_FAST : mEnv_WIND_STATE_SLOW; + mEnv_wind_info.last_wind_power = mEnv_wind_info.wind_power; + mEnv_wind_info.wind_power_timer = 200.0f + rng2 * 100.0f; + + if (mEnv_wind_info.wind_state == mEnv_WIND_STATE_FAST) { + mEnv_wind_info.gust_wind_power = mEnv_wind_info.wind_power_range_max + 0.3f + rng1 * ((mEnv_wind_info.wind_power_range_max + 0.4f) - (mEnv_wind_info.wind_power_range_max + 0.3f)); // ?? + } + else { + mEnv_wind_info.gust_wind_power = mEnv_wind_info.wind_power_range_min - 0.3f + rng1 * ((mEnv_wind_info.wind_power_range_min - 0.4f) - (mEnv_wind_info.wind_power_range_min - 0.3f)); // ?? + } + } + else { + if (mEnv_wind_info.gust_timer > 0) { + mEnv_wind_info.gust_timer--; + } + + if (mEnv_wind_info.wind_change_timer <= 0) { + mEnv_ChangeWind(); + mEnv_wind_info.wind_change_timer = mEnv_WIND_CHANGE_RATE; + } + } + } + else if (mEnv_wind_info.wind_state == mEnv_WIND_STATE_FAST) { + add_calc(&mEnv_wind_info.wind_power, mEnv_wind_info.gust_wind_power, 0.05f, 0.05f, 0.0001f); + + if (mEnv_wind_info.wind_power_timer <= 0) { + mEnv_wind_info.wind_state = mEnv_WIND_STATE_REDUCING; + } + else { + mEnv_wind_info.wind_power_timer--; + } + } + else if (mEnv_wind_info.wind_state == mEnv_WIND_STATE_SLOW) { + add_calc(&mEnv_wind_info.wind_power, mEnv_wind_info.gust_wind_power, 0.05f, 0.05f, 0.0001f); + + if (mEnv_wind_info.wind_power_timer <= 0) { + mEnv_wind_info.wind_state = mEnv_WIND_STATE_REDUCING; + } + else { + mEnv_wind_info.wind_power_timer--; + } + } + else { + add_calc(&mEnv_wind_info.wind_power, mEnv_wind_info.last_wind_power, 0.032f, 0.032f, 0.000005f); + + if (mEnv_wind_info.wind_power == mEnv_wind_info.last_wind_power) { + f32 rng = fqrand(); + + mEnv_wind_info.gust_timer = rng * 450.0f + 150.0f; + mEnv_wind_info.wind_state = mEnv_WIND_STATE_STEADY; + } + } + + if (mEnv_wind_info.wind_change_timer > 0) { + mEnv_wind_info.wind_change_timer--; + } +} + +extern void mEnv_DecideWeather_GameStart() { + s16 weather; + s16 intensity; + s16 event_weather; + s16 event_intensity; + + mEnv_RandomWeather(&weather, &intensity); + mEv_GetEventWeather(&event_weather, &event_intensity); + + if (event_weather != -1) { + weather = event_weather; + intensity = event_intensity; + } + + if (mEv_CheckRealArbeit() == TRUE && weather == mEnv_WEATHER_RAIN) { + weather = mEnv_WEATHER_CLEAR; + intensity = mEnv_WEATHER_INTENSITY_NONE; + } + + Common_Set(weather, weather); + Common_Set(weather_intensity, intensity); + Common_Set(weather_time, Common_Get(time.rtc_time)); +} + +extern void mEnv_DecideWeather_FirstGameStart() { + mEnv_DecideWeather_GameStart(); + Save_Set(weather, ((u8)Common_Get(weather_intensity) | (u8)Common_Get(weather) << 4)); + + if (mTM_check_renew_time(mTM_RENEW_TIME_WEATHER)) { + mTM_off_renew_time(mTM_RENEW_TIME_WEATHER); + } +} + +static void mEnv_Rainbow_reserve() { + Save_Set(rainbow_reserved, TRUE); + Save_Set(rainbow_month, Common_Get(time.rtc_time).month); + Save_Set(rainbow_day, Common_Get(time.rtc_time).day); +} + +extern void mEnv_PreRainNowFine_Init() { + mAGrw_OrderSetHaniwa(); + mEnv_Rainbow_reserve(); +} + +extern void mEnv_DecideWeather_NormalGameStart() { + u8 weather; + u8 intensity; + + if (mTM_check_renew_time(mTM_RENEW_TIME_WEATHER)) { + u8 save_weather; + + mEnv_DecideWeather_GameStart(); + mTM_off_renew_time(mTM_RENEW_TIME_WEATHER); + weather = Common_Get(weather); + intensity = Common_Get(weather_intensity); + save_weather = mEnv_SAVE_GET_WEATHER_TYPE(Save_Get(weather)); + + if ( + (weather == mEnv_WEATHER_CLEAR || weather == mEnv_WEATHER_SAKURA) && + (save_weather == mEnv_WEATHER_SNOW || save_weather == mEnv_WEATHER_RAIN) + ) { + mEnv_PreRainNowFine_Init(); + } + + Save_Set(weather, intensity | (weather << 4)); + } + else { + weather = mEnv_SAVE_GET_WEATHER_TYPE(Save_Get(weather)); + intensity = mEnv_SAVE_GET_WEATHER_INTENSITY(Save_Get(weather)); + + if (mEv_CheckRealArbeit() == TRUE && weather == mEnv_WEATHER_RAIN) { + weather = mEnv_WEATHER_CLEAR; + intensity = mEnv_WEATHER_INTENSITY_NONE; + + Save_Set(weather, (intensity | (u8)weather << 4)); + } + + Common_Set(weather, weather); + Common_Set(weather_intensity, intensity); + } + + if (fqrand() < (f32)GETREG(TAKREG, 50) * 0.1f + 0.8f) { + Common_Set(island_weather, mEnv_WEATHER_CLEAR); + Common_Set(island_weather_intensity, mEnv_WEATHER_INTENSITY_NONE); + } + else { + Common_Set(island_weather, mEnv_WEATHER_RAIN); + Common_Set(island_weather_intensity, mEnv_WEATHER_INTENSITY_HEAVY); + + } +} + +extern int mEnv_NowWeather() { + switch (mEv_CheckTitleDemo()) { + case 1: + return mEnv_WEATHER_SAKURA; + case 2: + return mEnv_WEATHER_RAIN; + case 3: + case 4: + return mEnv_WEATHER_CLEAR; + case 5: + return mEnv_WEATHER_SNOW; + } + + if (mFI_GET_TYPE(mFI_GetFieldId()) == mFI_FIELD_FG) { + return Common_Get(weather); + } + + return mEnv_WEATHER_CLEAR; +} diff --git a/rel/m_lights.c b/rel/m_lights.c index 63118d0b..286f5deb 100644 --- a/rel/m_lights.c +++ b/rel/m_lights.c @@ -214,8 +214,7 @@ static void LightsN__diffuse_proc(LightsN* lights, LightParams* lightInfo){ } } - -extern void LightsN_list_check(LightsN* lights, LightNode* node, xyz_t* pos){ +extern void LightsN_list_check(LightsN* lights, Light_list* node, xyz_t* pos){ const static light_point_proc poslight_type_proc[] = { LightsN__point_proc, @@ -243,9 +242,9 @@ extern void LightsN_list_check(LightsN* lights, LightNode* node, xyz_t* pos){ } } -static LightNode* Light_list_buf_new(){ +static Light_list* Light_list_buf_new(){ - LightNode* light; + Light_list* light; if(light_list_buf.current >= 32){ return NULL; @@ -268,11 +267,11 @@ static LightNode* Light_list_buf_new(){ return light; } -static void Light_list_buf_delete(LightNode* light){ +static void Light_list_buf_delete(Light_list* light){ if(light != NULL){ light_list_buf.current--; light->info = NULL; - light_list_buf.idx = (light - light_list_buf.lights) / (int)(sizeof(LightNode)); + light_list_buf.idx = (light - light_list_buf.lights) / (int)(sizeof(Light_list)); } } @@ -312,9 +311,9 @@ static void Global_light_list_ct(Global_light* glight){ glight->list = NULL; } -extern void Global_light_list_new(GAME_PLAY* play, Global_light* glight, Lights* light){ +extern Light_list* Global_light_list_new(GAME_PLAY* play, Global_light* glight, Lights* light){ - LightNode* clight; + Light_list* clight; clight = Light_list_buf_new(); @@ -329,9 +328,11 @@ extern void Global_light_list_new(GAME_PLAY* play, Global_light* glight, Lights* glight->list = clight; } + + return clight; } -extern void Global_light_list_delete(Global_light* glight, LightNode* light){ +extern void Global_light_list_delete(Global_light* glight, Light_list* light){ if(light != NULL){ if(light->prev != NULL){ @@ -367,7 +368,7 @@ static LightsN* new_LightsN(GRAPH* graph, u8 r, u8 g, u8 b){ extern void Light_list_point_draw(GAME_PLAY* play){ LightPoint* lightInfo; - LightNode* light; + Light_list* light; GRAPH* g = play->game.graph; f32 rad; Gfx* dl; diff --git a/rel/m_play.c b/rel/m_play.c index 794753f3..61a4fff1 100644 --- a/rel/m_play.c +++ b/rel/m_play.c @@ -167,8 +167,8 @@ void Game_play_fbdemo_wipe_init(GAME_PLAY* play){ play->fbdemo_wipe.wipe_procs.init_proc(&wipe->wipe_data); - Common_Set(transWipeSpeed, 28); - Common_Set(transFadeDuration, 30); + Common_Set(transition.wipe_rate, 28); + Common_Set(transition.fade_rate, 30); wipe->wipe_procs.setcolor_proc(&wipe->wipe_data,0); @@ -478,9 +478,9 @@ void play_init(GAME* game){ play->fb_wipe_mode = 0; play->fb_fade_type = 1; - if(Common_Get(wipeType) != 0xFF){ - type = Common_Get(wipeType); - Common_Set(wipeType, 0xFF); + if(Common_Get(transition.wipe_type) != 0xFF){ + type = Common_Get(transition.wipe_type); + Common_Set(transition.wipe_type, 0xFF); } play->fb_wipe_type = type; diff --git a/rel/m_trademark.c b/rel/m_trademark.c index 6c2d4067..34e6aa05 100644 --- a/rel/m_trademark.c +++ b/rel/m_trademark.c @@ -192,7 +192,7 @@ static void trademark_goto_demo_scene(GAME_TRADEMARK* trademark) { mTM_demotime_set(demo_no); // set demo date, time, and weather mPr_RandomSetPlayerData_title_demo(); // randomize player data set_npc_4_title_demo(trademark); // set animals in the demo - Common_Set(wipeType, 3); + Common_Set(transition.wipe_type, 3); } Save_Set(scene_no, SCENE_TITLE_DEMO);