/*KJL************************************************************************************ * kshape.c - replacement for all the pipeline stuff previously done in shape.c & clip.c * ************************************************************************************KJL*/ #include "3dc.h" #include #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>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 (specularBZ*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)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]; } } #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; inumpoints; 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 (maxZZ) maxZ = renderVerticesPtr->Z; *vertexPtr++ = *renderVerticesPtr++; } while(--i); TranslucentPolygons[CurrentNumberOfTranslucentPolygons].MaxZ = maxZ; TranslucentPolygonHeaders[CurrentNumberOfTranslucentPolygons] = *inputPolyPtr; /* increment counter */ CurrentNumberOfTranslucentPolygons++; LOCALASSERT(CurrentNumberOfTranslucentPolygonsTranslucentPolygons[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;iVDB_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; f0) 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; fONE_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; fONE_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; fvx = 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(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; fPosition[f]; TranslatePointIntoViewspace(vSphere); vSphere++; } for (f=0; fLifeTime)*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; iVDB_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 (x0) { if (array[x][y-1]) RenderWallX(x,y); } else { RenderWallX(x,0); } if (yPolyPtr = 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 (xVDB_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 (yVDB_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 (xVDB_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 (yVDB_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 (xVDB_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 (yVDB_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