1 
2 #include "3dc.h"
3 
4 #include <math.h>
5 
6 #include "inline.h"
7 #include "module.h"
8 #include "stratdef.h"
9 #include "gamedef.h"
10 #include "bh_types.h"
11 #include "pvisible.h"
12 
13 #include "kzsort.h"
14 #include "kshape.h"
15 
16 /*
17 
18  Platform Specific Functions
19 
20  These functions have been written specifically for a given platform.
21 
22  They are not necessarily IO or inline functions; these have their own files.
23 
24 */
25 
26 
27 /*
28 
29  externs for commonly used global variables and arrays
30 
31 */
32 
33 	extern VECTORCH RotatedPts[];
34 	extern unsigned int Outcodes[];
35 	extern DISPLAYBLOCK *Global_ODB_Ptr;
36 	extern VIEWDESCRIPTORBLOCK *Global_VDB_Ptr;
37 	extern SHAPEHEADER *Global_ShapeHeaderPtr;
38 	extern MATRIXCH LToVMat;
39 	#if SupportMorphing
40 	extern VECTORCH MorphedPts[];
41 	extern MORPHDISPLAY MorphDisplay;
42 	#endif
43 
44 	extern DISPLAYBLOCK *OnScreenBlockList[];
45 	extern int NumOnScreenBlocks;
46 	extern int NumActiveBlocks;
47 	extern DISPLAYBLOCK *ActiveBlockList[];
48 	#if SupportModules
49 	extern char *ModuleLocalVisArray;
50 	#endif
51 
52 
53 
54 /*
55 
56  Global Variables
57 
58 */
59 
60 	LONGLONGCH ll_one14 = {one14, 0};
61 	LONGLONGCH ll_zero = {0, 0};
62 
63 
64 
65 
66 
67 
68 /*
69 
70  Find out which objects are in the View Volume.
71 
72  The list of these objects, "OnScreenBlockList", is constructed in a number
73  of stages.
74 
75  The Range Test is a simple outcode of the View Space Location against the
76  Object Radius. The View Volume Test is more involved. The VSL is tested
77  against each of the View Volume Planes. If it is more than one Object Radius
78  outside any plane, the test fails.
79 
80 */
81 
82 /*
83 
84  This is the main view volume test shell
85 
86 */
87 
88 
89 
90 
91 
92 
93 
94 
95 #if StandardShapeLanguage
96 
97 
98 /*
99 
100  Shape Points
101 
102  The item array is a table of pointers to item arrays. The points data is
103  in the first and only item array.
104 
105  Rotate each point and write it out to the Rotated Points Buffer
106 
107  NOTE:
108 
109  There is a global pointer to the shape header "Global_ShapeHeaderPtr"
110 
111 */
112 
113 
114 #define print_bfcro_stats No
115 
116 #if SupportMorphing
117 #define checkmorphpts No
118 #endif
119 
120 
ShapePointsInstr(SHAPEINSTR * shapeinstrptr)121 void ShapePointsInstr(SHAPEINSTR *shapeinstrptr)
122 
123 {
124 
125 	int **shapeitemarrayptr;
126 	int *shapeitemptr;
127 	VECTORCH *rotptsptr;
128 	int x, y, z;
129 	int numitems;
130 	#if print_bfcro_stats
131 	int num_rot, num_not_rot;
132 	#endif
133 
134 
135 
136 	/*
137 
138 	Kevin, morphed doors WON'T be using shared points, so I've put your
139 	patch here, AFTER the intercept for the shared version of the points
140 	instruction -- Chris.
141 
142 	*/
143 
144 	#if KZSORT_ON /* KJL 15:13:46 02/07/97 - used for z-sorting doors correctly! */
145 	{
146 		extern int *MorphedObjectPointsPtr;
147 		MorphedObjectPointsPtr = 0;
148 	}
149 	#endif
150 
151 
152 	/* Set up pointers */
153 
154 	shapeitemarrayptr = shapeinstrptr->sh_instr_data;
155 	shapeitemptr      = *shapeitemarrayptr;
156 	rotptsptr         = &RotatedPts[0];
157 
158 
159 
160 	#if SupportMorphing
161 
162 	if(Global_ODB_Ptr->ObMorphCtrl) {
163 
164 
165 		#if LazyEvaluationForMorphing
166 
167 		VECTORCH *morphptsptr;
168 
169 		if(Global_ODB_Ptr->ObMorphedPts == 0) {
170 
171 			Global_ODB_Ptr->ObMorphedPts = GetMorphedPts(Global_ODB_Ptr,
172 																		&MorphDisplay);
173 
174 		}
175 
176 		morphptsptr = Global_ODB_Ptr->ObMorphedPts;
177 
178 		GLOBALASSERT(shapeinstrptr->sh_numitems<maxmorphPts);
179 
180 		for(numitems = shapeinstrptr->sh_numitems; numitems!=0; numitems--) {
181 
182 			#if SUPPORT_MMX
183 			if (use_mmx_math)
184 				MMX_VectorTransformedAndAdd(rotptsptr,morphptsptr,&LToVMat,&Global_ODB_Ptr->ObView);
185 			else
186 			#endif
187 			{
188 				rotptsptr->vx =  MUL_FIXED(LToVMat.mat11, morphptsptr->vx);
189 				rotptsptr->vx += MUL_FIXED(LToVMat.mat21, morphptsptr->vy);
190 				rotptsptr->vx += MUL_FIXED(LToVMat.mat31, morphptsptr->vz);
191 				rotptsptr->vx += Global_ODB_Ptr->ObView.vx;
192 
193 				rotptsptr->vy =  MUL_FIXED(LToVMat.mat12, morphptsptr->vx);
194 				rotptsptr->vy += MUL_FIXED(LToVMat.mat22, morphptsptr->vy);
195 				rotptsptr->vy += MUL_FIXED(LToVMat.mat32, morphptsptr->vz);
196 				rotptsptr->vy += Global_ODB_Ptr->ObView.vy;
197 
198 				rotptsptr->vz =  MUL_FIXED(LToVMat.mat13, morphptsptr->vx);
199 				rotptsptr->vz += MUL_FIXED(LToVMat.mat23, morphptsptr->vy);
200 				rotptsptr->vz += MUL_FIXED(LToVMat.mat33, morphptsptr->vz);
201 				rotptsptr->vz += Global_ODB_Ptr->ObView.vz;
202 			}
203 
204 			rotptsptr->vy = MUL_FIXED(rotptsptr->vy,87381);
205 			morphptsptr++;
206 			rotptsptr++;
207 
208 		}
209 
210 
211 		#else	/* LazyEvaluationForMorphing */
212 
213 
214 		VECTORCH *morphptsptr = &MorphedPts[0];
215 		SHAPEHEADER *sptr1;
216 		SHAPEHEADER *sptr2;
217 		int *shapeitemptr1;
218 		int *shapeitemptr2;
219 		int x1, y1, z1;
220 		int x2, y2, z2;
221 		#if checkmorphpts
222 		int num_old_pts = 0;
223 		int num_new_pts = 0;
224 		#endif
225 
226 
227 		/*textprint("morphing points\n");*/
228 
229 		sptr1 = MorphDisplay.md_sptr1;
230 		sptr2 = MorphDisplay.md_sptr2;
231 
232 		shapeitemptr1 = *(sptr1->points);
233 		shapeitemptr2 = *(sptr2->points);
234 
235 
236 		#if KZSORT_ON /* KJL 15:13:46 02/07/97 - used for z-sorting doors correctly! */
237 		{
238 			extern int *MorphedObjectPointsPtr;
239 			MorphedObjectPointsPtr = shapeitemptr2;
240 		}
241 		#endif
242 
243 
244 		for(numitems = shapeinstrptr->sh_numitems; numitems!=0; numitems--) {
245 
246 			x1 = shapeitemptr1[ix];
247 			y1 = shapeitemptr1[iy];
248 			z1 = shapeitemptr1[iz];
249 
250 			x2 = shapeitemptr2[ix];
251 			y2 = shapeitemptr2[iy];
252 			z2 = shapeitemptr2[iz];
253 
254 			if(x1 == x2 && y1 == y2 && z1 == z2) {
255 
256 				x = x1;
257 				y = y1;
258 				z = z1;
259 
260 				#if checkmorphpts
261 				num_old_pts++;
262 				#endif
263 
264 			}
265 
266 			else if(MorphDisplay.md_lerp == 0) {
267 
268 				x = x1;
269 				y = y1;
270 				z = z1;
271 
272 			}
273 
274 			else if(MorphDisplay.md_lerp == 0xffff) {
275 
276 				x = x2;
277 				y = y2;
278 				z = z2;
279 
280 			}
281 
282 			else
283 			{
284 				/* KJL 15:27:20 05/22/97 - I've changed this to speed things up, If a vertex
285 				component has a magnitude greater than 32768 things will go wrong. */
286 				x = x1 + (((x2-x1)*MorphDisplay.md_lerp)>>16);
287 				y = y1 + (((y2-y1)*MorphDisplay.md_lerp)>>16);
288 				z = z1 + (((z2-z1)*MorphDisplay.md_lerp)>>16);
289 
290 				#if checkmorphpts
291 				num_new_pts++;
292 				#endif
293 
294 			}
295 
296 			morphptsptr->vx = x;
297 			morphptsptr->vy = y;
298 			morphptsptr->vz = z;
299 
300 			/* KJL 16:07:15 11/27/97 - I know this test is inside the loop,
301 			        but all this will go when I change to float everywhere. */
302 			#if MIRRORING_ON
303 			if(!Global_ODB_Ptr->ObMyModule || MirroringActive)
304 			#else
305 			if (!Global_ODB_Ptr->ObMyModule)
306 			#endif
307 			{
308 				#if SUPPORT_MMX
309 				if (use_mmx_math)
310 					MMX_VectorTransformedAndAdd(rotptsptr,morphptsptr,&LToVMat,&Global_ODB_Ptr->ObView);
311 				else
312 				#endif
313 				{
314 					rotptsptr->vx =  MUL_FIXED(LToVMat.mat11, x);
315 					rotptsptr->vx += MUL_FIXED(LToVMat.mat21, y);
316 					rotptsptr->vx += MUL_FIXED(LToVMat.mat31, z);
317 					rotptsptr->vx += Global_ODB_Ptr->ObView.vx;
318 
319 					rotptsptr->vy =  MUL_FIXED(LToVMat.mat12, x);
320 					rotptsptr->vy += MUL_FIXED(LToVMat.mat22, y);
321 					rotptsptr->vy += MUL_FIXED(LToVMat.mat32, z);
322 					rotptsptr->vy += Global_ODB_Ptr->ObView.vy;
323 
324 					rotptsptr->vz =  MUL_FIXED(LToVMat.mat13, x);
325 					rotptsptr->vz += MUL_FIXED(LToVMat.mat23, y);
326 					rotptsptr->vz += MUL_FIXED(LToVMat.mat33, z);
327 					rotptsptr->vz += Global_ODB_Ptr->ObView.vz;
328 				}
329 			}
330 			else /* KJL 14:33:24 11/27/97 - experiment to get rid of tears */
331 			{
332 				x += Global_ODB_Ptr->ObWorld.vx - Global_VDB_Ptr->VDB_World.vx;
333 				y += Global_ODB_Ptr->ObWorld.vy - Global_VDB_Ptr->VDB_World.vy;
334 				z += Global_ODB_Ptr->ObWorld.vz - Global_VDB_Ptr->VDB_World.vz;
335 
336 				rotptsptr->vx =  MUL_FIXED(LToVMat.mat11, x);
337 				rotptsptr->vx += MUL_FIXED(LToVMat.mat21, y);
338 				rotptsptr->vx += MUL_FIXED(LToVMat.mat31, z);
339 
340 				rotptsptr->vy =  MUL_FIXED(LToVMat.mat12, x);
341 				rotptsptr->vy += MUL_FIXED(LToVMat.mat22, y);
342 				rotptsptr->vy += MUL_FIXED(LToVMat.mat32, z);
343 
344 				rotptsptr->vz =  MUL_FIXED(LToVMat.mat13, x);
345 				rotptsptr->vz += MUL_FIXED(LToVMat.mat23, y);
346 				rotptsptr->vz += MUL_FIXED(LToVMat.mat33, z);
347 			}
348 
349 
350 			shapeitemptr1 += vsize;
351 			shapeitemptr2 += vsize;
352 			morphptsptr++;
353 
354 			rotptsptr->vy = MUL_FIXED(rotptsptr->vy,87381);
355 			rotptsptr++;
356 
357 		}
358 
359 		#if checkmorphpts
360 		textprint("num_old_pts = %d\n", num_old_pts);
361 		textprint("num_new_pts = %d\n", num_new_pts);
362 		#endif
363 
364 
365 		#endif	/* LazyEvaluationForMorphing */
366 
367 
368 	}
369 
370 	else {
371 
372 	#endif
373 
374 		#if MIRRORING_ON
375 		int useFirstMethod = 0;
376 
377 
378 		if(!Global_ODB_Ptr->ObMyModule || MirroringActive)
379 		{
380 			useFirstMethod = 1;
381 		}
382 		if (Global_ODB_Ptr->ObStrategyBlock)
383 		{
384 			#if 0
385 			if(Global_ODB_Ptr->ObStrategyBlock->I_SBtype == I_BehaviourInanimateObject)
386 			{
387 				INANIMATEOBJECT_STATUSBLOCK* osPtr = Global_ODB_Ptr->ObStrategyBlock->SBdataptr;
388 				if(osPtr->typeId==IOT_Static)
389 				{
390 					useFirstMethod=0;
391 				}
392 			}
393 			#endif
394 		}
395 
396 		if(useFirstMethod)
397 		#else
398 		if (!Global_ODB_Ptr->ObMyModule)
399 		#endif
400 		{
401 			for(numitems = shapeinstrptr->sh_numitems; numitems!=0; numitems--)
402 			{
403 				#if SUPPORT_MMX
404 				if (use_mmx_math)
405 					MMX_VectorTransformedAndAdd(rotptsptr,(VECTORCH *)shapeitemptr,&LToVMat,&Global_ODB_Ptr->ObView);
406 				else
407 				#endif
408 				{
409 					x = shapeitemptr[ix];
410 					y = shapeitemptr[iy];
411 					z = shapeitemptr[iz];
412 
413 					rotptsptr->vx =  MUL_FIXED(LToVMat.mat11, x);
414 					rotptsptr->vx += MUL_FIXED(LToVMat.mat21, y);
415 					rotptsptr->vx += MUL_FIXED(LToVMat.mat31, z);
416 					rotptsptr->vx += Global_ODB_Ptr->ObView.vx;
417 
418 					rotptsptr->vy =  MUL_FIXED(LToVMat.mat12, x);
419 					rotptsptr->vy += MUL_FIXED(LToVMat.mat22, y);
420 					rotptsptr->vy += MUL_FIXED(LToVMat.mat32, z);
421 					rotptsptr->vy += Global_ODB_Ptr->ObView.vy;
422 
423 					rotptsptr->vz =  MUL_FIXED(LToVMat.mat13, x);
424 					rotptsptr->vz += MUL_FIXED(LToVMat.mat23, y);
425 					rotptsptr->vz += MUL_FIXED(LToVMat.mat33, z);
426 					rotptsptr->vz += Global_ODB_Ptr->ObView.vz;
427 				}
428 				shapeitemptr += 3;
429 				rotptsptr->vy = MUL_FIXED(rotptsptr->vy,87381);
430 				rotptsptr++;
431 
432 			}
433 		}
434 		else
435 		{
436 			/* KJL 14:33:24 11/27/97 - experiment to get rid of tears */
437 			for(numitems = shapeinstrptr->sh_numitems; numitems!=0; numitems--)
438 			{
439 				x = shapeitemptr[ix];
440 				y = shapeitemptr[iy];
441 				z = shapeitemptr[iz];
442 
443 				x += Global_ODB_Ptr->ObWorld.vx - Global_VDB_Ptr->VDB_World.vx;
444 				y += Global_ODB_Ptr->ObWorld.vy - Global_VDB_Ptr->VDB_World.vy;
445 				z += Global_ODB_Ptr->ObWorld.vz - Global_VDB_Ptr->VDB_World.vz;
446 
447 				rotptsptr->vx =  MUL_FIXED(LToVMat.mat11, x);
448 				rotptsptr->vx += MUL_FIXED(LToVMat.mat21, y);
449 				rotptsptr->vx += MUL_FIXED(LToVMat.mat31, z);
450 
451 				rotptsptr->vy =  MUL_FIXED(LToVMat.mat12, x);
452 				rotptsptr->vy += MUL_FIXED(LToVMat.mat22, y);
453 				rotptsptr->vy += MUL_FIXED(LToVMat.mat32, z);
454 
455 				rotptsptr->vz =  MUL_FIXED(LToVMat.mat13, x);
456 				rotptsptr->vz += MUL_FIXED(LToVMat.mat23, y);
457 				rotptsptr->vz += MUL_FIXED(LToVMat.mat33, z);
458 				shapeitemptr += 3;
459 				rotptsptr->vy = MUL_FIXED(rotptsptr->vy,87381);
460 				rotptsptr++;
461 			}
462 
463 		}
464 
465 	#if SupportMorphing
466 	}
467 	#endif
468 
469 
470 }
471 
472 
473 #endif	/* StandardShapeLanguage */
474 
475 
476 
477 
478 
479 
480 
481 /*
482 
483  WideMul2NarrowDiv
484 
485  This function takes two pairs of integers, adds their 64-bit products
486  together, divides the summed product with another integer and then returns
487  the result of that divide, which is also an integer.
488 
489 */
490 
WideMul2NarrowDiv(int a,int b,int c,int d,int e)491 int WideMul2NarrowDiv(int a, int b, int c, int d, int e)
492 
493 {
494 
495 	LONGLONGCH f;
496 	LONGLONGCH g;
497 
498 
499 	MUL_I_WIDE(a, b, &f);
500 	MUL_I_WIDE(c, d, &g);
501 	ADD_LL_PP(&f, &g);
502 
503 	return NarrowDivide(&f, e);
504 
505 }
506 
507 
508 /*
509 
510  Calculate Plane Normal from three POP's
511 
512  The three input vectors are treated as POP's and used to make two vectors.
513  These are then crossed to create the normal.
514 
515  Make two vectors; (2-1) & (3-1)
516  Cross them
517  Normalise the vector
518   Find the magnitude of the vector
519   Divide each component by the magnitude
520 
521 */
522 
MakeNormal(VECTORCH * v1,VECTORCH * v2,VECTORCH * v3,VECTORCH * v4)523 void MakeNormal(VECTORCH *v1, VECTORCH *v2, VECTORCH *v3, VECTORCH *v4)
524 
525 {
526 
527 	VECTORCHF vect0;
528 	VECTORCHF vect1;
529 	VECTORCHF n;
530 
531 
532 	/* vect0 = v2 - v1 */
533 
534 	vect0.vx = v2->vx - v1->vx;
535 	vect0.vy = v2->vy - v1->vy;
536 	vect0.vz = v2->vz - v1->vz;
537 
538 	/* vect1 = v3 - v1 */
539 
540 	vect1.vx = v3->vx - v1->vx;
541 	vect1.vy = v3->vy - v1->vy;
542 	vect1.vz = v3->vz - v1->vz;
543 
544 
545 	/* nx = v0y.v1z - v0z.v1y */
546 
547 	n.vx = (vect0.vy * vect1.vz) - (vect0.vz * vect1.vy);
548 
549 	/* ny = v0z.v1x - v0x.v1z */
550 
551 	n.vy = (vect0.vz * vect1.vx) - (vect0.vx * vect1.vz);
552 
553 	/* nz = v0x.v1y - v0y.v1x */
554 
555 	n.vz = (vect0.vx * vect1.vy) - (vect0.vy * vect1.vx);
556 
557 
558 	FNormalise(&n);
559 
560 	f2i(v4->vx, n.vx * ONE_FIXED);
561 	f2i(v4->vy, n.vy * ONE_FIXED);
562 	f2i(v4->vz, n.vz * ONE_FIXED);
563 
564 
565 	#if 0
566 	textprint("Magnitude of v4 = %d\n", Magnitude(v4));
567 	WaitForReturn();
568 	#endif
569 
570 }
571 
572 
573 /*
574 
575  Normalise a vector.
576 
577  The returned vector is a fixed point unit vector.
578 
579  WARNING!
580 
581  The vector must be no larger than 2<<14 because of the square root.
582  Because this is an integer function, small components produce errors.
583 
584  e.g.
585 
586  (100,100,0)
587 
588  m=141 (141.42)
589 
590  nx = 100 * ONE_FIXED / m = 46,479
591  ny = 100 * ONE_FIXED / m = 46,479
592  nz = 0
593 
594  New m ought to be 65,536 but in fact is 65,731 i.e. 0.29% too large.
595 
596 */
597 
Normalise(VECTORCH * nvector)598 void Normalise(VECTORCH *nvector)
599 
600 {
601 	VECTORCHF n;
602 	float m;
603 
604 
605 	n.vx = nvector->vx;
606 	n.vy = nvector->vy;
607 	n.vz = nvector->vz;
608 
609 	m = 65536.0/sqrt((n.vx * n.vx) + (n.vy * n.vy) + (n.vz * n.vz));
610 
611 	f2i(nvector->vx, (n.vx * m) );
612 	f2i(nvector->vy, (n.vy * m) );
613 	f2i(nvector->vz, (n.vz * m) );
614 }
615 
616 
617 
618 
619 
620 
621 
Normalise2d(VECTOR2D * nvector)622 void Normalise2d(VECTOR2D *nvector)
623 
624 {
625 	VECTOR2DF n;
626 	float m;
627 
628 
629 	n.vx = nvector->vx;
630 	n.vy = nvector->vy;
631 
632 	m = sqrt((n.vx * n.vx) + (n.vy * n.vy));
633 
634 	nvector->vx = (n.vx * ONE_FIXED) / m;
635 	nvector->vy = (n.vy * ONE_FIXED) / m;
636 }
637 
638 
FNormalise(VECTORCHF * n)639 void FNormalise(VECTORCHF *n)
640 
641 {
642 
643 	float m;
644 
645 
646 	m = sqrt((n->vx * n->vx) + (n->vy * n->vy) + (n->vz * n->vz));
647 
648 	n->vx /= m;
649 	n->vy /= m;
650 	n->vz /= m;
651 
652 }
653 
FNormalise2d(VECTOR2DF * n)654 void FNormalise2d(VECTOR2DF *n)
655 
656 {
657 
658 	float m;
659 
660 
661 	m = sqrt((n->vx * n->vx) + (n->vy * n->vy));
662 
663 	n->vx /= m;
664 	n->vy /= m;
665 
666 }
667 
668 
669 /*
670 
671  Return the magnitude of a vector
672 
673 */
674 
Magnitude(VECTORCH * v)675 int Magnitude(VECTORCH *v)
676 
677 {
678 	VECTORCHF n;
679 	int m;
680 
681 
682 	n.vx = v->vx;
683 	n.vy = v->vy;
684 	n.vz = v->vz;
685 
686 	f2i(m, sqrt((n.vx * n.vx) + (n.vy * n.vy) + (n.vz * n.vz)));
687 
688 	return m;
689 }
690 
691 /*
692 
693  Shift the 64-bit value until is LTE the limit
694 
695  Return the shift value
696 
697 */
698 
FindShift64(LONGLONGCH * value,LONGLONGCH * limit)699 int FindShift64(LONGLONGCH *value, LONGLONGCH *limit)
700 
701 {
702 
703 	int shift = 0;
704 	int s;
705 	LONGLONGCH value_tmp;
706 
707 
708 	EQUALS_LL(&value_tmp, value);
709 
710 	s = CMP_LL(&value_tmp, &ll_zero);
711 	if(s < 0) NEG_LL(&value_tmp);
712 
713 
714 	while(GT_LL(&value_tmp, limit)) {
715 
716 		shift++;
717 
718 		ASR_LL(&value_tmp, 1);
719 
720 	}
721 
722 	return shift;
723 
724 }
725 
726 
727 /*
728 
729  MaxLONGLONGCH
730 
731  Return a pointer to the largest value of a long long array
732 
733 */
734 
MaxLONGLONGCH(LONGLONGCH * llarrayptr,int llarraysize,LONGLONGCH * llmax)735 void MaxLONGLONGCH(LONGLONGCH *llarrayptr, int llarraysize, LONGLONGCH *llmax)
736 
737 {
738 
739 	int i;
740 
741 
742 	EQUALS_LL(llmax, &ll_zero);
743 
744 	for(i = llarraysize; i!=0; i--) {
745 
746 		if(LT_LL(llmax, llarrayptr)) {
747 
748 			EQUALS_LL(llmax, llarrayptr);
749 
750 		}
751 
752 		llarrayptr++;
753 
754 	}
755 
756 }
757 
758 
759 
760 
761 
762 
763 
764 
765 
766 
767 
768 
769 /*
770 
771  Some operators derived from the 64-bit CMP function.
772 
773 */
774 
775 
776 /*
777 
778  GT_LL
779 
780  To express if(a > b)
781 
782  use
783 
784  if(GT_LL(a, b))
785 
786 */
787 
GT_LL(LONGLONGCH * a,LONGLONGCH * b)788 int GT_LL(LONGLONGCH *a, LONGLONGCH *b)
789 
790 {
791 
792 	int s = CMP_LL(a, b);		/* a-b */
793 
794 
795 	if(s > 0) return (Yes);
796 
797 	else return (No);
798 
799 }
800 
801 
802 /*
803 
804  LT_LL
805 
806  To express if(a < b)
807 
808  use
809 
810  if(LT_LL(a, b))
811 
812 */
813 
LT_LL(LONGLONGCH * a,LONGLONGCH * b)814 int LT_LL(LONGLONGCH *a, LONGLONGCH *b)
815 
816 {
817 
818 	int s = CMP_LL(a, b);		/* a-b */
819 
820 
821 	if(s < 0) return (Yes);
822 
823 	else return (No);
824 
825 }
826 
827 
828 
829 
830 /*
831 
832  Copy Clip Point Function
833 
834 */
835 
CopyClipPoint(CLIP_POINT * cp1,CLIP_POINT * cp2)836 void CopyClipPoint(CLIP_POINT *cp1, CLIP_POINT *cp2)
837 
838 {
839 
840 	cp2->ClipPoint.vx = cp1->ClipPoint.vx;
841 	cp2->ClipPoint.vy = cp1->ClipPoint.vy;
842 	cp2->ClipPoint.vz = cp1->ClipPoint.vz;
843 
844 	cp2->ClipNormal.vx = cp1->ClipNormal.vx;
845 	cp2->ClipNormal.vy = cp1->ClipNormal.vy;
846 	cp2->ClipNormal.vz = cp1->ClipNormal.vz;
847 
848 	cp2->ClipTexel.uuu = cp1->ClipTexel.uuu;
849 	cp2->ClipTexel.vee = cp1->ClipTexel.vee;
850 
851 	cp2->ClipInt     = cp1->ClipInt;
852 	cp2->ClipZBuffer = cp1->ClipZBuffer;
853 
854 }
855 
856 
857 /*
858 
859  Matrix Rotatation of a Vector - Inline Version
860 
861  Overwrite the Source Vector with the Rotated Vector
862 
863  x' = v.c1
864  y' = v.c2
865  z' = v.c3
866 
867 */
868 
RotVect(VECTORCH * v,MATRIXCH * m)869 void RotVect(VECTORCH *v, MATRIXCH *m)
870 
871 {
872 
873 	int x, y, z;
874 
875 	x =  MUL_FIXED(m->mat11, v->vx);
876 	x += MUL_FIXED(m->mat21, v->vy);
877 	x += MUL_FIXED(m->mat31, v->vz);
878 
879 	y  = MUL_FIXED(m->mat12, v->vx);
880 	y += MUL_FIXED(m->mat22, v->vy);
881 	y += MUL_FIXED(m->mat32, v->vz);
882 
883 	z  = MUL_FIXED(m->mat13, v->vx);
884 	z += MUL_FIXED(m->mat23, v->vy);
885 	z += MUL_FIXED(m->mat33, v->vz);
886 
887 	v->vx = x;
888 	v->vy = y;
889 	v->vz = z;
890 
891 }
892 
893 
894 
895 /*
896 
897  Dot Product Function - Inline Version
898 
899  It accepts two pointers to vectors and returns an int result
900 
901 */
902 
_Dot(VECTORCH * vptr1,VECTORCH * vptr2)903 int _Dot(VECTORCH *vptr1, VECTORCH *vptr2)
904 
905 {
906 
907 	int dp;
908 
909 	dp  = MUL_FIXED(vptr1->vx, vptr2->vx);
910 	dp += MUL_FIXED(vptr1->vy, vptr2->vy);
911 	dp += MUL_FIXED(vptr1->vz, vptr2->vz);
912 
913 	return(dp);
914 
915 }
916 
917 
918 /*
919 
920  Make a Vector - Inline Version
921 
922  v3 = v1 - v2
923 
924 */
925 
MakeV(VECTORCH * v1,VECTORCH * v2,VECTORCH * v3)926 void MakeV(VECTORCH *v1, VECTORCH *v2, VECTORCH *v3)
927 
928 {
929 
930 	v3->vx = v1->vx - v2->vx;
931 	v3->vy = v1->vy - v2->vy;
932 	v3->vz = v1->vz - v2->vz;
933 
934 }
935 
936 /*
937 
938  Add a Vector.
939 
940  v2 = v2 + v1
941 
942 */
943 
AddV(VECTORCH * v1,VECTORCH * v2)944 void AddV(VECTORCH *v1, VECTORCH *v2)
945 
946 {
947 
948 	v2->vx += v1->vx;
949 	v2->vy += v1->vy;
950 	v2->vz += v1->vz;
951 
952 }
953