This repository has been archived on 2025-02-27. You can view files and clone it, but cannot push or open issues or pull requests.
CnC_Renegade/Code/Combat/timemgr.cpp

321 lines
8.7 KiB
C++
Raw Permalink Normal View History

/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts 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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Combat/timemgr.cpp $*
* *
* $Author:: Jani_p $*
* *
* $Modtime:: 3/14/02 11:29a $*
* *
* $Revision:: 64 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "timemgr.h"
#include "always.h"
#include "ww3d.h"
#include "debug.h"
#include "slist.h"
#include "input.h"
#include "combat.h"
#include "ccamera.h"
#include "chunkio.h"
#include "persistfactory.h"
#include "combatchunkid.h"
#include "wwprofile.h"
#include "win.h"
//#include "systimer.h" // for timegettime
#include "systimer.h"
/*
**
*/
int TimeManager::FrameTicks = 0;
int TimeManager::RealFrameTicks = 0;
int TimeManager::LastTicks = 0;
float TimeManager::TimeScale = 1.0f;
float TimeManager::TotalSeconds = 0;
float TimeManager::AveragedFPS = 0.0f;
int TimeManager::AveragedFPSTicks = 0;
int TimeManager::AveragedFPSCounter = 0;
float TimeManager::FrameSeconds = 0.0f;
float TimeManager::RealFrameSeconds = 0.0f;
#define TIME_STABILIZING_TECHNOLOGY_ENABLED 0
#define TIME_DESTABILIZING_TECHNOLOGY_ENABLED 0
#define SLOWEST_FPS 5
FrameTimeHistogramClass::FrameTimeHistogramClass(unsigned slot_count, float step)
:
SlotCount(slot_count),
Step(step)
{
Counts=new unsigned[SlotCount];
Reset();
}
FrameTimeHistogramClass::~FrameTimeHistogramClass()
{
delete[] Counts;
}
// Report normalized counts for each frame time slot, packed to unsigned bytes.
void FrameTimeHistogramClass::Get_Packed_Report(unsigned char* bytes)
{
unsigned total=0;
unsigned i;
for (i=0;i<SlotCount;++i) {
total+=Counts[i];
}
if (total==0) total=1;
for (i=0;i<SlotCount;++i) {
unsigned char value=255*Counts[i]/total;
if (value==0 && Counts[i]!=0) value=1;
bytes[i]=value;
}
}
// Report the absolute counts for each frame time slot
void FrameTimeHistogramClass::Get_Report(unsigned* counts)
{
unsigned i;
for (i=0;i<SlotCount;++i) {
counts[i]=Counts[i];
}
}
// Reset the counts.
void FrameTimeHistogramClass::Reset()
{
for (unsigned i=0;i<SlotCount;++i) {
Counts[i]=0;
}
}
// Place the time of current frame to a correct slot.
void FrameTimeHistogramClass::Add(float frame_time)
{
unsigned long slot=WWMath::Float_To_Long(frame_time*(1000.0f/Step));
if (slot>=SlotCount) slot=SlotCount-1;
Counts[slot]++;
}
FrameTimeHistogramClass FrameTimeHistogram(16,15.0f);
FrameTimeHistogramClass& TimeManager::Peek_Frame_Time_Histogram()
{
return FrameTimeHistogram;
}
/*
**
*/
int TimeManager::SystemTicks()
{
return TIMEGETTIME();
}
void TimeManager::Reset(void)
{
FrameTicks = 0;
RealFrameTicks = 0;
LastTicks = 0;
TimeScale = 1.0f;
TotalSeconds = 0;
AveragedFPS = 0.0f;
AveragedFPSTicks = 0;
AveragedFPSCounter = 0;
FrameSeconds = 0.0f;
RealFrameSeconds = 0.0f;
}
/*
**
*/
void TimeManager::Update_Frame_Time()
{
int ticks = SystemTicks();
if ( LastTicks == 0) { // sync first time
LastTicks = ticks;
}
FrameTicks = ticks - LastTicks;
RealFrameTicks = ticks - LastTicks;
LastTicks = ticks;
FrameTicks = MIN( FrameTicks, (TICKS_PER_SECOND / SLOWEST_FPS) );
if ( WW3D::Get_Movie_Capture_Frame_Rate() != 0.0f ) {
FrameTicks = TICKS_PER_SECOND / WW3D::Get_Movie_Capture_Frame_Rate();
}
#if TIME_STABILIZING_TECHNOLOGY_ENABLED
FrameTicks = TICKS_PER_SECOND / 30;
#endif
#if TIME_DESTABILIZING_TECHNOLOGY_ENABLED
static int state = 0;
FrameTicks = TICKS_PER_SECOND / 15;
if ( ++state & 0x2 ) {
FrameTicks = TICKS_PER_SECOND / 30;
}
#endif
// Single Step
static bool single_step = false;
#ifdef WWDEBUG
if ( Input::Get_State( INPUT_FUNCTION_DEBUG_SINGLE_STEP ) ) {
single_step = !single_step;
Debug_Say(( "Single_Step %s\n", single_step ? "ON" : "OFF" ));
}
if ( single_step ) {
// Wait_Seconds( 0.2 );
FrameTicks = 0;
if ( Input::Get_State( INPUT_FUNCTION_DEBUG_SINGLE_STEP_STEP ) ) {
Debug_Say(( "Single_Step STEP!!\n" ));
FrameTicks = TICKS_PER_SECOND / 15;
}
}
#endif
if ( COMBAT_CAMERA && COMBAT_CAMERA->Is_Snap_Shot_Mode() ) {
FrameTicks = 0;
}
if ( CombatManager::Is_Game_Paused() ) {
FrameTicks = 0;
}
FrameTicks *= TimeScale;
FrameSeconds=(float)FrameTicks / TICKS_PER_SECOND;
RealFrameSeconds=(float)RealFrameTicks / TICKS_PER_SECOND;
WW3D::Sync( WW3D::Get_Sync_Time() + FrameTicks );
/*
#if 0
// testing animation smoothing
if (!WWDEBUG_TRIGGER(WWDEBUG_TRIGGER_GENERIC0) ) {
static int rlticks = 0;
if (rlticks == 0) {
rlticks = ticks;
}
int rtime = ticks - rlticks;
//float amount = (float)rtime / (3.0f*1000.0f);
//Debug_Say(( "Time %d %f\n", rtime, amount ));
if (rtime < 200) {
// Wait_Seconds( amount );
}
rlticks = SystemTicks();
}
#endif
#if 0
//if ( IS_SOLOPLAY && Input::Get_State( INPUT_FUNCTION_DEBUG_RAPID_MOVE ) ) {
if ( Input::Get_State( INPUT_FUNCTION_DEBUG_RAPID_MOVE ) ) {
if ( COMBAT_CAMERA->Is_Using_Host_Model() ) {
FrameTicks *= 10;
// FrameTicks /= 5;
}
}
#endif
#if 0
if (FrameTicks == 0) {
// WWDEBUG_SAY(("Frame Ticks was ZERO!\n"));
FrameTicks = 1;
}
#endif
*/
TotalSeconds += Get_Frame_Seconds();
/*
** Time averaged fps (averaged over 10 seconds)
*/
AveragedFPSTicks += RealFrameTicks;
AveragedFPSCounter++;
if ( AveragedFPSTicks >= 10 * TICKS_PER_SECOND ) {
AveragedFPS = (float)AveragedFPSCounter / ((float)AveragedFPSTicks / (float)TICKS_PER_SECOND);
AveragedFPSTicks = AveragedFPSCounter = 0;
}
FrameTimeHistogram.Add(FrameSeconds);
}
void TimeManager::Wait_Seconds( float time )
{
float end = Get_Seconds() + time;
while ( Get_Seconds() < end );
}
/***********************************************************************************************
* TimeManager::Update( void ) - updates all current timers by the frame time
* *
* INPUT:
* *
* OUTPUT:
* *
* WARNINGS: None *
* *
* HISTORY: *
* 09/01/1997 BG : Created. *
*=============================================================================================*/
void TimeManager::Update( void )
{
Update_Frame_Time();
// tell the profiling code that another frame has gone by
WWProfileManager::Increment_Frame_Counter();
#ifdef WWDEBUG
//
// TSS101401
// Watch out for unexpected slow frames. They may interrupt networking.
//
if (Get_Frame_Real_Seconds() > 2) {
Debug_Say(("TimeManager::Update: warning, frame %d was slow (%d ms)\n",
WWProfileManager::Get_Frame_Count_Since_Reset(),
(int)(1000 * Get_Frame_Real_Seconds())));
}
#endif // WWDEBUG
}