1 /*KJL************************************************************************************
2 * kshape.c - replacement for all the pipeline stuff previously done in shape.c & clip.c *
3 ************************************************************************************KJL*/
4 #include "3dc.h"
5 #include <math.h>
6 #include "module.h"
7 #include "inline.h"
8
9 #include "stratdef.h"
10 #include "gamedef.h"
11 #include "maths.h"
12
13 #include "kshape.h"
14 #include "kzsort.h"
15 #include "frustum.h"
16
17 #define UseLocalAssert Yes
18 #include "ourasert.h"
19 #include "equipmnt.h"
20 #include "bh_pred.h"
21 #include "bh_marin.h"
22 #include "bh_corpse.h"
23 #include "bh_debri.h"
24 #include "bh_weap.h"
25 #include "bh_types.h"
26 #include "pldghost.h"
27 #include "particle.h"
28 #include "vision.h"
29 #include "sfx.h"
30 #include "d3d_render.h"
31 #include "opengl.h"
32 #include "avpview.h"
33 #include "sphere.h"
34 #include "detaillevels.h"
35 #include "avp_userprofile.h"
36 #include "hud.h"
37 #include "weapons.h"
38
39 #define ALIENS_LIFEFORCE_GLOW_COLOUR 0x20ff8080
40 #define MARINES_LIFEFORCE_GLOW_COLOUR 0x208080ff
41 #define PREDATORS_LIFEFORCE_GLOW_COLOUR 0x2080ff80
42
43 /* KJL 15:02:50 05/14/97 - new max lighting intensity */
44 #define MAX_INTENSITY (65536*4-1)
45
46 extern VIEWDESCRIPTORBLOCK *Global_VDB_Ptr;
47 extern DISPLAYBLOCK *Global_ODB_Ptr;
48 extern EXTRAITEMDATA *Global_EID_Ptr;
49 extern int *Global_EID_IPtr;
50 extern int ScanDrawMode;
51 extern int ZBufferMode;
52 extern int NormalFrameTime;
53
54 extern SHAPEHEADER *Global_ShapeHeaderPtr;
55 extern int *Global_ShapePoints;
56 extern int **Global_ShapeItems;
57 extern int *Global_ShapeNormals;
58 extern int *Global_ShapeVNormals;
59 extern int **Global_ShapeTextures;
60
61 extern MATRIXCH LToVMat;
62 extern EULER LToVMat_Euler;
63 extern MATRIXCH WToLMat;
64 extern VECTORCH LocalView;
65 extern VECTORCH LocalLightCH;
66
67 extern int NumLightSourcesForObject;
68 extern LIGHTBLOCK *LightSourcesForObject[];
69
70 #if SupportMorphing
71 extern MORPHDISPLAY MorphDisplay;
72 #endif
73
74 extern int VideoModeType;
75 extern int GlobalAmbience;
76 extern int NumActiveBlocks;
77
78 extern DISPLAYBLOCK *ActiveBlockList[];
79 extern SHAPEHEADER **mainshapelist;
80
81 int MirroringActive=0;
82 int MirroringAxis=-149*2;
83
84 VECTORCHF FogPosition;
85 float FogMagnitude;
86 #define VOLUMETRIC_FOG 0
87 #define UNDERWATER 0
88 #define SPATIAL_SHOCKWAVE 0
89 float CameraZoomScale;
90
91 int DrawFullBright;
92
93 int TripTasticPhase;
94
95 void SetupShapePipeline(void);
96 void ShapePipeline(SHAPEHEADER *shapePtr);
97
98 static void GouraudPolygon_Construct(POLYHEADER *polyPtr);
99
100 static void GouraudTexturedPolygon_Construct(POLYHEADER *polyPtr);
101
102 static void (*VertexIntensity)(RENDERVERTEX *renderVertexPtr);
103 static void VertexIntensity_Pred_Thermal(RENDERVERTEX *renderVertexPtr);
104 static void VertexIntensity_Pred_SeeAliens(RENDERVERTEX *renderVertexPtr);
105 static void VertexIntensity_Pred_SeePredatorTech(RENDERVERTEX *renderVertexPtr);
106 static void VertexIntensity_ImageIntensifier(RENDERVERTEX *renderVertexPtr);
107 static void VertexIntensity_Alien_Sense(RENDERVERTEX *renderVertexPtr);
108
109 static void VertexIntensity_Standard_Opt(RENDERVERTEX *renderVertexPtr);
110 static void VertexIntensity_FullBright(RENDERVERTEX *renderVertexPtr);
111 static void VertexIntensity_DiscoInferno(RENDERVERTEX *renderVertexPtr);
112 static void VertexIntensity_Underwater(RENDERVERTEX *renderVertexPtr);
113
114
115 extern void CreateTxAnimUVArray(int *txa_data, int *uv_array, int *shapeitemptr);
116
117 void PredatorThermalVision_ShapePipeline(SHAPEHEADER *shapePtr);
118 void PredatorSeeAliensVision_ShapePipeline(SHAPEHEADER *shapePtr);
119 static void CloakedPolygon_Construct(POLYHEADER *polyPtr);
120 static void PredatorThermalVisionPolygon_Construct(POLYHEADER *polyPtr);
121 static void PredatorSeeAliensVisionPolygon_Construct(POLYHEADER *polyPtr);
122 void DoAlienEnergyView(DISPLAYBLOCK *dispPtr);
123 static void FindAlienEnergySource_Recursion(HMODELCONTROLLER *controllerPtr, SECTION_DATA *sectionDataPtr, unsigned int colour);
124 void SquishPoints(SHAPEINSTR *shapeinstrptr);
125 void MorphPoints(SHAPEINSTR *shapeinstrptr);
126 void TranslateShapeVertices(SHAPEINSTR *shapeinstrptr);
127 static void ParticlePolygon_Construct(PARTICLE *particlePtr);
128 void RenderMirroredDecal(DECAL *decalPtr);
129 static void DecalPolygon_Construct(DECAL *decalPtr);
130 void RenderShaftOfLight2(MODULE *modulePtr);
131 void FindIntersectionWithYPlane(VECTORCH *startPtr, VECTORCH *directionPtr, VECTORCH *intersectionPtr);
132 void FindZFromXYIntersection(VECTORCH *startPtr, VECTORCH *directionPtr, VECTORCH *intersectionPtr);
133 void AddToTranslucentPolyList(POLYHEADER *inputPolyPtr,RENDERVERTEX *renderVerticesPtr);
134 void DrawWaterFallPoly(VECTORCH *v);
135
136
137 /*KJL************************************************************************************
138 * N.B. All the following global variables have their first elements initialised so that *
139 * they will end up in high memory on the Saturn. *
140 ************************************************************************************KJL*/
141
142 /*
143 Global variables and arrays
144 */
145
146 VECTORCH RotatedPts[maxrotpts]={{1,}};
147 int ItemColour=1;
148
149
150
151 #if SupportMorphing
152
153 #if (LazyEvaluationForMorphing == No)
154 VECTORCH MorphedPts[maxmorphPts];
155 #endif
156
157
158 #endif /* SupportMorphing */
159
160
161 static COLOURINTENSITIES ColourIntensityArray[maxrotpts];
162
163
164
165 RENDERPOLYGON RenderPolygon;
166 RENDERVERTEX VerticesBuffer[9]={{1,}};
167 static RENDERVERTEX TriangleVerticesBuffer[3]={{1,}};
168
169 static int *VertexNumberPtr=(int*)1;
170
171 extern struct KItem KItemList[maxpolyptrs];
172 extern int *MorphedObjectPointsPtr;
173
174 #define MAX_NO_OF_TRANSLUCENT_POLYGONS 1000
175 RENDERPOLYGON TranslucentPolygons[MAX_NO_OF_TRANSLUCENT_POLYGONS];
176 POLYHEADER TranslucentPolygonHeaders[MAX_NO_OF_TRANSLUCENT_POLYGONS];
177 int CurrentNumberOfTranslucentPolygons;
178
179 /* KJL 10:25:44 7/23/97 - this offset is used to push back the normal game gfx,
180 so that the HUD can be drawn over the top without sinking into walls, etc. */
181 int HeadUpDisplayZOffset=0;
182
183 extern int CloakingPhase;
184 static VECTORCH ObjectCentre;
185 static int HierarchicalObjectsLowestYValue;
186
187 HEATSOURCE HeatSourceList[MAX_NUMBER_OF_HEAT_SOURCES];
188 int NumberOfHeatSources;
189 int CloakingMode;
190 char CloakedPredatorIsMoving;
191 #if 0
192 static VECTORCH LocalCameraZAxis;
193 #endif
194
195 static int ObjectCounter;
196
InitialiseLightIntensityStamps(void)197 extern void InitialiseLightIntensityStamps(void)
198 {
199 int i = maxrotpts;
200 do
201 {
202 i--;
203 ColourIntensityArray[i].Stamp=0;
204 }
205 while(i);
206 ObjectCounter = 0;
207
208 }
209
210
SetupShapePipeline(void)211 void SetupShapePipeline(void)
212 {
213 #if VOLUMETRIC_FOG
214 {
215 // VECTORCH v = {-30399, -1792, 1050}; // genshd1
216 // VECTORCH v = {49937,-4000,-37709}; // hangar
217 // VECTORCH v = {-185,0,642};
218 // VECTORCH v = {6894,469,-13203};
219 VECTORCH v = {73608,3582,56211};
220 TranslatePointIntoViewspace(&v);
221 FogPosition.vx = v.vx;
222 FogPosition.vy = v.vy;
223 FogPosition.vz = v.vz;
224 FogMagnitude = FogPosition.vx*FogPosition.vx+FogPosition.vy*FogPosition.vy+FogPosition.vz*FogPosition.vz;
225 }
226 #endif
227
228 /* Set up these global pointers */
229 Global_ShapePoints = *(Global_ShapeHeaderPtr->points);
230 Global_ShapeTextures = Global_ShapeHeaderPtr->sh_textures;
231
232 if(Global_ODB_Ptr->ObEIDPtr)
233 {
234 Global_EID_Ptr = Global_ODB_Ptr->ObEIDPtr;
235 Global_EID_IPtr = (int *) Global_ODB_Ptr->ObEIDPtr;
236 }
237 else
238 {
239 Global_EID_Ptr = Global_ShapeHeaderPtr->sh_extraitemdata;
240 Global_EID_IPtr = (int *) Global_ShapeHeaderPtr->sh_extraitemdata;
241 }
242
243 if(Global_ShapeHeaderPtr->sh_normals)
244 {
245 Global_ShapeNormals = *(Global_ShapeHeaderPtr->sh_normals);
246 }
247 else
248 {
249 Global_ShapeNormals = 0;
250 }
251
252 if(Global_ShapeHeaderPtr->sh_vnormals)
253 {
254 Global_ShapeVNormals = *(Global_ShapeHeaderPtr->sh_vnormals);
255 }
256 else
257 {
258 Global_ShapeVNormals = 0;
259 }
260
261
262 // if((Global_ODB_Ptr->ObStrategyBlock)&&(Global_ODB_Ptr->ObStrategyBlock->I_SBtype == I_BehaviourQueenAlien))
263 // Global_ODB_Ptr->ObFlags3 &= ObFlag3_NoLightDot;
264
265 ObjectCounter++;
266
267 }
268
ChooseLightingModel(DISPLAYBLOCK * dispPtr)269 void ChooseLightingModel(DISPLAYBLOCK *dispPtr)
270 {
271 LOCALASSERT(dispPtr);
272 LOCALASSERT(dispPtr->ObShapeData);
273
274 if (DrawFullBright)
275 {
276 VertexIntensity = VertexIntensity_FullBright;
277 }
278 else if (DISCOINFERNO_CHEATMODE || TRIPTASTIC_CHEATMODE)
279 {
280 VertexIntensity = VertexIntensity_DiscoInferno;
281 }
282 else if (UNDERWATER_CHEATMODE)
283 {
284 VertexIntensity = VertexIntensity_Underwater;
285 }
286 else
287 {
288 switch (CurrentVisionMode)
289 {
290 default:
291 case VISION_MODE_NORMAL:
292 {
293 VertexIntensity = VertexIntensity_Standard_Opt;
294 break;
295 }
296 case VISION_MODE_ALIEN_SENSE:
297 {
298 VertexIntensity = VertexIntensity_Alien_Sense;
299 break;
300 }
301 case VISION_MODE_IMAGEINTENSIFIER:
302 {
303 VertexIntensity = VertexIntensity_ImageIntensifier;
304 break;
305 }
306 case VISION_MODE_PRED_THERMAL:
307 {
308 VertexIntensity = VertexIntensity_Pred_Thermal;
309 break;
310 }
311 case VISION_MODE_PRED_SEEALIENS:
312 {
313 VertexIntensity = VertexIntensity_Pred_SeeAliens;
314 break;
315 }
316 case VISION_MODE_PRED_SEEPREDTECH:
317 {
318 VertexIntensity = VertexIntensity_Pred_SeePredatorTech;
319 break;
320 }
321 }
322 }
323 }
324
325
326
327 /*KJL**********************************************************************************
328 * ShapePipeline() - this function processes a shape for rendering by considering each *
329 * polygon (item) in turn. *
330 **********************************************************************************KJL*/
ShapePipeline(SHAPEHEADER * shapePtr)331 void ShapePipeline(SHAPEHEADER *shapePtr)
332 {
333 int numitems= shapePtr->numitems;
334 int **itemArrayPtr = shapePtr->items;
335 #if 0
336 char objectCompletelyInView;
337 #endif
338 LOCALASSERT(numitems);
339
340 switch(CurrentVisionMode)
341 {
342 case VISION_MODE_PRED_THERMAL:
343 {
344 /* if we have an object with heat sources, draw it as such */
345 if (NumberOfHeatSources)//||((Global_ODB_Ptr->ObStrategyBlock)&&(Global_ODB_Ptr->ObStrategyBlock->I_SBtype == I_BehaviourAlien)))
346 {
347 PredatorThermalVision_ShapePipeline(shapePtr);
348 return;
349 }
350 break;
351 }
352 case VISION_MODE_PRED_SEEALIENS:
353 {
354 STRATEGYBLOCK *sbPtr = Global_ODB_Ptr->ObStrategyBlock;
355 if(sbPtr)
356 {
357 int useVision=0;
358 switch (sbPtr->I_SBtype)
359 {
360 case I_BehaviourAutoGun:
361 case I_BehaviourAlien:
362 case I_BehaviourQueenAlien:
363 case I_BehaviourFaceHugger:
364 case I_BehaviourPredatorAlien:
365 case I_BehaviourXenoborg:
366 {
367 useVision=1;
368 break;
369 }
370 case I_BehaviourMarine:
371 {
372 MARINE_STATUS_BLOCK *marineStatusPointer = (MARINE_STATUS_BLOCK *)(sbPtr->SBdataptr);
373 GLOBALASSERT(marineStatusPointer);
374
375 if (marineStatusPointer->Android)
376 {
377 useVision=1;
378 }
379 break;
380 }
381
382 case I_BehaviourNetGhost:
383 {
384 NETGHOSTDATABLOCK *ghostDataPtr = (NETGHOSTDATABLOCK *)Global_ODB_Ptr->ObStrategyBlock->SBdataptr;
385
386 if (ghostDataPtr->type==I_BehaviourAlienPlayer || ghostDataPtr->type==I_BehaviourAlien
387 || (ghostDataPtr->type==I_BehaviourNetCorpse&&ghostDataPtr->subtype==I_BehaviourAlienPlayer) )
388 {
389 useVision=1;
390 }
391 break;
392 }
393
394 case I_BehaviourNetCorpse:
395 {
396 NETCORPSEDATABLOCK *corpseDataPtr = (NETCORPSEDATABLOCK *)sbPtr->SBdataptr;
397 if (corpseDataPtr->Android || corpseDataPtr->Type==I_BehaviourAlienPlayer || corpseDataPtr->Type==I_BehaviourAlien)
398 {
399 useVision=1;
400 }
401 break;
402 }
403 case I_BehaviourHierarchicalFragment:
404 {
405 HDEBRIS_BEHAV_BLOCK *debrisDataPtr = (HDEBRIS_BEHAV_BLOCK *)sbPtr->SBdataptr;
406 if (debrisDataPtr->Type==I_BehaviourAlien
407 ||debrisDataPtr->Type==I_BehaviourQueenAlien
408 ||debrisDataPtr->Type==I_BehaviourPredatorAlien
409 ||debrisDataPtr->Type==I_BehaviourAutoGun
410 ||debrisDataPtr->Android)
411 {
412 useVision=1;
413 }
414 break;
415 }
416 case I_BehaviourSpeargunBolt:
417 {
418 SPEAR_BEHAV_BLOCK *spearDataPtr = (SPEAR_BEHAV_BLOCK *)sbPtr->SBdataptr;
419 if (spearDataPtr->SpearThroughFragment) // more flags required!
420 if (spearDataPtr->Type==I_BehaviourAlien
421 ||spearDataPtr->Type==I_BehaviourPredatorAlien
422 ||spearDataPtr->Type==I_BehaviourAutoGun)
423 {
424 useVision=1;
425 }
426 break;
427 }
428 default:
429 break;
430 }
431
432 if (useVision)
433 {
434 PredatorSeeAliensVision_ShapePipeline(shapePtr);
435 return;
436 }
437 }
438 break;
439 }
440 case VISION_MODE_PRED_SEEPREDTECH:
441 {
442 STRATEGYBLOCK *sbPtr = Global_ODB_Ptr->ObStrategyBlock;
443 if(sbPtr)
444 {
445 int useVision=0;
446 switch (sbPtr->I_SBtype)
447 {
448 case I_BehaviourPredator:
449 {
450 PREDATOR_STATUS_BLOCK *predData = (PREDATOR_STATUS_BLOCK *)Global_ODB_Ptr->ObStrategyBlock->SBdataptr;
451
452 if (!predData->CloakingEffectiveness)
453 {
454 useVision=1;
455 }
456 break;
457 }
458 case I_BehaviourNPCPredatorDisc:
459 case I_BehaviourPredatorDisc_SeekTrack:
460 {
461 useVision=1;
462 break;
463 }
464 case I_BehaviourNetGhost:
465 {
466 NETGHOSTDATABLOCK *ghostDataPtr = (NETGHOSTDATABLOCK *)Global_ODB_Ptr->ObStrategyBlock->SBdataptr;
467
468 if((ghostDataPtr->CloakingEffectiveness == 0)
469 && (ghostDataPtr->type==I_BehaviourPredatorPlayer || ghostDataPtr->type==I_BehaviourPredator
470 || (ghostDataPtr->type==I_BehaviourInanimateObject&&ghostDataPtr->IOType==IOT_Ammo&&ghostDataPtr->subtype==AMMO_PRED_DISC)
471 || (ghostDataPtr->type==I_BehaviourPredatorDisc_SeekTrack)
472 || (ghostDataPtr->type==I_BehaviourNetCorpse&&ghostDataPtr->subtype==I_BehaviourPredatorPlayer) ))
473 {
474 useVision=1;
475 }
476 break;
477 }
478
479 case I_BehaviourNetCorpse:
480 {
481 NETCORPSEDATABLOCK *corpseDataPtr = (NETCORPSEDATABLOCK *)sbPtr->SBdataptr;
482 if (corpseDataPtr->Type==I_BehaviourPredatorPlayer || corpseDataPtr->Type==I_BehaviourPredator)
483 {
484 useVision=1;
485 }
486 break;
487 }
488 case I_BehaviourHierarchicalFragment:
489 {
490 HDEBRIS_BEHAV_BLOCK *debrisDataPtr = (HDEBRIS_BEHAV_BLOCK *)sbPtr->SBdataptr;
491 if (debrisDataPtr->Type==I_BehaviourPredator)
492 {
493 useVision=1;
494 }
495 break;
496 }
497 case I_BehaviourInanimateObject:
498 {
499 INANIMATEOBJECT_STATUSBLOCK* objStatPtr = (INANIMATEOBJECT_STATUSBLOCK*) sbPtr->SBdataptr;
500
501 switch(objStatPtr->typeId)
502 {
503 case IOT_FieldCharge:
504 {
505 useVision = 1;
506 break;
507 }
508 case IOT_Ammo:
509 {
510 if (objStatPtr->subType == AMMO_PRED_RIFLE || objStatPtr->subType == AMMO_PRED_DISC)
511 {
512 useVision = 1;
513 }
514 break;
515 }
516 default:
517 break;
518 }
519 break;
520 }
521
522 default:
523 break;
524 }
525
526 if (useVision)
527 {
528 PredatorSeeAliensVision_ShapePipeline(shapePtr);
529 return;
530 }
531 }
532 else if (!Global_ODB_Ptr->ObMyModule)
533 {
534 PLAYER_STATUS *playerStatusPtr= (PLAYER_STATUS *) (Player->ObStrategyBlock->SBdataptr);
535 if (!(playerStatusPtr->cloakOn||playerStatusPtr->CloakingEffectiveness!=0))
536 {
537 PredatorSeeAliensVision_ShapePipeline(shapePtr);
538 return;
539 }
540 }
541 break;
542 }
543 default:
544 break;
545 }
546
547 // if((Global_ODB_Ptr->ObStrategyBlock)&&(Global_ODB_Ptr->ObStrategyBlock->I_SBtype == I_BehaviourAlien))
548 //textprint("shape alien\n");
549 #if 0
550 objectCompletelyInView = ObjectCompletelyWithinFrustrum(Global_ODB_Ptr);
551 if(!objectCompletelyInView) TestVerticesWithFrustrum();
552 #else
553 TestVerticesWithFrustrum();
554 #endif
555
556 #if 1
557 /* interesting hack for predator cloaking */
558 if(Global_ODB_Ptr->ObStrategyBlock)
559 {
560 PRED_CLOAKSTATE cloakingStatus = PCLOAK_Off;
561
562 if(Global_ODB_Ptr->ObStrategyBlock->I_SBtype == I_BehaviourNetGhost)
563 {
564 NETGHOSTDATABLOCK *ghostData = (NETGHOSTDATABLOCK *)Global_ODB_Ptr->ObStrategyBlock->SBdataptr;
565
566 if(ghostData->CloakingEffectiveness)
567 {
568 cloakingStatus = PCLOAK_On;
569 CloakingMode = ONE_FIXED*5/4-ghostData->CloakingEffectiveness;
570 }
571 }
572 if(Global_ODB_Ptr->ObStrategyBlock->I_SBtype == I_BehaviourPredator)
573 {
574 PREDATOR_STATUS_BLOCK *predData = (PREDATOR_STATUS_BLOCK *)Global_ODB_Ptr->ObStrategyBlock->SBdataptr;
575
576 if (predData->CloakingEffectiveness)
577 {
578 cloakingStatus = PCLOAK_On;
579 CloakingMode = ONE_FIXED*5/4-predData->CloakingEffectiveness;//32768;
580 }
581 }
582
583 if (cloakingStatus == PCLOAK_On)
584 {
585 do
586 {
587 POLYHEADER *polyPtr = (POLYHEADER*) (*itemArrayPtr++);
588 int pif;
589 #if 0
590 if (objectCompletelyInView)
591 {
592 pif = PolygonShouldBeDrawn(polyPtr);
593 }
594 else
595 {
596 pif = PolygonWithinFrustrum(polyPtr);
597 }
598 #else
599 pif = PolygonWithinFrustrum(polyPtr);
600 #endif
601 if(pif)
602 {
603
604 #if 1
605 switch(polyPtr->PolyItemType)
606 {
607 case I_ZB_Gouraud3dTexturedPolygon:
608 case I_ZB_Gouraud2dTexturedPolygon:
609 CloakedPolygon_Construct(polyPtr);
610 if (pif!=2)
611 {
612 GouraudTexturedPolygon_ClipWithZ();
613 if(RenderPolygon.NumberOfVertices<3) continue;
614 GouraudTexturedPolygon_ClipWithNegativeX();
615 if(RenderPolygon.NumberOfVertices<3) continue;
616 GouraudTexturedPolygon_ClipWithPositiveY();
617 if(RenderPolygon.NumberOfVertices<3) continue;
618 GouraudTexturedPolygon_ClipWithNegativeY();
619 if(RenderPolygon.NumberOfVertices<3) continue;
620 GouraudTexturedPolygon_ClipWithPositiveX();
621 if(RenderPolygon.NumberOfVertices<3) continue;
622 D3D_ZBufferedCloakedPolygon_Output(polyPtr,RenderPolygon.Vertices);
623 }
624 else D3D_ZBufferedCloakedPolygon_Output(polyPtr,VerticesBuffer);
625 break;
626 default:
627 textprint("found polygon of type %d\n",polyPtr->PolyItemType);
628 break;
629 }
630 #else
631 {
632 CloakedTexturedPolygon_Construct(polyPtr);
633 if (pif!=2)
634 {
635 TexturedPolygon_ClipWithZ();
636 if(RenderPolygon.NumberOfVertices<3) continue;
637 TexturedPolygon_ClipWithNegativeX();
638 if(RenderPolygon.NumberOfVertices<3) continue;
639 TexturedPolygon_ClipWithPositiveY();
640 if(RenderPolygon.NumberOfVertices<3) continue;
641 TexturedPolygon_ClipWithNegativeY();
642 if(RenderPolygon.NumberOfVertices<3) continue;
643 TexturedPolygon_ClipWithPositiveX();
644 if(RenderPolygon.NumberOfVertices<3) continue;
645 D3D_CloakedPredatorPolygon_Output(polyPtr,RenderPolygon.Vertices);
646 }
647 else D3D_CloakedPredatorPolygon_Output(polyPtr,VerticesBuffer);
648 }
649 #endif
650 }
651 }
652 while(--numitems);
653 return;
654 }
655 }
656 else if (!Global_ODB_Ptr->ObMyModule)
657 {
658 PLAYER_STATUS *playerStatusPtr= (PLAYER_STATUS *) (Player->ObStrategyBlock->SBdataptr);
659 if (playerStatusPtr->cloakOn||playerStatusPtr->CloakingEffectiveness!=0)
660 {
661 int a = GetSin(CloakingPhase&4095);
662 a = MUL_FIXED(a,a);
663 CloakingMode = ONE_FIXED*5/4-playerStatusPtr->CloakingEffectiveness;//32768;
664 do
665 {
666 POLYHEADER *polyPtr = (POLYHEADER*) (*itemArrayPtr++);
667 int pif;
668 pif = PolygonWithinFrustrum(polyPtr);
669 if(pif)
670 {
671 switch(polyPtr->PolyItemType)
672 {
673 case I_ZB_Gouraud3dTexturedPolygon:
674 case I_ZB_Gouraud2dTexturedPolygon:
675 CloakedPolygon_Construct(polyPtr);
676 if (pif!=2)
677 {
678 GouraudTexturedPolygon_ClipWithZ();
679 if(RenderPolygon.NumberOfVertices<3) continue;
680 GouraudTexturedPolygon_ClipWithNegativeX();
681 if(RenderPolygon.NumberOfVertices<3) continue;
682 GouraudTexturedPolygon_ClipWithPositiveY();
683 if(RenderPolygon.NumberOfVertices<3) continue;
684 GouraudTexturedPolygon_ClipWithNegativeY();
685 if(RenderPolygon.NumberOfVertices<3) continue;
686 GouraudTexturedPolygon_ClipWithPositiveX();
687 if(RenderPolygon.NumberOfVertices<3) continue;
688 D3D_ZBufferedCloakedPolygon_Output(polyPtr,RenderPolygon.Vertices);
689 }
690 else D3D_ZBufferedCloakedPolygon_Output(polyPtr,VerticesBuffer);
691 break;
692 default:
693 textprint("found polygon of type %d\n",polyPtr->PolyItemType);
694 break;
695 }
696 }
697 }
698 while(--numitems);
699 return;
700 }
701
702 }
703 #endif
704 #if 0
705 // if (Global_ODB_Ptr->ObStrategyBlock && !Global_ODB_Ptr->ObMyModule)
706 {
707 do
708 {
709 POLYHEADER *polyPtr = (POLYHEADER*) (*itemArrayPtr++);
710 int pif;
711
712 pif = PolygonWithinFrustrum(polyPtr);
713
714 if (pif)
715 {
716 GouraudPolygon_Construct(polyPtr);
717
718 if (pif!=2)
719 {
720 GouraudPolygon_ClipWithZ();
721 if(RenderPolygon.NumberOfVertices<3) continue;
722 GouraudPolygon_ClipWithNegativeX();
723 if(RenderPolygon.NumberOfVertices<3) continue;
724 GouraudPolygon_ClipWithPositiveY();
725 if(RenderPolygon.NumberOfVertices<3) continue;
726 GouraudPolygon_ClipWithNegativeY();
727 if(RenderPolygon.NumberOfVertices<3) continue;
728 GouraudPolygon_ClipWithPositiveX();
729 if(RenderPolygon.NumberOfVertices<3) continue;
730 D3D_ZBufferedGouraudPolygon_Output(polyPtr,RenderPolygon.Vertices);
731
732 }
733 else D3D_ZBufferedGouraudPolygon_Output(polyPtr,VerticesBuffer);
734 }
735 }
736 while(--numitems);
737 return;
738 }
739 #endif
740 do
741 {
742 POLYHEADER *polyPtr = (POLYHEADER*) (*itemArrayPtr++);
743 int pif;
744 #if 0
745 if (objectCompletelyInView)
746 {
747 pif = PolygonShouldBeDrawn(polyPtr);
748 }
749 else
750 {
751 pif = PolygonWithinFrustrum(polyPtr);
752 }
753 #else
754 pif = PolygonWithinFrustrum(polyPtr);
755 #endif
756
757 if (pif)
758 {
759 switch(polyPtr->PolyItemType)
760 {
761 #if debug
762 case I_Polyline:
763 case I_FilledPolyline:
764 case I_Wireframe:
765
766 /* NB This is intended to fall through to the GouraudPolygon case */
767 #endif
768 // case I_Gouraud3dTexturedPolygon:
769 case I_GouraudPolygon:
770 case I_Gouraud2dTexturedPolygon:
771 case I_Gouraud3dTexturedPolygon:
772 case I_2dTexturedPolygon:
773 case I_3dTexturedPolygon:
774 case I_ZB_2dTexturedPolygon:
775 case I_ZB_3dTexturedPolygon:
776 {
777
778 // LOCALASSERT(0);
779 break;
780 }
781 case I_ZB_GouraudPolygon:
782 {
783 // break;
784 // LOCALASSERT(0);
785 GouraudPolygon_Construct(polyPtr);
786
787 if (pif!=2)
788 {
789 GouraudPolygon_ClipWithZ();
790 if(RenderPolygon.NumberOfVertices<3) continue;
791 GouraudPolygon_ClipWithNegativeX();
792 if(RenderPolygon.NumberOfVertices<3) continue;
793 GouraudPolygon_ClipWithPositiveY();
794 if(RenderPolygon.NumberOfVertices<3) continue;
795 GouraudPolygon_ClipWithNegativeY();
796 if(RenderPolygon.NumberOfVertices<3) continue;
797 GouraudPolygon_ClipWithPositiveX();
798 if(RenderPolygon.NumberOfVertices<3) continue;
799 D3D_ZBufferedGouraudPolygon_Output(polyPtr,RenderPolygon.Vertices);
800
801 }
802 else D3D_ZBufferedGouraudPolygon_Output(polyPtr,VerticesBuffer);
803 break;
804 }
805 case I_ZB_Gouraud3dTexturedPolygon:
806 case I_ZB_Gouraud2dTexturedPolygon:
807 {
808 GouraudTexturedPolygon_Construct(polyPtr);
809 if (pif!=2)
810 {
811 /* if this polygon is a quad, split it into two */
812 if(RenderPolygon.NumberOfVertices==4)
813 {
814 RenderPolygon.NumberOfVertices=3;
815 TriangleVerticesBuffer[0] = VerticesBuffer[0];
816 TriangleVerticesBuffer[1] = VerticesBuffer[2];
817 TriangleVerticesBuffer[2] = VerticesBuffer[3];
818
819 GouraudTexturedPolygon_ClipWithZ();
820 if(RenderPolygon.NumberOfVertices<3) goto SecondTriangle;
821 GouraudTexturedPolygon_ClipWithNegativeX();
822 if(RenderPolygon.NumberOfVertices<3) goto SecondTriangle;
823 GouraudTexturedPolygon_ClipWithPositiveY();
824 if(RenderPolygon.NumberOfVertices<3) goto SecondTriangle;
825 GouraudTexturedPolygon_ClipWithNegativeY();
826 if(RenderPolygon.NumberOfVertices<3) goto SecondTriangle;
827 GouraudTexturedPolygon_ClipWithPositiveX();
828 if(RenderPolygon.NumberOfVertices<3) goto SecondTriangle;
829
830 if (polyPtr->PolyFlags & iflag_transparent)
831 {
832 AddToTranslucentPolyList(polyPtr,RenderPolygon.Vertices);
833 }
834 else
835 {
836 D3D_ZBufferedGouraudTexturedPolygon_Output(polyPtr,RenderPolygon.Vertices);
837 }
838
839 SecondTriangle:
840 RenderPolygon.NumberOfVertices=3;
841 VerticesBuffer[0] = TriangleVerticesBuffer[0];
842 VerticesBuffer[1] = TriangleVerticesBuffer[1];
843 VerticesBuffer[2] = TriangleVerticesBuffer[2];
844 }
845 GouraudTexturedPolygon_ClipWithZ();
846 if(RenderPolygon.NumberOfVertices<3) continue;
847 GouraudTexturedPolygon_ClipWithNegativeX();
848 if(RenderPolygon.NumberOfVertices<3) continue;
849 GouraudTexturedPolygon_ClipWithPositiveY();
850 if(RenderPolygon.NumberOfVertices<3) continue;
851 GouraudTexturedPolygon_ClipWithNegativeY();
852 if(RenderPolygon.NumberOfVertices<3) continue;
853 GouraudTexturedPolygon_ClipWithPositiveX();
854 if(RenderPolygon.NumberOfVertices<3) continue;
855
856 // polyPtr->PolyFlags |= iflag_transparent;
857 if (polyPtr->PolyFlags & iflag_transparent)
858 {
859 AddToTranslucentPolyList(polyPtr,RenderPolygon.Vertices);
860 }
861 else
862 {
863 D3D_ZBufferedGouraudTexturedPolygon_Output(polyPtr,RenderPolygon.Vertices);
864 }
865
866 }
867 else
868 {
869 // polyPtr->PolyFlags |= iflag_transparent;
870 if (polyPtr->PolyFlags & iflag_transparent)
871 {
872 AddToTranslucentPolyList(polyPtr,VerticesBuffer);
873 }
874 else
875 {
876 D3D_ZBufferedGouraudTexturedPolygon_Output(polyPtr,VerticesBuffer);
877 }
878 }
879 break;
880 }
881 default:
882 break;
883 }
884 }
885 }
886 while(--numitems);
887 }
888
PredatorThermalVision_ShapePipeline(SHAPEHEADER * shapePtr)889 void PredatorThermalVision_ShapePipeline(SHAPEHEADER *shapePtr)
890 {
891 int numitems= shapePtr->numitems;
892 int **itemArrayPtr = shapePtr->items;
893
894 LOCALASSERT(numitems);
895
896 TestVerticesWithFrustrum();
897 do
898 {
899 POLYHEADER *polyPtr = (POLYHEADER*) (*itemArrayPtr++);
900
901 int pif = PolygonWithinFrustrum(polyPtr);
902
903 if (pif)
904 {
905 PredatorThermalVisionPolygon_Construct(polyPtr);
906
907 if (pif!=2)
908 {
909 GouraudPolygon_ClipWithZ();
910 if(RenderPolygon.NumberOfVertices<3) continue;
911 GouraudPolygon_ClipWithNegativeX();
912 if(RenderPolygon.NumberOfVertices<3) continue;
913 GouraudPolygon_ClipWithPositiveY();
914 if(RenderPolygon.NumberOfVertices<3) continue;
915 GouraudPolygon_ClipWithNegativeY();
916 if(RenderPolygon.NumberOfVertices<3) continue;
917 GouraudPolygon_ClipWithPositiveX();
918 if(RenderPolygon.NumberOfVertices<3) continue;
919
920 D3D_PredatorThermalVisionPolygon_Output(polyPtr,RenderPolygon.Vertices);
921 }
922 else D3D_PredatorThermalVisionPolygon_Output(polyPtr,VerticesBuffer);
923 }
924 }
925 while(--numitems);
926 }
PredatorSeeAliensVision_ShapePipeline(SHAPEHEADER * shapePtr)927 void PredatorSeeAliensVision_ShapePipeline(SHAPEHEADER *shapePtr)
928 {
929 int numitems= shapePtr->numitems;
930 int **itemArrayPtr = shapePtr->items;
931
932 LOCALASSERT(numitems);
933
934 TestVerticesWithFrustrum();
935 do
936 {
937 POLYHEADER *polyPtr = (POLYHEADER*) (*itemArrayPtr++);
938
939 switch (polyPtr->PolyItemType)
940 {
941 case I_ZB_Gouraud3dTexturedPolygon:
942 case I_ZB_Gouraud2dTexturedPolygon:
943 {
944 int pif = PolygonWithinFrustrum(polyPtr);
945
946 if (pif)
947 {
948 PredatorSeeAliensVisionPolygon_Construct(polyPtr);
949
950 #if 0
951 if (pif!=2)
952 {
953 GouraudPolygon_ClipWithZ();
954 if(RenderPolygon.NumberOfVertices<3) continue;
955 GouraudPolygon_ClipWithNegativeX();
956 if(RenderPolygon.NumberOfVertices<3) continue;
957 GouraudPolygon_ClipWithPositiveY();
958 if(RenderPolygon.NumberOfVertices<3) continue;
959 GouraudPolygon_ClipWithNegativeY();
960 if(RenderPolygon.NumberOfVertices<3) continue;
961 GouraudPolygon_ClipWithPositiveX();
962 if(RenderPolygon.NumberOfVertices<3) continue;
963
964 D3D_PredatorSeeAliensVisionPolygon_Output(polyPtr,RenderPolygon.Vertices);
965 }
966 else D3D_PredatorSeeAliensVisionPolygon_Output(polyPtr,VerticesBuffer);
967 #else
968 if (pif!=2)
969 {
970 GouraudTexturedPolygon_ClipWithZ();
971 if(RenderPolygon.NumberOfVertices<3) continue;
972 GouraudTexturedPolygon_ClipWithNegativeX();
973 if(RenderPolygon.NumberOfVertices<3) continue;
974 GouraudTexturedPolygon_ClipWithPositiveY();
975 if(RenderPolygon.NumberOfVertices<3) continue;
976 GouraudTexturedPolygon_ClipWithNegativeY();
977 if(RenderPolygon.NumberOfVertices<3) continue;
978 GouraudTexturedPolygon_ClipWithPositiveX();
979 if(RenderPolygon.NumberOfVertices<3) continue;
980 D3D_ZBufferedGouraudTexturedPolygon_Output(polyPtr,RenderPolygon.Vertices);
981 }
982 else D3D_ZBufferedGouraudTexturedPolygon_Output(polyPtr,VerticesBuffer);
983 #endif
984 }
985 break;
986 }
987 default:
988 break;
989 }
990 }
991 while(--numitems);
992 }
993
994
995 /* CLOAKED POLYGONS */
CloakedPolygon_Construct(POLYHEADER * polyPtr)996 static void CloakedPolygon_Construct(POLYHEADER *polyPtr)
997 {
998 int *texture_defn_ptr;
999 RENDERVERTEX *renderVerticesPtr = VerticesBuffer;
1000 int i = RenderPolygon.NumberOfVertices;
1001
1002 /* get ptr to uv coords for this polygon */
1003 {
1004 int texture_defn_index = (polyPtr->PolyColour >> TxDefn);
1005 texture_defn_ptr = Global_ShapeTextures[texture_defn_index];
1006 }
1007
1008 VertexNumberPtr = &polyPtr->Poly1stPt;
1009
1010 /* If this texture is animated the UV array must be calculated */
1011 if(polyPtr->PolyFlags & iflag_txanim)
1012 {
1013 /* Create the UV array */
1014 int uv_array[maxpolypts * 2];
1015 CreateTxAnimUVArray(texture_defn_ptr, uv_array, (int*)polyPtr);
1016 texture_defn_ptr = uv_array;
1017
1018 do
1019 {
1020 VECTORCH *vertexPtr = &(RotatedPts[*VertexNumberPtr]);
1021 renderVerticesPtr->X = vertexPtr->vx;
1022 renderVerticesPtr->Y = vertexPtr->vy;
1023 renderVerticesPtr->Z = vertexPtr->vz;
1024 renderVerticesPtr->U = texture_defn_ptr[0];
1025 renderVerticesPtr->V = texture_defn_ptr[1];
1026
1027 VertexIntensity(renderVerticesPtr);
1028 {
1029 VECTORCH mag;
1030 int alpha;
1031 mag.vx = vertexPtr->vx - Global_ODB_Ptr->ObView.vx;
1032 mag.vy = vertexPtr->vy - Global_ODB_Ptr->ObView.vy;
1033 mag.vz = vertexPtr->vz - Global_ODB_Ptr->ObView.vz;
1034
1035
1036 if (mag.vx<0) mag.vx = -mag.vx;
1037 if (mag.vy<0) mag.vy = -mag.vy;
1038 if (mag.vz<0) mag.vz = -mag.vz;
1039 alpha = GetSin(((mag.vx+mag.vy+mag.vz)*3+CloakingPhase)&4095);
1040
1041 renderVerticesPtr->A = MUL_FIXED(alpha,alpha)>>10;
1042
1043 if(renderVerticesPtr->A==255)
1044 {
1045 renderVerticesPtr->R = 255;
1046 renderVerticesPtr->G = 255;
1047 renderVerticesPtr->B = 255;
1048 }
1049
1050 }
1051 renderVerticesPtr++;
1052 VertexNumberPtr++;
1053
1054 texture_defn_ptr += 2;
1055 }
1056 while(--i);
1057 }
1058 else
1059 {
1060 do
1061 {
1062 VECTORCH *vertexPtr = &(RotatedPts[*VertexNumberPtr]);
1063 renderVerticesPtr->X = vertexPtr->vx;
1064 renderVerticesPtr->Y = vertexPtr->vy;
1065 renderVerticesPtr->Z = vertexPtr->vz;
1066 renderVerticesPtr->U = texture_defn_ptr[0] << 16;
1067 renderVerticesPtr->V = texture_defn_ptr[1] << 16;
1068
1069 VertexIntensity(renderVerticesPtr);
1070 {
1071 VECTORCH mag;
1072 int alpha;
1073
1074 mag.vx = vertexPtr->vx - ObjectCentre.vx;
1075 mag.vy = vertexPtr->vy - MUL_FIXED(ObjectCentre.vy,87381);
1076 mag.vz = vertexPtr->vz - ObjectCentre.vz;
1077
1078 if (mag.vx<0) mag.vx = -mag.vx;
1079 if (mag.vy<0) mag.vy = -mag.vy;
1080 if (mag.vz<0) mag.vz = -mag.vz;
1081 alpha = GetSin(((mag.vx+mag.vy+mag.vz)*8+CloakingPhase)&4095);
1082
1083 alpha=MUL_FIXED(alpha,alpha);
1084 if (alpha>CloakingMode)
1085 {
1086 alpha=CloakingMode;
1087 }
1088 alpha/=256;
1089 if (alpha>255) alpha = 255;
1090 renderVerticesPtr->A = alpha;
1091
1092 if(CloakingMode>ONE_FIXED)
1093 {
1094 alpha = GetSin(((mag.vx+mag.vy+mag.vz)+CloakingPhase)&4095);
1095 alpha = MUL_FIXED(alpha,alpha)>>8;
1096 if(alpha==255)
1097 {
1098 renderVerticesPtr->A = 255;
1099 renderVerticesPtr->G = 128;
1100 renderVerticesPtr->B = 255;
1101 }
1102 }
1103 }
1104 renderVerticesPtr++;
1105 VertexNumberPtr++;
1106
1107 texture_defn_ptr += 2;
1108 }
1109 while(--i);
1110 }
1111
1112 }
1113
PredatorThermalVisionPolygon_Construct(POLYHEADER * polyPtr)1114 static void PredatorThermalVisionPolygon_Construct(POLYHEADER *polyPtr)
1115 {
1116 RENDERVERTEX *renderVerticesPtr = VerticesBuffer;
1117 int i = RenderPolygon.NumberOfVertices;
1118
1119 VertexNumberPtr = &polyPtr->Poly1stPt;
1120
1121 do
1122 {
1123 VECTORCH *vertexPtr = &(RotatedPts[*VertexNumberPtr]);
1124 renderVerticesPtr->X = vertexPtr->vx;
1125 renderVerticesPtr->Y = vertexPtr->vy;
1126 renderVerticesPtr->Z = vertexPtr->vz;
1127
1128 {
1129 int alpha;
1130 if (Global_ODB_Ptr->SpecialFXFlags&SFXFLAG_ISAFFECTEDBYHEAT)
1131 {
1132 int distanceFromHeatSource = 100000;
1133 int sourceNumber=NumberOfHeatSources;
1134 while(sourceNumber--)
1135 {
1136 VECTORCH mag;
1137 int m;
1138 mag.vx = vertexPtr->vx - HeatSourceList[sourceNumber].Position.vx;
1139 mag.vy = vertexPtr->vy - HeatSourceList[sourceNumber].Position.vy;
1140 mag.vz = vertexPtr->vz - HeatSourceList[sourceNumber].Position.vz;
1141
1142 m = Approximate3dMagnitude(&mag)*64;
1143
1144 if(m<distanceFromHeatSource) distanceFromHeatSource = m;
1145 }
1146
1147 alpha = distanceFromHeatSource+(GetSin(CloakingPhase&4095)>>3);
1148 if (alpha>65536) alpha = 65536;
1149 }
1150 else
1151 {
1152 alpha = 65536;
1153 }
1154
1155 {
1156 int brightness = MUL_FIXED(MUL_FIXED(alpha,alpha),1275);
1157
1158 if (brightness<256)
1159 {
1160 renderVerticesPtr->R=255;
1161 renderVerticesPtr->G=brightness;
1162 renderVerticesPtr->B=0;
1163 }
1164 else if (brightness<255+256)
1165 {
1166 int b=brightness-255;
1167 renderVerticesPtr->R=(255-b);
1168 renderVerticesPtr->G=255;
1169 renderVerticesPtr->B=0;
1170 }
1171 else if (brightness<255*2+256)
1172 {
1173 int b=brightness-255*2;
1174 renderVerticesPtr->R=0;
1175 renderVerticesPtr->G=255;
1176 renderVerticesPtr->B=b;
1177 }
1178 else if (brightness<255*3+256)
1179 {
1180 int b=brightness-255*3;
1181 renderVerticesPtr->R=0;
1182 renderVerticesPtr->G=255-b;
1183 renderVerticesPtr->B=255;
1184 }
1185 else
1186 {
1187 int b=brightness-255*4;
1188 renderVerticesPtr->R=0;
1189 renderVerticesPtr->G=0;
1190 renderVerticesPtr->B=255-b/2;
1191 }
1192 }
1193 }
1194 renderVerticesPtr++;
1195 VertexNumberPtr++;
1196 }
1197 while(--i);
1198 }
1199
PredatorSeeAliensVisionPolygon_Construct(POLYHEADER * polyPtr)1200 static void PredatorSeeAliensVisionPolygon_Construct(POLYHEADER *polyPtr)
1201 {
1202 int *texture_defn_ptr;
1203 RENDERVERTEX *renderVerticesPtr = VerticesBuffer;
1204 int i = RenderPolygon.NumberOfVertices;
1205 int alpha;
1206
1207 VertexNumberPtr = &polyPtr->Poly1stPt;
1208
1209 {
1210 {
1211 int texture_defn_index = (polyPtr->PolyColour >> TxDefn);
1212 texture_defn_ptr = Global_ShapeTextures[texture_defn_index];
1213 }
1214
1215 /* get ptr to uv coords for this polygon */
1216 if(polyPtr->PolyFlags & iflag_txanim)
1217 {
1218 /* Create the UV array */
1219 int uv_array[maxpolypts * 2];
1220 CreateTxAnimUVArray(texture_defn_ptr, uv_array, (int*)polyPtr);
1221 texture_defn_ptr = uv_array;
1222 }
1223
1224 if( (Global_ODB_Ptr->SpecialFXFlags & SFXFLAG_MELTINGINTOGROUND)
1225 &&(Global_ODB_Ptr->ObFlags2 < ONE_FIXED) )
1226 {
1227 alpha = Global_ODB_Ptr->ObFlags2 >> 8;
1228 RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL;
1229 }
1230 else
1231 {
1232 alpha = 255;
1233 RenderPolygon.TranslucencyMode = TRANSLUCENCY_OFF;
1234 }
1235
1236 do
1237 {
1238 VECTORCH *vertexPtr = &(RotatedPts[*VertexNumberPtr]);
1239
1240 if(polyPtr->PolyFlags & iflag_txanim)
1241 {
1242 renderVerticesPtr->U = texture_defn_ptr[0];
1243 renderVerticesPtr->V = texture_defn_ptr[1];
1244 }
1245 else
1246 {
1247 renderVerticesPtr->U = texture_defn_ptr[0] << 16;
1248 renderVerticesPtr->V = texture_defn_ptr[1] << 16;
1249 }
1250
1251
1252 renderVerticesPtr->X = vertexPtr->vx;
1253 renderVerticesPtr->Y = vertexPtr->vy;
1254 renderVerticesPtr->Z = vertexPtr->vz;
1255 {
1256 VECTORCH mag = RotatedPts[*VertexNumberPtr];//*(((VECTORCH *)Global_ShapeVNormals) + *VertexNumberPtr);
1257 int colour;
1258 mag.vx = vertexPtr->vx - Global_ODB_Ptr->ObView.vx;
1259 mag.vy = vertexPtr->vy - Global_ODB_Ptr->ObView.vy;
1260 mag.vz = vertexPtr->vz - Global_ODB_Ptr->ObView.vz;
1261
1262 colour = GetSin(((mag.vx+mag.vy+mag.vz)*8+CloakingPhase)&4095);
1263 colour = MUL_FIXED(colour,colour);
1264 renderVerticesPtr->B = MUL_FIXED(colour,255);
1265 renderVerticesPtr->R = renderVerticesPtr->B/2;
1266 renderVerticesPtr->G = renderVerticesPtr->B/2;
1267
1268 colour = MUL_FIXED(colour,colour);
1269 colour = MUL_FIXED(colour,colour);
1270
1271 renderVerticesPtr->SpecularR = colour/1024;
1272 renderVerticesPtr->SpecularG = colour/1024;
1273 renderVerticesPtr->SpecularB = colour/1024;
1274 renderVerticesPtr->A = alpha;
1275 }
1276
1277 texture_defn_ptr += 2;
1278 renderVerticesPtr++;
1279 VertexNumberPtr++;
1280 }
1281 while(--i);
1282 }
1283 }
1284
1285 /* GOURAUD POLYGONS */
GouraudPolygon_Construct(POLYHEADER * polyPtr)1286 static void GouraudPolygon_Construct(POLYHEADER *polyPtr)
1287 {
1288 RENDERVERTEX *renderVerticesPtr = VerticesBuffer;
1289 int i = RenderPolygon.NumberOfVertices;
1290 VertexNumberPtr = &polyPtr->Poly1stPt;
1291 RenderPolygon.TranslucencyMode = TRANSLUCENCY_OFF;
1292
1293 do
1294 {
1295 int i;
1296 renderVerticesPtr->X = RotatedPts[*VertexNumberPtr].vx;
1297 renderVerticesPtr->Y = RotatedPts[*VertexNumberPtr].vy;
1298 renderVerticesPtr->Z = RotatedPts[*VertexNumberPtr].vz;
1299 VertexIntensity(renderVerticesPtr);
1300 i = (renderVerticesPtr->B+renderVerticesPtr->R+renderVerticesPtr->G)/3;
1301 renderVerticesPtr->R = i;
1302 renderVerticesPtr->G = i;
1303 renderVerticesPtr->B = 0;
1304 renderVerticesPtr++;
1305 VertexNumberPtr++;
1306 }
1307 while(--i);
1308
1309 }
1310
1311
1312
1313
1314
1315
1316 /* GOURAUD TEXTURED POLYGONS */
GouraudTexturedPolygon_Construct(POLYHEADER * polyPtr)1317 static void GouraudTexturedPolygon_Construct(POLYHEADER *polyPtr)
1318 {
1319 int *texture_defn_ptr;
1320 RENDERVERTEX *renderVerticesPtr = VerticesBuffer;
1321 int i = RenderPolygon.NumberOfVertices;
1322
1323
1324 /* get ptr to uv coords for this polygon */
1325 {
1326 int texture_defn_index = (polyPtr->PolyColour >> TxDefn);
1327 texture_defn_ptr = Global_ShapeTextures[texture_defn_index];
1328 }
1329
1330 VertexNumberPtr = &polyPtr->Poly1stPt;
1331
1332 /* If this texture is animated the UV array must be calculated */
1333 if(polyPtr->PolyFlags & iflag_txanim)
1334 {
1335 /* Create the UV array */
1336 int uv_array[maxpolypts * 2];
1337 CreateTxAnimUVArray(texture_defn_ptr, uv_array, (int*)polyPtr);
1338 texture_defn_ptr = uv_array;
1339
1340 do
1341 {
1342 VECTORCH *vertexPtr = &(RotatedPts[*VertexNumberPtr]);
1343 if (TRIPTASTIC_CHEATMODE)
1344 {
1345 renderVerticesPtr->X = vertexPtr->vx+GetSin((CloakingPhase*2 +vertexPtr->vz)&4095)/1024;
1346 renderVerticesPtr->Y = vertexPtr->vy+GetSin((CloakingPhase-3000 +vertexPtr->vx)&4095)/1024;
1347 renderVerticesPtr->Z = vertexPtr->vz+GetSin((CloakingPhase*3+239+vertexPtr->vy)&4095)/1024;
1348 }
1349 else if (UNDERWATER_CHEATMODE)
1350 {
1351 renderVerticesPtr->X = vertexPtr->vx+(GetSin((CloakingPhase/2 +vertexPtr->vz)&4095))/1024;
1352 renderVerticesPtr->Y = vertexPtr->vy+(GetSin((CloakingPhase-3000+vertexPtr->vx)&4095))/1024;
1353 renderVerticesPtr->Z = vertexPtr->vz+(GetSin((CloakingPhase/3+239+vertexPtr->vy)&4095))/1024;
1354 }
1355 else
1356 {
1357 renderVerticesPtr->X = vertexPtr->vx;
1358 renderVerticesPtr->Y = vertexPtr->vy;
1359 renderVerticesPtr->Z = vertexPtr->vz;
1360 }
1361 renderVerticesPtr->U = texture_defn_ptr[0];
1362 renderVerticesPtr->V = texture_defn_ptr[1];
1363
1364 if( (Global_ODB_Ptr->SpecialFXFlags & SFXFLAG_MELTINGINTOGROUND)
1365 &&(Global_ODB_Ptr->ObFlags2 < ONE_FIXED) )
1366 {
1367 renderVerticesPtr->A = Global_ODB_Ptr->ObFlags2 >> 8;
1368 RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL;
1369
1370 }
1371 else if (polyPtr->PolyFlags & iflag_transparent)
1372 {
1373 renderVerticesPtr->A = 128;
1374 RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL;
1375 }
1376 else
1377 {
1378 if (TRIPTASTIC_CHEATMODE)
1379 {
1380 renderVerticesPtr->A = TripTasticPhase;
1381 }
1382 else if (MOTIONBLUR_CHEATMODE)
1383 {
1384 renderVerticesPtr->A = 128;
1385 }
1386 else
1387 {
1388 renderVerticesPtr->A = 255;
1389 }
1390 RenderPolygon.TranslucencyMode = TRANSLUCENCY_OFF;
1391 }
1392
1393 if (polyPtr->PolyFlags & iflag_nolight)
1394 {
1395 switch (CurrentVisionMode)
1396 {
1397 default:
1398 case VISION_MODE_NORMAL:
1399 {
1400 renderVerticesPtr->R = 255;
1401 renderVerticesPtr->G = 255;
1402 renderVerticesPtr->B = 255;
1403 renderVerticesPtr->SpecularR = 0;
1404 renderVerticesPtr->SpecularG = 0;
1405 renderVerticesPtr->SpecularB = 0;
1406 break;
1407 }
1408 case VISION_MODE_IMAGEINTENSIFIER:
1409 {
1410 renderVerticesPtr->R = 0;
1411 renderVerticesPtr->G = 255;
1412 renderVerticesPtr->B = 0;
1413 renderVerticesPtr->SpecularR = 0;
1414 renderVerticesPtr->SpecularG = 0;
1415 renderVerticesPtr->SpecularB = 0;
1416 break;
1417 }
1418 case VISION_MODE_PRED_THERMAL:
1419 {
1420 renderVerticesPtr->R = 0;
1421 renderVerticesPtr->G = 0;
1422 renderVerticesPtr->B = 255;
1423 renderVerticesPtr->SpecularR = 0;
1424 renderVerticesPtr->SpecularG = 0;
1425 renderVerticesPtr->SpecularB = 0;
1426 break;
1427 }
1428 case VISION_MODE_PRED_SEEALIENS:
1429 {
1430 renderVerticesPtr->R = 255;
1431 renderVerticesPtr->G = 0;
1432 renderVerticesPtr->B = 0;
1433 renderVerticesPtr->SpecularR = 0;
1434 renderVerticesPtr->SpecularG = 0;
1435 renderVerticesPtr->SpecularB = 0;
1436 break;
1437 }
1438 case VISION_MODE_PRED_SEEPREDTECH:
1439 {
1440 renderVerticesPtr->R = 0;
1441 renderVerticesPtr->G = 255;
1442 renderVerticesPtr->B = 0;
1443 renderVerticesPtr->SpecularR = 255;
1444 renderVerticesPtr->SpecularG = 0;
1445 renderVerticesPtr->SpecularB = 255;
1446 break;
1447 }
1448 }
1449
1450 }
1451 else
1452 {
1453 VertexIntensity(renderVerticesPtr);
1454 }
1455 renderVerticesPtr++;
1456 VertexNumberPtr++;
1457
1458 texture_defn_ptr += 2;
1459 }
1460 while(--i);
1461 }
1462 else
1463 {
1464 do
1465 {
1466 VECTORCH *vertexPtr = &(RotatedPts[*VertexNumberPtr]);
1467 #if UNDERWATER
1468 renderVerticesPtr->X = vertexPtr->vx+GetSin((CloakingPhase*2 +vertexPtr->vz)&4095)/1024;
1469 renderVerticesPtr->Y = vertexPtr->vy+GetSin((CloakingPhase-3000 +vertexPtr->vx)&4095)/1024;
1470 renderVerticesPtr->Z = vertexPtr->vz+GetSin((CloakingPhase*3+239+vertexPtr->vy)&4095)/1024;
1471 #elif SPATIAL_SHOCKWAVE
1472 {
1473 int d = Magnitude(vertexPtr);
1474 int a = (CloakingPhase&16383)+4000;
1475 int u = d-a;
1476 int offset;
1477
1478 if (u>0 && u<8192)
1479 {
1480 VECTORCH n = *vertexPtr;
1481 Normalise(&n);
1482 u<<=3;
1483 offset = MUL_FIXED(MUL_FIXED(2*u,ONE_FIXED-u),8000) + MUL_FIXED(MUL_FIXED(u,u),8192 );
1484 LOCALASSERT(offset>=0 && offset<=8192);
1485 renderVerticesPtr->X = MUL_FIXED(n.vx,d);//a+offset*2);
1486 renderVerticesPtr->Y = MUL_FIXED(n.vy,d);//a+offset*2);
1487 renderVerticesPtr->Z = MUL_FIXED(n.vz,a+offset);
1488
1489 }
1490 else
1491 {
1492 renderVerticesPtr->X = vertexPtr->vx;
1493 renderVerticesPtr->Y = vertexPtr->vy;
1494 renderVerticesPtr->Z = vertexPtr->vz;
1495 }
1496
1497 }
1498 #else
1499 if (TRIPTASTIC_CHEATMODE)
1500 {
1501 renderVerticesPtr->X = vertexPtr->vx+GetSin((CloakingPhase*2 +vertexPtr->vz)&4095)/1024;
1502 renderVerticesPtr->Y = vertexPtr->vy+GetSin((CloakingPhase-3000 +vertexPtr->vx)&4095)/1024;
1503 renderVerticesPtr->Z = vertexPtr->vz+GetSin((CloakingPhase*3+239+vertexPtr->vy)&4095)/1024;
1504 }
1505 else if (UNDERWATER_CHEATMODE)
1506 {
1507 renderVerticesPtr->X = vertexPtr->vx+(GetSin((CloakingPhase/2 +vertexPtr->vz)&4095))/1024;
1508 renderVerticesPtr->Y = vertexPtr->vy+(GetSin((CloakingPhase-3000 +vertexPtr->vx)&4095))/1024;
1509 renderVerticesPtr->Z = vertexPtr->vz+(GetSin((CloakingPhase/3+239+vertexPtr->vy)&4095))/1024;
1510 }
1511 else
1512 {
1513 renderVerticesPtr->X = vertexPtr->vx;
1514 renderVerticesPtr->Y = vertexPtr->vy;
1515 renderVerticesPtr->Z = vertexPtr->vz;
1516 }
1517 #endif
1518 renderVerticesPtr->U = texture_defn_ptr[0] << 16;
1519 renderVerticesPtr->V = texture_defn_ptr[1] << 16;
1520
1521 if( (Global_ODB_Ptr->SpecialFXFlags & SFXFLAG_MELTINGINTOGROUND)
1522 &&(Global_ODB_Ptr->ObFlags2 < ONE_FIXED) )
1523 {
1524 renderVerticesPtr->A = Global_ODB_Ptr->ObFlags2 >> 8;
1525 RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL;
1526
1527 }
1528 else if (polyPtr->PolyFlags & iflag_transparent)
1529 {
1530 renderVerticesPtr->A = 128;
1531 RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL;
1532 }
1533 else
1534 {
1535 #if 0
1536 VECTORCH velocity;
1537 int a;
1538 velocity.vx = Player->ObStrategyBlock->DynPtr->Position.vx - Player->ObStrategyBlock->DynPtr->PrevPosition.vx;
1539 velocity.vy = Player->ObStrategyBlock->DynPtr->Position.vy - Player->ObStrategyBlock->DynPtr->PrevPosition.vy;
1540 velocity.vz = Player->ObStrategyBlock->DynPtr->Position.vz - Player->ObStrategyBlock->DynPtr->PrevPosition.vz;
1541 a = DIV_FIXED(Magnitude(&velocity)*4,NormalFrameTime)/256;
1542 if (a>192) a = 192;
1543 renderVerticesPtr->A = a;
1544
1545 #elif 1
1546 if (TRIPTASTIC_CHEATMODE)
1547 {
1548 renderVerticesPtr->A = TripTasticPhase;
1549 }
1550 else if (MOTIONBLUR_CHEATMODE)
1551 {
1552 renderVerticesPtr->A = 128;
1553 }
1554 else
1555 {
1556 renderVerticesPtr->A = 255;
1557 }
1558 #endif
1559
1560 RenderPolygon.TranslucencyMode = TRANSLUCENCY_OFF;
1561 }
1562
1563
1564 if (polyPtr->PolyFlags & iflag_nolight)
1565 {
1566 switch (CurrentVisionMode)
1567 {
1568 default:
1569 case VISION_MODE_NORMAL:
1570 {
1571 renderVerticesPtr->R = 255;
1572 renderVerticesPtr->G = 255;
1573 renderVerticesPtr->B = 255;
1574 renderVerticesPtr->SpecularR = 0;
1575 renderVerticesPtr->SpecularG = 0;
1576 renderVerticesPtr->SpecularB = 0;
1577 break;
1578 }
1579 case VISION_MODE_IMAGEINTENSIFIER:
1580 {
1581 renderVerticesPtr->R = 0;
1582 renderVerticesPtr->G = 255;
1583 renderVerticesPtr->B = 0;
1584 renderVerticesPtr->SpecularR = 0;
1585 renderVerticesPtr->SpecularG = 0;
1586 renderVerticesPtr->SpecularB = 0;
1587 break;
1588 }
1589 case VISION_MODE_PRED_THERMAL:
1590 {
1591 renderVerticesPtr->R = 0;
1592 renderVerticesPtr->G = 0;
1593 renderVerticesPtr->B = 255;
1594 renderVerticesPtr->SpecularR = 0;
1595 renderVerticesPtr->SpecularG = 0;
1596 renderVerticesPtr->SpecularB = 0;
1597 break;
1598 }
1599 case VISION_MODE_PRED_SEEALIENS:
1600 {
1601 renderVerticesPtr->R = 255;
1602 renderVerticesPtr->G = 0;
1603 renderVerticesPtr->B = 0;
1604 renderVerticesPtr->SpecularR = 0;
1605 renderVerticesPtr->SpecularG = 0;
1606 renderVerticesPtr->SpecularB = 0;
1607 break;
1608 }
1609 case VISION_MODE_PRED_SEEPREDTECH:
1610 {
1611 renderVerticesPtr->R = 0;
1612 renderVerticesPtr->G = 255;
1613 renderVerticesPtr->B = 0;
1614 renderVerticesPtr->SpecularR = 255;
1615 renderVerticesPtr->SpecularG = 0;
1616 renderVerticesPtr->SpecularB = 255;
1617 break;
1618 }
1619 }
1620
1621 }
1622 else
1623 {
1624 VertexIntensity(renderVerticesPtr);
1625 }
1626 renderVerticesPtr++;
1627 VertexNumberPtr++;
1628
1629 texture_defn_ptr += 2;
1630 }
1631 while(--i);
1632 }
1633
1634 }
1635
1636
1637
1638
1639
VertexIntensity_Pred_Thermal(RENDERVERTEX * renderVertexPtr)1640 static void VertexIntensity_Pred_Thermal(RENDERVERTEX *renderVertexPtr)
1641 {
1642 int redI,blueI,specular=0;
1643
1644 int vertexNumber = *VertexNumberPtr;
1645
1646
1647
1648 if(ColourIntensityArray[vertexNumber].Stamp==ObjectCounter)
1649 {
1650 renderVertexPtr->R = ColourIntensityArray[vertexNumber].R;
1651 renderVertexPtr->G = ColourIntensityArray[vertexNumber].G;
1652 renderVertexPtr->B = ColourIntensityArray[vertexNumber].B;
1653 renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR;
1654 renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG;
1655 renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB;
1656 return;
1657 }
1658 {
1659 VECTORCH *vertexNormalPtr = ((VECTORCH *)Global_ShapeVNormals) + vertexNumber;
1660 VECTORCH *vertexPtr = ((VECTORCH *)Global_ShapePoints)+vertexNumber;
1661 LIGHTBLOCK **larrayptr;
1662 LIGHTBLOCK *lptr;
1663 int i;
1664
1665 redI = 0;
1666
1667 larrayptr = LightSourcesForObject;
1668
1669 for(i = NumLightSourcesForObject; i!=0; i--)
1670 {
1671
1672 VECTORCH vertexToLight;
1673 int distanceToLight;
1674
1675 lptr = *larrayptr++;
1676
1677 if (lptr->LightFlags & LFlag_PreLitSource) continue;
1678
1679 vertexToLight.vx = lptr->LocalLP.vx - vertexPtr->vx;
1680 vertexToLight.vy = lptr->LocalLP.vy - vertexPtr->vy;
1681 vertexToLight.vz = lptr->LocalLP.vz - vertexPtr->vz;
1682
1683 #if 0
1684 distanceToLight = Approximate3dMagnitude(&vertexToLight)/2;
1685 #else
1686 distanceToLight = Approximate3dMagnitude(&vertexToLight);
1687 #endif
1688 if(distanceToLight < lptr->LightRange)
1689 {
1690 int idot = MUL_FIXED(lptr->LightRange-distanceToLight,lptr->BrightnessOverRange);
1691
1692 if( (distanceToLight>0) && (!(Global_ODB_Ptr->ObFlags3 & ObFlag3_NoLightDot)) )
1693 {
1694 int dotproduct = MUL_FIXED(vertexNormalPtr->vx,vertexToLight.vx)
1695 + MUL_FIXED(vertexNormalPtr->vy,vertexToLight.vy)
1696 + MUL_FIXED(vertexNormalPtr->vz,vertexToLight.vz);
1697 if(dotproduct>0)
1698 {
1699 idot = WideMulNarrowDiv(idot,dotproduct,distanceToLight);
1700 }
1701 else
1702 {
1703 idot = 0;
1704 }
1705
1706 idot = WideMulNarrowDiv(idot,dotproduct,distanceToLight);
1707 }
1708
1709
1710 redI += idot;
1711 if (lptr->LightFlags&LFlag_Thermal)
1712 {
1713 specular += idot;
1714 }
1715 }
1716 }
1717 }
1718 blueI = ONE_FIXED/2;
1719 if (renderVertexPtr->Z>5000)
1720 {
1721 int a = (renderVertexPtr->Z-5000);
1722 if (a>4096) blueI = (blueI*4096)/a;
1723 }
1724
1725 blueI >>= 8;
1726
1727 if(redI >= ONE_FIXED) redI = (ONE_FIXED - 1);
1728 redI >>=8;
1729
1730 specular>>=6;
1731 if (specular >= 255) specular = 255;
1732
1733 /* KJL 12:41:54 05/10/98 - red/green swapped, whilst testing colours */
1734 renderVertexPtr->R = 0;
1735 ColourIntensityArray[vertexNumber].R = 0;
1736 renderVertexPtr->B = blueI;
1737 ColourIntensityArray[vertexNumber].B = blueI;
1738 renderVertexPtr->G = redI/2;
1739 ColourIntensityArray[vertexNumber].G = redI/2;
1740
1741
1742 renderVertexPtr->SpecularR = specular;//specularR;
1743 ColourIntensityArray[vertexNumber].SpecularR = specular;//specularR;
1744
1745 renderVertexPtr->SpecularG = specular;
1746 ColourIntensityArray[vertexNumber].SpecularG = specular;
1747
1748 renderVertexPtr->SpecularB = specular;//specularB;
1749 ColourIntensityArray[vertexNumber].SpecularB = specular;//specularB;
1750
1751 ColourIntensityArray[vertexNumber].Stamp=ObjectCounter;
1752 }
VertexIntensity_Pred_SeeAliens(RENDERVERTEX * renderVertexPtr)1753 static void VertexIntensity_Pred_SeeAliens(RENDERVERTEX *renderVertexPtr)
1754 {
1755 int redI,blueI,specular=0;
1756
1757 int vertexNumber = *VertexNumberPtr;
1758
1759
1760
1761 if(ColourIntensityArray[vertexNumber].Stamp==ObjectCounter)
1762 {
1763 renderVertexPtr->R = ColourIntensityArray[vertexNumber].R;
1764 renderVertexPtr->G = ColourIntensityArray[vertexNumber].G;
1765 renderVertexPtr->B = ColourIntensityArray[vertexNumber].B;
1766 renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR;
1767 renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG;
1768 renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB;
1769 return;
1770 }
1771
1772 ColourIntensityArray[vertexNumber].Stamp=ObjectCounter;
1773
1774 {
1775 VECTORCH *vertexPtr = ((VECTORCH *)Global_ShapePoints)+vertexNumber;
1776 LIGHTBLOCK **larrayptr;
1777 LIGHTBLOCK *lptr;
1778 int i;
1779
1780 redI = 0;
1781
1782 larrayptr = LightSourcesForObject;
1783
1784 for(i = NumLightSourcesForObject; i!=0; i--)
1785 {
1786
1787 VECTORCH vertexToLight;
1788 int distanceToLight;
1789
1790 lptr = *larrayptr++;
1791
1792 if (lptr->LightFlags & LFlag_PreLitSource) continue;
1793
1794 vertexToLight.vx = lptr->LocalLP.vx - vertexPtr->vx;
1795 vertexToLight.vy = lptr->LocalLP.vy - vertexPtr->vy;
1796 vertexToLight.vz = lptr->LocalLP.vz - vertexPtr->vz;
1797
1798 distanceToLight = Approximate3dMagnitude(&vertexToLight);
1799 if(distanceToLight < lptr->LightRange)
1800 {
1801 int idot = MUL_FIXED(lptr->LightRange-distanceToLight,lptr->BrightnessOverRange);
1802
1803 redI += idot;
1804 if(lptr->LightFlags&LFlag_Electrical)
1805 {
1806 specular += idot;
1807 }
1808 }
1809 }
1810 }
1811 redI >>=11;
1812 if(redI > 255) redI = 255;
1813 renderVertexPtr->G = redI;
1814 ColourIntensityArray[vertexNumber].G = redI;
1815
1816
1817 blueI = ONE_FIXED/2;
1818 if (renderVertexPtr->Z>5000)
1819 {
1820 int a = (renderVertexPtr->Z-5000);
1821 if (a>4096) blueI = (blueI*4096)/a;
1822 }
1823 /* KJL 12:41:54 05/10/98 - red/green swapped, whilst testing colours */
1824 blueI >>= 9;
1825 renderVertexPtr->R = blueI;
1826 ColourIntensityArray[vertexNumber].R = blueI;
1827 renderVertexPtr->B = 0;
1828 ColourIntensityArray[vertexNumber].B = 0;
1829
1830 specular >>=10;
1831 if(specular>255) specular = 255;
1832 renderVertexPtr->SpecularR = specular;//specularR;
1833 ColourIntensityArray[vertexNumber].SpecularR = specular;//specularR;
1834 renderVertexPtr->SpecularG = specular;
1835 ColourIntensityArray[vertexNumber].SpecularG = specular;
1836 renderVertexPtr->SpecularB = specular;//specularB;
1837 ColourIntensityArray[vertexNumber].SpecularB = specular;//specularB;
1838 }
VertexIntensity_Pred_SeePredatorTech(RENDERVERTEX * renderVertexPtr)1839 static void VertexIntensity_Pred_SeePredatorTech(RENDERVERTEX *renderVertexPtr)
1840 {
1841 int redI,blueI;
1842
1843 int vertexNumber = *VertexNumberPtr;
1844
1845
1846
1847 if(ColourIntensityArray[vertexNumber].Stamp==ObjectCounter)
1848 {
1849 renderVertexPtr->R = ColourIntensityArray[vertexNumber].R;
1850 renderVertexPtr->G = ColourIntensityArray[vertexNumber].G;
1851 renderVertexPtr->B = ColourIntensityArray[vertexNumber].B;
1852 renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR;
1853 renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG;
1854 renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB;
1855 return;
1856 }
1857 ColourIntensityArray[vertexNumber].Stamp=ObjectCounter;
1858 {
1859 VECTORCH *vertexPtr = ((VECTORCH *)Global_ShapePoints)+vertexNumber;
1860 LIGHTBLOCK **larrayptr;
1861 LIGHTBLOCK *lptr;
1862 int i;
1863
1864 redI = 0;
1865
1866 larrayptr = LightSourcesForObject;
1867
1868 for(i = NumLightSourcesForObject; i!=0; i--)
1869 {
1870
1871 VECTORCH vertexToLight;
1872 int distanceToLight;
1873
1874 lptr = *larrayptr++;
1875
1876 if (lptr->LightFlags & LFlag_PreLitSource) continue;
1877
1878 vertexToLight.vx = lptr->LocalLP.vx - vertexPtr->vx;
1879 vertexToLight.vy = lptr->LocalLP.vy - vertexPtr->vy;
1880 vertexToLight.vz = lptr->LocalLP.vz - vertexPtr->vz;
1881
1882 distanceToLight = Approximate3dMagnitude(&vertexToLight);
1883 if(distanceToLight < lptr->LightRange)
1884 {
1885 int idot = MUL_FIXED(lptr->LightRange-distanceToLight,lptr->BrightnessOverRange);
1886
1887 redI += idot;
1888 }
1889 }
1890 }
1891 blueI = ONE_FIXED-1;
1892 if (renderVertexPtr->Z>5000)
1893 {
1894 int a = (renderVertexPtr->Z-5000);
1895 if (a>4096) blueI = (blueI*4096)/a;
1896 }
1897
1898 blueI >>=8;
1899
1900 redI >>=9;
1901 if (redI>255) redI=255;
1902
1903 /* KJL 12:41:54 05/10/98 - red/green swapped, whilst testing colours */
1904 renderVertexPtr->R = 255;
1905 ColourIntensityArray[vertexNumber].R = 255;
1906 renderVertexPtr->B = 255;
1907 ColourIntensityArray[vertexNumber].B = 255;
1908 renderVertexPtr->G = blueI;
1909 ColourIntensityArray[vertexNumber].G = blueI;
1910
1911
1912 renderVertexPtr->SpecularR = 255;//specularR;
1913 ColourIntensityArray[vertexNumber].SpecularR = 255;//specularR;
1914
1915 renderVertexPtr->SpecularG = redI;
1916 ColourIntensityArray[vertexNumber].SpecularG = redI;
1917
1918 renderVertexPtr->SpecularB = 255;//specularB;
1919 ColourIntensityArray[vertexNumber].SpecularB = 255;//specularB;
1920
1921 }
VertexIntensity_ImageIntensifier(RENDERVERTEX * renderVertexPtr)1922 static void VertexIntensity_ImageIntensifier(RENDERVERTEX *renderVertexPtr)
1923 {
1924 int greenI;
1925 int specular;
1926
1927 int vertexNumber = *VertexNumberPtr;
1928
1929 if(ColourIntensityArray[vertexNumber].Stamp==ObjectCounter)
1930 {
1931 renderVertexPtr->R = ColourIntensityArray[vertexNumber].R;
1932 renderVertexPtr->G = ColourIntensityArray[vertexNumber].G;
1933 renderVertexPtr->B = ColourIntensityArray[vertexNumber].B;
1934 renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR;
1935 renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG;
1936 renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB;
1937 return;
1938 }
1939 ColourIntensityArray[vertexNumber].Stamp=ObjectCounter;
1940
1941 {
1942 VECTORCH *vertexNormalPtr = ((VECTORCH *)Global_ShapeVNormals) + vertexNumber;
1943 VECTORCH *vertexPtr = ((VECTORCH *)Global_ShapePoints)+vertexNumber;
1944
1945 LIGHTBLOCK **larrayptr;
1946 LIGHTBLOCK *lptr;
1947 int i;
1948
1949 greenI = 0;
1950 specular = 0;
1951
1952 larrayptr = LightSourcesForObject;
1953
1954 for(i = NumLightSourcesForObject; i!=0; i--)
1955 {
1956
1957 VECTORCH vertexToLight;
1958 int distanceToLight;
1959
1960 lptr = *larrayptr++;
1961
1962 vertexToLight.vx = lptr->LocalLP.vx - vertexPtr->vx;
1963 vertexToLight.vy = lptr->LocalLP.vy - vertexPtr->vy;
1964 vertexToLight.vz = lptr->LocalLP.vz - vertexPtr->vz;
1965 {
1966 int dx,dy,dz;
1967
1968 dx = vertexToLight.vx;
1969 if (dx<0) dx = -dx;
1970
1971 dy = vertexToLight.vy;
1972 if (dy<0) dy = -dy;
1973
1974 dz = vertexToLight.vz;
1975 if (dz<0) dz = -dz;
1976
1977
1978 if (dx>dy)
1979 {
1980 if (dx>dz)
1981 {
1982 distanceToLight = dx + ((dy+dz)>>2);
1983 }
1984 else
1985 {
1986 distanceToLight = dz + ((dy+dx)>>2);
1987 }
1988 }
1989 else
1990 {
1991 if (dy>dz)
1992 {
1993 distanceToLight = dy + ((dx+dz)>>2);
1994 }
1995 else
1996 {
1997 distanceToLight = dz + ((dx+dy)>>2);
1998 }
1999 }
2000 }
2001
2002 if(distanceToLight < lptr->LightRange)
2003 {
2004 int idot = MUL_FIXED(lptr->LightRange-distanceToLight,lptr->BrightnessOverRange);
2005
2006 if(distanceToLight>0)
2007 {
2008 int dotproduct = MUL_FIXED(vertexNormalPtr->vx,vertexToLight.vx)
2009 + MUL_FIXED(vertexNormalPtr->vy,vertexToLight.vy)
2010 + MUL_FIXED(vertexNormalPtr->vz,vertexToLight.vz);
2011
2012 if(dotproduct>0)
2013 {
2014 idot = (WideMulNarrowDiv(idot,dotproduct,distanceToLight)+idot/4);
2015 }
2016 else
2017 {
2018 idot /= 4;
2019 }
2020 }
2021 if(idot<0)
2022 {
2023 LOCALASSERT(idot>=0);
2024 }
2025 specular += idot;
2026 }
2027 }
2028 }
2029
2030 greenI = 255;
2031 if (renderVertexPtr->Z>5000)
2032 {
2033 int a = (renderVertexPtr->Z-5000);
2034 if (a>4096) greenI = (greenI*4096)/a;
2035 }
2036 renderVertexPtr->G = greenI;
2037 ColourIntensityArray[vertexNumber].G = greenI;
2038
2039 renderVertexPtr->R = 0;
2040 ColourIntensityArray[vertexNumber].R = 0;
2041 renderVertexPtr->B = 0;
2042 ColourIntensityArray[vertexNumber].B = 0;
2043
2044 specular>>=7;
2045 if (specular>254) specular=254;
2046 LOCALASSERT(specular>=0 && specular<=254);
2047 renderVertexPtr->SpecularR = specular;
2048 ColourIntensityArray[vertexNumber].SpecularR = specular;
2049 renderVertexPtr->SpecularG = specular;
2050 ColourIntensityArray[vertexNumber].SpecularG = specular;
2051 renderVertexPtr->SpecularB = specular;
2052 ColourIntensityArray[vertexNumber].SpecularB = specular;
2053
2054 }
2055
VertexIntensity_Alien_Sense(RENDERVERTEX * renderVertexPtr)2056 static void VertexIntensity_Alien_Sense(RENDERVERTEX *renderVertexPtr)
2057 {
2058 int intensity;
2059 int vertexNumber = *VertexNumberPtr;
2060
2061 if(ColourIntensityArray[vertexNumber].Stamp==ObjectCounter)
2062 {
2063 renderVertexPtr->R = ColourIntensityArray[vertexNumber].R;
2064 renderVertexPtr->G = ColourIntensityArray[vertexNumber].G;
2065 renderVertexPtr->B = ColourIntensityArray[vertexNumber].B;
2066 renderVertexPtr->SpecularR = 0;
2067 renderVertexPtr->SpecularG = 0;
2068 renderVertexPtr->SpecularB = 0;
2069 return;
2070 }
2071 ColourIntensityArray[vertexNumber].Stamp=ObjectCounter;
2072
2073 intensity = 255;
2074 if (renderVertexPtr->Z>5000)
2075 {
2076 int a = (renderVertexPtr->Z-5000);
2077 if (a>1024) intensity = (intensity*1024)/a;
2078 }
2079
2080 renderVertexPtr->R = intensity;
2081 ColourIntensityArray[vertexNumber].R = intensity;
2082
2083 renderVertexPtr->G = intensity;
2084 ColourIntensityArray[vertexNumber].G = intensity;
2085
2086 renderVertexPtr->B = intensity;
2087 ColourIntensityArray[vertexNumber].B = intensity;
2088
2089 renderVertexPtr->SpecularR = 0;
2090 renderVertexPtr->SpecularG = 0;
2091 renderVertexPtr->SpecularB = 0;
2092
2093 }
2094
2095
2096
VertexIntensity_Standard_Opt(RENDERVERTEX * renderVertexPtr)2097 static void VertexIntensity_Standard_Opt(RENDERVERTEX *renderVertexPtr)
2098 {
2099 int redI,greenI,blueI;
2100 int specularR,specularG,specularB;
2101
2102 int vertexNumber = *VertexNumberPtr;
2103
2104 if(ColourIntensityArray[vertexNumber].Stamp==ObjectCounter)
2105 {
2106 renderVertexPtr->R = ColourIntensityArray[vertexNumber].R;
2107 renderVertexPtr->G = ColourIntensityArray[vertexNumber].G;
2108 renderVertexPtr->B = ColourIntensityArray[vertexNumber].B;
2109 renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR;
2110 renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG;
2111 renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB;
2112 return;
2113 }
2114 ColourIntensityArray[vertexNumber].Stamp=ObjectCounter;
2115 {
2116 VECTORCH *vertexNormalPtr = ((VECTORCH *)Global_ShapeVNormals) + vertexNumber;
2117 VECTORCH *vertexPtr = ((VECTORCH *)Global_ShapePoints)+vertexNumber;
2118
2119 LIGHTBLOCK **larrayptr;
2120 LIGHTBLOCK *lptr;
2121 int i;
2122
2123 if(Global_ShapeHeaderPtr->shapeflags & ShapeFlag_PreLit)
2124 {
2125 unsigned int packedI = Global_EID_IPtr[vertexNumber];
2126 blueI = (packedI&255)*257;
2127
2128 packedI >>=8;
2129 greenI = (packedI&255)*257;
2130
2131 packedI >>=8;
2132 redI = (packedI&255)*257;
2133 }
2134 else
2135 {
2136 redI = 0;
2137 greenI = 0;
2138 blueI = 0;
2139 }
2140
2141 specularR = 0;
2142 specularG = 0;
2143 specularB = 0;
2144
2145
2146
2147 larrayptr = LightSourcesForObject;
2148
2149 for(i = NumLightSourcesForObject; i!=0; i--)
2150 {
2151
2152 VECTORCH vertexToLight;
2153 int distanceToLight;
2154
2155 lptr = *larrayptr++;
2156
2157 vertexToLight.vx = lptr->LocalLP.vx - vertexPtr->vx;
2158 vertexToLight.vy = lptr->LocalLP.vy - vertexPtr->vy;
2159 vertexToLight.vz = lptr->LocalLP.vz - vertexPtr->vz;
2160 {
2161 int dx,dy,dz;
2162
2163 dx = vertexToLight.vx;
2164 if (dx<0) dx = -dx;
2165
2166 dy = vertexToLight.vy;
2167 if (dy<0) dy = -dy;
2168
2169 dz = vertexToLight.vz;
2170 if (dz<0) dz = -dz;
2171
2172
2173 if (dx>dy)
2174 {
2175 if (dx>dz)
2176 {
2177 distanceToLight = dx + ((dy+dz)>>2);
2178 }
2179 else
2180 {
2181 distanceToLight = dz + ((dy+dx)>>2);
2182 }
2183 }
2184 else
2185 {
2186 if (dy>dz)
2187 {
2188 distanceToLight = dy + ((dx+dz)>>2);
2189 }
2190 else
2191 {
2192 distanceToLight = dz + ((dx+dy)>>2);
2193 }
2194 }
2195 }
2196
2197 if(distanceToLight < lptr->LightRange)
2198 {
2199 int idot = MUL_FIXED(lptr->LightRange-distanceToLight,lptr->BrightnessOverRange);
2200 int r,g,b;
2201
2202 if(distanceToLight>0)
2203 {
2204 int dotproduct = MUL_FIXED(vertexNormalPtr->vx,vertexToLight.vx)
2205 + MUL_FIXED(vertexNormalPtr->vy,vertexToLight.vy)
2206 + MUL_FIXED(vertexNormalPtr->vz,vertexToLight.vz);
2207
2208 if(dotproduct>0)
2209 {
2210 idot = (WideMulNarrowDiv(idot,dotproduct,distanceToLight)+idot/4)/2;
2211 }
2212 else
2213 {
2214 idot /= 8;
2215 }
2216 }
2217
2218 r = MUL_FIXED(idot,lptr->RedScale);
2219 g = MUL_FIXED(idot,lptr->GreenScale);
2220 b = MUL_FIXED(idot,lptr->BlueScale);
2221
2222 redI += r;
2223 greenI += g;
2224 blueI += b;
2225
2226 if( !(lptr->LightFlags & LFlag_PreLitSource)
2227 && !(lptr->LightFlags & LFlag_NoSpecular) )
2228 {
2229 specularR += r;
2230 specularG += g;
2231 specularB += b;
2232 }
2233 }
2234 }
2235 }
2236
2237 if(Global_ODB_Ptr->SpecialFXFlags & SFXFLAG_ONFIRE)
2238 {
2239 specularR>>=2;
2240 specularG>>=2;
2241 specularB>>=2;
2242
2243 redI>>=1;
2244 greenI>>=1;
2245 blueI>>=1;
2246 }
2247
2248 /* Intensity for Textures */
2249 redI >>= 8;
2250 if(redI > 255) redI = 255;
2251 renderVertexPtr->R = redI;
2252 ColourIntensityArray[vertexNumber].R = redI;
2253
2254 greenI >>= 8;
2255 if(greenI > 255) greenI = 255;
2256 renderVertexPtr->G = greenI;
2257 ColourIntensityArray[vertexNumber].G = greenI;
2258
2259 blueI >>= 8;
2260 if(blueI > 255) blueI = 255;
2261 renderVertexPtr->B = blueI;
2262 ColourIntensityArray[vertexNumber].B = blueI;
2263
2264 specularR >>= 10;
2265 if(specularR > 255) specularR = 255;
2266 renderVertexPtr->SpecularR = specularR;
2267 ColourIntensityArray[vertexNumber].SpecularR = specularR;
2268
2269 specularG >>= 10;
2270 if(specularG > 255) specularG = 255;
2271 renderVertexPtr->SpecularG = specularG;
2272 ColourIntensityArray[vertexNumber].SpecularG = specularG;
2273
2274 specularB >>= 10;
2275 if(specularB > 255) specularB = 255;
2276 renderVertexPtr->SpecularB = specularB;
2277 ColourIntensityArray[vertexNumber].SpecularB = specularB;
2278
2279 }
VertexIntensity_FullBright(RENDERVERTEX * renderVertexPtr)2280 static void VertexIntensity_FullBright(RENDERVERTEX *renderVertexPtr)
2281 {
2282 int vertexNumber = *VertexNumberPtr;
2283 renderVertexPtr->R = 255;
2284 ColourIntensityArray[vertexNumber].R = 255;
2285 renderVertexPtr->G = 255;
2286 ColourIntensityArray[vertexNumber].G = 255;
2287 renderVertexPtr->B = 255;
2288 ColourIntensityArray[vertexNumber].B = 255;
2289
2290 renderVertexPtr->SpecularR = 0;
2291 ColourIntensityArray[vertexNumber].SpecularR = 0;
2292 renderVertexPtr->SpecularG = 0;
2293 ColourIntensityArray[vertexNumber].SpecularG = 0;
2294 renderVertexPtr->SpecularB = 0;
2295 ColourIntensityArray[vertexNumber].SpecularB = 0;
2296 }
2297
VertexIntensity_DiscoInferno(RENDERVERTEX * renderVertexPtr)2298 static void VertexIntensity_DiscoInferno(RENDERVERTEX *renderVertexPtr)
2299 {
2300 int redI,greenI,blueI;
2301 int specularR,specularG,specularB;
2302
2303 int vertexNumber = *VertexNumberPtr;
2304
2305 if(ColourIntensityArray[vertexNumber].Stamp==ObjectCounter)
2306 {
2307 renderVertexPtr->R = ColourIntensityArray[vertexNumber].R;
2308 renderVertexPtr->G = ColourIntensityArray[vertexNumber].G;
2309 renderVertexPtr->B = ColourIntensityArray[vertexNumber].B;
2310 renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR;
2311 renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG;
2312 renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB;
2313 return;
2314 }
2315 ColourIntensityArray[vertexNumber].Stamp=ObjectCounter;
2316 {
2317 VECTORCH *vertexNormalPtr = ((VECTORCH *)Global_ShapeVNormals) + vertexNumber;
2318 VECTORCH *vertexPtr = ((VECTORCH *)Global_ShapePoints)+vertexNumber;
2319
2320 LIGHTBLOCK **larrayptr;
2321 LIGHTBLOCK *lptr;
2322 int i;
2323
2324 if(Global_ShapeHeaderPtr->shapeflags & ShapeFlag_PreLit)
2325 {
2326 unsigned int packedI = Global_EID_IPtr[vertexNumber];
2327 blueI = (packedI&255)*257;
2328
2329 packedI >>=8;
2330 greenI = (packedI&255)*257;
2331
2332 packedI >>=8;
2333 redI = (packedI&255)*257;
2334 }
2335 else
2336 {
2337 redI = 0;
2338 greenI = 0;
2339 blueI = 0;
2340 }
2341
2342 specularR = 0;
2343 specularG = 0;
2344 specularB = 0;
2345
2346
2347
2348 larrayptr = LightSourcesForObject;
2349
2350 for(i = NumLightSourcesForObject; i!=0; i--)
2351 {
2352
2353 VECTORCH vertexToLight;
2354 int distanceToLight;
2355
2356 lptr = *larrayptr++;
2357
2358 vertexToLight.vx = lptr->LocalLP.vx - vertexPtr->vx;
2359 vertexToLight.vy = lptr->LocalLP.vy - vertexPtr->vy;
2360 vertexToLight.vz = lptr->LocalLP.vz - vertexPtr->vz;
2361 {
2362 int dx,dy,dz;
2363
2364 dx = vertexToLight.vx;
2365 if (dx<0) dx = -dx;
2366
2367 dy = vertexToLight.vy;
2368 if (dy<0) dy = -dy;
2369
2370 dz = vertexToLight.vz;
2371 if (dz<0) dz = -dz;
2372
2373
2374 if (dx>dy)
2375 {
2376 if (dx>dz)
2377 {
2378 distanceToLight = dx + ((dy+dz)>>2);
2379 }
2380 else
2381 {
2382 distanceToLight = dz + ((dy+dx)>>2);
2383 }
2384 }
2385 else
2386 {
2387 if (dy>dz)
2388 {
2389 distanceToLight = dy + ((dx+dz)>>2);
2390 }
2391 else
2392 {
2393 distanceToLight = dz + ((dx+dy)>>2);
2394 }
2395 }
2396 }
2397
2398 if(distanceToLight < lptr->LightRange)
2399 {
2400 int idot = MUL_FIXED(lptr->LightRange-distanceToLight,lptr->BrightnessOverRange);
2401 int r,g,b;
2402
2403 if(distanceToLight>0)
2404 {
2405 int dotproduct = MUL_FIXED(vertexNormalPtr->vx,vertexToLight.vx)
2406 + MUL_FIXED(vertexNormalPtr->vy,vertexToLight.vy)
2407 + MUL_FIXED(vertexNormalPtr->vz,vertexToLight.vz);
2408
2409 if(dotproduct>0)
2410 {
2411 idot = (WideMulNarrowDiv(idot,dotproduct,distanceToLight)+idot/4)/2;
2412 }
2413 else
2414 {
2415 idot /= 8;
2416 }
2417 }
2418
2419 r = MUL_FIXED(idot,lptr->RedScale);
2420 g = MUL_FIXED(idot,lptr->GreenScale);
2421 b = MUL_FIXED(idot,lptr->BlueScale);
2422
2423 redI += r;
2424 greenI += g;
2425 blueI += b;
2426
2427 if( !(lptr->LightFlags & LFlag_PreLitSource)
2428 && !(lptr->LightFlags & LFlag_NoSpecular) )
2429 {
2430 specularR += r;
2431 specularG += g;
2432 specularB += b;
2433 }
2434 }
2435 }
2436 }
2437
2438 if(Global_ODB_Ptr->SpecialFXFlags & SFXFLAG_ONFIRE)
2439 {
2440 specularR>>=2;
2441 specularG>>=2;
2442 specularB>>=2;
2443
2444 redI>>=1;
2445 greenI>>=1;
2446 blueI>>=1;
2447 }
2448
2449 {
2450 int i = (redI+greenI+blueI);
2451 int si = (specularR+specularG+specularB);
2452
2453 VECTORCH vertex = *(((VECTORCH *)Global_ShapePoints)+vertexNumber);
2454 int r,g,b;
2455 vertex.vx += Global_ODB_Ptr->ObWorld.vx;
2456 vertex.vy += Global_ODB_Ptr->ObWorld.vy;
2457 vertex.vz += Global_ODB_Ptr->ObWorld.vz;
2458
2459 r = GetSin((vertex.vx+CloakingPhase)&4095);
2460 r = MUL_FIXED(r,r);
2461 redI = MUL_FIXED(r,i);
2462 specularR = MUL_FIXED(r,si);
2463
2464 g = GetSin((vertex.vy+CloakingPhase/2)&4095);
2465 g = MUL_FIXED(g,g);
2466 greenI = MUL_FIXED(g,i);
2467 specularG = MUL_FIXED(g,si);
2468
2469 b = GetSin((vertex.vz+CloakingPhase*3)&4095);
2470 b = MUL_FIXED(b,b);
2471 blueI = MUL_FIXED(b,i);
2472 specularB = MUL_FIXED(b,si);
2473
2474 }
2475
2476
2477
2478 /* Intensity for Textures */
2479 redI >>= 8;
2480 if(redI > 255) redI = 255;
2481 renderVertexPtr->R = redI;
2482 ColourIntensityArray[vertexNumber].R = redI;
2483
2484 greenI >>= 8;
2485 if(greenI > 255) greenI = 255;
2486 renderVertexPtr->G = greenI;
2487 ColourIntensityArray[vertexNumber].G = greenI;
2488
2489 blueI >>= 8;
2490 if(blueI > 255) blueI = 255;
2491 renderVertexPtr->B = blueI;
2492 ColourIntensityArray[vertexNumber].B = blueI;
2493
2494 specularR >>= 10;
2495 if(specularR > 255) specularR = 255;
2496 renderVertexPtr->SpecularR = specularR;
2497 ColourIntensityArray[vertexNumber].SpecularR = specularR;
2498
2499 specularG >>= 10;
2500 if(specularG > 255) specularG = 255;
2501 renderVertexPtr->SpecularG = specularG;
2502 ColourIntensityArray[vertexNumber].SpecularG = specularG;
2503
2504 specularB >>= 10;
2505 if(specularB > 255) specularB = 255;
2506 renderVertexPtr->SpecularB = specularB;
2507 ColourIntensityArray[vertexNumber].SpecularB = specularB;
2508
2509
2510 }
VertexIntensity_Underwater(RENDERVERTEX * renderVertexPtr)2511 static void VertexIntensity_Underwater(RENDERVERTEX *renderVertexPtr)
2512 {
2513 int redI,greenI,blueI;
2514 int specularR,specularG,specularB;
2515
2516 int vertexNumber = *VertexNumberPtr;
2517
2518 if(ColourIntensityArray[vertexNumber].Stamp==ObjectCounter)
2519 {
2520 renderVertexPtr->R = ColourIntensityArray[vertexNumber].R;
2521 renderVertexPtr->G = ColourIntensityArray[vertexNumber].G;
2522 renderVertexPtr->B = ColourIntensityArray[vertexNumber].B;
2523 renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR;
2524 renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG;
2525 renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB;
2526 return;
2527 }
2528 ColourIntensityArray[vertexNumber].Stamp=ObjectCounter;
2529 {
2530 VECTORCH *vertexNormalPtr = ((VECTORCH *)Global_ShapeVNormals) + vertexNumber;
2531 VECTORCH *vertexPtr = ((VECTORCH *)Global_ShapePoints)+vertexNumber;
2532
2533 LIGHTBLOCK **larrayptr;
2534 LIGHTBLOCK *lptr;
2535 int i;
2536
2537 if(Global_ShapeHeaderPtr->shapeflags & ShapeFlag_PreLit)
2538 {
2539 unsigned int packedI = Global_EID_IPtr[vertexNumber];
2540 blueI = (packedI&255)*257;
2541
2542 packedI >>=8;
2543 greenI = (packedI&255)*257;
2544
2545 packedI >>=8;
2546 redI = (packedI&255)*257;
2547 }
2548 else
2549 {
2550 redI = 0;
2551 greenI = 0;
2552 blueI = 0;
2553 }
2554
2555 specularR = 0;
2556 specularG = 0;
2557 specularB = 0;
2558
2559
2560
2561 larrayptr = LightSourcesForObject;
2562
2563 for(i = NumLightSourcesForObject; i!=0; i--)
2564 {
2565
2566 VECTORCH vertexToLight;
2567 int distanceToLight;
2568
2569 lptr = *larrayptr++;
2570
2571 vertexToLight.vx = lptr->LocalLP.vx - vertexPtr->vx;
2572 vertexToLight.vy = lptr->LocalLP.vy - vertexPtr->vy;
2573 vertexToLight.vz = lptr->LocalLP.vz - vertexPtr->vz;
2574 {
2575 int dx,dy,dz;
2576
2577 dx = vertexToLight.vx;
2578 if (dx<0) dx = -dx;
2579
2580 dy = vertexToLight.vy;
2581 if (dy<0) dy = -dy;
2582
2583 dz = vertexToLight.vz;
2584 if (dz<0) dz = -dz;
2585
2586
2587 if (dx>dy)
2588 {
2589 if (dx>dz)
2590 {
2591 distanceToLight = dx + ((dy+dz)>>2);
2592 }
2593 else
2594 {
2595 distanceToLight = dz + ((dy+dx)>>2);
2596 }
2597 }
2598 else
2599 {
2600 if (dy>dz)
2601 {
2602 distanceToLight = dy + ((dx+dz)>>2);
2603 }
2604 else
2605 {
2606 distanceToLight = dz + ((dx+dy)>>2);
2607 }
2608 }
2609 }
2610
2611 if(distanceToLight < lptr->LightRange)
2612 {
2613 int idot = MUL_FIXED(lptr->LightRange-distanceToLight,lptr->BrightnessOverRange);
2614 int r,g,b;
2615
2616 if(distanceToLight>0)
2617 {
2618 int dotproduct = MUL_FIXED(vertexNormalPtr->vx,vertexToLight.vx)
2619 + MUL_FIXED(vertexNormalPtr->vy,vertexToLight.vy)
2620 + MUL_FIXED(vertexNormalPtr->vz,vertexToLight.vz);
2621
2622 if(dotproduct>0)
2623 {
2624 idot = (WideMulNarrowDiv(idot,dotproduct,distanceToLight)+idot/4)/2;
2625 }
2626 else
2627 {
2628 idot /= 8;
2629 }
2630 }
2631
2632 r = MUL_FIXED(idot,lptr->RedScale);
2633 g = MUL_FIXED(idot,lptr->GreenScale);
2634 b = MUL_FIXED(idot,lptr->BlueScale);
2635
2636 redI += r;
2637 greenI += g;
2638 blueI += b;
2639
2640 if( !(lptr->LightFlags & LFlag_PreLitSource)
2641 && !(lptr->LightFlags & LFlag_NoSpecular) )
2642 {
2643 specularR += r;
2644 specularG += g;
2645 specularB += b;
2646 }
2647 }
2648 }
2649 }
2650
2651 if(Global_ODB_Ptr->SpecialFXFlags & SFXFLAG_ONFIRE)
2652 {
2653 specularR>>=2;
2654 specularG>>=2;
2655 specularB>>=2;
2656
2657 redI>>=1;
2658 greenI>>=1;
2659 blueI>>=1;
2660 }
2661
2662 {
2663 if (specularB<renderVertexPtr->Z*4)
2664 specularB = renderVertexPtr->Z*4;
2665
2666 }
2667
2668
2669
2670 /* Intensity for Textures */
2671 redI >>= 8;
2672 if(redI > 255) redI = 255;
2673 renderVertexPtr->R = redI;
2674 ColourIntensityArray[vertexNumber].R = redI;
2675
2676 greenI >>= 8;
2677 if(greenI > 255) greenI = 255;
2678 renderVertexPtr->G = greenI;
2679 ColourIntensityArray[vertexNumber].G = greenI;
2680
2681 blueI >>= 8;
2682 if(blueI > 255) blueI = 255;
2683 renderVertexPtr->B = blueI;
2684 ColourIntensityArray[vertexNumber].B = blueI;
2685
2686 specularR >>= 10;
2687 if(specularR > 255) specularR = 255;
2688 renderVertexPtr->SpecularR = specularR;
2689 ColourIntensityArray[vertexNumber].SpecularR = specularR;
2690
2691 specularG >>= 10;
2692 if(specularG > 255) specularG = 255;
2693 renderVertexPtr->SpecularG = specularG;
2694 ColourIntensityArray[vertexNumber].SpecularG = specularG;
2695
2696 specularB >>= 10;
2697 if(specularB > 255) specularB = 255;
2698 renderVertexPtr->SpecularB = specularB;
2699 ColourIntensityArray[vertexNumber].SpecularB = specularB;
2700
2701
2702 }
2703
2704 /*KJL***********************************************************************
2705 * The following functions have been transplanted from the old shape.c, and *
2706 * will probably be found a new home at some point in the future. *
2707 ***********************************************************************KJL*/
2708
2709 /*
2710
2711 Texture Animation
2712
2713 */
2714
GetTxAnimArrayZ(int shape,int item)2715 int* GetTxAnimArrayZ(int shape, int item)
2716
2717 {
2718
2719 SHAPEHEADER *sptr;
2720 int **item_array_ptr;
2721 int **shape_textures;
2722 int *item_ptr;
2723 POLYHEADER *pheader;
2724 int texture_defn_index;
2725
2726
2727 sptr = GetShapeData(shape);
2728
2729 if(sptr && sptr->sh_textures && sptr->items) {
2730
2731 item_array_ptr = sptr->items;
2732 shape_textures = sptr->sh_textures;
2733
2734 item_ptr = item_array_ptr[item];
2735 pheader = (POLYHEADER *) item_ptr;
2736
2737 texture_defn_index = (pheader->PolyColour >> TxDefn);
2738
2739 if(pheader->PolyFlags & iflag_txanim) {
2740
2741 return (int*) shape_textures[texture_defn_index];
2742
2743 }
2744
2745 else return 0;
2746
2747 }
2748
2749 else return 0;
2750
2751 }
2752
2753
GetTxAnimDataZ(int shape,int item,int sequence)2754 TXANIMHEADER* GetTxAnimDataZ(int shape, int item, int sequence)
2755
2756 {
2757
2758 SHAPEHEADER *sptr;
2759 TXANIMHEADER **txah_ptr;
2760 TXANIMHEADER *txah;
2761 int **item_array_ptr;
2762 int **shape_textures;
2763 int *item_ptr;
2764 POLYHEADER *pheader;
2765 int texture_defn_index;
2766
2767
2768 sptr = GetShapeData(shape);
2769
2770 if(sptr && sptr->sh_textures && sptr->items) {
2771
2772 item_array_ptr = sptr->items;
2773 shape_textures = sptr->sh_textures;
2774
2775 item_ptr = item_array_ptr[item];
2776 pheader = (POLYHEADER *) item_ptr;
2777
2778 texture_defn_index = (pheader->PolyColour >> TxDefn);
2779
2780 if(pheader->PolyFlags & iflag_txanim) {
2781
2782 txah_ptr = (TXANIMHEADER **) shape_textures[texture_defn_index];
2783 txah_ptr++; /* Skip sequence shadow */
2784
2785 txah = txah_ptr[sequence];
2786
2787 return txah;
2788
2789 }
2790
2791 else return 0;
2792
2793 }
2794
2795 else return 0;
2796
2797 }
2798
2799
2800
2801
2802 /*
2803
2804 For some animated textures each sequence will represent a different view
2805 of a sprite. When each sequence has the same number of frames there is no
2806 problem transferring the value from one "txa_currentframe" to the other.
2807 However if the new sequence has a different number of frames a scaling must
2808 be done.
2809
2810 */
2811
ChangeSequence(TXANIMHEADER * txah_old,TXANIMHEADER * txah_new)2812 void ChangeSequence(TXANIMHEADER *txah_old, TXANIMHEADER *txah_new)
2813
2814 {
2815
2816 if(txah_new->txa_numframes == txah_old->txa_numframes) {
2817
2818 txah_new->txa_currentframe = txah_old->txa_currentframe;
2819
2820 }
2821
2822 else {
2823
2824 txah_new->txa_currentframe =
2825
2826 WideMulNarrowDiv(txah_old->txa_currentframe,
2827 txah_new->txa_maxframe,
2828 txah_old->txa_maxframe);
2829
2830 }
2831 }
2832
2833
2834 /*
2835
2836 This function copies the TXANIMHEADER from the shape data item sequence
2837 selected by the TXACTRLBLK to the TXANIMHEADER in the TXACTRLBLK
2838
2839 */
2840
GetTxAnimHeaderFromShape(TXACTRLBLK * taptr,int shape)2841 TXANIMHEADER* GetTxAnimHeaderFromShape(TXACTRLBLK *taptr, int shape)
2842
2843 {
2844
2845 TXANIMHEADER *txah = 0;
2846
2847
2848 {
2849
2850 txah = GetTxAnimDataZ(shape, taptr->tac_item, taptr->tac_sequence);
2851
2852 }
2853
2854 if(txah) {
2855
2856 taptr->tac_txah.txa_flags = txah->txa_flags;
2857 taptr->tac_txah.txa_state = txah->txa_state;
2858 taptr->tac_txah.txa_numframes = txah->txa_numframes;
2859 taptr->tac_txah.txa_framedata = txah->txa_framedata;
2860 taptr->tac_txah.txa_currentframe = txah->txa_currentframe;
2861 taptr->tac_txah.txa_maxframe = txah->txa_maxframe;
2862 taptr->tac_txah.txa_speed = txah->txa_speed;
2863
2864 }
2865
2866 return txah;
2867
2868 }
2869
2870
2871 /*
2872
2873 Texture Animation Control Blocks are used to update animation. At the start
2874 of "AddShape()" the relevant control block values are copied across to the
2875 item TXANIMHEADER.
2876
2877 */
2878
UpdateTxAnim(TXANIMHEADER * txah)2879 void UpdateTxAnim(TXANIMHEADER *txah)
2880
2881 {
2882
2883 int UpdateRate;
2884
2885
2886 if(txah->txa_flags & txa_flag_play) {
2887
2888 /* How fast do we go? */
2889
2890 if(txah->txa_flags & txa_flag_quantiseframetime) {
2891
2892 /* This option is still being designed and tested */
2893
2894 UpdateRate = txah->txa_speed & (~4096); /* 1/16th */
2895 if(UpdateRate < 4096) UpdateRate = 4096;
2896 UpdateRate = MUL_FIXED(NormalFrameTime, txah->txa_speed);
2897
2898 }
2899
2900 else UpdateRate = MUL_FIXED(NormalFrameTime, txah->txa_speed);
2901
2902
2903 /* Update the current frame */
2904
2905 if(txah->txa_flags & txa_flag_reverse) {
2906
2907 txah->txa_currentframe -= UpdateRate;
2908
2909 if(txah->txa_currentframe < 0) {
2910
2911 if(txah->txa_flags & txa_flag_noloop) {
2912
2913 txah->txa_currentframe = 0;
2914
2915 }
2916
2917 else {
2918
2919 txah->txa_currentframe += txah->txa_maxframe;
2920
2921 }
2922
2923 }
2924
2925 }
2926
2927 else {
2928
2929 txah->txa_currentframe += UpdateRate;
2930
2931 if(txah->txa_currentframe >= txah->txa_maxframe) {
2932
2933 if(txah->txa_flags & txa_flag_noloop) {
2934
2935 txah->txa_currentframe = txah->txa_maxframe - 1;
2936
2937 }
2938
2939 else {
2940
2941 txah->txa_currentframe -= txah->txa_maxframe;
2942
2943 }
2944
2945 }
2946
2947 }
2948
2949 }
2950
2951 }
2952
2953
2954 /*
2955
2956 Display block TXACTRLBLKS pass their data on to shape TXANIMHEADERs
2957
2958 */
2959
ControlTextureAnimation(DISPLAYBLOCK * dptr)2960 void ControlTextureAnimation(DISPLAYBLOCK *dptr)
2961 {
2962
2963 TXACTRLBLK *taptr;
2964 TXANIMHEADER *txah;
2965 int *iptr;
2966
2967
2968 taptr = dptr->ObTxAnimCtrlBlks;
2969
2970 while(taptr)
2971 {
2972 /* Update animation for the display block TXACTRLBLK */
2973 LOCALASSERT(&(taptr->tac_txah));
2974 UpdateTxAnim(&taptr->tac_txah);
2975
2976 /* Get the TXANIMHEADER from the shape data */
2977
2978 txah = taptr->tac_txah_s;
2979
2980 /* Copy across the current frame */
2981 LOCALASSERT(txah);
2982 txah->txa_currentframe = taptr->tac_txah.txa_currentframe;
2983
2984 iptr = taptr->tac_txarray;
2985 LOCALASSERT(iptr);
2986 *iptr = taptr->tac_sequence;
2987
2988 taptr = taptr->tac_next;
2989 }
2990 }
2991
CreateTxAnimUVArray(int * txa_data,int * uv_array,int * shapeitemptr)2992 void CreateTxAnimUVArray(int *txa_data, int *uv_array, int *shapeitemptr)
2993 {
2994 TXANIMHEADER **txah_ptr;
2995 TXANIMHEADER *txah;
2996 TXANIMFRAME *txaf;
2997 TXANIMFRAME *txaf0;
2998 TXANIMFRAME *txaf1;
2999 int *txaf0_uv;
3000 int *txaf1_uv;
3001 int CurrentFrame, NextFrame, Alpha, OneMinusAlpha;
3002 int i;
3003 int *iptr;
3004 int Orient, Scale;
3005 int OrientX, OrientY;
3006 int ScaleX, ScaleY;
3007 int sin, cos;
3008 int x, y;
3009 int x1, y1;
3010 int o1, o2, od;
3011 POLYHEADER *pheader = (POLYHEADER*) shapeitemptr;
3012 int sequence;
3013 int *txf_imageptr;
3014
3015
3016 /* The sequence # will have been copied across by the control block */
3017
3018 sequence = *txa_data;
3019
3020 // SBF: 64HACK - skip over the rest of the int*
3021 txa_data = (int *)((intptr_t) txa_data + sizeof(int *));
3022
3023 #if 0
3024 textprint("sequence = %d\n", sequence);
3025 #endif
3026
3027 txah_ptr = (TXANIMHEADER **) txa_data;
3028 txah = txah_ptr[sequence];
3029 txaf = txah->txa_framedata;
3030
3031
3032 /* Because the current frame can be set from outside, clamp it first */
3033
3034 if(txah->txa_currentframe < 0) {
3035
3036 txah->txa_currentframe = 0;
3037
3038 }
3039
3040 if(txah->txa_currentframe >= txah->txa_maxframe) {
3041
3042 txah->txa_currentframe = txah->txa_maxframe - 1;
3043
3044 }
3045
3046
3047 /* Frame # */
3048
3049 CurrentFrame = txah->txa_currentframe >> 16;
3050 Alpha = txah->txa_currentframe - (CurrentFrame << 16);
3051 OneMinusAlpha = ONE_FIXED - Alpha;
3052
3053
3054 /* Start and End Frame */
3055
3056 NextFrame = CurrentFrame + 1;
3057 if(NextFrame >= txah->txa_numframes) NextFrame = 0;
3058
3059 txaf0 = &txaf[CurrentFrame];
3060 txaf1 = &txaf[NextFrame];
3061
3062
3063 /*
3064
3065 Write the image index back to the item by overwriting the shape data.
3066 This is not elegant but it is one of the kind of things you expect to
3067 have happen when a major new feature is retro-fitted to a system.
3068
3069 */
3070
3071 pheader->PolyColour &= ClrTxIndex;
3072
3073
3074 /* Multi-View Sprites need to select an image from the array */
3075
3076 if(Global_ShapeHeaderPtr->shapeflags & ShapeFlag_MultiViewSprite) {
3077
3078 int **txf_uvarrayptr0 = (int **) txaf0->txf_uvdata;
3079 int **txf_uvarrayptr1 = (int **) txaf1->txf_uvdata;
3080 int index;
3081
3082
3083 index = GetMVSIndex(txah, <oVMat_Euler);
3084
3085 /*textprint("index = %d\n", index);*/
3086
3087
3088 txf_imageptr = (int *) txaf0->txf_image;
3089 pheader->PolyColour |= txf_imageptr[index];
3090
3091
3092 /* Get the uv data */
3093
3094 txaf0_uv = txf_uvarrayptr0[index];
3095 txaf1_uv = txf_uvarrayptr1[index];
3096
3097 }
3098
3099
3100 /* Single-View Sprites have just one image per frame */
3101
3102 else {
3103
3104 pheader->PolyColour |= txaf0->txf_image;
3105
3106 txaf0_uv = txaf0->txf_uvdata;
3107 txaf1_uv = txaf1->txf_uvdata;
3108
3109 }
3110
3111
3112 /* Calculate UVs */
3113
3114 iptr = uv_array;
3115
3116 if(txah->txa_flags & txa_flag_interpolate_uvs) {
3117
3118 for(i = txaf0->txf_numuvs; i!=0; i--) {
3119
3120 iptr[0] = MUL_FIXED(txaf0_uv[0], OneMinusAlpha)
3121 + MUL_FIXED(txaf1_uv[0], Alpha);
3122
3123 iptr[1] = MUL_FIXED(txaf0_uv[1], OneMinusAlpha)
3124 + MUL_FIXED(txaf1_uv[1], Alpha);
3125
3126 /*textprint("%d, %d\n", iptr[0] >> 16, iptr[1] >> 16);*/
3127
3128 txaf0_uv += 2;
3129 txaf1_uv += 2;
3130 iptr += 2;
3131
3132 }
3133
3134 }
3135
3136 else {
3137
3138 for(i = txaf0->txf_numuvs; i!=0; i--) {
3139
3140 iptr[0] = txaf0_uv[0];
3141 iptr[1] = txaf0_uv[1];
3142
3143 /*textprint("%d, %d\n", iptr[0] >> 16, iptr[1] >> 16);*/
3144
3145 txaf0_uv += 2;
3146 iptr += 2;
3147
3148 }
3149
3150 }
3151
3152
3153 /* Interpolate Orient and Scale */
3154
3155 o1 = txaf0->txf_orient;
3156 o2 = txaf1->txf_orient;
3157
3158 if(o1 == o2) {
3159
3160 Orient = o1;
3161
3162 }
3163
3164 else {
3165
3166 od = o1 - o2;
3167 if(od < 0) od = -od;
3168
3169 if(od >= deg180) {
3170
3171 o1 <<= (32 - 12);
3172 o1 >>= (32 - 12);
3173 o2 <<= (32 - 12);
3174 o2 >>= (32 - 12);
3175
3176 }
3177
3178 Orient = MUL_FIXED(o1, OneMinusAlpha) + MUL_FIXED(o2, Alpha);
3179 Orient &= wrap360;
3180
3181 }
3182
3183
3184 if(txaf0->txf_scale == txaf1->txf_scale) {
3185
3186 Scale = txaf0->txf_scale;
3187
3188 }
3189
3190 else {
3191
3192 Scale = WideMul2NarrowDiv(txaf0->txf_scale, OneMinusAlpha,
3193 txaf1->txf_scale, Alpha, ONE_FIXED);
3194
3195 }
3196
3197
3198 /* Interpolate Orient and Scale Origins */
3199
3200 if(txaf0->txf_orientx == txaf1->txf_orientx) {
3201
3202 OrientX = txaf0->txf_orientx;
3203
3204 }
3205
3206 else {
3207
3208 OrientX = MUL_FIXED(txaf0->txf_orientx, OneMinusAlpha)
3209 + MUL_FIXED(txaf1->txf_orientx, Alpha);
3210
3211 }
3212
3213
3214 if(txaf0->txf_orienty == txaf1->txf_orienty) {
3215
3216 OrientY = txaf0->txf_orienty;
3217
3218 }
3219
3220 else {
3221
3222 OrientY = MUL_FIXED(txaf0->txf_orienty, OneMinusAlpha)
3223 + MUL_FIXED(txaf1->txf_orienty, Alpha);
3224
3225 }
3226
3227
3228 if(txaf0->txf_scalex == txaf1->txf_scalex) {
3229
3230 ScaleX = txaf0->txf_scalex;
3231
3232 }
3233
3234 else {
3235
3236 ScaleX = MUL_FIXED(txaf0->txf_scalex, OneMinusAlpha)
3237 + MUL_FIXED(txaf1->txf_scalex, Alpha);
3238
3239 }
3240
3241
3242 if(txaf0->txf_scaley == txaf1->txf_scaley) {
3243
3244 ScaleY = txaf0->txf_scaley;
3245
3246 }
3247
3248 else {
3249
3250 ScaleY = MUL_FIXED(txaf0->txf_scaley, OneMinusAlpha)
3251 + MUL_FIXED(txaf1->txf_scaley, Alpha);
3252
3253 }
3254
3255
3256
3257 #if 0
3258 textprint("Alpha = %d\n", Alpha);
3259 textprint("OneMinusAlpha = %d\n", OneMinusAlpha);
3260 textprint("Orient = %d\n", Orient);
3261 textprint("txaf0->txf_scale = %d\n", txaf0->txf_scale);
3262 textprint("txaf1->txf_scale = %d\n", txaf1->txf_scale);
3263 textprint("Scale = %d\n", Scale);
3264 #endif
3265
3266 /*WaitForReturn();*/
3267
3268
3269
3270 #if 1
3271
3272
3273 /* Rotate UV Array */
3274
3275 if(Orient) {
3276
3277 sin = GetSin(Orient);
3278 cos = GetCos(Orient);
3279
3280 iptr = uv_array;
3281
3282 for(i = txaf0->txf_numuvs; i!=0; i--) {
3283
3284 x = iptr[0] - OrientX;
3285 y = iptr[1] - OrientY;
3286
3287 x1 = MUL_FIXED(x, cos) - MUL_FIXED(y, sin);
3288 y1 = MUL_FIXED(x, sin) + MUL_FIXED(y, cos);
3289
3290 iptr[0] = x1 + OrientX;
3291 iptr[1] = y1 + OrientY;
3292
3293 iptr += 2;
3294
3295 }
3296
3297 }
3298
3299
3300 /* Scale UV Array */
3301
3302 if(Scale != ONE_FIXED) {
3303
3304 iptr = uv_array;
3305
3306 for(i = txaf0->txf_numuvs; i!=0; i--) {
3307
3308 x = iptr[0] - ScaleX;
3309 y = iptr[1] - ScaleY;
3310
3311 x = MUL_FIXED(x, Scale);
3312 y = MUL_FIXED(y, Scale);
3313
3314 iptr[0] = x + ScaleX;
3315 iptr[1] = y + ScaleY;
3316
3317 iptr += 2;
3318
3319 }
3320
3321 }
3322
3323
3324 #endif
3325
3326
3327
3328
3329
3330
3331 #if 0
3332 textprint("Current Frame = %d\n", txah->txa_currentframe);
3333 textprint("Current Frame = %d\n", CurrentFrame);
3334 textprint("Next Frame = %d\n", NextFrame);
3335 textprint("Alpha = %d\n", Alpha);
3336 #endif
3337
3338
3339 /*textprint("Leaving CreateTxAnimUVArray\n");*/
3340 /*WaitForReturn();*/
3341
3342 }
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356 /*
3357
3358 Shape Points for Unrotated Sprites
3359
3360 */
3361
ShapeSpritePointsInstr(SHAPEINSTR * shapeinstrptr)3362 void ShapeSpritePointsInstr(SHAPEINSTR *shapeinstrptr)
3363
3364 {
3365
3366 int **shapeitemarrayptr = shapeinstrptr->sh_instr_data;
3367 int *shapeitemptr = *shapeitemarrayptr;
3368 VECTORCH *rotptsptr = RotatedPts;
3369 int numitems;
3370
3371
3372 for(numitems = shapeinstrptr->sh_numitems; numitems!=0; numitems--) {
3373
3374 rotptsptr->vx = shapeitemptr[ix];
3375 rotptsptr->vx += Global_ODB_Ptr->ObView.vx;
3376
3377 rotptsptr->vy = shapeitemptr[iy];
3378 rotptsptr->vy += Global_ODB_Ptr->ObView.vy;
3379
3380 rotptsptr->vz = shapeitemptr[iz];
3381 rotptsptr->vz += Global_ODB_Ptr->ObView.vz;
3382
3383 shapeitemptr += vsize;
3384 rotptsptr++;
3385
3386 }
3387
3388 }
3389
3390
3391 /*
3392
3393 Shape Points for Rotated Sprites
3394
3395 */
3396
3397
3398 //I've put my alterations to the sprite rotation
3399 //in the #else part.Richard
3400 #define UseKevinsModifiedSSRPI No
3401
3402
3403 #if UseKevinsModifiedSSRPI
3404
3405
3406
3407 #define ssrpi_kill_py Yes
3408
ShapeSpriteRPointsInstr(SHAPEINSTR * shapeinstrptr)3409 void ShapeSpriteRPointsInstr(SHAPEINSTR *shapeinstrptr)
3410
3411 {
3412
3413 int **shapeitemarrayptr = shapeinstrptr->sh_instr_data;
3414 int *shapeitemptr = *shapeitemarrayptr;
3415 VECTORCH *rotptsptr = RotatedPts;
3416 int numitems;
3417 int x,y,z;
3418 MATRIXCH m;
3419 #if ssrpi_kill_py
3420 EULER e;
3421 char flipX=0;
3422 #endif
3423 /*
3424
3425 Sprite Resizing
3426
3427 If this shape is a sprite and is using sprite resizing, there will be a transformed
3428 copy of the polygon points array (XY only) to copy back to the shape.
3429
3430 WARNING!
3431
3432 This function and data structure ASSUME that the sprite shape is using an item array,
3433 that there is just the one item, and that the world and UV space coordinates are in the
3434 form of "TL, BL, BR, TR". It also assumes that the sprite polygon is in the XY plane.
3435
3436 If ANY of these is not true for your sprite, DON'T attempt to use resizing!
3437
3438 */
3439
3440 if(Global_ShapeHeaderPtr->shapeflags & ShapeFlag_Sprite &&
3441 Global_ShapeHeaderPtr->shapeflags & ShapeFlag_SpriteResizing) {
3442
3443 int *ShapePoints;
3444 int **item_array_ptr;
3445 int *item_ptr;
3446 POLYHEADER *pheader;
3447 int *mypolystart;
3448 int texture_defn_index;
3449 int *texture_defn_ptr;
3450 TXANIMHEADER **txah_ptr;
3451 TXANIMHEADER *txah;
3452 TXANIMFRAME *txaf;
3453 TXANIMFRAME *txaf0;
3454 int CurrentFrame, sequence;
3455 int *iptr;
3456
3457 ShapePoints = *(Global_ShapeHeaderPtr->points);
3458
3459 /* Item */
3460
3461 item_array_ptr = Global_ShapeHeaderPtr->items; /* Assume item array */
3462 item_ptr = item_array_ptr[0]; /* Assume only one polygon */
3463 pheader = (POLYHEADER *) item_ptr;
3464
3465 /* Texture Animation */
3466
3467 texture_defn_index = (pheader->PolyColour >> TxDefn);
3468 texture_defn_ptr = Global_ShapeTextures[texture_defn_index];
3469
3470 sequence = *texture_defn_ptr++;
3471
3472 txah_ptr = (TXANIMHEADER **) texture_defn_ptr;
3473 txah = txah_ptr[sequence];
3474 txaf = txah->txa_framedata;
3475
3476 /* Because the current frame can be set from outside, clamp it first */
3477
3478 if(txah->txa_currentframe < 0)
3479 txah->txa_currentframe = 0;
3480 if(txah->txa_currentframe >= txah->txa_maxframe)
3481 txah->txa_currentframe = txah->txa_maxframe - 1;
3482
3483 CurrentFrame = txah->txa_currentframe >> 16;
3484
3485 txaf0 = &txaf[CurrentFrame];
3486
3487 /* UV array */
3488
3489 if(Global_ShapeHeaderPtr->shapeflags & ShapeFlag_Sprite) {
3490
3491 int **uvarrayptr = (int **) txaf0->txf_uvdata;
3492 iptr = uvarrayptr[GetMVSIndex(txah, <oVMat_Euler)];
3493
3494 }
3495
3496 else {
3497
3498 iptr = txaf0->txf_uvdata;
3499
3500 }
3501
3502 iptr += (txaf0->txf_numuvs * 2);
3503
3504 /* Redefine the Shape Points */
3505
3506 mypolystart = &pheader->Poly1stPt;
3507
3508 while(*mypolystart != Term) {
3509
3510 /*textprint("copying point %d\n", *mypolystart / vsize);*/
3511
3512 *(ShapePoints + *mypolystart + ix) = iptr[0];
3513 *(ShapePoints + *mypolystart + iy) = iptr[1];
3514
3515 mypolystart++;
3516 iptr += 2;
3517
3518 }
3519
3520 }
3521
3522
3523 #if ssrpi_kill_py
3524
3525
3526 /* Make a copy of the object matrix */
3527
3528 CopyMatrix(&Global_ODB_Ptr->ObMat, &m);
3529
3530
3531
3532 /* Combine it with the view matrix */
3533
3534 MatrixMultiply(&Global_VDB_Ptr->VDB_SpriteMat, &m, &m);
3535
3536 /* Extract the Euler Angles */
3537 MatrixToEuler(&m, &e);
3538
3539 #if 0
3540 textprint("X: %d\n", e.EulerX);
3541 textprint("Y: %d\n", e.EulerY);
3542 textprint("Z: %d\n", e.EulerZ);
3543 #endif
3544
3545
3546 /* Knock out the pitch and yaw */
3547
3548 /* KJL 17:23:22 01/09/97 - If the sprite is turned away from you, flip along the
3549 x-axis so that you get the mirror image of the sprite */
3550 if (e.EulerY<1024 || e.EulerY>3072) flipX = 1;
3551 e.EulerY=0;
3552 e.EulerX=0;
3553
3554
3555 /* Turn it back into a matrix */
3556 CreateEulerMatrix(&e, &m);
3557 TransposeMatrixCH(&m);
3558
3559 #else /* ssrpi_kill_py */
3560
3561
3562 MatrixMultiply(&Global_VDB_Ptr->VDB_SpriteMat, &Global_ODB_Ptr->ObMat, &m);
3563
3564
3565 #endif /* ssrpi_kill_py */
3566
3567
3568 for(numitems = shapeinstrptr->sh_numitems; numitems!=0; numitems--) {
3569
3570 x = shapeitemptr[ix];
3571 y = shapeitemptr[iy];
3572 z = shapeitemptr[iz];
3573
3574 rotptsptr->vx = MUL_FIXED(m.mat11, x);
3575 rotptsptr->vx += MUL_FIXED(m.mat21, y);
3576 rotptsptr->vx += MUL_FIXED(m.mat31, z);
3577 #if ssrpi_kill_py
3578 if (flipX) rotptsptr->vx = - rotptsptr->vx;
3579 #endif
3580 rotptsptr->vx += Global_ODB_Ptr->ObView.vx;
3581
3582 rotptsptr->vy = MUL_FIXED(m.mat12, x);
3583 rotptsptr->vy += MUL_FIXED(m.mat22, y);
3584 rotptsptr->vy += MUL_FIXED(m.mat32, z);
3585 rotptsptr->vy += Global_ODB_Ptr->ObView.vy;
3586
3587 rotptsptr->vz = MUL_FIXED(m.mat13, x);
3588 rotptsptr->vz += MUL_FIXED(m.mat23, y);
3589 rotptsptr->vz += MUL_FIXED(m.mat33, z);
3590 rotptsptr->vz += Global_ODB_Ptr->ObView.vz;
3591
3592 shapeitemptr += vsize;
3593 rotptsptr++;
3594
3595 }
3596
3597 }
3598
3599
3600
3601
3602 #else /* UseKevinsModifiedSSRPI */
3603
3604
3605
3606
3607 #define ssrpi_kill_py No
3608
ShapeSpriteRPointsInstr(SHAPEINSTR * shapeinstrptr)3609 void ShapeSpriteRPointsInstr(SHAPEINSTR *shapeinstrptr)
3610
3611 {
3612
3613 int **shapeitemarrayptr = shapeinstrptr->sh_instr_data;
3614 int *shapeitemptr = *shapeitemarrayptr;
3615 VECTORCH *rotptsptr = RotatedPts;
3616 int numitems;
3617 int x,y;
3618 VECTORCH vectx,vecty;
3619 #if ssrpi_kill_py
3620 MATRIXCH m2;
3621 EULER e;
3622 #endif
3623
3624
3625 /*
3626
3627 Sprite Resizing
3628
3629 If this shape is a sprite and is using sprite resizing, there will be a transformed
3630 copy of the polygon points array (XY only) to copy back to the shape.
3631
3632 WARNING!
3633
3634 This function and data structure ASSUME that the sprite shape is using an item array,
3635 that there is just the one item, and that the world and UV space coordinates are in the
3636 form of "TL, BL, BR, TR". It also assumes that the sprite polygon is in the XY plane.
3637
3638 If ANY of these is not true for your sprite, DON'T attempt to use resizing!
3639
3640 */
3641
3642 if(Global_ShapeHeaderPtr->shapeflags & ShapeFlag_Sprite &&
3643 Global_ShapeHeaderPtr->shapeflags & ShapeFlag_SpriteResizing) {
3644
3645 int *ShapePoints;
3646 int **item_array_ptr;
3647 int *item_ptr;
3648 POLYHEADER *pheader;
3649 int *mypolystart;
3650 int texture_defn_index;
3651 int *texture_defn_ptr;
3652 TXANIMHEADER **txah_ptr;
3653 TXANIMHEADER *txah;
3654 TXANIMFRAME *txaf;
3655 TXANIMFRAME *txaf0;
3656 int CurrentFrame, sequence;
3657 int *iptr;
3658
3659 ShapePoints = *(Global_ShapeHeaderPtr->points);
3660
3661 /* Item */
3662
3663 item_array_ptr = Global_ShapeHeaderPtr->items; /* Assume item array */
3664 item_ptr = item_array_ptr[0]; /* Assume only one polygon */
3665 pheader = (POLYHEADER *) item_ptr;
3666
3667 /* Texture Animation */
3668
3669 texture_defn_index = (pheader->PolyColour >> TxDefn);
3670 texture_defn_ptr = Global_ShapeTextures[texture_defn_index];
3671
3672 sequence = *texture_defn_ptr++;
3673
3674 txah_ptr = (TXANIMHEADER **) texture_defn_ptr;
3675 txah = txah_ptr[sequence];
3676 txaf = txah->txa_framedata;
3677
3678 /* Because the current frame can be set from outside, clamp it first */
3679
3680 if(txah->txa_currentframe < 0)
3681 txah->txa_currentframe = 0;
3682 if(txah->txa_currentframe >= txah->txa_maxframe)
3683 txah->txa_currentframe = txah->txa_maxframe - 1;
3684
3685 CurrentFrame = txah->txa_currentframe >> 16;
3686
3687 txaf0 = &txaf[CurrentFrame];
3688
3689
3690 /* UV array */
3691
3692 if(Global_ShapeHeaderPtr->shapeflags & ShapeFlag_Sprite) {
3693
3694 int **uvarrayptr = (int **) txaf0->txf_uvdata;
3695 iptr = uvarrayptr[GetMVSIndex(txah, <oVMat_Euler)];
3696
3697 }
3698
3699 else {
3700
3701 iptr = txaf0->txf_uvdata;
3702
3703 }
3704
3705 iptr += (txaf0->txf_numuvs * 2);
3706
3707
3708 /* Redefine the Shape Points */
3709
3710 mypolystart = &pheader->Poly1stPt;
3711
3712 while(*mypolystart != Term) {
3713
3714 /*textprint("copying point %d\n", *mypolystart / vsize);*/
3715
3716 ((VECTORCH *)ShapePoints)[*mypolystart].vx = iptr[0];
3717 ((VECTORCH *)ShapePoints)[*mypolystart].vy = iptr[1];
3718
3719 /*textprint("x, y = %d, %d\n", iptr[0], iptr[1]);*/
3720
3721 mypolystart++;
3722 iptr += 2;
3723
3724 }
3725
3726 }
3727
3728 //project the object's y vector onto the screen.
3729 //then rotate the sprite's points according to the vector's orintation
3730 //relative to the screen's y vector.
3731 vecty=*(VECTORCH*)&Global_ODB_Ptr->ObMat.mat21;
3732
3733 RotateVector(&vecty,&Global_VDB_Ptr->VDB_Mat);
3734 if(Global_VDB_Ptr->VDB_ProjX!=Global_VDB_Ptr->VDB_ProjY)
3735 {
3736 vecty.vx=MUL_FIXED(vecty.vx,Global_VDB_Ptr->VDB_ProjX);
3737 vecty.vy=MUL_FIXED(vecty.vy,Global_VDB_Ptr->VDB_ProjY);
3738 }
3739 vecty.vz=0;
3740 if(!vecty.vx && !vecty.vy)vecty.vy=ONE_FIXED;
3741 Normalise(&vecty);
3742 vectx.vx=-vecty.vy;
3743 vectx.vy=vecty.vx;
3744 vectx.vz=0;
3745
3746 for(numitems = shapeinstrptr->sh_numitems; numitems!=0; numitems--) {
3747
3748 x = -shapeitemptr[ix];
3749 y = shapeitemptr[iy];
3750
3751 rotptsptr->vx = MUL_FIXED(vectx.vx, x);
3752 rotptsptr->vx += MUL_FIXED(vectx.vy, y);
3753 rotptsptr->vx += Global_ODB_Ptr->ObView.vx;
3754
3755 rotptsptr->vy = MUL_FIXED(vecty.vx, x);
3756 rotptsptr->vy += MUL_FIXED(vecty.vy, y);
3757 rotptsptr->vy += Global_ODB_Ptr->ObView.vy;
3758
3759 rotptsptr->vz = Global_ODB_Ptr->ObView.vz;
3760
3761 shapeitemptr += vsize;
3762 rotptsptr++;
3763
3764 }
3765
3766
3767 }
3768
3769
3770
3771 #endif /* UseKevinsModifiedSSRPI */
3772
GetMVSIndex(TXANIMHEADER * txah,EULER * e)3773 int GetMVSIndex(TXANIMHEADER
3774 *txah, EULER* e )
3775 {
3776 int EulerXIndex, EulerYIndex;
3777 int theta,phi; //angles in spherical polar coordinates
3778 //phi goes from 0 (top) to deg180 (bottom)
3779 VECTORCH v;
3780
3781 MakeVectorLocal(&Global_ODB_Ptr->ObWorld,&v,&Global_VDB_Ptr->VDB_World,&Global_ODB_Ptr->ObMat);
3782 Normalise(&v);
3783 phi=-ArcSin(v.vy);
3784 phi+=deg90;
3785 phi&=wrap360;
3786 if(phi==deg180)phi--;
3787 if(!v.vx && !v.vz)
3788 {
3789 theta=0;
3790 }
3791 else
3792 {
3793 v.vy=0;
3794 Normalise(&v);
3795 if(v.vz > Cosine45 || -v.vz>Cosine45) {
3796
3797 theta = ArcSin(-v.vx);
3798
3799 if(v.vz < 0) {
3800 theta &= wrap360;
3801 }
3802 else
3803 {
3804 theta+=deg180;
3805 theta =-theta;
3806 theta &= wrap360;
3807 }
3808 }
3809
3810 else {
3811
3812 theta = ArcCos(v.vz);
3813
3814 if(v.vx < 0) {
3815 theta = -theta;
3816 }
3817 theta+=deg180;
3818 theta &= wrap360;
3819
3820 }
3821 }
3822
3823 EulerYIndex = theta;
3824 EulerYIndex >>= txah->txa_euleryshift;
3825
3826
3827 EulerYIndex <<= (11 - txah->txa_eulerxshift);
3828
3829 EulerXIndex = phi;
3830 EulerXIndex >>= txah->txa_eulerxshift;
3831
3832 GLOBALASSERT((EulerXIndex+EulerYIndex)<txah->txa_num_mvs_images);
3833
3834 return (EulerXIndex + EulerYIndex);
3835
3836 }
3837
3838
AddShape(DISPLAYBLOCK * dptr,VIEWDESCRIPTORBLOCK * VDB_Ptr)3839 void AddShape(DISPLAYBLOCK *dptr, VIEWDESCRIPTORBLOCK *VDB_Ptr)
3840 {
3841 SHAPEHEADER *shapeheaderptr;
3842
3843 if (!dptr->ObShape && dptr->SfxPtr)
3844 {
3845 // DrawSfxObject(dptr);
3846 return;
3847 }
3848 /* KJL 12:42:38 18/05/98 - check to see if object is on fire */
3849 if (dptr->ObStrategyBlock)
3850 {
3851 if(dptr->ObStrategyBlock->SBDamageBlock.IsOnFire)
3852 {
3853 dptr->SpecialFXFlags |= SFXFLAG_ONFIRE;
3854 }
3855 else
3856 {
3857 dptr->SpecialFXFlags &= ~SFXFLAG_ONFIRE;
3858 }
3859
3860 }
3861
3862 /* is object a morphing one? */
3863 if(dptr->ObMorphCtrl)
3864 {
3865 LOCALASSERT(dptr->ObMorphCtrl->ObMorphHeader);
3866
3867 /* SBF - commented out */
3868 /* if(dptr->ObMorphCtrl->ObMorphHeader) */
3869 {
3870 GetMorphDisplay(&MorphDisplay, dptr);
3871 dptr->ObShape = MorphDisplay.md_shape1;
3872 dptr->ObShapeData = MorphDisplay.md_sptr1;
3873 shapeheaderptr = MorphDisplay.md_sptr1;
3874 }
3875 }
3876 else
3877 {
3878 shapeheaderptr = GetShapeData(dptr->ObShape);
3879
3880 /* It is important to pass this SHAPEHEADER* on to the display block */
3881 dptr->ObShapeData = shapeheaderptr;
3882
3883 // I've put this inside the else so that it does
3884 // not conflict with morphing !!!
3885 // make sure dptr->ObShapeData is up to date before
3886 // doing CopyAnimationFrameToShape
3887
3888 if (dptr->ShapeAnimControlBlock)
3889 {
3890 if (!(dptr->ShapeAnimControlBlock->current.empty))
3891 {
3892 CopyAnimationFrameToShape (&dptr->ShapeAnimControlBlock->current, dptr);
3893 }
3894 }
3895 }
3896
3897
3898 ChooseLightingModel(dptr);
3899 /* hierarchical object? */
3900 #if 0
3901 if (dptr->HModelControlBlock && !dptr->ObStrategyBlock)
3902 {
3903 DoHModel(dptr->HModelControlBlock,dptr);
3904 return;
3905 }
3906 #endif
3907
3908
3909
3910 /* Texture Animation Control */
3911
3912 if(dptr->ObTxAnimCtrlBlks) ControlTextureAnimation(dptr);
3913
3914 /* Global Variables */
3915 Global_VDB_Ptr = VDB_Ptr;
3916 Global_ODB_Ptr = dptr;
3917 Global_ShapeHeaderPtr = shapeheaderptr;
3918
3919 /* Shape Language Specific Setup */
3920 SetupShapePipeline();
3921
3922 /*
3923
3924 Create the Local -> View Matrix
3925
3926 LToVMat = VDB_Mat * ObMat
3927
3928 "Get the points into View Space, then apply the Local Transformation"
3929
3930 */
3931
3932 MatrixMultiply(&VDB_Ptr->VDB_Mat, &dptr->ObMat, <oVMat);
3933 MatrixToEuler(<oVMat, <oVMat_Euler);
3934
3935 /*
3936
3937 Create the World -> Local Matrix
3938
3939 WToLMat = Transposed Local Matrix
3940
3941 */
3942
3943 CopyMatrix(&dptr->ObMat, &WToLMat);
3944 TransposeMatrixCH(&WToLMat);
3945
3946
3947 /*
3948
3949 Transform the View World Location to Local Space
3950
3951 -> Make the View Loc. relative to the Object View Space Centre
3952 -> Rotate this vector using WToLMat
3953
3954 */
3955
3956
3957 MakeVector(&VDB_Ptr->VDB_World, &dptr->ObWorld, &LocalView);
3958 RotateVector(&LocalView, &WToLMat);
3959
3960 #if 0
3961 {
3962 LocalCameraZAxis.vx = - dptr->ObWorld.vx;
3963 LocalCameraZAxis.vy = - dptr->ObWorld.vy;
3964 LocalCameraZAxis.vz = - dptr->ObWorld.vz;
3965
3966 RotateVector(&LocalCameraZAxis, &WToLMat);
3967 }
3968 #endif
3969
3970 NumberOfHeatSources=0;
3971 if (dptr->HModelControlBlock)
3972 {
3973 ObjectCentre = dptr->ObView;
3974
3975 if (dptr->ObStrategyBlock)
3976 {
3977 HierarchicalObjectsLowestYValue = dptr->ObStrategyBlock->DynPtr->ObjectVertices[0].vy;
3978 if (CurrentVisionMode == VISION_MODE_NORMAL && AvP.PlayerType==I_Alien)
3979 {
3980 DoAlienEnergyView(dptr);
3981 }
3982 /*
3983 else if (CurrentVisionMode == VISION_MODE_PRED_SEEALIENS && dptr->ObStrategyBlock->I_SBtype == I_BehaviourAlien)
3984 {
3985 DoAlienEnergyView(dptr);
3986 }
3987 */
3988 }
3989
3990 if (CurrentVisionMode == VISION_MODE_PRED_THERMAL)
3991 {
3992 FindHeatSourcesInHModel(dptr);
3993 }
3994 DoHModel(dptr->HModelControlBlock,dptr);
3995 return;
3996 }
3997 // return;
3998
3999
4000 /* Find out which light sources are in range of of the object */
4001 LightSourcesInRangeOfObject(dptr);
4002
4003 /* Shape Language Execution Shell */
4004 {
4005 SHAPEINSTR *shapeinstrptr = shapeheaderptr->sh_instruction;
4006
4007 /* setup the rotated points array */
4008 switch (shapeinstrptr->sh_instr)
4009 {
4010 default:
4011 case I_ShapePoints:
4012 {
4013 if(Global_ODB_Ptr->ObMorphCtrl)
4014 {
4015 MorphPoints(shapeinstrptr);
4016 }
4017 else
4018 {
4019 TranslateShapeVertices(shapeinstrptr);
4020 }
4021 break;
4022 }
4023 }
4024 }
4025 /* call polygon pipeline */
4026 ShapePipeline(shapeheaderptr);
4027 /* call sfx code */
4028 HandleSfxForObject(dptr);
4029 if (dptr->ObStrategyBlock)
4030 {
4031 if (dptr->ObStrategyBlock->I_SBtype==I_BehaviourInanimateObject)
4032 {
4033 INANIMATEOBJECT_STATUSBLOCK* objStatPtr = (INANIMATEOBJECT_STATUSBLOCK*) dptr->ObStrategyBlock->SBdataptr;
4034 if(objStatPtr->typeId==IOT_FieldCharge)
4035 {
4036
4037 int i;
4038 D3D_DecalSystem_Setup();
4039 for(i=0; i<63; i++)
4040 {
4041 PARTICLE particle;
4042
4043 // SBF - 20080518 - commented out the undefined usage of particle.Position.vz
4044 particle.Position.vy = -280+i-GetCos((CloakingPhase/16*i + i*64/*+particle.Position.vz*/)&4095)/1024;
4045
4046 particle.Position.vx = GetCos((CloakingPhase +i*64+particle.Position.vy)&4095)/512;
4047 particle.Position.vz = GetSin((CloakingPhase +i*64+particle.Position.vy)&4095)/512;
4048 RotateVector(&particle.Position,&dptr->ObMat);
4049 particle.Position.vx += dptr->ObWorld.vx;
4050 particle.Position.vy += dptr->ObWorld.vy;
4051 particle.Position.vz += dptr->ObWorld.vz;
4052
4053 particle.ParticleID=PARTICLE_MUZZLEFLASH;
4054 particle.Colour = 0xff00007f+(FastRandom()&0x7f7f7f);
4055 particle.Size = 40;
4056 RenderParticle(&particle);
4057 }
4058 D3D_DecalSystem_End();
4059
4060 }
4061
4062 }
4063 }
4064 }
DoAlienEnergyView(DISPLAYBLOCK * dispPtr)4065 void DoAlienEnergyView(DISPLAYBLOCK *dispPtr)
4066 {
4067 HMODELCONTROLLER *controllerPtr = dispPtr->HModelControlBlock;
4068 unsigned int colour = MARINES_LIFEFORCE_GLOW_COLOUR;
4069
4070 LOCALASSERT(controllerPtr);
4071
4072
4073
4074 /* KJL 16:36:25 10/02/98 - process model */
4075 {
4076 STRATEGYBLOCK *sbPtr = Global_ODB_Ptr->ObStrategyBlock;
4077 if(sbPtr)
4078 {
4079 switch (sbPtr->I_SBtype)
4080 {
4081 case I_BehaviourAlien:
4082 {
4083 colour = ALIENS_LIFEFORCE_GLOW_COLOUR;
4084 break;
4085 }
4086 case I_BehaviourPredator:
4087 {
4088 colour = PREDATORS_LIFEFORCE_GLOW_COLOUR;
4089 break;
4090 }
4091 case I_BehaviourMarine:
4092 case I_BehaviourSeal:
4093 {
4094 MARINE_STATUS_BLOCK *marineStatusPointer = (MARINE_STATUS_BLOCK *)(sbPtr->SBdataptr);
4095 GLOBALASSERT(marineStatusPointer);
4096
4097 if (marineStatusPointer->Android)
4098 {
4099 return;
4100 }
4101 colour = MARINES_LIFEFORCE_GLOW_COLOUR;
4102 }
4103
4104 case I_BehaviourNetGhost:
4105 {
4106 NETGHOSTDATABLOCK *ghostDataPtr = (NETGHOSTDATABLOCK *)Global_ODB_Ptr->ObStrategyBlock->SBdataptr;
4107
4108 if (ghostDataPtr->type==I_BehaviourAlienPlayer || ghostDataPtr->type==I_BehaviourAlien
4109 || (ghostDataPtr->type==I_BehaviourNetCorpse&&ghostDataPtr->subtype==I_BehaviourAlienPlayer) )
4110 {
4111 colour = ALIENS_LIFEFORCE_GLOW_COLOUR;
4112 }
4113 else if (ghostDataPtr->type==I_BehaviourPredatorPlayer || ghostDataPtr->type==I_BehaviourPredator
4114 || (ghostDataPtr->type==I_BehaviourNetCorpse&&ghostDataPtr->subtype==I_BehaviourPredatorPlayer) )
4115 {
4116 colour = PREDATORS_LIFEFORCE_GLOW_COLOUR;
4117 }
4118
4119 break;
4120 }
4121
4122 case I_BehaviourNetCorpse:
4123 {
4124 NETCORPSEDATABLOCK *corpseDataPtr = (NETCORPSEDATABLOCK *)sbPtr->SBdataptr;
4125
4126 if (corpseDataPtr->Android)
4127 {
4128 return;
4129 }
4130
4131 if (corpseDataPtr->Type==I_BehaviourAlienPlayer || corpseDataPtr->Type==I_BehaviourAlien)
4132 {
4133 colour = ALIENS_LIFEFORCE_GLOW_COLOUR;
4134 }
4135 else if (corpseDataPtr->Type==I_BehaviourPredatorPlayer || corpseDataPtr->Type==I_BehaviourPredator)
4136 {
4137 colour = PREDATORS_LIFEFORCE_GLOW_COLOUR;
4138 }
4139 break;
4140 }
4141 case I_BehaviourHierarchicalFragment:
4142 {
4143 HDEBRIS_BEHAV_BLOCK *debrisDataPtr = (HDEBRIS_BEHAV_BLOCK *)sbPtr->SBdataptr;
4144 if(debrisDataPtr->Type==I_BehaviourAutoGun || debrisDataPtr->Android)
4145 {
4146 return;
4147 }
4148 else if(debrisDataPtr->Type==I_BehaviourAlien)
4149 {
4150 colour = ALIENS_LIFEFORCE_GLOW_COLOUR;
4151 }
4152 else if (debrisDataPtr->Type==I_BehaviourPredator)
4153 {
4154 colour = PREDATORS_LIFEFORCE_GLOW_COLOUR;
4155 }
4156 else if ((debrisDataPtr->Type==I_BehaviourMarine)||(debrisDataPtr->Type==I_BehaviourSeal))
4157 {
4158 colour = MARINES_LIFEFORCE_GLOW_COLOUR;
4159 }
4160 else return;
4161 break;
4162 }
4163
4164 case I_BehaviourAutoGun:
4165 {
4166 /* KJL 19:31:53 25/01/99 - organics only, please */
4167 return;
4168 break;
4169 }
4170 default:
4171 break;
4172 }
4173 }
4174 }
4175 if( (Global_ODB_Ptr->SpecialFXFlags & SFXFLAG_MELTINGINTOGROUND)
4176 &&(Global_ODB_Ptr->ObFlags2 < ONE_FIXED) )
4177 {
4178 unsigned int alpha = MUL_FIXED(Global_ODB_Ptr->ObFlags2,colour >> 24);
4179 colour = (colour&0xffffff)+(alpha<<24);
4180 }
4181
4182 /* KJL 16:36:12 10/02/98 - check positions are up to date */
4183 ProveHModel(controllerPtr,dispPtr);
4184
4185 D3D_DecalSystem_Setup();
4186
4187 FindAlienEnergySource_Recursion(controllerPtr,controllerPtr->section_data,colour);
4188
4189 D3D_DecalSystem_End();
4190 }
4191
FindAlienEnergySource_Recursion(HMODELCONTROLLER * controllerPtr,SECTION_DATA * sectionDataPtr,unsigned int colour)4192 static void FindAlienEnergySource_Recursion(HMODELCONTROLLER *controllerPtr, SECTION_DATA *sectionDataPtr, unsigned int colour)
4193 {
4194 /* KJL 16:29:40 10/02/98 - Recurse through hmodel */
4195 if ((sectionDataPtr->First_Child!=NULL)&&(!(sectionDataPtr->flags§ion_data_terminate_here)))
4196 {
4197 SECTION_DATA *childSectionPtr = sectionDataPtr->First_Child;
4198
4199 while (childSectionPtr!=NULL)
4200 {
4201 LOCALASSERT(childSectionPtr->My_Parent==sectionDataPtr);
4202
4203 FindAlienEnergySource_Recursion(controllerPtr,childSectionPtr,colour);
4204 childSectionPtr=childSectionPtr->Next_Sibling;
4205 }
4206 }
4207 if(sectionDataPtr->Shape && sectionDataPtr->Shape->shaperadius>LocalDetailLevels.AlienEnergyViewThreshold)
4208 {
4209 PARTICLE particle;
4210
4211 particle.Position = sectionDataPtr->World_Offset;
4212 particle.ParticleID=PARTICLE_MUZZLEFLASH;
4213 particle.Colour = colour;//0x208080ff;
4214 // particle.Colour = 0x20ff8080;
4215 // particle.Size = sectionDataPtr->Shape->shaperadius*3;
4216 // particle.Colour = 0x20ffffff;
4217 particle.Size = sectionDataPtr->Shape->shaperadius*2;
4218 RenderParticle(&particle);
4219 }
4220 }
4221
AddHierarchicalShape(DISPLAYBLOCK * dptr,VIEWDESCRIPTORBLOCK * VDB_Ptr)4222 void AddHierarchicalShape(DISPLAYBLOCK *dptr, VIEWDESCRIPTORBLOCK *VDB_Ptr)
4223 {
4224
4225 SHAPEHEADER *shapeheaderptr;
4226 SHAPEINSTR *shapeinstrptr;
4227
4228 GLOBALASSERT(!dptr->HModelControlBlock);
4229 if(!ObjectWithinFrustrum(dptr)) return;
4230
4231
4232 #if 0
4233 shapeheaderptr = GetShapeData(dptr->ObShape);
4234
4235 /* It is important to pass this SHAPEHEADER* on to the display block */
4236
4237 dptr->ObShapeData = shapeheaderptr;
4238 #else
4239 shapeheaderptr = dptr->ObShapeData;
4240 #endif
4241
4242
4243 /* Texture Animation Control */
4244 if(dptr->ObTxAnimCtrlBlks) ControlTextureAnimation(dptr);
4245
4246 /* Global Variables */
4247 Global_VDB_Ptr = VDB_Ptr;
4248 Global_ODB_Ptr = dptr;
4249 Global_ShapeHeaderPtr = shapeheaderptr;
4250
4251 // if((Global_ODB_Ptr->ObStrategyBlock)&&(Global_ODB_Ptr->ObStrategyBlock->I_SBtype == I_BehaviourAlien))
4252 // textprint("hier alien part\n");
4253
4254 /* Shape Language Specific Setup */
4255 SetupShapePipeline();
4256
4257 /*
4258
4259 Create the Local -> View Matrix
4260
4261 LToVMat = VDB_Mat * ObMat
4262
4263 "Get the points into View Space, then apply the Local Transformation"
4264
4265 */
4266
4267 MatrixMultiply(&VDB_Ptr->VDB_Mat, &dptr->ObMat, <oVMat);
4268 MatrixToEuler(<oVMat, <oVMat_Euler);
4269
4270 /*
4271
4272 Create the World -> Local Matrix
4273
4274 WToLMat = Transposed Local Matrix
4275
4276 */
4277
4278 CopyMatrix(&dptr->ObMat, &WToLMat);
4279 TransposeMatrixCH(&WToLMat);
4280
4281
4282 /*
4283
4284 Transform the View World Location to Local Space
4285
4286 -> Make the View Loc. relative to the Object View Space Centre
4287 -> Rotate this vector using WToLMat
4288
4289 */
4290
4291
4292 MakeVector(&VDB_Ptr->VDB_World, &dptr->ObWorld, &LocalView);
4293 RotateVector(&LocalView, &WToLMat);
4294
4295 if (!(PIPECLEANER_CHEATMODE||BALLSOFFIRE_CHEATMODE) || !dptr->ObStrategyBlock)
4296 {
4297 /* Find out which light sources are in range of of the object */
4298 LightSourcesInRangeOfObject(dptr);
4299
4300 /* Shape Language Execution Shell */
4301 shapeinstrptr = shapeheaderptr->sh_instruction;
4302
4303 /* setup the rotated points array */
4304 if( (dptr->SpecialFXFlags & SFXFLAG_MELTINGINTOGROUND)
4305 &&(dptr->ObFlags2 <= ONE_FIXED) )
4306 {
4307 SquishPoints(shapeinstrptr);
4308 }
4309 else
4310 {
4311 TranslateShapeVertices(shapeinstrptr);
4312 }
4313
4314 /* call polygon pipeline */
4315 ShapePipeline(shapeheaderptr);
4316 }
4317
4318 if (BALLSOFFIRE_CHEATMODE && dptr->ObStrategyBlock)
4319 {
4320 HandleObjectOnFire(dptr);
4321 }
4322
4323 /* call sfx code */
4324 HandleSfxForObject(dptr);
4325
4326 }
4327
4328
4329 float ViewMatrix[12];
4330 float ObjectViewMatrix[12];
4331 float Source[3];
4332 float Dest[3];
4333
TranslationSetup(void)4334 extern void TranslationSetup(void)
4335 {
4336 VECTORCH v = Global_VDB_Ptr->VDB_World;
4337 extern int PredatorVisionChangeCounter;
4338 float p = PredatorVisionChangeCounter/65536.0f;
4339 float o = 1.0f;
4340 p = 1.0f+p;
4341
4342 if (NAUSEA_CHEATMODE)
4343 {
4344 p = (GetSin((CloakingPhase/3)&4095))/65536.0f;
4345 p = 1.0f + p*p;
4346
4347 o = (GetCos((CloakingPhase/5)&4095))/65536.0f;
4348 o = 1.0f + o*o;
4349 }
4350
4351 #if 1
4352 ViewMatrix[0+0*4] = (float)(Global_VDB_Ptr->VDB_Mat.mat11)/65536.0f*o;
4353 ViewMatrix[1+0*4] = (float)(Global_VDB_Ptr->VDB_Mat.mat21)/65536.0f*o;
4354 ViewMatrix[2+0*4] = (float)(Global_VDB_Ptr->VDB_Mat.mat31)/65536.0f*o;
4355 #else
4356 ViewMatrix[0+0*4] = (float)(Global_VDB_Ptr->VDB_Mat.mat11)/65536.0f;
4357 ViewMatrix[1+0*4] = (float)(Global_VDB_Ptr->VDB_Mat.mat21)/65536.0f;
4358 ViewMatrix[2+0*4] = (float)(Global_VDB_Ptr->VDB_Mat.mat31)/65536.0f;
4359 #endif
4360
4361 #if 1
4362 ViewMatrix[0+1*4] = (float)(Global_VDB_Ptr->VDB_Mat.mat12)*4.0f/(65536.0f*3.0f)*p;
4363 ViewMatrix[1+1*4] = (float)(Global_VDB_Ptr->VDB_Mat.mat22)*4.0f/(65536.0f*3.0f)*p;
4364 ViewMatrix[2+1*4] = (float)(Global_VDB_Ptr->VDB_Mat.mat32)*4.0f/(65536.0f*3.0f)*p;
4365 #else
4366 ViewMatrix[0+1*4] = (float)(Global_VDB_Ptr->VDB_Mat.mat12)/(65536.0f);
4367 ViewMatrix[1+1*4] = (float)(Global_VDB_Ptr->VDB_Mat.mat22)/(65536.0f);
4368 ViewMatrix[2+1*4] = (float)(Global_VDB_Ptr->VDB_Mat.mat32)/(65536.0f);
4369 #endif
4370 ViewMatrix[0+2*4] = (float)(Global_VDB_Ptr->VDB_Mat.mat13)/65536.0f*CameraZoomScale;
4371 ViewMatrix[1+2*4] = (float)(Global_VDB_Ptr->VDB_Mat.mat23)/65536.0f*CameraZoomScale;
4372 ViewMatrix[2+2*4] = (float)(Global_VDB_Ptr->VDB_Mat.mat33)/65536.0f*CameraZoomScale;
4373
4374 RotateVector(&v,&Global_VDB_Ptr->VDB_Mat);
4375
4376 ViewMatrix[3+0*4] = ((float)-v.vx)*o;
4377 ViewMatrix[3+1*4] = ((float)-v.vy)*4.0f/3.0f*p;
4378 ViewMatrix[3+2*4] = ((float)-v.vz)*CameraZoomScale;
4379
4380 if (MIRROR_CHEATMODE)
4381 {
4382 ViewMatrix[0+0*4] = -ViewMatrix[0+0*4];
4383 ViewMatrix[1+0*4] = -ViewMatrix[1+0*4];
4384 ViewMatrix[2+0*4] = -ViewMatrix[2+0*4];
4385
4386 ViewMatrix[3+0*4] = -ViewMatrix[3+0*4];
4387 }
4388 }
4389
4390
4391 #if defined(_MSC_VER) && 0
TranslatePoint(int * source,int * dest,int * matrix)4392 void TranslatePoint(int *source, int *dest, int *matrix)
4393 {
4394 __asm
4395 {
4396 mov esi,source
4397 mov ebx,dest
4398 mov edi,matrix
4399 fld DWORD PTR [esi]
4400 fmul DWORD PTR [edi]
4401 fld DWORD PTR [esi+4]
4402 fmul DWORD PTR [edi+4]
4403 fld DWORD PTR [esi+8]
4404 fmul DWORD PTR [edi+8]
4405 fxch st(1)
4406 faddp st(2),st
4407 fld DWORD PTR [esi]
4408 fmul DWORD PTR [edi+16]
4409 fxch st(1)
4410 faddp st(2),st
4411 fld DWORD PTR [esi+4]
4412 fmul DWORD PTR [edi+20]
4413 fld DWORD PTR [esi+8]
4414 fmul DWORD PTR [edi+24]
4415 fxch st(1)
4416 faddp st(2),st
4417 fld DWORD PTR [esi]
4418 fmul DWORD PTR [edi+32]
4419 fxch st(1)
4420 faddp st(2),st
4421 fld DWORD PTR [esi+4]
4422 fmul DWORD PTR [edi+36]
4423 fld DWORD PTR [esi+8]
4424 fmul DWORD PTR [edi+40]
4425 fxch st(1)
4426 faddp st(2),st
4427 fxch st(3)
4428 fadd DWORD PTR [edi+12]
4429 fxch st(1)
4430 faddp st(3),st
4431 fxch st(1)
4432 fadd DWORD PTR [edi+28]
4433 fxch st(2)
4434 fadd DWORD PTR [edi+44]
4435 fxch st(1)
4436 fstp DWORD PTR [ebx]
4437 fxch st(1)
4438 fstp DWORD PTR [ebx+4]
4439 fstp DWORD PTR [ebx+8]
4440 }
4441 }
4442 #else
TranslatePoint(const float * source,float * dest,const float * matrix)4443 static void TranslatePoint(const float *source, float *dest, const float *matrix)
4444 {
4445 dest[0] = matrix[ 0] * source[0] + matrix[ 1] * source[1] + matrix[ 2] * source[2] + matrix[ 3];
4446 dest[1] = matrix[ 4] * source[0] + matrix[ 5] * source[1] + matrix[ 6] * source[2] + matrix[ 7];
4447 dest[2] = matrix[ 8] * source[0] + matrix[ 9] * source[1] + matrix[10] * source[2] + matrix[11];
4448 }
4449 #endif
4450
TranslatePointIntoViewspace(VECTORCH * pointPtr)4451 void TranslatePointIntoViewspace(VECTORCH *pointPtr)
4452 {
4453 Source[0] = pointPtr->vx;
4454 Source[1] = pointPtr->vy;
4455 Source[2] = pointPtr->vz;
4456
4457 TranslatePoint(Source, Dest, ViewMatrix);
4458
4459 f2i(pointPtr->vx,Dest[0]);
4460 f2i(pointPtr->vy,Dest[1]);
4461 f2i(pointPtr->vz,Dest[2]);
4462 }
4463
SquishPoints(SHAPEINSTR * shapeinstrptr)4464 void SquishPoints(SHAPEINSTR *shapeinstrptr)
4465 {
4466 int **shapeitemarrayptr = shapeinstrptr->sh_instr_data;
4467 VECTORCH *shapePts = (VECTORCH*)*shapeitemarrayptr;
4468 {
4469 int i;
4470 int scale = Global_ODB_Ptr->ObFlags2;
4471
4472 for (i=0; i<Global_ShapeHeaderPtr->numpoints; i++)
4473 {
4474 VECTORCH point = shapePts[i];
4475
4476 RotateVector(&point,&Global_ODB_Ptr->ObMat);
4477
4478 point.vx = MUL_FIXED(point.vx,ONE_FIXED*3/2 - scale/2);
4479 point.vx += Global_ODB_Ptr->ObWorld.vx;
4480
4481 point.vz = MUL_FIXED(point.vz,ONE_FIXED*3/2 - scale/2);
4482 point.vz += Global_ODB_Ptr->ObWorld.vz;
4483
4484 point.vy += Global_ODB_Ptr->ObWorld.vy;
4485 point.vy = HierarchicalObjectsLowestYValue + MUL_FIXED(point.vy-HierarchicalObjectsLowestYValue, scale);
4486
4487 Source[0] = point.vx;
4488 Source[1] = point.vy;
4489 Source[2] = point.vz;
4490
4491 TranslatePoint(Source, Dest, ViewMatrix);
4492
4493 f2i(RotatedPts[i].vx,Dest[0]);
4494 f2i(RotatedPts[i].vy,Dest[1]);
4495 f2i(RotatedPts[i].vz,Dest[2]);
4496 }
4497 }
4498 }
4499
MorphPoints(SHAPEINSTR * shapeinstrptr)4500 void MorphPoints(SHAPEINSTR *shapeinstrptr)
4501 {
4502 VECTORCH *srcPtr;
4503 {
4504 SHAPEHEADER *shape1Ptr;
4505 VECTORCH *shape1PointsPtr;
4506 VECTORCH *shape2PointsPtr;
4507
4508 /* Set up the morph data */
4509 GetMorphDisplay(&MorphDisplay, Global_ODB_Ptr);
4510
4511 shape1Ptr = MorphDisplay.md_sptr1;
4512
4513 if(MorphDisplay.md_lerp == 0x0000)
4514 {
4515
4516 srcPtr = (VECTORCH *)*shape1Ptr->points;
4517 }
4518 else if(MorphDisplay.md_lerp == 0xffff)
4519 {
4520 SHAPEHEADER *shape2Ptr;
4521 shape2Ptr = MorphDisplay.md_sptr2;
4522
4523 srcPtr = (VECTORCH *)*shape2Ptr->points;
4524 Global_ShapePoints = *(shape2Ptr->points);
4525
4526 }
4527 else
4528 {
4529 SHAPEHEADER *shape2Ptr;
4530 shape2Ptr = MorphDisplay.md_sptr2;
4531
4532 shape1PointsPtr = (VECTORCH *)(*shape1Ptr->points);
4533 shape2PointsPtr = (VECTORCH *)(*shape2Ptr->points);
4534
4535 {
4536 int numberOfPoints = shape1Ptr->numpoints;
4537 VECTORCH *morphedPointsPtr = (VECTORCH *) MorphedPts;
4538
4539 while(numberOfPoints--)
4540 {
4541 VECTORCH vertex1 = *shape1PointsPtr;
4542 VECTORCH vertex2 = *shape2PointsPtr;
4543
4544 if( (vertex1.vx == vertex2.vx && vertex1.vy == vertex2.vy && vertex1.vz == vertex2.vz) )
4545 {
4546 *morphedPointsPtr = vertex1;
4547 }
4548 else
4549 {
4550 /* KJL 15:27:20 05/22/97 - I've changed this to speed things up, If a vertex
4551 component has a magnitude greater than 32768 things will go wrong. */
4552 morphedPointsPtr->vx = vertex1.vx + (((vertex2.vx-vertex1.vx)*MorphDisplay.md_lerp)>>16);
4553 morphedPointsPtr->vy = vertex1.vy + (((vertex2.vy-vertex1.vy)*MorphDisplay.md_lerp)>>16);
4554 morphedPointsPtr->vz = vertex1.vz + (((vertex2.vz-vertex1.vz)*MorphDisplay.md_lerp)>>16);
4555 }
4556
4557 shape1PointsPtr++;
4558 shape2PointsPtr++;
4559 morphedPointsPtr++;
4560 }
4561 }
4562
4563 Global_ShapePoints = (int*)MorphedPts;
4564 srcPtr = (VECTORCH *)MorphedPts;
4565 }
4566 }
4567 {
4568 VECTORCH *destPtr = RotatedPts;
4569 int i;
4570 for(i = shapeinstrptr->sh_numitems; i!=0; i--)
4571 {
4572 Source[0] = srcPtr->vx+Global_ODB_Ptr->ObWorld.vx;
4573 Source[1] = srcPtr->vy+Global_ODB_Ptr->ObWorld.vy;
4574 Source[2] = srcPtr->vz+Global_ODB_Ptr->ObWorld.vz;
4575
4576 TranslatePoint(Source, Dest, ViewMatrix);
4577
4578 f2i(destPtr->vx,Dest[0]);
4579 f2i(destPtr->vy,Dest[1]);
4580 f2i(destPtr->vz,Dest[2]);
4581 srcPtr++;
4582 destPtr++;
4583 }
4584 }
4585
4586 }
4587
TranslateShapeVertices(SHAPEINSTR * shapeinstrptr)4588 void TranslateShapeVertices(SHAPEINSTR *shapeinstrptr)
4589 {
4590 VECTORCH *destPtr = RotatedPts;
4591 int **shapeitemarrayptr;
4592 VECTORCH *srcPtr;
4593 int i;
4594 // MNormalise(<oVMat);
4595 shapeitemarrayptr = shapeinstrptr->sh_instr_data;
4596 srcPtr = (VECTORCH*)*shapeitemarrayptr;
4597 if (Global_ODB_Ptr->ObFlags & ObFlag_ArbRot)
4598 {
4599 for(i = shapeinstrptr->sh_numitems; i!=0; i--)
4600 {
4601 destPtr->vx = (srcPtr->vx+Global_ODB_Ptr->ObView.vx);
4602 destPtr->vy = ((srcPtr->vy+Global_ODB_Ptr->ObView.vy)*4)/3;
4603 destPtr->vz = (srcPtr->vz+Global_ODB_Ptr->ObView.vz);
4604
4605 srcPtr++;
4606 destPtr++;
4607
4608 }
4609 }
4610 else
4611 {
4612 ObjectViewMatrix[0+0*4] = (float)(Global_ODB_Ptr->ObMat.mat11)/65536.0f;
4613 ObjectViewMatrix[1+0*4] = (float)(Global_ODB_Ptr->ObMat.mat21)/65536.0f;
4614 ObjectViewMatrix[2+0*4] = (float)(Global_ODB_Ptr->ObMat.mat31)/65536.0f;
4615
4616 ObjectViewMatrix[0+1*4] = (float)(Global_ODB_Ptr->ObMat.mat12)/(65536.0f);
4617 ObjectViewMatrix[1+1*4] = (float)(Global_ODB_Ptr->ObMat.mat22)/(65536.0f);
4618 ObjectViewMatrix[2+1*4] = (float)(Global_ODB_Ptr->ObMat.mat32)/(65536.0f);
4619
4620 ObjectViewMatrix[0+2*4] = (float)(Global_ODB_Ptr->ObMat.mat13)/65536.0f;
4621 ObjectViewMatrix[1+2*4] = (float)(Global_ODB_Ptr->ObMat.mat23)/65536.0f;
4622 ObjectViewMatrix[2+2*4] = (float)(Global_ODB_Ptr->ObMat.mat33)/65536.0f;
4623
4624 ObjectViewMatrix[3+0*4] = Global_ODB_Ptr->ObWorld.vx;
4625 ObjectViewMatrix[3+1*4] = Global_ODB_Ptr->ObWorld.vy;
4626 ObjectViewMatrix[3+2*4] = Global_ODB_Ptr->ObWorld.vz;
4627 for(i = shapeinstrptr->sh_numitems; i!=0; i--)
4628 {
4629 Source[0] = srcPtr->vx;
4630 Source[1] = srcPtr->vy;
4631 Source[2] = srcPtr->vz;
4632
4633 TranslatePoint(Source, Dest, ObjectViewMatrix);
4634 TranslatePoint(Dest, Source, ViewMatrix);
4635
4636 f2i(destPtr->vx,Source[0]);
4637 f2i(destPtr->vy,Source[1]);
4638 f2i(destPtr->vz,Source[2]);
4639 srcPtr++;
4640 destPtr++;
4641 }
4642 }
4643 }
4644
RenderDecal(DECAL * decalPtr)4645 void RenderDecal(DECAL *decalPtr)
4646 {
4647 /* translate decal into view space */
4648 {
4649 VECTORCH translatedPosition = decalPtr->Vertices[0];
4650 TranslatePointIntoViewspace(&translatedPosition);
4651 VerticesBuffer[0].X = translatedPosition.vx;
4652 VerticesBuffer[0].Y = translatedPosition.vy;
4653 VerticesBuffer[0].Z = translatedPosition.vz;
4654 }
4655 {
4656 VECTORCH translatedPosition = decalPtr->Vertices[1];
4657 TranslatePointIntoViewspace(&translatedPosition);
4658 VerticesBuffer[1].X = translatedPosition.vx;
4659 VerticesBuffer[1].Y = translatedPosition.vy;
4660 VerticesBuffer[1].Z = translatedPosition.vz;
4661 }
4662 {
4663 VECTORCH translatedPosition = decalPtr->Vertices[2];
4664 TranslatePointIntoViewspace(&translatedPosition);
4665 VerticesBuffer[2].X = translatedPosition.vx;
4666 VerticesBuffer[2].Y = translatedPosition.vy;
4667 VerticesBuffer[2].Z = translatedPosition.vz;
4668 }
4669 {
4670 VECTORCH translatedPosition = decalPtr->Vertices[3];
4671 TranslatePointIntoViewspace(&translatedPosition);
4672 VerticesBuffer[3].X = translatedPosition.vx;
4673 VerticesBuffer[3].Y = translatedPosition.vy;
4674 VerticesBuffer[3].Z = translatedPosition.vz;
4675 }
4676 {
4677 int outcode = DecalWithinFrustrum(decalPtr);
4678
4679 if (outcode)
4680 {
4681 switch(decalPtr->DecalID)
4682 {
4683 default:
4684 case DECAL_SCORCHED:
4685 {
4686 DecalPolygon_Construct(decalPtr);
4687
4688 if (outcode!=2)
4689 {
4690 TexturedPolygon_ClipWithZ();
4691 if(RenderPolygon.NumberOfVertices<3) return;
4692 TexturedPolygon_ClipWithNegativeX();
4693 if(RenderPolygon.NumberOfVertices<3) return;
4694 TexturedPolygon_ClipWithPositiveY();
4695 if(RenderPolygon.NumberOfVertices<3) return;
4696 TexturedPolygon_ClipWithNegativeY();
4697 if(RenderPolygon.NumberOfVertices<3) return;
4698 TexturedPolygon_ClipWithPositiveX();
4699 if(RenderPolygon.NumberOfVertices<3) return;
4700 D3D_Decal_Output(decalPtr,RenderPolygon.Vertices);
4701
4702 }
4703 else D3D_Decal_Output(decalPtr,VerticesBuffer);
4704 break;
4705 }
4706 }
4707 }
4708 }
4709 #if MIRRORING_ON
4710 if (MirroringActive) RenderMirroredDecal(decalPtr);
4711 #endif
4712 }
RenderParticle(PARTICLE * particlePtr)4713 void RenderParticle(PARTICLE *particlePtr)
4714 {
4715 // PARTICLE_DESC *particleDescPtr = &ParticleDescription[particlePtr->ParticleID];
4716 int particleSize = particlePtr->Size;
4717
4718 {
4719 VECTORCH translatedPosition = particlePtr->Position;
4720 TranslatePointIntoViewspace(&translatedPosition);
4721 VerticesBuffer[0].X = translatedPosition.vx;
4722 VerticesBuffer[3].X = translatedPosition.vx;
4723 VerticesBuffer[0].Y = translatedPosition.vy;
4724 VerticesBuffer[3].Y = translatedPosition.vy;
4725 VerticesBuffer[0].Z = translatedPosition.vz;
4726 VerticesBuffer[3].Z = translatedPosition.vz;
4727 }
4728
4729 if ((particlePtr->ParticleID == PARTICLE_EXPLOSIONFIRE)
4730 ||(particlePtr->ParticleID == PARTICLE_RICOCHET_SPARK)
4731 ||(particlePtr->ParticleID == PARTICLE_SPARK)
4732 ||(particlePtr->ParticleID == PARTICLE_ORANGE_SPARK)
4733 ||(particlePtr->ParticleID == PARTICLE_ORANGE_PLASMA)
4734 ||(particlePtr->ParticleID == PARTICLE_ALIEN_BLOOD)
4735 ||(particlePtr->ParticleID == PARTICLE_PREDATOR_BLOOD)
4736 ||(particlePtr->ParticleID == PARTICLE_HUMAN_BLOOD)
4737 ||(particlePtr->ParticleID == PARTICLE_WATERFALLSPRAY)
4738 ||(particlePtr->ParticleID == PARTICLE_LASERBEAM)
4739 ||(particlePtr->ParticleID == PARTICLE_PLASMABEAM)
4740 ||(particlePtr->ParticleID == PARTICLE_TRACER)
4741 ||(particlePtr->ParticleID == PARTICLE_PREDPISTOL_FLECHETTE)
4742 ||(particlePtr->ParticleID == PARTICLE_PREDPISTOL_FLECHETTE_NONDAMAGING)
4743 )
4744 {
4745 VECTORCH translatedPosition = particlePtr->Offset;
4746 TranslatePointIntoViewspace(&translatedPosition);
4747 VerticesBuffer[1].X = translatedPosition.vx;
4748 VerticesBuffer[2].X = translatedPosition.vx;
4749 VerticesBuffer[1].Y = translatedPosition.vy;
4750 VerticesBuffer[2].Y = translatedPosition.vy;
4751 VerticesBuffer[1].Z = translatedPosition.vz;
4752 VerticesBuffer[2].Z = translatedPosition.vz;
4753
4754 {
4755 int deltaX = VerticesBuffer[1].X - VerticesBuffer[0].X;
4756 int deltaY = VerticesBuffer[1].Y - VerticesBuffer[0].Y;
4757 int splitY = 0;
4758
4759 if (deltaX>=0)
4760 {
4761 if (deltaY>=0)
4762 {
4763 if (deltaX>deltaY)
4764 {
4765 splitY = 1;
4766 }
4767 }
4768 else if (deltaX>-deltaY)
4769 {
4770 splitY = 1;
4771 }
4772 }
4773 else
4774 {
4775 if (deltaY>=0)
4776 {
4777 if (-deltaX>deltaY)
4778 {
4779 splitY = 1;
4780 }
4781 }
4782 else if (-deltaX>-deltaY)
4783 {
4784 splitY = 1;
4785 }
4786 }
4787 if (splitY)
4788 {
4789 if (deltaX>0)
4790 {
4791 /* 1 & 2 are more +ve in X */
4792 VerticesBuffer[0].X -= particleSize;
4793 VerticesBuffer[0].Y -= MUL_FIXED(particleSize,87381);
4794 VerticesBuffer[1].X += particleSize;
4795 VerticesBuffer[1].Y -= MUL_FIXED(particleSize,87381);
4796 VerticesBuffer[2].X += particleSize;
4797 VerticesBuffer[2].Y += MUL_FIXED(particleSize,87381);
4798 VerticesBuffer[3].X -= particleSize;
4799 VerticesBuffer[3].Y += MUL_FIXED(particleSize,87381);
4800 }
4801 else
4802 {
4803 /* 1 & 2 are more -ve in X */
4804 VerticesBuffer[0].X += particleSize;
4805 VerticesBuffer[0].Y -= MUL_FIXED(particleSize,87381);
4806 VerticesBuffer[1].X -= particleSize;
4807 VerticesBuffer[1].Y -= MUL_FIXED(particleSize,87381);
4808 VerticesBuffer[2].X -= particleSize;
4809 VerticesBuffer[2].Y += MUL_FIXED(particleSize,87381);
4810 VerticesBuffer[3].X += particleSize;
4811 VerticesBuffer[3].Y += MUL_FIXED(particleSize,87381);
4812 }
4813
4814 }
4815 else
4816 {
4817 if (deltaY>0)
4818 {
4819 /* 1 & 2 are more +ve in Y */
4820 VerticesBuffer[0].X -= particleSize;
4821 VerticesBuffer[0].Y -= MUL_FIXED(particleSize,87381);
4822 VerticesBuffer[1].X -= particleSize;
4823 VerticesBuffer[1].Y += MUL_FIXED(particleSize,87381);
4824 VerticesBuffer[2].X += particleSize;
4825 VerticesBuffer[2].Y += MUL_FIXED(particleSize,87381);
4826 VerticesBuffer[3].X += particleSize;
4827 VerticesBuffer[3].Y -= MUL_FIXED(particleSize,87381);
4828 }
4829 else
4830 {
4831 /* 1 & 2 are more -ve in Y */
4832 VerticesBuffer[0].X -= particleSize;
4833 VerticesBuffer[0].Y += MUL_FIXED(particleSize,87381);
4834 VerticesBuffer[1].X -= particleSize;
4835 VerticesBuffer[1].Y -= MUL_FIXED(particleSize,87381);
4836 VerticesBuffer[2].X += particleSize;
4837 VerticesBuffer[2].Y -= MUL_FIXED(particleSize,87381);
4838 VerticesBuffer[3].X += particleSize;
4839 VerticesBuffer[3].Y += MUL_FIXED(particleSize,87381);
4840 }
4841
4842 }
4843 }
4844 }
4845 else
4846 {
4847 VECTOR2D offset[4];
4848 VerticesBuffer[1].X = VerticesBuffer[0].X;
4849 VerticesBuffer[2].X = VerticesBuffer[0].X;
4850 VerticesBuffer[1].Y = VerticesBuffer[0].Y;
4851 VerticesBuffer[2].Y = VerticesBuffer[0].Y;
4852 VerticesBuffer[1].Z = VerticesBuffer[0].Z;
4853 VerticesBuffer[2].Z = VerticesBuffer[0].Z;
4854
4855 offset[0].vx = -particleSize;
4856 offset[0].vy = -particleSize;
4857
4858 offset[1].vx = +particleSize;
4859 offset[1].vy = -particleSize;
4860
4861 offset[2].vx = +particleSize;
4862 offset[2].vy = +particleSize;
4863
4864 offset[3].vx = -particleSize;
4865 offset[3].vy = +particleSize;
4866
4867 if ((particlePtr->ParticleID == PARTICLE_MUZZLEFLASH) )
4868 {
4869 int theta = FastRandom()&4095;
4870 RotateVertex(&offset[0],theta);
4871 RotateVertex(&offset[1],theta);
4872 RotateVertex(&offset[2],theta);
4873 RotateVertex(&offset[3],theta);
4874 }
4875 else if ((particlePtr->ParticleID == PARTICLE_SMOKECLOUD)
4876 ||(particlePtr->ParticleID == PARTICLE_GUNMUZZLE_SMOKE)
4877 ||(particlePtr->ParticleID == PARTICLE_PARGEN_FLAME)
4878 ||(particlePtr->ParticleID == PARTICLE_FLAME))
4879 {
4880 int theta = (particlePtr->Offset.vx+MUL_FIXED(CloakingPhase,particlePtr->Offset.vy))&4095;
4881 RotateVertex(&offset[0],theta);
4882 RotateVertex(&offset[1],theta);
4883 RotateVertex(&offset[2],theta);
4884 RotateVertex(&offset[3],theta);
4885 }
4886 VerticesBuffer[0].X += offset[0].vx;
4887 VerticesBuffer[0].Y += MUL_FIXED(offset[0].vy,87381);
4888
4889 VerticesBuffer[1].X += offset[1].vx;
4890 VerticesBuffer[1].Y += MUL_FIXED(offset[1].vy,87381);
4891
4892 VerticesBuffer[2].X += offset[2].vx;
4893 VerticesBuffer[2].Y += MUL_FIXED(offset[2].vy,87381);
4894
4895 VerticesBuffer[3].X += offset[3].vx;
4896 VerticesBuffer[3].Y += MUL_FIXED(offset[3].vy,87381);
4897
4898 }
4899
4900 {
4901 int outcode = QuadWithinFrustrum();
4902
4903 if (outcode)
4904 {
4905 ParticlePolygon_Construct(particlePtr);
4906
4907 if (outcode!=2)
4908 {
4909 TexturedPolygon_ClipWithZ();
4910 if(RenderPolygon.NumberOfVertices<3) return;
4911 TexturedPolygon_ClipWithNegativeX();
4912 if(RenderPolygon.NumberOfVertices<3) return;
4913 TexturedPolygon_ClipWithPositiveY();
4914 if(RenderPolygon.NumberOfVertices<3) return;
4915 TexturedPolygon_ClipWithNegativeY();
4916 if(RenderPolygon.NumberOfVertices<3) return;
4917 TexturedPolygon_ClipWithPositiveX();
4918 if(RenderPolygon.NumberOfVertices<3) return;
4919 D3D_Particle_Output(particlePtr,RenderPolygon.Vertices);
4920
4921 }
4922 else D3D_Particle_Output(particlePtr,VerticesBuffer);
4923 }
4924 }
4925 }
4926
RenderFlechetteParticle(PARTICLE * particlePtr)4927 extern void RenderFlechetteParticle(PARTICLE *particlePtr)
4928 {
4929 VECTORCH vertices[5];
4930 MATRIXCH mat;
4931
4932 MakeMatrixFromDirection(&particlePtr->Velocity,&mat);
4933
4934 mat.mat11 >>= 12;
4935 mat.mat12 >>= 12;
4936 mat.mat13 >>= 12;
4937 mat.mat21 >>= 12;
4938 mat.mat22 >>= 12;
4939 mat.mat23 >>= 12;
4940 mat.mat31 >>= 9;
4941 mat.mat32 >>= 9;
4942 mat.mat33 >>= 9;
4943
4944
4945 vertices[0].vx = particlePtr->Position.vx-mat.mat31+mat.mat11;
4946 vertices[0].vy = particlePtr->Position.vy-mat.mat32+mat.mat12;
4947 vertices[0].vz = particlePtr->Position.vz-mat.mat33+mat.mat13;
4948
4949 vertices[1].vx = particlePtr->Position.vx-mat.mat31-mat.mat11;
4950 vertices[1].vy = particlePtr->Position.vy-mat.mat32-mat.mat12;
4951 vertices[1].vz = particlePtr->Position.vz-mat.mat33-mat.mat13;
4952
4953 vertices[2] = particlePtr->Position;
4954
4955 vertices[3].vx = particlePtr->Position.vx-mat.mat31+mat.mat21;
4956 vertices[3].vy = particlePtr->Position.vy-mat.mat32+mat.mat22;
4957 vertices[3].vz = particlePtr->Position.vz-mat.mat33+mat.mat23;
4958
4959 vertices[4].vx = particlePtr->Position.vx-mat.mat31-mat.mat21;
4960 vertices[4].vy = particlePtr->Position.vy-mat.mat32-mat.mat22;
4961 vertices[4].vz = particlePtr->Position.vz-mat.mat33-mat.mat23;
4962
4963 TranslatePointIntoViewspace(&vertices[0]);
4964 TranslatePointIntoViewspace(&vertices[1]);
4965 TranslatePointIntoViewspace(&vertices[2]);
4966 TranslatePointIntoViewspace(&vertices[3]);
4967 TranslatePointIntoViewspace(&vertices[4]);
4968
4969 {
4970 int i;
4971 for (i=0; i<3; i++)
4972 {
4973 VerticesBuffer[i].X = vertices[i].vx;
4974 VerticesBuffer[i].Y = vertices[i].vy;
4975 VerticesBuffer[i].Z = vertices[i].vz;
4976
4977 VerticesBuffer[i].A = (particlePtr->Colour>>24)&255;
4978 VerticesBuffer[i].R = (particlePtr->Colour>>16)&255;
4979 VerticesBuffer[i].G = (particlePtr->Colour>>8)&255;
4980 VerticesBuffer[i].B = (particlePtr->Colour)&255;
4981 }
4982 RenderPolygon.NumberOfVertices=3;
4983 RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL;
4984 }
4985 {
4986 int outcode = TriangleWithinFrustrum();
4987 POLYHEADER fakeHeader;
4988 fakeHeader.PolyFlags = iflag_transparent;
4989
4990 do
4991 {
4992 if (outcode)
4993 {
4994 if (outcode!=2)
4995 {
4996 GouraudPolygon_ClipWithZ();
4997 if(RenderPolygon.NumberOfVertices<3) continue;
4998 GouraudPolygon_ClipWithNegativeX();
4999 if(RenderPolygon.NumberOfVertices<3) continue;
5000 GouraudPolygon_ClipWithPositiveY();
5001 if(RenderPolygon.NumberOfVertices<3) continue;
5002 GouraudPolygon_ClipWithNegativeY();
5003 if(RenderPolygon.NumberOfVertices<3) continue;
5004 GouraudPolygon_ClipWithPositiveX();
5005 if(RenderPolygon.NumberOfVertices<3) continue;
5006 D3D_ZBufferedGouraudPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
5007 }
5008 else D3D_ZBufferedGouraudPolygon_Output(&fakeHeader,VerticesBuffer);
5009 }
5010 }
5011 while(0);
5012 }
5013 {
5014 int i;
5015 for (i=0; i<3; i++)
5016 {
5017 VerticesBuffer[i].X = vertices[i+2].vx;
5018 VerticesBuffer[i].Y = vertices[i+2].vy;
5019 VerticesBuffer[i].Z = vertices[i+2].vz;
5020
5021 VerticesBuffer[i].A = (particlePtr->Colour>>24)&255;
5022 VerticesBuffer[i].R = (particlePtr->Colour>>16)&255;
5023 VerticesBuffer[i].G = (particlePtr->Colour>>8)&255;
5024 VerticesBuffer[i].B = (particlePtr->Colour)&255;
5025 }
5026 RenderPolygon.NumberOfVertices=3;
5027 RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL;
5028 }
5029 {
5030 int outcode = TriangleWithinFrustrum();
5031 POLYHEADER fakeHeader;
5032 fakeHeader.PolyFlags = iflag_transparent;
5033
5034 do
5035 {
5036 if (outcode)
5037 {
5038 if (outcode!=2)
5039 {
5040 GouraudPolygon_ClipWithZ();
5041 if(RenderPolygon.NumberOfVertices<3) continue;
5042 GouraudPolygon_ClipWithNegativeX();
5043 if(RenderPolygon.NumberOfVertices<3) continue;
5044 GouraudPolygon_ClipWithPositiveY();
5045 if(RenderPolygon.NumberOfVertices<3) continue;
5046 GouraudPolygon_ClipWithNegativeY();
5047 if(RenderPolygon.NumberOfVertices<3) continue;
5048 GouraudPolygon_ClipWithPositiveX();
5049 if(RenderPolygon.NumberOfVertices<3) continue;
5050 D3D_ZBufferedGouraudPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
5051 }
5052 else D3D_ZBufferedGouraudPolygon_Output(&fakeHeader,VerticesBuffer);
5053 }
5054 }
5055 while(0);
5056 }
5057
5058 }
5059
ParticlePolygon_Construct(PARTICLE * particlePtr)5060 static void ParticlePolygon_Construct(PARTICLE *particlePtr)
5061 {
5062 PARTICLE_DESC *particleDescPtr = &ParticleDescription[particlePtr->ParticleID];
5063 RenderPolygon.NumberOfVertices=4;
5064
5065 VerticesBuffer[0].U = particleDescPtr->StartU;
5066 VerticesBuffer[0].V = particleDescPtr->StartV;
5067
5068 VerticesBuffer[1].U = particleDescPtr->EndU;
5069 VerticesBuffer[1].V = particleDescPtr->StartV;
5070
5071 VerticesBuffer[2].U = particleDescPtr->EndU;
5072 VerticesBuffer[2].V = particleDescPtr->EndV;
5073
5074 VerticesBuffer[3].U = particleDescPtr->StartU;
5075 VerticesBuffer[3].V = particleDescPtr->EndV;
5076
5077 }
5078
RenderMirroredDecal(DECAL * decalPtr)5079 void RenderMirroredDecal(DECAL *decalPtr)
5080 {
5081 /* translate decal into view space */
5082 {
5083 VECTORCH translatedPosition = decalPtr->Vertices[0];
5084 translatedPosition.vx = MirroringAxis - translatedPosition.vx;
5085 TranslatePointIntoViewspace(&translatedPosition);
5086 VerticesBuffer[0].X = translatedPosition.vx;
5087 VerticesBuffer[0].Y = translatedPosition.vy;
5088 VerticesBuffer[0].Z = translatedPosition.vz;
5089 }
5090 {
5091 VECTORCH translatedPosition = decalPtr->Vertices[1];
5092 translatedPosition.vx = MirroringAxis - translatedPosition.vx;
5093 TranslatePointIntoViewspace(&translatedPosition);
5094 VerticesBuffer[1].X = translatedPosition.vx;
5095 VerticesBuffer[1].Y = translatedPosition.vy;
5096 VerticesBuffer[1].Z = translatedPosition.vz;
5097 }
5098 {
5099 VECTORCH translatedPosition = decalPtr->Vertices[2];
5100 translatedPosition.vx = MirroringAxis - translatedPosition.vx;
5101 TranslatePointIntoViewspace(&translatedPosition);
5102 VerticesBuffer[2].X = translatedPosition.vx;
5103 VerticesBuffer[2].Y = translatedPosition.vy;
5104 VerticesBuffer[2].Z = translatedPosition.vz;
5105 }
5106 {
5107 VECTORCH translatedPosition = decalPtr->Vertices[3];
5108 translatedPosition.vx = MirroringAxis - translatedPosition.vx;
5109 TranslatePointIntoViewspace(&translatedPosition);
5110 VerticesBuffer[3].X = translatedPosition.vx;
5111 VerticesBuffer[3].Y = translatedPosition.vy;
5112 VerticesBuffer[3].Z = translatedPosition.vz;
5113 }
5114 {
5115 int outcode = DecalWithinFrustrum(decalPtr);
5116
5117 if (outcode)
5118 {
5119 switch(decalPtr->DecalID)
5120 {
5121 default:
5122 case DECAL_SCORCHED:
5123 {
5124 DecalPolygon_Construct(decalPtr);
5125
5126 if (outcode!=2)
5127 {
5128 TexturedPolygon_ClipWithZ();
5129 if(RenderPolygon.NumberOfVertices<3) return;
5130 TexturedPolygon_ClipWithNegativeX();
5131 if(RenderPolygon.NumberOfVertices<3) return;
5132 TexturedPolygon_ClipWithPositiveY();
5133 if(RenderPolygon.NumberOfVertices<3) return;
5134 TexturedPolygon_ClipWithNegativeY();
5135 if(RenderPolygon.NumberOfVertices<3) return;
5136 TexturedPolygon_ClipWithPositiveX();
5137 if(RenderPolygon.NumberOfVertices<3) return;
5138 D3D_Decal_Output(decalPtr,RenderPolygon.Vertices);
5139
5140 }
5141 else D3D_Decal_Output(decalPtr,VerticesBuffer);
5142 break;
5143 }
5144 }
5145 }
5146 }
5147 }
5148
5149
DecalPolygon_Construct(DECAL * decalPtr)5150 static void DecalPolygon_Construct(DECAL *decalPtr)
5151 {
5152 DECAL_DESC *decalDescPtr = &DecalDescription[decalPtr->DecalID];
5153 RenderPolygon.NumberOfVertices=4;
5154
5155 VerticesBuffer[0].U = decalDescPtr->StartU+decalPtr->UOffset;
5156 VerticesBuffer[0].V = decalDescPtr->StartV;
5157
5158 VerticesBuffer[1].U = decalDescPtr->EndU+decalPtr->UOffset;
5159 VerticesBuffer[1].V = decalDescPtr->StartV;
5160
5161 VerticesBuffer[2].U = decalDescPtr->EndU+decalPtr->UOffset;
5162 VerticesBuffer[2].V = decalDescPtr->EndV;
5163
5164 VerticesBuffer[3].U = decalDescPtr->StartU+decalPtr->UOffset;
5165 VerticesBuffer[3].V = decalDescPtr->EndV;
5166
5167 }
5168
5169 #if 0
5170 int polys[][4] =
5171 {
5172 {1,3,5,7},
5173 {1,3,9,11},
5174 {2,3,5,4},
5175 {2,3,9,8},
5176
5177 {0,2,4,6},
5178 {0,2,8,10},
5179 {0,1,7,6},
5180 {0,1,11,10},
5181
5182 {12,13,15,14},
5183 {4,5,7,6},
5184
5185 {8,9,5,4},
5186 {6,7,11,10},
5187 {8,4,6,10},
5188 {5,9,11,7},
5189
5190 // {8,2,4,4},
5191 // {9,3,5,5},
5192 // {10,0,6,6},
5193 // {7,1,11,11}
5194 };
5195 int alphaValue[]={64,64,64,64, 16,16,16,16, 0,0,0,0, 128,128,128,128};
5196
5197 //void RenderShaftOfLight(SHAFTOFLIGHT *shaftPtr)
5198 void RenderShaftOfLight(MODULE *modulePtr)
5199 {
5200 /* translate shaft into view space */
5201
5202 // suitable for invasion2
5203 VECTORCH shaftVertices[]=
5204 {
5205 {-5500,9000,9822},
5206 {-4500,9000,9822},
5207 {-5500,10000,9822},
5208 {-4500,10000,9822},
5209
5210 {-6000,15900,13000},
5211 {-4000,15900,13000},
5212 {-6000,15900,15500},
5213 {-4000,15900,15500},
5214
5215 {-6500,15900,12500},
5216 {-3500,15900,12500},
5217 {-6500,15900,16000},
5218 {-3500,15900,16000},
5219 };
5220 /*
5221 VECTORCH shaftVertices[]=
5222 {
5223 {0, 0, 0},
5224 {0, 0, 1139},
5225 {-1338, 7113, 0},
5226 {-1338, 7113, 1139},
5227
5228
5229 {,1948,}
5230
5231 {26002+ -1700, 7781 , -25328+ -800},
5232 {26002+ -900, 7781 , -25328+ +800},
5233 {26002+ 1700, 7781 , -25328+ -800},
5234 {26002+ 1700, 7781 , -25328+ +800},
5235
5236 {26002+ -1100, 7781 , -25328+ -1000},
5237 {26002+ -1100, 7781 , -25328+ +1000},
5238 {26002+ 2000, 7781 , -25328+ -1000},
5239 {26002+ 2000, 7781 , -25328+ +1000},
5240
5241 };
5242 */
5243 VECTORCH translatedPts[12];
5244
5245 POLYHEADER fakeHeader;
5246 DECAL fakeDecal;
5247 int polyNumber;
5248
5249 fakeDecal.ModuleIndex=148;
5250 // fakeDecal.ModuleIndex=17;
5251 fakeHeader.PolyFlags = iflag_transparent;
5252
5253 {
5254 int i = 11;
5255 do
5256 {
5257 translatedPts[i] = shaftVertices[i];
5258 // translatedPts[i].vx+=10712;
5259 // translatedPts[i].vy+=-6480;
5260 // translatedPts[i].vz+=-25898;
5261 TranslatePointIntoViewspace(&translatedPts[i]);
5262 }
5263 while(i--);
5264 }
5265
5266 for(polyNumber=0; polyNumber<10; polyNumber++)
5267 {
5268 {
5269 int i;
5270 for (i=0; i<4; i++)
5271 {
5272 int v = polys[polyNumber][i];
5273 VerticesBuffer[i].A = alphaValue[v];
5274 if (v>11)
5275 {
5276 VerticesBuffer[i].X = translatedPts[v-12].vx;
5277 VerticesBuffer[i].Y = translatedPts[v-12].vy;
5278 VerticesBuffer[i].Z = translatedPts[v-12].vz;
5279 }
5280 else
5281 {
5282 VerticesBuffer[i].X = translatedPts[v].vx;
5283 VerticesBuffer[i].Y = translatedPts[v].vy;
5284 VerticesBuffer[i].Z = translatedPts[v].vz;
5285 }
5286 VerticesBuffer[i].R = 255;
5287 VerticesBuffer[i].G = 255;
5288 VerticesBuffer[i].B = 192;
5289 }
5290 RenderPolygon.NumberOfVertices=4;
5291 }
5292 {
5293 int outcode = DecalWithinFrustrum(&fakeDecal);
5294
5295 if (outcode)
5296 {
5297 if (outcode!=2)
5298 {
5299 GouraudPolygon_ClipWithZ();
5300 if(RenderPolygon.NumberOfVertices<3) return;
5301 GouraudPolygon_ClipWithNegativeX();
5302 if(RenderPolygon.NumberOfVertices<3) return;
5303 GouraudPolygon_ClipWithPositiveY();
5304 if(RenderPolygon.NumberOfVertices<3) return;
5305 GouraudPolygon_ClipWithNegativeY();
5306 if(RenderPolygon.NumberOfVertices<3) return;
5307 GouraudPolygon_ClipWithPositiveX();
5308 if(RenderPolygon.NumberOfVertices<3) return;
5309 D3D_ZBufferedGouraudPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
5310 }
5311 else D3D_ZBufferedGouraudPolygon_Output(&fakeHeader,VerticesBuffer);
5312 }
5313 }
5314 }
5315 }
5316 #else
5317 int polys[][4] =
5318 {
5319 {0,1,3,2},
5320 {2,3,5,4},
5321 {4,5,7,6},
5322
5323 {1,3,5,7},
5324 {0,2,4,6},
5325 {6,8,10,0},
5326 {7,9,11,1},
5327
5328 {0,1,11,10},
5329 {6,7,9,8},
5330
5331
5332 };
5333 int alphaValue[]={32,32,32,32, 28,28,28,28, 4,4,4,4, 128,128,128,128};
5334 // int alphaValue[]={16,16,16,16, 14,14,14,14, 2,2,2,2, 128,128,128,128};
5335 VECTORCH shaftVertices[]=
5336 {
5337 {0, 0, 0},
5338 {0, 0, 1956},
5339 {-1492, 7969, 0},
5340 {-1492, 7969, 1956},
5341
5342 // {0, 0, 0},
5343 // {0, 0, 1139},
5344 // {-1338, 7113, 0},
5345 // {-1338, 7113, 1139},
5346
5347 {0, 8840, 0},
5348 {0, 8840, 0},
5349 {3138, 8850, 0},
5350 {3138, 8850, 0},
5351
5352 {0, 14500, 0},
5353 {0, 14500, 0},
5354 {0, 14500, 0},
5355 {0, 14500, 0},
5356
5357
5358 };
5359
RenderShaftOfLight(MODULE * modulePtr)5360 void RenderShaftOfLight(MODULE *modulePtr)
5361 {
5362 /* translate shaft into view space */
5363 #define NUM_OF_SHAFT_VERTICES 12
5364 VECTORCH translatedPts[NUM_OF_SHAFT_VERTICES];
5365
5366 POLYHEADER fakeHeader;
5367 DECAL fakeDecal;
5368 int polyNumber;
5369 VECTORCH lightDirection1 = {29309,29309,-2000};
5370 VECTORCH lightDirection2 = {29309,29309,2000};
5371
5372 // return;
5373 {
5374 int offset = GetSin((CloakingPhase/16)&4095);
5375 if (offset<0) offset=-offset;
5376 offset = MUL_FIXED(offset,offset);
5377 offset = MUL_FIXED(offset,offset);
5378 offset=MUL_FIXED(offset,4000);
5379 lightDirection1.vz += offset;
5380 lightDirection2.vz += offset;
5381 }
5382 Normalise(&lightDirection1);
5383 Normalise(&lightDirection2);
5384 // textprint("light shaft active");
5385 fakeDecal.ModuleIndex=modulePtr->m_index;
5386 fakeHeader.PolyFlags = iflag_transparent;
5387
5388
5389 FindIntersectionWithYPlane(&shaftVertices[2],&lightDirection1,&shaftVertices[4]);
5390 FindIntersectionWithYPlane(&shaftVertices[3],&lightDirection2,&shaftVertices[5]);
5391 FindZFromXYIntersection(&shaftVertices[2],&lightDirection1,&shaftVertices[6]);
5392 FindZFromXYIntersection(&shaftVertices[3],&lightDirection2,&shaftVertices[7]);
5393 FindIntersectionWithYPlane(&shaftVertices[0],&lightDirection1,&shaftVertices[10]);
5394 FindIntersectionWithYPlane(&shaftVertices[1],&lightDirection2,&shaftVertices[11]);
5395 FindIntersectionWithYPlane(&shaftVertices[6],&lightDirection1,&shaftVertices[8]);
5396 FindIntersectionWithYPlane(&shaftVertices[7],&lightDirection2,&shaftVertices[9]);
5397
5398 {
5399
5400 int i = NUM_OF_SHAFT_VERTICES-1;
5401 do
5402 {
5403 translatedPts[i] = shaftVertices[i];
5404 translatedPts[i].vx+=11762;
5405 translatedPts[i].vy+=-6919;
5406 translatedPts[i].vz+=-26312;
5407 // translatedPts[i].vx+=10712;
5408 // translatedPts[i].vy+=-6480;
5409 // translatedPts[i].vz+=-25898;
5410 TranslatePointIntoViewspace(&translatedPts[i]);
5411 }
5412 while(i--);
5413 }
5414
5415
5416 for(polyNumber=0; polyNumber<9; polyNumber++)
5417 {
5418 {
5419 int i;
5420 for (i=0; i<4; i++)
5421 {
5422 int v = polys[polyNumber][i];
5423 VerticesBuffer[i].A = alphaValue[v];
5424 VerticesBuffer[i].X = translatedPts[v].vx;
5425 VerticesBuffer[i].Y = translatedPts[v].vy;
5426 VerticesBuffer[i].Z = translatedPts[v].vz;
5427 VerticesBuffer[i].R = 255;
5428 VerticesBuffer[i].G = 255;
5429 VerticesBuffer[i].B = 192;
5430 }
5431 RenderPolygon.NumberOfVertices=4;
5432 }
5433 {
5434 int outcode = DecalWithinFrustrum(&fakeDecal);
5435
5436 if (outcode)
5437 {
5438 if (outcode!=2)
5439 {
5440 GouraudPolygon_ClipWithZ();
5441 if(RenderPolygon.NumberOfVertices<3) continue;
5442 GouraudPolygon_ClipWithNegativeX();
5443 if(RenderPolygon.NumberOfVertices<3) continue;
5444 GouraudPolygon_ClipWithPositiveY();
5445 if(RenderPolygon.NumberOfVertices<3) continue;
5446 GouraudPolygon_ClipWithNegativeY();
5447 if(RenderPolygon.NumberOfVertices<3) continue;
5448 GouraudPolygon_ClipWithPositiveX();
5449 if(RenderPolygon.NumberOfVertices<3) continue;
5450 D3D_ZBufferedGouraudPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
5451 }
5452 else D3D_ZBufferedGouraudPolygon_Output(&fakeHeader,VerticesBuffer);
5453 }
5454 }
5455 }
5456 RenderShaftOfLight2(modulePtr);
5457 }
RenderShaftOfLight2(MODULE * modulePtr)5458 void RenderShaftOfLight2(MODULE *modulePtr)
5459 {
5460 /* translate shaft into view space */
5461 #define NUM_OF_SHAFT_VERTICES 12
5462 VECTORCH translatedPts[NUM_OF_SHAFT_VERTICES];
5463
5464 POLYHEADER fakeHeader;
5465 DECAL fakeDecal;
5466 int polyNumber;
5467 VECTORCH lightDirection1 = {29309+1000,29309,-3000};
5468 VECTORCH lightDirection2 = {29309+1000,29309,3000};
5469 VECTORCH lightDirection3 = {29309-1000,29309,-3000};
5470 VECTORCH lightDirection4 = {29309-1000,29309,3000};
5471 {
5472 int offset = GetSin((CloakingPhase/16)&4095);
5473 if (offset<0) offset=-offset;
5474 offset = MUL_FIXED(offset,offset);
5475 offset = MUL_FIXED(offset,offset);
5476 offset=MUL_FIXED(offset,4000);
5477 lightDirection1.vz += offset;
5478 lightDirection2.vz += offset;
5479 lightDirection3.vz += offset;
5480 lightDirection4.vz += offset;
5481 }
5482 Normalise(&lightDirection1);
5483 Normalise(&lightDirection2);
5484 Normalise(&lightDirection3);
5485 Normalise(&lightDirection4);
5486
5487 fakeDecal.ModuleIndex=modulePtr->m_index;
5488 fakeHeader.PolyFlags = iflag_transparent;
5489
5490
5491 FindIntersectionWithYPlane(&shaftVertices[2],&lightDirection1,&shaftVertices[4]);
5492 FindIntersectionWithYPlane(&shaftVertices[3],&lightDirection2,&shaftVertices[5]);
5493 FindZFromXYIntersection(&shaftVertices[2],&lightDirection3,&shaftVertices[6]);
5494 FindZFromXYIntersection(&shaftVertices[3],&lightDirection4,&shaftVertices[7]);
5495 FindIntersectionWithYPlane(&shaftVertices[0],&lightDirection1,&shaftVertices[10]);
5496 FindIntersectionWithYPlane(&shaftVertices[1],&lightDirection2,&shaftVertices[11]);
5497 FindIntersectionWithYPlane(&shaftVertices[6],&lightDirection3,&shaftVertices[8]);
5498 FindIntersectionWithYPlane(&shaftVertices[7],&lightDirection4,&shaftVertices[9]);
5499
5500
5501 {
5502
5503 int i = NUM_OF_SHAFT_VERTICES-1;
5504 do
5505 {
5506 translatedPts[i] = shaftVertices[i];
5507 translatedPts[i].vx+=11762;
5508 translatedPts[i].vy+=-6919;
5509 translatedPts[i].vz+=-26312;
5510 // translatedPts[i].vx+=10712;
5511 // translatedPts[i].vy+=-6480;
5512 // translatedPts[i].vz+=-25898;
5513 TranslatePointIntoViewspace(&translatedPts[i]);
5514 }
5515 while(i--);
5516 }
5517
5518
5519 for(polyNumber=0; polyNumber<9; polyNumber++)
5520 {
5521 {
5522 int i;
5523 for (i=0; i<4; i++)
5524 {
5525 int v = polys[polyNumber][i];
5526 VerticesBuffer[i].A = alphaValue[v]/2;
5527 VerticesBuffer[i].X = translatedPts[v].vx;
5528 VerticesBuffer[i].Y = translatedPts[v].vy;
5529 VerticesBuffer[i].Z = translatedPts[v].vz;
5530 VerticesBuffer[i].R = 255;
5531 VerticesBuffer[i].G = 255;
5532 VerticesBuffer[i].B = 192;
5533 }
5534 RenderPolygon.NumberOfVertices=4;
5535 }
5536 {
5537 int outcode = DecalWithinFrustrum(&fakeDecal);
5538
5539 if (outcode)
5540 {
5541 if (outcode!=2)
5542 {
5543 GouraudPolygon_ClipWithZ();
5544 if(RenderPolygon.NumberOfVertices<3) continue;
5545 GouraudPolygon_ClipWithNegativeX();
5546 if(RenderPolygon.NumberOfVertices<3) continue;
5547 GouraudPolygon_ClipWithPositiveY();
5548 if(RenderPolygon.NumberOfVertices<3) continue;
5549 GouraudPolygon_ClipWithNegativeY();
5550 if(RenderPolygon.NumberOfVertices<3) continue;
5551 GouraudPolygon_ClipWithPositiveX();
5552 if(RenderPolygon.NumberOfVertices<3) continue;
5553 D3D_ZBufferedGouraudPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
5554 }
5555 else D3D_ZBufferedGouraudPolygon_Output(&fakeHeader,VerticesBuffer);
5556 }
5557 }
5558 }
5559 }
5560
FindIntersectionWithYPlane(VECTORCH * startPtr,VECTORCH * directionPtr,VECTORCH * intersectionPtr)5561 void FindIntersectionWithYPlane(VECTORCH *startPtr, VECTORCH *directionPtr, VECTORCH *intersectionPtr)
5562 {
5563 int lambda = DIV_FIXED(intersectionPtr->vy - startPtr->vy,directionPtr->vy);
5564
5565 intersectionPtr->vx = startPtr->vx + MUL_FIXED(directionPtr->vx,lambda);
5566 intersectionPtr->vz = startPtr->vz + MUL_FIXED(directionPtr->vz,lambda);
5567 // textprint("%d %d %d\n",intersectionPtr->vx,intersectionPtr->vy,intersectionPtr->vz);
5568 }
FindZFromXYIntersection(VECTORCH * startPtr,VECTORCH * directionPtr,VECTORCH * intersectionPtr)5569 void FindZFromXYIntersection(VECTORCH *startPtr, VECTORCH *directionPtr, VECTORCH *intersectionPtr)
5570 {
5571 float a = intersectionPtr->vx - startPtr->vx;
5572
5573 a/=directionPtr->vx;
5574
5575 intersectionPtr->vz = startPtr->vz + (directionPtr->vz*a);
5576 // textprint("%d %d %d\n",intersectionPtr->vx,intersectionPtr->vy,intersectionPtr->vz);
5577 }
5578
5579 #endif
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
ClearTranslucentPolyList(void)5592 void ClearTranslucentPolyList(void)
5593 {
5594 CurrentNumberOfTranslucentPolygons=0;
5595 }
5596
AddToTranslucentPolyList(POLYHEADER * inputPolyPtr,RENDERVERTEX * renderVerticesPtr)5597 void AddToTranslucentPolyList(POLYHEADER *inputPolyPtr,RENDERVERTEX *renderVerticesPtr)
5598 {
5599 /* copy the data to the list for processing later */
5600 int i = RenderPolygon.NumberOfVertices;
5601 int maxZ = 0;
5602 RENDERVERTEX *vertexPtr = TranslucentPolygons[CurrentNumberOfTranslucentPolygons].Vertices;
5603
5604 TranslucentPolygons[CurrentNumberOfTranslucentPolygons].NumberOfVertices = i;
5605
5606 do
5607 {
5608 if (maxZ<renderVerticesPtr->Z)
5609 maxZ = renderVerticesPtr->Z;
5610 *vertexPtr++ = *renderVerticesPtr++;
5611 }
5612 while(--i);
5613 TranslucentPolygons[CurrentNumberOfTranslucentPolygons].MaxZ = maxZ;
5614 TranslucentPolygonHeaders[CurrentNumberOfTranslucentPolygons] = *inputPolyPtr;
5615
5616 /* increment counter */
5617 CurrentNumberOfTranslucentPolygons++;
5618 LOCALASSERT(CurrentNumberOfTranslucentPolygons<MAX_NO_OF_TRANSLUCENT_POLYGONS);
5619 }
5620
OutputTranslucentPolyList(void)5621 void OutputTranslucentPolyList(void)
5622 {
5623 int i = CurrentNumberOfTranslucentPolygons;
5624 while(i--)
5625 {
5626 int k = CurrentNumberOfTranslucentPolygons;
5627 int maxFound = 0;
5628 while(k--)
5629 {
5630 if (TranslucentPolygons[k].MaxZ>TranslucentPolygons[maxFound].MaxZ)
5631 {
5632 maxFound = k;
5633 }
5634 }
5635
5636 RenderAllParticlesFurtherAwayThan(TranslucentPolygons[maxFound].MaxZ);
5637
5638 RenderPolygon.NumberOfVertices = TranslucentPolygons[maxFound].NumberOfVertices;
5639 RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL;
5640 D3D_ZBufferedGouraudTexturedPolygon_Output(&TranslucentPolygonHeaders[maxFound],TranslucentPolygons[maxFound].Vertices);
5641 TranslucentPolygons[maxFound].MaxZ=0;
5642 }
5643
5644 RenderAllParticlesFurtherAwayThan(-0x7fffffff);
5645
5646 }
5647
5648
5649 static const int CuboidPolyVertexU[][4] =
5650 {
5651 {1,1,1,1},
5652
5653 {127,127,0,0},
5654 {128,128,255,255},
5655
5656 {127,127,0,0},
5657 {128,128,255,255},
5658 };
5659 static const int CuboidPolyVertexV[][4] =
5660 {
5661 {1,1,1,1},
5662
5663 {127,0,0,127},
5664 {127,0,0,127},
5665 {128,255,255,128},
5666 {128,255,255,128},
5667 };
5668
5669
RenderMirrorSurface(void)5670 void RenderMirrorSurface(void)
5671 {
5672 VECTORCH translatedPts[4] =
5673 {
5674 {-5596,-932,-1872},
5675 {-5596,-932,-702},
5676 {-5596,1212,-702},
5677 {-5596,1212,-1872},
5678
5679 };
5680 int mirrorUV[]=
5681 { 0,0, 127<<16,0, 127<<16,127<<16, 0,127<<16};
5682 POLYHEADER fakeHeader;
5683
5684
5685 {
5686 extern int CloudyImageNumber;
5687 fakeHeader.PolyFlags = iflag_transparent;
5688 fakeHeader.PolyColour = CloudyImageNumber;
5689 }
5690
5691 {
5692 int i;
5693 for (i=0; i<4; i++)
5694 {
5695 VerticesBuffer[i].A = 128;
5696
5697 TranslatePointIntoViewspace(&translatedPts[i]);
5698 VerticesBuffer[i].X = translatedPts[i].vx;
5699 VerticesBuffer[i].Y = translatedPts[i].vy;
5700 VerticesBuffer[i].Z = translatedPts[i].vz;
5701 VerticesBuffer[i].U = mirrorUV[i*2];
5702 VerticesBuffer[i].V = mirrorUV[i*2+1];
5703
5704
5705 VerticesBuffer[i].R = 255;
5706 VerticesBuffer[i].G = 255;
5707 VerticesBuffer[i].B = 255;
5708 VerticesBuffer[i].SpecularR = 0;
5709 VerticesBuffer[i].SpecularG = 0;
5710 VerticesBuffer[i].SpecularB = 0;
5711
5712 }
5713 RenderPolygon.NumberOfVertices=4;
5714 RenderPolygon.TranslucencyMode = TRANSLUCENCY_COLOUR;
5715 }
5716
5717 GouraudTexturedPolygon_ClipWithZ();
5718 if(RenderPolygon.NumberOfVertices<3) return;
5719 GouraudTexturedPolygon_ClipWithNegativeX();
5720 if(RenderPolygon.NumberOfVertices<3) return;
5721 GouraudTexturedPolygon_ClipWithPositiveY();
5722 if(RenderPolygon.NumberOfVertices<3) return;
5723 GouraudTexturedPolygon_ClipWithNegativeY();
5724 if(RenderPolygon.NumberOfVertices<3) return;
5725 GouraudTexturedPolygon_ClipWithPositiveX();
5726 if(RenderPolygon.NumberOfVertices<3) return;
5727 D3D_ZBufferedGouraudTexturedPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
5728 }
RenderMirrorSurface2(void)5729 void RenderMirrorSurface2(void)
5730 {
5731 VECTORCH translatedPts[4] =
5732 {
5733 {-5596,-592,562},
5734 {-5596,-592,1344},
5735 {-5596,140,1344},
5736 {-5596,140,562},
5737
5738 };
5739 int mirrorUV[]=
5740 { 0,0, 127<<16,0, 127<<16,127<<16, 0,127<<16};
5741 POLYHEADER fakeHeader;
5742
5743
5744 {
5745 extern int CloudyImageNumber;
5746 fakeHeader.PolyFlags = iflag_transparent;
5747 fakeHeader.PolyColour = CloudyImageNumber;
5748 }
5749
5750 {
5751 int i;
5752 for (i=0; i<4; i++)
5753 {
5754 VerticesBuffer[i].A = 128;
5755
5756 TranslatePointIntoViewspace(&translatedPts[i]);
5757 VerticesBuffer[i].X = translatedPts[i].vx;
5758 VerticesBuffer[i].Y = translatedPts[i].vy;
5759 VerticesBuffer[i].Z = translatedPts[i].vz;
5760 VerticesBuffer[i].U = mirrorUV[i*2];
5761 VerticesBuffer[i].V = mirrorUV[i*2+1];
5762
5763
5764 VerticesBuffer[i].R = 255;
5765 VerticesBuffer[i].G = 255;
5766 VerticesBuffer[i].B = 255;
5767 VerticesBuffer[i].SpecularR = 0;
5768 VerticesBuffer[i].SpecularG = 0;
5769 VerticesBuffer[i].SpecularB = 0;
5770
5771 }
5772 RenderPolygon.NumberOfVertices=4;
5773 RenderPolygon.TranslucencyMode = TRANSLUCENCY_COLOUR;
5774 }
5775
5776 GouraudTexturedPolygon_ClipWithZ();
5777 if(RenderPolygon.NumberOfVertices<3) return;
5778 GouraudTexturedPolygon_ClipWithNegativeX();
5779 if(RenderPolygon.NumberOfVertices<3) return;
5780 GouraudTexturedPolygon_ClipWithPositiveY();
5781 if(RenderPolygon.NumberOfVertices<3) return;
5782 GouraudTexturedPolygon_ClipWithNegativeY();
5783 if(RenderPolygon.NumberOfVertices<3) return;
5784 GouraudTexturedPolygon_ClipWithPositiveX();
5785 if(RenderPolygon.NumberOfVertices<3) return;
5786 D3D_ZBufferedGouraudTexturedPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
5787 }
RenderSmokeTest(void)5788 void RenderSmokeTest(void)
5789 {
5790 int mirrorUV[]=
5791 {
5792 64<<16, 0,
5793 64<<16, 31<<16,
5794 95<<16, 31<<16,
5795 95<<16, 0
5796 };
5797 POLYHEADER fakeHeader;
5798 int a = GetSin(CloakingPhase&4095);
5799 int image;
5800
5801 a = MUL_FIXED(MUL_FIXED(a,a),255);
5802 {
5803 extern int SpecialFXImageNumber;
5804 fakeHeader.PolyFlags = iflag_transparent;
5805 fakeHeader.PolyColour = SpecialFXImageNumber;
5806 }
5807
5808 for (image = 0; image<=1; image++)
5809 {
5810 {
5811 VECTORCH translatedPts[4] =
5812 {
5813 {45300,0+-1000, 26000+-1000},
5814 {45300,0+-1000, 26000+ 1000},
5815 {45300,0+ 1000, 26000+ 1000},
5816 {45300,0+ 1000, 26000+-1000},
5817
5818 };
5819
5820 int i;
5821
5822 if (image) a = 255-a;
5823 for (i=0; i<4; i++)
5824 {
5825 VerticesBuffer[i].A = a/2;
5826
5827 TranslatePointIntoViewspace(&translatedPts[i]);
5828 VerticesBuffer[i].X = translatedPts[i].vx;
5829 VerticesBuffer[i].Y = translatedPts[i].vy;
5830 VerticesBuffer[i].Z = translatedPts[i].vz;
5831 VerticesBuffer[i].U = mirrorUV[i*2];
5832 VerticesBuffer[i].V = mirrorUV[i*2+1]+image*(32<<16);
5833
5834
5835 VerticesBuffer[i].R = 255;
5836 VerticesBuffer[i].G = 255;
5837 VerticesBuffer[i].B = 255;
5838 VerticesBuffer[i].SpecularR = 0;
5839 VerticesBuffer[i].SpecularG = 0;
5840 VerticesBuffer[i].SpecularB = 0;
5841
5842 }
5843 RenderPolygon.NumberOfVertices=4;
5844 RenderPolygon.TranslucencyMode = TRANSLUCENCY_GLOWING;
5845 }
5846
5847 GouraudTexturedPolygon_ClipWithZ();
5848 if(RenderPolygon.NumberOfVertices<3) return;
5849 GouraudTexturedPolygon_ClipWithNegativeX();
5850 if(RenderPolygon.NumberOfVertices<3) return;
5851 GouraudTexturedPolygon_ClipWithPositiveY();
5852 if(RenderPolygon.NumberOfVertices<3) return;
5853 GouraudTexturedPolygon_ClipWithNegativeY();
5854 if(RenderPolygon.NumberOfVertices<3) return;
5855 GouraudTexturedPolygon_ClipWithPositiveX();
5856 if(RenderPolygon.NumberOfVertices<3) return;
5857 D3D_ZBufferedGouraudTexturedPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
5858 }
5859 }
5860 #if 1
5861 #define OCTAVES 3
5862 int u[OCTAVES];
5863 int v[OCTAVES];
5864 int du[OCTAVES];
5865 int dv[OCTAVES];
5866 int setup=0;
5867
5868 int SkyColour_R=200;
5869 int SkyColour_G=200;
5870 int SkyColour_B=200;
RenderSky(void)5871 void RenderSky(void)
5872 {
5873 POLYHEADER fakeHeader;
5874 int x,z,o;
5875 if(!setup)
5876 {
5877 int i;
5878 setup=1;
5879 for(i=0;i<OCTAVES;i++)
5880 {
5881 u[i] = (FastRandom()&65535)*128;
5882 v[i] = (FastRandom()&65535)*128;
5883 du[i] = ( ((FastRandom()&65535)-32768)*(i+1) )*8;
5884 dv[i] = ( ((FastRandom()&65535)-32768)*(i+1) )*8;
5885 }
5886 }
5887 {
5888 extern int CloudyImageNumber;
5889 fakeHeader.PolyFlags = iflag_transparent;
5890 fakeHeader.PolyColour = CloudyImageNumber;
5891 RenderPolygon.TranslucencyMode = TRANSLUCENCY_GLOWING;
5892 }
5893 for (o=0; o<OCTAVES; o++)
5894 {
5895 u[o]+=MUL_FIXED(du[o],NormalFrameTime);
5896 v[o]+=MUL_FIXED(dv[o],NormalFrameTime);
5897 }
5898 for(x=-10; x<=10; x++)
5899 {
5900 for(z=-10; z<=10; z++)
5901 {
5902 int t = 255;
5903 int size = 65536*128;
5904 for (o=0; o<OCTAVES; o++)
5905 {
5906 {
5907 VECTORCH translatedPts[4] =
5908 {
5909 {-1024,-1000,-1024},
5910 {-1024,-1000, 1024},
5911 { 1024,-1000, 1024},
5912 { 1024,-1000,-1024},
5913
5914 };
5915 int i;
5916 for (i=0; i<4; i++)
5917 {
5918 VerticesBuffer[i].A = t;
5919 translatedPts[i].vx += 2048*x;//+(Global_VDB_Ptr->VDB_World.vx*7)/8;
5920 translatedPts[i].vz += 2048*z;//+(Global_VDB_Ptr->VDB_World.vz*7)/8;
5921 // RotateVector(&translatedPts[i],&(Global_VDB_Ptr->VDB_Mat));
5922 // translatedPts[i].vy = MUL_FIXED(translatedPts[i].vy,87381);
5923 translatedPts[i].vx += Global_VDB_Ptr->VDB_World.vx;
5924 translatedPts[i].vy += Global_VDB_Ptr->VDB_World.vy;
5925 translatedPts[i].vz += Global_VDB_Ptr->VDB_World.vz;
5926 TranslatePointIntoViewspace(&translatedPts[i]);
5927 VerticesBuffer[i].X = translatedPts[i].vx;
5928 VerticesBuffer[i].Y = translatedPts[i].vy;
5929 VerticesBuffer[i].Z = translatedPts[i].vz;
5930
5931 switch (CurrentVisionMode)
5932 {
5933 default:
5934 case VISION_MODE_NORMAL:
5935 {
5936 VerticesBuffer[i].R = SkyColour_R;
5937 VerticesBuffer[i].G = SkyColour_G;
5938 VerticesBuffer[i].B = SkyColour_B;
5939 break;
5940 }
5941 case VISION_MODE_IMAGEINTENSIFIER:
5942 {
5943 VerticesBuffer[i].R = 0;
5944 VerticesBuffer[i].G = 255;
5945 VerticesBuffer[i].B = 0;
5946 break;
5947 }
5948 case VISION_MODE_PRED_THERMAL:
5949 case VISION_MODE_PRED_SEEALIENS:
5950 case VISION_MODE_PRED_SEEPREDTECH:
5951 {
5952 VerticesBuffer[i].R = 0;
5953 VerticesBuffer[i].G = 0;
5954 VerticesBuffer[i].B = 255;
5955 break;
5956 }
5957 }
5958
5959 }
5960 VerticesBuffer[0].U = (u[o]+size*x);
5961 VerticesBuffer[0].V = (v[o]+size*z);
5962 VerticesBuffer[1].U = (u[o]+size*x);
5963 VerticesBuffer[1].V = (v[o]+size*(z+1));
5964 VerticesBuffer[2].U = (u[o]+size*(x+1));
5965 VerticesBuffer[2].V = (v[o]+size*(z+1));
5966 VerticesBuffer[3].U = (u[o]+size*(x+1));
5967 VerticesBuffer[3].V = (v[o]+size*z);
5968
5969
5970 RenderPolygon.NumberOfVertices=4;
5971 }
5972
5973 GouraudTexturedPolygon_ClipWithZ();
5974 if(RenderPolygon.NumberOfVertices>=3)
5975 {
5976 GouraudTexturedPolygon_ClipWithNegativeX();
5977 if(RenderPolygon.NumberOfVertices>=3)
5978 {
5979 GouraudTexturedPolygon_ClipWithPositiveY();
5980 if(RenderPolygon.NumberOfVertices>=3)
5981 {
5982 GouraudTexturedPolygon_ClipWithNegativeY();
5983 if(RenderPolygon.NumberOfVertices>=3)
5984 {
5985 GouraudTexturedPolygon_ClipWithPositiveX();
5986 if(RenderPolygon.NumberOfVertices>=3)
5987 {
5988 D3D_SkyPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
5989 }
5990 }
5991 }
5992 }
5993 }
5994 t/=2;
5995 size*=2;
5996 }
5997 }
5998 }
5999 }
6000 #endif
RenderWaterFall(int xOrigin,int yOrigin,int zOrigin)6001 void RenderWaterFall(int xOrigin, int yOrigin, int zOrigin)
6002 {
6003 int i,z;
6004 VECTORCH v[4];
6005
6006 {
6007 int waterfallX[9];
6008 int waterfallY[9];
6009 int waterfallZ[9];
6010 int waterfallZScale[9];
6011 for (i=0; i<9; i++)
6012 {
6013
6014 int u = (i*65536)/8;
6015
6016 int b = MUL_FIXED(2*u,(65536-u));
6017 int c = MUL_FIXED(u,u);
6018 int y3 = (4742-yOrigin);
6019 int x3 = 2000;
6020 int y2 = 2000;
6021 int x2 = 1500;
6022
6023 waterfallX[i] = MUL_FIXED(b,x2)+MUL_FIXED(c,x3);
6024 waterfallY[i] = yOrigin+MUL_FIXED(b,y2)+MUL_FIXED(c,y3);
6025 waterfallZ[i] = zOrigin+MUL_FIXED((66572-zOrigin),u);
6026 waterfallZScale[i] = ONE_FIXED+b/2-c;
6027 if (i!=8)
6028 {
6029 waterfallZScale[i]+=(FastRandom()&8191);
6030 waterfallY[i]-=(FastRandom()&127);
6031 }
6032
6033 }
6034 for (z=0; z<8; z++)
6035 for (i=0; i<8; i++)
6036 {
6037 v[0].vx = xOrigin+MUL_FIXED(waterfallX[i],waterfallZScale[z]);
6038 v[1].vx = xOrigin+MUL_FIXED(waterfallX[i],waterfallZScale[z+1]);
6039 v[2].vx = xOrigin+MUL_FIXED(waterfallX[i+1],waterfallZScale[z+1]);
6040 v[3].vx = xOrigin+MUL_FIXED(waterfallX[i+1],waterfallZScale[z]);
6041 v[0].vy = waterfallY[i];
6042 v[1].vy = waterfallY[i];
6043 v[2].vy = waterfallY[i+1];
6044 v[3].vy = waterfallY[i+1];
6045
6046
6047 v[0].vz = waterfallZ[z];
6048 v[1].vz = waterfallZ[z+1];
6049 v[2].vz = v[1].vz;
6050 v[3].vz = v[0].vz;
6051
6052 DrawWaterFallPoly(v);
6053 }
6054 for (z=0; z<3; z++)
6055 {
6056 v[0].vx = xOrigin+MUL_FIXED(waterfallX[8],waterfallZScale[z+1]);
6057 v[1].vx = xOrigin+MUL_FIXED(waterfallX[8],waterfallZScale[z]);
6058 v[2].vx = 179450;
6059 v[3].vx = 179450;
6060
6061 v[0].vy = 4742;
6062 v[1].vy = 4742;
6063 v[2].vy = 4742;
6064 v[3].vy = 4742;
6065
6066 v[0].vz = waterfallZ[z];
6067 v[1].vz = waterfallZ[z+1];
6068 v[2].vz = v[1].vz;
6069 v[3].vz = v[0].vz;
6070
6071 DrawWaterFallPoly(v);
6072 }
6073
6074 for (z=0; z<8; z++)
6075 for (i=0; i<16; i++)
6076 {
6077 int xOffset,xOffset2;
6078 if (z<3) xOffset = 179450;
6079 else xOffset = xOrigin+MUL_FIXED(waterfallX[8],waterfallZScale[z]);
6080 if (z<2) xOffset2 = 179450;
6081 else xOffset2 = xOrigin+MUL_FIXED(waterfallX[8],waterfallZScale[z+1]);
6082
6083 v[0].vx = xOffset;
6084 v[1].vx = xOffset2;
6085 v[2].vx = xOffset2;
6086 v[3].vx = xOffset;
6087
6088 v[0].vy = 4742+i*4096;
6089 v[1].vy = 4742+i*4096;
6090 v[2].vy = 4742+(i+1)*4096;
6091 v[3].vy = 4742+(i+1)*4096;
6092
6093
6094 v[0].vz = waterfallZ[z];
6095 v[1].vz = waterfallZ[z+1];
6096 v[2].vz = v[1].vz;
6097 v[3].vz = v[0].vz;
6098
6099 DrawWaterFallPoly(v);
6100 }
6101
6102 }
6103 }
6104
DrawWaterFallPoly(VECTORCH * v)6105 void DrawWaterFallPoly(VECTORCH *v)
6106 {
6107 POLYHEADER fakeHeader;
6108
6109 {
6110 extern int CloudyImageNumber;
6111 fakeHeader.PolyFlags = iflag_transparent;
6112 fakeHeader.PolyColour = CloudyImageNumber;
6113 RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL;
6114 }
6115 {
6116 static int wv=0;
6117 unsigned int a;
6118 for (a=0; a<4; a++)
6119 {
6120 VerticesBuffer[a].A = 128;
6121 VerticesBuffer[a].U = (v[a].vz)<<11;
6122 VerticesBuffer[a].V = (v[a].vy<<10)-wv;
6123
6124 TranslatePointIntoViewspace(&v[a]);
6125 VerticesBuffer[a].X = v[a].vx;
6126 VerticesBuffer[a].Y = v[a].vy;
6127 VerticesBuffer[a].Z = v[a].vz;
6128 VerticesBuffer[a].R = 200;
6129 VerticesBuffer[a].G = 200;
6130 VerticesBuffer[a].B = 255;
6131 VerticesBuffer[a].SpecularR = 0;
6132 VerticesBuffer[a].SpecularG = 0;
6133 VerticesBuffer[a].SpecularB = 0;
6134
6135
6136 }
6137 wv+=NormalFrameTime*2;
6138 RenderPolygon.NumberOfVertices=4;
6139 }
6140
6141 GouraudTexturedPolygon_ClipWithZ();
6142 if(RenderPolygon.NumberOfVertices>=3)
6143 {
6144 GouraudTexturedPolygon_ClipWithNegativeX();
6145 if(RenderPolygon.NumberOfVertices>=3)
6146 {
6147 GouraudTexturedPolygon_ClipWithPositiveY();
6148 if(RenderPolygon.NumberOfVertices>=3)
6149 {
6150 GouraudTexturedPolygon_ClipWithNegativeY();
6151 if(RenderPolygon.NumberOfVertices>=3)
6152 {
6153 GouraudTexturedPolygon_ClipWithPositiveX();
6154 if(RenderPolygon.NumberOfVertices>=3)
6155 {
6156 D3D_ZBufferedGouraudTexturedPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
6157 }
6158 }
6159 }
6160 }
6161 }
6162 }
RenderPredatorTargetingSegment(int theta,int scale,int drawInRed)6163 void RenderPredatorTargetingSegment(int theta, int scale, int drawInRed)
6164 {
6165 VECTOR2D offset[4];
6166 POLYHEADER fakeHeader;
6167 int centreX,centreY;
6168 int z = ONE_FIXED-scale;
6169 z = MUL_FIXED(MUL_FIXED(z,z),2048);
6170 {
6171 extern int SmartTargetSightX, SmartTargetSightY;
6172 extern SCREENDESCRIPTORBLOCK ScreenDescriptorBlock;
6173 centreY = MUL_FIXED( (SmartTargetSightY-(ScreenDescriptorBlock.SDB_Height<<15)) /Global_VDB_Ptr->VDB_ProjY,z);
6174 if (MIRROR_CHEATMODE)
6175 {
6176 centreX = MUL_FIXED( ( - (SmartTargetSightX-(ScreenDescriptorBlock.SDB_Width<<15))) /Global_VDB_Ptr->VDB_ProjX,z);
6177 }
6178 else
6179 {
6180 centreX = MUL_FIXED( (SmartTargetSightX-(ScreenDescriptorBlock.SDB_Width<<15)) /Global_VDB_Ptr->VDB_ProjX,z);
6181 }
6182 }
6183 z = (float)z*CameraZoomScale;
6184
6185 {
6186 int a = 160;
6187 int b = 40;
6188
6189 /* tan(30) = 1/sqrt(3), & 65536/(sqrt(3)) = 37837 */
6190
6191 int y = MUL_FIXED(37837,a+20);
6192
6193 offset[0].vx = -a+MUL_FIXED(113512,b);
6194 offset[0].vy = y-b;
6195
6196 offset[1].vx = -offset[0].vx;
6197 offset[1].vy = y-b;
6198
6199 offset[2].vx = a;
6200 offset[2].vy = y;
6201
6202 offset[3].vx = -a;
6203 offset[3].vy = y;
6204
6205 if (theta)
6206 {
6207 RotateVertex(&offset[0],theta);
6208 RotateVertex(&offset[1],theta);
6209 RotateVertex(&offset[2],theta);
6210 RotateVertex(&offset[3],theta);
6211 }
6212
6213 if (MIRROR_CHEATMODE)
6214 {
6215 offset[0].vx = -offset[0].vx;
6216 offset[1].vx = -offset[1].vx;
6217 offset[2].vx = -offset[2].vx;
6218 offset[3].vx = -offset[3].vx;
6219 }
6220 VerticesBuffer[0].X = offset[0].vx+centreX;
6221 VerticesBuffer[0].Y = MUL_FIXED(offset[0].vy,87381)+centreY;
6222
6223 VerticesBuffer[1].X = offset[1].vx+centreX;
6224 VerticesBuffer[1].Y = MUL_FIXED(offset[1].vy,87381)+centreY;
6225
6226 VerticesBuffer[2].X = offset[2].vx+centreX;
6227 VerticesBuffer[2].Y = MUL_FIXED(offset[2].vy,87381)+centreY;
6228
6229 VerticesBuffer[3].X = offset[3].vx+centreX;
6230 VerticesBuffer[3].Y = MUL_FIXED(offset[3].vy,87381)+centreY;
6231 }
6232 fakeHeader.PolyFlags = iflag_transparent;
6233 RenderPolygon.TranslucencyMode = TRANSLUCENCY_GLOWING;
6234
6235
6236 {
6237 int i;
6238 for (i=0; i<4; i++)
6239 {
6240 VerticesBuffer[i].A = 128;
6241
6242 VerticesBuffer[i].Z = z;
6243
6244 VerticesBuffer[i].R = 255;
6245
6246 if (drawInRed)
6247 {
6248 VerticesBuffer[i].G = 0;
6249 VerticesBuffer[i].B = 0;
6250 }
6251 else
6252 {
6253 VerticesBuffer[i].G = 255;
6254 VerticesBuffer[i].B = 255;
6255 }
6256
6257 }
6258 RenderPolygon.NumberOfVertices=4;
6259 }
6260
6261 GouraudPolygon_ClipWithZ();
6262 if(RenderPolygon.NumberOfVertices<3) return;
6263 GouraudPolygon_ClipWithNegativeX();
6264 if(RenderPolygon.NumberOfVertices<3) return;
6265 GouraudPolygon_ClipWithPositiveY();
6266 if(RenderPolygon.NumberOfVertices<3) return;
6267 GouraudPolygon_ClipWithNegativeY();
6268 if(RenderPolygon.NumberOfVertices<3) return;
6269 GouraudPolygon_ClipWithPositiveX();
6270 if(RenderPolygon.NumberOfVertices<3) return;
6271 D3D_ZBufferedGouraudPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
6272
6273 if (drawInRed)
6274 {
6275 VerticesBuffer[0].X = MUL_FIXED(offset[3].vx,scale*8)+centreX;
6276 VerticesBuffer[0].Y = MUL_FIXED(MUL_FIXED(offset[3].vy,scale*8),87381)+centreY;
6277
6278 VerticesBuffer[1].X = MUL_FIXED(offset[2].vx,scale*8)+centreX;
6279 VerticesBuffer[1].Y = MUL_FIXED(MUL_FIXED(offset[2].vy,scale*8),87381)+centreY;
6280
6281 VerticesBuffer[2].X = offset[2].vx+centreX;
6282 VerticesBuffer[2].Y = MUL_FIXED(offset[2].vy,87381)+centreY;
6283
6284 VerticesBuffer[3].X = offset[3].vx+centreX;
6285 VerticesBuffer[3].Y = MUL_FIXED(offset[3].vy,87381)+centreY;
6286 {
6287 int i;
6288 for (i=0; i<2; i++)
6289 {
6290 VerticesBuffer[i].A = 0;
6291 VerticesBuffer[i].Z = z;
6292 VerticesBuffer[i].R = 255;
6293 VerticesBuffer[i].G = 0;
6294 VerticesBuffer[i].B = 0;
6295 }
6296 for (i=2; i<4; i++)
6297 {
6298 VerticesBuffer[i].A = 128;
6299 VerticesBuffer[i].Z = z;
6300 VerticesBuffer[i].R = 255;
6301 VerticesBuffer[i].G = 0;
6302 VerticesBuffer[i].B = 0;
6303 }
6304 RenderPolygon.NumberOfVertices=4;
6305 }
6306
6307 GouraudPolygon_ClipWithZ();
6308 if(RenderPolygon.NumberOfVertices<3) return;
6309 GouraudPolygon_ClipWithNegativeX();
6310 if(RenderPolygon.NumberOfVertices<3) return;
6311 GouraudPolygon_ClipWithPositiveY();
6312 if(RenderPolygon.NumberOfVertices<3) return;
6313 GouraudPolygon_ClipWithNegativeY();
6314 if(RenderPolygon.NumberOfVertices<3) return;
6315 GouraudPolygon_ClipWithPositiveX();
6316 if(RenderPolygon.NumberOfVertices<3) return;
6317 D3D_ZBufferedGouraudPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
6318 }
6319 }
RenderPredatorPlasmaCasterCharge(int value,VECTORCH * worldOffsetPtr,MATRIXCH * orientationPtr)6320 void RenderPredatorPlasmaCasterCharge(int value, VECTORCH *worldOffsetPtr, MATRIXCH *orientationPtr)
6321 {
6322 POLYHEADER fakeHeader;
6323 VECTORCH translatedPts[4];
6324 int halfWidth = 100;
6325 int halfHeight = 4;
6326 int z = -1;
6327 translatedPts[0].vx = -halfWidth;
6328 translatedPts[0].vy = z;
6329 translatedPts[0].vz = -halfHeight-4;
6330
6331 translatedPts[1].vx = -halfWidth+MUL_FIXED(value,2*halfWidth-10);
6332 translatedPts[1].vy = z;
6333 translatedPts[1].vz = -halfHeight-4;
6334
6335 translatedPts[2].vx = -halfWidth+MUL_FIXED(value,2*halfWidth-10);
6336 translatedPts[2].vy = z;
6337 translatedPts[2].vz = halfHeight-4;
6338
6339 translatedPts[3].vx = -halfWidth;
6340 translatedPts[3].vy = z;
6341 translatedPts[3].vz = halfHeight-4;
6342
6343 fakeHeader.PolyFlags = iflag_transparent;
6344 RenderPolygon.TranslucencyMode = TRANSLUCENCY_GLOWING;
6345
6346
6347 {
6348 int i;
6349 for (i=0; i<4; i++)
6350 {
6351 VerticesBuffer[i].A = 255;
6352
6353 RotateVector(&(translatedPts[i]),orientationPtr);
6354 translatedPts[i].vx += worldOffsetPtr->vx;
6355 translatedPts[i].vy += worldOffsetPtr->vy;
6356 translatedPts[i].vz += worldOffsetPtr->vz;
6357 TranslatePointIntoViewspace(&translatedPts[i]);
6358
6359 VerticesBuffer[i].X = translatedPts[i].vx;
6360 VerticesBuffer[i].Y = translatedPts[i].vy;
6361 VerticesBuffer[i].Z = translatedPts[i].vz;
6362
6363 VerticesBuffer[i].R = 32;
6364 VerticesBuffer[i].G = 0;
6365 VerticesBuffer[i].B = 0;
6366 }
6367 RenderPolygon.NumberOfVertices=4;
6368 }
6369 {
6370 int outcode = QuadWithinFrustrum();
6371
6372 if (outcode)
6373 {
6374 if (outcode!=2)
6375 {
6376 GouraudPolygon_ClipWithZ();
6377 if(RenderPolygon.NumberOfVertices<3) return;
6378 GouraudPolygon_ClipWithNegativeX();
6379 if(RenderPolygon.NumberOfVertices<3) return;
6380 GouraudPolygon_ClipWithPositiveY();
6381 if(RenderPolygon.NumberOfVertices<3) return;
6382 GouraudPolygon_ClipWithNegativeY();
6383 if(RenderPolygon.NumberOfVertices<3) return;
6384 GouraudPolygon_ClipWithPositiveX();
6385 if(RenderPolygon.NumberOfVertices<3) return;
6386 D3D_ZBufferedGouraudPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
6387 }
6388 else D3D_ZBufferedGouraudPolygon_Output(&fakeHeader,VerticesBuffer);
6389 }
6390 }
6391 }
6392
6393
6394
6395
6396
6397 int LightFlareAlpha = 65535;
RenderLightFlare(VECTORCH * positionPtr,unsigned int colour)6398 void RenderLightFlare(VECTORCH *positionPtr, unsigned int colour)
6399 {
6400 int centreX,centreY,sizeX,sizeY,z;
6401 PARTICLE particle;
6402 // VECTORCH point = {-20947,-8216,2244};
6403 VECTORCH point = *positionPtr;
6404
6405
6406 #if 0
6407 if (IsThisObjectVisibleFromThisPosition(Player,&point,ONE_FIXED))
6408 {
6409 LightFlareAlpha+=NormalFrameTime*8;
6410 if (LightFlareAlpha > 65535) LightFlareAlpha = 65535;
6411 textprint("FLARE VIS\n");
6412 }
6413 else
6414 {
6415 LightFlareAlpha-=NormalFrameTime*8;
6416 if (LightFlareAlpha < 0) LightFlareAlpha = 0;
6417 textprint("FLARE INVIS\n");
6418 }
6419 #endif
6420 TranslatePointIntoViewspace(&point);
6421 if(point.vz<64) return;
6422
6423 #if 0
6424 {
6425 int alpha = ONE_FIXED - point.vz*2;
6426 if (alpha<0) return;
6427
6428 alpha = MUL_FIXED(LightFlareAlpha,alpha)>>8;
6429
6430 particle.ParticleID = PARTICLE_MUZZLEFLASH;
6431 particle.Colour = 0xffffff+((alpha)<<24);
6432 }
6433 #else
6434 particle.ParticleID = PARTICLE_LIGHTFLARE;
6435 // particle.Colour = 0xffffff+((LightFlareAlpha>>8)<<24);
6436 particle.Colour = colour;
6437 #endif
6438 // textprint("render fn %d %d %d\n",positionPtr->vx,positionPtr->vy,positionPtr->vz);
6439 // PARTICLE_DESC *particleDescPtr = &ParticleDescription[particlePtr->ParticleID];
6440 // int particleSize = particlePtr->Size;
6441 z=ONE_FIXED;
6442 {
6443 extern SCREENDESCRIPTORBLOCK ScreenDescriptorBlock;
6444 centreX = DIV_FIXED(point.vx,point.vz);
6445 centreY = DIV_FIXED(point.vy,point.vz);
6446 sizeX = (ScreenDescriptorBlock.SDB_Width<<13)/Global_VDB_Ptr->VDB_ProjX;
6447 sizeY = MUL_FIXED(ScreenDescriptorBlock.SDB_Height<<13,87381)/Global_VDB_Ptr->VDB_ProjY;
6448 }
6449
6450 VerticesBuffer[0].X = centreX - sizeX;
6451 VerticesBuffer[0].Y = centreY - sizeY;
6452 VerticesBuffer[0].Z = z;
6453 VerticesBuffer[1].X = centreX + sizeX;
6454 VerticesBuffer[1].Y = centreY - sizeY;
6455 VerticesBuffer[1].Z = z;
6456 VerticesBuffer[2].X = centreX + sizeX;
6457 VerticesBuffer[2].Y = centreY + sizeY;
6458 VerticesBuffer[2].Z = z;
6459 VerticesBuffer[3].X = centreX - sizeX;
6460 VerticesBuffer[3].Y = centreY + sizeY;
6461 VerticesBuffer[3].Z = z;
6462
6463 {
6464 int outcode = QuadWithinFrustrum();
6465
6466 if (outcode)
6467 {
6468 RenderPolygon.NumberOfVertices=4;
6469
6470 // textprint("On Screen!\n");
6471 VerticesBuffer[0].U = 192<<16;
6472 VerticesBuffer[0].V = 0;
6473
6474 VerticesBuffer[1].U = 255<<16;
6475 VerticesBuffer[1].V = 0;
6476
6477 VerticesBuffer[2].U = 255<<16;
6478 VerticesBuffer[2].V = 63<<16;
6479
6480 VerticesBuffer[3].U = 192<<16;
6481 VerticesBuffer[3].V = 63<<16;
6482
6483 if (outcode!=2)
6484 {
6485 TexturedPolygon_ClipWithZ();
6486 if(RenderPolygon.NumberOfVertices<3) return;
6487 TexturedPolygon_ClipWithNegativeX();
6488 if(RenderPolygon.NumberOfVertices<3) return;
6489 TexturedPolygon_ClipWithPositiveY();
6490 if(RenderPolygon.NumberOfVertices<3) return;
6491 TexturedPolygon_ClipWithNegativeY();
6492 if(RenderPolygon.NumberOfVertices<3) return;
6493 TexturedPolygon_ClipWithPositiveX();
6494 if(RenderPolygon.NumberOfVertices<3) return;
6495 D3D_Particle_Output(&particle,RenderPolygon.Vertices);
6496
6497 }
6498 else D3D_Particle_Output(&particle,VerticesBuffer);
6499 }
6500 }
6501 }
6502
6503 #if VOLUMETRIC_FOG
6504
FogValue(VECTORCH * vertexPtr)6505 int FogValue(VECTORCH *vertexPtr)
6506 {
6507 float a,b,c,d, lMax,lMin;
6508 VECTORCHF v;
6509 v.vx = vertexPtr->vx;
6510 v.vy = vertexPtr->vy;
6511 v.vz = vertexPtr->vz;
6512
6513 a = (v.vx*v.vx + v.vy*v.vy + v.vz*v.vz)*2.0;
6514 b = -2.0*(v.vx*FogPosition.vx+v.vy*FogPosition.vy+v.vz*FogPosition.vz);
6515 {
6516 // float s = MUL_FIXED(GetSin(CloakingPhase&4095),GetSin(CloakingPhase&4095));
6517 c = FogMagnitude - 10000.0*10000.0;
6518 }
6519 d = b*b-2.0*a*c;
6520 if (d<0) return 0;
6521
6522 d = sqrt(d);
6523
6524 lMin = (-b-d)/(a);
6525 if (lMin>1.0) return 0;
6526
6527 lMax = (-b+d)/(a);
6528
6529 if (lMax<0.0)
6530 {
6531 return 0;
6532 }
6533 else if (lMax>1.0)
6534 {
6535 if (lMin>0.0)
6536 {
6537 float m;
6538 int f;
6539 m = Approximate3dMagnitude(vertexPtr);
6540 f2i(f,(lMax-lMin)*m);
6541 return f;
6542 }
6543 else return Approximate3dMagnitude(vertexPtr);
6544 }
6545 else //(lMax<1.0)
6546 {
6547 if (lMin>0.0)
6548 {
6549 float m;
6550 int f;
6551 m = Approximate3dMagnitude(vertexPtr);
6552 f2i(f,(lMax-lMin)*m);
6553 return f;
6554 }
6555 else
6556 {
6557 float m;
6558 int f;
6559 m = Approximate3dMagnitude(vertexPtr);
6560 f2i(f,(lMax)*m);
6561 return f;
6562 }
6563
6564 }
6565 }
6566 #endif
6567 #if 0
6568 int SphereGenerated=0;
6569 void RenderSphere(void)
6570 {
6571 if(!SphereGenerated)
6572 {
6573 Generate_Sphere();
6574 SphereGenerated=1;
6575 }
6576 // EvolveSphere();
6577 {
6578 int f;
6579 POLYHEADER fakeHeader;
6580 MATRIXCH mat = (Global_VDB_Ptr->VDB_Mat);
6581 VECTORCH *vSphere = SphereRotatedVertex;
6582 VECTORCH *v2 = SphereAtmosRotatedVertex;
6583 VECTORCH d;
6584 {
6585 fakeHeader.PolyFlags = 0;
6586 RenderPolygon.TranslucencyMode = TRANSLUCENCY_OFF;
6587 }
6588 {
6589 MATRIXCH m2;
6590 EULER e;
6591 e.EulerX =0;
6592 e.EulerY =(CloakingPhase/32)&4095;
6593 e.EulerZ =0;
6594 CreateEulerMatrix(&e,&m2);
6595 TransposeMatrixCH(&m2);
6596 MatrixMultiply(&mat,&m2,&mat);
6597 d.vx = -3316 - Global_VDB_Ptr->VDB_World.vx;
6598 d.vy = -50000 -Global_VDB_Ptr->VDB_World.vy;
6599 d.vz = 26926 -Global_VDB_Ptr->VDB_World.vz;
6600
6601 RotateVector(&d,&(Global_VDB_Ptr->VDB_Mat));
6602
6603 }
6604 for (f=0; f<SPHERE_VERTICES; f++)
6605 {
6606
6607 int h = SphereVertexHeight[f];
6608 int radius = 4096;
6609 if (h>0) radius += h;
6610 *vSphere = SphereVertex[f];
6611
6612 RotateVector(vSphere,&mat);
6613 v2->vx = MUL_FIXED(vSphere->vx,4096+300);
6614 v2->vy = MUL_FIXED(vSphere->vy,4096+300);
6615 v2->vz = MUL_FIXED(vSphere->vz,4096+300);
6616 v2++;
6617 vSphere->vx = MUL_FIXED(vSphere->vx,radius);
6618 vSphere->vy = MUL_FIXED(vSphere->vy,radius);
6619 vSphere->vz = MUL_FIXED(vSphere->vz,radius);
6620 vSphere++;
6621 }
6622 #if 0
6623 for (f=0; f<SPHERE_FACES; f++)
6624 {
6625 {
6626 int i;
6627 VECTORCH v[3];
6628
6629 {
6630 int facingAway=1;
6631 for (i=0; i<3; i++)
6632 {
6633 int n = SphereFace[f].v[i];
6634 v[i] = SphereRotatedVertex[n];
6635 if (v[i].vz<=0) facingAway=0;
6636 }
6637 if(facingAway) continue;
6638 }
6639 for (i=0; i<3; i++)
6640 {
6641 int n = SphereFace[f].v[i];
6642 int l = (v[i].vx*16+ONE_FIXED)/2;
6643 int h = SphereVertexHeight[n];
6644 if (l>ONE_FIXED) l = ONE_FIXED;
6645 if (l<0) l = 0;
6646
6647 v[i].vx += d.vx;
6648 v[i].vy += d.vy;
6649 v[i].vz += d.vz;
6650 v[i].vy = MUL_FIXED(v[i].vy,87381);
6651
6652 VerticesBuffer[i].X = v[i].vx;
6653 VerticesBuffer[i].Y = v[i].vy;
6654 VerticesBuffer[i].Z = v[i].vz;
6655
6656 VerticesBuffer[i].A = 0;
6657 if (h<=0)
6658 {
6659 VerticesBuffer[i].R = 0;
6660 VerticesBuffer[i].G = 255+h;
6661 VerticesBuffer[i].B = 255;
6662 }
6663 else if (h>128)
6664 {
6665 VerticesBuffer[i].R = MUL_FIXED(255,h*256);
6666 VerticesBuffer[i].G = MUL_FIXED(200,h*256);
6667 VerticesBuffer[i].B = MUL_FIXED(150,h*256);
6668 }
6669 else
6670 {
6671 VerticesBuffer[i].R = 0;
6672 VerticesBuffer[i].G = 96-h/2;
6673 VerticesBuffer[i].B = 0;
6674 }
6675 VerticesBuffer[i].R = MUL_FIXED(VerticesBuffer[i].R,l);
6676 VerticesBuffer[i].G = MUL_FIXED(VerticesBuffer[i].G,l);
6677 VerticesBuffer[i].B = MUL_FIXED(VerticesBuffer[i].B,l);
6678 }
6679 RenderPolygon.NumberOfVertices=3;
6680 }
6681
6682 GouraudPolygon_ClipWithZ();
6683 if(RenderPolygon.NumberOfVertices>=3)
6684 {
6685 GouraudPolygon_ClipWithNegativeX();
6686 if(RenderPolygon.NumberOfVertices>=3)
6687 {
6688 GouraudPolygon_ClipWithPositiveY();
6689 if(RenderPolygon.NumberOfVertices>=3)
6690 {
6691 GouraudPolygon_ClipWithNegativeY();
6692 if(RenderPolygon.NumberOfVertices>=3)
6693 {
6694 GouraudPolygon_ClipWithPositiveX();
6695 if(RenderPolygon.NumberOfVertices>=3)
6696 {
6697 D3D_ZBufferedGouraudPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
6698 }
6699 }
6700 }
6701 }
6702 }
6703
6704 }
6705 #endif
6706 {
6707 extern int CloudyImageNumber;
6708 fakeHeader.PolyFlags = iflag_transparent;
6709 fakeHeader.PolyColour = CloudyImageNumber;
6710 RenderPolygon.TranslucencyMode = TRANSLUCENCY_OFF;
6711 }
6712 for (f=0; f<SPHERE_FACES; f++)
6713 {
6714 {
6715 int i;
6716 VECTORCH vertex[3];
6717
6718 {
6719 int facingAway=1;
6720 for (i=0; i<3; i++)
6721 {
6722 int n = SphereFace[f].v[i];
6723 vertex[i] = SphereAtmosRotatedVertex[n];
6724 if (vertex[i].vz<=0) facingAway=0;
6725 }
6726 if(facingAway) continue;
6727 }
6728 for (i=0; i<3; i++)
6729 {
6730 int n = SphereFace[f].v[i];
6731 int l = (vertex[i].vx*16+ONE_FIXED)/514;
6732 if (l>ONE_FIXED) l = ONE_FIXED;
6733 if (l<0) l = 0;
6734
6735 vertex[i].vx += d.vx;
6736 vertex[i].vy += d.vy;
6737 vertex[i].vz += d.vz;
6738 vertex[i].vy = MUL_FIXED(vertex[i].vy,87381);
6739
6740 VerticesBuffer[i].X = vertex[i].vx;
6741 VerticesBuffer[i].Y = vertex[i].vy;
6742 VerticesBuffer[i].Z = vertex[i].vz;
6743 VerticesBuffer[i].U = SphereAtmosU[n];//+u[0];
6744 VerticesBuffer[i].V = SphereAtmosV[n];//+v[0];
6745
6746 VerticesBuffer[i].A = 255;
6747 VerticesBuffer[i].R = l;
6748 VerticesBuffer[i].G = l/2;
6749 VerticesBuffer[i].B = 0;
6750 VerticesBuffer[i].SpecularR = 0;
6751 VerticesBuffer[i].SpecularG = 0;
6752 VerticesBuffer[i].SpecularB = 0;
6753 }
6754 RenderPolygon.NumberOfVertices=3;
6755 }
6756
6757 GouraudTexturedPolygon_ClipWithZ();
6758 if(RenderPolygon.NumberOfVertices>=3)
6759 {
6760 GouraudTexturedPolygon_ClipWithNegativeX();
6761 if(RenderPolygon.NumberOfVertices>=3)
6762 {
6763 GouraudTexturedPolygon_ClipWithPositiveY();
6764 if(RenderPolygon.NumberOfVertices>=3)
6765 {
6766 GouraudTexturedPolygon_ClipWithNegativeY();
6767 if(RenderPolygon.NumberOfVertices>=3)
6768 {
6769 GouraudTexturedPolygon_ClipWithPositiveX();
6770 if(RenderPolygon.NumberOfVertices>=3)
6771 {
6772 D3D_ZBufferedGouraudTexturedPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
6773 }
6774 }
6775 }
6776 }
6777 }
6778 }
6779 }
6780
6781 }
6782 void RenderBoom(void)
6783 {
6784 VECTORCH d;
6785 if(!SphereGenerated)
6786 {
6787 Generate_Sphere();
6788 SphereGenerated=1;
6789 }
6790 d.vx = 0;
6791 d.vy = 0;
6792 d.vz = 0;
6793
6794 RenderBoomSphere(&d,4096);
6795
6796 }
6797 void RenderBoomSphere(VECTORCH *position, int radius)
6798 {
6799 int Alpha[SPHERE_VERTICES];
6800 extern D3DTEXTUREHANDLE FMVTextureHandle[];
6801
6802 {
6803 int f;
6804 POLYHEADER fakeHeader;
6805 VECTORCH *vSphere = SphereRotatedVertex;
6806 static int o=0;
6807 o++;
6808
6809 {
6810 extern int CloudyImageNumber;
6811 fakeHeader.PolyFlags = iflag_transparent;
6812 fakeHeader.PolyColour = CloudyImageNumber;
6813 RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL;
6814 }
6815 for (f=0; f<SPHERE_VERTICES; f++)
6816 {
6817 int r;
6818 int t = GetSin((f+o+CloakingPhase/32)&4095);
6819 t = MUL_FIXED(t,t);
6820 t = MUL_FIXED(t,t);
6821 t = MUL_FIXED(t,t);
6822 // t = MUL_FIXED(t,t);
6823 // t = MUL_FIXED(t,t);
6824 t = MUL_FIXED(t,t);
6825 t = MUL_FIXED(t,t);
6826 t = MUL_FIXED(t,t);
6827 r = radius+MUL_FIXED(t,t)/128;
6828 Alpha[f] = (r-radius)/2;
6829
6830 *vSphere = SphereVertex[f];
6831
6832 vSphere->vx = MUL_FIXED(vSphere->vx,r);
6833 vSphere->vy = MUL_FIXED(vSphere->vy,r);
6834 vSphere->vz = MUL_FIXED(vSphere->vz,r);
6835
6836 vSphere->vx += position->vx;
6837 vSphere->vy += position->vy;
6838 vSphere->vz += position->vz;
6839 TranslatePointIntoViewspace(vSphere);
6840 vSphere++;
6841
6842 }
6843
6844 for (f=0; f<SPHERE_FACES; f++)
6845 {
6846 {
6847 int i;
6848 VECTORCH vertex[3];
6849
6850 {
6851 for (i=0; i<3; i++)
6852 {
6853 int n = SphereFace[f].v[i];
6854 vertex[i] = SphereRotatedVertex[n];
6855
6856 }
6857 }
6858 for (i=0; i<3; i++)
6859 {
6860 int n = SphereFace[f].v[i];
6861
6862 VerticesBuffer[i].X = vertex[i].vx;
6863 VerticesBuffer[i].Y = vertex[i].vy;
6864 VerticesBuffer[i].Z = vertex[i].vz;
6865
6866
6867 // SphereAtmosU[0]=(vertex[i].vx)*4*128+GetSin((CloakingPhase)&4095)*16;
6868 // SphereAtmosV[0]=(vertex[i].vy)*4*128+GetCos((CloakingPhase)&4095)*16;
6869 {
6870 int t = GetSin((CloakingPhase/20)&4095);
6871 int u;
6872
6873 u = t*(128);
6874 // SphereAtmosU[0]=MUL_FIXED(SphereAtmosU[0],u);
6875 // SphereAtmosV[0]=MUL_FIXED(SphereAtmosV[0],u);
6876 VerticesBuffer[i].U = (SphereAtmosU[n]+u);//+u[0];
6877 VerticesBuffer[i].V = (SphereAtmosV[n]);//+v[0];
6878 }
6879 {
6880 int d1 = VerticesBuffer[0].U-VerticesBuffer[1].U;
6881 int d2 = VerticesBuffer[0].U-VerticesBuffer[2].U;
6882 int d3 = VerticesBuffer[1].U-VerticesBuffer[2].U;
6883
6884 int ad1=d1,ad2=d2,ad3=d3;
6885 int i1=0,i2=0,i3=0;
6886
6887 if (ad1<0) ad1=-ad1;
6888 if (ad2<0) ad2=-ad2;
6889 if (ad3<0) ad3=-ad3;
6890
6891 if (ad1>(128*3+64)*65536)
6892 {
6893 if (d1>0) i2=1;
6894 else i1=1;
6895 }
6896 if (ad2>(128*3+64)*65536)
6897 {
6898 if (d2>0) i3=1;
6899 else i1=1;
6900 }
6901 if (ad3>(128*3+64)*65536)
6902 {
6903 if (d3>0) i3=1;
6904 else i2=1;
6905 }
6906
6907 if(i1) VerticesBuffer[0].U+=128*65536*4;
6908 if(i2) VerticesBuffer[1].U+=128*65536*4;
6909 if(i3) VerticesBuffer[2].U+=128*65536*4;
6910 }
6911
6912 VerticesBuffer[i].A = 128+Alpha[n];
6913 VerticesBuffer[i].R = 0;
6914 VerticesBuffer[i].G = 128;
6915 VerticesBuffer[i].B = 255;
6916 VerticesBuffer[i].SpecularR = 0;
6917 VerticesBuffer[i].SpecularG = 0;
6918 VerticesBuffer[i].SpecularB = 0;
6919 }
6920 RenderPolygon.NumberOfVertices=3;
6921 }
6922
6923 GouraudTexturedPolygon_ClipWithZ();
6924 if(RenderPolygon.NumberOfVertices>=3)
6925 {
6926 GouraudTexturedPolygon_ClipWithNegativeX();
6927 if(RenderPolygon.NumberOfVertices>=3)
6928 {
6929 GouraudTexturedPolygon_ClipWithPositiveY();
6930 if(RenderPolygon.NumberOfVertices>=3)
6931 {
6932 GouraudTexturedPolygon_ClipWithNegativeY();
6933 if(RenderPolygon.NumberOfVertices>=3)
6934 {
6935 GouraudTexturedPolygon_ClipWithPositiveX();
6936 if(RenderPolygon.NumberOfVertices>=3)
6937 {
6938 D3D_ZBufferedGouraudTexturedPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
6939 // D3D_FMVParticle_Output(RenderPolygon.Vertices);
6940 }
6941 }
6942 }
6943 }
6944 }
6945 }
6946 }
6947
6948 }
6949 #endif
6950
6951 int Alpha[SPHERE_VERTICES];
RenderExplosionSurface(VOLUMETRIC_EXPLOSION * explosionPtr)6952 void RenderExplosionSurface(VOLUMETRIC_EXPLOSION *explosionPtr)
6953 {
6954 int red,green,blue;
6955
6956 switch (CurrentVisionMode)
6957 {
6958 default:
6959 case VISION_MODE_NORMAL:
6960 {
6961 red = 255;
6962 green = 255;
6963 blue = 255;
6964 break;
6965 }
6966 case VISION_MODE_IMAGEINTENSIFIER:
6967 {
6968 red = 0;
6969 green = 255;
6970 blue = 0;
6971 break;
6972 }
6973 case VISION_MODE_PRED_THERMAL:
6974 case VISION_MODE_PRED_SEEALIENS:
6975 case VISION_MODE_PRED_SEEPREDTECH:
6976 {
6977 red = 255;
6978 green = 0;
6979 blue = 255;
6980 break;
6981 }
6982 }
6983 {
6984 int f;
6985 POLYHEADER fakeHeader;
6986 VECTORCH *vSphere = SphereRotatedVertex;
6987 static int o=0;
6988 o++;
6989
6990 if (explosionPtr->ExplosionPhase)
6991 {
6992 extern int BurningImageNumber;
6993 fakeHeader.PolyFlags = iflag_transparent;
6994 fakeHeader.PolyColour = BurningImageNumber;
6995 RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL;
6996 }
6997 else
6998 {
6999 extern int CloudyImageNumber;
7000 fakeHeader.PolyFlags = iflag_transparent;
7001 fakeHeader.PolyColour = CloudyImageNumber;
7002 RenderPolygon.TranslucencyMode = TRANSLUCENCY_INVCOLOUR;
7003 red = explosionPtr->LifeTime/256;
7004 green = explosionPtr->LifeTime/256;
7005 blue = explosionPtr->LifeTime/256;
7006 }
7007
7008 for (f=0; f<SPHERE_VERTICES; f++)
7009 {
7010 *vSphere = explosionPtr->Position[f];
7011
7012 TranslatePointIntoViewspace(vSphere);
7013 vSphere++;
7014 }
7015
7016 for (f=0; f<SPHERE_FACES; f++)
7017 {
7018 {
7019 int i;
7020 VECTORCH vertex[3];
7021
7022 {
7023 for (i=0; i<3; i++)
7024 {
7025 int n = SphereFace[f].v[i];
7026 vertex[i] = SphereRotatedVertex[n];
7027
7028 }
7029 }
7030 for (i=0; i<3; i++)
7031 {
7032 int n = SphereFace[f].v[i];
7033
7034 VerticesBuffer[i].X = vertex[i].vx;
7035 VerticesBuffer[i].Y = vertex[i].vy;
7036 VerticesBuffer[i].Z = vertex[i].vz;
7037
7038
7039 // SphereAtmosU[0]=(vertex[i].vx)*4*128+GetSin((CloakingPhase)&4095)*16;
7040 // SphereAtmosV[0]=(vertex[i].vy)*4*128+GetCos((CloakingPhase)&4095)*16;
7041 {
7042 int u = -(ONE_FIXED-explosionPtr->LifeTime)*128*2;
7043 // SphereAtmosU[0]=MUL_FIXED(SphereAtmosU[0],u);
7044 // SphereAtmosV[0]=MUL_FIXED(SphereAtmosV[0],u);
7045 VerticesBuffer[i].U = (SphereAtmosU[n]);//+u[0];
7046 VerticesBuffer[i].V = (SphereAtmosV[n]+u);//+v[0];
7047 }
7048 {
7049 int d1 = VerticesBuffer[0].U-VerticesBuffer[1].U;
7050 int d2 = VerticesBuffer[0].U-VerticesBuffer[2].U;
7051 int d3 = VerticesBuffer[1].U-VerticesBuffer[2].U;
7052
7053 int ad1=d1,ad2=d2,ad3=d3;
7054 int i1=0,i2=0,i3=0;
7055
7056 if (ad1<0) ad1=-ad1;
7057 if (ad2<0) ad2=-ad2;
7058 if (ad3<0) ad3=-ad3;
7059
7060 if (ad1>(128*(SPHERE_TEXTURE_WRAP-1)+64)*65536)
7061 {
7062 if (d1>0) i2=1;
7063 else i1=1;
7064 }
7065 if (ad2>(128*(SPHERE_TEXTURE_WRAP-1)+64)*65536)
7066 {
7067 if (d2>0) i3=1;
7068 else i1=1;
7069 }
7070 if (ad3>(128*(SPHERE_TEXTURE_WRAP-1)+64)*65536)
7071 {
7072 if (d3>0) i3=1;
7073 else i2=1;
7074 }
7075
7076 if(i1) VerticesBuffer[0].U+=128*65536*SPHERE_TEXTURE_WRAP;
7077 if(i2) VerticesBuffer[1].U+=128*65536*SPHERE_TEXTURE_WRAP;
7078 if(i3) VerticesBuffer[2].U+=128*65536*SPHERE_TEXTURE_WRAP;
7079 }
7080
7081 VerticesBuffer[i].A = explosionPtr->LifeTime/256;
7082 VerticesBuffer[i].R = red;
7083 VerticesBuffer[i].G = green;
7084 VerticesBuffer[i].B = blue;
7085 VerticesBuffer[i].SpecularR = 0;
7086 VerticesBuffer[i].SpecularG = 0;
7087 VerticesBuffer[i].SpecularB = 0;
7088
7089 }
7090 RenderPolygon.NumberOfVertices=3;
7091 }
7092
7093 GouraudTexturedPolygon_ClipWithZ();
7094 if(RenderPolygon.NumberOfVertices>=3)
7095 {
7096 GouraudTexturedPolygon_ClipWithNegativeX();
7097 if(RenderPolygon.NumberOfVertices>=3)
7098 {
7099 GouraudTexturedPolygon_ClipWithPositiveY();
7100 if(RenderPolygon.NumberOfVertices>=3)
7101 {
7102 GouraudTexturedPolygon_ClipWithNegativeY();
7103 if(RenderPolygon.NumberOfVertices>=3)
7104 {
7105 GouraudTexturedPolygon_ClipWithPositiveX();
7106 if(RenderPolygon.NumberOfVertices>=3)
7107 {
7108 D3D_ZBufferedGouraudTexturedPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
7109 // D3D_FMVParticle_Output(RenderPolygon.Vertices);
7110 }
7111 }
7112 }
7113 }
7114 }
7115 }
7116 }
7117 }
RenderInsideAlienTongue(int offset)7118 void RenderInsideAlienTongue(int offset)
7119 {
7120 #define TONGUE_SCALE 1024
7121 int TonguePolyVertexList[4][4] =
7122 {
7123 {0,3,7,4}, //+ve y
7124 {1,2,3,0}, //+ve x
7125 {5,6,7,4}, //-ve x
7126 {1,2,6,5}, //-ve y
7127 };
7128 VECTORCH vertices[8]=
7129 {
7130 {+TONGUE_SCALE,-TONGUE_SCALE,0},
7131 {+TONGUE_SCALE,+TONGUE_SCALE,0},
7132 {+TONGUE_SCALE,+TONGUE_SCALE,+TONGUE_SCALE*4},
7133 {+TONGUE_SCALE,-TONGUE_SCALE,+TONGUE_SCALE*4},
7134
7135 {-TONGUE_SCALE,-TONGUE_SCALE,0},
7136 {-TONGUE_SCALE,+TONGUE_SCALE,0},
7137 {-TONGUE_SCALE,+TONGUE_SCALE,+TONGUE_SCALE*4},
7138 {-TONGUE_SCALE,-TONGUE_SCALE,+TONGUE_SCALE*4},
7139 };
7140 VECTORCH translatedPts[8];
7141
7142 POLYHEADER fakeHeader;
7143 int polyNumber;
7144
7145 #if 1
7146 {
7147
7148 int i = 7;
7149 do
7150 {
7151 translatedPts[i] = vertices[i];
7152 translatedPts[i].vz -= (ONE_FIXED-offset)/16;
7153 // TranslatePointIntoViewspace(&translatedPts[i]);
7154 }
7155 while(i--);
7156 }
7157 #endif
7158 {
7159 extern int AlienTongueImageNumber;
7160 fakeHeader.PolyFlags = 0;
7161 fakeHeader.PolyColour = AlienTongueImageNumber;
7162 RenderPolygon.TranslucencyMode = TRANSLUCENCY_GLOWING;
7163 }
7164
7165 for(polyNumber=0; polyNumber<4; polyNumber++)
7166 {
7167 {
7168 int i;
7169 for (i=0; i<4; i++)
7170 {
7171 int v = TonguePolyVertexList[polyNumber][i];
7172 VerticesBuffer[i].A = 255;
7173 VerticesBuffer[i].X = translatedPts[v].vx;
7174 VerticesBuffer[i].Y = translatedPts[v].vy;
7175 VerticesBuffer[i].Z = translatedPts[v].vz;
7176 VerticesBuffer[i].U = CuboidPolyVertexU[3][i]<<16;
7177 VerticesBuffer[i].V = CuboidPolyVertexV[3][i]<<16;
7178
7179
7180 VerticesBuffer[i].R = offset/2048;
7181 VerticesBuffer[i].G = offset/2048;
7182 VerticesBuffer[i].B = offset/2048;
7183 VerticesBuffer[i].SpecularR = 0;
7184 VerticesBuffer[i].SpecularG = 0;
7185 VerticesBuffer[i].SpecularB = 0;
7186
7187 }
7188 RenderPolygon.NumberOfVertices=4;
7189 }
7190 {
7191 GouraudTexturedPolygon_ClipWithZ();
7192 if(RenderPolygon.NumberOfVertices<3) continue;
7193 GouraudTexturedPolygon_ClipWithNegativeX();
7194 if(RenderPolygon.NumberOfVertices<3) continue;
7195 GouraudTexturedPolygon_ClipWithPositiveY();
7196 if(RenderPolygon.NumberOfVertices<3) continue;
7197 GouraudTexturedPolygon_ClipWithNegativeY();
7198 if(RenderPolygon.NumberOfVertices<3) continue;
7199 GouraudTexturedPolygon_ClipWithPositiveX();
7200 if(RenderPolygon.NumberOfVertices<3) continue;
7201 D3D_ZBufferedGouraudTexturedPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
7202
7203 }
7204 }
7205 }
7206
7207
7208
7209 #define NO_OF_STARS 500
7210 typedef struct
7211 {
7212 VECTORCH Position;
7213 int Colour;
7214 int Frequency;
7215 int Phase;
7216
7217 } STARDESC;
7218 static STARDESC StarArray[NO_OF_STARS];
7219
CreateStarArray(void)7220 void CreateStarArray(void)
7221 {
7222 int i;
7223
7224 SetSeededFastRandom(FastRandom());
7225 for (i=0; i<NO_OF_STARS; i++)
7226 {
7227 int phi = SeededFastRandom()&4095;
7228
7229 StarArray[i].Position.vy = ONE_FIXED-(SeededFastRandom()&131071);
7230 {
7231 float y = ((float)StarArray[i].Position.vy)/65536.0;
7232 y = sqrt(1-y*y);
7233
7234 f2i(StarArray[i].Position.vx,(float)GetCos(phi)*y);
7235 f2i(StarArray[i].Position.vz,(float)GetSin(phi)*y);
7236 }
7237 StarArray[i].Colour = 0xff000000 + (FastRandom()&0x7f7f7f)+0x7f7f7f;
7238 StarArray[i].Frequency = (FastRandom()&4095);
7239 StarArray[i].Phase = FastRandom()&4095;
7240 }
7241 }
7242
RenderStarfield(void)7243 void RenderStarfield(void)
7244 {
7245 int i;
7246
7247 int sizeX;
7248 int sizeY;
7249
7250 #if 0
7251 sizeX = GetSin((MUL_FIXED(CloakingPhase,StarArray[i].Frequency)+StarArray[i].Phase)&4095);
7252 sizeX = MUL_FIXED(sizeX,sizeX)/1024+256;
7253 #else
7254 sizeX = 256;
7255 #endif
7256
7257 sizeY = MUL_FIXED(sizeX,87381);
7258
7259 for (i=0; i<NO_OF_STARS; i++)
7260 {
7261 VECTORCH position = StarArray[i].Position;
7262 PARTICLE particle;
7263 particle.ParticleID = PARTICLE_STAR;
7264 particle.Colour = StarArray[i].Colour;
7265 #if 1
7266 position.vx += Global_VDB_Ptr->VDB_World.vx;
7267 position.vy += Global_VDB_Ptr->VDB_World.vy;
7268 position.vz += Global_VDB_Ptr->VDB_World.vz;
7269
7270 TranslatePointIntoViewspace(&position);
7271 #endif
7272 // RotateVector(&position,&(Global_VDB_Ptr->VDB_Mat));
7273
7274
7275 VerticesBuffer[0].X = position.vx - sizeX;
7276 VerticesBuffer[0].Y = position.vy - sizeY;
7277 VerticesBuffer[0].Z = position.vz;
7278 VerticesBuffer[1].X = position.vx + sizeX;
7279 VerticesBuffer[1].Y = position.vy - sizeY;
7280 VerticesBuffer[1].Z = position.vz;
7281 VerticesBuffer[2].X = position.vx + sizeX;
7282 VerticesBuffer[2].Y = position.vy + sizeY;
7283 VerticesBuffer[2].Z = position.vz;
7284 VerticesBuffer[3].X = position.vx - sizeX;
7285 VerticesBuffer[3].Y = position.vy + sizeY;
7286 VerticesBuffer[3].Z = position.vz;
7287
7288 {
7289 int outcode = QuadWithinFrustrum();
7290
7291 if (outcode)
7292 {
7293 RenderPolygon.NumberOfVertices=4;
7294
7295 // textprint("On Screen!\n");
7296 VerticesBuffer[0].U = 192<<16;
7297 VerticesBuffer[0].V = 0;
7298
7299 VerticesBuffer[1].U = 255<<16;
7300 VerticesBuffer[1].V = 0;
7301
7302 VerticesBuffer[2].U = 255<<16;
7303 VerticesBuffer[2].V = 63<<16;
7304
7305 VerticesBuffer[3].U = 192<<16;
7306 VerticesBuffer[3].V = 63<<16;
7307
7308 if (outcode!=2)
7309 {
7310 TexturedPolygon_ClipWithZ();
7311 if(RenderPolygon.NumberOfVertices<3) return;
7312 TexturedPolygon_ClipWithNegativeX();
7313 if(RenderPolygon.NumberOfVertices<3) return;
7314 TexturedPolygon_ClipWithPositiveY();
7315 if(RenderPolygon.NumberOfVertices<3) return;
7316 TexturedPolygon_ClipWithNegativeY();
7317 if(RenderPolygon.NumberOfVertices<3) return;
7318 TexturedPolygon_ClipWithPositiveX();
7319 if(RenderPolygon.NumberOfVertices<3) return;
7320 D3D_Particle_Output(&particle,RenderPolygon.Vertices);
7321
7322 }
7323 else D3D_Particle_Output(&particle,VerticesBuffer);
7324 }
7325 }
7326 }
7327 }
7328