#include "Timer.h"
#pragma comment(lib, "winmm.lib")
//////////////////////////////////////////////////////////////
// コンストラクタ 初期化はここでやっちゃう
//////////////////////////////////////////////////////////////
Timer::Timer()
:m_fps(0), m_periodMin(0),m_isElapsedFrame(false), m_lastTime(0),
m_surplusTime(0), m_maxWait(0), m_skipCount(0), m_drawCount(0),
m_drawFPS(0), m_drawSkip(0), m_lastCalc(0)
{
//分解能を調べてTIMECAPS構造体に格納
TIMECAPS tc;
::timeGetDevCaps(&tc, sizeof(tc));
m_periodMin = tc.wPeriodMin;
//最小の分解能をマルチメディアタイマに設定
::timeBeginPeriod(m_periodMin);
setFPS(60);
resetTimer();
}
///////////////////////////////////////////////////////////////
// デストラクタ
///////////////////////////////////////////////////////////////
Timer::~Timer()
{
//timeBeginPeriodが呼ばれていたら0にはなっていない
if(m_periodMin != 0)
::timeEndPeriod(m_periodMin);
}
///////////////////////////////////////////////////////////////
// タイマーをリセット
///////////////////////////////////////////////////////////////
void Timer::resetTimer(){
m_lastTime = ::timeGetTime();
m_surplusTime = 0;
return;
}
void Timer::setFPS(unsigned fps){
m_fps = fps;
m_maxWait = 1000/fps;
return;
}
///////////////////////////////////////////////////////////////
// 前フレームの処理が1Fの単位時間を越えていたかを返す
///////////////////////////////////////////////////////////////
bool Timer::isElapsedFrame(){
return m_isElapsedFrame;
}
///////////////////////////////////////////////////////////////
// ウェイト時間を計算し、sleepする関数
///////////////////////////////////////////////////////////////
void Timer::wait(){
//現在時間取得
__int64 current_time = ::timeGetTime();
//待機、超過時間設定
//1F単位時間から経過時間を引いて、待つべき時間を計算
__int64 wait_time = m_maxWait - (current_time - m_lastTime);
m_surplusTime += wait_time; //余剰時間の累積
//余剰時間がマイナスの場合(処理時間が単位時間を超えてしまっている場合)
if(m_surplusTime < 0){
wait_time = 0;
m_skipCount++;
m_isElapsedFrame = true; //フラグをセット
//余剰時間が問題ない場合、処理が追いついた場合
} else {
if(wait_time != m_surplusTime)
wait_time = m_surplusTime;
m_surplusTime = 0;
m_drawCount++;
m_isElapsedFrame = false; //フラグをセット
}
//Sleepする
if(wait_time > 0)
::Sleep((DWORD)wait_time);
m_lastTime = ::timeGetTime();
}
///////////////////////////////////////////////////////////////
// フレームレート関連
// wait後に呼ばれることを想定
///////////////////////////////////////////////////////////////
FPSData Timer::getFPS(){
//
const DWORD CURRENT_TIME = ::timeGetTime();
const DWORD ELAPSED_TIME = CURRENT_TIME - m_lastCalc; //経過時間
if(ELAPSED_TIME >= 1000) {
m_drawFPS = m_drawCount * 1000 / ELAPSED_TIME;
m_drawSkip = m_skipCount * 1000 / ELAPSED_TIME;
m_drawCount = 0;
m_skipCount = 0;
m_lastCalc = CURRENT_TIME;
}
FPSData data;
data.fps = m_drawFPS;
data.skipFrame = m_drawSkip;
return data;
}
最終更新:2008年11月26日 07:28