1953 lines
41 KiB
C
1953 lines
41 KiB
C
#include <ultra64.h>
|
|
#include "constants.h"
|
|
#include "game/cheats.h"
|
|
#include "game/dlights.h"
|
|
#include "game/gfxmemory.h"
|
|
#include "game/propsnd.h"
|
|
#include "game/tex.h"
|
|
#include "game/camera.h"
|
|
#include "game/player.h"
|
|
#include "game/smoke.h"
|
|
#include "game/sparks.h"
|
|
#include "game/bg.h"
|
|
#include "game/file.h"
|
|
#include "game/lv.h"
|
|
#include "game/game_176080.h"
|
|
#include "game/mplayer/scenarios.h"
|
|
#include "game/portal.h"
|
|
#include "game/propobj.h"
|
|
#include "game/utils.h"
|
|
#include "game/wallhit.h"
|
|
#include "bss.h"
|
|
#include "lib/snd.h"
|
|
#include "lib/memp.h"
|
|
#include "lib/rng.h"
|
|
#include "lib/mtx.h"
|
|
#include "lib/lib_17ce0.h"
|
|
#include "lib/lib_2f490.h"
|
|
#include "lib/lib_317f0.h"
|
|
#include "data.h"
|
|
#include "types.h"
|
|
|
|
|
|
s32 *var8009cad0;
|
|
s32 *var8009cad8;
|
|
s32 g_NumPortals;
|
|
s32 var8009cae0;
|
|
s32 var8009cae4;
|
|
f32 (*var8009cae8)(s32 roomnum, f32 mult, s32 portalnum1, s32 portalnum2);
|
|
u8 var8009caec;
|
|
u8 var8009caed;
|
|
u8 var8009caee;
|
|
u8 var8009caef;
|
|
u8 var8009caf0;
|
|
|
|
struct var80061420 *var80061420 = NULL;
|
|
struct coord *var80061428 = NULL;
|
|
u16 **var8006142c = NULL;
|
|
u16 **var80061430 = NULL;
|
|
f32 *var80061434 = NULL;
|
|
bool *var80061438 = NULL;
|
|
f32 var8006143c = 50;
|
|
u32 var80061440 = 0x00000000;
|
|
bool g_IsSwitchingGoggles = false;
|
|
|
|
s32 var80061458 = 0x00000000;
|
|
|
|
Lights1 var80061460 = gdSPDefLights1(0x96, 0x96, 0x96, 0xff, 0xff, 0xff, 0x4d, 0x4d, 0x2e);
|
|
|
|
static void func0f0023b8(void);
|
|
static void func0f002844(s32 roomnum, f32 arg1, s32 arg2, s32 portalnum);
|
|
static void func0f00259c(s32 roomnum);
|
|
static void func0f00215c(u8 *arg0);
|
|
static void func0f003444(void);
|
|
static void func0f0035c0(void);
|
|
static void func0f00372c(void);
|
|
static void func0f0037ac(void);
|
|
static void func0f004558(s32 roomnum, s32 increment, s32 limit);
|
|
static void func0f00505c(void);
|
|
static void func0f004c6c(void);
|
|
static f32 func0f0053d0(s32 roomnum1, struct coord *pos1, s32 portalnum1, s32 roomnum2, struct coord *pos2, s32 portalnum2, f32 *arg6);
|
|
static void func0f005bb0(void);
|
|
|
|
static s32 func0f177a54(u8 *arg0, s32 arg1, u8 *arg2, s32 arg3)
|
|
{
|
|
s32 i = 0;
|
|
s32 v1 = 0;
|
|
s32 t0 = 0;
|
|
|
|
for (; i < arg1; i++) {
|
|
s32 index = i * arg3;
|
|
|
|
if (arg0[index] != 0) {
|
|
u8 *ptr = &arg0[index];
|
|
|
|
if (i != 0 && ptr[-arg3] == 0) {
|
|
arg2[v1++] = 0;
|
|
|
|
if (t0 == 255) {
|
|
arg2[v1++] = 200;
|
|
arg2[v1++] = 0;
|
|
t0 -= 200;
|
|
} else {
|
|
while (t0 > 255) {
|
|
arg2[v1++] = 255;
|
|
t0 -= 255;
|
|
}
|
|
}
|
|
|
|
arg2[v1++] = t0;
|
|
t0 = 0;
|
|
}
|
|
|
|
arg2[v1++] = arg0[index];
|
|
} else {
|
|
t0++;
|
|
}
|
|
}
|
|
|
|
arg2[v1++] = 0;
|
|
arg2[v1++] = 0;
|
|
|
|
return v1;
|
|
}
|
|
|
|
static s32 func0f177c8c(u8 *arg0, s32 *arg1, s32 *arg2)
|
|
{
|
|
s32 result;
|
|
|
|
if (*arg1 == 0) {
|
|
*arg2 = -1;
|
|
}
|
|
|
|
while (arg0[*arg1] == 0) {
|
|
*arg1 += 1;
|
|
|
|
if (arg0[*arg1]) {
|
|
while (arg0[*arg1] == 255) {
|
|
*arg2 += 255;
|
|
*arg1 += 1;
|
|
}
|
|
|
|
*arg2 += arg0[*arg1];
|
|
*arg1 += 1;
|
|
} else {
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
*arg2 += 1;
|
|
|
|
result = arg0[*arg1];
|
|
|
|
*arg1 += 1;
|
|
|
|
return result;
|
|
}
|
|
|
|
static u32 func0f000920(s32 portalnum1, s32 portalnum2)
|
|
{
|
|
if (portalnum1 != portalnum2) {
|
|
s32 upper = (portalnum1 > portalnum2) ? portalnum1 : portalnum2;
|
|
s32 lower = (portalnum1 < portalnum2) ? portalnum1 : portalnum2;
|
|
|
|
return var80061430[upper][lower];
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static struct light *roomGetLight(s32 roomnum, s32 lightnum)
|
|
{
|
|
return (struct light *)&g_BgLightsFileData[(g_Rooms[roomnum].lightindex + lightnum) * 0x22];
|
|
}
|
|
|
|
u8 func0f0009c0(s32 roomnum)
|
|
{
|
|
s32 value = g_Rooms[roomnum].unk52 + g_Rooms[roomnum].unk4b;
|
|
|
|
if (value > 255) {
|
|
value = 255;
|
|
}
|
|
|
|
if (value < 0) {
|
|
value = 0;
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
u8 func0f000a10(s32 roomnum)
|
|
{
|
|
s32 value = g_Rooms[roomnum].unk52;
|
|
|
|
if (USINGDEVICE(DEVICE_NIGHTVISION) || USINGDEVICE(DEVICE_IRSCANNER)) {
|
|
value += var8009caec;
|
|
} else {
|
|
value += g_Rooms[roomnum].unk4b;
|
|
}
|
|
|
|
if (value > 255) {
|
|
value = 255;
|
|
}
|
|
|
|
if (value < 0) {
|
|
value = 0;
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
u8 func0f000b24(s32 roomnum)
|
|
{
|
|
u32 value;
|
|
|
|
if (USINGDEVICE(DEVICE_NIGHTVISION) || USINGDEVICE(DEVICE_IRSCANNER)) {
|
|
return var8009caec;
|
|
}
|
|
|
|
if (g_Rooms[roomnum].flags & ROOMFLAG_0040) {
|
|
value = g_Rooms[roomnum].unk4b;
|
|
} else {
|
|
value = 255;
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
u8 roomGetBrightness(s32 room)
|
|
{
|
|
return g_Rooms[room].brightness & 0xff;
|
|
}
|
|
|
|
s32 func0f000c54(s32 roomnum)
|
|
{
|
|
if (g_Rooms[roomnum].unk52 > 255) {
|
|
return 255;
|
|
}
|
|
|
|
if (g_Rooms[roomnum].unk52 < 0) {
|
|
return 0;
|
|
}
|
|
|
|
return (g_Rooms[roomnum].flags & ROOMFLAG_0040) ? g_Rooms[roomnum].unk52 : 0;
|
|
}
|
|
|
|
f32 roomGetUnk5c(s32 roomnum)
|
|
{
|
|
return g_Rooms[roomnum].unk5c;
|
|
}
|
|
|
|
f32 func0f000dbc(s32 roomnum)
|
|
{
|
|
return g_Rooms[roomnum].brightness / 255.0f;
|
|
}
|
|
|
|
/**
|
|
* The resulting position is not a world position. It is relative to the room.
|
|
*/
|
|
bool lightGetBboxCentre(s32 roomnum, u32 lightnum, struct coord *pos)
|
|
{
|
|
struct light *light = (struct light *)&g_BgLightsFileData[g_Rooms[roomnum].lightindex * 0x22];
|
|
s32 i;
|
|
light += lightnum;
|
|
|
|
pos->x = 0;
|
|
pos->y = 0;
|
|
pos->z = 0;
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
pos->x += light->bbox[i].x;
|
|
pos->y += light->bbox[i].y;
|
|
pos->z += light->bbox[i].z;
|
|
}
|
|
|
|
pos->x *= 0.25f;
|
|
pos->y *= 0.25f;
|
|
pos->z *= 0.25f;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool lightIsHealthy(s32 roomnum, s32 lightnum)
|
|
{
|
|
bool healthy;
|
|
|
|
if (roomnum && roomGetLight(roomnum, lightnum)->healthy) {
|
|
healthy = true;
|
|
} else {
|
|
healthy = false;
|
|
}
|
|
|
|
return healthy;
|
|
}
|
|
|
|
bool lightIsVulnerable(s32 roomnum, s32 lightnum)
|
|
{
|
|
struct light *light = roomGetLight(roomnum, lightnum);
|
|
|
|
return light->vulnerable;
|
|
}
|
|
|
|
bool lightIsOn(s32 roomnum, s32 lightnum)
|
|
{
|
|
bool on;
|
|
|
|
if (roomnum && roomGetLight(roomnum, lightnum)->on) {
|
|
on = true;
|
|
} else {
|
|
on = false;
|
|
}
|
|
|
|
return on;
|
|
}
|
|
|
|
void roomSetUnk52(s32 roomnum, s32 value)
|
|
{
|
|
g_Rooms[roomnum].unk52 = value;
|
|
}
|
|
|
|
static void roomSetDefaults(struct room *room)
|
|
{
|
|
room->unk48 = 0;
|
|
room->unk49 = 255;
|
|
room->unk4a = 0;
|
|
room->brightness = 128;
|
|
room->unk52 = 0;
|
|
room->unk4b = 0;
|
|
room->lightop = 0;
|
|
room->flags &= ~(ROOMFLAG_0200 | ROOMFLAG_DIRTY | ROOMFLAG_RENDERALWAYS | ROOMFLAG_0040);
|
|
room->unk6c = 1;
|
|
room->unk70 = 1;
|
|
room->unk5c = 1;
|
|
room->unk60 = 0;
|
|
room->unk64 = 0;
|
|
room->unk68 = 0;
|
|
}
|
|
|
|
Gfx *lightsSetForRoom(Gfx *gdl, s16 roomnum)
|
|
{
|
|
Lights1 *lights = gfxAllocate(sizeof(Lights1));
|
|
|
|
u8 v0 = func0f000a10(roomnum);
|
|
u8 a0 = (u32)(v0 * 0.5882353f);
|
|
|
|
lights->a.l.col[0] = a0;
|
|
lights->a.l.col[1] = a0;
|
|
lights->a.l.col[2] = a0;
|
|
lights->a.l.colc[0] = a0;
|
|
lights->a.l.colc[1] = a0;
|
|
lights->a.l.colc[2] = a0;
|
|
|
|
lights->l[0].l.col[0] = v0;
|
|
lights->l[0].l.col[1] = v0;
|
|
lights->l[0].l.col[2] = v0;
|
|
lights->l[0].l.colc[0] = v0;
|
|
lights->l[0].l.colc[1] = v0;
|
|
lights->l[0].l.colc[2] = v0;
|
|
lights->l[0].l.dir[0] = 0x4d;
|
|
lights->l[0].l.dir[1] = 0x4d;
|
|
lights->l[0].l.dir[2] = 0x2e;
|
|
|
|
gSPSetLights1(gdl++, (*lights));
|
|
|
|
gSPLookAtX(gdl++, &camGetLookAt()->l[0]);
|
|
gSPLookAtY(gdl++, &camGetLookAt()->l[1]);
|
|
|
|
return gdl;
|
|
}
|
|
|
|
Gfx *lightsSetDefault(Gfx *gdl)
|
|
{
|
|
gSPSetLights1(gdl++, var80061460);
|
|
|
|
gSPLookAtX(gdl++, &camGetLookAt()->l[0]);
|
|
gSPLookAtY(gdl++, &camGetLookAt()->l[1]);
|
|
|
|
return gdl;
|
|
}
|
|
|
|
void roomInitLights(s32 roomnum)
|
|
{
|
|
struct room *room = &g_Rooms[roomnum];
|
|
struct light *light;
|
|
s32 i;
|
|
|
|
func0f158108(roomnum, &room->unk48, &room->unk49);
|
|
|
|
room->unk48 = room->unk48 / 4;
|
|
|
|
if (room->numlights) {
|
|
room->unk4a = (f32)(room->unk49 - room->unk48) / (f32)room->numlights;
|
|
} else {
|
|
room->unk4a = 0;
|
|
}
|
|
|
|
if (room->unk48 > 255) {
|
|
room->unk48 = 255;
|
|
}
|
|
|
|
if (room->unk49 > 255) {
|
|
room->unk49 = 255;
|
|
}
|
|
|
|
room->unk4c = room->unk48;
|
|
|
|
if (room->numlights == 0) {
|
|
room->unk4c += (room->unk49 - room->unk48) * 4 / 5;
|
|
}
|
|
|
|
switch (g_Vars.stagenum) {
|
|
case STAGE_EXTRACTION:
|
|
case STAGE_DEFECTION:
|
|
if (roomnum == 0x003d) { // near the top comms hub
|
|
room->unk4c = 2;
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (((g_StageIndex == STAGEINDEX_INFILTRATION || g_StageIndex == STAGEINDEX_RESCUE || g_StageIndex == STAGEINDEX_ESCAPE || g_StageIndex == STAGEINDEX_MAIANSOS)
|
|
&& roomnum == 0x000f) // freight elevator shaft
|
|
|| ((g_StageIndex == STAGEINDEX_DEFECTION || g_StageIndex == STAGEINDEX_EXTRACTION || g_StageIndex == STAGEINDEX_MBR)
|
|
&& roomnum == 0x0001) // moon
|
|
|| ((g_StageIndex == STAGEINDEX_SKEDARRUINS || g_StageIndex == STAGEINDEX_WAR)
|
|
&& roomnum == 0x0002) // fake sky
|
|
|| ((s32)g_StageIndex == STAGEINDEX_TEST_OLD
|
|
&& roomnum == 0x0001)
|
|
|| (g_StageIndex == STAGEINDEX_ATTACKSHIP
|
|
&& roomnum == 0x0071)) { // planet
|
|
room->flags |= ROOMFLAG_RENDERALWAYS;
|
|
} else {
|
|
room->flags &= ~ROOMFLAG_RENDERALWAYS;
|
|
}
|
|
|
|
room->flags |= ROOMFLAG_DIRTY;
|
|
|
|
light = (struct light *)&g_BgLightsFileData[(u32)g_Rooms[roomnum].lightindex * 0x22];
|
|
|
|
for (i = 0; i < room->numlights; i++) {
|
|
{
|
|
light->unk04 = g_Rooms[roomnum].unk4a;
|
|
light->unk05_00 = true;
|
|
light->healthy = true;
|
|
light->on = true;
|
|
light->sparking = false;
|
|
light->vulnerable = true;
|
|
|
|
switch (g_Vars.stagenum) {
|
|
case STAGE_CITRAINING:
|
|
case STAGE_DEFENSE:
|
|
if (roomnum == 0x000a) { // firing range
|
|
light->vulnerable = false;
|
|
}
|
|
break;
|
|
case STAGE_DEFECTION:
|
|
case STAGE_EXTRACTION:
|
|
if (roomnum == 0x003e && (i == 0 || i == 1)) { // top comms hub
|
|
light->vulnerable = false;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
light++;
|
|
}
|
|
}
|
|
|
|
bool lightsHandleHit(struct coord *gunpos, struct coord *hitpos, s32 roomnum)
|
|
{
|
|
s32 i;
|
|
f32 f2;
|
|
struct coord spa4;
|
|
struct coord sp98;
|
|
struct coord sp8c;
|
|
struct light *light;
|
|
|
|
if (roomnum == 0 || g_Rooms[roomnum].numlights == 0) {
|
|
return false;
|
|
}
|
|
|
|
spa4.x = gunpos->x - g_BgRooms[roomnum].pos.x;
|
|
spa4.y = gunpos->y - g_BgRooms[roomnum].pos.y;
|
|
spa4.z = gunpos->z - g_BgRooms[roomnum].pos.z;
|
|
|
|
sp98.x = hitpos->x - g_BgRooms[roomnum].pos.x;
|
|
sp98.y = hitpos->y - g_BgRooms[roomnum].pos.y;
|
|
sp98.z = hitpos->z - g_BgRooms[roomnum].pos.z;
|
|
|
|
sp8c.x = sp98.x - spa4.x;
|
|
sp8c.y = sp98.y - spa4.y;
|
|
sp8c.z = sp98.z - spa4.z;
|
|
|
|
f2 = 2.0f / sqrtf(sp8c.x * sp8c.x + sp8c.y * sp8c.y + sp8c.z * sp8c.z);
|
|
|
|
sp8c.x *= f2;
|
|
sp8c.y *= f2;
|
|
sp8c.z *= f2;
|
|
|
|
sp98.x += sp8c.x;
|
|
sp98.y += sp8c.y;
|
|
sp98.z += sp8c.z;
|
|
|
|
light = (struct light *)&g_BgLightsFileData[g_Rooms[roomnum].lightindex * 0x22];
|
|
|
|
for (i = 0; i < g_Rooms[roomnum].numlights; i++) {
|
|
if (light->healthy && light->vulnerable) {
|
|
if (func0002f490(&light->bbox[0], &light->bbox[1], &light->bbox[3], 0, &spa4, &sp98, &sp8c, 0, 0)
|
|
|| func0002f490(&light->bbox[1], &light->bbox[2], &light->bbox[3], 0, &spa4, &sp98, &sp8c, 0, 0)) {
|
|
struct coord soundpos;
|
|
|
|
soundpos.x = light->bbox[0].x;
|
|
soundpos.y = light->bbox[0].y;
|
|
soundpos.z = light->bbox[0].z;
|
|
|
|
roomSetLightBroken(roomnum, i);
|
|
propsnd0f0939f8(0, 0, SFX_HIT_GLASS, -1, -1, 0x400, 0, 0, &soundpos, -1.0f, 0, roomnum, -1.0f, -1.0f, -1.0f);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
light++;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void roomSetLightsFaulty(s32 roomnum, s32 chance)
|
|
{
|
|
struct light *light = (struct light *)&g_BgLightsFileData[g_Rooms[roomnum].lightindex * 0x22];
|
|
s32 i;
|
|
|
|
if (g_Rooms[roomnum].numlights) {
|
|
for (i = 0; i < g_Rooms[roomnum].numlights; i++) {
|
|
if ((random() % 100) < chance) {
|
|
light->healthy = false;
|
|
light->on = false;
|
|
}
|
|
|
|
light++;
|
|
}
|
|
}
|
|
|
|
g_Rooms[roomnum].unk4c = 50;
|
|
|
|
g_Rooms[roomnum].flags |= ROOMFLAG_DIRTY;
|
|
}
|
|
|
|
void roomSetLightBroken(s32 roomnum, s32 lightnum)
|
|
{
|
|
struct light *light = roomGetLight(roomnum, lightnum);
|
|
light->healthy = false;
|
|
light->on = false;
|
|
|
|
g_Rooms[roomnum].flags |= ROOMFLAG_DIRTY;
|
|
}
|
|
|
|
void lightsReset(void)
|
|
{
|
|
func0f004c6c();
|
|
}
|
|
|
|
void func0f001c0c(void)
|
|
{
|
|
s32 i;
|
|
s32 sp68;
|
|
s32 table1size;
|
|
s32 table2size;
|
|
s32 table3size;
|
|
s32 table4size;
|
|
s32 sp54;
|
|
u8 *ptr;
|
|
u8 *s5;
|
|
u8 *sp48;
|
|
s32 *sp44;
|
|
s32 j;
|
|
s32 stack[4];
|
|
|
|
osGetCount();
|
|
|
|
var80061440 = 0;
|
|
|
|
func0f0023b8();
|
|
|
|
if (1);
|
|
for (g_NumPortals = 0; g_BgPortals[g_NumPortals].verticesoffset != 0; g_NumPortals++);
|
|
|
|
if (g_NumPortals == 0) {
|
|
return;
|
|
}
|
|
|
|
table1size = ALIGN16(g_Vars.roomcount * 4);
|
|
table2size = ALIGN16(g_NumPortals * 4);
|
|
table3size = ALIGN16(g_Vars.roomcount * 4);
|
|
table4size = ALIGN16((u32)var8009cae0 * (u32)var8009cae0);
|
|
sp68 = ALIGN16(g_Vars.roomcount * 8);
|
|
|
|
mempGetStageFree();
|
|
|
|
ptr = mblurGetAllocation();
|
|
|
|
var80061434 = (f32 *)ptr;
|
|
ptr += table1size;
|
|
|
|
var80061438 = (bool *)ptr;
|
|
ptr += table2size;
|
|
|
|
sp44 = (s32 *)(ptr);
|
|
ptr += table3size;
|
|
|
|
sp48 = (u8 *)ptr;
|
|
ptr += table4size;
|
|
|
|
s5 = (u8 *)ptr;
|
|
|
|
var80061420 = mempAlloc(sp68, MEMPOOL_STAGE);
|
|
|
|
for (i = 0; i < g_NumPortals; i++) {
|
|
if (PORTAL_IS_CLOSED(i)) {
|
|
var80061438[i] = false;
|
|
} else {
|
|
var80061438[i] = true;
|
|
if (1);
|
|
}
|
|
}
|
|
|
|
if (g_Vars.stagenum == STAGE_EXTRACTION || g_Vars.stagenum == STAGE_DEFECTION) {
|
|
var80061438[98] = false;
|
|
var80061438[100] = false;
|
|
}
|
|
|
|
func0f00215c(sp48);
|
|
|
|
for (i = 1, table3size = 0; i < g_Vars.roomcount; i++) {
|
|
sp44[i] = func0f177a54((void *)(i * var8009cae0 + sp48), g_Vars.roomcount, (void *)(&s5[i * var8009cae0]), 1);
|
|
table3size += ALIGN4(sp44[i]);
|
|
}
|
|
|
|
ptr = mempAlloc(ALIGN16(table3size), MEMPOOL_STAGE);
|
|
|
|
sp68 += ALIGN16(table3size);
|
|
|
|
sp54 = 0;
|
|
|
|
for (i = 1; i < g_Vars.roomcount; i++) {
|
|
s32 size = ALIGN4(sp44[i]);
|
|
|
|
var80061420[i].unk00 = ptr;
|
|
|
|
ptr += size;
|
|
sp54 += size;
|
|
|
|
for (j = 0; j < sp44[i]; j++) {
|
|
var80061420[i].unk00[j] = *(&s5[i * var8009cae0] + j);
|
|
}
|
|
}
|
|
|
|
table3size = 0;
|
|
|
|
for (i = 1; i < g_Vars.roomcount; i++) {
|
|
sp44[i] = func0f177a54((void *)(sp48 + i), g_Vars.roomcount, (void *)(&s5[i * var8009cae0]), var8009cae0);
|
|
|
|
table3size += ALIGN4(sp44[i]);
|
|
}
|
|
|
|
ptr = mempAlloc(ALIGN16(table3size), MEMPOOL_STAGE);
|
|
|
|
for (i = 1; i < g_Vars.roomcount; i++) {
|
|
var80061420[i].unk04 = ptr;
|
|
|
|
ptr += ALIGN4(sp44[i]);
|
|
|
|
for (j = 0; j < sp44[i]; j++) {
|
|
var80061420[i].unk04[j] = *(&s5[i * var8009cae0] + j);
|
|
}
|
|
}
|
|
|
|
for (i = 1; i < g_Vars.roomcount; i++) {
|
|
g_Rooms[i].flags |= ROOMFLAG_ONSCREEN;
|
|
}
|
|
|
|
lightingTick();
|
|
|
|
for (i = 1; i < g_Vars.roomcount; i++) {
|
|
g_Rooms[i].flags &= ~ROOMFLAG_ONSCREEN;
|
|
}
|
|
|
|
osGetCount();
|
|
|
|
if (sp68);
|
|
}
|
|
|
|
static f32 func0f002334(s32 roomnum, f32 mult, s32 portalnum1, s32 portalnum2);
|
|
|
|
static void func0f00215c(u8 *arg0)
|
|
{
|
|
s32 i;
|
|
s32 j;
|
|
|
|
var8009cae8 = &func0f002334;
|
|
|
|
var8006143c = 50.0f;
|
|
var8009cae4 = 20;
|
|
var80061440 = 0;
|
|
|
|
for (i = 1; i < g_Vars.roomcount; i++) {
|
|
u8 *ptr = &arg0[i * var8009cae0];
|
|
|
|
func0f00259c(i);
|
|
|
|
for (j = 0; j < 1; j++) {
|
|
ptr[j] = 0;
|
|
}
|
|
|
|
for (j = 1; j < g_Vars.roomcount; j++) {
|
|
if (var80061434[i] < var80061434[j]) {
|
|
var80061434[j] = var80061434[i];
|
|
}
|
|
|
|
ptr[j] = var80061434[j];
|
|
}
|
|
}
|
|
}
|
|
|
|
f32 func0f002334(s32 roomnum, f32 mult, s32 portalnum1, s32 portalnum2)
|
|
{
|
|
f32 fVar2 = 0;
|
|
f32 result;
|
|
|
|
if (portalnum1 != -1) {
|
|
fVar2 = portal0f15b274(portalnum1);
|
|
}
|
|
|
|
result = (portal0f15b274(portalnum2) / (g_Rooms[roomnum].unk70 - fVar2)) * mult;
|
|
return result;
|
|
}
|
|
|
|
static void func0f0023b8(void)
|
|
{
|
|
s32 i;
|
|
s32 j;
|
|
|
|
for (i = 0; i < g_Vars.roomcount; i++) {
|
|
bool valid = true;
|
|
|
|
g_Rooms[i].unk6c = 1.0f;
|
|
g_Rooms[i].unk70 = 1.0f;
|
|
|
|
for (j = 0; j < 3; j++) {
|
|
f32 diff = g_Rooms[i].bbmax[j] - g_Rooms[i].bbmin[j];
|
|
|
|
if (diff > 0.0f) {
|
|
g_Rooms[i].unk6c *= (g_Rooms[i].bbmax[j] - g_Rooms[i].bbmin[j]) / 100.0f;
|
|
} else {
|
|
valid = false;
|
|
}
|
|
}
|
|
|
|
g_Rooms[i].unk6c += 1.0f;
|
|
|
|
if (g_Rooms[i].unk6c > 60.0f) {
|
|
g_Rooms[i].unk6c = 60.0f;
|
|
}
|
|
|
|
if (valid) {
|
|
f32 xdiff = g_Rooms[i].bbmax[0] - g_Rooms[i].bbmin[0];
|
|
f32 ydiff = g_Rooms[i].bbmax[1] - g_Rooms[i].bbmin[1];
|
|
f32 zdiff = g_Rooms[i].bbmax[2] - g_Rooms[i].bbmin[2];
|
|
|
|
if (!(xdiff > 0)) {
|
|
xdiff = -xdiff;
|
|
}
|
|
|
|
if (!(ydiff > 0)) {
|
|
ydiff = -ydiff;
|
|
}
|
|
|
|
if (!(zdiff > 0)) {
|
|
zdiff = -zdiff;
|
|
}
|
|
|
|
g_Rooms[i].unk70 = 2.0f * (xdiff * ydiff + xdiff * zdiff + ydiff * zdiff);
|
|
} else {
|
|
g_Rooms[i].unk70 = 20000000.0f;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void func0f00259c(s32 roomnum)
|
|
{
|
|
s32 i;
|
|
f32 sp58;
|
|
f32 f20 = 0.0f;
|
|
|
|
for (i = 0; i < g_Vars.roomcount; i++) {
|
|
var80061434[i] = 0.0f;
|
|
}
|
|
|
|
var80061434[roomnum] = sqrtf(g_Rooms[roomnum].unk6c) * 255.0f;
|
|
if (1);
|
|
|
|
if (g_Rooms[roomnum].numportals != 0) {
|
|
func0f002844(roomnum, var80061434[roomnum], 0, -1);
|
|
if (1);
|
|
if (1);
|
|
}
|
|
|
|
for (i = 0; i < g_Rooms[roomnum].numportals; i++) {
|
|
f20 += portal0f15b274(g_RoomPortals[g_Rooms[roomnum].roomportallistoffset + i]);
|
|
}
|
|
|
|
sp58 = (g_Rooms[roomnum].unk70 - f20) / g_Rooms[roomnum].unk70;
|
|
|
|
for (i = 1; i < g_Vars.roomcount; i++) {
|
|
var80061434[i] *= 3.0f / sqrtf(g_Rooms[i].unk6c);
|
|
}
|
|
|
|
if (var80061434[roomnum] > 255.0f) {
|
|
var80061434[roomnum] = 255.0f;
|
|
}
|
|
|
|
if (sp58 < 0.1f) {
|
|
g_Rooms[roomnum].unk48 = g_Rooms[roomnum].unk49 >> 1;
|
|
var80061434[roomnum] = g_Rooms[roomnum].unk49;
|
|
}
|
|
}
|
|
|
|
static void func0f002844(s32 roomnum, f32 arg1, s32 arg2, s32 portalnum)
|
|
{
|
|
s32 i;
|
|
s32 otherroomnum = -1;
|
|
|
|
var80061440++;
|
|
|
|
if (portalnum != -1) {
|
|
if (roomnum == g_BgPortals[portalnum].roomnum1) {
|
|
otherroomnum = (s32) g_BgPortals[portalnum].roomnum2;
|
|
} else {
|
|
otherroomnum = (s32) g_BgPortals[portalnum].roomnum1;
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < g_Rooms[roomnum].numportals; i++) {
|
|
s32 iterportalnum = g_RoomPortals[g_Rooms[roomnum].roomportallistoffset + i];
|
|
s32 iterroomnum;
|
|
|
|
if (var80061438[iterportalnum]) {
|
|
if (roomnum == g_BgPortals[iterportalnum].roomnum1) {
|
|
iterroomnum = g_BgPortals[iterportalnum].roomnum2;
|
|
} else {
|
|
iterroomnum = g_BgPortals[iterportalnum].roomnum1;
|
|
}
|
|
|
|
if (iterroomnum != otherroomnum) {
|
|
f32 f0 = var8009cae8(roomnum, arg1, portalnum, iterportalnum);
|
|
|
|
if (f0 > var8006143c && arg2 < var8009cae4) {
|
|
var80061434[roomnum] -= f0;
|
|
var80061434[iterroomnum] += f0;
|
|
|
|
if (var80061434[roomnum] < 0.0f) {
|
|
var80061434[roomnum] = 0.0f;
|
|
}
|
|
|
|
func0f002844(iterroomnum, f0, arg2 + 1, iterportalnum);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void func0f002a98(void)
|
|
{
|
|
s32 i;
|
|
|
|
var8009cae0 = ALIGN4(g_Vars.roomcount);
|
|
var80061458 = 0;
|
|
g_Vars.remakewallhitvtx = 0;
|
|
|
|
for (i = 1; i < g_Vars.roomcount; i++) {
|
|
roomSetDefaults(&g_Rooms[i]);
|
|
roomInitLights(i);
|
|
}
|
|
|
|
var80061420 = 0;
|
|
}
|
|
|
|
void roomSetLightsOn(s32 roomnum, s32 enable)
|
|
{
|
|
struct light *light = (struct light *)&g_BgLightsFileData[g_Rooms[roomnum].lightindex * 0x22];
|
|
s32 i;
|
|
|
|
if (g_Rooms[roomnum].numlights) {
|
|
for (i = 0; i < g_Rooms[roomnum].numlights; i++) {
|
|
if (light->healthy) {
|
|
light->on = enable;
|
|
}
|
|
|
|
light++;
|
|
}
|
|
}
|
|
|
|
if (enable) {
|
|
g_Rooms[roomnum].flags &= ~ROOMFLAG_LIGHTSOFF;
|
|
} else {
|
|
g_Rooms[roomnum].flags |= ROOMFLAG_LIGHTSOFF;
|
|
}
|
|
|
|
g_Rooms[roomnum].flags |= ROOMFLAG_DIRTY;
|
|
}
|
|
|
|
void roomSetLighting(s32 roomnum, s32 operation, u8 arg2, u8 arg3, u8 arg4)
|
|
{
|
|
if (cheatIsActive(CHEAT_PERFECTDARKNESS) == false) {
|
|
g_Rooms[roomnum].lightop = operation;
|
|
|
|
switch (operation) {
|
|
case LIGHTOP_1:
|
|
g_Rooms[roomnum].unk60 = arg2 * 0.01f;
|
|
break;
|
|
case LIGHTOP_2:
|
|
g_Rooms[roomnum].unk60 = arg2;
|
|
g_Rooms[roomnum].unk64 = arg3 * 0.01f;
|
|
g_Rooms[roomnum].unk68 = arg4 * 4.0f;
|
|
g_Rooms[roomnum].unk54 = arg4;
|
|
break;
|
|
case LIGHTOP_3:
|
|
g_Rooms[roomnum].unk60 = arg2 * 0.01f;
|
|
g_Rooms[roomnum].unk64 = arg3 * 0.01f;
|
|
g_Rooms[roomnum].unk68 = arg4 * 4.0f;
|
|
g_Rooms[roomnum].unk54 = arg4;
|
|
break;
|
|
case LIGHTOP_4:
|
|
g_Rooms[roomnum].unk60 = arg2 * 0.01f;
|
|
g_Rooms[roomnum].unk64 = arg3 * 0.01f;
|
|
g_Rooms[roomnum].unk68 = arg4 * 4.0f;
|
|
g_Rooms[roomnum].unk54 = 0;
|
|
break;
|
|
case LIGHTOP_5:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool lightTickBroken(s32 roomnum, s32 lightnum)
|
|
{
|
|
struct light *light = (struct light *)(g_BgLightsFileData + ((g_Rooms[roomnum].lightindex + lightnum) * 0x22));
|
|
struct coord spc8;
|
|
struct coord spbc;
|
|
struct coord spb0;
|
|
struct coord spa4;
|
|
struct coord sp98;
|
|
struct coord sp8c;
|
|
struct coord sp80;
|
|
struct coord centre; // 74
|
|
f32 rand1; // 70
|
|
f32 rand2; // 6c
|
|
s32 sparktype; // 68
|
|
|
|
if (!light->unk05_00) {
|
|
return false;
|
|
}
|
|
|
|
if (light->sparking) {
|
|
if ((random() % 8) == 0) {
|
|
light->sparking = false;
|
|
} else if ((random() % 2) == 0) {
|
|
rand1 = 2.0f * RANDOMFRAC() - 1.0f; // range -1 to 1
|
|
rand2 = 2.0f * RANDOMFRAC() - 1.0f; // range -1 to 1
|
|
sparktype = -1;
|
|
|
|
spc8.x = light->bbox[1].x - light->bbox[0].x;
|
|
spc8.y = light->bbox[1].y - light->bbox[0].y;
|
|
spc8.z = light->bbox[1].z - light->bbox[0].z;
|
|
|
|
spc8.x = rand1 * spc8.x;
|
|
spc8.y = rand1 * spc8.y;
|
|
spc8.z = rand1 * spc8.z;
|
|
|
|
spbc.x = light->bbox[2].x - light->bbox[0].x;
|
|
spbc.y = light->bbox[2].y - light->bbox[0].y;
|
|
spbc.z = light->bbox[2].z - light->bbox[0].z;
|
|
|
|
spbc.x = rand2 * spbc.x;
|
|
spbc.y = rand2 * spbc.y;
|
|
spbc.z = rand2 * spbc.z;
|
|
|
|
// @bug? These all use x
|
|
sp98.x = light->bbox[0].x + spc8.x + spbc.x;
|
|
sp98.y = light->bbox[0].x + spc8.y + spbc.y;
|
|
sp98.z = light->bbox[0].x + spc8.z + spbc.z;
|
|
|
|
sp8c.x = light->unk07;
|
|
sp8c.y = light->unk08;
|
|
sp8c.z = light->unk09;
|
|
|
|
sp80.x = -sp8c.f[0];
|
|
sp80.y = -sp8c.f[1];
|
|
sp80.z = -sp8c.f[2];
|
|
|
|
func0f177164(&sp98, &spa4);
|
|
|
|
spa4.x += sp80.x;
|
|
spa4.y += sp80.y;
|
|
spa4.z += sp80.z;
|
|
|
|
func0f177164(&spa4, &spa4);
|
|
|
|
// Mismatch: Goal loads roomnum * 0x14 into sp58 here but doesn't
|
|
// use it until after lightGetBboxCentre. The below statement does
|
|
// the same but also emits the load and store instructions.
|
|
g_BgRooms[roomnum].unk00 += 0;
|
|
|
|
switch (random() % 4) {
|
|
case 0:
|
|
sparktype = SPARKTYPE_LIGHT1;
|
|
break;
|
|
case 1:
|
|
sparktype = SPARKTYPE_LIGHT2;
|
|
break;
|
|
case 2:
|
|
sparktype = SPARKTYPE_LIGHT3;
|
|
break;
|
|
case 3:
|
|
sparktype = SPARKTYPE_LIGHT4;
|
|
break;
|
|
}
|
|
|
|
lightGetBboxCentre(roomnum, lightnum, ¢re);
|
|
|
|
centre.x += g_BgRooms[roomnum].pos.x;
|
|
centre.y += g_BgRooms[roomnum].pos.y;
|
|
centre.z += g_BgRooms[roomnum].pos.z;
|
|
|
|
sparksCreate(roomnum, NULL, ¢re, &spa4, &sp8c, sparktype);
|
|
|
|
if ((random() % 4) == 0) {
|
|
s16 smokerooms[2]; // 64
|
|
smokerooms[0] = roomnum;
|
|
smokerooms[1] = -1;
|
|
|
|
smokeCreateSimple(¢re, smokerooms, SMOKETYPE_BULLETIMPACT);
|
|
}
|
|
|
|
roomAdjustLighting(roomnum, 0x40, 0x50);
|
|
propsnd0f0939f8(NULL, NULL, propsndGetRandomSparkSound(), -1, -1, 0x400, 0, 0x10, ¢re, -1.0f, 0, roomnum, -1.0f, -1.0f, -1.0f);
|
|
return true;
|
|
}
|
|
} else {
|
|
u32 stack;
|
|
|
|
if ((random() % 80) == 0) {
|
|
light->sparking = true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
void lightingTick(void)
|
|
{
|
|
s32 i;
|
|
|
|
func0f0037ac();
|
|
|
|
if (g_Vars.remakewallhitvtx) {
|
|
wallhitsRecolour();
|
|
|
|
g_Vars.remakewallhitvtx = false;
|
|
|
|
for (i = 1; i < g_Vars.roomcount; i++) {
|
|
g_Rooms[i].flags &= ~ROOMFLAG_1000;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void func0f003444(void)
|
|
{
|
|
s32 i;
|
|
s32 j;
|
|
|
|
for (i = 0; i < g_Vars.roomcount; i++) {
|
|
struct light *light = (struct light *)&g_BgLightsFileData[g_Rooms[i].lightindex * 0x22];
|
|
g_Rooms[i].lightop = LIGHTOP_1;
|
|
g_Rooms[i].unk60 = 0.5f;
|
|
|
|
for (j = 0; j < g_Rooms[i].numlights; j++) {
|
|
light->unk05_00 = random() % 2 ? true : false;
|
|
light->healthy = true;
|
|
light->on = true;
|
|
light->sparking = false;
|
|
light->vulnerable = true;
|
|
light->unk04 = g_Rooms[i].unk4a;
|
|
|
|
light++;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void func0f0035c0(void)
|
|
{
|
|
s32 i;
|
|
s32 j;
|
|
|
|
for (i = 0; i < g_Vars.roomcount; i++) {
|
|
struct light *light = (struct light *)&g_BgLightsFileData[g_Rooms[i].lightindex * 0x22];
|
|
g_Rooms[i].lightop = LIGHTOP_1;
|
|
g_Rooms[i].unk60 = 0;
|
|
|
|
for (j = 0; j < g_Rooms[i].numlights; j++) {
|
|
light->unk05_00 = random() % 2 ? true : false;
|
|
light->healthy = false;
|
|
light->on = false;
|
|
light->sparking = false;
|
|
light->vulnerable = false;
|
|
light->unk04 = 0;
|
|
|
|
light++;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void func0f00372c(void)
|
|
{
|
|
if (g_Vars.tickmode != var80061458) {
|
|
if (TICKMODE_CUTSCENE == g_Vars.tickmode && TICKMODE_CUTSCENE != var80061458) {
|
|
func0f003444();
|
|
} else if (TICKMODE_NORMAL == g_Vars.tickmode && TICKMODE_NORMAL != var80061458) {
|
|
func0f0035c0();
|
|
}
|
|
|
|
var80061458 = g_Vars.tickmode;
|
|
}
|
|
}
|
|
|
|
static void func0f0037ac(void)
|
|
{
|
|
s32 i;
|
|
s32 numprocessed = 0;
|
|
s32 j;
|
|
bool wasdirty = false;
|
|
struct light *light;
|
|
f32 amount;
|
|
s32 v1;
|
|
f32 angle;
|
|
f32 average;
|
|
u32 stack;
|
|
|
|
if (cheatIsActive(CHEAT_PERFECTDARKNESS)) {
|
|
func0f00372c();
|
|
}
|
|
|
|
if (var80061420 == NULL) {
|
|
return;
|
|
}
|
|
|
|
for (i = 1; i < g_Vars.roomcount; i++) {
|
|
g_Rooms[i].flags &= ~ROOMFLAG_0400;
|
|
}
|
|
|
|
for (i = 1; i < g_Vars.roomcount; i++) {
|
|
g_Rooms[i].unk54 -= g_Vars.lvupdate240;
|
|
|
|
switch (g_Rooms[i].lightop) {
|
|
case LIGHTOP_1:
|
|
g_Rooms[i].unk5c = g_Rooms[i].unk60;
|
|
|
|
if (g_Rooms[i].unk5c < 0.0f) {
|
|
g_Rooms[i].unk5c = 0.0f;
|
|
}
|
|
|
|
g_Rooms[i].flags |= ROOMFLAG_DIRTY;
|
|
roomSetLighting(i, 0, 0, 0, 0);
|
|
break;
|
|
case LIGHTOP_2:
|
|
if (g_Rooms[i].unk54 < 0) {
|
|
if (RANDOMFRAC() * 100.0f < g_Rooms[i].unk60) {
|
|
g_Rooms[i].unk5c = 1.0f;
|
|
} else {
|
|
g_Rooms[i].unk5c = g_Rooms[i].unk64;
|
|
|
|
if (g_Rooms[i].unk5c < 0.0f) {
|
|
g_Rooms[i].unk5c = 0.0f;
|
|
}
|
|
}
|
|
|
|
g_Rooms[i].unk54 = g_Rooms[i].unk68;
|
|
g_Rooms[i].flags |= ROOMFLAG_DIRTY;
|
|
}
|
|
break;
|
|
case LIGHTOP_3:
|
|
if (g_Rooms[i].unk54 > 0) {
|
|
g_Rooms[i].unk5c = g_Rooms[i].unk64;
|
|
g_Rooms[i].unk5c += g_Rooms[i].unk54 / g_Rooms[i].unk68 * (g_Rooms[i].unk60 - g_Rooms[i].unk64);
|
|
|
|
if (g_Rooms[i].unk5c < 0.0f) {
|
|
g_Rooms[i].unk5c = 0.0f;
|
|
}
|
|
} else {
|
|
roomSetLighting(i, 0, 0, 0, 0);
|
|
}
|
|
|
|
g_Rooms[i].flags |= ROOMFLAG_DIRTY;
|
|
break;
|
|
case LIGHTOP_4:
|
|
v1 = g_Rooms[i].unk54 > 0 ? g_Rooms[i].unk54 : -g_Rooms[i].unk54;
|
|
|
|
angle = (v1 % (s32) g_Rooms[i].unk68) * M_TAU / g_Rooms[i].unk68;
|
|
average = (g_Rooms[i].unk60 + g_Rooms[i].unk64) * 0.5f;
|
|
|
|
g_Rooms[i].unk5c = g_Rooms[i].unk60 + (cosf(angle) + 1.0f) * average;
|
|
|
|
if (g_Rooms[i].unk5c < 0.0f) {
|
|
g_Rooms[i].unk5c = 0.0f;
|
|
}
|
|
|
|
g_Rooms[i].flags |= ROOMFLAG_DIRTY;
|
|
break;
|
|
case LIGHTOP_5:
|
|
g_Rooms[i].flags |= ROOMFLAG_DIRTY;
|
|
break;
|
|
}
|
|
|
|
if (g_IsSwitchingGoggles) {
|
|
g_Rooms[i].flags |= ROOMFLAG_DIRTY;
|
|
}
|
|
|
|
if (g_Rooms[i].flags & ROOMFLAG_DIRTY) {
|
|
if (g_Rooms[i].numlights != 0) {
|
|
s32 numlightson = 0;
|
|
struct light *light = (struct light *)&g_BgLightsFileData[g_Rooms[i].lightindex * 0x22];
|
|
|
|
for (j = 0; j < g_Rooms[i].numlights; j++) {
|
|
if (light->on) {
|
|
numlightson++;
|
|
}
|
|
|
|
light++;
|
|
}
|
|
|
|
if (g_Rooms[i].flags & ROOMFLAG_LIGHTSOFF) {
|
|
amount = 2.0f;
|
|
} else if (numlightson != 0) {
|
|
amount = g_Rooms[i].unk4c;
|
|
} else {
|
|
amount = (f32)g_Rooms[i].unk4c / 2;
|
|
}
|
|
} else {
|
|
if (g_Rooms[i].flags & ROOMFLAG_LIGHTSOFF) {
|
|
amount = 2.0f;
|
|
} else {
|
|
amount = g_Rooms[i].unk4c;
|
|
}
|
|
}
|
|
|
|
amount *= g_Rooms[i].unk5c;
|
|
g_Rooms[i].brightness = amount;
|
|
|
|
light = (struct light *)&g_BgLightsFileData[g_Rooms[i].lightindex * 0x22];
|
|
|
|
for (j = 0; j < g_Rooms[i].numlights; j++) {
|
|
if (light->on) {
|
|
amount = g_Rooms[i].unk5c * light->unk04;
|
|
g_Rooms[i].brightness += (s32)amount;
|
|
}
|
|
|
|
light++;
|
|
}
|
|
|
|
if (g_Rooms[i].brightness > 255) {
|
|
g_Rooms[i].brightness = 255;
|
|
}
|
|
|
|
g_Rooms[i].flags &= ~ROOMFLAG_DIRTY;
|
|
|
|
wasdirty = 1;
|
|
}
|
|
|
|
if (g_Rooms[i].unk52 != 0) {
|
|
s32 updaterate = g_Vars.lvupdate240 * 2;
|
|
|
|
if (var80061420 != NULL) {
|
|
s32 spa0 = 0;
|
|
s32 sp9c = 0;
|
|
|
|
s32 ret = func0f177c8c(var80061420[i].unk04, &spa0, &sp9c);
|
|
|
|
while (ret != -1) {
|
|
if (ret != 0) {
|
|
g_Rooms[sp9c].flags |= ROOMFLAG_0400;
|
|
}
|
|
|
|
ret = func0f177c8c(var80061420[i].unk04, &spa0, &sp9c);
|
|
}
|
|
}
|
|
|
|
if (g_Rooms[i].unk52 > 0) {
|
|
if (g_Rooms[i].unk52 < updaterate) {
|
|
updaterate = g_Rooms[i].unk52;
|
|
}
|
|
|
|
g_Rooms[i].unk52 -= updaterate;
|
|
} else {
|
|
if (g_Rooms[i].unk52 > updaterate) {
|
|
updaterate = g_Rooms[i].unk52;
|
|
}
|
|
|
|
g_Rooms[i].unk52 += updaterate;
|
|
}
|
|
|
|
g_Rooms[i].flags |= ROOMFLAG_0400;
|
|
}
|
|
|
|
g_Rooms[i].flags &= ~ROOMFLAG_DIRTY;
|
|
}
|
|
|
|
if (g_IsSwitchingGoggles || wasdirty) {
|
|
for (i = 1; i < g_Vars.roomcount; i++) {
|
|
g_Rooms[i].flags |= ROOMFLAG_0200;
|
|
}
|
|
}
|
|
|
|
for (i = 1; i < g_Vars.roomcount; i++) {
|
|
if (i != 0) {
|
|
if ((g_Rooms[i].flags & ROOMFLAG_RENDERALWAYS) || (g_Rooms[i].flags & (ROOMFLAG_ONSCREEN | ROOMFLAG_STANDBY))) {
|
|
if (g_Rooms[i].flags & (ROOMFLAG_0200 | ROOMFLAG_0400)) {
|
|
s32 sum = 0;
|
|
s32 sp90 = 0;
|
|
s32 sp8c = 0;
|
|
|
|
s32 ret = func0f177c8c(var80061420[i].unk00, &sp90, &sp8c);
|
|
|
|
while (ret != -1) {
|
|
if (sp8c != 0) {
|
|
s32 add = 0;
|
|
|
|
if (sp8c) {
|
|
add += (s32)((1.0f / 255.0f) * ret * g_Rooms[sp8c].brightness);
|
|
}
|
|
|
|
sum += add;
|
|
}
|
|
|
|
ret = func0f177c8c(var80061420[i].unk00, &sp90, &sp8c);
|
|
}
|
|
|
|
if (sum > 255) {
|
|
sum = 255;
|
|
}
|
|
|
|
g_Rooms[i].unk4b = sum;
|
|
g_Rooms[i].flags |= ROOMFLAG_0040;
|
|
g_Rooms[i].flags |= ROOMFLAG_1000;
|
|
g_Rooms[i].flags &= ~(ROOMFLAG_0200 | ROOMFLAG_0400);
|
|
|
|
if (g_Rooms[i].lightop == LIGHTOP_5) {
|
|
s32 sp80;
|
|
s32 sp7c;
|
|
s32 sp78;
|
|
|
|
sp78 = sp7c = sp80 = func0f000a10(i);
|
|
|
|
scenarioHighlightRoom(i, &sp80, &sp7c, &sp78);
|
|
|
|
g_Rooms[i].unk74 = sp80 * (1.0f / 255.0f);
|
|
g_Rooms[i].unk78 = sp7c * (1.0f / 255.0f);
|
|
g_Rooms[i].unk7c = sp78 * (1.0f / 255.0f);
|
|
} else {
|
|
g_Rooms[i].unk74 = func0f000a10(i) * (1.0f / 255.0f);
|
|
g_Rooms[i].unk78 = g_Rooms[i].unk74;
|
|
g_Rooms[i].unk7c = g_Rooms[i].unk74;
|
|
}
|
|
|
|
numprocessed++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (g_Vars.joydisableframestogo <= 0 && (numprocessed || g_IsSwitchingGoggles)) {
|
|
struct prop *prop = g_Vars.activeprops;
|
|
|
|
while (prop) {
|
|
if (prop->type == PROPTYPE_CHR) {
|
|
for (i = 0; prop->rooms[i] != -1; i++) {
|
|
if (g_Rooms[prop->rooms[i]].flags & ROOMFLAG_1000) {
|
|
if (2 == g_IsSwitchingGoggles) {
|
|
struct chrdata *chr = prop->chr;
|
|
propCalculateShadeColour(chr->prop, chr->nextcol, chr->floorcol);
|
|
} else {
|
|
struct chrdata *chr = prop->chr;
|
|
chr->unk32c_18 = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
prop = prop->next;
|
|
}
|
|
|
|
g_Vars.remakewallhitvtx = 0xf;
|
|
}
|
|
|
|
if (g_IsSwitchingGoggles) {
|
|
g_IsSwitchingGoggles = false;
|
|
}
|
|
}
|
|
|
|
void lightsTick(void)
|
|
{
|
|
struct hand *hand1 = &g_Vars.currentplayer->hands[0];
|
|
struct hand *hand2 = &g_Vars.currentplayer->hands[1];
|
|
|
|
func0f005bb0();
|
|
|
|
if (hand1->flashon || hand2->flashon) {
|
|
roomAdjustLighting(g_Vars.currentplayer->prop->rooms[0], 64, 80);
|
|
}
|
|
}
|
|
|
|
void roomAdjustLighting(s32 roomnum, s32 start, s32 limit)
|
|
{
|
|
if (var80061420 && !(g_Rooms[roomnum].flags & ROOMFLAG_OUTDOORS ? 1 : 0)) {
|
|
s32 value;
|
|
s32 sp78 = 0;
|
|
s32 neighbournum = 0;
|
|
|
|
value = func0f177c8c(var80061420[roomnum].unk04, &sp78, &neighbournum);
|
|
|
|
while (value != -1) {
|
|
f32 increment = value * 0.0039215688593686f * start * 5.0f;
|
|
|
|
if (start > 0) {
|
|
if (increment > start) {
|
|
increment = start;
|
|
}
|
|
} else {
|
|
if (increment < start) {
|
|
increment = start;
|
|
}
|
|
}
|
|
|
|
// @bug: Should be checking neighbournum flags, not roomnum
|
|
if (!(g_Rooms[roomnum].flags & ROOMFLAG_OUTDOORS ? 1 : 0)) {
|
|
func0f004558(neighbournum, increment, limit);
|
|
}
|
|
|
|
value = func0f177c8c(var80061420[roomnum].unk04, &sp78, &neighbournum);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void func0f004558(s32 roomnum, s32 increment, s32 limit)
|
|
{
|
|
if (roomnum) {
|
|
if (g_Rooms[roomnum].flags & ROOMFLAG_ONSCREEN) {
|
|
if (increment > 0) {
|
|
// Increasing
|
|
if (g_Rooms[roomnum].unk52 < limit) {
|
|
g_Rooms[roomnum].unk52 += increment;
|
|
|
|
if (g_Rooms[roomnum].unk52 > limit) {
|
|
g_Rooms[roomnum].unk52 = limit;
|
|
}
|
|
}
|
|
} else {
|
|
// Decreasing
|
|
if (g_Rooms[roomnum].unk52 > limit) {
|
|
g_Rooms[roomnum].unk52 += increment;
|
|
|
|
if (g_Rooms[roomnum].unk52 < limit) {
|
|
g_Rooms[roomnum].unk52 = limit;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void roomHighlight(s32 roomnum)
|
|
{
|
|
s32 i;
|
|
s32 tmpr;
|
|
s32 tmpg;
|
|
s32 tmpb;
|
|
s32 alpha;
|
|
s32 red;
|
|
s32 green;
|
|
s32 blue;
|
|
s32 extra;
|
|
s32 numcolours;
|
|
struct colour *src;
|
|
struct colour *dst;
|
|
u8 s2;
|
|
s32 max;
|
|
f32 mult;
|
|
u32 stack;
|
|
|
|
if (var8007fc3c != g_Rooms[roomnum].unk56 && g_Rooms[roomnum].loaded240 != 0) {
|
|
g_Rooms[roomnum].unk56 = var8007fc3c;
|
|
|
|
if ((g_Rooms[roomnum].flags & ROOMFLAG_0040) == 0) {
|
|
g_Rooms[roomnum].flags |= ROOMFLAG_0200;
|
|
}
|
|
|
|
s2 = func0f000b24(roomnum);
|
|
numcolours = g_Rooms[roomnum].gfxdata->numcolours;
|
|
dst = gfxAllocateColours(numcolours);
|
|
g_Rooms[roomnum].colours = dst;
|
|
|
|
extra = g_Rooms[roomnum].unk52;
|
|
src = (struct colour *)((u32)g_Rooms[roomnum].gfxdata->vertices + g_Rooms[roomnum].gfxdata->numvertices * sizeof(struct gfxvtx));
|
|
src = (struct colour *)ALIGN8((s32)src);
|
|
|
|
if (g_Rooms[roomnum].flags & ROOMFLAG_RENDERALWAYS) {
|
|
g_Rooms[roomnum].colours = src;
|
|
return;
|
|
}
|
|
|
|
for (i = 0; i < numcolours; i++) {
|
|
// @bug? Why is this looking up vertices using a colour index?
|
|
if (g_Rooms[roomnum].gfxdata->vertices[i].flags & 0x01) {
|
|
dst[i].r = src[i].r;
|
|
dst[i].g = src[i].g;
|
|
dst[i].b = src[i].b;
|
|
dst[i].a = src[i].a * (1.0f / 255.0f * s2);
|
|
} else {
|
|
if (USINGDEVICE(DEVICE_NIGHTVISION) || USINGDEVICE(DEVICE_IRSCANNER)) {
|
|
tmpr = tmpg = tmpb = (src[i].r > src[i].g && src[i].r > src[i].b)
|
|
? src[i].r
|
|
: src[i].g > src[i].b ? src[i].g : src[i].b;
|
|
} else {
|
|
tmpr = src[i].r;
|
|
tmpg = src[i].g;
|
|
tmpb = src[i].b;
|
|
}
|
|
|
|
alpha = src[i].a;
|
|
max = tmpr;
|
|
|
|
if (tmpg > max) {
|
|
max = tmpg;
|
|
}
|
|
|
|
if (tmpb > max) {
|
|
max = tmpb;
|
|
}
|
|
|
|
if (max > s2) {
|
|
mult = s2 / (f32)max;
|
|
} else {
|
|
mult = 1.0f;
|
|
}
|
|
|
|
red = tmpr * mult;
|
|
green = tmpg * mult;
|
|
blue = tmpb * mult;
|
|
max *= mult;
|
|
|
|
if (USINGDEVICE(DEVICE_NIGHTVISION) || USINGDEVICE(DEVICE_IRSCANNER)) {
|
|
extra = 0;
|
|
} else if (extra + max > 285) {
|
|
extra = 285 - max;
|
|
}
|
|
|
|
if (red + green + blue != 0
|
|
|| g_Rooms[roomnum].unk5c == 0.0f
|
|
|| (g_Rooms[roomnum].flags & ROOMFLAG_LIGHTSOFF)) {
|
|
red += extra;
|
|
green += extra;
|
|
blue += extra;
|
|
}
|
|
|
|
if (g_Rooms[roomnum].lightop == LIGHTOP_5) {
|
|
scenarioHighlightRoom(roomnum, &red, &green, &blue);
|
|
}
|
|
|
|
if (red > 255) {
|
|
red = 255;
|
|
}
|
|
|
|
if (green > 255) {
|
|
green = 255;
|
|
}
|
|
|
|
if (blue > 255) {
|
|
blue = 255;
|
|
}
|
|
|
|
if (red < 0) {
|
|
red = 0;
|
|
}
|
|
|
|
if (green < 0) {
|
|
green = 0;
|
|
}
|
|
|
|
if (blue < 0) {
|
|
blue = 0;
|
|
}
|
|
|
|
dst[i].r = red;
|
|
dst[i].g = green;
|
|
dst[i].b = blue;
|
|
dst[i].a = alpha;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void func0f004c6c(void)
|
|
{
|
|
s32 sp44;
|
|
s32 sp40;
|
|
s32 sp3c;
|
|
s32 sp38;
|
|
s32 sp34;
|
|
s32 i;
|
|
s32 j;
|
|
s32 s4;
|
|
u8 *ptr;
|
|
u8 *backupptr;
|
|
|
|
sp44 = ALIGN16(0x2000);
|
|
sp40 = ALIGN16(g_NumPortals * 4);
|
|
sp3c = ALIGN16(g_NumPortals * 0xc);
|
|
sp38 = ALIGN16(g_NumPortals * 4);
|
|
sp34 = ALIGN16(g_NumPortals * 2);
|
|
|
|
for (i = 0, s4 = sp38; i < g_NumPortals; i++) {
|
|
if (i != 0) {
|
|
s4 += i * 2;
|
|
}
|
|
}
|
|
|
|
s4 = ALIGN16(s4);
|
|
ptr = mempAlloc(ALIGN16(s4), MEMPOOL_STAGE);
|
|
var80061430 = (void *)ptr;
|
|
|
|
ptr += sp38;
|
|
|
|
for (i = 0; i < g_NumPortals; i++) {
|
|
if (i != 0) {
|
|
var80061430[i] = (void *)ptr;
|
|
ptr += i * 2;
|
|
} else {
|
|
var80061430[i] = 0;
|
|
}
|
|
}
|
|
|
|
s4 += sp3c;
|
|
s4 += sp44;
|
|
s4 += sp40;
|
|
s4 += sp38;
|
|
s4 += g_NumPortals * sp34;
|
|
|
|
ptr = mempGetNextStageAllocation();
|
|
var8009cad0 = (void *)ptr;
|
|
ptr += sp44;
|
|
|
|
var8009cad8 = (void *)ptr;
|
|
ptr += sp40;
|
|
|
|
var8006142c = (void *)ptr;
|
|
ptr += sp38;
|
|
|
|
backupptr = ptr;
|
|
|
|
ptr += g_NumPortals * sp34;
|
|
var80061428 = (void *)ptr;
|
|
ptr = backupptr;
|
|
|
|
s4 = sp38;
|
|
|
|
for (i = 0; i < g_NumPortals; i++) {
|
|
var8006142c[i] = (void *)ptr;
|
|
ptr += sp34;
|
|
s4 += sp34;
|
|
|
|
for (j = 0; j < g_NumPortals; j++) {
|
|
var8006142c[i][j] = 0x8009;
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < g_NumPortals; i++) {
|
|
var8009cad8[i] = portalGetXluFrac(i) > 0.5f;
|
|
|
|
portalGetAvgVertexPos(i, &var80061428[i]);
|
|
}
|
|
|
|
if (g_Vars.stagenum == STAGE_INVESTIGATION) {
|
|
var8009cad8[0] = 1;
|
|
}
|
|
|
|
for (i = 0; i < g_NumPortals; i++) {
|
|
var8006142c[i][i] = 0;
|
|
}
|
|
|
|
func0f00505c();
|
|
|
|
for (i = 0; i < g_NumPortals; i++) {
|
|
for (j = 0; j < i; j++) {
|
|
u16 a = var8006142c[i][j];
|
|
u16 b = var8006142c[j][i];
|
|
|
|
var80061430[i][j] = a < b ? a : b;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void func0f00505c(void)
|
|
{
|
|
s32 j;
|
|
s32 sp78;
|
|
s32 i;
|
|
s32 k;
|
|
s32 portalnum;
|
|
s32 portalnum2;
|
|
s32 roomnum;
|
|
s32 l;
|
|
u16 dist;
|
|
u32 stack;
|
|
|
|
for (i = 0; i < g_NumPortals; i++) {
|
|
for (j = 0, var8009cad0[0] = i, sp78 = 1; j != sp78; j = (j + 1) & 0x7ff) {
|
|
portalnum = var8009cad0[j];
|
|
|
|
for (k = 0; k < 2; k++) {
|
|
if (k != 0) {
|
|
roomnum = g_BgPortals[portalnum].roomnum2;
|
|
} else {
|
|
roomnum = g_BgPortals[portalnum].roomnum1;
|
|
}
|
|
|
|
for (l = 0; l < g_Rooms[roomnum].numportals; l++) {
|
|
portalnum2 = g_RoomPortals[g_Rooms[roomnum].roomportallistoffset + l];
|
|
|
|
if (portalnum2 != portalnum && var8009cad8[portalnum2] != 0) {
|
|
if (var8006142c[portalnum][portalnum2] >= 0x8000) {
|
|
f32 xdiff = var80061428[portalnum].x - var80061428[portalnum2].x;
|
|
f32 ydiff = var80061428[portalnum].y - var80061428[portalnum2].y;
|
|
f32 zdiff = var80061428[portalnum].z - var80061428[portalnum2].z;
|
|
|
|
f32 dist = sqrtf(xdiff * xdiff + ydiff * ydiff + zdiff * zdiff);
|
|
|
|
var8006142c[portalnum][portalnum2] = dist;
|
|
var8006142c[portalnum2][portalnum] = dist;
|
|
}
|
|
|
|
dist = (var8006142c[i][portalnum] + var8006142c[portalnum2][portalnum]);
|
|
|
|
if (dist <= 5800 && ((i == portalnum) != 0 || dist < var8006142c[i][portalnum2])) {
|
|
var8006142c[i][portalnum2] = dist;
|
|
var8009cad0[sp78] = portalnum2;
|
|
sp78 = (sp78 + 1) & 0x7ff;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static f32 func0f0053d0(s32 roomnum1, struct coord *pos1, s32 portalnum1, s32 roomnum2, struct coord *pos2, s32 portalnum2, f32 *arg6)
|
|
{
|
|
f32 sp6c;
|
|
f32 *sp68;
|
|
f32 sp64;
|
|
f32 xdiff;
|
|
f32 ydiff;
|
|
f32 zdiff;
|
|
|
|
sp6c = 32767.0f;
|
|
sp68 = arg6 ? arg6 : &sp6c;
|
|
sp64 = *sp68;
|
|
|
|
xdiff = pos1->x - pos2->x;
|
|
xdiff = xdiff > 0.0f ? xdiff : -xdiff;
|
|
|
|
if (xdiff < sp64) {
|
|
zdiff = pos1->z - pos2->z;
|
|
zdiff = zdiff > 0.0f ? zdiff : -zdiff;
|
|
|
|
if (zdiff < sp64) {
|
|
ydiff = pos1->y - pos2->y;
|
|
ydiff = ydiff > 0.0f ? ydiff : -ydiff;
|
|
|
|
if (ydiff < sp64) {
|
|
f32 dist = sqrtf(xdiff * xdiff + ydiff * ydiff + zdiff * zdiff);
|
|
|
|
if (dist < sp64) {
|
|
if (roomnum1 == roomnum2 || portalnum1 == portalnum2) {
|
|
if (dist < *sp68) {
|
|
*sp68 = dist;
|
|
}
|
|
} else {
|
|
f32 sp50 = func0f000920(portalnum1, portalnum2);
|
|
|
|
if (sp50 < sp64) {
|
|
struct coord sp44;
|
|
f32 xdiff2;
|
|
f32 zdiff2;
|
|
|
|
portalGetAvgVertexPos(portalnum1, &sp44);
|
|
sp64 -= sp50;
|
|
|
|
xdiff2 = sp44.x - pos1->x;
|
|
xdiff2 = xdiff2 > 0.0f ? xdiff2 : -xdiff2;
|
|
|
|
if (xdiff2 < sp64) {
|
|
zdiff2 = sp44.z - pos1->z;
|
|
zdiff2 = zdiff2 > 0.0f ? zdiff2 : -zdiff2;
|
|
|
|
if (zdiff2 < sp64) {
|
|
f32 sp38 = sqrtf(xdiff2 * xdiff2 + zdiff2 * zdiff2);
|
|
|
|
if (sp38 < sp64) {
|
|
struct coord sp2c;
|
|
f32 xdiff3;
|
|
f32 zdiff3;
|
|
|
|
portalGetAvgVertexPos(portalnum2, &sp2c);
|
|
sp64 -= sp38;
|
|
|
|
xdiff3 = sp2c.x - pos2->x;
|
|
xdiff3 = xdiff3 > 0.0f ? xdiff3 : -xdiff3;
|
|
|
|
if (xdiff3 < sp64) {
|
|
zdiff3 = sp2c.z - pos2->z;
|
|
zdiff3 = zdiff3 > 0.0f ? zdiff3 : -zdiff3;
|
|
|
|
if (zdiff3 < sp64) {
|
|
f32 dist3 = sqrtf(xdiff3 * xdiff3 + zdiff3 * zdiff3);
|
|
|
|
if (dist3 < sp64) {
|
|
sp64 -= dist3;
|
|
*sp68 -= sp64;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return *sp68;
|
|
}
|
|
|
|
void func0f0056f4(s32 roomnum1, struct coord *pos1, s32 roomnum2, struct coord *pos2, s32 arg4, f32 *result, s32 arg6)
|
|
{
|
|
f32 dist;
|
|
|
|
if (PLAYERCOUNT() >= 3
|
|
|| roomnum1 == roomnum2
|
|
|| roomnum1 == -1
|
|
|| roomnum2 == -1) {
|
|
f32 xdist = pos1->x - pos2->x;
|
|
|
|
if (!(xdist > 0.0f)) {
|
|
xdist = -xdist;
|
|
}
|
|
|
|
if (xdist < *result) {
|
|
f32 zdist = pos1->z - pos2->z;
|
|
|
|
if (!(zdist > 0.0f)) {
|
|
zdist = -zdist;
|
|
}
|
|
|
|
if (zdist < *result) {
|
|
f32 ydist = pos1->y - pos2->y;
|
|
|
|
if (!(ydist > 0.0f)) {
|
|
ydist = -ydist;
|
|
}
|
|
|
|
if (ydist < *result) {
|
|
dist = sqrtf(xdist * xdist + ydist * ydist + zdist * zdist);
|
|
|
|
if (dist < *result) {
|
|
*result = dist;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
s32 portalnum1;
|
|
s32 portalnum2;
|
|
s32 i;
|
|
s32 j;
|
|
|
|
for (i = 0; i < g_Rooms[roomnum1].numportals; i++) {
|
|
portalnum1 = g_RoomPortals[g_Rooms[roomnum1].roomportallistoffset + i];
|
|
|
|
for (j = 0; j < g_Rooms[roomnum2].numportals; j++) {
|
|
portalnum2 = g_RoomPortals[g_Rooms[roomnum2].roomportallistoffset + j];
|
|
|
|
dist = func0f0053d0(roomnum1, pos1, portalnum1, roomnum2, pos2, portalnum2, result);
|
|
|
|
if (dist < *result) {
|
|
*result = dist;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This function:
|
|
* - Controls the sound effects for the night vision and IR scanner.
|
|
* - Sets g_IsSwitchingGoggles if equipping or unequipping NV/IR on this frame.
|
|
* - Updates the player's usinggoggles property.
|
|
*/
|
|
static void func0f005bb0(void)
|
|
{
|
|
s32 brightness = func0f0009c0(g_Vars.currentplayer->prop->rooms[0]);
|
|
|
|
if (((USINGDEVICE(DEVICE_NIGHTVISION) || USINGDEVICE(DEVICE_IRSCANNER)) && !g_Vars.currentplayer->usinggoggles)
|
|
|| ((!USINGDEVICE(DEVICE_NIGHTVISION) && !USINGDEVICE(DEVICE_IRSCANNER)) && g_Vars.currentplayer->usinggoggles)) {
|
|
g_IsSwitchingGoggles = true;
|
|
}
|
|
|
|
g_Vars.currentplayer->usinggoggles = USINGDEVICE(DEVICE_NIGHTVISION) || USINGDEVICE(DEVICE_IRSCANNER);
|
|
|
|
if (USINGDEVICE(DEVICE_NIGHTVISION) && !lvIsPaused()) {
|
|
// Play the goggle's hum sound
|
|
if (g_Vars.currentplayer->nvhum == NULL) {
|
|
sndStart(var80095200, SFX_0505, &g_Vars.currentplayer->nvhum, -1, -1, -1.0f, -1, -1);
|
|
}
|
|
|
|
if (brightness > 128) {
|
|
// Room is too bright for night vision - play overload sound
|
|
if (g_Vars.currentplayer->nvoverload == NULL) {
|
|
sndStart(var80095200, SFX_01BE, &g_Vars.currentplayer->nvoverload, -1, -1, -1.0f, -1, -1);
|
|
}
|
|
} else {
|
|
// Room is dark enough for night vision - stop overload sound if active
|
|
if (g_Vars.currentplayer->nvoverload != NULL) {
|
|
if (sndGetState(g_Vars.currentplayer->nvoverload) != AL_STOPPED) {
|
|
audioStop(g_Vars.currentplayer->nvoverload);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
// Paused or not wearing night vision - stop both sounds
|
|
if (g_Vars.currentplayer->nvhum != NULL) {
|
|
if (sndGetState(g_Vars.currentplayer->nvhum) != NULL) {
|
|
audioStop(g_Vars.currentplayer->nvhum);
|
|
}
|
|
}
|
|
|
|
if (g_Vars.currentplayer->nvoverload != NULL) {
|
|
if (sndGetState(g_Vars.currentplayer->nvoverload) != NULL) {
|
|
audioStop(g_Vars.currentplayer->nvoverload);
|
|
}
|
|
}
|
|
}
|
|
}
|