mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-12-13 13:50:59 +00:00
0f2938089d
This is supposed to be come the place where all pure play code should be placed, but for that all CVARs and CCMDs and other things that do not directly handle play data should be taken out to make code reviewing easier. These now get collected in two separate files, g_cvars.cpp and g_dumpinfo.cpp respectively. The sole ZScript property in here has also been moved - to thingdef_properties.cpp.
249 lines
7.1 KiB
C++
249 lines
7.1 KiB
C++
#pragma once
|
|
#include "c_cvars.h"
|
|
#include "actor.h"
|
|
#include "cycler.h"
|
|
#include "g_levellocals.h"
|
|
|
|
struct side_t;
|
|
struct seg_t;
|
|
|
|
class FSerializer;
|
|
struct FSectionLine;
|
|
|
|
enum ELightType
|
|
{
|
|
PointLight,
|
|
PulseLight,
|
|
FlickerLight,
|
|
RandomFlickerLight,
|
|
SectorLight,
|
|
DummyLight,
|
|
ColorPulseLight,
|
|
ColorFlickerLight,
|
|
RandomColorFlickerLight
|
|
};
|
|
|
|
enum
|
|
{
|
|
LIGHT_RED = 0,
|
|
LIGHT_GREEN = 1,
|
|
LIGHT_BLUE = 2,
|
|
LIGHT_INTENSITY = 3,
|
|
LIGHT_SECONDARY_INTENSITY = 4,
|
|
};
|
|
|
|
enum LightFlag
|
|
{
|
|
LF_SUBTRACTIVE = 1,
|
|
LF_ADDITIVE = 2,
|
|
LF_DONTLIGHTSELF = 4,
|
|
LF_ATTENUATE = 8,
|
|
LF_NOSHADOWMAP = 16,
|
|
LF_DONTLIGHTACTORS = 32,
|
|
LF_SPOT = 64
|
|
};
|
|
|
|
typedef TFlags<LightFlag> LightFlags;
|
|
DEFINE_TFLAGS_OPERATORS(LightFlags)
|
|
|
|
//==========================================================================
|
|
//
|
|
// Light definitions
|
|
//
|
|
//==========================================================================
|
|
class FLightDefaults
|
|
{
|
|
public:
|
|
FLightDefaults(FName name, ELightType type);
|
|
|
|
void ApplyProperties(FDynamicLight * light) const;
|
|
FName GetName() const { return m_Name; }
|
|
void SetParameter(double p) { m_Param = p; }
|
|
void SetArg(int arg, int val) { m_Args[arg] = val; }
|
|
int GetArg(int arg) { return m_Args[arg]; }
|
|
uint8_t GetAttenuate() const { return m_attenuate; }
|
|
void SetOffset(float* ft) { m_Pos.X = ft[0]; m_Pos.Z = ft[1]; m_Pos.Y = ft[2]; }
|
|
void SetSubtractive(bool subtract) { if (subtract) m_lightFlags |= LF_SUBTRACTIVE; else m_lightFlags &= ~LF_SUBTRACTIVE; }
|
|
void SetAdditive(bool add) { if (add) m_lightFlags |= LF_ADDITIVE; else m_lightFlags &= ~LF_ADDITIVE; }
|
|
void SetDontLightSelf(bool add) { if (add) m_lightFlags |= LF_DONTLIGHTSELF; else m_lightFlags &= ~LF_DONTLIGHTSELF; }
|
|
void SetAttenuate(bool on) { m_attenuate = on; if (on) m_lightFlags |= LF_ATTENUATE; else m_lightFlags &= ~LF_ATTENUATE; }
|
|
void SetDontLightActors(bool on) { if (on) m_lightFlags |= LF_DONTLIGHTACTORS; else m_lightFlags &= ~LF_DONTLIGHTACTORS; }
|
|
void SetNoShadowmap(bool on) { if (on) m_lightFlags |= LF_NOSHADOWMAP; else m_lightFlags &= ~LF_NOSHADOWMAP; }
|
|
void SetSpot(bool spot) { if (spot) m_lightFlags |= LF_SPOT; else m_lightFlags &= ~LF_SPOT; }
|
|
void SetSpotInnerAngle(double angle) { m_spotInnerAngle = angle; }
|
|
void SetSpotOuterAngle(double angle) { m_spotOuterAngle = angle; }
|
|
static void SetAttenuationForLevel(bool);
|
|
|
|
void OrderIntensities()
|
|
{
|
|
if (m_Args[LIGHT_INTENSITY] > m_Args[LIGHT_SECONDARY_INTENSITY])
|
|
{
|
|
std::swap(m_Args[LIGHT_INTENSITY], m_Args[LIGHT_SECONDARY_INTENSITY]);
|
|
m_swapped = true;
|
|
}
|
|
}
|
|
|
|
protected:
|
|
FName m_Name = NAME_None;
|
|
int m_Args[5] = { 0,0,0,0,0 };
|
|
double m_Param = 0;
|
|
DVector3 m_Pos = { 0,0,0 };
|
|
ELightType m_type;
|
|
int8_t m_attenuate = -1;
|
|
LightFlags m_lightFlags = 0;
|
|
bool m_swapped = false;
|
|
bool m_spot = false;
|
|
bool m_explicitPitch = false;
|
|
DAngle m_spotInnerAngle = 10.0;
|
|
DAngle m_spotOuterAngle = 25.0;
|
|
DAngle m_pitch = 0.0;
|
|
};
|
|
|
|
//==========================================================================
|
|
//
|
|
// Light associations (intermediate parser data)
|
|
//
|
|
//==========================================================================
|
|
|
|
class FLightAssociation
|
|
{
|
|
public:
|
|
//FLightAssociation();
|
|
FLightAssociation(FName actorName, const char *frameName, FName lightName)
|
|
: m_ActorName(actorName), m_AssocLight(lightName)
|
|
{
|
|
strncpy(m_FrameName, frameName, 8);
|
|
}
|
|
|
|
FName ActorName() { return m_ActorName; }
|
|
const char *FrameName() { return m_FrameName; }
|
|
FName Light() { return m_AssocLight; }
|
|
void ReplaceLightName(FName newName) { m_AssocLight = newName; }
|
|
protected:
|
|
char m_FrameName[8];
|
|
FName m_ActorName, m_AssocLight;
|
|
};
|
|
|
|
|
|
//==========================================================================
|
|
//
|
|
// Light associations per actor class
|
|
//
|
|
//==========================================================================
|
|
|
|
class FInternalLightAssociation
|
|
{
|
|
public:
|
|
FInternalLightAssociation(FLightAssociation * asso);
|
|
int Sprite() const { return m_sprite; }
|
|
int Frame() const { return m_frame; }
|
|
const FLightDefaults *Light() const { return m_AssocLight; }
|
|
protected:
|
|
int m_sprite;
|
|
int m_frame;
|
|
FLightDefaults * m_AssocLight;
|
|
};
|
|
|
|
|
|
struct FLightNode
|
|
{
|
|
FLightNode ** prevTarget;
|
|
FLightNode * nextTarget;
|
|
FLightNode ** prevLight;
|
|
FLightNode * nextLight;
|
|
FDynamicLight * lightsource;
|
|
union
|
|
{
|
|
side_t * targLine;
|
|
subsector_t * targSubsector;
|
|
void * targ;
|
|
};
|
|
};
|
|
|
|
struct FDynamicLight
|
|
{
|
|
friend class FLightDefaults;
|
|
|
|
inline DVector3 PosRelative(int portalgroup) const
|
|
{
|
|
return Pos + Level->Displacements.getOffset(Sector->PortalGroup, portalgroup);
|
|
}
|
|
|
|
bool ShouldLightActor(AActor *check)
|
|
{
|
|
return visibletoplayer && IsActive() && (!((*pLightFlags) & LF_DONTLIGHTSELF) || target != check) && !((*pLightFlags) & LF_DONTLIGHTACTORS);
|
|
}
|
|
|
|
void SetOffset(const DVector3 &pos)
|
|
{
|
|
m_off = pos;
|
|
}
|
|
|
|
|
|
bool IsActive() const { return m_active; }
|
|
float GetRadius() const { return (IsActive() ? m_currentRadius * 2.f : 0.f); }
|
|
int GetRed() const { return pArgs[LIGHT_RED]; }
|
|
int GetGreen() const { return pArgs[LIGHT_GREEN]; }
|
|
int GetBlue() const { return pArgs[LIGHT_BLUE]; }
|
|
int GetIntensity() const { return pArgs[LIGHT_INTENSITY]; }
|
|
int GetSecondaryIntensity() const { return pArgs[LIGHT_SECONDARY_INTENSITY]; }
|
|
|
|
bool IsSubtractive() const { return !!((*pLightFlags) & LF_SUBTRACTIVE); }
|
|
bool IsAdditive() const { return !!((*pLightFlags) & LF_ADDITIVE); }
|
|
bool IsSpot() const { return !!((*pLightFlags) & LF_SPOT); }
|
|
bool IsAttenuated() const { return !!((*pLightFlags) & LF_ATTENUATE); }
|
|
bool DontShadowmap() const { return !!((*pLightFlags) & LF_NOSHADOWMAP); }
|
|
bool DontLightSelf() const { return !!((*pLightFlags) & (LF_DONTLIGHTSELF|LF_DONTLIGHTACTORS)); } // dontlightactors implies dontlightself.
|
|
bool DontLightActors() const { return !!((*pLightFlags) & LF_DONTLIGHTACTORS); }
|
|
void Deactivate() { m_active = false; }
|
|
void Activate();
|
|
|
|
void SetActor(AActor *ac, bool isowned) { target = ac; owned = isowned; }
|
|
double X() const { return Pos.X; }
|
|
double Y() const { return Pos.Y; }
|
|
double Z() const { return Pos.Z; }
|
|
|
|
void Tick();
|
|
void UpdateLocation();
|
|
void LinkLight();
|
|
void UnlinkLight();
|
|
void ReleaseLight();
|
|
|
|
private:
|
|
double DistToSeg(const DVector3 &pos, vertex_t *start, vertex_t *end);
|
|
void CollectWithinRadius(const DVector3 &pos, FSection *section, float radius);
|
|
|
|
public:
|
|
FCycler m_cycler;
|
|
DVector3 Pos;
|
|
DVector3 m_off;
|
|
|
|
// This date can either come from the owning actor or from a light definition
|
|
// To avoid having to copy these around every tic, these are pointers to the source data.
|
|
const DAngle *pSpotInnerAngle;
|
|
const DAngle *pSpotOuterAngle;
|
|
const DAngle *pPitch; // This is to handle pitch overrides through GLDEFS, it can either point to the target's pitch or the light definition.
|
|
const int *pArgs;
|
|
const LightFlags *pLightFlags;
|
|
|
|
double specialf1;
|
|
FDynamicLight *next, *prev;
|
|
sector_t *Sector;
|
|
FLevelLocals *Level;
|
|
TObjPtr<AActor *> target;
|
|
FLightNode * touching_sides;
|
|
FLightNode * touching_sector;
|
|
float radius; // The maximum size the light can be with its current settings.
|
|
float m_currentRadius; // The current light size.
|
|
int m_tickCount;
|
|
int m_lastUpdate;
|
|
int mShadowmapIndex;
|
|
bool m_active;
|
|
bool visibletoplayer;
|
|
bool shadowmapped;
|
|
uint8_t lighttype;
|
|
bool owned;
|
|
bool swapped;
|
|
bool explicitpitch;
|
|
|
|
};
|