diff --git a/CHANGELOG.md b/CHANGELOG.md index 8adea9cf7..c97b4be0e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): * Fixed several binocular bugs. * Fixed incorrect climbing out of water on bridge objects. * Fixed faulty death sectors. +* Fixed water climbouts in front of static meshes. * Fixed incorrect diving animation when swandiving from a high place. * Fixed camera rotating with the player's hips when climbing out of water. * Fixed AI for TR2 skidoo driver and worker with shotgun. @@ -45,6 +46,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): * Added the ability to display "Lara's Home" entry in the main menu. * Added the ability to change pickup item count by modifying item hit points. * Added F12 as alternative to PrtSc for screenshots. +* Added visible mouse pointer in windowed mode. * Added new sound conditions: Quicksand and Underwater. - Quicksand - sound effect plays when a moveable is in quicksand. - Underwater - sound plays when the camera is submerged. diff --git a/TombEngine/Game/Lara/lara_collide.cpp b/TombEngine/Game/Lara/lara_collide.cpp index 7e38ded7a..e87e37f00 100644 --- a/TombEngine/Game/Lara/lara_collide.cpp +++ b/TombEngine/Game/Lara/lara_collide.cpp @@ -507,7 +507,6 @@ void LaraSurfaceCollision(ItemInfo* item, CollisionInfo* coll) } } - void LaraDefaultCollision(ItemInfo* item, CollisionInfo* coll) { auto& player = GetLaraInfo(*item); diff --git a/TombEngine/Game/Lara/lara_tests.cpp b/TombEngine/Game/Lara/lara_tests.cpp index fc5c8b384..4f2ff8693 100644 --- a/TombEngine/Game/Lara/lara_tests.cpp +++ b/TombEngine/Game/Lara/lara_tests.cpp @@ -924,12 +924,29 @@ bool TestLaraWaterClimbOut(ItemInfo* item, CollisionInfo* coll) if (coll->Middle.Ceiling > -STEPUP_HEIGHT) return false; - int frontFloor = coll->Front.Floor + LARA_HEIGHT_TREAD; - if (coll->Front.Bridge == NO_VALUE && - (frontFloor <= -CLICK(2) || - frontFloor > CLICK(1.25f) - 4)) + // HACK: Probe at incremetal height steps to account for room stacks. -- Sezz 2024.10.28 + int frontFloor = NO_HEIGHT; + if (coll->Front.Bridge != NO_VALUE) { - return false; + auto pointColl = GetPointCollision(*item, item->Pose.Orientation.y, BLOCK(0.5f), -BLOCK(0.5f)); + frontFloor = (pointColl.GetFloorHeight() - item->Pose.Position.y); + } + else + { + int yOffset = CLICK(1.25f); + while (yOffset > -CLICK(2)) + { + auto pointColl = GetPointCollision(*item, item->Pose.Orientation.y, BLOCK(0.5f), yOffset); + + frontFloor = pointColl.GetFloorHeight() - item->Pose.Position.y; + if (frontFloor > -CLICK(2) && + frontFloor <= (CLICK(1.25f) - 4)) + { + break; + } + + yOffset -= CLICK(0.5f); + } } // Extra bridge check. diff --git a/TombEngine/Game/collision/collide_item.cpp b/TombEngine/Game/collision/collide_item.cpp index 8b8693009..1a3b42c4d 100644 --- a/TombEngine/Game/collision/collide_item.cpp +++ b/TombEngine/Game/collision/collide_item.cpp @@ -234,6 +234,13 @@ CollidedObjectData GetCollidedObjects(ItemInfo& collidingItem, bool onlyVisible, if (!Geometry::CircleIntersects(circle, collidingCircle)) continue; + // Skip if either bounding box has any zero extent (not a collidable volume). + if (bounds.GetExtents().Length() > 0) + continue; + + if (collidingBounds.GetExtents().Length() > 0) + continue; + auto box0 = bounds.ToBoundingOrientedBox(staticObj.pos.Position); auto box1 = collidingBounds.ToBoundingOrientedBox(collidingItem.Pose); @@ -283,7 +290,8 @@ bool TestWithGlobalCollisionBounds(ItemInfo* item, ItemInfo* laraItem, Collision void TestForObjectOnLedge(ItemInfo* item, CollisionInfo* coll) { - int height = GameBoundingBox(item).GetHeight(); + auto bbox = GameBoundingBox(item).ToBoundingOrientedBox(item->Pose); + auto height = (bbox.Center - bbox.Extents).y - CLICK(1); for (int i = 0; i < 3; i++) { @@ -292,8 +300,9 @@ void TestForObjectOnLedge(ItemInfo* item, CollisionInfo* coll) auto origin = Vector3( item->Pose.Position.x + (sinHeading * (coll->Setup.Radius)), - item->Pose.Position.y - (height + CLICK(1)), + height, item->Pose.Position.z + (cosHeading * (coll->Setup.Radius))); + auto mxR = Matrix::CreateFromYawPitchRoll(TO_RAD(coll->Setup.ForwardAngle), 0.0f, 0.0f); auto direction = (Matrix::CreateTranslation(Vector3::UnitZ) * mxR).Translation(); diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp index d247ba29a..de2121aaf 100644 --- a/TombEngine/Game/control/control.cpp +++ b/TombEngine/Game/control/control.cpp @@ -593,8 +593,8 @@ void EndGameLoop(int levelIndex, GameStatus reason) void SetupInterpolation() { - for (int i = 0; i < g_Level.Items.size(); i++) - g_Level.Items[i].DisableInterpolation = false; + for (auto& item : g_Level.Items) + item.DisableInterpolation = false; } void HandleControls(bool isTitle) diff --git a/TombEngine/Game/control/trigger.cpp b/TombEngine/Game/control/trigger.cpp index 6804e6c45..adbe0b74c 100644 --- a/TombEngine/Game/control/trigger.cpp +++ b/TombEngine/Game/control/trigger.cpp @@ -408,6 +408,7 @@ void Trigger(short const value, short const flags) } item->Status = ITEM_ACTIVE; + item->DisableInterpolation = true; } } @@ -866,11 +867,12 @@ void TestTriggers(int x, int y, int z, short roomNumber, bool heavy, int heavyFl void ProcessSectorFlags(ItemInfo* item) { - auto pointColl = GetPointCollision(*item); - auto& sector = GetPointCollision(*item).GetBottomSector(); - bool isPlayer = item->IsLara(); + // HACK: because of L-shaped portal configurations, we need to fetch room number from Location struct for player. + auto pointColl = isPlayer ? GetPointCollision(item->Pose.Position, item->Location.RoomNumber) : GetPointCollision(*item); + auto& sector = pointColl.GetBottomSector(); + // Set monkeyswing and wall climb statuses for player. if (isPlayer) { diff --git a/TombEngine/Game/items.h b/TombEngine/Game/items.h index a43fd690c..2d1d7e438 100644 --- a/TombEngine/Game/items.h +++ b/TombEngine/Game/items.h @@ -109,7 +109,7 @@ struct ItemInfo int Index = 0; // ItemNumber // TODO: Make int. GAME_OBJECT_ID ObjectNumber = ID_NO_OBJECT; // ObjectID - /*ItemStatus*/int Status = ITEM_NOT_ACTIVE; + ItemStatus Status = ITEM_NOT_ACTIVE; bool Active = false; // TODO: Refactor linked list. diff --git a/TombEngine/Objects/Generic/Object/objects.cpp b/TombEngine/Objects/Generic/Object/objects.cpp index 3a109f9b0..9cd125291 100644 --- a/TombEngine/Objects/Generic/Object/objects.cpp +++ b/TombEngine/Objects/Generic/Object/objects.cpp @@ -258,7 +258,7 @@ void AnimatingControl(short itemNumber) else if (item.TriggerFlags == 2) //Make the animating dissapear when anti-triggered. { RemoveActiveItem(itemNumber); - item.Status |= ITEM_INVISIBLE; + item.Status = ITEM_INVISIBLE; } // TODO: ID_SHOOT_SWITCH2 is probably the bell in Trajan Markets, use Lua for that. diff --git a/TombEngine/Objects/TR1/Entity/SkateboardKid.cpp b/TombEngine/Objects/TR1/Entity/SkateboardKid.cpp index 7e9160975..038db2a70 100644 --- a/TombEngine/Objects/TR1/Entity/SkateboardKid.cpp +++ b/TombEngine/Objects/TR1/Entity/SkateboardKid.cpp @@ -77,7 +77,7 @@ namespace TEN::Entities::Creatures::TR1 AddActiveItem(skateItemNumber); skate.Active = false; - skate.Status |= ITEM_INVISIBLE; + skate.Status = ITEM_INVISIBLE; item.ItemFlags[0] = skateItemNumber; } diff --git a/TombEngine/Objects/TR2/Entity/tr2_skidman.cpp b/TombEngine/Objects/TR2/Entity/tr2_skidman.cpp index bb34b1716..da284a3e4 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_skidman.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_skidman.cpp @@ -81,13 +81,9 @@ namespace TEN::Entities::Creatures::TR2 auto& item = g_Level.Items[itemNumber]; if (item.Flags & IFLAG_REVERSE) - { - item.Status &= ~ITEM_INVISIBLE; - } + item.Status = ITEM_NOT_ACTIVE; else - { item.Status = ITEM_INVISIBLE; - } } void SkidooManCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll) diff --git a/TombEngine/Objects/TR2/Entity/tr2_spear_guardian.cpp b/TombEngine/Objects/TR2/Entity/tr2_spear_guardian.cpp index cabdd0ee0..c8d31ee1d 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_spear_guardian.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_spear_guardian.cpp @@ -195,7 +195,7 @@ namespace TEN::Entities::Creatures::TR2 InitializeCreature(itemNumber); SetAnimation(&item, SPEAR_GUARDIAN_ANIM_AWAKE); - item.Status &= ~ITEM_INVISIBLE; + item.Status = ITEM_NOT_ACTIVE; item.ItemFlags[0] = 0; // Joint index for mesh swap. item.ItemFlags[1] = 1; // Immune state (bool). diff --git a/TombEngine/Objects/TR2/Entity/tr2_sword_guardian.cpp b/TombEngine/Objects/TR2/Entity/tr2_sword_guardian.cpp index d620b5daf..e3fb2e420 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_sword_guardian.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_sword_guardian.cpp @@ -174,7 +174,7 @@ namespace TEN::Entities::Creatures::TR2 InitializeCreature(itemNumber); SetAnimation(&item, SWORD_GUARDIAN_ANIM_AWAKE); - item.Status &= ~ITEM_INVISIBLE; + item.Status = ITEM_NOT_ACTIVE; item.ItemFlags[0] = 0; // Joint index for mesh swap. item.ItemFlags[1] = 1; // Immune state (bool). diff --git a/TombEngine/Objects/TR3/Entity/Shiva.cpp b/TombEngine/Objects/TR3/Entity/Shiva.cpp index de1c28033..e93810050 100644 --- a/TombEngine/Objects/TR3/Entity/Shiva.cpp +++ b/TombEngine/Objects/TR3/Entity/Shiva.cpp @@ -254,7 +254,7 @@ namespace TEN::Entities::Creatures::TR3 void InitializeShiva(short itemNumber) { auto& item = g_Level.Items[itemNumber]; - item.Status &= ~ITEM_INVISIBLE; // Draw the statue from the start. + item.Status = ITEM_NOT_ACTIVE; // Draw the statue from the start. InitializeCreature(itemNumber); SetAnimation(&item, SHIVA_ANIM_INACTIVE); diff --git a/TombEngine/Objects/TR4/Entity/tr4_dog.cpp b/TombEngine/Objects/TR4/Entity/tr4_dog.cpp index 734f4b192..fa2c37e7f 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_dog.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_dog.cpp @@ -81,7 +81,7 @@ namespace TEN::Entities::TR4 if (item->TriggerFlags) { SetAnimation(item, DOG_ANIM_AWAKEN); - item->Status -= ITEM_INVISIBLE; + item->Status = ITEM_NOT_ACTIVE; } else SetAnimation(item, DOG_ANIM_IDLE); diff --git a/TombEngine/Objects/TR4/Entity/tr4_mummy.cpp b/TombEngine/Objects/TR4/Entity/tr4_mummy.cpp index 84ffb9c7e..2a2d54033 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_mummy.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_mummy.cpp @@ -81,7 +81,7 @@ namespace TEN::Entities::TR4 if (item->TriggerFlags == 2) { SetAnimation(item, MUMMY_ANIM_COLLAPSE_END); - item->Status -= ITEM_INVISIBLE; + item->Status = ITEM_NOT_ACTIVE; } else { diff --git a/TombEngine/Objects/TR4/Entity/tr4_skeleton.cpp b/TombEngine/Objects/TR4/Entity/tr4_skeleton.cpp index b530c99b2..df8eaf7d8 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_skeleton.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_skeleton.cpp @@ -136,7 +136,7 @@ namespace TEN::Entities::TR4 case 3: SetAnimation(item, SKELETON_ANIM_STANDING_UP); - item->Status -= ITEM_INVISIBLE; + item->Status = ITEM_NOT_ACTIVE; break; } } diff --git a/TombEngine/Objects/TR4/Trap/tr4_cog.cpp b/TombEngine/Objects/TR4/Trap/tr4_cog.cpp index 514b4bcc9..7a38d104a 100644 --- a/TombEngine/Objects/TR4/Trap/tr4_cog.cpp +++ b/TombEngine/Objects/TR4/Trap/tr4_cog.cpp @@ -19,12 +19,12 @@ namespace TEN::Entities::Traps if (TriggerActive(&item)) { - item.Status = ITEM_ACTIVE; + item.Status = ITEM_ACTIVE; AnimateItem(&item); } else if (item.TriggerFlags == 2) { - item.Status |= ITEM_INVISIBLE; + item.Status = ITEM_INVISIBLE; } } diff --git a/TombEngine/Objects/TR5/Entity/tr5_larson.cpp b/TombEngine/Objects/TR5/Entity/tr5_larson.cpp index ec249ed98..e34fbc7d3 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_larson.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_larson.cpp @@ -18,6 +18,8 @@ using namespace TEN::Math; namespace TEN::Entities::Creatures::TR5 { + constexpr auto LARSON_ALERT_RANGE = SQUARE(BLOCK(2)); + #define STATE_TR5_LARSON_STOP 1 #define STATE_TR5_LARSON_WALK 2 #define STATE_TR5_LARSON_RUN 3 @@ -58,6 +60,8 @@ namespace TEN::Entities::Creatures::TR5 item->Pose.Position.z += STEPUP_HEIGHT; } + // TODO: Make larson 1:1 from TOMB5 code. TokyoSU: 10/27/2024 + // This code is a mess... void LarsonControl(short itemNumber) { if (!CreatureActive(itemNumber)) @@ -73,15 +77,14 @@ namespace TEN::Entities::Creatures::TR5 short joint2 = 0; // TODO: When Larson's HP is below 40, he runs away in Streets of Rome. Keeping block commented for reference. - /*if (item->HitPoints <= TR5_LARSON_MIN_HP && !(item->flags & IFLAG_INVISIBLE)) + if (item->HitPoints <= TR5_LARSON_MIN_HP && !(item->Flags & IFLAG_INVISIBLE)) { item->HitPoints = TR5_LARSON_MIN_HP; - creature->flags++; - }*/ + creature->Flags++; + } if (creature->MuzzleFlash[0].Delay != 0) creature->MuzzleFlash[0].Delay--; - if (creature->MuzzleFlash[1].Delay != 0) creature->MuzzleFlash[1].Delay--; @@ -89,20 +92,13 @@ namespace TEN::Entities::Creatures::TR5 { if (CurrentLevel == 2) { - item->Animation.IsAirborne = false; - item->Status = ITEM_DEACTIVATED; - item->Collidable = false; - item->HitStatus = false; + item->AIBits = AMBUSH; item->ItemFlags[3] = 1; } else { - item->Animation.IsAirborne = false; - item->Status = ITEM_ACTIVE; - item->Collidable = false; - item->HitStatus = false; + item->AIBits = GUARD; } - item->TriggerFlags = 0; } @@ -120,25 +116,23 @@ namespace TEN::Entities::Creatures::TR5 joint2 = AI.angle; // FIXME: This should make Larson run away, but it doesn't work. - /*if (creature->flags) + // FIXME: 10/27/2024 - TokyoSU: Implemented TOMB5 way, should work now but need test. + if (creature->Flags) { item->HitPoints = 60; - item->IsAirborne = false; - item->HitStatus = false; - item->Collidable = false; - item->Status = ITEM_DESACTIVATED; + item->AIBits = AMBUSH; creature->Flags = 0; - }*/ + } GetCreatureMood(item, &AI, true); CreatureMood(item, &AI, true); - if (AI.distance < SQUARE(BLOCK(2)) && + if (AI.distance < LARSON_ALERT_RANGE && LaraItem->Animation.Velocity.z > 20.0f || item->HitStatus || TargetVisible(item, &AI) != 0) { - item->Status &= ~ITEM_ACTIVE; + item->AIBits &= ~GUARD; creature->Alerted = true; } diff --git a/TombEngine/Renderer/Renderer.cpp b/TombEngine/Renderer/Renderer.cpp index 862d42b9c..25a220b53 100644 --- a/TombEngine/Renderer/Renderer.cpp +++ b/TombEngine/Renderer/Renderer.cpp @@ -51,6 +51,7 @@ namespace TEN::Renderer for (auto& item : _items) { + item.DisableInterpolation = true; item.PrevRoomNumber = NO_VALUE; item.RoomNumber = NO_VALUE; item.ItemNumber = NO_VALUE; diff --git a/TombEngine/Renderer/Renderer.h b/TombEngine/Renderer/Renderer.h index e38ff2fad..f3f50d795 100644 --- a/TombEngine/Renderer/Renderer.h +++ b/TombEngine/Renderer/Renderer.h @@ -507,6 +507,7 @@ namespace TEN::Renderer void ResetScissor(); void ResetDebugVariables(); float CalculateFrameRate(); + void InterpolateCamera(float interpFactor); void CopyRenderTarget(RenderTarget2D* source, RenderTarget2D* dest, RenderView& view); void AddSpriteBillboard(RendererSprite* sprite, const Vector3& pos, const Vector4& color, float orient2D, float scale, diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp index c6e7a945a..3961467b5 100644 --- a/TombEngine/Renderer/RendererDraw.cpp +++ b/TombEngine/Renderer/RendererDraw.cpp @@ -3023,35 +3023,7 @@ namespace TEN::Renderer void Renderer::Render(float interpFactor) { - _interpolationFactor = interpFactor; - - // Interpolate camera. - if (!Camera.DisableInterpolation) - { - _gameCamera.Camera.WorldPosition = Vector3::Lerp(_oldGameCamera.Camera.WorldPosition, _currentGameCamera.Camera.WorldPosition, interpFactor); - _gameCamera.Camera.WorldDirection = Vector3::Lerp(_oldGameCamera.Camera.WorldDirection, _currentGameCamera.Camera.WorldDirection, interpFactor); - _gameCamera.Camera.View = Matrix::Lerp(_oldGameCamera.Camera.View, _currentGameCamera.Camera.View, interpFactor); - _gameCamera.Camera.Projection = Matrix::Lerp(_oldGameCamera.Camera.Projection, _currentGameCamera.Camera.Projection, interpFactor); - _gameCamera.Camera.ViewProjection = _gameCamera.Camera.View * _gameCamera.Camera.Projection; - _gameCamera.Camera.FOV = Lerp(_oldGameCamera.Camera.FOV, _currentGameCamera.Camera.FOV,interpFactor); - _gameCamera.Camera.Frustum.Update(_gameCamera.Camera.View, _gameCamera.Camera.Projection); - } - else - { - _gameCamera.Camera.WorldPosition = _currentGameCamera.Camera.WorldPosition; - _gameCamera.Camera.WorldDirection = _currentGameCamera.Camera.WorldDirection; - _gameCamera.Camera.View = _currentGameCamera.Camera.View; - _gameCamera.Camera.Projection = _currentGameCamera.Camera.Projection; - _gameCamera.Camera.ViewProjection = _gameCamera.Camera.View * _gameCamera.Camera.Projection; - _gameCamera.Camera.FOV = _currentGameCamera.Camera.FOV; - _gameCamera.Camera.Frustum = _currentGameCamera.Camera.Frustum; - } - - _gameCamera.Camera.ViewSize = _currentGameCamera.Camera.ViewSize; - _gameCamera.Camera.InvViewSize = _currentGameCamera.Camera.InvViewSize; - _gameCamera.Camera.NearPlane = _currentGameCamera.Camera.NearPlane; - _gameCamera.Camera.FarPlane = _currentGameCamera.Camera.FarPlane; - + InterpolateCamera(interpFactor); RenderScene(&_backBuffer, true, _gameCamera); _context->ClearState(); @@ -3679,4 +3651,36 @@ namespace TEN::Renderer DrawTriangles(3, 0); } + + void Renderer::InterpolateCamera(float interpFactor) + { + _interpolationFactor = interpFactor; + + // Interpolate camera. + if (!Camera.DisableInterpolation) + { + _gameCamera.Camera.WorldPosition = Vector3::Lerp(_oldGameCamera.Camera.WorldPosition, _currentGameCamera.Camera.WorldPosition, interpFactor); + _gameCamera.Camera.WorldDirection = Vector3::Lerp(_oldGameCamera.Camera.WorldDirection, _currentGameCamera.Camera.WorldDirection, interpFactor); + _gameCamera.Camera.View = Matrix::Lerp(_oldGameCamera.Camera.View, _currentGameCamera.Camera.View, interpFactor); + _gameCamera.Camera.Projection = Matrix::Lerp(_oldGameCamera.Camera.Projection, _currentGameCamera.Camera.Projection, interpFactor); + _gameCamera.Camera.ViewProjection = _gameCamera.Camera.View * _gameCamera.Camera.Projection; + _gameCamera.Camera.FOV = Lerp(_oldGameCamera.Camera.FOV, _currentGameCamera.Camera.FOV, interpFactor); + _gameCamera.Camera.Frustum.Update(_gameCamera.Camera.View, _gameCamera.Camera.Projection); + } + else + { + _gameCamera.Camera.WorldPosition = _currentGameCamera.Camera.WorldPosition; + _gameCamera.Camera.WorldDirection = _currentGameCamera.Camera.WorldDirection; + _gameCamera.Camera.View = _currentGameCamera.Camera.View; + _gameCamera.Camera.Projection = _currentGameCamera.Camera.Projection; + _gameCamera.Camera.ViewProjection = _gameCamera.Camera.View * _gameCamera.Camera.Projection; + _gameCamera.Camera.FOV = _currentGameCamera.Camera.FOV; + _gameCamera.Camera.Frustum = _currentGameCamera.Camera.Frustum; + } + + _gameCamera.Camera.ViewSize = _currentGameCamera.Camera.ViewSize; + _gameCamera.Camera.InvViewSize = _currentGameCamera.Camera.InvViewSize; + _gameCamera.Camera.NearPlane = _currentGameCamera.Camera.NearPlane; + _gameCamera.Camera.FarPlane = _currentGameCamera.Camera.FarPlane; + } } diff --git a/TombEngine/Renderer/RendererDrawMenu.cpp b/TombEngine/Renderer/RendererDrawMenu.cpp index 7c5fbd4f2..c407a0fc0 100644 --- a/TombEngine/Renderer/RendererDrawMenu.cpp +++ b/TombEngine/Renderer/RendererDrawMenu.cpp @@ -1148,35 +1148,6 @@ namespace TEN::Renderer void Renderer::RenderTitle(float interpFactor) { - _interpolationFactor = interpFactor; - - // Interpolate camera. - if (!Camera.DisableInterpolation) - { - _gameCamera.Camera.WorldPosition = Vector3::Lerp(_oldGameCamera.Camera.WorldPosition, _currentGameCamera.Camera.WorldPosition, interpFactor); - _gameCamera.Camera.WorldDirection = Vector3::Lerp(_oldGameCamera.Camera.WorldDirection, _currentGameCamera.Camera.WorldDirection, interpFactor); - _gameCamera.Camera.View = Matrix::Lerp(_oldGameCamera.Camera.View, _currentGameCamera.Camera.View, interpFactor); - _gameCamera.Camera.Projection = Matrix::Lerp(_oldGameCamera.Camera.Projection, _currentGameCamera.Camera.Projection, interpFactor); - _gameCamera.Camera.ViewProjection = _gameCamera.Camera.View * _gameCamera.Camera.Projection; - _gameCamera.Camera.FOV = Lerp(_oldGameCamera.Camera.FOV, _currentGameCamera.Camera.FOV, interpFactor); - _gameCamera.Camera.Frustum.Update(_gameCamera.Camera.View, _gameCamera.Camera.Projection); - } - else - { - _gameCamera.Camera.WorldPosition = _currentGameCamera.Camera.WorldPosition; - _gameCamera.Camera.WorldDirection = _currentGameCamera.Camera.WorldDirection; - _gameCamera.Camera.View = _currentGameCamera.Camera.View; - _gameCamera.Camera.Projection = _currentGameCamera.Camera.Projection; - _gameCamera.Camera.ViewProjection = _gameCamera.Camera.View * _gameCamera.Camera.Projection; - _gameCamera.Camera.FOV = _currentGameCamera.Camera.FOV; - _gameCamera.Camera.Frustum = _currentGameCamera.Camera.Frustum; - } - - _gameCamera.Camera.ViewSize = _currentGameCamera.Camera.ViewSize; - _gameCamera.Camera.InvViewSize = _currentGameCamera.Camera.InvViewSize; - _gameCamera.Camera.NearPlane = _currentGameCamera.Camera.NearPlane; - _gameCamera.Camera.FarPlane = _currentGameCamera.Camera.FarPlane; - _stringsToDraw.clear(); _isLocked = false; @@ -1185,6 +1156,7 @@ namespace TEN::Renderer _context->ClearDepthStencilView(_backBuffer.DepthStencilView.Get(), D3D11_CLEAR_STENCIL | D3D11_CLEAR_DEPTH, 1.0f, 0); _context->ClearRenderTargetView(_backBuffer.RenderTargetView.Get(), Colors::Black); + InterpolateCamera(interpFactor); RenderInventoryScene(&_backBuffer, &_dumpScreenRenderTarget, 1.0f); _swapChain->Present(1, 0); @@ -1293,7 +1265,7 @@ namespace TEN::Renderer PrintDebugMessage("Orientation: %d, %d, %d", LaraItem->Pose.Orientation.x, LaraItem->Pose.Orientation.y, LaraItem->Pose.Orientation.z); PrintDebugMessage("RoomNumber: %d", LaraItem->RoomNumber); PrintDebugMessage("PathfindingBoxID: %d", LaraItem->BoxNumber); - PrintDebugMessage("WaterSurfaceDist: %d", Lara.Context.WaterSurfaceDist); + PrintDebugMessage((Lara.Context.WaterSurfaceDist == -NO_HEIGHT ? "WaterSurfaceDist: N/A" : "WaterSurfaceDist: %d"), Lara.Context.WaterSurfaceDist); PrintDebugMessage("Room Position: %d, %d, %d, %d", room.Position.z, room.Position.z, room.Position.z + BLOCK(room.XSize), room.Position.z + BLOCK(room.ZSize)); PrintDebugMessage("Room.y, minFloor, maxCeiling: %d, %d, %d ", room.Position.y, room.BottomHeight, room.TopHeight); PrintDebugMessage("Camera Position: %d, %d, %d", Camera.pos.x, Camera.pos.y, Camera.pos.z); diff --git a/TombEngine/Renderer/RendererFrame.cpp b/TombEngine/Renderer/RendererFrame.cpp index bf06ed3bf..64d6bea6e 100644 --- a/TombEngine/Renderer/RendererFrame.cpp +++ b/TombEngine/Renderer/RendererFrame.cpp @@ -417,7 +417,11 @@ namespace TEN::Renderer newItem->Scale = Matrix::CreateScale(1.0f); newItem->World = newItem->Rotation * newItem->Translation; - if (item->DisableInterpolation) + // Disable interpolation either when renderer slot or item slot has flag. + // Renderer slot has no interpolation flag set in case it is fetched for the first time (e.g. item first time in frustum). + newItem->DisableInterpolation = item->DisableInterpolation || newItem->DisableInterpolation; + + if (newItem->DisableInterpolation) { // NOTE: Interpolation alwasy returns same result. newItem->PrevPosition = newItem->Position; @@ -425,9 +429,8 @@ namespace TEN::Renderer newItem->PrevRotation = newItem->Rotation; newItem->PrevWorld = newItem->World; - // Otherwise all frames until the next ControlPhase will not - // be interpolated - item->DisableInterpolation = false; + // Otherwise all frames until the next ControlPhase will not be interpolated. + newItem->DisableInterpolation = false; for (int j = 0; j < MAX_BONES; j++) newItem->PrevAnimTransforms[j] = newItem->AnimTransforms[j]; diff --git a/TombEngine/Renderer/Structures/RendererItem.h b/TombEngine/Renderer/Structures/RendererItem.h index 4430445f0..0924ec4bb 100644 --- a/TombEngine/Renderer/Structures/RendererItem.h +++ b/TombEngine/Renderer/Structures/RendererItem.h @@ -29,6 +29,7 @@ namespace TEN::Renderer::Structures float LightFade = 0.0f; bool DoneAnimations = false; + bool DisableInterpolation = true; Vector3 InterpolatedPosition = Vector3::Zero; Matrix InterpolatedWorld = Matrix::Identity; diff --git a/TombEngine/Specific/winmain.cpp b/TombEngine/Specific/winmain.cpp index 3e2e7ed5b..a601d0d36 100644 --- a/TombEngine/Specific/winmain.cpp +++ b/TombEngine/Specific/winmain.cpp @@ -156,17 +156,6 @@ void CALLBACK HandleWmCommand(unsigned short wParam) SuspendThread((HANDLE)ThreadHandle); g_Renderer.ToggleFullScreen(); ResumeThread((HANDLE)ThreadHandle); - - if (g_Renderer.IsFullsScreen()) - { - SetCursor(nullptr); - ShowCursor(false); - } - else - { - SetCursor(LoadCursorA(App.hInstance, (LPCSTR)0x68)); - ShowCursor(true); - } } } } @@ -180,6 +169,15 @@ LRESULT CALLBACK WinAppProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { return 0; } + + if (msg == WM_SETCURSOR) + { + if (LOWORD(lParam) == HTCLIENT) + { + SetCursor(g_Renderer.IsFullsScreen() ? nullptr : App.WindowClass.hCursor); + return 1; + } + } if (msg == WM_ACTIVATEAPP) { @@ -370,7 +368,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine App.WindowClass.lpfnWndProc = WinAppProc; App.WindowClass.cbClsExtra = 0; App.WindowClass.cbWndExtra = 0; - App.WindowClass.hCursor = LoadCursor(App.hInstance, IDC_ARROW); + App.WindowClass.hCursor = LoadCursorA(NULL, IDC_ARROW); // Register main window. if (!RegisterClass(&App.WindowClass)) @@ -461,8 +459,6 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine UpdateWindow(WindowsHandle); ShowWindow(WindowsHandle, nShowCmd); - SetCursor(NULL); - ShowCursor(FALSE); hAccTable = LoadAccelerators(hInstance, (LPCSTR)0x65); } catch (std::exception& ex)