4b825dc642cb6eb9a060e54bf8d69288fbee490494a6641b73026d662261604d7d192beae70b11dc
 
 
1
#include "system.h"
 
 
2
#include "prototyp.h"
 
 
3
#include "stratdef.h"
 
 
4
#include "lighting.h"
 
 
5
#include "bh_types.h"
 
 
6
#include "hud.h"
 
 
7
#include "userprofile.h"
 
 
8
#include "kshape.h"
 
 
9
#include "menus.h"
 
 
10
#include <SDL/SDL_opengl.h>
 
 
11
 
 
 
12
const int VDB_ClipZ = 64;
 
 
13
#define ClrTxDefn 0x0000ffff    /* AND with this to clear the high 16-bits */
 
 
14
extern void HandleRainShaft(MODULE *modulePtr, int bottomY, int topY, int numberOfRaindrops);
 
 
15
extern int got_any_key();
 
 
16
 
 
 
17
extern unsigned char GammaValues[256];
 
 
18
extern SCREENDESCRIPTORBLOCK ScreenDescriptorBlock;
 
 
19
extern DISPLAYBLOCK *ActiveBlockList[];
 
 
20
extern int HUDScaleFactor;
 
 
21
extern int CloakingPhase;
 
 
22
extern int NumActiveBlocks;
 
 
23
extern int ChromeImageNumber;
 
 
24
extern int WaterShaftImageNumber;
 
 
25
 
 
 
26
static int StaticImageNumber;
 
 
27
int SpecialFXImageNumber;
 
 
28
int CloudyImageNumber;
 
 
29
int HUDImageNumber;
 
 
30
int AlienTongueImageNumber;
 
 
31
int PredatorNumbersImageNumber;
 
 
32
int BurningImageNumber;
 
 
33
int HUDFontsImageNumber;
 
 
34
 
 
 
35
int WaterFallBase;
 
 
36
static int MeshXScale;
 
 
37
static int MeshZScale;
 
 
38
static int WaterXOrigin;
 
 
39
static int WaterZOrigin;
 
 
40
static float WaterUScale;
 
 
41
static float WaterVScale;
 
 
42
 
 
 
43
#define MaxImages 200
 
 
44
 
 
 
45
enum FILTERING_MODE_ID
 
 
46
{
 
 
47
        FILTERING_BILINEAR_OFF,
 
 
48
        FILTERING_BILINEAR_ON,
 
 
49
        FILTERING_NOT_SET
 
 
50
 
 
 
51
} CurrentFilteringMode = FILTERING_BILINEAR_OFF;
 
 
52
 
 
 
53
struct TEXTURE
 
 
54
{
 
 
55
    uint8_t *buf;
 
 
56
    GLuint id;
 
 
57
    uint32_t w;
 
 
58
    uint32_t h;
 
 
59
    enum FILTERING_MODE_ID filter;
 
 
60
 
 
 
61
} *CurrTextureHandle, *CurrentlyBoundTexture;
 
 
62
 
 
 
63
struct
 
 
64
{
 
 
65
    struct TEXTURE  *Texture;
 
 
66
    char * ImageName;
 
 
67
 
 
 
68
} ImageHeaderArray[MaxImages];
 
 
69
 
 
 
70
static int AAFontImageNumber;
 
 
71
char AAFontWidths[256];
 
 
72
 
 
 
73
int NumImages = -1;
 
 
74
 
 
 
75
enum TRANSLUCENCY_TYPE CurrentTranslucencyMode = TRANSLUCENCY_OFF;
 
 
76
 
 
 
77
#define TA_MAXVERTICES        2048
 
 
78
#define TA_MAXTRIANGLES        2048
 
 
79
 
 
 
80
struct VertexArray
 
 
81
{
 
 
82
    GLfloat v[4];
 
 
83
    GLfloat t[3]; /* 3rd float is padding */
 
 
84
    GLubyte c[4];
 
 
85
 
 
 
86
} *varrp, *svarrp;
 
 
87
 
 
 
88
struct TriangleArray
 
 
89
{
 
 
90
    int a;
 
 
91
    int b;
 
 
92
    int c;
 
 
93
 
 
 
94
} *tarrp, *starrp;
 
 
95
 
 
 
96
struct VertexArray varr[TA_MAXVERTICES * 2];
 
 
97
 
 
 
98
struct TriangleArray tarr[TA_MAXTRIANGLES * 2];
 
 
99
struct TriangleArray *starr = &tarr[TA_MAXTRIANGLES];
 
 
100
 
 
 
101
int varrc, tarrc, svarrc, starrc;
 
 
102
 
 
 
103
VECTORCH MeshVertex[256];
 
 
104
VECTORCH MeshWorldVertex[256];
 
 
105
unsigned int MeshVertexColour[256];
 
 
106
unsigned int MeshVertexSpecular[256];
 
 
107
char MeshVertexOutcode[256];
 
 
108
 
 
 
109
/* Do not call this directly! */
 
 
110
static void SetTranslucencyMode(enum TRANSLUCENCY_TYPE mode)
 
 
111
{        
 
 
112
    switch(mode) 
 
 
113
    {
 
 
114
        case TRANSLUCENCY_OFF:
 
 
115
            switch(UserProfile.active_bonus)
 
 
116
            {
 
 
117
                case CHEATMODE_NONACTIVE:
 
 
118
                default:
 
 
119
                    glBlendFunc(GL_ONE, GL_ZERO);
 
 
120
                break;
 
 
121
                case CHEATMODE_TRIPTASTIC:
 
 
122
                case CHEATMODE_MOTIONBLUR: 
 
 
123
                    glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA);
 
 
124
            }
 
 
125
        break;
 
 
126
        case TRANSLUCENCY_NORMAL:
 
 
127
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
 
128
        break;
 
 
129
        case TRANSLUCENCY_COLOUR:
 
 
130
            glBlendFunc(GL_ZERO, GL_SRC_COLOR);
 
 
131
        break;
 
 
132
        case TRANSLUCENCY_INVCOLOUR:
 
 
133
            glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
 
 
134
        break;
 
 
135
        case TRANSLUCENCY_GLOWING:
 
 
136
            glBlendFunc(GL_SRC_ALPHA, GL_ONE);
 
 
137
        break;
 
 
138
        case TRANSLUCENCY_DARKENINGCOLOUR:
 
 
139
            glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO);
 
 
140
        break;
 
 
141
        case TRANSLUCENCY_JUSTSETZ:
 
 
142
            glBlendFunc(GL_ZERO, GL_ONE);
 
 
143
        break;
 
 
144
        default:
 
 
145
            fprintf(stderr, "RenderPolygon.TranslucencyMode: invalid %d\n", RenderPolygon.TranslucencyMode);
 
 
146
    }
 
 
147
}
 
 
148
 
 
 
149
/* 
 
 
150
A few things:
 
 
151
- Vertices with a specular color are done twice.
 
 
152
  Might want to try spitting apart the three arrays and using the same vertex
 
 
153
  array for both passes.
 
 
154
- Fix code for separate color support.
 
 
155
*/
 
 
156
 
 
 
157
void InitOpenGL()
 
 
158
{
 
 
159
    CurrentTranslucencyMode = TRANSLUCENCY_OFF;
 
 
160
    CurrentFilteringMode = FILTERING_BILINEAR_OFF;
 
 
161
    CurrentlyBoundTexture = NULL;
 
 
162
    //glBindTexture(GL_TEXTURE_2D, 0);
 
 
163
    glBlendFunc(GL_ONE, GL_ZERO);
 
 
164
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 
 
165
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 
 
166
 
 
 
167
    glEnableClientState(GL_VERTEX_ARRAY);
 
 
168
    glVertexPointer(4, GL_FLOAT, sizeof(varr[0]), varr[0].v);
 
 
169
 
 
 
170
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 
 
171
    glTexCoordPointer(2, GL_FLOAT, sizeof(varr[0]), varr[0].t);
 
 
172
 
 
 
173
    glEnableClientState(GL_COLOR_ARRAY);
 
 
174
    glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(varr[0]), varr[0].c);
 
 
175
 
 
 
176
    tarrc = varrc = starrc = svarrc = 0;
 
 
177
    tarrp = tarr;
 
 
178
    varrp = varr;
 
 
179
    starrp = &tarr[TA_MAXTRIANGLES];
 
 
180
    svarrp = &varr[TA_MAXVERTICES];
 
 
181
}
 
 
182
 
 
 
183
static void FlushTriangleBuffers(int backup)
 
 
184
{
 
 
185
    if (tarrc)
 
 
186
    {
 
 
187
        glDrawElements(GL_TRIANGLES, tarrc*3, GL_UNSIGNED_INT, tarr);
 
 
188
 
 
 
189
        tarrc = varrc = 0;
 
 
190
        tarrp = tarr;
 
 
191
        varrp = varr;
 
 
192
    }
 
 
193
 
 
 
194
    if (starrc)
 
 
195
    {
 
 
196
        if (CurrentlyBoundTexture != NULL) 
 
 
197
        {
 
 
198
            if (!backup) 
 
 
199
                CurrentlyBoundTexture = NULL;
 
 
200
 
 
 
201
            glBindTexture(GL_TEXTURE_2D, 0);
 
 
202
        }
 
 
203
 
 
 
204
        if (CurrentTranslucencyMode != TRANSLUCENCY_GLOWING) 
 
 
205
        {
 
 
206
            if (!backup)
 
 
207
                CurrentTranslucencyMode = TRANSLUCENCY_GLOWING;
 
 
208
 
 
 
209
            SetTranslucencyMode(TRANSLUCENCY_GLOWING);
 
 
210
 
 
 
211
            if (CurrentTranslucencyMode == TRANSLUCENCY_OFF)
 
 
212
            {
 
 
213
                glEnable(GL_BLEND);
 
 
214
                glBlendFunc(GL_SRC_ALPHA, GL_ONE);
 
 
215
            }
 
 
216
        }
 
 
217
 
 
 
218
        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
 
 
219
 
 
 
220
        glDrawElements(GL_TRIANGLES, starrc*3, GL_UNSIGNED_INT, starr);
 
 
221
 
 
 
222
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 
 
223
 
 
 
224
        if (backup)
 
 
225
        {
 
 
226
            if (CurrentlyBoundTexture)
 
 
227
                glBindTexture(GL_TEXTURE_2D, CurrentlyBoundTexture->id);
 
 
228
 
 
 
229
            if (CurrentTranslucencyMode != TRANSLUCENCY_GLOWING)
 
 
230
                SetTranslucencyMode(CurrentTranslucencyMode);
 
 
231
        }
 
 
232
        else
 
 
233
        {
 
 
234
            CurrentlyBoundTexture = NULL;
 
 
235
            CurrentTranslucencyMode = TRANSLUCENCY_GLOWING;
 
 
236
        }
 
 
237
 
 
 
238
        starrc = 0;
 
 
239
        starrp = &tarr[TA_MAXTRIANGLES];
 
 
240
 
 
 
241
        svarrc = 0;
 
 
242
        svarrp = &varr[TA_MAXVERTICES];
 
 
243
    }
 
 
244
}
 
 
245
 
 
 
246
static void CheckBoundTextureIsCorrect(struct TEXTURE *tex)
 
 
247
{
 
 
248
    if (tex == CurrentlyBoundTexture)
 
 
249
        return;
 
 
250
 
 
 
251
    FlushTriangleBuffers(1);
 
 
252
 
 
 
253
    if (tex == NULL)
 
 
254
    {
 
 
255
        glBindTexture(GL_TEXTURE_2D, 0);
 
 
256
 
 
 
257
        CurrentlyBoundTexture = NULL;
 
 
258
    }
 
 
259
    else
 
 
260
    {
 
 
261
        glBindTexture(GL_TEXTURE_2D, tex->id);
 
 
262
 
 
 
263
        if (tex->filter != CurrentFilteringMode) 
 
 
264
        {
 
 
265
            switch(CurrentFilteringMode) 
 
 
266
            {
 
 
267
                case FILTERING_BILINEAR_OFF:
 
 
268
                    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 
 
269
                    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 
 
270
                break;
 
 
271
                case FILTERING_BILINEAR_ON:
 
 
272
                    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 
 
273
                    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 
 
274
                default:
 
 
275
                break;
 
 
276
            }
 
 
277
 
 
 
278
            tex->filter = CurrentFilteringMode;
 
 
279
        }
 
 
280
 
 
 
281
        CurrentlyBoundTexture = tex;
 
 
282
    }
 
 
283
}
 
 
284
 
 
 
285
static void CheckFilteringModeIsCorrect(enum FILTERING_MODE_ID filter)
 
 
286
{
 
 
287
    CurrentFilteringMode = filter;
 
 
288
 
 
 
289
    if (CurrentlyBoundTexture && CurrentlyBoundTexture->filter != CurrentFilteringMode) 
 
 
290
    {
 
 
291
        FlushTriangleBuffers(1);
 
 
292
 
 
 
293
        switch(CurrentFilteringMode) 
 
 
294
        {
 
 
295
            case FILTERING_BILINEAR_OFF:
 
 
296
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 
 
297
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 
 
298
            break;
 
 
299
            case FILTERING_BILINEAR_ON:
 
 
300
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 
 
301
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 
 
302
            default:
 
 
303
            break;
 
 
304
        }
 
 
305
 
 
 
306
        CurrentlyBoundTexture->filter = CurrentFilteringMode;
 
 
307
    }
 
 
308
}
 
 
309
 
 
 
310
static void CheckTranslucencyModeIsCorrect(enum TRANSLUCENCY_TYPE mode)
 
 
311
{    
 
 
312
    if (CurrentTranslucencyMode != mode)
 
 
313
    {
 
 
314
        FlushTriangleBuffers(1);
 
 
315
        SetTranslucencyMode(mode);
 
 
316
        CurrentTranslucencyMode = mode;
 
 
317
    }
 
 
318
}
 
 
319
 
 
 
320
static void CheckTriangleBuffer(int rver, int sver, int rtri, int stri, struct TEXTURE *tex, enum TRANSLUCENCY_TYPE mode)
 
 
321
{
 
 
322
    if ((rver + varrc) >= TA_MAXVERTICES) 
 
 
323
    {
 
 
324
        FlushTriangleBuffers(0);
 
 
325
    }
 
 
326
    else if ((sver + svarrc) >= TA_MAXVERTICES) 
 
 
327
    {
 
 
328
        FlushTriangleBuffers(0);
 
 
329
    }
 
 
330
    else if (!rtri && ((rver - 2 + tarrc) >= TA_MAXTRIANGLES)) 
 
 
331
    {
 
 
332
        FlushTriangleBuffers(0);
 
 
333
    }
 
 
334
    else if (rtri && ((rtri + tarrc) >= TA_MAXTRIANGLES)) 
 
 
335
    {
 
 
336
        FlushTriangleBuffers(0);
 
 
337
    }
 
 
338
    else if (!stri && ((sver - 2 + starrc) >= TA_MAXTRIANGLES)) 
 
 
339
    {
 
 
340
        FlushTriangleBuffers(0);
 
 
341
    }
 
 
342
    else if (stri && ((stri + starrc) >= TA_MAXTRIANGLES)) 
 
 
343
    {
 
 
344
        FlushTriangleBuffers(0);
 
 
345
    }
 
 
346
 
 
 
347
    if (-1 != (intptr_t)tex)
 
 
348
        CheckBoundTextureIsCorrect(tex);
 
 
349
 
 
 
350
    if (mode != -1)
 
 
351
        CheckTranslucencyModeIsCorrect(mode);
 
 
352
 
 
 
353
#define OUTPUT_TRIANGLE(x, y, z) \
 
 
354
{ \
 
 
355
    tarrp->a = varrc + (x);    \
 
 
356
    tarrp->b = varrc + (y);    \
 
 
357
    tarrp->c = varrc + (z);    \
 
 
358
                \
 
 
359
    tarrp++;        \
 
 
360
    tarrc++;         \
 
 
361
}
 
 
362
    if (!rtri)
 
 
363
    {
 
 
364
        switch(rver) 
 
 
365
        {
 
 
366
            case 0:
 
 
367
                break;
 
 
368
            case 3:
 
 
369
                OUTPUT_TRIANGLE(0, 2, 1);
 
 
370
                break;
 
 
371
            case 5:
 
 
372
                OUTPUT_TRIANGLE(0, 1, 4);
 
 
373
                OUTPUT_TRIANGLE(1, 3, 4);
 
 
374
                OUTPUT_TRIANGLE(1, 2, 3);
 
 
375
                break;
 
 
376
            case 8:
 
 
377
                OUTPUT_TRIANGLE(0, 6, 7);
 
 
378
            case 7:
 
 
379
                OUTPUT_TRIANGLE(0, 5, 6);
 
 
380
            case 6:
 
 
381
                OUTPUT_TRIANGLE(0, 4, 5);
 
 
382
                OUTPUT_TRIANGLE(0, 3, 4);
 
 
383
            case 4:
 
 
384
                OUTPUT_TRIANGLE(0, 2, 3);
 
 
385
                OUTPUT_TRIANGLE(0, 1, 2);            
 
 
386
                break;
 
 
387
            default:
 
 
388
                fprintf(stderr, "DrawTriangles_T2F_C4UB_V4F: vertices = %d\n", rver);
 
 
389
        }
 
 
390
    }    
 
 
391
#undef OUTPUT_TRIANGLE
 
 
392
 
 
 
393
#define OUTPUT_TRIANGLE(x, y, z) \
 
 
394
{ \
 
 
395
    starrp->a = TA_MAXVERTICES + svarrc + (x);\
 
 
396
    starrp->b = TA_MAXVERTICES + svarrc + (y);\
 
 
397
    starrp->c = TA_MAXVERTICES + svarrc + (z);\
 
 
398
                        \
 
 
399
    starrp++;                \
 
 
400
    starrc++;                 \
 
 
401
}
 
 
402
    if (!stri)
 
 
403
    {
 
 
404
        switch(sver)
 
 
405
        {
 
 
406
            case 0:
 
 
407
                break;
 
 
408
            case 3:
 
 
409
                OUTPUT_TRIANGLE(0, 2, 1);
 
 
410
                break;
 
 
411
            case 5:
 
 
412
                OUTPUT_TRIANGLE(0, 1, 4);
 
 
413
                OUTPUT_TRIANGLE(1, 3, 4);
 
 
414
                OUTPUT_TRIANGLE(1, 2, 3);
 
 
415
                break;
 
 
416
            case 8:
 
 
417
                OUTPUT_TRIANGLE(0, 6, 7);
 
 
418
            case 7:
 
 
419
                OUTPUT_TRIANGLE(0, 5, 6);
 
 
420
            case 6:
 
 
421
                OUTPUT_TRIANGLE(0, 4, 5);
 
 
422
                OUTPUT_TRIANGLE(0, 3, 4);
 
 
423
            case 4:
 
 
424
                OUTPUT_TRIANGLE(0, 2, 3);
 
 
425
                OUTPUT_TRIANGLE(0, 1, 2);
 
 
426
                break;
 
 
427
            default:
 
 
428
                fprintf(stderr, "DrawTriangles_T2F_C4UB_V4F: vertices = %d\n", sver);
 
 
429
        }
 
 
430
    }
 
 
431
#undef OUTPUT_TRIANGLE
 
 
432
}
 
 
433
 
 
 
434
static void CreateOGLTexture(struct TEXTURE *tex)
 
 
435
{
 
 
436
    FlushTriangleBuffers(1);
 
 
437
 
 
 
438
    glGenTextures(1, &tex->id);
 
 
439
    glBindTexture(GL_TEXTURE_2D, tex->id);
 
 
440
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
 
 
441
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
 
 
442
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 
 
443
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 
 
444
 
 
 
445
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex->w, tex->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex->buf);
 
 
446
 
 
 
447
    tex->filter = FILTERING_BILINEAR_ON;
 
 
448
}
 
 
449
 
 
 
450
void assign_textures()
 
 
451
{
 
 
452
    int i = 2;
 
 
453
 
 
 
454
    for (; i <= NumImages; i++)
 
 
455
    {
 
 
456
        struct TEXTURE *tex = ImageHeaderArray[i].Texture;
 
 
457
 
 
 
458
        if (NULL != tex->buf)
 
 
459
        {
 
 
460
            CreateOGLTexture(tex);
 
 
461
            free(tex->buf);
 
 
462
            tex->buf = NULL;
 
 
463
        }
 
 
464
    }
 
 
465
}
 
 
466
 
 
 
467
void ThisFramesRenderingHasBegun()
 
 
468
{
 
 
469
    CheckFilteringModeIsCorrect(FILTERING_BILINEAR_ON);            
 
 
470
}
 
 
471
 
 
 
472
void ThisFramesRenderingHasFinished()
 
 
473
{
 
 
474
    FlushTriangleBuffers(0);
 
 
475
}
 
 
476
 
 
 
477
void DecalSystem_Setup()
 
 
478
{
 
 
479
    FlushTriangleBuffers(0);
 
 
480
 
 
 
481
    glDepthMask(GL_FALSE);
 
 
482
 
 
 
483
    /* this does stop zfighting with bulletmarks on walls... */
 
 
484
    glEnable(GL_POLYGON_OFFSET_FILL);
 
 
485
    glPolygonOffset(-8.0, -8.0);
 
 
486
}
 
 
487
 
 
 
