4b825dc642cb6eb9a060e54bf8d69288fbee490494a6641b73026d662261604d7d192beae70b11dc
 
 
1
#include "system.h"
 
 
2
#include "prototyp.h"
 
 
3
#include <math.h>
 
 
4
#include "stratdef.h"
 
 
5
#include "frustum.h"
 
 
6
#include "npc_marine.h"
 
 
7
#include "corpse.h"
 
 
8
#include "debris.h"
 
 
9
#include "weaponbehaviour.h"
 
 
10
#include "bh_types.h"
 
 
11
#include "pldghost.h"
 
 
12
#include "userprofile.h"
 
 
13
#include "weapons.h"
 
 
14
#include "lighting.h"
 
 
15
#include "hud.h"
 
 
16
#include "bh_light.h"
 
 
17
#include <assert.h>
 
 
18
 
 
 
19
extern void GetMorphDisplay(MORPHDISPLAY *md, DISPLAYBLOCK *dptr);
 
 
20
extern void Decal_Output(const DECAL *decalPtr, RENDERVERTEX *renderVerticesPtr);
 
 
21
extern void SkyPolygon_Output(RENDERVERTEX *renderVerticesPtr);
 
 
22
extern void ZBufferedCloakedPolygon_Output(POLYHEADER *inputPolyPtr, RENDERVERTEX *renderVerticesPtr);
 
 
23
extern void ZBufferedGouraudTexturedPolygon_Output(POLYHEADER *inputPolyPtr, RENDERVERTEX *renderVerticesPtr);
 
 
24
extern void ZBufferedGouraudPolygon_Output(POLYHEADER *inputPolyPtr, RENDERVERTEX *renderVerticesPtr);
 
 
25
extern void PredatorThermalVisionPolygon_Output(RENDERVERTEX *renderVerticesPtr);
 
 
26
extern void Particle_Output(PARTICLE *particlePtr, RENDERVERTEX *renderVerticesPtr);
 
 
27
extern void DoPlayersWeaponHModel(DISPLAYBLOCK *dptr);
 
 
28
 
 
 
29
#define ALIENS_LIFEFORCE_GLOW_COLOUR 0x20ff8080
 
 
30
#define MARINES_LIFEFORCE_GLOW_COLOUR 0x208080ff
 
 
31
#define PREDATORS_LIFEFORCE_GLOW_COLOUR 0x2080ff80
 
 
32
#define MAX_NO_OF_TRANSLUCENT_POLYGONS 1000
 
 
33
 
 
 
34
#define SPATIAL_SHOCKWAVE 0
 
 
35
 
 
 
36
#define MaxLightsPerObject 100  /* Sources lighting the object */
 
 
37
int DrawingAReflection;
 
 
38
extern DISPLAYBLOCK* ActiveBlockList[];
 
 
39
extern int NumActiveBlocks;
 
 
40
 
 
 
41
extern int CloakingPhase;
 
 
42
extern int CloudyImageNumber;
 
 
43
extern SCREENDESCRIPTORBLOCK ScreenDescriptorBlock;
 
 
44
 
 
 
45
static LIGHTBLOCK *LightSourcesForObject[MaxLightsPerObject];
 
 
46
static DISPLAYBLOCK *Global_ODB_Ptr;
 
 
47
static struct shapeheader *Global_ShapeHeaderPtr;
 
 
48
static int*    Global_ShapePoints;
 
 
49
static int*    Global_ShapeNormals;
 
 
50
static int*    Global_ShapeVNormals;
 
 
51
static int HierarchicalObjectsLowestYValue;
 
 
52
static int ObjectCounter = 0;
 
 
53
static int NumLightSourcesForObject;
 
 
54
 
 
 
55
static float Source[3];
 
 
56
static float Dest[3];
 
 
57
static float ViewMatrix[12];
 
 
58
static float ObjectViewMatrix[12];
 
 
59
 
 
 
60
static VECTORCH ObjectCentre;
 
 
61
 
 
 
62
MATRIXCH LToVMat;
 
 
63
EULER LToVMat_Euler;
 
 
64
MATRIXCH WToLMat;
 
 
65
VECTORCH LocalView;
 
 
66
 
 
 
67
int TripTasticPhase;
 
 
68
int MirroringActive = 0;
 
 
69
int MirroringAxis = -149*2;
 
 
70
int NumberOfHeatSources;
 
 
71
float CameraZoomScale;
 
 
72
 
 
 
73
struct render_polygon RenderPolygon;
 
 
74
RENDERVERTEX VerticesBuffer[9];
 
 
75
 
 
 
76
static void (*VertexIntensity)(RENDERVERTEX *renderVertexPtr);
 
 
77
 
 
 
78
VECTORCH RotatedPts[maxrotpts];
 
 
79
 
 
 
80
MORPHDISPLAY MorphDisplay;
 
 
81
VECTORCH MorphedPts[1024];
 
 
82
 
 
 
83
static struct
 
 
84
{
 
 
85
    /* stamp used for lazy evaluation */
 
 
86
    int Stamp;
 
 
87
 
 
 
88
    /* colour scalings */
 
 
89
    uint8_t R;
 
 
90
    uint8_t G;
 
 
91
    uint8_t B;
 
 
92
 
 
 
93
    /* specular colour */
 
 
94
    uint8_t SpecularR;
 
 
95
    uint8_t SpecularG;
 
 
96
    uint8_t SpecularB;
 
 
97
 
 
 
98
} ColourIntensityArray[maxrotpts];
 
 
99
 
 
 
100
static struct
 
 
101
{
 
 
102
    struct render_polygon polygon;
 
 
103
    struct polyheader polygon_header;
 
 
104
 
 
 
105
} TranslucentPolygons[MAX_NO_OF_TRANSLUCENT_POLYGONS];
 
 
106
 
 
 
107
static int CurrentNumberOfTranslucentPolygons = 0;
 
 
108
static const int* VertexNumberPtr = (int*)1;
 
 
109
 
 
 
110
HEATSOURCE HeatSourceList[MAX_NUMBER_OF_HEAT_SOURCES];
 
 
111
 
 
 
112
static void LightSourcesInRangeOfObject(DISPLAYBLOCK *dptr)
 
 
113
{
 
 
114
    int i,j;
 
 
115
    NumLightSourcesForObject = 0;
 
 
116
 
 
 
117
    /* Light Sources attached to other objects */
 
 
118
 
 
 
119
    for(i=0; (i < NumActiveBlocks) && (NumLightSourcesForObject < MaxLightsPerObject); i++) 
 
 
120
    {
 
 
121
        DISPLAYBLOCK *dptr2 = ActiveBlockList[i];
 
 
122
 
 
 
123
        for(j=0; j < dptr2->ObNumLights && (NumLightSourcesForObject < MaxLightsPerObject); j++)
 
 
124
        {
 
 
125
            LIGHTBLOCK *lptr = dptr2->ObLights[j];
 
 
126
 
 
 
127
            if (!lptr->LightBright || !(lptr->RedScale || lptr->GreenScale || lptr->BlueScale))
 
 
128
                 continue;
 
 
129
 
 
 
130
            if ((PlayerStatus.VisionMode == VISION_MODE_IMAGEINTENSIFIER) && (lptr->LightFlags & LFlag_PreLitSource))
 
 
131
                continue;
 
 
132
 
 
 
133
            if(!(dptr->ObFlags3 & ObFlag3_PreLit && lptr->LightFlags & LFlag_PreLitSource))
 
 
134
            {
 
 
135
                VECTORCH vertexToLight;
 
 
136
 
 
 
137
                if (DrawingAReflection)
 
 
138
                    vertexToLight.vx = (MirroringAxis - lptr->LightWorld.vx) - dptr->ObWorld.vx;
 
 
139
                else
 
 
140
                    vertexToLight.vx = lptr->LightWorld.vx - dptr->ObWorld.vx;
 
 
141
 
 
 
142
                vertexToLight.vy = lptr->LightWorld.vy - dptr->ObWorld.vy;
 
 
143
                vertexToLight.vz = lptr->LightWorld.vz - dptr->ObWorld.vz;
 
 
144
 
 
 
145
                int distanceToLight = Approximate3dMagnitude(&vertexToLight);
 
 
146
 
 
 
147
                if(distanceToLight < (lptr->LightRange + dptr->extent.radius))
 
 
148
                {
 
 
149
                    LightSourcesForObject[NumLightSourcesForObject++] = lptr;
 
 
150
 
 
 
151
                    /* Transform the light position to local space */
 
 
152
 
 
 
153
                    RotateAndCopyVector(&vertexToLight, &lptr->LocalLP, &WToLMat);
 
 
154
                }
 
 
155
            }
 
 
156
        }
 
 
157
    }
 
 
158
 
 
 
159
    {
 
 
160
        extern LIGHTELEMENT LightElementStorage[];
 
 
161
        extern int NumActiveLightElements;
 
 
162
 
 
 
163
        for(i=0; i < NumActiveLightElements; i++)
 
 
164
        {
 
 
165
            LIGHTBLOCK *lptr = &LightElementStorage[i].LightBlock;
 
 
166
            VECTORCH vertexToLight;
 
 
167
 
 
 
168
            vertexToLight.vx = lptr->LightWorld.vx - dptr->ObWorld.vx;
 
 
169
            vertexToLight.vy = lptr->LightWorld.vy - dptr->ObWorld.vy;
 
 
170
            vertexToLight.vz = lptr->LightWorld.vz - dptr->ObWorld.vz;
 
 
171
 
 
 
172
            int distanceToLight = Approximate3dMagnitude(&vertexToLight);
 
 
173
 
 
 
174
            if(distanceToLight < (lptr->LightRange + dptr->extent.radius) )
 
 
175
            {
 
 
176
                LightSourcesForObject[NumLightSourcesForObject] = lptr;
 
 
177
                NumLightSourcesForObject++;
 
 
178
 
 
 
179
                /* Transform the light position to local space */
 
 
180
                RotateAndCopyVector(&vertexToLight, &lptr->LocalLP, &WToLMat);
 
 
181
            }
 
 
182
        }
 
 
183
    }
 
 
184
}
 
 
185
 
 
 
186
static void SetupShapePipeline(DISPLAYBLOCK * dptr)
 
 
187
{
 
 
188
    Global_ODB_Ptr = dptr;
 
 
189
    Global_ShapeHeaderPtr = dptr->ShapeData;
 
 
190
    Global_ShapePoints    = *(Global_ShapeHeaderPtr->points);
 
 
191
    Global_ShapeNormals = Global_ShapeHeaderPtr->sh_normals ? *(Global_ShapeHeaderPtr->sh_normals) : 0;
 
 
192
    Global_ShapeVNormals = Global_ShapeHeaderPtr->sh_vnormals ? *(Global_ShapeHeaderPtr->sh_vnormals) : 0;
 
 
193
 
 
 
194
    ObjectCounter++;
 
 
195
 
 
 
196
    /*
 
 
197
    Create the Local -> View Matrix
 
 
198
 
 
 
199
    LToVMat = VDB_Mat * ObMat
 
 
200
 
 
 
201
    "Get the points into View Space, then apply the Local Transformation"
 
 
202
    */
 
 
203
 
 
 
204
    MatrixMultiply(&Global_VDB.VDB_Mat, &dptr->ObMat, &LToVMat);
 
 
205
    MatrixToEuler(&LToVMat, &LToVMat_Euler);
 
 
206
 
 
 
207
    /*
 
 
208
    Create the World -> Local Matrix
 
 
209
 
 
 
210
    WToLMat = Transposed Local Matrix
 
 
211
    */
 
 
212
 
 
 
213
    WToLMat = dptr->ObMat;
 
 
214
    TransposeMatrixCH(&WToLMat);
 
 
215
 
 
 
216
    /*
 
 
217
 
 
 
218
    Transform the View World Location to Local Space
 
 
219
 
 
 
220
    -> Make the View Loc. relative to the Object View Space Centre
 
 
221
    -> Rotate this vector using WToLMat
 
 
222
 
 
 
223
    */
 
 
224
 
 
 
225
    LocalView.vx = Global_VDB.VDB_World.vx - dptr->ObWorld.vx;
 
 
226
    LocalView.vy = Global_VDB.VDB_World.vy - dptr->ObWorld.vy;
 
 
227
    LocalView.vz = Global_VDB.VDB_World.vz - dptr->ObWorld.vz;
 
 
228
 
 
 
229
    RotateVector(&LocalView, &WToLMat);
 
 
230
 
 
 
231
      /* Find out which light sources are in range of of the object */
 
 
232
    LightSourcesInRangeOfObject(dptr);
 
 
233
}
 
 
234
 
 
 
235
static void VertexIntensity_Pred_Thermal(RENDERVERTEX *renderVertexPtr)
 
 
236
{
 
 
237
    int vertexNumber = *VertexNumberPtr;
 
 
238
 
 
 
239
    if(ColourIntensityArray[vertexNumber].Stamp == ObjectCounter)
 
 
240
    {
 
 
241
        renderVertexPtr->R = ColourIntensityArray[vertexNumber].R;
 
 
242
        renderVertexPtr->G = ColourIntensityArray[vertexNumber].G;
 
 
243
        renderVertexPtr->B = ColourIntensityArray[vertexNumber].B;    
 
 
244
        renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR;
 
 
245
        renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG;
 
 
246
        renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB;
 
 
247
    }
 
 
248
    else
 
 
249
    {
 
 
250
        int redI = 0,specular = 0;
 
 
251
        int blueI = ONE_FIXED / 2;
 
 
252
 
 
 
253
        {
 
 
254
            VECTORCH *vertexNormalPtr = ((VECTORCH *)Global_ShapeVNormals) + vertexNumber;
 
 
255
            VECTORCH *vertexPtr = ((VECTORCH *)Global_ShapePoints) + vertexNumber;
 
 
256
            VECTORCH vertexToLight;
 
 
257
            int i;
 
 
258
 
 
 
259
            for(i=0; i < NumLightSourcesForObject; i++)
 
 
260
            {
 
 
261
                LIGHTBLOCK *lptr = LightSourcesForObject[i];
 
 
262
 
 
 
263
                if (lptr->LightFlags & LFlag_PreLitSource)
 
 
264
                        continue;
 
 
265
 
 
 
266
                vertexToLight.vx = lptr->LocalLP.vx - vertexPtr->vx;
 
 
267
                vertexToLight.vy = lptr->LocalLP.vy - vertexPtr->vy;
 
 
268
                vertexToLight.vz = lptr->LocalLP.vz - vertexPtr->vz;
 
 
269
 
 
 
270
                int distanceToLight = Approximate3dMagnitude(&vertexToLight);
 
 
271
 
 
 
272
                if(distanceToLight < lptr->LightRange) 
 
 
273
                {
 
 
274
                    int idot = MUL_FIXED(lptr->LightRange-distanceToLight,lptr->BrightnessOverRange);
 
 
275
 
 
 
276
                    if( (distanceToLight > 0) && !(Global_ODB_Ptr->ObFlags3 & ObFlag3_NoLightDot))
 
 
277
                    {
 
 
278
                        int dotproduct = MUL_FIXED(vertexNormalPtr->vx,vertexToLight.vx)
 
 
279
                             + MUL_FIXED(vertexNormalPtr->vy,vertexToLight.vy)
 
 
280
                             + MUL_FIXED(vertexNormalPtr->vz,vertexToLight.vz);
 
 
281
 
 
 
282
                        if(dotproduct > 0)
 
 
283
                        {
 
 
284
                            idot = WideMulNarrowDiv(idot,dotproduct,distanceToLight);
 
 
285
                            redI += idot;            
 
 
286
                        }
 
 
287
                    }
 
 
288
 
 
 
289
                    if (lptr->LightFlags & LFlag_Thermal)
 
 
290
                        specular += idot;
 
 
291
                }
 
 
292
            }
 
 
293
        }
 
 
294
 
 
 
295
        if (renderVertexPtr->Z > 5000)
 
 
296
        {
 
 
297
            int a = (renderVertexPtr->Z - 5000);    
 
 
298
 
 
 
299
            if (a > 4096)
 
 
300
                blueI = (blueI*4096)/a;
 
 
301
        }
 
 
302
 
 
 
303
        blueI >>= 8;
 
 
304
 
 
 
305
        if(redI >= ONE_FIXED)
 
 
306
            redI = (ONE_FIXED - 1);
 
 
307
 
 
 
308
        redI >>=8;
 
 
309
 
 
 
310
        specular >>= 6;
 
 
311
 
 
 
312
        if (specular >= 255)
 
 
313
            specular = 255;
 
 
314
 
 
 
315
        /* KJL 12:41:54 05/10/98 - red/green swapped, whilst testing colours */
 
 
316
        renderVertexPtr->R = ColourIntensityArray[vertexNumber].R = 0;
 
 
317
        renderVertexPtr->B = ColourIntensityArray[vertexNumber].B = blueI;
 
 
318
        renderVertexPtr->G = ColourIntensityArray[vertexNumber].G = redI/2;
 
 
319
 
 
 
320
        renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR = specular;
 
 
321
        renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG = specular;
 
 
322
        renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB = specular;
 
 
323
 
 
 
324
        ColourIntensityArray[vertexNumber].Stamp = ObjectCounter;
 
 
325
    }
 
 
326
}
 
 
327
 
 
 
328
static void VertexIntensity_Pred_SeeAliens(RENDERVERTEX *renderVertexPtr)
 
 
329
{
 
 
330
    int vertexNumber = *VertexNumberPtr;
 
 
331
 
 
 
332
    if(ColourIntensityArray[vertexNumber].Stamp == ObjectCounter)
 
 
333
    {
 
 
334
        renderVertexPtr->R = ColourIntensityArray[vertexNumber].R;
 
 
335
        renderVertexPtr->G = ColourIntensityArray[vertexNumber].G;
 
 
336
        renderVertexPtr->B = ColourIntensityArray[vertexNumber].B;    
 
 
337
        renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR;
 
 
338
        renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG;
 
 
339
        renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB;    
 
 
340
    }
 
 
341
    else
 
 
342
    {
 
 
343
        int redI = 0,specular = 0;
 
 
344
        int blueI = ONE_FIXED/2;
 
 
345
 
 
 
346
        ColourIntensityArray[vertexNumber].Stamp = ObjectCounter;
 
 
347
 
 
 
348
        {
 
 
349
            VECTORCH *vertexPtr = ((VECTORCH *)Global_ShapePoints) + vertexNumber;
 
 
350
            VECTORCH vertexToLight;
 
 
351
            int i;
 
 
352
 
 
 
353
            for(i=0; i < NumLightSourcesForObject; i++)
 
 
354
            {
 
 
355
                LIGHTBLOCK *lptr = LightSourcesForObject[i];
 
 
356
 
 
 
357
                if (lptr->LightFlags & LFlag_PreLitSource)
 
 
358
                    continue;
 
 
359
 
 
 
360
                vertexToLight.vx = lptr->LocalLP.vx - vertexPtr->vx;
 
 
361
                vertexToLight.vy = lptr->LocalLP.vy - vertexPtr->vy;
 
 
362
                vertexToLight.vz = lptr->LocalLP.vz - vertexPtr->vz;
 
 
363
 
 
 
364
                int distanceToLight = Approximate3dMagnitude(&vertexToLight);
 
 
365
 
 
 
366
                if(distanceToLight < lptr->LightRange) 
 
 
367
                {
 
 
368
                    int idot = MUL_FIXED(lptr->LightRange-distanceToLight,lptr->BrightnessOverRange);
 
 
369
 
 
 
370
                    redI += idot;            
 
 
371
 
 
 
372
                    if(lptr->LightFlags & LFlag_Electrical)
 
 
373
                        specular += idot;
 
 
374
                }
 
 
375
            }
 
 
376
        }
 
 
377
 
 
 
378
        redI >>=11;
 
 
379
 
 
 
380
        if(redI > 255)
 
 
381
            redI = 255;
 
 
382
 
 
 
383
        renderVertexPtr->G = ColourIntensityArray[vertexNumber].G = redI;
 
 
384
 
 
 
385
        if (renderVertexPtr->Z > 5000)
 
 
386
        {
 
 
387
            int a = renderVertexPtr->Z - 5000;    
 
 
388
 
 
 
389
            if (a > 4096)
 
 
390
                blueI = (blueI*4096)/a;
 
 
391
        }
 
 
392
 
 
 
393
        /* KJL 12:41:54 05/10/98 - red/green swapped, whilst testing colours */
 
 
394
        blueI >>= 9;
 
 
395
        renderVertexPtr->R = ColourIntensityArray[vertexNumber].R = blueI;
 
 
396
        renderVertexPtr->B = ColourIntensityArray[vertexNumber].B = 0;
 
 
397
 
 
 
398
        specular >>=10;
 
 
399
 
 
 
400
        if(specular > 255)
 
 
401
            specular = 255;
 
 
402
 
 
 
403
        renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR = specular;
 
 
404
        renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG = specular;
 
 
405
        renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB = specular;
 
 
406
    }
 
 
407
}
 
 
408
 
 
 
409
static void VertexIntensity_Pred_SeePredatorTech(RENDERVERTEX *renderVertexPtr)
 
 
410
{
 
 
411
    int vertexNumber = *VertexNumberPtr;
 
 
412
 
 
 
413
    if(ColourIntensityArray[vertexNumber].Stamp == ObjectCounter)
 
 
414
    {
 
 
415
        renderVertexPtr->R = ColourIntensityArray[vertexNumber].R;
 
 
416
        renderVertexPtr->G = ColourIntensityArray[vertexNumber].G;
 
 
417
        renderVertexPtr->B = ColourIntensityArray[vertexNumber].B;    
 
 
418
        renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR;
 
 
419
        renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG;
 
 
420
        renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB;    
 
 
421
    }
 
 
422
    else
 
 
423
    {
 
 
424
        int redI = 0;
 
 
425
        int blueI = ONE_FIXED-1;
 
 
426
 
 
 
427
        ColourIntensityArray[vertexNumber].Stamp = ObjectCounter;
 
 
428
 
 
 
429
        {
 
 
430
            VECTORCH *vertexPtr = ((VECTORCH *)Global_ShapePoints) + vertexNumber;
 
 
431
            VECTORCH vertexToLight;
 
 
432
            int i;
 
 
433
 
 
 
434
            for(i=0; i < NumLightSourcesForObject; i++)
 
 
435
            {
 
 
436
                LIGHTBLOCK *lptr = LightSourcesForObject[i];
 
 
437
 
 
 
438
                if (lptr->LightFlags & LFlag_PreLitSource)
 
 
439
                        continue;
 
 
440
 
 
 
441
                vertexToLight.vx = lptr->LocalLP.vx - vertexPtr->vx;
 
 
442
                vertexToLight.vy = lptr->LocalLP.vy - vertexPtr->vy;
 
 
443
                vertexToLight.vz = lptr->LocalLP.vz - vertexPtr->vz;
 
 
444
 
 
 
445
                int distanceToLight = Approximate3dMagnitude(&vertexToLight);
 
 
446
 
 
 
447
                if(distanceToLight < lptr->LightRange) 
 
 
448
                    redI += MUL_FIXED(lptr->LightRange - distanceToLight, lptr->BrightnessOverRange);
 
 
449
            }
 
 
450
        }
 
 
451
 
 
 
452
        if (renderVertexPtr->Z > 5000)
 
 
453
        {
 
 
454
            int a = (renderVertexPtr->Z - 5000);
 
 
455
 
 
 
456
            if (a > 4096)
 
 
457
                blueI = (blueI*4096)/a;
 
 
458
        }
 
 
459
 
 
 
460
        blueI >>=8;
 
 
461
 
 
 
462
        redI >>=9;
 
 
463
 
 
 
464
        if (redI > 255)
 
 
465
            redI = 255;
 
 
466
 
 
 
467
        /* KJL 12:41:54 05/10/98 - red/green swapped, whilst testing colours */
 
 
468
        renderVertexPtr->R = ColourIntensityArray[vertexNumber].R = 255;
 
 
469
        renderVertexPtr->B = ColourIntensityArray[vertexNumber].B = 255;
 
 
470
        renderVertexPtr->G = ColourIntensityArray[vertexNumber].G = blueI;
 
 
471
 
 
 
472
        renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR = 255;
 
 
473
        renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG = redI;
 
 
474
        renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB = 255;
 
 
475
    }
 
 
476
}
 
 
477
 
 
 
478
static void VertexIntensity_ImageIntensifier(RENDERVERTEX *renderVertexPtr)
 
 
479
{
 
 
480
    int vertexNumber = *VertexNumberPtr;
 
 
481
 
 
 
482
    if(ColourIntensityArray[vertexNumber].Stamp == ObjectCounter)
 
 
483
    {
 
 
484
        renderVertexPtr->R = ColourIntensityArray[vertexNumber].R;
 
 
485
        renderVertexPtr->G = ColourIntensityArray[vertexNumber].G;
 
 
486
        renderVertexPtr->B = ColourIntensityArray[vertexNumber].B;    
 
 
487
        renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR;
 
 
488
        renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG;
 
 
489
        renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB;    
 
 
490
    }
 
 
491
    else
 
 
492
    {
 
 
493
        int specular = 0;
 
 
494
 
 
 
495
        ColourIntensityArray[vertexNumber].Stamp = ObjectCounter;
 
 
496
 
 
 
497
        {
 
 
498
            VECTORCH *vertexNormalPtr = ((VECTORCH *)Global_ShapeVNormals) + vertexNumber;
 
 
499
            VECTORCH *vertexPtr = ((VECTORCH *)Global_ShapePoints) + vertexNumber;
 
 
500
            VECTORCH vertexToLight;
 
 
501
            int distanceToLight, i;
 
 
502
 
 
 
503
            for(i=0; i < NumLightSourcesForObject; i++)
 
 
504
            {
 
 
505
                LIGHTBLOCK *lptr = LightSourcesForObject[i];
 
 
506
 
 
 
507
                vertexToLight.vx = lptr->LocalLP.vx - vertexPtr->vx;
 
 
508
                vertexToLight.vy = lptr->LocalLP.vy - vertexPtr->vy;
 
 
509
                vertexToLight.vz = lptr->LocalLP.vz - vertexPtr->vz;
 
 
510
 
 
 
511
                {
 
 
512
                    int dx = abs(vertexToLight.vx);
 
 
513
                    int dy = abs(vertexToLight.vy);
 
 
514
                    int dz = abs(vertexToLight.vz);          
 
 
515
 
 
 
516
                    if (dx > dy)
 
 
517
                    {
 
 
518
                        if (dx > dz)
 
 
519
                            distanceToLight = dx + ((dy+dz)>>2);
 
 
520
                        else
 
 
521
                            distanceToLight = dz + ((dy+dx)>>2);
 
 
522
                    }
 
 
523
                    else
 
 
524
                    {
 
 
525
                        if (dy > dz)
 
 
526
                            distanceToLight = dy + ((dx+dz)>>2);
 
 
527
                        else
 
 
528
                            distanceToLight = dz + ((dx+dy)>>2);
 
 
529
                    }
 
 
530
                }
 
 
531
 
 
 
532
                if(distanceToLight < lptr->LightRange) 
 
 
533
                {
 
 
534
                    int idot = MUL_FIXED(lptr->LightRange-distanceToLight, lptr->BrightnessOverRange);
 
 
535
 
 
 
536
                    if(distanceToLight > 0)
 
 
537
                    {
 
 
538
                        int dotproduct = MUL_FIXED(vertexNormalPtr->vx,vertexToLight.vx)
 
 
539
                             + MUL_FIXED(vertexNormalPtr->vy,vertexToLight.vy)
 
 
540
                             + MUL_FIXED(vertexNormalPtr->vz,vertexToLight.vz);
 
 
541
 
 
 
542
                        if(dotproduct > 0)
 
 
543
                            idot = WideMulNarrowDiv(idot,dotproduct,distanceToLight) + idot/4;
 
 
544
                        else
 
 
545
                            idot /= 4;
 
 
546
                    }
 
 
547
 
 
 
548
                    if(idot < 0)
 
 
549
                    {
 
 
550
                        assert(idot >= 0);
 
 
551
                    }
 
 
552
 
 
 
553
                    specular += idot;            
 
 
554
                }
 
 
555
            }
 
 
556
        }
 
 
557
 
 
 
558
        int greenI = 255;
 
 
559
 
 
 
560
        if (renderVertexPtr->Z > 5000)
 
 
561
        {
 
 
562
            int a = renderVertexPtr->Z - 5000;    
 
 
563
 
 
 
564
            if (a > 4096) 
 
 
565
                greenI = (greenI*4096)/a;
 
 
566
        }
 
 
567
 
 
 
568
        renderVertexPtr->G = greenI;
 
 
569
        ColourIntensityArray[vertexNumber].G = greenI;
 
 
570
 
 
 
571
        renderVertexPtr->R =  ColourIntensityArray[vertexNumber].R = 0;
 
 
572
        renderVertexPtr->B = ColourIntensityArray[vertexNumber].B = 0;
 
 
573
 
 
 
574
        specular >>= 7;
 
 
575
 
 
 
576
        if (specular > 254)
 
 
577
            specular = 254;
 
 
578
 
 
 
579
        assert(specular >= 0 && specular <= 254); 
 
 
580
        renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR = specular;
 
 
581
        renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG = specular;
 
 
582
        renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB = specular;
 
 
583
    }
 
 
584
}
 
 
585
 
 
 
586
static void VertexIntensity_Alien_Sense(RENDERVERTEX *renderVertexPtr)
 
 
587
{
 
 
588
    int vertexNumber = *VertexNumberPtr;
 
 
589
    renderVertexPtr->SpecularR = renderVertexPtr->SpecularG = renderVertexPtr->SpecularB = 0; 
 
 
590
 
 
 
591
    if(ColourIntensityArray[vertexNumber].Stamp == ObjectCounter)
 
 
592
    {
 
 
593
        renderVertexPtr->R = ColourIntensityArray[vertexNumber].R;
 
 
594
        renderVertexPtr->G = ColourIntensityArray[vertexNumber].G;
 
 
595
        renderVertexPtr->B = ColourIntensityArray[vertexNumber].B;    
 
 
596
    }
 
 
597
    else
 
 
598
    {
 
 
599
        int intensity = 255;
 
 
600
        ColourIntensityArray[vertexNumber].Stamp = ObjectCounter;
 
 
601
 
 
 
602
        if (renderVertexPtr->Z > 5000)
 
 
603
        {
 
 
604
            int a = renderVertexPtr->Z - 5000;    
 
 
605
 
 
 
606
            if (a > 1024)
 
 
607
                intensity = (intensity*1024)/a;
 
 
608
        }
 
 
609
 
 
 
610
        renderVertexPtr->R = ColourIntensityArray[vertexNumber].R = intensity;
 
 
611
        renderVertexPtr->G = ColourIntensityArray[vertexNumber].G = intensity;
 
 
612
        renderVertexPtr->B = ColourIntensityArray[vertexNumber].B = intensity;
 
 
613
    }
 
 
614
}
 
 
615
 
 
 
616
static void VertexIntensity_Standard_Opt(RENDERVERTEX *renderVertexPtr)
 
 
617
{
 
 
618
    int vertexNumber = *VertexNumberPtr;
 
 
619
 
 
 
620
    if(ColourIntensityArray[vertexNumber].Stamp == ObjectCounter)
 
 
621
    {
 
 
622
        renderVertexPtr->R = ColourIntensityArray[vertexNumber].R;
 
 
623
        renderVertexPtr->G = ColourIntensityArray[vertexNumber].G;
 
 
624
        renderVertexPtr->B = ColourIntensityArray[vertexNumber].B;    
 
 
625
        renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR;
 
 
626
        renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG;
 
 
627
        renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB;    
 
 
628
    }
 
 
629
    else
 
 
630
    {
 
 
631
        int redI = 0,greenI = 0,blueI = 0;
 
 
632
        int specularR = 0,specularG = 0,specularB = 0;
 
 
633
 
 
 
634
        ColourIntensityArray[vertexNumber].Stamp = ObjectCounter;
 
 
635
 
 
 
636
        {
 
 
637
            VECTORCH *vertexNormalPtr = ((VECTORCH *)Global_ShapeVNormals) + vertexNumber;
 
 
638
            VECTORCH *vertexPtr = ((VECTORCH *)Global_ShapePoints) + vertexNumber;
 
 
639
            VECTORCH vertexToLight;
 
 
640
            int distanceToLight, i;
 
 
641
 
 
 
642
            if(Global_ShapeHeaderPtr->shapeflags & ShapeFlag_PreLit) 
 
 
643
            {
 
 
644
                unsigned int packedI = Global_ShapeHeaderPtr->prelighting[vertexNumber];
 
 
645
                blueI = (packedI & 255) * 257;
 
 
646
 
 
 
647
                packedI >>= 8;
 
 
648
                greenI = (packedI & 255) * 257;
 
 
649
 
 
 
650
                packedI >>= 8;
 
 
651
                redI = (packedI & 255) * 257;
 
 
652
            }
 
 
653
 
 
 
654
            for(i = 0; i < NumLightSourcesForObject; i++)
 
 
655
            {
 
 
656
                LIGHTBLOCK *lptr = LightSourcesForObject[i];
 
 
657
 
 
 
658
                vertexToLight.vx = lptr->LocalLP.vx - vertexPtr->vx;
 
 
659
                vertexToLight.vy = lptr->LocalLP.vy - vertexPtr->vy;
 
 
660
                vertexToLight.vz = lptr->LocalLP.vz - vertexPtr->vz;
 
 
661
 
 
 
662
                {
 
 
663
                    int dx = abs(vertexToLight.vx);
 
 
664
                    int dy = abs(vertexToLight.vy);
 
 
665
                    int dz = abs(vertexToLight.vz);          
 
 
666
 
 
 
667
                    if (dx > dy)
 
 
668
                    {
 
 
669
                        if (dx > dz)
 
 
670
                            distanceToLight = dx + ((dy+dz)>>2);
 
 
671
                        else
 
 
672
                            distanceToLight = dz + ((dy+dx)>>2);
 
 
673
                    }
 
 
674
                    else
 
 
675
                    {
 
 
676
                        if (dy > dz)
 
 
677
                            distanceToLight = dy + ((dx+dz)>>2);
 
 
678
                        else
 
 
679
                            distanceToLight = dz + ((dx+dy)>>2);
 
 
680
                    }
 
 
681
                }
 
 
682
 
 
 
683
                if(distanceToLight < lptr->LightRange) 
 
 
684
                {
 
 
685
                    int idot = MUL_FIXED(lptr->LightRange-distanceToLight, lptr->BrightnessOverRange);
 
 
686
 
 
 
687
                    if(distanceToLight > 0)
 
 
688
                    {
 
 
689
                        int dotproduct = MUL_FIXED(vertexNormalPtr->vx,vertexToLight.vx)
 
 
690
                             + MUL_FIXED(vertexNormalPtr->vy,vertexToLight.vy)
 
 
691
                             + MUL_FIXED(vertexNormalPtr->vz,vertexToLight.vz);
 
 
692
 
 
 
693
                        if(dotproduct > 0)
 
 
694
                            idot = (WideMulNarrowDiv(idot,dotproduct,distanceToLight)+idot/4)/2;
 
 
695
                        else
 
 
696
                            idot /= 8;
 
 
697
                    }
 
 
698
 
 
 
699
                    int r = MUL_FIXED(idot,lptr->RedScale);            
 
 
700
                    int g = MUL_FIXED(idot,lptr->GreenScale);            
 
 
701
                    int b = MUL_FIXED(idot,lptr->BlueScale);            
 
 
702
 
 
 
703
                    redI += r;            
 
 
704
                    greenI += g;            
 
 
705
                    blueI += b;            
 
 
706
 
 
 
707
                    if( !(lptr->LightFlags & LFlag_PreLitSource) && !(lptr->LightFlags & LFlag_NoSpecular) )
 
 
708
                    {
 
 
709
                        specularR += r;            
 
 
710
                        specularG += g;            
 
 
711
                        specularB += b;            
 
 
712
                    }
 
 
713
                }
 
 
714
            }
 
 
715
        }
 
 
716
 
 
 
717
        if(Global_ODB_Ptr->SpecialFXFlags & SFXFLAG_ONFIRE)
 
 
718
        {
 
 
719
            specularR >>= 2;
 
 
720
            specularG >>= 2;
 
 
721
            specularB >>= 2;
 
 
722
 
 
 
723
            redI >>= 1;
 
 
724
            greenI >>= 1;
 
 
725
            blueI >>= 1;
 
 
726
        }
 
 
727
 
 
 
728
        /* Intensity for Textures */
 
 
729
        redI >>= 8;
 
 
730
 
 
 
731
        if(redI > 255)
 
 
732
            redI = 255;
 
 
733
 
 
 
734
        renderVertexPtr->R = ColourIntensityArray[vertexNumber].R = redI;
 
 
735
 
 
 
736
        greenI >>= 8;
 
 
737
 
 
 
738
        if(greenI > 255)
 
 
739
            greenI = 255;
 
 
740
 
 
 
741
        renderVertexPtr->G = ColourIntensityArray[vertexNumber].G = greenI;
 
 
742
 
 
 
743
        blueI >>= 8;
 
 
744
 
 
 
745
        if(blueI > 255)
 
 
746
            blueI = 255;
 
 
747
 
 
 
748
        renderVertexPtr->B = ColourIntensityArray[vertexNumber].B = blueI;
 
 
749
 
 
 
750
        specularR >>= 10;
 
 
751
 
 
 
752
        if(specularR > 255)
 
 
753
            specularR = 255;         
 
 
754
 
 
 
755
        renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR = specularR;
 
 
756
 
 
 
757
        specularG >>= 10;
 
 
758
 
 
 
759
        if(specularG > 255)
 
 
760
            specularG = 255;
 
 
761
 
 
 
762
        renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG = specularG;
 
 
763
 
 
 
764
        specularB >>= 10;
 
 
765
 
 
 
766
        if(specularB > 255) 
 
 
767
            specularB = 255;
 
 
768
 
 
 
769
        renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB = specularB;
 
 
770
    }
 
 
771
}
 
 
772
 
 
 
