From 411c397027f9d6f30ffe2d40fe538491f6aa6ba4 Mon Sep 17 00:00:00 2001 From: Sezz Date: Fri, 17 May 2024 18:52:26 +1000 Subject: [PATCH 1/3] Minor formatting --- Scripts/SystemStrings.lua | 2 +- TombEngine/Renderer/RendererDraw.cpp | 17 ++++++++--------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/Scripts/SystemStrings.lua b/Scripts/SystemStrings.lua index 69009d8eb..73caa9386 100644 --- a/Scripts/SystemStrings.lua +++ b/Scripts/SystemStrings.lua @@ -110,10 +110,10 @@ local strings = total_secrets_found = { "Secrets Found Total" }, use = { "Use" }, used_medipacks = { "Medipacks Used" }, + variable_framerate = { "Variable Framerate" }, vehicle_actions = { "Vehicle Actions" }, view = { "View" }, volumetric_fog = { "Volumetric Fog" }, - variable_framerate = { "Variable Framerate" }, waiting_for_input = { "Waiting For Input" }, window_title = { "TombEngine" }, windowed = { "Windowed" }, diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp index 137143413..364ad3156 100644 --- a/TombEngine/Renderer/RendererDraw.cpp +++ b/TombEngine/Renderer/RendererDraw.cpp @@ -3547,8 +3547,8 @@ namespace TEN::Renderer void Renderer::DrawItemSorted(RendererSortableObject* objectInfo, RendererObjectType lastObjectType, RenderView& view) { - UINT stride = sizeof(Vertex); - UINT offset = 0; + unsigned int stride = sizeof(Vertex); + unsigned int offset = 0; _context->IASetVertexBuffers(0, 1, _moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset); _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); _context->IASetInputLayout(_inputLayout.Get()); @@ -3561,25 +3561,24 @@ namespace TEN::Renderer _context->VSSetShader(_vsItems.Get(), nullptr, 0); _context->PSSetShader(_psItems.Get(), nullptr, 0); - ItemInfo* nativeItem = &g_Level.Items[objectInfo->Item->ItemNumber]; - RendererRoom* room = &_rooms[objectInfo->Item->RoomNumber]; - RendererObject& moveableObj = *_moveableObjects[objectInfo->Item->ObjectNumber]; - - // Bind item main properties + // Bind main item properties. _stItem.World = objectInfo->Item->InterpolatedWorld; _stItem.Color = objectInfo->Item->Color; _stItem.AmbientLight = objectInfo->Item->AmbientLight; memcpy(_stItem.BonesMatrices, objectInfo->Item->InterpolatedAnimationTransforms, sizeof(Matrix) * MAX_BONES); + const auto& moveableObj = *_moveableObjects[objectInfo->Item->ObjectNumber]; for (int k = 0; k < moveableObj.ObjectMeshes.size(); k++) _stItem.BoneLightModes[k] = (int)moveableObj.ObjectMeshes[k]->LightMode; BindMoveableLights(objectInfo->Item->LightsToDraw, objectInfo->Item->RoomNumber, objectInfo->Item->PrevRoomNumber, objectInfo->Item->LightFade); _cbItem.UpdateData(_stItem, _context.Get()); - BindTexture(TextureRegister::ColorMap, &std::get<0>(_moveablesTextures[objectInfo->Bucket->Texture]), + BindTexture( + TextureRegister::ColorMap, &std::get<0>(_moveablesTextures[objectInfo->Bucket->Texture]), SamplerStateRegister::AnisotropicClamp); - BindTexture(TextureRegister::NormalMap, &std::get<1>(_moveablesTextures[objectInfo->Bucket->Texture]), + BindTexture( + TextureRegister::NormalMap, &std::get<1>(_moveablesTextures[objectInfo->Bucket->Texture]), SamplerStateRegister::AnisotropicClamp); _sortedPolygonsIndexBuffer.Update(_context.Get(), _sortedPolygonsIndices, 0, (int)_sortedPolygonsIndices.size()); From 206fd59e55fbcef30069feee2d4ff8cebc588463 Mon Sep 17 00:00:00 2001 From: Sezz Date: Fri, 17 May 2024 18:57:22 +1000 Subject: [PATCH 2/3] Interpolate speedometer --- TombEngine/Game/Hud/Speedometer.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/TombEngine/Game/Hud/Speedometer.cpp b/TombEngine/Game/Hud/Speedometer.cpp index cc3d0fe69..9689c6d73 100644 --- a/TombEngine/Game/Hud/Speedometer.cpp +++ b/TombEngine/Game/Hud/Speedometer.cpp @@ -48,7 +48,7 @@ namespace TEN::Hud void SpeedometerController::Draw() const { constexpr auto POS = Vector2(DISPLAY_SPACE_RES.x - (DISPLAY_SPACE_RES.x / 6), DISPLAY_SPACE_RES.y - (DISPLAY_SPACE_RES.y / 10)); - constexpr auto ORIENT_OFFSET = ANGLE(90.0f); + constexpr auto POINTER_ANGLE_OFFSET = ANGLE(90.0f); constexpr auto SCALE = Vector2(0.35f); constexpr auto DIAL_ELEMENT_SPRITE_ID = 0; constexpr auto POINTER_ELEMENT_SPRITE_ID = 1; @@ -60,9 +60,8 @@ namespace TEN::Hud if (_life <= 0.0f) return; - // TODO: Interpolation. - - auto color = Color(1.0f, 1.0f, 1.0f, _opacity); + short pointerAngle = (short)Lerp(_prevPointerAngle, _pointerAngle, g_Renderer.GetInterpolationFactor()); + auto color = Color(1.0f, 1.0f, 1.0f, Lerp(_prevOpacity, _opacity, g_Renderer.GetInterpolationFactor())); // Draw dial. AddDisplaySprite( @@ -74,7 +73,7 @@ namespace TEN::Hud // Draw pointer. AddDisplaySprite( ID_SPEEDOMETER, POINTER_ELEMENT_SPRITE_ID, - POS, _pointerAngle + ORIENT_OFFSET, SCALE, color, + POS, pointerAngle + POINTER_ANGLE_OFFSET, SCALE, color, POINTER_PRIORITY, DisplaySpriteAlignMode::Center, DisplaySpriteScaleMode::Fit, BlendMode::AlphaBlend, DisplaySpritePhase::Draw); } From de91720fc9c6857bdaa7b7ac88c919a0155db715 Mon Sep 17 00:00:00 2001 From: Sezz Date: Fri, 17 May 2024 19:40:09 +1000 Subject: [PATCH 3/3] Formatting --- TombEngine/Game/Lara/lara.cpp | 6 -- TombEngine/Game/Lara/lara.h | 6 +- TombEngine/Game/camera.cpp | 2 +- TombEngine/Game/control/control.cpp | 116 +++++++++++++++------------- TombEngine/Game/gui.cpp | 4 +- 5 files changed, 68 insertions(+), 66 deletions(-) diff --git a/TombEngine/Game/Lara/lara.cpp b/TombEngine/Game/Lara/lara.cpp index b39f9c246..bc4465ce6 100644 --- a/TombEngine/Game/Lara/lara.cpp +++ b/TombEngine/Game/Lara/lara.cpp @@ -629,12 +629,6 @@ void UpdateLara(ItemInfo* item, bool isTitle) // Control player. InItemControlLoop = true; - - // Copy current state to old state for interpolation - //memcpy(&item->OldPose, &item->Pose, sizeof(Pose)); - //memcpy(&item->OldLocation, &item->Location, sizeof(Vector3i)); - //memcpy(&item->OldAnimation, &item->Animation, sizeof(EntityAnimationData)); - //memcpy(&OldLara, &Lara, sizeof(LaraInfo)); LaraControl(item, &LaraCollision); HandlePlayerFlyCheat(*item); diff --git a/TombEngine/Game/Lara/lara.h b/TombEngine/Game/Lara/lara.h index 223f47f77..fda62282c 100644 --- a/TombEngine/Game/Lara/lara.h +++ b/TombEngine/Game/Lara/lara.h @@ -93,9 +93,9 @@ constexpr auto WADE_WATER_DEPTH = STEPUP_HEIGHT; constexpr auto SWIM_WATER_DEPTH = CLICK(2.75f); constexpr auto SLOPE_DIFFERENCE = 60; -extern LaraInfo Lara; -extern LaraInfo PrevLara; -extern ItemInfo* LaraItem; +extern LaraInfo Lara; +extern LaraInfo PrevLara; +extern ItemInfo* LaraItem; extern CollisionInfo LaraCollision; void LaraControl(ItemInfo* item, CollisionInfo* coll); diff --git a/TombEngine/Game/camera.cpp b/TombEngine/Game/camera.cpp index b3733f0d1..a53123c16 100644 --- a/TombEngine/Game/camera.cpp +++ b/TombEngine/Game/camera.cpp @@ -202,7 +202,7 @@ void LookAt(CAMERA_INFO* cam, short roll) float levelFarView = g_GameFlow->GetLevel(CurrentLevel)->GetFarView() * float(BLOCK(1)); - g_Renderer.UpdateCameraMatrices(cam, r, fov, levelFarView); + g_Renderer.UpdateCameraMatrices(cam, r, fov, levelFarView); } void AlterFOV(short value, bool store) diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp index 504a55a9f..6fa9b355d 100644 --- a/TombEngine/Game/control/control.cpp +++ b/TombEngine/Game/control/control.cpp @@ -153,20 +153,18 @@ GameStatus ControlPhase() SetupInterpolation(); g_Renderer.SaveOldState(); - // Controls are polled before OnLoop, so input data could be - // overwritten by script API methods. + // Controls are polled before OnLoop to allow input data to be overwritten by script API methods. HandleControls(isTitle); // Pre-loop script and event handling. g_GameScript->OnLoop(DELTA_TIME, false); // TODO: Don't use DELTA_TIME constant with variable framerate HandleAllGlobalEvents(EventType::Loop, (Activator)LaraItem->Index); - // Control lock is processed after handling scripts, because builder may want to - // process input externally, while still locking Lara from input. + // Control lock is processed after handling scripts because builder may want to process input externally while locking player from input. if (!isTitle && Lara.Control.IsLocked) ClearAllActions(); - // Handle inventory / pause / load / save screens. + // Handle inventory, pause, load, save screens. auto result = HandleMenuCalls(isTitle); if (result != GameStatus::Normal) return result; @@ -176,9 +174,8 @@ GameStatus ControlPhase() if (result != GameStatus::Normal) return result; - // Queued input actions are read again and cleared after UI - // interrupts are processed, so first frame after exiting UI - // will still register it. + // Queued input actions are read again and cleared after UI interrupts are processed, + // so first game frame after exiting UI will still register it. ApplyActionQueue(); ClearActionQueue(); @@ -188,14 +185,14 @@ GameStatus ControlPhase() g_GameScriptEntities->TestCollidingObjects(); + // Draw flyby cameras. if (UseSpotCam) { - // Draw flyby cameras. CalculateSpotCameras(); } + // Do standard camera. else { - // Do the standard camera. TrackCameraInit = false; CalculateCamera(LaraCollision); } @@ -206,11 +203,11 @@ GameStatus ControlPhase() // Smash shatters and clear stopper flags under them. UpdateShatters(); - // Clear last selected item in inventory (need to be after on loop event handling, so they can detect that). + // Clear last selected item in inventory (must be after on loop event handling, so they can detect that). g_Gui.CancelInventorySelection(); - // Control lock is processed after handling scripts, because builder may want to - // process input externally, while still locking Lara from input. + // Control lock is processed after handling scripts because builder may want to + // process input externally while locking player from input. if (!isTitle && Lara.Control.IsLocked) ClearAllActions(); @@ -286,22 +283,26 @@ GameStatus ControlPhase() unsigned CALLBACK GameMain(void *) { - TENLog("Starting GameMain...", LogLevel::Info); + TENLog("Starting GameMain()...", LogLevel::Info); TimeInit(); - // Do a fixed time title image. + // Do fixed-time title image. if (g_GameFlow->IntroImagePath.empty()) - TENLog("Intro image path is not set.", LogLevel::Warning); + { + TENLog("Intro image path not set.", LogLevel::Warning); + } else + { g_Renderer.RenderTitleImage(); + } - // Execute the Lua gameflow and play the game. + // Execute Lua gameflow and play game. g_GameFlow->DoFlow(); DoTheGame = false; - // Finish the thread. + // Finish thread. PostMessage(WindowsHandle, WM_CLOSE, NULL, NULL); EndThread(); @@ -317,7 +318,7 @@ GameStatus DoLevel(int levelIndex, bool loadGame) // Load level. Fall back to title if unsuccessful. if (!LoadLevelFile(levelIndex)) - return isTitle ? GameStatus::ExitGame : GameStatus::ExitToTitle; + return (isTitle ? GameStatus::ExitGame : GameStatus::ExitToTitle); // Initialize items, effects, lots, and cameras. HairEffect.Initialize(); @@ -374,11 +375,15 @@ void KillMoveItems() { for (int i = 0; i < ItemNewRoomNo; i++) { - short itemNumber = ItemNewRooms[2 * i]; + int itemNumber = ItemNewRooms[i * 2]; if (itemNumber >= 0) - ItemNewRoom(itemNumber, ItemNewRooms[2 * i + 1]); + { + ItemNewRoom(itemNumber, ItemNewRooms[(i * 2) + 1]); + } else + { KillItem(itemNumber & 0x7FFF); + } } } @@ -391,11 +396,15 @@ void KillMoveEffects() { for (int i = 0; i < ItemNewRoomNo; i++) { - short itemNumber = ItemNewRooms[2 * i]; + int itemNumber = ItemNewRooms[i * 2]; if (itemNumber >= 0) - EffectNewRoom(itemNumber, ItemNewRooms[2 * i + 1]); + { + EffectNewRoom(itemNumber, ItemNewRooms[(i * 2) + 1]); + } else + { KillEffect(itemNumber & 0x7FFF); + } } } @@ -417,13 +426,13 @@ void CleanUp() // Reset oscillator seed. Wibble = 0; - // Needs to be cleared, otherwise controls will lock if user exits to title while playing flyby with locked controls. + // Clear player lock, otherwise controls will lock if user exits to title while playing flyby with locked controls. Lara.Control.IsLocked = false; // Resets lightning and wind parameters to avoid holding over previous weather to new level. Weather.Clear(); - // Needs to be cleared, otherwise a list of active creatures from previous level will spill into new level. + // Clear creatures, otherwise list of active creatures from previous level will spill into new level. ActiveCreatures.clear(); // Clear ropes. @@ -473,26 +482,27 @@ void InitializeScripting(int levelIndex, LevelLoadType type) g_GameStringsHandler->ClearDisplayStrings(); g_GameScript->ResetScripts(!levelIndex || type != LevelLoadType::New); - auto* level = g_GameFlow->GetLevel(levelIndex); + const auto& level = *g_GameFlow->GetLevel(levelIndex); // Run level script if it exists. - if (!level->ScriptFileName.empty()) + if (!level.ScriptFileName.empty()) { - g_GameScript->ExecuteScriptFile(g_GameFlow->GetGameDir() + level->ScriptFileName); + g_GameScript->ExecuteScriptFile(g_GameFlow->GetGameDir() + level.ScriptFileName); g_GameScript->InitCallbacks(); g_GameStringsHandler->SetCallbackDrawString([](const std::string& key, D3DCOLOR color, const Vec2& pos, float scale, int flags) { g_Renderer.AddString( key, - Vector2(((float)pos.x / (float)g_Configuration.ScreenWidth * DISPLAY_SPACE_RES.x), - ((float)pos.y / (float)g_Configuration.ScreenHeight * DISPLAY_SPACE_RES.y)), + Vector2( + (pos.x / g_Configuration.ScreenWidth) * DISPLAY_SPACE_RES.x, + (pos.y / g_Configuration.ScreenHeight) * DISPLAY_SPACE_RES.y), Color(color), scale, flags); }); } // Play default background music. if (type != LevelLoadType::Load) - PlaySoundTrack(level->GetAmbientTrack(), SoundTrackType::BGM); + PlaySoundTrack(level.GetAmbientTrack(), SoundTrackType::BGM); } void DeInitializeScripting(int levelIndex, GameStatus reason) @@ -503,7 +513,7 @@ void DeInitializeScripting(int levelIndex, GameStatus reason) g_GameScript->FreeLevelScripts(); g_GameScriptEntities->FreeEntities(); - if (!levelIndex) + if (levelIndex == 0) g_GameScript->ResetScripts(true); } @@ -512,7 +522,7 @@ void InitializeOrLoadGame(bool loadGame) g_Gui.SetInventoryItemChosen(NO_VALUE); g_Gui.SetEnterInventory(NO_VALUE); - // Restore the game? + // Restore game? if (loadGame) { SaveGame::Load(g_GameFlow->SelectedSaveGame); @@ -533,7 +543,7 @@ void InitializeOrLoadGame(bool loadGame) } else { - // If not loading a savegame, clear all info. + // If not loading savegame, clear all info. SaveGame::Statistics.Level = {}; if (InitializeGame) @@ -559,19 +569,19 @@ void InitializeOrLoadGame(bool loadGame) GameStatus DoGameLoop(int levelIndex) { - int numFrames = LOOP_FRAME_COUNT; + constexpr auto CONTROL_FRAME_TIME = 1000.0f / 30.0f; + + int frameCount = LOOP_FRAME_COUNT; auto& status = g_GameFlow->LastGameStatus; - // Before entering actual game loop, ControlPhase must be + // Before entering actual game loop, ControlPhase() must be // called once to sort out various runtime shenanigangs (e.g. hair). - status = ControlPhase(); LARGE_INTEGER lastTime; LARGE_INTEGER currentTime; double controlLag = 0; double frameTime = 0; - constexpr auto controlFrameTime = 1000.0f / 30.0f; LARGE_INTEGER frequency; QueryPerformanceFrequency(&frequency); @@ -600,21 +610,21 @@ GameStatus DoGameLoop(int levelIndex) controlLag += frameTime; } - while (controlLag >= controlFrameTime) + while (controlLag >= CONTROL_FRAME_TIME) { #if _DEBUG constexpr auto DEBUG_SKIP_FRAMES = 10; - if (controlLag >= DEBUG_SKIP_FRAMES * controlFrameTime) + if (controlLag >= DEBUG_SKIP_FRAMES * CONTROL_FRAME_TIME) { - TENLog("Game loop is running too slow!", LogLevel::Warning); + TENLog("Game loop is running too slow.", LogLevel::Warning); App.ResetClock = true; break; } #endif status = ControlPhase(); - controlLag -= controlFrameTime; + controlLag -= CONTROL_FRAME_TIME; controlCalls++; legacy30FpsDoneDraw = false; @@ -634,7 +644,7 @@ GameStatus DoGameLoop(int levelIndex) } else { - float interpolationFactor = std::min((float)controlLag / (float)controlFrameTime, 1.0f); + float interpolationFactor = std::min((float)controlLag / (float)CONTROL_FRAME_TIME, 1.0f); DrawPhase(!levelIndex, interpolationFactor); drawCalls++; } @@ -658,9 +668,7 @@ void EndGameLoop(int levelIndex, GameStatus reason) void SetupInterpolation() { for (int i = 0; i < g_Level.Items.size(); i++) - { g_Level.Items[i].DisableInterpolation = false; - } } void HandleControls(bool isTitle) @@ -675,10 +683,10 @@ void HandleControls(bool isTitle) GameStatus HandleMenuCalls(bool isTitle) { - auto result = GameStatus::Normal; + auto gameStatus = GameStatus::Normal; if (ScreenFading) - return result; + return gameStatus; if (isTitle) { @@ -697,10 +705,10 @@ GameStatus HandleMenuCalls(bool isTitle) return GameStatus::ExitGame; } - return result; + return gameStatus; } - // Does the player want to enter inventory? + // Handle inventory. if (IsClicked(In::Save) && LaraItem->HitPoints > 0 && g_Gui.GetInventoryMode() != InventoryMode::Save && g_GameFlow->IsLoadSaveEnabled()) @@ -717,28 +725,28 @@ GameStatus HandleMenuCalls(bool isTitle) g_Gui.SetInventoryMode(InventoryMode::Load); if (g_Gui.CallInventory(LaraItem, false)) - result = GameStatus::LoadGame; + gameStatus = GameStatus::LoadGame; } else if (IsClicked(In::Pause) && LaraItem->HitPoints > 0 && g_Gui.GetInventoryMode() != InventoryMode::Pause) { if (g_Gui.CallPause()) - result = GameStatus::ExitToTitle; + gameStatus = GameStatus::ExitToTitle; } else if ((IsClicked(In::Inventory) || g_Gui.GetEnterInventory() != NO_VALUE) && LaraItem->HitPoints > 0 && !Lara.Control.Look.IsUsingBinoculars) { if (g_Gui.CallInventory(LaraItem, true)) - result = GameStatus::LoadGame; + gameStatus = GameStatus::LoadGame; } - if (result != GameStatus::Normal) + if (gameStatus != GameStatus::Normal) { StopAllSounds(); StopRumble(); } - return result; + return gameStatus; } GameStatus HandleGlobalInputEvents(bool isTitle) diff --git a/TombEngine/Game/gui.cpp b/TombEngine/Game/gui.cpp index 6af798543..16ef14da1 100644 --- a/TombEngine/Game/gui.cpp +++ b/TombEngine/Game/gui.cpp @@ -3588,8 +3588,8 @@ namespace TEN::Gui auto needleOrient = EulerAngles(0, CompassNeedleAngle, 0); needleOrient.Lerp(EulerAngles(0, item->Pose.Orientation.y, 0), LERP_ALPHA); - float wibble = std::sin(((float)(GameTimer & 0x3F) / (float)0x3F) * PI_MUL_2); - CompassNeedleAngle = needleOrient.y + ANGLE(wibble); + float wibble = std::sin((float(GameTimer & 0x3F) / (float)0x3F) * PI_MUL_2); + CompassNeedleAngle = needleOrient.y + ANGLE(wibble / 2); // HACK: Needle is rotated in the draw function. const auto& invObject = InventoryObjectTable[INV_OBJECT_COMPASS];