488
void DecalSystem_End()
 
 
489
{
 
 
490
    FlushTriangleBuffers(0);
 
 
491
 
 
 
492
    glDepthMask(GL_TRUE);
 
 
493
 
 
 
494
    glDisable(GL_POLYGON_OFFSET_FILL);
 
 
495
}
 
 
496
 
 
 
497
void Rectangle(int x0, int y0, int x1, int y1, int r, int g, int b, int a)
 
 
498
{
 
 
499
    GLfloat x[4], y[4];
 
 
500
 
 
 
501
    if (y1 <= y0)
 
 
502
        return;
 
 
503
 
 
 
504
    CheckTranslucencyModeIsCorrect(TRANSLUCENCY_GLOWING);
 
 
505
    CheckBoundTextureIsCorrect(NULL);
 
 
506
 
 
 
507
    glColor4ub(r, g, b, a);
 
 
508
 
 
 
509
    x[0] = x0;
 
 
510
    x[0] =  (x[0] - ScreenDescriptorBlock.SDB_CentreX) / ScreenDescriptorBlock.SDB_CentreX;
 
 
511
    y[0] = y0;
 
 
512
    y[0] = -(y[0] - ScreenDescriptorBlock.SDB_CentreY) / ScreenDescriptorBlock.SDB_CentreY;
 
 
513
 
 
 
514
    x[1] = x1 - 1;
 
 
515
    x[1] =  (x[1] - ScreenDescriptorBlock.SDB_CentreX) / ScreenDescriptorBlock.SDB_CentreX;
 
 
516
    y[1] = y0;
 
 
517
    y[1] = -(y[1] - ScreenDescriptorBlock.SDB_CentreY) / ScreenDescriptorBlock.SDB_CentreY;
 
 
518
 
 
 
519
    x[2] = x1 - 1;
 
 
520
    x[2] =  (x[2] - ScreenDescriptorBlock.SDB_CentreX) / ScreenDescriptorBlock.SDB_CentreX;
 
 
521
    y[2] = y1 - 1;
 
 
522
    y[2] = -(y[2] - ScreenDescriptorBlock.SDB_CentreY) / ScreenDescriptorBlock.SDB_CentreY;
 
 
523
 
 
 
524
    x[3] = x0;
 
 
525
    x[3] =  (x[3] - ScreenDescriptorBlock.SDB_CentreX) / ScreenDescriptorBlock.SDB_CentreX;
 
 
526
    y[3] = y1 - 1;
 
 
527
    y[3] = -(y[3] - ScreenDescriptorBlock.SDB_CentreY) / ScreenDescriptorBlock.SDB_CentreY;
 
 
528
 
 
 
529
    glBegin(GL_QUADS);
 
 
530
        glVertex3f(x[0], y[0], -1);
 
 
531
        glVertex3f(x[1], y[1], -1);
 
 
532
        glVertex3f(x[2], y[2], -1);
 
 
533
        glVertex3f(x[3], y[3], -1);
 
 
534
    glEnd();
 
 
535
} 
 
 
536
 
 
 
537
void ZBufferedGouraudTexturedPolygon_Output(POLYHEADER *inputPolyPtr, RENDERVERTEX *renderVerticesPtr)
 
 
538
{
 
 
539
    struct TEXTURE *TextureHandle;
 
 
540
    unsigned int i;
 
 
541
    float RecipW, RecipH;
 
 
542
 
 
 
543
    GLfloat ZNear = (GLfloat) (VDB_ClipZ * GlobalScale);
 
 
544
    int texoffset = inputPolyPtr->PolyColour & ClrTxDefn;
 
 
545
 
 
 
546
    if (texoffset)
 
 
547
    {
 
 
548
        CurrTextureHandle = TextureHandle = ImageHeaderArray[texoffset].Texture;
 
 
549
    } 
 
 
550
    else
 
 
551
        TextureHandle = CurrTextureHandle;
 
 
552
 
 
 
553
    if (TextureHandle->w == 128) 
 
 
554
    {
 
 
555
        RecipW = (1.0f / 128.0f) / 65536.0f;
 
 
556
    }
 
 
557
    else
 
 
558
    {
 
 
559
        float width = TextureHandle->w;
 
 
560
        RecipW = (1.0f / width) / 65536.0f;
 
 
561
    }
 
 
562
 
 
 
563
    if (TextureHandle->h == 128) 
 
 
564
    {
 
 
565
        RecipH = (1.0f / 128.0f) / 65536.0f;
 
 
566
    }
 
 
567
    else
 
 
568
    {
 
 
569
        float height = TextureHandle->h;
 
 
570
        RecipH = (1.0f / height) / 65536.0f;
 
 
571
    }
 
 
572
 
 
 
573
    CheckTriangleBuffer(RenderPolygon.NumberOfVertices, RenderPolygon.NumberOfVertices, 0, 0, TextureHandle, RenderPolygon.TranslucencyMode);
 
 
574
 
 
 
575
    for (i = 0; i < RenderPolygon.NumberOfVertices; i++) 
 
 
576
    {
 
 
577
        RENDERVERTEX *vertices = &renderVerticesPtr[i];
 
 
578
        GLfloat rhw = 1.0/(float)vertices->Z, zvalue;
 
 
579
 
 
 
580
        GLfloat s = ((float)vertices->U) * RecipW + (1.0f/256.0f);
 
 
581
        GLfloat t = ((float)vertices->V) * RecipH + (1.0f/256.0f);
 
 
582
 
 
 
583
//        if (s < 0.0 || t < 0.0 || s >= 1.0 || t >= 1.0)
 
 
584
//            fprintf(stderr, "HEY! s = %f, t = %f (%d, %d)\n", s, t, vertices->U, vertices->V);
 
 
585
 
 
 
586
        GLfloat x =  ((float)vertices->X*((float)Global_VDB.VDB_ProjX+1.0f))/((float)vertices->Z*(float)ScreenDescriptorBlock.SDB_CentreX);
 
 
587
        GLfloat y = -((float)vertices->Y*((float)Global_VDB.VDB_ProjY+1.0f))/((float)vertices->Z*(float)ScreenDescriptorBlock.SDB_CentreY);
 
 
588
 
 
 
589
        zvalue = vertices->Z;
 
 
590
        GLfloat z = 1.0f - 2.0f * ZNear / zvalue;
 
 
591
 
 
 
592
        varrp->v[0] = svarrp->v[0] = x / rhw;
 
 
593
        varrp->v[1] = svarrp->v[1] = y / rhw;
 
 
594
        varrp->v[2] = svarrp->v[2] = z / rhw;
 
 
595
        varrp->v[3] = svarrp->v[3] = 1 / rhw;
 
 
596
 
 
 
597
        varrp->t[0] = /**/ svarrp->t[0] = /**/ s;
 
 
598
        varrp->t[1] = /**/ svarrp->t[1] = /**/ t;
 
 
599
 
 
 
600
        varrp->c[0] = GammaValues[vertices->R];
 
 
601
        varrp->c[1] = GammaValues[vertices->G];
 
 
602
        varrp->c[2] = GammaValues[vertices->B];
 
 
603
        varrp->c[3] = vertices->A;
 
 
604
 
 
 
605
        svarrp->c[0] = GammaValues[vertices->SpecularR];
 
 
606
        svarrp->c[1] = GammaValues[vertices->SpecularG];
 
 
607
        svarrp->c[2] = GammaValues[vertices->SpecularB];
 
 
608
        svarrp->c[3] = 255;
 
 
609
 
 
 
610
        varrp++;
 
 
611
        varrc++;
 
 
612
        svarrp++;
 
 
613
        svarrc++;
 
 
614
    }
 
 
615
}
 
 
616
 
 
 
617
void SkyPolygon_Output(RENDERVERTEX *renderVerticesPtr)
 
 
618
{
 
 
619
    unsigned int i;
 
 
620
    float RecipW, RecipH;
 
 
621
    struct TEXTURE *TextureHandle = ImageHeaderArray[CloudyImageNumber].Texture;        
 
 
622
 
 
 
623
    CurrTextureHandle = TextureHandle;
 
 
624
 
 
 
625
    if (TextureHandle->w == 128) 
 
 
626
    {
 
 
627
        RecipW = (1.0f / 128.0f) / 65536.0f;
 
 
628
    }
 
 
629
    else
 
 
630
    {
 
 
631
        float width = TextureHandle->w;
 
 
632
        RecipW = (1.0f / width) / 65536.0f;
 
 
633
    }
 
 
634
 
 
 
635
    if (TextureHandle->h == 128) 
 
 
636
    {
 
 
637
        RecipH = (1.0f / 128.0f) / 65536.0f;
 
 
638
    }
 
 
639
    else
 
 
640
    {
 
 
641
        float height = TextureHandle->h;
 
 
642
        RecipH = (1.0f / height) / 65536.0f;
 
 
643
    }
 
 
644
 
 
 
645
    CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, 0, 0, TextureHandle, RenderPolygon.TranslucencyMode);
 
 
646
 
 
 
647
    for (i = 0; i < RenderPolygon.NumberOfVertices; i++) 
 
 
648
    {
 
 
649
        RENDERVERTEX *vertices = &renderVerticesPtr[i];
 
 
650
 
 
 
651
        GLfloat rhw = 1.0 / (float)vertices->Z;
 
 
652
 
 
 
653
        GLfloat s = ((float)vertices->U) * RecipW + (1.0f/256.0f);
 
 
654
        GLfloat t = ((float)vertices->V) * RecipH + (1.0f/256.0f);
 
 
655
 
 
 
656
//        if (s < 0.0 || t < 0.0 || s >= 1.0 || t >= 1.0)
 
 
657
//            fprintf(stderr, "HEY! s = %f, t = %f (%d, %d)\n", s, t, vertices->U, vertices->V);
 
 
658
 
 
 
659
        GLfloat x =  ((float)vertices->X*((float)Global_VDB.VDB_ProjX+1.0f))/((float)vertices->Z*(float)ScreenDescriptorBlock.SDB_CentreX);
 
 
660
        GLfloat y = -((float)vertices->Y*((float)Global_VDB.VDB_ProjY+1.0f))/((float)vertices->Z*(float)ScreenDescriptorBlock.SDB_CentreY);
 
 
661
 
 
 
662
        GLfloat z = 1.0f;
 
 
663
 
 
 
664
        varrp->v[0] = x / rhw;
 
 
665
        varrp->v[1] = y / rhw;
 
 
666
        varrp->v[2] = z / rhw;
 
 
667
        varrp->v[3] = 1 / rhw;
 
 
668
 
 
 
669
        varrp->t[0] = s;
 
 
670
        varrp->t[1] = t;
 
 
671
 
 
 
672
        varrp->c[0] = vertices->R;
 
 
673
        varrp->c[1] = vertices->G;
 
 
674
        varrp->c[2] = vertices->B;
 
 
675
        varrp->c[3] = vertices->A;
 
 
676
 
 
 
677
        varrp++;
 
 
678
        varrc++;
 
 
679
    }
 
 
680
}
 
 
681
 
 
 
682
void ZBufferedCloakedPolygon_Output(POLYHEADER *inputPolyPtr, RENDERVERTEX *renderVerticesPtr)
 
 
683
{
 
 
684
    float RecipW, RecipH;
 
 
685
    unsigned int i = 0;
 
 
686
    float ZNear = (float) (VDB_ClipZ * GlobalScale);
 
 
687
    int texoffset = (inputPolyPtr->PolyColour & ClrTxDefn);
 
 
688
    struct TEXTURE *TextureHandle = ImageHeaderArray[texoffset].Texture;
 
 
689
 
 
 
690
    CurrTextureHandle = TextureHandle;
 
 
691
 
 
 
692
    if (TextureHandle->w == 128) 
 
 
693
    {
 
 
694
        RecipW = 1.0f / 128.0f;
 
 
695
    }
 
 
696
    else
 
 
697
    {
 
 
698
        float width = (float) TextureHandle->w;
 
 
699
        RecipW = 1.0f / width;
 
 
700
    }
 
 
701
 
 
 
702
    if (TextureHandle->h == 128) 
 
 
703
    {
 
 
704
        RecipH = 1.0f / 128.0f;
 
 
705
    }
 
 
706
    else
 
 
707
    {
 
 
708
        float height = (float) TextureHandle->h;
 
 
709
        RecipH = 1.0f / height;
 
 
710
    }
 
 
711
 
 
 
712
    CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, 0, 0, TextureHandle, TRANSLUCENCY_NORMAL);
 
 
713
 
 
 
714
    for (; i < RenderPolygon.NumberOfVertices; i++) 
 
 
715
    {
 
 
716
        RENDERVERTEX *vertices = &renderVerticesPtr[i];
 
 
717
 
 
 
718
        GLfloat rhw = 1.0 / (float)vertices->Z;
 
 
719
 
 
 
720
        GLfloat s = (((float)vertices->U/65536.0f)+0.5) * RecipW;
 
 
721
        GLfloat t = (((float)vertices->V/65536.0f)+0.5) * RecipH;
 
 
722
 
 
 
723
//        if (s < 0.0 || t < 0.0 || s >= 1.0 || t >= 1.0)
 
 
724
//            fprintf(stderr, "HEY! s = %f, t = %f (%d, %d)\n", s, t, vertices->U, vertices->V);
 
 
725
 
 
 
726
        GLfloat x =  ((float)vertices->X*((float)Global_VDB.VDB_ProjX+1.0f))/((float)vertices->Z*(float)ScreenDescriptorBlock.SDB_CentreX);
 
 
727
        GLfloat y = -((float)vertices->Y*((float)Global_VDB.VDB_ProjY+1.0f))/((float)vertices->Z*(float)ScreenDescriptorBlock.SDB_CentreY);
 
 
728
 
 
 
729
        GLfloat zvalue = vertices->Z;
 
 
730
        GLfloat z = 1.0 - 2*ZNear/zvalue;
 
 
731
 
 
 
732
        varrp->v[0] = x / rhw;
 
 
733
        varrp->v[1] = y / rhw;
 
 
734
        varrp->v[2] = z / rhw;
 
 
735
        varrp->v[3] = 1 / rhw;
 
 
736
 
 
 
737
        varrp->t[0] = s;
 
 
738
        varrp->t[1] = t;
 
 
739
 
 
 
740
        varrp->c[0] = vertices->R;
 
 
741
        varrp->c[1] = vertices->G;
 
 
742
        varrp->c[2] = vertices->B;
 
 
743
        varrp->c[3] = vertices->A;
 
 
744
 
 
 
745
        varrp++;
 
 
746
        varrc++;
 
 
747
    }
 
 
748
}
 
 
749
 
 
 
750
int LightIntensityAtPoint(const VECTORCH *pointPtr)
 
 
751
{
 
 
752
    int intensity = 0;
 
 
753
    int i, j; 
 
 
754
 
 
 
755
    for(i=0; i < NumActiveBlocks; i++) 
 
 
756
    {
 
 
757
        DISPLAYBLOCK *dispPtr = ActiveBlockList[i];
 
 
758
 
 
 
759
        if (dispPtr->ObNumLights) 
 
 
760
        {
 
 
761
            for(j = 0; j < dispPtr->ObNumLights; j++) 
 
 
762
            {
 
 
763
                LIGHTBLOCK *lptr = dispPtr->ObLights[j];
 
 
764
                VECTORCH disp = lptr->LightWorld;
 
 
765
 
 
 
766
                disp.vx -= pointPtr->vx;
 
 
767
                disp.vy -= pointPtr->vy;
 
 
768
                disp.vz -= pointPtr->vz;
 
 
769
 
 
 
770
                int dist = Approximate3dMagnitude(&disp);
 
 
771
 
 
 
772
                if (dist < lptr->LightRange) 
 
 
773
                    intensity += WideMulNarrowDiv(lptr->LightBright, lptr->LightRange - dist, lptr->LightRange);
 
 
774
            }
 
 
775
        }
 
 
776
    }
 
 
777
 
 
 
778
    return (intensity > ONE_FIXED) ? ONE_FIXED : intensity;
 
 
779
}
 
 
780
 
 
 
781
void Decal_Output(const DECAL *decalPtr, RENDERVERTEX *renderVerticesPtr)
 
 
782
{
 
 
783
    const DECAL_DESC *decalDescPtr = &DecalDescription[decalPtr->DecalID];
 
 
784
    struct TEXTURE *TextureHandle;
 
 
785
    unsigned int i;
 
 
786
    float RecipW = 1.0 / 256.0;
 
 
787
    float RecipH = 1.0 / 256.0;
 
 
788
    int r, g, b;
 
 
789
    float ZNear = (float) (VDB_ClipZ * GlobalScale);
 
 
790
 
 
 
791
    switch(decalPtr->DecalID)
 
 
792
    {
 
 
793
        case DECAL_SHAFTOFLIGHT:
 
 
794
        case DECAL_SHAFTOFLIGHT_OUTER:
 
 
795
            TextureHandle = NULL;
 
 
796
        break;
 
 
797
        default:
 
 
798
            TextureHandle = ImageHeaderArray[SpecialFXImageNumber].Texture;
 
 
799
    }
 
 
800
 
 
 
801
    if (CHEATMODE_RAINBOWBLOOD == UserProfile.active_bonus) 
 
 
802
    {
 
 
803
        r = FastRandom() & 255;
 
 
804
        g = FastRandom() & 255;
 
 
805
        b = FastRandom() & 255;
 
 
806
    }
 
 
807
    else if (decalDescPtr->IsLit) 
 
 
808
    {
 
 
809
        int intensity = LightIntensityAtPoint(decalPtr->Vertices);
 
 
810
 
 
 
811
        r = MUL_FIXED(intensity, decalDescPtr->RedScale[PlayerStatus.VisionMode]);
 
 
812
        g = MUL_FIXED(intensity, decalDescPtr->GreenScale[PlayerStatus.VisionMode]);
 
 
813
        b = MUL_FIXED(intensity, decalDescPtr->BlueScale[PlayerStatus.VisionMode]);
 
 
814
    }
 
 
815
    else
 
 
816
    {
 
 
817
        r = decalDescPtr->RedScale[PlayerStatus.VisionMode];
 
 
818
        g = decalDescPtr->GreenScale[PlayerStatus.VisionMode];
 
 
819
        b = decalDescPtr->BlueScale[PlayerStatus.VisionMode];
 
 
820
    }
 
 
821
 
 
 
822
    CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, 0, 0, TextureHandle, decalDescPtr->TranslucencyType);
 
 
823
 
 
 
824
    for (i = 0; i < RenderPolygon.NumberOfVertices; i++) 
 
 
825
    {
 
 
826
        RENDERVERTEX *vertices = &renderVerticesPtr[i];
 
 
827
 
 
 
828
        GLfloat rhw = 1.0 / (float)vertices->Z;
 
 
829
 
 
 
830
        GLfloat x =  ((float)vertices->X*((float)Global_VDB.VDB_ProjX+1.0f))/((float)vertices->Z*(float)ScreenDescriptorBlock.SDB_CentreX);
 
 
831
        GLfloat y = -((float)vertices->Y*((float)Global_VDB.VDB_ProjY+1.0f))/((float)vertices->Z*(float)ScreenDescriptorBlock.SDB_CentreY);
 
 
832
 
 
 
833
        GLfloat s = ((float)(vertices->U/65536.0f)+0.5f) * RecipW;
 
 
834
        GLfloat t = ((float)(vertices->V/65536.0f)+0.5f) * RecipH;
 
 
835
 
 
 
836
        GLfloat zvalue = vertices->Z;
 
 
837
        GLfloat z = 1.0f - 2.0f*ZNear/zvalue;
 
 
838
 
 
 
839
        varrp->v[0] = x / rhw;
 
 
840
        varrp->v[1] = y / rhw;
 
 
841
        varrp->v[2] = z / rhw;
 
 
842
        varrp->v[3] = 1 / rhw;
 
 
843
 
 
 
844
        varrp->t[0] = s;
 
 
845
        varrp->t[1] = t;
 
 
846
 
 
 
847
        varrp->c[0] = r;
 
 
848
        varrp->c[1] = g;
 
 
849
        varrp->c[2] = b;
 
 
850
        varrp->c[3] = decalDescPtr->Alpha;
 
 
851
 
 
 
852
        varrp++;
 
 
853
        varrc++;
 
 
854
    }
 
 
855
}
 
 
856
 
 
 
