/* ** Command & Conquer Renegade(tm) ** Copyright 2025 Electronic Arts Inc. ** ** This program is free software: you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation, either version 3 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program. If not, see . */ /*********************************************************************************************** *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** *********************************************************************************************** * * * Project Name : Commando * * * * $Archive:: /Commando/Code/Combat/backgroundmgr.h $* * * * Author:: Patrick Smith * * * * $Modtime:: 1/15/02 7:26p $* * * * $Revision:: 25 $* * * *---------------------------------------------------------------------------------------------* * Functions: * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #ifndef __BACKGROUNDMGR_H #define __BACKGROUNDMGR_H // Includes. #include "combat.h" #include "combatchunkid.h" #include "dx8indexbuffer.h" #include "networkobject.h" #include "rendobj.h" #include "saveloadsubsystem.h" #include "segline.h" #include "shader.h" #include "vector3.h" #include "vector3i.h" #include "vertmaterial.h" #include "wwdebug.h" // Forward declarations. class CameraClass; class DazzleRenderObjClass; class SimpleSceneClass; class TextureClass; class SoundEnvironmentClass; // Classes. class VisibilityClass { public: VisibilityClass() {Visible = true;} bool Is_Visible() {return (Visible);} void Set_Visibility (bool visible) {Visible = visible;} private : bool Visible; }; class HazeClass : public VisibilityClass { public: HazeClass (float radius); ~HazeClass(); void Configure (const Vector3 &blendcolor, const Vector3 &horizoncolor, float intensity); void Configure (const Vector3 &blendcolor, const Vector3 &horizoncolor); void Configure (const Vector3 &blendcolor, float intensity); void Configure (const Vector3 &blendcolor); Vector3 Get_Horizon_Color() {return (HorizonColor * Intensity);} void Render(); protected: enum { ROW_COUNT = 3, VERTICES_PER_TRIANGLE = 3 }; void Configure(); Vector3 BlendColor; Vector3 HorizonColor; float Intensity; unsigned RowCount; unsigned VertexCount; Vector3 *VertexArray; unsigned TriangleCount; DX8IndexBufferClass *IndexBuffer; unsigned *DiffuseArray; VertexMaterialClass *Material; ShaderClass Shader; }; class StarfieldClass : public VisibilityClass { public: StarfieldClass (float radius, unsigned starcount); ~StarfieldClass(); void Configure (const Vector3 &orientation, float length, float radius, const Vector3 &color0, const Vector3 &color1, float alpha); void Configure (const Vector3 &orientation, float length, float radius); void Configure (const Vector3 &color0, const Vector3 &color1, float alpha); void Render(); protected: void Configure(); enum { VERTICES_PER_TRIANGLE = 3 }; Vector3 Orientation; float Length; float Radius; Vector3 Color0, Color1; float Alpha; unsigned VertexCount; Vector3 *VertexArray; unsigned TriangleCount; DX8IndexBufferClass *IndexBuffer; VertexMaterialClass *Material; ShaderClass Shader; TextureClass *Texture; unsigned *DiffuseArray; unsigned ActiveVertexCount; unsigned ActiveTriangleCount; }; class SkyObjectClass : public VisibilityClass { public: SkyObjectClass (ShaderClass shader); ~SkyObjectClass(); void Configure (const Vector3 &direction, float length, float radius, const Vector3 &color); void Configure (const Vector3 &direction, float length, float width, float height); void Configure (const Vector3 &direction, float length, float radius); void Configure (const Vector3 &color); void Set_Texture (const char *texturename); Vector3 Get_Color() {return (Color);} void Render(); protected: enum { VERTICES_PER_TRIANGLE = 3 }; void Configure(); Vector3 Direction; float Length; float Width; float Height; Vector3 Color; unsigned VertexCount; Vector3 *VertexArray; unsigned TriangleCount; DX8IndexBufferClass *IndexBuffer; VertexMaterialClass *Material; ShaderClass Shader; TextureClass *Texture; Vector2 *TexCoordArray; unsigned *DiffuseArray; }; class CloudLayerClass : public VisibilityClass { public: CloudLayerClass (float maxdistance, const char *texturename, const Vector2 &velocity, float tilefactor, bool rotate); ~CloudLayerClass(); void Configure (const Vector3 &warmcolor, const Vector3 &coldcolor); void Configure (const Vector3 &warmdirection); void Configure (const Vector3 &warmcolor, const Vector3 &coldcolor, const Vector3 &warmdirection); void Configure (float alpha, float cloudintensity, float horizonintensity); void Render(); protected: enum { VERTICES_PER_TRIANGLE = 3 }; void Configure(); Vector3 WarmColor; Vector3 ColdColor; Vector3 WarmDirection; float Alpha; float CloudIntensity; float HorizonIntensity; unsigned RowCount; unsigned VertexCount; Vector3 *VertexArray; unsigned TriangleCount; DX8IndexBufferClass *IndexBuffer; VertexMaterialClass *Material; ShaderClass Shader; TextureClass *Texture; Vector2 *TexCoordArray; Vector2 Velocity; unsigned *DiffuseArray; }; class SkyGlowClass : public VisibilityClass { public: SkyGlowClass (float radius); ~SkyGlowClass(); void Configure (const Vector2 &hotdirection, const Vector3 &horizoncolor, float coldintensity); void Render(); protected: enum { ROW_COUNT = 5, VERTICES_PER_TRIANGLE = 3 }; void Configure(); Vector2 HotDirection; Vector3 HorizonColor; float ColdIntensity; unsigned RowCount; float Radius; float MinZ, MaxZ; unsigned VertexCount; Vector3 *VertexArray; unsigned TriangleCount; DX8IndexBufferClass *IndexBuffer; unsigned *DiffuseArray; VertexMaterialClass *Material; ShaderClass Shader; }; class LightningBoltClass : public VisibilityClass, public SegmentedLineClass { public: LightningBoltClass::LightningBoltClass (int branchcount, Matrix3D &m, float length, float childlength, float width, float amplitude); ~LightningBoltClass (); void Configure (Vector3 &color); virtual void Set_Transform (Matrix3D &t); virtual void Render (RenderInfoClass &rinfo); void Set_Visibility (bool visible, bool recurse); private: struct BranchStruct { LightningBoltClass *LightningBolt; }; BranchStruct *Branches; int BranchCount; }; class LightningClass { public: LightningClass (float extent, float startdistance, float enddistance, float heading, float distribution); ~LightningClass(); bool Update (Matrix3D &t, Vector3 &additivecolor, SoundEnvironmentClass *soundenvironment); void Render (RenderInfoClass &rinfo); private: SkyGlowClass *LightningGlow; LightningBoltClass *LightningBolt; SkyObjectClass *LightningSource; Vector2 Direction; float Distance; unsigned Time; unsigned ThunderDelayTime; Vector3 ThunderPosition; const char *ThunderSampleName; bool PlayedThunder; }; class WarBlitzClass { public: WarBlitzClass (float extent, float startdistance, float enddistance, float heading, float distribution); ~WarBlitzClass(); bool Update (Matrix3D &t, Vector3 &additivecolor); void Render (RenderInfoClass &rinfo); private: SkyGlowClass *WarBlitzGlow; Vector2 Direction; float Distance; unsigned Time; unsigned SampleDelayTime; Vector3 SamplePosition; bool PlayedSample; }; class SkyClass : public RenderObjClass { public: enum MoonTypeEnum { MOON_TYPE_FULL, MOON_TYPE_PART, MOON_TYPE_COUNT }; SkyClass (SoundEnvironmentClass *soundenvironment); ~SkyClass(); RenderObjClass *Clone() const { WWASSERT (false); return (0); } void Set_Color(); Vector3 Get_Color() {return (Color);} SkyObjectClass *Get_Sun() {return (Sun);} void Set_Light_Direction (const Vector3 &sundirection, const Vector3 &moondirection); void Set_Time_Of_Day (unsigned hours, unsigned minutes); void Set_Moon_Type (MoonTypeEnum moontype); void Set_Clouds (float cloudcover, float gloominess); void Set_Tint_Factor (float tintfactor); void Set_Lightning (float intensity, float startdistance, float enddistance, float heading, float distribution) { LightningIntensity = intensity; LightningStartDistance = startdistance; LightningEndDistance = enddistance; LightningHeading = DEG_TO_RADF (heading); LightningDistribution = distribution; } void Set_War_Blitz (float intensity, float startdistance, float enddistance, float heading, float distribution) { WarBlitzIntensity = intensity; WarBlitzStartDistance = startdistance; WarBlitzEndDistance = enddistance; WarBlitzHeading = DEG_TO_RADF (heading); WarBlitzDistribution = distribution; } void Update (SceneClass *mainscene, const Vector3 &cameraposition); void Render (RenderInfoClass &rinfo); void Get_Obj_Space_Bounding_Sphere (SphereClass &sphere) const; void Get_Obj_Space_Bounding_Box (AABoxClass &box) const; protected: enum { LIGHTNING_COUNT = 2 }; Vector3 Interpolate_Color (const unsigned char colortable [][3], unsigned colorcount, float interpolant); float Interpolate_Scalar (const unsigned char scalartable [], unsigned scalarcount, float interpolant); unsigned Lightning_Delay(); unsigned War_Blitz_Delay(); float Extent; // Radius of sphere (and half cube width) which contains all sky objects (for clipping purposes). Vector3 Color; unsigned Hours, Minutes; float Gloominess; float TintFactor; HazeClass *Haze; StarfieldClass *Starfield; SkyObjectClass *Sun; SkyObjectClass *SunHalo; SkyObjectClass *Moon; SkyObjectClass *MoonHalo; CloudLayerClass *CloudLayer0; CloudLayerClass *CloudLayer1; LightningClass *Lightning [LIGHTNING_COUNT]; int LightningCountdown [LIGHTNING_COUNT]; float LightningIntensity; float LightningStartDistance; float LightningEndDistance; float LightningHeading; float LightningDistribution; SoundEnvironmentClass *SoundEnvironment; WarBlitzClass *WarBlitz; int WarBlitzCountdown; float WarBlitzIntensity; float WarBlitzStartDistance; float WarBlitzEndDistance; float WarBlitzHeading; float WarBlitzDistribution; }; class BackgroundParameterClass { public: void Initialize(); void Set (float targetvalue, float ramptime, bool override); void Set (float overrideramptime) {OverrideDuration = overrideramptime;} float Value() {return (CurrentValue);} bool Update (float time, bool override); void Update (float &value, float &target, float &duration, float time); private: float CurrentValue; float NormalValue; float NormalTarget; float NormalDuration; float OverrideTarget; float OverrideDuration; friend class BackgroundMgrClass; }; class BackgroundMgrClass : public SaveLoadSubSystemClass, public NetworkObjectClass { public: enum LightSourceTypeEnum { LIGHT_SOURCE_TYPE_SUN, LIGHT_SOURCE_TYPE_MOON }; BackgroundMgrClass(); ~BackgroundMgrClass() {} uint32 Chunk_ID() const {return (CHUNKID_BACKGROUND_MGR);} const char *Name() const {return ("BackgroundMgrClass");} void Delete (void) {} virtual void Set_Delete_Pending (void) {}; bool Save (ChunkSaveClass &csave); bool Load (ChunkLoadClass &cload); bool Load_Micro_Chunks (ChunkLoadClass &cload); void Export_Rare (BitStreamClass &packet); void Import_Rare (BitStreamClass &packet); static void Init (SimpleSceneClass *renderscene, SoundEnvironmentClass *soundenvironment, bool render_available = true); static void Reset(); static void Shutdown(); static bool Save_Dynamic (ChunkSaveClass &csave); static bool Load_Dynamic (ChunkLoadClass &cload); static bool Load_Dynamic_Micro_Chunks (ChunkLoadClass &cload); static Vector3 Get_Clear_Color() { if (_Sky != NULL) { return (_Sky->Get_Color()); } else { return (Vector3 (0.0f, 0.0f, 0.0f)); } } static bool Set_Time_Of_Day (unsigned hours, unsigned minutes) { if ((hours >= 0) && (hours <= 23) && (minutes >= 0) && (minutes <= 59)) { _Hours = hours; _Minutes = minutes; Set_Dirty(); return (true); } else { return (false); } } static void Get_Time_Of_Day (unsigned &hours, unsigned &minutes) { hours = _Hours; minutes = _Minutes; } static void Set_Light_Source_Type (LightSourceTypeEnum lightsourcetype) { _LightSourceType = lightsourcetype; Set_Dirty(); } static LightSourceTypeEnum Get_Light_Source_Type() {return (_LightSourceType);} static void Set_Moon_Type (SkyClass::MoonTypeEnum moontype) { _MoonType = moontype; Set_Dirty(); } static SkyClass::MoonTypeEnum Get_Moon_Type() { return (_MoonType); } static bool Set_Clouds (float cloudcover, float cloudgloominess, float ramptime = 0.0f); static bool Override_Clouds (float cloudcover, float cloudgloominess, float ramptime = 0.0f); static void Get_Clouds (float &cloudcover, float &gloominess); static void Restore_Clouds (float ramptime); static bool Set_Sky_Tint (float skytintfactor, float ramptime = 0.0f); static bool Override_Sky_Tint (float skytintfactor, float ramptime = 0.0f); static void Restore_Sky_Tint (float ramptime); static bool Set_Lightning_Intensity (float intensity, float ramptime = 0.0f); static bool Set_Lightning (float intensity, float startdistance, float enddistance, float heading, float distribution, float ramptime = 0.0f); static bool Override_Lightning (float intensity, float startdistance, float enddistance, float heading, float distribution, float ramptime = 0.0f); static void Get_Lightning (float &intensity, float &startdistance, float &enddistance, float &heading, float &distribution); static void Restore_Lightning (float ramptime); static bool Set_War_Blitz (float intensity, float ramptime = 0.0f); static bool Set_War_Blitz (float intensity, float startdistance, float enddistance, float heading, float distribution, float ramptime = 0.0f, bool override = false); static void Get_War_Blitz (float &intensity, float &startdistance, float &enddistance, float &heading, float &distribution); static void Update (PhysicsSceneClass *mainscene, CameraClass *camera); private: #define VARID_PARAMETER(varname) \ VARID_ ## varname ## _CURRENT_VALUE, \ VARID_ ## varname ## _NORMAL_VALUE, \ VARID_ ## varname ## _NORMAL_TARGET, \ VARID_ ## varname ## _NORMAL_DURATION, \ VARID_ ## varname ## _OVERRIDE_TARGET, \ VARID_ ## varname ## _OVERRIDE_DURATION // Constants. enum { CHUNKID_MICRO_CHUNKS = 0x11080732, CHUNKID_DYNAMIC_MICRO_CHUNKS = 0x11020216 }; enum { VARID_TIME_HOURS = 0x14, VARID_TIME_MINUTES, VARID_LIGHT_SOURCE_TYPE, VARID_MOON_TYPE, VARID_PARAMETER (CLOUD_COVER), VARID_PARAMETER (CLOUD_GLOOMINESS), VARID_PARAMETER (SKY_TINT_FACTOR), VARID_PARAMETER (LIGHTNING_INTENSITY), VARID_PARAMETER (LIGHTNING_START_DISTANCE), VARID_PARAMETER (LIGHTNING_END_DISTANCE), VARID_PARAMETER (LIGHTNING_HEADING), VARID_PARAMETER (LIGHTNING_DISTRIBUTION), VARID_CLOUD_OVERRIDE_COUNT, VARID_LIGHTNING_OVERRIDE_COUNT, VARID_PARAMETER (WAR_BLITZ_INTENSITY), VARID_PARAMETER (WAR_BLITZ_START_DISTANCE), VARID_PARAMETER (WAR_BLITZ_END_DISTANCE), VARID_PARAMETER (WAR_BLITZ_HEADING), VARID_PARAMETER (WAR_BLITZ_DISTRIBUTION), VARID_SKY_TINT_OVERRIDE_COUNT }; #undef VARID_PARAMETER enum { PARAMETER_CLOUD_COVER, PARAMETER_CLOUD_GLOOMINESS, PARAMETER_SKY_TINT_FACTOR, PARAMETER_LIGHTNING_INTENSITY, PARAMETER_LIGHTNING_START_DISTANCE, PARAMETER_LIGHTNING_END_DISTANCE, PARAMETER_LIGHTNING_HEADING, PARAMETER_LIGHTNING_DISTRIBUTION, PARAMETER_WAR_BLITZ_INTENSITY, PARAMETER_WAR_BLITZ_START_DISTANCE, PARAMETER_WAR_BLITZ_END_DISTANCE, PARAMETER_WAR_BLITZ_HEADING, PARAMETER_WAR_BLITZ_DISTRIBUTION, PARAMETER_COUNT }; static bool Set_Clouds (float cloudcover, float cloudgloominess, float ramptime, bool override); static bool Set_Sky_Tint (float skytintfactor, float ramptime, bool override); static bool Set_Lightning_Intensity (float intensity, float ramptime, bool override); static bool Set_Lightning (float intensity, float startdistance, float enddistance, float heading, float distribution, float ramptime, bool override); static bool Is_Dirty() {return (_Dirty);} static void Set_Dirty (bool dirty = true) {_Dirty = dirty;} static unsigned _Hours; static unsigned _Minutes; static LightSourceTypeEnum _LightSourceType; static SkyClass::MoonTypeEnum _MoonType; static BackgroundParameterClass _Parameters [PARAMETER_COUNT]; static Vector3 _LightVector; static Vector3 _UnitLightVector; static unsigned _CloudOverrideCount; static unsigned _LightningOverrideCount; static unsigned _SkyTintOverrideCount; static bool _Dirty; static bool _FogEnabled; static SkyClass *_Sky; static DazzleRenderObjClass *_Dazzle; }; // Externals. extern BackgroundMgrClass _TheBackgroundMgr; #endif // BACKGROUNDMGR_H