mirror of
https://gitlab.com/ryandwyer/perfect-dark
synced 2026-06-28 10:10:43 -04:00
474 lines
22 KiB
C
474 lines
22 KiB
C
#include <ultra64.h>
|
|
#include "constants.h"
|
|
#include "game/tex.h"
|
|
#include "game/camera.h"
|
|
#include "game/bg.h"
|
|
#include "game/env.h"
|
|
#include "bss.h"
|
|
#include "lib/vi.h"
|
|
#include "data.h"
|
|
#include "types.h"
|
|
|
|
bool g_FogEnabled;
|
|
bool g_EnvHasTransparency;
|
|
struct distfadesettings *g_EnvDistFadeSettingsPtr;
|
|
struct distfadesettings g_EnvDistFadeSettings;
|
|
u32 var800a65fc;
|
|
|
|
struct shadesettings g_EnvShadeSettings;
|
|
f32 g_EnvFogMaxFrac;
|
|
f32 g_EnvFogMinFrac;
|
|
struct fogenvironment *g_EnvOrigFogEnvironment;
|
|
struct fogenvironment *g_EnvTransitionFrom;
|
|
struct fogenvironment *g_EnvTransitionTo;
|
|
|
|
f32 g_EnvFogMax = MAXFLOAT;
|
|
f32 g_EnvFogMin = 0;
|
|
struct environment g_Env = {900, 1000};
|
|
u32 var800810a8 = 0;
|
|
u32 var800810ac = 0;
|
|
|
|
#define RGB(col) col >> 16, (col >> 8) & 0xff, col & 0xff
|
|
#define NO_SUNS 0, NULL
|
|
#define SUNS(arr) ARRAYCOUNT(arr), arr
|
|
|
|
// lensflare, colour, x, y, z, texture size, orb size
|
|
struct sun suns_00[] = { 1, RGB(0xffffff), -1000000, 200000, 50000, 20, 48 };
|
|
struct sun suns_area51[] = { 0, RGB(0xffe080), -200000, 310000, 1000000, 20, 48 };
|
|
struct sun suns_villa[] = { 1, RGB(0xffffff), -1000000, 200000, 50000, 20, 48 };
|
|
struct sun suns_ci[] = { 1, RGB(0xffffff), 400000, 600000, -1000000, 20, 48 };
|
|
|
|
struct sun suns_skedar[] = {
|
|
{ 1, RGB(0xffffff), -400000, 600000, 1000000, 20, 48 },
|
|
{ 1, RGB(0xffffff), 0, 1000000, 1000000, 25, 60 },
|
|
{ 1, RGB(0xffffff), 400000, 600000, 1000000, 15, 36 },
|
|
};
|
|
|
|
struct sun suns_crashsite[] = { 1, RGB(0xffd7f2), 1900000, 300000, -1400000, 22, 48 };
|
|
struct sun suns_airbase[] = { 1, RGB(0xffd7f2), -1200000, 200000, 150000, 30, 60 };
|
|
|
|
struct fogenvironment g_FogEnvironments[] = {
|
|
// |- distfade --| |- fog -| |-------------- clouds --------------| |--------------- water --------------|
|
|
// stage near far opa% xlu% ref min max sky colour e scale type colour e scale type colour clouds_height
|
|
{ STAGE_CRASHSITE, 15, 10000, 0, 0, 0, 994, 1000, RGB(0x9b2d1e), SUNS(suns_crashsite), 1, 1500, TEX_ENV_00, RGB(0xfafa00), 0, -5000, TEX_ENV_00, RGB(0x000000), 0 },
|
|
{ STAGE_PELAGIC, 15, 15000, 3333, 4444, 600, 995, 1000, RGB(0x2d3e60), NO_SUNS, 1, 5000, TEX_ENV_00, RGB(0xf0f0f0), 0, -2000, TEX_ENV_00, RGB(0x14212b), 0 },
|
|
{ STAGE_VILLA, 15, 20000, 0, 0, 0, 981, 1047, RGB(0x46a0ff), SUNS(suns_villa), 1, 5000, TEX_ENV_00, RGB(0xffffff), 0, -1850, TEX_ENV_01, RGB(0x00ffff), 0 },
|
|
{ STAGE_PELAGIC + 900, 30, 15000, 3333, 4444, 600, 995, 1000, RGB(0x103060), NO_SUNS, 1, 5000, TEX_ENV_00, RGB(0xffffff), 0, -1000, TEX_ENV_00, RGB(0x000000), 0 },
|
|
{ STAGE_24, 2, 25000, 0, 0, 0, 996, 1000, RGB(0x000000), NO_SUNS, 1, 10000, TEX_ENV_00, RGB(0xffffff), 0, 0, TEX_ENV_01, RGB(0x00ffff), 7 },
|
|
{ STAGE_2B, 2, 2000, 2500, 3055, 750, 957, 1000, RGB(0x201010), NO_SUNS, 1, 5000, TEX_ENV_00, RGB(0x3a1100), 0, -1000, TEX_ENV_01, RGB(0x00ffff), 20 },
|
|
{ STAGE_2B + 900, 2, 8000, 6000, 8000, 800, 991, 1000, RGB(0x201010), NO_SUNS, 1, 5000, TEX_ENV_00, RGB(0x3a1100), 0, -1000, TEX_ENV_01, RGB(0x00ffff), 0 },
|
|
{ 238, 10, 6000, 0, 0, 0, 996, 1000, RGB(0x181818), NO_SUNS, 1, 10000, TEX_ENV_00, RGB(0x787878), 0, -500, TEX_ENV_00, RGB(0x000000), 0 },
|
|
{ 338, 10, 6000, 0, 0, 0, 996, 1000, RGB(0x181818), NO_SUNS, 1, 10000, TEX_ENV_00, RGB(0x787878), 0, -500, TEX_ENV_00, RGB(0x000000), 0 },
|
|
{ 438, 10, 6000, 0, 0, 0, 996, 1000, RGB(0x181818), NO_SUNS, 1, 10000, TEX_ENV_00, RGB(0x787878), 0, -500, TEX_ENV_00, RGB(0x000000), 0 },
|
|
{ 200, 10, 7500, 0, 0, 0, 996, 1000, RGB(0x000000), NO_SUNS, 0, 0, TEX_ENV_00, RGB(0x000000), 0, 0, TEX_ENV_00, RGB(0x000000), 0 },
|
|
{ 300, 10, 6000, 0, 0, 0, 996, 1000, RGB(0x000000), NO_SUNS, 0, 0, TEX_ENV_00, RGB(0x000000), 0, 0, TEX_ENV_00, RGB(0x000000), 0 },
|
|
{ 400, 10, 5000, 0, 0, 0, 996, 1000, RGB(0x000000), NO_SUNS, 0, 0, TEX_ENV_00, RGB(0x000000), 0, 0, TEX_ENV_00, RGB(0x000000), 0 },
|
|
{ 0 },
|
|
};
|
|
|
|
struct nofogenvironment g_NoFogEnvironments[] = {
|
|
// clouds_height
|
|
// |distfade | |-------------- clouds --------------| |------------ water ------------| | transparency
|
|
// stage near far opa xlu ref sky colour e colour scale type e colour scale type | |
|
|
{ -1, 15, 10000, 0, 0, 0, RGB(0x001040), NO_SUNS, 0, RGB(0xffffff), 5000, TEX_ENV_00, 0, RGB(0x000000), 0, TEX_ENV_00, 0, 0 },
|
|
{ STAGE_RESCUE, 15, 10000, 0, 0, 0, RGB(0x000000), NO_SUNS, 0, RGB(0xffffff), 5000, TEX_ENV_00, 0, RGB(0x000000), 0, TEX_ENV_00, 0, 1 },
|
|
{ STAGE_MAIANSOS, 15, 10000, 0, 0, 0, RGB(0x000000), NO_SUNS, 0, RGB(0xffffff), 5000, TEX_ENV_00, 0, RGB(0x000000), 0, TEX_ENV_00, 0, 1 },
|
|
{ STAGE_ATTACKSHIP, 15, 10000, 0, 0, 0, RGB(0x000000), NO_SUNS, 0, RGB(0xffffff), 5000, TEX_ENV_00, 0, RGB(0x000000), 0, TEX_ENV_00, 0, 0 },
|
|
{ STAGE_INFILTRATION, 15, 12000, 0, 0, 0, RGB(0x000000), SUNS(suns_area51), 0, RGB(0xffffff), 5000, TEX_ENV_00, 0, RGB(0x000000), 0, TEX_ENV_00, 0, 1 },
|
|
{ STAGE_ESCAPE, 15, 10000, 0, 0, 0, RGB(0x000000), SUNS(suns_area51), 0, RGB(0xffffff), 5000, TEX_ENV_00, 0, RGB(0x000000), 0, TEX_ENV_00, 0, 1 },
|
|
{ STAGE_TEST_ARCH, 15, 10000, 0, 0, 0, RGB(0x000000), NO_SUNS, 0, RGB(0xffffff), 5000, TEX_ENV_00, 0, RGB(0x000000), 0, TEX_ENV_00, 0, 0 },
|
|
{ STAGE_DEEPSEA, 15, 10000, 0, 0, 0, RGB(0x050000), NO_SUNS, 0, RGB(0x9b9b9b), 5000, TEX_ENV_00, 0, RGB(0x000000), 0, TEX_ENV_00, 0, 0 },
|
|
{ STAGE_TEST_DEST, 15, 10000, 0, 0, 0, RGB(0x103060), NO_SUNS, 1, RGB(0xe6e6e6), 3000, TEX_ENV_00, 1, RGB(0xffff96), -150, TEX_ENV_02, 0, 0 },
|
|
{ STAGE_TEST_LEN, 15, 10000, 0, 0, 0, RGB(0x304010), NO_SUNS, 0, RGB(0xffffff), 5000, TEX_ENV_00, 0, RGB(0x000000), 0, TEX_ENV_00, 0, 0 },
|
|
{ STAGE_TEST_ASH, 15, 25000, 0, 0, 0, RGB(0x000000), NO_SUNS, 0, RGB(0xffffff), 5000, TEX_ENV_00, 0, RGB(0x000000), 0, TEX_ENV_00, 0, 1 },
|
|
{ STAGE_DEFENSE, 15, 10000, 0, 0, 0, RGB(0x65b2ff), SUNS(suns_ci), 0, RGB(0xffffff), 5000, TEX_ENV_00, 0, RGB(0x000000), 0, TEX_ENV_00, 0, 1 },
|
|
{ STAGE_CITRAINING, 15, 10000, 0, 0, 0, RGB(0x65b2ff), SUNS(suns_ci), 0, RGB(0xffffff), 5000, TEX_ENV_00, 0, RGB(0x000000), 0, TEX_ENV_00, 0, 1 },
|
|
{ STAGE_DUEL, 10, 10000, 0, 0, 0, RGB(0x65b2ff), SUNS(suns_ci), 0, RGB(0xffffff), 5000, TEX_ENV_00, 0, RGB(0x000000), 0, TEX_ENV_00, 0, 1 },
|
|
{ STAGE_RETAKING, 15, 10000, 0, 0, 0, RGB(0x65b2ff), SUNS(suns_ci), 0, RGB(0xffffff), 5000, TEX_ENV_00, 0, RGB(0x000000), 0, TEX_ENV_00, 0, 1 },
|
|
{ STAGE_DEFECTION, 10, 10000, 0, 0, 0, RGB(0x000000), NO_SUNS, 0, RGB(0x3a1100), 5000, TEX_ENV_00, 0, RGB(0x000000), 0, TEX_ENV_00, 0, 1 },
|
|
{ STAGE_MBR, 10, 10000, 0, 0, 0, RGB(0x000000), NO_SUNS, 0, RGB(0x3a1100), 5000, TEX_ENV_00, 0, RGB(0x000000), 0, TEX_ENV_00, 0, 1 },
|
|
{ STAGE_EXTRACTION, 10, 10000, 0, 0, 0, RGB(0x000000), NO_SUNS, 0, RGB(0x3a1100), 5000, TEX_ENV_00, 0, RGB(0x000000), 0, TEX_ENV_00, 0, 1 },
|
|
{ STAGE_SKEDARRUINS, 15, 10000, 0, 0, 0, RGB(0x6565ff), SUNS(suns_skedar), 0, RGB(0xffffff), 5000, TEX_ENV_00, 0, RGB(0x000000), 0, TEX_ENV_00, 0, 1 },
|
|
{ STAGE_WAR, 15, 10000, 0, 0, 0, RGB(0x6565ff), SUNS(suns_skedar), 0, RGB(0xffffff), 5000, TEX_ENV_00, 0, RGB(0x000000), 0, TEX_ENV_00, 0, 1 },
|
|
{ STAGE_TEST_RUN, 15, 10000, 0, 0, 0, RGB(0x000000), NO_SUNS, 0, RGB(0x3a1100), 5000, TEX_ENV_00, 0, RGB(0x000000), 0, TEX_ENV_00, 0, 1 },
|
|
{ STAGE_MP_SKEDAR, 15, 10000, 0, 0, 0, RGB(0x000000), NO_SUNS, 1, RGB(0x3a1100), 5000, TEX_ENV_00, 0, RGB(0x000000), -5000, TEX_ENV_00, 0, 1 },
|
|
{ STAGE_TEST_SILO, 15, 10000, 0, 0, 0, RGB(0x000000), NO_SUNS, 1, RGB(0x3a1100), 5000, TEX_ENV_00, 0, RGB(0x000000), -5000, TEX_ENV_00, 0, 1 },
|
|
{ STAGE_CHICAGO, 10, 10000, 0, 0, 0, RGB(0x000000), NO_SUNS, 1, RGB(0x50280a), 5000, TEX_ENV_00, 0, RGB(0x000000), -5000, TEX_ENV_00, 0, 1 },
|
|
{ STAGE_G5BUILDING, 15, 10000, 0, 0, 0, RGB(0x000000), NO_SUNS, 0, RGB(0x50280a), 5000, TEX_ENV_00, 0, RGB(0x000000), -5000, TEX_ENV_00, 0, 1 },
|
|
{ STAGE_AIRFORCEONE, 15, 20000, 0, 0, 0, RGB(0x001040), NO_SUNS, 1, RGB(0xffffff), 5000, TEX_ENV_00, 1, RGB(0xffffff), -5000, TEX_ENV_02, 0, 1 },
|
|
{ STAGE_MP_RAVINE, 15, 10000, 0, 0, 0, RGB(0x000000), NO_SUNS, 1, RGB(0x50280a), 5000, TEX_ENV_00, 0, RGB(0x000000), -31000, TEX_ENV_00, 0, 1 },
|
|
{ STAGE_AIRBASE, 15, 20000, 0, 0, 0, RGB(0x001040), SUNS(suns_airbase), 1, RGB(0xffffff), 5000, TEX_ENV_00, 0, RGB(0x000000), -5000, TEX_ENV_00, 0, 1 },
|
|
{ STAGE_INVESTIGATION, 15, 10000, 0, 0, 0, RGB(0x000000), NO_SUNS, 0, RGB(0x1e1e1e), 5000, TEX_ENV_00, 0, RGB(0x000000), -5000, TEX_ENV_00, 0, 1 },
|
|
{ STAGE_MP_PIPES, 15, 10000, 0, 0, 0, RGB(0x000008), NO_SUNS, 1, RGB(0x46c7ba), 4500, TEX_ENV_00, 0, RGB(0x000000), -5000, TEX_ENV_00, 0, 0 },
|
|
{ STAGE_MP_G5BUILDING, 15, 10000, 0, 0, 0, RGB(0x000008), NO_SUNS, 1, RGB(0x5a90a5), 4500, TEX_ENV_00, 0, RGB(0x000000), -20000, TEX_ENV_00, 0, 0 },
|
|
{ STAGE_MP_TEMPLE, 15, 10000, 0, 0, 0, RGB(0x001080), NO_SUNS, 1, RGB(0xffffff), 5000, TEX_ENV_00, 0, RGB(0x00ffff), -1850, TEX_ENV_01, 0, 1 },
|
|
{ STAGE_MP_COMPLEX, 15, 10000, 0, 0, 0, RGB(0x020000), NO_SUNS, 1, RGB(0x82aac8), 5000, TEX_ENV_00, 0, RGB(0x000000), -5000, TEX_ENV_00, 0, 0 },
|
|
{ STAGE_TEST_UFF, 10, 10000, 0, 0, 0, RGB(0x000000), NO_SUNS, 0, RGB(0x1e1e1e), 5000, TEX_ENV_00, 0, RGB(0x000000), -5000, TEX_ENV_00, 0, 0 },
|
|
{ STAGE_TEST_OLD, 15, 30000, 0, 0, 0, RGB(0x000000), NO_SUNS, 0, RGB(0x1e1e1e), 5000, TEX_ENV_00, 0, RGB(0x000000), -5000, TEX_ENV_00, 0, 0 },
|
|
{ STAGE_TEST_LAM, 15, 20000, 0, 0, 0, RGB(0x000000), NO_SUNS, 0, RGB(0x1e1e1e), 5000, TEX_ENV_00, 0, RGB(0x000000), -5000, TEX_ENV_00, 0, 0 },
|
|
{ STAGE_MP_BASE, 15, 20000, 0, 0, 0, RGB(0x040000), NO_SUNS, 1, RGB(0x82b464), 5000, TEX_ENV_00, 0, RGB(0x000000), -5000, TEX_ENV_00, 0, 0 },
|
|
{ STAGE_TEST_MP2, 15, 20000, 0, 0, 0, RGB(0x000008), NO_SUNS, 1, RGB(0x46c7ba), 5000, TEX_ENV_00, 0, RGB(0x000000), -5000, TEX_ENV_00, 0, 0 },
|
|
{ STAGE_MP_AREA52, 15, 10000, 0, 0, 0, RGB(0x000008), NO_SUNS, 1, RGB(0x46c7ba), 4500, TEX_ENV_00, 0, RGB(0x000000), -5000, TEX_ENV_00, 0, 0 },
|
|
{ STAGE_MP_WAREHOUSE, 15, 10000, 0, 0, 0, RGB(0x020000), NO_SUNS, 1, RGB(0x82aac8), 5000, TEX_ENV_00, 0, RGB(0x000000), -5000, TEX_ENV_00, 0, 0 },
|
|
{ STAGE_MP_CARPARK, 15, 10000, 0, 0, 0, RGB(0x000000), NO_SUNS, 1, RGB(0x64c886), 5500, TEX_ENV_00, 0, RGB(0x000000), -5000, TEX_ENV_00, 0, 0 },
|
|
{ STAGE_TEST_MP6, 15, 20000, 0, 0, 0, RGB(0x000000), NO_SUNS, 0, RGB(0x1e1e1e), 5000, TEX_ENV_00, 0, RGB(0x000000), -5000, TEX_ENV_00, 0, 0 },
|
|
{ STAGE_TEST_MP7, 15, 20000, 0, 0, 0, RGB(0x000000), NO_SUNS, 0, RGB(0x1e1e1e), 5000, TEX_ENV_00, 0, RGB(0x000000), -5000, TEX_ENV_00, 0, 0 },
|
|
{ STAGE_TEST_MP8, 15, 20000, 0, 0, 0, RGB(0x000000), NO_SUNS, 0, RGB(0x1e1e1e), 5000, TEX_ENV_00, 0, RGB(0x000000), -5000, TEX_ENV_00, 0, 0 },
|
|
{ STAGE_MP_RUINS, 15, 10000, 0, 0, 0, RGB(0x030000), NO_SUNS, 1, RGB(0x82e6aa), 5000, TEX_ENV_00, 0, RGB(0x000000), -5000, TEX_ENV_00, 0, 0 },
|
|
{ STAGE_MP_SEWERS, 15, 10000, 0, 0, 0, RGB(0x000000), NO_SUNS, 1, RGB(0x646464), 5000, TEX_ENV_00, 0, RGB(0x000000), -5000, TEX_ENV_00, 0, 0 },
|
|
{ STAGE_MP_FELICITY, 10, 10000, 0, 0, 0, RGB(0x040500), NO_SUNS, 1, RGB(0x64d282), 5000, TEX_ENV_00, 0, RGB(0x000000), -5000, TEX_ENV_00, 0, 0 },
|
|
{ STAGE_MP_FORTRESS, 15, 10000, 0, 0, 0, RGB(0x000008), NO_SUNS, 1, RGB(0x5a90a5), 5500, TEX_ENV_00, 0, RGB(0x000000), -5000, TEX_ENV_00, 0, 0 },
|
|
{ STAGE_MP_VILLA, 15, 10000, 0, 0, 0, RGB(0x8888dc), NO_SUNS, 1, RGB(0xffaa2a), 5000, TEX_ENV_00, 0, RGB(0x000000), -5000, TEX_ENV_00, 0, 0 },
|
|
{ STAGE_TEST_MP14, 15, 20000, 0, 0, 0, RGB(0x000000), NO_SUNS, 0, RGB(0x1e1e1e), 5000, TEX_ENV_00, 0, RGB(0x000000), -5000, TEX_ENV_00, 0, 0 },
|
|
{ STAGE_MP_GRID, 15, 10000, 0, 0, 0, RGB(0x000000), NO_SUNS, 0, RGB(0x1e1e1e), 5000, TEX_ENV_00, 0, RGB(0x000000), -5000, TEX_ENV_00, 0, 0 },
|
|
{ STAGE_TEST_MP16, 15, 20000, 0, 0, 0, RGB(0x000000), NO_SUNS, 0, RGB(0x1e1e1e), 5000, TEX_ENV_00, 0, RGB(0x000000), -5000, TEX_ENV_00, 0, 0 },
|
|
{ STAGE_TEST_MP17, 15, 20000, 0, 0, 0, RGB(0x000000), NO_SUNS, 1, RGB(0x64c886), 10000, TEX_ENV_00, 0, RGB(0x000000), -5000, TEX_ENV_00, 0, 0 },
|
|
{ STAGE_TEST_MP18, 15, 20000, 0, 0, 0, RGB(0x000000), NO_SUNS, 0, RGB(0x1e1e1e), 5000, TEX_ENV_00, 0, RGB(0x000000), -5000, TEX_ENV_00, 0, 0 },
|
|
{ STAGE_TEST_MP19, 15, 20000, 0, 0, 0, RGB(0x000000), NO_SUNS, 0, RGB(0x1e1e1e), 5000, TEX_ENV_00, 0, RGB(0x000000), -5000, TEX_ENV_00, 0, 0 },
|
|
{ STAGE_TEST_MP20, 15, 20000, 0, 0, 0, RGB(0x00103c), NO_SUNS, 1, RGB(0xffffff), 5000, TEX_ENV_00, 0, RGB(0x000000), -5000, TEX_ENV_00, 0, 1 },
|
|
{ 0 },
|
|
};
|
|
|
|
void env0f1657c0(s32 arg0, s32 arg1)
|
|
{
|
|
// empty
|
|
}
|
|
|
|
struct environment *env_get_current(void)
|
|
{
|
|
return &g_Env;
|
|
}
|
|
|
|
f32 env_get_fog_max(void)
|
|
{
|
|
return g_EnvFogMax;
|
|
}
|
|
|
|
f32 env_get_squared_fog_max(void)
|
|
{
|
|
return g_EnvFogMax * g_EnvFogMax;
|
|
}
|
|
|
|
void env_tick(void)
|
|
{
|
|
struct zrange zrange;
|
|
f32 scale;
|
|
f32 zfar;
|
|
f32 znear;
|
|
f32 sp28;
|
|
f32 sp24;
|
|
|
|
if (!g_FogEnabled) {
|
|
return;
|
|
}
|
|
|
|
vi_get_z_range(&zrange);
|
|
|
|
scale = bg_get_scale_bg2gfx();
|
|
|
|
zrange.near /= scale;
|
|
zrange.far /= scale;
|
|
|
|
// g_Env.fogmin and fogmax are a percentage of the draw distance, where a
|
|
// value of 1000 is 100%. So this is changing it back to a frac (0-1).
|
|
g_EnvFogMinFrac = g_Env.fogmin * 0.001f;
|
|
g_EnvFogMaxFrac = g_Env.fogmax * 0.001f;
|
|
|
|
g_EnvFogMax = (zrange.far - zrange.near) * g_EnvFogMaxFrac + zrange.f[0];
|
|
g_EnvFogMin = (zrange.far - zrange.near) * g_EnvFogMinFrac + zrange.f[0];
|
|
|
|
g_EnvShadeSettings.znear = zrange.near;
|
|
g_EnvShadeSettings.zfar = zrange.far;
|
|
|
|
zfar = g_EnvShadeSettings.zfar;
|
|
znear = g_EnvShadeSettings.znear;
|
|
sp28 = 128.0f / (g_EnvFogMaxFrac - g_EnvFogMinFrac);
|
|
sp24 = (0.5f - g_EnvFogMinFrac) * 256.0f / (g_EnvFogMaxFrac - g_EnvFogMinFrac);
|
|
|
|
g_EnvShadeSettings.alphafar = -sp28 * zfar * (znear + 1.0f) / (zfar - znear) / 255.0f;
|
|
g_EnvShadeSettings.alphanear = (sp28 * (zfar + 1.0f) / (zfar - znear) + sp24) / 255.0f;
|
|
}
|
|
|
|
void env_apply_fog_environment(struct fogenvironment *env)
|
|
{
|
|
g_FogEnabled = true;
|
|
g_EnvHasTransparency = false;
|
|
|
|
vi_set_z_range(env->near, env->far);
|
|
|
|
g_Env.fogmin = env->fogmin;
|
|
g_Env.fogmax = env->fogmax;
|
|
|
|
g_Env.sky_r = env->sky_r;
|
|
g_Env.sky_g = env->sky_g;
|
|
g_Env.sky_b = env->sky_b;
|
|
g_Env.skyredfrac = g_Env.sky_r / 255.0f;
|
|
g_Env.skygreenfrac = g_Env.sky_g / 255.0f;
|
|
g_Env.skybluefrac = g_Env.sky_b / 255.0f;
|
|
|
|
g_Env.numsuns = env->numsuns;
|
|
g_Env.suns = env->suns;
|
|
|
|
g_Env.clouds_enabled = env->clouds_enabled;
|
|
g_Env.clouds_scale = env->clouds_scale;
|
|
g_Env.clouds_type = env->clouds_type;
|
|
g_Env.clouds_r = env->clouds_r;
|
|
g_Env.clouds_g = env->clouds_g;
|
|
g_Env.clouds_b = env->clouds_b;
|
|
|
|
g_Env.water_enabled = env->water_enabled;
|
|
g_Env.water_scale = env->water_scale;
|
|
g_Env.water_type = env->water_type;
|
|
g_Env.water_r = env->water_r;
|
|
g_Env.water_g = env->water_g;
|
|
g_Env.water_b = env->water_b;
|
|
g_Env.clouds_height = env->clouds_height;
|
|
|
|
if (!env->opaperc) {
|
|
g_EnvDistFadeSettingsPtr = NULL;
|
|
} else {
|
|
g_EnvDistFadeSettings.opaperc = env->opaperc;
|
|
g_EnvDistFadeSettings.xluperc = env->xluperc;
|
|
g_EnvDistFadeSettings.refdist = env->refdist;
|
|
g_EnvDistFadeSettingsPtr = &g_EnvDistFadeSettings;
|
|
}
|
|
|
|
env_tick();
|
|
}
|
|
|
|
void env_apply_no_fog_environment(struct nofogenvironment *env)
|
|
{
|
|
struct zrange zrange;
|
|
|
|
vi_set_z_range(env->near, env->far);
|
|
|
|
g_Env.sky_r = env->sky_r;
|
|
g_Env.sky_g = env->sky_g;
|
|
g_Env.sky_b = env->sky_b;
|
|
|
|
g_Env.skyredfrac = g_Env.sky_r / 255.0f;
|
|
g_Env.skygreenfrac = g_Env.sky_g / 255.0f;
|
|
g_Env.skybluefrac = g_Env.sky_b / 255.0f;
|
|
|
|
g_Env.numsuns = env->numsuns;
|
|
g_Env.suns = env->suns;
|
|
g_Env.clouds_enabled = env->clouds_enabled;
|
|
g_Env.clouds_scale = env->clouds_scale;
|
|
g_Env.clouds_type = env->clouds_type;
|
|
|
|
g_Env.clouds_r = env->clouds_r;
|
|
g_Env.clouds_g = env->clouds_g;
|
|
g_Env.clouds_b = env->clouds_b;
|
|
|
|
g_Env.water_enabled = env->water_enabled;
|
|
g_Env.water_scale = env->water_scale;
|
|
g_Env.water_type = env->water_type;
|
|
|
|
g_Env.water_r = env->water_r;
|
|
g_Env.water_g = env->water_g;
|
|
g_Env.water_b = env->water_b;
|
|
g_Env.clouds_height = env->clouds_height;
|
|
|
|
if (!env->opaperc) {
|
|
g_EnvDistFadeSettingsPtr = NULL;
|
|
} else {
|
|
g_EnvDistFadeSettings.opaperc = env->opaperc;
|
|
g_EnvDistFadeSettings.xluperc = env->xluperc;
|
|
g_EnvDistFadeSettings.refdist = env->refdist;
|
|
g_EnvDistFadeSettingsPtr = &g_EnvDistFadeSettings;
|
|
}
|
|
|
|
g_FogEnabled = false;
|
|
|
|
g_EnvHasTransparency = env->transparency;
|
|
}
|
|
|
|
void env_disable_sky(void)
|
|
{
|
|
g_Env.sky_r = 0;
|
|
g_Env.sky_g = 0;
|
|
g_Env.sky_b = 0;
|
|
|
|
g_Env.skyredfrac = 0;
|
|
g_Env.skygreenfrac = 0;
|
|
g_Env.skybluefrac = 0;
|
|
}
|
|
|
|
void env_set_stage_num(s32 stagenum)
|
|
{
|
|
// empty
|
|
}
|
|
|
|
void env_choose_and_apply(s32 stagenum, bool allowoverride)
|
|
{
|
|
struct nofogenvironment *finalenv = NULL;
|
|
struct nofogenvironment *env2;
|
|
struct fogenvironment *env1;
|
|
|
|
if (PLAYERCOUNT());
|
|
|
|
g_EnvFogMax = MAXFLOAT;
|
|
g_EnvFogMin = 0;
|
|
|
|
// If allowoverride is set, try to find an env1 with stage + 900.
|
|
// But allowoverride is never set, so this never happens.
|
|
if (allowoverride) {
|
|
for (env1 = &g_FogEnvironments[0]; env1->stage != 0; env1++) {
|
|
if (env1->stage == stagenum + 900) {
|
|
g_EnvOrigFogEnvironment = env1;
|
|
g_EnvTransitionFrom = env1;
|
|
g_EnvTransitionTo = env1 + 1;
|
|
env_apply_fog_environment(g_EnvOrigFogEnvironment);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Try to find an env1
|
|
for (env1 = &g_FogEnvironments[0]; env1->stage != 0; env1++) {
|
|
if (env1->stage == stagenum) {
|
|
g_EnvOrigFogEnvironment = env1;
|
|
g_EnvTransitionFrom = env1;
|
|
g_EnvTransitionTo = env1 + 1;
|
|
env_apply_fog_environment(g_EnvOrigFogEnvironment);
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Try to find an env2
|
|
for (env2 = &g_NoFogEnvironments[0]; env2->stage != 0; env2++) {
|
|
if (env2->stage == stagenum) {
|
|
finalenv = env2;
|
|
}
|
|
}
|
|
|
|
if (env2);
|
|
|
|
if (finalenv == NULL) {
|
|
finalenv = &g_NoFogEnvironments[0];
|
|
}
|
|
|
|
env_apply_no_fog_environment(finalenv);
|
|
|
|
g_EnvOrigFogEnvironment = NULL;
|
|
}
|
|
|
|
void env_apply_transition_frac(f32 frac)
|
|
{
|
|
static struct fogenvironment tmp;
|
|
|
|
tmp = *g_EnvTransitionFrom;
|
|
|
|
tmp.near = g_EnvTransitionFrom->near + frac * ((f32)g_EnvTransitionTo->near - (f32)g_EnvTransitionFrom->near);
|
|
tmp.far = g_EnvTransitionFrom->far + frac * ((f32)g_EnvTransitionTo->far - (f32)g_EnvTransitionFrom->far);
|
|
tmp.fogmin = g_EnvTransitionFrom->fogmin + frac * ((f32)g_EnvTransitionTo->fogmin - (f32)g_EnvTransitionFrom->fogmin);
|
|
tmp.fogmax = g_EnvTransitionFrom->fogmax + frac * ((f32)g_EnvTransitionTo->fogmax - (f32)g_EnvTransitionFrom->fogmax);
|
|
|
|
tmp.sky_r = g_EnvTransitionFrom->sky_r + frac * ((f32)g_EnvTransitionTo->sky_r - (f32)g_EnvTransitionFrom->sky_r);
|
|
tmp.sky_g = g_EnvTransitionFrom->sky_g + frac * ((f32)g_EnvTransitionTo->sky_g - (f32)g_EnvTransitionFrom->sky_g);
|
|
tmp.sky_b = g_EnvTransitionFrom->sky_b + frac * ((f32)g_EnvTransitionTo->sky_b - (f32)g_EnvTransitionFrom->sky_b);
|
|
|
|
tmp.sky_r &= 0xf8;
|
|
tmp.sky_g &= 0xf8;
|
|
tmp.sky_b &= 0xf8;
|
|
|
|
env_apply_fog_environment(&tmp);
|
|
}
|
|
|
|
Gfx *env_start_fog(Gfx *gdl, bool xlupass)
|
|
{
|
|
if (!g_FogEnabled) {
|
|
return gdl;
|
|
}
|
|
|
|
if (xlupass) {
|
|
gDPSetFogColor(gdl++, g_Env.sky_r, g_Env.sky_g, g_Env.sky_b, 0xff);
|
|
gSPFogPosition(gdl++, g_Env.fogmin, g_Env.fogmax);
|
|
} else {
|
|
gDPSetFogColor(gdl++, g_Env.sky_r, g_Env.sky_g, g_Env.sky_b, 0xff);
|
|
gSPFogPosition(gdl++, g_Env.fogmin, g_Env.fogmax);
|
|
}
|
|
|
|
gSPSetGeometryMode(gdl++, G_FOG);
|
|
gDPSetAlphaDither(gdl++, G_AD_NOISE);
|
|
|
|
return gdl;
|
|
}
|
|
|
|
Gfx *env_stop_fog(Gfx *gdl)
|
|
{
|
|
if (!g_FogEnabled) {
|
|
return gdl;
|
|
}
|
|
|
|
gSPClearGeometryMode(gdl++, G_FOG);
|
|
|
|
return gdl;
|
|
}
|
|
|
|
bool env_is_pos_in_fog_max_distance(struct coord *pos, f32 tolerance)
|
|
{
|
|
struct coord sp24;
|
|
Mtxf *mtx;
|
|
struct coord *campos;
|
|
f32 tmp;
|
|
|
|
if (!g_FogEnabled) {
|
|
return true;
|
|
}
|
|
|
|
if (g_Vars.currentplayer->visionmode == VISIONMODE_XRAY) {
|
|
return true;
|
|
}
|
|
|
|
campos = &g_Vars.currentplayer->cam_pos;
|
|
mtx = cam_get_world_to_screen_mtxf();
|
|
|
|
sp24.x = pos->x - campos->x;
|
|
sp24.y = pos->y - campos->y;
|
|
sp24.z = pos->z - campos->z;
|
|
|
|
tmp = sp24.f[0] * mtx->m[0][0] + sp24.f[1] * mtx->m[0][1] + sp24.f[2] * mtx->m[0][2];
|
|
|
|
if (tmp > g_EnvFogMax + tolerance) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
struct distfadesettings *env_get_dist_fade_settings(void)
|
|
{
|
|
return g_EnvDistFadeSettingsPtr;
|
|
}
|
|
|
|
s32 env_get_obj_shade_mode(struct prop *prop, f32 out[4])
|
|
{
|
|
if (!g_FogEnabled) {
|
|
return SHADEMODE_OPA;
|
|
}
|
|
|
|
if (prop->z < 0.0f) {
|
|
return SHADEMODE_OPA;
|
|
}
|
|
|
|
if (g_Vars.currentplayer->visionmode == VISIONMODE_XRAY) {
|
|
return SHADEMODE_OPA;
|
|
}
|
|
|
|
out[0] = g_Env.skyredfrac;
|
|
out[1] = g_Env.skygreenfrac;
|
|
out[2] = g_Env.skybluefrac;
|
|
out[3] = g_EnvShadeSettings.alphanear + g_EnvShadeSettings.alphafar / prop->z;
|
|
|
|
if (out[3] < 0.0f) {
|
|
return SHADEMODE_OPA;
|
|
}
|
|
|
|
if (out[3] > 1.0f) {
|
|
return SHADEMODE_XLU;
|
|
}
|
|
|
|
return SHADEMODE_FRAC;
|
|
}
|