857
void Particle_Output(PARTICLE *particlePtr, RENDERVERTEX *renderVerticesPtr)
 
 
858
{
 
 
859
    unsigned int i;
 
 
860
    int r, g, b, a;
 
 
861
    const PARTICLE_DESC *particleDescPtr = &ParticleDescription[particlePtr->ParticleID];
 
 
862
    struct TEXTURE *TextureHandle = ImageHeaderArray[SpecialFXImageNumber].Texture;
 
 
863
    GLfloat ZNear = (GLfloat) (VDB_ClipZ * GlobalScale);    
 
 
864
    float RecipW = 1.0 / 256.0;
 
 
865
    float RecipH = 1.0 / 256.0;
 
 
866
 
 
 
867
    if (CHEATMODE_RAINBOWBLOOD == UserProfile.active_bonus) 
 
 
868
    {
 
 
869
        r = FastRandom() & 255;
 
 
870
        g = FastRandom() & 255;
 
 
871
        b = FastRandom() & 255;
 
 
872
        a = particleDescPtr->Alpha;
 
 
873
    }
 
 
874
    else if (particleDescPtr->IsLit && !(particlePtr->ParticleID == PARTICLE_ALIEN_BLOOD && PlayerStatus.VisionMode ==
VISION_MODE_PRED_SEEALIENS))
 
 
875
    {
 
 
876
        if (particlePtr->ParticleID == PARTICLE_SMOKECLOUD || particlePtr->ParticleID == PARTICLE_ANDROID_BLOOD)
 
 
877
        {
 
 
878
            /* this should be OK. (ColourComponents was RGBA while RGBA_MAKE is BGRA (little endian) */
 
 
879
            r = (particlePtr->Colour >> 0)  & 0xFF;
 
 
880
            g = (particlePtr->Colour >> 8)  & 0xFF;
 
 
881
            b = (particlePtr->Colour >> 16) & 0xFF;
 
 
882
            a = (particlePtr->Colour >> 24) & 0xFF;
 
 
883
        }
 
 
884
        else
 
 
885
        {
 
 
886
            int intensity = LightIntensityAtPoint(&particlePtr->Position);
 
 
887
 
 
 
888
            r = MUL_FIXED(intensity, particleDescPtr->RedScale[PlayerStatus.VisionMode]);
 
 
889
            g = MUL_FIXED(intensity, particleDescPtr->GreenScale[PlayerStatus.VisionMode]);
 
 
890
            b = MUL_FIXED(intensity, particleDescPtr->BlueScale[PlayerStatus.VisionMode]);
 
 
891
            a = particleDescPtr->Alpha;
 
 
892
        }
 
 
893
    } 
 
 
894
    else
 
 
895
    {
 
 
896
        b = particlePtr->Colour        & 0xFF;
 
 
897
        g = (particlePtr->Colour >> 8)  & 0xFF;
 
 
898
        r = (particlePtr->Colour >> 16) & 0xFF;
 
 
899
        a = (particlePtr->Colour >> 24) & 0xFF;
 
 
900
    }
 
 
901
 
 
 
902
    CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, 0, 0, TextureHandle, particleDescPtr->TranslucencyType);
 
 
903
 
 
 
904
    GLfloat z = (particleDescPtr->IsDrawnInFront) ? -0.999f : (particleDescPtr->IsDrawnAtBack) ? 0.999f : 0;
 
 
905
 
 
 
906
    for (i = 0; i < RenderPolygon.NumberOfVertices; i++) 
 
 
907
    {
 
 
908
        RENDERVERTEX *vertices = &renderVerticesPtr[i];
 
 
909
 
 
 
910
        GLfloat rhw = 1/(float)vertices->Z;
 
 
911
        GLfloat s = ((float)(vertices->U>>16)+.5) * RecipW;
 
 
912
        GLfloat t = ((float)(vertices->V>>16)+.5) * RecipH;
 
 
913
 
 
 
914
        GLfloat x =  ((float)vertices->X*((float)Global_VDB.VDB_ProjX+1.0f))/((float)vertices->Z*(float)ScreenDescriptorBlock.SDB_CentreX);
 
 
915
        GLfloat y = -((float)vertices->Y*((float)Global_VDB.VDB_ProjY+1.0f))/((float)vertices->Z*(float)ScreenDescriptorBlock.SDB_CentreY);        
 
 
916
 
 
 
917
        if(!z)
 
 
918
            z = 1.0 - 2.0 * ZNear / ((float)vertices->Z); /* currently maps [ZNear, inf) to [-1, 1], probably could be more precise with a ZFar */
 
 
919
 
 
 
920
        varrp->v[0] = x / rhw;
 
 
921
        varrp->v[1] = y / rhw;
 
 
922
        varrp->v[2] = z / rhw;
 
 
923
        varrp->v[3] = 1 / rhw;
 
 
924
 
 
 
925
        varrp->t[0] = s;
 
 
926
        varrp->t[1] = t;
 
 
927
 
 
 
928
        varrp->c[0] = r;
 
 
929
        varrp->c[1] = g;
 
 
930
        varrp->c[2] = b;
 
 
931
        varrp->c[3] = a;
 
 
932
 
 
 
933
        varrp++;
 
 
934
        varrc++;
 
 
935
    }
 
 
936
}
 
 
937
 
 
 
938
void PredatorThermalVisionPolygon_Output(RENDERVERTEX *renderVerticesPtr)
 
 
939
{
 
 
940
    unsigned int i;
 
 
941
    float ZNear = (float) (VDB_ClipZ * GlobalScale);
 
 
942
 
 
 
943
    CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, 0, 0, NULL, TRANSLUCENCY_OFF);
 
 
944
 
 
 
945
    for (i = 0; i < RenderPolygon.NumberOfVertices; i++) 
 
 
946
    {
 
 
947
        RENDERVERTEX *vertices = &renderVerticesPtr[i];
 
 
948
 
 
 
949
        GLfloat x =  ((float)vertices->X * ((float)Global_VDB.VDB_ProjX+1.0f)) / ((float)vertices->Z * (float)ScreenDescriptorBlock.SDB_CentreX);
 
 
950
        GLfloat y = -((float)vertices->Y * ((float)Global_VDB.VDB_ProjY+1.0f)) / ((float)vertices->Z * (float)ScreenDescriptorBlock.SDB_CentreY);
 
 
951
 
 
 
952
        float zvalue = vertices->Z;
 
 
953
        GLfloat z = 1.0 - 2 * ZNear / zvalue;
 
 
954
 
 
 
955
        float rhw = 1.0 / (float)vertices->Z;
 
 
956
 
 
 
957
        varrp->v[0] = x / rhw;
 
 
958
        varrp->v[1] = y / rhw;
 
 
959
        varrp->v[2] = z / rhw;
 
 
960
        varrp->v[3] = 1 / rhw;
 
 
961
 
 
 
962
        varrp->c[0] = vertices->R;
 
 
963
        varrp->c[1] = vertices->G;
 
 
964
        varrp->c[2] = vertices->B;
 
 
965
        varrp->c[3] = vertices->A;
 
 
966
 
 
 
967
        varrp++;
 
 
968
        varrc++;
 
 
969
    }
 
 
970
}
 
 
971
 
 
 
972
void ZBufferedGouraudPolygon_Output(POLYHEADER *inputPolyPtr, RENDERVERTEX *renderVerticesPtr)
 
 
973
{
 
 
974
    unsigned int i;
 
 
975
    float ZNear = (float) (VDB_ClipZ * GlobalScale);
 
 
976
    int flags = inputPolyPtr->PolyFlags;
 
 
977
 
 
 
978
    CheckTriangleBuffer(RenderPolygon.NumberOfVertices, 0, 0, 0, NULL, RenderPolygon.TranslucencyMode);
 
 
979
 
 
 
980
    for (i = 0; i < RenderPolygon.NumberOfVertices; i++) 
 
 
981
    {
 
 
982
        RENDERVERTEX *vertices = &renderVerticesPtr[i];    
 
 
983
 
 
 
984
        float zvalue = vertices->Z;
 
 
985
        GLfloat z = 1.0 - 2 * ZNear/zvalue;
 
 
986
 
 
 
987
        float rhw = 1.0 / (float)vertices->Z;
 
 
988
 
 
 
989
        GLfloat x =  ((float)vertices->X * ((float)Global_VDB.VDB_ProjX+1.0f)) / ((float)vertices->Z * (float)ScreenDescriptorBlock.SDB_CentreX);
 
 
990
        GLfloat y = -((float)vertices->Y * ((float)Global_VDB.VDB_ProjY+1.0f)) / ((float)vertices->Z * (float)ScreenDescriptorBlock.SDB_CentreY);    
 
 
991
 
 
 
992
        varrp->v[0] = x / rhw;
 
 
993
        varrp->v[1] = y / rhw;
 
 
994
        varrp->v[2] = z / rhw;
 
 
995
        varrp->v[3] = 1 / rhw;
 
 
996
 
 
 
997
        varrp->c[0] = vertices->R;
 
 
998
        varrp->c[1] = vertices->G;
 
 
999
        varrp->c[2] = vertices->B;
 
 
1000
 
 
 
1001
        varrp->c[3] = (flags & iflag_transparent) ? vertices->A : 255;
 
 
1002
 
 
 
1003
        varrp++;
 
 
1004
        varrc++;
 
 
1005
    }
 
 
1006
}
 
 
1007
 
 
 
1008
void PlayerOnFireOverlay()
 
 
1009
{
 
 
1010
    int FMVParticleColour = (VISION_MODE_IMAGEINTENSIFIER == PlayerStatus.VisionMode) ? RGBA_MAKE(0,255,0,128) : RGBA_MAKE(255,255,255,128);
 
 
1011
 
 
 
1012
    int colour = (FMVParticleColour & 0xffffff) + (128 << 24);
 
 
1013
    GLfloat s[4], t[4];
 
 
1014
    int b = (colour >> 0)  & 0xFF;
 
 
1015
    int g = (colour >> 8)  & 0xFF;
 
 
1016
    int r = (colour >> 16) & 0xFF;
 
 
1017
    int a = (colour >> 24) & 0xFF;
 
 
1018
    float u = (FastRandom() & 255) / 256.0f;
 
 
1019
    float v = (FastRandom() & 255) / 256.0f;
 
 
1020
 
 
 
1021
    CheckTranslucencyModeIsCorrect(TRANSLUCENCY_GLOWING);
 
 
1022
    CheckBoundTextureIsCorrect(ImageHeaderArray[BurningImageNumber].Texture);
 
 
1023
    CheckFilteringModeIsCorrect(FILTERING_BILINEAR_ON);
 
 
1024
 
 
 
1025
    glColor4ub(r, g, b, a);
 
 
1026
 
 
 
1027
    s[0] = s[3] = u;
 
 
1028
    s[1] = s[2] = u + 1.0f;
 
 
1029
 
 
 
1030
    t[0] = t[1] = v;
 
 
1031
    t[2] = t[3] = v + 1.0f;
 
 
1032
 
 
 
1033
    glBegin(GL_QUADS);
 
 
1034
        glTexCoord2f(s[0], t[0]); glVertex3i(-1, -1, -1);
 
 
1035
        glTexCoord2f(s[1], t[1]); glVertex3i(1, -1, -1);
 
 
1036
        glTexCoord2f(s[2], t[2]); glVertex3i(1, 1, -1);
 
 
1037
        glTexCoord2f(s[3], t[3]); glVertex3i(-1, 1, -1);
 
 
1038
    glEnd();
 
 
1039
}
 
 
1040
 
 
 
1041
void PlayerDamagedOverlay(int intensity)
 
 
1042
{
 
 
1043
    int theta[2];
 
 
1044
    int colour, baseColour;
 
 
1045
    int r, g, b, a;
 
 
1046
    int i;
 
 
1047
 
 
 
1048
    theta[0] = (CloakingPhase / 8) & 4095;
 
 
1049
    theta[1] = (800 - CloakingPhase / 8) & 4095;
 
 
1050
 
 
 
1051
    switch(AvP.PlayerType)
 
 
1052
    {
 
 
1053
        case I_Marine:
 
 
1054
        default:
 
 
1055
            baseColour = 0xff0000;
 
 
1056
        break;
 
 
1057
        case I_Alien:
 
 
1058
            baseColour = 0xffff00;
 
 
1059
        break;
 
 
1060
        case I_Predator:
 
 
1061
            baseColour = 0x00ff00;
 
 
1062
    }
 
 
1063
 
 
 
1064
    CheckBoundTextureIsCorrect(ImageHeaderArray[SpecialFXImageNumber].Texture);
 
 
1065
    CheckFilteringModeIsCorrect(FILTERING_BILINEAR_ON);
 
 
1066
 
 
 
1067
    colour = 0xffffff - baseColour + (intensity << 24);
 
 
1068
 
 
 
1069
    b = (colour >> 0)  & 0xFF;
 
 
1070
    g = (colour >> 8)  & 0xFF;
 
 
1071
    r = (colour >> 16) & 0xFF;
 
 
1072
    a = (colour >> 24) & 0xFF;
 
 
1073
 
 
 
1074
    CheckTranslucencyModeIsCorrect(TRANSLUCENCY_INVCOLOUR);
 
 
1075
 
 
 
1076
    glColor4ub(r, g, b, a);
 
 
1077
 
 
 
1078
    for (i = 0; i < 2; i++)
 
 
1079
    {
 
 
1080
        GLfloat s[4], t[4];
 
 
1081
 
 
 
1082
        float sin = (GetSin(theta[i])) / 65536.0f / 16.0f;
 
 
1083
        float cos = (GetCos(theta[i])) / 65536.0f / 16.0f;    
 
 
1084
 
 
 
1085
        s[0] = 0.875f + (cos*(-1) - sin*(-1));
 
 
1086
        s[1] = 0.875f + (cos*(+1) - sin*(-1));
 
 
1087
        s[2] = 0.875f + (cos*(+1) - sin*(+1));
 
 
1088
        s[3] = 0.875f + (cos*(-1) - sin*(+1));
 
 
1089
 
 
 
1090
        t[0] = 0.375f + (sin*(-1) + cos*(-1));
 
 
1091
        t[1] = 0.375f + (sin*(+1) + cos*(-1));
 
 
1092
        t[2] = 0.375f + (sin*(+1) + cos*(+1));
 
 
1093
        t[3] = 0.375f + (sin*(-1) + cos*(+1));
 
 
1094
 
 
 
1095
        glBegin(GL_QUADS);
 
 
1096
            glTexCoord2f(s[0], t[0]); glVertex3i(-1, -1, -1);
 
 
1097
            glTexCoord2f(s[1], t[1]); glVertex3i(1, -1, -1);
 
 
1098
            glTexCoord2f(s[2], t[2]); glVertex3i(1, 1, -1);
 
 
1099
            glTexCoord2f(s[3], t[3]); glVertex3i(-1, 1, -1);
 
 
1100
        glEnd();
 
 
1101
 
 
 
1102
        colour = baseColour + (intensity << 24);
 
 
1103
 
 
 
1104
        b = (colour >> 0)  & 0xFF;
 
 
1105
        g = (colour >> 8)  & 0xFF;
 
 
1106
        r = (colour >> 16) & 0xFF;
 
 
1107
        a = (colour >> 24) & 0xFF;
 
 
1108
 
 
 
1109
        glColor4ub(r, g, b, a);
 
 
1110
 
 
 
1111
        CheckTranslucencyModeIsCorrect(TRANSLUCENCY_GLOWING);
 
 
1112
    }
 
 
1113
}
 
 
1114
 
 
 
1115
void update_static()
 
 
1116
{
 
 
1117
    struct TEXTURE *temp = ImageHeaderArray[StaticImageNumber].Texture;
 
 
1118
    unsigned char *ptr  = temp->buf;
 
 
1119
    int i;
 
 
1120
 
 
 
1121
    for(i=0; i < 128 * 128; i++, ptr += 3)
 
 
1122
        ptr[0] = ptr[1] = ptr[2] = ((random() % 2) ? 0 : 255);
 
 
1123
 
 
 
1124
    //glBindTexture(GL_TEXTURE_2D, temp->id);
 
 
1125
    CheckFilteringModeIsCorrect(FILTERING_BILINEAR_ON);            
 
 
1126
    CheckBoundTextureIsCorrect(ImageHeaderArray[StaticImageNumber].Texture);
 
 
1127
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, temp->w, temp->h, 0, GL_RGB, GL_UNSIGNED_BYTE, temp->buf);
 
 
1128
}
 
 
1129
 
 
 
1130
void DrawNoiseOverlay(int tr)
 
 
1131
{
 
 
1132
    update_static();
 
 
1133
 
 
 
1134
    glColor4ub(255, 255, 255, tr);
 
 
1135
 
 
 
1136
    glBegin(GL_QUADS);
 
 
1137
        glTexCoord2i(0, 0); glVertex3i(-1, -1, -1);
 
 
1138
        glTexCoord2i(1, 0); glVertex3i(1, -1, -1);
 
 
1139
        glTexCoord2i(1, 1); glVertex3i(1, 1, -1);
 
 
1140
        glTexCoord2i(0, 1); glVertex3i(-1, 1, -1);
 
 
1141
    glEnd();
 
 
1142
}
 
 
1143
 
 
 
1144
void ScreenInversionOverlay()
 
 
1145
{
 
 
1146
    int i = 0;
 
 
1147
    int theta[2];
 
 
1148
 
 
 
1149
    theta[0] = (CloakingPhase / 8) & 4095;
 
 
1150
    theta[1] = (800 - CloakingPhase / 8) & 4095;
 
 
1151
 
 
 
1152
    CheckTranslucencyModeIsCorrect(TRANSLUCENCY_DARKENINGCOLOUR);
 
 
1153
    CheckBoundTextureIsCorrect(ImageHeaderArray[SpecialFXImageNumber].Texture);
 
 
1154
    CheckFilteringModeIsCorrect(FILTERING_BILINEAR_ON);
 
 
1155
 
 
 
1156
    glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
 
 
1157
 
 
 
1158
    for (; i < 2; i++) 
 
 
1159
    {
 
 
1160
        GLfloat s[4], t[4];
 
 
1161
 
 
 
1162
        float sin = GetSin(theta[i]) / 65536.0f / 16.0f;
 
 
1163
        float cos = GetCos(theta[i]) / 65536.0f / 16.0f;
 
 
1164
 
 
 
1165
        s[0] = 0.375f + (cos*(-1) - sin*(-1));
 
 
1166
        s[1] = 0.375f + (cos*(+1) - sin*(-1));
 
 
1167
        s[2] = 0.375f + (cos*(+1) - sin*(+1));
 
 
1168
        s[3] = 0.375f + (cos*(-1) - sin*(+1));
 
 
1169
 
 
 
1170
        t[0] = 0.375f + (sin*(-1) + cos*(-1));
 
 
1171
        t[2] = 0.375f + (sin*(+1) + cos*(+1));
 
 
1172
        t[1] = 0.375f + (sin*(+1) + cos*(-1));
 
 
1173
        t[3] = 0.375f + (sin*(-1) + cos*(+1));
 
 
1174
 
 
 
1175
        glBegin(GL_QUADS);
 
 
1176
            glTexCoord2f(s[0], t[0]); glVertex2i(-1, -1);
 
 
1177
            glTexCoord2f(s[1], t[1]); glVertex2i(1, -1);
 
 
1178
            glTexCoord2f(s[2], t[2]); glVertex2i(1, 1);
 
 
1179
            glTexCoord2f(s[3], t[3]); glVertex2i(-1, 1);
 
 
1180
        glEnd();
 
 
1181
 
 
 
1182
        CheckTranslucencyModeIsCorrect(TRANSLUCENCY_COLOUR);
 
 
1183
    }
 
 
1184
}
 
 
1185
 
 
 
1186
void PredatorScreenInversionOverlay()
 
 
1187
{
 
 
1188
    CheckTranslucencyModeIsCorrect(TRANSLUCENCY_DARKENINGCOLOUR);
 
 
1189
    CheckBoundTextureIsCorrect(NULL);
 
 
1190
 
 
 
1191
    glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
 
 
1192
 
 
 
1193
    glBegin(GL_QUADS);
 
 
1194
        glVertex3i(-1, -1, -1);
 
 
1195
        glVertex3i( 1, -1, -1);
 
 
1196
        glVertex3i( 1,  1, -1);
 
 
1197
        glVertex3i(-1,  1, -1);
 
 
1198
    glEnd();
 
 
1199
}
 
 
1200
 
 
 
1201
void DrawScanlinesOverlay(float level)
 
 
1202
{
 
 
1203
    GLfloat s[4];
 
 
1204
    int a = 64.0f + level * 64.0f;
 
 
1205
    float size = 128.0f * (1.0f - level * 0.8f);
 
 
1206
 
 
 
1207
    CheckTranslucencyModeIsCorrect(TRANSLUCENCY_NORMAL);
 
 
1208
    CheckBoundTextureIsCorrect(ImageHeaderArray[PredatorNumbersImageNumber].Texture);
 
 
1209
    CheckFilteringModeIsCorrect(FILTERING_BILINEAR_ON);
 
 
1210
 
 
 
1211
    glColor4ub(255, 255, 255, a);
 
 
1212
 
 
 
1213
    s[0] = s[1] = (128.0f - size) / 256.0f;
 
 
1214
    s[2] = s[3] = (128.0f + size) / 256.0f;
 
 
1215
 
 
 
1216
    glBegin(GL_QUADS);
 
 
1217
        glTexCoord2f(s[0], 1.0f); glVertex3i(-1, -1, -1);
 
 
1218
        glTexCoord2f(s[1], 1.0f); glVertex3i(1, -1, -1);
 
 
1219
        glTexCoord2f(s[2], 1.0f); glVertex3i(1, 1, -1);
 
 
1220
        glTexCoord2f(s[3], 1.0f); glVertex3i(-1, 1, -1);
 
 
1221
    glEnd();
 
 
1222
}
 
 
1223
 
 
 