773
static void VertexIntensity_FullBright(RENDERVERTEX *renderVertexPtr)
 
 
774
{
 
 
775
    int vertexNumber = *VertexNumberPtr;
 
 
776
    renderVertexPtr->R = ColourIntensityArray[vertexNumber].R = 255;
 
 
777
    renderVertexPtr->G = ColourIntensityArray[vertexNumber].G = 255;
 
 
778
    renderVertexPtr->B = ColourIntensityArray[vertexNumber].B = 255;
 
 
779
 
 
 
780
    renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR = 0;
 
 
781
    renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG = 0;
 
 
782
    renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB = 0;
 
 
783
}
 
 
784
 
 
 
785
static void VertexIntensity_DiscoInferno(RENDERVERTEX *renderVertexPtr)
 
 
786
{
 
 
787
    int vertexNumber = *VertexNumberPtr;
 
 
788
 
 
 
789
    if(ColourIntensityArray[vertexNumber].Stamp == ObjectCounter)
 
 
790
    {
 
 
791
        renderVertexPtr->R = ColourIntensityArray[vertexNumber].R;
 
 
792
        renderVertexPtr->G = ColourIntensityArray[vertexNumber].G;
 
 
793
        renderVertexPtr->B = ColourIntensityArray[vertexNumber].B;    
 
 
794
        renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR;
 
 
795
        renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG;
 
 
796
        renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB;    
 
 
797
    }
 
 
798
    else
 
 
799
    {
 
 
800
        int redI = 0,greenI = 0,blueI = 0;
 
 
801
        int specularR = 0,specularG = 0,specularB = 0;
 
 
802
 
 
 
803
        ColourIntensityArray[vertexNumber].Stamp = ObjectCounter;
 
 
804
 
 
 
805
        {
 
 
806
            VECTORCH *vertexNormalPtr = ((VECTORCH *)Global_ShapeVNormals) + vertexNumber;
 
 
807
            VECTORCH *vertexPtr = ((VECTORCH *)Global_ShapePoints) + vertexNumber;
 
 
808
            VECTORCH vertexToLight;
 
 
809
            int distanceToLight, i;
 
 
810
 
 
 
811
            if(Global_ShapeHeaderPtr->shapeflags & ShapeFlag_PreLit) 
 
 
812
            {
 
 
813
                unsigned int packedI = Global_ShapeHeaderPtr->prelighting[vertexNumber];
 
 
814
                blueI = (packedI & 255) * 257;
 
 
815
 
 
 
816
                packedI >>= 8;
 
 
817
                greenI = (packedI & 255) * 257;
 
 
818
 
 
 
819
                packedI >>= 8;
 
 
820
                redI = (packedI & 255) * 257;
 
 
821
            }
 
 
822
 
 
 
823
            for(i=0; i < NumLightSourcesForObject; i++)
 
 
824
            {
 
 
825
                LIGHTBLOCK *lptr = LightSourcesForObject[i];
 
 
826
 
 
 
827
                vertexToLight.vx = lptr->LocalLP.vx - vertexPtr->vx;
 
 
828
                vertexToLight.vy = lptr->LocalLP.vy - vertexPtr->vy;
 
 
829
                vertexToLight.vz = lptr->LocalLP.vz - vertexPtr->vz;
 
 
830
 
 
 
831
                {
 
 
832
                    int dx = abs(vertexToLight.vx);
 
 
833
                    int dy = abs(vertexToLight.vy);
 
 
834
                    int dz = abs(vertexToLight.vz);          
 
 
835
 
 
 
836
                    if (dx > dy)
 
 
837
                    {
 
 
838
                        if (dx > dz)
 
 
839
                            distanceToLight = dx + ((dy+dz)>>2);
 
 
840
                        else
 
 
841
                            distanceToLight = dz + ((dy+dx)>>2);
 
 
842
                    }
 
 
843
                    else
 
 
844
                    {
 
 
845
                        if (dy > dz)
 
 
846
                            distanceToLight = dy + ((dx+dz)>>2);
 
 
847
                        else
 
 
848
                            distanceToLight = dz + ((dx+dy)>>2);
 
 
849
                    }
 
 
850
                }
 
 
851
 
 
 
852
                if(distanceToLight < lptr->LightRange) 
 
 
853
                {
 
 
854
                    int idot = MUL_FIXED(lptr->LightRange-distanceToLight, lptr->BrightnessOverRange);
 
 
855
 
 
 
856
                    if(distanceToLight > 0)
 
 
857
                    {
 
 
858
                        int dotproduct = MUL_FIXED(vertexNormalPtr->vx,vertexToLight.vx)
 
 
859
                             + MUL_FIXED(vertexNormalPtr->vy,vertexToLight.vy)
 
 
860
                             + MUL_FIXED(vertexNormalPtr->vz,vertexToLight.vz);
 
 
861
 
 
 
862
                        if(dotproduct > 0)
 
 
863
                            idot = (WideMulNarrowDiv(idot,dotproduct,distanceToLight)+idot/4)/2;
 
 
864
                        else
 
 
865
                            idot /= 8;
 
 
866
                    }
 
 
867
 
 
 
868
                    int r = MUL_FIXED(idot,lptr->RedScale);
 
 
869
                    int g = MUL_FIXED(idot,lptr->GreenScale);
 
 
870
                    int b = MUL_FIXED(idot,lptr->BlueScale);
 
 
871
 
 
 
872
                    redI += r;
 
 
873
                    greenI += g;
 
 
874
                    blueI += b;
 
 
875
 
 
 
876
                    if(!(lptr->LightFlags & LFlag_PreLitSource) && !(lptr->LightFlags & LFlag_NoSpecular))
 
 
877
                    {
 
 
878
                        specularR += r;
 
 
879
                        specularG += g;
 
 
880
                        specularB += b;
 
 
881
                    }
 
 
882
                }
 
 
883
            }
 
 
884
        }
 
 
885
 
 
 
886
        if(Global_ODB_Ptr->SpecialFXFlags & SFXFLAG_ONFIRE)
 
 
887
        {
 
 
888
            specularR >>= 2;
 
 
889
            specularG >>= 2;
 
 
890
            specularB >>= 2;
 
 
891
 
 
 
892
            redI >>= 1;
 
 
893
            greenI >>= 1;
 
 
894
            blueI >>= 1;
 
 
895
        }
 
 
896
 
 
 
897
        {
 
 
898
            int i = redI + greenI + blueI;
 
 
899
            int si = specularR + specularG + specularB;
 
 
900
 
 
 
901
            VECTORCH vertex = *(((VECTORCH *)Global_ShapePoints)+vertexNumber);
 
 
902
            vertex.vx += Global_ODB_Ptr->ObWorld.vx;
 
 
903
            vertex.vy += Global_ODB_Ptr->ObWorld.vy;
 
 
904
            vertex.vz += Global_ODB_Ptr->ObWorld.vz;
 
 
905
 
 
 
906
            int r = GetSin((vertex.vx+CloakingPhase)&4095);
 
 
907
            r = MUL_FIXED(r,r);
 
 
908
            redI = MUL_FIXED(r,i);
 
 
909
            specularR = MUL_FIXED(r,si);
 
 
910
 
 
 
911
            int g = GetSin((vertex.vy+CloakingPhase/2)&4095);
 
 
912
            g = MUL_FIXED(g,g);
 
 
913
            greenI = MUL_FIXED(g,i);
 
 
914
            specularG = MUL_FIXED(g,si);
 
 
915
 
 
 
916
            int b = GetSin((vertex.vz+CloakingPhase*3)&4095);
 
 
917
            b = MUL_FIXED(b,b);
 
 
918
            blueI = MUL_FIXED(b,i);
 
 
919
            specularB = MUL_FIXED(b,si);
 
 
920
        }
 
 
921
 
 
 
922
        /* Intensity for Textures */
 
 
923
        redI >>= 8;
 
 
924
 
 
 
925
        if(redI > 255)
 
 
926
            redI = 255;
 
 
927
 
 
 
928
        renderVertexPtr->R = ColourIntensityArray[vertexNumber].R = redI;
 
 
929
 
 
 
930
        greenI >>= 8;
 
 
931
 
 
 
932
        if(greenI > 255)
 
 
933
            greenI = 255;
 
 
934
 
 
 
935
        renderVertexPtr->G = ColourIntensityArray[vertexNumber].G = greenI;
 
 
936
 
 
 
937
        blueI >>= 8;
 
 
938
 
 
 
939
        if(blueI > 255)
 
 
940
            blueI = 255;
 
 
941
 
 
 
942
        renderVertexPtr->B = ColourIntensityArray[vertexNumber].B = blueI;
 
 
943
 
 
 
944
        specularR >>= 10;
 
 
945
 
 
 
946
        if(specularR > 255)
 
 
947
            specularR = 255;         
 
 
948
 
 
 
949
        renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR = specularR;
 
 
950
 
 
 
951
        specularG >>= 10;
 
 
952
 
 
 
953
        if(specularG > 255)
 
 
954
            specularG = 255;
 
 
955
 
 
 
956
        renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG = specularG;
 
 
957
 
 
 
958
        specularB >>= 10;
 
 
959
 
 
 
960
        if(specularB > 255)
 
 
961
            specularB = 255;
 
 
962
 
 
 
963
        renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB = specularB;
 
 
964
    }
 
 
965
}
 
 
966
 
 
 
967
static void VertexIntensity_Underwater(RENDERVERTEX *renderVertexPtr)
 
 
968
{
 
 
969
    int vertexNumber = *VertexNumberPtr;
 
 
970
 
 
 
971
    if(ColourIntensityArray[vertexNumber].Stamp == ObjectCounter)
 
 
972
    {
 
 
973
        renderVertexPtr->R = ColourIntensityArray[vertexNumber].R;
 
 
974
        renderVertexPtr->G = ColourIntensityArray[vertexNumber].G;
 
 
975
        renderVertexPtr->B = ColourIntensityArray[vertexNumber].B;    
 
 
976
        renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR;
 
 
977
        renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG;
 
 
978
        renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB;    
 
 
979
    }
 
 
980
    else
 
 
981
    {
 
 
982
        int redI = 0, greenI = 0, blueI = 0;
 
 
983
        int specularR = 0,specularG = 0,specularB = 0;
 
 
984
 
 
 
985
        ColourIntensityArray[vertexNumber].Stamp = ObjectCounter;
 
 
986
 
 
 
987
        {
 
 
988
            VECTORCH *vertexNormalPtr = ((VECTORCH *)Global_ShapeVNormals) + vertexNumber;
 
 
989
            VECTORCH *vertexPtr = ((VECTORCH *)Global_ShapePoints) + vertexNumber;
 
 
990
            VECTORCH vertexToLight;
 
 
991
            int distanceToLight, i;
 
 
992
 
 
 
993
            if(Global_ShapeHeaderPtr->shapeflags & ShapeFlag_PreLit) 
 
 
994
            {
 
 
995
                unsigned int packedI = Global_ShapeHeaderPtr->prelighting[vertexNumber];
 
 
996
                blueI = (packedI & 255) * 257;
 
 
997
 
 
 
998
                packedI >>= 8;
 
 
999
                greenI = (packedI & 255) * 257;
 
 
1000
 
 
 
1001
                packedI >>= 8;
 
 
1002
                redI = (packedI & 255) * 257;
 
 
1003
            }
 
 
1004
 
 
 
1005
            for(i=0; i < NumLightSourcesForObject; i++)
 
 
1006
            {
 
 
1007
                LIGHTBLOCK *lptr = LightSourcesForObject[i];
 
 
1008
 
 
 
1009
                vertexToLight.vx = lptr->LocalLP.vx - vertexPtr->vx;
 
 
1010
                vertexToLight.vy = lptr->LocalLP.vy - vertexPtr->vy;
 
 
1011
                vertexToLight.vz = lptr->LocalLP.vz - vertexPtr->vz;
 
 
1012
 
 
 
1013
                {
 
 
1014
                    int dx = abs(vertexToLight.vx);
 
 
1015
                    int dy = abs(vertexToLight.vy);
 
 
1016
                    int dz = abs(vertexToLight.vz);          
 
 
1017
 
 
 
1018
                    if (dx > dy)
 
 
1019
                    {
 
 
1020
                        if (dx > dz)
 
 
1021
                            distanceToLight = dx + ((dy+dz)>>2);
 
 
1022
                        else
 
 
1023
                            distanceToLight = dz + ((dy+dx)>>2);
 
 
1024
                    }
 
 
1025
                    else
 
 
1026
                    {
 
 
1027
                        if (dy > dz)
 
 
1028
                            distanceToLight = dy + ((dx+dz)>>2);
 
 
1029
                        else
 
 
1030
                            distanceToLight = dz + ((dx+dy)>>2);
 
 
1031
                    }
 
 
1032
                }
 
 
1033
 
 
 
1034
                if(distanceToLight < lptr->LightRange) 
 
 
1035
                {
 
 
1036
                    int idot = MUL_FIXED(lptr->LightRange-distanceToLight,lptr->BrightnessOverRange);
 
 
1037
 
 
 
1038
                    if(distanceToLight > 0)
 
 
1039
                    {
 
 
1040
                        int dotproduct = MUL_FIXED(vertexNormalPtr->vx,vertexToLight.vx)
 
 
1041
                             + MUL_FIXED(vertexNormalPtr->vy,vertexToLight.vy)
 
 
1042
                             + MUL_FIXED(vertexNormalPtr->vz,vertexToLight.vz);
 
 
1043
 
 
 
1044
                        if(dotproduct > 0)
 
 
1045
                            idot = (WideMulNarrowDiv(idot,dotproduct,distanceToLight)+idot/4)/2;
 
 
1046
                        else
 
 
1047
                            idot /= 8;
 
 
1048
                    }
 
 
1049
 
 
 
1050
                    int r = MUL_FIXED(idot,lptr->RedScale);
 
 
1051
                    int g = MUL_FIXED(idot,lptr->GreenScale);
 
 
1052
                    int b = MUL_FIXED(idot,lptr->BlueScale);
 
 
1053
 
 
 
1054
                    redI += r;
 
 
1055
                    greenI += g;
 
 
1056
                    blueI += b;
 
 
1057
 
 
 
1058
                    if(!(lptr->LightFlags & LFlag_PreLitSource) && !(lptr->LightFlags & LFlag_NoSpecular) )
 
 
1059
                    {
 
 
1060
                        specularR += r;
 
 
1061
                        specularG += g;
 
 
1062
                        specularB += b;
 
 
1063
                    }
 
 
1064
                }
 
 
1065
            }
 
 
1066
        }
 
 
1067
 
 
 
1068
        if(Global_ODB_Ptr->SpecialFXFlags & SFXFLAG_ONFIRE)
 
 
1069
        {
 
 
1070
            specularR >>= 2;
 
 
1071
            specularG >>= 2;
 
 
1072
            specularB >>= 2;
 
 
1073
 
 
 
1074
            redI >>= 1;
 
 
1075
            greenI >>= 1;
 
 
1076
            blueI >>= 1;
 
 
1077
        }
 
 
1078
 
 
 
1079
        if (specularB < renderVertexPtr->Z*4)
 
 
1080
            specularB = renderVertexPtr->Z*4;
 
 
1081
 
 
 
1082
        /* Intensity for Textures */
 
 
1083
        redI >>= 8;
 
 
1084
 
 
 
1085
        if(redI > 255)
 
 
1086
            redI = 255;
 
 
1087
 
 
 
1088
        renderVertexPtr->R = ColourIntensityArray[vertexNumber].R = redI;
 
 
1089
 
 
 
1090
        greenI >>= 8;
 
 
1091
 
 
 
1092
        if(greenI > 255) 
 
 
1093
            greenI = 255;
 
 
1094
 
 
 
1095
        renderVertexPtr->G = ColourIntensityArray[vertexNumber].G = greenI;
 
 
1096
 
 
 
1097
        blueI >>= 8;
 
 
1098
 
 
 
1099
        if(blueI > 255) 
 
 
1100
            blueI = 255;
 
 
1101
 
 
 
1102
        renderVertexPtr->B = ColourIntensityArray[vertexNumber].B = blueI;
 
 
1103
 
 
 
1104
        specularR >>= 10;
 
 
1105
 
 
 
1106
        if(specularR > 255)
 
 
1107
            specularR = 255;
 
 
1108
 
 
 
1109
        renderVertexPtr->SpecularR = ColourIntensityArray[vertexNumber].SpecularR = specularR;
 
 
1110
 
 
 
1111
        specularG >>= 10;
 
 
1112
 
 
 
1113
        if(specularG > 255)
 
 
1114
            specularG = 255;
 
 
1115
 
 
 
1116
        renderVertexPtr->SpecularG = ColourIntensityArray[vertexNumber].SpecularG = specularG;
 
 
1117
 
 
 
1118
        specularB >>= 10;
 
 
1119
 
 
 
1120
        if(specularB > 255)
 
 
1121
            specularB = 255;
 
 
1122
 
 
 
1123
        renderVertexPtr->SpecularB = ColourIntensityArray[vertexNumber].SpecularB = specularB;
 
 
1124
    }
 
 
1125
}
 
 
1126
 
 
 
1127
static void PredatorThermalVisionPolygon_Construct(POLYHEADER *polyPtr)
 
 
1128
{
 
 
1129
    RENDERVERTEX *renderVerticesPtr = VerticesBuffer;
 
 
1130
    int i = RenderPolygon.NumberOfVertices;
 
 
1131
 
 
 
1132
    VertexNumberPtr = &polyPtr->Poly1stPt;
 
 
1133
 
 
 
1134
    do
 
 
1135
    {
 
 
1136
        VECTORCH *vertexPtr = &RotatedPts[*VertexNumberPtr];
 
 
1137
        renderVerticesPtr->X = vertexPtr->vx;
 
 
1138
        renderVerticesPtr->Y = vertexPtr->vy;
 
 
1139
        renderVerticesPtr->Z = vertexPtr->vz;
 
 
1140
 
 
 
1141
        {
 
 
1142
            int alpha;
 
 
1143
            if (Global_ODB_Ptr->SpecialFXFlags & SFXFLAG_ISAFFECTEDBYHEAT)
 
 
1144
            {
 
 
1145
                int distanceFromHeatSource = 100000;
 
 
1146
                int sourceNumber = NumberOfHeatSources;
 
 
1147
 
 
 
1148
                while(sourceNumber--)
 
 
1149
                {
 
 
1150
                    VECTORCH mag;
 
 
1151
                    mag.vx = vertexPtr->vx - HeatSourceList[sourceNumber].Position.vx;
 
 
1152
                    mag.vy = vertexPtr->vy - HeatSourceList[sourceNumber].Position.vy;
 
 
1153
                    mag.vz = vertexPtr->vz - HeatSourceList[sourceNumber].Position.vz;
 
 
1154
 
 
 
1155
                    int m = Approximate3dMagnitude(&mag) * 64;
 
 
1156
 
 
 
1157
                    if(m < distanceFromHeatSource)
 
 
1158
                        distanceFromHeatSource = m;
 
 
1159
                }
 
 
1160
 
 
 
1161
                alpha = distanceFromHeatSource + (GetSin(CloakingPhase & 4095) >> 3);
 
 
1162
 
 
 
1163
                if (alpha > 65536)
 
 
1164
                    alpha = 65536;
 
 
1165
            }
 
 
1166
            else
 
 
1167
            {
 
 
1168
                alpha = 65536;
 
 
1169
            }
 
 
1170
 
 
 
1171
            {
 
 
1172
                int brightness = MUL_FIXED(MUL_FIXED(alpha, alpha), 1275);
 
 
1173
 
 
 
1174
                if (brightness < 256)
 
 
1175
                {
 
 
1176
                    renderVerticesPtr->R = 255;
 
 
1177
                    renderVerticesPtr->G = brightness;
 
 
1178
                    renderVerticesPtr->B = 0;
 
 
1179
                }
 
 
1180
                else if (brightness < 255 + 256)
 
 
1181
                {
 
 
1182
                    int b = brightness - 255;
 
 
1183
                    renderVerticesPtr->R = (255-b);
 
 
1184
                    renderVerticesPtr->G = 255;
 
 
1185
                    renderVerticesPtr->B = 0;
 
 
1186
                }
 
 
1187
                else if (brightness < 255 * 2 + 256)
 
 
1188
                {
 
 
1189
                    int b = brightness-255*2;
 
 
1190
                    renderVerticesPtr->R = 0;
 
 
1191
                    renderVerticesPtr->G = 255;
 
 
1192
                    renderVerticesPtr->B = b;
 
 
1193
                }
 
 
1194
                else if (brightness < 255 * 3 + 256)
 
 
1195
                {
 
 
1196
                    int b = brightness-255*3;
 
 
1197
                    renderVerticesPtr->R = 0;
 
 
1198
                    renderVerticesPtr->G = 255-b;
 
 
1199
                    renderVerticesPtr->B = 255;
 
 
1200
                }
 
 
1201
                else
 
 
1202
                {
 
 
1203
                    int b = brightness-255*4;
 
 
1204
                    renderVerticesPtr->R = 0;
 
 
1205
                    renderVerticesPtr->G = 0;
 
 
1206
                    renderVerticesPtr->B = 255-b/2;
 
 
1207
                }
 
 
1208
             }
 
 
1209
        }
 
 
1210
 
 
 
1211
        renderVerticesPtr++;
 
 
1212
        VertexNumberPtr++;
 
 
1213
 
 
 
1214
    } while(--i);
 
 
1215
}
 
 
1216
 
 
 
1217
static int PolygonWithinFrustrum(POLYHEADER *polyPtr)
 
 
1218
{            
 
 
1219
    int* vertexNumberPtr = &polyPtr->Poly1stPt;
 
 
1220
 
 
 
1221
    if (polyPtr->PolyFlags & iflag_notvis)
 
 
1222
        return 0;
 
 
1223
 
 
 
1224
    char inFrustrumFlag = 0;
 
 
1225
       char noClippingFlag = INSIDE_FRUSTRUM;
 
 
1226
    RenderPolygon.NumberOfVertices = 0; 
 
 
1227
 
 
 
1228
    while(*vertexNumberPtr != -1)
 
 
1229
    {
 
 
1230
        int vertexNumber = *vertexNumberPtr++;
 
 
1231
 
 
 
1232
        inFrustrumFlag |= FrustrumFlagForVertex[vertexNumber];
 
 
1233
        noClippingFlag &= FrustrumFlagForVertex[vertexNumber];
 
 
1234
 
 
 
1235
        /* count the number of points in the polygon; this is used for all the loops that follow */
 
 
1236
           RenderPolygon.NumberOfVertices++; 
 
 
1237
    }
 
 
1238
 
 
 
1239
    if (inFrustrumFlag != INSIDE_FRUSTRUM)
 
 
1240
        return 0;
 
 
1241
 
 
 
1242
    /* at this point we know that the poly is inside the view frustrum */
 
 
1243
 
 
 
1244
    /* if not a sprite, test direction of poly */
 
 
1245
    if (!(polyPtr->PolyFlags & iflag_no_bfc))
 
 
1246
    {
 
 
1247
        VECTORCH pop;
 
 
1248
        VECTORCH *normalPtr = (VECTORCH*)(Global_ShapeNormals + polyPtr->PolyNormalIndex);
 
 
1249
 
 
 
1250
        if(Global_ODB_Ptr->ObMorphCtrl)
 
 
1251
        {
 
 
1252
               VECTORCH *shape1PointsPtr;
 
 
1253
            VECTORCH *shape2PointsPtr;
 
 
1254
 
 
 
1255
            /* Set up the morph data */
 
 
1256
            GetMorphDisplay(&MorphDisplay, Global_ODB_Ptr);
 
 
1257
 
 
 
1258
               struct shapeheader *shape1Ptr = MorphDisplay.md_sptr1;
 
 
1259
 
 
 
1260
            switch(MorphDisplay.md_lerp)
 
 
1261
            {
 
 
1262
                case 0x0000:
 
 
1263
                {
 
 
1264
                    shape1PointsPtr = (VECTORCH *)*shape1Ptr->points;
 
 
1265
                    pop = shape1PointsPtr[polyPtr->Poly1stPt];    
 
 
1266
                }
 
 
1267
                break;
 
 
1268
                case 0xffff:
 
 
1269
                {
 
 
1270
                    struct shapeheader* shape2Ptr = MorphDisplay.md_sptr2;
 
 
1271
 
 
 
1272
                    shape2PointsPtr = (VECTORCH *)*shape2Ptr->points;
 
 
1273
                    pop = shape2PointsPtr[polyPtr->Poly1stPt];    
 
 
1274
                }
 
 
1275
                break;
 
 
1276
                default:
 
 
1277
                {
 
 
1278
                    struct shapeheader* shape2Ptr = MorphDisplay.md_sptr2;
 
 
1279
 
 
 
1280
                    shape1PointsPtr = (VECTORCH *)(*shape1Ptr->points);
 
 
1281
                    shape2PointsPtr = (VECTORCH *)(*shape2Ptr->points);
 
 
1282
 
 
 
1283
                    {
 
 
1284
                        VECTORCH vertex1 = shape1PointsPtr[polyPtr->Poly1stPt];
 
 
1285
                        VECTORCH vertex2 = shape2PointsPtr[polyPtr->Poly1stPt];
 
 
1286
 
 
 
1287
                        if( (vertex1.vx == vertex2.vx && vertex1.vy == vertex2.vy && vertex1.vz == vertex2.vz) )
 
 
1288
                        {
 
 
1289
                            pop = vertex1;
 
 
1290
                        }
 
 
1291
                        else
 
 
1292
                        {
 
 
1293
                            /* KJL 15:27:20 05/22/97 - I've changed this to speed things up, If a vertex
 
 
1294
                            component has a magnitude greater than 32768 things will go wrong. */
 
 
1295
                            pop.vx = vertex1.vx + (((vertex2.vx-vertex1.vx)*MorphDisplay.md_lerp)>>16);
 
 
1296
                            pop.vy = vertex1.vy + (((vertex2.vy-vertex1.vy)*MorphDisplay.md_lerp)>>16);
 
 
1297
                            pop.vz = vertex1.vz + (((vertex2.vz-vertex1.vz)*MorphDisplay.md_lerp)>>16);
 
 
1298
                        }
 
 
1299
                    }
 
 
1300
                }
 
 
1301
            }
 
 
1302
         }
 
 
1303
        else
 
 
1304
        {
 
 
1305
            /* Get the 1st polygon point as the POP */
 
 
1306
            VECTORCH *pointsArray = (VECTORCH*)(Global_ShapePoints);
 
 
1307
            pop = pointsArray[polyPtr->Poly1stPt];
 
 
1308
        }
 
 
1309
 
 
 
1310
        pop.vx -= LocalView.vx;
 
 
1311
        pop.vy -= LocalView.vy;
 
 
1312
        pop.vz -= LocalView.vz;
 
 
1313
 
 
 
1314
        if (DotProduct(&pop, normalPtr) > 0)
 
 
1315
            return 0;
 
 
1316
    }
 
 
1317
 
 
 
1318
    /* yes, we need to draw poly */
 
 
1319
    return (noClippingFlag == INSIDE_FRUSTRUM) ? 2 : 1;
 
 
1320
}
 
 
1321
 
 
 
1322
static void PredatorThermalVision_ShapePipeline(struct shapeheader* shapePtr)
 
 
1323
{
 
 
1324
    int numitems = shapePtr->numitems;
 
 
1325
    int** itemArrayPtr = shapePtr->items;
 
 
1326
 
 
 
1327
    assert(numitems);
 
 
1328
 
 
 
1329
    do
 
 
1330
    {
 
 
1331
        POLYHEADER *polyPtr = (POLYHEADER*) (*itemArrayPtr++);
 
 
1332
 
 
 
1333
        int pif = PolygonWithinFrustrum(polyPtr);
 
 
1334
 
 
 
1335
        if (pif)
 
 
1336
        {
 
 
1337
            PredatorThermalVisionPolygon_Construct(polyPtr);
 
 
1338
 
 
 
1339
            if (pif != 2)
 
 
1340
            {
 
 
1341
                GouraudPolygon_ClipWithZ();
 
 
1342
 
 
 
1343
                if(RenderPolygon.NumberOfVertices < 3)
 
 
1344
                    continue;
 
 
1345
 
 
 
1346
                GouraudPolygon_ClipWithNegativeX();
 
 
1347
 
 
 
1348
                if(RenderPolygon.NumberOfVertices < 3)
 
 
1349
                    continue;
 
 
1350
 
 
 
1351
                GouraudPolygon_ClipWithPositiveY();
 
 
1352
 
 
 
1353
                if(RenderPolygon.NumberOfVertices < 3)
 
 
1354
                    continue;
 
 
1355
 
 
 
1356
                GouraudPolygon_ClipWithNegativeY();
 
 
1357
 
 
 
1358
                if(RenderPolygon.NumberOfVertices < 3)
 
 
1359
                    continue;
 
 
1360
 
 
 
1361
                GouraudPolygon_ClipWithPositiveX();
 
 
1362
 
 
 
1363
                if(RenderPolygon.NumberOfVertices < 3)
 
 
1364
                    continue;
 
 
1365
 
 
 
1366
                PredatorThermalVisionPolygon_Output(RenderPolygon.Vertices);
 
 
1367
              }
 
 
1368
              else
 
 
1369
            {
 
 
1370
                PredatorThermalVisionPolygon_Output(VerticesBuffer);
 
 
1371
            }
 
 
1372
        }
 
 
1373
 
 
 
1374
    } while(--numitems);
 
 
1375
}
 
 
1376
 
 
 
1377
/*
 
 
1378
 WideMul2NarrowDiv
 
 
1379
 
 
 
1380
 This function takes two pairs of integers, adds their 64-bit products
 
 
1381
 together, divides the summed product with another integer and then returns
 
 
1382
 the result of that divide, which is also an integer.
 
 
1383
 
 
 
1384
*/
 
 
1385
 
 
 
1386
static int WideMul2NarrowDiv(int a, int b, int c, int d) 
 
 
1387
{
 
 
1388
    int64_t a_b = (int64_t)a * (int64_t)b;
 
 
1389
    int64_t c_d = (int64_t)c * (int64_t)d;
 
 
1390
 
 
 
1391
    return (a_b + c_d)/c;
 
 
1392
}
 
 
1393
 
 
 
