1 /*
2  * KJL 15:13:43 7/17/97 - frustrum.c
3  *
4  * Contains all the functions connected
5  * to the view frustrum and clipping
6  *
7  */
8 #include "3dc.h"
9 #include "module.h"
10 #include "inline.h"
11 
12 #include "stratdef.h"
13 #include "gamedef.h"
14 
15 #include "kshape.h"
16 #include "kzsort.h"
17 #include "frustum.h"
18 
19 #include "particle.h"
20 
21 #define UseLocalAssert Yes
22 #include "ourasert.h"
23 
24 /*KJL****************************************************************************************
25 *  										G L O B A L S 	            					    *
26 ****************************************************************************************KJL*/
27 extern VECTORCH RotatedPts[];
28 
29 extern DISPLAYBLOCK *Global_ODB_Ptr;
30 extern SHAPEHEADER *Global_ShapeHeaderPtr;
31 extern int *Global_ShapePoints;
32 extern int *Global_ShapeNormals;
33 
34 extern VECTORCH LocalView;
35 
36 #define FAR_Z_CLIP 0
37 #define FAR_Z_CLIP_RANGE 49000
38 /*KJL****************************************************************************************
39 *                                    P R O T O T Y P E S	                                *
40 ****************************************************************************************KJL*/
41 /* GOURAUD POLYGON CLIPPING */
42 void (*GouraudPolygon_ClipWithNegativeX)(void);
43 void (*GouraudPolygon_ClipWithPositiveY)(void);
44 void (*GouraudPolygon_ClipWithNegativeY)(void);
45 void (*GouraudPolygon_ClipWithPositiveX)(void);
46 
47 /* TEXTURED POLYGON CLIPPING */
48 void (*TexturedPolygon_ClipWithNegativeX)(void);
49 void (*TexturedPolygon_ClipWithPositiveY)(void);
50 void (*TexturedPolygon_ClipWithNegativeY)(void);
51 void (*TexturedPolygon_ClipWithPositiveX)(void);
52 
53 /* GOURAUD TEXTURED POLYGON CLIPPING */
54 void (*GouraudTexturedPolygon_ClipWithNegativeX)(void);
55 void (*GouraudTexturedPolygon_ClipWithPositiveY)(void);
56 void (*GouraudTexturedPolygon_ClipWithNegativeY)(void);
57 void (*GouraudTexturedPolygon_ClipWithPositiveX)(void);
58 
59 /* FRUSTRUM TESTS */
60 int (*ObjectWithinFrustrum)(DISPLAYBLOCK *dbPtr);
61 int (*ObjectCompletelyWithinFrustrum)(DISPLAYBLOCK *dbPtr);
62 int (*VertexWithinFrustrum)(RENDERVERTEX *vertexPtr);
63 void (*TestVerticesWithFrustrum)(void);
64 
65 
66 static void GouraudPolygon_Norm_ClipWithNegativeX(void);
67 static void GouraudPolygon_Wide_ClipWithNegativeX(void);
68 static void GouraudPolygon_Norm_ClipWithPositiveY(void);
69 static void GouraudPolygon_Wide_ClipWithPositiveY(void);
70 static void GouraudPolygon_Norm_ClipWithNegativeY(void);
71 static void GouraudPolygon_Wide_ClipWithNegativeY(void);
72 static void GouraudPolygon_Norm_ClipWithPositiveX(void);
73 static void GouraudPolygon_Wide_ClipWithPositiveX(void);
74 
75 static void TexturedPolygon_Norm_ClipWithNegativeX(void);
76 static void TexturedPolygon_Wide_ClipWithNegativeX(void);
77 static void TexturedPolygon_Norm_ClipWithPositiveY(void);
78 static void TexturedPolygon_Wide_ClipWithPositiveY(void);
79 static void TexturedPolygon_Norm_ClipWithNegativeY(void);
80 static void TexturedPolygon_Wide_ClipWithNegativeY(void);
81 static void TexturedPolygon_Norm_ClipWithPositiveX(void);
82 static void TexturedPolygon_Wide_ClipWithPositiveX(void);
83 
84 static void GouraudTexturedPolygon_Norm_ClipWithNegativeX(void);
85 static void GouraudTexturedPolygon_Wide_ClipWithNegativeX(void);
86 static void GouraudTexturedPolygon_Norm_ClipWithPositiveY(void);
87 static void GouraudTexturedPolygon_Wide_ClipWithPositiveY(void);
88 static void GouraudTexturedPolygon_Norm_ClipWithNegativeY(void);
89 static void GouraudTexturedPolygon_Wide_ClipWithNegativeY(void);
90 static void GouraudTexturedPolygon_Norm_ClipWithPositiveX(void);
91 static void GouraudTexturedPolygon_Wide_ClipWithPositiveX(void);
92 
93 static int VertexWithin_Norm_Frustrum(RENDERVERTEX *vertexPtr);
94 static int VertexWithin_Wide_Frustrum(RENDERVERTEX *vertexPtr);
95 static int ObjectWithin_Norm_Frustrum(DISPLAYBLOCK *dbPtr);
96 static int ObjectWithin_Wide_Frustrum(DISPLAYBLOCK *dbPtr);
97 static int ObjectCompletelyWithin_Norm_Frustrum(DISPLAYBLOCK *dbPtr);
98 static int ObjectCompletelyWithin_Wide_Frustrum(DISPLAYBLOCK *dbPtr);
99 static void TestVerticesWith_Norm_Frustrum(void);
100 static void TestVerticesWith_Wide_Frustrum(void);
101 
102 /*KJL****************************************************************************************
103 *                                     F U N C T I O N S	                                    *
104 ****************************************************************************************KJL*/
SetFrustrumType(enum FrustrumType frustrumType)105 void SetFrustrumType(enum FrustrumType frustrumType)
106 {
107 	switch (frustrumType)
108 	{
109 		default:
110   		case FRUSTRUM_TYPE_NORMAL:
111 		{
112 			/* GOURAUD POLYGON CLIPPING */
113 			GouraudPolygon_ClipWithNegativeX = GouraudPolygon_Norm_ClipWithNegativeX;
114 			GouraudPolygon_ClipWithPositiveY = GouraudPolygon_Norm_ClipWithPositiveY;
115 			GouraudPolygon_ClipWithNegativeY = GouraudPolygon_Norm_ClipWithNegativeY;
116 			GouraudPolygon_ClipWithPositiveX = GouraudPolygon_Norm_ClipWithPositiveX;
117 
118 			/* TEXTURED POLYGON CLIPPING */
119 			TexturedPolygon_ClipWithNegativeX = TexturedPolygon_Norm_ClipWithNegativeX;
120 			TexturedPolygon_ClipWithPositiveY = TexturedPolygon_Norm_ClipWithPositiveY;
121 			TexturedPolygon_ClipWithNegativeY = TexturedPolygon_Norm_ClipWithNegativeY;
122 			TexturedPolygon_ClipWithPositiveX = TexturedPolygon_Norm_ClipWithPositiveX;
123 
124 			/* GOURAUD TEXTURED POLYGON CLIPPING */
125 			GouraudTexturedPolygon_ClipWithNegativeX = GouraudTexturedPolygon_Norm_ClipWithNegativeX;
126 			GouraudTexturedPolygon_ClipWithPositiveY = GouraudTexturedPolygon_Norm_ClipWithPositiveY;
127 			GouraudTexturedPolygon_ClipWithNegativeY = GouraudTexturedPolygon_Norm_ClipWithNegativeY;
128 			GouraudTexturedPolygon_ClipWithPositiveX = GouraudTexturedPolygon_Norm_ClipWithPositiveX;
129 
130 			/* FRUSTRUM TESTS */
131 			TestVerticesWithFrustrum = TestVerticesWith_Norm_Frustrum;
132 			ObjectWithinFrustrum = ObjectWithin_Norm_Frustrum;
133 			ObjectCompletelyWithinFrustrum = ObjectCompletelyWithin_Norm_Frustrum;
134 			VertexWithinFrustrum = VertexWithin_Norm_Frustrum;
135 
136 			break;
137 		}
138 
139 		case FRUSTRUM_TYPE_WIDE:
140 		{
141 			/* GOURAUD POLYGON CLIPPING */
142 			GouraudPolygon_ClipWithNegativeX = GouraudPolygon_Wide_ClipWithNegativeX;
143 			GouraudPolygon_ClipWithPositiveY = GouraudPolygon_Wide_ClipWithPositiveY;
144 			GouraudPolygon_ClipWithNegativeY = GouraudPolygon_Wide_ClipWithNegativeY;
145 			GouraudPolygon_ClipWithPositiveX = GouraudPolygon_Wide_ClipWithPositiveX;
146 
147 			/* TEXTURED POLYGON CLIPPING */
148 			TexturedPolygon_ClipWithNegativeX = TexturedPolygon_Wide_ClipWithNegativeX;
149 			TexturedPolygon_ClipWithPositiveY = TexturedPolygon_Wide_ClipWithPositiveY;
150 			TexturedPolygon_ClipWithNegativeY = TexturedPolygon_Wide_ClipWithNegativeY;
151 			TexturedPolygon_ClipWithPositiveX = TexturedPolygon_Wide_ClipWithPositiveX;
152 
153 			/* GOURAUD TEXTURED POLYGON CLIPPING */
154 			GouraudTexturedPolygon_ClipWithNegativeX = GouraudTexturedPolygon_Wide_ClipWithNegativeX;
155 			GouraudTexturedPolygon_ClipWithPositiveY = GouraudTexturedPolygon_Wide_ClipWithPositiveY;
156 			GouraudTexturedPolygon_ClipWithNegativeY = GouraudTexturedPolygon_Wide_ClipWithNegativeY;
157 			GouraudTexturedPolygon_ClipWithPositiveX = GouraudTexturedPolygon_Wide_ClipWithPositiveX;
158 
159 			/* FRUSTRUM TESTS */
160 			TestVerticesWithFrustrum = TestVerticesWith_Wide_Frustrum;
161 			ObjectWithinFrustrum = ObjectWithin_Wide_Frustrum;
162 			ObjectCompletelyWithinFrustrum = ObjectCompletelyWithin_Wide_Frustrum;
163 			VertexWithinFrustrum = VertexWithin_Wide_Frustrum;
164 
165 			break;
166 		}
167 	}
168 }
169 
170 /* clipping code macros - these are used as building blocks to assemble
171 clipping fns for different polygon types with the minimum of fuss */
172 #define ZCLIPPINGVALUE 4
173 //64
174 #define Clip_Z_Test(v) (ZCLIPPINGVALUE <= (v)->Z)
175 #define Clip_NX_Test(v) (-(v)->X <= (v)->Z)
176 #define Clip_PX_Test(v) ((v)->X <= (v)->Z)
177 #define Clip_NY_Test(v) (-(v)->Y <= (v)->Z)
178 #define Clip_PY_Test(v) ((v)->Y <= (v)->Z)
179 
180 
181 #define Clip_LoopStart(b) \
182 	do \
183 	{ \
184 		RENDERVERTEX *nextVertexPtr; \
185 		int nextVertexInside; \
186  \
187 		/* setup pointer to next vertex, wrapping round if necessary */ \
188 		if (!--verticesLeft) \
189 		{ \
190 			nextVertexPtr = (b); \
191 		} \
192 		else  \
193 		{ \
194 			nextVertexPtr = curVertexPtr+1; \
195 		} \
196  \
197 		/* if current vertex is inside the plane, output it */ \
198 		if (curVertexInside) \
199 		{ \
200 			numberOfPointsOutputted++; \
201 			*outputVerticesPtr++ = *curVertexPtr; \
202   		} \
203  \
204 		/* test if next vertex is inside the plane */ \
205 			nextVertexInside =
206 
207 #define Clip_Z_OutputXYZ \
208 		/* if one is in, and the other is out, output a clipped vertex */ \
209 		if (nextVertexInside != curVertexInside) \
210 		{ \
211 			int lambda; \
212  \
213 			lambda = DIV_FIXED \
214 			( \
215 				(ZCLIPPINGVALUE - curVertexPtr->Z), \
216 				(nextVertexPtr->Z - curVertexPtr->Z) \
217 			); \
218  \
219 			outputVerticesPtr->X = curVertexPtr->X + MUL_FIXED(lambda,nextVertexPtr->X-curVertexPtr->X); \
220 			outputVerticesPtr->Y = curVertexPtr->Y + MUL_FIXED(lambda,nextVertexPtr->Y-curVertexPtr->Y); \
221 			outputVerticesPtr->Z = ZCLIPPINGVALUE;
222 
223 #define Clip_NX_OutputXYZ \
224 		/* if one is in, and the other is out, output a clipped vertex */ \
225 		if (nextVertexInside != curVertexInside) \
226 		{ \
227 			int lambda; \
228  \
229 			lambda = DIV_FIXED \
230 			( \
231 				(curVertexPtr->Z + curVertexPtr->X), \
232 				-(nextVertexPtr->X-curVertexPtr->X) - (nextVertexPtr->Z-curVertexPtr->Z) \
233 			); \
234  \
235 			outputVerticesPtr->X = curVertexPtr->X + MUL_FIXED(lambda,nextVertexPtr->X-curVertexPtr->X); \
236 			outputVerticesPtr->Z = -outputVerticesPtr->X; \
237 			outputVerticesPtr->Y = curVertexPtr->Y + MUL_FIXED(lambda,nextVertexPtr->Y-curVertexPtr->Y);
238 
239 #define Clip_PX_OutputXYZ \
240 		/* if one is in, and the other is out, output a clipped vertex */ \
241 		if (nextVertexInside != curVertexInside) \
242 		{ \
243 			int lambda; \
244  \
245 			lambda = DIV_FIXED \
246 			( \
247 				(curVertexPtr->Z - curVertexPtr->X), \
248 				(nextVertexPtr->X-curVertexPtr->X) - (nextVertexPtr->Z-curVertexPtr->Z) \
249 			); \
250  \
251 			outputVerticesPtr->X = curVertexPtr->X + MUL_FIXED(lambda,nextVertexPtr->X-curVertexPtr->X); \
252 			outputVerticesPtr->Z = outputVerticesPtr->X; \
253 			outputVerticesPtr->Y = curVertexPtr->Y + MUL_FIXED(lambda,nextVertexPtr->Y-curVertexPtr->Y);
254 
255 #define Clip_NY_OutputXYZ \
256 		/* if one is in, and the other is out, output a clipped vertex */ \
257 		if (nextVertexInside != curVertexInside) \
258 		{ \
259 			int lambda; \
260  \
261 			lambda = DIV_FIXED \
262 			( \
263 				(curVertexPtr->Z + curVertexPtr->Y), \
264 				-(nextVertexPtr->Y-curVertexPtr->Y) - (nextVertexPtr->Z-curVertexPtr->Z) \
265 			); \
266  \
267 			outputVerticesPtr->Z = curVertexPtr->Z + MUL_FIXED(lambda,nextVertexPtr->Z-curVertexPtr->Z); \
268 			outputVerticesPtr->Y = -(outputVerticesPtr->Z); \
269 			outputVerticesPtr->X = curVertexPtr->X + MUL_FIXED(lambda,nextVertexPtr->X-curVertexPtr->X);
270 
271 #define Clip_PY_OutputXYZ \
272 		/* if one is in, and the other is out, output a clipped vertex */ \
273 		if (nextVertexInside != curVertexInside) \
274 		{ \
275 			int lambda; \
276  \
277 			lambda = DIV_FIXED \
278 			( \
279 				(curVertexPtr->Z - curVertexPtr->Y), \
280 				(nextVertexPtr->Y-curVertexPtr->Y) - (nextVertexPtr->Z-curVertexPtr->Z) \
281 			); \
282  \
283 			outputVerticesPtr->Z = curVertexPtr->Z + MUL_FIXED(lambda,nextVertexPtr->Z-curVertexPtr->Z); \
284 			outputVerticesPtr->Y = (outputVerticesPtr->Z); \
285 			outputVerticesPtr->X = curVertexPtr->X + MUL_FIXED(lambda,nextVertexPtr->X-curVertexPtr->X);
286 
287 #define Clip_OutputUV \
288 			outputVerticesPtr->U = curVertexPtr->U + MUL_FIXED(lambda,nextVertexPtr->U-curVertexPtr->U); \
289 			outputVerticesPtr->V = curVertexPtr->V + MUL_FIXED(lambda,nextVertexPtr->V-curVertexPtr->V);
290 
291 #define Clip_OutputI \
292 			outputVerticesPtr->A = curVertexPtr->A + MUL_FIXED(lambda,nextVertexPtr->A-curVertexPtr->A); \
293 			outputVerticesPtr->R = curVertexPtr->R + MUL_FIXED(lambda,nextVertexPtr->R-curVertexPtr->R); \
294 			outputVerticesPtr->G = curVertexPtr->G + MUL_FIXED(lambda,nextVertexPtr->G-curVertexPtr->G); \
295 			outputVerticesPtr->B = curVertexPtr->B + MUL_FIXED(lambda,nextVertexPtr->B-curVertexPtr->B); \
296 			outputVerticesPtr->SpecularR = curVertexPtr->SpecularR + MUL_FIXED(lambda,nextVertexPtr->SpecularR-curVertexPtr->SpecularR); \
297 			outputVerticesPtr->SpecularG = curVertexPtr->SpecularG + MUL_FIXED(lambda,nextVertexPtr->SpecularG-curVertexPtr->SpecularG); \
298 			outputVerticesPtr->SpecularB = curVertexPtr->SpecularB + MUL_FIXED(lambda,nextVertexPtr->SpecularB-curVertexPtr->SpecularB);
299 
300 #define Clip_LoopEnd(b) \
301 			numberOfPointsOutputted++; \
302 			outputVerticesPtr++; \
303 		} \
304  \
305 		/* okay, now the current vertex becomes what was the next vertex */ \
306 		curVertexPtr = nextVertexPtr; \
307 		curVertexInside = nextVertexInside; \
308 	} \
309 	while(verticesLeft); \
310  \
311 	RenderPolygon.NumberOfVertices = numberOfPointsOutputted;
312 
313 /* Wide screen versions of clip macros */
314 
315 #define Clip_Wide_NX_Test(v) (-(v)->X <= (v)->Z*2)
316 #define Clip_Wide_PX_Test(v) ((v)->X <= (v)->Z*2)
317 #define Clip_Wide_NY_Test(v) (-(v)->Y <= (v)->Z*2)
318 #define Clip_Wide_PY_Test(v) ((v)->Y <= (v)->Z*2)
319 #define Clip_Wide_NX_OutputXYZ \
320 		/* if one is in, and the other is out, output a clipped vertex */ \
321 		if (nextVertexInside != curVertexInside) \
322 		{ \
323 			int lambda; \
324  \
325 			lambda = DIV_FIXED \
326 			( \
327 				(-2*curVertexPtr->Z - curVertexPtr->X), \
328 				(nextVertexPtr->X-curVertexPtr->X) - (-2)*(nextVertexPtr->Z-curVertexPtr->Z) \
329 			); \
330  \
331 			outputVerticesPtr->X = curVertexPtr->X + MUL_FIXED(lambda,nextVertexPtr->X-curVertexPtr->X); \
332 			outputVerticesPtr->Z = -outputVerticesPtr->X/2; \
333 			outputVerticesPtr->Y = curVertexPtr->Y + MUL_FIXED(lambda,nextVertexPtr->Y-curVertexPtr->Y);
334 
335 #define Clip_Wide_PX_OutputXYZ \
336 		/* if one is in, and the other is out, output a clipped vertex */ \
337 		if (nextVertexInside != curVertexInside) \
338 		{ \
339 			int lambda; \
340  \
341 			lambda = DIV_FIXED \
342 			( \
343 				(2*curVertexPtr->Z - curVertexPtr->X), \
344 				(nextVertexPtr->X-curVertexPtr->X) - 2*(nextVertexPtr->Z-curVertexPtr->Z) \
345 			); \
346  \
347 			outputVerticesPtr->X = curVertexPtr->X + MUL_FIXED(lambda,nextVertexPtr->X-curVertexPtr->X); \
348 			outputVerticesPtr->Z = outputVerticesPtr->X/2; \
349 			outputVerticesPtr->Y = curVertexPtr->Y + MUL_FIXED(lambda,nextVertexPtr->Y-curVertexPtr->Y);
350 
351 #define Clip_Wide_NY_OutputXYZ \
352 		/* if one is in, and the other is out, output a clipped vertex */ \
353 		if (nextVertexInside != curVertexInside) \
354 		{ \
355 			int lambda; \
356  \
357 			lambda = DIV_FIXED \
358 			( \
359 				(2*curVertexPtr->Z + curVertexPtr->Y), \
360 				-(nextVertexPtr->Y-curVertexPtr->Y) - 2*(nextVertexPtr->Z-curVertexPtr->Z) \
361 			); \
362  \
363 			outputVerticesPtr->Z = curVertexPtr->Z + MUL_FIXED(lambda,nextVertexPtr->Z-curVertexPtr->Z); \
364 			outputVerticesPtr->Y = -(outputVerticesPtr->Z*2); \
365 			outputVerticesPtr->X = curVertexPtr->X + MUL_FIXED(lambda,nextVertexPtr->X-curVertexPtr->X);
366 
367 #define Clip_Wide_PY_OutputXYZ \
368 		/* if one is in, and the other is out, output a clipped vertex */ \
369 		if (nextVertexInside != curVertexInside) \
370 		{ \
371 			int lambda; \
372  \
373 			lambda = DIV_FIXED \
374 			( \
375 				(2*curVertexPtr->Z - curVertexPtr->Y), \
376 				(nextVertexPtr->Y-curVertexPtr->Y) - 2*(nextVertexPtr->Z-curVertexPtr->Z) \
377 			); \
378  \
379 			outputVerticesPtr->Z = curVertexPtr->Z + MUL_FIXED(lambda,nextVertexPtr->Z-curVertexPtr->Z); \
380 			outputVerticesPtr->Y = (outputVerticesPtr->Z*2); \
381 			outputVerticesPtr->X = curVertexPtr->X + MUL_FIXED(lambda,nextVertexPtr->X-curVertexPtr->X);
382 
383 
384 /*KJL**************
385 * GOURAUD POLYGON *
386 **************KJL*/
387 
388 /* Clip against Z plane */
GouraudPolygon_ClipWithZ(void)389 void GouraudPolygon_ClipWithZ(void)
390 {
391 	RENDERVERTEX *curVertexPtr = VerticesBuffer;
392 	RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
393 	int verticesLeft = RenderPolygon.NumberOfVertices;
394 	int numberOfPointsOutputted=0;
395 
396 	int curVertexInside = Clip_Z_Test(curVertexPtr);
397 
398 	Clip_LoopStart(VerticesBuffer)
399 	Clip_Z_Test(nextVertexPtr);
400 	Clip_Z_OutputXYZ
401 	Clip_OutputI
402 	Clip_LoopEnd((RenderPolygon.Vertices))
403 }
404 
405 
406 /* Clip against negative X plane */
GouraudPolygon_Norm_ClipWithNegativeX(void)407 static void GouraudPolygon_Norm_ClipWithNegativeX(void)
408 {
409 	RENDERVERTEX *curVertexPtr = (RenderPolygon.Vertices);
410 	RENDERVERTEX *outputVerticesPtr = VerticesBuffer;
411 	int verticesLeft = RenderPolygon.NumberOfVertices;
412 	int numberOfPointsOutputted=0;
413 
414 	int curVertexInside = Clip_NX_Test(curVertexPtr);
415 
416 	Clip_LoopStart((RenderPolygon.Vertices))
417 	Clip_NX_Test(nextVertexPtr);
418 	Clip_NX_OutputXYZ
419 	Clip_OutputI
420 	Clip_LoopEnd(VerticesBuffer)
421 }
GouraudPolygon_Wide_ClipWithNegativeX(void)422 static void GouraudPolygon_Wide_ClipWithNegativeX(void)
423 {
424 	RENDERVERTEX *curVertexPtr = (RenderPolygon.Vertices);
425 	RENDERVERTEX *outputVerticesPtr = VerticesBuffer;
426 	int verticesLeft = RenderPolygon.NumberOfVertices;
427 	int numberOfPointsOutputted=0;
428 
429 	int curVertexInside = Clip_Wide_NX_Test(curVertexPtr);
430 
431 	Clip_LoopStart((RenderPolygon.Vertices))
432 	Clip_Wide_NX_Test(nextVertexPtr);
433 	Clip_Wide_NX_OutputXYZ
434 	Clip_OutputI
435 	Clip_LoopEnd(VerticesBuffer)
436 }
437 
438 /* Clip against positive Y plane*/
GouraudPolygon_Norm_ClipWithPositiveY(void)439 static void GouraudPolygon_Norm_ClipWithPositiveY(void)
440 {
441 	RENDERVERTEX *curVertexPtr = VerticesBuffer;
442 	RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
443 	int verticesLeft = RenderPolygon.NumberOfVertices;
444 	int numberOfPointsOutputted=0;
445 
446 	int curVertexInside = Clip_PY_Test(curVertexPtr);
447 
448 	Clip_LoopStart(VerticesBuffer)
449 	Clip_PY_Test(nextVertexPtr);
450 	Clip_PY_OutputXYZ
451 	Clip_OutputI
452 	Clip_LoopEnd((RenderPolygon.Vertices))
453 }
GouraudPolygon_Wide_ClipWithPositiveY(void)454 static void GouraudPolygon_Wide_ClipWithPositiveY(void)
455 {
456 	RENDERVERTEX *curVertexPtr = VerticesBuffer;
457 	RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
458 	int verticesLeft = RenderPolygon.NumberOfVertices;
459 	int numberOfPointsOutputted=0;
460 
461 	int curVertexInside = Clip_Wide_PY_Test(curVertexPtr);
462 
463 	Clip_LoopStart(VerticesBuffer)
464 	Clip_Wide_PY_Test(nextVertexPtr);
465 	Clip_Wide_PY_OutputXYZ
466 	Clip_OutputI
467 	Clip_LoopEnd((RenderPolygon.Vertices))
468 }
469 
470 /* Clip against negative Y plane*/
GouraudPolygon_Norm_ClipWithNegativeY(void)471 static void GouraudPolygon_Norm_ClipWithNegativeY(void)
472 {
473 	RENDERVERTEX *curVertexPtr = (RenderPolygon.Vertices);
474 	RENDERVERTEX *outputVerticesPtr = VerticesBuffer;
475 	int verticesLeft = RenderPolygon.NumberOfVertices;
476 	int numberOfPointsOutputted=0;
477 
478 	int curVertexInside = Clip_NY_Test(curVertexPtr);
479 
480 	Clip_LoopStart((RenderPolygon.Vertices))
481 	Clip_NY_Test(nextVertexPtr);
482 	Clip_NY_OutputXYZ
483 	Clip_OutputI
484 	Clip_LoopEnd(VerticesBuffer)
485 }
GouraudPolygon_Wide_ClipWithNegativeY(void)486 static void GouraudPolygon_Wide_ClipWithNegativeY(void)
487 {
488 	RENDERVERTEX *curVertexPtr = (RenderPolygon.Vertices);
489 	RENDERVERTEX *outputVerticesPtr = VerticesBuffer;
490 	int verticesLeft = RenderPolygon.NumberOfVertices;
491 	int numberOfPointsOutputted=0;
492 
493 	int curVertexInside = Clip_Wide_NY_Test(curVertexPtr);
494 
495 	Clip_LoopStart((RenderPolygon.Vertices))
496 	Clip_Wide_NY_Test(nextVertexPtr);
497 	Clip_Wide_NY_OutputXYZ
498 	Clip_OutputI
499 	Clip_LoopEnd(VerticesBuffer)
500 }
501 
502 /* Clip against positive X plane */
GouraudPolygon_Norm_ClipWithPositiveX(void)503 static void GouraudPolygon_Norm_ClipWithPositiveX(void)
504 {
505 	RENDERVERTEX *curVertexPtr = VerticesBuffer;
506 	RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
507 	int verticesLeft = RenderPolygon.NumberOfVertices;
508 	int numberOfPointsOutputted=0;
509 
510 	int curVertexInside = Clip_PX_Test(curVertexPtr);
511 
512 	Clip_LoopStart(VerticesBuffer)
513 	Clip_PX_Test(nextVertexPtr);
514 	Clip_PX_OutputXYZ
515 	Clip_OutputI
516 	Clip_LoopEnd((RenderPolygon.Vertices))
517 }
GouraudPolygon_Wide_ClipWithPositiveX(void)518 static void GouraudPolygon_Wide_ClipWithPositiveX(void)
519 {
520 	RENDERVERTEX *curVertexPtr = VerticesBuffer;
521 	RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
522 	int verticesLeft = RenderPolygon.NumberOfVertices;
523 	int numberOfPointsOutputted=0;
524 
525 	int curVertexInside = Clip_Wide_PX_Test(curVertexPtr);
526 
527 	Clip_LoopStart(VerticesBuffer)
528 	Clip_Wide_PX_Test(nextVertexPtr);
529 	Clip_Wide_PX_OutputXYZ
530 	Clip_OutputI
531 	Clip_LoopEnd((RenderPolygon.Vertices))
532 }
533 
534 /*KJL***************
535 * TEXTURED POLYGON *
536 ***************KJL*/
537 
538 /* Clip against Z plane */
TexturedPolygon_ClipWithZ(void)539 void TexturedPolygon_ClipWithZ(void)
540 {
541 	RENDERVERTEX *curVertexPtr = VerticesBuffer;
542 	RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
543 	int verticesLeft = RenderPolygon.NumberOfVertices;
544 	int numberOfPointsOutputted=0;
545 
546 	int curVertexInside = Clip_Z_Test(curVertexPtr);
547 
548 	Clip_LoopStart(VerticesBuffer)
549 	Clip_Z_Test(nextVertexPtr);
550 	Clip_Z_OutputXYZ
551 	Clip_OutputUV
552 	Clip_OutputI
553 	Clip_LoopEnd((RenderPolygon.Vertices))
554 }
555 
556 /* Clip against negative X plane */
TexturedPolygon_Norm_ClipWithNegativeX(void)557 static void TexturedPolygon_Norm_ClipWithNegativeX(void)
558 {
559 	RENDERVERTEX *curVertexPtr = (RenderPolygon.Vertices);
560 	RENDERVERTEX *outputVerticesPtr = VerticesBuffer;
561 	int verticesLeft = RenderPolygon.NumberOfVertices;
562 	int numberOfPointsOutputted=0;
563 
564 	int curVertexInside = Clip_NX_Test(curVertexPtr);
565 
566 	Clip_LoopStart((RenderPolygon.Vertices))
567 	Clip_NX_Test(nextVertexPtr);
568 	Clip_NX_OutputXYZ
569 	Clip_OutputUV
570 	Clip_OutputI
571 	Clip_LoopEnd(VerticesBuffer)
572 }
TexturedPolygon_Wide_ClipWithNegativeX(void)573 static void TexturedPolygon_Wide_ClipWithNegativeX(void)
574 {
575 	RENDERVERTEX *curVertexPtr = (RenderPolygon.Vertices);
576 	RENDERVERTEX *outputVerticesPtr = VerticesBuffer;
577 	int verticesLeft = RenderPolygon.NumberOfVertices;
578 	int numberOfPointsOutputted=0;
579 
580 	int curVertexInside = Clip_Wide_NX_Test(curVertexPtr);
581 
582 	Clip_LoopStart((RenderPolygon.Vertices))
583 	Clip_Wide_NX_Test(nextVertexPtr);
584 	Clip_Wide_NX_OutputXYZ
585 	Clip_OutputUV
586 	Clip_OutputI
587 	Clip_LoopEnd(VerticesBuffer)
588 }
589 
590 /* Clip against positive Y plane*/
TexturedPolygon_Norm_ClipWithPositiveY(void)591 static void TexturedPolygon_Norm_ClipWithPositiveY(void)
592 {
593 	RENDERVERTEX *curVertexPtr = VerticesBuffer;
594 	RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
595 	int verticesLeft = RenderPolygon.NumberOfVertices;
596 	int numberOfPointsOutputted=0;
597 
598 	int curVertexInside = Clip_PY_Test(curVertexPtr);
599 
600 	Clip_LoopStart(VerticesBuffer)
601 	Clip_PY_Test(nextVertexPtr);
602 	Clip_PY_OutputXYZ
603 	Clip_OutputUV
604 	Clip_OutputI
605 	Clip_LoopEnd((RenderPolygon.Vertices))
606 }
TexturedPolygon_Wide_ClipWithPositiveY(void)607 static void TexturedPolygon_Wide_ClipWithPositiveY(void)
608 {
609 	RENDERVERTEX *curVertexPtr = VerticesBuffer;
610 	RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
611 	int verticesLeft = RenderPolygon.NumberOfVertices;
612 	int numberOfPointsOutputted=0;
613 
614 	int curVertexInside = Clip_Wide_PY_Test(curVertexPtr);
615 
616 	Clip_LoopStart(VerticesBuffer)
617 	Clip_Wide_PY_Test(nextVertexPtr);
618 	Clip_Wide_PY_OutputXYZ
619 	Clip_OutputUV
620 	Clip_OutputI
621 	Clip_LoopEnd((RenderPolygon.Vertices))
622 }
623 
624 /* Clip against negative Y plane*/
TexturedPolygon_Norm_ClipWithNegativeY(void)625 static void TexturedPolygon_Norm_ClipWithNegativeY(void)
626 {
627 	RENDERVERTEX *curVertexPtr = (RenderPolygon.Vertices);
628 	RENDERVERTEX *outputVerticesPtr = VerticesBuffer;
629 	int verticesLeft = RenderPolygon.NumberOfVertices;
630 	int numberOfPointsOutputted=0;
631 
632 	int curVertexInside = Clip_NY_Test(curVertexPtr);
633 
634 	Clip_LoopStart((RenderPolygon.Vertices))
635 	Clip_NY_Test(nextVertexPtr);
636 	Clip_NY_OutputXYZ
637 	Clip_OutputUV
638 	Clip_OutputI
639 	Clip_LoopEnd(VerticesBuffer)
640 }
TexturedPolygon_Wide_ClipWithNegativeY(void)641 static void TexturedPolygon_Wide_ClipWithNegativeY(void)
642 {
643 	RENDERVERTEX *curVertexPtr = (RenderPolygon.Vertices);
644 	RENDERVERTEX *outputVerticesPtr = VerticesBuffer;
645 	int verticesLeft = RenderPolygon.NumberOfVertices;
646 	int numberOfPointsOutputted=0;
647 
648 	int curVertexInside = Clip_Wide_NY_Test(curVertexPtr);
649 
650 	Clip_LoopStart((RenderPolygon.Vertices))
651 	Clip_Wide_NY_Test(nextVertexPtr);
652 	Clip_Wide_NY_OutputXYZ
653 	Clip_OutputUV
654 	Clip_OutputI
655 	Clip_LoopEnd(VerticesBuffer)
656 }
657 
658 /* Clip against positive X plane */
TexturedPolygon_Norm_ClipWithPositiveX(void)659 static void TexturedPolygon_Norm_ClipWithPositiveX(void)
660 {
661 	RENDERVERTEX *curVertexPtr = VerticesBuffer;
662 	RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
663 	int verticesLeft = RenderPolygon.NumberOfVertices;
664 	int numberOfPointsOutputted=0;
665 
666 	int curVertexInside = Clip_PX_Test(curVertexPtr);
667 
668 	Clip_LoopStart(VerticesBuffer)
669 	Clip_PX_Test(nextVertexPtr);
670 	Clip_PX_OutputXYZ
671 	Clip_OutputUV
672 	Clip_OutputI
673 	Clip_LoopEnd((RenderPolygon.Vertices))
674 }
TexturedPolygon_Wide_ClipWithPositiveX(void)675 static void TexturedPolygon_Wide_ClipWithPositiveX(void)
676 {
677 	RENDERVERTEX *curVertexPtr = VerticesBuffer;
678 	RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
679 	int verticesLeft = RenderPolygon.NumberOfVertices;
680 	int numberOfPointsOutputted=0;
681 
682 	int curVertexInside = Clip_Wide_PX_Test(curVertexPtr);
683 
684 	Clip_LoopStart(VerticesBuffer)
685 	Clip_Wide_PX_Test(nextVertexPtr);
686 	Clip_Wide_PX_OutputXYZ
687 	Clip_OutputUV
688 	Clip_OutputI
689 	Clip_LoopEnd((RenderPolygon.Vertices))
690 }
691 
692 
693 
694 
695 /*KJL************************
696 * GOURAUD TEXTURED POLYGONS *
697 ************************KJL*/
698 
699 /* Clip against Z plane */
GouraudTexturedPolygon_ClipWithZ(void)700 void GouraudTexturedPolygon_ClipWithZ(void)
701 {
702 	RENDERVERTEX *curVertexPtr = VerticesBuffer;
703 	RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
704 	int verticesLeft = RenderPolygon.NumberOfVertices;
705 	int numberOfPointsOutputted=0;
706 
707 	int curVertexInside = Clip_Z_Test(curVertexPtr);
708 
709 	Clip_LoopStart(VerticesBuffer)
710 	Clip_Z_Test(nextVertexPtr);
711 	Clip_Z_OutputXYZ
712 	Clip_OutputUV
713 	Clip_OutputI
714 	Clip_LoopEnd((RenderPolygon.Vertices))
715 }
716 
717 /* Clip against negative X plane */
GouraudTexturedPolygon_Norm_ClipWithNegativeX(void)718 static void GouraudTexturedPolygon_Norm_ClipWithNegativeX(void)
719 {
720 	RENDERVERTEX *curVertexPtr = (RenderPolygon.Vertices);
721 	RENDERVERTEX *outputVerticesPtr = VerticesBuffer;
722 	int verticesLeft = RenderPolygon.NumberOfVertices;
723 	int numberOfPointsOutputted=0;
724 
725 	int curVertexInside = Clip_NX_Test(curVertexPtr);
726 
727 	Clip_LoopStart((RenderPolygon.Vertices))
728 	Clip_NX_Test(nextVertexPtr);
729 	Clip_NX_OutputXYZ
730 	Clip_OutputUV
731 	Clip_OutputI
732 	Clip_LoopEnd(VerticesBuffer)
733 }
GouraudTexturedPolygon_Wide_ClipWithNegativeX(void)734 static void GouraudTexturedPolygon_Wide_ClipWithNegativeX(void)
735 {
736 	RENDERVERTEX *curVertexPtr = (RenderPolygon.Vertices);
737 	RENDERVERTEX *outputVerticesPtr = VerticesBuffer;
738 	int verticesLeft = RenderPolygon.NumberOfVertices;
739 	int numberOfPointsOutputted=0;
740 
741 	int curVertexInside = Clip_Wide_NX_Test(curVertexPtr);
742 
743 	Clip_LoopStart((RenderPolygon.Vertices))
744 	Clip_Wide_NX_Test(nextVertexPtr);
745 	Clip_Wide_NX_OutputXYZ
746 	Clip_OutputUV
747 	Clip_OutputI
748 	Clip_LoopEnd(VerticesBuffer)
749 }
750 
751 /* Clip against positive Y plane*/
GouraudTexturedPolygon_Norm_ClipWithPositiveY(void)752 static void GouraudTexturedPolygon_Norm_ClipWithPositiveY(void)
753 {
754 	RENDERVERTEX *curVertexPtr = VerticesBuffer;
755 	RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
756 	int verticesLeft = RenderPolygon.NumberOfVertices;
757 	int numberOfPointsOutputted=0;
758 
759 	int curVertexInside = Clip_PY_Test(curVertexPtr);
760 
761 	Clip_LoopStart(VerticesBuffer)
762 	Clip_PY_Test(nextVertexPtr);
763 	Clip_PY_OutputXYZ
764 	Clip_OutputUV
765 	Clip_OutputI
766 	Clip_LoopEnd((RenderPolygon.Vertices))
767 }
GouraudTexturedPolygon_Wide_ClipWithPositiveY(void)768 static void GouraudTexturedPolygon_Wide_ClipWithPositiveY(void)
769 {
770 	RENDERVERTEX *curVertexPtr = VerticesBuffer;
771 	RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
772 	int verticesLeft = RenderPolygon.NumberOfVertices;
773 	int numberOfPointsOutputted=0;
774 
775 	int curVertexInside = Clip_Wide_PY_Test(curVertexPtr);
776 
777 	Clip_LoopStart(VerticesBuffer)
778 	Clip_Wide_PY_Test(nextVertexPtr);
779 	Clip_Wide_PY_OutputXYZ
780 	Clip_OutputUV
781 	Clip_OutputI
782 	Clip_LoopEnd((RenderPolygon.Vertices))
783 }
784 
785 /* Clip against negative Y plane*/
GouraudTexturedPolygon_Norm_ClipWithNegativeY(void)786 static void GouraudTexturedPolygon_Norm_ClipWithNegativeY(void)
787 {
788 	RENDERVERTEX *curVertexPtr = (RenderPolygon.Vertices);
789 	RENDERVERTEX *outputVerticesPtr = VerticesBuffer;
790 	int verticesLeft = RenderPolygon.NumberOfVertices;
791 	int numberOfPointsOutputted=0;
792 
793 	int curVertexInside = Clip_NY_Test(curVertexPtr);
794 
795 	Clip_LoopStart((RenderPolygon.Vertices))
796 	Clip_NY_Test(nextVertexPtr);
797 	Clip_NY_OutputXYZ
798 	Clip_OutputUV
799 	Clip_OutputI
800 	Clip_LoopEnd(VerticesBuffer)
801 }
GouraudTexturedPolygon_Wide_ClipWithNegativeY(void)802 static void GouraudTexturedPolygon_Wide_ClipWithNegativeY(void)
803 {
804 	RENDERVERTEX *curVertexPtr = (RenderPolygon.Vertices);
805 	RENDERVERTEX *outputVerticesPtr = VerticesBuffer;
806 	int verticesLeft = RenderPolygon.NumberOfVertices;
807 	int numberOfPointsOutputted=0;
808 
809 	int curVertexInside = Clip_Wide_NY_Test(curVertexPtr);
810 
811 	Clip_LoopStart((RenderPolygon.Vertices))
812 	Clip_Wide_NY_Test(nextVertexPtr);
813 	Clip_Wide_NY_OutputXYZ
814 	Clip_OutputUV
815 	Clip_OutputI
816 	Clip_LoopEnd(VerticesBuffer)
817 }
818 
819 /* Clip against positive X plane */
GouraudTexturedPolygon_Norm_ClipWithPositiveX(void)820 static void GouraudTexturedPolygon_Norm_ClipWithPositiveX(void)
821 {
822 	RENDERVERTEX *curVertexPtr = VerticesBuffer;
823 	RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
824 	int verticesLeft = RenderPolygon.NumberOfVertices;
825 	int numberOfPointsOutputted=0;
826 
827 	int curVertexInside = Clip_PX_Test(curVertexPtr);
828 
829 	Clip_LoopStart(VerticesBuffer)
830 	Clip_PX_Test(nextVertexPtr);
831 	Clip_PX_OutputXYZ
832 	Clip_OutputUV
833 	Clip_OutputI
834 	Clip_LoopEnd((RenderPolygon.Vertices))
835 }
GouraudTexturedPolygon_Wide_ClipWithPositiveX(void)836 static void GouraudTexturedPolygon_Wide_ClipWithPositiveX(void)
837 {
838 	RENDERVERTEX *curVertexPtr = VerticesBuffer;
839 	RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
840 	int verticesLeft = RenderPolygon.NumberOfVertices;
841 	int numberOfPointsOutputted=0;
842 
843 	int curVertexInside = Clip_Wide_PX_Test(curVertexPtr);
844 
845 	Clip_LoopStart(VerticesBuffer)
846 	Clip_Wide_PX_Test(nextVertexPtr);
847 	Clip_Wide_PX_OutputXYZ
848 	Clip_OutputUV
849 	Clip_OutputI
850 	Clip_LoopEnd((RenderPolygon.Vertices))
851 }
852 
853 
854 
855 
856 
857 
858 
PolygonWithinFrustrum(POLYHEADER * polyPtr)859 int PolygonWithinFrustrum(POLYHEADER *polyPtr)
860 {
861     char inFrustrumFlag=0;
862    	char noClippingFlag=INSIDE_FRUSTRUM;
863 	int *vertexNumberPtr = &polyPtr->Poly1stPt;
864 
865 	if (polyPtr->PolyFlags & iflag_notvis) return 0;
866 
867 	RenderPolygon.NumberOfVertices=0;
868 	while(*vertexNumberPtr != Term)
869 	{
870 		int vertexNumber = *vertexNumberPtr++;
871 
872 		inFrustrumFlag |= FrustrumFlagForVertex[vertexNumber];
873 		noClippingFlag &= FrustrumFlagForVertex[vertexNumber];
874 
875 		/* count the number of points in the polygon; this is used for all the loops that follow */
876 	   	RenderPolygon.NumberOfVertices++;
877 	}
878 
879 	if (inFrustrumFlag != INSIDE_FRUSTRUM) return 0;
880 
881 	/* at this point we know that the poly is inside the view frustrum */
882 
883 	/* if not a sprite, test direction of poly */
884 	if (!( (Global_ShapeHeaderPtr->shapeflags&ShapeFlag_Sprite) || (polyPtr->PolyFlags & iflag_no_bfc) ))
885 	{
886 		VECTORCH pop;
887 		VECTORCH *normalPtr = (VECTORCH*)(Global_ShapeNormals + polyPtr->PolyNormalIndex);
888 
889 		#if 1
890 		if(Global_ODB_Ptr->ObMorphCtrl)
891 		{
892 			extern MORPHDISPLAY MorphDisplay;
893 		   	SHAPEHEADER *shape1Ptr;
894 		   	VECTORCH *shape1PointsPtr;
895 			VECTORCH *shape2PointsPtr;
896 
897 			/* Set up the morph data */
898 			GetMorphDisplay(&MorphDisplay, Global_ODB_Ptr);
899 
900 			shape1Ptr = MorphDisplay.md_sptr1;
901 
902 			if(MorphDisplay.md_lerp == 0x0000)
903 			{
904 				shape1PointsPtr = (VECTORCH *)*shape1Ptr->points;
905 				pop = shape1PointsPtr[polyPtr->Poly1stPt];
906 
907 			}
908 			else if(MorphDisplay.md_lerp == 0xffff)
909 			{
910 				SHAPEHEADER *shape2Ptr = MorphDisplay.md_sptr2;
911 
912 				shape2PointsPtr = (VECTORCH *)*shape2Ptr->points;
913 				pop = shape2PointsPtr[polyPtr->Poly1stPt];
914 			}
915 			else
916 			{
917 				SHAPEHEADER *shape2Ptr = MorphDisplay.md_sptr2;
918 
919 				shape1PointsPtr = (VECTORCH *)(*shape1Ptr->points);
920 				shape2PointsPtr = (VECTORCH *)(*shape2Ptr->points);
921 
922 				{
923 				   	VECTORCH vertex1 = shape1PointsPtr[polyPtr->Poly1stPt];
924 				   	VECTORCH vertex2 = shape2PointsPtr[polyPtr->Poly1stPt];
925 
926 					if( (vertex1.vx == vertex2.vx && vertex1.vy == vertex2.vy && vertex1.vz == vertex2.vz) )
927 					{
928 						pop = vertex1;
929 					}
930 					else
931 					{
932 						/* KJL 15:27:20 05/22/97 - I've changed this to speed things up, If a vertex
933 						component has a magnitude greater than 32768 things will go wrong. */
934 						pop.vx = vertex1.vx + (((vertex2.vx-vertex1.vx)*MorphDisplay.md_lerp)>>16);
935 						pop.vy = vertex1.vy + (((vertex2.vy-vertex1.vy)*MorphDisplay.md_lerp)>>16);
936 						pop.vz = vertex1.vz + (((vertex2.vz-vertex1.vz)*MorphDisplay.md_lerp)>>16);
937 					}
938 				}
939 			}
940  		}
941 		else
942 		#endif
943 		{
944 			/* Get the 1st polygon point as the POP */
945 			VECTORCH *pointsArray = (VECTORCH*)(Global_ShapePoints);
946 			pop = pointsArray[polyPtr->Poly1stPt];
947 		}
948 		pop.vx -= LocalView.vx;
949 		pop.vy -= LocalView.vy;
950 		pop.vz -= LocalView.vz;
951 
952 		if (Dot(&pop, normalPtr)>0) return 0;
953 	}
954 
955 	if (noClippingFlag == INSIDE_FRUSTRUM) return 2;
956 
957 	/* yes, we need to draw poly */
958 	return 1;
959 }
960 
PolygonShouldBeDrawn(POLYHEADER * polyPtr)961 int PolygonShouldBeDrawn(POLYHEADER *polyPtr)
962 {
963 
964 	/* at this point we know that the poly is inside the view frustrum */
965 	if (polyPtr->PolyFlags & iflag_notvis) return 0;
966 
967 	#if 1
968 	/* if not a sprite, test direction of poly */
969 	if (!( (Global_ShapeHeaderPtr->shapeflags&ShapeFlag_Sprite) || (polyPtr->PolyFlags & iflag_no_bfc) ))
970 	{
971 		/* KJL 16:49:14 7/10/97 -
972 
973 		***** MORPHED NORMALS SUPPORT NOT YET ADDED *****
974 
975 		*/
976 		VECTORCH pop;
977 		VECTORCH *normalPtr = (VECTORCH*)(Global_ShapeNormals + polyPtr->PolyNormalIndex);
978 		VECTORCH *pointsArray = (VECTORCH*)(Global_ShapePoints);
979 		/* Get the 1st polygon point as the POP */
980 
981 		pop.vx = pointsArray[polyPtr->Poly1stPt].vx - LocalView.vx;
982 		pop.vy = pointsArray[polyPtr->Poly1stPt].vy - LocalView.vy;
983 		pop.vz = pointsArray[polyPtr->Poly1stPt].vz - LocalView.vz;
984 
985 		if (Dot(&pop, normalPtr)>0) return 0;
986 	}
987 	#endif
988 	#if 0
989 	{
990 		int *vertexNumberPtr = &polyPtr->Poly1stPt;
991 		RenderPolygon.NumberOfVertices=0;
992 		while(*vertexNumberPtr++ != Term)
993 		{
994 			/* count the number of points in the polygon; this is used for all the loops that follow */
995 		   	RenderPolygon.NumberOfVertices++;
996 		}
997 	}
998 	#elif 0
999 	RenderPolygon.NumberOfVertices = 3;
1000 	#else
1001 	{
1002 		int *vertexNumberPtr = &polyPtr->Poly1stPt;
1003 		if (vertexNumberPtr[3] == Term)
1004 		{
1005 			RenderPolygon.NumberOfVertices = 3;
1006 		}
1007 		else
1008 		{
1009 			RenderPolygon.NumberOfVertices = 4;
1010 		}
1011 	}
1012 	#endif
1013 
1014 	return 2;
1015 }
1016 
1017 /* KJL 16:18:59 7/7/97 - simple vertex test to be used in first
1018 pass of subdividing code */
VertexWithin_Norm_Frustrum(RENDERVERTEX * vertexPtr)1019 static int VertexWithin_Norm_Frustrum(RENDERVERTEX *vertexPtr)
1020 {
1021 	int vertexFlag = 0;
1022 
1023 	if(Clip_Z_Test(vertexPtr))	vertexFlag |= INSIDE_FRUSTRUM_Z_PLANE;
1024 	if(Clip_PX_Test(vertexPtr))	vertexFlag |= INSIDE_FRUSTRUM_PX_PLANE;
1025 	if(Clip_NX_Test(vertexPtr))	vertexFlag |= INSIDE_FRUSTRUM_NX_PLANE;
1026 	if(Clip_PY_Test(vertexPtr))	vertexFlag |= INSIDE_FRUSTRUM_PY_PLANE;
1027 	if(Clip_NY_Test(vertexPtr))	vertexFlag |= INSIDE_FRUSTRUM_NY_PLANE;
1028 
1029 	return vertexFlag;
1030 }
1031 
VertexWithin_Wide_Frustrum(RENDERVERTEX * vertexPtr)1032 static int VertexWithin_Wide_Frustrum(RENDERVERTEX *vertexPtr)
1033 {
1034 	int vertexFlag = 0;
1035 
1036 	if(Clip_Z_Test(vertexPtr))			vertexFlag |= INSIDE_FRUSTRUM_Z_PLANE;
1037 	if(Clip_Wide_PX_Test(vertexPtr))	vertexFlag |= INSIDE_FRUSTRUM_PX_PLANE;
1038 	if(Clip_Wide_NX_Test(vertexPtr))	vertexFlag |= INSIDE_FRUSTRUM_NX_PLANE;
1039 	if(Clip_Wide_PY_Test(vertexPtr))	vertexFlag |= INSIDE_FRUSTRUM_PY_PLANE;
1040 	if(Clip_Wide_NY_Test(vertexPtr))	vertexFlag |= INSIDE_FRUSTRUM_NY_PLANE;
1041 
1042 	return vertexFlag;
1043 }
1044 
1045 
1046 /* KJL 15:32:52 7/17/97 - Test to see if an object is in the view frustrum */
ObjectWithin_Norm_Frustrum(DISPLAYBLOCK * dbPtr)1047 static int ObjectWithin_Norm_Frustrum(DISPLAYBLOCK *dbPtr)
1048 {
1049  //	LOCALASSERT(dbPtr->ObShapeData->shaperadius);
1050 
1051 #if FAR_Z_CLIP
1052 	if(dbPtr->ObView.vz-dbPtr->ObShapeData->shaperadius<=FAR_Z_CLIP_RANGE)
1053 #endif
1054 	if (dbPtr->ObView.vz+dbPtr->ObShapeData->shaperadius>=ZCLIPPINGVALUE)
1055 	{
1056 		/* scale radius by square root of 2 */
1057 		int radius = MUL_FIXED(92682,dbPtr->ObShapeData->shaperadius);
1058 
1059 		if ((dbPtr->ObView.vx-dbPtr->ObView.vz)<=radius)
1060 			if ((-dbPtr->ObView.vx-dbPtr->ObView.vz)<=radius)
1061 				if ((dbPtr->ObView.vy-dbPtr->ObView.vz)<=radius)
1062 					if ((-dbPtr->ObView.vy-dbPtr->ObView.vz)<=radius)
1063 						return 1;
1064 	}
1065 	return 0;
1066 }
ObjectCompletelyWithin_Norm_Frustrum(DISPLAYBLOCK * dbPtr)1067 static int ObjectCompletelyWithin_Norm_Frustrum(DISPLAYBLOCK *dbPtr)
1068 {
1069  //	LOCALASSERT(dbPtr->ObShapeData->shaperadius);
1070 	if (dbPtr->ObView.vz-dbPtr->ObShapeData->shaperadius>=ZCLIPPINGVALUE)
1071 	{
1072 		/* scale radius by square root of 2 */
1073 		int radius = MUL_FIXED(92682,dbPtr->ObShapeData->shaperadius);
1074 
1075 		if ((dbPtr->ObView.vz-dbPtr->ObView.vx)>=radius)
1076 			if ((dbPtr->ObView.vz+dbPtr->ObView.vx)>=radius)
1077 				if ((dbPtr->ObView.vz-dbPtr->ObView.vy)>=radius)
1078 					if ((dbPtr->ObView.vz+dbPtr->ObView.vy)>=radius)
1079 						return 1;
1080 	}
1081 	return 0;
1082 }
ObjectCompletelyWithin_Wide_Frustrum(DISPLAYBLOCK * dbPtr)1083 static int ObjectCompletelyWithin_Wide_Frustrum(DISPLAYBLOCK *dbPtr)
1084 {
1085 	return 0;
1086 }
1087 
ObjectWithin_Wide_Frustrum(DISPLAYBLOCK * dbPtr)1088 static int ObjectWithin_Wide_Frustrum(DISPLAYBLOCK *dbPtr)
1089 {
1090 	if (dbPtr->ObView.vz+dbPtr->ObShapeData->shaperadius>=ZCLIPPINGVALUE)
1091 	{
1092 		/* scale radius by square root of 5 */
1093 		int radius = MUL_FIXED(146543,dbPtr->ObShapeData->shaperadius);
1094 
1095 		if ((dbPtr->ObView.vx-2*dbPtr->ObView.vz)<=radius)
1096 			if ((-dbPtr->ObView.vx-2*dbPtr->ObView.vz)<=radius)
1097 				if ((dbPtr->ObView.vy-2*dbPtr->ObView.vz)<=radius)
1098 					if ((-dbPtr->ObView.vy-2*dbPtr->ObView.vz)<=radius)
1099 						return 1;
1100 	}
1101 	return 0;
1102 }
1103 
1104 
1105 char FrustrumFlagForVertex[maxrotpts];
1106 
TestVerticesWith_Norm_Frustrum(void)1107 void TestVerticesWith_Norm_Frustrum(void)
1108 {
1109 	int v = Global_ShapeHeaderPtr->numpoints;
1110 
1111 	GLOBALASSERT(v>0);
1112 
1113 	while(v--)
1114 	{
1115 		char vertexFlag = 0;
1116 
1117 #if FAR_Z_CLIP
1118 		if(ZCLIPPINGVALUE <= RotatedPts[v].vz && RotatedPts[v].vz<=FAR_Z_CLIP_RANGE)
1119 #else
1120 		if(ZCLIPPINGVALUE <= RotatedPts[v].vz)
1121 #endif
1122 			vertexFlag |= INSIDE_FRUSTRUM_Z_PLANE;
1123 
1124 		if(-RotatedPts[v].vx <= RotatedPts[v].vz)
1125 			vertexFlag |= INSIDE_FRUSTRUM_PX_PLANE;
1126 
1127 		if(RotatedPts[v].vx <= RotatedPts[v].vz)
1128 			vertexFlag |= INSIDE_FRUSTRUM_NX_PLANE;
1129 
1130 		if(-RotatedPts[v].vy <= RotatedPts[v].vz)
1131 			vertexFlag |= INSIDE_FRUSTRUM_PY_PLANE;
1132 
1133 		if(RotatedPts[v].vy <= RotatedPts[v].vz)
1134 			vertexFlag |= INSIDE_FRUSTRUM_NY_PLANE;
1135 
1136 		FrustrumFlagForVertex[v] = vertexFlag;
1137 	}
1138 }
TestVerticesWith_Wide_Frustrum(void)1139 void TestVerticesWith_Wide_Frustrum(void)
1140 {
1141 	int v = Global_ShapeHeaderPtr->numpoints;
1142 
1143 	GLOBALASSERT(v>0);
1144 
1145 	while(v--)
1146 	{
1147 		char vertexFlag = 0;
1148 
1149 		if(ZCLIPPINGVALUE <= RotatedPts[v].vz)
1150 			vertexFlag |= INSIDE_FRUSTRUM_Z_PLANE;
1151 
1152 		if(-RotatedPts[v].vx <= RotatedPts[v].vz*2)
1153 			vertexFlag |= INSIDE_FRUSTRUM_PX_PLANE;
1154 
1155 		if(RotatedPts[v].vx <= RotatedPts[v].vz*2)
1156 			vertexFlag |= INSIDE_FRUSTRUM_NX_PLANE;
1157 
1158 		if(-RotatedPts[v].vy <= RotatedPts[v].vz*2)
1159 			vertexFlag |= INSIDE_FRUSTRUM_PY_PLANE;
1160 
1161 		if(RotatedPts[v].vy <= RotatedPts[v].vz*2)
1162 			vertexFlag |= INSIDE_FRUSTRUM_NY_PLANE;
1163 
1164 		FrustrumFlagForVertex[v] = vertexFlag;
1165 	}
1166 }
1167 
1168 
1169 
DecalWithinFrustrum(DECAL * decalPtr)1170 int DecalWithinFrustrum(DECAL *decalPtr)
1171 {
1172 	char inFrustrumFlag;
1173 	char noClippingFlag;
1174 
1175 	if(ModuleCurrVisArray[decalPtr->ModuleIndex] != 2) return 0;
1176 
1177     inFrustrumFlag=0;
1178    	noClippingFlag=INSIDE_FRUSTRUM;
1179 
1180 	{
1181 		int vertexFlag = VertexWithinFrustrum(&VerticesBuffer[0]);
1182 		inFrustrumFlag |= vertexFlag;
1183 		noClippingFlag &= vertexFlag;
1184 	}
1185 	{
1186 		int vertexFlag = VertexWithinFrustrum(&VerticesBuffer[1]);
1187 		inFrustrumFlag |= vertexFlag;
1188 		noClippingFlag &= vertexFlag;
1189 	}
1190 	{
1191 		int vertexFlag = VertexWithinFrustrum(&VerticesBuffer[2]);
1192 		inFrustrumFlag |= vertexFlag;
1193 		noClippingFlag &= vertexFlag;
1194 	}
1195 	{
1196 		int vertexFlag = VertexWithinFrustrum(&VerticesBuffer[3]);
1197 		inFrustrumFlag |= vertexFlag;
1198 		noClippingFlag &= vertexFlag;
1199 	}
1200 
1201 	if (inFrustrumFlag != INSIDE_FRUSTRUM) return 0;
1202 	if (noClippingFlag == INSIDE_FRUSTRUM) return 2;
1203 
1204 	/* yes, we need to draw poly */
1205 	return 1;
1206 }
1207 
QuadWithinFrustrum(void)1208 int QuadWithinFrustrum(void)
1209 {
1210 	char inFrustrumFlag;
1211 	char noClippingFlag;
1212 
1213     inFrustrumFlag=0;
1214    	noClippingFlag=INSIDE_FRUSTRUM;
1215 
1216 	{
1217 		int vertexFlag = VertexWithinFrustrum(&VerticesBuffer[0]);
1218 		inFrustrumFlag |= vertexFlag;
1219 		noClippingFlag &= vertexFlag;
1220 	}
1221 	{
1222 		int vertexFlag = VertexWithinFrustrum(&VerticesBuffer[1]);
1223 		inFrustrumFlag |= vertexFlag;
1224 		noClippingFlag &= vertexFlag;
1225 	}
1226 	{
1227 		int vertexFlag = VertexWithinFrustrum(&VerticesBuffer[2]);
1228 		inFrustrumFlag |= vertexFlag;
1229 		noClippingFlag &= vertexFlag;
1230 	}
1231 	{
1232 		int vertexFlag = VertexWithinFrustrum(&VerticesBuffer[3]);
1233 		inFrustrumFlag |= vertexFlag;
1234 		noClippingFlag &= vertexFlag;
1235 	}
1236 
1237 	if (inFrustrumFlag != INSIDE_FRUSTRUM) return 0;
1238 	if (noClippingFlag == INSIDE_FRUSTRUM) return 2;
1239 
1240 	/* yes, we need to draw poly */
1241 	return 1;
1242 }
1243 
TriangleWithinFrustrum(void)1244 int TriangleWithinFrustrum(void)
1245 {
1246 	char inFrustrumFlag;
1247 	char noClippingFlag;
1248 
1249     inFrustrumFlag=0;
1250    	noClippingFlag=INSIDE_FRUSTRUM;
1251 
1252 	{
1253 		int vertexFlag = VertexWithinFrustrum(&VerticesBuffer[0]);
1254 		inFrustrumFlag |= vertexFlag;
1255 		noClippingFlag &= vertexFlag;
1256 	}
1257 	{
1258 		int vertexFlag = VertexWithinFrustrum(&VerticesBuffer[1]);
1259 		inFrustrumFlag |= vertexFlag;
1260 		noClippingFlag &= vertexFlag;
1261 	}
1262 	{
1263 		int vertexFlag = VertexWithinFrustrum(&VerticesBuffer[2]);
1264 		inFrustrumFlag |= vertexFlag;
1265 		noClippingFlag &= vertexFlag;
1266 	}
1267 
1268 	if (inFrustrumFlag != INSIDE_FRUSTRUM) return 0;
1269 	if (noClippingFlag == INSIDE_FRUSTRUM) return 2;
1270 
1271 	/* yes, we need to draw poly */
1272 	return 1;
1273 }
1274