1224
void FadeDownScreen(int brightness, int colour)
 
 
1225
{
 
 
1226
    int t = 255 - (brightness >> 8);
 
 
1227
 
 
 
1228
    if (t < 0)
 
 
1229
        t = 0;
 
 
1230
 
 
 
1231
    colour = (t << 24) + colour;
 
 
1232
 
 
 
1233
    CheckTranslucencyModeIsCorrect(TRANSLUCENCY_NORMAL);
 
 
1234
    CheckBoundTextureIsCorrect(NULL);
 
 
1235
 
 
 
1236
    int b = (colour >> 0)  & 0xFF;
 
 
1237
    int g = (colour >> 8)  & 0xFF;
 
 
1238
    int r = (colour >> 16) & 0xFF;
 
 
1239
    int a = (colour >> 24) & 0xFF;
 
 
1240
 
 
 
1241
    glColor4ub(r, g, b, a);
 
 
1242
 
 
 
1243
    glBegin(GL_QUADS);
 
 
1244
        glVertex3i(-1, -1, -1);
 
 
1245
        glVertex3i(1, -1, -1);
 
 
1246
        glVertex3i(1, 1, -1);
 
 
1247
        glVertex3i(-1, 1, -1);
 
 
1248
    glEnd();
 
 
1249
}
 
 
1250
 
 
 
1251
void HUDQuad_Output(int imageNumber, struct VertexTag *quadVerticesPtr, unsigned int colour)
 
 
1252
{
 
 
1253
    float RecipW, RecipH;
 
 
1254
    int i;
 
 
1255
    GLfloat x[4], y[4], s[4], t[4];
 
 
1256
    struct TEXTURE *tex = ImageHeaderArray[imageNumber].Texture;
 
 
1257
 
 
 
1258
    /* possibly use polygon offset? (predator hud) */
 
 
1259
 
 
 
1260
    CheckTranslucencyModeIsCorrect(TRANSLUCENCY_GLOWING);
 
 
1261
    CheckBoundTextureIsCorrect(tex);
 
 
1262
 
 
 
1263
    if (tex->w == 128)
 
 
1264
    {
 
 
1265
        RecipW = 1.0f / 128.0f;
 
 
1266
    }
 
 
1267
    else
 
 
1268
    {
 
 
1269
        float width = (float) tex->w;
 
 
1270
        RecipW = 1.0f / width;
 
 
1271
    }
 
 
1272
 
 
 
1273
    if (tex->h == 128) 
 
 
1274
    {
 
 
1275
        RecipH = 1.0f / 128.0f;
 
 
1276
    }
 
 
1277
    else
 
 
1278
    {
 
 
1279
        float height = (float) tex->h;
 
 
1280
        RecipH = 1.0f / height;
 
 
1281
    }
 
 
1282
 
 
 
1283
    int b = (colour >> 0)  & 0xFF;
 
 
1284
    int g = (colour >> 8)  & 0xFF;
 
 
1285
    int r = (colour >> 16) & 0xFF;
 
 
1286
    int a = (colour >> 24) & 0xFF;
 
 
1287
 
 
 
1288
    glColor4ub(r, g, b, a);
 
 
1289
 
 
 
1290
    for (i = 0; i < 4; i++) 
 
 
1291
    {
 
 
1292
        x[i] = quadVerticesPtr[i].X;
 
 
1293
        x[i] =  (x[i] - ScreenDescriptorBlock.SDB_CentreX) / ScreenDescriptorBlock.SDB_CentreX;
 
 
1294
        y[i] = quadVerticesPtr[i].Y;
 
 
1295
        y[i] = -(y[i] - ScreenDescriptorBlock.SDB_CentreY) / ScreenDescriptorBlock.SDB_CentreY;
 
 
1296
 
 
 
1297
        s[i] = ((float)quadVerticesPtr[i].U) * RecipW;
 
 
1298
        t[i] = ((float)quadVerticesPtr[i].V) * RecipH;
 
 
1299
    }
 
 
1300
 
 
 
1301
    glBegin(GL_QUADS);
 
 
1302
        glTexCoord2f(s[0], t[0]); glVertex3f(x[0], y[0], -1.0f);
 
 
1303
        glTexCoord2f(s[1], t[1]); glVertex3f(x[1], y[1], -1.0f);
 
 
1304
        glTexCoord2f(s[2], t[2]); glVertex3f(x[2], y[2], -1.0f);
 
 
1305
        glTexCoord2f(s[3], t[3]); glVertex3f(x[3], y[3], -1.0f);
 
 
1306
    glEnd();
 
 
1307
}
 
 
1308
 
 
 
1309
void RenderHUDNumber_Centred(unsigned int number,int x,int y,int colour)
 
 
1310
{
 
 
1311
    struct VertexTag quadVertices[4];
 
 
1312
    int noOfDigits = 3;
 
 
1313
    int h = MUL_FIXED(HUDScaleFactor, HUD_DIGITAL_NUMBERS_HEIGHT);
 
 
1314
    int w = MUL_FIXED(HUDScaleFactor, HUD_DIGITAL_NUMBERS_WIDTH);
 
 
1315
 
 
 
1316
    quadVertices[0].Y = y;
 
 
1317
    quadVertices[1].Y = y;
 
 
1318
    quadVertices[2].Y = y + h;
 
 
1319
    quadVertices[3].Y = y + h;
 
 
1320
 
 
 
1321
    x += (3 * w) / 2;
 
 
1322
 
 
 
1323
    CheckFilteringModeIsCorrect(FILTERING_BILINEAR_OFF);
 
 
1324
 
 
 
1325
    do {
 
 
1326
        int topLeftU, topLeftV;
 
 
1327
 
 
 
1328
        int digit = number % 10;
 
 
1329
        number /= 10;
 
 
1330
 
 
 
1331
        if (digit < 8)
 
 
1332
        {
 
 
1333
            topLeftU = 1 + (digit) * 16;
 
 
1334
            topLeftV = 1;
 
 
1335
        }
 
 
1336
        else
 
 
1337
        {
 
 
1338
            topLeftU = 1 + (digit-8) * 16;
 
 
1339
            topLeftV = 1 + 24;
 
 
1340
        }
 
 
1341
 
 
 
1342
        topLeftV += 80;
 
 
1343
 
 
 
1344
        quadVertices[0].U = topLeftU;
 
 
1345
        quadVertices[0].V = topLeftV;
 
 
1346
        quadVertices[1].U = topLeftU + HUD_DIGITAL_NUMBERS_WIDTH;
 
 
1347
        quadVertices[1].V = topLeftV;
 
 
1348
        quadVertices[2].U = topLeftU + HUD_DIGITAL_NUMBERS_WIDTH;
 
 
1349
        quadVertices[2].V = topLeftV + HUD_DIGITAL_NUMBERS_HEIGHT;
 
 
1350
        quadVertices[3].U = topLeftU;
 
 
1351
        quadVertices[3].V = topLeftV + HUD_DIGITAL_NUMBERS_HEIGHT;
 
 
1352
 
 
 
1353
        x -= 1+w;
 
 
1354
        quadVertices[0].X = x;
 
 
1355
        quadVertices[3].X = x;
 
 
1356
        quadVertices[1].X = x + w;
 
 
1357
        quadVertices[2].X = x + w;
 
 
1358
 
 
 
1359
        HUDQuad_Output(HUDFontsImageNumber, quadVertices, colour);
 
 
1360
 
 
 
1361
    } while (--noOfDigits);
 
 
1362
}
 
 
1363
 
 
 
1364
void RenderHUDString(const char *stringPtr, int x,int y,int colour)
 
 
1365
{
 
 
1366
    struct VertexTag quadVertices[4];
 
 
1367
    quadVertices[0].Y = y-1;
 
 
1368
    quadVertices[1].Y = y-1;
 
 
1369
    quadVertices[2].Y = y + HUD_FONT_HEIGHT + 1;
 
 
1370
    quadVertices[3].Y = y + HUD_FONT_HEIGHT + 1;
 
 
1371
 
 
 
1372
    CheckFilteringModeIsCorrect(FILTERING_BILINEAR_OFF);
 
 
1373
 
 
 
1374
    while(*stringPtr)
 
 
1375
    {
 
 
1376
        char c = *stringPtr++;
 
 
1377
        int topLeftU = 1+((c-32) & 15) * 16;
 
 
1378
        int topLeftV = 1+((c-32) >> 4) * 16;
 
 
1379
 
 
 
1380
        quadVertices[0].U = topLeftU - 1;
 
 
1381
        quadVertices[0].V = topLeftV - 1;
 
 
1382
        quadVertices[1].U = topLeftU + HUD_FONT_WIDTH + 1;
 
 
1383
        quadVertices[1].V = topLeftV - 1;
 
 
1384
        quadVertices[2].U = topLeftU + HUD_FONT_WIDTH + 1;
 
 
1385
        quadVertices[2].V = topLeftV + HUD_FONT_HEIGHT + 1;
 
 
1386
        quadVertices[3].U = topLeftU - 1;
 
 
1387
        quadVertices[3].V = topLeftV + HUD_FONT_HEIGHT + 1;
 
 
1388
 
 
 
1389
        quadVertices[0].X = x - 1;
 
 
1390
        quadVertices[3].X = x - 1;
 
 
1391
        quadVertices[1].X = x + HUD_FONT_WIDTH + 1;
 
 
1392
        quadVertices[2].X = x + HUD_FONT_WIDTH + 1;
 
 
1393
 
 
 
1394
        HUDQuad_Output(AAFontImageNumber, quadVertices, colour);
 
 
1395
 
 
 
1396
        x += AAFontWidths[(unsigned char)c];
 
 
1397
    }
 
 
1398
}
 
 
1399
 
 
 
1400
void RenderHUDString_Centred(const char *stringPtr, int centreX, int y, int colour)
 
 
1401
{
 
 
1402
    int x, length = 0;
 
 
1403
    const char *ptr = stringPtr;
 
 
1404
    struct VertexTag quadVertices[4];
 
 
1405
 
 
 
1406
    while(*ptr)
 
 
1407
        length += AAFontWidths[(unsigned char)*ptr++];
 
 
1408
 
 
 
1409
    length = MUL_FIXED(HUDScaleFactor, length);
 
 
1410
 
 
 
1411
    x = centreX-length / 2;
 
 
1412
 
 
 
1413
    quadVertices[0].Y = y - MUL_FIXED(HUDScaleFactor, 1);
 
 
1414
    quadVertices[1].Y = y - MUL_FIXED(HUDScaleFactor, 1);
 
 
1415
    quadVertices[2].Y = y + MUL_FIXED(HUDScaleFactor, HUD_FONT_HEIGHT + 1);
 
 
1416
    quadVertices[3].Y = y + MUL_FIXED(HUDScaleFactor, HUD_FONT_HEIGHT + 1);
 
 
1417
 
 
 
1418
    CheckFilteringModeIsCorrect(FILTERING_BILINEAR_OFF);
 
 
1419
 
 
 
1420
    while(*stringPtr)
 
 
1421
    {
 
 
1422
        char c = *stringPtr++;
 
 
1423
 
 
 
1424
        int topLeftU = 1+((c-32)&15)*16;
 
 
1425
        int topLeftV = 1+((c-32)>>4)*16;
 
 
1426
 
 
 
1427
        quadVertices[0].U = topLeftU - 1;
 
 
1428
        quadVertices[0].V = topLeftV - 1;
 
 
1429
        quadVertices[1].U = topLeftU + HUD_FONT_WIDTH + 1;
 
 
1430
        quadVertices[1].V = topLeftV - 1;
 
 
1431
        quadVertices[2].U = topLeftU + HUD_FONT_WIDTH + 1;
 
 
1432
        quadVertices[2].V = topLeftV + HUD_FONT_HEIGHT + 1;
 
 
1433
        quadVertices[3].U = topLeftU - 1;
 
 
1434
        quadVertices[3].V = topLeftV + HUD_FONT_HEIGHT + 1;
 
 
1435
 
 
 
1436
        quadVertices[0].X = x - MUL_FIXED(HUDScaleFactor,1);
 
 
1437
        quadVertices[3].X = x - MUL_FIXED(HUDScaleFactor,1);
 
 
1438
        quadVertices[1].X = x + MUL_FIXED(HUDScaleFactor,HUD_FONT_WIDTH + 1);
 
 
1439
        quadVertices[2].X = x + MUL_FIXED(HUDScaleFactor,HUD_FONT_WIDTH + 1);
 
 
1440
 
 
 
1441
        HUDQuad_Output(AAFontImageNumber, quadVertices, colour);
 
 
1442
 
 
 
1443
        x += MUL_FIXED(HUDScaleFactor,AAFontWidths[(unsigned char)c]);
 
 
1444
    }
 
 
1445
}
 
 
1446
 
 
 
1447
void RenderStringCentred(const char *stringPtr, int centreX, int y, int colour)
 
 
1448
{
 
 
1449
    int length = 0;
 
 
1450
    const char *ptr = stringPtr;
 
 
1451
 
 
 
1452
    while(*ptr)
 
 
1453
        length += AAFontWidths[(unsigned char)*ptr++];
 
 
1454
 
 
 
1455
    RenderHUDString(stringPtr, centreX-length/2, y, colour);
 
 
1456
}
 
 
1457
 
 
 
1458
void RenderStringVertically(const char *stringPtr, int centreX, int bottomY, int colour)
 
 
1459
{
 
 
1460
    struct VertexTag quadVertices[4];
 
 
1461
    int y = bottomY;
 
 
1462
 
 
 
1463
    quadVertices[0].X = centreX - (HUD_FONT_HEIGHT/2) - 1;
 
 
1464
    quadVertices[1].X = quadVertices[0].X;
 
 
1465
    quadVertices[2].X = quadVertices[0].X+2+HUD_FONT_HEIGHT*1;
 
 
1466
    quadVertices[3].X = quadVertices[2].X;
 
 
1467
 
 
 
1468
    CheckFilteringModeIsCorrect(FILTERING_BILINEAR_OFF);
 
 
1469
 
 
 
1470
    while(*stringPtr)
 
 
1471
    {
 
 
1472
        char c = *stringPtr++;
 
 
1473
 
 
 
1474
        int topLeftU = 1+((c-32)&15)*16;
 
 
1475
        int topLeftV = 1+((c-32)>>4)*16;
 
 
1476
 
 
 
1477
        quadVertices[0].U = topLeftU - 1;
 
 
1478
        quadVertices[0].V = topLeftV - 1;
 
 
1479
        quadVertices[1].U = topLeftU + HUD_FONT_WIDTH;
 
 
1480
        quadVertices[1].V = topLeftV - 1;
 
 
1481
        quadVertices[2].U = topLeftU + HUD_FONT_WIDTH;
 
 
1482
        quadVertices[2].V = topLeftV + HUD_FONT_HEIGHT + 1;
 
 
1483
        quadVertices[3].U = topLeftU - 1;
 
 
1484
        quadVertices[3].V = topLeftV + HUD_FONT_HEIGHT + 1;
 
 
1485
 
 
 
1486
        quadVertices[0].Y = y ;
 
 
1487
        quadVertices[1].Y = y - HUD_FONT_WIDTH*1 -1;
 
 
1488
        quadVertices[2].Y = y - HUD_FONT_WIDTH*1 -1;
 
 
1489
        quadVertices[3].Y = y ;
 
 
1490
 
 
 
1491
        HUDQuad_Output(AAFontImageNumber, quadVertices, colour);
 
 
1492
 
 
 
1493
           y -= AAFontWidths[(unsigned char)c];
 
 
1494
    }
 
 
1495
}
 
 
1496
 
 
 
1497
int RenderSmallMenuText(const char *textPtr, int x, int y, int alpha, enum MENUFORMAT_ID format) 
 
 
1498
{
 
 
1499
    switch(format)
 
 
1500
    {
 
 
1501
        case MENUFORMAT_LEFTJUSTIFIED:
 
 
1502
        break; // supplied x is correct
 
 
1503
        case MENUFORMAT_RIGHTJUSTIFIED:
 
 
1504
        {
 
 
1505
            int length = 0;
 
 
1506
            const char *ptr = textPtr;
 
 
1507
 
 
 
1508
            while(*ptr)
 
 
1509
            {
 
 
1510
                int index  = *ptr++;
 
 
1511
                length += AAFontWidths[index];
 
 
1512
            }
 
 
1513
 
 
 
1514
            x -= length;
 
 
1515
        }
 
 
1516
        break;
 
 
1517
        case MENUFORMAT_CENTREJUSTIFIED:
 
 
1518
        {
 
 
1519
            int length = 0;
 
 
1520
            const char *ptr = textPtr;
 
 
1521
 
 
 
1522
            while(*ptr)
 
 
1523
            {
 
 
1524
                int index  = *ptr++;
 
 
1525
                length+=AAFontWidths[index];
 
 
1526
            }
 
 
1527
 
 
 
1528
            x -= length/2;
 
 
1529
        }    
 
 
1530
        break;
 
 
1531
        default:
 
 
1532
            fprintf(stderr, "RenderSmallMenuText: UNKNOWN TEXT FORMAT\n");
 
 
1533
            exit(4);
 
 
1534
    }
 
 
1535
 
 
 
1536
    //assert(x > 0);
 
 
1537
 
 
 
1538
    {
 
 
1539
        unsigned int colour = alpha >> 8;
 
 
1540
 
 
 
1541
        if (colour > 255)
 
 
1542
            colour = 255;
 
 
1543
 
 
 
1544
        colour = (colour << 24) + 0xffffff;
 
 
1545
 
 
 
1546
        RenderHUDString(textPtr, x, y, colour);
 
 
1547
    }
 
 
1548
 
 
 
1549
return x;
 
 
1550
}
 
 
1551
 
 
 
1552
int RenderSmallMenuText_Coloured(const char *textPtr, int x, int y, int alpha, enum MENUFORMAT_ID format, int red, int green, int blue)
 
 
1553
{
 
 
1554
    switch(format)
 
 
1555
    {
 
 
1556
        case MENUFORMAT_LEFTJUSTIFIED:
 
 
1557
            // supplied x is correct
 
 
1558
        break;
 
 
1559
        case MENUFORMAT_RIGHTJUSTIFIED:
 
 
1560
        {
 
 
1561
            int length = 0;
 
 
1562
            const char *ptr = textPtr;
 
 
1563
 
 
 
1564
            while(*ptr)
 
 
1565
            {
 
 
1566
                int index  = *ptr++;
 
 
1567
                length+=AAFontWidths[index];
 
 
1568
            }
 
 
1569
 
 
 
1570
            x -= length;
 
 
1571
        }
 
 
1572
        break;
 
 
1573
        case MENUFORMAT_CENTREJUSTIFIED:
 
 
1574
        {
 
 
1575
            int length = 0;
 
 
1576
            const char *ptr = textPtr;
 
 
1577
 
 
 
1578
            while(*ptr)
 
 
1579
            {
 
 
1580
                int index  = *ptr++;
 
 
1581
                length+=AAFontWidths[index];
 
 
1582
            }
 
 
1583
 
 
 
1584
            x -= length/2;
 
 
1585
        }    
 
 
1586
        break;
 
 
1587
        default:
 
 
1588
            fprintf(stderr, "RenderSmallMenuText_Coloured: UNKNOWN TEXT FORMAT\n");
 
 
1589
            exit(3);
 
 
1590
    }
 
 
1591
 
 
 
1592
    {
 
 
1593
        unsigned int colour = alpha>>8;
 
 
1594
 
 
 
1595
        if (colour>255)
 
 
1596
            colour = 255;
 
 
1597
 
 
 
1598
        colour = (colour<<24);
 
 
1599
        colour += MUL_FIXED(red,255)<<16;
 
 
1600
        colour += MUL_FIXED(green,255)<<8;
 
 
1601
        colour += MUL_FIXED(blue,255);
 
 
1602
        RenderHUDString(textPtr,x,y,colour);
 
 
1603
    }
 
 
1604
 
 
 
1605
return x;
 
 
1606
}
 
 
1607
 
 
 
