DOOM64-RE

DOOM 64 Reverse Engineering
Log | Files | Refs | README | LICENSE

p_lights.c (16051B)


      1 #include "doomdef.h"
      2 #include "p_local.h"
      3 
      4 /*================================================================== */
      5 /*================================================================== */
      6 /* */
      7 /*							BROKEN LIGHT FLASHING */
      8 /* */
      9 /*================================================================== */
     10 /*================================================================== */
     11 
     12 /*================================================================== */
     13 /* */
     14 /*	T_FireFlicker */
     15 /* */
     16 /*	Exclusive Psx Doom From PC Doom */
     17 /* */
     18 /*================================================================== */
     19 
     20 void T_FireFlicker(fireflicker_t *flick) // 80015740
     21 {
     22 	int	amount;
     23 
     24 	if (--flick->count)
     25 		return;
     26 
     27     if(flick->sector->special != flick->special)
     28     {
     29         P_RemoveThinker(&flick->thinker);
     30         return;
     31     }
     32 
     33     amount = (P_Random() & 31);
     34     flick->sector->lightlevel = amount;
     35     flick->count = 3;
     36 }
     37 
     38 /*================================================================== */
     39 /* */
     40 /*	P_SpawnFireFlicker */
     41 /* */
     42 /*================================================================== */
     43 
     44 void P_SpawnFireFlicker(sector_t *sector) // 800157B4
     45 {
     46 	fireflicker_t *flick;
     47 
     48 	flick = Z_Malloc(sizeof(*flick), PU_LEVSPEC, 0);
     49 	P_AddThinker(&flick->thinker);
     50 	flick->thinker.function = T_FireFlicker;
     51 	flick->sector = sector;
     52 	flick->special = sector->special;
     53 	flick->count = 3;
     54 }
     55 
     56 /*================================================================== */
     57 /* */
     58 /*	Spawn glowing light */
     59 /* */
     60 /*================================================================== */
     61 
     62 void T_Glow(glow_t *g) // 80015820
     63 {
     64     if(--g->count)
     65         return;
     66 
     67     if(g->sector->special != g->special)
     68     {
     69         P_RemoveThinker(&g->thinker);
     70         return;
     71     }
     72 
     73     g->count = 2;
     74 
     75 	switch(g->direction)
     76 	{
     77 		case -1:		/* DOWN */
     78 			g->sector->lightlevel -= GLOWSPEED;
     79 			if (g->sector->lightlevel < g->minlight)
     80 			{
     81 				g->sector->lightlevel = g->minlight;
     82 
     83 				if(g->type == PULSERANDOM)
     84                     g->maxlight = (P_Random() & 31) + 17;
     85 
     86 				g->direction = 1;
     87 			}
     88 			break;
     89 		case 1:			/* UP */
     90 			g->sector->lightlevel += GLOWSPEED;
     91 			if (g->maxlight < g->sector->lightlevel)
     92 			{
     93 				g->sector->lightlevel = g->maxlight;
     94 
     95 				if(g->type == PULSERANDOM)
     96                     g->minlight = (P_Random() & 15);
     97 
     98 				g->direction = -1;
     99 			}
    100 			break;
    101 	}
    102 }
    103 
    104 /*================================================================== */
    105 /* */
    106 /*	P_SpawnGlowingLight */
    107 /* */
    108 /*================================================================== */
    109 
    110 void P_SpawnGlowingLight(sector_t *sector, glowtype_e type) // 80015968
    111 {
    112 	glow_t *g;
    113 
    114 	g = Z_Malloc(sizeof(*g), PU_LEVSPEC, 0);
    115 	P_AddThinker(&g->thinker);
    116 	g->thinker.function = T_Glow;
    117 	g->sector = sector;
    118 	g->count = 2;
    119 	g->direction = 1;
    120 	g->minlight = 0;
    121 	g->type = type;
    122 	g->special = sector->special;
    123 
    124 	switch (type)
    125 	{
    126 	case PULSENORMAL:
    127 		g->maxlight = 32;
    128 		break;
    129 	case PULSESLOW:
    130 	case PULSERANDOM:
    131 		g->maxlight = 48;
    132 		break;
    133 	}
    134 }
    135 
    136 /*================================================================== */
    137 /* */
    138 /*	T_LightFlash */
    139 /* */
    140 /*	After the map has been loaded, scan each sector for specials */
    141 /*	that spawn thinkers */
    142 /* */
    143 /*================================================================== */
    144 void T_LightFlash (lightflash_t *flash) // 80015A14
    145 {
    146 	if (--flash->count)
    147 		return;
    148 
    149     if(flash->sector->special != flash->special)
    150     {
    151         P_RemoveThinker(&flash->thinker);
    152         return;
    153     }
    154 
    155 	if (flash->sector->lightlevel == 32)
    156 	{
    157 		flash->sector->lightlevel = 0;
    158 		flash->count = (P_Random()&7)+1;
    159 	}
    160 	else
    161 	{
    162 		flash->sector->lightlevel = 32;
    163 		flash->count = (P_Random()&32)+1;
    164 	}
    165 }
    166 
    167 /*================================================================== */
    168 /* */
    169 /*	P_SpawnLightFlash */
    170 /* */
    171 /*	After the map has been loaded, scan each sector for specials that spawn thinkers */
    172 /* */
    173 /*================================================================== */
    174 void P_SpawnLightFlash (sector_t *sector) // 80015AB4
    175 {
    176 	lightflash_t	*flash;
    177 
    178 	sector->special = 0;		/* nothing special about it during gameplay */
    179 
    180 	flash = Z_Malloc ( sizeof(*flash), PU_LEVSPEC, 0);
    181 	P_AddThinker (&flash->thinker);
    182 	flash->thinker.function = T_LightFlash;
    183 	flash->sector = sector;
    184 	flash->special = sector->special;
    185 	flash->count = (P_Random()&63)+1;
    186 }
    187 
    188 /*================================================================== */
    189 /* */
    190 /*							STROBE LIGHT FLASHING */
    191 /* */
    192 /*================================================================== */
    193 
    194 /*================================================================== */
    195 /* */
    196 /*	T_StrobeFlash */
    197 /* */
    198 /*	After the map has been loaded, scan each sector for specials that spawn thinkers */
    199 /* */
    200 /*================================================================== */
    201 void T_StrobeFlash (strobe_t *flash) // 80015B28
    202 {
    203 	if (--flash->count)
    204 		return;
    205 
    206     if(flash->sector->special != flash->special)
    207     {
    208         P_RemoveThinker(&flash->thinker);
    209         return;
    210     }
    211 
    212 	if (flash->sector->lightlevel == 0)
    213 	{
    214 		flash->sector->lightlevel = flash->maxlight;
    215 		flash->count = flash->brighttime;
    216 	}
    217 	else
    218 	{
    219 		flash->sector->lightlevel = 0;
    220 		flash->count = flash->darktime;
    221 	}
    222 }
    223 
    224 /*================================================================== */
    225 /* */
    226 /*	P_SpawnLightFlash */
    227 /* */
    228 /*	After the map has been loaded, scan each sector for specials that spawn thinkers */
    229 /* */
    230 /*================================================================== */
    231 
    232 void P_SpawnStrobeFlash (sector_t *sector,int fastOrSlow) // 80015BB4
    233 {
    234 	strobe_t	*flash;
    235 
    236 	flash = Z_Malloc ( sizeof(*flash), PU_LEVSPEC, 0);
    237 	P_AddThinker (&flash->thinker);
    238 	flash->thinker.function = T_StrobeFlash;
    239 	flash->sector = sector;
    240 	flash->special = sector->special;
    241 	flash->brighttime = STROBEBRIGHT;
    242 	flash->maxlight = 16;
    243 	flash->darktime = fastOrSlow;
    244     flash->count = (P_Random()&7)+1;
    245 }
    246 
    247 /*================================================================== */
    248 /* */
    249 /*	P_SpawnStrobeAltFlash */
    250 /*	Alternate variation of P_SpawnStrobeFlash */
    251 /* */
    252 /*================================================================== */
    253 void P_SpawnStrobeAltFlash (sector_t *sector,int fastOrSlow) // 80015C44
    254 {
    255 	strobe_t	*flash;
    256 
    257 	flash = Z_Malloc ( sizeof(*flash), PU_LEVSPEC, 0);
    258 	P_AddThinker (&flash->thinker);
    259 	flash->thinker.function = T_StrobeFlash;
    260 	flash->sector = sector;
    261 	flash->special = sector->special;
    262 	flash->brighttime = STROBEBRIGHT2;
    263 	flash->maxlight = 127;
    264 	flash->darktime = fastOrSlow;
    265     flash->count = 1;
    266 }
    267 
    268 /*================================================================== */
    269 /* */
    270 /*	Start strobing lights (usually from a trigger) */
    271 /* */
    272 /*================================================================== */
    273 int EV_StartLightStrobing(line_t *line) // 80015CC4
    274 {
    275 	int	secnum;
    276 	sector_t	*sec;
    277 	int ok;
    278 
    279 	ok = 0;
    280 	secnum = -1;
    281 	while ((secnum = P_FindSectorFromLineTag(line->tag,secnum)) >= 0)
    282 	{
    283 		sec = &sectors[secnum];
    284 		if (sec->specialdata)
    285 			continue;
    286 
    287         ok = 1;
    288 		P_SpawnStrobeFlash (sec,SLOWDARK);
    289 	}
    290 
    291 	return ok;
    292 }
    293 
    294 /*================================================================== */
    295 /* */
    296 /*							SPECIALS FUNCTIONS */
    297 /* */
    298 /*================================================================== */
    299 
    300 /*================================================================== */
    301 /* */
    302 /*	Changes a sector light index */
    303 /*	This doesn't appear to be used at all */
    304 /* */
    305 /*================================================================== */
    306 int P_ModifySectorColor(line_t* line, int index, int type) // 80015D6C
    307 {
    308     int secnum;
    309     int rtn;
    310     sector_t* sec;
    311 
    312     secnum = -1;
    313     rtn = 0;
    314 
    315     while((secnum = P_FindSectorFromLineTag(line->tag, secnum)) >= 0)
    316     {
    317         sec = &sectors[secnum];
    318         rtn = 1;
    319 
    320         switch(type)
    321         {
    322         case 0:
    323             sec->colors[1] = index;
    324             break;
    325         case 1:
    326             sec->colors[0] = index;
    327             break;
    328         case 2:
    329             sec->colors[2] = index;
    330             break;
    331         case 3:
    332             sec->colors[3] = index;
    333             break;
    334         case 4:
    335             sec->colors[4] = index;
    336             break;
    337         }
    338     }
    339 
    340     return rtn;
    341 }
    342 
    343 /*================================================================== */
    344 /* */
    345 /*	T_SequenceGlow */
    346 /* */
    347 /*================================================================== */
    348 void T_SequenceGlow(sequenceglow_t *seq) // 80015E5C
    349 {
    350     sector_t *next;
    351     int i;
    352 
    353     if(--seq->count)
    354         return;
    355 
    356     if(seq->sector->special != seq->special)
    357     {
    358         P_RemoveThinker(&seq->thinker);
    359         return;
    360     }
    361 
    362     seq->count = 1;
    363 
    364     switch(seq->start)
    365 	{
    366 		case -1:		/* DOWN */
    367 			seq->sector->lightlevel -= GLOWSPEED;
    368 
    369 			if(seq->sector->lightlevel > 0)
    370                 return;
    371 
    372             seq->sector->lightlevel = 0;
    373 
    374             if (seq->headsector == NULL)
    375             {
    376                 seq->sector->special = 0;
    377                 P_RemoveThinker(&seq->thinker);
    378                 return;
    379             }
    380 
    381             seq->start = 0;
    382 			break;
    383         case 0:		    /* CHECK */
    384             if(!seq->headsector->lightlevel)
    385                 return;
    386 
    387             seq->start = 1;
    388             break;
    389 		case 1:			/* UP */
    390 			seq->sector->lightlevel += GLOWSPEED;
    391 			if (seq->sector->lightlevel < (SEQUENCELIGHTMAX + 1))
    392 			{
    393                 if(seq->sector->lightlevel != 8)
    394                     return;
    395 
    396                 if(seq->sector->linecount <= 0)
    397                     return;
    398 
    399                 for(i = 0; i < seq->sector->linecount; i++)
    400                 {
    401                     next = seq->sector->lines[i]->backsector;
    402 
    403                     if(next && (next->special == 0))
    404                     {
    405                         if(next->tag == (seq->sector->tag + 1))
    406                         {
    407                             next->special = seq->sector->special;
    408                             P_SpawnSequenceLight(next, false);
    409                         }
    410                     }
    411                 }
    412 			}
    413 			else
    414 			{
    415                 seq->sector->lightlevel = SEQUENCELIGHTMAX;
    416                 seq->start = -1;
    417 			}
    418 			break;
    419 	}
    420 }
    421 
    422 /*================================================================== */
    423 /* */
    424 /*	P_SpawnSequenceLight */
    425 /* */
    426 /*================================================================== */
    427 void P_SpawnSequenceLight(sector_t* sector, boolean first) // 80016038
    428 {
    429     sequenceglow_t *seq;
    430     sector_t *headsector;
    431     int i;
    432 
    433     headsector = NULL;
    434 
    435     if(first)
    436     {
    437         for(i = 0; i < sector->linecount; i++)
    438         {
    439             headsector = sector->lines[i]->frontsector;
    440 
    441             if ((headsector != sector) && (sector->tag == headsector->tag))
    442                 break;
    443         }
    444 
    445         if(headsector == NULL)
    446             return;
    447     }
    448 
    449     seq = Z_Malloc ( sizeof(*seq), PU_LEVSPEC, 0);
    450 	P_AddThinker (&seq->thinker);
    451 	seq->thinker.function = T_SequenceGlow;
    452 	seq->sector = sector;
    453 	seq->special = sector->special;
    454     seq->count = 1;
    455     seq->index = sector->tag;
    456     seq->start = (headsector == NULL ? 1 : 0);
    457     seq->headsector = headsector;
    458 }
    459 
    460 /*================================================================== */
    461 /* */
    462 /*	P_UpdateLightThinker */
    463 /* */
    464 /*================================================================== */
    465 
    466 extern maplights_t *maplights;     // 800A5EA4
    467 
    468 void P_UpdateLightThinker(int destlight, int srclight) // 80016118
    469 {
    470     lightmorph_t *lt;
    471     byte r, g, b;
    472     int rgb;
    473 
    474     r = g = b = (byte)destlight;
    475 
    476     if (destlight > 255)
    477     {
    478         r = maplights[destlight-256].r;
    479         g = maplights[destlight-256].b;
    480         b = maplights[destlight-256].g;
    481     }
    482 
    483     maplights[srclight-256].r = r;
    484     maplights[srclight-256].b = g;
    485     maplights[srclight-256].g = b;
    486 
    487     rgb = lights[srclight].rgba;
    488 
    489     lt = Z_Malloc ( sizeof(*lt), PU_LEVSPEC, 0);
    490     P_AddThinker(&lt->thinker);
    491     lt->thinker.function = T_LightMorph;
    492     lt->inc = 0;
    493     lt->dest = destlight;
    494     lt->src = srclight;
    495     lt->r = (rgb >> 24) & 0xff;
    496     lt->g = (rgb >> 16) & 0xff;
    497     lt->b = (rgb >>  8) & 0xff;
    498 }
    499 
    500 /*================================================================== */
    501 /* */
    502 /*	T_LightMorph */
    503 /* */
    504 /*================================================================== */
    505 void T_LightMorph(lightmorph_t *lt) // 80016244
    506 {
    507     int rgb;
    508 
    509     lt->inc += 4;
    510 
    511     if(lt->inc > 256)
    512     {
    513         P_RemoveThinker(&lt->thinker);
    514         return;
    515     }
    516 
    517     rgb = lights[lt->dest].rgba;
    518     lights[lt->src].rgba =
    519     (lt->r + ((lt->inc * (((rgb >> 24) & 0xff) - lt->r)) >> 8)) << 24 |
    520     (lt->g + ((lt->inc * (((rgb >> 16) & 0xff) - lt->g)) >> 8)) << 16 |
    521     (lt->b + ((lt->inc * (((rgb >>  8) & 0xff) - lt->b)) >> 8)) <<  8 | 0xff;
    522 }
    523 
    524 /*================================================================== */
    525 /* */
    526 /*	P_ChangeLightByTag */
    527 /*	This has to be early stuff because this is only */
    528 /*	used once in the entire game and the only place where */
    529 /*	internal light tags are used.. */
    530 /* */
    531 /*================================================================== */
    532 int P_ChangeLightByTag(int tag1, int tag2) // 80016320
    533 {
    534     int destlight;
    535     int srclight;
    536     int rtn;
    537 
    538     destlight = P_FindLightFromLightTag(tag1,-1);
    539     if (destlight < 0)
    540         return 0;
    541 
    542     srclight = -1;
    543     rtn = 0;
    544 
    545     while((srclight = P_FindLightFromLightTag(tag2, srclight)) >= 256)
    546     {
    547         rtn = 1;
    548         P_UpdateLightThinker(destlight, srclight);
    549     }
    550 
    551     return rtn;
    552 }
    553 
    554 /*================================================================== */
    555 /* */
    556 /*	P_DoSectorLightChange */
    557 /* */
    558 /*================================================================== */
    559 int P_DoSectorLightChange(int tag1,int tag2) // 800163B8
    560 {
    561     sector_t *sec1;
    562     sector_t *sec2;
    563     int secnum;
    564     int rtn;
    565 
    566     secnum = P_FindSectorFromLineTag(tag1, -1);
    567     if (secnum < 0)
    568         return 0;
    569 
    570     sec2 = &sectors[secnum];
    571 
    572     secnum = -1;
    573     rtn = 0;
    574 
    575     while((secnum = P_FindSectorFromLineTag(tag2, secnum)) >= 0)
    576     {
    577         sec1 = &sectors[secnum];
    578         rtn = 1;
    579 
    580         if (sec1->colors[0] >= 256)
    581             P_UpdateLightThinker(sec2->colors[0], sec1->colors[0]);
    582 
    583         if (sec1->colors[1] >= 256)
    584             P_UpdateLightThinker(sec2->colors[1], sec1->colors[1]);
    585 
    586         if (sec1->colors[2] >= 256)
    587             P_UpdateLightThinker(sec2->colors[2], sec1->colors[2]);
    588 
    589         if (sec1->colors[3] >= 256)
    590             P_UpdateLightThinker(sec2->colors[3], sec1->colors[3]);
    591 
    592         if (sec1->colors[4] >= 256)
    593             P_UpdateLightThinker(sec2->colors[4], sec1->colors[4]);
    594     }
    595 
    596     return rtn;
    597 }
    598 
    599 /*================================================================== */
    600 /* */
    601 /*	T_Combine */
    602 /* */
    603 /*================================================================== */
    604 void T_Combine(combine_t *combine) // 80016524
    605 {
    606     sector_t *sector;
    607 
    608     sector = combine->sector;
    609     if (sector->special != combine->special)
    610     {
    611         P_RemoveThinker(&combine->thinker);
    612         return;
    613     }
    614 
    615     sector->lightlevel = combine->combiner->lightlevel;
    616 }
    617 
    618 /*================================================================== */
    619 /* */
    620 /*	P_CombineLightSpecials */
    621 /* */
    622 /*================================================================== */
    623 void P_CombineLightSpecials(sector_t *sector) // 80016578
    624 {
    625     think_t func;
    626 	thinker_t *thinker;
    627 	combine_t *combine;
    628 
    629 	switch(sector->special)
    630 	{
    631 		case 1:
    632 			func = T_LightFlash;
    633 			break;
    634 		case 2:
    635         case 3:
    636         case 202:
    637         case 204:
    638         //case 205:
    639         case 206:
    640         case 208:
    641 			func = T_StrobeFlash;
    642 			break;
    643 		case 8:
    644         case 9:
    645         case 11:
    646 			func = T_Glow;
    647 			break;
    648 		case 17:
    649 			func = T_FireFlicker;
    650 			break;
    651 		default:
    652 			return;
    653 	}
    654 
    655 	for(thinker = thinkercap.next; thinker != &thinkercap; thinker = thinker->next)
    656 	{
    657 		if(func != thinker->function)
    658 			continue;
    659 
    660         combine = Z_Malloc ( sizeof(*combine), PU_LEVSPEC, 0);
    661         P_AddThinker(&combine->thinker);
    662         combine->thinker.function = T_Combine;
    663         combine->sector = sector;
    664         combine->combiner = ((combine_t *)thinker)->sector;
    665         combine->special = sector->special;
    666 		return;
    667 	}
    668 }