From 2827c13d0c4d4fe8411154f4d9d788dd0939803f Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Fri, 20 Feb 2015 19:36:13 -0600 Subject: [PATCH] Rewrite new quake stuff for correctness - Quake scaling should be handled for each quake. The former implementation was potentially taking flags from one quake and applying them to another, which is broken. - Remove all the int<->float conversions. --- src/g_shared/a_quake.cpp | 79 +++++++++++++++++++++++++---------- src/g_shared/a_sharedglobal.h | 15 +++---- src/r_utility.cpp | 70 ++++++++----------------------- 3 files changed, 80 insertions(+), 84 deletions(-) diff --git a/src/g_shared/a_quake.cpp b/src/g_shared/a_quake.cpp index 5cce4c3716..e1b340f279 100644 --- a/src/g_shared/a_quake.cpp +++ b/src/g_shared/a_quake.cpp @@ -45,7 +45,7 @@ DEarthquake::DEarthquake (AActor *center, int intensityX, int intensityY, int in m_IntensityX = intensityX; m_IntensityY = intensityY; m_IntensityZ = intensityZ; - m_CountdownStart = (double)duration; + m_CountdownStart = duration; m_Countdown = duration; m_Flags = flags; } @@ -151,6 +151,48 @@ void DEarthquake::Tick () } } +//========================================================================== +// +// DEarthquake :: GetModIntensity +// +// Given a base intensity, modify it according to the quake's flags. +// +//========================================================================== + +fixed_t DEarthquake::GetModIntensity(int intensity) const +{ + assert(m_CountdownStart >= m_Countdown); + intensity += intensity; // always doubled + if (m_Flags & (QF_SCALEDOWN | QF_SCALEUP)) + { + int scalar; + if ((m_Flags & (QF_SCALEDOWN | QF_SCALEUP)) == (QF_SCALEDOWN | QF_SCALEUP)) + { + scalar = (m_Flags & QF_MAX) ? MAX(m_Countdown, m_CountdownStart - m_Countdown) + : MIN(m_Countdown, m_CountdownStart - m_Countdown); + if (m_Flags & QF_FULLINTENSITY) + { + scalar *= 2; + } + } + else if (m_Flags & QF_SCALEDOWN) + { + scalar = m_Countdown; + } + else // QF_SCALEUP + { + scalar = m_CountdownStart - m_Countdown; + } + assert(m_CountdownStart > 0); + intensity = intensity * (scalar << FRACBITS) / m_CountdownStart; + } + else + { + intensity <<= FRACBITS; + } + return intensity; +} + //========================================================================== // // DEarthquake::StaticGetQuakeIntensity @@ -160,14 +202,15 @@ void DEarthquake::Tick () // //========================================================================== -int DEarthquake::StaticGetQuakeIntensities(AActor *victim, quakeInfo &qprop) +int DEarthquake::StaticGetQuakeIntensities(AActor *victim, + fixed_t &intensityX, fixed_t &intensityY, fixed_t &intensityZ, + fixed_t &relIntensityX, fixed_t &relIntensityY, fixed_t &relIntensityZ) { if (victim->player != NULL && (victim->player->cheats & CF_NOCLIP)) { return 0; } - qprop.isScalingDown = qprop.isScalingUp = qprop.preferMaximum = qprop.fullIntensity = false; - qprop.intensityX = qprop.intensityY = qprop.intensityZ = qprop.relIntensityX = qprop.relIntensityY = qprop.relIntensityZ = 0; + intensityX = intensityY = intensityZ = relIntensityX = relIntensityY = relIntensityZ = 0; TThinkerIterator iterator(STAT_EARTHQUAKE); DEarthquake *quake; @@ -182,30 +225,20 @@ int DEarthquake::StaticGetQuakeIntensities(AActor *victim, quakeInfo &qprop) if (dist < quake->m_TremorRadius) { ++count; + fixed_t x = quake->GetModIntensity(quake->m_IntensityX); + fixed_t y = quake->GetModIntensity(quake->m_IntensityY); + fixed_t z = quake->GetModIntensity(quake->m_IntensityZ); if (quake->m_Flags & QF_RELATIVE) { - qprop.relIntensityX = MAX(qprop.relIntensityX, quake->m_IntensityX); - qprop.relIntensityY = MAX(qprop.relIntensityY, quake->m_IntensityY); - qprop.relIntensityZ = MAX(qprop.relIntensityZ, quake->m_IntensityZ); + relIntensityX = MAX(relIntensityX, x); + relIntensityY = MAX(relIntensityY, y); + relIntensityZ = MAX(relIntensityZ, z); } else { - qprop.intensityX = MAX(qprop.intensityX, quake->m_IntensityX); - qprop.intensityY = MAX(qprop.intensityY, quake->m_IntensityY); - qprop.intensityZ = MAX(qprop.intensityZ, quake->m_IntensityZ); - } - if (quake->m_Flags) - { - qprop.scaleDownStart = quake->m_CountdownStart; - qprop.scaleDown = quake->m_Countdown; - qprop.isScalingDown = (quake->m_Flags & QF_SCALEDOWN) ? true : false; - qprop.isScalingUp = (quake->m_Flags & QF_SCALEUP) ? true : false; - qprop.preferMaximum = (quake->m_Flags & QF_MAX) ? true : false; - qprop.fullIntensity = (quake->m_Flags & QF_FULLINTENSITY) ? true : false; - } - else - { - qprop.scaleDownStart = qprop.scaleDown = 0.0; + intensityX = MAX(intensityX, x); + intensityY = MAX(intensityY, y); + intensityZ = MAX(intensityZ, z); } } } diff --git a/src/g_shared/a_sharedglobal.h b/src/g_shared/a_sharedglobal.h index 00247c224d..02ba94036b 100644 --- a/src/g_shared/a_sharedglobal.h +++ b/src/g_shared/a_sharedglobal.h @@ -140,13 +140,6 @@ enum QF_FULLINTENSITY = 1 << 4, }; -struct quakeInfo -{ - int intensityX, intensityY, intensityZ, relIntensityX, relIntensityY, relIntensityZ; - double scaleDown, scaleDownStart; - bool isScalingDown, isScalingUp, preferMaximum, fullIntensity; -}; - class DEarthquake : public DThinker { DECLARE_CLASS (DEarthquake, DThinker) @@ -159,12 +152,16 @@ public: TObjPtr m_Spot; fixed_t m_TremorRadius, m_DamageRadius; int m_Countdown; - double m_CountdownStart; + int m_CountdownStart; FSoundID m_QuakeSFX; int m_Flags; int m_IntensityX, m_IntensityY, m_IntensityZ; - static int StaticGetQuakeIntensities(AActor *viewer, quakeInfo &qprop); + fixed_t GetModIntensity(int intensity) const; + + static int StaticGetQuakeIntensities(AActor *viewer, + fixed_t &intensityX, fixed_t &intensityY, fixed_t &intensityZ, + fixed_t &relIntensityX, fixed_t &relIntensityY, fixed_t &relIntensityZ); private: DEarthquake (); diff --git a/src/r_utility.cpp b/src/r_utility.cpp index ebcff8af56..c82216e742 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -770,45 +770,9 @@ bool R_GetViewInterpolationStatus() // //========================================================================== -static fixed_t QuakePower(double factor, int intensity, quakeInfo quake) +static fixed_t QuakePower(fixed_t factor, fixed_t intensity) { - double scaleDownStart = quake.scaleDownStart; - double scaleDown = quake.scaleDown; - if (intensity == 0) - { - return 0; - } - else - { - double ss = (double)((pr_torchflicker() % (intensity << 2)) - (intensity << 1)); - double mtp = (quake.fullIntensity) ? 2.0 : 1.0; - if (quake.isScalingDown || quake.isScalingUp) - { - fixed_t result; - if (scaleDownStart == 0) scaleDownStart = 1; - - if (quake.isScalingDown && quake.isScalingUp) - { - if (quake.preferMaximum) - result = FLOAT2FIXED((factor * ss) * MAX(((scaleDown*mtp) / scaleDownStart), ((scaleDownStart - scaleDown)*mtp) / scaleDownStart)); - else - result = FLOAT2FIXED((factor * ss) * MIN(((scaleDown*mtp) / scaleDownStart), ((scaleDownStart - scaleDown)*mtp) / scaleDownStart)); - } - else if (quake.isScalingDown) - result = FLOAT2FIXED((factor * ss) * (scaleDown / scaleDownStart)); - else if (quake.isScalingUp) - result = FLOAT2FIXED((factor * ss) * ((scaleDownStart - scaleDown) / scaleDownStart)); - else - result = FLOAT2FIXED(factor * ss); - - return result; - } - else - { - return FLOAT2FIXED(factor * ss); - } - } - + return FixedMul(factor, pr_torchflicker(intensity * 2) - intensity); } //========================================================================== @@ -921,38 +885,40 @@ void R_SetupFrame (AActor *actor) if (!paused) { - quakeInfo quake; - if (DEarthquake::StaticGetQuakeIntensities(camera, quake) > 0) + fixed_t intensityX, intensityY, intensityZ, relIntensityX, relIntensityY, relIntensityZ; + if (DEarthquake::StaticGetQuakeIntensities(camera, + intensityX, intensityY, intensityZ, + relIntensityX, relIntensityY, relIntensityZ) > 0) { - double quakefactor = r_quakeintensity; + fixed_t quakefactor = FLOAT2FIXED(r_quakeintensity); - if (quake.relIntensityX != 0) + if (relIntensityX != 0) { int ang = (camera->angle) >> ANGLETOFINESHIFT; - fixed_t power = QuakePower(quakefactor, quake.relIntensityX, quake); + fixed_t power = QuakePower(quakefactor, relIntensityX); viewx += FixedMul(finecosine[ang], power); viewy += FixedMul(finesine[ang], power); } - if (quake.relIntensityY != 0) + if (relIntensityY != 0) { int ang = (camera->angle + ANG90) >> ANGLETOFINESHIFT; - fixed_t power = QuakePower(quakefactor, quake.relIntensityY, quake); + fixed_t power = QuakePower(quakefactor, relIntensityY); viewx += FixedMul(finecosine[ang], power); viewy += FixedMul(finesine[ang], power); } - if (quake.intensityX != 0) + if (intensityX != 0) { - viewx += QuakePower(quakefactor, quake.intensityX, quake); + viewx += QuakePower(quakefactor, intensityX); } - if (quake.intensityY != 0) + if (intensityY != 0) { - viewy += QuakePower(quakefactor, quake.intensityY, quake); + viewy += QuakePower(quakefactor, intensityY); } // FIXME: Relative Z is not relative - quake.intensityZ = MAX(quake.intensityZ, quake.relIntensityZ); - if (quake.intensityZ != 0) + intensityZ = MAX(intensityZ, relIntensityZ); + if (intensityZ != 0) { - viewz += QuakePower(quakefactor, quake.intensityZ, quake); + viewz += QuakePower(quakefactor, intensityZ); } } }