4b825dc642cb6eb9a060e54bf8d69288fbee490494a6641b73026d662261604d7d192beae70b11dc
 
 
1
#include "system.h"
 
 
2
#include "prototyp.h"
 
 
3
#include "module.h"
 
 
4
#include "stratdef.h"
 
 
5
#include <assert.h>
 
 
6
#include "bh_ltfx.h"
 
 
7
#include <stdlib.h>
 
 
8
 
 
 
9
extern struct shapeheader** mainshapelist;
 
 
10
 
 
 
11
void LightFXBehaveInit(void * bhdata, STRATEGYBLOCK* sbptr)
 
 
12
{
 
 
13
    MODULE * my_mod;
 
 
14
 
 
 
15
    LIGHT_FX_BEHAV_BLOCK * lfxbb = malloc(sizeof(LIGHT_FX_BEHAV_BLOCK));
 
 
16
 
 
 
17
    if (!lfxbb)
 
 
18
    {
 
 
19
        RemoveBehaviourStrategy(sbptr);
 
 
20
        return;
 
 
21
    }
 
 
22
 
 
 
23
    sbptr->dataptr = lfxbb;
 
 
24
    LIGHT_FX_TOOLS_TEMPLATE * lfxtt = (LIGHT_FX_TOOLS_TEMPLATE *)bhdata;
 
 
25
 
 
 
26
    COPY_NAME (sbptr->SBname, lfxtt->nameID);
 
 
27
    lfxbb->bhvr_type = I_BehaviourLightFX;
 
 
28
 
 
 
29
    // Setup module ref
 
 
30
    {
 
 
31
        extern SCENEMODULE MainScene;
 
 
32
        MREF mref = lfxtt->my_module;
 
 
33
        ConvertModuleNameToPointer (&mref, MainScene.sm_marray);
 
 
34
        my_mod = mref.mref_ptr;
 
 
35
    }
 
 
36
 
 
 
37
    my_mod->m_sbptr = sbptr;
 
 
38
    sbptr->moptr = my_mod;
 
 
39
 
 
 
40
    assert (my_mod);
 
 
41
 
 
 
42
    lfxbb->type = lfxtt->light_data.type;
 
 
43
    lfxbb->current_state = lfxtt->light_data.init_state;
 
 
44
    lfxbb->fade_up_speed = lfxtt->light_data.fade_up_speed;
 
 
45
    lfxbb->fade_down_speed = lfxtt->light_data.fade_down_speed;
 
 
46
    lfxbb->post_fade_up_delay = lfxtt->light_data.post_fade_up_delay;
 
 
47
    lfxbb->post_fade_down_delay = lfxtt->light_data.post_fade_down_delay;
 
 
48
 
 
 
49
    if (!lfxbb->fade_up_speed)
 
 
50
        lfxbb->fade_up_speed = 10;
 
 
51
 
 
 
52
    if (!lfxbb->fade_down_speed)
 
 
53
        lfxbb->fade_down_speed = 10;
 
 
54
 
 
 
55
    if (!lfxbb->post_fade_up_delay)
 
 
56
        lfxbb->post_fade_up_delay = 10;
 
 
57
 
 
 
58
    if (!lfxbb->post_fade_down_delay)
 
 
59
        lfxbb->post_fade_down_delay = 10;
 
 
60
 
 
 
61
    lfxbb->fade_up_speed_multiplier = DIV_FIXED (ONE_FIXED, lfxbb->fade_up_speed);
 
 
62
    lfxbb->fade_down_speed_multiplier = DIV_FIXED (ONE_FIXED, lfxbb->fade_down_speed);
 
 
63
    lfxbb->post_fade_up_delay_multiplier = DIV_FIXED (ONE_FIXED, lfxbb->post_fade_up_delay);
 
 
64
    lfxbb->post_fade_down_delay_multiplier = DIV_FIXED (ONE_FIXED, lfxbb->post_fade_down_delay);
 
 
65
 
 
 
66
    switch (lfxbb->type)
 
 
67
    {
 
 
68
        case LFX_Strobe:
 
 
69
        case LFX_Switch:
 
 
70
        case LFX_FlickySwitch:
 
 
71
        {
 
 
72
            switch (lfxbb->current_state)
 
 
73
            {
 
 
74
                case LFXS_LightOn:
 
 
75
                {
 
 
76
                    lfxbb->multiplier = ONE_FIXED;
 
 
77
                    lfxbb->timer = 0;
 
 
78
                    lfxbb->timer2 = 0;
 
 
79
                }
 
 
80
                break;
 
 
81
                case LFXS_LightOff:
 
 
82
                {
 
 
83
                    lfxbb->multiplier = 0;
 
 
84
                    lfxbb->timer = 0;
 
 
85
                    lfxbb->timer2 = 0;
 
 
86
                }
 
 
87
                break;
 
 
88
                default:
 
 
89
                {
 
 
90
                    lfxbb->multiplier = ONE_FIXED;
 
 
91
                    lfxbb->timer = 0;
 
 
92
                    lfxbb->timer2 = 0;
 
 
93
                }
 
 
94
            }
 
 
95
        }
 
 
96
        break;
 
 
97
        case LFX_RandomFlicker:
 
 
98
        {
 
 
99
            lfxbb->current_state = LFXS_Flicking;
 
 
100
            lfxbb->multiplier = ONE_FIXED;
 
 
101
            lfxbb->timer = 0;
 
 
102
            lfxbb->timer2 = 0;
 
 
103
            lfxbb->time_to_next_flicker_state = 0;
 
 
104
        }
 
 
105
        break;
 
 
106
        default:
 
 
107
        {
 
 
108
            lfxbb->multiplier = ONE_FIXED;
 
 
109
            lfxbb->timer = 0;
 
 
110
            lfxbb->timer2 = 0;
 
 
111
            lfxbb->time_to_next_flicker_state = 0;
 
 
112
        }
 
 
113
    }
 
 
114
 
 
 
115
    /* see if this module has a texture animation*/
 
 
116
    {
 
 
117
        int item_num = 0;
 
 
118
        struct shapeheader* shptr = mainshapelist[sbptr->shapeIndex];
 
 
119
        TXACTRLBLK **pptxactrlblk = &lfxbb->anim_control;
 
 
120
 
 
 
121
        for(; item_num < shptr->numitems; item_num++)
 
 
122
        {
 
 
123
            POLYHEADER *poly = (POLYHEADER*)(shptr->items[item_num]);
 
 
124
            assert(poly);
 
 
125
 
 
 
126
            if(poly->PolyFlags & iflag_txanim)
 
 
127
            {
 
 
128
                TXACTRLBLK *pnew_txactrlblk = malloc(sizeof(TXACTRLBLK));
 
 
129
 
 
 
130
                if (pnew_txactrlblk)
 
 
131
                {
 
 
132
                    pnew_txactrlblk->tac_flags = 0;                                        
 
 
133
                    pnew_txactrlblk->tac_item = item_num;                                        
 
 
134
                    pnew_txactrlblk->tac_sequence = 0;                                        
 
 
135
                    pnew_txactrlblk->tac_node = 0;                                        
 
 
136
                    pnew_txactrlblk->tac_txarray = GetTxAnimArrayZ(sbptr->shapeIndex, item_num);                                        
 
 
137
                    pnew_txactrlblk->tac_txah_s = GetTxAnimHeaderFromShape(pnew_txactrlblk, sbptr->shapeIndex);
 
 
138
 
 
 
139
                    // change the value held in pptxactrlblk which point to the previous structures "next" pointer
 
 
140
 
 
 
141
                    *pptxactrlblk = pnew_txactrlblk;
 
 
142
                    pptxactrlblk = &pnew_txactrlblk->tac_next;
 
 
143
                }
 
 
144
                else
 
 
145
                {
 
 
146
                    break;
 
 
147
                }
 
 
148
            }
 
 
149
        }
 
 
150
        *pptxactrlblk = NULL;
 
 
151
    }
 
 
152
}
 
 
153
 
 
 
