mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-04-07 10:34:48 +00:00
Merge remote-tracking branch 'origin/master' into le-fadefof
This commit is contained in:
commit
899e8ef2a0
16 changed files with 1375 additions and 333 deletions
|
@ -1126,7 +1126,7 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum,
|
|||
else
|
||||
{
|
||||
lightnum = *list[i].lightlevel;
|
||||
colormap = list[i].extra_colormap;
|
||||
colormap = *list[i].extra_colormap;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3486,12 +3486,12 @@ static void HWR_Subsector(size_t num)
|
|||
light = R_GetPlaneLight(gr_frontsector, locFloorHeight, false);
|
||||
if (gr_frontsector->floorlightsec == -1)
|
||||
floorlightlevel = *gr_frontsector->lightlist[light].lightlevel;
|
||||
floorcolormap = gr_frontsector->lightlist[light].extra_colormap;
|
||||
floorcolormap = *gr_frontsector->lightlist[light].extra_colormap;
|
||||
|
||||
light = R_GetPlaneLight(gr_frontsector, locCeilingHeight, false);
|
||||
if (gr_frontsector->ceilinglightsec == -1)
|
||||
ceilinglightlevel = *gr_frontsector->lightlist[light].lightlevel;
|
||||
ceilingcolormap = gr_frontsector->lightlist[light].extra_colormap;
|
||||
ceilingcolormap = *gr_frontsector->lightlist[light].extra_colormap;
|
||||
}
|
||||
|
||||
sub->sector->extra_colormap = gr_frontsector->extra_colormap;
|
||||
|
@ -3617,7 +3617,7 @@ static void HWR_Subsector(size_t num)
|
|||
*rover->bottomheight,
|
||||
*gr_frontsector->lightlist[light].lightlevel,
|
||||
rover->alpha-1 > 255 ? 255 : rover->alpha-1, rover->master->frontsector, PF_Translucent,
|
||||
false, gr_frontsector->lightlist[light].extra_colormap);
|
||||
false, *gr_frontsector->lightlist[light].extra_colormap);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
|
@ -3625,7 +3625,7 @@ static void HWR_Subsector(size_t num)
|
|||
HWR_GetFlat(levelflats[*rover->bottompic].lumpnum);
|
||||
light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false);
|
||||
HWR_RenderPlane(NULL, &extrasubsectors[num], false, *rover->bottomheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->bottompic].lumpnum,
|
||||
rover->master->frontsector, 255, false, gr_frontsector->lightlist[light].extra_colormap);
|
||||
rover->master->frontsector, 255, false, *gr_frontsector->lightlist[light].extra_colormap);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3680,7 +3680,7 @@ static void HWR_Subsector(size_t num)
|
|||
*rover->topheight,
|
||||
*gr_frontsector->lightlist[light].lightlevel,
|
||||
rover->alpha-1 > 255 ? 255 : rover->alpha-1, rover->master->frontsector, PF_Translucent,
|
||||
false, gr_frontsector->lightlist[light].extra_colormap);
|
||||
false, *gr_frontsector->lightlist[light].extra_colormap);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
@ -3689,7 +3689,7 @@ static void HWR_Subsector(size_t num)
|
|||
HWR_GetFlat(levelflats[*rover->toppic].lumpnum);
|
||||
light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false);
|
||||
HWR_RenderPlane(NULL, &extrasubsectors[num], true, *rover->topheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->toppic].lumpnum,
|
||||
rover->master->frontsector, 255, false, gr_frontsector->lightlist[light].extra_colormap);
|
||||
rover->master->frontsector, 255, false, *gr_frontsector->lightlist[light].extra_colormap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4200,8 +4200,8 @@ static void HWR_DrawSpriteShadow(gr_vissprite_t *spr, GLPatch_t *gpatch, float t
|
|||
if (!(spr->mobj->frame & FF_FULLBRIGHT))
|
||||
lightlevel = *sector->lightlist[light].lightlevel;
|
||||
|
||||
if (sector->lightlist[light].extra_colormap)
|
||||
colormap = sector->lightlist[light].extra_colormap;
|
||||
if (*sector->lightlist[light].extra_colormap)
|
||||
colormap = *sector->lightlist[light].extra_colormap;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4362,7 +4362,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
|
|||
|
||||
// Start with the lightlevel and colormap from the top of the sprite
|
||||
lightlevel = *list[sector->numlights - 1].lightlevel;
|
||||
colormap = list[sector->numlights - 1].extra_colormap;
|
||||
colormap = *list[sector->numlights - 1].extra_colormap;
|
||||
i = 0;
|
||||
temp = FLOAT_TO_FIXED(realtop);
|
||||
|
||||
|
@ -4378,7 +4378,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
|
|||
{
|
||||
if (!(spr->mobj->frame & FF_FULLBRIGHT))
|
||||
lightlevel = *list[i-1].lightlevel;
|
||||
colormap = list[i-1].extra_colormap;
|
||||
colormap = *list[i-1].extra_colormap;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -4386,7 +4386,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
|
|||
i = R_GetPlaneLight(sector, temp, false);
|
||||
if (!(spr->mobj->frame & FF_FULLBRIGHT))
|
||||
lightlevel = *list[i].lightlevel;
|
||||
colormap = list[i].extra_colormap;
|
||||
colormap = *list[i].extra_colormap;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < sector->numlights; i++)
|
||||
|
@ -4402,7 +4402,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
|
|||
{
|
||||
if (!(spr->mobj->frame & FF_FULLBRIGHT))
|
||||
lightlevel = *list[i].lightlevel;
|
||||
colormap = list[i].extra_colormap;
|
||||
colormap = *list[i].extra_colormap;
|
||||
}
|
||||
|
||||
#ifdef ESLOPE
|
||||
|
@ -4734,8 +4734,8 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr)
|
|||
if (!(spr->mobj->frame & FF_FULLBRIGHT))
|
||||
lightlevel = *sector->lightlist[light].lightlevel;
|
||||
|
||||
if (sector->lightlist[light].extra_colormap)
|
||||
colormap = sector->lightlist[light].extra_colormap;
|
||||
if (*sector->lightlist[light].extra_colormap)
|
||||
colormap = *sector->lightlist[light].extra_colormap;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1194,8 +1194,8 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
|
|||
if (!(spr->mobj->frame & FF_FULLBRIGHT))
|
||||
lightlevel = *sector->lightlist[light].lightlevel;
|
||||
|
||||
if (sector->lightlist[light].extra_colormap)
|
||||
colormap = sector->lightlist[light].extra_colormap;
|
||||
if (*sector->lightlist[light].extra_colormap)
|
||||
colormap = *sector->lightlist[light].extra_colormap;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1839,6 +1839,7 @@ void T_ThwompSector(levelspecthink_t *thwomp)
|
|||
#define ceilingwasheight vars[5]
|
||||
fixed_t thwompx, thwompy;
|
||||
sector_t *actionsector;
|
||||
ffloor_t *rover = NULL;
|
||||
INT32 secnum;
|
||||
|
||||
// If you just crashed down, wait a second before coming back up.
|
||||
|
@ -1853,7 +1854,16 @@ void T_ThwompSector(levelspecthink_t *thwomp)
|
|||
secnum = P_FindSectorFromTag((INT16)thwomp->vars[0], -1);
|
||||
|
||||
if (secnum > 0)
|
||||
{
|
||||
actionsector = §ors[secnum];
|
||||
|
||||
// Look for thwomp FFloor
|
||||
for (rover = actionsector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (rover->master == thwomp->sourceline)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
return; // Bad bad bad!
|
||||
|
||||
|
@ -1942,10 +1952,13 @@ void T_ThwompSector(levelspecthink_t *thwomp)
|
|||
{
|
||||
mobj_t *mp = (void *)&actionsector->soundorg;
|
||||
|
||||
if (thwomp->sourceline->flags & ML_EFFECT4)
|
||||
S_StartSound(mp, sides[thwomp->sourceline->sidenum[0]].textureoffset>>FRACBITS);
|
||||
else
|
||||
S_StartSound(mp, sfx_thwomp);
|
||||
if (!rover || (rover->flags & FF_EXISTS))
|
||||
{
|
||||
if (thwomp->sourceline->flags & ML_EFFECT4)
|
||||
S_StartSound(mp, sides[thwomp->sourceline->sidenum[0]].textureoffset>>FRACBITS);
|
||||
else
|
||||
S_StartSound(mp, sfx_thwomp);
|
||||
}
|
||||
|
||||
thwomp->direction = 1; // start heading back up
|
||||
thwomp->distance = TICRATE; // but only after a small delay
|
||||
|
@ -1959,18 +1972,22 @@ void T_ThwompSector(levelspecthink_t *thwomp)
|
|||
thinker_t *th;
|
||||
mobj_t *mo;
|
||||
|
||||
// scan the thinkers to find players!
|
||||
for (th = thinkercap.next; th != &thinkercap; th = th->next)
|
||||
if (!rover || (rover->flags & FF_EXISTS))
|
||||
{
|
||||
if (th->function.acp1 != (actionf_p1)P_MobjThinker)
|
||||
continue;
|
||||
|
||||
mo = (mobj_t *)th;
|
||||
if (mo->type == MT_PLAYER && mo->health && mo->z <= thwomp->sector->ceilingheight
|
||||
&& P_AproxDistance(thwompx - mo->x, thwompy - mo->y) <= 96*FRACUNIT)
|
||||
// scan the thinkers to find players!
|
||||
for (th = thinkercap.next; th != &thinkercap; th = th->next)
|
||||
{
|
||||
thwomp->direction = -1;
|
||||
break;
|
||||
if (th->function.acp1 != (actionf_p1)P_MobjThinker)
|
||||
continue;
|
||||
|
||||
mo = (mobj_t *)th;
|
||||
if (mo->type == MT_PLAYER && mo->health && mo->player && !mo->player->spectator
|
||||
&& mo->z <= thwomp->sector->ceilingheight
|
||||
&& P_AproxDistance(thwompx - mo->x, thwompy - mo->y) <= 96*FRACUNIT)
|
||||
{
|
||||
thwomp->direction = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
159
src/p_polyobj.c
159
src/p_polyobj.c
|
@ -2853,6 +2853,165 @@ INT32 EV_DoPolyObjFlag(line_t *pfdata)
|
|||
return 1;
|
||||
}
|
||||
|
||||
void T_PolyObjFade(polyfade_t *th)
|
||||
{
|
||||
boolean stillfading = false;
|
||||
polyobj_t *po = Polyobj_GetForNum(th->polyObjNum);
|
||||
|
||||
if (!po)
|
||||
#ifdef RANGECHECK
|
||||
I_Error("T_PolyObjFade: thinker has invalid id %d\n", th->polyObjNum);
|
||||
#else
|
||||
{
|
||||
CONS_Debug(DBG_POLYOBJ, "T_PolyObjFade: thinker with invalid id %d removed.\n", th->polyObjNum);
|
||||
P_RemoveThinkerDelayed(&th->thinker);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// check for displacement due to override and reattach when possible
|
||||
if (po->thinker == NULL)
|
||||
po->thinker = &th->thinker;
|
||||
|
||||
stillfading = th->ticbased ? !(--(th->timer) <= 0)
|
||||
: !((th->timer -= th->duration) <= 0);
|
||||
|
||||
if (th->timer <= 0)
|
||||
{
|
||||
po->translucency = max(min(th->destvalue, NUMTRANSMAPS), 0);
|
||||
|
||||
// remove thinker
|
||||
if (po->thinker == &th->thinker)
|
||||
po->thinker = NULL;
|
||||
P_RemoveThinker(&th->thinker);
|
||||
}
|
||||
else
|
||||
{
|
||||
INT16 delta = abs(th->destvalue - th->sourcevalue);
|
||||
INT32 duration = th->ticbased ? th->duration
|
||||
: abs(FixedMul(FixedDiv(256, NUMTRANSMAPS), NUMTRANSMAPS - th->destvalue)
|
||||
- FixedMul(FixedDiv(256, NUMTRANSMAPS), NUMTRANSMAPS - th->sourcevalue)); // speed-based internal counter duration: delta in 256 scale
|
||||
fixed_t factor = min(FixedDiv(duration - th->timer, duration), 1*FRACUNIT);
|
||||
if (th->destvalue < th->sourcevalue)
|
||||
po->translucency = max(min(po->translucency, th->sourcevalue - (INT16)FixedMul(delta, factor)), th->destvalue);
|
||||
else if (th->destvalue > th->sourcevalue)
|
||||
po->translucency = min(max(po->translucency, th->sourcevalue + (INT16)FixedMul(delta, factor)), th->destvalue);
|
||||
}
|
||||
|
||||
if (!stillfading)
|
||||
{
|
||||
// set render flags
|
||||
if (po->translucency >= NUMTRANSMAPS) // invisible
|
||||
po->flags &= ~POF_RENDERALL;
|
||||
else
|
||||
po->flags |= (po->spawnflags & POF_RENDERALL);
|
||||
|
||||
// set collision
|
||||
if (th->docollision)
|
||||
{
|
||||
if (th->destvalue > th->sourcevalue) // faded out
|
||||
{
|
||||
po->flags &= ~POF_SOLID;
|
||||
po->flags |= POF_NOSPECIALS;
|
||||
}
|
||||
else
|
||||
{
|
||||
po->flags |= (po->spawnflags & POF_SOLID);
|
||||
if (!(po->spawnflags & POF_NOSPECIALS))
|
||||
po->flags &= ~POF_NOSPECIALS;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (po->translucency >= NUMTRANSMAPS)
|
||||
// HACK: OpenGL renders fully opaque when >= NUMTRANSMAPS
|
||||
po->translucency = NUMTRANSMAPS-1;
|
||||
|
||||
po->flags |= (po->spawnflags & POF_RENDERALL);
|
||||
|
||||
// set collision
|
||||
if (th->docollision)
|
||||
{
|
||||
if (th->doghostfade)
|
||||
{
|
||||
po->flags &= ~POF_SOLID;
|
||||
po->flags |= POF_NOSPECIALS;
|
||||
}
|
||||
else
|
||||
{
|
||||
po->flags |= (po->spawnflags & POF_SOLID);
|
||||
if (!(po->spawnflags & POF_NOSPECIALS))
|
||||
po->flags &= ~POF_NOSPECIALS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
INT32 EV_DoPolyObjFade(polyfadedata_t *pfdata)
|
||||
{
|
||||
polyobj_t *po;
|
||||
polyobj_t *oldpo;
|
||||
polyfade_t *th;
|
||||
INT32 start;
|
||||
|
||||
if (!(po = Polyobj_GetForNum(pfdata->polyObjNum)))
|
||||
{
|
||||
CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjFade: bad polyobj %d\n", pfdata->polyObjNum);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// don't allow line actions to affect bad polyobjects
|
||||
if (po->isBad)
|
||||
return 0;
|
||||
|
||||
// already equal, nothing to do
|
||||
if (po->translucency == pfdata->destvalue)
|
||||
return 1;
|
||||
|
||||
if (po->thinker && po->thinker->function.acp1 == (actionf_p1)T_PolyObjFade)
|
||||
P_RemoveThinker(po->thinker);
|
||||
|
||||
// create a new thinker
|
||||
th = Z_Malloc(sizeof(polyfade_t), PU_LEVSPEC, NULL);
|
||||
th->thinker.function.acp1 = (actionf_p1)T_PolyObjFade;
|
||||
PolyObj_AddThinker(&th->thinker);
|
||||
po->thinker = &th->thinker;
|
||||
|
||||
// set fields
|
||||
th->polyObjNum = pfdata->polyObjNum;
|
||||
th->sourcevalue = po->translucency;
|
||||
th->destvalue = pfdata->destvalue;
|
||||
th->docollision = pfdata->docollision;
|
||||
th->doghostfade = pfdata->doghostfade;
|
||||
|
||||
if (pfdata->ticbased)
|
||||
{
|
||||
th->ticbased = true;
|
||||
th->timer = th->duration = abs(pfdata->speed); // pfdata->speed is duration
|
||||
}
|
||||
else
|
||||
{
|
||||
th->ticbased = false;
|
||||
th->timer = abs(FixedMul(FixedDiv(256, NUMTRANSMAPS), NUMTRANSMAPS - th->destvalue)
|
||||
- FixedMul(FixedDiv(256, NUMTRANSMAPS), NUMTRANSMAPS - th->sourcevalue)); // delta converted to 256 scale, use as internal counter
|
||||
th->duration = abs(pfdata->speed); // use th->duration as speed decrement
|
||||
}
|
||||
|
||||
oldpo = po;
|
||||
|
||||
// apply action to mirroring polyobjects as well
|
||||
start = 0;
|
||||
while ((po = Polyobj_GetChild(oldpo, &start)))
|
||||
{
|
||||
pfdata->polyObjNum = po->id;
|
||||
EV_DoPolyObjFade(pfdata);
|
||||
}
|
||||
|
||||
// action was successful
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif // ifdef POLYOBJECTS
|
||||
|
||||
// EOF
|
||||
|
|
|
@ -207,6 +207,20 @@ typedef struct polydisplace_s
|
|||
fixed_t oldHeights;
|
||||
} polydisplace_t;
|
||||
|
||||
typedef struct polyfade_s
|
||||
{
|
||||
thinker_t thinker; // must be first
|
||||
|
||||
INT32 polyObjNum;
|
||||
INT32 sourcevalue;
|
||||
INT32 destvalue;
|
||||
boolean docollision;
|
||||
boolean doghostfade;
|
||||
boolean ticbased;
|
||||
INT32 duration;
|
||||
INT32 timer;
|
||||
} polyfade_t;
|
||||
|
||||
//
|
||||
// Line Activation Data Structures
|
||||
//
|
||||
|
@ -266,6 +280,16 @@ typedef struct polydisplacedata_s
|
|||
fixed_t dy;
|
||||
} polydisplacedata_t;
|
||||
|
||||
typedef struct polyfadedata_s
|
||||
{
|
||||
INT32 polyObjNum;
|
||||
INT32 destvalue;
|
||||
boolean docollision;
|
||||
boolean doghostfade;
|
||||
boolean ticbased;
|
||||
INT32 speed;
|
||||
} polyfadedata_t;
|
||||
|
||||
//
|
||||
// Functions
|
||||
//
|
||||
|
@ -287,6 +311,7 @@ void T_PolyDoorSlide(polyslidedoor_t *);
|
|||
void T_PolyDoorSwing(polyswingdoor_t *);
|
||||
void T_PolyObjDisplace (polydisplace_t *);
|
||||
void T_PolyObjFlag (polymove_t *);
|
||||
void T_PolyObjFade (polyfade_t *);
|
||||
|
||||
INT32 EV_DoPolyDoor(polydoordata_t *);
|
||||
INT32 EV_DoPolyObjMove(polymovedata_t *);
|
||||
|
@ -294,6 +319,7 @@ INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *);
|
|||
INT32 EV_DoPolyObjRotate(polyrotdata_t *);
|
||||
INT32 EV_DoPolyObjDisplace(polydisplacedata_t *);
|
||||
INT32 EV_DoPolyObjFlag(struct line_s *);
|
||||
INT32 EV_DoPolyObjFade(polyfadedata_t *);
|
||||
|
||||
|
||||
//
|
||||
|
|
332
src/p_saveg.c
332
src/p_saveg.c
|
@ -21,6 +21,7 @@
|
|||
#include "p_local.h"
|
||||
#include "p_setup.h"
|
||||
#include "p_saveg.h"
|
||||
#include "r_data.h"
|
||||
#include "r_things.h"
|
||||
#include "r_state.h"
|
||||
#include "w_wad.h"
|
||||
|
@ -473,6 +474,243 @@ static void P_NetUnArchivePlayers(void)
|
|||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Colormaps
|
||||
///
|
||||
|
||||
static extracolormap_t *net_colormaps = NULL;
|
||||
static UINT32 num_net_colormaps = 0;
|
||||
static UINT32 num_ffloors = 0; // for loading
|
||||
|
||||
// Copypasta from r_data.c AddColormapToList
|
||||
// But also check for equality and return the matching index
|
||||
static UINT32 CheckAddNetColormapToList(extracolormap_t *extra_colormap)
|
||||
{
|
||||
extracolormap_t *exc, *exc_prev;
|
||||
UINT32 i = 0;
|
||||
|
||||
if (!net_colormaps)
|
||||
{
|
||||
net_colormaps = R_CopyColormap(extra_colormap, false);
|
||||
net_colormaps->next = 0;
|
||||
net_colormaps->prev = 0;
|
||||
num_net_colormaps = i+1;
|
||||
return i;
|
||||
}
|
||||
|
||||
for (exc = net_colormaps; exc; exc_prev = exc, exc = exc->next)
|
||||
{
|
||||
if (R_CheckEqualColormaps(exc, extra_colormap, true, true, true))
|
||||
return i;
|
||||
i++;
|
||||
}
|
||||
|
||||
exc_prev->next = R_CopyColormap(extra_colormap, false);
|
||||
extra_colormap->prev = exc_prev;
|
||||
extra_colormap->next = 0;
|
||||
|
||||
num_net_colormaps = i+1;
|
||||
return i;
|
||||
}
|
||||
|
||||
static extracolormap_t *GetNetColormapFromList(UINT32 index)
|
||||
{
|
||||
// For loading, we have to be tricky:
|
||||
// We load the sectors BEFORE knowing the colormap values
|
||||
// So if an index doesn't exist, fill our list with dummy colormaps
|
||||
// until we get the index we want
|
||||
// Then when we load the color data, we set up the dummy colormaps
|
||||
|
||||
extracolormap_t *exc, *last_exc = NULL;
|
||||
UINT32 i = 0;
|
||||
|
||||
if (!net_colormaps) // initialize our list
|
||||
net_colormaps = R_CreateDefaultColormap(false);
|
||||
|
||||
for (exc = net_colormaps; exc; last_exc = exc, exc = exc->next)
|
||||
{
|
||||
if (i++ == index)
|
||||
return exc;
|
||||
}
|
||||
|
||||
|
||||
// LET'S HOPE that index is a sane value, because we create up to [index]
|
||||
// entries in net_colormaps. At this point, we don't know
|
||||
// what the total colormap count is
|
||||
if (index >= numsectors*3 + num_ffloors)
|
||||
// if every sector had a unique colormap change AND a fade color thinker which has two colormap entries
|
||||
// AND every ffloor had a fade FOF thinker with one colormap entry
|
||||
I_Error("Colormap %d from server is too high for sectors %d", index, (UINT32)numsectors);
|
||||
|
||||
// our index doesn't exist, so just make the entry
|
||||
for (; i <= index; i++)
|
||||
{
|
||||
exc = R_CreateDefaultColormap(false);
|
||||
if (last_exc)
|
||||
last_exc->next = exc;
|
||||
exc->prev = last_exc;
|
||||
exc->next = NULL;
|
||||
last_exc = exc;
|
||||
}
|
||||
return exc;
|
||||
}
|
||||
|
||||
static void ClearNetColormaps(void)
|
||||
{
|
||||
// We're actually Z_Freeing each entry here,
|
||||
// so don't call this in P_NetUnArchiveColormaps (where entries will be used in-game)
|
||||
extracolormap_t *exc, *exc_next;
|
||||
|
||||
for (exc = net_colormaps; exc; exc = exc_next)
|
||||
{
|
||||
exc_next = exc->next;
|
||||
Z_Free(exc);
|
||||
}
|
||||
num_net_colormaps = 0;
|
||||
num_ffloors = 0;
|
||||
net_colormaps = NULL;
|
||||
}
|
||||
|
||||
static void P_NetArchiveColormaps(void)
|
||||
{
|
||||
// We save and then we clean up our colormap mess
|
||||
extracolormap_t *exc, *exc_next;
|
||||
UINT32 i = 0;
|
||||
WRITEUINT32(save_p, num_net_colormaps); // save for safety
|
||||
|
||||
for (exc = net_colormaps; i < num_net_colormaps; i++, exc = exc_next)
|
||||
{
|
||||
// We must save num_net_colormaps worth of data
|
||||
// So fill non-existent entries with default.
|
||||
if (!exc)
|
||||
exc = R_CreateDefaultColormap(false);
|
||||
|
||||
WRITEUINT8(save_p, exc->fadestart);
|
||||
WRITEUINT8(save_p, exc->fadeend);
|
||||
WRITEUINT8(save_p, exc->fog);
|
||||
|
||||
WRITEINT32(save_p, exc->rgba);
|
||||
WRITEINT32(save_p, exc->fadergba);
|
||||
|
||||
#ifdef EXTRACOLORMAPLUMPS
|
||||
WRITESTRINGN(save_p, exc->lumpname, 9);
|
||||
#endif
|
||||
|
||||
exc_next = exc->next;
|
||||
Z_Free(exc); // don't need anymore
|
||||
}
|
||||
|
||||
num_net_colormaps = 0;
|
||||
num_ffloors = 0;
|
||||
net_colormaps = NULL;
|
||||
}
|
||||
|
||||
static void P_NetUnArchiveColormaps(void)
|
||||
{
|
||||
// When we reach this point, we already populated our list with
|
||||
// dummy colormaps. Now that we are loading the color data,
|
||||
// set up the dummies.
|
||||
extracolormap_t *exc, *existing_exc, *exc_next = NULL;
|
||||
UINT32 i = 0;
|
||||
|
||||
num_net_colormaps = READUINT32(save_p);
|
||||
|
||||
for (exc = net_colormaps; i < num_net_colormaps; i++, exc = exc_next)
|
||||
{
|
||||
UINT8 fadestart, fadeend, fog;
|
||||
INT32 rgba, fadergba;
|
||||
#ifdef EXTRACOLORMAPLUMPS
|
||||
char lumpname[9];
|
||||
#endif
|
||||
|
||||
fadestart = READUINT8(save_p);
|
||||
fadeend = READUINT8(save_p);
|
||||
fog = READUINT8(save_p);
|
||||
|
||||
rgba = READINT32(save_p);
|
||||
fadergba = READINT32(save_p);
|
||||
|
||||
#ifdef EXTRACOLORMAPLUMPS
|
||||
READSTRINGN(save_p, lumpname, 9);
|
||||
|
||||
if (lumpname[0])
|
||||
{
|
||||
if (!exc)
|
||||
// no point making a new entry since nothing points to it,
|
||||
// but we needed to read the data so now continue
|
||||
continue;
|
||||
|
||||
exc_next = exc->next; // this gets overwritten during our operations here, so get it now
|
||||
existing_exc = R_ColormapForName(lumpname);
|
||||
*exc = *existing_exc;
|
||||
R_AddColormapToList(exc); // see HACK note below on why we're adding duplicates
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!exc)
|
||||
// no point making a new entry since nothing points to it,
|
||||
// but we needed to read the data so now continue
|
||||
continue;
|
||||
|
||||
exc_next = exc->next; // this gets overwritten during our operations here, so get it now
|
||||
|
||||
exc->fadestart = fadestart;
|
||||
exc->fadeend = fadeend;
|
||||
exc->fog = fog;
|
||||
|
||||
exc->rgba = rgba;
|
||||
exc->fadergba = fadergba;
|
||||
|
||||
#ifdef EXTRACOLORMAPLUMPS
|
||||
exc->lump = LUMPERROR;
|
||||
exc->lumpname[0] = 0;
|
||||
#endif
|
||||
|
||||
existing_exc = R_GetColormapFromListByValues(rgba, fadergba, fadestart, fadeend, fog);
|
||||
|
||||
if (existing_exc)
|
||||
exc->colormap = existing_exc->colormap;
|
||||
else
|
||||
// CONS_Debug(DBG_RENDER, "Creating Colormap: rgba(%d,%d,%d,%d) fadergba(%d,%d,%d,%d)\n",
|
||||
// R_GetRgbaR(rgba), R_GetRgbaG(rgba), R_GetRgbaB(rgba), R_GetRgbaA(rgba),
|
||||
// R_GetRgbaR(fadergba), R_GetRgbaG(fadergba), R_GetRgbaB(fadergba), R_GetRgbaA(fadergba));
|
||||
exc->colormap = R_CreateLightTable(exc);
|
||||
|
||||
// HACK: If this dummy is a duplicate, we're going to add it
|
||||
// to the extra_colormaps list anyway. I think this is faster
|
||||
// than going through every loaded sector and correcting their
|
||||
// colormap address to the pre-existing one, PER net_colormap entry
|
||||
R_AddColormapToList(exc);
|
||||
|
||||
if (i < num_net_colormaps-1 && !exc_next)
|
||||
exc_next = R_CreateDefaultColormap(false);
|
||||
}
|
||||
|
||||
// if we still have a valid net_colormap after iterating up to num_net_colormaps,
|
||||
// some sector had a colormap index higher than num_net_colormaps. We done goofed or $$$ was corrupted.
|
||||
// In any case, add them to the colormap list too so that at least the sectors' colormap
|
||||
// addresses are valid and accounted properly
|
||||
if (exc_next)
|
||||
{
|
||||
existing_exc = R_GetDefaultColormap();
|
||||
for (exc = exc_next; exc; exc = exc->next)
|
||||
{
|
||||
exc->colormap = existing_exc->colormap; // all our dummies are default values
|
||||
R_AddColormapToList(exc);
|
||||
}
|
||||
}
|
||||
|
||||
// Don't need these anymore
|
||||
num_net_colormaps = 0;
|
||||
num_ffloors = 0;
|
||||
net_colormaps = NULL;
|
||||
}
|
||||
|
||||
///
|
||||
/// World Archiving
|
||||
///
|
||||
|
||||
#define SD_FLOORHT 0x01
|
||||
#define SD_CEILHT 0x02
|
||||
#define SD_FLOORPIC 0x04
|
||||
|
@ -494,7 +732,7 @@ static void P_NetUnArchivePlayers(void)
|
|||
|
||||
// diff3 flags
|
||||
#define SD_TAGLIST 0x01
|
||||
#define SD_MIDMAP 0x02
|
||||
#define SD_COLORMAP 0x02
|
||||
|
||||
#define LD_FLAG 0x01
|
||||
#define LD_SPECIAL 0x02
|
||||
|
@ -529,6 +767,9 @@ static void P_NetArchiveWorld(void)
|
|||
const sector_t *ss = sectors;
|
||||
UINT8 diff, diff2, diff3;
|
||||
|
||||
// initialize colormap vars because paranoia
|
||||
ClearNetColormaps();
|
||||
|
||||
WRITEUINT32(save_p, ARCHIVEBLOCK_WORLD);
|
||||
put = save_p;
|
||||
|
||||
|
@ -589,8 +830,9 @@ static void P_NetArchiveWorld(void)
|
|||
diff2 |= SD_TAG;
|
||||
if (ss->nexttag != ss->spawn_nexttag || ss->firsttag != ss->spawn_firsttag)
|
||||
diff3 |= SD_TAGLIST;
|
||||
if (ss->midmap != ss->spawn_midmap)
|
||||
diff3 |= SD_MIDMAP;
|
||||
|
||||
if (ss->extra_colormap != ss->spawn_extra_colormap)
|
||||
diff3 |= SD_COLORMAP;
|
||||
|
||||
// Check if any of the sector's FOFs differ from how they spawned
|
||||
if (ss->ffloors)
|
||||
|
@ -654,8 +896,10 @@ static void P_NetArchiveWorld(void)
|
|||
WRITEINT32(put, ss->firsttag);
|
||||
WRITEINT32(put, ss->nexttag);
|
||||
}
|
||||
if (diff3 & SD_MIDMAP)
|
||||
WRITEINT32(put, ss->midmap);
|
||||
|
||||
if (diff3 & SD_COLORMAP)
|
||||
WRITEUINT32(put, CheckAddNetColormapToList(ss->extra_colormap));
|
||||
// returns existing index if already added, or appends to net_colormaps and returns new index
|
||||
|
||||
// Special case: save the stats of all modified ffloors along with their ffloor "number"s
|
||||
// we don't bother with ffloors that haven't changed, that would just add to savegame even more than is really needed
|
||||
|
@ -790,6 +1034,17 @@ static void P_NetUnArchiveWorld(void)
|
|||
if (READUINT32(save_p) != ARCHIVEBLOCK_WORLD)
|
||||
I_Error("Bad $$$.sav at archive block World");
|
||||
|
||||
// initialize colormap vars because paranoia
|
||||
ClearNetColormaps();
|
||||
|
||||
// count the level's ffloors so that colormap loading can have an upper limit
|
||||
for (i = 0; i < numsectors; i++)
|
||||
{
|
||||
ffloor_t *rover;
|
||||
for (rover = sectors[i].ffloors; rover; rover = rover->next)
|
||||
num_ffloors++;
|
||||
}
|
||||
|
||||
get = save_p;
|
||||
|
||||
for (;;)
|
||||
|
@ -850,8 +1105,9 @@ static void P_NetUnArchiveWorld(void)
|
|||
sectors[i].firsttag = READINT32(get);
|
||||
sectors[i].nexttag = READINT32(get);
|
||||
}
|
||||
if (diff3 & SD_MIDMAP)
|
||||
sectors[i].midmap = READINT32(get);
|
||||
|
||||
if (diff3 & SD_COLORMAP)
|
||||
sectors[i].extra_colormap = GetNetColormapFromList(READUINT32(get));
|
||||
|
||||
if (diff & SD_FFLOORS)
|
||||
{
|
||||
|
@ -1018,6 +1274,7 @@ typedef enum
|
|||
tc_bouncecheese,
|
||||
tc_startcrumble,
|
||||
tc_marioblock,
|
||||
tc_marioblockchecker,
|
||||
tc_spikesector,
|
||||
tc_floatsector,
|
||||
tc_bridgethinker,
|
||||
|
@ -1042,6 +1299,7 @@ typedef enum
|
|||
tc_polyswingdoor,
|
||||
tc_polyflag,
|
||||
tc_polydisplace,
|
||||
tc_polyfade,
|
||||
#endif
|
||||
tc_end
|
||||
} specials_e;
|
||||
|
@ -1334,7 +1592,10 @@ static void SaveSpecialLevelThinker(const thinker_t *th, const UINT8 type)
|
|||
size_t i;
|
||||
WRITEUINT8(save_p, type);
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
WRITEFIXED(save_p, ht->vars[i]); //var[16]
|
||||
WRITEFIXED(save_p, ht->var2s[i]); //var[16]
|
||||
}
|
||||
WRITEUINT32(save_p, SaveLine(ht->sourceline));
|
||||
WRITEUINT32(save_p, SaveSector(ht->sector));
|
||||
}
|
||||
|
@ -1753,6 +2014,20 @@ static void SavePolydisplaceThinker(const thinker_t *th, const UINT8 type)
|
|||
WRITEFIXED(save_p, ht->oldHeights);
|
||||
}
|
||||
|
||||
static void SavePolyfadeThinker(const thinker_t *th, const UINT8 type)
|
||||
{
|
||||
const polyfade_t *ht = (const void *)th;
|
||||
WRITEUINT8(save_p, type);
|
||||
WRITEINT32(save_p, ht->polyObjNum);
|
||||
WRITEINT32(save_p, ht->sourcevalue);
|
||||
WRITEINT32(save_p, ht->destvalue);
|
||||
WRITEUINT8(save_p, (UINT8)ht->docollision);
|
||||
WRITEUINT8(save_p, (UINT8)ht->doghostfade);
|
||||
WRITEUINT8(save_p, (UINT8)ht->ticbased);
|
||||
WRITEINT32(save_p, ht->duration);
|
||||
WRITEINT32(save_p, ht->timer);
|
||||
}
|
||||
|
||||
#endif
|
||||
/*
|
||||
//
|
||||
|
@ -1895,6 +2170,11 @@ static void P_NetArchiveThinkers(void)
|
|||
SaveSpecialLevelThinker(th, tc_marioblock);
|
||||
continue;
|
||||
}
|
||||
else if (th->function.acp1 == (actionf_p1)T_MarioBlockChecker)
|
||||
{
|
||||
SaveSpecialLevelThinker(th, tc_marioblockchecker);
|
||||
continue;
|
||||
}
|
||||
else if (th->function.acp1 == (actionf_p1)T_SpikeSector)
|
||||
{
|
||||
SaveSpecialLevelThinker(th, tc_spikesector);
|
||||
|
@ -1977,6 +2257,11 @@ static void P_NetArchiveThinkers(void)
|
|||
SavePolydisplaceThinker(th, tc_polydisplace);
|
||||
continue;
|
||||
}
|
||||
else if (th->function.acp1 == (actionf_p1)T_PolyObjFade)
|
||||
{
|
||||
SavePolyfadeThinker(th, tc_polyfade);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
#ifdef PARANOIA
|
||||
else if (th->function.acv != P_RemoveThinkerDelayed) // wait garbage collection
|
||||
|
@ -2295,7 +2580,10 @@ static void LoadSpecialLevelThinker(actionf_p1 thinker, UINT8 floorOrCeiling)
|
|||
size_t i;
|
||||
ht->thinker.function.acp1 = thinker;
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
ht->vars[i] = READFIXED(save_p); //var[16]
|
||||
ht->var2s[i] = READFIXED(save_p); //var[16]
|
||||
}
|
||||
ht->sourceline = LoadLine(READUINT32(save_p));
|
||||
ht->sector = LoadSector(READUINT32(save_p));
|
||||
|
||||
|
@ -2799,6 +3087,26 @@ static inline void LoadPolydisplaceThinker(actionf_p1 thinker)
|
|||
ht->oldHeights = READFIXED(save_p);
|
||||
P_AddThinker(&ht->thinker);
|
||||
}
|
||||
|
||||
//
|
||||
// LoadPolyfadeThinker
|
||||
//
|
||||
// Loads a polyfadet_t thinker
|
||||
//
|
||||
static void LoadPolyfadeThinker(actionf_p1 thinker)
|
||||
{
|
||||
polyfade_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
|
||||
ht->thinker.function.acp1 = thinker;
|
||||
ht->polyObjNum = READINT32(save_p);
|
||||
ht->sourcevalue = READINT32(save_p);
|
||||
ht->destvalue = READINT32(save_p);
|
||||
ht->docollision = (boolean)READUINT8(save_p);
|
||||
ht->doghostfade = (boolean)READUINT8(save_p);
|
||||
ht->ticbased = (boolean)READUINT8(save_p);
|
||||
ht->duration = READINT32(save_p);
|
||||
ht->timer = READINT32(save_p);
|
||||
P_AddThinker(&ht->thinker);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -2936,6 +3244,10 @@ static void P_NetUnArchiveThinkers(void)
|
|||
LoadSpecialLevelThinker((actionf_p1)T_MarioBlock, 3);
|
||||
break;
|
||||
|
||||
case tc_marioblockchecker:
|
||||
LoadSpecialLevelThinker((actionf_p1)T_MarioBlockChecker, 0);
|
||||
break;
|
||||
|
||||
case tc_spikesector:
|
||||
LoadSpecialLevelThinker((actionf_p1)T_SpikeSector, 0);
|
||||
break;
|
||||
|
@ -3000,6 +3312,10 @@ static void P_NetUnArchiveThinkers(void)
|
|||
case tc_polydisplace:
|
||||
LoadPolydisplaceThinker((actionf_p1)T_PolyObjDisplace);
|
||||
break;
|
||||
|
||||
case tc_polyfade:
|
||||
LoadPolyfadeThinker((actionf_p1)T_PolyObjFade);
|
||||
break;
|
||||
#endif
|
||||
case tc_scroll:
|
||||
LoadScrollThinker((actionf_p1)T_Scroll);
|
||||
|
@ -3552,6 +3868,7 @@ void P_SaveNetGame(void)
|
|||
#endif
|
||||
P_NetArchiveThinkers();
|
||||
P_NetArchiveSpecials();
|
||||
P_NetArchiveColormaps();
|
||||
}
|
||||
#ifdef HAVE_BLUA
|
||||
LUA_Archive();
|
||||
|
@ -3594,6 +3911,7 @@ boolean P_LoadNetGame(void)
|
|||
#endif
|
||||
P_NetUnArchiveThinkers();
|
||||
P_NetUnArchiveSpecials();
|
||||
P_NetUnArchiveColormaps();
|
||||
P_RelinkPointers();
|
||||
P_FinishMobjs();
|
||||
}
|
||||
|
|
115
src/p_setup.c
115
src/p_setup.c
|
@ -714,13 +714,12 @@ static void P_LoadRawSectors(UINT8 *data, size_t i)
|
|||
ss->moved = true;
|
||||
|
||||
ss->extra_colormap = NULL;
|
||||
ss->spawn_extra_colormap = NULL;
|
||||
|
||||
ss->floor_xoffs = ss->ceiling_xoffs = ss->floor_yoffs = ss->ceiling_yoffs = 0;
|
||||
ss->spawn_flr_xoffs = ss->spawn_ceil_xoffs = ss->spawn_flr_yoffs = ss->spawn_ceil_yoffs = 0;
|
||||
ss->floorpic_angle = ss->ceilingpic_angle = 0;
|
||||
ss->spawn_flrpic_angle = ss->spawn_ceilpic_angle = 0;
|
||||
ss->bottommap = ss->midmap = ss->topmap = -1;
|
||||
ss->spawn_bottommap = ss->spawn_midmap = ss->spawn_topmap = -1;
|
||||
ss->gravity = NULL;
|
||||
ss->cullheight = NULL;
|
||||
ss->verticalflip = false;
|
||||
|
@ -1333,7 +1332,8 @@ static void P_LoadLineDefs2(void)
|
|||
ld->backsector = ld->sidenum[1] != 0xffff ? sides[ld->sidenum[1]].sector : 0;
|
||||
|
||||
// Repeat count for midtexture
|
||||
if ((ld->flags & ML_EFFECT5) && (ld->sidenum[1] != 0xffff))
|
||||
if ((ld->flags & ML_EFFECT5) && (ld->sidenum[1] != 0xffff)
|
||||
&& !(ld->special >= 300 && ld->special < 500)) // exempt linedef exec specials
|
||||
{
|
||||
sides[ld->sidenum[0]].repeatcnt = (INT16)(((unsigned)sides[ld->sidenum[0]].textureoffset >> FRACBITS) >> 12);
|
||||
sides[ld->sidenum[0]].textureoffset = (((unsigned)sides[ld->sidenum[0]].textureoffset >> FRACBITS) & 2047) << FRACBITS;
|
||||
|
@ -1440,7 +1440,6 @@ static inline void P_LoadSideDefs(lumpnum_t lumpnum)
|
|||
static void P_LoadRawSideDefs2(void *data)
|
||||
{
|
||||
UINT16 i;
|
||||
INT32 num;
|
||||
|
||||
for (i = 0; i < numsides; i++)
|
||||
{
|
||||
|
@ -1462,11 +1461,10 @@ static void P_LoadRawSideDefs2(void *data)
|
|||
sd->sector = sec = §ors[sector_num];
|
||||
}
|
||||
|
||||
// refined to allow colormaps to work as wall textures if invalid as colormaps
|
||||
// but valid as textures.
|
||||
|
||||
sd->sector = sec = §ors[SHORT(msd->sector)];
|
||||
|
||||
sd->colormap_data = NULL;
|
||||
|
||||
// Colormaps!
|
||||
switch (sd->special)
|
||||
{
|
||||
|
@ -1475,105 +1473,10 @@ static void P_LoadRawSideDefs2(void *data)
|
|||
case 447: // Change colormap of tagged sectors! -- Monster Iestyn 14/06/18
|
||||
// SoM: R_CreateColormap will only create a colormap in software mode...
|
||||
// Perhaps we should just call it instead of doing the calculations here.
|
||||
if (rendermode == render_soft || rendermode == render_none)
|
||||
{
|
||||
if (msd->toptexture[0] == '#' || msd->bottomtexture[0] == '#')
|
||||
{
|
||||
sec->midmap = sec->spawn_midmap = R_CreateColormap(msd->toptexture, msd->midtexture,
|
||||
msd->bottomtexture);
|
||||
sd->toptexture = sd->bottomtexture = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((num = R_CheckTextureNumForName(msd->toptexture)) == -1)
|
||||
sd->toptexture = 0;
|
||||
else
|
||||
sd->toptexture = num;
|
||||
if ((num = R_CheckTextureNumForName(msd->midtexture)) == -1)
|
||||
sd->midtexture = 0;
|
||||
else
|
||||
sd->midtexture = num;
|
||||
if ((num = R_CheckTextureNumForName(msd->bottomtexture)) == -1)
|
||||
sd->bottomtexture = 0;
|
||||
else
|
||||
sd->bottomtexture = num;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#ifdef HWRENDER
|
||||
else
|
||||
{
|
||||
// for now, full support of toptexture only
|
||||
if ((msd->toptexture[0] == '#' && msd->toptexture[1] && msd->toptexture[2] && msd->toptexture[3] && msd->toptexture[4] && msd->toptexture[5] && msd->toptexture[6])
|
||||
|| (msd->bottomtexture[0] == '#' && msd->bottomtexture[1] && msd->bottomtexture[2] && msd->bottomtexture[3] && msd->bottomtexture[4] && msd->bottomtexture[5] && msd->bottomtexture[6]))
|
||||
{
|
||||
char *col;
|
||||
|
||||
sec->midmap = sec->spawn_midmap = R_CreateColormap(msd->toptexture, msd->midtexture,
|
||||
msd->bottomtexture);
|
||||
sd->toptexture = sd->bottomtexture = 0;
|
||||
#define HEX2INT(x) (x >= '0' && x <= '9' ? x - '0' : x >= 'a' && x <= 'f' ? x - 'a' + 10 : x >= 'A' && x <= 'F' ? x - 'A' + 10 : 0)
|
||||
#define ALPHA2INT(x) (x >= 'a' && x <= 'z' ? x - 'a' : x >= 'A' && x <= 'Z' ? x - 'A' : x >= '0' && x <= '9' ? 25 : 0)
|
||||
sec->extra_colormap = &extra_colormaps[sec->midmap];
|
||||
|
||||
if (msd->toptexture[0] == '#' && msd->toptexture[1] && msd->toptexture[2] && msd->toptexture[3] && msd->toptexture[4] && msd->toptexture[5] && msd->toptexture[6])
|
||||
{
|
||||
col = msd->toptexture;
|
||||
|
||||
sec->extra_colormap->rgba =
|
||||
(HEX2INT(col[1]) << 4) + (HEX2INT(col[2]) << 0) +
|
||||
(HEX2INT(col[3]) << 12) + (HEX2INT(col[4]) << 8) +
|
||||
(HEX2INT(col[5]) << 20) + (HEX2INT(col[6]) << 16);
|
||||
|
||||
// alpha
|
||||
if (msd->toptexture[7])
|
||||
sec->extra_colormap->rgba += (ALPHA2INT(col[7]) << 24);
|
||||
else
|
||||
sec->extra_colormap->rgba += (25 << 24);
|
||||
}
|
||||
else
|
||||
sec->extra_colormap->rgba = 0;
|
||||
|
||||
if (msd->bottomtexture[0] == '#' && msd->bottomtexture[1] && msd->bottomtexture[2] && msd->bottomtexture[3] && msd->bottomtexture[4] && msd->bottomtexture[5] && msd->bottomtexture[6])
|
||||
{
|
||||
col = msd->bottomtexture;
|
||||
|
||||
sec->extra_colormap->fadergba =
|
||||
(HEX2INT(col[1]) << 4) + (HEX2INT(col[2]) << 0) +
|
||||
(HEX2INT(col[3]) << 12) + (HEX2INT(col[4]) << 8) +
|
||||
(HEX2INT(col[5]) << 20) + (HEX2INT(col[6]) << 16);
|
||||
|
||||
// alpha
|
||||
if (msd->bottomtexture[7])
|
||||
sec->extra_colormap->fadergba += (ALPHA2INT(col[7]) << 24);
|
||||
else
|
||||
sec->extra_colormap->fadergba += (25 << 24);
|
||||
}
|
||||
else
|
||||
sec->extra_colormap->fadergba = 0x19000000; // default alpha, (25 << 24)
|
||||
#undef ALPHA2INT
|
||||
#undef HEX2INT
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((num = R_CheckTextureNumForName(msd->toptexture)) == -1)
|
||||
sd->toptexture = 0;
|
||||
else
|
||||
sd->toptexture = num;
|
||||
|
||||
if ((num = R_CheckTextureNumForName(msd->midtexture)) == -1)
|
||||
sd->midtexture = 0;
|
||||
else
|
||||
sd->midtexture = num;
|
||||
|
||||
if ((num = R_CheckTextureNumForName(msd->bottomtexture)) == -1)
|
||||
sd->bottomtexture = 0;
|
||||
else
|
||||
sd->bottomtexture = num;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
sd->colormap_data = R_CreateColormap(msd->toptexture, msd->midtexture,
|
||||
msd->bottomtexture);
|
||||
sd->toptexture = sd->midtexture = sd->bottomtexture = 0;
|
||||
break;
|
||||
|
||||
case 413: // Change music
|
||||
{
|
||||
|
|
147
src/p_spec.c
147
src/p_spec.c
|
@ -1230,7 +1230,7 @@ static void PolyVisible(line_t *line)
|
|||
po->flags |= POF_SOLID;
|
||||
|
||||
po->flags &= ~POF_NOSPECIALS;
|
||||
po->flags |= POF_RENDERALL;
|
||||
po->flags |= (po->spawnflags & POF_RENDERALL);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -1254,7 +1254,94 @@ static void PolyTranslucency(line_t *line)
|
|||
if (po->isBad)
|
||||
return;
|
||||
|
||||
po->translucency = (line->frontsector->floorheight >> FRACBITS) / 100;
|
||||
// if DONTPEGBOTTOM, specify raw translucency value in Front X Offset
|
||||
// else, take it out of 1000. If Front X Offset is specified, use that. Else, use floorheight.
|
||||
if (line->flags & ML_EFFECT3) // relative calc
|
||||
po->translucency = max(min(po->translucency + ((line->flags & ML_DONTPEGBOTTOM) ?
|
||||
(sides[line->sidenum[0]].textureoffset ?
|
||||
max(min(sides[line->sidenum[0]].textureoffset>>FRACBITS, NUMTRANSMAPS), -NUMTRANSMAPS)
|
||||
: max(min(line->frontsector->floorheight>>FRACBITS, NUMTRANSMAPS), -NUMTRANSMAPS))
|
||||
: (sides[line->sidenum[0]].textureoffset ?
|
||||
max(min(sides[line->sidenum[0]].textureoffset>>FRACBITS, 1000), -1000) / 100
|
||||
: max(min(line->frontsector->floorheight>>FRACBITS, 1000), -1000) / 100)),
|
||||
NUMTRANSMAPS), 0);
|
||||
else
|
||||
po->translucency = (line->flags & ML_DONTPEGBOTTOM) ?
|
||||
(sides[line->sidenum[0]].textureoffset ?
|
||||
max(min(sides[line->sidenum[0]].textureoffset>>FRACBITS, NUMTRANSMAPS), 0)
|
||||
: max(min(line->frontsector->floorheight>>FRACBITS, NUMTRANSMAPS), 0))
|
||||
: (sides[line->sidenum[0]].textureoffset ?
|
||||
max(min(sides[line->sidenum[0]].textureoffset>>FRACBITS, 1000), 0) / 100
|
||||
: max(min(line->frontsector->floorheight>>FRACBITS, 1000), 0) / 100);
|
||||
}
|
||||
|
||||
//
|
||||
// PolyFade
|
||||
//
|
||||
// Makes a polyobject translucency fade and applies tangibility
|
||||
//
|
||||
static boolean PolyFade(line_t *line)
|
||||
{
|
||||
INT32 polyObjNum = line->tag;
|
||||
polyobj_t *po;
|
||||
polyfadedata_t pfd;
|
||||
|
||||
if (!(po = Polyobj_GetForNum(polyObjNum)))
|
||||
{
|
||||
CONS_Debug(DBG_POLYOBJ, "PolyFade: bad polyobj %d\n", polyObjNum);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// don't allow line actions to affect bad polyobjects
|
||||
if (po->isBad)
|
||||
return 0;
|
||||
|
||||
// Prevent continuous execs from interfering on an existing fade
|
||||
if (!(line->flags & ML_EFFECT5)
|
||||
&& po->thinker
|
||||
&& po->thinker->function.acp1 == (actionf_p1)T_PolyObjFade)
|
||||
{
|
||||
CONS_Debug(DBG_POLYOBJ, "Line type 492 Executor: Fade PolyObject thinker already exists\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
pfd.polyObjNum = polyObjNum;
|
||||
|
||||
// if DONTPEGBOTTOM, specify raw translucency value in Front X Offset
|
||||
// else, take it out of 1000. If Front X Offset is specified, use that. Else, use floorheight.
|
||||
if (line->flags & ML_EFFECT3) // relative calc
|
||||
pfd.destvalue = max(min(po->translucency + ((line->flags & ML_DONTPEGBOTTOM) ?
|
||||
(sides[line->sidenum[0]].textureoffset ?
|
||||
max(min(sides[line->sidenum[0]].textureoffset>>FRACBITS, NUMTRANSMAPS), -NUMTRANSMAPS)
|
||||
: max(min(line->frontsector->floorheight>>FRACBITS, NUMTRANSMAPS), -NUMTRANSMAPS))
|
||||
: (sides[line->sidenum[0]].textureoffset ?
|
||||
max(min(sides[line->sidenum[0]].textureoffset>>FRACBITS, 1000), -1000) / 100
|
||||
: max(min(line->frontsector->floorheight>>FRACBITS, 1000), -1000) / 100)),
|
||||
NUMTRANSMAPS), 0);
|
||||
else
|
||||
pfd.destvalue = (line->flags & ML_DONTPEGBOTTOM) ?
|
||||
(sides[line->sidenum[0]].textureoffset ?
|
||||
max(min(sides[line->sidenum[0]].textureoffset>>FRACBITS, NUMTRANSMAPS), 0)
|
||||
: max(min(line->frontsector->floorheight>>FRACBITS, NUMTRANSMAPS), 0))
|
||||
: (sides[line->sidenum[0]].textureoffset ?
|
||||
max(min(sides[line->sidenum[0]].textureoffset>>FRACBITS, 1000), 0) / 100
|
||||
: max(min(line->frontsector->floorheight>>FRACBITS, 1000), 0) / 100);
|
||||
|
||||
// already equal, nothing to do
|
||||
if (po->translucency == pfd.destvalue)
|
||||
return 1;
|
||||
|
||||
pfd.docollision = !(line->flags & ML_BOUNCY); // do not handle collision flags
|
||||
pfd.doghostfade = (line->flags & ML_EFFECT1); // do ghost fade (no collision flags during fade)
|
||||
pfd.ticbased = (line->flags & ML_EFFECT4); // Speed = Tic Duration
|
||||
|
||||
// allow Back Y Offset to be consistent with other fade specials
|
||||
pfd.speed = (line->sidenum[1] != 0xFFFF && !sides[line->sidenum[0]].rowoffset) ?
|
||||
abs(sides[line->sidenum[1]].rowoffset>>FRACBITS)
|
||||
: abs(sides[line->sidenum[0]].rowoffset>>FRACBITS);
|
||||
|
||||
|
||||
return EV_DoPolyObjFade(&pfd);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -3277,7 +3364,56 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
// This could even override existing colormaps I believe
|
||||
// -- Monster Iestyn 14/06/18
|
||||
for (secnum = -1; (secnum = P_FindSectorFromLineTag(line, secnum)) >= 0 ;)
|
||||
sectors[secnum].midmap = line->frontsector->midmap;
|
||||
{
|
||||
if (line->flags & ML_EFFECT3) // relative calc
|
||||
{
|
||||
extracolormap_t *exc = R_AddColormaps(
|
||||
(line->flags & ML_TFERLINE) && line->sidenum[1] != 0xFFFF ?
|
||||
sides[line->sidenum[1]].colormap_data : sectors[secnum].extra_colormap, // use back colormap instead of target sector
|
||||
sides[line->sidenum[0]].colormap_data,
|
||||
line->flags & ML_EFFECT1, // subtract R
|
||||
line->flags & ML_NOCLIMB, // subtract G
|
||||
line->flags & ML_EFFECT2, // subtract B
|
||||
false, // subtract A (no flag for this, just pass negative alpha)
|
||||
line->flags & ML_EFFECT1, // subtract FadeR
|
||||
line->flags & ML_NOCLIMB, // subtract FadeG
|
||||
line->flags & ML_EFFECT2, // subtract FadeB
|
||||
false, // subtract FadeA (no flag for this, just pass negative alpha)
|
||||
false, // subtract FadeStart (we ran out of flags)
|
||||
false, // subtract FadeEnd (we ran out of flags)
|
||||
false, // ignore Fog (we ran out of flags)
|
||||
line->flags & ML_DONTPEGBOTTOM,
|
||||
(line->flags & ML_DONTPEGBOTTOM) ? (sides[line->sidenum[0]].textureoffset >> FRACBITS) : 0,
|
||||
(line->flags & ML_DONTPEGBOTTOM) ? (sides[line->sidenum[0]].rowoffset >> FRACBITS) : 0,
|
||||
false);
|
||||
|
||||
if (!(sectors[secnum].extra_colormap = R_GetColormapFromList(exc)))
|
||||
{
|
||||
exc->colormap = R_CreateLightTable(exc);
|
||||
R_AddColormapToList(exc);
|
||||
sectors[secnum].extra_colormap = exc;
|
||||
}
|
||||
else
|
||||
Z_Free(exc);
|
||||
}
|
||||
else if (line->flags & ML_DONTPEGBOTTOM) // alternate alpha (by texture offsets)
|
||||
{
|
||||
extracolormap_t *exc = R_CopyColormap(sides[line->sidenum[0]].colormap_data, false);
|
||||
exc->rgba = R_GetRgbaRGB(exc->rgba) + R_PutRgbaA(max(min(sides[line->sidenum[0]].textureoffset >> FRACBITS, 25), 0));
|
||||
exc->fadergba = R_GetRgbaRGB(exc->fadergba) + R_PutRgbaA(max(min(sides[line->sidenum[0]].rowoffset >> FRACBITS, 25), 0));
|
||||
|
||||
if (!(sectors[secnum].extra_colormap = R_GetColormapFromList(exc)))
|
||||
{
|
||||
exc->colormap = R_CreateLightTable(exc);
|
||||
R_AddColormapToList(exc);
|
||||
sectors[secnum].extra_colormap = exc;
|
||||
}
|
||||
else
|
||||
Z_Free(exc);
|
||||
}
|
||||
else
|
||||
sectors[secnum].extra_colormap = sides[line->sidenum[0]].colormap_data;
|
||||
}
|
||||
break;
|
||||
|
||||
case 448: // Change skybox viewpoint/centerpoint
|
||||
|
@ -3547,6 +3683,9 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
case 491:
|
||||
PolyTranslucency(line);
|
||||
break;
|
||||
case 492:
|
||||
PolyFade(line);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
|
@ -6970,7 +7109,7 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
|||
|
||||
case 606: // HACK! Copy colormaps. Just plain colormaps.
|
||||
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
|
||||
sectors[s].midmap = sectors[s].spawn_midmap = lines[i].frontsector->midmap;
|
||||
sectors[s].extra_colormap = sectors[s].spawn_extra_colormap = sides[lines[i].sidenum[0]].colormap_data;
|
||||
break;
|
||||
|
||||
#ifdef ESLOPE // Slope copy specials. Handled here for sanity.
|
||||
|
|
41
src/r_bsp.c
41
src/r_bsp.c
|
@ -234,8 +234,6 @@ static INT32 R_DoorClosed(void)
|
|||
sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
|
||||
INT32 *ceilinglightlevel, boolean back)
|
||||
{
|
||||
INT32 mapnum = -1;
|
||||
|
||||
if (floorlightlevel)
|
||||
*floorlightlevel = sec->floorlightsec == -1 ?
|
||||
sec->lightlevel : sectors[sec->floorlightsec].lightlevel;
|
||||
|
@ -244,10 +242,10 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
|
|||
*ceilinglightlevel = sec->ceilinglightsec == -1 ?
|
||||
sec->lightlevel : sectors[sec->ceilinglightsec].lightlevel;
|
||||
|
||||
// If the sector has a midmap, it's probably from 280 type
|
||||
if (sec->midmap != -1)
|
||||
mapnum = sec->midmap;
|
||||
else if (sec->heightsec != -1)
|
||||
// if (sec->midmap != -1)
|
||||
// mapnum = sec->midmap;
|
||||
// In original colormap code, this block did not run if sec->midmap was set
|
||||
if (!sec->extra_colormap && sec->heightsec != -1)
|
||||
{
|
||||
const sector_t *s = §ors[sec->heightsec];
|
||||
mobj_t *viewmobj = viewplayer->mo;
|
||||
|
@ -271,8 +269,6 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
|
|||
tempsec->floorheight = s->floorheight;
|
||||
tempsec->ceilingheight = s->ceilingheight;
|
||||
|
||||
mapnum = s->midmap;
|
||||
|
||||
if ((underwater && (tempsec-> floorheight = sec->floorheight,
|
||||
tempsec->ceilingheight = s->floorheight - 1, !back)) || viewz <= s->floorheight)
|
||||
{ // head-below-floor hack
|
||||
|
@ -298,7 +294,6 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
|
|||
tempsec->ceiling_yoffs = s->ceiling_yoffs;
|
||||
tempsec->ceilingpic_angle = s->ceilingpic_angle;
|
||||
}
|
||||
mapnum = s->bottommap;
|
||||
}
|
||||
|
||||
tempsec->lightlevel = s->lightlevel;
|
||||
|
@ -322,8 +317,6 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
|
|||
tempsec->floor_yoffs = tempsec->ceiling_yoffs = s->ceiling_yoffs;
|
||||
tempsec->floorpic_angle = tempsec->ceilingpic_angle = s->ceilingpic_angle;
|
||||
|
||||
mapnum = s->topmap;
|
||||
|
||||
if (s->floorpic == skyflatnum) // SKYFIX?
|
||||
{
|
||||
tempsec->ceilingheight = tempsec->floorheight-1;
|
||||
|
@ -354,11 +347,6 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
|
|||
sec = tempsec;
|
||||
}
|
||||
|
||||
if (mapnum >= 0 && (size_t)mapnum < num_extra_colormaps)
|
||||
sec->extra_colormap = &extra_colormaps[mapnum];
|
||||
else
|
||||
sec->extra_colormap = NULL;
|
||||
|
||||
return sec;
|
||||
}
|
||||
|
||||
|
@ -937,11 +925,11 @@ static void R_Subsector(size_t num)
|
|||
light = R_GetPlaneLight(frontsector, floorcenterz, false);
|
||||
if (frontsector->floorlightsec == -1)
|
||||
floorlightlevel = *frontsector->lightlist[light].lightlevel;
|
||||
floorcolormap = frontsector->lightlist[light].extra_colormap;
|
||||
floorcolormap = *frontsector->lightlist[light].extra_colormap;
|
||||
light = R_GetPlaneLight(frontsector, ceilingcenterz, false);
|
||||
if (frontsector->ceilinglightsec == -1)
|
||||
ceilinglightlevel = *frontsector->lightlist[light].lightlevel;
|
||||
ceilingcolormap = frontsector->lightlist[light].extra_colormap;
|
||||
ceilingcolormap = *frontsector->lightlist[light].extra_colormap;
|
||||
}
|
||||
|
||||
sub->sector->extra_colormap = frontsector->extra_colormap;
|
||||
|
@ -1038,7 +1026,7 @@ static void R_Subsector(size_t num)
|
|||
|
||||
ffloor[numffloors].plane = R_FindPlane(*rover->bottomheight, *rover->bottompic,
|
||||
*frontsector->lightlist[light].lightlevel, *rover->bottomxoffs,
|
||||
*rover->bottomyoffs, *rover->bottomangle, frontsector->lightlist[light].extra_colormap, rover
|
||||
*rover->bottomyoffs, *rover->bottomangle, *frontsector->lightlist[light].extra_colormap, rover
|
||||
#ifdef POLYOBJECTS_PLANES
|
||||
, NULL
|
||||
#endif
|
||||
|
@ -1084,7 +1072,7 @@ static void R_Subsector(size_t num)
|
|||
|
||||
ffloor[numffloors].plane = R_FindPlane(*rover->topheight, *rover->toppic,
|
||||
*frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs, *rover->topangle,
|
||||
frontsector->lightlist[light].extra_colormap, rover
|
||||
*frontsector->lightlist[light].extra_colormap, rover
|
||||
#ifdef POLYOBJECTS_PLANES
|
||||
, NULL
|
||||
#endif
|
||||
|
@ -1237,7 +1225,7 @@ void R_Prep3DFloors(sector_t *sector)
|
|||
ffloor_t *rover;
|
||||
ffloor_t *best;
|
||||
fixed_t bestheight, maxheight;
|
||||
INT32 count, i, mapnum;
|
||||
INT32 count, i;
|
||||
sector_t *sec;
|
||||
#ifdef ESLOPE
|
||||
pslope_t *bestslope = NULL;
|
||||
|
@ -1276,7 +1264,7 @@ void R_Prep3DFloors(sector_t *sector)
|
|||
#endif
|
||||
sector->lightlist[0].lightlevel = §or->lightlevel;
|
||||
sector->lightlist[0].caster = NULL;
|
||||
sector->lightlist[0].extra_colormap = sector->extra_colormap;
|
||||
sector->lightlist[0].extra_colormap = §or->extra_colormap;
|
||||
sector->lightlist[0].flags = 0;
|
||||
|
||||
maxheight = INT32_MAX;
|
||||
|
@ -1342,11 +1330,6 @@ void R_Prep3DFloors(sector_t *sector)
|
|||
sector->lightlist[i].slope = bestslope;
|
||||
#endif
|
||||
sec = §ors[best->secnum];
|
||||
mapnum = sec->midmap;
|
||||
if (mapnum >= 0 && (size_t)mapnum < num_extra_colormaps)
|
||||
sec->extra_colormap = &extra_colormaps[mapnum];
|
||||
else
|
||||
sec->extra_colormap = NULL;
|
||||
|
||||
if (best->flags & FF_NOSHADE)
|
||||
{
|
||||
|
@ -1356,12 +1339,12 @@ void R_Prep3DFloors(sector_t *sector)
|
|||
else if (best->flags & FF_COLORMAPONLY)
|
||||
{
|
||||
sector->lightlist[i].lightlevel = sector->lightlist[i-1].lightlevel;
|
||||
sector->lightlist[i].extra_colormap = sec->extra_colormap;
|
||||
sector->lightlist[i].extra_colormap = &sec->extra_colormap;
|
||||
}
|
||||
else
|
||||
{
|
||||
sector->lightlist[i].lightlevel = best->toplightlevel;
|
||||
sector->lightlist[i].extra_colormap = sec->extra_colormap;
|
||||
sector->lightlist[i].extra_colormap = &sec->extra_colormap;
|
||||
}
|
||||
|
||||
if (best->flags & FF_DOUBLESHADOW)
|
||||
|
|
709
src/r_data.c
709
src/r_data.c
|
@ -1144,6 +1144,10 @@ void R_ParseTEXTURESLump(UINT16 wadNum, UINT16 lumpNum, INT32 *texindex)
|
|||
Z_Free((void *)texturesText);
|
||||
}
|
||||
|
||||
#ifdef EXTRACOLORMAPLUMPS
|
||||
static lumplist_t *colormaplumps = NULL; ///\todo free leak
|
||||
static size_t numcolormaplumps = 0;
|
||||
|
||||
static inline lumpnum_t R_CheckNumForNameList(const char *name, lumplist_t *list, size_t listsize)
|
||||
{
|
||||
size_t i;
|
||||
|
@ -1160,9 +1164,6 @@ static inline lumpnum_t R_CheckNumForNameList(const char *name, lumplist_t *list
|
|||
return LUMPERROR;
|
||||
}
|
||||
|
||||
static lumplist_t *colormaplumps = NULL; ///\todo free leak
|
||||
static size_t numcolormaplumps = 0;
|
||||
|
||||
static void R_InitExtraColormaps(void)
|
||||
{
|
||||
lumpnum_t startnum, endnum;
|
||||
|
@ -1195,6 +1196,7 @@ static void R_InitExtraColormaps(void)
|
|||
}
|
||||
CONS_Printf(M_GetText("Number of Extra Colormaps: %s\n"), sizeu1(numcolormaplumps));
|
||||
}
|
||||
#endif
|
||||
|
||||
// Search for flat name through all
|
||||
lumpnum_t R_GetFlatNumForName(const char *name)
|
||||
|
@ -1291,7 +1293,9 @@ static void R_InitColormaps(void)
|
|||
|
||||
// Init Boom colormaps.
|
||||
R_ClearColormaps();
|
||||
#ifdef EXTRACOLORMAPLUMPS
|
||||
R_InitExtraColormaps();
|
||||
#endif
|
||||
}
|
||||
|
||||
void R_ReInitColormaps(UINT16 num)
|
||||
|
@ -1311,8 +1315,6 @@ void R_ReInitColormaps(UINT16 num)
|
|||
R_ClearColormaps();
|
||||
}
|
||||
|
||||
static lumpnum_t foundcolormaps[MAXCOLORMAPS];
|
||||
|
||||
//
|
||||
// R_ClearColormaps
|
||||
//
|
||||
|
@ -1320,49 +1322,264 @@ static lumpnum_t foundcolormaps[MAXCOLORMAPS];
|
|||
//
|
||||
void R_ClearColormaps(void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
num_extra_colormaps = 0;
|
||||
|
||||
for (i = 0; i < MAXCOLORMAPS; i++)
|
||||
foundcolormaps[i] = LUMPERROR;
|
||||
|
||||
memset(extra_colormaps, 0, sizeof (extra_colormaps));
|
||||
// Purged by PU_LEVEL, just overwrite the pointer
|
||||
extra_colormaps = R_CreateDefaultColormap(true);
|
||||
}
|
||||
|
||||
INT32 R_ColormapNumForName(char *name)
|
||||
//
|
||||
// R_CreateDefaultColormap()
|
||||
// NOTE: The result colormap is not added to the extra_colormaps chain. You must do that yourself!
|
||||
//
|
||||
extracolormap_t *R_CreateDefaultColormap(boolean lighttable)
|
||||
{
|
||||
lumpnum_t lump, i;
|
||||
extracolormap_t *exc = Z_Calloc(sizeof (*exc), PU_LEVEL, NULL);
|
||||
exc->fadestart = 0;
|
||||
exc->fadeend = 31;
|
||||
exc->fog = 0;
|
||||
exc->rgba = 0;
|
||||
exc->fadergba = 0x19000000;
|
||||
exc->colormap = lighttable ? R_CreateLightTable(exc) : NULL;
|
||||
#ifdef EXTRACOLORMAPLUMPS
|
||||
exc->lump = LUMPERROR;
|
||||
exc->lumpname[0] = 0;
|
||||
#endif
|
||||
exc->next = exc->prev = NULL;
|
||||
return exc;
|
||||
}
|
||||
|
||||
if (num_extra_colormaps == MAXCOLORMAPS)
|
||||
I_Error("R_ColormapNumForName: Too many colormaps! the limit is %d\n", MAXCOLORMAPS);
|
||||
//
|
||||
// R_GetDefaultColormap()
|
||||
//
|
||||
extracolormap_t *R_GetDefaultColormap(void)
|
||||
{
|
||||
#ifdef COLORMAPREVERSELIST
|
||||
extracolormap_t *exc;
|
||||
#endif
|
||||
|
||||
if (!extra_colormaps)
|
||||
return (extra_colormaps = R_CreateDefaultColormap(true));
|
||||
|
||||
#ifdef COLORMAPREVERSELIST
|
||||
for (exc = extra_colormaps; exc->next; exc = exc->next);
|
||||
return exc;
|
||||
#else
|
||||
return extra_colormaps;
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// R_CopyColormap()
|
||||
// NOTE: The result colormap is not added to the extra_colormaps chain. You must do that yourself!
|
||||
//
|
||||
extracolormap_t *R_CopyColormap(extracolormap_t *extra_colormap, boolean lighttable)
|
||||
{
|
||||
extracolormap_t *exc = Z_Calloc(sizeof (*exc), PU_LEVEL, NULL);
|
||||
|
||||
if (!extra_colormap)
|
||||
extra_colormap = R_GetDefaultColormap();
|
||||
|
||||
*exc = *extra_colormap;
|
||||
exc->next = exc->prev = NULL;
|
||||
|
||||
#ifdef EXTRACOLORMAPLUMPS
|
||||
strncpy(exc->lumpname, extra_colormap->lumpname, 9);
|
||||
|
||||
if (exc->lump != LUMPERROR && lighttable)
|
||||
{
|
||||
// aligned on 8 bit for asm code
|
||||
exc->colormap = Z_MallocAlign(W_LumpLength(lump), PU_LEVEL, NULL, 16);
|
||||
W_ReadLump(lump, exc->colormap);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (lighttable)
|
||||
exc->colormap = R_CreateLightTable(exc);
|
||||
else
|
||||
exc->colormap = NULL;
|
||||
|
||||
return exc;
|
||||
}
|
||||
|
||||
//
|
||||
// R_AddColormapToList
|
||||
//
|
||||
// Sets prev/next chain for extra_colormaps var
|
||||
// Copypasta from P_AddFFloorToList
|
||||
//
|
||||
void R_AddColormapToList(extracolormap_t *extra_colormap)
|
||||
{
|
||||
#ifndef COLORMAPREVERSELIST
|
||||
extracolormap_t *exc;
|
||||
#endif
|
||||
|
||||
if (!extra_colormaps)
|
||||
{
|
||||
extra_colormaps = extra_colormap;
|
||||
extra_colormap->next = 0;
|
||||
extra_colormap->prev = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef COLORMAPREVERSELIST
|
||||
extra_colormaps->prev = extra_colormap;
|
||||
extra_colormap->next = extra_colormaps;
|
||||
extra_colormaps = extra_colormap;
|
||||
extra_colormap->prev = 0;
|
||||
#else
|
||||
for (exc = extra_colormaps; exc->next; exc = exc->next);
|
||||
|
||||
exc->next = extra_colormap;
|
||||
extra_colormap->prev = exc;
|
||||
extra_colormap->next = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// R_CheckDefaultColormapByValues()
|
||||
//
|
||||
#ifdef EXTRACOLORMAPLUMPS
|
||||
boolean R_CheckDefaultColormapByValues(boolean checkrgba, boolean checkfadergba, boolean checkparams,
|
||||
INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 fog, lumpnum_t lump)
|
||||
#else
|
||||
boolean R_CheckDefaultColormapByValues(boolean checkrgba, boolean checkfadergba, boolean checkparams,
|
||||
INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 fog)
|
||||
#endif
|
||||
{
|
||||
return (
|
||||
(!checkparams ? true :
|
||||
(fadestart == 0
|
||||
&& fadeend == 31
|
||||
&& !fog)
|
||||
)
|
||||
&& (!checkrgba ? true : rgba == 0)
|
||||
&& (!checkfadergba ? true : fadergba == 0x19000000)
|
||||
#ifdef EXTRACOLORMAPLUMPS
|
||||
&& lump == LUMPERROR
|
||||
&& extra_colormap->lumpname[0] == 0
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
boolean R_CheckDefaultColormap(extracolormap_t *extra_colormap, boolean checkrgba, boolean checkfadergba, boolean checkparams)
|
||||
{
|
||||
if (!extra_colormap)
|
||||
return true;
|
||||
|
||||
#ifdef EXTRACOLORMAPLUMPS
|
||||
return R_CheckDefaultColormapByValues(checkrgba, checkfadergba, checkparams, extra_colormap->rgba, extra_colormap->fadergba, extra_colormap->fadestart, extra_colormap->fadeend, extra_colormap->fog, extra_colormap->lump);
|
||||
#else
|
||||
return R_CheckDefaultColormapByValues(checkrgba, checkfadergba, checkparams, extra_colormap->rgba, extra_colormap->fadergba, extra_colormap->fadestart, extra_colormap->fadeend, extra_colormap->fog);
|
||||
#endif
|
||||
}
|
||||
|
||||
boolean R_CheckEqualColormaps(extracolormap_t *exc_a, extracolormap_t *exc_b, boolean checkrgba, boolean checkfadergba, boolean checkparams)
|
||||
{
|
||||
// Treat NULL as default colormap
|
||||
// We need this because what if one exc is a default colormap, and the other is NULL? They're really both equal.
|
||||
if (!exc_a)
|
||||
exc_a = R_GetDefaultColormap();
|
||||
if (!exc_b)
|
||||
exc_b = R_GetDefaultColormap();
|
||||
|
||||
if (exc_a == exc_b)
|
||||
return true;
|
||||
|
||||
return (
|
||||
(!checkparams ? true :
|
||||
(exc_a->fadestart == exc_b->fadestart
|
||||
&& exc_a->fadeend == exc_b->fadeend
|
||||
&& exc_a->fog == exc_b->fog)
|
||||
)
|
||||
&& (!checkrgba ? true : exc_a->rgba == exc_b->rgba)
|
||||
&& (!checkfadergba ? true : exc_a->fadergba == exc_b->fadergba)
|
||||
#ifdef EXTRACOLORMAPLUMPS
|
||||
&& exc_a->lump == exc_b->lump
|
||||
&& !strncmp(exc_a->lumpname, exc_b->lumpname, 9)
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// R_GetColormapFromListByValues()
|
||||
// NOTE: Returns NULL if no match is found
|
||||
//
|
||||
#ifdef EXTRACOLORMAPLUMPS
|
||||
extracolormap_t *R_GetColormapFromListByValues(INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 fog, lumpnum_t lump)
|
||||
#else
|
||||
extracolormap_t *R_GetColormapFromListByValues(INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 fog)
|
||||
#endif
|
||||
{
|
||||
extracolormap_t *exc;
|
||||
UINT32 dbg_i = 0;
|
||||
|
||||
for (exc = extra_colormaps; exc; exc = exc->next)
|
||||
{
|
||||
if (rgba == exc->rgba
|
||||
&& fadergba == exc->fadergba
|
||||
&& fadestart == exc->fadestart
|
||||
&& fadeend == exc->fadeend
|
||||
&& fog == exc->fog
|
||||
#ifdef EXTRACOLORMAPLUMPS
|
||||
&& (lump != LUMPERROR && lump == exc->lump)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
CONS_Debug(DBG_RENDER, "Found Colormap %d: rgba(%d,%d,%d,%d) fadergba(%d,%d,%d,%d)\n",
|
||||
dbg_i, R_GetRgbaR(rgba), R_GetRgbaG(rgba), R_GetRgbaB(rgba), R_GetRgbaA(rgba),
|
||||
R_GetRgbaR(fadergba), R_GetRgbaG(fadergba), R_GetRgbaB(fadergba), R_GetRgbaA(fadergba));
|
||||
return exc;
|
||||
}
|
||||
dbg_i++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
extracolormap_t *R_GetColormapFromList(extracolormap_t *extra_colormap)
|
||||
{
|
||||
#ifdef EXTRACOLORMAPLUMPS
|
||||
return R_GetColormapFromListByValues(extra_colormap->rgba, extra_colormap->fadergba, extra_colormap->fadestart, extra_colormap->fadeend, extra_colormap->fog, extra_colormap->lump);
|
||||
#else
|
||||
return R_GetColormapFromListByValues(extra_colormap->rgba, extra_colormap->fadergba, extra_colormap->fadestart, extra_colormap->fadeend, extra_colormap->fog);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef EXTRACOLORMAPLUMPS
|
||||
extracolormap_t *R_ColormapForName(char *name)
|
||||
{
|
||||
lumpnum_t lump;
|
||||
extracolormap_t *exc;
|
||||
|
||||
lump = R_CheckNumForNameList(name, colormaplumps, numcolormaplumps);
|
||||
if (lump == LUMPERROR)
|
||||
I_Error("R_ColormapNumForName: Cannot find colormap lump %.8s\n", name);
|
||||
I_Error("R_ColormapForName: Cannot find colormap lump %.8s\n", name);
|
||||
|
||||
for (i = 0; i < num_extra_colormaps; i++)
|
||||
if (lump == foundcolormaps[i])
|
||||
return i;
|
||||
exc = R_GetColormapFromListByValues(0, 0x19000000, 0, 31, 0, lump);
|
||||
if (exc)
|
||||
return exc;
|
||||
|
||||
foundcolormaps[num_extra_colormaps] = lump;
|
||||
exc = Z_Calloc(sizeof (*exc), PU_LEVEL, NULL);
|
||||
|
||||
exc->lump = lump;
|
||||
strncpy(exc->lumpname, name, 9);
|
||||
exc->lumpname[8] = 0;
|
||||
|
||||
// aligned on 8 bit for asm code
|
||||
extra_colormaps[num_extra_colormaps].colormap = Z_MallocAlign(W_LumpLength(lump), PU_LEVEL, NULL, 16);
|
||||
W_ReadLump(lump, extra_colormaps[num_extra_colormaps].colormap);
|
||||
exc->colormap = Z_MallocAlign(W_LumpLength(lump), PU_LEVEL, NULL, 16);
|
||||
W_ReadLump(lump, exc->colormap);
|
||||
|
||||
// We set all params of the colormap to normal because there
|
||||
// is no real way to tell how GL should handle a colormap lump anyway..
|
||||
extra_colormaps[num_extra_colormaps].maskcolor = 0xffff;
|
||||
extra_colormaps[num_extra_colormaps].fadecolor = 0x0;
|
||||
extra_colormaps[num_extra_colormaps].maskamt = 0x0;
|
||||
extra_colormaps[num_extra_colormaps].fadestart = 0;
|
||||
extra_colormaps[num_extra_colormaps].fadeend = 31;
|
||||
extra_colormaps[num_extra_colormaps].fog = 0;
|
||||
exc->fadestart = 0;
|
||||
exc->fadeend = 31;
|
||||
exc->fog = 0;
|
||||
exc->rgba = 0;
|
||||
exc->fadergba = 0x19000000;
|
||||
|
||||
num_extra_colormaps++;
|
||||
return (INT32)num_extra_colormaps - 1;
|
||||
R_AddColormapToList(exc);
|
||||
|
||||
return exc;
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// R_CreateColormap
|
||||
|
@ -1377,107 +1594,60 @@ static double deltas[256][3], map[256][3];
|
|||
static UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b);
|
||||
static int RoundUp(double number);
|
||||
|
||||
INT32 R_CreateColormap(char *p1, char *p2, char *p3)
|
||||
lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap)
|
||||
{
|
||||
double cmaskr, cmaskg, cmaskb, cdestr, cdestg, cdestb;
|
||||
double maskamt = 0, othermask = 0;
|
||||
int mask, fog = 0;
|
||||
size_t mapnum = num_extra_colormaps;
|
||||
|
||||
UINT8 cr = R_GetRgbaR(extra_colormap->rgba),
|
||||
cg = R_GetRgbaG(extra_colormap->rgba),
|
||||
cb = R_GetRgbaB(extra_colormap->rgba),
|
||||
ca = R_GetRgbaA(extra_colormap->rgba),
|
||||
cfr = R_GetRgbaR(extra_colormap->fadergba),
|
||||
cfg = R_GetRgbaG(extra_colormap->fadergba),
|
||||
cfb = R_GetRgbaB(extra_colormap->fadergba);
|
||||
// cfa = R_GetRgbaA(extra_colormap->fadergba); // unused in software
|
||||
|
||||
UINT8 fadestart = extra_colormap->fadestart,
|
||||
fadedist = extra_colormap->fadeend - extra_colormap->fadestart;
|
||||
|
||||
lighttable_t *lighttable = NULL;
|
||||
size_t i;
|
||||
UINT32 cr, cg, cb, maskcolor, fadecolor;
|
||||
UINT32 fadestart = 0, fadeend = 31, fadedist = 31;
|
||||
|
||||
#define HEX2INT(x) (UINT32)(x >= '0' && x <= '9' ? x - '0' : x >= 'a' && x <= 'f' ? x - 'a' + 10 : x >= 'A' && x <= 'F' ? x - 'A' + 10 : 0)
|
||||
if (p1[0] == '#')
|
||||
{
|
||||
cr = ((HEX2INT(p1[1]) * 16) + HEX2INT(p1[2]));
|
||||
cmaskr = cr;
|
||||
cg = ((HEX2INT(p1[3]) * 16) + HEX2INT(p1[4]));
|
||||
cmaskg = cg;
|
||||
cb = ((HEX2INT(p1[5]) * 16) + HEX2INT(p1[6]));
|
||||
cmaskb = cb;
|
||||
// Create a rough approximation of the color (a 16 bit color)
|
||||
maskcolor = ((cb) >> 3) + (((cg) >> 2) << 5) + (((cr) >> 3) << 11);
|
||||
if (p1[7] >= 'a' && p1[7] <= 'z')
|
||||
mask = (p1[7] - 'a');
|
||||
else if (p1[7] >= 'A' && p1[7] <= 'Z')
|
||||
mask = (p1[7] - 'A');
|
||||
else
|
||||
mask = 24;
|
||||
/////////////////////
|
||||
// Calc the RGBA mask
|
||||
/////////////////////
|
||||
cmaskr = cr;
|
||||
cmaskg = cg;
|
||||
cmaskb = cb;
|
||||
|
||||
maskamt = (double)(mask/24.0l);
|
||||
maskamt = (double)(ca/24.0l);
|
||||
othermask = 1 - maskamt;
|
||||
maskamt /= 0xff;
|
||||
|
||||
othermask = 1 - maskamt;
|
||||
maskamt /= 0xff;
|
||||
cmaskr *= maskamt;
|
||||
cmaskg *= maskamt;
|
||||
cmaskb *= maskamt;
|
||||
}
|
||||
else
|
||||
{
|
||||
cmaskr = cmaskg = cmaskb = 0xff;
|
||||
maskamt = 0;
|
||||
maskcolor = ((0xff) >> 3) + (((0xff) >> 2) << 5) + (((0xff) >> 3) << 11);
|
||||
}
|
||||
cmaskr *= maskamt;
|
||||
cmaskg *= maskamt;
|
||||
cmaskb *= maskamt;
|
||||
|
||||
#define NUMFROMCHAR(c) (c >= '0' && c <= '9' ? c - '0' : 0)
|
||||
if (p2[0] == '#')
|
||||
{
|
||||
// Get parameters like fadestart, fadeend, and the fogflag
|
||||
fadestart = NUMFROMCHAR(p2[3]) + (NUMFROMCHAR(p2[2]) * 10);
|
||||
fadeend = NUMFROMCHAR(p2[5]) + (NUMFROMCHAR(p2[4]) * 10);
|
||||
if (fadestart > 30)
|
||||
fadestart = 0;
|
||||
if (fadeend > 31 || fadeend < 1)
|
||||
fadeend = 31;
|
||||
fadedist = fadeend - fadestart;
|
||||
fog = NUMFROMCHAR(p2[1]);
|
||||
}
|
||||
#undef NUMFROMCHAR
|
||||
/////////////////////
|
||||
// Calc the RGBA fade mask
|
||||
/////////////////////
|
||||
cdestr = cfr;
|
||||
cdestg = cfg;
|
||||
cdestb = cfb;
|
||||
|
||||
if (p3[0] == '#')
|
||||
{
|
||||
cdestr = cr = ((HEX2INT(p3[1]) * 16) + HEX2INT(p3[2]));
|
||||
cdestg = cg = ((HEX2INT(p3[3]) * 16) + HEX2INT(p3[4]));
|
||||
cdestb = cb = ((HEX2INT(p3[5]) * 16) + HEX2INT(p3[6]));
|
||||
fadecolor = (((cb) >> 3) + (((cg) >> 2) << 5) + (((cr) >> 3) << 11));
|
||||
}
|
||||
else
|
||||
cdestr = cdestg = cdestb = fadecolor = 0;
|
||||
#undef HEX2INT
|
||||
// fade alpha unused in software
|
||||
// maskamt = (double)(cfa/24.0l);
|
||||
// othermask = 1 - maskamt;
|
||||
// maskamt /= 0xff;
|
||||
|
||||
for (i = 0; i < num_extra_colormaps; i++)
|
||||
{
|
||||
if (foundcolormaps[i] != LUMPERROR)
|
||||
continue;
|
||||
if (maskcolor == extra_colormaps[i].maskcolor
|
||||
&& fadecolor == extra_colormaps[i].fadecolor
|
||||
&& (float)maskamt == (float)extra_colormaps[i].maskamt
|
||||
&& fadestart == extra_colormaps[i].fadestart
|
||||
&& fadeend == extra_colormaps[i].fadeend
|
||||
&& fog == extra_colormaps[i].fog)
|
||||
{
|
||||
return (INT32)i;
|
||||
}
|
||||
}
|
||||
|
||||
if (num_extra_colormaps == MAXCOLORMAPS)
|
||||
I_Error("R_CreateColormap: Too many colormaps! the limit is %d\n", MAXCOLORMAPS);
|
||||
|
||||
num_extra_colormaps++;
|
||||
|
||||
foundcolormaps[mapnum] = LUMPERROR;
|
||||
|
||||
// aligned on 8 bit for asm code
|
||||
extra_colormaps[mapnum].colormap = NULL;
|
||||
extra_colormaps[mapnum].maskcolor = (UINT16)maskcolor;
|
||||
extra_colormaps[mapnum].fadecolor = (UINT16)fadecolor;
|
||||
extra_colormaps[mapnum].maskamt = maskamt;
|
||||
extra_colormaps[mapnum].fadestart = (UINT16)fadestart;
|
||||
extra_colormaps[mapnum].fadeend = (UINT16)fadeend;
|
||||
extra_colormaps[mapnum].fog = fog;
|
||||
// cdestr *= maskamt;
|
||||
// cdestg *= maskamt;
|
||||
// cdestb *= maskamt;
|
||||
|
||||
/////////////////////
|
||||
// This code creates the colormap array used by software renderer
|
||||
/////////////////////
|
||||
if (rendermode == render_soft)
|
||||
{
|
||||
double r, g, b, cbrightness;
|
||||
|
@ -1513,8 +1683,9 @@ INT32 R_CreateColormap(char *p1, char *p2, char *p3)
|
|||
}
|
||||
|
||||
// Now allocate memory for the actual colormap array itself!
|
||||
// aligned on 8 bit for asm code
|
||||
colormap_p = Z_MallocAlign((256 * 34) + 10, PU_LEVEL, NULL, 8);
|
||||
extra_colormaps[mapnum].colormap = (UINT8 *)colormap_p;
|
||||
lighttable = (UINT8 *)colormap_p;
|
||||
|
||||
// Calculate the palette index for each palette index, for each light level
|
||||
// (as well as the two unused colormap lines we inherited from Doom)
|
||||
|
@ -1549,7 +1720,285 @@ INT32 R_CreateColormap(char *p1, char *p2, char *p3)
|
|||
}
|
||||
}
|
||||
|
||||
return (INT32)mapnum;
|
||||
return lighttable;
|
||||
}
|
||||
|
||||
extracolormap_t *R_CreateColormap(char *p1, char *p2, char *p3)
|
||||
{
|
||||
extracolormap_t *extra_colormap, *exc;
|
||||
|
||||
// default values
|
||||
UINT8 cr = 0, cg = 0, cb = 0, ca = 0, cfr = 0, cfg = 0, cfb = 0, cfa = 25;
|
||||
UINT32 fadestart = 0, fadeend = 31;
|
||||
UINT8 fog = 0;
|
||||
INT32 rgba = 0, fadergba = 0x19000000;
|
||||
|
||||
#define HEX2INT(x) (UINT32)(x >= '0' && x <= '9' ? x - '0' : x >= 'a' && x <= 'f' ? x - 'a' + 10 : x >= 'A' && x <= 'F' ? x - 'A' + 10 : 0)
|
||||
#define ALPHA2INT(x) (x >= 'a' && x <= 'z' ? x - 'a' : x >= 'A' && x <= 'Z' ? x - 'A' : x >= '0' && x <= '9' ? 25 : 0)
|
||||
|
||||
// Get base colormap value
|
||||
// First alpha-only, then full value
|
||||
if (p1[0] >= 'a' && p1[0] <= 'z' && !p1[1])
|
||||
ca = (p1[0] - 'a');
|
||||
else if (p1[0] == '#' && p1[1] >= 'a' && p1[1] <= 'z' && !p1[2])
|
||||
ca = (p1[1] - 'a');
|
||||
else if (p1[0] >= 'A' && p1[0] <= 'Z' && !p1[1])
|
||||
ca = (p1[0] - 'A');
|
||||
else if (p1[0] == '#' && p1[1] >= 'A' && p1[1] <= 'Z' && !p1[2])
|
||||
ca = (p1[1] - 'A');
|
||||
else if (p1[0] == '#')
|
||||
{
|
||||
// For each subsequent value, the value before it must exist
|
||||
// If we don't get every value, then set alpha to max
|
||||
if (p1[1] && p1[2])
|
||||
{
|
||||
cr = ((HEX2INT(p1[1]) * 16) + HEX2INT(p1[2]));
|
||||
if (p1[3] && p1[4])
|
||||
{
|
||||
cg = ((HEX2INT(p1[3]) * 16) + HEX2INT(p1[4]));
|
||||
if (p1[5] && p1[6])
|
||||
{
|
||||
cb = ((HEX2INT(p1[5]) * 16) + HEX2INT(p1[6]));
|
||||
|
||||
if (p1[7] >= 'a' && p1[7] <= 'z')
|
||||
ca = (p1[7] - 'a');
|
||||
else if (p1[7] >= 'A' && p1[7] <= 'Z')
|
||||
ca = (p1[7] - 'A');
|
||||
else
|
||||
ca = 25;
|
||||
}
|
||||
else
|
||||
ca = 25;
|
||||
}
|
||||
else
|
||||
ca = 25;
|
||||
}
|
||||
else
|
||||
ca = 25;
|
||||
}
|
||||
|
||||
#define NUMFROMCHAR(c) (c >= '0' && c <= '9' ? c - '0' : 0)
|
||||
|
||||
// Get parameters like fadestart, fadeend, and the fogflag
|
||||
if (p2[0] == '#')
|
||||
{
|
||||
if (p2[1])
|
||||
{
|
||||
fog = NUMFROMCHAR(p2[1]);
|
||||
if (p2[2] && p2[3])
|
||||
{
|
||||
fadestart = NUMFROMCHAR(p2[3]) + (NUMFROMCHAR(p2[2]) * 10);
|
||||
if (p2[4] && p2[5])
|
||||
fadeend = NUMFROMCHAR(p2[5]) + (NUMFROMCHAR(p2[4]) * 10);
|
||||
}
|
||||
}
|
||||
|
||||
if (fadestart > 30)
|
||||
fadestart = 0;
|
||||
if (fadeend > 31 || fadeend < 1)
|
||||
fadeend = 31;
|
||||
}
|
||||
|
||||
#undef NUMFROMCHAR
|
||||
|
||||
// Get fade (dark) colormap value
|
||||
// First alpha-only, then full value
|
||||
if (p3[0] >= 'a' && p3[0] <= 'z' && !p3[1])
|
||||
cfa = (p3[0] - 'a');
|
||||
else if (p3[0] == '#' && p3[1] >= 'a' && p3[1] <= 'z' && !p3[2])
|
||||
cfa = (p3[1] - 'a');
|
||||
else if (p3[0] >= 'A' && p3[0] <= 'Z' && !p3[1])
|
||||
cfa = (p3[0] - 'A');
|
||||
else if (p3[0] == '#' && p3[1] >= 'A' && p3[1] <= 'Z' && !p3[2])
|
||||
cfa = (p3[1] - 'A');
|
||||
else if (p3[0] == '#')
|
||||
{
|
||||
// For each subsequent value, the value before it must exist
|
||||
// If we don't get every value, then set alpha to max
|
||||
if (p3[1] && p3[2])
|
||||
{
|
||||
cfr = ((HEX2INT(p3[1]) * 16) + HEX2INT(p3[2]));
|
||||
if (p3[3] && p3[4])
|
||||
{
|
||||
cfg = ((HEX2INT(p3[3]) * 16) + HEX2INT(p3[4]));
|
||||
if (p3[5] && p3[6])
|
||||
{
|
||||
cfb = ((HEX2INT(p3[5]) * 16) + HEX2INT(p3[6]));
|
||||
|
||||
if (p3[7] >= 'a' && p3[7] <= 'z')
|
||||
cfa = (p3[7] - 'a');
|
||||
else if (p3[7] >= 'A' && p3[7] <= 'Z')
|
||||
cfa = (p3[7] - 'A');
|
||||
else
|
||||
cfa = 25;
|
||||
}
|
||||
else
|
||||
cfa = 25;
|
||||
}
|
||||
else
|
||||
cfa = 25;
|
||||
}
|
||||
else
|
||||
cfa = 25;
|
||||
}
|
||||
#undef ALPHA2INT
|
||||
#undef HEX2INT
|
||||
|
||||
// Pack rgba values into combined var
|
||||
// OpenGL also uses this instead of lighttables for rendering
|
||||
rgba = R_PutRgbaRGBA(cr, cg, cb, ca);
|
||||
fadergba = R_PutRgbaRGBA(cfr, cfg, cfb, cfa);
|
||||
|
||||
// Did we just make a default colormap?
|
||||
#ifdef EXTRACOLORMAPLUMPS
|
||||
if (R_CheckDefaultColormapByValues(true, true, true, rgba, fadergba, fadestart, fadeend, fog, LUMPERROR))
|
||||
return NULL;
|
||||
#else
|
||||
if (R_CheckDefaultColormapByValues(true, true, true, rgba, fadergba, fadestart, fadeend, fog))
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
// Look for existing colormaps
|
||||
#ifdef EXTRACOLORMAPLUMPS
|
||||
exc = R_GetColormapFromListByValues(rgba, fadergba, fadestart, fadeend, fog, LUMPERROR);
|
||||
#else
|
||||
exc = R_GetColormapFromListByValues(rgba, fadergba, fadestart, fadeend, fog);
|
||||
#endif
|
||||
if (exc)
|
||||
return exc;
|
||||
|
||||
CONS_Debug(DBG_RENDER, "Creating Colormap: rgba(%d,%d,%d,%d) fadergba(%d,%d,%d,%d)\n",
|
||||
cr, cg, cb, ca, cfr, cfg, cfb, cfa);
|
||||
|
||||
extra_colormap = Z_Calloc(sizeof (*extra_colormap), PU_LEVEL, NULL);
|
||||
|
||||
extra_colormap->fadestart = (UINT16)fadestart;
|
||||
extra_colormap->fadeend = (UINT16)fadeend;
|
||||
extra_colormap->fog = fog;
|
||||
|
||||
extra_colormap->rgba = rgba;
|
||||
extra_colormap->fadergba = fadergba;
|
||||
|
||||
#ifdef EXTRACOLORMAPLUMPS
|
||||
extra_colormap->lump = LUMPERROR;
|
||||
extra_colormap->lumpname[0] = 0;
|
||||
#endif
|
||||
|
||||
// Having lighttables for alpha-only entries is kind of pointless,
|
||||
// but if there happens to be a matching rgba entry that is NOT alpha-only (but has same rgb values),
|
||||
// then it needs this lighttable because we share matching entries.
|
||||
extra_colormap->colormap = R_CreateLightTable(extra_colormap);
|
||||
|
||||
R_AddColormapToList(extra_colormap);
|
||||
|
||||
return extra_colormap;
|
||||
}
|
||||
|
||||
//
|
||||
// R_AddColormaps()
|
||||
// NOTE: The result colormap is not added to the extra_colormaps chain. You must do that yourself!
|
||||
//
|
||||
extracolormap_t *R_AddColormaps(extracolormap_t *exc_augend, extracolormap_t *exc_addend,
|
||||
boolean subR, boolean subG, boolean subB, boolean subA,
|
||||
boolean subFadeR, boolean subFadeG, boolean subFadeB, boolean subFadeA,
|
||||
boolean subFadeStart, boolean subFadeEnd, boolean ignoreFog,
|
||||
boolean useAltAlpha, INT16 altAlpha, INT16 altFadeAlpha,
|
||||
boolean lighttable)
|
||||
{
|
||||
INT16 red, green, blue, alpha;
|
||||
|
||||
// exc_augend is added (or subtracted) onto by exc_addend
|
||||
// In Rennaisance times, the first number was considered the augend, the second number the addend
|
||||
// But since the commutative property was discovered, today they're both called addends!
|
||||
// So let's be Olde English for a hot second.
|
||||
|
||||
exc_augend = R_CopyColormap(exc_augend, false);
|
||||
if(!exc_addend)
|
||||
exc_addend = R_GetDefaultColormap();
|
||||
|
||||
///////////////////
|
||||
// base rgba
|
||||
///////////////////
|
||||
|
||||
red = max(min(
|
||||
R_GetRgbaR(exc_augend->rgba)
|
||||
+ (subR ? -1 : 1) // subtract R
|
||||
* R_GetRgbaR(exc_addend->rgba)
|
||||
, 255), 0);
|
||||
|
||||
green = max(min(
|
||||
R_GetRgbaG(exc_augend->rgba)
|
||||
+ (subG ? -1 : 1) // subtract G
|
||||
* R_GetRgbaG(exc_addend->rgba)
|
||||
, 255), 0);
|
||||
|
||||
blue = max(min(
|
||||
R_GetRgbaB(exc_augend->rgba)
|
||||
+ (subB ? -1 : 1) // subtract B
|
||||
* R_GetRgbaB(exc_addend->rgba)
|
||||
, 255), 0);
|
||||
|
||||
alpha = useAltAlpha ? altAlpha : R_GetRgbaA(exc_addend->rgba);
|
||||
alpha = max(min(R_GetRgbaA(exc_augend->rgba) + (subA ? -1 : 1) * alpha, 25), 0);
|
||||
|
||||
exc_augend->rgba = R_PutRgbaRGBA(red, green, blue, alpha);
|
||||
|
||||
///////////////////
|
||||
// fade/dark rgba
|
||||
///////////////////
|
||||
|
||||
red = max(min(
|
||||
R_GetRgbaR(exc_augend->fadergba)
|
||||
+ (subFadeR ? -1 : 1) // subtract R
|
||||
* R_GetRgbaR(exc_addend->fadergba)
|
||||
, 255), 0);
|
||||
|
||||
green = max(min(
|
||||
R_GetRgbaG(exc_augend->fadergba)
|
||||
+ (subFadeG ? -1 : 1) // subtract G
|
||||
* R_GetRgbaG(exc_addend->fadergba)
|
||||
, 255), 0);
|
||||
|
||||
blue = max(min(
|
||||
R_GetRgbaB(exc_augend->fadergba)
|
||||
+ (subFadeB ? -1 : 1) // subtract B
|
||||
* R_GetRgbaB(exc_addend->fadergba)
|
||||
, 255), 0);
|
||||
|
||||
alpha = useAltAlpha ? altFadeAlpha : R_GetRgbaA(exc_addend->fadergba);
|
||||
if (alpha == 25 && !useAltAlpha && !R_GetRgbaRGB(exc_addend->fadergba))
|
||||
alpha = 0; // HACK: fadergba A defaults at 25, so don't add anything in this case
|
||||
alpha = max(min(R_GetRgbaA(exc_augend->fadergba) + (subFadeA ? -1 : 1) * alpha, 25), 0);
|
||||
|
||||
exc_augend->fadergba = R_PutRgbaRGBA(red, green, blue, alpha);
|
||||
|
||||
///////////////////
|
||||
// parameters
|
||||
///////////////////
|
||||
|
||||
exc_augend->fadestart = max(min(
|
||||
exc_augend->fadestart
|
||||
+ (subFadeStart ? -1 : 1) // subtract fadestart
|
||||
* exc_addend->fadestart
|
||||
, 31), 0);
|
||||
|
||||
exc_augend->fadeend = max(min(
|
||||
exc_augend->fadeend
|
||||
+ (subFadeEnd ? -1 : 1) // subtract fadeend
|
||||
* (exc_addend->fadeend == 31 && !exc_addend->fadestart ? 0 : exc_addend->fadeend)
|
||||
// HACK: fadeend defaults to 31, so don't add anything in this case
|
||||
, 31), 0);
|
||||
|
||||
if (!ignoreFog) // overwrite fog with new value
|
||||
exc_augend->fog = exc_addend->fog;
|
||||
|
||||
///////////////////
|
||||
// put it together
|
||||
///////////////////
|
||||
|
||||
exc_augend->colormap = lighttable ? R_CreateLightTable(exc_augend) : NULL;
|
||||
exc_augend->next = exc_augend->prev = NULL;
|
||||
return exc_augend;
|
||||
}
|
||||
|
||||
// Thanks to quake2 source!
|
||||
|
@ -1592,20 +2041,18 @@ static int RoundUp(double number)
|
|||
return (int)number;
|
||||
}
|
||||
|
||||
const char *R_ColormapNameForNum(INT32 num)
|
||||
#ifdef EXTRACOLORMAPLUMPS
|
||||
const char *R_NameForColormap(extracolormap_t *extra_colormap)
|
||||
{
|
||||
if (num == -1)
|
||||
if (!extra_colormap)
|
||||
return "NONE";
|
||||
|
||||
if (num < 0 || num > MAXCOLORMAPS)
|
||||
I_Error("R_ColormapNameForNum: num %d is invalid!\n", num);
|
||||
|
||||
if (foundcolormaps[num] == LUMPERROR)
|
||||
if (extra_colormap->lump == LUMPERROR)
|
||||
return "INLEVEL";
|
||||
|
||||
return W_CheckNameForNum(foundcolormaps[num]);
|
||||
return extra_colormap->lumpname;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
// build a table for quick conversion from 8bpp to 15bpp
|
||||
|
|
52
src/r_data.h
52
src/r_data.h
|
@ -96,11 +96,57 @@ void R_ClearTextureNumCache(boolean btell);
|
|||
INT32 R_TextureNumForName(const char *name);
|
||||
INT32 R_CheckTextureNumForName(const char *name);
|
||||
|
||||
// Extra Colormap lumps (C_START/C_END) are not used anywhere
|
||||
// Uncomment to enable
|
||||
//#define EXTRACOLORMAPLUMPS
|
||||
|
||||
// Uncomment to make extra_colormaps order Newest -> Oldest
|
||||
//#define COLORMAPREVERSELIST
|
||||
|
||||
void R_ReInitColormaps(UINT16 num);
|
||||
void R_ClearColormaps(void);
|
||||
INT32 R_ColormapNumForName(char *name);
|
||||
INT32 R_CreateColormap(char *p1, char *p2, char *p3);
|
||||
const char *R_ColormapNameForNum(INT32 num);
|
||||
extracolormap_t *R_CreateDefaultColormap(boolean lighttable);
|
||||
extracolormap_t *R_GetDefaultColormap(void);
|
||||
extracolormap_t *R_CopyColormap(extracolormap_t *extra_colormap, boolean lighttable);
|
||||
void R_AddColormapToList(extracolormap_t *extra_colormap);
|
||||
|
||||
#ifdef EXTRACOLORMAPLUMPS
|
||||
boolean R_CheckDefaultColormapByValues(boolean checkrgba, boolean checkfadergba, boolean checkparams,
|
||||
INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 fog, lumpnum_t lump);
|
||||
extracolormap_t *R_GetColormapFromListByValues(INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 fog, lumpnum_t lump);
|
||||
#else
|
||||
boolean R_CheckDefaultColormapByValues(boolean checkrgba, boolean checkfadergba, boolean checkparams,
|
||||
INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 fog);
|
||||
extracolormap_t *R_GetColormapFromListByValues(INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 fog);
|
||||
#endif
|
||||
boolean R_CheckDefaultColormap(extracolormap_t *extra_colormap, boolean checkrgba, boolean checkfadergba, boolean checkparams);
|
||||
boolean R_CheckEqualColormaps(extracolormap_t *exc_a, extracolormap_t *exc_b, boolean checkrgba, boolean checkfadergba, boolean checkparams);
|
||||
extracolormap_t *R_GetColormapFromList(extracolormap_t *extra_colormap);
|
||||
|
||||
lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap);
|
||||
extracolormap_t *R_CreateColormap(char *p1, char *p2, char *p3);
|
||||
extracolormap_t *R_AddColormaps(extracolormap_t *exc_augend, extracolormap_t *exc_addend,
|
||||
boolean subR, boolean subG, boolean subB, boolean subA,
|
||||
boolean subFadeR, boolean subFadeG, boolean subFadeB, boolean subFadeA,
|
||||
boolean subFadeStart, boolean subFadeEnd, boolean ignoreFog,
|
||||
boolean useAltAlpha, INT16 altAlpha, INT16 altFadeAlpha,
|
||||
boolean lighttable);
|
||||
#ifdef EXTRACOLORMAPLUMPS
|
||||
extracolormap_t *R_ColormapForName(char *name);
|
||||
const char *R_NameForColormap(extracolormap_t *extra_colormap);
|
||||
#endif
|
||||
|
||||
#define R_GetRgbaR(rgba) (rgba & 0xFF)
|
||||
#define R_GetRgbaG(rgba) ((rgba >> 8) & 0xFF)
|
||||
#define R_GetRgbaB(rgba) ((rgba >> 16) & 0xFF)
|
||||
#define R_GetRgbaA(rgba) ((rgba >> 24) & 0xFF)
|
||||
#define R_GetRgbaRGB(rgba) (rgba & 0xFFFFFF)
|
||||
#define R_PutRgbaR(r) (r)
|
||||
#define R_PutRgbaG(g) (g << 8)
|
||||
#define R_PutRgbaB(b) (b << 16)
|
||||
#define R_PutRgbaA(a) (a << 24)
|
||||
#define R_PutRgbaRGB(r, g, b) (R_PutRgbaR(r) + R_PutRgbaG(g) + R_PutRgbaB(b))
|
||||
#define R_PutRgbaRGBA(r, g, b, a) (R_PutRgbaRGB(r, g, b) + R_PutRgbaA(a))
|
||||
|
||||
extern INT32 numtextures;
|
||||
|
||||
|
|
29
src/r_defs.h
29
src/r_defs.h
|
@ -50,18 +50,25 @@ typedef struct
|
|||
typedef UINT8 lighttable_t;
|
||||
|
||||
// ExtraColormap type. Use for extra_colormaps from now on.
|
||||
typedef struct
|
||||
typedef struct extracolormap_s
|
||||
{
|
||||
UINT16 maskcolor, fadecolor;
|
||||
double maskamt;
|
||||
UINT16 fadestart, fadeend;
|
||||
INT32 fog;
|
||||
UINT8 fadestart, fadeend;
|
||||
UINT8 fog; // categorical value, not boolean
|
||||
|
||||
// rgba is used in hw mode for colored sector lighting
|
||||
// store rgba values in combined bitwise
|
||||
// also used in OpenGL instead lighttables
|
||||
INT32 rgba; // similar to maskcolor in sw mode
|
||||
INT32 fadergba; // The colour the colourmaps fade to
|
||||
|
||||
lighttable_t *colormap;
|
||||
|
||||
#ifdef EXTRACOLORMAPLUMPS
|
||||
lumpnum_t lump; // for colormap lump matching, init to LUMPERROR
|
||||
char lumpname[9]; // for netsyncing
|
||||
#endif
|
||||
|
||||
struct extracolormap_s *next;
|
||||
struct extracolormap_s *prev;
|
||||
} extracolormap_t;
|
||||
|
||||
//
|
||||
|
@ -189,7 +196,7 @@ typedef struct lightlist_s
|
|||
{
|
||||
fixed_t height;
|
||||
INT16 *lightlevel;
|
||||
extracolormap_t *extra_colormap;
|
||||
extracolormap_t **extra_colormap; // pointer-to-a-pointer, so we can react to colormap changes
|
||||
INT32 flags;
|
||||
ffloor_t *caster;
|
||||
#ifdef ESLOPE
|
||||
|
@ -325,8 +332,6 @@ typedef struct sector_s
|
|||
INT32 floorlightsec, ceilinglightsec;
|
||||
INT32 crumblestate; // used for crumbling and bobbing
|
||||
|
||||
INT32 bottommap, midmap, topmap; // dynamic colormaps
|
||||
|
||||
// list of mobjs that are at least partially in the sector
|
||||
// thinglist is a subset of touching_thinglist
|
||||
struct msecnode_s *touching_thinglist;
|
||||
|
@ -390,7 +395,6 @@ typedef struct sector_s
|
|||
|
||||
// these are saved for netgames, so do not let Lua touch these!
|
||||
INT32 spawn_nexttag, spawn_firsttag; // the actual nexttag/firsttag values may differ if the sector's tag was changed
|
||||
INT32 spawn_bottommap, spawn_midmap, spawn_topmap;
|
||||
|
||||
// offsets sector spawned with (via linedef type 7)
|
||||
fixed_t spawn_flr_xoffs, spawn_flr_yoffs;
|
||||
|
@ -399,6 +403,9 @@ typedef struct sector_s
|
|||
// flag angles sector spawned with (via linedef type 7)
|
||||
angle_t spawn_flrpic_angle;
|
||||
angle_t spawn_ceilpic_angle;
|
||||
|
||||
// colormap structure
|
||||
extracolormap_t *spawn_extra_colormap;
|
||||
} sector_t;
|
||||
|
||||
//
|
||||
|
@ -474,6 +481,8 @@ typedef struct
|
|||
INT16 repeatcnt; // # of times to repeat midtexture
|
||||
|
||||
char *text; // a concatination of all top, bottom, and mid texture names, for linedef specials that require a string.
|
||||
|
||||
extracolormap_t *colormap_data; // storage for colormaps; not applied to sectors.
|
||||
} side_t;
|
||||
|
||||
//
|
||||
|
|
|
@ -118,8 +118,7 @@ lighttable_t *scalelightfixed[MAXLIGHTSCALE];
|
|||
lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ];
|
||||
|
||||
// Hack to support extra boom colormaps.
|
||||
size_t num_extra_colormaps;
|
||||
extracolormap_t extra_colormaps[MAXCOLORMAPS];
|
||||
extracolormap_t *extra_colormaps = NULL;
|
||||
|
||||
static CV_PossibleValue_t drawdist_cons_t[] = {
|
||||
{256, "256"}, {512, "512"}, {768, "768"},
|
||||
|
|
|
@ -413,7 +413,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
#endif
|
||||
rlight->startheight = rlight->height; // keep starting value here to reset for each repeat
|
||||
rlight->lightlevel = *light->lightlevel;
|
||||
rlight->extra_colormap = light->extra_colormap;
|
||||
rlight->extra_colormap = *light->extra_colormap;
|
||||
rlight->flags = light->flags;
|
||||
|
||||
if (rlight->flags & FF_FOG || (rlight->extra_colormap && rlight->extra_colormap->fog))
|
||||
|
@ -944,7 +944,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
}
|
||||
|
||||
rlight->lightlevel = *light->lightlevel;
|
||||
rlight->extra_colormap = light->extra_colormap;
|
||||
rlight->extra_colormap = *light->extra_colormap;
|
||||
|
||||
// Check if the current light effects the colormap/lightlevel
|
||||
if (pfloor->flags & FF_FOG)
|
||||
|
@ -2808,7 +2808,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
|||
}
|
||||
|
||||
rlight->lightlevel = *light->lightlevel;
|
||||
rlight->extra_colormap = light->extra_colormap;
|
||||
rlight->extra_colormap = *light->extra_colormap;
|
||||
p++;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,11 +40,7 @@ extern sprcache_t *spritecachedinfo;
|
|||
extern lighttable_t *colormaps;
|
||||
|
||||
// Boom colormaps.
|
||||
// Had to put a limit on colormaps :(
|
||||
#define MAXCOLORMAPS 60
|
||||
|
||||
extern size_t num_extra_colormaps;
|
||||
extern extracolormap_t extra_colormaps[MAXCOLORMAPS];
|
||||
extern extracolormap_t *extra_colormaps;
|
||||
|
||||
// for global animation
|
||||
extern INT32 *texturetranslation;
|
||||
|
|
|
@ -981,7 +981,7 @@ static void R_SplitSprite(vissprite_t *sprite)
|
|||
else
|
||||
spritelights = scalelight[lightnum];
|
||||
|
||||
newsprite->extra_colormap = sector->lightlist[i].extra_colormap;
|
||||
newsprite->extra_colormap = *sector->lightlist[i].extra_colormap;
|
||||
|
||||
if (!((newsprite->cut & SC_FULLBRIGHT)
|
||||
&& (!newsprite->extra_colormap || !(newsprite->extra_colormap->fog & 1))))
|
||||
|
@ -1360,7 +1360,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
vis->sz = (INT16)((centeryfrac - FixedMul(vis->gz - viewz, sortscale))>>FRACBITS);
|
||||
vis->cut = cut;
|
||||
if (thing->subsector->sector->numlights)
|
||||
vis->extra_colormap = thing->subsector->sector->lightlist[light].extra_colormap;
|
||||
vis->extra_colormap = *thing->subsector->sector->lightlist[light].extra_colormap;
|
||||
else
|
||||
vis->extra_colormap = thing->subsector->sector->extra_colormap;
|
||||
|
||||
|
|
Loading…
Reference in a new issue