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