Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

274 lines
7.3 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. //=======================================================================================//
  4. #include "replay/replaytime.h"
  5. #include "KeyValues.h"
  6. #include <time.h>
  7. // memdbgon must be the last include file in a .cpp file!!!
  8. #include "tier0/memdbgon.h"
  9. //----------------------------------------------------------------------------------------
  10. CReplayTime::CReplayTime()
  11. : m_fDate( 0 ),
  12. m_fTime( 0 )
  13. {
  14. }
  15. void CReplayTime::InitDateAndTimeToNow()
  16. {
  17. tm now;
  18. VCRHook_LocalTime( &now );
  19. SetDate( now.tm_mday, now.tm_mon + 1, now.tm_year + 1900 );
  20. SetTime( now.tm_hour, now.tm_min, now.tm_sec );
  21. }
  22. void CReplayTime::SetDate( int nDay, int nMonth, int nYear )
  23. {
  24. Assert( nDay >= 1 && nDay <= 31 );
  25. Assert( nMonth >= 1 && nMonth <= 12 );
  26. Assert( nYear >= 2009 && nYear <= 2136 );
  27. m_fDate = nDay - 1;
  28. m_fDate |= ( ( nMonth - 1 ) << 5 );
  29. m_fDate |= ( ( nYear - 2009 ) << 9 );
  30. #ifdef _DEBUG
  31. int nDbgDay, nDbgMonth, nDbgYear;
  32. GetDate( nDbgDay, nDbgMonth, nDbgYear );
  33. Assert( nDay == nDbgDay );
  34. Assert( nMonth == nDbgMonth );
  35. Assert( nYear == nDbgYear );
  36. #endif
  37. }
  38. void CReplayTime::GetDate( int &nDay, int &nMonth, int &nYear ) const
  39. {
  40. nDay = 1 + ( m_fDate & 0x1F ); // Bits 0-4 for day
  41. nMonth = 1 + ( ( m_fDate >> 5 ) & 0x0F ); // Bits 5-8 for month
  42. nYear = 2009 + ( ( m_fDate >> 9 ) & 0x7F ); // Bits 9-15 for year
  43. Assert( nDay >= 1 && nDay <= 31 );
  44. Assert( nMonth >= 1 && nMonth <= 12 );
  45. Assert( nYear >= 2009 && nYear <= 2136 );
  46. }
  47. void CReplayTime::SetTime( int nHour, int nMin, int nSec )
  48. {
  49. Assert( nHour >= 0 && nHour <= 23 );
  50. Assert( nMin >= 0 && nMin <= 59 );
  51. Assert( nSec >= 0 && nSec <= 59 );
  52. m_fTime = nHour;
  53. m_fTime |= ( ( nMin ) << 5 );
  54. m_fTime |= ( ( nSec ) << 11 );
  55. #ifdef _DEBUG
  56. int nDbgHour, nDbgMin, nDbgSec;
  57. GetTime( nDbgHour, nDbgMin, nDbgSec );
  58. Assert( nHour == nDbgHour );
  59. Assert( nMin == nDbgMin );
  60. Assert( nSec == nDbgSec );
  61. #endif
  62. }
  63. void CReplayTime::GetTime( int &nHour, int &nMin, int &nSec ) const
  64. {
  65. nHour = m_fTime & 0x1F; // Bits 0-4 for hour
  66. nMin = ( m_fTime >> 5 ) & 0x3F; // Bits 5-10 for min
  67. nSec = ( m_fTime >> 11 ) & 0x3F; // Bits 11-16 for sec
  68. Assert( nHour >= 0 && nHour <= 23 );
  69. Assert( nMin >= 0 && nMin <= 59 );
  70. Assert( nSec >= 0 && nSec <= 59 );
  71. }
  72. void CReplayTime::Read( KeyValues *pIn )
  73. {
  74. m_fDate = pIn->GetInt( "date" );
  75. m_fTime = pIn->GetInt( "time" );
  76. }
  77. void CReplayTime::Write( KeyValues *pOut )
  78. {
  79. pOut->SetInt( "date", m_fDate );
  80. pOut->SetInt( "time", m_fTime );
  81. }
  82. /*static*/ const wchar_t *CReplayTime::GetLocalizedMonth( vgui::ILocalize *pLocalize, int nMonth )
  83. {
  84. char szMonthKey[32]; // Get localized month
  85. V_snprintf( szMonthKey, sizeof( szMonthKey ), "#Month_%i", nMonth );
  86. wchar_t *pResult = pLocalize->Find( szMonthKey );
  87. return pResult ? pResult : L"";
  88. }
  89. /*static*/ const wchar_t *CReplayTime::GetLocalizedDay( vgui::ILocalize *pLocalize, int nDay )
  90. {
  91. char szDay[8]; // Convert day to wide
  92. static wchar_t s_wDay[8];
  93. V_snprintf( szDay, sizeof( szDay ), "%i", nDay );
  94. pLocalize->ConvertANSIToUnicode( szDay, s_wDay, sizeof( s_wDay ) );
  95. return s_wDay;
  96. }
  97. /*static*/ const wchar_t *CReplayTime::GetLocalizedYear( vgui::ILocalize *pLocalize, int nYear )
  98. {
  99. char szYear[8]; // Convert year to wide
  100. static wchar_t s_wYear[8];
  101. V_snprintf( szYear, sizeof( szYear ), "%i", nYear );
  102. pLocalize->ConvertANSIToUnicode( szYear, s_wYear, sizeof( s_wYear ) );
  103. return s_wYear;
  104. }
  105. /*static*/ const wchar_t *CReplayTime::GetLocalizedTime( vgui::ILocalize *pLocalize, int nHour, int nMin, int nSec )
  106. {
  107. char szTime[16]; // Convert time to wide
  108. static wchar_t s_wTime[16];
  109. V_snprintf( szTime, sizeof( szTime ), "%i:%02i %s", nHour % 12, nMin, nHour < 12 ? "AM" : "PM" );
  110. pLocalize->ConvertANSIToUnicode( szTime, s_wTime, sizeof( s_wTime ) );
  111. return s_wTime;
  112. }
  113. /*static*/ const wchar_t *CReplayTime::GetLocalizedDate( vgui::ILocalize *pLocalize, const CReplayTime &t,
  114. bool bForceFullFormat/*=false*/ )
  115. {
  116. int nHour, nMin, nSec;
  117. int nDay, nMonth, nYear;
  118. t.GetTime( nHour, nMin, nSec );
  119. t.GetDate( nDay, nMonth, nYear );
  120. return GetLocalizedDate( pLocalize, nDay, nMonth, nYear, &nHour, &nMin, &nSec, bForceFullFormat );
  121. }
  122. /*static*/ const wchar_t *CReplayTime::GetLocalizedDate( vgui::ILocalize *pLocalize, int nDay, int nMonth, int nYear,
  123. int *pHour/*=NULL*/, int *pMin/*=NULL*/, int *pSec/*=NULL*/,
  124. bool bForceFullFormat/*=false*/ )
  125. {
  126. static wchar_t s_wBuf[256];
  127. // Is this collection for replays from today?
  128. time_t today;
  129. time( &today );
  130. tm *pNowTime = localtime( &today );
  131. bool bToday = ( pNowTime->tm_mday == nDay ) && ( pNowTime->tm_mon + 1 == nMonth ) && ( 1900 + pNowTime->tm_year == nYear );
  132. // Yesterday?
  133. time_t yesterday = today - time_t( 86400 );
  134. tm *pYesterdayTime = localtime( &yesterday );
  135. bool bYesterday = ( pYesterdayTime->tm_mday == nDay ) && ( pYesterdayTime->tm_mon + 1 == nMonth ) && ( 1900 + pYesterdayTime->tm_year == nYear );
  136. const wchar_t *pMonth = GetLocalizedMonth( pLocalize, nMonth );
  137. const wchar_t *pDay = GetLocalizedDay( pLocalize, nDay );
  138. const wchar_t *pYear = GetLocalizedYear( pLocalize, nYear );
  139. const wchar_t *pToday = pLocalize->Find( "#Replay_Today" );
  140. const wchar_t *pYesterday = pLocalize->Find( "#Replay_Yesterday" );
  141. bool bTime = pHour && pMin && pSec;
  142. // Include time in formatted string?
  143. if ( bTime )
  144. {
  145. const wchar_t *pTime = GetLocalizedTime( pLocalize, *pHour, *pMin, *pSec );
  146. if ( bForceFullFormat || ( !bToday && !bYesterday ) )
  147. {
  148. pLocalize->ConstructString(
  149. s_wBuf,
  150. sizeof( s_wBuf ),
  151. pLocalize->Find( "#Replay_DateAndTime" ),
  152. 4,
  153. pMonth, pDay, pYear, pTime
  154. );
  155. }
  156. else
  157. {
  158. pLocalize->ConstructString(
  159. s_wBuf,
  160. sizeof( s_wBuf ),
  161. pLocalize->Find( "#Replay_SingleWordDateAndTime" ),
  162. 2,
  163. bToday ? pToday : pYesterday,
  164. pTime
  165. );
  166. }
  167. }
  168. else
  169. {
  170. if ( !bToday && !bYesterday )
  171. {
  172. pLocalize->ConstructString(
  173. s_wBuf,
  174. sizeof( s_wBuf ),
  175. pLocalize->Find( "#Replay_Date" ),
  176. 3,
  177. pMonth, pDay, pYear
  178. );
  179. }
  180. else
  181. {
  182. V_wcsncpy( s_wBuf, bToday ? pToday : pYesterday, sizeof( s_wBuf ) );
  183. }
  184. }
  185. return s_wBuf;
  186. }
  187. /*static*/ const char *CReplayTime::FormatTimeString( int nSecs )
  188. {
  189. static int nWhichStr = 0;
  190. static const int nNumStrings = 2;
  191. static const int nStrLen = 32;
  192. static char s_szResult[nNumStrings][nStrLen];
  193. char *pResult = s_szResult[ nWhichStr ];
  194. int nSeconds = nSecs % 60;
  195. int nMins = nSecs / 60;
  196. int nHours = nMins / 60;
  197. nMins %= 60;
  198. if ( nHours > 0 )
  199. {
  200. V_snprintf( pResult, nStrLen, "%i:%02i:%02i", nHours, nMins, nSeconds );
  201. }
  202. else
  203. {
  204. V_snprintf( pResult, nStrLen, "%02i:%02i", nMins, nSeconds );
  205. }
  206. nWhichStr = ( nWhichStr + 1 ) % nNumStrings;
  207. return pResult;
  208. }
  209. /*static*/ const char *CReplayTime::FormatPreciseTimeString( float flSecs )
  210. {
  211. static int nWhichStr = 0;
  212. static const int nNumStrings = 2;
  213. static const int nStrLen = 32;
  214. static char s_szResult[nNumStrings][nStrLen];
  215. char *pResult = s_szResult[ nWhichStr ];
  216. int nSecs = (int)flSecs;
  217. int nMins = ( nSecs % 3600 ) / 60;
  218. int nSeconds = nSecs % 60;
  219. int nMilliseconds = (flSecs - (float)nSecs) * 10.0f;
  220. V_snprintf( pResult, nStrLen, "%02i:%02i:%02i", nMins, nSeconds, nMilliseconds );
  221. nWhichStr = ( nWhichStr + 1 ) % nNumStrings;
  222. return pResult;
  223. }
  224. //----------------------------------------------------------------------------------------