154 lines
4.2 KiB
C++
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
|