
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.
8501 lines
No EOL
206 KiB
Text
8501 lines
No EOL
206 KiB
Text
/*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, <oVMat_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, <oVMat_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, <oVMat_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, <oVMat);
|
|
MatrixToEuler(<oVMat, <oVMat_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§ion_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, <oVMat);
|
|
MatrixToEuler(<oVMat, <oVMat_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];
|
|
}
|
|
}
|
|
|
|
|
|
#if 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(<oVMat);
|
|
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 |