1394
static void CreateTxAnimUVArray(intptr_t * txa_data, int* uv_array, int* shapeitemptr)
 
 
1395
{
 
 
1396
    int Orient, Scale;
 
 
1397
    int OrientX, OrientY;
 
 
1398
    int ScaleX, ScaleY;
 
 
1399
    POLYHEADER *pheader = (POLYHEADER*) shapeitemptr;
 
 
1400
 
 
 
1401
    /* The sequence will have been copied across by the control block */
 
 
1402
 
 
 
1403
    int sequence = *txa_data++;
 
 
1404
    TXANIMHEADER **txah_ptr = (TXANIMHEADER **) txa_data;
 
 
1405
    TXANIMHEADER *txah = txah_ptr[sequence];
 
 
1406
    TXANIMFRAME *txaf = txah->txa_framedata;
 
 
1407
 
 
 
1408
    /* Because the current frame can be set from outside, clamp it first */
 
 
1409
 
 
 
1410
    if(txah->txa_currentframe < 0) 
 
 
1411
        txah->txa_currentframe = 0;
 
 
1412
 
 
 
1413
    if(txah->txa_currentframe >= txah->txa_maxframe) 
 
 
1414
        txah->txa_currentframe = txah->txa_maxframe - 1;
 
 
1415
 
 
 
1416
    /* Frame # */
 
 
1417
 
 
 
1418
    int CurrentFrame  = txah->txa_currentframe >> 16;
 
 
1419
    int Alpha         = txah->txa_currentframe - (CurrentFrame << 16);
 
 
1420
    int OneMinusAlpha = ONE_FIXED - Alpha;
 
 
1421
 
 
 
1422
    /* Start and End Frame */
 
 
1423
 
 
 
1424
    int NextFrame = CurrentFrame + 1;
 
 
1425
 
 
 
1426
    if(NextFrame >= txah->txa_numframes)
 
 
1427
        NextFrame = 0;
 
 
1428
 
 
 
1429
    TXANIMFRAME *txaf0 = &txaf[CurrentFrame];
 
 
1430
    TXANIMFRAME *txaf1 = &txaf[NextFrame];
 
 
1431
 
 
 
1432
    /*
 
 
1433
 
 
 
1434
    Write the image index back to the item by overwriting the shape data.
 
 
1435
    This is not elegant but it is one of the kind of things you expect to
 
 
1436
    have happen when a major new feature is retro-fitted to a system.
 
 
1437
 
 
 
1438
    */
 
 
1439
 
 
 
1440
    #define ClrTxIndex 0xffff0000   /* AND with this to clear the low 16-bits */
 
 
1441
 
 
 
1442
    pheader->PolyColour &= ClrTxIndex;
 
 
1443
    pheader->PolyColour |= txaf0->txf_image;
 
 
1444
 
 
 
1445
    int* txaf0_uv = txaf0->txf_uvdata;
 
 
1446
    int* txaf1_uv = txaf1->txf_uvdata;
 
 
1447
 
 
 
1448
    // Calculate UVs
 
 
1449
 
 
 
1450
    int *iptr = uv_array;
 
 
1451
 
 
 
1452
    if(txah->txa_flags & txa_flag_interpolate_uvs) 
 
 
1453
    {
 
 
1454
        int i = txaf0->txf_numuvs;
 
 
1455
 
 
 
1456
        for(; i; i--) 
 
 
1457
        {
 
 
1458
            iptr[0] = MUL_FIXED(txaf0_uv[0], OneMinusAlpha) + MUL_FIXED(txaf1_uv[0], Alpha);
 
 
1459
 
 
 
1460
            iptr[1] = MUL_FIXED(txaf0_uv[1], OneMinusAlpha) + MUL_FIXED(txaf1_uv[1], Alpha);
 
 
1461
 
 
 
1462
            // printf("%d, %d\n", iptr[0] >> 16, iptr[1] >> 16);
 
 
1463
 
 
 
1464
            txaf0_uv += 2;
 
 
1465
            txaf1_uv += 2;
 
 
1466
            iptr += 2;
 
 
1467
        }
 
 
1468
    }
 
 
1469
    else 
 
 
1470
    {
 
 
1471
        int i = txaf0->txf_numuvs;
 
 
1472
 
 
 
1473
        for(; i; i--) 
 
 
1474
        {
 
 
1475
            iptr[0] = txaf0_uv[0];
 
 
1476
            iptr[1] = txaf0_uv[1];
 
 
1477
 
 
 
1478
            // printf("%d, %d\n", iptr[0] >> 16, iptr[1] >> 16);
 
 
1479
 
 
 
1480
            txaf0_uv += 2;
 
 
1481
            iptr += 2;
 
 
1482
        }
 
 
1483
    }
 
 
1484
 
 
 
1485
    // Interpolate Orient and Scale
 
 
1486
 
 
 
1487
    int o1 = txaf0->txf_orient;
 
 
1488
    int o2 = txaf1->txf_orient;
 
 
1489
 
 
 
1490
    if(o1 == o2)
 
 
1491
    {
 
 
1492
        Orient = o1;
 
 
1493
    }
 
 
1494
    else 
 
 
1495
    {
 
 
1496
        int od = o1 - o2;
 
 
1497
 
 
 
1498
        if(od < 0)
 
 
1499
            od = -od;
 
 
1500
 
 
 
1501
        if(od >= deg180) 
 
 
1502
        {
 
 
1503
            o1 <<= (32 - 12);
 
 
1504
            o1 >>= (32 - 12);
 
 
1505
            o2 <<= (32 - 12);
 
 
1506
            o2 >>= (32 - 12);
 
 
1507
        }
 
 
1508
 
 
 
1509
        Orient = MUL_FIXED(o1, OneMinusAlpha) + MUL_FIXED(o2, Alpha);
 
 
1510
        Orient &= wrap360;
 
 
1511
    }
 
 
1512
 
 
 
1513
    if(txaf0->txf_scale == txaf1->txf_scale) 
 
 
1514
        Scale = txaf0->txf_scale;
 
 
1515
    else 
 
 
1516
        Scale = WideMul2NarrowDiv(txaf0->txf_scale, OneMinusAlpha, txaf1->txf_scale, Alpha);
 
 
1517
 
 
 
1518
    // Interpolate Orient and Scale Origins
 
 
1519
 
 
 
1520
    if(txaf0->txf_orientx == txaf1->txf_orientx) 
 
 
1521
        OrientX = txaf0->txf_orientx;
 
 
1522
    else
 
 
1523
        OrientX = MUL_FIXED(txaf0->txf_orientx, OneMinusAlpha) + MUL_FIXED(txaf1->txf_orientx, Alpha);
 
 
1524
 
 
 
1525
    if(txaf0->txf_orienty == txaf1->txf_orienty) 
 
 
1526
        OrientY = txaf0->txf_orienty;
 
 
1527
    else
 
 
1528
        OrientY = MUL_FIXED(txaf0->txf_orienty, OneMinusAlpha) + MUL_FIXED(txaf1->txf_orienty, Alpha);
 
 
1529
 
 
 
1530
    if(txaf0->txf_scalex == txaf1->txf_scalex) 
 
 
1531
        ScaleX = txaf0->txf_scalex;
 
 
1532
    else 
 
 
1533
        ScaleX = MUL_FIXED(txaf0->txf_scalex, OneMinusAlpha) + MUL_FIXED(txaf1->txf_scalex, Alpha);
 
 
1534
 
 
 
1535
    if(txaf0->txf_scaley == txaf1->txf_scaley) 
 
 
1536
        ScaleY = txaf0->txf_scaley;
 
 
1537
    else 
 
 
1538
        ScaleY = MUL_FIXED(txaf0->txf_scaley, OneMinusAlpha) + MUL_FIXED(txaf1->txf_scaley, Alpha);
 
 
1539
 
 
 
1540
/*
 
 
1541
    printf("Alpha         = %d\n", Alpha);
 
 
1542
    printf("OneMinusAlpha = %d\n", OneMinusAlpha);
 
 
1543
    printf("Orient = %d\n", Orient);
 
 
1544
    printf("txaf0->txf_scale = %d\n", txaf0->txf_scale);
 
 
1545
    printf("txaf1->txf_scale = %d\n", txaf1->txf_scale);
 
 
1546
    printf("Scale  = %d\n", Scale);
 
 
1547
*/
 
 
1548
 
 
 
1549
#if 1
 
 
1550
    // Rotate UV Array
 
 
1551
 
 
 
1552
    if(Orient)
 
 
1553
    {
 
 
1554
        int i = txaf0->txf_numuvs;
 
 
1555
        int sin = GetSin(Orient);
 
 
1556
        int cos = GetCos(Orient);
 
 
1557
        iptr = uv_array;
 
 
1558
 
 
 
1559
        for(; i; i--) 
 
 
1560
        {
 
 
1561
            int x = iptr[0] - OrientX;
 
 
1562
            int y = iptr[1] - OrientY;
 
 
1563
            int x1 = MUL_FIXED(x, cos) - MUL_FIXED(y, sin);
 
 
1564
            int y1 = MUL_FIXED(x, sin) + MUL_FIXED(y, cos);
 
 
1565
 
 
 
1566
            iptr[0] = x1 + OrientX;
 
 
1567
            iptr[1] = y1 + OrientY;
 
 
1568
 
 
 
1569
            iptr += 2;
 
 
1570
        }
 
 
1571
    }
 
 
1572
 
 
 
1573
    // Scale UV Array
 
 
1574
 
 
 
1575
    if(Scale != ONE_FIXED) 
 
 
1576
    {
 
 
1577
        int i = txaf0->txf_numuvs;
 
 
1578
        iptr = uv_array;
 
 
1579
 
 
 
1580
        for(; i; i--) 
 
 
1581
        {
 
 
1582
            int x = iptr[0] - ScaleX;
 
 
1583
            int y = iptr[1] - ScaleY;
 
 
1584
 
 
 
1585
            x = MUL_FIXED(x, Scale);
 
 
1586
            y = MUL_FIXED(y, Scale);
 
 
1587
 
 
 
1588
            iptr[0] = x + ScaleX;
 
 
1589
            iptr[1] = y + ScaleY;
 
 
1590
 
 
 
1591
            iptr += 2;
 
 
1592
        }
 
 
1593
    }
 
 
1594
#endif
 
 
1595
 
 
 
1596
/*
 
 
1597
    printf("Current Frame = %d\n", txah->txa_currentframe);
 
 
1598
    printf("Current Frame = %d\n", CurrentFrame);
 
 
1599
    printf("Next Frame    = %d\n", NextFrame);
 
 
1600
    printf("Alpha         = %d\n", Alpha);
 
 
1601
*/
 
 
1602
 
 
 
1603
}
 
 
1604
 
 
 
1605
static void PredatorSeeAliensVisionPolygon_Construct(POLYHEADER *polyPtr)
 
 
1606
{
 
 
1607
    int    alpha;
 
 
1608
    // get ptr to uv coords for this polygon
 
 
1609
    int*    texture_defn_ptr = Global_ShapeHeaderPtr->sh_textures[(polyPtr->PolyColour >> TxDefn)];
 
 
1610
    RENDERVERTEX*    renderVerticesPtr = VerticesBuffer;
 
 
1611
    int i = RenderPolygon.NumberOfVertices;
 
 
1612
 
 
 
1613
    VertexNumberPtr = &polyPtr->Poly1stPt;
 
 
1614
 
 
 
1615
    if(polyPtr->PolyFlags & iflag_txanim)
 
 
1616
    {
 
 
1617
        // Create the UV array
 
 
1618
        int uv_array[18];
 
 
1619
        CreateTxAnimUVArray((intptr_t*)texture_defn_ptr, uv_array, (int*)polyPtr);
 
 
1620
        texture_defn_ptr = uv_array;
 
 
1621
    }
 
 
1622
 
 
 
1623
    if( (Global_ODB_Ptr->SpecialFXFlags & SFXFLAG_MELTINGINTOGROUND) && (Global_ODB_Ptr->ObFlags2 < ONE_FIXED) )    
 
 
1624
    {
 
 
1625
        alpha = Global_ODB_Ptr->ObFlags2 >> 8;
 
 
1626
        RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL;
 
 
1627
    }
 
 
1628
    else
 
 
1629
    {
 
 
1630
        alpha = 0;
 
 
1631
        RenderPolygon.TranslucencyMode = TRANSLUCENCY_OFF;
 
 
1632
    }
 
 
1633
 
 
 
1634
    do
 
 
1635
    {
 
 
1636
        VECTORCH *vertexPtr = &RotatedPts[*VertexNumberPtr];
 
 
1637
 
 
 
1638
        if(polyPtr->PolyFlags & iflag_txanim)
 
 
1639
        {
 
 
1640
            renderVerticesPtr->U = texture_defn_ptr[0];
 
 
1641
            renderVerticesPtr->V = texture_defn_ptr[1];
 
 
1642
        }
 
 
1643
        else
 
 
1644
        {
 
 
1645
            renderVerticesPtr->U = texture_defn_ptr[0] << 16;
 
 
1646
            renderVerticesPtr->V = texture_defn_ptr[1] << 16;
 
 
1647
        }
 
 
1648
 
 
 
1649
        renderVerticesPtr->X = vertexPtr->vx;
 
 
1650
        renderVerticesPtr->Y = vertexPtr->vy;
 
 
1651
        renderVerticesPtr->Z = vertexPtr->vz;
 
 
1652
 
 
 
1653
        {
 
 
1654
            VECTORCH mag = RotatedPts[*VertexNumberPtr]; //*(((VECTORCH *)Global_ShapeVNormals) + *VertexNumberPtr);
 
 
1655
            int colour;
 
 
1656
            mag.vx = vertexPtr->vx - Global_ODB_Ptr->ObView.vx;
 
 
1657
            mag.vy = vertexPtr->vy - Global_ODB_Ptr->ObView.vy;
 
 
1658
            mag.vz = vertexPtr->vz - Global_ODB_Ptr->ObView.vz;
 
 
1659
 
 
 
1660
            colour = GetSin(((mag.vx+mag.vy+mag.vz)*8+CloakingPhase)&4095);
 
 
1661
            colour = MUL_FIXED(colour,colour);
 
 
1662
            renderVerticesPtr->B = MUL_FIXED(colour,255);
 
 
1663
            renderVerticesPtr->R = renderVerticesPtr->B/2;
 
 
1664
            renderVerticesPtr->G = renderVerticesPtr->B/2;
 
 
1665
 
 
 
1666
            colour = MUL_FIXED(colour,colour);
 
 
1667
            colour = MUL_FIXED(colour,colour);
 
 
1668
 
 
 
1669
            renderVerticesPtr->SpecularR = colour/1024;
 
 
1670
            renderVerticesPtr->SpecularG = colour/1024;
 
 
1671
            renderVerticesPtr->SpecularB = colour/1024;
 
 
1672
            renderVerticesPtr->A = alpha;
 
 
1673
        }
 
 
1674
 
 
 
1675
        texture_defn_ptr += 2;
 
 
1676
        renderVerticesPtr++;
 
 
1677
        VertexNumberPtr++;
 
 
1678
 
 
 
1679
    } while(--i);
 
 
1680
}
 
 
1681
 
 
 
1682
static void PredatorSeeAliensVision_ShapePipeline(struct shapeheader* shapePtr)
 
 
1683
{
 
 
1684
    int numitems = shapePtr->numitems;
 
 
1685
    int** itemArrayPtr = shapePtr->items;
 
 
1686
 
 
 
1687
    assert(numitems);
 
 
1688
 
 
 
1689
    do
 
 
1690
    {
 
 
1691
        POLYHEADER *polyPtr = (POLYHEADER*) (*itemArrayPtr++);
 
 
1692
 
 
 
1693
        switch (polyPtr->PolyItemType)
 
 
1694
        {
 
 
1695
             case I_ZB_Gouraud3dTexturedPolygon:
 
 
1696
            case I_ZB_Gouraud2dTexturedPolygon:
 
 
1697
            {
 
 
1698
                int pif = PolygonWithinFrustrum(polyPtr);
 
 
1699
 
 
 
1700
                if (pif)
 
 
1701
                {         
 
 
1702
                    PredatorSeeAliensVisionPolygon_Construct(polyPtr);
 
 
1703
 
 
 
1704
                    if (pif != 2)
 
 
1705
                    {
 
 
1706
                        GouraudTexturedPolygon_ClipWithZ();
 
 
1707
 
 
 
1708
                        if(RenderPolygon.NumberOfVertices < 3)
 
 
1709
                            continue;
 
 
1710
 
 
 
1711
                        GouraudTexturedPolygon_ClipWithNegativeX();
 
 
1712
 
 
 
1713
                        if(RenderPolygon.NumberOfVertices < 3)
 
 
1714
                            continue;
 
 
1715
 
 
 
1716
                        GouraudTexturedPolygon_ClipWithPositiveY();
 
 
1717
 
 
 
1718
                        if(RenderPolygon.NumberOfVertices < 3)
 
 
1719
                            continue;
 
 
1720
 
 
 
1721
                        GouraudTexturedPolygon_ClipWithNegativeY();
 
 
1722
 
 
 
1723
                        if(RenderPolygon.NumberOfVertices < 3)
 
 
1724
                            continue;
 
 
1725
 
 
 
1726
                        GouraudTexturedPolygon_ClipWithPositiveX();
 
 
1727
 
 
 
1728
                        if(RenderPolygon.NumberOfVertices < 3)
 
 
1729
                            continue;
 
 
1730
 
 
 
1731
                        ZBufferedGouraudTexturedPolygon_Output(polyPtr, RenderPolygon.Vertices);
 
 
1732
                    }
 
 
1733
                    else
 
 
1734
                    {
 
 
1735
                        ZBufferedGouraudTexturedPolygon_Output(polyPtr, VerticesBuffer);
 
 
1736
                    }
 
 
1737
                }
 
 
1738
            }
 
 
1739
            default:
 
 
1740
                break;
 
 
1741
        }
 
 
1742
 
 
 
1743
    } while(--numitems);
 
 
1744
}
 
 
1745
 
 
 
1746
static void CloakedPolygon_Construct(POLYHEADER *polyPtr, int CloakingMode)
 
 
1747
{
 
 
1748
    RENDERVERTEX *renderVerticesPtr = VerticesBuffer;
 
 
1749
    int i = RenderPolygon.NumberOfVertices;
 
 
1750
 
 
 
1751
    // get ptr to uv coords for this polygon
 
 
1752
    int *texture_defn_ptr = Global_ShapeHeaderPtr->sh_textures[(polyPtr->PolyColour >> TxDefn)];
 
 
1753
 
 
 
1754
    VertexNumberPtr = &polyPtr->Poly1stPt;
 
 
1755
 
 
 
1756
    do
 
 
1757
    {
 
 
1758
        VECTORCH *vertexPtr = &RotatedPts[*VertexNumberPtr];
 
 
1759
        renderVerticesPtr->X = vertexPtr->vx;
 
 
1760
        renderVerticesPtr->Y = vertexPtr->vy;
 
 
1761
        renderVerticesPtr->Z = vertexPtr->vz;
 
 
1762
        renderVerticesPtr->U = texture_defn_ptr[0] << 16;
 
 
1763
        renderVerticesPtr->V = texture_defn_ptr[1] << 16;
 
 
1764
 
 
 
1765
        VertexIntensity(renderVerticesPtr);
 
 
1766
 
 
 
1767
        {
 
 
1768
            VECTORCH mag;
 
 
1769
 
 
 
1770
            mag.vx = abs(vertexPtr->vx - ObjectCentre.vx);
 
 
1771
            mag.vy = abs(vertexPtr->vy - MUL_FIXED(ObjectCentre.vy, 87381));
 
 
1772
            mag.vz = abs(vertexPtr->vz - ObjectCentre.vz);
 
 
1773
 
 
 
1774
            int alpha = GetSin(((mag.vx+mag.vy+mag.vz)*8+CloakingPhase)&4095);
 
 
1775
 
 
 
1776
            alpha = MUL_FIXED(alpha, alpha);
 
 
1777
 
 
 
1778
            if (alpha > CloakingMode) 
 
 
1779
                alpha = CloakingMode;
 
 
1780
 
 
 
1781
            alpha /= 256;
 
 
1782
 
 
 
1783
            if (alpha > 255)
 
 
1784
                alpha = 255;
 
 
1785
 
 
 
1786
            renderVerticesPtr->A = alpha;
 
 
1787
 
 
 
1788
            if(CloakingMode > ONE_FIXED)
 
 
1789
            {
 
 
1790
                alpha = GetSin(((mag.vx+mag.vy+mag.vz)+CloakingPhase)&4095);
 
 
1791
                alpha = MUL_FIXED(alpha, alpha)>>8;
 
 
1792
 
 
 
1793
                if(alpha == 255)
 
 
1794
                {
 
 
1795
                    renderVerticesPtr->A = 255;
 
 
1796
                    renderVerticesPtr->G = 128;
 
 
1797
                    renderVerticesPtr->B = 255;
 
 
1798
                }
 
 
1799
            }    
 
 
1800
        }
 
 
1801
 
 
 
1802
        renderVerticesPtr++;
 
 
1803
        VertexNumberPtr++;
 
 
1804
        texture_defn_ptr += 2;
 
 
1805
 
 
 
1806
    } while(--i);
 
 
1807
}
 
 
1808
 
 
 
1809
static void AddToTranslucentPolyList(const POLYHEADER *inputPolyPtr, const RENDERVERTEX *renderVerticesPtr)
 
 
1810
{
 
 
1811
    if (CurrentNumberOfTranslucentPolygons < MAX_NO_OF_TRANSLUCENT_POLYGONS)
 
 
1812
    {
 
 
1813
        // copy the data to the list for processing later
 
 
1814
        unsigned int i;
 
 
1815
        TranslucentPolygons[CurrentNumberOfTranslucentPolygons].polygon.NumberOfVertices = RenderPolygon.NumberOfVertices;
 
 
1816
 
 
 
1817
        for (i=0; i < RenderPolygon.NumberOfVertices; i++)
 
 
1818
            TranslucentPolygons[CurrentNumberOfTranslucentPolygons].polygon.Vertices[i] = *renderVerticesPtr++;
 
 
1819
 
 
 
1820
        TranslucentPolygons[CurrentNumberOfTranslucentPolygons++].polygon_header = *inputPolyPtr;
 
 
1821
    }
 
 
1822
}
 
 
1823
 
 
 
1824
static void GouraudPolygon_Construct(const POLYHEADER *polyPtr)
 
 
1825
{
 
 
1826
    RENDERVERTEX *renderVerticesPtr = VerticesBuffer;
 
 
1827
    int i = RenderPolygon.NumberOfVertices;
 
 
1828
    VertexNumberPtr = &polyPtr->Poly1stPt;
 
 
1829
    RenderPolygon.TranslucencyMode = TRANSLUCENCY_OFF;
 
 
1830
 
 
 
1831
    do
 
 
1832
    {
 
 
1833
        renderVerticesPtr->X = RotatedPts[*VertexNumberPtr].vx;
 
 
1834
        renderVerticesPtr->Y = RotatedPts[*VertexNumberPtr].vy;
 
 
1835
        renderVerticesPtr->Z = RotatedPts[*VertexNumberPtr].vz;
 
 
1836
        VertexIntensity(renderVerticesPtr);
 
 
1837
        renderVerticesPtr->R = renderVerticesPtr->G = (renderVerticesPtr->B + renderVerticesPtr->R + renderVerticesPtr->G) / 3;
 
 
1838
        renderVerticesPtr->B = 0;
 
 
1839
        renderVerticesPtr++;
 
 
1840
        VertexNumberPtr++;
 
 
1841
 
 
 
1842
    } while(--i);
 
 
1843
}
 
 
1844
 
 
 
1845
static void GouraudTexturedPolygon_Construct(const POLYHEADER *polyPtr)
 
 
1846
{
 
 
1847
    /* get ptr to uv coords for this polygon */
 
 
1848
    int *texture_defn_ptr = Global_ShapeHeaderPtr->sh_textures[(polyPtr->PolyColour >> TxDefn)];
 
 
1849
 
 
 
1850
    RENDERVERTEX *renderVerticesPtr = VerticesBuffer;
 
 
1851
    int i = RenderPolygon.NumberOfVertices;
 
 
1852
 
 
 
1853
    VertexNumberPtr = &polyPtr->Poly1stPt;
 
 
1854
 
 
 
1855
    /* If this texture is animated the UV array must be calculated */
 
 
1856
 
 
 
1857
    if(polyPtr->PolyFlags & iflag_txanim)
 
 
1858
    {
 
 
1859
        /* Create the UV array */
 
 
1860
        int uv_array[18];
 
 
1861
        CreateTxAnimUVArray((intptr_t*)texture_defn_ptr, uv_array, (int*)polyPtr);
 
 
1862
        texture_defn_ptr = uv_array;
 
 
1863
 
 
 
1864
        do
 
 
1865
        {
 
 
1866
            VECTORCH *vertexPtr = &RotatedPts[*VertexNumberPtr];
 
 
1867
 
 
 
1868
            switch(UserProfile.active_bonus)
 
 
1869
            {
 
 
1870
                case CHEATMODE_NONACTIVE:
 
 
1871
                default:
 
 
1872
                    renderVerticesPtr->X = vertexPtr->vx;
 
 
1873
                    renderVerticesPtr->Y = vertexPtr->vy;
 
 
1874
                    renderVerticesPtr->Z = vertexPtr->vz;
 
 
1875
                break;
 
 
1876
                case CHEATMODE_TRIPTASTIC:
 
 
1877
                {
 
 
1878
                    renderVerticesPtr->X = vertexPtr->vx+GetSin((CloakingPhase*2    +vertexPtr->vz)&4095)/1024;
 
 
1879
                    renderVerticesPtr->Y = vertexPtr->vy+GetSin((CloakingPhase-3000    +vertexPtr->vx)&4095)/1024;
 
 
1880
                    renderVerticesPtr->Z = vertexPtr->vz+GetSin((CloakingPhase*3+239+vertexPtr->vy)&4095)/1024;
 
 
1881
                }
 
 
1882
                break;
 
 
1883
                case CHEATMODE_UNDERWATER:
 
 
1884
                {
 
 
1885
                    renderVerticesPtr->X = vertexPtr->vx+(GetSin((CloakingPhase/2    +vertexPtr->vz)&4095))/1024;
 
 
1886
                    renderVerticesPtr->Y = vertexPtr->vy+(GetSin((CloakingPhase-3000+vertexPtr->vx)&4095))/1024;
 
 
1887
                    renderVerticesPtr->Z = vertexPtr->vz+(GetSin((CloakingPhase/3+239+vertexPtr->vy)&4095))/1024;
 
 
1888
                }
 
 
1889
            }
 
 
1890
 
 
 
1891
            renderVerticesPtr->U = texture_defn_ptr[0];
 
 
1892
            renderVerticesPtr->V = texture_defn_ptr[1];
 
 
1893
 
 
 
1894
            if( (Global_ODB_Ptr->SpecialFXFlags & SFXFLAG_MELTINGINTOGROUND) && (Global_ODB_Ptr->ObFlags2 < ONE_FIXED) )    
 
 
1895
            {
 
 
1896
                renderVerticesPtr->A = Global_ODB_Ptr->ObFlags2 >> 8;
 
 
1897
                RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL;
 
 
1898
            }
 
 
1899
            else if (polyPtr->PolyFlags & iflag_transparent)
 
 
1900
            {
 
 
1901
                renderVerticesPtr->A = 128;
 
 
1902
                RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL;
 
 
1903
            }
 
 
1904
            else
 
 
1905
            {
 
 
1906
                switch(UserProfile.active_bonus)
 
 
1907
                {
 
 
1908
                    case CHEATMODE_NONACTIVE:
 
 
1909
                    default:
 
 
1910
                        renderVerticesPtr->A = 255;
 
 
1911
                    break;
 
 
1912
                    case CHEATMODE_TRIPTASTIC:
 
 
1913
                        renderVerticesPtr->A = TripTasticPhase;
 
 
1914
                    break;
 
 
1915
                    case CHEATMODE_MOTIONBLUR:
 
 
1916
                        renderVerticesPtr->A = 128;
 
 
1917
                }
 
 
1918
 
 
 
1919
                RenderPolygon.TranslucencyMode = TRANSLUCENCY_OFF;
 
 
1920
            }
 
 
1921
 
 
 
1922
             if (polyPtr->PolyFlags & iflag_nolight)
 
 
1923
            {
 
 
1924
                switch (PlayerStatus.VisionMode)
 
 
1925
                {
 
 
1926
                    default:
 
 
1927
                    case VISION_MODE_NORMAL:
 
 
1928
                    {
 
 
1929
                        renderVerticesPtr->R = renderVerticesPtr->G = renderVerticesPtr->B = 255;
 
 
1930
                        renderVerticesPtr->SpecularR = renderVerticesPtr->SpecularG = renderVerticesPtr->SpecularB = 0;
 
 
1931
                    }
 
 
1932
                    break;
 
 
1933
                    case VISION_MODE_IMAGEINTENSIFIER:
 
 
1934
                    {
 
 
1935
                        renderVerticesPtr->R = renderVerticesPtr->B = 0;
 
 
1936
                        renderVerticesPtr->G = 255;
 
 
1937
                        renderVerticesPtr->SpecularR = renderVerticesPtr->SpecularG = renderVerticesPtr->SpecularB = 0;
 
 
1938
                    }
 
 
1939
                    break;
 
 
1940
                    case VISION_MODE_PRED_THERMAL:
 
 
1941
                    {
 
 
1942
                        renderVerticesPtr->R =  renderVerticesPtr->G = 0;
 
 
1943
                        renderVerticesPtr->B = 255;
 
 
1944
                        renderVerticesPtr->SpecularR = renderVerticesPtr->SpecularG = renderVerticesPtr->SpecularB = 0;
 
 
1945
                    }
 
 
1946
                      break;
 
 
1947
                    case VISION_MODE_PRED_SEEALIENS:
 
 
1948
                    {
 
 
1949
                        renderVerticesPtr->R = 255;
 
 
1950
                        renderVerticesPtr->G = renderVerticesPtr->B = 0;
 
 
1951
                        renderVerticesPtr->SpecularR = renderVerticesPtr->SpecularG = renderVerticesPtr->SpecularB = 0;
 
 
1952
                    }
 
 
1953
                      break;
 
 
1954
                    case VISION_MODE_PRED_SEEPREDTECH:
 
 
1955
                    {
 
 
1956
                        renderVerticesPtr->R = renderVerticesPtr->B = 0;
 
 
1957
                        renderVerticesPtr->G = 255;
 
 
1958
                        renderVerticesPtr->SpecularR = renderVerticesPtr->SpecularB = 255;
 
 
1959
                        renderVerticesPtr->SpecularG = 0;
 
 
1960
                    }
 
 
1961
                }
 
 
1962
            }
 
 
1963
            else
 
 
1964
            {
 
 
1965
                VertexIntensity(renderVerticesPtr);
 
 
1966
            }
 
 
1967
 
 
 
1968
            renderVerticesPtr++;
 
 
1969
            VertexNumberPtr++;
 
 
1970
 
 
 
1971
            texture_defn_ptr += 2;
 
 
1972
 
 
 
1973
        } while(--i);
 
 
1974
    }
 
 
1975
    else
 
 
1976
    {
 
 
1977
        do
 
 
1978
        {
 
 
1979
            VECTORCH *vertexPtr = &RotatedPts[*VertexNumberPtr];
 
 
1980
            #if SPATIAL_SHOCKWAVE
 
 
1981
            {
 
 
1982
                int d = Magnitude(vertexPtr);
 
 
1983
                int a = (CloakingPhase&16383)+4000;
 
 
1984
                int u = d-a;
 
 
1985
                int offset;
 
 
1986
 
 
 
1987
                if (u > 0 && u < 8192)
 
 
1988
                {
 
 
1989
                    VECTORCH n = *vertexPtr;
 
 
1990
                    Normalise(&n);
 
 
1991
                    u <<= 3;
 
 
1992
                    offset = MUL_FIXED(MUL_FIXED(2*u,ONE_FIXED-u),8000) + MUL_FIXED(MUL_FIXED(u,u),8192 );
 
 
1993
                    assert(offset>=0 && offset<=8192);
 
 
1994
                    renderVerticesPtr->X = MUL_FIXED(n.vx,d);//a+offset*2);
 
 
1995
                    renderVerticesPtr->Y = MUL_FIXED(n.vy,d);//a+offset*2);
 
 
1996
                    renderVerticesPtr->Z = MUL_FIXED(n.vz,a+offset);
 
 
1997
                }
 
 
1998
                else
 
 
1999
                {
 
 
2000
                    renderVerticesPtr->X = vertexPtr->vx;
 
 
2001
                    renderVerticesPtr->Y = vertexPtr->vy;
 
 
2002
                    renderVerticesPtr->Z = vertexPtr->vz;
 
 
2003
                }
 
 
2004
            }
 
 
2005
            #else
 
 
2006
            switch(UserProfile.active_bonus)
 
 
2007
            {
 
 
2008
                case CHEATMODE_NONACTIVE:
 
 
2009
                default:
 
 
2010
                {
 
 
2011
                    renderVerticesPtr->X = vertexPtr->vx;
 
 
2012
                    renderVerticesPtr->Y = vertexPtr->vy;
 
 
2013
                    renderVerticesPtr->Z = vertexPtr->vz;
 
 
2014
                }
 
 
2015
                break;
 
 
2016
                case CHEATMODE_TRIPTASTIC:
 
 
2017
                {
 
 
2018
                    renderVerticesPtr->X = vertexPtr->vx+GetSin((CloakingPhase*2 + vertexPtr->vz) & 4095)/1024;
 
 
2019
                    renderVerticesPtr->Y = vertexPtr->vy+GetSin((CloakingPhase-3000    + vertexPtr->vx) & 4095)/1024;
 
 
2020
                    renderVerticesPtr->Z = vertexPtr->vz+GetSin((CloakingPhase*3+239 + vertexPtr->vy) & 4095)/1024;
 
 
2021
                }
 
 
2022
                break;
 
 
2023
                case CHEATMODE_UNDERWATER:
 
 
2024
                {
 
 
2025
                    renderVerticesPtr->X = vertexPtr->vx+(GetSin((CloakingPhase/2 + vertexPtr->vz)&4095))/1024;
 
 
2026
                    renderVerticesPtr->Y = vertexPtr->vy+(GetSin((CloakingPhase - 3000 + vertexPtr->vx)&4095))/1024;
 
 
2027
                    renderVerticesPtr->Z = vertexPtr->vz+(GetSin((CloakingPhase/3+239 + vertexPtr->vy)&4095))/1024;
 
 
2028
                }
 
 
2029
            }
 
 
2030
            #endif
 
 
2031
 
 
 
2032
            renderVerticesPtr->U = texture_defn_ptr[0] << 16;
 
 
2033
            renderVerticesPtr->V = texture_defn_ptr[1] << 16;
 
 
2034
 
 
 
2035
            if( (Global_ODB_Ptr->SpecialFXFlags & SFXFLAG_MELTINGINTOGROUND) && (Global_ODB_Ptr->ObFlags2 < ONE_FIXED) )    
 
 
2036
            {
 
 
2037
                renderVerticesPtr->A = Global_ODB_Ptr->ObFlags2 >> 8;
 
 
2038
                RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL;
 
 
2039
            }
 
 
2040
            else if (polyPtr->PolyFlags & iflag_transparent)
 
 
2041
            {
 
 
2042
                renderVerticesPtr->A = 128;
 
 
2043
                RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL;
 
 
2044
            }
 
 
2045
            else
 
 
2046
            {
 
 
2047
                switch(UserProfile.active_bonus)
 
 
2048
                {
 
 
2049
                    case CHEATMODE_NONACTIVE:
 
 
2050
                    default:
 
 
2051
                        renderVerticesPtr->A = 255;
 
 
2052
                    break;
 
 
2053
                    case CHEATMODE_TRIPTASTIC:
 
 
2054
                        renderVerticesPtr->A = TripTasticPhase;
 
 
2055
                    break;
 
 
2056
                    case CHEATMODE_MOTIONBLUR:
 
 
2057
                        renderVerticesPtr->A = 128;
 
 
2058
                }
 
 
2059
 
 
 
2060
                RenderPolygon.TranslucencyMode = TRANSLUCENCY_OFF;
 
 
2061
            }
 
 
2062
 
 
 
2063
RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL;
 
 
2064
 
 
 
2065
             if (polyPtr->PolyFlags & iflag_nolight)
 
 
2066
            {
 
 
2067
                switch (PlayerStatus.VisionMode)
 
 
2068
                {
 
 
2069
                    default:
 
 
2070
                    case VISION_MODE_NORMAL:
 
 
2071
                    {
 
 
2072
                        renderVerticesPtr->R = renderVerticesPtr->G = renderVerticesPtr->B = 255;
 
 
2073
                        renderVerticesPtr->SpecularR = renderVerticesPtr->SpecularG = renderVerticesPtr->SpecularB = 0;
 
 
2074
                    }
 
 
2075
                    break;
 
 
2076
                    case VISION_MODE_IMAGEINTENSIFIER:
 
 
2077
                    {
 
 
2078
                        renderVerticesPtr->R = renderVerticesPtr->B = 0;
 
 
2079
                        renderVerticesPtr->G = 255;
 
 
2080
                        renderVerticesPtr->SpecularR = renderVerticesPtr->SpecularG = renderVerticesPtr->SpecularB = 0;
 
 
2081
                    }
 
 
2082
                    break;
 
 
2083
                    case VISION_MODE_PRED_THERMAL:
 
 
2084
                    {
 
 
2085
                        renderVerticesPtr->R = renderVerticesPtr->G = 0;
 
 
2086
                        renderVerticesPtr->B = 255;
 
 
2087
                        renderVerticesPtr->SpecularR = renderVerticesPtr->SpecularG = renderVerticesPtr->SpecularB = 0;
 
 
2088
                    }
 
 
2089
                      break;
 
 
2090
                    case VISION_MODE_PRED_SEEALIENS:
 
 
2091
                    {
 
 
2092
                        renderVerticesPtr->R = 255;
 
 
2093
                        renderVerticesPtr->G =  renderVerticesPtr->B = 0;
 
 
2094
                        renderVerticesPtr->SpecularR = renderVerticesPtr->SpecularG = renderVerticesPtr->SpecularB = 0;
 
 
2095
                    }
 
 
2096
                      break;
 
 
2097
                    case VISION_MODE_PRED_SEEPREDTECH:
 
 
2098
                    {
 
 
2099
                        renderVerticesPtr->R = renderVerticesPtr->B = 0;
 
 
2100
                        renderVerticesPtr->G = 255;
 
 
2101
                        renderVerticesPtr->SpecularR = renderVerticesPtr->SpecularB = 255;
 
 
2102
                        renderVerticesPtr->SpecularG = 0;
 
 
2103
                    }
 
 
2104
                }
 
 
2105
            }
 
 
2106
            else
 
 
2107
            {
 
 
2108
                 VertexIntensity(renderVerticesPtr);
 
 
2109
            }
 
 
2110
 
 
 
2111
            renderVerticesPtr++;
 
 
2112
            VertexNumberPtr++;
 
 
2113
            texture_defn_ptr += 2;
 
 
2114
 
 
 
2115
        } while(--i);
 
 
2116
    }
 
 
2117
}
 
 
2118
 
 
 
