timemgr.cpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. /*
  2. ** Command & Conquer Renegade(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /***********************************************************************************************
  19. *** Confidential - Westwood Studios ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : Commando *
  23. * *
  24. * $Archive:: /Commando/Code/Combat/timemgr.cpp $*
  25. * *
  26. * $Author:: Jani_p $*
  27. * *
  28. * $Modtime:: 3/14/02 11:29a $*
  29. * *
  30. * $Revision:: 64 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #include "timemgr.h"
  36. #include "always.h"
  37. #include "ww3d.h"
  38. #include "debug.h"
  39. #include "slist.h"
  40. #include "input.h"
  41. #include "combat.h"
  42. #include "ccamera.h"
  43. #include "chunkio.h"
  44. #include "persistfactory.h"
  45. #include "combatchunkid.h"
  46. #include "wwprofile.h"
  47. #include "win.h"
  48. //#include "systimer.h" // for timegettime
  49. #include "systimer.h"
  50. /*
  51. **
  52. */
  53. int TimeManager::FrameTicks = 0;
  54. int TimeManager::RealFrameTicks = 0;
  55. int TimeManager::LastTicks = 0;
  56. float TimeManager::TimeScale = 1.0f;
  57. float TimeManager::TotalSeconds = 0;
  58. float TimeManager::AveragedFPS = 0.0f;
  59. int TimeManager::AveragedFPSTicks = 0;
  60. int TimeManager::AveragedFPSCounter = 0;
  61. float TimeManager::FrameSeconds = 0.0f;
  62. float TimeManager::RealFrameSeconds = 0.0f;
  63. #define TIME_STABILIZING_TECHNOLOGY_ENABLED 0
  64. #define TIME_DESTABILIZING_TECHNOLOGY_ENABLED 0
  65. #define SLOWEST_FPS 5
  66. FrameTimeHistogramClass::FrameTimeHistogramClass(unsigned slot_count, float step)
  67. :
  68. SlotCount(slot_count),
  69. Step(step)
  70. {
  71. Counts=new unsigned[SlotCount];
  72. Reset();
  73. }
  74. FrameTimeHistogramClass::~FrameTimeHistogramClass()
  75. {
  76. delete[] Counts;
  77. }
  78. // Report normalized counts for each frame time slot, packed to unsigned bytes.
  79. void FrameTimeHistogramClass::Get_Packed_Report(unsigned char* bytes)
  80. {
  81. unsigned total=0;
  82. unsigned i;
  83. for (i=0;i<SlotCount;++i) {
  84. total+=Counts[i];
  85. }
  86. if (total==0) total=1;
  87. for (i=0;i<SlotCount;++i) {
  88. unsigned char value=255*Counts[i]/total;
  89. if (value==0 && Counts[i]!=0) value=1;
  90. bytes[i]=value;
  91. }
  92. }
  93. // Report the absolute counts for each frame time slot
  94. void FrameTimeHistogramClass::Get_Report(unsigned* counts)
  95. {
  96. unsigned i;
  97. for (i=0;i<SlotCount;++i) {
  98. counts[i]=Counts[i];
  99. }
  100. }
  101. // Reset the counts.
  102. void FrameTimeHistogramClass::Reset()
  103. {
  104. for (unsigned i=0;i<SlotCount;++i) {
  105. Counts[i]=0;
  106. }
  107. }
  108. // Place the time of current frame to a correct slot.
  109. void FrameTimeHistogramClass::Add(float frame_time)
  110. {
  111. unsigned long slot=WWMath::Float_To_Long(frame_time*(1000.0f/Step));
  112. if (slot>=SlotCount) slot=SlotCount-1;
  113. Counts[slot]++;
  114. }
  115. FrameTimeHistogramClass FrameTimeHistogram(16,15.0f);
  116. FrameTimeHistogramClass& TimeManager::Peek_Frame_Time_Histogram()
  117. {
  118. return FrameTimeHistogram;
  119. }
  120. /*
  121. **
  122. */
  123. int TimeManager::SystemTicks()
  124. {
  125. return TIMEGETTIME();
  126. }
  127. void TimeManager::Reset(void)
  128. {
  129. FrameTicks = 0;
  130. RealFrameTicks = 0;
  131. LastTicks = 0;
  132. TimeScale = 1.0f;
  133. TotalSeconds = 0;
  134. AveragedFPS = 0.0f;
  135. AveragedFPSTicks = 0;
  136. AveragedFPSCounter = 0;
  137. FrameSeconds = 0.0f;
  138. RealFrameSeconds = 0.0f;
  139. }
  140. /*
  141. **
  142. */
  143. void TimeManager::Update_Frame_Time()
  144. {
  145. int ticks = SystemTicks();
  146. if ( LastTicks == 0) { // sync first time
  147. LastTicks = ticks;
  148. }
  149. FrameTicks = ticks - LastTicks;
  150. RealFrameTicks = ticks - LastTicks;
  151. LastTicks = ticks;
  152. FrameTicks = MIN( FrameTicks, (TICKS_PER_SECOND / SLOWEST_FPS) );
  153. if ( WW3D::Get_Movie_Capture_Frame_Rate() != 0.0f ) {
  154. FrameTicks = TICKS_PER_SECOND / WW3D::Get_Movie_Capture_Frame_Rate();
  155. }
  156. #if TIME_STABILIZING_TECHNOLOGY_ENABLED
  157. FrameTicks = TICKS_PER_SECOND / 30;
  158. #endif
  159. #if TIME_DESTABILIZING_TECHNOLOGY_ENABLED
  160. static int state = 0;
  161. FrameTicks = TICKS_PER_SECOND / 15;
  162. if ( ++state & 0x2 ) {
  163. FrameTicks = TICKS_PER_SECOND / 30;
  164. }
  165. #endif
  166. // Single Step
  167. static bool single_step = false;
  168. #ifdef WWDEBUG
  169. if ( Input::Get_State( INPUT_FUNCTION_DEBUG_SINGLE_STEP ) ) {
  170. single_step = !single_step;
  171. Debug_Say(( "Single_Step %s\n", single_step ? "ON" : "OFF" ));
  172. }
  173. if ( single_step ) {
  174. // Wait_Seconds( 0.2 );
  175. FrameTicks = 0;
  176. if ( Input::Get_State( INPUT_FUNCTION_DEBUG_SINGLE_STEP_STEP ) ) {
  177. Debug_Say(( "Single_Step STEP!!\n" ));
  178. FrameTicks = TICKS_PER_SECOND / 15;
  179. }
  180. }
  181. #endif
  182. if ( COMBAT_CAMERA && COMBAT_CAMERA->Is_Snap_Shot_Mode() ) {
  183. FrameTicks = 0;
  184. }
  185. if ( CombatManager::Is_Game_Paused() ) {
  186. FrameTicks = 0;
  187. }
  188. FrameTicks *= TimeScale;
  189. FrameSeconds=(float)FrameTicks / TICKS_PER_SECOND;
  190. RealFrameSeconds=(float)RealFrameTicks / TICKS_PER_SECOND;
  191. WW3D::Sync( WW3D::Get_Sync_Time() + FrameTicks );
  192. /*
  193. #if 0
  194. // testing animation smoothing
  195. if (!WWDEBUG_TRIGGER(WWDEBUG_TRIGGER_GENERIC0) ) {
  196. static int rlticks = 0;
  197. if (rlticks == 0) {
  198. rlticks = ticks;
  199. }
  200. int rtime = ticks - rlticks;
  201. //float amount = (float)rtime / (3.0f*1000.0f);
  202. //Debug_Say(( "Time %d %f\n", rtime, amount ));
  203. if (rtime < 200) {
  204. // Wait_Seconds( amount );
  205. }
  206. rlticks = SystemTicks();
  207. }
  208. #endif
  209. #if 0
  210. //if ( IS_SOLOPLAY && Input::Get_State( INPUT_FUNCTION_DEBUG_RAPID_MOVE ) ) {
  211. if ( Input::Get_State( INPUT_FUNCTION_DEBUG_RAPID_MOVE ) ) {
  212. if ( COMBAT_CAMERA->Is_Using_Host_Model() ) {
  213. FrameTicks *= 10;
  214. // FrameTicks /= 5;
  215. }
  216. }
  217. #endif
  218. #if 0
  219. if (FrameTicks == 0) {
  220. // WWDEBUG_SAY(("Frame Ticks was ZERO!\n"));
  221. FrameTicks = 1;
  222. }
  223. #endif
  224. */
  225. TotalSeconds += Get_Frame_Seconds();
  226. /*
  227. ** Time averaged fps (averaged over 10 seconds)
  228. */
  229. AveragedFPSTicks += RealFrameTicks;
  230. AveragedFPSCounter++;
  231. if ( AveragedFPSTicks >= 10 * TICKS_PER_SECOND ) {
  232. AveragedFPS = (float)AveragedFPSCounter / ((float)AveragedFPSTicks / (float)TICKS_PER_SECOND);
  233. AveragedFPSTicks = AveragedFPSCounter = 0;
  234. }
  235. FrameTimeHistogram.Add(FrameSeconds);
  236. }
  237. void TimeManager::Wait_Seconds( float time )
  238. {
  239. float end = Get_Seconds() + time;
  240. while ( Get_Seconds() < end );
  241. }
  242. /***********************************************************************************************
  243. * TimeManager::Update( void ) - updates all current timers by the frame time
  244. * *
  245. * INPUT:
  246. * *
  247. * OUTPUT:
  248. * *
  249. * WARNINGS: None *
  250. * *
  251. * HISTORY: *
  252. * 09/01/1997 BG : Created. *
  253. *=============================================================================================*/
  254. void TimeManager::Update( void )
  255. {
  256. Update_Frame_Time();
  257. // tell the profiling code that another frame has gone by
  258. WWProfileManager::Increment_Frame_Counter();
  259. #ifdef WWDEBUG
  260. //
  261. // TSS101401
  262. // Watch out for unexpected slow frames. They may interrupt networking.
  263. //
  264. if (Get_Frame_Real_Seconds() > 2) {
  265. Debug_Say(("TimeManager::Update: warning, frame %d was slow (%d ms)\n",
  266. WWProfileManager::Get_Frame_Count_Since_Reset(),
  267. (int)(1000 * Get_Frame_Real_Seconds())));
  268. }
  269. #endif // WWDEBUG
  270. }