1608
void DrawRectangle(int x, int y, int w, int h, int alpha)
 
 
1609
{
 
 
1610
    struct VertexTag quadVertices[4];
 
 
1611
    unsigned int colour = alpha>>8;
 
 
1612
 
 
 
1613
    if (colour > 255)
 
 
1614
        colour = 255;
 
 
1615
 
 
 
1616
    colour = (colour << 24) + 0xffffff;
 
 
1617
 
 
 
1618
    quadVertices[0].Y = y;
 
 
1619
    quadVertices[1].Y = y;
 
 
1620
    quadVertices[2].Y = y + 6;
 
 
1621
    quadVertices[3].Y = y + 6;
 
 
1622
 
 
 
1623
    CheckFilteringModeIsCorrect(FILTERING_BILINEAR_OFF);
 
 
1624
    /* top left corner */
 
 
1625
    {
 
 
1626
        int topLeftU = 1;
 
 
1627
        int topLeftV = 238;
 
 
1628
 
 
 
1629
        quadVertices[0].U = topLeftU;
 
 
1630
        quadVertices[0].V = topLeftV;
 
 
1631
        quadVertices[1].U = topLeftU + 6;
 
 
1632
        quadVertices[1].V = topLeftV;
 
 
1633
        quadVertices[2].U = topLeftU + 6;
 
 
1634
        quadVertices[2].V = topLeftV + 6;
 
 
1635
        quadVertices[3].U = topLeftU;
 
 
1636
        quadVertices[3].V = topLeftV + 6;
 
 
1637
 
 
 
1638
        quadVertices[0].X = x;
 
 
1639
        quadVertices[3].X = x;
 
 
1640
        quadVertices[1].X = x + 6;
 
 
1641
        quadVertices[2].X = x + 6;
 
 
1642
 
 
 
1643
        HUDQuad_Output(AAFontImageNumber, quadVertices, colour);
 
 
1644
    }
 
 
1645
    /* top */
 
 
1646
    {
 
 
1647
        int topLeftU = 9;
 
 
1648
        int topLeftV = 238;
 
 
1649
 
 
 
1650
        quadVertices[0].U = topLeftU;
 
 
1651
        quadVertices[0].V = topLeftV;
 
 
1652
        quadVertices[1].U = topLeftU;
 
 
1653
        quadVertices[1].V = topLeftV;
 
 
1654
        quadVertices[2].U = topLeftU;
 
 
1655
        quadVertices[2].V = topLeftV + 6;
 
 
1656
        quadVertices[3].U = topLeftU;
 
 
1657
        quadVertices[3].V = topLeftV + 6;
 
 
1658
 
 
 
1659
        quadVertices[0].X = x+6;
 
 
1660
        quadVertices[3].X = x+6;
 
 
1661
        quadVertices[1].X = x+6 + w-12;
 
 
1662
        quadVertices[2].X = x+6 + w-12;
 
 
1663
 
 
 
1664
        HUDQuad_Output(AAFontImageNumber, quadVertices, colour);
 
 
1665
    }
 
 
1666
    /* top right corner */
 
 
1667
    {
 
 
1668
        int topLeftU = 11;
 
 
1669
        int topLeftV = 238;
 
 
1670
 
 
 
1671
        quadVertices[0].U = topLeftU;
 
 
1672
        quadVertices[0].V = topLeftV;
 
 
1673
        quadVertices[1].U = topLeftU + 6;
 
 
1674
        quadVertices[1].V = topLeftV;
 
 
1675
        quadVertices[2].U = topLeftU + 6;
 
 
1676
        quadVertices[2].V = topLeftV + 6;
 
 
1677
        quadVertices[3].U = topLeftU;
 
 
1678
        quadVertices[3].V = topLeftV + 6;
 
 
1679
 
 
 
1680
        quadVertices[0].X = x + w - 6;
 
 
1681
        quadVertices[3].X = x + w - 6;
 
 
1682
        quadVertices[1].X = x + w;
 
 
1683
        quadVertices[2].X = x + w;
 
 
1684
 
 
 
1685
        HUDQuad_Output(AAFontImageNumber, quadVertices, colour);
 
 
1686
    }
 
 
1687
    quadVertices[0].Y = y + 6;
 
 
1688
    quadVertices[1].Y = y + 6;
 
 
1689
    quadVertices[2].Y = y + h - 6;
 
 
1690
    quadVertices[3].Y = y + h - 6;
 
 
1691
    /* right */
 
 
1692
    {
 
 
1693
        int topLeftU = 1;
 
 
1694
        int topLeftV = 246;
 
 
1695
 
 
 
1696
        quadVertices[0].U = topLeftU;
 
 
1697
        quadVertices[0].V = topLeftV;
 
 
1698
        quadVertices[1].U = topLeftU + 6;
 
 
1699
        quadVertices[1].V = topLeftV;
 
 
1700
        quadVertices[2].U = topLeftU + 6;
 
 
1701
        quadVertices[2].V = topLeftV;
 
 
1702
        quadVertices[3].U = topLeftU;
 
 
1703
        quadVertices[3].V = topLeftV;
 
 
1704
 
 
 
1705
        HUDQuad_Output(AAFontImageNumber, quadVertices, colour);
 
 
1706
    }
 
 
1707
    /* left */
 
 
1708
    {
 
 
1709
        int topLeftU = 1;
 
 
1710
        int topLeftV = 246;
 
 
1711
 
 
 
1712
        quadVertices[0].U = topLeftU;
 
 
1713
        quadVertices[0].V = topLeftV;
 
 
1714
        quadVertices[1].U = topLeftU + 6;
 
 
1715
        quadVertices[1].V = topLeftV;
 
 
1716
        quadVertices[2].U = topLeftU + 6;
 
 
1717
        quadVertices[2].V = topLeftV;
 
 
1718
        quadVertices[3].U = topLeftU;
 
 
1719
        quadVertices[3].V = topLeftV;
 
 
1720
 
 
 
1721
        quadVertices[0].X = x;
 
 
1722
        quadVertices[3].X = x;
 
 
1723
        quadVertices[1].X = x + 6;
 
 
1724
        quadVertices[2].X = x + 6;
 
 
1725
 
 
 
1726
        HUDQuad_Output(AAFontImageNumber, quadVertices, colour);
 
 
1727
    }
 
 
1728
    quadVertices[0].Y = y + h - 6;
 
 
1729
    quadVertices[1].Y = y + h - 6;
 
 
1730
    quadVertices[2].Y = y + h;
 
 
1731
    quadVertices[3].Y = y + h;
 
 
1732
    /* bottom left corner */
 
 
1733
    {
 
 
1734
        int topLeftU = 1;
 
 
1735
        int topLeftV = 248;
 
 
1736
 
 
 
1737
        quadVertices[0].U = topLeftU;
 
 
1738
        quadVertices[0].V = topLeftV;
 
 
1739
        quadVertices[1].U = topLeftU + 6;
 
 
1740
        quadVertices[1].V = topLeftV;
 
 
1741
        quadVertices[2].U = topLeftU + 6;
 
 
1742
        quadVertices[2].V = topLeftV + 6;
 
 
1743
        quadVertices[3].U = topLeftU;
 
 
1744
        quadVertices[3].V = topLeftV + 6;
 
 
1745
 
 
 
1746
        quadVertices[0].X = x;
 
 
1747
        quadVertices[3].X = x;
 
 
1748
        quadVertices[1].X = x + 6;
 
 
1749
        quadVertices[2].X = x + 6;
 
 
1750
 
 
 
1751
        HUDQuad_Output(AAFontImageNumber, quadVertices, colour);
 
 
1752
    }
 
 
1753
    /* bottom */
 
 
1754
    {
 
 
1755
        int topLeftU = 9;
 
 
1756
        int topLeftV = 238;
 
 
1757
 
 
 
1758
        quadVertices[0].U = topLeftU;
 
 
1759
        quadVertices[0].V = topLeftV;
 
 
1760
        quadVertices[1].U = topLeftU;
 
 
1761
        quadVertices[1].V = topLeftV;
 
 
1762
        quadVertices[2].U = topLeftU;
 
 
1763
        quadVertices[2].V = topLeftV + 6;
 
 
1764
        quadVertices[3].U = topLeftU;
 
 
1765
        quadVertices[3].V = topLeftV + 6;
 
 
1766
 
 
 
1767
        quadVertices[0].X = x+6;
 
 
1768
        quadVertices[3].X = x+6;
 
 
1769
        quadVertices[1].X = x+6 + w-12;
 
 
1770
        quadVertices[2].X = x+6 + w-12;
 
 
1771
 
 
 
1772
        HUDQuad_Output(AAFontImageNumber, quadVertices, colour);
 
 
1773
    }
 
 
1774
    /* bottom right corner */
 
 
1775
    {
 
 
1776
        int topLeftU = 11;
 
 
1777
        int topLeftV = 248;
 
 
1778
 
 
 
1779
        quadVertices[0].U = topLeftU;
 
 
1780
        quadVertices[0].V = topLeftV;
 
 
1781
        quadVertices[1].U = topLeftU + 6;
 
 
1782
        quadVertices[1].V = topLeftV;
 
 
1783
        quadVertices[2].U = topLeftU + 6;
 
 
1784
        quadVertices[2].V = topLeftV + 6;
 
 
1785
        quadVertices[3].U = topLeftU;
 
 
1786
        quadVertices[3].V = topLeftV + 6;
 
 
1787
 
 
 
1788
        quadVertices[0].X = x + w - 6;
 
 
1789
        quadVertices[3].X = x + w - 6;
 
 
1790
        quadVertices[1].X = x + w;
 
 
1791
        quadVertices[2].X = x + w;
 
 
1792
 
 
 
1793
        HUDQuad_Output(AAFontImageNumber, quadVertices, colour);
 
 
1794
    }
 
 
1795
}
 
 
1796
 
 
 
1797
void DrawSliderBar(int x, int y, int alpha)
 
 
1798
{
 
 
1799
    struct VertexTag quadVertices[4];
 
 
1800
    int sliderHeight = 11;
 
 
1801
    unsigned int colour = alpha>>8;
 
 
1802
 
 
 
1803
    if (colour > 255)
 
 
1804
        colour = 255;
 
 
1805
 
 
 
1806
    colour = (colour << 24)+0xffffff;
 
 
1807
 
 
 
1808
    quadVertices[0].Y = y;
 
 
1809
    quadVertices[1].Y = y;
 
 
1810
    quadVertices[2].Y = y + sliderHeight;
 
 
1811
    quadVertices[3].Y = y + sliderHeight;
 
 
1812
 
 
 
1813
    CheckFilteringModeIsCorrect(FILTERING_BILINEAR_OFF);
 
 
1814
    {
 
 
1815
        int topLeftU = 1;
 
 
1816
        int topLeftV = 68;
 
 
1817
 
 
 
1818
        quadVertices[0].U = topLeftU;
 
 
1819
        quadVertices[0].V = topLeftV;
 
 
1820
        quadVertices[1].U = topLeftU + 2;
 
 
1821
        quadVertices[1].V = topLeftV;
 
 
1822
        quadVertices[2].U = topLeftU + 2;
 
 
1823
        quadVertices[2].V = topLeftV + sliderHeight;
 
 
1824
        quadVertices[3].U = topLeftU;
 
 
1825
        quadVertices[3].V = topLeftV + sliderHeight;
 
 
1826
 
 
 
1827
        quadVertices[0].X = x;
 
 
1828
        quadVertices[3].X = x;
 
 
1829
        quadVertices[1].X = x + 2;
 
 
1830
        quadVertices[2].X = x + 2;
 
 
1831
 
 
 
1832
        HUDQuad_Output(HUDFontsImageNumber, quadVertices, colour );
 
 
1833
    }
 
 
1834
    {
 
 
1835
        int topLeftU = 7;
 
 
1836
        int topLeftV = 68;
 
 
1837
 
 
 
1838
        quadVertices[0].U = topLeftU;
 
 
1839
        quadVertices[0].V = topLeftV;
 
 
1840
        quadVertices[1].U = topLeftU + 2;
 
 
1841
        quadVertices[1].V = topLeftV;
 
 
1842
        quadVertices[2].U = topLeftU + 2;
 
 
1843
        quadVertices[2].V = topLeftV + sliderHeight;
 
 
1844
        quadVertices[3].U = topLeftU;
 
 
1845
        quadVertices[3].V = topLeftV + sliderHeight;
 
 
1846
 
 
 
1847
        quadVertices[0].X = x+213+2;
 
 
1848
        quadVertices[3].X = x+213+2;
 
 
1849
        quadVertices[1].X = x+2 +213+2;
 
 
1850
        quadVertices[2].X = x+2 +213+2;
 
 
1851
 
 
 
1852
        HUDQuad_Output(HUDFontsImageNumber, quadVertices, colour );
 
 
1853
    }
 
 
1854
    quadVertices[2].Y = y + 2;
 
 
1855
    quadVertices[3].Y = y + 2;
 
 
1856
 
 
 
1857
    {
 
 
1858
        int topLeftU = 5;
 
 
1859
        int topLeftV = 77;
 
 
1860
 
 
 
1861
        quadVertices[0].U = topLeftU;
 
 
1862
        quadVertices[0].V = topLeftV;
 
 
1863
        quadVertices[1].U = topLeftU;
 
 
1864
        quadVertices[1].V = topLeftV;
 
 
1865
        quadVertices[2].U = topLeftU;
 
 
1866
        quadVertices[2].V = topLeftV + 2;
 
 
1867
        quadVertices[3].U = topLeftU;
 
 
1868
        quadVertices[3].V = topLeftV + 2;
 
 
1869
 
 
 
1870
        quadVertices[0].X = x + 2;
 
 
1871
        quadVertices[3].X = x + 2;
 
 
1872
        quadVertices[1].X = x + 215;
 
 
1873
        quadVertices[2].X = x + 215;
 
 
1874
 
 
 
1875
        HUDQuad_Output(HUDFontsImageNumber, quadVertices, colour );
 
 
1876
    }
 
 
1877
    quadVertices[0].Y = y + 9;
 
 
1878
    quadVertices[1].Y = y + 9;
 
 
1879
    quadVertices[2].Y = y + 11;
 
 
1880
    quadVertices[3].Y = y + 11;
 
 
1881
 
 
 
1882
    {
 
 
1883
        int topLeftU = 5;
 
 
1884
        int topLeftV = 77;
 
 
1885
 
 
 
1886
        quadVertices[0].U = topLeftU;
 
 
1887
        quadVertices[0].V = topLeftV;
 
 
1888
        quadVertices[1].U = topLeftU;
 
 
1889
        quadVertices[1].V = topLeftV;
 
 
1890
        quadVertices[2].U = topLeftU;
 
 
1891
        quadVertices[2].V = topLeftV + 2;
 
 
1892
        quadVertices[3].U = topLeftU;
 
 
1893
        quadVertices[3].V = topLeftV + 2;
 
 
1894
 
 
 
1895
        quadVertices[0].X = x + 2;
 
 
1896
        quadVertices[3].X = x + 2;
 
 
1897
        quadVertices[1].X = x + 215;
 
 
1898
        quadVertices[2].X = x + 215;
 
 
1899
 
 
 
1900
        HUDQuad_Output(HUDFontsImageNumber, quadVertices, colour );
 
 
1901
    }
 
 
1902
}
 
 
1903
 
 
 
1904
void DrawSlider(int x, int y, int alpha)
 
 
1905
{
 
 
1906
    struct VertexTag quadVertices[4];
 
 
1907
    int sliderHeight = 5;
 
 
1908
    unsigned int colour = alpha>>8;
 
 
1909
 
 
 
1910
    if (colour > 255)
 
 
1911
        colour = 255;
 
 
1912
 
 
 
1913
    colour = (colour << 24) + 0xffffff;
 
 
1914
 
 
 
1915
    quadVertices[0].Y = y;
 
 
1916
    quadVertices[1].Y = y;
 
 
1917
    quadVertices[2].Y = y + sliderHeight;
 
 
1918
    quadVertices[3].Y = y + sliderHeight;
 
 
1919
 
 
 
1920
    CheckFilteringModeIsCorrect(FILTERING_BILINEAR_OFF);
 
 
1921
 
 
 
1922
    {
 
 
1923
        int topLeftU = 11;
 
 
1924
        int topLeftV = 74;
 
 
1925
 
 
 
1926
        quadVertices[0].U = topLeftU;
 
 
1927
        quadVertices[0].V = topLeftV;
 
 
1928
        quadVertices[1].U = topLeftU + 9;
 
 
1929
        quadVertices[1].V = topLeftV;
 
 
1930
        quadVertices[2].U = topLeftU + 9;
 
 
1931
        quadVertices[2].V = topLeftV + sliderHeight;
 
 
1932
        quadVertices[3].U = topLeftU;
 
 
1933
        quadVertices[3].V = topLeftV + sliderHeight;
 
 
1934
 
 
 
1935
        quadVertices[0].X = x;
 
 
1936
        quadVertices[3].X = x;
 
 
1937
        quadVertices[1].X = x + 9;
 
 
1938
        quadVertices[2].X = x + 9;
 
 
1939
 
 
 
1940
        HUDQuad_Output(HUDFontsImageNumber, quadVertices, colour );
 
 
1941
    }
 
 
1942
}
 
 
1943
 
 
 
1944
void DrawColourBar(int yTop, int yBottom, int rScale, int gScale, int bScale)
 
 
1945
{
 
 
1946
    GLfloat x[4], y[4];
 
 
1947
    int i;
 
 
1948
 
 
 
1949
    CheckTranslucencyModeIsCorrect(TRANSLUCENCY_OFF);
 
 
1950
    CheckBoundTextureIsCorrect(NULL);
 
 
1951
 
 
 
1952
    glBegin(GL_QUADS);
 
 
1953
    for (i = 0; i < 255; ) 
 
 
1954
    {
 
 
1955
        unsigned int c = GammaValues[i];
 
 
1956
 
 
 
1957
        glColor4ub(MUL_FIXED(c, rScale), MUL_FIXED(c,gScale), MUL_FIXED(c,bScale), 0);
 
 
1958
 
 
 
1959
        x[0] = (ScreenDescriptorBlock.SDB_Width * i)/255;
 
 
1960
        x[0] =  (x[0] - ScreenDescriptorBlock.SDB_CentreX) / ScreenDescriptorBlock.SDB_CentreX;
 
 
1961
        y[0] = yTop;
 
 
1962
        y[0] = -(y[0] - ScreenDescriptorBlock.SDB_CentreY) / ScreenDescriptorBlock.SDB_CentreY;
 
 
1963
 
 
 
1964
        x[1] = (ScreenDescriptorBlock.SDB_Width * i)/255;
 
 
1965
        x[1] =  (x[1] - ScreenDescriptorBlock.SDB_CentreX) / ScreenDescriptorBlock.SDB_CentreX;
 
 
1966
        y[1] = yBottom;
 
 
1967
        y[1] = -(y[1] - ScreenDescriptorBlock.SDB_CentreY) / ScreenDescriptorBlock.SDB_CentreY;
 
 
1968
 
 
 
1969
        i++;
 
 
1970
        c = GammaValues[i];
 
 
1971
 
 
 
1972
        glColor4ub(MUL_FIXED(c,rScale), MUL_FIXED(c,gScale), MUL_FIXED(c,bScale), 0);
 
 
1973
 
 
 
1974
        x[2] = (ScreenDescriptorBlock.SDB_Width * i)/255;
 
 
1975
        x[2] =  (x[2] - ScreenDescriptorBlock.SDB_CentreX) / ScreenDescriptorBlock.SDB_CentreX;
 
 
1976
        y[2] = yBottom;
 
 
1977
        y[2] = -(y[2] - ScreenDescriptorBlock.SDB_CentreY) / ScreenDescriptorBlock.SDB_CentreY;
 
 
1978
 
 
 
1979
        x[3] = (ScreenDescriptorBlock.SDB_Width * i)/255;
 
 
1980
        x[3] =  (x[3] - ScreenDescriptorBlock.SDB_CentreX) / ScreenDescriptorBlock.SDB_CentreX;
 
 
1981
        y[3] = yTop;
 
 
1982
        y[3] = -(y[3] - ScreenDescriptorBlock.SDB_CentreY) / ScreenDescriptorBlock.SDB_CentreY;
 
 
1983
 
 
 
1984
        glVertex3f(x[0], y[0], -1.0f);
 
 
1985
        glVertex3f(x[1], y[1], -1.0f);
 
 
1986
        glVertex3f(x[2], y[2], -1.0f);
 
 
1987
        glVertex3f(x[3], y[3], -1.0f);
 
 
1988
    }
 
 
1989
    glEnd();
 
 
1990
}
 
 
1991
 
 
 
