1 // Emacs style mode select   -*- C++ -*-
2 //-----------------------------------------------------------------------------
3 //
4 // $Id: p_lights.c 1440 2019-05-19 02:31:03Z wesleyjohnson $
5 //
6 // Copyright (C) 1993-1996 by id Software, Inc.
7 // Portions Copyright (C) 1998-2000 by DooM Legacy Team.
8 //
9 // This program is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU General Public License
11 // as published by the Free Software Foundation; either version 2
12 // of the License, or (at your option) any later version.
13 //
14 // This program is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 // GNU General Public License for more details.
18 //
19 //
20 // $Log: p_lights.c,v $
21 // Revision 1.5  2000/11/02 17:50:07  stroggonmeth
22 // Big 3Dfloors & FraggleScript commit!!
23 //
24 // Revision 1.4  2000/04/11 19:07:24  stroggonmeth
25 // Finished my logs, fixed a crashing bug.
26 //
27 // Revision 1.3  2000/04/04 00:32:46  stroggonmeth
28 // Initial Boom compatability plus few misc changes all around.
29 //
30 // Revision 1.2  2000/02/27 00:42:10  hurdler
31 // Revision 1.1.1.1  2000/02/22 20:32:32  hurdler
32 // Initial import into CVS (v1.29 pr3)
33 //
34 //
35 // DESCRIPTION:
36 //      Handle Sector base lighting effects.
37 //      Muzzle flash?
38 //
39 //-----------------------------------------------------------------------------
40 
41 
42 #include "doomincl.h"
43 #include "doomstat.h"
44 #include "p_local.h"
45 #include "p_tick.h"
46   // think
47 #include "r_state.h"
48 #include "z_zone.h"
49 #include "m_random.h"
50 
51 
52 // =========================================================================
53 //                           FIRELIGHT FLICKER
54 // =========================================================================
55 
56 //
57 // T_FireFlicker
58 //
T_FireFlicker(fireflicker_t * flick)59 void T_FireFlicker (fireflicker_t* flick)
60 {
61     int amount;
62 
63     if (--flick->count)
64         return;
65 
66     amount = (PP_Random(pr_lights)&3)*16;
67 
68     if (flick->sector->lightlevel - amount < flick->minlight)
69         flick->sector->lightlevel = flick->minlight;
70     else
71         flick->sector->lightlevel = flick->maxlight - amount;
72 
73     flick->count = 4;
74 }
75 
76 
77 
78 //
79 // P_SpawnFireFlicker
80 //
P_SpawnFireFlicker(sector_t * sector)81 void P_SpawnFireFlicker (sector_t*  sector)
82 {
83     fireflicker_t*      flick;
84 
85     // Note that we are resetting sector attributes.
86     // Nothing special about it during gameplay.
87     sector->special &= ~31; //SoM: Clear non-generalized sector type
88 
89     flick = Z_Malloc ( sizeof(*flick), PU_LEVSPEC, 0);
90     flick->thinker.function.acp1 = (actionf_p1) T_FireFlicker;
91 
92     flick->sector = sector;
93     flick->maxlight = sector->lightlevel;
94     flick->minlight = P_FindMinSurroundingLight(sector,sector->lightlevel)+16;
95     flick->count = 4;
96 
97     P_AddThinker (&flick->thinker);
98 }
99 
100 
101 
102 //
103 // BROKEN LIGHT FLASHING
104 //
105 
106 
107 //
108 // T_LightFlash
109 // Do flashing lights.
110 //
T_LightFlash(lightflash_t * flash)111 void T_LightFlash (lightflash_t* flash)
112 {
113     if (--flash->count)
114         return;
115 
116     if (flash->sector->lightlevel == flash->maxlight)
117     {
118         flash-> sector->lightlevel = flash->minlight;
119         flash->count = (PP_Random(pr_lights)&flash->mintime)+1;
120     }
121     else
122     {
123         flash-> sector->lightlevel = flash->maxlight;
124         flash->count = (PP_Random(pr_lights)&flash->maxtime)+1;
125     }
126 
127 }
128 
129 
130 
131 
132 //
133 // P_SpawnLightFlash
134 // After the map has been loaded, scan each sector
135 // for specials that spawn thinkers
136 //
P_SpawnLightFlash(sector_t * sector)137 void P_SpawnLightFlash (sector_t* sector)
138 {
139     lightflash_t*       flash;
140 
141     // nothing special about it during gameplay
142     sector->special &= ~31; //SoM: 3/7/2000: Clear non-generalized type
143 
144     flash = Z_Malloc ( sizeof(*flash), PU_LEVSPEC, 0);
145     flash->thinker.function.acp1 = (actionf_p1) T_LightFlash;
146 
147     flash->sector = sector;
148     flash->maxlight = sector->lightlevel;
149 
150     flash->minlight = P_FindMinSurroundingLight(sector,sector->lightlevel);
151     flash->maxtime = 64;
152     flash->mintime = 7;
153     flash->count = (PP_Random(pr_lights)&flash->maxtime)+1;
154 
155     P_AddThinker (&flash->thinker);
156 }
157 
158 
159 
160 //
161 // STROBE LIGHT FLASHING
162 //
163 
164 
165 //
166 // T_StrobeFlash
167 //
T_StrobeFlash(strobe_t * flash)168 void T_StrobeFlash (strobe_t*  flash)
169 {
170     if (--flash->count)
171         return;
172 
173     if (flash->sector->lightlevel == flash->minlight)
174     {
175         flash-> sector->lightlevel = flash->maxlight;
176         flash->count = flash->brighttime;
177     }
178     else
179     {
180         flash-> sector->lightlevel = flash->minlight;
181         flash->count =flash->darktime;
182     }
183 
184 }
185 
186 
187 
188 //
189 // P_SpawnStrobeFlash
190 // After the map has been loaded, scan each sector
191 // for specials that spawn thinkers
192 //
193 void
P_SpawnStrobeFlash(sector_t * sector,int fastOrSlow,int inSync)194 P_SpawnStrobeFlash( sector_t* sector,
195                     int fastOrSlow, int inSync )
196 {
197     strobe_t*   flash;
198 
199     flash = Z_Malloc ( sizeof(*flash), PU_LEVSPEC, 0);
200     flash->thinker.function.acp1 = (actionf_p1) T_StrobeFlash;
201 
202     flash->sector = sector;
203     flash->darktime = fastOrSlow;
204     flash->brighttime = STROBEBRIGHT;
205     flash->maxlight = sector->lightlevel;
206     flash->minlight = P_FindMinSurroundingLight(sector, sector->lightlevel);
207 
208     if (flash->minlight == flash->maxlight)
209         flash->minlight = 0;
210 
211     // nothing special about it during gameplay
212     sector->special &= ~31; //SoM: 3/7/2000: Clear non-generalized sector type
213 
214     if (!inSync)
215         flash->count = (PP_Random(pr_lights)&7)+1;
216     else
217         flash->count = 1;
218 
219     P_AddThinker (&flash->thinker);
220 }
221 
222 
223 //
224 // Start strobing lights (usually from a trigger)
225 //
EV_StartLightStrobing(line_t * line)226 int EV_StartLightStrobing(line_t* line)
227 {
228     sector_t*   sec;
229 
230     int secnum = -1; // init search FindSector
231     while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
232     {
233         sec = &sectors[secnum];
234         if (P_SectorActive( S_lighting_special, sec)) //SoM: 3/7/2000: New way to check thinker
235           continue;
236 
237         P_SpawnStrobeFlash (sec,SLOWDARK, 0);
238     }
239     return 1;
240 }
241 
242 
243 
244 //
245 // TURN LINE'S TAG LIGHTS OFF
246 //
EV_TurnTagLightsOff(line_t * line)247 int EV_TurnTagLightsOff(line_t* line)
248 {
249     int                 i;
250     int                 j;
251     int                 min;
252     sector_t*           sector;
253     sector_t*           tsec;
254     line_t*             templine;
255 
256     sector = sectors;
257 
258     for (j = 0; j < numsectors; j++, sector++)
259     {
260         // for each sector
261         if (sector->tag == line->tag)
262         {
263             // for each sector with matching tag
264             min = sector->lightlevel;
265             for (i = 0; i < sector->linecount; i++)
266             {
267                 // for all lines in sector linelist
268                 templine = sector->linelist[i];
269                 tsec = getNextSector(templine,sector);
270                 if (!tsec)
271                     continue;
272                 // find any lower light level
273                 if (tsec->lightlevel < min)
274                     min = tsec->lightlevel;
275             }
276             sector->lightlevel = min;
277         }
278     }
279     return 1;
280 }
281 
282 
283 //
284 // TURN LINE'S TAG LIGHTS ON
285 // Turn tagged sectors to specified or max neighbor level.
286 //
287 //  bright: light level,  0= use max neighbor light level
288 //  return 1
EV_LightTurnOn(line_t * line,lightlev_t bright)289 int EV_LightTurnOn ( line_t* line, lightlev_t bright )
290 {
291     int         fsecn, j;
292     lightlev_t  sll;  // set or max light level
293     sector_t*   sector;
294     sector_t*   adjsec;
295     line_t*     adjline;
296 
297     fsecn = -1;
298     while ((fsecn = P_FindSectorFromLineTag(line, fsecn)) >= 0)
299     {
300         // For each sector with matching Tag
301         sll = bright; //SoM: 3/7/2000: Search for maximum per sector
302         sector = &sectors[fsecn];
303 
304         // For each sector with matching tag
305         if( bright == 0 )
306         {
307             // Find max adjacent light.
308             for (j = 0; j < sector->linecount; j++)
309             {
310                 // for each line in sector linelist
311                 adjline = sector->linelist[j];
312                 adjsec = getNextSector(adjline,sector);
313 
314                 if( !adjsec )
315                     continue;
316 
317                 // find any brighter light level
318                 if( sll < adjsec->lightlevel ) //SoM: 3/7/2000
319                     sll = adjsec->lightlevel;
320             }
321         }
322         sector->lightlevel = sll;
323 
324         if( !EN_boom_physics )  // old behavior
325             bright = sll;  // maximums are not independent
326     }
327     return 1;
328 }
329 
330 
331 //
332 // Spawn glowing light
333 //
334 
T_Glow(glow_t * gp)335 void T_Glow( glow_t* gp)
336 {
337     switch(gp->direction)
338     {
339       case -1:
340         // DOWN
341         gp->sector->lightlevel -= GLOWSPEED;
342         if (gp->sector->lightlevel <= gp->minlight)
343         {
344             gp->sector->lightlevel += GLOWSPEED;
345             gp->direction = 1;
346         }
347         break;
348 
349       case 1:
350         // UP
351         gp->sector->lightlevel += GLOWSPEED;
352         if (gp->sector->lightlevel >= gp->maxlight)
353         {
354             gp->sector->lightlevel -= GLOWSPEED;
355             gp->direction = -1;
356         }
357         break;
358     }
359 }
360 
361 
P_SpawnGlowingLight(sector_t * sector)362 void P_SpawnGlowingLight( sector_t*  sector)
363 {
364     glow_t* gp;
365 
366     gp = Z_Malloc( sizeof(*gp), PU_LEVSPEC, 0);
367     gp->thinker.function.acp1 = (actionf_p1) T_Glow;
368 
369     gp->sector = sector;
370     gp->minlight = P_FindMinSurroundingLight(sector,sector->lightlevel);
371     gp->maxlight = sector->lightlevel;
372     gp->direction = -1;
373 
374     sector->special &= ~0x1F; //SoM: 3/7/2000: Reset only non-generic types.
375 
376     P_AddThinker(& gp->thinker);
377 }
378 
379 
380 
381 // P_FadeLight()
382 //
383 // Fade all the lights in sectors with a particular tag to a new value
384 //
P_FadeLight(uint16_t tag,lightlev_t destvalue,lightlev_t speed)385 void P_FadeLight( uint16_t tag, lightlev_t destvalue, lightlev_t speed)
386 {
387   lightfader_t * lf;
388 
389   // search all sectors for ones with tag
390   int secnum = -1; // init search FindSector
391   while ((secnum = P_FindSectorFromTag(tag,secnum)) >= 0)
392   {
393       sector_t *sector = &sectors[secnum];
394       sector->lightingdata = sector;    // just set it to something
395 
396       lf = Z_Malloc(sizeof(*lf), PU_LEVSPEC, 0);
397       lf->thinker.function.acp1 = (actionf_p1)T_LightFade;
398 
399       P_AddThinker(&lf->thinker);       // add thinker
400 
401       lf->sector = sector;
402       lf->destlight = destvalue;
403       lf->speed = speed;
404   }
405 }
406 
407 
408 
409 // T_LightFade()
410 //
411 // Just fade the light level in a sector to a new level
412 //
413 
T_LightFade(lightfader_t * lf)414 void T_LightFade(lightfader_t * lf)
415 {
416   lightlev_t seclight = lf->sector->lightlevel;
417 
418   if(seclight < lf->destlight)
419   {
420     // increase the lightlevel
421     seclight += lf->speed; // move lightlevel
422     if(seclight >= lf->destlight)
423       goto achieved_target;
424   }
425   else
426   {
427     // decrease lightlevel
428     seclight -= lf->speed; // move lightlevel
429     if(seclight <= lf->destlight)
430       goto achieved_target;
431   }
432   lf->sector->lightlevel = seclight;
433   return;
434 
435 achieved_target:
436   // stop changing light level
437   lf->sector->lightlevel = lf->destlight;    // set to dest lightlevel
438 
439   lf->sector->lightingdata = NULL;          // clear lightingdata
440   P_RemoveThinker(&lf->thinker);            // remove thinker
441 }
442 
443 
444 // [WDJ] From MBF, PrBoom
445 // killough 10/98:
446 //
447 // Used for doors with gradual lighting effects.
448 // Turn light in tagged sectors to specified or max neighbor level.
449 //
450 //   line :  has sector TAG
451 //   level : light level fraction, 0=min, 1=max, else interpolate min..max
452 // Returns true
EV_LightTurnOnPartway(line_t * line,fixed_t level)453 int EV_LightTurnOnPartway(line_t *line, fixed_t level)
454 {
455   sector_t * sector;
456   int i, j;
457   int minll, maxll;
458 
459   if (level < 0)          // clip at extremes
460     level = 0;
461   if (level > FRACUNIT)
462     level = FRACUNIT;
463 
464   // search all sectors for ones with same tag as activating line
465   i = -1;
466   while ( (i = P_FindSectorFromLineTag(line,i)) >= 0 )
467   {
468       sector = &sectors[i];
469       maxll = 0;
470       minll = sector->lightlevel;
471 
472       for (j = 0; j < sector->linecount; j++)
473       {
474           sector_t * adjsec = getNextSector(sector->linelist[j], sector);
475           if(adjsec)
476           {
477               if( maxll < adjsec->lightlevel )
478                   maxll = adjsec->lightlevel;
479               if( minll > adjsec->lightlevel )
480                   minll = adjsec->lightlevel;
481           }
482       }
483 
484       // Set level in-between extremes
485       sector->lightlevel =
486         (level * maxll + (FRACUNIT-level) * minll) >> FRACBITS;
487   }
488   return 1;
489 }
490 
491 
492 // **** Corona and Dynamic lights
493 
494 //Hurdler: now we can change those values via FS :)
495 // RGBA( r, g, b, a )
496 // Indexed by sprite_light_ind_e
497 spr_light_t  sprite_light[NUMLIGHTS] = {
498     // type       offset x, y  coronas color, c_size,light color,l_radius, sqr radius computed at init
499    // LT_NOLIGHT
500 //    { SPLGT_none,     0.0f,   0.0f,        0x0,  24.0f,        0x0,   0.0f },
501     { SPLGT_none,     0, 0, {RGBA(0,0,0,0)},  24.0f, {RGBA(0,0,0,0)},   0.0f },
502     // weapons
503     // LT_PLASMA
504 //    { SPLGT_dynamic,  0.0f,   0.0f, 0x60ff7750,  24.0f, 0x20f77760,  80.0f },
505     { SPLGT_dynamic,  0, 0, {RGBA(0x50,0x77,0xff,0x60)},  24.0f, {RGBA(0x60,0x77,0xf7,0x20)},  80.0f },
506     // LT_PLASMAEXP
507 //    { SPLGT_dynamic,  0.0f,   0.0f, 0x60ff7750,  24.0f, 0x40f77760, 120.0f },
508     { SPLGT_dynamic,  0, 0, {RGBA(0x50,0x77,0xff,0x60)},  24.0f, {RGBA(0x60,0x77,0xf7,0x40)}, 120.0f },
509     // LT_ROCKET
510 //    { SPLGT_rocket,   0,   0, 0x606060f0,  20, 0x4020f7f7, 120 },
511     { SPLGT_rocket,   0, 0, {RGBA(0xf0,0x60,0x60,0x60)},  20.0f, {RGBA(0xf7,0xf7,0x20,0x40)}, 120.0f },
512     // LT_ROCKETEXP
513 //    { SPLGT_dynamic,  0,   0, 0x606060f0,  20, 0x6020f7f7, 200 },
514     { SPLGT_dynamic,  0, 0, {RGBA(0xf0,0x60,0x60,0x60)},  20.0f, {RGBA(0xf7,0xf7,0x20,0x60)}, 200.0f },
515     // LT_BFG
516 //    { SPLGT_dynamic,  0,   0, 0x6077f777, 120, 0x8060f060, 200 },
517     { SPLGT_dynamic,  0, 0, {RGBA(0x77,0xf7,0x77,0x60)}, 120.0f, {RGBA(0x60,0xf0,0x60,0x80)}, 200.0f },
518     // LT_BFGEXP
519 //    { SPLGT_dynamic,  0,   0, 0x6077f777, 120, 0x6060f060, 400 },
520     { SPLGT_dynamic,  0, 0, {RGBA(0x77,0xf7,0x77,0x60)}, 120.0f, {RGBA(0x60,0xf0,0x60,0x60)}, 400.0f },
521 
522     // tall lights
523     // LT_BLUETALL
524 //    { SPLGT_light,    0,  27, 0x80ff7070,  75, 0x40ff5050, 100 },
525 //    { SPLGT_light,    0,27, {RGBA(0x70,0x70,0xff,0x80)},  75.0f, {RGBA(0x50,0x50,0xff,0x40)}, 100.0f },
526     { SPLGT_dynamic|SPLGT_corona|SPLT_fire,    0,27, {RGBA(0x70,0x70,0xff,0x80)},  75.0f, {RGBA(0x50,0x50,0xff,0x40)}, 100.0f },
527     // LT_GREENTALL
528 //    { SPLGT_light,    0,  27, 0x5060ff60,  75, 0x4070ff70, 100 },
529 //    { SPLGT_light,    0,27, {RGBA(0x60,0xff,0x60,0x50)},  75.0f, {RGBA(0x70,0xff,0x70,0x40)}, 100.0f },
530     { SPLGT_dynamic|SPLGT_corona|SPLT_fire,    0,27, {RGBA(0x60,0xff,0x60,0x50)},  75.0f, {RGBA(0x70,0xff,0x70,0x40)}, 100.0f },
531     // LT_REDTALL
532 //    { SPLGT_light,    0,  27, 0x705070ff,  75, 0x405070ff, 100 },
533 //    { SPLGT_light,    0,27, {RGBA(0xff,0x70,0x50,0x70)},  75.0f, {RGBA(0xff,0x70,0x50,0x40)}, 100.0f },
534     { SPLGT_dynamic|SPLGT_corona|SPLT_fire,    0,27, {RGBA(0xff,0x70,0x50,0x70)},  75.0f, {RGBA(0xff,0x70,0x50,0x40)}, 100.0f },
535 
536     // small lights
537     // LT_BLUESMALL
538 //    { SPLGT_light,    0,  14, 0x80ff7070,  60, 0x40ff5050, 100 },
539 //    { SPLGT_light,    0,14, {RGBA(0x70,0x70,0xff,0x80)},  60.0f, {RGBA(0x50,0x50,0xff,0x40)}, 100.0f },
540     { SPLGT_dynamic|SPLGT_corona|SPLT_fire,    0,14, {RGBA(0x70,0x70,0xff,0x80)},  60.0f, {RGBA(0x50,0x50,0xff,0x40)}, 100.0f },
541     // LT_GREENSMALL
542 //    { SPLGT_light,    0,  14, 0x6070ff70,  60, 0x4070ff70, 100 },
543 //    { SPLGT_light,    0,14, {RGBA(0x70,0xff,0x70,0x60)},  60.0f, {RGBA(0x70,0xff,0x70,0x40)}, 100.0f },
544     { SPLGT_dynamic|SPLGT_corona|SPLT_fire,    0,14, {RGBA(0x70,0xff,0x70,0x60)},  60.0f, {RGBA(0x70,0xff,0x70,0x40)}, 100.0f },
545     // LT_REDSMALL
546 //    { SPLGT_light,    0,  14, 0x705070ff,  60, 0x405070ff, 100 },
547 //    { SPLGT_light,    0,14, {RGBA(0xff,0x70,0x50,0x70)},  60.0f, {RGBA(0xff,0x70,0x50,0x40)}, 100.0f },
548     { SPLGT_dynamic|SPLGT_corona|SPLT_fire,    0,14, {RGBA(0xff,0x70,0x50,0x70)},  60.0f, {RGBA(0xff,0x70,0x50,0x40)}, 100.0f },
549 
550     // other lights
551     // LT_TECHLAMP
552 //    { SPLGT_light,    0,  33, 0x80ffb0b0,  75, 0x40ffb0b0, 100 },
553 //    { SPLGT_light,    0,33, {RGBA(0xb0,0xb0,0xff,0x80)},  75.0f, {RGBA(0xb0,0xb0,0xff,0x40)}, 100.0f },
554     { SPLGT_dynamic|SPLGT_corona|SPLT_lamp,    0,33, {RGBA(0xb0,0xb0,0xff,0x80)},  75.0f, {RGBA(0xb0,0xb0,0xff,0x40)}, 100.0f },
555     // LT_TECHLAMP2
556 //    { SPLGT_light,    0,  33, 0x80ffb0b0,  75, 0x40ffb0b0, 100 },
557 //    { SPLGT_light,    0,26, {RGBA(0xb0,0xb0,0xff,0x80)},  60.0f, {RGBA(0xb0,0xb0,0xff,0x40)}, 100.0f },
558     { SPLGT_dynamic|SPLGT_corona|SPLT_lamp,    0,26, {RGBA(0xb0,0xb0,0xff,0x80)},  60.0f, {RGBA(0xb0,0xb0,0xff,0x40)}, 100.0f },
559     // LT_COLUMN
560 //    { SPLGT_light,    3,  19, 0x80b0f0f0,  60, 0x40b0f0f0, 100 },
561 //    { SPLGT_light,    3,19, {RGBA(0xf0,0xf0,0xb0,0x80)},  60.0f, {RGBA(0xf0,0xf0,0xb0,0x40)}, 100.0f },
562     { SPLGT_dynamic|SPLGT_corona|SPLT_lamp,    3,19, {RGBA(0xf0,0xf0,0xb0,0x80)},  60.0f, {RGBA(0xf0,0xf0,0xb0,0x40)}, 100.0f },
563     // LT_CANDLE
564 //    { SPLGT_light,    0,   6, 0x60b0f0f0,  20, 0x30b0f0f0,  30 },
565 //    { SPLGT_light,    0, 6, {RGBA(0xf0,0xf0,0xb0,0x60)},  20.0f, {RGBA(0xf0,0xf0,0xb0,0x30)},  30.0f },
566     { SPLGT_dynamic|SPLGT_corona|SPLT_fire,    0, 6, {RGBA(0xf0,0xf0,0xb0,0x60)},  20.0f, {RGBA(0xf0,0xf0,0xb0,0x30)},  30.0f },
567     // LT_CANDLEABRE
568 //    { SPLGT_light,    0,  30, 0x60b0f0f0,  60, 0x30b0f0f0, 100 },
569 //    { SPLGT_light,    0,30, {RGBA(0xf0,0xf0,0xb0,0x60)},  60.0f, {RGBA(0xf0,0xf0,0xb0,0x30)}, 100.0f },
570     { SPLGT_dynamic|SPLGT_corona|SPLT_fire,    0,30, {RGBA(0xf0,0xf0,0xb0,0x60)},  60.0f, {RGBA(0xf0,0xf0,0xb0,0x30)}, 100.0f },
571 
572     // monsters
573     // LT_REDBALL
574 //    { SPLGT_dynamic,   0,   0, 0x606060f0,   0, 0x302070ff, 100 },
575     { SPLGT_dynamic,   0, 0, {RGBA(0xf0,0x60,0x60,0x60)},   0.0f, {RGBA(0xff,0x70,0x20,0x30)}, 100.0f },
576     // LT_GREENBALL
577 //    { SPLGT_dynamic,   0,   0, 0x6077f777, 120, 0x3060f060, 100 },
578     { SPLGT_dynamic,   0, 0, {RGBA(0x77,0xf7,0x77,0x60)}, 120, {RGBA(0x60,0xf0,0x60,0x30)}, 100.0f },
579     // LT_ROCKET2
580 //    { SPLGT_dynamic,   0,   0, 0x606060f0,  20, 0x4020f7f7, 120 },
581     { SPLGT_dynamic,   0, 0, {RGBA(0xf0,0x60,0x60,0x60)},  20.0f, {RGBA(0xf7,0xf7,0x20,0x40)}, 120.0f },
582 
583     // weapons
584     // LT_FX03
585 //    { SPLGT_dynamic,   0,   0, 0x6077ff50,  24, 0x2077f760,  80 },
586     { SPLGT_dynamic,   0, 0, {RGBA(0x50,0xff,0x77,0x60)},  24.0f, {RGBA(0x60,0xf7,0x77,0x20)},  80.0f },
587     // LT_FX17
588 //    { SPLGT_dynamic,   0,   0, 0x60ff7750,  24, 0x40f77760,  80 },
589     { SPLGT_dynamic,   0, 0, {RGBA(0x50,0x77,0xff,0x60)},  24.0f, {RGBA(0x60,0x77,0xf7,0x40)},  80.0f },
590     // LT_FX00
591 //    { SPLGT_dynamic,   0,   0, 0x602020ff,  24, 0x302020f7,  80 },
592     { SPLGT_dynamic,   0, 0, {RGBA(0xff,0x20,0x20,0x60)},  24.0f, {RGBA(0xf7,0x20,0x20,0x30)},  80.0f },
593     // LT_FX08
594 //    { SPLGT_rocket,    0,   0, 0x606060f0,  20, 0x4020c0f7, 120 },
595     { SPLGT_rocket,    0, 0, {RGBA(0xf0,0x60,0x60,0x60)},  20.0f, {RGBA(0xf7,0xc0,0x20,0x40)}, 120.0f },
596     // LT_FX04
597 //    { SPLGT_rocket,    0,   0, 0x606060f0,  20, 0x2020c0f7, 120 },
598     { SPLGT_rocket,    0, 0, {RGBA(0xf0,0x60,0x60,0x60)},  20.0f, {RGBA(0xf7,0xc0,0x20,0x20)}, 120.0f },
599     // LT_FX02
600 //    { SPLGT_rocket,    0,   0, 0x606060f0,  20, 0x1720f7f7, 120 },
601     { SPLGT_rocket,    0, 0, {RGBA(0xf0,0x60,0x60,0x60)},  20.0f, {RGBA(0xf7,0xf7,0x20,0x17)}, 120.0f },
602 
603     //lights
604     // LT_WTRH
605 //    { SPLGT_dynamic,   0,  68, 0x606060f0,  60, 0x4020a0f7, 100 },
606     { SPLGT_dynamic,   0,68, {RGBA(0xf0,0x60,0x60,0x60)},  60.0f, {RGBA(0xf7,0xa0,0x20,0x40)}, 100.0f },
607     // LT_SRTC
608 //    { SPLGT_dynamic,   0,  27, 0x606060f0,  60, 0x4020a0f7, 100 },
609     { SPLGT_dynamic,   0,27, {RGBA(0xf0,0x60,0x60,0x60)},  60.0f, {RGBA(0xf7,0xa0,0x20,0x40)}, 100.0f },
610     // LT_CHDL
611 //    { SPLGT_dynamic,   0,  -8, 0x606060f0,  60, 0x502070f7, 100 },
612     { SPLGT_dynamic,   0,-8, {RGBA(0xf0,0x60,0x60,0x60)},  60.0f, {RGBA(0xf7,0x70,0x20,0x50)}, 100.0f },
613     // LT_KFR1
614 //    { SPLGT_dynamic,   0,  27, 0x606060f0,  60, 0x4020a0f7, 100 },
615 //    { SPLGT_dynamic,   0,27, {RGBA(0xf0,0x60,0x60,0x60)},  60.0f, {RGBA(0xf7,0xa0,0x20,0x40)}, 100.0f },
616     { SPLGT_dynamic|SPLGT_corona|SPLT_fire,   0,27, {RGBA(0xf0,0x60,0x60,0x60)},  60.0f, {RGBA(0xf7,0xa0,0x20,0x40)}, 100.0f },
617 };
618 
619 
620 
621 // sprite light indirection
622 // Indexed by spritenum_t
623 byte  sprite_light_ind[NUMSPRITES] = {
624     LT_NOLIGHT,     // SPR_TROO
625     LT_NOLIGHT,     // SPR_SHTG
626     LT_NOLIGHT,     // SPR_PUNG
627     LT_NOLIGHT,     // SPR_PISG
628     LT_NOLIGHT,     // SPR_PISF
629     LT_NOLIGHT,     // SPR_SHTF
630     LT_NOLIGHT,     // SPR_SHT2
631     LT_NOLIGHT,     // SPR_CHGG
632     LT_NOLIGHT,     // SPR_CHGF
633     LT_NOLIGHT,     // SPR_MISG
634     LT_NOLIGHT,     // SPR_MISF
635     LT_NOLIGHT,     // SPR_SAWG
636     LT_NOLIGHT,     // SPR_PLSG
637     LT_NOLIGHT,     // SPR_PLSF
638     LT_NOLIGHT,     // SPR_BFGG
639     LT_NOLIGHT,     // SPR_BFGF
640     LT_NOLIGHT,     // SPR_BLUD
641     LT_NOLIGHT,     // SPR_PUFF
642     LT_REDBALL,   // SPR_BAL1 * // imp
643     LT_REDBALL,   // SPR_BAL2 * // cacodemon
644     LT_PLASMA,    // SPR_PLSS * // plasma
645     LT_PLASMAEXP, // SPR_PLSE * // plasma explosion
646     LT_ROCKET,    // SPR_MISL * // rocket
647     LT_BFG,       // SPR_BFS1 * // bfg
648     LT_BFGEXP,    // SPR_BFE1 * // bfg explosion
649     LT_NOLIGHT,     // SPR_BFE2
650     LT_GREENBALL, // SPR_TFOG * teleport fog
651     LT_PLASMA,    // SPR_IFOG * respaw fog
652     LT_NOLIGHT,     // SPR_PLAY
653     LT_NOLIGHT,     // SPR_POSS
654     LT_NOLIGHT,     // SPR_SPOS
655     LT_NOLIGHT,     // SPR_VILE
656     LT_NOLIGHT,     // SPR_FIRE
657     LT_REDBALL,   // SPR_FATB * // revenent tracer
658     LT_NOLIGHT,     // SPR_FBXP
659     LT_NOLIGHT,     // SPR_SKEL
660     LT_ROCKET2,   // SPR_MANF * // mancubus
661     LT_NOLIGHT,     // SPR_FATT
662     LT_NOLIGHT,     // SPR_CPOS
663     LT_NOLIGHT,     // SPR_SARG
664     LT_NOLIGHT,     // SPR_HEAD
665     LT_GREENBALL, // SPR_BAL7 * // hell knight / baron of hell
666     LT_NOLIGHT,     // SPR_BOSS
667     LT_NOLIGHT,     // SPR_BOS2
668     LT_REDBALL,   // SPR_SKUL // lost soul
669     LT_NOLIGHT,     // SPR_SPID
670     LT_NOLIGHT,     // SPR_BSPI
671     LT_GREENBALL, // SPR_APLS * // arachnotron
672     LT_GREENBALL, // SPR_APBX * // arachnotron explosion
673     LT_NOLIGHT,     // SPR_CYBR
674     LT_NOLIGHT,     // SPR_PAIN
675     LT_NOLIGHT,     // SPR_SSWV
676     LT_NOLIGHT,     // SPR_KEEN
677     LT_NOLIGHT,     // SPR_BBRN
678     LT_NOLIGHT,     // SPR_BOSF
679     LT_NOLIGHT,     // SPR_ARM1
680     LT_NOLIGHT,     // SPR_ARM2
681     LT_NOLIGHT,     // SPR_BAR1
682     LT_ROCKETEXP, // SPR_BEXP // barrel explosion
683     LT_NOLIGHT,     // SPR_FCAN
684     LT_NOLIGHT,     // SPR_BON1
685     LT_NOLIGHT,     // SPR_BON2
686     LT_NOLIGHT,     // SPR_BKEY
687     LT_NOLIGHT,     // SPR_RKEY
688     LT_NOLIGHT,     // SPR_YKEY
689     LT_NOLIGHT,     // SPR_BSKU
690     LT_NOLIGHT,     // SPR_RSKU
691     LT_NOLIGHT,     // SPR_YSKU
692     LT_NOLIGHT,     // SPR_STIM
693     LT_NOLIGHT,     // SPR_MEDI
694     LT_NOLIGHT,     // SPR_SOUL
695     LT_NOLIGHT,     // SPR_PINV
696     LT_NOLIGHT,     // SPR_PSTR
697     LT_NOLIGHT,     // SPR_PINS
698     LT_NOLIGHT,     // SPR_MEGA
699     LT_NOLIGHT,     // SPR_SUIT
700     LT_NOLIGHT,     // SPR_PMAP
701     LT_NOLIGHT,     // SPR_PVIS
702     LT_NOLIGHT,     // SPR_CLIP
703     LT_NOLIGHT,     // SPR_AMMO
704     LT_NOLIGHT,     // SPR_ROCK
705     LT_NOLIGHT,     // SPR_BROK
706     LT_NOLIGHT,     // SPR_CELL
707     LT_NOLIGHT,     // SPR_CELP
708     LT_NOLIGHT,     // SPR_SHEL
709     LT_NOLIGHT,     // SPR_SBOX
710     LT_NOLIGHT,     // SPR_BPAK
711     LT_NOLIGHT,     // SPR_BFUG
712     LT_NOLIGHT,     // SPR_MGUN
713     LT_NOLIGHT,     // SPR_CSAW
714     LT_NOLIGHT,     // SPR_LAUN
715     LT_NOLIGHT,     // SPR_PLAS
716     LT_NOLIGHT,     // SPR_SHOT
717     LT_NOLIGHT,     // SPR_SGN2
718     LT_COLUMN,    // SPR_COLU * // yellow little light column
719     LT_NOLIGHT,     // SPR_SMT2
720     LT_NOLIGHT,     // SPR_GOR1
721     LT_NOLIGHT,     // SPR_POL2
722     LT_NOLIGHT,     // SPR_POL5
723     LT_NOLIGHT,     // SPR_POL4
724     LT_NOLIGHT,     // SPR_POL3
725     LT_NOLIGHT,     // SPR_POL1
726     LT_NOLIGHT,     // SPR_POL6
727     LT_NOLIGHT,     // SPR_GOR2
728     LT_NOLIGHT,     // SPR_GOR3
729     LT_NOLIGHT,     // SPR_GOR4
730     LT_NOLIGHT,     // SPR_GOR5
731     LT_NOLIGHT,     // SPR_SMIT
732     LT_NOLIGHT,     // SPR_COL1
733     LT_NOLIGHT,     // SPR_COL2
734     LT_NOLIGHT,     // SPR_COL3
735     LT_NOLIGHT,     // SPR_COL4
736     LT_CANDLE,    // SPR_CAND * // candle
737     LT_CANDLEABRE,// SPR_CBRA * // candleabre
738     LT_NOLIGHT,     // SPR_COL6
739     LT_NOLIGHT,     // SPR_TRE1
740     LT_NOLIGHT,     // SPR_TRE2
741     LT_NOLIGHT,     // SPR_ELEC
742     LT_NOLIGHT,     // SPR_CEYE
743     LT_NOLIGHT,     // SPR_FSKU
744     LT_NOLIGHT,     // SPR_COL5
745     LT_BLUETALL,  // SPR_TBLU *
746     LT_GREENTALL, // SPR_TGRN *
747     LT_REDTALL,   // SPR_TLT_RED *
748     LT_BLUESMALL, // SPR_SMBT *
749     LT_GREENSMALL,// SPR_SMGT *
750     LT_REDSMALL,  // SPR_SMRT *
751     LT_NOLIGHT,     // SPR_HDB1
752     LT_NOLIGHT,     // SPR_HDB2
753     LT_NOLIGHT,     // SPR_HDB3
754     LT_NOLIGHT,     // SPR_HDB4
755     LT_NOLIGHT,     // SPR_HDB5
756     LT_NOLIGHT,     // SPR_HDB6
757     LT_NOLIGHT,     // SPR_POB1
758     LT_NOLIGHT,     // SPR_POB2
759     LT_NOLIGHT,     // SPR_BRS1
760     LT_TECHLAMP,  // SPR_TLMP *
761     LT_TECHLAMP2, // SPR_TLP2 *
762     LT_NOLIGHT,     // SPR_SMOK
763     LT_NOLIGHT,     // SPR_SPLA
764     LT_NOLIGHT,     // SPR_TNT1
765 
766 // heretic sprites
767 
768     LT_NOLIGHT,     // SPR_IMPX,
769     LT_NOLIGHT,     // SPR_ACLO,
770     LT_NOLIGHT,     // SPR_PTN1,
771     LT_NOLIGHT,     // SPR_SHLD,
772     LT_NOLIGHT,     // SPR_SHD2,
773     LT_NOLIGHT,     // SPR_BAGH,
774     LT_NOLIGHT,     // SPR_SPMP,
775     LT_NOLIGHT,     // SPR_INVS,
776     LT_NOLIGHT,     // SPR_PTN2,
777     LT_NOLIGHT,     // SPR_SOAR,
778     LT_NOLIGHT,     // SPR_INVU,
779     LT_NOLIGHT,     // SPR_PWBK,
780     LT_NOLIGHT,     // SPR_EGGC,
781     LT_NOLIGHT,     // SPR_EGGM,
782     LT_NOLIGHT,     // SPR_FX01,
783     LT_NOLIGHT,     // SPR_SPHL,
784     LT_NOLIGHT,     // SPR_TRCH,
785     LT_NOLIGHT,     // SPR_FBMB,
786     LT_NOLIGHT,     // SPR_XPL1,
787     LT_NOLIGHT,     // SPR_ATLP,
788     LT_NOLIGHT,     // SPR_PPOD,
789     LT_NOLIGHT,     // SPR_AMG1,
790     LT_NOLIGHT,     // SPR_SPSH,
791     LT_NOLIGHT,     // SPR_LVAS,
792     LT_NOLIGHT,     // SPR_SLDG,
793     LT_NOLIGHT,     // SPR_SKH1,
794     LT_NOLIGHT,     // SPR_SKH2,
795     LT_NOLIGHT,     // SPR_SKH3,
796     LT_NOLIGHT,     // SPR_SKH4,
797     LT_CHDL,      // SPR_CHDL,
798     LT_SRTC,      // SPR_SRTC,
799     LT_NOLIGHT,     // SPR_SMPL,
800     LT_NOLIGHT,     // SPR_STGS,
801     LT_NOLIGHT,     // SPR_STGL,
802     LT_NOLIGHT,     // SPR_STCS,
803     LT_NOLIGHT,     // SPR_STCL,
804     LT_KFR1,      // SPR_KFR1,
805     LT_NOLIGHT,     // SPR_BARL,
806     LT_NOLIGHT,     // SPR_BRPL,
807     LT_NOLIGHT,     // SPR_MOS1,
808     LT_NOLIGHT,     // SPR_MOS2,
809     LT_WTRH,      // SPR_WTRH,
810     LT_NOLIGHT,     // SPR_HCOR,
811     LT_NOLIGHT,     // SPR_KGZ1,
812     LT_NOLIGHT,     // SPR_KGZB,
813     LT_NOLIGHT,     // SPR_KGZG,
814     LT_NOLIGHT,     // SPR_KGZY,
815     LT_NOLIGHT,     // SPR_VLCO,
816     LT_NOLIGHT,     // SPR_VFBL,
817     LT_NOLIGHT,     // SPR_VTFB,
818     LT_NOLIGHT,     // SPR_SFFI,
819     LT_NOLIGHT,     // SPR_TGLT,
820     LT_NOLIGHT,     // SPR_TELE,
821     LT_NOLIGHT,     // SPR_STFF,
822     LT_NOLIGHT,     // SPR_PUF3,
823     LT_NOLIGHT,     // SPR_PUF4,
824     LT_NOLIGHT,     // SPR_BEAK,
825     LT_NOLIGHT,     // SPR_WGNT,
826     LT_NOLIGHT,     // SPR_GAUN,
827     LT_NOLIGHT,     // SPR_PUF1,
828     LT_NOLIGHT,     // SPR_WBLS,
829     LT_NOLIGHT,     // SPR_BLSR,
830     LT_NOLIGHT,     // SPR_FX18,
831     LT_FX17,      // SPR_FX17,
832     LT_NOLIGHT,     // SPR_WMCE,
833     LT_NOLIGHT,     // SPR_MACE,
834     LT_FX02,      // SPR_FX02,
835     LT_NOLIGHT,     // SPR_WSKL,
836     LT_NOLIGHT,     // SPR_HROD,
837     LT_FX00,      // SPR_FX00,
838     LT_NOLIGHT,     // SPR_FX20,
839     LT_NOLIGHT,     // SPR_FX21,
840     LT_NOLIGHT,     // SPR_FX22,
841     LT_NOLIGHT,     // SPR_FX23,
842     LT_NOLIGHT,     // SPR_GWND,
843     LT_NOLIGHT,     // SPR_PUF2,
844     LT_NOLIGHT,     // SPR_WPHX,
845     LT_NOLIGHT,     // SPR_PHNX,
846     LT_FX04,      // SPR_FX04,
847     LT_FX08,      // SPR_FX08,
848     LT_NOLIGHT,     // SPR_FX09,
849     LT_NOLIGHT,     // SPR_WBOW,
850     LT_NOLIGHT,     // SPR_CRBW,
851     LT_FX03,      // SPR_FX03,
852 //    LT_NOLIGHT,     // SPR_BLOD,
853 //    LT_NOLIGHT,     // SPR_PLAY,
854     LT_NOLIGHT,     // SPR_FDTH,
855     LT_NOLIGHT,     // SPR_BSKL,
856     LT_NOLIGHT,     // SPR_CHKN,
857     LT_NOLIGHT,     // SPR_MUMM,
858     LT_NOLIGHT,     // SPR_FX15,
859     LT_NOLIGHT,     // SPR_BEAS,
860     LT_NOLIGHT,     // SPR_FRB1,
861     LT_NOLIGHT,     // SPR_SNKE,
862     LT_NOLIGHT,     // SPR_SNFX,
863     LT_NOLIGHT,     // SPR_HHEAD,
864     LT_NOLIGHT,     // SPR_FX05,
865     LT_NOLIGHT,     // SPR_FX06,
866     LT_NOLIGHT,     // SPR_FX07,
867     LT_NOLIGHT,     // SPR_CLNK,
868     LT_NOLIGHT,     // SPR_WZRD,
869     LT_NOLIGHT,     // SPR_FX11,
870     LT_NOLIGHT,     // SPR_FX10,
871     LT_NOLIGHT,     // SPR_KNIG,
872     LT_NOLIGHT,     // SPR_SPAX,
873     LT_NOLIGHT,     // SPR_RAXE,
874     LT_NOLIGHT,     // SPR_SRCR,
875     LT_NOLIGHT,     // SPR_FX14,
876     LT_NOLIGHT,     // SPR_SOR2,
877     LT_NOLIGHT,     // SPR_SDTH,
878     LT_NOLIGHT,     // SPR_FX16,
879     LT_NOLIGHT,     // SPR_MNTR,
880     LT_NOLIGHT,     // SPR_FX12,
881     LT_NOLIGHT,     // SPR_FX13,
882     LT_NOLIGHT,     // SPR_AKYY,
883     LT_NOLIGHT,     // SPR_BKYY,
884     LT_NOLIGHT,     // SPR_CKYY,
885     LT_NOLIGHT,     // SPR_AMG2,
886     LT_NOLIGHT,     // SPR_AMM1,
887     LT_NOLIGHT,     // SPR_AMM2,
888     LT_NOLIGHT,     // SPR_AMC1,
889     LT_NOLIGHT,     // SPR_AMC2,
890     LT_NOLIGHT,     // SPR_AMS1,
891     LT_NOLIGHT,     // SPR_AMS2,
892     LT_NOLIGHT,     // SPR_AMP1,
893     LT_NOLIGHT,     // SPR_AMP2,
894     LT_NOLIGHT,     // SPR_AMB1,
895     LT_NOLIGHT,     // SPR_AMB2,
896  };
897 
898 
Setup_sprite_light(byte mons_ball_light)899 void  Setup_sprite_light( byte  mons_ball_light )
900 {
901     if( mons_ball_light )
902     {
903         sprite_light_ind[SPR_BAL1] = LT_REDBALL;
904         sprite_light_ind[SPR_BAL2] = LT_REDBALL;
905         sprite_light_ind[SPR_MANF] = LT_ROCKET2;
906         sprite_light_ind[SPR_BAL7] = LT_GREENBALL;
907         sprite_light_ind[SPR_APLS] = LT_GREENBALL;
908         sprite_light_ind[SPR_APBX] = LT_GREENBALL;
909         sprite_light_ind[SPR_SKUL] = LT_REDBALL;
910         sprite_light_ind[SPR_FATB] = LT_REDBALL;
911     }
912     else
913     {
914         sprite_light_ind[SPR_BAL1] = LT_NOLIGHT;
915         sprite_light_ind[SPR_BAL2] = LT_NOLIGHT;
916         sprite_light_ind[SPR_MANF] = LT_NOLIGHT;
917         sprite_light_ind[SPR_BAL7] = LT_NOLIGHT;
918         sprite_light_ind[SPR_APLS] = LT_NOLIGHT;
919         sprite_light_ind[SPR_APBX] = LT_NOLIGHT;
920         sprite_light_ind[SPR_SKUL] = LT_NOLIGHT;
921         sprite_light_ind[SPR_FATB] = LT_NOLIGHT;
922     }
923 }
924 
925 
926 void CV_MonBall_OnChange( void );
927 void CV_corona_OnChange( void );
928 
929 
930 //consvar_t cv_dynamiclight = {"dynamiclighting",  "On", CV_SAVE, CV_OnOff };
931 //consvar_t cv_staticlight  = {"staticlighting",   "On", CV_SAVE, CV_OnOff };
932 //#ifdef CORONA_CHOICE
933 //CV_PossibleValue_t corona_draw_cons_t[] = { {0, "Off"}, {1, "Sprite"}, {2, "Dyn"}, {3, "Auto"}, {0, NULL} };
934 //consvar_t cv_corona_draw     = {"corona_draw",    "Auto", CV_SAVE, corona_cons_t };
935 //#else
936 //consvar_t cv_corona_draw         = {"corona_draw",    "On", CV_SAVE, CV_OnOff };
937 //#endif
938 CV_PossibleValue_t corona_cons_t[] = { {0, "Off"}, {1, "Special"}, {2, "Most"}, {14, "Dim"}, {15, "All"}, {16, "Bright"}, {20, "Old"}, {0, NULL} };
939 consvar_t cv_corona         = {"corona",    "All", CV_SAVE|CV_CALL, corona_cons_t, CV_corona_OnChange};
940 consvar_t cv_coronasize      = {"coronasize",        "1", CV_SAVE| CV_FLOAT, NULL };
941 CV_PossibleValue_t corona_draw_mode_cons_t[] = { {0, "Blend"}, {1, "Blend_BG"}, {2, "Additive"}, {3, "Additive_BG"}, {4, "Add_Limit"}, {0, NULL} };
942 consvar_t cv_corona_draw_mode = {"corona_draw_mode", "2", CV_SAVE, corona_draw_mode_cons_t, NULL};
943 // Monster ball weapon light
944 consvar_t cv_monball_light  = {"monball_light", "On", CV_SAVE|CV_CALL, CV_OnOff, CV_MonBall_OnChange };
945 
CV_MonBall_OnChange(void)946 void CV_MonBall_OnChange( void )
947 {
948     Setup_sprite_light( cv_monball_light.EV );
949 }
950 
CV_corona_OnChange(void)951 void CV_corona_OnChange( void )
952 {
953     int i;
954     // Force light setup, without another test.
955     for( i=0; i<NUMLIGHTS; i++ )
956     {
957         sprite_light[i].impl_flags |= SLI_changed;
958     }
959 }
960 
961 
962