| | 1 | #include "system.h" |
| | 2 | #include "stratdef.h" |
| | 3 | #include "frustum.h" |
| | 4 | #include "npc_marine.h" |
| | 5 | #include "corpse.h" |
| | 6 | #include "debris.h" |
| | 7 | #include "weaponbehaviour.h" |
| | 8 | #include "bh_types.h" |
| | 9 | #include "pldghost.h" |
| | 10 | #include "userprofile.h" |
| | 11 | #include "weapons.h" |
| | 12 | #include "lighting.h" |
| | 13 | #include "hud.h" |
| | 14 | #include "bh_light.h" |
| | 15 | #include <math.h> |
| | 16 | #include <assert.h> |
| | 17 | |
| | 18 | #define ALIENS_LIFEFORCE_GLOW_COLOUR 0x20ff8080 |
| | 19 | #define MARINES_LIFEFORCE_GLOW_COLOUR 0x208080ff |
| | 20 | #define PREDATORS_LIFEFORCE_GLOW_COLOUR 0x2080ff80 |
| | 21 | #define MAX_NO_OF_TRANSLUCENT_POLYGONS 1000 |
| | 22 | |
| | 23 | #define SPATIAL_SHOCKWAVE 0 |
| | 24 | #define ClrTxDefn 0x0000ffff /* AND with this to clear the high 16-bits */ |
| | 25 | #define MaxLightsPerObject 100 /* Sources lighting the object */ |
| | 26 | |
| | 27 | extern void GetMorphDisplay(MORPHDISPLAY *md, DISPLAYBLOCK *dptr); |
| | 28 | extern void Decal_Output(const DECAL *decalPtr, RENDERVERTEX *renderVerticesPtr); |
| | 29 | extern void SkyPolygon_Output(RENDERVERTEX *renderVerticesPtr, enum TRANSLUCENCY_TYPE TranslucencyMode); |
| | 30 | extern void ZBufferedCloakedPolygon_Output(int texture_number, RENDERVERTEX *renderVerticesPtr); |
| | 31 | extern void TexturedPolygon(int texture_number, RENDERVERTEX *renderVerticesPtr, enum TRANSLUCENCY_TYPE TranslucencyMode); |
| | 32 | extern void Polygon(RENDERVERTEX *renderVerticesPtr, enum TRANSLUCENCY_TYPE TranslucencyMode); |
| | 33 | extern void Particle_Output(PARTICLE *particlePtr, RENDERVERTEX *renderVerticesPtr); |
| | 34 | extern void DoPlayersWeaponHModel(DISPLAYBLOCK *dptr); |
| | 35 | |
| | 36 | extern SCREENDESCRIPTORBLOCK ScreenDescriptorBlock; |
| | 37 | extern DISPLAYBLOCK* ActiveBlockList[]; |
| | 38 | extern int NumActiveBlocks; |
| | 39 | extern int CloakingPhase; |
| | 40 | extern int CloudyImageNumber; |
| | 41 | |
| | 42 | static void (*VertexIntensity)(RENDERVERTEX *renderVertexPtr); |
| | 43 | |
| | 44 | static LIGHTBLOCK *LightSourcesForObject[MaxLightsPerObject]; |
| | 45 | static DISPLAYBLOCK *Global_ODB_Ptr; |
| | 46 | static struct shapeheader *Global_ShapeHeaderPtr; |
| | 47 | static int *Global_ShapePoints; |
| | 48 | static int *Global_ShapeNormals; |
| | 49 | static int *Global_ShapeVNormals; |
| | 50 | static int HierarchicalObjectsLowestYValue; |
| | 51 | static int ObjectCounter = 0; |
| | 52 | static int NumLightSourcesForObject; |
| | 53 | static int CurrentNumberOfTranslucentPolygons = 0; |
| | 54 | static VECTORCH ObjectCentre; |
| | 55 | static VECTORCH LocalView; |
| | 56 | static float ViewMatrix[12]; |
| | 57 | static const int* VertexNumberPtr = (int*)1; |
| | 58 | |
| | 59 | int DrawingAReflection; |
| | 60 | int TripTasticPhase; |
| | 61 | int MirroringActive = 0; |
| | 62 | int MirroringAxis = -149*2; |
| | 63 | int NumberOfHeatSources; |
| | 64 | float CameraZoomScale; |
| | 65 | |
| | 66 | RENDERVERTEX *draw_vertices; |
| | 67 | RENDERVERTEX VerticesUnClipped[9]; |
| | 68 | struct render_polygon RenderPolygon; |
| | 69 | VECTORCH RotatedPts[maxrotpts]; |
| | 70 | |
| | 71 | MORPHDISPLAY MorphDisplay; |
| | 72 | VECTORCH MorphedPts[1024]; |
| | 73 | HEATSOURCE HeatSourceList[MAX_NUMBER_OF_HEAT_SOURCES]; |
| | 74 | |
| | 75 | static struct |
| | 76 | { |
| | 77 | /* stamp used for lazy evaluation */ |
| | 78 | int Stamp; |
| | 79 | |
| | 80 | /* colour scalings */ |
| | 81 | uint8_t R; |
| | 82 | uint8_t G; |
| | 83 | uint8_t B; |
| | 84 | |
| | 85 | /* specular colour */ |
| | 86 | uint8_t SpecularR; |
| | 87 | uint8_t SpecularG; |
| | 88 | uint8_t SpecularB; |
| | 89 | |
| | 90 | } ColourIntensityArray[maxrotpts]; |
| | 91 | |
| | 92 | static struct |
| | 93 | { |
| | 94 | struct render_polygon polygon; |
| | 95 | int flags; |
| | 96 | int texture_number; |
| | 97 | |
| | 98 | } TranslucentPolygons[MAX_NO_OF_TRANSLUCENT_POLYGONS]; |
| | 99 | |
| | 100 | static void LightSourcesInRangeOfObject(DISPLAYBLOCK *dptr, const MATRIXCH *WToLMat) |
| | 101 | { |
| | 102 | int i,j; |
| | 103 | NumLightSourcesForObject = 0; |
| | 104 | |
| | 105 | /* Light Sources attached to other objects */ |
| | 106 | |
| | 107 | for(i=0; (i < NumActiveBlocks) && (NumLightSourcesForObject < MaxLightsPerObject); i++) |
| | 108 | { |
| | 109 | DISPLAYBLOCK *dptr2 = ActiveBlockList[i]; |
| | 110 | |
| | 111 | for(j=0; j < dptr2->ObNumLights && (NumLightSourcesForObject < MaxLightsPerObject); j++) |
| | 112 | { |
| | 113 | LIGHTBLOCK *lptr = dptr2->ObLights[j]; |
| | 114 | |
| | 115 | if (!lptr->LightBright || !(lptr->RedScale || lptr->GreenScale || lptr->BlueScale)) |
| | 116 | continue; |
| | 117 | |
| | 118 | if ((PlayerStatus.VisionMode == VISION_MODE_IMAGEINTENSIFIER) && (lptr->LightFlags & LFlag_PreLitSource)) |
| | 119 | continue; |
| | 120 | |
| | 121 | if(!(dptr->ObFlags3 & ObFlag3_PreLit && lptr->LightFlags & LFlag_PreLitSource)) |
| | 122 | { |
| | 123 | VECTORCH vertexToLight; |
| | 124 | |
| | 125 | if (DrawingAReflection) |
| | 126 | vertexToLight.vx = (MirroringAxis - lptr->LightWorld.vx) - dptr->ObWorld.vx; |
| | 127 | else |
| | 128 | vertexToLight.vx = lptr->LightWorld.vx - dptr->ObWorld.vx; |
| | 129 | |
| | 130 | vertexToLight.vy = lptr->LightWorld.vy - dptr->ObWorld.vy; |
| | 131 | vertexToLight.vz = lptr->LightWorld.vz - dptr->ObWorld.vz; |
| | 132 | |
| | 133 | int distanceToLight = Approximate3dMagnitude(&vertexToLight); |
| | 134 | |
| | 135 | if(distanceToLight < (lptr->LightRange + dptr->extent.radius)) |
| | 136 | { |
| | 137 | LightSourcesForObject[NumLightSourcesForObject++] = lptr; |
| | 138 | |
| | 139 | /* Transform the light position to local space */ |
| | 140 | |
| | 141 | RotateAndCopyVector(&vertexToLight, &lptr->LocalLP, WToLMat); |
| | 142 | } |
| | 143 | } |
| | 144 | } |
| | 145 | } |
| | 146 | |
| | 147 | { |
| | 148 | extern LIGHTELEMENT LightElementStorage[]; |
| | 149 | extern int NumActiveLightElements; |
| | 150 | |
| | 151 | for(i=0; i < NumActiveLightElements; i++) |
| | 152 | { |
| | 153 | LIGHTBLOCK *lptr = &LightElementStorage[i].LightBlock; |
| | 154 | VECTORCH vertexToLight; |
| | 155 | |
| | 156 | vertexToLight.vx = lptr->LightWorld.vx - dptr->ObWorld.vx; |
| | 157 | vertexToLight.vy = lptr->LightWorld.vy - dptr->ObWorld.vy; |
| | 158 | vertexToLight.vz = lptr->LightWorld.vz - dptr->ObWorld.vz; |
| | 159 | |
| | 160 | int distanceToLight = Approximate3dMagnitude(&vertexToLight); |
| | 161 | |
| | 162 | if(distanceToLight < (lptr->LightRange + dptr->extent.radius) ) |
| | 163 | { |
| | 164 | LightSourcesForObject[NumLightSourcesForObject] = lptr; |
| | 165 | NumLightSourcesForObject++; |
| | 166 | |
| | 167 | /* Transform the light position to local space */ |
| | 168 | RotateAndCopyVector(&vertexToLight, &lptr->LocalLP, WToLMat); |
| | 169 | } |
| | 170 | } |
| | 171 | } |
| | 172 | } |
| | 173 | |
| | 174 | static void SetupShapePipeline(DISPLAYBLOCK * dptr) |
| | 175 | { |
| | 176 | MATRIXCH WToLMat = dptr->ObMat; |
| | 177 | Global_ODB_Ptr = dptr; |
| | 178 | Global_ShapeHeaderPtr = dptr->ShapeData; |
| | 179 | Global_ShapePoints = *(Global_ShapeHeaderPtr->points); |
| | 180 | Global_ShapeNormals = Global_ShapeHeaderPtr->sh_normals ? *(Global_ShapeHeaderPtr->sh_normals) : 0; |
| | 181 | Global_ShapeVNormals = Global_ShapeHeaderPtr->sh_vnormals ? *(Global_ShapeHeaderPtr->sh_vnormals) : 0; |
| | 182 | ObjectCounter++; |
| | 183 | |
| | 184 | /* |
| | 185 | Create the World -> Local Matrix |
| | 186 | WToLMat = Transposed Local Matrix |
| | 187 | */ |
| | 188 | |
| | 189 | TransposeMatrixCH(&WToLMat); |
| | 190 | |
| | 191 | /* |
| | 192 | Transform the View World Location to Local Space |
| | 193 | |
| | 194 | -> Make the View Loc. relative to the Object View Space Centre |
| | 195 | -> Rotate this vector using WToLMat |
| | 196 | */ |
| | 197 | |
| | 198 | LocalView.vx = Global_VDB.VDB_World.vx - dptr->ObWorld.vx; |
| | 199 | LocalView.vy = Global_VDB.VDB_World.vy - dptr->ObWorld.vy; |
| | 200 | LocalView.vz = Global_VDB.VDB_World.vz - dptr->ObWorld.vz; |
| | 201 | |
| | 202 | RotateVector(&LocalView, &WToLMat); |
| | 203 | LightSourcesInRangeOfObject(dptr, &WToLMat); |
| | 204 | } |
| | 205 | |
| | 206 | static void VertexIntensity_Pred_Thermal(RENDERVERTEX *renderVertexPtr) |
| | 207 | { |
| | 208 | int vertexNumber = *VertexNumberPtr; |
| | 209 | |
| | 210 | if(ColourIntensityArray[vertexNumber].Stamp == ObjectCounter) |
| | 211 | { |
| | 212 | renderVertexPtr->R = ColourIntensityArray[vertexNumber].R; |
| | 213 | renderVertexPtr->G = ColourIntensityArray[vertexNumber].G; |
| | 214 | renderVertexPtr->B = ColourIntensityArray[vertexNumber].B; |
| | 215 | renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR; |
| | 216 | renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG; |
| | 217 | renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB; |
| | 218 | } |
| | 219 | else |
| | 220 | { |
| | 221 | int redI = 0,specular = 0; |
| | 222 | int blueI = ONE_FIXED / 2; |
| | 223 | |
| | 224 | { |
| | 225 | VECTORCH *vertexNormalPtr = ((VECTORCH *)Global_ShapeVNormals) + vertexNumber; |
| | 226 | VECTORCH *vertexPtr = ((VECTORCH *)Global_ShapePoints) + vertexNumber; |
| | 227 | VECTORCH vertexToLight; |
| | 228 | int i; |
| | 229 | |
| | 230 | for(i=0; i < NumLightSourcesForObject; i++) |
| | 231 | { |
| | 232 | LIGHTBLOCK *lptr = LightSourcesForObject[i]; |
| | 233 | |
| | 234 | if (lptr->LightFlags & LFlag_PreLitSource) |
| | 235 | continue; |
| | 236 | |
| | 237 | vertexToLight.vx = lptr->LocalLP.vx - vertexPtr->vx; |
| | 238 | vertexToLight.vy = lptr->LocalLP.vy - vertexPtr->vy; |
| | 239 | vertexToLight.vz = lptr->LocalLP.vz - vertexPtr->vz; |
| | 240 | |
| | 241 | int distanceToLight = Approximate3dMagnitude(&vertexToLight); |
| | 242 | |
| | 243 | if(distanceToLight < lptr->LightRange) |
| | 244 | { |
| | 245 | int idot = MUL_FIXED(lptr->LightRange-distanceToLight,lptr->BrightnessOverRange); |
| | 246 | |
| | 247 | if( (distanceToLight > 0) && !(Global_ODB_Ptr->ObFlags3 & ObFlag3_NoLightDot)) |
| | 248 | { |
| | 249 | int dotproduct = MUL_FIXED(vertexNormalPtr->vx,vertexToLight.vx) |
| | 250 | + MUL_FIXED(vertexNormalPtr->vy,vertexToLight.vy) |
| | 251 | + MUL_FIXED(vertexNormalPtr->vz,vertexToLight.vz); |
| | 252 | |
| | 253 | if(dotproduct > 0) |
| | 254 | { |
| | 255 | idot = WideMulNarrowDiv(idot,dotproduct,distanceToLight); |
| | 256 | redI += idot; |
| | 257 | } |
| | 258 | } |
| | 259 | |
| | 260 | if (lptr->LightFlags & LFlag_Thermal) |
| | 261 | specular += idot; |
| | 262 | } |
| | 263 | } |
| | 264 | } |
| | 265 | |
| | 266 | if (renderVertexPtr->Z > 5000) |
| | 267 | { |
| | 268 | int a = (renderVertexPtr->Z - 5000); |
| | 269 | |
| | 270 | if (a > 4096) |
| | 271 | blueI = (blueI*4096)/a; |
| | 272 | } |
| | 273 | |
| | 274 | blueI >>= 8; |
| | 275 | |
| | 276 | if(redI >= ONE_FIXED) |
| | 277 | redI = (ONE_FIXED - 1); |
| | 278 | |
| | 279 | redI >>=8; |
| | 280 | |
| | 281 | specular >>= 6; |
| | 282 | |
| | 283 | if (specular >= 255) |
| | 284 | specular = 255; |
| | 285 | |
| | 286 | /* KJL 12:41:54 05/10/98 - red/green swapped, whilst testing colours */ |
| | 287 | renderVertexPtr->R = ColourIntensityArray[vertexNumber].R = 0; |
| | 288 | renderVertexPtr->B = ColourIntensityArray[vertexNumber].B = blueI; |
| | 289 | renderVertexPtr->G = ColourIntensityArray[vertexNumber].G = redI/2; |
| | 290 | |
| | 291 | renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR = specular; |
| | 292 | renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG = specular; |
| | 293 | renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB = specular; |
| | 294 | |
| | 295 | ColourIntensityArray[vertexNumber].Stamp = ObjectCounter; |
| | 296 | } |
| | 297 | } |
| | 298 | |
| | 299 | static void VertexIntensity_Pred_SeeAliens(RENDERVERTEX *renderVertexPtr) |
| | 300 | { |
| | 301 | int vertexNumber = *VertexNumberPtr; |
| | 302 | |
| | 303 | if(ColourIntensityArray[vertexNumber].Stamp == ObjectCounter) |
| | 304 | { |
| | 305 | renderVertexPtr->R = ColourIntensityArray[vertexNumber].R; |
| | 306 | renderVertexPtr->G = ColourIntensityArray[vertexNumber].G; |
| | 307 | renderVertexPtr->B = ColourIntensityArray[vertexNumber].B; |
| | 308 | renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR; |
| | 309 | renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG; |
| | 310 | renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB; |
| | 311 | } |
| | 312 | else |
| | 313 | { |
| | 314 | int redI = 0,specular = 0; |
| | 315 | int blueI = ONE_FIXED/2; |
| | 316 | |
| | 317 | ColourIntensityArray[vertexNumber].Stamp = ObjectCounter; |
| | 318 | |
| | 319 | { |
| | 320 | VECTORCH *vertexPtr = ((VECTORCH *)Global_ShapePoints) + vertexNumber; |
| | 321 | VECTORCH vertexToLight; |
| | 322 | int i; |
| | 323 | |
| | 324 | for(i=0; i < NumLightSourcesForObject; i++) |
| | 325 | { |
| | 326 | LIGHTBLOCK *lptr = LightSourcesForObject[i]; |
| | 327 | |
| | 328 | if (lptr->LightFlags & LFlag_PreLitSource) |
| | 329 | continue; |
| | 330 | |
| | 331 | vertexToLight.vx = lptr->LocalLP.vx - vertexPtr->vx; |
| | 332 | vertexToLight.vy = lptr->LocalLP.vy - vertexPtr->vy; |
| | 333 | vertexToLight.vz = lptr->LocalLP.vz - vertexPtr->vz; |
| | 334 | |
| | 335 | int distanceToLight = Approximate3dMagnitude(&vertexToLight); |
| | 336 | |
| | 337 | if(distanceToLight < lptr->LightRange) |
| | 338 | { |
| | 339 | int idot = MUL_FIXED(lptr->LightRange-distanceToLight,lptr->BrightnessOverRange); |
| | 340 | |
| | 341 | redI += idot; |
| | 342 | |
| | 343 | if(lptr->LightFlags & LFlag_Electrical) |
| | 344 | specular += idot; |
| | 345 | } |
| | 346 | } |
| | 347 | } |
| | 348 | |
| | 349 | redI >>=11; |
| | 350 | |
| | 351 | if(redI > 255) |
| | 352 | redI = 255; |
| | 353 | |
| | 354 | renderVertexPtr->G = ColourIntensityArray[vertexNumber].G = redI; |
| | 355 | |
| | 356 | if (renderVertexPtr->Z > 5000) |
| | 357 | { |
| | 358 | int a = renderVertexPtr->Z - 5000; |
| | 359 | |
| | 360 | if (a > 4096) |
| | 361 | blueI = (blueI*4096)/a; |
| | 362 | } |
| | 363 | |
| | 364 | /* KJL 12:41:54 05/10/98 - red/green swapped, whilst testing colours */ |
| | 365 | blueI >>= 9; |
| | 366 | renderVertexPtr->R = ColourIntensityArray[vertexNumber].R = blueI; |
| | 367 | renderVertexPtr->B = ColourIntensityArray[vertexNumber].B = 0; |
| | 368 | |
| | 369 | specular >>=10; |
| | 370 | |
| | 371 | if(specular > 255) |
| | 372 | specular = 255; |
| | 373 | |
| | 374 | renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR = specular; |
| | 375 | renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG = specular; |
| | 376 | renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB = specular; |
| | 377 | } |
| | 378 | } |
| | 379 | |
| | 380 | static void VertexIntensity_Pred_SeePredatorTech(RENDERVERTEX *renderVertexPtr) |
| | 381 | { |
| | 382 | int vertexNumber = *VertexNumberPtr; |
| | 383 | |
| | 384 | if(ColourIntensityArray[vertexNumber].Stamp == ObjectCounter) |
| | 385 | { |
| | 386 | renderVertexPtr->R = ColourIntensityArray[vertexNumber].R; |
| | 387 | renderVertexPtr->G = ColourIntensityArray[vertexNumber].G; |
| | 388 | renderVertexPtr->B = ColourIntensityArray[vertexNumber].B; |
| | 389 | renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR; |
| | 390 | renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG; |
| | 391 | renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB; |
| | 392 | } |
| | 393 | else |
| | 394 | { |
| | 395 | int redI = 0; |
| | 396 | int blueI = ONE_FIXED-1; |
| | 397 | |
| | 398 | ColourIntensityArray[vertexNumber].Stamp = ObjectCounter; |
| | 399 | |
| | 400 | { |
| | 401 | VECTORCH *vertexPtr = ((VECTORCH *)Global_ShapePoints) + vertexNumber; |
| | 402 | VECTORCH vertexToLight; |
| | 403 | int i; |
| | 404 | |
| | 405 | for(i=0; i < NumLightSourcesForObject; i++) |
| | 406 | { |
| | 407 | LIGHTBLOCK *lptr = LightSourcesForObject[i]; |
| | 408 | |
| | 409 | if (lptr->LightFlags & LFlag_PreLitSource) |
| | 410 | continue; |
| | 411 | |
| | 412 | vertexToLight.vx = lptr->LocalLP.vx - vertexPtr->vx; |
| | 413 | vertexToLight.vy = lptr->LocalLP.vy - vertexPtr->vy; |
| | 414 | vertexToLight.vz = lptr->LocalLP.vz - vertexPtr->vz; |
| | 415 | |
| | 416 | int distanceToLight = Approximate3dMagnitude(&vertexToLight); |
| | 417 | |
| | 418 | if(distanceToLight < lptr->LightRange) |
| | 419 | redI += MUL_FIXED(lptr->LightRange - distanceToLight, lptr->BrightnessOverRange); |
| | 420 | } |
| | 421 | } |
| | 422 | |
| | 423 | if (renderVertexPtr->Z > 5000) |
| | 424 | { |
| | 425 | int a = (renderVertexPtr->Z - 5000); |
| | 426 | |
| | 427 | if (a > 4096) |
| | 428 | blueI = (blueI*4096)/a; |
| | 429 | } |
| | 430 | |
| | 431 | blueI >>=8; |
| | 432 | |
| | 433 | redI >>=9; |
| | 434 | |
| | 435 | if (redI > 255) |
| | 436 | redI = 255; |
| | 437 | |
| | 438 | /* KJL 12:41:54 05/10/98 - red/green swapped, whilst testing colours */ |
| | 439 | renderVertexPtr->R = ColourIntensityArray[vertexNumber].R = 255; |
| | 440 | renderVertexPtr->B = ColourIntensityArray[vertexNumber].B = 255; |
| | 441 | renderVertexPtr->G = ColourIntensityArray[vertexNumber].G = blueI; |
| | 442 | |
| | 443 | renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR = 255; |
| | 444 | renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG = redI; |
| | 445 | renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB = 255; |
| | 446 | } |
| | 447 | } |
| | 448 | |
| | 449 | static void VertexIntensity_ImageIntensifier(RENDERVERTEX *renderVertexPtr) |
| | 450 | { |
| | 451 | int vertexNumber = *VertexNumberPtr; |
| | 452 | |
| | 453 | if(ColourIntensityArray[vertexNumber].Stamp == ObjectCounter) |
| | 454 | { |
| | 455 | renderVertexPtr->R = ColourIntensityArray[vertexNumber].R; |
| | 456 | renderVertexPtr->G = ColourIntensityArray[vertexNumber].G; |
| | 457 | renderVertexPtr->B = ColourIntensityArray[vertexNumber].B; |
| | 458 | renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR; |
| | 459 | renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG; |
| | 460 | renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB; |
| | 461 | } |
| | 462 | else |
| | 463 | { |
| | 464 | int specular = 0; |
| | 465 | |
| | 466 | ColourIntensityArray[vertexNumber].Stamp = ObjectCounter; |
| | 467 | |
| | 468 | { |
| | 469 | VECTORCH *vertexNormalPtr = ((VECTORCH *)Global_ShapeVNormals) + vertexNumber; |
| | 470 | VECTORCH *vertexPtr = ((VECTORCH *)Global_ShapePoints) + vertexNumber; |
| | 471 | VECTORCH vertexToLight; |
| | 472 | int distanceToLight, i; |
| | 473 | |
| | 474 | for(i=0; i < NumLightSourcesForObject; i++) |
| | 475 | { |
| | 476 | LIGHTBLOCK *lptr = LightSourcesForObject[i]; |
| | 477 | |
| | 478 | vertexToLight.vx = lptr->LocalLP.vx - vertexPtr->vx; |
| | 479 | vertexToLight.vy = lptr->LocalLP.vy - vertexPtr->vy; |
| | 480 | vertexToLight.vz = lptr->LocalLP.vz - vertexPtr->vz; |
| | 481 | |
| | 482 | { |
| | 483 | int dx = abs(vertexToLight.vx); |
| | 484 | int dy = abs(vertexToLight.vy); |
| | 485 | int dz = abs(vertexToLight.vz); |
| | 486 | |
| | 487 | if (dx > dy) |
| | 488 | { |
| | 489 | if (dx > dz) |
| | 490 | distanceToLight = dx + ((dy+dz)>>2); |
| | 491 | else |
| | 492 | distanceToLight = dz + ((dy+dx)>>2); |
| | 493 | } |
| | 494 | else |
| | 495 | { |
| | 496 | if (dy > dz) |
| | 497 | distanceToLight = dy + ((dx+dz)>>2); |
| | 498 | else |
| | 499 | distanceToLight = dz + ((dx+dy)>>2); |
| | 500 | } |
| | 501 | } |
| | 502 | |
| | 503 | if(distanceToLight < lptr->LightRange) |
| | 504 | { |
| | 505 | int idot = MUL_FIXED(lptr->LightRange-distanceToLight, lptr->BrightnessOverRange); |
| | 506 | |
| | 507 | if(distanceToLight > 0) |
| | 508 | { |
| | 509 | int dotproduct = MUL_FIXED(vertexNormalPtr->vx,vertexToLight.vx) |
| | 510 | + MUL_FIXED(vertexNormalPtr->vy,vertexToLight.vy) |
| | 511 | + MUL_FIXED(vertexNormalPtr->vz,vertexToLight.vz); |
| | 512 | |
| | 513 | if(dotproduct > 0) |
| | 514 | idot = WideMulNarrowDiv(idot,dotproduct,distanceToLight) + idot/4; |
| | 515 | else |
| | 516 | idot /= 4; |
| | 517 | } |
| | 518 | |
| | 519 | if(idot < 0) |
| | 520 | { |
| | 521 | assert(idot >= 0); |
| | 522 | } |
| | 523 | |
| | 524 | specular += idot; |
| | 525 | } |
| | 526 | } |
| | 527 | } |
| | 528 | |
| | 529 | int greenI = 255; |
| | 530 | |
| | 531 | if (renderVertexPtr->Z > 5000) |
| | 532 | { |
| | 533 | int a = renderVertexPtr->Z - 5000; |
| | 534 | |
| | 535 | if (a > 4096) |
| | 536 | greenI = (greenI*4096)/a; |
| | 537 | } |
| | 538 | |
| | 539 | renderVertexPtr->G = greenI; |
| | 540 | ColourIntensityArray[vertexNumber].G = greenI; |
| | 541 | |
| | 542 | renderVertexPtr->R = ColourIntensityArray[vertexNumber].R = 0; |
| | 543 | renderVertexPtr->B = ColourIntensityArray[vertexNumber].B = 0; |
| | 544 | |
| | 545 | specular >>= 7; |
| | 546 | |
| | 547 | if (specular > 254) |
| | 548 | specular = 254; |
| | 549 | |
| | 550 | assert(specular >= 0 && specular <= 254); |
| | 551 | renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR = specular; |
| | 552 | renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG = specular; |
| | 553 | renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB = specular; |
| | 554 | } |
| | 555 | } |
| | 556 | |
| | 557 | static void VertexIntensity_Alien_Sense(RENDERVERTEX *renderVertexPtr) |
| | 558 | { |
| | 559 | int vertexNumber = *VertexNumberPtr; |
| | 560 | renderVertexPtr->SpecularR = renderVertexPtr->SpecularG = renderVertexPtr->SpecularB = 0; |
| | 561 | |
| | 562 | if(ColourIntensityArray[vertexNumber].Stamp == ObjectCounter) |
| | 563 | { |
| | 564 | renderVertexPtr->R = ColourIntensityArray[vertexNumber].R; |
| | 565 | renderVertexPtr->G = ColourIntensityArray[vertexNumber].G; |
| | 566 | renderVertexPtr->B = ColourIntensityArray[vertexNumber].B; |
| | 567 | } |
| | 568 | else |
| | 569 | { |
| | 570 | int intensity = 255; |
| | 571 | ColourIntensityArray[vertexNumber].Stamp = ObjectCounter; |
| | 572 | |
| | 573 | if (renderVertexPtr->Z > 5000) |
| | 574 | { |
| | 575 | int a = renderVertexPtr->Z - 5000; |
| | 576 | |
| | 577 | if (a > 1024) |
| | 578 | intensity = (intensity*1024)/a; |
| | 579 | } |
| | 580 | |
| | 581 | renderVertexPtr->R = ColourIntensityArray[vertexNumber].R = intensity; |
| | 582 | renderVertexPtr->G = ColourIntensityArray[vertexNumber].G = intensity; |
| | 583 | renderVertexPtr->B = ColourIntensityArray[vertexNumber].B = intensity; |
| | 584 | } |
| | 585 | } |
| | 586 | |
| | 587 | static void VertexIntensity_Standard_Opt(RENDERVERTEX *renderVertexPtr) |
| | 588 | { |
| | 589 | int vertexNumber = *VertexNumberPtr; |
| | 590 | |
| | 591 | if(ColourIntensityArray[vertexNumber].Stamp == ObjectCounter) |
| | 592 | { |
| | 593 | renderVertexPtr->R = ColourIntensityArray[vertexNumber].R; |
| | 594 | renderVertexPtr->G = ColourIntensityArray[vertexNumber].G; |
| | 595 | renderVertexPtr->B = ColourIntensityArray[vertexNumber].B; |
| | 596 | renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR; |
| | 597 | renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG; |
| | 598 | renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB; |
| | 599 | } |
| | 600 | else |
| | 601 | { |
| | 602 | int redI = 0,greenI = 0,blueI = 0; |
| | 603 | int specularR = 0,specularG = 0,specularB = 0; |
| | 604 | |
| | 605 | ColourIntensityArray[vertexNumber].Stamp = ObjectCounter; |
| | 606 | |
| | 607 | { |
| | 608 | VECTORCH *vertexNormalPtr = ((VECTORCH *)Global_ShapeVNormals) + vertexNumber; |
| | 609 | VECTORCH *vertexPtr = ((VECTORCH *)Global_ShapePoints) + vertexNumber; |
| | 610 | VECTORCH vertexToLight; |
| | 611 | int distanceToLight, i; |
| | 612 | |
| | 613 | if(Global_ShapeHeaderPtr->shapeflags & ShapeFlag_PreLit) |
| | 614 | { |
| | 615 | unsigned int packedI = Global_ShapeHeaderPtr->prelighting[vertexNumber]; |
| | 616 | blueI = (packedI & 255) * 257; |
| | 617 | |
| | 618 | packedI >>= 8; |
| | 619 | greenI = (packedI & 255) * 257; |
| | 620 | |
| | 621 | packedI >>= 8; |
| | 622 | redI = (packedI & 255) * 257; |
| | 623 | } |
| | 624 | |
| | 625 | for(i = 0; i < NumLightSourcesForObject; i++) |
| | 626 | { |
| | 627 | LIGHTBLOCK *lptr = LightSourcesForObject[i]; |
| | 628 | |
| | 629 | vertexToLight.vx = lptr->LocalLP.vx - vertexPtr->vx; |
| | 630 | vertexToLight.vy = lptr->LocalLP.vy - vertexPtr->vy; |
| | 631 | vertexToLight.vz = lptr->LocalLP.vz - vertexPtr->vz; |
| | 632 | |
| | 633 | { |
| | 634 | int dx = abs(vertexToLight.vx); |
| | 635 | int dy = abs(vertexToLight.vy); |
| | 636 | int dz = abs(vertexToLight.vz); |
| | 637 | |
| | 638 | if (dx > dy) |
| | 639 | { |
| | 640 | if (dx > dz) |
| | 641 | distanceToLight = dx + ((dy+dz)>>2); |
| | 642 | else |
| | 643 | distanceToLight = dz + ((dy+dx)>>2); |
| | 644 | } |
| | 645 | else |
| | 646 | { |
| | 647 | if (dy > dz) |
| | 648 | distanceToLight = dy + ((dx+dz)>>2); |
| | 649 | else |
| | 650 | distanceToLight = dz + ((dx+dy)>>2); |
| | 651 | } |
| | 652 | } |
| | 653 | |
| | 654 | if(distanceToLight < lptr->LightRange) |
| | 655 | { |
| | 656 | int idot = MUL_FIXED(lptr->LightRange-distanceToLight, lptr->BrightnessOverRange); |
| | 657 | |
| | 658 | if(distanceToLight > 0) |
| | 659 | { |
| | 660 | int dotproduct = MUL_FIXED(vertexNormalPtr->vx,vertexToLight.vx) |
| | 661 | + MUL_FIXED(vertexNormalPtr->vy,vertexToLight.vy) |
| | 662 | + MUL_FIXED(vertexNormalPtr->vz,vertexToLight.vz); |
| | 663 | |
| | 664 | if(dotproduct > 0) |
| | 665 | idot = (WideMulNarrowDiv(idot,dotproduct,distanceToLight)+idot/4)/2; |
| | 666 | else |
| | 667 | idot /= 8; |
| | 668 | } |
| | 669 | |
| | 670 | int r = MUL_FIXED(idot,lptr->RedScale); |
| | 671 | int g = MUL_FIXED(idot,lptr->GreenScale); |
| | 672 | int b = MUL_FIXED(idot,lptr->BlueScale); |
| | 673 | |
| | 674 | redI += r; |
| | 675 | greenI += g; |
| | 676 | blueI += b; |
| | 677 | |
| | 678 | if( !(lptr->LightFlags & LFlag_PreLitSource) && !(lptr->LightFlags & LFlag_NoSpecular) ) |
| | 679 | { |
| | 680 | specularR += r; |
| | 681 | specularG += g; |
| | 682 | specularB += b; |
| | 683 | } |
| | 684 | } |
| | 685 | } |
| | 686 | } |
| | 687 | |
| | 688 | if(Global_ODB_Ptr->SpecialFXFlags & SFXFLAG_ONFIRE) |
| | 689 | { |
| | 690 | specularR >>= 2; |
| | 691 | specularG >>= 2; |
| | 692 | specularB >>= 2; |
| | 693 | |
| | 694 | redI >>= 1; |
| | 695 | greenI >>= 1; |
| | 696 | blueI >>= 1; |
| | 697 | } |
| | 698 | |
| | 699 | /* Intensity for Textures */ |
| | 700 | redI >>= 8; |
| | 701 | |
| | 702 | if(redI > 255) |
| | 703 | redI = 255; |
| | 704 | |
| | 705 | renderVertexPtr->R = ColourIntensityArray[vertexNumber].R = redI; |
| | 706 | |
| | 707 | greenI >>= 8; |
| | 708 | |
| | 709 | if(greenI > 255) |
| | 710 | greenI = 255; |
| | 711 | |
| | 712 | renderVertexPtr->G = ColourIntensityArray[vertexNumber].G = greenI; |
| | 713 | |
| | 714 | blueI >>= 8; |
| | 715 | |
| | 716 | if(blueI > 255) |
| | 717 | blueI = 255; |
| | 718 | |
| | 719 | renderVertexPtr->B = ColourIntensityArray[vertexNumber].B = blueI; |
| | 720 | |
| | 721 | specularR >>= 10; |
| | 722 | |
| | 723 | if(specularR > 255) |
| | 724 | specularR = 255; |
| | 725 | |
| | 726 | renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR = specularR; |
| | 727 | |
| | 728 | specularG >>= 10; |
| | 729 | |
| | 730 | if(specularG > 255) |
| | 731 | specularG = 255; |
| | 732 | |
| | 733 | renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG = specularG; |
| | 734 | |
| | 735 | specularB >>= 10; |
| | 736 | |
| | 737 | if(specularB > 255) |
| | 738 | specularB = 255; |
| | 739 | |
| | 740 | renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB = specularB; |
| | 741 | } |
| | 742 | } |
| | 743 | |
| | 744 | static void VertexIntensity_FullBright(RENDERVERTEX *renderVertexPtr) |
| | 745 | { |
| | 746 | int vertexNumber = *VertexNumberPtr; |
| | 747 | renderVertexPtr->R = ColourIntensityArray[vertexNumber].R = 255; |
| | 748 | renderVertexPtr->G = ColourIntensityArray[vertexNumber].G = 255; |
| | 749 | renderVertexPtr->B = ColourIntensityArray[vertexNumber].B = 255; |
| | 750 | |
| | 751 | renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR = 0; |
| | 752 | renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG = 0; |
| | 753 | renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB = 0; |
| | 754 | } |
| | 755 | |
| | 756 | static void VertexIntensity_DiscoInferno(RENDERVERTEX *renderVertexPtr) |
| | 757 | { |
| | 758 | int vertexNumber = *VertexNumberPtr; |
| | 759 | |
| | 760 | if(ColourIntensityArray[vertexNumber].Stamp == ObjectCounter) |
| | 761 | { |
| | 762 | renderVertexPtr->R = ColourIntensityArray[vertexNumber].R; |
| | 763 | renderVertexPtr->G = ColourIntensityArray[vertexNumber].G; |
| | 764 | renderVertexPtr->B = ColourIntensityArray[vertexNumber].B; |
| | 765 | renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR; |
| | 766 | renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG; |
| | 767 | renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB; |
| | 768 | } |
| | 769 | else |
| | 770 | { |
| | 771 | int redI = 0,greenI = 0,blueI = 0; |
| | 772 | int specularR = 0,specularG = 0,specularB = 0; |
| | 773 | |
| | 774 | ColourIntensityArray[vertexNumber].Stamp = ObjectCounter; |
| | 775 | |
| | 776 | { |
| | 777 | VECTORCH *vertexNormalPtr = ((VECTORCH *)Global_ShapeVNormals) + vertexNumber; |
| | 778 | VECTORCH *vertexPtr = ((VECTORCH *)Global_ShapePoints) + vertexNumber; |
| | 779 | VECTORCH vertexToLight; |
| | 780 | int distanceToLight, i; |
| | 781 | |
| | 782 | if(Global_ShapeHeaderPtr->shapeflags & ShapeFlag_PreLit) |
| | 783 | { |
| | 784 | unsigned int packedI = Global_ShapeHeaderPtr->prelighting[vertexNumber]; |
| | 785 | blueI = (packedI & 255) * 257; |
| | 786 | |
| | 787 | packedI >>= 8; |
| | 788 | greenI = (packedI & 255) * 257; |
| | 789 | |
| | 790 | packedI >>= 8; |
| | 791 | redI = (packedI & 255) * 257; |
| | 792 | } |
| | 793 | |
| | 794 | for(i=0; i < NumLightSourcesForObject; i++) |
| | 795 | { |
| | 796 | LIGHTBLOCK *lptr = LightSourcesForObject[i]; |
| | 797 | |
| | 798 | vertexToLight.vx = lptr->LocalLP.vx - vertexPtr->vx; |
| | 799 | vertexToLight.vy = lptr->LocalLP.vy - vertexPtr->vy; |
| | 800 | vertexToLight.vz = lptr->LocalLP.vz - vertexPtr->vz; |
| | 801 | |
| | 802 | { |
| | 803 | int dx = abs(vertexToLight.vx); |
| | 804 | int dy = abs(vertexToLight.vy); |
| | 805 | int dz = abs(vertexToLight.vz); |
| | 806 | |
| | 807 | if (dx > dy) |
| | 808 | { |
| | 809 | if (dx > dz) |
| | 810 | distanceToLight = dx + ((dy+dz)>>2); |
| | 811 | else |
| | 812 | distanceToLight = dz + ((dy+dx)>>2); |
| | 813 | } |
| | 814 | else |
| | 815 | { |
| | 816 | if (dy > dz) |
| | 817 | distanceToLight = dy + ((dx+dz)>>2); |
| | 818 | else |
| | 819 | distanceToLight = dz + ((dx+dy)>>2); |
| | 820 | } |
| | 821 | } |
| | 822 | |
| | 823 | if(distanceToLight < lptr->LightRange) |
| | 824 | { |
| | 825 | int idot = MUL_FIXED(lptr->LightRange-distanceToLight, lptr->BrightnessOverRange); |
| | 826 | |
| | 827 | if(distanceToLight > 0) |
| | 828 | { |
| | 829 | int dotproduct = MUL_FIXED(vertexNormalPtr->vx,vertexToLight.vx) |
| | 830 | + MUL_FIXED(vertexNormalPtr->vy,vertexToLight.vy) |
| | 831 | + MUL_FIXED(vertexNormalPtr->vz,vertexToLight.vz); |
| | 832 | |
| | 833 | if(dotproduct > 0) |
| | 834 | idot = (WideMulNarrowDiv(idot,dotproduct,distanceToLight)+idot/4)/2; |
| | 835 | else |
| | 836 | idot /= 8; |
| | 837 | } |
| | 838 | |
| | 839 | int r = MUL_FIXED(idot,lptr->RedScale); |
| | 840 | int g = MUL_FIXED(idot,lptr->GreenScale); |
| | 841 | int b = MUL_FIXED(idot,lptr->BlueScale); |
| | 842 | |
| | 843 | redI += r; |
| | 844 | greenI += g; |
| | 845 | blueI += b; |
| | 846 | |
| | 847 | if(!(lptr->LightFlags & LFlag_PreLitSource) && !(lptr->LightFlags & LFlag_NoSpecular)) |
| | 848 | { |
| | 849 | specularR += r; |
| | 850 | specularG += g; |
| | 851 | specularB += b; |
| | 852 | } |
| | 853 | } |
| | 854 | } |
| | 855 | } |
| | 856 | |
| | 857 | if(Global_ODB_Ptr->SpecialFXFlags & SFXFLAG_ONFIRE) |
| | 858 | { |
| | 859 | specularR >>= 2; |
| | 860 | specularG >>= 2; |
| | 861 | specularB >>= 2; |
| | 862 | |
| | 863 | redI >>= 1; |
| | 864 | greenI >>= 1; |
| | 865 | blueI >>= 1; |
| | 866 | } |
| | 867 | |
| | 868 | { |
| | 869 | int i = redI + greenI + blueI; |
| | 870 | int si = specularR + specularG + specularB; |
| | 871 | |
| | 872 | VECTORCH vertex = *(((VECTORCH *)Global_ShapePoints)+vertexNumber); |
| | 873 | vertex.vx += Global_ODB_Ptr->ObWorld.vx; |
| | 874 | vertex.vy += Global_ODB_Ptr->ObWorld.vy; |
| | 875 | vertex.vz += Global_ODB_Ptr->ObWorld.vz; |
| | 876 | |
| | 877 | int r = GetSin((vertex.vx+CloakingPhase)&4095); |
| | 878 | r = MUL_FIXED(r,r); |
| | 879 | redI = MUL_FIXED(r,i); |
| | 880 | specularR = MUL_FIXED(r,si); |
| | 881 | |
| | 882 | int g = GetSin((vertex.vy+CloakingPhase/2)&4095); |
| | 883 | g = MUL_FIXED(g,g); |
| | 884 | greenI = MUL_FIXED(g,i); |
| | 885 | specularG = MUL_FIXED(g,si); |
| | 886 | |
| | 887 | int b = GetSin((vertex.vz+CloakingPhase*3)&4095); |
| | 888 | b = MUL_FIXED(b,b); |
| | 889 | blueI = MUL_FIXED(b,i); |
| | 890 | specularB = MUL_FIXED(b,si); |
| | 891 | } |
| | 892 | |
| | 893 | /* Intensity for Textures */ |
| | 894 | redI >>= 8; |
| | 895 | |
| | 896 | if(redI > 255) |
| | 897 | redI = 255; |
| | 898 | |
| | 899 | renderVertexPtr->R = ColourIntensityArray[vertexNumber].R = redI; |
| | 900 | |
| | 901 | greenI >>= 8; |
| | 902 | |
| | 903 | if(greenI > 255) |
| | 904 | greenI = 255; |
| | 905 | |
| | 906 | renderVertexPtr->G = ColourIntensityArray[vertexNumber].G = greenI; |
| | 907 | |
| | 908 | blueI >>= 8; |
| | 909 | |
| | 910 | if(blueI > 255) |
| | 911 | blueI = 255; |
| | 912 | |
| | 913 | renderVertexPtr->B = ColourIntensityArray[vertexNumber].B = blueI; |
| | 914 | |
| | 915 | specularR >>= 10; |
| | 916 | |
| | 917 | if(specularR > 255) |
| | 918 | specularR = 255; |
| | 919 | |
| | 920 | renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR = specularR; |
| | 921 | |
| | 922 | specularG >>= 10; |
| | 923 | |
| | 924 | if(specularG > 255) |
| | 925 | specularG = 255; |
| | 926 | |
| | 927 | renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG = specularG; |
| | 928 | |
| | 929 | specularB >>= 10; |
| | 930 | |
| | 931 | if(specularB > 255) |
| | 932 | specularB = 255; |
| | 933 | |
| | 934 | renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB = specularB; |
| | 935 | } |
| | 936 | } |
| | 937 | |
| | 938 | static void VertexIntensity_Underwater(RENDERVERTEX *renderVertexPtr) |
| | 939 | { |
| | 940 | int vertexNumber = *VertexNumberPtr; |
| | 941 | |
| | 942 | if(ColourIntensityArray[vertexNumber].Stamp == ObjectCounter) |
| | 943 | { |
| | 944 | renderVertexPtr->R = ColourIntensityArray[vertexNumber].R; |
| | 945 | renderVertexPtr->G = ColourIntensityArray[vertexNumber].G; |
| | 946 | renderVertexPtr->B = ColourIntensityArray[vertexNumber].B; |
| | 947 | renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR; |
| | 948 | renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG; |
| | 949 | renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB; |
| | 950 | } |
| | 951 | else |
| | 952 | { |
| | 953 | int redI = 0, greenI = 0, blueI = 0; |
| | 954 | int specularR = 0,specularG = 0,specularB = 0; |
| | 955 | |
| | 956 | ColourIntensityArray[vertexNumber].Stamp = ObjectCounter; |
| | 957 | |
| | 958 | { |
| | 959 | VECTORCH *vertexNormalPtr = ((VECTORCH *)Global_ShapeVNormals) + vertexNumber; |
| | 960 | VECTORCH *vertexPtr = ((VECTORCH *)Global_ShapePoints) + vertexNumber; |
| | 961 | VECTORCH vertexToLight; |
| | 962 | int distanceToLight, i; |
| | 963 | |
| | 964 | if(Global_ShapeHeaderPtr->shapeflags & ShapeFlag_PreLit) |
| | 965 | { |
| | 966 | unsigned int packedI = Global_ShapeHeaderPtr->prelighting[vertexNumber]; |
| | 967 | blueI = (packedI & 255) * 257; |
| | 968 | |
| | 969 | packedI >>= 8; |
| | 970 | greenI = (packedI & 255) * 257; |
| | 971 | |
| | 972 | packedI >>= 8; |
| | 973 | redI = (packedI & 255) * 257; |
| | 974 | } |
| | 975 | |
| | 976 | for(i=0; i < NumLightSourcesForObject; i++) |
| | 977 | { |
| | 978 | LIGHTBLOCK *lptr = LightSourcesForObject[i]; |
| | 979 | |
| | 980 | vertexToLight.vx = lptr->LocalLP.vx - vertexPtr->vx; |
| | 981 | vertexToLight.vy = lptr->LocalLP.vy - vertexPtr->vy; |
| | 982 | vertexToLight.vz = lptr->LocalLP.vz - vertexPtr->vz; |
| | 983 | |
| | 984 | { |
| | 985 | int dx = abs(vertexToLight.vx); |
| | 986 | int dy = abs(vertexToLight.vy); |
| | 987 | int dz = abs(vertexToLight.vz); |
| | 988 | |
| | 989 | if (dx > dy) |
| | 990 | { |
| | 991 | if (dx > dz) |
| | 992 | distanceToLight = dx + ((dy+dz)>>2); |
| | 993 | else |
| | 994 | distanceToLight = dz + ((dy+dx)>>2); |
| | 995 | } |
| | 996 | else |
| | 997 | { |
| | 998 | if (dy > dz) |
| | 999 | distanceToLight = dy + ((dx+dz)>>2); |
| | 1000 | else |
| | 1001 | distanceToLight = dz + ((dx+dy)>>2); |
| | 1002 | } |
| | 1003 | } |
| | 1004 | |
| | 1005 | if(distanceToLight < lptr->LightRange) |
| | 1006 | { |
| | 1007 | int idot = MUL_FIXED(lptr->LightRange-distanceToLight,lptr->BrightnessOverRange); |
| | 1008 | |
| | 1009 | if(distanceToLight > 0) |
| | 1010 | { |
| | 1011 | int dotproduct = MUL_FIXED(vertexNormalPtr->vx,vertexToLight.vx) |
| | 1012 | + MUL_FIXED(vertexNormalPtr->vy,vertexToLight.vy) |
| | 1013 | + MUL_FIXED(vertexNormalPtr->vz,vertexToLight.vz); |
| | 1014 | |
| | 1015 | if(dotproduct > 0) |
| | 1016 | idot = (WideMulNarrowDiv(idot,dotproduct,distanceToLight)+idot/4)/2; |
| | 1017 | else |
| | 1018 | idot /= 8; |
| | 1019 | } |
| | 1020 | |
| | 1021 | int r = MUL_FIXED(idot,lptr->RedScale); |
| | 1022 | int g = MUL_FIXED(idot,lptr->GreenScale); |
| | 1023 | int b = MUL_FIXED(idot,lptr->BlueScale); |
| | 1024 | |
| | 1025 | redI += r; |
| | 1026 | greenI += g; |
| | 1027 | blueI += b; |
| | 1028 | |
| | 1029 | if(!(lptr->LightFlags & LFlag_PreLitSource) && !(lptr->LightFlags & LFlag_NoSpecular) ) |
| | 1030 | { |
| | 1031 | specularR += r; |
| | 1032 | specularG += g; |
| | 1033 | specularB += b; |
| | 1034 | } |
| | 1035 | } |
| | 1036 | } |
| | 1037 | } |
| | 1038 | |
| | 1039 | if(Global_ODB_Ptr->SpecialFXFlags & SFXFLAG_ONFIRE) |
| | 1040 | { |
| | 1041 | specularR >>= 2; |
| | 1042 | specularG >>= 2; |
| | 1043 | specularB >>= 2; |
| | 1044 | |
| | 1045 | redI >>= 1; |
| | 1046 | greenI >>= 1; |
| | 1047 | blueI >>= 1; |
| | 1048 | } |
| | 1049 | |
| | 1050 | if (specularB < renderVertexPtr->Z*4) |
| | 1051 | specularB = renderVertexPtr->Z*4; |
| | 1052 | |
| | 1053 | /* Intensity for Textures */ |
| | 1054 | redI >>= 8; |
| | 1055 | |
| | 1056 | if(redI > 255) |
| | 1057 | redI = 255; |
| | 1058 | |
| | 1059 | renderVertexPtr->R = ColourIntensityArray[vertexNumber].R = redI; |
| | 1060 | |
| | 1061 | greenI >>= 8; |
| | 1062 | |
| | 1063 | if(greenI > 255) |
| | 1064 | greenI = 255; |
| | 1065 | |
| | 1066 | renderVertexPtr->G = ColourIntensityArray[vertexNumber].G = greenI; |
| | 1067 | |
| | 1068 | blueI >>= 8; |
| | 1069 | |
| | 1070 | if(blueI > 255) |
| | 1071 | blueI = 255; |
| | 1072 | |
| | 1073 | renderVertexPtr->B = ColourIntensityArray[vertexNumber].B = blueI; |
| | 1074 | |
| | 1075 | specularR >>= 10; |
| | 1076 | |
| | 1077 | if(specularR > 255) |
| | 1078 | specularR = 255; |
| | 1079 | |
| | 1080 | renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR = specularR; |
| | 1081 | |
| | 1082 | specularG >>= 10; |
| | 1083 | |
| | 1084 | if(specularG > 255) |
| | 1085 | specularG = 255; |
| | 1086 | |
| | 1087 | renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG = specularG; |
| | 1088 | |
| | 1089 | specularB >>= 10; |
| | 1090 | |
| | 1091 | if(specularB > 255) |
| | 1092 | specularB = 255; |
| | 1093 | |
| | 1094 | renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB = specularB; |
| | 1095 | } |
| | 1096 | } |
| | 1097 | |
| | 1098 | static int PolygonWithinFrustrum(POLYHEADER *polyPtr) |
| | 1099 | { |
| | 1100 | int* vertexNumberPtr = &polyPtr->Poly1stPt; |
| | 1101 | |
| | 1102 | if (polyPtr->PolyFlags & iflag_notvis) |
| | 1103 | return 0; |
| | 1104 | |
| | 1105 | char inFrustrumFlag = 0; |
| | 1106 | char noClippingFlag = INSIDE_FRUSTRUM; |
| | 1107 | RenderPolygon.NumberOfVertices = 0; |
| | 1108 | |
| | 1109 | while(*vertexNumberPtr != -1) |
| | 1110 | { |
| | 1111 | int vertexNumber = *vertexNumberPtr++; |
| | 1112 | |
| | 1113 | inFrustrumFlag |= FrustrumFlagForVertex[vertexNumber]; |
| | 1114 | noClippingFlag &= FrustrumFlagForVertex[vertexNumber]; |
| | 1115 | |
| | 1116 | /* count the number of points in the polygon; this is used for all the loops that follow */ |
| | 1117 | RenderPolygon.NumberOfVertices++; |
| | 1118 | } |
| | 1119 | |
| | 1120 | if (inFrustrumFlag != INSIDE_FRUSTRUM) |
| | 1121 | return 0; |
| | 1122 | |
| | 1123 | /* at this point we know that the poly is inside the view frustrum */ |
| | 1124 | |
| | 1125 | /* if not a sprite, test direction of poly */ |
| | 1126 | if (!(polyPtr->PolyFlags & iflag_no_bfc)) |
| | 1127 | { |
| | 1128 | VECTORCH pop; |
| | 1129 | VECTORCH *normalPtr = (VECTORCH*)(Global_ShapeNormals + polyPtr->PolyNormalIndex); |
| | 1130 | |
| | 1131 | if(Global_ODB_Ptr->ObMorphCtrl) |
| | 1132 | { |
| | 1133 | VECTORCH *shape1PointsPtr; |
| | 1134 | VECTORCH *shape2PointsPtr; |
| | 1135 | |
| | 1136 | /* Set up the morph data */ |
| | 1137 | GetMorphDisplay(&MorphDisplay, Global_ODB_Ptr); |
| | 1138 | |
| | 1139 | struct shapeheader *shape1Ptr = MorphDisplay.md_sptr1; |
| | 1140 | |
| | 1141 | switch(MorphDisplay.md_lerp) |
| | 1142 | { |
| | 1143 | case 0x0000: |
| | 1144 | { |
| | 1145 | shape1PointsPtr = (VECTORCH *)*shape1Ptr->points; |
| | 1146 | pop = shape1PointsPtr[polyPtr->Poly1stPt]; |
| | 1147 | } |
| | 1148 | break; |
| | 1149 | case 0xffff: |
| | 1150 | { |
| | 1151 | struct shapeheader* shape2Ptr = MorphDisplay.md_sptr2; |
| | 1152 | |
| | 1153 | shape2PointsPtr = (VECTORCH *)*shape2Ptr->points; |
| | 1154 | pop = shape2PointsPtr[polyPtr->Poly1stPt]; |
| | 1155 | } |
| | 1156 | break; |
| | 1157 | default: |
| | 1158 | { |
| | 1159 | struct shapeheader* shape2Ptr = MorphDisplay.md_sptr2; |
| | 1160 | |
| | 1161 | shape1PointsPtr = (VECTORCH *)(*shape1Ptr->points); |
| | 1162 | shape2PointsPtr = (VECTORCH *)(*shape2Ptr->points); |
| | 1163 | |
| | 1164 | { |
| | 1165 | VECTORCH vertex1 = shape1PointsPtr[polyPtr->Poly1stPt]; |
| | 1166 | VECTORCH vertex2 = shape2PointsPtr[polyPtr->Poly1stPt]; |
| | 1167 | |
| | 1168 | if( (vertex1.vx == vertex2.vx && vertex1.vy == vertex2.vy && vertex1.vz == vertex2.vz) ) |
| | 1169 | { |
| | 1170 | pop = vertex1; |
| | 1171 | } |
| | 1172 | else |
| | 1173 | { |
| | 1174 | /* KJL 15:27:20 05/22/97 - I've changed this to speed things up, If a vertex |
| | 1175 | component has a magnitude greater than 32768 things will go wrong. */ |
| | 1176 | pop.vx = vertex1.vx + (((vertex2.vx-vertex1.vx)*MorphDisplay.md_lerp)>>16); |
| | 1177 | pop.vy = vertex1.vy + (((vertex2.vy-vertex1.vy)*MorphDisplay.md_lerp)>>16); |
| | 1178 | pop.vz = vertex1.vz + (((vertex2.vz-vertex1.vz)*MorphDisplay.md_lerp)>>16); |
| | 1179 | } |
| | 1180 | } |
| | 1181 | } |
| | 1182 | } |
| | 1183 | } |
| | 1184 | else |
| | 1185 | { |
| | 1186 | /* Get the 1st polygon point as the POP */ |
| | 1187 | VECTORCH *pointsArray = (VECTORCH*)(Global_ShapePoints); |
| | 1188 | pop = pointsArray[polyPtr->Poly1stPt]; |
| | 1189 | } |
| | 1190 | |
| | 1191 | pop.vx -= LocalView.vx; |
| | 1192 | pop.vy -= LocalView.vy; |
| | 1193 | pop.vz -= LocalView.vz; |
| | 1194 | |
| | 1195 | if (DotProduct(&pop, normalPtr) > 0) |
| | 1196 | return 0; |
| | 1197 | } |
| | 1198 | |
| | 1199 | /* yes, we need to draw poly */ |
| | 1200 | if(noClippingFlag == INSIDE_FRUSTRUM) |
| | 1201 | { |
| | 1202 | draw_vertices = VerticesUnClipped; |
| | 1203 | return 1; |
| | 1204 | } |
| | 1205 | |
| | 1206 | return -1; |
| | 1207 | } |
| | 1208 | |
| | 1209 | static void PredatorThermalVision_ShapePipeline(struct shapeheader* shapePtr) |
| | 1210 | { |
| | 1211 | int numitems = shapePtr->numitems; |
| | 1212 | int** itemArrayPtr = shapePtr->items; |
| | 1213 | |
| | 1214 | assert(numitems); |
| | 1215 | |
| | 1216 | do |
| | 1217 | { |
| | 1218 | POLYHEADER *polyPtr = (POLYHEADER*) (*itemArrayPtr++); |
| | 1219 | |
| | 1220 | int pif = PolygonWithinFrustrum(polyPtr); |
| | 1221 | |
| | 1222 | if (pif) |
| | 1223 | { |
| | 1224 | RENDERVERTEX *renderVerticesPtr = VerticesUnClipped; |
| | 1225 | int i = RenderPolygon.NumberOfVertices; |
| | 1226 | |
| | 1227 | VertexNumberPtr = &polyPtr->Poly1stPt; |
| | 1228 | |
| | 1229 | do |
| | 1230 | { |
| | 1231 | VECTORCH *vertexPtr = &RotatedPts[*VertexNumberPtr]; |
| | 1232 | renderVerticesPtr->X = vertexPtr->vx; |
| | 1233 | renderVerticesPtr->Y = vertexPtr->vy; |
| | 1234 | renderVerticesPtr->Z = vertexPtr->vz; |
| | 1235 | |
| | 1236 | { |
| | 1237 | int alpha; |
| | 1238 | if (Global_ODB_Ptr->SpecialFXFlags & SFXFLAG_ISAFFECTEDBYHEAT) |
| | 1239 | { |
| | 1240 | int distanceFromHeatSource = 100000; |
| | 1241 | int sourceNumber = NumberOfHeatSources; |
| | 1242 | |
| | 1243 | while(sourceNumber--) |
| | 1244 | { |
| | 1245 | VECTORCH mag; |
| | 1246 | mag.vx = vertexPtr->vx - HeatSourceList[sourceNumber].Position.vx; |
| | 1247 | mag.vy = vertexPtr->vy - HeatSourceList[sourceNumber].Position.vy; |
| | 1248 | mag.vz = vertexPtr->vz - HeatSourceList[sourceNumber].Position.vz; |
| | 1249 | |
| | 1250 | int m = Approximate3dMagnitude(&mag) * 64; |
| | 1251 | |
| | 1252 | if(m < distanceFromHeatSource) |
| | 1253 | distanceFromHeatSource = m; |
| | 1254 | } |
| | 1255 | |
| | 1256 | alpha = distanceFromHeatSource + (GetSin(CloakingPhase & 4095) >> 3); |
| | 1257 | |
| | 1258 | if (alpha > 65536) |
| | 1259 | alpha = 65536; |
| | 1260 | } |
| | 1261 | else |
| | 1262 | { |
| | 1263 | alpha = 65536; |
| | 1264 | } |
| | 1265 | |
| | 1266 | { |
| | 1267 | int brightness = MUL_FIXED(MUL_FIXED(alpha, alpha), 1275); |
| | 1268 | |
| | 1269 | if (brightness < 256) |
| | 1270 | { |
| | 1271 | renderVerticesPtr->R = 255; |
| | 1272 | renderVerticesPtr->G = brightness; |
| | 1273 | renderVerticesPtr->B = 0; |
| | 1274 | } |
| | 1275 | else if (brightness < 255 + 256) |
| | 1276 | { |
| | 1277 | int b = brightness - 255; |
| | 1278 | renderVerticesPtr->R = (255-b); |
| | 1279 | renderVerticesPtr->G = 255; |
| | 1280 | renderVerticesPtr->B = 0; |
| | 1281 | } |
| | 1282 | else if (brightness < 255 * 2 + 256) |
| | 1283 | { |
| | 1284 | int b = brightness-255*2; |
| | 1285 | renderVerticesPtr->R = 0; |
| | 1286 | renderVerticesPtr->G = 255; |
| | 1287 | renderVerticesPtr->B = b; |
| | 1288 | } |
| | 1289 | else if (brightness < 255 * 3 + 256) |
| | 1290 | { |
| | 1291 | int b = brightness-255*3; |
| | 1292 | renderVerticesPtr->R = 0; |
| | 1293 | renderVerticesPtr->G = 255-b; |
| | 1294 | renderVerticesPtr->B = 255; |
| | 1295 | } |
| | 1296 | else |
| | 1297 | { |
| | 1298 | int b = brightness-255*4; |
| | 1299 | renderVerticesPtr->R = 0; |
| | 1300 | renderVerticesPtr->G = 0; |
| | 1301 | renderVerticesPtr->B = 255-b/2; |
| | 1302 | } |
| | 1303 | } |
| | 1304 | } |
| | 1305 | |
| | 1306 | renderVerticesPtr++; |
| | 1307 | VertexNumberPtr++; |
| | 1308 | |
| | 1309 | } while(--i); |
| | 1310 | |
| | 1311 | if ((pif < 0) && !ClipPolygon(RenderPolygon.NumberOfVertices)) |
| | 1312 | { |
| | 1313 | } |
| | 1314 | else |
| | 1315 | { |
| | 1316 | Polygon(draw_vertices, TRANSLUCENCY_OFF); |
| | 1317 | } |
| | 1318 | } |
| | 1319 | |
| | 1320 | } while(--numitems); |
| | 1321 | } |
| | 1322 | |
| | 1323 | /* |
| | 1324 | WideMul2NarrowDiv |
| | 1325 | |
| | 1326 | This function takes two pairs of integers, adds their 64-bit products |
| | 1327 | together, divides the summed product with another integer and then returns |
| | 1328 | the result of that divide, which is also an integer. |
| | 1329 | |
| | 1330 | */ |
| | 1331 | |
| | 1332 | static int WideMul2NarrowDiv(int a, int b, int c, int d) |
| | 1333 | { |
| | 1334 | int64_t a_b = (int64_t)a * (int64_t)b; |
| | 1335 | int64_t c_d = (int64_t)c * (int64_t)d; |
| | 1336 | |
| | 1337 | return (a_b + c_d)/c; |
| | 1338 | } |
| | 1339 | |
| | 1340 | static void CreateTxAnimUVArray(intptr_t * txa_data, int* uv_array, int* shapeitemptr) |
| | 1341 | { |
| | 1342 | int Orient, Scale; |
| | 1343 | int OrientX, OrientY; |
| | 1344 | int ScaleX, ScaleY; |
| | 1345 | POLYHEADER *pheader = (POLYHEADER*) shapeitemptr; |
| | 1346 | |
| | 1347 | /* The sequence will have been copied across by the control block */ |
| | 1348 | |
| | 1349 | int sequence = *txa_data++; |
| | 1350 | TXANIMHEADER **txah_ptr = (TXANIMHEADER **) txa_data; |
| | 1351 | TXANIMHEADER *txah = txah_ptr[sequence]; |
| | 1352 | TXANIMFRAME *txaf = txah->txa_framedata; |
| | 1353 | |
| | 1354 | /* Because the current frame can be set from outside, clamp it first */ |
| | 1355 | |
| | 1356 | if(txah->txa_currentframe < 0) |
| | 1357 | txah->txa_currentframe = 0; |
| | 1358 | |
| | 1359 | if(txah->txa_currentframe >= txah->txa_maxframe) |
| | 1360 | txah->txa_currentframe = txah->txa_maxframe - 1; |
| | 1361 | |
| | 1362 | /* Frame # */ |
| | 1363 | |
| | 1364 | int CurrentFrame = txah->txa_currentframe >> 16; |
| | 1365 | int Alpha = txah->txa_currentframe - (CurrentFrame << 16); |
| | 1366 | int OneMinusAlpha = ONE_FIXED - Alpha; |
| | 1367 | |
| | 1368 | /* Start and End Frame */ |
| | 1369 | |
| | 1370 | int NextFrame = CurrentFrame + 1; |
| | 1371 | |
| | 1372 | if(NextFrame >= txah->txa_numframes) |
| | 1373 | NextFrame = 0; |
| | 1374 | |
| | 1375 | TXANIMFRAME *txaf0 = &txaf[CurrentFrame]; |
| | 1376 | TXANIMFRAME *txaf1 = &txaf[NextFrame]; |
| | 1377 | |
| | 1378 | /* |
| | 1379 | |
| | 1380 | Write the image index back to the item by overwriting the shape data. |
| | 1381 | This is not elegant but it is one of the kind of things you expect to |
| | 1382 | have happen when a major new feature is retro-fitted to a system. |
| | 1383 | |
| | 1384 | */ |
| | 1385 | |
| | 1386 | #define ClrTxIndex 0xffff0000 /* AND with this to clear the low 16-bits */ |
| | 1387 | |
| | 1388 | pheader->PolyColour &= ClrTxIndex; |
| | 1389 | pheader->PolyColour |= txaf0->txf_image; |
| | 1390 | |
| | 1391 | int* txaf0_uv = txaf0->txf_uvdata; |
| | 1392 | int* txaf1_uv = txaf1->txf_uvdata; |
| | 1393 | |
| | 1394 | // Calculate UVs |
| | 1395 | |
| | 1396 | int *iptr = uv_array; |
| | 1397 | |
| | 1398 | if(txah->txa_flags & txa_flag_interpolate_uvs) |
| | 1399 | { |
| | 1400 | int i = txaf0->txf_numuvs; |
| | 1401 | |
| | 1402 | for(; i; i--) |
| | 1403 | { |
| | 1404 | iptr[0] = MUL_FIXED(txaf0_uv[0], OneMinusAlpha) + MUL_FIXED(txaf1_uv[0], Alpha); |
| | 1405 | |
| | 1406 | iptr[1] = MUL_FIXED(txaf0_uv[1], OneMinusAlpha) + MUL_FIXED(txaf1_uv[1], Alpha); |
| | 1407 | |
| | 1408 | // printf("%d, %d\n", iptr[0] >> 16, iptr[1] >> 16); |
| | 1409 | |
| | 1410 | txaf0_uv += 2; |
| | 1411 | txaf1_uv += 2; |
| | 1412 | iptr += 2; |
| | 1413 | } |
| | 1414 | } |
| | 1415 | else |
| | 1416 | { |
| | 1417 | int i = txaf0->txf_numuvs; |
| | 1418 | |
| | 1419 | for(; i; i--) |
| | 1420 | { |
| | 1421 | iptr[0] = txaf0_uv[0]; |
| | 1422 | iptr[1] = txaf0_uv[1]; |
| | 1423 | |
| | 1424 | // printf("%d, %d\n", iptr[0] >> 16, iptr[1] >> 16); |
| | 1425 | |
| | 1426 | txaf0_uv += 2; |
| | 1427 | iptr += 2; |
| | 1428 | } |
| | 1429 | } |
| | 1430 | |
| | 1431 | // Interpolate Orient and Scale |
| | 1432 | |
| | 1433 | int o1 = txaf0->txf_orient; |
| | 1434 | int o2 = txaf1->txf_orient; |
| | 1435 | |
| | 1436 | if(o1 == o2) |
| | 1437 | { |
| | 1438 | Orient = o1; |
| | 1439 | } |
| | 1440 | else |
| | 1441 | { |
| | 1442 | int od = o1 - o2; |
| | 1443 | |
| | 1444 | if(od < 0) |
| | 1445 | od = -od; |
| | 1446 | |
| | 1447 | if(od >= deg180) |
| | 1448 | { |
| | 1449 | o1 <<= (32 - 12); |
| | 1450 | o1 >>= (32 - 12); |
| | 1451 | o2 <<= (32 - 12); |
| | 1452 | o2 >>= (32 - 12); |
| | 1453 | } |
| | 1454 | |
| | 1455 | Orient = MUL_FIXED(o1, OneMinusAlpha) + MUL_FIXED(o2, Alpha); |
| | 1456 | Orient &= wrap360; |
| | 1457 | } |
| | 1458 | |
| | 1459 | if(txaf0->txf_scale == txaf1->txf_scale) |
| | 1460 | Scale = txaf0->txf_scale; |
| | 1461 | else |
| | 1462 | Scale = WideMul2NarrowDiv(txaf0->txf_scale, OneMinusAlpha, txaf1->txf_scale, Alpha); |
| | 1463 | |
| | 1464 | // Interpolate Orient and Scale Origins |
| | 1465 | |
| | 1466 | if(txaf0->txf_orientx == txaf1->txf_orientx) |
| | 1467 | OrientX = txaf0->txf_orientx; |
| | 1468 | else |
| | 1469 | OrientX = MUL_FIXED(txaf0->txf_orientx, OneMinusAlpha) + MUL_FIXED(txaf1->txf_orientx, Alpha); |
| | 1470 | |
| | 1471 | if(txaf0->txf_orienty == txaf1->txf_orienty) |
| | 1472 | OrientY = txaf0->txf_orienty; |
| | 1473 | else |
| | 1474 | OrientY = MUL_FIXED(txaf0->txf_orienty, OneMinusAlpha) + MUL_FIXED(txaf1->txf_orienty, Alpha); |
| | 1475 | |
| | 1476 | if(txaf0->txf_scalex == txaf1->txf_scalex) |
| | 1477 | ScaleX = txaf0->txf_scalex; |
| | 1478 | else |
| | 1479 | ScaleX = MUL_FIXED(txaf0->txf_scalex, OneMinusAlpha) + MUL_FIXED(txaf1->txf_scalex, Alpha); |
| | 1480 | |
| | 1481 | if(txaf0->txf_scaley == txaf1->txf_scaley) |
| | 1482 | ScaleY = txaf0->txf_scaley; |
| | 1483 | else |
| | 1484 | ScaleY = MUL_FIXED(txaf0->txf_scaley, OneMinusAlpha) + MUL_FIXED(txaf1->txf_scaley, Alpha); |
| | 1485 | |
| | 1486 | /* |
| | 1487 | printf("Alpha = %d\n", Alpha); |
| | 1488 | printf("OneMinusAlpha = %d\n", OneMinusAlpha); |
| | 1489 | printf("Orient = %d\n", Orient); |
| | 1490 | printf("txaf0->txf_scale = %d\n", txaf0->txf_scale); |
| | 1491 | printf("txaf1->txf_scale = %d\n", txaf1->txf_scale); |
| | 1492 | printf("Scale = %d\n", Scale); |
| | 1493 | */ |
| | 1494 | |
| | 1495 | #if 1 |
| | 1496 | // Rotate UV Array |
| | 1497 | |
| | 1498 | if(Orient) |
| | 1499 | { |
| | 1500 | int i = txaf0->txf_numuvs; |
| | 1501 | int sin = GetSin(Orient); |
| | 1502 | int cos = GetCos(Orient); |
| | 1503 | iptr = uv_array; |
| | 1504 | |
| | 1505 | for(; i; i--) |
| | 1506 | { |
| | 1507 | int x = iptr[0] - OrientX; |
| | 1508 | int y = iptr[1] - OrientY; |
| | 1509 | int x1 = MUL_FIXED(x, cos) - MUL_FIXED(y, sin); |
| | 1510 | int y1 = MUL_FIXED(x, sin) + MUL_FIXED(y, cos); |
| | 1511 | |
| | 1512 | iptr[0] = x1 + OrientX; |
| | 1513 | iptr[1] = y1 + OrientY; |
| | 1514 | |
| | 1515 | iptr += 2; |
| | 1516 | } |
| | 1517 | } |
| | 1518 | |
| | 1519 | // Scale UV Array |
| | 1520 | |
| | 1521 | if(Scale != ONE_FIXED) |
| | 1522 | { |
| | 1523 | int i = txaf0->txf_numuvs; |
| | 1524 | iptr = uv_array; |
| | 1525 | |
| | 1526 | for(; i; i--) |
| | 1527 | { |
| | 1528 | int x = iptr[0] - ScaleX; |
| | 1529 | int y = iptr[1] - ScaleY; |
| | 1530 | |
| | 1531 | x = MUL_FIXED(x, Scale); |
| | 1532 | y = MUL_FIXED(y, Scale); |
| | 1533 | |
| | 1534 | iptr[0] = x + ScaleX; |
| | 1535 | iptr[1] = y + ScaleY; |
| | 1536 | |
| | 1537 | iptr += 2; |
| | 1538 | } |
| | 1539 | } |
| | 1540 | #endif |
| | 1541 | |
| | 1542 | /* |
| | 1543 | printf("Current Frame = %d\n", txah->txa_currentframe); |
| | 1544 | printf("Current Frame = %d\n", CurrentFrame); |
| | 1545 | printf("Next Frame = %d\n", NextFrame); |
| | 1546 | printf("Alpha = %d\n", Alpha); |
| | 1547 | */ |
| | 1548 | |
| | 1549 | } |
| | 1550 | |
| | 1551 | static void PredatorSeeAliensVision_ShapePipeline(struct shapeheader* shapePtr) |
| | 1552 | { |
| | 1553 | int numitems = shapePtr->numitems; |
| | 1554 | int** itemArrayPtr = shapePtr->items; |
| | 1555 | |
| | 1556 | assert(numitems); |
| | 1557 | |
| | 1558 | do |
| | 1559 | { |
| | 1560 | POLYHEADER *polyPtr = (POLYHEADER*) (*itemArrayPtr++); |
| | 1561 | |
| | 1562 | switch (polyPtr->PolyItemType) |
| | 1563 | { |
| | 1564 | case I_ZB_Gouraud3dTexturedPolygon: |
| | 1565 | case I_ZB_Gouraud2dTexturedPolygon: |
| | 1566 | { |
| | 1567 | int pif = PolygonWithinFrustrum(polyPtr); |
| | 1568 | |
| | 1569 | if (pif) |
| | 1570 | { |
| | 1571 | int alpha; |
| | 1572 | // get ptr to uv coords for this polygon |
| | 1573 | int *texture_defn_ptr = Global_ShapeHeaderPtr->sh_textures[(polyPtr->PolyColour >> TxDefn)]; |
| | 1574 | RENDERVERTEX *renderVerticesPtr = VerticesUnClipped; |
| | 1575 | int i = RenderPolygon.NumberOfVertices; |
| | 1576 | |
| | 1577 | VertexNumberPtr = &polyPtr->Poly1stPt; |
| | 1578 | |
| | 1579 | if(polyPtr->PolyFlags & iflag_txanim) |
| | 1580 | { |
| | 1581 | // Create the UV array |
| | 1582 | int uv_array[18]; |
| | 1583 | CreateTxAnimUVArray((intptr_t*)texture_defn_ptr, uv_array, (int*)polyPtr); |
| | 1584 | texture_defn_ptr = uv_array; |
| | 1585 | } |
| | 1586 | |
| | 1587 | if( (Global_ODB_Ptr->SpecialFXFlags & SFXFLAG_MELTINGINTOGROUND) && (Global_ODB_Ptr->ObFlags2 < ONE_FIXED) ) |
| | 1588 | { |
| | 1589 | alpha = Global_ODB_Ptr->ObFlags2 >> 8; |
| | 1590 | RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL; |
| | 1591 | } |
| | 1592 | else |
| | 1593 | { |
| | 1594 | alpha = 0; |
| | 1595 | RenderPolygon.TranslucencyMode = TRANSLUCENCY_OFF; |
| | 1596 | } |
| | 1597 | |
| | 1598 | do |
| | 1599 | { |
| | 1600 | VECTORCH *vertexPtr = &RotatedPts[*VertexNumberPtr]; |
| | 1601 | |
| | 1602 | if(polyPtr->PolyFlags & iflag_txanim) |
| | 1603 | { |
| | 1604 | renderVerticesPtr->U = texture_defn_ptr[0]; |
| | 1605 | renderVerticesPtr->V = texture_defn_ptr[1]; |
| | 1606 | } |
| | 1607 | else |
| | 1608 | { |
| | 1609 | renderVerticesPtr->U = texture_defn_ptr[0] << 16; |
| | 1610 | renderVerticesPtr->V = texture_defn_ptr[1] << 16; |
| | 1611 | } |
| | 1612 | |
| | 1613 | renderVerticesPtr->X = vertexPtr->vx; |
| | 1614 | renderVerticesPtr->Y = vertexPtr->vy; |
| | 1615 | renderVerticesPtr->Z = vertexPtr->vz; |
| | 1616 | |
| | 1617 | { |
| | 1618 | VECTORCH mag = RotatedPts[*VertexNumberPtr]; //*(((VECTORCH *)Global_ShapeVNormals) + *VertexNumberPtr); |
| | 1619 | int colour; |
| | 1620 | mag.vx = vertexPtr->vx - Global_ODB_Ptr->ObView.vx; |
| | 1621 | mag.vy = vertexPtr->vy - Global_ODB_Ptr->ObView.vy; |
| | 1622 | mag.vz = vertexPtr->vz - Global_ODB_Ptr->ObView.vz; |
| | 1623 | |
| | 1624 | colour = GetSin(((mag.vx+mag.vy+mag.vz)*8+CloakingPhase)&4095); |
| | 1625 | colour = MUL_FIXED(colour,colour); |
| | 1626 | renderVerticesPtr->B = MUL_FIXED(colour,255); |
| | 1627 | renderVerticesPtr->R = renderVerticesPtr->B/2; |
| | 1628 | renderVerticesPtr->G = renderVerticesPtr->B/2; |
| | 1629 | |
| | 1630 | colour = MUL_FIXED(colour,colour); |
| | 1631 | colour = MUL_FIXED(colour,colour); |
| | 1632 | |
| | 1633 | renderVerticesPtr->SpecularR = colour/1024; |
| | 1634 | renderVerticesPtr->SpecularG = colour/1024; |
| | 1635 | renderVerticesPtr->SpecularB = colour/1024; |
| | 1636 | renderVerticesPtr->A = alpha; |
| | 1637 | } |
| | 1638 | |
| | 1639 | texture_defn_ptr += 2; |
| | 1640 | renderVerticesPtr++; |
| | 1641 | VertexNumberPtr++; |
| | 1642 | |
| | 1643 | } while(--i); |
| | 1644 | |
| | 1645 | |
| | 1646 | if ((pif < 0) && !ClipPolygon(RenderPolygon.NumberOfVertices)) |
| | 1647 | { |
| | 1648 | } |
| | 1649 | else |
| | 1650 | { |
| | 1651 | TexturedPolygon((polyPtr->PolyColour & ClrTxDefn), draw_vertices , RenderPolygon.TranslucencyMode); |
| | 1652 | } |
| | 1653 | } |
| | 1654 | } |
| | 1655 | default: |
| | 1656 | break; |
| | 1657 | } |
| | 1658 | |
| | 1659 | } while(--numitems); |
| | 1660 | } |
| | 1661 | |
| | 1662 | static void CloakedPolygon_Construct(POLYHEADER *polyPtr, int CloakingMode) |
| | 1663 | { |
| | 1664 | RENDERVERTEX *renderVerticesPtr = VerticesUnClipped; |
| | 1665 | int i = RenderPolygon.NumberOfVertices; |
| | 1666 | |
| | 1667 | // get ptr to uv coords for this polygon |
| | 1668 | int *texture_defn_ptr = Global_ShapeHeaderPtr->sh_textures[(polyPtr->PolyColour >> TxDefn)]; |
| | 1669 | |
| | 1670 | VertexNumberPtr = &polyPtr->Poly1stPt; |
| | 1671 | |
| | 1672 | do |
| | 1673 | { |
| | 1674 | VECTORCH *vertexPtr = &RotatedPts[*VertexNumberPtr]; |
| | 1675 | renderVerticesPtr->X = vertexPtr->vx; |
| | 1676 | renderVerticesPtr->Y = vertexPtr->vy; |
| | 1677 | renderVerticesPtr->Z = vertexPtr->vz; |
| | 1678 | renderVerticesPtr->U = texture_defn_ptr[0] << 16; |
| | 1679 | renderVerticesPtr->V = texture_defn_ptr[1] << 16; |
| | 1680 | |
| | 1681 | VertexIntensity(renderVerticesPtr); |
| | 1682 | |
| | 1683 | { |
| | 1684 | VECTORCH mag; |
| | 1685 | |
| | 1686 | mag.vx = abs(vertexPtr->vx - ObjectCentre.vx); |
| | 1687 | mag.vy = abs(vertexPtr->vy - MUL_FIXED(ObjectCentre.vy, 87381)); |
| | 1688 | mag.vz = abs(vertexPtr->vz - ObjectCentre.vz); |
| | 1689 | |
| | 1690 | int alpha = GetSin(((mag.vx+mag.vy+mag.vz)*8+CloakingPhase)&4095); |
| | 1691 | |
| | 1692 | alpha = MUL_FIXED(alpha, alpha); |
| | 1693 | |
| | 1694 | if (alpha > CloakingMode) |
| | 1695 | alpha = CloakingMode; |
| | 1696 | |
| | 1697 | alpha /= 256; |
| | 1698 | |
| | 1699 | if (alpha > 255) |
| | 1700 | alpha = 255; |
| | 1701 | |
| | 1702 | renderVerticesPtr->A = alpha; |
| | 1703 | |
| | 1704 | if(CloakingMode > ONE_FIXED) |
| | 1705 | { |
| | 1706 | alpha = GetSin(((mag.vx+mag.vy+mag.vz)+CloakingPhase)&4095); |
| | 1707 | alpha = MUL_FIXED(alpha, alpha)>>8; |
| | 1708 | |
| | 1709 | if(alpha == 255) |
| | 1710 | { |
| | 1711 | renderVerticesPtr->A = 255; |
| | 1712 | renderVerticesPtr->G = 128; |
| | 1713 | renderVerticesPtr->B = 255; |
| | 1714 | } |
| | 1715 | } |
| | 1716 | } |
| | 1717 | |
| | 1718 | renderVerticesPtr++; |
| | 1719 | VertexNumberPtr++; |
| | 1720 | texture_defn_ptr += 2; |
| | 1721 | |
| | 1722 | } while(--i); |
| | 1723 | } |
| | 1724 | |
| | 1725 | static void AddToTranslucentPolyList(int texture_number, int flags, const RENDERVERTEX *renderVerticesPtr) |
| | 1726 | { |
| | 1727 | // copy the data to the list for processing later |
| | 1728 | |
| | 1729 | if (CurrentNumberOfTranslucentPolygons < MAX_NO_OF_TRANSLUCENT_POLYGONS) |
| | 1730 | { |
| | 1731 | unsigned int i; |
| | 1732 | TranslucentPolygons[CurrentNumberOfTranslucentPolygons].polygon.NumberOfVertices = RenderPolygon.NumberOfVertices; |
| | 1733 | |
| | 1734 | for (i=0; i < RenderPolygon.NumberOfVertices; i++) |
| | 1735 | TranslucentPolygons[CurrentNumberOfTranslucentPolygons].polygon.Vertices[i] = *renderVerticesPtr++; |
| | 1736 | |
| | 1737 | TranslucentPolygons[CurrentNumberOfTranslucentPolygons].texture_number = texture_number; |
| | 1738 | TranslucentPolygons[CurrentNumberOfTranslucentPolygons++].flags = flags; |
| | 1739 | } |
| | 1740 | } |
| | 1741 | |
| | 1742 | static void GouraudTexturedPolygon_Construct(const POLYHEADER *polyPtr) |
| | 1743 | { |
| | 1744 | /* get ptr to uv coords for this polygon */ |
| | 1745 | int *texture_defn_ptr = Global_ShapeHeaderPtr->sh_textures[(polyPtr->PolyColour >> TxDefn)]; |
| | 1746 | |
| | 1747 | RENDERVERTEX *renderVerticesPtr = VerticesUnClipped; |
| | 1748 | int i = RenderPolygon.NumberOfVertices; |
| | 1749 | |
| | 1750 | VertexNumberPtr = &polyPtr->Poly1stPt; |
| | 1751 | |
| | 1752 | /* If this texture is animated the UV array must be calculated */ |
| | 1753 | |
| | 1754 | if(polyPtr->PolyFlags & iflag_txanim) |
| | 1755 | { |
| | 1756 | /* Create the UV array */ |
| | 1757 | int uv_array[18]; |
| | 1758 | CreateTxAnimUVArray((intptr_t*)texture_defn_ptr, uv_array, (int*)polyPtr); |
| | 1759 | texture_defn_ptr = uv_array; |
| | 1760 | |
| | 1761 | do |
| | 1762 | { |
| | 1763 | VECTORCH *vertexPtr = &RotatedPts[*VertexNumberPtr]; |
| | 1764 | |
| | 1765 | switch(UserProfile.active_bonus) |
| | 1766 | { |
| | 1767 | case CHEATMODE_NONACTIVE: |
| | 1768 | default: |
| | 1769 | renderVerticesPtr->X = vertexPtr->vx; |
| | 1770 | renderVerticesPtr->Y = vertexPtr->vy; |
| | 1771 | renderVerticesPtr->Z = vertexPtr->vz; |
| | 1772 | break; |
| | 1773 | case CHEATMODE_TRIPTASTIC: |
| | 1774 | { |
| | 1775 | renderVerticesPtr->X = vertexPtr->vx+GetSin((CloakingPhase*2 +vertexPtr->vz)&4095)/1024; |
| | 1776 | renderVerticesPtr->Y = vertexPtr->vy+GetSin((CloakingPhase-3000 +vertexPtr->vx)&4095)/1024; |
| | 1777 | renderVerticesPtr->Z = vertexPtr->vz+GetSin((CloakingPhase*3+239+vertexPtr->vy)&4095)/1024; |
| | 1778 | } |
| | 1779 | break; |
| | 1780 | case CHEATMODE_UNDERWATER: |
| | 1781 | { |
| | 1782 | renderVerticesPtr->X = vertexPtr->vx+(GetSin((CloakingPhase/2 +vertexPtr->vz)&4095))/1024; |
| | 1783 | renderVerticesPtr->Y = vertexPtr->vy+(GetSin((CloakingPhase-3000+vertexPtr->vx)&4095))/1024; |
| | 1784 | renderVerticesPtr->Z = vertexPtr->vz+(GetSin((CloakingPhase/3+239+vertexPtr->vy)&4095))/1024; |
| | 1785 | } |
| | 1786 | } |
| | 1787 | |
| | 1788 | renderVerticesPtr->U = texture_defn_ptr[0]; |
| | 1789 | renderVerticesPtr->V = texture_defn_ptr[1]; |
| | 1790 | |
| | 1791 | if( (Global_ODB_Ptr->SpecialFXFlags & SFXFLAG_MELTINGINTOGROUND) && (Global_ODB_Ptr->ObFlags2 < ONE_FIXED) ) |
| | 1792 | { |
| | 1793 | renderVerticesPtr->A = Global_ODB_Ptr->ObFlags2 >> 8; |
| | 1794 | RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL; |
| | 1795 | } |
| | 1796 | else if (polyPtr->PolyFlags & iflag_transparent) |
| | 1797 | { |
| | 1798 | renderVerticesPtr->A = 128; |
| | 1799 | RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL; |
| | 1800 | } |
| | 1801 | else |
| | 1802 | { |
| | 1803 | switch(UserProfile.active_bonus) |
| | 1804 | { |
| | 1805 | case CHEATMODE_NONACTIVE: |
| | 1806 | default: |
| | 1807 | renderVerticesPtr->A = 255; |
| | 1808 | break; |
| | 1809 | case CHEATMODE_TRIPTASTIC: |
| | 1810 | renderVerticesPtr->A = TripTasticPhase; |
| | 1811 | break; |
| | 1812 | case CHEATMODE_MOTIONBLUR: |
| | 1813 | renderVerticesPtr->A = 128; |
| | 1814 | } |
| | 1815 | |
| | 1816 | RenderPolygon.TranslucencyMode = TRANSLUCENCY_OFF; |
| | 1817 | } |
| | 1818 | |
| | 1819 | if (polyPtr->PolyFlags & iflag_nolight) |
| | 1820 | { |
| | 1821 | switch (PlayerStatus.VisionMode) |
| | 1822 | { |
| | 1823 | default: |
| | 1824 | case VISION_MODE_NORMAL: |
| | 1825 | { |
| | 1826 | renderVerticesPtr->R = renderVerticesPtr->G = renderVerticesPtr->B = 255; |
| | 1827 | renderVerticesPtr->SpecularR = renderVerticesPtr->SpecularG = renderVerticesPtr->SpecularB = 0; |
| | 1828 | } |
| | 1829 | break; |
| | 1830 | case VISION_MODE_IMAGEINTENSIFIER: |
| | 1831 | { |
| | 1832 | renderVerticesPtr->R = renderVerticesPtr->B = 0; |
| | 1833 | renderVerticesPtr->G = 255; |
| | 1834 | renderVerticesPtr->SpecularR = renderVerticesPtr->SpecularG = renderVerticesPtr->SpecularB = 0; |
| | 1835 | } |
| | 1836 | break; |
| | 1837 | case VISION_MODE_PRED_THERMAL: |
| | 1838 | { |
| | 1839 | renderVerticesPtr->R = renderVerticesPtr->G = 0; |
| | 1840 | renderVerticesPtr->B = 255; |
| | 1841 | renderVerticesPtr->SpecularR = renderVerticesPtr->SpecularG = renderVerticesPtr->SpecularB = 0; |
| | 1842 | } |
| | 1843 | break; |
| | 1844 | case VISION_MODE_PRED_SEEALIENS: |
| | 1845 | { |
| | 1846 | renderVerticesPtr->R = 255; |
| | 1847 | renderVerticesPtr->G = renderVerticesPtr->B = 0; |
| | 1848 | renderVerticesPtr->SpecularR = renderVerticesPtr->SpecularG = renderVerticesPtr->SpecularB = 0; |
| | 1849 | } |
| | 1850 | break; |
| | 1851 | case VISION_MODE_PRED_SEEPREDTECH: |
| | 1852 | { |
| | 1853 | renderVerticesPtr->R = renderVerticesPtr->B = 0; |
| | 1854 | renderVerticesPtr->G = 255; |
| | 1855 | renderVerticesPtr->SpecularR = renderVerticesPtr->SpecularB = 255; |
| | 1856 | renderVerticesPtr->SpecularG = 0; |
| | 1857 | } |
| | 1858 | } |
| | 1859 | } |
| | 1860 | else |
| | 1861 | { |
| | 1862 | VertexIntensity(renderVerticesPtr); |
| | 1863 | } |
| | 1864 | |
| | 1865 | renderVerticesPtr++; |
| | 1866 | VertexNumberPtr++; |
| | 1867 | |
| | 1868 | texture_defn_ptr += 2; |
| | 1869 | |
| | 1870 | } while(--i); |
| | 1871 | } |
| | 1872 | else |
| | 1873 | { |
| | 1874 | do |
| | 1875 | { |
| | 1876 | VECTORCH *vertexPtr = &RotatedPts[*VertexNumberPtr]; |
| | 1877 | #if SPATIAL_SHOCKWAVE |
| | 1878 | { |
| | 1879 | int d = Magnitude(vertexPtr); |
| | 1880 | int a = (CloakingPhase&16383)+4000; |
| | 1881 | int u = d-a; |
| | 1882 | int offset; |
| | 1883 | |
| | 1884 | if (u > 0 && u < 8192) |
| | 1885 | { |
| | 1886 | VECTORCH n = *vertexPtr; |
| | 1887 | Normalise(&n); |
| | 1888 | u <<= 3; |
| | 1889 | offset = MUL_FIXED(MUL_FIXED(2*u,ONE_FIXED-u),8000) + MUL_FIXED(MUL_FIXED(u,u),8192 ); |
| | 1890 | assert(offset>=0 && offset<=8192); |
| | 1891 | renderVerticesPtr->X = MUL_FIXED(n.vx,d);//a+offset*2); |
| | 1892 | renderVerticesPtr->Y = MUL_FIXED(n.vy,d);//a+offset*2); |
| | 1893 | renderVerticesPtr->Z = MUL_FIXED(n.vz,a+offset); |
| | 1894 | } |
| | 1895 | else |
| | 1896 | { |
| | 1897 | renderVerticesPtr->X = vertexPtr->vx; |
| | 1898 | renderVerticesPtr->Y = vertexPtr->vy; |
| | 1899 | renderVerticesPtr->Z = vertexPtr->vz; |
| | 1900 | } |
| | 1901 | } |
| | 1902 | #else |
| | 1903 | switch(UserProfile.active_bonus) |
| | 1904 | { |
| | 1905 | case CHEATMODE_NONACTIVE: |
| | 1906 | default: |
| | 1907 | { |
| | 1908 | renderVerticesPtr->X = vertexPtr->vx; |
| | 1909 | renderVerticesPtr->Y = vertexPtr->vy; |
| | 1910 | renderVerticesPtr->Z = vertexPtr->vz; |
| | 1911 | } |
| | 1912 | break; |
| | 1913 | case CHEATMODE_TRIPTASTIC: |
| | 1914 | { |
| | 1915 | renderVerticesPtr->X = vertexPtr->vx+GetSin((CloakingPhase*2 + vertexPtr->vz) & 4095)/1024; |
| | 1916 | renderVerticesPtr->Y = vertexPtr->vy+GetSin((CloakingPhase-3000 + vertexPtr->vx) & 4095)/1024; |
| | 1917 | renderVerticesPtr->Z = vertexPtr->vz+GetSin((CloakingPhase*3+239 + vertexPtr->vy) & 4095)/1024; |
| | 1918 | } |
| | 1919 | break; |
| | 1920 | case CHEATMODE_UNDERWATER: |
| | 1921 | { |
| | 1922 | renderVerticesPtr->X = vertexPtr->vx+(GetSin((CloakingPhase/2 + vertexPtr->vz)&4095))/1024; |
| | 1923 | renderVerticesPtr->Y = vertexPtr->vy+(GetSin((CloakingPhase - 3000 + vertexPtr->vx)&4095))/1024; |
| | 1924 | renderVerticesPtr->Z = vertexPtr->vz+(GetSin((CloakingPhase/3+239 + vertexPtr->vy)&4095))/1024; |
| | 1925 | } |
| | 1926 | } |
| | 1927 | #endif |
| | 1928 | |
| | 1929 | renderVerticesPtr->U = texture_defn_ptr[0] << 16; |
| | 1930 | renderVerticesPtr->V = texture_defn_ptr[1] << 16; |
| | 1931 | |
| | 1932 | if( (Global_ODB_Ptr->SpecialFXFlags & SFXFLAG_MELTINGINTOGROUND) && (Global_ODB_Ptr->ObFlags2 < ONE_FIXED) ) |
| | 1933 | { |
| | 1934 | renderVerticesPtr->A = Global_ODB_Ptr->ObFlags2 >> 8; |
| | 1935 | RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL; |
| | 1936 | } |
| | 1937 | else if (polyPtr->PolyFlags & iflag_transparent) |
| | 1938 | { |
| | 1939 | renderVerticesPtr->A = 128; |
| | 1940 | RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL; |
| | 1941 | } |
| | 1942 | else |
| | 1943 | { |
| | 1944 | switch(UserProfile.active_bonus) |
| | 1945 | { |
| | 1946 | case CHEATMODE_NONACTIVE: |
| | 1947 | default: |
| | 1948 | renderVerticesPtr->A = 255; |
| | 1949 | break; |
| | 1950 | case CHEATMODE_TRIPTASTIC: |
| | 1951 | renderVerticesPtr->A = TripTasticPhase; |
| | 1952 | break; |
| | 1953 | case CHEATMODE_MOTIONBLUR: |
| | 1954 | renderVerticesPtr->A = 128; |
| | 1955 | } |
| | 1956 | |
| | 1957 | RenderPolygon.TranslucencyMode = TRANSLUCENCY_OFF; |
| | 1958 | } |
| | 1959 | |
| | 1960 | RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL; |
| | 1961 | |
| | 1962 | if (polyPtr->PolyFlags & iflag_nolight) |
| | 1963 | { |
| | 1964 | switch (PlayerStatus.VisionMode) |
| | 1965 | { |
| | 1966 | default: |
| | 1967 | case VISION_MODE_NORMAL: |
| | 1968 | { |
| | 1969 | renderVerticesPtr->R = renderVerticesPtr->G = renderVerticesPtr->B = 255; |
| | 1970 | renderVerticesPtr->SpecularR = renderVerticesPtr->SpecularG = renderVerticesPtr->SpecularB = 0; |
| | 1971 | } |
| | 1972 | break; |
| | 1973 | case VISION_MODE_IMAGEINTENSIFIER: |
| | 1974 | { |
| | 1975 | renderVerticesPtr->R = renderVerticesPtr->B = 0; |
| | 1976 | renderVerticesPtr->G = 255; |
| | 1977 | renderVerticesPtr->SpecularR = renderVerticesPtr->SpecularG = renderVerticesPtr->SpecularB = 0; |
| | 1978 | } |
| | 1979 | break; |
| | 1980 | case VISION_MODE_PRED_THERMAL: |
| | 1981 | { |
| | 1982 | renderVerticesPtr->R = renderVerticesPtr->G = 0; |
| | 1983 | renderVerticesPtr->B = 255; |
| | 1984 | renderVerticesPtr->SpecularR = renderVerticesPtr->SpecularG = renderVerticesPtr->SpecularB = 0; |
| | 1985 | } |
| | 1986 | break; |
| | 1987 | case VISION_MODE_PRED_SEEALIENS: |
| | 1988 | { |
| | 1989 | renderVerticesPtr->R = 255; |
| | 1990 | renderVerticesPtr->G = renderVerticesPtr->B = 0; |
| | 1991 | renderVerticesPtr->SpecularR = renderVerticesPtr->SpecularG = renderVerticesPtr->SpecularB = 0; |
| | 1992 | } |
| | 1993 | break; |
| | 1994 | case VISION_MODE_PRED_SEEPREDTECH: |
| | 1995 | { |
| | 1996 | renderVerticesPtr->R = renderVerticesPtr->B = 0; |
| | 1997 | renderVerticesPtr->G = 255; |
| | 1998 | renderVerticesPtr->SpecularR = renderVerticesPtr->SpecularB = 255; |
| | 1999 | renderVerticesPtr->SpecularG = 0; |
| | 2000 | } |
| | 2001 | } |
| | 2002 | } |
| | 2003 | else |
| | 2004 | { |
| | 2005 | VertexIntensity(renderVerticesPtr); |
| | 2006 | } |
| | 2007 | |
| | 2008 | renderVerticesPtr++; |
| | 2009 | VertexNumberPtr++; |
| | 2010 | texture_defn_ptr += 2; |
| | 2011 | |
| | 2012 | } while(--i); |
| | 2013 | } |
| | 2014 | } |
| | 2015 | |
| | 2016 | struct shapeheader* GetShapeData(int shapenum) |
| | 2017 | { |
| | 2018 | return mainshapelist[shapenum]; |
| | 2019 | } |
| | 2020 | |
| | 2021 | int* GetTxAnimArrayZ(int shape, int item) |
| | 2022 | { |
| | 2023 | struct shapeheader *sptr = mainshapelist[shape]; |
| | 2024 | |
| | 2025 | if(sptr->sh_textures && sptr->items) |
| | 2026 | { |
| | 2027 | int** item_array_ptr = sptr->items; |
| | 2028 | int** shape_textures = sptr->sh_textures; |
| | 2029 | int* item_ptr = item_array_ptr[item]; |
| | 2030 | POLYHEADER *pheader = (POLYHEADER *) item_ptr; |
| | 2031 | |
| | 2032 | if(pheader->PolyFlags & iflag_txanim) |
| | 2033 | return (int*) shape_textures[(pheader->PolyColour >> TxDefn)]; |
| | 2034 | } |
| | 2035 | |
| | 2036 | return NULL; |
| | 2037 | } |
| | 2038 | |
| | 2039 | static TXANIMHEADER* GetTxAnimDataZ(int shape, int item, int sequence) |
| | 2040 | { |
| | 2041 | struct shapeheader* sptr = mainshapelist[shape]; |
| | 2042 | |
| | 2043 | if(sptr && sptr->sh_textures && sptr->items) |
| | 2044 | { |
| | 2045 | int** item_array_ptr = sptr->items; |
| | 2046 | int** shape_textures = sptr->sh_textures; |
| | 2047 | int* item_ptr = item_array_ptr[item]; |
| | 2048 | POLYHEADER *pheader = (POLYHEADER *) item_ptr; |
| | 2049 | |
| | 2050 | if(pheader->PolyFlags & iflag_txanim) |
| | 2051 | { |
| | 2052 | TXANIMHEADER **txah_ptr = (TXANIMHEADER **) shape_textures[(pheader->PolyColour >> TxDefn)]; |
| | 2053 | txah_ptr++; /* Skip sequence shadow */ |
| | 2054 | return txah_ptr[sequence]; |
| | 2055 | } |
| | 2056 | } |
| | 2057 | |
| | 2058 | return NULL; |
| | 2059 | } |
| | 2060 | |
| | 2061 | /* |
| | 2062 | |
| | 2063 | This function copies the TXANIMHEADER from the shape data item sequence |
| | 2064 | selected by the TXACTRLBLK to the TXANIMHEADER in the TXACTRLBLK |
| | 2065 | |
| | 2066 | */ |
| | 2067 | |
| | 2068 | TXANIMHEADER* GetTxAnimHeaderFromShape(TXACTRLBLK *taptr, int shape) |
| | 2069 | { |
| | 2070 | TXANIMHEADER *txah = GetTxAnimDataZ(shape, taptr->tac_item, taptr->tac_sequence); |
| | 2071 | |
| | 2072 | if(txah) |
| | 2073 | { |
| | 2074 | taptr->tac_txah.txa_flags = txah->txa_flags; |
| | 2075 | taptr->tac_txah.txa_state = txah->txa_state; |
| | 2076 | taptr->tac_txah.txa_numframes = txah->txa_numframes; |
| | 2077 | taptr->tac_txah.txa_framedata = txah->txa_framedata; |
| | 2078 | taptr->tac_txah.txa_currentframe = txah->txa_currentframe; |
| | 2079 | taptr->tac_txah.txa_maxframe = txah->txa_maxframe; |
| | 2080 | taptr->tac_txah.txa_speed = txah->txa_speed; |
| | 2081 | } |
| | 2082 | |
| | 2083 | return txah; |
| | 2084 | } |
| | 2085 | |
| | 2086 | /* |
| | 2087 | |
| | 2088 | Texture Animation Control Blocks are used to update animation. At the start |
| | 2089 | of "AddShape()" the relevant control block values are copied across to the |
| | 2090 | item TXANIMHEADER. |
| | 2091 | |
| | 2092 | */ |
| | 2093 | |
| | 2094 | static void UpdateTxAnim(TXANIMHEADER *txah) |
| | 2095 | { |
| | 2096 | int UpdateRate; |
| | 2097 | |
| | 2098 | if(txah->txa_flags & txa_flag_play) |
| | 2099 | { |
| | 2100 | /* How fast do we go? */ |
| | 2101 | |
| | 2102 | if(txah->txa_flags & txa_flag_quantiseframetime) |
| | 2103 | { |
| | 2104 | /* This option is still being designed and tested */ |
| | 2105 | |
| | 2106 | UpdateRate = txah->txa_speed & (~4096); /* 1/16th */ |
| | 2107 | |
| | 2108 | if(UpdateRate < 4096) |
| | 2109 | UpdateRate = 4096; |
| | 2110 | } |
| | 2111 | |
| | 2112 | UpdateRate = MUL_FIXED(NormalFrameTime, txah->txa_speed); |
| | 2113 | |
| | 2114 | /* Update the current frame */ |
| | 2115 | |
| | 2116 | if(txah->txa_flags & txa_flag_reverse) |
| | 2117 | { |
| | 2118 | txah->txa_currentframe -= UpdateRate; |
| | 2119 | |
| | 2120 | if(txah->txa_currentframe < 0) |
| | 2121 | { |
| | 2122 | if(txah->txa_flags & txa_flag_noloop) |
| | 2123 | txah->txa_currentframe = 0; |
| | 2124 | else |
| | 2125 | txah->txa_currentframe += txah->txa_maxframe; |
| | 2126 | } |
| | 2127 | } |
| | 2128 | else |
| | 2129 | { |
| | 2130 | txah->txa_currentframe += UpdateRate; |
| | 2131 | |
| | 2132 | if(txah->txa_currentframe >= txah->txa_maxframe) |
| | 2133 | { |
| | 2134 | if(txah->txa_flags & txa_flag_noloop) |
| | 2135 | txah->txa_currentframe = txah->txa_maxframe - 1; |
| | 2136 | else |
| | 2137 | txah->txa_currentframe -= txah->txa_maxframe; |
| | 2138 | } |
| | 2139 | } |
| | 2140 | } |
| | 2141 | } |
| | 2142 | |
| | 2143 | // Display block TXACTRLBLKS pass their data on to shape TXANIMHEADERs |
| | 2144 | |
| | 2145 | static void ControlTextureAnimation(DISPLAYBLOCK *dptr) |
| | 2146 | { |
| | 2147 | TXACTRLBLK *taptr = dptr->ObTxAnimCtrlBlks; |
| | 2148 | |
| | 2149 | while(taptr) |
| | 2150 | { |
| | 2151 | /* Update animation for the display block TXACTRLBLK */ |
| | 2152 | assert(&(taptr->tac_txah)); |
| | 2153 | UpdateTxAnim(&taptr->tac_txah); |
| | 2154 | |
| | 2155 | /* Get the TXANIMHEADER from the shape data */ |
| | 2156 | |
| | 2157 | TXANIMHEADER *txah = taptr->tac_txah_s; |
| | 2158 | |
| | 2159 | /* Copy across the current frame */ |
| | 2160 | assert(txah); |
| | 2161 | txah->txa_currentframe = taptr->tac_txah.txa_currentframe; |
| | 2162 | |
| | 2163 | int* iptr = taptr->tac_txarray; |
| | 2164 | assert(iptr); |
| | 2165 | *iptr = taptr->tac_sequence; |
| | 2166 | taptr = taptr->tac_next; |
| | 2167 | } |
| | 2168 | } |
| | 2169 | |
| | 2170 | static void RotateVertex(VECTOR2D *vertexPtr, int theta) |
| | 2171 | { |
| | 2172 | int sin = GetSin(theta); |
| | 2173 | int cos = GetCos(theta); |
| | 2174 | |
| | 2175 | int vx = MUL_FIXED(vertexPtr->vx, cos) - MUL_FIXED(vertexPtr->vy, sin); |
| | 2176 | int vy = MUL_FIXED(vertexPtr->vx, sin) + MUL_FIXED(vertexPtr->vy, cos); |
| | 2177 | |
| | 2178 | vertexPtr->vx = vx; |
| | 2179 | vertexPtr->vy = vy; |
| | 2180 | } |
| | 2181 | |
| | 2182 | static void TranslatePoint(const float *matrix, const float *source, float *dest) |
| | 2183 | { |
| | 2184 | dest[0] = matrix[0] * source[0] + matrix[1] * source[1] + matrix[ 2] * source[2] + matrix[ 3]; |
| | 2185 | dest[1] = matrix[4] * source[0] + matrix[5] * source[1] + matrix[ 6] * source[2] + matrix[ 7]; |
| | 2186 | dest[2] = matrix[8] * source[0] + matrix[9] * source[1] + matrix[10] * source[2] + matrix[11]; |
| | 2187 | } |
| | 2188 | |
| | 2189 | void TranslatePointIntoViewspace(VECTORCH * pointPtr) |
| | 2190 | { |
| | 2191 | float Dest[3]; |
| | 2192 | float Source[3]; |
| | 2193 | Source[0] = pointPtr->vx; |
| | 2194 | Source[1] = pointPtr->vy; |
| | 2195 | Source[2] = pointPtr->vz; |
| | 2196 | |
| | 2197 | TranslatePoint(ViewMatrix, Source, Dest); |
| | 2198 | |
| | 2199 | pointPtr->vx = (int)Dest[0]; |
| | 2200 | pointPtr->vy = (int)Dest[1]; |
| | 2201 | pointPtr->vz = (int)Dest[2]; |
| | 2202 | } |
| | 2203 | |
| | 2204 | void RenderParticle(PARTICLE *particlePtr) |
| | 2205 | { |
| | 2206 | int particleSize = particlePtr->Size; |
| | 2207 | |
| | 2208 | VECTORCH translatedPosition = particlePtr->Position; |
| | 2209 | TranslatePointIntoViewspace(&translatedPosition); |
| | 2210 | RENDERVERTEX *VerticesBuffer = VerticesUnClipped; |
| | 2211 | |
| | 2212 | switch(particlePtr->ParticleID) |
| | 2213 | { |
| | 2214 | case PARTICLE_ALIEN_BLOOD: |
| | 2215 | case PARTICLE_HUMAN_BLOOD: |
| | 2216 | case PARTICLE_PREDATOR_BLOOD: |
| | 2217 | case PARTICLE_SPARK: |
| | 2218 | case PARTICLE_RICOCHET_SPARK: |
| | 2219 | case PARTICLE_EXPLOSIONFIRE: |
| | 2220 | case PARTICLE_WATERFALLSPRAY: |
| | 2221 | case PARTICLE_LASERBEAM: |
| | 2222 | case PARTICLE_PLASMABEAM: |
| | 2223 | case PARTICLE_ORANGE_SPARK: |
| | 2224 | case PARTICLE_ORANGE_PLASMA: |
| | 2225 | { |
| | 2226 | VerticesBuffer[0].X = translatedPosition.vx; |
| | 2227 | VerticesBuffer[0].Y = translatedPosition.vy; |
| | 2228 | VerticesBuffer[0].Z = translatedPosition.vz; |
| | 2229 | VerticesBuffer[3].X = translatedPosition.vx; |
| | 2230 | VerticesBuffer[3].Y = translatedPosition.vy; |
| | 2231 | VerticesBuffer[3].Z = translatedPosition.vz; |
| | 2232 | const int temp_size = MUL_FIXED(particleSize, 87381); |
| | 2233 | VECTORCH translatedOffset= particlePtr->Offset; |
| | 2234 | TranslatePointIntoViewspace(&translatedOffset); |
| | 2235 | VerticesBuffer[1].X = translatedOffset.vx; |
| | 2236 | VerticesBuffer[1].Y = translatedOffset.vy; |
| | 2237 | VerticesBuffer[1].Z = translatedOffset.vz; |
| | 2238 | VerticesBuffer[2].X = translatedOffset.vx; |
| | 2239 | VerticesBuffer[2].Y = translatedOffset.vy; |
| | 2240 | VerticesBuffer[2].Z = translatedOffset.vz; |
| | 2241 | |
| | 2242 | { |
| | 2243 | int deltaX = translatedOffset.vx - translatedPosition.vx; |
| | 2244 | int deltaY = translatedOffset.vy - translatedPosition.vy; |
| | 2245 | int splitY = 0; |
| | 2246 | |
| | 2247 | if (deltaX >= 0) |
| | 2248 | { |
| | 2249 | if (deltaY >= 0) |
| | 2250 | { |
| | 2251 | if (deltaX > deltaY) |
| | 2252 | splitY = 1; |
| | 2253 | } |
| | 2254 | else if (deltaX > -deltaY) |
| | 2255 | splitY = 1; |
| | 2256 | } |
| | 2257 | else |
| | 2258 | { |
| | 2259 | if (deltaY >= 0) |
| | 2260 | { |
| | 2261 | if (-deltaX > deltaY) |
| | 2262 | splitY = 1; |
| | 2263 | } |
| | 2264 | else if (-deltaX > -deltaY) |
| | 2265 | { |
| | 2266 | splitY = 1; |
| | 2267 | } |
| | 2268 | } |
| | 2269 | |
| | 2270 | if (splitY) |
| | 2271 | { |
| | 2272 | if (deltaX > 0) |
| | 2273 | { |
| | 2274 | /* 1 & 2 are more +ve in X */ |
| | 2275 | VerticesBuffer[0].X -= particleSize; |
| | 2276 | VerticesBuffer[0].Y -= temp_size; |
| | 2277 | VerticesBuffer[1].X += particleSize; |
| | 2278 | VerticesBuffer[1].Y -= temp_size; |
| | 2279 | VerticesBuffer[2].X += particleSize; |
| | 2280 | VerticesBuffer[2].Y += temp_size; |
| | 2281 | VerticesBuffer[3].X -= particleSize; |
| | 2282 | VerticesBuffer[3].Y += temp_size; |
| | 2283 | } |
| | 2284 | else |
| | 2285 | { |
| | 2286 | /* 1 & 2 are more -ve in X */ |
| | 2287 | VerticesBuffer[0].X += particleSize; |
| | 2288 | VerticesBuffer[0].Y -= temp_size; |
| | 2289 | VerticesBuffer[1].X -= particleSize; |
| | 2290 | VerticesBuffer[1].Y -= temp_size; |
| | 2291 | VerticesBuffer[2].X -= particleSize; |
| | 2292 | VerticesBuffer[2].Y += temp_size; |
| | 2293 | VerticesBuffer[3].X += particleSize; |
| | 2294 | VerticesBuffer[3].Y += temp_size; |
| | 2295 | } |
| | 2296 | } |
| | 2297 | else |
| | 2298 | { |
| | 2299 | if (deltaY > 0) |
| | 2300 | { |
| | 2301 | /* 1 & 2 are more +ve in Y */ |
| | 2302 | VerticesBuffer[0].X -= particleSize; |
| | 2303 | VerticesBuffer[0].Y -= temp_size; |
| | 2304 | VerticesBuffer[1].X -= particleSize; |
| | 2305 | VerticesBuffer[1].Y += temp_size; |
| | 2306 | VerticesBuffer[2].X += particleSize; |
| | 2307 | VerticesBuffer[2].Y += temp_size; |
| | 2308 | VerticesBuffer[3].X += particleSize; |
| | 2309 | VerticesBuffer[3].Y -= temp_size; |
| | 2310 | } |
| | 2311 | else |
| | 2312 | { |
| | 2313 | /* 1 & 2 are more -ve in Y */ |
| | 2314 | VerticesBuffer[0].X -= particleSize; |
| | 2315 | VerticesBuffer[0].Y += temp_size; |
| | 2316 | VerticesBuffer[1].X -= particleSize; |
| | 2317 | VerticesBuffer[1].Y -= temp_size; |
| | 2318 | VerticesBuffer[2].X += particleSize; |
| | 2319 | VerticesBuffer[2].Y -= temp_size; |
| | 2320 | VerticesBuffer[3].X += particleSize; |
| | 2321 | VerticesBuffer[3].Y += temp_size; |
| | 2322 | } |
| | 2323 | } |
| | 2324 | } |
| | 2325 | } |
| | 2326 | break; |
| | 2327 | default: |
| | 2328 | { |
| | 2329 | VECTOR2D offset[4]; |
| | 2330 | offset[0].vx = -particleSize; |
| | 2331 | offset[0].vy = -particleSize; |
| | 2332 | |
| | 2333 | offset[1].vx = +particleSize; |
| | 2334 | offset[1].vy = -particleSize; |
| | 2335 | |
| | 2336 | offset[2].vx = +particleSize; |
| | 2337 | offset[2].vy = +particleSize; |
| | 2338 | |
| | 2339 | offset[3].vx = -particleSize; |
| | 2340 | offset[3].vy = +particleSize; |
| | 2341 | |
| | 2342 | switch(particlePtr->ParticleID) |
| | 2343 | { |
| | 2344 | case PARTICLE_MUZZLEFLASH: |
| | 2345 | { |
| | 2346 | int theta = FastRandom()&4095; |
| | 2347 | RotateVertex(&offset[0],theta); |
| | 2348 | RotateVertex(&offset[1],theta); |
| | 2349 | RotateVertex(&offset[2],theta); |
| | 2350 | RotateVertex(&offset[3],theta); |
| | 2351 | } |
| | 2352 | break; |
| | 2353 | case PARTICLE_SMOKECLOUD: |
| | 2354 | case PARTICLE_GUNMUZZLE_SMOKE: |
| | 2355 | case PARTICLE_FLAME: |
| | 2356 | { |
| | 2357 | int theta = (particlePtr->Offset.vx + MUL_FIXED(CloakingPhase, particlePtr->Offset.vy)) & 4095; |
| | 2358 | RotateVertex(&offset[0],theta); |
| | 2359 | RotateVertex(&offset[1],theta); |
| | 2360 | RotateVertex(&offset[2],theta); |
| | 2361 | RotateVertex(&offset[3],theta); |
| | 2362 | } |
| | 2363 | default: |
| | 2364 | break; |
| | 2365 | } |
| | 2366 | |
| | 2367 | { |
| | 2368 | VerticesBuffer[0].X = translatedPosition.vx + offset[0].vx; |
| | 2369 | VerticesBuffer[0].Y = translatedPosition.vy + MUL_FIXED(offset[0].vy,87381); |
| | 2370 | VerticesBuffer[0].Z = translatedPosition.vz; |
| | 2371 | |
| | 2372 | VerticesBuffer[1].X = translatedPosition.vx + offset[1].vx; |
| | 2373 | VerticesBuffer[1].Y = translatedPosition.vy + MUL_FIXED(offset[1].vy,87381); |
| | 2374 | VerticesBuffer[1].Z = translatedPosition.vz; |
| | 2375 | |
| | 2376 | VerticesBuffer[2].X = translatedPosition.vx + offset[2].vx; |
| | 2377 | VerticesBuffer[2].Y = translatedPosition.vy + MUL_FIXED(offset[2].vy,87381); |
| | 2378 | VerticesBuffer[2].Z = translatedPosition.vz; |
| | 2379 | |
| | 2380 | VerticesBuffer[3].X = translatedPosition.vx + offset[3].vx; |
| | 2381 | VerticesBuffer[3].Y = translatedPosition.vy + MUL_FIXED(offset[3].vy,87381); |
| | 2382 | VerticesBuffer[3].Z = translatedPosition.vz; |
| | 2383 | } |
| | 2384 | } |
| | 2385 | } |
| | 2386 | |
| | 2387 | { |
| | 2388 | const PARTICLE_DESC *particleDescPtr = &ParticleDescription[particlePtr->ParticleID]; |
| | 2389 | |
| | 2390 | VerticesBuffer[0].U = particleDescPtr->StartU; |
| | 2391 | VerticesBuffer[0].V = particleDescPtr->StartV; |
| | 2392 | |
| | 2393 | VerticesBuffer[1].U = particleDescPtr->EndU; |
| | 2394 | VerticesBuffer[1].V = particleDescPtr->StartV; |
| | 2395 | |
| | 2396 | VerticesBuffer[2].U = particleDescPtr->EndU; |
| | 2397 | VerticesBuffer[2].V = particleDescPtr->EndV; |
| | 2398 | |
| | 2399 | VerticesBuffer[3].U = particleDescPtr->StartU; |
| | 2400 | VerticesBuffer[3].V = particleDescPtr->EndV; |
| | 2401 | } |
| | 2402 | |
| | 2403 | if(PolyWithinFrustrum(4)) |
| | 2404 | Particle_Output(particlePtr, draw_vertices); |
| | 2405 | } |
| | 2406 | |
| | 2407 | static void FindAlienEnergySource_Recursion(HMODELCONTROLLER *controllerPtr, SECTION_DATA *sectionDataPtr, unsigned int colour) |
| | 2408 | { |
| | 2409 | /* KJL 16:29:40 10/02/98 - Recurse through hmodel */ |
| | 2410 | if ((sectionDataPtr->First_Child != NULL) && !(sectionDataPtr->flags & section_data_terminate_here)) |
| | 2411 | { |
| | 2412 | SECTION_DATA *childSectionPtr = sectionDataPtr->First_Child; |
| | 2413 | |
| | 2414 | while (childSectionPtr != NULL) |
| | 2415 | { |
| | 2416 | assert(childSectionPtr->My_Parent == sectionDataPtr); |
| | 2417 | |
| | 2418 | FindAlienEnergySource_Recursion(controllerPtr, childSectionPtr, colour); |
| | 2419 | childSectionPtr = childSectionPtr->Next_Sibling; |
| | 2420 | } |
| | 2421 | } |
| | 2422 | |
| | 2423 | if(sectionDataPtr->Shape && (sectionDataPtr->Shape->shaperadius > LocalDetailLevels.AlienEnergyViewThreshold)) |
| | 2424 | { |
| | 2425 | PARTICLE particle; |
| | 2426 | particle.Position = sectionDataPtr->World_Offset; |
| | 2427 | particle.ParticleID = PARTICLE_MUZZLEFLASH; |
| | 2428 | particle.Colour = colour; |
| | 2429 | particle.Size = sectionDataPtr->Shape->shaperadius * 2; |
| | 2430 | RenderParticle(&particle); |
| | 2431 | |
| | 2432 | if(0) |
| | 2433 | { |
| | 2434 | VECTORCH velocity; |
| | 2435 | velocity.vx = (FastRandom() & 255) - 128; |
| | 2436 | velocity.vy = (FastRandom() & 255) - 128; |
| | 2437 | velocity.vz = 0; |
| | 2438 | //velocity.vy = -1000 - (FastRandom() & 255); |
| | 2439 | //MakeParticle(§ionDataPtr->World_Offset, &velocity, PARTICLE_SPARK); |
| | 2440 | MakeParticle(§ionDataPtr->World_Offset, &velocity, PARTICLE_PLASMATRAIL); |
| | 2441 | } |
| | 2442 | } |
| | 2443 | } |
| | 2444 | |
| | 2445 | static void DoAlienEnergyView(DISPLAYBLOCK *dispPtr) |
| | 2446 | { |
| | 2447 | HMODELCONTROLLER *controllerPtr = dispPtr->HModelControlBlock; |
| | 2448 | STRATEGYBLOCK *sbPtr = dispPtr->ObStrategyBlock; |
| | 2449 | unsigned int colour; |
| | 2450 | |
| | 2451 | switch (sbPtr->type) |
| | 2452 | { |
| | 2453 | case I_BehaviourAlien: |
| | 2454 | case I_BehaviourAlienPlayer: |
| | 2455 | case I_BehaviourQueenAlien: |
| | 2456 | case I_BehaviourFaceHugger: |
| | 2457 | case I_BehaviourXenoborg: |
| | 2458 | colour = ALIENS_LIFEFORCE_GLOW_COLOUR; |
| | 2459 | break; |
| | 2460 | case I_BehaviourPredator: |
| | 2461 | case I_BehaviourPredatorPlayer: |
| | 2462 | colour = PREDATORS_LIFEFORCE_GLOW_COLOUR; |
| | 2463 | break; |
| | 2464 | case I_BehaviourMarine: |
| | 2465 | case I_BehaviourMarinePlayer: |
| | 2466 | { |
| | 2467 | MARINE_STATUS_BLOCK *marineStatusPointer = (MARINE_STATUS_BLOCK *)(sbPtr->dataptr); |
| | 2468 | |
| | 2469 | if (marineStatusPointer->Android) |
| | 2470 | return; |
| | 2471 | |
| | 2472 | colour = MARINES_LIFEFORCE_GLOW_COLOUR; |
| | 2473 | } |
| | 2474 | break; |
| | 2475 | case I_BehaviourNetGhost: |
| | 2476 | { |
| | 2477 | NETGHOSTDATABLOCK *ghostDataPtr = (NETGHOSTDATABLOCK *)sbPtr->dataptr; |
| | 2478 | |
| | 2479 | switch(ghostDataPtr->type) |
| | 2480 | { |
| | 2481 | case I_BehaviourAlienPlayer: |
| | 2482 | colour = ALIENS_LIFEFORCE_GLOW_COLOUR; |
| | 2483 | break; |
| | 2484 | case I_BehaviourPredatorPlayer: |
| | 2485 | colour = PREDATORS_LIFEFORCE_GLOW_COLOUR; |
| | 2486 | break; |
| | 2487 | case I_BehaviourMarinePlayer: |
| | 2488 | colour = MARINES_LIFEFORCE_GLOW_COLOUR; |
| | 2489 | break; |
| | 2490 | case I_BehaviourCorpse: |
| | 2491 | switch(ghostDataPtr->subtype) |
| | 2492 | { |
| | 2493 | case I_BehaviourAlienPlayer: |
| | 2494 | colour = ALIENS_LIFEFORCE_GLOW_COLOUR; |
| | 2495 | break; |
| | 2496 | case I_BehaviourPredatorPlayer: |
| | 2497 | colour = PREDATORS_LIFEFORCE_GLOW_COLOUR; |
| | 2498 | break; |
| | 2499 | case I_BehaviourMarinePlayer: |
| | 2500 | colour = MARINES_LIFEFORCE_GLOW_COLOUR; |
| | 2501 | default: |
| | 2502 | return; |
| | 2503 | } |
| | 2504 | default: |
| | 2505 | return; |
| | 2506 | } |
| | 2507 | } |
| | 2508 | break; |
| | 2509 | case I_BehaviourCorpse: |
| | 2510 | { |
| | 2511 | CORPSEDATABLOCK *corpseDataPtr = (CORPSEDATABLOCK *)sbPtr->dataptr; |
| | 2512 | |
| | 2513 | switch(corpseDataPtr->Type) |
| | 2514 | { |
| | 2515 | case I_BehaviourAlien: |
| | 2516 | case I_BehaviourAlienPlayer: |
| | 2517 | colour = ALIENS_LIFEFORCE_GLOW_COLOUR; |
| | 2518 | break; |
| | 2519 | case I_BehaviourMarine: |
| | 2520 | case I_BehaviourMarinePlayer: |
| | 2521 | { |
| | 2522 | if (-1 == corpseDataPtr->subtype) // android |
| | 2523 | return; |
| | 2524 | |
| | 2525 | colour = MARINES_LIFEFORCE_GLOW_COLOUR; |
| | 2526 | } |
| | 2527 | break; |
| | 2528 | case I_BehaviourPredator: |
| | 2529 | case I_BehaviourPredatorPlayer: |
| | 2530 | colour = PREDATORS_LIFEFORCE_GLOW_COLOUR; |
| | 2531 | break; |
| | 2532 | default: |
| | 2533 | return; |
| | 2534 | } |
| | 2535 | } |
| | 2536 | break; |
| | 2537 | case I_BehaviourHierarchicalFragment: |
| | 2538 | { |
| | 2539 | HDEBRIS_BEHAV_BLOCK *debrisDataPtr = (HDEBRIS_BEHAV_BLOCK *)sbPtr->dataptr; |
| | 2540 | |
| | 2541 | switch(debrisDataPtr->Type) |
| | 2542 | { |
| | 2543 | case I_BehaviourAlien: |
| | 2544 | case I_BehaviourAlienPlayer: |
| | 2545 | colour = ALIENS_LIFEFORCE_GLOW_COLOUR; |
| | 2546 | break; |
| | 2547 | case I_BehaviourPredator: |
| | 2548 | case I_BehaviourPredatorPlayer: |
| | 2549 | colour = PREDATORS_LIFEFORCE_GLOW_COLOUR; |
| | 2550 | break; |
| | 2551 | case I_BehaviourMarine: |
| | 2552 | case I_BehaviourMarinePlayer: |
| | 2553 | if (-1 == debrisDataPtr->SubType) // android |
| | 2554 | return; |
| | 2555 | |
| | 2556 | colour = MARINES_LIFEFORCE_GLOW_COLOUR; |
| | 2557 | break; |
| | 2558 | default: |
| | 2559 | return; |
| | 2560 | } |
| | 2561 | } |
| | 2562 | break; |
| | 2563 | default: |
| | 2564 | return; |
| | 2565 | } |
| | 2566 | |
| | 2567 | if((dispPtr->SpecialFXFlags & SFXFLAG_MELTINGINTOGROUND) && (dispPtr->ObFlags2 < ONE_FIXED)) |
| | 2568 | { |
| | 2569 | unsigned int alpha = MUL_FIXED(dispPtr->ObFlags2,colour >> 24); |
| | 2570 | colour = (colour & 0xffffff) + (alpha << 24); |
| | 2571 | } |
| | 2572 | |
| | 2573 | /* KJL 16:36:12 10/02/98 - check positions are up to date */ |
| | 2574 | ProveHModel(controllerPtr, dispPtr); |
| | 2575 | |
| | 2576 | DecalSystem_Setup(); |
| | 2577 | |
| | 2578 | FindAlienEnergySource_Recursion(controllerPtr, controllerPtr->section_data, colour); |
| | 2579 | |
| | 2580 | DecalSystem_End(); |
| | 2581 | } |
| | 2582 | |
| | 2583 | static void MorphPoints(SHAPEINSTR *shapeinstrptr) |
| | 2584 | { |
| | 2585 | VECTORCH *destPtr = RotatedPts; |
| | 2586 | VECTORCH *srcPtr; |
| | 2587 | int i = shapeinstrptr->sh_numitems; |
| | 2588 | struct shapeheader* shape1Ptr = MorphDisplay.md_sptr1; |
| | 2589 | |
| | 2590 | switch(MorphDisplay.md_lerp) |
| | 2591 | { |
| | 2592 | case 0x0000: |
| | 2593 | { |
| | 2594 | srcPtr = (VECTORCH *)*shape1Ptr->points; |
| | 2595 | } |
| | 2596 | break; |
| | 2597 | case 0xffff: |
| | 2598 | { |
| | 2599 | struct shapeheader* shape2Ptr = MorphDisplay.md_sptr2; |
| | 2600 | |
| | 2601 | srcPtr = (VECTORCH *)*shape2Ptr->points; |
| | 2602 | Global_ShapePoints = *(shape2Ptr->points); |
| | 2603 | } |
| | 2604 | break; |
| | 2605 | default: |
| | 2606 | { |
| | 2607 | struct shapeheader* shape2Ptr = MorphDisplay.md_sptr2; |
| | 2608 | VECTORCH *shape1PointsPtr = (VECTORCH *)(*shape1Ptr->points); |
| | 2609 | VECTORCH *shape2PointsPtr = (VECTORCH *)(*shape2Ptr->points); |
| | 2610 | |
| | 2611 | { |
| | 2612 | int numberOfPoints = shape1Ptr->numpoints; |
| | 2613 | VECTORCH *morphedPointsPtr = (VECTORCH *) MorphedPts; |
| | 2614 | |
| | 2615 | while(numberOfPoints--) |
| | 2616 | { |
| | 2617 | VECTORCH vertex1 = *shape1PointsPtr; |
| | 2618 | VECTORCH vertex2 = *shape2PointsPtr; |
| | 2619 | |
| | 2620 | if( (vertex1.vx == vertex2.vx && vertex1.vy == vertex2.vy && vertex1.vz == vertex2.vz) ) |
| | 2621 | { |
| | 2622 | *morphedPointsPtr = vertex1; |
| | 2623 | } |
| | 2624 | else |
| | 2625 | { |
| | 2626 | /* KJL 15:27:20 05/22/97 - I've changed this to speed things up, If a vertex |
| | 2627 | component has a magnitude greater than 32768 things will go wrong. */ |
| | 2628 | morphedPointsPtr->vx = vertex1.vx + (((vertex2.vx-vertex1.vx)*MorphDisplay.md_lerp)>>16); |
| | 2629 | morphedPointsPtr->vy = vertex1.vy + (((vertex2.vy-vertex1.vy)*MorphDisplay.md_lerp)>>16); |
| | 2630 | morphedPointsPtr->vz = vertex1.vz + (((vertex2.vz-vertex1.vz)*MorphDisplay.md_lerp)>>16); |
| | 2631 | } |
| | 2632 | |
| | 2633 | shape1PointsPtr++; |
| | 2634 | shape2PointsPtr++; |
| | 2635 | morphedPointsPtr++; |
| | 2636 | } |
| | 2637 | } |
| | 2638 | |
| | 2639 | Global_ShapePoints = (int*)MorphedPts; |
| | 2640 | srcPtr = (VECTORCH *)MorphedPts; |
| | 2641 | } |
| | 2642 | } |
| | 2643 | |
| | 2644 | for(; i; i--) |
| | 2645 | { |
| | 2646 | destPtr->vx = srcPtr->vx + Global_ODB_Ptr->ObWorld.vx; |
| | 2647 | destPtr->vy = srcPtr->vy + Global_ODB_Ptr->ObWorld.vy; |
| | 2648 | destPtr->vz = srcPtr->vz + Global_ODB_Ptr->ObWorld.vz; |
| | 2649 | |
| | 2650 | TranslatePointIntoViewspace(destPtr); |
| | 2651 | |
| | 2652 | srcPtr++; |
| | 2653 | destPtr++; |
| | 2654 | } |
| | 2655 | } |
| | 2656 | |
| | 2657 | static void TranslateShapeVertices(SHAPEINSTR *shapeinstrptr) |
| | 2658 | { |
| | 2659 | int** shapeitemarrayptr = shapeinstrptr->sh_instr_data; |
| | 2660 | int i = shapeinstrptr->sh_numitems; |
| | 2661 | VECTORCH *destPtr = RotatedPts; |
| | 2662 | VECTORCH *srcPtr = (VECTORCH*)*shapeitemarrayptr; |
| | 2663 | float ObjectViewMatrix[12], Source[3], Dest[3]; |
| | 2664 | |
| | 2665 | ObjectViewMatrix[0+0*4] = (float)(Global_ODB_Ptr->ObMat.mat11)/65536.0f; |
| | 2666 | ObjectViewMatrix[1+0*4] = (float)(Global_ODB_Ptr->ObMat.mat21)/65536.0f; |
| | 2667 | ObjectViewMatrix[2+0*4] = (float)(Global_ODB_Ptr->ObMat.mat31)/65536.0f; |
| | 2668 | |
| | 2669 | ObjectViewMatrix[0+1*4] = (float)(Global_ODB_Ptr->ObMat.mat12)/65536.0f; |
| | 2670 | ObjectViewMatrix[1+1*4] = (float)(Global_ODB_Ptr->ObMat.mat22)/65536.0f; |
| | 2671 | ObjectViewMatrix[2+1*4] = (float)(Global_ODB_Ptr->ObMat.mat32)/65536.0f; |
| | 2672 | |
| | 2673 | ObjectViewMatrix[0+2*4] = (float)(Global_ODB_Ptr->ObMat.mat13)/65536.0f; |
| | 2674 | ObjectViewMatrix[1+2*4] = (float)(Global_ODB_Ptr->ObMat.mat23)/65536.0f; |
| | 2675 | ObjectViewMatrix[2+2*4] = (float)(Global_ODB_Ptr->ObMat.mat33)/65536.0f; |
| | 2676 | |
| | 2677 | ObjectViewMatrix[3+0*4] = Global_ODB_Ptr->ObWorld.vx; |
| | 2678 | ObjectViewMatrix[3+1*4] = Global_ODB_Ptr->ObWorld.vy; |
| | 2679 | ObjectViewMatrix[3+2*4] = Global_ODB_Ptr->ObWorld.vz; |
| | 2680 | |
| | 2681 | while(i--) |
| | 2682 | { |
| | 2683 | Source[0] = srcPtr->vx; |
| | 2684 | Source[1] = srcPtr->vy; |
| | 2685 | Source[2] = srcPtr->vz; |
| | 2686 | |
| | 2687 | TranslatePoint(ObjectViewMatrix, Source, Dest); |
| | 2688 | TranslatePoint(ViewMatrix, Dest, Source); |
| | 2689 | |
| | 2690 | destPtr->vx = (int)Source[0]; |
| | 2691 | destPtr->vy = (int)Source[1]; |
| | 2692 | destPtr->vz = (int)Source[2]; |
| | 2693 | |
| | 2694 | srcPtr++; |
| | 2695 | destPtr++; |
| | 2696 | } |
| | 2697 | } |
| | 2698 | |
| | 2699 | static int predator_vision(struct shapeheader* shapePtr) |
| | 2700 | { |
| | 2701 | switch(PlayerStatus.VisionMode) |
| | 2702 | { |
| | 2703 | case VISION_MODE_PRED_THERMAL: |
| | 2704 | { |
| | 2705 | /* if we have an object with heat sources, draw it as such */ |
| | 2706 | if (NumberOfHeatSources) |
| | 2707 | { |
| | 2708 | PredatorThermalVision_ShapePipeline(shapePtr); |
| | 2709 | return 1; |
| | 2710 | } |
| | 2711 | } |
| | 2712 | return 0; |
| | 2713 | case VISION_MODE_PRED_SEEALIENS: |
| | 2714 | { |
| | 2715 | STRATEGYBLOCK *sbPtr = Global_ODB_Ptr->ObStrategyBlock; |
| | 2716 | |
| | 2717 | if(sbPtr) |
| | 2718 | { |
| | 2719 | switch (sbPtr->type) |
| | 2720 | { |
| | 2721 | case I_BehaviourAlien: |
| | 2722 | case I_BehaviourAlienPlayer: |
| | 2723 | case I_BehaviourFaceHugger: |
| | 2724 | case I_BehaviourXenoborg: |
| | 2725 | case I_BehaviourQueenAlien: |
| | 2726 | break; |
| | 2727 | case I_BehaviourHierarchicalFragment: |
| | 2728 | { |
| | 2729 | HDEBRIS_BEHAV_BLOCK *debrisDataPtr = (HDEBRIS_BEHAV_BLOCK *)sbPtr->dataptr; |
| | 2730 | |
| | 2731 | switch(debrisDataPtr->Type) |
| | 2732 | { |
| | 2733 | case I_BehaviourAlien: |
| | 2734 | case I_BehaviourQueenAlien: |
| | 2735 | case I_BehaviourFaceHugger: |
| | 2736 | case I_BehaviourXenoborg: |
| | 2737 | case I_BehaviourAlienPlayer: |
| | 2738 | break; |
| | 2739 | default: |
| | 2740 | return 0; |
| | 2741 | } |
| | 2742 | } |
| | 2743 | break; |
| | 2744 | case I_BehaviourCorpse: |
| | 2745 | { |
| | 2746 | CORPSEDATABLOCK *corpseDataPtr = (CORPSEDATABLOCK *)sbPtr->dataptr; |
| | 2747 | |
| | 2748 | switch(corpseDataPtr->Type) |
| | 2749 | { |
| | 2750 | case I_BehaviourAlien: |
| | 2751 | case I_BehaviourAlienPlayer: |
| | 2752 | case I_BehaviourFaceHugger: |
| | 2753 | case I_BehaviourXenoborg: |
| | 2754 | case I_BehaviourQueenAlien: |
| | 2755 | break; |
| | 2756 | default: |
| | 2757 | return 0; |
| | 2758 | } |
| | 2759 | } |
| | 2760 | break; |
| | 2761 | case I_BehaviourNetGhost: |
| | 2762 | { |
| | 2763 | NETGHOSTDATABLOCK *ghostDataPtr = (NETGHOSTDATABLOCK *)Global_ODB_Ptr->ObStrategyBlock->dataptr; |
| | 2764 | |
| | 2765 | switch(ghostDataPtr->type) |
| | 2766 | { |
| | 2767 | case I_BehaviourCorpse: |
| | 2768 | if (ghostDataPtr->subtype != I_BehaviourAlienPlayer) |
| | 2769 | return 0; |
| | 2770 | case I_BehaviourAlienPlayer: |
| | 2771 | case I_BehaviourAlien: |
| | 2772 | break; |
| | 2773 | default: |
| | 2774 | return 0; |
| | 2775 | } |
| | 2776 | } |
| | 2777 | break; |
| | 2778 | case I_BehaviourSpeargunBolt: |
| | 2779 | { |
| | 2780 | SPEAR_BEHAV_BLOCK *spearDataPtr = (SPEAR_BEHAV_BLOCK *)sbPtr->dataptr; |
| | 2781 | |
| | 2782 | if (spearDataPtr->SpearThroughFragment) // more flags required! |
| | 2783 | { |
| | 2784 | switch(spearDataPtr->Type) |
| | 2785 | { |
| | 2786 | case I_BehaviourAlien: |
| | 2787 | case I_BehaviourQueenAlien: |
| | 2788 | case I_BehaviourFaceHugger: |
| | 2789 | case I_BehaviourXenoborg: |
| | 2790 | case I_BehaviourAlienPlayer: |
| | 2791 | break; |
| | 2792 | default: |
| | 2793 | return 0; |
| | 2794 | } |
| | 2795 | } |
| | 2796 | } |
| | 2797 | default: |
| | 2798 | return 0; |
| | 2799 | } |
| | 2800 | |
| | 2801 | PredatorSeeAliensVision_ShapePipeline(shapePtr); |
| | 2802 | return 1; |
| | 2803 | } |
| | 2804 | } |
| | 2805 | break; |
| | 2806 | case VISION_MODE_PRED_SEEPREDTECH: |
| | 2807 | { |
| | 2808 | STRATEGYBLOCK *sbPtr = Global_ODB_Ptr->ObStrategyBlock; |
| | 2809 | |
| | 2810 | if(sbPtr) |
| | 2811 | { |
| | 2812 | switch (sbPtr->type) |
| | 2813 | { |
| | 2814 | case I_BehaviourPredator: |
| | 2815 | { |
| | 2816 | PREDATOR_STATUS_BLOCK *predData = (PREDATOR_STATUS_BLOCK *)Global_ODB_Ptr->ObStrategyBlock->dataptr; |
| | 2817 | |
| | 2818 | if (predData->CloakingEffectiveness) |
| | 2819 | return 0; |
| | 2820 | } |
| | 2821 | case I_BehaviourPredatorDisc_SeekTrack: |
| | 2822 | break; |
| | 2823 | case I_BehaviourCorpse: |
| | 2824 | { |
| | 2825 | CORPSEDATABLOCK *corpseDataPtr = (CORPSEDATABLOCK *)sbPtr->dataptr; |
| | 2826 | |
| | 2827 | switch(corpseDataPtr->Type) |
| | 2828 | { |
| | 2829 | case I_BehaviourPredator: |
| | 2830 | case I_BehaviourPredatorPlayer: |
| | 2831 | break; |
| | 2832 | default: |
| | 2833 | return 0; |
| | 2834 | } |
| | 2835 | } |
| | 2836 | break; |
| | 2837 | case I_BehaviourHierarchicalFragment: |
| | 2838 | { |
| | 2839 | HDEBRIS_BEHAV_BLOCK *debrisDataPtr = (HDEBRIS_BEHAV_BLOCK *)sbPtr->dataptr; |
| | 2840 | |
| | 2841 | if (debrisDataPtr->Type != I_BehaviourPredator) |
| | 2842 | return 0; |
| | 2843 | } |
| | 2844 | break; |
| | 2845 | case I_BehaviourNetGhost: |
| | 2846 | { |
| | 2847 | NETGHOSTDATABLOCK *ghostDataPtr = (NETGHOSTDATABLOCK *)Global_ODB_Ptr->ObStrategyBlock->dataptr; |
| | 2848 | |
| | 2849 | if(!ghostDataPtr->CloakingEffectiveness) |
| | 2850 | { |
| | 2851 | switch(ghostDataPtr->type) |
| | 2852 | { |
| | 2853 | case I_BehaviourCorpse: |
| | 2854 | if (ghostDataPtr->subtype != I_BehaviourPredatorPlayer) |
| | 2855 | return 0; |
| | 2856 | case I_BehaviourInanimateObject: |
| | 2857 | if (ghostDataPtr->IOType != IOT_Ammo && ghostDataPtr->subtype != AMMO_PRED_DISC) |
| | 2858 | return 0; |
| | 2859 | case I_BehaviourPredator: |
| | 2860 | case I_BehaviourPredatorPlayer: |
| | 2861 | case I_BehaviourPredatorDisc_SeekTrack: |
| | 2862 | break; |
| | 2863 | default: |
| | 2864 | return 0; |
| | 2865 | } |
| | 2866 | } |
| | 2867 | } |
| | 2868 | break; |
| | 2869 | case I_BehaviourInanimateObject: |
| | 2870 | { |
| | 2871 | INANIMATEOBJECT_STATUSBLOCK* objStatPtr = (INANIMATEOBJECT_STATUSBLOCK*) sbPtr->dataptr; |
| | 2872 | |
| | 2873 | switch(objStatPtr->typeId) |
| | 2874 | { |
| | 2875 | case IOT_FieldCharge: |
| | 2876 | break; |
| | 2877 | case IOT_Weapon: |
| | 2878 | if(WEAPON_PRED_DISC == objStatPtr->subType) |
| | 2879 | break; |
| | 2880 | case IOT_Ammo: |
| | 2881 | if(AMMO_PRED_RIFLE == objStatPtr->subType) |
| | 2882 | break; |
| | 2883 | default: |
| | 2884 | return 0; |
| | 2885 | } |
| | 2886 | } |
| | 2887 | break; |
| | 2888 | case I_BehaviourSpeargunBolt: |
| | 2889 | { |
| | 2890 | SPEAR_BEHAV_BLOCK *spearDataPtr = (SPEAR_BEHAV_BLOCK *)sbPtr->dataptr; |
| | 2891 | |
| | 2892 | if (spearDataPtr->SpearThroughFragment) // more flags required! |
| | 2893 | { |
| | 2894 | switch(spearDataPtr->Type) |
| | 2895 | { |
| | 2896 | case I_BehaviourPredator: |
| | 2897 | case I_BehaviourPredatorPlayer: |
| | 2898 | break; |
| | 2899 | default: |
| | 2900 | return 0; |
| | 2901 | } |
| | 2902 | } |
| | 2903 | else |
| | 2904 | break; |
| | 2905 | } |
| | 2906 | default: |
| | 2907 | return 0; |
| | 2908 | } |
| | 2909 | |
| | 2910 | PredatorSeeAliensVision_ShapePipeline(shapePtr); |
| | 2911 | return 1; |
| | 2912 | } |
| | 2913 | } |
| | 2914 | default: |
| | 2915 | return 0; |
| | 2916 | } |
| | 2917 | |
| | 2918 | return 0; |
| | 2919 | } |
| | 2920 | |
| | 2921 | int jadda(struct shapeheader* shapeheaderptr) |
| | 2922 | { |
| | 2923 | /* interesting hack for predator cloaking */ |
| | 2924 | |
| | 2925 | int numitems = shapeheaderptr->numitems; |
| | 2926 | int **itemArrayPtr = shapeheaderptr->items; |
| | 2927 | |
| | 2928 | int CloakingEffectiveness; |
| | 2929 | |
| | 2930 | switch(Global_ODB_Ptr->ObStrategyBlock->type) |
| | 2931 | { |
| | 2932 | case I_BehaviourNetGhost: |
| | 2933 | { |
| | 2934 | NETGHOSTDATABLOCK *ghostData = (NETGHOSTDATABLOCK *)Global_ODB_Ptr->ObStrategyBlock->dataptr; |
| | 2935 | |
| | 2936 | if(!ghostData->CloakingEffectiveness) |
| | 2937 | return 0; |
| | 2938 | |
| | 2939 | CloakingEffectiveness = ghostData->CloakingEffectiveness; |
| | 2940 | } |
| | 2941 | break; |
| | 2942 | case I_BehaviourPredator: |
| | 2943 | { |
| | 2944 | PREDATOR_STATUS_BLOCK *predData = (PREDATOR_STATUS_BLOCK *)Global_ODB_Ptr->ObStrategyBlock->dataptr; |
| | 2945 | |
| | 2946 | if (!predData->CloakingEffectiveness) |
| | 2947 | return 0; |
| | 2948 | |
| | 2949 | CloakingEffectiveness = predData->CloakingEffectiveness; |
| | 2950 | } |
| | 2951 | default: |
| | 2952 | return 0; |
| | 2953 | } |
| | 2954 | |
| | 2955 | do |
| | 2956 | { |
| | 2957 | POLYHEADER *polyPtr = (POLYHEADER*) (*itemArrayPtr++); |
| | 2958 | int pif = PolygonWithinFrustrum(polyPtr); |
| | 2959 | |
| | 2960 | if(pif) |
| | 2961 | { |
| | 2962 | switch(polyPtr->PolyItemType) |
| | 2963 | { |
| | 2964 | case I_ZB_Gouraud3dTexturedPolygon: |
| | 2965 | case I_ZB_Gouraud2dTexturedPolygon: |
| | 2966 | { |
| | 2967 | CloakedPolygon_Construct(polyPtr, ((ONE_FIXED * 5 / 4) - CloakingEffectiveness)); |
| | 2968 | |
| | 2969 | if ((pif < 0) && !ClipPolygon(RenderPolygon.NumberOfVertices)) |
| | 2970 | break; |
| | 2971 | |
| | 2972 | ZBufferedCloakedPolygon_Output((polyPtr->PolyColour & ClrTxDefn), draw_vertices); |
| | 2973 | } |
| | 2974 | break; |
| | 2975 | default: |
| | 2976 | printf("found polygon of type %d\n", polyPtr->PolyItemType); |
| | 2977 | } |
| | 2978 | } |
| | 2979 | |
| | 2980 | } while(--numitems); |
| | 2981 | |
| | 2982 | return 1; |
| | 2983 | } |
| | 2984 | |
| | 2985 | static void ShapePipeline(struct shapeheader* shapePtr) |
| | 2986 | { |
| | 2987 | int numitems = shapePtr->numitems; |
| | 2988 | int **itemArrayPtr = shapePtr->items; |
| | 2989 | |
| | 2990 | assert(numitems); |
| | 2991 | |
| | 2992 | if(Global_ODB_Ptr->ObStrategyBlock && jadda(shapePtr)) |
| | 2993 | return; |
| | 2994 | |
| | 2995 | do |
| | 2996 | { |
| | 2997 | POLYHEADER *polyPtr = (POLYHEADER*) (*itemArrayPtr++); |
| | 2998 | |
| | 2999 | int pif = PolygonWithinFrustrum(polyPtr); |
| | 3000 | |
| | 3001 | if (pif) |
| | 3002 | { |
| | 3003 | switch(polyPtr->PolyItemType) |
| | 3004 | { |
| | 3005 | case I_ZB_GouraudPolygon: |
| | 3006 | { |
| | 3007 | RENDERVERTEX *renderVerticesPtr = VerticesUnClipped; |
| | 3008 | int i = RenderPolygon.NumberOfVertices; |
| | 3009 | VertexNumberPtr = &polyPtr->Poly1stPt; |
| | 3010 | |
| | 3011 | do |
| | 3012 | { |
| | 3013 | renderVerticesPtr->X = RotatedPts[*VertexNumberPtr].vx; |
| | 3014 | renderVerticesPtr->Y = RotatedPts[*VertexNumberPtr].vy; |
| | 3015 | renderVerticesPtr->Z = RotatedPts[*VertexNumberPtr].vz; |
| | 3016 | VertexIntensity(renderVerticesPtr); |
| | 3017 | renderVerticesPtr->R = renderVerticesPtr->G = (renderVerticesPtr->B + renderVerticesPtr->R + renderVerticesPtr->G) / 3; |
| | 3018 | renderVerticesPtr->B = 0; |
| | 3019 | renderVerticesPtr->A = (polyPtr->PolyFlags & iflag_transparent) ? 0 : 255; |
| | 3020 | renderVerticesPtr++; |
| | 3021 | VertexNumberPtr++; |
| | 3022 | |
| | 3023 | } while(--i); |
| | 3024 | |
| | 3025 | |
| | 3026 | if ((pif < 0) && !ClipPolygon(RenderPolygon.NumberOfVertices)) |
| | 3027 | { |
| | 3028 | } |
| | 3029 | else |
| | 3030 | { |
| | 3031 | Polygon(draw_vertices, TRANSLUCENCY_OFF); |
| | 3032 | } |
| | 3033 | } |
| | 3034 | break; |
| | 3035 | case I_ZB_Gouraud3dTexturedPolygon: |
| | 3036 | case I_ZB_Gouraud2dTexturedPolygon: |
| | 3037 | { |
| | 3038 | GouraudTexturedPolygon_Construct(polyPtr); |
| | 3039 | |
| | 3040 | int texture_number = (polyPtr->PolyColour & ClrTxDefn); |
| | 3041 | |
| | 3042 | if (pif < 0) |
| | 3043 | { |
| | 3044 | /* if this polygon is a quad, split it into two */ |
| | 3045 | if(RenderPolygon.NumberOfVertices == 4) |
| | 3046 | { |
| | 3047 | RENDERVERTEX TriangleVerticesBuffer[3] = { VerticesUnClipped[0], VerticesUnClipped[2], VerticesUnClipped[3] }; |
| | 3048 | |
| | 3049 | if(ClipPolygon(3)) |
| | 3050 | { |
| | 3051 | if (polyPtr->PolyFlags & iflag_transparent) |
| | 3052 | AddToTranslucentPolyList(texture_number, polyPtr->PolyFlags, draw_vertices); |
| | 3053 | else |
| | 3054 | TexturedPolygon(texture_number, draw_vertices, RenderPolygon.TranslucencyMode); |
| | 3055 | } |
| | 3056 | |
| | 3057 | VerticesUnClipped[0] = TriangleVerticesBuffer[0]; |
| | 3058 | VerticesUnClipped[1] = TriangleVerticesBuffer[1]; |
| | 3059 | VerticesUnClipped[2] = TriangleVerticesBuffer[2]; |
| | 3060 | } |
| | 3061 | |
| | 3062 | if(ClipPolygon(3)) |
| | 3063 | { |
| | 3064 | if (polyPtr->PolyFlags & iflag_transparent) |
| | 3065 | AddToTranslucentPolyList(texture_number, polyPtr->PolyFlags, draw_vertices); |
| | 3066 | else |
| | 3067 | TexturedPolygon(texture_number, draw_vertices, RenderPolygon.TranslucencyMode); |
| | 3068 | } |
| | 3069 | } |
| | 3070 | else |
| | 3071 | { |
| | 3072 | if (polyPtr->PolyFlags & iflag_transparent) |
| | 3073 | AddToTranslucentPolyList(texture_number, polyPtr->PolyFlags, draw_vertices); |
| | 3074 | else |
| | 3075 | TexturedPolygon(texture_number, draw_vertices, RenderPolygon.TranslucencyMode); |
| | 3076 | } |
| | 3077 | } |
| | 3078 | default: |
| | 3079 | break; |
| | 3080 | } |
| | 3081 | } |
| | 3082 | |
| | 3083 | } while(--numitems); |
| | 3084 | } |
| | 3085 | |
| | 3086 | static void HandleObjectOnFire(DISPLAYBLOCK *dispPtr) |
| | 3087 | { |
| | 3088 | int noRequired = 1; |
| | 3089 | int i; |
| | 3090 | VECTORCH velocity; |
| | 3091 | |
| | 3092 | if (dispPtr->extent.radius <= LocalDetailLevels.AlienEnergyViewThreshold) |
| | 3093 | return; |
| | 3094 | |
| | 3095 | { |
| | 3096 | STRATEGYBLOCK *sbPtr = dispPtr->ObStrategyBlock; |
| | 3097 | DYNAMICSBLOCK *dynPtr = sbPtr->DynPtr; |
| | 3098 | |
| | 3099 | velocity.vx = DIV_FIXED((dynPtr->Position.vx - dynPtr->PrevPosition.vx)*3, NormalFrameTime*4); |
| | 3100 | velocity.vy = DIV_FIXED((dynPtr->Position.vy - dynPtr->PrevPosition.vy)*3, NormalFrameTime*4); |
| | 3101 | velocity.vz = DIV_FIXED((dynPtr->Position.vz - dynPtr->PrevPosition.vz)*3, NormalFrameTime*4); |
| | 3102 | |
| | 3103 | if (dispPtr == sbPtr->DisplayBlock) |
| | 3104 | noRequired = 5; |
| | 3105 | } |
| | 3106 | |
| | 3107 | int objectIsDisappearing = ( (dispPtr->SpecialFXFlags & SFXFLAG_MELTINGINTOGROUND) && (dispPtr->ObFlags2 <= ONE_FIXED) ); |
| | 3108 | |
| | 3109 | for (i=0; i < noRequired; i++) |
| | 3110 | { |
| | 3111 | VECTORCH position; |
| | 3112 | position.vx = dispPtr->ObWorld.vx + (FastRandom() & 255)-128; |
| | 3113 | position.vy = dispPtr->ObWorld.vy + (FastRandom() & 255)-128; |
| | 3114 | position.vz = dispPtr->ObWorld.vz + (FastRandom() & 255)-128; |
| | 3115 | |
| | 3116 | if (objectIsDisappearing) |
| | 3117 | { |
| | 3118 | if ((FastRandom()&65535) < dispPtr->ObFlags2) |
| | 3119 | MakeParticle(&position, &velocity, PARTICLE_FIRE); |
| | 3120 | } |
| | 3121 | else |
| | 3122 | { |
| | 3123 | MakeParticle(&position, &velocity, PARTICLE_FIRE); |
| | 3124 | } |
| | 3125 | |
| | 3126 | if ((FastRandom() & 65535) > 32768) |
| | 3127 | MakeParticle(&position, &velocity, PARTICLE_IMPACTSMOKE); |
| | 3128 | } |
| | 3129 | } |
| | 3130 | |
| | 3131 | void AddShape(DISPLAYBLOCK *dptr) |
| | 3132 | { |
| | 3133 | struct shapeheader* shapeheaderptr = dptr->ShapeData; |
| | 3134 | |
| | 3135 | int f=1; |
| | 3136 | if (dptr->ObStrategyBlock) |
| | 3137 | { |
| | 3138 | if(dptr->ObStrategyBlock->type == I_BehaviourPlacedLight) |
| | 3139 | f=0; |
| | 3140 | } |
| | 3141 | |
| | 3142 | if(dptr->ObTxAnimCtrlBlks) |
| | 3143 | ControlTextureAnimation(dptr); |
| | 3144 | //if(f) |
| | 3145 | { |
| | 3146 | SetupShapePipeline(dptr); |
| | 3147 | |
| | 3148 | TranslateShapeVertices(shapeheaderptr->sh_instruction); |
| | 3149 | TestVerticesWithFrustrum(shapeheaderptr->numpoints); |
| | 3150 | |
| | 3151 | if(!predator_vision(shapeheaderptr)) |
| | 3152 | ShapePipeline(shapeheaderptr); |
| | 3153 | } |
| | 3154 | |
| | 3155 | //if(0) |
| | 3156 | if (dptr->ObStrategyBlock) |
| | 3157 | { |
| | 3158 | if(dptr->ObStrategyBlock->DamageBlock.IsOnFire) |
| | 3159 | { |
| | 3160 | dptr->SpecialFXFlags |= SFXFLAG_ONFIRE; |
| | 3161 | HandleObjectOnFire(dptr); |
| | 3162 | } |
| | 3163 | else |
| | 3164 | dptr->SpecialFXFlags &= ~SFXFLAG_ONFIRE; |
| | 3165 | |
| | 3166 | switch(dptr->ObStrategyBlock->type) |
| | 3167 | { |
| | 3168 | case I_BehaviourPlacedLight: |
| | 3169 | { |
| | 3170 | STRATEGYBLOCK *sbPtr = dptr->ObStrategyBlock; |
| | 3171 | PLACED_LIGHT_BEHAV_BLOCK* pl_bhv = sbPtr->dataptr; |
| | 3172 | |
| | 3173 | if (pl_bhv->has_corona && pl_bhv->light->LightBright |
| | 3174 | && (ModuleCurrVisArray[sbPtr->containingModule->m_index] > 1) |
| | 3175 | && (pl_bhv->light->RedScale || pl_bhv->light->GreenScale || pl_bhv->light->BlueScale)) |
| | 3176 | { |
| | 3177 | LIGHTBLOCK *lPtr = pl_bhv->light; |
| | 3178 | int colour; |
| | 3179 | VECTORCH position = pl_bhv->corona_location; |
| | 3180 | RotateVector(&position, &dptr->ObMat); |
| | 3181 | position.vx += dptr->ObWorld.vx; |
| | 3182 | position.vy += dptr->ObWorld.vy; |
| | 3183 | position.vz += dptr->ObWorld.vz; |
| | 3184 | |
| | 3185 | |
| | 3186 | |
| | 3187 | |
| | 3188 | switch (PlayerStatus.VisionMode) |
| | 3189 | { |
| | 3190 | case VISION_MODE_NORMAL: |
| | 3191 | default: |
| | 3192 | { |
| | 3193 | int r = MUL_FIXED(lPtr->RedScale, lPtr->LightBright) >> 8; |
| | 3194 | int g = MUL_FIXED(lPtr->GreenScale, lPtr->LightBright) >> 8; |
| | 3195 | int b = MUL_FIXED(lPtr->BlueScale, lPtr->LightBright) >> 8; |
| | 3196 | if (r > 255) r = 255; |
| | 3197 | if (g > 255) g = 255; |
| | 3198 | if (b > 255) b = 255; |
| | 3199 | colour = 0xff000000+(r<<16)+(g<<8)+(b); |
| | 3200 | } |
| | 3201 | break; |
| | 3202 | case VISION_MODE_IMAGEINTENSIFIER: |
| | 3203 | colour = 0xffffffff; |
| | 3204 | break; |
| | 3205 | case VISION_MODE_PRED_THERMAL: |
| | 3206 | case VISION_MODE_PRED_SEEALIENS: |
| | 3207 | case VISION_MODE_PRED_SEEPREDTECH: |
| | 3208 | { |
| | 3209 | int b = MUL_FIXED(lPtr->RedScale+lPtr->GreenScale+lPtr->BlueScale, lPtr->LightBright) >> 10; |
| | 3210 | if (b > 255) b = 255; |
| | 3211 | |
| | 3212 | colour = 0xff000000+(b<<16)+((b>>1)<<8); |
| | 3213 | } |
| | 3214 | } |
| | 3215 | |
| | 3216 | { |
| | 3217 | PARTICLE particle; |
| | 3218 | particle.Position = dptr->ObWorld; |
| | 3219 | //particle.Position = position; |
| | 3220 | particle.Colour = colour; |
| | 3221 | //particle.ParticleID = PARTICLE_MUZZLEFLASH; |
| | 3222 | particle.ParticleID = PARTICLE_LIGHTFLARE; |
| | 3223 | particle.ParticleID = PARTICLE_ORANGE_PLASMA; |
| | 3224 | particle.ParticleID = PARTICLE_STAR; |
| | 3225 | particle.ParticleID = PARTICLE_LIGHT; // jadda |
| | 3226 | particle.Size = 300 * 2; |
| | 3227 | RenderParticle(&particle); |
| | 3228 | } |
| | 3229 | } |
| | 3230 | } |
| | 3231 | break; |
| | 3232 | /* |
| | 3233 | case I_BehaviourInanimateObject: |
| | 3234 | { |
| | 3235 | INANIMATEOBJECT_STATUSBLOCK* objStatPtr = dptr->ObStrategyBlock->dataptr; |
| | 3236 | |
| | 3237 | if(objStatPtr->typeId == IOT_FieldCharge) |
| | 3238 | { |
| | 3239 | int i = 0; |
| | 3240 | DecalSystem_Setup(); |
| | 3241 | |
| | 3242 | for(; i < 63; i++) |
| | 3243 | { |
| | 3244 | PARTICLE particle; |
| | 3245 | |
| | 3246 | // SBF - 20080518 - commented out the undefined usage of particle.Position.vz |
| | 3247 | particle.Position.vy = -280+i-GetCos((CloakingPhase/16*i + i*64)&4095)/1024; |
| | 3248 | particle.Position.vx = GetCos((CloakingPhase +i*64+particle.Position.vy)&4095)/512; |
| | 3249 | particle.Position.vz = GetSin((CloakingPhase +i*64+particle.Position.vy)&4095)/512; |
| | 3250 | RotateVector(&particle.Position, &dptr->ObMat); |
| | 3251 | particle.Position.vx += dptr->ObWorld.vx; |
| | 3252 | particle.Position.vy += dptr->ObWorld.vy; |
| | 3253 | particle.Position.vz += dptr->ObWorld.vz; |
| | 3254 | particle.ParticleID = PARTICLE_MUZZLEFLASH; |
| | 3255 | particle.Colour = 0xff00007f+(FastRandom()&0x7f7f7f); |
| | 3256 | particle.Size = 40; |
| | 3257 | RenderParticle(&particle); |
| | 3258 | } |
| | 3259 | |
| | 3260 | DecalSystem_End(); |
| | 3261 | } |
| | 3262 | } |
| | 3263 | */ |
| | 3264 | default: |
| | 3265 | break; |
| | 3266 | } |
| | 3267 | } |
| | 3268 | } |
| | 3269 | |
| | 3270 | void AddModuleShape(DISPLAYBLOCK *dptr) |
| | 3271 | { |
| | 3272 | struct shapeheader* shapeheaderptr; |
| | 3273 | |
| | 3274 | if(dptr->ObMorphCtrl) |
| | 3275 | { |
| | 3276 | GetMorphDisplay(&MorphDisplay, dptr); |
| | 3277 | dptr->ObShape = MorphDisplay.md_shape1; |
| | 3278 | dptr->ShapeData = MorphDisplay.md_sptr1; |
| | 3279 | shapeheaderptr = MorphDisplay.md_sptr1; |
| | 3280 | SetupShapePipeline(dptr); |
| | 3281 | MorphPoints(shapeheaderptr->sh_instruction); |
| | 3282 | } |
| | 3283 | else |
| | 3284 | { |
| | 3285 | shapeheaderptr = dptr->ShapeData; |
| | 3286 | SetupShapePipeline(dptr); |
| | 3287 | TranslateShapeVertices(shapeheaderptr->sh_instruction); |
| | 3288 | } |
| | 3289 | |
| | 3290 | if(dptr->ObTxAnimCtrlBlks) |
| | 3291 | ControlTextureAnimation(dptr); |
| | 3292 | |
| | 3293 | TestVerticesWithFrustrum(shapeheaderptr->numpoints); |
| | 3294 | ShapePipeline(shapeheaderptr); |
| | 3295 | } |
| | 3296 | |
| | 3297 | void AttachSpearGunArrow(DISPLAYBLOCK *dptr) |
| | 3298 | { |
| | 3299 | struct shapeheader* shapeheaderptr = dptr->ShapeData; |
| | 3300 | |
| | 3301 | SetupShapePipeline(dptr); |
| | 3302 | |
| | 3303 | TranslateShapeVertices(shapeheaderptr->sh_instruction); |
| | 3304 | TestVerticesWithFrustrum(shapeheaderptr->numpoints); |
| | 3305 | ShapePipeline(shapeheaderptr); |
| | 3306 | } |
| | 3307 | |
| | 3308 | void DisplayAlienTeeth(DISPLAYBLOCK *dptr) |
| | 3309 | { |
| | 3310 | struct shapeheader* shapeheaderptr = mainshapelist[dptr->ObShape]; |
| | 3311 | dptr->ShapeData = shapeheaderptr; |
| | 3312 | SetupShapePipeline(dptr); |
| | 3313 | { |
| | 3314 | SHAPEINSTR *shapeinstrptr = shapeheaderptr->sh_instruction; |
| | 3315 | VECTORCH *destPtr = RotatedPts; |
| | 3316 | int** shapeitemarrayptr = shapeinstrptr->sh_instr_data; |
| | 3317 | VECTORCH *srcPtr = (VECTORCH*)*shapeitemarrayptr; |
| | 3318 | int i = shapeinstrptr->sh_numitems; |
| | 3319 | |
| | 3320 | while(i--) |
| | 3321 | { |
| | 3322 | destPtr->vx = (srcPtr->vx + Global_ODB_Ptr->ObView.vx); |
| | 3323 | destPtr->vy = ((srcPtr->vy + Global_ODB_Ptr->ObView.vy) * 4)/3; |
| | 3324 | destPtr->vz = (srcPtr->vz + Global_ODB_Ptr->ObView.vz); |
| | 3325 | |
| | 3326 | srcPtr++; |
| | 3327 | destPtr++; |
| | 3328 | } |
| | 3329 | } |
| | 3330 | TestVerticesWithFrustrum(shapeheaderptr->numpoints); |
| | 3331 | ShapePipeline(shapeheaderptr); |
| | 3332 | } |
| | 3333 | |
| | 3334 | static void SquishPoints(DISPLAYBLOCK * dptr) |
| | 3335 | { |
| | 3336 | struct shapeheader* shapeheaderptr = dptr->ShapeData; |
| | 3337 | int** shapeitemarrayptr = shapeheaderptr->sh_instruction->sh_instr_data; |
| | 3338 | VECTORCH *shapePts = (VECTORCH*)*shapeitemarrayptr; |
| | 3339 | int i; |
| | 3340 | int scale = dptr->ObFlags2; |
| | 3341 | |
| | 3342 | for (i=0; i < shapeheaderptr->numpoints; i++) |
| | 3343 | { |
| | 3344 | VECTORCH point = shapePts[i]; |
| | 3345 | |
| | 3346 | RotateVector(&point, &dptr->ObMat); |
| | 3347 | |
| | 3348 | point.vx = MUL_FIXED(point.vx, ONE_FIXED*3/2 - scale/2); |
| | 3349 | point.vx += dptr->ObWorld.vx; |
| | 3350 | |
| | 3351 | point.vz = MUL_FIXED(point.vz, ONE_FIXED*3/2 - scale/2); |
| | 3352 | point.vz += dptr->ObWorld.vz; |
| | 3353 | |
| | 3354 | point.vy += dptr->ObWorld.vy; |
| | 3355 | point.vy = HierarchicalObjectsLowestYValue + MUL_FIXED(point.vy - HierarchicalObjectsLowestYValue, scale); |
| | 3356 | |
| | 3357 | TranslatePointIntoViewspace(&point); |
| | 3358 | RotatedPts[i].vx = point.vx; |
| | 3359 | RotatedPts[i].vy = point.vy; |
| | 3360 | RotatedPts[i].vz = point.vz; |
| | 3361 | } |
| | 3362 | } |
| | 3363 | |
| | 3364 | void AddHierarchicalShapes(DISPLAYBLOCK *dptr) |
| | 3365 | { |
| | 3366 | if(dptr->ObStrategyBlock->DamageBlock.IsOnFire) |
| | 3367 | dptr->SpecialFXFlags |= SFXFLAG_ONFIRE; |
| | 3368 | else |
| | 3369 | dptr->SpecialFXFlags &= ~SFXFLAG_ONFIRE; |
| | 3370 | |
| | 3371 | ObjectCentre = dptr->ObView; |
| | 3372 | |
| | 3373 | HierarchicalObjectsLowestYValue = dptr->ObStrategyBlock->DynPtr->ObjectVertices[0].vy; |
| | 3374 | |
| | 3375 | if (AvP.PlayerType == I_Alien)// && PlayerStatus.VisionMode == VISION_MODE_NORMAL) |
| | 3376 | { |
| | 3377 | //DoAlienEnergyView(dptr); |
| | 3378 | } |
| | 3379 | else if (PlayerStatus.VisionMode == VISION_MODE_PRED_THERMAL) |
| | 3380 | { |
| | 3381 | NumberOfHeatSources = 0; |
| | 3382 | FindHeatSourcesInHModel(dptr); |
| | 3383 | } |
| | 3384 | |
| | 3385 | DoHModel(dptr); |
| | 3386 | } |
| | 3387 | |
| | 3388 | void AddHierarchicalShape(DISPLAYBLOCK *dptr) |
| | 3389 | { |
| | 3390 | struct shapeheader* shapeheaderptr = dptr->ShapeData; |
| | 3391 | |
| | 3392 | /* Texture Animation Control */ |
| | 3393 | if(dptr->ObTxAnimCtrlBlks) |
| | 3394 | ControlTextureAnimation(dptr); |
| | 3395 | |
| | 3396 | SetupShapePipeline(dptr); |
| | 3397 | |
| | 3398 | switch(UserProfile.active_bonus) |
| | 3399 | { |
| | 3400 | case CHEATMODE_BALLSOFFIRE: |
| | 3401 | dptr->SpecialFXFlags |= SFXFLAG_ONFIRE; |
| | 3402 | case CHEATMODE_PIPECLEANER: |
| | 3403 | if(!dptr->ObStrategyBlock) |
| | 3404 | break; |
| | 3405 | case CHEATMODE_NONACTIVE: |
| | 3406 | default: |
| | 3407 | { |
| | 3408 | // setup the rotated points array |
| | 3409 | |
| | 3410 | if((dptr->SpecialFXFlags & SFXFLAG_MELTINGINTOGROUND) && (dptr->ObFlags2 <= ONE_FIXED)) |
| | 3411 | SquishPoints(dptr); |
| | 3412 | else |
| | 3413 | TranslateShapeVertices(shapeheaderptr->sh_instruction); |
| | 3414 | |
| | 3415 | TestVerticesWithFrustrum(shapeheaderptr->numpoints); |
| | 3416 | |
| | 3417 | if(!predator_vision(shapeheaderptr)) |
| | 3418 | ShapePipeline(shapeheaderptr); |
| | 3419 | } |
| | 3420 | } |
| | 3421 | |
| | 3422 | if (dptr->SpecialFXFlags & SFXFLAG_ONFIRE) |
| | 3423 | HandleObjectOnFire(dptr); |
| | 3424 | } |
| | 3425 | |
| | 3426 | void AddPlayersWeaponShape(DISPLAYBLOCK *dptr) |
| | 3427 | { |
| | 3428 | struct shapeheader* shapeheaderptr = dptr->ShapeData; |
| | 3429 | |
| | 3430 | SetupShapePipeline(dptr); |
| | 3431 | |
| | 3432 | /* setup the rotated points array */ |
| | 3433 | |
| | 3434 | TranslateShapeVertices(shapeheaderptr->sh_instruction); |
| | 3435 | |
| | 3436 | TestVerticesWithFrustrum(shapeheaderptr->numpoints); |
| | 3437 | |
| | 3438 | if(I_Predator == AvP.PlayerType) |
| | 3439 | { |
| | 3440 | if (PlayerStatus.cloakOn || PlayerStatus.CloakingEffectiveness) |
| | 3441 | { |
| | 3442 | int numitems = shapeheaderptr->numitems; |
| | 3443 | int **itemArrayPtr = shapeheaderptr->items; |
| | 3444 | |
| | 3445 | int a = GetSin(CloakingPhase & 4095); |
| | 3446 | a = MUL_FIXED(a, a); |
| | 3447 | int CloakingMode = ONE_FIXED * 5 / 4 - PlayerStatus.CloakingEffectiveness; |
| | 3448 | |
| | 3449 | do |
| | 3450 | { |
| | 3451 | POLYHEADER *polyPtr = (POLYHEADER*) (*itemArrayPtr++); |
| | 3452 | int pif = PolygonWithinFrustrum(polyPtr); |
| | 3453 | |
| | 3454 | if(pif) |
| | 3455 | { |
| | 3456 | switch(polyPtr->PolyItemType) |
| | 3457 | { |
| | 3458 | case I_ZB_Gouraud3dTexturedPolygon: |
| | 3459 | case I_ZB_Gouraud2dTexturedPolygon: |
| | 3460 | { |
| | 3461 | CloakedPolygon_Construct(polyPtr, CloakingMode); |
| | 3462 | |
| | 3463 | if ((pif < 0) && !ClipPolygon(RenderPolygon.NumberOfVertices)) |
| | 3464 | break; |
| | 3465 | |
| | 3466 | ZBufferedCloakedPolygon_Output((polyPtr->PolyColour & ClrTxDefn), draw_vertices); |
| | 3467 | } |
| | 3468 | break; |
| | 3469 | default: |
| | 3470 | printf("found polygon of type %d\n",polyPtr->PolyItemType); |
| | 3471 | } |
| | 3472 | } |
| | 3473 | |
| | 3474 | } while(--numitems); |
| | 3475 | } |
| | 3476 | else if(VISION_MODE_PRED_SEEPREDTECH == PlayerStatus.VisionMode) |
| | 3477 | PredatorSeeAliensVision_ShapePipeline(shapeheaderptr); |
| | 3478 | else |
| | 3479 | ShapePipeline(shapeheaderptr); |
| | 3480 | } |
| | 3481 | else |
| | 3482 | { |
| | 3483 | ShapePipeline(shapeheaderptr); |
| | 3484 | } |
| | 3485 | } |
| | 3486 | |
| | 3487 | void TranslationSetup() |
| | 3488 | { |
| | 3489 | VECTORCH v = Global_VDB.VDB_World; |
| | 3490 | float p = (PredatorVisionChangeCounter / 65536.0f) + 1.0f; |
| | 3491 | CurrentNumberOfTranslucentPolygons = 0; // put it here just it make variable static |
| | 3492 | RotateVector(&v, &Global_VDB.VDB_Mat); |
| | 3493 | |
| | 3494 | if (CHEATMODE_NAUSEA != UserProfile.active_bonus) |
| | 3495 | { |
| | 3496 | ViewMatrix[0+0*4] = (float)(Global_VDB.VDB_Mat.mat11)/65536.0f; |
| | 3497 | ViewMatrix[1+0*4] = (float)(Global_VDB.VDB_Mat.mat21)/65536.0f; |
| | 3498 | ViewMatrix[2+0*4] = (float)(Global_VDB.VDB_Mat.mat31)/65536.0f; |
| | 3499 | ViewMatrix[3+0*4] = ((float)-v.vx); |
| | 3500 | } |
| | 3501 | else |
| | 3502 | { |
| | 3503 | float o; |
| | 3504 | p = (GetSin((CloakingPhase/3) & 4095))/65536.0f; |
| | 3505 | p = 1.0f + p*p; |
| | 3506 | |
| | 3507 | o = (GetCos((CloakingPhase/5) & 4095))/65536.0f; |
| | 3508 | o = 1.0f + o*o; |
| | 3509 | |
| | 3510 | ViewMatrix[0+0*4] = (float)(Global_VDB.VDB_Mat.mat11)/65536.0f * o; |
| | 3511 | ViewMatrix[1+0*4] = (float)(Global_VDB.VDB_Mat.mat21)/65536.0f * o; |
| | 3512 | ViewMatrix[2+0*4] = (float)(Global_VDB.VDB_Mat.mat31)/65536.0f * o; |
| | 3513 | ViewMatrix[3+0*4] = ((float)-v.vx) * o; |
| | 3514 | } |
| | 3515 | |
| | 3516 | #if 1 |
| | 3517 | ViewMatrix[0+1*4] = (float)(Global_VDB.VDB_Mat.mat12)*4.0f/(65536.0f*3.0f)*p; |
| | 3518 | ViewMatrix[1+1*4] = (float)(Global_VDB.VDB_Mat.mat22)*4.0f/(65536.0f*3.0f)*p; |
| | 3519 | ViewMatrix[2+1*4] = (float)(Global_VDB.VDB_Mat.mat32)*4.0f/(65536.0f*3.0f)*p; |
| | 3520 | #else |
| | 3521 | ViewMatrix[0+1*4] = (float)(Global_VDB.VDB_Mat.mat12)/65536.0f; |
| | 3522 | ViewMatrix[1+1*4] = (float)(Global_VDB.VDB_Mat.mat22)/65536.0f; |
| | 3523 | ViewMatrix[2+1*4] = (float)(Global_VDB.VDB_Mat.mat32)/65536.0f; |
| | 3524 | #endif |
| | 3525 | |
| | 3526 | ViewMatrix[0+2*4] = (float)(Global_VDB.VDB_Mat.mat13)/65536.0f * CameraZoomScale; |
| | 3527 | ViewMatrix[1+2*4] = (float)(Global_VDB.VDB_Mat.mat23)/65536.0f * CameraZoomScale; |
| | 3528 | ViewMatrix[2+2*4] = (float)(Global_VDB.VDB_Mat.mat33)/65536.0f * CameraZoomScale; |
| | 3529 | |
| | 3530 | ViewMatrix[3+1*4] = ((float)-v.vy)*4.0f/3.0f*p; |
| | 3531 | ViewMatrix[3+2*4] = ((float)-v.vz)*CameraZoomScale; |
| | 3532 | |
| | 3533 | if (CHEATMODE_MIRROR == UserProfile.active_bonus) |
| | 3534 | { |
| | 3535 | ViewMatrix[0+0*4] = -ViewMatrix[0+0*4]; |
| | 3536 | ViewMatrix[1+0*4] = -ViewMatrix[1+0*4]; |
| | 3537 | ViewMatrix[2+0*4] = -ViewMatrix[2+0*4]; |
| | 3538 | ViewMatrix[3+0*4] = -ViewMatrix[3+0*4]; |
| | 3539 | } |
| | 3540 | } |
| | 3541 | |
| | 3542 | static void DecalPolygon_Construct(const DECAL *decalPtr) |
| | 3543 | { |
| | 3544 | DECAL_DESC *decalDescPtr = &DecalDescription[decalPtr->DecalID]; |
| | 3545 | RENDERVERTEX *VerticesBuffer = VerticesUnClipped; |
| | 3546 | |
| | 3547 | RenderPolygon.NumberOfVertices = 4; |
| | 3548 | |
| | 3549 | VerticesBuffer->U = decalDescPtr->StartU + decalPtr->UOffset; |
| | 3550 | VerticesBuffer->V = decalDescPtr->StartV; |
| | 3551 | VerticesBuffer++; |
| | 3552 | |
| | 3553 | VerticesBuffer->U = decalDescPtr->EndU + decalPtr->UOffset; |
| | 3554 | VerticesBuffer->V = decalDescPtr->StartV; |
| | 3555 | VerticesBuffer++; |
| | 3556 | |
| | 3557 | VerticesBuffer->U = decalDescPtr->EndU + decalPtr->UOffset; |
| | 3558 | VerticesBuffer->V = decalDescPtr->EndV; |
| | 3559 | VerticesBuffer++; |
| | 3560 | |
| | 3561 | VerticesBuffer->U = decalDescPtr->StartU + decalPtr->UOffset; |
| | 3562 | VerticesBuffer->V = decalDescPtr->EndV; |
| | 3563 | } |
| | 3564 | |
| | 3565 | #if MIRRORING_ON |
| | 3566 | static void RenderMirroredDecal(DECAL *decalPtr) |
| | 3567 | { |
| | 3568 | RENDERVERTEX *VerticesBuffer = VerticesUnClipped; |
| | 3569 | VECTORCH translatedPosition; |
| | 3570 | |
| | 3571 | /* translate decal into view space */ |
| | 3572 | |
| | 3573 | translatedPosition = decalPtr->Vertices[0]; |
| | 3574 | translatedPosition.vx = MirroringAxis - translatedPosition.vx; |
| | 3575 | TranslatePointIntoViewspace(&translatedPosition); |
| | 3576 | VerticesBuffer->X = translatedPosition.vx; |
| | 3577 | VerticesBuffer->Y = translatedPosition.vy; |
| | 3578 | VerticesBuffer->Z = translatedPosition.vz; |
| | 3579 | VerticesBuffer++; |
| | 3580 | |
| | 3581 | translatedPosition = decalPtr->Vertices[1]; |
| | 3582 | translatedPosition.vx = MirroringAxis - translatedPosition.vx; |
| | 3583 | TranslatePointIntoViewspace(&translatedPosition); |
| | 3584 | VerticesBuffer->X = translatedPosition.vx; |
| | 3585 | VerticesBuffer->Y = translatedPosition.vy; |
| | 3586 | VerticesBuffer->Z = translatedPosition.vz; |
| | 3587 | VerticesBuffer++; |
| | 3588 | |
| | 3589 | translatedPosition = decalPtr->Vertices[2]; |
| | 3590 | translatedPosition.vx = MirroringAxis - translatedPosition.vx; |
| | 3591 | TranslatePointIntoViewspace(&translatedPosition); |
| | 3592 | VerticesBuffer->X = translatedPosition.vx; |
| | 3593 | VerticesBuffer->Y = translatedPosition.vy; |
| | 3594 | VerticesBuffer->Z = translatedPosition.vz; |
| | 3595 | VerticesBuffer++; |
| | 3596 | |
| | 3597 | translatedPosition = decalPtr->Vertices[3]; |
| | 3598 | translatedPosition.vx = MirroringAxis - translatedPosition.vx; |
| | 3599 | TranslatePointIntoViewspace(&translatedPosition); |
| | 3600 | VerticesBuffer->X = translatedPosition.vx; |
| | 3601 | VerticesBuffer->Y = translatedPosition.vy; |
| | 3602 | VerticesBuffer->Z = translatedPosition.vz; |
| | 3603 | |
| | 3604 | DecalPolygon_Construct(decalPtr); |
| | 3605 | |
| | 3606 | if(PolyWithinFrustrum(4)) |
| | 3607 | Decal_Output(decalPtr, draw_vertices); |
| | 3608 | } |
| | 3609 | #endif |
| | 3610 | |
| | 3611 | void RenderDecal(const DECAL *decalPtr) |
| | 3612 | { |
| | 3613 | RENDERVERTEX *VerticesBuffer = VerticesUnClipped; |
| | 3614 | VECTORCH translatedPosition; |
| | 3615 | |
| | 3616 | translatedPosition = decalPtr->Vertices[0]; |
| | 3617 | TranslatePointIntoViewspace(&translatedPosition); |
| | 3618 | VerticesBuffer->X = translatedPosition.vx; |
| | 3619 | VerticesBuffer->Y = translatedPosition.vy; |
| | 3620 | VerticesBuffer->Z = translatedPosition.vz; |
| | 3621 | VerticesBuffer++; |
| | 3622 | |
| | 3623 | translatedPosition = decalPtr->Vertices[1]; |
| | 3624 | TranslatePointIntoViewspace(&translatedPosition); |
| | 3625 | VerticesBuffer->X = translatedPosition.vx; |
| | 3626 | VerticesBuffer->Y = translatedPosition.vy; |
| | 3627 | VerticesBuffer->Z = translatedPosition.vz; |
| | 3628 | VerticesBuffer++; |
| | 3629 | |
| | 3630 | translatedPosition = decalPtr->Vertices[2]; |
| | 3631 | TranslatePointIntoViewspace(&translatedPosition); |
| | 3632 | VerticesBuffer->X = translatedPosition.vx; |
| | 3633 | VerticesBuffer->Y = translatedPosition.vy; |
| | 3634 | VerticesBuffer->Z = translatedPosition.vz; |
| | 3635 | VerticesBuffer++; |
| | 3636 | |
| | 3637 | translatedPosition = decalPtr->Vertices[3]; |
| | 3638 | TranslatePointIntoViewspace(&translatedPosition); |
| | 3639 | VerticesBuffer->X = translatedPosition.vx; |
| | 3640 | VerticesBuffer->Y = translatedPosition.vy; |
| | 3641 | VerticesBuffer->Z = translatedPosition.vz; |
| | 3642 | |
| | 3643 | DecalPolygon_Construct(decalPtr); |
| | 3644 | |
| | 3645 | if(PolyWithinFrustrum(4)) |
| | 3646 | Decal_Output(decalPtr, draw_vertices); |
| | 3647 | |
| | 3648 | #if MIRRORING_ON |
| | 3649 | if (MirroringActive) |
| | 3650 | RenderMirroredDecal(decalPtr); |
| | 3651 | #endif |
| | 3652 | } |
| | 3653 | |
| | 3654 | void RenderBoundingbox(VECTORCH objectVertices[4], DISPLAYBLOCK *objectPtr) |
| | 3655 | { |
| | 3656 | RENDERVERTEX *VerticesBuffer = VerticesUnClipped; |
| | 3657 | { |
| | 3658 | VECTORCH *translatedPosition = objectVertices; |
| | 3659 | |
| | 3660 | TranslatePointIntoViewspace(translatedPosition); |
| | 3661 | VerticesBuffer->X = translatedPosition->vx; |
| | 3662 | VerticesBuffer->Y = translatedPosition->vy; |
| | 3663 | VerticesBuffer->Z = translatedPosition->vz; |
| | 3664 | VerticesBuffer->R = 255; |
| | 3665 | VerticesBuffer->G = 0; |
| | 3666 | VerticesBuffer->B = 0; |
| | 3667 | VerticesBuffer->A = 255; |
| | 3668 | VerticesBuffer++; |
| | 3669 | translatedPosition++; |
| | 3670 | |
| | 3671 | TranslatePointIntoViewspace(translatedPosition); |
| | 3672 | VerticesBuffer->X = translatedPosition->vx; |
| | 3673 | VerticesBuffer->Y = translatedPosition->vy; |
| | 3674 | VerticesBuffer->Z = translatedPosition->vz; |
| | 3675 | VerticesBuffer->R = 255; |
| | 3676 | VerticesBuffer->G = 0; |
| | 3677 | VerticesBuffer->B = 0; |
| | 3678 | VerticesBuffer->A = 255; |
| | 3679 | VerticesBuffer++; |
| | 3680 | translatedPosition++; |
| | 3681 | |
| | 3682 | TranslatePointIntoViewspace(translatedPosition); |
| | 3683 | VerticesBuffer->X = translatedPosition->vx; |
| | 3684 | VerticesBuffer->Y = translatedPosition->vy; |
| | 3685 | VerticesBuffer->Z = translatedPosition->vz; |
| | 3686 | VerticesBuffer->R = 255; |
| | 3687 | VerticesBuffer->G = 0; |
| | 3688 | VerticesBuffer->B = 0; |
| | 3689 | VerticesBuffer->A = 255; |
| | 3690 | VerticesBuffer++; |
| | 3691 | translatedPosition++; |
| | 3692 | |
| | 3693 | TranslatePointIntoViewspace(translatedPosition); |
| | 3694 | VerticesBuffer->X = translatedPosition->vx; |
| | 3695 | VerticesBuffer->Y = translatedPosition->vy; |
| | 3696 | VerticesBuffer->Z = translatedPosition->vz; |
| | 3697 | VerticesBuffer->R = 255; |
| | 3698 | VerticesBuffer->G = 0; |
| | 3699 | VerticesBuffer->B = 0; |
| | 3700 | VerticesBuffer->A = 255; |
| | 3701 | } |
| | 3702 | |
| | 3703 | if(PolyWithinFrustrum(4)) |
| | 3704 | Polygon(draw_vertices, TRANSLUCENCY_OFF); |
| | 3705 | } |
| | 3706 | |
| | 3707 | void RenderFlechetteParticle(PARTICLE *particlePtr) |
| | 3708 | { |
| | 3709 | RENDERVERTEX *VerticesBuffer = VerticesUnClipped; |
| | 3710 | VECTORCH vertices[5]; |
| | 3711 | MATRIXCH mat; |
| | 3712 | int i; |
| | 3713 | |
| | 3714 | MakeMatrixFromDirection(&particlePtr->Velocity, &mat); |
| | 3715 | |
| | 3716 | mat.mat11 >>= 12; |
| | 3717 | mat.mat12 >>= 12; |
| | 3718 | mat.mat13 >>= 12; |
| | 3719 | mat.mat21 >>= 12; |
| | 3720 | mat.mat22 >>= 12; |
| | 3721 | mat.mat23 >>= 12; |
| | 3722 | mat.mat31 >>= 9; |
| | 3723 | mat.mat32 >>= 9; |
| | 3724 | mat.mat33 >>= 9; |
| | 3725 | |
| | 3726 | vertices[0].vx = particlePtr->Position.vx - mat.mat31 + mat.mat11; |
| | 3727 | vertices[0].vy = particlePtr->Position.vy - mat.mat32 + mat.mat12; |
| | 3728 | vertices[0].vz = particlePtr->Position.vz - mat.mat33 + mat.mat13; |
| | 3729 | |
| | 3730 | vertices[1].vx = particlePtr->Position.vx - mat.mat31 - mat.mat11; |
| | 3731 | vertices[1].vy = particlePtr->Position.vy - mat.mat32 - mat.mat12; |
| | 3732 | vertices[1].vz = particlePtr->Position.vz - mat.mat33 - mat.mat13; |
| | 3733 | |
| | 3734 | vertices[2] = particlePtr->Position; |
| | 3735 | |
| | 3736 | vertices[3].vx = particlePtr->Position.vx - mat.mat31 + mat.mat21; |
| | 3737 | vertices[3].vy = particlePtr->Position.vy - mat.mat32 + mat.mat22; |
| | 3738 | vertices[3].vz = particlePtr->Position.vz - mat.mat33 + mat.mat23; |
| | 3739 | |
| | 3740 | vertices[4].vx = particlePtr->Position.vx - mat.mat31 - mat.mat21; |
| | 3741 | vertices[4].vy = particlePtr->Position.vy - mat.mat32 - mat.mat22; |
| | 3742 | vertices[4].vz = particlePtr->Position.vz - mat.mat33 - mat.mat23; |
| | 3743 | |
| | 3744 | TranslatePointIntoViewspace(vertices); |
| | 3745 | TranslatePointIntoViewspace(vertices + 1); |
| | 3746 | TranslatePointIntoViewspace(vertices + 2); |
| | 3747 | TranslatePointIntoViewspace(vertices + 3); |
| | 3748 | TranslatePointIntoViewspace(vertices + 4); |
| | 3749 | |
| | 3750 | for (i=0; i < 3; i++) |
| | 3751 | { |
| | 3752 | VerticesBuffer[i].X = vertices[i].vx; |
| | 3753 | VerticesBuffer[i].Y = vertices[i].vy; |
| | 3754 | VerticesBuffer[i].Z = vertices[i].vz; |
| | 3755 | |
| | 3756 | VerticesBuffer[i].A = (particlePtr->Colour >> 24) & 255; |
| | 3757 | VerticesBuffer[i].R = (particlePtr->Colour >> 16) & 255; |
| | 3758 | VerticesBuffer[i].G = (particlePtr->Colour >> 8) & 255; |
| | 3759 | VerticesBuffer[i].B = (particlePtr->Colour) & 255; |
| | 3760 | } |
| | 3761 | |
| | 3762 | if(PolyWithinFrustrum(3)) |
| | 3763 | Polygon(draw_vertices, TRANSLUCENCY_NORMAL); |
| | 3764 | |
| | 3765 | for (i=0; i < 3; i++) |
| | 3766 | { |
| | 3767 | VerticesBuffer[i].X = vertices[i+2].vx; |
| | 3768 | VerticesBuffer[i].Y = vertices[i+2].vy; |
| | 3769 | VerticesBuffer[i].Z = vertices[i+2].vz; |
| | 3770 | |
| | 3771 | VerticesBuffer[i].A = (particlePtr->Colour >> 24) & 255; |
| | 3772 | VerticesBuffer[i].R = (particlePtr->Colour >> 16) & 255; |
| | 3773 | VerticesBuffer[i].G = (particlePtr->Colour >> 8) & 255; |
| | 3774 | VerticesBuffer[i].B = (particlePtr->Colour) & 255; |
| | 3775 | } |
| | 3776 | |
| | 3777 | if(PolyWithinFrustrum(3)) |
| | 3778 | Polygon(draw_vertices, TRANSLUCENCY_NORMAL); |
| | 3779 | } |
| | 3780 | |
| | 3781 | void OutputTranslucentPolyList() |
| | 3782 | { |
| | 3783 | int i; |
| | 3784 | for (i = 0; i < CurrentNumberOfTranslucentPolygons; i++) |
| | 3785 | { |
| | 3786 | if(TranslucentPolygons[i].flags & iflag_glowing) |
| | 3787 | { |
| | 3788 | RenderPolygon.TranslucencyMode = TRANSLUCENCY_GLOWING; |
| | 3789 | TranslucentPolygons[i].polygon.Vertices->A = 250; |
| | 3790 | } |
| | 3791 | else |
| | 3792 | { |
| | 3793 | RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL; |
| | 3794 | } |
| | 3795 | |
| | 3796 | RenderPolygon.NumberOfVertices = TranslucentPolygons[i].polygon.NumberOfVertices; |
| | 3797 | TexturedPolygon(TranslucentPolygons[i].texture_number, TranslucentPolygons[i].polygon.Vertices, RenderPolygon.TranslucencyMode); |
| | 3798 | } |
| | 3799 | } |
| | 3800 | |
| | 3801 | void RenderMirrorSurface() |
| | 3802 | { |
| | 3803 | RENDERVERTEX *VerticesBuffer = VerticesUnClipped; |
| | 3804 | int i; |
| | 3805 | |
| | 3806 | VECTORCH translatedPts[4] = |
| | 3807 | { |
| | 3808 | {-5596,-932,-1872}, |
| | 3809 | {-5596,-932,-702}, |
| | 3810 | {-5596,1212,-702}, |
| | 3811 | {-5596,1212,-1872}, |
| | 3812 | }; |
| | 3813 | |
| | 3814 | int mirrorUV[]= { 0,0, 127<<16,0, 127<<16,127<<16, 0,127<<16}; |
| | 3815 | |
| | 3816 | for (i=0; i < 4; i++) |
| | 3817 | { |
| | 3818 | VerticesBuffer[i].A = 128; |
| | 3819 | |
| | 3820 | TranslatePointIntoViewspace(&translatedPts[i]); |
| | 3821 | VerticesBuffer[i].X = translatedPts[i].vx; |
| | 3822 | VerticesBuffer[i].Y = translatedPts[i].vy; |
| | 3823 | VerticesBuffer[i].Z = translatedPts[i].vz; |
| | 3824 | VerticesBuffer[i].U = mirrorUV[i*2]; |
| | 3825 | VerticesBuffer[i].V = mirrorUV[i*2+1]; |
| | 3826 | |
| | 3827 | VerticesBuffer[i].R = 255; |
| | 3828 | VerticesBuffer[i].G = 255; |
| | 3829 | VerticesBuffer[i].B = 255; |
| | 3830 | VerticesBuffer[i].SpecularR = 0; |
| | 3831 | VerticesBuffer[i].SpecularG = 0; |
| | 3832 | VerticesBuffer[i].SpecularB = 0; |
| | 3833 | } |
| | 3834 | |
| | 3835 | if(ClipPolygon(4)) |
| | 3836 | TexturedPolygon(CloudyImageNumber, draw_vertices, TRANSLUCENCY_COLOUR); |
| | 3837 | } |
| | 3838 | |
| | 3839 | void RenderMirrorSurface2() |
| | 3840 | { |
| | 3841 | int i; |
| | 3842 | RENDERVERTEX *VerticesBuffer = VerticesUnClipped; |
| | 3843 | VECTORCH translatedPts[4] = |
| | 3844 | { |
| | 3845 | {-5596,-592,562}, |
| | 3846 | {-5596,-592,1344}, |
| | 3847 | {-5596,140,1344}, |
| | 3848 | {-5596,140,562}, |
| | 3849 | |
| | 3850 | }; |
| | 3851 | |
| | 3852 | int mirrorUV[]= { 0,0, 127<<16,0, 127<<16,127<<16, 0,127<<16}; |
| | 3853 | |
| | 3854 | for (i=0; i < 4; i++) |
| | 3855 | { |
| | 3856 | VerticesBuffer[i].A = 128; |
| | 3857 | |
| | 3858 | TranslatePointIntoViewspace(&translatedPts[i]); |
| | 3859 | VerticesBuffer[i].X = translatedPts[i].vx; |
| | 3860 | VerticesBuffer[i].Y = translatedPts[i].vy; |
| | 3861 | VerticesBuffer[i].Z = translatedPts[i].vz; |
| | 3862 | VerticesBuffer[i].U = mirrorUV[i*2]; |
| | 3863 | VerticesBuffer[i].V = mirrorUV[i*2+1]; |
| | 3864 | |
| | 3865 | VerticesBuffer[i].R = 255; |
| | 3866 | VerticesBuffer[i].G = 255; |
| | 3867 | VerticesBuffer[i].B = 255; |
| | 3868 | VerticesBuffer[i].SpecularR = 0; |
| | 3869 | VerticesBuffer[i].SpecularG = 0; |
| | 3870 | VerticesBuffer[i].SpecularB = 0; |
| | 3871 | } |
| | 3872 | |
| | 3873 | if(ClipPolygon(4)) |
| | 3874 | TexturedPolygon(CloudyImageNumber, draw_vertices, TRANSLUCENCY_COLOUR); |
| | 3875 | } |
| | 3876 | |
| | 3877 | #define OCTAVES 3 |
| | 3878 | int u[OCTAVES]; |
| | 3879 | int v[OCTAVES]; |
| | 3880 | int du[OCTAVES]; |
| | 3881 | int dv[OCTAVES]; |
| | 3882 | |
| | 3883 | int SkyColour_R = 200; |
| | 3884 | int SkyColour_G = 200; |
| | 3885 | int SkyColour_B = 200; |
| | 3886 | |
| | 3887 | void init_sky() |
| | 3888 | { |
| | 3889 | int i = 0; |
| | 3890 | for(; i < OCTAVES; i++) |
| | 3891 | { |
| | 3892 | u[i] = (FastRandom() & 65535)*128; |
| | 3893 | v[i] = (FastRandom() & 65535)*128; |
| | 3894 | du[i] = ( ((FastRandom() & 65535)-32768) * (i+1) )*8; |
| | 3895 | dv[i] = ( ((FastRandom() & 65535)-32768) * (i+1) )*8; |
| | 3896 | } |
| | 3897 | } |
| | 3898 | |
| | 3899 | void RenderSky() |
| | 3900 | { |
| | 3901 | RENDERVERTEX *VerticesBuffer = VerticesUnClipped; |
| | 3902 | |
| | 3903 | int x = -10; |
| | 3904 | |
| | 3905 | { |
| | 3906 | int i=0; |
| | 3907 | for (; i < OCTAVES; i++) |
| | 3908 | { |
| | 3909 | u[i] += MUL_FIXED(du[i], NormalFrameTime); |
| | 3910 | v[i] += MUL_FIXED(dv[i], NormalFrameTime); |
| | 3911 | } |
| | 3912 | } |
| | 3913 | |
| | 3914 | for(; x <= 10; x++) |
| | 3915 | { |
| | 3916 | int z = -10; |
| | 3917 | for(; z <= 10; z++) |
| | 3918 | { |
| | 3919 | int t = 255; |
| | 3920 | int size = 65536*128; |
| | 3921 | int o = 0; |
| | 3922 | |
| | 3923 | for (o=0; o < OCTAVES; o++) |
| | 3924 | { |
| | 3925 | { |
| | 3926 | VECTORCH translatedPts[4] = |
| | 3927 | { |
| | 3928 | {-1024,-1000,-1024}, |
| | 3929 | {-1024,-1000, 1024}, |
| | 3930 | { 1024,-1000, 1024}, |
| | 3931 | { 1024,-1000,-1024}, |
| | 3932 | |
| | 3933 | }; |
| | 3934 | |
| | 3935 | int i = 0; |
| | 3936 | for (; i < 4; i++) |
| | 3937 | { |
| | 3938 | VerticesBuffer[i].A = t; |
| | 3939 | translatedPts[i].vx += 2048*x;//+(Global_VDB.VDB_World.vx*7)/8; |
| | 3940 | translatedPts[i].vz += 2048*z;//+(Global_VDB.VDB_World.vz*7)/8; |
| | 3941 | |
| | 3942 | // RotateVector(&translatedPts[i],&(Global_VDB.VDB_Mat)); |
| | 3943 | |
| | 3944 | // translatedPts[i].vy = MUL_FIXED(translatedPts[i].vy,87381); |
| | 3945 | translatedPts[i].vx += Global_VDB.VDB_World.vx; |
| | 3946 | translatedPts[i].vy += Global_VDB.VDB_World.vy; |
| | 3947 | translatedPts[i].vz += Global_VDB.VDB_World.vz; |
| | 3948 | TranslatePointIntoViewspace(&translatedPts[i]); |
| | 3949 | |
| | 3950 | VerticesBuffer[i].X = translatedPts[i].vx; |
| | 3951 | VerticesBuffer[i].Y = translatedPts[i].vy; |
| | 3952 | VerticesBuffer[i].Z = translatedPts[i].vz; |
| | 3953 | |
| | 3954 | switch (PlayerStatus.VisionMode) |
| | 3955 | { |
| | 3956 | default: |
| | 3957 | case VISION_MODE_NORMAL: |
| | 3958 | { |
| | 3959 | VerticesBuffer[i].R = SkyColour_R; |
| | 3960 | VerticesBuffer[i].G = SkyColour_G; |
| | 3961 | VerticesBuffer[i].B = SkyColour_B; |
| | 3962 | break; |
| | 3963 | } |
| | 3964 | case VISION_MODE_IMAGEINTENSIFIER: |
| | 3965 | { |
| | 3966 | VerticesBuffer[i].R = 0; |
| | 3967 | VerticesBuffer[i].G = 255; |
| | 3968 | VerticesBuffer[i].B = 0; |
| | 3969 | break; |
| | 3970 | } |
| | 3971 | case VISION_MODE_PRED_THERMAL: |
| | 3972 | case VISION_MODE_PRED_SEEALIENS: |
| | 3973 | case VISION_MODE_PRED_SEEPREDTECH: |
| | 3974 | { |
| | 3975 | VerticesBuffer[i].R = 0; |
| | 3976 | VerticesBuffer[i].G = 0; |
| | 3977 | VerticesBuffer[i].B = 255; |
| | 3978 | break; |
| | 3979 | } |
| | 3980 | } |
| | 3981 | } |
| | 3982 | |
| | 3983 | VerticesBuffer[0].U = (u[o]+size*x); |
| | 3984 | VerticesBuffer[0].V = (v[o]+size*z); |
| | 3985 | VerticesBuffer[1].U = (u[o]+size*x); |
| | 3986 | VerticesBuffer[1].V = (v[o]+size*(z+1)); |
| | 3987 | VerticesBuffer[2].U = (u[o]+size*(x+1)); |
| | 3988 | VerticesBuffer[2].V = (v[o]+size*(z+1)); |
| | 3989 | VerticesBuffer[3].U = (u[o]+size*(x+1)); |
| | 3990 | VerticesBuffer[3].V = (v[o]+size*z); |
| | 3991 | } |
| | 3992 | |
| | 3993 | if(ClipPolygon(4)) |
| | 3994 | SkyPolygon_Output(draw_vertices, TRANSLUCENCY_GLOWING); |
| | 3995 | |
| | 3996 | t /= 2; |
| | 3997 | size *= 2; |
| | 3998 | } |
| | 3999 | } |
| | 4000 | } |
| | 4001 | } |
| | 4002 | |
| | 4003 | void DrawWaterFallPoly(VECTORCH *v) |
| | 4004 | { |
| | 4005 | RENDERVERTEX *VerticesBuffer = VerticesUnClipped; |
| | 4006 | static int wv = 0; |
| | 4007 | unsigned int a = 0; |
| | 4008 | |
| | 4009 | for (; a < 4; a++) |
| | 4010 | { |
| | 4011 | VerticesBuffer[a].A = 128; |
| | 4012 | VerticesBuffer[a].U = (v[a].vz)<<11; |
| | 4013 | VerticesBuffer[a].V = (v[a].vy<<10)-wv; |
| | 4014 | |
| | 4015 | TranslatePointIntoViewspace(&v[a]); |
| | 4016 | VerticesBuffer[a].X = v[a].vx; |
| | 4017 | VerticesBuffer[a].Y = v[a].vy; |
| | 4018 | VerticesBuffer[a].Z = v[a].vz; |
| | 4019 | VerticesBuffer[a].R = 200; |
| | 4020 | VerticesBuffer[a].G = 200; |
| | 4021 | VerticesBuffer[a].B = 255; |
| | 4022 | VerticesBuffer[a].SpecularR = 0; |
| | 4023 | VerticesBuffer[a].SpecularG = 0; |
| | 4024 | VerticesBuffer[a].SpecularB = 0; |
| | 4025 | } |
| | 4026 | |
| | 4027 | wv += NormalFrameTime * 2; |
| | 4028 | |
| | 4029 | if(ClipPolygon(4)) |
| | 4030 | TexturedPolygon(CloudyImageNumber, draw_vertices, TRANSLUCENCY_NORMAL); |
| | 4031 | } |
| | 4032 | |
| | 4033 | void RenderWaterFall(int xOrigin, int yOrigin, int zOrigin) |
| | 4034 | { |
| | 4035 | int i,z; |
| | 4036 | VECTORCH v[4]; |
| | 4037 | |
| | 4038 | { |
| | 4039 | int waterfallX[9]; |
| | 4040 | int waterfallY[9]; |
| | 4041 | int waterfallZ[9]; |
| | 4042 | int waterfallZScale[9]; |
| | 4043 | |
| | 4044 | for (i=0; i < 9; i++) |
| | 4045 | { |
| | 4046 | int u = (i*65536)/8; |
| | 4047 | |
| | 4048 | int b = MUL_FIXED(2*u,(65536-u)); |
| | 4049 | int c = MUL_FIXED(u,u); |
| | 4050 | int y3 = (4742-yOrigin); |
| | 4051 | int x3 = 2000; |
| | 4052 | int y2 = 2000; |
| | 4053 | int x2 = 1500; |
| | 4054 | |
| | 4055 | waterfallX[i] = MUL_FIXED(b,x2)+MUL_FIXED(c,x3); |
| | 4056 | waterfallY[i] = yOrigin+MUL_FIXED(b,y2)+MUL_FIXED(c,y3); |
| | 4057 | waterfallZ[i] = zOrigin+MUL_FIXED((66572-zOrigin),u); |
| | 4058 | waterfallZScale[i] = ONE_FIXED+b/2-c; |
| | 4059 | |
| | 4060 | if (i != 8) |
| | 4061 | { |
| | 4062 | waterfallZScale[i]+=(FastRandom()&8191); |
| | 4063 | waterfallY[i]-=(FastRandom()&127); |
| | 4064 | } |
| | 4065 | } |
| | 4066 | |
| | 4067 | for (z=0; z<8; z++) |
| | 4068 | for (i=0; i<8; i++) |
| | 4069 | { |
| | 4070 | v[0].vx = xOrigin+MUL_FIXED(waterfallX[i],waterfallZScale[z]); |
| | 4071 | v[1].vx = xOrigin+MUL_FIXED(waterfallX[i],waterfallZScale[z+1]); |
| | 4072 | v[2].vx = xOrigin+MUL_FIXED(waterfallX[i+1],waterfallZScale[z+1]); |
| | 4073 | v[3].vx = xOrigin+MUL_FIXED(waterfallX[i+1],waterfallZScale[z]); |
| | 4074 | v[0].vy = waterfallY[i]; |
| | 4075 | v[1].vy = waterfallY[i]; |
| | 4076 | v[2].vy = waterfallY[i+1]; |
| | 4077 | v[3].vy = waterfallY[i+1]; |
| | 4078 | |
| | 4079 | v[0].vz = waterfallZ[z]; |
| | 4080 | v[1].vz = waterfallZ[z+1]; |
| | 4081 | v[2].vz = v[1].vz; |
| | 4082 | v[3].vz = v[0].vz; |
| | 4083 | |
| | 4084 | DrawWaterFallPoly(v); |
| | 4085 | } |
| | 4086 | |
| | 4087 | for (z=0; z<3; z++) |
| | 4088 | { |
| | 4089 | v[0].vx = xOrigin+MUL_FIXED(waterfallX[8],waterfallZScale[z+1]); |
| | 4090 | v[1].vx = xOrigin+MUL_FIXED(waterfallX[8],waterfallZScale[z]); |
| | 4091 | v[2].vx = 179450; |
| | 4092 | v[3].vx = 179450; |
| | 4093 | |
| | 4094 | v[0].vy = 4742; |
| | 4095 | v[1].vy = 4742; |
| | 4096 | v[2].vy = 4742; |
| | 4097 | v[3].vy = 4742; |
| | 4098 | |
| | 4099 | v[0].vz = waterfallZ[z]; |
| | 4100 | v[1].vz = waterfallZ[z+1]; |
| | 4101 | v[2].vz = v[1].vz; |
| | 4102 | v[3].vz = v[0].vz; |
| | 4103 | |
| | 4104 | DrawWaterFallPoly(v); |
| | 4105 | } |
| | 4106 | |
| | 4107 | for (z=0; z<8; z++) |
| | 4108 | for (i=0; i<16; i++) |
| | 4109 | { |
| | 4110 | int xOffset,xOffset2; |
| | 4111 | |
| | 4112 | if (z < 3) |
| | 4113 | xOffset = 179450; |
| | 4114 | else |
| | 4115 | xOffset = xOrigin+MUL_FIXED(waterfallX[8],waterfallZScale[z]); |
| | 4116 | |
| | 4117 | if (z < 2) |
| | 4118 | xOffset2 = 179450; |
| | 4119 | else |
| | 4120 | xOffset2 = xOrigin+MUL_FIXED(waterfallX[8],waterfallZScale[z+1]); |
| | 4121 | |
| | 4122 | v[0].vx = xOffset; |
| | 4123 | v[1].vx = xOffset2; |
| | 4124 | v[2].vx = xOffset2; |
| | 4125 | v[3].vx = xOffset; |
| | 4126 | |
| | 4127 | v[0].vy = 4742+i*4096; |
| | 4128 | v[1].vy = 4742+i*4096; |
| | 4129 | v[2].vy = 4742+(i+1)*4096; |
| | 4130 | v[3].vy = 4742+(i+1)*4096; |
| | 4131 | |
| | 4132 | v[0].vz = waterfallZ[z]; |
| | 4133 | v[1].vz = waterfallZ[z+1]; |
| | 4134 | v[2].vz = v[1].vz; |
| | 4135 | v[3].vz = v[0].vz; |
| | 4136 | |
| | 4137 | DrawWaterFallPoly(v); |
| | 4138 | } |
| | 4139 | } |
| | 4140 | } |
| | 4141 | |
| | 4142 | void RenderPredatorTargetingSegment(int theta, int scale, int drawInRed) |
| | 4143 | { |
| | 4144 | RENDERVERTEX *VerticesBuffer = VerticesUnClipped; |
| | 4145 | |
| | 4146 | VECTOR2D offset[4]; |
| | 4147 | int centreX,centreY; |
| | 4148 | int i; |
| | 4149 | int z = ONE_FIXED - scale; |
| | 4150 | z = MUL_FIXED(MUL_FIXED(z, z), 2048); |
| | 4151 | |
| | 4152 | { |
| | 4153 | extern int SmartTargetSightX, SmartTargetSightY; |
| | 4154 | centreY = MUL_FIXED( (SmartTargetSightY-(ScreenDescriptorBlock.SDB_Height<<15)) / Global_VDB.VDB_ProjY,z); |
| | 4155 | |
| | 4156 | centreX = (CHEATMODE_MIRROR == UserProfile.active_bonus) ? |
| | 4157 | MUL_FIXED((-(SmartTargetSightX-(ScreenDescriptorBlock.SDB_Width<<15))) / Global_VDB.VDB_ProjX,z) : |
| | 4158 | MUL_FIXED(( SmartTargetSightX-(ScreenDescriptorBlock.SDB_Width<<15)) / Global_VDB.VDB_ProjX,z); |
| | 4159 | } |
| | 4160 | |
| | 4161 | z = (float)z * CameraZoomScale; |
| | 4162 | |
| | 4163 | { |
| | 4164 | int a = 160; |
| | 4165 | int b = 40; |
| | 4166 | |
| | 4167 | /* tan(30) = 1/sqrt(3), & 65536/(sqrt(3)) = 37837 */ |
| | 4168 | |
| | 4169 | int y = MUL_FIXED(37837,a+20); |
| | 4170 | |
| | 4171 | offset[0].vx = -a+MUL_FIXED(113512,b); |
| | 4172 | offset[0].vy = y-b; |
| | 4173 | |
| | 4174 | offset[1].vx = -offset[0].vx; |
| | 4175 | offset[1].vy = y-b; |
| | 4176 | |
| | 4177 | offset[2].vx = a; |
| | 4178 | offset[2].vy = y; |
| | 4179 | |
| | 4180 | offset[3].vx = -a; |
| | 4181 | offset[3].vy = y; |
| | 4182 | |
| | 4183 | if (theta) |
| | 4184 | { |
| | 4185 | RotateVertex(&offset[0],theta); |
| | 4186 | RotateVertex(&offset[1],theta); |
| | 4187 | RotateVertex(&offset[2],theta); |
| | 4188 | RotateVertex(&offset[3],theta); |
| | 4189 | } |
| | 4190 | |
| | 4191 | if (CHEATMODE_MIRROR == UserProfile.active_bonus) |
| | 4192 | { |
| | 4193 | offset[0].vx = -offset[0].vx; |
| | 4194 | offset[1].vx = -offset[1].vx; |
| | 4195 | offset[2].vx = -offset[2].vx; |
| | 4196 | offset[3].vx = -offset[3].vx; |
| | 4197 | } |
| | 4198 | |
| | 4199 | VerticesBuffer[0].X = offset[0].vx+centreX; |
| | 4200 | VerticesBuffer[0].Y = MUL_FIXED(offset[0].vy,87381)+centreY; |
| | 4201 | |
| | 4202 | VerticesBuffer[1].X = offset[1].vx+centreX; |
| | 4203 | VerticesBuffer[1].Y = MUL_FIXED(offset[1].vy,87381)+centreY; |
| | 4204 | |
| | 4205 | VerticesBuffer[2].X = offset[2].vx+centreX; |
| | 4206 | VerticesBuffer[2].Y = MUL_FIXED(offset[2].vy,87381)+centreY; |
| | 4207 | |
| | 4208 | VerticesBuffer[3].X = offset[3].vx+centreX; |
| | 4209 | VerticesBuffer[3].Y = MUL_FIXED(offset[3].vy,87381)+centreY; |
| | 4210 | } |
| | 4211 | |
| | 4212 | for (i=0; i < 4; i++) |
| | 4213 | { |
| | 4214 | VerticesBuffer[i].A = 128; |
| | 4215 | VerticesBuffer[i].Z = z; |
| | 4216 | VerticesBuffer[i].R = 255; |
| | 4217 | VerticesBuffer[i].G = VerticesBuffer[i].B = drawInRed ? 0 : 255; |
| | 4218 | } |
| | 4219 | |
| | 4220 | if(!ClipPolygon(4)) |
| | 4221 | return; |
| | 4222 | |
| | 4223 | Polygon(draw_vertices, TRANSLUCENCY_GLOWING); |
| | 4224 | |
| | 4225 | if (drawInRed) |
| | 4226 | { |
| | 4227 | VerticesBuffer[0].X = MUL_FIXED(offset[3].vx,scale*8)+centreX; |
| | 4228 | VerticesBuffer[0].Y = MUL_FIXED(MUL_FIXED(offset[3].vy,scale*8),87381)+centreY; |
| | 4229 | |
| | 4230 | VerticesBuffer[1].X = MUL_FIXED(offset[2].vx,scale*8)+centreX; |
| | 4231 | VerticesBuffer[1].Y = MUL_FIXED(MUL_FIXED(offset[2].vy,scale*8),87381)+centreY; |
| | 4232 | |
| | 4233 | VerticesBuffer[2].X = offset[2].vx+centreX; |
| | 4234 | VerticesBuffer[2].Y = MUL_FIXED(offset[2].vy,87381)+centreY; |
| | 4235 | |
| | 4236 | VerticesBuffer[3].X = offset[3].vx+centreX; |
| | 4237 | VerticesBuffer[3].Y = MUL_FIXED(offset[3].vy,87381)+centreY; |
| | 4238 | |
| | 4239 | for (i=0; i < 2; i++) |
| | 4240 | { |
| | 4241 | VerticesBuffer[i].A = 0; |
| | 4242 | VerticesBuffer[i].Z = z; |
| | 4243 | VerticesBuffer[i].R = 255; |
| | 4244 | VerticesBuffer[i].G = 0; |
| | 4245 | VerticesBuffer[i].B = 0; |
| | 4246 | } |
| | 4247 | |
| | 4248 | for (i=2; i < 4; i++) |
| | 4249 | { |
| | 4250 | VerticesBuffer[i].A = 128; |
| | 4251 | VerticesBuffer[i].Z = z; |
| | 4252 | VerticesBuffer[i].R = 255; |
| | 4253 | VerticesBuffer[i].G = 0; |
| | 4254 | VerticesBuffer[i].B = 0; |
| | 4255 | } |
| | 4256 | |
| | 4257 | if(ClipPolygon(4)) |
| | 4258 | Polygon(draw_vertices, TRANSLUCENCY_GLOWING); |
| | 4259 | } |
| | 4260 | } |
| | 4261 | |
| | 4262 | void RenderPredatorPlasmaCasterCharge(int value, VECTORCH *worldOffsetPtr, MATRIXCH *orientationPtr) |
| | 4263 | { |
| | 4264 | RENDERVERTEX *VerticesBuffer = VerticesUnClipped; |
| | 4265 | |
| | 4266 | VECTORCH translatedPts[4]; |
| | 4267 | int halfWidth = 100; |
| | 4268 | int halfHeight = 4; |
| | 4269 | int i, z = -1; |
| | 4270 | |
| | 4271 | translatedPts[0].vx = -halfWidth; |
| | 4272 | translatedPts[0].vy = z; |
| | 4273 | translatedPts[0].vz = -halfHeight-4; |
| | 4274 | |
| | 4275 | translatedPts[1].vx = -halfWidth+MUL_FIXED(value,2*halfWidth-10); |
| | 4276 | translatedPts[1].vy = z; |
| | 4277 | translatedPts[1].vz = -halfHeight-4; |
| | 4278 | |
| | 4279 | translatedPts[2].vx = -halfWidth+MUL_FIXED(value,2*halfWidth-10); |
| | 4280 | translatedPts[2].vy = z; |
| | 4281 | translatedPts[2].vz = halfHeight-4; |
| | 4282 | |
| | 4283 | translatedPts[3].vx = -halfWidth; |
| | 4284 | translatedPts[3].vy = z; |
| | 4285 | translatedPts[3].vz = halfHeight-4; |
| | 4286 | |
| | 4287 | for (i=0; i < 4; i++) |
| | 4288 | { |
| | 4289 | VerticesBuffer[i].A = 155; |
| | 4290 | |
| | 4291 | RotateVector(&translatedPts[i],orientationPtr); |
| | 4292 | translatedPts[i].vx += worldOffsetPtr->vx; |
| | 4293 | translatedPts[i].vy += worldOffsetPtr->vy; |
| | 4294 | translatedPts[i].vz += worldOffsetPtr->vz; |
| | 4295 | TranslatePointIntoViewspace(&translatedPts[i]); |
| | 4296 | |
| | 4297 | VerticesBuffer[i].X = translatedPts[i].vx; |
| | 4298 | VerticesBuffer[i].Y = translatedPts[i].vy; |
| | 4299 | VerticesBuffer[i].Z = translatedPts[i].vz; |
| | 4300 | |
| | 4301 | VerticesBuffer[i].R = 32; |
| | 4302 | VerticesBuffer[i].G = 0; |
| | 4303 | VerticesBuffer[i].B = 0; |
| | 4304 | } |
| | 4305 | |
| | 4306 | if(PolyWithinFrustrum(4)) |
| | 4307 | Polygon(draw_vertices, TRANSLUCENCY_GLOWING); |
| | 4308 | } |
| | 4309 | |
| | 4310 | void RenderLightFlare(VECTORCH *positionPtr, unsigned int colour) |
| | 4311 | { |
| | 4312 | RENDERVERTEX *VerticesBuffer = VerticesUnClipped; |
| | 4313 | |
| | 4314 | PARTICLE particle; |
| | 4315 | VECTORCH point = *positionPtr; |
| | 4316 | |
| | 4317 | TranslatePointIntoViewspace(&point); |
| | 4318 | |
| | 4319 | if(point.vz < 64) |
| | 4320 | return; |
| | 4321 | |
| | 4322 | particle.ParticleID = PARTICLE_LIGHTFLARE; |
| | 4323 | particle.Colour = colour; |
| | 4324 | //printf("render fn %d %d %d\n", positionPtr->vx, positionPtr->vy, positionPtr->vz); |
| | 4325 | |
| | 4326 | { |
| | 4327 | int centreX = DIV_FIXED(point.vx, point.vz); |
| | 4328 | int centreY = DIV_FIXED(point.vy, point.vz); |
| | 4329 | int sizeX = (ScreenDescriptorBlock.SDB_Width << 13) / Global_VDB.VDB_ProjX; |
| | 4330 | int sizeY = MUL_FIXED(ScreenDescriptorBlock.SDB_Height << 13, 87381) / Global_VDB.VDB_ProjY; |
| | 4331 | int z = ONE_FIXED; |
| | 4332 | |
| | 4333 | VerticesBuffer[0].X = centreX - sizeX; |
| | 4334 | VerticesBuffer[0].Y = centreY - sizeY; |
| | 4335 | VerticesBuffer[0].Z = z; |
| | 4336 | VerticesBuffer[0].U = 192 << 16; |
| | 4337 | VerticesBuffer[0].V = 0; |
| | 4338 | |
| | 4339 | VerticesBuffer[1].X = centreX + sizeX; |
| | 4340 | VerticesBuffer[1].Y = centreY - sizeY; |
| | 4341 | VerticesBuffer[1].Z = z; |
| | 4342 | VerticesBuffer[1].U = 255 << 16; |
| | 4343 | VerticesBuffer[1].V = 0; |
| | 4344 | |
| | 4345 | VerticesBuffer[2].X = centreX + sizeX; |
| | 4346 | VerticesBuffer[2].Y = centreY + sizeY; |
| | 4347 | VerticesBuffer[2].Z = z; |
| | 4348 | VerticesBuffer[2].U = 255 << 16; |
| | 4349 | VerticesBuffer[2].V = 63 << 16; |
| | 4350 | |
| | 4351 | VerticesBuffer[3].X = centreX - sizeX; |
| | 4352 | VerticesBuffer[3].Y = centreY + sizeY; |
| | 4353 | VerticesBuffer[3].Z = z; |
| | 4354 | VerticesBuffer[3].U = 192 << 16; |
| | 4355 | VerticesBuffer[3].V = 63 << 16; |
| | 4356 | } |
| | 4357 | |
| | 4358 | if(PolyWithinFrustrum(4)) |
| | 4359 | Particle_Output(&particle, draw_vertices); |
| | 4360 | } |
| | 4361 | |
| | 4362 | void RenderExplosionSurface(struct VOLUMETRIC_EXPLOSION *explosionPtr) |
| | 4363 | { |
| | 4364 | extern int BurningImageNumber; |
| | 4365 | RENDERVERTEX *VerticesBuffer = VerticesUnClipped; |
| | 4366 | int red,green,blue,f; |
| | 4367 | |
| | 4368 | switch (PlayerStatus.VisionMode) |
| | 4369 | { |
| | 4370 | case VISION_MODE_NORMAL: |
| | 4371 | default: |
| | 4372 | red = green = blue = 255; |
| | 4373 | break; |
| | 4374 | case VISION_MODE_IMAGEINTENSIFIER: |
| | 4375 | red = blue = 0; |
| | 4376 | green = 255; |
| | 4377 | break; |
| | 4378 | case VISION_MODE_PRED_THERMAL: |
| | 4379 | case VISION_MODE_PRED_SEEALIENS: |
| | 4380 | case VISION_MODE_PRED_SEEPREDTECH: |
| | 4381 | red = blue = 255; |
| | 4382 | green = 0; |
| | 4383 | } |
| | 4384 | |
| | 4385 | { |
| | 4386 | VECTORCH *vSphere = SphereRotatedVertex; |
| | 4387 | |
| | 4388 | for (f=0; f < SPHERE_VERTICES; f++) |
| | 4389 | { |
| | 4390 | *vSphere = explosionPtr->Position[f]; |
| | 4391 | TranslatePointIntoViewspace(vSphere); |
| | 4392 | vSphere++; |
| | 4393 | } |
| | 4394 | } |
| | 4395 | for (f=0; f < SPHERE_FACES; f++) |
| | 4396 | { |
| | 4397 | int i; |
| | 4398 | |
| | 4399 | for (i=0; i < 3; i++) |
| | 4400 | { |
| | 4401 | int n = SphereFace[f].v[i]; |
| | 4402 | VECTORCH *vertex = &SphereRotatedVertex[n]; |
| | 4403 | |
| | 4404 | VerticesBuffer[i].X = vertex->vx; |
| | 4405 | VerticesBuffer[i].Y = vertex->vy; |
| | 4406 | VerticesBuffer[i].Z = vertex->vz; |
| | 4407 | |
| | 4408 | /* |
| | 4409 | { |
| | 4410 | int u = -(ONE_FIXED - explosionPtr->LifeTime) * 128 * 2; |
| | 4411 | VerticesBuffer[i].U = SphereAtmosU[n]; |
| | 4412 | VerticesBuffer[i].V = SphereAtmosV[n] + u; |
| | 4413 | } |
| | 4414 | |
| | 4415 | { |
| | 4416 | int d1 = VerticesBuffer[0].U - VerticesBuffer[1].U; |
| | 4417 | int d2 = VerticesBuffer[0].U - VerticesBuffer[2].U; |
| | 4418 | int d3 = VerticesBuffer[1].U - VerticesBuffer[2].U; |
| | 4419 | |
| | 4420 | int ad1 = (d1 < 0) ? -d1 : d1, ad2 = (d2 < 0) ? -d2 : d2, ad3 = (d3 < 0) ? -d3 : d3; |
| | 4421 | int i1=0, i2=0, i3=0; |
| | 4422 | |
| | 4423 | if (ad1 > (128*(SPHERE_TEXTURE_WRAP-1)+64)*65536) |
| | 4424 | { |
| | 4425 | if (d1 > 0) |
| | 4426 | i2 = 1; |
| | 4427 | else |
| | 4428 | i1 = 1; |
| | 4429 | } |
| | 4430 | |
| | 4431 | if (ad2 > (128*(SPHERE_TEXTURE_WRAP-1)+64)*65536) |
| | 4432 | { |
| | 4433 | if (d2 > 0) |
| | 4434 | i3 = 1; |
| | 4435 | else |
| | 4436 | i1 = 1; |
| | 4437 | } |
| | 4438 | |
| | 4439 | if (ad3 > (128*(SPHERE_TEXTURE_WRAP-1)+64)*65536) |
| | 4440 | { |
| | 4441 | if (d3 > 0) |
| | 4442 | i3 = 1; |
| | 4443 | else |
| | 4444 | i2 = 1; |
| | 4445 | } |
| | 4446 | |
| | 4447 | if(i1) |
| | 4448 | VerticesBuffer[0].U += 128*65536*SPHERE_TEXTURE_WRAP; |
| | 4449 | |
| | 4450 | if(i2) |
| | 4451 | VerticesBuffer[1].U += 128*65536*SPHERE_TEXTURE_WRAP; |
| | 4452 | |
| | 4453 | if(i3) |
| | 4454 | VerticesBuffer[2].U += 128*65536*SPHERE_TEXTURE_WRAP; |
| | 4455 | } |
| | 4456 | */ |
| | 4457 | |
| | 4458 | VerticesBuffer[i].A = explosionPtr->LifeTime / 256; |
| | 4459 | VerticesBuffer[i].R = red; |
| | 4460 | VerticesBuffer[i].G = green; |
| | 4461 | VerticesBuffer[i].B = blue; |
| | 4462 | VerticesBuffer[i].SpecularR = VerticesBuffer[i].SpecularG = VerticesBuffer[i].SpecularB = 0; |
| | 4463 | //VerticesBuffer[i].U = VerticesBuffer[i].V = FastRandom() & 255; |
| | 4464 | //printf("TEXTUR SD %d %d\n", VerticesBuffer[i].U, VerticesBuffer[i].V); |
| | 4465 | |
| | 4466 | // no texture? |
| | 4467 | //VerticesBuffer[i].U = VerticesBuffer[i].V = 0; |
| | 4468 | } |
| | 4469 | |
| | 4470 | if(PolyWithinFrustrum(3)) |
| | 4471 | TexturedPolygon(BurningImageNumber, draw_vertices, TRANSLUCENCY_NORMAL); |
| | 4472 | } |
| | 4473 | } |
| | 4474 | |
| | 4475 | void RenderInsideAlienTongue(int offset) |
| | 4476 | { |
| | 4477 | RENDERVERTEX *VerticesBuffer = VerticesUnClipped; |
| | 4478 | |
| | 4479 | extern int AlienTongueImageNumber; |
| | 4480 | |
| | 4481 | #define TONGUE_SCALE 1024 |
| | 4482 | int TonguePolyVertexList[4][4] = |
| | 4483 | { |
| | 4484 | {0,3,7,4}, //+ve y |
| | 4485 | {1,2,3,0}, //+ve x |
| | 4486 | {5,6,7,4}, //-ve x |
| | 4487 | {1,2,6,5}, //-ve y |
| | 4488 | }; |
| | 4489 | |
| | 4490 | VECTORCH vertices[8]= |
| | 4491 | { |
| | 4492 | {+TONGUE_SCALE,-TONGUE_SCALE,0}, |
| | 4493 | {+TONGUE_SCALE,+TONGUE_SCALE,0}, |
| | 4494 | {+TONGUE_SCALE,+TONGUE_SCALE,+TONGUE_SCALE*4}, |
| | 4495 | {+TONGUE_SCALE,-TONGUE_SCALE,+TONGUE_SCALE*4}, |
| | 4496 | |
| | 4497 | {-TONGUE_SCALE,-TONGUE_SCALE,0}, |
| | 4498 | {-TONGUE_SCALE,+TONGUE_SCALE,0}, |
| | 4499 | {-TONGUE_SCALE,+TONGUE_SCALE,+TONGUE_SCALE*4}, |
| | 4500 | {-TONGUE_SCALE,-TONGUE_SCALE,+TONGUE_SCALE*4}, |
| | 4501 | }; |
| | 4502 | |
| | 4503 | static const int CuboidPolyVertexU[][4] = |
| | 4504 | { |
| | 4505 | {1,1,1,1}, |
| | 4506 | |
| | 4507 | {127,127,0,0}, |
| | 4508 | {128,128,255,255}, |
| | 4509 | |
| | 4510 | {127,127,0,0}, |
| | 4511 | {128,128,255,255}, |
| | 4512 | }; |
| | 4513 | |
| | 4514 | static const int CuboidPolyVertexV[][4] = |
| | 4515 | { |
| | 4516 | {1,1,1,1}, |
| | 4517 | |
| | 4518 | {127,0,0,127}, |
| | 4519 | {127,0,0,127}, |
| | 4520 | {128,255,255,128}, |
| | 4521 | {128,255,255,128}, |
| | 4522 | }; |
| | 4523 | |
| | 4524 | VECTORCH translatedPts[8]; |
| | 4525 | |
| | 4526 | int polyNumber = 0; |
| | 4527 | |
| | 4528 | #if 1 |
| | 4529 | { |
| | 4530 | int i = 7; |
| | 4531 | do |
| | 4532 | { |
| | 4533 | translatedPts[i] = vertices[i]; |
| | 4534 | translatedPts[i].vz -= (ONE_FIXED-offset)/16; |
| | 4535 | // TranslatePointIntoViewspace(&translatedPts[i]); |
| | 4536 | |
| | 4537 | } while(i--); |
| | 4538 | } |
| | 4539 | #endif |
| | 4540 | |
| | 4541 | for(; polyNumber < 4; polyNumber++) |
| | 4542 | { |
| | 4543 | int i=0; |
| | 4544 | for (; i < 4; i++) |
| | 4545 | { |
| | 4546 | int v = TonguePolyVertexList[polyNumber][i]; |
| | 4547 | VerticesBuffer[i].A = 255; |
| | 4548 | VerticesBuffer[i].X = translatedPts[v].vx; |
| | 4549 | VerticesBuffer[i].Y = translatedPts[v].vy; |
| | 4550 | VerticesBuffer[i].Z = translatedPts[v].vz; |
| | 4551 | VerticesBuffer[i].U = CuboidPolyVertexU[3][i]<<16; |
| | 4552 | VerticesBuffer[i].V = CuboidPolyVertexV[3][i]<<16; |
| | 4553 | |
| | 4554 | VerticesBuffer[i].R = VerticesBuffer[i].G = VerticesBuffer[i].B = offset/2048; |
| | 4555 | VerticesBuffer[i].SpecularR = VerticesBuffer[i].SpecularG = VerticesBuffer[i].SpecularB = 0; |
| | 4556 | } |
| | 4557 | |
| | 4558 | if(ClipPolygon(4)) |
| | 4559 | TexturedPolygon(AlienTongueImageNumber, draw_vertices, TRANSLUCENCY_GLOWING); |
| | 4560 | } |
| | 4561 | } |
| | 4562 | |
| | 4563 | #define NO_OF_STARS 700 |
| | 4564 | struct |
| | 4565 | { |
| | 4566 | VECTORCH Position; |
| | 4567 | int Colour; |
| | 4568 | int Frequency; |
| | 4569 | int Phase; |
| | 4570 | |
| | 4571 | } StarArray[NO_OF_STARS]; |
| | 4572 | |
| | 4573 | void CreateStarArray() |
| | 4574 | { |
| | 4575 | int i=0; |
| | 4576 | for (; i < NO_OF_STARS; i++) |
| | 4577 | { |
| | 4578 | int phi = random() & 4095; |
| | 4579 | |
| | 4580 | StarArray[i].Position.vy = ONE_FIXED-(random()&131071); |
| | 4581 | |
| | 4582 | { |
| | 4583 | float y = ((float)StarArray[i].Position.vy)/65536.0; |
| | 4584 | y = sqrt(1-y*y); |
| | 4585 | |
| | 4586 | StarArray[i].Position.vx = ((float)GetCos(phi)*y); |
| | 4587 | StarArray[i].Position.vz = ((float)GetSin(phi)*y); |
| | 4588 | } |
| | 4589 | |
| | 4590 | StarArray[i].Colour = 0xff000000 + (random()&0x7f7f7f)+0x7f7f7f; |
| | 4591 | StarArray[i].Frequency = random() & 4095; |
| | 4592 | StarArray[i].Phase = random() & 4095; |
| | 4593 | } |
| | 4594 | } |
| | 4595 | |
| | 4596 | void RenderStarfield() |
| | 4597 | { |
| | 4598 | RENDERVERTEX *VerticesBuffer = VerticesUnClipped; |
| | 4599 | int i; |
| | 4600 | int sizeX = 256; |
| | 4601 | int sizeY = MUL_FIXED(sizeX,87381); |
| | 4602 | |
| | 4603 | for (i=0; i < NO_OF_STARS; i++) |
| | 4604 | { |
| | 4605 | VECTORCH position = StarArray[i].Position; |
| | 4606 | PARTICLE particle; |
| | 4607 | particle.ParticleID = PARTICLE_STAR; |
| | 4608 | particle.Colour = StarArray[i].Colour; |
| | 4609 | #if 1 |
| | 4610 | position.vx += Global_VDB.VDB_World.vx; |
| | 4611 | position.vy += Global_VDB.VDB_World.vy; |
| | 4612 | position.vz += Global_VDB.VDB_World.vz; |
| | 4613 | |
| | 4614 | TranslatePointIntoViewspace(&position); |
| | 4615 | #endif |
| | 4616 | // RotateVector(&position,&(Global_VDB.VDB_Mat)); |
| | 4617 | |
| | 4618 | VerticesBuffer[0].X = position.vx - sizeX; |
| | 4619 | VerticesBuffer[0].Y = position.vy - sizeY; |
| | 4620 | VerticesBuffer[0].Z = position.vz; |
| | 4621 | VerticesBuffer[0].U = 192<<16; |
| | 4622 | VerticesBuffer[0].V = 0; |
| | 4623 | |
| | 4624 | VerticesBuffer[1].X = position.vx + sizeX; |
| | 4625 | VerticesBuffer[1].Y = position.vy - sizeY; |
| | 4626 | VerticesBuffer[1].Z = position.vz; |
| | 4627 | VerticesBuffer[1].U = 255<<16; |
| | 4628 | VerticesBuffer[1].V = 0; |
| | 4629 | |
| | 4630 | VerticesBuffer[2].X = position.vx + sizeX; |
| | 4631 | VerticesBuffer[2].Y = position.vy + sizeY; |
| | 4632 | VerticesBuffer[2].Z = position.vz; |
| | 4633 | VerticesBuffer[2].U = 255<<16; |
| | 4634 | VerticesBuffer[2].V = 63<<16; |
| | 4635 | |
| | 4636 | VerticesBuffer[3].X = position.vx - sizeX; |
| | 4637 | VerticesBuffer[3].Y = position.vy + sizeY; |
| | 4638 | VerticesBuffer[3].Z = position.vz; |
| | 4639 | VerticesBuffer[3].U = 192<<16; |
| | 4640 | VerticesBuffer[3].V = 63<<16; |
| | 4641 | |
| | 4642 | if(PolyWithinFrustrum(4)) |
| | 4643 | Particle_Output(&particle, draw_vertices); |
| | 4644 | } |
| | 4645 | } |
| | 4646 | |
| | 4647 | void ChooseLightingModel() |
| | 4648 | { |
| | 4649 | switch(UserProfile.active_bonus) |
| | 4650 | { |
| | 4651 | case CHEATMODE_NONACTIVE: |
| | 4652 | default: |
| | 4653 | { |
| | 4654 | switch (PlayerStatus.VisionMode) |
| | 4655 | { |
| | 4656 | default: |
| | 4657 | case VISION_MODE_NORMAL: |
| | 4658 | VertexIntensity = VertexIntensity_Standard_Opt; |
| | 4659 | break; |
| | 4660 | case VISION_MODE_IMAGEINTENSIFIER: |
| | 4661 | VertexIntensity = VertexIntensity_ImageIntensifier; |
| | 4662 | break; |
| | 4663 | case VISION_MODE_ALIEN_SENSE: |
| | 4664 | VertexIntensity = VertexIntensity_Alien_Sense; |
| | 4665 | break; |
| | 4666 | case VISION_MODE_PRED_THERMAL: |
| | 4667 | VertexIntensity = VertexIntensity_Pred_Thermal; |
| | 4668 | break; |
| | 4669 | case VISION_MODE_PRED_SEEALIENS: |
| | 4670 | VertexIntensity = VertexIntensity_Pred_SeeAliens; |
| | 4671 | break; |
| | 4672 | case VISION_MODE_PRED_SEEPREDTECH: |
| | 4673 | VertexIntensity = VertexIntensity_Pred_SeePredatorTech; |
| | 4674 | } |
| | 4675 | } |
| | 4676 | break; |
| | 4677 | case CHEATMODE_DRAWFULLBRIGHT: |
| | 4678 | VertexIntensity = VertexIntensity_FullBright; |
| | 4679 | break; |
| | 4680 | case CHEATMODE_DISCOINFERNO: |
| | 4681 | case CHEATMODE_TRIPTASTIC: |
| | 4682 | VertexIntensity = VertexIntensity_DiscoInferno; |
| | 4683 | break; |
| | 4684 | case CHEATMODE_UNDERWATER: |
| | 4685 | VertexIntensity = VertexIntensity_Underwater; |
| | 4686 | } |
| | 4687 | } |