1 #include "3dc.h"
2 
3 #include "inline.h"
4 #include "module.h"
5 #include "gamedef.h"
6 #include "stratdef.h"
7 #include "dynblock.h"
8 #include "bh_types.h"
9 #include "avpview.h"
10 #include "opengl.h"
11 
12 #include "kshape.h"
13 #include "kzsort.h"
14 #include "frustum.h"
15 #include "vision.h"
16 #include "lighting.h"
17 #include "weapons.h"
18 #include "sfx.h"
19 #include "fmv.h"
20 /* character extents data so you know where the player's eyes are */
21 #include "extents.h"
22 #include "avp_userprofile.h"
23 
24 #define UseLocalAssert Yes
25 #include "ourasert.h"
26 
27 /* KJL 13:59:05 04/19/97 - avpview.c
28  *
29  *	This is intended to be an AvP-specific streamlined version of view.c.
30  */
31 
32 extern void AllNewModuleHandler(void);
33 extern SCREENDESCRIPTORBLOCK ScreenDescriptorBlock;
34 
35 DISPLAYBLOCK *OnScreenBlockList[maxobjects];
36 int NumOnScreenBlocks;
37 
38 extern DISPLAYBLOCK *ActiveBlockList[];
39 extern int NumActiveBlocks;
40 
41 extern int ScanDrawMode;
42 /* JH 13/5/97 */
43 extern int DrawMode;
44 extern int ZBufferMode;
45 
46 //extern DPID MultiplayerObservedPlayer;
47 extern int MultiplayerObservedPlayer;
48 
49 #if SupportMorphing
50 MORPHDISPLAY MorphDisplay;
51 #endif
52 
53 #if SupportModules
54 SCENEMODULE **Global_ModulePtr = 0;
55 MODULE *Global_MotherModule;
56 char *ModuleCurrVisArray = 0;
57 char *ModulePrevVisArray = 0;
58 char *ModuleTempArray = 0;
59 char *ModuleLocalVisArray = 0;
60 int ModuleArraySize = 0;
61 #endif
62 
63 /* KJL 11:12:10 06/06/97 - orientation */
64 MATRIXCH LToVMat;
65 EULER LToVMat_Euler;
66 MATRIXCH WToLMat = {1,};
67 VECTORCH LocalView;
68 
69 /* KJL 11:16:37 06/06/97 - lights */
70 VECTORCH LocalLightCH;
71 int NumLightSourcesForObject;
72 LIGHTBLOCK *LightSourcesForObject[MaxLightsPerObject];
73 int GlobalAmbience;
74 int LightScale=ONE_FIXED;
75 int DrawingAReflection;
76 
77 int *Global_ShapePoints;
78 int **Global_ShapeItems;
79 int *Global_ShapeNormals;
80 int *Global_ShapeVNormals;
81 int **Global_ShapeTextures;
82 VIEWDESCRIPTORBLOCK *Global_VDB_Ptr;
83 DISPLAYBLOCK *Global_ODB_Ptr;
84 SHAPEHEADER *Global_ShapeHeaderPtr;
85 EXTRAITEMDATA *Global_EID_Ptr;
86 int *Global_EID_IPtr;
87 
88 
89 extern float CameraZoomScale;
90 extern int CameraZoomLevel;
91 int AlienBiteAttackInProgress;
92 
93 /* phase for cloaked objects */
94 int CloakingPhase;
95 extern int NormalFrameTime;
96 
97 int LeanScale;
98 EULER deathTargetOrientation={0,0,0};
99 
100 extern int GetSingleColourForPrimary(int Colour);
101 extern void ColourFillBackBuffer(int FillColour);
102 
103 static void ModifyHeadOrientation(void);
104 int AVPViewVolumePlaneTest(CLIPPLANEBLOCK *cpb, DISPLAYBLOCK *dblockptr, int obr);
105 
106 
107 
UpdateRunTimeLights(void)108 void UpdateRunTimeLights(void)
109 {
110 	extern int NumActiveBlocks;
111 	extern DISPLAYBLOCK *ActiveBlockList[];
112 	int numberOfObjects = NumActiveBlocks;
113 
114 	while (numberOfObjects--)
115 	{
116 		DISPLAYBLOCK *dispPtr = ActiveBlockList[numberOfObjects];
117 
118 		if( (dispPtr->SpecialFXFlags & SFXFLAG_ONFIRE)
119 		  ||((dispPtr->ObStrategyBlock)&&(dispPtr->ObStrategyBlock->SBDamageBlock.IsOnFire)) )
120 			AddLightingEffectToObject(dispPtr,LFX_OBJECTONFIRE);
121 
122 		UpdateObjectLights(dispPtr);
123 	}
124 
125 	HandleLightElementSystem();
126 }
LightSourcesInRangeOfObject(DISPLAYBLOCK * dptr)127 void LightSourcesInRangeOfObject(DISPLAYBLOCK *dptr)
128 {
129 
130 	DISPLAYBLOCK **aptr;
131 	DISPLAYBLOCK *dptr2;
132 	LIGHTBLOCK *lptr;
133 	VECTORCH llocal;
134 	int i, j;
135 
136 
137 	aptr = ActiveBlockList;
138 
139 
140 	NumLightSourcesForObject = 0;
141 
142 
143 	/*
144 
145 	Light Sources attached to other objects
146 
147 	*/
148 
149 	for(i = NumActiveBlocks;
150 		i!=0 && NumLightSourcesForObject < MaxLightsPerObject; i--) {
151 
152 		dptr2 = *aptr++;
153 
154 		if(dptr2->ObNumLights) {
155 
156 			for(j = 0; j < dptr2->ObNumLights
157 				&& NumLightSourcesForObject < MaxLightsPerObject; j++) {
158 
159 				lptr = dptr2->ObLights[j];
160 
161 				if (!lptr->LightBright || !(lptr->RedScale||lptr->GreenScale||lptr->BlueScale))
162 				{
163 					 continue;
164 				}
165 
166 				if ((CurrentVisionMode == VISION_MODE_IMAGEINTENSIFIER) && (lptr->LightFlags & LFlag_PreLitSource))
167 					 continue;
168 //				lptr->LightFlags |= LFlag_NoSpecular;
169 
170 		   		if(!(dptr->ObFlags3 & ObFlag3_PreLit &&
171 					lptr->LightFlags & LFlag_PreLitSource))
172 				{
173 					{
174 						VECTORCH vertexToLight;
175 						int distanceToLight;
176 
177 						if (DrawingAReflection)
178 						{
179 							vertexToLight.vx = (MirroringAxis - lptr->LightWorld.vx) - dptr->ObWorld.vx;
180 						}
181 						else
182 						{
183 							vertexToLight.vx = lptr->LightWorld.vx - dptr->ObWorld.vx;
184 						}
185 						vertexToLight.vy = lptr->LightWorld.vy - dptr->ObWorld.vy;
186 						vertexToLight.vz = lptr->LightWorld.vz - dptr->ObWorld.vz;
187 
188 						distanceToLight = Approximate3dMagnitude(&vertexToLight);
189 
190 						#if 0
191 						if (CurrentVisionMode == VISION_MODE_IMAGEINTENSIFIER)
192 							distanceToLight /= 2;
193 						#endif
194 
195 						if(distanceToLight < (lptr->LightRange + dptr->ObRadius) )
196 						{
197 
198 							LightSourcesForObject[NumLightSourcesForObject] = lptr;
199 							NumLightSourcesForObject++;
200 
201 							/* Transform the light position to local space */
202 
203 							llocal = vertexToLight;
204 
205 							RotateAndCopyVector(&llocal, &lptr->LocalLP, &WToLMat);
206 
207 						}
208 
209 
210 					}
211 
212 				}
213 
214 			}
215 
216 		}
217 
218 	}
219 
220 	{
221 		extern LIGHTELEMENT LightElementStorage[];
222 		extern int NumActiveLightElements;
223 		int i = NumActiveLightElements;
224 		LIGHTELEMENT *lightElementPtr = LightElementStorage;
225 		while(i--)
226 		{
227 			LIGHTBLOCK *lptr = &(lightElementPtr->LightBlock);
228 			VECTORCH vertexToLight;
229 			int distanceToLight;
230 
231 			vertexToLight.vx = lptr->LightWorld.vx - dptr->ObWorld.vx;
232 			vertexToLight.vy = lptr->LightWorld.vy - dptr->ObWorld.vy;
233 			vertexToLight.vz = lptr->LightWorld.vz - dptr->ObWorld.vz;
234 
235 			distanceToLight = Approximate3dMagnitude(&vertexToLight);
236 
237 			#if 0
238 			if (CurrentVisionMode == VISION_MODE_IMAGEINTENSIFIER)
239 				distanceToLight /= 2;
240 			#endif
241 
242 			if(distanceToLight < (lptr->LightRange + dptr->ObRadius) )
243 			{
244 
245 				LightSourcesForObject[NumLightSourcesForObject] = lptr;
246 				NumLightSourcesForObject++;
247 
248 				/* Transform the light position to local space */
249 				llocal = vertexToLight;
250 				RotateAndCopyVector(&llocal, &lptr->LocalLP, &WToLMat);
251 
252 			}
253 
254 			lightElementPtr++;
255 		}
256 	}
257 }
258 
LightIntensityAtPoint(VECTORCH * pointPtr)259 int LightIntensityAtPoint(VECTORCH *pointPtr)
260 {
261 	int intensity = 0;
262 	int i, j;
263 
264 	DISPLAYBLOCK **activeBlockListPtr = ActiveBlockList;
265 	for(i = NumActiveBlocks; i != 0; i--) {
266 		DISPLAYBLOCK *dispPtr = *activeBlockListPtr++;
267 
268 		if (dispPtr->ObNumLights) {
269 			for(j = 0; j < dispPtr->ObNumLights; j++) {
270 				LIGHTBLOCK *lptr = dispPtr->ObLights[j];
271 				VECTORCH disp = lptr->LightWorld;
272 				int dist;
273 
274 				disp.vx -= pointPtr->vx;
275 				disp.vy -= pointPtr->vy;
276 				disp.vz -= pointPtr->vz;
277 
278 				dist = Approximate3dMagnitude(&disp);
279 
280 				if (dist<lptr->LightRange) {
281 					intensity += WideMulNarrowDiv(lptr->LightBright,lptr->LightRange-dist,lptr->LightRange);
282 				}
283 			}
284 		}
285 	}
286 	if (intensity>ONE_FIXED) intensity=ONE_FIXED;
287 	else if (intensity<GlobalAmbience) intensity=GlobalAmbience;
288 
289 	/* KJL 20:31:39 12/1/97 - limit how dark things can be so blood doesn't go green */
290 	if (intensity<10*256) intensity = 10*256;
291 
292 	return intensity;
293 }
294 
295 EULER HeadOrientation = {0,0,0};
296 
ModifyHeadOrientation(void)297 static void ModifyHeadOrientation(void)
298 {
299 	extern int NormalFrameTime;
300 	#define TILT_THRESHOLD 128
301 	PLAYER_STATUS *playerStatusPtr;
302 
303 	/* get the player status block ... */
304 	playerStatusPtr = (PLAYER_STATUS *) (Player->ObStrategyBlock->SBdataptr);
305     GLOBALASSERT(playerStatusPtr);
306 
307     if (!playerStatusPtr->IsAlive && !MultiplayerObservedPlayer)
308 	{
309 		int decay = NormalFrameTime>>6;
310 
311 		HeadOrientation.EulerX &= 4095;
312 	   	HeadOrientation.EulerX -= decay;
313 		if(HeadOrientation.EulerX < 3072)
314 			HeadOrientation.EulerX = 3072;
315 
316 	}
317 	else
318 	{
319 		int decay = NormalFrameTime>>8;
320 		if(HeadOrientation.EulerX > 2048)
321 		{
322 			if (HeadOrientation.EulerX < 4096 - TILT_THRESHOLD)
323 				HeadOrientation.EulerX = 4096 - TILT_THRESHOLD;
324 
325 		   	HeadOrientation.EulerX += decay;
326 			if(HeadOrientation.EulerX > 4095)
327 				HeadOrientation.EulerX =0;
328 		}
329 		else
330 		{
331 			if (HeadOrientation.EulerX > TILT_THRESHOLD)
332 				HeadOrientation.EulerX = TILT_THRESHOLD;
333 
334 		   	HeadOrientation.EulerX -= decay;
335 			if(HeadOrientation.EulerX < 0)
336 				HeadOrientation.EulerX =0;
337 		}
338 
339 		if(HeadOrientation.EulerY > 2048)
340 		{
341 			if (HeadOrientation.EulerY < 4096 - TILT_THRESHOLD)
342 				HeadOrientation.EulerY = 4096 - TILT_THRESHOLD;
343 
344 		   	HeadOrientation.EulerY += decay;
345 			if(HeadOrientation.EulerY > 4095)
346 				HeadOrientation.EulerY =0;
347 		}
348 		else
349 		{
350 			if (HeadOrientation.EulerY > TILT_THRESHOLD)
351 				HeadOrientation.EulerY = TILT_THRESHOLD;
352 
353 		   	HeadOrientation.EulerY -= decay;
354 			if(HeadOrientation.EulerY < 0)
355 				HeadOrientation.EulerY =0;
356 		}
357 
358 		if(HeadOrientation.EulerZ > 2048)
359 		{
360 			if (HeadOrientation.EulerZ < 4096 - TILT_THRESHOLD)
361 				HeadOrientation.EulerZ = 4096 - TILT_THRESHOLD;
362 
363 		   	HeadOrientation.EulerZ += decay;
364 			if(HeadOrientation.EulerZ > 4095)
365 				HeadOrientation.EulerZ =0;
366 		}
367 		else
368 		{
369 			if (HeadOrientation.EulerZ > TILT_THRESHOLD)
370 				HeadOrientation.EulerZ = TILT_THRESHOLD;
371 
372 		   	HeadOrientation.EulerZ -= decay;
373 			if(HeadOrientation.EulerZ < 0)
374 				HeadOrientation.EulerZ =0;
375 		}
376 	}
377 }
378 
InteriorType_Body()379 void InteriorType_Body()
380 {
381 	DISPLAYBLOCK *subjectPtr = Player;
382 	extern int NormalFrameTime;
383 
384 	static int verticalSpeed = 0;
385 	static int zAxisTilt=0;
386 	STRATEGYBLOCK *sbPtr;
387 	DYNAMICSBLOCK *dynPtr;
388 
389 	sbPtr = subjectPtr->ObStrategyBlock;
390 	LOCALASSERT(sbPtr);
391 	dynPtr = sbPtr->DynPtr;
392 	LOCALASSERT(dynPtr);
393 
394 	ModifyHeadOrientation();
395 	{
396 		/* eye offset */
397 		VECTORCH ioff;
398 		COLLISION_EXTENTS *extentsPtr = 0;
399 		PLAYER_STATUS *playerStatusPtr= (PLAYER_STATUS *) (sbPtr->SBdataptr);
400 
401 		switch(AvP.PlayerType)
402 		{
403 			case I_Marine:
404 				extentsPtr = &CollisionExtents[CE_MARINE];
405 				break;
406 
407 			case I_Alien:
408 				extentsPtr = &CollisionExtents[CE_ALIEN];
409 				break;
410 
411 			case I_Predator:
412 				extentsPtr = &CollisionExtents[CE_PREDATOR];
413 				break;
414 		}
415 
416 		/* set player state */
417 		if (playerStatusPtr->ShapeState == PMph_Standing)
418 		{
419 			ioff.vy = extentsPtr->StandingTop;
420 		}
421 		else
422 		{
423 			ioff.vy = extentsPtr->CrouchingTop;
424 		}
425 
426 		if (LANDOFTHEGIANTS_CHEATMODE)
427 		{
428 			ioff.vy/=4;
429 		}
430 		if (!playerStatusPtr->IsAlive && !MultiplayerObservedPlayer)
431 		{
432 			extern int deathFadeLevel;
433 
434 			ioff.vy = MUL_FIXED(deathFadeLevel*4-3*ONE_FIXED,ioff.vy);
435 
436 			if (ioff.vy>-100)
437 			{
438 				ioff.vy = -100;
439 			}
440 		}
441 
442 
443 		ioff.vx = 0;
444 		ioff.vz = 0;//-extentsPtr->CollisionRadius*2;
445 		ioff.vy += verticalSpeed/16+200;
446 
447 		RotateVector(&ioff, &subjectPtr->ObMat);
448 		AddVector(&ioff, &Global_VDB_Ptr->VDB_World);
449 
450 		#if 0
451 		{
452 			static int i=-10;
453 			i=-i;
454 			ioff.vx = MUL_FIXED(GetSin((CloakingPhase/5)&4095),i);
455 			ioff.vy = MUL_FIXED(GetCos((CloakingPhase/3)&4095),i);
456 			ioff.vz = 0;
457 
458 			RotateVector(&ioff, &subjectPtr->ObMat);
459 			AddVector(&ioff, &Global_VDB_Ptr->VDB_World);
460 
461 
462 		}
463 		#endif
464 	}
465 	{
466 		EULER orientation;
467 		MATRIXCH matrix;
468 
469 		orientation = HeadOrientation;
470 
471 	  orientation.EulerZ += (zAxisTilt>>8);
472 	  orientation.EulerZ &= 4095;
473 
474 		if (NAUSEA_CHEATMODE)
475 		{
476 			orientation.EulerZ = (orientation.EulerZ+GetSin((CloakingPhase/2)&4095)/256)&4095;
477 			orientation.EulerX = (orientation.EulerX+GetSin((CloakingPhase/2+500)&4095)/512)&4095;
478 			orientation.EulerY = (orientation.EulerY+GetSin((CloakingPhase/3+800)&4095)/512)&4095;
479 		}
480 		// The next test drops the matrix multiply if the orientation is close to zero
481 		// There is an inaccuracy problem with the Z angle at this point
482 
483 		if (orientation.EulerX != 0 || orientation.EulerY != 0 ||
484 					(orientation.EulerZ > 1 && orientation.EulerZ <	4095))
485 		{
486 			CreateEulerMatrix(&orientation, &matrix);
487 			MatrixMultiply(&Global_VDB_Ptr->VDB_Mat, &matrix, &Global_VDB_Ptr->VDB_Mat);
488 	 	}
489 
490 	}
491 
492 	{
493 		VECTORCH relativeVelocity;
494 
495 		/* get subject's total velocity */
496 		{
497 			MATRIXCH worldToLocalMatrix;
498 
499 			/* make world to local matrix */
500 			worldToLocalMatrix = subjectPtr->ObMat;
501 			TransposeMatrixCH(&worldToLocalMatrix);
502 
503 			relativeVelocity.vx = dynPtr->Position.vx - dynPtr->PrevPosition.vx;
504 			relativeVelocity.vy = dynPtr->Position.vy - dynPtr->PrevPosition.vy;
505 			relativeVelocity.vz = dynPtr->Position.vz - dynPtr->PrevPosition.vz;
506 			/* rotate into object space */
507 
508 			RotateVector(&relativeVelocity,&worldToLocalMatrix);
509 		}
510 
511 		{
512 			int targetingSpeed = 10*NormalFrameTime;
513 
514 			/* KJL 14:08:50 09/20/96 - the targeting is FRI, but care has to be taken
515 			   at very low frame rates to ensure that you can't overshoot */
516 			if (targetingSpeed > 65536)	targetingSpeed=65536;
517 
518 			zAxisTilt += MUL_FIXED
519 				(
520 					DIV_FIXED
521 					(
522 						MUL_FIXED(relativeVelocity.vx,LeanScale),
523 						NormalFrameTime
524 					)-zAxisTilt,
525 					targetingSpeed
526 				);
527 
528 			{
529 				static int previousVerticalSpeed = 0;
530 				int difference;
531 
532 				if (relativeVelocity.vy >= 0)
533 				{
534 					difference = DIV_FIXED
535 					(
536 						previousVerticalSpeed - relativeVelocity.vy,
537 						NormalFrameTime
538 					);
539 				}
540 				else difference = 0;
541 
542 				if (verticalSpeed < difference) verticalSpeed = difference;
543 
544 			 	if(verticalSpeed > 150*16) verticalSpeed = 150*16;
545 
546 				verticalSpeed -= NormalFrameTime>>2;
547 				if (verticalSpeed < 0) verticalSpeed = 0;
548 
549 				previousVerticalSpeed = relativeVelocity.vy;
550 			}
551 	 	}
552 	}
553 }
554 
UpdateCamera(void)555 void UpdateCamera(void)
556 {
557 	PLAYER_STATUS *playerStatusPtr= (PLAYER_STATUS *) (Player->ObStrategyBlock->SBdataptr);
558 	int cos = GetCos(playerStatusPtr->ViewPanX);
559 	int sin = GetSin(playerStatusPtr->ViewPanX);
560 	MATRIXCH mat;
561 	DISPLAYBLOCK *dptr_s = Player;
562 
563 	Global_VDB_Ptr->VDB_World = dptr_s->ObWorld;
564 	Global_VDB_Ptr->VDB_Mat = dptr_s->ObMat;
565 
566 	mat.mat11 = ONE_FIXED;
567 	mat.mat12 = 0;
568 	mat.mat13 = 0;
569 	mat.mat21 = 0;
570 	mat.mat22 = cos;
571 	mat.mat23 = -sin;
572 	mat.mat31 = 0;
573 	mat.mat32 = sin;
574 	mat.mat33 = cos;
575  	MatrixMultiply(&Global_VDB_Ptr->VDB_Mat,&mat,&Global_VDB_Ptr->VDB_Mat);
576 
577 
578 	InteriorType_Body();
579 }
580 
AVPGetInViewVolumeList(VIEWDESCRIPTORBLOCK * VDB_Ptr)581 void AVPGetInViewVolumeList(VIEWDESCRIPTORBLOCK *VDB_Ptr)
582 {
583 	DISPLAYBLOCK **activeblocksptr;
584 	int t;
585 	#if (SupportModules && SupportMultiCamModules)
586 	int MVis;
587 	#endif
588 
589 	/* Initialisation */
590 	NumOnScreenBlocks = 0;
591 
592 	/* Scan the Active Blocks List */
593 	activeblocksptr = &ActiveBlockList[0];
594 
595 	for(t = NumActiveBlocks; t!=0; t--)
596 	{
597 		DISPLAYBLOCK *dptr = *activeblocksptr++;
598 
599 		if (dptr==Player) continue;
600 		MVis = Yes;
601 		if(dptr->ObMyModule)
602 		{
603 			MODULE *mptr = dptr->ObMyModule;
604 			if(ModuleCurrVisArray[mptr->m_index] != 2) MVis = No;
605 			else
606 			{
607 				extern int NumberOfLandscapePolygons;
608 				SHAPEHEADER *shapePtr = GetShapeData(dptr->ObShape);
609 				NumberOfLandscapePolygons+=shapePtr->numitems;
610 			}
611 
612 		}
613 		if (!(dptr->ObFlags&ObFlag_NotVis) && MVis)
614 		{
615 			MakeVector(&dptr->ObWorld, &VDB_Ptr->VDB_World, &dptr->ObView);
616 			RotateVector(&dptr->ObView, &VDB_Ptr->VDB_Mat);
617 
618 			/* Screen Test */
619 			#if MIRRORING_ON
620 			if (MirroringActive || dptr->HModelControlBlock || dptr->SfxPtr)
621 			{
622 				OnScreenBlockList[NumOnScreenBlocks++] = dptr;
623 			}
624 			else if (ObjectWithinFrustrum(dptr))
625 			{
626 				OnScreenBlockList[NumOnScreenBlocks++] = dptr;
627 			}
628 			#else
629 			if(dptr->SfxPtr || dptr->HModelControlBlock || ObjectWithinFrustrum(dptr))
630 			{
631 				OnScreenBlockList[NumOnScreenBlocks++] = dptr;
632 			}
633 			else
634 			{
635 				if(dptr->HModelControlBlock)
636 				{
637 					DoHModelTimer(dptr->HModelControlBlock);
638 				}
639 			}
640 			#endif
641 		}
642 
643 	}
644 }
645 
ReflectObject(DISPLAYBLOCK * dPtr)646 void ReflectObject(DISPLAYBLOCK *dPtr)
647 {
648 	dPtr->ObWorld.vx = MirroringAxis - dPtr->ObWorld.vx;
649 	dPtr->ObMat.mat11 = -dPtr->ObMat.mat11;
650 	dPtr->ObMat.mat21 = -dPtr->ObMat.mat21;
651 	dPtr->ObMat.mat31 = -dPtr->ObMat.mat31;
652 }
653 
654 void CheckIfMirroringIsRequired(void);
AvpShowViews(void)655 void AvpShowViews(void)
656 {
657 	FlushD3DZBuffer();
658 
659 	UpdateAllFMVTextures();
660 
661 
662 	/* Update attached object positions and orientations etc. */
663 	UpdateCamera();
664 
665 	/* Initialise the global VMA */
666 //	GlobalAmbience=655;
667 //	textprint("Global Ambience: %d\n",GlobalAmbience);
668 
669 	/* Prepare the View Descriptor Block for use in ShowView() */
670 
671 	PrepareVDBForShowView(Global_VDB_Ptr);
672 	PlatformSpecificShowViewEntry(Global_VDB_Ptr, &ScreenDescriptorBlock);
673 	TranslationSetup();
674 
675 	{
676 		extern void ThisFramesRenderingHasBegun(void);
677 		ThisFramesRenderingHasBegun();
678 		D3D_DrawBackdrop();
679 	}
680 
681 	/* Now we know where the camera is, update the modules */
682 
683 	#if SupportModules
684 	AllNewModuleHandler();
685 //	ModuleHandler(Global_VDB_Ptr);
686 	#endif
687 
688 	#if MIRRORING_ON
689 	CheckIfMirroringIsRequired();
690 	#endif
691 
692 	/* Do lights */
693 	UpdateRunTimeLights();
694 	if (AvP.PlayerType==I_Alien)
695 	{
696 		MakeLightElement(&Player->ObWorld,LIGHTELEMENT_ALIEN_TEETH);
697 		MakeLightElement(&Player->ObWorld,LIGHTELEMENT_ALIEN_TEETH2);
698 	}
699 
700 //	GlobalAmbience=ONE_FIXED/4;
701 	/* Find out which objects are in the View Volume */
702 	AVPGetInViewVolumeList(Global_VDB_Ptr);
703 
704 	if (AlienBiteAttackInProgress)
705 	{
706 		CameraZoomScale += (float)NormalFrameTime/65536.0f;
707 		if (CameraZoomScale > 1.0f)
708 		{
709 			AlienBiteAttackInProgress = 0;
710 			CameraZoomScale = 1.0f;
711 		}
712 	}
713 
714 	/* update players weapon */
715 	UpdateWeaponStateMachine();
716 	/* lights associated with the player may have changed */
717 	UpdateObjectLights(Player);
718 
719 
720 	if(NumOnScreenBlocks)
721 	{
722 	 	/* KJL 12:13:26 02/05/97 - divert rendering for AvP */
723 		KRenderItems(Global_VDB_Ptr);
724 	}
725 
726 	PlatformSpecificShowViewExit(Global_VDB_Ptr, &ScreenDescriptorBlock);
727 
728 	#if SupportZBuffering
729 	if ((ScanDrawMode != ScanDrawDirectDraw) &&	(ZBufferMode != ZBufferOff))
730 	{
731 		/* KJL 10:25:44 7/23/97 - this offset is used to push back the normal game gfx,
732 		so that the HUD can be drawn over the top without sinking into walls, etc. */
733 		HeadUpDisplayZOffset = 0;
734 	}
735 	#endif
736 }
737 
738 
InitCameraValues(void)739 void InitCameraValues(void)
740 {
741 	extern VIEWDESCRIPTORBLOCK *ActiveVDBList[];
742 	Global_VDB_Ptr = ActiveVDBList[0];
743 
744 	HeadOrientation.EulerX = 0;
745 	HeadOrientation.EulerY = 0;
746 	HeadOrientation.EulerZ = 0;
747 
748 	CameraZoomScale = 1.0f;
749 	CameraZoomLevel=0;
750 }
751 
752 
753 
754 /*
755 
756  Prepare the View Descriptor Block for use in ShowView() and others.
757 
758  If there is a display block attached to the view, update the view location
759  and orientation.
760 
761 */
762 
PrepareVDBForShowView(VIEWDESCRIPTORBLOCK * VDB_Ptr)763 void PrepareVDBForShowView(VIEWDESCRIPTORBLOCK *VDB_Ptr)
764 {
765 	EULER e;
766 
767 
768 	/* Get the View Object Matrix, transposed */
769  	TransposeMatrixCH(&VDB_Ptr->VDB_Mat);
770 
771 	/* Get the Matrix Euler Angles */
772 	MatrixToEuler(&VDB_Ptr->VDB_Mat, &VDB_Ptr->VDB_MatrixEuler);
773 
774 	/* Get the Matrix Euler Angles */
775 	MatrixToEuler(&VDB_Ptr->VDB_Mat, &e);
776 
777 	/* Create the "sprite" matrix" */
778 	e.EulerX = 0;
779 	e.EulerY = 0;
780 	e.EulerZ = (-e.EulerZ) & wrap360;
781 
782 	CreateEulerMatrix(&e, &VDB_Ptr->VDB_SpriteMat);
783 }
784 
785 
786 /*
787 
788  This function updates the position and orientation of the lights attached
789  to an object.
790 
791  It must be called after the object has completed its movements in a frame,
792  prior to the call to the renderer.
793 
794 */
795 
UpdateObjectLights(DISPLAYBLOCK * dptr)796 void UpdateObjectLights(DISPLAYBLOCK *dptr)
797 {
798 
799 	int i;
800 	LIGHTBLOCK *lptr;
801 	LIGHTBLOCK **larrayptr = &dptr->ObLights[0];
802 
803 
804 	for(i = dptr->ObNumLights; i!=0; i--)
805 	{
806 		/* Get a light */
807 		lptr = *larrayptr++;
808 
809 		/* Calculate the light's location */
810 		if(!(lptr->LightFlags & LFlag_AbsPos))
811 		{
812 			CopyVector(&dptr->ObWorld, &lptr->LightWorld);
813      	}
814 		LOCALASSERT(lptr->LightRange!=0);
815 		lptr->BrightnessOverRange = DIV_FIXED(MUL_FIXED(lptr->LightBright,LightScale),lptr->LightRange);
816 	}
817 
818 
819 }
820 
821 
822 
823 
824 
825 
826 
827 
828 
829 
830 
831 
832 
833 
834 /****************************************************************************/
835 
836 /*
837 
838  Find out which light sources are in range of the object.
839 
840 */
841 
842 
843 
844 
845 /*
846 
847  Initialise the Renderer
848 
849 */
850 
InitialiseRenderer(void)851 void InitialiseRenderer(void)
852 {
853 	InitialiseObjectBlocks();
854 	InitialiseStrategyBlocks();
855 
856 	InitialiseTxAnimBlocks();
857 
858 	InitialiseLightBlocks();
859 	InitialiseVDBs();
860 
861 	/* KJL 14:46:42 09/09/98 */
862 	InitialiseLightIntensityStamps();
863 }
864 
865 
866 
867 
868 
869 /*
870 
871  General View Volume Test for Objects and Sub-Object Trees
872 
873  This function returns returns "Yes" / "True" for an if()
874 
875 */
876 
AVPViewVolumeTest(VIEWDESCRIPTORBLOCK * VDB_Ptr,DISPLAYBLOCK * dblockptr)877 int AVPViewVolumeTest(VIEWDESCRIPTORBLOCK *VDB_Ptr, DISPLAYBLOCK *dblockptr)
878 {
879 	int obr = dblockptr->ObRadius;
880 
881 	/* Perform the view volume plane tests */
882 
883 	if(
884 	AVPViewVolumePlaneTest(&VDB_Ptr->VDB_ClipZPlane, dblockptr, obr) &&
885 	AVPViewVolumePlaneTest(&VDB_Ptr->VDB_ClipLeftPlane, dblockptr, obr) &&
886 	AVPViewVolumePlaneTest(&VDB_Ptr->VDB_ClipRightPlane, dblockptr, obr) &&
887 	AVPViewVolumePlaneTest(&VDB_Ptr->VDB_ClipUpPlane, dblockptr, obr) &&
888 	AVPViewVolumePlaneTest(&VDB_Ptr->VDB_ClipDownPlane, dblockptr, obr))
889 		return Yes;
890 
891 	else
892 		return No;
893 
894 }
895 /*
896 
897  View Volume Plane Test
898 
899  Make the ODB VSL relative to the VDB Clip Plane POP and dot the resultant
900  vector with the Clip Plane Normal.
901 
902 */
903 
AVPViewVolumePlaneTest(CLIPPLANEBLOCK * cpb,DISPLAYBLOCK * dblockptr,int obr)904 int AVPViewVolumePlaneTest(CLIPPLANEBLOCK *cpb, DISPLAYBLOCK *dblockptr, int obr)
905 {
906 	VECTORCH POPRelObView;
907 
908 	MakeVector(&dblockptr->ObView, &cpb->CPB_POP, &POPRelObView);
909 
910 	if(DotProduct(&POPRelObView, &cpb->CPB_Normal) < obr) return Yes;
911 	else return No;
912 }
913 
914 
915 #if MIRRORING_ON
CheckIfMirroringIsRequired(void)916 void CheckIfMirroringIsRequired(void)
917 {
918 	extern char LevelName[];
919 	extern MODULE * playerPherModule;
920 
921 	MirroringActive = 0;
922 	#if 0
923 	if ( (!stricmp(LevelName,"e3demo")) || (!stricmp(LevelName,"e3demosp")) )
924 	{
925 		int numOfObjects = NumActiveBlocks;
926 
927 		while(numOfObjects)
928 		{
929 			DISPLAYBLOCK *objectPtr = ActiveBlockList[--numOfObjects];
930 			MODULE *modulePtr = objectPtr->ObMyModule;
931 
932 			/* if it's a module, which isn't inside another module */
933 			if (modulePtr && modulePtr->name)
934 			{
935 				if(!stricmp(modulePtr->name,"marine01b"))
936 				{
937 					if(ModuleCurrVisArray[modulePtr->m_index] == 2)
938 					{
939 						MirroringActive = 1;
940 						MirroringAxis = -149*2;
941 						break;
942 					}
943 				}
944 			}
945 		}
946 
947 		if (playerPherModule && playerPherModule->name)
948 		{
949 			textprint("<%s>\n",playerPherModule->name);
950 			if((!stricmp(playerPherModule->name,"predator"))
951 			 ||(!stricmp(playerPherModule->name,"predator01"))
952 			 ||(!stricmp(playerPherModule->name,"predator03"))
953 			 ||(!stricmp(playerPherModule->name,"predator02")) )
954 			{
955 				MirroringActive = 1;
956 				MirroringAxis = -7164*2;
957 			}
958 		}
959 	}
960 	else
961 	#endif
962 	#if 1
963 	if (!stricmp(LevelName,"derelict"))
964 	{
965 		if (playerPherModule && playerPherModule->name)
966 		{
967 			if((!stricmp(playerPherModule->name,"start"))
968 			 ||(!stricmp(playerPherModule->name,"start-en01")) )
969 			{
970 				MirroringActive = 1;
971 				MirroringAxis = -5596*2;
972 			}
973 		}
974 	}
975 	#endif
976 }
977 #endif
978 
979 #define MinChangeInXSize 8
MakeViewingWindowSmaller(void)980 void MakeViewingWindowSmaller(void)
981 {
982 	extern VIEWDESCRIPTORBLOCK *Global_VDB_Ptr;
983 	int MinChangeInYSize = (ScreenDescriptorBlock.SDB_Height*MinChangeInXSize)/ScreenDescriptorBlock.SDB_Width;
984 
985 	if (Global_VDB_Ptr->VDB_ClipLeft<ScreenDescriptorBlock.SDB_Width/2-16)
986 	{
987 		Global_VDB_Ptr->VDB_ClipLeft +=MinChangeInXSize;
988 		Global_VDB_Ptr->VDB_ClipRight -=MinChangeInXSize;
989 		Global_VDB_Ptr->VDB_ClipUp +=MinChangeInYSize;
990 		Global_VDB_Ptr->VDB_ClipDown -=MinChangeInYSize;
991 	}
992 	if(AvP.PlayerType == I_Alien)
993 	{
994 		Global_VDB_Ptr->VDB_ProjX = (Global_VDB_Ptr->VDB_ClipRight - Global_VDB_Ptr->VDB_ClipLeft)/4;
995 		Global_VDB_Ptr->VDB_ProjY = (Global_VDB_Ptr->VDB_ClipDown - Global_VDB_Ptr->VDB_ClipUp)/4;
996 	}
997 	else
998 	{
999 		Global_VDB_Ptr->VDB_ProjX = (Global_VDB_Ptr->VDB_ClipRight - Global_VDB_Ptr->VDB_ClipLeft)/2;
1000 		Global_VDB_Ptr->VDB_ProjY = (Global_VDB_Ptr->VDB_ClipDown - Global_VDB_Ptr->VDB_ClipUp)/2;
1001 	}
1002 	//BlankScreen();
1003 }
1004 
MakeViewingWindowLarger(void)1005 void MakeViewingWindowLarger(void)
1006 {
1007 	extern VIEWDESCRIPTORBLOCK *Global_VDB_Ptr;
1008 	int MinChangeInYSize = (ScreenDescriptorBlock.SDB_Height*MinChangeInXSize)/ScreenDescriptorBlock.SDB_Width;
1009 
1010 	if (Global_VDB_Ptr->VDB_ClipLeft>0)
1011 	{
1012 		Global_VDB_Ptr->VDB_ClipLeft -=MinChangeInXSize;
1013 		Global_VDB_Ptr->VDB_ClipRight +=MinChangeInXSize;
1014 		Global_VDB_Ptr->VDB_ClipUp -=MinChangeInYSize;
1015 		Global_VDB_Ptr->VDB_ClipDown +=MinChangeInYSize;
1016 	}
1017 	if(AvP.PlayerType == I_Alien)
1018 	{
1019 		Global_VDB_Ptr->VDB_ProjX = (Global_VDB_Ptr->VDB_ClipRight - Global_VDB_Ptr->VDB_ClipLeft)/4;
1020 		Global_VDB_Ptr->VDB_ProjY = (Global_VDB_Ptr->VDB_ClipDown - Global_VDB_Ptr->VDB_ClipUp)/4;
1021 	}
1022 	else
1023 	{
1024 		Global_VDB_Ptr->VDB_ProjX = (Global_VDB_Ptr->VDB_ClipRight - Global_VDB_Ptr->VDB_ClipLeft)/2;
1025 		Global_VDB_Ptr->VDB_ProjY = (Global_VDB_Ptr->VDB_ClipDown - Global_VDB_Ptr->VDB_ClipUp)/2;
1026 	}
1027 }
1028 
1029 
AlienBiteAttackHasHappened(void)1030 extern void AlienBiteAttackHasHappened(void)
1031 {
1032 	extern int AlienTongueOffset;
1033 	extern int AlienTeethOffset;
1034 
1035 	AlienBiteAttackInProgress = 1;
1036 
1037 	CameraZoomScale = 0.25f;
1038 	AlienTongueOffset = ONE_FIXED;
1039 	AlienTeethOffset = 0;
1040 }
1041 
1042