2119
struct shapeheader* GetShapeData(int shapenum)
 
 
2120
{
 
 
2121
    return mainshapelist[shapenum];
 
 
2122
}
 
 
2123
 
 
 
2124
int* GetTxAnimArrayZ(int shape, int item)
 
 
2125
{
 
 
2126
    struct shapeheader *sptr = mainshapelist[shape];
 
 
2127
 
 
 
2128
    if(sptr->sh_textures && sptr->items) 
 
 
2129
    {
 
 
2130
        int**    item_array_ptr = sptr->items;
 
 
2131
        int**    shape_textures = sptr->sh_textures;
 
 
2132
        int*    item_ptr = item_array_ptr[item];
 
 
2133
        POLYHEADER *pheader = (POLYHEADER *) item_ptr;
 
 
2134
 
 
 
2135
        if(pheader->PolyFlags & iflag_txanim) 
 
 
2136
            return (int*) shape_textures[(pheader->PolyColour >> TxDefn)];
 
 
2137
    }
 
 
2138
 
 
 
2139
return NULL;
 
 
2140
}
 
 
2141
 
 
 
2142
static TXANIMHEADER* GetTxAnimDataZ(int shape, int item, int sequence)
 
 
2143
{
 
 
2144
    struct shapeheader* sptr = mainshapelist[shape];
 
 
2145
 
 
 
2146
    if(sptr && sptr->sh_textures && sptr->items) 
 
 
2147
    {
 
 
2148
        int**    item_array_ptr = sptr->items;
 
 
2149
        int**    shape_textures = sptr->sh_textures;
 
 
2150
        int*    item_ptr = item_array_ptr[item];
 
 
2151
        POLYHEADER *pheader = (POLYHEADER *) item_ptr;
 
 
2152
 
 
 
2153
        if(pheader->PolyFlags & iflag_txanim) 
 
 
2154
        {
 
 
2155
            TXANIMHEADER **txah_ptr = (TXANIMHEADER **) shape_textures[(pheader->PolyColour >> TxDefn)];
 
 
2156
            txah_ptr++;        /* Skip sequence shadow */
 
 
2157
            return txah_ptr[sequence];
 
 
2158
        }
 
 
2159
    }
 
 
2160
 
 
 
2161
return NULL;
 
 
2162
}
 
 
2163
 
 
 
2164
/*
 
 
2165
 
 
 
2166
 This function copies the TXANIMHEADER from the shape data item sequence
 
 
2167
 selected by the TXACTRLBLK to the TXANIMHEADER in the TXACTRLBLK
 
 
2168
 
 
 
2169
*/
 
 
2170
 
 
 
2171
TXANIMHEADER* GetTxAnimHeaderFromShape(TXACTRLBLK *taptr, int shape)
 
 
2172
{
 
 
2173
    TXANIMHEADER *txah = GetTxAnimDataZ(shape, taptr->tac_item, taptr->tac_sequence);
 
 
2174
 
 
 
2175
    if(txah) 
 
 
2176
    {
 
 
2177
        taptr->tac_txah.txa_flags        = txah->txa_flags;
 
 
2178
        taptr->tac_txah.txa_state        = txah->txa_state;
 
 
2179
        taptr->tac_txah.txa_numframes    = txah->txa_numframes;
 
 
2180
        taptr->tac_txah.txa_framedata    = txah->txa_framedata;
 
 
2181
        taptr->tac_txah.txa_currentframe = txah->txa_currentframe;
 
 
2182
        taptr->tac_txah.txa_maxframe     = txah->txa_maxframe;
 
 
2183
        taptr->tac_txah.txa_speed        = txah->txa_speed;
 
 
2184
    }
 
 
2185
 
 
 
2186
return txah;
 
 
2187
}
 
 
2188
 
 
 
2189
/*
 
 
2190
 
 
 
2191
 Texture Animation Control Blocks are used to update animation. At the start
 
 
2192
 of "AddShape()" the relevant control block values are copied across to the
 
 
2193
 item TXANIMHEADER.
 
 
2194
 
 
 
2195
*/
 
 
2196
 
 
 
2197
static void UpdateTxAnim(TXANIMHEADER *txah)
 
 
2198
{
 
 
2199
    int UpdateRate;
 
 
2200
 
 
 
2201
    if(txah->txa_flags & txa_flag_play) 
 
 
2202
    {
 
 
2203
        /* How fast do we go? */
 
 
2204
 
 
 
2205
        if(txah->txa_flags & txa_flag_quantiseframetime) 
 
 
2206
        {
 
 
2207
            /* This option is still being designed and tested */
 
 
2208
 
 
 
2209
            UpdateRate = txah->txa_speed & (~4096);        /* 1/16th */
 
 
2210
 
 
 
2211
            if(UpdateRate < 4096)
 
 
2212
                UpdateRate = 4096;
 
 
2213
        }
 
 
2214
 
 
 
2215
        UpdateRate = MUL_FIXED(NormalFrameTime, txah->txa_speed);
 
 
2216
 
 
 
2217
        /* Update the current frame */
 
 
2218
 
 
 
2219
        if(txah->txa_flags & txa_flag_reverse) 
 
 
2220
        {
 
 
2221
            txah->txa_currentframe -= UpdateRate;
 
 
2222
 
 
 
2223
            if(txah->txa_currentframe < 0)
 
 
2224
            {
 
 
2225
                if(txah->txa_flags & txa_flag_noloop)
 
 
2226
                    txah->txa_currentframe = 0;
 
 
2227
                else
 
 
2228
                    txah->txa_currentframe += txah->txa_maxframe;
 
 
2229
            }
 
 
2230
        }
 
 
2231
        else
 
 
2232
        {
 
 
2233
            txah->txa_currentframe += UpdateRate;
 
 
2234
 
 
 
2235
            if(txah->txa_currentframe >= txah->txa_maxframe)
 
 
2236
            {
 
 
2237
                if(txah->txa_flags & txa_flag_noloop)
 
 
2238
                    txah->txa_currentframe = txah->txa_maxframe - 1;
 
 
2239
                else
 
 
2240
                    txah->txa_currentframe -= txah->txa_maxframe;
 
 
2241
            }
 
 
2242
        }
 
 
2243
    }
 
 
2244
}
 
 
2245
 
 
 
2246
// Display block TXACTRLBLKS pass their data on to shape TXANIMHEADERs
 
 
2247
 
 
 
2248
static void ControlTextureAnimation(DISPLAYBLOCK *dptr)
 
 
2249
{
 
 
2250
    TXACTRLBLK *taptr = dptr->ObTxAnimCtrlBlks;
 
 
2251
 
 
 
2252
    while(taptr)
 
 
2253
    {
 
 
2254
        /* Update animation for the display block TXACTRLBLK */
 
 
2255
        assert(&(taptr->tac_txah));
 
 
2256
        UpdateTxAnim(&taptr->tac_txah);
 
 
2257
 
 
 
2258
        /* Get the TXANIMHEADER from the shape data */
 
 
2259
 
 
 
2260
        TXANIMHEADER *txah = taptr->tac_txah_s;
 
 
2261
 
 
 
2262
        /* Copy across the current frame */
 
 
2263
        assert(txah);
 
 
2264
        txah->txa_currentframe = taptr->tac_txah.txa_currentframe;
 
 
2265
 
 
 
2266
        int* iptr = taptr->tac_txarray;
 
 
2267
        assert(iptr);
 
 
2268
        *iptr = taptr->tac_sequence;
 
 
2269
        taptr = taptr->tac_next;
 
 
2270
    }
 
 
2271
}
 
 
2272
 
 
 
2273
static void RotateVertex(VECTOR2D *vertexPtr, int theta)
 
 
2274
{
 
 
2275
    int sin = GetSin(theta);
 
 
2276
    int cos = GetCos(theta);
 
 
2277
 
 
 
2278
    int vx = MUL_FIXED(vertexPtr->vx, cos) - MUL_FIXED(vertexPtr->vy, sin);
 
 
2279
    int vy = MUL_FIXED(vertexPtr->vx, sin) + MUL_FIXED(vertexPtr->vy, cos);
 
 
2280
 
 
 
2281
    vertexPtr->vx = vx;
 
 
2282
    vertexPtr->vy = vy;
 
 
2283
}
 
 
2284
 
 
 
2285
static void TranslatePoint(const float *source, float *dest, const float *matrix)
 
 
2286
{
 
 
2287
    dest[0] = matrix[ 0] * source[0] + matrix[ 1] * source[1] + matrix[ 2] * source[2] + matrix[ 3];
 
 
2288
    dest[1] = matrix[ 4] * source[0] + matrix[ 5] * source[1] + matrix[ 6] * source[2] + matrix[ 7];
 
 
2289
    dest[2] = matrix[ 8] * source[0] + matrix[ 9] * source[1] + matrix[10] * source[2] + matrix[11];
 
 
2290
}
 
 
2291
 
 
 
2292
void TranslatePointIntoViewspace(VECTORCH * pointPtr)
 
 
2293
{
 
 
2294
    Source[0] = pointPtr->vx;
 
 
2295
    Source[1] = pointPtr->vy;
 
 
2296
    Source[2] = pointPtr->vz;
 
 
2297
 
 
 
2298
    TranslatePoint(Source, Dest, ViewMatrix);
 
 
2299
 
 
 
2300
    pointPtr->vx = (int)Dest[0];
 
 
2301
    pointPtr->vy = (int)Dest[1];
 
 
2302
    pointPtr->vz = (int)Dest[2];
 
 
2303
}
 
 
2304
 
 
 
2305
void RenderParticle(PARTICLE *particlePtr)
 
 
2306
{
 
 
2307
    int particleSize = particlePtr->Size;
 
 
2308
 
 
 
2309
    {
 
 
2310
        VECTORCH translatedPosition = particlePtr->Position;
 
 
2311
        TranslatePointIntoViewspace(&translatedPosition);
 
 
2312
        VerticesBuffer[0].X = translatedPosition.vx;
 
 
2313
        VerticesBuffer[3].X = translatedPosition.vx;
 
 
2314
        VerticesBuffer[0].Y = translatedPosition.vy;
 
 
2315
        VerticesBuffer[3].Y = translatedPosition.vy;
 
 
2316
        VerticesBuffer[0].Z = translatedPosition.vz;
 
 
2317
        VerticesBuffer[3].Z = translatedPosition.vz;
 
 
2318
    }
 
 
2319
 
 
 
2320
    switch(particlePtr->ParticleID)
 
 
2321
    {
 
 
2322
        case PARTICLE_ALIEN_BLOOD:
 
 
2323
        case PARTICLE_HUMAN_BLOOD:
 
 
2324
        case PARTICLE_PREDATOR_BLOOD:
 
 
2325
        case PARTICLE_SPARK:
 
 
2326
        case PARTICLE_RICOCHET_SPARK:
 
 
2327
        case PARTICLE_EXPLOSIONFIRE:
 
 
2328
        case PARTICLE_WATERFALLSPRAY:
 
 
2329
        case PARTICLE_LASERBEAM:
 
 
2330
        case PARTICLE_PLASMABEAM:
 
 
2331
        case PARTICLE_ORANGE_SPARK:
 
 
2332
        case PARTICLE_ORANGE_PLASMA:
 
 
2333
        {
 
 
2334
            VECTORCH translatedPosition = particlePtr->Offset;
 
 
2335
            TranslatePointIntoViewspace(&translatedPosition);
 
 
2336
            VerticesBuffer[1].X = translatedPosition.vx;
 
 
2337
            VerticesBuffer[2].X = translatedPosition.vx;
 
 
2338
            VerticesBuffer[1].Y = translatedPosition.vy;
 
 
2339
            VerticesBuffer[2].Y = translatedPosition.vy;
 
 
2340
            VerticesBuffer[1].Z = translatedPosition.vz;
 
 
2341
            VerticesBuffer[2].Z = translatedPosition.vz;
 
 
2342
 
 
 
2343
            {
 
 
2344
                int deltaX = VerticesBuffer[1].X - VerticesBuffer[0].X;
 
 
2345
                int deltaY = VerticesBuffer[1].Y - VerticesBuffer[0].Y;
 
 
2346
                int splitY = 0;
 
 
2347
 
 
 
2348
                if (deltaX >= 0)
 
 
2349
                {    
 
 
2350
                    if (deltaY >= 0)
 
 
2351
                    {
 
 
2352
                        if (deltaX > deltaY)
 
 
2353
                            splitY = 1;
 
 
2354
                    }
 
 
2355
                    else if (deltaX > -deltaY)
 
 
2356
                        splitY = 1;
 
 
2357
                }
 
 
2358
                else
 
 
2359
                {    
 
 
2360
                    if (deltaY >= 0)
 
 
2361
                    {
 
 
2362
                        if (-deltaX > deltaY)
 
 
2363
                            splitY = 1;
 
 
2364
                    }
 
 
2365
                    else if (-deltaX > -deltaY)
 
 
2366
                    {
 
 
2367
                        splitY = 1;
 
 
2368
                    }
 
 
2369
                }
 
 
2370
 
 
 
2371
                if (splitY)
 
 
2372
                {
 
 
2373
                    if (deltaX > 0)
 
 
2374
                    {
 
 
2375
                        /* 1 & 2 are more +ve in X */
 
 
2376
                        VerticesBuffer[0].X -= particleSize;
 
 
2377
                        VerticesBuffer[0].Y -= MUL_FIXED(particleSize,87381);
 
 
2378
                        VerticesBuffer[1].X += particleSize;
 
 
2379
                        VerticesBuffer[1].Y -= MUL_FIXED(particleSize,87381);
 
 
2380
                        VerticesBuffer[2].X += particleSize;
 
 
2381
                        VerticesBuffer[2].Y += MUL_FIXED(particleSize,87381);
 
 
2382
                        VerticesBuffer[3].X -= particleSize;
 
 
2383
                        VerticesBuffer[3].Y += MUL_FIXED(particleSize,87381);
 
 
2384
                    }
 
 
2385
                    else
 
 
2386
                    {
 
 
2387
                        /* 1 & 2 are more -ve in X */
 
 
2388
                        VerticesBuffer[0].X += particleSize;
 
 
2389
                        VerticesBuffer[0].Y -= MUL_FIXED(particleSize,87381);
 
 
2390
                        VerticesBuffer[1].X -= particleSize;
 
 
2391
                        VerticesBuffer[1].Y -= MUL_FIXED(particleSize,87381);
 
 
2392
                        VerticesBuffer[2].X -= particleSize;
 
 
2393
                        VerticesBuffer[2].Y += MUL_FIXED(particleSize,87381);
 
 
2394
                        VerticesBuffer[3].X += particleSize;
 
 
2395
                        VerticesBuffer[3].Y += MUL_FIXED(particleSize,87381);
 
 
2396
                    }
 
 
2397
                }
 
 
2398
                else
 
 
2399
                {
 
 
2400
                    if (deltaY > 0)
 
 
2401
                    {
 
 
2402
                        /* 1 & 2 are more +ve in Y */
 
 
2403
                        VerticesBuffer[0].X -= particleSize;
 
 
2404
                        VerticesBuffer[0].Y -= MUL_FIXED(particleSize,87381);
 
 
2405
                        VerticesBuffer[1].X -= particleSize;
 
 
2406
                        VerticesBuffer[1].Y += MUL_FIXED(particleSize,87381);
 
 
2407
                        VerticesBuffer[2].X += particleSize;
 
 
2408
                        VerticesBuffer[2].Y += MUL_FIXED(particleSize,87381);
 
 
2409
                        VerticesBuffer[3].X += particleSize;
 
 
2410
                        VerticesBuffer[3].Y -= MUL_FIXED(particleSize,87381);
 
 
2411
                    }
 
 
2412
                    else
 
 
2413
                    {
 
 
2414
                        /* 1 & 2 are more -ve in Y */
 
 
2415
                        VerticesBuffer[0].X -= particleSize;
 
 
2416
                        VerticesBuffer[0].Y += MUL_FIXED(particleSize,87381);
 
 
2417
                        VerticesBuffer[1].X -= particleSize;
 
 
2418
                        VerticesBuffer[1].Y -= MUL_FIXED(particleSize,87381);
 
 
2419
                        VerticesBuffer[2].X += particleSize;
 
 
2420
                        VerticesBuffer[2].Y -= MUL_FIXED(particleSize,87381);
 
 
2421
                        VerticesBuffer[3].X += particleSize;
 
 
2422
                        VerticesBuffer[3].Y += MUL_FIXED(particleSize,87381);
 
 
2423
                    }
 
 
2424
                }
 
 
2425
            }
 
 
2426
        }
 
 
2427
        break;
 
 
2428
        default:
 
 
2429
        {
 
 
2430
            VECTOR2D offset[4];
 
 
2431
            VerticesBuffer[1].X = VerticesBuffer[0].X;
 
 
2432
            VerticesBuffer[2].X = VerticesBuffer[0].X;
 
 
2433
            VerticesBuffer[1].Y = VerticesBuffer[0].Y;
 
 
2434
            VerticesBuffer[2].Y = VerticesBuffer[0].Y;
 
 
2435
            VerticesBuffer[1].Z = VerticesBuffer[0].Z;
 
 
2436
            VerticesBuffer[2].Z = VerticesBuffer[0].Z;
 
 
2437
 
 
 
2438
            offset[0].vx = -particleSize;
 
 
2439
            offset[0].vy = -particleSize;
 
 
2440
 
 
 
2441
            offset[1].vx = +particleSize;
 
 
2442
            offset[1].vy = -particleSize;
 
 
2443
 
 
 
2444
            offset[2].vx = +particleSize;
 
 
2445
            offset[2].vy = +particleSize;
 
 
2446
 
 
 
2447
            offset[3].vx = -particleSize;
 
 
2448
            offset[3].vy = +particleSize;
 
 
2449
 
 
 
2450
            switch(particlePtr->ParticleID)
 
 
2451
            {
 
 
2452
                case PARTICLE_MUZZLEFLASH:
 
 
2453
                {
 
 
2454
                    int theta = FastRandom()&4095;
 
 
2455
                    RotateVertex(&offset[0],theta);
 
 
2456
                    RotateVertex(&offset[1],theta);
 
 
2457
                    RotateVertex(&offset[2],theta);
 
 
2458
                    RotateVertex(&offset[3],theta);
 
 
2459
                }
 
 
2460
                break;
 
 
2461
                case PARTICLE_SMOKECLOUD:
 
 
2462
                case PARTICLE_GUNMUZZLE_SMOKE:
 
 
2463
                case PARTICLE_FLAME:
 
 
2464
                {
 
 
2465
                    int theta = (particlePtr->Offset.vx + MUL_FIXED(CloakingPhase,particlePtr->Offset.vy)) & 4095;
 
 
2466
                    RotateVertex(&offset[0],theta);
 
 
2467
                    RotateVertex(&offset[1],theta);
 
 
2468
                    RotateVertex(&offset[2],theta);
 
 
2469
                    RotateVertex(&offset[3],theta);
 
 
2470
                }
 
 
2471
                default:
 
 
2472
                break;
 
 
2473
            }
 
 
2474
 
 
 
2475
            VerticesBuffer[0].X += offset[0].vx;
 
 
2476
            VerticesBuffer[0].Y += MUL_FIXED(offset[0].vy,87381);
 
 
2477
 
 
 
2478
            VerticesBuffer[1].X += offset[1].vx;
 
 
2479
            VerticesBuffer[1].Y += MUL_FIXED(offset[1].vy,87381);
 
 
2480
 
 
 
2481
            VerticesBuffer[2].X += offset[2].vx;
 
 
2482
            VerticesBuffer[2].Y += MUL_FIXED(offset[2].vy,87381);
 
 
2483
 
 
 
2484
            VerticesBuffer[3].X += offset[3].vx;
 
 
2485
            VerticesBuffer[3].Y += MUL_FIXED(offset[3].vy,87381);
 
 
2486
        }
 
 
2487
    }
 
 
2488
 
 
 
2489
    {
 
 
2490
        int outcode = QuadWithinFrustrum();
 
 
2491
 
 
 
2492
        if (outcode)
 
 
2493
        {
 
 
2494
            const PARTICLE_DESC *particleDescPtr = &ParticleDescription[particlePtr->ParticleID];
 
 
2495
            RenderPolygon.NumberOfVertices = 4;
 
 
2496
 
 
 
2497
            VerticesBuffer[0].U = particleDescPtr->StartU;
 
 
2498
            VerticesBuffer[0].V = particleDescPtr->StartV;
 
 
2499
 
 
 
2500
            VerticesBuffer[1].U = particleDescPtr->EndU;
 
 
2501
            VerticesBuffer[1].V = particleDescPtr->StartV;
 
 
2502
 
 
 
2503
            VerticesBuffer[2].U = particleDescPtr->EndU;
 
 
2504
            VerticesBuffer[2].V = particleDescPtr->EndV;
 
 
2505
 
 
 
2506
            VerticesBuffer[3].U = particleDescPtr->StartU;
 
 
2507
            VerticesBuffer[3].V = particleDescPtr->EndV;
 
 
2508
 
 
 
2509
            if (outcode != 2)
 
 
2510
            {
 
 
2511
                TexturedPolygon_ClipWithZ();
 
 
2512
 
 
 
2513
                if(RenderPolygon.NumberOfVertices < 3)
 
 
2514
                    return;
 
 
2515
 
 
 
2516
                TexturedPolygon_ClipWithNegativeX();
 
 
2517
 
 
 
2518
                if(RenderPolygon.NumberOfVertices < 3)
 
 
2519
                    return;
 
 
2520
 
 
 
2521
                TexturedPolygon_ClipWithPositiveY();
 
 
2522
 
 
 
2523
                if(RenderPolygon.NumberOfVertices < 3)
 
 
2524
                    return;
 
 
2525
 
 
 
2526
                TexturedPolygon_ClipWithNegativeY();
 
 
2527
 
 
 
2528
                if(RenderPolygon.NumberOfVertices < 3)
 
 
2529
                    return;
 
 
2530
 
 
 
2531
                TexturedPolygon_ClipWithPositiveX();
 
 
2532
 
 
 
2533
                if(RenderPolygon.NumberOfVertices < 3)
 
 
2534
                    return;
 
 
2535
 
 
 
2536
                Particle_Output(particlePtr, RenderPolygon.Vertices);
 
 
2537
              }
 
 
2538
            else
 
 
2539
            {
 
 
2540
                Particle_Output(particlePtr, VerticesBuffer);
 
 
2541
            }
 
 
2542
        }
 
 
2543
    }
 
 
2544
}
 
 
2545
 
 
 
2546
static void FindAlienEnergySource_Recursion(HMODELCONTROLLER *controllerPtr, SECTION_DATA *sectionDataPtr, unsigned int colour)
 
 
2547
{
 
 
2548
    /* KJL 16:29:40 10/02/98 - Recurse through hmodel */
 
 
2549
    if ((sectionDataPtr->First_Child != NULL) && !(sectionDataPtr->flags & section_data_terminate_here))
 
 
2550
    {
 
 
2551
        SECTION_DATA *childSectionPtr = sectionDataPtr->First_Child;
 
 
2552
 
 
 
2553
        while (childSectionPtr != NULL)
 
 
2554
        {
 
 
2555
            assert(childSectionPtr->My_Parent == sectionDataPtr);
 
 
2556
 
 
 
2557
            FindAlienEnergySource_Recursion(controllerPtr, childSectionPtr, colour);
 
 
2558
            childSectionPtr = childSectionPtr->Next_Sibling;
 
 
2559
        }
 
 
2560
    }
 
 
2561
 
 
 
2562
    if(sectionDataPtr->Shape && (sectionDataPtr->Shape->shaperadius > LocalDetailLevels.AlienEnergyViewThreshold))
 
 
2563
    {
 
 
2564
        PARTICLE particle;
 
 
2565
        particle.Position = sectionDataPtr->World_Offset;
 
 
2566
        particle.ParticleID = PARTICLE_MUZZLEFLASH;
 
 
2567
        particle.Colour = colour;
 
 
2568
        particle.Size = sectionDataPtr->Shape->shaperadius * 2;
 
 
2569
        RenderParticle(&particle);
 
 
2570
 
 
 
2571
        //if(0)
 
 
2572
        {
 
 
2573
        VECTORCH velocity;
 
 
2574
        velocity.vx = (FastRandom() & 255) - 128;
 
 
2575
        velocity.vy = (FastRandom() & 255) - 128;
 
 
2576
        velocity.vz = 0;
 
 
2577
        //velocity.vy = -1000 - (FastRandom() & 255);
 
 
2578
        //MakeParticle(&sectionDataPtr->World_Offset, &velocity, PARTICLE_SPARK);
 
 
2579
        MakeParticle(&sectionDataPtr->World_Offset, &velocity, PARTICLE_PLASMATRAIL);
 
 
2580
        }
 
 
2581
    }
 
 
2582
}
 
 
2583
 
 
 
2584
static void DoAlienEnergyView(DISPLAYBLOCK *dispPtr)
 
 
2585
{
 
 
2586
    HMODELCONTROLLER *controllerPtr = dispPtr->HModelControlBlock;
 
 
2587
    STRATEGYBLOCK *sbPtr = dispPtr->ObStrategyBlock;
 
 
2588
    unsigned int colour;
 
 
2589
 
 
 
2590
    switch (sbPtr->type)
 
 
2591
    {
 
 
2592
        case I_BehaviourAlien:
 
 
2593
        case I_BehaviourAlienPlayer:
 
 
2594
        case I_BehaviourQueenAlien:
 
 
2595
        case I_BehaviourFaceHugger:
 
 
2596
        case I_BehaviourXenoborg:
 
 
2597
            colour = ALIENS_LIFEFORCE_GLOW_COLOUR;
 
 
2598
        break;
 
 
2599
        case I_BehaviourPredator:
 
 
2600
        case I_BehaviourPredatorPlayer:
 
 
2601
            colour = PREDATORS_LIFEFORCE_GLOW_COLOUR;
 
 
2602
        break;
 
 
2603
        case I_BehaviourMarine:
 
 
2604
        case I_BehaviourMarinePlayer:
 
 
2605
        {
 
 
2606
            MARINE_STATUS_BLOCK *marineStatusPointer = (MARINE_STATUS_BLOCK *)(sbPtr->dataptr);    
 
 
2607
 
 
 
2608
            if (marineStatusPointer->Android)
 
 
2609
                return;
 
 
2610
 
 
 
2611
            colour = MARINES_LIFEFORCE_GLOW_COLOUR;
 
 
2612
        }
 
 
2613
        break;
 
 
2614
        case I_BehaviourNetGhost:
 
 
2615
        {
 
 
2616
            NETGHOSTDATABLOCK *ghostDataPtr = (NETGHOSTDATABLOCK *)sbPtr->dataptr;
 
 
2617
 
 
 
2618
            switch(ghostDataPtr->type)
 
 
2619
            {
 
 
2620
                case I_BehaviourAlienPlayer:
 
 
2621
                    colour = ALIENS_LIFEFORCE_GLOW_COLOUR;
 
 
2622
                break;
 
 
2623
                case I_BehaviourPredatorPlayer:
 
 
2624
                    colour = PREDATORS_LIFEFORCE_GLOW_COLOUR;
 
 
2625
                break;
 
 
2626
                case I_BehaviourMarinePlayer:
 
 
2627
                    colour = MARINES_LIFEFORCE_GLOW_COLOUR;
 
 
2628
                break;
 
 
2629
                case I_BehaviourCorpse:
 
 
2630
                    switch(ghostDataPtr->subtype)
 
 
2631
                    {
 
 
2632
                        case I_BehaviourAlienPlayer:
 
 
2633
                            colour = ALIENS_LIFEFORCE_GLOW_COLOUR;
 
 
2634
                        break;
 
 
2635
                        case I_BehaviourPredatorPlayer:
 
 
2636
                            colour = PREDATORS_LIFEFORCE_GLOW_COLOUR;
 
 
2637
                        break;
 
 
2638
                        case I_BehaviourMarinePlayer:
 
 
2639
                            colour = MARINES_LIFEFORCE_GLOW_COLOUR;
 
 
2640
                        default:
 
 
2641
                        return;
 
 
2642
                    }
 
 
2643
                default:
 
 
2644
                return;
 
 
2645
            }
 
 
2646
        }
 
 
2647
        break;
 
 
2648
        case I_BehaviourCorpse:
 
 
2649
        {
 
 
2650
            CORPSEDATABLOCK *corpseDataPtr = (CORPSEDATABLOCK *)sbPtr->dataptr;
 
 
2651
 
 
 
2652
            switch(corpseDataPtr->Type)
 
 
2653
            {
 
 
2654
                case I_BehaviourAlien:
 
 
2655
                case I_BehaviourAlienPlayer:
 
 
2656
                    colour = ALIENS_LIFEFORCE_GLOW_COLOUR;
 
 
2657
                break;
 
 
2658
                case I_BehaviourMarine:
 
 
2659
                case I_BehaviourMarinePlayer:
 
 
2660
                {
 
 
2661
                    if (corpseDataPtr->Android)
 
 
2662
                        return;
 
 
2663
 
 
 
2664
                    colour = MARINES_LIFEFORCE_GLOW_COLOUR;
 
 
2665
                }
 
 
2666
                break;
 
 
2667
                case I_BehaviourPredator:
 
 
2668
                case I_BehaviourPredatorPlayer:
 
 
2669
                    colour = PREDATORS_LIFEFORCE_GLOW_COLOUR;
 
 
2670
                break;
 
 
2671
                default:
 
 
2672
                return;
 
 
2673
            }
 
 
2674
        }
 
 
2675
        break;
 
 
2676
        case I_BehaviourHierarchicalFragment:
 
 
2677
        {
 
 
2678
            HDEBRIS_BEHAV_BLOCK *debrisDataPtr  = (HDEBRIS_BEHAV_BLOCK *)sbPtr->dataptr;
 
 
2679
 
 
 
2680
            switch(debrisDataPtr->Type)
 
 
2681
            {
 
 
2682
                case I_BehaviourAlien:
 
 
2683
                case I_BehaviourAlienPlayer:
 
 
2684
                    colour = ALIENS_LIFEFORCE_GLOW_COLOUR;
 
 
2685
                break;
 
 
2686
                case I_BehaviourPredator:
 
 
2687
                case I_BehaviourPredatorPlayer:
 
 
2688
                    colour = PREDATORS_LIFEFORCE_GLOW_COLOUR;
 
 
2689
                break;
 
 
2690
                case I_BehaviourMarine:
 
 
2691
                case I_BehaviourMarinePlayer:
 
 
2692
                    if (debrisDataPtr->Android)
 
 
2693
                        return;
 
 
2694
                    colour = MARINES_LIFEFORCE_GLOW_COLOUR;
 
 
2695
                break;
 
 
2696
                default:
 
 
2697
                return;
 
 
2698
            }
 
 
2699
        }
 
 
2700
        break;
 
 
2701
        default:
 
 
2702
        return;
 
 
2703
    }
 
 
2704
 
 
 
2705
    if((dispPtr->SpecialFXFlags & SFXFLAG_MELTINGINTOGROUND) && (dispPtr->ObFlags2 < ONE_FIXED))    
 
 
2706
    {
 
 
2707
        unsigned int alpha = MUL_FIXED(dispPtr->ObFlags2,colour >> 24);
 
 
2708
        colour = (colour & 0xffffff) + (alpha << 24);
 
 
2709
    }
 
 
2710
 
 
 
2711
    /* KJL 16:36:12 10/02/98 - check positions are up to date */
 
 
2712
    ProveHModel(controllerPtr, dispPtr);
 
 
2713
 
 
 
2714
    DecalSystem_Setup();
 
 
2715
 
 
 
2716
    FindAlienEnergySource_Recursion(controllerPtr, controllerPtr->section_data, colour);
 
 
2717
 
 
 
2718
    DecalSystem_End();
 
 
2719
}
 
 
2720
 
 
 
