| | 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 | } |