1992
void DrawParticle_Rain(PARTICLE *particlePtr, VECTORCH *prevPositionPtr)
 
 
1993
{
 
 
1994
    VECTORCH vertices[3];
 
 
1995
 
 
 
1996
    vertices[0] = *prevPositionPtr;
 
 
1997
 
 
 
1998
    /* translate second vertex into view space */
 
 
1999
    TranslatePointIntoViewspace(&vertices[0]);
 
 
2000
 
 
 
2001
    /* is particle within normal view frustrum ? */
 
 
2002
    if((-vertices[0].vx <= vertices[0].vz)
 
 
2003
    &&(vertices[0].vx <= vertices[0].vz)
 
 
2004
    &&(-vertices[0].vy <= vertices[0].vz)
 
 
2005
    &&(vertices[0].vy <= vertices[0].vz))
 
 
2006
    {                                                    
 
 
2007
        vertices[1] = particlePtr->Position;
 
 
2008
        vertices[2] = particlePtr->Position;
 
 
2009
        vertices[1].vx += particlePtr->Offset.vx;
 
 
2010
        vertices[2].vx -= particlePtr->Offset.vx;
 
 
2011
        vertices[1].vz += particlePtr->Offset.vz;
 
 
2012
        vertices[2].vz -= particlePtr->Offset.vz;
 
 
2013
 
 
 
2014
        /* translate particle into view space */
 
 
2015
        TranslatePointIntoViewspace(&vertices[1]);
 
 
2016
        TranslatePointIntoViewspace(&vertices[2]);
 
 
2017
 
 
 
2018
        float ZNear = (float) (VDB_ClipZ * GlobalScale);
 
 
2019
 
 
 
2020
        CheckTriangleBuffer(3, 0, 0, 0, NULL, TRANSLUCENCY_NORMAL);
 
 
2021
 
 
 
2022
        int i;
 
 
2023
        for (i = 0; i < 3; i++)
 
 
2024
        {
 
 
2025
            GLfloat xf, yf, zf, rhw;
 
 
2026
 
 
 
2027
            xf =  ((float)vertices[i].vx*((float)Global_VDB.VDB_ProjX+1.0f))/((float)vertices[i].vz*(float)ScreenDescriptorBlock.SDB_CentreX);
 
 
2028
            yf = -((float)vertices[i].vy*((float)Global_VDB.VDB_ProjY+1.0f))/((float)vertices[i].vz*(float)ScreenDescriptorBlock.SDB_CentreY);
 
 
2029
 
 
 
2030
            zf = 1.0f - 2.0f*ZNear/(float)vertices[i].vz;
 
 
2031
            rhw = 1.0f / (float)vertices[i].vz;
 
 
2032
 
 
 
2033
            varrp->v[0] = xf/rhw;
 
 
2034
            varrp->v[1] = yf/rhw;
 
 
2035
            varrp->v[2] = zf/rhw;
 
 
2036
            varrp->v[3] = 1.0f/rhw;
 
 
2037
 
 
 
2038
            if (!i)
 
 
2039
            {
 
 
2040
                varrp->c[0] = 0;
 
 
2041
                varrp->c[1] = 255;
 
 
2042
                varrp->c[2] = 255;
 
 
2043
                varrp->c[3] = 32;
 
 
2044
            }
 
 
2045
            else
 
 
2046
            {
 
 
2047
                varrp->c[0] = 255;
 
 
2048
                varrp->c[1] = 255;
 
 
2049
                varrp->c[2] = 255;
 
 
2050
                varrp->c[3] = 32;
 
 
2051
            }
 
 
2052
            varrp++;
 
 
2053
            varrc++;
 
 
2054
        }
 
 
2055
    }
 
 
2056
}
 
 
2057
 
 
 
2058
void DrawWaterFall(int xOrigin, int yOrigin, int zOrigin)
 
 
2059
{
 
 
2060
    int i;
 
 
2061
 
 
 
2062
    int noRequired = MUL_FIXED(250, NormalFrameTime);
 
 
2063
 
 
 
2064
    for (i=0; i < noRequired; i++)
 
 
2065
    {
 
 
2066
        VECTORCH velocity;
 
 
2067
        VECTORCH position;
 
 
2068
        position.vx = xOrigin;
 
 
2069
        position.vy = yOrigin-(FastRandom()&511);//+45*MeshXScale;
 
 
2070
        position.vz = zOrigin+(FastRandom()%(15*MeshZScale));
 
 
2071
 
 
 
2072
        velocity.vy = (FastRandom()&511)+512;//-((FastRandom()&1023)+2048)*8;
 
 
2073
        velocity.vx = ((FastRandom()&511)+256)*2;
 
 
2074
        velocity.vz = 0;//-((FastRandom()&511))*8;
 
 
2075
        MakeParticle(&position, &velocity, PARTICLE_WATERFALLSPRAY);
 
 
2076
    }
 
 
2077
}
 
 
2078
 
 
 
2079
void DrawMoltenMetalMesh_Unclipped()
 
 
2080
{
 
 
2081
    float ZNear = (float) (VDB_ClipZ * GlobalScale);
 
 
2082
 
 
 
2083
    VECTORCH *point = MeshVertex;
 
 
2084
    VECTORCH *pointWS = MeshWorldVertex;
 
 
2085
 
 
 
2086
    int i, x, y, z;
 
 
2087
    int start;
 
 
2088
 
 
 
2089
    CheckTriangleBuffer(256, 0, 450, 0, (struct TEXTURE *)-1, -1);
 
 
2090
 
 
 
2091
    start = varrc;
 
 
2092
 
 
 
2093
    for (i=0; i < 256; i++)
 
 
2094
    {
 
 
2095
        GLfloat xf, yf, zf;
 
 
2096
        GLfloat sf, tf, rhw;
 
 
2097
        int r, g, b, a;
 
 
2098
 
 
 
2099
        if (point->vz < 1)
 
 
2100
            point->vz = 1;
 
 
2101
 
 
 
2102
        xf =  ((float)point->vx*((float)Global_VDB.VDB_ProjX+1.0f))/((float)point->vz*(float)ScreenDescriptorBlock.SDB_CentreX);
 
 
2103
        yf = -((float)point->vy*((float)Global_VDB.VDB_ProjY+1.0f))/((float)point->vz*(float)ScreenDescriptorBlock.SDB_CentreY);
 
 
2104
 
 
 
2105
        z = point->vz;
 
 
2106
        rhw = 1.0f / (float)point->vz;
 
 
2107
        zf = 1.0f - 2.0f*ZNear/(float)z;
 
 
2108
 
 
 
2109
        sf = pointWS->vx*WaterUScale+(1.0f/256.0f);
 
 
2110
        tf = pointWS->vy*WaterVScale+(1.0f/256.0f);
 
 
2111
 
 
 
2112
        b = (MeshVertexColour[i] >> 0)  & 0xFF;
 
 
2113
        g = (MeshVertexColour[i] >> 8)  & 0xFF;
 
 
2114
        r = (MeshVertexColour[i] >> 16) & 0xFF;
 
 
2115
        a = (MeshVertexColour[i] >> 24) & 0xFF;
 
 
2116
 
 
 
2117
        varrp->v[0] = xf/rhw;
 
 
2118
        varrp->v[1] = yf/rhw;
 
 
2119
        varrp->v[2] = zf/rhw;
 
 
2120
        varrp->v[3] = 1.0f/rhw;
 
 
2121
 
 
 
2122
        varrp->t[0] = sf;
 
 
2123
        varrp->t[1] = tf;
 
 
2124
 
 
 
2125
        varrp->c[0] = r;
 
 
2126
        varrp->c[1] = g;
 
 
2127
        varrp->c[2] = b;
 
 
2128
        varrp->c[3] = a;
 
 
2129
 
 
 
2130
        varrp++;
 
 
2131
        varrc++;
 
 
2132
 
 
 
2133
        point++;
 
 
2134
        pointWS++;
 
 
2135
    }
 
 
2136
 
 
 
2137
    /* CONSTRUCT POLYS */
 
 
2138
 
 
 
2139
    for (x = 0; x < 15; x++)
 
 
2140
    {
 
 
2141
        for(y = 0; y < 15; y++)
 
 
2142
        {
 
 
2143
            tarrp[0].a = start+0+x+(16*y);
 
 
2144
            tarrp[0].b = start+1+x+(16*y);
 
 
2145
            tarrp[0].c = start+16+x+(16*y);
 
 
2146
 
 
 
2147
            tarrp[1].a = start+1+x+(16*y);
 
 
2148
            tarrp[1].b = start+17+x+(16*y);
 
 
2149
            tarrp[1].c = start+16+x+(16*y);
 
 
2150
 
 
 
2151
            tarrp += 2;
 
 
2152
            tarrc += 2;
 
 
2153
        }
 
 
2154
    }
 
 
2155
}
 
 
2156
 
 
 
2157
static void DrawWaterPatch(int xOrigin, int yOrigin, int zOrigin)
 
 
2158
{
 
 
2159
    int i=0;
 
 
2160
    int x;
 
 
2161
    int offset;
 
 
2162
 
 
 
2163
    for (x=0; x < 16; x++)
 
 
2164
    {
 
 
2165
        int z;
 
 
2166
        for(z=0; z < 16; z++)
 
 
2167
        {
 
 
2168
            VECTORCH *point = &MeshVertex[i];
 
 
2169
 
 
 
2170
            point->vx = xOrigin+(x*MeshXScale)/15;
 
 
2171
            point->vz = zOrigin+(z*MeshZScale)/15;
 
 
2172
 
 
 
2173
            offset = 0;
 
 
2174
         #if 1
 
 
2175
            /* basic noise ripples */
 
 
2176
//             offset = MUL_FIXED(32,GetSin(  (point->vx+point->vz+CloakingPhase)&4095 ) );
 
 
2177
//             offset += MUL_FIXED(16,GetSin(  (point->vx-point->vz*2+CloakingPhase/2)&4095 ) );
 
 
2178
            {
 
 
2179
                 offset += EffectOfRipples(point);
 
 
2180
            }
 
 
2181
        #endif
 
 
2182
    //        if (offset > 450) offset = 450;
 
 
2183
    //        if (offset < -450) offset = -450;
 
 
2184
            point->vy = yOrigin+offset;
 
 
2185
 
 
 
2186
            {
 
 
2187
                int alpha = 128-offset/4;
 
 
2188
        //        if (alpha > 255) alpha = 255;
 
 
2189
        //        if (alpha < 128) alpha = 128;
 
 
2190
 
 
 
2191
                switch (PlayerStatus.VisionMode)
 
 
2192
                {
 
 
2193
                    default:
 
 
2194
                    case VISION_MODE_NORMAL:
 
 
2195
                    {
 
 
2196
//                        MeshVertexColour[i] = RGBA_MAKE(10,51,28,alpha);
 
 
2197
                        MeshVertexColour[i] = RGBA_MAKE(255,255,255,alpha);
 
 
2198
                        #if 0
 
 
2199
                        #if 1
 
 
2200
                        VECTORCH pos = {24087,yOrigin,39165};
 
 
2201
                        int c = (8191-VectorDistance(&pos,point));
 
 
2202
                        if (c < 0) c=0;
 
 
2203
                        else
 
 
2204
                        {
 
 
2205
                            int s = GetSin((CloakingPhase/2)&4095);
 
 
2206
                            s = MUL_FIXED(s,s)/64;
 
 
2207
                            c = MUL_FIXED(s,c);
 
 
2208
                        }
 
 
2209
                        MeshVertexSpecular[i] = (c<<16)+(((c/4)<<8)&0xff00) + (c/4);
 
 
2210
                        #else 
 
 
2211
                        if (!(FastRandom()&1023))
 
 
2212
                            MeshVertexSpecular[i] = 0xc04040;
 
 
2213
                        else
 
 
2214
                            MeshVertexSpecular[i] = 0;
 
 
2215
                        #endif
 
 
2216
                        #endif
 
 
2217
                        break;
 
 
2218
                    }
 
 
2219
                    case VISION_MODE_IMAGEINTENSIFIER:
 
 
2220
                    {
 
 
2221
                        MeshVertexColour[i] = RGBA_MAKE(0,51,0,alpha);
 
 
2222
                        break;
 
 
2223
                    }
 
 
2224
                    case VISION_MODE_PRED_THERMAL:
 
 
2225
                    case VISION_MODE_PRED_SEEALIENS:
 
 
2226
                    case VISION_MODE_PRED_SEEPREDTECH:
 
 
2227
                    {
 
 
2228
                        MeshVertexColour[i] = RGBA_MAKE(0,0,28,alpha);
 
 
2229
                          break;
 
 
2230
                    }
 
 
2231
                }
 
 
2232
            }
 
 
2233
 
 
 
2234
            #if 1
 
 
2235
            MeshWorldVertex[i].vx = ((point->vx-WaterXOrigin)/4+MUL_FIXED(GetSin((point->vy*16)&4095),128));
 
 
2236
            MeshWorldVertex[i].vy = ((point->vz-WaterZOrigin)/4+MUL_FIXED(GetSin((point->vy*16+200)&4095),128));
 
 
2237
            #endif
 
 
2238
 
 
 
2239
            #if 1
 
 
2240
            TranslatePointIntoViewspace(point);
 
 
2241
            #else
 
 
2242
            point->vx -= Global_VDB.VDB_World.vx;
 
 
2243
            point->vy -= Global_VDB.VDB_World.vy;
 
 
2244
            point->vz -= Global_VDB.VDB_World.vz;
 
 
2245
            RotateVector(point,&(Global_VDB.VDB_Mat));
 
 
2246
            point->vy = MUL_FIXED(point->vy,87381);
 
 
2247
 
 
 
2248
            #endif
 
 
2249
            /* is particle within normal view frustrum ? */
 
 
2250
            if(AvP.PlayerType == I_Alien)    /* wide frustrum */
 
 
2251
            {
 
 
2252
                if(( (-point->vx <= point->vz*2)
 
 
2253
                       &&(point->vx <= point->vz*2)
 
 
2254
                    &&(-point->vy <= point->vz*2)
 
 
2255
                    &&(point->vy <= point->vz*2) ))
 
 
2256
                {
 
 
2257
                    MeshVertexOutcode[i] = 1;
 
 
2258
                }
 
 
2259
                else
 
 
2260
                {
 
 
2261
                    MeshVertexOutcode[i] = 0;
 
 
2262
                }
 
 
2263
            }
 
 
2264
            else
 
 
2265
            {
 
 
2266
                if(( (-point->vx <= point->vz)
 
 
2267
                       &&(point->vx <= point->vz)
 
 
2268
                    &&(-point->vy <= point->vz)
 
 
2269
                    &&(point->vy <= point->vz) ))
 
 
2270
                {
 
 
2271
                    MeshVertexOutcode[i] = 1;
 
 
2272
                }
 
 
2273
                else
 
 
2274
                {
 
 
2275
                    MeshVertexOutcode[i] = 0;
 
 
2276
                }
 
 
2277
            }
 
 
2278
 
 
 
2279
            i++;
 
 
2280
        }
 
 
2281
    }
 
 
2282
 
 
 
2283
    if ((MeshVertexOutcode[0] && MeshVertexOutcode[15] && MeshVertexOutcode[240] && MeshVertexOutcode[255]))
 
 
2284
        DrawMoltenMetalMesh_Unclipped();
 
 
2285
    else
 
 
2286
        DrawMoltenMetalMesh_Unclipped();
 
 
2287
}
 
 
2288
 
 
 
2289
extern struct KObject VisibleModules[MAX_NUMBER_OF_VISIBLE_MODULES];
 
 
2290
extern int numVisMods;
 
 
2291
 
 
 