2721
static void MorphPoints(SHAPEINSTR *shapeinstrptr)
 
 
2722
{
 
 
2723
    VECTORCH *srcPtr;
 
 
2724
 
 
 
2725
    {
 
 
2726
        /* Set up the morph data */
 
 
2727
 
 
 
2728
        struct shapeheader* shape1Ptr = MorphDisplay.md_sptr1;
 
 
2729
 
 
 
2730
        switch(MorphDisplay.md_lerp)
 
 
2731
        {
 
 
2732
            case 0x0000:
 
 
2733
            {
 
 
2734
                srcPtr = (VECTORCH *)*shape1Ptr->points;
 
 
2735
            }
 
 
2736
            break;
 
 
2737
            case 0xffff:
 
 
2738
            {
 
 
2739
                struct shapeheader* shape2Ptr = MorphDisplay.md_sptr2;
 
 
2740
 
 
 
2741
                srcPtr = (VECTORCH *)*shape2Ptr->points;
 
 
2742
                Global_ShapePoints = *(shape2Ptr->points);
 
 
2743
            }
 
 
2744
            break;
 
 
2745
            default:
 
 
2746
            {
 
 
2747
                struct shapeheader* shape2Ptr = MorphDisplay.md_sptr2;
 
 
2748
                VECTORCH *shape1PointsPtr = (VECTORCH *)(*shape1Ptr->points);
 
 
2749
                VECTORCH *shape2PointsPtr = (VECTORCH *)(*shape2Ptr->points);
 
 
2750
 
 
 
2751
                {
 
 
2752
                    int numberOfPoints = shape1Ptr->numpoints;
 
 
2753
                    VECTORCH *morphedPointsPtr = (VECTORCH *) MorphedPts;
 
 
2754
 
 
 
2755
                    while(numberOfPoints--)
 
 
2756
                    {
 
 
2757
                        VECTORCH vertex1 = *shape1PointsPtr;
 
 
2758
                        VECTORCH vertex2 = *shape2PointsPtr;
 
 
2759
 
 
 
2760
                        if( (vertex1.vx == vertex2.vx && vertex1.vy == vertex2.vy && vertex1.vz == vertex2.vz) )
 
 
2761
                        {
 
 
2762
                            *morphedPointsPtr = vertex1;
 
 
2763
                        }
 
 
2764
                        else
 
 
2765
                        {
 
 
2766
                            /* KJL 15:27:20 05/22/97 - I've changed this to speed things up, If a vertex
 
 
2767
                            component has a magnitude greater than 32768 things will go wrong. */
 
 
2768
                            morphedPointsPtr->vx = vertex1.vx + (((vertex2.vx-vertex1.vx)*MorphDisplay.md_lerp)>>16);
 
 
2769
                            morphedPointsPtr->vy = vertex1.vy + (((vertex2.vy-vertex1.vy)*MorphDisplay.md_lerp)>>16);
 
 
2770
                            morphedPointsPtr->vz = vertex1.vz + (((vertex2.vz-vertex1.vz)*MorphDisplay.md_lerp)>>16);
 
 
2771
                        }
 
 
2772
 
 
 
2773
                        shape1PointsPtr++;
 
 
2774
                        shape2PointsPtr++;
 
 
2775
                        morphedPointsPtr++;
 
 
2776
                    }
 
 
2777
                }
 
 
2778
 
 
 
2779
                Global_ShapePoints = (int*)MorphedPts;
 
 
2780
                srcPtr = (VECTORCH *)MorphedPts;
 
 
2781
            }
 
 
2782
        }
 
 
2783
    }
 
 
2784
 
 
 
2785
    {
 
 
2786
        VECTORCH *destPtr = RotatedPts;
 
 
2787
        int i = shapeinstrptr->sh_numitems;
 
 
2788
 
 
 
2789
        for(; i; i--)
 
 
2790
        {
 
 
2791
            Source[0] = srcPtr->vx + Global_ODB_Ptr->ObWorld.vx;
 
 
2792
            Source[1] = srcPtr->vy + Global_ODB_Ptr->ObWorld.vy;
 
 
2793
            Source[2] = srcPtr->vz + Global_ODB_Ptr->ObWorld.vz;
 
 
2794
 
 
 
2795
            TranslatePoint(Source, Dest, ViewMatrix);
 
 
2796
 
 
 
2797
            destPtr->vx = (int)Dest[0];
 
 
2798
            destPtr->vy = (int)Dest[1];
 
 
2799
            destPtr->vz = (int)Dest[2];
 
 
2800
            srcPtr++;
 
 
2801
            destPtr++;
 
 
2802
        }
 
 
2803
    }
 
 
2804
}
 
 
2805
 
 
 
2806
static void TranslateShapeVertices(SHAPEINSTR *shapeinstrptr)
 
 
2807
{
 
 
2808
    VECTORCH *destPtr = RotatedPts;
 
 
2809
    int**    shapeitemarrayptr = shapeinstrptr->sh_instr_data;
 
 
2810
    VECTORCH *srcPtr = (VECTORCH*)*shapeitemarrayptr;
 
 
2811
    int i = shapeinstrptr->sh_numitems;
 
 
2812
 
 
 
2813
    ObjectViewMatrix[0+0*4] = (float)(Global_ODB_Ptr->ObMat.mat11)/65536.0f;
 
 
2814
    ObjectViewMatrix[1+0*4] = (float)(Global_ODB_Ptr->ObMat.mat21)/65536.0f;
 
 
2815
    ObjectViewMatrix[2+0*4] = (float)(Global_ODB_Ptr->ObMat.mat31)/65536.0f;
 
 
2816
 
 
 
2817
    ObjectViewMatrix[0+1*4] = (float)(Global_ODB_Ptr->ObMat.mat12)/(65536.0f);
 
 
2818
    ObjectViewMatrix[1+1*4] = (float)(Global_ODB_Ptr->ObMat.mat22)/(65536.0f);
 
 
2819
    ObjectViewMatrix[2+1*4] = (float)(Global_ODB_Ptr->ObMat.mat32)/(65536.0f);
 
 
2820
 
 
 
2821
    ObjectViewMatrix[0+2*4] = (float)(Global_ODB_Ptr->ObMat.mat13)/65536.0f;
 
 
2822
    ObjectViewMatrix[1+2*4] = (float)(Global_ODB_Ptr->ObMat.mat23)/65536.0f;
 
 
2823
    ObjectViewMatrix[2+2*4] = (float)(Global_ODB_Ptr->ObMat.mat33)/65536.0f;
 
 
2824
 
 
 
2825
    ObjectViewMatrix[3+0*4] = Global_ODB_Ptr->ObWorld.vx;
 
 
2826
    ObjectViewMatrix[3+1*4] = Global_ODB_Ptr->ObWorld.vy;
 
 
2827
    ObjectViewMatrix[3+2*4] = Global_ODB_Ptr->ObWorld.vz;
 
 
2828
 
 
 
2829
    while(i--)
 
 
2830
    {
 
 
2831
        Source[0] = srcPtr->vx;
 
 
2832
        Source[1] = srcPtr->vy;
 
 
2833
        Source[2] = srcPtr->vz;
 
 
2834
 
 
 
2835
        TranslatePoint(Source, Dest, ObjectViewMatrix);
 
 
2836
        TranslatePoint(Dest, Source, ViewMatrix);
 
 
2837
 
 
 
2838
        destPtr->vx = (int)Source[0];
 
 
2839
        destPtr->vy = (int)Source[1];
 
 
2840
        destPtr->vz = (int)Source[2];
 
 
2841
        srcPtr++;
 
 
2842
        destPtr++;
 
 
2843
    }
 
 
2844
}
 
 
2845
 
 
 
2846
static int predator_vision(struct shapeheader* shapePtr)
 
 
2847
{
 
 
2848
    switch(PlayerStatus.VisionMode)
 
 
2849
    {
 
 
2850
        case VISION_MODE_PRED_THERMAL:
 
 
2851
        {
 
 
2852
            /* if we have an object with heat sources, draw it as such */
 
 
2853
            if (NumberOfHeatSources)
 
 
2854
            {
 
 
2855
                PredatorThermalVision_ShapePipeline(shapePtr);
 
 
2856
                return 1;
 
 
2857
            }
 
 
2858
        }
 
 
2859
        return 0;
 
 
2860
        case VISION_MODE_PRED_SEEALIENS:
 
 
2861
        {
 
 
2862
            STRATEGYBLOCK *sbPtr = Global_ODB_Ptr->ObStrategyBlock;
 
 
2863
 
 
 
2864
             if(sbPtr)
 
 
2865
             {
 
 
2866
                 switch (sbPtr->type)
 
 
2867
                {
 
 
2868
                     case I_BehaviourAlien:
 
 
2869
                    case I_BehaviourAlienPlayer:
 
 
2870
                    case I_BehaviourFaceHugger:
 
 
2871
                    case I_BehaviourXenoborg:
 
 
2872
                    case I_BehaviourQueenAlien:
 
 
2873
                    break;
 
 
2874
                    case I_BehaviourHierarchicalFragment:
 
 
2875
                    {
 
 
2876
                        HDEBRIS_BEHAV_BLOCK *debrisDataPtr = (HDEBRIS_BEHAV_BLOCK *)sbPtr->dataptr;
 
 
2877
 
 
 
2878
                        switch(debrisDataPtr->Type)
 
 
2879
                        {
 
 
2880
                            case I_BehaviourAlien:
 
 
2881
                            case I_BehaviourQueenAlien:
 
 
2882
                            case I_BehaviourFaceHugger:
 
 
2883
                            case I_BehaviourXenoborg:
 
 
2884
                            case I_BehaviourAlienPlayer:
 
 
2885
                            break;
 
 
2886
                            default:
 
 
2887
                            return 0;
 
 
2888
                        }
 
 
2889
                    }
 
 
2890
                    break;
 
 
2891
                    case I_BehaviourCorpse:
 
 
2892
                    {
 
 
2893
                        CORPSEDATABLOCK *corpseDataPtr = (CORPSEDATABLOCK *)sbPtr->dataptr;
 
 
2894
 
 
 
2895
                        switch(corpseDataPtr->Type)
 
 
2896
                        {
 
 
2897
                            case I_BehaviourAlien:
 
 
2898
                            case I_BehaviourAlienPlayer:
 
 
2899
                            case I_BehaviourFaceHugger:
 
 
2900
                            case I_BehaviourXenoborg:
 
 
2901
                            case I_BehaviourQueenAlien:
 
 
2902
                            break;
 
 
2903
                            default:
 
 
2904
                            return 0;
 
 
2905
                        }
 
 
2906
                    }
 
 
2907
                    break;
 
 
2908
                    case I_BehaviourNetGhost:
 
 
2909
                    {
 
 
2910
                           NETGHOSTDATABLOCK *ghostDataPtr = (NETGHOSTDATABLOCK *)Global_ODB_Ptr->ObStrategyBlock->dataptr;
 
 
2911
 
 
 
2912
                        switch(ghostDataPtr->type)
 
 
2913
                        {
 
 
2914
                            case I_BehaviourCorpse:
 
 
2915
                                if (ghostDataPtr->subtype != I_BehaviourAlienPlayer)
 
 
2916
                                    return 0;
 
 
2917
                            case I_BehaviourAlienPlayer:
 
 
2918
                            case I_BehaviourAlien:
 
 
2919
                            break;
 
 
2920
                            default:
 
 
2921
                            return 0;
 
 
2922
                        }
 
 
2923
                    }
 
 
2924
                    break;
 
 
2925
                    case I_BehaviourSpeargunBolt:
 
 
2926
                    {
 
 
2927
                        SPEAR_BEHAV_BLOCK *spearDataPtr = (SPEAR_BEHAV_BLOCK *)sbPtr->dataptr;
 
 
2928
 
 
 
2929
                        if (spearDataPtr->SpearThroughFragment) // more flags required!
 
 
2930
                        {
 
 
2931
                            switch(spearDataPtr->Type)
 
 
2932
                            {
 
 
2933
                                case I_BehaviourAlien:
 
 
2934
                                case I_BehaviourQueenAlien:
 
 
2935
                                case I_BehaviourFaceHugger:
 
 
2936
                                case I_BehaviourXenoborg:
 
 
2937
                                case I_BehaviourAlienPlayer:
 
 
2938
                                break;
 
 
2939
                                default:
 
 
2940
                                return 0;
 
 
2941
                            }
 
 
2942
                        }
 
 
2943
                    }
 
 
2944
                    default:
 
 
2945
                    return 0;
 
 
2946
                }
 
 
2947
 
 
 
2948
                PredatorSeeAliensVision_ShapePipeline(shapePtr);
 
 
2949
                return 1;
 
 
2950
            }
 
 
2951
        }
 
 
2952
        break;
 
 
2953
        case VISION_MODE_PRED_SEEPREDTECH:
 
 
2954
        {
 
 
2955
            STRATEGYBLOCK *sbPtr = Global_ODB_Ptr->ObStrategyBlock;
 
 
2956
 
 
 
2957
             if(sbPtr)
 
 
2958
            {
 
 
2959
                 switch (sbPtr->type)
 
 
2960
                {
 
 
2961
                     case I_BehaviourPredator:
 
 
2962
                    {
 
 
2963
                           PREDATOR_STATUS_BLOCK *predData = (PREDATOR_STATUS_BLOCK *)Global_ODB_Ptr->ObStrategyBlock->dataptr;
 
 
2964
 
 
 
2965
                        if (predData->CloakingEffectiveness)
 
 
2966
                            return 0;
 
 
2967
                    }
 
 
2968
                    case I_BehaviourPredatorDisc_SeekTrack:
 
 
2969
                    break;
 
 
2970
                    case I_BehaviourCorpse:
 
 
2971
                    {
 
 
2972
                        CORPSEDATABLOCK *corpseDataPtr = (CORPSEDATABLOCK *)sbPtr->dataptr;
 
 
2973
 
 
 
2974
                        switch(corpseDataPtr->Type)
 
 
2975
                        {
 
 
2976
                            case I_BehaviourPredator:
 
 
2977
                            case I_BehaviourPredatorPlayer:
 
 
2978
                            break;
 
 
2979
                            default:
 
 
2980
                            return 0;
 
 
2981
                        }
 
 
2982
                    }
 
 
2983
                    break;
 
 
2984
                    case I_BehaviourHierarchicalFragment:
 
 
2985
                    {
 
 
2986
                        HDEBRIS_BEHAV_BLOCK *debrisDataPtr  = (HDEBRIS_BEHAV_BLOCK *)sbPtr->dataptr;
 
 
2987
 
 
 
2988
                        if (debrisDataPtr->Type != I_BehaviourPredator)
 
 
2989
                            return 0;
 
 
2990
                    }
 
 
2991
                    break;
 
 
2992
                    case I_BehaviourNetGhost:
 
 
2993
                    {
 
 
2994
                           NETGHOSTDATABLOCK *ghostDataPtr = (NETGHOSTDATABLOCK *)Global_ODB_Ptr->ObStrategyBlock->dataptr;
 
 
2995
 
 
 
2996
                        if(!ghostDataPtr->CloakingEffectiveness)
 
 
2997
                        {
 
 
2998
                            switch(ghostDataPtr->type)
 
 
2999
                            {
 
 
3000
                                case I_BehaviourCorpse:
 
 
3001
                                    if (ghostDataPtr->subtype != I_BehaviourPredatorPlayer)
 
 
3002
                                        return 0;
 
 
3003
                                case I_BehaviourInanimateObject:
 
 
3004
                                    if (ghostDataPtr->IOType != IOT_Ammo && ghostDataPtr->subtype != AMMO_PRED_DISC) 
 
 
3005
                                        return 0;
 
 
3006
                                case I_BehaviourPredator:
 
 
3007
                                case I_BehaviourPredatorPlayer:
 
 
3008
                                case I_BehaviourPredatorDisc_SeekTrack: 
 
 
3009
                                    break;
 
 
3010
                                default:
 
 
3011
                                return 0;
 
 
3012
                            }
 
 
3013
                        }
 
 
3014
                    }
 
 
3015
                    break;
 
 
3016
                    case I_BehaviourInanimateObject:
 
 
3017
                    {
 
 
3018
                        INANIMATEOBJECT_STATUSBLOCK* objStatPtr = (INANIMATEOBJECT_STATUSBLOCK*) sbPtr->dataptr;
 
 
3019
 
 
 
3020
                        switch(objStatPtr->typeId)
 
 
3021
                        {
 
 
3022
                            case IOT_FieldCharge:
 
 
3023
                                break;
 
 
3024
                            case IOT_Weapon:
 
 
3025
                            if(WEAPON_PRED_DISC == objStatPtr->subType)
 
 
3026
                                break;
 
 
3027
                            case IOT_Ammo:
 
 
3028
                            if(AMMO_PRED_RIFLE == objStatPtr->subType)
 
 
3029
                                break;
 
 
3030
                            default:
 
 
3031
                            return 0;
 
 
3032
                        }
 
 
3033
                    }
 
 
3034
                    break;
 
 
3035
                    case I_BehaviourSpeargunBolt:
 
 
3036
                    {
 
 
3037
                        SPEAR_BEHAV_BLOCK *spearDataPtr = (SPEAR_BEHAV_BLOCK *)sbPtr->dataptr;
 
 
3038
 
 
 
3039
                        if (spearDataPtr->SpearThroughFragment) // more flags required!
 
 
3040
                        {
 
 
3041
                            switch(spearDataPtr->Type)
 
 
3042
                            {
 
 
3043
                                case I_BehaviourPredator:
 
 
3044
                                case I_BehaviourPredatorPlayer:
 
 
3045
                                    break;
 
 
3046
                                default:
 
 
3047
                                return 0;
 
 
3048
                            }
 
 
3049
                        }
 
 
3050
                        else
 
 
3051
                        break;
 
 
3052
                    }
 
 
3053
                    default:
 
 
3054
                    return 0;
 
 
3055
                }
 
 
3056
 
 
 
3057
                    PredatorSeeAliensVision_ShapePipeline(shapePtr);
 
 
3058
                    return 1;
 
 
3059
            }
 
 
3060
        }
 
 
3061
        default:
 
 
3062
        return 0;
 
 
3063
    }
 
 
3064
 
 
 
3065
return 0;
 
 
3066
}
 
 
3067
 
 
 
3068
int jadda(struct shapeheader* shapeheaderptr)
 
 
3069
{
 
 
3070
    /* interesting hack for predator cloaking */
 
 
3071
 
 
 
3072
    int numitems = shapeheaderptr->numitems;
 
 
3073
    int **itemArrayPtr = shapeheaderptr->items;
 
 
3074
 
 
 
3075
    int CloakingEffectiveness;
 
 
3076
 
 
 
3077
    switch(Global_ODB_Ptr->ObStrategyBlock->type)
 
 
3078
    {
 
 
3079
        case I_BehaviourNetGhost:
 
 
3080
        {
 
 
3081
            NETGHOSTDATABLOCK *ghostData = (NETGHOSTDATABLOCK *)Global_ODB_Ptr->ObStrategyBlock->dataptr;
 
 
3082
 
 
 
3083
            if(!ghostData->CloakingEffectiveness)
 
 
3084
                return 0;
 
 
3085
 
 
 
3086
            CloakingEffectiveness = ghostData->CloakingEffectiveness;
 
 
3087
        }
 
 
3088
        break;
 
 
3089
        case I_BehaviourPredator:
 
 
3090
        {
 
 
3091
            PREDATOR_STATUS_BLOCK *predData = (PREDATOR_STATUS_BLOCK *)Global_ODB_Ptr->ObStrategyBlock->dataptr;
 
 
3092
 
 
 
3093
            if (!predData->CloakingEffectiveness)
 
 
3094
                return 0;
 
 
3095
 
 
 
3096
            CloakingEffectiveness = predData->CloakingEffectiveness;
 
 
3097
        }
 
 
3098
        default:
 
 
3099
        return 0;
 
 
3100
    }
 
 
3101
 
 
 
3102
    do
 
 
3103
    {
 
 
3104
        POLYHEADER *polyPtr = (POLYHEADER*) (*itemArrayPtr++);
 
 
3105
        int pif = PolygonWithinFrustrum(polyPtr);
 
 
3106
 
 
 
3107
        if(pif)
 
 
3108
        {
 
 
3109
            switch(polyPtr->PolyItemType)
 
 
3110
            {
 
 
3111
                case I_ZB_Gouraud3dTexturedPolygon:
 
 
3112
                case I_ZB_Gouraud2dTexturedPolygon:
 
 
3113
                CloakedPolygon_Construct(polyPtr, ((ONE_FIXED * 5 / 4) - CloakingEffectiveness));
 
 
3114
 
 
 
3115
                if (pif != 2) 
 
 
3116
                {
 
 
3117
                    GouraudTexturedPolygon_ClipWithZ();
 
 
3118
 
 
 
3119
                    if(RenderPolygon.NumberOfVertices < 3)
 
 
3120
                            continue;
 
 
3121
 
 
 
3122
                    GouraudTexturedPolygon_ClipWithNegativeX();
 
 
3123
 
 
 
3124
                    if(RenderPolygon.NumberOfVertices < 3)
 
 
3125
                            continue;
 
 
3126
 
 
 
3127
                    GouraudTexturedPolygon_ClipWithPositiveY();
 
 
3128
 
 
 
3129
                    if(RenderPolygon.NumberOfVertices < 3)
 
 
3130
                            continue;
 
 
3131
 
 
 
3132
                    GouraudTexturedPolygon_ClipWithNegativeY();
 
 
3133
 
 
 
3134
                    if(RenderPolygon.NumberOfVertices < 3)
 
 
3135
                            continue;
 
 
3136
 
 
 
3137
                    GouraudTexturedPolygon_ClipWithPositiveX();
 
 
3138
 
 
 
3139
                    if(RenderPolygon.NumberOfVertices < 3)
 
 
3140
                            continue;
 
 
3141
 
 
 
3142
                    ZBufferedCloakedPolygon_Output(polyPtr, RenderPolygon.Vertices);
 
 
3143
                }
 
 
3144
                else
 
 
3145
                {
 
 
3146
                    ZBufferedCloakedPolygon_Output(polyPtr, VerticesBuffer);
 
 
3147
                }
 
 
3148
                break;
 
 
3149
                default:
 
 
3150
                    printf("found polygon of type %d\n",polyPtr->PolyItemType);
 
 
3151
            }
 
 
3152
        }
 
 
3153
 
 
 
3154
    } while(--numitems);
 
 
3155
 
 
 
3156
    return 1;
 
 
3157
}
 
 
3158
 
 
 
3159
static void ShapePipeline(struct shapeheader* shapePtr)
 
 
3160
{
 
 
3161
    int numitems = shapePtr->numitems;
 
 
3162
    int **itemArrayPtr = shapePtr->items;
 
 
3163
 
 
 
3164
    assert(numitems);
 
 
3165
 
 
 
3166
      if(Global_ODB_Ptr->ObStrategyBlock && jadda(shapePtr))
 
 
3167
        return;
 
 
3168
 
 
 
3169
    do
 
 
3170
    {
 
 
3171
        POLYHEADER *polyPtr = (POLYHEADER*) (*itemArrayPtr++);
 
 
3172
 
 
 
3173
        int pif = PolygonWithinFrustrum(polyPtr);
 
 
3174
 
 
 
3175
        if (pif)
 
 
3176
        {
 
 
3177
            switch(polyPtr->PolyItemType)
 
 
3178
            {
 
 
3179
                case I_ZB_GouraudPolygon:
 
 
3180
                {
 
 
3181
                    GouraudPolygon_Construct(polyPtr);
 
 
3182
 
 
 
3183
                    if (pif != 2)
 
 
3184
                    {
 
 
3185
                        GouraudPolygon_ClipWithZ();
 
 
3186
 
 
 
3187
                        if(RenderPolygon.NumberOfVertices < 3)
 
 
3188
                                continue;
 
 
3189
 
 
 
3190
                        GouraudPolygon_ClipWithNegativeX();
 
 
3191
 
 
 
3192
                        if(RenderPolygon.NumberOfVertices < 3)
 
 
3193
                                continue;
 
 
3194
 
 
 
3195
                        GouraudPolygon_ClipWithPositiveY();
 
 
3196
 
 
 
3197
                        if(RenderPolygon.NumberOfVertices < 3)
 
 
3198
                                continue;
 
 
3199
 
 
 
3200
                        GouraudPolygon_ClipWithNegativeY();
 
 
3201
 
 
 
3202
                        if(RenderPolygon.NumberOfVertices < 3)
 
 
3203
                                continue;
 
 
3204
 
 
 
3205
                        GouraudPolygon_ClipWithPositiveX();
 
 
3206
 
 
 
3207
                        if(RenderPolygon.NumberOfVertices < 3)
 
 
3208
                                continue;
 
 
3209
 
 
 
3210
                        ZBufferedGouraudPolygon_Output(polyPtr, RenderPolygon.Vertices);
 
 
3211
                      }
 
 
3212
                    else
 
 
3213
                    {
 
 
3214
                        ZBufferedGouraudPolygon_Output(polyPtr, VerticesBuffer);
 
 
3215
                    }
 
 
3216
                }
 
 
3217
                break;
 
 
3218
                 case I_ZB_Gouraud3dTexturedPolygon:
 
 
3219
                case I_ZB_Gouraud2dTexturedPolygon:
 
 
3220
                {
 
 
3221
                    GouraudTexturedPolygon_Construct(polyPtr);
 
 
3222
 
 
 
3223
                       if (pif != 2)
 
 
3224
                    {
 
 
3225
                        /* if this polygon is a quad, split it into two */
 
 
3226
                        if(RenderPolygon.NumberOfVertices == 4)
 
 
3227
                        {
 
 
3228
                            RENDERVERTEX TriangleVerticesBuffer[3] = { VerticesBuffer[0], VerticesBuffer[2], VerticesBuffer[3] };
 
 
3229
                            RenderPolygon.NumberOfVertices = 3;
 
 
3230
 
 
 
3231
                            GouraudTexturedPolygon_ClipWithZ();
 
 
3232
 
 
 
3233
                            if(RenderPolygon.NumberOfVertices < 3)
 
 
3234
                                goto SecondTriangle;
 
 
3235
 
 
 
3236
                            GouraudTexturedPolygon_ClipWithNegativeX();
 
 
3237
 
 
 
3238
                            if(RenderPolygon.NumberOfVertices < 3)
 
 
3239
                                goto SecondTriangle;
 
 
3240
 
 
 
3241
                            GouraudTexturedPolygon_ClipWithPositiveY();
 
 
3242
 
 
 
3243
                            if(RenderPolygon.NumberOfVertices < 3)
 
 
3244
                                goto SecondTriangle;
 
 
3245
 
 
 
3246
                            GouraudTexturedPolygon_ClipWithNegativeY();
 
 
3247
 
 
 
3248
                            if(RenderPolygon.NumberOfVertices < 3)
 
 
3249
                                goto SecondTriangle;
 
 
3250
 
 
 
3251
                            GouraudTexturedPolygon_ClipWithPositiveX();
 
 
3252
 
 
 
3253
                            if(RenderPolygon.NumberOfVertices < 3)
 
 
3254
                                goto SecondTriangle;
 
 
3255
 
 
 
3256
                            if (polyPtr->PolyFlags & iflag_transparent)
 
 
3257
                                AddToTranslucentPolyList(polyPtr, RenderPolygon.Vertices);
 
 
3258
                            else 
 
 
3259
                                ZBufferedGouraudTexturedPolygon_Output(polyPtr, RenderPolygon.Vertices);
 
 
3260
 
 
 
3261
                            SecondTriangle:
 
 
3262
                            RenderPolygon.NumberOfVertices = 3;
 
 
3263
                            VerticesBuffer[0] = TriangleVerticesBuffer[0];
 
 
3264
                            VerticesBuffer[1] = TriangleVerticesBuffer[1];
 
 
3265
                            VerticesBuffer[2] = TriangleVerticesBuffer[2];
 
 
3266
                        }
 
 
3267
 
 
 
3268
                        GouraudTexturedPolygon_ClipWithZ();
 
 
3269
 
 
 
3270
                        if(RenderPolygon.NumberOfVertices < 3)
 
 
3271
                                continue;
 
 
3272
 
 
 
3273
                        GouraudTexturedPolygon_ClipWithNegativeX();
 
 
3274
 
 
 
3275
                        if(RenderPolygon.NumberOfVertices < 3)
 
 
3276
                                continue;
 
 
3277
 
 
 
3278
                        GouraudTexturedPolygon_ClipWithPositiveY();
 
 
3279
 
 
 
3280
                        if(RenderPolygon.NumberOfVertices < 3)
 
 
3281
                                continue;
 
 
3282
 
 
 
3283
                        GouraudTexturedPolygon_ClipWithNegativeY();
 
 
3284
 
 
 
3285
                        if(RenderPolygon.NumberOfVertices < 3)
 
 
3286
                                continue;
 
 
3287
 
 
 
3288
                        GouraudTexturedPolygon_ClipWithPositiveX();
 
 
3289
 
 
 
3290
                        if(RenderPolygon.NumberOfVertices < 3)
 
 
3291
                                continue;
 
 
3292
 
 
 
3293
                        if (polyPtr->PolyFlags & iflag_transparent)
 
 
3294
                            AddToTranslucentPolyList(polyPtr, RenderPolygon.Vertices);
 
 
3295
                        else 
 
 
3296
                            ZBufferedGouraudTexturedPolygon_Output(polyPtr, RenderPolygon.Vertices);
 
 
3297
                      }
 
 
3298
                    else
 
 
3299
                    {
 
 
3300
                        if (polyPtr->PolyFlags & iflag_transparent)
 
 
3301
                            AddToTranslucentPolyList(polyPtr, VerticesBuffer);
 
 
3302
                        else 
 
 
3303
                            ZBufferedGouraudTexturedPolygon_Output(polyPtr, VerticesBuffer);
 
 
3304
                    }
 
 
3305
                }
 
 
3306
                   default:
 
 
3307
                break;
 
 
3308
            }
 
 
3309
         }
 
 
3310
 
 
 
3311
    } while(--numitems);
 
 
3312
}
 
 
3313
 
 
 
3314
static void HandleObjectOnFire(DISPLAYBLOCK *dispPtr)
 
 
3315
{
 
 
3316
    int noRequired = 1;
 
 
3317
    int i;
 
 
3318
    VECTORCH velocity;
 
 
3319
 
 
 
3320
    if (dispPtr->extent.radius <= LocalDetailLevels.AlienEnergyViewThreshold)
 
 
3321
        return;
 
 
3322
 
 
 
3323
    {
 
 
3324
        STRATEGYBLOCK *sbPtr = dispPtr->ObStrategyBlock;
 
 
3325
        DYNAMICSBLOCK *dynPtr = sbPtr->DynPtr;
 
 
3326
 
 
 
3327
        velocity.vx = DIV_FIXED((dynPtr->Position.vx - dynPtr->PrevPosition.vx)*3, NormalFrameTime*4);
 
 
3328
        velocity.vy = DIV_FIXED((dynPtr->Position.vy - dynPtr->PrevPosition.vy)*3, NormalFrameTime*4);
 
 
3329
        velocity.vz = DIV_FIXED((dynPtr->Position.vz - dynPtr->PrevPosition.vz)*3, NormalFrameTime*4);
 
 
3330
 
 
 
3331
        if (dispPtr == sbPtr->DisplayBlock)
 
 
3332
            noRequired = 5;
 
 
3333
    }
 
 
3334
 
 
 
3335
    int objectIsDisappearing = ( (dispPtr->SpecialFXFlags & SFXFLAG_MELTINGINTOGROUND) && (dispPtr->ObFlags2 <= ONE_FIXED) );
 
 
3336
 
 
 
3337
    for (i=0; i < noRequired; i++)
 
 
3338
    {
 
 
3339
        VECTORCH position;
 
 
3340
        position.vx = dispPtr->ObWorld.vx + (FastRandom() & 255)-128;
 
 
3341
        position.vy = dispPtr->ObWorld.vy + (FastRandom() & 255)-128;
 
 
3342
        position.vz = dispPtr->ObWorld.vz + (FastRandom() & 255)-128;
 
 
3343
 
 
 
3344
        if (objectIsDisappearing)
 
 
3345
        {
 
 
3346
            if ((FastRandom()&65535) < dispPtr->ObFlags2)
 
 
3347
                MakeParticle(&position, &velocity, PARTICLE_FIRE);
 
 
3348
        }
 
 
3349
        else
 
 
3350
        {
 
 
3351
            MakeParticle(&position, &velocity, PARTICLE_FIRE);
 
 
3352
        }
 
 
3353
 
 
 
3354
        if ((FastRandom() & 65535) > 32768)
 
 
3355
            MakeParticle(&position, &velocity, PARTICLE_IMPACTSMOKE);
 
 
3356
    }
 
 
3357
}
 
 
3358
 
 
 
3359
void AddShape(DISPLAYBLOCK *dptr)
 
 
3360
{
 
 
3361
    struct shapeheader* shapeheaderptr = dptr->ShapeData;
 
 
3362
 
 
 
3363
    if(dptr->ObTxAnimCtrlBlks)
 
 
3364
        ControlTextureAnimation(dptr);
 
 
3365
 
 
 
3366
    SetupShapePipeline(dptr);
 
 
3367
 
 
 
3368
    TranslateShapeVertices(shapeheaderptr->sh_instruction);
 
 
3369
    TestVerticesWithFrustrum(shapeheaderptr->numpoints);
 
 
3370
 
 
 
3371
    if(!predator_vision(shapeheaderptr))
 
 
3372
        ShapePipeline(shapeheaderptr);
 
 
3373
 
 
 
3374
    if (dptr->ObStrategyBlock)
 
 
3375
    {
 
 
3376
        if(dptr->ObStrategyBlock->DamageBlock.IsOnFire)
 
 
3377
        {
 
 
3378
            dptr->SpecialFXFlags |= SFXFLAG_ONFIRE;
 
 
3379
            HandleObjectOnFire(dptr);
 
 
3380
        }
 
 
3381
        else
 
 
3382
            dptr->SpecialFXFlags &= ~SFXFLAG_ONFIRE;
 
 
3383
 
 
 
3384
/*
 
 
3385
        switch(dptr->ObStrategyBlock->type)
 
 
3386
        {
 
 
3387
            case I_BehaviourPlacedLight:
 
 
3388
            {
 
 
3389
                STRATEGYBLOCK *sbPtr =  dptr->ObStrategyBlock;
 
 
3390
                PLACED_LIGHT_BEHAV_BLOCK* pl_bhv = sbPtr->dataptr;
 
 
3391
 
 
 
3392
                if (pl_bhv->has_corona && pl_bhv->light->LightBright
 
 
3393
                && (ModuleCurrVisArray[sbPtr->containingModule->m_index] == 2)
 
 
3394
                && (pl_bhv->light->RedScale || pl_bhv->light->GreenScale || pl_bhv->light->BlueScale))
 
 
3395
                {
 
 
3396
                    LIGHTBLOCK *lPtr = pl_bhv->light;
 
 
3397
                    int colour;
 
 
3398
 
 
 
3399
                    switch (PlayerStatus.VisionMode)
 
 
3400
                    {
 
 
3401
                        case VISION_MODE_NORMAL:
 
 
3402
                        default:
 
 
3403
                        {
 
 
3404
                            int r = MUL_FIXED(lPtr->RedScale, lPtr->LightBright) >> 8;
 
 
3405
                            int g = MUL_FIXED(lPtr->GreenScale, lPtr->LightBright) >> 8;
 
 
3406
                            int b = MUL_FIXED(lPtr->BlueScale, lPtr->LightBright) >> 8;
 
 
3407
                            if (r > 255) r = 255;
 
 
3408
                            if (g > 255) g = 255;
 
 
3409
                            if (b > 255) b = 255;
 
 
3410
                            colour = 0xff000000+(r<<16)+(g<<8)+(b);
 
 
3411
                        }
 
 
3412
                        break;
 
 
3413
                        case VISION_MODE_IMAGEINTENSIFIER:
 
 
3414
                            colour = 0xffffffff;
 
 
3415
                        break;
 
 
3416
                        case VISION_MODE_PRED_THERMAL:
 
 
3417
                        case VISION_MODE_PRED_SEEALIENS:
 
 
3418
                        case VISION_MODE_PRED_SEEPREDTECH:
 
 
3419
                        {
 
 
3420
                            int b = MUL_FIXED(lPtr->RedScale+lPtr->GreenScale+lPtr->BlueScale, lPtr->LightBright) >> 10;
 
 
3421
                            if (b > 255) b = 255;
 
 
3422
 
 
 
3423
                            colour = 0xff000000+(b<<16)+((b>>1)<<8);
 
 
3424
                        }
 
 
3425
                    }
 
 
3426
 
 
 
3427
                    {
 
 
3428
                    DecalSystem_Setup();
 
 
3429
                    PARTICLE particle;
 
 
3430
 
 
 
3431
                    particle.Position = dptr->ObWorld;
 
 
3432
 
 
 
3433
                    particle.Colour = colour;
 
 
3434
                    particle.ParticleID = PARTICLE_MUZZLEFLASH;
 
 
3435
                    particle.Size = 300;
 
 
3436
                    RenderParticle(&particle);
 
 
3437
 
 
 
3438
                    DecalSystem_End();
 
 
3439
                    }
 
 
3440
                }
 
 
3441
            }
 
 
3442
            break;
 
 
3443
            case I_BehaviourInanimateObject:
 
 
3444
            {
 
 
3445
                INANIMATEOBJECT_STATUSBLOCK* objStatPtr = dptr->ObStrategyBlock->dataptr;
 
 
3446
 
 
 
3447
                if(objStatPtr->typeId == IOT_FieldCharge)
 
 
3448
                {
 
 
3449
                    int i = 0;
 
 
3450
                    DecalSystem_Setup();
 
 
3451
 
 
 
3452
                    for(; i < 63; i++)
 
 
3453
                    {
 
 
3454
                        PARTICLE particle;
 
 
3455
 
 
 
3456
                        // SBF - 20080518 - commented out the undefined usage of particle.Position.vz
 
 
3457
                        particle.Position.vy = -280+i-GetCos((CloakingPhase/16*i + i*64)&4095)/1024;
 
 
3458
                        particle.Position.vx = GetCos((CloakingPhase +i*64+particle.Position.vy)&4095)/512;
 
 
3459
                        particle.Position.vz = GetSin((CloakingPhase +i*64+particle.Position.vy)&4095)/512;
 
 
3460
                        RotateVector(&particle.Position, &dptr->ObMat);
 
 
3461
                        particle.Position.vx += dptr->ObWorld.vx;
 
 
3462
                        particle.Position.vy += dptr->ObWorld.vy;
 
 
3463
                        particle.Position.vz += dptr->ObWorld.vz;
 
 
3464
                        particle.ParticleID = PARTICLE_MUZZLEFLASH;
 
 
3465
                        particle.Colour = 0xff00007f+(FastRandom()&0x7f7f7f);
 
 
3466
                        particle.Size = 40;
 
 
3467
                        RenderParticle(&particle);
 
 
3468
                    }
 
 
3469
 
 
 
3470
                    DecalSystem_End();
 
 
3471
                }
 
 
3472
            }
 
 
3473
            default:
 
 
3474
            break;
 
 
3475
        }
 
 
3476
*/
 
 
3477
    }
 
 
3478
}
 
 
3479
 
 
 
