165 lines
3.2 KiB
C++
165 lines
3.2 KiB
C++
|
// Copyright (C) 2007 Id Software, Inc.
|
||
|
//
|
||
|
|
||
|
#include "../precompiled.h"
|
||
|
#pragma hdrstop
|
||
|
|
||
|
#include "../Game_local.h"
|
||
|
|
||
|
#include "BotThread.h"
|
||
|
#include "BotThreadData.h"
|
||
|
|
||
|
idBotThread botThreadLocal;
|
||
|
idBotThread* botThread = &botThreadLocal;
|
||
|
|
||
|
/*
|
||
|
=====================
|
||
|
idBotThread::idBotThread
|
||
|
=====================
|
||
|
*/
|
||
|
idBotThread::idBotThread() :
|
||
|
thread( NULL ),
|
||
|
lastGameFrameNum( -1 ),
|
||
|
isWaiting( false ),
|
||
|
isActive( false ),
|
||
|
numFrameTimes( 0 ) {
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
=====================
|
||
|
idBotThread::~idBotThread
|
||
|
=====================
|
||
|
*/
|
||
|
idBotThread::~idBotThread() {
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
=====================
|
||
|
idBotThread::StartThread
|
||
|
=====================
|
||
|
*/
|
||
|
void idBotThread::StartThread() {
|
||
|
if ( thread != NULL ) {
|
||
|
return;
|
||
|
}
|
||
|
#ifdef _XENON
|
||
|
thread = new sdThread( this, THREAD_NORMAL, XENON_STACKSIZE_BOT );
|
||
|
#else
|
||
|
thread = new sdThread( this, THREAD_LOWEST );
|
||
|
#endif
|
||
|
thread->SetName( "BotThread" );
|
||
|
|
||
|
#ifdef _XENON
|
||
|
thread->SetProcessor( XENON_THREADCORE_BOT );
|
||
|
#endif
|
||
|
|
||
|
if ( !thread->Start() ) {
|
||
|
common->Error( "idBotThread::StartThread : failed to start thread" );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
=====================
|
||
|
idBotThread::StopThread
|
||
|
=====================
|
||
|
*/
|
||
|
void idBotThread::StopThread() {
|
||
|
if ( thread != NULL ) {
|
||
|
thread->Stop();
|
||
|
thread->Join();
|
||
|
thread->Destroy();
|
||
|
thread = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
=====================
|
||
|
idBotThread::Run
|
||
|
=====================
|
||
|
*/
|
||
|
unsigned int idBotThread::Run( void *parm ) {
|
||
|
int previousTime = 0;
|
||
|
|
||
|
isActive = true;
|
||
|
|
||
|
lastGameFrameNum = gameLocal.GetFrameNum();
|
||
|
|
||
|
gameLocal.clip.AllocThread();
|
||
|
|
||
|
while ( !Terminating() ) {
|
||
|
|
||
|
// let the game know another bot AI frame has started
|
||
|
SignalGameThread();
|
||
|
|
||
|
// never run more bot think frames than game frames
|
||
|
while ( lastGameFrameNum >= gameLocal.GetFrameNum() - botThreadData.GetThreadMinFrameDelay() && !Terminating() ) {
|
||
|
isWaiting = true;
|
||
|
WaitForGameThread();
|
||
|
isWaiting = false;
|
||
|
}
|
||
|
lastGameFrameNum = gameLocal.GetFrameNum();
|
||
|
|
||
|
// delete any bots for real
|
||
|
botThreadData.DeleteBots();
|
||
|
|
||
|
// let the bots think
|
||
|
if ( botThreadData.IsThreadingEnabled() ) {
|
||
|
botThreadData.RunFrame();
|
||
|
}
|
||
|
|
||
|
// decrease deleted clip model reference counts
|
||
|
botThreadData.clip->ThreadDeleteClipModels();
|
||
|
|
||
|
// update bot think frame times
|
||
|
int t = sys->Milliseconds();
|
||
|
int delta = t - previousTime;
|
||
|
frameTimes[numFrameTimes++ % MAX_FRAME_TIMES] = delta;
|
||
|
previousTime = t;
|
||
|
}
|
||
|
|
||
|
gameLocal.clip.FreeThread();
|
||
|
|
||
|
isActive = false;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
=====================
|
||
|
idBotThread::Stop
|
||
|
=====================
|
||
|
*/
|
||
|
void idBotThread::Stop() {
|
||
|
sdThreadProcess::Stop();
|
||
|
// need to signal the thread so it wakes up and terminates
|
||
|
gameSignal.Set();
|
||
|
botSignal.Set();
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
=====================
|
||
|
idBotThread::GetFrameRate
|
||
|
=====================
|
||
|
*/
|
||
|
int idBotThread::GetFrameRate() const {
|
||
|
int i, total, fps;
|
||
|
|
||
|
if ( numFrameTimes < MAX_FRAME_TIMES ) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// average multiple frames together to smooth changes out a bit
|
||
|
total = 0;
|
||
|
|
||
|
for ( i = 0; i < MAX_FRAME_TIMES; i++ ) {
|
||
|
total += frameTimes[i];
|
||
|
}
|
||
|
if ( total == 0 ) {
|
||
|
total = 1;
|
||
|
}
|
||
|
fps = 2000 * MAX_FRAME_TIMES / total;
|
||
|
fps = ( fps + 1 ) / 2;
|
||
|
|
||
|
return fps;
|
||
|
}
|