diff --git a/Core/GameEngine/CMakeLists.txt b/Core/GameEngine/CMakeLists.txt index e486efe32e..cd3cb89e9e 100644 --- a/Core/GameEngine/CMakeLists.txt +++ b/Core/GameEngine/CMakeLists.txt @@ -69,7 +69,7 @@ set(GAMEENGINE_SRC # Include/Common/List.h Include/Common/LocalFile.h Include/Common/LocalFileSystem.h -# Include/Common/MapObject.h + Include/Common/MapObject.h # Include/Common/MapReaderWriterInfo.h # Include/Common/MessageStream.h Include/Common/MiniDumper.h @@ -204,7 +204,7 @@ set(GAMEENGINE_SRC # Include/GameClient/Line2D.h # Include/GameClient/LoadScreen.h # Include/GameClient/LookAtXlat.h -# Include/GameClient/MapUtil.h + Include/GameClient/MapUtil.h # Include/GameClient/MessageBox.h # Include/GameClient/MetaEvent.h # Include/GameClient/Module/AnimatedParticleSysBoneClientUpdate.h @@ -224,10 +224,10 @@ set(GAMEENGINE_SRC # Include/GameClient/ShellHooks.h # Include/GameClient/ShellMenuScheme.h Include/GameClient/Smudge.h -# Include/GameClient/Snow.h + Include/GameClient/Snow.h # Include/GameClient/Statistics.h -# Include/GameClient/TerrainRoads.h -# Include/GameClient/TerrainVisual.h + Include/GameClient/TerrainRoads.h + Include/GameClient/TerrainVisual.h Include/GameClient/VideoPlayer.h Include/GameClient/View.h Include/GameClient/Water.h @@ -807,7 +807,7 @@ set(GAMEENGINE_SRC # Source/GameClient/Input/Mouse.cpp # Source/GameClient/LanguageFilter.cpp # Source/GameClient/Line2D.cpp -# Source/GameClient/MapUtil.cpp + Source/GameClient/MapUtil.cpp # Source/GameClient/MessageStream/CommandXlat.cpp # Source/GameClient/MessageStream/GUICommandTranslator.cpp # Source/GameClient/MessageStream/HintSpy.cpp @@ -820,7 +820,7 @@ set(GAMEENGINE_SRC Source/GameClient/ParabolicEase.cpp # Source/GameClient/RadiusDecal.cpp # Source/GameClient/SelectionInfo.cpp -# Source/GameClient/Snow.cpp + Source/GameClient/Snow.cpp # Source/GameClient/Statistics.cpp # Source/GameClient/System/Anim2D.cpp # Source/GameClient/System/CampaignManager.cpp @@ -830,8 +830,8 @@ set(GAMEENGINE_SRC # Source/GameClient/System/ParticleSys.cpp # Source/GameClient/System/RayEffect.cpp Source/GameClient/System/Smudge.cpp -# Source/GameClient/Terrain/TerrainRoads.cpp -# Source/GameClient/Terrain/TerrainVisual.cpp + Source/GameClient/Terrain/TerrainRoads.cpp + Source/GameClient/Terrain/TerrainVisual.cpp Source/GameClient/VideoPlayer.cpp Source/GameClient/VideoStream.cpp Source/GameClient/View.cpp diff --git a/GeneralsMD/Code/GameEngine/Include/Common/MapObject.h b/Core/GameEngine/Include/Common/MapObject.h similarity index 100% rename from GeneralsMD/Code/GameEngine/Include/Common/MapObject.h rename to Core/GameEngine/Include/Common/MapObject.h diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/MapUtil.h b/Core/GameEngine/Include/GameClient/MapUtil.h similarity index 100% rename from GeneralsMD/Code/GameEngine/Include/GameClient/MapUtil.h rename to Core/GameEngine/Include/GameClient/MapUtil.h diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/Snow.h b/Core/GameEngine/Include/GameClient/Snow.h similarity index 100% rename from GeneralsMD/Code/GameEngine/Include/GameClient/Snow.h rename to Core/GameEngine/Include/GameClient/Snow.h diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/TerrainRoads.h b/Core/GameEngine/Include/GameClient/TerrainRoads.h similarity index 100% rename from GeneralsMD/Code/GameEngine/Include/GameClient/TerrainRoads.h rename to Core/GameEngine/Include/GameClient/TerrainRoads.h diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/TerrainVisual.h b/Core/GameEngine/Include/GameClient/TerrainVisual.h similarity index 99% rename from GeneralsMD/Code/GameEngine/Include/GameClient/TerrainVisual.h rename to Core/GameEngine/Include/GameClient/TerrainVisual.h index 5fd50282f4..8463ff83ab 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameClient/TerrainVisual.h +++ b/Core/GameEngine/Include/GameClient/TerrainVisual.h @@ -47,8 +47,6 @@ struct SeismicSimulationNode; class SeismicSimulationFilterBase; - - #define DEFAULT_SEISMIC_SIMULATION_MAGNITUDE (20.0f) struct SeismicSimulationNode; // just a forward declaration folks, no cause for alarm class SeismicSimulationFilterBase @@ -65,10 +63,6 @@ class SeismicSimulationFilterBase virtual Real applyGravityCallback( Real velocityIn ) = 0; }; - - - - struct SeismicSimulationNode { SeismicSimulationNode() @@ -159,11 +153,6 @@ class DomeStyleSeismicFilter : public SeismicSimulationFilterBase }; - - - - - //------------------------------------------------------------------------------------------------- /** LOD values for terrain, keep this in sync with TerrainLODNames[] */ //------------------------------------------------------------------------------------------------- @@ -303,7 +292,6 @@ class TerrainVisual : public Snapshot, //////////////////////////////////////////////////// - /// Replace the skybox texture virtual void replaceSkyboxTextures(const AsciiString *oldTexName[NumSkyboxTextures], const AsciiString *newTexName[NumSkyboxTextures])=0; diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/MapUtil.cpp b/Core/GameEngine/Source/GameClient/MapUtil.cpp similarity index 100% rename from GeneralsMD/Code/GameEngine/Source/GameClient/MapUtil.cpp rename to Core/GameEngine/Source/GameClient/MapUtil.cpp diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/Snow.cpp b/Core/GameEngine/Source/GameClient/Snow.cpp similarity index 100% rename from GeneralsMD/Code/GameEngine/Source/GameClient/Snow.cpp rename to Core/GameEngine/Source/GameClient/Snow.cpp diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/Terrain/TerrainRoads.cpp b/Core/GameEngine/Source/GameClient/Terrain/TerrainRoads.cpp similarity index 100% rename from GeneralsMD/Code/GameEngine/Source/GameClient/Terrain/TerrainRoads.cpp rename to Core/GameEngine/Source/GameClient/Terrain/TerrainRoads.cpp diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/Terrain/TerrainVisual.cpp b/Core/GameEngine/Source/GameClient/Terrain/TerrainVisual.cpp similarity index 99% rename from GeneralsMD/Code/GameEngine/Source/GameClient/Terrain/TerrainVisual.cpp rename to Core/GameEngine/Source/GameClient/Terrain/TerrainVisual.cpp index fd2aff3e4a..7b200f35d8 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/Terrain/TerrainVisual.cpp +++ b/Core/GameEngine/Source/GameClient/Terrain/TerrainVisual.cpp @@ -130,11 +130,6 @@ void TerrainVisual::loadPostProcess( void ) } - - - - - SeismicSimulationFilterBase::SeismicSimStatusCode DomeStyleSeismicFilter::filterCallback( WorldHeightMapInterfaceClass *heightMap, const SeismicSimulationNode *node ) { diff --git a/Core/GameEngineDevice/CMakeLists.txt b/Core/GameEngineDevice/CMakeLists.txt index 66dff03ecc..7ebd9b0294 100644 --- a/Core/GameEngineDevice/CMakeLists.txt +++ b/Core/GameEngineDevice/CMakeLists.txt @@ -6,10 +6,10 @@ set(GAMEENGINEDEVICE_SRC # Include/W3DDevice/Common/W3DModuleFactory.h Include/W3DDevice/Common/W3DRadar.h # Include/W3DDevice/Common/W3DThingFactory.h -# Include/W3DDevice/GameClient/BaseHeightMap.h + Include/W3DDevice/GameClient/BaseHeightMap.h # Include/W3DDevice/GameClient/camerashakesystem.h -# Include/W3DDevice/GameClient/FlatHeightMap.h -# Include/W3DDevice/GameClient/HeightMap.h + Include/W3DDevice/GameClient/FlatHeightMap.h + Include/W3DDevice/GameClient/HeightMap.h # Include/W3DDevice/GameClient/Module/W3DDebrisDraw.h # Include/W3DDevice/GameClient/Module/W3DDefaultDraw.h # Include/W3DDevice/GameClient/Module/W3DDependencyModelDraw.h @@ -20,17 +20,17 @@ set(GAMEENGINEDEVICE_SRC # Include/W3DDevice/GameClient/Module/W3DOverlordTruckDraw.h # Include/W3DDevice/GameClient/Module/W3DPoliceCarDraw.h # Include/W3DDevice/GameClient/Module/W3DProjectileStreamDraw.h -# Include/W3DDevice/GameClient/Module/W3DPropDraw.h + Include/W3DDevice/GameClient/Module/W3DPropDraw.h # Include/W3DDevice/GameClient/Module/W3DRopeDraw.h # Include/W3DDevice/GameClient/Module/W3DScienceModelDraw.h # Include/W3DDevice/GameClient/Module/W3DSupplyDraw.h # Include/W3DDevice/GameClient/Module/W3DTankDraw.h # Include/W3DDevice/GameClient/Module/W3DTankTruckDraw.h # Include/W3DDevice/GameClient/Module/W3DTracerDraw.h -# Include/W3DDevice/GameClient/Module/W3DTreeDraw.h + Include/W3DDevice/GameClient/Module/W3DTreeDraw.h # Include/W3DDevice/GameClient/Module/W3DTruckDraw.h -# Include/W3DDevice/GameClient/TerrainTex.h -# Include/W3DDevice/GameClient/TileData.h + Include/W3DDevice/GameClient/TerrainTex.h + Include/W3DDevice/GameClient/TileData.h # Include/W3DDevice/GameClient/W3DAssetManager.h # Include/W3DDevice/GameClient/W3DAssetManagerExposed.h # Include/W3DDevice/GameClient/W3DBibBuffer.h @@ -57,19 +57,19 @@ set(GAMEENGINEDEVICE_SRC # Include/W3DDevice/GameClient/W3DParticleSys.h # Include/W3DDevice/GameClient/W3DPoly.h # Include/W3DDevice/GameClient/W3DProjectedShadow.h -# Include/W3DDevice/GameClient/W3DPropBuffer.h + Include/W3DDevice/GameClient/W3DPropBuffer.h # Include/W3DDevice/GameClient/W3DRoadBuffer.h # Include/W3DDevice/GameClient/W3DScene.h Include/W3DDevice/GameClient/W3DShaderManager.h # Include/W3DDevice/GameClient/W3DShadow.h # Include/W3DDevice/GameClient/W3DShroud.h Include/W3DDevice/GameClient/W3DSmudge.h -# Include/W3DDevice/GameClient/W3DSnow.h + Include/W3DDevice/GameClient/W3DSnow.h # Include/W3DDevice/GameClient/W3DStatusCircle.h -# Include/W3DDevice/GameClient/W3DTerrainBackground.h -# Include/W3DDevice/GameClient/W3DTerrainTracks.h -# Include/W3DDevice/GameClient/W3DTerrainVisual.h -# Include/W3DDevice/GameClient/W3DTreeBuffer.h + Include/W3DDevice/GameClient/W3DTerrainBackground.h + Include/W3DDevice/GameClient/W3DTerrainTracks.h + Include/W3DDevice/GameClient/W3DTerrainVisual.h + Include/W3DDevice/GameClient/W3DTreeBuffer.h Include/W3DDevice/GameClient/W3DVideoBuffer.h Include/W3DDevice/GameClient/W3DView.h # Include/W3DDevice/GameClient/W3DVolumetricShadow.h @@ -77,7 +77,7 @@ set(GAMEENGINEDEVICE_SRC Include/W3DDevice/GameClient/W3DWaterTracks.h # Include/W3DDevice/GameClient/W3DWaypointBuffer.h # Include/W3DDevice/GameClient/W3DWebBrowser.h -# Include/W3DDevice/GameClient/WorldHeightMap.h + Include/W3DDevice/GameClient/WorldHeightMap.h # Include/W3DDevice/GameLogic/W3DGameLogic.h # Include/W3DDevice/GameLogic/W3DGhostObject.h # Include/W3DDevice/GameLogic/W3DTerrainLogic.h @@ -97,7 +97,7 @@ set(GAMEENGINEDEVICE_SRC # Source/W3DDevice/Common/Thing/W3DModuleFactory.cpp # Source/W3DDevice/Common/Thing/W3DThingFactory.cpp # Source/W3DDevice/Common/W3DConvert.cpp -# Source/W3DDevice/GameClient/BaseHeightMap.cpp + Source/W3DDevice/GameClient/BaseHeightMap.cpp Source/W3DDevice/GameClient/CameraShakeSystem.cpp # Source/W3DDevice/GameClient/Drawable/Draw/W3DDebrisDraw.cpp # Source/W3DDevice/GameClient/Drawable/Draw/W3DDefaultDraw.cpp @@ -109,16 +109,16 @@ set(GAMEENGINEDEVICE_SRC # Source/W3DDevice/GameClient/Drawable/Draw/W3DOverlordTruckDraw.cpp # Source/W3DDevice/GameClient/Drawable/Draw/W3DPoliceCarDraw.cpp # Source/W3DDevice/GameClient/Drawable/Draw/W3DProjectileStreamDraw.cpp -# Source/W3DDevice/GameClient/Drawable/Draw/W3DPropDraw.cpp + Source/W3DDevice/GameClient/Drawable/Draw/W3DPropDraw.cpp # Source/W3DDevice/GameClient/Drawable/Draw/W3DRopeDraw.cpp # Source/W3DDevice/GameClient/Drawable/Draw/W3DScienceModelDraw.cpp # Source/W3DDevice/GameClient/Drawable/Draw/W3DSupplyDraw.cpp # Source/W3DDevice/GameClient/Drawable/Draw/W3DTankDraw.cpp # Source/W3DDevice/GameClient/Drawable/Draw/W3DTankTruckDraw.cpp # Source/W3DDevice/GameClient/Drawable/Draw/W3DTracerDraw.cpp -# Source/W3DDevice/GameClient/Drawable/Draw/W3DTreeDraw.cpp + Source/W3DDevice/GameClient/Drawable/Draw/W3DTreeDraw.cpp # Source/W3DDevice/GameClient/Drawable/Draw/W3DTruckDraw.cpp -# Source/W3DDevice/GameClient/FlatHeightMap.cpp + Source/W3DDevice/GameClient/FlatHeightMap.cpp # Source/W3DDevice/GameClient/GUI/Gadget/W3DCheckBox.cpp # Source/W3DDevice/GameClient/GUI/Gadget/W3DComboBox.cpp # Source/W3DDevice/GameClient/GUI/Gadget/W3DHorizontalSlider.cpp @@ -136,13 +136,13 @@ set(GAMEENGINEDEVICE_SRC # Source/W3DDevice/GameClient/GUI/W3DGameFont.cpp # Source/W3DDevice/GameClient/GUI/W3DGameWindow.cpp # Source/W3DDevice/GameClient/GUI/W3DGameWindowManager.cpp -# Source/W3DDevice/GameClient/HeightMap.cpp + Source/W3DDevice/GameClient/HeightMap.cpp # Source/W3DDevice/GameClient/Shadow/W3DBufferManager.cpp # Source/W3DDevice/GameClient/Shadow/W3DProjectedShadow.cpp # Source/W3DDevice/GameClient/Shadow/W3DShadow.cpp # Source/W3DDevice/GameClient/Shadow/W3DVolumetricShadow.cpp -# Source/W3DDevice/GameClient/TerrainTex.cpp -# Source/W3DDevice/GameClient/TileData.cpp + Source/W3DDevice/GameClient/TerrainTex.cpp + Source/W3DDevice/GameClient/TileData.cpp # Source/W3DDevice/GameClient/W3DAssetManager.cpp # Source/W3DDevice/GameClient/W3DAssetManagerExposed.cpp # Source/W3DDevice/GameClient/W3DBibBuffer.cpp @@ -160,25 +160,25 @@ set(GAMEENGINEDEVICE_SRC # Source/W3DDevice/GameClient/W3DMouse.cpp # Source/W3DDevice/GameClient/W3DParticleSys.cpp # Source/W3DDevice/GameClient/W3DPoly.cpp -# Source/W3DDevice/GameClient/W3DPropBuffer.cpp + Source/W3DDevice/GameClient/W3DPropBuffer.cpp # Source/W3DDevice/GameClient/W3DRoadBuffer.cpp # Source/W3DDevice/GameClient/W3DScene.cpp Source/W3DDevice/GameClient/W3DShaderManager.cpp # Source/W3DDevice/GameClient/W3DShroud.cpp Source/W3DDevice/GameClient/W3DSmudge.cpp -# Source/W3DDevice/GameClient/W3DSnow.cpp + Source/W3DDevice/GameClient/W3DSnow.cpp # Source/W3DDevice/GameClient/W3DStatusCircle.cpp -# Source/W3DDevice/GameClient/W3DTerrainBackground.cpp -# Source/W3DDevice/GameClient/W3DTerrainTracks.cpp -# Source/W3DDevice/GameClient/W3DTerrainVisual.cpp -# Source/W3DDevice/GameClient/W3DTreeBuffer.cpp + Source/W3DDevice/GameClient/W3DTerrainBackground.cpp + Source/W3DDevice/GameClient/W3DTerrainTracks.cpp + Source/W3DDevice/GameClient/W3DTerrainVisual.cpp + Source/W3DDevice/GameClient/W3DTreeBuffer.cpp Source/W3DDevice/GameClient/W3DVideoBuffer.cpp Source/W3DDevice/GameClient/W3DView.cpp # Source/W3DDevice/GameClient/W3dWaypointBuffer.cpp # Source/W3DDevice/GameClient/W3DWebBrowser.cpp Source/W3DDevice/GameClient/Water/W3DWater.cpp Source/W3DDevice/GameClient/Water/W3DWaterTracks.cpp -# Source/W3DDevice/GameClient/WorldHeightMap.cpp + Source/W3DDevice/GameClient/WorldHeightMap.cpp # Source/W3DDevice/GameLogic/W3DGameLogic.cpp # Source/W3DDevice/GameLogic/W3DGhostObject.cpp # Source/W3DDevice/GameLogic/W3DTerrainLogic.cpp diff --git a/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/BaseHeightMap.h b/Core/GameEngineDevice/Include/W3DDevice/GameClient/BaseHeightMap.h similarity index 99% rename from GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/BaseHeightMap.h rename to Core/GameEngineDevice/Include/W3DDevice/GameClient/BaseHeightMap.h index 591fb04b03..9d3469a36b 100644 --- a/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/BaseHeightMap.h +++ b/Core/GameEngineDevice/Include/W3DDevice/GameClient/BaseHeightMap.h @@ -34,7 +34,7 @@ #include "vertmaterial.h" #include "Lib/BaseType.h" #include "Common/GameType.h" -#include "WorldHeightMap.h" +#include "W3DDevice/GameClient/WorldHeightMap.h" #define MAX_ENABLED_DYNAMIC_LIGHTS 20 typedef UnsignedByte HeightSampleType; //type of data to store in heightmap diff --git a/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/FlatHeightMap.h b/Core/GameEngineDevice/Include/W3DDevice/GameClient/FlatHeightMap.h similarity index 97% rename from GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/FlatHeightMap.h rename to Core/GameEngineDevice/Include/W3DDevice/GameClient/FlatHeightMap.h index cebe16170a..7cbea55a47 100644 --- a/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/FlatHeightMap.h +++ b/Core/GameEngineDevice/Include/W3DDevice/GameClient/FlatHeightMap.h @@ -34,8 +34,8 @@ #include "vertmaterial.h" #include "Lib/BaseType.h" #include "Common/GameType.h" -#include "WorldHeightMap.h" -#include "BaseHeightMap.h" +#include "W3DDevice/GameClient/WorldHeightMap.h" +#include "W3DDevice/GameClient/BaseHeightMap.h" class W3DTerrainBackground; /// Custom render object that draws the heightmap and handles intersection tests. diff --git a/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/HeightMap.h b/Core/GameEngineDevice/Include/W3DDevice/GameClient/HeightMap.h similarity index 98% rename from GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/HeightMap.h rename to Core/GameEngineDevice/Include/W3DDevice/GameClient/HeightMap.h index 7491d7333b..4e35b06729 100644 --- a/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/HeightMap.h +++ b/Core/GameEngineDevice/Include/W3DDevice/GameClient/HeightMap.h @@ -34,8 +34,8 @@ #include "vertmaterial.h" #include "Lib/BaseType.h" #include "Common/GameType.h" -#include "WorldHeightMap.h" -#include "BaseHeightMap.h" +#include "W3DDevice/GameClient/WorldHeightMap.h" +#include "W3DDevice/GameClient/BaseHeightMap.h" #define VERTEX_BUFFER_TILE_LENGTH 32 //tiles of side length 32 (grid of 33x33 vertices). diff --git a/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/Module/W3DPropDraw.h b/Core/GameEngineDevice/Include/W3DDevice/GameClient/Module/W3DPropDraw.h similarity index 100% rename from GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/Module/W3DPropDraw.h rename to Core/GameEngineDevice/Include/W3DDevice/GameClient/Module/W3DPropDraw.h diff --git a/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/Module/W3DTreeDraw.h b/Core/GameEngineDevice/Include/W3DDevice/GameClient/Module/W3DTreeDraw.h similarity index 100% rename from GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/Module/W3DTreeDraw.h rename to Core/GameEngineDevice/Include/W3DDevice/GameClient/Module/W3DTreeDraw.h diff --git a/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/TerrainTex.h b/Core/GameEngineDevice/Include/W3DDevice/GameClient/TerrainTex.h similarity index 100% rename from GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/TerrainTex.h rename to Core/GameEngineDevice/Include/W3DDevice/GameClient/TerrainTex.h diff --git a/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/TileData.h b/Core/GameEngineDevice/Include/W3DDevice/GameClient/TileData.h similarity index 100% rename from GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/TileData.h rename to Core/GameEngineDevice/Include/W3DDevice/GameClient/TileData.h diff --git a/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DPropBuffer.h b/Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DPropBuffer.h similarity index 100% rename from GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DPropBuffer.h rename to Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DPropBuffer.h diff --git a/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DSnow.h b/Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DSnow.h similarity index 100% rename from GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DSnow.h rename to Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DSnow.h diff --git a/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DTerrainBackground.h b/Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DTerrainBackground.h similarity index 100% rename from GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DTerrainBackground.h rename to Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DTerrainBackground.h diff --git a/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DTerrainTracks.h b/Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DTerrainTracks.h similarity index 100% rename from GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DTerrainTracks.h rename to Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DTerrainTracks.h diff --git a/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DTerrainVisual.h b/Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DTerrainVisual.h similarity index 99% rename from GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DTerrainVisual.h rename to Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DTerrainVisual.h index 35046b9a59..56f80c570e 100644 --- a/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DTerrainVisual.h +++ b/Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DTerrainVisual.h @@ -38,12 +38,6 @@ class WaterHandle; class BaseHeightMapRenderObjClass; class WorldHeightMap; - - - - - - //------------------------------------------------------------------------------------------------- /** W3D impelmentation of visual terrain details singleton */ //------------------------------------------------------------------------------------------------- @@ -150,9 +144,6 @@ class W3DTerrainVisual : public TerrainVisual //////////////////////////////////////////////////// //////////////////////////////////////////////////// - - - protected: // snapshot methods @@ -160,8 +151,6 @@ class W3DTerrainVisual : public TerrainVisual virtual void xfer( Xfer *xfer ); virtual void loadPostProcess( void ); - - #ifdef DO_SEISMIC_SIMULATIONS //////////////////////////////////////////////////// //////////////////////////////////////////////////// @@ -175,8 +164,6 @@ class W3DTerrainVisual : public TerrainVisual //////////////////////////////////////////////////// #endif - - BaseHeightMapRenderObjClass *m_terrainRenderObject; ///< W3D render object for terrain WaterRenderObjClass *m_waterRenderObject; ///< W3D render object for water plane @@ -191,7 +178,4 @@ class W3DTerrainVisual : public TerrainVisual AsciiString m_currentSkyboxTexNames[NumSkyboxTextures]; /// VecICoord2D; diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/BaseHeightMap.cpp b/Core/GameEngineDevice/Source/W3DDevice/GameClient/BaseHeightMap.cpp similarity index 99% rename from GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/BaseHeightMap.cpp rename to Core/GameEngineDevice/Source/W3DDevice/GameClient/BaseHeightMap.cpp index 7400b5673c..afb6045e68 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/BaseHeightMap.cpp +++ b/Core/GameEngineDevice/Source/W3DDevice/GameClient/BaseHeightMap.cpp @@ -57,6 +57,7 @@ #include #include "Common/GlobalData.h" #include "Common/PerfTimer.h" +#include "Common/Xfer.h" #include "GameClient/TerrainVisual.h" #include "GameClient/View.h" diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DPropDraw.cpp b/Core/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DPropDraw.cpp similarity index 100% rename from GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DPropDraw.cpp rename to Core/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DPropDraw.cpp diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DTreeDraw.cpp b/Core/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DTreeDraw.cpp similarity index 100% rename from GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DTreeDraw.cpp rename to Core/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DTreeDraw.cpp diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/FlatHeightMap.cpp b/Core/GameEngineDevice/Source/W3DDevice/GameClient/FlatHeightMap.cpp similarity index 100% rename from GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/FlatHeightMap.cpp rename to Core/GameEngineDevice/Source/W3DDevice/GameClient/FlatHeightMap.cpp diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/HeightMap.cpp b/Core/GameEngineDevice/Source/W3DDevice/GameClient/HeightMap.cpp similarity index 99% rename from GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/HeightMap.cpp rename to Core/GameEngineDevice/Source/W3DDevice/GameClient/HeightMap.cpp index d8ca4d28de..55f228a81d 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/HeightMap.cpp +++ b/Core/GameEngineDevice/Source/W3DDevice/GameClient/HeightMap.cpp @@ -45,8 +45,6 @@ //----------------------------------------------------------------------------- // Includes //----------------------------------------------------------------------------- - - #include "W3DDevice/GameClient/HeightMap.h" #ifndef USE_FLAT_HEIGHT_MAP // Flat height map uses flattened textures. jba. [3/20/2003] diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/TerrainTex.cpp b/Core/GameEngineDevice/Source/W3DDevice/GameClient/TerrainTex.cpp similarity index 99% rename from GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/TerrainTex.cpp rename to Core/GameEngineDevice/Source/W3DDevice/GameClient/TerrainTex.cpp index 7702b77b66..9e923b1d6d 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/TerrainTex.cpp +++ b/Core/GameEngineDevice/Source/W3DDevice/GameClient/TerrainTex.cpp @@ -103,6 +103,7 @@ int TerrainTextureClass::update(WorldHeightMap *htMap) DX8_ErrorCode(Peek_D3D_Texture()->GetSurfaceLevel(0, &surface_level)); DX8_ErrorCode(surface_level->GetDesc(&surface_desc)); if (surface_desc.Width < TEXTURE_WIDTH) { + surface_level->Release(); return 0; } @@ -944,7 +945,6 @@ void CloudMapTerrainTextureClass::Apply(unsigned int stage) // Do the base apply. TextureClass::Apply(stage); - return; #if 0 // obsolete /* previous setup */ if (TheGlobalData && TheGlobalData->m_trilinearTerrainTex) { diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/TileData.cpp b/Core/GameEngineDevice/Source/W3DDevice/GameClient/TileData.cpp similarity index 100% rename from GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/TileData.cpp rename to Core/GameEngineDevice/Source/W3DDevice/GameClient/TileData.cpp diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DPropBuffer.cpp b/Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DPropBuffer.cpp similarity index 100% rename from GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DPropBuffer.cpp rename to Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DPropBuffer.cpp diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DSnow.cpp b/Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DSnow.cpp similarity index 100% rename from GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DSnow.cpp rename to Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DSnow.cpp diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DTerrainBackground.cpp b/Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DTerrainBackground.cpp similarity index 100% rename from GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DTerrainBackground.cpp rename to Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DTerrainBackground.cpp diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DTerrainTracks.cpp b/Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DTerrainTracks.cpp similarity index 100% rename from GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DTerrainTracks.cpp rename to Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DTerrainTracks.cpp diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DTerrainVisual.cpp b/Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DTerrainVisual.cpp similarity index 99% rename from GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DTerrainVisual.cpp rename to Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DTerrainVisual.cpp index d1e770c2f0..77935049c5 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DTerrainVisual.cpp +++ b/Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DTerrainVisual.cpp @@ -169,16 +169,6 @@ W3DTerrainVisual::W3DTerrainVisual() m_clientHeightMap = NULL; #endif - - - - - - - - - - } //------------------------------------------------------------------------------------------------- @@ -344,7 +334,6 @@ void W3DTerrainVisual::update( void ) if( m_waterRenderObject ) m_waterRenderObject->update(); - } @@ -448,10 +437,6 @@ void W3DTerrainVisual::handleSeismicSimulations( void ) } } - - - - } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -573,9 +558,6 @@ Bool W3DTerrainVisual::load( AsciiString filename ) REF_PTR_RELEASE( m_logicHeightMap ); m_logicHeightMap = NEW WorldHeightMap(pStrm); - - - #ifdef DO_SEISMIC_SIMULATIONS fileStrm.close(); @@ -587,13 +569,6 @@ Bool W3DTerrainVisual::load( AsciiString filename ) #endif - - - - - - - // Add any lights loaded by map. MapObject *pMapObj = MapObject::getFirstMapObject(); while (pMapObj) @@ -656,7 +631,7 @@ Bool W3DTerrainVisual::load( AsciiString filename ) if (W3DDisplay::m_3DScene != NULL) { W3DDebugIcons *icons = NEW W3DDebugIcons; - W3DDisplay::m_3DScene->Add_Render_Object( icons ); + W3DDisplay::m_3DScene->Add_Render_Object( icons ); icons->Release_Ref(); // belongs to scene. } #endif @@ -770,7 +745,6 @@ TerrainType *W3DTerrainVisual::getTerrainTile( Real x, Real y ) { TerrainType *tile = NULL; - #ifdef DO_SEISMIC_SIMULATIONS if( m_clientHeightMap ) { @@ -785,11 +759,7 @@ TerrainType *W3DTerrainVisual::getTerrainTile( Real x, Real y ) } #endif - - - return tile; - } // ------------------------------------------------------------------------------------------------ @@ -1175,14 +1145,18 @@ void W3DTerrainVisual::crc( Xfer *xfer ) * Version Info: * 1: Initial version * 2: Add height map heights. - * 3: Add client side trees & props. jba. + * 3: Add client side trees & props. jba. (Added for Zero Hour) */ // ------------------------------------------------------------------------------------------------ void W3DTerrainVisual::xfer( Xfer *xfer ) { // version +#if RTS_GENERALS && RETAIL_COMPATIBLE_XFER_SAVE + XferVersion currentVersion = 2; +#else XferVersion currentVersion = 3; +#endif XferVersion version = currentVersion; xfer->xferVersion( &version, currentVersion ); @@ -1258,8 +1232,6 @@ void W3DTerrainVisual::xfer( Xfer *xfer ) xfer->xferSnapshot(m_terrainRenderObject); } - - // XFER // // X R // // X R // @@ -1274,10 +1246,6 @@ void W3DTerrainVisual::xfer( Xfer *xfer ) // X R // // XFER // - - - - } // ------------------------------------------------------------------------------------------------ diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DTreeBuffer.cpp b/Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DTreeBuffer.cpp similarity index 100% rename from GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DTreeBuffer.cpp rename to Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DTreeBuffer.cpp diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/WorldHeightMap.cpp b/Core/GameEngineDevice/Source/W3DDevice/GameClient/WorldHeightMap.cpp similarity index 99% rename from GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/WorldHeightMap.cpp rename to Core/GameEngineDevice/Source/W3DDevice/GameClient/WorldHeightMap.cpp index 6fe0998491..52384dfed5 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/WorldHeightMap.cpp +++ b/Core/GameEngineDevice/Source/W3DDevice/GameClient/WorldHeightMap.cpp @@ -580,9 +580,6 @@ void WorldHeightMap::clearFlipStates(void) { } } - - - //////////////////////////////////////////////////////////////////////////////m_SeismicUpdateFlag Bool WorldHeightMap::getSeismicUpdateFlag(Int xIndex, Int yIndex) const { @@ -698,21 +695,6 @@ Real WorldHeightMap::getBilinearSampleSeismicZVelocity( Int x, Int y) } - - - - - - - - - - - - - - - /** Get whether the cell is a cliff cell (impassable to ground vehicles). */ Bool WorldHeightMap::getCliffState(Int xIndex, Int yIndex) const diff --git a/Generals/Code/GameEngine/CMakeLists.txt b/Generals/Code/GameEngine/CMakeLists.txt index 357a3a48b6..9553884b67 100644 --- a/Generals/Code/GameEngine/CMakeLists.txt +++ b/Generals/Code/GameEngine/CMakeLists.txt @@ -62,7 +62,7 @@ set(GAMEENGINE_SRC Include/Common/List.h # Include/Common/LocalFile.h # Include/Common/LocalFileSystem.h - Include/Common/MapObject.h +# Include/Common/MapObject.h Include/Common/MapReaderWriterInfo.h Include/Common/MessageStream.h Include/Common/MiniLog.h @@ -192,7 +192,7 @@ set(GAMEENGINE_SRC Include/GameClient/Line2D.h Include/GameClient/LoadScreen.h Include/GameClient/LookAtXlat.h - Include/GameClient/MapUtil.h +# Include/GameClient/MapUtil.h Include/GameClient/MessageBox.h Include/GameClient/MetaEvent.h Include/GameClient/Module/AnimatedParticleSysBoneClientUpdate.h @@ -211,8 +211,8 @@ set(GAMEENGINE_SRC Include/GameClient/ShellHooks.h Include/GameClient/ShellMenuScheme.h Include/GameClient/Statistics.h - Include/GameClient/TerrainRoads.h - Include/GameClient/TerrainVisual.h +# Include/GameClient/TerrainRoads.h +# Include/GameClient/TerrainVisual.h # Include/GameClient/VideoPlayer.h # Include/GameClient/View.h # Include/GameClient/Water.h @@ -753,7 +753,7 @@ set(GAMEENGINE_SRC Source/GameClient/Input/Mouse.cpp Source/GameClient/LanguageFilter.cpp Source/GameClient/Line2D.cpp - Source/GameClient/MapUtil.cpp +# Source/GameClient/MapUtil.cpp Source/GameClient/MessageStream/CommandXlat.cpp Source/GameClient/MessageStream/GUICommandTranslator.cpp Source/GameClient/MessageStream/HintSpy.cpp @@ -773,8 +773,8 @@ set(GAMEENGINE_SRC Source/GameClient/System/Image.cpp Source/GameClient/System/ParticleSys.cpp Source/GameClient/System/RayEffect.cpp - Source/GameClient/Terrain/TerrainRoads.cpp - Source/GameClient/Terrain/TerrainVisual.cpp +# Source/GameClient/Terrain/TerrainRoads.cpp +# Source/GameClient/Terrain/TerrainVisual.cpp # Source/GameClient/VideoPlayer.cpp # Source/GameClient/View.cpp # Source/GameClient/Water.cpp diff --git a/Generals/Code/GameEngine/Include/Common/GlobalData.h b/Generals/Code/GameEngine/Include/Common/GlobalData.h index 0e59219221..cb7c0d1dda 100644 --- a/Generals/Code/GameEngine/Include/Common/GlobalData.h +++ b/Generals/Code/GameEngine/Include/Common/GlobalData.h @@ -153,6 +153,7 @@ class GlobalData : public SubsystemInterface Int m_waterType; Bool m_showSoftWaterEdge; Bool m_usingWaterTrackEditor; + Bool m_isWorldBuilder; Int m_featherWater; diff --git a/Generals/Code/GameEngine/Include/Common/INI.h b/Generals/Code/GameEngine/Include/Common/INI.h index 869b4d1c20..0e48452dc5 100644 --- a/Generals/Code/GameEngine/Include/Common/INI.h +++ b/Generals/Code/GameEngine/Include/Common/INI.h @@ -204,6 +204,7 @@ class INI static void parseParticleSystemDefinition( INI *ini ); static void parseWaterSettingDefinition( INI *ini ); static void parseWaterTransparencyDefinition( INI *ini ); + static void parseWeatherDefinition( INI *ini ); static void parseMappedImageDefinition( INI *ini ); static void parseArmorDefinition( INI *ini ); static void parseDamageFXDefinition( INI *ini ); diff --git a/Generals/Code/GameEngine/Include/Common/MapObject.h b/Generals/Code/GameEngine/Include/Common/MapObject.h deleted file mode 100644 index 9b29e983ad..0000000000 --- a/Generals/Code/GameEngine/Include/Common/MapObject.h +++ /dev/null @@ -1,169 +0,0 @@ -/* -** Command & Conquer Generals(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) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - - -// MapObject.h -// Class to encapsulate height map. -// Author: John Ahlquist, April 2001 - -#pragma once - -#include "Common/Dict.h" -#include "Common/GameMemory.h" -#include "GameClient/TerrainRoads.h" - -/** MapObject class -Not ref counted. Do not store pointers to this class. */ -class WorldHeightMap; -class RenderObjClass; -class ThingTemplate; -class Shadow; -enum WaypointID CPP_11(: Int); - -#define MAP_XY_FACTOR (10.0f) //How wide and tall each height map square is in world space. -#define MAP_HEIGHT_SCALE (MAP_XY_FACTOR/16.0f) //divide all map heights by 8. - -// m_flags bit values. -enum { - FLAG_DRAWS_IN_MIRROR = 0x00000001, ///< If set, draws in water mirror. - FLAG_ROAD_POINT1 = 0x00000002, ///< If set, is the first point in a road segment. - FLAG_ROAD_POINT2 = 0x00000004, ///< If set, is the second point in a road segment. - FLAG_ROAD_FLAGS = (FLAG_ROAD_POINT1|FLAG_ROAD_POINT2), ///< If nonzero, object is a road piece. - FLAG_ROAD_CORNER_ANGLED = 0x00000008, ///< If set, the road corner is angled rather than curved. - FLAG_BRIDGE_POINT1 = 0x00000010, ///< If set, is the first point in a bridge. - FLAG_BRIDGE_POINT2 = 0x00000020, ///< If set, is the second point in a bridge. - FLAG_BRIDGE_FLAGS = (FLAG_BRIDGE_POINT1|FLAG_BRIDGE_POINT2), ///< If nonzero, object is a bridge piece. - FLAG_ROAD_CORNER_TIGHT = 0x00000040, - FLAG_ROAD_JOIN = 0x00000080, ///< If set, this road end does a generic alpha join. - FLAG_DONT_RENDER = 0x00000100 ///< If set, do not render this object. Only WB pays attention to this. (Right now, anyways) -}; - -class MapObject : public MemoryPoolObject -{ - MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(MapObject, "MapObject") - -// friend doesn't play well with MPO -- srj -// friend class WorldHeightMap; -// friend class WorldHeightMapEdit; -// friend class AddObjectUndoable; -// friend class DeleteInfo; - - enum - { - MO_SELECTED = 0x01, - MO_LIGHT = 0x02, - MO_WAYPOINT = 0x04, - MO_SCORCH = 0x08 - }; - - // This data is currently written out into the map data file. - Coord3D m_location; ///< Location of the center of the object. - AsciiString m_objectName; ///< The object name. - const ThingTemplate* m_thingTemplate; ///< thing template for map object - Real m_angle; ///< positive x is 0 degrees, angle is counterclockwise in degrees. - MapObject* m_nextMapObject; ///< linked list. - Int m_flags; ///< Bit flags. - Dict m_properties; ///< general property sheet. - // This data is runtime data that is used by the worldbuider editor, but - // not saved in the map file. - Int m_color; ///< Display color. - RenderObjClass* m_renderObj; ///< object that renders in the 3d scene. - Shadow* m_shadowObj; ///< object that renders shadow in the 3d scene. - RenderObjClass* m_bridgeTowers[ BRIDGE_MAX_TOWERS ]; ///< for bridge towers - Int m_runtimeFlags; - -public: - static MapObject *TheMapObjectListPtr; - static Dict TheWorldDict; - -public: - MapObject(Coord3D loc, AsciiString name, Real angle, Int flags, const Dict* props, - const ThingTemplate *thingTemplate ); - //~MapObject(void); ///< Note that deleting the head of a list deletes all linked objects in the list. - -public: - - Dict *getProperties() { return &m_properties; } ///< return the object's property sheet. - - void setNextMap(MapObject *nextMap) {m_nextMapObject = nextMap;} ///< Link the next map object. - const Coord3D *getLocation(void) const {return &m_location;} ///< Get the center point. - Real getAngle(void) const {return m_angle;} ///< Get the angle. - Int getColor(void) const {return m_color;} ///< Gets whatever ui color we set. - void setColor(Int color) {m_color=color;} ///< Sets the ui color. - AsciiString getName(void) const {return m_objectName;} ///< Gets the object name - void setName(AsciiString name); ///< Sets the object name - void setThingTemplate( const ThingTemplate* thing ); ///< set template - const ThingTemplate *getThingTemplate( void ) const; - MapObject *getNext(void) const {return m_nextMapObject;} ///< Next map object in the list. Not a copy, don't delete it. - MapObject *duplicate(void); ///< Allocates a copy. Caller is responsible for delete-ing this when done with it. - - void setAngle(Real angle) {m_angle = normalizeAngle(angle);} - void setLocation(Coord3D *pLoc) {m_location = *pLoc;} - void setFlag(Int flag) {m_flags |= flag;} - void clearFlag(Int flag) {m_flags &= (~flag);} - Bool getFlag(Int flag) const {return (m_flags&flag)?true:false;} - Int getFlags(void) const {return (m_flags);} - - Bool isSelected(void) const {return (m_runtimeFlags & MO_SELECTED) != 0;} - void setSelected(Bool sel) { if (sel) m_runtimeFlags |= MO_SELECTED; else m_runtimeFlags &= ~MO_SELECTED; } - - Bool isLight(void) const {return (m_runtimeFlags & MO_LIGHT) != 0;} - Bool isWaypoint(void) const {return (m_runtimeFlags & MO_WAYPOINT) != 0;} - Bool isScorch(void) const {return (m_runtimeFlags & MO_SCORCH) != 0;} - - void setIsLight() {m_runtimeFlags |= MO_LIGHT;} - void setIsWaypoint() { m_runtimeFlags |= MO_WAYPOINT; } - void setIsScorch() { m_runtimeFlags |= MO_SCORCH; } - - void setRenderObj(RenderObjClass *pObj); - RenderObjClass *getRenderObj(void) const {return m_renderObj;} - void setShadowObj(Shadow *pObj) {m_shadowObj=pObj;} - Shadow *getShadowObj(void) const {return m_shadowObj;} - - RenderObjClass* getBridgeRenderObject( BridgeTowerType type ); - void setBridgeRenderObject( BridgeTowerType type, RenderObjClass* renderObj ); - - WaypointID getWaypointID(); - AsciiString getWaypointName(); - void setWaypointID(Int i); - void setWaypointName(AsciiString n); - - // calling validate will call verifyValidTeam and verifyValidUniqueID. - void validate(void); - - // verifyValidTeam will either place the map object on an approrpriate team, or leave the - // current team (if it is valid) - void verifyValidTeam(void); - - // verifyValidUniqueID will ensure that this unit isn't sharing a number with another unit. - void verifyValidUniqueID(void); - - // The fast version doesn't attempt to verify uniqueness. It goes - static void fastAssignAllUniqueIDs(void); - - - static MapObject *getFirstMapObject(void) { return TheMapObjectListPtr; } - static Dict* getWorldDict() { return &TheWorldDict; } - static Int countMapObjectsWithOwner(const AsciiString& n); -}; diff --git a/Generals/Code/GameEngine/Include/Common/ThingFactory.h b/Generals/Code/GameEngine/Include/Common/ThingFactory.h index 4d4871aedb..c9469239c2 100644 --- a/Generals/Code/GameEngine/Include/Common/ThingFactory.h +++ b/Generals/Code/GameEngine/Include/Common/ThingFactory.h @@ -73,7 +73,7 @@ class ThingFactory : public SubsystemInterface get a template given template database name. return null if not found. note, this is now substantially faster (does a hash-table lookup) */ - const ThingTemplate *findTemplate( const AsciiString& name ) { return findTemplateInternal(name); } + const ThingTemplate *findTemplate( const AsciiString& name, Bool check = TRUE ) { return findTemplateInternal( name, check ); } /** get a template given ID. return null if not found. @@ -120,7 +120,7 @@ class ThingFactory : public SubsystemInterface NOTE: this is protected since it returns a NON-CONST template, and folks outside of the template system itself shouldn't get access... */ - ThingTemplate *findTemplateInternal( const AsciiString& name ); + ThingTemplate *findTemplateInternal( const AsciiString& name, Bool check = TRUE ); ThingTemplate *m_firstTemplate; ///< head of linked list UnsignedShort m_nextTemplateID; ///< next available ID for templates diff --git a/Generals/Code/GameEngine/Include/GameClient/MapUtil.h b/Generals/Code/GameEngine/Include/GameClient/MapUtil.h deleted file mode 100644 index 5db7a1ede1..0000000000 --- a/Generals/Code/GameEngine/Include/GameClient/MapUtil.h +++ /dev/null @@ -1,150 +0,0 @@ -/* -** Command & Conquer Generals(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) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -// FILE: MapUtil.h ///////////////////////////////////////////////////////// -// Author: Matt Campbell, December 2001 -// Description: Map utility/convenience routines -//////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include "Common/AsciiString.h" -#include "Common/UnicodeString.h" - -#include "Common/STLTypedefs.h" - -class GameWindow; -class AsciiString; -struct Coord3D; -struct FileInfo; -class Image; -class DataChunkInput; -struct DataChunkInfo; -// This matches the windows timestamp. -enum { SUPPLY_TECH_SIZE = 15}; -typedef std::list ICoord2DList; - -class TechAndSupplyImages -{ -public: - ICoord2DList m_techPosList; - ICoord2DList m_supplyPosList; -}; - -struct WinTimeStamp -{ - UnsignedInt m_lowTimeStamp; - UnsignedInt m_highTimeStamp; -}; - - -class WaypointMap : public std::map -{ -public: - void update( void ); ///< returns the number of multiplayer start spots found - Int m_numStartSpots; -}; - -typedef std::list Coord3DList; - -class MapMetaData -{ -public: - UnicodeString m_displayName; - AsciiString m_nameLookupTag; - Region3D m_extent; - Int m_numPlayers; - - Bool m_isMultiplayer; - Bool m_isOfficial; - Bool m_doesExist; ///< Flag to indicate whether the map physically exists. Should be true. - UnsignedInt m_filesize; - UnsignedInt m_CRC; - - WinTimeStamp m_timestamp; - - WaypointMap m_waypoints; - Coord3DList m_supplyPositions; - Coord3DList m_techPositions; - AsciiString m_fileName; -}; - -// TheSuperHackers @performance xezon 02/11/2025 Simplifies and improves the implementation of MapCache -// to prevent expensive reoccurring redundant map cache reads. - -class MapCache : public std::map -{ - typedef std::set MapNameSet; - -public: - MapCache() - : m_doCreateStandardMapCacheINI(TRUE) - , m_doLoadStandardMapCacheINI(TRUE) - , m_doLoadUserMapCacheINI(TRUE) - {} - - void updateCache( void ); - - AsciiString getMapDir() const; - AsciiString getUserMapDir() const; - AsciiString getMapExtension() const; - - const MapMetaData *findMap(AsciiString mapName); - - // allow us to create a set of shippable maps to be in mapcache.ini. For use with -buildMapCache. - void addShippingMap(AsciiString mapName) { mapName.toLower(); m_allowedMaps.insert(mapName); } - -private: - void prepareUnseenMaps(const AsciiString &mapDir); - Bool clearUnseenMaps(const AsciiString &mapDir); - void loadMapsFromMapCacheINI(const AsciiString &mapDir); - Bool loadMapsFromDisk(const AsciiString &mapDir, Bool isOfficial, Bool filterByAllowedMaps = FALSE); // returns true if we needed to (re)parse a map - Bool addMap(const AsciiString &mapDir, const AsciiString &fname, const AsciiString &lowerFname, FileInfo &fileInfo, Bool isOfficial); ///< returns true if it had to (re)parse the map - void writeCacheINI(const AsciiString &mapDir); - - static const char *const m_mapCacheName; - - MapNameSet m_allowedMaps; - Bool m_doCreateStandardMapCacheINI; - Bool m_doLoadStandardMapCacheINI; - Bool m_doLoadUserMapCacheINI; -}; - -extern MapCache *TheMapCache; -extern TechAndSupplyImages TheSupplyAndTechImageLocations; - -// TheSuperHackers @refactor xezon 28/11/2025 Refactors the map list population implementation -// by breaking it into smaller pieces to make it more maintainable. - -Int populateMapListbox( GameWindow *listbox, Bool useSystemMaps, Bool isMultiplayer, AsciiString mapToSelect = AsciiString::TheEmptyString ); /// Read a list of maps from the run directory and fill in the listbox. Return the selected index -Int populateMapListboxNoReset( GameWindow *listbox, Bool useSystemMaps, Bool isMultiplayer, AsciiString mapToSelect = AsciiString::TheEmptyString ); /// Read a list of maps from the run directory and fill in the listbox. Return the selected index -Bool isValidMap( AsciiString mapName, Bool isMultiplayer ); /// Validate a map -Image *getMapPreviewImage( AsciiString mapName ); -AsciiString getDefaultMap( Bool isMultiplayer ); /// Find a valid map -AsciiString getDefaultOfficialMap(); -Bool isOfficialMap( AsciiString mapName ); -Bool parseMapPreviewChunk(DataChunkInput &file, DataChunkInfo *info, void *userData); -void findDrawPositions( Int startX, Int startY, Int width, Int height, Region3D extent, - ICoord2D *ul, ICoord2D *lr ); -Bool WouldMapTransfer( const AsciiString& mapName ); diff --git a/Generals/Code/GameEngine/Include/GameClient/TerrainRoads.h b/Generals/Code/GameEngine/Include/GameClient/TerrainRoads.h deleted file mode 100644 index 72fa329122..0000000000 --- a/Generals/Code/GameEngine/Include/GameClient/TerrainRoads.h +++ /dev/null @@ -1,229 +0,0 @@ -/* -** Command & Conquer Generals(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) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -// FILE: TerrainRoads.h /////////////////////////////////////////////////////////////////////////// -// Author: Colin Day, December 2001 -// Desc: Terrain road descriptions -/////////////////////////////////////////////////////////////////////////////////////////////////// - -#pragma once - -// INCLUDES /////////////////////////////////////////////////////////////////////////////////////// -#include "Common/GameMemory.h" -#include "Common/SubsystemInterface.h" - -#include "GameLogic/Module/BodyModule.h" - - -// FORWARD DECLARATIONS /////////////////////////////////////////////////////////////////////////// -struct FieldParse; -class AsciiString; - -// ------------------------------------------------------------------------------------------------ -/** Bridges have 4 towers around it that the player can attack or use to repair the bridge */ -// ------------------------------------------------------------------------------------------------ -enum BridgeTowerType CPP_11(: Int) -{ - BRIDGE_TOWER_FROM_LEFT = 0, - BRIDGE_TOWER_FROM_RIGHT, - BRIDGE_TOWER_TO_LEFT, - BRIDGE_TOWER_TO_RIGHT, - - BRIDGE_MAX_TOWERS -}; - -// ------------------------------------------------------------------------------------------------ -enum { MAX_BRIDGE_BODY_FX = 3 }; - -//------------------------------------------------------------------------------------------------- -/** Terrain road description, good for roads and bridges */ -//------------------------------------------------------------------------------------------------- -class TerrainRoadType : public MemoryPoolObject -{ - - MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( TerrainRoadType, "TerrainRoadType" ) - -public: - - TerrainRoadType( void ); - // destructor prototypes defined by memory pool object - - AsciiString getName( void ) { return m_name; } - AsciiString getTexture( void ) { return m_texture; } - Bool isBridge( void ) { return m_isBridge; } - UnsignedInt getID( void ) { return m_id; } - - Real getRoadWidth( void ) { return m_roadWidth; } - Real getRoadWidthInTexture( void ) { return m_roadWidthInTexture; } - - Real getBridgeScale( void ) { return m_bridgeScale; } - AsciiString getScaffoldObjectName( void ) { return m_scaffoldObjectName; } - AsciiString getScaffoldSupportObjectName( void ) { return m_scaffoldSupportObjectName; } - RGBColor getRadarColor( void ) { return m_radarColor; } - AsciiString getBridgeModel( void ) { return m_bridgeModelName; } - AsciiString getBridgeModelNameDamaged( void ) { return m_bridgeModelNameDamaged; } - AsciiString getBridgeModelNameReallyDamaged( void ) { return m_bridgeModelNameReallyDamaged; } - AsciiString getBridgeModelNameBroken( void ) { return m_bridgeModelNameBroken; } - AsciiString getTextureDamaged( void ) { return m_textureDamaged; } - AsciiString getTextureReallyDamaged( void ) { return m_textureReallyDamaged; } - AsciiString getTextureBroken( void ) { return m_textureBroken; } - AsciiString getTowerObjectName( BridgeTowerType tower ) { return m_towerObjectName[ tower ]; } - AsciiString getDamageToSoundString( BodyDamageType state ) { return m_damageToSoundString[ state ]; } - AsciiString getDamageToOCLString( BodyDamageType state, Int index ) { return m_damageToOCLString[ state ][ index ]; } - AsciiString getDamageToFXString( BodyDamageType state, Int index ) { return m_damageToFXString[ state ][ index ]; } - AsciiString getRepairedToSoundString( BodyDamageType state ) { return m_repairedToSoundString[ state ]; } - AsciiString getRepairedToOCLString( BodyDamageType state, Int index ) { return m_repairedToOCLString[ state ][ index ]; } - AsciiString getRepairedToFXString( BodyDamageType state, Int index ) { return m_repairedToFXString[ state ][ index ]; } - Real getTransitionEffectsHeight( void ) { return m_transitionEffectsHeight; } - Int getNumFXPerType( void ) { return m_numFXPerType; } - - // friend access methods to be used by the road collection only! - void friend_setName( AsciiString name ) { m_name = name; } - void friend_setTexture( AsciiString texture ) { m_texture = texture; } - void friend_setBridge( Bool isBridge ) { m_isBridge = isBridge; } - void friend_setID( UnsignedInt id ) { m_id = id; } - void friend_setNext( TerrainRoadType *next ) { m_next = next; } - TerrainRoadType *friend_getNext( void ) { return m_next; } - void friend_setRoadWidth( Real width ) { m_roadWidth = width; } - void friend_setRoadWidthInTexture( Real width ) { m_roadWidthInTexture = width; } - void friend_setBridgeScale( Real scale ) { m_bridgeScale = scale; } - void friend_setScaffoldObjectName( AsciiString name ) { m_scaffoldObjectName = name; } - void friend_setScaffoldSupportObjectName( AsciiString name ) { m_scaffoldSupportObjectName = name; } - void friend_setBridgeModelName( AsciiString name ) { m_bridgeModelName = name; } - void friend_setBridgeModelNameDamaged( AsciiString name ) { m_bridgeModelNameDamaged = name; } - void friend_setBridgeModelNameReallyDamaged( AsciiString name ) { m_bridgeModelNameReallyDamaged = name; } - void friend_setBridgeModelNameBroken( AsciiString name ) { m_bridgeModelNameBroken = name; } - void friend_setTextureDamaged( AsciiString texture ) { m_textureDamaged = texture; } - void friend_setTextureReallyDamaged( AsciiString texture ) { m_textureReallyDamaged = texture; } - void friend_setTextureBroken( AsciiString texture ) { m_textureBroken = texture; } - void friend_setTowerObjectName( BridgeTowerType tower, AsciiString name ) { m_towerObjectName[ tower ] = name; } - void friend_setDamageToSoundString( BodyDamageType state, AsciiString s ) { m_damageToSoundString[ state ] = s; } - void friend_setDamageToOCLString( BodyDamageType state, Int index, AsciiString s ) { m_damageToOCLString[ state ][ index ] = s; } - void friend_setDamageToFXString( BodyDamageType state, Int index, AsciiString s ) { m_damageToFXString[ state ][ index ] = s; } - void friend_setRepairedToSoundString( BodyDamageType state, AsciiString s ) { m_repairedToSoundString[ state ] = s; } - void friend_setRepairedToOCLString( BodyDamageType state, Int index, AsciiString s ) { m_repairedToOCLString[ state ][ index ] = s; } - void friend_setRepairedToFXString( BodyDamageType state, Int index, AsciiString s ) { m_repairedToFXString[ state ][ index ] = s; } - void friend_setTransitionEffectsHeight( Real height ) { m_transitionEffectsHeight = height; } - void friend_setNumFXPerType( Int num ) { m_numFXPerType = num; } - - /// get the parsing table for INI - const FieldParse *getRoadFieldParse( void ) { return m_terrainRoadFieldParseTable; } - const FieldParse *getBridgeFieldParse( void ) { return m_terrainBridgeFieldParseTable; } - -protected: - - AsciiString m_name; ///< entry name - Bool m_isBridge; ///< true if entry is for a bridge - UnsignedInt m_id; ///< unique id - TerrainRoadType *m_next; ///< next in road list - - // for parsing from INI - static const FieldParse m_terrainRoadFieldParseTable[]; ///< the parse table for INI definition - static const FieldParse m_terrainBridgeFieldParseTable[]; ///< the parse table for INI definition - static void parseTransitionToOCL( INI *ini, void *instance, void *store, const void *userData ); - static void parseTransitionToFX( INI *ini, void *instance, void *store, const void *userData ); - - // - // *note* I would union the road and bridge data, but unions can't have a copy - // constructor such as the AsciiString does - // - - // road data - Real m_roadWidth; ///< width of road - Real m_roadWidthInTexture; ///< width of road in the texture - - // bridge data - Real m_bridgeScale; ///< scale for bridge - - AsciiString m_scaffoldObjectName; ///< scaffold object name - AsciiString m_scaffoldSupportObjectName; ///< scaffold support object name - - RGBColor m_radarColor; ///< color for this bridge on the radar - - AsciiString m_bridgeModelName; ///< model name for bridge - AsciiString m_texture; ///< texture filename - - AsciiString m_bridgeModelNameDamaged; ///< model name for bridge - AsciiString m_textureDamaged; ///< model name for bridge - - AsciiString m_bridgeModelNameReallyDamaged; ///< model name for bridge - AsciiString m_textureReallyDamaged; ///< model name for bridge - - AsciiString m_bridgeModelNameBroken; ///< model name for bridge - AsciiString m_textureBroken; ///< model name for bridge - - AsciiString m_towerObjectName[ BRIDGE_MAX_TOWERS ]; ///< object names for the targetable towers on the bridge - - // - // the following strings are for repair/damage transition events, what sounds to - // play and a collection of OCL and FX lists to play over the bridge area - // - AsciiString m_damageToSoundString[ BODYDAMAGETYPE_COUNT ]; - AsciiString m_damageToOCLString[ BODYDAMAGETYPE_COUNT ][ MAX_BRIDGE_BODY_FX ]; - AsciiString m_damageToFXString[ BODYDAMAGETYPE_COUNT ][ MAX_BRIDGE_BODY_FX ]; - AsciiString m_repairedToSoundString[ BODYDAMAGETYPE_COUNT ]; - AsciiString m_repairedToOCLString[ BODYDAMAGETYPE_COUNT ][ MAX_BRIDGE_BODY_FX ]; - AsciiString m_repairedToFXString[ BODYDAMAGETYPE_COUNT ][ MAX_BRIDGE_BODY_FX ]; - Real m_transitionEffectsHeight; - Int m_numFXPerType; ///< for *each* fx/ocl we will make this many of them on the bridge area - -}; - -//------------------------------------------------------------------------------------------------- -/** Collection of all roads and bridges */ -//------------------------------------------------------------------------------------------------- -class TerrainRoadCollection : public SubsystemInterface -{ - -public: - - TerrainRoadCollection( void ); - ~TerrainRoadCollection( void ); - - void init() { } - void reset() { } - void update() { } - - TerrainRoadType *findRoad( AsciiString name ); ///< find road with matching name - TerrainRoadType *newRoad( AsciiString name ); ///< allocate new road, assing name, and link to list - TerrainRoadType *firstRoad( void ) { return m_roadList; } ///< return first road - TerrainRoadType *nextRoad( TerrainRoadType *road ); ///< get next road - - TerrainRoadType *findBridge( AsciiString name ); ///< find bridge with matching name - TerrainRoadType *newBridge( AsciiString name ); ///< allocate new bridge, assign name, and link - TerrainRoadType *firstBridge( void ) { return m_bridgeList; } ///< return first bridge - TerrainRoadType *nextBridge( TerrainRoadType *bridge ); ///< get next bridge - - TerrainRoadType *findRoadOrBridge( AsciiString name ); ///< search roads and bridges - -protected: - - TerrainRoadType *m_roadList; ///< list of available roads - TerrainRoadType *m_bridgeList; ///< list of available bridges - static UnsignedInt m_idCounter; ///< unique id counter when allocating roads/bridges - -}; - -// EXTERNAL //////////////////////////////////////////////////////////////////////////////////////// -extern TerrainRoadCollection *TheTerrainRoads; diff --git a/Generals/Code/GameEngine/Include/GameClient/TerrainVisual.h b/Generals/Code/GameEngine/Include/GameClient/TerrainVisual.h deleted file mode 100644 index a6cb48cb63..0000000000 --- a/Generals/Code/GameEngine/Include/GameClient/TerrainVisual.h +++ /dev/null @@ -1,173 +0,0 @@ -/* -** Command & Conquer Generals(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) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -// FILE: TerrainVisual.h ////////////////////////////////////////////////////////////////////////// -// Interface for visual representation of terrain on the client -// Author: Colin Day, April 2001 -/////////////////////////////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include "Common/Terrain.h" -#include "Common/Snapshot.h" - -// FORWARD REFERENCES ///////////////////////////////////////////////////////////////////////////// -class TerrainType; -class WaterHandle; -class Matrix3D; -class Object; -class Drawable; - -//------------------------------------------------------------------------------------------------- -/** LOD values for terrain, keep this in sync with TerrainLODNames[] */ -//------------------------------------------------------------------------------------------------- -typedef enum _TerrainLOD CPP_11(: Int) -{ - TERRAIN_LOD_INVALID, - TERRAIN_LOD_MIN, // note that this is less than max - TERRAIN_LOD_STRETCH_NO_CLOUDS, - TERRAIN_LOD_HALF_CLOUDS, - TERRAIN_LOD_NO_CLOUDS, - TERRAIN_LOD_STRETCH_CLOUDS, - TERRAIN_LOD_NO_WATER, - TERRAIN_LOD_MAX, // note that this is larger than min - TERRAIN_LOD_AUTOMATIC, - TERRAIN_LOD_DISABLE, - - TERRAIN_LOD_NUM_TYPES - -} TerrainLOD; -#ifdef DEFINE_TERRAIN_LOD_NAMES -static const char *const TerrainLODNames[] = -{ - "NONE", - "MIN", - "STRETCH_NO_CLOUDS", - "HALF_CLOUDS", - "NO_CLOUDS", - "STRETCH_CLOUDS", - "NO_WATER", - "MAX", - "AUTOMATIC", - "DISABLE", - - NULL -}; -static_assert(ARRAY_SIZE(TerrainLODNames) == TERRAIN_LOD_NUM_TYPES + 1, "Incorrect array size"); -#endif // end DEFINE_TERRAIN_LOD_NAMES - -//------------------------------------------------------------------------------------------------- -/** Device independent implementation for visual terrain */ -//------------------------------------------------------------------------------------------------- -class TerrainVisual : public Snapshot, - public SubsystemInterface -{ - -public: - - enum {NumSkyboxTextures = 5}; - - TerrainVisual(); - virtual ~TerrainVisual(); - - virtual void init( void ); - virtual void reset( void ); - virtual void update( void ); - - virtual Bool load( AsciiString filename ); - - /// get color of texture on the terrain at location specified - virtual void getTerrainColorAt( Real x, Real y, RGBColor *pColor ) = 0; - - /// get the terrain tile type at the world location in the (x,y) plane ignoring Z - virtual TerrainType *getTerrainTile( Real x, Real y ) = 0; - - /** intersect the ray with the terrain, if a hit occurs TRUE is returned - and the result point on the terrain is returned in "result" */ - virtual Bool intersectTerrain( Coord3D *rayStart, - Coord3D *rayEnd, - Coord3D *result ) { return FALSE; } - - // - // water methods - // - virtual void enableWaterGrid( Bool enable ) = 0; - /// set min/max height values allowed in water grid pointed to by waterTable - virtual void setWaterGridHeightClamps( const WaterHandle *waterTable, Real minZ, Real maxZ ) = 0; - /// adjust fallof parameters for grid change method - virtual void setWaterAttenuationFactors( const WaterHandle *waterTable, Real a, Real b, Real c, Real range ) = 0; - /// set the water table position and orientation in world space - virtual void setWaterTransform( const WaterHandle *waterTable, Real angle, Real x, Real y, Real z ) = 0; - virtual void setWaterTransform( const Matrix3D *transform ) = 0; - /// get water transform parameters - virtual void getWaterTransform( const WaterHandle *waterTable, Matrix3D *transform ) = 0; - /// water grid resolution spacing - virtual void setWaterGridResolution( const WaterHandle *waterTable, Real gridCellsX, Real gridCellsY, Real cellSize ) = 0; - virtual void getWaterGridResolution( const WaterHandle *waterTable, Real *gridCellsX, Real *gridCellsY, Real *cellSize ) = 0; - /// adjust the water grid in world coords by the delta - virtual void changeWaterHeight( Real x, Real y, Real delta ) = 0; - /// adjust the velocity at a water grid point corresponding to the world x,y - virtual void addWaterVelocity( Real worldX, Real worldY, Real velocity, Real preferredHeight ) = 0; - /// get height of water grid at specified position - virtual Bool getWaterGridHeight( Real worldX, Real worldY, Real *height) = 0; - - /// set detail of terrain tracks. - virtual void setTerrainTracksDetail(void)=0; - virtual void setShoreLineDetail(void)=0; - - /// Add a bib for an object at location. - virtual void addFactionBib(Object *factionBuilding, Bool highlight, Real extra = 0)=0; - /// Remove a bib. - virtual void removeFactionBib(Object *factionBuilding)=0; - - /// Add a bib for a drawable at location. - virtual void addFactionBibDrawable(Drawable *factionBuilding, Bool highlight, Real extra = 0)=0; - /// Remove a bib. - virtual void removeFactionBibDrawable(Drawable *factionBuilding)=0; - - virtual void removeAllBibs(void)=0; - virtual void removeBibHighlighting(void)=0; - - - // - // Modify height. - // - virtual void setRawMapHeight(const ICoord2D *gridPos, Int height)=0; - - /// Replace the skybox texture - virtual void replaceSkyboxTextures(const AsciiString *oldTexName[NumSkyboxTextures], const AsciiString *newTexName[NumSkyboxTextures])=0; - -protected: - - // snapshot methods - virtual void crc( Xfer *xfer ); - virtual void xfer( Xfer *xfer ); - virtual void loadPostProcess( void ); - - AsciiString m_filenameString; ///< file with terrain data - -}; - -// EXTERNALS ////////////////////////////////////////////////////////////////////////////////////// -extern TerrainVisual *TheTerrainVisual; ///< singleton extern diff --git a/Generals/Code/GameEngine/Include/GameLogic/PartitionManager.h b/Generals/Code/GameEngine/Include/GameLogic/PartitionManager.h index 20c9146ac3..18e278bb71 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/PartitionManager.h +++ b/Generals/Code/GameEngine/Include/GameLogic/PartitionManager.h @@ -1479,6 +1479,8 @@ class PartitionManager : public SubsystemInterface, public Snapshot CellShroudStatus getShroudStatusForPlayer( Int playerIndex, Int x, Int y ) const; CellShroudStatus getShroudStatusForPlayer( Int playerIndex, const Coord3D *loc ) const; + ObjectShroudStatus getPropShroudStatusForPlayer(Int playerIndex, const Coord3D *loc ) const; + Real getGroundOrStructureHeight(Real posx, Real posy); void getMostValuableLocation( Int playerIndex, UnsignedInt whichPlayerTypes, ValueOrThreat valType, Coord3D *outLocation ); diff --git a/Generals/Code/GameEngine/Source/Common/GlobalData.cpp b/Generals/Code/GameEngine/Source/Common/GlobalData.cpp index 9bb81b3165..348374f57f 100644 --- a/Generals/Code/GameEngine/Source/Common/GlobalData.cpp +++ b/Generals/Code/GameEngine/Source/Common/GlobalData.cpp @@ -670,6 +670,7 @@ GlobalData::GlobalData() m_featherWater = FALSE; m_showSoftWaterEdge = TRUE; //display soft water edge m_usingWaterTrackEditor = FALSE; + m_isWorldBuilder = FALSE; m_showMetrics = false; diff --git a/Generals/Code/GameEngine/Source/Common/INI/INI.cpp b/Generals/Code/GameEngine/Source/Common/INI/INI.cpp index 8e39f00c65..51b8fc2e8a 100644 --- a/Generals/Code/GameEngine/Source/Common/INI/INI.cpp +++ b/Generals/Code/GameEngine/Source/Common/INI/INI.cpp @@ -127,6 +127,7 @@ static const BlockParse theTypeTable[] = { "Video", INI::parseVideoDefinition }, { "WaterSet", INI::parseWaterSettingDefinition }, { "WaterTransparency", INI::parseWaterTransparencyDefinition}, + { "Weather", INI::parseWeatherDefinition}, { "Weapon", INI::parseWeaponTemplateDefinition }, { "WebpageURL", INI::parseWebpageURLDefinition }, { "HeaderTemplate", INI::parseHeaderTemplateDefinition }, diff --git a/Generals/Code/GameEngine/Source/Common/Thing/ThingFactory.cpp b/Generals/Code/GameEngine/Source/Common/Thing/ThingFactory.cpp index 8c75ab0f3d..22db98ea19 100644 --- a/Generals/Code/GameEngine/Source/Common/Thing/ThingFactory.cpp +++ b/Generals/Code/GameEngine/Source/Common/Thing/ThingFactory.cpp @@ -134,7 +134,7 @@ ThingTemplate *ThingFactory::newTemplate( const AsciiString& name ) newTemplate = newInstance(ThingTemplate); // if the default template is present, get it and copy over any data to the new template - const ThingTemplate *defaultT = findTemplate( "DefaultThingTemplate" ); + const ThingTemplate *defaultT = findTemplate( "DefaultThingTemplate", FALSE ); if( defaultT ) { @@ -265,7 +265,7 @@ const ThingTemplate *ThingFactory::findByTemplateID( UnsignedShort id ) //------------------------------------------------------------------------------------------------- /** Return the template with the matching database name */ //------------------------------------------------------------------------------------------------- -ThingTemplate *ThingFactory::findTemplateInternal( const AsciiString& name ) +ThingTemplate *ThingFactory::findTemplateInternal( const AsciiString& name, Bool check ) { ThingTemplateHashMapIt tIt = m_templateHashMap.find(name); @@ -292,7 +292,10 @@ ThingTemplate *ThingFactory::findTemplateInternal( const AsciiString& name ) #endif - //DEBUG_LOG(("*** Object template %s not found",name.str())); + if( check && name.isNotEmpty() ) + { + DEBUG_CRASH( ("Failed to find thing template %s (case sensitive) This issue has a chance of crashing after you ignore it!", name.str() ) ); + } return NULL; } @@ -372,7 +375,7 @@ AsciiString TheThingTemplateBeingParsedName; #endif // find existing item if present - ThingTemplate *thingTemplate = TheThingFactory->findTemplateInternal( name ); + ThingTemplate *thingTemplate = TheThingFactory->findTemplateInternal( name, FALSE ); if( !thingTemplate ) { // no item is present, create a new one diff --git a/Generals/Code/GameEngine/Source/GameClient/MapUtil.cpp b/Generals/Code/GameEngine/Source/GameClient/MapUtil.cpp deleted file mode 100644 index 41fcbb2578..0000000000 --- a/Generals/Code/GameEngine/Source/GameClient/MapUtil.cpp +++ /dev/null @@ -1,1348 +0,0 @@ -/* -** Command & Conquer Generals(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) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -// FILE: MapUtil.cpp ////////////////////////////////////////////////////////////////////////////// -// Author: Matt Campbell, December 2001 -// Description: Map utility/convenience routines -/////////////////////////////////////////////////////////////////////////////////////////////////// - -// INCLUDES /////////////////////////////////////////////////////////////////////////////////////// -#include "PreRTS.h" // This must go first in EVERY cpp file in the GameEngine - -#include "Common/crc.h" -#include "Common/FileSystem.h" -#include "Common/LocalFileSystem.h" -#include "Common/file.h" -#include "Common/GlobalData.h" -#include "Common/GameState.h" -#include "Common/GameEngine.h" -#include "Common/NameKeyGenerator.h" -#include "Common/DataChunk.h" -#include "Common/MapReaderWriterInfo.h" -#include "Common/MessageStream.h" -#include "Common/WellKnownKeys.h" -#include "Common/INI.h" -#include "Common/QuotedPrintable.h" -#include "Common/SkirmishBattleHonors.h" -#include "Common/ThingFactory.h" -#include "Common/ThingTemplate.h" -#include "Common/MapObject.h" -#include "GameClient/GameText.h" -#include "GameClient/WindowLayout.h" -#include "GameClient/Gadget.h" -#include "GameClient/Image.h" -#include "GameClient/Shell.h" -#include "GameClient/GameWindowManager.h" -#include "GameClient/GadgetListBox.h" -#include "GameClient/MapUtil.h" -#include "GameLogic/GameLogic.h" -#include "GameLogic/FPUControl.h" -#include "GameNetwork/GameInfo.h" -#include "GameNetwork/NetworkDefs.h" - - -//------------------------------------------------------------------------------- -// PRIVATE DATA /////////////////////////////////////////////////////////////////////////////////// -static const char *mapExtension = ".map"; - -static Int m_width = 0; ///< Height map width. -static Int m_height = 0; ///< Height map height (y size of array). -static Int m_borderSize = 0; ///< Non-playable border area. -static std::vector m_boundaries; ///< All the boundaries we use for the map -static Int m_dataSize = 0; ///< size of m_data. -static UnsignedByte *m_data = 0; ///< array of z(height) values in the height map. -static Dict worldDict = 0; - -static WaypointMap *m_waypoints = 0; -static Coord3DList m_supplyPositions; -static Coord3DList m_techPositions; - -static Int m_mapDX = 0; -static Int m_mapDY = 0; - -static UnsignedInt calcCRC( AsciiString fname ) -{ - CRC theCRC; - theCRC.clear(); - - File *fp = TheFileSystem->openFile(fname.str(), File::READ); - if( !fp ) - { - DEBUG_CRASH(("Couldn't open '%s'", fname.str())); - return 0; - } - - UnsignedByte buf[4096]; - Int num; - while ( (num=fp->read(buf, 4096)) > 0 ) - { - theCRC.computeCRC(buf, num); - } - - fp->close(); - fp = NULL; - - return theCRC.get(); -} - -static Bool ParseObjectDataChunk(DataChunkInput &file, DataChunkInfo *info, void *userData) -{ - Bool readDict = info->version >= K_OBJECTS_VERSION_2; - - Coord3D loc; - loc.x = file.readReal(); - loc.y = file.readReal(); - loc.z = file.readReal(); - if (info->version <= K_OBJECTS_VERSION_2) - { - loc.z = 0; - } - - Real angle = file.readReal(); - Int flags = file.readInt(); - AsciiString name = file.readAsciiString(); - Dict d; - if (readDict) - { - d = file.readDict(); - } - MapObject *pThisOne; - - // create the map object - pThisOne = newInstance( MapObject )( loc, name, angle, flags, &d, - TheThingFactory->findTemplate( name ) ); - -//DEBUG_LOG(("obj %s owner %s",name.str(),d.getAsciiString(TheKey_originalOwner).str())); - - if (pThisOne->getProperties()->getType(TheKey_waypointID) == Dict::DICT_INT) - { - pThisOne->setIsWaypoint(); - - // grab useful info - (*m_waypoints)[pThisOne->getWaypointName()] = loc; - } - else if (pThisOne->getThingTemplate() && pThisOne->getThingTemplate()->isKindOf(KINDOF_TECH_BUILDING)) - { - m_techPositions.push_back(loc); - } - else if (pThisOne->getThingTemplate() && pThisOne->getThingTemplate()->isKindOf(KINDOF_SUPPLY_SOURCE_ON_PREVIEW)) - { - m_supplyPositions.push_back(loc); - } - - deleteInstance(pThisOne); - return TRUE; -} - -static Bool ParseObjectsDataChunk(DataChunkInput &file, DataChunkInfo *info, void *userData) -{ - file.m_currentObject = NULL; - file.registerParser( "Object", info->label, ParseObjectDataChunk ); - return (file.parse(userData)); -} - -static Bool ParseWorldDictDataChunk(DataChunkInput &file, DataChunkInfo *info, void *userData) -{ - worldDict = file.readDict(); - return true; -} - -static Bool ParseSizeOnly(DataChunkInput &file, DataChunkInfo *info, void *userData) -{ - m_width = file.readInt(); - m_height = file.readInt(); - if (info->version >= K_HEIGHT_MAP_VERSION_3) { - m_borderSize = file.readInt(); - } else { - m_borderSize = 0; - } - - if (info->version >= K_HEIGHT_MAP_VERSION_4) { - Int numBorders = file.readInt(); - m_boundaries.resize(numBorders); - for (int i = 0; i < numBorders; ++i) { - m_boundaries[i].x = file.readInt(); - m_boundaries[i].y = file.readInt(); - } - } - return true; - - m_dataSize = file.readInt(); - m_data = NEW UnsignedByte[m_dataSize]; // pool[]ify - if (m_dataSize <= 0 || (m_dataSize != (m_width*m_height))) { - throw ERROR_CORRUPT_FILE_FORMAT ; - } - file.readArrayOfBytes((char *)m_data, m_dataSize); - // Resize me. - if (info->version == K_HEIGHT_MAP_VERSION_1) { - Int newWidth = (m_width+1)/2; - Int newHeight = (m_height+1)/2; - Int i, j; - for (i=0; ilo.x = 0.0f; - - extent->lo.y = 0.0f; - - // Note - m_mapDX & Y are the number of height map grids wide, so we have to - // multiply by the grid width. - extent->hi.x = m_mapDX*MAP_XY_FACTOR; - extent->hi.y = m_mapDY*MAP_XY_FACTOR; - - extent->lo.z = 0; - extent->hi.z = 0; -} - -//------------------------------------------------------------------------------- - -void WaypointMap::update( void ) -{ - if (!m_waypoints) - { - m_numStartSpots = 1; - return; - } - - this->clear(); - - AsciiString startingCamName = TheNameKeyGenerator->keyToName(TheKey_InitialCameraPosition); - WaypointMap::const_iterator it; - - it = m_waypoints->find(startingCamName); - if (it != m_waypoints->end()) - { - (*this)[startingCamName] = it->second; - } - - m_numStartSpots = 0; - for (Int i=0; ifind(startingCamName); - if (it != m_waypoints->end()) - { - (*this)[startingCamName] = it->second; - ++m_numStartSpots; - } - else - { - break; - } - } - - m_numStartSpots = max(1, m_numStartSpots); -} - -const char *const MapCache::m_mapCacheName = "MapCache.ini"; - -AsciiString MapCache::getMapDir() const -{ - return "Maps"; -} - -AsciiString MapCache::getUserMapDir() const -{ - AsciiString tmp = TheGlobalData->getPath_UserData(); - tmp.concat(getMapDir()); - return tmp; -} - -AsciiString MapCache::getMapExtension() const -{ - return "map"; -} - -void MapCache::writeCacheINI( const AsciiString &mapDir ) -{ - AsciiString filepath = mapDir; - filepath.concat('\\'); - - TheFileSystem->createDirectory(mapDir); - - filepath.concat(m_mapCacheName); - FILE *fp = fopen(filepath.str(), "w"); - DEBUG_ASSERTCRASH(fp != NULL, ("Failed to create %s", filepath.str())); - if (fp == NULL) { - return; - } - - fprintf(fp, "; FILE: %s /////////////////////////////////////////////////////////////\n", filepath.str()); - fprintf(fp, "; This INI file is auto-generated - do not modify\n"); - fprintf(fp, "; /////////////////////////////////////////////////////////////////////////////\n"); - - MapCache::iterator it = begin(); - for (; it != end(); ++it) - { - if (it->first.startsWithNoCase(mapDir.str())) - { - const MapMetaData &md = it->second; - fprintf(fp, "\nMapCache %s\n", AsciiStringToQuotedPrintable(it->first.str()).str()); - fprintf(fp, " fileSize = %u\n", md.m_filesize); - fprintf(fp, " fileCRC = %u\n", md.m_CRC); - fprintf(fp, " timestampLo = %d\n", md.m_timestamp.m_lowTimeStamp); - fprintf(fp, " timestampHi = %d\n", md.m_timestamp.m_highTimeStamp); - fprintf(fp, " isOfficial = %s\n", (md.m_isOfficial)?"yes":"no"); - - fprintf(fp, " isMultiplayer = %s\n", (md.m_isMultiplayer)?"yes":"no"); - fprintf(fp, " numPlayers = %d\n", md.m_numPlayers); - - fprintf(fp, " extentMin = X:%2.2f Y:%2.2f Z:%2.2f\n", md.m_extent.lo.x, md.m_extent.lo.y, md.m_extent.lo.z); - fprintf(fp, " extentMax = X:%2.2f Y:%2.2f Z:%2.2f\n", md.m_extent.hi.x, md.m_extent.hi.y, md.m_extent.hi.z); - -// BAD AND NOW UNUSED: the mapcache.ini should not contain localized data... using the lookup tag instead -#if RTS_GENERALS - fprintf(fp, " displayName = %s\n", UnicodeStringToQuotedPrintable(md.m_displayName).str()); -#else - fprintf(fp, " nameLookupTag = %s\n", md.m_nameLookupTag.str()); -#endif - - Coord3D pos; - WaypointMap::const_iterator itw = md.m_waypoints.begin(); - for (; itw != md.m_waypoints.end(); ++itw) - { - pos = itw->second; - fprintf(fp, " %s = X:%2.2f Y:%2.2f Z:%2.2f\n", itw->first.str(), pos.x, pos.y, pos.z); - } - Coord3DList::const_iterator itc3d = md.m_techPositions.begin(); - for (; itc3d != md.m_techPositions.end(); ++itc3d) - { - pos = *itc3d; - fprintf(fp, " techPosition = X:%2.2f Y:%2.2f Z:%2.2f\n", pos.x, pos.y, pos.z); - } - - itc3d = md.m_supplyPositions.begin(); - for (; itc3d != md.m_supplyPositions.end(); ++itc3d) - { - pos = *itc3d; - fprintf(fp, " supplyPosition = X:%2.2f Y:%2.2f Z:%2.2f\n", pos.x, pos.y, pos.z); - } - fprintf(fp, "END\n\n"); - } - else - { - //DEBUG_LOG(("%s does not start %s", mapDir.str(), it->first.str())); - } - } - - fclose(fp); -} - -void MapCache::updateCache( void ) -{ - setFPMode(); - - const AsciiString mapDir = getMapDir(); - const AsciiString userMapDir = getUserMapDir(); - - // Create the standard map cache if required. Is only relevant for Mod developers. - // TheSuperHackers @tweak This step is done before loading any other map caches to not poison the cached state. - if (m_doCreateStandardMapCacheINI) - { -#if defined(RTS_DEBUG) - // only create the map cache file if "Maps" folder exists - const Bool buildMapCache = TheLocalFileSystem->doesFileExist(mapDir.str()); -#else - const Bool buildMapCache = TheGlobalData->m_buildMapCache; -#endif - if (buildMapCache) - { - const Bool isOfficial = TRUE; - const Bool filterByAllowedMaps = !m_allowedMaps.empty(); - - if (loadMapsFromDisk(mapDir, isOfficial, filterByAllowedMaps)) - { - writeCacheINI(mapDir); - } - } - m_doCreateStandardMapCacheINI = FALSE; - } - - // Load user map cache first. - if (m_doLoadUserMapCacheINI) - { - loadMapsFromMapCacheINI(userMapDir); - m_doLoadUserMapCacheINI = FALSE; - } - - // Load user maps from disk and update any discrepancies from the map cache. - if (loadMapsFromDisk(userMapDir, FALSE)) - { - writeCacheINI(userMapDir); - m_doLoadStandardMapCacheINI = TRUE; - } - - // Load standard maps from map cache last. - // This overwrites matching user maps to prevent munkees getting rowdy :) - if (m_doLoadStandardMapCacheINI) - { - loadMapsFromMapCacheINI(mapDir); - m_doLoadStandardMapCacheINI = FALSE; - } -} - -void MapCache::prepareUnseenMaps( const AsciiString &mapDir ) -{ - MapCache::iterator it = begin(); - for (; it != end(); ++it) - { - const AsciiString &mapName = it->first; - - if (mapName.startsWithNoCase(mapDir.str())) - { - it->second.m_doesExist = FALSE; - } - } -} - -Bool MapCache::clearUnseenMaps( const AsciiString &mapDir ) -{ - Bool erasedSomething = FALSE; - - MapCache::iterator it = begin(); - while (it != end()) - { - MapCache::iterator next = it; - ++next; - - const AsciiString &mapName = it->first; - const MapMetaData &mapData = it->second; - - if (mapName.startsWithNoCase(mapDir.str()) && !mapData.m_doesExist) - { - erase(it); - erasedSomething = TRUE; - } - - it = next; - } - - return erasedSomething; -} - -void MapCache::loadMapsFromMapCacheINI( const AsciiString &mapDir ) -{ - INI ini; - AsciiString fname; - fname.format("%s\\%s", mapDir.str(), m_mapCacheName); - - if (TheFileSystem->doesFileExist(fname.str())) - { - ini.load( fname, INI_LOAD_OVERWRITE, NULL ); - } -} - -Bool MapCache::loadMapsFromDisk( const AsciiString &mapDir, Bool isOfficial, Bool filterByAllowedMaps ) -{ - prepareUnseenMaps(mapDir); - - FilenameList filepathList; - FilenameListIter filepathIt; - AsciiString toplevelPattern; - toplevelPattern.format("%s\\", mapDir.str()); - Bool mapListChanged = FALSE; - AsciiString filenamepattern; - filenamepattern.format("*.%s", getMapExtension().str()); - - TheFileSystem->getFileListInDirectory(toplevelPattern, filenamepattern, filepathList, TRUE); - - filepathIt = filepathList.begin(); - - for (; filepathIt != filepathList.end(); ++filepathIt) - { - FileInfo fileInfo; - AsciiString filepathLower = *filepathIt; - filepathLower.toLower(); - - const char *szFilenameLower = filepathLower.reverseFind('\\'); - if (!szFilenameLower) - { - DEBUG_CRASH(("Couldn't find \\ in map name!")); - continue; - } - - AsciiString endingStr; - AsciiString filenameLower = szFilenameLower+1; - filenameLower.truncateBy(strlen(mapExtension)); - - if (filterByAllowedMaps && m_allowedMaps.find(filenameLower) == m_allowedMaps.end()) - { - DEBUG_CRASH(("Map '%s' has been filtered out", filenameLower.str())); - continue; - } - - endingStr.format("%s\\%s%s", filenameLower.str(), filenameLower.str(), mapExtension); - - if (!filepathLower.endsWithNoCase(endingStr.str())) - { - DEBUG_CRASH(("Found map '%s' in wrong spot (%s)", filenameLower.str(), filepathLower.str())); - continue; - } - - if (!TheFileSystem->getFileInfo(*filepathIt, &fileInfo)) - { - DEBUG_CRASH(("Could not get file info for map %s", filepathIt->str())); - continue; - } - - mapListChanged |= addMap(mapDir, *filepathIt, filepathLower, fileInfo, isOfficial); - } - - if (clearUnseenMaps(mapDir)) - { - mapListChanged = TRUE; - } - - return mapListChanged; -} - -Bool MapCache::addMap( - const AsciiString &mapDir, - const AsciiString &fname, - const AsciiString &lowerFname, - FileInfo &fileInfo, - Bool isOfficial) -{ - MapCache::iterator it = find(lowerFname); - if (it != end()) - { - // Found the map in our cache. Check to see if it has changed. - const MapMetaData& md = it->second; - - if (md.m_filesize == fileInfo.sizeLow && md.m_CRC != 0) - { - // Force a lookup so that we don't display the English localization in all builds. - if (md.m_nameLookupTag.isEmpty()) - { - // unofficial maps or maps without names - AsciiString tempdisplayname; - tempdisplayname = fname.reverseFind('\\') + 1; - (*this)[lowerFname].m_displayName.translate(tempdisplayname); - if (md.m_numPlayers >= 2) - { - UnicodeString extension; - extension.format(L" (%d)", md.m_numPlayers); - (*this)[lowerFname].m_displayName.concat(extension); - } - } - else - { - // official maps with name tags - (*this)[lowerFname].m_displayName = TheGameText->fetch(md.m_nameLookupTag); - if (md.m_numPlayers >= 2) - { - UnicodeString extension; - extension.format(L" (%d)", md.m_numPlayers); - (*this)[lowerFname].m_displayName.concat(extension); - } - } - - it->second.m_doesExist = TRUE; - -// DEBUG_LOG(("MapCache::addMap - found match for map %s", lowerFname.str())); - return FALSE; // OK, it checks out. - } - DEBUG_LOG(("%s didn't match file in MapCache", fname.str())); - DEBUG_LOG(("size: %d / %d", fileInfo.sizeLow, md.m_filesize)); - DEBUG_LOG(("time1: %d / %d", fileInfo.timestampHigh, md.m_timestamp.m_highTimeStamp)); - DEBUG_LOG(("time2: %d / %d", fileInfo.timestampLow, md.m_timestamp.m_lowTimeStamp)); -// DEBUG_LOG(("size: %d / %d", filesize, md.m_filesize)); -// DEBUG_LOG(("time1: %d / %d", timestamp.m_highTimeStamp, md.m_timestamp.m_highTimeStamp)); -// DEBUG_LOG(("time2: %d / %d", timestamp.m_lowTimeStamp, md.m_timestamp.m_lowTimeStamp)); - } - - DEBUG_LOG(("MapCache::addMap(): caching '%s' because '%s' was not found", fname.str(), lowerFname.str())); - - loadMap(fname); // Just load for querying the data, since we aren't playing this map. - - // The map is now loaded. Pick out what we need. - MapMetaData md; - md.m_fileName = lowerFname; - md.m_filesize = fileInfo.sizeLow; - md.m_isOfficial = isOfficial; - md.m_doesExist = TRUE; - md.m_waypoints.update(); - md.m_numPlayers = md.m_waypoints.m_numStartSpots; - md.m_isMultiplayer = (md.m_numPlayers >= 2); - md.m_timestamp.m_highTimeStamp = fileInfo.timestampHigh; - md.m_timestamp.m_lowTimeStamp = fileInfo.timestampLow; - md.m_supplyPositions = m_supplyPositions; - md.m_techPositions = m_techPositions; - md.m_CRC = calcCRC(fname); - - Bool exists = false; - AsciiString nameLookupTag = worldDict.getAsciiString(TheKey_mapName, &exists); - md.m_nameLookupTag = nameLookupTag; - - if (!exists || nameLookupTag.isEmpty()) - { - DEBUG_LOG(("Missing TheKey_mapName!")); - AsciiString tempdisplayname; - tempdisplayname = fname.reverseFind('\\') + 1; - md.m_displayName.translate(tempdisplayname); - if (md.m_numPlayers >= 2) - { - UnicodeString extension; - extension.format(L" (%d)", md.m_numPlayers); - md.m_displayName.concat(extension); - } - TheGameText->reset(); - } - else - { - AsciiString stringFileName; - stringFileName.format("%s\\%s", mapDir.str(), fname.str()); - stringFileName.truncateBy(4); - stringFileName.concat("\\map.str"); - TheGameText->initMapStringFile(stringFileName); - md.m_displayName = TheGameText->fetch(nameLookupTag); - if (md.m_numPlayers >= 2) - { - UnicodeString extension; - extension.format(L" (%d)", md.m_numPlayers); - md.m_displayName.concat(extension); - } - DEBUG_LOG(("Map name is now '%ls'", md.m_displayName.str())); - TheGameText->reset(); - } - - getExtent(&(md.m_extent)); - - (*this)[lowerFname] = md; - - DEBUG_LOG((" filesize = %d bytes", md.m_filesize)); - DEBUG_LOG((" displayName = %ls", md.m_displayName.str())); - DEBUG_LOG((" CRC = %X", md.m_CRC)); - DEBUG_LOG((" timestamp = %d", md.m_timestamp)); - DEBUG_LOG((" isOfficial = %s", (md.m_isOfficial)?"yes":"no")); - - DEBUG_LOG((" isMultiplayer = %s", (md.m_isMultiplayer)?"yes":"no")); - DEBUG_LOG((" numPlayers = %d", md.m_numPlayers)); - - DEBUG_LOG((" extent = (%2.2f,%2.2f) -> (%2.2f,%2.2f)", - md.m_extent.lo.x, md.m_extent.lo.y, - md.m_extent.hi.x, md.m_extent.hi.y)); - - Coord3D pos; - WaypointMap::iterator itw = md.m_waypoints.begin(); - for (; itw != md.m_waypoints.end(); ++itw) - { - pos = itw->second; - DEBUG_LOG((" waypoint %s: (%2.2f,%2.2f)", itw->first.str(), pos.x, pos.y)); - } - - resetMap(); - - return TRUE; -} - -MapCache *TheMapCache = NULL; - -// PUBLIC FUNCTIONS ////////////////////////////////////////////////////////////////////////////// - -Bool WouldMapTransfer( const AsciiString& mapName ) -{ - return mapName.startsWithNoCase(TheMapCache->getUserMapDir()); -} - -//------------------------------------------------------------------------------------------------- -typedef std::set > MapNameList; -typedef std::map MapDisplayToFileNameList; - -static void buildMapListForNumPlayers(MapNameList &outMapNames, MapDisplayToFileNameList &outFileNames, Int numPlayers) -{ - MapCache::iterator it = TheMapCache->begin(); - - for (; it != TheMapCache->end(); ++it) - { - const MapMetaData &mapData = it->second; - if (mapData.m_numPlayers == numPlayers) - { - outMapNames.insert(it->second.m_displayName); - outFileNames[it->second.m_displayName] = it->first; - } - } -} - -//------------------------------------------------------------------------------------------------- -struct MapListBoxData -{ - MapListBoxData() - : listbox(NULL) - , numLength(0) - , numColumns(0) - , w(10) - , h(10) - , color(GameMakeColor(255, 255, 255, 255)) - , battleHonors(NULL) - , easyImage(NULL) - , mediumImage(NULL) - , brutalImage(NULL) - , maxBrutalImage(NULL) - , mapToSelect() - , selectionIndex(0) // always select *something* - , isMultiplayer(false) - { - } - - GameWindow *listbox; - Int numLength; - Int numColumns; - Int w; - Int h; - Color color; - const SkirmishBattleHonors *battleHonors; - const Image *easyImage; - const Image *mediumImage; - const Image *brutalImage; - const Image *maxBrutalImage; - AsciiString mapToSelect; - Int selectionIndex; - Bool isMultiplayer; -}; - -//------------------------------------------------------------------------------------------------- -static Bool addMapToMapListbox( - MapListBoxData& lbData, - const AsciiString& mapDir, - const AsciiString& mapName, - const MapMetaData& mapMetaData) -{ - const Bool mapOk = mapName.startsWithNoCase(mapDir.str()) && lbData.isMultiplayer == mapMetaData.m_isMultiplayer && !mapMetaData.m_displayName.isEmpty(); - - if (mapOk) - { - UnicodeString mapDisplayName; - /// @todo: mapDisplayName = TheGameText->fetch(mapMetaData.m_displayName.str()); - mapDisplayName = mapMetaData.m_displayName; - - Int index = -1; - Int imageItemData = -1; - if (lbData.numColumns > 1 && mapMetaData.m_isMultiplayer) - { - const Int numEasy = lbData.battleHonors->getEnduranceMedal(mapName.str(), SLOT_EASY_AI); - const Int numMedium = lbData.battleHonors->getEnduranceMedal(mapName.str(), SLOT_MED_AI); - const Int numBrutal = lbData.battleHonors->getEnduranceMedal(mapName.str(), SLOT_BRUTAL_AI); - if (numBrutal) - { - const Int maxBrutalSlots = mapMetaData.m_numPlayers - 1; - if (lbData.maxBrutalImage != NULL && numBrutal == maxBrutalSlots) - { - index = GadgetListBoxAddEntryImage( lbData.listbox, lbData.maxBrutalImage, index, 0, lbData.w, lbData.h, TRUE); - imageItemData = 4; - } - else - { - index = GadgetListBoxAddEntryImage( lbData.listbox, lbData.brutalImage, index, 0, lbData.w, lbData.h, TRUE); - imageItemData = 3; - } - } - else if (numMedium) - { - imageItemData = 2; - index = GadgetListBoxAddEntryImage( lbData.listbox, lbData.mediumImage, index, 0, lbData.w, lbData.h, TRUE); - } - else if (numEasy) - { - imageItemData = 1; - index = GadgetListBoxAddEntryImage( lbData.listbox, lbData.easyImage, index, 0, lbData.w, lbData.h, TRUE); - } - else - { - imageItemData = 0; - index = GadgetListBoxAddEntryImage( lbData.listbox, NULL, index, 0, lbData.w, lbData.h, TRUE); - } - } - - index = GadgetListBoxAddEntryText( lbData.listbox, mapDisplayName, lbData.color, index, lbData.numColumns-1 ); - DEBUG_ASSERTCRASH(index >= 0, ("Expects valid index")); - - if (mapName == lbData.mapToSelect) - { - lbData.selectionIndex = index; - } - - // now set the char* as the item data. this works because the map cache isn't being - // modified while a map listbox is up. - GadgetListBoxSetItemData( lbData.listbox, (void *)(mapName.str()), index ); - - if (lbData.numColumns > 1) - { - GadgetListBoxSetItemData( lbData.listbox, (void *)imageItemData, index, 1 ); - } - - // TheSuperHackers @performance Now stops processing when the list is full. - if (index == lbData.numLength - 1) - { - return false; - } - } - - return true; -} - -//------------------------------------------------------------------------------------------------- -static Bool addMapCollectionToMapListbox( - MapListBoxData& lbData, - const AsciiString& mapDir, - const MapNameList& mapNames, - const MapDisplayToFileNameList& fileNames) -{ - MapNameList::const_iterator mapNameIt = mapNames.begin(); - - for (; mapNameIt != mapNames.end(); ++mapNameIt) - { - MapDisplayToFileNameList::const_iterator fileNameIt = fileNames.find(*mapNameIt); - DEBUG_ASSERTCRASH(fileNameIt != fileNames.end(), ("Map '%s' not found in file names map", mapNameIt->str())); - - const AsciiString& asciiMapName = fileNameIt->second; - -#if RTS_ZEROHOUR - //Patch 1.03 -- Purposely filter out these broken maps that exist in Generals. - if( !asciiMapName.compare( "maps\\armored fury\\armored fury.map" ) || - !asciiMapName.compare( "maps\\scorched earth\\scorched earth.map" ) ) - { - continue; - } -#endif - - MapCache::iterator mapCacheIt = TheMapCache->find(asciiMapName); - DEBUG_ASSERTCRASH(mapCacheIt != TheMapCache->end(), ("Map '%s' not found in map cache.", mapNameIt->str())); - /* - if (it != TheMapCache->end()) - { - DEBUG_LOG(("populateMapListbox(): looking at %s (displayName = %ls), mp = %d (== %d?) mapDir=%s (ok=%d)", - it->first.str(), it->second.m_displayName.str(), it->second.m_isMultiplayer, isMultiplayer, - mapDir.str(), it->first.startsWith(mapDir.str()))); - } - */ - - const Bool ok = addMapToMapListbox(lbData, mapDir, mapCacheIt->first, mapCacheIt->second); - - if (!ok) - return false; - } - - return true; -} - -//------------------------------------------------------------------------------------------------- -/** Load the listbox with all the map files available to play */ -//------------------------------------------------------------------------------------------------- -Int populateMapListboxNoReset( GameWindow *listbox, Bool useSystemMaps, Bool isMultiplayer, AsciiString mapToSelect ) -{ - if(!TheMapCache) - return -1; - - if (!listbox) - return -1; - - MapListBoxData lbData; - lbData.listbox = listbox; - lbData.numLength = GadgetListBoxGetListLength( listbox ); - lbData.numColumns = GadgetListBoxGetNumColumns( listbox ); - lbData.mapToSelect = mapToSelect; - lbData.isMultiplayer = isMultiplayer; - - if (lbData.numColumns > 1) - { - lbData.easyImage = TheMappedImageCollection->findImageByName("Star-Bronze"); - lbData.mediumImage = TheMappedImageCollection->findImageByName("Star-Silver"); - lbData.brutalImage = TheMappedImageCollection->findImageByName("Star-Gold"); - lbData.maxBrutalImage = TheMappedImageCollection->findImageByName("RedYell_Star"); - lbData.battleHonors = new SkirmishBattleHonors; - - lbData.w = lbData.brutalImage ? lbData.brutalImage->getImageWidth() : 10; - lbData.w = min(GadgetListBoxGetColumnWidth(listbox, 0), lbData.w); - lbData.h = lbData.w; - } - - AsciiString mapDir; - if (useSystemMaps) - { - mapDir = TheMapCache->getMapDir(); - } - else - { - mapDir = TheGlobalData->getPath_UserData(); - mapDir.concat(TheMapCache->getMapDir()); - } - mapDir.toLower(); - - MapNameList mapNames; - MapDisplayToFileNameList fileNames; - Int curNumPlayersInMap = 1; - - for (; curNumPlayersInMap <= MAX_SLOTS; ++curNumPlayersInMap) - { - buildMapListForNumPlayers(mapNames, fileNames, curNumPlayersInMap); - - const Bool ok = addMapCollectionToMapListbox(lbData, mapDir, mapNames, fileNames); - - mapNames.clear(); - fileNames.clear(); - - if (!ok) - break; - } - - delete lbData.battleHonors; - lbData.battleHonors = NULL; - - GadgetListBoxSetSelected(listbox, &lbData.selectionIndex, 1); - - if (lbData.selectionIndex >= 0) - { - Int topIndex = GadgetListBoxGetTopVisibleEntry(listbox); - Int bottomIndex = GadgetListBoxGetBottomVisibleEntry(listbox); - Int rowsOnScreen = bottomIndex - topIndex; - - if (lbData.selectionIndex >= bottomIndex) - { - Int newTop = max( 0, lbData.selectionIndex - max( 1, rowsOnScreen / 2 ) ); - //The trouble is that rowsOnScreen/2 can be zero if bottom is 1 and top is zero - GadgetListBoxSetTopVisibleEntry( listbox, newTop ); - } - } - - return lbData.selectionIndex; -} - -//------------------------------------------------------------------------------------------------- -/** Load the listbox with all the map files available to play */ -//------------------------------------------------------------------------------------------------- -Int populateMapListbox( GameWindow *listbox, Bool useSystemMaps, Bool isMultiplayer, AsciiString mapToSelect ) -{ - if(!TheMapCache) - return -1; - - if (!listbox) - return -1; - - // reset the listbox content - GadgetListBoxReset( listbox ); - - return populateMapListboxNoReset( listbox, useSystemMaps, isMultiplayer, mapToSelect ); -} - - - -//------------------------------------------------------------------------------------------------- -/** Validate a map */ -//------------------------------------------------------------------------------------------------- -Bool isValidMap( AsciiString mapName, Bool isMultiplayer ) -{ - if(!TheMapCache || mapName.isEmpty()) - return FALSE; - TheMapCache->updateCache(); - - mapName.toLower(); - MapCache::iterator it = TheMapCache->find(mapName); - if (it != TheMapCache->end()) - { - if (isMultiplayer == it->second.m_isMultiplayer) - { - return TRUE; - } - } - - return FALSE; -} - -//------------------------------------------------------------------------------------------------- -/** Find a valid map */ -//------------------------------------------------------------------------------------------------- -AsciiString getDefaultMap( Bool isMultiplayer ) -{ - if(!TheMapCache) - return AsciiString::TheEmptyString; - TheMapCache->updateCache(); - - MapCache::iterator it = TheMapCache->begin(); - for (; it != TheMapCache->end(); ++it) - { - if (isMultiplayer == it->second.m_isMultiplayer) - { - return it->first; - } - } - - return AsciiString::TheEmptyString; -} - - -AsciiString getDefaultOfficialMap() -{ - if(!TheMapCache) - return AsciiString::TheEmptyString; - TheMapCache->updateCache(); - - MapCache::iterator it = TheMapCache->begin(); - for (; it != TheMapCache->end(); ++it) - { - if (it->second.m_isMultiplayer && it->second.m_isOfficial) - { - return it->first; - } - } - return AsciiString::TheEmptyString; -} - - -Bool isOfficialMap( AsciiString mapName ) -{ - if(!TheMapCache || mapName.isEmpty()) - return FALSE; - TheMapCache->updateCache(); - mapName.toLower(); - MapCache::iterator it = TheMapCache->find(mapName); - if (it != TheMapCache->end()) - return it->second.m_isOfficial; - return FALSE; -} - - -const MapMetaData *MapCache::findMap(AsciiString mapName) -{ - mapName.toLower(); - MapCache::iterator it = find(mapName); - if (it == end()) - return NULL; - return &(it->second); -} - -// ------------------------------------------------------------------------------------------------ -/** Embed the pristine map into the xfer stream */ -// ------------------------------------------------------------------------------------------------ -static void copyFromBigToDir( const AsciiString& infile, const AsciiString& outfile ) -{ - // open the map file - - File *file = TheFileSystem->openFile( infile.str(), File::READ | File::BINARY ); - if( file == NULL ) - { - DEBUG_CRASH(( "copyFromBigToDir - Error opening source file '%s'", infile.str() )); - throw SC_INVALID_DATA; - } - - // how big is the map file - Int fileSize = file->seek( 0, File::END ); - - - // rewind to beginning of file - file->seek( 0, File::START ); - - // allocate buffer big enough to hold the entire map file - char *buffer = NEW char[ fileSize ]; - if( buffer == NULL ) - { - DEBUG_CRASH(( "copyFromBigToDir - Unable to allocate buffer for file '%s'", infile.str() )); - throw SC_INVALID_DATA; - } - - // copy the file to the buffer - if( file->read( buffer, fileSize ) < fileSize ) - { - DEBUG_CRASH(( "copyFromBigToDir - Error reading from file '%s'", infile.str() )); - throw SC_INVALID_DATA; - } - // close the BIG file - file->close(); - - File *filenew = TheFileSystem->openFile( outfile.str(), File::WRITE | File::CREATE | File::BINARY ); - - if( !filenew || filenew->write(buffer, fileSize) < fileSize) - { - DEBUG_CRASH(( "copyFromBigToDir - Error writing to file '%s'", outfile.str() )); - throw SC_INVALID_DATA; - } - - filenew->close(); - - // delete the buffer - delete [] buffer; -} - -Image *getMapPreviewImage( AsciiString mapName ) -{ - if(!TheGlobalData) - return NULL; - DEBUG_LOG(("%s Map Name", mapName.str())); - AsciiString tgaName = mapName; - AsciiString name; - AsciiString tempName; - tgaName.truncateBy(4); // ".map" - name = tgaName; - tgaName.concat(".tga"); - - AsciiString portableName = TheGameState->realMapPathToPortableMapPath(name); - tempName.set(AsciiString::TheEmptyString); - for(Int i = 0; i < portableName.getLength(); ++i) - { - char c = portableName.getCharAt(i); - if (c == '\\' || c == ':') - tempName.concat('_'); - else - tempName.concat(c); - } - - name = tempName; - name.concat(".tga"); - - - // copy file over - // copy source tgaName, to name - - Image *image = (Image *)TheMappedImageCollection->findImageByName(tempName); - if(!image) - { - - if(!TheFileSystem->doesFileExist(tgaName.str())) - return NULL; - AsciiString mapPreviewDir; - mapPreviewDir.format(MAP_PREVIEW_DIR_PATH, TheGlobalData->getPath_UserData().str()); - TheFileSystem->createDirectory(mapPreviewDir); - - mapPreviewDir.concat(name); - - Bool success = false; - try - { - copyFromBigToDir(tgaName, mapPreviewDir); - success = true; - } - catch (...) - { - success = false; // no rethrow - } - - if (success) - { - image = newInstance(Image); - image->setName(tempName); - //image->setFullPath("mission.tga"); - image->setFilename(name); - image->setStatus(IMAGE_STATUS_NONE); - Region2D uv; - uv.hi.x = 1.0f; - uv.hi.y = 1.0f; - uv.lo.x = 0.0f; - uv.lo.y = 0.0f; - image->setUV(&uv); - image->setTextureHeight(128); - image->setTextureWidth(128); - TheMappedImageCollection->addImage(image); - } - else - { - image = NULL; - } - } - - return image; - - - -/* - // sanity - if( mapName.isEmpty() ) - return NULL; - Region2D uv; - mapPreviewImage = TheMappedImageCollection->findImageByName("MapPreview"); - if(mapPreviewImage) - deleteInstance(mapPreviewImage); - - mapPreviewImage = TheMappedImageCollection->newImage(); - mapPreviewImage->setName("MapPreview"); - mapPreviewImage->setStatus(IMAGE_STATUS_RAW_TEXTURE); -// allocate our terrain texture - TextureClass * texture = new TextureClass( size.x, size.y, - WW3D_FORMAT_X8R8G8B8, MIP_LEVELS_1 ); - uv.lo.x = 0.0f; - uv.lo.y = 1.0f; - uv.hi.x = 1.0f; - uv.hi.y = 0.0f; - mapPreviewImage->setStatus( IMAGE_STATUS_RAW_TEXTURE ); - mapPreviewImage->setRawTextureData( texture ); - mapPreviewImage->setUV( &uv ); - mapPreviewImage->setTextureWidth( size.x ); - mapPreviewImage->setTextureHeight( size.y ); - mapPreviewImage->setImageSize( &size ); - - - CachedFileInputStream theInputStream; - if (theInputStream.open(AsciiString(mapName.str()))) - { - ChunkInputStream *pStrm = &theInputStream; - pStrm->absoluteSeek(0); - DataChunkInput file( pStrm ); - if (file.isValidFileType()) { // Backwards compatible files aren't valid data chunk files. - // Read the waypoints. - file.registerParser( "MapPreview", AsciiString::TheEmptyString, parseMapPreviewChunk ); - if (!file.parse(NULL)) { - DEBUG_ASSERTCRASH(false,("Unable to read MapPreview info.")); - deleteInstance(mapPreviewImage); - return NULL; - } - } - theInputStream.close(); - } - else - { - deleteInstance(mapPreviewImage); - return NULL; - } - - - return mapPreviewImage; - -*/ - return NULL; -} - -Bool parseMapPreviewChunk(DataChunkInput &file, DataChunkInfo *info, void *userData) -{ -/* - ICoord2D size; - - SurfaceClass *surface; - size.x = file.readInt(); - size.y = file.readInt(); - - - surface = (TextureClass *)mapPreviewImage->getRawTextureData()->Get_Surface_Level(); - //texture->Get_Surface_Level(); - - DEBUG_LOG(("BeginMapPreviewInfo")); - UnsignedInt *buffer = new UnsignedInt[size.x * size.y]; - Int x,y; - for (y=0; yDrawPixel( x, y, file.readInt() ); - buffer[y + x] = file.readInt(); - DEBUG_LOG(("x:%d, y:%d, %X", x, y, buffer[y + x])); - } - } - mapPreviewImage->setRawTextureData(buffer); - DEBUG_ASSERTCRASH(file.atEndOfChunk(), ("Unexpected data left over.")); - DEBUG_LOG(("EndMapPreviewInfo")); - REF_PTR_RELEASE(surface); - return true; -*/ - return FALSE; -} - -void findDrawPositions( Int startX, Int startY, Int width, Int height, Region3D extent, - ICoord2D *ul, ICoord2D *lr ) -{ - - Real ratioWidth; - Real ratioHeight; - Coord2D radar; - ratioWidth = extent.width()/(width * 1.0f); - ratioHeight = extent.height()/(height* 1.0f); - - if( ratioWidth >= ratioHeight) - { - radar.x = extent.width() / ratioWidth; - radar.y = extent.height()/ ratioWidth; - ul->x = 0; - ul->y = (height - radar.y) / 2.0f; - lr->x = radar.x; - lr->y = height - ul->y; - } - else - { - radar.x = extent.width() / ratioHeight; - radar.y = extent.height()/ ratioHeight; - ul->x = (width - radar.x ) / 2.0f; - ul->y = 0; - lr->x = width - ul->x; - lr->y = radar.y; - } - - // make them pixel positions - ul->x += startX; - ul->y += startY; - lr->x += startX; - lr->y += startY; - -} - diff --git a/Generals/Code/GameEngine/Source/GameClient/Terrain/TerrainRoads.cpp b/Generals/Code/GameEngine/Source/GameClient/Terrain/TerrainRoads.cpp deleted file mode 100644 index 03f3054a91..0000000000 --- a/Generals/Code/GameEngine/Source/GameClient/Terrain/TerrainRoads.cpp +++ /dev/null @@ -1,458 +0,0 @@ -/* -** Command & Conquer Generals(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) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -// FILE: TerrainRoads.cpp ///////////////////////////////////////////////////////////////////////// -// Author: Colin Day, December 2001 -// Desc: Terrain road/bridge descriptions -/////////////////////////////////////////////////////////////////////////////////////////////////// - -// INCLDUES /////////////////////////////////////////////////////////////////////////////////////// -#include "PreRTS.h" // This must go first in EVERY cpp file in the GameEngine - -#define DEFINE_BODYDAMAGETYPE_NAMES -#include "Common/INI.h" -#include "GameClient/TerrainRoads.h" - -// PUBLIC DATA //////////////////////////////////////////////////////////////////////////////////// -TerrainRoadCollection *TheTerrainRoads = NULL; - -// PRIVATE DATA /////////////////////////////////////////////////////////////////////////////////// -UnsignedInt TerrainRoadCollection::m_idCounter = 0; - -//------------------------------------------------------------------------------------------------- -//------------------------------------------------------------------------------------------------- -const FieldParse TerrainRoadType::m_terrainRoadFieldParseTable[] = -{ - - { "Texture", INI::parseAsciiString, NULL, offsetof( TerrainRoadType, m_texture ) }, - { "RoadWidth", INI::parseReal, NULL, offsetof( TerrainRoadType, m_roadWidth ) }, - { "RoadWidthInTexture", INI::parseReal, NULL, offsetof( TerrainRoadType, m_roadWidthInTexture ) }, - - { NULL, NULL, NULL, 0 }, - -}; - -//------------------------------------------------------------------------------------------------- -//------------------------------------------------------------------------------------------------- -const FieldParse TerrainRoadType::m_terrainBridgeFieldParseTable[] = -{ - - { "BridgeScale", INI::parseReal, NULL, offsetof( TerrainRoadType, m_bridgeScale ) }, - { "ScaffoldObjectName", INI::parseAsciiString, NULL, offsetof( TerrainRoadType, m_scaffoldObjectName ) }, - { "ScaffoldSupportObjectName", INI::parseAsciiString, NULL, offsetof( TerrainRoadType, m_scaffoldSupportObjectName ) }, - { "RadarColor", INI::parseRGBColor, NULL, offsetof( TerrainRoadType, m_radarColor ) }, - - { "TransitionEffectsHeight", INI::parseReal, NULL, offsetof( TerrainRoadType, m_transitionEffectsHeight ) }, - { "NumFXPerType", INI::parseInt, NULL, offsetof( TerrainRoadType, m_numFXPerType ) }, - - { "BridgeModelName", INI::parseAsciiString, NULL, offsetof( TerrainRoadType, m_bridgeModelName ) }, - { "Texture", INI::parseAsciiString, NULL, offsetof( TerrainRoadType, m_texture ) }, - { "BridgeModelNameDamaged", INI::parseAsciiString, NULL, offsetof( TerrainRoadType, m_bridgeModelNameDamaged ) }, - { "TextureDamaged", INI::parseAsciiString, NULL, offsetof( TerrainRoadType, m_textureDamaged ) }, - { "BridgeModelNameReallyDamaged", INI::parseAsciiString, NULL, offsetof( TerrainRoadType, m_bridgeModelNameReallyDamaged ) }, - { "TextureReallyDamaged", INI::parseAsciiString, NULL, offsetof( TerrainRoadType, m_textureReallyDamaged ) }, - { "BridgeModelNameBroken", INI::parseAsciiString, NULL, offsetof( TerrainRoadType, m_bridgeModelNameBroken ) }, - { "TextureBroken", INI::parseAsciiString, NULL, offsetof( TerrainRoadType, m_textureBroken ) }, - - { "TowerObjectNameFromLeft", INI::parseAsciiString, NULL, offsetof( TerrainRoadType, m_towerObjectName[ BRIDGE_TOWER_FROM_LEFT ] ) }, - { "TowerObjectNameFromRight", INI::parseAsciiString, NULL, offsetof( TerrainRoadType, m_towerObjectName[ BRIDGE_TOWER_FROM_RIGHT ] ) }, - { "TowerObjectNameToLeft", INI::parseAsciiString, NULL, offsetof( TerrainRoadType, m_towerObjectName[ BRIDGE_TOWER_TO_LEFT ] ) }, - { "TowerObjectNameToRight", INI::parseAsciiString, NULL, offsetof( TerrainRoadType, m_towerObjectName[ BRIDGE_TOWER_TO_RIGHT ] ) }, - - { "DamagedToSound", INI::parseAsciiString, NULL, offsetof( TerrainRoadType, m_damageToSoundString[ BODY_DAMAGED ] ) }, - { "RepairedToSound", INI::parseAsciiString, NULL, offsetof( TerrainRoadType, m_repairedToSoundString[ BODY_DAMAGED ] ) }, - { "TransitionToOCL", parseTransitionToOCL, NULL, NULL }, - { "TransitionToFX", parseTransitionToFX, NULL, NULL }, - - - { NULL, NULL, NULL, 0 }, - -}; - -// ------------------------------------------------------------------------------------------------ -/** In the form of - * Label = Transition: ToState: EffectNum: OCL: */ -// ------------------------------------------------------------------------------------------------ -/*static*/ void TerrainRoadType::parseTransitionToOCL( INI *ini, - void *instance, - void *store, - const void *userData ) -{ - const char *token; - TerrainRoadType *theInstance = (TerrainRoadType *)instance; - - // which transition is this - Bool damageTransition; - token = ini->getNextSubToken( "Transition" ); - if( stricmp( token, "Damage" ) == 0 ) - damageTransition = TRUE; - else if( stricmp( token, "Repair" ) == 0 ) - damageTransition = FALSE; - else - { - - DEBUG_CRASH(( "Expected Damage/Repair transition keyword" )); - throw INI_INVALID_DATA; - - } - - // get body damage state - token = ini->getNextSubToken( "ToState" ); - BodyDamageType state = (BodyDamageType)ini->scanIndexList( token, TheBodyDamageTypeNames ); - - // get effect num - token = ini->getNextSubToken( "EffectNum" ); - Int effectNum = ini->scanInt( token ); - - // make effectNum zero based - --effectNum; - - // sanity check effect num - if( effectNum < 0 || effectNum >= MAX_BRIDGE_BODY_FX ) - { - - DEBUG_CRASH(( "Effect number max on bridge transitions is '%d'", MAX_BRIDGE_BODY_FX )); - throw INI_INVALID_DATA; - - } - - // read the string - token = ini->getNextSubToken( "OCL" ); - if( damageTransition ) - theInstance->friend_setDamageToOCLString( state, effectNum, AsciiString( token ) ); - else - theInstance->friend_setRepairedToOCLString( state, effectNum, AsciiString( token ) ); - -} - -// ------------------------------------------------------------------------------------------------ -/** In the form of - * Label = Transition: ToState: EffectNum: FX: */ -// ------------------------------------------------------------------------------------------------ -/*static*/ void TerrainRoadType::parseTransitionToFX( INI *ini, - void *instance, - void *store, - const void *userData ) -{ - const char *token; - TerrainRoadType *theInstance = (TerrainRoadType *)instance; - - // which transition is this - Bool damageTransition; - token = ini->getNextSubToken( "Transition" ); - if( stricmp( token, "Damage" ) == 0 ) - damageTransition = TRUE; - else if( stricmp( token, "Repair" ) == 0 ) - damageTransition = FALSE; - else - { - - DEBUG_CRASH(( "Expected Damage/Repair transition keyword" )); - throw INI_INVALID_DATA; - - } - - // get body damage state - token = ini->getNextSubToken( "ToState" ); - BodyDamageType state = (BodyDamageType)ini->scanIndexList( token, TheBodyDamageTypeNames ); - - // get effect num - token = ini->getNextSubToken( "EffectNum" ); - Int effectNum = ini->scanInt( token ); - - // make effectNum zero based - --effectNum; - - // sanity check effect num - if( effectNum < 0 || effectNum >= MAX_BRIDGE_BODY_FX ) - { - - DEBUG_CRASH(( "Effect number max on bridge transitions is '%d'", MAX_BRIDGE_BODY_FX )); - throw INI_INVALID_DATA; - - } - - // read the string - token = ini->getNextSubToken( "FX" ); - if( damageTransition ) - theInstance->friend_setDamageToFXString( state, effectNum, AsciiString( token ) ); - else - theInstance->friend_setRepairedToFXString( state, effectNum, AsciiString( token ) ); - -} - -//------------------------------------------------------------------------------------------------- -//------------------------------------------------------------------------------------------------- -TerrainRoadType::TerrainRoadType( void ) -{ - - m_isBridge = FALSE; - m_id = 0; - m_next = NULL; - m_roadWidth = 0.0f; - m_roadWidthInTexture = 0.0f; - m_bridgeScale = 1.0f; - m_radarColor.red = 0.0f; - m_radarColor.green = 0.0f; - m_radarColor.blue = 0.0f; - m_transitionEffectsHeight = 0.0f; - m_numFXPerType = 0; - -} - -//------------------------------------------------------------------------------------------------- -//------------------------------------------------------------------------------------------------- -TerrainRoadType::~TerrainRoadType( void ) -{ - -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////////// - -//------------------------------------------------------------------------------------------------- -//------------------------------------------------------------------------------------------------- -TerrainRoadCollection::TerrainRoadCollection( void ) -{ - - m_roadList = NULL; - m_bridgeList = NULL; - - m_idCounter = 1; ///< MUST start this at 1. - -} - -//------------------------------------------------------------------------------------------------- -//------------------------------------------------------------------------------------------------- -TerrainRoadCollection::~TerrainRoadCollection( void ) -{ - TerrainRoadType *temp; - - // delete all roads in the list - while( m_roadList ) - { - - // get next road - temp = m_roadList->friend_getNext(); - - // delete this road - deleteInstance(m_roadList); - - // set the new head of the list - m_roadList = temp; - - } - - // delete all bridges in the list - while( m_bridgeList ) - { - - // get next bridge - temp = m_bridgeList->friend_getNext(); - - // delete this bridge - deleteInstance(m_bridgeList); - - // set the new head of the list - m_bridgeList = temp; - - } - -} - -//------------------------------------------------------------------------------------------------- -/** Find road with matching name */ -//------------------------------------------------------------------------------------------------- -TerrainRoadType *TerrainRoadCollection::findRoad( AsciiString name ) -{ - TerrainRoadType *road; - - for( road = m_roadList; road; road = nextRoad( road ) ) - { - - if( road->getName() == name ) - return road; - - } - - // not found - return NULL; - -} - -//------------------------------------------------------------------------------------------------- -/** Find bridge with matching name */ -//------------------------------------------------------------------------------------------------- -TerrainRoadType *TerrainRoadCollection::findBridge( AsciiString name ) -{ - TerrainRoadType *bridge; - - for( bridge = m_bridgeList; bridge; bridge = nextBridge( bridge ) ) - { - - if( bridge->getName() == name ) - return bridge; - - } - - // not found - return NULL; - -} - -//------------------------------------------------------------------------------------------------- -/** Search the roads AND bridge lists for the name */ -//------------------------------------------------------------------------------------------------- -TerrainRoadType *TerrainRoadCollection::findRoadOrBridge( AsciiString name ) -{ - TerrainRoadType *road = findRoad( name ); - - if( road ) - return road; - else - return findBridge( name ); - -} - -//------------------------------------------------------------------------------------------------- -/** Allocate a new road, set the name, and link to the road list */ -//------------------------------------------------------------------------------------------------- -TerrainRoadType *TerrainRoadCollection::newRoad( AsciiString name ) -{ - TerrainRoadType *road = newInstance(TerrainRoadType); - - // assign the name - road->friend_setName( name ); - - // assign unique id - road->friend_setID( m_idCounter++ ); - - // is not a bridge - road->friend_setBridge( FALSE ); - - // set defaults from the default road - TerrainRoadType *defaultRoad = findRoad( "DefaultRoad" ); - if( defaultRoad ) - { - - road->friend_setTexture( defaultRoad->getTexture() ); - road->friend_setRoadWidth( defaultRoad->getRoadWidth() ); - road->friend_setRoadWidthInTexture( defaultRoad->getRoadWidthInTexture() ); - - } - - // link to list - road->friend_setNext( m_roadList ); - m_roadList = road; - - // return the new road - return road; - -} - -//------------------------------------------------------------------------------------------------- -/** Allocate a new bridge */ -//------------------------------------------------------------------------------------------------- -TerrainRoadType *TerrainRoadCollection::newBridge( AsciiString name ) -{ - TerrainRoadType *bridge = newInstance(TerrainRoadType); - - // assign the name - bridge->friend_setName( name ); - - // assign unique id - bridge->friend_setID( m_idCounter++ ); - - // is a bridge - bridge->friend_setBridge( TRUE ); - - // set defaults from the default bridge - TerrainRoadType *defaultBridge = findBridge( "DefaultBridge" ); - if( defaultBridge ) - { - - bridge->friend_setTexture( defaultBridge->getTexture() ); - bridge->friend_setBridgeScale( defaultBridge->getBridgeScale() ); - bridge->friend_setBridgeModelName( defaultBridge->getBridgeModel() ); - bridge->friend_setBridgeModelNameDamaged( defaultBridge->getBridgeModelNameDamaged() ); - bridge->friend_setBridgeModelNameReallyDamaged( defaultBridge->getBridgeModelNameReallyDamaged() ); - bridge->friend_setBridgeModelNameBroken( defaultBridge->getBridgeModelNameBroken() ); - bridge->friend_setTextureDamaged( defaultBridge->getTextureDamaged() ); - bridge->friend_setTextureReallyDamaged( defaultBridge->getTextureReallyDamaged() ); - bridge->friend_setTextureBroken( defaultBridge->getTextureBroken() ); - - bridge->friend_setTransitionEffectsHeight( defaultBridge->getTransitionEffectsHeight() ); - bridge->friend_setNumFXPerType( defaultBridge->getNumFXPerType() ); - for( Int state = BODY_PRISTINE; state < BODYDAMAGETYPE_COUNT; state++ ) - { - - bridge->friend_setDamageToSoundString( (BodyDamageType)state, bridge->getDamageToSoundString( (BodyDamageType)state ) ); - bridge->friend_setRepairedToSoundString( (BodyDamageType)state, bridge->getRepairedToSoundString( (BodyDamageType)state ) ); - - for( Int i = 0; i < MAX_BRIDGE_BODY_FX; i++ ) - { - - bridge->friend_setDamageToOCLString( (BodyDamageType)state, i, bridge->getDamageToOCLString( (BodyDamageType)state, i ) ); - bridge->friend_setDamageToFXString( (BodyDamageType)state, i, bridge->getDamageToOCLString( (BodyDamageType)state, i ) ); - bridge->friend_setRepairedToOCLString( (BodyDamageType)state, i, bridge->getDamageToOCLString( (BodyDamageType)state, i ) ); - bridge->friend_setRepairedToFXString( (BodyDamageType)state, i, bridge->getDamageToOCLString( (BodyDamageType)state, i ) ); - - } - - } - - } - - // link to list - bridge->friend_setNext( m_bridgeList ); - m_bridgeList = bridge; - - // return the new bridge - return bridge; - -} - -//------------------------------------------------------------------------------------------------- -/** Return next road in list */ -//------------------------------------------------------------------------------------------------- -TerrainRoadType *TerrainRoadCollection::nextRoad( TerrainRoadType *road ) -{ - - DEBUG_ASSERTCRASH( road->isBridge() == FALSE, ("nextRoad: road not a road") ); - return road->friend_getNext(); - -} - -//------------------------------------------------------------------------------------------------- -/** Return next bridge in list */ -//------------------------------------------------------------------------------------------------- -TerrainRoadType *TerrainRoadCollection::nextBridge( TerrainRoadType *bridge ) -{ - - DEBUG_ASSERTCRASH( bridge->isBridge() == TRUE, ("nextBridge, bridge is not a bridge") ); - return bridge->friend_getNext(); - -} - diff --git a/Generals/Code/GameEngine/Source/GameClient/Terrain/TerrainVisual.cpp b/Generals/Code/GameEngine/Source/GameClient/Terrain/TerrainVisual.cpp deleted file mode 100644 index 712769dde3..0000000000 --- a/Generals/Code/GameEngine/Source/GameClient/Terrain/TerrainVisual.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/* -** Command & Conquer Generals(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) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -// FILE: TerrainVisual.cpp //////////////////////////////////////////////////////////////////////// -// Interface for visual representation of terrain on the client -// Author: Colin Day, April 2001 -/////////////////////////////////////////////////////////////////////////////////////////////////// - -#include "PreRTS.h" // This must go first in EVERY cpp file in the GameEngine -#include "Common/Xfer.h" -#include "GameClient/TerrainVisual.h" - - - - - -// GLOBALS //////////////////////////////////////////////////////////////////////////////////////// -TerrainVisual *TheTerrainVisual = NULL; - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// DEFINITIONS -/////////////////////////////////////////////////////////////////////////////////////////////////// - -//------------------------------------------------------------------------------------------------- -//------------------------------------------------------------------------------------------------- -TerrainVisual::TerrainVisual() -{ - -} - -//------------------------------------------------------------------------------------------------- -//------------------------------------------------------------------------------------------------- -TerrainVisual::~TerrainVisual() -{ - -} - -//------------------------------------------------------------------------------------------------- -/** initialize the device independent functionality of the visual terrain */ -//------------------------------------------------------------------------------------------------- -void TerrainVisual::init( void ) -{ - -} - -//------------------------------------------------------------------------------------------------- -/** Reset */ -//------------------------------------------------------------------------------------------------- -void TerrainVisual::reset( void ) -{ - - m_filenameString.clear(); - -} - -//------------------------------------------------------------------------------------------------- -/** Update */ -//------------------------------------------------------------------------------------------------- -void TerrainVisual::update( void ) -{ - // All the interesting stuff happens in load. jba. -} - -//------------------------------------------------------------------------------------------------- -/** device independent implementation for common terrain visual systems */ -//------------------------------------------------------------------------------------------------- -Bool TerrainVisual::load( AsciiString filename ) -{ - - // save the filename - if (filename.isEmpty()) - return FALSE; - - m_filenameString = filename; - - return TRUE; // success - -} - -// ------------------------------------------------------------------------------------------------ -/** CRC */ -// ------------------------------------------------------------------------------------------------ -void TerrainVisual::crc( Xfer *xfer ) -{ - -} - -// ------------------------------------------------------------------------------------------------ -/** Xfer - * Version Info: - * 1: Initial version */ -// ------------------------------------------------------------------------------------------------ -void TerrainVisual::xfer( Xfer *xfer ) -{ - - // version - XferVersion currentVersion = 1; - XferVersion version = currentVersion; - xfer->xferVersion( &version, currentVersion ); - -} - -// ------------------------------------------------------------------------------------------------ -/** Load post process */ -// ------------------------------------------------------------------------------------------------ -void TerrainVisual::loadPostProcess( void ) -{ - -} diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/PartitionManager.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/PartitionManager.cpp index b2c353701d..9986736965 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/PartitionManager.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/PartitionManager.cpp @@ -3080,6 +3080,32 @@ CellShroudStatus PartitionManager::getShroudStatusForPlayer(Int playerIndex, con } +//----------------------------------------------------------------------------- +ObjectShroudStatus PartitionManager::getPropShroudStatusForPlayer(Int playerIndex, const Coord3D *loc ) const +{ + Int x, y; + + ThePartitionManager->worldToCell( loc->x - m_cellSize*0.5f, loc->y - m_cellSize*0.5f, &x, &y ); + + CellShroudStatus cellStat = getShroudStatusForPlayer( playerIndex, x, y ); + if (cellStat != getShroudStatusForPlayer( playerIndex, x+1, y )) { + return OBJECTSHROUD_PARTIAL_CLEAR; + } + if (cellStat != getShroudStatusForPlayer( playerIndex, x+1, y+1 )) { + return OBJECTSHROUD_PARTIAL_CLEAR; + } + if (cellStat != getShroudStatusForPlayer( playerIndex, x, y+1 )) { + return OBJECTSHROUD_PARTIAL_CLEAR; + } + if (cellStat == CELLSHROUD_SHROUDED) { + return OBJECTSHROUD_SHROUDED; + } + if (cellStat == CELLSHROUD_CLEAR) { + return OBJECTSHROUD_CLEAR; + } + return OBJECTSHROUD_FOGGED; +} + #ifdef FASTER_GCO diff --git a/Generals/Code/GameEngine/Source/GameLogic/ScriptEngine/ScriptActions.cpp b/Generals/Code/GameEngine/Source/GameLogic/ScriptEngine/ScriptActions.cpp index e0242d431c..6680f09c8c 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/ScriptEngine/ScriptActions.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/ScriptEngine/ScriptActions.cpp @@ -4923,7 +4923,7 @@ void ScriptActions::doMoveUnitTowardsNearest( const AsciiString& unitName, const return; } - const ThingTemplate *templ = TheThingFactory->findTemplate(objectType); + const ThingTemplate *templ = TheThingFactory->findTemplate(objectType, FALSE); if (!templ) { return; } @@ -4958,7 +4958,7 @@ void ScriptActions::doMoveTeamTowardsNearest( const AsciiString& teamName, const return; } - const ThingTemplate *templ = TheThingFactory->findTemplate(objectType); + const ThingTemplate *templ = TheThingFactory->findTemplate(objectType, FALSE); if (!templ) { return; } @@ -5447,7 +5447,7 @@ void ScriptActions::doTeamUseCommandButtonOnNearestObjectType( const AsciiString return; } - const ThingTemplate *thingTemplate = TheThingFactory->findTemplate(objectType); + const ThingTemplate *thingTemplate = TheThingFactory->findTemplate(objectType, FALSE); if (!thingTemplate) { return; } diff --git a/Generals/Code/GameEngineDevice/CMakeLists.txt b/Generals/Code/GameEngineDevice/CMakeLists.txt index 37a9ed2334..ab3d8f1d62 100644 --- a/Generals/Code/GameEngineDevice/CMakeLists.txt +++ b/Generals/Code/GameEngineDevice/CMakeLists.txt @@ -6,7 +6,7 @@ set(GAMEENGINEDEVICE_SRC Include/W3DDevice/Common/W3DModuleFactory.h # Include/W3DDevice/Common/W3DRadar.h Include/W3DDevice/Common/W3DThingFactory.h - Include/W3DDevice/GameClient/HeightMap.h +# Include/W3DDevice/GameClient/HeightMap.h Include/W3DDevice/GameClient/Module/W3DDebrisDraw.h Include/W3DDevice/GameClient/Module/W3DDefaultDraw.h Include/W3DDevice/GameClient/Module/W3DDependencyModelDraw.h @@ -22,8 +22,8 @@ set(GAMEENGINEDEVICE_SRC Include/W3DDevice/GameClient/Module/W3DTankTruckDraw.h Include/W3DDevice/GameClient/Module/W3DTracerDraw.h Include/W3DDevice/GameClient/Module/W3DTruckDraw.h - Include/W3DDevice/GameClient/TerrainTex.h - Include/W3DDevice/GameClient/TileData.h +# Include/W3DDevice/GameClient/TerrainTex.h +# Include/W3DDevice/GameClient/TileData.h Include/W3DDevice/GameClient/W3DAssetManager.h Include/W3DDevice/GameClient/W3DAssetManagerExposed.h Include/W3DDevice/GameClient/W3DBibBuffer.h @@ -56,9 +56,9 @@ set(GAMEENGINEDEVICE_SRC Include/W3DDevice/GameClient/W3DShadow.h Include/W3DDevice/GameClient/W3DShroud.h Include/W3DDevice/GameClient/W3DStatusCircle.h - Include/W3DDevice/GameClient/W3DTerrainTracks.h - Include/W3DDevice/GameClient/W3DTerrainVisual.h - Include/W3DDevice/GameClient/W3DTreeBuffer.h +# Include/W3DDevice/GameClient/W3DTerrainTracks.h +# Include/W3DDevice/GameClient/W3DTerrainVisual.h +# Include/W3DDevice/GameClient/W3DTreeBuffer.h # Include/W3DDevice/GameClient/W3DVideoBuffer.h # Include/W3DDevice/GameClient/W3DView.h Include/W3DDevice/GameClient/W3DVolumetricShadow.h @@ -66,7 +66,7 @@ set(GAMEENGINEDEVICE_SRC # Include/W3DDevice/GameClient/W3DWaterTracks.h Include/W3DDevice/GameClient/W3DWaypointBuffer.h Include/W3DDevice/GameClient/W3DWebBrowser.h - Include/W3DDevice/GameClient/WorldHeightMap.h +# Include/W3DDevice/GameClient/WorldHeightMap.h Include/W3DDevice/GameLogic/W3DGameLogic.h Include/W3DDevice/GameLogic/W3DGhostObject.h Include/W3DDevice/GameLogic/W3DTerrainLogic.h @@ -117,7 +117,7 @@ set(GAMEENGINEDEVICE_SRC Source/W3DDevice/GameClient/GUI/W3DGameFont.cpp Source/W3DDevice/GameClient/GUI/W3DGameWindow.cpp Source/W3DDevice/GameClient/GUI/W3DGameWindowManager.cpp - Source/W3DDevice/GameClient/HeightMap.cpp +# Source/W3DDevice/GameClient/HeightMap.cpp Source/W3DDevice/GameClient/Shaders/invmonochrome.nvp Source/W3DDevice/GameClient/Shaders/monochrome.nvp Source/W3DDevice/GameClient/Shaders/motionblur.nvp @@ -130,8 +130,8 @@ set(GAMEENGINEDEVICE_SRC Source/W3DDevice/GameClient/Shadow/W3DProjectedShadow.cpp Source/W3DDevice/GameClient/Shadow/W3DShadow.cpp Source/W3DDevice/GameClient/Shadow/W3DVolumetricShadow.cpp - Source/W3DDevice/GameClient/TerrainTex.cpp - Source/W3DDevice/GameClient/TileData.cpp +# Source/W3DDevice/GameClient/TerrainTex.cpp +# Source/W3DDevice/GameClient/TileData.cpp Source/W3DDevice/GameClient/W3DAssetManager.cpp Source/W3DDevice/GameClient/W3DAssetManagerExposed.cpp Source/W3DDevice/GameClient/W3DBibBuffer.cpp @@ -154,9 +154,9 @@ set(GAMEENGINEDEVICE_SRC # Source/W3DDevice/GameClient/W3DShaderManager.cpp Source/W3DDevice/GameClient/W3DShroud.cpp Source/W3DDevice/GameClient/W3DStatusCircle.cpp - Source/W3DDevice/GameClient/W3DTerrainTracks.cpp - Source/W3DDevice/GameClient/W3DTerrainVisual.cpp - Source/W3DDevice/GameClient/W3DTreeBuffer.cpp +# Source/W3DDevice/GameClient/W3DTerrainTracks.cpp +# Source/W3DDevice/GameClient/W3DTerrainVisual.cpp +# Source/W3DDevice/GameClient/W3DTreeBuffer.cpp # Source/W3DDevice/GameClient/W3DVideoBuffer.cpp # Source/W3DDevice/GameClient/W3DView.cpp Source/W3DDevice/GameClient/W3dWaypointBuffer.cpp @@ -165,7 +165,7 @@ set(GAMEENGINEDEVICE_SRC # Source/W3DDevice/GameClient/Water/W3DWaterTracks.cpp # Source/W3DDevice/GameClient/Water/wave.nvp # Source/W3DDevice/GameClient/Water/wave.nvv - Source/W3DDevice/GameClient/WorldHeightMap.cpp +# Source/W3DDevice/GameClient/WorldHeightMap.cpp Source/W3DDevice/GameLogic/W3DGameLogic.cpp Source/W3DDevice/GameLogic/W3DGhostObject.cpp Source/W3DDevice/GameLogic/W3DTerrainLogic.cpp diff --git a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/HeightMap.h b/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/HeightMap.h deleted file mode 100644 index 4e0829dedd..0000000000 --- a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/HeightMap.h +++ /dev/null @@ -1,323 +0,0 @@ -/* -** Command & Conquer Generals(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) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include "always.h" -#include "rendobj.h" -#include "w3d_file.h" -#include "dx8vertexbuffer.h" -#include "dx8indexbuffer.h" -#include "dx8wrapper.h" -#include "shader.h" -#include "vertmaterial.h" -#include "Lib/BaseType.h" -#include "Common/GameType.h" -#include "WorldHeightMap.h" - -#define MAX_ENABLED_DYNAMIC_LIGHTS 20 -typedef UnsignedByte HeightSampleType; //type of data to store in heightmap -class W3DTreeBuffer; -class W3DBibBuffer; -class W3DRoadBuffer; -class W3DBridgeBuffer; -class W3DWaypointBuffer; -class W3DTerrainLogic; -class W3DCustomEdging; -class W3DAssetManager; -class SimpleSceneClass; -class W3DShroud; - -#define no_TIMING_TESTS 1 - -#define no_PRE_TRANSFORM_VERTEX // Don't do this, not a performance win. jba. - -#define no_USE_TREE_BUFFER ///@todoRe-enable this optimization later... jba. - -typedef struct { - Int minX, maxX; - Int minY, maxY; -} TBounds; - -#define VERTEX_BUFFER_TILE_LENGTH 32 //tiles of side length 32 (grid of 33x33 vertices). - -class LightMapTerrainTextureClass; -class CloudMapTerrainTextureClass; -class W3DDynamicLight; - -#if 0 -#define USE_NORMALS 1 -#define VERTEX_FORMAT VertexFormatXYZNUV2 -#else -#define USE_DIFFUSE 1 -#define VERTEX_FORMAT VertexFormatXYZDUV2 -#define DX8_VERTEX_FORMAT DX8_FVF_XYZDUV2 -#endif - -#define DO_SCORCH 1 - -#define DO_ROADS 1 - -#define TEST_CUSTOM_EDGING 1 - -// Adjust the triangles to make cliff sides most attractive. jba. -#define FLIP_TRIANGLES 1 - -#ifdef DO_SCORCH -typedef struct { - Vector3 location; - Real radius; - Int scorchType; -} TScorch; -#endif - -/// Custom render object that draws the heightmap and handles intersection tests. -/** -Custom W3D render object that's used to process the terrain. It handles -virtually everything to do with the terrain, including: drawing, lighting, -scorchmarks and intersection tests. -*/ -class HeightMapRenderObjClass : public RenderObjClass, public DX8_CleanupHook -{ - -public: - - HeightMapRenderObjClass(void); - ~HeightMapRenderObjClass(void); - - // DX8_CleanupHook methods - virtual void ReleaseResources(void); ///< Release all dx8 resources so the device can be reset. - virtual void ReAcquireResources(void); ///< Reacquire all resources after device reset. - - - ///////////////////////////////////////////////////////////////////////////// - // Render Object Interface (W3D methods) - ///////////////////////////////////////////////////////////////////////////// - virtual RenderObjClass * Clone(void) const; - virtual int Class_ID(void) const; - virtual void Render(RenderInfoClass & rinfo); - virtual bool Cast_Ray(RayCollisionTestClass & raytest); // This CANNOT be Bool, as it will not inherit properly if you make Bool == Int -///@todo: Add methods for collision detection with terrain -// virtual Bool Cast_AABox(AABoxCollisionTestClass & boxtest); -// virtual Bool Cast_OBBox(OBBoxCollisionTestClass & boxtest); -// virtual Bool Intersect_AABox(AABoxIntersectionTestClass & boxtest); -// virtual Bool Intersect_OBBox(OBBoxIntersectionTestClass & boxtest); - - virtual void Get_Obj_Space_Bounding_Sphere(SphereClass & sphere) const; - virtual void Get_Obj_Space_Bounding_Box(AABoxClass & aabox) const; - - - virtual void On_Frame_Update(void); - virtual void Notify_Added(SceneClass * scene); - - ///allocate resources needed to render heightmap - int initHeightData(Int width, Int height, WorldHeightMap *pMap, RefRenderObjListIterator *pLightsIterator); - Int freeMapResources(void); ///< free resources used to render heightmap - UnsignedByte getClipHeight(Int x, Int y) const - { - Int xextent = m_map->getXExtent() - 1; - Int yextent = m_map->getYExtent() - 1; - - if (x < 0) - x = 0; - else if (x > xextent) - x = xextent; - - if (y < 0) - y = 0; - else if (y > yextent) - y = yextent; - - return m_map->getDataPtr()[x + y*m_map->getXExtent()]; - } - void updateCenter(CameraClass *camera, RefRenderObjListIterator *pLightsIterator); - - /// Update the macro texture (pass 3). - void updateMacroTexture(AsciiString textureName); - void doTextures(Bool flag) {m_disableTextures = !flag;}; - /// Update the diffuse value from static light info for one vertex. - void doTheLight(VERTEX_FORMAT *vb, Vector3*light, Vector3*normal, RefRenderObjListIterator *pLightsIterator, UnsignedByte alpha); - void addScorch(Vector3 location, Real radius, Scorches type); - void addTree(Coord3D location, Real scale, Real angle, AsciiString name, Bool visibleInMirror); - void renderTrees(CameraClass * camera); ///< renders the tree buffer. - - /// Add a bib at location. - void addTerrainBib(Vector3 corners[4], ObjectID id, Bool highlight); - void addTerrainBibDrawable(Vector3 corners[4], DrawableID id, Bool highlight); - /// Remove a bib. - void removeTerrainBib(ObjectID id); - void removeTerrainBibDrawable(DrawableID id); - - /// Removes all bibs. - void removeAllTerrainBibs(void); - /// Remove all highlighting. - void removeTerrainBibHighlighting(void); - - void renderTerrainPass(CameraClass *pCamera); ///< renders additional terrain pass. - W3DShroud *getShroud() {return m_shroud;} - void updateShorelineTiles(Int minX, Int minY, Int maxX, Int maxY, WorldHeightMap *pMap); ///
m_showAsVisibleCliff; - - - DX8IndexBufferClass *m_indexBuffer; ///. -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -// TerrainTex.h -// Class to generate texture for terrain. -// Author: John Ahlquist, April 2001 - -#pragma once - -//#define DO_8STAGE_TERRAIN_PASS //optimized terrain rendering for Nvidia based cards - -#include "WW3D2/texture.h" -#include "WWMath/matrix3d.h" -#include "Common/AsciiString.h" - -class WorldHeightMap; -#define TILE_OFFSET 8 -/** *********************************************************************** -** TerrainTextureClass -***************************************************************************/ -class TerrainTextureClass : public TextureClass -{ - W3DMPO_GLUE(TerrainTextureClass) -protected: - virtual void Apply(unsigned int stage); - int update256(WorldHeightMap *htMap);///< Sets the pixels, and returns the actual height of the texture. - -public: - /// Create texture for a height map. - TerrainTextureClass(int height, MipCountType mipLevelCount = MIP_LEVELS_3 ); - - // just use default destructor. ~TerrainTextureClass(void); -public: - int update(WorldHeightMap *htMap); ///< Sets the pixels, and returns the actual height of the texture. - -}; - - -class AlphaTerrainTextureClass : public TextureClass -{ - W3DMPO_GLUE(AlphaTerrainTextureClass) -protected: - virtual void Apply(unsigned int stage); -public: - // Create texture for a height map. - AlphaTerrainTextureClass(TextureClass *pBaseTex ); - - // just use default destructor. ~TerrainTextureClass(void); - -}; - -/** *********************************************************************** -** AlphaEdgeTextureClass -***************************************************************************/ -class AlphaEdgeTextureClass : public TextureClass -{ - W3DMPO_GLUE(AlphaEdgeTextureClass) -protected: - virtual void Apply(unsigned int stage); - int update256(WorldHeightMap *htMap);///< Sets the pixels, and returns the actual height of the texture. - -public: - /// Create texture for a height map. - AlphaEdgeTextureClass(int height, MipCountType mipLevelCount = MIP_LEVELS_3 ); - - // just use default destructor. ~TerrainTextureClass(void); -public: - int update(WorldHeightMap *htMap); ///< Sets the pixels, and returns the actual height of the texture. - -}; - -class LightMapTerrainTextureClass : public TextureClass -{ - W3DMPO_GLUE(LightMapTerrainTextureClass) -protected: - virtual void Apply(unsigned int stage); - -public: - // Create texture from a height map. - LightMapTerrainTextureClass( AsciiString name, MipCountType mipLevelCount = MIP_LEVELS_ALL ); - - // just use default destructor. -}; - -class ScorchTextureClass : public TextureClass -{ - W3DMPO_GLUE(ScorchTextureClass) -protected: - virtual void Apply(unsigned int stage); - -public: - // Create texture. - ScorchTextureClass( MipCountType mipLevelCount = MIP_LEVELS_3 ); - - // just use default destructor. ~ScorchTextureClass(void); -}; - -class CloudMapTerrainTextureClass : public TextureClass -{ - W3DMPO_GLUE(CloudMapTerrainTextureClass) -protected: - virtual void Apply(unsigned int stage); - -protected: - float m_xSlidePerSecond ; ///< How far the clouds move per second. - float m_ySlidePerSecond ; ///< How far the clouds move per second. - int m_curTick; - float m_xOffset; - float m_yOffset; - - -public: - // Create texture from a height map. - CloudMapTerrainTextureClass( MipCountType mipLevelCount = MIP_LEVELS_ALL ); - - // just use default destructor. ~TerrainTextureClass(void); - - void restore(void); -}; diff --git a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/TileData.h b/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/TileData.h deleted file mode 100644 index 8eb350f2ae..0000000000 --- a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/TileData.h +++ /dev/null @@ -1,101 +0,0 @@ -/* -** Command & Conquer Generals(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) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -// TileData.h -// Class to hold 1 tile's data. -// Author: John Ahlquist, April 2001 - -#pragma once - -#include "Lib/BaseType.h" -#include "WWLib/refcount.h" -#include "Common/AsciiString.h" - -typedef struct { - Int blendNdx; - UnsignedByte horiz; - UnsignedByte vert; - UnsignedByte rightDiagonal; - UnsignedByte leftDiagonal; - UnsignedByte inverted; - UnsignedByte longDiagonal; - Int customBlendEdgeClass; // Class of texture for a blend edge. -1 means use alpha. -} TBlendTileInfo; - -#define INVERTED_MASK 0x1 //AND this with TBlendTileInfo.inverted to get actual inverted state -#define FLIPPED_MASK 0x2 //AND this with TBlendTileInfo.inverted to get forced flip state (for horizontal/vertical flips). -#define TILE_PIXEL_EXTENT 64 -#define TILE_BYTES_PER_PIXEL 4 -#define DATA_LEN_BYTES TILE_PIXEL_EXTENT*TILE_PIXEL_EXTENT*TILE_BYTES_PER_PIXEL -#define DATA_LEN_PIXELS TILE_PIXEL_EXTENT*TILE_PIXEL_EXTENT -#define TILE_PIXEL_EXTENT_MIP1 32 -#define TILE_PIXEL_EXTENT_MIP2 16 -#define TILE_PIXEL_EXTENT_MIP3 8 -#define TILE_PIXEL_EXTENT_MIP4 4 -#define TILE_PIXEL_EXTENT_MIP5 2 -#define TILE_PIXEL_EXTENT_MIP6 1 -#define TEXTURE_WIDTH 2048 // was 1024 jba - -/** This class holds the bitmap data from the .tga texture files. It is used to -create the D3D texture in the game and 3d windows, and to create DIB data for the -2d window. */ -class TileData : public RefCountClass -{ -protected: - - // data is bgrabgrabgra to be compatible with windows blt. jba. - // Also, first byte is lower left pixel, not upper left pixel. - // so 0,0 is lower left, not upper left. - UnsignedByte m_tileData[DATA_LEN_BYTES]; - /// Mipped down copies of the tile data. - UnsignedByte m_tileDataMip32[TILE_PIXEL_EXTENT_MIP1*TILE_PIXEL_EXTENT_MIP1*TILE_BYTES_PER_PIXEL]; - UnsignedByte m_tileDataMip16[TILE_PIXEL_EXTENT_MIP2*TILE_PIXEL_EXTENT_MIP2*TILE_BYTES_PER_PIXEL]; - UnsignedByte m_tileDataMip8[TILE_PIXEL_EXTENT_MIP3*TILE_PIXEL_EXTENT_MIP3*TILE_BYTES_PER_PIXEL]; - UnsignedByte m_tileDataMip4[TILE_PIXEL_EXTENT_MIP4*TILE_PIXEL_EXTENT_MIP4*TILE_BYTES_PER_PIXEL]; - UnsignedByte m_tileDataMip2[TILE_PIXEL_EXTENT_MIP5*TILE_PIXEL_EXTENT_MIP5*TILE_BYTES_PER_PIXEL]; - UnsignedByte m_tileDataMip1[TILE_PIXEL_EXTENT_MIP6*TILE_PIXEL_EXTENT_MIP6*TILE_BYTES_PER_PIXEL]; - -public: - ICoord2D m_tileLocationInTexture; - - -protected: - /** doMip - generates the next mip level mipping pHiRes down to pLoRes. - pLoRes is 1/2 the width of pHiRes, and both are square. */ - static void doMip(UnsignedByte *pHiRes, Int hiRow, UnsignedByte *pLoRes); - - - -public: - TileData(void); - -public: - UnsignedByte *getDataPtr(void) {return(m_tileData);}; - static Int dataLen(void) {return(DATA_LEN_BYTES);}; - - void updateMips(void); - - Bool hasRGBDataForWidth(Int width); - UnsignedByte *getRGBDataForWidth(Int width); -}; diff --git a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DBibBuffer.h b/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DBibBuffer.h index 8227e1a272..fedb5ce979 100644 --- a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DBibBuffer.h +++ b/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DBibBuffer.h @@ -83,7 +83,7 @@ typedef struct { // class W3DBibBuffer { -friend class HeightMapRenderObjClass; +friend class BaseHeightMapRenderObjClass; public: W3DBibBuffer(void); diff --git a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DBridgeBuffer.h b/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DBridgeBuffer.h index ad5359665f..979d3d40af 100644 --- a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DBridgeBuffer.h +++ b/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DBridgeBuffer.h @@ -147,7 +147,7 @@ class W3DBridge // class W3DBridgeBuffer { -friend class HeightMapRenderObjClass; +friend class BaseHeightMapRenderObjClass; public: W3DBridgeBuffer(void); diff --git a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DRoadBuffer.h b/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DRoadBuffer.h index 19f9893f71..91e5a4ffe2 100644 --- a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DRoadBuffer.h +++ b/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DRoadBuffer.h @@ -190,7 +190,7 @@ class WorldHeightMap; // class W3DRoadBuffer { -friend class HeightMapRenderObjClass; +friend class BaseHeightMapRenderObjClass; public: W3DRoadBuffer(void); @@ -206,6 +206,8 @@ friend class HeightMapRenderObjClass; void setMap(WorldHeightMap *pMap); /// Updates the diffuse lighting in the buffers. void updateLighting(void); + /// Notifies that the camera moved. + void updateCenter(void); protected: RoadType *m_roadTypes; ///. -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include "always.h" -#include "rendobj.h" -#include "w3d_file.h" -#include "dx8vertexbuffer.h" -#include "dx8indexbuffer.h" -#include "shader.h" -#include "vertmaterial.h" -#include "Lib/BaseType.h" - -#define MAX_TRACK_EDGE_COUNT 100 //maximum number of edges or divisions in track mark -#define MAX_TRACK_OPAQUE_EDGE 25 //linear fade of edges will begin at this edge -#define FADE_TIME_FRAMES 300000 // 300 seconds at 30 fps - time to fade out an edge and remove it from the system. - -class TerrainTracksRenderObjClassSystem; -class Drawable; - -/// Custom render object that draws tracks on the terrain. -/** -This render object handles drawing tracks left by objects moving on the terrain. -*/ -class TerrainTracksRenderObjClass : public W3DMPO, public RenderObjClass -{ - W3DMPO_GLUE(TerrainTracksRenderObjClass) - - friend class TerrainTracksRenderObjClassSystem; - -public: - - TerrainTracksRenderObjClass(void); - ~TerrainTracksRenderObjClass(void); - - ///////////////////////////////////////////////////////////////////////////// - // Render Object Interface (W3D methods) - ///////////////////////////////////////////////////////////////////////////// - virtual RenderObjClass * Clone(void) const; - virtual int Class_ID(void) const; - virtual void Render(RenderInfoClass & rinfo); - virtual void Get_Obj_Space_Bounding_Sphere(SphereClass & sphere) const; - virtual void Get_Obj_Space_Bounding_Box(AABoxClass & aabox) const; - - Int freeTerrainTracksResources(void); ///. -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -// FILE: W3DTerrainVisual.h /////////////////////////////////////////////////////////////////////// -// W3D implementation details for visual aspects of terrain -// Author: Colin Day, April 2001 -/////////////////////////////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include "GameClient/TerrainVisual.h" -#include "W3DDevice/GameClient/W3DWater.h" - -// FORWARD REFERENCES ///////////////////////////////////////////////////////////////////////////// -class Matrix3D; -class WaterHandle; -class HeightMapRenderObjClass; -class WorldHeightMap; - -//------------------------------------------------------------------------------------------------- -/** W3D impelmentation of visual terrain details singleton */ -//------------------------------------------------------------------------------------------------- -class W3DTerrainVisual : public TerrainVisual -{ - -public: - - W3DTerrainVisual(); - virtual ~W3DTerrainVisual(); - - virtual void init( void ); - virtual void reset( void ); - virtual void update( void ); - - virtual Bool load( AsciiString filename ); - - void getTerrainColorAt( Real x, Real y, RGBColor *pColor ); - - /// get the terrain tile type at the world location in the (x,y) plane ignoring Z - TerrainType *getTerrainTile( Real x, Real y ); - - /** intersect the ray with the terrain, if a hit occurs TRUE is returned - and the result point on the terrain is returned in "result" */ - virtual Bool intersectTerrain( Coord3D *rayStart, Coord3D *rayEnd, Coord3D *result ); - - // - // water methods - // - /// enable/disable the water grid - virtual void enableWaterGrid( Bool enable ); - /// set min/max height values allowed in water grid pointed to by waterTable - virtual void setWaterGridHeightClamps( const WaterHandle *waterTable, Real minZ, Real maxZ ); - /// adjust fallof parameters for grid change method - virtual void setWaterAttenuationFactors( const WaterHandle *waterTable, - Real a, Real b, Real c, Real range ); - /// set the water table position and orientation in world space - virtual void setWaterTransform( const WaterHandle *waterTable, - Real angle, Real x, Real y, Real z ); - virtual void setWaterTransform( const Matrix3D *transform ); - virtual void getWaterTransform( const WaterHandle *waterTable, Matrix3D *transform ); - /// water grid resolution spacing - virtual void setWaterGridResolution( const WaterHandle *waterTable, - Real gridCellsX, Real gridCellsY, Real cellSize ); - virtual void getWaterGridResolution( const WaterHandle *waterTable, - Real *gridCellsX, Real *gridCellsY, Real *cellSize ); - /// adjust the water grid in world coords by the delta - virtual void changeWaterHeight( Real x, Real y, Real delta ); - /// adjust the velocity at a water grid point corresponding to the world x,y - virtual void addWaterVelocity( Real worldX, Real worldY, - Real velocity, Real preferredHeight ); - virtual Bool getWaterGridHeight( Real worldX, Real worldY, Real *height); - - virtual void setTerrainTracksDetail(void); - virtual void setShoreLineDetail(void); - - /// Add a bib at location. - void addFactionBib(Object *factionBuilding, Bool highlight, Real extra = 0); - /// Remove a bib. - void removeFactionBib(Object *factionBuilding); - - /// Add a bib at location. - void addFactionBibDrawable(Drawable *factionBuilding, Bool highlight, Real extra = 0); - /// Remove a bib. - void removeFactionBibDrawable(Drawable *factionBuilding); - - virtual void removeAllBibs(void); - virtual void removeBibHighlighting(void); - - // - // Modify height. - // - virtual void setRawMapHeight(const ICoord2D *gridPos, Int height); - - /// Replace the skybox texture - virtual void replaceSkyboxTextures(const AsciiString *oldTexName[NumSkyboxTextures], const AsciiString *newTexName[NumSkyboxTextures]); - - -protected: - - // snapshot methods - virtual void crc( Xfer *xfer ); - virtual void xfer( Xfer *xfer ); - virtual void loadPostProcess( void ); - - HeightMapRenderObjClass *m_terrainRenderObject; ///< W3D render object for terrain - WaterRenderObjClass *m_waterRenderObject; ///< W3D render object for water plane - WorldHeightMap *m_terrainHeightMap; ///< height map used for render obj building - Bool m_isWaterGridRenderingEnabled; - AsciiString m_currentSkyboxTexNames[NumSkyboxTextures]; ///. -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -// FILE: W3DTreeBuffer.h ////////////////////////////////////////////////// -//----------------------------------------------------------------------------- -// -// Westwood Studios Pacific. -// -// Confidential Information -// Copyright (C) 2001 - All Rights Reserved -// -//----------------------------------------------------------------------------- -// -// Project: RTS3 -// -// File name: W3DTreeBuffer.h -// -// Created: John Ahlquist, May 2001 -// -// Desc: Draw buffer to handle all the trees in a scene. -// -//----------------------------------------------------------------------------- - -#pragma once - -//----------------------------------------------------------------------------- -// Includes -//----------------------------------------------------------------------------- -#include "always.h" -#include "rendobj.h" -#include "w3d_file.h" -#include "dx8vertexbuffer.h" -#include "dx8indexbuffer.h" -#include "shader.h" -#include "vertmaterial.h" -#include "Lib/BaseType.h" -#include "Common/GameType.h" -#include "Common/AsciiString.h" - -//----------------------------------------------------------------------------- -// Forward References -//----------------------------------------------------------------------------- -class MeshClass; - -//----------------------------------------------------------------------------- -// Type Defines -//----------------------------------------------------------------------------- - -typedef enum { - ALPINE_TREE = 0, - DECIDUOUS_TREE = 1, - SHRUB = 2, - FENCE = 3 -} TTreeType; - -/// The individual data for a tree. -typedef struct { - Vector3 location; ///< Drawing location - Real scale; ///< Scale at location. - Real sin; ///< Sine of the rotation angle at location. - Real cos; ///< Cosine of the rotation angle at location. - Int panelStart; ///< Index of the "panel" lod. - TTreeType treeType; ///< Type of tree. Currently only 3 supported. - Bool visible; ///< Visible flag, updated each frame. - Bool mirrorVisible; ///< Possibly visible in mirror. - Bool rotates; ///< Trees rotate to follow the camera in single panel mode, fences don't - SphereClass bounds; ///< Bounding sphere for culling to set the visible flag. - Real sortKey; ///< Sort key, essentially the distance along the look at vector. -} TTree; - -// -// W3DTreeBuffer: Draw buffer for the trees. -// -// -class W3DTreeBuffer -{ -friend class HeightMapRenderObjClass; -public: - - W3DTreeBuffer(void); - ~W3DTreeBuffer(void); - /// Add a tree at location. Name is the w3d model name. - void addTree(Coord3D location, Real scale, Real angle, AsciiString name, Bool visibleInMirror); - /// Empties the tree buffer. - void clearAllTrees(void); - /// Draws the trees. Uses camera for culling. - void drawTrees(CameraClass * camera, RefRenderObjListIterator *pDynamicLightsIterator); - /// Called when the view changes, and sort key needs to be recalculated. - /// Normally sortKey gets calculated when a tree becomes visible. - void doFullUpdate(void) {m_updateAllKeys = true;}; - void setIsTerrain(void) {m_isTerrainPass = true;}; ///< Terrain calls this to tell trees to draw. - Bool needToDraw(void) {return m_isTerrainPass;}; -protected: - enum { MAX_TREE_VERTEX=4000, - MAX_TREE_INDEX=2*4000, - MAX_TREES=2000}; - enum {MAX_TYPES = 4, - SORT_ITERATIONS_PER_FRAME=10}; - DX8VertexBufferClass *m_vertexTree; ///. -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - - -// WorldHeightMap.h -// Class to encapsulate height map. -// Author: John Ahlquist, April 2001 - -#pragma once - -#include "Lib/BaseType.h" -#include "WWLib/refcount.h" -#include "WWMath/vector3.h" -#include "W3DDevice/GameClient/TileData.h" -#include "../../GameEngine/Include/Common/MapObject.h" - -#include "Common/STLTypedefs.h" -typedef std::vector VecICoord2D; - - -/** MapObject class -Not ref counted. Do not store pointers to this class. */ - -#define K_MIN_HEIGHT 0 -#define K_MAX_HEIGHT 255 - -#define NUM_SOURCE_TILES 1024 -#define NUM_BLEND_TILES 16192 -#define NUM_CLIFF_INFO 32384 -#define FLAG_VAL 0x7ADA0000 - -// For backwards compatiblity. -#define TEX_PATH_LEN 256 - - -/// Struct in memory. -typedef struct { - Int globalTextureClass; - Int firstTile; - Int numTiles; - Int width; - Int isBlendEdgeTile; ///< True if the texture contains blend edges. - AsciiString name; - ICoord2D positionInTexture; -} TXTextureClass; - -typedef enum {POS_X, POS_Y, NEG_X, NEG_Y} TVDirection; -/// Struct in memory. -typedef struct { - Real u0, v0; // Upper left uv - Real u1, v1; // Lower left uv - Real u2, v2; // Lower right uv - Real u3, v3; // Upper right uv - Bool flip; - Bool mutant; // Mutant mapping needed to get this to fit. - Short tileIndex; // Tile texture. -} TCliffInfo; - -#define NUM_TEXTURE_CLASSES 256 - - -class TextureClass; -class ChunkInputStream; -class InputStream; -class OutputStream; -class DataChunkInput; -struct DataChunkInfo; -class AlphaEdgeTextureClass; - -class WorldHeightMap : public RefCountClass -{ - friend class TerrainTextureClass; - friend class AlphaTerrainTextureClass; - friend class W3DCustomEdging; - friend class AlphaEdgeTextureClass; - -#define NO_EVAL_TILING_MODES - -public: -#ifdef EVAL_TILING_MODES - enum {TILE_4x4, TILE_6x6, TILE_8x8} m_tileMode; -#endif - enum { - NORMAL_DRAW_WIDTH = 129, - NORMAL_DRAW_HEIGHT = 129, - STRETCH_DRAW_WIDTH = 65, - STRETCH_DRAW_HEIGHT = 65 - }; - -protected: - Int m_width; ///< Height map width. - Int m_height; ///< Height map height (y size of array). - Int m_borderSize; ///< Non-playable border area. - VecICoord2D m_boundaries; ///< the in-game boundaries - Int m_dataSize; ///< size of m_data. - UnsignedByte *m_data; ///< array of z(height) values in the height map. - UnsignedByte *m_cellFlipState; ///< array of bits to indicate the flip state of each cell. - Int m_flipStateWidth; ///< with of the array holding cellFlipState - UnsignedByte *m_cellCliffState; ///< array of bits to indicate the cliff state of each cell. - - /// Texture indices. - Short *m_tileNdxes; ///< matches m_Data, indexes into m_SourceTiles. - Short *m_blendTileNdxes; ///< matches m_Data, indexes into m_blendedTiles. 0 means no blend info. - Short *m_cliffInfoNdxes; ///< matches m_Data, indexes into m_cliffInfo. 0 means no cliff info. - Short *m_extraBlendTileNdxes; ///< matches m_Data, indexes into m_extraBlendedTiles. 0 means no blend info. - - - Int m_numBitmapTiles; // Number of tiles initialized from bitmaps in m_SourceTiles. - Int m_numEdgeTiles; // Number of tiles initialized from bitmaps in m_SourceTiles. - Int m_numBlendedTiles; // Number of blended tiles created from bitmap tiles. - - TileData *m_sourceTiles[NUM_SOURCE_TILES]; ///< Tiles for m_textureClasses - TileData *m_edgeTiles[NUM_SOURCE_TILES]; ///< Tiles for m_textureClasses - - TBlendTileInfo m_blendedTiles[NUM_BLEND_TILES]; - TBlendTileInfo m_extraBlendedTiles[NUM_BLEND_TILES]; - - TCliffInfo m_cliffInfo[NUM_CLIFF_INFO]; - Int m_numCliffInfo; ///< Number of cliffInfo's used in m_cliffInfo. - - // Texture classes. There is one texture class for each bitmap read in. - // A class may have more than one tile. For example, if the grass bitmap is - // 128x128, it creates 4 64x64 tiles, so the grass texture class will have 4 tiles. - int m_numTextureClasses; - TXTextureClass m_textureClasses[NUM_TEXTURE_CLASSES]; - - // Edge Texture classes. There is one texture class for each bitmap read in. - // An edge class will normally have 4 tiles. - int m_numEdgeTextureClasses; - TXTextureClass m_edgeTextureClasses[NUM_TEXTURE_CLASSES]; - - /** The actual texture used to render the 3d mesh. Note that it is - basically m_SourceTiles laid out in rows, so by itself it is not useful. - Use GetUVData to get the mapping info for height cells to map into the - texture. */ - TerrainTextureClass *m_terrainTex; - Int m_terrainTexHeight; /// Height of m_terrainTex allocated. - /** The texture that contains the alpha edge tiles that get blended on - top of the base texture. getAlphaUVData does the mapping. */ - AlphaTerrainTextureClass *m_alphaTerrainTex; - Int m_alphaTexHeight; /// Height of m_alphaTerrainTex allocated. - - /** The texture that contains custom blend edge tiles. */ - AlphaEdgeTextureClass *m_alphaEdgeTex; - Int m_alphaEdgeHeight; /// Height of m_alphaEdgeTex allocated. - - /// Drawing info - re the part of the map that is being drawn. - Int m_drawOriginX; - Int m_drawOriginY; - Int m_drawWidthX; - Int m_drawHeightY; - -protected: - TileData *getSourceTile(UnsignedInt ndx) { if (ndxm_width) m_drawWidthX = m_width;} - void setDrawHeight(Int height) {m_drawHeightY = height; if (m_drawHeightY>m_height) m_drawHeightY = m_height;} - Int getBorderSize(void) {return m_borderSize;} - /// Get height with the offset that HeightMapRenderObjClass uses built in. - UnsignedByte getDisplayHeight(Int x, Int y) { return m_data[x+m_drawOriginX+m_width*(y+m_drawOriginY)];} - - /// Get height in normal coordinates. - UnsignedByte getHeight(Int xIndex, Int yIndex) - { - Int ndx = (yIndex*m_width)+xIndex; - if ((ndx>=0) && (ndx=0) && (ndx. -*/ - -//////////////////////////////////////////////////////////////////////////////// -// // -// (c) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -// FILE: Heightmap.cpp //////////////////////////////////////////////// -//----------------------------------------------------------------------------- -// -// Westwood Studios Pacific. -// -// Confidential Information -// Copyright (C) 2001 - All Rights Reserved -// -//----------------------------------------------------------------------------- -// -// Project: RTS3 -// -// File name: Heightmap.cpp -// -// Created: Mark W., John Ahlquist, April/May 2001 -// -// Desc: Draw the terrain and scorchmarks in a scene. -// -//----------------------------------------------------------------------------- - -//----------------------------------------------------------------------------- -// Includes -//----------------------------------------------------------------------------- -#include "W3DDevice/GameClient/HeightMap.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "Common/GlobalData.h" -#include "Common/PerfTimer.h" - -#include "GameClient/TerrainVisual.h" -#include "GameClient/View.h" -#include "GameClient/Water.h" - -#include "GameLogic/AIPathfind.h" -#include "GameLogic/TerrainLogic.h" -#include "W3DDevice/GameClient/TerrainTex.h" -#include "W3DDevice/GameClient/W3DDynamicLight.h" -#include "W3DDevice/GameClient/W3DScene.h" -#include "W3DDevice/GameClient/W3DTerrainTracks.h" -#include "W3DDevice/GameClient/W3DBibBuffer.h" -#include "W3DDevice/GameClient/W3DTreeBuffer.h" -#include "W3DDevice/GameClient/W3DRoadBuffer.h" -#include "W3DDevice/GameClient/W3DBridgeBuffer.h" -#include "W3DDevice/GameClient/W3DWaypointBuffer.h" -#include "W3DDevice/GameClient/W3DCustomEdging.h" -#include "W3DDevice/GameClient/WorldHeightMap.h" -#include "W3DDevice/GameClient/W3DShaderManager.h" -#include "W3DDevice/GameClient/W3DShadow.h" -#include "W3DDevice/GameClient/W3DWater.h" -#include "W3DDevice/GameClient/W3DShroud.h" -#include "WW3D2/dx8wrapper.h" -#include "WW3D2/light.h" -#include "WW3D2/scene.h" -#include "W3DDevice/GameClient/W3DPoly.h" -#include "W3DDevice/GameClient/W3DCustomScene.h" - -#include "Common/UnitTimings.h" //Contains the DO_UNIT_TIMINGS define jba. - - -#define no_OPTIMIZED_HEIGHTMAP_LIGHTING 01 -// Doesn't work well. jba. - -//----------------------------------------------------------------------------- -// Private Data -//----------------------------------------------------------------------------- -#define SC_DETAIL_BLEND ( SHADE_CNST(ShaderClass::PASS_LEQUAL, ShaderClass::DEPTH_WRITE_ENABLE, ShaderClass::COLOR_WRITE_ENABLE, ShaderClass::SRCBLEND_ONE, \ - ShaderClass::DSTBLEND_ZERO, ShaderClass::FOG_DISABLE, ShaderClass::GRADIENT_MODULATE, ShaderClass::SECONDARY_GRADIENT_DISABLE, ShaderClass::TEXTURING_ENABLE, \ - ShaderClass::ALPHATEST_DISABLE, ShaderClass::CULL_MODE_ENABLE, ShaderClass::DETAILCOLOR_SCALE, ShaderClass::DETAILALPHA_DISABLE) ) - -static ShaderClass detailOpaqueShader(SC_DETAIL_BLEND); - -//----------------------------------------------------------------------------- -// Global Functions & Data -//----------------------------------------------------------------------------- -/// The one-of for the terrain rendering object. -HeightMapRenderObjClass *TheTerrainRenderObject=NULL; - -/** Entry point so that trees can be drawn at the appropriate point in the rendering pipe for - transparent objects. */ -void DoTrees(RenderInfoClass & rinfo) -{ - if (TheTerrainRenderObject) { - TheTerrainRenderObject->renderTrees(&rinfo.Camera); - } -} - -void oversizeTheTerrain(Int amount) -{ - if (TheTerrainRenderObject) - { - TheTerrainRenderObject->oversizeTerrain(amount); - } -} - -#define DEFAULT_MAX_FRAME_EXTRABLEND_TILES 256 //default number of terrain tiles rendered per call (must fit in one VB) -#define DEFAULT_MAX_MAP_EXTRABLEND_TILES 2048 //default size of array allocated to hold all map extra blend tiles. -#define DEFAULT_MAX_BATCH_SHORELINE_TILES 512 //maximum number of terrain tiles rendered per call (must fit in one VB) -#define DEFAULT_MAX_MAP_SHORELINE_TILES 4096 //default size of array allocated to hold all map shoreline tiles. - -#define ADJUST_FROM_INDEX_TO_REAL(k) ((k-m_map->getBorderSize())*MAP_XY_FACTOR) -inline Int IABS(Int x) { if (x>=0) return x; return -x;}; - -//----------------------------------------------------------------------------- -// Private Functions -//----------------------------------------------------------------------------- - -//============================================================================= -// HeightMapRenderObjClass::freeMapResources -//============================================================================= -/** Frees the w3d resources used to draw the terrain. */ -//============================================================================= -Int HeightMapRenderObjClass::freeMapResources(void) -{ -#ifdef DO_SCORCH - freeScorchBuffers(); -#endif - REF_PTR_RELEASE(m_indexBuffer); - if (m_vertexBufferTiles) { - for (int i=0; iRelease(); - delete[] m_xformedVertexBuffer; - m_xformedVertexBuffer = NULL; - } -#endif - REF_PTR_RELEASE(m_vertexMaterialClass); - REF_PTR_RELEASE(m_stageZeroTexture); - REF_PTR_RELEASE(m_stageOneTexture); - REF_PTR_RELEASE(m_stageTwoTexture); - REF_PTR_RELEASE(m_stageThreeTexture); - REF_PTR_RELEASE(m_destAlphaTexture); - REF_PTR_RELEASE(m_map); - - return 0; -} - -//============================================================================= -// HeightMapRenderObjClass::doTheLight -//============================================================================= -/** Calculates the diffuse lighting for a vertex in the terrain, taking all of the -static lights into account as well. It is possible to just use the normal in the -vertex and let D3D do the lighting, but it is slower to render, and can only -handle 4 lights at this point. */ -//============================================================================= -void HeightMapRenderObjClass::doTheLight(VERTEX_FORMAT *vb, Vector3*light, Vector3*normal, RefRenderObjListIterator *pLightsIterator, UnsignedByte alpha) -{ -#ifdef USE_NORMALS - vb->nx = normal->X; - vb->ny = normal->Y; - vb->nz = normal->Z; -#else - Real shadeR, shadeG, shadeB; - Real shade; - shadeR = TheGlobalData->m_terrainAmbient[0].red; //only the first terrain light contributes to ambient - shadeG = TheGlobalData->m_terrainAmbient[0].green; - shadeB = TheGlobalData->m_terrainAmbient[0].blue; - - if (pLightsIterator) { - for (pLightsIterator->First(); !pLightsIterator->Is_Done(); pLightsIterator->Next()) - { - LightClass *pLight = (LightClass*)pLightsIterator->Peek_Obj(); - Vector3 lightDirection(vb->x, vb->y, vb->z); - Real factor = 1.0f; - switch(pLight->Get_Type()) { - case LightClass::POINT: - case LightClass::SPOT: { - Vector3 lightLoc = pLight->Get_Position(); - lightDirection -= lightLoc; - double range, midRange; - pLight->Get_Far_Attenuation_Range(midRange, range); - if (vb->x < lightLoc.X-range) continue; - if (vb->x > lightLoc.X+range) continue; - if (vb->y < lightLoc.Y-range) continue; - if (vb->y > lightLoc.Y+range) continue; - Real dist = lightDirection.Length(); - if (dist >= range) continue; - if (midRange < 0.1) continue; -#if 1 - factor = 1.0f - (dist - midRange) / (range - midRange); -#else - // f = 1.0 / (atten0 + d*atten1 + d*d/atten2); - if (fabs(range-midRange)<1e-5) { - // if the attenuation range is too small assume uniform with cutoff - factor = 1.0; - } else { - factor = 1.0f/(0.1+dist/midRange + 5.0f*dist*dist/(range*range)); - } -#endif - factor = WWMath::Clamp(factor,0.0f,1.0f); - } - break; - case LightClass::DIRECTIONAL: - lightDirection = pLight->Get_Transform().Get_Z_Vector(); - factor = 1.0; - break; - }; - lightDirection.Normalize(); - Vector3 lightRay(-lightDirection.X, -lightDirection.Y, -lightDirection.Z); - shade = Vector3::Dot_Product(lightRay, *normal); - shade *= factor; - Vector3 diffuse; - pLight->Get_Diffuse(&diffuse); - Vector3 ambient; - pLight->Get_Ambient(&ambient); - if (shade > 1.0) shade = 1.0; - if(shade < 0.0f) shade = 0.0f; - shadeR += shade*diffuse.X; - shadeG += shade*diffuse.Y; - shadeB += shade*diffuse.Z; - shadeR += factor*ambient.X; - shadeG += factor*ambient.Y; - shadeB += factor*ambient.Z; - - } - } - // Add in global diffuse value. - const RGBColor *terrainDiffuse; - for (Int lightIndex=0; lightIndex < TheGlobalData->m_numGlobalLights; lightIndex++) - { - shade = Vector3::Dot_Product(light[lightIndex], *normal); - if (shade > 1.0) shade = 1.0; - if(shade < 0.0f) shade = 0.0f; - terrainDiffuse=&TheGlobalData->m_terrainDiffuse[lightIndex]; - shadeR += shade*terrainDiffuse->red; - shadeG += shade*terrainDiffuse->green; - shadeB += shade*terrainDiffuse->blue; - } - - if (shadeR > 1.0) shadeR = 1.0; - if(shadeR < 0.0f) shadeR = 0.0f; - if (shadeG > 1.0) shadeG = 1.0; - if(shadeG < 0.0f) shadeG = 0.0f; - if (shadeB > 1.0) shadeB = 1.0; - if(shadeB < 0.0f) shadeB = 0.0f; - - if (m_useDepthFade && vb->z <= TheGlobalData->m_waterPositionZ) - { //height is below water level - //reduce lighting values based on light fall off as it travels through water. - float depthScale = (1.4f - vb->z)/TheGlobalData->m_waterPositionZ; - shadeR *= 1.0f - depthScale * (1.0f-m_depthFade.X); - shadeG *= 1.0f - depthScale * (1.0f-m_depthFade.Y); - shadeB *= 1.0f - depthScale * (1.0f-m_depthFade.Z); - } - - shadeR*=255.0f; - shadeG*=255.0f; - shadeB*=255.0f; - vb->diffuse = REAL_TO_INT(shadeB) | (REAL_TO_INT(shadeG) << 8) | (REAL_TO_INT(shadeR) << 16) | ((Int)alpha << 24); -#endif -} - -//============================================================================= -// HeightMapRenderObjClass::doTheDynamicLight -//============================================================================= -/** Calculates the diffuse lighting as affected by dynamic lighting. */ -//============================================================================= -UnsignedInt HeightMapRenderObjClass::doTheDynamicLight(VERTEX_FORMAT *vb, VERTEX_FORMAT *vbMirror, Vector3*light, Vector3*normal, W3DDynamicLight *pLights[], Int numLights) -{ -#ifdef USE_NORMALS - return; -#else - Real shadeR, shadeG, shadeB; - Int diffuse = vbMirror->diffuse; -#ifdef RTS_DEBUG - //vbMirror->diffuse += 30; // Shows which vertexes are geting touched by dynamic light. debug only. -#endif - - // (gth) avoiding the extra divides (compiler unfortunately didn't do this automatically...) - const float oo255 = (1.0f/255.0f); - shadeR = ((diffuse>>16)&0x00FF) * oo255; - shadeG = ((diffuse>>8)&0x00FF) * oo255; - shadeB = (diffuse&0x00FF) * oo255; - - Int alpha = (diffuse>>24)&0x00FF; - Int k; - for (k=0; kisEnabled()) { - continue; // he is turned off. - } - Vector3 lightDirection(vbMirror->x, vbMirror->y, vbMirror->z); - Real factor = 1.0f; - switch(pLight->Get_Type()) { - case LightClass::POINT: - case LightClass::SPOT: { - Vector3 lightLoc = pLight->Get_Position(); - lightDirection -= lightLoc; - double range, midRange; - pLight->Get_Far_Attenuation_Range(midRange, range); - Real dist = lightDirection.Length(); - if (dist >= range) continue; - if (midRange < 0.1) continue; - factor = 1.0f - (dist - midRange) / (range - midRange); - factor = WWMath::Clamp(factor,0.0f,1.0f); - - // (gth) normalize here since we have the length - lightDirection /= dist; - } - break; - case LightClass::DIRECTIONAL: - pLight->Get_Spot_Direction(lightDirection); - factor = 1.0; - break; - }; - - // (gth) unneeded due to above normalization - //lightDirection.Normalize(); - - Vector3 lightRay(-lightDirection.X, -lightDirection.Y, -lightDirection.Z); - Real shade = Vector3::Dot_Product(lightRay, *normal); - shade *= factor; - Vector3 diffuse; - pLight->Get_Diffuse(&diffuse); - Vector3 ambient; - pLight->Get_Ambient(&ambient); - if (shade > 1.0) shade = 1.0; - if(shade < 0.0f) shade = 0.0f; - shadeR += shade*diffuse.X; - shadeG += shade*diffuse.Y; - shadeB += shade*diffuse.Z; - shadeR += factor*ambient.X; - shadeG += factor*ambient.Y; - shadeB += factor*ambient.Z; - - } - if (shadeR > 1.0) shadeR = 1.0; - if(shadeR < 0.0f) shadeR = 0.0f; - if (shadeG > 1.0) shadeG = 1.0; - if(shadeG < 0.0f) shadeG = 0.0f; - if (shadeB > 1.0) shadeB = 1.0; - if(shadeB < 0.0f) shadeB = 0.0f; - shadeR*=255.0f; - shadeG*=255.0f; - shadeB*=255.0f; - -// (gth) faster float to int conversion, return the result so we can re-use it. -// vb->diffuse=REAL_TO_INT(shadeB) | (REAL_TO_INT(shadeG) << 8) | (REAL_TO_INT(shadeR) << 16) | ((int)alpha << 24); - UnsignedInt light_val = WWMath::Float_To_Int_Chop(shadeB) | (WWMath::Float_To_Int_Chop(shadeG) << 8) | (WWMath::Float_To_Int_Chop(shadeR) << 16) | ((int)alpha << 24); - vb->diffuse = light_val; - return light_val; - -#endif -} - -//============================================================================= -// HeightMapRenderObjClass::getXWithOrigin -//============================================================================= -/** Gets the x index that corresponds to the data. For example, if the columns -are shifted by 3, index 3 is actually the first row of polygons, or 0. Yes it -is confusing, but it makes sliding the map 10x faster. */ -//============================================================================= -Int HeightMapRenderObjClass::getXWithOrigin(Int x) -{ - x -= m_originX; - if (x<0) x+= m_x-1; - if (x>= m_x-1) x-=m_x-1; -#ifdef RTS_DEBUG - DEBUG_ASSERTCRASH (x>=0, ("X out of range.")); - DEBUG_ASSERTCRASH (x= m_x-1) x=m_x-1; - return x; -} - -//============================================================================= -// HeightMapRenderObjClass::getYWithOrigin -//============================================================================= -/** Gets the y index that corresponds to the data. For example, if the rows -are shifted by 3, index 3 is actually the first row of polygons, or 0. Yes it -is confusing, but it makes sliding the map 10x faster. */ -//============================================================================= -Int HeightMapRenderObjClass::getYWithOrigin(Int y) -{ - y -= m_originY; - if (y<0) y+= m_y-1; - if (y>= m_y-1) y-=m_y-1; -#ifdef RTS_DEBUG - DEBUG_ASSERTCRASH (y>=0, ("Y out of range.")); - DEBUG_ASSERTCRASH (y= m_y-1) y=m_y-1; - return y; -} - -//============================================================================= -// HeightMapRenderObjClass::updateVB -//============================================================================= -/** Update a rectangular block of the given Vertex Buffer. -data is expected to be an array same dimensions as current heightmap -mapped into this VB. -*/ -//============================================================================= -Int HeightMapRenderObjClass::updateVB(DX8VertexBufferClass *pVB, char *data, Int x0, Int y0, Int x1, Int y1, Int originX, Int originY, WorldHeightMap *pMap, RefRenderObjListIterator *pLightsIterator) -{ - Int i,j; - Vector3 lightRay[MAX_GLOBAL_LIGHTS]; - const Coord3D *lightPos; - Int xCoord, yCoord; - Int vn0,un0,vp1,up1; - Vector3 l2r,n2f,normalAtTexel; - Int vertsPerRow=(VERTEX_BUFFER_TILE_LENGTH)*4; //vertices per row of VB - - Int cellOffset = 1; - if (m_halfResMesh) { - cellOffset = 2; - } - - REF_PTR_SET(m_map, pMap); //update our heightmap pointer in case it changed since last call. - if (m_vertexBufferTiles && pMap) - { -#ifdef RTS_DEBUG - assert(x0 >= originX && y0 >= originY && x1>x0 && y1>y0 && x1<=originX+VERTEX_BUFFER_TILE_LENGTH && y1<=originY+VERTEX_BUFFER_TILE_LENGTH); -#endif - - DX8VertexBufferClass::WriteLockClass lockVtxBuffer(pVB); - VERTEX_FORMAT *vbHardware = (VERTEX_FORMAT*)lockVtxBuffer.Get_Vertex_Array(); - VERTEX_FORMAT *vBase = (VERTEX_FORMAT*)data; - // Note that we are building the vertex buffer data in the memory buffer, data. - // At the bottom, we will copy the final vertex data for one cell into the - // hardware vertex buffer. - - for (j=y0; jgetDrawOrgY()) - vn0=-pMap->getDrawOrgY(); - vp1 = getYWithOrigin(j+cellOffset)+cellOffset; - if (vp1 >= pMap->getYExtent()-pMap->getDrawOrgY()) - vp1=pMap->getYExtent()-pMap->getDrawOrgY()-1; - - yCoord = getYWithOrigin(j)+pMap->getDrawOrgY(); - for (i=x0; igetDrawOrgX()) - un0=-pMap->getDrawOrgX(); - up1 = getXWithOrigin(i+cellOffset)+cellOffset; - if (up1 >= pMap->getXExtent()-pMap->getDrawOrgX()) - up1=pMap->getXExtent()-pMap->getDrawOrgX()-1; - xCoord = getXWithOrigin(i)+pMap->getDrawOrgX(); - - //update the 4 vertices in this block - float U[4], V[4]; - UnsignedByte alpha[4]; - float UA[4], VA[4]; - Bool flipForBlend = false; // True if the blend needs the triangles flipped. - - if (pMap) { - pMap->getUVData(getXWithOrigin(i),getYWithOrigin(j),U, V, m_halfResMesh); - pMap->getAlphaUVData(getXWithOrigin(i),getYWithOrigin(j), UA, VA, alpha, &flipForBlend, m_halfResMesh); - } - - - for (Int lightIndex=0; lightIndex < TheGlobalData->m_numGlobalLights; lightIndex++) - { - lightPos=&TheGlobalData->m_terrainLightPos[lightIndex]; - lightRay[lightIndex].Set(-lightPos->x,-lightPos->y, -lightPos->z); - } - - //top-left sample - l2r.Set(2*MAP_XY_FACTOR,0,MAP_HEIGHT_SCALE*(pMap->getDisplayHeight(getXWithOrigin(i)+cellOffset, getYWithOrigin(j)) - pMap->getDisplayHeight(un0, getYWithOrigin(j)))); - n2f.Set(0,2*MAP_XY_FACTOR,MAP_HEIGHT_SCALE*(pMap->getDisplayHeight(getXWithOrigin(i), (getYWithOrigin(j)+cellOffset)) - pMap->getDisplayHeight(getXWithOrigin(i), vn0))); - -#ifdef ALLOW_TEMPORARIES - normalAtTexel= Normalize(Vector3::Cross_Product(l2r,n2f)); -#else - Vector3::Normalized_Cross_Product(l2r, n2f, &normalAtTexel); -#endif - - vb->x=xCoord; - vb->y=yCoord; - vb->z= ((float)pMap->getDisplayHeight(getXWithOrigin(i), getYWithOrigin(j)))*MAP_HEIGHT_SCALE; - vb->x = ADJUST_FROM_INDEX_TO_REAL(vb->x); - vb->y = ADJUST_FROM_INDEX_TO_REAL(vb->y); - vb->u1=U[0]; - vb->v1=V[0]; - vb->u2=UA[0]; - vb->v2=VA[0]; - doTheLight(vb, lightRay, &normalAtTexel, pLightsIterator, alpha[0]); - vb++; - - //top-right sample - l2r.Set(2*MAP_XY_FACTOR,0,MAP_HEIGHT_SCALE*(pMap->getDisplayHeight(up1 , getYWithOrigin(j) ) - pMap->getDisplayHeight(getXWithOrigin(i) , getYWithOrigin(j) ))); - n2f.Set(0,2*MAP_XY_FACTOR,MAP_HEIGHT_SCALE*(pMap->getDisplayHeight(getXWithOrigin(i)+cellOffset , (getYWithOrigin(j)+cellOffset) ) - pMap->getDisplayHeight(getXWithOrigin(i)+cellOffset , vn0 ))); - -#ifdef ALLOW_TEMPORARIES - normalAtTexel= Normalize(Vector3::Cross_Product(l2r,n2f)); -#else - Vector3::Normalized_Cross_Product(l2r, n2f, &normalAtTexel); -#endif - - vb->x=xCoord+cellOffset; - vb->y=yCoord; - vb->z= ((float)pMap->getDisplayHeight(getXWithOrigin(i)+cellOffset, getYWithOrigin(j)))*MAP_HEIGHT_SCALE; - vb->x = ADJUST_FROM_INDEX_TO_REAL(vb->x); - vb->y = ADJUST_FROM_INDEX_TO_REAL(vb->y); - vb->u1=U[1]; - vb->v1=V[1]; - vb->u2=UA[1]; - vb->v2=VA[1]; - doTheLight(vb, lightRay, &normalAtTexel, pLightsIterator, alpha[1]); - vb++; - - //bottom-right sample - l2r.Set(2*MAP_XY_FACTOR,0,MAP_HEIGHT_SCALE*(pMap->getDisplayHeight(up1 , (getYWithOrigin(j)+cellOffset) ) - pMap->getDisplayHeight(getXWithOrigin(i) , (getYWithOrigin(j)+cellOffset) ))); - n2f.Set(0,2*MAP_XY_FACTOR,MAP_HEIGHT_SCALE*(pMap->getDisplayHeight(getXWithOrigin(i)+cellOffset , vp1 ) - pMap->getDisplayHeight(getXWithOrigin(i)+cellOffset , getYWithOrigin(j) ))); - -#ifdef ALLOW_TEMPORARIES - normalAtTexel= Normalize(Vector3::Cross_Product(l2r,n2f)); -#else - Vector3::Normalized_Cross_Product(l2r, n2f, &normalAtTexel); -#endif - - vb->x=xCoord+cellOffset; - if (yCoord + 1 == pMap->getDrawOrgY() + m_y - 1) { - vb->y=yCoord+1; - } else { - vb->y=yCoord+cellOffset; - } - vb->z= ((float)pMap->getDisplayHeight(getXWithOrigin(i)+cellOffset, getYWithOrigin(j)+cellOffset))*MAP_HEIGHT_SCALE; - vb->x = ADJUST_FROM_INDEX_TO_REAL(vb->x); - vb->y = ADJUST_FROM_INDEX_TO_REAL(vb->y); - vb->u1=U[2]; - vb->v1=V[2]; - vb->u2=UA[2]; - vb->v2=VA[2]; - doTheLight(vb, lightRay, &normalAtTexel, pLightsIterator, alpha[2]); - vb++; - - //bottom-left sample - l2r.Set(2*MAP_XY_FACTOR,0,MAP_HEIGHT_SCALE*(pMap->getDisplayHeight(getXWithOrigin(i)+cellOffset , (getYWithOrigin(j)+cellOffset) ) - pMap->getDisplayHeight(un0 , (getYWithOrigin(j)+cellOffset) ))); - n2f.Set(0,2*MAP_XY_FACTOR,MAP_HEIGHT_SCALE*(pMap->getDisplayHeight(getXWithOrigin(i) , vp1 ) - pMap->getDisplayHeight(getXWithOrigin(i) , getYWithOrigin(j) ))); - -#ifdef ALLOW_TEMPORARIES - normalAtTexel= Normalize(Vector3::Cross_Product(l2r,n2f)); -#else - Vector3::Normalized_Cross_Product(l2r, n2f, &normalAtTexel); -#endif - - if (xCoord == pMap->getDrawOrgX()) { - vb->x=xCoord; - //if (vb->x < 0) vb->x = 0; - } else { - vb->x=xCoord; - } - if (yCoord + 1 == pMap->getDrawOrgY() + m_y - 1) { - vb->y=yCoord+1; - } else { - vb->y=yCoord+cellOffset; - } - vb->z= ((float)pMap->getDisplayHeight(getXWithOrigin(i), getYWithOrigin(j)+cellOffset))*MAP_HEIGHT_SCALE; - vb->x = ADJUST_FROM_INDEX_TO_REAL(vb->x); - vb->y = ADJUST_FROM_INDEX_TO_REAL(vb->y); - vb->u1=U[3]; - vb->v1=V[3]; - vb->u2=UA[3]; - vb->v2=VA[3]; - doTheLight(vb, lightRay, &normalAtTexel, pLightsIterator, alpha[3]); - vb++; - - VERTEX_FORMAT *pCurVertices = vb-4; -#ifdef FLIP_TRIANGLES // jba - reduces "diamonding" in some cases, not others. Better cliffs, though. - VERTEX_FORMAT tmpVertex; - if (flipForBlend) { - tmpVertex = pCurVertices[0]; - pCurVertices[0] = pCurVertices[1]; - pCurVertices[1] = pCurVertices[2]; - pCurVertices[2] = pCurVertices[3]; - pCurVertices[3] = tmpVertex; - } -#endif - - if (m_showImpassableAreas) { - // Color impassable cells "red" - DEBUG_ASSERTCRASH(PATHFIND_CELL_SIZE_F == MAP_XY_FACTOR, ("Pathfind must be terrain cell size, or this code needs reworking. John A.")); - Real borderHiX = (pMap->getXExtent()-2*pMap->getBorderSize())*MAP_XY_FACTOR; - Real borderHiY = (pMap->getYExtent()-2*pMap->getBorderSize())*MAP_XY_FACTOR; - Bool border = pCurVertices[0].x == -MAP_XY_FACTOR || pCurVertices[0].y == -MAP_XY_FACTOR; - Bool cliffMapped = pMap->isCliffMappedTexture(getXWithOrigin(i), getYWithOrigin(j)); - if (pCurVertices[0].x == borderHiX) { - border = true; - } - if (pCurVertices[0].y == borderHiY) { - border = true; - } - Bool isCliff = pMap->getCliffState(getXWithOrigin(i)+pMap->getDrawOrgX(), getYWithOrigin(j)+pMap->getDrawOrgY()) - || showAsVisibleCliff(getXWithOrigin(i) + pMap->getDrawOrgX(), getYWithOrigin(j)+pMap->getDrawOrgY()); - - if ( isCliff || border || cliffMapped) { - Int cellX, cellY; - for (cellX=0; cellX<2; cellX++) { - for (cellY=0; cellY<2; cellY++) { - Int vertex = cellX+2*cellY; - if (border) { - Bool doBorder = false; - if (pCurVertices[vertex].y >= 0 && pCurVertices[vertex].y <= borderHiY) { - if (pCurVertices[vertex].x == 0 || pCurVertices[vertex].x == borderHiX) { - doBorder = true; - } - } - if (pCurVertices[vertex].x >= 0 && pCurVertices[vertex].x <= borderHiX) { - if (pCurVertices[vertex].y == 0 || pCurVertices[vertex].y == borderHiY) { - doBorder = true; - } - } - if (doBorder) { - pCurVertices[vertex].diffuse &= 0xFF0000ff; // blue with alpha. - } - } else if (isCliff) { - pCurVertices[vertex].diffuse &= 0xFFFF0000; // red with alpha. - } - if (cliffMapped && vertex==0) { - pCurVertices[vertex].diffuse &= 0xFF000000; // Black. - pCurVertices[vertex].diffuse |= 0xff00; // Add green. - } - } - } - } - } - - // Note - We have been building the vertex buffer in the memory location. - // Now copy the set of vertices into the hardware buffer. - // We don't copy the whole vertex buffer because we often update only - // a couple of rows and its a lot faster to just copy the ones that change. - Int offset = pCurVertices - vBase; - memcpy(vbHardware+offset, pCurVertices, 4*sizeof(VERTEX_FORMAT)); - } - } - return 0; //success. - } - return -1; -} - -//============================================================================= -// HeightMapRenderObjClass::updateVBForLight -//============================================================================= -/** Update the dynamic lighting values only in a rectangular block of the given Vertex Buffer. -The vertex locations and texture coords are unchanged. -*/ -Int HeightMapRenderObjClass::updateVBForLight(DX8VertexBufferClass *pVB, char *data, Int x0, Int y0, Int x1, Int y1, Int originX, Int originY, W3DDynamicLight *pLights[], Int numLights) -{ - -#if (OPTIMIZED_HEIGHTMAP_LIGHTING) // (gth) if optimizations are enabled, jump over to the "optimized" version of this function. - return updateVBForLightOptimized( pVB, data, x0, y0, x1, y1, originX, originY, pLights, numLights ); -#endif - - Int i,j,k; - Int vn0,un0,vp1,up1; - Vector3 l2r,n2f,normalAtTexel; - Int vertsPerRow=(VERTEX_BUFFER_TILE_LENGTH)*4; //vertices per row of VB - - if (m_vertexBufferTiles && m_map) - { -#ifdef RTS_DEBUG - assert(x0 >= originX && y0 >= originY && x1>x0 && y1>y0 && x1<=originX+VERTEX_BUFFER_TILE_LENGTH && y1<=originY+VERTEX_BUFFER_TILE_LENGTH); -#endif - - DX8VertexBufferClass::WriteLockClass lockVtxBuffer(pVB); - VERTEX_FORMAT *vBase = (VERTEX_FORMAT*)lockVtxBuffer.Get_Vertex_Array(); - VERTEX_FORMAT *vb; - - for (j=y0; jgetDrawOrgY()-m_map->getBorderSize(); - Bool intersect = false; - for (k=0; km_minY <= yCoord+1 && - pLights[k]->m_maxY >= yCoord) { - intersect = true; - } - if (pLights[k]->m_prevMinY <= yCoord+1 && - pLights[k]->m_prevMaxY >= yCoord) { - intersect = true; - } - } - if (!intersect) { - continue; - } - vn0 = getYWithOrigin(j)-1; - if (vn0 < -m_map->getDrawOrgY()) - vn0=-m_map->getDrawOrgY(); - vp1 = getYWithOrigin(j+1)+1; - if (vp1 >= m_map->getYExtent()-m_map->getDrawOrgY()) - vp1=m_map->getYExtent()-m_map->getDrawOrgY()-1; - - for (i=x0; igetDrawOrgX()-m_map->getBorderSize(); - Bool intersect = false; - for (k=0; km_minX <= xCoord+1 && - pLights[k]->m_maxX >= xCoord && - pLights[k]->m_minY <= yCoord+1 && - pLights[k]->m_maxY >= yCoord) { - intersect = true; - } - if (pLights[k]->m_prevMinX <= xCoord+1 && - pLights[k]->m_prevMaxX >= xCoord && - pLights[k]->m_prevMinY <= yCoord+1 && - pLights[k]->m_prevMaxY >= yCoord) { - intersect = true; - } - } - if (!intersect) { - continue; - } - // vb is the pointer to the vertex in the hardware dx8 vertex buffer. - Int offset = (j-originY)*vertsPerRow+4*(i-originX); - if (m_halfResMesh) { - offset = (j-originY)*vertsPerRow/4+2*(i-originX); - } - vb = vBase + offset; //skip to correct row in vertex buffer - // vbMirror is the pointer to the vertex in our memory based copy. - // The important point is that we can read out of our copy to get the original - // diffuse color, and xyz location. It is VERY SLOW to read out of the - // hardware vertex buffer, possibly worse... jba. - VERTEX_FORMAT *vbMirror = ((VERTEX_FORMAT*)data) + offset; - un0 = getXWithOrigin(i)-1; - if (un0 < -m_map->getDrawOrgX()) - un0=-m_map->getDrawOrgX(); - up1 = getXWithOrigin(i+1)+1; - if (up1 >= m_map->getXExtent()-m_map->getDrawOrgX()) - up1=m_map->getXExtent()-m_map->getDrawOrgX()-1; - - Vector3 lightRay(0,0,0); - - //top-left sample - l2r.Set(2*MAP_XY_FACTOR,0,MAP_HEIGHT_SCALE*(m_map->getDisplayHeight(getXWithOrigin(i)+1, getYWithOrigin(j)) - m_map->getDisplayHeight(un0, getYWithOrigin(j)))); - n2f.Set(0,2*MAP_XY_FACTOR,MAP_HEIGHT_SCALE*(m_map->getDisplayHeight(getXWithOrigin(i), (getYWithOrigin(j)+1)) - m_map->getDisplayHeight(getXWithOrigin(i), vn0))); - -#ifdef ALLOW_TEMPORARIES - normalAtTexel= Normalize(Vector3::Cross_Product(l2r,n2f)); -#else - Vector3::Normalized_Cross_Product(l2r, n2f, &normalAtTexel); -#endif - - doTheDynamicLight(vb, vbMirror, &lightRay, &normalAtTexel, pLights, numLights); - vb++; vbMirror++; - - //top-right sample - l2r.Set(2*MAP_XY_FACTOR,0,MAP_HEIGHT_SCALE*(m_map->getDisplayHeight(up1 , getYWithOrigin(j) ) - m_map->getDisplayHeight(getXWithOrigin(i) , getYWithOrigin(j) ))); - n2f.Set(0,2*MAP_XY_FACTOR,MAP_HEIGHT_SCALE*(m_map->getDisplayHeight(getXWithOrigin(i)+1 , (getYWithOrigin(j)+1) ) - m_map->getDisplayHeight(getXWithOrigin(i)+1 , vn0 ))); - -#ifdef ALLOW_TEMPORARIES - normalAtTexel= Normalize(Vector3::Cross_Product(l2r,n2f)); -#else - Vector3::Normalized_Cross_Product(l2r, n2f, &normalAtTexel); -#endif - - doTheDynamicLight(vb, vbMirror, &lightRay, &normalAtTexel, pLights, numLights); - vb++; vbMirror++; - - //bottom-right sample - l2r.Set(2*MAP_XY_FACTOR,0,MAP_HEIGHT_SCALE*(m_map->getDisplayHeight(up1 , (getYWithOrigin(j)+1) ) - m_map->getDisplayHeight(getXWithOrigin(i) , (getYWithOrigin(j)+1) ))); - n2f.Set(0,2*MAP_XY_FACTOR,MAP_HEIGHT_SCALE*(m_map->getDisplayHeight(getXWithOrigin(i)+1 , vp1 ) - m_map->getDisplayHeight(getXWithOrigin(i)+1 , getYWithOrigin(j) ))); - -#ifdef ALLOW_TEMPORARIES - normalAtTexel= Normalize(Vector3::Cross_Product(l2r,n2f)); -#else - Vector3::Normalized_Cross_Product(l2r, n2f, &normalAtTexel); -#endif - - doTheDynamicLight(vb, vbMirror, &lightRay, &normalAtTexel, pLights, numLights); - vb++; vbMirror++; - - //bottom-left sample - l2r.Set(2*MAP_XY_FACTOR,0,MAP_HEIGHT_SCALE*(m_map->getDisplayHeight(getXWithOrigin(i)+1 , (getYWithOrigin(j)+1) ) - m_map->getDisplayHeight(un0 , (getYWithOrigin(j)+1) ))); - n2f.Set(0,2*MAP_XY_FACTOR,MAP_HEIGHT_SCALE*(m_map->getDisplayHeight(getXWithOrigin(i) , vp1 ) - m_map->getDisplayHeight(getXWithOrigin(i) , getYWithOrigin(j) ))); - -#ifdef ALLOW_TEMPORARIES - normalAtTexel= Normalize(Vector3::Cross_Product(l2r,n2f)); -#else - Vector3::Normalized_Cross_Product(l2r, n2f, &normalAtTexel); -#endif - - doTheDynamicLight(vb, vbMirror, &lightRay, &normalAtTexel, pLights, numLights); - vb++; vbMirror++; - } - } - return 0; //success. - } - return -1; -} - - -Int HeightMapRenderObjClass::updateVBForLightOptimized(DX8VertexBufferClass *pVB, char *data, Int x0, Int y0, Int x1, Int y1, Int originX, Int originY, W3DDynamicLight *pLights[], Int numLights) -{ - Int i,j,k; - Int vn0,un0,vp1,up1; - Vector3 l2r,n2f,normalAtTexel; - Int vertsPerRow=(VERTEX_BUFFER_TILE_LENGTH)*4; //vertices per row of VB - - if (m_vertexBufferTiles && m_map) - { -#ifdef RTS_DEBUG - assert(x0 >= originX && y0 >= originY && x1>x0 && y1>y0 && x1<=originX+VERTEX_BUFFER_TILE_LENGTH && y1<=originY+VERTEX_BUFFER_TILE_LENGTH); -#endif - - DX8VertexBufferClass::WriteLockClass lockVtxBuffer(pVB); - VERTEX_FORMAT *vBase = (VERTEX_FORMAT*)lockVtxBuffer.Get_Vertex_Array(); - VERTEX_FORMAT *vb; - - // - // (gth) the optimization in this function is to take advantage of verts in the same - // x,y position who have already computed their lighting. To do this, we need to set up - // some offsets in the vertex buffer. I've computed these offsets to be consistent with - // the formula's that Generals is using but in the case of the "half-res-mesh" I'm not - // sure things are correct... - // - Int quad_right_offset; - Int quad_below_offset; - Int quad_below_right_offset; - - if (m_halfResMesh == false) { - // offset = (j-originY)*vertsPerRow+4*(i-originX); - quad_right_offset = 4; - quad_below_offset = vertsPerRow; - quad_below_right_offset = vertsPerRow + 4; - - } else { - // offset = (j-originY)*vertsPerRow/4+2*(i-originX); - quad_right_offset = 2; - quad_below_offset = vertsPerRow/4; - quad_below_right_offset = vertsPerRow/4 + 2; - } - - // - // i,j loop over the quads affected by the light. Each quad has its *own* 4 vertices. This - // means that for any vertex position on the map, there are actually 4 copies of the vertex. - // - for (j=y0; jgetDrawOrgY()-m_map->getBorderSize(); - Bool intersect = false; - for (k=0; km_minY <= yCoord+1 && - pLights[k]->m_maxY >= yCoord) { - intersect = true; - } - if (pLights[k]->m_prevMinY <= yCoord+1 && - pLights[k]->m_prevMaxY >= yCoord) { - intersect = true; - } - } - if (!intersect) { - continue; - } - vn0 = getYWithOrigin(j)-1; - if (vn0 < -m_map->getDrawOrgY()) - vn0=-m_map->getDrawOrgY(); - vp1 = getYWithOrigin(j+1)+1; - if (vp1 >= m_map->getYExtent()-m_map->getDrawOrgY()) - vp1=m_map->getYExtent()-m_map->getDrawOrgY()-1; - - for (i=x0; igetDrawOrgX()-m_map->getBorderSize(); - Bool intersect = false; - for (k=0; km_minX <= xCoord+1 && - pLights[k]->m_maxX >= xCoord && - pLights[k]->m_minY <= yCoord+1 && - pLights[k]->m_maxY >= yCoord) { - intersect = true; - } - if (pLights[k]->m_prevMinX <= xCoord+1 && - pLights[k]->m_prevMaxX >= xCoord && - pLights[k]->m_prevMinY <= yCoord+1 && - pLights[k]->m_prevMaxY >= yCoord) { - intersect = true; - } - } - if (!intersect) { - continue; - } - // vb is the pointer to the vertex in the hardware dx8 vertex buffer. - Int offset = (j-originY)*vertsPerRow+4*(i-originX); - if (m_halfResMesh) { - offset = (j-originY)*vertsPerRow/4+2*(i-originX); - } - vb = vBase + offset; //skip to correct row in vertex buffer - // vbMirror is the pointer to the vertex in our memory based copy. - // The important point is that we can read out of our copy to get the original - // diffuse color, and xyz location. It is VERY SLOW to read out of the - // hardware vertex buffer, possibly worse... jba. - VERTEX_FORMAT *vbMirror = ((VERTEX_FORMAT*)data) + offset; - VERTEX_FORMAT *vbaseMirror = ((VERTEX_FORMAT*)data); - un0 = getXWithOrigin(i)-1; - if (un0 < -m_map->getDrawOrgX()) - un0=-m_map->getDrawOrgX(); - up1 = getXWithOrigin(i+1)+1; - if (up1 >= m_map->getXExtent()-m_map->getDrawOrgX()) - up1=m_map->getXExtent()-m_map->getDrawOrgX()-1; - - Vector3 lightRay(0,0,0); - - // - // (gth) Following the set of rules below lets us take advantage of lighting values that have - // been previously computed. The idea is to copy them ahead to future quads that will need them - // and then not compute them when we get to those quads. This also avoids having to read-back - // from the vertex buffer but we do jump around in memory... probably bad anyway, maybe we should - // compute into a temporary buffer and copy all at once... - // - unsigned long light_copy; - - // top-left sample -> only compute when i==0 and j==0 - if ((i==x0) && (j==y0)) { - l2r.Set(2*MAP_XY_FACTOR,0,MAP_HEIGHT_SCALE*(m_map->getDisplayHeight(getXWithOrigin(i)+1, getYWithOrigin(j)) - m_map->getDisplayHeight(un0, getYWithOrigin(j)))); - n2f.Set(0,2*MAP_XY_FACTOR,MAP_HEIGHT_SCALE*(m_map->getDisplayHeight(getXWithOrigin(i), (getYWithOrigin(j)+1)) - m_map->getDisplayHeight(getXWithOrigin(i), vn0))); - Vector3::Normalized_Cross_Product(l2r, n2f, &normalAtTexel); - doTheDynamicLight(vb, vbMirror, &lightRay, &normalAtTexel, pLights, numLights); - } - vb++; vbMirror++; - - //top-right sample -> compute when j==0, then copy to (right,0) - if (j==y0) { - l2r.Set(2*MAP_XY_FACTOR,0,MAP_HEIGHT_SCALE*(m_map->getDisplayHeight(up1 , getYWithOrigin(j) ) - m_map->getDisplayHeight(getXWithOrigin(i) , getYWithOrigin(j) ))); - n2f.Set(0,2*MAP_XY_FACTOR,MAP_HEIGHT_SCALE*(m_map->getDisplayHeight(getXWithOrigin(i)+1 , (getYWithOrigin(j)+1) ) - m_map->getDisplayHeight(getXWithOrigin(i)+1 , vn0 ))); - Vector3::Normalized_Cross_Product(l2r, n2f, &normalAtTexel); - light_copy = doTheDynamicLight(vb, vbMirror, &lightRay, &normalAtTexel, pLights, numLights); - - if (i < x1-1) { - // copy light to (right,0) - (vBase + offset + quad_right_offset)->diffuse = (light_copy&0x00FFFFFF) | ((vbaseMirror + offset + quad_right_offset)->diffuse&0xff000000) ; - } - } - vb++; vbMirror++; - - //bottom-right sample -> always compute, then copy to (right,3), (down,1), (down+right,0) - l2r.Set(2*MAP_XY_FACTOR,0,MAP_HEIGHT_SCALE*(m_map->getDisplayHeight(up1 , (getYWithOrigin(j)+1) ) - m_map->getDisplayHeight(getXWithOrigin(i) , (getYWithOrigin(j)+1) ))); - n2f.Set(0,2*MAP_XY_FACTOR,MAP_HEIGHT_SCALE*(m_map->getDisplayHeight(getXWithOrigin(i)+1 , vp1 ) - m_map->getDisplayHeight(getXWithOrigin(i)+1 , getYWithOrigin(j) ))); - Vector3::Normalized_Cross_Product(l2r, n2f, &normalAtTexel); - light_copy = doTheDynamicLight(vb, vbMirror, &lightRay, &normalAtTexel, pLights, numLights); - - if (i < x1-1) { - // copy light to (right,3) - //(vBase + offset + quad_right_offset + 3)->diffuse = light_copy; - (vBase + offset + quad_right_offset + 3)->diffuse = (light_copy&0x00FFFFFF) | ((vbaseMirror + offset + quad_right_offset + 3)->diffuse&0xff000000) ; - } - if (j < y1-1) { - // copy light to (down,1) - //(vBase + offset + quad_below_offset + 1)->diffuse = light_copy; - (vBase + offset + quad_right_offset + 1)->diffuse = (light_copy&0x00FFFFFF) | ((vbaseMirror + offset + quad_right_offset + 1)->diffuse&0xff000000) ; - } - if ((i < x1-1) && (j < y1-1)) { - // copy light to (right+down,0) - //(vBase + offset + quad_below_right_offset)->diffuse = light_copy; - (vBase + offset + quad_right_offset)->diffuse = (light_copy&0x00FFFFFF) | ((vbaseMirror + offset + quad_right_offset)->diffuse&0xff000000) ; - } - vb++; vbMirror++; - - //bottom-left sample -> compute when i==0, otherwise copy from (left,2) - if (i==x0) { - l2r.Set(2*MAP_XY_FACTOR,0,MAP_HEIGHT_SCALE*(m_map->getDisplayHeight(getXWithOrigin(i)+1 , (getYWithOrigin(j)+1) ) - m_map->getDisplayHeight(un0 , (getYWithOrigin(j)+1) ))); - n2f.Set(0,2*MAP_XY_FACTOR,MAP_HEIGHT_SCALE*(m_map->getDisplayHeight(getXWithOrigin(i) , vp1 ) - m_map->getDisplayHeight(getXWithOrigin(i) , getYWithOrigin(j) ))); - Vector3::Normalized_Cross_Product(l2r, n2f, &normalAtTexel); - light_copy = doTheDynamicLight(vb, vbMirror, &lightRay, &normalAtTexel, pLights, numLights); - - if (j < y1-1) { - // copy light to (down,0) - //(vBase + offset + quad_below_offset)->diffuse = light_copy; - (vBase + offset + quad_below_offset)->diffuse = (light_copy&0x00FFFFFF) | ((vbaseMirror + offset + quad_below_offset)->diffuse&0xff000000) ; - } - } - vb++; vbMirror++; - } - } - return 0; //success. - } - return -1; -} - - - -//============================================================================= -// HeightMapRenderObjClass::doPartialUpdate -//============================================================================= -/** Updates a partial block of vertices from [x0,y0 to x1,y1] -The coordinates in partialRange are map cell coordinates, relative to the entire map. -The vertex coordinates and texture coordinates, as well as static lighting are updated. -*/ -void HeightMapRenderObjClass::doPartialUpdate(const IRegion2D &partialRange, WorldHeightMap *htMap, RefRenderObjListIterator *pLightsIterator) -{ - // Adjust range into the current drawn map range. - Int minX = partialRange.lo.x - htMap->getDrawOrgX(); - Int maxX = partialRange.hi.x - htMap->getDrawOrgX(); - Int minY = partialRange.lo.y - htMap->getDrawOrgY(); - Int maxY = partialRange.hi.y - htMap->getDrawOrgY(); - if (minX<0) minX = 0; - if (minY<0) minY = 0; - if (maxX > m_x-1) maxX = m_x-1; - if (maxY > m_y-1) maxY = m_y-1; - if (maxX < minX) return; - if (maxY < minY) return; - if (m_originX == 0 && m_originY == 0) { - // simple case. - updateBlock(minX, minY, maxX, maxY, - htMap, pLightsIterator); - } - else - { - minY = minY+m_originY; - maxY = maxY+m_originY; - - if (minY> m_y-1) { - minY -= m_y-1; - maxY -= m_y-1; - } - if (maxY > m_y-1) { - maxY -= m_y-1; - updateBlock(0, minY, m_x-1, m_y-1, htMap, pLightsIterator); - updateBlock(0, 0, m_x-1, maxY, htMap, pLightsIterator); - } else { - updateBlock(0, minY, m_x-1, maxY, htMap, pLightsIterator); - } - } - - if (!m_extraBlendTilePositions) - { //Need to allocate memory - m_extraBlendTilePositions = NEW Int[DEFAULT_MAX_MAP_EXTRABLEND_TILES]; - m_extraBlendTilePositionsSize = DEFAULT_MAX_MAP_EXTRABLEND_TILES; - } - - //Find list of all extra blend tiles used on map. These are tiles with 3 materials/textures - //over the same tile and require an extra render pass. - - Int i, j; - //First remove any existing extra blend tiles within this partial region - for (j=0; j> 16; - if (x >= partialRange.lo.x && x < partialRange.hi.x && - y >= partialRange.lo.y && y < partialRange.hi.y) - { //this tile is inside region being updated so remove it by shifting tile array - memcpy(m_extraBlendTilePositions+j,m_extraBlendTilePositions+j+1,(m_numExtraBlendTiles-1-j)*sizeof(Int)); - m_numExtraBlendTiles--; - j--; //need to look at index j again because this tile was removed - } - } - - for (j=partialRange.lo.y; jgetExtraAlphaUVData(i,j,U,V,alpha,&flipState, &cliffState)) - { if (m_numExtraBlendTiles >= m_extraBlendTilePositionsSize) - { //no more room to store extra blend tiles so enlarge the buffer. - Int *tempPositions=NEW Int[m_extraBlendTilePositionsSize+512]; - memcpy(tempPositions, m_extraBlendTilePositions, m_extraBlendTilePositionsSize*sizeof(Int)); - delete [] m_extraBlendTilePositions; - //enlarge by more tiles to reduce memory trashing - m_extraBlendTilePositions = tempPositions; - m_extraBlendTilePositionsSize += 512; - } - //Pack x and y position into single integer since maps are limited in size - m_extraBlendTilePositions[m_numExtraBlendTiles]=i | (j <<16); - m_numExtraBlendTiles++; - } - } - updateShorelineTiles(partialRange.lo.x,partialRange.lo.y,partialRange.hi.x,partialRange.hi.y,htMap); - - updateViewImpassableAreas(TRUE, minX, maxX, minY, maxY); -} - -//============================================================================= -// HeightMapRenderObjClass::updateBlock -//============================================================================= -/** Updates a block of vertices from [x0,y0 to x1,y1] -The vertex coordinates and texture coordinates, as well as static lighting are updated. -*/ -Int HeightMapRenderObjClass::updateBlock(Int x0, Int y0, Int x1, Int y1, WorldHeightMap *pMap, RefRenderObjListIterator *pLightsIterator) -{ -#ifdef RTS_DEBUG - DEBUG_ASSERTCRASH(x0>=0&&y0>=0 && x1getTerrainTexture()); - REF_PTR_SET(m_stageOneTexture, pMap->getAlphaTerrainTexture()); - } - - Int i,j; - DX8VertexBufferClass **pVB; - Int originX,originY; - //step through each vertex buffer that needs updating - for (j=0; jyMin) yMin = y0; - yMax = originY+VERTEX_BUFFER_TILE_LENGTH; - if (y1= yMax) { - continue; - } - for (i=0; ix1) xMax = x1; - if (xMin >= xMax) { - continue; - } - pVB=m_vertexBufferTiles+j*m_numVBTilesX+i; //point to correct row/column of vertex buffers - char **pData = m_vertexBufferBackup+j*m_numVBTilesX+i; - updateVB(*pVB, *pData, xMin, yMin, xMax, yMax, originX, originY, pMap, pLightsIterator); - } - } - - return 0; -} - -//============================================================================= -// HeightMapRenderObjClass::getTileBoundingBox -//============================================================================= -/** Calculate the bounding box for given terrain tile. Right now each terrain tile is equivalent -to one of the vertex buffers holding heightmap vertices. */ -//============================================================================= -AABoxClass & HeightMapRenderObjClass::getTileBoundingBox(AABoxClass *aabox, Int x, Int y) -{ - Vector3 vmin; - Vector3 vmax; - Int xOffset = 0; - Int yOffset = 0; - if (m_map) { - xOffset = m_map->getDrawOrgX(); - yOffset = m_map->getDrawOrgY(); - } - - vmin.Set(x*VERTEX_BUFFER_TILE_LENGTH+xOffset,y*VERTEX_BUFFER_TILE_LENGTH+yOffset,m_minHeight); - vmax.Set((x+1)*VERTEX_BUFFER_TILE_LENGTH+xOffset,(y+1)*VERTEX_BUFFER_TILE_LENGTH+yOffset,m_maxHeight); - - aabox->Init_Min_Max(vmin,vmax); - return *aabox; -} - -#ifdef DO_SCORCH -//============================================================================= -// HeightMapRenderObjClass::drawScorches -//============================================================================= -/** Draws the scorch marks. */ -//============================================================================= -void HeightMapRenderObjClass::drawScorches(void) -{ - updateScorches(); - if (m_curNumScorchIndices == 0) { - return; - } - DX8Wrapper::Set_Index_Buffer(m_indexScorch,0); - DX8Wrapper::Set_Vertex_Buffer(m_vertexScorch); - - DX8Wrapper::Set_Texture(0,m_scorchTexture); - if (Is_Hidden() == 0) { - DX8Wrapper::Draw_Triangles( 0,m_curNumScorchIndices/3, 0, m_curNumScorchVertices); - } -} -#endif - - -//----------------------------------------------------------------------------- -// Public Functions -//----------------------------------------------------------------------------- - -//============================================================================= -// HeightMapRenderObjClass::~HeightMapRenderObjClass -//============================================================================= -/** Destructor. Releases w3d assets. */ -//============================================================================= -HeightMapRenderObjClass::~HeightMapRenderObjClass(void) -{ - freeMapResources(); - - delete m_treeBuffer; - m_treeBuffer = NULL; - - delete m_bibBuffer; - m_bibBuffer = NULL; - -#ifdef TEST_CUSTOM_EDGING - delete m_customEdging; - m_customEdging = NULL; -#endif - -#ifdef DO_ROADS - delete m_roadBuffer; - m_roadBuffer = NULL; -#endif - - delete m_bridgeBuffer; - m_bridgeBuffer = NULL; - - delete m_waypointBuffer; - m_waypointBuffer = NULL; - - delete m_shroud; - m_shroud = NULL; - - delete [] m_extraBlendTilePositions; - m_extraBlendTilePositions = NULL; - - delete [] m_shoreLineTilePositions; - m_shoreLineTilePositions = NULL; -} - -//============================================================================= -// HeightMapRenderObjClass::HeightMapRenderObjClass -//============================================================================= -/** Constructor. Mostly nulls out the member variables. */ -//============================================================================= -HeightMapRenderObjClass::HeightMapRenderObjClass(void) -{ - m_x=0; - m_y=0; - m_needFullUpdate = false; - m_showImpassableAreas = false; - m_originX = 0; - m_originY = 0; - m_updating = false; - //Set height to the maximum value that can be stored. - //We should refine this with actual value. - m_maxHeight=(pow(256.0, sizeof(HeightSampleType))-1.0)*MAP_HEIGHT_SCALE; - m_minHeight=0; - m_numExtraBlendTiles=0; - m_extraBlendTilePositions=NULL; - m_extraBlendTilePositionsSize=0; - m_shoreLineTilePositions=NULL; - m_numShoreLineTiles=0; - m_shoreLineTilePositionsSize=0; - m_currentMinWaterOpacity = -1.0f; - - m_numVertexBufferTiles=0; - m_indexBuffer=NULL; - m_vertexMaterialClass=NULL; -#ifdef PRE_TRANSFORM_VERTEX - m_xformedVertexBuffer = NULL; -#endif - m_stageZeroTexture=NULL; - m_stageOneTexture=NULL; - m_stageTwoTexture=NULL; - m_stageThreeTexture=NULL; - m_destAlphaTexture=NULL; - m_vertexBufferTiles=NULL; - m_vertexBufferBackup=NULL; - m_map=NULL; - m_depthFade.X = 0.0f; - m_depthFade.Y = 0.0f; - m_depthFade.Z = 0.0f; - m_useDepthFade = false; - m_disableTextures = false; - TheTerrainRenderObject = this; - - m_treeBuffer = NULL; - m_bibBuffer = NULL; -#ifdef TEST_CUSTOM_EDGING - m_customEdging = NULL; -#endif - m_bridgeBuffer = NULL; - m_waypointBuffer = NULL; -#ifdef DO_ROADS - m_roadBuffer = NULL; -#endif -#ifdef DO_SCORCH - m_vertexScorch = NULL; - m_indexScorch = NULL; - m_scorchTexture = NULL; - clearAllScorches(); - m_shroud = NULL; -#endif - m_bridgeBuffer = NEW W3DBridgeBuffer; - - if (TheGlobalData->m_headless) - return; - - m_treeBuffer = NEW W3DTreeBuffer; - - m_bibBuffer = NEW W3DBibBuffer; - - m_curImpassableSlope = 45.0f; // default to 45 degrees. - -#ifdef TEST_CUSTOM_EDGING - m_customEdging = NEW W3DCustomEdging; -#endif - m_waypointBuffer = NEW W3DWaypointBuffer; -#ifdef DO_ROADS - m_roadBuffer = NEW W3DRoadBuffer; -#endif - -#if defined(RTS_DEBUG) - if (TheGlobalData->m_shroudOn) - m_shroud = NEW W3DShroud; -#else - m_shroud = NEW W3DShroud; -#endif - DX8Wrapper::SetCleanupHook(this); -} - - -//============================================================================= -// HeightMapRenderObjClass::adjustTerrainLOD -//============================================================================= -/** Adjust the terrain Level Of Detail. If adj > 0 , increases LOD 1 step, if -adj < 0 decreases it one step, if adj==0, then just sets up for the current LOD */ -//============================================================================= -void HeightMapRenderObjClass::adjustTerrainLOD(Int adj) -{ - if (adj>0 && TheGlobalData->m_terrainLODm_terrainLOD=(TerrainLOD)(TheGlobalData->m_terrainLOD+1); - if (adj<0 && TheGlobalData->m_terrainLOD>TERRAIN_LOD_MIN) TheWritableGlobalData->m_terrainLOD=(TerrainLOD)(TheGlobalData->m_terrainLOD-1); - - switch (TheGlobalData->m_terrainLOD) { - case TERRAIN_LOD_MIN: TheWritableGlobalData->m_useCloudMap = false; - TheWritableGlobalData->m_useLightMap = false ; - TheWritableGlobalData->m_useWaterPlane = false; - TheWritableGlobalData->m_stretchTerrain = false; - TheWritableGlobalData->m_useHalfHeightMap = true; - break; - case TERRAIN_LOD_HALF_CLOUDS: TheWritableGlobalData->m_useCloudMap = true; - TheWritableGlobalData->m_useLightMap = true; - TheWritableGlobalData->m_useWaterPlane = false; - TheWritableGlobalData->m_stretchTerrain = false; - TheWritableGlobalData->m_useHalfHeightMap = true; - break; - case TERRAIN_LOD_STRETCH_NO_CLOUDS: TheWritableGlobalData->m_useCloudMap = false; - TheWritableGlobalData->m_useLightMap = false; - TheWritableGlobalData->m_useWaterPlane = false; - TheWritableGlobalData->m_stretchTerrain = true; - TheWritableGlobalData->m_useHalfHeightMap = false; - break; - case TERRAIN_LOD_STRETCH_CLOUDS: TheWritableGlobalData->m_useCloudMap = true; - TheWritableGlobalData->m_useLightMap = true; - TheWritableGlobalData->m_useWaterPlane = false; - TheWritableGlobalData->m_stretchTerrain = true; - TheWritableGlobalData->m_useHalfHeightMap = false; - break; - case TERRAIN_LOD_NO_CLOUDS: TheWritableGlobalData->m_useCloudMap = false; - TheWritableGlobalData->m_useLightMap = false; - TheWritableGlobalData->m_useWaterPlane = false; - TheWritableGlobalData->m_stretchTerrain = false; - TheWritableGlobalData->m_useHalfHeightMap = false; - break; - default: - case TERRAIN_LOD_NO_WATER: TheWritableGlobalData->m_useCloudMap = true; - TheWritableGlobalData->m_useLightMap = true; - TheWritableGlobalData->m_useWaterPlane = false; - TheWritableGlobalData->m_stretchTerrain = false; - TheWritableGlobalData->m_useHalfHeightMap = false; - break; - case TERRAIN_LOD_MAX: TheWritableGlobalData->m_useCloudMap = true; - TheWritableGlobalData->m_useLightMap = true; - TheWritableGlobalData->m_useWaterPlane = true; - TheWritableGlobalData->m_stretchTerrain = false; - TheWritableGlobalData->m_useHalfHeightMap = false; - break; - } - if (m_map==NULL) return; - m_map->setDrawOrg(m_map->getDrawOrgX(), m_map->getDrawOrgX()); - if (m_shroud) - m_shroud->reset(); //need reset here since initHeightData will load new shroud. - this->initHeightData(m_map->getDrawWidth(), - m_map->getDrawHeight(), m_map, NULL); - staticLightingChanged(); - if (TheTacticalView) { - TheTacticalView->setAngle(TheTacticalView->getAngle() + 1); - TheTacticalView->setAngle(TheTacticalView->getAngle() - 1); - } -} - -//============================================================================= -// HeightMapRenderObjClass::ReleaseResources -//============================================================================= -/** Releases all w3d assets, to prepare for Reset device call. */ -//============================================================================= -void HeightMapRenderObjClass::ReleaseResources(void) -{ - if (m_treeBuffer) { - m_treeBuffer->freeTreeBuffers(); - } - if (m_bibBuffer) { - m_bibBuffer->freeBibBuffers(); - } -#ifdef TEST_CUSTOM_EDGING - if (m_customEdging) - m_customEdging ->freeEdgingBuffers(); -#endif - if (m_bridgeBuffer) { - m_bridgeBuffer->freeBridgeBuffers(); - } - - if( m_waypointBuffer ) - { - m_waypointBuffer->freeWaypointBuffers(); - } - // We need to save the map. - WorldHeightMap *pMap=NULL; - REF_PTR_SET(pMap, m_map); - freeMapResources(); - m_map = pMap; // ref_ptr_set has already incremented the ref count. - if (TheWaterRenderObj) - TheWaterRenderObj->ReleaseResources(); - if (TheTerrainTracksRenderObjClassSystem) - TheTerrainTracksRenderObjClassSystem->ReleaseResources(); - if (TheW3DShadowManager) - TheW3DShadowManager->ReleaseResources(); - if (m_shroud) - { m_shroud->reset(); - m_shroud->ReleaseResources(); - } - - //Release any resources that may be used by custom pixel/vertex shaders - W3DShaderManager::shutdown(); -#ifdef DO_ROADS - if (m_roadBuffer) { - m_roadBuffer->freeRoadBuffers(); - } -#endif -} - -//============================================================================= -// HeightMapRenderObjClass::ReAcquireResources -//============================================================================= -/** Reallocates all W3D assets after a reset.. */ -//============================================================================= -void HeightMapRenderObjClass::ReAcquireResources(void) -{ - W3DShaderManager::init(); //reaquire resources which may be needed by custom shaders - - if (TheWaterRenderObj) - TheWaterRenderObj->ReAcquireResources(); - - if (TheTerrainTracksRenderObjClassSystem) - TheTerrainTracksRenderObjClassSystem->ReAcquireResources(); - - if (TheW3DShadowManager) - TheW3DShadowManager->ReAcquireResources(); - if (m_shroud) - m_shroud->ReAcquireResources(); - - Int x = m_x; - Int y = m_y; - - if (m_map) - { - this->initHeightData(x,y,m_map, NULL); - // Tell lights to update next time through. - m_needFullUpdate = true; - } - - if (m_treeBuffer) { - m_treeBuffer->allocateTreeBuffers(); - } - if (m_bibBuffer) { - m_bibBuffer->allocateBibBuffers(); - } -#ifdef TEST_CUSTOM_EDGING - if (m_customEdging) - m_customEdging ->allocateEdgingBuffers(); -#endif - if (m_bridgeBuffer) { - m_bridgeBuffer->allocateBridgeBuffers(); - } - - //Waypoint buffers are done dynamically. One line, one node (just rendered multiple times accessing other data). - //Internally creates it if needed. - -#ifdef DO_ROADS - if (m_roadBuffer) { - m_roadBuffer->allocateRoadBuffers(); - m_roadBuffer->loadRoads(); - } -#endif - - if (TheTacticalView) - { TheTacticalView->forceRedraw(); //force map to update itself for the current camera position. - //for some reason we need to do it twice otherwise we sometimes end up with a black map until - //the player moves. - TheTacticalView->forceRedraw(); - } -} - -//============================================================================= -// HeightMapRenderObjClass::updateMacroTexture -//============================================================================= -/** Updates the macro noise/lightmap texture (pass 3) */ -//============================================================================= -void HeightMapRenderObjClass::updateMacroTexture(AsciiString textureName) -{ - m_macroTextureName = textureName; - // Release texture. - REF_PTR_RELEASE(m_stageThreeTexture); - // Reallocate texture. - m_stageThreeTexture=NEW LightMapTerrainTextureClass(m_macroTextureName); -} - -//============================================================================= -// HeightMapRenderObjClass::reset -//============================================================================= -/** Updates the macro noise/lightmap texture (pass 3) */ -//============================================================================= -void HeightMapRenderObjClass::reset(void) -{ - if (m_treeBuffer) { - m_treeBuffer->clearAllTrees(); - } - clearAllScorches(); -#ifdef TEST_CUSTOM_EDGING - if (m_customEdging) - m_customEdging ->clearAllEdging(); -#endif -#ifdef DO_ROADS - if (m_roadBuffer) { - m_roadBuffer->clearAllRoads(); - } -#endif - if (m_bridgeBuffer) { - m_bridgeBuffer->clearAllBridges(); - } - - if (m_bibBuffer) { - m_bibBuffer->clearAllBibs(); - } - - m_showAsVisibleCliff.clear(); - - if (m_shroud) - { m_shroud->reset(); - m_shroud->setBorderShroudLevel((W3DShroudLevel)TheGlobalData->m_shroudAlpha); //assume border is always black at start. - } -} - -/**@todo: Ray intersection needs to be optimized with some sort of grid-tracing -(ala line drawing). We should also try making the search in a front->back order -relative to the ray so we can early exit as soon as we have a hit. -* -//============================================================================= -// HeightMapRenderObjClass::Cast_Ray -//============================================================================= -/** Return intersection of a ray with the heightmap mesh. -This is a quick version that just checks every polygon inside -a 2D bounding rectangle of the ray projected onto the heightfield plane. -For most of our view-picking cases the ray in almost perpendicular to the -map plane so this is very quick (small bounding box). But it can become slow -for arbitrary rays such as those used in AI visbility checks.(2 units on -opposite corners of the map would check every polygon in the map). -*/ -//============================================================================= -bool HeightMapRenderObjClass::Cast_Ray(RayCollisionTestClass & raytest) -{ - TriClass tri; - Bool hit = false; - Int X,Y; - Vector3 normal,P0,P1,P2,P3; - - if (!m_map) - return false; //need valid pointer to heightmap samples -//HeightSampleType *pData = m_map->getDataPtr(); - //Clip ray to extents of heightfield - AABoxClass hbox; - LineSegClass lineseg,lineseg2; - CastResultStruct result; - Int StartCellX = 0; - Int EndCellX = 0; - Int StartCellY = 0; - Int EndCellY = 0; - const Int overhang = 2*VERTEX_BUFFER_TILE_LENGTH+m_map->getBorderSize(); // Allow picking past the edge for scrolling & objects. - Vector3 minPt(MAP_XY_FACTOR*(-overhang), MAP_XY_FACTOR*(-overhang), -MAP_XY_FACTOR); - Vector3 maxPt(MAP_XY_FACTOR*(m_map->getXExtent()+overhang), - MAP_XY_FACTOR*(m_map->getYExtent()+overhang), MAP_HEIGHT_SCALE*m_map->getMaxHeightValue()+MAP_XY_FACTOR); - MinMaxAABoxClass mmbox(minPt, maxPt); - hbox.Init(mmbox); - - lineseg=raytest.Ray; - - //Set initial ray endpoints - P0 = raytest.Ray.Get_P0(); - P1 = raytest.Ray.Get_P1(); - result.ComputeContactPoint=true; - - Int p; - for (p=0; p<3; p++) { - //find intersection point of ray and terrain bounding box - result.Reset(); - result.ComputeContactPoint=true; - if (CollisionMath::Collide(lineseg,hbox,&result)) - { //ray intersects terrain or starts inside the terrain. - if (!result.StartBad) //check if start point inside terrain - P0 = result.ContactPoint; //make intersection point the new start of the ray. - - //reverse direction of original ray and clip again to extent of - //heightmap - result.Fraction=1.0f; //reset the result - result.StartBad=false; - lineseg2.Set(lineseg.Get_P1(),lineseg.Get_P0()); //reverse line segment - if (CollisionMath::Collide(lineseg2,hbox,&result)) - { if (!result.StartBad) //check if end point inside terrain - P1 = result.ContactPoint; //make intersection point the new end pont of ray - } - } else { - if (p==0) return(false); - break; - } - - // Take the 2D bounding box of ray and check heights - // inside this box for intersection. - if (P0.X > P1.X) { //flip start/end points - StartCellX = REAL_TO_INT_FLOOR(P1.X/MAP_XY_FACTOR); - EndCellX = REAL_TO_INT_CEIL(P0.X/MAP_XY_FACTOR); - } else { - StartCellX = REAL_TO_INT_FLOOR(P0.X/MAP_XY_FACTOR); - EndCellX = REAL_TO_INT_CEIL(P1.X/MAP_XY_FACTOR); - } - if (P0.Y > P1.Y) { //flip start/end points - StartCellY = REAL_TO_INT_FLOOR(P1.Y/MAP_XY_FACTOR); - EndCellY = REAL_TO_INT_CEIL(P0.Y/MAP_XY_FACTOR); - } else { - StartCellY = REAL_TO_INT_FLOOR(P0.Y/MAP_XY_FACTOR); - EndCellY = REAL_TO_INT_CEIL(P1.Y/MAP_XY_FACTOR); - } - - Int i, j, minHt, maxHt; - - minHt = m_map->getMaxHeightValue(); - maxHt = 0; - - for (j=StartCellY; j<=EndCellY; j++) { - for (i=StartCellX; i<=EndCellX; i++) { - Short cur = getClipHeight(i+m_map->getBorderSize(),j+m_map->getBorderSize()); - if (curComputeContactPoint=true; //tell CollisionMath that we need point. - - // Adjust indexes into the bordered height map. - - StartCellX += m_map->getBorderSize(); - EndCellX += m_map->getBorderSize(); - StartCellY += m_map->getBorderSize(); - EndCellY += m_map->getBorderSize(); - - Int offset; - for (offset = 1; offset < 5; offset *= 3) { - for (Y=StartCellY-offset; Y<=EndCellY+offset; Y++) { - //if (Y<0) continue; - //if (Y>=m_map->getYExtent()-1) continue; - - for (X=StartCellX-offset; X<=EndCellX+offset; X++) { - //test the 2 triangles in this cell - // 3-----2 - // | /| - // | / | - // |/ | - // 0-----1 - - //bottom triangle first - P0.X=ADJUST_FROM_INDEX_TO_REAL(X); - P0.Y=ADJUST_FROM_INDEX_TO_REAL(Y); - P0.Z=MAP_HEIGHT_SCALE*(float)getClipHeight(X, Y); - - P1.X=ADJUST_FROM_INDEX_TO_REAL(X+1); - P1.Y=ADJUST_FROM_INDEX_TO_REAL(Y); - P1.Z=MAP_HEIGHT_SCALE*(float)getClipHeight(X+1, Y); - - P2.X=ADJUST_FROM_INDEX_TO_REAL(X+1); - P2.Y=ADJUST_FROM_INDEX_TO_REAL(Y+1); - P2.Z=MAP_HEIGHT_SCALE*(float)getClipHeight(X+1, Y+1); - - P3.X=ADJUST_FROM_INDEX_TO_REAL(X); - P3.Y=ADJUST_FROM_INDEX_TO_REAL(Y+1); - P3.Z=MAP_HEIGHT_SCALE*(float)getClipHeight(X, Y+1); - - - tri.V[0] = &P0; - tri.V[1] = &P1; - tri.V[2] = &P2; - - tri.N = &normal; - - tri.Compute_Normal(); - - hit = hit || (Bool)CollisionMath::Collide(raytest.Ray, tri, raytest.Result); - - if (raytest.Result->StartBad) - return true; - - //top triangle - tri.V[0] = &P2; - tri.V[1] = &P3; - tri.V[2] = &P0; - - tri.N = &normal; - - tri.Compute_Normal(); - - hit = hit || (Bool)CollisionMath::Collide(raytest.Ray, tri, raytest.Result); - - if (hit) - raytest.Result->SurfaceType = SURFACE_TYPE_DEFAULT; ///@todo: WW3D uses this to return dirt, grass, etc. Do we need this? - } - // Don't break. It is possible to intersect 2 triangles, and the second is closer. if (hit) break; - } - // Don't break. It is possible to intersect 2 triangles, and the second is closer. if (hit) break; - } - return hit; -} - -//============================================================================= -// HeightMapRenderObjClass::getHeightMapHeight -//============================================================================= -/** return the height and normal of the triangle plane containing given location within heightmap. */ -//============================================================================= -Real HeightMapRenderObjClass::getHeightMapHeight(Real x, Real y, Coord3D* normal) const -{ - if (m_map == NULL) - { - if (normal) - { - // return a default normal pointing up - normal->x = 0.0f; - normal->y = 0.0f; - normal->z = 1.0f; - } - return 0; - } - - float height; - - // 3-----2 - // | /| - // | / | - // |/ | - // 0-----1 - //Find surrounding grid points - - const Real MAP_XY_FACTOR_INV = 1.0f / MAP_XY_FACTOR; - - float xdiv = x * MAP_XY_FACTOR_INV; - float ydiv = y * MAP_XY_FACTOR_INV; - - float ixf = floorf(xdiv); - float iyf = floorf(ydiv); - - float fx = xdiv - ixf; //get fraction - float fy = ydiv - iyf; //get fraction - - // since ixf & iyf are already floor'ed, we can use the fastest f->i conversion we have... - Int ix = REAL_TO_INT_FLOOR(ixf) + m_map->getBorderSize(); - Int iy = REAL_TO_INT_FLOOR(iyf) + m_map->getBorderSize(); - Int xExtent = m_map->getXExtent(); - - // Check for extent-3, not extent-1: we go into the next row/column of data for smoothed triangle points, so extent-1 - // goes off the end... - if (ix > (xExtent-3) || iy > (m_map->getYExtent()-3) || iy < 1 || ix < 1) - { - // sample point is not on the heightmap - if (normal) - { - // return a default normal pointing up - normal->x = 0.0f; - normal->y = 0.0f; - normal->z = 1.0f; - } - return getClipHeight(ix, iy) * MAP_HEIGHT_SCALE; - } - - const UnsignedByte* data = m_map->getDataPtr(); - int idx = ix + iy*xExtent; - float p0 = data[idx]; - float p2 = data[idx + xExtent + 1]; - if (fy > fx) // test if we are in the upper triangle - { - float p3 = data[idx + xExtent]; - height = (p3 + (1.0f-fy)*(p0-p3) + fx*(p2-p3)) * MAP_HEIGHT_SCALE; - } - else - { - // we are in the lower triangle - float p1 = data[idx + 1]; - height = (p1 + fy*(p2-p1) + (1.0f-fx)*(p0-p1)) * MAP_HEIGHT_SCALE; - } - if (normal) { - // 9 8 - // - //10 3-----2 7 - // | /| - // | / | - // |/ | - //11 0-----1 6 - // - // 4 5 - //Find surrounding grid points for smoothed normals. - int idx4 = ix + (iy-1)*xExtent; - int idx0 = ix + iy*xExtent; - int idx3 = ix + iy*xExtent+xExtent; - int idx9 = ix + (iy+2)*xExtent; - UnsignedByte d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11; - d0 = data[idx0]; - d1 = data[idx0+1]; - d2 = data[idx3+1]; - d3 = data[idx3]; - d4 = data[idx4]; - d5 = data[idx4+1]; - d6 = data[idx0+2]; - d7 = data[idx3+2]; - d8 = data[idx9+1]; - d9 = data[idx9]; - d10 = data[idx3-1]; - d11 = data[idx0-1]; - - Real deltaZ_X0 = d1-d11; - Real deltaZ_X1 = d6-d0; - Real deltaZ_X2 = d7-d3; - Real deltaZ_X3 = d6-d0; - - Real deltaZ_Y0 = d3-d4; - Real deltaZ_Y1 = d2-d5; - Real deltaZ_Y2 = d8-d1; - Real deltaZ_Y3 = d9-d0; - - // Interpolate to get the smoothed valued. - Real deltaZ_X_Left = deltaZ_X0*(1.0f-fx) + fx*deltaZ_X3; - Real deltaZ_X_Right = deltaZ_X1*(1.0f-fx) + fx*deltaZ_X2; - Real deltaZ_X = deltaZ_X_Left*(1.0-fy) + fy*deltaZ_X_Right; - - Real deltaZ_Y_Left = deltaZ_Y0*(1.0f-fx) + fx*deltaZ_Y3; - Real deltaZ_Y_Right = deltaZ_Y1*(1.0f-fx) + fx*deltaZ_Y2; - Real deltaZ_Y = deltaZ_Y_Left*(1.0-fy) + fy*deltaZ_Y_Right; - - - - Vector3 l2r, n2f, normalAtTexel; - l2r.Set(2*MAP_XY_FACTOR/MAP_HEIGHT_SCALE, 0, deltaZ_X); - n2f.Set(0, 2*MAP_XY_FACTOR/MAP_HEIGHT_SCALE, deltaZ_Y); - Vector3::Normalized_Cross_Product(l2r,n2f, &normalAtTexel); - normal->x = normalAtTexel.X; - normal->y = normalAtTexel.Y; - normal->z = normalAtTexel.Z; - - } - - - return height; -} - -//============================================================================= -Bool HeightMapRenderObjClass::isClearLineOfSight(const Coord3D& pos, const Coord3D& posOther) const -{ - if (m_map == NULL) - return false; // doh. should not happen. - -#define DO_BRESENHAM -#ifdef DO_BRESENHAM - - /* - this is WAY faster, though not quite as accurate... however, the inaccuracy - is pretty minimal, so we really should force other code to live with it. (srj) - */ - const Real MAP_XY_FACTOR_INV = 1.0f / MAP_XY_FACTOR; - - Int borderSize = m_map->getBorderSize(); - Int start_x = REAL_TO_INT_FLOOR(pos.x * MAP_XY_FACTOR_INV) + borderSize; - Int start_y = REAL_TO_INT_FLOOR(pos.y * MAP_XY_FACTOR_INV) + borderSize; - Int end_x = REAL_TO_INT_FLOOR(posOther.x * MAP_XY_FACTOR_INV) + borderSize; - Int end_y = REAL_TO_INT_FLOOR(posOther.y * MAP_XY_FACTOR_INV) + borderSize; - Int delta_x = abs(end_x - start_x); // The difference between the x's - Int delta_y = abs(end_y - start_y); // The difference between the y's - Int x = start_x; // Start x off at the first pixel - Int y = start_y; // Start y off at the first pixel - - Int xinc1, xinc2; - if (end_x >= start_x) // The x-values are increasing - { - xinc1 = 1; - xinc2 = 1; - } - else // The x-values are decreasing - { - xinc1 = -1; - xinc2 = -1; - } - - Int yinc1, yinc2; - if (end_y >= start_y) // The y-values are increasing - { - yinc1 = 1; - yinc2 = 1; - } - else // The y-values are decreasing - { - yinc1 = -1; - yinc2 = -1; - } - - Int den, num, numadd, numpixels; - - Bool checkY = true; - if (delta_x >= delta_y) // There is at least one x-value for every y-value - { - xinc1 = 0; // Don't change the x when numerator >= denominator - yinc2 = 0; // Don't change the y for every iteration - den = delta_x; - num = delta_x / 2; - numadd = delta_y; - numpixels = delta_x; // There are more x-values than y-values - } - else // There is at least one y-value for every x-value - { - checkY = false; - xinc2 = 0; // Don't change the x for every iteration - yinc1 = 0; // Don't change the y when numerator >= denominator - den = delta_y; - num = delta_y / 2; - numadd = delta_x; - numpixels = delta_y; // There are more y-values than x-values - } - - Real nsInv = 1.0f / numpixels; - Real z = pos.z; - Real dz = posOther.z - z; - Real zinc = dz * nsInv; - - Bool result = true; - const UnsignedByte* data = m_map->getDataPtr(); - Int xExtent = m_map->getXExtent(); - Int yExtent = m_map->getYExtent(); - for (Int curpixel = 0; curpixel < numpixels; curpixel++) - { - if (x < 0 || - y < 0 || - x >= xExtent-1 || - y >= yExtent-1) - { - // once we go off the map, we're done - break; - } - - Int idx = x + y*xExtent; - float height = data[idx]; - height = __max(height, data[idx + 1]); - height = __max(height, data[idx + xExtent]); - height = __max(height, data[idx + xExtent + 1]); - height *= MAP_HEIGHT_SCALE; - - // if terrainHeight > z, we can't see, so punt. - // add a little fudge to account for slop. - const Real LOS_FUDGE = 0.5f; - if (height > z + LOS_FUDGE) - { - result = false; - break; - } - - // we're above the max height of the terrain and still looking up, so we're done. - // (don't bother for reverse test, since that doesn't generally happen) - if (z >= getMaxHeight() && zinc > 0.0f) - { - break; - } - - z += zinc; - - // continue with the maintenance. - num += numadd; // Increase the numerator by the top of the fraction - if (num >= den) // Check if numerator >= denominator - { - num -= den; // Calculate the new numerator value - x += xinc1; // Change the x as appropriate - y += yinc1; // Change the y as appropriate - } - x += xinc2; // Change the x as appropriate - y += yinc2; // Change the y as appropriate - } - - return result; - -#else - - // walk a line from obj to objOther and - // find the highest point in between 'em. while - // we're doing this, also estimate the point on the - // line at the same x,y as the high-terrain-point. - - Real fx = pos.x; - Real fy = pos.y; - Real fz = pos.z; - Real fdx = posOther.x - fx; - Real fdy = posOther.y - fy; - Real fdz = posOther.z - fz; - - // What's the largest step size that will be accurate enough? - // Currently we use a step size of about 2 "feet", which - // seems acceptable accuracy. If performance here is inadequate, - // we can try increasing the step size, but be sure to retest - // accuracy. - Real len = ceilf(sqrtf(fdx*fdx + fdy*fdy)); - const Real STEP_LEN = 2.0f; - Int numSteps = REAL_TO_INT_CEIL(len / STEP_LEN); - if (numSteps < 1) numSteps = 1; - Real fnsInv = 1.0f / numSteps; - Real fxinc = fdx * fnsInv; - Real fyinc = fdy * fnsInv; - Real fzinc = fdz * fnsInv; - while (numSteps--) - { - Real terrainHeight = getHeightMapHeight( fx, fy, NULL ); - - // if terrainHeight > fz, we can't see, so punt. - // add a little fudge to account for slop. - const Real LOS_FUDGE = 0.5f; - if (terrainHeight > fz + LOS_FUDGE) - { - return false; - } - - // we're above the max height of the terrain and still looking up, so we're done. - // (don't bother for reverse test, since that doesn't generally happen) - if (fz >= getMaxHeight() && fzinc > 0.0f) - { - return true; - } - - fx += fxinc; - fy += fyinc; - fz += fzinc; - - } - - return true; -#endif -} - -//============================================================================= -// HeightMapRenderObjClass::getMaxCellHeight -//============================================================================= -/** Returns maximum height of the 4 corners containing the given point */ -//============================================================================= -Real HeightMapRenderObjClass::getMaxCellHeight(Real x, Real y) const -{ - float p0,p1,p2,p3; - float height; - - // 3-----2 - // | /| - // | / | - // |/ | - // 0-----1 - //Find surrounding grid points - - if (m_map == NULL) - { //sample point is not on the heightmap - return 0.0f; //return default height - } - Int offset = 1; - Int iX = x/MAP_XY_FACTOR; - Int iY = y/MAP_XY_FACTOR; - iX += m_map->getBorderSize(); - iY += m_map->getBorderSize(); - if (iX<0) iX = 0; - if (iY<0) iY = 0; - if (iX >= (m_map->getXExtent()-1)) { - iX = m_map->getXExtent()-2; - } - if (iY >= (m_map->getYExtent()-1)) { - iY = m_map->getYExtent()-2; - } - if (m_halfResMesh) { - offset = 2; - iX = (iX/2)*2; - iY = (iY/2)*2; - } - UnsignedByte *data = m_map->getDataPtr(); - p0=data[iX+iY*m_map->getXExtent()]*MAP_HEIGHT_SCALE; - p1=data[(iX+offset)+iY*m_map->getXExtent()]*MAP_HEIGHT_SCALE; - p2=data[(iX+offset)+(iY+offset)*m_map->getXExtent()]*MAP_HEIGHT_SCALE; - p3=data[iX+(iY+offset)*m_map->getXExtent()]*MAP_HEIGHT_SCALE; - - height=p0; - height=__max(height,p1); - height=__max(height,p2); - height=__max(height,p3); - - return height; -} - -//============================================================================= -// HeightMapRenderObjClass::isCliffCell -//============================================================================= -/** Returns true if the cell containing the point is a cliff cell */ -//============================================================================= -Bool HeightMapRenderObjClass::isCliffCell(Real x, Real y) -{ - - if (m_map == NULL) - { //sample point is not on the heightmap - return false; - } - Int iX = x/MAP_XY_FACTOR; - Int iY = y/MAP_XY_FACTOR; - iX += m_map->getBorderSize(); - iY += m_map->getBorderSize(); - if (iX<0) iX = 0; - if (iY<0) iY = 0; - if (iX >= (m_map->getXExtent()-1)) { - iX = m_map->getXExtent()-2; - } - if (iY >= (m_map->getYExtent()-1)) { - iY = m_map->getYExtent()-2; - } - return m_map->getCliffState(iX, iY); -} - -//============================================================================= -//============================================================================= -Bool HeightMapRenderObjClass::showAsVisibleCliff(Int xIndex, Int yIndex) const -{ - Int xSize = m_map->getXExtent(); - - return m_showAsVisibleCliff[xIndex + yIndex * xSize]; -} - -//============================================================================= -//============================================================================= -Bool HeightMapRenderObjClass::evaluateAsVisibleCliff(Int xIndex, Int yIndex, Real valuesGreaterThanRad) -{ - // This one never changes, so don't bother recomputing it. - static const Real distance[4] = - { - 0.0f, - 1.0 * MAP_XY_FACTOR, - sqrt(2.0f) * MAP_XY_FACTOR, - 1.0 * MAP_XY_FACTOR, - }; - - // Note: getHeight will protect us from going out of bounds by returning 0 if we give it - // a value outside of its bounds. - UnsignedByte bytes[4] = - { - m_map->getHeight(xIndex + 0, yIndex + 0), - m_map->getHeight(xIndex + 1, yIndex + 0), - m_map->getHeight(xIndex + 1, yIndex + 1), - m_map->getHeight(xIndex + 0, yIndex + 1), - }; - - Real heights[4] = - { - INT_TO_REAL(bytes[0]) * MAP_HEIGHT_SCALE, - INT_TO_REAL(bytes[1]) * MAP_HEIGHT_SCALE, - INT_TO_REAL(bytes[2]) * MAP_HEIGHT_SCALE, - INT_TO_REAL(bytes[3]) * MAP_HEIGHT_SCALE, - }; - - Bool anyImpassable = FALSE; - - for (Int i = 1; i < 4 && !anyImpassable; ++i) { - if (fabs((heights[i] - heights[0]) / distance[i]) > valuesGreaterThanRad) { - anyImpassable = TRUE; - } - } - - return anyImpassable; -} - -//============================================================================= -// HeightMapRenderObjClass::oversizeTerrain -//============================================================================= -/** Sets the terrain oversize amount. */ -//============================================================================= -void HeightMapRenderObjClass::oversizeTerrain(Int tilesToOversize) -{ - Int width = WorldHeightMap::NORMAL_DRAW_WIDTH; - Int height = WorldHeightMap::NORMAL_DRAW_HEIGHT; - if (tilesToOversize>0 && tilesToOversize<5) - { - width += 32*tilesToOversize; - height += 32*tilesToOversize; - if (width>m_map->getXExtent()) - width = m_map->getXExtent(); - if (height>m_map->getYExtent()) - height = m_map->getYExtent(); - } - Int dx = width-m_map->getDrawWidth(); - Int dy = height-m_map->getDrawHeight(); - m_map->setDrawWidth(width); - m_map->setDrawHeight(height); - dx /= 2; - dy /= 2; - Int newOrgX = m_map->getDrawOrgX()-dx; - Int newOrgy = m_map->getDrawOrgY()-dy; - if (newOrgX<0) newOrgX=0; - if (newOrgy<0) newOrgy=0; - m_map->setDrawOrg(newOrgX,newOrgy); - m_originX = 0; - m_originY = 0; - if (m_shroud) - m_shroud->reset(); - //delete m_shroud; - //m_shroud = NULL; - initHeightData(m_map->getDrawWidth(), m_map->getDrawHeight(), m_map, NULL); - m_needFullUpdate = true; -} - - - -//============================================================================= -// HeightMapRenderObjClass::Get_Obj_Space_Bounding_Sphere -//============================================================================= -/** WW3D method that returns object bounding sphere used in frustum culling*/ -//============================================================================= -void HeightMapRenderObjClass::Get_Obj_Space_Bounding_Sphere(SphereClass & sphere) const -{ - Vector3 ObjSpaceCenter((float)m_x*0.5f*MAP_XY_FACTOR,(float)m_y*0.5f*MAP_XY_FACTOR,(float)m_minHeight+(m_maxHeight-m_minHeight)*0.5f); - float length = ObjSpaceCenter.Length(); - - if (m_map) { - ObjSpaceCenter.X += m_map->getDrawOrgX()*MAP_XY_FACTOR; - ObjSpaceCenter.Y += m_map->getDrawOrgY()*MAP_XY_FACTOR; - } - sphere.Init(ObjSpaceCenter, length); -} - -//============================================================================= -// HeightMapRenderObjClass::Get_Obj_Space_Bounding_Box -//============================================================================= -/** WW3D method that returns object bounding box used in collision detection*/ -//============================================================================= -void HeightMapRenderObjClass::Get_Obj_Space_Bounding_Box(AABoxClass & box) const -{ - Vector3 minPt(0,0,m_minHeight); - Vector3 maxPt((float)m_x*MAP_XY_FACTOR,(float)m_y*MAP_XY_FACTOR,(float)m_maxHeight); - if (m_map) { - minPt.X += m_map->getDrawOrgX()*MAP_XY_FACTOR; - minPt.Y += m_map->getDrawOrgY()*MAP_XY_FACTOR; - maxPt.X += m_map->getDrawOrgX()*MAP_XY_FACTOR; - maxPt.Y += m_map->getDrawOrgY()*MAP_XY_FACTOR; - } - MinMaxAABoxClass minMaxBox(minPt, maxPt); - - box.Init(minMaxBox); -} - -//------------------------------------------------------------------------------------------------- -/** Get the 3D extent of the terrain visible through the camera. Return value - is false if no part of terrain is visible. This function returns a worse - case bounding volume based on lowest/highest points in entire terrain. It - does not optimize the volume to heights actually visible. Unlike some of - the other methods, this function is guaranteed not to miss any visible - polygons. The ignoreMaxHeight flag is used to return a box that uses the - camera position as the maximum height instead of the terrain - good for getting - a volume enclosing things that can float above terrain. - */ -//------------------------------------------------------------------------------------------------- -Bool HeightMapRenderObjClass::getMaximumVisibleBox(const FrustumClass &frustum, AABoxClass *box, Bool ignoreMaxHeight) -{ - //create a plane from the lowest point on the terrain - PlaneClass groundPlane(Vector3(0,0,1), m_minHeight); - - //clip each side of the view frustum to ground plane - float clipFraction; - Vector3 ClippedCorners[8]; - ClippedCorners[0]=frustum.Corners[0]; - for (Int i=0; i<4; i++) - { ClippedCorners[i]=frustum.Corners[i]; - if (groundPlane.Compute_Intersection(frustum.Corners[i],frustum.Corners[i+4],&clipFraction)) - { //edge intersects the terrain - ClippedCorners[i+4]=frustum.Corners[i]+(frustum.Corners[i+4]-frustum.Corners[i])*clipFraction; - } - else - ClippedCorners[i+4]=frustum.Corners[i+4]; - } - - if (box) - box->Init(ClippedCorners,8); - - return TRUE; -} - -//============================================================================= -// HeightMapRenderObjClass::Class_ID -//============================================================================= -/** returns the class id, so the scene can tell what kind of render object it has. */ -//============================================================================= -Int HeightMapRenderObjClass::Class_ID(void) const -{ - return RenderObjClass::CLASSID_TILEMAP; -} - -//============================================================================= -// HeightMapRenderObjClass::Clone -//============================================================================= -/** Not used, but required virtual method. */ -//============================================================================= -RenderObjClass * HeightMapRenderObjClass::Clone(void) const -{ - assert(false); - return NULL; -} - -//============================================================================= -// HeightMapRenderObjClass::loadRoadsAndBridges -//============================================================================= -/** Loads the roads from the map objects. */ -//============================================================================= -void HeightMapRenderObjClass::loadRoadsAndBridges(W3DTerrainLogic *pTerrainLogic, Bool saveGame) -{ - if (DX8Wrapper::_Get_D3D_Device8() && (DX8Wrapper::_Get_D3D_Device8()->TestCooperativeLevel()) != D3D_OK) - return; //device not ready to render anything - -#ifdef DO_ROADS - if (m_roadBuffer) { - m_roadBuffer->loadRoads(); - } -#endif - if (m_bridgeBuffer) { - m_bridgeBuffer->loadBridges(pTerrainLogic, saveGame); - } -} - -// ============================================================================ -// HeightMapRenderObjClass::worldBuilderUpdateBridgeTowers -// ============================================================================ -/** The worldbuilder has it's own method here to update the visual representation - * of the bridge towers */ -// ============================================================================ -void HeightMapRenderObjClass::worldBuilderUpdateBridgeTowers( W3DAssetManager *assetManager, - SimpleSceneClass *scene ) -{ - - if( m_bridgeBuffer ) - m_bridgeBuffer->worldBuilderUpdateBridgeTowers( assetManager, scene ); - -} - -void HeightMapRenderObjClass::setShoreLineDetail(void) -{ - if (!m_map) - return; - - Int m_mapDX=m_map->getXExtent(); - Int m_mapDY=m_map->getYExtent(); - - //Find all shoreline tiles so they can get extra alpha blend - updateShorelineTiles(0,0,m_mapDX-1,m_mapDY-1,m_map); -} - -/**Scan through our map and record all tiles which cross a water plane and are within visible depth under -water.*/ -void HeightMapRenderObjClass::updateShorelineTiles(Int minX, Int minY, Int maxX, Int maxY, WorldHeightMap *pMap) -{ - Int border = pMap->getBorderSize(); - - //Clamp region to valid terrain tiles - if (minX<0) - minX = 0; - if (minY<0) - minY = 0; - if (maxX > (pMap->getXExtent() - 1)) - maxX = (pMap->getXExtent() - 1); - if (maxY > (pMap->getYExtent() - 1)) - maxY = (pMap->getYExtent() - 1); - - if (!m_shoreLineTilePositions) - { //Need to allocate memory - m_shoreLineTilePositions = NEW shoreLineTileInfo[DEFAULT_MAX_MAP_SHORELINE_TILES]; - m_shoreLineTilePositionsSize = DEFAULT_MAX_MAP_SHORELINE_TILES; - } - - //Find list of all extra blend tiles used on map. These are tiles with 3 materials/textures - //over the same tile and require an extra render pass. - - //First remove any existing extra blend tiles within this partial region - Int j=0; - for (; j> 16; - if (x >= minX && x < maxX && - y >= minY && y < maxY) - { //this tile is inside region being updated so remove it by shifting tile array - memcpy(m_shoreLineTilePositions+j,m_shoreLineTilePositions+j+1,(m_numShoreLineTiles-1-j)*sizeof(shoreLineTileInfo)); - m_numShoreLineTiles--; - j--; //look at current tile again since it was removed. - } - } - - if (TheWaterTransparency->m_transparentWaterDepth == 0 || !TheGlobalData->m_showSoftWaterEdge) - return; - - Int waterSide; - Real waterZ0,waterZ1,waterZ2,waterZ3; - Real terrainZ0, terrainZ1, terrainZ2, terrainZ3; - //Figure out maximum depth of water before we reach the m_minWaterOpacity value. Depths greater than this don't need - //custom shoreline tiles because they will get their opacity from the default value stored in the frame buffer during - //a screen clear operation. - Real transparentDepth=TheWaterTransparency->m_transparentWaterDepth*TheWaterTransparency->m_minWaterOpacity; - Real depthScaleFactor = 1.0f/transparentDepth; - - for (j=minY; jgetWaterHeight((i-border)*MAP_XY_FACTOR,(j-border)*MAP_XY_FACTOR)) > ((terrainZ0=MAP_HEIGHT_SCALE*pMap->getHeight(i,j))); - waterSide |=((waterZ1=TheWaterRenderObj->getWaterHeight((i-border+1)*MAP_XY_FACTOR,(j-border)*MAP_XY_FACTOR)) > ((terrainZ1=MAP_HEIGHT_SCALE*pMap->getHeight(i+1,j)))) << 1; - waterSide |=((waterZ2=TheWaterRenderObj->getWaterHeight((i-border+1)*MAP_XY_FACTOR,(j-border+1)*MAP_XY_FACTOR)) > ((terrainZ2=MAP_HEIGHT_SCALE*pMap->getHeight(i+1,j+1)))) << 2; - waterSide |=((waterZ3=TheWaterRenderObj->getWaterHeight((i-border)*MAP_XY_FACTOR,(j-border+1)*MAP_XY_FACTOR)) > ((terrainZ3=MAP_HEIGHT_SCALE*pMap->getHeight(i,j+1)))) << 3; - - if (!waterSide || (waterZ0*waterZ1*waterZ2*waterZ3) <= 0) - continue; //all verts are on positive (surface) side of water so don't need blending. Or one of them is outside the water plane bounds (waterHeight <= 0!) - - //Check if mix of under/over water vertices or some vertices within depth fade region. - if (waterSide < 0xf || (waterZ0 - terrainZ0) < transparentDepth || - (waterZ1 - terrainZ1) < transparentDepth || (waterZ2 - terrainZ2) < transparentDepth - || (waterZ3 - terrainZ3) < transparentDepth) - { //add tile to set that needs shoreline blending. - if (m_numShoreLineTiles >= m_shoreLineTilePositionsSize) - { //no more room to store extra blend tiles so enlarge the buffer. - shoreLineTileInfo *tempPositions=NEW shoreLineTileInfo[m_shoreLineTilePositionsSize+512]; - memcpy(tempPositions, m_shoreLineTilePositions, m_shoreLineTilePositionsSize*sizeof(shoreLineTileInfo)); - delete [] m_shoreLineTilePositions; - //enlarge by more tiles to reduce memory trashing - m_shoreLineTilePositions = tempPositions; - m_shoreLineTilePositionsSize += 512; - } - //Pack x and y position into single integer since maps are limited in size - shoreLineTileInfo *shoreInfo=&m_shoreLineTilePositions[m_numShoreLineTiles]; - shoreInfo->m_xy=i | (j <<16); - shoreInfo->t0=(waterZ0 - terrainZ0)*depthScaleFactor; - shoreInfo->t1=(waterZ1 - terrainZ1)*depthScaleFactor; - shoreInfo->t2=(waterZ2 - terrainZ2)*depthScaleFactor; - shoreInfo->t3=(waterZ3 - terrainZ3)*depthScaleFactor; - m_numShoreLineTiles++; - } - } -} - -/** Generate a lookup table for arbitrary angled impassable area viewing. */ -void HeightMapRenderObjClass::updateViewImpassableAreas(Bool partial, Int minX, Int maxX, Int minY, Int maxY) -{ - Int xSize = m_map->getXExtent(); - Int ySize = m_map->getYExtent(); - if (m_showAsVisibleCliff.size() != xSize * ySize) { - m_showAsVisibleCliff.resize(xSize * ySize); - } - - if (!partial) { - minX = 0; - minY = 0; - maxX = xSize; - maxY = ySize; - } - - // save calculating the tangent over and over again. - Real tanImpassableRad = tan(m_curImpassableSlope / 360.f * 2 * PI); - for (Int j = minY; j < maxY; ++j) { - for (Int i = minX; i < maxX; ++i) { - m_showAsVisibleCliff[i + j * xSize] = evaluateAsVisibleCliff(i, j, tanImpassableRad); - } - } -} - -/** Generate a lookup table which can be used to generate an -alpha value from a given set of uv coordinates. Currently used -for smoothing water/terrain border*/ -void HeightMapRenderObjClass::initDestAlphaLUT(void) -{ - if (!m_destAlphaTexture) - return; - - SurfaceClass *surf=m_destAlphaTexture->Get_Surface_Level(); - - if (surf) - { - Int pitch; - UnsignedInt *pData=(UnsignedInt*)surf->Lock(&pitch); - - Int maxOpacity=(Int)(TheWaterTransparency->m_minWaterOpacity * 255.0f); - Int alpha; - - if (pData) - { - //Fill texture with alpha gradient - for (Int x=0; x<256; x++) - { - alpha = x; - if (alpha > maxOpacity) - alpha = maxOpacity; - *pData=(alpha<<24)|0x00ffffff; - pData++; - } - surf->Unlock(); - } - - m_destAlphaTexture->Get_Filter().Set_U_Addr_Mode(TextureFilterClass::TEXTURE_ADDRESS_CLAMP); - m_destAlphaTexture->Get_Filter().Set_V_Addr_Mode(TextureFilterClass::TEXTURE_ADDRESS_CLAMP); - REF_PTR_RELEASE(surf); - m_currentMinWaterOpacity = TheWaterTransparency->m_minWaterOpacity; - } -} - -//============================================================================= -// HeightMapRenderObjClass::initHeightData -//============================================================================= -/** Allocate a heightmap of x by y vertices and fill with initial height values. -Also allocates all rendering resources such as vertex buffers, index buffers, -shaders, and materials.*/ -//============================================================================= -Int HeightMapRenderObjClass::initHeightData(Int x, Int y, WorldHeightMap *pMap, RefRenderObjListIterator *pLightsIterator) -{ - Int i,j; -// Int vertsPerRow=x*2-2; -// Int vertsPerColumn=y*2-2; - - REF_PTR_SET(m_map,pMap); //update our heightmap pointer in case it changed since last call. - - if (m_shroud) - m_shroud->init(m_map,TheGlobalData->m_partitionCellSize,TheGlobalData->m_partitionCellSize); -#ifdef DO_ROADS - if (m_roadBuffer) - m_roadBuffer->setMap(m_map); -#endif - HeightSampleType *data = NULL; - if (pMap) { - data = pMap->getDataPtr(); - } - - m_numExtraBlendTiles = 0; - m_numShoreLineTiles = 0; - //Do some preprocessing on map to extract useful data - if (pMap) - { - //Find min/max values for all terrain heights, useful for rendering optimization - Int m_mapDX=pMap->getXExtent(); - Int m_mapDY=pMap->getYExtent(); - Int i, j, minHt, maxHt; - - minHt = pMap->getMaxHeightValue(); - maxHt = 0; - - for (j=0; jgetHeight(i,j); - if (curgetExtraAlphaUVData(i,j,U,V,alpha,&flipState, &cliffState)) - { if (m_numExtraBlendTiles >= m_extraBlendTilePositionsSize) - { //no more room to store extra blend tiles so enlarge the buffer. - Int *tempPositions=NEW Int[m_extraBlendTilePositionsSize+512]; - memcpy(tempPositions, m_extraBlendTilePositions, m_extraBlendTilePositionsSize*sizeof(Int)); - delete [] m_extraBlendTilePositions; - //enlarge by more tiles to reduce memory trashing - m_extraBlendTilePositions = tempPositions; - m_extraBlendTilePositionsSize += 512; - } - //Pack x and y position into single integer since maps are limited in size - m_extraBlendTilePositions[m_numExtraBlendTiles]=i | (j <<16); - m_numExtraBlendTiles++; - } - } - - //Find all shoreline tiles so they can get extra alpha blend - updateShorelineTiles(0,0,m_mapDX-1,m_mapDY-1,pMap); - if (TheWaterTransparency->m_minWaterOpacity != m_currentMinWaterOpacity) - initDestAlphaLUT(); - } - - Set_Force_Visible(TRUE); //terrain is always visible. - m_halfResMesh = TheGlobalData->m_useHalfHeightMap; - m_originX = 0; - m_originY = 0; - m_needFullUpdate = true; - - m_scorchesInBuffer = 0; - m_curNumScorchVertices=0; - m_curNumScorchIndices=0; - // If the size changed, we need to allocate. - Bool needToAllocate = (x != m_x || y != m_y); - // If the textures aren't allocated (usually because of a hardware reset) need to allocate. - if (m_stageOneTexture == NULL && m_treeBuffer) { - needToAllocate = true; - } - if (data && needToAllocate && m_treeBuffer != NULL) - { //requested heightmap different from old one. - //allocate a new one. - freeMapResources(); //free old data and ib/vb - REF_PTR_SET(m_map,pMap); //update our heightmap pointer in case it changed since last call. - m_stageTwoTexture=NEW CloudMapTerrainTextureClass; - m_stageThreeTexture=NEW LightMapTerrainTextureClass(m_macroTextureName); - m_destAlphaTexture=MSGNEW("TextureClass") TextureClass(256,1,WW3D_FORMAT_A8R8G8B8,MIP_LEVELS_1); - initDestAlphaLUT(); -#ifdef DO_SCORCH - allocateScorchBuffers(); -#endif - - //Create static index buffers. These will index the vertex buffers holding the map. - m_indexBuffer=NEW_REF(DX8IndexBufferClass,(VERTEX_BUFFER_TILE_LENGTH*VERTEX_BUFFER_TILE_LENGTH*2*3)); - - // Fill up the IB - DX8IndexBufferClass::WriteLockClass lockIdxBuffer(m_indexBuffer); - UnsignedShort *ib=lockIdxBuffer.Get_Index_Array(); - - for (j=0; j<(VERTEX_BUFFER_TILE_LENGTH*VERTEX_BUFFER_TILE_LENGTH*4); j+=VERTEX_BUFFER_TILE_LENGTH*4) - { - for (i=j; i<(j+VERTEX_BUFFER_TILE_LENGTH*4); i+=4) //4 vertices per 2x2 block - { - ib[0]=i; - ib[1]=i+2; - ib[2]=i+3; - - ib[3]=i; - ib[4]=i+1; - ib[5]=i+2; - - ib+=6; //skip the 6 indices we just filled - } - } - - //Get number of vertex buffers needed to hold current map - //First round dimensions to next multiple of VERTEX_BUFFER_TILE_LENGTH since that's our - //blocksize - m_numVBTilesX=1; - for (i=VERTEX_BUFFER_TILE_LENGTH+1; iGetCreationParameters(&parms); - Bool softwareVertexProcessing = 0!=(parms.BehaviorFlags&D3DCREATE_SOFTWARE_VERTEXPROCESSING); - if (m_xformedVertexBuffer == NULL && softwareVertexProcessing) { - m_xformedVertexBuffer = NEW IDirect3DVertexBuffer8*[m_numVertexBufferTiles]; - } -#endif - - for (i=0; iCreateVertexBuffer( - D3DXGetFVFVertexSize(D3DFVF_XYZRHW |D3DFVF_DIFFUSE|D3DFVF_TEX2)*numVertex, - D3DUSAGE_WRITEONLY|D3DUSAGE_DYNAMIC, - D3DFVF_XYZRHW |D3DFVF_DIFFUSE|D3DFVF_TEX2, - D3DPOOL_DEFAULT, - &m_xformedVertexBuffer[i]); - } -#endif - } - - //go with a preset material for now. -#ifdef USE_NORMALS - m_vertexMaterialClass= NEW VertexMaterialClass(); - m_vertexMaterialClass->Set_Shininess(0.0); - m_vertexMaterialClass->Set_Ambient(1,1,1); - m_vertexMaterialClass->Set_Diffuse(1,1,1); - m_vertexMaterialClass->Set_Specular(0,0,0); - m_vertexMaterialClass->Set_Opacity(0); - m_vertexMaterialClass->Set_Lighting(true); -#else - m_vertexMaterialClass=VertexMaterialClass::Get_Preset(VertexMaterialClass::PRELIT_DIFFUSE); -#endif - - m_shaderClass = detailOpaqueShader; // ShaderClass::_PresetOpaqueShader; - } - - updateBlock(0,0,x-1,y-1,pMap,pLightsIterator); - - return 0; -} - -#ifdef DO_SCORCH -//============================================================================= -// HeightMapRenderObjClass::freeScorchBuffers -//============================================================================= -/** Frees the vertex buffers for scorches.*/ -//============================================================================= -void HeightMapRenderObjClass::freeScorchBuffers(void) -{ - REF_PTR_RELEASE(m_vertexScorch); - REF_PTR_RELEASE(m_indexScorch); - REF_PTR_RELEASE(m_scorchTexture); -} - -//============================================================================= -// HeightMapRenderObjClass::allocateScorchBuffers -//============================================================================= -/** Allocates the vertex buffer and texture for scorches.*/ -//============================================================================= -void HeightMapRenderObjClass::allocateScorchBuffers(void) -{ - m_vertexScorch=NEW_REF(DX8VertexBufferClass,(DX8_FVF_XYZDUV1,MAX_SCORCH_VERTEX,DX8VertexBufferClass::USAGE_DEFAULT)); - m_indexScorch=NEW_REF(DX8IndexBufferClass,(MAX_SCORCH_INDEX)); - m_scorchTexture=NEW ScorchTextureClass; - m_scorchesInBuffer = 0; // If we just allocated the buffers, we got no scorches in the buffer. - m_curNumScorchVertices=0; - m_curNumScorchIndices=0; -#ifdef RTS_DEBUG - Vector3 loc(4*MAP_XY_FACTOR,4*MAP_XY_FACTOR,0); - addScorch(loc, 1*MAP_XY_FACTOR, SCORCH_1); - loc.Y += 10*MAP_XY_FACTOR; - loc.X += 5*MAP_XY_FACTOR; - addScorch(loc, 3*MAP_XY_FACTOR, SCORCH_1); -#endif - -} - -//============================================================================= -// HeightMapRenderObjClass::updateScorches -//============================================================================= -/** Builds the vertex buffer data for drawing the scorches.*/ -//============================================================================= -void HeightMapRenderObjClass::updateScorches(void) -{ - if (m_scorchesInBuffer > 1) { - return; - } - if (!m_indexScorch || !m_vertexScorch) { - return; - } - m_curNumScorchVertices = 0; - m_curNumScorchIndices = 0; - DX8IndexBufferClass::WriteLockClass lockIdxBuffer(m_indexScorch); - UnsignedShort *ib=lockIdxBuffer.Get_Index_Array(); - UnsignedShort *curIb = ib; - - DX8VertexBufferClass::WriteLockClass lockVtxBuffer(m_vertexScorch); - VertexFormatXYZDUV1 *vb = (VertexFormatXYZDUV1*)lockVtxBuffer.Get_Vertex_Array(); - VertexFormatXYZDUV1 *curVb = vb; - - Int curScorch; - Real shadeR, shadeG, shadeB; - shadeR = TheGlobalData->m_terrainAmbient[0].red; - shadeG = TheGlobalData->m_terrainAmbient[0].green; - shadeB = TheGlobalData->m_terrainAmbient[0].blue; - shadeR += TheGlobalData->m_terrainDiffuse[0].red/2; - shadeG += TheGlobalData->m_terrainDiffuse[0].green/2; - shadeB += TheGlobalData->m_terrainDiffuse[0].blue/2; - shadeR*=255.0f; - shadeG*=255.0f; - shadeB*=255.0f; - Int diffuse=REAL_TO_INT(shadeB) | (REAL_TO_INT(shadeG) << 8) | (REAL_TO_INT(shadeR) << 16) | ((int)255 << 24); - m_scorchesInBuffer = 0; - for (curScorch=m_numScorches-1; curScorch>=0; curScorch--) { - m_scorchesInBuffer++; - Real radius = m_scorches[curScorch].radius; - Vector3 loc = m_scorches[curScorch].location; - Int type = m_scorches[curScorch].scorchType; - if (type<0) { - type = 0; - } - if (type >= SCORCH_MARKS_IN_TEXTURE) { - type = 0; - } - Real amtToFloat = 0; - if (m_halfResMesh) { - amtToFloat = MAP_HEIGHT_SCALE/8; - } - - Int minX = REAL_TO_INT_FLOOR((loc.X-radius)/MAP_XY_FACTOR); - Int minY = REAL_TO_INT_FLOOR((loc.Y-radius)/MAP_XY_FACTOR); - if (minX<-m_map->getBorderSize()) minX=-m_map->getBorderSize(); - if (minY<-m_map->getBorderSize()) minY=-m_map->getBorderSize(); - Int maxX = REAL_TO_INT_CEIL((loc.X+radius)/MAP_XY_FACTOR); - Int maxY = REAL_TO_INT_CEIL((loc.Y+radius)/MAP_XY_FACTOR); - maxX++; maxY++; - if (maxX > m_map->getXExtent()-m_map->getBorderSize()) { - maxX = m_map->getXExtent()-m_map->getBorderSize(); - } - if (maxY > m_map->getYExtent()-m_map->getBorderSize()) { - maxY = m_map->getYExtent()-m_map->getBorderSize(); - } - Int startVertex = m_curNumScorchVertices; - Int i, j; - for (j=minY; j= MAX_SCORCH_VERTEX) return; - curVb->diffuse = diffuse; - Real theZ; - theZ = amtToFloat+((float)getClipHeight(i+m_map->getBorderSize(),j+m_map->getBorderSize())*MAP_HEIGHT_SCALE); - if (m_halfResMesh) { - theZ = amtToFloat + this->getMaxCellHeight(i, j); - Real amt2 = amtToFloat + getMaxCellHeight(i-1, j-1); - if (amt2 > theZ) { - theZ = amt2; - } - } - // The scorchmarks are spaced out by 1.5 in the texture. - Real uOffset = (type%SCORCH_PER_ROW) * 1.5f; - Real vOffset = (type/SCORCH_PER_ROW) * 1.5f; - Real X = i*MAP_XY_FACTOR; - Real Y = j*MAP_XY_FACTOR; - curVb->u1 = (uOffset + 0.5f + (X - loc.X)/(2*radius)) / (SCORCH_PER_ROW+1); - curVb->v1 = (vOffset + 0.5f + (Y - loc.Y)/(2*radius)) / (SCORCH_PER_ROW+1); - curVb->x = X; - curVb->y = Y; - curVb->z = theZ; - curVb++; - m_curNumScorchVertices++; - } - } - Int yOffset = maxX-minX; - for (j=0; j MAX_SCORCH_INDEX) return; - Int xNdx = i+minX+m_map->getBorderSize(); - Int yNdx = j+minY+m_map->getBorderSize(); - Bool flipForBlend = m_map->getFlipState(xNdx, yNdx); -#if 0 - UnsignedByte alpha[4]; - float UA[4], VA[4]; - m_map->getAlphaUVData(xNdx, yNdx, UA, VA, alpha, &flipForBlend, false); -#endif - if (flipForBlend) { - *curIb++ = startVertex + j*yOffset + i+1; - *curIb++ = startVertex + j*yOffset + i+yOffset; - *curIb++ = startVertex + j*yOffset + i; - *curIb++ = startVertex + j*yOffset + i+1; - *curIb++ = startVertex + j*yOffset + i+1+yOffset; - *curIb++ = startVertex + j*yOffset + i+yOffset; - } - else - { - *curIb++ = startVertex + j*yOffset + i; - *curIb++ = startVertex + j*yOffset + i+1+yOffset; - *curIb++ = startVertex + j*yOffset + i+yOffset; - *curIb++ = startVertex + j*yOffset + i; - *curIb++ = startVertex + j*yOffset + i+1; - *curIb++ = startVertex + j*yOffset + i+1+yOffset; - } - m_curNumScorchIndices+=6; - } - } - } - -} - -#endif - -//============================================================================= -// HeightMapRenderObjClass::clearAllScorches -//============================================================================= -/** Removes all scorches. */ -//============================================================================= -void HeightMapRenderObjClass::clearAllScorches(void) -{ -#ifdef DO_SCORCH - m_numScorches=0; - m_scorchesInBuffer=0; -#endif -} - -//============================================================================= -// HeightMapRenderObjClass::addScorch -//============================================================================= -/** Adds a scorch mark. */ -//============================================================================= -void HeightMapRenderObjClass::addScorch(Vector3 location, Real radius, Scorches type) -{ -#ifdef DO_SCORCH - if (m_numScorches >= MAX_SCORCH_MARKS) { - Int i; - for (i=0; i= m_map->getXExtent()) - x=m_map->getXExtent()-1; - if (y >= m_map->getYExtent()) - y=m_map->getYExtent()-1; - if (m_halfResMesh) { - x&=0xffffffe; - y&=0xffffffe; - } - - if (m_map == NULL) { - return(0); - } - - Vector3 l2r,n2f,normalAtTexel; - Int vn0,un0,vp1,up1; - Int cellOffset = 1; - if (m_halfResMesh) { - cellOffset = 2; - } - - vn0 = y-cellOffset; - vp1 = y+cellOffset; - if (vp1 >= m_map->getYExtent()) - vp1=m_map->getYExtent()-1; - if (vn0<0) vn0 = 0; - un0 = x-cellOffset; - up1 = x+cellOffset; - if (un0 < 0) - un0=0; - if (up1 >= m_map->getXExtent()) - up1=m_map->getXExtent()-1; - - Vector3 lightRay[MAX_GLOBAL_LIGHTS]; - const Coord3D *lightPos; - - for (Int lightIndex=0; lightIndex < TheGlobalData->m_numGlobalLights; lightIndex++) - { - lightPos=&TheGlobalData->m_terrainLightPos[lightIndex]; - lightRay[lightIndex].Set(-lightPos->x,-lightPos->y, -lightPos->z); - } - - //top-left sample - l2r.Set(2*MAP_XY_FACTOR,0,MAP_HEIGHT_SCALE*(m_map->getHeight(up1, y) - m_map->getHeight(un0, y))); - n2f.Set(0,2*MAP_XY_FACTOR,MAP_HEIGHT_SCALE*(m_map->getHeight(x, vp1) - m_map->getHeight(x, vn0))); - -#ifdef ALLOW_TEMPORARIES - normalAtTexel= Normalize(Vector3::Cross_Product(l2r,n2f)); -#else - Vector3::Normalized_Cross_Product(l2r,n2f, &normalAtTexel); -#endif - - VERTEX_FORMAT vertex; - vertex.x=ADJUST_FROM_INDEX_TO_REAL(x); - vertex.y=ADJUST_FROM_INDEX_TO_REAL(y); - - vertex.z= ((float)m_map->getHeight(x,y))*MAP_HEIGHT_SCALE; - vertex.u1=0; - vertex.v1=0; - vertex.u2=1; - vertex.v2=1; - - RTS3DScene *pMyScene = (RTS3DScene *)Scene; - if (pMyScene) { - RefRenderObjListIterator *it = pMyScene->createLightsIterator(); - doTheLight(&vertex, lightRay, &normalAtTexel, it, 1.0f); - if (it) { - pMyScene->destroyLightsIterator(it); - it = NULL; - } - } else { - doTheLight(&vertex, lightRay, &normalAtTexel, NULL, 1.0f); - } -#ifdef USE_NORMALS - return(0xffffffff); -#else - return vertex.diffuse; -#endif - -#define not_VERTS_MATCH -#ifdef VERTS_MATCH - Int i,j; - if (m_halfResMesh) { - x&=0xffffffe; - y&=0xffffffe; - } - Real X = x*MAP_XY_FACTOR; - Real Y = y*MAP_XY_FACTOR; - // This code digs the diffuse out of the vertex buffer. - // It makes sense if the road vertexes match the terrain. - // However, they don't match anymore. jba. - - Int yCoordMin = m_map->getDrawOrgY(); - Int yCoordMax = m_y+m_map->getDrawOrgY()-1; - Int xCoordMin = m_map->getDrawOrgX(); - Int xCoordMax = m_x+m_map->getDrawOrgX()-1; - if (x xCoordMax || y>yCoordMax) { - return(0); - } - if (x==xCoordMax) x--; - if (y==yCoordMax) y--; - x -= xCoordMin; - y -= yCoordMin; - - y += m_originY; - if (y<0) y+= m_y-1; - if (y> m_y-1) y-=m_y-1; - if (y<0) y = 0; - if (y>= m_y-1) y=m_y-1; - - x += m_originX; - if (x<0) x+= m_x-1; - if (x> m_x-1) x-=m_x-1; - if (x<0) x = 0; - if (x>= m_x-1) x=m_x-1; - i = 0; - while (x>VERTEX_BUFFER_TILE_LENGTH) { - i++; - x -= VERTEX_BUFFER_TILE_LENGTH; - } - if (x==VERTEX_BUFFER_TILE_LENGTH) x--; - j = 0; - while (y>VERTEX_BUFFER_TILE_LENGTH) { - j++; - y -= VERTEX_BUFFER_TILE_LENGTH; - } - if (y==VERTEX_BUFFER_TILE_LENGTH) y--; - - char **pData = m_vertexBufferBackup+j*m_numVBTilesX+i; - Int vertsPerRow=(VERTEX_BUFFER_TILE_LENGTH)*4; //vertices per row of VB - - if (m_halfResMesh) { - x/=2; - y/=2; - vertsPerRow /= 2; - } - - VERTEX_FORMAT *vbMirror = ((VERTEX_FORMAT*)(*pData)) + (y)*vertsPerRow+4*(x); - if ( vbMirror[0].x==X && vbMirror[0].y==Y) { - return(vbMirror[0].diffuse); - } - if ( vbMirror[3].x==X && vbMirror[3].y==Y) { - return(vbMirror[3].diffuse); - } - if ( vbMirror[1].x==X && vbMirror[1].y==Y) { - return(vbMirror[1].diffuse); - } - if ( vbMirror[2].x==X && vbMirror[2].y==Y) { - return(vbMirror[2].diffuse); - } -#ifdef RTS_DEBUG - char buf[256]; - sprintf(buf, "(%f,%f) -> mirror (%f, %f)\n", X, Y, vbMirror->x, vbMirror->y); - ::OutputDebugString(buf); -#endif - return(vbMirror->diffuse); -#endif -} - -//============================================================================= -// HeightMapRenderObjClass::On_Frame_Update -//============================================================================= -/** Updates the diffuse color values in the vertices as affected by the dynamic lights.*/ -//============================================================================= -void HeightMapRenderObjClass::On_Frame_Update(void) -{ - - Int i,j,k; - DX8VertexBufferClass **pVB; - Int originX,originY; - if (Scene==NULL) return; - RTS3DScene *pMyScene = (RTS3DScene *)Scene; - - - RefRenderObjListIterator pDynamicLightsIterator(pMyScene->getDynamicLights()); - if (m_map == NULL) { - return; - } - -#ifdef DO_UNIT_TIMINGS -#pragma MESSAGE("*** WARNING *** DOING DO_UNIT_TIMINGS!!!!") - return; -#endif - -#ifdef EXTENDED_STATS - if (DX8Wrapper::stats.m_disableTerrain) { - return; - } -#endif - - Int numDynaLights=0; - W3DDynamicLight *enabledLights[MAX_ENABLED_DYNAMIC_LIGHTS]; - - Int yCoordMin = m_map->getDrawOrgY(); - Int yCoordMax = m_y+m_map->getDrawOrgY(); - Int xCoordMin = m_map->getDrawOrgX(); - Int xCoordMax = m_x+m_map->getDrawOrgX(); - - for (pDynamicLightsIterator.First(); !pDynamicLightsIterator.Is_Done(); pDynamicLightsIterator.Next()) - { - W3DDynamicLight *pLight = (W3DDynamicLight*)pDynamicLightsIterator.Peek_Obj(); - pLight->m_processMe = false; - if (pLight->m_enabled || pLight->m_priorEnable) { - Real range = pLight->Get_Attenuation_Range(); - if (pLight->m_priorEnable) { - pLight->m_prevMinX = pLight->m_minX; - pLight->m_prevMinY = pLight->m_minY; - pLight->m_prevMaxX = pLight->m_maxX; - pLight->m_prevMaxY = pLight->m_maxY; - } - Vector3 pos = pLight->Get_Position(); - pLight->m_minX = (pos.X-range)/MAP_XY_FACTOR; - pLight->m_maxX = (pos.X+range)/MAP_XY_FACTOR+1.0f; - pLight->m_minY = (pos.Y-range)/MAP_XY_FACTOR; - pLight->m_maxY = (pos.Y+range)/MAP_XY_FACTOR+1.0f; - if (!pLight->m_priorEnable) { - pLight->m_prevMinX = pLight->m_minX; - pLight->m_prevMinY = pLight->m_minY; - pLight->m_prevMaxX = pLight->m_maxX; - pLight->m_prevMaxY = pLight->m_maxY; - } - - if (pLight->m_minX < xCoordMax && - pLight->m_minY < yCoordMax && - pLight->m_maxX > xCoordMin && - pLight->m_maxY > yCoordMin) { - pLight->m_processMe = TRUE; - } else if (pLight->m_prevMinX < xCoordMax && - pLight->m_prevMinY < yCoordMax && - pLight->m_prevMaxX > xCoordMin && - pLight->m_prevMaxY > yCoordMin) { - pLight->m_processMe = TRUE; - } else { - pLight->m_processMe = false; - } - if (pLight->m_processMe) { - enabledLights[numDynaLights] = pLight; - numDynaLights++; - if (numDynaLights == MAX_ENABLED_DYNAMIC_LIGHTS) { - break; - } - } - } - pLight->m_priorEnable = pLight->m_enabled; - } - if (numDynaLights > 0) { - //step through each vertex buffer that needs updating - for (j=0; jgetDrawOrgY()-m_map->getBorderSize(); - Int yCoordMax = getYWithOrigin(yMax-1)+m_map->getDrawOrgY()+1-m_map->getBorderSize(); - if (yCoordMax>yCoordMin) { - // no wrap occurred. - for (k=0; km_minY < yCoordMax && - enabledLights[k]->m_maxY > yCoordMin) { - intersect = true; - break; - } - if (enabledLights[k]->m_prevMinY < yCoordMax && - enabledLights[k]->m_prevMaxY > yCoordMin) { - intersect = true; - break; - } - } - } else { - // wrap occurred, so we are outside of this range. - int tmp=yCoordMin; - yCoordMin = yCoordMax; - yCoordMax = tmp; - for (k=0; km_minY <= yCoordMin || - enabledLights[k]->m_maxY >= yCoordMax) { - intersect = true; - break; - } - if (enabledLights[k]->m_prevMinY <= yCoordMin || - enabledLights[k]->m_prevMaxY >= yCoordMax) { - intersect = true; - break; - } - } - } - if (!intersect) { - continue; - } - - for (i=0; igetDrawOrgX()-m_map->getBorderSize(); - Int xCoordMax = getXWithOrigin(xMax-1)+m_map->getDrawOrgX()+1-m_map->getBorderSize(); - if (xCoordMax>xCoordMin) { - // no wrap occurred. - for (k=0; km_minX < xCoordMax && - enabledLights[k]->m_maxX > xCoordMin) { - intersect = true; - break; - } - if (enabledLights[k]->m_prevMinX < xCoordMax && - enabledLights[k]->m_prevMaxX > xCoordMin) { - intersect = true; - break; - } - } - } else { - // wrap occurred, so we are outside of this range. - int tmp=xCoordMin; - xCoordMin = xCoordMax; - xCoordMax = tmp; - for (k=0; km_minX <= xCoordMin || - enabledLights[k]->m_maxX >= xCoordMax) { - intersect = true; - break; - } - if (enabledLights[k]->m_prevMinX <= xCoordMin || - enabledLights[k]->m_prevMaxX >= xCoordMax) { - intersect = true; - break; - } - } - } - if (!intersect) { - continue; - } - pVB=m_vertexBufferTiles+j*m_numVBTilesX+i; //point to correct row/column of vertex buffers - char **pData = m_vertexBufferBackup+j*m_numVBTilesX+i; - updateVBForLight(*pVB, *pData, xMin, yMin, xMax, yMax, originX,originY, enabledLights, numDynaLights); - } - } - } -} - -//============================================================================= -// HeightMapRenderObjClass::addTree -//============================================================================= -/** Adds a tree to the tree buffer.*/ -//============================================================================= -void HeightMapRenderObjClass::addTree(Coord3D location, Real scale, Real angle, - AsciiString name, Bool visibleInMirror) -{ - m_treeBuffer->addTree(location, scale, angle, name, visibleInMirror); -}; - -//============================================================================= -// HeightMapRenderObjClass::addTerrainBib -//============================================================================= -/** Adds a terrainBib to the bib buffer.*/ -//============================================================================= -void HeightMapRenderObjClass::addTerrainBib(Vector3 corners[4], - ObjectID id, Bool highlight) -{ - if (m_bibBuffer) - m_bibBuffer->addBib(corners, id, highlight); -}; - -//============================================================================= -// HeightMapRenderObjClass::addTerrainBib -//============================================================================= -/** Adds a terrainBib to the bib buffer.*/ -//============================================================================= -void HeightMapRenderObjClass::addTerrainBibDrawable(Vector3 corners[4], - DrawableID id, Bool highlight) -{ - if (m_bibBuffer) - m_bibBuffer->addBibDrawable(corners, id, highlight); -}; - -//============================================================================= -// HeightMapRenderObjClass::removeAllTerrainBibs -//============================================================================= -/** Removes all terrainBib highlighting from the bib buffer.*/ -//============================================================================= -void HeightMapRenderObjClass::removeTerrainBibHighlighting() -{ - if (m_bibBuffer) - m_bibBuffer->removeHighlighting( ); -}; - -//============================================================================= -// HeightMapRenderObjClass::removeAllTerrainBibs -//============================================================================= -/** Removes all terrainBibs from the bib buffer.*/ -//============================================================================= -void HeightMapRenderObjClass::removeAllTerrainBibs() -{ - if (m_bibBuffer) - m_bibBuffer->clearAllBibs( ); -}; - -//============================================================================= -// HeightMapRenderObjClass::removeTerrainBib -//============================================================================= -/** Removes a terrainBib from the bib buffer.*/ -//============================================================================= -void HeightMapRenderObjClass::removeTerrainBib(ObjectID id) -{ - if (m_bibBuffer) - m_bibBuffer->removeBib( id ); -}; - -//============================================================================= -// HeightMapRenderObjClass::removeTerrainBib -//============================================================================= -/** Removes a terrainBib from the bib buffer.*/ -//============================================================================= -void HeightMapRenderObjClass::removeTerrainBibDrawable(DrawableID id) -{ - if (m_bibBuffer) - m_bibBuffer->removeBibDrawable( id ); -}; - -//============================================================================= -// HeightMapRenderObjClass::staticLightingChanged -//============================================================================= -/** Notification that all lighting needs to be recalculated. */ -//============================================================================= -void HeightMapRenderObjClass::staticLightingChanged( void ) -{ - // Cause the terrain to get updated with new lighting. - m_needFullUpdate = true; - - // Cause the scorches to get updated with new lighting. - m_scorchesInBuffer = 0; // If we just allocated the buffers, we got no scorches in the buffer. - m_curNumScorchVertices=0; - m_curNumScorchIndices=0; - -} - -//============================================================================= -// HeightMapRenderObjClass::setTimeOfDay -//============================================================================= -/** When the time of day changes, the lighting changes and we need to update. */ -//============================================================================= -void HeightMapRenderObjClass::setTimeOfDay( TimeOfDay tod ) -{ - staticLightingChanged(); -} - -//============================================================================= -// HeightMapRenderObjClass::Notify_Added -//============================================================================= -/** W3D render object method, we use it to add ourselves to tthe update -list, so On_Frame_Update gets called. */ -//============================================================================= -void HeightMapRenderObjClass::Notify_Added(SceneClass * scene) -{ - RenderObjClass::Notify_Added(scene); - scene->Register(this,SceneClass::ON_FRAME_UPDATE); -} - - - -#define CENTER_LIMIT 2 -#define BIG_JUMP 16 -#define WIDE_STEP 32 - -static Int visMinX, visMinY, visMaxX, visMaxY; -static Bool check(const FrustumClass & frustum, WorldHeightMap *pMap, Int x, Int y) -{ - if (x<0 || y<0) return(false); - if (x>= pMap->getXExtent() || y>= pMap->getYExtent()) return(false); - if (x >= visMinX && y >= visMinY && x <=visMaxX && y <= visMaxY) { - return(true); - } - Int height = pMap->getHeight(x, y); - Vector3 loc((x-pMap->getBorderSize())*MAP_XY_FACTOR, (y-pMap->getBorderSize())*MAP_XY_FACTOR, height*MAP_HEIGHT_SCALE); - if (CollisionMath::Overlap_Test(frustum,loc) == CollisionMath::INSIDE) { - if (xvisMaxX) visMaxX=x; - if (yvisMaxY) visMaxY=y; - return(true); - } - return(false); -} - -static void calcVis(const FrustumClass & frustum, WorldHeightMap *pMap, Int minX, Int minY, Int maxX, Int maxY, Int limit) -{ - if (maxX-minX<2) return; - if (maxY-minY<2) return; - if (minX >=visMinX && minY >= visMinY && maxX <=visMaxX && maxY <= visMaxY) { - return; - } - Int midX = (minX+maxX)/2; - Int midY = (minY+maxY)/2; - Bool recurse1 = maxX-minX>=limit; - Bool recurse2 = recurse1; - Bool recurse3 = recurse1; - Bool recurse4 = recurse1; - /* boxes are: - - 1 2 - - - 3 4 */ - - if (check(frustum, pMap, midX, maxY)) { - recurse1=true; - recurse2=true; - } - if (check(frustum, pMap, midX, minY)) { - recurse3=true; - recurse4=true; - } - if (check(frustum, pMap, midX, midY)) { - recurse1=true; - recurse2=true; - recurse3=true; - recurse4=true; - } - if (check(frustum, pMap, minX, midY)) { - recurse1=true; - recurse3=true; - } - if (check(frustum, pMap, maxX, midY)) { - recurse2=true; - recurse4=true; - } - if (recurse1) { - calcVis(frustum, pMap, minX, midY, midX, maxY, limit); - } - if (recurse2) { - calcVis(frustum, pMap, midX, midY, maxX, maxY, limit); - } - if (recurse3) { - calcVis(frustum, pMap, minX, minY, midX, midY, limit); - } - if (recurse4) { - calcVis(frustum, pMap, midX, minY, maxX, midY, limit); - } -} - - -//============================================================================= -// HeightMapRenderObjClass::updateCenter -//============================================================================= -/** Updates the positioning of the drawn portion of the height map in the -heightmap. As the view slides around, this determines what is the actually -rendered portion of the terrain. Only a 96x96 section is rendered at any time, -even though maps can be up to 1024x1024. This function determines which subset -is rendered. */ -//============================================================================= -void HeightMapRenderObjClass::updateCenter(CameraClass *camera , RefRenderObjListIterator *pLightsIterator) -{ - if (m_map==NULL) { - return; - } - if (m_updating) { - return; - } - - if (m_vertexBufferTiles ==NULL) - return; //did not initialize resources yet. - - m_treeBuffer->doFullUpdate(); // Tell the trees to update for view change. - -#ifdef TEST_CUSTOM_EDGING - m_customEdging->doFullUpdate(); -#endif - - m_updating = true; - if (m_needFullUpdate) { - m_needFullUpdate = false; - updateBlock(0, 0, m_x-1, m_y-1, m_map, pLightsIterator); -#ifdef DO_ROADS - if (m_roadBuffer) { - m_roadBuffer->updateLighting(); - } -#endif - m_bridgeBuffer->doFullUpdate(); - m_bridgeBuffer->updateCenter(camera, pLightsIterator); - m_updating = false; - return; - } - m_bridgeBuffer->updateCenter(camera, pLightsIterator); - - if (m_x >= m_map->getXExtent() && m_y >= m_map->getYExtent()) { - m_updating = false; - return; // no need to center. - } - - Int cellOffset = 1; - if (m_halfResMesh) { - cellOffset = 2; - } - // determine the ray corresponding to the camera and distance to projection plane - Matrix3D camera_matrix = camera->Get_Transform(); - - Vector3 camera_location = camera->Get_Position(); - - Vector3 rayLocation; - Vector3 rayDirection; - Vector3 rayDirectionPt; - // the projected ray has the same origin as the camera - rayLocation = camera_location; - // determine the location of the screen coordinate in camera-model space - const ViewportClass &viewport = camera->Get_Viewport(); - Int i, j, minHt; - - Real intersectionZ; - minHt = m_map->getMaxHeightValue(); - for (i=0; igetDisplayHeight(i,j); - if (curGet_Aspect_Ratio(); - - Vector2 min,max; - camera->Get_View_Plane(min,max); - float xscale = (max.X - min.X); - float yscale = (max.Y - min.Y); - - float zmod = -1.0; // Scene->vpd; // Note: view plane distance is now always 1.0 from the camera - float minX = 200000; - float maxX = -minX; - float minY = 200000; - float maxY = -minY; - for (i=0; i<2; i++) { - for (j=0; j<2; j++) { - float xmod = (-i + 0.5 + viewport.Min.X) * zmod * xscale;// / aspect; - float ymod = (j - 0.5 - viewport.Min.Y) * zmod * yscale;// * aspect; - - // transform the screen coordinates by the camera's matrix into world coordinates. - float x = zmod * camera_matrix[0][2] + xmod * camera_matrix[0][0] + ymod * camera_matrix[0][1]; - float y = zmod * camera_matrix[1][2] + xmod * camera_matrix[1][0] + ymod * camera_matrix[1][1]; - float z = zmod * camera_matrix[2][2] + xmod * camera_matrix[2][0] + ymod * camera_matrix[2][1]; - - rayDirection.Set(x,y,z); - rayDirection.Normalize(); - rayDirectionPt = rayLocation+rayDirection; - - x = Vector3::Find_X_At_Z(intersectionZ, rayLocation, rayDirectionPt); - y = Vector3::Find_Y_At_Z(intersectionZ, rayLocation, rayDirectionPt); - if (xmaxX) maxX = x; - if (ymaxY) maxY = y; - } - } - - // convert back to cell indexes. - minX /= MAP_XY_FACTOR; - maxX /= MAP_XY_FACTOR; - minY /= MAP_XY_FACTOR; - maxY /= MAP_XY_FACTOR; - - minX += m_map->getBorderSize(); - maxX += m_map->getBorderSize(); - minY += m_map->getBorderSize(); - maxY += m_map->getBorderSize(); - - visMinX = m_map->getXExtent(); - visMinY = m_map->getYExtent(); - visMaxX = 0; - visMaxY = 0; - - ///< @todo find out why values go out of range - if (minX<0) minX=0; - if (minY<0) minY=0; - if (maxX > visMinX) maxX = visMinX; - if (maxY > visMinY) maxY = visMinY; - - const FrustumClass & frustum = camera->Get_Frustum(); - Int limit = (maxX-minX)/2; - if (limit > WIDE_STEP/2) { - limit=WIDE_STEP/2; - } - calcVis(frustum, m_map, minX-WIDE_STEP/2, minY-WIDE_STEP/2, maxX+WIDE_STEP/2, maxY+WIDE_STEP/2, limit); - - if (m_map) { - Int newOrgX; - if (visMaxX-visMinX > m_x) { - newOrgX = (maxX+minX)/2-m_x/2.0; - } else { - newOrgX = (visMaxX+visMinX)/2-m_x/2.0; - } - - Int newOrgY; - if (visMaxY - visMinY > m_y) { - newOrgY = visMinY+1; - } else { - newOrgY = (visMaxY+visMinY)/2-m_y/2.0; - } - if (TheTacticalView->getFieldOfView() != 0) { - newOrgX = (visMaxX+visMinX)/2-m_x/2.0; - newOrgY = (visMaxY+visMinY)/2-m_y/2.0; - } - if (m_halfResMesh) { - newOrgX &= 0xFFFFFFFE; - newOrgY &= 0xFFFFFFFE; - } - Int deltaX = newOrgX - m_map->getDrawOrgX(); - Int deltaY = newOrgY - m_map->getDrawOrgY(); - if (IABS(deltaX) > m_x/2 || IABS(deltaY)>m_x/2) { - m_map->setDrawOrg(newOrgX, newOrgY); - m_originY = 0; - m_originX = 0; - updateBlock(0, 0, m_x-1, m_y-1, m_map, pLightsIterator); - m_updating = false; - return; - } - - if (abs(deltaX)>CENTER_LIMIT || abs(deltaY)>CENTER_LIMIT) { - if (abs(deltaY) >= CENTER_LIMIT) { - if (m_map->setDrawOrg(m_map->getDrawOrgX(), newOrgY)) { - Int minY = 0; - Int maxY = 0; - deltaY -= newOrgY - m_map->getDrawOrgY(); - m_originY += deltaY; - if (m_originY >= m_y-1) m_originY -= m_y-1; - if (deltaY<0) { - minY = m_originY; - maxY = m_originY-deltaY; - } else { - minY = m_originY - deltaY; - maxY = m_originY; - } - minY-=cellOffset; - if (m_originY < 0) m_originY += m_y-1; - if (minY<0) { - minY += m_y-1; - if (minY<0) minY = 0; - updateBlock(0, minY, m_x-1, m_y-1, m_map, pLightsIterator); - updateBlock(0, 0, m_x-1, maxY, m_map, pLightsIterator); - } else { - updateBlock(0, minY, m_x-1, maxY, m_map, pLightsIterator); - } - } - // It is much more efficient to update a cople of columns one frame, and then - // a couple of rows. So if we aren't "jumping" to a new view, and have done X - // recently, return. - if (abs(deltaX) < BIG_JUMP && !m_doXNextTime) { - m_updating = false; - m_doXNextTime = true; - return; // Only do the y this frame. Do x next frame. jba. - } - } - if (abs(deltaX) > CENTER_LIMIT) { - m_doXNextTime = false; - newOrgX = m_map->getDrawOrgX() + deltaX; - if (m_map->setDrawOrg(newOrgX, m_map->getDrawOrgY())) { - Int minX = 0; - Int maxX = 0; - deltaX -= newOrgX - m_map->getDrawOrgX(); - m_originX += deltaX; - if (m_originX >= m_x-1) m_originX -= m_x-1; - if (deltaX<0) { - minX = m_originX; - maxX = m_originX-deltaX; - } else { - minX = m_originX - deltaX; - maxX = m_originX; - } - minX-=cellOffset; - maxX+=cellOffset; - if (m_originX < 0) m_originX += m_x-1; - if (minX<0) { - minX += m_x-1; - if (minX<0) minX = 0; - updateBlock(minX,0,m_x-1, m_y-1, m_map, pLightsIterator); - updateBlock(0,0,maxX, m_y-1, m_map, pLightsIterator); - } else { - updateBlock(minX,0,maxX, m_y-1, m_map, pLightsIterator); - } - } - } - } - } - m_updating = false; -} - -//============================================================================= -// HeightMapRenderObjClass::Render -//============================================================================= -/** Renders (draws) the terrain. */ -//============================================================================= -//DECLARE_PERF_TIMER(Terrain_Render) - -void HeightMapRenderObjClass::Render(RenderInfoClass & rinfo) -{ - //USE_PERF_TIMER(Terrain_Render) - - Int i,j,devicePasses; - W3DShaderManager::ShaderTypes st; - const Bool doCloud = useCloud(); - - if (doCloud) - { - // TheSuperHackers @tweak Updates the cloud movement before applying it to the world. - // Is now decoupled from logic step. - W3DShaderManager::updateCloud(); - } - - Matrix3D tm(Transform); -#if 0 // There is some weirdness sometimes with the dx8 static buffers. - // This usually fixes terrain flashing. jba. - static Int delay = 1; - delay --; - if (delay<1) { - delay = 1; - static Int ndx = -1; - ndx++; - if (ndx>=m_numVertexBufferTiles) { - ndx = 0; - } - DX8VertexBufferClass::WriteLockClass lockVtxBuffer(m_vertexBufferTiles[ndx]); - VERTEX_FORMAT *vb = (VERTEX_FORMAT*)lockVtxBuffer.Get_Vertex_Array(); - vb = 0; - } -#endif - // If there are trees, tell them to draw at the transparent time to draw. - if (m_treeBuffer) { - m_treeBuffer->setIsTerrain(); - } - - -#ifdef DO_UNIT_TIMINGS -#pragma MESSAGE("*** WARNING *** DOING DO_UNIT_TIMINGS!!!!") - return; -#endif - -#ifdef EXTENDED_STATS - if (DX8Wrapper::stats.m_disableTerrain) { - return; - } -#endif - - DX8Wrapper::Set_Light_Environment(rinfo.light_environment); - - // Force shaders to update. - m_stageTwoTexture->restore(); - DX8Wrapper::Set_Texture(0,NULL); - DX8Wrapper::Set_Texture(1,NULL); - ShaderClass::Invalidate(); - - // tm.Scale(ObjSpaceExtent); - DX8Wrapper::Set_Transform(D3DTS_WORLD,tm); - - //Apply the shader and material - - DX8Wrapper::Set_Index_Buffer(m_indexBuffer,0); - - Bool doMultiPassWireFrame=FALSE; - - if (((RTS3DScene *)rinfo.Camera.Get_User_Data())->getCustomPassMode() == SCENE_PASS_ALPHA_MASK || - ((SceneClass *)rinfo.Camera.Get_User_Data())->Get_Extra_Pass_Polygon_Mode() == SceneClass::EXTRA_PASS_CLEAR_LINE) - { - if (WW3D::Is_Texturing_Enabled()) - { //first pass where we just fill the z-buffer - - devicePasses=1; //one pass solid, next in wireframe. - doMultiPassWireFrame=TRUE; - - if (rinfo.Additional_Pass_Count()) - { - rinfo.Peek_Additional_Pass(0)->Install_Materials(); - renderTerrainPass(&rinfo.Camera); - rinfo.Peek_Additional_Pass(0)->UnInstall_Materials(); - return; - } - } - else - { //wireframe pass - //Set to vertex diffuse lighting - DX8Wrapper::Set_Material(m_vertexMaterialClass); - //Set shader to non-textured solid color from vertex - DX8Wrapper::Set_Shader(ShaderClass::_PresetOpaqueSolidShader); - devicePasses=1; //one pass solid, next in wireframe. - DX8Wrapper::Apply_Render_State_Changes(); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG2, D3DTA_TFACTOR ); - DX8Wrapper::Set_DX8_Render_State(D3DRS_TEXTUREFACTOR,0xff808080); - doMultiPassWireFrame=TRUE; - renderTerrainPass(&rinfo.Camera); - DX8Wrapper::Set_DX8_Render_State(D3DRS_TEXTUREFACTOR,0xff008000); - return; - } - } - else - { - DX8Wrapper::Set_Material(m_vertexMaterialClass); - DX8Wrapper::Set_Shader(m_shaderClass); - - st=W3DShaderManager::ST_TERRAIN_BASE; //set default shader - - //set correct shader based on current settings - if (!ShaderClass::Is_Backface_Culling_Inverted()) - { //not reflection pass - if (TheGlobalData->m_useLightMap && doCloud) - { st=W3DShaderManager::ST_TERRAIN_BASE_NOISE12; - } - else - if (TheGlobalData->m_useLightMap) - { //lightmap only - st=W3DShaderManager::ST_TERRAIN_BASE_NOISE2; - } - else - if (doCloud) - { //cloudmap only - st=W3DShaderManager::ST_TERRAIN_BASE_NOISE1; - } - } - else - { //reflection pass, just do base texture - st=W3DShaderManager::ST_TERRAIN_BASE; - } - - //Find number of passes required to render current shader - devicePasses=W3DShaderManager::getShaderPasses(st); - - if (m_disableTextures) - devicePasses=1; //force to 1 lighting-only pass - - //Specify all textures that this shader may need. - W3DShaderManager::setTexture(0,m_stageZeroTexture); - W3DShaderManager::setTexture(1,m_stageZeroTexture); - W3DShaderManager::setTexture(2,m_stageTwoTexture); //cloud - W3DShaderManager::setTexture(3,m_stageThreeTexture);//noise - //Disable writes to destination alpha channel (if there is one) - if (DX8Wrapper::getBackBufferFormat() == WW3D_FORMAT_A8R8G8B8) - DX8Wrapper::Set_DX8_Render_State(D3DRS_COLORWRITEENABLE,D3DCOLORWRITEENABLE_BLUE|D3DCOLORWRITEENABLE_GREEN|D3DCOLORWRITEENABLE_RED); - } - - Int pass; - for (pass=0; passProcessVertices(0, 0, numVertex, m_xformedVertexBuffer[j*m_numVBTilesX+i], 0); - ::OutputDebugString("did process vertex\n"); - } - if (m_xformedVertexBuffer) { - // Note - m_xformedVertexBuffer should only be used for non T&L hardware. jba. - DX8Wrapper::Apply_Render_State_Changes(); - DX8Wrapper::_Get_D3D_Device8()->SetStreamSource( - 0, - m_xformedVertexBuffer[j*m_numVBTilesX+i], - D3DXGetFVFVertexSize(D3DFVF_XYZRHW |D3DFVF_DIFFUSE|D3DFVF_TEX2)); - DX8Wrapper::_Get_D3D_Device8()->SetVertexShader(D3DFVF_XYZRHW |D3DFVF_DIFFUSE|D3DFVF_TEX2); - } -#endif - if (Is_Hidden() == 0) { - DX8Wrapper::Draw_Triangles( 0,numPolys, 0, numVertex); - } - - } - } - - if (!doMultiPassWireFrame) - { - if (pass) //shader was applied at least once? - W3DShaderManager::resetShader(st); - - //Draw feathered shorelines - renderShoreLines(&rinfo.Camera); - - //Do additional pass over any tiles that have 3 textures blended together. - if (TheGlobalData->m_use3WayTerrainBlends) - renderExtraBlendTiles(); - - #ifdef TEST_CUSTOM_EDGING - // Draw edging just before last pass. - DX8Wrapper::Set_Texture(0,NULL); - DX8Wrapper::Set_Texture(1,NULL); - m_stageTwoTexture->restore(); - Int yCoordMin = m_map->getDrawOrgY(); - Int yCoordMax = m_y+m_map->getDrawOrgY()-1; - Int xCoordMin = m_map->getDrawOrgX(); - Int xCoordMax = m_x+m_map->getDrawOrgX()-1; - m_customEdging->drawEdging(m_map, xCoordMin, xCoordMax, yCoordMin, yCoordMax, - m_stageZeroTexture, doCloud?m_stageTwoTexture:NULL, TheGlobalData->m_useLightMap?m_stageThreeTexture:NULL); - #endif - #ifdef DO_ROADS - DX8Wrapper::Set_Texture(0,NULL); - DX8Wrapper::Set_Texture(1,NULL); - m_stageTwoTexture->restore(); - - ShaderClass::Invalidate(); - if (!ShaderClass::Is_Backface_Culling_Inverted()) { - DX8Wrapper::Set_Material(m_vertexMaterialClass); - if (Scene) { - RTS3DScene *pMyScene = (RTS3DScene *)Scene; - RefRenderObjListIterator pDynamicLightsIterator(pMyScene->getDynamicLights()); - m_roadBuffer->drawRoads(&rinfo.Camera, doCloud?m_stageTwoTexture:NULL, TheGlobalData->m_useLightMap?m_stageThreeTexture:NULL, - m_disableTextures,xCoordMin-m_map->getBorderSize(), xCoordMax-m_map->getBorderSize(), yCoordMin-m_map->getBorderSize(), yCoordMax-m_map->getBorderSize(), &pDynamicLightsIterator); - } - } - #endif - - #ifdef DO_SCORCH - DX8Wrapper::Set_Texture(0,NULL); - DX8Wrapper::Set_Texture(1,NULL); - m_stageTwoTexture->restore(); - - ShaderClass::Invalidate(); - if (!ShaderClass::Is_Backface_Culling_Inverted()) { - drawScorches(); - } - #endif - DX8Wrapper::Set_Texture(0,NULL); - DX8Wrapper::Set_Texture(1,NULL); - m_stageTwoTexture->restore(); - ShaderClass::Invalidate(); - DX8Wrapper::Apply_Render_State_Changes(); - - m_bridgeBuffer->drawBridges(&rinfo.Camera, m_disableTextures, m_stageTwoTexture); - - if (TheTerrainTracksRenderObjClassSystem) - TheTerrainTracksRenderObjClassSystem->flush(); - - if (m_shroud && rinfo.Additional_Pass_Count()) - { - rinfo.Peek_Additional_Pass(0)->Install_Materials(); - renderTerrainPass(&rinfo.Camera); - rinfo.Peek_Additional_Pass(0)->UnInstall_Materials(); - } - - ShaderClass::Invalidate(); - DX8Wrapper::Apply_Render_State_Changes(); - } - else - m_bridgeBuffer->drawBridges(&rinfo.Camera, m_disableTextures, m_stageTwoTexture); - - m_waypointBuffer->drawWaypoints(rinfo); - - m_bibBuffer->renderBibs(); - - // We do some custom blending, so tell the shader class to reset everything. - DX8Wrapper::Set_Texture(0,NULL); - DX8Wrapper::Set_Texture(1,NULL); - m_stageTwoTexture->restore(); - ShaderClass::Invalidate(); - DX8Wrapper::Set_Material(NULL); - -} - -/**Render parts of terrain that are along the coast line and have vertices directly under the -water plane. Applying a custom render to these polygons allows for a smoother land->water -transition*/ -void HeightMapRenderObjClass::renderShoreLines(CameraClass *pCamera) -{ - if (!TheGlobalData->m_showSoftWaterEdge || TheWaterTransparency->m_transparentWaterDepth==0 || m_numShoreLineTiles == 0) - return; - - //Check if video card is capable of using this effect - if (DX8Wrapper::getBackBufferFormat() != WW3D_FORMAT_A8R8G8B8) - return; //can't apply effect on cards without destination alpha - - Int vertexCount = 0; - Int indexCount = 0; - Int xExtent = m_map->getXExtent(); - Int border = m_map->getBorderSize(); - Int drawEdgeY=m_map->getDrawOrgY()+m_map->getDrawHeight()-1; - Int drawEdgeX=m_map->getDrawOrgX()+m_map->getDrawWidth()-1; - if (drawEdgeX > (m_map->getXExtent()-1)) - drawEdgeX = m_map->getXExtent()-1; - if (drawEdgeY > (m_map->getYExtent()-1)) - drawEdgeY = m_map->getYExtent()-1; - Int drawStartX=m_map->getDrawOrgX(); - Int drawStartY=m_map->getDrawOrgY(); - const UnsignedByte* data = m_map->getDataPtr(); - Int j=0; - - ShaderClass unlitShader=ShaderClass::_PresetOpaque2DShader; - unlitShader.Set_Depth_Compare(ShaderClass::PASS_LEQUAL); - DX8Wrapper::Set_Shader(unlitShader); - VertexMaterialClass *vmat=VertexMaterialClass::Get_Preset(VertexMaterialClass::PRELIT_DIFFUSE); - DX8Wrapper::Set_Material(vmat); - REF_PTR_RELEASE(vmat); - DX8Wrapper::Set_Texture(0,m_destAlphaTexture); - DX8Wrapper::Set_Transform(D3DTS_WORLD,Matrix3D(1)); - //Enabled writes to destination alpha only - DX8Wrapper::Set_DX8_Render_State(D3DRS_COLORWRITEENABLE,D3DCOLORWRITEENABLE_ALPHA); - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_TEXCOORDINDEX, 0); - - while (j != m_numShoreLineTiles) - { - { //Need to put this in another code block so vb/ib gets automatically locked/unlocked by destructors - DynamicVBAccessClass vb_access(BUFFER_TYPE_DYNAMIC_DX8,dynamic_fvf_type,DEFAULT_MAX_BATCH_SHORELINE_TILES*4); - DynamicIBAccessClass ib_access(BUFFER_TYPE_DYNAMIC_DX8,DEFAULT_MAX_BATCH_SHORELINE_TILES*6); - - DynamicVBAccessClass::WriteLockClass lock(&vb_access); - VertexFormatXYZNDUV2 *vb= lock.Get_Formatted_Vertex_Array(); - DynamicIBAccessClass::WriteLockClass lockib(&ib_access); - UnsignedShort *ib=lockib.Get_Index_Array(); - if (!ib || !vb) - { DX8Wrapper::Set_DX8_Render_State(D3DRS_COLORWRITEENABLE,D3DCOLORWRITEENABLE_BLUE|D3DCOLORWRITEENABLE_GREEN|D3DCOLORWRITEENABLE_RED); - return; - } - - //Loop over visible terrain and extract all the tiles that need shoreline blend - for (; j= (DEFAULT_MAX_BATCH_SHORELINE_TILES*4)) - break; //no room in vertex buffer - - shoreLineTileInfo *shoreInfo=&m_shoreLineTilePositions[j]; - - Int x = shoreInfo->m_xy & 0xffff; - Int y = shoreInfo->m_xy >> 16; - - if (x >= drawStartX && x < drawEdgeX && y >= drawStartY && y < drawEdgeY) - { //this tile is inside visible region - - Int idx = x+y*xExtent; - - Real p0=data[idx]*MAP_HEIGHT_SCALE; - Real p1=data[idx+1]*MAP_HEIGHT_SCALE; - Real p2=data[idx + 1 + xExtent]*MAP_HEIGHT_SCALE; - Real p3=data[idx + xExtent]*MAP_HEIGHT_SCALE; - - vb->x=(x-border)*MAP_XY_FACTOR; - vb->y=(y-border)*MAP_XY_FACTOR; - vb->z=p0; - vb->u1=shoreInfo->t0; - vb->v1=0; - vb++; - - vb->x=(x+1-border)*MAP_XY_FACTOR; - vb->y=(y-border)*MAP_XY_FACTOR; - vb->z=p1; - vb->u1=shoreInfo->t1; - vb->v1=0; - vb++; - - vb->x=(x+1-border)*MAP_XY_FACTOR; - vb->y=(y+1-border)*MAP_XY_FACTOR; - vb->z=p2; - vb->u1=shoreInfo->t2; - vb->v1=0; - vb++; - - vb->x=(x-border)*MAP_XY_FACTOR; - vb->y=(y+1-border)*MAP_XY_FACTOR; - vb->z=p3; - vb->u1=shoreInfo->t3; - vb->v1=0; - vb++; - - if (m_map->getFlipState(x,y)) - { - ib[0]=1+vertexCount; - ib[1]=3+vertexCount; - ib[2]=0+vertexCount; - ib[3]=1+vertexCount; - ib[4]=2+vertexCount; - ib[5]=3+vertexCount; - } - else - { - ib[0]=0+vertexCount; - ib[1]=2+vertexCount; - ib[2]=3+vertexCount; - ib[3]=0+vertexCount; - ib[4]=1+vertexCount; - ib[5]=2+vertexCount; - } - ib += 6; - vertexCount +=4; - indexCount +=6; - } - } - - DX8Wrapper::Set_Index_Buffer(ib_access,0); - DX8Wrapper::Set_Vertex_Buffer(vb_access); - } - - if (indexCount > 0 && vertexCount > 0) - DX8Wrapper::Draw_Triangles( 0,indexCount/3, 0, vertexCount); //draw a quad, 2 triangles, 4 verts - vertexCount=0; - indexCount=0; - } - - //Disable writes to destination alpha - DX8Wrapper::Set_DX8_Render_State(D3DRS_COLORWRITEENABLE,D3DCOLORWRITEENABLE_BLUE|D3DCOLORWRITEENABLE_GREEN|D3DCOLORWRITEENABLE_RED); - ShaderClass::Invalidate(); -} - -///Performs additional terrain rendering pass, blending in the black shroud texture. -void HeightMapRenderObjClass::renderTerrainPass(CameraClass *pCamera) -{ - DX8Wrapper::Set_Transform(D3DTS_WORLD,Matrix3D(1)); - - //Apply the shader and material - - DX8Wrapper::Set_Index_Buffer(m_indexBuffer,0); - - for (Int j=0; jProcessVertices(0, 0, numVertex, m_xformedVertexBuffer[j*m_numVBTilesX+i], 0); - ::OutputDebugString("did process vertex\n"); - } - if (m_xformedVertexBuffer) { - // Note - m_xformedVertexBuffer should only be used for non T&L hardware. jba. - DX8Wrapper::Apply_Render_State_Changes(); - DX8Wrapper::_Get_D3D_Device8()->SetStreamSource( - 0, - m_xformedVertexBuffer[j*m_numVBTilesX+i], - D3DXGetFVFVertexSize(D3DFVF_XYZRHW |D3DFVF_DIFFUSE|D3DFVF_TEX2)); - DX8Wrapper::_Get_D3D_Device8()->SetVertexShader(D3DFVF_XYZRHW |D3DFVF_DIFFUSE|D3DFVF_TEX2); - } -#endif - if (Is_Hidden() == 0) { - DX8Wrapper::Draw_Triangles( 0,numPolys, 0, numVertex); - } - } -} - -//============================================================================= -// HeightMapRenderObjClass::renderTrees -//============================================================================= -/** Renders (draws) the trees. Since the trees are transparent, this has to be -called after flush. */ -//============================================================================= -void HeightMapRenderObjClass::renderTrees(CameraClass * camera) -{ -#ifdef EXTENDED_STATS - if (DX8Wrapper::stats.m_disableObjects) { - return; - } -#endif - if (m_map==NULL) return; - if (Scene==NULL) return; - if (m_treeBuffer) { - Matrix3D tm(Transform); - DX8Wrapper::Set_Transform(D3DTS_WORLD,tm); - DX8Wrapper::Set_Material(m_vertexMaterialClass); - RTS3DScene *pMyScene = (RTS3DScene *)Scene; - RefRenderObjListIterator pDynamicLightsIterator(pMyScene->getDynamicLights()); - m_treeBuffer->drawTrees(camera, &pDynamicLightsIterator); - } -} - -/** Renders an additoinal terrain pass including only those tiles which have more than 2 textures -blended together. Used primarily for corner cases where 3 different textures meet.*/ -void HeightMapRenderObjClass::renderExtraBlendTiles(void) -{ - Int vertexCount = 0; - Int indexCount = 0; - Int xExtent = m_map->getXExtent(); - Int border = m_map->getBorderSize(); - static Int maxBlendTiles = DEFAULT_MAX_FRAME_EXTRABLEND_TILES; - - if (!m_numExtraBlendTiles) - return; //nothing to draw - - if (maxBlendTiles > 10000) //we can only fit about 10000 tiles into a single VB. - maxBlendTiles = 10000; - - DynamicVBAccessClass vb_access(BUFFER_TYPE_DYNAMIC_DX8,DX8_FVF_XYZNDUV2,maxBlendTiles*4); - DynamicIBAccessClass ib_access(BUFFER_TYPE_DYNAMIC_DX8,maxBlendTiles*6); - { - - DynamicVBAccessClass::WriteLockClass lock(&vb_access); - VertexFormatXYZNDUV2* vb= lock.Get_Formatted_Vertex_Array(); - DynamicIBAccessClass::WriteLockClass lockib(&ib_access); - UnsignedShort *ib=lockib.Get_Index_Array(); - - if (!vb || !ib) return; - - const UnsignedByte* data = m_map->getDataPtr(); - - //Loop over visible terrain and extract all the tiles that need extra blend - Int drawEdgeY=m_map->getDrawOrgY()+m_map->getDrawHeight()-1; - Int drawEdgeX=m_map->getDrawOrgX()+m_map->getDrawWidth()-1; - if (drawEdgeX > (m_map->getXExtent()-1)) - drawEdgeX = m_map->getXExtent()-1; - if (drawEdgeY > (m_map->getYExtent()-1)) - drawEdgeY = m_map->getYExtent()-1; - Int drawStartX=m_map->getDrawOrgX(); - Int drawStartY=m_map->getDrawOrgY(); - - for (Int j=0; j= (maxBlendTiles*4)) - break; //no room in vertex buffer - - Real U[4],V[4]; - UnsignedByte alpha[4]; - Bool flipState,cliffState; - Int x = m_extraBlendTilePositions[j] & 0xffff; - Int y = m_extraBlendTilePositions[j] >> 16; - - if (x >= drawStartX && x < drawEdgeX && - y >= drawStartY && y < drawEdgeY && - m_map->getExtraAlphaUVData(x,y,U,V,alpha,&flipState, &cliffState)) - { //this tile is inside visible region and has 3rd blend layer. - - Int idx = x+y*xExtent; - - Real p0=data[idx]*MAP_HEIGHT_SCALE; - Real p1=data[idx+1]*MAP_HEIGHT_SCALE; - Real p2=data[idx + 1 + xExtent]*MAP_HEIGHT_SCALE; - Real p3=data[idx + xExtent]*MAP_HEIGHT_SCALE; - if (cliffState && abs(p0-p2) > abs(p1-p3)) //cliffs sometimes force a flip - flipState = TRUE; - - vb->x=(x-border)*MAP_XY_FACTOR; - vb->y=(y-border)*MAP_XY_FACTOR; - vb->z=p0; - vb->diffuse=(alpha[0]<<24)|(getStaticDiffuse(x,y) & 0x00ffffff); - vb->u1=U[0]; - vb->v1=V[0]; - vb++; - - vb->x=(x+1-border)*MAP_XY_FACTOR; - vb->y=(y-border)*MAP_XY_FACTOR; - vb->z=p1; - vb->diffuse=(alpha[1]<<24)|(getStaticDiffuse(x+1,y) & 0x00ffffff); - vb->u1=U[1]; - vb->v1=V[1]; - vb++; - - vb->x=(x+1-border)*MAP_XY_FACTOR; - vb->y=(y+1-border)*MAP_XY_FACTOR; - vb->z=p2; - vb->diffuse=(alpha[2]<<24)|(getStaticDiffuse(x+1,y+1) & 0x00ffffff); - vb->u1=U[2]; - vb->v1=V[2]; - vb++; - - vb->x=(x-border)*MAP_XY_FACTOR; - vb->y=(y+1-border)*MAP_XY_FACTOR; - vb->z=p3; - vb->diffuse=(alpha[3]<<24)|(getStaticDiffuse(x,y+1) & 0x00ffffff); - vb->u1=U[3]; - vb->v1=V[3]; - vb++; - - if (flipState) - { - ib[0]=1+vertexCount; - ib[1]=3+vertexCount; - ib[2]=0+vertexCount; - ib[3]=1+vertexCount; - ib[4]=2+vertexCount; - ib[5]=3+vertexCount; - } - else - { - ib[0]=0+vertexCount; - ib[1]=2+vertexCount; - ib[2]=3+vertexCount; - ib[3]=0+vertexCount; - ib[4]=1+vertexCount; - ib[5]=2+vertexCount; - } - ib += 6; - vertexCount +=4; - indexCount +=6; - } - } - } - - if (vertexCount) - { - //Check if we couldn't fit all blend tiles into vertex buffer so we can enlarge it for next frame. - if (vertexCount == (maxBlendTiles*4)) - maxBlendTiles += 16; //enlarge by 16 to reduce trashing. - - ShaderClass::Invalidate(); //invalidate to force shader to reset since we directly changed states - DX8Wrapper::Set_Index_Buffer(ib_access,0); - DX8Wrapper::Set_Vertex_Buffer(vb_access); - VertexMaterialClass *vmat=VertexMaterialClass::Get_Preset(VertexMaterialClass::PRELIT_DIFFUSE); - DX8Wrapper::Set_Material(vmat); - REF_PTR_RELEASE(vmat); - ShaderClass shader=ShaderClass::_PresetOpaqueShader; - shader.Set_Depth_Mask(ShaderClass::DEPTH_WRITE_DISABLE); //disable writes to z - DX8Wrapper::Set_Shader(shader); - - if (TheGlobalData->m_use3WayTerrainBlends == 2) - { - shader.Set_Primary_Gradient(ShaderClass::GRADIENT_DISABLE); //disable lighting. - shader.Set_Texturing(ShaderClass::TEXTURING_DISABLE); //disable texturing. - DX8Wrapper::Set_Shader(shader); - DX8Wrapper::Set_Texture(0,NULL); //debug mode which draws terrain tiles in white. - if (Is_Hidden() == 0) { - DX8Wrapper::Draw_Triangles( 0,indexCount/3, 0, vertexCount); //draw a quad, 2 triangles, 4 verts - } - } - else - { - W3DShaderManager::setTexture(0,m_stageOneTexture); - W3DShaderManager::setTexture(1,m_stageTwoTexture); //cloud - W3DShaderManager::setTexture(2,m_stageThreeTexture); //noise/lightmap - - W3DShaderManager::ShaderTypes st = W3DShaderManager::ST_ROAD_BASE; - - const Bool doCloud = useCloud(); - - if (TheGlobalData->m_useLightMap && doCloud) - { - st = W3DShaderManager::ST_ROAD_BASE_NOISE12; - } - else if (TheGlobalData->m_useLightMap) - { //lightmap only - st = W3DShaderManager::ST_ROAD_BASE_NOISE2; - } - else if (doCloud) - { //cloudmap only - st = W3DShaderManager::ST_ROAD_BASE_NOISE1; - } - - Int devicePasses=W3DShaderManager::getShaderPasses(st); - - for (Int pass=0; pass < devicePasses; pass++) - { - W3DShaderManager::setShader(st, pass); - //Draw all this road type. - if (Is_Hidden() == 0) { - DX8Wrapper::Draw_Triangles( 0,indexCount/3, 0, vertexCount); //draw a quad, 2 triangles, 4 verts - } - } - W3DShaderManager::resetShader(st); - } - } -} - -//============================================================================= -Bool HeightMapRenderObjClass::useCloud() -{ - return TheGlobalData->m_useCloudMap && TheGlobalData->m_timeOfDay != TIME_OF_DAY_NIGHT; -} diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/TerrainTex.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/TerrainTex.cpp deleted file mode 100644 index 91c0d47eea..0000000000 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/TerrainTex.cpp +++ /dev/null @@ -1,1206 +0,0 @@ -/* -** Command & Conquer Generals(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) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -// FILE: TerrainTex.cpp //////////////////////////////////////////////// -//----------------------------------------------------------------------------- -// -// Westwood Studios Pacific. -// -// Confidential Information -// Copyright (C) 2001 - All Rights Reserved -// -//----------------------------------------------------------------------------- -// -// Project: RTS3 -// -// File name: TerrainTex.cpp -// -// Created: John Ahlquist, April 2001 -// -// Desc: TextureClass overrides to perform custom texturing for the terrain. -// -//----------------------------------------------------------------------------- - -//----------------------------------------------------------------------------- -// Includes -//----------------------------------------------------------------------------- -#include - -#include "W3DDevice/GameClient/TerrainTex.h" -#include "W3DDevice/GameClient/WorldHeightMap.h" -#include "W3DDevice/GameClient/TileData.h" -#include "Common/GlobalData.h" -#include "WW3D2/dx8wrapper.h" -#include "d3dx8tex.h" - -/****************************************************************************** - TerrainTextureClass -******************************************************************************/ -//----------------------------------------------------------------------------- -// Public Functions -//----------------------------------------------------------------------------- - -//============================================================================= -// TerrainTextureClass::TerrainTextureClass -//============================================================================= -/** Constructor. Calls parent constructor to create a 16 bit per pixel D3D -texture of the desired height and mip level. */ -//============================================================================= -TerrainTextureClass::TerrainTextureClass(int height, MipCountType mipLevelCount) : - TextureClass(TEXTURE_WIDTH, height, - WW3D_FORMAT_A1R5G5B5, mipLevelCount ) -{ -} - - -//============================================================================= -// TerrainTextureClass::update -//============================================================================= -/** Sets the tile bitmap data into the texture. The tiles are placed with 4 - pixel borders around them, so that when the tiles are scaled and bilinearly - interpolated, you don't get seams between the tiles. */ -//============================================================================= -int TerrainTextureClass::update(WorldHeightMap *htMap) -{ - // D3DTexture is our texture; - - IDirect3DSurface8 *surface_level; - D3DSURFACE_DESC surface_desc; - D3DLOCKED_RECT locked_rect; - DX8_ErrorCode(Peek_D3D_Texture()->GetSurfaceLevel(0, &surface_level)); - DX8_ErrorCode(surface_level->GetDesc(&surface_desc)); - if (surface_desc.Width < TEXTURE_WIDTH) { - surface_level->Release(); - if (surface_desc.Width == 256) { - return update256(htMap); - } - return false; - } - - DX8_ErrorCode(surface_level->LockRect(&locked_rect, NULL, 0)); - - Int tilePixelExtent = TILE_PIXEL_EXTENT; - Int tilesPerRow = surface_desc.Width/(2*TILE_PIXEL_EXTENT+TILE_OFFSET); - tilesPerRow *= 2; -// Int numRows = surface_desc.Height/(tilePixelExtent+TILE_OFFSET); -#ifdef RTS_DEBUG - //DEBUG_ASSERTCRASH(tilesPerRow*numRows >= htMap->m_numBitmapTiles, ("Too many tiles.")); - DEBUG_ASSERTCRASH((Int)surface_desc.Width >= tilePixelExtent*tilesPerRow, ("Bitmap too small.")); -#endif - if (surface_desc.Format == D3DFMT_A1R5G5B5) { -#if 0 - UnsignedInt cellX, cellY; - for (cellX = 0; cellX < surface_desc.Width; cellX++) { - for (cellY = 0; cellY < surface_desc.Height; cellY++) { - UnsignedByte *pBGR = ((UnsignedByte *)locked_rect.pBits)+(cellY*surface_desc.Width+cellX)*2; - *((Short*)pBGR) = (((255-2*cellY)>>3)<<10) + ((4*cellX)>>4); - } - } -#endif - Int tileNdx; - Int pixelBytes = 2; - for (tileNdx=0; tileNdx < htMap->m_numBitmapTiles; tileNdx++) { - TileData *pTile = htMap->getSourceTile(tileNdx); - if (!pTile) continue; - ICoord2D position = pTile->m_tileLocationInTexture; - if (position.x<=0) continue; // all real tile offsets start at 2. jba. - - Int i,j; - for (j=0; jgetRGBDataForWidth(tilePixelExtent); - pBGR += (tilePixelExtent-1-j)*TILE_BYTES_PER_PIXEL*tilePixelExtent; // invert to match. - Int row = position.y+j; - UnsignedByte *pBGRX = ((UnsignedByte*)locked_rect.pBits) + - (row)*surface_desc.Width*pixelBytes; - - Int column = position.x; - pBGRX += column*pixelBytes; - for (i=0; i>3)<<10) + ((pBGR[1]>>3)<<5) + (pBGR[0]>>3); - pBGRX +=pixelBytes; - pBGR +=TILE_BYTES_PER_PIXEL; - } - } - } - // Now draw the 4 pixel border around each tile class. - Int texClass; - for (texClass=0; texClassm_numTextureClasses; texClass++) { - Int width = htMap->m_textureClasses[texClass].width; - ICoord2D origin = htMap->m_textureClasses[texClass].positionInTexture; - if (origin.x<=0) continue; - width *= TILE_PIXEL_EXTENT; - // Duplicate 4 columns of pixels before and after. - Int j; - for (j=0; jUnlockRect(); - surface_level->Release(); - DX8_ErrorCode(D3DXFilterTexture(Peek_D3D_Texture(), NULL, 0, D3DX_FILTER_BOX)); - if (WW3D::Get_Texture_Reduction()) { - Peek_D3D_Texture()->SetLOD(WW3D::Get_Texture_Reduction()); - } - return(surface_desc.Height); -} - -#if 0 // old version. -//============================================================================= -// TerrainTextureClass::update -//============================================================================= -/** Sets the tile bitmap data into the texture. The tiles are placed with 4 - pixel borders around them, so that when the tiles are scaled and bilinearly - interpolated, you don't get seams between the tiles. */ -//============================================================================= -int TerrainTextureClass::update(WorldHeightMap *htMap) -{ - // D3DTexture is our texture; - - IDirect3DSurface8 *surface_level; - D3DSURFACE_DESC surface_desc; - D3DLOCKED_RECT locked_rect; - DX8_ErrorCode(D3DTexture->GetSurfaceLevel(0, &surface_level)); - DX8_ErrorCode(surface_level->GetDesc(&surface_desc)); - if (surface_desc.Width < TEXTURE_WIDTH) { - surface_level->Release(); - if (surface_desc.Width == 256) { - return update256(htMap); - } - return false; - } - - DX8_ErrorCode(surface_level->LockRect(&locked_rect, NULL, 0)); - - Int tilePixelExtent = TILE_PIXEL_EXTENT; - Int tilesPerRow = surface_desc.Width/(2*TILE_PIXEL_EXTENT+TILE_OFFSET); - tilesPerRow *= 2; - Int numRows = surface_desc.Height/(tilePixelExtent+TILE_OFFSET); -#ifdef RTS_DEBUG - assert(tilesPerRow*numRows >= htMap->m_numBitmapTiles); - assert((Int)surface_desc.Width >= tilePixelExtent*tilesPerRow); -#endif - if (surface_desc.Format == D3DFMT_A1R5G5B5) { - Int cellX, cellY; -#if 0 - for (cellX = 0; cellX < surface_desc.Width; cellX++) { - for (cellY = 0; cellY < surface_desc.Height; cellY++) { - UnsignedByte *pBGR = ((UnsignedByte *)locked_rect.pBits)+(cellY*surface_desc.Width+cellX)*2; - *((Short*)pBGR) = (((255-2*cellY)>>3)<<10) + ((4*cellX)>>4); - } - } -#endif - Int pixelBytes = 2; - for (cellY = 0; cellY < numRows; cellY++) { - for (cellX = 0; cellX < tilesPerRow; cellX++) { - Int tileNdx = cellX/2 + (tilesPerRow/2)*(cellY/2); - tileNdx *=4; - if (cellX&1) tileNdx++; - if (!(cellY&1)) tileNdx += 2; -#define ADD_EXTRA_TILES 1 -#if ADD_EXTRA_TILES // Fills in an extra 2 columns and 1 row of tiles if there is room. - if (!htMap->getSourceTile(tileNdx) && htMap->getSourceTile(tileNdx-4)) { - tileNdx -= 4; - } - if (!htMap->getSourceTile(tileNdx) && htMap->getSourceTile(tileNdx-8)) { - tileNdx -= 8; - } - if (!htMap->getSourceTile(tileNdx) && htMap->getSourceTile(tileNdx-2*tilesPerRow)) { - tileNdx -= 2*tilesPerRow; - } -#endif - if (htMap->getSourceTile(tileNdx)) { - Int i,j; - for (j=0; jgetSourceTile(tileNdx)->getRGBDataForWidth(tilePixelExtent); - pBGR += (tilePixelExtent-1-j)*TILE_BYTES_PER_PIXEL*tilePixelExtent; // invert to match. - Int row = cellY*tilePixelExtent+j; - row += TILE_OFFSET/2; - row += TILE_OFFSET*(cellY/2); - UnsignedByte *pBGRX = ((UnsignedByte*)locked_rect.pBits) + - (row)*surface_desc.Width*pixelBytes; - - Int column = cellX*tilePixelExtent; - column += TILE_OFFSET*(cellX/2); - pBGRX += column*pixelBytes; - pBGRX += (TILE_OFFSET/2)*pixelBytes; - for (i=0; i>3)<<10) + ((pBGR[1]>>3)<<5) + (pBGR[0]>>3); - pBGRX +=pixelBytes; - pBGR +=TILE_BYTES_PER_PIXEL; - } - } - - } - } - - } - - - for (cellY = 0; cellY < numRows; cellY++) { - for (cellX = 0; cellX < tilesPerRow; cellX++) { - // Duplicate 4 rows of pixels before and after. - Int j; - for (j=0; jUnlockRect(); - surface_level->Release(); - DX8_ErrorCode(D3DXFilterTexture(D3DTexture, NULL, 0, D3DX_FILTER_BOX)); - return(surface_desc.Height); -} -#endif -//============================================================================= -// TerrainTextureClass::update256 -//============================================================================= -/** Sets the tile bitmap data into the texture. Handles the special case for voodoos - and the like where the max texture size is 256. The tiles are placed with 1 - pixel borders around them, so that when the tiles are scaled and bilinearly - interpolated, you don't get seams between the tiles. */ -//============================================================================= -int TerrainTextureClass::update256(WorldHeightMap *htMap) -{ - // D3DTexture is our texture; - - IDirect3DSurface8 *surface_level; - D3DSURFACE_DESC surface_desc; - D3DLOCKED_RECT locked_rect; - DX8_ErrorCode(Peek_D3D_Texture()->GetSurfaceLevel(0, &surface_level)); - DX8_ErrorCode(surface_level->GetDesc(&surface_desc)); - if (surface_desc.Width != 256) { - surface_level->Release(); - return surface_desc.Height; - } - - DX8_ErrorCode(surface_level->LockRect(&locked_rect, NULL, 0)); - - Int tilePixelExtent = TILE_PIXEL_EXTENT/4; // We are going from 1024 to 256, so need to divide all the constants by 4. - Int tileOffset = TILE_OFFSET/4; - Int tilesPerRow = surface_desc.Width/(2*tilePixelExtent+tileOffset); - tilesPerRow *= 2; - Int numRows = surface_desc.Height/(tilePixelExtent+tileOffset); - -#ifdef RTS_DEBUG - assert(tilesPerRow*numRows >= htMap->m_numBitmapTiles); - assert((Int)surface_desc.Width >= tilePixelExtent*tilesPerRow); -#endif - if (surface_desc.Format == D3DFMT_A1R5G5B5) { - Int cellX, cellY; -#if 0 - for (cellX = 0; cellX < surface_desc.Width; cellX++) { - for (cellY = 0; cellY < surface_desc.Height; cellY++) { - UnsignedByte *pBGR = ((UnsignedByte *)locked_rect.pBits)+(cellY*surface_desc.Width+cellX)*2; - *((Short*)pBGR) = (((255-2*cellY)>>3)<<10) + ((4*cellX)>>4); - } - } - numRows = 0; -#endif - Int pixelBytes = 2; - for (cellY = 0; cellY < numRows; cellY++) { - for (cellX = 0; cellX < tilesPerRow; cellX++) { - Int tileNdx = cellX/2 + (tilesPerRow/2)*(cellY/2); - tileNdx *=4; - if (cellX&1) tileNdx++; - if (!(cellY&1)) tileNdx += 2; -#if ADD_EXTRA_TILES // Fills in an extra 2 columns and 1 row of tiles if there is room. - if (!htMap->getSourceTile(tileNdx) && htMap->getSourceTile(tileNdx-4)) { - tileNdx -= 4; - } - if (!htMap->getSourceTile(tileNdx) && htMap->getSourceTile(tileNdx-8)) { - tileNdx -= 8; - } - if (!htMap->getSourceTile(tileNdx) && htMap->getSourceTile(tileNdx-2*tilesPerRow)) { - tileNdx -= 2*tilesPerRow; - } -#endif - if (htMap->getSourceTile(tileNdx)) { - Int i,j; - for (j=0; jgetSourceTile(tileNdx)->getRGBDataForWidth(tilePixelExtent); - pBGR += (tilePixelExtent-1-j)*TILE_BYTES_PER_PIXEL*tilePixelExtent; // invert to match. - Int row = cellY*tilePixelExtent+j; - row += tileOffset/2; - row += tileOffset*(cellY/2); - UnsignedByte *pBGRX = ((UnsignedByte*)locked_rect.pBits) + - (row)*surface_desc.Width*pixelBytes; - - Int column = cellX*tilePixelExtent; - column += tileOffset*(cellX/2); - pBGRX += column*pixelBytes; - pBGRX += (tileOffset/2)*pixelBytes; - for (i=0; i>3)<<10) + ((pBGR[1]>>3)<<5) + (pBGR[0]>>3); - pBGRX +=pixelBytes; - pBGR +=TILE_BYTES_PER_PIXEL; - } - } - - } - } - - } - - for (cellY = 0; cellY < numRows; cellY++) { - for (cellX = 0; cellX < tilesPerRow; cellX++) { - // Duplicate 1 rows of pixels before and after. - Int j; - for (j=0; jUnlockRect(); - surface_level->Release(); - DX8_ErrorCode(D3DXFilterTexture(Peek_D3D_Texture(), NULL, 0, D3DX_FILTER_BOX)); - // Note - normal width for the terrain texture is 1024. We are at 256 - // probably running on a voodoo. The height we return is scaled up - // to match the expected width of 1024. jba. - return(surface_desc.Height*4); -} - - -//============================================================================= -// TerrainTextureClass::Apply -//============================================================================= -/** Sets the texture as the current D3D texture, and does some custom setup -(standard D3D setup, but beyond the scope of W3D). */ -//============================================================================= -void TerrainTextureClass::Apply(unsigned int stage) -{ - // Do the base apply. - TextureClass::Apply(stage); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); - if (TheGlobalData && (TheGlobalData->m_bilinearTerrainTex || TheGlobalData->m_trilinearTerrainTex)) { - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MINFILTER, D3DTEXF_LINEAR); - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); - } else { - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MINFILTER, D3DTEXF_POINT); - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MAGFILTER, D3DTEXF_POINT); - } - if (TheGlobalData && TheGlobalData->m_trilinearTerrainTex) { - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); - } else { - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MIPFILTER, D3DTEXF_POINT); - } - // Now setup the texture pipeline. - if (stage==0) { - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); - - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_DISABLE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, 0 ); - DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHABLENDENABLE,false); - - } -} - -/****************************************************************************** - AlphaTerrainTextureClass -******************************************************************************/ -//----------------------------------------------------------------------------- -// Public Functions -//----------------------------------------------------------------------------- - -//============================================================================= -// AlphaTerrainTextureClass::AlphaTerrainTextureClass -//============================================================================= -/** Constructor. Calls parent constructor to creat a throw away 8x8 texture, -then uses the base texture's D3D texture. This way the base tiles pass, drawn -using TerrainTextureClass shares the same texture with the blended edges pass, -saving lots of texture memory, and preventing seams between blended tiles. */ -//============================================================================= -AlphaTerrainTextureClass::AlphaTerrainTextureClass( TextureClass *pBaseTex ): - TextureClass(8, 8, - WW3D_FORMAT_A1R5G5B5, MIP_LEVELS_1 ) -{ - // Attach the base texture's d3d texture. - IDirect3DTexture8 * d3d_tex = pBaseTex->Peek_D3D_Texture(); - Set_D3D_Base_Texture(d3d_tex); -} - - -//============================================================================= -// AlphaTerrainTextureClass::Apply -//============================================================================= -/** Sets the texture as the current D3D texture, and does some custom setup. -This may be applied in either single pass, as the second texture in the pipe, -or multipass. If stage==0, we are doing multipass and we set up the pipe -for a single texture. If stage==1, then we are doing a single pass, and we -set up the pipe so that we blend onto the base texture in stage 0. -(standard D3D setup, but beyond the scope of W3D). */ -//============================================================================= -void AlphaTerrainTextureClass::Apply(unsigned int stage) -{ - // Do the base apply. - TextureClass::Apply(stage); - - // Set the bilinear or trilinear filtering. - if (TheGlobalData && (TheGlobalData->m_bilinearTerrainTex || TheGlobalData->m_trilinearTerrainTex)) { - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MINFILTER, D3DTEXF_LINEAR); - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); - } else { - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MINFILTER, D3DTEXF_POINT); - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MAGFILTER, D3DTEXF_POINT); - } - if (TheGlobalData && TheGlobalData->m_trilinearTerrainTex) { - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); - } else { - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MIPFILTER, D3DTEXF_POINT); - } - // Since we are using multiple distinct tiles, the textures doesn't wrap, so clamp it. - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); - // Now setup the texture pipeline. - if (stage==0) { - // Modulate the diffuse color with the texture as lighting comes from diffuse. - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, 1 ); - // Blend the result using the alpha. (came from diffuse mod texture) - DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHABLENDENABLE,true); - DX8Wrapper::Set_DX8_Render_State(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA); - DX8Wrapper::Set_DX8_Render_State(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA); - // Disable stage 2. - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_DISABLE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); - } else if (stage==1) { - - if (TheGlobalData && !TheGlobalData->m_multiPassTerrain) - { - ///@todo: Remove 8-Stage Nvidia hack after drivers are fixed. - //This method is a backdoor specific to Nvidia based cards. It will fail on - //other hardware. Allows single pass blend of 2 textures and post modulate diffuse. - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLOROP, D3DTOP_MODULATE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, 0); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); - - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_ADD); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXCOORDINDEX, 1); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_COMPLEMENT | D3DTA_ALPHAREPLICATE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_ADD); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAARG1, D3DTA_TFACTOR | D3DTA_COMPLEMENT); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAARG2, D3DTA_TFACTOR); - - DX8Wrapper::Set_DX8_Texture(2, NULL); - DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_COLOROP, D3DTOP_MODULATE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_TEXCOORDINDEX, 2); - DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_COLORARG1, D3DTA_TEXTURE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_COLORARG2, D3DTA_TEXTURE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_ALPHAOP, D3DTOP_MODULATE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_ALPHAARG1, D3DTA_TFACTOR); - DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_ALPHAARG2, D3DTA_TFACTOR); - - DX8Wrapper::Set_DX8_Texture(3, NULL); - DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_COLOROP, D3DTOP_SELECTARG1); - DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_TEXCOORDINDEX, 3); - DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_COLORARG1, D3DTA_DIFFUSE | 0 | D3DTA_ALPHAREPLICATE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_COLORARG2, D3DTA_DIFFUSE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_ALPHAARG1, D3DTA_TFACTOR); - DX8Wrapper::Set_DX8_Texture_Stage_State( 3, D3DTSS_ALPHAARG2, D3DTA_TFACTOR); - - DX8Wrapper::Set_DX8_Texture(4, NULL); - DX8Wrapper::Set_DX8_Texture_Stage_State( 4, D3DTSS_COLOROP, D3DTOP_MODULATE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 4, D3DTSS_TEXCOORDINDEX, 4); - DX8Wrapper::Set_DX8_Texture_Stage_State( 4, D3DTSS_COLORARG1, D3DTA_CURRENT); - DX8Wrapper::Set_DX8_Texture_Stage_State( 4, D3DTSS_COLORARG2, D3DTA_DIFFUSE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 4, D3DTSS_ALPHAOP, D3DTOP_MODULATE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 4, D3DTSS_ALPHAARG1, D3DTA_CURRENT); - DX8Wrapper::Set_DX8_Texture_Stage_State( 4, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); - - DX8Wrapper::Set_DX8_Texture(5, NULL); - DX8Wrapper::Set_DX8_Texture_Stage_State( 5, D3DTSS_COLOROP, D3DTOP_ADD); - DX8Wrapper::Set_DX8_Texture_Stage_State( 5, D3DTSS_TEXCOORDINDEX, 5); - DX8Wrapper::Set_DX8_Texture_Stage_State( 5, D3DTSS_COLORARG1, D3DTA_DIFFUSE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 5, D3DTSS_COLORARG2, D3DTA_DIFFUSE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 5, D3DTSS_ALPHAOP, D3DTOP_ADD); - DX8Wrapper::Set_DX8_Texture_Stage_State( 5, D3DTSS_ALPHAARG1, D3DTA_TFACTOR | D3DTA_COMPLEMENT); - DX8Wrapper::Set_DX8_Texture_Stage_State( 5, D3DTSS_ALPHAARG2, D3DTA_TFACTOR); - - DX8Wrapper::Set_DX8_Texture(6, NULL); - DX8Wrapper::Set_DX8_Texture_Stage_State( 6, D3DTSS_COLOROP, D3DTOP_MODULATE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 6, D3DTSS_TEXCOORDINDEX, 6); - DX8Wrapper::Set_DX8_Texture_Stage_State( 6, D3DTSS_COLORARG1, D3DTA_TFACTOR); - DX8Wrapper::Set_DX8_Texture_Stage_State( 6, D3DTSS_COLORARG2, D3DTA_TFACTOR); - DX8Wrapper::Set_DX8_Texture_Stage_State( 6, D3DTSS_ALPHAOP, D3DTOP_MODULATE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 6, D3DTSS_ALPHAARG1, D3DTA_TFACTOR); - DX8Wrapper::Set_DX8_Texture_Stage_State( 6, D3DTSS_ALPHAARG2, D3DTA_TFACTOR); - - DX8Wrapper::Set_DX8_Texture(7, NULL); - DX8Wrapper::Set_DX8_Texture_Stage_State( 7, D3DTSS_COLOROP, D3DTOP_SELECTARG1); - DX8Wrapper::Set_DX8_Texture_Stage_State( 7, D3DTSS_TEXCOORDINDEX, 7); - DX8Wrapper::Set_DX8_Texture_Stage_State( 7, D3DTSS_COLORARG1, D3DTA_TFACTOR); - DX8Wrapper::Set_DX8_Texture_Stage_State( 7, D3DTSS_COLORARG2, D3DTA_TFACTOR); - DX8Wrapper::Set_DX8_Texture_Stage_State( 7, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - DX8Wrapper::Set_DX8_Texture_Stage_State( 7, D3DTSS_ALPHAARG1, D3DTA_TFACTOR); - DX8Wrapper::Set_DX8_Texture_Stage_State( 7, D3DTSS_ALPHAARG2, D3DTA_TFACTOR); - } - else - { - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ); - - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_MODULATE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG2, D3DTA_CURRENT ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ); - } - } -} - - -/****************************************************************************** - LightMapTerrainTextureClass -******************************************************************************/ -//----------------------------------------------------------------------------- -// Public Functions -//----------------------------------------------------------------------------- - -//============================================================================= -// LightMapTerrainTextureClass::LightMapTerrainTextureClass -//============================================================================= -/** Constructor. Calls parent constructor to load the .tga texture. */ -//============================================================================= -LightMapTerrainTextureClass::LightMapTerrainTextureClass(AsciiString name, MipCountType mipLevelCount) : -TextureClass(name.isEmpty()?"TSNoiseUrb.tga":name.str(),name.isEmpty()?"TSNoiseUrb.tga":name.str(), mipLevelCount ) -{ -} - -#define STRETCH_FACTOR ((float)(1/(63.0*MAP_XY_FACTOR/2))) /* covers 63/2 tiles */ - -//============================================================================= -// LightMapTerrainTextureClass::Apply -//============================================================================= -/** Sets the texture as the current D3D texture, and does some custom setup. -The LightMapTerrainTextureClass may be applied by itself, or with the -CloudMapTerrainTextureClass. This may be applied in either single pass, -as the second texture in the pipe, -or multipass. If stage==0, we are doing multipass and we set up the pipe -for a single texture. If stage==1, then we are doing a single pass, and we -set up the pipe so that we blend onto the cloud map texture in stage 0. -Also, texture is mapped using the x/y coordinates of the map, saving us -yet another set of uv coordinates. -(standard D3D setup, but beyond the scope of W3D). */ -//============================================================================= -void LightMapTerrainTextureClass::Apply(unsigned int stage) -{ - // Do the base apply. - TextureClass::Apply(stage); - /* previous setup */ - if (TheGlobalData && TheGlobalData->m_trilinearTerrainTex) { - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); - } else { - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MIPFILTER, D3DTEXF_POINT); - } - - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MINFILTER, D3DTEXF_POINT); - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); - - // Disable 3rd stage just in case. - DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_COLOROP, D3DTOP_DISABLE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); - - // Now setup the texture pipeline. - DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_COLORARG2, D3DTA_CURRENT ); - if (stage == 0) { - DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_COLOROP, D3DTOP_SELECTARG1 ); - //Disable second stage - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_DISABLE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); - } else { - DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_COLOROP, D3DTOP_MODULATE ); - } - DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); - // Two output coordinates are used. - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); - - - DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); - DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); - - Matrix4x4 curView; - DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, curView); - - - D3DXMATRIX inv; - float det; - D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView); - D3DXMATRIX scale; - D3DXMatrixScaling(&scale, STRETCH_FACTOR, STRETCH_FACTOR,1); - inv *=scale; - if (stage==0) { - DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE0, *((Matrix4x4*)&inv)); - } if (stage==1) { - DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE1, *((Matrix4x4*)&inv)); - } - - - if (stage==0) { - DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHABLENDENABLE,true); - DX8Wrapper::Set_DX8_Render_State(D3DRS_SRCBLEND,D3DBLEND_DESTCOLOR); - DX8Wrapper::Set_DX8_Render_State(D3DRS_DESTBLEND,D3DBLEND_ZERO); - } -} - - - - - - - - - -/****************************************************************************** - AlphaEdgeTextureClass -******************************************************************************/ -//----------------------------------------------------------------------------- -// Public Functions -//----------------------------------------------------------------------------- - -/** -* AlphaEdgeTextureClass - Generates the alpha edge blending for terrain. -* -*/ -AlphaEdgeTextureClass::AlphaEdgeTextureClass( int height, MipCountType mipLevelCount) : -// TextureClass("EdgingTemplate.tga","EdgingTemplate.tga", mipLevelCount ) - TextureClass(TEXTURE_WIDTH, height, WW3D_FORMAT_A8R8G8B8, mipLevelCount ) -{ - -} - -int AlphaEdgeTextureClass::update256(WorldHeightMap *htMap) -{ - return 1; -} - -int AlphaEdgeTextureClass::update(WorldHeightMap *htMap) -{ - // D3DTexture is our texture; - - IDirect3DSurface8 *surface_level; - D3DSURFACE_DESC surface_desc; - D3DLOCKED_RECT locked_rect; - DX8_ErrorCode(Peek_D3D_Texture()->GetSurfaceLevel(0, &surface_level)); - DX8_ErrorCode(surface_level->LockRect(&locked_rect, NULL, 0)); - DX8_ErrorCode(surface_level->GetDesc(&surface_desc)); - - Int tilePixelExtent = TILE_PIXEL_EXTENT; // blend tiles are 1/4 tiles. -// Int tilesPerRow = surface_desc.Width / (tilePixelExtent+8); - -// Int numRows = surface_desc.Height/(tilePixelExtent+8); - - if (surface_desc.Format == D3DFMT_A8R8G8B8) { -#if 1 -#if 1 - Int cellX, cellY; - for (cellX = 0; (UnsignedInt)cellX < surface_desc.Width; cellX++) { - for (cellY = 0; cellY < surface_desc.Height; cellY++) { - UnsignedByte *pBGR = ((UnsignedByte *)locked_rect.pBits)+(cellY*surface_desc.Width+cellX)*4; - pBGR[2] = 255-cellY/2; - pBGR[0] = cellX/2; - pBGR[3] = cellX/2; // alpha. - pBGR[3] = 128; // alpha. - } - } -#endif -#if 1 - Int tileNdx; - Int pixelBytes = 4; - for (tileNdx=0; tileNdx < htMap->m_numEdgeTiles; tileNdx++) { - TileData *pTile = htMap->getEdgeTile(tileNdx); - if (!pTile) continue; - ICoord2D position = pTile->m_tileLocationInTexture; - if (position.x<=0) continue; // all real edge offsets start at 4. jba. - Int i,j; - Int column = position.x; - for (j=0; jgetEdgeTile(tileNdx)->getRGBDataForWidth(tilePixelExtent); - pBGR += (tilePixelExtent-1-j)*TILE_BYTES_PER_PIXEL*tilePixelExtent; // invert to match. - UnsignedByte *pBGRX = ((UnsignedByte*)locked_rect.pBits) + - (row)*surface_desc.Width*pixelBytes; - pBGRX += column*pixelBytes; - - for (i=0; iUnlockRect(); - surface_level->Release(); - DX8_ErrorCode(D3DXFilterTexture(Peek_D3D_Texture(), NULL, 0, D3DX_FILTER_BOX)); - return(surface_desc.Height); -} - -void AlphaEdgeTextureClass::Apply(unsigned int stage) -{ - // Do the base apply. - TextureClass::Apply(stage); - - if (TheGlobalData && (TheGlobalData->m_bilinearTerrainTex || TheGlobalData->m_trilinearTerrainTex)) { - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MINFILTER, D3DTEXF_LINEAR); - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); - } else { - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MINFILTER, D3DTEXF_POINT); - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MAGFILTER, D3DTEXF_POINT); - } - if (TheGlobalData && TheGlobalData->m_trilinearTerrainTex) { - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); - } else { - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MIPFILTER, D3DTEXF_POINT); - } - - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); - // Now setup the texture pipeline. - if (stage==0) { - - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, 1 ); - DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHABLENDENABLE,true); - DX8Wrapper::Set_DX8_Render_State(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA); - DX8Wrapper::Set_DX8_Render_State(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA); - - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_DISABLE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); - - } else if (stage==1) { - // Drawing texture through the mask. - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAARG1, D3DTA_CURRENT ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ); - - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG1, D3DTA_CURRENT ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG2, D3DTA_TEXTURE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1 ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAARG1, D3DTA_CURRENT ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAARG2, D3DTA_TEXTURE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2 ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXCOORDINDEX, 1 ); - DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHABLENDENABLE,true); - DX8Wrapper::Set_DX8_Render_State(D3DRS_SRCBLEND,D3DBLEND_ONE); - DX8Wrapper::Set_DX8_Render_State(D3DRS_DESTBLEND,D3DBLEND_ZERO); - - } -} - - -/****************************************************************************** - CloudMapTerrainTextureClass -******************************************************************************/ -//----------------------------------------------------------------------------- -// Public Functions -//----------------------------------------------------------------------------- - -//============================================================================= -// CloudMapTerrainTextureClass::CloudMapTerrainTextureClass -//============================================================================= -/** Constructor. Calls parent constructor to load the .tga texture, and sets -up the "sliding" parameters for the clouds to slide over the terrain. */ -//============================================================================= -//@todo - Allow adjustment of the cloud slide rate, and lose the hard coded "cloudmap.tga" -CloudMapTerrainTextureClass::CloudMapTerrainTextureClass(MipCountType mipLevelCount) : - TextureClass("TSCloudMed.tga","TSCloudMed.tga", mipLevelCount ) -{ - Get_Filter().Set_Mip_Mapping( TextureFilterClass::FILTER_TYPE_FAST ); - m_xSlidePerSecond = -0.02f; - m_ySlidePerSecond = 1.50f * m_xSlidePerSecond; - m_curTick = 0; - m_xOffset = 0; - m_yOffset = 0; - -} - -//============================================================================= -// CloudMapTerrainTextureClass::Apply -//============================================================================= -/** Sets the texture as the current D3D texture, and does some custom setup. -The CloudMapTerrainTextureClass may be applied by itself, or with the -LightMapTerrainTexture. This may be applied in either single pass, -as the first texture in the pipe with LightMapTerrainTextureClass as the -second stage of the pape, or multipass. We setup for stage 0, assuming that -we are the only texture, as LightMapTerrainTexture will adjust for multitexture -if it is applied to stage 1. -Also, texture is mapped using the x/y coordinates of the map, saving us -yet another set of uv coordinates. -(standard D3D setup, but beyond the scope of W3D). */ -//============================================================================= -void CloudMapTerrainTextureClass::Apply(unsigned int stage) -{ - - - // Do the base apply. - TextureClass::Apply(stage); - /* previous setup */ - if (TheGlobalData && TheGlobalData->m_trilinearTerrainTex) { - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); - } else { - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MIPFILTER, D3DTEXF_POINT); - } - - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MINFILTER, D3DTEXF_LINEAR); - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); - - // Now setup the texture pipeline. - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); - // Two output coordinates are used. - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); - - - DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); - DX8Wrapper::Set_DX8_Texture_Stage_State( stage, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); - - Matrix4x4 curView; - DX8Wrapper::_Get_DX8_Transform(D3DTS_VIEW, curView); - - - D3DXMATRIX inv; - float det; - D3DXMatrixInverse(&inv, &det, (D3DXMATRIX*)&curView); - D3DXMATRIX scale; - D3DXMatrixScaling(&scale, STRETCH_FACTOR, STRETCH_FACTOR,1); - inv *=scale; - D3DXMATRIX offset; - - Int delta = m_curTick; - m_curTick = ::GetTickCount(); - delta = m_curTick-delta; - m_xOffset += m_xSlidePerSecond*delta/1000; - m_yOffset += m_ySlidePerSecond*delta/1000; - - if (m_xOffset > 1) m_xOffset -= 1; - if (m_yOffset > 1) m_yOffset -= 1; - if (m_xOffset < -1) m_xOffset += 1; - if (m_yOffset < -1) m_yOffset += 1; - - - D3DXMatrixTranslation(&offset, m_xOffset, m_yOffset,0); - - inv *= offset; - - if (stage==0) { - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); - - DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE0, *((Matrix4x4*)&inv)); - - // Disable 3rd stage just in case. - DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_COLOROP, D3DTOP_DISABLE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 2, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); - - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_DISABLE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); - - DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHABLENDENABLE,true); - DX8Wrapper::Set_DX8_Render_State(D3DRS_SRCBLEND,D3DBLEND_DESTCOLOR); - DX8Wrapper::Set_DX8_Render_State(D3DRS_DESTBLEND,D3DBLEND_ZERO); - } else if (stage==1) { - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG2, D3DTA_CURRENT ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_MODULATE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAARG1, D3DTA_CURRENT ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ); - - DX8Wrapper::_Set_DX8_Transform(D3DTS_TEXTURE1, *((Matrix4x4*)&inv)); - } -} - -//============================================================================= -// CloudMapTerrainTextureClass::restore -//============================================================================= -/** Cleans up any custom settings to the texturing pipeline that may not be -understood by w3d. */ -//============================================================================= -void CloudMapTerrainTextureClass::restore(void) -{ - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); - - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, 0 ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); - - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_MODULATE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); - - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXCOORDINDEX, 0 ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); - DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHABLENDENABLE,false); - DX8Wrapper::Set_DX8_Render_State(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA); - DX8Wrapper::Set_DX8_Render_State(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA); - - - if (TheGlobalData && !TheGlobalData->m_multiPassTerrain) - { - ///@todo: Remove 8-Stage Nvidia hack after drivers are fixed. - //This method is a backdoor specific to Nvidia based cards. It will fail on - //other hardware. Allows single pass blend of 2 textures and post modulate diffuse. - Int i; - for (i=0; i<8; i++) { - DX8Wrapper::Set_DX8_Texture_Stage_State( i, D3DTSS_COLOROP, D3DTOP_DISABLE); - DX8Wrapper::Set_DX8_Texture_Stage_State( i, D3DTSS_TEXCOORDINDEX, i); - DX8Wrapper::Set_DX8_Texture_Stage_State( i, D3DTSS_COLORARG1, D3DTA_TEXTURE); - DX8Wrapper::Set_DX8_Texture_Stage_State( i, D3DTSS_COLORARG2, D3DTA_DIFFUSE); - DX8Wrapper::Set_DX8_Texture_Stage_State( i, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - DX8Wrapper::Set_DX8_Texture_Stage_State( i, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); - DX8Wrapper::Set_DX8_Texture_Stage_State( i, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); - - DX8Wrapper::Set_DX8_Texture(i, NULL); - } - } -} - -/****************************************************************************** - ScorchTextureClass -******************************************************************************/ -//----------------------------------------------------------------------------- -// Public Functions -//----------------------------------------------------------------------------- - -//============================================================================= -// ScorchTextureClass::ScorchTextureClass -//============================================================================= -/** Constructor. Calls parent constructor to load the .tga texture. */ -//============================================================================= -/// @todo - get "EXScorch01.tga" from not hard coded location. -ScorchTextureClass::ScorchTextureClass(MipCountType mipLevelCount) : - TextureClass("EXScorch01.tga","EXScorch01.tga", mipLevelCount ) -{ -} - -//============================================================================= -// ScorchTextureClass::Apply -//============================================================================= -/** Sets the texture as the current D3D texture, and does some custom setup. -The ScorchTextureClass is applied by iteself, as it's mesh is a subset of the -terrain mesh. -(standard D3D setup, but beyond the scope of W3D). */ -//============================================================================= -void ScorchTextureClass::Apply(unsigned int stage) -{ - // Do the base apply. - TextureClass::Apply(stage); - // Setup bilinear or trilinear filtering as specified in global data. - if (TheGlobalData && (TheGlobalData->m_bilinearTerrainTex || TheGlobalData->m_trilinearTerrainTex)) { - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MINFILTER, D3DTEXF_LINEAR); - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); - } else { - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MINFILTER, D3DTEXF_POINT); - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MAGFILTER, D3DTEXF_POINT); - } - if (TheGlobalData && TheGlobalData->m_trilinearTerrainTex) { - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); - } else { - DX8Wrapper::Set_DX8_Texture_Stage_State(stage, D3DTSS_MIPFILTER, D3DTEXF_POINT); - } - - DX8Wrapper::Set_DX8_Texture_Stage_State(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); - // Now setup the texture pipeline. - - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 0, D3DTSS_TEXCOORDINDEX, 0 ); - DX8Wrapper::Set_DX8_Render_State(D3DRS_ALPHABLENDENABLE,true); - DX8Wrapper::Set_DX8_Render_State(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA); - DX8Wrapper::Set_DX8_Render_State(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA); - - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_COLOROP, D3DTOP_DISABLE ); - DX8Wrapper::Set_DX8_Texture_Stage_State( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); -} - - diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/TileData.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/TileData.cpp deleted file mode 100644 index 6566b9f399..0000000000 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/TileData.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* -** Command & Conquer Generals(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) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -// TileData.cpp -// Class to handle tile data. -// Author: John Ahlquist, April 2001 - -#include "W3DDevice/GameClient/TileData.h" -#include "W3DDevice/GameClient/WorldHeightMap.h" - - - -// -// TileData - no destructor. -// - -// -// TileData - create a new texture tile . -// -TileData::TileData() -{ - -} - -#define TILE_PIXEL_EXTENT_MIP1 32 -#define TILE_PIXEL_EXTENT_MIP2 16 -#define TILE_PIXEL_EXTENT_MIP3 8 -#define TILE_PIXEL_EXTENT_MIP4 4 -#define TILE_PIXEL_EXTENT_MIP5 2 -#define TILE_PIXEL_EXTENT_MIP6 1 - -Bool TileData::hasRGBDataForWidth(Int width) -{ - if (width == TILE_PIXEL_EXTENT) return(true); - if (width == TILE_PIXEL_EXTENT_MIP1) return(true); - if (width == TILE_PIXEL_EXTENT_MIP2) return(true); - if (width == TILE_PIXEL_EXTENT_MIP3) return(true); - if (width == TILE_PIXEL_EXTENT_MIP4) return(true); - if (width == TILE_PIXEL_EXTENT_MIP5) return(true); - if (width == TILE_PIXEL_EXTENT_MIP6) return(true); - return(false); -} - -UnsignedByte * TileData::getRGBDataForWidth(Int width) -{ - // default - if (width == TILE_PIXEL_EXTENT_MIP1) return(m_tileDataMip32); - if (width == TILE_PIXEL_EXTENT_MIP2) return(m_tileDataMip16); - if (width == TILE_PIXEL_EXTENT_MIP3) return(m_tileDataMip8); - if (width == TILE_PIXEL_EXTENT_MIP4) return(m_tileDataMip4); - if (width == TILE_PIXEL_EXTENT_MIP5) return(m_tileDataMip2); - if (width == TILE_PIXEL_EXTENT_MIP6) return(m_tileDataMip1); - return(m_tileData); -} - -void TileData::updateMips(void) -{ - doMip(m_tileData, TILE_PIXEL_EXTENT, m_tileDataMip32); - doMip(m_tileDataMip32, TILE_PIXEL_EXTENT_MIP1, m_tileDataMip16); - doMip(m_tileDataMip16, TILE_PIXEL_EXTENT_MIP2, m_tileDataMip8); - doMip(m_tileDataMip8, TILE_PIXEL_EXTENT_MIP3, m_tileDataMip4); - doMip(m_tileDataMip4, TILE_PIXEL_EXTENT_MIP4, m_tileDataMip2); - doMip(m_tileDataMip2, TILE_PIXEL_EXTENT_MIP5, m_tileDataMip1); -} - - -void TileData::doMip(UnsignedByte *pHiRes, Int hiRow, UnsignedByte *pLoRes) -{ - Int i, j; - for (i=0; igetNumExtraBlendTiles(), - TheTerrainRenderObject->getNumShoreLineTiles()); + unibuffer.format( L"3-Way Blends: %d/%d, Shoreline Blends: %d/%d", TheTerrainRenderObject->getNumExtraBlendTiles(TRUE), + TheTerrainRenderObject->getNumExtraBlendTiles(FALSE), + TheTerrainRenderObject->getNumShoreLineTiles(TRUE), + TheTerrainRenderObject->getNumShoreLineTiles(FALSE)); m_displayStrings[TerrainStats]->setText( unibuffer ); // misc debug info diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DRoadBuffer.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DRoadBuffer.cpp index 9b538a211e..b8d8db3d90 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DRoadBuffer.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DRoadBuffer.cpp @@ -3177,6 +3177,7 @@ void W3DRoadBuffer::loadRoads() insertCurveSegments(); insertCrossTypeJoins(); preloadRoadsInVertexAndIndexBuffers(); + m_updateBuffers = true; //ticks = ::GetTickCount() - ticks; //char buf[256]; //sprintf(buf, "%d road segs, %d milisec.\n", m_numRoads, ticks); @@ -3197,6 +3198,16 @@ void W3DRoadBuffer::updateLighting(void) } } +//============================================================================= +// W3DRoadBuffer::updateCenter +//============================================================================= +/** Sets the flag to reload the vertex buffer. */ +//============================================================================= +void W3DRoadBuffer::updateCenter(void) +{ + m_updateBuffers = true; +} + //============================================================================= // W3DRoadBuffer::drawRoads //============================================================================= diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DTerrainTracks.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DTerrainTracks.cpp deleted file mode 100644 index 7e1d5b352c..0000000000 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DTerrainTracks.cpp +++ /dev/null @@ -1,974 +0,0 @@ -/* -** Command & Conquer Generals(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) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -// FILE: W3DTerrainTracks.cpp //////////////////////////////////////////////// -//----------------------------------------------------------------------------- -// -// Westwood Studios Pacific. -// -// Confidential Information -// Copyright (C) 2001 - All Rights Reserved -// -//----------------------------------------------------------------------------- -// -// Project: RTS3 -// -// File name: W3DTerrainTracks.cpp -// -// Created: Mark Wilczynski, May 2001 -// -// Desc: Draw track marks on the terrain. Uses a sequence of connected -// quads that are oriented to fit the terrain and updated when object -// moves. -//----------------------------------------------------------------------------- - -#include "W3DDevice/GameClient/W3DTerrainTracks.h" -#include "W3DDevice/GameClient/HeightMap.h" -#include "Common/PerfTimer.h" -#include "Common/GlobalData.h" -#include "Common/Debug.h" -#include "texture.h" -#include "colmath.h" -#include "coltest.h" -#include "rinfo.h" -#include "camera.h" -#include "assetmgr.h" -#include "WW3D2/dx8wrapper.h" -#include "WW3D2/scene.h" -#include "GameLogic/TerrainLogic.h" -#include "GameLogic/Object.h" -#include "GameClient/Drawable.h" - - -#define BRIDGE_OFFSET_FACTOR 0.25f //amount to raise tracks above bridges. -//============================================================================= -// TerrainTracksRenderObjClass::~TerrainTracksRenderObjClass -//============================================================================= -/** Destructor. Releases w3d assets. */ -//============================================================================= -TerrainTracksRenderObjClass::~TerrainTracksRenderObjClass(void) -{ - freeTerrainTracksResources(); -} - -//============================================================================= -// TerrainTracksRenderObjClass::TerrainTracksRenderObjClass -//============================================================================= -/** Constructor. Just nulls out some variables. */ -//============================================================================= -TerrainTracksRenderObjClass::TerrainTracksRenderObjClass(void) -{ - m_stageZeroTexture=NULL; - m_lastAnchor=Vector3(0,1,2.25); - m_haveAnchor=false; - m_haveCap=true; - m_topIndex=0; - m_bottomIndex=0; - m_activeEdgeCount=0; - m_totalEdgesAdded=0; - m_bound=false; - m_ownerDrawable = NULL; -} - -//============================================================================= -// TerrainTracksRenderObjClass::Get_Obj_Space_Bounding_Sphere -//============================================================================= -/** WW3D method that returns object bounding sphere used in frustum culling*/ -//============================================================================= -void TerrainTracksRenderObjClass::Get_Obj_Space_Bounding_Sphere(SphereClass & sphere) const -{ /// @todo: Add code to cull track marks to screen by constantly updating bounding volumes - sphere=m_boundingSphere; -} - -//============================================================================= -// TerrainTracksRenderObjClass::Get_Obj_Space_Bounding_Box -//============================================================================= -/** WW3D method that returns object bounding box used in collision detection*/ -//============================================================================= -void TerrainTracksRenderObjClass::Get_Obj_Space_Bounding_Box(AABoxClass & box) const -{ - box=m_boundingBox; -} - -//============================================================================= -// MirrorRenderObjClass::Class_ID -//============================================================================= -/** returns the class id, so the scene can tell what kind of render object it has. */ -//============================================================================= -Int TerrainTracksRenderObjClass::Class_ID(void) const -{ - return RenderObjClass::CLASSID_IMAGE3D; -} - -//============================================================================= -// TerrainTracksRenderObjClass::Clone -//============================================================================= -/** Not used, but required virtual method. */ -//============================================================================= -RenderObjClass * TerrainTracksRenderObjClass::Clone(void) const -{ - assert(false); - return NULL; -} - -//============================================================================= -// TerrainTracksRenderObjClass::freeTerrainTracksResources -//============================================================================= -/** Free any W3D resources associated with this object */ -//============================================================================= -Int TerrainTracksRenderObjClass::freeTerrainTracksResources(void) -{ - REF_PTR_RELEASE(m_stageZeroTexture); - m_haveAnchor=false; - m_haveCap=true; - m_topIndex=0; - m_bottomIndex=0; - m_activeEdgeCount=0; - m_totalEdgesAdded=0; - m_ownerDrawable = NULL; - - return 0; -} - -//============================================================================= -// TerrainTracksRenderObjClass::init -//============================================================================= -/** Setup size settings and allocate W3D texture */ -//============================================================================= -void TerrainTracksRenderObjClass::init( Real width, Real length, const Char *texturename) -{ - freeTerrainTracksResources(); //free old data and ib/vb - - m_boundingSphere.Init(Vector3(0,0,0),400*MAP_XY_FACTOR); - m_boundingBox.Center.Set(0.0f, 0.0f, 0.0f); - m_boundingBox.Extent.Set(400.0f*MAP_XY_FACTOR, 400.0f*MAP_XY_FACTOR, 1.0f); - m_width=width; - m_length=length; - //no sense culling these things since they have very irregular shape and fade - //out over time. - Set_Force_Visible(TRUE); - m_stageZeroTexture=WW3DAssetManager::Get_Instance()->Get_Texture(texturename); -} - -//============================================================================= -// TerrainTracksRenderObjClass::addCapEdgeToTrack -//============================================================================= -/** Cap the current track (adding an feathered edge) so we're ready to resume - the track at a new location. Used by objects entering FOW where we need to - stop adding edges to the track when they enter the fog boundary but resume - elsewhere if they become visible again. -*/ -//============================================================================= -void TerrainTracksRenderObjClass::addCapEdgeToTrack(Real x, Real y) -{ - /// @todo: Have object pass its height and orientation so we can remove extra calls. - - if (m_haveCap) - { //we already have a cap or there are no segments to cap - return; - } - - if (m_activeEdgeCount == 1) - { //if we only have one edge, then it must be the current anchor edge. - //since achnors are caps, there is not point in adding another. - m_haveCap=TRUE; - m_haveAnchor=false; //recreate a new anchor when track resumes. - return; - } - - Vector3 vPos,vZ; - Coord3D vZTmp; - PathfindLayerEnum objectLayer; - Real eHeight; - - if (m_ownerDrawable && (objectLayer=m_ownerDrawable->getObject()->getLayer()) != LAYER_GROUND) - eHeight=BRIDGE_OFFSET_FACTOR+TheTerrainLogic->getLayerHeight(x,y,objectLayer,&vZTmp); - else - eHeight=TheTerrainLogic->getGroundHeight(x,y,&vZTmp); - - vZ.X = vZTmp.x; - vZ.Y = vZTmp.y; - vZ.Z = vZTmp.z; - - vPos.X=x; - vPos.Y=y; - vPos.Z=eHeight; - - Vector3 vDir=Vector3(x,y,eHeight)-m_lastAnchor; - Int maxEdgeCount=TheTerrainTracksRenderObjClassSystem->m_maxTankTrackEdges; - - //avoid sqrt() by checking distance squared since last track mark - if (vDir.Length2() < sqr(m_length)) - { //not far enough from anchor to add track - //since this is a cap, we'll force the previous segment to transparent - Int lastAddedEdge=m_topIndex-1; - if (lastAddedEdge < 0) - lastAddedEdge = maxEdgeCount-1; - m_edges[lastAddedEdge].alpha=0.0f; //force the last added edge to transparent. - m_haveCap=TRUE; - m_haveAnchor=false; //recreate a new anchor when track resumes. - return; - } - - if (m_activeEdgeCount >= maxEdgeCount) - { //no more room in buffer so release oldest edge - m_bottomIndex++; - m_activeEdgeCount--; - - if (m_bottomIndex >= maxEdgeCount) - m_bottomIndex=0; //roll buffer back to start - } - - if (m_topIndex >= maxEdgeCount) - m_topIndex=0; //roll around buffer - - //we traveled far enough from last point. - //accept new point - vDir.Z=0; //ignore height - vDir.Normalize(); - - Vector3 vX; - - Vector3::Cross_Product(vDir,vZ,&vX); - - //calculate left end point - edgeInfo& topEdge = m_edges[m_topIndex]; - - topEdge.endPointPos[0]=vPos-(m_width*0.5f*vX); ///@todo: try getting height at endpoint - topEdge.endPointPos[0].Z += 0.2f * MAP_XY_FACTOR; //raise above terrain slightly - - if (m_totalEdgesAdded&1) //every other edge has different set of UV's - { - topEdge.endPointUV[0].X=0.0f; - topEdge.endPointUV[0].Y=0.0f; - } - else - { - topEdge.endPointUV[0].X=0.0f; - topEdge.endPointUV[0].Y=1.0f; - } - - //calculate right end point - topEdge.endPointPos[1]=vPos+(m_width*0.5f*vX); ///@todo: try getting height at endpoint - topEdge.endPointPos[1].Z += 0.2f * MAP_XY_FACTOR; //raise above terrain slightly - - if (m_totalEdgesAdded&1) //every other edge has different set of UV's - { - topEdge.endPointUV[1].X=1.0f; - topEdge.endPointUV[1].Y=0.0f; - } - else - { - topEdge.endPointUV[1].X=1.0f; - topEdge.endPointUV[1].Y=1.0f; - } - - topEdge.timeAdded=WW3D::Get_Sync_Time(); - topEdge.alpha=0.0f; //fully transparent at cap. - m_lastAnchor=vPos; - m_activeEdgeCount++; - m_totalEdgesAdded++; - m_topIndex++; //make space for new edge - m_haveCap=TRUE; - m_haveAnchor=false; -} - -//============================================================================= -// TerrainTracksRenderObjClass::addEdgeToTrack -//============================================================================= -/** Try to add an additional segment to track mark. Will do nothing if distance -* from last edge is too small. Will overwrite the oldest edge if maximum track -* length is reached. Oldest edges should by faded out by that time. -*/ -//============================================================================= -void TerrainTracksRenderObjClass::addEdgeToTrack(Real x, Real y) -{ - /// @todo: Have object pass its height and orientation so we can remove extra calls. - - if (!m_haveAnchor) - { //no anchor yet, make this point an anchor. - PathfindLayerEnum objectLayer; - if (m_ownerDrawable && (objectLayer=m_ownerDrawable->getObject()->getLayer()) != LAYER_GROUND) - m_lastAnchor=Vector3(x,y,TheTerrainLogic->getLayerHeight(x,y,objectLayer)+BRIDGE_OFFSET_FACTOR); - else - m_lastAnchor=Vector3(x,y,TheTerrainLogic->getGroundHeight(x,y)); - - m_haveAnchor=true; - m_airborne = true; - m_haveCap = true; //single segment tracks are always capped because nothing is drawn. - return; - } - - m_haveCap = false; //have more than 1 segment now so will need to cap if it's interrupted. - - Vector3 vPos,vZ; - Coord3D vZTmp; - Real eHeight; - PathfindLayerEnum objectLayer; - - if (m_ownerDrawable && (objectLayer=m_ownerDrawable->getObject()->getLayer()) != LAYER_GROUND) - eHeight=BRIDGE_OFFSET_FACTOR+TheTerrainLogic->getLayerHeight(x,y,objectLayer,&vZTmp); - else - eHeight=TheTerrainLogic->getGroundHeight(x,y,&vZTmp); - - vZ.X = vZTmp.x; - vZ.Y = vZTmp.y; - vZ.Z = vZTmp.z; - - vPos.X=x; - vPos.Y=y; - vPos.Z=eHeight; - - Vector3 vDir=Vector3(x,y,eHeight)-m_lastAnchor; - - //avoid sqrt() by checking distance squared since last track mark - if (vDir.Length2() < sqr(m_length)) - return; //not far enough from anchor to add track - - Int maxEdgeCount=TheTerrainTracksRenderObjClassSystem->m_maxTankTrackEdges; - - if (m_activeEdgeCount >= maxEdgeCount) - { //no more room in buffer so release oldest edge - m_bottomIndex++; - m_activeEdgeCount--; - - if (m_bottomIndex >= maxEdgeCount) - m_bottomIndex=0; //roll buffer back to start - } - - if (m_topIndex >= maxEdgeCount) - m_topIndex=0; //roll around buffer - - //we traveled far enough from last point. - //accept new point - vDir.Z=0; //ignore height - vDir.Normalize(); - - Vector3 vX; - - Vector3::Cross_Product(vDir,vZ,&vX); - - edgeInfo& topEdge = m_edges[m_topIndex]; - - //calculate left end point - topEdge.endPointPos[0]=vPos-(m_width*0.5f*vX); ///@todo: try getting height at endpoint - topEdge.endPointPos[0].Z += 0.2f * MAP_XY_FACTOR; //raise above terrain slightly - - if (m_totalEdgesAdded&1) //every other edge has different set of UV's - { - topEdge.endPointUV[0].X=0.0f; - topEdge.endPointUV[0].Y=0.0f; - } - else - { - topEdge.endPointUV[0].X=0.0f; - topEdge.endPointUV[0].Y=1.0f; - } - - //calculate right end point - topEdge.endPointPos[1]=vPos+(m_width*0.5f*vX); ///@todo: try getting height at endpoint - topEdge.endPointPos[1].Z += 0.2f * MAP_XY_FACTOR; //raise above terrain slightly - - if (m_totalEdgesAdded&1) //every other edge has different set of UV's - { - topEdge.endPointUV[1].X=1.0f; - topEdge.endPointUV[1].Y=0.0f; - } - else - { - topEdge.endPointUV[1].X=1.0f; - topEdge.endPointUV[1].Y=1.0f; - } - - topEdge.timeAdded=WW3D::Get_Sync_Time(); - topEdge.alpha=1.0f; //fully opaque at start. - if (m_airborne || m_activeEdgeCount <= 1) { - topEdge.alpha=0.0f; //smooth out track restarts by setting transparent - } - m_airborne = false; - - m_lastAnchor=vPos; - m_activeEdgeCount++; - m_totalEdgesAdded++; - m_topIndex++; //make space for new edge -} - -//============================================================================= -// TerrainTracksRenderObjClass::Render -//============================================================================= -/** Does nothing. Just increments a counter of how many track edges were -* requested for rendering this frame. Actual rendering is done in flush(). -*/ -//============================================================================= -void TerrainTracksRenderObjClass::Render(RenderInfoClass & rinfo) -{ ///@todo: After adding track mark visibility tests, add visible marks to another list. - if (TheGlobalData->m_makeTrackMarks && m_activeEdgeCount >= 2) - TheTerrainTracksRenderObjClassSystem->m_edgesToFlush += m_activeEdgeCount; -} - -#define DEFAULT_TRACK_SPACING (MAP_XY_FACTOR * 1.4f) -#define DEFAULT_TRACK_WIDTH 4.0f; - -/**Find distance between the "trackfx" bones of the model. This tells us the correct - width for the trackmarks. -*/ -static Real computeTrackSpacing(RenderObjClass *renderObj) -{ - Real trackSpacing = DEFAULT_TRACK_SPACING; - Int leftTrack; - Int rightTrack; - - if ((leftTrack=renderObj->Get_Bone_Index( "TREADFX01" )) != 0 && (rightTrack=renderObj->Get_Bone_Index( "TREADFX02" )) != 0) - { //both bones found, determine distance between them. - Vector3 leftPos,rightPos; - leftPos=renderObj->Get_Bone_Transform( leftTrack ).Get_Translation(); - rightPos=renderObj->Get_Bone_Transform( rightTrack ).Get_Translation(); - rightPos -= leftPos; //get distance between centers of tracks - trackSpacing = rightPos.Length() + DEFAULT_TRACK_WIDTH; //add width of each track - ///@todo: It's assumed that all tank treads have the same width. - }; - - return trackSpacing; -} - -//============================================================================= -//TerrainTracksRenderObjClassSystem::bindTrack -//============================================================================= -/** Grab a track from the free store. If no free tracks exist, return NULL. - As long as a track is bound to an object (like a tank) it is ready to accept - updates with additional edges. Once it is unbound, it will expire and return - to the free store once all tracks have faded out. - - Input: width in world units of each track edge (should probably width of vehicle). - length in world units between edges. Shorter lengths produce more edges and - smoother curves. - texture to use for the tracks - image should be symetrical and include alpha channel. -*/ -//============================================================================= -TerrainTracksRenderObjClass *TerrainTracksRenderObjClassSystem::bindTrack( RenderObjClass *renderObject, Real length, const Char *texturename) -{ - TerrainTracksRenderObjClass *mod; - - mod = m_freeModules; - if( mod ) - { - // take module off the free list - if( mod->m_nextSystem ) - mod->m_nextSystem->m_prevSystem = mod->m_prevSystem; - if( mod->m_prevSystem ) - mod->m_prevSystem->m_nextSystem = mod->m_nextSystem; - else - m_freeModules = mod->m_nextSystem; - - // put module on the used list - mod->m_prevSystem = NULL; - mod->m_nextSystem = m_usedModules; - if( m_usedModules ) - m_usedModules->m_prevSystem = mod; - m_usedModules = mod; - - mod->init(computeTrackSpacing(renderObject),length,texturename); - mod->m_bound=true; - m_TerrainTracksScene->Add_Render_Object( mod); - } - - return mod; - -} - -//============================================================================= -//TerrainTracksRenderObjClassSystem::unbindTrack -//============================================================================= -/** Called when an object (i.e Tank) will not lay down any more tracks and -doesn't need this object anymore. The track-laying object will be returned -to pool of available tracks as soon as any remaining track edges have faded out. -*/ -//============================================================================= -void TerrainTracksRenderObjClassSystem::unbindTrack( TerrainTracksRenderObjClass *mod ) -{ - //this object should return to free store as soon as there is nothing - //left to render. - mod->m_bound=false; - mod->m_ownerDrawable = NULL; -} - -//============================================================================= -//TerrainTracksRenderObjClassSystem::releaseTrack -//============================================================================= -/** Returns a track laying object to free store to be used again later. -*/ -void TerrainTracksRenderObjClassSystem::releaseTrack( TerrainTracksRenderObjClass *mod ) -{ - if (mod==NULL) - return; - - DEBUG_ASSERTCRASH(mod->m_bound == false, ("mod is bound.")); - - // remove module from used list - if( mod->m_nextSystem ) - mod->m_nextSystem->m_prevSystem = mod->m_prevSystem; - if( mod->m_prevSystem ) - mod->m_prevSystem->m_nextSystem = mod->m_nextSystem; - else - m_usedModules = mod->m_nextSystem; - - // add module to free list - mod->m_prevSystem = NULL; - mod->m_nextSystem = m_freeModules; - if( m_freeModules ) - m_freeModules->m_prevSystem = mod; - m_freeModules = mod; - mod->freeTerrainTracksResources(); - m_TerrainTracksScene->Remove_Render_Object(mod); -} - -//============================================================================= -// TerrainTracksRenderObjClassSystem::TerrainTracksRenderObjClassSystem -//============================================================================= -/** Constructor. Just nulls out some variables. */ -//============================================================================= -TerrainTracksRenderObjClassSystem::TerrainTracksRenderObjClassSystem() -{ - m_usedModules = NULL; - m_freeModules = NULL; - m_TerrainTracksScene = NULL; - m_edgesToFlush = 0; - m_indexBuffer = NULL; - m_vertexMaterialClass = NULL; - m_vertexBuffer = NULL; - - m_maxTankTrackEdges=TheGlobalData->m_maxTankTrackEdges; - m_maxTankTrackOpaqueEdges=TheGlobalData->m_maxTankTrackOpaqueEdges; - m_maxTankTrackFadeDelay=TheGlobalData->m_maxTankTrackFadeDelay; -} - -//============================================================================= -// TerrainTracksRenderObjClassSystem::~TerrainTracksRenderObjClassSystem -//============================================================================= -/** Destructor. Free all pre-allocated track laying render objects*/ -//============================================================================= -TerrainTracksRenderObjClassSystem::~TerrainTracksRenderObjClassSystem( void ) -{ - - // free all data - shutdown(); - - m_vertexMaterialClass=NULL; - m_TerrainTracksScene=NULL; - -} - -//============================================================================= -// TerrainTracksRenderObjClassSystem::ReAcquireResources -//============================================================================= -/** (Re)allocates all W3D assets after a reset.. */ -//============================================================================= -void TerrainTracksRenderObjClassSystem::ReAcquireResources(void) -{ - Int i; - const Int numModules=TheGlobalData->m_maxTerrainTracks; - - // just for paranoia's sake. - REF_PTR_RELEASE(m_indexBuffer); - REF_PTR_RELEASE(m_vertexBuffer); - - //Create static index buffers. These will index the vertex buffers holding the track segments - m_indexBuffer=NEW_REF(DX8IndexBufferClass,((m_maxTankTrackEdges-1)*6)); - - // Fill up the IB - { - DX8IndexBufferClass::WriteLockClass lockIdxBuffer(m_indexBuffer); - UnsignedShort *ib=lockIdxBuffer.Get_Index_Array(); - - for (i=0; i<(m_maxTankTrackEdges-1); i++) - { - ib[3]=ib[0]=i*2; - ib[1]=i*2+1; - ib[4]=ib[2]=(i+1)*2+1; - ib[5]=(i+1)*2; - ib+=6; //skip the 6 indices we just filled - } - } - - DEBUG_ASSERTCRASH(numModules*m_maxTankTrackEdges*2 < 65535, ("Too many terrain track edges")); - - m_vertexBuffer=NEW_REF(DX8VertexBufferClass,(DX8_FVF_XYZDUV1,numModules*m_maxTankTrackEdges*2,DX8VertexBufferClass::USAGE_DYNAMIC)); -} - -//============================================================================= -// TerrainTracksRenderObjClassSystem::ReleaseResources -//============================================================================= -/** (Re)allocates all W3D assets after a reset.. */ -//============================================================================= -void TerrainTracksRenderObjClassSystem::ReleaseResources(void) -{ - REF_PTR_RELEASE(m_indexBuffer); - REF_PTR_RELEASE(m_vertexBuffer); - // Note - it is ok to not release the material, as it is a w3d object that - // has no dx8 resources. jba. -} - -//============================================================================= -// TerrainTracksRenderObjClassSystem::init -//============================================================================= -/** initialize the system, allocate all the render objects we will need */ -//============================================================================= -void TerrainTracksRenderObjClassSystem::init( SceneClass *TerrainTracksScene ) -{ - const Int numModules=TheGlobalData->m_maxTerrainTracks; - - Int i; - TerrainTracksRenderObjClass *mod; - - m_TerrainTracksScene=TerrainTracksScene; - - ReAcquireResources(); - //go with a preset material for now. - m_vertexMaterialClass=VertexMaterialClass::Get_Preset(VertexMaterialClass::PRELIT_DIFFUSE); - - //use a multi-texture shader: (text1*diffuse)*text2. - m_shaderClass = ShaderClass::_PresetAlphaShader;//_PresetATestSpriteShader;//_PresetOpaqueShader; - - // we cannot initialize a system that is already initialized - if( m_freeModules || m_usedModules ) - { - - // system already online! - assert( 0 ); - return; - - } - - // allocate our modules for this system - for( i = 0; i < numModules; i++ ) - { - - mod = NEW_REF( TerrainTracksRenderObjClass, () ); - - if( mod == NULL ) - { - - // unable to allocate modules needed - assert( 0 ); - return; - - } - - mod->m_prevSystem = NULL; - mod->m_nextSystem = m_freeModules; - if( m_freeModules ) - m_freeModules->m_prevSystem = mod; - m_freeModules = mod; - - } - -} - -//============================================================================= -// TerrainTracksRenderObjClassSystem::shutdown -//============================================================================= -/** Shutdown and free all memory for this system */ -//============================================================================= -void TerrainTracksRenderObjClassSystem::shutdown( void ) -{ - TerrainTracksRenderObjClass *nextMod,*mod; - - //release unbound tracks that may still be fading out - mod=m_usedModules; - - while(mod) - { - nextMod=mod->m_nextSystem; - - if (!mod->m_bound) - releaseTrack(mod); - - mod = nextMod; - } - - - // free all attached things and used modules - assert( m_usedModules == NULL ); - - // free all module storage - while( m_freeModules ) - { - - nextMod = m_freeModules->m_nextSystem; - REF_PTR_RELEASE (m_freeModules); - m_freeModules = nextMod; - - } - - REF_PTR_RELEASE(m_indexBuffer); - REF_PTR_RELEASE(m_vertexMaterialClass); - REF_PTR_RELEASE(m_vertexBuffer); - -} - -//============================================================================= -// TerrainTracksRenderObjClassSystem::update -//============================================================================= -/** Update the state of all active track marks - fade, expire, etc. */ -//============================================================================= -void TerrainTracksRenderObjClassSystem::update() -{ - - Int iTime=WW3D::Get_Sync_Time(); - Real iDiff; - TerrainTracksRenderObjClass *mod=m_usedModules,*nextMod; - - //first update all the tracks - while( mod ) - { - Int i,index; - Vector3 *endPoint; - Vector2 *endPointUV; - - nextMod = mod->m_nextSystem; - - if (!TheGlobalData->m_makeTrackMarks) - mod->m_haveAnchor=false; //force a track restart next time around. - - for (i=0,index=mod->m_bottomIndex; im_activeEdgeCount; i++,index++) - { - if (index >= m_maxTankTrackEdges) - index=0; - - endPoint=&mod->m_edges[index].endPointPos[0]; //left endpoint - endPointUV=&mod->m_edges[index].endPointUV[0]; - iDiff=(float)(iTime-mod->m_edges[index].timeAdded); - iDiff = 1.0f - iDiff/(Real)m_maxTankTrackFadeDelay; - if (iDiff < 0.0) - iDiff=0.0f; - if (mod->m_edges[index].alpha>0.0f) { - mod->m_edges[index].alpha=iDiff; - } - - if (iDiff == 0.0f) - { //this edge was invisible, we can remove it - mod->m_bottomIndex++; - mod->m_activeEdgeCount--; - - if (mod->m_bottomIndex >= m_maxTankTrackEdges) - mod->m_bottomIndex=0; //roll buffer back to start - } - if (mod->m_activeEdgeCount == 0 && !mod->m_bound) - releaseTrack(mod); - } - mod = nextMod; - } -} - - -//============================================================================= -// TerrainTracksRenderObjClassSystem::flush -//============================================================================= -/** Draw all active track marks for this frame */ -//============================================================================= -void TerrainTracksRenderObjClassSystem::flush() -{ -/** @todo: Optimize system by drawing tracks as triangle strips and use dynamic vertex buffer access. -May also try rendering all tracks with one call to W3D/D3D by grouping them by texture. -Try improving the fit to vertical surfaces like cliffs. -*/ - - Int diffuseLight; - TerrainTracksRenderObjClass *mod=m_usedModules; - if (!mod) - return; //nothing to render - - Int trackStartIndex; - Real distanceFade; - - if (ShaderClass::Is_Backface_Culling_Inverted()) - return; //don't render track marks in reflections. - - // adjust shading for time of day. - Real shadeR, shadeG, shadeB; - shadeR = TheGlobalData->m_terrainAmbient[0].red; - shadeG = TheGlobalData->m_terrainAmbient[0].green; - shadeB = TheGlobalData->m_terrainAmbient[0].blue; - shadeR += TheGlobalData->m_terrainDiffuse[0].red/2; - shadeG += TheGlobalData->m_terrainDiffuse[0].green/2; - shadeB += TheGlobalData->m_terrainDiffuse[0].blue/2; - shadeR*=255.0f; - shadeG*=255.0f; - shadeB*=255.0f; - - diffuseLight = REAL_TO_INT(shadeB) | (REAL_TO_INT(shadeG) << 8) | (REAL_TO_INT(shadeR) << 16); - Real numFadedEdges=m_maxTankTrackEdges-m_maxTankTrackOpaqueEdges; - - //check if there is anything to draw and fill vertex buffer - if (m_edgesToFlush >= 2) - { - DX8VertexBufferClass::WriteLockClass lockVtxBuffer(m_vertexBuffer); - VertexFormatXYZDUV1 *verts = (VertexFormatXYZDUV1*)lockVtxBuffer.Get_Vertex_Array(); - trackStartIndex=0; - - mod=m_usedModules; - //Fill our vertex buffer with all the tracks - while( mod ) - { - Int i,index; - Vector3 *endPoint; - Vector2 *endPointUV; - - if (mod->m_activeEdgeCount >= 2 && mod->Is_Really_Visible()) - { - for (i=0,index=mod->m_bottomIndex; im_activeEdgeCount; i++,index++) - { - if (index >= m_maxTankTrackEdges) - index=0; - - endPoint=&mod->m_edges[index].endPointPos[0]; //left endpoint - endPointUV=&mod->m_edges[index].endPointUV[0]; - - distanceFade=1.0f; - - if ((mod->m_activeEdgeCount -1 -i) >= m_maxTankTrackOpaqueEdges)// && i < (MAX_PER_TRACK_EDGE_COUNT-FORCE_FADE_AT_EDGE)) - { //we're getting close to the limit on the number of track pieces allowed - //so force it to fade out. - distanceFade=1.0f-(float)((mod->m_activeEdgeCount -i)-m_maxTankTrackOpaqueEdges)/numFadedEdges; - } - - distanceFade *= mod->m_edges[index].alpha; //adjust fade with distance from start of track - - verts->x=endPoint->X; - verts->y=endPoint->Y; - verts->z=endPoint->Z; - - verts->u1=endPointUV->X; - verts->v1=endPointUV->Y; - - //fade the alpha channel with distance - verts->diffuse=diffuseLight | ( REAL_TO_INT(distanceFade*255.0f) <<24); - verts++; - - endPoint=&mod->m_edges[index].endPointPos[1]; //right endpoint - endPointUV=&mod->m_edges[index].endPointUV[1]; - - verts->x=endPoint->X; - verts->y=endPoint->Y; - verts->z=endPoint->Z; - - verts->u1=endPointUV->X; - verts->v1=endPointUV->Y; ///@todo: Add diffuse lighting. - - verts->diffuse=diffuseLight | ( REAL_TO_INT(distanceFade*255.0f) <<24); - verts++; - } - } - mod = mod->m_nextSystem; - } - } - - //draw the filled vertex buffers - if (m_edgesToFlush >= 2) - { - ShaderClass::Invalidate(); - DX8Wrapper::Set_Material(m_vertexMaterialClass); - DX8Wrapper::Set_Shader(m_shaderClass); - DX8Wrapper::Set_Index_Buffer(m_indexBuffer,0); - DX8Wrapper::Set_Vertex_Buffer(m_vertexBuffer); - - trackStartIndex=0; - mod=m_usedModules; - Matrix3D tm(mod->Transform); - DX8Wrapper::Set_Transform(D3DTS_WORLD,tm); - while (mod) - { - if (mod->m_activeEdgeCount >= 2 && mod->Is_Really_Visible()) - { - DX8Wrapper::Set_Texture(0,mod->m_stageZeroTexture); - DX8Wrapper::Set_Index_Buffer_Index_Offset(trackStartIndex); - DX8Wrapper::Draw_Triangles( 0,(mod->m_activeEdgeCount-1)*2, 0, mod->m_activeEdgeCount*2); - - trackStartIndex += mod->m_activeEdgeCount*2; - } - mod=mod->m_nextSystem; - } - } - - m_edgesToFlush=0; //reset count for next flush -} - -/**Removes all remaining tracks from the rendering system*/ -void TerrainTracksRenderObjClassSystem::Reset(void) -{ - TerrainTracksRenderObjClass *nextMod,*mod=m_usedModules; - - while(mod) - { - nextMod=mod->m_nextSystem; - - releaseTrack(mod); - - mod = nextMod; - } - - - // free all attached things and used modules - assert( m_usedModules == NULL ); - m_edgesToFlush=0; -} - -/**Clear the treads from each track laying object without freeing the objects. -Mostly used when user changed LOD level*/ -void TerrainTracksRenderObjClassSystem::clearTracks(void) -{ - TerrainTracksRenderObjClass *mod=m_usedModules; - - while(mod) - { - mod->m_haveAnchor=false; - mod->m_haveCap=true; - mod->m_topIndex=0; - mod->m_bottomIndex=0; - mod->m_activeEdgeCount=0; - mod->m_totalEdgesAdded=0; - - mod = mod->m_nextSystem; - } - - m_edgesToFlush=0; -} - -/**Adjust various paremeters which affect the cost of rendering tracks on the map. -Parameters are passed via GlobalData*/ -void TerrainTracksRenderObjClassSystem::setDetail(void) -{ - //Remove all existing track segments from screen. - clearTracks(); - ReleaseResources(); - - m_maxTankTrackEdges=TheGlobalData->m_maxTankTrackEdges; - m_maxTankTrackOpaqueEdges=TheGlobalData->m_maxTankTrackOpaqueEdges; - m_maxTankTrackFadeDelay=TheGlobalData->m_maxTankTrackFadeDelay; - - //We changed the maximum number of visible edges so re-allocate our resources to match. - ReAcquireResources(); -}; - -TerrainTracksRenderObjClassSystem *TheTerrainTracksRenderObjClassSystem=NULL; ///< singleton for track drawing system. diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DTerrainVisual.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DTerrainVisual.cpp deleted file mode 100644 index 1119bea537..0000000000 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DTerrainVisual.cpp +++ /dev/null @@ -1,818 +0,0 @@ -/* -** Command & Conquer Generals(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) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -// FILE: W3DTerrainVisual.cpp ///////////////////////////////////////////////////////////////////// -// W3D implementation details for visual aspects of terrain -// Author: Colin Day, April 2001 -/////////////////////////////////////////////////////////////////////////////////////////////////// - -#include -#include - -#include "Common/GameState.h" -#include "Common/GlobalData.h" -#include "Common/PerfTimer.h" -#include "Common/MapReaderWriterInfo.h" -#include "Common/ThingTemplate.h" -#include "Common/WellKnownKeys.h" -#include "Common/TerrainTypes.h" -#include "Common/Xfer.h" -#include "GameClient/Drawable.h" -#include "GameLogic/Object.h" -#include "W3DDevice/GameClient/W3DScene.h" -#include "W3DDevice/GameClient/W3DTerrainVisual.h" -#include "W3DDevice/GameClient/WorldHeightMap.h" -#include "W3DDevice/GameClient/W3DWater.h" -#include "W3DDevice/GameClient/W3DDisplay.h" -#include "W3DDevice/GameClient/W3DDebugIcons.h" -#include "W3DDevice/GameClient/W3DTerrainTracks.h" -#include "W3DDevice/GameClient/W3DShadow.h" -#include "W3DDevice/GameClient/HeightMap.h" -#include "WW3D2/light.h" -#include "WW3D2/rendobj.h" -#include "WW3D2/coltype.h" -#include "WW3D2/coltest.h" -#include "WW3D2/assetmgr.h" - -#include "Common/UnitTimings.h" //Contains the DO_UNIT_TIMINGS define jba. -//------------------------------------------------------------------------------------------------- -//------------------------------------------------------------------------------------------------- -W3DTerrainVisual::W3DTerrainVisual() -{ - - m_terrainRenderObject = NULL; - m_terrainHeightMap = NULL; - m_waterRenderObject = NULL; - TheWaterRenderObj = NULL; - -} - -//------------------------------------------------------------------------------------------------- -//------------------------------------------------------------------------------------------------- -W3DTerrainVisual::~W3DTerrainVisual() -{ - // release our render object - if (TheTerrainRenderObject == m_terrainRenderObject) { - TheTerrainRenderObject = NULL; - } - - delete TheTerrainTracksRenderObjClassSystem; - TheTerrainTracksRenderObjClassSystem=NULL; - - delete TheW3DShadowManager; - TheW3DShadowManager=NULL; - - REF_PTR_RELEASE( m_waterRenderObject ); - TheWaterRenderObj=NULL; - REF_PTR_RELEASE( m_terrainRenderObject ); - REF_PTR_RELEASE( m_terrainHeightMap ); -} - -//------------------------------------------------------------------------------------------------- -/** init */ -//------------------------------------------------------------------------------------------------- -void W3DTerrainVisual::init( void ) -{ - - // extend - TerrainVisual::init(); - // create a new render object for W3D - m_terrainRenderObject = NEW_REF( HeightMapRenderObjClass, () ); - m_terrainRenderObject->Set_Collision_Type( PICK_TYPE_TERRAIN ); - TheTerrainRenderObject = m_terrainRenderObject; - - if (!TheGlobalData->m_headless) - { - // initialize track drawing system - TheTerrainTracksRenderObjClassSystem = NEW TerrainTracksRenderObjClassSystem; - TheTerrainTracksRenderObjClassSystem->init(W3DDisplay::m_3DScene); - - // initialize object shadow drawing system - TheW3DShadowManager = NEW W3DShadowManager; - TheW3DShadowManager->init(); - - // create a water plane render object - TheWaterRenderObj=m_waterRenderObject = NEW_REF( WaterRenderObjClass, () ); - m_waterRenderObject->init(TheGlobalData->m_waterPositionZ, TheGlobalData->m_waterExtentX, TheGlobalData->m_waterExtentY, W3DDisplay::m_3DScene, (WaterRenderObjClass::WaterType)TheGlobalData->m_waterType); //create a water plane that's 128x128 units - m_waterRenderObject->Set_Position(Vector3(TheGlobalData->m_waterPositionX,TheGlobalData->m_waterPositionY,TheGlobalData->m_waterPositionZ)); //place water in world - -#ifdef DO_UNIT_TIMINGS -#pragma MESSAGE("********************* WARNING- Doing UNIT TIMINGS. ") -#else - if (TheGlobalData->m_waterType == WaterRenderObjClass::WATER_TYPE_1_FB_REFLECTION) - { // add water render object to the pre-pass scene (to be rendered before main scene) - //W3DDisplay::m_prePass3DScene->Add_Render_Object( m_waterRenderObject); - } - else - { // add water render object to the post-pass scene (to be rendered after main scene) - W3DDisplay::m_3DScene->Add_Render_Object( m_waterRenderObject); - } -#endif - if (TheGlobalData->m_useCloudPlane) - m_waterRenderObject->toggleCloudLayer(true); - else - m_waterRenderObject->toggleCloudLayer(false); - } - - // set the vertex animated water properties - Int waterSettingIndex = 0; // use index 0 settings by default - TheTerrainVisual->setWaterGridHeightClamps( NULL, - TheGlobalData->m_vertexWaterHeightClampLow[ waterSettingIndex ], - TheGlobalData->m_vertexWaterHeightClampHi[ waterSettingIndex ] ); - TheTerrainVisual->setWaterTransform( NULL, - TheGlobalData->m_vertexWaterAngle[ waterSettingIndex ], - TheGlobalData->m_vertexWaterXPosition[ waterSettingIndex ], - TheGlobalData->m_vertexWaterYPosition[ waterSettingIndex ], - TheGlobalData->m_vertexWaterZPosition[ waterSettingIndex ] ); - TheTerrainVisual->setWaterGridResolution( NULL, - TheGlobalData->m_vertexWaterXGridCells[ waterSettingIndex ], - TheGlobalData->m_vertexWaterYGridCells[ waterSettingIndex ], - TheGlobalData->m_vertexWaterGridSize[ waterSettingIndex ] ); - TheTerrainVisual->setWaterAttenuationFactors( NULL, - TheGlobalData->m_vertexWaterAttenuationA[ waterSettingIndex ], - TheGlobalData->m_vertexWaterAttenuationB[ waterSettingIndex ], - TheGlobalData->m_vertexWaterAttenuationC[ waterSettingIndex ], - TheGlobalData->m_vertexWaterAttenuationRange[ waterSettingIndex ] ); - m_isWaterGridRenderingEnabled = FALSE; - -} - -//------------------------------------------------------------------------------------------------- -/** reset */ -//------------------------------------------------------------------------------------------------- -void W3DTerrainVisual::reset( void ) -{ - - // extend - TerrainVisual::reset(); - - m_terrainRenderObject->reset(); - - if (TheW3DShadowManager) - TheW3DShadowManager->Reset(); - - if (TheTerrainTracksRenderObjClassSystem) - TheTerrainTracksRenderObjClassSystem->Reset(); - - // reset water render object if present - if( m_waterRenderObject ) - { - for (Int i=0; i<5; i++) - { - //check if this texture was ever changed from default - if (m_currentSkyboxTexNames[i] != m_initialSkyboxTexNames[i]) - { - m_waterRenderObject->replaceSkyboxTexture(m_currentSkyboxTexNames[i], m_initialSkyboxTexNames[i]); - m_currentSkyboxTexNames[i]=m_initialSkyboxTexNames[i]; //update current state to new texture - } - } - - m_waterRenderObject->reset(); - } - -} - -//------------------------------------------------------------------------------------------------- -/** update */ -//------------------------------------------------------------------------------------------------- -void W3DTerrainVisual::update( void ) -{ - - // extend - TerrainVisual::update(); - - // if we have a water render object, it has an update method - if( m_waterRenderObject ) - m_waterRenderObject->update(); - -} - -//------------------------------------------------------------------------------------------------- -/** load method for W3D visual terrain */ -//------------------------------------------------------------------------------------------------- -Bool W3DTerrainVisual::load( AsciiString filename ) -{ - -#if 0 - // (gth) Testing exclusion list asset releasing - DynamicVectorClass exclusion_list(8000); - - WW3DAssetManager::Get_Instance()->Create_Asset_List(exclusion_list); - - exclusion_list.Add(StringClass("avcomanche")); - exclusion_list.Add(StringClass("avcomanche_d")); - exclusion_list.Add(StringClass("ptdogwood08")); - exclusion_list.Add(StringClass("ptdogwood01_b")); - exclusion_list.Add(StringClass("ptpalm01")); - exclusion_list.Add(StringClass("ptpalm01_b")); - exclusion_list.Add(StringClass("avhummer")); - exclusion_list.Add(StringClass("avhummer_d")); - exclusion_list.Add(StringClass("avleopard")); - exclusion_list.Add(StringClass("avleopard_d")); - - WW3DAssetManager::Get_Instance()->Free_Assets_With_Exclusion_List(exclusion_list); -#endif - - // enhancing functionality specific for W3D terrain - if( TerrainVisual::load( filename ) == FALSE ) - return FALSE; // failed - - // open the terrain file - CachedFileInputStream fileStrm; - if( !fileStrm.open(filename) ) - { - - REF_PTR_RELEASE( m_terrainRenderObject ); - return FALSE; - - } - - if( m_terrainRenderObject == NULL ) - return FALSE; - - REF_PTR_RELEASE( m_terrainHeightMap ); - ChunkInputStream *pStrm = &fileStrm; - // allocate new height map data to read from file - m_terrainHeightMap = NEW WorldHeightMap(pStrm); - - // Add any lights loaded by map. - MapObject *pMapObj = MapObject::getFirstMapObject(); - while (pMapObj) - { - Dict *d = pMapObj->getProperties(); - if (pMapObj->isLight()) - { - Coord3D loc = *pMapObj->getLocation(); - if (loc.z < 0) { - Vector3 vec; - loc.z = m_terrainRenderObject->getHeightMapHeight(loc.x, loc.y, NULL); - loc.z += d->getReal(TheKey_lightHeightAboveTerrain); - } - // It is a light, and handled at the device level. jba. - LightClass* lightP = NEW_REF(LightClass, (LightClass::POINT)); - - RGBColor c; - c.setFromInt(d->getInt(TheKey_lightAmbientColor)); - lightP->Set_Ambient( Vector3( c.red, c.green, c.blue ) ); - - c.setFromInt(d->getInt(TheKey_lightDiffuseColor)); - lightP->Set_Diffuse( Vector3( c.red, c.green, c.blue) ); - - lightP->Set_Position(Vector3(loc.x, loc.y, loc.z)); - - lightP->Set_Far_Attenuation_Range(d->getReal(TheKey_lightInnerRadius), d->getReal(TheKey_lightOuterRadius)); - W3DDisplay::m_3DScene->Add_Render_Object(lightP); - REF_PTR_RELEASE( lightP ); - } - pMapObj = pMapObj->getNext(); - } - - - RefRenderObjListIterator *it = W3DDisplay::m_3DScene ? W3DDisplay::m_3DScene->createLightsIterator() : NULL; - // apply the heightmap to the terrain render object - m_terrainRenderObject->initHeightData( m_terrainHeightMap->getDrawWidth(), - m_terrainHeightMap->getDrawHeight(), - m_terrainHeightMap, - it); - if (it) { - W3DDisplay::m_3DScene->destroyLightsIterator(it); - it = NULL; - } - // add our terrain render object to the scene - if (W3DDisplay::m_3DScene != NULL) - W3DDisplay::m_3DScene->Add_Render_Object( m_terrainRenderObject ); - -#if defined(RTS_DEBUG) - // Icon drawing utility object for pathfinding. - if (W3DDisplay::m_3DScene != NULL) - { - W3DDebugIcons *icons = NEW W3DDebugIcons; - W3DDisplay::m_3DScene->Add_Render_Object( icons ); - icons->Release_Ref(); // belongs to scene. - } -#endif - -#ifdef DO_UNIT_TIMINGS -#pragma MESSAGE("********************* WARNING- Doing UNIT TIMINGS. ") -#else - if (m_waterRenderObject) - { - W3DDisplay::m_3DScene->Add_Render_Object( m_waterRenderObject); - m_waterRenderObject->enableWaterGrid(false); - } -#endif - - pMapObj = MapObject::getFirstMapObject(); - while (pMapObj) - { - Dict *d = pMapObj->getProperties(); - if (pMapObj->isScorch()) { - const Coord3D *pos = pMapObj->getLocation(); - Vector3 loc(pos->x, pos->y, pos->z); - Real radius = d->getReal(TheKey_objectRadius); - Scorches type = (Scorches)d->getInt(TheKey_scorchType); - m_terrainRenderObject->addScorch(loc, radius, type); - } - pMapObj = pMapObj->getNext(); - } - - // reset water render object if present - if( m_waterRenderObject ) - { - m_waterRenderObject->load(); - } - - return TRUE; // success - -} - -// ------------------------------------------------------------------------------------------------ -// ------------------------------------------------------------------------------------------------ -void W3DTerrainVisual::enableWaterGrid( Bool enable ) -{ - - //Get default water type - m_isWaterGridRenderingEnabled = enable; - - // make the changes in the water render object - if( m_waterRenderObject ) - m_waterRenderObject->enableWaterGrid( enable ); - -} - -//------------------------------------------------------------------------------------------------- -/** intersect the ray with the terrain, if a hit occurs TRUE is returned - * and the result point on the terrain is returned in "result" */ -//------------------------------------------------------------------------------------------------- -Bool W3DTerrainVisual::intersectTerrain( Coord3D *rayStart, - Coord3D *rayEnd, - Coord3D *result ) -{ - Bool hit = FALSE; - - // sanity - if( rayStart == NULL || rayEnd == NULL ) - return hit; - - if( m_terrainRenderObject ) - { - CastResultStruct res; - LineSegClass lineSeg( Vector3( rayStart->x, rayStart->y, rayStart->z ), - Vector3( rayEnd->x, rayEnd->y, rayEnd->z ) ); - RayCollisionTestClass rayTest( lineSeg, &res ); - - hit = m_terrainRenderObject->Cast_Ray( rayTest ); - if( hit && result ) - { - Vector3 point = rayTest.Result->ContactPoint; - - result->x = point.X; - result->y = point.Y; - result->z = point.Z; - - } - - } - - // return hit result - return hit; - -} - -//------------------------------------------------------------------------------------------------- -//------------------------------------------------------------------------------------------------- -void W3DTerrainVisual::getTerrainColorAt( Real x, Real y, RGBColor *pColor ) -{ - - if( m_terrainHeightMap ) - m_terrainHeightMap->getTerrainColorAt( x, y, pColor ); - -} - -//------------------------------------------------------------------------------------------------- -//------------------------------------------------------------------------------------------------- -TerrainType *W3DTerrainVisual::getTerrainTile( Real x, Real y ) -{ - TerrainType *tile = NULL; - - if( m_terrainHeightMap ) - { - AsciiString tileName = m_terrainHeightMap->getTerrainNameAt( x, y ); - - tile = TheTerrainTypes->findTerrain( tileName ); - - } - - return tile; - -} - -// ------------------------------------------------------------------------------------------------ -/** set min/max height values allowed in water grid pointed to by waterTable */ -// ------------------------------------------------------------------------------------------------ -void W3DTerrainVisual::setWaterGridHeightClamps( const WaterHandle *waterTable, - Real minZ, Real maxZ ) -{ - - if( m_waterRenderObject ) - m_waterRenderObject->setGridHeightClamps( minZ, maxZ ); - -} - -// ------------------------------------------------------------------------------------------------ -/** adjust fallof parameters for grid change method */ -// ------------------------------------------------------------------------------------------------ -void W3DTerrainVisual::setWaterAttenuationFactors( const WaterHandle *waterTable, - Real a, Real b, Real c, Real range ) -{ - - if( m_waterRenderObject ) - m_waterRenderObject->setGridChangeAttenuationFactors( a, b, c, range ); - -} - -// ------------------------------------------------------------------------------------------------ -/** set the water table position and orientation in world space */ -// ------------------------------------------------------------------------------------------------ -void W3DTerrainVisual::setWaterTransform( const WaterHandle *waterTable, - Real angle, Real x, Real y, Real z ) -{ - - if( m_waterRenderObject ) - m_waterRenderObject->setGridTransform( angle, x, y, z ); - -} - -// ------------------------------------------------------------------------------------------------ -/** set water table transform by matrix */ -// ------------------------------------------------------------------------------------------------ -void W3DTerrainVisual::setWaterTransform( const Matrix3D *transform ) -{ - - if( m_waterRenderObject ) - m_waterRenderObject->setGridTransform( transform ); - -} - -// ------------------------------------------------------------------------------------------------ -/** get the water transform matrix */ -// ------------------------------------------------------------------------------------------------ -void W3DTerrainVisual::getWaterTransform( const WaterHandle *waterTable, Matrix3D *transform ) -{ - - if( m_waterRenderObject ) - m_waterRenderObject->getGridTransform( transform ); - -} - -// ------------------------------------------------------------------------------------------------ -/** water grid resolution spacing */ -// ------------------------------------------------------------------------------------------------ -void W3DTerrainVisual::setWaterGridResolution( const WaterHandle *waterTable, - Real gridCellsX, Real gridCellsY, Real cellSize ) -{ - - if( m_waterRenderObject ) - m_waterRenderObject->setGridResolution( gridCellsX, gridCellsY, cellSize ); - -} - -// ------------------------------------------------------------------------------------------------ -/** get water grid resolution spacing */ -// ------------------------------------------------------------------------------------------------ -void W3DTerrainVisual::getWaterGridResolution( const WaterHandle *waterTable, - Real *gridCellsX, Real *gridCellsY, Real *cellSize ) -{ - - if( m_waterRenderObject ) - m_waterRenderObject->getGridResolution( gridCellsX, gridCellsY, cellSize ); - -} - -// ------------------------------------------------------------------------------------------------ -/** adjust the water grid in world coords by the delta */ -// ------------------------------------------------------------------------------------------------ -void W3DTerrainVisual::changeWaterHeight( Real x, Real y, Real delta ) -{ - - if( m_waterRenderObject ) - m_waterRenderObject->changeGridHeight( x, y, delta ); - -} - -// ------------------------------------------------------------------------------------------------ -// ------------------------------------------------------------------------------------------------ -void W3DTerrainVisual::addWaterVelocity( Real worldX, Real worldY, - Real velocity, Real preferredHeight ) -{ - - if( m_waterRenderObject ) - m_waterRenderObject->addVelocity( worldX, worldY, velocity, preferredHeight ); - -} - -// ------------------------------------------------------------------------------------------------ -// ------------------------------------------------------------------------------------------------ -Bool W3DTerrainVisual::getWaterGridHeight( Real worldX, Real worldY, Real *height) -{ - Real gridX, gridY; - - if (m_isWaterGridRenderingEnabled && m_waterRenderObject && - m_waterRenderObject->worldToGridSpace(worldX, worldY, gridX, gridY)) - { //point falls within grid, return correct height - m_waterRenderObject->getGridVertexHeight(REAL_TO_INT(gridX),REAL_TO_INT(gridY),height); - return TRUE; - } - return FALSE; -} - -// ------------------------------------------------------------------------------------------------ -// ------------------------------------------------------------------------------------------------ -void W3DTerrainVisual::setRawMapHeight(const ICoord2D *gridPos, Int height) -{ - if (m_terrainHeightMap) { - Int x = gridPos->x+m_terrainHeightMap->getBorderSize(); - Int y = gridPos->y+m_terrainHeightMap->getBorderSize(); - //if (m_terrainHeightMap->getHeight(x,y) != height) //ML changed to prevent scissoring with roads - if (m_terrainHeightMap->getHeight(x,y) > height) - { - m_terrainHeightMap->setRawHeight(x, y, height); - m_terrainRenderObject->staticLightingChanged(); - } - } -} - -// ------------------------------------------------------------------------------------------------ -// ------------------------------------------------------------------------------------------------ -void W3DTerrainVisual::addFactionBibDrawable(Drawable *factionBuilding, Bool highlight, Real extra) -{ - if (m_terrainHeightMap) { - const Matrix3D * mtx = factionBuilding->getTransformMatrix(); - Vector3 corners[4]; - Coord3D pos; - pos.set(0,0,0); - Real exitWidth = factionBuilding->getTemplate()->getFactoryExitWidth(); - Real extraWidth = factionBuilding->getTemplate()->getFactoryExtraBibWidth() + extra; - const GeometryInfo info = factionBuilding->getTemplate()->getTemplateGeometryInfo(); - Real sizeX = info.getMajorRadius(); - Real sizeY = info.getMinorRadius(); - if (info.getGeomType() != GEOMETRY_BOX) { - sizeY = sizeX; - } - corners[0].Set(pos.x, pos.y, pos.z); - corners[0].X -= sizeX+extraWidth; - corners[0].Y -= sizeY+extraWidth; - corners[1].Set(pos.x, pos.y, pos.z); - corners[1].X += sizeX+exitWidth+extraWidth; - corners[1].Y -= sizeY+extraWidth; - corners[2].Set(pos.x, pos.y, pos.z); - corners[2].X += sizeX+exitWidth+extraWidth; - corners[2].Y += sizeY+extraWidth; - corners[3].Set(pos.x, pos.y, pos.z); - corners[3].X -= sizeX+extraWidth; - corners[3].Y += sizeY+extraWidth; - mtx->Transform_Vector(*mtx, corners[0], &corners[0]); - mtx->Transform_Vector(*mtx, corners[1], &corners[1]); - mtx->Transform_Vector(*mtx, corners[2], &corners[2]); - mtx->Transform_Vector(*mtx, corners[3], &corners[3]); - m_terrainRenderObject->addTerrainBibDrawable(corners, factionBuilding->getID(), highlight); - } -} - -// ------------------------------------------------------------------------------------------------ -// ------------------------------------------------------------------------------------------------ -void W3DTerrainVisual::addFactionBib(Object *factionBuilding, Bool highlight, Real extra) -{ - if (m_terrainHeightMap) { - const Matrix3D * mtx = factionBuilding->getTransformMatrix(); - Vector3 corners[4]; - Coord3D pos; - pos.set(0,0,0); - Real exitWidth = factionBuilding->getTemplate()->getFactoryExitWidth(); - Real extraWidth = factionBuilding->getTemplate()->getFactoryExtraBibWidth() + extra; - const GeometryInfo info = factionBuilding->getGeometryInfo(); - Real sizeX = info.getMajorRadius(); - Real sizeY = info.getMinorRadius(); - if (info.getGeomType() != GEOMETRY_BOX) { - sizeY = sizeX; - } - corners[0].Set(pos.x, pos.y, pos.z); - corners[0].X -= sizeX+extraWidth; - corners[0].Y -= sizeY+extraWidth; - corners[1].Set(pos.x, pos.y, pos.z); - corners[1].X += sizeX+exitWidth+extraWidth; - corners[1].Y -= sizeY+extraWidth; - corners[2].Set(pos.x, pos.y, pos.z); - corners[2].X += sizeX+exitWidth+extraWidth; - corners[2].Y += sizeY+extraWidth; - corners[3].Set(pos.x, pos.y, pos.z); - corners[3].X -= sizeX+extraWidth; - corners[3].Y += sizeY+extraWidth; - mtx->Transform_Vector(*mtx, corners[0], &corners[0]); - mtx->Transform_Vector(*mtx, corners[1], &corners[1]); - mtx->Transform_Vector(*mtx, corners[2], &corners[2]); - mtx->Transform_Vector(*mtx, corners[3], &corners[3]); - m_terrainRenderObject->addTerrainBib(corners, factionBuilding->getID(), highlight); - } -} - -// ------------------------------------------------------------------------------------------------ -// ------------------------------------------------------------------------------------------------ -void W3DTerrainVisual::removeFactionBibDrawable(Drawable *factionBuilding) -{ - if (m_terrainHeightMap) { - m_terrainRenderObject->removeTerrainBibDrawable(factionBuilding->getID()); - } -} - -// ------------------------------------------------------------------------------------------------ -// ------------------------------------------------------------------------------------------------ -void W3DTerrainVisual::removeFactionBib(Object *factionBuilding) -{ - if (m_terrainHeightMap) { - m_terrainRenderObject->removeTerrainBib(factionBuilding->getID()); - } -} - -// ------------------------------------------------------------------------------------------------ -// ------------------------------------------------------------------------------------------------ -void W3DTerrainVisual::removeAllBibs(void) -{ - if (m_terrainHeightMap) { - m_terrainRenderObject->removeAllTerrainBibs(); - } -} - -// ------------------------------------------------------------------------------------------------ -// ------------------------------------------------------------------------------------------------ -void W3DTerrainVisual::removeBibHighlighting(void) -{ - if (m_terrainHeightMap) { - m_terrainRenderObject->removeTerrainBibHighlighting(); - } -} - -// ------------------------------------------------------------------------------------------------ -// ------------------------------------------------------------------------------------------------ -void W3DTerrainVisual::setTerrainTracksDetail(void) -{ - if (TheTerrainTracksRenderObjClassSystem) - TheTerrainTracksRenderObjClassSystem->setDetail(); -} - -// ------------------------------------------------------------------------------------------------ -// ------------------------------------------------------------------------------------------------ -void W3DTerrainVisual::setShoreLineDetail(void) -{ - if (m_terrainRenderObject) - m_terrainRenderObject->setShoreLineDetail(); -} - -// ------------------------------------------------------------------------------------------------ -// ------------------------------------------------------------------------------------------------ -/// Replace the skybox texture -void W3DTerrainVisual::replaceSkyboxTextures(const AsciiString *oldTexName[5], const AsciiString *newTexName[5]) -{ - if (m_waterRenderObject) - { - for (Int i=0; i<5; i++) - { - //check if this texture was never changed before and is still using the default art. - if (m_initialSkyboxTexNames[i].isEmpty()) - { m_initialSkyboxTexNames[i]=*oldTexName[i]; - m_currentSkyboxTexNames[i]=*oldTexName[i]; - } - - if (m_currentSkyboxTexNames[i] != *newTexName[i]) - { m_waterRenderObject->replaceSkyboxTexture(m_currentSkyboxTexNames[i], *newTexName[i]); - m_currentSkyboxTexNames[i]=*newTexName[i]; //update current state to new texture - } - } - } -} - -// ------------------------------------------------------------------------------------------------ -/** CRC */ -// ------------------------------------------------------------------------------------------------ -void W3DTerrainVisual::crc( Xfer *xfer ) -{ - - // extend base class - TerrainVisual::crc( xfer ); - -} - -// ------------------------------------------------------------------------------------------------ -/** Xfer - * Version Info: - * 1: Initial version */ -// ------------------------------------------------------------------------------------------------ -void W3DTerrainVisual::xfer( Xfer *xfer ) -{ - - // version - XferVersion currentVersion = 2; - XferVersion version = currentVersion; - xfer->xferVersion( &version, currentVersion ); - - // extend base class - TerrainVisual::xfer( xfer ); - - // flag for whether or not the water grid is enabled - Bool gridEnabled = m_isWaterGridRenderingEnabled; - xfer->xferBool( &gridEnabled ); - if( gridEnabled != m_isWaterGridRenderingEnabled ) - { - - DEBUG_CRASH(( "W3DTerrainVisual::xfer - m_isWaterGridRenderingEnabled mismatch" )); - throw SC_INVALID_DATA; - - } - - // xfer grid data if enabled - if( gridEnabled ) - xfer->xferSnapshot( m_waterRenderObject ); - -/* - { - - // grid width and height - Int width = getGridWidth(); - Int height = getGridheight(); - xfer->xferInt( &width ); - xfer->xferInt( &height ); - if( width != getGridWidth() ) - { - - DEBUG_CRASH(( "W3DTerainVisual::xfer - grid width mismatch '%d' should be '%d'", - width, getGridWidth() )); - throw SC_INVALID_DATA; - - } - if( height != getGridHeight() ) - { - - DEBUG_CRASH(( "W3DTerainVisual::xfer - grid height mismatch '%d' should be '%d'", - height, getGridHeight() )); - throw SC_INVALID_DATA; - - } - - // write data for each grid - - } -*/ - - // Write out the terrain height data. - if (version >= 2) { - UnsignedByte *data = m_terrainHeightMap->getDataPtr(); - Int len = m_terrainHeightMap->getXExtent()*m_terrainHeightMap->getYExtent(); - Int xferLen = len; - xfer->xferInt(&xferLen); - if (len!=xferLen) { - DEBUG_CRASH(("Bad height map length.")); - if (len>xferLen) { - len = xferLen; - } - } - xfer->xferUser(data, len); - if (xfer->getXferMode() == XFER_LOAD) { - // Update the display height map. - m_terrainRenderObject->staticLightingChanged(); - } - } - -} - -// ------------------------------------------------------------------------------------------------ -/** Load post process */ -// ------------------------------------------------------------------------------------------------ -void W3DTerrainVisual::loadPostProcess( void ) -{ - - // extend base class - TerrainVisual::loadPostProcess(); - -} - diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DTreeBuffer.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DTreeBuffer.cpp deleted file mode 100644 index b609f4dde5..0000000000 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DTreeBuffer.cpp +++ /dev/null @@ -1,693 +0,0 @@ -/* -** Command & Conquer Generals(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) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -// FILE: W3DTreeBuffer.cpp //////////////////////////////////////////////// -//----------------------------------------------------------------------------- -// -// Westwood Studios Pacific. -// -// Confidential Information -// Copyright (C) 2001 - All Rights Reserved -// -//----------------------------------------------------------------------------- -// -// Project: RTS3 -// -// File name: W3DTreeBuffer.cpp -// -// Created: John Ahlquist, May 2001 -// -// Desc: Draw buffer to handle all the trees in a scene. -// -//----------------------------------------------------------------------------- - -//----------------------------------------------------------------------------- -// Includes -//----------------------------------------------------------------------------- -#include "W3DDevice/GameClient/W3DTreeBuffer.h" - -#include -#include -#include "Common/GameUtility.h" -#include "Common/GlobalData.h" -#include "GameClient/ClientRandomValue.h" -#include "W3DDevice/GameClient/TerrainTex.h" -#include "W3DDevice/GameClient/HeightMap.h" -#include "W3DDevice/GameClient/W3DDynamicLight.h" -#include "WW3D2/camera.h" -#include "WW3D2/dx8wrapper.h" -#include "WW3D2/dx8renderer.h" -#include "WW3D2/mesh.h" -#include "WW3D2/meshmdl.h" - -//----------------------------------------------------------------------------- -// Private Data -//----------------------------------------------------------------------------- -// A W3D shader that does alpha, texturing, tests zbuffer, doesn't update zbuffer. -#define SC_ALPHA_DETAIL ( SHADE_CNST(ShaderClass::PASS_LEQUAL, ShaderClass::DEPTH_WRITE_DISABLE, ShaderClass::COLOR_WRITE_ENABLE, ShaderClass::SRCBLEND_SRC_ALPHA, \ - ShaderClass::DSTBLEND_ONE_MINUS_SRC_ALPHA, ShaderClass::FOG_DISABLE, ShaderClass::GRADIENT_MODULATE, ShaderClass::SECONDARY_GRADIENT_DISABLE, ShaderClass::TEXTURING_ENABLE, \ - ShaderClass::ALPHATEST_DISABLE, ShaderClass::CULL_MODE_DISABLE, \ - ShaderClass::DETAILCOLOR_DISABLE, ShaderClass::DETAILALPHA_DISABLE) ) - -static ShaderClass detailAlphaShader(SC_ALPHA_DETAIL); - - -/* -#define SC_ALPHA_MIRROR ( SHADE_CNST(ShaderClass::PASS_LEQUAL, ShaderClass::DEPTH_WRITE_DISABLE, ShaderClass::COLOR_WRITE_ENABLE, ShaderClass::SRCBLEND_SRC_ALPHA, \ - ShaderClass::DSTBLEND_ONE_MINUS_SRC_ALPHA, ShaderClass::FOG_DISABLE, ShaderClass::GRADIENT_MODULATE, ShaderClass::SECONDARY_GRADIENT_DISABLE, ShaderClass::TEXTURING_ENABLE, \ - ShaderClass::DETAILCOLOR_DISABLE, ShaderClass::DETAILALPHA_DISABLE, ShaderClass::ALPHATEST_DISABLE, ShaderClass::CULL_MODE_DISABLE, \ - ShaderClass::DETAILCOLOR_DISABLE, ShaderClass::DETAILALPHA_DISABLE) ) - -static ShaderClass mirrorAlphaShader(SC_ALPHA_DETAIL); - -// ShaderClass::PASS_ALWAYS, - -#define SC_ALPHA_2D ( SHADE_CNST(PASS_ALWAYS, DEPTH_WRITE_DISABLE, COLOR_WRITE_ENABLE, \ - SRCBLEND_SRC_ALPHA, DSTBLEND_ONE_MINUS_SRC_ALPHA, FOG_DISABLE, GRADIENT_DISABLE, \ - SECONDARY_GRADIENT_DISABLE, TEXTURING_ENABLE, DETAILCOLOR_DISABLE, DETAILALPHA_DISABLE, \ - ALPHATEST_DISABLE, CULL_MODE_ENABLE, DETAILCOLOR_DISABLE, DETAILALPHA_DISABLE) ) -ShaderClass ShaderClass::_PresetAlpha2DShader(SC_ALPHA_2D); -*/ -//----------------------------------------------------------------------------- -// Private Functions -//----------------------------------------------------------------------------- - -//============================================================================= -// W3DTreeBuffer::cull -//============================================================================= -/** Culls the trees, marking the visible flag. If a tree becomes visible, it sets -it's sortKey */ -//============================================================================= -void W3DTreeBuffer::cull(CameraClass * camera) -{ - Int curTree; - - m_anythingChanged = false; - // Calulate the vector direction that the camera is looking at. - Matrix3D camera_matrix = camera->Get_Transform(); - float zmod = -1; - float x = zmod * camera_matrix[0][2] ; - float y = zmod * camera_matrix[1][2] ; - float z = zmod * camera_matrix[2][2] ; - m_cameraLookAtVector.Set(x,y,z); - - for (curTree=0; curTreeCull_Sphere(m_trees[curTree].bounds); - if (visible!=m_trees[curTree].visible) { - m_trees[curTree].visible=visible; - m_anythingChanged = true; - if (visible) { - doKey = true; - } - } - // Also calculate sort key if a tree is visible, and the view changed setting m_updateAllKeys to true. - if (doKey || (visible&&m_updateAllKeys)) { - // The sort key is essentially the distance of location in the direction of the - // camera look at. - m_trees[curTree].sortKey = Vector3::Dot_Product(m_trees[curTree].location, m_cameraLookAtVector); - } - } - m_updateAllKeys = false; -} - -//============================================================================= -// W3DTreeBuffer::cullMirror -//============================================================================= -/** Culls the trees, marking the visible flag for the mirror view. Unlike cull(), -doesn't update anything except the visible flag. */ -//============================================================================= -void W3DTreeBuffer::cullMirror(CameraClass * camera) -{ - Int curTree; - m_anythingChanged = false; - for (curTree=0; curTreeCull_Sphere(m_trees[curTree].bounds); - m_trees[curTree].visible=visible; - } -} - -//============================================================================= -// W3DTreeBuffer::sort -//============================================================================= -/** Sorts the trees. Does num_iterations of a bubble sort. This is good because -it ends immediately if the trees are already sorted (which is most of the time) -and will perform a fixed amount of work each frame until it becomes sorted. */ -//============================================================================= -void W3DTreeBuffer::sort(Int numIterations) -{ - // sort in descending order. - Int iter; - Bool swap = false; - for (iter = 0; iter m_trees[i].sortKey) { - TTree tmp = m_trees[cur]; - m_trees[cur] = m_trees[i]; - m_trees[i] = tmp; - swap = true; - } - cur = i; - } - } - if (!swap) { - return; - } - m_anythingChanged = true; - } -} - -//============================================================================= -// W3DTreeBuffer::doLighting -//============================================================================= -/** Calculates the diffuse lighting as affected by dynamic lighting. */ -//============================================================================= -Int W3DTreeBuffer::doLighting(Vector3 *loc, Real r, Real g, Real b, SphereClass &bounds, RefRenderObjListIterator *pDynamicLightsIterator) -{ - if (pDynamicLightsIterator == NULL) { - return(REAL_TO_INT(b) | (REAL_TO_INT(g) << 8) | (REAL_TO_INT(r) << 16) | (255 << 24)); - } - Real shadeR, shadeG, shadeB; - shadeR = r; - shadeG = g; - shadeB = b; - Bool didLight = false; - for (pDynamicLightsIterator->First(); !pDynamicLightsIterator->Is_Done(); pDynamicLightsIterator->Next()) - { - W3DDynamicLight *pLight = (W3DDynamicLight*)pDynamicLightsIterator->Peek_Obj(); - if (!pLight->isEnabled()) { - continue; // he is turned off. - } - if (CollisionMath::Overlap_Test(bounds, pLight->Get_Bounding_Sphere()) == CollisionMath::OUTSIDE) { - continue; // this tree is outside of the light's influence. - } - Vector3 lightDirection = *loc; - Real factor; - switch(pLight->Get_Type()) { - case LightClass::POINT: - case LightClass::SPOT: { - Vector3 lightLoc = pLight->Get_Position(); - lightDirection -= lightLoc; - double range, midRange; - pLight->Get_Far_Attenuation_Range(midRange, range); - Real dist = lightDirection.Length(); - if (dist >= range) continue; - if (midRange < 0.1) continue; - factor = 1.0f - (dist - midRange) / (range - midRange); - factor = WWMath::Clamp(factor,0.0f,1.0f); - } - break; - case LightClass::DIRECTIONAL: - pLight->Get_Spot_Direction(lightDirection); - factor = 1.0; - break; - }; - Real shade = 0.5f * factor; // Assume adjustment for diffuse. - Vector3 vDiffuse; - pLight->Get_Diffuse(&vDiffuse); - Vector3 ambient; - pLight->Get_Ambient(&ambient); - if (shade > 1.0) shade = 1.0; - if(shade < 0.0f) shade = 0.0f; - shadeR += shade*vDiffuse.X; - shadeG += shade*vDiffuse.Y; - shadeB += shade*vDiffuse.Z; - shadeR += factor*ambient.X; - shadeG += factor*ambient.Y; - shadeB += factor*ambient.Z; - didLight = true; - } - if (!didLight) { - return(REAL_TO_INT(b) | (REAL_TO_INT(g) << 8) | (REAL_TO_INT(r) << 16) | (255 << 24)); - } - if (shadeR > 1.0) shadeR = 1.0; - if(shadeR < 0.0f) shadeR = 0.0f; - if (shadeG > 1.0) shadeG = 1.0; - if(shadeG < 0.0f) shadeG = 0.0f; - if (shadeB > 1.0) shadeB = 1.0; - if(shadeB < 0.0f) shadeB = 0.0f; - shadeR*=255.0f; - shadeG*=255.0f; - shadeB*=255.0f; - return(REAL_TO_INT(shadeB) | (REAL_TO_INT(shadeG) << 8) | (REAL_TO_INT(shadeR) << 16) | (255 << 24)); -} - -//============================================================================= -// W3DTreeBuffer::loadTreesInVertexAndIndexBuffers -//============================================================================= -/** Loads the trees into the vertex buffer for drawing. */ -//============================================================================= -void W3DTreeBuffer::loadTreesInVertexAndIndexBuffers(RefRenderObjListIterator *pDynamicLightsIterator) -{ - if (!m_indexTree || !m_vertexTree || !m_initialized) { - return; - } - if (!m_anythingChanged) { - //return; - } - m_curNumTreeVertices = 0; - m_curNumTreeIndices = 0; - VertexFormatXYZDUV1 *vb; - UnsignedShort *ib; - // Lock the buffers. - DX8IndexBufferClass::WriteLockClass lockIdxBuffer(m_indexTree); - DX8VertexBufferClass::WriteLockClass lockVtxBuffer(m_vertexTree); - vb=(VertexFormatXYZDUV1*)lockVtxBuffer.Get_Vertex_Array(); - ib = lockIdxBuffer.Get_Index_Array(); - // Add to the index buffer & vertex buffer. - Vector2 lookAtVector(m_cameraLookAtVector.X, m_cameraLookAtVector.Y); - lookAtVector.Normalize(); - // We draw from back to front, so we put the indexes in the buffer - // from back to front. - UnsignedShort *curIb = ib+MAX_TREE_INDEX; - - VertexFormatXYZDUV1 *curVb = vb; - - Int curTree; - - // Calculate a static lighting value to use for all the trees. - Real shadeR, shadeG, shadeB; - shadeR = TheGlobalData->m_terrainAmbient[0].red; - shadeG = TheGlobalData->m_terrainAmbient[0].green; - shadeB = TheGlobalData->m_terrainAmbient[0].blue; - shadeR += TheGlobalData->m_terrainDiffuse[0].red; - shadeG += TheGlobalData->m_terrainDiffuse[0].green; - shadeB += TheGlobalData->m_terrainDiffuse[0].blue; - if (shadeR>1.0f) shadeR=1.0f; - if (shadeG>1.0f) shadeG=1.0f; - if (shadeB>1.0f) shadeB=1.0f; - shadeR*=255.0f; - shadeG*=255.0f; - shadeB*=255.0f; - - for (curTree=0; curTreeFirst(); !pDynamicLightsIterator->Is_Done(); pDynamicLightsIterator->Next()) - { - W3DDynamicLight *pLight = (W3DDynamicLight*)pDynamicLightsIterator->Peek_Obj(); - if (!pLight->isEnabled()) { - continue; // he is turned off. - } - if (CollisionMath::Overlap_Test(m_trees[curTree].bounds, pLight->Get_Bounding_Sphere()) == CollisionMath::OUTSIDE) { - continue; // this tree is outside of the light's influence. - } - doVertexLighting = true; - } -#endif - - Int diffuse = 0; - if (!doVertexLighting) { - diffuse = doLighting(&loc, shadeR, shadeG, shadeB, m_trees[curTree].bounds, NULL); - } - - Real typeOffset = type*0.5; - Int startVertex = m_curNumTreeVertices; - Int i, j; - Int numVertex = m_typeMesh[type]->Peek_Model()->Get_Vertex_Count(); - Vector3 *pVert = m_typeMesh[type]->Peek_Model()->Get_Vertex_Array(); - // If we happen to have too many trees, stop. - if (m_curNumTreeVertices+numVertex+2>= MAX_TREE_VERTEX) { - break; - } - Int numIndex = m_typeMesh[type]->Get_Model()->Get_Polygon_Count(); - const Vector3i *pPoly = m_typeMesh[type]->Get_Model()->Get_Polygon_Array(); - if (m_curNumTreeIndices+3*numIndex+6 >= MAX_TREE_INDEX) { - break; - } - - const Vector2*uvs=m_typeMesh[type]->Get_Model()->Get_UV_Array_By_Index(0); - - // If we are doing reduced resolution terrain, do reduced - // poly trees. - Bool doPanel = (TheGlobalData->m_useHalfHeightMap || TheGlobalData->m_stretchTerrain); - - if (doPanel) { - if (m_trees[curTree].rotates) { - theSin = -lookAtVector.X; - theCos = lookAtVector.Y; - } - // panel start is index offset, there are 3 index per triangle. - if (m_trees[curTree].panelStart/3 + 2 > numIndex) { - continue; // not enought polygons for the offset. jba. - } - for (j=0; j<6; j++) { - i = ((Int *)pPoly)[j+m_trees[curTree].panelStart]; - if (m_curNumTreeVertices >= MAX_TREE_VERTEX) - break; - - // Update the uv values. The W3D models each have their own texture, and - // we use one texture with all images in one, so we have to change the uvs to - // match. - Real U, V; - if (type==SHRUB) { - // shrub texture is tucked in the corner - U = ((512-64)+uvs[i].U*64.0f)/512.0f; - V = ((256-64)+uvs[i].V*64.0f)/256.0f; - } else if (type==FENCE) { - U = uvs[i].U*0.5f; - V = 1.0f + uvs[i].V; - } else { - U = typeOffset+uvs[i].U*0.5f; - V = uvs[i].V; - } - curVb->u1 = U; - curVb->v1 = V/2.0; - Vector3 vLoc; - vLoc.X = pVert[i].X*scale*theCos - pVert[i].Z*scale*theSin; - vLoc.Y = pVert[i].Z*scale*theCos + pVert[i].X*scale*theSin; - - vLoc.X += loc.X; - vLoc.Y += loc.Y; - vLoc.Z = loc.Z + pVert[i].Y*scale; // In W3D z is up, in 3dMax y is up. - - curVb->x = vLoc.X; - curVb->y = vLoc.Y; - curVb->z = vLoc.Z; - if (doVertexLighting) { - curVb->diffuse = doLighting(&vLoc, shadeR, shadeG, shadeB, m_trees[curTree].bounds, pDynamicLightsIterator); - } else { - curVb->diffuse = diffuse; - } - curVb++; - m_curNumTreeVertices++; - } - - for (i=0; i<6; i++) { - if (m_curNumTreeIndices+4 > MAX_TREE_INDEX) - break; - curIb--; - *curIb = startVertex + i; - m_curNumTreeIndices++; - } - } else { - for (i=0; i= MAX_TREE_VERTEX) - break; - - // Update the uv values. The W3D models each have their own texture, and - // we use one texture with all images in one, so we have to change the uvs to - // match. - Real U, V; - if (type==SHRUB) { - // shrub texture is tucked in the corner - U = ((512-64)+uvs[i].U*64.0f)/512.0f; - V = ((256-64)+uvs[i].V*64.0f)/256.0f; - } else if (type==FENCE) { - U = uvs[i].U*0.5f; - V = 1.0f + uvs[i].V; - } else { - U = typeOffset+uvs[i].U*0.5f; - V = uvs[i].V; - } - curVb->u1 = U; - curVb->v1 = V/2.0; - Vector3 vLoc; - vLoc.X = pVert[i].X*scale*theCos - pVert[i].Z*scale*theSin; - vLoc.Y = pVert[i].Z*scale*theCos + pVert[i].X*scale*theSin; - - vLoc.X += loc.X; - vLoc.Y += loc.Y; - vLoc.Z = loc.Z + pVert[i].Y*scale; // In W3D z is up, in 3dMax y is up. - - curVb->x = vLoc.X; - curVb->y = vLoc.Y; - curVb->z = vLoc.Z; - if (doVertexLighting) { - curVb->diffuse = doLighting(&vLoc, shadeR, shadeG, shadeB, m_trees[curTree].bounds, pDynamicLightsIterator); - } else { - curVb->diffuse = diffuse; - } - curVb++; - m_curNumTreeVertices++; - } - - for (i=0; i MAX_TREE_INDEX) - break; - curIb-=3; - *curIb++ = startVertex + pPoly[i].I; - *curIb++ = startVertex + pPoly[i].J; - *curIb++ = startVertex + pPoly[i].K; - curIb-=3; - m_curNumTreeIndices+=3; - } - } - } - m_curTreeIndexOffset = curIb - ib; -} - -//----------------------------------------------------------------------------- -// Public Functions -//----------------------------------------------------------------------------- - -//============================================================================= -// W3DTreeBuffer::~W3DTreeBuffer -//============================================================================= -/** Destructor. Releases w3d assets. */ -//============================================================================= -W3DTreeBuffer::~W3DTreeBuffer(void) -{ - freeTreeBuffers(); - REF_PTR_RELEASE(m_treeTexture); - Int i; - for (i=0; iGet_Filter().Set_U_Addr_Mode(TextureFilterClass::TEXTURE_ADDRESS_CLAMP); - m_treeTexture->Get_Filter().Set_V_Addr_Mode(TextureFilterClass::TEXTURE_ADDRESS_CLAMP); - for (i=0; iCreate_Render_Obj("ALPINETREE.TREE 1" ); - break; - case 1: - m_typeMesh[i] = (MeshClass*)WW3DAssetManager::Get_Instance()->Create_Render_Obj("DECIDUOUS.TREE 1" ); - break; - case 2: - m_typeMesh[i] = (MeshClass*)WW3DAssetManager::Get_Instance()->Create_Render_Obj("SHRUB.TREE 1" ); - break; - case 3: - m_typeMesh[i] = (MeshClass*)WW3DAssetManager::Get_Instance()->Create_Render_Obj("FENCE.PLANE09" ); - break; - } - if (m_typeMesh[i] == NULL) continue; - Int numVertex = m_typeMesh[i]->Peek_Model()->Get_Vertex_Count(); - Vector3 *pVert = m_typeMesh[i]->Peek_Model()->Get_Vertex_Array(); - - const Matrix3D xfm = m_typeMesh[i]->Get_Transform(); - SphereClass bounds(pVert, numVertex); - // Model is in y up format, so swap y and z. - Real tmp; - tmp = bounds.Center.Y; - bounds.Center.Y = bounds.Center.Z; - bounds.Center.Z = tmp; - m_typeBounds[i] = bounds; - } - if (m_typeMesh[0] == NULL) { - - //DEBUG_LOG("!!!!!!!!!!!!*************** W3DTreeBuffer failed to initialize."); - return; // didn't initialize. - } - m_initialized = true; -} - - -//============================================================================= -// W3DTreeBuffer::freeTreeBuffers -//============================================================================= -/** Frees the index and vertex buffers. */ -//============================================================================= -void W3DTreeBuffer::freeTreeBuffers(void) -{ - REF_PTR_RELEASE(m_vertexTree); - REF_PTR_RELEASE(m_indexTree); -} - -//============================================================================= -// W3DTreeBuffer::allocateTreeBuffers -//============================================================================= -/** Allocates the index and vertex buffers. */ -//============================================================================= -void W3DTreeBuffer::allocateTreeBuffers(void) -{ - m_vertexTree=NEW_REF(DX8VertexBufferClass,(DX8_FVF_XYZDUV1,MAX_TREE_VERTEX+4,DX8VertexBufferClass::USAGE_DYNAMIC)); - m_indexTree=NEW_REF(DX8IndexBufferClass,(2*MAX_TREE_INDEX+4, DX8IndexBufferClass::USAGE_DYNAMIC)); - m_curNumTreeVertices=0; - m_curNumTreeIndices=0; -} - -//============================================================================= -// W3DTreeBuffer::clearAllTrees -//============================================================================= -/** Removes all trees. */ -//============================================================================= -void W3DTreeBuffer::clearAllTrees(void) -{ - m_numTrees=0; -} - -//============================================================================= -// W3DTreeBuffer::addTree -//============================================================================= -/** Adds a tree. Name is the W3D model name, supported models are -ALPINE, DECIDUOUS and SHRUB. */ -//============================================================================= -void W3DTreeBuffer::addTree(Coord3D loc, Real scale, Real angle, AsciiString name, Bool mirrorVisible) -{ - if (m_numTrees >= MAX_TREES) { - return; - } - - if (!m_initialized) { - return; - } - - TTreeType treeType = ALPINE_TREE; - if (!name.compare("DECIDUOUS")) { - treeType = DECIDUOUS_TREE; - } else if (!name.compare("SHRUB")) { - treeType = SHRUB; - } else if (!name.compare("FENCE")) { - treeType = FENCE; - } - m_trees[m_numTrees].panelStart = 0; - Real randomScale = GameClientRandomValueReal( 0.7f, 1.3f ); - if (treeType == FENCE) { - // Fences don't randomly scale & orient - m_trees[m_numTrees].sin = WWMath::Sin(angle); - m_trees[m_numTrees].scale = scale; - m_trees[m_numTrees].cos = WWMath::Cos(angle); - m_trees[m_numTrees].rotates = false; - m_trees[m_numTrees].panelStart = 48; - } else { - // Randomizes the scale and orientation of trees. - m_trees[m_numTrees].sin = GameClientRandomValueReal( -1.0f, 1.0f ); - m_trees[m_numTrees].scale = scale*randomScale; - m_trees[m_numTrees].cos = WWMath::Sqrt(1.0 - m_trees[m_numTrees].sin*m_trees[m_numTrees].sin); - m_trees[m_numTrees].rotates = true; - } - m_trees[m_numTrees].location = Vector3(loc.x, loc.y, loc.z); - m_trees[m_numTrees].treeType = treeType; - // Translate the bounding sphere of the model. - m_trees[m_numTrees].bounds = m_typeBounds[treeType]; - m_trees[m_numTrees].bounds.Center *= scale; - m_trees[m_numTrees].bounds.Radius *= scale; - m_trees[m_numTrees].bounds.Center += m_trees[m_numTrees].location; - // Initially set it invisible. cull will update it's visiblity flag. - m_trees[m_numTrees].visible = false; - m_trees[m_numTrees].mirrorVisible = mirrorVisible; - m_numTrees++; -} - - -//============================================================================= -// W3DTreeBuffer::drawTrees -//============================================================================= -/** Draws the trees. Uses camera to cull. */ -//============================================================================= -void W3DTreeBuffer::drawTrees(CameraClass * camera, RefRenderObjListIterator *pDynamicLightsIterator) -{ - if (!m_isTerrainPass) { - return; - } - m_isTerrainPass = false; - - if (ShaderClass::Is_Backface_Culling_Inverted()) { - // Mirror inverts backface culling. - cullMirror(camera); - } else { - // Normal draw. - cull(camera); - // Only sort once per frame. - sort(SORT_ITERATIONS_PER_FRAME); - } - loadTreesInVertexAndIndexBuffers(pDynamicLightsIterator); - - if (m_curNumTreeIndices == 0) { - return; - } - // Setup the vertex buffer, shader & texture. - DX8Wrapper::Set_Index_Buffer(m_indexTree,0); - DX8Wrapper::Set_Vertex_Buffer(m_vertexTree); - DX8Wrapper::Set_Shader(detailAlphaShader); - DX8Wrapper::Set_Texture(0,m_treeTexture); - // Draw all the trees. - DX8Wrapper::Draw_Triangles( m_curTreeIndexOffset, m_curNumTreeIndices/3, 0, m_curNumTreeVertices); -} - - diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/WorldHeightMap.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/WorldHeightMap.cpp deleted file mode 100644 index 38eb63b462..0000000000 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/WorldHeightMap.cpp +++ /dev/null @@ -1,2163 +0,0 @@ -/* -** Command & Conquer Generals(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) 2001-2003 Electronic Arts Inc. // -// // -//////////////////////////////////////////////////////////////////////////////// - -// WorldHeightMap.cpp -// Class to encapsulate height map. -// Author: John Ahlquist, April 2001 - -#define INSTANTIATE_WELL_KNOWN_KEYS - -#include "windows.h" -#include "stdlib.h" -#include "Common/STLTypedefs.h" - -#include "Common/DataChunk.h" -//#include "Common/GameFileSystem.h" -#include "Common/FileSystem.h" // for LOAD_TEST_ASSETS -#include "Common/GlobalData.h" -#include "Common/MapReaderWriterInfo.h" -#include "Common/TerrainTypes.h" -#include "Common/ThingFactory.h" -#include "Common/ThingTemplate.h" -#include "Common/WellKnownKeys.h" - -#include "GameLogic/PolygonTrigger.h" -#include "GameLogic/SidesList.h" - -#include "W3DDevice/GameClient/WorldHeightMap.h" -#include "W3DDevice/GameClient/TileData.h" -#include "W3DDevice/GameClient/HeightMap.h" -#include "W3DDevice/GameClient/TerrainTex.h" -#include "W3DDevice/GameClient/W3DShadow.h" - -#include "Common/file.h" - -#define K_OBSOLETE_HEIGHT_MAP_VERSION 8 - -#define PATHFIND_CLIFF_SLOPE_LIMIT_F 9.8f - -// ----------------------------------------------------------- -static AsciiString validateName(AsciiString n, Int flags) -{ - - return n; - -} - -/* ********* GDIFileStream class ****************************/ -class GDIFileStream : public InputStream -{ -protected: - File* m_file; -public: - GDIFileStream(File* pFile):m_file(pFile) {}; - virtual Int read(void *pData, Int numBytes) { - return(m_file->read(pData, numBytes)); - }; -}; - - -/* ********* MapObject class ****************************/ -/*static*/ MapObject *MapObject::TheMapObjectListPtr = NULL; -/*static*/ Dict MapObject::TheWorldDict; - -MapObject::MapObject(Coord3D loc, AsciiString name, Real angle, Int flags, const Dict* props, - const ThingTemplate *thingTemplate ) -{ - m_objectName = validateName( name, flags ); - m_thingTemplate = thingTemplate; - m_nextMapObject = NULL; - m_location = loc; - m_angle = normalizeAngle(angle); - m_color = (0xff)<<8; // Bright green. - m_flags = flags; - m_renderObj = NULL; - m_shadowObj = NULL; - m_runtimeFlags = 0; - - if (props) - { - m_properties = *props; - if (thingTemplate && !props->known(TheKey_objectSelectable, Dict::DICT_BOOL)) { - Bool selectable = thingTemplate->isKindOf(KINDOF_SELECTABLE); - m_properties.setBool(TheKey_objectSelectable, selectable); - } - } - else - { - m_properties.setInt(TheKey_objectInitialHealth, 100); - m_properties.setBool(TheKey_objectEnabled, true); - m_properties.setBool(TheKey_objectIndestructible, false); - m_properties.setBool(TheKey_objectUnsellable, false); - m_properties.setBool(TheKey_objectPowered, true); - m_properties.setBool(TheKey_objectRecruitableAI, true); - m_properties.setBool(TheKey_objectTargetable, false ); - - Bool selectable = false; - if (thingTemplate) { - selectable = thingTemplate->isKindOf(KINDOF_SELECTABLE); - } - m_properties.setBool(TheKey_objectSelectable, selectable); - } - - for( Int i = 0; i < BRIDGE_MAX_TOWERS; ++i ) - setBridgeRenderObject( (BridgeTowerType)i, NULL ); - -} - - -MapObject::~MapObject(void) -{ - setRenderObj(NULL); - setShadowObj(NULL); - if (m_nextMapObject) { - MapObject *cur = m_nextMapObject; - MapObject *next; - while (cur) { - next = cur->getNext(); - cur->setNextMap(NULL); // prevents recursion. - deleteInstance(cur); - cur = next; - } - } - for( Int i = 0; i < BRIDGE_MAX_TOWERS; ++i ) - setBridgeRenderObject( (BridgeTowerType)i, NULL ); - -} - -MapObject *MapObject::duplicate(void) -{ - MapObject *pObj = newInstance( MapObject)(m_location, m_objectName, m_angle, m_flags, &m_properties, m_thingTemplate); - pObj->setColor(getColor()); - pObj->m_runtimeFlags = m_runtimeFlags; - return pObj; -} - -void MapObject::setRenderObj(RenderObjClass *pObj) -{ - REF_PTR_SET(m_renderObj, pObj); -} - -void MapObject::setBridgeRenderObject( BridgeTowerType type, RenderObjClass* renderObj ) -{ - - if( type >= 0 && type < BRIDGE_MAX_TOWERS ) - REF_PTR_SET( m_bridgeTowers[ type ], renderObj ); - -} - -RenderObjClass* MapObject::getBridgeRenderObject( BridgeTowerType type ) -{ - - if( type >= 0 && type < BRIDGE_MAX_TOWERS ) - return m_bridgeTowers[ type ]; - return NULL; - -} - -void MapObject::validate(void) -{ - verifyValidTeam(); - verifyValidUniqueID(); -} - -void MapObject::verifyValidTeam(void) -{ - // if this map object has a valid team, then do nothing. - // if it has an invalid team, the place it on the default neutral team, (by clearing the - // existing team name.) - Bool exists; - AsciiString teamName = getProperties()->getAsciiString(TheKey_originalOwner, &exists); - if (exists) { - Bool valid = false; - - int numSides = TheSidesList->getNumTeams(); - - for (int i = 0; i < numSides; ++i) { - TeamsInfo *teamInfo = TheSidesList->getTeamInfo(i); - if (!teamInfo) { - continue; - } - - Bool itBetter; - AsciiString testAgainstTeamName = teamInfo->getDict()->getAsciiString(TheKey_teamName, &itBetter); - if (itBetter) { - if (testAgainstTeamName.compare(teamName) == 0) { - valid = true; - } - } - } - - if (!valid) { - getProperties()->remove(TheKey_originalOwner); - } - } -} - -void MapObject::verifyValidUniqueID(void) -{ - Bool exists; - AsciiString uniqueID = getProperties()->getAsciiString(TheKey_uniqueID, &exists); - MapObject *obj = MapObject::getFirstMapObject(); - - // -1 is the sentinel - int highestIndex = -1; - - while (obj) { - if (obj == this) { - // the first object is THIS OBJECT, cause we've already been added. - obj = obj->getNext(); - continue; - } - - if (obj->isWaypoint()) { - // waypoints throw this off. Sad but true. :-( - obj = obj->getNext(); - continue; - } - - Bool iterateExists; - AsciiString tempStr = obj->getProperties()->getAsciiString(TheKey_uniqueID, &iterateExists); - const char* lastSpace = tempStr.reverseFind(' '); - - int testIndex = -1; - if (lastSpace) { - testIndex = atoi(lastSpace); - } - - if (testIndex > highestIndex) { - highestIndex = testIndex; - } - break; - } - - int indexOfThisObject = highestIndex + 1; - - const char* thingName; - if (getThingTemplate()) { - thingName = getThingTemplate()->getName().str(); - } else if (isWaypoint()) { - thingName = getWaypointName().str(); - } else { - thingName = getName().str(); - } - const char* pName = thingName; - - while (*thingName) { - if ((*thingName) == '/') { - pName = thingName + 1; - } - ++thingName; - } - - AsciiString newID; - if (isWaypoint()) { - newID.format("%s", pName); - } else { - newID.format("%s %d", pName, indexOfThisObject); - } - getProperties()->setAsciiString(TheKey_uniqueID, newID); -} - -void MapObject::fastAssignAllUniqueIDs(void) -{ - // here's what we do. Take all of them, push them onto a stack. Then, pop each one, setting its id. - // should be much faster than what we currently do. - - MapObject *pMapObj = getFirstMapObject(); - - std::stack objStack; - Int actualNumObjects = 0; - - while (pMapObj) { - ++actualNumObjects; - objStack.push(pMapObj); - pMapObj = pMapObj->getNext(); - } - - Int indexOfThisObject = 0; - while (actualNumObjects) { - MapObject *obj = objStack.top(); - - - const char* thingName; - if (obj->getThingTemplate()) { - thingName = obj->getThingTemplate()->getName().str(); - } else if (obj->isWaypoint()) { - thingName = obj->getWaypointName().str(); - } else { - thingName = obj->getName().str(); - } - const char* pName = thingName; - - while (*thingName) { - if ((*thingName) == '/') { - pName = thingName + 1; - } - ++thingName; - } - - AsciiString newID; - if (obj->isWaypoint()) { - newID.format("%s", pName); - } else { - newID.format("%s %d", pName, indexOfThisObject); - } - - obj->getProperties()->setAsciiString(TheKey_uniqueID, newID); - objStack.pop(); - - ++indexOfThisObject; - --actualNumObjects; - } -} - - - -void MapObject::setThingTemplate(const ThingTemplate *thing) -{ - m_thingTemplate = thing; - m_objectName = thing->getName(); -} - - -void MapObject::setName(AsciiString name) -{ - m_objectName = name; -} - -WaypointID MapObject::getWaypointID() { return (WaypointID)getProperties()->getInt(TheKey_waypointID); } -AsciiString MapObject::getWaypointName() { return getProperties()->getAsciiString(TheKey_waypointName); } -void MapObject::setWaypointID(Int i) { getProperties()->setInt(TheKey_waypointID, i); } -void MapObject::setWaypointName(AsciiString n) { getProperties()->setAsciiString(TheKey_waypointName, n); } - -/*static */ Int MapObject::countMapObjectsWithOwner(const AsciiString& n) -{ - Int count = 0; - for (MapObject *pMapObj = MapObject::getFirstMapObject(); pMapObj; pMapObj = pMapObj->getNext()) - { - if (pMapObj->getProperties()->getAsciiString(TheKey_originalOwner) == n) - ++count; - } - return count; -} - -//------------------------------------------------------------------------------------------------- -const ThingTemplate *MapObject::getThingTemplate( void ) const -{ - if (m_thingTemplate) - return (const ThingTemplate*) m_thingTemplate->getFinalOverride(); - - return NULL; -} - - -/* ********* WorldHeightMap class ****************************/ - - -// -// WorldHeightMap destructor . -// -WorldHeightMap::~WorldHeightMap(void) -{ - delete[](m_data); - m_data = NULL; - - delete[](m_tileNdxes); - m_tileNdxes = NULL; - - delete[](m_blendTileNdxes); - m_blendTileNdxes = NULL; - - delete[](m_extraBlendTileNdxes); - m_extraBlendTileNdxes = NULL; - - delete[](m_cliffInfoNdxes); - m_cliffInfoNdxes = NULL; - - delete[](m_cellFlipState); - m_cellFlipState = NULL; - - delete[](m_cellCliffState); - m_cellCliffState = NULL; - - int i; - for (i=0; iclear(); -} - - -/** - WorldHeightMap - create a new height map for class WorldHeightMap. - Note that there is 1 m_numBlendedTiles, which is the implied - transparent tile for non-blended tiles. -*/ -WorldHeightMap::WorldHeightMap(): - m_width(0), m_height(0), m_dataSize(0), m_data(NULL), m_cellFlipState(NULL), - m_drawOriginX(0), m_drawOriginY(0), - m_numTextureClasses(0), - m_drawWidthX(NORMAL_DRAW_WIDTH), m_drawHeightY(NORMAL_DRAW_HEIGHT), - m_tileNdxes(NULL), m_blendTileNdxes(NULL), m_extraBlendTileNdxes(NULL), m_cliffInfoNdxes(NULL), - m_terrainTexHeight(1), m_alphaTexHeight(1), m_cellCliffState(NULL), -#ifdef EVAL_TILING_MODES - m_tileMode(TILE_4x4), -#endif - m_numCliffInfo(1), - m_terrainTex(NULL), m_alphaTerrainTex(NULL), m_numBitmapTiles(0), m_numBlendedTiles(1) -{ - Int i; - for (i=0; ivalidateSides(); -} - -#ifdef EVAL_TILING_MODES -static Bool ParseFunkyTilingDataChunk(DataChunkInput &file, DataChunkInfo *info, void *userData) -{ - WorldHeightMap *pThis = (WorldHeightMap *)userData; - *((Int *)&pThis->m_tileMode) = file.readInt(); - return true; -} -#endif - -/** -* WorldHeightMap - read a height map from a file. -* Format is Chunky. -* -* Input: ChunkInputStream, -* -*/ -WorldHeightMap::WorldHeightMap(ChunkInputStream *pStrm, Bool logicalDataOnly): - m_width(0), m_height(0), m_dataSize(0), m_data(NULL), m_cellFlipState(NULL), - m_drawOriginX(0), m_cellCliffState(NULL), m_drawOriginY(0), - m_numTextureClasses(0), - m_drawWidthX(NORMAL_DRAW_WIDTH), m_drawHeightY(NORMAL_DRAW_HEIGHT), - m_tileNdxes(NULL), m_blendTileNdxes(NULL), m_extraBlendTileNdxes(NULL), m_cliffInfoNdxes(NULL), - m_terrainTexHeight(1), m_alphaTexHeight(1), -#ifdef EVAL_TILING_MODES - m_tileMode(TILE_4x4), -#endif - m_numCliffInfo(1), - m_terrainTex(NULL), m_alphaTerrainTex(NULL), m_numBitmapTiles(0), m_numBlendedTiles(1) -{ - - int i; - for (i=0; im_stretchTerrain) { - m_drawWidthX=STRETCH_DRAW_WIDTH; - m_drawHeightY=STRETCH_DRAW_HEIGHT; - } - - DataChunkInput file( pStrm ); - - if (logicalDataOnly) { - file.registerParser( "HeightMapData", AsciiString::TheEmptyString, ParseSizeOnlyInChunk ); - file.registerParser( "WorldInfo", AsciiString::TheEmptyString, ParseWorldDictDataChunk ); - file.registerParser( "ObjectsList", AsciiString::TheEmptyString, ParseObjectsDataChunk ); - freeListOfMapObjects(); // just in case. - file.registerParser( "PolygonTriggers", AsciiString::TheEmptyString, PolygonTrigger::ParsePolygonTriggersDataChunk ); - PolygonTrigger::deleteTriggers(); // just in case. - TheSidesList->emptySides(); - file.registerParser("SidesList", AsciiString::TheEmptyString, SidesList::ParseSidesDataChunk ); - } else { - file.registerParser( "HeightMapData", AsciiString::TheEmptyString, ParseHeightMapDataChunk ); - file.registerParser( "BlendTileData", AsciiString::TheEmptyString, ParseBlendTileDataChunk ); -#ifdef EVAL_TILING_MODES - file.registerParser( "FUNKY_TILING", AsciiString::TheEmptyString, ParseFunkyTilingDataChunk ); -#endif - file.registerParser( "GlobalLighting", AsciiString::TheEmptyString, ParseLightingDataChunk ); - } - if (!file.parse(this)) { - throw(ERROR_CORRUPT_FILE_FORMAT); - } - // patch bad maps. - if (!logicalDataOnly) { - for(i=0; i= m_numCliffInfo) { - m_cliffInfoNdxes[i] = 0; - } - if (m_blendTileNdxes[i]<0 || m_blendTileNdxes[i]>= m_numBlendedTiles) { - m_blendTileNdxes[i] = 0; - } - if (m_extraBlendTileNdxes[i]<0 || m_extraBlendTileNdxes[i]>= m_numBlendedTiles) { - m_extraBlendTileNdxes[i] = 0; - } - } - } - if (TheGlobalData && TheGlobalData->m_drawEntireTerrain) { - m_drawWidthX=m_width; - m_drawHeightY=m_height; - } - if (m_drawWidthX > m_width) { - m_drawWidthX = m_width; - } - if (m_drawHeightY > m_height) { - m_drawHeightY = m_height; - } - - TheSidesList->validateSides(); -} - -/** Optimized version of method to get triangle flip state of a terrain cell. Use this -* instead of getAlphaUVData() whenever possible. -*/ -Bool WorldHeightMap::getFlipState(Int xIndex, Int yIndex) const -{ - if (xIndex<0 || yIndex<0) return false; - if (yIndex>=m_height) return false; - if (xIndex>=m_width) return false; - if (!m_cellFlipState) return false; - return m_cellFlipState[yIndex*m_flipStateWidth + (xIndex >> 3)] & (1<<(xIndex&0x7)); -} - -/** Get whether the cell is a cliff cell (impassable to ground vehicles). -*/ -Bool WorldHeightMap::getCliffState(Int xIndex, Int yIndex) const -{ - if (xIndex<0 || yIndex<0) return false; - if (yIndex>=m_height) return false; - if (xIndex>=m_width) return false; - if (!m_cellCliffState) return false; - return m_cellCliffState[yIndex*m_flipStateWidth + (xIndex >> 3)] & (1<<(xIndex&0x7)); -} - -//============================================================================= -// setCliffState -//============================================================================= -/** Sets the cliff state for a given cell. */ -//============================================================================= -void WorldHeightMap::setCliffState(Int xIndex, Int yIndex, Bool state) -{ - if (xIndex<0 || yIndex<0) return; - if (yIndex>=m_height) return; - if (xIndex>=m_width) return; - if (!m_cellCliffState) return; - UnsignedByte flagByte = m_cellCliffState[yIndex*m_flipStateWidth + (xIndex >> 3)]; - UnsignedByte flagMask = (1<<(xIndex&0x7)); - if (state) { - flagByte |= flagMask; - } else { - flagByte &= (~flagMask); - } - m_cellCliffState[yIndex*m_flipStateWidth + (xIndex >> 3)] = flagByte; -} - -Bool WorldHeightMap::ParseWorldDictDataChunk(DataChunkInput &file, DataChunkInfo *info, void *userData) -{ - Dict d = file.readDict(); - *MapObject::getWorldDict() = d; - Bool exists; - Int theWeather = MapObject::getWorldDict()->getInt(TheKey_weather, &exists); - if (exists) { - TheWritableGlobalData->m_weather = (Weather) theWeather; - } - return true; -} - -/** -* WorldHeightMap::ParseLightingDataChunk - read a global lights chunk. -* Format is the newer CHUNKY format. -* See WHeightMapEdit.cpp for the writer. -* Input: DataChunkInput -* -*/ -Bool WorldHeightMap::ParseLightingDataChunk(DataChunkInput &file, DataChunkInfo *info, void *userData) -{ - TheWritableGlobalData->m_timeOfDay = (TimeOfDay)file.readInt(); - Int i; - GlobalData::TerrainLighting initLightValues = { { 0,0,0},{0,0,0},{0,0,-1.0f}}; - - // initialize the directions of the lights to not be totally invalid, in case old maps are read - for (i=0; i<4; i++) { - for (Int j=0;jm_terrainObjectsLighting[i+TIME_OF_DAY_FIRST][j]=initLightValues; - TheWritableGlobalData->m_terrainLighting[i+TIME_OF_DAY_FIRST][j]=initLightValues; - } - } - - for (i=0; i<4; i++) { - TheWritableGlobalData->m_terrainLighting[i+TIME_OF_DAY_FIRST][0].ambient.red = file.readReal(); - TheWritableGlobalData->m_terrainLighting[i+TIME_OF_DAY_FIRST][0].ambient.green = file.readReal(); - TheWritableGlobalData->m_terrainLighting[i+TIME_OF_DAY_FIRST][0].ambient.blue = file.readReal(); - TheWritableGlobalData->m_terrainLighting[i+TIME_OF_DAY_FIRST][0].diffuse.red = file.readReal(); - TheWritableGlobalData->m_terrainLighting[i+TIME_OF_DAY_FIRST][0].diffuse.green = file.readReal(); - TheWritableGlobalData->m_terrainLighting[i+TIME_OF_DAY_FIRST][0].diffuse.blue = file.readReal(); - TheWritableGlobalData->m_terrainLighting[i+TIME_OF_DAY_FIRST][0].lightPos.x = file.readReal(); - TheWritableGlobalData->m_terrainLighting[i+TIME_OF_DAY_FIRST][0].lightPos.y = file.readReal(); - TheWritableGlobalData->m_terrainLighting[i+TIME_OF_DAY_FIRST][0].lightPos.z = file.readReal(); - - TheWritableGlobalData->m_terrainObjectsLighting[i+TIME_OF_DAY_FIRST][0].ambient.red = file.readReal(); - TheWritableGlobalData->m_terrainObjectsLighting[i+TIME_OF_DAY_FIRST][0].ambient.green = file.readReal(); - TheWritableGlobalData->m_terrainObjectsLighting[i+TIME_OF_DAY_FIRST][0].ambient.blue = file.readReal(); - TheWritableGlobalData->m_terrainObjectsLighting[i+TIME_OF_DAY_FIRST][0].diffuse.red = file.readReal(); - TheWritableGlobalData->m_terrainObjectsLighting[i+TIME_OF_DAY_FIRST][0].diffuse.green = file.readReal(); - TheWritableGlobalData->m_terrainObjectsLighting[i+TIME_OF_DAY_FIRST][0].diffuse.blue = file.readReal(); - TheWritableGlobalData->m_terrainObjectsLighting[i+TIME_OF_DAY_FIRST][0].lightPos.x = file.readReal(); - TheWritableGlobalData->m_terrainObjectsLighting[i+TIME_OF_DAY_FIRST][0].lightPos.y = file.readReal(); - TheWritableGlobalData->m_terrainObjectsLighting[i+TIME_OF_DAY_FIRST][0].lightPos.z = file.readReal(); - - if (info->version >= K_LIGHTING_VERSION_2) { - for (Int j=1; j<3; j++) //added support for 2 extra object lights - { - TheWritableGlobalData->m_terrainObjectsLighting[i+TIME_OF_DAY_FIRST][j].ambient.red = file.readReal(); - TheWritableGlobalData->m_terrainObjectsLighting[i+TIME_OF_DAY_FIRST][j].ambient.green = file.readReal(); - TheWritableGlobalData->m_terrainObjectsLighting[i+TIME_OF_DAY_FIRST][j].ambient.blue = file.readReal(); - TheWritableGlobalData->m_terrainObjectsLighting[i+TIME_OF_DAY_FIRST][j].diffuse.red = file.readReal(); - TheWritableGlobalData->m_terrainObjectsLighting[i+TIME_OF_DAY_FIRST][j].diffuse.green = file.readReal(); - TheWritableGlobalData->m_terrainObjectsLighting[i+TIME_OF_DAY_FIRST][j].diffuse.blue = file.readReal(); - TheWritableGlobalData->m_terrainObjectsLighting[i+TIME_OF_DAY_FIRST][j].lightPos.x = file.readReal(); - TheWritableGlobalData->m_terrainObjectsLighting[i+TIME_OF_DAY_FIRST][j].lightPos.y = file.readReal(); - TheWritableGlobalData->m_terrainObjectsLighting[i+TIME_OF_DAY_FIRST][j].lightPos.z = file.readReal(); - } - } - if (info->version >= K_LIGHTING_VERSION_3) { - for (Int j=1; j<3; j++) //added support for 2 extra terrain lights - { - TheWritableGlobalData->m_terrainLighting[i+TIME_OF_DAY_FIRST][j].ambient.red = file.readReal(); - TheWritableGlobalData->m_terrainLighting[i+TIME_OF_DAY_FIRST][j].ambient.green = file.readReal(); - TheWritableGlobalData->m_terrainLighting[i+TIME_OF_DAY_FIRST][j].ambient.blue = file.readReal(); - TheWritableGlobalData->m_terrainLighting[i+TIME_OF_DAY_FIRST][j].diffuse.red = file.readReal(); - TheWritableGlobalData->m_terrainLighting[i+TIME_OF_DAY_FIRST][j].diffuse.green = file.readReal(); - TheWritableGlobalData->m_terrainLighting[i+TIME_OF_DAY_FIRST][j].diffuse.blue = file.readReal(); - TheWritableGlobalData->m_terrainLighting[i+TIME_OF_DAY_FIRST][j].lightPos.x = file.readReal(); - TheWritableGlobalData->m_terrainLighting[i+TIME_OF_DAY_FIRST][j].lightPos.y = file.readReal(); - TheWritableGlobalData->m_terrainLighting[i+TIME_OF_DAY_FIRST][j].lightPos.z = file.readReal(); - } - } - } - if (!file.atEndOfChunk()) { - UnsignedInt shadowColor = file.readInt(); - if (TheW3DShadowManager) { - TheW3DShadowManager->setShadowColor(shadowColor); - } - } - DEBUG_ASSERTCRASH(file.atEndOfChunk(), ("Unexpected data left over.")); - return true; -} - -/** -* WorldHeightMap::ParseObjectsDataChunk - read a height map chunk. -* Format is the newer CHUNKY format. -* See WHeightMapEdit.cpp for the writer. -* Input: DataChunkInput -* -*/ -Bool WorldHeightMap::ParseObjectsDataChunk(DataChunkInput &file, DataChunkInfo *info, void *userData) -{ - file.m_currentObject = NULL; - file.registerParser( "Object", info->label, ParseObjectDataChunk ); - return (file.parse(userData)); -} - -/** -* WorldHeightMap::ParseHeightMapData - read a height map chunk. -* Format is the newer CHUNKY format. -* See WHeightMapEdit.cpp for the writer. -* Input: DataChunkInput -* -*/ -Bool WorldHeightMap::ParseHeightMapDataChunk(DataChunkInput &file, DataChunkInfo *info, void *userData) -{ - WorldHeightMap *pThis = (WorldHeightMap *)userData; - return pThis->ParseHeightMapData(file, info, userData); -} - -/** -* WorldHeightMap::ParseHeightMapData - read a height map chunk. -* Format is the newer CHUNKY format. -* See WHeightMapEdit.cpp for the writer. -* Input: DataChunkInput -* -*/ -Bool WorldHeightMap::ParseHeightMapData(DataChunkInput &file, DataChunkInfo *info, void *userData) -{ - m_width = file.readInt(); - m_height = file.readInt(); - if (info->version >= K_HEIGHT_MAP_VERSION_3) { - m_borderSize = file.readInt(); - } else { - m_borderSize = 0; - } - - if (info->version >= K_HEIGHT_MAP_VERSION_4) { - Int numBorders = file.readInt(); - m_boundaries.resize(numBorders); - for (int i = 0; i < numBorders; ++i) { - m_boundaries[i].x = file.readInt(); - m_boundaries[i].y = file.readInt(); - } - } else { - m_boundaries.resize(1); - m_boundaries[0].x = m_width - 2 * m_borderSize; - m_boundaries[0].y = m_height - 2 * m_borderSize; - } - - m_dataSize = file.readInt(); - m_data = MSGNEW("WorldHeightMap_ParseHeightMapData") UnsignedByte[m_dataSize]; - if (m_dataSize <= 0 || (m_dataSize != (m_width*m_height))) { - throw ERROR_CORRUPT_FILE_FORMAT ; - } - file.readArrayOfBytes((char *)m_data, m_dataSize); - // Resize me. - if (info->version == K_HEIGHT_MAP_VERSION_1) { - Int newWidth = (m_width+1)/2; - Int newHeight = (m_height+1)/2; - Int i, j; - for (i=0; iParseSizeOnly(file, info, userData); -} - -/** -* WorldHeightMap::ParseHeightMapData - read a height map chunk. -* Format is the newer CHUNKY format. -* See WHeightMapEdit.cpp for the writer. -* Input: DataChunkInput -* -*/ -Bool WorldHeightMap::ParseSizeOnly(DataChunkInput &file, DataChunkInfo *info, void *userData) -{ - m_width = file.readInt(); - m_height = file.readInt(); - if (info->version >= K_HEIGHT_MAP_VERSION_3) { - m_borderSize = file.readInt(); - } else { - m_borderSize = 0; - } - - if (info->version >= K_HEIGHT_MAP_VERSION_4) { - Int numBorders = file.readInt(); - m_boundaries.resize(numBorders); - for (int i = 0; i < numBorders; ++i) { - m_boundaries[i].x = file.readInt(); - m_boundaries[i].y = file.readInt(); - } - } else { - m_boundaries.resize(1); - m_boundaries[0].x = m_width - 2 * m_borderSize; - m_boundaries[0].y = m_height - 2 * m_borderSize; - } - - m_dataSize = file.readInt(); - m_data = MSGNEW("WorldHeightMap_ParseSizeOnly") UnsignedByte[m_dataSize]; - if (m_dataSize <= 0 || (m_dataSize != (m_width*m_height))) { - throw ERROR_CORRUPT_FILE_FORMAT ; - } - file.readArrayOfBytes((char *)m_data, m_dataSize); - // Resize me. - if (info->version == K_HEIGHT_MAP_VERSION_1) { - Int newWidth = (m_width+1)/2; - Int newHeight = (m_height+1)/2; - Int i, j; - for (i=0; iParseBlendTileData(file, info, userData); -} - -/** Function to read in the tiles for a texture class. */ -void WorldHeightMap::readTexClass(TXTextureClass *texClass, TileData **tileData) -{ - char path[_MAX_PATH]; - path[0] = 0; - File *theFile = NULL; - - // get the file from the description in TheTerrainTypes - TerrainType *terrain = TheTerrainTypes->findTerrain( texClass->name ); - char texturePath[ _MAX_PATH ]; - if (terrain==NULL) - { -#ifdef LOAD_TEST_ASSETS - theFile = TheFileSystem->openFile( texClass->name.str(), File::READ|File::BINARY); -#endif - } - else - { - sprintf( texturePath, "%s%s", TERRAIN_TGA_DIR_PATH, terrain->getTexture().str() ); - theFile = TheFileSystem->openFile( texturePath, File::READ|File::BINARY); - } - - if (theFile != NULL) { - GDIFileStream theStream(theFile); - InputStream *pStr = &theStream; - Int numTiles = WorldHeightMap::countTiles(pStr); - theFile->seek(0, File::START); - if (numTiles >= texClass->numTiles) { - numTiles = texClass->numTiles; - Int width; - for (width = 10; width >= 1; width--) { - if (numTiles >= width*width) { - numTiles = width*width; - break; - } - } - WorldHeightMap::readTiles(pStr, tileData+texClass->firstTile, width); - } - theFile->close(); - } -} - -/** -* WorldHeightMap::ParseBlendTileData - read a blend tile info chunk. -* Format is the newer CHUNKY format. -* See WHeightMapEdit.cpp for the writer. -* Input: DataChunkInput -* -*/ -Bool WorldHeightMap::ParseBlendTileData(DataChunkInput &file, DataChunkInfo *info, void *userData) -{ - Int len = file.readInt(); - if (m_dataSize != len) { - throw ERROR_CORRUPT_FILE_FORMAT ; - } - m_tileNdxes = MSGNEW("WorldHeightMap_ParseBlendTileData") Short[m_dataSize]; - m_cliffInfoNdxes = MSGNEW("WorldHeightMap_ParseBlendTileData") Short[m_dataSize]; - m_blendTileNdxes = MSGNEW("WorldHeightMap_ParseBlendTileData") Short[m_dataSize]; - m_extraBlendTileNdxes = MSGNEW("WorldHeightMap_ParseBlendTileData") Short[m_dataSize]; - // Note - we have one less cell than the width & height. But for paranoia, allocate - // extra row. jba. - // - Int numBytesX = (m_width+1)/8; //how many bytes to fit all bitflags - Int numBytesY = m_height; - - m_flipStateWidth=numBytesX; - - m_cellFlipState = MSGNEW("WorldHeightMap_getTerrainTexture") UnsignedByte[numBytesX*numBytesY]; - m_cellCliffState = MSGNEW("WorldHeightMap_getTerrainTexture") UnsignedByte[numBytesX*numBytesY]; - memset(m_cellFlipState,0,numBytesX*numBytesY); //clear all flags - memset(m_cellCliffState,0,numBytesX*numBytesY); //clear all flags - - file.readArrayOfBytes((char*)m_tileNdxes, m_dataSize*sizeof(Short)); - file.readArrayOfBytes((char*)m_blendTileNdxes, m_dataSize*sizeof(Short)); - if (info->version >= K_BLEND_TILE_VERSION_6) { - file.readArrayOfBytes((char*)m_extraBlendTileNdxes, m_dataSize*sizeof(Short)); - //Allow clearing of extra blend tiles via ini and resaving of map. - //Useful for flushing out initial maps made with buggy 3-way blending. - if (!TheGlobalData->m_use3WayTerrainBlends) - memset(m_extraBlendTileNdxes,0,m_dataSize*sizeof(Short)); - } - if (info->version >= K_BLEND_TILE_VERSION_5) { - file.readArrayOfBytes((char*)m_cliffInfoNdxes, m_dataSize*sizeof(Short)); - } - if (info->version >= K_BLEND_TILE_VERSION_7) { - file.readArrayOfBytes((char*)m_cellCliffState, m_height*m_flipStateWidth); - } else { - initCliffFlagsFromHeights(); - } - m_numBitmapTiles = file.readInt(); - DEBUG_ASSERTCRASH(m_numBitmapTiles>0 && m_numBitmapTiles<2048, ("Unlikely numBitmapTiles.")); - m_numBlendedTiles = file.readInt(); - DEBUG_ASSERTCRASH(m_numBlendedTiles>0 && m_numBlendedTilesversion >= K_BLEND_TILE_VERSION_5) { - m_numCliffInfo = file.readInt(); - } else { - m_numCliffInfo = 1; // cliffInfo[0] is the default info. - } -// --> file loading here - int i; - m_numTextureClasses = file.readInt(); - DEBUG_ASSERTCRASH(m_numTextureClasses>0 && m_numTextureClasses<200, ("Unlikely m_numTextureClasses.")); - for (i=0; iversion >= K_BLEND_TILE_VERSION_4) { - m_numEdgeTiles = file.readInt(); - m_numEdgeTextureClasses = file.readInt(); - for (i=0; im_use3WayTerrainBlends) - m_blendedTiles[i].inverted &= ~FLIPPED_MASK; //filter out extra flips from 3-way - - if (info->version >= K_BLEND_TILE_VERSION_3) { - m_blendedTiles[i].longDiagonal = file.readByte(); - } else { - m_blendedTiles[i].longDiagonal = false; - } - if (info->version >= K_BLEND_TILE_VERSION_4) { - m_blendedTiles[i].customBlendEdgeClass = file.readInt(); - } else { - m_blendedTiles[i].customBlendEdgeClass = -1; - } - - flag = file.readInt(); - DEBUG_ASSERTCRASH(flag==FLAG_VAL, ("Invalid format.")); - if (flag != FLAG_VAL) { - throw ERROR_CORRUPT_FILE_FORMAT; - } - } - if (info->version >= K_BLEND_TILE_VERSION_5) { - for (i=1; iversion == K_BLEND_TILE_VERSION_1) { - Int newWidth = (m_width+1)/2; - Int newHeight = (m_height+1)/2; - Int i, j; - for (i=0; iParseObjectData(file, info, userData, info->version >= K_OBJECTS_VERSION_2); -} - -/** -* WorldHeightMap::ParseObjectData - read a object info chunk. -* Format is the newer CHUNKY format. -* See WHeightMapEdit.cpp for the writer. -* Input: DataChunkInput -* -*/ -Bool WorldHeightMap::ParseObjectData(DataChunkInput &file, DataChunkInfo *info, void *userData, Bool readDict) -{ - MapObject *pPrevious = (MapObject *)file.m_currentObject; - - Coord3D loc; - loc.x = file.readReal(); - loc.y = file.readReal(); - loc.z = file.readReal(); - - Real minZ = -100*MAP_XY_FACTOR; - Real maxZ = (255*10)*MAP_HEIGHT_SCALE; - - if (info->version <= K_OBJECTS_VERSION_2) { - loc.z = 0; - } - - Real angle = file.readReal(); - Int flags = file.readInt(); - AsciiString name = file.readAsciiString(); - Dict d; - if (readDict) - { - d = file.readDict(); - } - - if (loc.zmaxZ) { - DEBUG_LOG(("Removing object at z height %f", loc.z)); - return true; - } - - MapObject *pThisOne; - - // create the map object - pThisOne = newInstance( MapObject )( loc, name, angle, flags, &d, - TheThingFactory->findTemplate( name ) ); - -//DEBUG_LOG(("obj %s owner %s",name.str(),d.getAsciiString(TheKey_originalOwner).str())); - - if (pThisOne->getProperties()->getType(TheKey_waypointID) == Dict::DICT_INT) - pThisOne->setIsWaypoint(); - - if (pThisOne->getProperties()->getType(TheKey_lightHeightAboveTerrain) == Dict::DICT_REAL) - pThisOne->setIsLight(); - - if (pThisOne->getProperties()->getType(TheKey_scorchType) == Dict::DICT_INT) - pThisOne->setIsScorch(); - - - if (pPrevious) { - DEBUG_ASSERTCRASH(MapObject::TheMapObjectListPtr != NULL && pPrevious->getNext() == NULL, ("Bad linkage.")); - pPrevious->setNextMap(pThisOne); - } else { - DEBUG_ASSERTCRASH(MapObject::TheMapObjectListPtr == NULL, ("Bad linkage.")); - MapObject::TheMapObjectListPtr = pThisOne; - } - file.m_currentObject = pThisOne; - return true; -} - - - -// Targa format: Header - -typedef struct { - UnsignedByte idLength; - UnsignedByte colorMapType; // 0 = rgb, 1 = indexed. - UnsignedByte imageType; //0x1 = indexed, 0x2 = rgb, 0x8 = rle. - UnsignedByte colorMapInfo[5]; // we ignore, only do rgb. - Short xOrigin; - Short yOrigin; - Short imageWidth; - Short imageHeight; - UnsignedByte pixelDepth; - UnsignedByte flags; // &0x0F = alpha channel bits, &0x10 is right to left flag, - // 0x20 is top to bottom flag. (0x0? is left to right, bottom to top) - // 0x3? is top to bottom, right to left. -} TTargaHeader; - -// followed by idLength bytes of ascii data - -// followed by pixel data - -// followed by optional data. - - - -/// Count how many tiles come in from a targa file. -Int WorldHeightMap::countTiles(InputStream *pStr) -{ - TTargaHeader hdr; - Int len = pStr->read(&hdr,sizeof(hdr)); - if (len!=sizeof(hdr)) return(0); - Int tileWidth = hdr.imageWidth/TILE_PIXEL_EXTENT; - Int tileHeight = hdr.imageHeight/TILE_PIXEL_EXTENT; - - if (hdr.colorMapType != 0) { - return(0); // we don't do indexed at this time. jba. - } - if (hdr.imageType != 0x2 && hdr.imageType != 0xA) { - return(0); // we don't do indexed at this time. jba. - } - - if (hdr.pixelDepth < 24) return(false); - if (hdr.pixelDepth > 32) return(false); - // 3x3 gives 9, - // 2x2 gives 4, - // 1x1 gives 1, - // else 0; - if (tileWidth>10 || tileHeight>10) return(0); // don't do huge images, or bad files. - if (tileWidth>=10 && tileHeight >=10) return(100); - if (tileWidth>=9 && tileHeight >=9) return(81); - if (tileWidth>=8 && tileHeight >=8) return(64); - if (tileWidth>=7 && tileHeight >=7) return(49); - if (tileWidth>=6 && tileHeight >=6) return(36); - if (tileWidth>=5 && tileHeight >=5) return(25); - if (tileWidth>=4 && tileHeight >=4) return(16); - if (tileWidth>=3 && tileHeight >=3) return(9); - if (tileWidth>=2 && tileHeight >=2) return(4); - if (tileWidth>=1 && tileHeight >=1) return(1); - return(0); -} -/*Break down a .tga file into a collection of tiles. numRows * numRows total tiles.*/ -Bool WorldHeightMap::readTiles(InputStream *pStr, TileData **tiles, Int numRows) -{ - TTargaHeader hdr; - pStr->read(&hdr, sizeof(hdr)); - Int tileWidth = hdr.imageWidth/TILE_PIXEL_EXTENT; - Int tileHeight = hdr.imageHeight/TILE_PIXEL_EXTENT; - - if (tileWidth 4) return(false); - int i; - for (i=0; iread(&flag, 1); - repeatCount = flag&0x7f; - repeatCount++; - if (flag&0x80) { - running = true; - pStr->read(buf, bytesPerPixel); - } else { - running = false; - } - } - if (compressed) repeatCount--; - if (!running) { - pStr->read(buf, bytesPerPixel); - } - if (column >= (numRows*TILE_PIXEL_EXTENT)) continue; - r = buf[2]; g = buf[1]; b = buf[0]; - - int tileNdx = (column/TILE_PIXEL_EXTENT) + numRows*(row/TILE_PIXEL_EXTENT); - int pixelNdx = (column%TILE_PIXEL_EXTENT) + TILE_PIXEL_EXTENT*(row%TILE_PIXEL_EXTENT); - - UnsignedByte *pixel = tiles[tileNdx]->getDataPtr(); - - pixel += pixelNdx*TILE_BYTES_PER_PIXEL; - *pixel++ = b; - *pixel++ = g; - *pixel++ = r; - *pixel = 0xFF; // solid alpha. - - } - DEBUG_ASSERTCRASH(repeatCount==0, ("Invalid tga.")); - } - for (i=0; iupdateMips(); - } - return(true); -} - - - -/** updateTileTexturePositions - assigns each tile a location in the texture. -*/ -Int WorldHeightMap::updateTileTexturePositions(Int *edgeHeight) -{ - Int i, j; - Int maxHeight = 0; - const Int tilesPerRow = TEXTURE_WIDTH/(TILE_PIXEL_EXTENT+TILE_OFFSET); - - Bool availableGrid[tilesPerRow][tilesPerRow]; - Int row, column; - for (row=0; rowm_tileLocationInTexture.x = 0; - m_sourceTiles[i]->m_tileLocationInTexture.y = 0; - } - } - - /* put the normal tiles into the terrain texture */ - Int texClass; - Int tileWidth; - for (tileWidth = tilesPerRow; tileWidth>0; tileWidth--) { - for (texClass=0; texClassm_tileLocationInTexture.x = x; - m_sourceTiles[baseNdx]->m_tileLocationInTexture.y = y; - } - } - } - } - - for (i=0; im_tileLocationInTexture.x = 0; - m_edgeTiles[i]->m_tileLocationInTexture.y = 0; - } - } - - /* put the blend edge tiles into the blend edges texture */ - Int maxEdgeHeight = 0; - // Reset the grid, cause we're using a different texture now. - for (row=0; rowm_tileLocationInTexture.x = x; - m_edgeTiles[baseNdx]->m_tileLocationInTexture.y = y; - } - } - } - if (edgeHeight) *edgeHeight = maxEdgeHeight; - return maxHeight; -} - -/** getUVData - Gets the texture coordinates to use. See getTerrainTexture. -*/ -void WorldHeightMap::getUVForNdx(Int tileNdx, float *minU, float *minV, float *maxU, float*maxV, Bool fullTile) -{ - Short baseNdx = tileNdx>>2; - if (m_sourceTiles[baseNdx] == NULL) { - // Missing texture. - *minU = *minV = *maxU = *maxV = 0.0f; - return; - } - ICoord2D pos = m_sourceTiles[baseNdx]->m_tileLocationInTexture; - *minU = pos.x; - *minV = pos.y; - *maxU = *minU+TILE_PIXEL_EXTENT; - *maxV = *minV+TILE_PIXEL_EXTENT; -#ifdef EVAL_TILING_MODES - if (m_tileMode == TILE_8x8) { - *maxU = *minU+TILE_PIXEL_EXTENT/2.0f; - *maxV = *minV+TILE_PIXEL_EXTENT/2.0f; - } else if (m_tileMode == TILE_6x6) { - *maxU = *minU+2.0f*TILE_PIXEL_EXTENT/3.0f; - *maxV = *minV+2.0f*TILE_PIXEL_EXTENT/3.0f; - } else { - *maxU = *minU+TILE_PIXEL_EXTENT; - *maxV = *minV+TILE_PIXEL_EXTENT; - } -#endif - *minU/=TEXTURE_WIDTH; - *minV/=m_terrainTexHeight; - *maxU/=TEXTURE_WIDTH; - *maxV/=m_terrainTexHeight; - if (!fullTile) { - // Tiles are 64x64 pixels, height grids map to 32x32. - // So get the proper quadrant of the tile. - Real midX = (*minU+*maxU)/2; - Real midY = (*minV+*maxV)/2; - if (tileNdx&2) { // y's are flipped. - *maxV = midY; - } else { - *minV = midY; - } - if (tileNdx&1) { - *minU = midX; - } else { - *maxU = midX; - } - } -} - -/** getUVData - Gets the texture coordinates to use. See getTerrainTexture. -*/ -void WorldHeightMap::getUVForBlend(Int edgeClass, Region2D *range) -{ - ICoord2D pos = m_edgeTextureClasses[edgeClass].positionInTexture; - Int width = m_edgeTextureClasses[edgeClass].width; - range->lo.x = (Real)pos.x/TEXTURE_WIDTH; - range->lo.y = (Real)pos.y/m_alphaEdgeHeight; - range->hi.x = ((Real)pos.x + width*TILE_PIXEL_EXTENT)/TEXTURE_WIDTH; - range->hi.y = ((Real)pos.y + width*TILE_PIXEL_EXTENT)/m_alphaEdgeHeight; -} - -/// Get whether something is cliff indexed with the offset that HeightMapRenderObjClass uses built in. -Bool WorldHeightMap::isCliffMappedTexture(Int x, Int y) { - Int ndx = x+m_drawOriginX+m_width*(y+m_drawOriginY); - if (ndx>=0 && ndxm_adjustCliffTextures) { - return false; - } - if (nU==0.0) { - return false; // missing texture. - } - if (fullTile) { - return false; - } - if (m_cliffInfoNdxes[ndx]) { - TCliffInfo info = m_cliffInfo[m_cliffInfoNdxes[ndx]]; - Bool tilesMatch = false; - Int ndx1 = tileNdx>>2; - Int ndx2 = info.tileIndex>>2; - Int i; - for (i=0; im_numTextureClasses; i++) { - if (ndx1 >= m_textureClasses[i].firstTile && ndx1 < m_textureClasses[i].firstTile + m_textureClasses[i].numTiles) { - tilesMatch = ndx2 >= m_textureClasses[i].firstTile && ndx2 < m_textureClasses[i].firstTile + m_textureClasses[i].numTiles; - //tilesMatch = true; - break; - } - } - if (tilesMatch) { - Real minU = m_textureClasses[i].positionInTexture.x; - Real maxV = m_textureClasses[i].positionInTexture.y + m_textureClasses[i].width*TILE_PIXEL_EXTENT; - minU/=TEXTURE_WIDTH; - maxV/=m_terrainTexHeight; - Real vFactor = TEXTURE_WIDTH/m_terrainTexHeight; - U[0] = info.u0+minU; - U[1] = info.u1+minU; - U[2] = info.u2+minU; - U[3] = info.u3+minU; - V[0] = info.v0*vFactor+maxV; - V[1] = info.v1*vFactor+maxV; - V[2] = info.v2*vFactor+maxV; - V[3] = info.v3*vFactor+maxV; - return info.flip; - } - } -#define DO_OLD_UV -#ifdef DO_OLD_UV -// old uv adjustment for cliffs - static Real STRETCH_LIMIT = 1.5f; // If it is stretching less than this, don't adjust. - static Real TILE_LIMIT = 4.0; // Our tiles are currently 4 cells wide & tall, so dont' - // adjust to more than 4.0. - - static Real TALL_STRETCH_LIMIT = 2.0f; - static Real DIAMOND_STRETCH_LIMIT = 2.4f; - static Real HEIGHT_SCALE = MAP_HEIGHT_SCALE / MAP_XY_FACTOR; - - Real nU, nV, xU, xV; - nU=nV=xU=xV = 0.0f; - Int tilesPerRow = TEXTURE_WIDTH/(2*TILE_PIXEL_EXTENT+TILE_OFFSET); - tilesPerRow *= 4; - - - getUVForNdx(tileNdx, &nU, &nV, &xU, &xV, fullTile); - U[0] = nU; U[1] = xU; U[2] = xU; U[3] = nU; - V[0] = xV; V[1] = xV; V[2] = nV; V[3] = nV; - if (TheGlobalData && !TheGlobalData->m_adjustCliffTextures) { - return false; - } - if (nU==0.0) { - return false; // missing texture. - } - if (fullTile) { - return false; - } - // check for excessive heights. - if (ndx < this->m_dataSize - m_width - 1) { - Int h0 = m_data[ndx]; - Int h1 = m_data[ndx+1]; - Int h2 = m_data[ndx+m_width+1]; - Int h3 = m_data[ndx+m_width]; - Int minH, maxH; - minH = maxH = h0; - if (minH>h1) minH = h1; - if (maxHh2) minH = h2; - if (maxHh3) minH = h3; - if (maxHaboveLimit) above++; - if (h1>aboveLimit) above++; - if (h2>aboveLimit) above++; - if (h3>aboveLimit) above++; - if (deltaH*HEIGHT_SCALE < STRETCH_LIMIT) { - return false; - } - - Short baseNdx = tileNdx>>2; - Short texClass; - for (texClass=0; texClass= m_textureClasses[texClass].firstTile && - baseNdx < m_textureClasses[texClass].firstTile+m_textureClasses[texClass].numTiles) { - break; - } - } - if (texClass>= m_numTextureClasses) return false; - Real nUb, nVb, xUb, xVb; - nUb = m_textureClasses[texClass].positionInTexture.x; - nVb = m_textureClasses[texClass].positionInTexture.y; - xUb = nUb+m_textureClasses[texClass].width*TILE_PIXEL_EXTENT; - xVb = nVb+m_textureClasses[texClass].width*TILE_PIXEL_EXTENT; - nUb/=TEXTURE_WIDTH; - nVb/=m_terrainTexHeight; - xUb/=TEXTURE_WIDTH; - xVb/=m_terrainTexHeight; - // Now covers texture bounds. - // too much stretch. - Real divisor = TILE_LIMIT/(deltaH*HEIGHT_SCALE); - if (divisor > TILE_LIMIT) divisor = TILE_LIMIT; - if (divisor < 1.0f) divisor = 1.0f; - Real deltaV = (xVb-nVb); -// Real deltaU = (xUb-nUb); - - if (above != 1 && below != 1 && (above!=2 || below != 2)) { - // diamond shaped. Use default if it is not too stretched, as - // the fix is not that appealing either. - if (deltaH*HEIGHT_SCALE < DIAMOND_STRETCH_LIMIT) { - return false; - } - } - - if (below==1 || above>below) { //(avgH > minH + (2*deltaH+2)/3) - // we got one low guy. - if (h0==minH) { - V[0] = nV+deltaV/divisor; - } else if (h1 == minH) { - V[1] = nV+deltaV/divisor; - } else if (h2 == minH) { - V[2] = xV-deltaV/divisor; - } else if (h3 == minH) { - V[3] = xV-deltaV/divisor; - } -#if 0 - nU = nV = xU = xV = 1.0f; - U[0] = nU; U[1] = xU; U[2] = xU; U[3] = nU; - V[0] = xV; V[1] = xV; V[2] = nV; V[3] = nV; - return false; -#endif - } else if (above==1 || below>above) { //(avgH < minH + (deltaH+1)/3) - // we got one high guy - if (h0==maxH) { - V[0] = nV+deltaV/divisor; - } else if (h1 == maxH) { - V[1] = nV+deltaV/divisor; - } else if (h2 == maxH) { - V[2] = xV-deltaV/divisor; - } else if (h3 == maxH) { - V[3] = xV-deltaV/divisor; - } -#if 0 - nU = nV = xU = xV = 0.0f; - U[0] = nU; U[1] = xU; U[2] = xU; U[3] = nU; - V[0] = xV; V[1] = xV; V[2] = nV; V[3] = nV; - return false; -#endif - } else { - // we got two up and two down. - if (deltaH*HEIGHT_SCALE < TALL_STRETCH_LIMIT) { - return false; - } -#if 0 - nU = nV = xU = xV = 0.0f; - U[0] = nU; U[1] = xU; U[2] = xU; U[3] = nU; - V[0] = xV; V[1] = xV; V[2] = nV; V[3] = nV; - return; -#endif - Real dx = (h3-h2)*HEIGHT_SCALE; - dx = sqrt(1+dx*dx); // lenght of the bottom of the cell - Real dy = (h3-h0)*HEIGHT_SCALE; - dy = sqrt(1+dy*dy); // length of the left side. - if (dxTILE_LIMIT) dx = TILE_LIMIT; // don't tile past the texture's edge. - if (dy>TILE_LIMIT) dy = TILE_LIMIT; // don't tile past the texture's edge. - dx *= xU-nU; - dy *= xV-nV; - U[0] = nU; U[1] = nU+dx; U[2] = nU+dx; U[3] = nU; - V[0] = nV+dy; V[1] = nV+dy; V[2] = nV; V[3] = nV; - if (below==1) { - below = 1; - } - // recalc for point 1. - dx = (h1-h0)*HEIGHT_SCALE; - dx = sqrt(1+dx*dx); // lenght of the bottom of the cell - dy = (h2-h1)*HEIGHT_SCALE; - dy = sqrt(1+dy*dy); // length of the left side. - if (dxTILE_LIMIT) dx = TILE_LIMIT; // don't tile past the texture's edge. - if (dy>TILE_LIMIT) dy = TILE_LIMIT; // don't tile past the texture's edge. - dx *= xU-nU; - dy *= xV-nV; - U[1] = U[0]+dx; - V[1] = V[3] + dy; - } - // Make sure we are within the texture; - Real adjU = 0; - Real adjV = 0; - Int i; - for (i=0; i<4; i++) { - if (nVb - V[i] > adjV) adjV = nVb - V[i]; - } - for (i=0; i<4; i++) { - V[i] += adjV; - } - adjV = 0; - for (i=0; i<4; i++) { - if (U[i] - xUb > adjU) adjU = U[i]-xUb; - if (V[i] - xVb > adjV) adjV = V[i]-xVb; - } - for (i=0; i<4; i++) { - U[i] -= adjU; - V[i] -= adjV; - } - } - return true; -// -#endif - - } - return false; -} - -///@todo: Are the different "if" cases mutually exclusive? If so, should add else statements. -Bool WorldHeightMap::getExtraAlphaUVData(Int xIndex, Int yIndex, float U[4], float V[4], UnsignedByte alpha[4], Bool *needFlip, Bool *cliff) -{ - Int ndx = (yIndex*m_width)+xIndex; - *needFlip = FALSE; - *cliff = FALSE; - - if ( (ndx>=0) && (ndx=0) { - alpha[0] = alpha[1] = alpha[2] = alpha[3] = 0; - // No alpha blend, so never need to flip. - *needFlip = FALSE; - } - } - } - - return TRUE; -} - -/** getUVData - Gets the texture coordinates to use with the alpha texture. - xIndex and yIndex are the integer coorddinates into the height map. - U and V are the texture coordiantes for the 4 corners of a height map cell. - fullTile is true if we are doing 1/2 resolution height map, and require a full - tile to texture a cell. Otherwise, we use quarter tiles per cell. - flip is set if we need to flip the diagonal across the cell to make the - alpha coordinates blend properly. Filling a square with 2 triangles is not symmetrical :) -*/ -void WorldHeightMap::getAlphaUVData(Int xIndex, Int yIndex, float U[4], float V[4], - UnsignedByte alpha[4], Bool *flip, Bool fullTile) -{ - xIndex += m_drawOriginX; - yIndex += m_drawOriginY; - Int ndx = (yIndex*m_width)+xIndex; - Bool stretchedForCliff = false; - Bool needFlip = false; - - if ((ndx=0) { - alpha[0] = alpha[1] = alpha[2] = alpha[3] = 0; - // No alpha blend, so never need to flip. - needFlip = false; - } - } - } - if (stretchedForCliff) { - // If we had to stretch for clif, check heights. - Int p0=getHeight(xIndex, yIndex); - Int p1=getHeight(xIndex+1, yIndex); - Int p2=getHeight(xIndex+1, yIndex+1); - Int p3=getHeight(xIndex, yIndex+1); - Int dz1 = abs(p0-p2); - Int dz2 = abs(p1-p3); - needFlip = dz1>dz2; - } -#ifdef FLIP_TRIANGLES - *flip = needFlip; -#endif -} - -TextureClass *WorldHeightMap::getTerrainTexture(void) -{ - if (m_terrainTex == NULL) { - Int edgeHeight; - Int height = updateTileTexturePositions(&edgeHeight); - Int pow2Height = 1; - while (pow2Heightupdate(this); - char buf[64]; - sprintf(buf, "Base tex height %d", pow2Height); - DEBUG_LOG((buf)); - REF_PTR_RELEASE(m_alphaTerrainTex); - m_alphaTerrainTex = MSGNEW("WorldHeightMap_getTerrainTexture") AlphaTerrainTextureClass(m_terrainTex); - - pow2Height = 1; - while (pow2Heightupdate(this); - - //Generate lookup table for determining triangle order in each terrain cell. - //Not the best place to put this but getAlphaUVData() requires a valid terrain - //texture to return valid values. - - for (Int y=0; y<(m_height-1); y++) - for (Int x=0; x<(m_width-1); x++) - { - UnsignedByte alpha[4]; - float UA[4], VA[4]; - Bool flipForBlend; - - getAlphaUVData(x, y, UA, VA, alpha, &flipForBlend, false); - - m_cellFlipState[y*m_flipStateWidth+(x>>3)] |= flipForBlend << (x & 0x7); - DEBUG_ASSERTCRASH ((y*m_flipStateWidth+(x>>3)) < (m_flipStateWidth * m_height), ("Bad range")); - } - } - - return m_terrainTex; -} - -TextureClass *WorldHeightMap::getAlphaTerrainTexture(void) -{ - if (m_alphaTerrainTex == NULL) { - getTerrainTexture(); - } - return m_alphaTerrainTex; -} - -TextureClass *WorldHeightMap::getEdgeTerrainTexture(void) -{ - if (m_alphaEdgeTex == NULL) { - getTerrainTexture(); - } - return m_alphaEdgeTex; -} - -Bool WorldHeightMap::setDrawOrg(Int xOrg, Int yOrg) -{ - Int newX, newY; - Int newWidth, newHeight; - newX = xOrg; - newY = yOrg; - newWidth = m_drawWidthX; - newHeight = m_drawHeightY; - if (TheGlobalData && TheGlobalData->m_stretchTerrain) { - newWidth=STRETCH_DRAW_WIDTH; - newHeight=STRETCH_DRAW_HEIGHT; - } - if (TheGlobalData && TheGlobalData->m_drawEntireTerrain) { - newWidth=m_width; - newHeight=m_height; - } - if (newWidth > m_width) newWidth = m_width; - if (newHeight > m_height) newHeight = m_height; - if (newX > m_width - newWidth) newX = m_width-newWidth; - if (newX<0) newX=0; - if (newY > m_height - newHeight) newY = m_height - newHeight; - if (newY<0) newY=0; - Bool anythingDifferent = (m_drawOriginX!=newX) || - (m_drawOriginY!=newY) || - (m_drawWidthX!=newWidth) || - (m_drawHeightY!=newHeight) ; - - if (anythingDifferent) { - m_drawOriginX=newX; - m_drawOriginY=newY; - m_drawWidthX=newWidth; - m_drawHeightY=newHeight; - return(true); - } - return(false); -} - -/** Gets global texture class. */ -Int WorldHeightMap::getTextureClass(Int xIndex, Int yIndex, Bool baseClass) -{ - Int ndx = (yIndex*m_width)+xIndex; - DEBUG_ASSERTCRASH((ndx>=0 && ndxm_dataSize),("oops")); - if (ndx<0 || ndx >= this->m_dataSize) return(-1); - Int textureNdx = m_tileNdxes[ndx]; - if (!baseClass && (m_blendTileNdxes[ndx] != 0 || m_extraBlendTileNdxes[ndx] != 0)) { - return(-1); // blended, so not of the original class. - } - return getTextureClassFromNdx(textureNdx); -} - - -/** Sets all the cliff flags in map based on height. */ -void WorldHeightMap::initCliffFlagsFromHeights() -{ - Int xIndex, yIndex; - - for (xIndex=0; xIndex height2) minZ = height2; - if (minZ > height3) minZ = height3; - if (minZ > height4) minZ = height4; - Real maxZ = height1; - if (maxZ < height2) maxZ = height2; - if (maxZ < height3) maxZ = height3; - if (maxZ < height4) maxZ = height4; - const Real cliffRange = PATHFIND_CLIFF_SLOPE_LIMIT_F; - Bool isCliff = (maxZ-minZ > cliffRange); - setCliffState(xIndex, yIndex, isCliff); - -} - -/** Gets global texture class. */ -Int WorldHeightMap::getTextureClassFromNdx(Int tileNdx) -{ - Int i; - tileNdx = tileNdx>>2; - for (i=0; i= m_textureClasses[i].firstTile && - tileNdx < m_textureClasses[i].firstTile+m_textureClasses[i].numTiles) { - return(m_textureClasses[i].globalTextureClass); - } - } - return(-1); -} - -TXTextureClass WorldHeightMap::getTextureFromIndex( Int textureIndex ) -{ - return m_textureClasses[textureIndex]; -} - -void WorldHeightMap::getTerrainColorAt(Real x, Real y, RGBColor *pColor) -{ - Int xIndex = REAL_TO_INT_FLOOR(x/MAP_XY_FACTOR); - Int yIndex = REAL_TO_INT_FLOOR(y/MAP_XY_FACTOR); - xIndex += m_borderSize; - yIndex += m_borderSize; - pColor->red = pColor->green = pColor->blue = 0; - if (xIndex<0) xIndex = 0; - if (yIndex<0) yIndex = 0; - if (xIndex >= m_width) xIndex = m_width-1; - if (yIndex >= m_height) yIndex = m_height-1; - Int ndx = (yIndex*m_width)+xIndex; - if (ndx<0 || ndx >= this->m_dataSize) return; - Int tileNdx = m_tileNdxes[ndx]; - tileNdx = tileNdx>>2; // We pack 4 grids into a tile. - - TileData *pTile = getSourceTile(tileNdx); - if (pTile) { - // pTile contains the bitmap data for 4 squares. - // Get the data mipped down to one pixel for the tile. - UnsignedByte *pData = pTile->getRGBDataForWidth(1); - // Data is in microsoft bgra format. - pColor->red = pData[2]/255.0; - pColor->green = pData[1]/255.0; - pColor->blue = pData[0]/255.0; - } -} - -AsciiString WorldHeightMap::getTerrainNameAt(Real x, Real y) -{ - Int xIndex = REAL_TO_INT_FLOOR(x/MAP_XY_FACTOR); - Int yIndex = REAL_TO_INT_FLOOR(y/MAP_XY_FACTOR); - xIndex += m_borderSize; - yIndex += m_borderSize; - if (xIndex<0) xIndex = 0; - if (yIndex<0) yIndex = 0; - if (xIndex >= m_width) xIndex = m_width-1; - if (yIndex >= m_height) yIndex = m_height-1; - Int ndx = (yIndex*m_width)+xIndex; - if (ndx<0 || ndx >= this->m_dataSize) return AsciiString::TheEmptyString; - Int tileNdx = m_tileNdxes[ndx]; - tileNdx = tileNdx>>2; // We pack 4 grids into a tile. - - Int i; - for (i=0; im_numTextureClasses; i++) { - if (tileNdx >= m_textureClasses[i].firstTile && tileNdx < m_textureClasses[i].firstTile + m_textureClasses[i].numTiles) { - return(m_textureClasses[i].name); - } - } - return AsciiString::TheEmptyString; -} - - diff --git a/Generals/Code/Libraries/Include/Lib/BaseType.h b/Generals/Code/Libraries/Include/Lib/BaseType.h index 478caf7c72..ea7efe1f5b 100644 --- a/Generals/Code/Libraries/Include/Lib/BaseType.h +++ b/Generals/Code/Libraries/Include/Lib/BaseType.h @@ -92,6 +92,52 @@ __forceinline long fast_float2long_round(float f) return i; } +// super fast float trunc routine, works always (independent of any FPU modes) +// code courtesy of Martin Hoffesommer (grin) +__forceinline float fast_float_trunc(float f) +{ +#if defined(_MSC_VER) && _MSC_VER < 1300 + _asm + { + mov ecx,[f] + shr ecx,23 + mov eax,0xff800000 + xor ebx,ebx + sub cl,127 + cmovc eax,ebx + sar eax,cl + and [f],eax + } + return f; +#else + unsigned x = *(unsigned *)&f; + unsigned char exp = x >> 23; + int mask = exp < 127 ? 0 : 0xff800000; + exp -= 127; + mask >>= exp & 31; + x &= mask; + return *(float *)&x; +#endif +} + +// same here, fast floor function +__forceinline float fast_float_floor(float f) +{ + static unsigned almost1=(126<<23)|0x7fffff; + if (*(unsigned *)&f &0x80000000) + f-=*(float *)&almost1; + return fast_float_trunc(f); +} + +// same here, fast ceil function +__forceinline float fast_float_ceil(float f) +{ + static unsigned almost1=(126<<23)|0x7fffff; + if ( (*(unsigned *)&f &0x80000000)==0) + f+=*(float *)&almost1; + return fast_float_trunc(f); +} + //------------------------------------------------------------------------------------------------- #define REAL_TO_INT(x) ((Int)(x)) #define REAL_TO_UNSIGNEDINT(x) ((UnsignedInt)(x)) @@ -100,14 +146,18 @@ __forceinline long fast_float2long_round(float f) #define REAL_TO_BYTE(x) ((Byte)(x)) #define REAL_TO_UNSIGNEDBYTE(x) ((UnsignedByte)(x)) #define REAL_TO_CHAR(x) ((Char)(x)) -#define DOUBLE_TO_REAL(x) ((Real) (x)) -#define DOUBLE_TO_INT(x) ((Int) (x)) -#define INT_TO_REAL(x) ((Real) (x)) +#define DOUBLE_TO_REAL(x) ((Real)(x)) +#define DOUBLE_TO_INT(x) ((Int)(x)) +#define INT_TO_REAL(x) ((Real)(x)) // once we've ceiled/floored, trunc and round are identical, and currently, round is faster... (srj) #define REAL_TO_INT_CEIL(x) (fast_float2long_round(ceilf(x))) #define REAL_TO_INT_FLOOR(x) (fast_float2long_round(floorf(x))) +#define FAST_REAL_TRUNC(x) fast_float_trunc(x) +#define FAST_REAL_CEIL(x) fast_float_ceil(x) +#define FAST_REAL_FLOOR(x) fast_float_floor(x) + //-------------------------------------------------------------------- // Derived type definitions //-------------------------------------------------------------------- diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8caps.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8caps.cpp index 38477273fe..4b151ba765 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8caps.cpp +++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8caps.cpp @@ -535,6 +535,7 @@ void DX8Caps::Compute_Caps(WW3DFormat display_format, const D3DADAPTER_IDENTIFIE } supportGamma=((swVPCaps.Caps2&D3DCAPS2_FULLSCREENGAMMA)==D3DCAPS2_FULLSCREENGAMMA); + SupportPointSprites = (caps.MaxPointSize > 1.0f); MaxTexturesPerPass=MAX_TEXTURE_STAGES; diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8caps.h b/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8caps.h index b988cf269a..69a793ae81 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8caps.h +++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/dx8caps.h @@ -215,6 +215,7 @@ class DX8Caps bool Support_Bump_Envmap() const { return SupportBumpEnvmap; } bool Support_Bump_Envmap_Luminance() const { return SupportBumpEnvmapLuminance; } bool Support_Dot3() const { return SupportDot3; } + bool Support_PointSprites() const { return SupportPointSprites; } int Get_Max_Textures_Per_Pass() const { return MaxTexturesPerPass; } // ------------------------------------------------------------------------- @@ -275,6 +276,7 @@ class DX8Caps bool SupportRenderToTextureFormat[WW3D_FORMAT_COUNT]; bool SupportDepthStencilFormat[WW3D_ZFORMAT_COUNT]; bool SupportDot3; + bool SupportPointSprites; int MaxTexturesPerPass; int VertexShaderVersion; int PixelShaderVersion; diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/shader.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/shader.cpp index db5caf2559..809a7d2660 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/shader.cpp +++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/shader.cpp @@ -615,17 +615,17 @@ void ShaderClass::Apply() } break; - // Bump map is a hack currently as we only have two stages in use! - case ShaderClass::GRADIENT_DOTPRODUCT3: - if(TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3) - { - PricOp = D3DTOP_DOTPRODUCT3; - PricArg1 = D3DTA_TEXTURE; - PricArg2 = D3DTA_DIFFUSE; - PriaOp = D3DTOP_DISABLE; - PriaArg1 = D3DTA_TEXTURE; - PriaArg2 = D3DTA_CURRENT; - } + case ShaderClass::GRADIENT_MODULATE2X: + //Modulate Alpha + if(!(TextureOpCaps & D3DTOP_MODULATE2X)) + PricOp = D3DTOP_MODULATE; + else + PricOp = D3DTOP_MODULATE2X; + PricArg1 = D3DTA_TEXTURE; + PricArg2 = D3DTA_DIFFUSE; + PriaOp = D3DTOP_MODULATE; + PriaArg1 = D3DTA_TEXTURE; + PriaArg2 = D3DTA_DIFFUSE; break; } } @@ -999,7 +999,7 @@ const StringClass& ShaderClass::Get_Description(StringClass& str) const case GRADIENT_ADD: str+="GRADIENT_ADD | "; break; case GRADIENT_BUMPENVMAP: str+="GRADIENT_BUMPENVMAP | "; break; case GRADIENT_BUMPENVMAPLUMINANCE: str+="GRADIENT_BUMPENVMAPLUMINANCE | "; break; - case GRADIENT_DOTPRODUCT3: str+="GRADIENT_DOTPRODUCT3 | "; break; + case GRADIENT_MODULATE2X: str+="GRADIENT_MODULATE2X | "; break; } switch (Get_Secondary_Gradient()) { diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/shader.h b/Generals/Code/Libraries/Source/WWVegas/WW3D2/shader.h index 3d7141f5a9..e3c1d7ec01 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/shader.h +++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/shader.h @@ -166,12 +166,12 @@ class ShaderClass enum PriGradientType { - GRADIENT_DISABLE=0, // 000 disable primary gradient (same as OpenGL 'decal' texture blend) - GRADIENT_MODULATE, // 001 modulate fragment ARGB by gradient ARGB (default) - GRADIENT_ADD, // 010 add gradient RGB to fragment RGB, copy gradient A to fragment A - GRADIENT_BUMPENVMAP, // 011 - GRADIENT_BUMPENVMAPLUMINANCE, // 100 - GRADIENT_DOTPRODUCT3, // 101 + GRADIENT_DISABLE=0, // 000 disable primary gradient (same as OpenGL 'decal' texture blend) + GRADIENT_MODULATE, // 001 modulate fragment ARGB by gradient ARGB (default) + GRADIENT_ADD, // 010 add gradient RGB to fragment RGB, copy gradient A to fragment A + GRADIENT_BUMPENVMAP, // 011 environment-mapped bump mapping + GRADIENT_BUMPENVMAPLUMINANCE, // 100 environment-mapped bump mapping with luminance control + GRADIENT_MODULATE2X, // 101 modulate fragment ARGB by gradient ARGB and multiply RGB by 2 }; enum SecGradientType diff --git a/Generals/Code/Tools/WorldBuilder/src/WorldBuilder.cpp b/Generals/Code/Tools/WorldBuilder/src/WorldBuilder.cpp index 9603cd1ec8..aa8be4c583 100644 --- a/Generals/Code/Tools/WorldBuilder/src/WorldBuilder.cpp +++ b/Generals/Code/Tools/WorldBuilder/src/WorldBuilder.cpp @@ -413,6 +413,8 @@ BOOL CWorldBuilderApp::InitInstance() TheWritableGlobalData->m_shroudOn = FALSE; #endif + TheWritableGlobalData->m_isWorldBuilder = TRUE; + // Change the registry key under which our settings are stored. // TODO: You should modify this string to be something appropriate // such as the name of your company or organization. diff --git a/GeneralsMD/Code/GameEngine/CMakeLists.txt b/GeneralsMD/Code/GameEngine/CMakeLists.txt index 065d37a8fb..648ea13dc8 100644 --- a/GeneralsMD/Code/GameEngine/CMakeLists.txt +++ b/GeneralsMD/Code/GameEngine/CMakeLists.txt @@ -65,7 +65,7 @@ set(GAMEENGINE_SRC Include/Common/List.h # Include/Common/LocalFile.h # Include/Common/LocalFileSystem.h - Include/Common/MapObject.h +# Include/Common/MapObject.h Include/Common/MapReaderWriterInfo.h Include/Common/MessageStream.h Include/Common/MiniLog.h @@ -199,7 +199,7 @@ set(GAMEENGINE_SRC Include/GameClient/Line2D.h Include/GameClient/LoadScreen.h Include/GameClient/LookAtXlat.h - Include/GameClient/MapUtil.h +# Include/GameClient/MapUtil.h Include/GameClient/MessageBox.h Include/GameClient/MetaEvent.h Include/GameClient/Module/AnimatedParticleSysBoneClientUpdate.h @@ -219,10 +219,10 @@ set(GAMEENGINE_SRC Include/GameClient/ShellHooks.h Include/GameClient/ShellMenuScheme.h # Include/GameClient/Smudge.h - Include/GameClient/Snow.h +# Include/GameClient/Snow.h Include/GameClient/Statistics.h - Include/GameClient/TerrainRoads.h - Include/GameClient/TerrainVisual.h +# Include/GameClient/TerrainRoads.h +# Include/GameClient/TerrainVisual.h # Include/GameClient/VideoPlayer.h # Include/GameClient/View.h # Include/GameClient/Water.h @@ -797,7 +797,7 @@ set(GAMEENGINE_SRC Source/GameClient/Input/Mouse.cpp Source/GameClient/LanguageFilter.cpp Source/GameClient/Line2D.cpp - Source/GameClient/MapUtil.cpp +# Source/GameClient/MapUtil.cpp Source/GameClient/MessageStream/CommandXlat.cpp Source/GameClient/MessageStream/GUICommandTranslator.cpp Source/GameClient/MessageStream/HintSpy.cpp @@ -810,7 +810,7 @@ set(GAMEENGINE_SRC # Source/GameClient/ParabolicEase.cpp Source/GameClient/RadiusDecal.cpp Source/GameClient/SelectionInfo.cpp - Source/GameClient/Snow.cpp +# Source/GameClient/Snow.cpp Source/GameClient/Statistics.cpp Source/GameClient/System/Anim2D.cpp Source/GameClient/System/CampaignManager.cpp @@ -820,8 +820,8 @@ set(GAMEENGINE_SRC Source/GameClient/System/ParticleSys.cpp Source/GameClient/System/RayEffect.cpp # Source/GameClient/System/Smudge.cpp - Source/GameClient/Terrain/TerrainRoads.cpp - Source/GameClient/Terrain/TerrainVisual.cpp +# Source/GameClient/Terrain/TerrainRoads.cpp +# Source/GameClient/Terrain/TerrainVisual.cpp # Source/GameClient/VideoPlayer.cpp # Source/GameClient/VideoStream.cpp # Source/GameClient/View.cpp diff --git a/GeneralsMD/Code/GameEngineDevice/CMakeLists.txt b/GeneralsMD/Code/GameEngineDevice/CMakeLists.txt index c96e1f0b27..7b66d902b1 100644 --- a/GeneralsMD/Code/GameEngineDevice/CMakeLists.txt +++ b/GeneralsMD/Code/GameEngineDevice/CMakeLists.txt @@ -6,10 +6,10 @@ set(GAMEENGINEDEVICE_SRC Include/W3DDevice/Common/W3DModuleFactory.h # Include/W3DDevice/Common/W3DRadar.h Include/W3DDevice/Common/W3DThingFactory.h - Include/W3DDevice/GameClient/BaseHeightMap.h +# Include/W3DDevice/GameClient/BaseHeightMap.h # Include/W3DDevice/GameClient/camerashakesystem.h - Include/W3DDevice/GameClient/FlatHeightMap.h - Include/W3DDevice/GameClient/HeightMap.h +# Include/W3DDevice/GameClient/FlatHeightMap.h +# Include/W3DDevice/GameClient/HeightMap.h Include/W3DDevice/GameClient/Module/W3DDebrisDraw.h Include/W3DDevice/GameClient/Module/W3DDefaultDraw.h Include/W3DDevice/GameClient/Module/W3DDependencyModelDraw.h @@ -20,17 +20,17 @@ set(GAMEENGINEDEVICE_SRC Include/W3DDevice/GameClient/Module/W3DOverlordTruckDraw.h Include/W3DDevice/GameClient/Module/W3DPoliceCarDraw.h Include/W3DDevice/GameClient/Module/W3DProjectileStreamDraw.h - Include/W3DDevice/GameClient/Module/W3DPropDraw.h +# Include/W3DDevice/GameClient/Module/W3DPropDraw.h Include/W3DDevice/GameClient/Module/W3DRopeDraw.h Include/W3DDevice/GameClient/Module/W3DScienceModelDraw.h Include/W3DDevice/GameClient/Module/W3DSupplyDraw.h Include/W3DDevice/GameClient/Module/W3DTankDraw.h Include/W3DDevice/GameClient/Module/W3DTankTruckDraw.h Include/W3DDevice/GameClient/Module/W3DTracerDraw.h - Include/W3DDevice/GameClient/Module/W3DTreeDraw.h +# Include/W3DDevice/GameClient/Module/W3DTreeDraw.h Include/W3DDevice/GameClient/Module/W3DTruckDraw.h - Include/W3DDevice/GameClient/TerrainTex.h - Include/W3DDevice/GameClient/TileData.h +# Include/W3DDevice/GameClient/TerrainTex.h +# Include/W3DDevice/GameClient/TileData.h Include/W3DDevice/GameClient/W3DAssetManager.h Include/W3DDevice/GameClient/W3DAssetManagerExposed.h Include/W3DDevice/GameClient/W3DBibBuffer.h @@ -57,19 +57,19 @@ set(GAMEENGINEDEVICE_SRC Include/W3DDevice/GameClient/W3DParticleSys.h Include/W3DDevice/GameClient/W3DPoly.h Include/W3DDevice/GameClient/W3DProjectedShadow.h - Include/W3DDevice/GameClient/W3DPropBuffer.h +# Include/W3DDevice/GameClient/W3DPropBuffer.h Include/W3DDevice/GameClient/W3DRoadBuffer.h Include/W3DDevice/GameClient/W3DScene.h # Include/W3DDevice/GameClient/W3DShaderManager.h Include/W3DDevice/GameClient/W3DShadow.h Include/W3DDevice/GameClient/W3DShroud.h # Include/W3DDevice/GameClient/W3DSmudge.h - Include/W3DDevice/GameClient/W3DSnow.h +# Include/W3DDevice/GameClient/W3DSnow.h Include/W3DDevice/GameClient/W3DStatusCircle.h - Include/W3DDevice/GameClient/W3DTerrainBackground.h - Include/W3DDevice/GameClient/W3DTerrainTracks.h - Include/W3DDevice/GameClient/W3DTerrainVisual.h - Include/W3DDevice/GameClient/W3DTreeBuffer.h +# Include/W3DDevice/GameClient/W3DTerrainBackground.h +# Include/W3DDevice/GameClient/W3DTerrainTracks.h +# Include/W3DDevice/GameClient/W3DTerrainVisual.h +# Include/W3DDevice/GameClient/W3DTreeBuffer.h # Include/W3DDevice/GameClient/W3DVideoBuffer.h # Include/W3DDevice/GameClient/W3DView.h Include/W3DDevice/GameClient/W3DVolumetricShadow.h @@ -77,7 +77,7 @@ set(GAMEENGINEDEVICE_SRC # Include/W3DDevice/GameClient/W3DWaterTracks.h Include/W3DDevice/GameClient/W3DWaypointBuffer.h Include/W3DDevice/GameClient/W3DWebBrowser.h - Include/W3DDevice/GameClient/WorldHeightMap.h +# Include/W3DDevice/GameClient/WorldHeightMap.h Include/W3DDevice/GameLogic/W3DGameLogic.h Include/W3DDevice/GameLogic/W3DGhostObject.h Include/W3DDevice/GameLogic/W3DTerrainLogic.h @@ -97,7 +97,7 @@ set(GAMEENGINEDEVICE_SRC Source/W3DDevice/Common/Thing/W3DModuleFactory.cpp Source/W3DDevice/Common/Thing/W3DThingFactory.cpp Source/W3DDevice/Common/W3DConvert.cpp - Source/W3DDevice/GameClient/BaseHeightMap.cpp +# Source/W3DDevice/GameClient/BaseHeightMap.cpp # Source/W3DDevice/GameClient/camerashakesystem.cpp Source/W3DDevice/GameClient/Drawable/Draw/W3DDebrisDraw.cpp Source/W3DDevice/GameClient/Drawable/Draw/W3DDefaultDraw.cpp @@ -109,16 +109,16 @@ set(GAMEENGINEDEVICE_SRC Source/W3DDevice/GameClient/Drawable/Draw/W3DOverlordTruckDraw.cpp Source/W3DDevice/GameClient/Drawable/Draw/W3DPoliceCarDraw.cpp Source/W3DDevice/GameClient/Drawable/Draw/W3DProjectileStreamDraw.cpp - Source/W3DDevice/GameClient/Drawable/Draw/W3DPropDraw.cpp +# Source/W3DDevice/GameClient/Drawable/Draw/W3DPropDraw.cpp Source/W3DDevice/GameClient/Drawable/Draw/W3DRopeDraw.cpp Source/W3DDevice/GameClient/Drawable/Draw/W3DScienceModelDraw.cpp Source/W3DDevice/GameClient/Drawable/Draw/W3DSupplyDraw.cpp Source/W3DDevice/GameClient/Drawable/Draw/W3DTankDraw.cpp Source/W3DDevice/GameClient/Drawable/Draw/W3DTankTruckDraw.cpp Source/W3DDevice/GameClient/Drawable/Draw/W3DTracerDraw.cpp - Source/W3DDevice/GameClient/Drawable/Draw/W3DTreeDraw.cpp +# Source/W3DDevice/GameClient/Drawable/Draw/W3DTreeDraw.cpp Source/W3DDevice/GameClient/Drawable/Draw/W3DTruckDraw.cpp - Source/W3DDevice/GameClient/FlatHeightMap.cpp +# Source/W3DDevice/GameClient/FlatHeightMap.cpp Source/W3DDevice/GameClient/GUI/Gadget/W3DCheckBox.cpp Source/W3DDevice/GameClient/GUI/Gadget/W3DComboBox.cpp Source/W3DDevice/GameClient/GUI/Gadget/W3DHorizontalSlider.cpp @@ -136,13 +136,13 @@ set(GAMEENGINEDEVICE_SRC Source/W3DDevice/GameClient/GUI/W3DGameFont.cpp Source/W3DDevice/GameClient/GUI/W3DGameWindow.cpp Source/W3DDevice/GameClient/GUI/W3DGameWindowManager.cpp - Source/W3DDevice/GameClient/HeightMap.cpp +# Source/W3DDevice/GameClient/HeightMap.cpp Source/W3DDevice/GameClient/Shadow/W3DBufferManager.cpp Source/W3DDevice/GameClient/Shadow/W3DProjectedShadow.cpp Source/W3DDevice/GameClient/Shadow/W3DShadow.cpp Source/W3DDevice/GameClient/Shadow/W3DVolumetricShadow.cpp - Source/W3DDevice/GameClient/TerrainTex.cpp - Source/W3DDevice/GameClient/TileData.cpp +# Source/W3DDevice/GameClient/TerrainTex.cpp +# Source/W3DDevice/GameClient/TileData.cpp Source/W3DDevice/GameClient/W3DAssetManager.cpp Source/W3DDevice/GameClient/W3DAssetManagerExposed.cpp Source/W3DDevice/GameClient/W3DBibBuffer.cpp @@ -160,25 +160,25 @@ set(GAMEENGINEDEVICE_SRC Source/W3DDevice/GameClient/W3DMouse.cpp Source/W3DDevice/GameClient/W3DParticleSys.cpp Source/W3DDevice/GameClient/W3DPoly.cpp - Source/W3DDevice/GameClient/W3DPropBuffer.cpp +# Source/W3DDevice/GameClient/W3DPropBuffer.cpp Source/W3DDevice/GameClient/W3DRoadBuffer.cpp Source/W3DDevice/GameClient/W3DScene.cpp # Source/W3DDevice/GameClient/W3DShaderManager.cpp Source/W3DDevice/GameClient/W3DShroud.cpp # Source/W3DDevice/GameClient/W3DSmudge.cpp - Source/W3DDevice/GameClient/W3DSnow.cpp +# Source/W3DDevice/GameClient/W3DSnow.cpp Source/W3DDevice/GameClient/W3DStatusCircle.cpp - Source/W3DDevice/GameClient/W3DTerrainBackground.cpp - Source/W3DDevice/GameClient/W3DTerrainTracks.cpp - Source/W3DDevice/GameClient/W3DTerrainVisual.cpp - Source/W3DDevice/GameClient/W3DTreeBuffer.cpp +# Source/W3DDevice/GameClient/W3DTerrainBackground.cpp +# Source/W3DDevice/GameClient/W3DTerrainTracks.cpp +# Source/W3DDevice/GameClient/W3DTerrainVisual.cpp +# Source/W3DDevice/GameClient/W3DTreeBuffer.cpp # Source/W3DDevice/GameClient/W3DVideoBuffer.cpp # Source/W3DDevice/GameClient/W3DView.cpp Source/W3DDevice/GameClient/W3dWaypointBuffer.cpp Source/W3DDevice/GameClient/W3DWebBrowser.cpp # Source/W3DDevice/GameClient/Water/W3DWater.cpp # Source/W3DDevice/GameClient/Water/W3DWaterTracks.cpp - Source/W3DDevice/GameClient/WorldHeightMap.cpp +# Source/W3DDevice/GameClient/WorldHeightMap.cpp Source/W3DDevice/GameLogic/W3DGameLogic.cpp Source/W3DDevice/GameLogic/W3DGhostObject.cpp Source/W3DDevice/GameLogic/W3DTerrainLogic.cpp diff --git a/scripts/cpp/unify_move_files.py b/scripts/cpp/unify_move_files.py index 42ec8582a2..e2757328ad 100644 --- a/scripts/cpp/unify_move_files.py +++ b/scripts/cpp/unify_move_files.py @@ -218,6 +218,45 @@ def main(): #unify_file(Game.ZEROHOUR, "GameEngineDevice/Source/W3DDevice/GameClient/Water/wave.nvp", Game.CORE, "GameEngineDevice/Source/W3DDevice/GameClient/Water/wave.nvp") #unify_file(Game.ZEROHOUR, "GameEngineDevice/Source/W3DDevice/GameClient/Water/wave.nvv", Game.CORE, "GameEngineDevice/Source/W3DDevice/GameClient/Water/wave.nvv") + #unify_move_file(Game.ZEROHOUR, "GameEngine/Include/GameClient/Snow.h", Game.CORE, "GameEngine/Include/GameClient/Snow.h") + #unify_move_file(Game.ZEROHOUR, "GameEngine/Source/GameClient/Snow.cpp", Game.CORE, "GameEngine/Source/GameClient/Snow.cpp") + #unify_move_file(Game.ZEROHOUR, "GameEngineDevice/Include/W3DDevice/GameClient/BaseHeightMap.h", Game.CORE, "GameEngineDevice/Include/W3DDevice/GameClient/BaseHeightMap.h") + #unify_move_file(Game.ZEROHOUR, "GameEngineDevice/Include/W3DDevice/GameClient/FlatHeightMap.h", Game.CORE, "GameEngineDevice/Include/W3DDevice/GameClient/FlatHeightMap.h") + #unify_move_file(Game.ZEROHOUR, "GameEngineDevice/Include/W3DDevice/GameClient/W3DPropBuffer.h", Game.CORE, "GameEngineDevice/Include/W3DDevice/GameClient/W3DPropBuffer.h") + #unify_move_file(Game.ZEROHOUR, "GameEngineDevice/Include/W3DDevice/GameClient/W3DSnow.h", Game.CORE, "GameEngineDevice/Include/W3DDevice/GameClient/W3DSnow.h") + #unify_move_file(Game.ZEROHOUR, "GameEngineDevice/Include/W3DDevice/GameClient/W3DTerrainBackground.h", Game.CORE, "GameEngineDevice/Include/W3DDevice/GameClient/W3DTerrainBackground.h") + #unify_move_file(Game.ZEROHOUR, "GameEngineDevice/Include/W3DDevice/GameClient/Module/W3DPropDraw.h", Game.CORE, "GameEngineDevice/Include/W3DDevice/GameClient/Module/W3DPropDraw.h") + #unify_move_file(Game.ZEROHOUR, "GameEngineDevice/Include/W3DDevice/GameClient/Module/W3DTreeDraw.h", Game.CORE, "GameEngineDevice/Include/W3DDevice/GameClient/Module/W3DTreeDraw.h") + #unify_move_file(Game.ZEROHOUR, "GameEngineDevice/Source/W3DDevice/GameClient/BaseHeightMap.cpp", Game.CORE, "GameEngineDevice/Source/W3DDevice/GameClient/BaseHeightMap.cpp") + #unify_move_file(Game.ZEROHOUR, "GameEngineDevice/Source/W3DDevice/GameClient/FlatHeightMap.cpp", Game.CORE, "GameEngineDevice/Source/W3DDevice/GameClient/FlatHeightMap.cpp") + #unify_move_file(Game.ZEROHOUR, "GameEngineDevice/Source/W3DDevice/GameClient/W3DPropBuffer.cpp", Game.CORE, "GameEngineDevice/Source/W3DDevice/GameClient/W3DPropBuffer.cpp") + #unify_move_file(Game.ZEROHOUR, "GameEngineDevice/Source/W3DDevice/GameClient/W3DSnow.cpp", Game.CORE, "GameEngineDevice/Source/W3DDevice/GameClient/W3DSnow.cpp") + #unify_move_file(Game.ZEROHOUR, "GameEngineDevice/Source/W3DDevice/GameClient/W3DTerrainBackground.cpp", Game.CORE, "GameEngineDevice/Source/W3DDevice/GameClient/W3DTerrainBackground.cpp") + #unify_move_file(Game.ZEROHOUR, "GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DPropDraw.cpp", Game.CORE, "GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DPropDraw.cpp") + #unify_move_file(Game.ZEROHOUR, "GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DTreeDraw.cpp", Game.CORE, "GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DTreeDraw.cpp") + + #unify_file(Game.ZEROHOUR, "GameEngine/Include/Common/MapObject.h", Game.CORE, "GameEngine/Include/Common/MapObject.h") + #unify_file(Game.ZEROHOUR, "GameEngine/Include/GameClient/MapUtil.h", Game.CORE, "GameEngine/Include/GameClient/MapUtil.h") + #unify_file(Game.ZEROHOUR, "GameEngine/Include/GameClient/TerrainRoads.h", Game.CORE, "GameEngine/Include/GameClient/TerrainRoads.h") + #unify_file(Game.ZEROHOUR, "GameEngine/Include/GameClient/TerrainVisual.h", Game.CORE, "GameEngine/Include/GameClient/TerrainVisual.h") + #unify_file(Game.ZEROHOUR, "GameEngine/Source/GameClient/MapUtil.cpp", Game.CORE, "GameEngine/Source/GameClient/MapUtil.cpp") + #unify_file(Game.ZEROHOUR, "GameEngine/Source/GameClient/Terrain/TerrainRoads.cpp", Game.CORE, "GameEngine/Source/GameClient/Terrain/TerrainRoads.cpp") + #unify_file(Game.ZEROHOUR, "GameEngine/Source/GameClient/Terrain/TerrainVisual.cpp", Game.CORE, "GameEngine/Source/GameClient/Terrain/TerrainVisual.cpp") + #unify_file(Game.ZEROHOUR, "GameEngineDevice/Include/W3DDevice/GameClient/HeightMap.h", Game.CORE, "GameEngineDevice/Include/W3DDevice/GameClient/HeightMap.h") + #unify_file(Game.ZEROHOUR, "GameEngineDevice/Include/W3DDevice/GameClient/TerrainTex.h", Game.CORE, "GameEngineDevice/Include/W3DDevice/GameClient/TerrainTex.h") + #unify_file(Game.ZEROHOUR, "GameEngineDevice/Include/W3DDevice/GameClient/TileData.h", Game.CORE, "GameEngineDevice/Include/W3DDevice/GameClient/TileData.h") + #unify_file(Game.ZEROHOUR, "GameEngineDevice/Include/W3DDevice/GameClient/W3DTerrainTracks.h", Game.CORE, "GameEngineDevice/Include/W3DDevice/GameClient/W3DTerrainTracks.h") + #unify_file(Game.ZEROHOUR, "GameEngineDevice/Include/W3DDevice/GameClient/W3DTerrainVisual.h", Game.CORE, "GameEngineDevice/Include/W3DDevice/GameClient/W3DTerrainVisual.h") + #unify_file(Game.ZEROHOUR, "GameEngineDevice/Include/W3DDevice/GameClient/W3DTreeBuffer.h", Game.CORE, "GameEngineDevice/Include/W3DDevice/GameClient/W3DTreeBuffer.h") + #unify_file(Game.ZEROHOUR, "GameEngineDevice/Include/W3DDevice/GameClient/WorldHeightMap.h", Game.CORE, "GameEngineDevice/Include/W3DDevice/GameClient/WorldHeightMap.h") + #unify_file(Game.ZEROHOUR, "GameEngineDevice/Source/W3DDevice/GameClient/HeightMap.cpp", Game.CORE, "GameEngineDevice/Source/W3DDevice/GameClient/HeightMap.cpp") + #unify_file(Game.ZEROHOUR, "GameEngineDevice/Source/W3DDevice/GameClient/TerrainTex.cpp", Game.CORE, "GameEngineDevice/Source/W3DDevice/GameClient/TerrainTex.cpp") + #unify_file(Game.ZEROHOUR, "GameEngineDevice/Source/W3DDevice/GameClient/TileData.cpp", Game.CORE, "GameEngineDevice/Source/W3DDevice/GameClient/TileData.cpp") + #unify_file(Game.ZEROHOUR, "GameEngineDevice/Source/W3DDevice/GameClient/W3DTerrainTracks.cpp", Game.CORE, "GameEngineDevice/Source/W3DDevice/GameClient/W3DTerrainTracks.cpp") + #unify_file(Game.ZEROHOUR, "GameEngineDevice/Source/W3DDevice/GameClient/W3DTerrainVisual.cpp", Game.CORE, "GameEngineDevice/Source/W3DDevice/GameClient/W3DTerrainVisual.cpp") + #unify_file(Game.ZEROHOUR, "GameEngineDevice/Source/W3DDevice/GameClient/W3DTreeBuffer.cpp", Game.CORE, "GameEngineDevice/Source/W3DDevice/GameClient/W3DTreeBuffer.cpp") + #unify_file(Game.ZEROHOUR, "GameEngineDevice/Source/W3DDevice/GameClient/WorldHeightMap.cpp", Game.CORE, "GameEngineDevice/Source/W3DDevice/GameClient/WorldHeightMap.cpp") + return