From 156d1e61fdf2cef56442be33fd404e174a41d5a0 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Mon, 2 Mar 2015 19:17:24 -0600 Subject: [PATCH] Use sub-tic accuracy for smooth sine quakes - Converting the wave speed back to floats, since I'm using sin() instead of the finesine table now. - Pre-shift the quake intensities to avoid extra shifting in GetModIntensity. - Loading old saves will shift the intensities to fixed point but will not convert the fixed wave speeds to floats. The chances of this being in a savegame where the speeds are non-zero is pretty much nil, and int and floating point 0 are bitwise identical (not counting -0.0). --- src/g_shared/a_quake.cpp | 38 +++++++++++++++---------------- src/g_shared/a_sharedglobal.h | 8 +++---- src/p_spec.h | 2 +- src/thingdef/thingdef_codeptr.cpp | 6 ++--- 4 files changed, 26 insertions(+), 28 deletions(-) diff --git a/src/g_shared/a_quake.cpp b/src/g_shared/a_quake.cpp index 6ddcd0e41..3c8d704aa 100644 --- a/src/g_shared/a_quake.cpp +++ b/src/g_shared/a_quake.cpp @@ -35,23 +35,23 @@ DEarthquake::DEarthquake() DEarthquake::DEarthquake (AActor *center, int intensityX, int intensityY, int intensityZ, int duration, int damrad, int tremrad, FSoundID quakesound, int flags, - fixed_t waveSpeedX, fixed_t waveSpeedY, fixed_t waveSpeedZ) + double waveSpeedX, double waveSpeedY, double waveSpeedZ) : DThinker(STAT_EARTHQUAKE) { m_QuakeSFX = quakesound; m_Spot = center; // Radii are specified in tile units (64 pixels) - m_DamageRadius = damrad << (FRACBITS); - m_TremorRadius = tremrad << (FRACBITS); - m_IntensityX = intensityX; - m_IntensityY = intensityY; - m_IntensityZ = intensityZ; + m_DamageRadius = damrad << FRACBITS; + m_TremorRadius = tremrad << FRACBITS; + m_IntensityX = intensityX << FRACBITS; + m_IntensityY = intensityY << FRACBITS; + m_IntensityZ = intensityZ << FRACBITS; m_CountdownStart = duration; m_Countdown = duration; m_Flags = flags; - m_WaveSpeedX = waveSpeedX; - m_WaveSpeedY = waveSpeedY; - m_WaveSpeedZ = waveSpeedZ; + m_WaveSpeedX = (float)waveSpeedX; + m_WaveSpeedY = (float)waveSpeedY; + m_WaveSpeedZ = (float)waveSpeedZ; } //========================================================================== @@ -87,6 +87,9 @@ void DEarthquake::Serialize (FArchive &arc) if (SaveVersion < 4521) { m_WaveSpeedX = m_WaveSpeedY = m_WaveSpeedZ = 0; + m_IntensityX <<= FRACBITS; + m_IntensityY <<= FRACBITS; + m_IntensityZ <<= FRACBITS; } else { @@ -163,15 +166,14 @@ void DEarthquake::Tick () } } -fixed_t DEarthquake::GetModWave(fixed_t waveMultiplier) const +fixed_t DEarthquake::GetModWave(double waveMultiplier) const { //QF_WAVE converts intensity into amplitude and unlocks a new property, the wave length. //This is, in short, waves per second (full cycles, mind you, from 0 to 360.) //Named waveMultiplier because that's as the name implies: adds more waves per second. - fixed_t wavesPerSecond = (waveMultiplier >> 15) * m_Countdown % (TICRATE * 2); - fixed_t index = ((wavesPerSecond * (FINEANGLES / 2)) / (TICRATE)); - return finesine[index & FINEMASK]; + double time = m_Countdown - FIXED2DBL(r_TicFrac); + return FLOAT2FIXED(sin(waveMultiplier * time * (M_PI * 2 / TICRATE))); } //========================================================================== @@ -182,7 +184,7 @@ fixed_t DEarthquake::GetModWave(fixed_t waveMultiplier) const // //========================================================================== -fixed_t DEarthquake::GetModIntensity(int intensity) const +fixed_t DEarthquake::GetModIntensity(fixed_t intensity) const { assert(m_CountdownStart >= m_Countdown); intensity += intensity; // always doubled @@ -209,11 +211,7 @@ fixed_t DEarthquake::GetModIntensity(int intensity) const scalar = m_CountdownStart - m_Countdown; } assert(m_CountdownStart > 0); - intensity = intensity * (scalar << FRACBITS) / m_CountdownStart; - } - else - { - intensity <<= FRACBITS; + intensity = Scale(intensity, scalar, m_CountdownStart); } return intensity; } @@ -305,7 +303,7 @@ int DEarthquake::StaticGetQuakeIntensities(AActor *victim, FQuakeJiggers &jigger bool P_StartQuakeXYZ(AActor *activator, int tid, int intensityX, int intensityY, int intensityZ, int duration, int damrad, int tremrad, FSoundID quakesfx, int flags, - fixed_t waveSpeedX, fixed_t waveSpeedY, fixed_t waveSpeedZ) + double waveSpeedX, double waveSpeedY, double waveSpeedZ) { AActor *center; bool res = false; diff --git a/src/g_shared/a_sharedglobal.h b/src/g_shared/a_sharedglobal.h index 7c994f3c7..3d9e4ed10 100644 --- a/src/g_shared/a_sharedglobal.h +++ b/src/g_shared/a_sharedglobal.h @@ -156,7 +156,7 @@ class DEarthquake : public DThinker public: DEarthquake(AActor *center, int intensityX, int intensityY, int intensityZ, int duration, int damrad, int tremrad, FSoundID quakesfx, int flags, - fixed_t waveSpeedX, fixed_t waveSpeedY, fixed_t waveSpeedZ); + double waveSpeedX, double waveSpeedY, double waveSpeedZ); void Serialize (FArchive &arc); void Tick (); @@ -166,11 +166,11 @@ public: int m_CountdownStart; FSoundID m_QuakeSFX; int m_Flags; - int m_IntensityX, m_IntensityY, m_IntensityZ; - fixed_t m_WaveSpeedX, m_WaveSpeedY, m_WaveSpeedZ; + fixed_t m_IntensityX, m_IntensityY, m_IntensityZ; + float m_WaveSpeedX, m_WaveSpeedY, m_WaveSpeedZ; fixed_t GetModIntensity(int intensity) const; - fixed_t GetModWave(fixed_t waveMultiplier) const; + fixed_t GetModWave(double waveMultiplier) const; static int StaticGetQuakeIntensities(AActor *viewer, FQuakeJiggers &jiggers); diff --git a/src/p_spec.h b/src/p_spec.h index b0c66b10e..5b4f0ba99 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -929,7 +929,7 @@ void P_DoDeferedScripts (void); // // [RH] p_quake.c // -bool P_StartQuakeXYZ(AActor *activator, int tid, int intensityX, int intensityY, int intensityZ, int duration, int damrad, int tremrad, FSoundID quakesfx, int flags, fixed_t waveSpeedX, fixed_t waveSpeedY, fixed_t waveSpeedZ); +bool P_StartQuakeXYZ(AActor *activator, int tid, int intensityX, int intensityY, int intensityZ, int duration, int damrad, int tremrad, FSoundID quakesfx, int flags, double waveSpeedX, double waveSpeedY, double waveSpeedZ); bool P_StartQuake(AActor *activator, int tid, int intensity, int duration, int damrad, int tremrad, FSoundID quakesfx); #endif diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 2c289849a..4da9cea5f 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -4428,9 +4428,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_QuakeEx) ACTION_PARAM_INT(tremrad, 5); ACTION_PARAM_SOUND(sound, 6); ACTION_PARAM_INT(flags, 7); - ACTION_PARAM_FIXED(mulWaveX, 8); - ACTION_PARAM_FIXED(mulWaveY, 9); - ACTION_PARAM_FIXED(mulWaveZ, 10); + ACTION_PARAM_DOUBLE(mulWaveX, 8); + ACTION_PARAM_DOUBLE(mulWaveY, 9); + ACTION_PARAM_DOUBLE(mulWaveZ, 10); P_StartQuakeXYZ(self, 0, intensityX, intensityY, intensityZ, duration, damrad, tremrad, sound, flags, mulWaveX, mulWaveY, mulWaveZ); }