diff --git a/docs/rh-log.txt b/docs/rh-log.txt index ab9dbf4dd..a7a16b7ba 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,3 +1,9 @@ +December 30, 2009 (Changes by Graf Zahl) +- fixed: Movement performed by actor movers was not interpolated because + it happened outside the moved actor's Tick function. This got particularly + obvious with moving skybox viewpoints (See Daedalus's MAP21 intro for a good + example.) + December 28, 2009 - Fixed: Shooting up and down with AArtiPoisonBag3::Use() was completely broken. I don't know what I thinking when I plugged in 2*finesine[pitch] diff --git a/src/actor.h b/src/actor.h index be6046f0e..90f80be1e 100644 --- a/src/actor.h +++ b/src/actor.h @@ -570,6 +570,7 @@ public: // BeginPlay: Called just after the actor is created virtual void BeginPlay (); + virtual void PostBeginPlay (); // LevelSpawned: Called after BeginPlay if this actor was spawned by the world virtual void LevelSpawned (); // Translates SpawnFlags into in-game flags. @@ -579,6 +580,7 @@ public: virtual void Deactivate (AActor *activator); virtual void Tick (); + void DoTick (); // Smallest yaw interval for a mapthing to be spawned with virtual angle_t AngleIncrements (); @@ -868,6 +870,10 @@ public: // [RH] Used to interpolate the view to get >35 FPS fixed_t PrevX, PrevY, PrevZ; + angle_t PrevAngle; + + fixed_t LastX, LastY, LastZ; + angle_t LastAngle; // ThingIDs static void ClearTIDHashes (); diff --git a/src/g_shared/a_fastprojectile.cpp b/src/g_shared/a_fastprojectile.cpp index 5829fc167..64b1451bb 100644 --- a/src/g_shared/a_fastprojectile.cpp +++ b/src/g_shared/a_fastprojectile.cpp @@ -26,6 +26,7 @@ void AFastProjectile::Tick () PrevX = x; PrevY = y; PrevZ = z; + PrevAngle = angle; if (!(flags5 & MF5_NOTIMEFREEZE)) { diff --git a/src/g_shared/a_movingcamera.cpp b/src/g_shared/a_movingcamera.cpp index 0e704c95a..55316dbf1 100644 --- a/src/g_shared/a_movingcamera.cpp +++ b/src/g_shared/a_movingcamera.cpp @@ -585,6 +585,7 @@ void AActorMover::Activate (AActor *activator) tracer->PrevX = tracer->x; tracer->PrevY = tracer->y; tracer->PrevZ = tracer->z; + tracer->PrevAngle = tracer->angle; } void AActorMover::Deactivate (AActor *activator) diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 4b80d5b68..0b5c29137 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -523,9 +523,9 @@ bool P_Move (AActor *actor) // so make it switchable if (nomonsterinterpolation) { - actor->PrevX = actor->x; - actor->PrevY = actor->y; - actor->PrevZ = actor->z; + actor->LastX = actor->PrevX = actor->x; + actor->LastY = actor->PrevY = actor->y; + actor->LastZ = actor->PrevZ = actor->z; } if (try_ok && friction > ORIG_FRICTION) @@ -2435,8 +2435,8 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi { if (nomonsterinterpolation) { - actor->PrevX = oldX; - actor->PrevY = oldY; + actor->LastX = actor->PrevX = oldX; + actor->LastY = actor->PrevY = oldY; } } P_NewChaseDir (actor); diff --git a/src/p_map.cpp b/src/p_map.cpp index dc056972f..0750050e9 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -392,9 +392,9 @@ bool P_TeleportMove (AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefr R_ResetViewInterpolation (); } - thing->PrevX = x; - thing->PrevY = y; - thing->PrevZ = z; + thing->LastX = thing->PrevX = x; + thing->LastY = thing->PrevY = y; + thing->LastZ = thing->PrevZ = z; return true; } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 29480a7ee..82d8120b7 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -434,9 +434,10 @@ void AActor::Serialize (FArchive &arc) Speed = GetDefault()->Speed; } } - PrevX = x; - PrevY = y; - PrevZ = z; + LastX = PrevX = x; + LastY = PrevY = y; + LastZ = PrevZ = z; + LastAngle = PrevAngle = angle; UpdateWaterLevel(z, false); } } @@ -2805,7 +2806,7 @@ void AActor::SetShade (int r, int g, int b) // // P_MobjThinker // -void AActor::Tick () +void AActor::DoTick () { // [RH] Data for Heretic/Hexen scrolling sectors static const BYTE HexenScrollDirs[8] = { 64, 0, 192, 128, 96, 32, 224, 160 }; @@ -2835,10 +2836,6 @@ void AActor::Tick () return; } - PrevX = x; - PrevY = y; - PrevZ = z; - if (flags5 & MF5_NOINTERACTION) { // only do the minimally necessary things here to save time: @@ -3378,6 +3375,23 @@ void AActor::Tick () } } +void AActor::Tick() +{ + // This is necessary to properly interpolate movement outside this function + // like from an ActorMover + PrevX = LastX; + PrevY = LastY; + PrevZ = LastZ; + PrevAngle = LastAngle; + + DoTick(); + + LastX = x; + LastY = y; + LastZ = z; + LastAngle = angle; +} + //========================================================================== // // AActor::UpdateWaterLevel @@ -3517,9 +3531,9 @@ AActor *AActor::StaticSpawn (const PClass *type, fixed_t ix, fixed_t iy, fixed_t actor = static_cast(const_cast(type)->CreateNew ()); - actor->x = actor->PrevX = ix; - actor->y = actor->PrevY = iy; - actor->z = actor->PrevZ = iz; + actor->x = actor->LastX = actor->PrevX = ix; + actor->y = actor->LastY = actor->PrevY = iy; + actor->z = actor->LastZ = actor->PrevZ = iz; actor->picnum.SetInvalid(); actor->health = actor->SpawnHealth(); @@ -3735,6 +3749,11 @@ void AActor::BeginPlay () } } +void AActor::PostBeginPlay () +{ + PrevAngle = angle; +} + bool AActor::isFast() { if (flags5&MF5_ALWAYSFAST) return true; @@ -4399,7 +4418,7 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) mobj->tid = mthing->thingid; mobj->AddToHash (); - mobj->angle = (DWORD)((mthing->angle * UCONST64(0x100000000)) / 360); + mobj->LastAngle = mobj->PrevAngle = mobj->angle = (DWORD)((mthing->angle * UCONST64(0x100000000)) / 360); mobj->BeginPlay (); if (!(mobj->ObjectFlags & OF_EuthanizeMe)) { diff --git a/src/p_things.cpp b/src/p_things.cpp index 109b2d698..46c46be99 100644 --- a/src/p_things.cpp +++ b/src/p_things.cpp @@ -142,9 +142,9 @@ bool P_MoveThing(AActor *source, fixed_t x, fixed_t y, fixed_t z, bool fog) Spawn (x, y, z + TELEFOGHEIGHT, ALLOW_REPLACE); Spawn (oldx, oldy, oldz + TELEFOGHEIGHT, ALLOW_REPLACE); } - source->PrevX=x; - source->PrevY=y; - source->PrevZ=z; + source->LastX = source->PrevX = x; + source->LastY = source->PrevY = y; + source->LastZ = source->PrevZ = z; return true; } else diff --git a/src/r_plane.cpp b/src/r_plane.cpp index c9612c24c..aae870fbe 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -1105,10 +1105,12 @@ void R_DrawSkyBoxes () // Don't let gun flashes brighten the sky box extralight = 0; R_SetVisibility (sky->args[0] * 0.25f); - viewx = sky->x; - viewy = sky->y; - viewz = sky->z; - viewangle = savedangle + sky->angle; + + viewx = sky->PrevX + FixedMul(r_TicFrac, sky->x - sky->PrevX); + viewy = sky->PrevY + FixedMul(r_TicFrac, sky->y - sky->PrevY); + viewz = sky->PrevZ + FixedMul(r_TicFrac, sky->z - sky->PrevZ); + viewangle = savedangle + sky->PrevAngle + FixedMul(r_TicFrac, sky->angle - sky->PrevAngle); + R_CopyStackedViewParameters(); } else