summaryrefslogtreecommitdiff
path: root/3dc/Kshape.c
diff options
context:
space:
mode:
authorRebellion Developments <rebellion@nomail>2000-03-16 11:25:00 +0100
committerPatryk Obara <dreamer.tan@gmail.com>2019-08-19 05:45:17 +0200
commit218ca90543758a20ac326e444ca0643174ca7384 (patch)
tree16bfe3e5307f9f515489000f28728224291a0e3b /3dc/Kshape.c
Import Aliens vs Predator - Gold (Build 116)
Source code release, imported from: https://www.gamefront.com/games/aliens-vs-predator-3/file/avp-gold-complete-source-code All text files were converted to Unix format.
Diffstat (limited to '3dc/Kshape.c')
-rw-r--r--3dc/Kshape.c8501
1 files changed, 8501 insertions, 0 deletions
diff --git a/3dc/Kshape.c b/3dc/Kshape.c
new file mode 100644
index 0000000..6f6ef94
--- /dev/null
+++ b/3dc/Kshape.c
@@ -0,0 +1,8501 @@
+/*KJL************************************************************************************
+* kshape.c - replacement for all the pipeline stuff previously done in shape.c & clip.c *
+************************************************************************************KJL*/
+#include "3dc.h"
+#include <math.h>
+#include "module.h"
+#include "inline.h"
+
+#include "stratdef.h"
+#include "gamedef.h"
+
+#include "kshape.h"
+#include "kzsort.h"
+#include "frustrum.h"
+
+#define UseLocalAssert Yes
+#include "ourasert.h"
+#include "equipmnt.h"
+#include "bh_pred.h"
+#include "bh_marin.h"
+#include "bh_corpse.h"
+#include "bh_debri.h"
+#include "bh_weap.h"
+#include "bh_types.h"
+#include "pldghost.h"
+#include "particle.h"
+#include "vision.h"
+#include "sfx.h"
+#include "d3d_render.h"
+#include "avpview.h"
+#include "sphere.h"
+#include "detaillevels.h"
+#include "avp_userprofile.h"
+
+#if SOFTWARE_RENDERER
+#define D3D_ZBufferedGouraudTexturedPolygon_Output Software_ZBufferedGouraudTexturedPolygon_Output
+#endif
+#define ALIENS_LIFEFORCE_GLOW_COLOUR 0x20ff8080
+#define MARINES_LIFEFORCE_GLOW_COLOUR 0x208080ff
+#define PREDATORS_LIFEFORCE_GLOW_COLOUR 0x2080ff80
+
+/* KJL 15:02:50 05/14/97 - new max lighting intensity */
+#define MAX_INTENSITY (65536*4-1)
+
+extern VIEWDESCRIPTORBLOCK *Global_VDB_Ptr;
+extern DISPLAYBLOCK *Global_ODB_Ptr;
+extern EXTRAITEMDATA *Global_EID_Ptr;
+extern int *Global_EID_IPtr;
+extern int ScanDrawMode;
+extern int ZBufferMode;
+extern int NormalFrameTime;
+
+extern SHAPEHEADER *Global_ShapeHeaderPtr;
+extern int *Global_ShapePoints;
+extern int **Global_ShapeItems;
+extern int *Global_ShapeNormals;
+extern int *Global_ShapeVNormals;
+extern int **Global_ShapeTextures;
+
+extern MATRIXCH LToVMat;
+extern EULER LToVMat_Euler;
+extern MATRIXCH WToLMat;
+extern VECTORCH LocalView;
+extern VECTORCH LocalLightCH;
+
+extern int NumLightSourcesForObject;
+extern LIGHTBLOCK *LightSourcesForObject[];
+
+#if SupportMorphing
+extern MORPHDISPLAY MorphDisplay;
+#endif
+
+extern int VideoModeType;
+extern int GlobalAmbience;
+extern int NumActiveBlocks;
+
+extern DISPLAYBLOCK *ActiveBlockList[];
+extern SHAPEHEADER **mainshapelist;
+
+int MirroringActive=0;
+int MirroringAxis=-149*2;
+
+VECTORCHF FogPosition;
+float FogMagnitude;
+#define VOLUMETRIC_FOG 0
+#define UNDERWATER 0
+#define SPATIAL_SHOCKWAVE 0
+float CameraZoomScale;
+
+int DrawFullBright;
+
+int TripTasticPhase;
+
+void SetupShapePipeline(void);
+void ShapePipeline(SHAPEHEADER *shapePtr);
+
+static void GouraudPolygon_Construct(POLYHEADER *polyPtr);
+static void GouraudPolygon_Output(POLYHEADER *inputPolyPtr, RENDERVERTEX *renderVerticesPtr);
+
+static void TexturedPolygon_Construct(POLYHEADER *polyPtr);
+static void TexturedPolygon_Output(POLYHEADER *inputPolyPtr, RENDERVERTEX *renderVerticesPtr);
+
+
+static void GouraudTexturedPolygon_Construct(POLYHEADER *polyPtr);
+
+static void (*VertexIntensity)(RENDERVERTEX *renderVertexPtr);
+static void VertexIntensity_Hierarchical(RENDERVERTEX *renderVertexPtr);
+static void VertexIntensity_PreLit(RENDERVERTEX *renderVertexPtr);
+static void VertexIntensity_Pred_Thermal(RENDERVERTEX *renderVertexPtr);
+static void VertexIntensity_Pred_SeeAliens(RENDERVERTEX *renderVertexPtr);
+static void VertexIntensity_Pred_SeePredatorTech(RENDERVERTEX *renderVertexPtr);
+static void VertexIntensity_ImageIntensifier(RENDERVERTEX *renderVertexPtr);
+static void VertexIntensity_Standard(RENDERVERTEX *renderVertexPtr);
+static void VertexIntensity_Alien_Sense(RENDERVERTEX *renderVertexPtr);
+
+static void VertexIntensity_Standard_Opt(RENDERVERTEX *renderVertexPtr);
+static void VertexIntensity_FullBright(RENDERVERTEX *renderVertexPtr);
+static void VertexIntensity_DiscoInferno(RENDERVERTEX *renderVertexPtr);
+static void VertexIntensity_Underwater(RENDERVERTEX *renderVertexPtr);
+
+
+extern void CreateTxAnimUVArray(int *txa_data, int *uv_array, int *shapeitemptr);
+
+void PredatorThermalVision_ShapePipeline(SHAPEHEADER *shapePtr);
+void PredatorSeeAliensVision_ShapePipeline(SHAPEHEADER *shapePtr);
+static void CloakedPolygon_Construct(POLYHEADER *polyPtr);
+static void PredatorThermalVisionPolygon_Construct(POLYHEADER *polyPtr);
+static void PredatorSeeAliensVisionPolygon_Construct(POLYHEADER *polyPtr);
+void DoAlienEnergyView(DISPLAYBLOCK *dispPtr);
+static void FindAlienEnergySource_Recursion(HMODELCONTROLLER *controllerPtr, SECTION_DATA *sectionDataPtr, unsigned int colour);
+void SquishPoints(SHAPEINSTR *shapeinstrptr);
+void MorphPoints(SHAPEINSTR *shapeinstrptr);
+void TranslateShapeVertices(SHAPEINSTR *shapeinstrptr);
+static void ParticlePolygon_Construct(PARTICLE *particlePtr);
+void RenderMirroredDecal(DECAL *decalPtr);
+static void DecalPolygon_Construct(DECAL *decalPtr);
+void RenderShaftOfLight2(MODULE *modulePtr);
+void FindIntersectionWithYPlane(VECTORCH *startPtr, VECTORCH *directionPtr, VECTORCH *intersectionPtr);
+void FindZFromXYIntersection(VECTORCH *startPtr, VECTORCH *directionPtr, VECTORCH *intersectionPtr);
+void AddToTranslucentPolyList(POLYHEADER *inputPolyPtr,RENDERVERTEX *renderVerticesPtr);
+void DrawWaterFallPoly(VECTORCH *v);
+
+#if platform_pc
+extern int sine[];
+extern int cosine[];
+#endif
+
+
+//extern int ItemCount;
+
+
+/*KJL************************************************************************************
+* N.B. All the following global variables have their first elements initialised so that *
+* they will end up in high memory on the Saturn. *
+************************************************************************************KJL*/
+
+VECTORCH Global_LightVector={1,};
+
+/*
+ Global variables and arrays
+*/
+
+VECTORCH RotatedPts[maxrotpts]={1,};
+int ItemColour=1;
+
+
+
+#if SupportMorphing
+
+#if (LazyEvaluationForMorphing == No)
+VECTORCH MorphedPts[maxmorphPts];
+#endif
+
+
+#endif /* SupportMorphing */
+
+
+#if Saturn
+extern int PolygonSubdivideEntry(POLYHEADER* itemptr);
+#endif
+
+static COLOURINTENSITIES ColourIntensityArray[maxrotpts];
+
+
+
+RENDERPOLYGON RenderPolygon={1,};
+RENDERVERTEX VerticesBuffer[9]={1,};
+static RENDERVERTEX TriangleVerticesBuffer[3]={1,};
+
+static int *VertexNumberPtr=(int*)1;
+
+extern struct KItem KItemList[maxpolyptrs];
+extern int *MorphedObjectPointsPtr;
+
+#define MAX_NO_OF_TRANSLUCENT_POLYGONS 1000
+RENDERPOLYGON TranslucentPolygons[MAX_NO_OF_TRANSLUCENT_POLYGONS];
+POLYHEADER TranslucentPolygonHeaders[MAX_NO_OF_TRANSLUCENT_POLYGONS];
+int CurrentNumberOfTranslucentPolygons;
+
+/* KJL 10:25:44 7/23/97 - this offset is used to push back the normal game gfx,
+so that the HUD can be drawn over the top without sinking into walls, etc. */
+int HeadUpDisplayZOffset=0;
+
+extern int CloakingPhase;
+static VECTORCH ObjectCentre;
+static int HierarchicalObjectsLowestYValue;
+
+HEATSOURCE HeatSourceList[MAX_NUMBER_OF_HEAT_SOURCES];
+int NumberOfHeatSources;
+int CloakingMode;
+char CloakedPredatorIsMoving;
+static VECTORCH LocalCameraZAxis;
+
+static int ObjectCounter;
+
+extern void InitialiseLightIntensityStamps(void)
+{
+ int i = maxrotpts;
+ do
+ {
+ i--;
+ ColourIntensityArray[i].Stamp=0;
+ }
+ while(i);
+ ObjectCounter = 0;
+
+}
+
+
+void SetupShapePipeline(void)
+{
+ #if VOLUMETRIC_FOG
+ {
+// VECTORCH v = {-30399, -1792, 1050}; // genshd1
+// VECTORCH v = {49937,-4000,-37709}; // hangar
+// VECTORCH v = {-185,0,642};
+// VECTORCH v = {6894,469,-13203};
+ VECTORCH v = {73608,3582,56211};
+ TranslatePointIntoViewspace(&v);
+ FogPosition.vx = v.vx;
+ FogPosition.vy = v.vy;
+ FogPosition.vz = v.vz;
+ FogMagnitude = FogPosition.vx*FogPosition.vx+FogPosition.vy*FogPosition.vy+FogPosition.vz*FogPosition.vz;
+ }
+ #endif
+
+ /* Set up these global pointers */
+ Global_ShapePoints = *(Global_ShapeHeaderPtr->points);
+ Global_ShapeTextures = Global_ShapeHeaderPtr->sh_textures;
+
+ if(Global_ODB_Ptr->ObEIDPtr)
+ {
+ Global_EID_Ptr = Global_ODB_Ptr->ObEIDPtr;
+ Global_EID_IPtr = (int *) Global_ODB_Ptr->ObEIDPtr;
+ }
+ else
+ {
+ Global_EID_Ptr = Global_ShapeHeaderPtr->sh_extraitemdata;
+ Global_EID_IPtr = (int *) Global_ShapeHeaderPtr->sh_extraitemdata;
+ }
+
+ if(Global_ShapeHeaderPtr->sh_normals)
+ {
+ Global_ShapeNormals = *(Global_ShapeHeaderPtr->sh_normals);
+ }
+ else
+ {
+ Global_ShapeNormals = 0;
+ }
+
+ if(Global_ShapeHeaderPtr->sh_vnormals)
+ {
+ Global_ShapeVNormals = *(Global_ShapeHeaderPtr->sh_vnormals);
+ }
+ else
+ {
+ Global_ShapeVNormals = 0;
+ }
+
+
+ // if((Global_ODB_Ptr->ObStrategyBlock)&&(Global_ODB_Ptr->ObStrategyBlock->I_SBtype == I_BehaviourQueenAlien))
+// Global_ODB_Ptr->ObFlags3 &= ObFlag3_NoLightDot;
+
+ ObjectCounter++;
+
+}
+
+void ChooseLightingModel(DISPLAYBLOCK *dispPtr)
+{
+ LOCALASSERT(dispPtr);
+ LOCALASSERT(dispPtr->ObShapeData);
+
+ if (DrawFullBright)
+ {
+ VertexIntensity = VertexIntensity_FullBright;
+ }
+ else if (DISCOINFERNO_CHEATMODE || TRIPTASTIC_CHEATMODE)
+ {
+ VertexIntensity = VertexIntensity_DiscoInferno;
+ }
+ else if (UNDERWATER_CHEATMODE)
+ {
+ VertexIntensity = VertexIntensity_Underwater;
+ }
+ else
+ {
+ switch (CurrentVisionMode)
+ {
+ default:
+ case VISION_MODE_NORMAL:
+ {
+ VertexIntensity = VertexIntensity_Standard_Opt;
+ break;
+ }
+ case VISION_MODE_ALIEN_SENSE:
+ {
+ VertexIntensity = VertexIntensity_Alien_Sense;
+ break;
+ }
+ case VISION_MODE_IMAGEINTENSIFIER:
+ {
+ VertexIntensity = VertexIntensity_ImageIntensifier;
+ break;
+ }
+ case VISION_MODE_PRED_THERMAL:
+ {
+ VertexIntensity = VertexIntensity_Pred_Thermal;
+ break;
+ }
+ case VISION_MODE_PRED_SEEALIENS:
+ {
+ VertexIntensity = VertexIntensity_Pred_SeeAliens;
+ break;
+ }
+ case VISION_MODE_PRED_SEEPREDTECH:
+ {
+ VertexIntensity = VertexIntensity_Pred_SeePredatorTech;
+ break;
+ }
+ }
+ }
+}
+
+
+
+/*KJL**********************************************************************************
+* ShapePipeline() - this function processes a shape for rendering by considering each *
+* polygon (item) in turn. *
+**********************************************************************************KJL*/
+void ShapePipeline(SHAPEHEADER *shapePtr)
+{
+ int numitems= shapePtr->numitems;
+ int **itemArrayPtr = shapePtr->items;
+ #if 0
+ char objectCompletelyInView;
+ #endif
+ LOCALASSERT(numitems);
+
+ switch(CurrentVisionMode)
+ {
+ case VISION_MODE_PRED_THERMAL:
+ {
+ /* if we have an object with heat sources, draw it as such */
+ if (NumberOfHeatSources)//||((Global_ODB_Ptr->ObStrategyBlock)&&(Global_ODB_Ptr->ObStrategyBlock->I_SBtype == I_BehaviourAlien)))
+ {
+ PredatorThermalVision_ShapePipeline(shapePtr);
+ return;
+ }
+ break;
+ }
+ case VISION_MODE_PRED_SEEALIENS:
+ {
+ STRATEGYBLOCK *sbPtr = Global_ODB_Ptr->ObStrategyBlock;
+ if(sbPtr)
+ {
+ int useVision=0;
+ switch (sbPtr->I_SBtype)
+ {
+ case I_BehaviourAutoGun:
+ case I_BehaviourAlien:
+ case I_BehaviourQueenAlien:
+ case I_BehaviourFaceHugger:
+ case I_BehaviourPredatorAlien:
+ case I_BehaviourXenoborg:
+ {
+ useVision=1;
+ break;
+ }
+ case I_BehaviourMarine:
+ {
+ MARINE_STATUS_BLOCK *marineStatusPointer = (MARINE_STATUS_BLOCK *)(sbPtr->SBdataptr);
+ GLOBALASSERT(marineStatusPointer);
+
+ if (marineStatusPointer->Android)
+ {
+ useVision=1;
+ }
+ break;
+ }
+
+ case I_BehaviourNetGhost:
+ {
+ NETGHOSTDATABLOCK *ghostDataPtr = (NETGHOSTDATABLOCK *)Global_ODB_Ptr->ObStrategyBlock->SBdataptr;
+
+ if (ghostDataPtr->type==I_BehaviourAlienPlayer || ghostDataPtr->type==I_BehaviourAlien
+ || (ghostDataPtr->type==I_BehaviourNetCorpse&&ghostDataPtr->subtype==I_BehaviourAlienPlayer) )
+ {
+ useVision=1;
+ }
+ break;
+ }
+
+ case I_BehaviourNetCorpse:
+ {
+ NETCORPSEDATABLOCK *corpseDataPtr = (NETCORPSEDATABLOCK *)sbPtr->SBdataptr;
+ if (corpseDataPtr->Android || corpseDataPtr->Type==I_BehaviourAlienPlayer || corpseDataPtr->Type==I_BehaviourAlien)
+ {
+ useVision=1;
+ }
+ break;
+ }
+ case I_BehaviourHierarchicalFragment:
+ {
+ HDEBRIS_BEHAV_BLOCK *debrisDataPtr = (HDEBRIS_BEHAV_BLOCK *)sbPtr->SBdataptr;
+ if (debrisDataPtr->Type==I_BehaviourAlien
+ ||debrisDataPtr->Type==I_BehaviourQueenAlien
+ ||debrisDataPtr->Type==I_BehaviourPredatorAlien
+ ||debrisDataPtr->Type==I_BehaviourAutoGun
+ ||debrisDataPtr->Android)
+ {
+ useVision=1;
+ }
+ break;
+ }
+ case I_BehaviourSpeargunBolt:
+ {
+ SPEAR_BEHAV_BLOCK *spearDataPtr = (SPEAR_BEHAV_BLOCK *)sbPtr->SBdataptr;
+ if (spearDataPtr->SpearThroughFragment) // more flags required!
+ if (spearDataPtr->Type==I_BehaviourAlien
+ ||spearDataPtr->Type==I_BehaviourPredatorAlien
+ ||spearDataPtr->Type==I_BehaviourAutoGun)
+ {
+ useVision=1;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ if (useVision)
+ {
+ PredatorSeeAliensVision_ShapePipeline(shapePtr);
+ return;
+ }
+ }
+ break;
+ }
+ case VISION_MODE_PRED_SEEPREDTECH:
+ {
+ STRATEGYBLOCK *sbPtr = Global_ODB_Ptr->ObStrategyBlock;
+ if(sbPtr)
+ {
+ int useVision=0;
+ switch (sbPtr->I_SBtype)
+ {
+ case I_BehaviourPredator:
+ {
+ PREDATOR_STATUS_BLOCK *predData = (PREDATOR_STATUS_BLOCK *)Global_ODB_Ptr->ObStrategyBlock->SBdataptr;
+
+ if (!predData->CloakingEffectiveness)
+ {
+ useVision=1;
+ }
+ break;
+ }
+ case I_BehaviourNPCPredatorDisc:
+ case I_BehaviourPredatorDisc_SeekTrack:
+ {
+ useVision=1;
+ break;
+ }
+ case I_BehaviourNetGhost:
+ {
+ NETGHOSTDATABLOCK *ghostDataPtr = (NETGHOSTDATABLOCK *)Global_ODB_Ptr->ObStrategyBlock->SBdataptr;
+
+ if((ghostDataPtr->CloakingEffectiveness == 0)
+ && (ghostDataPtr->type==I_BehaviourPredatorPlayer || ghostDataPtr->type==I_BehaviourPredator
+ || (ghostDataPtr->type==I_BehaviourInanimateObject&&ghostDataPtr->IOType==IOT_Ammo&&ghostDataPtr->subtype==AMMO_PRED_DISC)
+ || (ghostDataPtr->type==I_BehaviourPredatorDisc_SeekTrack)
+ || (ghostDataPtr->type==I_BehaviourNetCorpse&&ghostDataPtr->subtype==I_BehaviourPredatorPlayer) ))
+ {
+ useVision=1;
+ }
+ break;
+ }
+
+ case I_BehaviourNetCorpse:
+ {
+ NETCORPSEDATABLOCK *corpseDataPtr = (NETCORPSEDATABLOCK *)sbPtr->SBdataptr;
+ if (corpseDataPtr->Type==I_BehaviourPredatorPlayer || corpseDataPtr->Type==I_BehaviourPredator)
+ {
+ useVision=1;
+ }
+ break;
+ }
+ case I_BehaviourHierarchicalFragment:
+ {
+ HDEBRIS_BEHAV_BLOCK *debrisDataPtr = (HDEBRIS_BEHAV_BLOCK *)sbPtr->SBdataptr;
+ if (debrisDataPtr->Type==I_BehaviourPredator)
+ {
+ useVision=1;
+ }
+ break;
+ }
+ case I_BehaviourInanimateObject:
+ {
+ INANIMATEOBJECT_STATUSBLOCK* objStatPtr = (INANIMATEOBJECT_STATUSBLOCK*) sbPtr->SBdataptr;
+
+ switch(objStatPtr->typeId)
+ {
+ case IOT_FieldCharge:
+ {
+ useVision = 1;
+ break;
+ }
+ case IOT_Ammo:
+ {
+ if (objStatPtr->subType == AMMO_PRED_RIFLE || objStatPtr->subType == AMMO_PRED_DISC)
+ {
+ useVision = 1;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ if (useVision)
+ {
+ PredatorSeeAliensVision_ShapePipeline(shapePtr);
+ return;
+ }
+ }
+ else if (!Global_ODB_Ptr->ObMyModule)
+ {
+ PLAYER_STATUS *playerStatusPtr= (PLAYER_STATUS *) (Player->ObStrategyBlock->SBdataptr);
+ if (!(playerStatusPtr->cloakOn||playerStatusPtr->CloakingEffectiveness!=0))
+ {
+ PredatorSeeAliensVision_ShapePipeline(shapePtr);
+ return;
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+// if((Global_ODB_Ptr->ObStrategyBlock)&&(Global_ODB_Ptr->ObStrategyBlock->I_SBtype == I_BehaviourAlien))
+ //textprint("shape alien\n");
+ #if 0
+ objectCompletelyInView = ObjectCompletelyWithinFrustrum(Global_ODB_Ptr);
+ if(!objectCompletelyInView) TestVerticesWithFrustrum();
+ #else
+ TestVerticesWithFrustrum();
+ #endif
+
+ #if 1
+ /* interesting hack for predator cloaking */
+ if(Global_ODB_Ptr->ObStrategyBlock)
+ {
+ PRED_CLOAKSTATE cloakingStatus = PCLOAK_Off;
+
+ if(Global_ODB_Ptr->ObStrategyBlock->I_SBtype == I_BehaviourNetGhost)
+ {
+ NETGHOSTDATABLOCK *ghostData = (NETGHOSTDATABLOCK *)Global_ODB_Ptr->ObStrategyBlock->SBdataptr;
+
+ if(ghostData->CloakingEffectiveness)
+ {
+ cloakingStatus = PCLOAK_On;
+ CloakingMode = ONE_FIXED*5/4-ghostData->CloakingEffectiveness;
+ }
+ }
+ if(Global_ODB_Ptr->ObStrategyBlock->I_SBtype == I_BehaviourPredator)
+ {
+ PREDATOR_STATUS_BLOCK *predData = (PREDATOR_STATUS_BLOCK *)Global_ODB_Ptr->ObStrategyBlock->SBdataptr;
+
+ if (predData->CloakingEffectiveness)
+ {
+ cloakingStatus = PCLOAK_On;
+ CloakingMode = ONE_FIXED*5/4-predData->CloakingEffectiveness;//32768;
+ }
+ }
+
+ if (cloakingStatus == PCLOAK_On)
+ {
+ do
+ {
+ POLYHEADER *polyPtr = (POLYHEADER*) (*itemArrayPtr++);
+ int pif;
+ #if 0
+ if (objectCompletelyInView)
+ {
+ pif = PolygonShouldBeDrawn(polyPtr);
+ }
+ else
+ {
+ pif = PolygonWithinFrustrum(polyPtr);
+ }
+ #else
+ pif = PolygonWithinFrustrum(polyPtr);
+ #endif
+ if(pif)
+ {
+
+ #if 1
+ switch(polyPtr->PolyItemType)
+ {
+ case I_ZB_Gouraud3dTexturedPolygon:
+ case I_ZB_Gouraud2dTexturedPolygon:
+ CloakedPolygon_Construct(polyPtr);
+ if (pif!=2)
+ {
+ GouraudTexturedPolygon_ClipWithZ();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudTexturedPolygon_ClipWithNegativeX();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudTexturedPolygon_ClipWithPositiveY();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudTexturedPolygon_ClipWithNegativeY();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudTexturedPolygon_ClipWithPositiveX();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ D3D_ZBufferedCloakedPolygon_Output(polyPtr,RenderPolygon.Vertices);
+ }
+ else D3D_ZBufferedCloakedPolygon_Output(polyPtr,VerticesBuffer);
+ break;
+ default:
+ textprint("found polygon of type %d\n",polyPtr->PolyItemType);
+ break;
+ }
+ #else
+ {
+ CloakedTexturedPolygon_Construct(polyPtr);
+ if (pif!=2)
+ {
+ TexturedPolygon_ClipWithZ();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ TexturedPolygon_ClipWithNegativeX();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ TexturedPolygon_ClipWithPositiveY();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ TexturedPolygon_ClipWithNegativeY();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ TexturedPolygon_ClipWithPositiveX();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ D3D_CloakedPredatorPolygon_Output(polyPtr,RenderPolygon.Vertices);
+ }
+ else D3D_CloakedPredatorPolygon_Output(polyPtr,VerticesBuffer);
+ }
+ #endif
+ }
+ }
+ while(--numitems);
+ return;
+ }
+ }
+ else if (!Global_ODB_Ptr->ObMyModule)
+ {
+ PLAYER_STATUS *playerStatusPtr= (PLAYER_STATUS *) (Player->ObStrategyBlock->SBdataptr);
+ if (playerStatusPtr->cloakOn||playerStatusPtr->CloakingEffectiveness!=0)
+ {
+ int a = GetSin(CloakingPhase&4095);
+ a = MUL_FIXED(a,a);
+ CloakingMode = ONE_FIXED*5/4-playerStatusPtr->CloakingEffectiveness;//32768;
+ do
+ {
+ POLYHEADER *polyPtr = (POLYHEADER*) (*itemArrayPtr++);
+ int pif;
+ pif = PolygonWithinFrustrum(polyPtr);
+ if(pif)
+ {
+ switch(polyPtr->PolyItemType)
+ {
+ case I_ZB_Gouraud3dTexturedPolygon:
+ case I_ZB_Gouraud2dTexturedPolygon:
+ CloakedPolygon_Construct(polyPtr);
+ if (pif!=2)
+ {
+ GouraudTexturedPolygon_ClipWithZ();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudTexturedPolygon_ClipWithNegativeX();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudTexturedPolygon_ClipWithPositiveY();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudTexturedPolygon_ClipWithNegativeY();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudTexturedPolygon_ClipWithPositiveX();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ D3D_ZBufferedCloakedPolygon_Output(polyPtr,RenderPolygon.Vertices);
+ }
+ else D3D_ZBufferedCloakedPolygon_Output(polyPtr,VerticesBuffer);
+ break;
+ default:
+ textprint("found polygon of type %d\n",polyPtr->PolyItemType);
+ break;
+ }
+ }
+ }
+ while(--numitems);
+ return;
+ }
+
+ }
+ #endif
+ #if 0
+// if (Global_ODB_Ptr->ObStrategyBlock && !Global_ODB_Ptr->ObMyModule)
+ {
+ do
+ {
+ POLYHEADER *polyPtr = (POLYHEADER*) (*itemArrayPtr++);
+ int pif;
+
+ pif = PolygonWithinFrustrum(polyPtr);
+
+ if (pif)
+ {
+ GouraudPolygon_Construct(polyPtr);
+
+ if (pif!=2)
+ {
+ GouraudPolygon_ClipWithZ();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudPolygon_ClipWithNegativeX();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudPolygon_ClipWithPositiveY();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudPolygon_ClipWithNegativeY();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudPolygon_ClipWithPositiveX();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ D3D_ZBufferedGouraudPolygon_Output(polyPtr,RenderPolygon.Vertices);
+
+ }
+ else D3D_ZBufferedGouraudPolygon_Output(polyPtr,VerticesBuffer);
+ }
+ }
+ while(--numitems);
+ return;
+ }
+ #endif
+ do
+ {
+ POLYHEADER *polyPtr = (POLYHEADER*) (*itemArrayPtr++);
+ int pif;
+ #if 0
+ if (objectCompletelyInView)
+ {
+ pif = PolygonShouldBeDrawn(polyPtr);
+ }
+ else
+ {
+ pif = PolygonWithinFrustrum(polyPtr);
+ }
+ #else
+ pif = PolygonWithinFrustrum(polyPtr);
+ #endif
+
+ if (pif)
+ {
+ switch(polyPtr->PolyItemType)
+ {
+ #if debug
+ case I_Polyline:
+ case I_FilledPolyline:
+ case I_Wireframe:
+
+ /* NB This is intended to fall through to the GouraudPolygon case */
+ #endif
+// case I_Gouraud3dTexturedPolygon:
+ case I_GouraudPolygon:
+ case I_Gouraud2dTexturedPolygon:
+ case I_Gouraud3dTexturedPolygon:
+ case I_2dTexturedPolygon:
+ case I_3dTexturedPolygon:
+ case I_ZB_2dTexturedPolygon:
+ case I_ZB_3dTexturedPolygon:
+ {
+
+ // LOCALASSERT(0);
+ break;
+ }
+ case I_ZB_GouraudPolygon:
+ {
+// break;
+ // LOCALASSERT(0);
+ GouraudPolygon_Construct(polyPtr);
+
+ if (pif!=2)
+ {
+ GouraudPolygon_ClipWithZ();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudPolygon_ClipWithNegativeX();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudPolygon_ClipWithPositiveY();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudPolygon_ClipWithNegativeY();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudPolygon_ClipWithPositiveX();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ D3D_ZBufferedGouraudPolygon_Output(polyPtr,RenderPolygon.Vertices);
+
+ }
+ else D3D_ZBufferedGouraudPolygon_Output(polyPtr,VerticesBuffer);
+ break;
+ }
+ case I_ZB_Gouraud3dTexturedPolygon:
+ case I_ZB_Gouraud2dTexturedPolygon:
+ {
+ GouraudTexturedPolygon_Construct(polyPtr);
+ if (pif!=2)
+ {
+ /* if this polygon is a quad, split it into two */
+ if(RenderPolygon.NumberOfVertices==4)
+ {
+ RenderPolygon.NumberOfVertices=3;
+ TriangleVerticesBuffer[0] = VerticesBuffer[0];
+ TriangleVerticesBuffer[1] = VerticesBuffer[2];
+ TriangleVerticesBuffer[2] = VerticesBuffer[3];
+
+ GouraudTexturedPolygon_ClipWithZ();
+ if(RenderPolygon.NumberOfVertices<3) goto SecondTriangle;
+ GouraudTexturedPolygon_ClipWithNegativeX();
+ if(RenderPolygon.NumberOfVertices<3) goto SecondTriangle;
+ GouraudTexturedPolygon_ClipWithPositiveY();
+ if(RenderPolygon.NumberOfVertices<3) goto SecondTriangle;
+ GouraudTexturedPolygon_ClipWithNegativeY();
+ if(RenderPolygon.NumberOfVertices<3) goto SecondTriangle;
+ GouraudTexturedPolygon_ClipWithPositiveX();
+ if(RenderPolygon.NumberOfVertices<3) goto SecondTriangle;
+
+ if (polyPtr->PolyFlags & iflag_transparent)
+ {
+ AddToTranslucentPolyList(polyPtr,RenderPolygon.Vertices);
+ }
+ else
+ {
+ D3D_ZBufferedGouraudTexturedPolygon_Output(polyPtr,RenderPolygon.Vertices);
+ }
+
+ SecondTriangle:
+ RenderPolygon.NumberOfVertices=3;
+ VerticesBuffer[0] = TriangleVerticesBuffer[0];
+ VerticesBuffer[1] = TriangleVerticesBuffer[1];
+ VerticesBuffer[2] = TriangleVerticesBuffer[2];
+ }
+ GouraudTexturedPolygon_ClipWithZ();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudTexturedPolygon_ClipWithNegativeX();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudTexturedPolygon_ClipWithPositiveY();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudTexturedPolygon_ClipWithNegativeY();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudTexturedPolygon_ClipWithPositiveX();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+
+// polyPtr->PolyFlags |= iflag_transparent;
+ if (polyPtr->PolyFlags & iflag_transparent)
+ {
+ AddToTranslucentPolyList(polyPtr,RenderPolygon.Vertices);
+ }
+ else
+ {
+ D3D_ZBufferedGouraudTexturedPolygon_Output(polyPtr,RenderPolygon.Vertices);
+ }
+
+ }
+ else
+ {
+// polyPtr->PolyFlags |= iflag_transparent;
+ if (polyPtr->PolyFlags & iflag_transparent)
+ {
+ AddToTranslucentPolyList(polyPtr,VerticesBuffer);
+ }
+ else
+ {
+ D3D_ZBufferedGouraudTexturedPolygon_Output(polyPtr,VerticesBuffer);
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ }
+ while(--numitems);
+}
+
+void PredatorThermalVision_ShapePipeline(SHAPEHEADER *shapePtr)
+{
+ int numitems= shapePtr->numitems;
+ int **itemArrayPtr = shapePtr->items;
+
+ LOCALASSERT(numitems);
+
+ TestVerticesWithFrustrum();
+ do
+ {
+ POLYHEADER *polyPtr = (POLYHEADER*) (*itemArrayPtr++);
+
+ int pif = PolygonWithinFrustrum(polyPtr);
+
+ if (pif)
+ {
+ PredatorThermalVisionPolygon_Construct(polyPtr);
+
+ if (pif!=2)
+ {
+ GouraudPolygon_ClipWithZ();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudPolygon_ClipWithNegativeX();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudPolygon_ClipWithPositiveY();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudPolygon_ClipWithNegativeY();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudPolygon_ClipWithPositiveX();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+
+ D3D_PredatorThermalVisionPolygon_Output(polyPtr,RenderPolygon.Vertices);
+ }
+ else D3D_PredatorThermalVisionPolygon_Output(polyPtr,VerticesBuffer);
+ }
+ }
+ while(--numitems);
+}
+void PredatorSeeAliensVision_ShapePipeline(SHAPEHEADER *shapePtr)
+{
+ int numitems= shapePtr->numitems;
+ int **itemArrayPtr = shapePtr->items;
+
+ LOCALASSERT(numitems);
+
+ TestVerticesWithFrustrum();
+ do
+ {
+ POLYHEADER *polyPtr = (POLYHEADER*) (*itemArrayPtr++);
+
+ switch (polyPtr->PolyItemType)
+ {
+ case I_ZB_Gouraud3dTexturedPolygon:
+ case I_ZB_Gouraud2dTexturedPolygon:
+ {
+ int pif = PolygonWithinFrustrum(polyPtr);
+
+ if (pif)
+ {
+ PredatorSeeAliensVisionPolygon_Construct(polyPtr);
+
+ #if 0
+ if (pif!=2)
+ {
+ GouraudPolygon_ClipWithZ();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudPolygon_ClipWithNegativeX();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudPolygon_ClipWithPositiveY();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudPolygon_ClipWithNegativeY();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudPolygon_ClipWithPositiveX();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+
+ D3D_PredatorSeeAliensVisionPolygon_Output(polyPtr,RenderPolygon.Vertices);
+ }
+ else D3D_PredatorSeeAliensVisionPolygon_Output(polyPtr,VerticesBuffer);
+ #else
+ if (pif!=2)
+ {
+ GouraudTexturedPolygon_ClipWithZ();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudTexturedPolygon_ClipWithNegativeX();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudTexturedPolygon_ClipWithPositiveY();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudTexturedPolygon_ClipWithNegativeY();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudTexturedPolygon_ClipWithPositiveX();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ D3D_ZBufferedGouraudTexturedPolygon_Output(polyPtr,RenderPolygon.Vertices);
+ }
+ else D3D_ZBufferedGouraudTexturedPolygon_Output(polyPtr,VerticesBuffer);
+ #endif
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ while(--numitems);
+}
+
+
+/* CLOAKED POLYGONS */
+static void CloakedPolygon_Construct(POLYHEADER *polyPtr)
+{
+ int *texture_defn_ptr;
+ RENDERVERTEX *renderVerticesPtr = VerticesBuffer;
+ int i = RenderPolygon.NumberOfVertices;
+
+ /* get ptr to uv coords for this polygon */
+ {
+ int texture_defn_index = (polyPtr->PolyColour >> TxDefn);
+ texture_defn_ptr = Global_ShapeTextures[texture_defn_index];
+ }
+
+ VertexNumberPtr = &polyPtr->Poly1stPt;
+
+ /* If this texture is animated the UV array must be calculated */
+ if(polyPtr->PolyFlags & iflag_txanim)
+ {
+ /* Create the UV array */
+ int uv_array[maxpolypts * 2];
+ CreateTxAnimUVArray(texture_defn_ptr, uv_array, (int*)polyPtr);
+ texture_defn_ptr = uv_array;
+
+ do
+ {
+ VECTORCH *vertexPtr = &(RotatedPts[*VertexNumberPtr]);
+ renderVerticesPtr->X = vertexPtr->vx;
+ renderVerticesPtr->Y = vertexPtr->vy;
+ renderVerticesPtr->Z = vertexPtr->vz;
+ renderVerticesPtr->U = texture_defn_ptr[0];
+ renderVerticesPtr->V = texture_defn_ptr[1];
+
+ VertexIntensity(renderVerticesPtr);
+ {
+ VECTORCH mag;
+ int alpha;
+ mag.vx = vertexPtr->vx - Global_ODB_Ptr->ObView.vx;
+ mag.vy = vertexPtr->vy - Global_ODB_Ptr->ObView.vy;
+ mag.vz = vertexPtr->vz - Global_ODB_Ptr->ObView.vz;
+
+
+ if (mag.vx<0) mag.vx = -mag.vx;
+ if (mag.vy<0) mag.vy = -mag.vy;
+ if (mag.vz<0) mag.vz = -mag.vz;
+ alpha = GetSin(((mag.vx+mag.vy+mag.vz)*3+CloakingPhase)&4095);
+
+ renderVerticesPtr->A = MUL_FIXED(alpha,alpha)>>10;
+
+ if(renderVerticesPtr->A==255)
+ {
+ renderVerticesPtr->R = 255;
+ renderVerticesPtr->G = 255;
+ renderVerticesPtr->B = 255;
+ }
+
+ }
+ renderVerticesPtr++;
+ VertexNumberPtr++;
+
+ texture_defn_ptr += 2;
+ }
+ while(--i);
+ }
+ else
+ {
+ do
+ {
+ VECTORCH *vertexPtr = &(RotatedPts[*VertexNumberPtr]);
+ renderVerticesPtr->X = vertexPtr->vx;
+ renderVerticesPtr->Y = vertexPtr->vy;
+ renderVerticesPtr->Z = vertexPtr->vz;
+ renderVerticesPtr->U = texture_defn_ptr[0] << 16;
+ renderVerticesPtr->V = texture_defn_ptr[1] << 16;
+
+ VertexIntensity(renderVerticesPtr);
+ {
+ VECTORCH mag;
+ int alpha;
+
+ mag.vx = vertexPtr->vx - ObjectCentre.vx;
+ mag.vy = vertexPtr->vy - MUL_FIXED(ObjectCentre.vy,87381);
+ mag.vz = vertexPtr->vz - ObjectCentre.vz;
+
+ if (mag.vx<0) mag.vx = -mag.vx;
+ if (mag.vy<0) mag.vy = -mag.vy;
+ if (mag.vz<0) mag.vz = -mag.vz;
+ alpha = GetSin(((mag.vx+mag.vy+mag.vz)*8+CloakingPhase)&4095);
+
+ alpha=MUL_FIXED(alpha,alpha);
+ if (alpha>CloakingMode)
+ {
+ alpha=CloakingMode;
+ }
+ alpha/=256;
+ if (alpha>255) alpha = 255;
+ renderVerticesPtr->A = alpha;
+
+ if(CloakingMode>ONE_FIXED)
+ {
+ alpha = GetSin(((mag.vx+mag.vy+mag.vz)+CloakingPhase)&4095);
+ alpha = MUL_FIXED(alpha,alpha)>>8;
+ if(alpha==255)
+ {
+ renderVerticesPtr->A = 255;
+ renderVerticesPtr->G = 128;
+ renderVerticesPtr->B = 255;
+ }
+ }
+ }
+ renderVerticesPtr++;
+ VertexNumberPtr++;
+
+ texture_defn_ptr += 2;
+ }
+ while(--i);
+ }
+
+}
+
+static void PredatorThermalVisionPolygon_Construct(POLYHEADER *polyPtr)
+{
+ RENDERVERTEX *renderVerticesPtr = VerticesBuffer;
+ int i = RenderPolygon.NumberOfVertices;
+
+ VertexNumberPtr = &polyPtr->Poly1stPt;
+
+ do
+ {
+ VECTORCH *vertexPtr = &(RotatedPts[*VertexNumberPtr]);
+ renderVerticesPtr->X = vertexPtr->vx;
+ renderVerticesPtr->Y = vertexPtr->vy;
+ renderVerticesPtr->Z = vertexPtr->vz;
+
+ {
+ int alpha;
+ if (Global_ODB_Ptr->SpecialFXFlags&SFXFLAG_ISAFFECTEDBYHEAT)
+ {
+ int distanceFromHeatSource = 100000;
+ int sourceNumber=NumberOfHeatSources;
+ while(sourceNumber--)
+ {
+ VECTORCH mag;
+ int m;
+ mag.vx = vertexPtr->vx - HeatSourceList[sourceNumber].Position.vx;
+ mag.vy = vertexPtr->vy - HeatSourceList[sourceNumber].Position.vy;
+ mag.vz = vertexPtr->vz - HeatSourceList[sourceNumber].Position.vz;
+
+ m = Approximate3dMagnitude(&mag)*64;
+
+ if(m<distanceFromHeatSource) distanceFromHeatSource = m;
+ }
+
+ alpha = distanceFromHeatSource+(GetSin(CloakingPhase&4095)>>3);
+ if (alpha>65536) alpha = 65536;
+ }
+ else
+ {
+ alpha = 65536;
+ }
+
+ {
+ int brightness = MUL_FIXED(MUL_FIXED(alpha,alpha),1275);
+
+ if (brightness<256)
+ {
+ renderVerticesPtr->R=255;
+ renderVerticesPtr->G=brightness;
+ renderVerticesPtr->B=0;
+ }
+ else if (brightness<255+256)
+ {
+ int b=brightness-255;
+ renderVerticesPtr->R=(255-b);
+ renderVerticesPtr->G=255;
+ renderVerticesPtr->B=0;
+ }
+ else if (brightness<255*2+256)
+ {
+ int b=brightness-255*2;
+ renderVerticesPtr->R=0;
+ renderVerticesPtr->G=255;
+ renderVerticesPtr->B=b;
+ }
+ else if (brightness<255*3+256)
+ {
+ int b=brightness-255*3;
+ renderVerticesPtr->R=0;
+ renderVerticesPtr->G=255-b;
+ renderVerticesPtr->B=255;
+ }
+ else
+ {
+ int b=brightness-255*4;
+ renderVerticesPtr->R=0;
+ renderVerticesPtr->G=0;
+ renderVerticesPtr->B=255-b/2;
+ }
+ }
+ }
+ renderVerticesPtr++;
+ VertexNumberPtr++;
+ }
+ while(--i);
+}
+
+static void PredatorSeeAliensVisionPolygon_Construct(POLYHEADER *polyPtr)
+{
+ int *texture_defn_ptr;
+ RENDERVERTEX *renderVerticesPtr = VerticesBuffer;
+ int i = RenderPolygon.NumberOfVertices;
+ int alpha;
+
+ VertexNumberPtr = &polyPtr->Poly1stPt;
+
+ {
+ {
+ int texture_defn_index = (polyPtr->PolyColour >> TxDefn);
+ texture_defn_ptr = Global_ShapeTextures[texture_defn_index];
+ }
+
+ /* get ptr to uv coords for this polygon */
+ if(polyPtr->PolyFlags & iflag_txanim)
+ {
+ /* Create the UV array */
+ int uv_array[maxpolypts * 2];
+ CreateTxAnimUVArray(texture_defn_ptr, uv_array, (int*)polyPtr);
+ texture_defn_ptr = uv_array;
+ }
+
+ if( (Global_ODB_Ptr->SpecialFXFlags & SFXFLAG_MELTINGINTOGROUND)
+ &&(Global_ODB_Ptr->ObFlags2 < ONE_FIXED) )
+ {
+ alpha = Global_ODB_Ptr->ObFlags2 >> 8;
+ RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL;
+ }
+ else
+ {
+ alpha = 0;
+ RenderPolygon.TranslucencyMode = TRANSLUCENCY_OFF;
+ }
+
+ do
+ {
+ VECTORCH *vertexPtr = &(RotatedPts[*VertexNumberPtr]);
+
+ if(polyPtr->PolyFlags & iflag_txanim)
+ {
+ renderVerticesPtr->U = texture_defn_ptr[0];
+ renderVerticesPtr->V = texture_defn_ptr[1];
+ }
+ else
+ {
+ renderVerticesPtr->U = texture_defn_ptr[0] << 16;
+ renderVerticesPtr->V = texture_defn_ptr[1] << 16;
+ }
+
+
+ renderVerticesPtr->X = vertexPtr->vx;
+ renderVerticesPtr->Y = vertexPtr->vy;
+ renderVerticesPtr->Z = vertexPtr->vz;
+ {
+ VECTORCH mag = RotatedPts[*VertexNumberPtr];//*(((VECTORCH *)Global_ShapeVNormals) + *VertexNumberPtr);
+ int colour;
+ mag.vx = vertexPtr->vx - Global_ODB_Ptr->ObView.vx;
+ mag.vy = vertexPtr->vy - Global_ODB_Ptr->ObView.vy;
+ mag.vz = vertexPtr->vz - Global_ODB_Ptr->ObView.vz;
+
+ colour = GetSin(((mag.vx+mag.vy+mag.vz)*8+CloakingPhase)&4095);
+ colour = MUL_FIXED(colour,colour);
+ renderVerticesPtr->B = MUL_FIXED(colour,255);
+ renderVerticesPtr->R = renderVerticesPtr->B/2;
+ renderVerticesPtr->G = renderVerticesPtr->B/2;
+
+ colour = MUL_FIXED(colour,colour);
+ colour = MUL_FIXED(colour,colour);
+
+ renderVerticesPtr->SpecularR = colour/1024;
+ renderVerticesPtr->SpecularG = colour/1024;
+ renderVerticesPtr->SpecularB = colour/1024;
+ renderVerticesPtr->A = alpha;
+ }
+
+ texture_defn_ptr += 2;
+ renderVerticesPtr++;
+ VertexNumberPtr++;
+ }
+ while(--i);
+ }
+}
+
+/* GOURAUD POLYGONS */
+static void GouraudPolygon_Construct(POLYHEADER *polyPtr)
+{
+ RENDERVERTEX *renderVerticesPtr = VerticesBuffer;
+ int i = RenderPolygon.NumberOfVertices;
+ VertexNumberPtr = &polyPtr->Poly1stPt;
+ RenderPolygon.TranslucencyMode = TRANSLUCENCY_OFF;
+
+ do
+ {
+ int i;
+ renderVerticesPtr->X = RotatedPts[*VertexNumberPtr].vx;
+ renderVerticesPtr->Y = RotatedPts[*VertexNumberPtr].vy;
+ renderVerticesPtr->Z = RotatedPts[*VertexNumberPtr].vz;
+ VertexIntensity(renderVerticesPtr);
+ i = (renderVerticesPtr->B+renderVerticesPtr->R+renderVerticesPtr->G)/3;
+ renderVerticesPtr->R = i;
+ renderVerticesPtr->G = i;
+ renderVerticesPtr->B = 0;
+ renderVerticesPtr++;
+ VertexNumberPtr++;
+ }
+ while(--i);
+
+}
+
+
+
+
+
+
+/* GOURAUD TEXTURED POLYGONS */
+static void GouraudTexturedPolygon_Construct(POLYHEADER *polyPtr)
+{
+ int *texture_defn_ptr;
+ RENDERVERTEX *renderVerticesPtr = VerticesBuffer;
+ int i = RenderPolygon.NumberOfVertices;
+
+
+ /* get ptr to uv coords for this polygon */
+ {
+ int texture_defn_index = (polyPtr->PolyColour >> TxDefn);
+ texture_defn_ptr = Global_ShapeTextures[texture_defn_index];
+ }
+
+ VertexNumberPtr = &polyPtr->Poly1stPt;
+
+ /* If this texture is animated the UV array must be calculated */
+ if(polyPtr->PolyFlags & iflag_txanim)
+ {
+ /* Create the UV array */
+ int uv_array[maxpolypts * 2];
+ CreateTxAnimUVArray(texture_defn_ptr, uv_array, (int*)polyPtr);
+ texture_defn_ptr = uv_array;
+
+ do
+ {
+ VECTORCH *vertexPtr = &(RotatedPts[*VertexNumberPtr]);
+ if (TRIPTASTIC_CHEATMODE)
+ {
+ renderVerticesPtr->X = vertexPtr->vx+GetSin((CloakingPhase*2 +vertexPtr->vz)&4095)/1024;
+ renderVerticesPtr->Y = vertexPtr->vy+GetSin((CloakingPhase-3000 +vertexPtr->vx)&4095)/1024;
+ renderVerticesPtr->Z = vertexPtr->vz+GetSin((CloakingPhase*3+239+vertexPtr->vy)&4095)/1024;
+ }
+ else if (UNDERWATER_CHEATMODE)
+ {
+ renderVerticesPtr->X = vertexPtr->vx+(GetSin((CloakingPhase/2 +vertexPtr->vz)&4095))/1024;
+ renderVerticesPtr->Y = vertexPtr->vy+(GetSin((CloakingPhase-3000+vertexPtr->vx)&4095))/1024;
+ renderVerticesPtr->Z = vertexPtr->vz+(GetSin((CloakingPhase/3+239+vertexPtr->vy)&4095))/1024;
+ }
+ else
+ {
+ renderVerticesPtr->X = vertexPtr->vx;
+ renderVerticesPtr->Y = vertexPtr->vy;
+ renderVerticesPtr->Z = vertexPtr->vz;
+ }
+ renderVerticesPtr->U = texture_defn_ptr[0];
+ renderVerticesPtr->V = texture_defn_ptr[1];
+
+ if( (Global_ODB_Ptr->SpecialFXFlags & SFXFLAG_MELTINGINTOGROUND)
+ &&(Global_ODB_Ptr->ObFlags2 < ONE_FIXED) )
+ {
+ renderVerticesPtr->A = Global_ODB_Ptr->ObFlags2 >> 8;
+ RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL;
+
+ }
+ else if (polyPtr->PolyFlags & iflag_transparent)
+ {
+ renderVerticesPtr->A = 128;
+ RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL;
+ }
+ else
+ {
+ if (TRIPTASTIC_CHEATMODE)
+ {
+ renderVerticesPtr->A = TripTasticPhase;
+ }
+ else if (MOTIONBLUR_CHEATMODE)
+ {
+ renderVerticesPtr->A = 128;
+ }
+ else
+ {
+ renderVerticesPtr->A = 255;
+ }
+ RenderPolygon.TranslucencyMode = TRANSLUCENCY_OFF;
+ }
+
+ if (polyPtr->PolyFlags & iflag_nolight)
+ {
+ switch (CurrentVisionMode)
+ {
+ default:
+ case VISION_MODE_NORMAL:
+ {
+ renderVerticesPtr->R = 255;
+ renderVerticesPtr->G = 255;
+ renderVerticesPtr->B = 255;
+ renderVerticesPtr->SpecularR = 0;
+ renderVerticesPtr->SpecularG = 0;
+ renderVerticesPtr->SpecularB = 0;
+ break;
+ }
+ case VISION_MODE_IMAGEINTENSIFIER:
+ {
+ renderVerticesPtr->R = 0;
+ renderVerticesPtr->G = 255;
+ renderVerticesPtr->B = 0;
+ renderVerticesPtr->SpecularR = 0;
+ renderVerticesPtr->SpecularG = 0;
+ renderVerticesPtr->SpecularB = 0;
+ break;
+ }
+ case VISION_MODE_PRED_THERMAL:
+ {
+ renderVerticesPtr->R = 0;
+ renderVerticesPtr->G = 0;
+ renderVerticesPtr->B = 255;
+ renderVerticesPtr->SpecularR = 0;
+ renderVerticesPtr->SpecularG = 0;
+ renderVerticesPtr->SpecularB = 0;
+ break;
+ }
+ case VISION_MODE_PRED_SEEALIENS:
+ {
+ renderVerticesPtr->R = 255;
+ renderVerticesPtr->G = 0;
+ renderVerticesPtr->B = 0;
+ renderVerticesPtr->SpecularR = 0;
+ renderVerticesPtr->SpecularG = 0;
+ renderVerticesPtr->SpecularB = 0;
+ break;
+ }
+ case VISION_MODE_PRED_SEEPREDTECH:
+ {
+ renderVerticesPtr->R = 0;
+ renderVerticesPtr->G = 255;
+ renderVerticesPtr->B = 0;
+ renderVerticesPtr->SpecularR = 255;
+ renderVerticesPtr->SpecularG = 0;
+ renderVerticesPtr->SpecularB = 255;
+ break;
+ }
+ }
+
+ }
+ else
+ {
+ VertexIntensity(renderVerticesPtr);
+ }
+ renderVerticesPtr++;
+ VertexNumberPtr++;
+
+ texture_defn_ptr += 2;
+ }
+ while(--i);
+ }
+ else
+ {
+ do
+ {
+ VECTORCH *vertexPtr = &(RotatedPts[*VertexNumberPtr]);
+ #if UNDERWATER
+ renderVerticesPtr->X = vertexPtr->vx+GetSin((CloakingPhase*2 +vertexPtr->vz)&4095)/1024;
+ renderVerticesPtr->Y = vertexPtr->vy+GetSin((CloakingPhase-3000 +vertexPtr->vx)&4095)/1024;
+ renderVerticesPtr->Z = vertexPtr->vz+GetSin((CloakingPhase*3+239+vertexPtr->vy)&4095)/1024;
+ #elif SPATIAL_SHOCKWAVE
+ {
+ int d = Magnitude(vertexPtr);
+ int a = (CloakingPhase&16383)+4000;
+ int u = d-a;
+ int offset;
+
+ if (u>0 && u<8192)
+ {
+ VECTORCH n = *vertexPtr;
+ Normalise(&n);
+ u<<=3;
+ offset = MUL_FIXED(MUL_FIXED(2*u,ONE_FIXED-u),8000) + MUL_FIXED(MUL_FIXED(u,u),8192 );
+ LOCALASSERT(offset>=0 && offset<=8192);
+ renderVerticesPtr->X = MUL_FIXED(n.vx,d);//a+offset*2);
+ renderVerticesPtr->Y = MUL_FIXED(n.vy,d);//a+offset*2);
+ renderVerticesPtr->Z = MUL_FIXED(n.vz,a+offset);
+
+ }
+ else
+ {
+ renderVerticesPtr->X = vertexPtr->vx;
+ renderVerticesPtr->Y = vertexPtr->vy;
+ renderVerticesPtr->Z = vertexPtr->vz;
+ }
+
+ }
+ #else
+ if (TRIPTASTIC_CHEATMODE)
+ {
+ renderVerticesPtr->X = vertexPtr->vx+GetSin((CloakingPhase*2 +vertexPtr->vz)&4095)/1024;
+ renderVerticesPtr->Y = vertexPtr->vy+GetSin((CloakingPhase-3000 +vertexPtr->vx)&4095)/1024;
+ renderVerticesPtr->Z = vertexPtr->vz+GetSin((CloakingPhase*3+239+vertexPtr->vy)&4095)/1024;
+ }
+ else if (UNDERWATER_CHEATMODE)
+ {
+ renderVerticesPtr->X = vertexPtr->vx+(GetSin((CloakingPhase/2 +vertexPtr->vz)&4095))/1024;
+ renderVerticesPtr->Y = vertexPtr->vy+(GetSin((CloakingPhase-3000 +vertexPtr->vx)&4095))/1024;
+ renderVerticesPtr->Z = vertexPtr->vz+(GetSin((CloakingPhase/3+239+vertexPtr->vy)&4095))/1024;
+ }
+ else
+ {
+ renderVerticesPtr->X = vertexPtr->vx;
+ renderVerticesPtr->Y = vertexPtr->vy;
+ renderVerticesPtr->Z = vertexPtr->vz;
+ }
+ #endif
+ renderVerticesPtr->U = texture_defn_ptr[0] << 16;
+ renderVerticesPtr->V = texture_defn_ptr[1] << 16;
+
+ if( (Global_ODB_Ptr->SpecialFXFlags & SFXFLAG_MELTINGINTOGROUND)
+ &&(Global_ODB_Ptr->ObFlags2 < ONE_FIXED) )
+ {
+ renderVerticesPtr->A = Global_ODB_Ptr->ObFlags2 >> 8;
+ RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL;
+
+ }
+ else if (polyPtr->PolyFlags & iflag_transparent)
+ {
+ renderVerticesPtr->A = 128;
+ RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL;
+ }
+ else
+ {
+ #if 0
+ VECTORCH velocity;
+ int a;
+ velocity.vx = Player->ObStrategyBlock->DynPtr->Position.vx - Player->ObStrategyBlock->DynPtr->PrevPosition.vx;
+ velocity.vy = Player->ObStrategyBlock->DynPtr->Position.vy - Player->ObStrategyBlock->DynPtr->PrevPosition.vy;
+ velocity.vz = Player->ObStrategyBlock->DynPtr->Position.vz - Player->ObStrategyBlock->DynPtr->PrevPosition.vz;
+ a = DIV_FIXED(Magnitude(&velocity)*4,NormalFrameTime)/256;
+ if (a>192) a = 192;
+ renderVerticesPtr->A = a;
+
+ #elif 1
+ if (TRIPTASTIC_CHEATMODE)
+ {
+ renderVerticesPtr->A = TripTasticPhase;
+ }
+ else if (MOTIONBLUR_CHEATMODE)
+ {
+ renderVerticesPtr->A = 128;
+ }
+ else
+ {
+ renderVerticesPtr->A = 255;
+ }
+ #endif
+
+ RenderPolygon.TranslucencyMode = TRANSLUCENCY_OFF;
+ }
+
+
+ if (polyPtr->PolyFlags & iflag_nolight)
+ {
+ switch (CurrentVisionMode)
+ {
+ default:
+ case VISION_MODE_NORMAL:
+ {
+ renderVerticesPtr->R = 255;
+ renderVerticesPtr->G = 255;
+ renderVerticesPtr->B = 255;
+ renderVerticesPtr->SpecularR = 0;
+ renderVerticesPtr->SpecularG = 0;
+ renderVerticesPtr->SpecularB = 0;
+ break;
+ }
+ case VISION_MODE_IMAGEINTENSIFIER:
+ {
+ renderVerticesPtr->R = 0;
+ renderVerticesPtr->G = 255;
+ renderVerticesPtr->B = 0;
+ renderVerticesPtr->SpecularR = 0;
+ renderVerticesPtr->SpecularG = 0;
+ renderVerticesPtr->SpecularB = 0;
+ break;
+ }
+ case VISION_MODE_PRED_THERMAL:
+ {
+ renderVerticesPtr->R = 0;
+ renderVerticesPtr->G = 0;
+ renderVerticesPtr->B = 255;
+ renderVerticesPtr->SpecularR = 0;
+ renderVerticesPtr->SpecularG = 0;
+ renderVerticesPtr->SpecularB = 0;
+ break;
+ }
+ case VISION_MODE_PRED_SEEALIENS:
+ {
+ renderVerticesPtr->R = 255;
+ renderVerticesPtr->G = 0;
+ renderVerticesPtr->B = 0;
+ renderVerticesPtr->SpecularR = 0;
+ renderVerticesPtr->SpecularG = 0;
+ renderVerticesPtr->SpecularB = 0;
+ break;
+ }
+ case VISION_MODE_PRED_SEEPREDTECH:
+ {
+ renderVerticesPtr->R = 0;
+ renderVerticesPtr->G = 255;
+ renderVerticesPtr->B = 0;
+ renderVerticesPtr->SpecularR = 255;
+ renderVerticesPtr->SpecularG = 0;
+ renderVerticesPtr->SpecularB = 255;
+ break;
+ }
+ }
+
+ }
+ else
+ {
+ VertexIntensity(renderVerticesPtr);
+ }
+ renderVerticesPtr++;
+ VertexNumberPtr++;
+
+ texture_defn_ptr += 2;
+ }
+ while(--i);
+ }
+
+}
+
+
+
+
+
+static void VertexIntensity_Pred_Thermal(RENDERVERTEX *renderVertexPtr)
+{
+ int redI,blueI,specular=0;
+
+ int vertexNumber = *VertexNumberPtr;
+
+
+
+ if(ColourIntensityArray[vertexNumber].Stamp==ObjectCounter)
+ {
+ renderVertexPtr->R = ColourIntensityArray[vertexNumber].R;
+ renderVertexPtr->G = ColourIntensityArray[vertexNumber].G;
+ renderVertexPtr->B = ColourIntensityArray[vertexNumber].B;
+ renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR;
+ renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG;
+ renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB;
+ return;
+ }
+ {
+ VECTORCH *vertexNormalPtr = ((VECTORCH *)Global_ShapeVNormals) + vertexNumber;
+ VECTORCH *vertexPtr = ((VECTORCH *)Global_ShapePoints)+vertexNumber;
+ LIGHTBLOCK **larrayptr;
+ LIGHTBLOCK *lptr;
+ int i;
+
+ redI = 0;
+
+ larrayptr = LightSourcesForObject;
+
+ for(i = NumLightSourcesForObject; i!=0; i--)
+ {
+
+ VECTORCH vertexToLight;
+ int distanceToLight;
+
+ lptr = *larrayptr++;
+
+ if (lptr->LightFlags & LFlag_PreLitSource) continue;
+
+ vertexToLight.vx = lptr->LocalLP.vx - vertexPtr->vx;
+ vertexToLight.vy = lptr->LocalLP.vy - vertexPtr->vy;
+ vertexToLight.vz = lptr->LocalLP.vz - vertexPtr->vz;
+
+ #if 0
+ distanceToLight = Approximate3dMagnitude(&vertexToLight)/2;
+ #else
+ distanceToLight = Approximate3dMagnitude(&vertexToLight);
+ #endif
+ if(distanceToLight < lptr->LightRange)
+ {
+ int idot = MUL_FIXED(lptr->LightRange-distanceToLight,lptr->BrightnessOverRange);
+
+ if( (distanceToLight>0) && (!(Global_ODB_Ptr->ObFlags3 & ObFlag3_NoLightDot)) )
+ {
+ int dotproduct = MUL_FIXED(vertexNormalPtr->vx,vertexToLight.vx)
+ + MUL_FIXED(vertexNormalPtr->vy,vertexToLight.vy)
+ + MUL_FIXED(vertexNormalPtr->vz,vertexToLight.vz);
+ if(dotproduct>0)
+ {
+ idot = WideMulNarrowDiv(idot,dotproduct,distanceToLight);
+ }
+ else
+ {
+ idot = 0;
+ }
+
+ idot = WideMulNarrowDiv(idot,dotproduct,distanceToLight);
+ }
+
+
+ redI += idot;
+ if (lptr->LightFlags&LFlag_Thermal)
+ {
+ specular += idot;
+ }
+ }
+ }
+ }
+ blueI = ONE_FIXED/2;
+ if (renderVertexPtr->Z>5000)
+ {
+ int a = (renderVertexPtr->Z-5000);
+ if (a>4096) blueI = (blueI*4096)/a;
+ }
+
+ blueI >>= 8;
+
+ if(redI >= ONE_FIXED) redI = (ONE_FIXED - 1);
+ redI >>=8;
+
+ specular>>=6;
+ if (specular >= 255) specular = 255;
+
+ /* KJL 12:41:54 05/10/98 - red/green swapped, whilst testing colours */
+ renderVertexPtr->R = 0;
+ ColourIntensityArray[vertexNumber].R = 0;
+ renderVertexPtr->B = blueI;
+ ColourIntensityArray[vertexNumber].B = blueI;
+ renderVertexPtr->G = redI/2;
+ ColourIntensityArray[vertexNumber].G = redI/2;
+
+
+ renderVertexPtr->SpecularR = specular;//specularR;
+ ColourIntensityArray[vertexNumber].SpecularR = specular;//specularR;
+
+ renderVertexPtr->SpecularG = specular;
+ ColourIntensityArray[vertexNumber].SpecularG = specular;
+
+ renderVertexPtr->SpecularB = specular;//specularB;
+ ColourIntensityArray[vertexNumber].SpecularB = specular;//specularB;
+
+ ColourIntensityArray[vertexNumber].Stamp=ObjectCounter;
+}
+static void VertexIntensity_Pred_SeeAliens(RENDERVERTEX *renderVertexPtr)
+{
+ int redI,blueI,specular=0;
+
+ int vertexNumber = *VertexNumberPtr;
+
+
+
+ if(ColourIntensityArray[vertexNumber].Stamp==ObjectCounter)
+ {
+ renderVertexPtr->R = ColourIntensityArray[vertexNumber].R;
+ renderVertexPtr->G = ColourIntensityArray[vertexNumber].G;
+ renderVertexPtr->B = ColourIntensityArray[vertexNumber].B;
+ renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR;
+ renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG;
+ renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB;
+ return;
+ }
+
+ ColourIntensityArray[vertexNumber].Stamp=ObjectCounter;
+
+ {
+ VECTORCH *vertexPtr = ((VECTORCH *)Global_ShapePoints)+vertexNumber;
+ LIGHTBLOCK **larrayptr;
+ LIGHTBLOCK *lptr;
+ int i;
+
+ redI = 0;
+
+ larrayptr = LightSourcesForObject;
+
+ for(i = NumLightSourcesForObject; i!=0; i--)
+ {
+
+ VECTORCH vertexToLight;
+ int distanceToLight;
+
+ lptr = *larrayptr++;
+
+ if (lptr->LightFlags & LFlag_PreLitSource) continue;
+
+ vertexToLight.vx = lptr->LocalLP.vx - vertexPtr->vx;
+ vertexToLight.vy = lptr->LocalLP.vy - vertexPtr->vy;
+ vertexToLight.vz = lptr->LocalLP.vz - vertexPtr->vz;
+
+ distanceToLight = Approximate3dMagnitude(&vertexToLight);
+ if(distanceToLight < lptr->LightRange)
+ {
+ int idot = MUL_FIXED(lptr->LightRange-distanceToLight,lptr->BrightnessOverRange);
+
+ redI += idot;
+ if(lptr->LightFlags&LFlag_Electrical)
+ {
+ specular += idot;
+ }
+ }
+ }
+ }
+ redI >>=11;
+ if(redI > 255) redI = 255;
+ renderVertexPtr->G = redI;
+ ColourIntensityArray[vertexNumber].G = redI;
+
+
+ blueI = ONE_FIXED/2;
+ if (renderVertexPtr->Z>5000)
+ {
+ int a = (renderVertexPtr->Z-5000);
+ if (a>4096) blueI = (blueI*4096)/a;
+ }
+ /* KJL 12:41:54 05/10/98 - red/green swapped, whilst testing colours */
+ blueI >>= 9;
+ renderVertexPtr->R = blueI;
+ ColourIntensityArray[vertexNumber].R = blueI;
+ renderVertexPtr->B = 0;
+ ColourIntensityArray[vertexNumber].B = 0;
+
+ specular >>=10;
+ if(specular>255) specular = 255;
+ renderVertexPtr->SpecularR = specular;//specularR;
+ ColourIntensityArray[vertexNumber].SpecularR = specular;//specularR;
+ renderVertexPtr->SpecularG = specular;
+ ColourIntensityArray[vertexNumber].SpecularG = specular;
+ renderVertexPtr->SpecularB = specular;//specularB;
+ ColourIntensityArray[vertexNumber].SpecularB = specular;//specularB;
+}
+static void VertexIntensity_Pred_SeePredatorTech(RENDERVERTEX *renderVertexPtr)
+{
+ int redI,blueI;
+
+ int vertexNumber = *VertexNumberPtr;
+
+
+
+ if(ColourIntensityArray[vertexNumber].Stamp==ObjectCounter)
+ {
+ renderVertexPtr->R = ColourIntensityArray[vertexNumber].R;
+ renderVertexPtr->G = ColourIntensityArray[vertexNumber].G;
+ renderVertexPtr->B = ColourIntensityArray[vertexNumber].B;
+ renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR;
+ renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG;
+ renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB;
+ return;
+ }
+ ColourIntensityArray[vertexNumber].Stamp=ObjectCounter;
+ {
+ VECTORCH *vertexPtr = ((VECTORCH *)Global_ShapePoints)+vertexNumber;
+ LIGHTBLOCK **larrayptr;
+ LIGHTBLOCK *lptr;
+ int i;
+
+ redI = 0;
+
+ larrayptr = LightSourcesForObject;
+
+ for(i = NumLightSourcesForObject; i!=0; i--)
+ {
+
+ VECTORCH vertexToLight;
+ int distanceToLight;
+
+ lptr = *larrayptr++;
+
+ if (lptr->LightFlags & LFlag_PreLitSource) continue;
+
+ vertexToLight.vx = lptr->LocalLP.vx - vertexPtr->vx;
+ vertexToLight.vy = lptr->LocalLP.vy - vertexPtr->vy;
+ vertexToLight.vz = lptr->LocalLP.vz - vertexPtr->vz;
+
+ distanceToLight = Approximate3dMagnitude(&vertexToLight);
+ if(distanceToLight < lptr->LightRange)
+ {
+ int idot = MUL_FIXED(lptr->LightRange-distanceToLight,lptr->BrightnessOverRange);
+
+ redI += idot;
+ }
+ }
+ }
+ blueI = ONE_FIXED-1;
+ if (renderVertexPtr->Z>5000)
+ {
+ int a = (renderVertexPtr->Z-5000);
+ if (a>4096) blueI = (blueI*4096)/a;
+ }
+
+ blueI >>=8;
+
+ redI >>=9;
+ if (redI>255) redI=255;
+
+ /* KJL 12:41:54 05/10/98 - red/green swapped, whilst testing colours */
+ renderVertexPtr->R = 255;
+ ColourIntensityArray[vertexNumber].R = 255;
+ renderVertexPtr->B = 255;
+ ColourIntensityArray[vertexNumber].B = 255;
+ renderVertexPtr->G = blueI;
+ ColourIntensityArray[vertexNumber].G = blueI;
+
+
+ renderVertexPtr->SpecularR = 255;//specularR;
+ ColourIntensityArray[vertexNumber].SpecularR = 255;//specularR;
+
+ renderVertexPtr->SpecularG = redI;
+ ColourIntensityArray[vertexNumber].SpecularG = redI;
+
+ renderVertexPtr->SpecularB = 255;//specularB;
+ ColourIntensityArray[vertexNumber].SpecularB = 255;//specularB;
+
+}
+static void VertexIntensity_ImageIntensifier(RENDERVERTEX *renderVertexPtr)
+{
+ int greenI;
+ int specular;
+
+ int vertexNumber = *VertexNumberPtr;
+
+ if(ColourIntensityArray[vertexNumber].Stamp==ObjectCounter)
+ {
+ renderVertexPtr->R = ColourIntensityArray[vertexNumber].R;
+ renderVertexPtr->G = ColourIntensityArray[vertexNumber].G;
+ renderVertexPtr->B = ColourIntensityArray[vertexNumber].B;
+ renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR;
+ renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG;
+ renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB;
+ return;
+ }
+ ColourIntensityArray[vertexNumber].Stamp=ObjectCounter;
+
+ {
+ VECTORCH *vertexNormalPtr = ((VECTORCH *)Global_ShapeVNormals) + vertexNumber;
+ VECTORCH *vertexPtr = ((VECTORCH *)Global_ShapePoints)+vertexNumber;
+
+ LIGHTBLOCK **larrayptr;
+ LIGHTBLOCK *lptr;
+ int i;
+
+ greenI = 0;
+ specular = 0;
+
+ larrayptr = LightSourcesForObject;
+
+ for(i = NumLightSourcesForObject; i!=0; i--)
+ {
+
+ VECTORCH vertexToLight;
+ int distanceToLight;
+
+ lptr = *larrayptr++;
+
+ vertexToLight.vx = lptr->LocalLP.vx - vertexPtr->vx;
+ vertexToLight.vy = lptr->LocalLP.vy - vertexPtr->vy;
+ vertexToLight.vz = lptr->LocalLP.vz - vertexPtr->vz;
+ {
+ int dx,dy,dz;
+
+ dx = vertexToLight.vx;
+ if (dx<0) dx = -dx;
+
+ dy = vertexToLight.vy;
+ if (dy<0) dy = -dy;
+
+ dz = vertexToLight.vz;
+ if (dz<0) dz = -dz;
+
+
+ if (dx>dy)
+ {
+ if (dx>dz)
+ {
+ distanceToLight = dx + ((dy+dz)>>2);
+ }
+ else
+ {
+ distanceToLight = dz + ((dy+dx)>>2);
+ }
+ }
+ else
+ {
+ if (dy>dz)
+ {
+ distanceToLight = dy + ((dx+dz)>>2);
+ }
+ else
+ {
+ distanceToLight = dz + ((dx+dy)>>2);
+ }
+ }
+ }
+
+ if(distanceToLight < lptr->LightRange)
+ {
+ int idot = MUL_FIXED(lptr->LightRange-distanceToLight,lptr->BrightnessOverRange);
+
+ if(distanceToLight>0)
+ {
+ int dotproduct = MUL_FIXED(vertexNormalPtr->vx,vertexToLight.vx)
+ + MUL_FIXED(vertexNormalPtr->vy,vertexToLight.vy)
+ + MUL_FIXED(vertexNormalPtr->vz,vertexToLight.vz);
+
+ if(dotproduct>0)
+ {
+ idot = (WideMulNarrowDiv(idot,dotproduct,distanceToLight)+idot/4);
+ }
+ else
+ {
+ idot /= 4;
+ }
+ }
+ if(idot<0)
+ {
+ LOCALASSERT(idot>=0);
+ }
+ specular += idot;
+ }
+ }
+ }
+
+ greenI = 255;
+ if (renderVertexPtr->Z>5000)
+ {
+ int a = (renderVertexPtr->Z-5000);
+ if (a>4096) greenI = (greenI*4096)/a;
+ }
+ renderVertexPtr->G = greenI;
+ ColourIntensityArray[vertexNumber].G = greenI;
+
+ renderVertexPtr->R = 0;
+ ColourIntensityArray[vertexNumber].R = 0;
+ renderVertexPtr->B = 0;
+ ColourIntensityArray[vertexNumber].B = 0;
+
+ specular>>=7;
+ if (specular>254) specular=254;
+ LOCALASSERT(specular>=0 && specular<=254);
+ renderVertexPtr->SpecularR = specular;
+ ColourIntensityArray[vertexNumber].SpecularR = specular;
+ renderVertexPtr->SpecularG = specular;
+ ColourIntensityArray[vertexNumber].SpecularG = specular;
+ renderVertexPtr->SpecularB = specular;
+ ColourIntensityArray[vertexNumber].SpecularB = specular;
+
+}
+
+static void VertexIntensity_Alien_Sense(RENDERVERTEX *renderVertexPtr)
+{
+ int intensity;
+ int vertexNumber = *VertexNumberPtr;
+
+ if(ColourIntensityArray[vertexNumber].Stamp==ObjectCounter)
+ {
+ renderVertexPtr->R = ColourIntensityArray[vertexNumber].R;
+ renderVertexPtr->G = ColourIntensityArray[vertexNumber].G;
+ renderVertexPtr->B = ColourIntensityArray[vertexNumber].B;
+ renderVertexPtr->SpecularR = 0;
+ renderVertexPtr->SpecularG = 0;
+ renderVertexPtr->SpecularB = 0;
+ return;
+ }
+ ColourIntensityArray[vertexNumber].Stamp=ObjectCounter;
+
+ intensity = 255;
+ if (renderVertexPtr->Z>5000)
+ {
+ int a = (renderVertexPtr->Z-5000);
+ if (a>1024) intensity = (intensity*1024)/a;
+ }
+
+ renderVertexPtr->R = intensity;
+ ColourIntensityArray[vertexNumber].R = intensity;
+
+ renderVertexPtr->G = intensity;
+ ColourIntensityArray[vertexNumber].G = intensity;
+
+ renderVertexPtr->B = intensity;
+ ColourIntensityArray[vertexNumber].B = intensity;
+
+ renderVertexPtr->SpecularR = 0;
+ renderVertexPtr->SpecularG = 0;
+ renderVertexPtr->SpecularB = 0;
+
+}
+
+
+
+static void VertexIntensity_Standard_Opt(RENDERVERTEX *renderVertexPtr)
+{
+ int redI,greenI,blueI;
+ int specularR,specularG,specularB;
+
+ int vertexNumber = *VertexNumberPtr;
+
+ if(ColourIntensityArray[vertexNumber].Stamp==ObjectCounter)
+ {
+ renderVertexPtr->R = ColourIntensityArray[vertexNumber].R;
+ renderVertexPtr->G = ColourIntensityArray[vertexNumber].G;
+ renderVertexPtr->B = ColourIntensityArray[vertexNumber].B;
+ renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR;
+ renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG;
+ renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB;
+ return;
+ }
+ ColourIntensityArray[vertexNumber].Stamp=ObjectCounter;
+ {
+ VECTORCH *vertexNormalPtr = ((VECTORCH *)Global_ShapeVNormals) + vertexNumber;
+ VECTORCH *vertexPtr = ((VECTORCH *)Global_ShapePoints)+vertexNumber;
+
+ LIGHTBLOCK **larrayptr;
+ LIGHTBLOCK *lptr;
+ int i;
+
+ if(Global_ShapeHeaderPtr->shapeflags & ShapeFlag_PreLit)
+ {
+ unsigned int packedI = Global_EID_IPtr[vertexNumber];
+ blueI = (packedI&255)*257;
+
+ packedI >>=8;
+ greenI = (packedI&255)*257;
+
+ packedI >>=8;
+ redI = (packedI&255)*257;
+ }
+ else
+ {
+ redI = 0;
+ greenI = 0;
+ blueI = 0;
+ }
+
+ specularR = 0;
+ specularG = 0;
+ specularB = 0;
+
+
+
+ larrayptr = LightSourcesForObject;
+
+ for(i = NumLightSourcesForObject; i!=0; i--)
+ {
+
+ VECTORCH vertexToLight;
+ int distanceToLight;
+
+ lptr = *larrayptr++;
+
+ vertexToLight.vx = lptr->LocalLP.vx - vertexPtr->vx;
+ vertexToLight.vy = lptr->LocalLP.vy - vertexPtr->vy;
+ vertexToLight.vz = lptr->LocalLP.vz - vertexPtr->vz;
+ {
+ int dx,dy,dz;
+
+ dx = vertexToLight.vx;
+ if (dx<0) dx = -dx;
+
+ dy = vertexToLight.vy;
+ if (dy<0) dy = -dy;
+
+ dz = vertexToLight.vz;
+ if (dz<0) dz = -dz;
+
+
+ if (dx>dy)
+ {
+ if (dx>dz)
+ {
+ distanceToLight = dx + ((dy+dz)>>2);
+ }
+ else
+ {
+ distanceToLight = dz + ((dy+dx)>>2);
+ }
+ }
+ else
+ {
+ if (dy>dz)
+ {
+ distanceToLight = dy + ((dx+dz)>>2);
+ }
+ else
+ {
+ distanceToLight = dz + ((dx+dy)>>2);
+ }
+ }
+ }
+
+ if(distanceToLight < lptr->LightRange)
+ {
+ int idot = MUL_FIXED(lptr->LightRange-distanceToLight,lptr->BrightnessOverRange);
+ int r,g,b;
+
+ if(distanceToLight>0)
+ {
+ int dotproduct = MUL_FIXED(vertexNormalPtr->vx,vertexToLight.vx)
+ + MUL_FIXED(vertexNormalPtr->vy,vertexToLight.vy)
+ + MUL_FIXED(vertexNormalPtr->vz,vertexToLight.vz);
+
+ if(dotproduct>0)
+ {
+ idot = (WideMulNarrowDiv(idot,dotproduct,distanceToLight)+idot/4)/2;
+ }
+ else
+ {
+ idot /= 8;
+ }
+ }
+
+ r = MUL_FIXED(idot,lptr->RedScale);
+ g = MUL_FIXED(idot,lptr->GreenScale);
+ b = MUL_FIXED(idot,lptr->BlueScale);
+
+ redI += r;
+ greenI += g;
+ blueI += b;
+
+ if( !(lptr->LightFlags & LFlag_PreLitSource)
+ && !(lptr->LightFlags & LFlag_NoSpecular) )
+ {
+ specularR += r;
+ specularG += g;
+ specularB += b;
+ }
+ }
+ }
+ }
+
+ if(Global_ODB_Ptr->SpecialFXFlags & SFXFLAG_ONFIRE)
+ {
+ specularR>>=2;
+ specularG>>=2;
+ specularB>>=2;
+
+ redI>>=1;
+ greenI>>=1;
+ blueI>>=1;
+ }
+
+ /* Intensity for Textures */
+ redI >>= 8;
+ if(redI > 255) redI = 255;
+ renderVertexPtr->R = redI;
+ ColourIntensityArray[vertexNumber].R = redI;
+
+ greenI >>= 8;
+ if(greenI > 255) greenI = 255;
+ renderVertexPtr->G = greenI;
+ ColourIntensityArray[vertexNumber].G = greenI;
+
+ blueI >>= 8;
+ if(blueI > 255) blueI = 255;
+ renderVertexPtr->B = blueI;
+ ColourIntensityArray[vertexNumber].B = blueI;
+
+ specularR >>= 10;
+ if(specularR > 255) specularR = 255;
+ renderVertexPtr->SpecularR = specularR;
+ ColourIntensityArray[vertexNumber].SpecularR = specularR;
+
+ specularG >>= 10;
+ if(specularG > 255) specularG = 255;
+ renderVertexPtr->SpecularG = specularG;
+ ColourIntensityArray[vertexNumber].SpecularG = specularG;
+
+ specularB >>= 10;
+ if(specularB > 255) specularB = 255;
+ renderVertexPtr->SpecularB = specularB;
+ ColourIntensityArray[vertexNumber].SpecularB = specularB;
+
+}
+static void VertexIntensity_FullBright(RENDERVERTEX *renderVertexPtr)
+{
+ int vertexNumber = *VertexNumberPtr;
+ renderVertexPtr->R = 255;
+ ColourIntensityArray[vertexNumber].R = 255;
+ renderVertexPtr->G = 255;
+ ColourIntensityArray[vertexNumber].G = 255;
+ renderVertexPtr->B = 255;
+ ColourIntensityArray[vertexNumber].B = 255;
+
+ renderVertexPtr->SpecularR = 0;
+ ColourIntensityArray[vertexNumber].SpecularR = 0;
+ renderVertexPtr->SpecularG = 0;
+ ColourIntensityArray[vertexNumber].SpecularG = 0;
+ renderVertexPtr->SpecularB = 0;
+ ColourIntensityArray[vertexNumber].SpecularB = 0;
+}
+
+static void VertexIntensity_DiscoInferno(RENDERVERTEX *renderVertexPtr)
+{
+ int redI,greenI,blueI;
+ int specularR,specularG,specularB;
+
+ int vertexNumber = *VertexNumberPtr;
+
+ if(ColourIntensityArray[vertexNumber].Stamp==ObjectCounter)
+ {
+ renderVertexPtr->R = ColourIntensityArray[vertexNumber].R;
+ renderVertexPtr->G = ColourIntensityArray[vertexNumber].G;
+ renderVertexPtr->B = ColourIntensityArray[vertexNumber].B;
+ renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR;
+ renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG;
+ renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB;
+ return;
+ }
+ ColourIntensityArray[vertexNumber].Stamp=ObjectCounter;
+ {
+ VECTORCH *vertexNormalPtr = ((VECTORCH *)Global_ShapeVNormals) + vertexNumber;
+ VECTORCH *vertexPtr = ((VECTORCH *)Global_ShapePoints)+vertexNumber;
+
+ LIGHTBLOCK **larrayptr;
+ LIGHTBLOCK *lptr;
+ int i;
+
+ if(Global_ShapeHeaderPtr->shapeflags & ShapeFlag_PreLit)
+ {
+ unsigned int packedI = Global_EID_IPtr[vertexNumber];
+ blueI = (packedI&255)*257;
+
+ packedI >>=8;
+ greenI = (packedI&255)*257;
+
+ packedI >>=8;
+ redI = (packedI&255)*257;
+ }
+ else
+ {
+ redI = 0;
+ greenI = 0;
+ blueI = 0;
+ }
+
+ specularR = 0;
+ specularG = 0;
+ specularB = 0;
+
+
+
+ larrayptr = LightSourcesForObject;
+
+ for(i = NumLightSourcesForObject; i!=0; i--)
+ {
+
+ VECTORCH vertexToLight;
+ int distanceToLight;
+
+ lptr = *larrayptr++;
+
+ vertexToLight.vx = lptr->LocalLP.vx - vertexPtr->vx;
+ vertexToLight.vy = lptr->LocalLP.vy - vertexPtr->vy;
+ vertexToLight.vz = lptr->LocalLP.vz - vertexPtr->vz;
+ {
+ int dx,dy,dz;
+
+ dx = vertexToLight.vx;
+ if (dx<0) dx = -dx;
+
+ dy = vertexToLight.vy;
+ if (dy<0) dy = -dy;
+
+ dz = vertexToLight.vz;
+ if (dz<0) dz = -dz;
+
+
+ if (dx>dy)
+ {
+ if (dx>dz)
+ {
+ distanceToLight = dx + ((dy+dz)>>2);
+ }
+ else
+ {
+ distanceToLight = dz + ((dy+dx)>>2);
+ }
+ }
+ else
+ {
+ if (dy>dz)
+ {
+ distanceToLight = dy + ((dx+dz)>>2);
+ }
+ else
+ {
+ distanceToLight = dz + ((dx+dy)>>2);
+ }
+ }
+ }
+
+ if(distanceToLight < lptr->LightRange)
+ {
+ int idot = MUL_FIXED(lptr->LightRange-distanceToLight,lptr->BrightnessOverRange);
+ int r,g,b;
+
+ if(distanceToLight>0)
+ {
+ int dotproduct = MUL_FIXED(vertexNormalPtr->vx,vertexToLight.vx)
+ + MUL_FIXED(vertexNormalPtr->vy,vertexToLight.vy)
+ + MUL_FIXED(vertexNormalPtr->vz,vertexToLight.vz);
+
+ if(dotproduct>0)
+ {
+ idot = (WideMulNarrowDiv(idot,dotproduct,distanceToLight)+idot/4)/2;
+ }
+ else
+ {
+ idot /= 8;
+ }
+ }
+
+ r = MUL_FIXED(idot,lptr->RedScale);
+ g = MUL_FIXED(idot,lptr->GreenScale);
+ b = MUL_FIXED(idot,lptr->BlueScale);
+
+ redI += r;
+ greenI += g;
+ blueI += b;
+
+ if( !(lptr->LightFlags & LFlag_PreLitSource)
+ && !(lptr->LightFlags & LFlag_NoSpecular) )
+ {
+ specularR += r;
+ specularG += g;
+ specularB += b;
+ }
+ }
+ }
+ }
+
+ if(Global_ODB_Ptr->SpecialFXFlags & SFXFLAG_ONFIRE)
+ {
+ specularR>>=2;
+ specularG>>=2;
+ specularB>>=2;
+
+ redI>>=1;
+ greenI>>=1;
+ blueI>>=1;
+ }
+
+ {
+ int i = (redI+greenI+blueI);
+ int si = (specularR+specularG+specularB);
+
+ VECTORCH vertex = *(((VECTORCH *)Global_ShapePoints)+vertexNumber);
+ int r,g,b;
+ vertex.vx += Global_ODB_Ptr->ObWorld.vx;
+ vertex.vy += Global_ODB_Ptr->ObWorld.vy;
+ vertex.vz += Global_ODB_Ptr->ObWorld.vz;
+
+ r = GetSin((vertex.vx+CloakingPhase)&4095);
+ r = MUL_FIXED(r,r);
+ redI = MUL_FIXED(r,i);
+ specularR = MUL_FIXED(r,si);
+
+ g = GetSin((vertex.vy+CloakingPhase/2)&4095);
+ g = MUL_FIXED(g,g);
+ greenI = MUL_FIXED(g,i);
+ specularG = MUL_FIXED(g,si);
+
+ b = GetSin((vertex.vz+CloakingPhase*3)&4095);
+ b = MUL_FIXED(b,b);
+ blueI = MUL_FIXED(b,i);
+ specularB = MUL_FIXED(b,si);
+
+ }
+
+
+
+ /* Intensity for Textures */
+ redI >>= 8;
+ if(redI > 255) redI = 255;
+ renderVertexPtr->R = redI;
+ ColourIntensityArray[vertexNumber].R = redI;
+
+ greenI >>= 8;
+ if(greenI > 255) greenI = 255;
+ renderVertexPtr->G = greenI;
+ ColourIntensityArray[vertexNumber].G = greenI;
+
+ blueI >>= 8;
+ if(blueI > 255) blueI = 255;
+ renderVertexPtr->B = blueI;
+ ColourIntensityArray[vertexNumber].B = blueI;
+
+ specularR >>= 10;
+ if(specularR > 255) specularR = 255;
+ renderVertexPtr->SpecularR = specularR;
+ ColourIntensityArray[vertexNumber].SpecularR = specularR;
+
+ specularG >>= 10;
+ if(specularG > 255) specularG = 255;
+ renderVertexPtr->SpecularG = specularG;
+ ColourIntensityArray[vertexNumber].SpecularG = specularG;
+
+ specularB >>= 10;
+ if(specularB > 255) specularB = 255;
+ renderVertexPtr->SpecularB = specularB;
+ ColourIntensityArray[vertexNumber].SpecularB = specularB;
+
+
+}
+static void VertexIntensity_Underwater(RENDERVERTEX *renderVertexPtr)
+{
+ int redI,greenI,blueI;
+ int specularR,specularG,specularB;
+
+ int vertexNumber = *VertexNumberPtr;
+
+ if(ColourIntensityArray[vertexNumber].Stamp==ObjectCounter)
+ {
+ renderVertexPtr->R = ColourIntensityArray[vertexNumber].R;
+ renderVertexPtr->G = ColourIntensityArray[vertexNumber].G;
+ renderVertexPtr->B = ColourIntensityArray[vertexNumber].B;
+ renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR;
+ renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG;
+ renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB;
+ return;
+ }
+ ColourIntensityArray[vertexNumber].Stamp=ObjectCounter;
+ {
+ VECTORCH *vertexNormalPtr = ((VECTORCH *)Global_ShapeVNormals) + vertexNumber;
+ VECTORCH *vertexPtr = ((VECTORCH *)Global_ShapePoints)+vertexNumber;
+
+ LIGHTBLOCK **larrayptr;
+ LIGHTBLOCK *lptr;
+ int i;
+
+ if(Global_ShapeHeaderPtr->shapeflags & ShapeFlag_PreLit)
+ {
+ unsigned int packedI = Global_EID_IPtr[vertexNumber];
+ blueI = (packedI&255)*257;
+
+ packedI >>=8;
+ greenI = (packedI&255)*257;
+
+ packedI >>=8;
+ redI = (packedI&255)*257;
+ }
+ else
+ {
+ redI = 0;
+ greenI = 0;
+ blueI = 0;
+ }
+
+ specularR = 0;
+ specularG = 0;
+ specularB = 0;
+
+
+
+ larrayptr = LightSourcesForObject;
+
+ for(i = NumLightSourcesForObject; i!=0; i--)
+ {
+
+ VECTORCH vertexToLight;
+ int distanceToLight;
+
+ lptr = *larrayptr++;
+
+ vertexToLight.vx = lptr->LocalLP.vx - vertexPtr->vx;
+ vertexToLight.vy = lptr->LocalLP.vy - vertexPtr->vy;
+ vertexToLight.vz = lptr->LocalLP.vz - vertexPtr->vz;
+ {
+ int dx,dy,dz;
+
+ dx = vertexToLight.vx;
+ if (dx<0) dx = -dx;
+
+ dy = vertexToLight.vy;
+ if (dy<0) dy = -dy;
+
+ dz = vertexToLight.vz;
+ if (dz<0) dz = -dz;
+
+
+ if (dx>dy)
+ {
+ if (dx>dz)
+ {
+ distanceToLight = dx + ((dy+dz)>>2);
+ }
+ else
+ {
+ distanceToLight = dz + ((dy+dx)>>2);
+ }
+ }
+ else
+ {
+ if (dy>dz)
+ {
+ distanceToLight = dy + ((dx+dz)>>2);
+ }
+ else
+ {
+ distanceToLight = dz + ((dx+dy)>>2);
+ }
+ }
+ }
+
+ if(distanceToLight < lptr->LightRange)
+ {
+ int idot = MUL_FIXED(lptr->LightRange-distanceToLight,lptr->BrightnessOverRange);
+ int r,g,b;
+
+ if(distanceToLight>0)
+ {
+ int dotproduct = MUL_FIXED(vertexNormalPtr->vx,vertexToLight.vx)
+ + MUL_FIXED(vertexNormalPtr->vy,vertexToLight.vy)
+ + MUL_FIXED(vertexNormalPtr->vz,vertexToLight.vz);
+
+ if(dotproduct>0)
+ {
+ idot = (WideMulNarrowDiv(idot,dotproduct,distanceToLight)+idot/4)/2;
+ }
+ else
+ {
+ idot /= 8;
+ }
+ }
+
+ r = MUL_FIXED(idot,lptr->RedScale);
+ g = MUL_FIXED(idot,lptr->GreenScale);
+ b = MUL_FIXED(idot,lptr->BlueScale);
+
+ redI += r;
+ greenI += g;
+ blueI += b;
+
+ if( !(lptr->LightFlags & LFlag_PreLitSource)
+ && !(lptr->LightFlags & LFlag_NoSpecular) )
+ {
+ specularR += r;
+ specularG += g;
+ specularB += b;
+ }
+ }
+ }
+ }
+
+ if(Global_ODB_Ptr->SpecialFXFlags & SFXFLAG_ONFIRE)
+ {
+ specularR>>=2;
+ specularG>>=2;
+ specularB>>=2;
+
+ redI>>=1;
+ greenI>>=1;
+ blueI>>=1;
+ }
+
+ {
+ if (specularB<renderVertexPtr->Z*4)
+ specularB = renderVertexPtr->Z*4;
+
+ }
+
+
+
+ /* Intensity for Textures */
+ redI >>= 8;
+ if(redI > 255) redI = 255;
+ renderVertexPtr->R = redI;
+ ColourIntensityArray[vertexNumber].R = redI;
+
+ greenI >>= 8;
+ if(greenI > 255) greenI = 255;
+ renderVertexPtr->G = greenI;
+ ColourIntensityArray[vertexNumber].G = greenI;
+
+ blueI >>= 8;
+ if(blueI > 255) blueI = 255;
+ renderVertexPtr->B = blueI;
+ ColourIntensityArray[vertexNumber].B = blueI;
+
+ specularR >>= 10;
+ if(specularR > 255) specularR = 255;
+ renderVertexPtr->SpecularR = specularR;
+ ColourIntensityArray[vertexNumber].SpecularR = specularR;
+
+ specularG >>= 10;
+ if(specularG > 255) specularG = 255;
+ renderVertexPtr->SpecularG = specularG;
+ ColourIntensityArray[vertexNumber].SpecularG = specularG;
+
+ specularB >>= 10;
+ if(specularB > 255) specularB = 255;
+ renderVertexPtr->SpecularB = specularB;
+ ColourIntensityArray[vertexNumber].SpecularB = specularB;
+
+
+ }
+
+/*KJL***********************************************************************
+* The following functions have been transplanted from the old shape.c, and *
+* will probably be found a new home at some point in the future. *
+***********************************************************************KJL*/
+
+/*
+
+ Texture Animation
+
+*/
+
+int* GetTxAnimArrayZ(int shape, int item)
+
+{
+
+ SHAPEHEADER *sptr;
+ int **item_array_ptr;
+ int **shape_textures;
+ int *item_ptr;
+ POLYHEADER *pheader;
+ int texture_defn_index;
+
+
+ sptr = GetShapeData(shape);
+
+ if(sptr && sptr->sh_textures && sptr->items) {
+
+ item_array_ptr = sptr->items;
+ shape_textures = sptr->sh_textures;
+
+ item_ptr = item_array_ptr[item];
+ pheader = (POLYHEADER *) item_ptr;
+
+ texture_defn_index = (pheader->PolyColour >> TxDefn);
+
+ if(pheader->PolyFlags & iflag_txanim) {
+
+ return (int*) shape_textures[texture_defn_index];
+
+ }
+
+ else return 0;
+
+ }
+
+ else return 0;
+
+}
+
+
+TXANIMHEADER* GetTxAnimDataZ(int shape, int item, int sequence)
+
+{
+
+ SHAPEHEADER *sptr;
+ TXANIMHEADER **txah_ptr;
+ TXANIMHEADER *txah;
+ int **item_array_ptr;
+ int **shape_textures;
+ int *item_ptr;
+ POLYHEADER *pheader;
+ int texture_defn_index;
+
+
+ sptr = GetShapeData(shape);
+
+ if(sptr && sptr->sh_textures && sptr->items) {
+
+ item_array_ptr = sptr->items;
+ shape_textures = sptr->sh_textures;
+
+ item_ptr = item_array_ptr[item];
+ pheader = (POLYHEADER *) item_ptr;
+
+ texture_defn_index = (pheader->PolyColour >> TxDefn);
+
+ if(pheader->PolyFlags & iflag_txanim) {
+
+ txah_ptr = (TXANIMHEADER **) shape_textures[texture_defn_index];
+ txah_ptr++; /* Skip sequence shadow */
+
+ txah = txah_ptr[sequence];
+
+ return txah;
+
+ }
+
+ else return 0;
+
+ }
+
+ else return 0;
+
+}
+
+
+
+
+/*
+
+ For some animated textures each sequence will represent a different view
+ of a sprite. When each sequence has the same number of frames there is no
+ problem transferring the value from one "txa_currentframe" to the other.
+ However if the new sequence has a different number of frames a scaling must
+ be done.
+
+*/
+
+void ChangeSequence(TXANIMHEADER *txah_old, TXANIMHEADER *txah_new)
+
+{
+
+ if(txah_new->txa_numframes == txah_old->txa_numframes) {
+
+ txah_new->txa_currentframe = txah_old->txa_currentframe;
+
+ }
+
+ else {
+
+ txah_new->txa_currentframe =
+
+ WideMulNarrowDiv(txah_old->txa_currentframe,
+ txah_new->txa_maxframe,
+ txah_old->txa_maxframe);
+
+ }
+}
+
+
+/*
+
+ This function copies the TXANIMHEADER from the shape data item sequence
+ selected by the TXACTRLBLK to the TXANIMHEADER in the TXACTRLBLK
+
+*/
+
+TXANIMHEADER* GetTxAnimHeaderFromShape(TXACTRLBLK *taptr, int shape)
+
+{
+
+ TXANIMHEADER *txah = 0;
+
+
+ {
+
+ txah = GetTxAnimDataZ(shape, taptr->tac_item, taptr->tac_sequence);
+
+ }
+
+ if(txah) {
+
+ taptr->tac_txah.txa_flags = txah->txa_flags;
+ taptr->tac_txah.txa_state = txah->txa_state;
+ taptr->tac_txah.txa_numframes = txah->txa_numframes;
+ taptr->tac_txah.txa_framedata = txah->txa_framedata;
+ taptr->tac_txah.txa_currentframe = txah->txa_currentframe;
+ taptr->tac_txah.txa_maxframe = txah->txa_maxframe;
+ taptr->tac_txah.txa_speed = txah->txa_speed;
+
+ }
+
+ return txah;
+
+}
+
+
+/*
+
+ Texture Animation Control Blocks are used to update animation. At the start
+ of "AddShape()" the relevant control block values are copied across to the
+ item TXANIMHEADER.
+
+*/
+
+void UpdateTxAnim(TXANIMHEADER *txah)
+
+{
+
+ int UpdateRate;
+
+
+ if(txah->txa_flags & txa_flag_play) {
+
+ /* How fast do we go? */
+
+ if(txah->txa_flags & txa_flag_quantiseframetime) {
+
+ /* This option is still being designed and tested */
+
+ UpdateRate = txah->txa_speed & (~4096); /* 1/16th */
+ if(UpdateRate < 4096) UpdateRate = 4096;
+ UpdateRate = MUL_FIXED(NormalFrameTime, txah->txa_speed);
+
+ }
+
+ else UpdateRate = MUL_FIXED(NormalFrameTime, txah->txa_speed);
+
+
+ /* Update the current frame */
+
+ if(txah->txa_flags & txa_flag_reverse) {
+
+ txah->txa_currentframe -= UpdateRate;
+
+ if(txah->txa_currentframe < 0) {
+
+ if(txah->txa_flags & txa_flag_noloop) {
+
+ txah->txa_currentframe = 0;
+
+ }
+
+ else {
+
+ txah->txa_currentframe += txah->txa_maxframe;
+
+ }
+
+ }
+
+ }
+
+ else {
+
+ txah->txa_currentframe += UpdateRate;
+
+ if(txah->txa_currentframe >= txah->txa_maxframe) {
+
+ if(txah->txa_flags & txa_flag_noloop) {
+
+ txah->txa_currentframe = txah->txa_maxframe - 1;
+
+ }
+
+ else {
+
+ txah->txa_currentframe -= txah->txa_maxframe;
+
+ }
+
+ }
+
+ }
+
+ }
+
+}
+
+
+/*
+
+ Display block TXACTRLBLKS pass their data on to shape TXANIMHEADERs
+
+*/
+
+void ControlTextureAnimation(DISPLAYBLOCK *dptr)
+{
+
+ TXACTRLBLK *taptr;
+ TXANIMHEADER *txah;
+ int *iptr;
+
+
+ taptr = dptr->ObTxAnimCtrlBlks;
+
+ while(taptr)
+ {
+ /* Update animation for the display block TXACTRLBLK */
+ LOCALASSERT(&(taptr->tac_txah));
+ UpdateTxAnim(&taptr->tac_txah);
+
+ /* Get the TXANIMHEADER from the shape data */
+
+ txah = taptr->tac_txah_s;
+
+ /* Copy across the current frame */
+ LOCALASSERT(txah);
+ txah->txa_currentframe = taptr->tac_txah.txa_currentframe;
+
+ iptr = taptr->tac_txarray;
+ LOCALASSERT(iptr);
+ *iptr = taptr->tac_sequence;
+
+ taptr = taptr->tac_next;
+ }
+}
+
+void CreateTxAnimUVArray(int *txa_data, int *uv_array, int *shapeitemptr)
+{
+ TXANIMHEADER **txah_ptr;
+ TXANIMHEADER *txah;
+ TXANIMFRAME *txaf;
+ TXANIMFRAME *txaf0;
+ TXANIMFRAME *txaf1;
+ int *txaf0_uv;
+ int *txaf1_uv;
+ int CurrentFrame, NextFrame, Alpha, OneMinusAlpha;
+ int i;
+ int *iptr;
+ int Orient, Scale;
+ int OrientX, OrientY;
+ int ScaleX, ScaleY;
+ int sin, cos;
+ int x, y;
+ int x1, y1;
+ int o1, o2, od;
+ POLYHEADER *pheader = (POLYHEADER*) shapeitemptr;
+ int sequence;
+ int *txf_imageptr;
+
+
+ /* The sequence # will have been copied across by the control block */
+
+ sequence = *txa_data++;
+
+ #if 0
+ textprint("sequence = %d\n", sequence);
+ #endif
+
+ txah_ptr = (TXANIMHEADER **) txa_data;
+ txah = txah_ptr[sequence];
+ txaf = txah->txa_framedata;
+
+
+ /* Because the current frame can be set from outside, clamp it first */
+
+ if(txah->txa_currentframe < 0) {
+
+ txah->txa_currentframe = 0;
+
+ }
+
+ if(txah->txa_currentframe >= txah->txa_maxframe) {
+
+ txah->txa_currentframe = txah->txa_maxframe - 1;
+
+ }
+
+
+ /* Frame # */
+
+ CurrentFrame = txah->txa_currentframe >> 16;
+ Alpha = txah->txa_currentframe - (CurrentFrame << 16);
+ OneMinusAlpha = ONE_FIXED - Alpha;
+
+
+ /* Start and End Frame */
+
+ NextFrame = CurrentFrame + 1;
+ if(NextFrame >= txah->txa_numframes) NextFrame = 0;
+
+ txaf0 = &txaf[CurrentFrame];
+ txaf1 = &txaf[NextFrame];
+
+
+ /*
+
+ Write the image index back to the item by overwriting the shape data.
+ This is not elegant but it is one of the kind of things you expect to
+ have happen when a major new feature is retro-fitted to a system.
+
+ */
+
+ pheader->PolyColour &= ClrTxIndex;
+
+
+ /* Multi-View Sprites need to select an image from the array */
+
+ if(Global_ShapeHeaderPtr->shapeflags & ShapeFlag_MultiViewSprite) {
+
+ int **txf_uvarrayptr0 = (int **) txaf0->txf_uvdata;
+ int **txf_uvarrayptr1 = (int **) txaf1->txf_uvdata;
+ int index;
+
+
+ index = GetMVSIndex(txah, &LToVMat_Euler);
+
+ /*textprint("index = %d\n", index);*/
+
+
+ txf_imageptr = (int *) txaf0->txf_image;
+ pheader->PolyColour |= txf_imageptr[index];
+
+
+ /* Get the uv data */
+
+ txaf0_uv = txf_uvarrayptr0[index];
+ txaf1_uv = txf_uvarrayptr1[index];
+
+ }
+
+
+ /* Single-View Sprites have just one image per frame */
+
+ else {
+
+ pheader->PolyColour |= txaf0->txf_image;
+
+ txaf0_uv = txaf0->txf_uvdata;
+ txaf1_uv = txaf1->txf_uvdata;
+
+ }
+
+
+ /* Calculate UVs */
+
+ iptr = uv_array;
+
+ if(txah->txa_flags & txa_flag_interpolate_uvs) {
+
+ for(i = txaf0->txf_numuvs; i!=0; i--) {
+
+ iptr[0] = MUL_FIXED(txaf0_uv[0], OneMinusAlpha)
+ + MUL_FIXED(txaf1_uv[0], Alpha);
+
+ iptr[1] = MUL_FIXED(txaf0_uv[1], OneMinusAlpha)
+ + MUL_FIXED(txaf1_uv[1], Alpha);
+
+ /*textprint("%d, %d\n", iptr[0] >> 16, iptr[1] >> 16);*/
+
+ txaf0_uv += 2;
+ txaf1_uv += 2;
+ iptr += 2;
+
+ }
+
+ }
+
+ else {
+
+ for(i = txaf0->txf_numuvs; i!=0; i--) {
+
+ iptr[0] = txaf0_uv[0];
+ iptr[1] = txaf0_uv[1];
+
+ /*textprint("%d, %d\n", iptr[0] >> 16, iptr[1] >> 16);*/
+
+ txaf0_uv += 2;
+ iptr += 2;
+
+ }
+
+ }
+
+
+ /* Interpolate Orient and Scale */
+
+ o1 = txaf0->txf_orient;
+ o2 = txaf1->txf_orient;
+
+ if(o1 == o2) {
+
+ Orient = o1;
+
+ }
+
+ else {
+
+ od = o1 - o2;
+ if(od < 0) od = -od;
+
+ if(od >= deg180) {
+
+ o1 <<= (32 - 12);
+ o1 >>= (32 - 12);
+ o2 <<= (32 - 12);
+ o2 >>= (32 - 12);
+
+ }
+
+ Orient = MUL_FIXED(o1, OneMinusAlpha) + MUL_FIXED(o2, Alpha);
+ Orient &= wrap360;
+
+ }
+
+
+ if(txaf0->txf_scale == txaf1->txf_scale) {
+
+ Scale = txaf0->txf_scale;
+
+ }
+
+ else {
+
+ Scale = WideMul2NarrowDiv(txaf0->txf_scale, OneMinusAlpha,
+ txaf1->txf_scale, Alpha, ONE_FIXED);
+
+ }
+
+
+ /* Interpolate Orient and Scale Origins */
+
+ if(txaf0->txf_orientx == txaf1->txf_orientx) {
+
+ OrientX = txaf0->txf_orientx;
+
+ }
+
+ else {
+
+ OrientX = MUL_FIXED(txaf0->txf_orientx, OneMinusAlpha)
+ + MUL_FIXED(txaf1->txf_orientx, Alpha);
+
+ }
+
+
+ if(txaf0->txf_orienty == txaf1->txf_orienty) {
+
+ OrientY = txaf0->txf_orienty;
+
+ }
+
+ else {
+
+ OrientY = MUL_FIXED(txaf0->txf_orienty, OneMinusAlpha)
+ + MUL_FIXED(txaf1->txf_orienty, Alpha);
+
+ }
+
+
+ if(txaf0->txf_scalex == txaf1->txf_scalex) {
+
+ ScaleX = txaf0->txf_scalex;
+
+ }
+
+ else {
+
+ ScaleX = MUL_FIXED(txaf0->txf_scalex, OneMinusAlpha)
+ + MUL_FIXED(txaf1->txf_scalex, Alpha);
+
+ }
+
+
+ if(txaf0->txf_scaley == txaf1->txf_scaley) {
+
+ ScaleY = txaf0->txf_scaley;
+
+ }
+
+ else {
+
+ ScaleY = MUL_FIXED(txaf0->txf_scaley, OneMinusAlpha)
+ + MUL_FIXED(txaf1->txf_scaley, Alpha);
+
+ }
+
+
+
+ #if 0
+ textprint("Alpha = %d\n", Alpha);
+ textprint("OneMinusAlpha = %d\n", OneMinusAlpha);
+ textprint("Orient = %d\n", Orient);
+ textprint("txaf0->txf_scale = %d\n", txaf0->txf_scale);
+ textprint("txaf1->txf_scale = %d\n", txaf1->txf_scale);
+ textprint("Scale = %d\n", Scale);
+ #endif
+
+ /*WaitForReturn();*/
+
+
+
+#if 1
+
+
+ /* Rotate UV Array */
+
+ if(Orient) {
+
+ sin = GetSin(Orient);
+ cos = GetCos(Orient);
+
+ iptr = uv_array;
+
+ for(i = txaf0->txf_numuvs; i!=0; i--) {
+
+ x = iptr[0] - OrientX;
+ y = iptr[1] - OrientY;
+
+ x1 = MUL_FIXED(x, cos) - MUL_FIXED(y, sin);
+ y1 = MUL_FIXED(x, sin) + MUL_FIXED(y, cos);
+
+ iptr[0] = x1 + OrientX;
+ iptr[1] = y1 + OrientY;
+
+ iptr += 2;
+
+ }
+
+ }
+
+
+ /* Scale UV Array */
+
+ if(Scale != ONE_FIXED) {
+
+ iptr = uv_array;
+
+ for(i = txaf0->txf_numuvs; i!=0; i--) {
+
+ x = iptr[0] - ScaleX;
+ y = iptr[1] - ScaleY;
+
+ x = MUL_FIXED(x, Scale);
+ y = MUL_FIXED(y, Scale);
+
+ iptr[0] = x + ScaleX;
+ iptr[1] = y + ScaleY;
+
+ iptr += 2;
+
+ }
+
+ }
+
+
+#endif
+
+
+
+
+
+
+ #if 0
+ textprint("Current Frame = %d\n", txah->txa_currentframe);
+ textprint("Current Frame = %d\n", CurrentFrame);
+ textprint("Next Frame = %d\n", NextFrame);
+ textprint("Alpha = %d\n", Alpha);
+ #endif
+
+
+ /*textprint("Leaving CreateTxAnimUVArray\n");*/
+ /*WaitForReturn();*/
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*
+
+ Shape Points for Unrotated Sprites
+
+*/
+
+void ShapeSpritePointsInstr(SHAPEINSTR *shapeinstrptr)
+
+{
+
+ int **shapeitemarrayptr = shapeinstrptr->sh_instr_data;
+ int *shapeitemptr = *shapeitemarrayptr;
+ VECTORCH *rotptsptr = RotatedPts;
+ int numitems;
+
+
+ for(numitems = shapeinstrptr->sh_numitems; numitems!=0; numitems--) {
+
+ rotptsptr->vx = shapeitemptr[ix];
+ rotptsptr->vx += Global_ODB_Ptr->ObView.vx;
+
+ rotptsptr->vy = shapeitemptr[iy];
+ rotptsptr->vy += Global_ODB_Ptr->ObView.vy;
+
+ rotptsptr->vz = shapeitemptr[iz];
+ rotptsptr->vz += Global_ODB_Ptr->ObView.vz;
+
+ shapeitemptr += vsize;
+ rotptsptr++;
+
+ }
+
+}
+
+
+/*
+
+ Shape Points for Rotated Sprites
+
+*/
+
+
+//I've put my alterations to the sprite rotation
+//in the #else part.Richard
+#define UseKevinsModifiedSSRPI No
+
+
+#if UseKevinsModifiedSSRPI
+
+
+
+#define ssrpi_kill_py Yes
+
+void ShapeSpriteRPointsInstr(SHAPEINSTR *shapeinstrptr)
+
+{
+
+ int **shapeitemarrayptr = shapeinstrptr->sh_instr_data;
+ int *shapeitemptr = *shapeitemarrayptr;
+ VECTORCH *rotptsptr = RotatedPts;
+ int numitems;
+ int x,y,z;
+ MATRIXCH m;
+ #if ssrpi_kill_py
+ EULER e;
+ char flipX=0;
+ #endif
+ /*
+
+ Sprite Resizing
+
+ If this shape is a sprite and is using sprite resizing, there will be a transformed
+ copy of the polygon points array (XY only) to copy back to the shape.
+
+ WARNING!
+
+ This function and data structure ASSUME that the sprite shape is using an item array,
+ that there is just the one item, and that the world and UV space coordinates are in the
+ form of "TL, BL, BR, TR". It also assumes that the sprite polygon is in the XY plane.
+
+ If ANY of these is not true for your sprite, DON'T attempt to use resizing!
+
+ */
+
+ if(Global_ShapeHeaderPtr->shapeflags & ShapeFlag_Sprite &&
+ Global_ShapeHeaderPtr->shapeflags & ShapeFlag_SpriteResizing) {
+
+ int *ShapePoints;
+ int **item_array_ptr;
+ int *item_ptr;
+ POLYHEADER *pheader;
+ int *mypolystart;
+ int texture_defn_index;
+ int *texture_defn_ptr;
+ TXANIMHEADER **txah_ptr;
+ TXANIMHEADER *txah;
+ TXANIMFRAME *txaf;
+ TXANIMFRAME *txaf0;
+ int CurrentFrame, sequence;
+ int *iptr;
+
+ ShapePoints = *(Global_ShapeHeaderPtr->points);
+
+ /* Item */
+
+ item_array_ptr = Global_ShapeHeaderPtr->items; /* Assume item array */
+ item_ptr = item_array_ptr[0]; /* Assume only one polygon */
+ pheader = (POLYHEADER *) item_ptr;
+
+ /* Texture Animation */
+
+ texture_defn_index = (pheader->PolyColour >> TxDefn);
+ texture_defn_ptr = Global_ShapeTextures[texture_defn_index];
+
+ sequence = *texture_defn_ptr++;
+
+ txah_ptr = (TXANIMHEADER **) texture_defn_ptr;
+ txah = txah_ptr[sequence];
+ txaf = txah->txa_framedata;
+
+ /* Because the current frame can be set from outside, clamp it first */
+
+ if(txah->txa_currentframe < 0)
+ txah->txa_currentframe = 0;
+ if(txah->txa_currentframe >= txah->txa_maxframe)
+ txah->txa_currentframe = txah->txa_maxframe - 1;
+
+ CurrentFrame = txah->txa_currentframe >> 16;
+
+ txaf0 = &txaf[CurrentFrame];
+
+ /* UV array */
+
+ if(Global_ShapeHeaderPtr->shapeflags & ShapeFlag_Sprite) {
+
+ int **uvarrayptr = (int **) txaf0->txf_uvdata;
+ iptr = uvarrayptr[GetMVSIndex(txah, &LToVMat_Euler)];
+
+ }
+
+ else {
+
+ iptr = txaf0->txf_uvdata;
+
+ }
+
+ iptr += (txaf0->txf_numuvs * 2);
+
+ /* Redefine the Shape Points */
+
+ mypolystart = &pheader->Poly1stPt;
+
+ while(*mypolystart != Term) {
+
+ /*textprint("copying point %d\n", *mypolystart / vsize);*/
+
+ *(ShapePoints + *mypolystart + ix) = iptr[0];
+ *(ShapePoints + *mypolystart + iy) = iptr[1];
+
+ mypolystart++;
+ iptr += 2;
+
+ }
+
+ }
+
+
+ #if ssrpi_kill_py
+
+
+ /* Make a copy of the object matrix */
+
+ CopyMatrix(&Global_ODB_Ptr->ObMat, &m);
+
+
+
+ /* Combine it with the view matrix */
+
+ MatrixMultiply(&Global_VDB_Ptr->VDB_SpriteMat, &m, &m);
+
+ /* Extract the Euler Angles */
+ MatrixToEuler(&m, &e);
+
+ #if 0
+ textprint("X: %d\n", e.EulerX);
+ textprint("Y: %d\n", e.EulerY);
+ textprint("Z: %d\n", e.EulerZ);
+ #endif
+
+
+ /* Knock out the pitch and yaw */
+
+ /* KJL 17:23:22 01/09/97 - If the sprite is turned away from you, flip along the
+ x-axis so that you get the mirror image of the sprite */
+ if (e.EulerY<1024 || e.EulerY>3072) flipX = 1;
+ e.EulerY=0;
+ e.EulerX=0;
+
+
+ /* Turn it back into a matrix */
+ CreateEulerMatrix(&e, &m);
+ TransposeMatrixCH(&m);
+
+ #else /* ssrpi_kill_py */
+
+
+ MatrixMultiply(&Global_VDB_Ptr->VDB_SpriteMat, &Global_ODB_Ptr->ObMat, &m);
+
+
+ #endif /* ssrpi_kill_py */
+
+
+ for(numitems = shapeinstrptr->sh_numitems; numitems!=0; numitems--) {
+
+ x = shapeitemptr[ix];
+ y = shapeitemptr[iy];
+ z = shapeitemptr[iz];
+
+ rotptsptr->vx = MUL_FIXED(m.mat11, x);
+ rotptsptr->vx += MUL_FIXED(m.mat21, y);
+ rotptsptr->vx += MUL_FIXED(m.mat31, z);
+ #if ssrpi_kill_py
+ if (flipX) rotptsptr->vx = - rotptsptr->vx;
+ #endif
+ rotptsptr->vx += Global_ODB_Ptr->ObView.vx;
+
+ rotptsptr->vy = MUL_FIXED(m.mat12, x);
+ rotptsptr->vy += MUL_FIXED(m.mat22, y);
+ rotptsptr->vy += MUL_FIXED(m.mat32, z);
+ rotptsptr->vy += Global_ODB_Ptr->ObView.vy;
+
+ rotptsptr->vz = MUL_FIXED(m.mat13, x);
+ rotptsptr->vz += MUL_FIXED(m.mat23, y);
+ rotptsptr->vz += MUL_FIXED(m.mat33, z);
+ rotptsptr->vz += Global_ODB_Ptr->ObView.vz;
+
+ shapeitemptr += vsize;
+ rotptsptr++;
+
+ }
+
+}
+
+
+
+
+#else /* UseKevinsModifiedSSRPI */
+
+
+
+
+#define ssrpi_kill_py No
+
+void ShapeSpriteRPointsInstr(SHAPEINSTR *shapeinstrptr)
+
+{
+
+ int **shapeitemarrayptr = shapeinstrptr->sh_instr_data;
+ int *shapeitemptr = *shapeitemarrayptr;
+ VECTORCH *rotptsptr = RotatedPts;
+ int numitems;
+ int x,y;
+ VECTORCH vectx,vecty;
+ #if ssrpi_kill_py
+ MATRIXCH m2;
+ EULER e;
+ #endif
+
+
+ /*
+
+ Sprite Resizing
+
+ If this shape is a sprite and is using sprite resizing, there will be a transformed
+ copy of the polygon points array (XY only) to copy back to the shape.
+
+ WARNING!
+
+ This function and data structure ASSUME that the sprite shape is using an item array,
+ that there is just the one item, and that the world and UV space coordinates are in the
+ form of "TL, BL, BR, TR". It also assumes that the sprite polygon is in the XY plane.
+
+ If ANY of these is not true for your sprite, DON'T attempt to use resizing!
+
+ */
+
+ if(Global_ShapeHeaderPtr->shapeflags & ShapeFlag_Sprite &&
+ Global_ShapeHeaderPtr->shapeflags & ShapeFlag_SpriteResizing) {
+
+ int *ShapePoints;
+ int **item_array_ptr;
+ int *item_ptr;
+ POLYHEADER *pheader;
+ int *mypolystart;
+ int texture_defn_index;
+ int *texture_defn_ptr;
+ TXANIMHEADER **txah_ptr;
+ TXANIMHEADER *txah;
+ TXANIMFRAME *txaf;
+ TXANIMFRAME *txaf0;
+ int CurrentFrame, sequence;
+ int *iptr;
+
+ ShapePoints = *(Global_ShapeHeaderPtr->points);
+
+ /* Item */
+
+ item_array_ptr = Global_ShapeHeaderPtr->items; /* Assume item array */
+ item_ptr = item_array_ptr[0]; /* Assume only one polygon */
+ pheader = (POLYHEADER *) item_ptr;
+
+ /* Texture Animation */
+
+ texture_defn_index = (pheader->PolyColour >> TxDefn);
+ texture_defn_ptr = Global_ShapeTextures[texture_defn_index];
+
+ sequence = *texture_defn_ptr++;
+
+ txah_ptr = (TXANIMHEADER **) texture_defn_ptr;
+ txah = txah_ptr[sequence];
+ txaf = txah->txa_framedata;
+
+ /* Because the current frame can be set from outside, clamp it first */
+
+ if(txah->txa_currentframe < 0)
+ txah->txa_currentframe = 0;
+ if(txah->txa_currentframe >= txah->txa_maxframe)
+ txah->txa_currentframe = txah->txa_maxframe - 1;
+
+ CurrentFrame = txah->txa_currentframe >> 16;
+
+ txaf0 = &txaf[CurrentFrame];
+
+
+ /* UV array */
+
+ if(Global_ShapeHeaderPtr->shapeflags & ShapeFlag_Sprite) {
+
+ int **uvarrayptr = (int **) txaf0->txf_uvdata;
+ iptr = uvarrayptr[GetMVSIndex(txah, &LToVMat_Euler)];
+
+ }
+
+ else {
+
+ iptr = txaf0->txf_uvdata;
+
+ }
+
+ iptr += (txaf0->txf_numuvs * 2);
+
+
+ /* Redefine the Shape Points */
+
+ mypolystart = &pheader->Poly1stPt;
+
+ while(*mypolystart != Term) {
+
+ /*textprint("copying point %d\n", *mypolystart / vsize);*/
+
+ ((VECTORCH *)ShapePoints)[*mypolystart].vx = iptr[0];
+ ((VECTORCH *)ShapePoints)[*mypolystart].vy = iptr[1];
+
+ /*textprint("x, y = %d, %d\n", iptr[0], iptr[1]);*/
+
+ mypolystart++;
+ iptr += 2;
+
+ }
+
+ }
+
+ //project the object's y vector onto the screen.
+ //then rotate the sprite's points according to the vector's orintation
+ //relative to the screen's y vector.
+ vecty=*(VECTORCH*)&Global_ODB_Ptr->ObMat.mat21;
+
+ RotateVector(&vecty,&Global_VDB_Ptr->VDB_Mat);
+ if(Global_VDB_Ptr->VDB_ProjX!=Global_VDB_Ptr->VDB_ProjY)
+ {
+ vecty.vx=MUL_FIXED(vecty.vx,Global_VDB_Ptr->VDB_ProjX);
+ vecty.vy=MUL_FIXED(vecty.vy,Global_VDB_Ptr->VDB_ProjY);
+ }
+ vecty.vz=0;
+ if(!vecty.vx && !vecty.vy)vecty.vy=ONE_FIXED;
+ Normalise(&vecty);
+ vectx.vx=-vecty.vy;
+ vectx.vy=vecty.vx;
+ vectx.vz=0;
+
+ for(numitems = shapeinstrptr->sh_numitems; numitems!=0; numitems--) {
+
+ x = -shapeitemptr[ix];
+ y = shapeitemptr[iy];
+
+ rotptsptr->vx = MUL_FIXED(vectx.vx, x);
+ rotptsptr->vx += MUL_FIXED(vectx.vy, y);
+ rotptsptr->vx += Global_ODB_Ptr->ObView.vx;
+
+ rotptsptr->vy = MUL_FIXED(vecty.vx, x);
+ rotptsptr->vy += MUL_FIXED(vecty.vy, y);
+ rotptsptr->vy += Global_ODB_Ptr->ObView.vy;
+
+ rotptsptr->vz = Global_ODB_Ptr->ObView.vz;
+
+ shapeitemptr += vsize;
+ rotptsptr++;
+
+ }
+
+
+}
+
+
+
+#endif /* UseKevinsModifiedSSRPI */
+
+int GetMVSIndex(TXANIMHEADER
+ *txah, EULER* e )
+{
+ int EulerXIndex, EulerYIndex;
+ int theta,phi; //angles in spherical polar coordinates
+ //phi goes from 0 (top) to deg180 (bottom)
+ VECTORCH v;
+
+ MakeVectorLocal(&Global_ODB_Ptr->ObWorld,&v,&Global_VDB_Ptr->VDB_World,&Global_ODB_Ptr->ObMat);
+ Normalise(&v);
+ phi=-ArcSin(v.vy);
+ phi+=deg90;
+ phi&=wrap360;
+ if(phi==deg180)phi--;
+ if(!v.vx && !v.vz)
+ {
+ theta=0;
+ }
+ else
+ {
+ v.vy=0;
+ Normalise(&v);
+ if(v.vz > Cosine45 || -v.vz>Cosine45) {
+
+ theta = ArcSin(-v.vx);
+
+ if(v.vz < 0) {
+ theta &= wrap360;
+ }
+ else
+ {
+ theta+=deg180;
+ theta =-theta;
+ theta &= wrap360;
+ }
+ }
+
+ else {
+
+ theta = ArcCos(v.vz);
+
+ if(v.vx < 0) {
+ theta = -theta;
+ }
+ theta+=deg180;
+ theta &= wrap360;
+
+ }
+ }
+
+ EulerYIndex = theta;
+ EulerYIndex >>= txah->txa_euleryshift;
+
+
+ EulerYIndex <<= (11 - txah->txa_eulerxshift);
+
+ EulerXIndex = phi;
+ EulerXIndex >>= txah->txa_eulerxshift;
+
+ GLOBALASSERT((EulerXIndex+EulerYIndex)<txah->txa_num_mvs_images);
+
+ return (EulerXIndex + EulerYIndex);
+
+}
+
+
+void AddShape(DISPLAYBLOCK *dptr, VIEWDESCRIPTORBLOCK *VDB_Ptr)
+{
+ SHAPEHEADER *shapeheaderptr;
+
+ if (!dptr->ObShape && dptr->SfxPtr)
+ {
+// DrawSfxObject(dptr);
+ return;
+ }
+ /* KJL 12:42:38 18/05/98 - check to see if object is on fire */
+ if (dptr->ObStrategyBlock)
+ {
+ if(dptr->ObStrategyBlock->SBDamageBlock.IsOnFire)
+ {
+ dptr->SpecialFXFlags |= SFXFLAG_ONFIRE;
+ }
+ else
+ {
+ dptr->SpecialFXFlags &= ~SFXFLAG_ONFIRE;
+ }
+
+ }
+
+ /* is object a morphing one? */
+ if(dptr->ObMorphCtrl)
+ {
+ LOCALASSERT(dptr->ObMorphCtrl->ObMorphHeader);
+ if(dptr->ObMorphCtrl->ObMorphHeader)
+ {
+ GetMorphDisplay(&MorphDisplay, dptr);
+ dptr->ObShape = MorphDisplay.md_shape1;
+ dptr->ObShapeData = MorphDisplay.md_sptr1;
+ shapeheaderptr = MorphDisplay.md_sptr1;
+ }
+ }
+ else
+ {
+ shapeheaderptr = GetShapeData(dptr->ObShape);
+
+ /* It is important to pass this SHAPEHEADER* on to the display block */
+ dptr->ObShapeData = shapeheaderptr;
+
+ // I've put this inside the else so that it does
+ // not conflict with morphing !!!
+ // make sure dptr->ObShapeData is up to date before
+ // doing CopyAnimationFrameToShape
+
+ if (dptr->ShapeAnimControlBlock)
+ {
+ if (!(dptr->ShapeAnimControlBlock->current.empty))
+ {
+ CopyAnimationFrameToShape (&dptr->ShapeAnimControlBlock->current, dptr);
+ }
+ }
+ }
+
+
+ ChooseLightingModel(dptr);
+ /* hierarchical object? */
+ #if 0
+ if (dptr->HModelControlBlock && !dptr->ObStrategyBlock)
+ {
+ DoHModel(dptr->HModelControlBlock,dptr);
+ return;
+ }
+ #endif
+
+
+
+ /* Texture Animation Control */
+
+ if(dptr->ObTxAnimCtrlBlks) ControlTextureAnimation(dptr);
+
+ /* Global Variables */
+ Global_VDB_Ptr = VDB_Ptr;
+ Global_ODB_Ptr = dptr;
+ Global_ShapeHeaderPtr = shapeheaderptr;
+
+ /* Shape Language Specific Setup */
+ SetupShapePipeline();
+
+ /*
+
+ Create the Local -> View Matrix
+
+ LToVMat = VDB_Mat * ObMat
+
+ "Get the points into View Space, then apply the Local Transformation"
+
+ */
+
+ MatrixMultiply(&VDB_Ptr->VDB_Mat, &dptr->ObMat, &LToVMat);
+ MatrixToEuler(&LToVMat, &LToVMat_Euler);
+
+ /*
+
+ Create the World -> Local Matrix
+
+ WToLMat = Transposed Local Matrix
+
+ */
+
+ CopyMatrix(&dptr->ObMat, &WToLMat);
+ TransposeMatrixCH(&WToLMat);
+
+
+ /*
+
+ Transform the View World Location to Local Space
+
+ -> Make the View Loc. relative to the Object View Space Centre
+ -> Rotate this vector using WToLMat
+
+ */
+
+
+ MakeVector(&VDB_Ptr->VDB_World, &dptr->ObWorld, &LocalView);
+ RotateVector(&LocalView, &WToLMat);
+
+ #if 0
+ {
+ LocalCameraZAxis.vx = - dptr->ObWorld.vx;
+ LocalCameraZAxis.vy = - dptr->ObWorld.vy;
+ LocalCameraZAxis.vz = - dptr->ObWorld.vz;
+
+ RotateVector(&LocalCameraZAxis, &WToLMat);
+ }
+ #endif
+
+ NumberOfHeatSources=0;
+ if (dptr->HModelControlBlock)
+ {
+ ObjectCentre = dptr->ObView;
+
+ if (dptr->ObStrategyBlock)
+ {
+ HierarchicalObjectsLowestYValue = dptr->ObStrategyBlock->DynPtr->ObjectVertices[0].vy;
+ if (CurrentVisionMode == VISION_MODE_NORMAL && AvP.PlayerType==I_Alien)
+ {
+ DoAlienEnergyView(dptr);
+ }
+ /*
+ else if (CurrentVisionMode == VISION_MODE_PRED_SEEALIENS && dptr->ObStrategyBlock->I_SBtype == I_BehaviourAlien)
+ {
+ DoAlienEnergyView(dptr);
+ }
+ */
+ }
+
+ if (CurrentVisionMode == VISION_MODE_PRED_THERMAL)
+ {
+ FindHeatSourcesInHModel(dptr);
+ }
+ DoHModel(dptr->HModelControlBlock,dptr);
+ return;
+ }
+ // return;
+
+
+ /* Find out which light sources are in range of of the object */
+ LightSourcesInRangeOfObject(dptr);
+
+ /* Shape Language Execution Shell */
+ {
+ SHAPEINSTR *shapeinstrptr = shapeheaderptr->sh_instruction;
+
+ /* setup the rotated points array */
+ switch (shapeinstrptr->sh_instr)
+ {
+ default:
+ case I_ShapePoints:
+ {
+ if(Global_ODB_Ptr->ObMorphCtrl)
+ {
+ MorphPoints(shapeinstrptr);
+ }
+ else
+ {
+ TranslateShapeVertices(shapeinstrptr);
+ }
+ break;
+ }
+ }
+ }
+ /* call polygon pipeline */
+ ShapePipeline(shapeheaderptr);
+ /* call sfx code */
+ HandleSfxForObject(dptr);
+ if (dptr->ObStrategyBlock)
+ {
+ if (dptr->ObStrategyBlock->I_SBtype==I_BehaviourInanimateObject)
+ {
+ INANIMATEOBJECT_STATUSBLOCK* objStatPtr = dptr->ObStrategyBlock->SBdataptr;
+ if(objStatPtr->typeId==IOT_FieldCharge)
+ {
+
+ int i;
+ D3D_DecalSystem_Setup();
+ for(i=0; i<63; i++)
+ {
+ PARTICLE particle;
+
+ particle.Position.vy = -280+i-GetCos((CloakingPhase/16*i + i*64+particle.Position.vz)&4095)/1024;
+
+ particle.Position.vx = GetCos((CloakingPhase +i*64+particle.Position.vy)&4095)/512;
+ particle.Position.vz = GetSin((CloakingPhase +i*64+particle.Position.vy)&4095)/512;
+ RotateVector(&particle.Position,&dptr->ObMat);
+ particle.Position.vx += dptr->ObWorld.vx;
+ particle.Position.vy += dptr->ObWorld.vy;
+ particle.Position.vz += dptr->ObWorld.vz;
+
+ particle.ParticleID=PARTICLE_MUZZLEFLASH;
+ particle.Colour = 0xff00007f+(FastRandom()&0x7f7f7f);
+ particle.Size = 40;
+ RenderParticle(&particle);
+ }
+ D3D_DecalSystem_End();
+
+ }
+
+ }
+ }
+}
+void DoAlienEnergyView(DISPLAYBLOCK *dispPtr)
+{
+ HMODELCONTROLLER *controllerPtr = dispPtr->HModelControlBlock;
+ unsigned int colour = MARINES_LIFEFORCE_GLOW_COLOUR;
+
+ LOCALASSERT(controllerPtr);
+
+
+
+ /* KJL 16:36:25 10/02/98 - process model */
+ {
+ STRATEGYBLOCK *sbPtr = Global_ODB_Ptr->ObStrategyBlock;
+ if(sbPtr)
+ {
+ switch (sbPtr->I_SBtype)
+ {
+ case I_BehaviourAlien:
+ {
+ colour = ALIENS_LIFEFORCE_GLOW_COLOUR;
+ break;
+ }
+ case I_BehaviourPredator:
+ {
+ colour = PREDATORS_LIFEFORCE_GLOW_COLOUR;
+ break;
+ }
+ case I_BehaviourMarine:
+ case I_BehaviourSeal:
+ {
+ MARINE_STATUS_BLOCK *marineStatusPointer = (MARINE_STATUS_BLOCK *)(sbPtr->SBdataptr);
+ GLOBALASSERT(marineStatusPointer);
+
+ if (marineStatusPointer->Android)
+ {
+ return;
+ }
+ colour = MARINES_LIFEFORCE_GLOW_COLOUR;
+ }
+
+ case I_BehaviourNetGhost:
+ {
+ NETGHOSTDATABLOCK *ghostDataPtr = (NETGHOSTDATABLOCK *)Global_ODB_Ptr->ObStrategyBlock->SBdataptr;
+
+ if (ghostDataPtr->type==I_BehaviourAlienPlayer || ghostDataPtr->type==I_BehaviourAlien
+ || (ghostDataPtr->type==I_BehaviourNetCorpse&&ghostDataPtr->subtype==I_BehaviourAlienPlayer) )
+ {
+ colour = ALIENS_LIFEFORCE_GLOW_COLOUR;
+ }
+ else if (ghostDataPtr->type==I_BehaviourPredatorPlayer || ghostDataPtr->type==I_BehaviourPredator
+ || (ghostDataPtr->type==I_BehaviourNetCorpse&&ghostDataPtr->subtype==I_BehaviourPredatorPlayer) )
+ {
+ colour = PREDATORS_LIFEFORCE_GLOW_COLOUR;
+ }
+
+ break;
+ }
+
+ case I_BehaviourNetCorpse:
+ {
+ NETCORPSEDATABLOCK *corpseDataPtr = (NETCORPSEDATABLOCK *)sbPtr->SBdataptr;
+
+ if (corpseDataPtr->Android)
+ {
+ return;
+ }
+
+ if (corpseDataPtr->Type==I_BehaviourAlienPlayer || corpseDataPtr->Type==I_BehaviourAlien)
+ {
+ colour = ALIENS_LIFEFORCE_GLOW_COLOUR;
+ }
+ else if (corpseDataPtr->Type==I_BehaviourPredatorPlayer || corpseDataPtr->Type==I_BehaviourPredator)
+ {
+ colour = PREDATORS_LIFEFORCE_GLOW_COLOUR;
+ }
+ break;
+ }
+ case I_BehaviourHierarchicalFragment:
+ {
+ HDEBRIS_BEHAV_BLOCK *debrisDataPtr = (HDEBRIS_BEHAV_BLOCK *)sbPtr->SBdataptr;
+ if(debrisDataPtr->Type==I_BehaviourAutoGun || debrisDataPtr->Android)
+ {
+ return;
+ }
+ else if(debrisDataPtr->Type==I_BehaviourAlien)
+ {
+ colour = ALIENS_LIFEFORCE_GLOW_COLOUR;
+ }
+ else if (debrisDataPtr->Type==I_BehaviourPredator)
+ {
+ colour = PREDATORS_LIFEFORCE_GLOW_COLOUR;
+ }
+ else if ((debrisDataPtr->Type==I_BehaviourMarine)||(debrisDataPtr->Type==I_BehaviourSeal))
+ {
+ colour = MARINES_LIFEFORCE_GLOW_COLOUR;
+ }
+ else return;
+ break;
+ }
+
+ case I_BehaviourAutoGun:
+ {
+ /* KJL 19:31:53 25/01/99 - organics only, please */
+ return;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ }
+ if( (Global_ODB_Ptr->SpecialFXFlags & SFXFLAG_MELTINGINTOGROUND)
+ &&(Global_ODB_Ptr->ObFlags2 < ONE_FIXED) )
+ {
+ unsigned int alpha = MUL_FIXED(Global_ODB_Ptr->ObFlags2,colour >> 24);
+ colour = (colour&0xffffff)+(alpha<<24);
+ }
+
+ /* KJL 16:36:12 10/02/98 - check positions are up to date */
+ ProveHModel(controllerPtr,dispPtr);
+
+ D3D_DecalSystem_Setup();
+
+ FindAlienEnergySource_Recursion(controllerPtr,controllerPtr->section_data,colour);
+
+ D3D_DecalSystem_End();
+}
+
+static void FindAlienEnergySource_Recursion(HMODELCONTROLLER *controllerPtr, SECTION_DATA *sectionDataPtr, unsigned int colour)
+{
+ /* KJL 16:29:40 10/02/98 - Recurse through hmodel */
+ if ((sectionDataPtr->First_Child!=NULL)&&(!(sectionDataPtr->flags&section_data_terminate_here)))
+ {
+ SECTION_DATA *childSectionPtr = sectionDataPtr->First_Child;
+
+ while (childSectionPtr!=NULL)
+ {
+ LOCALASSERT(childSectionPtr->My_Parent==sectionDataPtr);
+
+ FindAlienEnergySource_Recursion(controllerPtr,childSectionPtr,colour);
+ childSectionPtr=childSectionPtr->Next_Sibling;
+ }
+ }
+ if(sectionDataPtr->Shape && sectionDataPtr->Shape->shaperadius>LocalDetailLevels.AlienEnergyViewThreshold)
+ {
+ PARTICLE particle;
+
+ particle.Position = sectionDataPtr->World_Offset;
+ particle.ParticleID=PARTICLE_MUZZLEFLASH;
+ particle.Colour = colour;//0x208080ff;
+// particle.Colour = 0x20ff8080;
+// particle.Size = sectionDataPtr->Shape->shaperadius*3;
+// particle.Colour = 0x20ffffff;
+ particle.Size = sectionDataPtr->Shape->shaperadius*2;
+ RenderParticle(&particle);
+ }
+}
+
+void AddHierarchicalShape(DISPLAYBLOCK *dptr, VIEWDESCRIPTORBLOCK *VDB_Ptr)
+{
+
+ SHAPEHEADER *shapeheaderptr;
+ SHAPEINSTR *shapeinstrptr;
+
+ GLOBALASSERT(!dptr->HModelControlBlock);
+ if(!ObjectWithinFrustrum(dptr)) return;
+
+
+ #if 0
+ shapeheaderptr = GetShapeData(dptr->ObShape);
+
+ /* It is important to pass this SHAPEHEADER* on to the display block */
+
+ dptr->ObShapeData = shapeheaderptr;
+ #else
+ shapeheaderptr = dptr->ObShapeData;
+ #endif
+
+
+ /* Texture Animation Control */
+ if(dptr->ObTxAnimCtrlBlks) ControlTextureAnimation(dptr);
+
+ /* Global Variables */
+ Global_VDB_Ptr = VDB_Ptr;
+ Global_ODB_Ptr = dptr;
+ Global_ShapeHeaderPtr = shapeheaderptr;
+
+// if((Global_ODB_Ptr->ObStrategyBlock)&&(Global_ODB_Ptr->ObStrategyBlock->I_SBtype == I_BehaviourAlien))
+ // textprint("hier alien part\n");
+
+ /* Shape Language Specific Setup */
+ SetupShapePipeline();
+
+ /*
+
+ Create the Local -> View Matrix
+
+ LToVMat = VDB_Mat * ObMat
+
+ "Get the points into View Space, then apply the Local Transformation"
+
+ */
+
+ MatrixMultiply(&VDB_Ptr->VDB_Mat, &dptr->ObMat, &LToVMat);
+ MatrixToEuler(&LToVMat, &LToVMat_Euler);
+
+ /*
+
+ Create the World -> Local Matrix
+
+ WToLMat = Transposed Local Matrix
+
+ */
+
+ CopyMatrix(&dptr->ObMat, &WToLMat);
+ TransposeMatrixCH(&WToLMat);
+
+
+ /*
+
+ Transform the View World Location to Local Space
+
+ -> Make the View Loc. relative to the Object View Space Centre
+ -> Rotate this vector using WToLMat
+
+ */
+
+
+ MakeVector(&VDB_Ptr->VDB_World, &dptr->ObWorld, &LocalView);
+ RotateVector(&LocalView, &WToLMat);
+
+ if (!(PIPECLEANER_CHEATMODE||BALLSOFFIRE_CHEATMODE) || !dptr->ObStrategyBlock)
+ {
+ /* Find out which light sources are in range of of the object */
+ LightSourcesInRangeOfObject(dptr);
+
+ /* Shape Language Execution Shell */
+ shapeinstrptr = shapeheaderptr->sh_instruction;
+
+ /* setup the rotated points array */
+ if( (dptr->SpecialFXFlags & SFXFLAG_MELTINGINTOGROUND)
+ &&(dptr->ObFlags2 <= ONE_FIXED) )
+ {
+ SquishPoints(shapeinstrptr);
+ }
+ else
+ {
+ TranslateShapeVertices(shapeinstrptr);
+ }
+
+ /* call polygon pipeline */
+ ShapePipeline(shapeheaderptr);
+ }
+
+ if (BALLSOFFIRE_CHEATMODE && dptr->ObStrategyBlock)
+ {
+ HandleObjectOnFire(dptr);
+ }
+
+ /* call sfx code */
+ HandleSfxForObject(dptr);
+
+}
+
+
+float ViewMatrix[12];
+float ObjectViewMatrix[12];
+float Source[3];
+float Dest[3];
+
+extern void TranslationSetup(void)
+{
+ VECTORCH v = Global_VDB_Ptr->VDB_World;
+ extern int PredatorVisionChangeCounter;
+ float p = PredatorVisionChangeCounter/65536.0f;
+ float o = 1.0f;
+ p = 1.0f+p;
+
+ if (NAUSEA_CHEATMODE)
+ {
+ p = (GetSin((CloakingPhase/3)&4095))/65536.0f;
+ p = 1.0f + p*p;
+
+ o = (GetCos((CloakingPhase/5)&4095))/65536.0f;
+ o = 1.0f + o*o;
+ }
+
+ #if 1
+ ViewMatrix[0+0*4] = (float)(Global_VDB_Ptr->VDB_Mat.mat11)/65536.0f*o;
+ ViewMatrix[1+0*4] = (float)(Global_VDB_Ptr->VDB_Mat.mat21)/65536.0f*o;
+ ViewMatrix[2+0*4] = (float)(Global_VDB_Ptr->VDB_Mat.mat31)/65536.0f*o;
+ #else
+ ViewMatrix[0+0*4] = (float)(Global_VDB_Ptr->VDB_Mat.mat11)/65536.0f;
+ ViewMatrix[1+0*4] = (float)(Global_VDB_Ptr->VDB_Mat.mat21)/65536.0f;
+ ViewMatrix[2+0*4] = (float)(Global_VDB_Ptr->VDB_Mat.mat31)/65536.0f;
+ #endif
+
+ #if 1
+ ViewMatrix[0+1*4] = (float)(Global_VDB_Ptr->VDB_Mat.mat12)*4.0f/(65536.0f*3.0f)*p;
+ ViewMatrix[1+1*4] = (float)(Global_VDB_Ptr->VDB_Mat.mat22)*4.0f/(65536.0f*3.0f)*p;
+ ViewMatrix[2+1*4] = (float)(Global_VDB_Ptr->VDB_Mat.mat32)*4.0f/(65536.0f*3.0f)*p;
+ #else
+ ViewMatrix[0+1*4] = (float)(Global_VDB_Ptr->VDB_Mat.mat12)/(65536.0f);
+ ViewMatrix[1+1*4] = (float)(Global_VDB_Ptr->VDB_Mat.mat22)/(65536.0f);
+ ViewMatrix[2+1*4] = (float)(Global_VDB_Ptr->VDB_Mat.mat32)/(65536.0f);
+ #endif
+ ViewMatrix[0+2*4] = (float)(Global_VDB_Ptr->VDB_Mat.mat13)/65536.0f*CameraZoomScale;
+ ViewMatrix[1+2*4] = (float)(Global_VDB_Ptr->VDB_Mat.mat23)/65536.0f*CameraZoomScale;
+ ViewMatrix[2+2*4] = (float)(Global_VDB_Ptr->VDB_Mat.mat33)/65536.0f*CameraZoomScale;
+
+ RotateVector(&v,&Global_VDB_Ptr->VDB_Mat);
+
+ ViewMatrix[3+0*4] = ((float)-v.vx)*o;
+ ViewMatrix[3+1*4] = ((float)-v.vy)*4.0f/3.0f*p;
+ ViewMatrix[3+2*4] = ((float)-v.vz)*CameraZoomScale;
+
+ if (MIRROR_CHEATMODE)
+ {
+ ViewMatrix[0+0*4] = -ViewMatrix[0+0*4];
+ ViewMatrix[1+0*4] = -ViewMatrix[1+0*4];
+ ViewMatrix[2+0*4] = -ViewMatrix[2+0*4];
+
+ ViewMatrix[3+0*4] = -ViewMatrix[3+0*4];
+ }
+}
+
+
+#ifndef _MSC_VER
+void TranslatePoint(int *source, int *dest, int *matrix);
+#pragma aux TranslatePoint = \
+"fld DWORD PTR [esi]"\
+"fmul DWORD PTR [edi]"\
+"fld DWORD PTR [esi+4]"\
+"fmul DWORD PTR [edi+4]"\
+"fld DWORD PTR [esi+8]"\
+"fmul DWORD PTR [edi+8]"\
+"fxch st(1)"\
+"faddp st(2),st"\
+"fld DWORD PTR [esi]"\
+"fmul DWORD PTR [edi+16]"\
+"fxch st(1)"\
+"faddp st(2),st"\
+"fld DWORD PTR [esi+4]"\
+"fmul DWORD PTR [edi+20]"\
+"fld DWORD PTR [esi+8]"\
+"fmul DWORD PTR [edi+24]"\
+"fxch st(1)"\
+"faddp st(2),st"\
+"fld DWORD PTR [esi]"\
+"fmul DWORD PTR [edi+32]"\
+"fxch st(1)"\
+"faddp st(2),st"\
+"fld DWORD PTR [esi+4]"\
+"fmul DWORD PTR [edi+36]"\
+"fld DWORD PTR [esi+8]"\
+"fmul DWORD PTR [edi+40]"\
+"fxch st(1)"\
+"faddp st(2),st"\
+"fxch st(3)"\
+"fadd DWORD PTR [edi+12]"\
+"fxch st(1)"\
+"faddp st(3),st"\
+"fxch st(1)"\
+"fadd DWORD PTR [edi+28]"\
+"fxch st(2)"\
+"fadd DWORD PTR [edi+44]"\
+"fxch st(1)"\
+"fstp DWORD PTR [ebx]"\
+"fxch st(1)"\
+"fstp DWORD PTR [ebx+4]"\
+"fstp DWORD PTR [ebx+8]"\
+parm[esi] [ebx] [edi];
+
+#else
+void TranslatePoint(int *source, int *dest, int *matrix)
+{
+ __asm
+ {
+ mov esi,source
+ mov ebx,dest
+ mov edi,matrix
+ fld DWORD PTR [esi]
+ fmul DWORD PTR [edi]
+ fld DWORD PTR [esi+4]
+ fmul DWORD PTR [edi+4]
+ fld DWORD PTR [esi+8]
+ fmul DWORD PTR [edi+8]
+ fxch st(1)
+ faddp st(2),st
+ fld DWORD PTR [esi]
+ fmul DWORD PTR [edi+16]
+ fxch st(1)
+ faddp st(2),st
+ fld DWORD PTR [esi+4]
+ fmul DWORD PTR [edi+20]
+ fld DWORD PTR [esi+8]
+ fmul DWORD PTR [edi+24]
+ fxch st(1)
+ faddp st(2),st
+ fld DWORD PTR [esi]
+ fmul DWORD PTR [edi+32]
+ fxch st(1)
+ faddp st(2),st
+ fld DWORD PTR [esi+4]
+ fmul DWORD PTR [edi+36]
+ fld DWORD PTR [esi+8]
+ fmul DWORD PTR [edi+40]
+ fxch st(1)
+ faddp st(2),st
+ fxch st(3)
+ fadd DWORD PTR [edi+12]
+ fxch st(1)
+ faddp st(3),st
+ fxch st(1)
+ fadd DWORD PTR [edi+28]
+ fxch st(2)
+ fadd DWORD PTR [edi+44]
+ fxch st(1)
+ fstp DWORD PTR [ebx]
+ fxch st(1)
+ fstp DWORD PTR [ebx+4]
+ fstp DWORD PTR [ebx+8]
+ }
+}
+
+#endif
+
+void TranslatePointIntoViewspace(VECTORCH *pointPtr)
+{
+
+ Source[0] = pointPtr->vx;
+ Source[1] = pointPtr->vy;
+ Source[2] = pointPtr->vz;
+
+ TranslatePoint((int*)&Source,(int*)&Dest,(int*)&ViewMatrix);
+
+ f2i(pointPtr->vx,Dest[0]);
+ f2i(pointPtr->vy,Dest[1]);
+ f2i(pointPtr->vz,Dest[2]);
+}
+void SquishPoints(SHAPEINSTR *shapeinstrptr)
+{
+ int **shapeitemarrayptr = shapeinstrptr->sh_instr_data;
+ VECTORCH *shapePts = (VECTORCH*)*shapeitemarrayptr;
+ {
+ int i;
+ int scale = Global_ODB_Ptr->ObFlags2;
+
+ for (i=0; i<Global_ShapeHeaderPtr->numpoints; i++)
+ {
+ VECTORCH point = shapePts[i];
+
+ RotateVector(&point,&Global_ODB_Ptr->ObMat);
+
+ point.vx = MUL_FIXED(point.vx,ONE_FIXED*3/2 - scale/2);
+ point.vx += Global_ODB_Ptr->ObWorld.vx;
+
+ point.vz = MUL_FIXED(point.vz,ONE_FIXED*3/2 - scale/2);
+ point.vz += Global_ODB_Ptr->ObWorld.vz;
+
+ point.vy += Global_ODB_Ptr->ObWorld.vy;
+ point.vy = HierarchicalObjectsLowestYValue + MUL_FIXED(point.vy-HierarchicalObjectsLowestYValue, scale);
+
+ Source[0] = point.vx;
+ Source[1] = point.vy;
+ Source[2] = point.vz;
+
+ TranslatePoint((int*)&Source,(int*)&Dest,(int*)&ViewMatrix);
+
+ f2i(RotatedPts[i].vx,Dest[0]);
+ f2i(RotatedPts[i].vy,Dest[1]);
+ f2i(RotatedPts[i].vz,Dest[2]);
+ }
+ }
+}
+
+void MorphPoints(SHAPEINSTR *shapeinstrptr)
+{
+ VECTORCH *srcPtr;
+ {
+ SHAPEHEADER *shape1Ptr;
+ VECTORCH *shape1PointsPtr;
+ VECTORCH *shape2PointsPtr;
+
+ /* Set up the morph data */
+ GetMorphDisplay(&MorphDisplay, Global_ODB_Ptr);
+
+ shape1Ptr = MorphDisplay.md_sptr1;
+
+ if(MorphDisplay.md_lerp == 0x0000)
+ {
+
+ srcPtr = (VECTORCH *)*shape1Ptr->points;
+ }
+ else if(MorphDisplay.md_lerp == 0xffff)
+ {
+ SHAPEHEADER *shape2Ptr;
+ shape2Ptr = MorphDisplay.md_sptr2;
+
+ srcPtr = (VECTORCH *)*shape2Ptr->points;
+ Global_ShapePoints = *(shape2Ptr->points);
+
+ }
+ else
+ {
+ SHAPEHEADER *shape2Ptr;
+ shape2Ptr = MorphDisplay.md_sptr2;
+
+ shape1PointsPtr = (VECTORCH *)(*shape1Ptr->points);
+ shape2PointsPtr = (VECTORCH *)(*shape2Ptr->points);
+
+ {
+ int numberOfPoints = shape1Ptr->numpoints;
+ VECTORCH *morphedPointsPtr = (VECTORCH *) MorphedPts;
+
+ while(numberOfPoints--)
+ {
+ VECTORCH vertex1 = *shape1PointsPtr;
+ VECTORCH vertex2 = *shape2PointsPtr;
+
+ if( (vertex1.vx == vertex2.vx && vertex1.vy == vertex2.vy && vertex1.vz == vertex2.vz) )
+ {
+ *morphedPointsPtr = vertex1;
+ }
+ else
+ {
+ /* KJL 15:27:20 05/22/97 - I've changed this to speed things up, If a vertex
+ component has a magnitude greater than 32768 things will go wrong. */
+ morphedPointsPtr->vx = vertex1.vx + (((vertex2.vx-vertex1.vx)*MorphDisplay.md_lerp)>>16);
+ morphedPointsPtr->vy = vertex1.vy + (((vertex2.vy-vertex1.vy)*MorphDisplay.md_lerp)>>16);
+ morphedPointsPtr->vz = vertex1.vz + (((vertex2.vz-vertex1.vz)*MorphDisplay.md_lerp)>>16);
+ }
+
+ shape1PointsPtr++;
+ shape2PointsPtr++;
+ morphedPointsPtr++;
+ }
+ }
+
+ Global_ShapePoints = (int*)MorphedPts;
+ srcPtr = (VECTORCH *)MorphedPts;
+ }
+ }
+ {
+ VECTORCH *destPtr = RotatedPts;
+ int i;
+ for(i = shapeinstrptr->sh_numitems; i!=0; i--)
+ {
+ Source[0] = srcPtr->vx+Global_ODB_Ptr->ObWorld.vx;
+ Source[1] = srcPtr->vy+Global_ODB_Ptr->ObWorld.vy;
+ Source[2] = srcPtr->vz+Global_ODB_Ptr->ObWorld.vz;
+
+ TranslatePoint((int*)&Source,(int*)&Dest,(int*)&ViewMatrix);
+
+ f2i(destPtr->vx,Dest[0]);
+ f2i(destPtr->vy,Dest[1]);
+ f2i(destPtr->vz,Dest[2]);
+ srcPtr++;
+ destPtr++;
+ }
+ }
+
+}
+
+void TranslateShapeVertices(SHAPEINSTR *shapeinstrptr)
+{
+ VECTORCH *destPtr = RotatedPts;
+ int **shapeitemarrayptr;
+ VECTORCH *srcPtr;
+ int i;
+// MNormalise(&LToVMat);
+ shapeitemarrayptr = shapeinstrptr->sh_instr_data;
+ srcPtr = (VECTORCH*)*shapeitemarrayptr;
+ if (Global_ODB_Ptr->ObFlags & ObFlag_ArbRot)
+ {
+ for(i = shapeinstrptr->sh_numitems; i!=0; i--)
+ {
+ destPtr->vx = (srcPtr->vx+Global_ODB_Ptr->ObView.vx);
+ destPtr->vy = ((srcPtr->vy+Global_ODB_Ptr->ObView.vy)*4)/3;
+ destPtr->vz = (srcPtr->vz+Global_ODB_Ptr->ObView.vz);
+
+ srcPtr++;
+ destPtr++;
+
+ }
+ }
+ else
+ {
+ ObjectViewMatrix[0+0*4] = (float)(Global_ODB_Ptr->ObMat.mat11)/65536.0f;
+ ObjectViewMatrix[1+0*4] = (float)(Global_ODB_Ptr->ObMat.mat21)/65536.0f;
+ ObjectViewMatrix[2+0*4] = (float)(Global_ODB_Ptr->ObMat.mat31)/65536.0f;
+
+ ObjectViewMatrix[0+1*4] = (float)(Global_ODB_Ptr->ObMat.mat12)/(65536.0f);
+ ObjectViewMatrix[1+1*4] = (float)(Global_ODB_Ptr->ObMat.mat22)/(65536.0f);
+ ObjectViewMatrix[2+1*4] = (float)(Global_ODB_Ptr->ObMat.mat32)/(65536.0f);
+
+ ObjectViewMatrix[0+2*4] = (float)(Global_ODB_Ptr->ObMat.mat13)/65536.0f;
+ ObjectViewMatrix[1+2*4] = (float)(Global_ODB_Ptr->ObMat.mat23)/65536.0f;
+ ObjectViewMatrix[2+2*4] = (float)(Global_ODB_Ptr->ObMat.mat33)/65536.0f;
+
+ ObjectViewMatrix[3+0*4] = Global_ODB_Ptr->ObWorld.vx;
+ ObjectViewMatrix[3+1*4] = Global_ODB_Ptr->ObWorld.vy;
+ ObjectViewMatrix[3+2*4] = Global_ODB_Ptr->ObWorld.vz;
+ for(i = shapeinstrptr->sh_numitems; i!=0; i--)
+ {
+ Source[0] = srcPtr->vx;
+ Source[1] = srcPtr->vy;
+ Source[2] = srcPtr->vz;
+
+ TranslatePoint((int*)&Source,(int*)&Dest,(int*)&ObjectViewMatrix);
+ TranslatePoint((int*)&Dest,(int*)&Source,(int*)&ViewMatrix);
+
+ f2i(destPtr->vx,Source[0]);
+ f2i(destPtr->vy,Source[1]);
+ f2i(destPtr->vz,Source[2]);
+ srcPtr++;
+ destPtr++;
+ }
+ }
+}
+
+void RenderDecal(DECAL *decalPtr)
+{
+ /* translate decal into view space */
+ {
+ VECTORCH translatedPosition = decalPtr->Vertices[0];
+ TranslatePointIntoViewspace(&translatedPosition);
+ VerticesBuffer[0].X = translatedPosition.vx;
+ VerticesBuffer[0].Y = translatedPosition.vy;
+ VerticesBuffer[0].Z = translatedPosition.vz;
+ }
+ {
+ VECTORCH translatedPosition = decalPtr->Vertices[1];
+ TranslatePointIntoViewspace(&translatedPosition);
+ VerticesBuffer[1].X = translatedPosition.vx;
+ VerticesBuffer[1].Y = translatedPosition.vy;
+ VerticesBuffer[1].Z = translatedPosition.vz;
+ }
+ {
+ VECTORCH translatedPosition = decalPtr->Vertices[2];
+ TranslatePointIntoViewspace(&translatedPosition);
+ VerticesBuffer[2].X = translatedPosition.vx;
+ VerticesBuffer[2].Y = translatedPosition.vy;
+ VerticesBuffer[2].Z = translatedPosition.vz;
+ }
+ {
+ VECTORCH translatedPosition = decalPtr->Vertices[3];
+ TranslatePointIntoViewspace(&translatedPosition);
+ VerticesBuffer[3].X = translatedPosition.vx;
+ VerticesBuffer[3].Y = translatedPosition.vy;
+ VerticesBuffer[3].Z = translatedPosition.vz;
+ }
+ {
+ int outcode = DecalWithinFrustrum(decalPtr);
+
+ if (outcode)
+ {
+ switch(decalPtr->DecalID)
+ {
+ default:
+ case DECAL_SCORCHED:
+ {
+ DecalPolygon_Construct(decalPtr);
+
+ if (outcode!=2)
+ {
+ TexturedPolygon_ClipWithZ();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ TexturedPolygon_ClipWithNegativeX();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ TexturedPolygon_ClipWithPositiveY();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ TexturedPolygon_ClipWithNegativeY();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ TexturedPolygon_ClipWithPositiveX();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ D3D_Decal_Output(decalPtr,RenderPolygon.Vertices);
+
+ }
+ else D3D_Decal_Output(decalPtr,VerticesBuffer);
+ break;
+ }
+ }
+ }
+ }
+ #if MIRRORING_ON
+ if (MirroringActive) RenderMirroredDecal(decalPtr);
+ #endif
+}
+void RenderParticle(PARTICLE *particlePtr)
+{
+// PARTICLE_DESC *particleDescPtr = &ParticleDescription[particlePtr->ParticleID];
+ int particleSize = particlePtr->Size;
+
+ {
+ VECTORCH translatedPosition = particlePtr->Position;
+ TranslatePointIntoViewspace(&translatedPosition);
+ VerticesBuffer[0].X = translatedPosition.vx;
+ VerticesBuffer[3].X = translatedPosition.vx;
+ VerticesBuffer[0].Y = translatedPosition.vy;
+ VerticesBuffer[3].Y = translatedPosition.vy;
+ VerticesBuffer[0].Z = translatedPosition.vz;
+ VerticesBuffer[3].Z = translatedPosition.vz;
+ }
+
+ if ((particlePtr->ParticleID == PARTICLE_EXPLOSIONFIRE)
+ ||(particlePtr->ParticleID == PARTICLE_RICOCHET_SPARK)
+ ||(particlePtr->ParticleID == PARTICLE_SPARK)
+ ||(particlePtr->ParticleID == PARTICLE_ORANGE_SPARK)
+ ||(particlePtr->ParticleID == PARTICLE_ORANGE_PLASMA)
+ ||(particlePtr->ParticleID == PARTICLE_ALIEN_BLOOD)
+ ||(particlePtr->ParticleID == PARTICLE_PREDATOR_BLOOD)
+ ||(particlePtr->ParticleID == PARTICLE_HUMAN_BLOOD)
+ ||(particlePtr->ParticleID == PARTICLE_WATERFALLSPRAY)
+ ||(particlePtr->ParticleID == PARTICLE_LASERBEAM)
+ ||(particlePtr->ParticleID == PARTICLE_PLASMABEAM)
+ ||(particlePtr->ParticleID == PARTICLE_TRACER)
+ ||(particlePtr->ParticleID == PARTICLE_PREDPISTOL_FLECHETTE)
+ ||(particlePtr->ParticleID == PARTICLE_PREDPISTOL_FLECHETTE_NONDAMAGING)
+ )
+ {
+ VECTORCH translatedPosition = particlePtr->Offset;
+ TranslatePointIntoViewspace(&translatedPosition);
+ VerticesBuffer[1].X = translatedPosition.vx;
+ VerticesBuffer[2].X = translatedPosition.vx;
+ VerticesBuffer[1].Y = translatedPosition.vy;
+ VerticesBuffer[2].Y = translatedPosition.vy;
+ VerticesBuffer[1].Z = translatedPosition.vz;
+ VerticesBuffer[2].Z = translatedPosition.vz;
+
+ {
+ int deltaX = VerticesBuffer[1].X - VerticesBuffer[0].X;
+ int deltaY = VerticesBuffer[1].Y - VerticesBuffer[0].Y;
+ int splitY = 0;
+
+ if (deltaX>=0)
+ {
+ if (deltaY>=0)
+ {
+ if (deltaX>deltaY)
+ {
+ splitY = 1;
+ }
+ }
+ else if (deltaX>-deltaY)
+ {
+ splitY = 1;
+ }
+ }
+ else
+ {
+ if (deltaY>=0)
+ {
+ if (-deltaX>deltaY)
+ {
+ splitY = 1;
+ }
+ }
+ else if (-deltaX>-deltaY)
+ {
+ splitY = 1;
+ }
+ }
+ if (splitY)
+ {
+ if (deltaX>0)
+ {
+ /* 1 & 2 are more +ve in X */
+ VerticesBuffer[0].X -= particleSize;
+ VerticesBuffer[0].Y -= MUL_FIXED(particleSize,87381);
+ VerticesBuffer[1].X += particleSize;
+ VerticesBuffer[1].Y -= MUL_FIXED(particleSize,87381);
+ VerticesBuffer[2].X += particleSize;
+ VerticesBuffer[2].Y += MUL_FIXED(particleSize,87381);
+ VerticesBuffer[3].X -= particleSize;
+ VerticesBuffer[3].Y += MUL_FIXED(particleSize,87381);
+ }
+ else
+ {
+ /* 1 & 2 are more -ve in X */
+ VerticesBuffer[0].X += particleSize;
+ VerticesBuffer[0].Y -= MUL_FIXED(particleSize,87381);
+ VerticesBuffer[1].X -= particleSize;
+ VerticesBuffer[1].Y -= MUL_FIXED(particleSize,87381);
+ VerticesBuffer[2].X -= particleSize;
+ VerticesBuffer[2].Y += MUL_FIXED(particleSize,87381);
+ VerticesBuffer[3].X += particleSize;
+ VerticesBuffer[3].Y += MUL_FIXED(particleSize,87381);
+ }
+
+ }
+ else
+ {
+ if (deltaY>0)
+ {
+ /* 1 & 2 are more +ve in Y */
+ VerticesBuffer[0].X -= particleSize;
+ VerticesBuffer[0].Y -= MUL_FIXED(particleSize,87381);
+ VerticesBuffer[1].X -= particleSize;
+ VerticesBuffer[1].Y += MUL_FIXED(particleSize,87381);
+ VerticesBuffer[2].X += particleSize;
+ VerticesBuffer[2].Y += MUL_FIXED(particleSize,87381);
+ VerticesBuffer[3].X += particleSize;
+ VerticesBuffer[3].Y -= MUL_FIXED(particleSize,87381);
+ }
+ else
+ {
+ /* 1 & 2 are more -ve in Y */
+ VerticesBuffer[0].X -= particleSize;
+ VerticesBuffer[0].Y += MUL_FIXED(particleSize,87381);
+ VerticesBuffer[1].X -= particleSize;
+ VerticesBuffer[1].Y -= MUL_FIXED(particleSize,87381);
+ VerticesBuffer[2].X += particleSize;
+ VerticesBuffer[2].Y -= MUL_FIXED(particleSize,87381);
+ VerticesBuffer[3].X += particleSize;
+ VerticesBuffer[3].Y += MUL_FIXED(particleSize,87381);
+ }
+
+ }
+ }
+ }
+ else
+ {
+ VECTOR2D offset[4];
+ VerticesBuffer[1].X = VerticesBuffer[0].X;
+ VerticesBuffer[2].X = VerticesBuffer[0].X;
+ VerticesBuffer[1].Y = VerticesBuffer[0].Y;
+ VerticesBuffer[2].Y = VerticesBuffer[0].Y;
+ VerticesBuffer[1].Z = VerticesBuffer[0].Z;
+ VerticesBuffer[2].Z = VerticesBuffer[0].Z;
+
+ offset[0].vx = -particleSize;
+ offset[0].vy = -particleSize;
+
+ offset[1].vx = +particleSize;
+ offset[1].vy = -particleSize;
+
+ offset[2].vx = +particleSize;
+ offset[2].vy = +particleSize;
+
+ offset[3].vx = -particleSize;
+ offset[3].vy = +particleSize;
+
+ if ((particlePtr->ParticleID == PARTICLE_MUZZLEFLASH) )
+ {
+ extern void RotateVertex(VECTOR2D *vertexPtr, int theta);
+ int theta = FastRandom()&4095;
+ RotateVertex(&offset[0],theta);
+ RotateVertex(&offset[1],theta);
+ RotateVertex(&offset[2],theta);
+ RotateVertex(&offset[3],theta);
+ }
+ else if ((particlePtr->ParticleID == PARTICLE_SMOKECLOUD)
+ ||(particlePtr->ParticleID == PARTICLE_GUNMUZZLE_SMOKE)
+ ||(particlePtr->ParticleID == PARTICLE_PARGEN_FLAME)
+ ||(particlePtr->ParticleID == PARTICLE_FLAME))
+ {
+ extern void RotateVertex(VECTOR2D *vertexPtr, int theta);
+ int theta = (particlePtr->Offset.vx+MUL_FIXED(CloakingPhase,particlePtr->Offset.vy))&4095;
+ RotateVertex(&offset[0],theta);
+ RotateVertex(&offset[1],theta);
+ RotateVertex(&offset[2],theta);
+ RotateVertex(&offset[3],theta);
+ }
+ VerticesBuffer[0].X += offset[0].vx;
+ VerticesBuffer[0].Y += MUL_FIXED(offset[0].vy,87381);
+
+ VerticesBuffer[1].X += offset[1].vx;
+ VerticesBuffer[1].Y += MUL_FIXED(offset[1].vy,87381);
+
+ VerticesBuffer[2].X += offset[2].vx;
+ VerticesBuffer[2].Y += MUL_FIXED(offset[2].vy,87381);
+
+ VerticesBuffer[3].X += offset[3].vx;
+ VerticesBuffer[3].Y += MUL_FIXED(offset[3].vy,87381);
+
+ }
+
+ {
+ int outcode = QuadWithinFrustrum();
+
+ if (outcode)
+ {
+ ParticlePolygon_Construct(particlePtr);
+
+ if (outcode!=2)
+ {
+ TexturedPolygon_ClipWithZ();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ TexturedPolygon_ClipWithNegativeX();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ TexturedPolygon_ClipWithPositiveY();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ TexturedPolygon_ClipWithNegativeY();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ TexturedPolygon_ClipWithPositiveX();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ D3D_Particle_Output(particlePtr,RenderPolygon.Vertices);
+
+ }
+ else D3D_Particle_Output(particlePtr,VerticesBuffer);
+ }
+ }
+}
+
+extern void RenderFlechetteParticle(PARTICLE *particlePtr)
+{
+ VECTORCH vertices[5];
+ MATRIXCH mat;
+
+ MakeMatrixFromDirection(&particlePtr->Velocity,&mat);
+
+ mat.mat11 >>= 12;
+ mat.mat12 >>= 12;
+ mat.mat13 >>= 12;
+ mat.mat21 >>= 12;
+ mat.mat22 >>= 12;
+ mat.mat23 >>= 12;
+ mat.mat31 >>= 9;
+ mat.mat32 >>= 9;
+ mat.mat33 >>= 9;
+
+
+ vertices[0].vx = particlePtr->Position.vx-mat.mat31+mat.mat11;
+ vertices[0].vy = particlePtr->Position.vy-mat.mat32+mat.mat12;
+ vertices[0].vz = particlePtr->Position.vz-mat.mat33+mat.mat13;
+
+ vertices[1].vx = particlePtr->Position.vx-mat.mat31-mat.mat11;
+ vertices[1].vy = particlePtr->Position.vy-mat.mat32-mat.mat12;
+ vertices[1].vz = particlePtr->Position.vz-mat.mat33-mat.mat13;
+
+ vertices[2] = particlePtr->Position;
+
+ vertices[3].vx = particlePtr->Position.vx-mat.mat31+mat.mat21;
+ vertices[3].vy = particlePtr->Position.vy-mat.mat32+mat.mat22;
+ vertices[3].vz = particlePtr->Position.vz-mat.mat33+mat.mat23;
+
+ vertices[4].vx = particlePtr->Position.vx-mat.mat31-mat.mat21;
+ vertices[4].vy = particlePtr->Position.vy-mat.mat32-mat.mat22;
+ vertices[4].vz = particlePtr->Position.vz-mat.mat33-mat.mat23;
+
+ TranslatePointIntoViewspace(&vertices[0]);
+ TranslatePointIntoViewspace(&vertices[1]);
+ TranslatePointIntoViewspace(&vertices[2]);
+ TranslatePointIntoViewspace(&vertices[3]);
+ TranslatePointIntoViewspace(&vertices[4]);
+
+ {
+ int i;
+ for (i=0; i<3; i++)
+ {
+ VerticesBuffer[i].X = vertices[i].vx;
+ VerticesBuffer[i].Y = vertices[i].vy;
+ VerticesBuffer[i].Z = vertices[i].vz;
+
+ VerticesBuffer[i].A = (particlePtr->Colour>>24)&255;
+ VerticesBuffer[i].R = (particlePtr->Colour>>16)&255;
+ VerticesBuffer[i].G = (particlePtr->Colour>>8)&255;
+ VerticesBuffer[i].B = (particlePtr->Colour)&255;
+ }
+ RenderPolygon.NumberOfVertices=3;
+ RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL;
+ }
+ {
+ int outcode = TriangleWithinFrustrum();
+ POLYHEADER fakeHeader;
+ fakeHeader.PolyFlags = iflag_transparent;
+
+ do
+ {
+ if (outcode)
+ {
+ if (outcode!=2)
+ {
+ GouraudPolygon_ClipWithZ();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudPolygon_ClipWithNegativeX();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudPolygon_ClipWithPositiveY();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudPolygon_ClipWithNegativeY();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudPolygon_ClipWithPositiveX();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ D3D_ZBufferedGouraudPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
+ }
+ else D3D_ZBufferedGouraudPolygon_Output(&fakeHeader,VerticesBuffer);
+ }
+ }
+ while(0);
+ }
+ {
+ int i;
+ for (i=0; i<3; i++)
+ {
+ VerticesBuffer[i].X = vertices[i+2].vx;
+ VerticesBuffer[i].Y = vertices[i+2].vy;
+ VerticesBuffer[i].Z = vertices[i+2].vz;
+
+ VerticesBuffer[i].A = (particlePtr->Colour>>24)&255;
+ VerticesBuffer[i].R = (particlePtr->Colour>>16)&255;
+ VerticesBuffer[i].G = (particlePtr->Colour>>8)&255;
+ VerticesBuffer[i].B = (particlePtr->Colour)&255;
+ }
+ RenderPolygon.NumberOfVertices=3;
+ RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL;
+ }
+ {
+ int outcode = TriangleWithinFrustrum();
+ POLYHEADER fakeHeader;
+ fakeHeader.PolyFlags = iflag_transparent;
+
+ do
+ {
+ if (outcode)
+ {
+ if (outcode!=2)
+ {
+ GouraudPolygon_ClipWithZ();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudPolygon_ClipWithNegativeX();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudPolygon_ClipWithPositiveY();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudPolygon_ClipWithNegativeY();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudPolygon_ClipWithPositiveX();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ D3D_ZBufferedGouraudPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
+ }
+ else D3D_ZBufferedGouraudPolygon_Output(&fakeHeader,VerticesBuffer);
+ }
+ }
+ while(0);
+ }
+
+}
+
+static void ParticlePolygon_Construct(PARTICLE *particlePtr)
+{
+ PARTICLE_DESC *particleDescPtr = &ParticleDescription[particlePtr->ParticleID];
+ RenderPolygon.NumberOfVertices=4;
+
+ VerticesBuffer[0].U = particleDescPtr->StartU;
+ VerticesBuffer[0].V = particleDescPtr->StartV;
+
+ VerticesBuffer[1].U = particleDescPtr->EndU;
+ VerticesBuffer[1].V = particleDescPtr->StartV;
+
+ VerticesBuffer[2].U = particleDescPtr->EndU;
+ VerticesBuffer[2].V = particleDescPtr->EndV;
+
+ VerticesBuffer[3].U = particleDescPtr->StartU;
+ VerticesBuffer[3].V = particleDescPtr->EndV;
+
+}
+
+void RenderMirroredDecal(DECAL *decalPtr)
+{
+ /* translate decal into view space */
+ {
+ VECTORCH translatedPosition = decalPtr->Vertices[0];
+ translatedPosition.vx = MirroringAxis - translatedPosition.vx;
+ TranslatePointIntoViewspace(&translatedPosition);
+ VerticesBuffer[0].X = translatedPosition.vx;
+ VerticesBuffer[0].Y = translatedPosition.vy;
+ VerticesBuffer[0].Z = translatedPosition.vz;
+ }
+ {
+ VECTORCH translatedPosition = decalPtr->Vertices[1];
+ translatedPosition.vx = MirroringAxis - translatedPosition.vx;
+ TranslatePointIntoViewspace(&translatedPosition);
+ VerticesBuffer[1].X = translatedPosition.vx;
+ VerticesBuffer[1].Y = translatedPosition.vy;
+ VerticesBuffer[1].Z = translatedPosition.vz;
+ }
+ {
+ VECTORCH translatedPosition = decalPtr->Vertices[2];
+ translatedPosition.vx = MirroringAxis - translatedPosition.vx;
+ TranslatePointIntoViewspace(&translatedPosition);
+ VerticesBuffer[2].X = translatedPosition.vx;
+ VerticesBuffer[2].Y = translatedPosition.vy;
+ VerticesBuffer[2].Z = translatedPosition.vz;
+ }
+ {
+ VECTORCH translatedPosition = decalPtr->Vertices[3];
+ translatedPosition.vx = MirroringAxis - translatedPosition.vx;
+ TranslatePointIntoViewspace(&translatedPosition);
+ VerticesBuffer[3].X = translatedPosition.vx;
+ VerticesBuffer[3].Y = translatedPosition.vy;
+ VerticesBuffer[3].Z = translatedPosition.vz;
+ }
+ {
+ int outcode = DecalWithinFrustrum(decalPtr);
+
+ if (outcode)
+ {
+ switch(decalPtr->DecalID)
+ {
+ default:
+ case DECAL_SCORCHED:
+ {
+ DecalPolygon_Construct(decalPtr);
+
+ if (outcode!=2)
+ {
+ TexturedPolygon_ClipWithZ();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ TexturedPolygon_ClipWithNegativeX();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ TexturedPolygon_ClipWithPositiveY();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ TexturedPolygon_ClipWithNegativeY();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ TexturedPolygon_ClipWithPositiveX();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ D3D_Decal_Output(decalPtr,RenderPolygon.Vertices);
+
+ }
+ else D3D_Decal_Output(decalPtr,VerticesBuffer);
+ break;
+ }
+ }
+ }
+ }
+}
+
+
+static void DecalPolygon_Construct(DECAL *decalPtr)
+{
+ DECAL_DESC *decalDescPtr = &DecalDescription[decalPtr->DecalID];
+ RenderPolygon.NumberOfVertices=4;
+
+ VerticesBuffer[0].U = decalDescPtr->StartU+decalPtr->UOffset;
+ VerticesBuffer[0].V = decalDescPtr->StartV;
+
+ VerticesBuffer[1].U = decalDescPtr->EndU+decalPtr->UOffset;
+ VerticesBuffer[1].V = decalDescPtr->StartV;
+
+ VerticesBuffer[2].U = decalDescPtr->EndU+decalPtr->UOffset;
+ VerticesBuffer[2].V = decalDescPtr->EndV;
+
+ VerticesBuffer[3].U = decalDescPtr->StartU+decalPtr->UOffset;
+ VerticesBuffer[3].V = decalDescPtr->EndV;
+
+}
+
+#if 0
+ int polys[][4] =
+ {
+ {1,3,5,7},
+ {1,3,9,11},
+ {2,3,5,4},
+ {2,3,9,8},
+
+ {0,2,4,6},
+ {0,2,8,10},
+ {0,1,7,6},
+ {0,1,11,10},
+
+ {12,13,15,14},
+ {4,5,7,6},
+
+ {8,9,5,4},
+ {6,7,11,10},
+ {8,4,6,10},
+ {5,9,11,7},
+
+// {8,2,4,4},
+// {9,3,5,5},
+// {10,0,6,6},
+// {7,1,11,11}
+ };
+ int alphaValue[]={64,64,64,64, 16,16,16,16, 0,0,0,0, 128,128,128,128};
+
+//void RenderShaftOfLight(SHAFTOFLIGHT *shaftPtr)
+void RenderShaftOfLight(MODULE *modulePtr)
+{
+ /* translate shaft into view space */
+
+// suitable for invasion2
+ VECTORCH shaftVertices[]=
+ {
+ {-5500,9000,9822},
+ {-4500,9000,9822},
+ {-5500,10000,9822},
+ {-4500,10000,9822},
+
+ {-6000,15900,13000},
+ {-4000,15900,13000},
+ {-6000,15900,15500},
+ {-4000,15900,15500},
+
+ {-6500,15900,12500},
+ {-3500,15900,12500},
+ {-6500,15900,16000},
+ {-3500,15900,16000},
+ };
+ /*
+ VECTORCH shaftVertices[]=
+ {
+ {0, 0, 0},
+ {0, 0, 1139},
+ {-1338, 7113, 0},
+ {-1338, 7113, 1139},
+
+
+ {,1948,}
+
+ {26002+ -1700, 7781 , -25328+ -800},
+ {26002+ -900, 7781 , -25328+ +800},
+ {26002+ 1700, 7781 , -25328+ -800},
+ {26002+ 1700, 7781 , -25328+ +800},
+
+ {26002+ -1100, 7781 , -25328+ -1000},
+ {26002+ -1100, 7781 , -25328+ +1000},
+ {26002+ 2000, 7781 , -25328+ -1000},
+ {26002+ 2000, 7781 , -25328+ +1000},
+
+ };
+ */
+ VECTORCH translatedPts[12];
+
+ POLYHEADER fakeHeader;
+ DECAL fakeDecal;
+ int polyNumber;
+
+ fakeDecal.ModuleIndex=148;
+// fakeDecal.ModuleIndex=17;
+ fakeHeader.PolyFlags = iflag_transparent;
+
+ {
+ int i = 11;
+ do
+ {
+ translatedPts[i] = shaftVertices[i];
+// translatedPts[i].vx+=10712;
+// translatedPts[i].vy+=-6480;
+// translatedPts[i].vz+=-25898;
+ TranslatePointIntoViewspace(&translatedPts[i]);
+ }
+ while(i--);
+ }
+
+ for(polyNumber=0; polyNumber<10; polyNumber++)
+ {
+ {
+ int i;
+ for (i=0; i<4; i++)
+ {
+ int v = polys[polyNumber][i];
+ VerticesBuffer[i].A = alphaValue[v];
+ if (v>11)
+ {
+ VerticesBuffer[i].X = translatedPts[v-12].vx;
+ VerticesBuffer[i].Y = translatedPts[v-12].vy;
+ VerticesBuffer[i].Z = translatedPts[v-12].vz;
+ }
+ else
+ {
+ VerticesBuffer[i].X = translatedPts[v].vx;
+ VerticesBuffer[i].Y = translatedPts[v].vy;
+ VerticesBuffer[i].Z = translatedPts[v].vz;
+ }
+ VerticesBuffer[i].R = 255;
+ VerticesBuffer[i].G = 255;
+ VerticesBuffer[i].B = 192;
+ }
+ RenderPolygon.NumberOfVertices=4;
+ }
+ {
+ int outcode = DecalWithinFrustrum(&fakeDecal);
+
+ if (outcode)
+ {
+ if (outcode!=2)
+ {
+ GouraudPolygon_ClipWithZ();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ GouraudPolygon_ClipWithNegativeX();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ GouraudPolygon_ClipWithPositiveY();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ GouraudPolygon_ClipWithNegativeY();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ GouraudPolygon_ClipWithPositiveX();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ D3D_ZBufferedGouraudPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
+ }
+ else D3D_ZBufferedGouraudPolygon_Output(&fakeHeader,VerticesBuffer);
+ }
+ }
+ }
+}
+#else
+ int polys[][4] =
+ {
+ {0,1,3,2},
+ {2,3,5,4},
+ {4,5,7,6},
+
+ {1,3,5,7},
+ {0,2,4,6},
+ {6,8,10,0},
+ {7,9,11,1},
+
+ {0,1,11,10},
+ {6,7,9,8},
+
+
+ };
+ int alphaValue[]={32,32,32,32, 28,28,28,28, 4,4,4,4, 128,128,128,128};
+// int alphaValue[]={16,16,16,16, 14,14,14,14, 2,2,2,2, 128,128,128,128};
+ VECTORCH shaftVertices[]=
+ {
+ {0, 0, 0},
+ {0, 0, 1956},
+ {-1492, 7969, 0},
+ {-1492, 7969, 1956},
+
+// {0, 0, 0},
+// {0, 0, 1139},
+// {-1338, 7113, 0},
+// {-1338, 7113, 1139},
+
+ {0, 8840, 0},
+ {0, 8840, 0},
+ {3138, 8850, 0},
+ {3138, 8850, 0},
+
+ {0, 14500, 0},
+ {0, 14500, 0},
+ {0, 14500, 0},
+ {0, 14500, 0},
+
+
+ };
+
+void RenderShaftOfLight(MODULE *modulePtr)
+{
+ /* translate shaft into view space */
+ #define NUM_OF_SHAFT_VERTICES 12
+ VECTORCH translatedPts[NUM_OF_SHAFT_VERTICES];
+
+ POLYHEADER fakeHeader;
+ DECAL fakeDecal;
+ int polyNumber;
+ VECTORCH lightDirection1 = {29309,29309,-2000};
+ VECTORCH lightDirection2 = {29309,29309,2000};
+
+// return;
+ {
+ int offset = GetSin((CloakingPhase/16)&4095);
+ if (offset<0) offset=-offset;
+ offset = MUL_FIXED(offset,offset);
+ offset = MUL_FIXED(offset,offset);
+ offset=MUL_FIXED(offset,4000);
+ lightDirection1.vz += offset;
+ lightDirection2.vz += offset;
+ }
+ Normalise(&lightDirection1);
+ Normalise(&lightDirection2);
+// textprint("light shaft active");
+ fakeDecal.ModuleIndex=modulePtr->m_index;
+ fakeHeader.PolyFlags = iflag_transparent;
+
+
+ FindIntersectionWithYPlane(&shaftVertices[2],&lightDirection1,&shaftVertices[4]);
+ FindIntersectionWithYPlane(&shaftVertices[3],&lightDirection2,&shaftVertices[5]);
+ FindZFromXYIntersection(&shaftVertices[2],&lightDirection1,&shaftVertices[6]);
+ FindZFromXYIntersection(&shaftVertices[3],&lightDirection2,&shaftVertices[7]);
+ FindIntersectionWithYPlane(&shaftVertices[0],&lightDirection1,&shaftVertices[10]);
+ FindIntersectionWithYPlane(&shaftVertices[1],&lightDirection2,&shaftVertices[11]);
+ FindIntersectionWithYPlane(&shaftVertices[6],&lightDirection1,&shaftVertices[8]);
+ FindIntersectionWithYPlane(&shaftVertices[7],&lightDirection2,&shaftVertices[9]);
+
+ {
+
+ int i = NUM_OF_SHAFT_VERTICES-1;
+ do
+ {
+ translatedPts[i] = shaftVertices[i];
+ translatedPts[i].vx+=11762;
+ translatedPts[i].vy+=-6919;
+ translatedPts[i].vz+=-26312;
+// translatedPts[i].vx+=10712;
+// translatedPts[i].vy+=-6480;
+// translatedPts[i].vz+=-25898;
+ TranslatePointIntoViewspace(&translatedPts[i]);
+ }
+ while(i--);
+ }
+
+
+ for(polyNumber=0; polyNumber<9; polyNumber++)
+ {
+ {
+ int i;
+ for (i=0; i<4; i++)
+ {
+ int v = polys[polyNumber][i];
+ VerticesBuffer[i].A = alphaValue[v];
+ VerticesBuffer[i].X = translatedPts[v].vx;
+ VerticesBuffer[i].Y = translatedPts[v].vy;
+ VerticesBuffer[i].Z = translatedPts[v].vz;
+ VerticesBuffer[i].R = 255;
+ VerticesBuffer[i].G = 255;
+ VerticesBuffer[i].B = 192;
+ }
+ RenderPolygon.NumberOfVertices=4;
+ }
+ {
+ int outcode = DecalWithinFrustrum(&fakeDecal);
+
+ if (outcode)
+ {
+ if (outcode!=2)
+ {
+ GouraudPolygon_ClipWithZ();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudPolygon_ClipWithNegativeX();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudPolygon_ClipWithPositiveY();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudPolygon_ClipWithNegativeY();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudPolygon_ClipWithPositiveX();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ D3D_ZBufferedGouraudPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
+ }
+ else D3D_ZBufferedGouraudPolygon_Output(&fakeHeader,VerticesBuffer);
+ }
+ }
+ }
+ RenderShaftOfLight2(modulePtr);
+}
+void RenderShaftOfLight2(MODULE *modulePtr)
+{
+ /* translate shaft into view space */
+ #define NUM_OF_SHAFT_VERTICES 12
+ VECTORCH translatedPts[NUM_OF_SHAFT_VERTICES];
+
+ POLYHEADER fakeHeader;
+ DECAL fakeDecal;
+ int polyNumber;
+ VECTORCH lightDirection1 = {29309+1000,29309,-3000};
+ VECTORCH lightDirection2 = {29309+1000,29309,3000};
+ VECTORCH lightDirection3 = {29309-1000,29309,-3000};
+ VECTORCH lightDirection4 = {29309-1000,29309,3000};
+ {
+ int offset = GetSin((CloakingPhase/16)&4095);
+ if (offset<0) offset=-offset;
+ offset = MUL_FIXED(offset,offset);
+ offset = MUL_FIXED(offset,offset);
+ offset=MUL_FIXED(offset,4000);
+ lightDirection1.vz += offset;
+ lightDirection2.vz += offset;
+ lightDirection3.vz += offset;
+ lightDirection4.vz += offset;
+ }
+ Normalise(&lightDirection1);
+ Normalise(&lightDirection2);
+ Normalise(&lightDirection3);
+ Normalise(&lightDirection4);
+
+ fakeDecal.ModuleIndex=modulePtr->m_index;
+ fakeHeader.PolyFlags = iflag_transparent;
+
+
+ FindIntersectionWithYPlane(&shaftVertices[2],&lightDirection1,&shaftVertices[4]);
+ FindIntersectionWithYPlane(&shaftVertices[3],&lightDirection2,&shaftVertices[5]);
+ FindZFromXYIntersection(&shaftVertices[2],&lightDirection3,&shaftVertices[6]);
+ FindZFromXYIntersection(&shaftVertices[3],&lightDirection4,&shaftVertices[7]);
+ FindIntersectionWithYPlane(&shaftVertices[0],&lightDirection1,&shaftVertices[10]);
+ FindIntersectionWithYPlane(&shaftVertices[1],&lightDirection2,&shaftVertices[11]);
+ FindIntersectionWithYPlane(&shaftVertices[6],&lightDirection3,&shaftVertices[8]);
+ FindIntersectionWithYPlane(&shaftVertices[7],&lightDirection4,&shaftVertices[9]);
+
+
+ {
+
+ int i = NUM_OF_SHAFT_VERTICES-1;
+ do
+ {
+ translatedPts[i] = shaftVertices[i];
+ translatedPts[i].vx+=11762;
+ translatedPts[i].vy+=-6919;
+ translatedPts[i].vz+=-26312;
+// translatedPts[i].vx+=10712;
+// translatedPts[i].vy+=-6480;
+// translatedPts[i].vz+=-25898;
+ TranslatePointIntoViewspace(&translatedPts[i]);
+ }
+ while(i--);
+ }
+
+
+ for(polyNumber=0; polyNumber<9; polyNumber++)
+ {
+ {
+ int i;
+ for (i=0; i<4; i++)
+ {
+ int v = polys[polyNumber][i];
+ VerticesBuffer[i].A = alphaValue[v]/2;
+ VerticesBuffer[i].X = translatedPts[v].vx;
+ VerticesBuffer[i].Y = translatedPts[v].vy;
+ VerticesBuffer[i].Z = translatedPts[v].vz;
+ VerticesBuffer[i].R = 255;
+ VerticesBuffer[i].G = 255;
+ VerticesBuffer[i].B = 192;
+ }
+ RenderPolygon.NumberOfVertices=4;
+ }
+ {
+ int outcode = DecalWithinFrustrum(&fakeDecal);
+
+ if (outcode)
+ {
+ if (outcode!=2)
+ {
+ GouraudPolygon_ClipWithZ();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudPolygon_ClipWithNegativeX();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudPolygon_ClipWithPositiveY();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudPolygon_ClipWithNegativeY();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudPolygon_ClipWithPositiveX();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ D3D_ZBufferedGouraudPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
+ }
+ else D3D_ZBufferedGouraudPolygon_Output(&fakeHeader,VerticesBuffer);
+ }
+ }
+ }
+}
+
+void FindIntersectionWithYPlane(VECTORCH *startPtr, VECTORCH *directionPtr, VECTORCH *intersectionPtr)
+{
+ int lambda = DIV_FIXED(intersectionPtr->vy - startPtr->vy,directionPtr->vy);
+
+ intersectionPtr->vx = startPtr->vx + MUL_FIXED(directionPtr->vx,lambda);
+ intersectionPtr->vz = startPtr->vz + MUL_FIXED(directionPtr->vz,lambda);
+// textprint("%d %d %d\n",intersectionPtr->vx,intersectionPtr->vy,intersectionPtr->vz);
+}
+void FindZFromXYIntersection(VECTORCH *startPtr, VECTORCH *directionPtr, VECTORCH *intersectionPtr)
+{
+ float a = intersectionPtr->vx - startPtr->vx;
+
+ a/=directionPtr->vx;
+
+ intersectionPtr->vz = startPtr->vz + (directionPtr->vz*a);
+// textprint("%d %d %d\n",intersectionPtr->vx,intersectionPtr->vy,intersectionPtr->vz);
+}
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+void ClearTranslucentPolyList(void)
+{
+ CurrentNumberOfTranslucentPolygons=0;
+}
+
+void AddToTranslucentPolyList(POLYHEADER *inputPolyPtr,RENDERVERTEX *renderVerticesPtr)
+{
+ /* copy the data to the list for processing later */
+ int i = RenderPolygon.NumberOfVertices;
+ int maxZ = 0;
+ RENDERVERTEX *vertexPtr = TranslucentPolygons[CurrentNumberOfTranslucentPolygons].Vertices;
+
+ TranslucentPolygons[CurrentNumberOfTranslucentPolygons].NumberOfVertices = i;
+
+ do
+ {
+ if (maxZ<renderVerticesPtr->Z)
+ maxZ = renderVerticesPtr->Z;
+ *vertexPtr++ = *renderVerticesPtr++;
+ }
+ while(--i);
+ TranslucentPolygons[CurrentNumberOfTranslucentPolygons].MaxZ = maxZ;
+ TranslucentPolygonHeaders[CurrentNumberOfTranslucentPolygons] = *inputPolyPtr;
+
+ /* increment counter */
+ CurrentNumberOfTranslucentPolygons++;
+ LOCALASSERT(CurrentNumberOfTranslucentPolygons<MAX_NO_OF_TRANSLUCENT_POLYGONS);
+}
+
+void OutputTranslucentPolyList(void)
+{
+ int i = CurrentNumberOfTranslucentPolygons;
+ while(i--)
+ {
+ int k = CurrentNumberOfTranslucentPolygons;
+ int maxFound = 0;
+ while(k--)
+ {
+ if (TranslucentPolygons[k].MaxZ>TranslucentPolygons[maxFound].MaxZ)
+ {
+ maxFound = k;
+ }
+ }
+
+ RenderAllParticlesFurtherAwayThan(TranslucentPolygons[maxFound].MaxZ);
+
+ RenderPolygon.NumberOfVertices = TranslucentPolygons[maxFound].NumberOfVertices;
+ RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL;
+ D3D_ZBufferedGouraudTexturedPolygon_Output(&TranslucentPolygonHeaders[maxFound],TranslucentPolygons[maxFound].Vertices);
+ TranslucentPolygons[maxFound].MaxZ=0;
+ }
+
+ RenderAllParticlesFurtherAwayThan(-0x7fffffff);
+
+}
+
+
+
+
+#if 0
+int CuboidPolyVertexList[][4] =
+{
+ {0,1,2,3}, //+ve x
+ {0,3,7,4}, //+ve y
+ {6,7,3,2}, //+ve z
+
+ {6,7,4,5}, //-ve x
+ {6,5,1,2}, //-ve y
+ {0,1,5,4}, //-ve z
+};
+EULER CubeOrient = {0,0,0};
+void CubeOMatic(void)
+{
+ #define CUBESCALE 128
+ VECTORCH vertices[8]=
+ {
+ {+CUBESCALE,+CUBESCALE,-CUBESCALE},
+ {+CUBESCALE,-CUBESCALE,-CUBESCALE},
+ {+CUBESCALE,-CUBESCALE,+CUBESCALE},
+ {+CUBESCALE,+CUBESCALE,+CUBESCALE},
+ {-CUBESCALE,+CUBESCALE,-CUBESCALE},
+ {-CUBESCALE,-CUBESCALE,-CUBESCALE},
+ {-CUBESCALE,-CUBESCALE,+CUBESCALE},
+ {-CUBESCALE,+CUBESCALE,+CUBESCALE},
+ };
+ VECTORCH translatedPts[8];
+
+ POLYHEADER fakeHeader;
+ int polyNumber;
+ MATRIXCH matrix;
+ CreateEulerMatrix(&CubeOrient,&matrix);
+ TransposeMatrixCH(&matrix);
+
+ CubeOrient.EulerX += MUL_FIXED(NormalFrameTime,128*4);
+ CubeOrient.EulerX &=4095;
+ CubeOrient.EulerY += MUL_FIXED(NormalFrameTime,256*4);
+ CubeOrient.EulerY &=4095;
+ CubeOrient.EulerZ += MUL_FIXED(NormalFrameTime,128*4);
+ CubeOrient.EulerZ &=4095;
+
+ fakeHeader.PolyFlags = iflag_transparent;
+
+ {
+
+ int i = 7;
+ do
+ {
+ translatedPts[i] = vertices[i];
+ RotateVector(&translatedPts[i],&matrix);
+ translatedPts[i].vy = MUL_FIXED(translatedPts[i].vy,87381);
+ }
+ while(i--);
+ }
+
+
+ for(polyNumber=0; polyNumber<6; polyNumber++)
+ {
+ {
+ int i;
+ for (i=0; i<4; i++)
+ {
+ int v = CuboidPolyVertexList[polyNumber][i];
+ VerticesBuffer[i].A = 128;
+ VerticesBuffer[i].X = translatedPts[v].vx-400;
+ VerticesBuffer[i].Y = translatedPts[v].vy+300;
+ VerticesBuffer[i].Z = translatedPts[v].vz+900;
+ VerticesBuffer[i].Y = MUL_FIXED(VerticesBuffer[i].Y,87381);
+
+ {
+ int brightness = -(translatedPts[v].vz*2);
+
+ if (brightness<0) brightness=0;
+ if (brightness>255) brightness=255;
+ VerticesBuffer[i].R = brightness;
+ }
+ VerticesBuffer[i].G = 0;
+ VerticesBuffer[i].B = 0;
+ }
+ RenderPolygon.NumberOfVertices=4;
+ }
+ {
+ int outcode = QuadWithinFrustrum();
+
+ if (outcode)
+ {
+ if (outcode!=2)
+ {
+ GouraudPolygon_ClipWithZ();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudPolygon_ClipWithNegativeX();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudPolygon_ClipWithPositiveY();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudPolygon_ClipWithNegativeY();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudPolygon_ClipWithPositiveX();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ D3D_ZBufferedGouraudPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
+ }
+ else D3D_ZBufferedGouraudPolygon_Output(&fakeHeader,VerticesBuffer);
+ }
+ }
+ }
+}
+#endif
+int CuboidPolyVertexList[][4] =
+{
+ {0,3,7,4}, //+ve y
+#if 0
+ {0,1,2,3}, //+ve x
+ {0,1,5,4}, //-ve z
+
+ {6,7,4,5}, //-ve x
+ {6,7,3,2}, //+ve z
+#else
+ {6,7,3,2}, //+ve z
+ {6,7,4,5}, //-ve x
+
+ {0,1,5,4}, //-ve z
+ {0,1,2,3}, //+ve x
+#endif
+};
+EULER CubeOrient = {0,0,0};
+int CuboidPolyVertexU[][4] =
+{
+ {1,1,1,1},
+
+ {127,127,0,0},
+ {128,128,255,255},
+
+ {127,127,0,0},
+ {128,128,255,255},
+};
+int CuboidPolyVertexV[][4] =
+{
+ {1,1,1,1},
+
+ {127,0,0,127},
+ {127,0,0,127},
+ {128,255,255,128},
+ {128,255,255,128},
+};
+
+#include "chnktexi.h"
+
+void CubeSky(void)
+{
+ #define CUBESCALE 1024
+ VECTORCH vertices[8]=
+ {
+ #if 0
+ {+CUBESCALE,-CUBESCALE,-CUBESCALE},
+ {+CUBESCALE,CUBESCALE,-CUBESCALE},
+ {+CUBESCALE,CUBESCALE,+CUBESCALE},
+ {+CUBESCALE,-CUBESCALE,+CUBESCALE},
+ {-CUBESCALE,-CUBESCALE,-CUBESCALE},
+ {-CUBESCALE,CUBESCALE,-CUBESCALE},
+ {-CUBESCALE,CUBESCALE,+CUBESCALE},
+ {-CUBESCALE,-CUBESCALE,+CUBESCALE},
+ #else
+ {+CUBESCALE,-CUBESCALE*2,-CUBESCALE},
+ {+CUBESCALE,0,-CUBESCALE},
+ {+CUBESCALE,0,+CUBESCALE},
+ {+CUBESCALE,-CUBESCALE*2,+CUBESCALE},
+ {-CUBESCALE,-CUBESCALE*2,-CUBESCALE},
+ {-CUBESCALE,0,-CUBESCALE},
+ {-CUBESCALE,0,+CUBESCALE},
+ {-CUBESCALE,-CUBESCALE*2,+CUBESCALE},
+ #endif
+ };
+ VECTORCH translatedPts[8];
+
+ POLYHEADER fakeHeader;
+ int polyNumber;
+
+ #if 1
+ {
+ extern int BackdropImage;
+ fakeHeader.PolyFlags = 0;
+ fakeHeader.PolyColour =BackdropImage;
+ }
+
+ {
+
+ int i = 7;
+ do
+ {
+ translatedPts[i] = vertices[i];
+ RotateVector(&translatedPts[i],&(Global_VDB_Ptr->VDB_Mat));
+ translatedPts[i].vy = MUL_FIXED(translatedPts[i].vy,87381);
+ }
+ while(i--);
+ }
+ #endif
+
+ for(polyNumber=0; polyNumber<5; polyNumber++)
+ {
+ {
+ int i;
+ for (i=0; i<4; i++)
+ {
+ int v = CuboidPolyVertexList[polyNumber][i];
+ VerticesBuffer[i].A = 0;
+ VerticesBuffer[i].X = translatedPts[v].vx;
+ VerticesBuffer[i].Y = translatedPts[v].vy;
+ VerticesBuffer[i].Z = translatedPts[v].vz;
+ VerticesBuffer[i].U = CuboidPolyVertexU[polyNumber][i]<<16;
+ VerticesBuffer[i].V = CuboidPolyVertexV[polyNumber][i]<<16;
+
+
+ VerticesBuffer[i].R = 127;
+ VerticesBuffer[i].G = 127;
+ VerticesBuffer[i].B = 127;
+ }
+ RenderPolygon.NumberOfVertices=4;
+ }
+ {
+ int outcode = QuadWithinFrustrum();
+
+ if (outcode)
+ {
+ if (outcode!=2)
+ {
+ GouraudTexturedPolygon_ClipWithZ();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudTexturedPolygon_ClipWithNegativeX();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudTexturedPolygon_ClipWithPositiveY();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudTexturedPolygon_ClipWithNegativeY();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudTexturedPolygon_ClipWithPositiveX();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ D3D_BackdropPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
+ }
+ else D3D_BackdropPolygon_Output(&fakeHeader,VerticesBuffer);
+ }
+ }
+ }
+}
+
+
+void RenderMirrorSurface(void)
+{
+ VECTORCH translatedPts[4] =
+ {
+ {-5596,-932,-1872},
+ {-5596,-932,-702},
+ {-5596,1212,-702},
+ {-5596,1212,-1872},
+
+ };
+ int mirrorUV[]=
+ { 0,0, 127<<16,0, 127<<16,127<<16, 0,127<<16};
+ POLYHEADER fakeHeader;
+
+
+ {
+ extern int CloudyImageNumber;
+ fakeHeader.PolyFlags = iflag_transparent;
+ fakeHeader.PolyColour = CloudyImageNumber;
+ }
+
+ {
+ int i;
+ for (i=0; i<4; i++)
+ {
+ VerticesBuffer[i].A = 128;
+
+ TranslatePointIntoViewspace(&translatedPts[i]);
+ VerticesBuffer[i].X = translatedPts[i].vx;
+ VerticesBuffer[i].Y = translatedPts[i].vy;
+ VerticesBuffer[i].Z = translatedPts[i].vz;
+ VerticesBuffer[i].U = mirrorUV[i*2];
+ VerticesBuffer[i].V = mirrorUV[i*2+1];
+
+
+ VerticesBuffer[i].R = 255;
+ VerticesBuffer[i].G = 255;
+ VerticesBuffer[i].B = 255;
+ VerticesBuffer[i].SpecularR = 0;
+ VerticesBuffer[i].SpecularG = 0;
+ VerticesBuffer[i].SpecularB = 0;
+
+ }
+ RenderPolygon.NumberOfVertices=4;
+ RenderPolygon.TranslucencyMode = TRANSLUCENCY_COLOUR;
+ }
+
+ GouraudTexturedPolygon_ClipWithZ();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ GouraudTexturedPolygon_ClipWithNegativeX();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ GouraudTexturedPolygon_ClipWithPositiveY();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ GouraudTexturedPolygon_ClipWithNegativeY();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ GouraudTexturedPolygon_ClipWithPositiveX();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ D3D_ZBufferedGouraudTexturedPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
+}
+void RenderMirrorSurface2(void)
+{
+ VECTORCH translatedPts[4] =
+ {
+ {-5596,-592,562},
+ {-5596,-592,1344},
+ {-5596,140,1344},
+ {-5596,140,562},
+
+ };
+ int mirrorUV[]=
+ { 0,0, 127<<16,0, 127<<16,127<<16, 0,127<<16};
+ POLYHEADER fakeHeader;
+
+
+ {
+ extern int CloudyImageNumber;
+ fakeHeader.PolyFlags = iflag_transparent;
+ fakeHeader.PolyColour = CloudyImageNumber;
+ }
+
+ {
+ int i;
+ for (i=0; i<4; i++)
+ {
+ VerticesBuffer[i].A = 128;
+
+ TranslatePointIntoViewspace(&translatedPts[i]);
+ VerticesBuffer[i].X = translatedPts[i].vx;
+ VerticesBuffer[i].Y = translatedPts[i].vy;
+ VerticesBuffer[i].Z = translatedPts[i].vz;
+ VerticesBuffer[i].U = mirrorUV[i*2];
+ VerticesBuffer[i].V = mirrorUV[i*2+1];
+
+
+ VerticesBuffer[i].R = 255;
+ VerticesBuffer[i].G = 255;
+ VerticesBuffer[i].B = 255;
+ VerticesBuffer[i].SpecularR = 0;
+ VerticesBuffer[i].SpecularG = 0;
+ VerticesBuffer[i].SpecularB = 0;
+
+ }
+ RenderPolygon.NumberOfVertices=4;
+ RenderPolygon.TranslucencyMode = TRANSLUCENCY_COLOUR;
+ }
+
+ GouraudTexturedPolygon_ClipWithZ();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ GouraudTexturedPolygon_ClipWithNegativeX();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ GouraudTexturedPolygon_ClipWithPositiveY();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ GouraudTexturedPolygon_ClipWithNegativeY();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ GouraudTexturedPolygon_ClipWithPositiveX();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ D3D_ZBufferedGouraudTexturedPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
+}
+void RenderSmokeTest(void)
+{
+ int mirrorUV[]=
+ {
+ 64<<16, 0,
+ 64<<16, 31<<16,
+ 95<<16, 31<<16,
+ 95<<16, 0
+ };
+ POLYHEADER fakeHeader;
+ int a = GetSin(CloakingPhase&4095);
+ int image;
+
+ a = MUL_FIXED(MUL_FIXED(a,a),255);
+ {
+ extern int SpecialFXImageNumber;
+ fakeHeader.PolyFlags = iflag_transparent;
+ fakeHeader.PolyColour = SpecialFXImageNumber;
+ }
+
+ for (image = 0; image<=1; image++)
+ {
+ {
+ VECTORCH translatedPts[4] =
+ {
+ {45300,0+-1000, 26000+-1000},
+ {45300,0+-1000, 26000+ 1000},
+ {45300,0+ 1000, 26000+ 1000},
+ {45300,0+ 1000, 26000+-1000},
+
+ };
+ extern int CurrentLightAtPlayer;
+ int i;
+
+ if (image) a = 255-a;
+ for (i=0; i<4; i++)
+ {
+ VerticesBuffer[i].A = a/2;
+
+ TranslatePointIntoViewspace(&translatedPts[i]);
+ VerticesBuffer[i].X = translatedPts[i].vx;
+ VerticesBuffer[i].Y = translatedPts[i].vy;
+ VerticesBuffer[i].Z = translatedPts[i].vz;
+ VerticesBuffer[i].U = mirrorUV[i*2];
+ VerticesBuffer[i].V = mirrorUV[i*2+1]+image*(32<<16);
+
+
+ VerticesBuffer[i].R = 255;
+ VerticesBuffer[i].G = 255;
+ VerticesBuffer[i].B = 255;
+ VerticesBuffer[i].SpecularR = 0;
+ VerticesBuffer[i].SpecularG = 0;
+ VerticesBuffer[i].SpecularB = 0;
+
+ }
+ RenderPolygon.NumberOfVertices=4;
+ RenderPolygon.TranslucencyMode = TRANSLUCENCY_GLOWING;
+ }
+
+ GouraudTexturedPolygon_ClipWithZ();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ GouraudTexturedPolygon_ClipWithNegativeX();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ GouraudTexturedPolygon_ClipWithPositiveY();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ GouraudTexturedPolygon_ClipWithNegativeY();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ GouraudTexturedPolygon_ClipWithPositiveX();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ D3D_ZBufferedGouraudTexturedPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
+ }
+}
+#if 1
+#define OCTAVES 3
+int u[OCTAVES];
+int v[OCTAVES];
+int du[OCTAVES];
+int dv[OCTAVES];
+int setup=0;
+
+int SkyColour_R=200;
+int SkyColour_G=200;
+int SkyColour_B=200;
+void RenderSky(void)
+{
+ POLYHEADER fakeHeader;
+ int x,z,o;
+ if(!setup)
+ {
+ int i;
+ setup=1;
+ for(i=0;i<OCTAVES;i++)
+ {
+ u[i] = (FastRandom()&65535)*128;
+ v[i] = (FastRandom()&65535)*128;
+ du[i] = ( ((FastRandom()&65535)-32768)*(i+1) )*8;
+ dv[i] = ( ((FastRandom()&65535)-32768)*(i+1) )*8;
+ }
+ }
+ {
+ extern int CloudyImageNumber;
+ fakeHeader.PolyFlags = iflag_transparent;
+ fakeHeader.PolyColour = CloudyImageNumber;
+ RenderPolygon.TranslucencyMode = TRANSLUCENCY_GLOWING;
+ }
+ for (o=0; o<OCTAVES; o++)
+ {
+ u[o]+=MUL_FIXED(du[o],NormalFrameTime);
+ v[o]+=MUL_FIXED(dv[o],NormalFrameTime);
+ }
+ for(x=-10; x<=10; x++)
+ {
+ for(z=-10; z<=10; z++)
+ {
+ int t = 255;
+ int size = 65536*128;
+ for (o=0; o<OCTAVES; o++)
+ {
+ {
+ VECTORCH translatedPts[4] =
+ {
+ {-1024,-1000,-1024},
+ {-1024,-1000, 1024},
+ { 1024,-1000, 1024},
+ { 1024,-1000,-1024},
+
+ };
+ int i;
+ for (i=0; i<4; i++)
+ {
+ VerticesBuffer[i].A = t;
+ translatedPts[i].vx += 2048*x;//+(Global_VDB_Ptr->VDB_World.vx*7)/8;
+ translatedPts[i].vz += 2048*z;//+(Global_VDB_Ptr->VDB_World.vz*7)/8;
+// RotateVector(&translatedPts[i],&(Global_VDB_Ptr->VDB_Mat));
+// translatedPts[i].vy = MUL_FIXED(translatedPts[i].vy,87381);
+ translatedPts[i].vx += Global_VDB_Ptr->VDB_World.vx;
+ translatedPts[i].vy += Global_VDB_Ptr->VDB_World.vy;
+ translatedPts[i].vz += Global_VDB_Ptr->VDB_World.vz;
+ TranslatePointIntoViewspace(&translatedPts[i]);
+ VerticesBuffer[i].X = translatedPts[i].vx;
+ VerticesBuffer[i].Y = translatedPts[i].vy;
+ VerticesBuffer[i].Z = translatedPts[i].vz;
+
+ switch (CurrentVisionMode)
+ {
+ default:
+ case VISION_MODE_NORMAL:
+ {
+ VerticesBuffer[i].R = SkyColour_R;
+ VerticesBuffer[i].G = SkyColour_G;
+ VerticesBuffer[i].B = SkyColour_B;
+ break;
+ }
+ case VISION_MODE_IMAGEINTENSIFIER:
+ {
+ VerticesBuffer[i].R = 0;
+ VerticesBuffer[i].G = 255;
+ VerticesBuffer[i].B = 0;
+ break;
+ }
+ case VISION_MODE_PRED_THERMAL:
+ case VISION_MODE_PRED_SEEALIENS:
+ case VISION_MODE_PRED_SEEPREDTECH:
+ {
+ VerticesBuffer[i].R = 0;
+ VerticesBuffer[i].G = 0;
+ VerticesBuffer[i].B = 255;
+ break;
+ }
+ }
+
+ }
+ VerticesBuffer[0].U = (u[o]+size*x);
+ VerticesBuffer[0].V = (v[o]+size*z);
+ VerticesBuffer[1].U = (u[o]+size*x);
+ VerticesBuffer[1].V = (v[o]+size*(z+1));
+ VerticesBuffer[2].U = (u[o]+size*(x+1));
+ VerticesBuffer[2].V = (v[o]+size*(z+1));
+ VerticesBuffer[3].U = (u[o]+size*(x+1));
+ VerticesBuffer[3].V = (v[o]+size*z);
+
+
+ RenderPolygon.NumberOfVertices=4;
+ }
+
+ GouraudTexturedPolygon_ClipWithZ();
+ if(RenderPolygon.NumberOfVertices>=3)
+ {
+ GouraudTexturedPolygon_ClipWithNegativeX();
+ if(RenderPolygon.NumberOfVertices>=3)
+ {
+ GouraudTexturedPolygon_ClipWithPositiveY();
+ if(RenderPolygon.NumberOfVertices>=3)
+ {
+ GouraudTexturedPolygon_ClipWithNegativeY();
+ if(RenderPolygon.NumberOfVertices>=3)
+ {
+ GouraudTexturedPolygon_ClipWithPositiveX();
+ if(RenderPolygon.NumberOfVertices>=3)
+ {
+ D3D_SkyPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
+ }
+ }
+ }
+ }
+ }
+ t/=2;
+ size*=2;
+ }
+ }
+ }
+}
+#endif
+void RenderWaterFall(int xOrigin, int yOrigin, int zOrigin)
+{
+ int i,z;
+ VECTORCH v[4];
+
+ {
+ int waterfallX[9];
+ int waterfallY[9];
+ int waterfallZ[9];
+ int waterfallZScale[9];
+ for (i=0; i<9; i++)
+ {
+
+ int u = (i*65536)/8;
+
+ int b = MUL_FIXED(2*u,(65536-u));
+ int c = MUL_FIXED(u,u);
+ int y3 = (4742-yOrigin);
+ int x3 = 2000;
+ int y2 = 2000;
+ int x2 = 1500;
+
+ waterfallX[i] = MUL_FIXED(b,x2)+MUL_FIXED(c,x3);
+ waterfallY[i] = yOrigin+MUL_FIXED(b,y2)+MUL_FIXED(c,y3);
+ waterfallZ[i] = zOrigin+MUL_FIXED((66572-zOrigin),u);
+ waterfallZScale[i] = ONE_FIXED+b/2-c;
+ if (i!=8)
+ {
+ waterfallZScale[i]+=(FastRandom()&8191);
+ waterfallY[i]-=(FastRandom()&127);
+ }
+
+ }
+ for (z=0; z<8; z++)
+ for (i=0; i<8; i++)
+ {
+ v[0].vx = xOrigin+MUL_FIXED(waterfallX[i],waterfallZScale[z]);
+ v[1].vx = xOrigin+MUL_FIXED(waterfallX[i],waterfallZScale[z+1]);
+ v[2].vx = xOrigin+MUL_FIXED(waterfallX[i+1],waterfallZScale[z+1]);
+ v[3].vx = xOrigin+MUL_FIXED(waterfallX[i+1],waterfallZScale[z]);
+ v[0].vy = waterfallY[i];
+ v[1].vy = waterfallY[i];
+ v[2].vy = waterfallY[i+1];
+ v[3].vy = waterfallY[i+1];
+
+
+ v[0].vz = waterfallZ[z];
+ v[1].vz = waterfallZ[z+1];
+ v[2].vz = v[1].vz;
+ v[3].vz = v[0].vz;
+
+ DrawWaterFallPoly(v);
+ }
+ for (z=0; z<3; z++)
+ {
+ v[0].vx = xOrigin+MUL_FIXED(waterfallX[8],waterfallZScale[z+1]);
+ v[1].vx = xOrigin+MUL_FIXED(waterfallX[8],waterfallZScale[z]);
+ v[2].vx = 179450;
+ v[3].vx = 179450;
+
+ v[0].vy = 4742;
+ v[1].vy = 4742;
+ v[2].vy = 4742;
+ v[3].vy = 4742;
+
+ v[0].vz = waterfallZ[z];
+ v[1].vz = waterfallZ[z+1];
+ v[2].vz = v[1].vz;
+ v[3].vz = v[0].vz;
+
+ DrawWaterFallPoly(v);
+ }
+
+ for (z=0; z<8; z++)
+ for (i=0; i<16; i++)
+ {
+ int xOffset,xOffset2;
+ if (z<3) xOffset = 179450;
+ else xOffset = xOrigin+MUL_FIXED(waterfallX[8],waterfallZScale[z]);
+ if (z<2) xOffset2 = 179450;
+ else xOffset2 = xOrigin+MUL_FIXED(waterfallX[8],waterfallZScale[z+1]);
+
+ v[0].vx = xOffset;
+ v[1].vx = xOffset2;
+ v[2].vx = xOffset2;
+ v[3].vx = xOffset;
+
+ v[0].vy = 4742+i*4096;
+ v[1].vy = 4742+i*4096;
+ v[2].vy = 4742+(i+1)*4096;
+ v[3].vy = 4742+(i+1)*4096;
+
+
+ v[0].vz = waterfallZ[z];
+ v[1].vz = waterfallZ[z+1];
+ v[2].vz = v[1].vz;
+ v[3].vz = v[0].vz;
+
+ DrawWaterFallPoly(v);
+ }
+
+ }
+}
+
+void DrawWaterFallPoly(VECTORCH *v)
+{
+ POLYHEADER fakeHeader;
+
+ {
+ extern int CloudyImageNumber;
+ fakeHeader.PolyFlags = iflag_transparent;
+ fakeHeader.PolyColour = CloudyImageNumber;
+ RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL;
+ }
+ {
+ static wv=0;
+ unsigned int a;
+ for (a=0; a<4; a++)
+ {
+ VerticesBuffer[a].A = 128;
+ VerticesBuffer[a].U = (v[a].vz)<<11;
+ VerticesBuffer[a].V = (v[a].vy<<10)-wv;
+
+ TranslatePointIntoViewspace(&v[a]);
+ VerticesBuffer[a].X = v[a].vx;
+ VerticesBuffer[a].Y = v[a].vy;
+ VerticesBuffer[a].Z = v[a].vz;
+ VerticesBuffer[a].R = 200;
+ VerticesBuffer[a].G = 200;
+ VerticesBuffer[a].B = 255;
+ VerticesBuffer[a].SpecularR = 0;
+ VerticesBuffer[a].SpecularG = 0;
+ VerticesBuffer[a].SpecularB = 0;
+
+
+ }
+ wv+=NormalFrameTime*2;
+ RenderPolygon.NumberOfVertices=4;
+ }
+
+ GouraudTexturedPolygon_ClipWithZ();
+ if(RenderPolygon.NumberOfVertices>=3)
+ {
+ GouraudTexturedPolygon_ClipWithNegativeX();
+ if(RenderPolygon.NumberOfVertices>=3)
+ {
+ GouraudTexturedPolygon_ClipWithPositiveY();
+ if(RenderPolygon.NumberOfVertices>=3)
+ {
+ GouraudTexturedPolygon_ClipWithNegativeY();
+ if(RenderPolygon.NumberOfVertices>=3)
+ {
+ GouraudTexturedPolygon_ClipWithPositiveX();
+ if(RenderPolygon.NumberOfVertices>=3)
+ {
+ D3D_ZBufferedGouraudTexturedPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
+ }
+ }
+ }
+ }
+ }
+}
+void RenderPredatorTargetingSegment(int theta, int scale, int drawInRed)
+{
+ VECTOR2D offset[4];
+ POLYHEADER fakeHeader;
+ int centreX,centreY;
+ int z = ONE_FIXED-scale;
+ z = MUL_FIXED(MUL_FIXED(z,z),2048);
+ {
+ extern int SmartTargetSightX, SmartTargetSightY;
+ extern SCREENDESCRIPTORBLOCK ScreenDescriptorBlock;
+ centreY = MUL_FIXED( (SmartTargetSightY-(ScreenDescriptorBlock.SDB_Height<<15)) /Global_VDB_Ptr->VDB_ProjY,z);
+ if (MIRROR_CHEATMODE)
+ {
+ centreX = MUL_FIXED( ( - (SmartTargetSightX-(ScreenDescriptorBlock.SDB_Width<<15))) /Global_VDB_Ptr->VDB_ProjX,z);
+ }
+ else
+ {
+ centreX = MUL_FIXED( (SmartTargetSightX-(ScreenDescriptorBlock.SDB_Width<<15)) /Global_VDB_Ptr->VDB_ProjX,z);
+ }
+ }
+ z = (float)z*CameraZoomScale;
+
+ {
+ int a = 160;
+ int b = 40;
+
+ /* tan(30) = 1/sqrt(3), & 65536/(sqrt(3)) = 37837 */
+
+ int y = MUL_FIXED(37837,a+20);
+
+ offset[0].vx = -a+MUL_FIXED(113512,b);
+ offset[0].vy = y-b;
+
+ offset[1].vx = -offset[0].vx;
+ offset[1].vy = y-b;
+
+ offset[2].vx = a;
+ offset[2].vy = y;
+
+ offset[3].vx = -a;
+ offset[3].vy = y;
+
+ if (theta)
+ {
+ extern void RotateVertex(VECTOR2D *vertexPtr, int theta);
+
+ RotateVertex(&offset[0],theta);
+ RotateVertex(&offset[1],theta);
+ RotateVertex(&offset[2],theta);
+ RotateVertex(&offset[3],theta);
+ }
+
+ if (MIRROR_CHEATMODE)
+ {
+ offset[0].vx = -offset[0].vx;
+ offset[1].vx = -offset[1].vx;
+ offset[2].vx = -offset[2].vx;
+ offset[3].vx = -offset[3].vx;
+ }
+ VerticesBuffer[0].X = offset[0].vx+centreX;
+ VerticesBuffer[0].Y = MUL_FIXED(offset[0].vy,87381)+centreY;
+
+ VerticesBuffer[1].X = offset[1].vx+centreX;
+ VerticesBuffer[1].Y = MUL_FIXED(offset[1].vy,87381)+centreY;
+
+ VerticesBuffer[2].X = offset[2].vx+centreX;
+ VerticesBuffer[2].Y = MUL_FIXED(offset[2].vy,87381)+centreY;
+
+ VerticesBuffer[3].X = offset[3].vx+centreX;
+ VerticesBuffer[3].Y = MUL_FIXED(offset[3].vy,87381)+centreY;
+ }
+ fakeHeader.PolyFlags = iflag_transparent;
+ RenderPolygon.TranslucencyMode = TRANSLUCENCY_GLOWING;
+
+
+ {
+ int i;
+ for (i=0; i<4; i++)
+ {
+ VerticesBuffer[i].A = 128;
+
+ VerticesBuffer[i].Z = z;
+
+ VerticesBuffer[i].R = 255;
+
+ if (drawInRed)
+ {
+ VerticesBuffer[i].G = 0;
+ VerticesBuffer[i].B = 0;
+ }
+ else
+ {
+ VerticesBuffer[i].G = 255;
+ VerticesBuffer[i].B = 255;
+ }
+
+ }
+ RenderPolygon.NumberOfVertices=4;
+ }
+
+ GouraudPolygon_ClipWithZ();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ GouraudPolygon_ClipWithNegativeX();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ GouraudPolygon_ClipWithPositiveY();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ GouraudPolygon_ClipWithNegativeY();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ GouraudPolygon_ClipWithPositiveX();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ D3D_ZBufferedGouraudPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
+
+ if (drawInRed)
+ {
+ VerticesBuffer[0].X = MUL_FIXED(offset[3].vx,scale*8)+centreX;
+ VerticesBuffer[0].Y = MUL_FIXED(MUL_FIXED(offset[3].vy,scale*8),87381)+centreY;
+
+ VerticesBuffer[1].X = MUL_FIXED(offset[2].vx,scale*8)+centreX;
+ VerticesBuffer[1].Y = MUL_FIXED(MUL_FIXED(offset[2].vy,scale*8),87381)+centreY;
+
+ VerticesBuffer[2].X = offset[2].vx+centreX;
+ VerticesBuffer[2].Y = MUL_FIXED(offset[2].vy,87381)+centreY;
+
+ VerticesBuffer[3].X = offset[3].vx+centreX;
+ VerticesBuffer[3].Y = MUL_FIXED(offset[3].vy,87381)+centreY;
+ {
+ int i;
+ for (i=0; i<2; i++)
+ {
+ VerticesBuffer[i].A = 0;
+ VerticesBuffer[i].Z = z;
+ VerticesBuffer[i].R = 255;
+ VerticesBuffer[i].G = 0;
+ VerticesBuffer[i].B = 0;
+ }
+ for (i=2; i<4; i++)
+ {
+ VerticesBuffer[i].A = 128;
+ VerticesBuffer[i].Z = z;
+ VerticesBuffer[i].R = 255;
+ VerticesBuffer[i].G = 0;
+ VerticesBuffer[i].B = 0;
+ }
+ RenderPolygon.NumberOfVertices=4;
+ }
+
+ GouraudPolygon_ClipWithZ();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ GouraudPolygon_ClipWithNegativeX();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ GouraudPolygon_ClipWithPositiveY();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ GouraudPolygon_ClipWithNegativeY();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ GouraudPolygon_ClipWithPositiveX();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ D3D_ZBufferedGouraudPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
+ }
+}
+void RenderPredatorPlasmaCasterCharge(int value, VECTORCH *worldOffsetPtr, MATRIXCH *orientationPtr)
+{
+ POLYHEADER fakeHeader;
+ VECTORCH translatedPts[4];
+ int halfWidth = 100;
+ int halfHeight = 4;
+ int z = -1;
+ translatedPts[0].vx = -halfWidth;
+ translatedPts[0].vy = z;
+ translatedPts[0].vz = -halfHeight-4;
+
+ translatedPts[1].vx = -halfWidth+MUL_FIXED(value,2*halfWidth-10);
+ translatedPts[1].vy = z;
+ translatedPts[1].vz = -halfHeight-4;
+
+ translatedPts[2].vx = -halfWidth+MUL_FIXED(value,2*halfWidth-10);
+ translatedPts[2].vy = z;
+ translatedPts[2].vz = halfHeight-4;
+
+ translatedPts[3].vx = -halfWidth;
+ translatedPts[3].vy = z;
+ translatedPts[3].vz = halfHeight-4;
+
+ fakeHeader.PolyFlags = iflag_transparent;
+ RenderPolygon.TranslucencyMode = TRANSLUCENCY_GLOWING;
+
+
+ {
+ int i;
+ for (i=0; i<4; i++)
+ {
+ VerticesBuffer[i].A = 255;
+
+ RotateVector(&(translatedPts[i]),orientationPtr);
+ translatedPts[i].vx += worldOffsetPtr->vx;
+ translatedPts[i].vy += worldOffsetPtr->vy;
+ translatedPts[i].vz += worldOffsetPtr->vz;
+ TranslatePointIntoViewspace(&translatedPts[i]);
+
+ VerticesBuffer[i].X = translatedPts[i].vx;
+ VerticesBuffer[i].Y = translatedPts[i].vy;
+ VerticesBuffer[i].Z = translatedPts[i].vz;
+
+ VerticesBuffer[i].R = 32;
+ VerticesBuffer[i].G = 0;
+ VerticesBuffer[i].B = 0;
+ }
+ RenderPolygon.NumberOfVertices=4;
+ }
+ {
+ int outcode = QuadWithinFrustrum();
+
+ if (outcode)
+ {
+ if (outcode!=2)
+ {
+ GouraudPolygon_ClipWithZ();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ GouraudPolygon_ClipWithNegativeX();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ GouraudPolygon_ClipWithPositiveY();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ GouraudPolygon_ClipWithNegativeY();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ GouraudPolygon_ClipWithPositiveX();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ D3D_ZBufferedGouraudPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
+ }
+ else D3D_ZBufferedGouraudPolygon_Output(&fakeHeader,VerticesBuffer);
+ }
+ }
+}
+
+
+
+
+
+int LightFlareAlpha = 65535;
+void RenderLightFlare(VECTORCH *positionPtr, unsigned int colour)
+{
+ int centreX,centreY,sizeX,sizeY,z;
+ PARTICLE particle;
+// VECTORCH point = {-20947,-8216,2244};
+ VECTORCH point = *positionPtr;
+
+
+ #if 0
+ if (IsThisObjectVisibleFromThisPosition(Player,&point,ONE_FIXED))
+ {
+ LightFlareAlpha+=NormalFrameTime*8;
+ if (LightFlareAlpha > 65535) LightFlareAlpha = 65535;
+ textprint("FLARE VIS\n");
+ }
+ else
+ {
+ LightFlareAlpha-=NormalFrameTime*8;
+ if (LightFlareAlpha < 0) LightFlareAlpha = 0;
+ textprint("FLARE INVIS\n");
+ }
+ #endif
+ TranslatePointIntoViewspace(&point);
+ if(point.vz<64) return;
+
+ #if 0
+ {
+ int alpha = ONE_FIXED - point.vz*2;
+ if (alpha<0) return;
+
+ alpha = MUL_FIXED(LightFlareAlpha,alpha)>>8;
+
+ particle.ParticleID = PARTICLE_MUZZLEFLASH;
+ particle.Colour = 0xffffff+((alpha)<<24);
+ }
+ #else
+ particle.ParticleID = PARTICLE_LIGHTFLARE;
+// particle.Colour = 0xffffff+((LightFlareAlpha>>8)<<24);
+ particle.Colour = colour;
+ #endif
+// textprint("render fn %d %d %d\n",positionPtr->vx,positionPtr->vy,positionPtr->vz);
+// PARTICLE_DESC *particleDescPtr = &ParticleDescription[particlePtr->ParticleID];
+// int particleSize = particlePtr->Size;
+ z=ONE_FIXED;
+ {
+ extern int SmartTargetSightX, SmartTargetSightY;
+ extern SCREENDESCRIPTORBLOCK ScreenDescriptorBlock;
+ centreX = DIV_FIXED(point.vx,point.vz);
+ centreY = DIV_FIXED(point.vy,point.vz);
+ sizeX = (ScreenDescriptorBlock.SDB_Width<<13)/Global_VDB_Ptr->VDB_ProjX;
+ sizeY = MUL_FIXED(ScreenDescriptorBlock.SDB_Height<<13,87381)/Global_VDB_Ptr->VDB_ProjY;
+ }
+
+ VerticesBuffer[0].X = centreX - sizeX;
+ VerticesBuffer[0].Y = centreY - sizeY;
+ VerticesBuffer[0].Z = z;
+ VerticesBuffer[1].X = centreX + sizeX;
+ VerticesBuffer[1].Y = centreY - sizeY;
+ VerticesBuffer[1].Z = z;
+ VerticesBuffer[2].X = centreX + sizeX;
+ VerticesBuffer[2].Y = centreY + sizeY;
+ VerticesBuffer[2].Z = z;
+ VerticesBuffer[3].X = centreX - sizeX;
+ VerticesBuffer[3].Y = centreY + sizeY;
+ VerticesBuffer[3].Z = z;
+
+ {
+ int outcode = QuadWithinFrustrum();
+
+ if (outcode)
+ {
+ RenderPolygon.NumberOfVertices=4;
+
+// textprint("On Screen!\n");
+ VerticesBuffer[0].U = 192<<16;
+ VerticesBuffer[0].V = 0;
+
+ VerticesBuffer[1].U = 255<<16;
+ VerticesBuffer[1].V = 0;
+
+ VerticesBuffer[2].U = 255<<16;
+ VerticesBuffer[2].V = 63<<16;
+
+ VerticesBuffer[3].U = 192<<16;
+ VerticesBuffer[3].V = 63<<16;
+
+ if (outcode!=2)
+ {
+ TexturedPolygon_ClipWithZ();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ TexturedPolygon_ClipWithNegativeX();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ TexturedPolygon_ClipWithPositiveY();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ TexturedPolygon_ClipWithNegativeY();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ TexturedPolygon_ClipWithPositiveX();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ D3D_Particle_Output(&particle,RenderPolygon.Vertices);
+
+ }
+ else D3D_Particle_Output(&particle,VerticesBuffer);
+ }
+ }
+}
+
+#if VOLUMETRIC_FOG
+
+int FogValue(VECTORCH *vertexPtr)
+{
+ float a,b,c,d, lMax,lMin;
+ VECTORCHF v;
+ v.vx = vertexPtr->vx;
+ v.vy = vertexPtr->vy;
+ v.vz = vertexPtr->vz;
+
+ a = (v.vx*v.vx + v.vy*v.vy + v.vz*v.vz)*2.0;
+ b = -2.0*(v.vx*FogPosition.vx+v.vy*FogPosition.vy+v.vz*FogPosition.vz);
+ {
+// float s = MUL_FIXED(GetSin(CloakingPhase&4095),GetSin(CloakingPhase&4095));
+ c = FogMagnitude - 10000.0*10000.0;
+ }
+ d = b*b-2.0*a*c;
+ if (d<0) return 0;
+
+ d = sqrt(d);
+
+ lMin = (-b-d)/(a);
+ if (lMin>1.0) return 0;
+
+ lMax = (-b+d)/(a);
+
+ if (lMax<0.0)
+ {
+ return 0;
+ }
+ else if (lMax>1.0)
+ {
+ if (lMin>0.0)
+ {
+ float m;
+ int f;
+ m = Approximate3dMagnitude(vertexPtr);
+ f2i(f,(lMax-lMin)*m);
+ return f;
+ }
+ else return Approximate3dMagnitude(vertexPtr);
+ }
+ else //(lMax<1.0)
+ {
+ if (lMin>0.0)
+ {
+ float m;
+ int f;
+ m = Approximate3dMagnitude(vertexPtr);
+ f2i(f,(lMax-lMin)*m);
+ return f;
+ }
+ else
+ {
+ float m;
+ int f;
+ m = Approximate3dMagnitude(vertexPtr);
+ f2i(f,(lMax)*m);
+ return f;
+ }
+
+ }
+}
+#endif
+#if 0
+int SphereGenerated=0;
+void RenderSphere(void)
+{
+ if(!SphereGenerated)
+ {
+ Generate_Sphere();
+ SphereGenerated=1;
+ }
+// EvolveSphere();
+ {
+ int f;
+ POLYHEADER fakeHeader;
+ MATRIXCH mat = (Global_VDB_Ptr->VDB_Mat);
+ VECTORCH *vSphere = SphereRotatedVertex;
+ VECTORCH *v2 = SphereAtmosRotatedVertex;
+ VECTORCH d;
+ {
+ fakeHeader.PolyFlags = 0;
+ RenderPolygon.TranslucencyMode = TRANSLUCENCY_OFF;
+ }
+ {
+ MATRIXCH m2;
+ EULER e;
+ e.EulerX =0;
+ e.EulerY =(CloakingPhase/32)&4095;
+ e.EulerZ =0;
+ CreateEulerMatrix(&e,&m2);
+ TransposeMatrixCH(&m2);
+ MatrixMultiply(&mat,&m2,&mat);
+ d.vx = -3316 - Global_VDB_Ptr->VDB_World.vx;
+ d.vy = -50000 -Global_VDB_Ptr->VDB_World.vy;
+ d.vz = 26926 -Global_VDB_Ptr->VDB_World.vz;
+
+ RotateVector(&d,&(Global_VDB_Ptr->VDB_Mat));
+
+ }
+ for (f=0; f<SPHERE_VERTICES; f++)
+ {
+
+ int h = SphereVertexHeight[f];
+ int radius = 4096;
+ if (h>0) radius += h;
+ *vSphere = SphereVertex[f];
+
+ RotateVector(vSphere,&mat);
+ v2->vx = MUL_FIXED(vSphere->vx,4096+300);
+ v2->vy = MUL_FIXED(vSphere->vy,4096+300);
+ v2->vz = MUL_FIXED(vSphere->vz,4096+300);
+ v2++;
+ vSphere->vx = MUL_FIXED(vSphere->vx,radius);
+ vSphere->vy = MUL_FIXED(vSphere->vy,radius);
+ vSphere->vz = MUL_FIXED(vSphere->vz,radius);
+ vSphere++;
+ }
+ #if 0
+ for (f=0; f<SPHERE_FACES; f++)
+ {
+ {
+ int i;
+ VECTORCH v[3];
+
+ {
+ int facingAway=1;
+ for (i=0; i<3; i++)
+ {
+ int n = SphereFace[f].v[i];
+ v[i] = SphereRotatedVertex[n];
+ if (v[i].vz<=0) facingAway=0;
+ }
+ if(facingAway) continue;
+ }
+ for (i=0; i<3; i++)
+ {
+ int n = SphereFace[f].v[i];
+ int l = (v[i].vx*16+ONE_FIXED)/2;
+ int h = SphereVertexHeight[n];
+ if (l>ONE_FIXED) l = ONE_FIXED;
+ if (l<0) l = 0;
+
+ v[i].vx += d.vx;
+ v[i].vy += d.vy;
+ v[i].vz += d.vz;
+ v[i].vy = MUL_FIXED(v[i].vy,87381);
+
+ VerticesBuffer[i].X = v[i].vx;
+ VerticesBuffer[i].Y = v[i].vy;
+ VerticesBuffer[i].Z = v[i].vz;
+
+ VerticesBuffer[i].A = 0;
+ if (h<=0)
+ {
+ VerticesBuffer[i].R = 0;
+ VerticesBuffer[i].G = 255+h;
+ VerticesBuffer[i].B = 255;
+ }
+ else if (h>128)
+ {
+ VerticesBuffer[i].R = MUL_FIXED(255,h*256);
+ VerticesBuffer[i].G = MUL_FIXED(200,h*256);
+ VerticesBuffer[i].B = MUL_FIXED(150,h*256);
+ }
+ else
+ {
+ VerticesBuffer[i].R = 0;
+ VerticesBuffer[i].G = 96-h/2;
+ VerticesBuffer[i].B = 0;
+ }
+ VerticesBuffer[i].R = MUL_FIXED(VerticesBuffer[i].R,l);
+ VerticesBuffer[i].G = MUL_FIXED(VerticesBuffer[i].G,l);
+ VerticesBuffer[i].B = MUL_FIXED(VerticesBuffer[i].B,l);
+ }
+ RenderPolygon.NumberOfVertices=3;
+ }
+
+ GouraudPolygon_ClipWithZ();
+ if(RenderPolygon.NumberOfVertices>=3)
+ {
+ GouraudPolygon_ClipWithNegativeX();
+ if(RenderPolygon.NumberOfVertices>=3)
+ {
+ GouraudPolygon_ClipWithPositiveY();
+ if(RenderPolygon.NumberOfVertices>=3)
+ {
+ GouraudPolygon_ClipWithNegativeY();
+ if(RenderPolygon.NumberOfVertices>=3)
+ {
+ GouraudPolygon_ClipWithPositiveX();
+ if(RenderPolygon.NumberOfVertices>=3)
+ {
+ D3D_ZBufferedGouraudPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
+ }
+ }
+ }
+ }
+ }
+
+ }
+ #endif
+ {
+ extern int CloudyImageNumber;
+ fakeHeader.PolyFlags = iflag_transparent;
+ fakeHeader.PolyColour = CloudyImageNumber;
+ RenderPolygon.TranslucencyMode = TRANSLUCENCY_OFF;
+ }
+ for (f=0; f<SPHERE_FACES; f++)
+ {
+ {
+ int i;
+ VECTORCH vertex[3];
+
+ {
+ int facingAway=1;
+ for (i=0; i<3; i++)
+ {
+ int n = SphereFace[f].v[i];
+ vertex[i] = SphereAtmosRotatedVertex[n];
+ if (vertex[i].vz<=0) facingAway=0;
+ }
+ if(facingAway) continue;
+ }
+ for (i=0; i<3; i++)
+ {
+ int n = SphereFace[f].v[i];
+ int l = (vertex[i].vx*16+ONE_FIXED)/514;
+ if (l>ONE_FIXED) l = ONE_FIXED;
+ if (l<0) l = 0;
+
+ vertex[i].vx += d.vx;
+ vertex[i].vy += d.vy;
+ vertex[i].vz += d.vz;
+ vertex[i].vy = MUL_FIXED(vertex[i].vy,87381);
+
+ VerticesBuffer[i].X = vertex[i].vx;
+ VerticesBuffer[i].Y = vertex[i].vy;
+ VerticesBuffer[i].Z = vertex[i].vz;
+ VerticesBuffer[i].U = SphereAtmosU[n];//+u[0];
+ VerticesBuffer[i].V = SphereAtmosV[n];//+v[0];
+
+ VerticesBuffer[i].A = 255;
+ VerticesBuffer[i].R = l;
+ VerticesBuffer[i].G = l/2;
+ VerticesBuffer[i].B = 0;
+ VerticesBuffer[i].SpecularR = 0;
+ VerticesBuffer[i].SpecularG = 0;
+ VerticesBuffer[i].SpecularB = 0;
+ }
+ RenderPolygon.NumberOfVertices=3;
+ }
+
+ GouraudTexturedPolygon_ClipWithZ();
+ if(RenderPolygon.NumberOfVertices>=3)
+ {
+ GouraudTexturedPolygon_ClipWithNegativeX();
+ if(RenderPolygon.NumberOfVertices>=3)
+ {
+ GouraudTexturedPolygon_ClipWithPositiveY();
+ if(RenderPolygon.NumberOfVertices>=3)
+ {
+ GouraudTexturedPolygon_ClipWithNegativeY();
+ if(RenderPolygon.NumberOfVertices>=3)
+ {
+ GouraudTexturedPolygon_ClipWithPositiveX();
+ if(RenderPolygon.NumberOfVertices>=3)
+ {
+ D3D_ZBufferedGouraudTexturedPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+}
+void RenderBoom(void)
+{
+ VECTORCH d;
+ if(!SphereGenerated)
+ {
+ Generate_Sphere();
+ SphereGenerated=1;
+ }
+ d.vx = 0;
+ d.vy = 0;
+ d.vz = 0;
+
+ RenderBoomSphere(&d,4096);
+
+}
+void RenderBoomSphere(VECTORCH *position, int radius)
+{
+ int Alpha[SPHERE_VERTICES];
+ extern D3DTEXTUREHANDLE FMVTextureHandle[];
+
+ {
+ int f;
+ POLYHEADER fakeHeader;
+ VECTORCH *vSphere = SphereRotatedVertex;
+ static int o=0;
+ o++;
+
+ {
+ extern int CloudyImageNumber;
+ fakeHeader.PolyFlags = iflag_transparent;
+ fakeHeader.PolyColour = CloudyImageNumber;
+ RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL;
+ }
+ for (f=0; f<SPHERE_VERTICES; f++)
+ {
+ int r;
+ int t = GetSin((f+o+CloakingPhase/32)&4095);
+ t = MUL_FIXED(t,t);
+ t = MUL_FIXED(t,t);
+ t = MUL_FIXED(t,t);
+// t = MUL_FIXED(t,t);
+// t = MUL_FIXED(t,t);
+ t = MUL_FIXED(t,t);
+ t = MUL_FIXED(t,t);
+ t = MUL_FIXED(t,t);
+ r = radius+MUL_FIXED(t,t)/128;
+ Alpha[f] = (r-radius)/2;
+
+ *vSphere = SphereVertex[f];
+
+ vSphere->vx = MUL_FIXED(vSphere->vx,r);
+ vSphere->vy = MUL_FIXED(vSphere->vy,r);
+ vSphere->vz = MUL_FIXED(vSphere->vz,r);
+
+ vSphere->vx += position->vx;
+ vSphere->vy += position->vy;
+ vSphere->vz += position->vz;
+ TranslatePointIntoViewspace(vSphere);
+ vSphere++;
+
+ }
+
+ for (f=0; f<SPHERE_FACES; f++)
+ {
+ {
+ int i;
+ VECTORCH vertex[3];
+
+ {
+ for (i=0; i<3; i++)
+ {
+ int n = SphereFace[f].v[i];
+ vertex[i] = SphereRotatedVertex[n];
+
+ }
+ }
+ for (i=0; i<3; i++)
+ {
+ int n = SphereFace[f].v[i];
+
+ VerticesBuffer[i].X = vertex[i].vx;
+ VerticesBuffer[i].Y = vertex[i].vy;
+ VerticesBuffer[i].Z = vertex[i].vz;
+
+
+// SphereAtmosU[0]=(vertex[i].vx)*4*128+GetSin((CloakingPhase)&4095)*16;
+// SphereAtmosV[0]=(vertex[i].vy)*4*128+GetCos((CloakingPhase)&4095)*16;
+ {
+ int t = GetSin((CloakingPhase/20)&4095);
+ int u;
+
+ u = t*(128);
+// SphereAtmosU[0]=MUL_FIXED(SphereAtmosU[0],u);
+// SphereAtmosV[0]=MUL_FIXED(SphereAtmosV[0],u);
+ VerticesBuffer[i].U = (SphereAtmosU[n]+u);//+u[0];
+ VerticesBuffer[i].V = (SphereAtmosV[n]);//+v[0];
+ }
+ {
+ int d1 = VerticesBuffer[0].U-VerticesBuffer[1].U;
+ int d2 = VerticesBuffer[0].U-VerticesBuffer[2].U;
+ int d3 = VerticesBuffer[1].U-VerticesBuffer[2].U;
+
+ int ad1=d1,ad2=d2,ad3=d3;
+ int i1=0,i2=0,i3=0;
+
+ if (ad1<0) ad1=-ad1;
+ if (ad2<0) ad2=-ad2;
+ if (ad3<0) ad3=-ad3;
+
+ if (ad1>(128*3+64)*65536)
+ {
+ if (d1>0) i2=1;
+ else i1=1;
+ }
+ if (ad2>(128*3+64)*65536)
+ {
+ if (d2>0) i3=1;
+ else i1=1;
+ }
+ if (ad3>(128*3+64)*65536)
+ {
+ if (d3>0) i3=1;
+ else i2=1;
+ }
+
+ if(i1) VerticesBuffer[0].U+=128*65536*4;
+ if(i2) VerticesBuffer[1].U+=128*65536*4;
+ if(i3) VerticesBuffer[2].U+=128*65536*4;
+ }
+
+ VerticesBuffer[i].A = 128+Alpha[n];
+ VerticesBuffer[i].R = 0;
+ VerticesBuffer[i].G = 128;
+ VerticesBuffer[i].B = 255;
+ VerticesBuffer[i].SpecularR = 0;
+ VerticesBuffer[i].SpecularG = 0;
+ VerticesBuffer[i].SpecularB = 0;
+ }
+ RenderPolygon.NumberOfVertices=3;
+ }
+
+ GouraudTexturedPolygon_ClipWithZ();
+ if(RenderPolygon.NumberOfVertices>=3)
+ {
+ GouraudTexturedPolygon_ClipWithNegativeX();
+ if(RenderPolygon.NumberOfVertices>=3)
+ {
+ GouraudTexturedPolygon_ClipWithPositiveY();
+ if(RenderPolygon.NumberOfVertices>=3)
+ {
+ GouraudTexturedPolygon_ClipWithNegativeY();
+ if(RenderPolygon.NumberOfVertices>=3)
+ {
+ GouraudTexturedPolygon_ClipWithPositiveX();
+ if(RenderPolygon.NumberOfVertices>=3)
+ {
+ D3D_ZBufferedGouraudTexturedPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
+// D3D_FMVParticle_Output(RenderPolygon.Vertices);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+}
+
+
+#endif
+int Alpha[SPHERE_VERTICES];
+void RenderExplosionSurface(VOLUMETRIC_EXPLOSION *explosionPtr)
+{
+ extern D3DTEXTUREHANDLE FMVTextureHandle[];
+ int red,green,blue;
+
+ switch (CurrentVisionMode)
+ {
+ default:
+ case VISION_MODE_NORMAL:
+ {
+ red = 255;
+ green = 255;
+ blue = 255;
+ break;
+ }
+ case VISION_MODE_IMAGEINTENSIFIER:
+ {
+ red = 0;
+ green = 255;
+ blue = 0;
+ break;
+ }
+ case VISION_MODE_PRED_THERMAL:
+ case VISION_MODE_PRED_SEEALIENS:
+ case VISION_MODE_PRED_SEEPREDTECH:
+ {
+ red = 255;
+ green = 0;
+ blue = 255;
+ break;
+ }
+ }
+ {
+ int f;
+ POLYHEADER fakeHeader;
+ VECTORCH *vSphere = SphereRotatedVertex;
+ static int o=0;
+ o++;
+
+ if (explosionPtr->ExplosionPhase)
+ {
+ extern int BurningImageNumber;
+ fakeHeader.PolyFlags = iflag_transparent;
+ fakeHeader.PolyColour = BurningImageNumber;
+ RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL;
+ }
+ else
+ {
+ extern int CloudyImageNumber;
+ fakeHeader.PolyFlags = iflag_transparent;
+ fakeHeader.PolyColour = CloudyImageNumber;
+ RenderPolygon.TranslucencyMode = TRANSLUCENCY_INVCOLOUR;
+ red = explosionPtr->LifeTime/256;
+ green = explosionPtr->LifeTime/256;
+ blue = explosionPtr->LifeTime/256;
+ }
+
+ for (f=0; f<SPHERE_VERTICES; f++)
+ {
+ *vSphere = explosionPtr->Position[f];
+
+ TranslatePointIntoViewspace(vSphere);
+ vSphere++;
+ }
+
+ for (f=0; f<SPHERE_FACES; f++)
+ {
+ {
+ int i;
+ VECTORCH vertex[3];
+
+ {
+ for (i=0; i<3; i++)
+ {
+ int n = SphereFace[f].v[i];
+ vertex[i] = SphereRotatedVertex[n];
+
+ }
+ }
+ for (i=0; i<3; i++)
+ {
+ int n = SphereFace[f].v[i];
+
+ VerticesBuffer[i].X = vertex[i].vx;
+ VerticesBuffer[i].Y = vertex[i].vy;
+ VerticesBuffer[i].Z = vertex[i].vz;
+
+
+// SphereAtmosU[0]=(vertex[i].vx)*4*128+GetSin((CloakingPhase)&4095)*16;
+// SphereAtmosV[0]=(vertex[i].vy)*4*128+GetCos((CloakingPhase)&4095)*16;
+ {
+ int u = -(ONE_FIXED-explosionPtr->LifeTime)*128*2;
+// SphereAtmosU[0]=MUL_FIXED(SphereAtmosU[0],u);
+// SphereAtmosV[0]=MUL_FIXED(SphereAtmosV[0],u);
+ VerticesBuffer[i].U = (SphereAtmosU[n]);//+u[0];
+ VerticesBuffer[i].V = (SphereAtmosV[n]+u);//+v[0];
+ }
+ {
+ int d1 = VerticesBuffer[0].U-VerticesBuffer[1].U;
+ int d2 = VerticesBuffer[0].U-VerticesBuffer[2].U;
+ int d3 = VerticesBuffer[1].U-VerticesBuffer[2].U;
+
+ int ad1=d1,ad2=d2,ad3=d3;
+ int i1=0,i2=0,i3=0;
+
+ if (ad1<0) ad1=-ad1;
+ if (ad2<0) ad2=-ad2;
+ if (ad3<0) ad3=-ad3;
+
+ if (ad1>(128*(SPHERE_TEXTURE_WRAP-1)+64)*65536)
+ {
+ if (d1>0) i2=1;
+ else i1=1;
+ }
+ if (ad2>(128*(SPHERE_TEXTURE_WRAP-1)+64)*65536)
+ {
+ if (d2>0) i3=1;
+ else i1=1;
+ }
+ if (ad3>(128*(SPHERE_TEXTURE_WRAP-1)+64)*65536)
+ {
+ if (d3>0) i3=1;
+ else i2=1;
+ }
+
+ if(i1) VerticesBuffer[0].U+=128*65536*SPHERE_TEXTURE_WRAP;
+ if(i2) VerticesBuffer[1].U+=128*65536*SPHERE_TEXTURE_WRAP;
+ if(i3) VerticesBuffer[2].U+=128*65536*SPHERE_TEXTURE_WRAP;
+ }
+
+ VerticesBuffer[i].A = explosionPtr->LifeTime/256;
+ VerticesBuffer[i].R = red;
+ VerticesBuffer[i].G = green;
+ VerticesBuffer[i].B = blue;
+ VerticesBuffer[i].SpecularR = 0;
+ VerticesBuffer[i].SpecularG = 0;
+ VerticesBuffer[i].SpecularB = 0;
+
+ }
+ RenderPolygon.NumberOfVertices=3;
+ }
+
+ GouraudTexturedPolygon_ClipWithZ();
+ if(RenderPolygon.NumberOfVertices>=3)
+ {
+ GouraudTexturedPolygon_ClipWithNegativeX();
+ if(RenderPolygon.NumberOfVertices>=3)
+ {
+ GouraudTexturedPolygon_ClipWithPositiveY();
+ if(RenderPolygon.NumberOfVertices>=3)
+ {
+ GouraudTexturedPolygon_ClipWithNegativeY();
+ if(RenderPolygon.NumberOfVertices>=3)
+ {
+ GouraudTexturedPolygon_ClipWithPositiveX();
+ if(RenderPolygon.NumberOfVertices>=3)
+ {
+ D3D_ZBufferedGouraudTexturedPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
+// D3D_FMVParticle_Output(RenderPolygon.Vertices);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+void RenderInsideAlienTongue(int offset)
+{
+ #define TONGUE_SCALE 1024
+ int TonguePolyVertexList[4][4] =
+ {
+ {0,3,7,4}, //+ve y
+ {1,2,3,0}, //+ve x
+ {5,6,7,4}, //-ve x
+ {1,2,6,5}, //-ve y
+ };
+ VECTORCH vertices[8]=
+ {
+ {+TONGUE_SCALE,-TONGUE_SCALE,0},
+ {+TONGUE_SCALE,+TONGUE_SCALE,0},
+ {+TONGUE_SCALE,+TONGUE_SCALE,+TONGUE_SCALE*4},
+ {+TONGUE_SCALE,-TONGUE_SCALE,+TONGUE_SCALE*4},
+
+ {-TONGUE_SCALE,-TONGUE_SCALE,0},
+ {-TONGUE_SCALE,+TONGUE_SCALE,0},
+ {-TONGUE_SCALE,+TONGUE_SCALE,+TONGUE_SCALE*4},
+ {-TONGUE_SCALE,-TONGUE_SCALE,+TONGUE_SCALE*4},
+ };
+ VECTORCH translatedPts[8];
+
+ POLYHEADER fakeHeader;
+ int polyNumber;
+
+ #if 1
+ {
+
+ int i = 7;
+ do
+ {
+ translatedPts[i] = vertices[i];
+ translatedPts[i].vz -= (ONE_FIXED-offset)/16;
+// TranslatePointIntoViewspace(&translatedPts[i]);
+ }
+ while(i--);
+ }
+ #endif
+ {
+ extern int AlienTongueImageNumber;
+ fakeHeader.PolyFlags = 0;
+ fakeHeader.PolyColour = AlienTongueImageNumber;
+ RenderPolygon.TranslucencyMode = TRANSLUCENCY_GLOWING;
+ }
+
+ for(polyNumber=0; polyNumber<4; polyNumber++)
+ {
+ {
+ int i;
+ for (i=0; i<4; i++)
+ {
+ int v = TonguePolyVertexList[polyNumber][i];
+ VerticesBuffer[i].A = 255;
+ VerticesBuffer[i].X = translatedPts[v].vx;
+ VerticesBuffer[i].Y = translatedPts[v].vy;
+ VerticesBuffer[i].Z = translatedPts[v].vz;
+ VerticesBuffer[i].U = CuboidPolyVertexU[3][i]<<16;
+ VerticesBuffer[i].V = CuboidPolyVertexV[3][i]<<16;
+
+
+ VerticesBuffer[i].R = offset/2048;
+ VerticesBuffer[i].G = offset/2048;
+ VerticesBuffer[i].B = offset/2048;
+ VerticesBuffer[i].SpecularR = 0;
+ VerticesBuffer[i].SpecularG = 0;
+ VerticesBuffer[i].SpecularB = 0;
+
+ }
+ RenderPolygon.NumberOfVertices=4;
+ }
+ {
+ GouraudTexturedPolygon_ClipWithZ();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudTexturedPolygon_ClipWithNegativeX();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudTexturedPolygon_ClipWithPositiveY();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudTexturedPolygon_ClipWithNegativeY();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ GouraudTexturedPolygon_ClipWithPositiveX();
+ if(RenderPolygon.NumberOfVertices<3) continue;
+ D3D_ZBufferedGouraudTexturedPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
+
+ }
+ }
+}
+
+
+
+#define NO_OF_STARS 500
+typedef struct
+{
+ VECTORCH Position;
+ int Colour;
+ int Frequency;
+ int Phase;
+
+} STARDESC;
+static STARDESC StarArray[NO_OF_STARS];
+
+void CreateStarArray(void)
+{
+ int i;
+
+ SetSeededFastRandom(FastRandom());
+ for (i=0; i<NO_OF_STARS; i++)
+ {
+ int phi = SeededFastRandom()&4095;
+
+ StarArray[i].Position.vy = ONE_FIXED-(SeededFastRandom()&131071);
+ {
+ float y = ((float)StarArray[i].Position.vy)/65536.0;
+ y = sqrt(1-y*y);
+
+ f2i(StarArray[i].Position.vx,(float)GetCos(phi)*y);
+ f2i(StarArray[i].Position.vz,(float)GetSin(phi)*y);
+ }
+ StarArray[i].Colour = 0xff000000 + (FastRandom()&0x7f7f7f)+0x7f7f7f;
+ StarArray[i].Frequency = (FastRandom()&4095);
+ StarArray[i].Phase = FastRandom()&4095;
+ }
+}
+
+void RenderStarfield(void)
+{
+ int i;
+
+ int sizeX;
+ int sizeY;
+
+ #if 0
+ sizeX = GetSin((MUL_FIXED(CloakingPhase,StarArray[i].Frequency)+StarArray[i].Phase)&4095);
+ sizeX = MUL_FIXED(sizeX,sizeX)/1024+256;
+ #else
+ sizeX = 256;
+ #endif
+
+ sizeY = MUL_FIXED(sizeX,87381);
+
+ for (i=0; i<NO_OF_STARS; i++)
+ {
+ VECTORCH position = StarArray[i].Position;
+ PARTICLE particle;
+ particle.ParticleID = PARTICLE_STAR;
+ particle.Colour = StarArray[i].Colour;
+ #if 1
+ position.vx += Global_VDB_Ptr->VDB_World.vx;
+ position.vy += Global_VDB_Ptr->VDB_World.vy;
+ position.vz += Global_VDB_Ptr->VDB_World.vz;
+
+ TranslatePointIntoViewspace(&position);
+ #endif
+// RotateVector(&position,&(Global_VDB_Ptr->VDB_Mat));
+
+
+ VerticesBuffer[0].X = position.vx - sizeX;
+ VerticesBuffer[0].Y = position.vy - sizeY;
+ VerticesBuffer[0].Z = position.vz;
+ VerticesBuffer[1].X = position.vx + sizeX;
+ VerticesBuffer[1].Y = position.vy - sizeY;
+ VerticesBuffer[1].Z = position.vz;
+ VerticesBuffer[2].X = position.vx + sizeX;
+ VerticesBuffer[2].Y = position.vy + sizeY;
+ VerticesBuffer[2].Z = position.vz;
+ VerticesBuffer[3].X = position.vx - sizeX;
+ VerticesBuffer[3].Y = position.vy + sizeY;
+ VerticesBuffer[3].Z = position.vz;
+
+ {
+ int outcode = QuadWithinFrustrum();
+
+ if (outcode)
+ {
+ RenderPolygon.NumberOfVertices=4;
+
+ // textprint("On Screen!\n");
+ VerticesBuffer[0].U = 192<<16;
+ VerticesBuffer[0].V = 0;
+
+ VerticesBuffer[1].U = 255<<16;
+ VerticesBuffer[1].V = 0;
+
+ VerticesBuffer[2].U = 255<<16;
+ VerticesBuffer[2].V = 63<<16;
+
+ VerticesBuffer[3].U = 192<<16;
+ VerticesBuffer[3].V = 63<<16;
+
+ if (outcode!=2)
+ {
+ TexturedPolygon_ClipWithZ();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ TexturedPolygon_ClipWithNegativeX();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ TexturedPolygon_ClipWithPositiveY();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ TexturedPolygon_ClipWithNegativeY();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ TexturedPolygon_ClipWithPositiveX();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ D3D_Particle_Output(&particle,RenderPolygon.Vertices);
+
+ }
+ else D3D_Particle_Output(&particle,VerticesBuffer);
+ }
+ }
+ }
+}
+
+
+
+
+
+
+#if 0
+/* KJL 17:07:52 07/11/98 - experiment! */
+extern unsigned char DebouncedKeyboardInput[];
+#include "dungeon\angband.h"
+char array[MAX_WID+1][MAX_HGT+1];
+extern cave_type cave[MAX_HGT][MAX_WID];
+void RenderDungeon(void)
+{
+ int x,y;
+ int maxX=MAX_WID-1,maxY=MAX_HGT-1;
+ static int notMade=1;
+
+ if (notMade || DebouncedKeyboardInput[KEY_G])
+ {
+ for (x=0; x<=maxX; x++)
+ for (y=0; y<=maxY; y++)
+ {
+ cave[y][x].feat = FEAT_WALL_OUTER;
+ }
+ generate_cave();
+ for (x=0; x<=maxX; x++)
+ for (y=0; y<=maxY; y++)
+ {
+ array[x][y] = 1;
+ if (cave[y][x].feat == FEAT_FLOOR)
+ array[x][y] = 0;
+ }
+ notMade = 0;
+ }
+ for (x=0; x<=maxX; x++)
+ for (y=0; y<=maxY; y++)
+ {
+ if (!array[x][y])
+ {
+
+ if (x>0)
+ {
+ if (array[x-1][y]) RenderWallY(x,y);
+ }
+ else
+ {
+ RenderWallY(0,y);
+ }
+ if (x<maxX)
+ {
+ if (array[x+1][y]) RenderWallY(x+1,y);
+ }
+ else
+ {
+ RenderWallY(maxX+1,y);
+ }
+ if (y>0)
+ {
+ if (array[x][y-1]) RenderWallX(x,y);
+ }
+ else
+ {
+ RenderWallX(x,0);
+ }
+ if (y<maxY)
+ {
+ if (array[x][y+1]) RenderWallX(x,y+1);
+ }
+ else
+ {
+ RenderWallX(x,maxY+1);
+ }
+ RenderFloor(x,y);
+ }
+
+ }
+}
+void RenderFloor(int x,int y)
+{
+ int mirrorUV[]=
+ {
+ 127<<16, 0,
+ 127<<16, 127<<16,
+ 0, 127<<16,
+ 0, 0
+ };
+ POLYHEADER fakeHeader;
+ {
+ extern int CloudyImageNumber;
+ fakeHeader.PolyFlags = 0;
+ fakeHeader.PolyColour = CloudyImageNumber;
+ }
+
+ {
+ {
+ VECTORCH translatedPts[4] =
+ {
+ {0,1000, 0},
+ {0,1000, 1000},
+ {1000,1000, 1000},
+ {1000,1000, 0},
+
+ };
+ int i;
+
+ for (i=0; i<4; i++)
+ {
+
+ translatedPts[i].vx+=x*1000;
+ translatedPts[i].vz+=y*1000;
+ TranslatePointIntoViewspace(&translatedPts[i]);
+ VerticesBuffer[i].X = translatedPts[i].vx;
+ VerticesBuffer[i].Y = translatedPts[i].vy;
+ VerticesBuffer[i].Z = translatedPts[i].vz;
+ VerticesBuffer[i].U = mirrorUV[i*2];
+ VerticesBuffer[i].V = mirrorUV[i*2+1];
+
+
+ VerticesBuffer[i].R = 255;
+ VerticesBuffer[i].G = 0;
+ VerticesBuffer[i].B = 0;
+ VerticesBuffer[i].SpecularR = 0;
+ VerticesBuffer[i].SpecularG = 0;
+ VerticesBuffer[i].SpecularB = 0;
+
+ }
+ RenderPolygon.NumberOfVertices=4;
+ RenderPolygon.TranslucencyMode = TRANSLUCENCY_OFF;
+ }
+
+ GouraudTexturedPolygon_ClipWithZ();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ GouraudTexturedPolygon_ClipWithNegativeX();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ GouraudTexturedPolygon_ClipWithPositiveY();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ GouraudTexturedPolygon_ClipWithNegativeY();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ GouraudTexturedPolygon_ClipWithPositiveX();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ D3D_ZBufferedGouraudTexturedPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
+ }
+
+}
+void RenderWallY(int x,int y)
+{
+ int mirrorUV[]=
+ {
+ 127<<16, 0,
+ 127<<16, 127<<16,
+ 0, 127<<16,
+ 0, 0
+ };
+ POLYHEADER fakeHeader;
+ {
+ extern int CloudyImageNumber;
+ fakeHeader.PolyFlags = 0;
+ fakeHeader.PolyColour = CloudyImageNumber;
+ }
+
+ {
+ {
+ VECTORCH translatedPts[4] =
+ {
+ {0,0, 0},
+ {0,0, 1000},
+ {0,0+ 1000, 1000},
+ {0,0+ 1000, 0},
+
+ };
+ int i;
+
+ for (i=0; i<4; i++)
+ {
+
+ translatedPts[i].vx+=x*1000;
+ translatedPts[i].vz+=y*1000;
+ TranslatePointIntoViewspace(&translatedPts[i]);
+ VerticesBuffer[i].X = translatedPts[i].vx;
+ VerticesBuffer[i].Y = translatedPts[i].vy;
+ VerticesBuffer[i].Z = translatedPts[i].vz;
+ VerticesBuffer[i].U = mirrorUV[i*2];
+ VerticesBuffer[i].V = mirrorUV[i*2+1];
+
+
+ VerticesBuffer[i].R = 255;
+ VerticesBuffer[i].G = 255;
+ VerticesBuffer[i].B = 255;
+ VerticesBuffer[i].SpecularR = 0;
+ VerticesBuffer[i].SpecularG = 0;
+ VerticesBuffer[i].SpecularB = 0;
+
+ }
+ RenderPolygon.NumberOfVertices=4;
+ RenderPolygon.TranslucencyMode = TRANSLUCENCY_OFF;
+ }
+
+ GouraudTexturedPolygon_ClipWithZ();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ GouraudTexturedPolygon_ClipWithNegativeX();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ GouraudTexturedPolygon_ClipWithPositiveY();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ GouraudTexturedPolygon_ClipWithNegativeY();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ GouraudTexturedPolygon_ClipWithPositiveX();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ D3D_ZBufferedGouraudTexturedPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
+ }
+
+}
+void RenderWallX(int x,int y)
+{
+ int mirrorUV[]=
+ {
+ 127<<16, 0,
+ 127<<16, 127<<16,
+ 0, 127<<16,
+ 0, 0
+ };
+ POLYHEADER fakeHeader;
+ {
+ extern int CloudyImageNumber;
+ fakeHeader.PolyFlags = 0;
+ fakeHeader.PolyColour = CloudyImageNumber;
+ }
+
+ {
+ {
+ VECTORCH translatedPts[4] =
+ {
+ {0,0, 0},
+ {1000,0, 0},
+ {1000, 1000, 0},
+ {0, 1000, 0},
+
+ };
+ int i;
+
+ for (i=0; i<4; i++)
+ {
+ translatedPts[i].vx+=x*1000;
+ translatedPts[i].vz+=y*1000;
+ TranslatePointIntoViewspace(&translatedPts[i]);
+ VerticesBuffer[i].X = translatedPts[i].vx;
+ VerticesBuffer[i].Y = translatedPts[i].vy;
+ VerticesBuffer[i].Z = translatedPts[i].vz;
+ VerticesBuffer[i].U = mirrorUV[i*2];
+ VerticesBuffer[i].V = mirrorUV[i*2+1];
+
+
+ VerticesBuffer[i].R = 255;
+ VerticesBuffer[i].G = 255;
+ VerticesBuffer[i].B = 255;
+ VerticesBuffer[i].SpecularR = 0;
+ VerticesBuffer[i].SpecularG = 0;
+ VerticesBuffer[i].SpecularB = 0;
+
+ }
+ RenderPolygon.NumberOfVertices=4;
+ RenderPolygon.TranslucencyMode = TRANSLUCENCY_OFF;
+ }
+
+ GouraudTexturedPolygon_ClipWithZ();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ GouraudTexturedPolygon_ClipWithNegativeX();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ GouraudTexturedPolygon_ClipWithPositiveY();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ GouraudTexturedPolygon_ClipWithNegativeY();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ GouraudTexturedPolygon_ClipWithPositiveX();
+ if(RenderPolygon.NumberOfVertices<3) return;
+ D3D_ZBufferedGouraudTexturedPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
+ }
+
+}
+#endif
+#if 0
+static void ZBufferedTexturedPolygon_Output(POLYHEADER *inputPolyPtr,RENDERVERTEX *renderVerticesPtr)
+{
+ int *itemDataPtr;
+
+ itemDataPtr = AllocateItemData(IHdrSize + RenderPolygon.NumberOfVertices*5 + ITrmSize);
+
+ if(itemDataPtr)
+ {
+ POLYHEADER *outputPolyPtr = (POLYHEADER*) itemDataPtr;
+ struct KItem * const currentItemPtr = &KItemList[ItemCount];
+
+ currentItemPtr->PolyPtr = outputPolyPtr;
+
+ {
+ int maxZ = smallint;
+ int minZ = bigint;
+ int i = RenderPolygon.NumberOfVertices;
+ RENDERVERTEX *vertices = renderVerticesPtr;
+
+ do
+ {
+ int z = vertices->Z;
+
+ if(z > maxZ) maxZ = z;
+ if(z < minZ) minZ = z;
+ vertices++;
+ }
+ while(--i);
+
+ if (inputPolyPtr->PolyFlags & iflag_sortnearz) currentItemPtr->SortKey = minZ;
+ else if (inputPolyPtr->PolyFlags & iflag_sortfarz) currentItemPtr->SortKey = maxZ +10;
+ else currentItemPtr->SortKey = maxZ;
+ }
+
+ ItemCount++;
+
+ /* Write out the Item Header */
+ outputPolyPtr->PolyItemType = I_ZB_2dTexturedPolygon;
+ outputPolyPtr->PolyNormalIndex = inputPolyPtr->PolyNormalIndex;
+ outputPolyPtr->PolyFlags = inputPolyPtr->PolyFlags;
+ if(Global_ShapeNormals)
+ outputPolyPtr->PolyColour = OldLightingModelForFlatShading((int *)inputPolyPtr);
+ else
+ outputPolyPtr->PolyColour = 0;
+
+ /* Write out the Item Points Array */
+ {
+ int i = RenderPolygon.NumberOfVertices;
+ RENDERVERTEX *vertices = renderVerticesPtr;
+
+ itemDataPtr = &outputPolyPtr->Poly1stPt;
+
+ do
+ {
+ *itemDataPtr++ = ProjectedAndClampedX(vertices);
+ *itemDataPtr++ = ProjectedAndClampedY(vertices);
+ *itemDataPtr++ = vertices->U;
+ *itemDataPtr++ = vertices->V;
+ {
+ float *fDataPtr = (float*)itemDataPtr;
+ *fDataPtr = 1.0/((float)(vertices->Z));
+ itemDataPtr++;
+ }
+ vertices++;
+ }
+ while(--i);
+ }
+ /* Write out the Item Terminator */
+ *itemDataPtr = Term;
+ }
+}
+/* TEXTURED POLYGONS */
+static void TexturedPolygon_Construct(POLYHEADER *polyPtr)
+{
+ int *texture_defn_ptr;
+ RENDERVERTEX *renderVerticesPtr = VerticesBuffer;
+ int i = RenderPolygon.NumberOfVertices;
+
+
+ /* get ptr to uv coords for this polygon */
+ {
+ int texture_defn_index = (polyPtr->PolyColour >> TxDefn);
+ texture_defn_ptr = Global_ShapeTextures[texture_defn_index];
+ }
+
+ VertexNumberPtr = &polyPtr->Poly1stPt;
+
+ /* If this texture is animated the UV array must be calculated */
+ if(polyPtr->PolyFlags & iflag_txanim)
+ {
+ /* Create the UV array */
+ int uv_array[maxpolypts * 2];
+ CreateTxAnimUVArray(texture_defn_ptr, uv_array, (int*)polyPtr);
+ texture_defn_ptr = uv_array;
+
+ do
+ {
+ renderVerticesPtr->X = RotatedPts[*VertexNumberPtr].vx;
+ renderVerticesPtr->Y = RotatedPts[*VertexNumberPtr].vy;
+ renderVerticesPtr->Z = RotatedPts[*VertexNumberPtr].vz;
+
+ renderVerticesPtr->U = texture_defn_ptr[0];
+ renderVerticesPtr->V = texture_defn_ptr[1];
+
+ renderVerticesPtr++;
+ VertexNumberPtr++;
+
+ texture_defn_ptr += 2;
+ }
+ while(--i);
+ }
+ else
+ {
+ do
+ {
+ renderVerticesPtr->X = RotatedPts[*VertexNumberPtr].vx;
+ renderVerticesPtr->Y = RotatedPts[*VertexNumberPtr].vy;
+ renderVerticesPtr->Z = RotatedPts[*VertexNumberPtr].vz;
+
+ renderVerticesPtr->U = texture_defn_ptr[0] << 16;
+ renderVerticesPtr->V = texture_defn_ptr[1] << 16;
+
+ renderVerticesPtr++;
+ VertexNumberPtr++;
+
+ texture_defn_ptr += 2;
+ }
+ while(--i);
+ }
+
+}
+static void TexturedPolygon_Output(POLYHEADER *inputPolyPtr, RENDERVERTEX *renderVerticesPtr)
+{
+ int *itemDataPtr;
+
+ itemDataPtr = AllocateItemData(IHdrSize + RenderPolygon.NumberOfVertices*4 + ITrmSize);
+
+ if(itemDataPtr)
+ {
+ POLYHEADER *outputPolyPtr = (POLYHEADER*) itemDataPtr;
+ struct KItem * const currentItemPtr = &KItemList[ItemCount];
+
+ currentItemPtr->PolyPtr = outputPolyPtr;
+
+ {
+ int maxZ = smallint;
+ int minZ = bigint;
+ int i = RenderPolygon.NumberOfVertices;
+ RENDERVERTEX *vertices = renderVerticesPtr;
+
+ do
+ {
+ int z = vertices->Z;
+
+ if(z > maxZ) maxZ = z;
+ if(z < minZ) minZ = z;
+ vertices++;
+ }
+ while(--i);
+
+ if (inputPolyPtr->PolyFlags & iflag_sortnearz) currentItemPtr->SortKey = minZ;
+ else if (inputPolyPtr->PolyFlags & iflag_sortfarz) currentItemPtr->SortKey = maxZ +10;
+ else currentItemPtr->SortKey = maxZ;
+ }
+
+ ItemCount++;
+
+ /* Write out the Item Header */
+ outputPolyPtr->PolyItemType = I_2dTexturedPolygon;
+ outputPolyPtr->PolyNormalIndex = inputPolyPtr->PolyNormalIndex;
+ outputPolyPtr->PolyFlags = inputPolyPtr->PolyFlags;
+ if(Global_ShapeNormals)
+ outputPolyPtr->PolyColour = OldLightingModelForFlatShading((int *)inputPolyPtr);
+ else
+ outputPolyPtr->PolyColour = 0;
+
+ /* Write out the Item Points Array */
+ {
+ int i = RenderPolygon.NumberOfVertices;
+ RENDERVERTEX *vertices = renderVerticesPtr;
+
+ itemDataPtr = &outputPolyPtr->Poly1stPt;
+
+ do
+ {
+ *itemDataPtr++ = ProjectedAndClampedX(vertices);
+ *itemDataPtr++ = ProjectedAndClampedY(vertices);
+ *itemDataPtr++ = vertices->U;
+ *itemDataPtr++ = vertices->V;
+ vertices++;
+ }
+ while(--i);
+ }
+ /* Write out the Item Terminator */
+ *itemDataPtr = Term;
+ }
+}
+static void ZBufferedGouraudTexturedPolygon_Output(POLYHEADER *inputPolyPtr,RENDERVERTEX *renderVerticesPtr)
+{
+ POLYHEADER *outputPolyPtr;
+ int *itemDataPtr;
+
+ struct KItem * const currentItemPtr = &KItemList[ItemCount];
+
+ {
+ int maxZ = smallint;
+ int minZ = bigint;
+ int i = RenderPolygon.NumberOfVertices;
+ RENDERVERTEX *vertices = renderVerticesPtr;
+
+ do
+ {
+ int z = vertices->Z;
+
+ if(z > maxZ) maxZ = z;
+ if(z < minZ) minZ = z;
+ vertices++;
+ }
+ while(--i);
+
+ if (inputPolyPtr->PolyFlags & iflag_sortnearz) currentItemPtr->SortKey = minZ;
+ else if (inputPolyPtr->PolyFlags & iflag_sortfarz) currentItemPtr->SortKey = maxZ +10;
+ else currentItemPtr->SortKey = maxZ;
+ }
+
+ /* draw in 3d */
+ {
+ itemDataPtr = AllocateItemData(IHdrSize + RenderPolygon.NumberOfVertices*6 + ITrmSize);
+ outputPolyPtr = (POLYHEADER*) itemDataPtr;
+
+ /* Write out the Item Header */
+ outputPolyPtr->PolyItemType = I_ZB_Gouraud3dTexturedPolygon;
+
+ /* Write out the Item Points Array */
+ {
+ int i = RenderPolygon.NumberOfVertices;
+ RENDERVERTEX *vertices = renderVerticesPtr;
+
+ itemDataPtr = &outputPolyPtr->Poly1stPt;
+
+ do
+ #if 1
+ {
+ float oneOverZ;
+ oneOverZ = (1.0)/vertices->Z;
+ {
+ int x = (vertices->X*(Global_VDB_Ptr->VDB_ProjX+1))/vertices->Z+Global_VDB_Ptr->VDB_CentreX;
+ if (x<Global_VDB_Ptr->VDB_ClipLeft)
+ {
+ x=Global_VDB_Ptr->VDB_ClipLeft;
+ }
+ else if (x>Global_VDB_Ptr->VDB_ClipRight)
+ {
+ x=Global_VDB_Ptr->VDB_ClipRight;
+ }
+
+ *itemDataPtr++=x;
+ }
+ {
+ int y = (vertices->Y*(Global_VDB_Ptr->VDB_ProjY+1))/vertices->Z+Global_VDB_Ptr->VDB_CentreY;
+ if (y<Global_VDB_Ptr->VDB_ClipUp)
+ {
+ y=Global_VDB_Ptr->VDB_ClipUp;
+ }
+ else if (y>Global_VDB_Ptr->VDB_ClipDown)
+ {
+ y=Global_VDB_Ptr->VDB_ClipDown;
+ }
+ *itemDataPtr++=y;
+ }
+ {
+ float *fDataPtr = (float*)itemDataPtr;
+
+ *fDataPtr++ = (float)(vertices->U>>16);
+ *fDataPtr++ = (float)(vertices->V>>16);
+ *fDataPtr++ = oneOverZ;
+ itemDataPtr = (int*)fDataPtr;
+ }
+ *itemDataPtr++ = vertices->I;
+ vertices++;
+ }
+ #else
+ {
+ *itemDataPtr++ = ProjectedAndClampedX(vertices);
+ *itemDataPtr++ = ProjectedAndClampedY(vertices);
+ {
+ float uf,vf,zf;
+ float *fDataPtr = (float*)itemDataPtr;
+
+ zf = (vertices->Z);
+
+ uf = vertices->U>>16;
+ *fDataPtr++ = uf;
+
+ vf = vertices->V>>16;
+ *fDataPtr++ = vf;
+ zf = 1.0/zf;
+ *fDataPtr++ = zf;
+ itemDataPtr = (int*)fDataPtr;
+ }
+ *itemDataPtr++ = vertices->I;
+ vertices++;
+ }
+ #endif
+ while(--i);
+ }
+ }
+
+ /* Write out the Item Terminator */
+ *itemDataPtr = Term;
+
+ currentItemPtr->PolyPtr = outputPolyPtr;
+
+ outputPolyPtr->PolyNormalIndex = inputPolyPtr->PolyNormalIndex;
+ outputPolyPtr->PolyFlags = inputPolyPtr->PolyFlags;
+ outputPolyPtr->PolyColour = inputPolyPtr->PolyColour;
+
+ ItemCount++;
+}
+static void GouraudPolygon_Output(POLYHEADER *inputPolyPtr, RENDERVERTEX *renderVerticesPtr)
+{
+ int *itemDataPtr;
+
+ itemDataPtr = AllocateItemData(IHdrSize + RenderPolygon.NumberOfVertices*3 + ITrmSize);
+
+ if(itemDataPtr)
+ {
+ POLYHEADER *outputPolyPtr = (POLYHEADER*) itemDataPtr;
+ struct KItem * const currentItemPtr = &KItemList[ItemCount];
+
+ currentItemPtr->PolyPtr = outputPolyPtr;
+
+ {
+
+ int maxZ = smallint;
+ int minZ = bigint;
+ int i = RenderPolygon.NumberOfVertices;
+ RENDERVERTEX *vertices = renderVerticesPtr;
+
+ do
+ {
+ int z = vertices->Z;
+
+ if(z > maxZ) maxZ = z;
+ if(z < minZ) minZ = z;
+ vertices++;
+ }
+ while(--i);
+
+ if (inputPolyPtr->PolyFlags & iflag_sortnearz) currentItemPtr->SortKey = minZ;
+ else if (inputPolyPtr->PolyFlags & iflag_sortfarz) currentItemPtr->SortKey = maxZ +10;
+ else currentItemPtr->SortKey = maxZ;
+ }
+
+ ItemCount++;
+
+ /* Write out the Item Header */
+ outputPolyPtr->PolyItemType = I_GouraudPolygon;
+ outputPolyPtr->PolyNormalIndex = inputPolyPtr->PolyNormalIndex;
+ outputPolyPtr->PolyFlags = inputPolyPtr->PolyFlags;
+
+ #if 1//debug
+ if (inputPolyPtr->PolyItemType != I_GouraudPolygon)
+ {
+ int c = GetSin((inputPolyPtr->PolyColour>>5)&4095);
+ if (c<0) c=-c;
+
+ inputPolyPtr->PolyColour+=NormalFrameTime;
+
+ if (VideoModeType==VideoModeType_8) c<<=6;
+
+ {
+ int i = RenderPolygon.NumberOfVertices;
+ RENDERVERTEX *vertices = renderVerticesPtr;
+
+ do
+ {
+ vertices->I = c;
+ vertices++;
+ }
+ while(--i);
+ }
+
+ outputPolyPtr->PolyColour = 0xff;
+ }
+ else
+ #endif
+ outputPolyPtr->PolyColour = inputPolyPtr->PolyColour;
+
+ /* Write out the Item Points Array */
+ {
+ int i = RenderPolygon.NumberOfVertices;
+ RENDERVERTEX *vertices = renderVerticesPtr;
+
+ itemDataPtr = &outputPolyPtr->Poly1stPt;
+
+ do
+ {
+ *itemDataPtr++ = ProjectedAndClampedX(vertices);
+ *itemDataPtr++ = ProjectedAndClampedY(vertices);
+ *itemDataPtr++ = vertices->I;
+ vertices++;
+ }
+ while(--i);
+ }
+ /* Write out the Item Terminator */
+ *itemDataPtr = Term;
+ }
+}
+static void CloakedTexturedPolygon_Construct(POLYHEADER *polyPtr)
+{
+ int cloakedU[] = { 248-8,256-8,256-8,248-8 };
+ int cloakedV[] = { 1,1,8,8 };
+
+ int *texture_defn_ptr;
+ RENDERVERTEX *renderVerticesPtr = VerticesBuffer;
+ int i = RenderPolygon.NumberOfVertices;
+
+
+ /* get ptr to uv coords for this polygon */
+ {
+ int texture_defn_index = (polyPtr->PolyColour >> TxDefn);
+ texture_defn_ptr = Global_ShapeTextures[texture_defn_index];
+ }
+
+ VertexNumberPtr = &polyPtr->Poly1stPt;
+
+ while(i--)
+ {
+ renderVerticesPtr->X = RotatedPts[*VertexNumberPtr].vx;
+ renderVerticesPtr->Y = RotatedPts[*VertexNumberPtr].vy;
+ renderVerticesPtr->Z = RotatedPts[*VertexNumberPtr].vz;
+
+ renderVerticesPtr->U = cloakedU[i];
+ renderVerticesPtr->V = cloakedV[i];
+
+ renderVerticesPtr++;
+ VertexNumberPtr++;
+ }
+}
+ void GouraudTexturedPolygon_Output(POLYHEADER *inputPolyPtr,RENDERVERTEX *renderVerticesPtr)
+{
+ POLYHEADER *outputPolyPtr;
+ int *itemDataPtr;
+ int drawIn2D;
+
+ struct KItem * const currentItemPtr = &KItemList[ItemCount];
+
+ {
+ int maxZ = smallint;
+ int minZ = bigint;
+ int i = RenderPolygon.NumberOfVertices;
+ RENDERVERTEX *vertices = renderVerticesPtr;
+
+ do
+ {
+ int z = vertices->Z;
+
+ if(z > maxZ) maxZ = z;
+ if(z < minZ) minZ = z;
+ vertices++;
+ }
+ while(--i);
+
+ if (inputPolyPtr->PolyFlags & iflag_sortnearz) currentItemPtr->SortKey = minZ;
+ else if (inputPolyPtr->PolyFlags & iflag_sortfarz) currentItemPtr->SortKey = maxZ +10;
+ else currentItemPtr->SortKey = maxZ;
+
+ drawIn2D = (maxZ*4 < minZ*5);
+ }
+
+ #if !Saturn
+ /* KJL 15:49:56 07/04/97 - draw all in 3D will become an option */
+ if ((ScanDrawMode == ScanDrawDirectDraw) && (drawIn2D))
+ #endif
+ {
+ itemDataPtr = AllocateItemData(IHdrSize + RenderPolygon.NumberOfVertices*5 + ITrmSize);
+ outputPolyPtr = (POLYHEADER*) itemDataPtr;
+
+ /* Write out the Item Header */
+ outputPolyPtr->PolyItemType = I_Gouraud2dTexturedPolygon;
+
+ /* Write out the Item Points Array */
+ {
+ int i = RenderPolygon.NumberOfVertices;
+ RENDERVERTEX *vertices = renderVerticesPtr;
+
+ itemDataPtr = &outputPolyPtr->Poly1stPt;
+
+ do
+ {
+ #if 1
+ {
+ int x = (vertices->X*(Global_VDB_Ptr->VDB_ProjX+1))/vertices->Z+Global_VDB_Ptr->VDB_CentreX;
+ if (x<Global_VDB_Ptr->VDB_ClipLeft)
+ {
+ x=Global_VDB_Ptr->VDB_ClipLeft;
+ }
+ else if (x>Global_VDB_Ptr->VDB_ClipRight)
+ {
+ x=Global_VDB_Ptr->VDB_ClipRight;
+ }
+
+ *itemDataPtr++=x;
+ }
+ {
+ int y = (vertices->Y*(Global_VDB_Ptr->VDB_ProjY+1))/vertices->Z+Global_VDB_Ptr->VDB_CentreY;
+ if (y<Global_VDB_Ptr->VDB_ClipUp)
+ {
+ y=Global_VDB_Ptr->VDB_ClipUp;
+ }
+ else if (y>Global_VDB_Ptr->VDB_ClipDown)
+ {
+ y=Global_VDB_Ptr->VDB_ClipDown;
+ }
+ *itemDataPtr++=y;
+ }
+ #endif
+ #if Saturn
+ *itemDataPtr++ = vertices->R;
+ *itemDataPtr++ = vertices->G;
+ *itemDataPtr++ = vertices->B;
+ #else
+ *itemDataPtr++ = vertices->U;
+ *itemDataPtr++ = vertices->V;
+ *itemDataPtr++ = vertices->I;
+ #endif
+ vertices++;
+ }
+ while(--i);
+ }
+ }
+ #if !Saturn
+ else /* draw in 3d */
+ {
+ itemDataPtr = AllocateItemData(IHdrSize + RenderPolygon.NumberOfVertices*6 + ITrmSize);
+ outputPolyPtr = (POLYHEADER*) itemDataPtr;
+
+ /* Write out the Item Header */
+ outputPolyPtr->PolyItemType = I_Gouraud3dTexturedPolygon;
+
+ /* Write out the Item Points Array */
+ {
+ int i = RenderPolygon.NumberOfVertices;
+ RENDERVERTEX *vertices = renderVerticesPtr;
+
+ itemDataPtr = &outputPolyPtr->Poly1stPt;
+
+ do
+ {
+ float oneOverZ,uf,vf;
+ uf = vertices->U>>16;
+ vf = vertices->V>>16;
+
+ oneOverZ = (1.0)/vertices->Z;
+ {
+ int x = (vertices->X*(Global_VDB_Ptr->VDB_ProjX+1))/vertices->Z+Global_VDB_Ptr->VDB_CentreX;
+ if (x<Global_VDB_Ptr->VDB_ClipLeft)
+ {
+ x=Global_VDB_Ptr->VDB_ClipLeft;
+ }
+ else if (x>Global_VDB_Ptr->VDB_ClipRight)
+ {
+ x=Global_VDB_Ptr->VDB_ClipRight;
+ }
+
+ *itemDataPtr++=x;
+ }
+ uf = uf*oneOverZ;
+ {
+ int y = (vertices->Y*(Global_VDB_Ptr->VDB_ProjY+1))/vertices->Z+Global_VDB_Ptr->VDB_CentreY;
+ if (y<Global_VDB_Ptr->VDB_ClipUp)
+ {
+ y=Global_VDB_Ptr->VDB_ClipUp;
+ }
+ else if (y>Global_VDB_Ptr->VDB_ClipDown)
+ {
+ y=Global_VDB_Ptr->VDB_ClipDown;
+ }
+ *itemDataPtr++=y;
+ }
+ vf = vf*oneOverZ;
+ {
+ float *fDataPtr = (float*)itemDataPtr;
+
+ *fDataPtr++ = uf;
+ *fDataPtr++ = vf;
+ *fDataPtr++ = oneOverZ;
+ itemDataPtr = (int*)fDataPtr;
+ }
+ *itemDataPtr++ = vertices->I;
+ vertices++;
+ }
+ while(--i);
+ }
+ }
+ #endif
+ /* Write out the Item Terminator */
+ *itemDataPtr = Term;
+
+ currentItemPtr->PolyPtr = outputPolyPtr;
+
+ outputPolyPtr->PolyNormalIndex = inputPolyPtr->PolyNormalIndex;
+ outputPolyPtr->PolyFlags = inputPolyPtr->PolyFlags;
+ outputPolyPtr->PolyColour = inputPolyPtr->PolyColour;
+
+ ItemCount++;
+}
+
+#endif \ No newline at end of file