SHADE_Y3/SHADE_Engine/src/FRC/SHFramerateController.cpp

154 lines
4.2 KiB
C++

/*********************************************************************
* \file SHFramerateController.cpp
* \author Ryan Wang Nian Jing
* \brief Definition for functions of the framerate controller
* Handles changing of scenes and manages loop (timestep, etc.)
*
* \copyright Copyright (c) 2022 DigiPen Institute of Technology. Reproduction
or disclosure of this file or its contents without the prior written
consent of DigiPen Institute of Technology is prohibited.
*********************************************************************/
//TODO Legacy code. Delete soon
#include <SHpch.h>
#include <chrono>
#include <cassert>
#include "SHFramerateController.h"
namespace SHADE
{
double SHFrameRateController::rawDeltaTime = 0.0;
std::chrono::steady_clock::time_point SHFrameRateController::prevFrameTime = std::chrono::high_resolution_clock::now();
void SHFrameRateController::UpdateFRC() noexcept
{
std::chrono::duration<double> deltaTime;
deltaTime = std::chrono::high_resolution_clock::now() - prevFrameTime;
prevFrameTime = std::chrono::high_resolution_clock::now();
rawDeltaTime = deltaTime.count();
}
}
//TODO Legacy code. Delete soon
#if 0
namespace SHADE
{
//Init statics
double SHFramerateController::fixedTimestep = 0.01;
SHScene* SHFramerateController::previousScene = nullptr;
SHScene* SHFramerateController::currentScene = nullptr;
SHScene* SHFramerateController::nextScene = nullptr;
bool SHFramerateController::toRestart = false;
bool SHFramerateController::toQuit = false;
//Scene manager loop
void SHFramerateController::Run(SHScene* firstScene)
{
if (firstScene == nullptr)
{
SHLOG_ERROR("Do not pass a nullptr as the firstScene");
return;
}
//Set quit and restart flags to false
toQuit = false;
toRestart = false;
//Set the first scene to run
previousScene = firstScene;
currentScene = firstScene;
nextScene = firstScene;
while (!toQuit)
{
if (toRestart)
{
//Restart current scene
currentScene = previousScene;
nextScene = previousScene;
toRestart = false;
}
else
{
//Move to a new scene
currentScene->Load();
}
//Call init function of current scene
currentScene->Init();
//Have an initial value
//This frame time will fluctuate
//SHOULD be larger than the fixed timestep
//TODO this might need to be changed
double variableLastFrameTime = fixedTimestep;
//Time accumulator for meshing between fixed and variable timesteps
double accumulator = 0.0;
//Start state loop
while (currentScene == nextScene && !toQuit && !toRestart)
{
//Use of new STL timing functions
//https://en.cppreference.com/w/cpp/chrono
std::chrono::duration<double> deltaTime;
auto startTime = std::chrono::high_resolution_clock::now();
//Whittle down the accumulator by continuously simulating
for (; accumulator > fixedTimestep; accumulator -= fixedTimestep)
{
MSG msg;
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
//TODO change to double
currentScene->Update((float)fixedTimestep);
}
//Interpolation
//Manage the alpha value well
//https://randomascii.wordpress.com/2012/02/13/dont-store-that-in-a-float/
//Key points:
//1) Any time you add or subtract floats of widely varying
// magnitudes, you need to watch for loss of precision
//2) Sometimes using double instead of float is the correct
// solution, but often a more stable algorithm is more important
//3) calcT() should probably use double (to give sufficient
// precision after many hours of gameplay)
//TODO awaiting approval to use this
//double alpha = accumulator / fixedTimestep;
//assert alpha does not go out of range
currentScene->Render();
auto endTime = std::chrono::high_resolution_clock::now();
deltaTime = endTime - startTime;
variableLastFrameTime = deltaTime.count();
//Increase accumulator
accumulator += variableLastFrameTime;
}
//Free once out of scene loop
currentScene->Free();
//Check if not to restart state
//If so, unload
if (!toRestart) currentScene->Unload();
//Shift forward scenes
previousScene = currentScene;
currentScene = nextScene;
}
}
}
#endif