From dca5f0e908dfeeff636ee8a55272b91a7689f16f Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 1 Mar 2015 18:53:34 -0600 Subject: [PATCH] Added QF_SINE - Squashed commit of the following: commit bc45fe3263d34ef5f746f524687999c19bf7b779 Author: Randy Heit Date: Sun Mar 1 18:51:05 2015 -0600 wave scale -> wave speed commit ff96388b128c724c1198757bfa52f1935a263356 Author: Randy Heit Date: Sun Mar 1 18:45:32 2015 -0600 More sine quake fixes commit 2a89749a6fe6d271b9fbdc218779f680afcf4cb6 Merge: 719dfbe 5456074 Author: MajorCooke Date: Sat Feb 28 20:37:22 2015 -0600 Added QF_WAVE to A_QuakeEx. - Changes the random quakes into a sine wave (see Shadow Warrior/Rise of the Triad reboots, Hard Reset, etc.) - Added 3 properties to control waves per second along each individual axis. Only works with QF_WAVE. - Intensity X/Y/Z property becomes the amplitude of the wave. - Stacks with regular quakes, allowing shaking along the camera which must be called using A_QuakeEx WITHOUT the flag, or the other quaking functions. - Uses the youngest quake's time for positioning. commit 54560741581e8d15cc7060e8e068cf85e9a4b432 Author: MajorCooke Date: Sat Feb 28 20:21:19 2015 -0600 Recommitted recommended changes by Randi, with some modifications. Now, we should be finished! commit 6f4473013411686d88fc185bdc1cc58b1035b0f1 Author: MajorCooke Date: Sat Feb 28 12:52:57 2015 -0600 Finish this revert. commit 467e53f9400f588a2ada9b32e7634cb1f4ad5066 Author: MajorCooke Date: Sat Feb 28 12:46:02 2015 -0600 Reverted back to what was working. commit da9de56a67efda08036e481fd5fccd5392ce6810 Author: MajorCooke Date: Thu Feb 26 18:53:20 2015 -0600 Forgot this bit, for testing. commit c5093d9bb97caf8478cefc32abc56a036feeea58 Author: MajorCooke Date: Thu Feb 26 18:52:46 2015 -0600 Some more progress, but... - This did not solve anything. In fact, it did the opposite -- completely broke wave quakes. Now they only happen whenever a random quake is in progress. - Left in the commented code on purpose so Randi can test it. commit 7e526405d2127cbb279f66008c8f8e55a5d497f3 Author: MajorCooke Date: Wed Feb 25 17:50:42 2015 -0600 - Use newest waveform timer, not oldest. commit 1356443609dbc6c7f46e081d0846816dc0836124 Author: MajorCooke Date: Wed Feb 25 17:32:09 2015 -0600 - Got regular quakes to multiply onto sine quakes, but the vice versa needs fixing too. commit d95796c94c70cd0229d4a6d30f69e3a7568b9588 Author: MajorCooke Date: Wed Feb 25 16:46:21 2015 -0600 - Last hurdle. Now just need to figure out how to properly scale up and down. commit 4bc3458e689155ce72c09776604d9eb4fa73d8be Author: MajorCooke Date: Tue Feb 24 23:18:03 2015 -0600 - Fixed the quakes being unstackable. commit b51012d6d4ea065bf7f6fc9c1a0472966491f7af Author: MajorCooke Date: Mon Feb 23 23:48:34 2015 -0600 QF_WAVE renamed from SINE. - Lots of ground covered, but still more to go. - Still need to figure out how to make the camera properly shudder. commit 427e4893193470bbf45415ffec70a0b69b8cccfd Author: MajorCooke Date: Sun Feb 22 16:52:30 2015 -0600 - Begin the groundworks for QF_SINE. - Need to figure out how to rework and manipulate the sine wave to move faster, and to allow going below 0 without breaking it too much. --- src/g_shared/a_quake.cpp | 93 +++++++++++++++++++++++------- src/g_shared/a_sharedglobal.h | 19 ++++-- src/p_spec.h | 2 +- src/r_utility.cpp | 57 +++++++++++------- src/thingdef/thingdef_codeptr.cpp | 7 ++- src/version.h | 2 +- wadsrc/static/actors/actor.txt | 2 +- wadsrc/static/actors/constants.txt | 1 + 8 files changed, 131 insertions(+), 52 deletions(-) diff --git a/src/g_shared/a_quake.cpp b/src/g_shared/a_quake.cpp index e1b340f279..2adef6affa 100644 --- a/src/g_shared/a_quake.cpp +++ b/src/g_shared/a_quake.cpp @@ -34,7 +34,8 @@ DEarthquake::DEarthquake() //========================================================================== DEarthquake::DEarthquake (AActor *center, int intensityX, int intensityY, int intensityZ, int duration, - int damrad, int tremrad, FSoundID quakesound, int flags) + int damrad, int tremrad, FSoundID quakesound, int flags, + fixed_t waveSpeedX, fixed_t waveSpeedY, fixed_t waveSpeedZ) : DThinker(STAT_EARTHQUAKE) { m_QuakeSFX = quakesound; @@ -48,6 +49,9 @@ DEarthquake::DEarthquake (AActor *center, int intensityX, int intensityY, int in m_CountdownStart = duration; m_Countdown = duration; m_Flags = flags; + m_WaveSpeedX = waveSpeedX; + m_WaveSpeedY = waveSpeedY; + m_WaveSpeedZ = waveSpeedZ; } //========================================================================== @@ -80,6 +84,14 @@ void DEarthquake::Serialize (FArchive &arc) { arc << m_CountdownStart; } + if (SaveVersion < 4521) + { + m_WaveSpeedX = m_WaveSpeedY = m_WaveSpeedZ = 0; + } + else + { + arc << m_WaveSpeedX << m_WaveSpeedY << m_WaveSpeedZ; + } } //========================================================================== @@ -151,6 +163,17 @@ void DEarthquake::Tick () } } +fixed_t DEarthquake::GetModWave(fixed_t 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]; +} + //========================================================================== // // DEarthquake :: GetModIntensity @@ -163,13 +186,15 @@ 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); + : MIN(m_Countdown, m_CountdownStart - m_Countdown); + if (m_Flags & QF_FULLINTENSITY) { scalar *= 2; @@ -186,10 +211,6 @@ fixed_t DEarthquake::GetModIntensity(int intensity) const assert(m_CountdownStart > 0); intensity = intensity * (scalar << FRACBITS) / m_CountdownStart; } - else - { - intensity <<= FRACBITS; - } return intensity; } @@ -200,17 +221,16 @@ fixed_t DEarthquake::GetModIntensity(int intensity) const // Searches for all quakes near the victim and returns their combined // intensity. // +// Pre: jiggers was pre-zeroed by the caller. +// //========================================================================== -int DEarthquake::StaticGetQuakeIntensities(AActor *victim, - fixed_t &intensityX, fixed_t &intensityY, fixed_t &intensityZ, - fixed_t &relIntensityX, fixed_t &relIntensityY, fixed_t &relIntensityZ) +int DEarthquake::StaticGetQuakeIntensities(AActor *victim, FQuakeJiggers &jiggers) { if (victim->player != NULL && (victim->player->cheats & CF_NOCLIP)) { return 0; } - intensityX = intensityY = intensityZ = relIntensityX = relIntensityY = relIntensityZ = 0; TThinkerIterator iterator(STAT_EARTHQUAKE); DEarthquake *quake; @@ -228,17 +248,44 @@ int DEarthquake::StaticGetQuakeIntensities(AActor *victim, 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) + if (!(quake->m_Flags & QF_WAVE)) { - relIntensityX = MAX(relIntensityX, x); - relIntensityY = MAX(relIntensityY, y); - relIntensityZ = MAX(relIntensityZ, z); + if (quake->m_Flags & QF_RELATIVE) + { + jiggers.RelIntensityX = MAX(x, jiggers.RelIntensityX); + jiggers.RelIntensityY = MAX(y, jiggers.RelIntensityY); + jiggers.RelIntensityZ = MAX(z, jiggers.RelIntensityZ); + } + else + { + jiggers.IntensityX = MAX(x, jiggers.IntensityX); + jiggers.IntensityY = MAX(y, jiggers.IntensityY); + jiggers.IntensityZ = MAX(z, jiggers.IntensityZ); + } } else { - intensityX = MAX(intensityX, x); - intensityY = MAX(intensityY, y); - intensityZ = MAX(intensityZ, z); + fixed_t mx = FixedMul(x, quake->GetModWave(quake->m_WaveSpeedX)); + fixed_t my = FixedMul(y, quake->GetModWave(quake->m_WaveSpeedY)); + fixed_t mz = FixedMul(z, quake->GetModWave(quake->m_WaveSpeedZ)); + + // [RH] This only gives effect to the last sine quake. I would + // prefer if some way was found to make multiples coexist + // peacefully, but just summing them together is undesirable + // because they could cancel each other out depending on their + // relative phases. + if (quake->m_Flags & QF_RELATIVE) + { + jiggers.RelOffsetX = mx; + jiggers.RelOffsetY = my; + jiggers.RelOffsetZ = mz; + } + else + { + jiggers.OffsetX = mx; + jiggers.OffsetY = my; + jiggers.OffsetZ = mz; + } } } } @@ -252,7 +299,9 @@ int DEarthquake::StaticGetQuakeIntensities(AActor *victim, // //========================================================================== -bool P_StartQuakeXYZ(AActor *activator, int tid, int intensityX, int intensityY, int intensityZ, int duration, int damrad, int tremrad, FSoundID quakesfx, int flags) +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) { AActor *center; bool res = false; @@ -265,7 +314,8 @@ bool P_StartQuakeXYZ(AActor *activator, int tid, int intensityX, int intensityY, { if (activator != NULL) { - new DEarthquake(activator, intensityX, intensityY, intensityZ, duration, damrad, tremrad, quakesfx, flags); + new DEarthquake(activator, intensityX, intensityY, intensityZ, duration, damrad, tremrad, + quakesfx, flags, waveSpeedX, waveSpeedY, waveSpeedZ); return true; } } @@ -275,7 +325,8 @@ bool P_StartQuakeXYZ(AActor *activator, int tid, int intensityX, int intensityY, while ( (center = iterator.Next ()) ) { res = true; - new DEarthquake(center, intensityX, intensityY, intensityZ, duration, damrad, tremrad, quakesfx, flags); + new DEarthquake(center, intensityX, intensityY, intensityZ, duration, damrad, tremrad, + quakesfx, flags, waveSpeedX, waveSpeedY, waveSpeedZ); } } @@ -284,5 +335,5 @@ bool P_StartQuakeXYZ(AActor *activator, int tid, int intensityX, int intensityY, bool P_StartQuake(AActor *activator, int tid, int intensity, int duration, int damrad, int tremrad, FSoundID quakesfx) { //Maintains original behavior by passing 0 to intensityZ, and flags. - return P_StartQuakeXYZ(activator, tid, intensity, intensity, 0, duration, damrad, tremrad, quakesfx, 0); + return P_StartQuakeXYZ(activator, tid, intensity, intensity, 0, duration, damrad, tremrad, quakesfx, 0, 0, 0, 0); } diff --git a/src/g_shared/a_sharedglobal.h b/src/g_shared/a_sharedglobal.h index 02ba94036b..7c994f3c73 100644 --- a/src/g_shared/a_sharedglobal.h +++ b/src/g_shared/a_sharedglobal.h @@ -138,6 +138,15 @@ enum QF_SCALEUP = 1 << 2, QF_MAX = 1 << 3, QF_FULLINTENSITY = 1 << 4, + QF_WAVE = 1 << 5, +}; + +struct FQuakeJiggers +{ + int IntensityX, IntensityY, IntensityZ; + int RelIntensityX, RelIntensityY, RelIntensityZ; + int OffsetX, OffsetY, OffsetZ; + int RelOffsetX, RelOffsetY, RelOffsetZ; }; class DEarthquake : public DThinker @@ -145,7 +154,9 @@ class DEarthquake : public DThinker DECLARE_CLASS (DEarthquake, DThinker) HAS_OBJECT_POINTERS public: - DEarthquake(AActor *center, int intensityX, int intensityY, int intensityZ, int duration, int damrad, int tremrad, FSoundID quakesfx, int flags); + 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); void Serialize (FArchive &arc); void Tick (); @@ -156,12 +167,12 @@ public: FSoundID m_QuakeSFX; int m_Flags; int m_IntensityX, m_IntensityY, m_IntensityZ; + fixed_t m_WaveSpeedX, m_WaveSpeedY, m_WaveSpeedZ; fixed_t GetModIntensity(int intensity) const; + fixed_t GetModWave(fixed_t waveMultiplier) const; - static int StaticGetQuakeIntensities(AActor *viewer, - fixed_t &intensityX, fixed_t &intensityY, fixed_t &intensityZ, - fixed_t &relIntensityX, fixed_t &relIntensityY, fixed_t &relIntensityZ); + static int StaticGetQuakeIntensities(AActor *viewer, FQuakeJiggers &jiggers); private: DEarthquake (); diff --git a/src/p_spec.h b/src/p_spec.h index 2edfe6390f..b0c66b10e1 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); +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_StartQuake(AActor *activator, int tid, int intensity, int duration, int damrad, int tremrad, FSoundID quakesfx); #endif diff --git a/src/r_utility.cpp b/src/r_utility.cpp index c82216e742..60e2c1af15 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -770,9 +770,19 @@ bool R_GetViewInterpolationStatus() // //========================================================================== -static fixed_t QuakePower(fixed_t factor, fixed_t intensity) -{ - return FixedMul(factor, pr_torchflicker(intensity * 2) - intensity); +static fixed_t QuakePower(fixed_t factor, fixed_t intensity, fixed_t offset) +{ + fixed_t randumb; + + if (intensity == 0) + { + randumb = 0; + } + else + { + randumb = pr_torchflicker(intensity * 2) - intensity; + } + return FixedMul(factor, randumb + offset); } //========================================================================== @@ -885,40 +895,43 @@ void R_SetupFrame (AActor *actor) if (!paused) { - fixed_t intensityX, intensityY, intensityZ, relIntensityX, relIntensityY, relIntensityZ; - if (DEarthquake::StaticGetQuakeIntensities(camera, - intensityX, intensityY, intensityZ, - relIntensityX, relIntensityY, relIntensityZ) > 0) + FQuakeJiggers jiggers = { 0, }; + + if (DEarthquake::StaticGetQuakeIntensities(camera, jiggers) > 0) { fixed_t quakefactor = FLOAT2FIXED(r_quakeintensity); - if (relIntensityX != 0) + if ((jiggers.RelIntensityX | jiggers.RelOffsetX) != 0) { int ang = (camera->angle) >> ANGLETOFINESHIFT; - fixed_t power = QuakePower(quakefactor, relIntensityX); + fixed_t power = QuakePower(quakefactor, jiggers.RelIntensityX, jiggers.RelOffsetX); viewx += FixedMul(finecosine[ang], power); viewy += FixedMul(finesine[ang], power); } - if (relIntensityY != 0) + if ((jiggers.RelIntensityY | jiggers.RelOffsetY) != 0) { int ang = (camera->angle + ANG90) >> ANGLETOFINESHIFT; - fixed_t power = QuakePower(quakefactor, relIntensityY); + fixed_t power = QuakePower(quakefactor, jiggers.RelIntensityY, jiggers.RelOffsetY); viewx += FixedMul(finecosine[ang], power); viewy += FixedMul(finesine[ang], power); } - if (intensityX != 0) - { - viewx += QuakePower(quakefactor, intensityX); - } - if (intensityY != 0) - { - viewy += QuakePower(quakefactor, intensityY); - } // FIXME: Relative Z is not relative - intensityZ = MAX(intensityZ, relIntensityZ); - if (intensityZ != 0) + // [MC]On it! Will be introducing pitch after QF_WAVE. + if ((jiggers.RelIntensityZ | jiggers.RelOffsetZ) != 0) { - viewz += QuakePower(quakefactor, intensityZ); + viewz += QuakePower(quakefactor, jiggers.RelIntensityZ, jiggers.RelOffsetZ); + } + if ((jiggers.IntensityX | jiggers.OffsetX) != 0) + { + viewx += QuakePower(quakefactor, jiggers.IntensityX, jiggers.OffsetX); + } + if ((jiggers.IntensityY | jiggers.OffsetY) != 0) + { + viewy += QuakePower(quakefactor, jiggers.IntensityY, jiggers.OffsetY); + } + if ((jiggers.IntensityZ | jiggers.OffsetZ) != 0) + { + viewz += QuakePower(quakefactor, jiggers.IntensityZ, jiggers.OffsetZ); } } } diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index c30d09c7a0..2c289849a8 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -4419,7 +4419,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Quake) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_QuakeEx) { - ACTION_PARAM_START(8); + ACTION_PARAM_START(11); ACTION_PARAM_INT(intensityX, 0); ACTION_PARAM_INT(intensityY, 1); ACTION_PARAM_INT(intensityZ, 2); @@ -4428,7 +4428,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_QuakeEx) ACTION_PARAM_INT(tremrad, 5); ACTION_PARAM_SOUND(sound, 6); ACTION_PARAM_INT(flags, 7); - P_StartQuakeXYZ(self, 0, intensityX, intensityY, intensityZ, duration, damrad, tremrad, sound, flags); + ACTION_PARAM_FIXED(mulWaveX, 8); + ACTION_PARAM_FIXED(mulWaveY, 9); + ACTION_PARAM_FIXED(mulWaveZ, 10); + P_StartQuakeXYZ(self, 0, intensityX, intensityY, intensityZ, duration, damrad, tremrad, sound, flags, mulWaveX, mulWaveY, mulWaveZ); } //=========================================================================== diff --git a/src/version.h b/src/version.h index 794bdcec8a..de33e93a79 100644 --- a/src/version.h +++ b/src/version.h @@ -76,7 +76,7 @@ const char *GetVersionString(); // Use 4500 as the base git save version, since it's higher than the // SVN revision ever got. -#define SAVEVER 4520 +#define SAVEVER 4521 #define SAVEVERSTRINGIFY2(x) #x #define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x) diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index e8906af3f7..f84151d187 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -299,7 +299,7 @@ ACTOR Actor native //: Thinker action native A_SetUserArray(name varname, int index, int value); action native A_SetSpecial(int spec, int arg0 = 0, int arg1 = 0, int arg2 = 0, int arg3 = 0, int arg4 = 0); action native A_Quake(int intensity, int duration, int damrad, int tremrad, sound sfx = "world/quake"); - action native A_QuakeEx(int intensityX, int intensityY, int intensityZ, int duration, int damrad, int tremrad, sound sfx = "world/quake", int flags = 0); + action native A_QuakeEx(int intensityX, int intensityY, int intensityZ, int duration, int damrad, int tremrad, sound sfx = "world/quake", int flags = 0, float mulWaveX = 1, float mulWaveY = 1, float mulWaveZ = 1); action native A_SetTics(int tics); action native A_SetDamageType(name damagetype); action native A_DropItem(class item, int dropamount = -1, int chance = 256); diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index 78149430ad..e6434a08ea 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -466,6 +466,7 @@ enum QF_SCALEUP = 1 << 2, QF_MAX = 1 << 3, QF_FULLINTENSITY = 1 << 4, + QF_WAVE = 1 << 5, }; // This is only here to provide one global variable for testing.