Decopypaste sync code, rename variable framerate to high, remove unused variables

This commit is contained in:
Lwmte 2024-10-25 08:43:45 +02:00
parent 9a3166b9a1
commit 53e7ca0972
21 changed files with 181 additions and 228 deletions

View file

@ -75,6 +75,7 @@ local strings =
exit_to_title = { "Exit to Title" },
general_actions = { "General Actions" },
high = { "High" },
high_framerate = { "High Framerate" },
level_secrets_found = { "Secrets Found in Level" },
load_game = { "Load Game" },
low = { "Low" },
@ -114,7 +115,6 @@ 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" },

View file

@ -60,7 +60,6 @@ using namespace TEN::Gui;
using TEN::Renderer::g_Renderer;
LaraInfo Lara = {};
LaraInfo PrevLara = {};
ItemInfo* LaraItem = nullptr;
CollisionInfo LaraCollision = {};

View file

@ -94,7 +94,6 @@ constexpr auto SWIM_WATER_DEPTH = CLICK(2.75f);
constexpr auto SLOPE_DIFFERENCE = 60;
extern LaraInfo Lara;
extern LaraInfo PrevLara;
extern ItemInfo* LaraItem;
extern CollisionInfo LaraCollision;

View file

@ -1,7 +1,6 @@
#include "framework.h"
#include "Game/control/control.h"
#include <chrono>
#include <process.h>
#include "Game/camera.h"
@ -60,7 +59,6 @@
#include "Specific/Input/Input.h"
#include "Specific/level.h"
#include "Specific/winmain.h"
#include "Game/Lara/lara_initialise.h"
using namespace std::chrono;
using namespace TEN::Effects;
@ -131,8 +129,6 @@ void DrawPhase(bool isTitle, float interpolationFactor)
GameStatus ControlPhase()
{
static int framesCount = 0;
auto time1 = std::chrono::high_resolution_clock::now();
bool isTitle = (CurrentLevel == 0);
@ -157,7 +153,7 @@ GameStatus ControlPhase()
HandleControls(isTitle);
// Pre-loop script and event handling.
g_GameScript->OnLoop(DELTA_TIME, false); // TODO: Don't use DELTA_TIME constant with variable framerate
g_GameScript->OnLoop(DELTA_TIME, false); // TODO: Don't use DELTA_TIME constant with high framerate.
HandleAllGlobalEvents(EventType::Loop, (Activator)LaraItem->Index);
// Control lock is processed after handling scripts because builder may want to process input externally while locking player from input.
@ -228,14 +224,7 @@ GameStatus ControlPhase()
UpdateLocusts();
UpdateUnderwaterBloodParticles();
UpdateFishSwarm();
if (g_GameFlow->GetLevel(CurrentLevel)->GetLensFlareEnabled())
{
SetupGlobalLensFlare(
EulerAngles(g_GameFlow->GetLevel(CurrentLevel)->GetLensFlarePitch(), g_GameFlow->GetLevel(CurrentLevel)->GetLensFlareYaw(), 0),
g_GameFlow->GetLevel(CurrentLevel)->GetLensFlareColor(),
g_GameFlow->GetLevel(CurrentLevel)->GetLensFlareSunSpriteID());
}
UpdateGlobalLensFlare();
// Update HUD.
g_Hud.Update(*LaraItem);
@ -245,21 +234,17 @@ GameStatus ControlPhase()
if (g_GameFlow->GetLevel(CurrentLevel)->Rumble)
RumbleScreen();
PlaySoundSources();
// Update cameras matrices there, after having done all the possible camera logic.
g_Renderer.UpdateCameraMatrices(&Camera, BLOCK(g_GameFlow->GetLevel(CurrentLevel)->GetFarView()));
DoFlipEffect(FlipEffect, LaraItem);
PlaySoundSources();
Sound_UpdateScene();
// Post-loop script and event handling.
g_GameScript->OnLoop(DELTA_TIME, true);
// Update cameras matrices. NOTE: Must be after handling all camera logic.
g_Renderer.UpdateCameraMatrices(
&Camera,
Camera.Roll,
Camera.Fov,
BLOCK(g_GameFlow->GetLevel(CurrentLevel)->GetFarView()));
// Clear savegame loaded flag.
JustLoaded = false;
@ -267,11 +252,8 @@ GameStatus ControlPhase()
GameTimer++;
GlobalCounter++;
using ns = std::chrono::nanoseconds;
using get_time = std::chrono::steady_clock;
auto time2 = std::chrono::high_resolution_clock::now();
ControlPhaseTime = (std::chrono::duration_cast<ns>(time2 - time1)).count() / 1000000;
ControlPhaseTime = (std::chrono::duration_cast<std::chrono::nanoseconds>(time2 - time1)).count() / 1000000;
return GameStatus::Normal;
}
@ -556,10 +538,6 @@ void InitializeOrLoadGame(bool loadGame)
{
SaveGame::LoadHub(CurrentLevel);
TENLog("Starting new level.", LogLevel::Info);
// Restore vehicle.
auto* item = FindItem(ID_LARA);
InitializePlayerVehicle(*item);
}
g_GameScript->OnStart();
@ -569,8 +547,6 @@ void InitializeOrLoadGame(bool loadGame)
GameStatus DoGameLoop(int levelIndex)
{
constexpr auto CONTROL_FRAME_TIME = 1000.0f / 30.0f;
int frameCount = LOOP_FRAME_COUNT;
auto& status = g_GameFlow->LastGameStatus;
@ -578,54 +554,17 @@ GameStatus DoGameLoop(int levelIndex)
// 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;
LARGE_INTEGER frequency;
QueryPerformanceFrequency(&frequency);
QueryPerformanceCounter(&lastTime);
int controlCalls = 0;
int drawCalls = 0;
g_Synchronizer.Init();
bool legacy30FpsDoneDraw = false;
while (DoTheGame)
{
if (App.ResetClock)
{
App.ResetClock = false;
QueryPerformanceCounter(&lastTime);
currentTime = lastTime;
controlLag = 0;
frameTime = 0;
}
else
{
QueryPerformanceCounter(&currentTime);
frameTime = (currentTime.QuadPart - lastTime.QuadPart) * 1000.0 / frequency.QuadPart;
lastTime = currentTime;
controlLag += frameTime;
}
g_Synchronizer.Sync();
while (controlLag >= CONTROL_FRAME_TIME)
while (g_Synchronizer.Synced())
{
#if _DEBUG
constexpr auto DEBUG_SKIP_FRAMES = 10;
if (controlLag >= DEBUG_SKIP_FRAMES * CONTROL_FRAME_TIME)
{
TENLog("Game loop is running too slow.", LogLevel::Warning);
App.ResetClock = true;
break;
}
#endif
status = ControlPhase();
controlLag -= CONTROL_FRAME_TIME;
controlCalls++;
g_Synchronizer.Step();
legacy30FpsDoneDraw = false;
}
@ -633,20 +572,17 @@ GameStatus DoGameLoop(int levelIndex)
if (status != GameStatus::Normal)
break;
if (!g_Configuration.EnableVariableFramerate)
if (!g_Configuration.EnableHighFramerate)
{
if (!legacy30FpsDoneDraw)
{
DrawPhase(!levelIndex, 0.0f);
drawCalls++;
legacy30FpsDoneDraw = true;
}
}
else
{
float interpolationFactor = std::min((float)controlLag / (float)CONTROL_FRAME_TIME, 1.0f);
DrawPhase(!levelIndex, interpolationFactor);
drawCalls++;
DrawPhase(!levelIndex, g_Synchronizer.GetInterpolationFactor());
}
}

View file

@ -50,7 +50,7 @@ enum FadeStatus
constexpr int MAX_ROOMS = 1024;
constexpr int LOOP_FRAME_COUNT = 2;
constexpr auto LOOP_FRAME_COUNT = 2;
extern int GameTimer;
extern int RumbleTimer;

View file

@ -193,11 +193,6 @@ namespace TEN::Gui
return false;
}
float GuiController::GetSpinSpeed()
{
return g_Configuration.EnableVariableFramerate ? (g_Renderer.GetScreenRefreshRate() / 30.0f) : 1.0f;
}
bool GuiController::CanDeselect() const
{
return !(IsHeld(In::Select) || IsHeld(In::Action));
@ -488,7 +483,7 @@ namespace TEN::Gui
Caustics,
Antialiasing,
AmbientOcclusion,
VariableFramerate,
HighFramerate,
Save,
Cancel
};
@ -551,9 +546,9 @@ namespace TEN::Gui
CurrentSettings.Configuration.EnableAmbientOcclusion = !CurrentSettings.Configuration.EnableAmbientOcclusion;
break;
case DisplaySettingsOption::VariableFramerate:
case DisplaySettingsOption::HighFramerate:
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
CurrentSettings.Configuration.EnableVariableFramerate = !CurrentSettings.Configuration.EnableVariableFramerate;
CurrentSettings.Configuration.EnableHighFramerate = !CurrentSettings.Configuration.EnableHighFramerate;
break;
}
@ -603,9 +598,9 @@ namespace TEN::Gui
CurrentSettings.Configuration.EnableAmbientOcclusion = !CurrentSettings.Configuration.EnableAmbientOcclusion;
break;
case DisplaySettingsOption::VariableFramerate:
case DisplaySettingsOption::HighFramerate:
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
CurrentSettings.Configuration.EnableVariableFramerate = !CurrentSettings.Configuration.EnableVariableFramerate;
CurrentSettings.Configuration.EnableHighFramerate = !CurrentSettings.Configuration.EnableHighFramerate;
break;
}
}
@ -745,7 +740,7 @@ namespace TEN::Gui
if (fromPauseMenu)
{
g_Renderer.RenderInventory();
if (!g_Configuration.EnableVariableFramerate)
if (!g_Configuration.EnableHighFramerate)
{
g_Renderer.Synchronize();
}
@ -753,7 +748,7 @@ namespace TEN::Gui
else
{
g_Renderer.RenderTitle(0);
if (!g_Configuration.EnableVariableFramerate)
if (!g_Configuration.EnableHighFramerate)
{
g_Renderer.Synchronize();
}
@ -1995,7 +1990,7 @@ namespace TEN::Gui
else if (AmmoSelectorFadeDir == 1)
{
if (AmmoSelectorFadeVal < 128)
AmmoSelectorFadeVal += 32 / GetSpinSpeed();
AmmoSelectorFadeVal += 32 / g_Renderer.GetFramerateMultiplier();
if (AmmoSelectorFadeVal > 128)
{
@ -2006,7 +2001,7 @@ namespace TEN::Gui
else if (AmmoSelectorFadeDir == 2)
{
if (AmmoSelectorFadeVal > 0)
AmmoSelectorFadeVal -= 32 / GetSpinSpeed();
AmmoSelectorFadeVal -= 32 / g_Renderer.GetFramerateMultiplier();
if (AmmoSelectorFadeVal < 0)
{
@ -2649,7 +2644,7 @@ namespace TEN::Gui
void GuiController::SpinBack(EulerAngles& orient)
{
orient.Lerp(EulerAngles::Identity, 1.0f / (8.0f * GetSpinSpeed()));
orient.Lerp(EulerAngles::Identity, 1.0f / (8.0f * g_Renderer.GetFramerateMultiplier()));
}
void GuiController::DrawAmmoSelector()
@ -2672,13 +2667,13 @@ namespace TEN::Gui
if (n == *CurrentAmmoType)
{
if (invObject->RotFlags & INV_ROT_X)
AmmoObjectList[n].Orientation.x += ANGLE(5.0f / GetSpinSpeed());
AmmoObjectList[n].Orientation.x += ANGLE(5.0f / g_Renderer.GetFramerateMultiplier());
if (invObject->RotFlags & INV_ROT_Y)
AmmoObjectList[n].Orientation.y += ANGLE(5.0f / GetSpinSpeed());
AmmoObjectList[n].Orientation.y += ANGLE(5.0f / g_Renderer.GetFramerateMultiplier());
if (invObject->RotFlags & INV_ROT_Z)
AmmoObjectList[n].Orientation.z += ANGLE(5.0f / GetSpinSpeed());
AmmoObjectList[n].Orientation.z += ANGLE(5.0f / g_Renderer.GetFramerateMultiplier());
}
else
SpinBack(AmmoObjectList[n].Orientation);
@ -3050,13 +3045,13 @@ namespace TEN::Gui
if (!i && !ring.ObjectListMovement)
{
if (invObject.RotFlags & INV_ROT_X)
listObject.Orientation.x += ANGLE(5.0f / GetSpinSpeed());
listObject.Orientation.x += ANGLE(5.0f / g_Renderer.GetFramerateMultiplier());
if (invObject.RotFlags & INV_ROT_Y)
listObject.Orientation.y += ANGLE(5.0f / GetSpinSpeed());
listObject.Orientation.y += ANGLE(5.0f / g_Renderer.GetFramerateMultiplier());
if (invObject.RotFlags & INV_ROT_Z)
listObject.Orientation.z += ANGLE(5.0f / GetSpinSpeed());
listObject.Orientation.z += ANGLE(5.0f / g_Renderer.GetFramerateMultiplier());
}
else
{
@ -3112,17 +3107,17 @@ namespace TEN::Gui
if (ring.NumObjectsInList != 1 && (ringType != RingTypes::Ammo || CombineRingFadeVal == 128))
{
if (ring.ObjectListMovement > 0)
ring.ObjectListMovement += ANGLE(45.0f / GetSpinSpeed());
ring.ObjectListMovement += ANGLE(45.0f / g_Renderer.GetFramerateMultiplier());
if (ring.ObjectListMovement < 0)
ring.ObjectListMovement -= ANGLE(45.0f / GetSpinSpeed());
ring.ObjectListMovement -= ANGLE(45.0f / g_Renderer.GetFramerateMultiplier());
if (IsHeld(In::Left))
{
if (!ring.ObjectListMovement)
{
SoundEffect(SFX_TR4_MENU_ROTATE, nullptr, SoundEnvironment::Always);
ring.ObjectListMovement += ANGLE(45.0f / GetSpinSpeed());
ring.ObjectListMovement += ANGLE(45.0f / g_Renderer.GetFramerateMultiplier());
if (AmmoSelectorFlag)
AmmoSelectorFadeDir = 2;
@ -3134,7 +3129,7 @@ namespace TEN::Gui
if (!ring.ObjectListMovement)
{
SoundEffect(SFX_TR4_MENU_ROTATE, nullptr, SoundEnvironment::Always);
ring.ObjectListMovement -= ANGLE(45.0f / GetSpinSpeed());
ring.ObjectListMovement -= ANGLE(45.0f / g_Renderer.GetFramerateMultiplier());
if (AmmoSelectorFlag)
AmmoSelectorFadeDir = 2;
@ -3175,8 +3170,6 @@ namespace TEN::Gui
bool GuiController::CallPause()
{
constexpr auto CONTROL_FRAME_TIME = 1000.0f / 30.0f;
g_Renderer.DumpGameScene();
PauseAllSounds(SoundPauseMode::Pause);
SoundEffect(SFX_TR4_MENU_SELECT, nullptr, SoundEnvironment::Always);
@ -3187,17 +3180,7 @@ namespace TEN::Gui
bool doExitToTitle = false;
LARGE_INTEGER lastTime;
LARGE_INTEGER currentTime;
double controlLag = 0;
double frameTime = 0;
LARGE_INTEGER frequency;
QueryPerformanceFrequency(&frequency);
QueryPerformanceCounter(&lastTime);
int controlCalls = 0;
int drawCalls = 0;
g_Synchronizer.Init();
bool legacy30FpsDoneDraw = false;
@ -3209,34 +3192,10 @@ namespace TEN::Gui
return false;
}
if (App.ResetClock)
{
App.ResetClock = false;
QueryPerformanceCounter(&lastTime);
currentTime = lastTime;
controlLag = 0;
frameTime = 0;
}
else
{
QueryPerformanceCounter(&currentTime);
frameTime = (currentTime.QuadPart - lastTime.QuadPart) * 1000.0 / frequency.QuadPart;
lastTime = currentTime;
controlLag += frameTime;
}
g_Synchronizer.Sync();
while (controlLag >= CONTROL_FRAME_TIME)
while (g_Synchronizer.Synced())
{
#if _DEBUG
constexpr auto DEBUG_SKIP_FRAMES = 10;
if (controlLag >= (DEBUG_SKIP_FRAMES * CONTROL_FRAME_TIME))
{
TENLog("Game loop is running too slow.", LogLevel::Warning);
App.ResetClock = true;
break;
}
#endif
g_Renderer.PrepareScene();
if (g_Gui.DoPauseMenu(LaraItem) == InventoryResult::ExitToTitle)
@ -3245,8 +3204,7 @@ namespace TEN::Gui
break;
}
controlLag -= CONTROL_FRAME_TIME;
controlCalls++;
g_Synchronizer.Step();
legacy30FpsDoneDraw = false;
}
@ -3254,14 +3212,13 @@ namespace TEN::Gui
if (doExitToTitle)
break;
if (!g_Configuration.EnableVariableFramerate)
if (!g_Configuration.EnableHighFramerate)
{
if (!legacy30FpsDoneDraw)
{
g_Renderer.RenderInventory();
g_Renderer.Lock();
g_Renderer.Synchronize();
drawCalls++;
legacy30FpsDoneDraw = true;
}
}
@ -3269,7 +3226,6 @@ namespace TEN::Gui
{
g_Renderer.RenderInventory();
g_Renderer.Lock();
drawCalls++;
}
}
@ -3289,8 +3245,6 @@ namespace TEN::Gui
bool GuiController::CallInventory(ItemInfo* item, bool resetMode)
{
constexpr auto CONTROL_FRAME_TIME = 1000.0f / 30.0f;
auto& player = GetLaraInfo(*item);
bool doLoad = false;
@ -3306,17 +3260,7 @@ namespace TEN::Gui
InitializeInventory(item);
LARGE_INTEGER lastTime;
LARGE_INTEGER currentTime;
double controlLag = 0;
double frameTime = 0;
LARGE_INTEGER frequency;
QueryPerformanceFrequency(&frequency);
QueryPerformanceCounter(&lastTime);
int controlCalls = 0;
int drawCalls = 0;
g_Synchronizer.Init();
bool legacy30FpsDoneDraw = false;
bool exitLoop = false;
@ -3329,34 +3273,10 @@ namespace TEN::Gui
return false;
}
if (App.ResetClock)
{
App.ResetClock = false;
QueryPerformanceCounter(&lastTime);
currentTime = lastTime;
controlLag = 0;
frameTime = 0;
}
else
{
QueryPerformanceCounter(&currentTime);
frameTime = (currentTime.QuadPart - lastTime.QuadPart) * 1000.0 / frequency.QuadPart;
lastTime = currentTime;
controlLag += frameTime;
}
g_Synchronizer.Sync();
while (controlLag >= CONTROL_FRAME_TIME)
while (g_Synchronizer.Synced())
{
#if _DEBUG
constexpr auto DEBUG_SKIP_FRAME_COUNT = 10;
if (controlLag >= (DEBUG_SKIP_FRAME_COUNT * CONTROL_FRAME_TIME))
{
TENLog("Game loop is running too slow.", LogLevel::Warning);
App.ResetClock = true;
break;
}
#endif
TimeInMenu++;
GameTimer++;
@ -3425,20 +3345,18 @@ namespace TEN::Gui
exitLoop = true;
SetEnterInventory(NO_VALUE);
controlLag -= CONTROL_FRAME_TIME;
controlCalls++;
g_Synchronizer.Step();
legacy30FpsDoneDraw = false;
}
if (!g_Configuration.EnableVariableFramerate)
if (!g_Configuration.EnableHighFramerate)
{
if (!legacy30FpsDoneDraw)
{
g_Renderer.RenderInventory();
g_Renderer.Lock();
g_Renderer.Synchronize();
drawCalls++;
legacy30FpsDoneDraw = true;
}
}
@ -3446,7 +3364,6 @@ namespace TEN::Gui
{
g_Renderer.RenderInventory();
g_Renderer.Lock();
drawCalls++;
}
}

View file

@ -128,9 +128,6 @@ namespace TEN::Gui
bool CanSelect() const;
bool CanDeselect() const;
// Variable FPS
float GetSpinSpeed();
// GUI variables
Menu MenuToDisplay = Menu::Title;
int SelectedOption;

View file

@ -15,6 +15,7 @@
#include "Game/items.h"
#include "Game/itemdata/creature_info.h"
#include "Game/Lara/lara.h"
#include "Game/Lara/lara_initialise.h"
#include "Game/misc.h"
#include "Game/spotcam.h"
#include "Game/room.h"
@ -1492,6 +1493,9 @@ void SaveGame::LoadHub(int index)
// Load hub data.
TENLog("Loading hub data for level #" + std::to_string(index), LogLevel::Info);
Parse(Hub[index], true);
// Restore vehicle.
InitializePlayerVehicle(*LaraItem);
}
bool SaveGame::IsOnHub(int index)

View file

@ -4,6 +4,8 @@
#include "Game/camera.h"
#include "Game/control/los.h"
#include "Math/Math.h"
#include "Scripting/Include/ScriptInterfaceLevel.h"
#include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h"
#include "Specific/level.h"
using namespace TEN::Math;
@ -75,10 +77,17 @@ namespace TEN::Entities::Effects
LensFlares.push_back(lensFlare);
}
void SetupGlobalLensFlare(const EulerAngles& orient, const Color& color, int spriteID)
void UpdateGlobalLensFlare()
{
constexpr auto BASE_POS = Vector3(0.0f, 0.0f, BLOCK(256));
if (!g_GameFlow->GetLevel(CurrentLevel)->GetLensFlareEnabled())
return;
auto orient = EulerAngles(g_GameFlow->GetLevel(CurrentLevel)->GetLensFlarePitch(), g_GameFlow->GetLevel(CurrentLevel)->GetLensFlareYaw(), 0);
auto color = g_GameFlow->GetLevel(CurrentLevel)->GetLensFlareColor();
auto spriteID = g_GameFlow->GetLevel(CurrentLevel)->GetLensFlareSunSpriteID();
auto pos = Camera.pos.ToVector3();
auto rotMatrix = orient.ToRotationMatrix();

View file

@ -17,8 +17,7 @@ namespace TEN::Entities::Effects
extern std::vector<LensFlare> LensFlares;
void SetupGlobalLensFlare(const EulerAngles& orient, const Color& color, int spriteID);
void ControlLensFlare(int itemNumber);
void ClearLensFlares();
void UpdateGlobalLensFlare();
}

View file

@ -66,14 +66,14 @@ namespace TEN::Renderer
int Renderer::Synchronize()
{
// Sync the renderer
int nf = Sync();
int nf = TimeSync();
if (nf < 2)
{
int i = 2 - nf;
nf = 2;
do
{
while (!Sync());
while (!TimeSync());
i--;
}
while (i);

View file

@ -381,7 +381,7 @@ namespace TEN::Renderer
VertexBuffer<Vertex> _sortedPolygonsVertexBuffer;
IndexBuffer _sortedPolygonsIndexBuffer;
// Variable framerate.
// High framerate.
float _interpolationFactor = 0.0f;
// Private functions
@ -594,7 +594,7 @@ namespace TEN::Renderer
void RenderTitle(float interpFactor);
void Lock();
bool PrepareDataForTheRenderer();
void UpdateCameraMatrices(CAMERA_INFO* cam, float roll, float fov, float farView);
void UpdateCameraMatrices(CAMERA_INFO* cam, float farView);
void RenderSimpleSceneToParaboloid(RenderTarget2D* renderTarget, Vector3 position, int emisphere);
void DumpGameScene();
void RenderInventory();
@ -646,6 +646,7 @@ namespace TEN::Renderer
std::string GetDefaultAdapterName();
void SaveOldState();
float GetFramerateMultiplier() const;
float GetInterpolationFactor() const;
Vector2i GetScreenResolution() const;
int GetScreenRefreshRate() const;

View file

@ -206,9 +206,9 @@ namespace TEN::Renderer
AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableAmbientOcclusion), PRINTSTRING_COLOR_WHITE, SF(titleOption == 5));
GetNextLinePosition(&y);
// Enable variable framerate
AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_VARIABLE_FRAMERATE), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 6));
AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableVariableFramerate), PRINTSTRING_COLOR_WHITE, SF(titleOption == 6));
// Enable high framerate
AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_HIGH_FRAMERATE), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 6));
AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableHighFramerate), PRINTSTRING_COLOR_WHITE, SF(titleOption == 6));
GetNextBlockPosition(&y);
// Apply
@ -924,7 +924,7 @@ namespace TEN::Renderer
static EulerAngles orient = EulerAngles::Identity;
static float scaler = 1.2f;
float multiplier = g_Configuration.EnableVariableFramerate ? g_Renderer.GetScreenRefreshRate() / 30.0f : 1.0f;
float multiplier = g_Renderer.GetFramerateMultiplier();
short invItem = g_Gui.GetRing(RingTypes::Inventory).CurrentObjectList[g_Gui.GetRing(RingTypes::Inventory).CurrentObjectInList].InventoryItem;

