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