2292
void PostLandscapeRendering()
 
 
2293
{
 
 
2294
    int numOfModules = numVisMods;
 
 
2295
 
 
 
2296
    switch(AvP.level)
 
 
2297
    {
 
 
2298
        case AVP_ENVIRONMENT_WATERFALL:
 
 
2299
        case AVP_ENVIRONMENT_WATERFALL_M:
 
 
2300
        {
 
 
2301
            char drawWaterFall = 0;
 
 
2302
            char drawStream = 0;
 
 
2303
            char drawStream2 = 0;
 
 
2304
 
 
 
2305
            while(numOfModules--)
 
 
2306
            {
 
 
2307
                DISPLAYBLOCK *objectPtr = VisibleModules[numOfModules].DispPtr;
 
 
2308
                MODULE *modulePtr = objectPtr->Module;
 
 
2309
 
 
 
2310
                if (modulePtr->name)
 
 
2311
                {
 
 
2312
                    if( !strcmp(modulePtr->name,"fall01")
 
 
2313
                      || !strcmp(modulePtr->name,"well01")
 
 
2314
                      || !strcmp(modulePtr->name,"well02")
 
 
2315
                      || !strcmp(modulePtr->name,"well03")
 
 
2316
                      || !strcmp(modulePtr->name,"well04")
 
 
2317
                      || !strcmp(modulePtr->name,"well05")
 
 
2318
                      || !strcmp(modulePtr->name,"well06")
 
 
2319
                      || !strcmp(modulePtr->name,"well07")
 
 
2320
                      || !strcmp(modulePtr->name,"well08")
 
 
2321
                      || !strcmp(modulePtr->name,"well"))
 
 
2322
                    {
 
 
2323
                        drawWaterFall = 1;
 
 
2324
                    }
 
 
2325
                    else if( !strcmp(modulePtr->name,"stream02")
 
 
2326
                           || !strcmp(modulePtr->name,"stream03")
 
 
2327
                           || !strcmp(modulePtr->name,"watergate"))
 
 
2328
                    {
 
 
2329
                        drawStream = 1;
 
 
2330
                    } 
 
 
2331
                    else if( !strcmp(modulePtr->name,"openwat03")
 
 
2332
                        || !strcmp(modulePtr->name,"openwat04")
 
 
2333
                        || !strcmp(modulePtr->name,"openwat04A")
 
 
2334
                        || !strcmp(modulePtr->name,"openwat02"))
 
 
2335
                    {
 
 
2336
                        drawStream2 = 1;
 
 
2337
                    }
 
 
2338
                }
 
 
2339
            }
 
 
2340
 
 
 
2341
            if (drawWaterFall)
 
 
2342
            {
 
 
2343
    //            CurrTextureHandle = NULL;
 
 
2344
    //            CheckBoundTextureIsCorrect(NULL);
 
 
2345
    //            CheckTranslucencyModeIsCorrect(TRANSLUCENCY_NORMAL);
 
 
2346
 
 
 
2347
                FlushTriangleBuffers(1);
 
 
2348
                glDepthMask(GL_FALSE);
 
 
2349
 
 
 
2350
                WaterFallBase = 109952;
 
 
2351
 
 
 
2352
                MeshZScale = (66572-51026)/15;
 
 
2353
                MeshXScale = (109952+3039)/45;
 
 
2354
 
 
 
2355
                DrawWaterFall(175545,-3039,51026);
 
 
2356
    //            MeshZScale = -(538490-392169);
 
 
2357
    //            MeshXScale = 55000;
 
 
2358
    //            DrawWaterPatch(-100000, WaterFallBase, 538490);
 
 
2359
 
 
 
2360
                FlushTriangleBuffers(1);
 
 
2361
                glDepthMask(GL_TRUE);
 
 
2362
            }
 
 
2363
 
 
 
2364
            if (drawStream)
 
 
2365
            {
 
 
2366
                int x = 68581;
 
 
2367
                int y = 12925; /* probably should lower this a little.. */
 
 
2368
                int z = 93696;
 
 
2369
                MeshXScale = (87869-68581);
 
 
2370
                MeshZScale = (105385-93696);
 
 
2371
                CheckForObjectsInWater(x, x+MeshXScale, z, z+MeshZScale, y);
 
 
2372
 
 
 
2373
                WaterXOrigin=x;
 
 
2374
                WaterZOrigin=z;
 
 
2375
                WaterUScale = 4.0f/(float)MeshXScale;
 
 
2376
                WaterVScale = 4.0f/(float)MeshZScale;
 
 
2377
                MeshXScale/=4;
 
 
2378
                MeshZScale/=2;
 
 
2379
 
 
 
2380
                CurrTextureHandle = ImageHeaderArray[ChromeImageNumber].Texture;
 
 
2381
                CheckTriangleBuffer(0, 0, 0, 0, CurrTextureHandle, TRANSLUCENCY_NORMAL);
 
 
2382
 
 
 
2383
                DrawWaterPatch(x, y, z);             
 
 
2384
                DrawWaterPatch(x+MeshXScale, y, z);
 
 
2385
                DrawWaterPatch(x+MeshXScale*2, y, z);
 
 
2386
                DrawWaterPatch(x+MeshXScale*3, y, z);
 
 
2387
                DrawWaterPatch(x, y, z+MeshZScale);
 
 
2388
                DrawWaterPatch(x+MeshXScale, y, z+MeshZScale);
 
 
2389
                DrawWaterPatch(x+MeshXScale*2, y, z+MeshZScale);
 
 
2390
                DrawWaterPatch(x+MeshXScale*3, y, z+MeshZScale);
 
 
2391
            }
 
 
2392
 
 
 
2393
    #if 0 /* added, but then disabled (too squishy) */
 
 
2394
            if (drawStream2)
 
 
2395
            {
 
 
2396
                int x = 217400;
 
 
2397
                int y = 20750;
 
 
2398
                int z = 54000;
 
 
2399
                MeshXScale = (87869-68581);
 
 
2400
                MeshZScale = (105385-93696);
 
 
2401
 
 
 
2402
                CheckForObjectsInWater(x, x+MeshXScale, z, z+MeshZScale, y);
 
 
2403
 
 
 
2404
                WaterXOrigin=x;
 
 
2405
                WaterZOrigin=z;
 
 
2406
                WaterUScale = 4.0f/(float)MeshXScale;
 
 
2407
                WaterVScale = 4.0f/(float)MeshZScale;
 
 
2408
                MeshXScale/=4;
 
 
2409
                MeshZScale/=2;
 
 
2410
 
 
 
2411
                CurrTextureHandle = ImageHeaderArray[ChromeImageNumber].Texture;
 
 
2412
                CheckTriangleBuffer(0, 0, 0, 0, CurrTextureHandle, TRANSLUCENCY_NORMAL);
 
 
2413
 
 
 
2414
                DrawWaterPatch(x, y, z);             
 
 
2415
                DrawWaterPatch(x+MeshXScale, y, z);
 
 
2416
                DrawWaterPatch(x+MeshXScale*2, y, z);
 
 
2417
                DrawWaterPatch(x+MeshXScale*3, y, z);
 
 
2418
                DrawWaterPatch(x, y, z+MeshZScale);
 
 
2419
                DrawWaterPatch(x+MeshXScale, y, z+MeshZScale);
 
 
2420
                DrawWaterPatch(x+MeshXScale*2, y, z+MeshZScale);
 
 
2421
                DrawWaterPatch(x+MeshXScale*3, y, z+MeshZScale);
 
 
2422
            }    
 
 
2423
    #endif             
 
 
2424
        }
 
 
2425
        break;
 
 
2426
        case AVP_ENVIRONMENT_INVASION_A:
 
 
2427
        {
 
 
2428
            char drawWater = 0;
 
 
2429
            char drawEndWater = 0;
 
 
2430
 
 
 
2431
            while(numOfModules--)
 
 
2432
            {
 
 
2433
                DISPLAYBLOCK *objectPtr = VisibleModules[numOfModules].DispPtr;
 
 
2434
                MODULE *modulePtr = objectPtr->Module;
 
 
2435
 
 
 
2436
                /* if it's a module, which isn't inside another module */
 
 
2437
                if (modulePtr->name)
 
 
2438
                {
 
 
2439
                    if( !strcmp(modulePtr->name,"hivepool") || !strcmp(modulePtr->name,"hivepool04"))
 
 
2440
                    {
 
 
2441
                        drawWater = 1;
 
 
2442
                        break;
 
 
2443
                    }
 
 
2444
                    else
 
 
2445
                    {
 
 
2446
                        if(!strcmp(modulePtr->name,"shaftbot"))
 
 
2447
                        {
 
 
2448
                            drawEndWater = 1;
 
 
2449
                        }
 
 
2450
                        if( !strcasecmp(modulePtr->name,"shaft01")
 
 
2451
                         || !strcasecmp(modulePtr->name,"shaft02")
 
 
2452
                         || !strcasecmp(modulePtr->name,"shaft03")
 
 
2453
                         || !strcasecmp(modulePtr->name,"shaft04")
 
 
2454
                         || !strcasecmp(modulePtr->name,"shaft05")
 
 
2455
                         || !strcasecmp(modulePtr->name,"shaft06"))
 
 
2456
                        {
 
 
2457
                            HandleRainShaft(modulePtr, -11726,-107080,10);
 
 
2458
                            drawEndWater = 1;
 
 
2459
                            break;
 
 
2460
                        }
 
 
2461
                    }
 
 
2462
                }
 
 
2463
            }    
 
 
2464
 
 
 
2465
            if (drawWater)
 
 
2466
            {
 
 
2467
                int x = 20767;
 
 
2468
                int y = -36000+200;
 
 
2469
                int z = 30238;
 
 
2470
                MeshXScale = (36353-20767);
 
 
2471
                MeshZScale = (41927-30238);
 
 
2472
 
 
 
2473
                CheckForObjectsInWater(x, x+MeshXScale, z, z+MeshZScale, y);
 
 
2474
 
 
 
2475
                WaterXOrigin=x;
 
 
2476
                WaterZOrigin=z;
 
 
2477
                WaterUScale = 4.0f/(float)MeshXScale;
 
 
2478
                WaterVScale = 4.0f/(float)MeshZScale;
 
 
2479
                MeshXScale/=4;
 
 
2480
                MeshZScale/=2;
 
 
2481
 
 
 
2482
                CurrTextureHandle = ImageHeaderArray[ChromeImageNumber].Texture;
 
 
2483
                CheckTriangleBuffer(0, 0, 0, 0, CurrTextureHandle, TRANSLUCENCY_NORMAL);
 
 
2484
                DrawWaterPatch(x, y, z);
 
 
2485
                DrawWaterPatch(x+MeshXScale, y, z);             
 
 
2486
                DrawWaterPatch(x+MeshXScale*2, y, z);
 
 
2487
                DrawWaterPatch(x+MeshXScale*3, y, z);
 
 
2488
                DrawWaterPatch(x, y, z+MeshZScale);
 
 
2489
                DrawWaterPatch(x+MeshXScale, y, z+MeshZScale);
 
 
2490
                DrawWaterPatch(x+MeshXScale*2, y, z+MeshZScale);
 
 
2491
                DrawWaterPatch(x+MeshXScale*3, y, z+MeshZScale);
 
 
2492
            }
 
 
2493
            else if (drawEndWater)
 
 
2494
            {
 
 
2495
                int x = -15471;
 
 
2496
                int y = -11720-500;
 
 
2497
                int z = -55875;
 
 
2498
                MeshXScale = (15471-1800);
 
 
2499
                MeshZScale = (55875-36392);
 
 
2500
 
 
 
2501
                CheckForObjectsInWater(x, x+MeshXScale, z, z+MeshZScale, y);
 
 
2502
 
 
 
2503
                WaterXOrigin=x;
 
 
2504
                WaterZOrigin=z;
 
 
2505
                WaterUScale = 4.0f/(float)(MeshXScale+1800-3782);
 
 
2506
                WaterVScale = 4.0f/(float)MeshZScale;
 
 
2507
                MeshXScale/=4;
 
 
2508
                MeshZScale/=2;
 
 
2509
 
 
 
2510
                CurrTextureHandle = ImageHeaderArray[WaterShaftImageNumber].Texture;
 
 
2511
                CheckTriangleBuffer(0, 0, 0, 0, CurrTextureHandle, TRANSLUCENCY_NORMAL);
 
 
2512
                DrawWaterPatch(x, y, z);
 
 
2513
                DrawWaterPatch(x+MeshXScale, y, z);
 
 
2514
                DrawWaterPatch(x+MeshXScale*2, y, z);
 
 
2515
                DrawWaterPatch(x+MeshXScale*3, y, z);
 
 
2516
                DrawWaterPatch(x, y, z+MeshZScale);
 
 
2517
                DrawWaterPatch(x+MeshXScale, y, z+MeshZScale);
 
 
2518
                DrawWaterPatch(x+MeshXScale*2, y, z+MeshZScale);
 
 
2519
                DrawWaterPatch(x+MeshXScale*3, y, z+MeshZScale);
 
 
2520
            }
 
 
2521
        }
 
 
2522
        break;
 
 
2523
        case AVP_ENVIRONMENT_DERELICT:
 
 
2524
        case AVP_ENVIRONMENT_DERELICT_A:
 
 
2525
        {
 
 
2526
            MirroringActive = 0;
 
 
2527
 
 
 
2528
            while(numOfModules--)
 
 
2529
            {
 
 
2530
                DISPLAYBLOCK *objectPtr = VisibleModules[numOfModules].DispPtr;
 
 
2531
                MODULE *modulePtr = objectPtr->Module;
 
 
2532
 
 
 
2533
                if (modulePtr->name)
 
 
2534
                {
 
 
2535
                    if(!strcasecmp(modulePtr->name,"start-en01") || !strcasecmp(modulePtr->name,"start"))
 
 
2536
                    {
 
 
2537
                        extern void RenderMirrorSurface();
 
 
2538
                        extern void RenderMirrorSurface2();
 
 
2539
                        extern void RenderParticlesInMirror();
 
 
2540
                        MirroringActive = 1;
 
 
2541
                        MirroringAxis = -5700*2;
 
 
2542
                        RenderParticlesInMirror();
 
 
2543
                        RenderMirrorSurface();
 
 
2544
                        RenderMirrorSurface2();
 
 
2545
                        break;
 
 
2546
                    }
 
 
2547
                    else if (!strcasecmp(modulePtr->name,"water-01"))
 
 
2548
                    {
 
 
2549
                        const int x = -102799;
 
 
2550
                        const int y = 32000;
 
 
2551
                        const int z = -200964;
 
 
2552
                        HandleRainShaft(modulePtr, y, 0, 16);
 
 
2553
                        MeshXScale = (102799-87216);
 
 
2554
                        MeshZScale = (200964-180986);
 
 
2555
 
 
 
2556
                        CheckForObjectsInWater(x, x+MeshXScale, z, z+MeshZScale, y);
 
 
2557
 
 
 
2558
                        WaterXOrigin = x;
 
 
2559
                        WaterZOrigin = z;
 
 
2560
                        WaterUScale = 4.0f/(float)MeshXScale;
 
 
2561
                        WaterVScale = 4.0f/(float)MeshZScale;
 
 
2562
                        MeshXScale /= 2;
 
 
2563
                        MeshZScale /= 2;
 
 
2564
 
 
 
2565
                        CurrTextureHandle = ImageHeaderArray[ChromeImageNumber].Texture;
 
 
2566
                        CheckTriangleBuffer(0, 0, 0, 0, CurrTextureHandle, TRANSLUCENCY_NORMAL);
 
 
2567
                        DrawWaterPatch(x, y, z);
 
 
2568
                        DrawWaterPatch(x+MeshXScale, y, z);
 
 
2569
                        DrawWaterPatch(x, y, z+MeshZScale);
 
 
2570
                        DrawWaterPatch(x+MeshXScale, y, z+MeshZScale);
 
 
2571
                        break;
 
 
2572
                    }
 
 
2573
                }
 
 
2574
            }
 
 
2575
        }
 
 
2576
        break;
 
 
2577
        case AVP_ENVIRONMENT_COLONY:
 
 
2578
        {
 
 
2579
            while(numOfModules--)
 
 
2580
            {
 
 
2581
                DISPLAYBLOCK *objectPtr = VisibleModules[numOfModules].DispPtr;
 
 
2582
                MODULE *modulePtr = objectPtr->Module;
 
 
2583
 
 
 
2584
                if (modulePtr->name)
 
 
2585
                {
 
 
2586
                    if(  !strcasecmp(modulePtr->name,"largespace")
 
 
2587
                      || !strcasecmp(modulePtr->name,"proc13")
 
 
2588
                      || !strcasecmp(modulePtr->name,"trench01")
 
 
2589
                      || !strcasecmp(modulePtr->name,"trench02")
 
 
2590
                      || !strcasecmp(modulePtr->name,"trench03")
 
 
2591
                      || !strcasecmp(modulePtr->name,"trench04")
 
 
2592
                      || !strcasecmp(modulePtr->name,"trench05")
 
 
2593
                      || !strcasecmp(modulePtr->name,"trench06")
 
 
2594
                      || !strcasecmp(modulePtr->name,"trench07")
 
 
2595
                      || !strcasecmp(modulePtr->name,"trench08")
 
 
2596
                      || !strcasecmp(modulePtr->name,"trench09"))
 
 
2597
                    {
 
 
2598
                        extern void HandleRain(int numberOfRaindrops);
 
 
2599
                        HandleRain(999);
 
 
2600
                        break;
 
 
2601
                    }
 
 
2602
                    else if (!strcmp(modulePtr->name,"05"))
 
 
2603
                    {
 
 
2604
                        int y = modulePtr->m_maxy+modulePtr->m_world.vy-500;
 
 
2605
                        int x = modulePtr->m_minx+modulePtr->m_world.vx;
 
 
2606
                        int z = modulePtr->m_minz+modulePtr->m_world.vz;
 
 
2607
                        MeshXScale = (7791 - -7794);
 
 
2608
                        MeshZScale = (23378 - 7793);
 
 
2609
 
 
 
2610
                        CheckForObjectsInWater(x, x+MeshXScale, z, z+MeshZScale, y);
 
 
2611
 
 
 
2612
                        CurrTextureHandle = ImageHeaderArray[WaterShaftImageNumber].Texture;
 
 
2613
                        CheckBoundTextureIsCorrect(CurrTextureHandle);
 
 
2614
                        CheckTranslucencyModeIsCorrect(TRANSLUCENCY_NORMAL);
 
 
2615
 
 
 
2616
                        WaterXOrigin=x;
 
 
2617
                        WaterZOrigin=z;
 
 
2618
                        WaterUScale = 4.0f/(float)(MeshXScale);
 
 
2619
                        WaterVScale = 4.0f/(float)MeshZScale;
 
 
2620
                        #if 0
 
 
2621
                    #if 1
 
 
2622
                        MeshXScale/=2;
 
 
2623
                        MeshZScale/=2;
 
 
2624
 
 
 
2625
                        CurrTextureHandle = ImageHeaderArray[WaterShaftImageNumber].Texture;
 
 
2626
                        CheckTriangleBuffer(0, 0, 0, 0, CurrTextureHandle, TRANSLUCENCY_NORMAL);
 
 
2627
                        DrawWaterPatch(x, y, z);
 
 
2628
                        DrawWaterPatch(x+MeshXScale, y, z);
 
 
2629
                        DrawWaterPatch(x, y, z+MeshZScale);
 
 
2630
                        DrawWaterPatch(x+MeshXScale, y, z+MeshZScale);
 
 
2631
 
 
 
2632
                        HandleRainShaft(modulePtr, y,-21000,1);
 
 
2633
                    #else
 
 
2634
                        MeshXScale/=4;
 
 
2635
                        MeshZScale/=4;
 
 
2636
                        DrawWaterPatch(x, y, z);
 
 
2637
                        DrawWaterPatch(x, y, z+MeshZScale);
 
 
2638
                        DrawWaterPatch(x, y, z+MeshZScale*2);
 
 
2639
                        DrawWaterPatch(x, y, z+MeshZScale*3);
 
 
2640
                        DrawWaterPatch(x+MeshXScale, y, z);
 
 
2641
                        DrawWaterPatch(x+MeshXScale, y, z+MeshZScale);
 
 
2642
                        DrawWaterPatch(x+MeshXScale, y, z+MeshZScale*2);
 
 
2643
                        DrawWaterPatch(x+MeshXScale, y, z+MeshZScale*3);
 
 
2644
                        DrawWaterPatch(x+MeshXScale*2, y, z);
 
 
2645
                        DrawWaterPatch(x+MeshXScale*2, y, z+MeshZScale);
 
 
2646
                        DrawWaterPatch(x+MeshXScale*2, y, z+MeshZScale*2);
 
 
2647
                        DrawWaterPatch(x+MeshXScale*2, y, z+MeshZScale*3);
 
 
2648
                        DrawWaterPatch(x+MeshXScale*3, y, z);
 
 
2649
                        DrawWaterPatch(x+MeshXScale*3, y, z+MeshZScale);
 
 
2650
                        DrawWaterPatch(x+MeshXScale*3, y, z+MeshZScale*2);
 
 
2651
                        DrawWaterPatch(x+MeshXScale*3, y, z+MeshZScale*3);
 
 
2652
                        HandleRainDrops(modulePtr, 2);
 
 
2653
                    #endif
 
 
2654
                    #endif
 
 
2655
                    }
 
 
2656
                }
 
 
2657
            }
 
 
2658
        }
 
 
2659
        break;
 
 
2660
    #if 0 /* not yet */
 
 
2661
        case AVP_ENVIRONMENT_TYRARGOHANGAR:
 
 
2662
        {
 
 
2663
            VECTORCH v = {49937,-4000,-37709};
 
 
2664
            DrawCable(&v);
 
 
2665
        }
 
 
2666
    #endif
 
 
2667
        default:
 
 
2668
        break;
 
 
2669
    }
 
 
2670
}
 
 
2671
 
 
 
2672
void DrawCable(VECTORCH *centrePtr, MATRIXCH *orientationPtr)
 
 
2673
{
 
 
2674
    int field;
 
 
2675
 
 
 
2676
    CurrTextureHandle = NULL;
 
 
2677
    CheckBoundTextureIsCorrect(NULL);
 
 
2678
    CheckTranslucencyModeIsCorrect(TRANSLUCENCY_GLOWING);
 
 
2679
    glDepthMask(GL_FALSE);
 
 
2680
 
 
 
2681
    MeshXScale = 4096/16;
 
 
2682
    MeshZScale = 4096/16;
 
 
2683
 
 
 
2684
    for (field=0; field<3; field++)
 
 
2685
    {
 
 
2686
        int i=0;               
 
 
2687
        int x;
 
 
2688
        for (x=(0+field*15); x < (16+field*15); x++)
 
 
2689
        {
 
 
2690
            int z;
 
 
2691
            for(z=0; z < 16; z++)
 
 
2692
            {
 
 
2693
                VECTORCH *point = &MeshVertex[i];
 
 
2694
                {    
 
 
2695
                    int innerRadius = 20;
 
 
2696
                    VECTORCH radius;
 
 
2697
                    int theta = ((4096*z)/15)&4095;
 
 
2698
                    int rOffset = GetSin((x*64+theta/32-CloakingPhase)&4095);
 
 
2699
                    rOffset = MUL_FIXED(rOffset,rOffset)/512;
 
 
2700
 
 
 
2701
                    radius.vx = MUL_FIXED(innerRadius+rOffset/8,GetSin(theta));
 
 
2702
                    radius.vy = MUL_FIXED(innerRadius+rOffset/8,GetCos(theta));
 
 
2703
                    radius.vz = 0;
 
 
2704
 
 
 
2705
                    RotateVector(&radius,orientationPtr);
 
 
2706
 
 
 
2707
                    point->vx = centrePtr[x].vx+radius.vx;
 
 
2708
                    point->vy = centrePtr[x].vy+radius.vy;
 
 
2709
                    point->vz = centrePtr[x].vz+radius.vz;
 
 
2710
 
 
 
2711
                    MeshVertexColour[i] = RGBA_MAKE(0,rOffset,255,128);
 
 
2712
                }
 
 
2713
 
 
 
2714
                TranslatePointIntoViewspace(point);
 
 
2715
 
 
 
2716
                /* is particle within normal view frustrum ? */
 
 
2717
                if(AvP.PlayerType == I_Alien)    /* wide frustrum */
 
 
2718
                {
 
 
2719
                    if(( (-point->vx <= point->vz*2)
 
 
2720
                        &&(point->vx <= point->vz*2)
 
 
2721
                        &&(-point->vy <= point->vz*2)
 
 
2722
                        &&(point->vy <= point->vz*2) ))
 
 
2723
                    {
 
 
2724
                        MeshVertexOutcode[i]=1;
 
 
2725
                    }
 
 
2726
                    else
 
 
2727
                    {
 
 
2728
                        MeshVertexOutcode[i]=0;
 
 
2729
                    }
 
 
2730
                }
 
 
2731
                else
 
 
2732
                {
 
 
2733
                    if(( (-point->vx <= point->vz)
 
 
2734
                        &&(point->vx <= point->vz)
 
 
2735
                        &&(-point->vy <= point->vz)
 
 
2736
                        &&(point->vy <= point->vz) ))
 
 
2737
                    {
 
 
2738
                        MeshVertexOutcode[i]=1;
 
 
2739
                    }
 
 
2740
                    else
 
 
2741
                    {
 
 
2742
                        MeshVertexOutcode[i]=0;
 
 
2743
                    }
 
 
2744
                }
 
 
2745
            i++;
 
 
2746
            }
 
 
2747
        }
 
 
2748
        //printf("\n");
 
 
2749
        if ((MeshVertexOutcode[0]&&MeshVertexOutcode[15]&&MeshVertexOutcode[240]&&MeshVertexOutcode[255]))
 
 
2750
        {
 
 
2751
            DrawMoltenMetalMesh_Unclipped();
 
 
2752
        }
 
 
2753
        else
 
 
2754
    //    else if (MeshVertexOutcode[0]||MeshVertexOutcode[15]||MeshVertexOutcode[240]||MeshVertexOutcode[255])
 
 
2755
        {
 
 
2756
            DrawMoltenMetalMesh_Unclipped();
 
 
2757
        }    
 
 
2758
    }
 
 
2759
 
 
 
2760
    glDepthMask(GL_TRUE);
 
 
2761
}
 
 
2762
 
 
 
2763
void DeallocateAllImages()
 
 
2764
{
 
 
2765
    if (NumImages > 0)
 
 
2766
    {
 
 
2767
        int i;
 
 
2768
 
 
 
2769
        if (NumImages > 1)
 
 
2770
        if(NULL != ImageHeaderArray[StaticImageNumber].Texture->buf)
 
 
2771
        {
 
 
2772
            free(ImageHeaderArray[StaticImageNumber].Texture->buf);
 
 
2773
            ImageHeaderArray[StaticImageNumber].Texture->buf = NULL;
 
 
2774
        }
 
 
2775
 
 
 
2776
        for (i=0; i <= NumImages; i++)
 
 
2777
        {
 
 
2778
            glDeleteTextures(1, &ImageHeaderArray[i].Texture->id);
 
 
2779
            free(ImageHeaderArray[i].Texture);
 
 
2780
            ImageHeaderArray[i].Texture = NULL;
 
 
2781
            //printf("%d %s\n",i, ImageHeaderArray[i].ImageName);
 
 
2782
            free(ImageHeaderArray[i].ImageName);
 
 
2783
            ImageHeaderArray[i].ImageName = NULL;
 
 
2784
        }
 
 
2785
    }
 
 
2786
}
 
 
2787
 
 
 