View file

@ -361,13 +361,13 @@ namespace TEN::Renderer
return (!_isWindowed);
}
void Renderer::UpdateCameraMatrices(CAMERA_INFO *cam, float roll, float fov, float farView)
void Renderer::UpdateCameraMatrices(CAMERA_INFO *cam, float farView)
{
if (farView < MIN_FAR_VIEW)
farView = DEFAULT_FAR_VIEW;
_currentGameCamera = RenderView(cam, roll, fov, 32, farView, g_Configuration.ScreenWidth, g_Configuration.ScreenHeight);
_gameCamera = RenderView(cam, roll, fov, 32, farView, g_Configuration.ScreenWidth, g_Configuration.ScreenHeight);
_currentGameCamera = RenderView(cam, cam->Roll, cam->Fov, 32, farView, g_Configuration.ScreenWidth, g_Configuration.ScreenHeight);
_gameCamera = RenderView(cam, cam->Roll, cam->Fov, 32, farView, g_Configuration.ScreenWidth, g_Configuration.ScreenHeight);
}
bool Renderer::SphereBoxIntersection(BoundingBox box, Vector3 sphereCentre, float sphereRadius)
@ -508,6 +508,11 @@ namespace TEN::Renderer
return s;
}
float Renderer::GetFramerateMultiplier() const
{
return g_Configuration.EnableHighFramerate ? (g_Renderer.GetScreenRefreshRate() / (float)FPS) : 1.0f;
}
float Renderer::GetInterpolationFactor() const
{
return _interpolationFactor;

View file

@ -464,7 +464,7 @@ namespace TEN::Renderer
DXGI_SWAP_CHAIN_DESC sd;
sd.BufferDesc.Width = w;
sd.BufferDesc.Height = h;
if (!g_Configuration.EnableVariableFramerate)
if (!g_Configuration.EnableHighFramerate)
{
_refreshRate = 30;

View file

@ -71,7 +71,7 @@
#define STRING_VOLUMETRIC_FOG "volumetric_fog"
#define STRING_ANTIALIASING "antialiasing"
#define STRING_AMBIENT_OCCLUSION "ambient_occlusion"
#define STRING_VARIABLE_FRAMERATE "variable_framerate"
#define STRING_HIGH_FRAMERATE "high_framerate"
#define STRING_ANTIALIASING_NONE "none"
#define STRING_ANTIALIASING_LOW "low"
#define STRING_ANTIALIASING_MEDIUM "medium"

View file

@ -580,8 +580,10 @@ Vec3 Moveable::GetPos() const
// @bool[opt] updateRoom Will room changes be automatically detected? Set to false if you are using overlapping rooms (default: true)
void Moveable::SetPos(const Vec3& pos, sol::optional<bool> updateRoom)
{
constexpr auto BIG_DISTANCE_THRESHOLD = BLOCK(1);
auto newPos = pos.ToVector3i();
bool bigDistance = Vector3i::Distance(newPos, m_item->Pose.Position) > BLOCK(1);
bool bigDistance = Vector3i::Distance(newPos, m_item->Pose.Position) > BIG_DISTANCE_THRESHOLD;
m_item->Pose.Position = newPos;
@ -629,8 +631,10 @@ Rotation Moveable::GetRot() const
void Moveable::SetRot(const Rotation& rot)
{
constexpr auto BIG_ANGLE_THRESHOLD = ANGLE(30.0f);
auto newRot = rot.ToEulerAngles();
bool bigRotation = !EulerAngles::Compare(newRot, m_item->Pose.Orientation, ANGLE(30.0f));
bool bigRotation = !EulerAngles::Compare(newRot, m_item->Pose.Orientation, BIG_ANGLE_THRESHOLD);
m_item->Pose.Orientation = newRot;

View file

@ -1,12 +1,76 @@
#include "framework.h"
#include <chrono>
#include "Specific/clock.h"
#include "winmain.h"
constexpr auto CONTROL_FRAME_TIME = 1000.0f / 30.0f;
constexpr auto DEBUG_SKIP_FRAME_TIME = 10 * CONTROL_FRAME_TIME;
// Globals
LARGE_INTEGER PerformanceCount = {};
double LdFreq = 0.0;
double LdSync = 0.0;
double LdFreq = 0.0;
double LdSync = 0.0;
int Sync()
HighFramerateSynchronizer g_Synchronizer;
void HighFramerateSynchronizer::Init()
{
_controlDelay = 0;
_frameTime = 0;
_lastTime.QuadPart = 0;
_currentTime.QuadPart = 0;
_frequency.QuadPart = 0;
QueryPerformanceFrequency(&_frequency);
QueryPerformanceCounter(&_lastTime);
}
void HighFramerateSynchronizer::Sync()
{
if (App.ResetClock)
{
App.ResetClock = false;
QueryPerformanceCounter(&_lastTime);
_currentTime = _lastTime;
_controlDelay = 0;
_frameTime = 0;
}
else
{
QueryPerformanceCounter(&_currentTime);
_frameTime = (_currentTime.QuadPart - _lastTime.QuadPart) * 1000.0 / _frequency.QuadPart;
_lastTime = _currentTime;
_controlDelay += _frameTime;
}
}
bool HighFramerateSynchronizer::Synced()
{
#if _DEBUG
if (_controlDelay >= DEBUG_SKIP_FRAME_TIME)
{
TENLog("Game loop is running too slow.", LogLevel::Warning);
App.ResetClock = true;
return false;
}
#endif
return (_controlDelay >= CONTROL_FRAME_TIME);
}
void HighFramerateSynchronizer::Step()
{
_controlDelay -= CONTROL_FRAME_TIME;
}
float HighFramerateSynchronizer::GetInterpolationFactor()
{
return std::min((float)_controlDelay / (float)CONTROL_FRAME_TIME, 1.0f);
}
int TimeSync()
{
auto ct = LARGE_INTEGER{};
QueryPerformanceCounter(&ct);
@ -65,4 +129,4 @@ bool TestGlobalTimeInterval(float intervalSecs, float offsetSecs)
}
return ((GlobalCounter % intervalGameFrames) == offsetGameFrames);
}
}

View file

@ -17,10 +17,29 @@ struct GameTime
int Seconds = 0;
};
int Sync();
class HighFramerateSynchronizer
{
private:
LARGE_INTEGER _lastTime;
LARGE_INTEGER _currentTime;
LARGE_INTEGER _frequency;
double _controlDelay = 0.0;
double _frameTime = 0.0;
public:
void Init();
void Sync();
void Step();
bool Synced();
float GetInterpolationFactor();
};
int TimeSync();
bool TimeInit();
bool TimeReset();
GameTime GetGameTime(int ticks);
bool TestGlobalTimeInterval(float intervalSecs, float offsetSecs = 0.0f);
extern HighFramerateSynchronizer g_Synchronizer;

View file

@ -188,7 +188,7 @@ bool SaveConfiguration()
SetBoolRegKey(graphicsKey, REGKEY_ENABLE_CAUSTICS, g_Configuration.EnableCaustics) != ERROR_SUCCESS ||
SetDWORDRegKey(graphicsKey, REGKEY_ANTIALIASING_MODE, (DWORD)g_Configuration.AntialiasingMode) != ERROR_SUCCESS ||
SetBoolRegKey(graphicsKey, REGKEY_AMBIENT_OCCLUSION, g_Configuration.EnableAmbientOcclusion) != ERROR_SUCCESS ||
SetBoolRegKey(graphicsKey, REGKEY_VARIABLE_FRAMERATE, g_Configuration.EnableVariableFramerate) != ERROR_SUCCESS)
SetBoolRegKey(graphicsKey, REGKEY_HIGH_FRAMERATE, g_Configuration.EnableHighFramerate) != ERROR_SUCCESS)
{
RegCloseKey(rootKey);
RegCloseKey(graphicsKey);
@ -316,7 +316,7 @@ void InitDefaultConfiguration()
g_Configuration.EnableCaustics = true;
g_Configuration.AntialiasingMode = AntialiasingMode::Medium;
g_Configuration.EnableAmbientOcclusion = true;
g_Configuration.EnableVariableFramerate = true;
g_Configuration.EnableHighFramerate = true;
g_Configuration.SoundDevice = 1;
g_Configuration.EnableSound = true;
@ -366,7 +366,7 @@ bool LoadConfiguration()
bool enableCaustics = false;
DWORD antialiasingMode = 1;
bool enableAmbientOcclusion = false;
bool enableVariableFramerate = false;
bool enableHighFramerate = false;
// Load Graphics keys.
if (GetDWORDRegKey(graphicsKey, REGKEY_SCREEN_WIDTH, &screenWidth, 0) != ERROR_SUCCESS ||
@ -378,7 +378,7 @@ bool LoadConfiguration()
GetBoolRegKey(graphicsKey, REGKEY_ENABLE_CAUSTICS, &enableCaustics, true) != ERROR_SUCCESS ||
GetDWORDRegKey(graphicsKey, REGKEY_ANTIALIASING_MODE, &antialiasingMode, true) != ERROR_SUCCESS ||
GetBoolRegKey(graphicsKey, REGKEY_AMBIENT_OCCLUSION, &enableAmbientOcclusion, false) != ERROR_SUCCESS ||
GetBoolRegKey(graphicsKey, REGKEY_VARIABLE_FRAMERATE, &enableVariableFramerate, false) != ERROR_SUCCESS)
GetBoolRegKey(graphicsKey, REGKEY_HIGH_FRAMERATE, &enableHighFramerate, false) != ERROR_SUCCESS)
{
RegCloseKey(rootKey);
RegCloseKey(graphicsKey);
@ -508,7 +508,7 @@ bool LoadConfiguration()
g_Configuration.AntialiasingMode = AntialiasingMode(antialiasingMode);
g_Configuration.ShadowMapSize = shadowMapSize;
g_Configuration.EnableAmbientOcclusion = enableAmbientOcclusion;
g_Configuration.EnableVariableFramerate = enableVariableFramerate;
g_Configuration.EnableHighFramerate = enableHighFramerate;
g_Configuration.EnableSound = enableSound;
g_Configuration.EnableReverb = enableReverb;

View file

@ -25,7 +25,7 @@ constexpr auto REGKEY_SHADOW_BLOBS_MAX = "ShadowBlobsMax";
constexpr auto REGKEY_ENABLE_CAUSTICS = "EnableCaustics";
constexpr auto REGKEY_ANTIALIASING_MODE = "AntialiasingMode";
constexpr auto REGKEY_AMBIENT_OCCLUSION = "AmbientOcclusion";
constexpr auto REGKEY_VARIABLE_FRAMERATE = "EnableVariableFramerate";
constexpr auto REGKEY_HIGH_FRAMERATE = "EnableHighFramerate";
// Sound keys
@ -72,7 +72,7 @@ struct GameConfiguration
int ShadowBlobsMax = DEFAULT_SHADOW_BLOBS_MAX;
bool EnableCaustics = false;
bool EnableAmbientOcclusion = false;
bool EnableVariableFramerate = true;
bool EnableHighFramerate = true;
AntialiasingMode AntialiasingMode = AntialiasingMode::None;
// Sound