Seaside/SpyCustom/sdk/timeutils.h
2021-06-16 18:48:15 +03:00

149 lines
5.5 KiB
C++

#ifndef TIMEUTILS_H
#define TIMEUTILS_H
#ifdef _WIN32
#pragma once
#endif
#include <limits.h>
#include <math.h>
#include "dbg.h"
enum RoundStyle_t
{
ROUND_NEAREST,
ROUND_DOWN,
ROUND_UP,
};
class DmeTime_t;
class DmeFramerate_t
{
public:
DmeFramerate_t(float fps);
DmeFramerate_t(int fps = 0);
DmeFramerate_t(const DmeFramerate_t& src) : m_num(src.m_num), m_den(src.m_den) {}
void SetFramerate(float flFrameRate);
void SetFramerate(int fps);
void SetFramerateNTSC(int multiplier = 30);
float GetFramesPerSecond() const;
DmeTime_t GetTimePerFrame() const;
bool operator==(DmeFramerate_t f) const { return m_num == f.m_num && m_den == f.m_den; }
bool operator!=(DmeFramerate_t f) const { return m_num != f.m_num && m_den != f.m_den; }
bool operator< (DmeFramerate_t f) const { return m_num * (int)f.m_den < f.m_num* (int)m_den; }
bool operator> (DmeFramerate_t f) const { return m_num * (int)f.m_den > f.m_num * (int)m_den; }
bool operator<=(DmeFramerate_t f) const { return m_num * (int)f.m_den <= f.m_num * (int)m_den; }
bool operator>=(DmeFramerate_t f) const { return m_num * (int)f.m_den >= f.m_num * (int)m_den; }
DmeFramerate_t operator*(int i) const { return DmeFramerate_t(m_num * i, m_den); }
DmeFramerate_t operator/(int i) const { return DmeFramerate_t(m_num, m_den * i); }
DmeFramerate_t operator*=(int i) { Assert(abs(m_num * i) <= USHRT_MAX); m_num *= (unsigned short)i; return *this; }
DmeFramerate_t operator/=(int i) { Assert(abs(m_den * i) <= USHRT_MAX); m_den *= (unsigned short)i; return *this; }
private:
DmeFramerate_t(int nNumerator, int nDenominator);
unsigned short m_num;
unsigned short m_den;
friend class DmeTime_t;
};
#define DMETIME_ZERO DmeTime_t(0)
#define DMETIME_MINDELTA DmeTime_t::MinTimeDelta()
#define DMETIME_MINTIME DmeTime_t::MinTime()
#define DMETIME_MAXTIME DmeTime_t::MaxTime()
#define DMETIME_INVALID DmeTime_t::InvalidTime()
class DmeTime_t
{
public:
DmeTime_t() : m_tms(INT_MIN) {}
explicit DmeTime_t(int tms) : m_tms(tms) {}
explicit DmeTime_t(float sec) : m_tms(RoundSecondsToTMS(sec)) {}
explicit DmeTime_t(double sec) : m_tms(RoundSecondsToTMS(sec)) {}
DmeTime_t(int frame, DmeFramerate_t framerate);
friend bool operator==(DmeTime_t a, DmeTime_t b) { return a.m_tms == b.m_tms; }
friend bool operator!=(DmeTime_t a, DmeTime_t b) { return a.m_tms != b.m_tms; }
friend bool operator< (DmeTime_t a, DmeTime_t b) { return a.m_tms < b.m_tms; }
friend bool operator> (DmeTime_t a, DmeTime_t b) { return a.m_tms > b.m_tms; }
friend bool operator<=(DmeTime_t a, DmeTime_t b) { return a.m_tms <= b.m_tms; }
friend bool operator>=(DmeTime_t a, DmeTime_t b) { return a.m_tms >= b.m_tms; }
friend DmeTime_t operator%(DmeTime_t a, DmeTime_t b) { return DmeTime_t(a.m_tms % b.m_tms); }
friend DmeTime_t operator+(DmeTime_t a, DmeTime_t b) { return DmeTime_t(a.m_tms + b.m_tms); }
friend DmeTime_t operator-(DmeTime_t a, DmeTime_t b) { return DmeTime_t(a.m_tms - b.m_tms); }
DmeTime_t operator-() const { return DmeTime_t(-m_tms); }
DmeTime_t operator+=(DmeTime_t t) { m_tms += t.m_tms; return *this; }
DmeTime_t operator-=(DmeTime_t t) { m_tms -= t.m_tms; return *this; }
friend DmeTime_t operator*(DmeTime_t t, float f) { t *= f; return t; }
friend DmeTime_t operator*(float f, DmeTime_t t) { t *= f; return t; }
friend DmeTime_t operator/(DmeTime_t t, float f) { t /= f; return t; }
friend float operator/(DmeTime_t n, DmeTime_t d) { return float(n.m_tms / double(d.m_tms)); }
DmeTime_t operator*=(float f);
DmeTime_t operator/=(float f);
DmeTime_t operator++() { ++m_tms; return *this; }
DmeTime_t operator--() { --m_tms; return *this; }
DmeTime_t operator++(int) { DmeTime_t t = *this; ++m_tms; return t; }
DmeTime_t operator--(int) { DmeTime_t t = *this; --m_tms; return t; }
bool IsValid() const { return m_tms != INT_MIN; }
static DmeTime_t InvalidTime() { return DmeTime_t(INT_MIN); }
static DmeTime_t MinTime() { return DmeTime_t(INT_MIN + 1); }
static DmeTime_t MaxTime() { return DmeTime_t(INT_MAX); }
static DmeTime_t MinTimeDelta() { return DmeTime_t(1); }
int GetTenthsOfMS() const { return m_tms; }
float GetSeconds() const { return m_tms * 0.0001f; }
void SetTenthsOfMS(int tms) { m_tms = tms; }
void SetSeconds(float sec) { m_tms = RoundSecondsToTMS(sec); }
void Clamp(DmeTime_t lo, DmeTime_t hi);
bool IsInRange(DmeTime_t lo, DmeTime_t hi) const;
friend float GetFractionOfTimeBetween(DmeTime_t t, DmeTime_t start, DmeTime_t end, bool bClamp);
friend float GetFractionOfTime(DmeTime_t t, DmeTime_t duration, bool bClamp);
friend int FrameForTime(DmeTime_t t, DmeFramerate_t framerate);
friend DmeTime_t abs(DmeTime_t t) { return t.m_tms >= 0 ? t : -t; }
int CurrentFrame(DmeFramerate_t framerate, RoundStyle_t roundStyle = ROUND_DOWN) const;
DmeTime_t TimeAtCurrentFrame(DmeFramerate_t framerate, RoundStyle_t roundStyle = ROUND_DOWN) const;
DmeTime_t TimeAtNextFrame(DmeFramerate_t framerate) const;
DmeTime_t TimeAtPrevFrame(DmeFramerate_t framerate) const;
private:
explicit DmeTime_t(int64 tms) : m_tms(int(tms)) {}
static int RoundSecondsToTMS(float sec);
static int RoundSecondsToTMS(double sec);
int m_tms;
};
float GetFractionOfTimeBetween(DmeTime_t t, DmeTime_t start, DmeTime_t end, bool bClamp = false);
float GetFractionOfTime(DmeTime_t t, DmeTime_t duration, bool bClamp = false);
class CUtlBuffer;
bool Serialize(CUtlBuffer& buf, const DmeTime_t& src);
bool Unserialize(CUtlBuffer& buf, DmeTime_t& dest);
#endif