mirror of
https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git
synced 2025-07-19 19:59:09 +00:00
Hoist MOULOpenSourceClientPlugin/Plasma20/* to top level
to match H'uru layout and make patching/cherry-picking easier.
This commit is contained in:
421
Sources/Plasma/NucleusLib/pnTimer/hsTimer.cpp
Normal file
421
Sources/Plasma/NucleusLib/pnTimer/hsTimer.cpp
Normal file
@ -0,0 +1,421 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#include "hsTimer.h"
|
||||
#include "hsUtils.h"
|
||||
|
||||
#if HS_BUILD_FOR_MAC
|
||||
#include <Timer.h>
|
||||
#endif
|
||||
|
||||
#include "plTweak.h"
|
||||
|
||||
//
|
||||
// plTimerShare - the actual worker. All process spaces should share a single
|
||||
// plTimerShare to keep time synchronized across spaces.
|
||||
//
|
||||
plTimerShare::plTimerShare()
|
||||
: fFirstTime(true),
|
||||
fSysSeconds(0),
|
||||
fRealSeconds(0),
|
||||
fDelSysSeconds(0),
|
||||
fFrameTimeInc(0.03f),
|
||||
fSysTimeScale(1.f),
|
||||
fTimeClampSecs(0.1f),
|
||||
fSmoothingClampSecs(-1.0f),
|
||||
fRunningFrameTime(false),
|
||||
fClamping(false),
|
||||
fResetSmooth(true),
|
||||
fCurrSlot(0)
|
||||
{
|
||||
}
|
||||
|
||||
plTimerShare::~plTimerShare()
|
||||
{
|
||||
}
|
||||
|
||||
double plTimerShare::GetSeconds() const
|
||||
{
|
||||
hsWide ticks;
|
||||
return hsTimer::GetRawTicks(&ticks)->AsDouble() / hsTimer::GetRawBase().AsDouble();
|
||||
}
|
||||
|
||||
double plTimerShare::GetMilliSeconds() const
|
||||
{
|
||||
return GetSeconds() * 1.e3;
|
||||
}
|
||||
|
||||
hsWide plTimerShare::DSecondsToRawTicks(double secs)
|
||||
{
|
||||
hsWide retVal;
|
||||
double ticks = secs * hsTimer::GetRawBase().AsDouble();
|
||||
double hi = ticks / double(65536) / double(65536);
|
||||
ticks -= hi;
|
||||
retVal.fHi = Int32(hi);
|
||||
retVal.fLo = Int32(ticks);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
double plTimerShare::RawTicksToDSeconds(const hsWide& ticks)
|
||||
{
|
||||
return ticks.AsDouble() / hsTimer::GetRawBase().AsDouble();
|
||||
}
|
||||
|
||||
|
||||
inline hsWide* plTimerShare::FactorInTimeZero(hsWide* ticks) const
|
||||
{
|
||||
if( fFirstTime )
|
||||
{
|
||||
fFirstTime = false;
|
||||
fRawTimeZero = *ticks;
|
||||
ticks->Set(0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ticks->Sub(&fRawTimeZero);
|
||||
}
|
||||
return ticks;
|
||||
}
|
||||
|
||||
double plTimerShare::IncSysSeconds()
|
||||
{
|
||||
if( fRunningFrameTime )
|
||||
{
|
||||
fDelSysSeconds = fFrameTimeInc * fSysTimeScale;
|
||||
fSysSeconds += fDelSysSeconds;
|
||||
|
||||
fResetSmooth = true;
|
||||
}
|
||||
else if( fSmoothingClampSecs >= 0 )
|
||||
{
|
||||
double t = GetSeconds();
|
||||
hsScalar delSys = hsScalar(t - fRealSeconds);
|
||||
fClamping = ( (fTimeClampSecs > 0) && (delSys > fTimeClampSecs) );
|
||||
if (fClamping)
|
||||
{
|
||||
delSys = fTimeClampSecs;
|
||||
}
|
||||
delSys *= fSysTimeScale;
|
||||
if( fDelSysSeconds > 0 && fDelSysSeconds < fSmoothingClampSecs )
|
||||
{
|
||||
const hsScalar kFrac = 0.1f;
|
||||
const hsScalar kOneMinusFrac = 1.f-kFrac;
|
||||
delSys *= kFrac;
|
||||
delSys += fDelSysSeconds * kOneMinusFrac;
|
||||
}
|
||||
if (delSys > 4.0f && delSys < 5.0f)
|
||||
{
|
||||
//got that mysterious bug, (Win2k? certain CPU's?) try again...
|
||||
#if HS_BUILD_FOR_WIN32
|
||||
int count = 10;
|
||||
while( delSys >= fDelSysSeconds * 2 && count > 0 )
|
||||
{
|
||||
fRealSeconds = t;
|
||||
t = GetSeconds();
|
||||
delSys = hsScalar(t - fRealSeconds);
|
||||
count--;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
fDelSysSeconds = delSys;
|
||||
fSysSeconds += fDelSysSeconds;
|
||||
fRealSeconds = t;
|
||||
|
||||
fResetSmooth = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
double t = GetSeconds();
|
||||
plCONST(int) kSmoothBuffUsed(kSmoothBuffLen);
|
||||
|
||||
if( fResetSmooth )
|
||||
{
|
||||
int i;
|
||||
for( i = 0; i < kSmoothBuffUsed; i++ )
|
||||
fSmoothBuff[i] = t;
|
||||
fResetSmooth = false;
|
||||
}
|
||||
|
||||
if( ++fCurrSlot >= kSmoothBuffUsed )
|
||||
fCurrSlot = 0;
|
||||
fSmoothBuff[fCurrSlot] = t;
|
||||
|
||||
double avg = 0;
|
||||
int j;
|
||||
for( j = 0; j < kSmoothBuffUsed; j++ )
|
||||
{
|
||||
avg += fSmoothBuff[j];
|
||||
}
|
||||
avg /= double(kSmoothBuffUsed);
|
||||
|
||||
plCONST(hsScalar) kMaxSmoothable(0.15f);
|
||||
fDelSysSeconds = hsScalar(avg - fRealSeconds) * fSysTimeScale;
|
||||
if( fDelSysSeconds > kMaxSmoothable * fSysTimeScale )
|
||||
{
|
||||
avg = t;
|
||||
fDelSysSeconds = hsScalar(avg - fRealSeconds) * fSysTimeScale;
|
||||
fResetSmooth = true;
|
||||
}
|
||||
fSysSeconds += fDelSysSeconds;
|
||||
fRealSeconds = avg;
|
||||
}
|
||||
return fSysSeconds;
|
||||
}
|
||||
|
||||
void plTimerShare::SetRealTime(hsBool realTime)
|
||||
{
|
||||
fRunningFrameTime = !realTime;
|
||||
if( realTime )
|
||||
{
|
||||
fRealSeconds = GetSeconds();
|
||||
}
|
||||
}
|
||||
|
||||
#if HS_BUILD_FOR_WIN32
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
hsWide* plTimerShare::GetRawTicks(hsWide* ticks) const
|
||||
{
|
||||
LARGE_INTEGER large;
|
||||
|
||||
if (::QueryPerformanceCounter(&large))
|
||||
{
|
||||
ticks->Set(large.HighPart, large.LowPart);
|
||||
}
|
||||
else
|
||||
{
|
||||
ticks->Set(0, ::GetTickCount());
|
||||
}
|
||||
|
||||
return FactorInTimeZero(ticks);
|
||||
}
|
||||
|
||||
hsWide hsTimer::IInitRawBase()
|
||||
{
|
||||
hsWide base;
|
||||
LARGE_INTEGER large;
|
||||
if (::QueryPerformanceFrequency(&large))
|
||||
base.Set(large.HighPart, large.LowPart);
|
||||
else
|
||||
base.Set(0, 1000);
|
||||
|
||||
return base;
|
||||
}
|
||||
|
||||
#elif HS_BUILD_FOR_MAC
|
||||
|
||||
#include <Events.h>
|
||||
#include <DriverServices.h>
|
||||
|
||||
//#define HS_USE_TICKCOUNT
|
||||
hsWide* plTimerShare::GetRawTicks(hsWide* ticks)
|
||||
{
|
||||
#ifndef HS_USE_TICKCOUNT
|
||||
UnsignedWide ns = AbsoluteToNanoseconds(UpTime());
|
||||
ticks->Set(ns.hi, ns.lo);
|
||||
#else
|
||||
ticks->Set(0, TickCount());
|
||||
#endif
|
||||
return FactorInTimeZero(ticks);
|
||||
}
|
||||
|
||||
hsWide plTimerShare::IInitRawBase()
|
||||
{
|
||||
hsWide base;
|
||||
#ifndef HS_USE_TICKCOUNT
|
||||
base.Set(0, 1000000000L);
|
||||
#else
|
||||
base.Set(0, 60);
|
||||
#endif
|
||||
return base;
|
||||
}
|
||||
|
||||
#elif HS_BUILD_FOR_UNIX
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
#define kMicroSecondsUnit 1000000
|
||||
static UInt32 gBaseTime = 0;
|
||||
|
||||
hsWide* plTimerShare::GetRawTicks(hsWide* ticks) const
|
||||
{
|
||||
timeval tv;
|
||||
|
||||
(void)::gettimeofday(&tv, nil);
|
||||
if (gBaseTime == 0)
|
||||
gBaseTime = tv.tv_sec;
|
||||
|
||||
ticks->Mul(tv.tv_sec - gBaseTime, kMicroSecondsUnit)->Add(tv.tv_usec);
|
||||
return ticks;
|
||||
}
|
||||
|
||||
hsWide hsTimer::IInitRawBase()
|
||||
{
|
||||
hsWide base;
|
||||
base.Set(0, kMicroSecondsUnit);
|
||||
return base;
|
||||
}
|
||||
|
||||
|
||||
#elif HS_BUILD_FOR_PS2
|
||||
|
||||
extern unsigned long psTimerGetCount();
|
||||
//#define kTickMul (150000000) // kTickMul/kTickDiv :: 4577.636719
|
||||
#define kTickMul (100000000) // kTickMul/kTickDiv :: 3051.757813 // for debugger
|
||||
#define kTickDiv (256*128)
|
||||
|
||||
|
||||
hsWide* plTimerShare::GetRawTicks(hsWide* ticks)
|
||||
{
|
||||
unsigned long t= psTimerGetCount();
|
||||
ticks->Set( (Int32)(t>>32), (Int32)(t&((1ul<<32)-1)));
|
||||
return ticks;
|
||||
}
|
||||
|
||||
hsWide plTimerShare::IInitRawBase()
|
||||
{
|
||||
hsWide base;
|
||||
base.Set(0, kTickMul/kTickDiv );
|
||||
return base;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
// hsTimer - thin static interface to plTimerShare. Also keeps a couple of
|
||||
// constants.
|
||||
//
|
||||
static plTimerShare staticTimer;
|
||||
plTimerShare* hsTimer::fTimer = &staticTimer; // until overridden.
|
||||
const double hsTimer::fPrecTicksPerSec = hsTimer::GetPrecTicksPerSec();
|
||||
const hsWide hsTimer::fRawBase = hsTimer::IInitRawBase();
|
||||
|
||||
void hsTimer::SetTheTimer(plTimerShare* timer)
|
||||
{
|
||||
fTimer = timer;
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
// Precision timer routines
|
||||
// These remain as statics
|
||||
// since they are stateless
|
||||
// anyway.
|
||||
///////////////////////////
|
||||
|
||||
double hsTimer::GetPrecTicksPerSec()
|
||||
{
|
||||
#if HS_BUILD_FOR_WIN32
|
||||
LARGE_INTEGER freq;
|
||||
if( !QueryPerformanceFrequency(&freq) )
|
||||
{
|
||||
return 1000.f;
|
||||
}
|
||||
return ((double) freq.LowPart);
|
||||
#endif
|
||||
#if HS_BUILD_FOR_MAC
|
||||
return 1000.f;
|
||||
#endif
|
||||
#if HS_BUILD_FOR_PS2
|
||||
return 1000.f;
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
UInt32 hsTimer::GetPrecTickCount()
|
||||
{
|
||||
#if HS_BUILD_FOR_WIN32
|
||||
LARGE_INTEGER ti;
|
||||
if( !QueryPerformanceCounter(&ti) )
|
||||
return GetTickCount();
|
||||
|
||||
return ti.LowPart;
|
||||
#endif
|
||||
#if HS_BUILD_FOR_MACPPC
|
||||
return hsTimer::GetMSeconds();
|
||||
#endif
|
||||
|
||||
#if HS_BUILD_FOR_PS2
|
||||
return hsTimer::GetMSeconds();
|
||||
#endif
|
||||
}
|
||||
UInt32 hsTimer::PrecSecsToTicks(hsScalar secs)
|
||||
{
|
||||
return (UInt32)(((double)secs) * fPrecTicksPerSec);
|
||||
}
|
||||
double hsTimer::PrecTicksToSecs(UInt32 ticks)
|
||||
{
|
||||
return ((double)ticks) / fPrecTicksPerSec;
|
||||
}
|
||||
double hsTimer::PrecTicksToHz(UInt32 ticks)
|
||||
{
|
||||
return fPrecTicksPerSec / ((double)ticks);
|
||||
}
|
||||
|
||||
UInt64 hsTimer::GetFullTickCount()
|
||||
{
|
||||
#if HS_BUILD_FOR_WIN32
|
||||
LARGE_INTEGER ticks;
|
||||
QueryPerformanceCounter(&ticks);
|
||||
return ticks.QuadPart;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
float hsTimer::FullTicksToMs(UInt64 ticks)
|
||||
{
|
||||
#ifdef HS_BUILD_FOR_WIN32
|
||||
static UInt64 ticksPerTenthMs = 0;
|
||||
|
||||
if (ticksPerTenthMs == 0)
|
||||
{
|
||||
LARGE_INTEGER perfFreq;
|
||||
QueryPerformanceFrequency(&perfFreq);
|
||||
ticksPerTenthMs = perfFreq.QuadPart / 10000;
|
||||
}
|
||||
|
||||
return float(ticks / ticksPerTenthMs) / 10.f;
|
||||
#else
|
||||
return 0.f;
|
||||
#endif
|
||||
}
|
Reference in New Issue
Block a user