1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 
5 #include "oglfunc.h"
6 
7 #include "fixer.h"
8 
9 #include "3dc.h"
10 #include "platform.h"
11 #include "inline.h"
12 #include "module.h"
13 #include "stratdef.h"
14 #include "projfont.h"
15 #include "kshape.h"
16 #include "prototyp.h"
17 #include "frustum.h"
18 #include "lighting.h"
19 #include "bh_types.h"
20 #include "showcmds.h"
21 #include "d3d_hud.h"
22 #include "hud_layout.h"
23 #include "avp_userprofile.h"
24 #include "aw.h"
25 #include "opengl.h"
26 
27 int LightIntensityAtPoint(VECTORCH *pointPtr);
28 
29 extern IMAGEHEADER ImageHeaderArray[];
30 extern VIEWDESCRIPTORBLOCK *Global_VDB_Ptr;
31 extern unsigned char GammaValues[256];
32 extern SCREENDESCRIPTORBLOCK ScreenDescriptorBlock;
33 
34 extern int SpecialFXImageNumber;
35 extern int StaticImageNumber;
36 extern int PredatorNumbersImageNumber;
37 extern int BurningImageNumber;
38 extern int ChromeImageNumber;
39 extern int WaterShaftImageNumber;
40 extern int HUDFontsImageNumber;
41 extern int AAFontImageNumber;
42 
43 extern int FMVParticleColour;
44 extern int HUDScaleFactor;
45 extern int CloakingPhase;
46 
47 static D3DTexture *CurrTextureHandle;
48 
49 enum AVP_SHADER_PROGRAM CurrShaderProgram;
50 
51 GLuint DefaultTexture;
52 
53 static enum TRANSLUCENCY_TYPE CurrentTranslucencyMode = TRANSLUCENCY_OFF;
54 static enum FILTERING_MODE_ID CurrentFilteringMode = FILTERING_BILINEAR_OFF;
55 static GLenum TextureMinFilter = GL_LINEAR; //GL_LINEAR_MIPMAP_LINEAR;
56 static D3DTexture *CurrentlyBoundTexture = NULL;
57 
58 #if defined(_MSC_VER)
59 #define ALIGN16 __declspec(align(16))
60 #else
61 #define ALIGN16 __attribute__((__aligned__(16)))
62 #endif
63 
64 // need to look into this again at some point
65 // everything but the hud rendering used an offset
66 #define TEXCOORD_FIXED(s, r) (((float)((s)+(0<<15))) * (r))
67 
68 #define TA_MAXVERTICES		2048
69 #define TA_MAXTRIANGLES		2048
70 
71 typedef struct VertexArray
72 {
73 	GLfloat v[4];
74 	GLfloat t[2];
75 	GLubyte c[4];
76 	GLubyte s[4];
77 } VertexArray;
78 
79 typedef struct TriangleArray
80 {
81 	unsigned short a;
82 	unsigned short b;
83 	unsigned short c;
84 } TriangleArray;
85 
86 static ALIGN16 VertexArray varr[TA_MAXVERTICES];
87 static ALIGN16 TriangleArray tarr[TA_MAXTRIANGLES];
88 static VertexArray *varrp = varr;
89 static TriangleArray *tarrp = tarr;
90 static int varrc, tarrc;
91 
92 static GLuint ElementArrayBuffer;
93 static GLuint ArrayBuffer;
94 
95 /* Do not call this directly! */
SetTranslucencyMode(enum TRANSLUCENCY_TYPE mode)96 static void SetTranslucencyMode(enum TRANSLUCENCY_TYPE mode)
97 {
98 	switch(mode) {
99 		case TRANSLUCENCY_OFF:
100 			if (TRIPTASTIC_CHEATMODE||MOTIONBLUR_CHEATMODE) {
101 				pglBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA);
102 			} else {
103 				pglBlendFunc(GL_ONE, GL_ZERO);
104 			}
105 			break;
106 		case TRANSLUCENCY_NORMAL:
107 			pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
108 			break;
109 		case TRANSLUCENCY_COLOUR:
110 			pglBlendFunc(GL_ZERO, GL_SRC_COLOR);
111 			break;
112 		case TRANSLUCENCY_INVCOLOUR:
113 			pglBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
114 			break;
115 		case TRANSLUCENCY_GLOWING:
116 			pglBlendFunc(GL_SRC_ALPHA, GL_ONE);
117 			break;
118 		case TRANSLUCENCY_DARKENINGCOLOUR:
119 			pglBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO);
120 			break;
121 		case TRANSLUCENCY_JUSTSETZ:
122 			pglBlendFunc(GL_ZERO, GL_ONE);
123 			break;
124 		default:
125 			fprintf(stderr, "SetTranslucencyMode: invalid blend mode %d\n", mode);
126 			break;
127 	}
128 }
129 
130 #if defined(USE_OPENGL_ES)
131 #define SHADER_PRAGMAS "\n"
132 #define SHADER_VERSION "#version 100\n"
133 #else
134 #define SHADER_PRAGMAS "\n"
135 #define SHADER_VERSION "#version 120\n"
136 #endif
137 
138 #if USE_OPENGL_ES
139 
140 #define SHADER_SETUP \
141 "#define HIGHP highp\n" \
142 "#define MEDIUMP mediump\n" \
143 "#define LOWP lowp\n"
144 
145 #else
146 
147 #define SHADER_SETUP \
148 "#ifdef GL_ES\n" \
149 "#define HIGHP highp\n" \
150 "#define MEDIUMP mediump\n" \
151 "#define LOWP lowp\n" \
152 "#else\n" \
153 "#define HIGHP\n" \
154 "#define MEDIUMP\n" \
155 "#define LOWP\n" \
156 "#endif\n"
157 
158 #endif
159 
160 static const char AVP_VERTEX_SHADER_SOURCE[] =
161    SHADER_VERSION
162    SHADER_PRAGMAS
163    SHADER_SETUP
164    "\n"
165    "attribute HIGHP vec4 aVertex;\n"
166    "attribute HIGHP vec2 aTexCoord;\n"
167    "attribute LOWP vec4 aColor0;\n"
168    "attribute LOWP vec4 aColor1;\n"
169    "\n"
170    "varying HIGHP vec2 vTexCoord;\n"
171    "varying LOWP vec4 vColor0;\n"
172    "varying LOWP vec4 vColor1;\n"
173    "\n"
174    "void main(void)\n"
175    "{\n"
176    "	gl_Position = aVertex;\n"
177    "	vTexCoord	= aTexCoord;\n"
178    "	vColor0		= aColor0;\n"
179    "	vColor1     = aColor1;\n"
180    "}\n"
181    ;
182 
183 static const char AVP_VERTEX_SHADER_SOURCE_NO_SECONDARY[] =
184    SHADER_VERSION
185    SHADER_PRAGMAS
186    SHADER_SETUP
187    "\n"
188    "attribute HIGHP vec4 aVertex;\n"
189    "attribute HIGHP vec2 aTexCoord;\n"
190    "attribute LOWP vec4 aColor0;\n"
191    "\n"
192    "varying HIGHP vec2 vTexCoord;\n"
193    "varying LOWP vec4 vColor0;\n"
194    "\n"
195    "void main(void)\n"
196    "{\n"
197    "	gl_Position = aVertex;\n"
198    "	vTexCoord	= aTexCoord;\n"
199    "	vColor0		= aColor0;\n"
200    "}\n"
201    ;
202 
203 static const char AVP_VERTEX_SHADER_SOURCE_NO_TEXTURE[] =
204    SHADER_VERSION
205    SHADER_PRAGMAS
206    SHADER_SETUP
207    "\n"
208    "attribute HIGHP vec4 aVertex;\n"
209    "attribute LOWP vec4 aColor0;\n"
210    "\n"
211    "varying LOWP vec4 vColor0;\n"
212    "\n"
213    "void main(void)\n"
214    "{\n"
215    "	gl_Position = aVertex;\n"
216    "	vColor0		= aColor0;\n"
217    "}\n"
218    ;
219 
220 static const char AVP_VERTEX_SHADER_SOURCE_NO_COLOR[] =
221    SHADER_VERSION
222    SHADER_PRAGMAS
223    SHADER_SETUP
224    "\n"
225    "attribute HIGHP vec4 aVertex;\n"
226    "attribute HIGHP vec2 aTexCoord;\n"
227    "\n"
228    "varying HIGHP vec2 vTexCoord;\n"
229    "\n"
230    "void main(void)\n"
231    "{\n"
232    "	gl_Position = aVertex;\n"
233    "	vTexCoord	= aTexCoord;\n"
234    "}\n"
235    ;
236 
237 static const char AVP_FRAGMENT_SHADER_SOURCE[] =
238    SHADER_VERSION
239    SHADER_PRAGMAS
240    SHADER_SETUP
241    "\n"
242    "uniform LOWP sampler2D uTexture;\n"
243    "\n"
244    "varying HIGHP vec2 vTexCoord;\n"
245    "varying LOWP vec4 vColor0;\n"
246    "varying LOWP vec4 vColor1;\n"
247    "\n"
248    "void main(void)\n"
249    "{\n"
250    "\n"
251    "	MEDIUMP vec4 t       = texture2D( uTexture, vTexCoord );\n"
252    "	if (t.a == 0.0) discard;\n"
253    "	gl_FragColor = t * vColor0 + vColor1;\n"
254    "}\n"
255    ;
256 
257 static const char AVP_FRAGMENT_SHADER_SOURCE_NO_SECONDARY[] =
258    SHADER_VERSION
259    SHADER_PRAGMAS
260    SHADER_SETUP
261    "\n"
262    "uniform LOWP sampler2D uTexture;\n"
263    "\n"
264    "varying HIGHP vec2 vTexCoord;\n"
265    "varying LOWP vec4 vColor0;\n"
266    "\n"
267    "void main(void)\n"
268    "{\n"
269    "	MEDIUMP vec4 t       = texture2D( uTexture, vTexCoord );\n"
270    "	if (t.a == 0.0) discard;\n"
271    "	gl_FragColor = t * vColor0;\n"
272    "}\n"
273    ;
274 
275 static const char AVP_FRAGMENT_SHADER_SOURCE_NO_TEXTURE[] =
276    SHADER_VERSION
277    SHADER_PRAGMAS
278    SHADER_SETUP
279    "\n"
280    "varying LOWP vec4 vColor0;\n"
281    "\n"
282    "void main(void)\n"
283    "{\n"
284    "	gl_FragColor = vColor0;\n"
285    "}\n"
286    ;
287 
288 static const char AVP_FRAGMENT_SHADER_SOURCE_NO_DISCARD[] =
289    SHADER_VERSION
290    SHADER_PRAGMAS
291    SHADER_SETUP
292    "\n"
293    "uniform LOWP sampler2D uTexture;\n"
294    "\n"
295    "varying HIGHP vec2 vTexCoord;\n"
296    "varying LOWP vec4 vColor0;\n"
297    "varying LOWP vec4 vColor1;\n"
298    "\n"
299    "void main(void)\n"
300    "{\n"
301    "	MEDIUMP vec4 t       = texture2D( uTexture, vTexCoord );\n"
302    "	gl_FragColor = t * vColor0 + vColor1;\n"
303    "}\n"
304    ;
305 
306 static const char AVP_FRAGMENT_SHADER_SOURCE_NO_SECONDARY_NO_DISCARD[] =
307    SHADER_VERSION
308    SHADER_PRAGMAS
309    SHADER_SETUP
310    "\n"
311    "uniform LOWP sampler2D uTexture;\n"
312    "\n"
313    "varying HIGHP vec2 vTexCoord;\n"
314    "varying LOWP vec4 vColor0;\n"
315    "\n"
316    "void main(void)\n"
317    "{\n"
318    "	MEDIUMP vec4 t       = texture2D( uTexture, vTexCoord );\n"
319    "	gl_FragColor = t * vColor0;\n"
320    "}\n"
321    ;
322 
323 static const char AVP_FRAGMENT_SHADER_SOURCE_NO_COLOR_NO_DISCARD[] =
324    SHADER_VERSION
325    SHADER_PRAGMAS
326    SHADER_SETUP
327    "\n"
328    "uniform LOWP sampler2D uTexture;\n"
329    "\n"
330    "varying HIGHP vec2 vTexCoord;\n"
331    "\n"
332    "void main(void)\n"
333    "{\n"
334    "	MEDIUMP vec4 t       = texture2D( uTexture, vTexCoord );\n"
335    "	gl_FragColor = t;\n"
336    "}\n"
337    ;
338 
339 enum AVP_VERTEX_SHADER {
340 	AVP_VERTEX_SHADER_DEFAULT,
341 	AVP_VERTEX_SHADER_NO_TEXTURE,
342 	AVP_VERTEX_SHADER_NO_SECONDARY,
343 	AVP_VERTEX_SHADER_NO_COLOR,
344 	AVP_VERTEX_SHADER_MAX
345 };
346 
347 enum AVP_FRAGMENT_SHADER {
348 	AVP_FRAGMENT_SHADER_DEFAULT,
349 	AVP_FRAGMENT_SHADER_NO_TEXTURE,
350 	AVP_FRAGMENT_SHADER_NO_DISCARD,
351 	AVP_FRAGMENT_SHADER_NO_SECONDARY,
352 	AVP_FRAGMENT_SHADER_NO_SECONDARY_NO_DISCARD,
353 	AVP_FRAGMENT_SHADER_NO_COLOR_NO_DISCARD,
354 	AVP_FRAGMENT_SHADER_MAX
355 };
356 
357 static const char* const AvpVertexShaderSources[AVP_VERTEX_SHADER_MAX] = {
358 	AVP_VERTEX_SHADER_SOURCE,
359 	AVP_VERTEX_SHADER_SOURCE_NO_TEXTURE,
360 	AVP_VERTEX_SHADER_SOURCE_NO_SECONDARY,
361 	AVP_VERTEX_SHADER_SOURCE_NO_COLOR
362 };
363 
364 static const char* AvpFragmentShaderSources[AVP_FRAGMENT_SHADER_MAX] = {
365 	AVP_FRAGMENT_SHADER_SOURCE,
366 	AVP_FRAGMENT_SHADER_SOURCE_NO_TEXTURE,
367 	AVP_FRAGMENT_SHADER_SOURCE_NO_DISCARD,
368 	AVP_FRAGMENT_SHADER_SOURCE_NO_SECONDARY,
369 	AVP_FRAGMENT_SHADER_SOURCE_NO_SECONDARY_NO_DISCARD,
370 	AVP_FRAGMENT_SHADER_SOURCE_NO_COLOR_NO_DISCARD
371 };
372 
373 struct AvpShaderProgramSource {
374 	enum AVP_VERTEX_SHADER VertexShader;
375 	enum AVP_FRAGMENT_SHADER FragmentShader;
376 };
377 
378 struct AvpVertexShader {
379 	int shaderObj;
380 };
381 
382 struct AvpFragmentShader {
383 	int shaderObj;
384 };
385 
386 struct AvpShaderProgram {
387 	int programObj;
388 
389 	int uTexture;
390 };
391 
392 static const struct AvpShaderProgramSource AvpShaderProgramSources[AVP_SHADER_PROGRAM_MAX] = {
393 	// AVP_SHADER_PROGRAM_DEFAULT
394 	{
395 		AVP_VERTEX_SHADER_DEFAULT,
396 		AVP_FRAGMENT_SHADER_DEFAULT
397 	},
398 	// AVP_SHADER_PROGRAM_NO_SECONDARY
399 	{
400 		AVP_VERTEX_SHADER_NO_SECONDARY,
401 		AVP_FRAGMENT_SHADER_NO_SECONDARY
402 	},
403 	// AVP_SHADER_PROGRAM_NO_TEXTURE
404 	{
405 		AVP_VERTEX_SHADER_NO_TEXTURE,
406 		AVP_FRAGMENT_SHADER_NO_TEXTURE
407 	},
408 	// AVP_SHADER_PROGRAM_NO_DISCARD
409 	{
410 		AVP_VERTEX_SHADER_DEFAULT,
411 		AVP_FRAGMENT_SHADER_NO_DISCARD
412 	},
413 	// AVP_SHADER_PROGRAM_NO_SECONDARY_NO_DISCARD
414 	{
415 		AVP_VERTEX_SHADER_NO_SECONDARY,
416 		AVP_FRAGMENT_SHADER_NO_SECONDARY_NO_DISCARD
417 	},
418 	// AVP_SHADER_PROGRAM_NO_COLOR_NO_DISCARD
419 	{
420 		AVP_VERTEX_SHADER_NO_COLOR,
421 		AVP_FRAGMENT_SHADER_NO_COLOR_NO_DISCARD
422 	}
423 };
424 
425 static const unsigned int AvpShaderProgramAttributes[AVP_SHADER_PROGRAM_MAX+1] = {
426 	// AVP_SHADER_PROGRAM_DEFAULT
427 	(1 << OPENGL_VERTEX_ATTRIB_INDEX) | (1 << OPENGL_TEXCOORD_ATTRIB_INDEX) | (1 << OPENGL_COLOR0_ATTRIB_INDEX) | (1 << OPENGL_COLOR1_ATTRIB_INDEX),
428 	// AVP_SHADER_PROGRAM_NO_SECONDARY
429 	(1 << OPENGL_VERTEX_ATTRIB_INDEX) | (1 << OPENGL_TEXCOORD_ATTRIB_INDEX) | (1 << OPENGL_COLOR0_ATTRIB_INDEX) | (0 << OPENGL_COLOR1_ATTRIB_INDEX),
430 	// AVP_SHADER_PROGRAM_NO_TEXTURE
431 	(1 << OPENGL_VERTEX_ATTRIB_INDEX) | (0 << OPENGL_TEXCOORD_ATTRIB_INDEX) | (1 << OPENGL_COLOR0_ATTRIB_INDEX) | (0 << OPENGL_COLOR1_ATTRIB_INDEX),
432 	// AVP_SHADER_PROGRAM_NO_DISCARD
433 	(1 << OPENGL_VERTEX_ATTRIB_INDEX) | (1 << OPENGL_TEXCOORD_ATTRIB_INDEX) | (1 << OPENGL_COLOR0_ATTRIB_INDEX) | (1 << OPENGL_COLOR1_ATTRIB_INDEX),
434 	// AVP_SHADER_PROGRAM_NO_SECONDARY_NO_DISCARD
435 	(1 << OPENGL_VERTEX_ATTRIB_INDEX) | (1 << OPENGL_TEXCOORD_ATTRIB_INDEX) | (1 << OPENGL_COLOR0_ATTRIB_INDEX) | (0 << OPENGL_COLOR1_ATTRIB_INDEX),
436 	// AVP_SHADER_PROGRAM_NO_COLOR_NO_DISCARD
437 	(1 << OPENGL_VERTEX_ATTRIB_INDEX) | (1 << OPENGL_TEXCOORD_ATTRIB_INDEX) | (0 << OPENGL_COLOR0_ATTRIB_INDEX) | (0 << OPENGL_COLOR1_ATTRIB_INDEX),
438 	// AVP_SHADER_PROGRAM_MAX
439 	0
440 };
441 
442 static const char* AvpShaderProgramAttributeNames[4] = {
443 	"aVertex",
444 	"aTexCoord",
445 	"aColor0",
446 	"aColor1"
447 };
448 
449 static struct AvpVertexShader AvpVertexShaders[AVP_FRAGMENT_SHADER_MAX];
450 static struct AvpFragmentShader AvpFragmentShaders[AVP_FRAGMENT_SHADER_MAX];
451 static struct AvpShaderProgram AvpShaderPrograms[AVP_SHADER_PROGRAM_MAX];
452 
CompileShader(GLuint shader,const GLchar * shaderSource)453 static int CompileShader(GLuint shader, const GLchar* shaderSource) {
454 	GLint infoLogLength;
455 	GLchar* infoLog;
456 	GLint compileStatus;
457 
458 	pglShaderSource(shader, 1, &shaderSource, NULL);
459 	pglCompileShader(shader);
460 
461 	pglGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
462 	if (infoLogLength > 1) {
463 		infoLog = (GLchar*) malloc((size_t) infoLogLength * sizeof(GLchar));
464 		if (infoLog == NULL) {
465 			fprintf(stderr, "unable to allocate info log\n");
466 			return GL_FALSE;
467 		}
468 
469 		pglGetShaderInfoLog(shader, infoLogLength, NULL, infoLog);
470 		printf("Shader:\n-------\n%s\n\nCompile Log:\n------------\n%s\n", shaderSource, infoLog);
471 
472 		free(infoLog);
473 	}
474 
475 	pglGetShaderiv(shader, GL_COMPILE_STATUS, &compileStatus);
476 	return compileStatus;
477 }
478 
LinkProgram(GLuint program)479 static int LinkProgram(GLuint program) {
480 	GLint infoLogLength;
481 	GLchar* infoLog;
482 	GLint compileStatus;
483 
484 	pglLinkProgram(program);
485 	pglGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
486 
487 	if (infoLogLength > 1) {
488 		infoLog = (GLchar*) malloc((size_t) infoLogLength * sizeof(GLchar));
489 		if (infoLog == NULL) {
490 			fprintf(stderr, "unable to allocate info log\n");
491 			return GL_FALSE;
492 		}
493 
494 		pglGetProgramInfoLog(program, infoLogLength, NULL, infoLog);
495 		printf("Program Link Log:\n%s\n", infoLog);
496 
497 		free(infoLog);
498 	}
499 
500 	pglGetProgramiv(program, GL_LINK_STATUS, &compileStatus);
501 	return compileStatus;
502 }
503 
ValidateProgram(GLuint program)504 static int ValidateProgram(GLuint program) {
505 	GLint infoLogLength;
506 	GLchar* infoLog;
507 	GLint compileStatus;
508 
509 	pglValidateProgram(program);
510 
511 	pglGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
512 
513 	if (infoLogLength > 1) {
514 		infoLog = (GLchar*) malloc((size_t) infoLogLength * sizeof(GLchar));
515 		if (infoLog == NULL) {
516 			fprintf(stderr, "unable to allocate info log\n");
517 			return GL_FALSE;
518 		}
519 
520 		pglGetProgramInfoLog(program, infoLogLength, NULL, infoLog);
521 		printf("Program Validation Log:\n%s\n", infoLog);
522 
523 		free(infoLog);
524 	}
525 
526 	pglGetProgramiv(program, GL_VALIDATE_STATUS, &compileStatus);
527 	return compileStatus;
528 }
529 
CreateProgram(GLuint * pprogram,const GLchar * vertexShaderSource,const GLchar * fragmentShaderSource)530 static int CreateProgram(GLuint* pprogram, const GLchar* vertexShaderSource, const GLchar* fragmentShaderSource) {
531 	GLuint program;
532 	GLuint vertexShader;
533 	GLuint fragmentShader;
534 
535 	GLint compileStatus;
536 
537 	// create program object
538 	program = pglCreateProgram();
539 
540 	// vertex shader
541 	vertexShader = pglCreateShader(GL_VERTEX_SHADER);
542 
543 	compileStatus = CompileShader(vertexShader, vertexShaderSource);
544 
545 	if (compileStatus == GL_FALSE) {
546 		fprintf(stderr, "vertex shader compilation failed\n");
547 
548 		pglDeleteProgram(program);
549 		return GL_FALSE;
550 	}
551 
552 	pglAttachShader(program, vertexShader);
553 	pglDeleteShader(vertexShader);
554 
555 	// fragment shader
556 	fragmentShader = pglCreateShader(GL_FRAGMENT_SHADER);
557 
558 	compileStatus = CompileShader(fragmentShader, fragmentShaderSource);
559 
560 	if (compileStatus == GL_FALSE) {
561 		fprintf(stderr, "fragment shader compilation failed\n");
562 
563 		pglDeleteProgram(program);
564 		return GL_FALSE;
565 	}
566 
567 	pglAttachShader(program, fragmentShader);
568 	pglDeleteShader(fragmentShader);
569 
570 	// link the program
571 	compileStatus = LinkProgram(program);
572 
573 	if (compileStatus == GL_FALSE) {
574 		fprintf(stderr, "program failed to link\n");
575 
576 		pglDeleteProgram(program);
577 		return GL_FALSE;
578 	}
579 
580 	// validate the program for good measure
581 	compileStatus = ValidateProgram(program);
582 
583 	if (compileStatus == GL_FALSE) {
584 		fprintf(stderr, "program failed to validate\n");
585 
586 		pglDeleteProgram(program);
587 		return GL_FALSE;
588 	}
589 
590 	*pprogram = program;
591 	return GL_TRUE;
592 }
593 
CreateProgram2(GLuint * pprogram,GLuint vertexShader,GLuint fragmentShader)594 static int CreateProgram2(GLuint* pprogram, GLuint vertexShader, GLuint fragmentShader) {
595 	GLuint program;
596 	GLint compileStatus;
597 	int i;
598 
599 	// create program object
600 	program = pglCreateProgram();
601 
602 	// vertex shader
603 	pglAttachShader(program, vertexShader);
604 
605 	// fragment shader
606 	pglAttachShader(program, fragmentShader);
607 
608 	// need to bind locations before linking
609 	pglBindAttribLocation(program, OPENGL_VERTEX_ATTRIB_INDEX, "aVertex");
610 	pglBindAttribLocation(program, OPENGL_TEXCOORD_ATTRIB_INDEX, "aTexCoord");
611 	pglBindAttribLocation(program, OPENGL_COLOR0_ATTRIB_INDEX, "aColor0");
612 	pglBindAttribLocation(program, OPENGL_COLOR1_ATTRIB_INDEX, "aColor1");
613 
614 	// link the program
615 	compileStatus = LinkProgram(program);
616 
617 	if (compileStatus == GL_FALSE) {
618 		fprintf(stderr, "program failed to link\n");
619 
620 		pglDeleteProgram(program);
621 		return GL_FALSE;
622 	}
623 
624 	// validate the program for good measure
625 	compileStatus = ValidateProgram(program);
626 
627 	if (compileStatus == GL_FALSE) {
628 		fprintf(stderr, "program failed to validate\n");
629 
630 		pglDeleteProgram(program);
631 		return GL_FALSE;
632 	}
633 
634 	*pprogram = program;
635 	return GL_TRUE;
636 }
637 
InitOpenGLPrograms(void)638 static int InitOpenGLPrograms(void) {
639 	GLenum status;
640 	int i;
641 
642 	for (i = 0; i < AVP_VERTEX_SHADER_MAX; i++) {
643 		GLuint vertexShader;
644 
645 		vertexShader = pglCreateShader(GL_VERTEX_SHADER);
646 
647 		status = CompileShader(vertexShader, AvpVertexShaderSources[i]);
648 
649 		if (status == GL_FALSE) {
650 			fprintf(stderr, "vertex shader compilation failed\n");
651 			return GL_FALSE;
652 		}
653 
654 		AvpVertexShaders[i].shaderObj = vertexShader;
655 	}
656 
657 	for (i = 0; i < AVP_FRAGMENT_SHADER_MAX; i++) {
658 		GLuint fragmentShader;
659 
660 		fragmentShader = pglCreateShader(GL_FRAGMENT_SHADER);
661 
662 		status = CompileShader(fragmentShader, AvpFragmentShaderSources[i]);
663 
664 		if (status == GL_FALSE) {
665 			fprintf(stderr, "fragment shader compilation failed\n");
666 			return GL_FALSE;
667 		}
668 
669 		AvpFragmentShaders[i].shaderObj = fragmentShader;
670 	}
671 
672 	for (i = 0; i < AVP_SHADER_PROGRAM_MAX; i++) {
673 		GLuint program;
674 		GLuint vertexShader;
675 		GLuint fragmentShader;
676 
677 		vertexShader = AvpVertexShaders[AvpShaderProgramSources[i].VertexShader].shaderObj;
678 		fragmentShader = AvpFragmentShaders[AvpShaderProgramSources[i].FragmentShader].shaderObj;
679 
680 		status = CreateProgram2(&program, vertexShader, fragmentShader);
681 		if (status == GL_FALSE) {
682 			fprintf(stderr, "program compilation failed\n");
683 			return GL_FALSE;
684 		}
685 
686 		AvpShaderPrograms[i].programObj = program;
687 		AvpShaderPrograms[i].uTexture = pglGetUniformLocation(program, "uTexture");
688 	}
689 
690 	return GL_TRUE;
691 }
692 
SelectProgram(enum AVP_SHADER_PROGRAM program)693 void SelectProgram(enum AVP_SHADER_PROGRAM program) {
694 
695 	if (CurrShaderProgram != program) {
696 		// supposed to flush here
697 
698 		unsigned int PrevAttribs = AvpShaderProgramAttributes[CurrShaderProgram];
699 		unsigned int NextAttribs = AvpShaderProgramAttributes[program];
700 		unsigned int DiffAttribs = PrevAttribs ^ NextAttribs;
701 		int ShaderProgram = AvpShaderPrograms[program].programObj;
702 		int TextureUniformIndex = AvpShaderPrograms[program].uTexture;
703 
704 		CurrShaderProgram = program;
705 		pglUseProgram(ShaderProgram);
706 
707 		if ((DiffAttribs & OPENGL_VERTEX_ATTRIB_BITINDEX) != 0) {
708 			if ((NextAttribs & OPENGL_VERTEX_ATTRIB_BITINDEX) != 0) {
709 				pglEnableVertexAttribArray(OPENGL_VERTEX_ATTRIB_INDEX);
710 			} else {
711 				pglDisableVertexAttribArray(OPENGL_VERTEX_ATTRIB_INDEX);
712 			}
713 		}
714 
715 		if ((DiffAttribs & OPENGL_TEXCOORD_ATTRIB_BITINDEX) != 0) {
716 			if ((NextAttribs & OPENGL_TEXCOORD_ATTRIB_BITINDEX) != 0) {
717 				pglEnableVertexAttribArray(OPENGL_TEXCOORD_ATTRIB_INDEX);
718 			} else {
719 				pglDisableVertexAttribArray(OPENGL_TEXCOORD_ATTRIB_INDEX);
720 			}
721 		}
722 
723 		if ((DiffAttribs & OPENGL_COLOR0_ATTRIB_BITINDEX) != 0) {
724 			if ((NextAttribs & OPENGL_COLOR0_ATTRIB_BITINDEX) != 0) {
725 				pglEnableVertexAttribArray(OPENGL_COLOR0_ATTRIB_INDEX);
726 			} else {
727 				pglDisableVertexAttribArray(OPENGL_COLOR0_ATTRIB_INDEX);
728 			}
729 		}
730 
731 		if ((DiffAttribs & OPENGL_COLOR1_ATTRIB_BITINDEX) != 0) {
732 			if ((NextAttribs & OPENGL_COLOR1_ATTRIB_BITINDEX) != 0) {
733 				pglEnableVertexAttribArray(OPENGL_COLOR1_ATTRIB_INDEX);
734 			} else {
735 				pglDisableVertexAttribArray(OPENGL_COLOR1_ATTRIB_INDEX);
736 			}
737 		}
738 
739 		if (TextureUniformIndex >= 0) {
740 			pglUniform1i(TextureUniformIndex, 0);
741 		}
742 	}
743 }
744 
InitOpenGLDefaultTexture(void)745 static void InitOpenGLDefaultTexture(void) {
746 	pglGenTextures(1, &DefaultTexture);
747 
748 	pglBindTexture(GL_TEXTURE_2D, DefaultTexture);
749 
750 	pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
751 
752 	pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
753 	pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
754 	pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
755 
756 	GLubyte defaultTexData[4] = { 255, 255, 255, 255 };
757 	pglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, defaultTexData);
758 }
759 
InitOpenGL(int firsttime)760 void InitOpenGL(int firsttime)
761 {
762 	if (firsttime) {
763 		InitOpenGLPrograms();
764 		check_for_errors();
765 		InitOpenGLDefaultTexture();
766 		check_for_errors();
767 	}
768 
769 	pglHint( GL_GENERATE_MIPMAP_HINT, GL_NICEST );
770 
771 #if GL_NV_multisample_filter_hint
772 	if ( ogl_use_multisample_filter_hint )
773 	{
774 		pglHint( GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST );
775 	}
776 #endif
777 
778 	CurrentTranslucencyMode = TRANSLUCENCY_OFF;
779 	pglBlendFunc(GL_ONE, GL_ZERO);
780 
781 	CurrentFilteringMode = FILTERING_BILINEAR_OFF;
782 	CurrentlyBoundTexture = NULL;
783 	pglBindTexture(GL_TEXTURE_2D, 0);
784 
785 	// create array and element array buffers, as required by WebGL
786 	pglGenBuffers(1, &ArrayBuffer);
787 	pglGenBuffers(1, &ElementArrayBuffer);
788 
789 	pglBindBuffer(GL_ARRAY_BUFFER, ArrayBuffer);
790 	pglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ElementArrayBuffer);
791 
792 	pglVertexAttribPointer(OPENGL_VERTEX_ATTRIB_INDEX, 4, GL_FLOAT, GL_FALSE, sizeof(varr[0]), (const GLvoid*) 0);
793 	pglVertexAttribPointer(OPENGL_TEXCOORD_ATTRIB_INDEX, 2, GL_FLOAT, GL_FALSE, sizeof(varr[0]), (const GLvoid*) 16);
794 	pglVertexAttribPointer(OPENGL_COLOR0_ATTRIB_INDEX, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(varr[0]), (const GLvoid*) 24);
795 	pglVertexAttribPointer(OPENGL_COLOR1_ATTRIB_INDEX, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(varr[0]), (const GLvoid*) 28);
796 
797 	CurrShaderProgram = AVP_SHADER_PROGRAM_MAX;
798 	SelectProgram(AVP_SHADER_PROGRAM_DEFAULT);
799 
800 	tarrc = 0;
801 	tarrp = tarr;
802 
803 	varrc = 0;
804 	varrp = varr;
805 
806 	check_for_errors();
807 }
808 
FlushTriangleBuffers(int backup)809 static void FlushTriangleBuffers(int backup)
810 {
811 	if (tarrc) {
812 		// not optimal but required by WebGL
813 		pglBufferData(GL_ARRAY_BUFFER, varrc * sizeof(varr[0]), varr, GL_STREAM_DRAW);
814 		pglBufferData(GL_ELEMENT_ARRAY_BUFFER, tarrc * sizeof(tarr[0]), tarr, GL_STREAM_DRAW);
815 
816 		pglDrawElements(GL_TRIANGLES, tarrc*3, GL_UNSIGNED_SHORT, (const GLvoid*) 0);
817 
818 		tarrc = 0;
819 		tarrp = tarr;
820 
821 		varrc = 0;
822 		varrp = varr;
823 	}
824 }
825 
CheckBoundTextureIsCorrect(D3DTexture * tex)826 static void CheckBoundTextureIsCorrect(D3DTexture *tex)
827 {
828 	if (tex == CurrentlyBoundTexture)
829 		return;
830 
831 	FlushTriangleBuffers(1);
832 
833 	if (tex == NULL) {
834 		pglBindTexture(GL_TEXTURE_2D, DefaultTexture);
835 
836 		CurrentlyBoundTexture = NULL;
837 
838 		return;
839 	}
840 
841 	pglBindTexture(GL_TEXTURE_2D, tex->id);
842 
843 	/*if (tex->hasAlpha != 0 || tex->hasChroma != 0) {
844 		// modulate emulation?
845 	}*/
846 
847 	if (tex->filter != CurrentFilteringMode) {
848 		switch(CurrentFilteringMode) {
849 			case FILTERING_BILINEAR_OFF:
850 				pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
851 				pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
852 				break;
853 			case FILTERING_BILINEAR_ON:
854 				pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
855 				pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, tex->IsNpot ? GL_LINEAR : TextureMinFilter);
856 				break;
857 			default:
858 				break;
859 		}
860 
861 		tex->filter = CurrentFilteringMode;
862 	}
863 
864 	CurrentlyBoundTexture = tex;
865 }
866 
CheckFilteringModeIsCorrect(enum FILTERING_MODE_ID filter)867 static void CheckFilteringModeIsCorrect(enum FILTERING_MODE_ID filter)
868 {
869 	CurrentFilteringMode = filter;
870 
871 	if (CurrentlyBoundTexture && CurrentlyBoundTexture->filter != CurrentFilteringMode) {
872 		FlushTriangleBuffers(1);
873 
874 		switch(CurrentFilteringMode) {
875 			case FILTERING_BILINEAR_OFF:
876 				pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
877 				pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
878 				break;
879 			case FILTERING_BILINEAR_ON:
880 				pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
881 				pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, CurrentlyBoundTexture->IsNpot ? GL_LINEAR : TextureMinFilter);
882 				break;
883 			default:
884 				break;
885 		}
886 
887 		CurrentlyBoundTexture->filter = CurrentFilteringMode;
888 	}
889 }
890 
CheckTranslucencyModeIsCorrect(enum TRANSLUCENCY_TYPE mode)891 static void CheckTranslucencyModeIsCorrect(enum TRANSLUCENCY_TYPE mode)
892 {
893 	if (CurrentTranslucencyMode == mode)
894 		return;
895 
896 	FlushTriangleBuffers(1);
897 
898 	SetTranslucencyMode(mode);
899 
900 	CurrentTranslucencyMode = mode;
901 }
902 
CheckTriangleBuffer(int rver,int rtri,D3DTexture * tex,enum TRANSLUCENCY_TYPE mode,enum FILTERING_MODE_ID filter)903 static void CheckTriangleBuffer(int rver, int rtri, D3DTexture *tex, enum TRANSLUCENCY_TYPE mode, enum FILTERING_MODE_ID filter)
904 {
905 	if ((rver+varrc) >= TA_MAXVERTICES) {
906 		FlushTriangleBuffers(0);
907 	} else if (rtri == 0 && ((rver-2+tarrc) >= TA_MAXTRIANGLES)) {
908 		FlushTriangleBuffers(0);
909 	} else if (rtri && ((rtri+tarrc) >= TA_MAXTRIANGLES)) {
910 		FlushTriangleBuffers(0);
911 	}
912 
913 	if ((intptr_t)tex != -1)
914 		CheckBoundTextureIsCorrect(tex);
915 	if (mode != -1)
916 		CheckTranslucencyModeIsCorrect(mode);
917 	if (filter != -1)
918 		CheckFilteringModeIsCorrect(filter);
919 
920 #define OUTPUT_TRIANGLE(x, y, z) \
921 { \
922 	tarrp->a = varrc+(x);	\
923 	tarrp->b = varrc+(y);	\
924 	tarrp->c = varrc+(z);	\
925 				\
926 	tarrp++;		\
927 	tarrc++; 		\
928 }
929 
930 	if (rtri == 0) {
931 		switch(rver) {
932 			case 0:
933 				break;
934 			case 3:
935 				OUTPUT_TRIANGLE(0, 2, 1);
936 				break;
937 			case 5:
938 				OUTPUT_TRIANGLE(0, 1, 4);
939 				OUTPUT_TRIANGLE(1, 3, 4);
940 				OUTPUT_TRIANGLE(1, 2, 3);
941 				break;
942 			case 8:
943 				OUTPUT_TRIANGLE(0, 6, 7);
944 			case 7:
945 				OUTPUT_TRIANGLE(0, 5, 6);
946 			case 6:
947 				OUTPUT_TRIANGLE(0, 4, 5);
948 				OUTPUT_TRIANGLE(0, 3, 4);
949 			case 4:
950 				OUTPUT_TRIANGLE(0, 2, 3);
951 				OUTPUT_TRIANGLE(0, 1, 2);
952 				break;
953 			default:
954 				fprintf(stderr, "DrawTriangles_T2F_C4UB_V4F: vertices = %d\n", rver);
955 		}
956 	}
957 #undef OUTPUT_TRIANGLE
958 }
959 
PowerOfTwo(unsigned int v)960 static unsigned int PowerOfTwo(unsigned int v) {
961     v--;
962     v |= v >> 1;
963     v |= v >> 2;
964     v |= v >> 4;
965     v |= v >> 8;
966     v |= v >> 16;
967     return v + 1;
968 }
969 
CreateOGLTexture(D3DTexture * tex,unsigned char * buf)970 GLuint CreateOGLTexture(D3DTexture *tex, unsigned char *buf)
971 {
972 	if (buf == NULL) {
973 	    // converting DDSurface to D3DTexture
974 	    buf = tex->buf;
975 	}
976 	if (buf == NULL) {
977 	    fprintf(stderr, "CreateOGLTexture - null buffer\n");
978 	    return 0;
979 	}
980 
981 	int i;
982 	int l = tex->w * tex->h;
983 	for (i = 0; i < l; i++) {
984 		int o = i*4;
985 		int r = buf[o+0];
986 		int g = buf[o+1];
987 		int b = buf[o+2];
988 		int a = buf[o+3];
989 
990 		// kinda pre-multiplied alpha;
991 		// texels with zero alpha shouldn't
992 		// be visible.
993 		if (a == 0) {
994 			r = 0;
995 			g = 0;
996 			b = 0;
997 		}
998 
999 		buf[o+0] = r;
1000 		buf[o+1] = g;
1001 		buf[o+2] = b;
1002 		buf[o+3] = a;
1003 	}
1004 
1005 	tex->TexWidth = tex->w;
1006 	tex->TexHeight = tex->h;
1007 
1008 	int PotWidth = PowerOfTwo(tex->TexWidth);
1009 	int PotHeight = PowerOfTwo(tex->TexHeight);
1010 	tex->IsNpot = (PotWidth != tex->TexWidth) || (PotHeight != tex->TexHeight);
1011 
1012 	GLuint h;
1013 	GLfloat max_anisotropy;
1014 
1015 	FlushTriangleBuffers(1);
1016 
1017 	pglGenTextures(1, &h);
1018 
1019 	pglBindTexture(GL_TEXTURE_2D, h);
1020 
1021 	pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1022 
1023 	if (tex->IsNpot) {
1024 		pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1025 		pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1026 		pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1027 	} else {
1028 		pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TextureMinFilter);
1029 		pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1030 		pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1031 	}
1032 
1033 	pglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex->w, tex->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, buf);
1034 
1035 	if (!tex->IsNpot && TextureMinFilter != GL_LINEAR) {
1036 		// generate mipmaps if needed
1037 		// OpenGL 3.0 / ES 2 feature -- need fbo extension support
1038 		//pglGenerateMipmap(GL_TEXTURE_2D);
1039 	}
1040 
1041     tex->buf = NULL;
1042 	tex->id = h;
1043 	tex->filter = FILTERING_BILINEAR_ON;
1044 	tex->RecipW = 1.0f / (float) tex->TexWidth;
1045 	tex->RecipH = 1.0f / (float) tex->TexHeight;
1046 
1047 	if ( ogl_use_texture_filter_anisotropic )
1048 	{
1049 		pglGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropy);
1050 		pglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, max_anisotropy);
1051 	}
1052 
1053 	if ( CurrentlyBoundTexture != NULL )
1054 	{
1055 		/* restore the previously-bound texture */
1056 		pglBindTexture(GL_TEXTURE_2D, CurrentlyBoundTexture->id);
1057 	}
1058 
1059 	free(buf);
1060 
1061 	return h;
1062 }
1063 
ReleaseD3DTexture(void * tex)1064 void ReleaseD3DTexture(void *tex)
1065 {
1066 	D3DTexture *TextureHandle = (D3DTexture *)tex;
1067 
1068 	if (TextureHandle == NULL) {
1069 		return;
1070 	}
1071 
1072 	if (TextureHandle->id != 0) {
1073 		pglDeleteTextures(1, (GLuint*) &(TextureHandle->id));
1074 		TextureHandle->id = 0;
1075 	}
1076 
1077 	if (TextureHandle->buf != NULL) {
1078 		free(TextureHandle->buf);
1079 		TextureHandle->buf = NULL;
1080 	}
1081 
1082 	free(TextureHandle);
1083 }
1084 
CreateIMGSurface(D3DTexture * tex,unsigned char * buf)1085 int CreateIMGSurface(D3DTexture *tex, unsigned char *buf)
1086 {
1087 	tex->buf = buf;
1088 	tex->id = 0;
1089 
1090 	return 0;
1091 }
1092 
ReleaseDDSurface(void * DDSurface)1093 void ReleaseDDSurface(void* DDSurface)
1094 {
1095 	ReleaseD3DTexture(DDSurface);
1096 }
1097 
1098 /* ** */
1099 
ThisFramesRenderingHasBegun()1100 void ThisFramesRenderingHasBegun()
1101 {
1102 	CheckFilteringModeIsCorrect(FILTERING_BILINEAR_ON);
1103 }
1104 
ThisFramesRenderingHasFinished()1105 void ThisFramesRenderingHasFinished()
1106 {
1107 	LightBlockDeallocation();
1108 
1109 	FlushTriangleBuffers(0);
1110 }
1111 
1112 /* ** */
1113 
FlushD3DZBuffer()1114 void FlushD3DZBuffer()
1115 {
1116 	pglClear(GL_DEPTH_BUFFER_BIT);
1117 }
1118 
SecondFlushD3DZBuffer()1119 void SecondFlushD3DZBuffer()
1120 {
1121 	FlushTriangleBuffers(0);
1122 
1123 	pglClear(GL_DEPTH_BUFFER_BIT);
1124 }
1125 
D3D_DecalSystem_Setup()1126 void D3D_DecalSystem_Setup()
1127 {
1128 	FlushTriangleBuffers(0);
1129 
1130 	pglDepthMask(GL_FALSE);
1131 
1132 	/* enable polygon offset to help lessen decal z-fighting... */
1133 	pglEnable(GL_POLYGON_OFFSET_FILL);
1134 
1135 	static GLfloat factor = 0.0f;
1136 	static GLfloat units = -0.09375f;
1137 	pglPolygonOffset(factor, units);
1138 }
1139 
D3D_DecalSystem_End()1140 void D3D_DecalSystem_End()
1141 {
1142 	FlushTriangleBuffers(0);
1143 
1144 	pglDepthMask(GL_TRUE);
1145 
1146 	pglDisable(GL_POLYGON_OFFSET_FILL);
1147 }
1148 
1149 /* ** */
1150 
D3D_Rectangle(int x0,int y0,int x1,int y1,int r,int g,int b,int a)1151 void D3D_Rectangle(int x0, int y0, int x1, int y1, int r, int g, int b, int a)
1152 {
1153 	GLfloat x[4], y[4];
1154 	int i;
1155 
1156 	if (y1 <= y0)
1157 		return;
1158 
1159 	CheckTriangleBuffer(4, 0, NULL, TRANSLUCENCY_GLOWING, -1);
1160 	SelectProgram(AVP_SHADER_PROGRAM_NO_TEXTURE);
1161 
1162 	x[0] = x0;
1163 	x[0] =  (x[0] - ScreenDescriptorBlock.SDB_CentreX)/ScreenDescriptorBlock.SDB_CentreX;
1164 	y[0] = y0;
1165 	y[0] = -(y[0] - ScreenDescriptorBlock.SDB_CentreY)/ScreenDescriptorBlock.SDB_CentreY;
1166 
1167 	x[1] = x1 - 1;
1168 	x[1] =  (x[1] - ScreenDescriptorBlock.SDB_CentreX)/ScreenDescriptorBlock.SDB_CentreX;
1169 	y[1] = y0;
1170 	y[1] = -(y[1] - ScreenDescriptorBlock.SDB_CentreY)/ScreenDescriptorBlock.SDB_CentreY;
1171 
1172 	x[2] = x1 - 1;
1173 	x[2] =  (x[2] - ScreenDescriptorBlock.SDB_CentreX)/ScreenDescriptorBlock.SDB_CentreX;
1174 	y[2] = y1 - 1;
1175 	y[2] = -(y[2] - ScreenDescriptorBlock.SDB_CentreY)/ScreenDescriptorBlock.SDB_CentreY;
1176 
1177 	x[3] = x0;
1178 	x[3] =  (x[3] - ScreenDescriptorBlock.SDB_CentreX)/ScreenDescriptorBlock.SDB_CentreX;
1179 	y[3] = y1 - 1;
1180 	y[3] = -(y[3] - ScreenDescriptorBlock.SDB_CentreY)/ScreenDescriptorBlock.SDB_CentreY;
1181 
1182 	for (i = 0; i < 4; i++) {
1183 		varrp->v[0] = x[i];
1184 		varrp->v[1] = y[i];
1185 		varrp->v[2] = -1.0f;
1186 		varrp->v[3] = 1.0f;
1187 
1188 		varrp->t[0] = 0.0f;
1189 		varrp->t[1] = 0.0f;
1190 
1191 		varrp->c[0] = r;
1192 		varrp->c[1] = g;
1193 		varrp->c[2] = b;
1194 		varrp->c[3] = a;
1195 
1196 		varrp->s[0] = 0;
1197 		varrp->s[1] = 0;
1198 		varrp->s[2] = 0;
1199 		varrp->s[3] = 0;
1200 
1201 		varrp++;
1202 		varrc++;
1203 	}
1204 }
1205 
1206 /* ** */
1207 
D3D_ZBufferedGouraudTexturedPolygon_Output(POLYHEADER * inputPolyPtr,RENDERVERTEX * renderVerticesPtr)1208 void D3D_ZBufferedGouraudTexturedPolygon_Output(POLYHEADER *inputPolyPtr, RENDERVERTEX *renderVerticesPtr)
1209 {
1210 	int texoffset;
1211 	D3DTexture *TextureHandle;
1212 	int i;
1213 	GLfloat ZNear;
1214 	float RecipW, RecipH;
1215 
1216 	ZNear = (GLfloat) (Global_VDB_Ptr->VDB_ClipZ * GlobalScale);
1217 
1218 	texoffset = inputPolyPtr->PolyColour & ClrTxDefn;
1219 	if (texoffset) {
1220 		TextureHandle = (void *)ImageHeaderArray[texoffset].D3DTexture;
1221 
1222 		CurrTextureHandle = TextureHandle;
1223 	} else {
1224 		TextureHandle = CurrTextureHandle;
1225 	}
1226 
1227 	RecipW = TextureHandle->RecipW / 65536.0f;
1228 	RecipH = TextureHandle->RecipH / 65536.0f;
1229 
1230 	CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, TextureHandle, RenderPolygon.TranslucencyMode, -1);
1231 	SelectProgram(AVP_SHADER_PROGRAM_DEFAULT);
1232 
1233 	for (i = 0; i < RenderPolygon.NumberOfVertices; i++) {
1234 		RENDERVERTEX *vertices = &renderVerticesPtr[i];
1235 		GLfloat x, y, z;
1236 		GLfloat s, t;
1237 		GLfloat w = (float)vertices->Z;
1238 		GLfloat zvalue;
1239 
1240 		s = TEXCOORD_FIXED(vertices->U, RecipW);
1241 		t = TEXCOORD_FIXED(vertices->V, RecipH);
1242 
1243 		x =  ((float)vertices->X*((float)Global_VDB_Ptr->VDB_ProjX+1.0f))/((float)vertices->Z*(float)ScreenDescriptorBlock.SDB_CentreX);
1244 		y = -((float)vertices->Y*((float)Global_VDB_Ptr->VDB_ProjY+1.0f))/((float)vertices->Z*(float)ScreenDescriptorBlock.SDB_CentreY);
1245 
1246 		zvalue = vertices->Z+HeadUpDisplayZOffset;
1247 		z = 1.0f - 2.0f*ZNear/zvalue;
1248 
1249 		varrp->v[0] = x*w;
1250 		varrp->v[1] = y*w;
1251 		varrp->v[2] = z*w;
1252 		varrp->v[3] = w;
1253 
1254 		varrp->t[0] = s;
1255 		varrp->t[1] = t;
1256 
1257 		varrp->c[0] = GammaValues[vertices->R];
1258 		varrp->c[1] = GammaValues[vertices->G];
1259 		varrp->c[2] = GammaValues[vertices->B];
1260 		varrp->c[3] = vertices->A;
1261 
1262 		varrp->s[0] = GammaValues[vertices->SpecularR];
1263 		varrp->s[1] = GammaValues[vertices->SpecularG];
1264 		varrp->s[2] = GammaValues[vertices->SpecularB];
1265 		varrp->s[3] = 0;
1266 
1267 		varrp++;
1268 		varrc++;
1269 	}
1270 }
1271 
D3D_SkyPolygon_Output(POLYHEADER * inputPolyPtr,RENDERVERTEX * renderVerticesPtr)1272 void D3D_SkyPolygon_Output(POLYHEADER *inputPolyPtr, RENDERVERTEX *renderVerticesPtr)
1273 {
1274 	int texoffset;
1275 	D3DTexture *TextureHandle;
1276 	int i;
1277 	float RecipW, RecipH;
1278 
1279 	texoffset = inputPolyPtr->PolyColour & ClrTxDefn;
1280 	TextureHandle = (void *)ImageHeaderArray[texoffset].D3DTexture;
1281 	CurrTextureHandle = TextureHandle;
1282 
1283 	RecipW = TextureHandle->RecipW / 65536.0f;
1284 	RecipH = TextureHandle->RecipH / 65536.0f;
1285 
1286 	CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, TextureHandle, RenderPolygon.TranslucencyMode, -1);
1287 	SelectProgram(AVP_SHADER_PROGRAM_NO_SECONDARY);
1288 
1289 	for (i = 0; i < RenderPolygon.NumberOfVertices; i++) {
1290 		RENDERVERTEX *vertices = &renderVerticesPtr[i];
1291 		GLfloat x, y, z;
1292 		GLfloat s, t;
1293 		GLfloat w;
1294 
1295 		w = (float)vertices->Z;
1296 
1297 		s = TEXCOORD_FIXED(vertices->U, RecipW);
1298 		t = TEXCOORD_FIXED(vertices->V, RecipH);
1299 
1300 		x =  ((float)vertices->X*((float)Global_VDB_Ptr->VDB_ProjX+1.0f))/((float)vertices->Z*(float)ScreenDescriptorBlock.SDB_CentreX);
1301 		y = -((float)vertices->Y*((float)Global_VDB_Ptr->VDB_ProjY+1.0f))/((float)vertices->Z*(float)ScreenDescriptorBlock.SDB_CentreY);
1302 
1303 		z = 1.0f;
1304 
1305 		varrp->v[0] = x*w;
1306 		varrp->v[1] = y*w;
1307 		varrp->v[2] = z*w;
1308 		varrp->v[3] = w;
1309 
1310 		varrp->t[0] = s;
1311 		varrp->t[1] = t;
1312 
1313 		varrp->c[0] = vertices->R;
1314 		varrp->c[1] = vertices->G;
1315 		varrp->c[2] = vertices->B;
1316 		varrp->c[3] = vertices->A;
1317 
1318 		varrp->s[0] = 0;
1319 		varrp->s[1] = 0;
1320 		varrp->s[2] = 0;
1321 		varrp->s[3] = 0;
1322 
1323 		varrp++;
1324 		varrc++;
1325 	}
1326 }
1327 
D3D_ZBufferedCloakedPolygon_Output(POLYHEADER * inputPolyPtr,RENDERVERTEX * renderVerticesPtr)1328 void D3D_ZBufferedCloakedPolygon_Output(POLYHEADER *inputPolyPtr, RENDERVERTEX *renderVerticesPtr)
1329 {
1330 	int flags;
1331 	int texoffset;
1332 	int i;
1333 	D3DTexture *TextureHandle;
1334 
1335 	float ZNear;
1336 	float RecipW, RecipH;
1337 
1338 	ZNear = (float) (Global_VDB_Ptr->VDB_ClipZ * GlobalScale);
1339 
1340 	flags = inputPolyPtr->PolyFlags;
1341 	texoffset = (inputPolyPtr->PolyColour & ClrTxDefn);
1342 
1343 	TextureHandle = ImageHeaderArray[texoffset].D3DTexture;
1344 	CurrTextureHandle = TextureHandle;
1345 
1346 	RecipW = TextureHandle->RecipW / 65536.0f;
1347 	RecipH = TextureHandle->RecipH / 65536.0f;
1348 
1349 	CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, TextureHandle, TRANSLUCENCY_NORMAL, -1);
1350 	SelectProgram(AVP_SHADER_PROGRAM_NO_SECONDARY);
1351 
1352 	for (i = 0; i < RenderPolygon.NumberOfVertices; i++) {
1353 		RENDERVERTEX *vertices = &renderVerticesPtr[i];
1354 
1355 		GLfloat x, y, z;
1356 		GLfloat s, t;
1357 		GLfloat w;
1358 		GLfloat zvalue;
1359 
1360 		w = (float)vertices->Z;
1361 
1362 		s = TEXCOORD_FIXED(vertices->U, RecipW);
1363 		t = TEXCOORD_FIXED(vertices->V, RecipH);
1364 
1365 		x =  ((float)vertices->X*((float)Global_VDB_Ptr->VDB_ProjX+1.0f))/((float)vertices->Z*(float)ScreenDescriptorBlock.SDB_CentreX);
1366 		y = -((float)vertices->Y*((float)Global_VDB_Ptr->VDB_ProjY+1.0f))/((float)vertices->Z*(float)ScreenDescriptorBlock.SDB_CentreY);
1367 
1368 		zvalue = vertices->Z+HeadUpDisplayZOffset;
1369 		z = 1.0 - 2*ZNear/zvalue;
1370 
1371 		varrp->v[0] = x*w;
1372 		varrp->v[1] = y*w;
1373 		varrp->v[2] = z*w;
1374 		varrp->v[3] = w;
1375 
1376 		varrp->t[0] = s;
1377 		varrp->t[1] = t;
1378 
1379 		varrp->c[0] = vertices->R;
1380 		varrp->c[1] = vertices->G;
1381 		varrp->c[2] = vertices->B;
1382 		varrp->c[3] = vertices->A;
1383 
1384 		varrp->s[0] = 0;
1385 		varrp->s[1] = 0;
1386 		varrp->s[2] = 0;
1387 		varrp->s[3] = 0;
1388 
1389 		varrp++;
1390 		varrc++;
1391 	}
1392 }
1393 
D3D_Decal_Output(DECAL * decalPtr,RENDERVERTEX * renderVerticesPtr)1394 void D3D_Decal_Output(DECAL *decalPtr, RENDERVERTEX *renderVerticesPtr)
1395 {
1396 	DECAL_DESC *decalDescPtr = &DecalDescription[decalPtr->DecalID];
1397 	int texoffset;
1398 	D3DTexture *TextureHandle;
1399 	int i;
1400 
1401 	float ZNear;
1402 	float RecipW, RecipH;
1403 	int r, g, b, a;
1404 
1405 	ZNear = (float) (Global_VDB_Ptr->VDB_ClipZ * GlobalScale);
1406 
1407 
1408 	if (decalPtr->DecalID == DECAL_FMV) {
1409 		/* not (yet) implemented */
1410 		return;
1411 	} else if (decalPtr->DecalID == DECAL_SHAFTOFLIGHT||decalPtr->DecalID == DECAL_SHAFTOFLIGHT_OUTER) {
1412 		TextureHandle = NULL;
1413 
1414 		RecipW = 1.0 / 256.0; /* ignored */
1415 		RecipH = 1.0 / 256.0;
1416 	} else {
1417 		texoffset = SpecialFXImageNumber;
1418 
1419 		TextureHandle = ImageHeaderArray[texoffset].D3DTexture;
1420 
1421 		RecipW = TextureHandle->RecipW / 65536.0f;
1422 		RecipH = TextureHandle->RecipH / 65536.0f;
1423 	}
1424 
1425 	if (decalDescPtr->IsLit) {
1426 		int intensity = LightIntensityAtPoint(decalPtr->Vertices);
1427 
1428 		r = MUL_FIXED(intensity,decalDescPtr->RedScale[CurrentVisionMode]);
1429 		g = MUL_FIXED(intensity,decalDescPtr->GreenScale[CurrentVisionMode]);
1430 		b = MUL_FIXED(intensity,decalDescPtr->BlueScale[CurrentVisionMode]);
1431 		a = decalDescPtr->Alpha;
1432 	} else {
1433 		r = decalDescPtr->RedScale[CurrentVisionMode];
1434 		g = decalDescPtr->GreenScale[CurrentVisionMode];
1435 		b = decalDescPtr->BlueScale[CurrentVisionMode];
1436 		a = decalDescPtr->Alpha;
1437 	}
1438 
1439 	if (RAINBOWBLOOD_CHEATMODE) {
1440 		r = FastRandom()&255;
1441 		g = FastRandom()&255;
1442 		b = FastRandom()&255;
1443 		a = decalDescPtr->Alpha;
1444 	}
1445 
1446 	CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, TextureHandle, decalDescPtr->TranslucencyType, -1);
1447 	SelectProgram(AVP_SHADER_PROGRAM_NO_SECONDARY);
1448 
1449 	for (i = 0; i < RenderPolygon.NumberOfVertices; i++) {
1450 		RENDERVERTEX *vertices = &renderVerticesPtr[i];
1451 
1452 		GLfloat x, y, z, zvalue;
1453 		GLfloat s, t;
1454 		GLfloat w;
1455 
1456 		w = (float)vertices->Z;
1457 
1458 		x =  ((float)vertices->X*((float)Global_VDB_Ptr->VDB_ProjX+1.0f))/((float)vertices->Z*(float)ScreenDescriptorBlock.SDB_CentreX);
1459 		y = -((float)vertices->Y*((float)Global_VDB_Ptr->VDB_ProjY+1.0f))/((float)vertices->Z*(float)ScreenDescriptorBlock.SDB_CentreY);
1460 
1461 		s = TEXCOORD_FIXED(vertices->U, RecipW);
1462 		t = TEXCOORD_FIXED(vertices->V, RecipH);
1463 
1464 		zvalue = vertices->Z+HeadUpDisplayZOffset;
1465 		z = 1.0f - 2.0f*ZNear/zvalue;
1466 
1467 		varrp->v[0] = x*w;
1468 		varrp->v[1] = y*w;
1469 		varrp->v[2] = z*w;
1470 		varrp->v[3] = w;
1471 
1472 		varrp->t[0] = s;
1473 		varrp->t[1] = t;
1474 
1475 		varrp->c[0] = r;
1476 		varrp->c[1] = g;
1477 		varrp->c[2] = b;
1478 		varrp->c[3] = a;
1479 
1480 		varrp->s[0] = 0;
1481 		varrp->s[1] = 0;
1482 		varrp->s[2] = 0;
1483 		varrp->s[3] = 0;
1484 
1485 		varrp++;
1486 		varrc++;
1487 	}
1488 }
1489 
D3D_Particle_Output(PARTICLE * particlePtr,RENDERVERTEX * renderVerticesPtr)1490 void D3D_Particle_Output(PARTICLE *particlePtr, RENDERVERTEX *renderVerticesPtr)
1491 {
1492 	PARTICLE_DESC *particleDescPtr = &ParticleDescription[particlePtr->ParticleID];
1493 	int texoffset = SpecialFXImageNumber;
1494 	GLfloat ZNear;
1495 	int i;
1496 	float RecipW, RecipH;
1497 	int r, g, b, a;
1498 
1499 	D3DTexture *TextureHandle;
1500 
1501 
1502 	ZNear = (GLfloat) (Global_VDB_Ptr->VDB_ClipZ * GlobalScale);
1503 
1504 	TextureHandle = ImageHeaderArray[texoffset].D3DTexture;
1505 
1506 	RecipW = TextureHandle->RecipW / 65536.0f;
1507 	RecipH = TextureHandle->RecipH / 65536.0f;
1508 
1509 	if (particleDescPtr->IsLit && !(particlePtr->ParticleID==PARTICLE_ALIEN_BLOOD && CurrentVisionMode==VISION_MODE_PRED_SEEALIENS) )
1510 	{
1511 		int intensity = LightIntensityAtPoint(&particlePtr->Position);
1512 
1513 		if (particlePtr->ParticleID==PARTICLE_SMOKECLOUD || particlePtr->ParticleID==PARTICLE_ANDROID_BLOOD)
1514 		{
1515 			/* this should be OK. (ColourComponents was RGBA while RGBA_MAKE is BGRA (little endian) */
1516 			r = (particlePtr->Colour >> 0)  & 0xFF;
1517 			g = (particlePtr->Colour >> 8)  & 0xFF;
1518 			b = (particlePtr->Colour >> 16) & 0xFF;
1519 			a = (particlePtr->Colour >> 24) & 0xFF;
1520 		} else {
1521 			r = MUL_FIXED(intensity,particleDescPtr->RedScale[CurrentVisionMode]);
1522 			g = MUL_FIXED(intensity,particleDescPtr->GreenScale[CurrentVisionMode]);
1523 			b = MUL_FIXED(intensity,particleDescPtr->BlueScale[CurrentVisionMode]);
1524 			a = particleDescPtr->Alpha;
1525 		}
1526 	} else {
1527 		b = (particlePtr->Colour >> 0)  & 0xFF;
1528 		g = (particlePtr->Colour >> 8)  & 0xFF;
1529 		r = (particlePtr->Colour >> 16) & 0xFF;
1530 		a = (particlePtr->Colour >> 24) & 0xFF;
1531 	}
1532 	if (RAINBOWBLOOD_CHEATMODE) {
1533 		r = FastRandom()&255;
1534 		g = FastRandom()&255;
1535 		b = FastRandom()&255;
1536 		a = particleDescPtr->Alpha;
1537 	}
1538 
1539 	CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, TextureHandle, particleDescPtr->TranslucencyType, -1);
1540 	SelectProgram(AVP_SHADER_PROGRAM_NO_SECONDARY);
1541 
1542 	for (i = 0; i < RenderPolygon.NumberOfVertices; i++) {
1543 		RENDERVERTEX *vertices = &renderVerticesPtr[i];
1544 
1545 		GLfloat x, y, z;
1546 		GLfloat s, t;
1547 		GLfloat w = (float)vertices->Z;
1548 
1549 		s = TEXCOORD_FIXED(vertices->U, RecipW);
1550 		t = TEXCOORD_FIXED(vertices->V, RecipH);
1551 
1552 		x =  ((float)vertices->X*((float)Global_VDB_Ptr->VDB_ProjX+1.0f))/((float)vertices->Z*(float)ScreenDescriptorBlock.SDB_CentreX);
1553 		y = -((float)vertices->Y*((float)Global_VDB_Ptr->VDB_ProjY+1.0f))/((float)vertices->Z*(float)ScreenDescriptorBlock.SDB_CentreY);
1554 
1555 		if (particleDescPtr->IsDrawnInFront) {
1556 			z = -0.99999f; /* ... */
1557 		} else if (particleDescPtr->IsDrawnAtBack) {
1558 			z = 0.99999f;
1559 		} else {
1560 			z = 1.0 - 2.0*ZNear/((float)vertices->Z); /* currently maps [ZNear, inf) to [-1, 1], probably could be more precise with a ZFar */
1561 		}
1562 
1563 		varrp->v[0] = x*w;
1564 		varrp->v[1] = y*w;
1565 		varrp->v[2] = z*w;
1566 		varrp->v[3] = w;
1567 
1568 		varrp->t[0] = s;
1569 		varrp->t[1] = t;
1570 
1571 		varrp->c[0] = r;
1572 		varrp->c[1] = g;
1573 		varrp->c[2] = b;
1574 		varrp->c[3] = a;
1575 
1576 		varrp->s[0] = 0;
1577 		varrp->s[1] = 0;
1578 		varrp->s[2] = 0;
1579 		varrp->s[3] = 0;
1580 
1581 		varrp++;
1582 		varrc++;
1583 	}
1584 }
1585 
D3D_PredatorThermalVisionPolygon_Output(POLYHEADER * inputPolyPtr,RENDERVERTEX * renderVerticesPtr)1586 void D3D_PredatorThermalVisionPolygon_Output(POLYHEADER *inputPolyPtr, RENDERVERTEX *renderVerticesPtr)
1587 {
1588 	float ZNear;
1589 	int i;
1590 	ZNear = (float) (Global_VDB_Ptr->VDB_ClipZ * GlobalScale);
1591 
1592 	CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, NULL, TRANSLUCENCY_OFF, -1);
1593 	SelectProgram(AVP_SHADER_PROGRAM_NO_TEXTURE);
1594 
1595 	for (i = 0; i < RenderPolygon.NumberOfVertices; i++) {
1596 		RENDERVERTEX *vertices = &renderVerticesPtr[i];
1597 
1598 		GLfloat x, y, z;
1599 		GLfloat w;
1600 		GLfloat zvalue;
1601 
1602 		x =  ((float)vertices->X*((float)Global_VDB_Ptr->VDB_ProjX+1.0f))/((float)vertices->Z*(float)ScreenDescriptorBlock.SDB_CentreX);
1603 		y = -((float)vertices->Y*((float)Global_VDB_Ptr->VDB_ProjY+1.0f))/((float)vertices->Z*(float)ScreenDescriptorBlock.SDB_CentreY);
1604 
1605 		zvalue = vertices->Z+HeadUpDisplayZOffset;
1606 		z = 1.0 - 2*ZNear/zvalue;
1607 
1608 		w = (float)vertices->Z;
1609 
1610 		varrp->v[0] = x*w;
1611 		varrp->v[1] = y*w;
1612 		varrp->v[2] = z*w;
1613 		varrp->v[3] = w;
1614 
1615 		varrp->c[0] = vertices->R;
1616 		varrp->c[1] = vertices->G;
1617 		varrp->c[2] = vertices->B;
1618 		varrp->c[3] = vertices->A;
1619 
1620 		varrp->s[0] = 0;
1621 		varrp->s[1] = 0;
1622 		varrp->s[2] = 0;
1623 		varrp->s[3] = 0;
1624 
1625 		varrp++;
1626 		varrc++;
1627 	}
1628 }
1629 
D3D_ZBufferedGouraudPolygon_Output(POLYHEADER * inputPolyPtr,RENDERVERTEX * renderVerticesPtr)1630 void D3D_ZBufferedGouraudPolygon_Output(POLYHEADER *inputPolyPtr, RENDERVERTEX *renderVerticesPtr)
1631 {
1632 	int flags, i;
1633 	float ZNear;
1634 
1635 	ZNear = (float) (Global_VDB_Ptr->VDB_ClipZ * GlobalScale);
1636 
1637 	flags = inputPolyPtr->PolyFlags;
1638 
1639 	CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, NULL, RenderPolygon.TranslucencyMode, -1);
1640 	SelectProgram(AVP_SHADER_PROGRAM_NO_TEXTURE);
1641 
1642 	for (i = 0; i < RenderPolygon.NumberOfVertices; i++) {
1643 		RENDERVERTEX *vertices = &renderVerticesPtr[i];
1644 		GLfloat x, y, z;
1645 		GLfloat w;
1646 		GLfloat zvalue;
1647 
1648 		zvalue = vertices->Z+HeadUpDisplayZOffset;
1649 		z = 1.0 - 2*ZNear/zvalue;
1650 
1651 		w = (float)vertices->Z;
1652 
1653 		x =  ((float)vertices->X*((float)Global_VDB_Ptr->VDB_ProjX+1.0f))/((float)vertices->Z*(float)ScreenDescriptorBlock.SDB_CentreX);
1654 		y = -((float)vertices->Y*((float)Global_VDB_Ptr->VDB_ProjY+1.0f))/((float)vertices->Z*(float)ScreenDescriptorBlock.SDB_CentreY);
1655 
1656 		varrp->v[0] = x*w;
1657 		varrp->v[1] = y*w;
1658 		varrp->v[2] = z*w;
1659 		varrp->v[3] = w;
1660 
1661 		varrp->c[0] = vertices->R;
1662 		varrp->c[1] = vertices->G;
1663 		varrp->c[2] = vertices->B;
1664 		if (flags & iflag_transparent)
1665 			varrp->c[3] = vertices->A;
1666 		else
1667 			varrp->c[3] = 255;
1668 
1669 		varrp->s[0] = 0;
1670 		varrp->s[1] = 0;
1671 		varrp->s[2] = 0;
1672 		varrp->s[3] = 0;
1673 
1674 		varrp++;
1675 		varrc++;
1676 	}
1677 }
1678 
D3D_PlayerOnFireOverlay()1679 void D3D_PlayerOnFireOverlay()
1680 {
1681 	int c = 128;
1682 	int colour = (FMVParticleColour&0xffffff)+(c<<24);
1683 	GLfloat x[4], y[4], s[4], t[4];
1684 	float u, v;
1685 	int r, g, b, a;
1686 	D3DTexture *TextureHandle;
1687 	int i;
1688 
1689 	b = (colour >> 0)  & 0xFF;
1690 	g = (colour >> 8)  & 0xFF;
1691 	r = (colour >> 16) & 0xFF;
1692 	a = (colour >> 24) & 0xFF;
1693 
1694 	TextureHandle = ImageHeaderArray[BurningImageNumber].D3DTexture;
1695 
1696 	u = (FastRandom()&255)/256.0f;
1697 	v = (FastRandom()&255)/256.0f;
1698 
1699 	x[0] = -1.0f;
1700 	y[0] = -1.0f;
1701 	s[0] = u;
1702 	t[0] = v;
1703 	x[1] =  1.0f;
1704 	y[1] = -1.0f;
1705 	s[1] = u + 1.0f;
1706 	t[1] = v;
1707 	x[2] =  1.0f;
1708 	y[2] =  1.0f;
1709 	s[2] = u + 1.0f;
1710 	t[2] = v + 1.0f;
1711 	x[3] = -1.0f;
1712 	y[3] =  1.0f;
1713 	s[3] = u;
1714 	t[3] = v + 1.0f;
1715 
1716 	CheckTriangleBuffer(4, 0, TextureHandle, TRANSLUCENCY_GLOWING, FILTERING_BILINEAR_ON);
1717 	SelectProgram(AVP_SHADER_PROGRAM_NO_SECONDARY);
1718 
1719 	for (i = 0; i < 4; i++) {
1720 		varrp->v[0] = x[i];
1721 		varrp->v[1] = y[i];
1722 		varrp->v[2] = -1.0f;
1723 		varrp->v[3] = 1.0f;
1724 
1725 		varrp->t[0] = s[i];
1726 		varrp->t[1] = t[i];
1727 
1728 		varrp->c[0] = r;
1729 		varrp->c[1] = g;
1730 		varrp->c[2] = b;
1731 		varrp->c[3] = a;
1732 
1733 		varrp->s[0] = 0;
1734 		varrp->s[1] = 0;
1735 		varrp->s[2] = 0;
1736 		varrp->s[3] = 0;
1737 
1738 		varrp++;
1739 		varrc++;
1740 	}
1741 }
1742 
D3D_PlayerDamagedOverlay(int intensity)1743 void D3D_PlayerDamagedOverlay(int intensity)
1744 {
1745 	D3DTexture *TextureHandle;
1746 	int theta[2];
1747 	int colour, baseColour;
1748 	int r, g, b, a;
1749 	int i;
1750 	int j;
1751 
1752 	theta[0] = (CloakingPhase/8)&4095;
1753 	theta[1] = (800-CloakingPhase/8)&4095;
1754 
1755 	TextureHandle = ImageHeaderArray[SpecialFXImageNumber].D3DTexture;
1756 	switch(AvP.PlayerType) {
1757 		default:
1758 			// LOCALASSERT(0);
1759 		case I_Marine:
1760 			baseColour = 0xff0000;
1761 			break;
1762 		case I_Alien:
1763 			baseColour = 0xffff00;
1764 			break;
1765 		case I_Predator:
1766 			baseColour = 0x00ff00;
1767 			break;
1768 	}
1769 
1770 	for (i = 0; i < 2; i++) {
1771 		GLfloat x[4], y[4], s[4], t[4];
1772 
1773 		if (i == 0) {
1774 			CheckTriangleBuffer(4, 0, TextureHandle, TRANSLUCENCY_INVCOLOUR, FILTERING_BILINEAR_ON);
1775 
1776 			colour = 0xffffff - baseColour + (intensity<<24);
1777 
1778 			b = (colour >> 0)  & 0xFF;
1779 			g = (colour >> 8)  & 0xFF;
1780 			r = (colour >> 16) & 0xFF;
1781 			a = (colour >> 24) & 0xFF;
1782 		} else {
1783 			CheckTriangleBuffer(4, 0, TextureHandle, TRANSLUCENCY_GLOWING, FILTERING_BILINEAR_ON);
1784 
1785 			colour = baseColour + (intensity<<24);
1786 
1787 			b = (colour >> 0)  & 0xFF;
1788 			g = (colour >> 8)  & 0xFF;
1789 			r = (colour >> 16) & 0xFF;
1790 			a = (colour >> 24) & 0xFF;
1791 		}
1792 
1793 		SelectProgram(AVP_SHADER_PROGRAM_NO_SECONDARY);
1794 
1795 		float sin = (GetSin(theta[i]))/65536.0f/16.0f;
1796 		float cos = (GetCos(theta[i]))/65536.0f/16.0f;
1797 
1798 		x[0] = -1.0f;
1799 		y[0] = -1.0f;
1800 		s[0] = 0.875f + (cos*(-1) - sin*(-1));
1801 		t[0] = 0.375f + (sin*(-1) + cos*(-1));
1802 		x[1] =  1.0f;
1803 		y[1] = -1.0f;
1804 		s[1] = 0.875f + (cos*(+1) - sin*(-1));
1805 		t[1] = 0.375f + (sin*(+1) + cos*(-1));
1806 		x[2] =  1.0f;
1807 		y[2] =  1.0f;
1808 		s[2] = 0.875f + (cos*(+1) - sin*(+1));
1809 		t[2] = 0.375f + (sin*(+1) + cos*(+1));
1810 		x[3] = -1.0f;
1811 		y[3] =  1.0f;
1812 		s[3] = 0.875f + (cos*(-1) - sin*(+1));
1813 		t[3] = 0.375f + (sin*(-1) + cos*(+1));
1814 
1815 		for (j = 0; j < 4; j++) {
1816 			varrp->v[0] = x[j];
1817 			varrp->v[1] = y[j];
1818 			varrp->v[2] = -1.0f;
1819 			varrp->v[3] = 1.0f;
1820 
1821 			varrp->t[0] = s[j];
1822 			varrp->t[1] = t[j];
1823 
1824 			varrp->c[0] = r;
1825 			varrp->c[1] = g;
1826 			varrp->c[2] = b;
1827 			varrp->c[3] = a;
1828 
1829 			varrp->s[0] = 0;
1830 			varrp->s[1] = 0;
1831 			varrp->s[2] = 0;
1832 			varrp->s[3] = 0;
1833 
1834 			varrp++;
1835 			varrc++;
1836 		}
1837 	}
1838 }
1839 
DrawNoiseOverlay(int tr)1840 void DrawNoiseOverlay(int tr)
1841 {
1842 	GLfloat x[4], y[4], s[4], t[4], u, v;
1843 	int r, g, b;
1844 	D3DTexture *tex;
1845 	int size;
1846 	int j;
1847 
1848 	r = 255;
1849 	g = 255;
1850 	b = 255;
1851 
1852 	size = 256;
1853 
1854 	tex = ImageHeaderArray[StaticImageNumber].D3DTexture;
1855 
1856 	u = FastRandom()&255;
1857 	v = FastRandom()&255;
1858 
1859 	x[0] = -1.0f;
1860 	y[0] = -1.0f;
1861 	s[0] = u / 256.0f;
1862 	t[0] = v / 256.0f;
1863 	x[1] =  1.0f;
1864 	y[1] = -1.0f;
1865 	s[1] = (u + size) / 256.0f;
1866 	t[1] = v / 256.0f;
1867 	x[2] =  1.0f;
1868 	y[2] =  1.0f;
1869 	s[2] = (u + size) / 256.0f;
1870 	t[2] = (v + size) / 256.0f;
1871 	x[3] = -1.0f;
1872 	y[3] =  1.0f;
1873 	s[3] = u / 256.0f;
1874 	t[3] = (v + size) / 256.0f;
1875 
1876 	// changing the depth func manually, so flush now
1877 	FlushTriangleBuffers(0);
1878 	CheckTriangleBuffer(4, 0, tex, TRANSLUCENCY_GLOWING, FILTERING_BILINEAR_ON);
1879 	SelectProgram(AVP_SHADER_PROGRAM_NO_SECONDARY);
1880 
1881 	for (j = 0; j < 4; j++) {
1882 		varrp->v[0] = x[j];
1883 		varrp->v[1] = y[j];
1884 		varrp->v[2] = 1.0f;
1885 		varrp->v[3] = 1.0f;
1886 
1887 		varrp->t[0] = s[j];
1888 		varrp->t[1] = t[j];
1889 
1890 		varrp->c[0] = r;
1891 		varrp->c[1] = g;
1892 		varrp->c[2] = b;
1893 		varrp->c[3] = tr;
1894 
1895 		varrp->s[0] = 0;
1896 		varrp->s[1] = 0;
1897 		varrp->s[2] = 0;
1898 		varrp->s[3] = 0;
1899 
1900 		varrp++;
1901 		varrc++;
1902 	}
1903 
1904 	pglDepthFunc(GL_ALWAYS);
1905 	FlushTriangleBuffers(0);
1906 	pglDepthFunc(GL_LEQUAL);
1907 }
1908 
D3D_ScreenInversionOverlay()1909 void D3D_ScreenInversionOverlay()
1910 {
1911 	D3DTexture *tex;
1912 	int theta[2];
1913 	int i;
1914 	int j;
1915 
1916 	theta[0] = (CloakingPhase/8)&4095;
1917 	theta[1] = (800-CloakingPhase/8)&4095;
1918 
1919 	tex = ImageHeaderArray[SpecialFXImageNumber].D3DTexture;
1920 
1921 	for (i = 0; i < 2; i++) {
1922 		GLfloat x[4], y[4], s[4], t[4];
1923 
1924 		if (i == 0) {
1925 			CheckTriangleBuffer(4, 0, tex, TRANSLUCENCY_DARKENINGCOLOUR, FILTERING_BILINEAR_ON);
1926 		} else {
1927 			CheckTriangleBuffer(4, 0, tex, TRANSLUCENCY_COLOUR, FILTERING_BILINEAR_ON);
1928 		}
1929 
1930 		SelectProgram(AVP_SHADER_PROGRAM_NO_SECONDARY);
1931 
1932 		float sin = (GetSin(theta[i]))/65536.0f/16.0f;
1933 		float cos = (GetCos(theta[i]))/65536.0f/16.0f;
1934 
1935 		x[0] = -1.0f;
1936 		y[0] = -1.0f;
1937 		s[0] = 0.375f + (cos*(-1) - sin*(-1));
1938 		t[0] = 0.375f + (sin*(-1) + cos*(-1));
1939 		x[1] =  1.0f;
1940 		y[1] = -1.0f;
1941 		s[1] = 0.375f + (cos*(+1) - sin*(-1));
1942 		t[1] = 0.375f + (sin*(+1) + cos*(-1));
1943 		x[2] =  1.0f;
1944 		y[2] =  1.0f;
1945 		s[2] = 0.375f + (cos*(+1) - sin*(+1));
1946 		t[2] = 0.375f + (sin*(+1) + cos*(+1));
1947 		x[3] = -1.0f;
1948 		y[3] =  1.0f;
1949 		s[3] = 0.375f + (cos*(-1) - sin*(+1));
1950 		t[3] = 0.375f + (sin*(-1) + cos*(+1));
1951 
1952 		for (j = 0; j < 4; j++) {
1953 			varrp->v[0] = x[j];
1954 			varrp->v[1] = y[j];
1955 			varrp->v[2] = -1.0f;
1956 			varrp->v[3] = 1.0f;
1957 
1958 			varrp->t[0] = s[j];
1959 			varrp->t[1] = t[j];
1960 
1961 			varrp->c[0] = 255;
1962 			varrp->c[1] = 255;
1963 			varrp->c[2] = 255;
1964 			varrp->c[3] = 255;
1965 
1966 			varrp->s[0] = 0;
1967 			varrp->s[1] = 0;
1968 			varrp->s[2] = 0;
1969 			varrp->s[3] = 0;
1970 
1971 			varrp++;
1972 			varrc++;
1973 		}
1974 	}
1975 }
1976 
D3D_PredatorScreenInversionOverlay()1977 void D3D_PredatorScreenInversionOverlay()
1978 {
1979 	int j;
1980 
1981 	// changing the depth func manually, so flush now
1982 	FlushTriangleBuffers(0);
1983 	CheckTriangleBuffer(4, 0, NULL, TRANSLUCENCY_DARKENINGCOLOUR, -1);
1984 	SelectProgram(AVP_SHADER_PROGRAM_NO_TEXTURE);
1985 
1986 	for (j = 0; j < 4; j++) {
1987 
1988 		switch (j) {
1989 			case 0:
1990 				varrp->v[0] = -1.0f;
1991 				varrp->v[1] = -1.0f;
1992 				break;
1993 			case 1:
1994 				varrp->v[0] =  1.0f;
1995 				varrp->v[1] = -1.0f;
1996 				break;
1997 			case 2:
1998 				varrp->v[0] =  1.0f;
1999 				varrp->v[1] =  1.0f;
2000 				break;
2001 			case 3:
2002 				varrp->v[0] = -1.0f;
2003 				varrp->v[1] =  1.0f;
2004 				break;
2005 		}
2006 
2007 		varrp->v[2] = 1.0f;
2008 		varrp->v[3] = 1.0f;
2009 
2010 		varrp->t[0] = 0.0f;
2011 		varrp->t[1] = 0.0f;
2012 
2013 		varrp->c[0] = 255;
2014 		varrp->c[1] = 255;
2015 		varrp->c[2] = 255;
2016 		varrp->c[3] = 255;
2017 
2018 		varrp->s[0] = 0;
2019 		varrp->s[1] = 0;
2020 		varrp->s[2] = 0;
2021 		varrp->s[3] = 0;
2022 
2023 		varrp++;
2024 		varrc++;
2025 	}
2026 
2027 	pglDepthFunc(GL_ALWAYS);
2028 	FlushTriangleBuffers(0);
2029 	pglDepthFunc(GL_LEQUAL);
2030 }
2031 
DrawScanlinesOverlay(float level)2032 void DrawScanlinesOverlay(float level)
2033 {
2034 	D3DTexture *tex;
2035 	GLfloat x[4], y[4], s[4], t[4];
2036 	float v, size;
2037 	int c;
2038 	int a;
2039 	int j;
2040 
2041 	tex = ImageHeaderArray[PredatorNumbersImageNumber].D3DTexture;
2042 
2043 	c = 255;
2044 	a = 64.0f+level*64.0f;
2045 
2046 	v = 128.0f;
2047 	size = 128.0f*(1.0f-level*0.8f);
2048 
2049 	x[0] = -1.0f;
2050 	y[0] = -1.0f;
2051 	s[0] = (v - size) / 256.0f;
2052 	t[0] = 1.0f;
2053 	x[1] =  1.0f;
2054 	y[1] = -1.0f;
2055 	s[1] = (v - size) / 256.0f;
2056 	t[1] = 1.0f;
2057 	x[2] =  1.0f;
2058 	y[2] =  1.0f;
2059 	s[2] = (v + size) / 256.0f;
2060 	t[2] = 1.0f;
2061 	x[3] = -1.0f;
2062 	y[3] =  1.0f;
2063 	s[3] = (v + size) / 256.0f;
2064 	t[3] = 1.0f;
2065 
2066 	// changing the depth func manually, so flush now
2067 	FlushTriangleBuffers(0);
2068 	CheckTriangleBuffer(4, 0, tex, TRANSLUCENCY_NORMAL, FILTERING_BILINEAR_ON);
2069 	SelectProgram(AVP_SHADER_PROGRAM_NO_SECONDARY);
2070 
2071 	for (j = 0; j < 4; j++) {
2072 		varrp->v[0] = x[j];
2073 		varrp->v[1] = y[j];
2074 		varrp->v[2] = 1.0f;
2075 		varrp->v[3] = 1.0f;
2076 
2077 		varrp->t[0] = s[j];
2078 		varrp->t[1] = t[j];
2079 
2080 		varrp->c[0] = c;
2081 		varrp->c[1] = c;
2082 		varrp->c[2] = c;
2083 		varrp->c[3] = a;
2084 
2085 		varrp->s[0] = 0;
2086 		varrp->s[1] = 0;
2087 		varrp->s[2] = 0;
2088 		varrp->s[3] = 0;
2089 
2090 		varrp++;
2091 		varrc++;
2092 	}
2093 
2094 	pglDepthFunc(GL_ALWAYS);
2095 	FlushTriangleBuffers(0);
2096 	pglDepthFunc(GL_LEQUAL);
2097 }
2098 
D3D_FadeDownScreen(int brightness,int colour)2099 void D3D_FadeDownScreen(int brightness, int colour)
2100 {
2101 	int t, r, g, b, a;
2102 	GLfloat x[4], y[4];
2103 	int i;
2104 
2105 	t = 255 - (brightness>>8);
2106 	if (t<0) t = 0;
2107 	colour = (t<<24)+colour;
2108 
2109 	CheckTriangleBuffer(4, 0, NULL, TRANSLUCENCY_NORMAL, -1);
2110 	SelectProgram(AVP_SHADER_PROGRAM_NO_TEXTURE);
2111 
2112 	b = (colour >> 0)  & 0xFF;
2113 	g = (colour >> 8)  & 0xFF;
2114 	r = (colour >> 16) & 0xFF;
2115 	a = (colour >> 24) & 0xFF;
2116 
2117 	x[0] = -1.0f;
2118 	y[0] = -1.0f;
2119 	x[1] =  1.0f;
2120 	y[1] = -1.0f;
2121 	x[2] =  1.0f;
2122 	y[2] =  1.0f;
2123 	x[3] = -1.0f;
2124 	y[3] =  1.0f;
2125 
2126 	for (i = 0; i < 4; i++) {
2127 		varrp->v[0] = x[i];
2128 		varrp->v[1] = y[i];
2129 		varrp->v[2] = -1.0f;
2130 		varrp->v[3] = 1.0f;
2131 
2132 		varrp->t[0] = 0.0f;
2133 		varrp->t[1] = 0.0f;
2134 
2135 		varrp->c[0] = r;
2136 		varrp->c[1] = g;
2137 		varrp->c[2] = b;
2138 		varrp->c[3] = a;
2139 
2140 		varrp->s[0] = 0;
2141 		varrp->s[1] = 0;
2142 		varrp->s[2] = 0;
2143 		varrp->s[3] = 0;
2144 
2145 		varrp++;
2146 		varrc++;
2147 	}
2148 }
2149 
DrawFullscreenTexture(int texureObject)2150 void DrawFullscreenTexture(int texureObject)
2151 {
2152 	int j;
2153 
2154 	// using a custom texture, so flush now
2155 	FlushTriangleBuffers(0);
2156 	CheckTriangleBuffer(4, 0, NULL, TRANSLUCENCY_OFF, -1);
2157 	SelectProgram(AVP_SHADER_PROGRAM_NO_COLOR_NO_DISCARD);
2158 	pglBindTexture(GL_TEXTURE_2D, texureObject);
2159 	pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2160 	pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2161 
2162 	for (j = 0; j < 4; j++) {
2163 
2164 		switch (j) {
2165 			case 0:
2166 				varrp->v[0] = -1.0f;
2167 				varrp->v[1] = -1.0f;
2168 				varrp->t[0] =  0.0f;
2169 				varrp->t[1] =  0.0f;
2170 				break;
2171 			case 1:
2172 				varrp->v[0] =  1.0f;
2173 				varrp->v[1] = -1.0f;
2174 				varrp->t[0] =  1.0f;
2175 				varrp->t[1] =  0.0f;
2176 				break;
2177 			case 2:
2178 				varrp->v[0] =  1.0f;
2179 				varrp->v[1] =  1.0f;
2180 				varrp->t[0] =  1.0f;
2181 				varrp->t[1] =  1.0f;
2182 				break;
2183 			case 3:
2184 				varrp->v[0] = -1.0f;
2185 				varrp->v[1] =  1.0f;
2186 				varrp->t[0] =  0.0f;
2187 				varrp->t[1] =  1.0f;
2188 				break;
2189 		}
2190 
2191 		varrp->v[2] = -1.0f;
2192 		varrp->v[3] =  1.0f;
2193 
2194 		varrp->c[0] = 255;
2195 		varrp->c[1] = 255;
2196 		varrp->c[2] = 255;
2197 		varrp->c[3] = 255;
2198 
2199 		varrp->s[0] = 0;
2200 		varrp->s[1] = 0;
2201 		varrp->s[2] = 0;
2202 		varrp->s[3] = 0;
2203 
2204 		varrp++;
2205 		varrc++;
2206 	}
2207 
2208 	FlushTriangleBuffers(0);
2209 	pglBindTexture(GL_TEXTURE_2D, 0);
2210 }
2211 
D3D_HUD_Setup()2212 void D3D_HUD_Setup()
2213 {
2214 	FlushTriangleBuffers(1);
2215 
2216 	CheckTranslucencyModeIsCorrect(TRANSLUCENCY_GLOWING);
2217 
2218 	pglDepthFunc(GL_LEQUAL);
2219 }
2220 
D3D_HUDQuad_Output(int imageNumber,struct VertexTag * quadVerticesPtr,unsigned int colour)2221 void D3D_HUDQuad_Output(int imageNumber, struct VertexTag *quadVerticesPtr, unsigned int colour)
2222 {
2223 	float RecipW, RecipH;
2224 	int i;
2225 	D3DTexture *tex = ImageHeaderArray[imageNumber].D3DTexture;
2226 	GLfloat x, y, s, t;
2227 	int r, g, b, a;
2228 
2229 /* possibly use polygon offset? (predator hud) */
2230 
2231 	CheckTriangleBuffer(4, 0, tex, TRANSLUCENCY_GLOWING, -1);
2232 	SelectProgram(AVP_SHADER_PROGRAM_NO_SECONDARY);
2233 
2234 	RecipW = tex->RecipW / 65536.0f;
2235 	RecipH = tex->RecipH / 65536.0f;
2236 
2237 	b = (colour >> 0)  & 0xFF;
2238 	g = (colour >> 8)  & 0xFF;
2239 	r = (colour >> 16) & 0xFF;
2240 	a = (colour >> 24) & 0xFF;
2241 
2242 	for (i = 0; i < 4; i++) {
2243 		x = quadVerticesPtr[i].X;
2244 		x =  (x - ScreenDescriptorBlock.SDB_CentreX)/ScreenDescriptorBlock.SDB_CentreX;
2245 		y = quadVerticesPtr[i].Y;
2246 		y = -(y - ScreenDescriptorBlock.SDB_CentreY)/ScreenDescriptorBlock.SDB_CentreY;
2247 
2248 		s = TEXCOORD_FIXED(quadVerticesPtr[i].U<<16, RecipW);
2249 		t = TEXCOORD_FIXED(quadVerticesPtr[i].V<<16, RecipH);
2250 
2251 		varrp->v[0] = x;
2252 		varrp->v[1] = y;
2253 		varrp->v[2] = -1.0f;
2254 		varrp->v[3] = 1.0f;
2255 
2256 		varrp->t[0] = s;
2257 		varrp->t[1] = t;
2258 
2259 		varrp->c[0] = r;
2260 		varrp->c[1] = g;
2261 		varrp->c[2] = b;
2262 		varrp->c[3] = a;
2263 
2264 		varrp->s[0] = 0;
2265 		varrp->s[1] = 0;
2266 		varrp->s[2] = 0;
2267 		varrp->s[3] = 0;
2268 
2269 		varrp++;
2270 		varrc++;
2271 	}
2272 }
2273 
D3D_RenderHUDNumber_Centred(unsigned int number,int x,int y,int colour)2274 void D3D_RenderHUDNumber_Centred(unsigned int number,int x,int y,int colour)
2275 {
2276 	struct VertexTag quadVertices[4];
2277 	int noOfDigits=3;
2278 	int h = MUL_FIXED(HUDScaleFactor,HUD_DIGITAL_NUMBERS_HEIGHT);
2279 	int w = MUL_FIXED(HUDScaleFactor,HUD_DIGITAL_NUMBERS_WIDTH);
2280 
2281 	quadVertices[0].Y = y;
2282 	quadVertices[1].Y = y;
2283 	quadVertices[2].Y = y + h;
2284 	quadVertices[3].Y = y + h;
2285 
2286 	x += (3*w)/2;
2287 
2288 	CheckFilteringModeIsCorrect(FILTERING_BILINEAR_OFF);
2289 
2290 	do {
2291 		int topLeftU, topLeftV;
2292 
2293 		int digit = number%10;
2294 		number/=10;
2295 
2296 		if (digit<8) {
2297 			topLeftU = 1+(digit)*16;
2298 			topLeftV = 1;
2299 		} else {
2300 			topLeftU = 1+(digit-8)*16;
2301 			topLeftV = 1+24;
2302 		}
2303 		if (AvP.PlayerType == I_Marine) topLeftV+=80;
2304 
2305 		quadVertices[0].U = topLeftU;
2306 		quadVertices[0].V = topLeftV;
2307 		quadVertices[1].U = topLeftU + HUD_DIGITAL_NUMBERS_WIDTH;
2308 		quadVertices[1].V = topLeftV;
2309 		quadVertices[2].U = topLeftU + HUD_DIGITAL_NUMBERS_WIDTH;
2310 		quadVertices[2].V = topLeftV + HUD_DIGITAL_NUMBERS_HEIGHT;
2311 		quadVertices[3].U = topLeftU;
2312 		quadVertices[3].V = topLeftV + HUD_DIGITAL_NUMBERS_HEIGHT;
2313 
2314 		x -= 1+w;
2315 		quadVertices[0].X = x;
2316 		quadVertices[3].X = x;
2317 		quadVertices[1].X = x + w;
2318 		quadVertices[2].X = x + w;
2319 
2320 		D3D_HUDQuad_Output(HUDFontsImageNumber, quadVertices, colour);
2321 
2322 	} while (--noOfDigits);
2323 }
2324 
D3D_RenderHUDString(char * stringPtr,int x,int y,int colour)2325 void D3D_RenderHUDString(char *stringPtr,int x,int y,int colour)
2326 {
2327 	struct VertexTag quadVertices[4];
2328 
2329 	if (stringPtr == NULL)
2330 	{
2331 		return;
2332 	}
2333 
2334 	quadVertices[0].Y = y-1;
2335 	quadVertices[1].Y = y-1;
2336 	quadVertices[2].Y = y + HUD_FONT_HEIGHT + 1;
2337 	quadVertices[3].Y = y + HUD_FONT_HEIGHT + 1;
2338 
2339 	CheckFilteringModeIsCorrect(FILTERING_BILINEAR_OFF);
2340 
2341 	while( *stringPtr )
2342 	{
2343 		char c = *stringPtr++;
2344 
2345 		{
2346 			int topLeftU = 1+((c-32)&15)*16;
2347 			int topLeftV = 1+((c-32)>>4)*16;
2348 
2349 			quadVertices[0].U = topLeftU - 1;
2350 			quadVertices[0].V = topLeftV - 1;
2351 			quadVertices[1].U = topLeftU + HUD_FONT_WIDTH + 1;
2352 			quadVertices[1].V = topLeftV - 1;
2353 			quadVertices[2].U = topLeftU + HUD_FONT_WIDTH + 1;
2354 			quadVertices[2].V = topLeftV + HUD_FONT_HEIGHT + 1;
2355 			quadVertices[3].U = topLeftU - 1;
2356 			quadVertices[3].V = topLeftV + HUD_FONT_HEIGHT + 1;
2357 
2358 			quadVertices[0].X = x - 1;
2359 			quadVertices[3].X = x - 1;
2360 			quadVertices[1].X = x + HUD_FONT_WIDTH + 1;
2361 			quadVertices[2].X = x + HUD_FONT_WIDTH + 1;
2362 
2363 			D3D_HUDQuad_Output
2364 			(
2365 				AAFontImageNumber,
2366 				quadVertices,
2367 				colour
2368 			);
2369 		}
2370 		x += AAFontWidths[(unsigned char)c];
2371 	}
2372 }
2373 
D3D_RenderHUDString_Clipped(char * stringPtr,int x,int y,int colour)2374 void D3D_RenderHUDString_Clipped(char *stringPtr,int x,int y,int colour)
2375 {
2376 	struct VertexTag quadVertices[4];
2377 
2378 // 	LOCALASSERT(y<=0);
2379 	if (stringPtr == NULL)
2380 	{
2381 		return;
2382 	}
2383 
2384 	CheckFilteringModeIsCorrect(FILTERING_BILINEAR_OFF);
2385 
2386 	quadVertices[2].Y = y + HUD_FONT_HEIGHT + 1;
2387 	quadVertices[3].Y = y + HUD_FONT_HEIGHT + 1;
2388 
2389 	quadVertices[0].Y = 0;
2390 	quadVertices[1].Y = 0;
2391 
2392 	while ( *stringPtr )
2393 	{
2394 		char c = *stringPtr++;
2395 
2396 		{
2397 			int topLeftU = 1+((c-32)&15)*16;
2398 			int topLeftV = 1+((c-32)>>4)*16;
2399 
2400 			quadVertices[0].U = topLeftU - 1;
2401 			quadVertices[0].V = topLeftV - y;
2402 			quadVertices[1].U = topLeftU + HUD_FONT_WIDTH+1;
2403 			quadVertices[1].V = topLeftV - y;
2404 			quadVertices[2].U = topLeftU + HUD_FONT_WIDTH+1;
2405 			quadVertices[2].V = topLeftV + HUD_FONT_HEIGHT+1;
2406 			quadVertices[3].U = topLeftU - 1;
2407 			quadVertices[3].V = topLeftV + HUD_FONT_HEIGHT+1;
2408 
2409 			quadVertices[0].X = x - 1;
2410 			quadVertices[3].X = x - 1;
2411 			quadVertices[1].X = x + HUD_FONT_WIDTH + 1;
2412 			quadVertices[2].X = x + HUD_FONT_WIDTH + 1;
2413 
2414 			D3D_HUDQuad_Output
2415 			(
2416 				AAFontImageNumber,
2417 				quadVertices,
2418 				colour
2419 			);
2420 		}
2421 		x += AAFontWidths[(unsigned char)c];
2422 	}
2423 }
2424 
D3D_RenderHUDString_Centred(char * stringPtr,int centreX,int y,int colour)2425 void D3D_RenderHUDString_Centred(char *stringPtr, int centreX, int y, int colour)
2426 {
2427 	int x, length = 0;
2428 	char *ptr = stringPtr;
2429 	struct VertexTag quadVertices[4];
2430 
2431 	if (stringPtr == NULL)
2432 	{
2433 		return;
2434 	}
2435 
2436 	while(*ptr)
2437 	{
2438 		length+=AAFontWidths[(unsigned char)*ptr++];
2439 	}
2440 	length = MUL_FIXED(HUDScaleFactor,length);
2441 
2442 	x = centreX-length/2;
2443 
2444 	quadVertices[0].Y = y-MUL_FIXED(HUDScaleFactor,1);
2445 	quadVertices[1].Y = y-MUL_FIXED(HUDScaleFactor,1);
2446 	quadVertices[2].Y = y + MUL_FIXED(HUDScaleFactor,HUD_FONT_HEIGHT + 1);
2447 	quadVertices[3].Y = y + MUL_FIXED(HUDScaleFactor,HUD_FONT_HEIGHT + 1);
2448 
2449 	CheckFilteringModeIsCorrect(FILTERING_BILINEAR_OFF);
2450 
2451 	while( *stringPtr )
2452 	{
2453 		char c = *stringPtr++;
2454 
2455 		{
2456 			int topLeftU = 1+((c-32)&15)*16;
2457 			int topLeftV = 1+((c-32)>>4)*16;
2458 
2459 			quadVertices[0].U = topLeftU - 1;
2460 			quadVertices[0].V = topLeftV - 1;
2461 			quadVertices[1].U = topLeftU + HUD_FONT_WIDTH + 1;
2462 			quadVertices[1].V = topLeftV - 1;
2463 			quadVertices[2].U = topLeftU + HUD_FONT_WIDTH + 1;
2464 			quadVertices[2].V = topLeftV + HUD_FONT_HEIGHT + 1;
2465 			quadVertices[3].U = topLeftU - 1;
2466 			quadVertices[3].V = topLeftV + HUD_FONT_HEIGHT + 1;
2467 
2468 			quadVertices[0].X = x - MUL_FIXED(HUDScaleFactor,1);
2469 			quadVertices[3].X = x - MUL_FIXED(HUDScaleFactor,1);
2470 			quadVertices[1].X = x + MUL_FIXED(HUDScaleFactor,HUD_FONT_WIDTH + 1);
2471 			quadVertices[2].X = x + MUL_FIXED(HUDScaleFactor,HUD_FONT_WIDTH + 1);
2472 
2473 			D3D_HUDQuad_Output
2474 			(
2475 				AAFontImageNumber,
2476 				quadVertices,
2477 				colour
2478 			);
2479 		}
2480 		x += MUL_FIXED(HUDScaleFactor,AAFontWidths[(unsigned char)c]);
2481 	}
2482 }
2483 
RenderString(char * stringPtr,int x,int y,int colour)2484 void RenderString(char *stringPtr, int x, int y, int colour)
2485 {
2486 	D3D_RenderHUDString(stringPtr,x,y,colour);
2487 }
2488 
RenderStringCentred(char * stringPtr,int centreX,int y,int colour)2489 void RenderStringCentred(char *stringPtr, int centreX, int y, int colour)
2490 {
2491 	int length = 0;
2492 	char *ptr = stringPtr;
2493 
2494 	while(*ptr)
2495 	{
2496 		length+=AAFontWidths[(unsigned char)*ptr++];
2497 	}
2498 	D3D_RenderHUDString(stringPtr,centreX-length/2,y,colour);
2499 }
2500 
RenderStringVertically(char * stringPtr,int centreX,int bottomY,int colour)2501 void RenderStringVertically(char *stringPtr, int centreX, int bottomY, int colour)
2502 {
2503 	struct VertexTag quadVertices[4];
2504 	int y = bottomY;
2505 
2506 	quadVertices[0].X = centreX - (HUD_FONT_HEIGHT/2) - 1;
2507 	quadVertices[1].X = quadVertices[0].X;
2508 	quadVertices[2].X = quadVertices[0].X+2+HUD_FONT_HEIGHT*1;
2509 	quadVertices[3].X = quadVertices[2].X;
2510 
2511 	CheckFilteringModeIsCorrect(FILTERING_BILINEAR_OFF);
2512 	while( *stringPtr )
2513 	{
2514 		char c = *stringPtr++;
2515 
2516 		{
2517 			int topLeftU = 1+((c-32)&15)*16;
2518 			int topLeftV = 1+((c-32)>>4)*16;
2519 
2520 			quadVertices[0].U = topLeftU - 1;
2521 			quadVertices[0].V = topLeftV - 1;
2522 			quadVertices[1].U = topLeftU + HUD_FONT_WIDTH;
2523 			quadVertices[1].V = topLeftV - 1;
2524 			quadVertices[2].U = topLeftU + HUD_FONT_WIDTH;
2525 			quadVertices[2].V = topLeftV + HUD_FONT_HEIGHT + 1;
2526 			quadVertices[3].U = topLeftU - 1;
2527 			quadVertices[3].V = topLeftV + HUD_FONT_HEIGHT + 1;
2528 
2529 			quadVertices[0].Y = y ;
2530 			quadVertices[1].Y = y - HUD_FONT_WIDTH*1 -1;
2531 			quadVertices[2].Y = y - HUD_FONT_WIDTH*1 -1;
2532 			quadVertices[3].Y = y ;
2533 
2534 			D3D_HUDQuad_Output
2535 			(
2536 				AAFontImageNumber,
2537 				quadVertices,
2538 				colour
2539 			);
2540 		}
2541 	   	y -= AAFontWidths[(unsigned char)c];
2542 	}
2543 }
2544 
Hardware_RenderSmallMenuText(char * textPtr,int x,int y,int alpha,enum AVPMENUFORMAT_ID format)2545 int Hardware_RenderSmallMenuText(char *textPtr, int x, int y, int alpha, enum AVPMENUFORMAT_ID format)
2546 {
2547 	switch(format)
2548 	{
2549 		default:
2550 			fprintf(stderr, "Hardware_RenderSmallMenuText: UNKNOWN TEXT FORMAT\n");
2551 			exit(EXIT_FAILURE);
2552 //		GLOBALASSERT("UNKNOWN TEXT FORMAT"==0);
2553 		case AVPMENUFORMAT_LEFTJUSTIFIED:
2554 		{
2555 			// supplied x is correct
2556 			break;
2557 		}
2558 		case AVPMENUFORMAT_RIGHTJUSTIFIED:
2559 		{
2560 			int length = 0;
2561 			char *ptr = textPtr;
2562 
2563 			while(*ptr)
2564 			{
2565 				length+=AAFontWidths[(unsigned char) *ptr++];
2566 			}
2567 
2568 			x -= length;
2569 			break;
2570 		}
2571 		case AVPMENUFORMAT_CENTREJUSTIFIED:
2572 		{
2573 			int length = 0;
2574 			char *ptr = textPtr;
2575 
2576 			while(*ptr)
2577 			{
2578 				length+=AAFontWidths[(unsigned char) *ptr++];
2579 			}
2580 
2581 			x -= length/2;
2582 			break;
2583 		}
2584 	}
2585 
2586 //	LOCALASSERT(x>0);
2587 
2588 	{
2589 		unsigned int colour = alpha>>8;
2590 		if (colour>255) colour = 255;
2591 		colour = (colour<<24)+0xffffff;
2592 		D3D_RenderHUDString(textPtr,x,y,colour);
2593 	}
2594 	return x;
2595 }
2596 
Hardware_RenderSmallMenuText_Coloured(char * textPtr,int x,int y,int alpha,enum AVPMENUFORMAT_ID format,int red,int green,int blue)2597 int Hardware_RenderSmallMenuText_Coloured(char *textPtr, int x, int y, int alpha, enum AVPMENUFORMAT_ID format, int red, int green, int blue)
2598 {
2599 	switch(format)
2600 	{
2601 		default:
2602 //		GLOBALASSERT("UNKNOWN TEXT FORMAT"==0);
2603 			fprintf(stderr, "Hardware_RenderSmallMenuText_Coloured: UNKNOWN TEXT FORMAT\n");
2604 			exit(EXIT_FAILURE);
2605 		case AVPMENUFORMAT_LEFTJUSTIFIED:
2606 		{
2607 			// supplied x is correct
2608 			break;
2609 		}
2610 		case AVPMENUFORMAT_RIGHTJUSTIFIED:
2611 		{
2612 			int length = 0;
2613 			char *ptr = textPtr;
2614 
2615 			while(*ptr)
2616 			{
2617 				length+=AAFontWidths[(unsigned char) *ptr++];
2618 			}
2619 
2620 			x -= length;
2621 			break;
2622 		}
2623 		case AVPMENUFORMAT_CENTREJUSTIFIED:
2624 		{
2625 			int length = 0;
2626 			char *ptr = textPtr;
2627 
2628 			while(*ptr)
2629 			{
2630 				length+=AAFontWidths[(unsigned char) *ptr++];
2631 			}
2632 
2633 			x -= length/2;
2634 			break;
2635 		}
2636 	}
2637 
2638 //	LOCALASSERT(x>0);
2639 
2640 	{
2641 		unsigned int colour = alpha>>8;
2642 		if (colour>255) colour = 255;
2643 		colour = (colour<<24);
2644 		colour += MUL_FIXED(red,255)<<16;
2645 		colour += MUL_FIXED(green,255)<<8;
2646 		colour += MUL_FIXED(blue,255);
2647 		D3D_RenderHUDString(textPtr,x,y,colour);
2648 	}
2649 	return x;
2650 }
2651 
Hardware_RenderKeyConfigRectangle(int alpha)2652 void Hardware_RenderKeyConfigRectangle(int alpha)
2653 {
2654 	extern void D3D_DrawRectangle(int x, int y, int w, int h, int alpha);
2655 	D3D_DrawRectangle(10,ScreenDescriptorBlock.SDB_Height/2+25-115,ScreenDescriptorBlock.SDB_Width-20,250,alpha);
2656 }
2657 
Hardware_RenderHighlightRectangle(int x1,int y1,int x2,int y2,int r,int g,int b)2658 void Hardware_RenderHighlightRectangle(int x1,int y1,int x2,int y2,int r, int g, int b)
2659 {
2660 	D3D_Rectangle(x1, y1, x2, y2, r, g, b, 255);
2661 }
2662 
D3D_DrawSliderBar(int x,int y,int alpha)2663 void D3D_DrawSliderBar(int x, int y, int alpha)
2664 {
2665 	struct VertexTag quadVertices[4];
2666 	int sliderHeight = 11;
2667 	unsigned int colour = alpha>>8;
2668 
2669 	if (colour>255) colour = 255;
2670 	colour = (colour<<24)+0xffffff;
2671 
2672 	quadVertices[0].Y = y;
2673 	quadVertices[1].Y = y;
2674 	quadVertices[2].Y = y + sliderHeight;
2675 	quadVertices[3].Y = y + sliderHeight;
2676 
2677 	CheckFilteringModeIsCorrect(FILTERING_BILINEAR_OFF);
2678 	{
2679 		int topLeftU = 1;
2680 		int topLeftV = 68;
2681 
2682 		quadVertices[0].U = topLeftU;
2683 		quadVertices[0].V = topLeftV;
2684 		quadVertices[1].U = topLeftU + 2;
2685 		quadVertices[1].V = topLeftV;
2686 		quadVertices[2].U = topLeftU + 2;
2687 		quadVertices[2].V = topLeftV + sliderHeight;
2688 		quadVertices[3].U = topLeftU;
2689 		quadVertices[3].V = topLeftV + sliderHeight;
2690 
2691 		quadVertices[0].X = x;
2692 		quadVertices[3].X = x;
2693 		quadVertices[1].X = x + 2;
2694 		quadVertices[2].X = x + 2;
2695 
2696 		D3D_HUDQuad_Output
2697 		(
2698 			HUDFontsImageNumber,
2699 			quadVertices,
2700 			colour
2701 		);
2702 	}
2703 	{
2704 		int topLeftU = 7;
2705 		int topLeftV = 68;
2706 
2707 		quadVertices[0].U = topLeftU;
2708 		quadVertices[0].V = topLeftV;
2709 		quadVertices[1].U = topLeftU + 2;
2710 		quadVertices[1].V = topLeftV;
2711 		quadVertices[2].U = topLeftU + 2;
2712 		quadVertices[2].V = topLeftV + sliderHeight;
2713 		quadVertices[3].U = topLeftU;
2714 		quadVertices[3].V = topLeftV + sliderHeight;
2715 
2716 		quadVertices[0].X = x+213+2;
2717 		quadVertices[3].X = x+213+2;
2718 		quadVertices[1].X = x+2 +213+2;
2719 		quadVertices[2].X = x+2 +213+2;
2720 
2721 		D3D_HUDQuad_Output
2722 		(
2723 			HUDFontsImageNumber,
2724 			quadVertices,
2725 			colour
2726 		);
2727 	}
2728 	quadVertices[2].Y = y + 2;
2729 	quadVertices[3].Y = y + 2;
2730 
2731 	{
2732 		int topLeftU = 5;
2733 		int topLeftV = 77;
2734 
2735 		quadVertices[0].U = topLeftU;
2736 		quadVertices[0].V = topLeftV;
2737 		quadVertices[1].U = topLeftU;
2738 		quadVertices[1].V = topLeftV;
2739 		quadVertices[2].U = topLeftU;
2740 		quadVertices[2].V = topLeftV + 2;
2741 		quadVertices[3].U = topLeftU;
2742 		quadVertices[3].V = topLeftV + 2;
2743 
2744 		quadVertices[0].X = x + 2;
2745 		quadVertices[3].X = x + 2;
2746 		quadVertices[1].X = x + 215;
2747 		quadVertices[2].X = x + 215;
2748 
2749 		D3D_HUDQuad_Output
2750 		(
2751 			HUDFontsImageNumber,
2752 			quadVertices,
2753 			colour
2754 		);
2755 	}
2756 	quadVertices[0].Y = y + 9;
2757 	quadVertices[1].Y = y + 9;
2758 	quadVertices[2].Y = y + 11;
2759 	quadVertices[3].Y = y + 11;
2760 
2761 	{
2762 		int topLeftU = 5;
2763 		int topLeftV = 77;
2764 
2765 		quadVertices[0].U = topLeftU;
2766 		quadVertices[0].V = topLeftV;
2767 		quadVertices[1].U = topLeftU;
2768 		quadVertices[1].V = topLeftV;
2769 		quadVertices[2].U = topLeftU;
2770 		quadVertices[2].V = topLeftV + 2;
2771 		quadVertices[3].U = topLeftU;
2772 		quadVertices[3].V = topLeftV + 2;
2773 
2774 		quadVertices[0].X = x + 2;
2775 		quadVertices[3].X = x + 2;
2776 		quadVertices[1].X = x + 215;
2777 		quadVertices[2].X = x + 215;
2778 
2779 		D3D_HUDQuad_Output
2780 		(
2781 			HUDFontsImageNumber,
2782 			quadVertices,
2783 			colour
2784 		);
2785 	}
2786 }
2787 
D3D_DrawSlider(int x,int y,int alpha)2788 void D3D_DrawSlider(int x, int y, int alpha)
2789 {
2790 	struct VertexTag quadVertices[4];
2791 	int sliderHeight = 5;
2792 	unsigned int colour = alpha>>8;
2793 
2794 	if (colour>255) colour = 255;
2795 	colour = (colour<<24)+0xffffff;
2796 
2797 	quadVertices[0].Y = y;
2798 	quadVertices[1].Y = y;
2799 	quadVertices[2].Y = y + sliderHeight;
2800 	quadVertices[3].Y = y + sliderHeight;
2801 
2802 	CheckFilteringModeIsCorrect(FILTERING_BILINEAR_OFF);
2803 	{
2804 		int topLeftU = 11;
2805 		int topLeftV = 74;
2806 
2807 		quadVertices[0].U = topLeftU;
2808 		quadVertices[0].V = topLeftV;
2809 		quadVertices[1].U = topLeftU + 9;
2810 		quadVertices[1].V = topLeftV;
2811 		quadVertices[2].U = topLeftU + 9;
2812 		quadVertices[2].V = topLeftV + sliderHeight;
2813 		quadVertices[3].U = topLeftU;
2814 		quadVertices[3].V = topLeftV + sliderHeight;
2815 
2816 		quadVertices[0].X = x;
2817 		quadVertices[3].X = x;
2818 		quadVertices[1].X = x + 9;
2819 		quadVertices[2].X = x + 9;
2820 
2821 		D3D_HUDQuad_Output
2822 		(
2823 			HUDFontsImageNumber,
2824 			quadVertices,
2825 			colour
2826 		);
2827 	}
2828 }
2829 
D3D_DrawRectangle(int x,int y,int w,int h,int alpha)2830 void D3D_DrawRectangle(int x, int y, int w, int h, int alpha)
2831 {
2832 	struct VertexTag quadVertices[4];
2833 	unsigned int colour = alpha>>8;
2834 
2835 	if (colour>255) colour = 255;
2836 	colour = (colour<<24)+0xffffff;
2837 
2838 	quadVertices[0].Y = y;
2839 	quadVertices[1].Y = y;
2840 	quadVertices[2].Y = y + 6;
2841 	quadVertices[3].Y = y + 6;
2842 
2843 	CheckFilteringModeIsCorrect(FILTERING_BILINEAR_OFF);
2844 	/* top left corner */
2845 	{
2846 		int topLeftU = 1;
2847 		int topLeftV = 238;
2848 
2849 		quadVertices[0].U = topLeftU;
2850 		quadVertices[0].V = topLeftV;
2851 		quadVertices[1].U = topLeftU + 6;
2852 		quadVertices[1].V = topLeftV;
2853 		quadVertices[2].U = topLeftU + 6;
2854 		quadVertices[2].V = topLeftV + 6;
2855 		quadVertices[3].U = topLeftU;
2856 		quadVertices[3].V = topLeftV + 6;
2857 
2858 		quadVertices[0].X = x;
2859 		quadVertices[3].X = x;
2860 		quadVertices[1].X = x + 6;
2861 		quadVertices[2].X = x + 6;
2862 
2863 		D3D_HUDQuad_Output
2864 		(
2865 			AAFontImageNumber,
2866 			quadVertices,
2867 			colour
2868 		);
2869 	}
2870 	/* top */
2871 	{
2872 		int topLeftU = 9;
2873 		int topLeftV = 238;
2874 
2875 		quadVertices[0].U = topLeftU;
2876 		quadVertices[0].V = topLeftV;
2877 		quadVertices[1].U = topLeftU;
2878 		quadVertices[1].V = topLeftV;
2879 		quadVertices[2].U = topLeftU;
2880 		quadVertices[2].V = topLeftV + 6;
2881 		quadVertices[3].U = topLeftU;
2882 		quadVertices[3].V = topLeftV + 6;
2883 
2884 		quadVertices[0].X = x+6;
2885 		quadVertices[3].X = x+6;
2886 		quadVertices[1].X = x+6 + w-12;
2887 		quadVertices[2].X = x+6 + w-12;
2888 
2889 		D3D_HUDQuad_Output
2890 		(
2891 			AAFontImageNumber,
2892 			quadVertices,
2893 			colour
2894 		);
2895 	}
2896 	/* top right corner */
2897 	{
2898 		int topLeftU = 11;
2899 		int topLeftV = 238;
2900 
2901 		quadVertices[0].U = topLeftU;
2902 		quadVertices[0].V = topLeftV;
2903 		quadVertices[1].U = topLeftU + 6;
2904 		quadVertices[1].V = topLeftV;
2905 		quadVertices[2].U = topLeftU + 6;
2906 		quadVertices[2].V = topLeftV + 6;
2907 		quadVertices[3].U = topLeftU;
2908 		quadVertices[3].V = topLeftV + 6;
2909 
2910 		quadVertices[0].X = x + w - 6;
2911 		quadVertices[3].X = x + w - 6;
2912 		quadVertices[1].X = x + w;
2913 		quadVertices[2].X = x + w;
2914 
2915 		D3D_HUDQuad_Output
2916 		(
2917 			AAFontImageNumber,
2918 			quadVertices,
2919 			colour
2920 		);
2921 	}
2922 	quadVertices[0].Y = y + 6;
2923 	quadVertices[1].Y = y + 6;
2924 	quadVertices[2].Y = y + h - 6;
2925 	quadVertices[3].Y = y + h - 6;
2926 	/* right */
2927 	{
2928 		int topLeftU = 1;
2929 		int topLeftV = 246;
2930 
2931 		quadVertices[0].U = topLeftU;
2932 		quadVertices[0].V = topLeftV;
2933 		quadVertices[1].U = topLeftU + 6;
2934 		quadVertices[1].V = topLeftV;
2935 		quadVertices[2].U = topLeftU + 6;
2936 		quadVertices[2].V = topLeftV;
2937 		quadVertices[3].U = topLeftU;
2938 		quadVertices[3].V = topLeftV;
2939 
2940 		D3D_HUDQuad_Output
2941 		(
2942 			AAFontImageNumber,
2943 			quadVertices,
2944 			colour
2945 		);
2946 	}
2947 	/* left */
2948 	{
2949 		int topLeftU = 1;
2950 		int topLeftV = 246;
2951 
2952 		quadVertices[0].U = topLeftU;
2953 		quadVertices[0].V = topLeftV;
2954 		quadVertices[1].U = topLeftU + 6;
2955 		quadVertices[1].V = topLeftV;
2956 		quadVertices[2].U = topLeftU + 6;
2957 		quadVertices[2].V = topLeftV;
2958 		quadVertices[3].U = topLeftU;
2959 		quadVertices[3].V = topLeftV;
2960 
2961 		quadVertices[0].X = x;
2962 		quadVertices[3].X = x;
2963 		quadVertices[1].X = x + 6;
2964 		quadVertices[2].X = x + 6;
2965 
2966 		D3D_HUDQuad_Output
2967 		(
2968 			AAFontImageNumber,
2969 			quadVertices,
2970 			colour
2971 		);
2972 	}
2973 	quadVertices[0].Y = y + h - 6;
2974 	quadVertices[1].Y = y + h - 6;
2975 	quadVertices[2].Y = y + h;
2976 	quadVertices[3].Y = y + h;
2977 	/* bottom left corner */
2978 	{
2979 		int topLeftU = 1;
2980 		int topLeftV = 248;
2981 
2982 		quadVertices[0].U = topLeftU;
2983 		quadVertices[0].V = topLeftV;
2984 		quadVertices[1].U = topLeftU + 6;
2985 		quadVertices[1].V = topLeftV;
2986 		quadVertices[2].U = topLeftU + 6;
2987 		quadVertices[2].V = topLeftV + 6;
2988 		quadVertices[3].U = topLeftU;
2989 		quadVertices[3].V = topLeftV + 6;
2990 
2991 		quadVertices[0].X = x;
2992 		quadVertices[3].X = x;
2993 		quadVertices[1].X = x + 6;
2994 		quadVertices[2].X = x + 6;
2995 
2996 		D3D_HUDQuad_Output
2997 		(
2998 			AAFontImageNumber,
2999 			quadVertices,
3000 			colour
3001 		);
3002 	}
3003 	/* bottom */
3004 	{
3005 		int topLeftU = 9;
3006 		int topLeftV = 238;
3007 
3008 		quadVertices[0].U = topLeftU;
3009 		quadVertices[0].V = topLeftV;
3010 		quadVertices[1].U = topLeftU;
3011 		quadVertices[1].V = topLeftV;
3012 		quadVertices[2].U = topLeftU;
3013 		quadVertices[2].V = topLeftV + 6;
3014 		quadVertices[3].U = topLeftU;
3015 		quadVertices[3].V = topLeftV + 6;
3016 
3017 		quadVertices[0].X = x+6;
3018 		quadVertices[3].X = x+6;
3019 		quadVertices[1].X = x+6 + w-12;
3020 		quadVertices[2].X = x+6 + w-12;
3021 
3022 		D3D_HUDQuad_Output
3023 		(
3024 			AAFontImageNumber,
3025 			quadVertices,
3026 			colour
3027 		);
3028 	}
3029 	/* bottom right corner */
3030 	{
3031 		int topLeftU = 11;
3032 		int topLeftV = 248;
3033 
3034 		quadVertices[0].U = topLeftU;
3035 		quadVertices[0].V = topLeftV;
3036 		quadVertices[1].U = topLeftU + 6;
3037 		quadVertices[1].V = topLeftV;
3038 		quadVertices[2].U = topLeftU + 6;
3039 		quadVertices[2].V = topLeftV + 6;
3040 		quadVertices[3].U = topLeftU;
3041 		quadVertices[3].V = topLeftV + 6;
3042 
3043 		quadVertices[0].X = x + w - 6;
3044 		quadVertices[3].X = x + w - 6;
3045 		quadVertices[1].X = x + w;
3046 		quadVertices[2].X = x + w;
3047 
3048 		D3D_HUDQuad_Output
3049 		(
3050 			AAFontImageNumber,
3051 			quadVertices,
3052 			colour
3053 		);
3054 	}
3055 }
3056 
D3D_DrawColourBar(int yTop,int yBottom,int rScale,int gScale,int bScale)3057 void D3D_DrawColourBar(int yTop, int yBottom, int rScale, int gScale, int bScale)
3058 {
3059 	extern unsigned char GammaValues[256];
3060 	GLfloat x[2], y[2];
3061 	int i;
3062 	int r;
3063 	int g;
3064 	int b;
3065 	int a;
3066 	int start;
3067 
3068 	CheckTriangleBuffer(256*2, 255*2, NULL, TRANSLUCENCY_OFF, -1);
3069 	SelectProgram(AVP_SHADER_PROGRAM_NO_TEXTURE);
3070 
3071 	start = varrc;
3072 
3073 	for (i = 0; i < 256; i++) {
3074 		unsigned int c;
3075 
3076 		c = GammaValues[i];
3077 		r = MUL_FIXED(c,rScale);
3078 		g = MUL_FIXED(c,gScale);
3079 		b = MUL_FIXED(c,bScale);
3080 		a = 255;
3081 
3082 		x[0] = (Global_VDB_Ptr->VDB_ClipRight*i)/255;
3083 		x[0] =  (x[0] - ScreenDescriptorBlock.SDB_CentreX)/ScreenDescriptorBlock.SDB_CentreX;
3084 		y[0] = yTop;
3085 		y[0] = -(y[0] - ScreenDescriptorBlock.SDB_CentreY)/ScreenDescriptorBlock.SDB_CentreY;
3086 
3087 		x[1] = x[0];
3088 		y[1] = yBottom;
3089 		y[1] = -(y[1] - ScreenDescriptorBlock.SDB_CentreY)/ScreenDescriptorBlock.SDB_CentreY;
3090 
3091 		varrp->v[0] = x[0];
3092 		varrp->v[1] = y[0];
3093 		varrp->v[2] = -1.0f;
3094 		varrp->v[3] = 1.0f;
3095 
3096 		varrp->t[0] = 0.0f;
3097 		varrp->t[1] = 0.0f;
3098 
3099 		varrp->c[0] = r;
3100 		varrp->c[1] = g;
3101 		varrp->c[2] = b;
3102 		varrp->c[3] = a;
3103 
3104 		varrp->s[0] = 0;
3105 		varrp->s[1] = 0;
3106 		varrp->s[2] = 0;
3107 		varrp->s[3] = 0;
3108 
3109 		varrp++;
3110 		varrc++;
3111 
3112 		varrp->v[0] = x[1];
3113 		varrp->v[1] = y[1];
3114 		varrp->v[2] = -1.0f;
3115 		varrp->v[3] = 1.0f;
3116 
3117 		varrp->t[0] = 0.0f;
3118 		varrp->t[1] = 0.0f;
3119 
3120 		varrp->c[0] = r;
3121 		varrp->c[1] = g;
3122 		varrp->c[2] = b;
3123 		varrp->c[3] = a;
3124 
3125 		varrp->s[0] = 0;
3126 		varrp->s[1] = 0;
3127 		varrp->s[2] = 0;
3128 		varrp->s[3] = 0;
3129 
3130 		varrp++;
3131 		varrc++;
3132 	}
3133 
3134 	for (i = 0; i < 255; i++) {
3135 		tarrp->a = start+(i+0)*2+0;
3136 		tarrp->b = start+(i+0)*2+1;
3137 		tarrp->c = start+(i+1)*2+0;
3138 		tarrp++;
3139 		tarrc++;
3140 		tarrp->a = start+(i+0)*2+1;
3141 		tarrp->b = start+(i+1)*2+1;
3142 		tarrp->c = start+(i+1)*2+0;
3143 		tarrp++;
3144 		tarrc++;
3145 	}
3146 }
3147 
ColourFillBackBuffer(int FillColour)3148 void ColourFillBackBuffer(int FillColour)
3149 {
3150 	float r, g, b, a;
3151 
3152 	FlushTriangleBuffers(1);
3153 
3154 	b = ((FillColour >> 0)  & 0xFF) / 255.0f;
3155 	g = ((FillColour >> 8)  & 0xFF) / 255.0f;
3156 	r = ((FillColour >> 16) & 0xFF) / 255.0f;
3157 	a = ((FillColour >> 24) & 0xFF) / 255.0f;
3158 
3159 	pglClearColor(r, g, b, a);
3160 
3161 	pglClear(GL_COLOR_BUFFER_BIT);
3162 }
3163 
ColourFillBackBufferQuad(int FillColour,int x0,int y0,int x1,int y1)3164 void ColourFillBackBufferQuad(int FillColour, int x0, int y0, int x1, int y1)
3165 {
3166 	GLfloat x[4], y[4];
3167 	int r, g, b, a;
3168 	int i;
3169 
3170 	if (y1 <= y0)
3171 		return;
3172 
3173 	CheckTriangleBuffer(4, 0, NULL, TRANSLUCENCY_OFF, -1);
3174 	SelectProgram(AVP_SHADER_PROGRAM_NO_TEXTURE);
3175 
3176 	b = ((FillColour >> 0)  & 0xFF);
3177 	g = ((FillColour >> 8)  & 0xFF);
3178 	r = ((FillColour >> 16) & 0xFF);
3179 	a = ((FillColour >> 24) & 0xFF);
3180 
3181 	x[0] = x0;
3182 	x[0] =  (x[0] - ScreenDescriptorBlock.SDB_CentreX)/ScreenDescriptorBlock.SDB_CentreX;
3183 	y[0] = y0;
3184 	y[0] = -(y[0] - ScreenDescriptorBlock.SDB_CentreY)/ScreenDescriptorBlock.SDB_CentreY;
3185 
3186 	x[1] = x1 - 1;
3187 	x[1] =  (x[1] - ScreenDescriptorBlock.SDB_CentreX)/ScreenDescriptorBlock.SDB_CentreX;
3188 	y[1] = y0;
3189 	y[1] = -(y[1] - ScreenDescriptorBlock.SDB_CentreY)/ScreenDescriptorBlock.SDB_CentreY;
3190 
3191 	x[2] = x1 - 1;
3192 	x[2] =  (x[2] - ScreenDescriptorBlock.SDB_CentreX)/ScreenDescriptorBlock.SDB_CentreX;
3193 	y[2] = y1 - 1;
3194 	y[2] = -(y[2] - ScreenDescriptorBlock.SDB_CentreY)/ScreenDescriptorBlock.SDB_CentreY;
3195 
3196 	x[3] = x0;
3197 	x[3] =  (x[3] - ScreenDescriptorBlock.SDB_CentreX)/ScreenDescriptorBlock.SDB_CentreX;
3198 	y[3] = y1 - 1;
3199 	y[3] = -(y[3] - ScreenDescriptorBlock.SDB_CentreY)/ScreenDescriptorBlock.SDB_CentreY;
3200 
3201 	for (i = 0; i < 4; i++) {
3202 		varrp->v[0] = x[i];
3203 		varrp->v[1] = y[i];
3204 		varrp->v[2] = -1.0f;
3205 		varrp->v[3] = 1.0f;
3206 
3207 		varrp->t[0] = 0.0f;
3208 		varrp->t[1] = 0.0f;
3209 
3210 		varrp->c[0] = r;
3211 		varrp->c[1] = g;
3212 		varrp->c[2] = b;
3213 		varrp->c[3] = a;
3214 
3215 		varrp->s[0] = 0;
3216 		varrp->s[1] = 0;
3217 		varrp->s[2] = 0;
3218 		varrp->s[3] = 0;
3219 
3220 		varrp++;
3221 		varrc++;
3222 	}
3223 }
3224 
D3D_DrawBackdrop()3225 void D3D_DrawBackdrop()
3226 {
3227 	extern int NumActiveBlocks;
3228 	extern DISPLAYBLOCK *ActiveBlockList[];
3229 	extern MODULE *playerPherModule;
3230 
3231 	PLAYER_STATUS *playerStatusPtr;
3232 	int numOfObjects = NumActiveBlocks;
3233 	int needToDrawBackdrop = 0;
3234 
3235 	if (TRIPTASTIC_CHEATMODE||MOTIONBLUR_CHEATMODE)
3236 		return;
3237 
3238 	if (ShowDebuggingText.Tears) {
3239 		ColourFillBackBuffer((63<<5));
3240 		return;
3241 	}
3242 
3243 	while(numOfObjects--) {
3244 		DISPLAYBLOCK *objectPtr = ActiveBlockList[numOfObjects];
3245 		MODULE *modulePtr = objectPtr->ObMyModule;
3246 
3247 		if (modulePtr && (ModuleCurrVisArray[modulePtr->m_index] == 2) && modulePtr->m_flags&MODULEFLAG_SKY) {
3248 			needToDrawBackdrop = 1;
3249 			break;
3250 		}
3251 	}
3252 
3253 	if (needToDrawBackdrop) {
3254 		extern BOOL LevelHasStars;
3255 		extern void RenderSky(void);
3256 		extern void RenderStarfield(void);
3257 
3258 		ColourFillBackBuffer(0);
3259 
3260 		if (LevelHasStars) {
3261 			RenderStarfield();
3262 		} else {
3263 			RenderSky();
3264 		}
3265 
3266 		return;
3267 	}
3268 
3269 	if (!playerPherModule) {
3270 		ColourFillBackBuffer(0);
3271 		return;
3272 	}
3273 
3274 	playerStatusPtr = (PLAYER_STATUS *) (Player->ObStrategyBlock->SBdataptr);
3275 
3276 	if (!playerStatusPtr->IsAlive || FREEFALL_CHEATMODE) {
3277 		ColourFillBackBuffer(0);
3278 		return;
3279 	}
3280 }
3281 
BltImage(RECT * dest,DDSurface * image,RECT * src)3282 void BltImage(RECT *dest, DDSurface *image, RECT *src)
3283 {
3284     float x[4];
3285     float y[4];
3286     float s[4];
3287     float t[4];
3288     int i;
3289 
3290 	x[0] = dest->left;
3291 	x[0] =  (x[0] - ScreenDescriptorBlock.SDB_CentreX)/ScreenDescriptorBlock.SDB_CentreX;
3292 	y[0] = dest->top;
3293 	y[0] = -(y[0] - ScreenDescriptorBlock.SDB_CentreY)/ScreenDescriptorBlock.SDB_CentreY;
3294 
3295 	x[1] = dest->right;
3296 	x[1] =  (x[1] - ScreenDescriptorBlock.SDB_CentreX)/ScreenDescriptorBlock.SDB_CentreX;
3297 	y[1] = dest->top;
3298 	y[1] = -(y[1] - ScreenDescriptorBlock.SDB_CentreY)/ScreenDescriptorBlock.SDB_CentreY;
3299 
3300 	x[2] = dest->right;
3301 	x[2] =  (x[2] - ScreenDescriptorBlock.SDB_CentreX)/ScreenDescriptorBlock.SDB_CentreX;
3302 	y[2] = dest->bottom;
3303 	y[2] = -(y[2] - ScreenDescriptorBlock.SDB_CentreY)/ScreenDescriptorBlock.SDB_CentreY;
3304 
3305 	x[3] = dest->left;
3306 	x[3] =  (x[3] - ScreenDescriptorBlock.SDB_CentreX)/ScreenDescriptorBlock.SDB_CentreX;
3307 	y[3] = dest->bottom;
3308 	y[3] = -(y[3] - ScreenDescriptorBlock.SDB_CentreY)/ScreenDescriptorBlock.SDB_CentreY;
3309 
3310 	s[0] = src->left * image->RecipW;
3311 	t[0] = src->top * image->RecipH;
3312 
3313 	s[1] = src->right * image->RecipW;
3314 	t[1] = src->top * image->RecipH;
3315 
3316 	s[2] = src->right * image->RecipW;
3317 	t[2] = src->bottom * image->RecipH;
3318 
3319 	s[3] = src->left * image->RecipW;
3320 	t[3] = src->bottom * image->RecipH;
3321 
3322     CheckTriangleBuffer(4, 0, image, TRANSLUCENCY_OFF, -1);
3323     SelectProgram(AVP_SHADER_PROGRAM_NO_SECONDARY);
3324 
3325 	for (i = 0; i < 4; i++) {
3326 		varrp->v[0] = x[i];
3327 		varrp->v[1] = y[i];
3328 		varrp->v[2] = -1.0f;
3329 		varrp->v[3] = 1.0f;
3330 
3331 		varrp->t[0] = s[i];
3332 		varrp->t[1] = t[i];
3333 
3334 		varrp->c[0] = 255;
3335 		varrp->c[1] = 255;
3336 		varrp->c[2] = 255;
3337 		varrp->c[3] = 255;
3338 
3339 		varrp->s[0] = 0;
3340 		varrp->s[1] = 0;
3341 		varrp->s[2] = 0;
3342 		varrp->s[3] = 0;
3343 
3344 		varrp++;
3345 		varrc++;
3346 	}
3347 }
3348 
3349 /* ** */
3350 
3351 /* Hacked in special effects */
3352 
3353 extern int NormalFrameTime;
3354 
3355 void UpdateForceField(void);
3356 void D3D_DrawForceField(int xOrigin, int yOrigin, int zOrigin, int fieldType);
3357 
3358 void UpdateWaterFall(void);
3359 void D3D_DrawWaterFall(int xOrigin, int yOrigin, int zOrigin);
3360 void D3D_DrawPowerFence(int xOrigin, int yOrigin, int zOrigin, int xScale, int yScale, int zScale);
3361 void D3D_DrawExplosion(int xOrigin, int yOrigin, int zOrigin, int size);
3362 
3363 void D3D_DrawWaterPatch(int xOrigin, int yOrigin, int zOrigin);
3364 
3365 void D3D_DrawWaterOctagonPatch(int xOrigin, int yOrigin, int zOrigin, int xOffset, int zOffset);
3366 
3367 int LightSourceWaterPoint(VECTORCH *pointPtr,int offset);
3368 void D3D_DrawWaterMesh_Unclipped(void);
3369 void D3D_DrawWaterMesh_Clipped(void);
3370 
3371 
3372 void D3D_DrawMoltenMetal(int xOrigin, int yOrigin, int zOrigin);
3373 void D3D_DrawMoltenMetalMesh_Unclipped(void);
3374 void D3D_DrawMoltenMetalMesh_Clipped(void);
3375 
3376 int MeshXScale;
3377 int MeshZScale;
3378 int WaterFallBase;
3379 
3380 int WaterXOrigin;
3381 int WaterZOrigin;
3382 float WaterUScale;
3383 float WaterVScale;
3384 
D3D_DrawParticle_Rain(PARTICLE * particlePtr,VECTORCH * prevPositionPtr)3385 void D3D_DrawParticle_Rain(PARTICLE *particlePtr,VECTORCH *prevPositionPtr)
3386 {
3387 	VECTORCH vertices[3];
3388 	float ZNear;
3389 	int i;
3390 
3391 	vertices[0] = *prevPositionPtr;
3392 
3393 	/* translate second vertex into view space */
3394 	TranslatePointIntoViewspace(&vertices[0]);
3395 
3396 	/* is particle within normal view frustrum ? */
3397 	if((-vertices[0].vx <= vertices[0].vz)
3398 	&&(vertices[0].vx <= vertices[0].vz)
3399 	&&(-vertices[0].vy <= vertices[0].vz)
3400 	&&(vertices[0].vy <= vertices[0].vz))
3401 	{
3402 
3403 		vertices[1] = particlePtr->Position;
3404 		vertices[2] = particlePtr->Position;
3405 		vertices[1].vx += particlePtr->Offset.vx;
3406 		vertices[2].vx -= particlePtr->Offset.vx;
3407 		vertices[1].vz += particlePtr->Offset.vz;
3408 		vertices[2].vz -= particlePtr->Offset.vz;
3409 
3410 		/* translate particle into view space */
3411 		TranslatePointIntoViewspace(&vertices[1]);
3412 		TranslatePointIntoViewspace(&vertices[2]);
3413 
3414 		ZNear = (float) (Global_VDB_Ptr->VDB_ClipZ * GlobalScale);
3415 
3416 		CheckTriangleBuffer(3, 0, NULL, TRANSLUCENCY_NORMAL, -1);
3417 		SelectProgram(AVP_SHADER_PROGRAM_NO_TEXTURE);
3418 
3419 		for (i = 0; i < 3; i++) {
3420 			GLfloat xf, yf, zf;
3421 			GLfloat w;
3422 
3423 			xf =  ((float)vertices[i].vx*((float)Global_VDB_Ptr->VDB_ProjX+1.0f))/((float)vertices[i].vz*(float)ScreenDescriptorBlock.SDB_CentreX);
3424 			yf = -((float)vertices[i].vy*((float)Global_VDB_Ptr->VDB_ProjY+1.0f))/((float)vertices[i].vz*(float)ScreenDescriptorBlock.SDB_CentreY);
3425 
3426 			zf = 1.0f - 2.0f*ZNear/(float)vertices[i].vz;
3427 			w = (float)vertices[i].vz;
3428 
3429 			varrp->v[0] = xf*w;
3430 			varrp->v[1] = yf*w;
3431 			varrp->v[2] = zf*w;
3432 			varrp->v[3] = w;
3433 
3434 			if (i == 0) {
3435 				varrp->c[0] = 0;
3436 				varrp->c[1] = 255;
3437 				varrp->c[2] = 255;
3438 				varrp->c[3] = 32;
3439 			} else {
3440 				varrp->c[0] = 255;
3441 				varrp->c[1] = 255;
3442 				varrp->c[2] = 255;
3443 				varrp->c[3] = 32;
3444 			}
3445 
3446 			varrp->s[0] = 0;
3447 			varrp->s[1] = 0;
3448 			varrp->s[2] = 0;
3449 			varrp->s[3] = 0;
3450 
3451 			varrp++;
3452 			varrc++;
3453 		}
3454 	}
3455 }
3456 
PostLandscapeRendering()3457 void PostLandscapeRendering()
3458 {
3459 	extern int NumOnScreenBlocks;
3460 	extern DISPLAYBLOCK *OnScreenBlockList[];
3461 	int numOfObjects = NumOnScreenBlocks;
3462 
3463 	extern char LevelName[];
3464 
3465 	if (!strcmp(LevelName,"fall")||!strcmp(LevelName,"fall_m"))
3466 	{
3467 		char drawWaterFall = 0;
3468 		char drawStream = 0;
3469 		char drawStream2 = 0;
3470 
3471 		while(numOfObjects)
3472 		{
3473 			DISPLAYBLOCK *objectPtr = OnScreenBlockList[--numOfObjects];
3474 			MODULE *modulePtr = objectPtr->ObMyModule;
3475 
3476 			/* if it's a module, which isn't inside another module */
3477 			if (modulePtr && modulePtr->name)
3478 			{
3479 				if( (!strcmp(modulePtr->name,"fall01"))
3480 				  ||(!strcmp(modulePtr->name,"well01"))
3481 				  ||(!strcmp(modulePtr->name,"well02"))
3482 				  ||(!strcmp(modulePtr->name,"well03"))
3483 				  ||(!strcmp(modulePtr->name,"well04"))
3484 				  ||(!strcmp(modulePtr->name,"well05"))
3485 				  ||(!strcmp(modulePtr->name,"well06"))
3486 				  ||(!strcmp(modulePtr->name,"well07"))
3487 				  ||(!strcmp(modulePtr->name,"well08"))
3488 				  ||(!strcmp(modulePtr->name,"well")))
3489 				{
3490 					drawWaterFall = 1;
3491 				}
3492 				else if( (!strcmp(modulePtr->name,"stream02"))
3493 				       ||(!strcmp(modulePtr->name,"stream03"))
3494 				       ||(!strcmp(modulePtr->name,"watergate")))
3495 				{
3496 		   			drawStream = 1;
3497 				}
3498 				else if(  (!strcmp(modulePtr->name,"openwat03"))
3499 					||(!strcmp(modulePtr->name,"openwat04"))
3500 					||(!strcmp(modulePtr->name,"openwat04A"))
3501 					||(!strcmp(modulePtr->name,"openwat02")))
3502 				{
3503 					drawStream2 = 1;
3504 				}
3505 
3506 			}
3507 		}
3508 
3509 		if (drawWaterFall)
3510 		{
3511 //			CurrTextureHandle = NULL;
3512 //			CheckBoundTextureIsCorrect(NULL);
3513 //			CheckTranslucencyModeIsCorrect(TRANSLUCENCY_NORMAL);
3514 
3515 			FlushTriangleBuffers(1);
3516 			pglDepthMask(GL_FALSE);
3517 
3518 			WaterFallBase = 109952;
3519 
3520 			MeshZScale = (66572-51026)/15;
3521 			MeshXScale = (109952+3039)/45;
3522 
3523 	   		D3D_DrawWaterFall(175545,-3039,51026);
3524 //			MeshZScale = -(538490-392169);
3525 //			MeshXScale = 55000;
3526 //			D3D_DrawWaterPatch(-100000, WaterFallBase, 538490);
3527 
3528 			FlushTriangleBuffers(1);
3529 			pglDepthMask(GL_TRUE);
3530 		}
3531 		if (drawStream)
3532 		{
3533 			int x = 68581;
3534 			int y = 12925; /* probably should lower this a little.. */
3535 			int z = 93696;
3536 			MeshXScale = (87869-68581);
3537 			MeshZScale = (105385-93696);
3538 			{
3539 				extern void CheckForObjectsInWater(int minX, int maxX, int minZ, int maxZ, int averageY);
3540 				CheckForObjectsInWater(x, x+MeshXScale, z, z+MeshZScale, y);
3541 			}
3542 
3543 			WaterXOrigin=x;
3544 			WaterZOrigin=z;
3545 			WaterUScale = 4.0f/(float)MeshXScale;
3546 			WaterVScale = 4.0f/(float)MeshZScale;
3547 		 	MeshXScale/=4;
3548 		 	MeshZScale/=2;
3549 
3550 			CurrTextureHandle = ImageHeaderArray[ChromeImageNumber].D3DTexture;
3551 			CheckTriangleBuffer(0, 0, CurrTextureHandle, TRANSLUCENCY_NORMAL, -1);
3552 
3553 		 	D3D_DrawWaterPatch(x, y, z);
3554 		 	D3D_DrawWaterPatch(x+MeshXScale, y, z);
3555 		 	D3D_DrawWaterPatch(x+MeshXScale*2, y, z);
3556 		 	D3D_DrawWaterPatch(x+MeshXScale*3, y, z);
3557 		 	D3D_DrawWaterPatch(x, y, z+MeshZScale);
3558 		 	D3D_DrawWaterPatch(x+MeshXScale, y, z+MeshZScale);
3559 		 	D3D_DrawWaterPatch(x+MeshXScale*2, y, z+MeshZScale);
3560 		 	D3D_DrawWaterPatch(x+MeshXScale*3, y, z+MeshZScale);
3561 		}
3562 		if (drawStream2)
3563 		{
3564 #if 0 /* added, but then disabled (too squishy) */
3565 			int x = 217400;
3566 			int y = 20750;
3567 			int z = 54000;
3568 			MeshXScale = (87869-68581);
3569 			MeshZScale = (105385-93696);
3570 			{
3571 				extern void CheckForObjectsInWater(int minX, int maxX, int minZ, int maxZ, int averageY);
3572 				CheckForObjectsInWater(x, x+MeshXScale, z, z+MeshZScale, y);
3573 			}
3574 
3575 			WaterXOrigin=x;
3576 			WaterZOrigin=z;
3577 			WaterUScale = 4.0f/(float)MeshXScale;
3578 			WaterVScale = 4.0f/(float)MeshZScale;
3579 		 	MeshXScale/=4;
3580 		 	MeshZScale/=2;
3581 
3582 			CurrTextureHandle = ImageHeaderArray[ChromeImageNumber].D3DTexture;
3583 			CheckTriangleBuffer(0, 0, CurrTextureHandle, TRANSLUCENCY_NORMAL, -1);
3584 
3585 		 	D3D_DrawWaterPatch(x, y, z);
3586 		 	D3D_DrawWaterPatch(x+MeshXScale, y, z);
3587 		 	D3D_DrawWaterPatch(x+MeshXScale*2, y, z);
3588 		 	D3D_DrawWaterPatch(x+MeshXScale*3, y, z);
3589 		 	D3D_DrawWaterPatch(x, y, z+MeshZScale);
3590 		 	D3D_DrawWaterPatch(x+MeshXScale, y, z+MeshZScale);
3591 		 	D3D_DrawWaterPatch(x+MeshXScale*2, y, z+MeshZScale);
3592 		 	D3D_DrawWaterPatch(x+MeshXScale*3, y, z+MeshZScale);
3593 #endif
3594 		}
3595 	}
3596 #if 0
3597 	else if ( (!__stricmp(LevelName,"e3demo")) || (!__stricmp(LevelName,"e3demosp")) )
3598 	{
3599 		int drawOctagonPool = -1;
3600 		int drawFMV = -1;
3601 		int drawPredatorFMV = -1;
3602 		int drawSwirlyFMV = -1;
3603 		int drawSwirlyFMV2 = -1;
3604 		int drawSwirlyFMV3 = -1;
3605 		while(numOfObjects)
3606 		{
3607 			DISPLAYBLOCK *objectPtr = OnScreenBlockList[--numOfObjects];
3608 			MODULE *modulePtr = objectPtr->ObMyModule;
3609 
3610 			/* if it's a module, which isn't inside another module */
3611 			if (modulePtr && modulePtr->name)
3612 			{
3613 				if(!__stricmp(modulePtr->name,"water1"))
3614 				{
3615 					drawOctagonPool = modulePtr->m_index;
3616 				}
3617 				else if(!__stricmp(modulePtr->name,"marine01b"))
3618 				{
3619 					drawFMV = modulePtr->m_index;
3620 				}
3621 				else if(!_stricmp(modulePtr->name,"predator01"))
3622 				{
3623 					drawPredatorFMV = modulePtr->m_index;
3624 				}
3625 				else if(!_stricmp(modulePtr->name,"toptopgr01"))
3626 				{
3627 					drawSwirlyFMV = modulePtr->m_index;
3628 				}
3629 				else if(!_stricmp(modulePtr->name,"grille04"))
3630 				{
3631 					drawSwirlyFMV2 = modulePtr->m_index;
3632 				}
3633 				#if 0
3634 				else if(!_stricmp(modulePtr->name,"marine05"))
3635 				{
3636 					drawSwirlyFMV3 = modulePtr->m_index;
3637 				}
3638 				#endif
3639 			}
3640 		}
3641 		#if FMV_ON
3642 //		UpdateFMVTextures(3);
3643 
3644 
3645 		if (drawFMV!=-1)
3646 		{
3647 			DECAL fmvDecal =
3648 			{
3649 				DECAL_FMV,
3650 			};
3651 			fmvDecal.ModuleIndex = drawFMV;
3652 			fmvDecal.UOffset = 0;
3653 
3654 			UpdateFMVTextures(4);
3655 
3656 			for (int z=0; z<6; z++)
3657 			{
3658 				for (int y=0; y<3; y++)
3659 				{
3660 					fmvDecal.Vertices[0].vx = -149;
3661 					fmvDecal.Vertices[1].vx = -149;
3662 					fmvDecal.Vertices[2].vx = -149;
3663 					fmvDecal.Vertices[3].vx = -149;
3664 
3665 					fmvDecal.Vertices[0].vy = -3254+y*744;
3666 					fmvDecal.Vertices[1].vy = -3254+y*744;
3667 					fmvDecal.Vertices[2].vy = -3254+y*744+744;
3668 					fmvDecal.Vertices[3].vy = -3254+y*744+744;
3669 
3670 					fmvDecal.Vertices[0].vz = 49440+z*993;
3671 					fmvDecal.Vertices[1].vz = 49440+z*993+993;
3672 					fmvDecal.Vertices[2].vz = 49440+z*993+993;
3673 					fmvDecal.Vertices[3].vz = 49440+z*993;
3674 					fmvDecal.Centre.vx = ((z+y)%3)+1;
3675 					RenderDecal(&fmvDecal);
3676 				}
3677 			}
3678 		}
3679 		if (drawPredatorFMV!=-1)
3680 		{
3681 			DECAL fmvDecal =
3682 			{
3683 				DECAL_FMV,
3684 			};
3685 			fmvDecal.ModuleIndex = drawPredatorFMV;
3686 			fmvDecal.UOffset = 0;
3687 
3688 			UpdateFMVTextures(4);
3689 
3690 			for (int z=0; z<12; z++)
3691 			{
3692 				for (int y=0; y<7; y++)
3693 				{
3694 					fmvDecal.Vertices[0].vx = -7164;
3695 					fmvDecal.Vertices[1].vx = -7164;
3696 					fmvDecal.Vertices[2].vx = -7164;
3697 					fmvDecal.Vertices[3].vx = -7164;
3698 
3699 					fmvDecal.Vertices[0].vy = -20360+y*362;
3700 					fmvDecal.Vertices[1].vy = -20360+y*362;
3701 					fmvDecal.Vertices[2].vy = -20360+y*362+362;
3702 					fmvDecal.Vertices[3].vy = -20360+y*362+362;
3703 
3704 					fmvDecal.Vertices[0].vz = 1271+z*483+483;
3705 					fmvDecal.Vertices[1].vz = 1271+z*483;
3706 					fmvDecal.Vertices[2].vz = 1271+z*483;
3707 					fmvDecal.Vertices[3].vz = 1271+z*483+483;
3708 					fmvDecal.Centre.vx = (z+y)%3;
3709 					RenderDecal(&fmvDecal);
3710 				}
3711 			}
3712 		}
3713 
3714 		#endif
3715 
3716 		if (drawSwirlyFMV!=-1)
3717 		{
3718 			UpdateFMVTextures(1);
3719 			D3D_DrawSwirlyFMV(30000,-12500,0);
3720 		}
3721 		if (drawSwirlyFMV2!=-1)
3722 		{
3723 			UpdateFMVTextures(1);
3724 			D3D_DrawSwirlyFMV(2605,-6267-2000,17394-3200);
3725 		}
3726 
3727 		if (drawSwirlyFMV3!=-1)
3728 		{
3729 //			UpdateFMVTextures(1);
3730 			D3D_DrawSwirlyFMV(5117,3456-3000,52710-2000);
3731 		}
3732 		if (drawOctagonPool!=-1)
3733 		{
3734 			#if FMV_ON
3735 			UpdateFMVTextures(1);
3736 
3737 			MeshXScale = (3000);
3738 			MeshZScale = (4000);
3739 			D3D_DrawFMVOnWater(-1000,3400,22000);
3740 			{
3741 				DECAL fmvDecal =
3742 				{
3743 					DECAL_FMV,
3744 					{
3745 					{0,-2500,29000},
3746 					{2000,-2500,29000},
3747 					{2000,-2500+750*2,29000},
3748 					{0,-2500+750*2,29000}
3749 					},
3750 					0
3751 				};
3752 				fmvDecal.ModuleIndex = drawOctagonPool;
3753 				fmvDecal.Centre.vx = 0;
3754 				fmvDecal.UOffset = 0;
3755 
3756 				RenderDecal(&fmvDecal);
3757 			}
3758 			#endif
3759 
3760 			int highDetailRequired = 1;
3761 			int x = 1023;
3762 			int y = 3400;
3763 			int z = 27536;
3764 
3765 			{
3766 				int dx = Player->ObWorld.vx - x;
3767 				if (dx< -8000 || dx > 8000)
3768 				{
3769 					highDetailRequired = 0;
3770 				}
3771 				else
3772 				{
3773 					int dz = Player->ObWorld.vz - z;
3774 					if (dz< -8000 || dz > 8000)
3775 					{
3776 						highDetailRequired = 0;
3777 					}
3778 				}
3779 			}
3780 			MeshXScale = 7700;
3781 			MeshZScale = 7700;
3782 			{
3783 				extern void CheckForObjectsInWater(int minX, int maxX, int minZ, int maxZ, int averageY);
3784 				CheckForObjectsInWater(x-MeshXScale, x+MeshXScale, z-MeshZScale, z+MeshZScale, y);
3785 			}
3786 
3787 			MeshXScale /=15;
3788 			MeshZScale /=15;
3789 
3790 			// Turn OFF texturing if it is on...
3791 			D3DTEXTUREHANDLE TextureHandle = NULL;
3792 			if (CurrTextureHandle != TextureHandle)
3793 			{
3794 				OP_STATE_RENDER(1, ExecBufInstPtr);
3795 				STATE_DATA(D3DRENDERSTATE_TEXTUREHANDLE, TextureHandle, ExecBufInstPtr);
3796 				CurrTextureHandle = TextureHandle;
3797 			}
3798 			CheckTranslucencyModeIsCorrect(TRANSLUCENCY_NORMAL);
3799 			if (NumVertices)
3800 			{
3801 			   WriteEndCodeToExecuteBuffer();
3802 		  	   UnlockExecuteBufferAndPrepareForUse();
3803 			   ExecuteBuffer();
3804 		  	   LockExecuteBuffer();
3805 			}
3806 			if (highDetailRequired)
3807 			{
3808 				MeshXScale /= 2;
3809 				MeshZScale /= 2;
3810 				D3D_DrawWaterOctagonPatch(x,y,z,0,0);
3811 				D3D_DrawWaterOctagonPatch(x,y,z,15,0);
3812 				D3D_DrawWaterOctagonPatch(x,y,z,0,15);
3813 				D3D_DrawWaterOctagonPatch(x,y,z,15,15);
3814 				MeshXScale = -MeshXScale;
3815 				D3D_DrawWaterOctagonPatch(x,y,z,0,0);
3816 				D3D_DrawWaterOctagonPatch(x,y,z,15,0);
3817 				D3D_DrawWaterOctagonPatch(x,y,z,0,15);
3818 				D3D_DrawWaterOctagonPatch(x,y,z,15,15);
3819 				MeshZScale = -MeshZScale;
3820 				D3D_DrawWaterOctagonPatch(x,y,z,0,0);
3821 				D3D_DrawWaterOctagonPatch(x,y,z,15,0);
3822 				D3D_DrawWaterOctagonPatch(x,y,z,0,15);
3823 				D3D_DrawWaterOctagonPatch(x,y,z,15,15);
3824 				MeshXScale = -MeshXScale;
3825 				D3D_DrawWaterOctagonPatch(x,y,z,0,0);
3826 				D3D_DrawWaterOctagonPatch(x,y,z,15,0);
3827 				D3D_DrawWaterOctagonPatch(x,y,z,0,15);
3828 				D3D_DrawWaterOctagonPatch(x,y,z,15,15);
3829 			}
3830 			else
3831 			{
3832 				D3D_DrawWaterOctagonPatch(x,y,z,0,0);
3833 				MeshXScale = -MeshXScale;
3834 				D3D_DrawWaterOctagonPatch(x,y,z,0,0);
3835 				MeshZScale = -MeshZScale;
3836 				D3D_DrawWaterOctagonPatch(x,y,z,0,0);
3837 				MeshXScale = -MeshXScale;
3838 				D3D_DrawWaterOctagonPatch(x,y,z,0,0);
3839 			}
3840 
3841 		}
3842 	}
3843 #endif
3844 	else if (!stricmp(LevelName,"hangar"))
3845 	{
3846 #if 0 /* not yet */
3847 	   	#if FMV_ON
3848 		#if WIBBLY_FMV_ON
3849 		UpdateFMVTextures(1);
3850 	   	D3D_DrawFMV(FmvPosition.vx,FmvPosition.vy,FmvPosition.vz);
3851 		#endif
3852 		#endif
3853 		#if 0
3854 		{
3855 			VECTORCH v = {49937,-4000,-37709};		// hangar
3856 			D3D_DrawCable(&v);
3857 		}
3858 		#endif
3859 #endif
3860 	}
3861 	else if (!stricmp(LevelName,"invasion_a"))
3862 	{
3863 		char drawWater = 0;
3864 		char drawEndWater = 0;
3865 
3866 		while(numOfObjects)
3867 		{
3868 			DISPLAYBLOCK *objectPtr = OnScreenBlockList[--numOfObjects];
3869 			MODULE *modulePtr = objectPtr->ObMyModule;
3870 
3871 			/* if it's a module, which isn't inside another module */
3872 			if (modulePtr && modulePtr->name)
3873 			{
3874 				if( (!strcmp(modulePtr->name,"hivepool"))
3875 				  ||(!strcmp(modulePtr->name,"hivepool04")))
3876 				{
3877 					drawWater = 1;
3878 					break;
3879 				}
3880 				else
3881 				{
3882 					if(!strcmp(modulePtr->name,"shaftbot"))
3883 					{
3884 						drawEndWater = 1;
3885 					}
3886 					if((!stricmp(modulePtr->name,"shaft01"))
3887 					 ||(!stricmp(modulePtr->name,"shaft02"))
3888 					 ||(!stricmp(modulePtr->name,"shaft03"))
3889 					 ||(!stricmp(modulePtr->name,"shaft04"))
3890 					 ||(!stricmp(modulePtr->name,"shaft05"))
3891 					 ||(!stricmp(modulePtr->name,"shaft06")))
3892 					{
3893 						extern void HandleRainShaft(MODULE *modulePtr, int bottomY, int topY, int numberOfRaindrops);
3894 						HandleRainShaft(modulePtr, -11726,-107080,10);
3895 						drawEndWater = 1;
3896 						break;
3897 					}
3898 				}
3899 			}
3900 
3901 		}
3902 
3903 		if (drawWater)
3904 		{
3905 			int x = 20767;
3906 			int y = -36000+200;
3907 			int z = 30238;
3908 			MeshXScale = (36353-20767);
3909 			MeshZScale = (41927-30238);
3910 			{
3911 				extern void CheckForObjectsInWater(int minX, int maxX, int minZ, int maxZ, int averageY);
3912 				CheckForObjectsInWater(x, x+MeshXScale, z, z+MeshZScale, y);
3913 			}
3914 
3915 			WaterXOrigin=x;
3916 			WaterZOrigin=z;
3917 			WaterUScale = 4.0f/(float)MeshXScale;
3918 			WaterVScale = 4.0f/(float)MeshZScale;
3919 		 	MeshXScale/=4;
3920 		 	MeshZScale/=2;
3921 
3922 			CurrTextureHandle = ImageHeaderArray[ChromeImageNumber].D3DTexture;
3923 			CheckTriangleBuffer(0, 0, CurrTextureHandle, TRANSLUCENCY_NORMAL, -1);
3924 		 	D3D_DrawWaterPatch(x, y, z);
3925 		 	D3D_DrawWaterPatch(x+MeshXScale, y, z);
3926 		 	D3D_DrawWaterPatch(x+MeshXScale*2, y, z);
3927 		 	D3D_DrawWaterPatch(x+MeshXScale*3, y, z);
3928 		 	D3D_DrawWaterPatch(x, y, z+MeshZScale);
3929 		 	D3D_DrawWaterPatch(x+MeshXScale, y, z+MeshZScale);
3930 		 	D3D_DrawWaterPatch(x+MeshXScale*2, y, z+MeshZScale);
3931 		 	D3D_DrawWaterPatch(x+MeshXScale*3, y, z+MeshZScale);
3932 		}
3933 		else if (drawEndWater)
3934 		{
3935 			int x = -15471;
3936 			int y = -11720-500;
3937 			int z = -55875;
3938 			MeshXScale = (15471-1800);
3939 			MeshZScale = (55875-36392);
3940 			{
3941 				extern void CheckForObjectsInWater(int minX, int maxX, int minZ, int maxZ, int averageY);
3942 				CheckForObjectsInWater(x, x+MeshXScale, z, z+MeshZScale, y);
3943 			}
3944 			WaterXOrigin=x;
3945 			WaterZOrigin=z;
3946 			WaterUScale = 4.0f/(float)(MeshXScale+1800-3782);
3947 			WaterVScale = 4.0f/(float)MeshZScale;
3948 		 	MeshXScale/=4;
3949 		 	MeshZScale/=2;
3950 
3951 			CurrTextureHandle = ImageHeaderArray[WaterShaftImageNumber].D3DTexture;
3952 			CheckTriangleBuffer(0, 0, CurrTextureHandle, TRANSLUCENCY_NORMAL, -1);
3953 		 	D3D_DrawWaterPatch(x, y, z);
3954 		 	D3D_DrawWaterPatch(x+MeshXScale, y, z);
3955 		 	D3D_DrawWaterPatch(x+MeshXScale*2, y, z);
3956 		 	D3D_DrawWaterPatch(x+MeshXScale*3, y, z);
3957 		 	D3D_DrawWaterPatch(x, y, z+MeshZScale);
3958 		 	D3D_DrawWaterPatch(x+MeshXScale, y, z+MeshZScale);
3959 		 	D3D_DrawWaterPatch(x+MeshXScale*2, y, z+MeshZScale);
3960 		 	D3D_DrawWaterPatch(x+MeshXScale*3, y, z+MeshZScale);
3961 		}
3962 	}
3963 	else if (!stricmp(LevelName, "derelict"))
3964 	{
3965 		char drawMirrorSurfaces = 0;
3966 		char drawWater = 0;
3967 
3968 		while(numOfObjects)
3969 		{
3970 			DISPLAYBLOCK *objectPtr = OnScreenBlockList[--numOfObjects];
3971 			MODULE *modulePtr = objectPtr->ObMyModule;
3972 
3973 			/* if it's a module, which isn't inside another module */
3974 			if (modulePtr && modulePtr->name)
3975 			{
3976 			  	if( (!stricmp(modulePtr->name,"start-en01"))
3977 			  	  ||(!stricmp(modulePtr->name,"start")))
3978 				{
3979 					drawMirrorSurfaces = 1;
3980 				}
3981 				else if (!stricmp(modulePtr->name,"water-01"))
3982 				{
3983 					extern void HandleRainShaft(MODULE *modulePtr, int bottomY, int topY, int numberOfRaindrops);
3984 					drawWater = 1;
3985 					HandleRainShaft(modulePtr, 32000, 0, 16);
3986 				}
3987 			}
3988 		}
3989 
3990 		if (drawMirrorSurfaces)
3991 		{
3992 			extern void RenderMirrorSurface(void);
3993 			extern void RenderMirrorSurface2(void);
3994 			extern void RenderParticlesInMirror(void);
3995 			RenderParticlesInMirror();
3996 			RenderMirrorSurface();
3997 			RenderMirrorSurface2();
3998 		}
3999 		if (drawWater)
4000 		{
4001 			int x = -102799;
4002 			int y = 32000;
4003 			int z = -200964;
4004 			MeshXScale = (102799-87216);
4005 			MeshZScale = (200964-180986);
4006 			{
4007 				extern void CheckForObjectsInWater(int minX, int maxX, int minZ, int maxZ, int averageY);
4008 				CheckForObjectsInWater(x, x+MeshXScale, z, z+MeshZScale, y);
4009 			}
4010 
4011 			WaterXOrigin=x;
4012 			WaterZOrigin=z;
4013 			WaterUScale = 4.0f/(float)MeshXScale;
4014 			WaterVScale = 4.0f/(float)MeshZScale;
4015 		 	MeshXScale/=2;
4016 		 	MeshZScale/=2;
4017 
4018 			CurrTextureHandle = ImageHeaderArray[ChromeImageNumber].D3DTexture;
4019 			CheckTriangleBuffer(0, 0, CurrTextureHandle, TRANSLUCENCY_NORMAL, -1);
4020 		 	D3D_DrawWaterPatch(x, y, z);
4021 		 	D3D_DrawWaterPatch(x+MeshXScale, y, z);
4022 		 	D3D_DrawWaterPatch(x, y, z+MeshZScale);
4023 		 	D3D_DrawWaterPatch(x+MeshXScale, y, z+MeshZScale);
4024 		}
4025 
4026 	}
4027 	else if (!stricmp(LevelName,"genshd1"))
4028 	{
4029 		while(numOfObjects)
4030 		{
4031 			DISPLAYBLOCK *objectPtr = OnScreenBlockList[--numOfObjects];
4032 			MODULE *modulePtr = objectPtr->ObMyModule;
4033 
4034 			/* if it's a module, which isn't inside another module */
4035 			if (modulePtr && modulePtr->name)
4036 			{
4037 				if( (!stricmp(modulePtr->name,"largespace"))
4038 				  ||(!stricmp(modulePtr->name,"proc13"))
4039 				  ||(!stricmp(modulePtr->name,"trench01"))
4040 				  ||(!stricmp(modulePtr->name,"trench02"))
4041 				  ||(!stricmp(modulePtr->name,"trench03"))
4042 				  ||(!stricmp(modulePtr->name,"trench04"))
4043 				  ||(!stricmp(modulePtr->name,"trench05"))
4044 				  ||(!stricmp(modulePtr->name,"trench06"))
4045 				  ||(!stricmp(modulePtr->name,"trench07"))
4046 				  ||(!stricmp(modulePtr->name,"trench08"))
4047 				  ||(!stricmp(modulePtr->name,"trench09")))
4048 				{
4049 					extern void HandleRain(int numberOfRaindrops);
4050 					HandleRain(999);
4051 					break;
4052 				}
4053 			}
4054 
4055 		}
4056 	}
4057 }
4058 
D3D_DrawWaterTest(MODULE * testModulePtr)4059 void D3D_DrawWaterTest(MODULE *testModulePtr)
4060 {
4061 	extern char LevelName[];
4062 	if (!strcmp(LevelName,"genshd1"))
4063 	{
4064 //		DISPLAYBLOCK *objectPtr = OnScreenBlockList[numOfObjects];
4065 		MODULE *modulePtr = testModulePtr;//objectPtr->ObMyModule;
4066 #if 0
4067 		if (testModulePtr && testModulePtr->name)
4068 		if(!strcmp(testModulePtr->name,"LargeSpace"))
4069 		{
4070 			extern void HandleRain(int numberOfRaindrops);
4071 			HandleRain(999);
4072 		}
4073 #endif
4074 		if (modulePtr && modulePtr->name)
4075 		{
4076 			if (!strcmp(modulePtr->name,"05"))
4077 			{
4078 				int y = modulePtr->m_maxy+modulePtr->m_world.vy-500;
4079 		   		int x = modulePtr->m_minx+modulePtr->m_world.vx;
4080 		   		int z = modulePtr->m_minz+modulePtr->m_world.vz;
4081 				MeshXScale = (7791 - -7794);
4082 				MeshZScale = (23378 - 7793);
4083 				{
4084 					extern void CheckForObjectsInWater(int minX, int maxX, int minZ, int maxZ, int averageY);
4085 					CheckForObjectsInWater(x, x+MeshXScale, z, z+MeshZScale, y);
4086 				}
4087 
4088 				CurrTextureHandle = ImageHeaderArray[WaterShaftImageNumber].D3DTexture;
4089 				CheckBoundTextureIsCorrect(CurrTextureHandle);
4090 				CheckTranslucencyModeIsCorrect(TRANSLUCENCY_NORMAL);
4091 
4092 				WaterXOrigin=x;
4093 				WaterZOrigin=z;
4094 				WaterUScale = 4.0f/(float)(MeshXScale);
4095 				WaterVScale = 4.0f/(float)MeshZScale;
4096 			#if 1
4097 				MeshXScale/=2;
4098 				MeshZScale/=2;
4099 
4100 				CurrTextureHandle = ImageHeaderArray[WaterShaftImageNumber].D3DTexture;
4101 				CheckTriangleBuffer(0, 0, CurrTextureHandle, TRANSLUCENCY_NORMAL, -1);
4102 				D3D_DrawWaterPatch(x, y, z);
4103 				D3D_DrawWaterPatch(x+MeshXScale, y, z);
4104 				D3D_DrawWaterPatch(x, y, z+MeshZScale);
4105 				D3D_DrawWaterPatch(x+MeshXScale, y, z+MeshZScale);
4106 
4107 				{
4108 					extern void HandleRainShaft(MODULE *modulePtr, int bottomY, int topY, int numberOfRaindrops);
4109 					HandleRainShaft(modulePtr, y,-21000,1);
4110 				}
4111 			#else
4112 				MeshXScale/=4;
4113 				MeshZScale/=4;
4114 				D3D_DrawWaterPatch(x, y, z);
4115 				D3D_DrawWaterPatch(x, y, z+MeshZScale);
4116 				D3D_DrawWaterPatch(x, y, z+MeshZScale*2);
4117 				D3D_DrawWaterPatch(x, y, z+MeshZScale*3);
4118 				D3D_DrawWaterPatch(x+MeshXScale, y, z);
4119 				D3D_DrawWaterPatch(x+MeshXScale, y, z+MeshZScale);
4120 				D3D_DrawWaterPatch(x+MeshXScale, y, z+MeshZScale*2);
4121 				D3D_DrawWaterPatch(x+MeshXScale, y, z+MeshZScale*3);
4122 				D3D_DrawWaterPatch(x+MeshXScale*2, y, z);
4123 				D3D_DrawWaterPatch(x+MeshXScale*2, y, z+MeshZScale);
4124 				D3D_DrawWaterPatch(x+MeshXScale*2, y, z+MeshZScale*2);
4125 				D3D_DrawWaterPatch(x+MeshXScale*2, y, z+MeshZScale*3);
4126 				D3D_DrawWaterPatch(x+MeshXScale*3, y, z);
4127 				D3D_DrawWaterPatch(x+MeshXScale*3, y, z+MeshZScale);
4128 				D3D_DrawWaterPatch(x+MeshXScale*3, y, z+MeshZScale*2);
4129 				D3D_DrawWaterPatch(x+MeshXScale*3, y, z+MeshZScale*3);
4130 				HandleRainDrops(modulePtr,2);
4131 			#endif
4132 			}
4133 		}
4134 	}
4135 #if 0
4136 	else if ( (!_stricmp(LevelName,"e3demo")) || (!_stricmp(LevelName,"e3demosp")) )
4137 	{
4138 		if (testModulePtr && testModulePtr->name)
4139 		{
4140 			#if 0
4141 			if(!_stricmp(testModulePtr->name,"watermid"))
4142 			{
4143 				DECAL fmvDecal =
4144 				{
4145 					DECAL_FMV,
4146 					{
4147 					{0,-2500,29000},
4148 					{2000,-2500,29000},
4149 					{2000,-2500+750*2,29000},
4150 					{0,-2500+750*2,29000}
4151 					},
4152 					0
4153 				};
4154 				fmvDecal.ModuleIndex = testModulePtr->m_index;
4155 				fmvDecal.Centre.vx = 0;
4156 				fmvDecal.UOffset = 0;
4157 
4158 				RenderDecal(&fmvDecal);
4159 			}
4160 			#endif
4161 			if(!_stricmp(testModulePtr->name,"lowlowlo03"))
4162 			{
4163 				VECTORCH position = {6894,469,-13203};
4164 				VECTORCH disp = position;
4165 				int i,d;
4166 
4167 				disp.vx -= Player->ObWorld.vx;
4168 				disp.vy -= Player->ObWorld.vy;
4169 				disp.vz -= Player->ObWorld.vz;
4170 				d = ONE_FIXED - Approximate3dMagnitude(&disp)*2;
4171 				if (d<0) d = 0;
4172 
4173 				i = MUL_FIXED(10,d);
4174 				while(i--)
4175 				{
4176 					VECTORCH velocity;
4177 					velocity.vx = ((FastRandom()&1023) - 512);
4178 					velocity.vy = ((FastRandom()&1023) - 512)+2000;
4179 					velocity.vz = (1000+(FastRandom()&255))*2;
4180 					MakeParticle(&(position),&(velocity),PARTICLE_STEAM);
4181 				}
4182 			}
4183 		}
4184 	}
4185 #endif
4186 }
4187 
4188 
4189 VECTORCH MeshVertex[256];
4190 #define TEXTURE_WATER 0
4191 
4192 VECTORCH MeshWorldVertex[256];
4193 unsigned int MeshVertexColour[256];
4194 unsigned int MeshVertexSpecular[256];
4195 char MeshVertexOutcode[256];
4196 
D3D_DrawWaterPatch(int xOrigin,int yOrigin,int zOrigin)4197 void D3D_DrawWaterPatch(int xOrigin, int yOrigin, int zOrigin)
4198 {
4199 	int i=0;
4200 	int x;
4201 	int offset;
4202 
4203 	for (x=0; x<16; x++)
4204 	{
4205 		int z;
4206 		for(z=0; z<16; z++)
4207 		{
4208 			VECTORCH *point = &MeshVertex[i];
4209 
4210 			point->vx = xOrigin+(x*MeshXScale)/15;
4211 			point->vz = zOrigin+(z*MeshZScale)/15;
4212 
4213 
4214 			offset=0;
4215 
4216 		 #if 1
4217 			/* basic noise ripples */
4218 //		 	offset = MUL_FIXED(32,GetSin(  (point->vx+point->vz+CloakingPhase)&4095 ) );
4219 //		 	offset += MUL_FIXED(16,GetSin(  (point->vx-point->vz*2+CloakingPhase/2)&4095 ) );
4220 
4221 			{
4222  				offset += EffectOfRipples(point);
4223 			}
4224 		#endif
4225 	//		if (offset>450) offset = 450;
4226 	//		if (offset<-450) offset = -450;
4227 			point->vy = yOrigin+offset;
4228 
4229 			#if 0
4230 			MeshVertexColour[i] = LightSourceWaterPoint(point,offset);
4231 			#else
4232 			{
4233 				int alpha = 128-offset/4;
4234 		//		if (alpha>255) alpha = 255;
4235 		//		if (alpha<128) alpha = 128;
4236 				switch (CurrentVisionMode)
4237 				{
4238 					default:
4239 					case VISION_MODE_NORMAL:
4240 					{
4241 //						MeshVertexColour[i] = RGBALIGHT_MAKE(10,51,28,alpha);
4242 						MeshVertexColour[i] = RGBA_MAKE(255,255,255,alpha);
4243 						#if 0
4244 						#if 1
4245 						VECTORCH pos = {24087,yOrigin,39165};
4246 						int c = (8191-VectorDistance(&pos,point));
4247 						if (c<0) c=0;
4248 						else
4249 						{
4250 							int s = GetSin((CloakingPhase/2)&4095);
4251 							s = MUL_FIXED(s,s)/64;
4252 							c = MUL_FIXED(s,c);
4253 						}
4254 						MeshVertexSpecular[i] = (c<<16)+(((c/4)<<8)&0xff00) + (c/4);
4255 						#else
4256 						if (!(FastRandom()&1023))
4257 						{
4258 							MeshVertexSpecular[i] = 0xc04040;
4259 						}
4260 						else
4261 						{
4262 							MeshVertexSpecular[i] = 0;
4263 						}
4264 						#endif
4265 						#endif
4266 						break;
4267 					}
4268 					case VISION_MODE_IMAGEINTENSIFIER:
4269 					{
4270 						MeshVertexColour[i] = RGBA_MAKE(0,51,0,alpha);
4271 						break;
4272 					}
4273 					case VISION_MODE_PRED_THERMAL:
4274 					case VISION_MODE_PRED_SEEALIENS:
4275 					case VISION_MODE_PRED_SEEPREDTECH:
4276 					{
4277 						MeshVertexColour[i] = RGBA_MAKE(0,0,28,alpha);
4278 					  	break;
4279 					}
4280 				}
4281 
4282 			}
4283 			#endif
4284 
4285 			#if 1
4286 			MeshWorldVertex[i].vx = ((point->vx-WaterXOrigin)/4+MUL_FIXED(GetSin((point->vy*16)&4095),128));
4287 			MeshWorldVertex[i].vy = ((point->vz-WaterZOrigin)/4+MUL_FIXED(GetSin((point->vy*16+200)&4095),128));
4288 			#endif
4289 
4290 			#if 1
4291 			TranslatePointIntoViewspace(point);
4292 			#else
4293 			point->vx -= Global_VDB_Ptr->VDB_World.vx;
4294 			point->vy -= Global_VDB_Ptr->VDB_World.vy;
4295 			point->vz -= Global_VDB_Ptr->VDB_World.vz;
4296 			RotateVector(point,&(Global_VDB_Ptr->VDB_Mat));
4297 			point->vy = MUL_FIXED(point->vy,87381);
4298 
4299 			#endif
4300 			/* is particle within normal view frustrum ? */
4301 			if(AvP.PlayerType==I_Alien)	/* wide frustrum */
4302 			{
4303 				if(( (-point->vx <= point->vz*2)
4304 		   			&&(point->vx <= point->vz*2)
4305 					&&(-point->vy <= point->vz*2)
4306 					&&(point->vy <= point->vz*2) ))
4307 				{
4308 					MeshVertexOutcode[i]=1;
4309 				}
4310 				else
4311 				{
4312 					MeshVertexOutcode[i]=0;
4313 				}
4314 			}
4315 			else
4316 			{
4317 				if(( (-point->vx <= point->vz)
4318 		   			&&(point->vx <= point->vz)
4319 					&&(-point->vy <= point->vz)
4320 					&&(point->vy <= point->vz) ))
4321 				{
4322 					MeshVertexOutcode[i]=1;
4323 				}
4324 				else
4325 				{
4326 					MeshVertexOutcode[i]=0;
4327 				}
4328 			}
4329 
4330 			i++;
4331 		}
4332 	}
4333 
4334 	if ((MeshVertexOutcode[0]&&MeshVertexOutcode[15]&&MeshVertexOutcode[240]&&MeshVertexOutcode[255]))
4335 	{
4336 		D3D_DrawMoltenMetalMesh_Unclipped();
4337 //		D3D_DrawWaterMesh_Unclipped();
4338 	} else {
4339 		D3D_DrawMoltenMetalMesh_Clipped();
4340 //		D3D_DrawWaterMesh_Clipped();
4341 	}
4342 
4343 
4344 }
4345 
4346 #if 0
4347 
4348 void D3D_DrawWaterMesh_Unclipped(void)
4349 {
4350 	float ZNear = (float) (Global_VDB_Ptr->VDB_ClipZ * GlobalScale);
4351 
4352 	/* OUTPUT VERTICES TO EXECUTE BUFFER */
4353 	{
4354 		D3DTLVERTEX *vertexPtr = &((LPD3DTLVERTEX)ExecuteBufferDataArea)[NumVertices];
4355 		VECTORCH *point = MeshVertex;
4356 		#if TEXTURE_WATER
4357 		VECTORCH *pointWS = MeshWorldVertex;
4358 		#endif
4359 		int i;
4360 		for (i=0; i<256; i++)
4361 		{
4362 
4363 			if (point->vz<=1) point->vz = 1;
4364 			int x = (point->vx*(Global_VDB_Ptr->VDB_ProjX))/point->vz+Global_VDB_Ptr->VDB_CentreX;
4365 			int y = (point->vy*(Global_VDB_Ptr->VDB_ProjY))/point->vz+Global_VDB_Ptr->VDB_CentreY;
4366   //			textprint("%d, %d\n",x,y);
4367 			#if 1
4368 			{
4369 				if (x<Global_VDB_Ptr->VDB_ClipLeft)
4370 				{
4371 					x=Global_VDB_Ptr->VDB_ClipLeft;
4372 				}
4373 				else if (x>Global_VDB_Ptr->VDB_ClipRight)
4374 				{
4375 					x=Global_VDB_Ptr->VDB_ClipRight;
4376 				}
4377 
4378 				vertexPtr->sx=x;
4379 			}
4380 			{
4381 				if (y<Global_VDB_Ptr->VDB_ClipUp)
4382 				{
4383 					y=Global_VDB_Ptr->VDB_ClipUp;
4384 				}
4385 				else if (y>Global_VDB_Ptr->VDB_ClipDown)
4386 				{
4387 					y=Global_VDB_Ptr->VDB_ClipDown;
4388 				}
4389 				vertexPtr->sy=y;
4390 			}
4391 			#else
4392 			vertexPtr->sx=x;
4393 			vertexPtr->sy=y;
4394 			#endif
4395 			#if FOG_ON
4396 			{
4397 				int fog = (point->vz)/FOG_SCALE;
4398 				if (fog<0) fog=0;
4399 			 	if (fog>254) fog=254;
4400 				fog=255-fog;
4401 			   	vertexPtr->specular=RGBALIGHT_MAKE(0,0,0,fog);
4402 			}
4403 			#endif
4404 			point->vz+=HeadUpDisplayZOffset;
4405 		  	float oneOverZ = ((float)(point->vz)-ZNear)/(float)(point->vz);
4406 		  //vertexPtr->color = RGBALIGHT_MAKE(66,70,0,127+(FastRandom()&63));
4407 			vertexPtr->color = MeshVertexColour[i];
4408 			vertexPtr->sz = oneOverZ;
4409 			#if TEXTURE_WATER
4410 			vertexPtr->tu = pointWS->vx/128.0;
4411 			vertexPtr->tv =	pointWS->vz/128.0;
4412 			#endif
4413 
4414 
4415 			NumVertices++;
4416 			vertexPtr++;
4417 			point++;
4418 			#if TEXTURE_WATER
4419 			pointWS++;
4420 			#endif
4421 		}
4422 	}
4423  //	textprint("numvertices %d\n",NumVertices);
4424 
4425 
4426     /*
4427      * Make sure that the triangle data (not OP) will be QWORD aligned
4428      */
4429 	if (QWORD_ALIGNED(ExecBufInstPtr))
4430     {
4431         OP_NOP(ExecBufInstPtr);
4432     }
4433 
4434   	OP_TRIANGLE_LIST(450, ExecBufInstPtr);
4435 	/* CONSTRUCT POLYS */
4436 	{
4437 		int x;
4438 		for (x=0; x<15; x++)
4439 		{
4440 			int y;
4441 			for(y=0; y<15; y++)
4442 			{
4443 				OUTPUT_TRIANGLE(0+x+(16*y),1+x+(16*y),16+x+(16*y), 256);
4444 				OUTPUT_TRIANGLE(1+x+(16*y),17+x+(16*y),16+x+(16*y), 256);
4445 			}
4446 		}
4447 	}
4448 	#if 1
4449 	{
4450 	   WriteEndCodeToExecuteBuffer();
4451   	   UnlockExecuteBufferAndPrepareForUse();
4452 	   ExecuteBuffer();
4453   	   LockExecuteBuffer();
4454 	}
4455 	#endif
4456 }
4457 void D3D_DrawWaterMesh_Clipped(void)
4458 {
4459 	float ZNear = (float) (Global_VDB_Ptr->VDB_ClipZ * GlobalScale);
4460 
4461 	/* OUTPUT VERTICES TO EXECUTE BUFFER */
4462 	{
4463 		D3DTLVERTEX *vertexPtr = &((LPD3DTLVERTEX)ExecuteBufferDataArea)[NumVertices];
4464 		VECTORCH *point = MeshVertex;
4465 		#if TEXTURE_WATER
4466 		VECTORCH *pointWS = MeshWorldVertex;
4467 		#endif
4468 		int i;
4469 		for (i=0; i<256; i++)
4470 		{
4471 			{
4472 				if (point->vz<=1) point->vz = 1;
4473 				int x = (point->vx*(Global_VDB_Ptr->VDB_ProjX))/point->vz+Global_VDB_Ptr->VDB_CentreX;
4474 				int y = (point->vy*(Global_VDB_Ptr->VDB_ProjY))/point->vz+Global_VDB_Ptr->VDB_CentreY;
4475 				#if 1
4476 				{
4477 					if (x<Global_VDB_Ptr->VDB_ClipLeft)
4478 					{
4479 						x=Global_VDB_Ptr->VDB_ClipLeft;
4480 					}
4481 					else if (x>Global_VDB_Ptr->VDB_ClipRight)
4482 					{
4483 						x=Global_VDB_Ptr->VDB_ClipRight;
4484 					}
4485 
4486 					vertexPtr->sx=x;
4487 				}
4488 				{
4489 					if (y<Global_VDB_Ptr->VDB_ClipUp)
4490 					{
4491 						y=Global_VDB_Ptr->VDB_ClipUp;
4492 					}
4493 					else if (y>Global_VDB_Ptr->VDB_ClipDown)
4494 					{
4495 						y=Global_VDB_Ptr->VDB_ClipDown;
4496 					}
4497 					vertexPtr->sy=y;
4498 				}
4499 				#else
4500 				vertexPtr->sx=x;
4501 				vertexPtr->sy=y;
4502 				#endif
4503 				#if FOG_ON
4504 				{
4505 					int fog = ((point->vz)/FOG_SCALE);
4506 					if (fog<0) fog=0;
4507 				 	if (fog>254) fog=254;
4508 					fog=255-fog;
4509 				   	vertexPtr->specular=RGBALIGHT_MAKE(0,0,0,fog);
4510 				}
4511 				#endif
4512 				#if TEXTURE_WATER
4513 				vertexPtr->tu = pointWS->vx/128.0;
4514 				vertexPtr->tv =	pointWS->vz/128.0;
4515 				#endif
4516 				point->vz+=HeadUpDisplayZOffset;
4517 			  	float oneOverZ = ((float)(point->vz)-ZNear)/(float)(point->vz);
4518 			  //	vertexPtr->color = RGBALIGHT_MAKE(66,70,0,127+(FastRandom()&63));
4519 				vertexPtr->color = MeshVertexColour[i];
4520 				vertexPtr->sz = oneOverZ;
4521 			}
4522 			NumVertices++;
4523 			vertexPtr++;
4524 			point++;
4525 			#if TEXTURE_WATER
4526 			pointWS++;
4527 			#endif
4528 		}
4529 	}
4530 //	textprint("numvertices %d\n",NumVertices);
4531 	/* CONSTRUCT POLYS */
4532 	{
4533 		int x;
4534 		for (x=0; x<15; x++)
4535 		{
4536 			int y;
4537 			for(y=0; y<15; y++)
4538 			{
4539 				#if 1
4540 				int p1 = 0+x+(16*y);
4541 				int p2 = 1+x+(16*y);
4542 				int p3 = 16+x+(16*y);
4543 				int p4 = 17+x+(16*y);
4544 
4545 				if (MeshVertexOutcode[p1]||MeshVertexOutcode[p2]||MeshVertexOutcode[p3])
4546 				{
4547 					OP_TRIANGLE_LIST(1, ExecBufInstPtr);
4548 					OUTPUT_TRIANGLE(p1,p2,p3, 256);
4549 				}
4550 				if (MeshVertexOutcode[p2]||MeshVertexOutcode[p3]||MeshVertexOutcode[p4])
4551 				{
4552 					OP_TRIANGLE_LIST(1, ExecBufInstPtr);
4553 					OUTPUT_TRIANGLE(p2,p4,p3, 256);
4554 				}
4555 				#else
4556 				int p2 = 1+x+(16*y);
4557 				int p3 = 16+x+(16*y);
4558 
4559 				if (MeshVertexOutcode[p2]&&MeshVertexOutcode[p3])
4560 				{
4561 					int p1 = 0+x+(16*y);
4562 					int p4 = 17+x+(16*y);
4563 					if (MeshVertexOutcode[p1])
4564 					{
4565 						OP_TRIANGLE_LIST(1, ExecBufInstPtr);
4566 						OUTPUT_TRIANGLE(p1,p2,p3, 256);
4567 					}
4568 					if (MeshVertexOutcode[p4])
4569 					{
4570 						OP_TRIANGLE_LIST(1, ExecBufInstPtr);
4571 						OUTPUT_TRIANGLE(p2,p4,p3, 256);
4572 					}
4573 				}
4574 				#endif
4575 			}
4576 		}
4577 	}
4578 	#if 1
4579 	{
4580 	   WriteEndCodeToExecuteBuffer();
4581   	   UnlockExecuteBufferAndPrepareForUse();
4582 	   ExecuteBuffer();
4583   	   LockExecuteBuffer();
4584 	}
4585 	#endif
4586 }
4587 
4588 #endif
4589 
4590 signed int ForceFieldPointDisplacement[15*3+1][16];
4591 signed int ForceFieldPointDisplacement2[15*3+1][16];
4592 signed int ForceFieldPointVelocity[15*3+1][16];
4593 unsigned char ForceFieldPointColour1[15*3+1][16];
4594 unsigned char ForceFieldPointColour2[15*3+1][16];
4595 
4596 int Phase=0;
4597 int ForceFieldPhase=0;
InitForceField(void)4598 void InitForceField(void)
4599 {
4600 	int x, y;
4601 
4602 	for (x=0; x<15*3+1; x++)
4603 		for (y=0; y<16; y++)
4604 		{
4605 			ForceFieldPointDisplacement[x][y]=0;
4606 			ForceFieldPointDisplacement2[x][y]=0;
4607 			ForceFieldPointVelocity[x][y]=0;
4608 		}
4609 	ForceFieldPhase=0;
4610 }
4611 
4612 #if 0 /* not used */
4613 
4614 #if 1
4615 
4616 extern int NormalFrameTime;
4617 
4618 void UpdateForceField(void)
4619 {
4620 	#if 1
4621 	int x, y;
4622 
4623 	Phase+=NormalFrameTime>>6;
4624 	ForceFieldPhase+=NormalFrameTime>>5;
4625 	for (x=1; x<15*3; x++)
4626 	{
4627 		for (y=1; y<15; y++)
4628 		{
4629 
4630 			int acceleration =32*(-8*ForceFieldPointDisplacement[x][y]
4631 								+ForceFieldPointDisplacement[x-1][y-1]
4632 								+ForceFieldPointDisplacement[x-1][y]
4633 								+ForceFieldPointDisplacement[x-1][y+1]
4634 								+ForceFieldPointDisplacement[x][y-1]
4635 								+ForceFieldPointDisplacement[x][y+1]
4636 #if 0
4637 								)
4638 #else
4639 
4640 								+ForceFieldPointDisplacement[x+1][y-1]
4641 								+ForceFieldPointDisplacement[x+1][y]
4642 								+ForceFieldPointDisplacement[x+1][y+1])
4643 #endif
4644 								-(ForceFieldPointVelocity[x][y]*5);
4645 
4646 			ForceFieldPointVelocity[x][y] += MUL_FIXED(acceleration,NormalFrameTime);
4647 			ForceFieldPointDisplacement2[x][y] += MUL_FIXED(ForceFieldPointVelocity[x][y],NormalFrameTime);
4648 #if 1
4649 			if(ForceFieldPointDisplacement2[x][y]>200) ForceFieldPointDisplacement2[x][y]=200;
4650 			if(ForceFieldPointDisplacement2[x][y]<-200) ForceFieldPointDisplacement2[x][y]=-200;
4651 #else
4652 			if(ForceFieldPointDisplacement2[x][y]>512) ForceFieldPointDisplacement2[x][y]=512;
4653 			if(ForceFieldPointDisplacement2[x][y]<-512) ForceFieldPointDisplacement2[x][y]=-512;
4654 
4655 #endif
4656 			{
4657 				int offset = ForceFieldPointDisplacement2[x][y];
4658 				int colour = ForceFieldPointVelocity[x][y]/4;
4659 
4660 				if (offset<0) offset =-offset;
4661 				if (colour<0) colour =-colour;
4662 				colour=(colour+offset)/2;
4663 
4664 				if(colour>255) colour=255;
4665 				colour++;
4666 
4667 				ForceFieldPointColour1[x][y]=FastRandom()%colour;
4668 				ForceFieldPointColour2[x][y]=FastRandom()%colour;
4669 			}
4670 		}
4671 
4672 	}
4673 	for (x=1; x<15*3; x++)
4674 	{
4675 		int y;
4676 		for (y=1; y<15; y++)
4677 		{
4678 			ForceFieldPointDisplacement[x][y] = ForceFieldPointDisplacement2[x][y];
4679 		}
4680 	}
4681 	{
4682 		#if 1
4683 	  	if(ForceFieldPhase>1000)
4684 		{
4685 			ForceFieldPhase=0;
4686 			x = 1+(FastRandom()%(15*3-2));
4687 			y = 1+(FastRandom()%13);
4688 			ForceFieldPointVelocity[x][y] = 10000;
4689 			ForceFieldPointVelocity[x][y+1] = 10000;
4690 			ForceFieldPointVelocity[x+1][y] = 10000;
4691 			ForceFieldPointVelocity[x+1][y+1] = 10000;
4692 		}
4693 		#else
4694 	   //	if(ForceFieldPhase>1000)
4695 		{
4696 			ForceFieldPhase=0;
4697 			x = 1+(FastRandom()%(15*3-2));
4698 			y = 1+(FastRandom()%13);
4699 			ForceFieldPointVelocity[x][y] = (FastRandom()&16383)+8192;
4700 		}
4701 		#endif
4702 	}
4703 	#else
4704 	int x;
4705 	int y;
4706 	for (y=0; y<=15; y++)
4707 	{
4708 		ForceFieldPointDisplacement[0][y] += (FastRandom()&127)-64;
4709 		if(ForceFieldPointDisplacement[0][y]>512) ForceFieldPointDisplacement[0][y]=512;
4710 		if(ForceFieldPointDisplacement[0][y]<-512) ForceFieldPointDisplacement[0][y]=-512;
4711 		ForceFieldPointVelocity[0][y] = (FastRandom()&16383)-8192;
4712 	}
4713 	for (x=15*3-1; x>0; x--)
4714 	{
4715 		for (y=0; y<=15; y++)
4716 		{
4717 			ForceFieldPointDisplacement[x][y] = ForceFieldPointDisplacement[x-1][y];
4718 			ForceFieldPointVelocity[x][y] = ForceFieldPointVelocity[x-1][y];
4719 		}
4720 
4721 	}
4722 	for (x=15*3-1; x>1; x--)
4723 	{
4724 		y = FastRandom()&15;
4725 	 	ForceFieldPointDisplacement[x][y] = ForceFieldPointDisplacement[x-1][y];
4726 		y = (FastRandom()&15)-1;
4727 	 	ForceFieldPointDisplacement[x][y] = ForceFieldPointDisplacement[x-1][y];
4728 	}
4729 	#endif
4730 }
4731 void UpdateWaterFall(void)
4732 {
4733 	int x;
4734 	int y;
4735 	for (y=0; y<=15; y++)
4736 	{
4737 		ForceFieldPointDisplacement[0][y] += (FastRandom()&127)-64;
4738 		if(ForceFieldPointDisplacement[0][y]>512) ForceFieldPointDisplacement[0][y]=512;
4739 		if(ForceFieldPointDisplacement[0][y]<-512) ForceFieldPointDisplacement[0][y]=-512;
4740 		ForceFieldPointVelocity[0][y] = (FastRandom()&16383)-8192;
4741 	}
4742 	for (x=15*3-1; x>0; x--)
4743 	{
4744 		for (y=0; y<=15; y++)
4745 		{
4746 			ForceFieldPointDisplacement[x][y] = ForceFieldPointDisplacement[x-1][y];
4747 			ForceFieldPointVelocity[x][y] = ForceFieldPointVelocity[x-1][y];
4748 		}
4749 
4750 	}
4751 	for (x=15*3-1; x>1; x--)
4752 	{
4753 		y = FastRandom()&15;
4754 	 	ForceFieldPointDisplacement[x][y] = ForceFieldPointDisplacement[x-1][y];
4755 		y = (FastRandom()&15)-1;
4756 	 	ForceFieldPointDisplacement[x][y] = ForceFieldPointDisplacement[x-1][y];
4757 	}
4758 }
4759 
4760 #endif
4761 #endif /* not used */
4762 
4763 #if 0 /* not yet */
4764 
4765 void D3D_DrawForceField(int xOrigin, int yOrigin, int zOrigin, int fieldType)
4766 {
4767 	MeshXScale = 4096/16;
4768 	MeshZScale = 4096/16;
4769 
4770 	for (int field=0; field<3; field++)
4771 	{
4772 	int i=0;
4773 	int x;
4774 	for (x=(0+field*15); x<(16+field*15); x++)
4775 	{
4776 		int z;
4777 		for(z=0; z<16; z++)
4778 		{
4779 			VECTORCH *point = &MeshVertex[i];
4780 			int offset = ForceFieldPointDisplacement[x][z];
4781 
4782 			switch(fieldType)
4783 			{
4784 				case 0:
4785 				{
4786 				 	point->vx = xOrigin+(x*MeshXScale);
4787 				 	point->vy = yOrigin+(z*MeshZScale);
4788 				 	point->vz = zOrigin+offset;
4789 					break;
4790 				}
4791 				case 1:
4792 				{
4793 
4794 					int theta = (z*4095)/15;
4795 					int u = (x*65536)/45;
4796 
4797 					int b = MUL_FIXED(2*u,(65536-u));
4798 					int c = MUL_FIXED(u,u);
4799 					int phi = (Phase&4095);
4800 					int x3 = (GetSin(phi))/64;
4801 					int y3 = 5000-(GetCos((phi*3+1000)&4095)/128);
4802 					int z3 = (GetSin((3*phi+1324)&4095))/32;
4803 					int x2 = -x3/2;
4804 					int y2 = 3000;
4805 					int z2 = -z3/4;
4806 					int innerRadius = 100;//GetSin(u/32)/16+offset;
4807 
4808 					point->vx = xOrigin+(b*x2+c*x3)/65536+MUL_FIXED(innerRadius,GetSin(theta));
4809 					point->vy = yOrigin-5000+(b*y2+c*y3)/65536;
4810 					point->vz = zOrigin+(b*z2+c*z3)/65536+MUL_FIXED(innerRadius,GetCos(theta));
4811 					break;
4812 				}
4813 				case 2:
4814 				{
4815 					int theta = (z*4095)/15;
4816 					int phi = (x*4095)/45;
4817 					int innerRadius = 1000+offset;
4818 					int outerRadius = 4000;
4819 
4820 
4821 					point->vx = xOrigin+MUL_FIXED(outerRadius-MUL_FIXED(innerRadius,GetSin(theta)),GetCos(phi));
4822 					point->vy = yOrigin+MUL_FIXED(innerRadius,GetCos(theta));
4823 					point->vz = zOrigin+MUL_FIXED(outerRadius-MUL_FIXED(innerRadius,GetSin(theta)),GetSin(phi));
4824 					break;
4825 				}
4826 				case 3:
4827 				{
4828 
4829 					int theta = (x*4095)/45;
4830 					int radius = offset+2000;
4831 					point->vx = xOrigin+MUL_FIXED(radius,GetCos(theta));
4832 					point->vy = yOrigin+(z*MeshZScale);
4833 					point->vz = zOrigin+MUL_FIXED(radius,GetSin(theta));
4834 					break;
4835 				}
4836 			}
4837 
4838 			if (offset<0) offset =-offset;
4839 			offset+=16;
4840 
4841 //			offset-=32;
4842 //			if (offset<0) offset = 0;
4843 
4844 			if(offset>255) offset=255;
4845 
4846 			MeshVertexColour[i] = RGBALIGHT_MAKE(ForceFieldPointColour1[x][z],ForceFieldPointColour2[x][z],255,offset);
4847 			#if TEXTURE_WATER
4848 			MeshWorldVertex[i].vx = point->vx;
4849 			MeshWorldVertex[i].vz = point->vz;
4850 			#endif
4851 
4852 			TranslatePointIntoViewspace(point);
4853 
4854 			/* is particle within normal view frustrum ? */
4855 			if(AvP.PlayerType==I_Alien)	/* wide frustrum */
4856 			{
4857 				if(( (-point->vx <= point->vz*2)
4858 		   			&&(point->vx <= point->vz*2)
4859 					&&(-point->vy <= point->vz*2)
4860 					&&(point->vy <= point->vz*2) ))
4861 				{
4862 					MeshVertexOutcode[i]=1;
4863 				}
4864 				else
4865 				{
4866 					MeshVertexOutcode[i]=0;
4867 				}
4868 			}
4869 			else
4870 			{
4871 				if(( (-point->vx <= point->vz)
4872 		   			&&(point->vx <= point->vz)
4873 					&&(-point->vy <= point->vz)
4874 					&&(point->vy <= point->vz) ))
4875 				{
4876 					MeshVertexOutcode[i]=1;
4877 				}
4878 				else
4879 				{
4880 					MeshVertexOutcode[i]=0;
4881 				}
4882 			}
4883 
4884 			i++;
4885 		}
4886 	}
4887 	//textprint("\n");
4888 	if ((MeshVertexOutcode[0]&&MeshVertexOutcode[15]&&MeshVertexOutcode[240]&&MeshVertexOutcode[255]))
4889 	{
4890 		D3D_DrawWaterMesh_Unclipped();
4891 	}
4892 	else
4893 //	else if (MeshVertexOutcode[0]||MeshVertexOutcode[15]||MeshVertexOutcode[240]||MeshVertexOutcode[255])
4894 	{
4895 		D3D_DrawWaterMesh_Clipped();
4896 	}
4897 	}
4898 }
4899 
4900 
4901 void D3D_DrawPowerFence(int xOrigin, int yOrigin, int zOrigin, int xScale, int yScale, int zScale)
4902 {
4903 	for (int field=0; field<3; field++)
4904 	{
4905 	int i=0;
4906 	int x;
4907 	for (x=(0+field*15); x<(16+field*15); x++)
4908 	{
4909 		int z;
4910 		for(z=0; z<16; z++)
4911 		{
4912 			VECTORCH *point = &MeshVertex[i];
4913 			int offset = ForceFieldPointDisplacement[x][z];
4914 
4915 		 	point->vx = xOrigin+(x*xScale);
4916 		 	point->vy = yOrigin+(z*yScale);
4917 		 	point->vz = zOrigin+(x*zScale);
4918 
4919 			if (offset<0) offset =-offset;
4920 			offset+=16;
4921 
4922 			if(offset>255) offset=255;
4923 
4924 			MeshVertexColour[i] = RGBALIGHT_MAKE(ForceFieldPointColour1[x][z],ForceFieldPointColour2[x][z],255,offset);
4925 
4926 			/* translate particle into view space */
4927 			TranslatePointIntoViewspace(point);
4928 
4929 			/* is particle within normal view frustrum ? */
4930 			if(AvP.PlayerType==I_Alien)	/* wide frustrum */
4931 			{
4932 				if(( (-point->vx <= point->vz*2)
4933 		   			&&(point->vx <= point->vz*2)
4934 					&&(-point->vy <= point->vz*2)
4935 					&&(point->vy <= point->vz*2) ))
4936 				{
4937 					MeshVertexOutcode[i]=1;
4938 				}
4939 				else
4940 				{
4941 					MeshVertexOutcode[i]=0;
4942 				}
4943 			}
4944 			else
4945 			{
4946 				if(( (-point->vx <= point->vz)
4947 		   			&&(point->vx <= point->vz)
4948 					&&(-point->vy <= point->vz)
4949 					&&(point->vy <= point->vz) ))
4950 				{
4951 					MeshVertexOutcode[i]=1;
4952 				}
4953 				else
4954 				{
4955 					MeshVertexOutcode[i]=0;
4956 				}
4957 			}
4958 
4959 			i++;
4960 		}
4961 	}
4962 	//textprint("\n");
4963 	if ((MeshVertexOutcode[0]&&MeshVertexOutcode[15]&&MeshVertexOutcode[240]&&MeshVertexOutcode[255]))
4964 	{
4965 		D3D_DrawWaterMesh_Unclipped();
4966 	}
4967 	else
4968 //	else if (MeshVertexOutcode[0]||MeshVertexOutcode[15]||MeshVertexOutcode[240]||MeshVertexOutcode[255])
4969 	{
4970 		D3D_DrawWaterMesh_Clipped();
4971 	}
4972 	}
4973 }
4974 
4975 #endif /* not yet */
4976 
D3D_DrawWaterFall(int xOrigin,int yOrigin,int zOrigin)4977 void D3D_DrawWaterFall(int xOrigin, int yOrigin, int zOrigin)
4978 {
4979 	int i;
4980 	int noRequired = MUL_FIXED(250,NormalFrameTime);
4981 	for (i=0; i<noRequired; i++)
4982 	{
4983 		VECTORCH velocity;
4984 		VECTORCH position;
4985 		position.vx = xOrigin;
4986 		position.vy = yOrigin-(FastRandom()&511);//+45*MeshXScale;
4987 		position.vz = zOrigin+(FastRandom()%(15*MeshZScale));
4988 
4989 		velocity.vy = (FastRandom()&511)+512;//-((FastRandom()&1023)+2048)*8;
4990 		velocity.vx = ((FastRandom()&511)+256)*2;
4991 		velocity.vz = 0;//-((FastRandom()&511))*8;
4992 		MakeParticle(&(position), &velocity, PARTICLE_WATERFALLSPRAY);
4993 	}
4994 
4995 #if 0 /* not used */
4996 		#if 0
4997 		noRequired = MUL_FIXED(200,NormalFrameTime);
4998 		for (i=0; i<noRequired; i++)
4999 		{
5000 			VECTORCH velocity;
5001 			VECTORCH position;
5002 			position.vx = xOrigin+(FastRandom()%(15*MeshZScale));
5003 			position.vy = yOrigin+45*MeshXScale;
5004 			position.vz = zOrigin;
5005 
5006 			velocity.vy = -((FastRandom()&16383)+4096);
5007 			velocity.vx = ((FastRandom()&4095)-2048);
5008 			velocity.vz = -((FastRandom()&2047)+1048);
5009 			MakeParticle(&(position), &velocity, PARTICLE_WATERFALLSPRAY);
5010 		}
5011 		#endif
5012 	{
5013 		extern void RenderWaterFall(int xOrigin, int yOrigin, int zOrigin);
5014 		//RenderWaterFall(xOrigin, yOrigin-500, zOrigin+50);
5015 	}
5016    	return;
5017 	for (int field=0; field<3; field++)
5018 	{
5019 	int i=0;
5020 	int x;
5021 	for (x=(0+field*15); x<(16+field*15); x++)
5022 	{
5023 		int z;
5024 		for(z=0; z<16; z++)
5025 		{
5026 			VECTORCH *point = &MeshVertex[i];
5027 			int offset = ForceFieldPointDisplacement[x][z];
5028 
5029 		#if 1
5030 			int u = (x*65536)/45;
5031 
5032 			int b = MUL_FIXED(2*u,(65536-u));
5033 			int c = MUL_FIXED(u,u);
5034 			int y3 = 45*MeshXScale;
5035 			int x3 = 5000;
5036 			int y2 = 1*MeshXScale;
5037 			int x2 = GetSin(CloakingPhase&4095)+GetCos((CloakingPhase*3+399)&4095);
5038 			x2 = MUL_FIXED(x2,x2)/128;
5039 
5040 			if (offset<0) offset =-offset;
5041 			point->vx = xOrigin+MUL_FIXED(b,x2)+MUL_FIXED(c,x3)+offset;
5042 			point->vy = yOrigin+MUL_FIXED(b,y2)+MUL_FIXED(c,y3);
5043 			point->vz = zOrigin+(z*MeshZScale);
5044 
5045 			if (point->vy>4742)
5046 			{
5047 				if (z<=4)
5048 				{
5049 					point->vy-=MeshXScale;
5050 					if (point->vy<4742) point->vy=4742;
5051 					if (point->vx<179427) point->vx=179427;
5052 				}
5053 				else if (z<=8)
5054 				{
5055 					point->vx+=(8-z)*1000;
5056 				}
5057 			}
5058 
5059 			#else
5060 			if (offset<0) offset =-offset;
5061 		 	point->vx = xOrigin-offset;
5062 		 	point->vy = yOrigin+(x*MeshXScale);
5063 		 	point->vz = zOrigin+(z*MeshZScale);
5064 			#endif
5065 
5066 
5067 
5068 
5069 			offset= (offset/4)+127;
5070 
5071 //			offset-=32;
5072 //			if (offset<0) offset = 0;
5073 
5074 			if(offset>255) offset=255;
5075 
5076 			MeshVertexColour[i] = RGBALIGHT_MAKE(offset,offset,255,offset/2);
5077 			#if TEXTURE_WATER
5078 			MeshWorldVertex[i].vx = point->vx;
5079 			MeshWorldVertex[i].vz = point->vz;
5080 			#endif
5081 
5082 			/* translate particle into view space */
5083 			TranslatePointIntoViewspace(point);
5084 
5085 			/* is particle within normal view frustrum ? */
5086 			if(AvP.PlayerType==I_Alien)	/* wide frustrum */
5087 			{
5088 				if(( (-point->vx <= point->vz*2)
5089 		   			&&(point->vx <= point->vz*2)
5090 					&&(-point->vy <= point->vz*2)
5091 					&&(point->vy <= point->vz*2) ))
5092 				{
5093 					MeshVertexOutcode[i]=1;
5094 				}
5095 				else
5096 				{
5097 					MeshVertexOutcode[i]=0;
5098 				}
5099 			}
5100 			else
5101 			{
5102 				if(( (-point->vx <= point->vz)
5103 		   			&&(point->vx <= point->vz)
5104 					&&(-point->vy <= point->vz)
5105 					&&(point->vy <= point->vz) ))
5106 				{
5107 					MeshVertexOutcode[i]=1;
5108 				}
5109 				else
5110 				{
5111 					MeshVertexOutcode[i]=0;
5112 				}
5113 			}
5114 
5115 			i++;
5116 		}
5117 	}
5118 	//textprint("\n");
5119 	if ((MeshVertexOutcode[0]&&MeshVertexOutcode[15]&&MeshVertexOutcode[240]&&MeshVertexOutcode[255]))
5120 	{
5121 		D3D_DrawWaterMesh_Unclipped();
5122 	}
5123 	else
5124 //	else if (MeshVertexOutcode[0]||MeshVertexOutcode[15]||MeshVertexOutcode[240]||MeshVertexOutcode[255])
5125 	{
5126 		D3D_DrawWaterMesh_Clipped();
5127 	}
5128 	}
5129 #endif
5130 }
5131 
5132 #if 0 /* not yet */
5133 
5134 void D3D_DrawMoltenMetal(int xOrigin, int yOrigin, int zOrigin)
5135 {
5136 	int i=0;
5137 	int x;
5138 	for (x=0; x<16; x++)
5139 	{
5140 		int z;
5141 		for(z=0; z<16; z++)
5142 		{
5143 			VECTORCH *point = &MeshVertex[i];
5144 
5145 			point->vx = xOrigin+(x*MeshXScale)/15;
5146 			point->vz = zOrigin+(z*MeshZScale)/15;
5147 		 #if 0
5148 
5149 			int offset=0;
5150 
5151 		 	offset = MUL_FIXED(32,GetSin(  (point->vx+point->vz+CloakingPhase)&4095 ) );
5152 		 	offset += MUL_FIXED(16,GetSin(  (point->vx-point->vz*2+CloakingPhase/2)&4095 ) );
5153 			{
5154 				float dx=point->vx-22704;
5155 				float dz=point->vz+20652;
5156 				float a = dx*dx+dz*dz;
5157 				a=sqrt(a);
5158 
5159 				offset+= MUL_FIXED(200,GetSin( (((int)a-CloakingPhase)&4095)  ));
5160 			}
5161 		#endif
5162 		 #if 1
5163 			int offset=0;
5164 
5165 			/* basic noise ripples */
5166 		 	offset = MUL_FIXED(128,GetSin(  ((point->vx+point->vz)/16+CloakingPhase)&4095 ) );
5167 		 	offset += MUL_FIXED(64,GetSin(  ((point->vx-point->vz*2)/4+CloakingPhase/2)&4095 ) );
5168 		 	offset += MUL_FIXED(64,GetSin(  ((point->vx*5-point->vz)/32+CloakingPhase/5)&4095 ) );
5169 
5170 		#endif
5171 			if (offset>450) offset = 450;
5172 			if (offset<-1000) offset = -1000;
5173 			point->vy = yOrigin+offset;
5174 
5175 			{
5176 				int shade = 191+(offset+256)/8;
5177 				MeshVertexColour[i] = RGBLIGHT_MAKE(shade,shade,shade);
5178 			}
5179 
5180 			#if 1
5181 			TranslatePointIntoViewspace(point);
5182 			#else
5183 			point->vx -= Global_VDB_Ptr->VDB_World.vx;
5184 			point->vy -= Global_VDB_Ptr->VDB_World.vy;
5185 			point->vz -= Global_VDB_Ptr->VDB_World.vz;
5186 			MeshWorldVertex[i] = *point;
5187 			RotateVector(point,&(Global_VDB_Ptr->VDB_Mat));
5188 			point->vy = MUL_FIXED(point->vy,87381);
5189 
5190 			#endif
5191 			/* is particle within normal view frustrum ? */
5192 			if(AvP.PlayerType==I_Alien)	/* wide frustrum */
5193 			{
5194 				if(( (-point->vx <= point->vz*2)
5195 		   			&&(point->vx <= point->vz*2)
5196 					&&(-point->vy <= point->vz*2)
5197 					&&(point->vy <= point->vz*2) ))
5198 				{
5199 					MeshVertexOutcode[i]=1;
5200 				}
5201 				else
5202 				{
5203 					MeshVertexOutcode[i]=0;
5204 				}
5205 			}
5206 			else
5207 			{
5208 				if(( (-point->vx <= point->vz)
5209 		   			&&(point->vx <= point->vz)
5210 					&&(-point->vy <= point->vz)
5211 					&&(point->vy <= point->vz) ))
5212 				{
5213 					MeshVertexOutcode[i]=1;
5214 				}
5215 				else
5216 				{
5217 					MeshVertexOutcode[i]=0;
5218 				}
5219 			}
5220 
5221 			#if 0
5222 			{
5223 				// v
5224 				MeshWorldVertex[i].vy = (offset+256)*4;
5225 				// u
5226 				MeshWorldVertex[i].vx = ((MeshWorldVertex[i].vx)&4095);
5227 
5228 			}
5229 			#else
5230 			{
5231 				Normalise(&MeshWorldVertex[i]);
5232 				// v
5233 				int theta = (MeshWorldVertex[i].vy+offset);
5234 				if (theta<0) theta=0;
5235 				if (theta>ONE_FIXED) theta=ONE_FIXED;
5236 
5237 				// u
5238 				int arctan = ((atan2((double)MeshWorldVertex[i].vx,(double)MeshWorldVertex[i].vz)/ 6.28318530718))*4095;
5239 				MeshWorldVertex[i].vx = (arctan+offset)&4095;
5240 
5241 				MeshWorldVertex[i].vy = ArcCos(theta);
5242 
5243 			}
5244 			#endif
5245 
5246 
5247 			i++;
5248 		}
5249 	}
5250 
5251 	D3DTEXTUREHANDLE TextureHandle = (D3DTEXTUREHANDLE)ImageHeaderArray[StaticImageNumber].D3DHandle;
5252 	if (CurrTextureHandle != TextureHandle)
5253 	{
5254 		OP_STATE_RENDER(1, ExecBufInstPtr);
5255 		STATE_DATA(D3DRENDERSTATE_TEXTUREHANDLE, TextureHandle, ExecBufInstPtr);
5256 		CurrTextureHandle = TextureHandle;
5257 	}
5258 	CheckTranslucencyModeIsCorrect(TRANSLUCENCY_OFF);
5259 	if (NumVertices)
5260 	{
5261 	   WriteEndCodeToExecuteBuffer();
5262   	   UnlockExecuteBufferAndPrepareForUse();
5263 	   ExecuteBuffer();
5264   	   LockExecuteBuffer();
5265 	}
5266 	if ((MeshVertexOutcode[0]&&MeshVertexOutcode[15]&&MeshVertexOutcode[240]&&MeshVertexOutcode[255]))
5267 	{
5268 		D3D_DrawMoltenMetalMesh_Unclipped();
5269 	}
5270 	else
5271 //	else if (MeshVertexOutcode[0]||MeshVertexOutcode[15]||MeshVertexOutcode[240]||MeshVertexOutcode[255])
5272 	{
5273 		D3D_DrawMoltenMetalMesh_Clipped();
5274 	}
5275 
5276 
5277 }
5278 
5279 #endif /* not yet */
5280 
D3D_DrawMoltenMetalMesh_Unclipped(void)5281 void D3D_DrawMoltenMetalMesh_Unclipped(void)
5282 {
5283 	float ZNear = (float) (Global_VDB_Ptr->VDB_ClipZ * GlobalScale);
5284 
5285 	VECTORCH *point = MeshVertex;
5286 	VECTORCH *pointWS = MeshWorldVertex;
5287 
5288 	int i, x, y, z;
5289 	int start;
5290 
5291 	CheckTriangleBuffer(256, 450, (D3DTexture *)-1, -1, -1);
5292 	SelectProgram(AVP_SHADER_PROGRAM_NO_SECONDARY);
5293 
5294 	start = varrc;
5295 	for (i=0; i<256; i++) {
5296 		GLfloat xf, yf, zf;
5297 		GLfloat sf, tf;
5298 		GLfloat w;
5299 		int r, g, b, a;
5300 
5301 		if (point->vz < 1) point->vz = 1;
5302 
5303 		xf =  ((float)point->vx*((float)Global_VDB_Ptr->VDB_ProjX+1.0f))/((float)point->vz*(float)ScreenDescriptorBlock.SDB_CentreX);
5304 		yf = -((float)point->vy*((float)Global_VDB_Ptr->VDB_ProjY+1.0f))/((float)point->vz*(float)ScreenDescriptorBlock.SDB_CentreY);
5305 
5306 		z = point->vz + HeadUpDisplayZOffset;
5307 		w = (float)point->vz;
5308 		zf = 1.0f - 2.0f*ZNear/(float)z;
5309 
5310 		sf = pointWS->vx*WaterUScale+(1.0f/256.0f);
5311 		tf = pointWS->vy*WaterVScale+(1.0f/256.0f);
5312 
5313 		b = (MeshVertexColour[i] >> 0)  & 0xFF;
5314 		g = (MeshVertexColour[i] >> 8)  & 0xFF;
5315 		r = (MeshVertexColour[i] >> 16) & 0xFF;
5316 		a = (MeshVertexColour[i] >> 24) & 0xFF;
5317 
5318 
5319 		varrp->v[0] = xf*w;
5320 		varrp->v[1] = yf*w;
5321 		varrp->v[2] = zf*w;
5322 		varrp->v[3] = w;
5323 
5324 		varrp->t[0] = sf;
5325 		varrp->t[1] = tf;
5326 
5327 		varrp->c[0] = r;
5328 		varrp->c[1] = g;
5329 		varrp->c[2] = b;
5330 		varrp->c[3] = a;
5331 
5332 		varrp->s[0] = 0;
5333 		varrp->s[1] = 0;
5334 		varrp->s[2] = 0;
5335 		varrp->s[3] = 0;
5336 
5337 		varrp++;
5338 		varrc++;
5339 
5340 		point++;
5341 		pointWS++;
5342 	}
5343 
5344 	/* CONSTRUCT POLYS */
5345 
5346 	for (x = 0; x < 15; x++) {
5347 		for(y = 0; y < 15; y++) {
5348 //			OUTPUT_TRIANGLE(0+x+(16*y),1+x+(16*y),16+x+(16*y), 256);
5349 //			OUTPUT_TRIANGLE(1+x+(16*y),17+x+(16*y),16+x+(16*y), 256);
5350 
5351 			tarrp[0].a = start+0+x+(16*y);
5352 			tarrp[0].b = start+1+x+(16*y);
5353 			tarrp[0].c = start+16+x+(16*y);
5354 
5355 			tarrp[1].a = start+1+x+(16*y);
5356 			tarrp[1].b = start+17+x+(16*y);
5357 			tarrp[1].c = start+16+x+(16*y);
5358 
5359 			tarrp += 2;
5360 			tarrc += 2;
5361 		}
5362 	}
5363 }
5364 
D3D_DrawMoltenMetalMesh_Clipped(void)5365 void D3D_DrawMoltenMetalMesh_Clipped(void)
5366 {
5367 	D3D_DrawMoltenMetalMesh_Unclipped();
5368 	return;
5369 #if 0
5370 	int i, x, y, z, c, start;
5371 
5372 	float ZNear = (float) (Global_VDB_Ptr->VDB_ClipZ * GlobalScale);
5373 
5374 	VECTORCH *point = MeshVertex;
5375 	VECTORCH *pointWS = MeshWorldVertex;
5376 
5377 	/* how many triangles drawn the first time, (450-c the second time) */
5378 	c = 0;
5379 	for (x=0; x<15; x++) {
5380 		for(y=0; y<15; y++) {
5381 			int p1 = 0+x+(16*y);
5382 			int p2 = 1+x+(16*y);
5383 			int p3 = 16+x+(16*y);
5384 			int p4 = 17+x+(16*y);
5385 
5386 			if (MeshVertexOutcode[p1]&&MeshVertexOutcode[p2]&&MeshVertexOutcode[p3]&&MeshVertexOutcode[p4])
5387 				c += 2;
5388 		}
5389 	}
5390 
5391 	CheckTriangleBuffer(256, c, (D3DTexture *)-1, -1, -1);
5392 	SelectProgram(AVP_SHADER_PROGRAM_NO_SECONDARY);
5393 	start = varrc;
5394 
5395 		for (i=0; i<256; i++)
5396 		{
5397 			GLfloat xf, yf, zf;
5398 			GLfloat sf, tf;
5399 			GLfloat w;
5400 			int r, g, b, a;
5401 
5402 			if (point->vz < 1) point->vz = 1;
5403 
5404 			x = (point->vx*(Global_VDB_Ptr->VDB_ProjX+1))/point->vz+Global_VDB_Ptr->VDB_CentreX;
5405 			y = (point->vy*(Global_VDB_Ptr->VDB_ProjY+1))/point->vz+Global_VDB_Ptr->VDB_CentreY;
5406 
5407 			if (x<Global_VDB_Ptr->VDB_ClipLeft) {
5408 				x=Global_VDB_Ptr->VDB_ClipLeft;
5409 			} else if (x>Global_VDB_Ptr->VDB_ClipRight) {
5410 				x=Global_VDB_Ptr->VDB_ClipRight;
5411 			}
5412 
5413 			if (y<Global_VDB_Ptr->VDB_ClipUp) {
5414 				y=Global_VDB_Ptr->VDB_ClipUp;
5415 			} else if (y>Global_VDB_Ptr->VDB_ClipDown) {
5416 				y=Global_VDB_Ptr->VDB_ClipDown;
5417 			}
5418 
5419 			sf = pointWS->vx*WaterUScale+(1.0f/256.0f);
5420 			tf = pointWS->vy*WaterVScale+(1.0f/256.0f);
5421 
5422 			z = point->vz + HeadUpDisplayZOffset;
5423 		  	w = (float)point->vz;
5424 
5425 			b = (MeshVertexColour[i] >> 0)  & 0xFF;
5426 			g = (MeshVertexColour[i] >> 8)  & 0xFF;
5427 			r = (MeshVertexColour[i] >> 16) & 0xFF;
5428 			a = (MeshVertexColour[i] >> 24) & 0xFF;
5429 
5430 			xf =  ((float)x - (float)ScreenDescriptorBlock.SDB_CentreX - 0.5f) / ((float)ScreenDescriptorBlock.SDB_CentreX - 0.5f);
5431 			yf = -((float)y - (float)ScreenDescriptorBlock.SDB_CentreY - 0.5f) / ((float)ScreenDescriptorBlock.SDB_CentreY - 0.5f);
5432 			zf = 1.0f - 2.0f*ZNear/(float)z;
5433 
5434 			varrp->v[0] = xf*w;
5435 			varrp->v[1] = yf*w;
5436 			varrp->v[2] = zf*w;
5437 			varrp->v[3] = w;
5438 
5439 			varrp->t[0] = sf;
5440 			varrp->t[1] = tf;
5441 
5442 			varrp->c[0] = r;
5443 			varrp->c[1] = g;
5444 			varrp->c[2] = b;
5445 			varrp->c[3] = a;
5446 
5447 			varrp->s[0] = 0;
5448 			varrp->s[1] = 0;
5449 			varrp->s[2] = 0;
5450 			varrp->s[3] = 0;
5451 
5452 			varrp++;
5453 			varrc++;
5454 
5455 			point++;
5456 			pointWS++;
5457 		}
5458 
5459 	/* CONSTRUCT POLYS */
5460 	{
5461 		for (x=0; x<15; x++)
5462 		{
5463 			for(y=0; y<15; y++)
5464 			{
5465 				int p1 = 0+x+(16*y);
5466 				int p2 = 1+x+(16*y);
5467 				int p3 = 16+x+(16*y);
5468 				int p4 = 17+x+(16*y);
5469 
5470 #if 0
5471 				#if 0
5472 				if (MeshVertexOutcode[p1]&&MeshVertexOutcode[p2]&&MeshVertexOutcode[p3])
5473 				{
5474 					OP_TRIANGLE_LIST(1, ExecBufInstPtr);
5475 					OUTPUT_TRIANGLE(p1,p2,p3, 256);
5476 				}
5477 				if (MeshVertexOutcode[p2]&&MeshVertexOutcode[p3]&&MeshVertexOutcode[p4])
5478 				{
5479 					OP_TRIANGLE_LIST(1, ExecBufInstPtr);
5480 					OUTPUT_TRIANGLE(p2,p4,p3, 256);
5481 				}
5482 				#else
5483 				if (MeshVertexOutcode[p1]&&MeshVertexOutcode[p2]&&MeshVertexOutcode[p3]&&MeshVertexOutcode[p4])
5484 				{
5485 					OP_TRIANGLE_LIST(2, ExecBufInstPtr);
5486 					OUTPUT_TRIANGLE(p1,p2,p3, 256);
5487 					OUTPUT_TRIANGLE(p2,p4,p3, 256);
5488 				}
5489 
5490 				#endif
5491 #endif
5492 				if (MeshVertexOutcode[p1]&&MeshVertexOutcode[p2]&&MeshVertexOutcode[p3]&&MeshVertexOutcode[p4]) {
5493 					tarrp[0].a = start+p1;
5494 					tarrp[0].b = start+p2;
5495 					tarrp[0].c = start+p3;
5496 					tarrp[1].a = start+p2;
5497 					tarrp[1].b = start+p4;
5498 					tarrp[1].c = start+p3;
5499 
5500 					tarrp += 2;
5501 					tarrc += 2;
5502 				}
5503 			}
5504 		}
5505 	}
5506 	{
5507 		POLYHEADER fakeHeader;
5508 
5509 		fakeHeader.PolyFlags = 0;
5510 		fakeHeader.PolyColour = 0;
5511 		RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL;
5512 
5513 		for (x=0; x<15; x++)
5514 		{
5515 			for(y=0; y<15; y++)
5516 			{
5517 				int p[4];
5518 				p[0] = 0+x+(16*y);
5519 				p[1] = 1+x+(16*y);
5520 				p[2] = 17+x+(16*y);
5521 				p[3] = 16+x+(16*y);
5522 
5523 				if (!(MeshVertexOutcode[p[0]]&&MeshVertexOutcode[p[1]]&&MeshVertexOutcode[p[2]]&&MeshVertexOutcode[p[3]]))
5524 				{
5525 					for (i=0; i<4; i++)
5526 					{
5527 						VerticesBuffer[i].X	= MeshVertex[p[i]].vx;
5528 						VerticesBuffer[i].Y	= MeshVertex[p[i]].vy;
5529 						VerticesBuffer[i].Z	= MeshVertex[p[i]].vz;
5530 						VerticesBuffer[i].U = MeshWorldVertex[p[i]].vx*(WaterUScale*128.0f*65536.0f);
5531 						VerticesBuffer[i].V = MeshWorldVertex[p[i]].vy*(WaterVScale*128.0f*65536.0f);
5532 
5533 						VerticesBuffer[i].A = (MeshVertexColour[p[i]]&0xff000000)>>24;
5534 						VerticesBuffer[i].R = (MeshVertexColour[p[i]]&0x00ff0000)>>16;
5535 						VerticesBuffer[i].G	= (MeshVertexColour[p[i]]&0x0000ff00)>>8;
5536 						VerticesBuffer[i].B = MeshVertexColour[p[i]]&0x000000ff;
5537 						VerticesBuffer[i].SpecularR = 0;
5538 						VerticesBuffer[i].SpecularG = 0;
5539 						VerticesBuffer[i].SpecularB = 0;
5540 						RenderPolygon.NumberOfVertices=4;
5541 
5542 					}
5543 					if (QuadWithinFrustrum())
5544 					{
5545 						GouraudTexturedPolygon_ClipWithZ();
5546 						if(RenderPolygon.NumberOfVertices<3) continue;
5547 						GouraudTexturedPolygon_ClipWithNegativeX();
5548 						if(RenderPolygon.NumberOfVertices<3) continue;
5549 						GouraudTexturedPolygon_ClipWithPositiveY();
5550 						if(RenderPolygon.NumberOfVertices<3) continue;
5551 						GouraudTexturedPolygon_ClipWithNegativeY();
5552 						if(RenderPolygon.NumberOfVertices<3) continue;
5553 						GouraudTexturedPolygon_ClipWithPositiveX();
5554 						if(RenderPolygon.NumberOfVertices<3) continue;
5555 
5556 						/* draw polygon */
5557 					}
5558 				}
5559 			}
5560 		}
5561 	}
5562 #endif
5563 }
5564 
5565 #if 0 /* not yet */
5566 
5567 void D3D_DrawWaterOctagonPatch(int xOrigin, int yOrigin, int zOrigin, int xOffset, int zOffset)
5568 {
5569 	float grad = 2.414213562373;
5570 	int i=0;
5571 	int x;
5572 	for (x=xOffset; x<16+xOffset; x++)
5573 	{
5574 		int z;
5575 		for(z=zOffset; z<16+zOffset; z++)
5576 		{
5577 			VECTORCH *point = &MeshVertex[i];
5578 
5579 		  	if (x>z)
5580 			{
5581 				float m,xs;
5582 				if (x!=0)
5583 				{
5584 					m = (float)(z)/(float)(x);
5585 					xs = grad/(grad+m);
5586 				}
5587 				else
5588 				{
5589 					xs = 0;
5590 				}
5591 				#if 1
5592 				f2i(point->vx , xs*x*MeshXScale);
5593 				f2i(point->vz , (grad-grad*xs)*x*MeshZScale);
5594 				#else
5595 				point->vx = xs*x*MeshXScale;
5596 				point->vz = (grad-grad*xs)*x*MeshZScale;
5597 				#endif
5598 			}
5599 			else
5600 			{
5601 				float m,xs;
5602 				if (z!=0)
5603 				{
5604 					m = (float)(x)/(float)(z);
5605 					xs = grad/(grad+m);
5606 				}
5607 				else
5608 				{
5609 					xs = 0;
5610 				}
5611 				#if 1
5612 				f2i(point->vz ,	xs*z*MeshZScale);
5613 				f2i(point->vx ,	(grad-grad*xs)*z*MeshXScale);
5614 				#else
5615 				point->vz =	xs*z*MeshZScale;
5616 				point->vx =	(grad-grad*xs)*z*MeshXScale;
5617 				#endif
5618 			}
5619 
5620 			point->vx += xOrigin;
5621 			point->vz += zOrigin;
5622 
5623 			int offset = EffectOfRipples(point);
5624 
5625 			point->vy = yOrigin+offset;
5626 
5627 			#if 0
5628 			MeshVertexColour[i] = LightSourceWaterPoint(point,offset);
5629 			#else
5630 			{
5631 				int alpha = 128-offset/4;
5632 		//		if (alpha>255) alpha = 255;
5633 		//		if (alpha<128) alpha = 128;
5634 				switch (CurrentVisionMode)
5635 				{
5636 					default:
5637 					case VISION_MODE_NORMAL:
5638 					{
5639 						MeshVertexColour[i] = RGBALIGHT_MAKE(10,51,28,alpha);
5640 						break;
5641 					}
5642 					case VISION_MODE_IMAGEINTENSIFIER:
5643 					{
5644 						MeshVertexColour[i] = RGBALIGHT_MAKE(0,51,0,alpha);
5645 						break;
5646 					}
5647 					case VISION_MODE_PRED_THERMAL:
5648 					case VISION_MODE_PRED_SEEALIENS:
5649 					case VISION_MODE_PRED_SEEPREDTECH:
5650 					{
5651 						MeshVertexColour[i] = RGBALIGHT_MAKE(0,0,28,alpha);
5652 					  	break;
5653 					}
5654 				}
5655 
5656 			}
5657 			#endif
5658 			TranslatePointIntoViewspace(point);
5659 			/* is particle within normal view frustrum ? */
5660 			if(AvP.PlayerType==I_Alien)	/* wide frustrum */
5661 			{
5662 				if(( (-point->vx <= point->vz*2)
5663 		   			&&(point->vx <= point->vz*2)
5664 					&&(-point->vy <= point->vz*2)
5665 					&&(point->vy <= point->vz*2) ))
5666 				{
5667 					MeshVertexOutcode[i]=1;
5668 				}
5669 				else
5670 				{
5671 					MeshVertexOutcode[i]=0;
5672 				}
5673 			}
5674 			else
5675 			{
5676 				if(( (-point->vx <= point->vz)
5677 		   			&&(point->vx <= point->vz)
5678 					&&(-point->vy <= point->vz)
5679 					&&(point->vy <= point->vz) ))
5680 				{
5681 					MeshVertexOutcode[i]=1;
5682 				}
5683 				else
5684 				{
5685 					MeshVertexOutcode[i]=0;
5686 				}
5687 			}
5688 
5689 			i++;
5690 		}
5691 	}
5692 
5693 	if ((MeshVertexOutcode[0]&&MeshVertexOutcode[15]&&MeshVertexOutcode[240]&&MeshVertexOutcode[255]))
5694 	{
5695 		D3D_DrawWaterMesh_Unclipped();
5696 	}
5697 	else
5698 //	else if (MeshVertexOutcode[0]||MeshVertexOutcode[15]||MeshVertexOutcode[240]||MeshVertexOutcode[255])
5699 	{
5700 		D3D_DrawWaterMesh_Clipped();
5701 	}
5702 
5703 
5704 }
5705 
5706 #endif /* not yet */
5707 
D3D_DrawCable(VECTORCH * centrePtr,MATRIXCH * orientationPtr)5708 void D3D_DrawCable(VECTORCH *centrePtr, MATRIXCH *orientationPtr)
5709 {
5710 	int field;
5711 
5712 	CurrTextureHandle = NULL;
5713 	CheckBoundTextureIsCorrect(NULL);
5714 	CheckTranslucencyModeIsCorrect(TRANSLUCENCY_GLOWING);
5715 	pglDepthMask(GL_FALSE);
5716 
5717 	MeshXScale = 4096/16;
5718 	MeshZScale = 4096/16;
5719 
5720 	for (field=0; field<3; field++)
5721 	{
5722 	int i=0;
5723 	int x;
5724 	for (x=(0+field*15); x<(16+field*15); x++)
5725 	{
5726 		int z;
5727 		for(z=0; z<16; z++)
5728 		{
5729 			VECTORCH *point = &MeshVertex[i];
5730 			{
5731 				int innerRadius = 20;
5732 				VECTORCH radius;
5733 				int theta = ((4096*z)/15)&4095;
5734 				int rOffset = GetSin((x*64+theta/32-CloakingPhase)&4095);
5735 				rOffset = MUL_FIXED(rOffset,rOffset)/512;
5736 
5737 
5738 				radius.vx = MUL_FIXED(innerRadius+rOffset/8,GetSin(theta));
5739 				radius.vy = MUL_FIXED(innerRadius+rOffset/8,GetCos(theta));
5740 				radius.vz = 0;
5741 
5742 				RotateVector(&radius,orientationPtr);
5743 
5744 				point->vx = centrePtr[x].vx+radius.vx;
5745 				point->vy = centrePtr[x].vy+radius.vy;
5746 				point->vz = centrePtr[x].vz+radius.vz;
5747 
5748 				MeshVertexColour[i] = RGBA_MAKE(0,rOffset,255,128);
5749 
5750 			}
5751 
5752 			TranslatePointIntoViewspace(point);
5753 
5754 			/* is particle within normal view frustrum ? */
5755 			if(AvP.PlayerType==I_Alien)	/* wide frustrum */
5756 			{
5757 				if(( (-point->vx <= point->vz*2)
5758 		   			&&(point->vx <= point->vz*2)
5759 					&&(-point->vy <= point->vz*2)
5760 					&&(point->vy <= point->vz*2) ))
5761 				{
5762 					MeshVertexOutcode[i]=1;
5763 				}
5764 				else
5765 				{
5766 					MeshVertexOutcode[i]=0;
5767 				}
5768 			}
5769 			else
5770 			{
5771 				if(( (-point->vx <= point->vz)
5772 		   			&&(point->vx <= point->vz)
5773 					&&(-point->vy <= point->vz)
5774 					&&(point->vy <= point->vz) ))
5775 				{
5776 					MeshVertexOutcode[i]=1;
5777 				}
5778 				else
5779 				{
5780 					MeshVertexOutcode[i]=0;
5781 				}
5782 			}
5783 
5784 			i++;
5785 		}
5786 	}
5787 	//textprint("\n");
5788    	if ((MeshVertexOutcode[0]&&MeshVertexOutcode[15]&&MeshVertexOutcode[240]&&MeshVertexOutcode[255]))
5789 	{
5790 		D3D_DrawMoltenMetalMesh_Unclipped();
5791 	   //	D3D_DrawWaterMesh_Unclipped();
5792 	}
5793 	else
5794 //	else if (MeshVertexOutcode[0]||MeshVertexOutcode[15]||MeshVertexOutcode[240]||MeshVertexOutcode[255])
5795 	{
5796 		D3D_DrawMoltenMetalMesh_Clipped();
5797   	   //	D3D_DrawWaterMesh_Clipped();
5798 	}
5799 	}
5800 
5801 	pglDepthMask(GL_TRUE);
5802 }
5803