diff --git a/assets/xml/objects/gameplay_field_keep.xml b/assets/xml/objects/gameplay_field_keep.xml
index eac8556695..32427cfe87 100644
--- a/assets/xml/objects/gameplay_field_keep.xml
+++ b/assets/xml/objects/gameplay_field_keep.xml
@@ -42,9 +42,11 @@
-
-
-
+
+
+
+
+
diff --git a/assets/xml/objects/gameplay_keep.xml b/assets/xml/objects/gameplay_keep.xml
index 37fb3fc615..3253e718c4 100644
--- a/assets/xml/objects/gameplay_keep.xml
+++ b/assets/xml/objects/gameplay_keep.xml
@@ -1230,7 +1230,7 @@
-
+
@@ -1347,7 +1347,7 @@
-
+
diff --git a/include/functions.h b/include/functions.h
index 907c35b5f8..5519036a30 100644
--- a/include/functions.h
+++ b/include/functions.h
@@ -537,7 +537,7 @@ void Lib_PlaySfx(u16 sfxId);
void Lib_PlaySfx_2(u16 sfxId);
void Lib_PlaySfx_AtPos(Vec3f* pos, u16 sfxId);
void Lib_Vec3f_TranslateAndRotateY(Vec3f* translation, s16 rotAngle, Vec3f* src, Vec3f* dst);
-void Color_RGB8_Lerp(Color_RGB8* a, Color_RGB8* b, f32 t, Color_RGB8* dst);
+void Color_RGB8_Lerp(Color_RGB8* from, Color_RGB8* to, f32 lerp, Color_RGB8* dst);
void Lib_Nop801004FC(void);
void* Lib_SegmentedToVirtual(void* ptr);
void* Lib_SegmentedToVirtualNull(void* ptr);
diff --git a/include/regs.h b/include/regs.h
index 2d113ea48a..354408378e 100644
--- a/include/regs.h
+++ b/include/regs.h
@@ -61,6 +61,7 @@ extern RegEditor* gRegEditor;
/* TODO: There are still a few OoT defines here that need confirmation */
+#define R_ENV_DISABLE_DBG REG(9)
#define R_TIME_SPEED REG(15)
#define R_RUN_SPEED_LIMIT REG(45)
@@ -148,6 +149,9 @@ extern RegEditor* gRegEditor;
#define R_REVERSE_FLOOR_INDEX XREG(94)
#define R_MINIMAP_DISABLED XREG(95)
+#define R_ENV_LIGHT1_DIR(i) cREG(3 + (i))
+#define R_ENV_LIGHT2_DIR(i) cREG(6 + (i))
+
#define R_TRANS_FADE_FLASH_ALPHA_STEP iREG(50) // Set to a negative number to start the flash
#define R_ROOM_CULL_DEBUG_MODE iREG(86)
#define R_ROOM_CULL_NUM_ENTRIES iREG(87)
diff --git a/include/variables.h b/include/variables.h
index 743f138caf..2b088fa0c0 100644
--- a/include/variables.h
+++ b/include/variables.h
@@ -32,7 +32,7 @@ extern u8* sYaz0MaxPtr;
extern void* gYaz0DecompressDstEnd;
// extern UNK_TYPE4 D_8009CD10;
-extern u32 sRandFloat;
+extern u32 gRandFloat;
// extern UNK_TYPE4 sArenaLockMsg;
extern DmaEntry dmadata[1568];
diff --git a/include/z64math.h b/include/z64math.h
index 4a4d15b98d..fa9b0a4ffc 100644
--- a/include/z64math.h
+++ b/include/z64math.h
@@ -131,7 +131,10 @@ typedef union {
} MtxF; // size = 0x40
#define LERPIMP(v0, v1, t) ((v0) + (((v1) - (v0)) * (t)))
+#define LERPIMP_ALT(v0, v1, t) (((v1) - (v0)) * (t) + (v0))
+#define S16_LERP(v0, v1, t) ((s16)(((v1) - (v0)) * (t)) + (v0))
#define F32_LERP(v0, v1, t) ((1.0f - (t)) * (f32)(v0) + (t) * (f32)(v1))
+#define F32_LERP_ALT(v0, v1, t) ((f32)(v0) * (1.0f - (t)) + (t) * (f32)(v1))
#define F32_LERPIMP(v0, v1, t) ((f32)(v0) + (((f32)(v1) - (f32)(v0)) * (t)))
#define F32_LERPIMPINV(v0, v1, t) ((f32)(v0) + (((f32)(v1) - (f32)(v0)) / (t)))
#define BINANG_LERPIMP(v0, v1, t) ((v0) + (s16)(BINANG_SUB((v1), (v0)) * (t)))
diff --git a/include/z64save.h b/include/z64save.h
index 25ce107f83..5fffb73c31 100644
--- a/include/z64save.h
+++ b/include/z64save.h
@@ -240,7 +240,7 @@ typedef struct PermanentSceneFlags {
/* 0x08 */ u32 switch1;
/* 0x0C */ u32 clearedRoom;
/* 0x10 */ u32 collectible;
- /* 0x14 */ u32 unk_14; // varies based on scene. For dungeons, floors visited.
+ /* 0x14 */ u32 unk_14; // varies based on scene. For dungeons, floors visited.
/* 0x18 */ u32 rooms;
} PermanentSceneFlags; // size = 0x1C
@@ -1598,9 +1598,8 @@ typedef enum {
#define EVENTINF_THREEDAYRESET_LOST_STICK_AMMO 0x73
#define EVENTINF_THREEDAYRESET_LOST_ARROW_AMMO 0x74
-#define EVENTINF_75 0x75
-#define EVENTINF_76 0x76
-#define EVENTINF_77 0x77
+// Checked in Kankyo as one to store the day: gSaveContext.eventInf[7] & 0xE0
+// EVENTINF_75 to EVENTINF_77
#define CHECK_EVENTINF(flag) (gSaveContext.eventInf[(flag) >> 4] & (1 << ((flag) & 0xF)))
#define SET_EVENTINF(flag) (gSaveContext.eventInf[(flag) >> 4] |= (1 << ((flag) & 0xF)))
@@ -1628,6 +1627,13 @@ typedef enum {
#define SET_EVENTINF_DOG_RACE_RACE_STANDING(raceStanding) \
(gSaveContext.eventInf[0] = (gSaveContext.eventInf[0] & EVENTINF_DOG_RACE_STATE_MASK) | (raceStanding << 3))
+#define EVENTINF_GET_7_E0 ((gSaveContext.eventInf[7] & 0xE0) >> 5)
+
+#define EVENTINF_SET_7_E0(day, temp) \
+ (temp) = gSaveContext.eventInf[7] & (u8)~0xE0; \
+ (temp) |= (u8)((day) << 5); \
+ gSaveContext.eventInf[7] = (temp)
+
typedef enum {
/* 0 */ DUNGEON_INDEX_WOODFALL_TEMPLE,
/* 1 */ DUNGEON_INDEX_SNOWHEAD_TEMPLE,
diff --git a/src/boot/O2/rand.c b/src/boot/O2/rand.c
index 2db64e9d57..9f30517176 100644
--- a/src/boot/O2/rand.c
+++ b/src/boot/O2/rand.c
@@ -5,7 +5,7 @@ static u32 sRandInt = 1;
//! Space to store a value to be re-interpreted as a float.
//! This can't be static because it is used in z_kankyo.
-u32 sRandFloat;
+u32 gRandFloat;
//! These values are recommended by the algorithms book *Numerical Recipes in C. The Art of Scientific Computing*, 2nd
//! Edition, 1992, ISBN 0-521-43108-5. (p. 284):
@@ -37,8 +37,8 @@ void Rand_Seed(u32 seed) {
*/
f32 Rand_ZeroOne(void) {
sRandInt = (sRandInt * RAND_MULTIPLIER) + RAND_INCREMENT;
- sRandFloat = ((sRandInt >> 9) | 0x3F800000);
- return *((f32*)&sRandFloat) - 1.0f;
+ gRandFloat = ((sRandInt >> 9) | 0x3F800000);
+ return *((f32*)&gRandFloat) - 1.0f;
}
/**
@@ -46,8 +46,8 @@ f32 Rand_ZeroOne(void) {
*/
f32 Rand_Centered(void) {
sRandInt = (sRandInt * RAND_MULTIPLIER) + RAND_INCREMENT;
- sRandFloat = ((sRandInt >> 9) | 0x3F800000);
- return *((f32*)&sRandFloat) - 1.5f;
+ gRandFloat = ((sRandInt >> 9) | 0x3F800000);
+ return *((f32*)&gRandFloat) - 1.5f;
}
//! All functions below are unused variants of the above four, that use a provided random number variable instead of the
@@ -79,8 +79,8 @@ u32 Rand_Next_Variable(u32* rndNum) {
f32 Rand_ZeroOne_Variable(u32* rndNum) {
u32 next = (*rndNum * RAND_MULTIPLIER) + RAND_INCREMENT;
- sRandFloat = ((*rndNum = next) >> 9) | 0x3F800000;
- return *((f32*)&sRandFloat) - 1.0f;
+ gRandFloat = ((*rndNum = next) >> 9) | 0x3F800000;
+ return *((f32*)&gRandFloat) - 1.0f;
}
/**
@@ -91,6 +91,6 @@ f32 Rand_ZeroOne_Variable(u32* rndNum) {
f32 Rand_Centered_Variable(u32* rndNum) {
u32 next = (*rndNum * RAND_MULTIPLIER) + RAND_INCREMENT;
- sRandFloat = ((*rndNum = next) >> 9) | 0x3F800000;
- return *((f32*)&sRandFloat) - 1.5f;
+ gRandFloat = ((*rndNum = next) >> 9) | 0x3F800000;
+ return *((f32*)&gRandFloat) - 1.5f;
}
diff --git a/src/code/z_kankyo.c b/src/code/z_kankyo.c
index 6dda9090d1..0326dcd24c 100644
--- a/src/code/z_kankyo.c
+++ b/src/code/z_kankyo.c
@@ -2,6 +2,13 @@
#include "z64light.h"
#include "z64math.h"
+typedef enum {
+ /* 0x00 */ LIGHTNING_BOLT_START,
+ /* 0x01 */ LIGHTNING_BOLT_WAIT,
+ /* 0x02 */ LIGHTNING_BOLT_DRAW,
+ /* 0xFF */ LIGHTNING_BOLT_INACTIVE = 0xFF
+} LightningBoltState;
+
typedef struct {
/* 0x00 */ u8 state;
/* 0x04 */ Vec3f offset;
@@ -56,6 +63,8 @@ Gfx* sSkyboxStarsDList;
#include "global.h"
#include "sys_cfb.h"
#include "objects/gameplay_keep/gameplay_keep.h"
+#include "objects/gameplay_field_keep/gameplay_field_keep.h"
+#include "overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope.h"
// Data
f32 sSandstormLerpScale = 0.0f;
@@ -64,7 +73,7 @@ s32 sEnvSkyboxNumStars = 0;
u16 sTimeJump = 0;
u8 sSandstormColorIndex = 0;
u8 sNextSandstormColorIndex = 0;
-u8 D_801BDBA8 = 0;
+u8 D_801BDBA8 = false;
u8 D_801BDBAC = 0;
u8 gWeatherMode = WEATHER_MODE_CLEAR;
u8 gLightConfigAfterUnderwater = 0;
@@ -474,6 +483,12 @@ SkyboxFile sNormalSkyFiles[] = {
},
};
+void Environment_UpdatePostmanEvents(PlayState* play);
+void Environment_UpdateRain(PlayState* play);
+void Environment_UpdateTimeBasedSequence(PlayState* play);
+u8 func_800FE5D0(struct PlayState* play);
+void Environment_JumpForwardInTime(void);
+
void Environment_GraphCallback(GraphicsContext* gfxCtx, void* arg) {
PlayState* play = (PlayState*)arg;
@@ -487,8 +502,8 @@ typedef struct {
} ZBufValConversionEntry; // size = 0x8
ZBufValConversionEntry sZBufValConversionTable[1 << 3] = {
- { 6, 0x00000 }, { 5, 0x20000 }, { 4, 0x30000 }, { 3, 0x38000 },
- { 2, 0x3C000 }, { 1, 0x3E000 }, { 0, 0x3F000 }, { 0, 0x3F800 },
+ { 6, 0x0000 << 3 }, { 5, 0x4000 << 3 }, { 4, 0x6000 << 3 }, { 3, 0x7000 << 3 },
+ { 2, 0x7800 << 3 }, { 1, 0x7C00 << 3 }, { 0, 0x7E00 << 3 }, { 0, 0x7F00 << 3 },
};
#define ZBUFVAL_EXPONENT(v) (((v) >> 15) & 7)
@@ -510,7 +525,305 @@ s32 Environment_ZBufValToFixedPoint(s32 zBufferVal) {
return ret;
}
+#ifdef NON_MATCHING
+// The 2 constant from the `gWeatherMode` switch branch is reused when checking `CURRENT_DAY`
+// A near identical issue is present in the non-matching `func_809F24C8` from `z_boss_06.c`
+void Environment_Init(PlayState* play2, EnvironmentContext* envCtx, s32 arg2) {
+ PlayState* play = play2;
+ f32 temp_ft4;
+ u8 var_a0;
+ u8 temp;
+ s16 i;
+
+ CREG(1) = 0;
+
+ gSaveContext.sunsSongState = SUNSSONG_INACTIVE;
+
+ gSaveContext.skyboxTime = ((void)0, gSaveContext.save.time);
+
+ Environment_JumpForwardInTime();
+
+ if ((((void)0, gSaveContext.save.time) >= CLOCK_TIME(18, 0)) ||
+ (((void)0, gSaveContext.save.time) < CLOCK_TIME(6, 0))) {
+ gSaveContext.save.isNight = true;
+ } else {
+ gSaveContext.save.isNight = false;
+ }
+
+ play->state.gfxCtx->callback = Environment_GraphCallback;
+ play->state.gfxCtx->callbackArg = play;
+
+ Lights_DirectionalSetInfo(&envCtx->dirLight1, 80, 80, 80, 80, 80, 80);
+ LightContext_InsertLight(play, &play->lightCtx, &envCtx->dirLight1);
+
+ Lights_DirectionalSetInfo(&envCtx->dirLight2, 80, 80, 80, 80, 80, 80);
+ LightContext_InsertLight(play, &play->lightCtx, &envCtx->dirLight2);
+
+ envCtx->changeSkyboxState = CHANGE_SKYBOX_INACTIVE;
+ envCtx->changeSkyboxTimer = 0;
+ envCtx->changeLightEnabled = false;
+ envCtx->changeLightTimer = 0;
+ envCtx->skyboxDmaState = 0;
+ envCtx->skybox1Index = 99;
+ envCtx->skybox2Index = 99;
+
+ envCtx->glareAlpha = 0.0f;
+ envCtx->lensFlareAlphaScale = 0.0f;
+
+ if ((play->sceneId == SCENE_00KEIKOKU) && (gSaveContext.sceneLayer == 8)) {
+ gSaveContext.save.day = 1;
+ }
+
+ switch (gSaveContext.save.day) {
+ default:
+ case 0:
+ case 1:
+ envCtx->lightConfig = 0;
+ envCtx->changeLightNextConfig = 0;
+ break;
+
+ case 2:
+ envCtx->lightConfig = 3;
+ envCtx->changeLightNextConfig = 3;
+ break;
+
+ case 3:
+ envCtx->lightConfig = 4;
+ envCtx->changeLightNextConfig = 4;
+ break;
+ }
+
+ envCtx->lightSetting = 0;
+ envCtx->prevLightSetting = 0;
+ envCtx->lightBlendOverride = LIGHT_BLEND_OVERRIDE_NONE;
+ envCtx->stormRequest = STORM_REQUEST_NONE;
+ envCtx->stormState = STORM_STATE_OFF;
+ envCtx->lightningState = LIGHTNING_OFF;
+ envCtx->timeSeqState = TIMESEQ_DAY_BGM;
+ envCtx->fillScreen = 0;
+ envCtx->screenFillColor[0] = 0;
+ envCtx->screenFillColor[1] = 0;
+ envCtx->screenFillColor[2] = 0;
+ envCtx->screenFillColor[3] = 0;
+ envCtx->customSkyboxFilter = false;
+ envCtx->skyboxFilterColor[0] = 0;
+ envCtx->skyboxFilterColor[1] = 0;
+ envCtx->skyboxFilterColor[2] = 0;
+ envCtx->skyboxFilterColor[3] = 0;
+ envCtx->sandstormState = SANDSTORM_OFF;
+ envCtx->sandstormPrimA = 0;
+ envCtx->sandstormEnvA = 0;
+ envCtx->lightBlend = 1.0f;
+
+ gLightningStrike.state = LIGHTNING_STRIKE_WAIT;
+ gLightningStrike.flashRed = 0;
+ gLightningStrike.flashGreen = 0;
+ gLightningStrike.flashBlue = 0;
+
+ sLightningFlashAlpha = 0;
+
+ D_801F4F30 = 0xFF;
+ D_801F4F31 = 0;
+ D_801F4E30 = 0;
+ D_801F4F33 = 0;
+
+ gSaveContext.cutsceneTransitionControl = 0;
+
+ envCtx->adjLightSettings.ambientColor[0] = 0;
+ envCtx->adjLightSettings.ambientColor[1] = 0;
+ envCtx->adjLightSettings.ambientColor[2] = 0;
+ envCtx->adjLightSettings.light1Color[0] = 0;
+ envCtx->adjLightSettings.light1Color[1] = 0;
+ envCtx->adjLightSettings.light1Color[2] = 0;
+ envCtx->adjLightSettings.light2Color[0] = 0;
+ envCtx->adjLightSettings.light2Color[1] = 0;
+ envCtx->adjLightSettings.light2Color[2] = 0;
+ envCtx->adjLightSettings.fogColor[0] = 0;
+ envCtx->adjLightSettings.fogColor[1] = 0;
+ envCtx->adjLightSettings.fogColor[2] = 0;
+ envCtx->adjLightSettings.fogNear = 0;
+ envCtx->adjLightSettings.zFar = 0;
+
+ envCtx->sunPos.x = -(Math_SinS(((void)0, gSaveContext.save.time) - CLOCK_TIME(12, 0)) * 120.0f) * 25.0f;
+ envCtx->sunPos.y = (Math_CosS(((void)0, gSaveContext.save.time) - CLOCK_TIME(12, 0)) * 120.0f) * 25.0f;
+ envCtx->sunPos.z = (Math_CosS(((void)0, gSaveContext.save.time) - CLOCK_TIME(12, 0)) * 20.0f) * 25.0f;
+
+ envCtx->windDirection.x = 80;
+ envCtx->windDirection.y = 80;
+ envCtx->windDirection.z = 80;
+ envCtx->windSpeed = 20.0f;
+
+ envCtx->lightBlendEnabled = false;
+ envCtx->lightSettingOverride = LIGHT_SETTING_OVERRIDE_NONE;
+ envCtx->lightBlendRateOverride = LIGHT_BLENDRATE_OVERRIDE_NONE;
+
+ R_TIME_SPEED = envCtx->sceneTimeSpeed = 0;
+ R_TIME_SPEED = R_TIME_SPEED;
+ R_ENV_DISABLE_DBG = false;
+
+ CREG(64) = 0;
+
+ play->envCtx.precipitation[PRECIP_RAIN_MAX] = 0;
+ play->envCtx.precipitation[PRECIP_SNOW_CUR] = 0;
+ play->envCtx.precipitation[PRECIP_SNOW_MAX] = 0;
+ play->envCtx.precipitation[PRECIP_SOS_MAX] = 0;
+
+ D_801F4E31 = envCtx->skyboxConfig;
+
+ var_a0 = 0;
+ if (((void)0, gSaveContext.save.day) != 0) {
+ //! FAKE: temp
+ var_a0 = ((void)0, temp = gSaveContext.save.day) - 1;
+ }
+ envCtx->skyboxConfig = var_a0 + (D_801F4E31 * 3);
+ envCtx->changeSkyboxNextConfig = envCtx->skyboxConfig;
+
+ if (D_801F4E31 == 4) {
+ envCtx->skyboxConfig = 0xE;
+ envCtx->changeSkyboxNextConfig = envCtx->skyboxConfig;
+ } else if (D_801F4E31 == 5) {
+ envCtx->skyboxConfig = 0x10;
+ envCtx->changeSkyboxNextConfig = envCtx->skyboxConfig;
+ } else if (D_801F4E31 == 6) {
+ envCtx->skyboxConfig = 0x11;
+ envCtx->changeSkyboxNextConfig = envCtx->skyboxConfig;
+ } else if (D_801F4E31 == 7) {
+ envCtx->skyboxConfig = var_a0 + 0x12;
+ envCtx->changeSkyboxNextConfig = envCtx->skyboxConfig;
+ } else if (D_801F4E31 == 8) {
+ envCtx->skyboxConfig = var_a0 + 0x15;
+ envCtx->changeSkyboxNextConfig = envCtx->skyboxConfig;
+ } else if (D_801F4E31 == 9) {
+ envCtx->skyboxConfig = 0x18;
+ envCtx->changeSkyboxNextConfig = envCtx->skyboxConfig;
+ } else if (D_801F4E31 == 0xA) {
+ envCtx->skyboxConfig = var_a0 + 0x19;
+ envCtx->changeSkyboxNextConfig = envCtx->skyboxConfig;
+ }
+
+ if (var_a0 >= 3) {
+ envCtx->skyboxConfig = 0xD;
+ envCtx->changeSkyboxNextConfig = 0xD;
+ }
+
+ if (envCtx->skyboxConfig >= 0x1C) {
+ envCtx->skyboxConfig = 0;
+ envCtx->changeSkyboxNextConfig = 0;
+ }
+
+ D_801F4E74 = 0.0f;
+
+ if ((play->sceneId == SCENE_IKANA) &&
+ ((((void)0, gSaveContext.sceneLayer) == 0) || (((void)0, gSaveContext.sceneLayer) == 1)) &&
+ !CHECK_WEEKEVENTREG(WEEKEVENTREG_CLEARED_STONE_TOWER_TEMPLE)) {
+ play->skyboxId = SKYBOX_3;
+ envCtx->lightConfig = 5;
+ envCtx->changeLightNextConfig = 5;
+ D_801F4E74 = 1.0f;
+ }
+
+ if (gSaveContext.retainWeatherMode || (gSaveContext.respawnFlag != 0)) {
+ // if (gWeatherMode == WEATHER_MODE_2) {
+ // if (1) {}
+ // if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_CLEARED_STONE_TOWER_TEMPLE)) {
+ // play->skyboxId = SKYBOX_3;
+ // envCtx->lightConfig = 5;
+ // envCtx->changeLightNextConfig = 5;
+ // D_801F4E74 = 1.0f;
+ // } else {
+ // gWeatherMode = WEATHER_MODE_CLEAR;
+ // }
+ // }
+
+ switch (gWeatherMode) {
+ case WEATHER_MODE_2:
+ if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_CLEARED_STONE_TOWER_TEMPLE)) {
+ play->skyboxId = SKYBOX_3;
+ envCtx->lightConfig = 5;
+ envCtx->changeLightNextConfig = 5;
+ D_801F4E74 = 1.0f;
+ } else {
+ gWeatherMode = WEATHER_MODE_CLEAR;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ play->envCtx.precipitation[PRECIP_SNOW_CUR] = 0;
+ play->envCtx.precipitation[PRECIP_SNOW_MAX] = 0;
+
+ if (gWeatherMode == WEATHER_MODE_1) {
+ if ((CURRENT_DAY == 2) && (((void)0, gSaveContext.save.time) >= CLOCK_TIME(7, 0)) &&
+ (((void)0, gSaveContext.save.time) < CLOCK_TIME(17, 30))) {
+ if (Environment_GetStormState(play) != STORM_STATE_OFF) {
+ play->envCtx.precipitation[PRECIP_RAIN_MAX] = 60;
+ }
+ play->envCtx.precipitation[PRECIP_RAIN_CUR] = 60;
+ } else {
+ gWeatherMode = WEATHER_MODE_CLEAR;
+ Environment_StopStormNatureAmbience(play);
+ }
+ } else if (gWeatherMode == WEATHER_MODE_SNOW) {
+ play->envCtx.precipitation[PRECIP_SNOW_CUR] = 128;
+ play->envCtx.precipitation[PRECIP_SNOW_MAX] = 128;
+ Environment_StopStormNatureAmbience(play);
+ } else {
+ Environment_StopStormNatureAmbience(play);
+ }
+ } else {
+ gWeatherMode = WEATHER_MODE_CLEAR;
+ Environment_StopStormNatureAmbience(play);
+ }
+
+ gInterruptSongOfStorms = false;
+ gLightConfigAfterUnderwater = 0;
+ sSkyboxIsChanging = false;
+ gSaveContext.retainWeatherMode = false;
+
+ R_ENV_LIGHT1_DIR(0) = 80;
+ R_ENV_LIGHT1_DIR(1) = 80;
+ R_ENV_LIGHT1_DIR(2) = 80;
+
+ R_ENV_LIGHT2_DIR(0) = -80;
+ R_ENV_LIGHT2_DIR(1) = -80;
+ R_ENV_LIGHT2_DIR(2) = -80;
+
+ cREG(9) = 10;
+ cREG(10) = 0;
+ cREG(11) = 0;
+ cREG(12) = 0;
+ cREG(13) = 0;
+ cREG(14) = 0;
+ D_801F4DDC = 1;
+
+ for (i = 0; i < ARRAY_COUNT(sLightningBolts); i++) {
+ sLightningBolts[i].state = LIGHTNING_BOLT_INACTIVE;
+ }
+
+ play->roomCtx.unk7A[0] = 0;
+ play->roomCtx.unk7A[1] = 0;
+
+ for (i = 0; i < ARRAY_COUNT(play->csCtx.actorCues); i++) {
+ play->csCtx.actorCues[i] = NULL;
+ }
+
+ gCustomLensFlare1On = false;
+ gCustomLensFlare2On = false;
+ Rumble_StateReset();
+
+ sEnvSkyboxNumStars = 0;
+ gSkyboxNumStars = 0;
+ D_801BDBA8 = false;
+ sEnvIsTimeStopped = false;
+ sSunPrimAlpha = 255.0f;
+
+ Environment_UpdatePostmanEvents(play);
+}
+#else
#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_Init.s")
+#endif
u8 Environment_SmoothStepToU8(u8* pvalue, u8 target, u8 scale, u8 step, u8 minStep) {
s16 stepSize = 0;
@@ -667,11 +980,170 @@ Color_RGBA8 sSkyboxEnvColors[] = {
{ 60, 0, 10, 0 }, { 75, 45, 0, 0 }, { 20, 20, 89, 0 }, { 0, 7, 17, 0 },
};
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_UpdateSkybox.s")
+void Environment_UpdateSkybox(u8 skyboxId, EnvironmentContext* envCtx, SkyboxContext* skyboxCtx) {
+ size_t size;
+ s32 i;
+ u8 skybox1Index = 255;
+ u8 skybox2Index = 255;
+ u8 color1Index = 255;
+ u8 color2Index = 255;
+ u8 skyboxBlend = 0;
+ f32 colorWeight = 0.0f;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_EnableUnderwaterLights.s")
+ if (envCtx->skyboxConfig >= 0x1C) {
+ envCtx->skyboxConfig = 0;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_DisableUnderwaterLights.s")
+ if ((skyboxId == SKYBOX_NORMAL_SKY) || ((skyboxId == SKYBOX_3) && (D_801F4E74 < 1.0f))) {
+ if (envCtx->skyboxDisabled) {
+ return;
+ }
+
+ for (i = 0; i < ARRAY_COUNT(sTimeBasedSkyboxConfigs[envCtx->skyboxConfig]); i++) {
+ if ((gSaveContext.skyboxTime >= sTimeBasedSkyboxConfigs[envCtx->skyboxConfig][i].startTime) &&
+ ((gSaveContext.skyboxTime < sTimeBasedSkyboxConfigs[envCtx->skyboxConfig][i].endTime) ||
+ (sTimeBasedSkyboxConfigs[envCtx->skyboxConfig][i].endTime == (CLOCK_TIME(24, 0) - 1)))) {
+
+ skybox1Index = sTimeBasedSkyboxConfigs[envCtx->skyboxConfig][i].skybox1Index;
+ skybox2Index = sTimeBasedSkyboxConfigs[envCtx->skyboxConfig][i].skybox2Index;
+ if (skybox1Index == skybox2Index) {
+ sSkyboxIsChanging = false;
+ } else {
+ sSkyboxIsChanging = true;
+ }
+
+ if (sSkyboxIsChanging) {
+ skyboxBlend = Environment_LerpWeight(sTimeBasedSkyboxConfigs[envCtx->skyboxConfig][i].endTime,
+ sTimeBasedSkyboxConfigs[envCtx->skyboxConfig][i].startTime,
+ ((void)0, gSaveContext.skyboxTime)) *
+ 255.0f;
+ } else {
+ skyboxBlend = Environment_LerpWeight(sTimeBasedSkyboxConfigs[envCtx->skyboxConfig][i].endTime,
+ sTimeBasedSkyboxConfigs[envCtx->skyboxConfig][i].startTime,
+ ((void)0, gSaveContext.skyboxTime)) *
+ 255.0f;
+
+ if (skyboxBlend < 128) {
+ skyboxBlend = 255;
+ } else {
+ skyboxBlend = 0;
+ }
+
+ if ((envCtx->changeSkyboxState != CHANGE_SKYBOX_INACTIVE) &&
+ (envCtx->changeSkyboxState < CHANGE_SKYBOX_ACTIVE)) {
+ envCtx->changeSkyboxState++;
+ skyboxBlend = 0;
+ }
+ }
+ color1Index = sTimeBasedSkyboxConfigs[envCtx->skyboxConfig][i].color1Index;
+ color2Index = sTimeBasedSkyboxConfigs[envCtx->skyboxConfig][i].color2Index;
+ colorWeight = Environment_LerpWeight(sTimeBasedSkyboxConfigs[envCtx->skyboxConfig][i].endTime,
+ sTimeBasedSkyboxConfigs[envCtx->skyboxConfig][i].startTime,
+ gSaveContext.skyboxTime);
+ break;
+ }
+ }
+
+ if (CREG(64) != 0) {
+ skybox1Index = skybox2Index = CREG(71);
+ } else {
+ CREG(71) = skybox1Index;
+ }
+
+ if (envCtx->changeSkyboxState >= CHANGE_SKYBOX_ACTIVE) {
+ skybox1Index = sTimeBasedSkyboxConfigs[envCtx->skyboxConfig][i].skybox1Index;
+ skybox2Index = sTimeBasedSkyboxConfigs[envCtx->changeSkyboxNextConfig][i].skybox2Index;
+ color1Index = sTimeBasedSkyboxConfigs[envCtx->skyboxConfig][i].color1Index;
+ color2Index = sTimeBasedSkyboxConfigs[envCtx->changeSkyboxNextConfig][i].color2Index;
+ skyboxBlend = ((envCtx->changeDuration - (f32)envCtx->changeSkyboxTimer) / envCtx->changeDuration) * 255.0f;
+ colorWeight = (envCtx->changeDuration - (f32)envCtx->changeSkyboxTimer) / envCtx->changeDuration;
+ envCtx->changeSkyboxTimer--;
+ if (envCtx->changeSkyboxTimer <= 0) {
+ envCtx->changeSkyboxState = CHANGE_SKYBOX_INACTIVE;
+ envCtx->skyboxConfig = envCtx->changeSkyboxNextConfig;
+ }
+ }
+
+ if ((envCtx->skybox1Index != skybox1Index) && (envCtx->skyboxDmaState == SKYBOX_DMA_INACTIVE)) {
+ envCtx->skyboxDmaState = SKYBOX_DMA_TEXTURE1_START;
+ size = sNormalSkyFiles[skybox1Index].file.vromEnd - sNormalSkyFiles[skybox1Index].file.vromStart;
+ osCreateMesgQueue(&envCtx->loadQueue, envCtx->loadMsg, ARRAY_COUNT(envCtx->loadMsg));
+ DmaMgr_SendRequestImpl(&envCtx->dmaRequest, skyboxCtx->staticSegments[0],
+ sNormalSkyFiles[skybox1Index].file.vromStart, size, 0, &envCtx->loadQueue, NULL);
+ envCtx->skybox1Index = skybox1Index;
+ }
+
+ if ((envCtx->skybox2Index != skybox2Index) && (envCtx->skyboxDmaState == SKYBOX_DMA_INACTIVE)) {
+ envCtx->skyboxDmaState = SKYBOX_DMA_TEXTURE2_START;
+ size = sNormalSkyFiles[skybox2Index].file.vromEnd - sNormalSkyFiles[skybox2Index].file.vromStart;
+ osCreateMesgQueue(&envCtx->loadQueue, envCtx->loadMsg, ARRAY_COUNT(envCtx->loadMsg));
+ DmaMgr_SendRequestImpl(&envCtx->dmaRequest, skyboxCtx->staticSegments[1],
+ sNormalSkyFiles[skybox2Index].file.vromStart, size, 0, &envCtx->loadQueue, NULL);
+ envCtx->skybox2Index = skybox2Index;
+ }
+
+ if ((envCtx->skyboxDmaState == SKYBOX_DMA_TEXTURE1_START) ||
+ (envCtx->skyboxDmaState == SKYBOX_DMA_TEXTURE2_START)) {
+ if (osRecvMesg(&envCtx->loadQueue, NULL, 0) == 0) {
+ envCtx->skyboxDmaState = SKYBOX_DMA_INACTIVE;
+ }
+ }
+
+ envCtx->skyboxBlend = skyboxBlend;
+ Skybox_SetColors(skyboxCtx,
+ LERPIMP_ALT(sSkyboxPrimColors[color1Index].r, sSkyboxPrimColors[color2Index].r, colorWeight),
+ LERPIMP_ALT(sSkyboxPrimColors[color1Index].g, sSkyboxPrimColors[color2Index].g, colorWeight),
+ LERPIMP_ALT(sSkyboxPrimColors[color1Index].b, sSkyboxPrimColors[color2Index].b, colorWeight),
+ LERPIMP_ALT(sSkyboxEnvColors[color1Index].r, sSkyboxEnvColors[color2Index].r, colorWeight),
+ LERPIMP_ALT(sSkyboxEnvColors[color1Index].g, sSkyboxEnvColors[color2Index].g, colorWeight),
+ LERPIMP_ALT(sSkyboxEnvColors[color1Index].b, sSkyboxEnvColors[color2Index].b, colorWeight));
+ }
+}
+
+void Environment_EnableUnderwaterLights(PlayState* play, s32 waterLightsIndex) {
+ if (waterLightsIndex == 0x1F) {
+ waterLightsIndex = 0;
+ }
+
+ if (play->envCtx.lightMode == LIGHT_MODE_TIME) {
+ if (!D_801F4F31) {
+ D_801F4F31 = true;
+ gLightConfigAfterUnderwater = play->envCtx.changeLightNextConfig;
+ if (play->envCtx.lightConfig != waterLightsIndex) {
+ play->envCtx.lightConfig = waterLightsIndex;
+ play->envCtx.changeLightNextConfig = waterLightsIndex;
+ }
+ } else if ((play->envCtx.lightConfig != waterLightsIndex) && (play->envCtx.changeLightTimer == 0)) {
+ play->envCtx.changeLightEnabled = true;
+ play->envCtx.changeLightNextConfig = waterLightsIndex;
+ play->envCtx.changeDuration = 20;
+ play->envCtx.changeLightTimer = play->envCtx.changeDuration;
+ }
+ } else if (play->envCtx.lightSettingOverride == LIGHT_SETTING_OVERRIDE_NONE) {
+ if (!D_801F4F31) {
+ D_801F4F31 = true;
+ gLightConfigAfterUnderwater = play->envCtx.lightSetting;
+ }
+ play->envCtx.lightBlendEnabled = false; // instantly switch to water lights
+ play->envCtx.lightSettingOverride = waterLightsIndex;
+ }
+}
+
+void Environment_DisableUnderwaterLights(PlayState* play) {
+ if (play->envCtx.lightMode == LIGHT_MODE_TIME) {
+ if (D_801F4F31) {
+ D_801F4F31 = false;
+ play->envCtx.lightConfig = gLightConfigAfterUnderwater;
+ play->envCtx.changeLightNextConfig = gLightConfigAfterUnderwater;
+ }
+ } else if (D_801F4F31) {
+ D_801F4F31 = false;
+ play->envCtx.lightSetting = gLightConfigAfterUnderwater;
+ play->envCtx.lightBlendEnabled = false; // instantly switch to previous lights
+ play->envCtx.lightSettingOverride = LIGHT_SETTING_OVERRIDE_NONE;
+ play->envCtx.lightBlend = 1.0f;
+ }
+}
void Environment_WipeRumbleRequests(void) {
if ((gSaveContext.gameMode != GAMEMODE_NORMAL) && (gSaveContext.gameMode != GAMEMODE_END_CREDITS)) {
@@ -679,15 +1151,118 @@ void Environment_WipeRumbleRequests(void) {
}
}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_UpdateSkyboxRotY.s")
+void Environment_UpdateSkyboxRotY(PlayState* play) {
+ if ((play->pauseCtx.state == PAUSE_STATE_OFF) && (play->pauseCtx.debugEditor == DEBUG_EDITOR_NONE) &&
+ ((play->skyboxId == SKYBOX_NORMAL_SKY) || (play->skyboxId == SKYBOX_3))) {
+ play->skyboxCtx.rot.y -= R_TIME_SPEED * 1.0e-4f;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_UpdateNextDayTime.s")
+void Environment_UpdateNextDayTime(void) {
+ if ((gSaveContext.nextDayTime >= 0xFF00) && (gSaveContext.nextDayTime != NEXT_TIME_NONE)) {
+ gSaveContext.nextDayTime -= 0x10;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_UpdateTime.s")
+ // nextDayTime is used as both a time of day value and a timer to delay sfx when changing days.
+ // When Sun's Song is played, nextDayTime is set to 0x8000 or 0 for day and night respectively.
+ // These values will actually get used as a time of day value.
+ // After this, nextDayTime is assigned magic values of 0xFFFE or 0xFFFD for day and night respectively.
+ // From here, 0x10 is decremented from nextDayTime until it reaches either 0xFF0E or 0xFF0D, effectively
+ // delaying the chicken crow or dog howl sfx by 15 frames when loading the new area.
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/func_800F6CEC.s")
+ if (gSaveContext.nextDayTime == (NEXT_TIME_DAY_SET - (15 * 0x10))) {
+ Audio_PlaySfx(NA_SE_EV_CHICKEN_CRY_M);
+ gSaveContext.nextDayTime = NEXT_TIME_NONE;
+ } else if (gSaveContext.nextDayTime == (NEXT_TIME_NIGHT_SET - (15 * 0x10))) {
+ Audio_PlaySfx_2(NA_SE_EV_DOG_CRY_EVENING);
+ gSaveContext.nextDayTime = NEXT_TIME_NONE;
+ }
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/func_800F6EA4.s")
+void Environment_UpdateTime(PlayState* play, EnvironmentContext* envCtx, PauseContext* pauseCtx, MessageContext* msgCtx,
+ GameOverContext* gameOverCtx) {
+ u16 time;
+
+ if (!sEnvIsTimeStopped && (pauseCtx->state == PAUSE_STATE_OFF) && (gameOverCtx->state == GAMEOVER_INACTIVE)) {
+ if ((msgCtx->msgMode == MSGMODE_NONE) || (msgCtx->currentTextId == 0xF7) || (msgCtx->currentTextId == 0x20D2) ||
+ (msgCtx->currentTextId == 0x140C) ||
+ ((msgCtx->currentTextId >= 0x100) && (msgCtx->currentTextId <= 0x200)) ||
+ (gSaveContext.gameMode == GAMEMODE_END_CREDITS)) {
+ if (!FrameAdvance_IsEnabled(&play->state) &&
+ ((play->transitionMode == TRANS_MODE_OFF) || (gSaveContext.gameMode != GAMEMODE_NORMAL))) {
+ if (play->transitionTrigger == TRANS_TRIGGER_OFF) {
+ if ((CutsceneManager_GetCurrentCsId() == CS_ID_NONE) && !Play_InCsMode(play)) {
+ gSaveContext.save.time = ((void)0, gSaveContext.save.time) + (u16)R_TIME_SPEED;
+ if (R_TIME_SPEED != 0) {
+ gSaveContext.save.time =
+ ((void)0, gSaveContext.save.time) + (u16)((void)0, gSaveContext.save.timeSpeedOffset);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if ((((void)0, gSaveContext.skyboxTime) >= CLOCK_TIME(6, 0)) ||
+ (((void)0, gSaveContext.save.time) < CLOCK_TIME(6, 0)) ||
+ (((void)0, gSaveContext.save.time) >= (CLOCK_TIME(6, 0) + 0x10))) {
+ gSaveContext.skyboxTime = gSaveContext.save.time;
+ }
+
+ time = ((void)0, gSaveContext.save.time);
+
+ if ((time >= CLOCK_TIME(18, 0)) || (time < CLOCK_TIME(6, 0))) {
+ gSaveContext.save.isNight = true;
+ } else {
+ gSaveContext.save.isNight = false;
+ }
+}
+
+void func_800F6CEC(PlayState* play, u8 arg1, AdjLightSettings* adjLightSettings, EnvLightSettings* lightSettings) {
+ s32 phi_t1;
+ s32 temp_v1_2;
+ s32 temp_v1 = (arg1 % 4);
+
+ if ((((void)0, gSaveContext.save.day) >= 2) && (arg1 >= 4) && (arg1 < 8)) {
+ temp_v1_2 = (((void)0, gSaveContext.save.day) + 1) * 4;
+ for (phi_t1 = 0; phi_t1 != 3; phi_t1++) {
+ adjLightSettings->ambientColor[phi_t1] =
+ lightSettings[temp_v1_2 + temp_v1].ambientColor[phi_t1] - lightSettings[temp_v1].ambientColor[phi_t1];
+ adjLightSettings->light1Color[phi_t1] =
+ lightSettings[temp_v1_2 + temp_v1].light1Color[phi_t1] - lightSettings[temp_v1].light1Color[phi_t1];
+ adjLightSettings->light2Color[phi_t1] =
+ lightSettings[temp_v1_2 + temp_v1].light2Color[phi_t1] - lightSettings[temp_v1].light2Color[phi_t1];
+ adjLightSettings->fogColor[phi_t1] =
+ lightSettings[temp_v1_2 + temp_v1].fogColor[phi_t1] - lightSettings[temp_v1].fogColor[phi_t1];
+ }
+ adjLightSettings->fogNear =
+ lightSettings[temp_v1_2 + temp_v1].blendRateAndFogNear - lightSettings[temp_v1].blendRateAndFogNear;
+ }
+
+ if ((arg1 >= 4) && (arg1 < 8) && (gWeatherMode == WEATHER_MODE_1)) {
+ adjLightSettings->ambientColor[0] = -50;
+ adjLightSettings->ambientColor[1] = -100;
+ adjLightSettings->ambientColor[2] = -100;
+ adjLightSettings->light1Color[0] = -100;
+ adjLightSettings->light1Color[1] = -100;
+ adjLightSettings->light1Color[2] = -100;
+ adjLightSettings->light2Color[0] = -100;
+ adjLightSettings->light2Color[1] = -100;
+ adjLightSettings->light2Color[2] = -100;
+
+ temp_v1 = arg1;
+ adjLightSettings->fogColor[0] = -lightSettings[temp_v1].fogColor[0] + 30;
+ adjLightSettings->fogColor[1] = -lightSettings[temp_v1].fogColor[1] + 30;
+ adjLightSettings->fogColor[2] = -lightSettings[temp_v1].fogColor[2] + 45;
+ }
+}
+
+u8 Environment_LerpColor(f32 to, f32 from, f32 lerp) {
+ to = CLAMP(to, 0.0f, 255.0f);
+ from = CLAMP(from, 0.0f, 255.0f);
+
+ return ((to - from) * lerp) + from;
+}
s32 Environment_IsSceneUpsideDown(PlayState* play) {
s32 ret = false;
@@ -698,12 +1273,399 @@ s32 Environment_IsSceneUpsideDown(PlayState* play) {
return ret;
}
+#ifdef NON_MATCHING
+// Something is happening with the indexing of:
+// `lightSettingsList[(s32)envCtx->lightSetting]` and `lightSettingsList[(s32)envCtx->prevLightSetting]`
+void Environment_UpdateLights(PlayState* play, EnvironmentContext* envCtx, LightContext* lightCtx) {
+ EnvLightSettings* lightSettingsList;
+ f32 var_fs3;
+ s32 i;
+ s32 j;
+ f32 temp_fv0;
+ s32 adjustment;
+ u16 temp_s0_2;
+ u16 var_v0;
+ AdjLightSettings spA4[4];
+
+ var_fs3 = 0.0f;
+ __osMemset(spA4, 0, sizeof(AdjLightSettings) * ARRAY_COUNT(spA4));
+ lightSettingsList = play->envCtx.lightSettingsList;
+
+ if ((envCtx->lightSettingOverride != LIGHT_SETTING_OVERRIDE_NONE) &&
+ (envCtx->lightBlendOverride != LIGHT_BLEND_OVERRIDE_FULL_CONTROL) &&
+ (envCtx->lightSetting != envCtx->lightSettingOverride) && (envCtx->lightBlend >= 1.0f) &&
+ (envCtx->lightSettingOverride <= LIGHT_SETTING_MAX)) {
+
+ envCtx->lightBlend = 0.0f;
+ envCtx->prevLightSetting = envCtx->lightSetting;
+ envCtx->lightSetting = envCtx->lightSettingOverride;
+ }
+
+ if (envCtx->lightSettingOverride != LIGHT_SETTING_OVERRIDE_FULL_CONTROL) {
+ if ((envCtx->lightMode == LIGHT_MODE_TIME) && (envCtx->lightSettingOverride == LIGHT_SETTING_OVERRIDE_NONE)) {
+ for (i = 0; i < ARRAY_COUNT(sTimeBasedLightConfigs[envCtx->lightConfig]); i++) {
+ f32 arg0;
+ f32 arg1;
+ u16 startTime;
+ u16 endTime;
+ u8 sp97;
+ u8 sp96;
+ u8 sp95;
+ u8 sp94;
+
+ startTime = sTimeBasedLightConfigs[envCtx->lightConfig][i].startTime;
+ endTime = sTimeBasedLightConfigs[envCtx->lightConfig][i].endTime;
+
+ sp97 = sTimeBasedLightConfigs[envCtx->lightConfig][i].lightSetting;
+ sp95 = sTimeBasedLightConfigs[envCtx->lightConfig][i].nextLightSetting;
+ sp96 = sTimeBasedLightConfigs[envCtx->changeLightNextConfig][i].lightSetting;
+ sp94 = sTimeBasedLightConfigs[envCtx->changeLightNextConfig][i].nextLightSetting;
+
+ if ((gSaveContext.skyboxTime >= startTime) &&
+ ((gSaveContext.skyboxTime < endTime) || (endTime == 0xFFFF))) {
+ u8 blend8[2]; // sp90
+ s16 blend16[2]; // sp8C
+
+ func_800F6CEC(play, sp97, &spA4[0], lightSettingsList);
+ func_800F6CEC(play, sp95, &spA4[1], lightSettingsList);
+ func_800F6CEC(play, sp96, &spA4[2], lightSettingsList);
+ func_800F6CEC(play, sp94, &spA4[3], lightSettingsList);
+
+ if ((sp94 >= envCtx->numLightSettings) && !D_801BDBA8) {
+ D_801BDBA8 = true;
+ }
+
+ if ((sp97 >= envCtx->numLightSettings) || (sp95 >= envCtx->numLightSettings) ||
+ (sp96 >= envCtx->numLightSettings) || (sp94 >= envCtx->numLightSettings)) {
+ sp97 = 0;
+ sp95 = 0;
+ sp96 = 0;
+ sp94 = 0;
+ }
+
+ temp_fv0 = Environment_LerpWeight(endTime, startTime, ((void)0, gSaveContext.skyboxTime));
+
+ sSandstormColorIndex = sp97 & 3;
+ sNextSandstormColorIndex = sp95 & 3;
+ sSandstormLerpScale = temp_fv0;
+
+ if (envCtx->changeLightEnabled) {
+ var_fs3 = ((f32)envCtx->changeDuration - envCtx->changeLightTimer) / envCtx->changeDuration;
+ envCtx->changeLightTimer--;
+
+ if (envCtx->changeLightTimer <= 0) {
+ envCtx->changeLightEnabled = false;
+ envCtx->lightConfig = envCtx->changeLightNextConfig;
+ }
+ }
+
+ for (j = 0; j < 3; j++) {
+ arg0 = lightSettingsList[(s32)sp95].ambientColor[j] + spA4[1].ambientColor[j];
+ arg1 = lightSettingsList[(s32)sp97].ambientColor[j] + spA4[0].ambientColor[j];
+ blend8[0] = Environment_LerpColor(arg0, arg1, temp_fv0);
+
+ arg0 = lightSettingsList[(s32)sp94].ambientColor[j] + spA4[3].ambientColor[j];
+ arg1 = lightSettingsList[(s32)sp96].ambientColor[j] + spA4[2].ambientColor[j];
+ blend8[1] = Environment_LerpColor(arg0, arg1, temp_fv0);
+
+ envCtx->lightSettings.ambientColor[j] = LERPIMP_ALT(blend8[0], blend8[1], var_fs3);
+ }
+
+ if (Environment_IsSceneUpsideDown(play)) {
+ var_v0 = ((void)0, gSaveContext.save.time) + CLOCK_TIME(12, 0);
+ } else {
+ var_v0 = ((void)0, gSaveContext.save.time);
+ }
+ temp_s0_2 = var_v0 - CLOCK_TIME(12, 0);
+
+ envCtx->lightSettings.light1Dir[0] = -(Math_SinS(temp_s0_2) * 120.0f);
+ envCtx->lightSettings.light1Dir[1] = Math_CosS(temp_s0_2) * 120.0f;
+ envCtx->lightSettings.light1Dir[2] = Math_CosS(temp_s0_2) * 20.0f;
+
+ envCtx->lightSettings.light2Dir[0] = -envCtx->lightSettings.light1Dir[0];
+ envCtx->lightSettings.light2Dir[1] = -envCtx->lightSettings.light1Dir[1];
+ envCtx->lightSettings.light2Dir[2] = -envCtx->lightSettings.light1Dir[2];
+
+ for (j = 0; j < 3; j++) {
+ arg0 = lightSettingsList[(s32)sp95].light1Color[j] + spA4[1].light1Color[j];
+ arg1 = lightSettingsList[(s32)sp97].light1Color[j] + spA4[0].light1Color[j];
+ blend8[0] = Environment_LerpColor(arg0, arg1, temp_fv0);
+
+ arg0 = lightSettingsList[(s32)sp94].light1Color[j] + spA4[3].light1Color[j];
+ arg1 = lightSettingsList[(s32)sp96].light1Color[j] + spA4[2].light1Color[j];
+ blend8[1] = Environment_LerpColor(arg0, arg1, temp_fv0);
+
+ envCtx->lightSettings.light1Color[j] = LERPIMP_ALT(blend8[0], blend8[1], var_fs3);
+
+ arg0 = lightSettingsList[(s32)sp95].light2Color[j] + spA4[1].light2Color[j];
+ arg1 = lightSettingsList[(s32)sp97].light2Color[j] + spA4[0].light2Color[j];
+ blend8[0] = Environment_LerpColor(arg0, arg1, temp_fv0);
+
+ arg0 = lightSettingsList[(s32)sp94].light2Color[j] + spA4[3].light2Color[j];
+ arg1 = lightSettingsList[(s32)sp96].light2Color[j] + spA4[2].light2Color[j];
+ blend8[1] = Environment_LerpColor(arg0, arg1, temp_fv0);
+
+ envCtx->lightSettings.light2Color[j] = LERPIMP_ALT(blend8[0], blend8[1], var_fs3);
+ }
+
+ for (j = 0; j < 3; j++) {
+ arg0 = lightSettingsList[(s32)sp95].fogColor[j] + spA4[1].fogColor[j];
+ arg1 = lightSettingsList[(s32)sp97].fogColor[j] + spA4[0].fogColor[j];
+ blend8[0] = Environment_LerpColor(arg0, arg1, temp_fv0);
+
+ arg0 = lightSettingsList[(s32)sp94].fogColor[j] + spA4[3].fogColor[j];
+ arg1 = lightSettingsList[(s32)sp96].fogColor[j] + spA4[2].fogColor[j];
+ blend8[1] = Environment_LerpColor(arg0, arg1, temp_fv0);
+
+ envCtx->lightSettings.fogColor[j] = LERPIMP_ALT(blend8[0], blend8[1], var_fs3);
+ }
+
+ blend16[0] = S16_LERP(ENV_LIGHT_SETTINGS_FOG_NEAR(lightSettingsList[(s32)sp97].blendRateAndFogNear),
+ ENV_LIGHT_SETTINGS_FOG_NEAR(lightSettingsList[(s32)sp95].blendRateAndFogNear),
+ temp_fv0);
+ blend16[1] = S16_LERP(ENV_LIGHT_SETTINGS_FOG_NEAR(lightSettingsList[(s32)sp96].blendRateAndFogNear),
+ ENV_LIGHT_SETTINGS_FOG_NEAR(lightSettingsList[(s32)sp94].blendRateAndFogNear),
+ temp_fv0);
+ envCtx->lightSettings.fogNear = LERPIMP_ALT(blend16[0], blend16[1], var_fs3);
+
+ blend16[0] =
+ S16_LERP(lightSettingsList[(s32)sp97].zFar, lightSettingsList[(s32)sp95].zFar, temp_fv0);
+ blend16[1] =
+ S16_LERP(lightSettingsList[(s32)sp96].zFar, lightSettingsList[(s32)sp94].zFar, temp_fv0);
+ envCtx->lightSettings.zFar = LERPIMP_ALT(blend16[0], blend16[1], var_fs3);
+
+ break;
+ }
+ }
+ } else {
+ if ((envCtx->lightSetting >= envCtx->numLightSettings) && !D_801BDBA8) {
+ D_801BDBA8 = true;
+ }
+
+ if (!envCtx->lightBlendEnabled) {
+ for (i = 0; i < 3; i++) {
+ envCtx->lightSettings.ambientColor[i] =
+ lightSettingsList[(s32)envCtx->lightSetting].ambientColor[i];
+ envCtx->lightSettings.light1Dir[i] = lightSettingsList[(s32)envCtx->lightSetting].light1Dir[i];
+ envCtx->lightSettings.light1Color[i] = lightSettingsList[(s32)envCtx->lightSetting].light1Color[i];
+ envCtx->lightSettings.light2Dir[i] = lightSettingsList[(s32)envCtx->lightSetting].light2Dir[i];
+ envCtx->lightSettings.light2Color[i] = lightSettingsList[(s32)envCtx->lightSetting].light2Color[i];
+ envCtx->lightSettings.fogColor[i] = lightSettingsList[(s32)envCtx->lightSetting].fogColor[i];
+ }
+ envCtx->lightSettings.fogNear =
+ ENV_LIGHT_SETTINGS_FOG_NEAR(lightSettingsList[(s32)envCtx->lightSetting].blendRateAndFogNear);
+ envCtx->lightSettings.zFar = lightSettingsList[(s32)envCtx->lightSetting].zFar;
+ envCtx->lightBlend = 1.0f;
+ } else {
+ u8 var_v0_3;
+
+ //! FAKE:
+ if (1) {}
+
+ var_v0_3 =
+ ENV_LIGHT_SETTINGS_BLEND_RATE_U8(lightSettingsList[(s32)envCtx->lightSetting].blendRateAndFogNear);
+
+ if (var_v0_3 == 0) {
+ var_v0_3++;
+ }
+
+ if (envCtx->lightBlendRateOverride != LIGHT_BLENDRATE_OVERRIDE_NONE) {
+ var_v0_3 = envCtx->lightBlendRateOverride;
+ }
+
+ if (envCtx->lightBlendOverride == LIGHT_BLEND_OVERRIDE_NONE) {
+ envCtx->lightBlend += var_v0_3 / 255.0f;
+ }
+
+ if (envCtx->lightBlend > 1.0f) {
+ envCtx->lightBlend = 1.0f;
+ }
+
+ for (i = 0; i < 3; i++) {
+ envCtx->lightSettings.ambientColor[i] =
+ LERPIMP_ALT(lightSettingsList[(s32)envCtx->prevLightSetting].ambientColor[i],
+ lightSettingsList[(s32)envCtx->lightSetting].ambientColor[i], envCtx->lightBlend);
+ envCtx->lightSettings.light1Dir[i] =
+ LERPIMP_ALT(lightSettingsList[(s32)envCtx->prevLightSetting].light1Dir[i],
+ lightSettingsList[(s32)envCtx->lightSetting].light1Dir[i], envCtx->lightBlend);
+ envCtx->lightSettings.light1Color[i] =
+ LERPIMP_ALT(lightSettingsList[(s32)envCtx->prevLightSetting].light1Color[i],
+ lightSettingsList[(s32)envCtx->lightSetting].light1Color[i], envCtx->lightBlend);
+ envCtx->lightSettings.light2Dir[i] =
+ LERPIMP_ALT(lightSettingsList[(s32)envCtx->prevLightSetting].light2Dir[i],
+ lightSettingsList[(s32)envCtx->lightSetting].light2Dir[i], envCtx->lightBlend);
+ envCtx->lightSettings.light2Color[i] =
+ LERPIMP_ALT(lightSettingsList[(s32)envCtx->prevLightSetting].light2Color[i],
+ lightSettingsList[(s32)envCtx->lightSetting].light2Color[i], envCtx->lightBlend);
+ envCtx->lightSettings.fogColor[i] =
+ LERPIMP_ALT(lightSettingsList[(s32)envCtx->prevLightSetting].fogColor[i],
+ lightSettingsList[(s32)envCtx->lightSetting].fogColor[i], envCtx->lightBlend);
+ }
+
+ envCtx->lightSettings.fogNear = LERPIMP_ALT(
+ ENV_LIGHT_SETTINGS_FOG_NEAR(lightSettingsList[(s32)envCtx->prevLightSetting].blendRateAndFogNear),
+ ENV_LIGHT_SETTINGS_FOG_NEAR(lightSettingsList[(s32)envCtx->lightSetting].blendRateAndFogNear),
+ envCtx->lightBlend);
+
+ envCtx->lightSettings.zFar =
+ LERPIMP_ALT(lightSettingsList[(s32)envCtx->prevLightSetting].zFar,
+ lightSettingsList[(s32)envCtx->lightSetting].zFar, envCtx->lightBlend);
+ }
+ }
+ }
+
+ envCtx->lightBlendEnabled = true;
+
+ for (i = 0; i < 3; i++) {
+ if ((s16)(envCtx->lightSettings.ambientColor[i] + envCtx->adjLightSettings.ambientColor[i]) > 255) {
+ lightCtx->ambientColor[i] = 255;
+ } else if ((s16)(envCtx->lightSettings.ambientColor[i] + envCtx->adjLightSettings.ambientColor[i]) < 0) {
+ lightCtx->ambientColor[i] = 0;
+ } else {
+ lightCtx->ambientColor[i] =
+ (s16)(envCtx->lightSettings.ambientColor[i] + envCtx->adjLightSettings.ambientColor[i]);
+ }
+
+ if ((s16)(envCtx->lightSettings.light1Color[i] + envCtx->adjLightSettings.light1Color[i]) > 255) {
+ envCtx->dirLight1.params.dir.color[i] = 255;
+ } else if ((s16)(envCtx->lightSettings.light1Color[i] + envCtx->adjLightSettings.light1Color[i]) < 0) {
+ envCtx->dirLight1.params.dir.color[i] = 0;
+ } else {
+ envCtx->dirLight1.params.dir.color[i] =
+ (s16)(envCtx->lightSettings.light1Color[i] + envCtx->adjLightSettings.light1Color[i]);
+ }
+
+ if ((s16)(envCtx->lightSettings.light2Color[i] + envCtx->adjLightSettings.light2Color[i]) > 255) {
+ envCtx->dirLight2.params.dir.color[i] = 255;
+ } else if ((s16)(envCtx->lightSettings.light2Color[i] + envCtx->adjLightSettings.light2Color[i]) < 0) {
+ envCtx->dirLight2.params.dir.color[i] = 0;
+ } else {
+ envCtx->dirLight2.params.dir.color[i] =
+ (s16)(envCtx->lightSettings.light2Color[i] + envCtx->adjLightSettings.light2Color[i]);
+ }
+
+ if ((s16)(envCtx->lightSettings.fogColor[i] + envCtx->adjLightSettings.fogColor[i]) > 255) {
+ lightCtx->fogColor[i] = 255;
+ } else if ((s16)(envCtx->lightSettings.fogColor[i] + envCtx->adjLightSettings.fogColor[i]) < 0) {
+ lightCtx->fogColor[i] = 0;
+ } else {
+ lightCtx->fogColor[i] = (s16)(envCtx->lightSettings.fogColor[i] + envCtx->adjLightSettings.fogColor[i]);
+ }
+ }
+
+ // Set both directional light directions
+ envCtx->dirLight1.params.dir.x = envCtx->lightSettings.light1Dir[0];
+ envCtx->dirLight1.params.dir.y = envCtx->lightSettings.light1Dir[1];
+ envCtx->dirLight1.params.dir.z = envCtx->lightSettings.light1Dir[2];
+
+ envCtx->dirLight2.params.dir.x = envCtx->lightSettings.light2Dir[0];
+ envCtx->dirLight2.params.dir.y = envCtx->lightSettings.light2Dir[1];
+ envCtx->dirLight2.params.dir.z = envCtx->lightSettings.light2Dir[2];
+
+ // Adjust fog near and far if necessary
+ adjustment = envCtx->lightSettings.fogNear + envCtx->adjLightSettings.fogNear;
+
+ if (adjustment <= ENV_FOGNEAR_MAX) {
+ lightCtx->fogNear = adjustment;
+ } else {
+ lightCtx->fogNear = ENV_FOGNEAR_MAX;
+ }
+
+ adjustment = envCtx->lightSettings.zFar + envCtx->adjLightSettings.zFar;
+
+ if (adjustment <= ENV_ZFAR_MAX) {
+ lightCtx->zFar = adjustment;
+ } else {
+ lightCtx->zFar = ENV_ZFAR_MAX;
+ }
+
+ if ((envCtx->dirLight1.params.dir.x == 0) && (envCtx->dirLight1.params.dir.y == 0) &&
+ (envCtx->dirLight1.params.dir.z == 0)) {
+ envCtx->dirLight1.params.dir.x = 1;
+ }
+ if ((envCtx->dirLight2.params.dir.x == 0) && (envCtx->dirLight2.params.dir.y == 0) &&
+ (envCtx->dirLight2.params.dir.z == 0)) {
+ envCtx->dirLight2.params.dir.x = 1;
+ }
+}
+#else
+void Environment_UpdateLights(PlayState* play, EnvironmentContext* envCtx, LightContext* lightCtx);
#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_UpdateLights.s")
+#endif
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_UpdateSun.s")
+void Environment_UpdateSun(PlayState* play) {
+ f32 temp_f0;
+ s16 temp_a0;
+ u16 phi_v0;
-void func_800F88C4(u16 weekEventFlag);
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/func_800F88C4.s")
+ if (!play->envCtx.sunDisabled) {
+ if (play->envCtx.precipitation[PRECIP_RAIN_CUR] != 0) {
+ Math_SmoothStepToF(&sSunPrimAlpha, 0.0f, 0.5f, 4.0f, 0.01f);
+ } else {
+ Math_SmoothStepToF(&sSunPrimAlpha, 255.0f, 0.5f, 4.0f, 0.01f);
+ }
+
+ if (Environment_IsSceneUpsideDown(play)) {
+ phi_v0 = ((void)0, gSaveContext.save.time) + CLOCK_TIME(12, 0);
+ } else {
+ phi_v0 = ((void)0, gSaveContext.save.time);
+ }
+
+ temp_a0 = phi_v0 - CLOCK_TIME(12, 0);
+
+ if (play->csCtx.state != CS_STATE_IDLE) {
+ Math_SmoothStepToF(&play->envCtx.sunPos.x, -(Math_SinS(temp_a0) * 120.0f) * 25.0f, 1.0f, 0.8f, 0.8f);
+ Math_SmoothStepToF(&play->envCtx.sunPos.y, Math_CosS(temp_a0) * 120.0f * 25.0f, 1.0f, 0.8f, 0.8f);
+ //! @bug This should be z.
+ Math_SmoothStepToF(&play->envCtx.sunPos.y, Math_CosS(temp_a0) * 20.0f * 25.0f, 1.0f, 0.8f, 0.8f);
+ } else {
+ play->envCtx.sunPos.x = -(Math_SinS(temp_a0) * 120.0f) * 25.0f;
+ play->envCtx.sunPos.y = Math_CosS(temp_a0) * 120.0f * 25.0f;
+ play->envCtx.sunPos.z = Math_CosS(temp_a0) * 20.0f * 25.0f;
+ }
+
+ temp_f0 = play->envCtx.sunPos.y / 25.0f;
+ if (Environment_IsSceneUpsideDown(play)) {
+ temp_f0 = -temp_f0;
+ }
+
+ sSunEnvAlpha = temp_f0 / 80.0f * 255.0f;
+ if (sSunEnvAlpha < 0.0f) {
+ sSunEnvAlpha = 0.0f;
+ }
+ if (sSunEnvAlpha > 255.0f) {
+ sSunEnvAlpha = 255.0f;
+ }
+ sSunEnvAlpha = 255.0f - sSunEnvAlpha;
+
+ sSunColor = temp_f0 / 80.0f;
+ if (sSunColor < 0.0f) {
+ sSunColor = 0.0f;
+ }
+ if (sSunColor > 1.0f) {
+ sSunColor = 1.0f;
+ }
+
+ sSunScale = (2.0f * sSunColor) + 12.0f;
+ }
+}
+
+void func_800F88C4(u16 weekEventFlag) {
+ if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_28_08) && !CHECK_WEEKEVENTREG(WEEKEVENTREG_28_10) &&
+ CHECK_WEEKEVENTREG(weekEventFlag)) {
+ if (CHECK_WEEKEVENTREG(WEEKEVENTREG_91_04)) {
+ SET_WEEKEVENTREG(WEEKEVENTREG_28_08);
+ SET_WEEKEVENTREG(WEEKEVENTREG_90_08);
+ SET_WEEKEVENTREG(WEEKEVENTREG_51_02);
+ }
+
+ if (CHECK_WEEKEVENTREG(WEEKEVENTREG_91_08)) {
+ SET_WEEKEVENTREG(WEEKEVENTREG_28_10);
+ SET_WEEKEVENTREG(WEEKEVENTREG_90_08);
+ SET_WEEKEVENTREG(WEEKEVENTREG_51_02);
+ }
+ }
+}
void func_800F8970(void) {
if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_27_40) && (SCHEDULE_TIME_NOW >= SCHEDULE_TIME(9, 31))) {
@@ -732,13 +1694,122 @@ void func_800F8970(void) {
}
}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_UpdatePostmanEvents.s")
+void Environment_UpdatePostmanEvents(PlayState* play) {
+ u16 temp_a2_2;
+ u8 eventInfBits;
+ u8 day = EVENTINF_GET_7_E0;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_Update.s")
+ if (day != (u8)((void)0, gSaveContext.save.day)) {
+ day = (u8)((void)0, gSaveContext.save.day);
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_DrawSun.s")
+ EVENTINF_SET_7_E0(day, eventInfBits);
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_DrawSunLensFlare.s")
+ SET_WEEKEVENTREG(WEEKEVENTREG_27_40);
+ SET_WEEKEVENTREG(WEEKEVENTREG_27_80);
+ SET_WEEKEVENTREG(WEEKEVENTREG_28_01);
+ SET_WEEKEVENTREG(WEEKEVENTREG_28_02);
+ SET_WEEKEVENTREG(WEEKEVENTREG_28_04);
+
+ func_800F88C4(WEEKEVENTREG_DEPOSITED_LETTER_TO_KAFEI_SOUTH_UPPER_CLOCKTOWN);
+ func_800F88C4(WEEKEVENTREG_DEPOSITED_LETTER_TO_KAFEI_NORTH_CLOCKTOWN);
+ func_800F88C4(WEEKEVENTREG_DEPOSITED_LETTER_TO_KAFEI_EAST_UPPER_CLOCKTOWN);
+ func_800F88C4(WEEKEVENTREG_DEPOSITED_LETTER_TO_KAFEI_EAST_LOWER_CLOCKTOWN);
+ func_800F88C4(WEEKEVENTREG_DEPOSITED_LETTER_TO_KAFEI_SOUTH_LOWER_CLOCKTOWN);
+
+ CLEAR_WEEKEVENTREG(WEEKEVENTREG_27_40);
+ CLEAR_WEEKEVENTREG(WEEKEVENTREG_27_80);
+ CLEAR_WEEKEVENTREG(WEEKEVENTREG_28_01);
+ CLEAR_WEEKEVENTREG(WEEKEVENTREG_28_02);
+ CLEAR_WEEKEVENTREG(WEEKEVENTREG_28_04);
+ }
+
+ if ((SCHEDULE_TIME_NOW < SCHEDULE_TIME(9, 0)) || (SCHEDULE_TIME_NOW > SCHEDULE_TIME(12, 0))) {
+ CLEAR_WEEKEVENTREG(WEEKEVENTREG_90_08);
+ }
+
+ func_800F8970();
+
+ if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_RECEIVED_ROOM_KEY) && !CHECK_WEEKEVENTREG(WEEKEVENTREG_55_02)) {
+ if (((void)0, gSaveContext.save.day) >= 2) {
+ SET_WEEKEVENTREG(WEEKEVENTREG_55_02);
+ } else if ((((void)0, gSaveContext.save.day) == 1) && (SCHEDULE_TIME_NOW >= SCHEDULE_TIME(16, 30))) {
+ SET_WEEKEVENTREG(WEEKEVENTREG_55_02);
+ }
+ }
+
+ if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_90_01)) {
+ temp_a2_2 = ((void)0, gSaveContext.save.time) - D_801F4E78;
+ if (CHECK_WEEKEVENTREG(WEEKEVENTREG_89_40) && ((u16)SCHEDULE_TIME_NOW >= (u16)SCHEDULE_TIME(5, 0))) {
+ SET_WEEKEVENTREG(WEEKEVENTREG_90_01);
+ } else if (CHECK_WEEKEVENTREG(WEEKEVENTREG_89_08) && (temp_a2_2 >= CLOCK_TIME(0, 23))) {
+ SET_WEEKEVENTREG(WEEKEVENTREG_89_40);
+ D_801F4E78 = 0;
+ } else if (CHECK_WEEKEVENTREG(WEEKEVENTREG_85_80) && (temp_a2_2 >= (CLOCK_TIME(1, 39) - 1))) {
+ SET_WEEKEVENTREG(WEEKEVENTREG_89_08);
+ D_801F4E78 = gSaveContext.save.time;
+ } else if (CHECK_WEEKEVENTREG(WEEKEVENTREG_86_01) && (temp_a2_2 >= (CLOCK_TIME(1, 9) - 1))) {
+ SET_WEEKEVENTREG(WEEKEVENTREG_85_80);
+ }
+ }
+}
+
+void Environment_Update(PlayState* play, EnvironmentContext* envCtx, LightContext* lightCtx, PauseContext* pauseCtx,
+ MessageContext* msgCtx, GameOverContext* gameOverCtx, GraphicsContext* gfxCtx) {
+ D_801BDBC0 = 0;
+ D_801BDBC4 = 0;
+
+ Environment_WipeRumbleRequests();
+
+ if (pauseCtx->state == PAUSE_STATE_OFF) {
+ Environment_UpdateSkyboxRotY(play);
+ Environment_UpdateRain(play);
+ Environment_UpdateTimeBasedSequence(play);
+ Environment_UpdateNextDayTime();
+ Environment_UpdateTime(play, envCtx, pauseCtx, msgCtx, gameOverCtx);
+ Environment_UpdateSun(play);
+ Environment_UpdateLights(play, envCtx, lightCtx);
+ Environment_UpdatePostmanEvents(play);
+ }
+}
+
+void Environment_DrawSun(PlayState* play) {
+ if (!play->envCtx.sunDisabled) {
+ OPEN_DISPS(play->state.gfxCtx);
+
+ if ((play->envCtx.sunPos.y > -800.0f) || Environment_IsSceneUpsideDown(play)) {
+ Matrix_Translate(play->view.eye.x + play->envCtx.sunPos.x, play->view.eye.y + play->envCtx.sunPos.y,
+ play->view.eye.z + play->envCtx.sunPos.z, MTXMODE_NEW);
+ if (((void)0, gSaveContext.save.time) < CLOCK_TIME(12, 0)) {
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, (u8)((u8)(sSunColor * 52.0f) + 203),
+ (u8)((u8)(sSunColor * 19.0f) + 181), (u8)sSunPrimAlpha);
+ gDPSetEnvColor(POLY_OPA_DISP++, (u8)(-(u8)(sSunColor * 5.0f) + 175),
+ (u8)((u8)(sSunColor * 135.0f) + 120), (u8)((u8)(sSunColor * 100.0f) + 100),
+ sSunEnvAlpha);
+ } else {
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, (u8)((u8)(sSunColor * 75.0f) + 180),
+ (u8)((u8)(sSunColor * 100.0f) + 100), (u8)sSunPrimAlpha);
+ gDPSetEnvColor(POLY_OPA_DISP++, 180, (u8)(sSunColor * 255.0f), (u8)(sSunColor * 200.0f), sSunEnvAlpha);
+ }
+ Matrix_Scale(sSunScale, sSunScale, sSunScale, MTXMODE_APPLY);
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_LOAD);
+ Gfx_SetupDL54_Opa(play->state.gfxCtx);
+ gSPDisplayList(POLY_OPA_DISP++, gSunDL);
+ }
+
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+}
+
+void Environment_DrawSunLensFlare(PlayState* play, EnvironmentContext* envCtx, View* view, GraphicsContext* gfxCtx,
+ Vec3f vec) {
+ if ((play->envCtx.precipitation[PRECIP_RAIN_CUR] == 0) &&
+ !(GET_ACTIVE_CAM(play)->stateFlags & CAM_STATE_UNDERWATER) && (play->skyboxId == SKYBOX_NORMAL_SKY)) {
+ f32 v0 = Math_CosS(((void)0, gSaveContext.save.time) - CLOCK_TIME(12, 0));
+
+ Environment_DrawLensFlare(play, &play->envCtx, &play->view, play->state.gfxCtx, vec, 370.0f, v0 * 120.0f, 0x190,
+ true);
+ }
+}
typedef enum {
/* 0 */ LENS_FLARE_CIRCLE0,
@@ -769,46 +1840,871 @@ static u32 sLensFlareTypes[] = {
LENS_FLARE_CIRCLE1, LENS_FLARE_CIRCLE1, LENS_FLARE_CIRCLE1, LENS_FLARE_CIRCLE1, LENS_FLARE_CIRCLE1,
};
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_DrawLensFlare.s")
+void Environment_DrawLensFlare(PlayState* play, EnvironmentContext* envCtx, View* view, GraphicsContext* gfxCtx,
+ Vec3f pos, f32 scale, f32 colorIntensity, s16 glareStrength, u8 isSun) {
+ s16 i;
+ f32 tempX;
+ f32 tempY;
+ f32 tempZ;
+ f32 lookDirX;
+ f32 lookDirY;
+ f32 lookDirZ;
+ f32 tempX2;
+ f32 tempY2;
+ f32 tempZ2;
+ f32 posDirX;
+ f32 posDirY;
+ f32 posDirZ;
+ f32 length;
+ f32 dist;
+ f32 halfPosX;
+ f32 halfPosY;
+ f32 halfPosZ;
+ f32 cosAngle;
+ s32 pad;
+ f32 lensFlareAlphaScaleTarget;
+ f32 alpha;
+ f32 adjScale;
+ f32 fogInfluence;
+ Vec3f screenPos;
+ u8 isOffScreen = false;
+ f32 weight = 0.0f;
+ f32 glareAlphaScale;
+ Mtx* mtx;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_RandCentered.s")
+ OPEN_DISPS(gfxCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_DrawRainImpl.s")
+ dist = Math3D_Distance(&pos, &view->eye) / 12.0f;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_DrawRain.s")
+ // compute a unit vector in the look direction
+ tempX = view->at.x - view->eye.x;
+ tempY = view->at.y - view->eye.y;
+ tempZ = view->at.z - view->eye.z;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_ChangeLightSetting.s")
+ length = sqrtf(SQ(tempX) + SQ(tempY) + SQ(tempZ));
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_DrawSkyboxFilters.s")
+ lookDirX = tempX / length;
+ lookDirY = tempY / length;
+ lookDirZ = tempZ / length;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_DrawLightningFlash.s")
+ // compute a position along the look vector half as far as pos
+ halfPosX = view->eye.x + lookDirX * (dist * 6.0f);
+ halfPosY = view->eye.y + lookDirY * (dist * 6.0f);
+ halfPosZ = view->eye.z + lookDirZ * (dist * 6.0f);
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_UpdateLightningStrike.s")
+ // compute a unit vector in the direction from halfPos to pos
+ tempX2 = pos.x - halfPosX;
+ tempY2 = pos.y - halfPosY;
+ tempZ2 = pos.z - halfPosZ;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_AddLightningBolts.s")
+ length = sqrtf(SQ(tempX2) + SQ(tempY2) + SQ(tempZ2));
+
+ posDirX = tempX2 / length;
+ posDirY = tempY2 / length;
+ posDirZ = tempZ2 / length;
+
+ // compute the cosine of the angle between lookDir and posDir
+ cosAngle = (lookDirX * posDirX + lookDirY * posDirY + lookDirZ * posDirZ) /
+ sqrtf((SQ(lookDirX) + SQ(lookDirY) + SQ(lookDirZ)) * (SQ(posDirX) + SQ(posDirY) + SQ(posDirZ)));
+
+ lensFlareAlphaScaleTarget = cosAngle * 3.5f;
+ lensFlareAlphaScaleTarget = CLAMP_MAX(lensFlareAlphaScaleTarget, 1.0f);
+
+ if (!isSun) {
+ lensFlareAlphaScaleTarget = cosAngle;
+ }
+
+ if (cosAngle < 0.0f) {
+ // don't draw lens flare
+ } else {
+ if (isSun) {
+ Play_GetScreenPos(play, &pos, &screenPos);
+ sSunDepthTestX = screenPos.x;
+ sSunDepthTestY = screenPos.y - 5.0f;
+ if (sSunDepthTestY < 0) {
+ sSunDepthTestY = 0;
+ }
+ if (sSunScreenDepth != GPACK_ZDZ(G_MAXFBZ, 0) || screenPos.x < 0.0f || screenPos.y < 0.0f ||
+ screenPos.x > SCREEN_WIDTH || screenPos.y > SCREEN_HEIGHT) {
+ isOffScreen = true;
+ }
+ }
+
+ for (i = 0; i < ARRAY_COUNT(sLensFlareTypes); i++) {
+ Matrix_Translate(pos.x, pos.y, pos.z, MTXMODE_NEW);
+
+ if (isSun) {
+ weight = Environment_LerpWeight(60, 15, play->view.fovy);
+ }
+
+ Matrix_Translate(-posDirX * i * dist, -posDirY * i * dist, -posDirZ * i * dist, MTXMODE_APPLY);
+ adjScale = sLensFlareScales[i] * cosAngle;
+
+ if (isSun) {
+ adjScale *= 0.001f * (scale + 630.0f * weight);
+ } else {
+ adjScale *= 0.0001f * scale * (2.0f * dist);
+ }
+
+ Matrix_Scale(adjScale, adjScale, adjScale, MTXMODE_APPLY);
+
+ alpha = colorIntensity / 10.0f;
+ alpha = CLAMP_MAX(alpha, 1.0f);
+ alpha = alpha * sLensFlareAlphas[i];
+ alpha = CLAMP_MIN(alpha, 0.0f);
+
+ if (isSun) {
+ fogInfluence = (ENV_FOGNEAR_MAX - play->lightCtx.fogNear) / 50.0f;
+
+ fogInfluence = CLAMP_MAX(fogInfluence, 1.0f);
+
+ alpha *= 1.0f - fogInfluence;
+ }
+
+ if (isOffScreen == false) {
+ Math_SmoothStepToF(&envCtx->lensFlareAlphaScale, lensFlareAlphaScaleTarget, 0.5f, 0.05f, 0.001f);
+ } else {
+ Math_SmoothStepToF(&envCtx->lensFlareAlphaScale, 0.0f, 0.5f, 0.05f, 0.001f);
+ }
+
+ POLY_XLU_DISP = Gfx_SetupDL65_NoCD(POLY_XLU_DISP++);
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, sLensFlareColors[i].r, sLensFlareColors[i].g, sLensFlareColors[i].b,
+ alpha * envCtx->lensFlareAlphaScale);
+ mtx = Matrix_NewMtx(gfxCtx);
+ if (mtx != NULL) {
+ gSPMatrix(POLY_XLU_DISP++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gDPSetCombineLERP(POLY_XLU_DISP++, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE,
+ TEXEL0, 0, PRIMITIVE, 0);
+ gDPSetAlphaDither(POLY_XLU_DISP++, G_AD_DISABLE);
+ gDPSetColorDither(POLY_XLU_DISP++, G_CD_DISABLE);
+ gSPMatrix(POLY_XLU_DISP++, &D_01000000, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_MODELVIEW);
+
+ switch (sLensFlareTypes[i]) {
+ case LENS_FLARE_CIRCLE0:
+ case LENS_FLARE_CIRCLE1:
+ gSPDisplayList(POLY_XLU_DISP++, gLensFlareCircleDL);
+ break;
+
+ case LENS_FLARE_RING:
+ gSPDisplayList(POLY_XLU_DISP++, gLensFlareRingDL);
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ glareAlphaScale = cosAngle - (1.5f - cosAngle);
+
+ if (glareStrength != 0) {
+ if (glareAlphaScale > 0.0f) {
+ POLY_XLU_DISP = Gfx_SetupDL57(POLY_XLU_DISP);
+ alpha = colorIntensity / 10.0f;
+ alpha = CLAMP_MAX(alpha, 1.0f);
+ alpha = alpha * glareStrength;
+ alpha = CLAMP_MIN(alpha, 0.0f);
+
+ fogInfluence = (ENV_FOGNEAR_MAX - play->lightCtx.fogNear) / 50.0f;
+
+ fogInfluence = CLAMP_MAX(fogInfluence, 1.0f);
+
+ alpha *= 1.0f - fogInfluence;
+
+ gDPSetAlphaDither(POLY_XLU_DISP++, G_AD_DISABLE);
+ gDPSetColorDither(POLY_XLU_DISP++, G_CD_DISABLE);
+
+ //! FAKE:
+ if (i) {}
+
+ if (isOffScreen == false) {
+ Math_SmoothStepToF(&envCtx->glareAlpha, alpha * glareAlphaScale, 0.5f, 50.0f, 0.1f);
+ } else {
+ Math_SmoothStepToF(&envCtx->glareAlpha, 0.0f, 0.5f, 50.0f, 0.1f);
+ }
+
+ weight = colorIntensity / 120.0f;
+ weight = CLAMP_MIN(weight, 0.0f);
+
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, (u8)(weight * 75.0f) + 180, (u8)(weight * 155.0f) + 100,
+ (u8)envCtx->glareAlpha);
+ gSPDisplayList(POLY_XLU_DISP++, D_0E000000.clearFillRect);
+ } else {
+ envCtx->glareAlpha = 0.0f;
+ }
+ }
+ }
+
+ CLOSE_DISPS(gfxCtx);
+}
+
+f32 Environment_RandCentered(void) {
+ return Rand_ZeroOne() - 0.5f;
+}
+
+void Environment_DrawRainImpl(PlayState* play, View* view, GraphicsContext* gfxCtx) {
+ Player* player = GET_PLAYER(play);
+ s32 i;
+ u8 precip;
+ Vec3f temp;
+ f32 length;
+ f32 precipScale;
+ f32 windScale;
+ f32 spF0;
+ f32 spEC;
+ f32 spE8;
+ f32 spE4;
+ f32 spE0;
+ Vec3f spD4;
+ u8 materialApplied;
+ f32 temp_fs1;
+ f32 temp_fs2;
+ s16 pitch;
+ s16 yaw;
+ f32 scale;
+
+ if (play->envCtx.precipitation[PRECIP_SOS_MAX] != 0) {
+ precip = play->envCtx.precipitation[PRECIP_RAIN_CUR];
+ } else {
+ precipScale = func_80173B48(&play->state) / 3e7f;
+ precipScale = CLAMP(precipScale, 0.0f, 1.0f);
+ precip = play->envCtx.precipitation[PRECIP_RAIN_CUR] * precipScale;
+ if (precip < 5) {
+ precip = 5;
+ }
+ }
+
+ OPEN_DISPS(gfxCtx);
+
+ temp.x = view->at.x - view->eye.x;
+ temp.y = view->at.y - view->eye.y;
+ temp.z = view->at.z - view->eye.z;
+ length = sqrtf(SQ(temp.x) + SQ(temp.y) + SQ(temp.z));
+
+ temp_fs1 = temp.x / length;
+ temp_fs2 = temp.z / length;
+
+ spF0 = view->eye.x + (temp_fs1 * 50.0f);
+ spEC = view->eye.y + ((temp.y / length) * 120.0f);
+ spE8 = view->eye.z + (temp_fs2 * 50.0f);
+
+ spE4 = view->eye.x + (temp_fs1 * 220.0f);
+ spE0 = view->eye.z + (temp_fs2 * 220.0f);
+
+ if ((u32)precip != 0) {
+ gDPPipeSync(POLY_XLU_DISP++);
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 150, 255, 255, 25);
+ POLY_XLU_DISP = Gfx_SetupDL(POLY_XLU_DISP, SETUPDL_20);
+ }
+
+ windScale = play->envCtx.windSpeed / 60.0f;
+ windScale = CLAMP(windScale, 0.0f, 1.0f);
+
+ spD4.x = play->envCtx.windDirection.x * windScale;
+ spD4.y = play->envCtx.windDirection.y + 100.0f;
+ spD4.z = play->envCtx.windDirection.z * windScale;
+
+ pitch = 0x4000 - Math_Vec3f_Pitch(&gZeroVec3f, &spD4);
+ yaw = Math_Vec3f_Yaw(&gZeroVec3f, &spD4) + 0x8000;
+
+ for (i = 0; i < precip; i++) {
+ Matrix_Translate(((Rand_ZeroOne() - 0.7f) * 100.0f) + spF0, ((Rand_ZeroOne() - 0.7f) * 100.0f) + spEC,
+ ((Rand_ZeroOne() - 0.7f) * 100.0f) + spE8, MTXMODE_NEW);
+ gSPMatrix(POLY_XLU_DISP++, &D_01000000, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_MODELVIEW);
+ Matrix_RotateYS(yaw + (s16)(i << 5), MTXMODE_APPLY);
+ Matrix_RotateXS(pitch + (s16)(i << 5), MTXMODE_APPLY);
+ Matrix_Scale(0.3f, 1.0f, 0.3f, MTXMODE_APPLY);
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_XLU_DISP++, gFallingRainDropDL);
+ }
+
+ if (player->actor.floorHeight < view->eye.y) {
+ materialApplied = false;
+ for (i = 0; i < precip; i++) {
+ if (!materialApplied) {
+ Gfx_SetupDL25_Xlu(gfxCtx);
+ gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 255, 255);
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, 100);
+ materialApplied++;
+ }
+ Matrix_Translate((Environment_RandCentered() * 220.0f) + spE4, player->actor.floorHeight + 2.0f,
+ (Environment_RandCentered() * 220.0f) + spE0, MTXMODE_NEW);
+ scale = (Rand_ZeroOne() * 0.05f) + 0.05f;
+ Matrix_Scale(scale, scale, scale, MTXMODE_APPLY);
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_XLU_DISP++, gEffShockwaveDL);
+ }
+ }
+
+ CLOSE_DISPS(gfxCtx);
+}
+
+void Environment_DrawRain(PlayState* play, View* view, GraphicsContext* gfxCtx) {
+ if (!(GET_ACTIVE_CAM(play)->stateFlags & CAM_STATE_UNDERWATER) &&
+ (play->envCtx.precipitation[PRECIP_SNOW_CUR] == 0)) {
+ if (play->envCtx.precipitation[PRECIP_SOS_MAX] != 0) {
+ if (play->envCtx.precipitation[PRECIP_SNOW_CUR] == 0) {
+ Environment_DrawRainImpl(play, view, gfxCtx);
+ }
+ } else if (!(GET_ACTIVE_CAM(play)->stateFlags & CAM_STATE_UNDERWATER)) {
+ if ((Environment_GetStormState(play) != STORM_STATE_OFF) &&
+ (play->envCtx.precipitation[PRECIP_SNOW_CUR] == 0)) {
+ Environment_DrawRainImpl(play, view, gfxCtx);
+ }
+ }
+ }
+}
+
+void Environment_ChangeLightSetting(PlayState* play, u8 lightSetting) {
+ if (play->envCtx.lightMode == LIGHT_MODE_TIME) {
+ if ((lightSetting == LIGHT_SETTING_MAX) || D_801F4F33) {
+ if (D_801F4F30 != 0xFF) {
+ play->envCtx.changeLightEnabled = true;
+ play->envCtx.changeLightNextConfig = D_801F4F30;
+ play->envCtx.changeDuration = 20;
+ play->envCtx.changeLightTimer = play->envCtx.changeDuration;
+ D_801F4F30 = 0xFF;
+ }
+ } else if (play->envCtx.changeLightNextConfig != lightSetting) {
+ D_801F4F30 = play->envCtx.lightConfig;
+ play->envCtx.changeLightEnabled = true;
+ play->envCtx.changeLightNextConfig = lightSetting;
+ play->envCtx.changeDuration = 20;
+ play->envCtx.changeLightTimer = play->envCtx.changeDuration;
+ }
+ } else if ((play->envCtx.lightSetting != lightSetting) && (play->envCtx.lightBlend >= 1.0f) &&
+ (play->envCtx.lightSettingOverride == LIGHT_SETTING_OVERRIDE_NONE)) {
+ if (lightSetting >= LIGHT_SETTING_MAX) {
+ lightSetting = 0;
+ }
+
+ play->envCtx.lightBlend = 0.0f;
+ play->envCtx.prevLightSetting = play->envCtx.lightSetting;
+ play->envCtx.lightSetting = lightSetting;
+ }
+}
+
+void Environment_DrawSkyboxFilters(PlayState* play) {
+ if ((((play->skyboxId != SKYBOX_NONE) && (play->lightCtx.fogNear < 980)) || (play->skyboxId >= SKYBOX_2)) &&
+ ((play->skyboxId != SKYBOX_3) || (D_801F4E74 != 0.0f))) {
+ f32 alpha;
+
+ OPEN_DISPS(play->state.gfxCtx);
+
+ Gfx_SetupDL57_Opa(play->state.gfxCtx);
+
+ alpha = (1000 - play->lightCtx.fogNear) * 0.02f;
+
+ if (play->skyboxId == SKYBOX_2) {
+ alpha = 1.0f;
+ }
+
+ if (alpha > 1.0f) {
+ alpha = 1.0f;
+ }
+
+ if (play->skyboxId != SKYBOX_3) {
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, play->lightCtx.fogColor[0], play->lightCtx.fogColor[1],
+ play->lightCtx.fogColor[2], 255.0f * alpha);
+ } else {
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, play->lightCtx.fogColor[0] + 16, play->lightCtx.fogColor[1] + 16,
+ play->lightCtx.fogColor[2] + 16, 255.0f * D_801F4E74);
+ }
+ gSPDisplayList(POLY_OPA_DISP++, D_0E000000.clearFillRect);
+
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+
+ if (play->envCtx.customSkyboxFilter) {
+ OPEN_DISPS(play->state.gfxCtx);
+
+ Gfx_SetupDL57_Opa(play->state.gfxCtx);
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, play->envCtx.skyboxFilterColor[0], play->envCtx.skyboxFilterColor[1],
+ play->envCtx.skyboxFilterColor[2], play->envCtx.skyboxFilterColor[3]);
+ gSPDisplayList(POLY_OPA_DISP++, D_0E000000.clearFillRect);
+
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+}
+
+void Environment_DrawLightningFlash(PlayState* play, u8 red, u8 green, u8 blue, u8 alpha) {
+ OPEN_DISPS(play->state.gfxCtx);
+
+ Gfx_SetupDL57_Opa(play->state.gfxCtx);
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, red, green, blue, alpha);
+ gSPDisplayList(POLY_OPA_DISP++, D_0E000000.clearFillRect);
+
+ CLOSE_DISPS(play->state.gfxCtx);
+}
+
+void Environment_UpdateLightningStrike(PlayState* play) {
+ if (play->envCtx.lightningState != LIGHTNING_OFF) {
+ switch (gLightningStrike.state) {
+ case LIGHTNING_STRIKE_WAIT:
+ // every frame theres a 10% chance of the timer advancing 10 units
+ if (Rand_ZeroOne() < 0.1f) {
+ gLightningStrike.delayTimer += 10.0f;
+ }
+
+ gLightningStrike.delayTimer += Rand_ZeroOne();
+
+ if (gLightningStrike.delayTimer > 500.0f) {
+ gLightningStrike.flashRed = 200;
+ gLightningStrike.flashGreen = 200;
+ gLightningStrike.flashBlue = 255;
+ gLightningStrike.flashAlphaTarget = 200;
+
+ gLightningStrike.delayTimer = 0.0f;
+ Environment_AddLightningBolts(
+ play, (u8)((Rand_ZeroOne() * (ARRAY_COUNT(sLightningBolts) - 0.1f)) + 1.0f));
+ sLightningFlashAlpha = 0;
+ gLightningStrike.state++;
+ }
+ break;
+
+ case LIGHTNING_STRIKE_START:
+ gLightningStrike.flashRed = 200;
+ gLightningStrike.flashGreen = 200;
+ gLightningStrike.flashBlue = 255;
+
+ play->envCtx.adjLightSettings.ambientColor[0] += 80;
+ play->envCtx.adjLightSettings.ambientColor[1] += 80;
+ play->envCtx.adjLightSettings.ambientColor[2] += 100;
+
+ sLightningFlashAlpha += 100;
+
+ if (sLightningFlashAlpha >= gLightningStrike.flashAlphaTarget) {
+ Audio_SetAmbienceChannelIO(AMBIENCE_CHANNEL_LIGHTNING, CHANNEL_IO_PORT_0, 0);
+ gLightningStrike.state++;
+ gLightningStrike.flashAlphaTarget = 0;
+ }
+ break;
+
+ case LIGHTNING_STRIKE_END:
+ if (play->envCtx.adjLightSettings.ambientColor[0] > 0) {
+ play->envCtx.adjLightSettings.ambientColor[0] -= 10;
+ play->envCtx.adjLightSettings.ambientColor[1] -= 10;
+ }
+
+ if (play->envCtx.adjLightSettings.ambientColor[2] > 0) {
+ play->envCtx.adjLightSettings.ambientColor[2] -= 10;
+ }
+
+ sLightningFlashAlpha -= 10;
+
+ if (sLightningFlashAlpha <= gLightningStrike.flashAlphaTarget) {
+ play->envCtx.adjLightSettings.ambientColor[0] = 0;
+ play->envCtx.adjLightSettings.ambientColor[1] = 0;
+ play->envCtx.adjLightSettings.ambientColor[2] = 0;
+
+ gLightningStrike.state = LIGHTNING_STRIKE_WAIT;
+
+ if (play->envCtx.lightningState == LIGHTNING_LAST) {
+ play->envCtx.lightningState = LIGHTNING_OFF;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (gLightningStrike.state != LIGHTNING_STRIKE_WAIT) {
+ Environment_DrawLightningFlash(play, gLightningStrike.flashRed, gLightningStrike.flashGreen,
+ gLightningStrike.flashBlue, sLightningFlashAlpha);
+ }
+}
+
+void Environment_AddLightningBolts(PlayState* play, u8 num) {
+ s16 boltsAdded = 0;
+ s16 i;
+
+ for (i = 0; i < ARRAY_COUNT(sLightningBolts); i++) {
+ if (sLightningBolts[i].state == LIGHTNING_BOLT_INACTIVE) {
+ sLightningBolts[i].state = LIGHTNING_BOLT_START;
+ boltsAdded++;
+
+ if (boltsAdded >= num) {
+ break;
+ }
+ }
+ }
+}
static TexturePtr sLightningTextures[] = {
gEffLightning1Tex, gEffLightning2Tex, gEffLightning3Tex, gEffLightning4Tex,
gEffLightning5Tex, gEffLightning6Tex, gEffLightning7Tex, gEffLightning8Tex,
};
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_DrawLightning.s")
+/**
+ * Draw any active lightning bolt entries contained in `sLightningBolts`
+ */
+void Environment_DrawLightning(PlayState* play, s32 unused) {
+ s16 i;
+ f32 dx;
+ f32 dz;
+ f32 x;
+ f32 z;
+ s32 pad[2];
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_PlaySceneSequence.s")
+ OPEN_DISPS(play->state.gfxCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_UpdateTimeBasedSequence.s")
+ for (i = 0; i < ARRAY_COUNT(sLightningBolts); i++) {
+ switch (sLightningBolts[i].state) {
+ case LIGHTNING_BOLT_START:
+ dx = play->view.at.x - play->view.eye.x;
+ dz = play->view.at.z - play->view.eye.z;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_DrawCustomLensFlare.s")
+ x = dx / sqrtf(SQ(dx) + SQ(dz));
+ z = dz / sqrtf(SQ(dx) + SQ(dz));
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_InitGameOverLights.s")
+ sLightningBolts[i].pos.x = play->view.eye.x + x * 9500.0f;
+ sLightningBolts[i].pos.y = Rand_ZeroOne() * 1000.0f + 4000.0f;
+ sLightningBolts[i].pos.z = play->view.eye.z + z * 9500.0f;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_FadeInGameOverLights.s")
+ sLightningBolts[i].offset.x = (Rand_ZeroOne() - 0.5f) * 5000.0f;
+ sLightningBolts[i].offset.y = 0.0f;
+ sLightningBolts[i].offset.z = (Rand_ZeroOne() - 0.5f) * 5000.0f;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_FadeOutGameOverLights.s")
+ sLightningBolts[i].textureIndex = 0;
+ sLightningBolts[i].pitch = (Rand_ZeroOne() - 0.5f) * 40.0f;
+ sLightningBolts[i].roll = (Rand_ZeroOne() - 0.5f) * 40.0f;
+ sLightningBolts[i].delayTimer = 3 * (i + 1);
+ sLightningBolts[i].state++;
+ break;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_UpdateRain.s")
+ case LIGHTNING_BOLT_WAIT:
+ sLightningBolts[i].delayTimer--;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_FillScreen.s")
+ if (sLightningBolts[i].delayTimer <= 0) {
+ sLightningBolts[i].state++;
+ }
+ break;
+
+ case LIGHTNING_BOLT_DRAW:
+ if (sLightningBolts[i].textureIndex < 7) {
+ sLightningBolts[i].textureIndex++;
+ } else {
+ sLightningBolts[i].state = LIGHTNING_BOLT_INACTIVE;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (sLightningBolts[i].state == LIGHTNING_BOLT_DRAW) {
+ Matrix_Translate(sLightningBolts[i].pos.x + sLightningBolts[i].offset.x,
+ sLightningBolts[i].pos.y + sLightningBolts[i].offset.y,
+ sLightningBolts[i].pos.z + sLightningBolts[i].offset.z, MTXMODE_NEW);
+ Matrix_RotateXFApply(DEG_TO_RAD(sLightningBolts[i].pitch));
+ Matrix_RotateZF(DEG_TO_RAD(sLightningBolts[i].roll), MTXMODE_APPLY);
+ Matrix_Scale(22.0f, 100.0f, 22.0f, MTXMODE_APPLY);
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, 128);
+ gDPSetEnvColor(POLY_XLU_DISP++, 0, 255, 255, 128);
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPSegment(POLY_XLU_DISP++, 0x08,
+ Lib_SegmentedToVirtual(sLightningTextures[sLightningBolts[i].textureIndex]));
+ Gfx_SetupDL61_Xlu(play->state.gfxCtx);
+ gSPMatrix(POLY_XLU_DISP++, &D_01000000, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_XLU_DISP++, gEffLightningDL);
+ }
+ }
+
+ CLOSE_DISPS(play->state.gfxCtx);
+}
+
+void Environment_PlaySceneSequence(PlayState* play) {
+ u8 dayMinusOne = ((void)0, gSaveContext.save.day) - 1;
+
+ if (dayMinusOne >= 3) {
+ dayMinusOne = 0;
+ }
+
+ if (play->envCtx.timeSeqState != TIMESEQ_REQUEST) {
+ play->envCtx.timeSeqState = TIMESEQ_DISABLED;
+ if (((void)0, gSaveContext.forcedSeqId) != NA_BGM_GENERAL_SFX) {
+ play->envCtx.timeSeqState = TIMESEQ_REQUEST;
+ SEQCMD_PLAY_SEQUENCE(SEQ_PLAYER_BGM_MAIN, 0, ((void)0, gSaveContext.forcedSeqId) + SEQ_FLAG_ASYNC);
+ gSaveContext.forcedSeqId = NA_BGM_GENERAL_SFX;
+ } else if (!Environment_IsFinalHours(play) || func_800FE5D0(play) ||
+ (AudioSeq_GetActiveSeqId(SEQ_PLAYER_BGM_MAIN) != NA_BGM_FINAL_HOURS)) {
+ if (play->sequenceCtx.seqId == NA_BGM_NO_MUSIC) {
+ if (play->sequenceCtx.ambienceId == AMBIENCE_ID_13) {
+ return;
+ }
+ if (play->sequenceCtx.ambienceId != ((void)0, gSaveContext.ambienceId)) {
+ Audio_PlayAmbience(play->sequenceCtx.ambienceId);
+ }
+ } else if (play->sequenceCtx.ambienceId == AMBIENCE_ID_13) {
+ if (play->sequenceCtx.seqId != ((void)0, gSaveContext.seqId)) {
+ Audio_PlaySceneSequence(play->sequenceCtx.seqId, dayMinusOne);
+ }
+ } else if ((((void)0, gSaveContext.save.time) >= CLOCK_TIME(6, 0)) &&
+ (((void)0, gSaveContext.save.time) <= CLOCK_TIME(17, 10))) {
+ if (gSceneSeqState != SCENESEQ_DEFAULT) {
+ Audio_PlayMorningSceneSequence(play->sequenceCtx.seqId, dayMinusOne);
+ } else if ((((void)0, gSaveContext.save.time) >= CLOCK_TIME(6, 1)) &&
+ (play->sequenceCtx.seqId != ((void)0, gSaveContext.seqId))) {
+ Audio_PlaySceneSequence(play->sequenceCtx.seqId, dayMinusOne);
+ }
+ play->envCtx.timeSeqState = TIMESEQ_FADE_DAY_BGM;
+ } else {
+ if (play->sequenceCtx.ambienceId != ((void)0, gSaveContext.ambienceId)) {
+ Audio_PlayAmbience(play->sequenceCtx.ambienceId);
+ }
+ if ((((void)0, gSaveContext.save.time) > CLOCK_TIME(17, 10)) &&
+ (((void)0, gSaveContext.save.time) < CLOCK_TIME(19, 0))) {
+ play->envCtx.timeSeqState = TIMESEQ_EARLY_NIGHT_CRITTERS;
+ } else if ((((void)0, gSaveContext.save.time) > CLOCK_TIME(19, 0)) ||
+ (((void)0, gSaveContext.save.time) < CLOCK_TIME(5, 0))) {
+ play->envCtx.timeSeqState = TIMESEQ_NIGHT_CRITTERS;
+ } else {
+ play->envCtx.timeSeqState = TIMESEQ_MORNING_CRITTERS;
+ }
+ }
+ }
+ Audio_SetEnvReverb(play->roomCtx.curRoom.echo);
+ gSceneSeqState = SCENESEQ_DEFAULT;
+ }
+}
+
+void Environment_UpdateTimeBasedSequence(PlayState* play) {
+ s32 pad;
+
+ //! FAKE:
+ if (!gSaveContext.sceneLayer) {}
+
+ if ((play->csCtx.state == 0) && !(play->actorCtx.flags & ACTORCTX_FLAG_1)) {
+ switch (play->envCtx.timeSeqState) {
+ case TIMESEQ_DAY_BGM:
+ break;
+
+ case TIMESEQ_FADE_DAY_BGM:
+ if (((void)0, gSaveContext.save.time) > CLOCK_TIME(17, 10)) {
+ SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_BGM_MAIN, 240);
+ play->envCtx.timeSeqState++;
+ }
+ break;
+
+ case TIMESEQ_NIGHT_BEGIN_SFX:
+ if (((void)0, gSaveContext.save.time) >= CLOCK_TIME(18, 0)) {
+ play->envCtx.timeSeqState++;
+ }
+ break;
+
+ case TIMESEQ_EARLY_NIGHT_CRITTERS:
+ if (play->envCtx.precipitation[PRECIP_RAIN_CUR] < 9) {
+ Audio_PlayAmbience(play->sequenceCtx.ambienceId);
+ Audio_SetAmbienceChannelIO(AMBIENCE_CHANNEL_CRITTER_0, 1, 1);
+ }
+ play->envCtx.timeSeqState++;
+ break;
+
+ case TIMESEQ_NIGHT_DELAY:
+ if (((void)0, gSaveContext.save.time) >= CLOCK_TIME(19, 0)) {
+ play->envCtx.timeSeqState++;
+ }
+ break;
+
+ case TIMESEQ_NIGHT_CRITTERS:
+ Audio_SetAmbienceChannelIO(AMBIENCE_CHANNEL_CRITTER_0, 1, 0);
+ Audio_SetAmbienceChannelIO(AMBIENCE_CHANNEL_CRITTER_1 << 4 | AMBIENCE_CHANNEL_CRITTER_3, 1, 1);
+ play->envCtx.timeSeqState++;
+ break;
+
+ case TIMESEQ_DAY_BEGIN_SFX:
+ if ((((void)0, gSaveContext.save.time) < CLOCK_TIME(19, 0)) &&
+ (((void)0, gSaveContext.save.time) >= CLOCK_TIME(5, 0))) {
+ play->envCtx.timeSeqState++;
+ }
+ break;
+
+ case TIMESEQ_MORNING_CRITTERS:
+ Audio_SetAmbienceChannelIO(AMBIENCE_CHANNEL_CRITTER_1 << 4 | AMBIENCE_CHANNEL_CRITTER_3, 1, 0);
+ Audio_SetAmbienceChannelIO(AMBIENCE_CHANNEL_CRITTER_4 << 4 | AMBIENCE_CHANNEL_CRITTER_5, 1, 1);
+ play->envCtx.timeSeqState++;
+ break;
+
+ case TIMESEQ_DAY_DELAY:
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if ((play->envCtx.timeSeqState != TIMESEQ_REQUEST) && (((void)0, gSaveContext.save.day) == 3) &&
+ (((void)0, gSaveContext.save.time) < CLOCK_TIME(6, 0)) && !func_800FE5D0(play) &&
+ (play->transitionTrigger == TRANS_TRIGGER_OFF) && (play->transitionMode == TRANS_MODE_OFF) &&
+ (play->csCtx.state == 0) && ((play->sceneId != SCENE_00KEIKOKU) || (((void)0, gSaveContext.sceneLayer) != 1)) &&
+ (CutsceneManager_GetCurrentCsId() == CS_ID_NONE) &&
+ (AudioSeq_GetActiveSeqId(SEQ_PLAYER_BGM_MAIN) != NA_BGM_FINAL_HOURS) &&
+ (AudioSeq_GetActiveSeqId(SEQ_PLAYER_BGM_MAIN) != NA_BGM_SONG_OF_SOARING)) {
+ SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_AMBIENCE, 0);
+ Audio_PlaySceneSequence(NA_BGM_FINAL_HOURS, 3 - 1);
+ }
+}
+
+void Environment_DrawCustomLensFlare(PlayState* play) {
+ Vec3f pos;
+
+ if (gCustomLensFlare1On) {
+ pos.x = gCustomLensFlare1Pos.x;
+ pos.y = gCustomLensFlare1Pos.y;
+ pos.z = gCustomLensFlare1Pos.z;
+ Environment_DrawLensFlare(play, &play->envCtx, &play->view, play->state.gfxCtx, pos, D_801F4E44, D_801F4E48,
+ D_801F4E4C, false);
+ }
+
+ if (gCustomLensFlare2On) {
+ pos.x = gCustomLensFlare2Pos.x;
+ pos.y = gCustomLensFlare2Pos.y;
+ pos.z = gCustomLensFlare2Pos.z;
+ Environment_DrawLensFlare(play, &play->envCtx, &play->view, play->state.gfxCtx, pos, D_801F4E5C, D_801F4E60,
+ D_801F4E64, false);
+ }
+}
+
+void Environment_InitGameOverLights(PlayState* play) {
+ s32 pad;
+ Player* player = GET_PLAYER(play);
+
+ sGameOverLightsIntensity = 0;
+
+ Lights_PointNoGlowSetInfo(&sNGameOverLightInfo, player->actor.world.pos.x - 10.0f,
+ player->actor.world.pos.y + 10.0f, player->actor.world.pos.z - 10.0f, 0, 0, 0, 255);
+ sNGameOverLightNode = LightContext_InsertLight(play, &play->lightCtx, &sNGameOverLightInfo);
+
+ Lights_PointNoGlowSetInfo(&sSGameOverLightInfo, player->actor.world.pos.x + 10.0f,
+ player->actor.world.pos.y + 10.0f, player->actor.world.pos.z + 10.0f, 0, 0, 0, 255);
+
+ sSGameOverLightNode = LightContext_InsertLight(play, &play->lightCtx, &sSGameOverLightInfo);
+}
+
+void Environment_FadeInGameOverLights(PlayState* play) {
+ Player* player = GET_PLAYER(play);
+ s16 i;
+
+ Lights_PointNoGlowSetInfo(&sNGameOverLightInfo, player->actor.world.pos.x - 10.0f,
+ player->actor.world.pos.y + 10.0f, player->actor.world.pos.z - 10.0f,
+ sGameOverLightsIntensity, sGameOverLightsIntensity, sGameOverLightsIntensity, 255);
+ Lights_PointNoGlowSetInfo(&sSGameOverLightInfo, player->actor.world.pos.x + 10.0f,
+ player->actor.world.pos.y + 10.0f, player->actor.world.pos.z + 10.0f,
+ sGameOverLightsIntensity, sGameOverLightsIntensity, sGameOverLightsIntensity, 255);
+
+ if (sGameOverLightsIntensity < 254) {
+ sGameOverLightsIntensity += 2;
+ }
+
+ if (Play_CamIsNotFixed(&play->state)) {
+ for (i = 0; i < 3; i++) {
+ if (play->envCtx.adjLightSettings.ambientColor[i] > -255) {
+ play->envCtx.adjLightSettings.ambientColor[i] -= 12;
+ play->envCtx.adjLightSettings.light1Color[i] -= 12;
+ }
+ play->envCtx.adjLightSettings.fogColor[i] = -255;
+ }
+
+ if (play->envCtx.lightSettings.zFar + play->envCtx.adjLightSettings.zFar > 900) {
+ play->envCtx.adjLightSettings.zFar -= 100;
+ }
+
+ if (play->envCtx.lightSettings.fogNear + play->envCtx.adjLightSettings.fogNear > 950) {
+ play->envCtx.adjLightSettings.fogNear -= 10;
+ }
+ } else {
+ play->envCtx.fillScreen = true;
+ play->envCtx.screenFillColor[0] = 0;
+ play->envCtx.screenFillColor[1] = 0;
+ play->envCtx.screenFillColor[2] = 0;
+ play->envCtx.screenFillColor[3] = sGameOverLightsIntensity;
+ }
+}
+
+void Environment_FadeOutGameOverLights(PlayState* play) {
+ Player* player = GET_PLAYER(play);
+ s32 i;
+
+ if (sGameOverLightsIntensity >= 3) {
+ sGameOverLightsIntensity -= 3;
+ } else {
+ sGameOverLightsIntensity = 0;
+ }
+
+ if (sGameOverLightsIntensity == 1) {
+ LightContext_RemoveLight(play, &play->lightCtx, sNGameOverLightNode);
+ LightContext_RemoveLight(play, &play->lightCtx, sSGameOverLightNode);
+ } else if (sGameOverLightsIntensity >= 2) {
+ Lights_PointNoGlowSetInfo(&sNGameOverLightInfo, player->actor.world.pos.x - 10.0f,
+ player->actor.world.pos.y + 10.0f, player->actor.world.pos.z - 10.0f,
+ sGameOverLightsIntensity, sGameOverLightsIntensity, sGameOverLightsIntensity, 255);
+ Lights_PointNoGlowSetInfo(&sSGameOverLightInfo, player->actor.world.pos.x + 10.0f,
+ player->actor.world.pos.y + 10.0f, player->actor.world.pos.z + 10.0f,
+ sGameOverLightsIntensity, sGameOverLightsIntensity, sGameOverLightsIntensity, 255);
+ }
+
+ if (Play_CamIsNotFixed(&play->state)) {
+ for (i = 0; i < 3; i++) {
+ Math_SmoothStepToS(&play->envCtx.adjLightSettings.ambientColor[i], 0, 5, 12, 1);
+ Math_SmoothStepToS(&play->envCtx.adjLightSettings.light1Color[i], 0, 5, 12, 1);
+ play->envCtx.adjLightSettings.fogColor[i] = 0;
+ }
+ play->envCtx.adjLightSettings.zFar = 0;
+ play->envCtx.adjLightSettings.fogNear = 0;
+ } else {
+ play->envCtx.fillScreen = true;
+ play->envCtx.screenFillColor[0] = 0;
+ play->envCtx.screenFillColor[1] = 0;
+ play->envCtx.screenFillColor[2] = 0;
+ play->envCtx.screenFillColor[3] = sGameOverLightsIntensity;
+ if (sGameOverLightsIntensity == 0) {
+ play->envCtx.fillScreen = false;
+ }
+ }
+}
+
+void Environment_UpdateRain(PlayState* play) {
+ u8 max = MAX(play->envCtx.precipitation[PRECIP_RAIN_MAX], play->envCtx.precipitation[PRECIP_SOS_MAX]);
+
+ if ((play->envCtx.precipitation[PRECIP_RAIN_CUR] != max) && ((play->state.frames % 8) == 0)) {
+ if (play->envCtx.precipitation[PRECIP_RAIN_CUR] < max) {
+ play->envCtx.precipitation[PRECIP_RAIN_CUR] += 2;
+ } else {
+ play->envCtx.precipitation[PRECIP_RAIN_CUR] -= 2;
+ }
+ }
+}
+
+void Environment_FillScreen(GraphicsContext* gfxCtx, u8 red, u8 green, u8 blue, u8 alpha, u8 drawFlags) {
+ if (alpha != 0) {
+ OPEN_DISPS(gfxCtx);
+
+ if (drawFlags & FILL_SCREEN_OPA) {
+ POLY_OPA_DISP = Gfx_SetupDL57(POLY_OPA_DISP);
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, red, green, blue, alpha);
+ gDPSetAlphaDither(POLY_OPA_DISP++, G_AD_DISABLE);
+ gDPSetColorDither(POLY_OPA_DISP++, G_CD_DISABLE);
+ gSPDisplayList(POLY_OPA_DISP++, D_0E000000.clearFillRect);
+ }
+
+ if (drawFlags & FILL_SCREEN_XLU) {
+ POLY_XLU_DISP = Gfx_SetupDL57(POLY_XLU_DISP);
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, red, green, blue, alpha);
+
+ if ((u32)alpha == 255) {
+ gDPSetRenderMode(POLY_XLU_DISP++, G_RM_OPA_SURF, G_RM_OPA_SURF2);
+ }
+
+ gDPSetAlphaDither(POLY_XLU_DISP++, G_AD_DISABLE);
+ gDPSetColorDither(POLY_XLU_DISP++, G_CD_DISABLE);
+ gSPDisplayList(POLY_XLU_DISP++, D_0E000000.clearFillRect);
+ }
+
+ CLOSE_DISPS(gfxCtx);
+ }
+}
u8 sSandstormPrimColors[] = {
255, 255, 255, //
@@ -832,9 +2728,267 @@ u8 sSandstormEnvColors[] = {
50, 40, 0, //
};
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_DrawSandstorm.s")
+void Environment_DrawSandstorm(PlayState* play, u8 sandstormState) {
+ s32 primA1 = 0;
+ s32 envA1 = 0;
+ s32 primA = play->envCtx.sandstormPrimA;
+ s32 envA = play->envCtx.sandstormEnvA;
+ s32 step = 9;
+ u16 sp96;
+ u16 sp94;
+ u16 sp92;
+ Color_RGBA8 primColor;
+ Color_RGBA8 envColor;
+ s32 index;
+ f32 sp98;
+ s32 pad;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_AdjustLights.s")
+ switch (sandstormState) {
+ case SANDSTORM_ACTIVE:
+ primA1 = play->state.frames % 128;
+ if (primA1 > 128) {
+ primA1 = 255 - primA1;
+ }
+ primA1 += 73;
+ envA1 = 255;
+ break;
+
+ case SANDSTORM_FILL:
+ primA1 = 255;
+ envA1 = (play->envCtx.sandstormPrimA >= 255) ? 255 : 128;
+ break;
+
+ case SANDSTORM_UNFILL:
+ case SANDSTORM_5:
+ envA1 = 128;
+ if (play->envCtx.sandstormEnvA > 128) {
+ primA1 = 255;
+ } else {
+ primA1 = play->state.frames % 128;
+ if (primA1 > 64) {
+ primA1 = 128 - primA1;
+ }
+ primA1 += 73;
+ }
+ if ((primA1 >= primA) && (primA1 != 255)) {
+ play->envCtx.sandstormState++;
+ }
+ break;
+
+ case SANDSTORM_DISSIPATE:
+ primA1 = (play->envCtx.sandstormEnvA > 128) ? 255 : play->envCtx.sandstormEnvA >> 1;
+
+ if (primA == 0) {
+ play->envCtx.sandstormState = SANDSTORM_OFF;
+ }
+ break;
+
+ case SANDSTORM_6:
+ case SANDSTORM_8:
+ primA1 = D_801F4E30;
+ envA1 = D_801F4E30;
+ step = 1;
+ if (sandstormState == SANDSTORM_8) {
+ step = 10;
+ }
+ break;
+
+ case SANDSTORM_7:
+ case SANDSTORM_9:
+ step = 1;
+ if (primA == 0) {
+ play->envCtx.sandstormState = SANDSTORM_OFF;
+ }
+ if (sandstormState == SANDSTORM_9) {
+ step = 10;
+ }
+ break;
+
+ case SANDSTORM_A:
+ step = 255;
+ primA1 = D_801F4E30;
+ envA1 = D_801F4E30;
+ if (primA == 0) {
+ play->envCtx.sandstormState = SANDSTORM_OFF;
+ }
+ break;
+
+ case SANDSTORM_B:
+ primA1 = play->state.frames & 0x7F;
+ if (primA1 > 64) {
+ primA1 = 128 - primA1;
+ }
+ primA1 += 73;
+ envA1 = 128;
+ break;
+
+ case SANDSTORM_C:
+ if (primA == 0) {
+ play->envCtx.sandstormState = SANDSTORM_OFF;
+ }
+ break;
+
+ case SANDSTORM_D:
+ primA1 = D_801F4E30;
+ envA1 = D_801F4E30;
+ step = 10;
+ break;
+
+ default:
+ break;
+ }
+
+ if (ABS_ALT(primA - primA1) < step) {
+ primA = primA1;
+ } else if (primA1 < primA) {
+ primA -= step;
+ } else {
+ primA += step;
+ }
+
+ if (ABS_ALT(envA - envA1) < step) {
+ envA = envA1;
+ } else if (envA1 < envA) {
+ envA -= step;
+ } else {
+ envA += step;
+ }
+
+ play->envCtx.sandstormPrimA = primA;
+ play->envCtx.sandstormEnvA = envA;
+
+ sp98 = (512.0f - (primA + envA)) * (3.0f / 128.0f);
+
+ if (sp98 > 6.0f) {
+ sp98 = 6.0f;
+ }
+
+ if (play->envCtx.sandstormPrimA != 0) {
+ index = 0;
+ if (sandstormState >= SANDSTORM_B) {
+ index = 4 * 3;
+ }
+
+ if ((play->envCtx.lightMode != LIGHT_MODE_TIME) ||
+ (play->envCtx.lightSettingOverride != LIGHT_SETTING_OVERRIDE_NONE)) {
+ primColor.r = sSandstormPrimColors[index + 1 * 3 + 0];
+ primColor.g = sSandstormPrimColors[index + 1 * 3 + 1];
+ primColor.b = sSandstormPrimColors[index + 1 * 3 + 2];
+ envColor.r = sSandstormEnvColors[index + 1 * 3 + 0];
+ envColor.g = sSandstormEnvColors[index + 1 * 3 + 1];
+ envColor.b = sSandstormEnvColors[index + 1 * 3 + 2];
+ } else if (sSandstormColorIndex == sNextSandstormColorIndex) {
+ primColor.r = sSandstormPrimColors[sSandstormColorIndex * 3 + index + 0];
+ primColor.g = sSandstormPrimColors[sSandstormColorIndex * 3 + index + 1];
+ primColor.b = sSandstormPrimColors[sSandstormColorIndex * 3 + index + 2];
+ envColor.r = sSandstormEnvColors[sSandstormColorIndex * 3 + index + 0];
+ envColor.g = sSandstormEnvColors[sSandstormColorIndex * 3 + index + 1];
+ envColor.b = sSandstormEnvColors[sSandstormColorIndex * 3 + index + 2];
+ } else {
+ primColor.r =
+ (s32)F32_LERP_ALT(sSandstormPrimColors[sSandstormColorIndex * 3 + index + 0],
+ sSandstormPrimColors[sNextSandstormColorIndex * 3 + index + 0], sSandstormLerpScale);
+ primColor.g =
+ (s32)F32_LERP_ALT(sSandstormPrimColors[sSandstormColorIndex * 3 + index + 1],
+ sSandstormPrimColors[sNextSandstormColorIndex * 3 + index + 1], sSandstormLerpScale);
+ primColor.b =
+ (s32)F32_LERP_ALT(sSandstormPrimColors[sSandstormColorIndex * 3 + index + 2],
+ sSandstormPrimColors[sNextSandstormColorIndex * 3 + index + 2], sSandstormLerpScale);
+ envColor.r =
+ (s32)F32_LERP_ALT(sSandstormEnvColors[sSandstormColorIndex * 3 + index + 0],
+ sSandstormEnvColors[sNextSandstormColorIndex * 3 + index + 0], sSandstormLerpScale);
+ envColor.g =
+ (s32)F32_LERP_ALT(sSandstormEnvColors[sSandstormColorIndex * 3 + index + 1],
+ sSandstormEnvColors[sNextSandstormColorIndex * 3 + index + 1], sSandstormLerpScale);
+ envColor.b =
+ (s32)F32_LERP_ALT(sSandstormEnvColors[sSandstormColorIndex * 3 + index + 2],
+ sSandstormEnvColors[sNextSandstormColorIndex * 3 + index + 2], sSandstormLerpScale);
+ }
+
+ envColor.r = ((envColor.r * sp98) + ((6.0f - sp98) * primColor.r)) * (1.0f / 6.0f);
+ envColor.g = ((envColor.g * sp98) + ((6.0f - sp98) * primColor.g)) * (1.0f / 6.0f);
+ envColor.b = ((envColor.b * sp98) + ((6.0f - sp98) * primColor.b)) * (1.0f / 6.0f);
+
+ sp96 = (sSandstormScroll * (11.0f / 6.0f));
+ sp94 = (sSandstormScroll * (9.0f / 6.0f));
+ sp92 = (sSandstormScroll * (6.0f / 6.0f));
+
+ OPEN_DISPS(play->state.gfxCtx);
+
+ POLY_XLU_DISP = Gfx_SetupDL64(POLY_XLU_DISP);
+
+ gDPSetAlphaDither(POLY_XLU_DISP++, G_AD_NOISE);
+ gDPSetColorDither(POLY_XLU_DISP++, G_CD_NOISE);
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, primColor.r, primColor.g, primColor.b, play->envCtx.sandstormPrimA);
+ gDPSetEnvColor(POLY_XLU_DISP++, envColor.r, envColor.g, envColor.b, play->envCtx.sandstormEnvA);
+ gSPSegment(POLY_XLU_DISP++, 0x08,
+ Gfx_TwoTexScroll(play->state.gfxCtx, G_TX_RENDERTILE, (u32)sp96 % 4096, 0, 512, 32, 1,
+ (u32)sp94 % 4096, 4095 - ((u32)sp92 % 4096), 256, 64));
+ gDPSetTextureLUT(POLY_XLU_DISP++, G_TT_NONE);
+ gSPDisplayList(POLY_XLU_DISP++, gFieldSandstormDL);
+
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+
+ sSandstormScroll += (s32)sp98;
+}
+
+s32 Environment_AdjustLights(PlayState* play, f32 arg1, f32 arg2, f32 arg3, f32 arg4) {
+ f32 temp;
+ s32 i;
+ Player* player = GET_PLAYER(play);
+
+ if (play->roomCtx.curRoom.behaviorType1 == ROOM_BEHAVIOR_TYPE1_5) {
+ return 0;
+ }
+
+ if (!Play_CamIsNotFixed(&play->state)) {
+ return 0;
+ }
+ if (play->unk_18880) {
+ return 0;
+ }
+ if ((player != NULL) && (player->stateFlags1 & PLAYER_STATE1_2)) {
+ return 0;
+ }
+
+ arg1 = CLAMP_MIN(arg1, 0.0f);
+ arg1 = CLAMP_MAX(arg1, 1.0f);
+
+ temp = arg1 - arg3;
+
+ if (arg1 < arg3) {
+ temp = 0.0f;
+ }
+
+ play->envCtx.adjLightSettings.fogNear = (arg2 - play->envCtx.lightSettings.fogNear) * temp;
+
+ if (arg1 == 0.0f) {
+ for (i = 0; i < 3; i++) {
+ play->envCtx.adjLightSettings.fogColor[i] = 0;
+ }
+ } else {
+ temp = arg1 * 5.0f;
+ temp = CLAMP_MAX(temp, 1.0f);
+
+ for (i = 0; i < 3; i++) {
+ play->envCtx.adjLightSettings.fogColor[i] = -(f32)play->envCtx.lightSettings.fogColor[i] * temp;
+ }
+ }
+
+ if (arg4 <= 0.0f) {
+ return 1;
+ }
+
+ arg1 *= arg4;
+
+ for (i = 0; i < 3; i++) {
+ play->envCtx.adjLightSettings.ambientColor[i] = -(f32)play->envCtx.lightSettings.ambientColor[i] * arg1;
+ play->envCtx.adjLightSettings.light1Color[i] = -(f32)play->envCtx.lightSettings.light1Color[i] * arg1;
+ }
+
+ return 1;
+}
void Environment_LerpRGB8(u8* from, Color_RGB8* to, f32 lerp, s16* dst) {
Color_RGB8 result;
@@ -879,13 +3033,49 @@ u32 Environment_GetTotalDays(void) {
return gSaveContext.save.day;
}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_ForcePlaySequence.s")
+void Environment_ForcePlaySequence(u16 seqId) {
+ gSaveContext.forcedSeqId = seqId;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_IsForcedSequenceDisabled.s")
+s32 Environment_IsForcedSequenceDisabled(void) {
+ s32 isDisabled = false;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_PlayStormNatureAmbience.s")
+ if (gSaveContext.forcedSeqId != NA_BGM_GENERAL_SFX) {
+ isDisabled = true;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_StopStormNatureAmbience.s")
+ return isDisabled;
+}
+
+void Environment_PlayStormNatureAmbience(PlayState* play) {
+ if (((play->sequenceCtx.seqId != NA_BGM_NO_MUSIC) && (play->sequenceCtx.ambienceId == AMBIENCE_ID_13)) ||
+ (AudioSeq_GetActiveSeqId(SEQ_PLAYER_BGM_MAIN) == NA_BGM_FINAL_HOURS)) {
+ Audio_PlayAmbience(AMBIENCE_ID_07);
+ } else if ((play->sequenceCtx.seqId != NA_BGM_NO_MUSIC) && (play->sequenceCtx.ambienceId != AMBIENCE_ID_13)) {
+ if ((((void)0, gSaveContext.save.time) >= CLOCK_TIME(6, 0)) &&
+ (((void)0, gSaveContext.save.time) < CLOCK_TIME(18, 0))) {
+ Audio_PlayAmbience(play->sequenceCtx.ambienceId);
+ }
+ }
+
+ Audio_SetAmbienceChannelIO(AMBIENCE_CHANNEL_RAIN, CHANNEL_IO_PORT_1, 1);
+ Audio_SetAmbienceChannelIO(AMBIENCE_CHANNEL_LIGHTNING, CHANNEL_IO_PORT_1, 1);
+}
+
+void Environment_StopStormNatureAmbience(PlayState* play) {
+ if (((play->sequenceCtx.seqId != NA_BGM_NO_MUSIC) && (play->sequenceCtx.ambienceId == AMBIENCE_ID_13)) ||
+ (AudioSeq_GetActiveSeqId(SEQ_PLAYER_BGM_MAIN) == NA_BGM_FINAL_HOURS)) {
+ SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_AMBIENCE, 20);
+ } else if ((play->sequenceCtx.seqId != NA_BGM_NO_MUSIC) && (play->sequenceCtx.ambienceId != AMBIENCE_ID_13)) {
+ if ((((void)0, gSaveContext.save.time) >= CLOCK_TIME(6, 0)) &&
+ (((void)0, gSaveContext.save.time) < CLOCK_TIME(18, 0))) {
+ SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_AMBIENCE, 20);
+ }
+ }
+
+ Audio_SetAmbienceChannelIO(AMBIENCE_CHANNEL_RAIN, CHANNEL_IO_PORT_1, 0);
+ Audio_SetAmbienceChannelIO(AMBIENCE_CHANNEL_LIGHTNING, CHANNEL_IO_PORT_1, 0);
+}
void Environment_WarpSongLeave(PlayState* play) {
gWeatherMode = WEATHER_MODE_CLEAR;
@@ -897,15 +3087,249 @@ void Environment_WarpSongLeave(PlayState* play) {
gSaveContext.nextTransitionType = TRANS_TYPE_FADE_WHITE;
}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_SetupSkyboxStars.s")
+void Environment_SetupSkyboxStars(PlayState* play) {
+ f32 phi_f0;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_DrawSkyboxStar.s")
+ if ((play->envCtx.skybox1Index == 0) && (play->skyboxId == SKYBOX_NORMAL_SKY)) {
+ if ((((void)0, gSaveContext.save.time) >= CLOCK_TIME(21, 0)) ||
+ (((void)0, gSaveContext.save.time) < CLOCK_TIME(2, 0))) {
+ phi_f0 = 1.0f;
+ } else if (((void)0, gSaveContext.save.time) > CLOCK_TIME(19, 0)) {
+ phi_f0 = 1.0f - ((CLOCK_TIME(21, 0) - ((void)0, gSaveContext.save.time)) * (1.0f / (CLOCK_TIME(2, 0) + 1)));
+ } else if (((void)0, gSaveContext.save.time) < CLOCK_TIME(3, 0)) {
+ phi_f0 = (CLOCK_TIME(3, 0) - ((void)0, gSaveContext.save.time)) * (1.0f / (CLOCK_TIME(1, 0) + 1));
+ } else {
+ phi_f0 = 0.0f;
+ }
+ phi_f0 = (play->envCtx.skyboxConfig == 0x18) ? 1.0f : phi_f0;
+
+ D_801F4F28 = phi_f0;
+ sEnvSkyboxNumStars = gSkyboxNumStars;
+ } else {
+ D_801F4F28 = 0.0f;
+ sEnvSkyboxNumStars = 0;
+ }
+
+ if ((sEnvSkyboxNumStars != 0) && (D_801F4F28 != 0.0f)) {
+ OPEN_DISPS(play->state.gfxCtx);
+
+ sSkyboxStarsDList = POLY_OPA_DISP;
+
+ gSPNoOp(POLY_OPA_DISP++);
+
+ CLOSE_DISPS(play->state.gfxCtx);
+ } else {
+ sSkyboxStarsDList = NULL;
+ }
+}
+
+void Environment_DrawSkyboxStar(Gfx** gfxp, f32 x, f32 y, s32 width, s32 height) {
+ Gfx* gfx = *gfxp;
+ u32 xl = x * 4.0f;
+ u32 yl = y * 4.0f;
+ u32 xd = width;
+ u32 yd = height;
+
+ gSPTextureRectangle(gfx++, xl, yl, xl + xd, yl + yd, 0, 0, 0, 0, 0);
+
+ *gfxp = gfx;
+}
+
+#ifdef NON_MATCHING
+// `D_801DD900`is loading unaligned but storing aligned
+// Also small float regalloc at the gRandFloat section
+// https://decomp.me/scratch/3zFop
+void Environment_DrawSkyboxStarsImpl(PlayState* play, Gfx** gfxP) {
+ static const Vec3s D_801DD880[] = {
+ { 0x0384, 0x2328, 0xD508 }, { 0x09C4, 0x2328, 0xDA1C }, { 0x0E74, 0x22D8, 0xDA1C }, { 0x1450, 0x2468, 0xD8F0 },
+ { 0x1C84, 0x28A0, 0xCBA8 }, { 0x1F40, 0x2134, 0xD8F0 }, { 0x1F40, 0x28A0, 0xDAE4 }, { 0xE4A8, 0x4A38, 0x4A38 },
+ { 0xD058, 0x4C2C, 0x3A98 }, { 0xD8F0, 0x36B0, 0x47E0 }, { 0xD954, 0x3264, 0x3E1C }, { 0xD8F0, 0x3070, 0x37DC },
+ { 0xD8F0, 0x1F40, 0x5208 }, { 0xD760, 0x1838, 0x27D8 }, { 0x0000, 0x4E20, 0x4A38 }, { 0x076C, 0x2328, 0xDCD8 },
+ };
+ // Possibly Color_RGBA8_u32
+ static const u32 D_801DD8E0[] = {
+ 0x41A4FFFF, 0x83A4E6FF, 0x62CDFFFF, 0x5252FFFF, 0x7BA4A4FF, 0x62CDFFFF, 0x62A4E6FF, 0xFF5A00FF,
+ };
+ static const u32 D_801DD900[] = {
+ 0x405070FF, 0x606080FF, 0x807090FF, 0xA080A0FF, 0xC090A8FF, 0xE0A0B0FF, 0xE0A0B0FF, 0x686888FF,
+ 0x887898FF, 0xA888A8FF, 0xC898B8FF, 0xE8A8B8FF, 0xE0B0B8FF, 0xF0C0C0FF, 0xE8B8C0FF, 0xF8C8C0FF,
+ };
+ Vec3f pos;
+ s32 pad1;
+ f32 imgY; // spF4
+ f32 imgX; // spF0
+ Gfx* gfx;
+ s32 phi_v1; // spE8
+ s32 negateY; // spE4
+ f32 invScale;
+ f32 temp_f20;
+ Gfx* gfxTemp; // spD8
+ f32 scale;
+ s32 i;
+ u32 randInt;
+ u32 imgWidth;
+ f32* imgXPtr;
+ f32* imgYPtr;
+ Vec3f* posPtr;
+ s32 pad[2];
+ f32(*viewProjectionMtxF)[4];
+
+ gfx = *gfxP;
+ negateY = Environment_IsSceneUpsideDown(play);
+
+ Matrix_MtxToMtxF(play->view.viewingPtr, &play->billboardMtxF);
+ Matrix_MtxToMtxF(&play->view.projection, &play->viewProjectionMtxF);
+ SkinMatrix_MtxFMtxFMult(&play->viewProjectionMtxF, &play->billboardMtxF, &play->viewProjectionMtxF);
+
+ phi_v1 = 0;
+
+ gDPPipeSync(gfx++);
+ gDPSetEnvColor(gfx++, 255, 255, 255, 255.0f * D_801F4F28);
+ gDPSetCombineLERP(gfx++, PRIMITIVE, 0, ENVIRONMENT, 0, PRIMITIVE, 0, ENVIRONMENT, 0, PRIMITIVE, 0, ENVIRONMENT, 0,
+ PRIMITIVE, 0, ENVIRONMENT, 0);
+ gDPSetOtherMode(gfx++,
+ G_AD_DISABLE | G_CD_DISABLE | G_CK_NONE | G_TC_FILT | G_TF_POINT | G_TT_NONE | G_TL_TILE |
+ G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
+ G_AC_NONE | G_ZS_PRIM | G_RM_AA_XLU_LINE | G_RM_AA_XLU_LINE2);
+
+ randInt = ((u32)gSaveContext.save.saveInfo.playerData.playerName[0] << 0x18) ^
+ ((u32)gSaveContext.save.saveInfo.playerData.playerName[1] << 0x14) ^
+ ((u32)gSaveContext.save.saveInfo.playerData.playerName[2] << 0x10) ^
+ ((u32)gSaveContext.save.saveInfo.playerData.playerName[3] << 0xC) ^
+ ((u32)gSaveContext.save.saveInfo.playerData.playerName[4] << 8) ^
+ ((u32)gSaveContext.save.saveInfo.playerData.playerName[5] << 4) ^
+ ((u32)gSaveContext.save.saveInfo.playerData.playerName[6] << 0) ^
+ ((u32)gSaveContext.save.saveInfo.playerData.playerName[7] >> 4) ^
+ ((u32)gSaveContext.save.saveInfo.playerData.playerName[7] << 0x1C);
+
+ //! FAKE:
+ if (play->view.viewingPtr && play->view.viewingPtr && play->view.viewingPtr) {}
+
+ for (i = 0; i < sEnvSkyboxNumStars; i++) {
+ if (i < 16) {
+ pos.x = play->view.eye.x + (s32)D_801DD880[i].x;
+ pos.y = play->view.eye.y + (s32)D_801DD880[i].y;
+ pos.z = play->view.eye.z + (s32)D_801DD880[i].z;
+ imgWidth = 8;
+ } else {
+ f32 temp_f22;
+ f32 temp_f4;
+ f32 temp_f2;
+
+ // temp_f4 = Rand_ZeroOne_Variable(&randInt);
+ randInt = (randInt * 1664525) + 1013904223;
+ gRandFloat = (randInt >> 9) | 0x3F800000;
+ temp_f4 = *((f32*)&gRandFloat) - 1.0f;
+
+ // temp_f20 = Rand_ZeroOne_Variable(&randInt);
+ randInt = (randInt * 1664525) + 1013904223;
+ gRandFloat = (randInt >> 9) | 0x3F800000;
+ temp_f20 = ((*((f32*)&gRandFloat) - 1.0f) + temp_f4) * 0.5f;
+
+ // randInt = Rand_Next_Variable(&randInt);
+ randInt = (randInt * 1664525) + 1013904223;
+
+ // Set random position
+ pos.y = play->view.eye.y + (SQ(temp_f20) * SQ(128.0f)) - 1000.0f;
+ pos.x = play->view.eye.x + (Math_SinS(randInt) * (1.2f - temp_f20) * SQ(128.0f));
+ pos.z = play->view.eye.z + (Math_CosS(randInt) * (1.2f - temp_f20) * SQ(128.0f));
+
+ // temp_f2 = Rand_ZeroOne_Variable(&randInt);
+ randInt = (randInt * 1664525) + 1013904223;
+ gRandFloat = ((randInt >> 9) | 0x3F800000);
+ temp_f2 = *((f32*)&gRandFloat) - 1.0f;
+
+ // Set random width
+ imgWidth = (u32)((SQ(temp_f2) * 8.0f) + 2.0f);
+ }
+
+ if (negateY) {
+ pos.y = -pos.y;
+ }
+
+ if ((i < 15) || ((i == 15) && ((((void)0, gSaveContext.save.day) % 7) == 0))) {
+ gDPSetColor(gfx++, G_SETPRIMCOLOR, D_801DD8E0[i % ARRAY_COUNTU(D_801DD8E0)]);
+ } else if (((i & 0x3F) == 0) || (i == 16)) {
+ gDPSetColor(gfx++, G_SETPRIMCOLOR, D_801DD900[phi_v1 % ARRAY_COUNTU(D_801DD900)]);
+ phi_v1++;
+ }
+
+ posPtr = &pos;
+ imgXPtr = &imgX;
+ imgYPtr = &imgY;
+ viewProjectionMtxF = play->viewProjectionMtxF.mf;
+
+ if (imgWidth >= 2) {
+ // w component
+ scale = pos.x * play->viewProjectionMtxF.mf[0][3] + pos.y * play->viewProjectionMtxF.mf[1][3] +
+ pos.z * play->viewProjectionMtxF.mf[2][3] + play->viewProjectionMtxF.mf[3][3];
+ if (scale >= 1.0f) {
+ invScale = 1.0f / scale;
+ // x component
+ imgX = (pos.x * viewProjectionMtxF[0][0] + pos.y * viewProjectionMtxF[1][0] +
+ pos.z * viewProjectionMtxF[2][0] + viewProjectionMtxF[3][0]) *
+ invScale;
+ // y component
+ imgY = (((pos.x * viewProjectionMtxF[0][1]) + (pos.y * viewProjectionMtxF[1][1]) +
+ (pos.z * viewProjectionMtxF[2][1])) +
+ viewProjectionMtxF[3][1]) *
+ invScale;
+ }
+
+ if ((scale >= 1.0f) && (imgX > -1.0f) && (imgX < 1.0f) && (imgY > -1.0f) && (imgY < 1.0f)) {
+ imgX = (imgX * (SCREEN_WIDTH / 2)) + (SCREEN_WIDTH / 2);
+ imgY = (imgY * -(SCREEN_HEIGHT / 2)) + (SCREEN_HEIGHT / 2);
+
+ gfxTemp = gfx;
+ Environment_DrawSkyboxStar(&gfxTemp, imgX, imgY, imgWidth, 4);
+ gfx = gfxTemp;
+ }
+ //! FAKE:
+ if (viewProjectionMtxF) {}
+ }
+ }
+
+ gDPPipeSync(gfx++);
+ *gfxP = gfx;
+}
+#else
+void Environment_DrawSkyboxStarsImpl(PlayState* play, Gfx** gfxP);
#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_DrawSkyboxStarsImpl.s")
+#endif
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_Draw.s")
+void Environment_Draw(PlayState* play) {
+ Environment_SetupSkyboxStars(play);
+ Environment_DrawSun(play);
+ Environment_UpdateLightningStrike(play);
+ Environment_DrawLightning(play, 0);
+ Environment_DrawSkyboxFilters(play);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_DrawSkyboxStars.s")
+void Environment_DrawSkyboxStars(PlayState* play) {
+ Gfx* nextOpa;
+ Gfx* opa;
+
+ if (sSkyboxStarsDList != NULL) {
+ OPEN_DISPS(play->state.gfxCtx);
+
+ opa = POLY_OPA_DISP;
+ nextOpa = Graph_GfxPlusOne(opa);
+
+ gSPDisplayList(sSkyboxStarsDList, nextOpa);
+
+ Environment_DrawSkyboxStarsImpl(play, &nextOpa);
+
+ gSPEndDisplayList(nextOpa++);
+
+ Graph_BranchDlist(opa, nextOpa);
+
+ POLY_OPA_DISP = nextOpa;
+ sSkyboxStarsDList = NULL;
+
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+}
void Environment_StopTime(void) {
sEnvIsTimeStopped = true;
@@ -992,21 +3416,101 @@ void Environment_SetTimeJump(f32 minutes) {
sTimeJump = CLOCK_TIME_F(0, minutes);
}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/func_800FE6F8.s")
+u8 func_800FE6F8(PlayState* play, s16 timeAdvanceScaling, s16 nextTimeLimit) {
+ u16 nextTime;
+ u8 ret = false;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_GetSandstormColorIndex.s")
+ if (R_TIME_SPEED != 0) {
+ nextTime = ((void)0, gSaveContext.save.time) +
+ (R_TIME_SPEED + ((void)0, gSaveContext.save.timeSpeedOffset)) * timeAdvanceScaling * 20;
+ if (nextTime > nextTimeLimit) {
+ ret = true;
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_GetNextSandstormColorIndex.s")
+ return ret;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_GetSandstormLerpScale.s")
+u8 Environment_GetSandstormColorIndex(void) {
+ return sSandstormColorIndex;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_LerpSandstormColors.s")
+u8 Environment_GetNextSandstormColorIndex(void) {
+ return sNextSandstormColorIndex;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/func_800FE9B4.s")
+f32 Environment_GetSandstormLerpScale(void) {
+ return sSandstormLerpScale;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/func_800FEA50.s")
+void Environment_LerpSandstormColors(Color_RGBA8* colorSrc, Color_RGBA8* colorDst) {
+ f32 sandstormLerpScale = Environment_GetSandstormLerpScale();
+ s32 pad;
+ u32 sandstormColorIndex = Environment_GetSandstormColorIndex();
+ u32 nextSandstormColorIndex = Environment_GetNextSandstormColorIndex();
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/func_800FEAB0.s")
+ if (sandstormLerpScale <= 0.0f) {
+ colorDst->r = colorSrc[sandstormColorIndex].r;
+ colorDst->g = colorSrc[sandstormColorIndex].g;
+ colorDst->b = colorSrc[sandstormColorIndex].b;
+ colorDst->a = colorSrc[sandstormColorIndex].a;
+ } else {
+ colorDst->r =
+ (s32)F32_LERP(colorSrc[sandstormColorIndex].r, colorSrc[nextSandstormColorIndex].r, sandstormLerpScale);
+ colorDst->g =
+ (s32)F32_LERP(colorSrc[sandstormColorIndex].g, colorSrc[nextSandstormColorIndex].g, sandstormLerpScale);
+ colorDst->b =
+ (s32)F32_LERP(colorSrc[sandstormColorIndex].b, colorSrc[nextSandstormColorIndex].b, sandstormLerpScale);
+ colorDst->a =
+ (s32)F32_LERP(colorSrc[sandstormColorIndex].a, colorSrc[nextSandstormColorIndex].a, sandstormLerpScale);
+ }
+}
+
+// Related to soft soil
+u8 func_800FE9B4(PlayState* play) {
+ u8 ret = false;
+
+ if ((play->envCtx.precipitation[PRECIP_SOS_MAX] == 60) && (play->envCtx.precipitation[PRECIP_SNOW_CUR] == 0)) {
+ ret = true;
+ }
+
+ if ((play->envCtx.precipitation[PRECIP_RAIN_MAX] == 60) &&
+ !(GET_ACTIVE_CAM(play)->stateFlags & CAM_STATE_UNDERWATER)) {
+ if ((Environment_GetStormState(play) != STORM_STATE_OFF) &&
+ (play->envCtx.precipitation[PRECIP_SNOW_CUR] == 0)) {
+ ret = true;
+ }
+ }
+
+ return ret;
+}
+
+void func_800FEA50(PlayState* play) {
+ s8 phi_v0;
+
+ switch (gSaveContext.save.day) {
+ default:
+ case 0:
+ case 1:
+ phi_v0 = 0;
+ break;
+
+ case 2:
+ phi_v0 = 3;
+ break;
+
+ case 3:
+ phi_v0 = 4;
+ break;
+ }
+
+ D_801F4F30 = phi_v0;
+ D_801F4F33 = true;
+}
+
+void func_800FEAB0() {
+ D_801F4F33 = false;
+}
void Environment_JumpForwardInTime(void) {
if (sTimeJump != 0) {
@@ -1015,4 +3519,65 @@ void Environment_JumpForwardInTime(void) {
}
}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/func_800FEAF4.s")
+void func_800FEAF4(EnvironmentContext* envCtx) {
+ u8 phi_v1 = 0;
+
+ if (((void)0, gSaveContext.save.day) != 0) {
+ phi_v1 = ((void)0, gSaveContext.save.day) - 1;
+ }
+
+ envCtx->skyboxConfig = phi_v1 + (D_801F4E31 * 3);
+ envCtx->changeSkyboxNextConfig = envCtx->skyboxConfig;
+
+ if (D_801F4E31 == 4) {
+ envCtx->skyboxConfig = 0xE;
+ envCtx->changeSkyboxNextConfig = envCtx->skyboxConfig;
+ } else if (D_801F4E31 == 5) {
+ envCtx->skyboxConfig = 0x10;
+ envCtx->changeSkyboxNextConfig = envCtx->skyboxConfig;
+ } else if (D_801F4E31 == 6) {
+ envCtx->skyboxConfig = 0x11;
+ envCtx->changeSkyboxNextConfig = envCtx->skyboxConfig;
+ } else if (D_801F4E31 == 7) {
+ envCtx->skyboxConfig = phi_v1 + 0x12;
+ envCtx->changeSkyboxNextConfig = envCtx->skyboxConfig;
+ } else if (D_801F4E31 == 8) {
+ envCtx->skyboxConfig = phi_v1 + 0x15;
+ envCtx->changeSkyboxNextConfig = envCtx->skyboxConfig;
+ } else if (D_801F4E31 == 9) {
+ envCtx->skyboxConfig = 0x18;
+ envCtx->changeSkyboxNextConfig = envCtx->skyboxConfig;
+ } else if (D_801F4E31 == 0xA) {
+ envCtx->skyboxConfig = phi_v1 + 0x19;
+ envCtx->changeSkyboxNextConfig = envCtx->skyboxConfig;
+ }
+
+ if (phi_v1 >= 3) {
+ envCtx->skyboxConfig = 0xD;
+ envCtx->changeSkyboxNextConfig = 0xD;
+ }
+
+ if (envCtx->skyboxConfig >= 0x1C) {
+ envCtx->skyboxConfig = 0;
+ envCtx->changeSkyboxNextConfig = 0;
+ }
+
+ switch (((void)0, gSaveContext.save.day)) {
+ default:
+ case 0:
+ case 1:
+ envCtx->lightConfig = 0;
+ envCtx->changeLightNextConfig = 0;
+ break;
+
+ case 2:
+ envCtx->lightConfig = 3;
+ envCtx->changeLightNextConfig = 3;
+ break;
+
+ case 3:
+ envCtx->lightConfig = 4;
+ envCtx->changeLightNextConfig = 4;
+ break;
+ }
+}
diff --git a/src/code/z_lib.c b/src/code/z_lib.c
index c520b00d56..cf5666ed48 100644
--- a/src/code/z_lib.c
+++ b/src/code/z_lib.c
@@ -663,15 +663,15 @@ void Lib_Vec3f_TranslateAndRotateY(Vec3f* translation, s16 rotAngle, Vec3f* src,
dst->z = translation->z + (src->z * cos - src->x * sin);
}
-void Color_RGB8_Lerp(Color_RGB8* a, Color_RGB8* b, f32 t, Color_RGB8* dst) {
+void Color_RGB8_Lerp(Color_RGB8* from, Color_RGB8* to, f32 lerp, Color_RGB8* dst) {
f32 aF;
- aF = a->r;
- dst->r = aF + (b->r - aF) * t;
- aF = a->g;
- dst->g = aF + (b->g - aF) * t;
- aF = a->b;
- dst->b = aF + (b->b - aF) * t;
+ aF = from->r;
+ dst->r = aF + (to->r - aF) * lerp;
+ aF = from->g;
+ dst->g = aF + (to->g - aF) * lerp;
+ aF = from->b;
+ dst->b = aF + (to->b - aF) * lerp;
}
f32 Math_Vec3f_StepTo(Vec3f* start, Vec3f* target, f32 speed) {
diff --git a/src/code/z_play.c b/src/code/z_play.c
index 783b73de29..bec7f5f442 100644
--- a/src/code/z_play.c
+++ b/src/code/z_play.c
@@ -385,7 +385,7 @@ void Play_Destroy(GameState* thisx) {
BombersNotebook_Destroy(&sBombersNotebook);
this->state.gfxCtx->callback = NULL;
- this->state.gfxCtx->callbackArg = 0;
+ this->state.gfxCtx->callbackArg = NULL;
Play_DestroyMotionBlur();
if (R_PAUSE_BG_PRERENDER_STATE != PAUSE_BG_PRERENDER_OFF) {
@@ -1332,7 +1332,7 @@ void Play_DrawMain(PlayState* this) {
}
if (1) {
- Environment_FillScreen(gfxCtx, 0, 0, 0, this->bgCoverAlpha, 1);
+ Environment_FillScreen(gfxCtx, 0, 0, 0, this->bgCoverAlpha, FILL_SCREEN_OPA);
}
if (1) {
@@ -1353,13 +1353,14 @@ void Play_DrawMain(PlayState* this) {
if (1) {
if (R_PLAY_FILL_SCREEN_ON) {
Environment_FillScreen(gfxCtx, R_PLAY_FILL_SCREEN_R, R_PLAY_FILL_SCREEN_G, R_PLAY_FILL_SCREEN_B,
- R_PLAY_FILL_SCREEN_ALPHA, 3);
+ R_PLAY_FILL_SCREEN_ALPHA, FILL_SCREEN_OPA | FILL_SCREEN_XLU);
}
switch (this->envCtx.fillScreen) {
case 1:
Environment_FillScreen(gfxCtx, this->envCtx.screenFillColor[0], this->envCtx.screenFillColor[1],
- this->envCtx.screenFillColor[2], this->envCtx.screenFillColor[3], 3);
+ this->envCtx.screenFillColor[2], this->envCtx.screenFillColor[3],
+ FILL_SCREEN_OPA | FILL_SCREEN_XLU);
break;
default:
@@ -1374,7 +1375,7 @@ void Play_DrawMain(PlayState* this) {
}
if (this->worldCoverAlpha != 0) {
- Environment_FillScreen(gfxCtx, 0, 0, 0, this->worldCoverAlpha, 3);
+ Environment_FillScreen(gfxCtx, 0, 0, 0, this->worldCoverAlpha, FILL_SCREEN_OPA | FILL_SCREEN_XLU);
}
if (1) {
diff --git a/src/overlays/actors/ovl_En_Encount3/z_en_encount3.c b/src/overlays/actors/ovl_En_Encount3/z_en_encount3.c
index 7646f7113b..f04714bb22 100644
--- a/src/overlays/actors/ovl_En_Encount3/z_en_encount3.c
+++ b/src/overlays/actors/ovl_En_Encount3/z_en_encount3.c
@@ -159,7 +159,7 @@ void EnEncount3_Update(Actor* thisx, PlayState* play2) {
Math_ApproachZeroF(&this->unk170, 0.3f, 10.0f);
Math_ApproachZeroF(&this->unk160, 0.3f, 5.0f);
if (this->unk160 < 1.0f) {
- play->unk_18880 = 0;
+ play->unk_18880 = false;
}
} else if (this->unk148 != 0) {
Math_ApproachF(&this->unk170, 255.0f, 0.4f, 10.0f);
diff --git a/src/overlays/actors/ovl_En_Invadepoh_Demo/z_en_invadepoh_demo.c b/src/overlays/actors/ovl_En_Invadepoh_Demo/z_en_invadepoh_demo.c
index 87164778e2..03dd89c435 100644
--- a/src/overlays/actors/ovl_En_Invadepoh_Demo/z_en_invadepoh_demo.c
+++ b/src/overlays/actors/ovl_En_Invadepoh_Demo/z_en_invadepoh_demo.c
@@ -750,7 +750,8 @@ void EnInvadepohDemo_Ufo_Draw(EnInvadepohDemo* this, PlayState* play) {
CLOSE_DISPS(play->state.gfxCtx);
if (EnInvadepohDemo_Ufo_ShouldDrawLensFlare(play, &flashPos)) {
- Environment_DrawLensFlare(play, &play->envCtx, &play->view, play->state.gfxCtx, flashPos, 20.0f, 9.0f, 0, 0);
+ Environment_DrawLensFlare(play, &play->envCtx, &play->view, play->state.gfxCtx, flashPos, 20.0f, 9.0f, 0,
+ false);
}
}
diff --git a/src/overlays/actors/ovl_En_Jso/z_en_jso.c b/src/overlays/actors/ovl_En_Jso/z_en_jso.c
index 18c342296f..48b9e0b401 100644
--- a/src/overlays/actors/ovl_En_Jso/z_en_jso.c
+++ b/src/overlays/actors/ovl_En_Jso/z_en_jso.c
@@ -553,7 +553,7 @@ void EnJso_HandleIntroCutscene(EnJso* this, PlayState* play) {
if (parent->actor.update != NULL) {
parent->unk148 = 1;
- play->unk_18880 = 1;
+ play->unk_18880 = true;
}
}
diff --git a/src/overlays/actors/ovl_En_Okarina_Effect/z_en_okarina_effect.c b/src/overlays/actors/ovl_En_Okarina_Effect/z_en_okarina_effect.c
index cef823a359..3e59cce626 100644
--- a/src/overlays/actors/ovl_En_Okarina_Effect/z_en_okarina_effect.c
+++ b/src/overlays/actors/ovl_En_Okarina_Effect/z_en_okarina_effect.c
@@ -48,7 +48,7 @@ void EnOkarinaEffect_Init(Actor* thisx, PlayState* play) {
}
void func_8096B104(EnOkarinaEffect* this, PlayState* play) {
- this->unk144 = 0x50;
+ this->timer = 80;
play->envCtx.precipitation[PRECIP_SOS_MAX] = 60;
gLightningStrike.delayTimer = 501.0f;
play->envCtx.lightningState = LIGHTNING_LAST;
@@ -57,9 +57,9 @@ void func_8096B104(EnOkarinaEffect* this, PlayState* play) {
}
void func_8096B174(EnOkarinaEffect* this, PlayState* play) {
- DECR(this->unk144);
+ DECR(this->timer);
if ((play->pauseCtx.state == PAUSE_STATE_OFF) && (play->gameOverCtx.state == GAMEOVER_INACTIVE) &&
- (play->msgCtx.msgLength == 0) && !FrameAdvance_IsEnabled(&play->state) && (this->unk144 == 0)) {
+ (play->msgCtx.msgLength == 0) && !FrameAdvance_IsEnabled(&play->state) && (this->timer == 0)) {
EnOkarinaEffect_SetupAction(this, func_8096B1FC);
}
}
diff --git a/src/overlays/actors/ovl_En_Okarina_Effect/z_en_okarina_effect.h b/src/overlays/actors/ovl_En_Okarina_Effect/z_en_okarina_effect.h
index b633ab3905..8be64654bc 100644
--- a/src/overlays/actors/ovl_En_Okarina_Effect/z_en_okarina_effect.h
+++ b/src/overlays/actors/ovl_En_Okarina_Effect/z_en_okarina_effect.h
@@ -9,8 +9,7 @@ typedef void (*EnOkarinaEffectActionFunc)(struct EnOkarinaEffect*, PlayState*);
typedef struct EnOkarinaEffect {
/* 0x000 */ Actor actor;
- /* 0x144 */ u16 unk144;
- /* 0x146 */ u16 unk146;
+ /* 0x144 */ u16 timer;
/* 0x148 */ EnOkarinaEffectActionFunc actionFunc;
} EnOkarinaEffect; // size = 0x14C
diff --git a/src/overlays/actors/ovl_En_Test4/z_en_test4.c b/src/overlays/actors/ovl_En_Test4/z_en_test4.c
index 75eed71487..0e2e81bbd8 100644
--- a/src/overlays/actors/ovl_En_Test4/z_en_test4.c
+++ b/src/overlays/actors/ovl_En_Test4/z_en_test4.c
@@ -431,7 +431,7 @@ void func_80A42AB8(EnTest4* this, PlayState* play) {
this->unk_146 = gSaveContext.save.time += CLOCK_TIME_MINUTE;
}
} else if ((new_var * bellDiff) <= 0) {
- Audio_PlaySfx_BigBells(&this->actor.projectedPos, (this->actor.params >> 5) & 0xF);
+ Audio_PlaySfx_BigBells(&this->actor.projectedPos, TEST4_GET_BIG_BELLS_SFX_VOLUME_INDEX(&this->actor));
this->lastBellTime = gSaveContext.save.time;
if (CURRENT_DAY == 3) {
@@ -553,11 +553,11 @@ void func_80A431C8(EnTest4* this, PlayState* play) {
}
}
-void func_80A4323C(EnTest4* this, PlayState* play) {
- s32 temp_v0 = (this->actor.params >> 0xA) * 0x64;
+void EnTest4_SetSkyboxNumStars(EnTest4* this, PlayState* play) {
+ s32 numStars = TEST4_GET_SKYBOX_NUM_STARS(&this->actor);
- if (temp_v0 > 0) {
- gSkyboxNumStars = temp_v0;
+ if (numStars > 0) {
+ gSkyboxNumStars = numStars;
}
}
@@ -578,6 +578,6 @@ void EnTest4_Update(Actor* thisx, PlayState* play) {
break;
}
}
- func_80A4323C(this, play);
+ EnTest4_SetSkyboxNumStars(this, play);
}
}
diff --git a/src/overlays/actors/ovl_En_Test4/z_en_test4.h b/src/overlays/actors/ovl_En_Test4/z_en_test4.h
index 106a5a9aaa..2d6e5a6ff7 100644
--- a/src/overlays/actors/ovl_En_Test4/z_en_test4.h
+++ b/src/overlays/actors/ovl_En_Test4/z_en_test4.h
@@ -5,6 +5,9 @@
struct EnTest4;
+#define TEST4_GET_SKYBOX_NUM_STARS(thisx) (((thisx)->params >> 10) * 100)
+#define TEST4_GET_BIG_BELLS_SFX_VOLUME_INDEX(thisx) (((thisx)->params >> 5) & 0xF)
+
typedef void (*EnTest4ActionFunc)(struct EnTest4*, PlayState*);
typedef struct EnTest4 {
diff --git a/src/overlays/actors/ovl_En_Test7/z_en_test7.c b/src/overlays/actors/ovl_En_Test7/z_en_test7.c
index 59de7be655..6c2c6f461a 100644
--- a/src/overlays/actors/ovl_En_Test7/z_en_test7.c
+++ b/src/overlays/actors/ovl_En_Test7/z_en_test7.c
@@ -988,6 +988,6 @@ void EnTest7_Draw(Actor* thisx, PlayState* play) {
if (this->unk_144 & 4) {
Environment_DrawLensFlare(play, &play->envCtx, &play->view, play->state.gfxCtx, this->actor.world.pos, 70.0f,
- 5.0f, 0, 0);
+ 5.0f, 0, false);
}
}
diff --git a/src/overlays/actors/ovl_En_Weather_Tag/z_en_weather_tag.c b/src/overlays/actors/ovl_En_Weather_Tag/z_en_weather_tag.c
index e0319ad7e0..37f80d372c 100644
--- a/src/overlays/actors/ovl_En_Weather_Tag/z_en_weather_tag.c
+++ b/src/overlays/actors/ovl_En_Weather_Tag/z_en_weather_tag.c
@@ -86,7 +86,7 @@ void EnWeatherTag_Init(Actor* thisx, PlayState* play) {
EnWeatherTag_SetupAction(this, func_80966EF0);
break;
- case WEATHERTAG_TYPE_UNK4:
+ case WEATHERTAG_TYPE_SKYBOX_STARS:
EnWeatherTag_SetupAction(this, func_80966FEC);
break;
@@ -352,14 +352,11 @@ void func_80966F74(EnWeatherTag* this, PlayState* play) {
}
}
-// WEATHERTAG_TYPE_UNK4: no visible effect, what does it doooo??
-// used in south clock town??? romani ranch, clock tower rooftop woodfall..? stt
-// all of them have shorter distances though, like 0xA and 0x6, so their locations are important
void func_80966FEC(EnWeatherTag* this, PlayState* play) {
- // weirdly, not the same as the other param lookup used in the rest of the file, which is float
- s32 distance = WEATHER_TAG_RANGE100INT(&this->actor);
- if (distance > 0) {
- gSkyboxNumStars = distance;
+ s32 numStars = WEATHER_TAG_GET_SKYBOX_NUM_STARS(&this->actor);
+
+ if (numStars > 0) {
+ gSkyboxNumStars = numStars;
}
if ((play->sceneId == SCENE_KAIZOKU) && (play->actorCtx.flags & ACTORCTX_FLAG_1)) {
diff --git a/src/overlays/actors/ovl_En_Weather_Tag/z_en_weather_tag.h b/src/overlays/actors/ovl_En_Weather_Tag/z_en_weather_tag.h
index 5313aacfd5..dece04414b 100644
--- a/src/overlays/actors/ovl_En_Weather_Tag/z_en_weather_tag.h
+++ b/src/overlays/actors/ovl_En_Weather_Tag/z_en_weather_tag.h
@@ -22,14 +22,14 @@ typedef struct EnWeatherTag {
#define WEATHER_TAG_TYPE(thisx) ((thisx)->params & 0xF)
#define WEATHER_TAG_PATHID(thisx) (((thisx)->params >> 4) & 0xF)
#define WEATHER_TAG_RANGE100(thisx) ((u8)(((thisx)->params >> 8) & 0xFF) * 100.0f)
-#define WEATHER_TAG_RANGE100INT(thisx) ((u8)(((thisx)->params >> 8) & 0xFF) * 100)
+#define WEATHER_TAG_GET_SKYBOX_NUM_STARS(thisx) ((u8)(((thisx)->params >> 8) & 0xFF) * 100)
typedef enum {
/* 0 */ WEATHERTAG_TYPE_UNK0,
/* 1 */ WEATHERTAG_TYPE_UNK1,
/* 2 */ WEATHERTAG_TYPE_WINTERFOG,
/* 3 */ WEATHERTAG_TYPE_UNK3,
- /* 4 */ WEATHERTAG_TYPE_UNK4,
+ /* 4 */ WEATHERTAG_TYPE_SKYBOX_STARS,
/* 5 */ WEATHERTAG_TYPE_UNK5,
/* 6 */ WEATHERTAG_TYPE_WATERMURK,
/* 7 */ WEATHERTAG_TYPE_LOCALDAY2RAIN
diff --git a/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c b/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c
index 309bbd8ad2..ab4df1a6ab 100644
--- a/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c
+++ b/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c
@@ -511,7 +511,8 @@ void func_808DD3C8(Actor* thisx, PlayState* play2) {
f32 temp_f2;
f32 tempf;
- if ((play->cameraPtrs[CAM_ID_MAIN]->stateFlags & CAM_STATE_UNDERWATER) || ((u8)play->envCtx.stormState == 0)) {
+ if ((play->cameraPtrs[CAM_ID_MAIN]->stateFlags & CAM_STATE_UNDERWATER) ||
+ ((u8)play->envCtx.stormState == STORM_STATE_OFF)) {
return;
}
@@ -687,7 +688,7 @@ void func_808DDE9C(Actor* thisx, PlayState* play2) {
}
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
- gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_0706E0);
+ gSPDisplayList(POLY_XLU_DISP++, gFallingRainDropDL);
}
}
diff --git a/src/overlays/gamestates/ovl_title/z_title.c b/src/overlays/gamestates/ovl_title/z_title.c
index 5cebc2fca4..3e87bb72eb 100644
--- a/src/overlays/gamestates/ovl_title/z_title.c
+++ b/src/overlays/gamestates/ovl_title/z_title.c
@@ -112,7 +112,7 @@ void ConsoleLogo_Draw(GameState* thisx) {
1 << 10, 1 << 10);
}
- Environment_FillScreen(this->state.gfxCtx, 0, 0, 0, this->coverAlpha, 2);
+ Environment_FillScreen(this->state.gfxCtx, 0, 0, 0, this->coverAlpha, FILL_SCREEN_XLU);
sTitleRotation += 300;
diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt
index 7e1f262c48..9f816e5c86 100644
--- a/tools/disasm/functions.txt
+++ b/tools/disasm/functions.txt
@@ -1720,7 +1720,7 @@
0x800F6AB8:("Environment_UpdateNextDayTime",),
0x800F6B44:("Environment_UpdateTime",),
0x800F6CEC:("func_800F6CEC",),
- 0x800F6EA4:("func_800F6EA4",),
+ 0x800F6EA4:("Environment_LerpColor",),
0x800F6FCC:("Environment_IsSceneUpsideDown",),
0x800F6FF8:("Environment_UpdateLights",),
0x800F8554:("Environment_UpdateSun",),
@@ -10412,7 +10412,7 @@
0x80A42F20:("func_80A42F20",),
0x80A430C8:("func_80A430C8",),
0x80A431C8:("func_80A431C8",),
- 0x80A4323C:("func_80A4323C",),
+ 0x80A4323C:("EnTest4_SetSkyboxNumStars",),
0x80A43274:("EnTest4_Update",),
0x80A434E0:("EnBat_Init",),
0x80A437A0:("EnBat_Destroy",),
diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt
index d80ea80a38..fe97f2b487 100644
--- a/tools/disasm/variables.txt
+++ b/tools/disasm/variables.txt
@@ -323,7 +323,7 @@
0x8009CCD0:("sFaultDrawer","FaultDrawer","",0x3c),
0x8009CD10:("D_8009CD10","UNK_TYPE4","",0x4),
0x8009CD20:("gSystemArena","Arena","",0x24),
- 0x8009CD50:("sRandFloat","f32","",0x4),
+ 0x8009CD50:("gRandFloat","f32","",0x4),
0x8009CD60:("sArenaLockMsg","OSMesg","[1]",0x4),
0x8009CD70:("tmp_task","OSTask","",0x40),
0x8009CDB0:("__MotorDataBuf","OSPifRam","[4]",0x100),
diff --git a/tools/sizes/code_functions.csv b/tools/sizes/code_functions.csv
index d4c9913495..4430810d3e 100644
--- a/tools/sizes/code_functions.csv
+++ b/tools/sizes/code_functions.csv
@@ -1229,12 +1229,12 @@ asm/non_matchings/code/z_kankyo/Environment_LerpWeightAccelDecel.s,Environment_L
asm/non_matchings/code/z_kankyo/Environment_UpdateSkybox.s,Environment_UpdateSkybox,0x800F5CD0,0x2D9
asm/non_matchings/code/z_kankyo/Environment_EnableUnderwaterLights.s,Environment_EnableUnderwaterLights,0x800F6834,0x46
asm/non_matchings/code/z_kankyo/Environment_DisableUnderwaterLights.s,Environment_DisableUnderwaterLights,0x800F694C,0x2E
-asm/non_matchings/code/z_kankyo/func_800F6A04.s,func_800F6A04,0x800F6A04,0xF
+asm/non_matchings/code/z_kankyo/Environment_WipeRumbleRequests.s,Environment_WipeRumbleRequests,0x800F6A04,0xF
asm/non_matchings/code/z_kankyo/Environment_UpdateSkyboxRotY.s,Environment_UpdateSkyboxRotY,0x800F6A40,0x1E
asm/non_matchings/code/z_kankyo/Environment_UpdateNextDayTime.s,Environment_UpdateNextDayTime,0x800F6AB8,0x23
asm/non_matchings/code/z_kankyo/Environment_UpdateTime.s,Environment_UpdateTime,0x800F6B44,0x6A
asm/non_matchings/code/z_kankyo/func_800F6CEC.s,func_800F6CEC,0x800F6CEC,0x6E
-asm/non_matchings/code/z_kankyo/func_800F6EA4.s,func_800F6EA4,0x800F6EA4,0x4A
+asm/non_matchings/code/z_kankyo/Environment_LerpColor.s,Environment_LerpColor,0x800F6EA4,0x4A
asm/non_matchings/code/z_kankyo/Environment_IsSceneUpsideDown.s,Environment_IsSceneUpsideDown,0x800F6FCC,0xB
asm/non_matchings/code/z_kankyo/Environment_UpdateLights.s,Environment_UpdateLights,0x800F6FF8,0x557
asm/non_matchings/code/z_kankyo/Environment_UpdateSun.s,Environment_UpdateSun,0x800F8554,0xDC