154
void LightFXBehaveFun (STRATEGYBLOCK* sbptr)
 
 
155
{
 
 
156
     assert(sbptr);
 
 
157
 
 
 
158
    DISPLAYBLOCK* dptr = sbptr->DisplayBlock;
 
 
159
 
 
 
160
    LIGHT_FX_BEHAV_BLOCK * lfxbb = (LIGHT_FX_BEHAV_BLOCK *)sbptr->dataptr;
 
 
161
    assert((lfxbb->bhvr_type == I_BehaviourLightFX));
 
 
162
 
 
 
163
    /*deal with any texture animation*/
 
 
164
    if(lfxbb->anim_control && dptr && !dptr->ObTxAnimCtrlBlks)
 
 
165
        dptr->ObTxAnimCtrlBlks = lfxbb->anim_control;
 
 
166
 
 
 
167
    /*now update the lighting effects*/
 
 
168
    switch (lfxbb->type)
 
 
169
    {
 
 
170
        case LFX_RandomFlicker:
 
 
171
        {
 
 
172
            if (dptr)
 
 
173
            {
 
 
174
                switch (lfxbb->current_state)
 
 
175
                {
 
 
176
                    case LFXS_Flicking:
 
 
177
                    {
 
 
178
                        lfxbb->time_to_next_flicker_state -= NormalFrameTime;
 
 
179
                        lfxbb->timer += NormalFrameTime;
 
 
180
 
 
 
181
                        if (lfxbb->timer > 1750)
 
 
182
                        {
 
 
183
                            int j;
 
 
184
 
 
 
185
                            lfxbb->multiplier = FastRandom() & 65535;
 
 
186
 
 
 
187
                            if (!((lfxbb->multiplier % 24 ) >> 3))
 
 
188
                                lfxbb->multiplier |= 0xa000;
 
 
189
                            else
 
 
190
                                lfxbb->multiplier &= ~0xf000;
 
 
191
 
 
 
192
                            for (j=0; j < dptr->ObNumLights; j++)
 
 
193
                            {
 
 
194
                                LIGHTBLOCK * lp = dptr->ObLights[j];
 
 
195
 
 
 
196
                                if (!(lp->LightFlags & LFlag_PreLitSource))
 
 
197
                                    lp->LightBright = MUL_FIXED (lp->LightBrightStore, lfxbb->multiplier);
 
 
198
                            }
 
 
199
 
 
 
200
                            lfxbb->timer = 0;                    
 
 
201
                        }
 
 
202
                    }
 
 
203
                    break;
 
 
204
                    case LFXS_NotFlicking:
 
 
205
                    {
 
 
206
                        lfxbb->time_to_next_flicker_state -= NormalFrameTime;
 
 
207
 
 
 
208
                        if (lfxbb->time_to_next_flicker_state < 0)
 
 
209
                        {
 
 
210
                            lfxbb->current_state = LFXS_Flicking;
 
 
211
                            lfxbb->time_to_next_flicker_state = FastRandom() & 65535;
 
 
212
                        }
 
 
213
 
 
 
214
                    }
 
 
215
                    break;
 
 
216
                    case LFXS_LightOff:
 
 
217
                    {
 
 
218
                        int j=0;
 
 
219
                        for (; j < dptr->ObNumLights; j++)
 
 
220
                        {
 
 
221
                            LIGHTBLOCK * lp = dptr->ObLights[j];
 
 
222
 
 
 
223
                            if (!(lp->LightFlags & LFlag_PreLitSource))
 
 
224
                                lp->LightBright = 0;
 
 
225
                        }
 
 
226
                    }
 
 
227
                    break;
 
 
228
                    default:
 
 
229
                        break;
 
 
230
                }
 
 
231
            }
 
 
232
        }
 
 
233
        break;
 
 
234
        case LFX_Strobe:
 
 
235
        {
 
 
236
            switch (lfxbb->current_state)
 
 
237
            {
 
 
238
                case LFXS_LightOn:
 
 
239
                {
 
 
240
                    lfxbb->timer += MUL_FIXED (NormalFrameTime, lfxbb->post_fade_up_delay_multiplier);
 
 
241
 
 
 
242
                    if (lfxbb->timer > ONE_FIXED)
 
 
243
                    {
 
 
244
                        lfxbb->current_state = LFXS_LightFadingDown;
 
 
245
                        lfxbb->timer = 0;
 
 
246
                    }
 
 
247
                }
 
 
248
                break;
 
 
249
                case LFXS_LightOff:
 
 
250
                {
 
 
251
                    lfxbb->timer += MUL_FIXED (NormalFrameTime, lfxbb->post_fade_down_delay_multiplier);
 
 
252
 
 
 
253
                    if (lfxbb->timer > ONE_FIXED)
 
 
254
                    {
 
 
255
                        lfxbb->current_state = LFXS_LightFadingUp;
 
 
256
                        lfxbb->timer = 0;
 
 
257
                    }
 
 
258
                }
 
 
259
                break;
 
 
260
                case LFXS_LightFadingUp:
 
 
261
                {
 
 
262
                    int diff = MUL_FIXED (NormalFrameTime, lfxbb->fade_up_speed_multiplier);
 
 
263
                    lfxbb->timer += diff;
 
 
264
                    lfxbb->multiplier += diff;
 
 
265
 
 
 
266
                    if (lfxbb->timer > ONE_FIXED)
 
 
267
                    {
 
 
268
                        lfxbb->current_state = LFXS_LightOn;
 
 
269
                        lfxbb->timer = 0;
 
 
270
                        lfxbb->multiplier = 65536;
 
 
271
                    }
 
 
272
                }
 
 
273
                break;
 
 
274
                case LFXS_LightFadingDown:
 
 
275
                {
 
 
276
                    int diff = MUL_FIXED (NormalFrameTime, lfxbb->fade_down_speed_multiplier);
 
 
277
                    lfxbb->timer += diff;
 
 
278
                    lfxbb->multiplier -= diff;
 
 
279
 
 
 
280
                    if (lfxbb->timer > ONE_FIXED)
 
 
281
                    {
 
 
282
                        lfxbb->current_state = LFXS_LightOff;
 
 
283
                        lfxbb->timer = 0;
 
 
284
                        lfxbb->multiplier = 0;
 
 
285
                    }
 
 
286
                }
 
 
287
                break;
 
 
288
                default:
 
 
289
                {
 
 
290
                    assert (0 == "Light FX state not supported");
 
 
291
                    break;
 
 
292
                }
 
 
293
            }
 
 
294
 
 
 
295
            if (dptr)
 
 
296
            {
 
 
297
                int j;
 
 
298
                for (j=0; j < dptr->ObNumLights; j++)
 
 
299
                {
 
 
300
                    LIGHTBLOCK * lp = dptr->ObLights[j];
 
 
301
 
 
 
302
                    if (!(lp->LightFlags & LFlag_PreLitSource))
 
 
303
                        lp->LightBright = MUL_FIXED (lp->LightBrightStore, lfxbb->multiplier);
 
 
304
                }
 
 
305
            }
 
 
306
        }
 
 
307
        break;
 
 
308
        case LFX_Switch:
 
 
309
        {
 
 
310
            switch (lfxbb->current_state)
 
 
311
            {
 
 
312
                case LFXS_LightFadingUp:
 
 
313
                {
 
 
314
                    int diff = MUL_FIXED (NormalFrameTime, lfxbb->fade_up_speed_multiplier);
 
 
315
 
 
 
316
                    lfxbb->timer += diff;
 
 
317
                    lfxbb->multiplier += diff;
 
 
318
 
 
 
319
                    if (lfxbb->timer > ONE_FIXED)
 
 
320
                    {
 
 
321
                        lfxbb->current_state = LFXS_LightOn;
 
 
322
                        lfxbb->timer = 0;
 
 
323
                        lfxbb->multiplier = 65536;
 
 
324
                    }
 
 
325
                }
 
 
326
                break;
 
 
327
                case LFXS_LightFadingDown:
 
 
328
                {
 
 
329
                    int diff = MUL_FIXED (NormalFrameTime, lfxbb->fade_down_speed_multiplier);
 
 
330
                    lfxbb->timer += diff;
 
 
331
                    lfxbb->multiplier -= diff;
 
 
332
 
 
 
333
                    if (lfxbb->timer > ONE_FIXED)
 
 
334
                    {
 
 
335
                        lfxbb->current_state = LFXS_LightOff;
 
 
336
                        lfxbb->timer = 0;
 
 
337
                        lfxbb->multiplier = 0;
 
 
338
                    }
 
 
339
                }
 
 
340
                break;
 
 
341
                case LFXS_LightOn:
 
 
342
                case LFXS_LightOff:
 
 
343
                    break;
 
 
344
 
 
 
345
                default:
 
 
346
                {
 
 
347
                    assert (0 == "Light FX state not supported");
 
 
348
                    break;
 
 
349
                }
 
 
350
            }
 
 
351
 
 
 
352
            if (dptr)
 
 
353
            {
 
 
354
                int j;
 
 
355
                for (j=0; j < dptr->ObNumLights; j++)
 
 
356
                {
 
 
357
                    LIGHTBLOCK * lp = dptr->ObLights[j];
 
 
358
 
 
 
359
                    if (!(lp->LightFlags & LFlag_PreLitSource))
 
 
360
                        lp->LightBright = MUL_FIXED (lp->LightBrightStore, lfxbb->multiplier);
 
 
361
                }
 
 
362
            }
 
 
363
        }
 
 
364
        break;
 
 
365
        case LFX_FlickySwitch:
 
 
366
        {
 
 
367
            switch (lfxbb->current_state)
 
 
368
            {
 
 
369
                case LFXS_LightFadingUp:
 
 
370
                {
 
 
371
                    int diff = MUL_FIXED (NormalFrameTime, lfxbb->fade_up_speed_multiplier);
 
 
372
 
 
 
373
                    lfxbb->timer += diff;
 
 
374
                    lfxbb->timer2 += NormalFrameTime;
 
 
375
 
 
 
376
                    if (lfxbb->timer2 > 3553)
 
 
377
                    {
 
 
378
                        lfxbb->multiplier = FastRandom() & 65535;
 
 
379
 
 
 
380
                        if (!((lfxbb->multiplier % 24 )>>3))
 
 
381
                            lfxbb->multiplier |= 0xa000;
 
 
382
                        else
 
 
383
                            lfxbb->multiplier &= ~0xf000;
 
 
384
 
 
 
385
                        lfxbb->timer2 = 0;                    
 
 
386
                    }
 
 
387
 
 
 
388
                    if (lfxbb->timer > ONE_FIXED)
 
 
389
                    {
 
 
390
                        lfxbb->current_state = LFXS_LightOn;
 
 
391
                        lfxbb->timer = 0;
 
 
392
                        lfxbb->multiplier = 65536;
 
 
393
                    }
 
 
394
                }
 
 
395
                break;
 
 
396
                case LFXS_LightFadingDown:
 
 
397
                {
 
 
398
                    int diff = MUL_FIXED (NormalFrameTime, lfxbb->fade_down_speed_multiplier);
 
 
399
                    lfxbb->timer += diff;
 
 
400
                    lfxbb->multiplier -= diff;
 
 
401
 
 
 
402
                    if (lfxbb->timer > ONE_FIXED)
 
 
403
                    {
 
 
404
                        lfxbb->current_state = LFXS_LightOff;
 
 
405
                        lfxbb->timer = 0;
 
 
406
                        lfxbb->multiplier = 0;
 
 
407
                    }
 
 
408
                }
 
 
409
                break;
 
 
410
                case LFXS_LightOn:
 
 
411
                case LFXS_LightOff:
 
 
412
                    break;
 
 
413
 
 
 
414
                default:
 
 
415
                {
 
 
416
                    assert (0 == "Light FX state not supported");
 
 
417
                    break;
 
 
418
                }
 
 
419
            }
 
 
420
 
 
 
421
            if (dptr)
 
 
422
            {
 
 
423
                int j;
 
 
424
                for (j=0; j < dptr->ObNumLights; j++)
 
 
425
                {
 
 
426
                    LIGHTBLOCK * lp = dptr->ObLights[j];
 
 
427
 
 
 
428
                    if (!(lp->LightFlags & LFlag_PreLitSource))
 
 
429
                        lp->LightBright = MUL_FIXED (lp->LightBrightStore, lfxbb->multiplier);
 
 
430
                }
 
 
431
            }
 
 
432
        }
 
 
433
        break;
 
 
434
        default:
 
 
435
        {
 
 
436
            assert (0 == "Light FX type not supported");
 
 
437
            break;
 
 
438
        }
 
 
439
    }
 
 
440
}
 
 
441
 
 
 
