mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-01-18 07:22:28 +00:00
Merge branch 'colormap-overhaul-fade' into 'master'
Linedef Exec 455 Fade Colormap, 456 Stop Fading Colormap See merge request STJr/SRB2Internal!191
This commit is contained in:
commit
a036c42973
5 changed files with 297 additions and 1 deletions
|
@ -1289,6 +1289,7 @@ typedef enum
|
|||
tc_noenemies,
|
||||
tc_eachtime,
|
||||
tc_disappear,
|
||||
tc_fadecolormap,
|
||||
tc_planedisplace,
|
||||
#ifdef POLYOBJECTS
|
||||
tc_polyrotate, // haleyjd 03/26/06: polyobjects
|
||||
|
@ -1860,6 +1861,23 @@ static void SaveDisappearThinker(const thinker_t *th, const UINT8 type)
|
|||
WRITEINT32(save_p, ht->exists);
|
||||
}
|
||||
|
||||
//
|
||||
// SaveFadeColormapThinker
|
||||
//
|
||||
// Saves a fadecolormap_t thinker
|
||||
//
|
||||
static void SaveFadeColormapThinker(const thinker_t *th, const UINT8 type)
|
||||
{
|
||||
const fadecolormap_t *ht = (const void *)th;
|
||||
WRITEUINT8(save_p, type);
|
||||
WRITEUINT32(save_p, SaveSector(ht->sector));
|
||||
WRITEUINT32(save_p, CheckAddNetColormapToList(ht->source_exc));
|
||||
WRITEUINT32(save_p, CheckAddNetColormapToList(ht->dest_exc));
|
||||
WRITEUINT8(save_p, (UINT8)ht->ticbased);
|
||||
WRITEINT32(save_p, ht->duration);
|
||||
WRITEINT32(save_p, ht->timer);
|
||||
}
|
||||
|
||||
//
|
||||
// SavePlaneDisplaceThinker
|
||||
//
|
||||
|
@ -2181,6 +2199,11 @@ static void P_NetArchiveThinkers(void)
|
|||
SaveDisappearThinker(th, tc_disappear);
|
||||
continue;
|
||||
}
|
||||
else if (th->function.acp1 == (actionf_p1)T_FadeColormap)
|
||||
{
|
||||
SaveFadeColormapThinker(th, tc_fadecolormap);
|
||||
continue;
|
||||
}
|
||||
|
||||
else if (th->function.acp1 == (actionf_p1)T_PlaneDisplace)
|
||||
{
|
||||
|
@ -2868,6 +2891,26 @@ static inline void LoadDisappearThinker(actionf_p1 thinker)
|
|||
P_AddThinker(&ht->thinker);
|
||||
}
|
||||
|
||||
//
|
||||
// LoadFadeColormapThinker
|
||||
//
|
||||
// Loads a fadecolormap_t from a save game
|
||||
//
|
||||
static inline void LoadFadeColormapThinker(actionf_p1 thinker)
|
||||
{
|
||||
fadecolormap_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
|
||||
ht->thinker.function.acp1 = thinker;
|
||||
ht->sector = LoadSector(READUINT32(save_p));
|
||||
ht->source_exc = GetNetColormapFromList(READUINT32(save_p));
|
||||
ht->dest_exc = GetNetColormapFromList(READUINT32(save_p));
|
||||
ht->ticbased = (boolean)READUINT8(save_p);
|
||||
ht->duration = READINT32(save_p);
|
||||
ht->timer = READINT32(save_p);
|
||||
if (ht->sector)
|
||||
ht->sector->fadecolormapdata = ht;
|
||||
P_AddThinker(&ht->thinker);
|
||||
}
|
||||
|
||||
//
|
||||
// LoadPlaneDisplaceThinker
|
||||
//
|
||||
|
@ -3074,7 +3117,7 @@ static void P_NetUnArchiveThinkers(void)
|
|||
// clear sector thinker pointers so they don't point to non-existant thinkers for all of eternity
|
||||
for (i = 0; i < numsectors; i++)
|
||||
{
|
||||
sectors[i].floordata = sectors[i].ceilingdata = sectors[i].lightingdata = NULL;
|
||||
sectors[i].floordata = sectors[i].ceilingdata = sectors[i].lightingdata = sectors[i].fadecolormapdata = NULL;
|
||||
}
|
||||
|
||||
// read in saved thinkers
|
||||
|
@ -3195,6 +3238,10 @@ static void P_NetUnArchiveThinkers(void)
|
|||
LoadDisappearThinker((actionf_p1)T_Disappear);
|
||||
break;
|
||||
|
||||
case tc_fadecolormap:
|
||||
LoadFadeColormapThinker((actionf_p1)T_FadeColormap);
|
||||
break;
|
||||
|
||||
case tc_planedisplace:
|
||||
LoadPlaneDisplaceThinker((actionf_p1)T_PlaneDisplace);
|
||||
break;
|
||||
|
|
|
@ -1470,6 +1470,7 @@ static void P_LoadRawSideDefs2(void *data)
|
|||
case 63: // variable colormap via 242 linedef
|
||||
case 606: //SoM: 4/4/2000: Just colormap transfer
|
||||
case 447: // Change colormap of tagged sectors! -- Monster Iestyn 14/06/18
|
||||
case 455: // Fade colormaps! mazmazz 9/12/2018 (:flag_us:)
|
||||
// SoM: R_CreateColormap will only create a colormap in software mode...
|
||||
// Perhaps we should just call it instead of doing the calculations here.
|
||||
sd->colormap_data = R_CreateColormap(msd->toptexture, msd->midtexture,
|
||||
|
|
232
src/p_spec.c
232
src/p_spec.c
|
@ -103,6 +103,9 @@ static void P_SpawnFriction(void);
|
|||
static void P_SpawnPushers(void);
|
||||
static void Add_Pusher(pushertype_e type, fixed_t x_mag, fixed_t y_mag, mobj_t *source, INT32 affectee, INT32 referrer, INT32 exclusive, INT32 slider); //SoM: 3/9/2000
|
||||
static void Add_MasterDisappearer(tic_t appeartime, tic_t disappeartime, tic_t offset, INT32 line, INT32 sourceline);
|
||||
static void P_ResetColormapFader(sector_t *sector);
|
||||
static void Add_ColormapFader(sector_t *sector, extracolormap_t *source_exc, extracolormap_t *dest_exc,
|
||||
boolean ticbased, INT32 duration);
|
||||
static void P_AddBlockThinker(sector_t *sec, line_t *sourceline);
|
||||
static void P_AddFloatThinker(sector_t *sec, INT32 tag, line_t *sourceline);
|
||||
//static void P_AddBridgeThinker(line_t *sourceline, sector_t *sec);
|
||||
|
@ -3353,6 +3356,8 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
// -- Monster Iestyn 14/06/18
|
||||
for (secnum = -1; (secnum = P_FindSectorFromLineTag(line, secnum)) >= 0 ;)
|
||||
{
|
||||
P_ResetColormapFader(§ors[secnum]);
|
||||
|
||||
if (line->flags & ML_EFFECT3) // relative calc
|
||||
{
|
||||
extracolormap_t *exc = R_AddColormaps(
|
||||
|
@ -3464,6 +3469,100 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
|||
break;
|
||||
}
|
||||
|
||||
case 455: // Fade colormap
|
||||
for (secnum = -1; (secnum = P_FindSectorFromLineTag(line, secnum)) >= 0 ;)
|
||||
{
|
||||
extracolormap_t *source_exc, *dest_exc, *exc;
|
||||
INT32 speed = (INT32)((line->flags & ML_DONTPEGBOTTOM) || !sides[line->sidenum[0]].rowoffset) && line->sidenum[1] != 0xFFFF ?
|
||||
abs(sides[line->sidenum[1]].rowoffset >> FRACBITS)
|
||||
: abs(sides[line->sidenum[0]].rowoffset >> FRACBITS);
|
||||
|
||||
// Prevent continuous execs from interfering on an existing fade
|
||||
if (!(line->flags & ML_EFFECT5)
|
||||
&& sectors[secnum].fadecolormapdata)
|
||||
//&& ((fadecolormap_t*)sectors[secnum].fadecolormapdata)->timer > (ticbased ? 2 : speed*2))
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "Line type 455 Executor: Fade color thinker already exists, timer: %d\n", ((fadecolormap_t*)sectors[secnum].fadecolormapdata)->timer);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (line->flags & ML_TFERLINE) // use back colormap instead of target sector
|
||||
sectors[secnum].extra_colormap = (line->sidenum[1] != 0xFFFF) ?
|
||||
sides[line->sidenum[1]].colormap_data : NULL;
|
||||
|
||||
exc = sectors[secnum].extra_colormap;
|
||||
|
||||
if (!(line->flags & ML_BOUNCY) // BOUNCY: Do not override fade from default rgba
|
||||
&& !R_CheckDefaultColormap(sides[line->sidenum[0]].colormap_data, true, false, false)
|
||||
&& R_CheckDefaultColormap(exc, true, false, false))
|
||||
{
|
||||
exc = R_CopyColormap(exc, false);
|
||||
exc->rgba = R_GetRgbaRGB(sides[line->sidenum[0]].colormap_data->rgba) + R_PutRgbaA(R_GetRgbaA(exc->rgba));
|
||||
//exc->fadergba = R_GetRgbaRGB(sides[line->sidenum[0]].colormap_data->rgba) + R_PutRgbaA(R_GetRgbaA(exc->fadergba));
|
||||
|
||||
if (!(source_exc = R_GetColormapFromList(exc)))
|
||||
{
|
||||
exc->colormap = R_CreateLightTable(exc);
|
||||
R_AddColormapToList(exc);
|
||||
source_exc = exc;
|
||||
}
|
||||
else
|
||||
Z_Free(exc);
|
||||
|
||||
sectors[secnum].extra_colormap = source_exc;
|
||||
}
|
||||
else
|
||||
source_exc = exc ? exc : R_GetDefaultColormap();
|
||||
|
||||
if (line->flags & ML_EFFECT3) // relative calc
|
||||
{
|
||||
exc = R_AddColormaps(
|
||||
source_exc,
|
||||
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);
|
||||
}
|
||||
else if (line->flags & ML_DONTPEGBOTTOM) // alternate alpha (by texture offsets)
|
||||
{
|
||||
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));
|
||||
}
|
||||
else
|
||||
exc = R_CopyColormap(sides[line->sidenum[0]].colormap_data, false);
|
||||
|
||||
if (!(dest_exc = R_GetColormapFromList(exc)))
|
||||
{
|
||||
exc->colormap = R_CreateLightTable(exc);
|
||||
R_AddColormapToList(exc);
|
||||
dest_exc = exc;
|
||||
}
|
||||
else
|
||||
Z_Free(exc);
|
||||
|
||||
Add_ColormapFader(§ors[secnum], source_exc, dest_exc, (line->flags & ML_EFFECT4), // tic-based timing
|
||||
speed);
|
||||
}
|
||||
break;
|
||||
|
||||
case 456: // Stop fade colormap
|
||||
for (secnum = -1; (secnum = P_FindSectorFromLineTag(line, secnum)) >= 0 ;)
|
||||
P_ResetColormapFader(§ors[secnum]);
|
||||
break;
|
||||
|
||||
#ifdef POLYOBJECTS
|
||||
case 480: // Polyobj_DoorSlide
|
||||
case 481: // Polyobj_DoorSwing
|
||||
|
@ -7479,6 +7578,139 @@ void T_Disappear(disappear_t *d)
|
|||
}
|
||||
}
|
||||
|
||||
static void P_ResetColormapFader(sector_t *sector)
|
||||
{
|
||||
if (sector->fadecolormapdata)
|
||||
{
|
||||
// The thinker is the first member in all the action structs,
|
||||
// so just let the thinker get freed, and that will free the whole
|
||||
// structure.
|
||||
P_RemoveThinker(&((elevator_t *)sector->fadecolormapdata)->thinker);
|
||||
sector->fadecolormapdata = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void Add_ColormapFader(sector_t *sector, extracolormap_t *source_exc, extracolormap_t *dest_exc,
|
||||
boolean ticbased, INT32 duration)
|
||||
{
|
||||
fadecolormap_t *d;
|
||||
|
||||
P_ResetColormapFader(sector);
|
||||
|
||||
// nothing to do, set immediately
|
||||
if (!duration || R_CheckEqualColormaps(source_exc, dest_exc, true, true, true))
|
||||
{
|
||||
sector->extra_colormap = dest_exc;
|
||||
return;
|
||||
}
|
||||
|
||||
d = Z_Malloc(sizeof *d, PU_LEVSPEC, NULL);
|
||||
d->thinker.function.acp1 = (actionf_p1)T_FadeColormap;
|
||||
d->sector = sector;
|
||||
d->source_exc = source_exc;
|
||||
d->dest_exc = dest_exc;
|
||||
|
||||
if (ticbased)
|
||||
{
|
||||
d->ticbased = true;
|
||||
d->duration = d->timer = duration;
|
||||
}
|
||||
else
|
||||
{
|
||||
d->ticbased = false;
|
||||
d->timer = 256;
|
||||
d->duration = duration; // use as speed
|
||||
}
|
||||
|
||||
sector->fadecolormapdata = d;
|
||||
P_AddThinker(&d->thinker); // add thinker
|
||||
}
|
||||
|
||||
void T_FadeColormap(fadecolormap_t *d)
|
||||
{
|
||||
if ((d->ticbased && --d->timer <= 0)
|
||||
|| (!d->ticbased && (d->timer -= d->duration) <= 0)) // d->duration used as speed decrement
|
||||
{
|
||||
d->sector->extra_colormap = d->dest_exc;
|
||||
P_ResetColormapFader(d->sector);
|
||||
}
|
||||
else
|
||||
{
|
||||
extracolormap_t *exc;
|
||||
INT32 duration = d->ticbased ? d->duration : 256;
|
||||
fixed_t factor = min(FixedDiv(duration - d->timer, duration), 1*FRACUNIT);
|
||||
INT16 cr, cg, cb, ca, fadestart, fadeend, fog;
|
||||
INT32 rgba, fadergba;
|
||||
|
||||
// NULL failsafes (or intentionally set to signify default)
|
||||
if (!d->sector->extra_colormap)
|
||||
d->sector->extra_colormap = R_GetDefaultColormap();
|
||||
|
||||
if (!d->source_exc)
|
||||
d->source_exc = R_GetDefaultColormap();
|
||||
|
||||
if (!d->dest_exc)
|
||||
d->dest_exc = R_GetDefaultColormap();
|
||||
|
||||
// For each var (rgba + fadergba + params = 11 vars), we apply
|
||||
// percentage fading: currentval = sourceval + (delta * percent of duration elapsed)
|
||||
// delta is negative when fading out (destval is lower)
|
||||
// max/min are used to ensure progressive calcs don't go backwards and to cap values to dest.
|
||||
|
||||
#define APPLYFADE(dest, src, cur) (\
|
||||
(dest-src < 0) ? \
|
||||
max(\
|
||||
min(cur,\
|
||||
src + (INT16)FixedMul(dest-src, factor)),\
|
||||
dest)\
|
||||
: (dest-src > 0) ? \
|
||||
min(\
|
||||
max(cur,\
|
||||
src + (INT16)FixedMul(dest-src, factor)),\
|
||||
dest)\
|
||||
: \
|
||||
dest\
|
||||
)
|
||||
|
||||
cr = APPLYFADE(R_GetRgbaR(d->dest_exc->rgba), R_GetRgbaR(d->source_exc->rgba), R_GetRgbaR(d->sector->extra_colormap->rgba));
|
||||
cg = APPLYFADE(R_GetRgbaG(d->dest_exc->rgba), R_GetRgbaG(d->source_exc->rgba), R_GetRgbaG(d->sector->extra_colormap->rgba));
|
||||
cb = APPLYFADE(R_GetRgbaB(d->dest_exc->rgba), R_GetRgbaB(d->source_exc->rgba), R_GetRgbaB(d->sector->extra_colormap->rgba));
|
||||
ca = APPLYFADE(R_GetRgbaA(d->dest_exc->rgba), R_GetRgbaA(d->source_exc->rgba), R_GetRgbaA(d->sector->extra_colormap->rgba));
|
||||
|
||||
rgba = R_PutRgbaRGBA(cr, cg, cb, ca);
|
||||
|
||||
cr = APPLYFADE(R_GetRgbaR(d->dest_exc->fadergba), R_GetRgbaR(d->source_exc->fadergba), R_GetRgbaR(d->sector->extra_colormap->fadergba));
|
||||
cg = APPLYFADE(R_GetRgbaG(d->dest_exc->fadergba), R_GetRgbaG(d->source_exc->fadergba), R_GetRgbaG(d->sector->extra_colormap->fadergba));
|
||||
cb = APPLYFADE(R_GetRgbaB(d->dest_exc->fadergba), R_GetRgbaB(d->source_exc->fadergba), R_GetRgbaB(d->sector->extra_colormap->fadergba));
|
||||
ca = APPLYFADE(R_GetRgbaA(d->dest_exc->fadergba), R_GetRgbaA(d->source_exc->fadergba), R_GetRgbaA(d->sector->extra_colormap->fadergba));
|
||||
|
||||
fadergba = R_PutRgbaRGBA(cr, cg, cb, ca);
|
||||
|
||||
fadestart = APPLYFADE(d->dest_exc->fadestart, d->source_exc->fadestart, d->sector->extra_colormap->fadestart);
|
||||
fadeend = APPLYFADE(d->dest_exc->fadeend, d->source_exc->fadeend, d->sector->extra_colormap->fadeend);
|
||||
fog = abs(factor) > FRACUNIT/2 ? d->dest_exc->fog : d->source_exc->fog; // set new fog flag halfway through fade
|
||||
|
||||
#undef APPLYFADE
|
||||
|
||||
//////////////////
|
||||
// setup new colormap
|
||||
//////////////////
|
||||
|
||||
if (!(d->sector->extra_colormap = R_GetColormapFromListByValues(rgba, fadergba, fadestart, fadeend, fog)))
|
||||
{
|
||||
exc = R_CreateDefaultColormap(false);
|
||||
exc->fadestart = fadestart;
|
||||
exc->fadeend = fadeend;
|
||||
exc->fog = (boolean)fog;
|
||||
exc->rgba = rgba;
|
||||
exc->fadergba = fadergba;
|
||||
exc->colormap = R_CreateLightTable(exc);
|
||||
R_AddColormapToList(exc);
|
||||
d->sector->extra_colormap = exc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
SoM: 3/8/2000: Friction functions start.
|
||||
Add_Friction,
|
||||
|
|
15
src/p_spec.h
15
src/p_spec.h
|
@ -459,6 +459,21 @@ typedef struct
|
|||
|
||||
void T_Disappear(disappear_t *d);
|
||||
|
||||
// Model for fading colormaps
|
||||
|
||||
typedef struct
|
||||
{
|
||||
thinker_t thinker; ///< Thinker structure for effect.
|
||||
sector_t *sector; ///< Sector where action is taking place.
|
||||
extracolormap_t *source_exc;
|
||||
extracolormap_t *dest_exc;
|
||||
boolean ticbased; ///< Tic-based timing
|
||||
INT32 duration; ///< Total duration for tic-based logic (OR: speed increment)
|
||||
INT32 timer; ///< Timer for tic-based logic (OR: internal speed counter)
|
||||
} fadecolormap_t;
|
||||
|
||||
void T_FadeColormap(fadecolormap_t *d);
|
||||
|
||||
// Prototype functions for pushers
|
||||
void T_Pusher(pusher_t *p);
|
||||
mobj_t *P_GetPushThing(UINT32 s);
|
||||
|
|
|
@ -315,6 +315,7 @@ typedef struct sector_s
|
|||
void *floordata; // floor move thinker
|
||||
void *ceilingdata; // ceiling move thinker
|
||||
void *lightingdata; // lighting change thinker
|
||||
void *fadecolormapdata; // fade colormap thinker
|
||||
|
||||
// floor and ceiling texture offsets
|
||||
fixed_t floor_xoffs, floor_yoffs;
|
||||
|
|
Loading…
Reference in a new issue