3480
void AddModuleShape(DISPLAYBLOCK *dptr)
 
 
3481
{
 
 
3482
    struct shapeheader* shapeheaderptr;
 
 
3483
 
 
 
3484
     if(dptr->ObMorphCtrl)
 
 
3485
    {
 
 
3486
        GetMorphDisplay(&MorphDisplay, dptr);
 
 
3487
        dptr->ObShape     = MorphDisplay.md_shape1;
 
 
3488
        dptr->ShapeData = MorphDisplay.md_sptr1;
 
 
3489
        shapeheaderptr = MorphDisplay.md_sptr1;
 
 
3490
        SetupShapePipeline(dptr);
 
 
3491
        MorphPoints(shapeheaderptr->sh_instruction);
 
 
3492
    }
 
 
3493
    else
 
 
3494
    {
 
 
3495
        shapeheaderptr = dptr->ShapeData;
 
 
3496
        SetupShapePipeline(dptr);
 
 
3497
        TranslateShapeVertices(shapeheaderptr->sh_instruction);
 
 
3498
    }
 
 
3499
 
 
 
3500
    if(dptr->ObTxAnimCtrlBlks)
 
 
3501
        ControlTextureAnimation(dptr);
 
 
3502
 
 
 
3503
    TestVerticesWithFrustrum(shapeheaderptr->numpoints);
 
 
3504
    ShapePipeline(shapeheaderptr);
 
 
3505
}
 
 
3506
 
 
 
3507
void AttachSpearGunArrow(DISPLAYBLOCK *dptr)
 
 
3508
{
 
 
3509
    struct shapeheader* shapeheaderptr = dptr->ShapeData;
 
 
3510
 
 
 
3511
    SetupShapePipeline(dptr);
 
 
3512
 
 
 
3513
    TranslateShapeVertices(shapeheaderptr->sh_instruction);
 
 
3514
    TestVerticesWithFrustrum(shapeheaderptr->numpoints);
 
 
3515
    ShapePipeline(shapeheaderptr);
 
 
3516
}
 
 
3517
 
 
 
3518
void DisplayFacehuggerOnHud(DISPLAYBLOCK *dptr)
 
 
3519
{
 
 
3520
    if(dptr->ObStrategyBlock->DamageBlock.IsOnFire)
 
 
3521
        dptr->SpecialFXFlags |= SFXFLAG_ONFIRE;
 
 
3522
    else
 
 
3523
        dptr->SpecialFXFlags &= ~SFXFLAG_ONFIRE;
 
 
3524
 
 
 
3525
    /*
 
 
3526
    Create the Local -> View Matrix
 
 
3527
 
 
 
3528
    LToVMat = VDB_Mat * ObMat
 
 
3529
 
 
 
3530
    "Get the points into View Space, then apply the Local Transformation"
 
 
3531
    */
 
 
3532
 
 
 
3533
    MatrixMultiply(&Global_VDB.VDB_Mat, &dptr->ObMat, &LToVMat);
 
 
3534
    MatrixToEuler(&LToVMat, &LToVMat_Euler);
 
 
3535
 
 
 
3536
    /*
 
 
3537
    Create the World -> Local Matrix
 
 
3538
 
 
 
3539
    WToLMat = Transposed Local Matrix
 
 
3540
    */
 
 
3541
 
 
 
3542
    WToLMat = dptr->ObMat;
 
 
3543
    TransposeMatrixCH(&WToLMat);
 
 
3544
 
 
 
3545
    /*
 
 
3546
 
 
 
3547
    Transform the View World Location to Local Space
 
 
3548
 
 
 
3549
    -> Make the View Loc. relative to the Object View Space Centre
 
 
3550
    -> Rotate this vector using WToLMat
 
 
3551
 
 
 
3552
    */
 
 
3553
 
 
 
3554
    LocalView.vx = Global_VDB.VDB_World.vx - dptr->ObWorld.vx;
 
 
3555
    LocalView.vy = Global_VDB.VDB_World.vy - dptr->ObWorld.vy;
 
 
3556
    LocalView.vz = Global_VDB.VDB_World.vz - dptr->ObWorld.vz;
 
 
3557
 
 
 
3558
    RotateVector(&LocalView, &WToLMat);
 
 
3559
 
 
 
3560
    DoHModel(dptr);
 
 
3561
}
 
 
3562
 
 
 
3563
void DisplayAlienTeeth(DISPLAYBLOCK *dptr)
 
 
3564
{
 
 
3565
    struct shapeheader* shapeheaderptr = mainshapelist[dptr->ObShape];
 
 
3566
    dptr->ShapeData = shapeheaderptr;
 
 
3567
    SetupShapePipeline(dptr);
 
 
3568
{
 
 
3569
    SHAPEINSTR *shapeinstrptr = shapeheaderptr->sh_instruction;
 
 
3570
    VECTORCH *destPtr = RotatedPts;
 
 
3571
    int**    shapeitemarrayptr = shapeinstrptr->sh_instr_data;
 
 
3572
    VECTORCH *srcPtr = (VECTORCH*)*shapeitemarrayptr;
 
 
3573
    int i = shapeinstrptr->sh_numitems;
 
 
3574
 
 
 
3575
    while(i--)
 
 
3576
    {
 
 
3577
        destPtr->vx = (srcPtr->vx + Global_ODB_Ptr->ObView.vx);
 
 
3578
        destPtr->vy = ((srcPtr->vy + Global_ODB_Ptr->ObView.vy) * 4)/3;
 
 
3579
        destPtr->vz = (srcPtr->vz + Global_ODB_Ptr->ObView.vz);
 
 
3580
 
 
 
3581
        srcPtr++;
 
 
3582
        destPtr++;
 
 
3583
    }
 
 
3584
}
 
 
3585
    TestVerticesWithFrustrum(shapeheaderptr->numpoints);
 
 
3586
    ShapePipeline(shapeheaderptr);
 
 
3587
}
 
 
3588
 
 
 
3589
void display_players_weapon()
 
 
3590
{
 
 
3591
    DISPLAYBLOCK *dptr = &PlayerStatus.weapon;
 
 
3592
 
 
 
3593
    /*
 
 
3594
        Create the Local -> View Matrix
 
 
3595
        LToVMat = VDB_Mat * ObMat
 
 
3596
        "Get the points into View Space, then apply the Local Transformation"
 
 
3597
    */
 
 
3598
 
 
 
3599
    MatrixMultiply(&Global_VDB.VDB_Mat, &dptr->ObMat, &LToVMat);
 
 
3600
    MatrixToEuler(&LToVMat, &LToVMat_Euler);
 
 
3601
 
 
 
3602
    /*
 
 
3603
        Create the World -> Local Matrix
 
 
3604
        WToLMat = Transposed Local Matrix
 
 
3605
    */
 
 
3606
 
 
 
3607
    WToLMat = dptr->ObMat;
 
 
3608
    TransposeMatrixCH(&WToLMat);
 
 
3609
 
 
 
3610
    /*
 
 
3611
        Transform the View World Location to Local Space
 
 
3612
 
 
 
3613
        -> Make the View Loc. relative to the Object View Space Centre
 
 
3614
        -> Rotate this vector using WToLMat
 
 
3615
    */
 
 
3616
 
 
 
3617
    LocalView.vx = Global_VDB.VDB_World.vx - dptr->ObWorld.vx;
 
 
3618
    LocalView.vy = Global_VDB.VDB_World.vy - dptr->ObWorld.vy;
 
 
3619
    LocalView.vz = Global_VDB.VDB_World.vz - dptr->ObWorld.vz;
 
 
3620
 
 
 
3621
    RotateVector(&LocalView, &WToLMat);
 
 
3622
    DoPlayersWeaponHModel(dptr);
 
 
3623
}
 
 
3624
 
 
 
3625
static void SquishPoints(DISPLAYBLOCK * dptr)
 
 
3626
{
 
 
3627
    struct shapeheader* shapeheaderptr = dptr->ShapeData;
 
 
3628
    int** shapeitemarrayptr = shapeheaderptr->sh_instruction->sh_instr_data;
 
 
3629
    VECTORCH *shapePts = (VECTORCH*)*shapeitemarrayptr;
 
 
3630
    int i;
 
 
3631
    int scale = dptr->ObFlags2;
 
 
3632
 
 
 
3633
    for (i=0; i < shapeheaderptr->numpoints; i++)
 
 
3634
    {
 
 
3635
        VECTORCH point = shapePts[i];
 
 
3636
 
 
 
3637
        RotateVector(&point, &dptr->ObMat);
 
 
3638
 
 
 
3639
        point.vx = MUL_FIXED(point.vx, ONE_FIXED*3/2 - scale/2);
 
 
3640
        point.vx += dptr->ObWorld.vx;
 
 
3641
 
 
 
3642
        point.vz = MUL_FIXED(point.vz, ONE_FIXED*3/2 - scale/2);
 
 
3643
        point.vz += dptr->ObWorld.vz;
 
 
3644
 
 
 
3645
        point.vy += dptr->ObWorld.vy;
 
 
3646
        point.vy = HierarchicalObjectsLowestYValue + MUL_FIXED(point.vy - HierarchicalObjectsLowestYValue, scale);
 
 
3647
 
 
 
3648
        Source[0] = point.vx;
 
 
3649
        Source[1] = point.vy;
 
 
3650
        Source[2] = point.vz;
 
 
3651
 
 
 
3652
        TranslatePoint(Source, Dest, ViewMatrix);
 
 
3653
 
 
 
3654
        RotatedPts[i].vx = (int)Dest[0];
 
 
3655
        RotatedPts[i].vy = (int)Dest[1];
 
 
3656
        RotatedPts[i].vz = (int)Dest[2];
 
 
3657
    }
 
 
3658
}
 
 
3659
 
 
 
3660
void AddShape2(DISPLAYBLOCK *dptr)
 
 
3661
{
 
 
3662
    if(dptr->ObStrategyBlock->DamageBlock.IsOnFire)
 
 
3663
        dptr->SpecialFXFlags |= SFXFLAG_ONFIRE;
 
 
3664
    else
 
 
3665
        dptr->SpecialFXFlags &= ~SFXFLAG_ONFIRE;
 
 
3666
 
 
 
3667
    /*
 
 
3668
    Create the Local -> View Matrix
 
 
3669
 
 
 
3670
    LToVMat = VDB_Mat * ObMat
 
 
3671
 
 
 
3672
    "Get the points into View Space, then apply the Local Transformation"
 
 
3673
    */
 
 
3674
 
 
 
3675
    MatrixMultiply(&Global_VDB.VDB_Mat, &dptr->ObMat, &LToVMat);
 
 
3676
    MatrixToEuler(&LToVMat, &LToVMat_Euler);
 
 
3677
 
 
 
3678
    /*
 
 
3679
    Create the World -> Local Matrix
 
 
3680
 
 
 
3681
    WToLMat = Transposed Local Matrix
 
 
3682
    */
 
 
3683
 
 
 
3684
    WToLMat = dptr->ObMat;
 
 
3685
    TransposeMatrixCH(&WToLMat);
 
 
3686
 
 
 
3687
    /*
 
 
3688
 
 
 
3689
    Transform the View World Location to Local Space
 
 
3690
 
 
 
3691
    -> Make the View Loc. relative to the Object View Space Centre
 
 
3692
    -> Rotate this vector using WToLMat
 
 
3693
 
 
 
3694
    */
 
 
3695
 
 
 
3696
    LocalView.vx = Global_VDB.VDB_World.vx - dptr->ObWorld.vx;
 
 
3697
    LocalView.vy = Global_VDB.VDB_World.vy - dptr->ObWorld.vy;
 
 
3698
    LocalView.vz = Global_VDB.VDB_World.vz - dptr->ObWorld.vz;
 
 
3699
 
 
 
3700
    RotateVector(&LocalView, &WToLMat);
 
 
3701
 
 
 
3702
    ObjectCentre = dptr->ObView;
 
 
3703
 
 
 
3704
    HierarchicalObjectsLowestYValue = dptr->ObStrategyBlock->DynPtr->ObjectVertices[0].vy;
 
 
3705
 
 
 
3706
    if (AvP.PlayerType == I_Alien)// && PlayerStatus.VisionMode == VISION_MODE_NORMAL)
 
 
3707
    {
 
 
3708
        DoAlienEnergyView(dptr);
 
 
3709
    }
 
 
3710
    else if (PlayerStatus.VisionMode == VISION_MODE_PRED_THERMAL)
 
 
3711
    {
 
 
3712
        NumberOfHeatSources = 0;
 
 
3713
        FindHeatSourcesInHModel(dptr);
 
 
3714
    }
 
 
3715
 
 
 
3716
    DoHModel(dptr);
 
 
3717
}
 
 
3718
 
 
 
3719
void AddHierarchicalShape(DISPLAYBLOCK *dptr)
 
 
3720
{
 
 
3721
    struct shapeheader* shapeheaderptr = dptr->ShapeData;
 
 
3722
 
 
 
3723
    /* Texture Animation Control */
 
 
3724
    if(dptr->ObTxAnimCtrlBlks)
 
 
3725
        ControlTextureAnimation(dptr);
 
 
3726
 
 
 
3727
    SetupShapePipeline(dptr);
 
 
3728
 
 
 
3729
    switch(UserProfile.active_bonus)
 
 
3730
    {
 
 
3731
        case CHEATMODE_BALLSOFFIRE:
 
 
3732
            dptr->SpecialFXFlags |= SFXFLAG_ONFIRE;
 
 
3733
        case CHEATMODE_PIPECLEANER:
 
 
3734
            if(!dptr->ObStrategyBlock)
 
 
3735
                break;
 
 
3736
        case CHEATMODE_NONACTIVE:
 
 
3737
        default:
 
 
3738
        {
 
 
3739
            // setup the rotated points array
 
 
3740
 
 
 
3741
            if((dptr->SpecialFXFlags & SFXFLAG_MELTINGINTOGROUND) && (dptr->ObFlags2 <= ONE_FIXED))    
 
 
3742
                SquishPoints(dptr);
 
 
3743
            else
 
 
3744
                TranslateShapeVertices(shapeheaderptr->sh_instruction);
 
 
3745
 
 
 
3746
            TestVerticesWithFrustrum(shapeheaderptr->numpoints);
 
 
3747
 
 
 
3748
            if(!predator_vision(shapeheaderptr))
 
 
3749
                ShapePipeline(shapeheaderptr);
 
 
3750
        }
 
 
3751
    }
 
 
3752
 
 
 
3753
    if (dptr->SpecialFXFlags & SFXFLAG_ONFIRE)
 
 
3754
        HandleObjectOnFire(dptr);
 
 
3755
}
 
 
3756
 
 
 
3757
void AddPlayersWeaponShape(DISPLAYBLOCK *dptr)
 
 
3758
{
 
 
3759
    struct shapeheader* shapeheaderptr = dptr->ShapeData;
 
 
3760
 
 
 
3761
    SetupShapePipeline(dptr);
 
 
3762
 
 
 
3763
    /*     setup the rotated points array */
 
 
3764
 
 
 
3765
    TranslateShapeVertices(shapeheaderptr->sh_instruction);
 
 
3766
 
 
 
3767
    TestVerticesWithFrustrum(shapeheaderptr->numpoints);
 
 
3768
 
 
 
3769
    if(I_Predator == AvP.PlayerType)
 
 
3770
    {
 
 
3771
        if (PlayerStatus.cloakOn || PlayerStatus.CloakingEffectiveness)
 
 
3772
        {
 
 
3773
            int numitems = shapeheaderptr->numitems;
 
 
3774
            int **itemArrayPtr = shapeheaderptr->items;
 
 
3775
 
 
 
3776
            int a = GetSin(CloakingPhase & 4095);
 
 
3777
            a = MUL_FIXED(a, a);
 
 
3778
            int CloakingMode = ONE_FIXED * 5 / 4 - PlayerStatus.CloakingEffectiveness;
 
 
3779
 
 
 
3780
            do
 
 
3781
            {
 
 
3782
                POLYHEADER *polyPtr = (POLYHEADER*) (*itemArrayPtr++);
 
 
3783
                int pif = PolygonWithinFrustrum(polyPtr);
 
 
3784
 
 
 
3785
                if(pif)
 
 
3786
                {
 
 
3787
                    switch(polyPtr->PolyItemType)
 
 
3788
                    {
 
 
3789
                        case I_ZB_Gouraud3dTexturedPolygon:
 
 
3790
                        case I_ZB_Gouraud2dTexturedPolygon:
 
 
3791
                        CloakedPolygon_Construct(polyPtr, CloakingMode);
 
 
3792
 
 
 
3793
                        if (pif != 2)
 
 
3794
                        {
 
 
3795
                            GouraudTexturedPolygon_ClipWithZ();
 
 
3796
 
 
 
3797
                            if(RenderPolygon.NumberOfVertices < 3)
 
 
3798
                                    continue;
 
 
3799
 
 
 
3800
                            GouraudTexturedPolygon_ClipWithNegativeX();
 
 
3801
 
 
 
3802
                            if(RenderPolygon.NumberOfVertices < 3)
 
 
3803
                                    continue;
 
 
3804
 
 
 
3805
                            GouraudTexturedPolygon_ClipWithPositiveY();
 
 
3806
 
 
 
3807
                            if(RenderPolygon.NumberOfVertices < 3)
 
 
3808
                                    continue;
 
 
3809
 
 
 
3810
                            GouraudTexturedPolygon_ClipWithNegativeY();
 
 
3811
 
 
 
3812
                            if(RenderPolygon.NumberOfVertices < 3)
 
 
3813
                                    continue;
 
 
3814
 
 
 
3815
                            GouraudTexturedPolygon_ClipWithPositiveX();
 
 
3816
 
 
 
3817
                            if(RenderPolygon.NumberOfVertices < 3)
 
 
3818
                                    continue;
 
 
3819
 
 
 
3820
                            ZBufferedCloakedPolygon_Output(polyPtr, RenderPolygon.Vertices);
 
 
3821
                        }
 
 
3822
                        else
 
 
3823
                        {
 
 
3824
                            ZBufferedCloakedPolygon_Output(polyPtr, VerticesBuffer);
 
 
3825
                        }
 
 
3826
                        break;
 
 
3827
                        default:
 
 
3828
                            printf("found polygon of type %d\n",polyPtr->PolyItemType);
 
 
3829
                    }
 
 
3830
                }
 
 
3831
 
 
 
3832
            } while(--numitems);
 
 
3833
        }
 
 
3834
        else if(VISION_MODE_PRED_SEEPREDTECH == PlayerStatus.VisionMode)
 
 
3835
            PredatorSeeAliensVision_ShapePipeline(shapeheaderptr);
 
 
3836
        else
 
 
3837
            ShapePipeline(shapeheaderptr);
 
 
3838
    }
 
 
3839
    else
 
 
3840
    {
 
 
3841
        ShapePipeline(shapeheaderptr);
 
 
3842
    }
 
 
3843
}
 
 
3844
 
 
 
3845
void TranslationSetup()
 
 
3846
{
 
 
3847
    VECTORCH v = Global_VDB.VDB_World;
 
 
3848
    float p = (PredatorVisionChangeCounter / 65536.0f) + 1.0f;
 
 
3849
    float o = 1.0f;
 
 
3850
    CurrentNumberOfTranslucentPolygons = 0; // put it here just it make variable static
 
 
3851
 
 
 
3852
    if (CHEATMODE_NAUSEA == UserProfile.active_bonus)
 
 
3853
    {
 
 
3854
        p = (GetSin((CloakingPhase/3)&4095))/65536.0f;
 
 
3855
        p = 1.0f + p*p;
 
 
3856
 
 
 
3857
        o = (GetCos((CloakingPhase/5)&4095))/65536.0f;
 
 
3858
        o = 1.0f + o*o;
 
 
3859
    }
 
 
3860
 
 
 
3861
    #if 1
 
 
3862
    ViewMatrix[0+0*4] = (float)(Global_VDB.VDB_Mat.mat11)/65536.0f*o;
 
 
3863
    ViewMatrix[1+0*4] = (float)(Global_VDB.VDB_Mat.mat21)/65536.0f*o;
 
 
3864
    ViewMatrix[2+0*4] = (float)(Global_VDB.VDB_Mat.mat31)/65536.0f*o;
 
 
3865
    #else
 
 
3866
    ViewMatrix[0+0*4] = (float)(Global_VDB.VDB_Mat.mat11)/65536.0f;
 
 
3867
    ViewMatrix[1+0*4] = (float)(Global_VDB.VDB_Mat.mat21)/65536.0f;
 
 
3868
    ViewMatrix[2+0*4] = (float)(Global_VDB.VDB_Mat.mat31)/65536.0f;
 
 
3869
    #endif
 
 
3870
 
 
 
3871
    #if 1
 
 
3872
    ViewMatrix[0+1*4] = (float)(Global_VDB.VDB_Mat.mat12)*4.0f/(65536.0f*3.0f)*p;
 
 
3873
    ViewMatrix[1+1*4] = (float)(Global_VDB.VDB_Mat.mat22)*4.0f/(65536.0f*3.0f)*p;
 
 
3874
    ViewMatrix[2+1*4] = (float)(Global_VDB.VDB_Mat.mat32)*4.0f/(65536.0f*3.0f)*p;
 
 
3875
    #else
 
 
3876
    ViewMatrix[0+1*4] = (float)(Global_VDB.VDB_Mat.mat12)/(65536.0f);
 
 
3877
    ViewMatrix[1+1*4] = (float)(Global_VDB.VDB_Mat.mat22)/(65536.0f);
 
 
3878
    ViewMatrix[2+1*4] = (float)(Global_VDB.VDB_Mat.mat32)/(65536.0f);
 
 
3879
    #endif
 
 
3880
 
 
 
3881
    ViewMatrix[0+2*4] = (float)(Global_VDB.VDB_Mat.mat13)/65536.0f*CameraZoomScale;
 
 
3882
    ViewMatrix[1+2*4] = (float)(Global_VDB.VDB_Mat.mat23)/65536.0f*CameraZoomScale;
 
 
3883
    ViewMatrix[2+2*4] = (float)(Global_VDB.VDB_Mat.mat33)/65536.0f*CameraZoomScale;
 
 
3884
 
 
 
3885
    RotateVector(&v,&Global_VDB.VDB_Mat);
 
 
3886
 
 
 
3887
    ViewMatrix[3+0*4] = ((float)-v.vx)*o;
 
 
3888
    ViewMatrix[3+1*4] = ((float)-v.vy)*4.0f/3.0f*p;
 
 
3889
    ViewMatrix[3+2*4] = ((float)-v.vz)*CameraZoomScale;
 
 
3890
 
 
 
3891
    if (CHEATMODE_MIRROR == UserProfile.active_bonus)
 
 
3892
    {
 
 
3893
        ViewMatrix[0+0*4] = -ViewMatrix[0+0*4];
 
 
3894
        ViewMatrix[1+0*4] = -ViewMatrix[1+0*4];
 
 
3895
        ViewMatrix[2+0*4] = -ViewMatrix[2+0*4];
 
 
3896
        ViewMatrix[3+0*4] = -ViewMatrix[3+0*4];
 
 
3897
    }
 
 
3898
}
 
 
3899
 
 
 
3900
static void DecalPolygon_Construct(const DECAL *decalPtr)
 
 
3901
{
 
 
3902
    DECAL_DESC *decalDescPtr = &DecalDescription[decalPtr->DecalID];
 
 
3903
    RenderPolygon.NumberOfVertices = 4;
 
 
3904
 
 
 
3905
    VerticesBuffer[0].U = decalDescPtr->StartU+decalPtr->UOffset;
 
 
3906
    VerticesBuffer[0].V = decalDescPtr->StartV;
 
 
3907
 
 
 
3908
    VerticesBuffer[1].U = decalDescPtr->EndU+decalPtr->UOffset;
 
 
3909
    VerticesBuffer[1].V = decalDescPtr->StartV;
 
 
3910
 
 
 
3911
    VerticesBuffer[2].U = decalDescPtr->EndU+decalPtr->UOffset;
 
 
3912
    VerticesBuffer[2].V = decalDescPtr->EndV;
 
 
3913
 
 
 
3914
    VerticesBuffer[3].U = decalDescPtr->StartU+decalPtr->UOffset;
 
 
3915
    VerticesBuffer[3].V = decalDescPtr->EndV;
 
 
3916
}
 
 
3917
 
 
 
3918
#if MIRRORING_ON
 
 
3919
static void RenderMirroredDecal(DECAL *decalPtr)
 
 
3920
{
 
 
3921
    /* translate decal into view space */
 
 
3922
    {
 
 
3923
        VECTORCH translatedPosition = decalPtr->Vertices[0];
 
 
3924
        translatedPosition.vx = MirroringAxis - translatedPosition.vx;
 
 
3925
        TranslatePointIntoViewspace(&translatedPosition);
 
 
3926
        VerticesBuffer[0].X = translatedPosition.vx;
 
 
3927
        VerticesBuffer[0].Y = translatedPosition.vy;
 
 
3928
        VerticesBuffer[0].Z = translatedPosition.vz;
 
 
3929
    }
 
 
3930
    {
 
 
3931
        VECTORCH translatedPosition = decalPtr->Vertices[1];
 
 
3932
        translatedPosition.vx = MirroringAxis - translatedPosition.vx;
 
 
3933
        TranslatePointIntoViewspace(&translatedPosition);
 
 
3934
        VerticesBuffer[1].X = translatedPosition.vx;
 
 
3935
        VerticesBuffer[1].Y = translatedPosition.vy;
 
 
3936
        VerticesBuffer[1].Z = translatedPosition.vz;
 
 
3937
    }
 
 
3938
    {
 
 
3939
        VECTORCH translatedPosition = decalPtr->Vertices[2];
 
 
3940
        translatedPosition.vx = MirroringAxis - translatedPosition.vx;
 
 
3941
        TranslatePointIntoViewspace(&translatedPosition);
 
 
3942
        VerticesBuffer[2].X = translatedPosition.vx;
 
 
3943
        VerticesBuffer[2].Y = translatedPosition.vy;
 
 
3944
        VerticesBuffer[2].Z = translatedPosition.vz;
 
 
3945
    }
 
 
3946
    {
 
 
3947
        VECTORCH translatedPosition = decalPtr->Vertices[3];
 
 
3948
        translatedPosition.vx = MirroringAxis - translatedPosition.vx;
 
 
3949
        TranslatePointIntoViewspace(&translatedPosition);
 
 
3950
        VerticesBuffer[3].X = translatedPosition.vx;
 
 
3951
        VerticesBuffer[3].Y = translatedPosition.vy;
 
 
3952
        VerticesBuffer[3].Z = translatedPosition.vz;
 
 
3953
    }
 
 
3954
    {
 
 
3955
        int outcode = DecalWithinFrustrum(decalPtr);
 
 
3956
 
 
 
3957
        if (outcode)
 
 
3958
        {
 
 
3959
            DecalPolygon_Construct(decalPtr);
 
 
3960
 
 
 
3961
            if (outcode != 2)
 
 
3962
            {
 
 
3963
                TexturedPolygon_ClipWithZ();
 
 
3964
 
 
 
3965
                if(RenderPolygon.NumberOfVertices < 3)
 
 
3966
                    return;
 
 
3967
 
 
 
3968
                TexturedPolygon_ClipWithNegativeX();
 
 
3969
 
 
 
3970
                if(RenderPolygon.NumberOfVertices < 3)
 
 
3971
                    return;
 
 
3972
 
 
 
3973
                TexturedPolygon_ClipWithPositiveY();
 
 
3974
 
 
 
3975
                if(RenderPolygon.NumberOfVertices < 3)
 
 
3976
                    return;
 
 
3977
 
 
 
3978
                TexturedPolygon_ClipWithNegativeY();
 
 
3979
 
 
 
3980
                if(RenderPolygon.NumberOfVertices < 3)
 
 
3981
                    return;
 
 
3982
 
 
 
3983
                TexturedPolygon_ClipWithPositiveX();
 
 
3984
 
 
 
3985
                if(RenderPolygon.NumberOfVertices < 3)
 
 
3986
                    return;
 
 
3987
 
 
 
3988
                Decal_Output(decalPtr,RenderPolygon.Vertices);
 
 
3989
            }
 
 
3990
            else
 
 
3991
            {
 
 
3992
                Decal_Output(decalPtr,VerticesBuffer);
 
 
3993
            }
 
 
3994
        }
 
 
3995
    }
 
 
3996
}
 
 
3997
#endif
 
 
3998
 
 
 
3999
void RenderDecal(const DECAL *decalPtr)
 
 
4000
{
 
 
4001
    /* translate decal into view space */
 
 
4002
    {
 
 
4003
        VECTORCH translatedPosition = decalPtr->Vertices[0];
 
 
4004
        TranslatePointIntoViewspace(&translatedPosition);
 
 
4005
        VerticesBuffer[0].X = translatedPosition.vx;
 
 
4006
        VerticesBuffer[0].Y = translatedPosition.vy;
 
 
4007
        VerticesBuffer[0].Z = translatedPosition.vz;
 
 
4008
    }
 
 
4009
    {
 
 
4010
        VECTORCH translatedPosition = decalPtr->Vertices[1];
 
 
4011
        TranslatePointIntoViewspace(&translatedPosition);
 
 
4012
        VerticesBuffer[1].X = translatedPosition.vx;
 
 
4013
        VerticesBuffer[1].Y = translatedPosition.vy;
 
 
4014
        VerticesBuffer[1].Z = translatedPosition.vz;
 
 
4015
    }
 
 
4016
    {
 
 
4017
        VECTORCH translatedPosition = decalPtr->Vertices[2];
 
 
4018
        TranslatePointIntoViewspace(&translatedPosition);
 
 
4019
        VerticesBuffer[2].X = translatedPosition.vx;
 
 
4020
        VerticesBuffer[2].Y = translatedPosition.vy;
 
 
4021
        VerticesBuffer[2].Z = translatedPosition.vz;
 
 
4022
    }
 
 
4023
    {
 
 
4024
        VECTORCH translatedPosition = decalPtr->Vertices[3];
 
 
4025
        TranslatePointIntoViewspace(&translatedPosition);
 
 
4026
        VerticesBuffer[3].X = translatedPosition.vx;
 
 
4027
        VerticesBuffer[3].Y = translatedPosition.vy;
 
 
4028
        VerticesBuffer[3].Z = translatedPosition.vz;
 
 
4029
    }
 
 
4030
    {
 
 
4031
        int outcode = DecalWithinFrustrum(decalPtr);
 
 
4032
 
 
 
4033
        if (outcode)
 
 
4034
        {
 
 
4035
            DecalPolygon_Construct(decalPtr);
 
 
4036
 
 
 
4037
            if (outcode != 2)
 
 
4038
            {
 
 
4039
                TexturedPolygon_ClipWithZ();
 
 
4040
 
 
 
4041
                if(RenderPolygon.NumberOfVertices < 3)
 
 
4042
                    return;
 
 
4043
 
 
 
4044
                TexturedPolygon_ClipWithNegativeX();
 
 
4045
 
 
 
4046
                if(RenderPolygon.NumberOfVertices < 3)
 
 
4047
                    return;
 
 
4048
 
 
 
4049
                TexturedPolygon_ClipWithPositiveY();
 
 
4050
 
 
 
4051
                if(RenderPolygon.NumberOfVertices < 3)
 
 
4052
                    return;
 
 
4053
 
 
 
4054
                TexturedPolygon_ClipWithNegativeY();
 
 
4055
 
 
 
4056
                if(RenderPolygon.NumberOfVertices < 3)
 
 
4057
                    return;
 
 
4058
 
 
 
4059
                TexturedPolygon_ClipWithPositiveX();
 
 
4060
 
 
 
4061
                if(RenderPolygon.NumberOfVertices < 3)
 
 
4062
                    return;
 
 
4063
 
 
 
4064
                Decal_Output(decalPtr, RenderPolygon.Vertices);
 
 
4065
            }
 
 
4066
            else
 
 
4067
            {
 
 
4068
                Decal_Output(decalPtr, VerticesBuffer);
 
 
4069
            }
 
 
4070
        }
 
 
4071
    }
 
 
4072
 
 
 
4073
    #if MIRRORING_ON
 
 
4074
    if (MirroringActive)
 
 
4075
        RenderMirroredDecal(decalPtr);
 
 
4076
    #endif
 
 
4077
}
 
 
4078
 
 
 