442
/*--------------------**
 
 
443
** Loading and Saving **
 
 
444
**--------------------*/
 
 
445
#include "savegame.h"
 
 
446
 
 
 
447
typedef struct light_fx_save_block
 
 
448
{
 
 
449
    SAVE_BLOCK_STRATEGY_HEADER header;
 
 
450
 
 
 
451
    LIGHT_FX_STATE current_state;
 
 
452
    int32_t multiplier;
 
 
453
    uint32_t timer;
 
 
454
    uint32_t timer2;
 
 
455
    int32_t time_to_next_flicker_state;
 
 
456
 
 
 
457
} LIGHT_FX_SAVE_BLOCK;
 
 
458
 
 
 
459
//defines for load/save macros
 
 
460
#define SAVELOAD_BLOCK block
 
 
461
#define SAVELOAD_BEHAV lfxbb
 
 
462
 
 
 
463
void LoadStrategy_LightFx(SAVE_BLOCK_STRATEGY_HEADER* header)
 
 
464
{
 
 
465
    LIGHT_FX_SAVE_BLOCK* block = (LIGHT_FX_SAVE_BLOCK*) header; 
 
 
466
 
 
 
467
    //check the size of the save block
 
 
468
    if(header->size != sizeof(*block))
 
 
469
        return;
 
 
470
 
 
 
471
    //find the existing strategy block
 
 
472
    STRATEGYBLOCK* sbPtr = FindSBWithName(header->SBname);
 
 
473
 
 
 
474
    if(!sbPtr)
 
 
475
        return;
 
 
476
 
 
 
477
    //make sure the strategy found is of the right type
 
 
478
    if(sbPtr->type != I_BehaviourLightFX)
 
 
479
        return;
 
 
480
 
 
 
481
    LIGHT_FX_BEHAV_BLOCK * lfxbb = (LIGHT_FX_BEHAV_BLOCK *)sbPtr->dataptr;
 
 
482
 
 
 
483
    //start copying stuff
 
 
484
 
 
 
485
    COPYELEMENT_LOAD(current_state)
 
 
486
    COPYELEMENT_LOAD(multiplier)
 
 
487
    COPYELEMENT_LOAD(timer)
 
 
488
    COPYELEMENT_LOAD(timer2)
 
 
489
    COPYELEMENT_LOAD(time_to_next_flicker_state)
 
 
490
 
 
 
491
    //update the brightness of the lights
 
 
492
    DISPLAYBLOCK* dptr = sbPtr->DisplayBlock;;
 
 
493
 
 
 
494
    if(dptr)
 
 
495
    {
 
 
496
        //I'm not sure that we will ever have a displayblock at this point, anyway. hmm.
 
 
497
        int j;
 
 
498
        for (j=0; j < dptr->ObNumLights; j++)
 
 
499
        {
 
 
500
            LIGHTBLOCK * lp = dptr->ObLights[j];
 
 
501
 
 
 
502
            if (!(lp->LightFlags & LFlag_PreLitSource))
 
 
503
                lp->LightBright = MUL_FIXED (lp->LightBrightStore, lfxbb->multiplier);
 
 
504
        }
 
 
505
    }
 
 
506
}
 
 
507
 
 
 
508
void SaveStrategy_LightFx(STRATEGYBLOCK* sbPtr)
 
 
509
{
 
 
510
    LIGHT_FX_SAVE_BLOCK *block;
 
 
511
    LIGHT_FX_BEHAV_BLOCK * lfxbb = (LIGHT_FX_BEHAV_BLOCK *)sbPtr->dataptr;
 
 
512
 
 
 
513
    GET_STRATEGY_SAVE_BLOCK(block,sbPtr);
 
 
514
 
 
 
515
    //start copying stuff
 
 
516
 
 
 
517
    COPYELEMENT_SAVE(current_state)
 
 
518
    COPYELEMENT_SAVE(multiplier)
 
 
519
    COPYELEMENT_SAVE(timer)
 
 
520
    COPYELEMENT_SAVE(timer2)
 
 
521
    COPYELEMENT_SAVE(time_to_next_flicker_state)
 
 
522
}