mirror of
https://github.com/zeldaret/oot.git
synced 2024-12-02 07:46:01 +00:00
8ff58118b3
* Generic Camera Flags * New flag names * Add flags to functions * Finish flag docs * More docs * More cleanup * More clarity * Better shrinkwindow flag docs * Improve name * CAM_INTERFACE_FLAGS * Better approach to edge cases * Change ordering for consistency * Oops * Add masks to macro * PR/Discord discussions * cleanup comment * Oops * PR Suggestions * More PR Feedback * More PR Suggestions * PR Suggestions * More flag style change * Small cleanup * sync names with other PRs * more fixes * fix comments * update with hud visibility mode docs * missed one * fix comments * Roman PR Suggestions * interfaceField * small fix * letterbox cleanup * fix macro arg * fix func declaration
2620 lines
107 KiB
C
2620 lines
107 KiB
C
#include "global.h"
|
||
#include "ultra64.h"
|
||
#include "terminal.h"
|
||
#include "assets/objects/gameplay_keep/gameplay_keep.h"
|
||
#include "assets/objects/gameplay_field_keep/gameplay_field_keep.h"
|
||
|
||
typedef enum {
|
||
/* 0x00 */ LIGHTNING_BOLT_START,
|
||
/* 0x01 */ LIGHTNING_BOLT_WAIT,
|
||
/* 0x02 */ LIGHTNING_BOLT_DRAW,
|
||
/* 0xFF */ LIGHTNING_BOLT_INACTIVE = 0xFF
|
||
} LightningBoltState;
|
||
|
||
typedef struct {
|
||
/* 0x00 */ s32 mantissa;
|
||
/* 0x04 */ s32 exponent;
|
||
} ZBufValConversionEntry; // size = 0x8
|
||
|
||
ZBufValConversionEntry sZBufValConversionTable[1 << 3] = {
|
||
{ 6, 0x00000 }, { 5, 0x20000 }, { 4, 0x30000 }, { 3, 0x38000 },
|
||
{ 2, 0x3C000 }, { 1, 0x3E000 }, { 0, 0x3F000 }, { 0, 0x3F800 },
|
||
};
|
||
|
||
u8 gWeatherMode = WEATHER_MODE_CLEAR; // "E_wether_flg"
|
||
|
||
u8 gLightConfigAfterUnderwater = 0;
|
||
|
||
u8 gInterruptSongOfStorms = false;
|
||
|
||
// Indicates whether the skybox is changing to a different index of the same config (based on time)
|
||
u8 gSkyboxIsChanging = false;
|
||
|
||
// how many units of time that pass every update
|
||
u16 gTimeSpeed = 0;
|
||
|
||
u16 sSunScreenDepth = GPACK_ZDZ(G_MAXFBZ, 0);
|
||
|
||
typedef struct {
|
||
/* 0x00 */ u16 startTime;
|
||
/* 0x02 */ u16 endTime;
|
||
/* 0x04 */ u8 lightSetting;
|
||
/* 0x05 */ u8 nextLightSetting;
|
||
} TimeBasedLightEntry; // size = 0x6
|
||
|
||
TimeBasedLightEntry sTimeBasedLightConfigs[][7] = {
|
||
{
|
||
{ CLOCK_TIME(0, 0), CLOCK_TIME(4, 0) + 1, 3, 3 },
|
||
{ CLOCK_TIME(4, 0) + 1, CLOCK_TIME(6, 0), 3, 0 },
|
||
{ CLOCK_TIME(6, 0), CLOCK_TIME(8, 0) + 1, 0, 1 },
|
||
{ CLOCK_TIME(8, 0) + 1, CLOCK_TIME(16, 0), 1, 1 },
|
||
{ CLOCK_TIME(16, 0), CLOCK_TIME(17, 0) + 1, 1, 2 },
|
||
{ CLOCK_TIME(17, 0) + 1, CLOCK_TIME(19, 0) + 1, 2, 3 },
|
||
{ CLOCK_TIME(19, 0) + 1, CLOCK_TIME(24, 0) - 1, 3, 3 },
|
||
},
|
||
{
|
||
{ CLOCK_TIME(0, 0), CLOCK_TIME(4, 0) + 1, 7, 7 },
|
||
{ CLOCK_TIME(4, 0) + 1, CLOCK_TIME(6, 0), 7, 4 },
|
||
{ CLOCK_TIME(6, 0), CLOCK_TIME(8, 0) + 1, 4, 5 },
|
||
{ CLOCK_TIME(8, 0) + 1, CLOCK_TIME(16, 0), 5, 5 },
|
||
{ CLOCK_TIME(16, 0), CLOCK_TIME(17, 0) + 1, 5, 6 },
|
||
{ CLOCK_TIME(17, 0) + 1, CLOCK_TIME(19, 0) + 1, 6, 7 },
|
||
{ CLOCK_TIME(19, 0) + 1, CLOCK_TIME(24, 0) - 1, 7, 7 },
|
||
},
|
||
{
|
||
{ CLOCK_TIME(0, 0), CLOCK_TIME(4, 0) + 1, 11, 11 },
|
||
{ CLOCK_TIME(4, 0) + 1, CLOCK_TIME(6, 0), 11, 8 },
|
||
{ CLOCK_TIME(6, 0), CLOCK_TIME(8, 0) + 1, 8, 9 },
|
||
{ CLOCK_TIME(8, 0) + 1, CLOCK_TIME(16, 0), 9, 9 },
|
||
{ CLOCK_TIME(16, 0), CLOCK_TIME(17, 0) + 1, 9, 10 },
|
||
{ CLOCK_TIME(17, 0) + 1, CLOCK_TIME(19, 0) + 1, 10, 11 },
|
||
{ CLOCK_TIME(19, 0) + 1, CLOCK_TIME(24, 0) - 1, 11, 11 },
|
||
},
|
||
{
|
||
{ CLOCK_TIME(0, 0), CLOCK_TIME(4, 0) + 1, 15, 15 },
|
||
{ CLOCK_TIME(4, 0) + 1, CLOCK_TIME(6, 0), 15, 12 },
|
||
{ CLOCK_TIME(6, 0), CLOCK_TIME(8, 0) + 1, 12, 13 },
|
||
{ CLOCK_TIME(8, 0) + 1, CLOCK_TIME(16, 0), 13, 13 },
|
||
{ CLOCK_TIME(16, 0), CLOCK_TIME(17, 0) + 1, 13, 14 },
|
||
{ CLOCK_TIME(17, 0) + 1, CLOCK_TIME(19, 0) + 1, 14, 15 },
|
||
{ CLOCK_TIME(19, 0) + 1, CLOCK_TIME(24, 0) - 1, 15, 15 },
|
||
},
|
||
{
|
||
{ CLOCK_TIME(0, 0), CLOCK_TIME(4, 0) + 1, 23, 23 },
|
||
{ CLOCK_TIME(4, 0) + 1, CLOCK_TIME(6, 0), 23, 20 },
|
||
{ CLOCK_TIME(6, 0), CLOCK_TIME(8, 0) + 1, 20, 21 },
|
||
{ CLOCK_TIME(8, 0) + 1, CLOCK_TIME(16, 0), 21, 21 },
|
||
{ CLOCK_TIME(16, 0), CLOCK_TIME(17, 0) + 1, 21, 22 },
|
||
{ CLOCK_TIME(17, 0) + 1, CLOCK_TIME(19, 0) + 1, 22, 23 },
|
||
{ CLOCK_TIME(19, 0) + 1, CLOCK_TIME(24, 0) - 1, 23, 23 },
|
||
},
|
||
};
|
||
|
||
TimeBasedSkyboxEntry gTimeBasedSkyboxConfigs[][9] = {
|
||
{
|
||
{ CLOCK_TIME(0, 0), CLOCK_TIME(4, 0) + 1, false, 3, 3 },
|
||
{ CLOCK_TIME(4, 0) + 1, CLOCK_TIME(5, 0) + 1, true, 3, 0 },
|
||
{ CLOCK_TIME(5, 0) + 1, CLOCK_TIME(6, 0), false, 0, 0 },
|
||
{ CLOCK_TIME(6, 0), CLOCK_TIME(8, 0) + 1, true, 0, 1 },
|
||
{ CLOCK_TIME(8, 0) + 1, CLOCK_TIME(16, 0), false, 1, 1 },
|
||
{ CLOCK_TIME(16, 0), CLOCK_TIME(17, 0) + 1, true, 1, 2 },
|
||
{ CLOCK_TIME(17, 0) + 1, CLOCK_TIME(18, 0) + 1, false, 2, 2 },
|
||
{ CLOCK_TIME(18, 0) + 1, CLOCK_TIME(19, 0) + 1, true, 2, 3 },
|
||
{ CLOCK_TIME(19, 0) + 1, CLOCK_TIME(24, 0) - 1, false, 3, 3 },
|
||
},
|
||
{
|
||
{ CLOCK_TIME(0, 0), CLOCK_TIME(4, 0) + 1, false, 7, 7 },
|
||
{ CLOCK_TIME(4, 0) + 1, CLOCK_TIME(5, 0) + 1, true, 7, 4 },
|
||
{ CLOCK_TIME(5, 0) + 1, CLOCK_TIME(6, 0), false, 4, 4 },
|
||
{ CLOCK_TIME(6, 0), CLOCK_TIME(8, 0) + 1, true, 4, 5 },
|
||
{ CLOCK_TIME(8, 0) + 1, CLOCK_TIME(16, 0), false, 5, 5 },
|
||
{ CLOCK_TIME(16, 0), CLOCK_TIME(17, 0) + 1, true, 5, 6 },
|
||
{ CLOCK_TIME(17, 0) + 1, CLOCK_TIME(18, 0) + 1, false, 6, 6 },
|
||
{ CLOCK_TIME(18, 0) + 1, CLOCK_TIME(19, 0) + 1, true, 6, 7 },
|
||
{ CLOCK_TIME(19, 0) + 1, CLOCK_TIME(24, 0) - 1, false, 7, 7 },
|
||
},
|
||
{
|
||
{ CLOCK_TIME(0, 0), CLOCK_TIME(2, 0) + 1, false, 3, 3 },
|
||
{ CLOCK_TIME(2, 0) + 1, CLOCK_TIME(4, 0) + 1, true, 3, 0 },
|
||
{ CLOCK_TIME(4, 0) + 1, CLOCK_TIME(8, 0) + 1, false, 0, 0 },
|
||
{ CLOCK_TIME(8, 0) + 1, CLOCK_TIME(10, 0), true, 0, 1 },
|
||
{ CLOCK_TIME(10, 0), CLOCK_TIME(14, 0) + 1, false, 1, 1 },
|
||
{ CLOCK_TIME(14, 0) + 1, CLOCK_TIME(16, 0), true, 1, 2 },
|
||
{ CLOCK_TIME(16, 0), CLOCK_TIME(20, 0) + 1, false, 2, 2 },
|
||
{ CLOCK_TIME(20, 0) + 1, CLOCK_TIME(22, 0), true, 2, 3 },
|
||
{ CLOCK_TIME(22, 0), CLOCK_TIME(24, 0) - 1, false, 3, 3 },
|
||
},
|
||
{
|
||
{ CLOCK_TIME(0, 0), CLOCK_TIME(5, 0) + 1, false, 11, 11 },
|
||
{ CLOCK_TIME(5, 0) + 1, CLOCK_TIME(6, 0), true, 11, 8 },
|
||
{ CLOCK_TIME(6, 0), CLOCK_TIME(7, 0), false, 8, 8 },
|
||
{ CLOCK_TIME(7, 0), CLOCK_TIME(8, 0) + 1, true, 8, 9 },
|
||
{ CLOCK_TIME(8, 0) + 1, CLOCK_TIME(16, 0), false, 9, 9 },
|
||
{ CLOCK_TIME(16, 0), CLOCK_TIME(17, 0) + 1, true, 9, 10 },
|
||
{ CLOCK_TIME(17, 0) + 1, CLOCK_TIME(18, 0) + 1, false, 10, 10 },
|
||
{ CLOCK_TIME(18, 0) + 1, CLOCK_TIME(19, 0) + 1, true, 10, 11 },
|
||
{ CLOCK_TIME(19, 0) + 1, CLOCK_TIME(24, 0) - 1, false, 11, 11 },
|
||
},
|
||
};
|
||
|
||
SkyboxFile gNormalSkyFiles[] = {
|
||
{
|
||
ROM_FILE(vr_fine0_static),
|
||
ROM_FILE(vr_fine0_pal_static),
|
||
},
|
||
{
|
||
ROM_FILE(vr_fine1_static),
|
||
ROM_FILE(vr_fine1_pal_static),
|
||
},
|
||
{
|
||
ROM_FILE(vr_fine2_static),
|
||
ROM_FILE(vr_fine2_pal_static),
|
||
},
|
||
{
|
||
ROM_FILE(vr_fine3_static),
|
||
ROM_FILE(vr_fine3_pal_static),
|
||
},
|
||
{
|
||
ROM_FILE(vr_cloud0_static),
|
||
ROM_FILE(vr_cloud0_pal_static),
|
||
},
|
||
{
|
||
ROM_FILE(vr_cloud1_static),
|
||
ROM_FILE(vr_cloud1_pal_static),
|
||
},
|
||
{
|
||
ROM_FILE(vr_cloud2_static),
|
||
ROM_FILE(vr_cloud2_pal_static),
|
||
},
|
||
{
|
||
ROM_FILE(vr_cloud3_static),
|
||
ROM_FILE(vr_cloud3_pal_static),
|
||
},
|
||
{
|
||
ROM_FILE(vr_holy0_static),
|
||
ROM_FILE(vr_holy0_pal_static),
|
||
},
|
||
};
|
||
|
||
u8 sSandstormColorIndex = 0;
|
||
u8 sNextSandstormColorIndex = 0;
|
||
f32 sSandstormLerpScale = 0.0f;
|
||
|
||
u8 gCustomLensFlareOn;
|
||
Vec3f gCustomLensFlarePos;
|
||
s16 gLensFlareUnused;
|
||
s16 gLensFlareScale;
|
||
f32 gLensFlareColorIntensity;
|
||
s16 gLensFlareGlareStrength;
|
||
|
||
typedef struct {
|
||
/* 0x00 */ u8 state;
|
||
/* 0x04 */ Vec3f offset;
|
||
/* 0x10 */ Vec3f pos;
|
||
/* 0x1C */ s8 pitch;
|
||
/* 0x1D */ s8 roll;
|
||
/* 0x1E */ u8 textureIndex;
|
||
/* 0x1F */ u8 delayTimer;
|
||
} LightningBolt; // size = 0x20
|
||
|
||
LightningBolt sLightningBolts[3];
|
||
|
||
LightningStrike gLightningStrike;
|
||
|
||
s16 sLightningFlashAlpha;
|
||
|
||
s16 sSunDepthTestX;
|
||
s16 sSunDepthTestY;
|
||
|
||
LightNode* sNGameOverLightNode;
|
||
LightInfo sNGameOverLightInfo;
|
||
LightNode* sSGameOverLightNode;
|
||
LightInfo sSGameOverLightInfo;
|
||
u8 sGameOverLightsIntensity;
|
||
u16 sSandstormScroll;
|
||
|
||
#define ZBUFVAL_EXPONENT(v) (((v) >> 15) & 7)
|
||
#define ZBUFVAL_MANTISSA(v) (((v) >> 4) & 0x7FF)
|
||
|
||
/**
|
||
* Convert an 18-bits Z buffer value to a fixed point 15.3 value
|
||
*
|
||
* zBufferVal is 18 bits:
|
||
* 3: Exponent of z value
|
||
* 11: Mantissa of z value
|
||
* 4: dz value (unused)
|
||
*/
|
||
s32 Environment_ZBufValToFixedPoint(s32 zBufferVal) {
|
||
// base[exp] + mantissa << shift[exp]
|
||
s32 ret = (ZBUFVAL_MANTISSA(zBufferVal) << sZBufValConversionTable[ZBUFVAL_EXPONENT(zBufferVal)].mantissa) +
|
||
sZBufValConversionTable[ZBUFVAL_EXPONENT(zBufferVal)].exponent;
|
||
|
||
return ret;
|
||
}
|
||
|
||
u16 Environment_GetPixelDepth(s32 x, s32 y) {
|
||
s32 pixelDepth = gZBuffer[y][x];
|
||
|
||
return pixelDepth;
|
||
}
|
||
|
||
void Environment_GraphCallback(GraphicsContext* gfxCtx, void* param) {
|
||
PlayState* play = (PlayState*)param;
|
||
|
||
sSunScreenDepth = Environment_GetPixelDepth(sSunDepthTestX, sSunDepthTestY);
|
||
Lights_GlowCheck(play);
|
||
}
|
||
|
||
void Environment_Init(PlayState* play2, EnvironmentContext* envCtx, s32 unused) {
|
||
u8 i;
|
||
PlayState* play = play2;
|
||
|
||
gSaveContext.sunsSongState = SUNSSONG_INACTIVE;
|
||
|
||
if (((void)0, gSaveContext.dayTime) > CLOCK_TIME(18, 0) || ((void)0, gSaveContext.dayTime) < CLOCK_TIME(6, 30)) {
|
||
((void)0, gSaveContext.nightFlag = 1);
|
||
} else {
|
||
((void)0, gSaveContext.nightFlag = 0);
|
||
}
|
||
|
||
play->state.gfxCtx->callback = Environment_GraphCallback;
|
||
play->state.gfxCtx->callbackParam = 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->skybox1Index = 99;
|
||
envCtx->skybox2Index = 99;
|
||
|
||
envCtx->changeSkyboxState = CHANGE_SKYBOX_INACTIVE;
|
||
envCtx->changeSkyboxTimer = 0;
|
||
envCtx->changeLightEnabled = false;
|
||
envCtx->changeLightTimer = 0;
|
||
|
||
envCtx->skyboxDmaState = SKYBOX_DMA_INACTIVE;
|
||
envCtx->lightConfig = 0;
|
||
envCtx->changeLightNextConfig = 0;
|
||
|
||
envCtx->glareAlpha = 0.0f;
|
||
envCtx->lensFlareAlphaScale = 0.0f;
|
||
|
||
envCtx->lightSetting = 0;
|
||
envCtx->prevLightSetting = 0;
|
||
envCtx->lightBlend = 1.0f;
|
||
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 = false;
|
||
|
||
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;
|
||
|
||
gLightningStrike.state = LIGHTNING_STRIKE_WAIT;
|
||
gLightningStrike.flashRed = 0;
|
||
gLightningStrike.flashGreen = 0;
|
||
gLightningStrike.flashBlue = 0;
|
||
|
||
sLightningFlashAlpha = 0;
|
||
|
||
gSaveContext.cutsceneTransitionControl = 0;
|
||
|
||
envCtx->adjAmbientColor[0] = envCtx->adjAmbientColor[1] = envCtx->adjAmbientColor[2] = envCtx->adjLight1Color[0] =
|
||
envCtx->adjLight1Color[1] = envCtx->adjLight1Color[2] = envCtx->adjFogColor[0] = envCtx->adjFogColor[1] =
|
||
envCtx->adjFogColor[2] = envCtx->adjFogNear = envCtx->adjZFar = 0;
|
||
|
||
envCtx->sunPos.x = -(Math_SinS(((void)0, gSaveContext.dayTime) - CLOCK_TIME(12, 0)) * 120.0f) * 25.0f;
|
||
envCtx->sunPos.y = +(Math_CosS(((void)0, gSaveContext.dayTime) - CLOCK_TIME(12, 0)) * 120.0f) * 25.0f;
|
||
envCtx->sunPos.z = +(Math_CosS(((void)0, gSaveContext.dayTime) - CLOCK_TIME(12, 0)) * 20.0f) * 25.0f;
|
||
|
||
envCtx->windDirection.x = 80;
|
||
envCtx->windDirection.y = 80;
|
||
envCtx->windDirection.z = 80;
|
||
|
||
envCtx->lightBlendEnabled = false;
|
||
envCtx->lightSettingOverride = LIGHT_SETTING_OVERRIDE_NONE;
|
||
envCtx->lightBlendRateOverride = LIGHT_BLENDRATE_OVERRIDE_NONE;
|
||
|
||
R_ENV_TIME_SPEED_OLD = gTimeSpeed = envCtx->sceneTimeSpeed = 0;
|
||
R_ENV_DISABLE_DBG = true;
|
||
|
||
if (CREG(3) != 0) {
|
||
gSaveContext.chamberCutsceneNum = CREG(3) - 1;
|
||
}
|
||
|
||
play->envCtx.precipitation[PRECIP_RAIN_MAX] = 0;
|
||
play->envCtx.precipitation[PRECIP_RAIN_CUR] = 0;
|
||
play->envCtx.precipitation[PRECIP_SNOW_CUR] = 0;
|
||
play->envCtx.precipitation[PRECIP_SNOW_MAX] = 0;
|
||
play->envCtx.precipitation[PRECIP_SOS_MAX] = 0;
|
||
|
||
if (gSaveContext.retainWeatherMode) {
|
||
if (!IS_CUTSCENE_LAYER) {
|
||
switch (gWeatherMode) {
|
||
case WEATHER_MODE_CLOUDY_CONFIG3:
|
||
envCtx->skyboxConfig = 1;
|
||
envCtx->changeSkyboxNextConfig = 1;
|
||
envCtx->lightConfig = 3;
|
||
envCtx->changeLightNextConfig = 3;
|
||
play->envCtx.precipitation[PRECIP_SNOW_MAX] = 0;
|
||
play->envCtx.precipitation[PRECIP_SNOW_CUR] = 0;
|
||
break;
|
||
|
||
case WEATHER_MODE_CLOUDY_CONFIG2:
|
||
case WEATHER_MODE_SNOW:
|
||
case WEATHER_MODE_RAIN:
|
||
envCtx->skyboxConfig = 1;
|
||
envCtx->changeSkyboxNextConfig = 1;
|
||
envCtx->lightConfig = 2;
|
||
envCtx->changeLightNextConfig = 2;
|
||
play->envCtx.precipitation[PRECIP_SNOW_MAX] = 0;
|
||
play->envCtx.precipitation[PRECIP_SNOW_CUR] = 0;
|
||
break;
|
||
|
||
case WEATHER_MODE_HEAVY_RAIN:
|
||
envCtx->skyboxConfig = 1;
|
||
envCtx->changeSkyboxNextConfig = 1;
|
||
envCtx->lightConfig = 4;
|
||
envCtx->changeLightNextConfig = 4;
|
||
play->envCtx.precipitation[PRECIP_SNOW_MAX] = 0;
|
||
play->envCtx.precipitation[PRECIP_SNOW_CUR] = 0;
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
|
||
if (play->skyboxId == SKYBOX_NORMAL_SKY) {
|
||
if (gWeatherMode == WEATHER_MODE_SNOW) {
|
||
play->envCtx.precipitation[PRECIP_SNOW_CUR] = play->envCtx.precipitation[PRECIP_SNOW_MAX] = 64;
|
||
} else if (gWeatherMode == WEATHER_MODE_RAIN) {
|
||
play->envCtx.precipitation[PRECIP_RAIN_MAX] = 20;
|
||
play->envCtx.precipitation[PRECIP_RAIN_CUR] = 20;
|
||
} else if (gWeatherMode == WEATHER_MODE_HEAVY_RAIN) {
|
||
play->envCtx.precipitation[PRECIP_RAIN_MAX] = 30;
|
||
play->envCtx.precipitation[PRECIP_RAIN_CUR] = 30;
|
||
}
|
||
}
|
||
}
|
||
} else {
|
||
gWeatherMode = WEATHER_MODE_CLEAR;
|
||
}
|
||
|
||
gInterruptSongOfStorms = false;
|
||
gLightConfigAfterUnderwater = 0;
|
||
gSkyboxIsChanging = 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_8015FCC8 = 1;
|
||
|
||
for (i = 0; i < ARRAY_COUNT(sLightningBolts); i++) {
|
||
sLightningBolts[i].state = LIGHTNING_BOLT_INACTIVE;
|
||
}
|
||
|
||
play->roomCtx.unk_74[0] = 0;
|
||
play->roomCtx.unk_74[1] = 0;
|
||
|
||
for (i = 0; i < ARRAY_COUNT(play->csCtx.npcActions); i++) {
|
||
play->csCtx.npcActions[i] = 0;
|
||
}
|
||
|
||
if (Object_GetIndex(&play->objectCtx, OBJECT_GAMEPLAY_FIELD_KEEP) < 0 && !play->envCtx.sunMoonDisabled) {
|
||
play->envCtx.sunMoonDisabled = true;
|
||
// "Sun setting other than field keep! So forced release!"
|
||
osSyncPrintf(VT_COL(YELLOW, BLACK) "\n\nフィールド常駐以外、太陽設定!よって強制解除!\n" VT_RST);
|
||
}
|
||
|
||
gCustomLensFlareOn = false;
|
||
Rumble_Reset();
|
||
}
|
||
|
||
u8 Environment_SmoothStepToU8(u8* pvalue, u8 target, u8 scale, u8 step, u8 minStep) {
|
||
s16 stepSize = 0;
|
||
s16 diff = target - *pvalue;
|
||
|
||
if (target != *pvalue) {
|
||
stepSize = diff / scale;
|
||
if ((stepSize >= (s16)minStep) || ((s16)-minStep >= stepSize)) {
|
||
if ((s16)step < stepSize) {
|
||
stepSize = step;
|
||
}
|
||
if ((s16)-step > stepSize) {
|
||
stepSize = -step;
|
||
}
|
||
*pvalue += (u8)stepSize;
|
||
} else {
|
||
if (stepSize < (s16)minStep) {
|
||
stepSize = minStep;
|
||
*pvalue += (u8)stepSize;
|
||
if (target < *pvalue) {
|
||
*pvalue = target;
|
||
}
|
||
}
|
||
if ((s16)-minStep < stepSize) {
|
||
stepSize = -minStep;
|
||
*pvalue += (u8)stepSize;
|
||
if (*pvalue < target) {
|
||
*pvalue = target;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return diff;
|
||
}
|
||
|
||
u8 Environment_SmoothStepToS8(s8* pvalue, s8 target, u8 scale, u8 step, u8 minStep) {
|
||
s16 stepSize = 0;
|
||
s16 diff = target - *pvalue;
|
||
|
||
if (target != *pvalue) {
|
||
stepSize = diff / scale;
|
||
if ((stepSize >= (s16)minStep) || ((s16)-minStep >= stepSize)) {
|
||
if ((s16)step < stepSize) {
|
||
stepSize = step;
|
||
}
|
||
if ((s16)-step > stepSize) {
|
||
stepSize = -step;
|
||
}
|
||
*pvalue += (s8)stepSize;
|
||
} else {
|
||
if (stepSize < (s16)minStep) {
|
||
stepSize = minStep;
|
||
*pvalue += (s8)stepSize;
|
||
if (target < *pvalue) {
|
||
*pvalue = target;
|
||
}
|
||
}
|
||
if ((s16)-minStep < stepSize) {
|
||
stepSize = -minStep;
|
||
*pvalue += (s8)stepSize;
|
||
if (*pvalue < target) {
|
||
*pvalue = target;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return diff;
|
||
}
|
||
|
||
f32 Environment_LerpWeight(u16 max, u16 min, u16 val) {
|
||
f32 diff = max - min;
|
||
f32 ret;
|
||
|
||
if (diff != 0.0f) {
|
||
ret = 1.0f - (max - val) / diff;
|
||
|
||
if (!(ret >= 1.0f)) {
|
||
return ret;
|
||
}
|
||
}
|
||
|
||
return 1.0f;
|
||
}
|
||
|
||
f32 Environment_LerpWeightAccelDecel(u16 endFrame, u16 startFrame, u16 curFrame, u16 accelDuration, u16 decelDuration) {
|
||
f32 endFrameF;
|
||
f32 startFrameF;
|
||
f32 curFrameF;
|
||
f32 accelDurationF;
|
||
f32 decelDurationF;
|
||
f32 totalFrames;
|
||
f32 temp;
|
||
f32 framesElapsed;
|
||
f32 ret;
|
||
|
||
if (curFrame <= startFrame) {
|
||
return 0.0f;
|
||
}
|
||
|
||
if (curFrame >= endFrame) {
|
||
return 1.0f;
|
||
}
|
||
|
||
endFrameF = (s32)endFrame;
|
||
startFrameF = (s32)startFrame;
|
||
curFrameF = (s32)curFrame;
|
||
totalFrames = endFrameF - startFrameF;
|
||
framesElapsed = curFrameF - startFrameF;
|
||
accelDurationF = (s32)accelDuration;
|
||
decelDurationF = (s32)decelDuration;
|
||
|
||
if ((startFrameF >= endFrameF) || (accelDurationF + decelDurationF > totalFrames)) {
|
||
// "The frame relation between end_frame and start_frame is wrong!!!"
|
||
osSyncPrintf(VT_COL(RED, WHITE) "\nend_frameとstart_frameのフレーム関係がおかしい!!!" VT_RST);
|
||
osSyncPrintf(VT_COL(RED, WHITE) "\nby get_parcent_forAccelBrake!!!!!!!!!" VT_RST);
|
||
|
||
return 0.0f;
|
||
}
|
||
|
||
temp = 1.0f / ((totalFrames * 2.0f) - accelDurationF - decelDurationF);
|
||
|
||
if (accelDurationF != 0.0f) {
|
||
if (framesElapsed <= accelDurationF) {
|
||
return temp * framesElapsed * framesElapsed / accelDurationF;
|
||
}
|
||
ret = temp * accelDurationF;
|
||
} else {
|
||
ret = 0.0f;
|
||
}
|
||
|
||
if (framesElapsed <= totalFrames - decelDurationF) {
|
||
ret += 2.0f * temp * (framesElapsed - accelDurationF);
|
||
return ret;
|
||
}
|
||
|
||
ret += 2.0f * temp * (totalFrames - accelDurationF - decelDurationF);
|
||
|
||
if (decelDurationF != 0.0f) {
|
||
ret += temp * decelDurationF;
|
||
if (framesElapsed < totalFrames) {
|
||
ret -= temp * (totalFrames - framesElapsed) * (totalFrames - framesElapsed) / decelDurationF;
|
||
}
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
void Environment_UpdateStorm(EnvironmentContext* envCtx, u8 unused) {
|
||
if (envCtx->stormRequest != STORM_REQUEST_NONE) {
|
||
switch (envCtx->stormState) {
|
||
case STORM_STATE_OFF:
|
||
if ((envCtx->stormRequest == STORM_REQUEST_START) && !gSkyboxIsChanging) {
|
||
envCtx->changeSkyboxState = CHANGE_SKYBOX_REQUESTED;
|
||
envCtx->skyboxConfig = 0;
|
||
envCtx->changeSkyboxNextConfig = 1;
|
||
envCtx->changeSkyboxTimer = 100;
|
||
envCtx->changeLightEnabled = true;
|
||
envCtx->lightConfig = 0;
|
||
envCtx->changeLightNextConfig = 2;
|
||
gLightConfigAfterUnderwater = 2;
|
||
envCtx->changeLightTimer = envCtx->changeDuration = 100;
|
||
envCtx->stormState++;
|
||
}
|
||
break;
|
||
|
||
case STORM_STATE_ON:
|
||
if (!gSkyboxIsChanging && (envCtx->stormRequest == STORM_REQUEST_STOP)) {
|
||
gWeatherMode = WEATHER_MODE_CLEAR;
|
||
envCtx->changeSkyboxState = CHANGE_SKYBOX_REQUESTED;
|
||
envCtx->skyboxConfig = 1;
|
||
envCtx->changeSkyboxNextConfig = 0;
|
||
envCtx->changeSkyboxTimer = 100;
|
||
envCtx->changeLightEnabled = true;
|
||
envCtx->lightConfig = 2;
|
||
envCtx->changeLightNextConfig = 0;
|
||
gLightConfigAfterUnderwater = 0;
|
||
envCtx->changeLightTimer = envCtx->changeDuration = 100;
|
||
envCtx->precipitation[PRECIP_RAIN_MAX] = 0;
|
||
envCtx->stormRequest = STORM_REQUEST_NONE;
|
||
envCtx->stormState = STORM_STATE_OFF;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
void Environment_UpdateSkybox(u8 skyboxId, EnvironmentContext* envCtx, SkyboxContext* skyboxCtx) {
|
||
u32 size;
|
||
u8 i;
|
||
u8 newSkybox1Index = 0xFF;
|
||
u8 newSkybox2Index = 0xFF;
|
||
u8 skyboxBlend = 0;
|
||
|
||
if (skyboxId == SKYBOX_CUTSCENE_MAP) {
|
||
envCtx->skyboxConfig = 3;
|
||
|
||
for (i = 0; i < ARRAY_COUNT(gTimeBasedSkyboxConfigs[envCtx->skyboxConfig]); i++) {
|
||
if (gSaveContext.skyboxTime >= gTimeBasedSkyboxConfigs[envCtx->skyboxConfig][i].startTime &&
|
||
(gSaveContext.skyboxTime < gTimeBasedSkyboxConfigs[envCtx->skyboxConfig][i].endTime ||
|
||
gTimeBasedSkyboxConfigs[envCtx->skyboxConfig][i].endTime == 0xFFFF)) {
|
||
if (gTimeBasedSkyboxConfigs[envCtx->skyboxConfig][i].changeSkybox) {
|
||
envCtx->skyboxBlend =
|
||
Environment_LerpWeight(gTimeBasedSkyboxConfigs[envCtx->skyboxConfig][i].endTime,
|
||
gTimeBasedSkyboxConfigs[envCtx->skyboxConfig][i].startTime,
|
||
((void)0, gSaveContext.skyboxTime)) *
|
||
255;
|
||
} else {
|
||
envCtx->skyboxBlend = 0;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
} else if (skyboxId == SKYBOX_NORMAL_SKY && !envCtx->skyboxDisabled) {
|
||
for (i = 0; i < ARRAY_COUNT(gTimeBasedSkyboxConfigs[envCtx->skyboxConfig]); i++) {
|
||
if (gSaveContext.skyboxTime >= gTimeBasedSkyboxConfigs[envCtx->skyboxConfig][i].startTime &&
|
||
(gSaveContext.skyboxTime < gTimeBasedSkyboxConfigs[envCtx->skyboxConfig][i].endTime ||
|
||
gTimeBasedSkyboxConfigs[envCtx->skyboxConfig][i].endTime == 0xFFFF)) {
|
||
newSkybox1Index = gTimeBasedSkyboxConfigs[envCtx->skyboxConfig][i].skybox1Index;
|
||
newSkybox2Index = gTimeBasedSkyboxConfigs[envCtx->skyboxConfig][i].skybox2Index;
|
||
gSkyboxIsChanging = gTimeBasedSkyboxConfigs[envCtx->skyboxConfig][i].changeSkybox;
|
||
|
||
if (gSkyboxIsChanging) {
|
||
skyboxBlend = Environment_LerpWeight(gTimeBasedSkyboxConfigs[envCtx->skyboxConfig][i].endTime,
|
||
gTimeBasedSkyboxConfigs[envCtx->skyboxConfig][i].startTime,
|
||
((void)0, gSaveContext.skyboxTime)) *
|
||
255;
|
||
} else {
|
||
skyboxBlend = Environment_LerpWeight(gTimeBasedSkyboxConfigs[envCtx->skyboxConfig][i].endTime,
|
||
gTimeBasedSkyboxConfigs[envCtx->skyboxConfig][i].startTime,
|
||
((void)0, gSaveContext.skyboxTime)) *
|
||
255;
|
||
|
||
skyboxBlend = (skyboxBlend < 128) ? 255 : 0;
|
||
|
||
if ((envCtx->changeSkyboxState != CHANGE_SKYBOX_INACTIVE) &&
|
||
(envCtx->changeSkyboxState < CHANGE_SKYBOX_ACTIVE)) {
|
||
envCtx->changeSkyboxState++;
|
||
skyboxBlend = 0;
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
Environment_UpdateStorm(envCtx, skyboxBlend);
|
||
|
||
if (envCtx->changeSkyboxState >= CHANGE_SKYBOX_ACTIVE) {
|
||
newSkybox1Index = gTimeBasedSkyboxConfigs[envCtx->skyboxConfig][i].skybox1Index;
|
||
newSkybox2Index = gTimeBasedSkyboxConfigs[envCtx->changeSkyboxNextConfig][i].skybox2Index;
|
||
|
||
skyboxBlend = ((f32)envCtx->changeDuration - envCtx->changeSkyboxTimer) / (f32)envCtx->changeDuration * 255;
|
||
envCtx->changeSkyboxTimer--;
|
||
|
||
if (envCtx->changeSkyboxTimer <= 0) {
|
||
envCtx->changeSkyboxState = CHANGE_SKYBOX_INACTIVE;
|
||
envCtx->skyboxConfig = envCtx->changeSkyboxNextConfig;
|
||
}
|
||
}
|
||
|
||
if (newSkybox1Index == 0xFF) {
|
||
// "Environment VR data acquisition failed! Report to Sasaki!"
|
||
osSyncPrintf(VT_COL(RED, WHITE) "\n環境VRデータ取得失敗! ささきまでご報告を!" VT_RST);
|
||
}
|
||
|
||
if ((envCtx->skybox1Index != newSkybox1Index) && (envCtx->skyboxDmaState == SKYBOX_DMA_INACTIVE)) {
|
||
envCtx->skyboxDmaState = SKYBOX_DMA_TEXTURE1_START;
|
||
size = gNormalSkyFiles[newSkybox1Index].file.vromEnd - gNormalSkyFiles[newSkybox1Index].file.vromStart;
|
||
|
||
osCreateMesgQueue(&envCtx->loadQueue, &envCtx->loadMsg, 1);
|
||
DmaMgr_RequestAsync(&envCtx->dmaRequest, skyboxCtx->staticSegments[0],
|
||
gNormalSkyFiles[newSkybox1Index].file.vromStart, size, 0, &envCtx->loadQueue, NULL,
|
||
"../z_kankyo.c", 1264);
|
||
envCtx->skybox1Index = newSkybox1Index;
|
||
}
|
||
|
||
if ((envCtx->skybox2Index != newSkybox2Index) && (envCtx->skyboxDmaState == SKYBOX_DMA_INACTIVE)) {
|
||
envCtx->skyboxDmaState = SKYBOX_DMA_TEXTURE2_START;
|
||
size = gNormalSkyFiles[newSkybox2Index].file.vromEnd - gNormalSkyFiles[newSkybox2Index].file.vromStart;
|
||
|
||
osCreateMesgQueue(&envCtx->loadQueue, &envCtx->loadMsg, 1);
|
||
DmaMgr_RequestAsync(&envCtx->dmaRequest, skyboxCtx->staticSegments[1],
|
||
gNormalSkyFiles[newSkybox2Index].file.vromStart, size, 0, &envCtx->loadQueue, NULL,
|
||
"../z_kankyo.c", 1281);
|
||
envCtx->skybox2Index = newSkybox2Index;
|
||
}
|
||
|
||
if (envCtx->skyboxDmaState == SKYBOX_DMA_TEXTURE1_DONE) {
|
||
envCtx->skyboxDmaState = SKYBOX_DMA_TLUT1_START;
|
||
|
||
if ((newSkybox1Index & 1) ^ ((newSkybox1Index & 4) >> 2)) {
|
||
size = gNormalSkyFiles[newSkybox1Index].palette.vromEnd -
|
||
gNormalSkyFiles[newSkybox1Index].palette.vromStart;
|
||
|
||
osCreateMesgQueue(&envCtx->loadQueue, &envCtx->loadMsg, 1);
|
||
DmaMgr_RequestAsync(&envCtx->dmaRequest, skyboxCtx->palettes,
|
||
gNormalSkyFiles[newSkybox1Index].palette.vromStart, size, 0, &envCtx->loadQueue,
|
||
NULL, "../z_kankyo.c", 1307);
|
||
} else {
|
||
size = gNormalSkyFiles[newSkybox1Index].palette.vromEnd -
|
||
gNormalSkyFiles[newSkybox1Index].palette.vromStart;
|
||
osCreateMesgQueue(&envCtx->loadQueue, &envCtx->loadMsg, 1);
|
||
DmaMgr_RequestAsync(&envCtx->dmaRequest, (u8*)skyboxCtx->palettes + size,
|
||
gNormalSkyFiles[newSkybox1Index].palette.vromStart, size, 0, &envCtx->loadQueue,
|
||
NULL, "../z_kankyo.c", 1320);
|
||
}
|
||
}
|
||
|
||
if (envCtx->skyboxDmaState == SKYBOX_DMA_TEXTURE2_DONE) {
|
||
envCtx->skyboxDmaState = SKYBOX_DMA_TLUT2_START;
|
||
|
||
if ((newSkybox2Index & 1) ^ ((newSkybox2Index & 4) >> 2)) {
|
||
size = gNormalSkyFiles[newSkybox2Index].palette.vromEnd -
|
||
gNormalSkyFiles[newSkybox2Index].palette.vromStart;
|
||
|
||
osCreateMesgQueue(&envCtx->loadQueue, &envCtx->loadMsg, 1);
|
||
DmaMgr_RequestAsync(&envCtx->dmaRequest, skyboxCtx->palettes,
|
||
gNormalSkyFiles[newSkybox2Index].palette.vromStart, size, 0, &envCtx->loadQueue,
|
||
NULL, "../z_kankyo.c", 1342);
|
||
} else {
|
||
size = gNormalSkyFiles[newSkybox2Index].palette.vromEnd -
|
||
gNormalSkyFiles[newSkybox2Index].palette.vromStart;
|
||
osCreateMesgQueue(&envCtx->loadQueue, &envCtx->loadMsg, 1);
|
||
DmaMgr_RequestAsync(&envCtx->dmaRequest, (u8*)skyboxCtx->palettes + size,
|
||
gNormalSkyFiles[newSkybox2Index].palette.vromStart, size, 0, &envCtx->loadQueue,
|
||
NULL, "../z_kankyo.c", 1355);
|
||
}
|
||
}
|
||
|
||
if ((envCtx->skyboxDmaState == SKYBOX_DMA_TEXTURE1_START) ||
|
||
(envCtx->skyboxDmaState == SKYBOX_DMA_TEXTURE2_START)) {
|
||
if (osRecvMesg(&envCtx->loadQueue, NULL, OS_MESG_NOBLOCK) == 0) {
|
||
envCtx->skyboxDmaState++;
|
||
}
|
||
} else if (envCtx->skyboxDmaState >= SKYBOX_DMA_TEXTURE1_DONE) {
|
||
if (osRecvMesg(&envCtx->loadQueue, NULL, OS_MESG_NOBLOCK) == 0) {
|
||
envCtx->skyboxDmaState = SKYBOX_DMA_INACTIVE;
|
||
}
|
||
}
|
||
|
||
envCtx->skyboxBlend = skyboxBlend;
|
||
}
|
||
}
|
||
|
||
void Environment_EnableUnderwaterLights(PlayState* play, s32 waterLightsIndex) {
|
||
if (waterLightsIndex == WATERBOX_LIGHT_INDEX_NONE) {
|
||
waterLightsIndex = 0;
|
||
// "Underwater color is not set in the water poly data!"
|
||
osSyncPrintf(VT_COL(YELLOW, BLACK) "\n水ポリゴンデータに水中カラーが設定されておりません!" VT_RST);
|
||
}
|
||
|
||
if (play->envCtx.lightMode == LIGHT_MODE_TIME) {
|
||
gLightConfigAfterUnderwater = play->envCtx.changeLightNextConfig;
|
||
|
||
if (play->envCtx.lightConfig != waterLightsIndex) {
|
||
play->envCtx.lightConfig = waterLightsIndex;
|
||
play->envCtx.changeLightNextConfig = waterLightsIndex;
|
||
}
|
||
} else {
|
||
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) {
|
||
play->envCtx.lightConfig = gLightConfigAfterUnderwater;
|
||
play->envCtx.changeLightNextConfig = gLightConfigAfterUnderwater;
|
||
} else {
|
||
play->envCtx.lightBlendEnabled = false; // instantly switch to previous lights
|
||
play->envCtx.lightSettingOverride = LIGHT_SETTING_OVERRIDE_NONE;
|
||
play->envCtx.lightBlend = 1.0f;
|
||
}
|
||
}
|
||
|
||
void Environment_PrintDebugInfo(PlayState* play, Gfx** gfx) {
|
||
GfxPrint printer;
|
||
s32 pad[2];
|
||
|
||
GfxPrint_Init(&printer);
|
||
GfxPrint_Open(&printer, *gfx);
|
||
|
||
GfxPrint_SetPos(&printer, 22, 7);
|
||
GfxPrint_SetColor(&printer, 155, 155, 255, 64);
|
||
GfxPrint_Printf(&printer, "T%03d ", ((void)0, gSaveContext.totalDays));
|
||
GfxPrint_Printf(&printer, "E%03d", ((void)0, gSaveContext.bgsDayCount));
|
||
|
||
GfxPrint_SetColor(&printer, 255, 255, 55, 64);
|
||
GfxPrint_SetPos(&printer, 22, 8);
|
||
GfxPrint_Printf(&printer, "%s", "ZELDATIME ");
|
||
|
||
GfxPrint_SetColor(&printer, 255, 255, 255, 64);
|
||
GfxPrint_Printf(&printer, "%02d", (u8)(24 * 60 / (f32)0x10000 * ((void)0, gSaveContext.dayTime) / 60.0f));
|
||
|
||
if ((gSaveContext.dayTime & 0x1F) >= 0x10 || gTimeSpeed >= 6) {
|
||
GfxPrint_Printf(&printer, "%s", ":");
|
||
} else {
|
||
GfxPrint_Printf(&printer, "%s", " ");
|
||
}
|
||
|
||
GfxPrint_Printf(&printer, "%02d", (s16)(24 * 60 / (f32)0x10000 * ((void)0, gSaveContext.dayTime)) % 60);
|
||
|
||
GfxPrint_SetColor(&printer, 255, 255, 55, 64);
|
||
GfxPrint_SetPos(&printer, 22, 9);
|
||
GfxPrint_Printf(&printer, "%s", "VRBOXTIME ");
|
||
|
||
GfxPrint_SetColor(&printer, 255, 255, 255, 64);
|
||
GfxPrint_Printf(&printer, "%02d", (u8)(24 * 60 / (f32)0x10000 * ((void)0, gSaveContext.skyboxTime) / 60.0f));
|
||
|
||
if ((((void)0, gSaveContext.skyboxTime) & 0x1F) >= 0x10 || gTimeSpeed >= 6) {
|
||
GfxPrint_Printf(&printer, "%s", ":");
|
||
} else {
|
||
GfxPrint_Printf(&printer, "%s", " ");
|
||
}
|
||
|
||
GfxPrint_Printf(&printer, "%02d", (s16)(24 * 60 / (f32)0x10000 * ((void)0, gSaveContext.skyboxTime)) % 60);
|
||
|
||
GfxPrint_SetColor(&printer, 55, 255, 255, 64);
|
||
GfxPrint_SetPos(&printer, 22, 6);
|
||
|
||
if (!IS_DAY) {
|
||
GfxPrint_Printf(&printer, "%s", "YORU"); // "night"
|
||
} else {
|
||
GfxPrint_Printf(&printer, "%s", "HIRU"); // "day"
|
||
}
|
||
|
||
*gfx = GfxPrint_Close(&printer);
|
||
GfxPrint_Destroy(&printer);
|
||
}
|
||
|
||
void Environment_PlayTimeBasedSequence(PlayState* play);
|
||
void Environment_UpdateRain(PlayState* play);
|
||
|
||
void Environment_Update(PlayState* play, EnvironmentContext* envCtx, LightContext* lightCtx, PauseContext* pauseCtx,
|
||
MessageContext* msgCtx, GameOverContext* gameOverCtx, GraphicsContext* gfxCtx) {
|
||
f32 timeChangeBlend;
|
||
f32 configChangeBlend = 0.0f;
|
||
u16 i;
|
||
u16 j;
|
||
u16 time;
|
||
EnvLightSettings* lightSettingsList = play->envCtx.lightSettingsList;
|
||
s32 adjustment;
|
||
|
||
if ((((void)0, gSaveContext.gameMode) != GAMEMODE_NORMAL) &&
|
||
(((void)0, gSaveContext.gameMode) != GAMEMODE_END_CREDITS)) {
|
||
Rumble_ClearRequests();
|
||
}
|
||
|
||
if (pauseCtx->state == 0) {
|
||
if ((play->pauseCtx.state == 0) && (play->pauseCtx.debugState == 0)) {
|
||
if (play->skyboxId == SKYBOX_NORMAL_SKY) {
|
||
play->skyboxCtx.rot.y -= 0.001f;
|
||
} else if (play->skyboxId == SKYBOX_CUTSCENE_MAP) {
|
||
play->skyboxCtx.rot.y -= 0.005f;
|
||
}
|
||
}
|
||
|
||
Environment_UpdateRain(play);
|
||
Environment_PlayTimeBasedSequence(play);
|
||
|
||
if (((void)0, gSaveContext.nextDayTime) >= 0xFF00 && ((void)0, gSaveContext.nextDayTime) != NEXT_TIME_NONE) {
|
||
gSaveContext.nextDayTime -= 0x10;
|
||
osSyncPrintf("\nnext_zelda_time=[%x]", ((void)0, gSaveContext.nextDayTime));
|
||
|
||
// 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 0x8001 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.
|
||
|
||
if (((void)0, gSaveContext.nextDayTime) == (NEXT_TIME_DAY_SET - (15 * 0x10))) {
|
||
func_80078884(NA_SE_EV_CHICKEN_CRY_M);
|
||
gSaveContext.nextDayTime = NEXT_TIME_NONE;
|
||
} else if (((void)0, gSaveContext.nextDayTime) == (NEXT_TIME_NIGHT_SET - (15 * 0x10))) {
|
||
func_800788CC(NA_SE_EV_DOG_CRY_EVENING);
|
||
gSaveContext.nextDayTime = NEXT_TIME_NONE;
|
||
}
|
||
}
|
||
|
||
if ((pauseCtx->state == 0) && (gameOverCtx->state == GAMEOVER_INACTIVE)) {
|
||
if (((msgCtx->msgLength == 0) && (msgCtx->msgMode == MSGMODE_NONE)) ||
|
||
(((void)0, gSaveContext.gameMode) == GAMEMODE_END_CREDITS)) {
|
||
if ((envCtx->changeSkyboxTimer == 0) && !FrameAdvance_IsEnabled(play) &&
|
||
(play->transitionMode == TRANS_MODE_OFF || ((void)0, gSaveContext.gameMode) != GAMEMODE_NORMAL)) {
|
||
|
||
if (IS_DAY || gTimeSpeed >= 400) {
|
||
gSaveContext.dayTime += gTimeSpeed;
|
||
} else {
|
||
gSaveContext.dayTime += gTimeSpeed * 2; // time moves twice as fast at night
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//! @bug `gTimeSpeed` is unsigned, it can't be negative
|
||
if (((((void)0, gSaveContext.sceneLayer) >= 5 || gTimeSpeed != 0) &&
|
||
((void)0, gSaveContext.dayTime) > gSaveContext.skyboxTime) ||
|
||
(((void)0, gSaveContext.dayTime) < CLOCK_TIME(1, 0) || gTimeSpeed < 0)) {
|
||
|
||
gSaveContext.skyboxTime = ((void)0, gSaveContext.dayTime);
|
||
}
|
||
|
||
time = gSaveContext.dayTime;
|
||
|
||
if (time > CLOCK_TIME(18, 0) || time < CLOCK_TIME(6, 30)) {
|
||
gSaveContext.nightFlag = 1;
|
||
} else {
|
||
gSaveContext.nightFlag = 0;
|
||
}
|
||
|
||
if (R_ENABLE_ARENA_DBG != 0 || CREG(2) != 0) {
|
||
Gfx* displayList;
|
||
Gfx* prevDisplayList;
|
||
|
||
OPEN_DISPS(play->state.gfxCtx, "../z_kankyo.c", 1682);
|
||
|
||
prevDisplayList = POLY_OPA_DISP;
|
||
displayList = Graph_GfxPlusOne(POLY_OPA_DISP);
|
||
gSPDisplayList(OVERLAY_DISP++, displayList);
|
||
Environment_PrintDebugInfo(play, &displayList);
|
||
gSPEndDisplayList(displayList++);
|
||
Graph_BranchDlist(prevDisplayList, displayList);
|
||
POLY_OPA_DISP = displayList;
|
||
if (1) {}
|
||
CLOSE_DISPS(play->state.gfxCtx, "../z_kankyo.c", 1690);
|
||
}
|
||
|
||
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->prevLightSetting = envCtx->lightSetting;
|
||
envCtx->lightSetting = envCtx->lightSettingOverride;
|
||
envCtx->lightBlend = 0.0f;
|
||
}
|
||
|
||
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++) {
|
||
if ((gSaveContext.skyboxTime >= sTimeBasedLightConfigs[envCtx->lightConfig][i].startTime) &&
|
||
((gSaveContext.skyboxTime < sTimeBasedLightConfigs[envCtx->lightConfig][i].endTime) ||
|
||
sTimeBasedLightConfigs[envCtx->lightConfig][i].endTime == 0xFFFF)) {
|
||
u8 blend8[2];
|
||
s16 blend16[2];
|
||
|
||
timeChangeBlend =
|
||
Environment_LerpWeight(sTimeBasedLightConfigs[envCtx->lightConfig][i].endTime,
|
||
sTimeBasedLightConfigs[envCtx->lightConfig][i].startTime,
|
||
((void)0, gSaveContext.skyboxTime));
|
||
|
||
sSandstormColorIndex = sTimeBasedLightConfigs[envCtx->lightConfig][i].lightSetting & 3;
|
||
sNextSandstormColorIndex = sTimeBasedLightConfigs[envCtx->lightConfig][i].nextLightSetting & 3;
|
||
sSandstormLerpScale = timeChangeBlend;
|
||
|
||
if (envCtx->changeLightEnabled) {
|
||
configChangeBlend =
|
||
((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++) {
|
||
// blend ambient color
|
||
blend8[0] =
|
||
LERP(lightSettingsList[sTimeBasedLightConfigs[envCtx->lightConfig][i].lightSetting]
|
||
.ambientColor[j],
|
||
lightSettingsList[sTimeBasedLightConfigs[envCtx->lightConfig][i].nextLightSetting]
|
||
.ambientColor[j],
|
||
timeChangeBlend);
|
||
blend8[1] = LERP(
|
||
lightSettingsList[sTimeBasedLightConfigs[envCtx->changeLightNextConfig][i].lightSetting]
|
||
.ambientColor[j],
|
||
lightSettingsList[sTimeBasedLightConfigs[envCtx->changeLightNextConfig][i]
|
||
.nextLightSetting]
|
||
.ambientColor[j],
|
||
timeChangeBlend);
|
||
*(envCtx->lightSettings.ambientColor + j) = LERP(blend8[0], blend8[1], configChangeBlend);
|
||
}
|
||
|
||
// set light1 direction for the sun
|
||
envCtx->lightSettings.light1Dir[0] =
|
||
-(Math_SinS(((void)0, gSaveContext.dayTime) - CLOCK_TIME(12, 0)) * 120.0f);
|
||
envCtx->lightSettings.light1Dir[1] =
|
||
Math_CosS(((void)0, gSaveContext.dayTime) - CLOCK_TIME(12, 0)) * 120.0f;
|
||
envCtx->lightSettings.light1Dir[2] =
|
||
Math_CosS(((void)0, gSaveContext.dayTime) - CLOCK_TIME(12, 0)) * 20.0f;
|
||
|
||
// set light2 direction for the moon
|
||
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++) {
|
||
// blend light1Color
|
||
blend8[0] =
|
||
LERP(lightSettingsList[sTimeBasedLightConfigs[envCtx->lightConfig][i].lightSetting]
|
||
.light1Color[j],
|
||
lightSettingsList[sTimeBasedLightConfigs[envCtx->lightConfig][i].nextLightSetting]
|
||
.light1Color[j],
|
||
timeChangeBlend);
|
||
blend8[1] = LERP(
|
||
lightSettingsList[sTimeBasedLightConfigs[envCtx->changeLightNextConfig][i].lightSetting]
|
||
.light1Color[j],
|
||
lightSettingsList[sTimeBasedLightConfigs[envCtx->changeLightNextConfig][i]
|
||
.nextLightSetting]
|
||
.light1Color[j],
|
||
timeChangeBlend);
|
||
*(envCtx->lightSettings.light1Color + j) = LERP(blend8[0], blend8[1], configChangeBlend);
|
||
|
||
// blend light2Color
|
||
blend8[0] =
|
||
LERP(lightSettingsList[sTimeBasedLightConfigs[envCtx->lightConfig][i].lightSetting]
|
||
.light2Color[j],
|
||
lightSettingsList[sTimeBasedLightConfigs[envCtx->lightConfig][i].nextLightSetting]
|
||
.light2Color[j],
|
||
timeChangeBlend);
|
||
blend8[1] = LERP(
|
||
lightSettingsList[sTimeBasedLightConfigs[envCtx->changeLightNextConfig][i].lightSetting]
|
||
.light2Color[j],
|
||
lightSettingsList[sTimeBasedLightConfigs[envCtx->changeLightNextConfig][i]
|
||
.nextLightSetting]
|
||
.light2Color[j],
|
||
timeChangeBlend);
|
||
*(envCtx->lightSettings.light2Color + j) = LERP(blend8[0], blend8[1], configChangeBlend);
|
||
}
|
||
|
||
// blend fogColor
|
||
for (j = 0; j < 3; j++) {
|
||
blend8[0] =
|
||
LERP(lightSettingsList[sTimeBasedLightConfigs[envCtx->lightConfig][i].lightSetting]
|
||
.fogColor[j],
|
||
lightSettingsList[sTimeBasedLightConfigs[envCtx->lightConfig][i].nextLightSetting]
|
||
.fogColor[j],
|
||
timeChangeBlend);
|
||
blend8[1] = LERP(
|
||
lightSettingsList[sTimeBasedLightConfigs[envCtx->changeLightNextConfig][i].lightSetting]
|
||
.fogColor[j],
|
||
lightSettingsList[sTimeBasedLightConfigs[envCtx->changeLightNextConfig][i]
|
||
.nextLightSetting]
|
||
.fogColor[j],
|
||
timeChangeBlend);
|
||
*(envCtx->lightSettings.fogColor + j) = LERP(blend8[0], blend8[1], configChangeBlend);
|
||
}
|
||
|
||
blend16[0] = LERP16(
|
||
ENV_LIGHT_SETTINGS_FOG_NEAR(
|
||
lightSettingsList[sTimeBasedLightConfigs[envCtx->lightConfig][i].lightSetting]
|
||
.blendRateAndFogNear),
|
||
ENV_LIGHT_SETTINGS_FOG_NEAR(
|
||
lightSettingsList[sTimeBasedLightConfigs[envCtx->lightConfig][i].nextLightSetting]
|
||
.blendRateAndFogNear),
|
||
timeChangeBlend);
|
||
blend16[1] = LERP16(
|
||
ENV_LIGHT_SETTINGS_FOG_NEAR(
|
||
lightSettingsList[sTimeBasedLightConfigs[envCtx->changeLightNextConfig][i].lightSetting]
|
||
.blendRateAndFogNear),
|
||
ENV_LIGHT_SETTINGS_FOG_NEAR(
|
||
lightSettingsList[sTimeBasedLightConfigs[envCtx->changeLightNextConfig][i]
|
||
.nextLightSetting]
|
||
.blendRateAndFogNear),
|
||
timeChangeBlend);
|
||
|
||
envCtx->lightSettings.fogNear = LERP16(blend16[0], blend16[1], configChangeBlend);
|
||
|
||
blend16[0] = LERP16(
|
||
lightSettingsList[sTimeBasedLightConfigs[envCtx->lightConfig][i].lightSetting].zFar,
|
||
lightSettingsList[sTimeBasedLightConfigs[envCtx->lightConfig][i].nextLightSetting].zFar,
|
||
timeChangeBlend);
|
||
blend16[1] = LERP16(
|
||
lightSettingsList[sTimeBasedLightConfigs[envCtx->changeLightNextConfig][i].lightSetting]
|
||
.zFar,
|
||
lightSettingsList[sTimeBasedLightConfigs[envCtx->changeLightNextConfig][i].nextLightSetting]
|
||
.zFar,
|
||
timeChangeBlend);
|
||
|
||
envCtx->lightSettings.zFar = LERP16(blend16[0], blend16[1], configChangeBlend);
|
||
|
||
if (sTimeBasedLightConfigs[envCtx->changeLightNextConfig][i].nextLightSetting >=
|
||
envCtx->numLightSettings) {
|
||
// "The color palette setting seems to be wrong!"
|
||
osSyncPrintf(VT_COL(RED, WHITE) "\nカラーパレットの設定がおかしいようです!" VT_RST);
|
||
|
||
// "Palette setting = [] Last palette number = []"
|
||
osSyncPrintf(VT_COL(RED, WHITE) "\n設定パレット=[%d] 最後パレット番号=[%d]\n" VT_RST,
|
||
sTimeBasedLightConfigs[envCtx->changeLightNextConfig][i].nextLightSetting,
|
||
envCtx->numLightSettings - 1);
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
} else {
|
||
if (!envCtx->lightBlendEnabled) {
|
||
for (i = 0; i < 3; i++) {
|
||
envCtx->lightSettings.ambientColor[i] = lightSettingsList[envCtx->lightSetting].ambientColor[i];
|
||
envCtx->lightSettings.light1Dir[i] = lightSettingsList[envCtx->lightSetting].light1Dir[i];
|
||
envCtx->lightSettings.light1Color[i] = lightSettingsList[envCtx->lightSetting].light1Color[i];
|
||
envCtx->lightSettings.light2Dir[i] = lightSettingsList[envCtx->lightSetting].light2Dir[i];
|
||
envCtx->lightSettings.light2Color[i] = lightSettingsList[envCtx->lightSetting].light2Color[i];
|
||
envCtx->lightSettings.fogColor[i] = lightSettingsList[envCtx->lightSetting].fogColor[i];
|
||
}
|
||
|
||
envCtx->lightSettings.fogNear =
|
||
ENV_LIGHT_SETTINGS_FOG_NEAR(lightSettingsList[envCtx->lightSetting].blendRateAndFogNear);
|
||
envCtx->lightSettings.zFar = lightSettingsList[envCtx->lightSetting].zFar;
|
||
envCtx->lightBlend = 1.0f;
|
||
} else {
|
||
u8 blendRate =
|
||
ENV_LIGHT_SETTINGS_BLEND_RATE_U8(lightSettingsList[envCtx->lightSetting].blendRateAndFogNear);
|
||
|
||
if (blendRate == 0) {
|
||
blendRate++;
|
||
}
|
||
|
||
if (envCtx->lightBlendRateOverride != LIGHT_BLENDRATE_OVERRIDE_NONE) {
|
||
blendRate = envCtx->lightBlendRateOverride;
|
||
}
|
||
|
||
if (envCtx->lightBlendOverride == LIGHT_BLEND_OVERRIDE_NONE) {
|
||
envCtx->lightBlend += blendRate / 255.0f;
|
||
}
|
||
|
||
if (envCtx->lightBlend > 1.0f) {
|
||
envCtx->lightBlend = 1.0f;
|
||
}
|
||
|
||
for (i = 0; i < 3; i++) {
|
||
envCtx->lightSettings.ambientColor[i] =
|
||
LERP(lightSettingsList[envCtx->prevLightSetting].ambientColor[i],
|
||
lightSettingsList[envCtx->lightSetting].ambientColor[i], envCtx->lightBlend);
|
||
envCtx->lightSettings.light1Dir[i] =
|
||
LERP16(lightSettingsList[envCtx->prevLightSetting].light1Dir[i],
|
||
lightSettingsList[envCtx->lightSetting].light1Dir[i], envCtx->lightBlend);
|
||
envCtx->lightSettings.light1Color[i] =
|
||
LERP(lightSettingsList[envCtx->prevLightSetting].light1Color[i],
|
||
lightSettingsList[envCtx->lightSetting].light1Color[i], envCtx->lightBlend);
|
||
envCtx->lightSettings.light2Dir[i] =
|
||
LERP16(lightSettingsList[envCtx->prevLightSetting].light2Dir[i],
|
||
lightSettingsList[envCtx->lightSetting].light2Dir[i], envCtx->lightBlend);
|
||
envCtx->lightSettings.light2Color[i] =
|
||
LERP(lightSettingsList[envCtx->prevLightSetting].light2Color[i],
|
||
lightSettingsList[envCtx->lightSetting].light2Color[i], envCtx->lightBlend);
|
||
envCtx->lightSettings.fogColor[i] =
|
||
LERP(lightSettingsList[envCtx->prevLightSetting].fogColor[i],
|
||
lightSettingsList[envCtx->lightSetting].fogColor[i], envCtx->lightBlend);
|
||
}
|
||
envCtx->lightSettings.fogNear = LERP16(
|
||
ENV_LIGHT_SETTINGS_FOG_NEAR(lightSettingsList[envCtx->prevLightSetting].blendRateAndFogNear),
|
||
ENV_LIGHT_SETTINGS_FOG_NEAR(lightSettingsList[envCtx->lightSetting].blendRateAndFogNear),
|
||
envCtx->lightBlend);
|
||
envCtx->lightSettings.zFar =
|
||
LERP16(lightSettingsList[envCtx->prevLightSetting].zFar,
|
||
lightSettingsList[envCtx->lightSetting].zFar, envCtx->lightBlend);
|
||
}
|
||
|
||
if (envCtx->lightSetting >= envCtx->numLightSettings) {
|
||
// "The color palette seems to be wrong!"
|
||
osSyncPrintf("\n" VT_FGCOL(RED) "カラーパレットがおかしいようです!");
|
||
|
||
// "Palette setting = [] Last palette number = []"
|
||
osSyncPrintf("\n" VT_FGCOL(YELLOW) "設定パレット=[%d] パレット数=[%d]\n" VT_RST,
|
||
envCtx->lightSetting, envCtx->numLightSettings);
|
||
}
|
||
}
|
||
}
|
||
|
||
envCtx->lightBlendEnabled = true;
|
||
|
||
// Apply lighting adjustments
|
||
for (i = 0; i < 3; i++) {
|
||
if ((s16)(envCtx->lightSettings.ambientColor[i] + envCtx->adjAmbientColor[i]) > 255) {
|
||
lightCtx->ambientColor[i] = 255;
|
||
} else if ((s16)(envCtx->lightSettings.ambientColor[i] + envCtx->adjAmbientColor[i]) < 0) {
|
||
lightCtx->ambientColor[i] = 0;
|
||
} else {
|
||
lightCtx->ambientColor[i] = (s16)(envCtx->lightSettings.ambientColor[i] + envCtx->adjAmbientColor[i]);
|
||
}
|
||
|
||
if ((s16)(envCtx->lightSettings.light1Color[i] + envCtx->adjLight1Color[i]) > 255) {
|
||
envCtx->dirLight1.params.dir.color[i] = 255;
|
||
} else if ((s16)(envCtx->lightSettings.light1Color[i] + envCtx->adjLight1Color[i]) < 0) {
|
||
envCtx->dirLight1.params.dir.color[i] = 0;
|
||
} else {
|
||
envCtx->dirLight1.params.dir.color[i] =
|
||
(s16)(envCtx->lightSettings.light1Color[i] + envCtx->adjLight1Color[i]);
|
||
}
|
||
|
||
if ((s16)(envCtx->lightSettings.light2Color[i] + envCtx->adjLight1Color[i]) > 255) {
|
||
envCtx->dirLight2.params.dir.color[i] = 255;
|
||
} else if ((s16)(envCtx->lightSettings.light2Color[i] + envCtx->adjLight1Color[i]) < 0) {
|
||
envCtx->dirLight2.params.dir.color[i] = 0;
|
||
} else {
|
||
envCtx->dirLight2.params.dir.color[i] =
|
||
(s16)(envCtx->lightSettings.light2Color[i] + envCtx->adjLight1Color[i]);
|
||
}
|
||
|
||
if ((s16)(envCtx->lightSettings.fogColor[i] + envCtx->adjFogColor[i]) > 255) {
|
||
lightCtx->fogColor[i] = 255;
|
||
} else if ((s16)(envCtx->lightSettings.fogColor[i] + envCtx->adjFogColor[i]) < 0) {
|
||
lightCtx->fogColor[i] = 0;
|
||
} else {
|
||
lightCtx->fogColor[i] = (s16)(envCtx->lightSettings.fogColor[i] + envCtx->adjFogColor[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->adjFogNear;
|
||
|
||
if (adjustment <= ENV_FOGNEAR_MAX) {
|
||
lightCtx->fogNear = adjustment;
|
||
} else {
|
||
lightCtx->fogNear = ENV_FOGNEAR_MAX;
|
||
}
|
||
|
||
adjustment = envCtx->lightSettings.zFar + envCtx->adjZFar;
|
||
|
||
if (adjustment <= ENV_ZFAR_MAX) {
|
||
lightCtx->zFar = adjustment;
|
||
} else {
|
||
lightCtx->zFar = ENV_ZFAR_MAX;
|
||
}
|
||
|
||
// When environment debug is enabled, various environment related variables can be configured via the reg editor
|
||
if (R_ENV_DISABLE_DBG) {
|
||
R_ENV_AMBIENT_COLOR(0) = lightCtx->ambientColor[0];
|
||
R_ENV_AMBIENT_COLOR(1) = lightCtx->ambientColor[1];
|
||
R_ENV_AMBIENT_COLOR(2) = lightCtx->ambientColor[2];
|
||
|
||
R_ENV_LIGHT1_COLOR(0) = envCtx->dirLight1.params.dir.color[0];
|
||
R_ENV_LIGHT1_COLOR(1) = envCtx->dirLight1.params.dir.color[1];
|
||
R_ENV_LIGHT1_COLOR(2) = envCtx->dirLight1.params.dir.color[2];
|
||
|
||
R_ENV_LIGHT2_COLOR(0) = envCtx->dirLight2.params.dir.color[0];
|
||
R_ENV_LIGHT2_COLOR(1) = envCtx->dirLight2.params.dir.color[1];
|
||
R_ENV_LIGHT2_COLOR(2) = envCtx->dirLight2.params.dir.color[2];
|
||
|
||
R_ENV_FOG_COLOR(0) = lightCtx->fogColor[0];
|
||
R_ENV_FOG_COLOR(1) = lightCtx->fogColor[1];
|
||
R_ENV_FOG_COLOR(2) = lightCtx->fogColor[2];
|
||
|
||
R_ENV_Z_FAR = lightCtx->zFar;
|
||
R_ENV_FOG_NEAR = lightCtx->fogNear;
|
||
|
||
R_ENV_LIGHT1_DIR(0) = envCtx->dirLight1.params.dir.x;
|
||
R_ENV_LIGHT1_DIR(1) = envCtx->dirLight1.params.dir.y;
|
||
R_ENV_LIGHT1_DIR(2) = envCtx->dirLight1.params.dir.z;
|
||
|
||
R_ENV_LIGHT2_DIR(0) = envCtx->dirLight2.params.dir.x;
|
||
R_ENV_LIGHT2_DIR(1) = envCtx->dirLight2.params.dir.y;
|
||
R_ENV_LIGHT2_DIR(2) = envCtx->dirLight2.params.dir.z;
|
||
|
||
R_ENV_WIND_DIR(0) = envCtx->windDirection.x;
|
||
R_ENV_WIND_DIR(1) = envCtx->windDirection.y;
|
||
R_ENV_WIND_DIR(2) = envCtx->windDirection.z;
|
||
R_ENV_WIND_SPEED = envCtx->windSpeed;
|
||
} else {
|
||
lightCtx->ambientColor[0] = R_ENV_AMBIENT_COLOR(0);
|
||
lightCtx->ambientColor[1] = R_ENV_AMBIENT_COLOR(1);
|
||
lightCtx->ambientColor[2] = R_ENV_AMBIENT_COLOR(2);
|
||
|
||
envCtx->dirLight1.params.dir.color[0] = R_ENV_LIGHT1_COLOR(0);
|
||
envCtx->dirLight1.params.dir.color[1] = R_ENV_LIGHT1_COLOR(1);
|
||
envCtx->dirLight1.params.dir.color[2] = R_ENV_LIGHT1_COLOR(2);
|
||
|
||
envCtx->dirLight2.params.dir.color[0] = R_ENV_LIGHT2_COLOR(0);
|
||
envCtx->dirLight2.params.dir.color[1] = R_ENV_LIGHT2_COLOR(1);
|
||
envCtx->dirLight2.params.dir.color[2] = R_ENV_LIGHT2_COLOR(2);
|
||
lightCtx->fogColor[0] = R_ENV_FOG_COLOR(0);
|
||
lightCtx->fogColor[1] = R_ENV_FOG_COLOR(1);
|
||
lightCtx->fogColor[2] = R_ENV_FOG_COLOR(2);
|
||
lightCtx->fogNear = R_ENV_FOG_NEAR;
|
||
lightCtx->zFar = R_ENV_Z_FAR;
|
||
|
||
if (cREG(14)) {
|
||
R_ENV_LIGHT1_DIR(0) = Math_CosS(cREG(10)) * Math_CosS(cREG(11)) * 120.0f;
|
||
envCtx->dirLight1.params.dir.x = R_ENV_LIGHT1_DIR(0);
|
||
R_ENV_LIGHT1_DIR(1) = Math_SinS(cREG(10)) * Math_CosS(cREG(11)) * 120.0f;
|
||
envCtx->dirLight1.params.dir.y = R_ENV_LIGHT1_DIR(1);
|
||
R_ENV_LIGHT1_DIR(2) = Math_SinS(cREG(11)) * 120.0f;
|
||
envCtx->dirLight1.params.dir.z = R_ENV_LIGHT1_DIR(2);
|
||
|
||
R_ENV_LIGHT2_DIR(0) = Math_CosS(cREG(12)) * Math_CosS(cREG(13)) * 120.0f;
|
||
envCtx->dirLight2.params.dir.x = R_ENV_LIGHT2_DIR(0);
|
||
R_ENV_LIGHT2_DIR(1) = Math_SinS(cREG(12)) * Math_CosS(cREG(13)) * 120.0f;
|
||
envCtx->dirLight2.params.dir.y = R_ENV_LIGHT2_DIR(1);
|
||
R_ENV_LIGHT2_DIR(2) = Math_SinS(cREG(13)) * 120.0f;
|
||
envCtx->dirLight2.params.dir.z = R_ENV_LIGHT2_DIR(2);
|
||
} else {
|
||
envCtx->dirLight1.params.dir.x = R_ENV_LIGHT1_DIR(0);
|
||
envCtx->dirLight1.params.dir.y = R_ENV_LIGHT1_DIR(1);
|
||
envCtx->dirLight1.params.dir.z = R_ENV_LIGHT1_DIR(2);
|
||
|
||
envCtx->dirLight2.params.dir.x = R_ENV_LIGHT2_DIR(0);
|
||
envCtx->dirLight2.params.dir.y = R_ENV_LIGHT2_DIR(1);
|
||
envCtx->dirLight2.params.dir.z = R_ENV_LIGHT2_DIR(2);
|
||
}
|
||
|
||
envCtx->windDirection.x = R_ENV_WIND_DIR(0);
|
||
envCtx->windDirection.y = R_ENV_WIND_DIR(1);
|
||
envCtx->windDirection.z = R_ENV_WIND_DIR(2);
|
||
envCtx->windSpeed = R_ENV_WIND_SPEED;
|
||
}
|
||
|
||
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;
|
||
}
|
||
}
|
||
}
|
||
|
||
void Environment_DrawSunAndMoon(PlayState* play) {
|
||
f32 alpha;
|
||
f32 color;
|
||
f32 y;
|
||
f32 scale;
|
||
f32 temp;
|
||
|
||
OPEN_DISPS(play->state.gfxCtx, "../z_kankyo.c", 2266);
|
||
|
||
if (play->csCtx.state != 0) {
|
||
Math_SmoothStepToF(&play->envCtx.sunPos.x,
|
||
-(Math_SinS(((void)0, gSaveContext.dayTime) - CLOCK_TIME(12, 0)) * 120.0f) * 25.0f, 1.0f,
|
||
0.8f, 0.8f);
|
||
Math_SmoothStepToF(&play->envCtx.sunPos.y,
|
||
(Math_CosS(((void)0, gSaveContext.dayTime) - CLOCK_TIME(12, 0)) * 120.0f) * 25.0f, 1.0f,
|
||
0.8f, 0.8f);
|
||
//! @bug This should be z.
|
||
Math_SmoothStepToF(&play->envCtx.sunPos.y,
|
||
(Math_CosS(((void)0, gSaveContext.dayTime) - CLOCK_TIME(12, 0)) * 20.0f) * 25.0f, 1.0f, 0.8f,
|
||
0.8f);
|
||
} else {
|
||
play->envCtx.sunPos.x = -(Math_SinS(((void)0, gSaveContext.dayTime) - CLOCK_TIME(12, 0)) * 120.0f) * 25.0f;
|
||
play->envCtx.sunPos.y = +(Math_CosS(((void)0, gSaveContext.dayTime) - CLOCK_TIME(12, 0)) * 120.0f) * 25.0f;
|
||
play->envCtx.sunPos.z = +(Math_CosS(((void)0, gSaveContext.dayTime) - CLOCK_TIME(12, 0)) * 20.0f) * 25.0f;
|
||
}
|
||
|
||
if (gSaveContext.entranceIndex != ENTR_HYRULE_FIELD_0 || ((void)0, gSaveContext.sceneLayer) != 5) {
|
||
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);
|
||
|
||
y = play->envCtx.sunPos.y / 25.0f;
|
||
temp = y / 80.0f;
|
||
|
||
alpha = temp * 255.0f;
|
||
if (alpha < 0.0f) {
|
||
alpha = 0.0f;
|
||
}
|
||
if (alpha > 255.0f) {
|
||
alpha = 255.0f;
|
||
}
|
||
|
||
alpha = 255.0f - alpha;
|
||
|
||
color = temp;
|
||
if (color < 0.0f) {
|
||
color = 0.0f;
|
||
}
|
||
|
||
if (color > 1.0f) {
|
||
color = 1.0f;
|
||
}
|
||
|
||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, (u8)(color * 75.0f) + 180, (u8)(color * 155.0f) + 100, 255);
|
||
gDPSetEnvColor(POLY_OPA_DISP++, 255, (u8)(color * 255.0f), (u8)(color * 255.0f), alpha);
|
||
|
||
scale = (color * 2.0f) + 10.0f;
|
||
Matrix_Scale(scale, scale, scale, MTXMODE_APPLY);
|
||
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, "../z_kankyo.c", 2364), G_MTX_LOAD);
|
||
Gfx_SetupDL_54Opa(play->state.gfxCtx);
|
||
gSPDisplayList(POLY_OPA_DISP++, gSunDL);
|
||
|
||
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);
|
||
|
||
color = -y / 120.0f;
|
||
color = CLAMP_MIN(color, 0.0f);
|
||
|
||
scale = -15.0f * color + 25.0f;
|
||
Matrix_Scale(scale, scale, scale, MTXMODE_APPLY);
|
||
|
||
temp = -y / 80.0f;
|
||
temp = CLAMP_MAX(temp, 1.0f);
|
||
|
||
alpha = temp * 255.0f;
|
||
|
||
if (alpha > 0.0f) {
|
||
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, "../z_kankyo.c", 2406), G_MTX_LOAD);
|
||
Gfx_SetupDL_51Opa(play->state.gfxCtx);
|
||
gDPPipeSync(POLY_OPA_DISP++);
|
||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 240, 255, 180, alpha);
|
||
gDPSetEnvColor(POLY_OPA_DISP++, 80, 70, 20, alpha);
|
||
gSPDisplayList(POLY_OPA_DISP++, gMoonDL);
|
||
}
|
||
}
|
||
|
||
CLOSE_DISPS(play->state.gfxCtx, "../z_kankyo.c", 2429);
|
||
}
|
||
|
||
void Environment_DrawSunLensFlare(PlayState* play, EnvironmentContext* envCtx, View* view, GraphicsContext* gfxCtx,
|
||
Vec3f pos, s32 unused) {
|
||
if ((play->envCtx.precipitation[PRECIP_RAIN_CUR] == 0) && (play->envCtx.skyboxConfig == 0)) {
|
||
Environment_DrawLensFlare(play, &play->envCtx, &play->view, play->state.gfxCtx, pos, 2000, 370,
|
||
Math_CosS(((void)0, gSaveContext.dayTime) - CLOCK_TIME(12, 0)) * 120.0f, 400, true);
|
||
}
|
||
}
|
||
|
||
f32 sLensFlareScales[] = { 23.0f, 12.0f, 7.0f, 5.0f, 3.0f, 10.0f, 6.0f, 2.0f, 3.0f, 1.0f };
|
||
|
||
typedef enum {
|
||
/* 0 */ LENS_FLARE_CIRCLE0,
|
||
/* 1 */ LENS_FLARE_CIRCLE1,
|
||
/* 2 */ LENS_FLARE_RING
|
||
} LensFlareType;
|
||
|
||
void Environment_DrawLensFlare(PlayState* play, EnvironmentContext* envCtx, View* view, GraphicsContext* gfxCtx,
|
||
Vec3f pos, s32 unused, s16 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;
|
||
u32 isOffScreen = false;
|
||
f32 alpha;
|
||
f32 adjScale;
|
||
Vec3f screenPos;
|
||
f32 fogInfluence;
|
||
f32 temp;
|
||
f32 glareAlphaScale;
|
||
Color_RGB8 lensFlareColors[] = {
|
||
{ 155, 205, 255 }, // blue
|
||
{ 255, 255, 205 }, // yellow
|
||
{ 255, 255, 205 }, // yellow
|
||
{ 255, 255, 205 }, // yellow
|
||
{ 155, 255, 205 }, // green
|
||
{ 205, 255, 255 }, // light blue
|
||
{ 155, 155, 255 }, // dark blue
|
||
{ 205, 175, 255 }, // purple
|
||
{ 175, 255, 205 }, // light green
|
||
{ 255, 155, 235 }, // pink
|
||
};
|
||
u32 lensFlareAlphas[] = {
|
||
50, 10, 25, 40, 70, 30, 50, 70, 50, 40,
|
||
};
|
||
u32 lensFlareTypes[] = {
|
||
LENS_FLARE_RING, LENS_FLARE_CIRCLE1, LENS_FLARE_CIRCLE1, LENS_FLARE_CIRCLE1, LENS_FLARE_CIRCLE1,
|
||
LENS_FLARE_CIRCLE1, LENS_FLARE_CIRCLE1, LENS_FLARE_CIRCLE1, LENS_FLARE_CIRCLE1, LENS_FLARE_CIRCLE1,
|
||
};
|
||
|
||
OPEN_DISPS(gfxCtx, "../z_kankyo.c", 2516);
|
||
|
||
dist = Math3D_Vec3f_DistXYZ(&pos, &view->eye) / 12.0f;
|
||
|
||
// 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;
|
||
|
||
length = sqrtf(SQ(tempX) + SQ(tempY) + SQ(tempZ));
|
||
|
||
lookDirX = tempX / length;
|
||
lookDirY = tempY / length;
|
||
lookDirZ = tempZ / length;
|
||
|
||
// 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);
|
||
|
||
// compute a unit vector in the direction from halfPos to pos
|
||
tempX2 = pos.x - halfPosX;
|
||
tempY2 = pos.y - halfPosY;
|
||
tempZ2 = pos.z - halfPosZ;
|
||
|
||
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 = (s16)screenPos.x;
|
||
sSunDepthTestY = (s16)screenPos.y - 5.0f;
|
||
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(lensFlareTypes); i++) {
|
||
Matrix_Translate(pos.x, pos.y, pos.z, MTXMODE_NEW);
|
||
|
||
if (isSun) {
|
||
temp = 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.001 * (scale + 630.0f * temp);
|
||
} 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 * lensFlareAlphas[i];
|
||
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;
|
||
|
||
if (1) {}
|
||
|
||
if (!(isOffScreen ^ 0)) {
|
||
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 = func_800947AC(POLY_XLU_DISP++);
|
||
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, lensFlareColors[i].r, lensFlareColors[i].g, lensFlareColors[i].b,
|
||
alpha * envCtx->lensFlareAlphaScale);
|
||
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx, "../z_kankyo.c", 2662),
|
||
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 (lensFlareTypes[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;
|
||
}
|
||
}
|
||
|
||
glareAlphaScale = cosAngle - (1.5f - cosAngle);
|
||
|
||
if (glareStrength != 0) {
|
||
if (glareAlphaScale > 0.0f) {
|
||
POLY_XLU_DISP = Gfx_SetupDL_57(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);
|
||
|
||
if (!(isOffScreen ^ 0)) {
|
||
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);
|
||
}
|
||
|
||
temp = colorIntensity / 120.0f;
|
||
temp = CLAMP_MIN(temp, 0.0f);
|
||
|
||
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, (u8)(temp * 75.0f) + 180, (u8)(temp * 155.0f) + 100,
|
||
(u8)envCtx->glareAlpha);
|
||
gDPFillRectangle(POLY_XLU_DISP++, 0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1);
|
||
} else {
|
||
envCtx->glareAlpha = 0.0f;
|
||
}
|
||
}
|
||
}
|
||
|
||
CLOSE_DISPS(gfxCtx, "../z_kankyo.c", 2750);
|
||
}
|
||
|
||
f32 Environment_RandCentered(void) {
|
||
return Rand_ZeroOne() - 0.5f;
|
||
}
|
||
|
||
void Environment_DrawRain(PlayState* play, View* view, GraphicsContext* gfxCtx) {
|
||
s16 i;
|
||
s32 pad;
|
||
Vec3f vec;
|
||
f32 temp1;
|
||
f32 temp2;
|
||
f32 temp3;
|
||
f32 length;
|
||
f32 rotX;
|
||
f32 rotY;
|
||
f32 x50;
|
||
f32 y50;
|
||
f32 z50;
|
||
f32 x280;
|
||
f32 z280;
|
||
Vec3f unused = { 0.0f, 0.0f, 0.0f };
|
||
Vec3f windDirection = { 0.0f, 0.0f, 0.0f };
|
||
Player* player = GET_PLAYER(play);
|
||
|
||
if (!(play->cameraPtrs[CAM_ID_MAIN]->stateFlags & CAM_STATE_8) &&
|
||
(play->envCtx.precipitation[PRECIP_SNOW_CUR] == 0)) {
|
||
OPEN_DISPS(gfxCtx, "../z_kankyo.c", 2799);
|
||
|
||
vec.x = view->at.x - view->eye.x;
|
||
vec.y = view->at.y - view->eye.y;
|
||
vec.z = view->at.z - view->eye.z;
|
||
|
||
length = sqrtf(SQXYZ(vec));
|
||
|
||
temp1 = vec.x / length;
|
||
temp2 = vec.y / length;
|
||
temp3 = vec.z / length;
|
||
|
||
x50 = view->eye.x + temp1 * 50.0f;
|
||
y50 = view->eye.y + temp2 * 50.0f;
|
||
z50 = view->eye.z + temp3 * 50.0f;
|
||
|
||
x280 = view->eye.x + temp1 * 280.0f;
|
||
z280 = view->eye.z + temp3 * 280.0f;
|
||
|
||
if (play->envCtx.precipitation[PRECIP_RAIN_CUR]) {
|
||
gDPPipeSync(POLY_XLU_DISP++);
|
||
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 150, 255, 255, 30);
|
||
POLY_XLU_DISP = Gfx_SetupDL(POLY_XLU_DISP, SETUPDL_20);
|
||
}
|
||
|
||
// draw rain drops
|
||
for (i = 0; i < play->envCtx.precipitation[PRECIP_RAIN_CUR]; i++) {
|
||
temp2 = Rand_ZeroOne();
|
||
temp1 = Rand_ZeroOne();
|
||
temp3 = Rand_ZeroOne();
|
||
|
||
Matrix_Translate((temp2 - 0.7f) * 100.0f + x50, (temp1 - 0.7f) * 100.0f + y50,
|
||
(temp3 - 0.7f) * 100.0f + z50, MTXMODE_NEW);
|
||
|
||
windDirection.x = play->envCtx.windDirection.x;
|
||
windDirection.y = play->envCtx.windDirection.y;
|
||
windDirection.z = play->envCtx.windDirection.z;
|
||
|
||
vec.x = windDirection.x;
|
||
vec.y = windDirection.y + 500.0f + Rand_ZeroOne() * 200.0f;
|
||
vec.z = windDirection.z;
|
||
length = sqrtf(SQXZ(vec));
|
||
|
||
gSPMatrix(POLY_XLU_DISP++, &D_01000000, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_MODELVIEW);
|
||
rotX = Math_Atan2F(length, -vec.y);
|
||
rotY = Math_Atan2F(vec.z, vec.x);
|
||
Matrix_RotateY(-rotY, MTXMODE_APPLY);
|
||
Matrix_RotateX(M_PI / 2 - rotX, MTXMODE_APPLY);
|
||
Matrix_Scale(0.4f, 1.2f, 0.4f, MTXMODE_APPLY);
|
||
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx, "../z_kankyo.c", 2887),
|
||
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||
gSPDisplayList(POLY_XLU_DISP++, gRaindropDL);
|
||
}
|
||
|
||
// draw droplet rings on the ground
|
||
if (player->actor.world.pos.y < view->eye.y) {
|
||
u8 materialFlag = false;
|
||
|
||
for (i = 0; i < play->envCtx.precipitation[PRECIP_RAIN_CUR]; i++) {
|
||
if (!materialFlag) {
|
||
Gfx_SetupDL_25Xlu(gfxCtx);
|
||
gDPSetEnvColor(POLY_XLU_DISP++, 155, 155, 155, 0);
|
||
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, 120);
|
||
materialFlag++;
|
||
}
|
||
|
||
Matrix_Translate(Environment_RandCentered() * 280.0f + x280, player->actor.world.pos.y + 2.0f,
|
||
Environment_RandCentered() * 280.0f + z280, MTXMODE_NEW);
|
||
|
||
if ((LINK_IS_ADULT && ((player->actor.world.pos.y + 2.0f - view->eye.y) > -48.0f)) ||
|
||
(!LINK_IS_ADULT && ((player->actor.world.pos.y + 2.0f - view->eye.y) > -30.0f))) {
|
||
Matrix_Scale(0.02f, 0.02f, 0.02f, MTXMODE_APPLY);
|
||
} else {
|
||
Matrix_Scale(0.1f, 0.1f, 0.1f, MTXMODE_APPLY);
|
||
}
|
||
|
||
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx, "../z_kankyo.c", 2940),
|
||
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||
gSPDisplayList(POLY_XLU_DISP++, gEffShockwaveDL);
|
||
}
|
||
}
|
||
|
||
CLOSE_DISPS(gfxCtx, "../z_kankyo.c", 2946);
|
||
}
|
||
}
|
||
|
||
void Environment_ChangeLightSetting(PlayState* play, u32 lightSetting) {
|
||
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;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Draw color filters over the skybox. There are two filters.
|
||
* The first uses the global fog color, and an alpha calculated with `fogNear`.
|
||
* This filter draws unconditionally for skybox 29 at full alpha.
|
||
* (note: skybox 29 is unused in the original game)
|
||
* For the rest of the skyboxes it will draw if fogNear is less than 980.
|
||
*
|
||
* The second filter uses a custom color specified in `skyboxFilterColor`
|
||
* and can be enabled with `customSkyboxFilter`.
|
||
*
|
||
* An example usage of a filter is to dim the skybox in cloudy conditions.
|
||
*/
|
||
void Environment_DrawSkyboxFilters(PlayState* play) {
|
||
if (((play->skyboxId != SKYBOX_NONE) && (play->lightCtx.fogNear < 980)) || (play->skyboxId == SKYBOX_UNSET_1D)) {
|
||
f32 alpha;
|
||
|
||
OPEN_DISPS(play->state.gfxCtx, "../z_kankyo.c", 3032);
|
||
|
||
Gfx_SetupDL_57Opa(play->state.gfxCtx);
|
||
|
||
alpha = (1000 - play->lightCtx.fogNear) * 0.02f;
|
||
|
||
if (play->skyboxId == SKYBOX_UNSET_1D) {
|
||
alpha = 1.0f;
|
||
}
|
||
|
||
if (alpha > 1.0f) {
|
||
alpha = 1.0f;
|
||
}
|
||
|
||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, play->lightCtx.fogColor[0], play->lightCtx.fogColor[1],
|
||
play->lightCtx.fogColor[2], 255.0f * alpha);
|
||
gDPFillRectangle(POLY_OPA_DISP++, 0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1);
|
||
|
||
CLOSE_DISPS(play->state.gfxCtx, "../z_kankyo.c", 3043);
|
||
}
|
||
|
||
if (play->envCtx.customSkyboxFilter) {
|
||
OPEN_DISPS(play->state.gfxCtx, "../z_kankyo.c", 3048);
|
||
|
||
Gfx_SetupDL_57Opa(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]);
|
||
gDPFillRectangle(POLY_OPA_DISP++, 0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1);
|
||
|
||
CLOSE_DISPS(play->state.gfxCtx, "../z_kankyo.c", 3056);
|
||
}
|
||
}
|
||
|
||
void Environment_DrawLightningFlash(PlayState* play, u8 red, u8 green, u8 blue, u8 alpha) {
|
||
OPEN_DISPS(play->state.gfxCtx, "../z_kankyo.c", 3069);
|
||
|
||
Gfx_SetupDL_57Opa(play->state.gfxCtx);
|
||
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, red, green, blue, alpha);
|
||
gDPFillRectangle(POLY_OPA_DISP++, 0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1);
|
||
|
||
CLOSE_DISPS(play->state.gfxCtx, "../z_kankyo.c", 3079);
|
||
}
|
||
|
||
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 50 units
|
||
if (Rand_ZeroOne() < 0.1f) {
|
||
gLightningStrike.delayTimer += 50.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);
|
||
sLightningFlashAlpha = 0;
|
||
gLightningStrike.state++;
|
||
}
|
||
break;
|
||
case LIGHTNING_STRIKE_START:
|
||
gLightningStrike.flashRed = 200;
|
||
gLightningStrike.flashGreen = 200;
|
||
gLightningStrike.flashBlue = 255;
|
||
|
||
play->envCtx.adjAmbientColor[0] += 80;
|
||
play->envCtx.adjAmbientColor[1] += 80;
|
||
play->envCtx.adjAmbientColor[2] += 100;
|
||
|
||
sLightningFlashAlpha += 100;
|
||
|
||
if (sLightningFlashAlpha >= gLightningStrike.flashAlphaTarget) {
|
||
Audio_SetNatureAmbienceChannelIO(NATURE_CHANNEL_LIGHTNING, CHANNEL_IO_PORT_0, 0);
|
||
gLightningStrike.state++;
|
||
gLightningStrike.flashAlphaTarget = 0;
|
||
}
|
||
break;
|
||
case LIGHTNING_STRIKE_END:
|
||
if (play->envCtx.adjAmbientColor[0] > 0) {
|
||
play->envCtx.adjAmbientColor[0] -= 10;
|
||
play->envCtx.adjAmbientColor[1] -= 10;
|
||
}
|
||
|
||
if (play->envCtx.adjAmbientColor[2] > 0) {
|
||
play->envCtx.adjAmbientColor[2] -= 10;
|
||
}
|
||
|
||
sLightningFlashAlpha -= 10;
|
||
|
||
if (sLightningFlashAlpha <= gLightningStrike.flashAlphaTarget) {
|
||
play->envCtx.adjAmbientColor[0] = 0;
|
||
play->envCtx.adjAmbientColor[1] = 0;
|
||
play->envCtx.adjAmbientColor[2] = 0;
|
||
|
||
gLightningStrike.state = LIGHTNING_STRIKE_WAIT;
|
||
|
||
if (play->envCtx.lightningState == LIGHTNING_LAST) {
|
||
play->envCtx.lightningState = LIGHTNING_OFF;
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (gLightningStrike.state != LIGHTNING_STRIKE_WAIT) {
|
||
Environment_DrawLightningFlash(play, gLightningStrike.flashRed, gLightningStrike.flashGreen,
|
||
gLightningStrike.flashBlue, sLightningFlashAlpha);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Request the number of lightning bolts specified by `num`
|
||
* Note: only 3 lightning bolts can be active at the same time.
|
||
*/
|
||
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;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Draw any active lightning bolt entries contained in `sLightningBolts`
|
||
*/
|
||
void Environment_DrawLightning(PlayState* play, s32 unused) {
|
||
static void* lightningTextures[] = {
|
||
gEffLightning1Tex, gEffLightning2Tex, gEffLightning3Tex,
|
||
gEffLightning4Tex, gEffLightning5Tex, gEffLightning6Tex,
|
||
gEffLightning7Tex, gEffLightning8Tex, NULL,
|
||
};
|
||
s16 i;
|
||
f32 dx;
|
||
f32 dz;
|
||
f32 x;
|
||
f32 z;
|
||
s32 pad[2];
|
||
Vec3f unused1 = { 0.0f, 0.0f, 0.0f };
|
||
Vec3f unused2 = { 0.0f, 0.0f, 0.0f };
|
||
|
||
OPEN_DISPS(play->state.gfxCtx, "../z_kankyo.c", 3253);
|
||
|
||
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;
|
||
|
||
x = dx / sqrtf(SQ(dx) + SQ(dz));
|
||
z = dz / sqrtf(SQ(dx) + SQ(dz));
|
||
|
||
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;
|
||
|
||
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;
|
||
|
||
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;
|
||
case LIGHTNING_BOLT_WAIT:
|
||
sLightningBolts[i].delayTimer--;
|
||
|
||
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;
|
||
}
|
||
|
||
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_RotateX(DEG_TO_RAD(sLightningBolts[i].pitch), MTXMODE_APPLY);
|
||
Matrix_RotateZ(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, "../z_kankyo.c", 3333),
|
||
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(lightningTextures[sLightningBolts[i].textureIndex]));
|
||
Gfx_SetupDL_61Xlu(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, "../z_kankyo.c", 3353);
|
||
}
|
||
|
||
void Environment_PlaySceneSequence(PlayState* play) {
|
||
play->envCtx.timeSeqState = TIMESEQ_DISABLED;
|
||
|
||
// both lost woods exits on the bridge from kokiri to hyrule field
|
||
if (((void)0, gSaveContext.entranceIndex) == ENTR_LOST_WOODS_8 ||
|
||
((void)0, gSaveContext.entranceIndex) == ENTR_LOST_WOODS_9) {
|
||
Audio_PlayNatureAmbienceSequence(NATURE_ID_KOKIRI_REGION);
|
||
} else if (((void)0, gSaveContext.forcedSeqId) != NA_BGM_GENERAL_SFX) {
|
||
if (!Environment_IsForcedSequenceDisabled()) {
|
||
SEQCMD_PLAY_SEQUENCE(SEQ_PLAYER_BGM_MAIN, 0, 0, ((void)0, gSaveContext.forcedSeqId));
|
||
}
|
||
gSaveContext.forcedSeqId = NA_BGM_GENERAL_SFX;
|
||
} else if (play->sequenceCtx.seqId == NA_BGM_NO_MUSIC) {
|
||
if (play->sequenceCtx.natureAmbienceId == NATURE_ID_NONE) {
|
||
return;
|
||
}
|
||
if (((void)0, gSaveContext.natureAmbienceId) != play->sequenceCtx.natureAmbienceId) {
|
||
Audio_PlayNatureAmbienceSequence(play->sequenceCtx.natureAmbienceId);
|
||
}
|
||
} else if (play->sequenceCtx.natureAmbienceId == NATURE_ID_NONE) {
|
||
// "BGM Configuration"
|
||
osSyncPrintf("\n\n\nBGM設定game_play->sound_info.BGM=[%d] old_bgm=[%d]\n\n", play->sequenceCtx.seqId,
|
||
((void)0, gSaveContext.seqId));
|
||
if (((void)0, gSaveContext.seqId) != play->sequenceCtx.seqId) {
|
||
Audio_PlaySceneSequence(play->sequenceCtx.seqId);
|
||
}
|
||
} else if (((void)0, gSaveContext.dayTime) >= CLOCK_TIME(7, 0) &&
|
||
((void)0, gSaveContext.dayTime) <= CLOCK_TIME(17, 10)) {
|
||
if (((void)0, gSaveContext.seqId) != play->sequenceCtx.seqId) {
|
||
Audio_PlaySceneSequence(play->sequenceCtx.seqId);
|
||
}
|
||
|
||
play->envCtx.timeSeqState = TIMESEQ_FADE_DAY_BGM;
|
||
} else {
|
||
if (((void)0, gSaveContext.natureAmbienceId) != play->sequenceCtx.natureAmbienceId) {
|
||
Audio_PlayNatureAmbienceSequence(play->sequenceCtx.natureAmbienceId);
|
||
}
|
||
|
||
if (((void)0, gSaveContext.dayTime) > CLOCK_TIME(17, 10) &&
|
||
((void)0, gSaveContext.dayTime) <= CLOCK_TIME(19, 0)) {
|
||
play->envCtx.timeSeqState = TIMESEQ_EARLY_NIGHT_CRITTERS;
|
||
} else if (((void)0, gSaveContext.dayTime) > CLOCK_TIME(19, 0) + 1 ||
|
||
((void)0, gSaveContext.dayTime) < CLOCK_TIME(6, 30)) {
|
||
play->envCtx.timeSeqState = TIMESEQ_NIGHT_CRITTERS;
|
||
} else {
|
||
play->envCtx.timeSeqState = TIMESEQ_MORNING_CRITTERS;
|
||
}
|
||
}
|
||
|
||
osSyncPrintf("\n-----------------\n", ((void)0, gSaveContext.forcedSeqId));
|
||
osSyncPrintf("\n 強制BGM=[%d]", ((void)0, gSaveContext.forcedSeqId)); // "Forced BGM"
|
||
osSyncPrintf("\n BGM=[%d]", play->sequenceCtx.seqId);
|
||
osSyncPrintf("\n エンブ=[%d]", play->sequenceCtx.natureAmbienceId);
|
||
osSyncPrintf("\n status=[%d]", play->envCtx.timeSeqState);
|
||
|
||
Audio_SetEnvReverb(play->roomCtx.curRoom.echo);
|
||
}
|
||
|
||
void Environment_PlayTimeBasedSequence(PlayState* play) {
|
||
switch (play->envCtx.timeSeqState) {
|
||
case TIMESEQ_DAY_BGM:
|
||
Audio_SetNatureAmbienceChannelIO(NATURE_CHANNEL_CRITTER_4 << 4 | NATURE_CHANNEL_CRITTER_5,
|
||
CHANNEL_IO_PORT_1, 0);
|
||
|
||
if (play->envCtx.precipitation[PRECIP_RAIN_MAX] == 0 && play->envCtx.precipitation[PRECIP_SOS_MAX] == 0) {
|
||
osSyncPrintf("\n\n\nNa_StartMorinigBgm\n\n");
|
||
Audio_PlayMorningSceneSequence(play->sequenceCtx.seqId);
|
||
}
|
||
|
||
play->envCtx.timeSeqState++;
|
||
break;
|
||
|
||
case TIMESEQ_FADE_DAY_BGM:
|
||
if (gSaveContext.dayTime > CLOCK_TIME(17, 10)) {
|
||
if (play->envCtx.precipitation[PRECIP_RAIN_MAX] == 0 &&
|
||
play->envCtx.precipitation[PRECIP_SOS_MAX] == 0) {
|
||
SEQCMD_STOP_SEQUENCE(SEQ_PLAYER_BGM_MAIN, 240);
|
||
}
|
||
|
||
play->envCtx.timeSeqState++;
|
||
}
|
||
break;
|
||
|
||
case TIMESEQ_NIGHT_BEGIN_SFX:
|
||
if (gSaveContext.dayTime > CLOCK_TIME(18, 0)) {
|
||
func_800788CC(NA_SE_EV_DOG_CRY_EVENING);
|
||
play->envCtx.timeSeqState++;
|
||
}
|
||
break;
|
||
|
||
case TIMESEQ_EARLY_NIGHT_CRITTERS:
|
||
if (play->envCtx.precipitation[PRECIP_RAIN_MAX] == 0 && play->envCtx.precipitation[PRECIP_SOS_MAX] == 0) {
|
||
Audio_PlayNatureAmbienceSequence(play->sequenceCtx.natureAmbienceId);
|
||
Audio_SetNatureAmbienceChannelIO(NATURE_CHANNEL_CRITTER_0, CHANNEL_IO_PORT_1, 1);
|
||
}
|
||
|
||
play->envCtx.timeSeqState++;
|
||
break;
|
||
|
||
case TIMESEQ_NIGHT_DELAY:
|
||
if (gSaveContext.dayTime > CLOCK_TIME(19, 0)) {
|
||
play->envCtx.timeSeqState++;
|
||
}
|
||
break;
|
||
|
||
case TIMESEQ_NIGHT_CRITTERS:
|
||
Audio_SetNatureAmbienceChannelIO(NATURE_CHANNEL_CRITTER_0, CHANNEL_IO_PORT_1, 0);
|
||
|
||
if (play->envCtx.precipitation[PRECIP_RAIN_MAX] == 0 && play->envCtx.precipitation[PRECIP_SOS_MAX] == 0) {
|
||
Audio_SetNatureAmbienceChannelIO(NATURE_CHANNEL_CRITTER_1 << 4 | NATURE_CHANNEL_CRITTER_3,
|
||
CHANNEL_IO_PORT_1, 1);
|
||
}
|
||
|
||
play->envCtx.timeSeqState++;
|
||
break;
|
||
|
||
case TIMESEQ_DAY_BEGIN_SFX:
|
||
if ((gSaveContext.dayTime <= CLOCK_TIME(19, 0)) && (gSaveContext.dayTime > CLOCK_TIME(6, 30))) {
|
||
gSaveContext.totalDays++;
|
||
gSaveContext.bgsDayCount++;
|
||
gSaveContext.dogIsLost = true;
|
||
func_80078884(NA_SE_EV_CHICKEN_CRY_M);
|
||
|
||
if ((Inventory_ReplaceItem(play, ITEM_WEIRD_EGG, ITEM_CHICKEN) ||
|
||
Inventory_ReplaceItem(play, ITEM_POCKET_EGG, ITEM_POCKET_CUCCO)) &&
|
||
play->csCtx.state == 0 && !Player_InCsMode(play)) {
|
||
Message_StartTextbox(play, 0x3066, NULL);
|
||
}
|
||
|
||
play->envCtx.timeSeqState++;
|
||
}
|
||
break;
|
||
|
||
case TIMESEQ_MORNING_CRITTERS:
|
||
Audio_SetNatureAmbienceChannelIO(NATURE_CHANNEL_CRITTER_1 << 4 | NATURE_CHANNEL_CRITTER_3,
|
||
CHANNEL_IO_PORT_1, 0);
|
||
|
||
if (play->envCtx.precipitation[PRECIP_RAIN_MAX] == 0 && play->envCtx.precipitation[PRECIP_SOS_MAX] == 0) {
|
||
Audio_SetNatureAmbienceChannelIO(NATURE_CHANNEL_CRITTER_4 << 4 | NATURE_CHANNEL_CRITTER_5,
|
||
CHANNEL_IO_PORT_1, 1);
|
||
}
|
||
|
||
play->envCtx.timeSeqState++;
|
||
break;
|
||
|
||
case TIMESEQ_DAY_DELAY:
|
||
if (gSaveContext.dayTime > CLOCK_TIME(7, 0)) {
|
||
play->envCtx.timeSeqState = 0;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
void Environment_DrawCustomLensFlare(PlayState* play) {
|
||
Vec3f pos;
|
||
|
||
if (gCustomLensFlareOn) {
|
||
pos.x = gCustomLensFlarePos.x;
|
||
pos.y = gCustomLensFlarePos.y;
|
||
pos.z = gCustomLensFlarePos.z;
|
||
|
||
Environment_DrawLensFlare(play, &play->envCtx, &play->view, play->state.gfxCtx, pos, gLensFlareUnused,
|
||
gLensFlareScale, gLensFlareColorIntensity, gLensFlareGlareStrength, false);
|
||
}
|
||
}
|
||
|
||
void Environment_InitGameOverLights(PlayState* play) {
|
||
s32 pad;
|
||
Player* player = GET_PLAYER(play);
|
||
|
||
sGameOverLightsIntensity = 0;
|
||
|
||
Lights_PointNoGlowSetInfo(&sNGameOverLightInfo, (s16)player->actor.world.pos.x - 10.0f,
|
||
(s16)player->actor.world.pos.y + 10.0f, (s16)player->actor.world.pos.z - 10.0f, 0, 0, 0,
|
||
255);
|
||
sNGameOverLightNode = LightContext_InsertLight(play, &play->lightCtx, &sNGameOverLightInfo);
|
||
|
||
Lights_PointNoGlowSetInfo(&sSGameOverLightInfo, (s16)player->actor.world.pos.x + 10.0f,
|
||
(s16)player->actor.world.pos.y + 10.0f, (s16)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, (s16)player->actor.world.pos.x - 10.0f,
|
||
(s16)player->actor.world.pos.y + 10.0f, (s16)player->actor.world.pos.z - 10.0f,
|
||
sGameOverLightsIntensity, sGameOverLightsIntensity, sGameOverLightsIntensity, 255);
|
||
Lights_PointNoGlowSetInfo(&sSGameOverLightInfo, (s16)player->actor.world.pos.x + 10.0f,
|
||
(s16)player->actor.world.pos.y + 10.0f, (s16)player->actor.world.pos.z + 10.0f,
|
||
sGameOverLightsIntensity, sGameOverLightsIntensity, sGameOverLightsIntensity, 255);
|
||
|
||
if (sGameOverLightsIntensity < 254) {
|
||
sGameOverLightsIntensity += 2;
|
||
}
|
||
|
||
if (Play_CamIsNotFixed(play)) {
|
||
for (i = 0; i < 3; i++) {
|
||
if (play->envCtx.adjAmbientColor[i] > -255) {
|
||
play->envCtx.adjAmbientColor[i] -= 12;
|
||
play->envCtx.adjLight1Color[i] -= 12;
|
||
}
|
||
play->envCtx.adjFogColor[i] = -255;
|
||
}
|
||
|
||
if (play->envCtx.lightSettings.zFar + play->envCtx.adjZFar > 900) {
|
||
play->envCtx.adjZFar -= 100;
|
||
}
|
||
|
||
if (play->envCtx.lightSettings.fogNear + play->envCtx.adjFogNear > 950) {
|
||
play->envCtx.adjFogNear -= 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);
|
||
s16 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, (s16)player->actor.world.pos.x - 10.0f,
|
||
(s16)player->actor.world.pos.y + 10.0f, (s16)player->actor.world.pos.z - 10.0f,
|
||
sGameOverLightsIntensity, sGameOverLightsIntensity, sGameOverLightsIntensity, 255);
|
||
Lights_PointNoGlowSetInfo(&sSGameOverLightInfo, (s16)player->actor.world.pos.x + 10.0f,
|
||
(s16)player->actor.world.pos.y + 10.0f, (s16)player->actor.world.pos.z + 10.0f,
|
||
sGameOverLightsIntensity, sGameOverLightsIntensity, sGameOverLightsIntensity, 255);
|
||
}
|
||
|
||
if (Play_CamIsNotFixed(play)) {
|
||
for (i = 0; i < 3; i++) {
|
||
Math_SmoothStepToS(&play->envCtx.adjAmbientColor[i], 0, 5, 12, 1);
|
||
Math_SmoothStepToS(&play->envCtx.adjLight1Color[i], 0, 5, 12, 1);
|
||
play->envCtx.adjFogColor[i] = 0;
|
||
}
|
||
play->envCtx.adjZFar = 0;
|
||
play->envCtx.adjFogNear = 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, "../z_kankyo.c", 3835);
|
||
|
||
if (drawFlags & FILL_SCREEN_OPA) {
|
||
POLY_OPA_DISP = Gfx_SetupDL_57(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);
|
||
gDPFillRectangle(POLY_OPA_DISP++, 0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1);
|
||
}
|
||
|
||
if (drawFlags & FILL_SCREEN_XLU) {
|
||
POLY_XLU_DISP = Gfx_SetupDL_57(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);
|
||
gDPFillRectangle(POLY_XLU_DISP++, 0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1);
|
||
}
|
||
|
||
CLOSE_DISPS(gfxCtx, "../z_kankyo.c", 3863);
|
||
}
|
||
}
|
||
|
||
Color_RGB8 sSandstormPrimColors[] = {
|
||
{ 210, 156, 85 },
|
||
{ 255, 200, 100 },
|
||
{ 225, 160, 50 },
|
||
{ 105, 90, 40 },
|
||
};
|
||
|
||
Color_RGB8 sSandstormEnvColors[] = {
|
||
{ 155, 106, 35 },
|
||
{ 200, 150, 50 },
|
||
{ 170, 110, 0 },
|
||
{ 50, 40, 0 },
|
||
};
|
||
|
||
void Environment_DrawSandstorm(PlayState* play, u8 sandstormState) {
|
||
s32 primA1;
|
||
s32 envA1;
|
||
s32 primA = play->envCtx.sandstormPrimA;
|
||
s32 envA = play->envCtx.sandstormEnvA;
|
||
Color_RGBA8 primColor;
|
||
Color_RGBA8 envColor;
|
||
s32 pad;
|
||
f32 sp98;
|
||
u16 sp96;
|
||
u16 sp94;
|
||
u16 sp92;
|
||
|
||
switch (sandstormState) {
|
||
case SANDSTORM_ACTIVE:
|
||
if ((play->sceneId == SCENE_HAUNTED_WASTELAND) && (play->roomCtx.curRoom.num == 0)) {
|
||
envA1 = 0;
|
||
primA1 = (play->envCtx.sandstormEnvA > 128) ? 255 : play->envCtx.sandstormEnvA >> 1;
|
||
} else {
|
||
primA1 = play->state.frames % 128;
|
||
if (primA1 > 64) {
|
||
primA1 = 128 - primA1;
|
||
}
|
||
primA1 += 73;
|
||
envA1 = 128;
|
||
}
|
||
break;
|
||
|
||
case SANDSTORM_FILL:
|
||
primA1 = 255;
|
||
envA1 = (play->envCtx.sandstormPrimA >= 255) ? 255 : 128;
|
||
break;
|
||
|
||
case SANDSTORM_UNFILL:
|
||
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 = SANDSTORM_ACTIVE;
|
||
}
|
||
break;
|
||
|
||
case SANDSTORM_DISSIPATE:
|
||
envA1 = 0;
|
||
primA1 = (play->envCtx.sandstormEnvA > 128) ? 255 : play->envCtx.sandstormEnvA >> 1;
|
||
|
||
if (primA == 0) {
|
||
play->envCtx.sandstormState = SANDSTORM_OFF;
|
||
}
|
||
break;
|
||
}
|
||
|
||
if (ABS(primA - primA1) < 9) {
|
||
primA = primA1;
|
||
} else if (primA1 < primA) {
|
||
primA = primA - 9;
|
||
} else {
|
||
primA = primA + 9;
|
||
}
|
||
|
||
if (ABS(envA - envA1) < 9) {
|
||
envA = envA1;
|
||
} else if (envA1 < envA) {
|
||
envA = envA - 9;
|
||
} else {
|
||
envA = envA + 9;
|
||
}
|
||
|
||
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.lightMode != LIGHT_MODE_TIME) ||
|
||
(play->envCtx.lightSettingOverride != LIGHT_SETTING_OVERRIDE_NONE)) {
|
||
primColor.r = sSandstormPrimColors[1].r;
|
||
primColor.g = sSandstormPrimColors[1].g;
|
||
primColor.b = sSandstormPrimColors[1].b;
|
||
envColor.r = sSandstormEnvColors[1].r;
|
||
envColor.g = sSandstormEnvColors[1].g;
|
||
envColor.b = sSandstormEnvColors[1].b;
|
||
} else if (sSandstormColorIndex == sNextSandstormColorIndex) {
|
||
primColor.r = sSandstormPrimColors[sSandstormColorIndex].r;
|
||
primColor.g = sSandstormPrimColors[sSandstormColorIndex].g;
|
||
primColor.b = sSandstormPrimColors[sSandstormColorIndex].b;
|
||
envColor.r = sSandstormEnvColors[sSandstormColorIndex].r;
|
||
envColor.g = sSandstormEnvColors[sSandstormColorIndex].g;
|
||
envColor.b = sSandstormEnvColors[sSandstormColorIndex].b;
|
||
} else {
|
||
primColor.r = (s32)F32_LERP(sSandstormPrimColors[sSandstormColorIndex].r,
|
||
sSandstormPrimColors[sNextSandstormColorIndex].r, sSandstormLerpScale);
|
||
primColor.g = (s32)F32_LERP(sSandstormPrimColors[sSandstormColorIndex].g,
|
||
sSandstormPrimColors[sNextSandstormColorIndex].g, sSandstormLerpScale);
|
||
primColor.b = (s32)F32_LERP(sSandstormPrimColors[sSandstormColorIndex].b,
|
||
sSandstormPrimColors[sNextSandstormColorIndex].b, sSandstormLerpScale);
|
||
envColor.r = (s32)F32_LERP(sSandstormEnvColors[sSandstormColorIndex].r,
|
||
sSandstormEnvColors[sNextSandstormColorIndex].r, sSandstormLerpScale);
|
||
envColor.g = (s32)F32_LERP(sSandstormEnvColors[sSandstormColorIndex].g,
|
||
sSandstormEnvColors[sNextSandstormColorIndex].g, sSandstormLerpScale);
|
||
envColor.b = (s32)F32_LERP(sSandstormEnvColors[sSandstormColorIndex].b,
|
||
sSandstormEnvColors[sNextSandstormColorIndex].b, 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 = (s32)(sSandstormScroll * (11.0f / 6.0f));
|
||
sp94 = (s32)(sSandstormScroll * (9.0f / 6.0f));
|
||
sp92 = (s32)(sSandstormScroll * (6.0f / 6.0f));
|
||
|
||
OPEN_DISPS(play->state.gfxCtx, "../z_kankyo.c", 4044);
|
||
|
||
POLY_XLU_DISP = Gfx_SetupDL_64(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, "../z_kankyo.c", 4068);
|
||
|
||
sSandstormScroll += (s32)sp98;
|
||
}
|
||
|
||
void Environment_AdjustLights(PlayState* play, f32 arg1, f32 arg2, f32 arg3, f32 arg4) {
|
||
f32 temp;
|
||
s32 i;
|
||
|
||
if (play->roomCtx.curRoom.behaviorType1 != ROOM_BEHAVIOR_TYPE1_5 && Play_CamIsNotFixed(play)) {
|
||
arg1 = CLAMP_MIN(arg1, 0.0f);
|
||
arg1 = CLAMP_MAX(arg1, 1.0f);
|
||
|
||
temp = arg1 - arg3;
|
||
|
||
if (arg1 < arg3) {
|
||
temp = 0.0f;
|
||
}
|
||
|
||
play->envCtx.adjFogNear = (arg2 - play->envCtx.lightSettings.fogNear) * temp;
|
||
|
||
if (arg1 == 0.0f) {
|
||
for (i = 0; i < 3; i++) {
|
||
play->envCtx.adjFogColor[i] = 0;
|
||
}
|
||
} else {
|
||
temp = arg1 * 5.0f;
|
||
temp = CLAMP_MAX(temp, 1.0f);
|
||
|
||
for (i = 0; i < 3; i++) {
|
||
play->envCtx.adjFogColor[i] = -(s16)(play->envCtx.lightSettings.fogColor[i] * temp);
|
||
}
|
||
}
|
||
|
||
if (arg4 <= 0.0f) {
|
||
return;
|
||
}
|
||
|
||
arg1 *= arg4;
|
||
|
||
for (i = 0; i < 3; i++) {
|
||
play->envCtx.adjAmbientColor[i] = -(s16)(play->envCtx.lightSettings.ambientColor[i] * arg1);
|
||
play->envCtx.adjLight1Color[i] = -(s16)(play->envCtx.lightSettings.light1Color[i] * arg1);
|
||
}
|
||
}
|
||
}
|
||
|
||
s32 Environment_GetBgsDayCount(void) {
|
||
return gSaveContext.bgsDayCount;
|
||
}
|
||
|
||
void Environment_ClearBgsDayCount(void) {
|
||
gSaveContext.bgsDayCount = 0;
|
||
}
|
||
|
||
s32 Environment_GetTotalDays(void) {
|
||
return gSaveContext.totalDays;
|
||
}
|
||
|
||
void Environment_ForcePlaySequence(u16 seqId) {
|
||
gSaveContext.forcedSeqId = seqId;
|
||
}
|
||
|
||
s32 Environment_IsForcedSequenceDisabled(void) {
|
||
s32 isDisabled = false;
|
||
|
||
if (gSaveContext.forcedSeqId == NA_BGM_DISABLED) {
|
||
isDisabled = true;
|
||
}
|
||
|
||
return isDisabled;
|
||
}
|
||
|
||
void Environment_PlayStormNatureAmbience(PlayState* play) {
|
||
if (play->sequenceCtx.natureAmbienceId == NATURE_ID_NONE) {
|
||
Audio_PlayNatureAmbienceSequence(NATURE_ID_MARKET_NIGHT);
|
||
} else {
|
||
Audio_PlayNatureAmbienceSequence(play->sequenceCtx.natureAmbienceId);
|
||
}
|
||
|
||
Audio_SetNatureAmbienceChannelIO(NATURE_CHANNEL_RAIN, CHANNEL_IO_PORT_1, 1);
|
||
Audio_SetNatureAmbienceChannelIO(NATURE_CHANNEL_LIGHTNING, CHANNEL_IO_PORT_1, 1);
|
||
}
|
||
|
||
void Environment_StopStormNatureAmbience(PlayState* play) {
|
||
Audio_SetNatureAmbienceChannelIO(NATURE_CHANNEL_RAIN, CHANNEL_IO_PORT_1, 0);
|
||
Audio_SetNatureAmbienceChannelIO(NATURE_CHANNEL_LIGHTNING, CHANNEL_IO_PORT_1, 0);
|
||
|
||
if (Audio_GetActiveSeqId(SEQ_PLAYER_BGM_MAIN) == NA_BGM_NATURE_AMBIENCE) {
|
||
gSaveContext.seqId = NA_BGM_NATURE_SFX_RAIN;
|
||
Environment_PlaySceneSequence(play);
|
||
}
|
||
}
|
||
|
||
void Environment_WarpSongLeave(PlayState* play) {
|
||
gWeatherMode = WEATHER_MODE_CLEAR;
|
||
gSaveContext.cutsceneIndex = 0;
|
||
gSaveContext.respawnFlag = -3;
|
||
play->nextEntranceIndex = gSaveContext.respawn[RESPAWN_MODE_RETURN].entranceIndex;
|
||
play->transitionTrigger = TRANS_TRIGGER_START;
|
||
play->transitionType = TRANS_TYPE_FADE_WHITE;
|
||
gSaveContext.nextTransitionType = TRANS_TYPE_FADE_WHITE;
|
||
|
||
switch (play->nextEntranceIndex) {
|
||
case ENTR_DEATH_MOUNTAIN_CRATER_0:
|
||
Flags_SetEventChkInf(EVENTCHKINF_B9);
|
||
break;
|
||
|
||
case ENTR_LAKE_HYLIA_0:
|
||
Flags_SetEventChkInf(EVENTCHKINF_B1);
|
||
break;
|
||
|
||
case ENTR_DESERT_COLOSSUS_0:
|
||
Flags_SetEventChkInf(EVENTCHKINF_B8);
|
||
break;
|
||
|
||
case ENTR_GRAVEYARD_0:
|
||
Flags_SetEventChkInf(EVENTCHKINF_B6);
|
||
break;
|
||
|
||
case ENTR_TEMPLE_OF_TIME_0:
|
||
Flags_SetEventChkInf(EVENTCHKINF_A7);
|
||
break;
|
||
|
||
case ENTR_SACRED_FOREST_MEADOW_0:
|
||
break;
|
||
}
|
||
}
|