2788
void DeallocateEnvImages()
 
 
2789
{
 
 
2790
    extern int number_of_level_textures;
 
 
2791
 
 
 
2792
    for(; number_of_level_textures > 0; number_of_level_textures--, NumImages--)
 
 
2793
    {
 
 
2794
        glDeleteTextures(1, &ImageHeaderArray[NumImages].Texture->id);
 
 
2795
        free(ImageHeaderArray[NumImages].Texture);
 
 
2796
        ImageHeaderArray[NumImages].Texture = NULL;
 
 
2797
        //printf("Deleteing ENV %s\n", ImageHeaderArray[NumImages].ImageName);
 
 
2798
        free(ImageHeaderArray[NumImages].ImageName);
 
 
2799
        ImageHeaderArray[NumImages].ImageName = NULL;
 
 
2800
    }
 
 
2801
 
 
 
2802
    number_of_level_textures = 0;
 
 
2803
}
 
 
2804
 
 
 
2805
#include "files.h"
 
 
2806
extern unsigned char *png_get_image_data(FILE *infile, unsigned int *width, unsigned int*height);
 
 
2807
 
 
 
2808
static struct TEXTURE * Create_png_Texture(const char * file_name)
 
 
2809
{
 
 
2810
    char *file_name_and_full_path = malloc(strlen("graphics/") + strlen(file_name) + 1);
 
 
2811
    struct TEXTURE *Tex = malloc(sizeof(struct TEXTURE));
 
 
2812
 
 
 
2813
    if ((NULL == Tex) || (NULL == file_name_and_full_path))
 
 
2814
    {
 
 
2815
        free(file_name_and_full_path);
 
 
2816
        free(Tex);
 
 
2817
        return NULL;
 
 
2818
    }
 
 
2819
 
 
 
2820
    sprintf(file_name_and_full_path, "graphics/%s", file_name);
 
 
2821
 
 
 
2822
    FILE * fileH = OpenGameFile(file_name_and_full_path, 1, FILETYPE_GAMEDATA);
 
 
2823
    free(file_name_and_full_path);
 
 
2824
 
 
 
2825
    if (NULL != fileH)
 
 
2826
    {
 
 
2827
        Tex->id = 0;
 
 
2828
        Tex->filter = 0;
 
 
2829
        Tex->buf = png_get_image_data(fileH, &Tex->w, &Tex->h);
 
 
2830
        fclose(fileH);
 
 
2831
 
 
 
2832
        if (NULL != Tex->buf)
 
 
2833
            return Tex;
 
 
2834
 
 
 
2835
        printf("ERROR Create_png_Texture(): reading file \"%s\"\n", file_name);
 
 
2836
    }
 
 
2837
    else
 
 
2838
    {
 
 
2839
        printf("\nMissing file '%s'\n", file_name);
 
 
2840
    }
 
 
2841
 
 
 
2842
    free(Tex);
 
 
2843
 
 
 
2844
return NULL;
 
 
2845
}
 
 
2846
 
 
 
2847
int CL_LoadImageOnce(char const * FileName)
 
 
2848
{
 
 
2849
    //assert(NumImages < MaxImages);
 
 
2850
 
 
 
2851
    if(strstr(FileName, "fmvs/"))
 
 
2852
        return StaticImageNumber;
 
 
2853
 
 
 
2854
    int i = NumImages;
 
 
2855
 
 
 
2856
    for (; i >= 0; i--)
 
 
2857
    {
 
 
2858
        if (!strcmp(ImageHeaderArray[i].ImageName, FileName)) 
 
 
2859
        {
 
 
2860
            //printf("\t Image %s is already loaded to image number %d\n", FileName, i);
 
 
2861
            return i;
 
 
2862
        }
 
 
2863
    }
 
 
2864
 
 
 
2865
    ImageHeaderArray[++NumImages].Texture = Create_png_Texture(FileName);
 
 
2866
 
 
 
2867
    if (NULL != ImageHeaderArray[NumImages].Texture)
 
 
2868
    {
 
 
2869
        char *new_file_name = malloc(strlen(FileName) + 1);
 
 
2870
 
 
 
2871
        if (NULL != new_file_name)
 
 
2872
        {
 
 
2873
            strcpy(new_file_name, FileName); 
 
 
2874
            ImageHeaderArray[NumImages].ImageName = new_file_name;
 
 
2875
            //printf("%s\t loaded to image number %d\n", ImageHeaderArray[NumImages].ImageName, NumImages);
 
 
2876
            return NumImages;
 
 
2877
        }
 
 
2878
    }
 
 
2879
    else
 
 
2880
    {
 
 
2881
        // this only happens once or twice with bonus levels; not fatal 
 
 
2882
        --NumImages;
 
 
2883
    }
 
 
2884
 
 
 
2885
return -1;
 
 
2886
}
 
 
2887
 
 
 
2888
static int load_font()
 
 
2889
{
 
 
2890
    AAFontImageNumber = CL_LoadImageOnce("common/aa_font.png");
 
 
2891
 
 
 
2892
    if( -1 != AAFontImageNumber)
 
 
2893
    {
 
 
2894
        struct TEXTURE *image = ImageHeaderArray[AAFontImageNumber].Texture;
 
 
2895
 
 
 
2896
        unsigned char *srcPtr = image->buf;
 
 
2897
        int c = 33;
 
 
2898
 
 
 
2899
        AAFontWidths[32] = 3;
 
 
2900
 
 
 
2901
        for (; c < 255; c++)
 
 
2902
        {
 
 
2903
            int x1 = 1 + ((c-32) & 15) * 16;
 
 
2904
            int y1 = 1 + ((c-32) >> 4) * 16;
 
 
2905
            int x = x1 + HUD_FONT_WIDTH;
 
 
2906
 
 
 
2907
            AAFontWidths[c] = 17;
 
 
2908
 
 
 
2909
            for (; x > x1; x--)
 
 
2910
            {
 
 
2911
                int blank = 1;
 
 
2912
                int y = y1;
 
 
2913
 
 
 
2914
                for (; y < y1 + HUD_FONT_HEIGHT; y++)
 
 
2915
                {
 
 
2916
                    unsigned char *s = &srcPtr[(x + y * image->w) * 4];
 
 
2917
 
 
 
2918
                    if (s[2] >= 0x80)
 
 
2919
                    {
 
 
2920
                        blank = 0;
 
 
2921
                        break;
 
 
2922
                    }
 
 
2923
                }
 
 
2924
 
 
 
2925
                if (blank)
 
 
2926
                    AAFontWidths[c]--;
 
 
2927
                else
 
 
2928
                    break;
 
 
2929
            }
 
 
2930
        }
 
 
2931
 
 
 
2932
        CreateOGLTexture(image);
 
 
2933
        free(image->buf);
 
 
2934
        image->buf = NULL;
 
 
2935
        return 1;
 
 
2936
    }
 
 
2937
 
 
 
2938
return 0;
 
 
2939
}
 
 
2940
 
 
 
2941
static int make_static_texture()
 
 
2942
{
 
 
2943
    struct TEXTURE *temp = malloc(sizeof(struct TEXTURE));
 
 
2944
 
 
 
2945
    if(NULL != temp)
 
 
2946
    {
 
 
2947
        temp->buf = malloc(128*128*3);
 
 
2948
 
 
 
2949
        if(NULL != temp->buf)
 
 
2950
        {
 
 
2951
            char *new_file_name = malloc(15);
 
 
2952
 
 
 
2953
            if(NULL != new_file_name)
 
 
2954
            {
 
 
2955
                temp->w = temp->h = 128;
 
 
2956
                strcpy(new_file_name, "fmvs/static"); 
 
 
2957
                StaticImageNumber = ++NumImages;
 
 
2958
                ImageHeaderArray[StaticImageNumber].ImageName = new_file_name;
 
 
2959
                ImageHeaderArray[StaticImageNumber].Texture = temp;
 
 
2960
                return 1;
 
 
2961
            }
 
 
2962
 
 
 
2963
            free(temp->buf);
 
 
2964
 
 
 
2965
        }
 
 
2966
 
 
 
2967
        free(temp);
 
 
2968
    }
 
 
2969
 
 
 
2970
return 0;
 
 
2971
}
 
 
2972
 
 
 
2973
int LoadCommonTextures()
 
 
2974
{
 
 
2975
    if(load_font() && make_static_texture())
 
 
2976
    {
 
 
2977
        HUDImageNumber = CL_LoadImageOnce("huds/marine/marinehud.png");
 
 
2978
        PredatorNumbersImageNumber = CL_LoadImageOnce("huds/predator/prednumbers.png");
 
 
2979
        AlienTongueImageNumber = CL_LoadImageOnce("huds/alien/alientongue.png");
 
 
2980
        HUDFontsImageNumber = CL_LoadImageOnce("common/hudfonts.png");
 
 
2981
        SpecialFXImageNumber = CL_LoadImageOnce("common/partclfx.png");
 
 
2982
        CloudyImageNumber = CL_LoadImageOnce("common/cloudy.png");
 
 
2983
        BurningImageNumber = CL_LoadImageOnce("common/burn.png");
 
 
2984
 
 
 
2985
        return
 
 
2986
        (
 
 
2987
            (-1 != HUDImageNumber)
 
 
2988
            &&
 
 
2989
            (-1 != PredatorNumbersImageNumber)
 
 
2990
            &&
 
 
2991
            (-1 != AlienTongueImageNumber)
 
 
2992
            &&
 
 
2993
            (-1 != HUDFontsImageNumber)
 
 
2994
            &&
 
 
2995
            (-1 != SpecialFXImageNumber)
 
 
2996
            &&
 
 
2997
            (-1 != CloudyImageNumber)
 
 
2998
            &&
 
 
2999
            (-1 != BurningImageNumber)
 
 
3000
        );
 
 
3001
    }
 
 
3002
 
 
 
3003
return 0;
 
 
3004
}
 
 
3005
 
 
 
3006
void shuffle_textures()
 
 
3007
{
 
 
3008
    static int * int_array = NULL;
 
 
3009
 
 
 
3010
    if (NULL == int_array)
 
 
3011
    {
 
 
3012
        int_array = malloc(sizeof(int) * (NumImages + 1));
 
 
3013
 
 
 
3014
        if (NULL != int_array)
 
 
3015
        {
 
 
3016
            int_array[0] = ImageHeaderArray[0].Texture->id;
 
 
3017
            int i = 1; // font texture is at 0
 
 
3018
 
 
 
3019
            srand(time(NULL));
 
 
3020
 
 
 
3021
            for (; i <= NumImages; i++)
 
 
3022
            {
 
 
3023
                int_array[i] = ImageHeaderArray[i].Texture->id;
 
 
3024
                ImageHeaderArray[i].Texture->id = ImageHeaderArray[rand() % NumImages].Texture->id;
 
 
3025
            }
 
 
3026
        }
 
 
3027
    }
 
 
3028
    else
 
 
3029
    {
 
 
3030
        int i = 1;
 
 
3031
 
 
 
3032
        for (; i <= NumImages; i++)
 
 
3033
            ImageHeaderArray[i].Texture->id = int_array[i];
 
 
3034
 
 
 
3035
        free(int_array);
 
 
3036
        int_array = NULL;
 
 
3037
    }
 
 
3038
}
 
 
3039
 
 
 
3040
extern int GotAnyKey;
 
 
3041
 
 
 
3042
static void bind_texture(struct TEXTURE *tex)
 
 
3043
{
 
 
3044
    glEnable(GL_TEXTURE_2D);
 
 
3045
    glGenTextures(1, &tex->id);
 
 
3046
    glBindTexture(GL_TEXTURE_2D, tex->id);
 
 
3047
    //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
 
 
3048
    //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
 
 
3049
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 
 
3050
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 
 
3051
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex->w, tex->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex->buf);
 
 
3052
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
 
 
3053
 
 
 
3054
    glBindTexture(GL_TEXTURE_2D, tex->id);
 
 
3055
}
 
 
3056
 
 
 
3057
void Show_CopyrightInfo()
 
 
3058
{
 
 
3059
    //struct TEXTURE * logo = Create_png_Texture("common/logo.png");
 
 
3060
    //struct TEXTURE * logo = Create_png_Texture("menus/copyright.png");
 
 
3061
    struct TEXTURE * logo = Create_png_Texture("common/foxlogo.png");
 
 
3062
 
 
 
3063
glEnable(GL_BLEND);
 
 
3064
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
 
3065
    int i=0;
 
 
3066
    for (; i < 2; i++, logo = Create_png_Texture("common/logo.png"))
 
 
3067
    {
 
 
3068
        if (NULL != logo)
 
 
3069
        {
 
 
3070
            bind_texture(logo);
 
 
3071
 
 
 
3072
            int timeRemaining = ONE_FIXED * 2;
 
 
3073
            float alpha_blend = 1;
 
 
3074
 
 
 
3075
            do
 
 
3076
            {
 
 
3077
                read_user_input();
 
 
3078
                //DrawAvPMenuGfx_Faded(MENUGFX_COPYRIGHT_SCREEN, 0, 0, ONE_FIXED-timeRemaining*2,MENUFORMAT_LEFTJUSTIFIED);
 
 
3079
 
 
 
3080
                glBegin(GL_QUADS);
 
 
3081
                glTexCoord2i(0.0, 0.0); glVertex3f(-0.5, 0.5, -1.0);
 
 
3082
                glTexCoord2i(1.0, 0.0); glVertex3f(0.5, 0.5, -1.0);
 
 
3083
                glTexCoord2i(1.0, 1.0); glVertex3f(0.5, -0.5, -1.0);
 
 
3084
                glTexCoord2i(0.0, 1.0); glVertex3f(-0.5, -0.5, -1.0);
 
 
3085
                glEnd();
 
 
3086
 
 
 
3087
                FrameCounterHandler();
 
 
3088
                timeRemaining -= NormalFrameTime;
 
 
3089
                SDL_GL_SwapBuffers();
 
 
3090
                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
 
3091
 
 
 
3092
                glColor4f(1, 1, 1, alpha_blend);
 
 
3093
                alpha_blend -= 0.005;
 
 
3094
                printf("%f\n", alpha_blend);
 
 
3095
 
 
 
3096
            //} while(timeRemaining > 0);
 
 
3097
            } while(alpha_blend > 0);
 
 
3098
 
 
 
3099
            timeRemaining = ONE_FIXED*2;
 
 
3100
 
 
 
3101
            free(logo->buf);
 
 
3102
            free(logo);
 
 
3103
            glDeleteTextures(1, &logo->id);
 
 
3104
        }
 
 
3105
    }
 
 
3106
/*
 
 
3107
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
 
3108
 
 
 
3109
    //struct TEXTURE * copyright = AwCreateTexture("menus/copyright.png");
 
 
3110
    //bind_texture(copyright);
 
 
3111
 
 
 
3112
    do
 
 
3113
    {
 
 
3114
        read_user_input();
 
 
3115
        //DrawAvPMenuGfx_Faded(MENUGFX_COPYRIGHT_SCREEN, 0, 0, ONE_FIXED,MENUFORMAT_LEFTJUSTIFIED);
 
 
3116
 
 
 
3117
glBegin(GL_QUADS);
 
 
3118
glTexCoord2d(0.0, 0.0); glVertex2d(-1.0, -1.0);
 
 
3119
glTexCoord2d(1.0, 0.0); glVertex2d(1.0, -1.0);
 
 
3120
glTexCoord2d(1.0, 1.0); glVertex2d(1.0, 1.0);
 
 
3121
glTexCoord2d(0.0, 1.0); glVertex2d(-1.0, 1.0);
 
 
3122
glEnd();
 
 
3123
 
 
 
3124
        FrameCounterHandler();
 
 
3125
        timeRemaining -= NormalFrameTime;
 
 
3126
 
 
 
3127
    } while(timeRemaining > 0);
 
 
3128
 
 
 
3129
        SDL_GL_SwapBuffers();
 
 
3130
    timeRemaining = ONE_FIXED/2;
 
 
3131
 
 
 
3132
//ReleaseTexture(copyright);
 
 
3133
 
 
 
3134
    do
 
 
3135
    {
 
 
3136
        read_user_input();
 
 
3137
        //DrawAvPMenuGfx_Faded(MENUGFX_COPYRIGHT_SCREEN, 0, 0, timeRemaining*2,MENUFORMAT_LEFTJUSTIFIED);
 
 
3138
        FrameCounterHandler();
 
 
3139
        timeRemaining -= NormalFrameTime;
 
 
3140
 
 
 
3141
    } while(timeRemaining > 0 );
 
 
3142
*/
 
 
3143
}
 
 
3144
 
 
 
3145
void fade_text(const char *textPtr)
 
 
3146
{
 
 
3147
    int timeRemaining = 7 * ONE_FIXED;
 
 
3148
    int y = ScreenDescriptorBlock.SDB_CentreY;
 
 
3149
 
 
 
3150
    do
 
 
3151
    {
 
 
3152
        read_user_input();
 
 
3153
 
 
 
3154
        if (timeRemaining > 13*ONE_FIXED/2)
 
 
3155
        {
 
 
3156
            RenderSmallMenuText(textPtr,ScreenDescriptorBlock.SDB_CentreX, y, 14*ONE_FIXED-timeRemaining*2,MENUFORMAT_CENTREJUSTIFIED);
 
 
3157
        }
 
 
3158
        else if (timeRemaining > 5*ONE_FIXED)
 
 
3159
        {
 
 
3160
            RenderSmallMenuText(textPtr,ScreenDescriptorBlock.SDB_CentreX, y, ONE_FIXED,MENUFORMAT_CENTREJUSTIFIED);
 
 
3161
        }
 
 
3162
        else if (timeRemaining > 3*ONE_FIXED)
 
 
3163
        {
 
 
3164
            RenderSmallMenuText(textPtr,ScreenDescriptorBlock.SDB_CentreX, y,(timeRemaining-3*ONE_FIXED)/2,MENUFORMAT_CENTREJUSTIFIED);
 
 
3165
        }
 
 
3166
 
 
 
3167
        SDL_GL_SwapBuffers();
 
 
3168
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
 
3169
 
 
 
3170
        FrameCounterHandler();
 
 
3171
        timeRemaining -= NormalFrameTime;
 
 
3172
 
 
 
3173
    } while((timeRemaining > 0) && !GotAnyKey);
 
 
3174
}
 
 
3175
 
 
 
3176
void roll_credits()
 
 
3177
{
 
 
3178
    extern const char * credits_text[];
 
 
3179
    const char ** char_ptr = credits_text;
 
 
3180
    int j = 0;
 
 
3181
    int y = ScreenDescriptorBlock.SDB_Height;
 
 
3182
    int font_height = 30;
 
 
3183
    int scroll_speed = ONE_FIXED/64;
 
 
3184
    int move_text_timer = scroll_speed;
 
 
3185
 
 
 
3186
    do
 
 
3187
    {
 
 
3188
        read_user_input();
 
 
3189
 
 
 
3190
        if ( '\n' == char_ptr[j] )
 
 
3191
        {
 
 
3192
            if (j == 0)
 
 
3193
                break;
 
 
3194
            else
 
 
3195
                j--;
 
 
3196
        }
 
 
3197
 
 
 
3198
        if (y > font_height)
 
 
3199
        {
 
 
3200
            int i = j;
 
 
3201
            float fade = ONE_FIXED;
 
 
3202
 
 
 
3203
            for (; i >= 0; i--)
 
 
3204
            {
 
 
3205
                if ( NULL != char_ptr[i])
 
 
3206
                {
 
 
3207
                    RenderSmallMenuText(char_ptr[i], ScreenDescriptorBlock.SDB_CentreX, (y + i * font_height) , fade, MENUFORMAT_CENTREJUSTIFIED);
 
 
3208
                    fade *= 0.80;
 
 
3209
                }
 
 
3210
            }
 
 
3211
 
 
 
3212
            if (move_text_timer < 0)
 
 
3213
            {
 
 
3214
                y--;
 
 
3215
                move_text_timer = scroll_speed;
 
 
3216
 
 
 
3217
                if ( y % font_height == 0)
 
 
3218
                    j++;
 
 
3219
            }
 
 
3220
 
 
 
3221
            SDL_GL_SwapBuffers();
 
 
3222
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
 
3223
 
 
 
3224
        }
 
 
3225
        else
 
 
3226
        {
 
 
3227
            y += font_height;
 
 
3228
            char_ptr++;
 
 
3229
            j--;
 
 
3230
        }
 
 
3231
 
 
 
3232
        FrameCounterHandler();
 
 
3233
        move_text_timer -= NormalFrameTime;
 
 
3234
 
 
 
3235
    } while(!got_any_key());
 
 
3236
}
 
 
3237
 
 
 
3238
void PlayIntroSequence()
 
 
3239
{
 
 
3240
    Show_CopyrightInfo();
 
 
3241
 
 
 
3242
    fade_text("Fox Interactive");
 
 
3243
    fade_text("And");
 
 
3244
    fade_text("Rebellion");
 
 
3245
 
 
 
3246
    if (!GotAnyKey)
 
 
3247
    {
 
 
3248
        fade_text("Presents");
 
 
3249
        fade_text("Aliens versus Predator Gold Edition");
 
 
3250
    }
 
 
3251
}