4079
void RenderFlechetteParticle(PARTICLE *particlePtr)
 
 
4080
{
 
 
4081
    VECTORCH vertices[5];
 
 
4082
    MATRIXCH mat;
 
 
4083
 
 
 
4084
    MakeMatrixFromDirection(&particlePtr->Velocity, &mat);
 
 
4085
 
 
 
4086
    mat.mat11 >>= 12;
 
 
4087
    mat.mat12 >>= 12;
 
 
4088
    mat.mat13 >>= 12;
 
 
4089
    mat.mat21 >>= 12;
 
 
4090
    mat.mat22 >>= 12;
 
 
4091
    mat.mat23 >>= 12;
 
 
4092
    mat.mat31 >>= 9;
 
 
4093
    mat.mat32 >>= 9;
 
 
4094
    mat.mat33 >>= 9;
 
 
4095
 
 
 
4096
    vertices[0].vx = particlePtr->Position.vx - mat.mat31 + mat.mat11;
 
 
4097
    vertices[0].vy = particlePtr->Position.vy - mat.mat32 + mat.mat12;
 
 
4098
    vertices[0].vz = particlePtr->Position.vz - mat.mat33 + mat.mat13;
 
 
4099
 
 
 
4100
    vertices[1].vx = particlePtr->Position.vx - mat.mat31 - mat.mat11;
 
 
4101
    vertices[1].vy = particlePtr->Position.vy - mat.mat32 - mat.mat12;
 
 
4102
    vertices[1].vz = particlePtr->Position.vz - mat.mat33 - mat.mat13;
 
 
4103
 
 
 
4104
    vertices[2] = particlePtr->Position;
 
 
4105
 
 
 
4106
    vertices[3].vx = particlePtr->Position.vx - mat.mat31 + mat.mat21;
 
 
4107
    vertices[3].vy = particlePtr->Position.vy - mat.mat32 + mat.mat22;
 
 
4108
    vertices[3].vz = particlePtr->Position.vz - mat.mat33 + mat.mat23;
 
 
4109
 
 
 
4110
    vertices[4].vx = particlePtr->Position.vx - mat.mat31 - mat.mat21;
 
 
4111
    vertices[4].vy = particlePtr->Position.vy - mat.mat32 - mat.mat22;
 
 
4112
    vertices[4].vz = particlePtr->Position.vz - mat.mat33 - mat.mat23;
 
 
4113
 
 
 
4114
    TranslatePointIntoViewspace(&vertices[0]);
 
 
4115
    TranslatePointIntoViewspace(&vertices[1]);
 
 
4116
    TranslatePointIntoViewspace(&vertices[2]);
 
 
4117
    TranslatePointIntoViewspace(&vertices[3]);
 
 
4118
    TranslatePointIntoViewspace(&vertices[4]);
 
 
4119
 
 
 
4120
    {
 
 
4121
        int i = 0;
 
 
4122
        for (; i < 3; i++)
 
 
4123
        {
 
 
4124
            VerticesBuffer[i].X = vertices[i].vx;
 
 
4125
            VerticesBuffer[i].Y = vertices[i].vy;
 
 
4126
            VerticesBuffer[i].Z = vertices[i].vz;
 
 
4127
 
 
 
4128
            VerticesBuffer[i].A = (particlePtr->Colour >> 24) & 255;
 
 
4129
            VerticesBuffer[i].R = (particlePtr->Colour >> 16) & 255;
 
 
4130
            VerticesBuffer[i].G = (particlePtr->Colour >> 8) & 255;
 
 
4131
            VerticesBuffer[i].B = (particlePtr->Colour) & 255;
 
 
4132
        }
 
 
4133
 
 
 
4134
        RenderPolygon.NumberOfVertices = 3;
 
 
4135
        RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL;
 
 
4136
    }
 
 
4137
 
 
 
4138
    {
 
 
4139
        int outcode = TriangleWithinFrustrum();
 
 
4140
        POLYHEADER fakeHeader;
 
 
4141
        fakeHeader.PolyFlags  = iflag_transparent;
 
 
4142
    do
 
 
4143
    {
 
 
4144
        if (outcode)
 
 
4145
        {
 
 
4146
            if(outcode != 2)
 
 
4147
            {
 
 
4148
                GouraudPolygon_ClipWithZ();
 
 
4149
 
 
 
4150
                if(RenderPolygon.NumberOfVertices < 3)
 
 
4151
                    continue;
 
 
4152
 
 
 
4153
                GouraudPolygon_ClipWithNegativeX();
 
 
4154
 
 
 
4155
                if(RenderPolygon.NumberOfVertices < 3)
 
 
4156
                    continue;
 
 
4157
 
 
 
4158
                GouraudPolygon_ClipWithPositiveY();
 
 
4159
 
 
 
4160
                if(RenderPolygon.NumberOfVertices < 3)
 
 
4161
                    continue;
 
 
4162
 
 
 
4163
                GouraudPolygon_ClipWithNegativeY();
 
 
4164
 
 
 
4165
                if(RenderPolygon.NumberOfVertices < 3)
 
 
4166
                    continue;
 
 
4167
 
 
 
4168
                GouraudPolygon_ClipWithPositiveX();
 
 
4169
 
 
 
4170
                if(RenderPolygon.NumberOfVertices < 3)
 
 
4171
                    continue;
 
 
4172
 
 
 
4173
                ZBufferedGouraudPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
 
 
4174
            }
 
 
4175
            else
 
 
4176
            {
 
 
4177
                ZBufferedGouraudPolygon_Output(&fakeHeader,VerticesBuffer);
 
 
4178
            }
 
 
4179
        }
 
 
4180
 
 
 
4181
    } while (0);
 
 
4182
 
 
 
4183
    }
 
 
4184
    {
 
 
4185
        int i = 0;
 
 
4186
        for (; i < 3; i++) 
 
 
4187
        {
 
 
4188
            VerticesBuffer[i].X = vertices[i+2].vx;
 
 
4189
            VerticesBuffer[i].Y = vertices[i+2].vy;
 
 
4190
            VerticesBuffer[i].Z = vertices[i+2].vz;
 
 
4191
 
 
 
4192
            VerticesBuffer[i].A = (particlePtr->Colour >> 24)&255;
 
 
4193
            VerticesBuffer[i].R = (particlePtr->Colour >> 16)&255;
 
 
4194
            VerticesBuffer[i].G = (particlePtr->Colour >> 8)&255;
 
 
4195
            VerticesBuffer[i].B = (particlePtr->Colour) & 255;
 
 
4196
        }
 
 
4197
 
 
 
4198
        RenderPolygon.NumberOfVertices = 3;
 
 
4199
        RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL;
 
 
4200
    }
 
 
4201
 
 
 
4202
    {
 
 
4203
        int outcode = TriangleWithinFrustrum();
 
 
4204
        POLYHEADER fakeHeader;
 
 
4205
        fakeHeader.PolyFlags  = iflag_transparent;
 
 
4206
 
 
 
4207
        do
 
 
4208
        {
 
 
4209
            if (outcode)
 
 
4210
            {
 
 
4211
                if(outcode != 2)
 
 
4212
                {
 
 
4213
                    GouraudPolygon_ClipWithZ();
 
 
4214
 
 
 
4215
                    if(RenderPolygon.NumberOfVertices < 3)
 
 
4216
                        continue;
 
 
4217
 
 
 
4218
                    GouraudPolygon_ClipWithNegativeX();
 
 
4219
 
 
 
4220
                    if(RenderPolygon.NumberOfVertices < 3)
 
 
4221
                        continue;
 
 
4222
 
 
 
4223
                    GouraudPolygon_ClipWithPositiveY();
 
 
4224
 
 
 
4225
                    if(RenderPolygon.NumberOfVertices < 3)
 
 
4226
                        continue;
 
 
4227
 
 
 
4228
                    GouraudPolygon_ClipWithNegativeY();
 
 
4229
 
 
 
4230
                    if(RenderPolygon.NumberOfVertices < 3)
 
 
4231
                        continue;
 
 
4232
 
 
 
4233
                    GouraudPolygon_ClipWithPositiveX();
 
 
4234
 
 
 
4235
                    if(RenderPolygon.NumberOfVertices < 3)
 
 
4236
                        continue;
 
 
4237
 
 
 
4238
                    ZBufferedGouraudPolygon_Output(&fakeHeader, RenderPolygon.Vertices);
 
 
4239
                }
 
 
4240
                else
 
 
4241
                {
 
 
4242
                    ZBufferedGouraudPolygon_Output(&fakeHeader, VerticesBuffer);
 
 
4243
                }
 
 
4244
            }
 
 
4245
 
 
 
4246
        } while(0);
 
 
4247
    }
 
 
4248
}
 
 
4249
 
 
 
4250
void OutputTranslucentPolyList()
 
 
4251
{
 
 
4252
    int i;
 
 
4253
    for (i = 0; i < CurrentNumberOfTranslucentPolygons; i++)
 
 
4254
    {
 
 
4255
        if(TranslucentPolygons[i].polygon_header.PolyFlags & iflag_glowing)
 
 
4256
        {
 
 
4257
            RenderPolygon.TranslucencyMode = TRANSLUCENCY_GLOWING;
 
 
4258
            TranslucentPolygons[i].polygon.Vertices->A = 250;
 
 
4259
        }
 
 
4260
        else
 
 
4261
        {
 
 
4262
            RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL;
 
 
4263
        }
 
 
4264
 
 
 
4265
        RenderPolygon.NumberOfVertices = TranslucentPolygons[i].polygon.NumberOfVertices;
 
 
4266
        ZBufferedGouraudTexturedPolygon_Output(&TranslucentPolygons[i].polygon_header, TranslucentPolygons[i].polygon.Vertices);
 
 
4267
    }
 
 
4268
}
 
 
4269
 
 
 
4270
static const int CuboidPolyVertexU[][4] =
 
 
4271
{
 
 
4272
    {1,1,1,1},
 
 
4273
 
 
 
4274
    {127,127,0,0},     
 
 
4275
    {128,128,255,255},     
 
 
4276
 
 
 
4277
    {127,127,0,0},     
 
 
4278
    {128,128,255,255},     
 
 
4279
};
 
 
4280
 
 
 
4281
static const int CuboidPolyVertexV[][4] =
 
 
4282
{
 
 
4283
    {1,1,1,1},    
 
 
4284
 
 
 
4285
    {127,0,0,127},         
 
 
4286
    {127,0,0,127},    
 
 
4287
    {128,255,255,128},    
 
 
4288
    {128,255,255,128},    
 
 
4289
};
 
 
4290
 
 
 
4291
void RenderMirrorSurface()
 
 
4292
{
 
 
4293
    VECTORCH translatedPts[4] =
 
 
4294
    {
 
 
4295
        {-5596,-932,-1872},
 
 
4296
        {-5596,-932,-702},
 
 
4297
        {-5596,1212,-702},
 
 
4298
        {-5596,1212,-1872},
 
 
4299
    };
 
 
4300
 
 
 
4301
     int mirrorUV[]= { 0,0, 127<<16,0, 127<<16,127<<16, 0,127<<16};
 
 
4302
 
 
 
4303
     POLYHEADER fakeHeader;
 
 
4304
 
 
 
4305
    fakeHeader.PolyFlags = iflag_transparent;
 
 
4306
    fakeHeader.PolyColour = CloudyImageNumber;
 
 
4307
 
 
 
4308
     {
 
 
4309
        int i=0;
 
 
4310
        for (; i < 4; i++) 
 
 
4311
        {
 
 
4312
            VerticesBuffer[i].A = 128;
 
 
4313
 
 
 
4314
            TranslatePointIntoViewspace(&translatedPts[i]);
 
 
4315
            VerticesBuffer[i].X    = translatedPts[i].vx;
 
 
4316
            VerticesBuffer[i].Y    = translatedPts[i].vy;
 
 
4317
            VerticesBuffer[i].Z    = translatedPts[i].vz;
 
 
4318
            VerticesBuffer[i].U = mirrorUV[i*2];
 
 
4319
            VerticesBuffer[i].V = mirrorUV[i*2+1];
 
 
4320
 
 
 
4321
            VerticesBuffer[i].R = 255;
 
 
4322
            VerticesBuffer[i].G    = 255;
 
 
4323
            VerticesBuffer[i].B = 255;
 
 
4324
            VerticesBuffer[i].SpecularR = 0;
 
 
4325
            VerticesBuffer[i].SpecularG = 0;
 
 
4326
            VerticesBuffer[i].SpecularB = 0;
 
 
4327
        }
 
 
4328
 
 
 
4329
        RenderPolygon.NumberOfVertices = 4;
 
 
4330
        RenderPolygon.TranslucencyMode = TRANSLUCENCY_COLOUR;
 
 
4331
    }
 
 
4332
 
 
 
4333
    GouraudTexturedPolygon_ClipWithZ();
 
 
4334
 
 
 
4335
    if(RenderPolygon.NumberOfVertices < 3)
 
 
4336
        return;
 
 
4337
 
 
 
4338
    GouraudTexturedPolygon_ClipWithNegativeX();
 
 
4339
 
 
 
4340
    if(RenderPolygon.NumberOfVertices < 3)
 
 
4341
        return;
 
 
4342
 
 
 
4343
    GouraudTexturedPolygon_ClipWithPositiveY();
 
 
4344
 
 
 
4345
    if(RenderPolygon.NumberOfVertices < 3)
 
 
4346
        return;
 
 
4347
 
 
 
4348
    GouraudTexturedPolygon_ClipWithNegativeY();
 
 
4349
 
 
 
4350
    if(RenderPolygon.NumberOfVertices < 3)
 
 
4351
        return;
 
 
4352
 
 
 
4353
    GouraudTexturedPolygon_ClipWithPositiveX();
 
 
4354
 
 
 
4355
    if(RenderPolygon.NumberOfVertices < 3)
 
 
4356
        return;
 
 
4357
 
 
 
4358
    ZBufferedGouraudTexturedPolygon_Output(&fakeHeader, RenderPolygon.Vertices);
 
 
4359
}
 
 
4360
 
 
 
4361
void RenderMirrorSurface2()
 
 
4362
{
 
 
4363
    VECTORCH translatedPts[4] =
 
 
4364
    {
 
 
4365
        {-5596,-592,562},
 
 
4366
        {-5596,-592,1344},
 
 
4367
        {-5596,140,1344},
 
 
4368
        {-5596,140,562},
 
 
4369
 
 
 
4370
    };
 
 
4371
 
 
 
4372
     int mirrorUV[]= { 0,0, 127<<16,0, 127<<16,127<<16, 0,127<<16};
 
 
4373
 
 
 
4374
     POLYHEADER fakeHeader;
 
 
4375
 
 
 
4376
    fakeHeader.PolyFlags = iflag_transparent;
 
 
4377
    fakeHeader.PolyColour = CloudyImageNumber;
 
 
4378
 
 
 
4379
     {
 
 
4380
        int i=0;
 
 
4381
        for (; i < 4; i++) 
 
 
4382
        {
 
 
4383
            VerticesBuffer[i].A = 128;
 
 
4384
 
 
 
4385
            TranslatePointIntoViewspace(&translatedPts[i]);
 
 
4386
            VerticesBuffer[i].X    = translatedPts[i].vx;
 
 
4387
            VerticesBuffer[i].Y    = translatedPts[i].vy;
 
 
4388
            VerticesBuffer[i].Z    = translatedPts[i].vz;
 
 
4389
            VerticesBuffer[i].U = mirrorUV[i*2];
 
 
4390
            VerticesBuffer[i].V = mirrorUV[i*2+1];
 
 
4391
 
 
 
4392
            VerticesBuffer[i].R = 255;
 
 
4393
            VerticesBuffer[i].G    = 255;
 
 
4394
            VerticesBuffer[i].B = 255;
 
 
4395
            VerticesBuffer[i].SpecularR = 0;
 
 
4396
            VerticesBuffer[i].SpecularG = 0;
 
 
4397
            VerticesBuffer[i].SpecularB = 0;
 
 
4398
        }
 
 
4399
 
 
 
4400
        RenderPolygon.NumberOfVertices = 4;
 
 
4401
        RenderPolygon.TranslucencyMode = TRANSLUCENCY_COLOUR;
 
 
4402
    }
 
 
4403
 
 
 
4404
    GouraudTexturedPolygon_ClipWithZ();
 
 
4405
 
 
 
4406
    if(RenderPolygon.NumberOfVertices < 3)
 
 
4407
        return;
 
 
4408
 
 
 
4409
    GouraudTexturedPolygon_ClipWithNegativeX();
 
 
4410
 
 
 
4411
    if(RenderPolygon.NumberOfVertices < 3)
 
 
4412
        return;
 
 
4413
 
 
 
4414
    GouraudTexturedPolygon_ClipWithPositiveY();
 
 
4415
 
 
 
4416
    if(RenderPolygon.NumberOfVertices < 3)
 
 
4417
        return;
 
 
4418
 
 
 
4419
    GouraudTexturedPolygon_ClipWithNegativeY();
 
 
4420
 
 
 
4421
    if(RenderPolygon.NumberOfVertices < 3)
 
 
4422
        return;
 
 
4423
 
 
 
4424
    GouraudTexturedPolygon_ClipWithPositiveX();
 
 
4425
 
 
 
4426
    if(RenderPolygon.NumberOfVertices < 3)
 
 
4427
        return;
 
 
4428
 
 
 
4429
    ZBufferedGouraudTexturedPolygon_Output(&fakeHeader, RenderPolygon.Vertices);
 
 
4430
}
 
 
4431
 
 
 
4432
#define OCTAVES 3
 
 
4433
int u[OCTAVES];
 
 
4434
int v[OCTAVES];
 
 
4435
int du[OCTAVES];
 
 
4436
int dv[OCTAVES];
 
 
4437
 
 
 
4438
int SkyColour_R = 200;
 
 
4439
int SkyColour_G = 200;
 
 
4440
int SkyColour_B = 200;
 
 
4441
 
 
 
4442
void init_sky()
 
 
4443
{
 
 
4444
    int i = 0;
 
 
4445
    for(; i < OCTAVES; i++)
 
 
4446
    {
 
 
4447
        u[i] = (FastRandom() & 65535)*128;
 
 
4448
        v[i] = (FastRandom() & 65535)*128;
 
 
4449
        du[i] = ( ((FastRandom() & 65535)-32768) * (i+1) )*8;
 
 
4450
        dv[i] = ( ((FastRandom() & 65535)-32768) * (i+1) )*8;
 
 
4451
    }
 
 
4452
}
 
 
4453
 
 
 
4454
void RenderSky()
 
 
4455
{
 
 
4456
    int x = -10;
 
 
4457
    RenderPolygon.TranslucencyMode = TRANSLUCENCY_GLOWING;
 
 
4458
 
 
 
4459
    {
 
 
4460
        int i=0;
 
 
4461
        for (; i < OCTAVES; i++)
 
 
4462
        {
 
 
4463
            u[i] += MUL_FIXED(du[i], NormalFrameTime);
 
 
4464
            v[i] += MUL_FIXED(dv[i], NormalFrameTime);
 
 
4465
        }
 
 
4466
    }
 
 
4467
 
 
 
4468
    for(; x <= 10; x++)
 
 
4469
    {
 
 
4470
        int z = -10;
 
 
4471
        for(; z <= 10; z++)
 
 
4472
        {
 
 
4473
            int t = 255;
 
 
4474
            int size = 65536*128;
 
 
4475
            int o = 0;
 
 
4476
 
 
 
4477
            for (o=0; o < OCTAVES; o++)
 
 
4478
            {
 
 
4479
                {
 
 
4480
                   VECTORCH translatedPts[4] =
 
 
4481
                    {
 
 
4482
                        {-1024,-1000,-1024},
 
 
4483
                        {-1024,-1000, 1024},
 
 
4484
                        { 1024,-1000, 1024},
 
 
4485
                        { 1024,-1000,-1024},
 
 
4486
 
 
 
4487
                    };            
 
 
4488
 
 
 
4489
                    int i = 0;
 
 
4490
                    for (; i < 4; i++) 
 
 
4491
                    {
 
 
4492
                        VerticesBuffer[i].A = t;
 
 
4493
                        translatedPts[i].vx += 2048*x;//+(Global_VDB.VDB_World.vx*7)/8;
 
 
4494
                        translatedPts[i].vz += 2048*z;//+(Global_VDB.VDB_World.vz*7)/8;
 
 
4495
 
 
 
4496
        //                RotateVector(&translatedPts[i],&(Global_VDB.VDB_Mat));
 
 
4497
 
 
 
4498
        //                translatedPts[i].vy = MUL_FIXED(translatedPts[i].vy,87381);
 
 
4499
                        translatedPts[i].vx += Global_VDB.VDB_World.vx;
 
 
4500
                        translatedPts[i].vy += Global_VDB.VDB_World.vy;
 
 
4501
                        translatedPts[i].vz += Global_VDB.VDB_World.vz;
 
 
4502
                        TranslatePointIntoViewspace(&translatedPts[i]);
 
 
4503
 
 
 
4504
                        VerticesBuffer[i].X = translatedPts[i].vx;
 
 
4505
                        VerticesBuffer[i].Y = translatedPts[i].vy;
 
 
4506
                        VerticesBuffer[i].Z = translatedPts[i].vz;
 
 
4507
 
 
 
4508
                        switch (PlayerStatus.VisionMode)
 
 
4509
                        {
 
 
4510
                            default:
 
 
4511
                            case VISION_MODE_NORMAL:
 
 
4512
                            {
 
 
4513
                                VerticesBuffer[i].R = SkyColour_R;
 
 
4514
                                VerticesBuffer[i].G = SkyColour_G;
 
 
4515
                                VerticesBuffer[i].B = SkyColour_B;
 
 
4516
                            break;
 
 
4517
                            }
 
 
4518
                            case VISION_MODE_IMAGEINTENSIFIER:
 
 
4519
                            {
 
 
4520
                                VerticesBuffer[i].R = 0;
 
 
4521
                                VerticesBuffer[i].G = 255;
 
 
4522
                                VerticesBuffer[i].B = 0;
 
 
4523
                            break;
 
 
4524
                            }
 
 
4525
                            case VISION_MODE_PRED_THERMAL:
 
 
4526
                            case VISION_MODE_PRED_SEEALIENS:
 
 
4527
                            case VISION_MODE_PRED_SEEPREDTECH:
 
 
4528
                            {
 
 
4529
                                VerticesBuffer[i].R = 0;
 
 
4530
                                VerticesBuffer[i].G = 0;
 
 
4531
                                VerticesBuffer[i].B = 255;
 
 
4532
                            break;
 
 
4533
                            }
 
 
4534
                        }
 
 
4535
                    }
 
 
4536
 
 
 
4537
                    VerticesBuffer[0].U = (u[o]+size*x);
 
 
4538
                    VerticesBuffer[0].V = (v[o]+size*z);
 
 
4539
                    VerticesBuffer[1].U = (u[o]+size*x);
 
 
4540
                    VerticesBuffer[1].V = (v[o]+size*(z+1));
 
 
4541
                    VerticesBuffer[2].U = (u[o]+size*(x+1));
 
 
4542
                    VerticesBuffer[2].V = (v[o]+size*(z+1));
 
 
4543
                    VerticesBuffer[3].U = (u[o]+size*(x+1));
 
 
4544
                    VerticesBuffer[3].V = (v[o]+size*z);
 
 
4545
 
 
 
4546
                    RenderPolygon.NumberOfVertices = 4;
 
 
4547
                }
 
 
4548
 
 
 
4549
                GouraudTexturedPolygon_ClipWithZ();
 
 
4550
 
 
 
4551
                if(RenderPolygon.NumberOfVertices >= 3)
 
 
4552
                {
 
 
4553
                    GouraudTexturedPolygon_ClipWithNegativeX();
 
 
4554
 
 
 
4555
                    if(RenderPolygon.NumberOfVertices >= 3)
 
 
4556
                    {
 
 
4557
                        GouraudTexturedPolygon_ClipWithPositiveY();
 
 
4558
 
 
 
4559
                        if(RenderPolygon.NumberOfVertices >= 3)
 
 
4560
                        {
 
 
4561
                            GouraudTexturedPolygon_ClipWithNegativeY();
 
 
4562
 
 
 
4563
                            if(RenderPolygon.NumberOfVertices >= 3)
 
 
4564
                            {
 
 
4565
                                GouraudTexturedPolygon_ClipWithPositiveX();
 
 
4566
 
 
 
4567
                                if(RenderPolygon.NumberOfVertices >= 3)
 
 
4568
                                    SkyPolygon_Output(RenderPolygon.Vertices);
 
 
4569
                            }
 
 
4570
                        }
 
 
4571
                    }
 
 
4572
                }
 
 
4573
            t /= 2;
 
 
4574
            size *= 2;
 
 
4575
            }
 
 
4576
        }
 
 
4577
    }
 
 
4578
}
 
 
4579
 
 
 
4580
void DrawWaterFallPoly(VECTORCH *v)
 
 
4581
{
 
 
4582
       POLYHEADER fakeHeader;
 
 
4583
 
 
 
4584
    fakeHeader.PolyFlags = iflag_transparent;
 
 
4585
    fakeHeader.PolyColour = CloudyImageNumber;
 
 
4586
    RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL;
 
 
4587
 
 
 
4588
    {
 
 
4589
        static int wv = 0;
 
 
4590
        unsigned int a = 0;
 
 
4591
 
 
 
4592
        for (; a < 4; a++) 
 
 
4593
        {
 
 
4594
            VerticesBuffer[a].A = 128;
 
 
4595
            VerticesBuffer[a].U = (v[a].vz)<<11;
 
 
4596
            VerticesBuffer[a].V = (v[a].vy<<10)-wv;
 
 
4597
 
 
 
4598
            TranslatePointIntoViewspace(&v[a]);
 
 
4599
            VerticesBuffer[a].X    = v[a].vx;
 
 
4600
            VerticesBuffer[a].Y    = v[a].vy;
 
 
4601
            VerticesBuffer[a].Z    = v[a].vz;
 
 
4602
            VerticesBuffer[a].R = 200;
 
 
4603
            VerticesBuffer[a].G    = 200;
 
 
4604
            VerticesBuffer[a].B = 255;
 
 
4605
            VerticesBuffer[a].SpecularR = 0;
 
 
4606
            VerticesBuffer[a].SpecularG = 0;
 
 
4607
            VerticesBuffer[a].SpecularB = 0;
 
 
4608
        }    
 
 
4609
 
 
 
4610
        wv += NormalFrameTime * 2;
 
 
4611
        RenderPolygon.NumberOfVertices = 4;
 
 
4612
    }
 
 
4613
 
 
 
4614
    GouraudTexturedPolygon_ClipWithZ();
 
 
4615
 
 
 
4616
    if(RenderPolygon.NumberOfVertices >= 3)
 
 
4617
    {
 
 
4618
        GouraudTexturedPolygon_ClipWithNegativeX();
 
 
4619
 
 
 
4620
        if(RenderPolygon.NumberOfVertices >= 3)
 
 
4621
        {
 
 
4622
            GouraudTexturedPolygon_ClipWithPositiveY();
 
 
4623
 
 
 
4624
            if(RenderPolygon.NumberOfVertices >= 3)
 
 
4625
            {
 
 
4626
                GouraudTexturedPolygon_ClipWithNegativeY();
 
 
4627
 
 
 
4628
                if(RenderPolygon.NumberOfVertices >= 3)
 
 
4629
                {
 
 
4630
                    GouraudTexturedPolygon_ClipWithPositiveX();
 
 
4631
 
 
 
4632
                    if(RenderPolygon.NumberOfVertices >= 3)
 
 
4633
                        ZBufferedGouraudTexturedPolygon_Output(&fakeHeader, RenderPolygon.Vertices);
 
 
4634
                }
 
 
4635
            }
 
 
4636
        }
 
 
4637
    }
 
 
4638
}
 
 
4639
 
 
 
4640
void RenderWaterFall(int xOrigin, int yOrigin, int zOrigin)
 
 
4641
{
 
 
4642
    int i,z;
 
 
4643
    VECTORCH v[4];
 
 
4644
 
 
 
4645
    {
 
 
4646
        int waterfallX[9];
 
 
4647
        int waterfallY[9];
 
 
4648
        int waterfallZ[9];
 
 
4649
        int waterfallZScale[9];
 
 
4650
 
 
 
4651
        for (i=0; i < 9; i++)
 
 
4652
        {
 
 
4653
            int u = (i*65536)/8;
 
 
4654
 
 
 
4655
            int b = MUL_FIXED(2*u,(65536-u));
 
 
4656
            int c = MUL_FIXED(u,u);
 
 
4657
            int y3 = (4742-yOrigin);
 
 
4658
            int x3 = 2000;
 
 
4659
            int y2 = 2000;
 
 
4660
            int x2 = 1500;
 
 
4661
 
 
 
4662
            waterfallX[i] = MUL_FIXED(b,x2)+MUL_FIXED(c,x3);
 
 
4663
            waterfallY[i] = yOrigin+MUL_FIXED(b,y2)+MUL_FIXED(c,y3);
 
 
4664
             waterfallZ[i] = zOrigin+MUL_FIXED((66572-zOrigin),u);
 
 
4665
            waterfallZScale[i] = ONE_FIXED+b/2-c;
 
 
4666
 
 
 
4667
            if (i != 8)
 
 
4668
            {
 
 
4669
                waterfallZScale[i]+=(FastRandom()&8191);
 
 
4670
                waterfallY[i]-=(FastRandom()&127);
 
 
4671
            }
 
 
4672
        }
 
 
4673
 
 
 
4674
        for (z=0; z<8; z++)
 
 
4675
        for (i=0; i<8; i++)
 
 
4676
        {
 
 
4677
            v[0].vx = xOrigin+MUL_FIXED(waterfallX[i],waterfallZScale[z]);
 
 
4678
            v[1].vx = xOrigin+MUL_FIXED(waterfallX[i],waterfallZScale[z+1]);
 
 
4679
            v[2].vx = xOrigin+MUL_FIXED(waterfallX[i+1],waterfallZScale[z+1]);
 
 
4680
            v[3].vx = xOrigin+MUL_FIXED(waterfallX[i+1],waterfallZScale[z]);
 
 
4681
            v[0].vy = waterfallY[i];
 
 
4682
            v[1].vy = waterfallY[i];
 
 
4683
            v[2].vy = waterfallY[i+1];
 
 
4684
            v[3].vy = waterfallY[i+1];
 
 
4685
 
 
 
4686
             v[0].vz = waterfallZ[z];
 
 
4687
            v[1].vz = waterfallZ[z+1];
 
 
4688
            v[2].vz = v[1].vz;
 
 
4689
            v[3].vz = v[0].vz;
 
 
4690
 
 
 
4691
            DrawWaterFallPoly(v);
 
 
4692
        }
 
 
4693
 
 
 
4694
        for (z=0; z<3; z++)
 
 
4695
        {
 
 
4696
            v[0].vx = xOrigin+MUL_FIXED(waterfallX[8],waterfallZScale[z+1]);
 
 
4697
            v[1].vx = xOrigin+MUL_FIXED(waterfallX[8],waterfallZScale[z]);
 
 
4698
            v[2].vx = 179450;
 
 
4699
            v[3].vx = 179450;
 
 
4700
 
 
 
4701
            v[0].vy = 4742;
 
 
4702
            v[1].vy = 4742;
 
 
4703
            v[2].vy = 4742;
 
 
4704
            v[3].vy = 4742;
 
 
4705
 
 
 
4706
             v[0].vz = waterfallZ[z];
 
 
4707
            v[1].vz = waterfallZ[z+1];
 
 
4708
            v[2].vz = v[1].vz;
 
 
4709
            v[3].vz = v[0].vz;
 
 
4710
 
 
 
4711
            DrawWaterFallPoly(v);
 
 
4712
        }
 
 
4713
 
 
 
4714
        for (z=0; z<8; z++)
 
 
4715
        for (i=0; i<16; i++)
 
 
4716
        {
 
 
4717
            int xOffset,xOffset2;
 
 
4718
 
 
 
4719
            if (z < 3)
 
 
4720
                xOffset = 179450;
 
 
4721
            else
 
 
4722
                xOffset = xOrigin+MUL_FIXED(waterfallX[8],waterfallZScale[z]);
 
 
4723
 
 
 
4724
            if (z < 2)
 
 
4725
                xOffset2 = 179450;
 
 
4726
            else
 
 
4727
                xOffset2 = xOrigin+MUL_FIXED(waterfallX[8],waterfallZScale[z+1]);
 
 
4728
 
 
 
4729
            v[0].vx = xOffset;
 
 
4730
            v[1].vx = xOffset2;
 
 
4731
            v[2].vx = xOffset2;
 
 
4732
            v[3].vx = xOffset;
 
 
4733
 
 
 
4734
            v[0].vy = 4742+i*4096;
 
 
4735
            v[1].vy = 4742+i*4096;
 
 
4736
            v[2].vy = 4742+(i+1)*4096;
 
 
4737
            v[3].vy = 4742+(i+1)*4096;
 
 
4738
 
 
 
4739
             v[0].vz = waterfallZ[z];
 
 
4740
            v[1].vz = waterfallZ[z+1];
 
 
4741
            v[2].vz = v[1].vz;
 
 
4742
            v[3].vz = v[0].vz;
 
 
4743
 
 
 
4744
            DrawWaterFallPoly(v);
 
 
4745
        }
 
 
4746
    }
 
 
4747
}
 
 
4748
 
 
 
