diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/external_dependencies/openmpt-trunk/common/mptTime.cpp | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/external_dependencies/openmpt-trunk/common/mptTime.cpp')
-rw-r--r-- | Src/external_dependencies/openmpt-trunk/common/mptTime.cpp | 307 |
1 files changed, 307 insertions, 0 deletions
diff --git a/Src/external_dependencies/openmpt-trunk/common/mptTime.cpp b/Src/external_dependencies/openmpt-trunk/common/mptTime.cpp new file mode 100644 index 00000000..70874d16 --- /dev/null +++ b/Src/external_dependencies/openmpt-trunk/common/mptTime.cpp @@ -0,0 +1,307 @@ +/* + * mptTime.cpp + * ----------- + * Purpose: Various time utility functions. + * Notes : (currently none) + * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + + +#include "stdafx.h" +#include "mptTime.h" + +#include "mptStringBuffer.h" + +#include <time.h> + +#if MPT_OS_WINDOWS +#include <windows.h> +#if defined(MODPLUG_TRACKER) +#include <mmsystem.h> +#endif +#endif + + +OPENMPT_NAMESPACE_BEGIN + + +namespace mpt +{ +namespace Date +{ + +#if defined(MODPLUG_TRACKER) + +#if MPT_OS_WINDOWS + +namespace ANSI +{ + +uint64 Now() +{ + FILETIME filetime; + GetSystemTimeAsFileTime(&filetime); + return ((uint64)filetime.dwHighDateTime << 32 | filetime.dwLowDateTime); +} + +mpt::ustring ToUString(uint64 time100ns) +{ + constexpr std::size_t bufsize = 256; + + mpt::ustring result; + + FILETIME filetime; + SYSTEMTIME systime; + filetime.dwHighDateTime = (DWORD)(((uint64)time100ns) >> 32); + filetime.dwLowDateTime = (DWORD)((uint64)time100ns); + FileTimeToSystemTime(&filetime, &systime); + + TCHAR buf[bufsize]; + + GetDateFormat(LOCALE_SYSTEM_DEFAULT, 0, &systime, TEXT("yyyy-MM-dd"), buf, bufsize); + result.append(mpt::ToUnicode(mpt::String::ReadWinBuf(buf))); + + result.append(U_(" ")); + + GetTimeFormat(LOCALE_SYSTEM_DEFAULT, TIME_FORCE24HOURFORMAT, &systime, TEXT("HH:mm:ss"), buf, bufsize); + result.append(mpt::ToUnicode(mpt::String::ReadWinBuf(buf))); + + result.append(U_(".")); + + result.append(mpt::ufmt::dec0<3>((unsigned)systime.wMilliseconds)); + + return result; + +} + +} // namespace ANSI + +#endif // MPT_OS_WINDOWS + +#endif // MODPLUG_TRACKER + +Unix::Unix() + : Value(0) +{ + return; +} + +Unix::Unix(int64 unixtime) + : Value(unixtime) +{ + return; +} + +Unix::operator int64 () const +{ + return Value; +} + +static int32 ToDaynum(int32 year, int32 month, int32 day) +{ + month = (month + 9) % 12; + year = year - (month / 10); + int32 daynum = year*365 + year/4 - year/100 + year/400 + (month*306 + 5)/10 + (day - 1); + return daynum; +} + +static void FromDaynum(int32 d, int32 & year, int32 & month, int32 & day) +{ + int64 g = d; + int64 y,ddd,mi,mm,dd; + + y = (10000*g + 14780)/3652425; + ddd = g - (365*y + y/4 - y/100 + y/400); + if(ddd < 0) + { + y = y - 1; + ddd = g - (365*y + y/4 - y/100 + y/400); + } + mi = (100*ddd + 52)/3060; + mm = (mi + 2)%12 + 1; + y = y + (mi + 2)/12; + dd = ddd - (mi*306 + 5)/10 + 1; + + year = static_cast<int32>(y); + month = static_cast<int32>(mm); + day = static_cast<int32>(dd); +} + +mpt::Date::Unix Unix::FromUTC(tm timeUtc) +{ + int32 daynum = ToDaynum(timeUtc.tm_year+1900, timeUtc.tm_mon+1, timeUtc.tm_mday); + int64 seconds = static_cast<int64>(daynum - ToDaynum(1970,1,1))*24*60*60 + timeUtc.tm_hour*60*60 + timeUtc.tm_min*60 + timeUtc.tm_sec; + return mpt::Date::Unix(seconds); +} + +tm Unix::AsUTC() const +{ + int64 tmp = Value; + int64 seconds = tmp % 60; tmp /= 60; + int64 minutes = tmp % 60; tmp /= 60; + int64 hours = tmp % 24; tmp /= 24; + int32 year = 0, month = 0, day = 0; + FromDaynum(static_cast<int32>(tmp) + ToDaynum(1970,1,1), year, month, day); + tm result = {}; + result.tm_year = year - 1900; + result.tm_mon = month - 1; + result.tm_mday = day; + result.tm_hour = static_cast<int32>(hours); + result.tm_min = static_cast<int32>(minutes); + result.tm_sec = static_cast<int32>(seconds); + return result; +} + +mpt::ustring ToShortenedISO8601(tm date) +{ + // We assume date in UTC here. + // There are too many differences in supported format specifiers in strftime() + // and strftime does not support reduced precision ISO8601 at all. + // Just do the formatting ourselves. + mpt::ustring result; + mpt::ustring tz = U_("Z"); + if(date.tm_year == 0) + { + return result; + } + result += mpt::ufmt::dec0<4>(date.tm_year + 1900); + if(date.tm_mon < 0 || date.tm_mon > 11) + { + return result; + } + result += U_("-") + mpt::ufmt::dec0<2>(date.tm_mon + 1); + if(date.tm_mday < 1 || date.tm_mday > 31) + { + return result; + } + result += U_("-") + mpt::ufmt::dec0<2>(date.tm_mday); + if(date.tm_hour == 0 && date.tm_min == 0 && date.tm_sec == 0) + { + return result; + } + if(date.tm_hour < 0 || date.tm_hour > 23) + { + return result; + } + if(date.tm_min < 0 || date.tm_min > 59) + { + return result; + } + result += U_("T"); + if(date.tm_isdst > 0) + { + tz = U_("+01:00"); + } + result += mpt::ufmt::dec0<2>(date.tm_hour) + U_(":") + mpt::ufmt::dec0<2>(date.tm_min); + if(date.tm_sec < 0 || date.tm_sec > 61) + { + return result + tz; + } + result += U_(":") + mpt::ufmt::dec0<2>(date.tm_sec); + result += tz; + return result; +} + +} // namespace Date +} // namespace mpt + + + +#ifdef MODPLUG_TRACKER + +namespace Util +{ + +#if MPT_OS_WINDOWS + +void MultimediaClock::Init() +{ + m_CurrentPeriod = 0; +} + +void MultimediaClock::SetPeriod(uint32 ms) +{ + TIMECAPS caps = {}; + if(timeGetDevCaps(&caps, sizeof(caps)) != MMSYSERR_NOERROR) + { + return; + } + if((caps.wPeriodMax == 0) || (caps.wPeriodMin > caps.wPeriodMax)) + { + return; + } + ms = std::clamp(mpt::saturate_cast<UINT>(ms), caps.wPeriodMin, caps.wPeriodMax); + if(timeBeginPeriod(ms) != MMSYSERR_NOERROR) + { + return; + } + m_CurrentPeriod = ms; +} + +void MultimediaClock::Cleanup() +{ + if(m_CurrentPeriod > 0) + { + if(timeEndPeriod(m_CurrentPeriod) != MMSYSERR_NOERROR) + { + // should not happen + MPT_ASSERT_NOTREACHED(); + } + m_CurrentPeriod = 0; + } +} + +MultimediaClock::MultimediaClock() +{ + Init(); +} + +MultimediaClock::MultimediaClock(uint32 ms) +{ + Init(); + SetResolution(ms); +} + +MultimediaClock::~MultimediaClock() +{ + Cleanup(); +} + +uint32 MultimediaClock::SetResolution(uint32 ms) +{ + if(m_CurrentPeriod == ms) + { + return m_CurrentPeriod; + } + Cleanup(); + if(ms != 0) + { + SetPeriod(ms); + } + return GetResolution(); +} + +uint32 MultimediaClock::GetResolution() const +{ + return m_CurrentPeriod; +} + +uint32 MultimediaClock::Now() const +{ + return timeGetTime(); +} + +uint64 MultimediaClock::NowNanoseconds() const +{ + return (uint64)timeGetTime() * (uint64)1000000; +} + +#endif // MPT_OS_WINDOWS + +} // namespace Util + +#endif // MODPLUG_TRACKER + + +OPENMPT_NAMESPACE_END |