diff --git a/src/p_saveg.c b/src/p_saveg.c index 334279a9a..162241573 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1593,6 +1593,9 @@ static void SaveFadeThinker(const thinker_t *th, const UINT8 type) WRITEINT16(save_p, ht->destvalue); WRITEINT16(save_p, ht->destlightlevel); WRITEINT16(save_p, ht->speed); + WRITEINT32(save_p, ht->duration); + WRITEUINT32(save_p, ht->interval); + WRITEUINT32(save_p, (UINT32)ht->firsttic); WRITEUINT8(save_p, ht->doexists); WRITEUINT8(save_p, ht->dotranslucent); WRITEUINT8(save_p, ht->dolighting); @@ -2602,6 +2605,9 @@ static inline void LoadFadeThinker(actionf_p1 thinker) ht->destvalue = READINT16(save_p); ht->destlightlevel = READINT16(save_p); ht->speed = READINT16(save_p); + ht->duration = READINT32(save_p); + ht->interval = READUINT32(save_p); + ht->firsttic = (tic_t)READUINT32(save_p); ht->doexists = READUINT8(save_p); ht->dotranslucent = READUINT8(save_p); ht->dolighting = READUINT8(save_p); diff --git a/src/p_spec.c b/src/p_spec.c index d291d1e3b..8d1f4f295 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -105,10 +105,10 @@ static void Add_Pusher(pushertype_e type, fixed_t x_mag, fixed_t y_mag, mobj_t * static void Add_MasterDisappearer(tic_t appeartime, tic_t disappeartime, tic_t offset, INT32 line, INT32 sourceline); static void P_ResetFakeFloorFader(ffloor_t *rover, fade_t *data, boolean finalize); #define P_RemoveFakeFloorFader(l) P_ResetFakeFloorFader(l, NULL, false); -static boolean P_FadeFakeFloor(ffloor_t *rover, INT16 destvalue, INT16 speed, +static boolean P_FadeFakeFloor(ffloor_t *rover, INT16 destvalue, INT16 speed, INT32 duration, UINT32 interval, tic_t firsttic, boolean doexists, boolean dotranslucent, boolean dolighting, boolean docollision, boolean doghostfade, boolean exactalpha); static void P_AddFakeFloorFader(ffloor_t *rover, size_t sectornum, size_t ffloornum, - INT16 destvalue, INT16 speed, + INT16 destvalue, INT16 speed, boolean ticbased, boolean doexists, boolean dotranslucent, boolean dolighting, boolean docollision, boolean doghostfade, boolean exactalpha); static void P_AddBlockThinker(sector_t *sec, line_t *sourceline); static void P_AddFloatThinker(sector_t *sec, INT32 tag, line_t *sourceline); @@ -3356,6 +3356,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) if (speed > 0) P_AddFakeFloorFader(rover, secnum, j, destvalue, speed, + (line->flags & ML_EFFECT5), // tic-based logic !(line->flags & ML_BLOCKMONSTERS), // do not handle FF_EXISTS !(line->flags & ML_NOCLIMB), // do not handle FF_TRANSLUCENT !(line->flags & ML_EFFECT2), // do not handle lighting @@ -3367,6 +3368,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) P_RemoveFakeFloorFader(rover); P_FadeFakeFloor(rover, destvalue, 0, // set alpha immediately + -1, 0, 0, // tic-based logic !(line->flags & ML_BLOCKMONSTERS), // do not handle FF_EXISTS !(line->flags & ML_NOCLIMB), // do not handle FF_TRANSLUCENT !(line->flags & ML_EFFECT2), // do not handle lighting @@ -7444,6 +7446,9 @@ static void P_ResetFakeFloorFader(ffloor_t *rover, fade_t *data, boolean finaliz fadingdata->alpha - 1 : // trigger fade-out finish fadingdata->alpha + 1, // trigger fade-in finish 0, + fadingdata->duration, + fadingdata->interval, + fadingdata->firsttic, fadingdata->doexists, fadingdata->dotranslucent, fadingdata->docollision, @@ -7462,9 +7467,10 @@ static void P_ResetFakeFloorFader(ffloor_t *rover, fade_t *data, boolean finaliz } } -static boolean P_FadeFakeFloor(ffloor_t *rover, INT16 destvalue, INT16 speed, +static boolean P_FadeFakeFloor(ffloor_t *rover, INT16 destvalue, INT16 speed, INT32 duration, UINT32 interval, tic_t firsttic, boolean doexists, boolean dotranslucent, boolean dolighting, boolean docollision, boolean doghostfade, boolean exactalpha) { + boolean ticbased = (duration > -1); boolean stillfading = false; INT32 alpha; fade_t *fadingdata = (fade_t *)rover->fadingdata; @@ -7492,7 +7498,8 @@ static boolean P_FadeFakeFloor(ffloor_t *rover, INT16 destvalue, INT16 speed, else if (alpha > destvalue) // fade out { // finish fading out - if (speed < 1 || alpha - speed <= destvalue + speed) + if (speed < 1 || (!ticbased && alpha - speed <= destvalue + speed) || + (ticbased && (gametic - firsttic >= duration || alpha <= destvalue))) { alpha = destvalue; @@ -7512,14 +7519,18 @@ static boolean P_FadeFakeFloor(ffloor_t *rover, INT16 destvalue, INT16 speed, } else // continue fading out { - alpha -= speed; + if (!ticbased) + alpha -= speed; + else if (ticbased && !((gametic - firsttic) % interval)) + alpha = max(alpha - speed, destvalue); stillfading = true; } } else // fade in { // finish fading in - if (speed < 1 || alpha + speed >= destvalue - speed) + if (speed < 1 || (!ticbased && alpha + speed >= destvalue - speed) || + (ticbased && (gametic - firsttic >= duration || alpha >= destvalue))) { alpha = destvalue; @@ -7539,7 +7550,10 @@ static boolean P_FadeFakeFloor(ffloor_t *rover, INT16 destvalue, INT16 speed, } else // continue fading in { - alpha += speed; + if (!ticbased) + alpha += speed; + else if (ticbased && !((gametic - firsttic) % interval)) + alpha = min(alpha + speed, destvalue); stillfading = true; } } @@ -7692,6 +7706,7 @@ static boolean P_FadeFakeFloor(ffloor_t *rover, INT16 destvalue, INT16 speed, * * \param destvalue transparency value to fade to * \param speed speed to fade by + * \param ticbased tic-based logic, speed = duration * \param doexists handle FF_EXISTS * \param dotranslucent handle FF_TRANSLUCENT * \param dolighting fade FOF light @@ -7700,7 +7715,7 @@ static boolean P_FadeFakeFloor(ffloor_t *rover, INT16 destvalue, INT16 speed, * \param exactalpha use exact alpha values (opengl) */ static void P_AddFakeFloorFader(ffloor_t *rover, size_t sectornum, size_t ffloornum, - INT16 destvalue, INT16 speed, + INT16 destvalue, INT16 speed, boolean ticbased, boolean doexists, boolean dotranslucent, boolean dolighting, boolean docollision, boolean doghostfade, boolean exactalpha) { // already equal, nothing to do @@ -7725,7 +7740,21 @@ static void P_AddFakeFloorFader(ffloor_t *rover, size_t sectornum, size_t ffloor d->alpha = rover->alpha; d->destvalue = max(1, min(256, destvalue)); // ffloor->alpha is 1-256 - d->speed = max(1, speed); // minimum speed 1/tic // if speed < 1, alpha is set immediately in thinker + + if (ticbased) + { + d->duration = abs(speed); + d->speed = max(abs(FixedFloor(FixedDiv(d->destvalue - d->alpha, d->duration))/FRACUNIT), 1); + d->interval = max(FixedFloor(FixedDiv(d->duration, abs(d->destvalue - d->alpha)))/FRACUNIT, 1); + d->firsttic = gametic; + } + else + { + d->speed = max(1, speed); // minimum speed 1/tic // if speed < 1, alpha is set immediately in thinker + d->duration = -1; + d->interval = d->firsttic = 0; + } + d->doexists = doexists; d->dotranslucent = dotranslucent; d->dolighting = dolighting; @@ -7750,7 +7779,8 @@ static void P_AddFakeFloorFader(ffloor_t *rover, size_t sectornum, size_t ffloor P_FadeLightBySector(§ors[rover->secnum], d->destlightlevel, - FixedFloor(FixedDiv(abs(d->destvalue - d->alpha), d->speed))/FRACUNIT, + ticbased ? d->duration : + FixedFloor(FixedDiv(abs(d->destvalue - d->alpha), d->speed))/FRACUNIT, true); } else @@ -7766,7 +7796,8 @@ static void P_AddFakeFloorFader(ffloor_t *rover, size_t sectornum, size_t ffloor */ void T_Fade(fade_t *d) { - if (d->rover && !P_FadeFakeFloor(d->rover, d->destvalue, d->speed, d->doexists, d->dotranslucent, d->dolighting, d->docollision, d->doghostfade, d->exactalpha)) + if (d->rover && !P_FadeFakeFloor(d->rover, d->destvalue, d->speed, d->duration, d->interval, d->firsttic, + d->doexists, d->dotranslucent, d->dolighting, d->docollision, d->doghostfade, d->exactalpha)) { // Finalize lighting, copypasta from P_AddFakeFloorFader if (d->dolighting && !(d->rover->flags & FF_NOSHADE) && d->destlightlevel > -1) diff --git a/src/p_spec.h b/src/p_spec.h index 461ae876b..93d113be3 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -472,6 +472,9 @@ typedef struct INT16 destvalue; ///< Transparency value to fade to INT16 destlightlevel; ///< Light level to fade to INT16 speed; ///< Speed to fade by + INT32 duration; ///< Duration for tic-based logic, > -1 means use tic-based + UINT32 interval; ///< Skip interval for tic-based logic + tic_t firsttic; ///< First tic for tic-based logic boolean doexists; ///< Handle FF_EXISTS boolean dotranslucent; ///< Handle FF_TRANSLUCENT boolean dolighting; ///< Handle shadows and light blocks