492 PolyObj Fade, 491 PolyObj Translucency, 490 PolyObj changes

* 490: Set proper render flags according to spawnflags
* 491: Add relative calc (EFFECT3) and Front X alpha param (DONTPEGTOP)
* 492:
    * Tic-based (EFFECT4) and speed timing
    * Add relative calc (EFFECT3) and Front X alpha param (DONTPEGTOP)
    * Set proper render flags according to spawnflags
    * Fix OpenGL >= NUMTRANSMAPS render bug
This commit is contained in:
mazmazz 2018-09-13 00:04:50 -04:00
parent 0697a1b90a
commit 4ab3a986f3
4 changed files with 116 additions and 38 deletions

View File

@ -2873,23 +2873,54 @@ void T_PolyObjFade(polyfade_t *th)
if (po->thinker == NULL)
po->thinker = &th->thinker;
stillfading = !(--(th->timer) <= 0);
if (th->timer <= 0)
if (th->ticbased)
{
po->translucency = th->destvalue; // set to dest translucency
stillfading = !(--(th->timer) <= 0);
// remove thinker
if (po->thinker == &th->thinker)
po->thinker = NULL;
P_RemoveThinker(&th->thinker);
}
else if (!(th->timer % th->interval))
{
if (th->speed <= 0)
po->translucency = max(po->translucency + th->speed, th->destvalue);
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
po->translucency = min(po->translucency + th->speed, th->destvalue);
{
INT16 delta = abs(th->destvalue - th->sourcevalue);
fixed_t factor = min(FixedDiv(th->speed - th->timer, th->speed), 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);
}
}
else
{
fixed_t timerdest = FixedMul(FixedDiv(256, NUMTRANSMAPS), NUMTRANSMAPS-th->destvalue);
if (th->destvalue > th->sourcevalue) // fading out, destvalue is higher
{
// for timer, lower is transparent, higher is opaque
stillfading = (th->timer > timerdest);
th->timer = max(timerdest, th->timer - th->speed);
}
else if (th->destvalue < th->sourcevalue) // fading in, destvalue is lower
{ stillfading = (th->timer < timerdest);
th->timer = min(timerdest, th->timer + th->speed);
}
if (!stillfading)
{
po->translucency = max(min(th->destvalue, NUMTRANSMAPS), 0);
// remove thinker
if (po->thinker == &th->thinker)
po->thinker = NULL;
P_RemoveThinker(&th->thinker);
}
else
po->translucency = FixedDiv(256-th->timer, FixedDiv(256, NUMTRANSMAPS));
}
if (!stillfading)
@ -2901,9 +2932,9 @@ void T_PolyObjFade(polyfade_t *th)
po->flags |= (po->spawnflags & POF_RENDERALL);
// set collision
if (th->docollision && th->speed)
if (th->docollision)
{
if (th->speed > 0) // faded out
if (th->destvalue > th->sourcevalue) // faded out
{
po->flags &= ~POF_SOLID;
po->flags |= POF_NOSPECIALS;
@ -2918,10 +2949,14 @@ void T_PolyObjFade(polyfade_t *th)
}
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 && th->speed)
if (th->docollision)
{
if (th->doghostfade)
{
@ -2967,12 +3002,22 @@ INT32 EV_DoPolyObjFade(polyfadedata_t *pfdata)
// set fields
th->polyObjNum = pfdata->polyObjNum;
th->sourcevalue = po->translucency;
th->destvalue = pfdata->destvalue;
th->docollision = pfdata->docollision;
th->doghostfade = pfdata->doghostfade;
th->timer = pfdata->timer;
th->speed = pfdata->speed;
th->interval = pfdata->interval;
if (pfdata->ticbased)
{
th->ticbased = true;
th->timer = th->speed = abs(pfdata->speed); // use th->speed for total duration
}
else
{
th->ticbased = false;
th->timer = FixedMul(FixedDiv(256, NUMTRANSMAPS), NUMTRANSMAPS - po->translucency); // use as internal counter
th->speed = pfdata->speed;
}
oldpo = po;

View File

@ -212,12 +212,13 @@ typedef struct polyfade_s
thinker_t thinker; // must be first
INT32 polyObjNum;
INT32 sourcevalue;
INT32 destvalue;
boolean docollision;
boolean doghostfade;
boolean ticbased;
INT32 timer;
INT32 speed;
UINT32 interval;
} polyfade_t;
//
@ -285,9 +286,8 @@ typedef struct polyfadedata_s
INT32 destvalue;
boolean docollision;
boolean doghostfade;
INT32 timer;
boolean ticbased;
INT32 speed;
UINT32 interval;
} polyfadedata_t;
//

View File

@ -1705,12 +1705,13 @@ 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->timer);
WRITEINT32(save_p, ht->speed);
WRITEUINT32(save_p, ht->interval);
}
#endif
@ -2719,12 +2720,13 @@ 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->timer = READINT32(save_p);
ht->speed = READINT32(save_p);
ht->interval = READUINT32(save_p);
P_AddThinker(&ht->thinker);
}
#endif

View File

@ -1242,7 +1242,21 @@ 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) ?
max(min(sides[line->sidenum[0]].textureoffset>>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) ?
max(min(sides[line->sidenum[0]].textureoffset>>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);
}
//
@ -1265,22 +1279,39 @@ static boolean PolyFade(line_t *line)
if (po->isBad)
return 0;
// already equal, nothing to do
if (po->translucency == max(min(sides[line->sidenum[0]].textureoffset>>FRACBITS, NUMTRANSMAPS), 0))
return 1;
polyfadedata_t pfd;
pfd.polyObjNum = polyObjNum;
pfd.destvalue = max(min(sides[line->sidenum[0]].textureoffset>>FRACBITS, NUMTRANSMAPS), 0);
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.timer = abs(sides[line->sidenum[0]].rowoffset>>FRACBITS);
pfd.speed = FixedFloor(FixedDiv(pfd.destvalue - po->translucency, pfd.timer))/FRACUNIT;
if (!pfd.speed)
pfd.speed = (pfd.destvalue < po->translucency) ? -1 : 1;
pfd.interval = max(FixedFloor(FixedDiv(pfd.timer, abs(pfd.destvalue - po->translucency)))/FRACUNIT, 1);
// if DONTPEGBOTTOM, specify raw translucency value in Front X Offset
// else, take it out of 1000 like type 491. If Front X Offset is specified, use that. Else, use floorheight.
if (line->flags & ML_EFFECT3)
pfd.destvalue = max(min(po->translucency + ((line->flags & ML_DONTPEGBOTTOM) ?
max(min(sides[line->sidenum[0]].textureoffset>>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) ?
max(min(sides[line->sidenum[0]].textureoffset>>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);
}