From 4ab3a986f319ec7632e4d0d0fde3f2e325f1704c Mon Sep 17 00:00:00 2001 From: mazmazz Date: Thu, 13 Sep 2018 00:04:50 -0400 Subject: [PATCH] 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 --- src/p_polyobj.c | 85 +++++++++++++++++++++++++++++++++++++------------ src/p_polyobj.h | 6 ++-- src/p_saveg.c | 6 ++-- src/p_spec.c | 57 +++++++++++++++++++++++++-------- 4 files changed, 116 insertions(+), 38 deletions(-) diff --git a/src/p_polyobj.c b/src/p_polyobj.c index b47afed27..f7545e5bd 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -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; diff --git a/src/p_polyobj.h b/src/p_polyobj.h index d5c07cb5b..61404112c 100644 --- a/src/p_polyobj.h +++ b/src/p_polyobj.h @@ -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; // diff --git a/src/p_saveg.c b/src/p_saveg.c index 403f05b00..2bfc5859a 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -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 diff --git a/src/p_spec.c b/src/p_spec.c index 65f7fcd67..49d266f99 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -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); }