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