4749
void RenderPredatorTargetingSegment(int theta, int scale, int drawInRed)
 
 
4750
{
 
 
4751
    VECTOR2D offset[4];
 
 
4752
     POLYHEADER fakeHeader;
 
 
4753
    int centreX,centreY;
 
 
4754
    int z = ONE_FIXED - scale;
 
 
4755
    z = MUL_FIXED(MUL_FIXED(z, z), 2048);
 
 
4756
 
 
 
4757
    {
 
 
4758
        extern int SmartTargetSightX, SmartTargetSightY;
 
 
4759
        centreY = MUL_FIXED( (SmartTargetSightY-(ScreenDescriptorBlock.SDB_Height<<15)) / Global_VDB.VDB_ProjY,z);
 
 
4760
 
 
 
4761
        centreX = (CHEATMODE_MIRROR == UserProfile.active_bonus) ?
 
 
4762
            MUL_FIXED((-(SmartTargetSightX-(ScreenDescriptorBlock.SDB_Width<<15)))  / Global_VDB.VDB_ProjX,z) :
 
 
4763
            MUL_FIXED(( SmartTargetSightX-(ScreenDescriptorBlock.SDB_Width<<15))  / Global_VDB.VDB_ProjX,z);
 
 
4764
    }
 
 
4765
 
 
 
4766
    z = (float)z * CameraZoomScale;
 
 
4767
 
 
 
4768
    {
 
 
4769
        int a = 160;
 
 
4770
        int b = 40;
 
 
4771
 
 
 
4772
        /* tan(30) = 1/sqrt(3), & 65536/(sqrt(3)) = 37837 */
 
 
4773
 
 
 
4774
        int y = MUL_FIXED(37837,a+20);
 
 
4775
 
 
 
4776
        offset[0].vx = -a+MUL_FIXED(113512,b);
 
 
4777
        offset[0].vy = y-b;
 
 
4778
 
 
 
4779
        offset[1].vx = -offset[0].vx;
 
 
4780
        offset[1].vy = y-b;
 
 
4781
 
 
 
4782
        offset[2].vx = a;
 
 
4783
        offset[2].vy = y;
 
 
4784
 
 
 
4785
        offset[3].vx = -a;
 
 
4786
        offset[3].vy = y;
 
 
4787
 
 
 
4788
        if (theta)
 
 
4789
        {
 
 
4790
            RotateVertex(&offset[0],theta);
 
 
4791
            RotateVertex(&offset[1],theta);
 
 
4792
            RotateVertex(&offset[2],theta);
 
 
4793
            RotateVertex(&offset[3],theta);
 
 
4794
        }
 
 
4795
 
 
 
4796
        if (CHEATMODE_MIRROR == UserProfile.active_bonus)
 
 
4797
        {
 
 
4798
            offset[0].vx = -offset[0].vx;
 
 
4799
            offset[1].vx = -offset[1].vx;
 
 
4800
            offset[2].vx = -offset[2].vx;
 
 
4801
            offset[3].vx = -offset[3].vx;
 
 
4802
        }
 
 
4803
 
 
 
4804
        VerticesBuffer[0].X = offset[0].vx+centreX;
 
 
4805
        VerticesBuffer[0].Y = MUL_FIXED(offset[0].vy,87381)+centreY;
 
 
4806
 
 
 
4807
        VerticesBuffer[1].X = offset[1].vx+centreX;
 
 
4808
        VerticesBuffer[1].Y = MUL_FIXED(offset[1].vy,87381)+centreY;
 
 
4809
 
 
 
4810
        VerticesBuffer[2].X = offset[2].vx+centreX;
 
 
4811
        VerticesBuffer[2].Y = MUL_FIXED(offset[2].vy,87381)+centreY;
 
 
4812
 
 
 
4813
        VerticesBuffer[3].X = offset[3].vx+centreX;
 
 
4814
        VerticesBuffer[3].Y = MUL_FIXED(offset[3].vy,87381)+centreY;
 
 
4815
    }
 
 
4816
 
 
 
4817
    fakeHeader.PolyFlags = iflag_transparent;
 
 
4818
    RenderPolygon.TranslucencyMode = TRANSLUCENCY_GLOWING;
 
 
4819
 
 
 
4820
     {
 
 
4821
        int i=0;
 
 
4822
        for (; i < 4; i++) 
 
 
4823
        {
 
 
4824
            VerticesBuffer[i].A = 128;
 
 
4825
            VerticesBuffer[i].Z = z;
 
 
4826
            VerticesBuffer[i].R = 255;
 
 
4827
            VerticesBuffer[i].G = VerticesBuffer[i].B = drawInRed ? 0 : 255;
 
 
4828
        }
 
 
4829
 
 
 
4830
        RenderPolygon.NumberOfVertices = 4;
 
 
4831
    }
 
 
4832
 
 
 
4833
    GouraudPolygon_ClipWithZ();
 
 
4834
 
 
 
4835
    if(RenderPolygon.NumberOfVertices < 3)
 
 
4836
        return;
 
 
4837
 
 
 
4838
    GouraudPolygon_ClipWithNegativeX();
 
 
4839
 
 
 
4840
    if(RenderPolygon.NumberOfVertices < 3)
 
 
4841
        return;
 
 
4842
 
 
 
4843
    GouraudPolygon_ClipWithPositiveY();
 
 
4844
 
 
 
4845
    if(RenderPolygon.NumberOfVertices < 3)
 
 
4846
        return;
 
 
4847
 
 
 
4848
    GouraudPolygon_ClipWithNegativeY();
 
 
4849
 
 
 
4850
    if(RenderPolygon.NumberOfVertices < 3)
 
 
4851
        return;
 
 
4852
 
 
 
4853
    GouraudPolygon_ClipWithPositiveX();
 
 
4854
 
 
 
4855
    if(RenderPolygon.NumberOfVertices < 3)
 
 
4856
        return;
 
 
4857
 
 
 
4858
    ZBufferedGouraudPolygon_Output(&fakeHeader, RenderPolygon.Vertices);
 
 
4859
 
 
 
4860
    if (drawInRed)
 
 
4861
    {
 
 
4862
        VerticesBuffer[0].X = MUL_FIXED(offset[3].vx,scale*8)+centreX;
 
 
4863
        VerticesBuffer[0].Y = MUL_FIXED(MUL_FIXED(offset[3].vy,scale*8),87381)+centreY;
 
 
4864
 
 
 
4865
        VerticesBuffer[1].X = MUL_FIXED(offset[2].vx,scale*8)+centreX;
 
 
4866
        VerticesBuffer[1].Y = MUL_FIXED(MUL_FIXED(offset[2].vy,scale*8),87381)+centreY;
 
 
4867
 
 
 
4868
        VerticesBuffer[2].X = offset[2].vx+centreX;
 
 
4869
        VerticesBuffer[2].Y = MUL_FIXED(offset[2].vy,87381)+centreY;
 
 
4870
 
 
 
4871
        VerticesBuffer[3].X = offset[3].vx+centreX;
 
 
4872
        VerticesBuffer[3].Y = MUL_FIXED(offset[3].vy,87381)+centreY;
 
 
4873
 
 
 
4874
         {
 
 
4875
            int i=0;
 
 
4876
            for (; i < 2; i++) 
 
 
4877
            {
 
 
4878
                VerticesBuffer[i].A = 0;
 
 
4879
                VerticesBuffer[i].Z = z;
 
 
4880
                VerticesBuffer[i].R = 255;
 
 
4881
                VerticesBuffer[i].G = 0;
 
 
4882
                VerticesBuffer[i].B = 0;
 
 
4883
            }
 
 
4884
 
 
 
4885
            for (i=2; i < 4; i++) 
 
 
4886
            {
 
 
4887
                VerticesBuffer[i].A = 128;
 
 
4888
                VerticesBuffer[i].Z = z;
 
 
4889
                VerticesBuffer[i].R = 255;
 
 
4890
                VerticesBuffer[i].G = 0;
 
 
4891
                VerticesBuffer[i].B = 0;
 
 
4892
            }
 
 
4893
 
 
 
4894
            RenderPolygon.NumberOfVertices = 4;
 
 
4895
        }
 
 
4896
 
 
 
4897
        GouraudPolygon_ClipWithZ();
 
 
4898
 
 
 
4899
        if(RenderPolygon.NumberOfVertices < 3)
 
 
4900
            return;
 
 
4901
 
 
 
4902
        GouraudPolygon_ClipWithNegativeX();
 
 
4903
 
 
 
4904
        if(RenderPolygon.NumberOfVertices < 3)
 
 
4905
            return;
 
 
4906
 
 
 
4907
        GouraudPolygon_ClipWithPositiveY();
 
 
4908
 
 
 
4909
        if(RenderPolygon.NumberOfVertices < 3)
 
 
4910
            return;
 
 
4911
 
 
 
4912
        GouraudPolygon_ClipWithNegativeY();
 
 
4913
 
 
 
4914
        if(RenderPolygon.NumberOfVertices < 3)
 
 
4915
            return;
 
 
4916
 
 
 
4917
        GouraudPolygon_ClipWithPositiveX();
 
 
4918
 
 
 
4919
        if(RenderPolygon.NumberOfVertices < 3)
 
 
4920
            return;
 
 
4921
 
 
 
4922
        ZBufferedGouraudPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
 
 
4923
    }
 
 
4924
}
 
 
4925
 
 
 
4926
void RenderPredatorPlasmaCasterCharge(int value, VECTORCH *worldOffsetPtr, MATRIXCH *orientationPtr)
 
 
4927
{
 
 
4928
     POLYHEADER fakeHeader;
 
 
4929
     VECTORCH translatedPts[4];
 
 
4930
    int halfWidth = 100;
 
 
4931
    int halfHeight = 4;
 
 
4932
    int z = -1;
 
 
4933
 
 
 
4934
    translatedPts[0].vx = -halfWidth;
 
 
4935
    translatedPts[0].vy = z;
 
 
4936
    translatedPts[0].vz = -halfHeight-4;
 
 
4937
 
 
 
4938
    translatedPts[1].vx = -halfWidth+MUL_FIXED(value,2*halfWidth-10);
 
 
4939
    translatedPts[1].vy = z;
 
 
4940
    translatedPts[1].vz = -halfHeight-4;
 
 
4941
 
 
 
4942
    translatedPts[2].vx = -halfWidth+MUL_FIXED(value,2*halfWidth-10);
 
 
4943
    translatedPts[2].vy = z;
 
 
4944
    translatedPts[2].vz = halfHeight-4;
 
 
4945
 
 
 
4946
    translatedPts[3].vx = -halfWidth;
 
 
4947
    translatedPts[3].vy = z;
 
 
4948
    translatedPts[3].vz = halfHeight-4;
 
 
4949
 
 
 
4950
    fakeHeader.PolyFlags = iflag_transparent;
 
 
4951
    RenderPolygon.TranslucencyMode = TRANSLUCENCY_GLOWING;
 
 
4952
 
 
 
4953
    {
 
 
4954
        int i=0;
 
 
4955
        for (; i < 4; i++) 
 
 
4956
        {
 
 
4957
            VerticesBuffer[i].A = 255;
 
 
4958
 
 
 
4959
            RotateVector(&(translatedPts[i]),orientationPtr);
 
 
4960
            translatedPts[i].vx += worldOffsetPtr->vx;
 
 
4961
            translatedPts[i].vy += worldOffsetPtr->vy;
 
 
4962
            translatedPts[i].vz += worldOffsetPtr->vz;
 
 
4963
            TranslatePointIntoViewspace(&translatedPts[i]);
 
 
4964
 
 
 
4965
            VerticesBuffer[i].X    = translatedPts[i].vx;
 
 
4966
            VerticesBuffer[i].Y    = translatedPts[i].vy;
 
 
4967
            VerticesBuffer[i].Z    = translatedPts[i].vz;
 
 
4968
 
 
 
4969
            VerticesBuffer[i].R = 32;
 
 
4970
            VerticesBuffer[i].G = 0;
 
 
4971
            VerticesBuffer[i].B = 0;
 
 
4972
        }
 
 
4973
 
 
 
4974
        RenderPolygon.NumberOfVertices = 4;
 
 
4975
    }
 
 
4976
 
 
 
4977
    {
 
 
4978
        int outcode = QuadWithinFrustrum();
 
 
4979
 
 
 
4980
        if (outcode)
 
 
4981
        {
 
 
4982
            if (outcode != 2)
 
 
4983
            {
 
 
4984
                GouraudPolygon_ClipWithZ();
 
 
4985
 
 
 
4986
                if(RenderPolygon.NumberOfVertices < 3)
 
 
4987
                    return;
 
 
4988
 
 
 
4989
                GouraudPolygon_ClipWithNegativeX();
 
 
4990
 
 
 
4991
                if(RenderPolygon.NumberOfVertices < 3)
 
 
4992
                    return;
 
 
4993
 
 
 
4994
                GouraudPolygon_ClipWithPositiveY();
 
 
4995
 
 
 
4996
                if(RenderPolygon.NumberOfVertices < 3)
 
 
4997
                    return;
 
 
4998
 
 
 
4999
                GouraudPolygon_ClipWithNegativeY();
 
 
5000
 
 
 
5001
                if(RenderPolygon.NumberOfVertices < 3) 
 
 
5002
                    return;
 
 
5003
 
 
 
5004
                GouraudPolygon_ClipWithPositiveX();
 
 
5005
 
 
 
5006
                if(RenderPolygon.NumberOfVertices < 3)
 
 
5007
                    return;
 
 
5008
 
 
 
5009
                ZBufferedGouraudPolygon_Output(&fakeHeader,RenderPolygon.Vertices);
 
 
5010
              }
 
 
5011
            else
 
 
5012
            {
 
 
5013
                ZBufferedGouraudPolygon_Output(&fakeHeader,VerticesBuffer);
 
 
5014
            }
 
 
5015
        }
 
 
5016
    }
 
 
5017
}
 
 
5018
 
 
 
5019
void RenderLightFlare(VECTORCH *positionPtr, unsigned int colour)
 
 
5020
{
 
 
5021
    PARTICLE particle;
 
 
5022
    VECTORCH point = *positionPtr;
 
 
5023
 
 
 
5024
    TranslatePointIntoViewspace(&point);
 
 
5025
 
 
 
5026
    if(point.vz < 64)
 
 
5027
    return;    
 
 
5028
 
 
 
5029
    particle.ParticleID = PARTICLE_LIGHTFLARE;
 
 
5030
    particle.Colour = colour;
 
 
5031
    //printf("render fn %d %d %d\n", positionPtr->vx, positionPtr->vy, positionPtr->vz);
 
 
5032
 
 
 
5033
    {
 
 
5034
        int centreX = DIV_FIXED(point.vx, point.vz);
 
 
5035
        int centreY = DIV_FIXED(point.vy, point.vz);
 
 
5036
        int sizeX = (ScreenDescriptorBlock.SDB_Width << 13) / Global_VDB.VDB_ProjX;
 
 
5037
        int sizeY = MUL_FIXED(ScreenDescriptorBlock.SDB_Height << 13, 87381) / Global_VDB.VDB_ProjY;
 
 
5038
        int z = ONE_FIXED;
 
 
5039
 
 
 
5040
        VerticesBuffer[0].X = centreX - sizeX;
 
 
5041
        VerticesBuffer[0].Y = centreY - sizeY;
 
 
5042
        VerticesBuffer[0].Z = z;
 
 
5043
        VerticesBuffer[1].X = centreX + sizeX;
 
 
5044
        VerticesBuffer[1].Y = centreY - sizeY;
 
 
5045
        VerticesBuffer[1].Z = z;
 
 
5046
        VerticesBuffer[2].X = centreX + sizeX;
 
 
5047
        VerticesBuffer[2].Y = centreY + sizeY;
 
 
5048
        VerticesBuffer[2].Z = z;
 
 
5049
        VerticesBuffer[3].X = centreX - sizeX;
 
 
5050
        VerticesBuffer[3].Y = centreY + sizeY;
 
 
5051
        VerticesBuffer[3].Z = z;
 
 
5052
    }
 
 
5053
 
 
 
5054
    {
 
 
5055
        int outcode = QuadWithinFrustrum();
 
 
5056
 
 
 
5057
        if (outcode)
 
 
5058
        {
 
 
5059
            RenderPolygon.NumberOfVertices = 4;
 
 
5060
 
 
 
5061
            //printf("On Screen!\n");
 
 
5062
            VerticesBuffer[0].U = 192 << 16;
 
 
5063
            VerticesBuffer[0].V = 0;
 
 
5064
 
 
 
5065
            VerticesBuffer[1].U = 255 << 16;
 
 
5066
            VerticesBuffer[1].V = 0;
 
 
5067
 
 
 
5068
            VerticesBuffer[2].U = 255 << 16;
 
 
5069
            VerticesBuffer[2].V = 63 << 16;
 
 
5070
 
 
 
5071
            VerticesBuffer[3].U = 192 << 16;
 
 
5072
            VerticesBuffer[3].V = 63 << 16;
 
 
5073
 
 
 
5074
            if (outcode != 2)
 
 
5075
            {
 
 
5076
                TexturedPolygon_ClipWithZ();
 
 
5077
 
 
 
5078
                if(RenderPolygon.NumberOfVertices < 3)
 
 
5079
                    return;
 
 
5080
 
 
 
5081
                TexturedPolygon_ClipWithNegativeX();
 
 
5082
 
 
 
5083
                if(RenderPolygon.NumberOfVertices < 3)
 
 
5084
                    return;
 
 
5085
 
 
 
5086
                TexturedPolygon_ClipWithPositiveY();
 
 
5087
 
 
 
5088
                if(RenderPolygon.NumberOfVertices < 3)
 
 
5089
                    return;
 
 
5090
 
 
 
5091
                TexturedPolygon_ClipWithNegativeY();
 
 
5092
 
 
 
5093
                if(RenderPolygon.NumberOfVertices < 3)
 
 
5094
                    return;
 
 
5095
 
 
 
5096
                TexturedPolygon_ClipWithPositiveX();
 
 
5097
 
 
 
5098
                if(RenderPolygon.NumberOfVertices < 3)
 
 
5099
                    return;
 
 
5100
 
 
 
5101
                Particle_Output(&particle, RenderPolygon.Vertices);
 
 
5102
              }
 
 
5103
            else 
 
 
5104
            {
 
 
5105
                Particle_Output(&particle, VerticesBuffer);
 
 
5106
            }
 
 
5107
        }
 
 
5108
    }
 
 
5109
}
 
 
5110
 
 
 
5111
void RenderExplosionSurface(struct VOLUMETRIC_EXPLOSION *explosionPtr)
 
 
5112
{
 
 
5113
    extern int BurningImageNumber;
 
 
5114
    int red,green,blue;
 
 
5115
 
 
 
5116
    switch (PlayerStatus.VisionMode)
 
 
5117
    {
 
 
5118
        case VISION_MODE_NORMAL:
 
 
5119
        default:
 
 
5120
            red = green = blue = 255;
 
 
5121
        break;
 
 
5122
        case VISION_MODE_IMAGEINTENSIFIER:
 
 
5123
            red = blue = 0;
 
 
5124
            green = 255;
 
 
5125
        break;
 
 
5126
        case VISION_MODE_PRED_THERMAL:
 
 
5127
        case VISION_MODE_PRED_SEEALIENS:
 
 
5128
        case VISION_MODE_PRED_SEEPREDTECH:
 
 
5129
            red = blue = 255;
 
 
5130
            green = 0;
 
 
5131
    }
 
 
5132
 
 
 
5133
    {
 
 
5134
           POLYHEADER fakeHeader;
 
 
5135
        VECTORCH *vSphere = SphereRotatedVertex;
 
 
5136
           int f;
 
 
5137
        fakeHeader.PolyFlags = iflag_transparent;
 
 
5138
        fakeHeader.PolyColour = BurningImageNumber;
 
 
5139
        RenderPolygon.TranslucencyMode = TRANSLUCENCY_NORMAL;
 
 
5140
 
 
 
5141
        for (f=0; f < SPHERE_VERTICES; f++)
 
 
5142
        {
 
 
5143
            *vSphere = explosionPtr->Position[f];
 
 
5144
            TranslatePointIntoViewspace(vSphere);
 
 
5145
            vSphere++;
 
 
5146
        }
 
 
5147
 
 
 
5148
        for (f=0; f < SPHERE_FACES; f++)
 
 
5149
        {
 
 
5150
             {
 
 
5151
                int i;
 
 
5152
                VECTORCH vertex[3];
 
 
5153
 
 
 
5154
                for (i=0; i < 3; i++) 
 
 
5155
                {
 
 
5156
                    int n = SphereFace[f].v[i];
 
 
5157
                    vertex[i] = SphereRotatedVertex[n];
 
 
5158
                }
 
 
5159
 
 
 
5160
                for (i=0; i < 3; i++) 
 
 
5161
                {
 
 
5162
                    int n = SphereFace[f].v[i];
 
 
5163
 
 
 
5164
                    VerticesBuffer[i].X = vertex[i].vx;
 
 
5165
                    VerticesBuffer[i].Y = vertex[i].vy;
 
 
5166
                    VerticesBuffer[i].Z = vertex[i].vz;
 
 
5167
 
 
 
5168
                    {
 
 
5169
                        int u = -(ONE_FIXED - explosionPtr->LifeTime) * 128 * 2;
 
 
5170
                          VerticesBuffer[i].U = SphereAtmosU[n];
 
 
5171
                        VerticesBuffer[i].V = SphereAtmosV[n] + u;
 
 
5172
                    }
 
 
5173
 
 
 
5174
                    {
 
 
5175
                        int d1 = VerticesBuffer[0].U - VerticesBuffer[1].U;
 
 
5176
                        int d2 = VerticesBuffer[0].U - VerticesBuffer[2].U;
 
 
5177
                        int d3 = VerticesBuffer[1].U - VerticesBuffer[2].U;
 
 
5178
 
 
 
5179
                        int ad1 = (d1 < 0) ? -d1 : d1, ad2 = (d2 < 0) ? -d2 : d2, ad3 = (d3 < 0) ? -d3 : d3;
 
 
5180
                        int i1=0, i2=0, i3=0;
 
 
5181
 
 
 
5182
                        if (ad1 > (128*(SPHERE_TEXTURE_WRAP-1)+64)*65536)
 
 
5183
                        {
 
 
5184
                            if (d1 > 0)
 
 
5185
                                i2 = 1;
 
 
5186
                            else
 
 
5187
                                i1 = 1;
 
 
5188
                        }
 
 
5189
 
 
 
5190
                        if (ad2 > (128*(SPHERE_TEXTURE_WRAP-1)+64)*65536)
 
 
5191
                        {
 
 
5192
                            if (d2 > 0)
 
 
5193
                                i3 = 1;
 
 
5194
                            else
 
 
5195
                                i1 = 1; 
 
 
5196
                        }
 
 
5197
 
 
 
5198
                        if (ad3 > (128*(SPHERE_TEXTURE_WRAP-1)+64)*65536)
 
 
5199
                        {
 
 
5200
                            if (d3 > 0)
 
 
5201
                                i3 = 1; 
 
 
5202
                            else
 
 
5203
                                i2 = 1; 
 
 
5204
                        }
 
 
5205
 
 
 
5206
                        if(i1)
 
 
5207
                        VerticesBuffer[0].U+=128*65536*SPHERE_TEXTURE_WRAP;
 
 
5208
 
 
 
5209
                        if(i2)
 
 
5210
                        VerticesBuffer[1].U+=128*65536*SPHERE_TEXTURE_WRAP;
 
 
5211
 
 
 
5212
                        if(i3)
 
 
5213
                        VerticesBuffer[2].U+=128*65536*SPHERE_TEXTURE_WRAP;
 
 
5214
                    }
 
 
5215
 
 
 
5216
                    VerticesBuffer[i].A = explosionPtr->LifeTime / 256;
 
 
5217
                      VerticesBuffer[i].R = red;
 
 
5218
                    VerticesBuffer[i].G = green;
 
 
5219
                    VerticesBuffer[i].B = blue;
 
 
5220
                    VerticesBuffer[i].SpecularR = VerticesBuffer[i].SpecularG = VerticesBuffer[i].SpecularB = 0;
 
 
5221
                }
 
 
5222
 
 
 
5223
                RenderPolygon.NumberOfVertices = 3;
 
 
5224
            }
 
 
5225
 
 
 
5226
            GouraudTexturedPolygon_ClipWithZ();
 
 
5227
 
 
 
5228
            if(RenderPolygon.NumberOfVertices >= 3)
 
 
5229
            {
 
 
5230
                GouraudTexturedPolygon_ClipWithNegativeX();
 
 
5231
 
 
 
5232
                if(RenderPolygon.NumberOfVertices >= 3)
 
 
5233
                {
 
 
5234
                    GouraudTexturedPolygon_ClipWithPositiveY();
 
 
5235
 
 
 
5236
                    if(RenderPolygon.NumberOfVertices >= 3)
 
 
5237
                    {
 
 
5238
                        GouraudTexturedPolygon_ClipWithNegativeY();
 
 
5239
 
 
 
5240
                        if(RenderPolygon.NumberOfVertices >= 3)
 
 
5241
                        {
 
 
5242
                            GouraudTexturedPolygon_ClipWithPositiveX();
 
 
5243
 
 
 
5244
                            if(RenderPolygon.NumberOfVertices >= 3)
 
 
5245
                                ZBufferedGouraudTexturedPolygon_Output(&fakeHeader, RenderPolygon.Vertices);
 
 
5246
                        }
 
 
5247
                    }
 
 
5248
                }
 
 
5249
            }
 
 
5250
           }
 
 
5251
    }
 
 
5252
}
 
 
5253
 
 
 
5254
void RenderInsideAlienTongue(int offset)
 
 
5255
{
 
 
5256
    #define TONGUE_SCALE 1024
 
 
5257
    int TonguePolyVertexList[4][4] = 
 
 
5258
    {
 
 
5259
        {0,3,7,4},     //+ve y
 
 
5260
        {1,2,3,0},     //+ve x
 
 
5261
        {5,6,7,4},     //-ve x
 
 
5262
        {1,2,6,5},     //-ve y
 
 
5263
    };
 
 
5264
 
 
 
5265
    VECTORCH vertices[8]=
 
 
5266
    {
 
 
5267
        {+TONGUE_SCALE,-TONGUE_SCALE,0},
 
 
5268
        {+TONGUE_SCALE,+TONGUE_SCALE,0},
 
 
5269
        {+TONGUE_SCALE,+TONGUE_SCALE,+TONGUE_SCALE*4},
 
 
5270
        {+TONGUE_SCALE,-TONGUE_SCALE,+TONGUE_SCALE*4},
 
 
5271
 
 
 
5272
        {-TONGUE_SCALE,-TONGUE_SCALE,0},
 
 
5273
        {-TONGUE_SCALE,+TONGUE_SCALE,0},
 
 
5274
        {-TONGUE_SCALE,+TONGUE_SCALE,+TONGUE_SCALE*4},
 
 
5275
        {-TONGUE_SCALE,-TONGUE_SCALE,+TONGUE_SCALE*4},
 
 
5276
    };
 
 
5277
 
 
 
5278
    VECTORCH translatedPts[8];
 
 
5279
 
 
 
5280
    POLYHEADER fakeHeader;
 
 
5281
    int polyNumber = 0;
 
 
5282
 
 
 
5283
    #if 1
 
 
5284
    {
 
 
5285
        int i = 7;
 
 
5286
        do
 
 
5287
        {
 
 
5288
            translatedPts[i] = vertices[i];
 
 
5289
            translatedPts[i].vz -= (ONE_FIXED-offset)/16;
 
 
5290
//            TranslatePointIntoViewspace(&translatedPts[i]);
 
 
5291
 
 
 
5292
        } while(i--);
 
 
5293
       }
 
 
5294
    #endif
 
 
5295
    {
 
 
5296
        extern int AlienTongueImageNumber;
 
 
5297
        fakeHeader.PolyFlags = 0;
 
 
5298
        fakeHeader.PolyColour = AlienTongueImageNumber;
 
 
5299
        RenderPolygon.TranslucencyMode = TRANSLUCENCY_GLOWING;
 
 
5300
    }
 
 
5301
 
 
 
5302
    for(; polyNumber < 4; polyNumber++)
 
 
5303
    {
 
 
5304
        {
 
 
5305
            int i=0;
 
 
5306
            for (; i < 4; i++) 
 
 
5307
            {
 
 
5308
                int v = TonguePolyVertexList[polyNumber][i];
 
 
5309
                VerticesBuffer[i].A = 255;
 
 
5310
                VerticesBuffer[i].X = translatedPts[v].vx;
 
 
5311
                VerticesBuffer[i].Y = translatedPts[v].vy;
 
 
5312
                VerticesBuffer[i].Z = translatedPts[v].vz;
 
 
5313
                VerticesBuffer[i].U = CuboidPolyVertexU[3][i]<<16;
 
 
5314
                VerticesBuffer[i].V = CuboidPolyVertexV[3][i]<<16;
 
 
5315
 
 
 
5316
                VerticesBuffer[i].R = VerticesBuffer[i].G = VerticesBuffer[i].B = offset/2048;
 
 
5317
                VerticesBuffer[i].SpecularR = VerticesBuffer[i].SpecularG = VerticesBuffer[i].SpecularB = 0;
 
 
5318
            }
 
 
5319
 
 
 
5320
            RenderPolygon.NumberOfVertices = 4;
 
 
5321
        }
 
 
5322
 
 
 
5323
        {
 
 
5324
            GouraudTexturedPolygon_ClipWithZ();
 
 
5325
 
 
 
5326
            if(RenderPolygon.NumberOfVertices < 3)
 
 
5327
                continue;
 
 
5328
 
 
 
5329
            GouraudTexturedPolygon_ClipWithNegativeX();
 
 
5330
 
 
 
5331
            if(RenderPolygon.NumberOfVertices < 3)
 
 
5332
                continue;
 
 
5333
 
 
 
5334
            GouraudTexturedPolygon_ClipWithPositiveY();
 
 
5335
 
 
 
5336
            if(RenderPolygon.NumberOfVertices < 3)
 
 
5337
                continue;
 
 
5338
 
 
 
5339
            GouraudTexturedPolygon_ClipWithNegativeY();
 
 
5340
 
 
 
5341
            if(RenderPolygon.NumberOfVertices < 3)
 
 
5342
                continue;
 
 
5343
 
 
 
5344
            GouraudTexturedPolygon_ClipWithPositiveX();
 
 
5345
 
 
 
5346
            if(RenderPolygon.NumberOfVertices < 3)
 
 
5347
                continue;
 
 
5348
 
 
 
5349
            ZBufferedGouraudTexturedPolygon_Output(&fakeHeader, RenderPolygon.Vertices);
 
 
5350
        }
 
 
5351
    }
 
 
5352
}
 
 
5353
 
 
 
5354
#define NO_OF_STARS 700
 
 
5355
struct
 
 
5356
{
 
 
5357
    VECTORCH Position;
 
 
5358
    int Colour;
 
 
5359
    int Frequency;
 
 
5360
    int Phase;
 
 
5361
 
 
 
5362
}  StarArray[NO_OF_STARS];
 
 
5363
 
 
 
5364
void CreateStarArray()
 
 
5365
{
 
 
5366
    int i=0;
 
 
5367
    for (; i < NO_OF_STARS; i++)
 
 
5368
    {
 
 
5369
        int phi = random() & 4095;
 
 
5370
 
 
 
5371
        StarArray[i].Position.vy = ONE_FIXED-(random()&131071);
 
 
5372
 
 
 
5373
        {
 
 
5374
            float y = ((float)StarArray[i].Position.vy)/65536.0;
 
 
5375
            y = sqrt(1-y*y);
 
 
5376
 
 
 
5377
            StarArray[i].Position.vx = ((float)GetCos(phi)*y);
 
 
5378
            StarArray[i].Position.vz = ((float)GetSin(phi)*y);
 
 
5379
        }
 
 
5380
 
 
 
5381
        StarArray[i].Colour = 0xff000000 + (random()&0x7f7f7f)+0x7f7f7f;
 
 
5382
        StarArray[i].Frequency = random() & 4095;
 
 
5383
        StarArray[i].Phase = random() & 4095;
 
 
5384
    }
 
 
5385
}
 
 
5386
 
 
 
5387
void RenderStarfield()
 
 
5388
{
 
 
5389
    int i = 0;
 
 
5390
    int sizeX = 256;
 
 
5391
    int sizeY = MUL_FIXED(sizeX,87381);
 
 
5392
 
 
 
5393
    for (; i < NO_OF_STARS; i++)
 
 
5394
    {
 
 
5395
        VECTORCH position = StarArray[i].Position;
 
 
5396
        PARTICLE particle;
 
 
5397
        particle.ParticleID = PARTICLE_STAR;
 
 
5398
        particle.Colour = StarArray[i].Colour;
 
 
5399
        #if 1
 
 
5400
        position.vx += Global_VDB.VDB_World.vx;
 
 
5401
        position.vy += Global_VDB.VDB_World.vy;
 
 
5402
        position.vz += Global_VDB.VDB_World.vz;
 
 
5403
 
 
 
5404
        TranslatePointIntoViewspace(&position);
 
 
5405
        #endif
 
 
5406
//        RotateVector(&position,&(Global_VDB.VDB_Mat));
 
 
5407
 
 
 
5408
        VerticesBuffer[0].X = position.vx - sizeX;
 
 
5409
        VerticesBuffer[0].Y = position.vy - sizeY;
 
 
5410
        VerticesBuffer[0].Z = position.vz;
 
 
5411
        VerticesBuffer[1].X = position.vx + sizeX;
 
 
5412
        VerticesBuffer[1].Y = position.vy - sizeY;
 
 
5413
        VerticesBuffer[1].Z = position.vz;
 
 
5414
        VerticesBuffer[2].X = position.vx + sizeX;
 
 
5415
        VerticesBuffer[2].Y = position.vy + sizeY;
 
 
5416
        VerticesBuffer[2].Z = position.vz;
 
 
5417
        VerticesBuffer[3].X = position.vx - sizeX;
 
 
5418
        VerticesBuffer[3].Y = position.vy + sizeY;
 
 
5419
        VerticesBuffer[3].Z = position.vz;
 
 
5420
 
 
 
5421
        {
 
 
5422
            int outcode = QuadWithinFrustrum();
 
 
5423
 
 
 
5424
            if (outcode)
 
 
5425
            {         
 
 
5426
                RenderPolygon.NumberOfVertices = 4;
 
 
5427
 
 
 
5428
    //            printf("On Screen!\n");
 
 
5429
                VerticesBuffer[0].U = 192<<16;
 
 
5430
                VerticesBuffer[0].V = 0;
 
 
5431
 
 
 
5432
                VerticesBuffer[1].U = 255<<16;
 
 
5433
                VerticesBuffer[1].V = 0;
 
 
5434
 
 
 
5435
                VerticesBuffer[2].U = 255<<16;
 
 
5436
                VerticesBuffer[2].V = 63<<16;
 
 
5437
 
 
 
5438
                VerticesBuffer[3].U = 192<<16;
 
 
5439
                VerticesBuffer[3].V = 63<<16;
 
 
5440
 
 
 
5441
                if (outcode != 2)
 
 
5442
                {
 
 
5443
                    TexturedPolygon_ClipWithZ();
 
 
5444
 
 
 
5445
                    if(RenderPolygon.NumberOfVertices < 3)
 
 
5446
                        return;
 
 
5447
 
 
 
5448
                    TexturedPolygon_ClipWithNegativeX();
 
 
5449
 
 
 
5450
                    if(RenderPolygon.NumberOfVertices < 3)
 
 
5451
                        return;
 
 
5452
 
 
 
5453
                    TexturedPolygon_ClipWithPositiveY();
 
 
5454
 
 
 
5455
                    if(RenderPolygon.NumberOfVertices < 3)
 
 
5456
                        return;
 
 
5457
 
 
 
5458
                    TexturedPolygon_ClipWithNegativeY();
 
 
5459
 
 
 
5460
                    if(RenderPolygon.NumberOfVertices < 3)
 
 
5461
                        return;
 
 
5462
 
 
 
5463
                    TexturedPolygon_ClipWithPositiveX();
 
 
5464
 
 
 
5465
                    if(RenderPolygon.NumberOfVertices < 3)
 
 
5466
                        return;
 
 
5467
 
 
 
5468
                    Particle_Output(&particle, RenderPolygon.Vertices);
 
 
5469
                  }
 
 
5470
                else
 
 
5471
                {
 
 
5472
                    Particle_Output(&particle, VerticesBuffer);
 
 
5473
                }
 
 
5474
            }
 
 
5475
        }
 
 
5476
    }
 
 
5477
}
 
 
5478
 
 
 
5479
void ChooseLightingModel()
 
 
5480
{
 
 
5481
    switch(UserProfile.active_bonus)
 
 
5482
    {
 
 
5483
        case CHEATMODE_NONACTIVE:
 
 
5484
        default:
 
 
5485
        {
 
 
5486
            switch (PlayerStatus.VisionMode)
 
 
5487
            {
 
 
5488
                default:
 
 
5489
                case VISION_MODE_NORMAL:
 
 
5490
                    VertexIntensity = VertexIntensity_Standard_Opt;
 
 
5491
                break;
 
 
5492
                case VISION_MODE_IMAGEINTENSIFIER:
 
 
5493
                    VertexIntensity = VertexIntensity_ImageIntensifier;
 
 
5494
                break;
 
 
5495
                case VISION_MODE_ALIEN_SENSE:
 
 
5496
                    VertexIntensity = VertexIntensity_Alien_Sense;
 
 
5497
                break;
 
 
5498
                case VISION_MODE_PRED_THERMAL:
 
 
5499
                    VertexIntensity = VertexIntensity_Pred_Thermal;
 
 
5500
                break;
 
 
5501
                case VISION_MODE_PRED_SEEALIENS:
 
 
5502
                    VertexIntensity = VertexIntensity_Pred_SeeAliens;
 
 
5503
                break;
 
 
5504
                case VISION_MODE_PRED_SEEPREDTECH:
 
 
5505
                    VertexIntensity = VertexIntensity_Pred_SeePredatorTech;
 
 
5506
            }
 
 
5507
        }
 
 
5508
        break;
 
 
5509
        case CHEATMODE_DRAWFULLBRIGHT:
 
 
5510
            VertexIntensity = VertexIntensity_FullBright;
 
 
5511
        break;
 
 
5512
        case CHEATMODE_DISCOINFERNO:
 
 
5513
        case CHEATMODE_TRIPTASTIC:
 
 
5514
            VertexIntensity = VertexIntensity_DiscoInferno;
 
 
5515
        break;
 
 
5516
        case CHEATMODE_UNDERWATER:
 
 
5517
            VertexIntensity = VertexIntensity_Underwater;
 
 
5518
    }
 
 
5519
}