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, &LToVMat_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, &LToVMat_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, &LToVMat_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, &LToVMat);
3933 	MatrixToEuler(&LToVMat, &LToVMat_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&section_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, &LToVMat);
4268 	MatrixToEuler(&LToVMat, &LToVMat_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(&LToVMat);
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